diff --git a/.buildkite/daily.yml b/.buildkite/daily.yml new file mode 100644 index 00000000000000..8b2c00f7b94438 --- /dev/null +++ b/.buildkite/daily.yml @@ -0,0 +1,32 @@ +steps: + - command: + - .buildkite/run.sh + env: + ZEPHYR_TOOLCHAIN_VARIANT: "zephyr" + ZEPHYR_SDK_INSTALL_DIR: "/opt/sdk/zephyr-sdk-0.11.4" + parallelism: 240 + timeout_in_minutes: 210 + retry: + manual: true + plugins: + - docker#v3.5.0: + image: "zephyrprojectrtos/ci:v0.11.10" + propagate-environment: true + volumes: + - "/var/lib/buildkite-agent/git-mirrors:/var/lib/buildkite-agent/git-mirrors" + - "/var/lib/buildkite-agent/zephyr-module-cache:/var/lib/buildkite-agent/zephyr-module-cache" + - "/var/lib/buildkite-agent/zephyr-ccache:/root/.ccache" + workdir: "/workdir/zephyr" + agents: + - "queue=default" + + - wait: ~ + continue_on_failure: true + + - plugins: + - junit-annotate#v1.7.0: + artifacts: twister-*.xml + +notify: + - email: "builds+int+399+7809482394022958124@lists.zephyrproject.org" + if: build.state != "passed" diff --git a/.buildkite/hooks/post-command b/.buildkite/hooks/post-command new file mode 100755 index 00000000000000..839d86ed2a5b71 --- /dev/null +++ b/.buildkite/hooks/post-command @@ -0,0 +1,8 @@ +#!/bin/bash +# Copyright (c) 2020 Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 + +# report disk usage: +echo "--- $0 disk usage" +df -h diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command new file mode 100755 index 00000000000000..f280b70e81b987 --- /dev/null +++ b/.buildkite/hooks/pre-command @@ -0,0 +1,44 @@ +#!/bin/bash +# Copyright (c) 2020 Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 + +# Save off where we started so we can go back there +WORKDIR=${PWD} + +echo "--- $0 disk usage" +df -h +du -hs /var/lib/buildkite-agent/* +docker images -a +docker system df -v + +if [ -n "${BUILDKITE_PULL_REQUEST_BASE_BRANCH}" ]; then + git fetch -v origin ${BUILDKITE_PULL_REQUEST_BASE_BRANCH} + git checkout FETCH_HEAD + git config --local user.email "builds@zephyrproject.org" + git config --local user.name "Zephyr CI" + git merge --no-edit "${BUILDKITE_COMMIT}" || { + local merge_result=$? + echo "Merge failed: ${merge_result}" + git merge --abort + exit $merge_result + } +fi + +mkdir -p /var/lib/buildkite-agent/zephyr-ccache/ + +# create cache dirs, no-op if they already exist +mkdir -p /var/lib/buildkite-agent/zephyr-module-cache/modules +mkdir -p /var/lib/buildkite-agent/zephyr-module-cache/tools +mkdir -p /var/lib/buildkite-agent/zephyr-module-cache/bootloader + +# Clean cache - if it already exists +cd /var/lib/buildkite-agent/zephyr-module-cache +find -type f -not -path "*/.git/*" -not -name ".git" -delete + +# Remove any stale locks +find -name index.lock -delete + +# return from where we started so we can find pipeline files from +# git repo +cd ${WORKDIR} diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml new file mode 100644 index 00000000000000..8c84928d24deb3 --- /dev/null +++ b/.buildkite/pipeline.yml @@ -0,0 +1,28 @@ +steps: + - command: + - .buildkite/run.sh + env: + ZEPHYR_TOOLCHAIN_VARIANT: "zephyr" + ZEPHYR_SDK_INSTALL_DIR: "/opt/sdk/zephyr-sdk-0.11.4" + parallelism: 40 + timeout_in_minutes: 180 + retry: + manual: true + plugins: + - docker#v3.5.0: + image: "zephyrprojectrtos/ci:v0.11.10" + propagate-environment: true + volumes: + - "/var/lib/buildkite-agent/git-mirrors:/var/lib/buildkite-agent/git-mirrors" + - "/var/lib/buildkite-agent/zephyr-module-cache:/var/lib/buildkite-agent/zephyr-module-cache" + - "/var/lib/buildkite-agent/zephyr-ccache:/root/.ccache" + workdir: "/workdir/zephyr" + agents: + - "queue=default" + + - wait: ~ + continue_on_failure: true + + - plugins: + - junit-annotate#v1.7.0: + artifacts: twister-*.xml diff --git a/.buildkite/run.sh b/.buildkite/run.sh new file mode 100755 index 00000000000000..d000a30c58d302 --- /dev/null +++ b/.buildkite/run.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# Copyright (c) 2020 Linaro Limited +# +# SPDX-License-Identifier: Apache-2.0 +set -eE + +function cleanup() +{ + # Rename twister junit xml for use with junit-annotate-buildkite-plugin + # create dummy file if twister did nothing + if [ ! -f twister-out/twister.xml ]; then + touch twister-out/twister.xml + fi + mv twister-out/twister.xml twister-${BUILDKITE_JOB_ID}.xml + buildkite-agent artifact upload twister-${BUILDKITE_JOB_ID}.xml + + + # Upload test_file to get list of tests that are build/run + if [ -f test_file.txt ]; then + buildkite-agent artifact upload test_file.txt + fi + + # ccache stats + echo "--- ccache stats at finish" + ccache -s + + # disk usage + echo "--- disk usage at finish" + df -h +} + +trap cleanup ERR + +echo "--- run $0" + +git log -n 5 --oneline --decorate --abbrev=12 + +# Setup module cache +cd /workdir +ln -s /var/lib/buildkite-agent/zephyr-module-cache/modules +ln -s /var/lib/buildkite-agent/zephyr-module-cache/tools +ln -s /var/lib/buildkite-agent/zephyr-module-cache/bootloader +cd /workdir/zephyr + +export JOB_NUM=$((${BUILDKITE_PARALLEL_JOB}+1)) + +# ccache stats +echo "" +echo "--- ccache stats at start" +ccache -s + + +if [ -n "${DAILY_BUILD}" ]; then + SANITYCHECK_OPTIONS=" --inline-logs -N --build-only --all --retry-failed 3 -v " + echo "--- DAILY BUILD" + west init -l . + west update 1> west.update.log || west update 1> west.update-2.log + west forall -c 'git reset --hard HEAD' + source zephyr-env.sh + ./scripts/twister --subset ${JOB_NUM}/${BUILDKITE_PARALLEL_JOB_COUNT} ${SANITYCHECK_OPTIONS} +else + if [ -n "${BUILDKITE_PULL_REQUEST_BASE_BRANCH}" ]; then + ./scripts/ci/run_ci.sh -c -b ${BUILDKITE_PULL_REQUEST_BASE_BRANCH} -r origin \ + -m ${JOB_NUM} -M ${BUILDKITE_PARALLEL_JOB_COUNT} -p ${BUILDKITE_PULL_REQUEST} + else + ./scripts/ci/run_ci.sh -c -b ${BUILDKITE_BRANCH} -r origin \ + -m ${JOB_NUM} -M ${BUILDKITE_PARALLEL_JOB_COUNT}; + fi +fi + +SANITY_EXIT_STATUS=$? + +cleanup + +exit ${SANITY_EXIT_STATUS} diff --git a/.checkpatch.conf b/.checkpatch.conf index a594d6f5e281a5..7107b75c46ecd7 100644 --- a/.checkpatch.conf +++ b/.checkpatch.conf @@ -10,6 +10,8 @@ --ignore SPLIT_STRING --ignore VOLATILE --ignore CONFIG_EXPERIMENTAL +--ignore PREFER_KERNEL_TYPES +--ignore PREFER_SECTION --ignore AVOID_EXTERNS --ignore NETWORKING_BLOCK_COMMENT_STYLE --ignore DATE_TIME @@ -17,4 +19,6 @@ --ignore CONST_STRUCT --ignore FILE_PATH_CHANGES --ignore SPDX_LICENSE_TAG +--ignore C99_COMMENT_TOLERANCE +--ignore REPEATED_WORD --exclude ext diff --git a/.editorconfig b/.editorconfig index 878556123c247a..07fc62990aa489 100644 --- a/.editorconfig +++ b/.editorconfig @@ -65,3 +65,11 @@ indent_style = tab [*.{dts,dtsi,overlay}] indent_style = tab indent_size = 8 + +# Git commit messages +[COMMIT_EDITMSG] +max_line_length = 72 + +# Kconfig +[Kconfig*] +indent_style=tab diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 1f67ed801218ea..10ca02cfa5f903 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -24,10 +24,11 @@ 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) -**Screenshots or console output** -If applicable, add a screenshot (drag-and-drop an image), or console logs -(cut-and-paste text and put a code fence (\`\`\`) before and after, to help -explain the issue. +**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) diff --git a/.github/ISSUE_TEMPLATE/hardware_support.md b/.github/ISSUE_TEMPLATE/hardware_support.md new file mode 100644 index 00000000000000..a81be5b81f8770 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/hardware_support.md @@ -0,0 +1,19 @@ +--- +name: Hardware Support +about: Suggest adding hardware support +title: '' +labels: Hardware Support +assignees: '' + +--- + +**Is this request related to a missing driver support for a particular hardware platform, SoC or board? Please describe.** +Describe in details the hardware support being requested and why this support benefits Zephyr. + +**Describe why you are asking for this support?** +Describe why you are asking for this support instead of contributing it directly to the tree + +If this is a new board or SoC, please state whether you are willing to maintain the Zephyr support for it if it is included in the main tree + +**Additional context** +Add any other context or graphics (drag-and-drop an image) about the hardware here. diff --git a/.github/ISSUE_TEMPLATE/rfc---proposal.md b/.github/ISSUE_TEMPLATE/rfc-proposal.md similarity index 100% rename from .github/ISSUE_TEMPLATE/rfc---proposal.md rename to .github/ISSUE_TEMPLATE/rfc-proposal.md diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000000000..25380e0b6db8a3 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,159 @@ +"area: Modem": + - "drivers/modem/**/*" +"area: PWM": + - "drivers/pwm/**/*" +"area: Watchdog": + - "drivers/watchdog/**/*" +"area: Sensors": + - "drivers/sensors/**/*" +"area: ADC": + - "drivers/adc/**/*" +"area: Counter": + - "drivers/counter/**/*" +"area: CAN": + - "include/drivers/can.h" + - "include/canbus/*/**" + - "drivers/can/**/*" + - "subsys/canbus/*/**" +"area: EEPROM": + - "include/drivers/eeprom.h" + - "drivers/eeprom/**/*" +"area: Timer": + - "drivers/timer/**/*" +"area: I2S": + - "drivers/i2s/**/*" +"area: C Library": + - "lib/libc/**/*" +"area: Devicetree": + - "dts/**/*" + - "**/*.dts" + - "**/*.dtsi" + - "include/devicetree.h" + - "include/devicetree/*" + - "doc/guides/dts/**/*" +"area: Devicetree Binding": + - "include/dt-bindings/**/*" + - "dts/bindings/**/*" +"area: Devicetree Tooling": + - "scripts/dts/**/*" +"area: I2C": + - "drivers/i2c/**/*" +"area: SPI": + - "drivers/spi/**/*" +"area: Boards": + - "boards/**/*" +"area: POSIX": + - "lib/posix/**/*" +"area: native port": + - "arch/posix/**/*" + - "include/arch/posix/**/*" + - "soc/posix/**/*" + - "**/*native_posix*" +"area: X86": + - "arch/x86/**/*" + - "include/arch/x86/**/*" +"area: ARM": + - "arch/arm/**/*" + - "include/arch/arm/**/*" +"area: ARM_64": + - "arch/arm/core/aarch64/**/*" + - "include/arch/arm/aarch64/**/*" +"area: NIOS2": + - "arch/nios2/**/*" + - "include/arch/nios2/**/*" +"area: Xtensa": + - "arch/xtensa/**/*" + - "include/arch/xtensa/**/*" +"area: RISCv32/64": + - "arch/risv/**/*" + - "include/arch/riscv/**/*" +"area: ARC": + - "arch/arc/**/*" + - "include/arch/arc/**/*" +"area: Networking": + - "subsys/net/**/*" + - "samples/net/**/*" + - "tests/net/**/*" + - "include/net/**/*" + - "include/drivers/ieee802154/**/*" + - "drivers/ethernet/**/*" + - "drivers/ieee802154/**/*" + - "drivers/wifi/**/*" + - "drivers/ptp_clock/**/*" + - "drivers/net/**/*" +"area: Logging": + - "subsys/logging/**/*" +"area: Shell": + - "subsys/shell/**/*" +"area: Console": + - "subsys/console/**/*" +"area: Test Framework": + - "subsys/testsuite/**/*" +"area: Settings": + - "subsys/settings/**/*" +"area: File System": + - "subsys/fs/**/*" +"area: Storage": + - "subsys/storage/**/*" +"area: Bluetooth": + - "subsys/bluetooth/**/*" + - "**/*bluetooth*" +"area: Bluetooth Mesh": + - "subsys/bluetooth/mesh/**/*" +"area: Bluetooth Controller": + - "subsys/bluetooth/controller/**/*" +"area: Bluetooth Host": + - "subsys/bluetooth/host/**/*" + - "subsys/bluetooth/services/**/*" +"area: API": + - "include/**/*" +"area: Samples": + - "samples/**/*" +"area: Tests": + - "tests/**/*" +"area: Kernel": + - "kernel/**/*" + - "tests/kernel/**/*" +"area: Documentation": + - "**/*.rst" + - "**/*.md" +"area: Build System": + - "cmake/**/*" + - "CmakeLists.txt" +"area: Kconfig": + - "scripts/kconfig/**/*" + - "Kconfig" + - "Kconfig.zephyr" +"area: Sanitycheck": + - "scripts/twister" + - "scripts/pylib/twister/**/*" +"area: Modules": + - "west.yml" + - "modules/**/*" +"area: Shields": + - "boards/shields/**" + - "samples/shields/**" +"platform: NXP": + - "boards/arm/frdm*/**" + - "boards/arm/hexiwear*/**" + - "boards/arm/lpcxpresso*/**" + - "boards/arm/*imx*/**" + - "drivers/**/*imx*" + - "drivers/**/*mcux*" + - "dts/arm/nxp/*/*" + - "dts/bindings/**/nxp*" + - "soc/arm/nxp*/**" +"platform: STM32": + - "boards/arm/nucleo_*/**" + - "boards/arm/*stm32*/**" + - "drivers/**/*stm32*" + - "dts/arm/st/*/*" + - "include/drivers/*/*stm32*" + - "soc/arm/st_stm32/**" +"platform: SiLabs": + - "boards/arm/efr32_*/**/*" + - "boards/arm/efm32_*/**/*" + - "drivers/**/*gecko*" + - "dts/arm/silabs/**/*" + - "dts/bindings/**/silabs,gecko*" + - "soc/arm/silabs_exx32/**/*" diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 00000000000000..92f08d21103a04 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,16 @@ +name: Backport +on: + pull_request_target: + types: + - closed + - labeled + +jobs: + backport: + runs-on: ubuntu-18.04 + name: Backport + steps: + - name: Backport + uses: zephyrproject-rtos/action-backport@v1.1.99 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml new file mode 100644 index 00000000000000..b1edfa993fcdce --- /dev/null +++ b/.github/workflows/compliance.yml @@ -0,0 +1,114 @@ +name: Compliance + +on: pull_request + +jobs: + compliance_job: + runs-on: ubuntu-latest + name: Run compliance checks on patch series (PR) + steps: + - name: Checkout the code + uses: actions/checkout@v1 + + - name: cache-pip + uses: actions/cache@v1 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-doc-pip + + - name: Install python dependencies + run: | + pip3 install setuptools + pip3 install wheel + pip3 install python-magic junitparser gitlint pylint pykwalify + pip3 install west + + - name: Run Compliance Tests + id: compliance + env: + BASE_REF: ${{ github.base_ref }} + run: | + export PATH=$PATH:~/.local/bin + export ZEPHYR_BASE=$PWD + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git rebase origin/${BASE_REF} + ./scripts/ci/check_compliance.py -m Codeowners -m Devicetree -m Gitlint -m Identity -m Nits -m pylint -m checkpatch -m Kconfig -c origin/${BASE_REF}.. || true + + - name: upload-results + uses: actions/upload-artifact@master + continue-on-error: True + with: + name: compliance.xml + path: compliance.xml + + - name: check-warns + run: | + if [ -s Nits.txt ]; then + errors=$(cat Nits.txt) + errors="${errors//'%'/'%25'}" + errors="${errors//$'\n'/'%0A'}" + errors="${errors//$'\r'/'%0D'}" + echo "::error file=Nits.txt::$errors" + exit=1 + fi + if [ -s checkpatch.txt ]; then + errors=$(cat checkpatch.txt) + errors="${errors//'%'/'%25'}" + errors="${errors//$'\n'/'%0A'}" + errors="${errors//$'\r'/'%0D'}" + echo "::error file=Checkpatch.txt::$errors" + exit=1 + fi + if [ -s Identity.txt ]; then + errors=$(cat Identity.txt) + errors="${errors//'%'/'%25'}" + errors="${errors//$'\n'/'%0A'}" + errors="${errors//$'\r'/'%0D'}" + echo "::error file=Identity.txt::$errors" + exit=1 + fi + if [ -s Gitlint.txt ]; then + errors=$(cat Gitlint.txt) + errors="${errors//'%'/'%25'}" + errors="${errors//$'\n'/'%0A'}" + errors="${errors//$'\r'/'%0D'}" + echo "::error file=Gitlint.txt::$errors" + exit=1 + fi + if [ -s pylint.txt ]; then + errors=$(cat pylint.txt) + errors="${errors//'%'/'%25'}" + errors="${errors//$'\n'/'%0A'}" + errors="${errors//$'\r'/'%0D'}" + echo "::error file=pylint.txt::$errors" + exit=1 + fi + if [ -s Devicetree.txt ]; then + errors=$(cat Devicetree.txt) + errors="${errors//'%'/'%25'}" + errors="${errors//$'\n'/'%0A'}" + errors="${errors//$'\r'/'%0D'}" + echo "::error file=Devicetree.txt::$errors" + exit=1 + fi + if [ -s Kconfig.txt ]; then + errors=$(cat Kconfig.txt) + errors="${errors//'%'/'%25'}" + errors="${errors//$'\n'/'%0A'}" + errors="${errors//$'\r'/'%0D'}" + echo "::error file=Kconfig.txt::$errors" + exit=1 + fi + if [ -s Codeowners.txt ]; then + errors=$(cat Codeowners.txt) + errors="${errors//'%'/'%25'}" + errors="${errors//$'\n'/'%0A'}" + errors="${errors//$'\r'/'%0D'}" + echo "::error file=Codeowners.txt::$errors" + exit=1 + fi + + if [ ${exit} == 1 ]; then + exit 1; + fi diff --git a/.github/workflows/conflict.yml b/.github/workflows/conflict.yml new file mode 100644 index 00000000000000..075c092950fd28 --- /dev/null +++ b/.github/workflows/conflict.yml @@ -0,0 +1,14 @@ +name: Conflict Finder + +on: + push: + branches-ignore: + - '**' +jobs: + conflict: + runs-on: ubuntu-latest + steps: + - uses: mschilde/auto-label-merge-conflicts@master + with: + CONFLICT_LABEL_NAME: "has conflicts" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/daily_test_version.yml b/.github/workflows/daily_test_version.yml new file mode 100644 index 00000000000000..6dfb62910fe7e8 --- /dev/null +++ b/.github/workflows/daily_test_version.yml @@ -0,0 +1,38 @@ +# Copyright (c) 2020 Intel Corp. +# SPDX-License-Identifier: Apache-2.0 + +name: Publish commit for daily testing + +on: + schedule: + - cron: '50 22 * * *' + push: + branches: + - refs/tags/* + +jobs: + get_version: + runs-on: ubuntu-latest + if: github.repository == 'zephyrproject-rtos/zephyr' + + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_TESTING }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_TESTING }} + aws-region: us-east-1 + + - name: install-pip + run: | + pip3 install gitpython + + - name: checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Upload to AWS S3 + run: | + python3 scripts/ci/version_mgr.py --update . + aws s3 cp versions.json s3://testing.zephyrproject.org/daily_tests/versions.json diff --git a/.github/workflows/devicetree_checks.yml b/.github/workflows/devicetree_checks.yml new file mode 100644 index 00000000000000..7e1f27d9a44150 --- /dev/null +++ b/.github/workflows/devicetree_checks.yml @@ -0,0 +1,63 @@ +# Copyright (c) 2020 Linaro Limited. +# Copyright (c) 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +name: Devicetree script tests + +on: + push: + paths: + - 'scripts/dts/**' + - '.github/workflows/devicetree_checks.yml' + pull_request: + paths: + - 'scripts/dts/**' + - '.github/workflows/devicetree_checks.yml' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: [3.6, 3.7, 3.8] + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - name: checkout + uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: cache-pip-linux + if: startsWith(runner.os, 'Linux') + uses: actions/cache@v1 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ matrix.python-version }} + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.python-version }} + - name: cache-pip-mac + if: startsWith(runner.os, 'macOS') + uses: actions/cache@v1 + with: + path: ~/Library/Caches/pip + # Trailing '-' was just to get a different cache name + key: ${{ runner.os }}-pip-${{ matrix.python-version }}- + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.python-version }}- + - name: cache-pip-win + if: startsWith(runner.os, 'Windows') + uses: actions/cache@v1 + with: + path: ~\AppData\Local\pip\Cache + key: ${{ runner.os }}-pip-${{ matrix.python-version }} + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.python-version }} + - name: install python dependencies + run: | + pip3 install wheel + pip3 install pytest pyyaml + - name: run pytest + working-directory: scripts/dts + run: | + python -m pytest testdtlib.py testedtlib.py diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index f9a6cb9cc961dc..5ba53bec02ecf6 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -3,7 +3,20 @@ name: Documentation GitHub Workflow -on: [pull_request] +on: + pull_request: + paths: + - 'doc/**' + - '**.rst' + - 'include/**' + - 'kernel/include/kernel_arch_interface.h' + - 'lib/libc/**' + - 'subsys/testsuite/ztest/include/**' + - 'tests/**' + - '.known-issues/doc/**' + - '**/Kconfig*' + - 'west.yml' + - '.github/workflows/doc-build.yml' jobs: build: @@ -12,7 +25,7 @@ jobs: steps: - name: Update PATH for west run: | - echo "::add-path::$HOME/.local/bin" + echo "$HOME/.local/bin" >> $GITHUB_PATH - name: checkout uses: actions/checkout@v2 @@ -30,10 +43,8 @@ jobs: - name: install-pip run: | pip3 install setuptools - pip3 install 'breathe>=4.9.1,<4.15.0' 'docutils>=0.14' \ - 'sphinx>=1.7.5,<3.0' sphinx_rtd_theme sphinx-tabs \ - sphinxcontrib-svg2pdfconverter 'west>=0.6.2' - pip3 install pyelftools canopen progress + pip3 install -r scripts/requirements-base.txt + pip3 install -r scripts/requirements-doc.txt - name: west setup run: | diff --git a/.github/workflows/doc-publish.yml b/.github/workflows/doc-publish.yml index a49df023900497..13c2b17cdb6570 100644 --- a/.github/workflows/doc-publish.yml +++ b/.github/workflows/doc-publish.yml @@ -14,11 +14,12 @@ on: jobs: build: runs-on: ubuntu-latest + if: github.repository == 'zephyrproject-rtos/zephyr' steps: - name: Update PATH for west run: | - echo "::add-path::$HOME/.local/bin" + echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Determine tag id: tag @@ -61,10 +62,8 @@ jobs: - name: install-pip run: | pip3 install setuptools - pip3 install 'breathe>=4.9.1,<4.15.0' 'docutils>=0.14' \ - 'sphinx>=1.7.5,<3.0' sphinx_rtd_theme sphinx-tabs \ - sphinxcontrib-svg2pdfconverter 'west>=0.6.2' - pip3 install pyelftools + pip3 install -r scripts/requirements-base.txt + pip3 install -r scripts/requirements-doc.txt - name: west setup run: | diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 00000000000000..ca16a800f8e538 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,11 @@ +name: 'Pull Request Labeler' +on: + - pull_request_target + +jobs: + labeler: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v2.1.1 + with: + repo-token: '${{ secrets.GITHUB_TOKEN }}' diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml new file mode 100644 index 00000000000000..fc2f9fa7531ab3 --- /dev/null +++ b/.github/workflows/manifest.yml @@ -0,0 +1,26 @@ +name: Manifest +on: + - pull_request_target + +jobs: + contribs: + runs-on: ubuntu-latest + name: Manifest + steps: + - name: Checkout the code + uses: actions/checkout@v2 + with: + path: zephyrproject/zephyr + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Manifest + uses: zephyrproject-rtos/action-manifest@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + manifest-path: 'west.yml' + checkout-path: 'zephyrproject/zephyr' + label-prefix: 'manifest-' + verbosity-level: '1' + labels: 'manifest, west' + dnm-labels: 'DNM' diff --git a/.github/workflows/sanitycheck_tests.yml b/.github/workflows/sanitycheck_tests.yml new file mode 100644 index 00000000000000..62ead116d50834 --- /dev/null +++ b/.github/workflows/sanitycheck_tests.yml @@ -0,0 +1,51 @@ +# Copyright (c) 2020 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +name: Zephyr Sanitycheck TestSuite + +on: + push: + paths: + - 'scripts/pylib/twister/**' + - 'scripts/twister' + - 'scripts/tests/twister/**' + - '.github/workflows/sanitycheck_tests.yml' + pull_request: + paths: + - 'scripts/pylib/twister/**' + - 'scripts/twister' + - 'scripts/tests/twister/**' + - '.github/workflows/sanitycheck_tests.yml' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: [3.6, 3.7, 3.8] + os: [ubuntu-latest] + steps: + - name: checkout + uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: cache-pip-linux + if: startsWith(runner.os, 'Linux') + uses: actions/cache@v1 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ matrix.python-version }} + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.python-version }} + - name: install-packages + run: | + pip3 install pytest colorama pyyaml ply mock + - name: Run pytest + env: + ZEPHYR_BASE: ./ + ZEPHYR_TOOLCHAIN_VARIANT: zephyr + run: | + echo "Run Sanitycheck tests" + PYTHONPATH=./scripts/tests pytest ./scripts/tests/twister diff --git a/.github/workflows/stale_issue.yml b/.github/workflows/stale_issue.yml new file mode 100644 index 00000000000000..d035d2879bcd6a --- /dev/null +++ b/.github/workflows/stale_issue.yml @@ -0,0 +1,22 @@ +name: "Close stale pull requests/issues" +on: + schedule: + - cron: "16 00 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + if: github.repository == 'zephyrproject-rtos/zephyr' + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-pr-message: 'This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.' + stale-issue-message: 'This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.' + days-before-stale: 60 + days-before-close: 14 + stale-issue-label: 'Stale' + stale-pr-label: 'Stale' + exempt-pr-labels: 'Blocked,In progress' + exempt-issue-labels: 'In progress,Enhancement,Feature,Feature Request,RFC,Meta' + operations-per-run: 400 diff --git a/.github/workflows/west_cmds.yml b/.github/workflows/west_cmds.yml index ef87fd28fafdcd..4a958b3bf8ca8b 100644 --- a/.github/workflows/west_cmds.yml +++ b/.github/workflows/west_cmds.yml @@ -8,10 +8,12 @@ on: paths: - 'scripts/west-commands.yml' - 'scripts/west_commands/**' + - '.github/workflows/west_cmds.yml' pull_request: paths: - 'scripts/west-commands.yml' - 'scripts/west_commands/**' + - '.github/workflows/west_cmds.yml' jobs: build: @@ -54,12 +56,13 @@ jobs: ${{ runner.os }}-pip-${{ matrix.python-version }} - name: install pytest run: | - pip3 install pytest west pyelftools canopen progress + pip3 install wheel + pip3 install pytest west pyelftools canopen progress mypy intelhex psutil - name: run pytest-win if: runner.os == 'Windows' run: | - cmd /C "set PYTHONPATH=.\scripts\west_commands && pytest ./scripts/west_commands/tests/" + python ./scripts/west_commands/run_tests.py - name: run pytest-mac-linux if: runner.os != 'Windows' run: | - PYTHONPATH=./scripts/west_commands pytest ./scripts/west_commands/tests/ + ./scripts/west_commands/run_tests.py diff --git a/.gitignore b/.gitignore index e41e431a28a70a..9bf7b1e6a0ea8a 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ doc/samples doc/latex doc/themes/zephyr-docs-theme sanity-out* +twister-out* bsim_bt_out scripts/grub doc/reference/kconfig/*.rst diff --git a/.known-issues/doc/bluetooth.conf b/.known-issues/doc/bluetooth.conf deleted file mode 100644 index c51d25a5d4b825..00000000000000 --- a/.known-issues/doc/bluetooth.conf +++ /dev/null @@ -1,68 +0,0 @@ -# -# Bluetooth unnamed struct definition -# -# FIXME: all these should match the relative filename -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+]$ -^[ \t]*$ -^[ \t]*\^$ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+]$ -^[ \t]*$ -^[ \t]*\^$ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+]$ -^.*bt_conn_info.__unnamed__.*$ -^[- \t]*\^$ -# -# bt_gatt_discover_params unnamed struct definition -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*bt_gatt_discover_params.__unnamed__.* -^[- \t]*\^ -# -# Bluetooth GATT unnamed struct definition -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*bt_gatt_read_params.__unnamed__.* -^[- \t]*\^ -# -# Bluetooth mesh unnamed struct definition -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*bt_mesh_model.__unnamed__.* -^[- \t]*\^ -# -# Bluetooth mesh pub struct definition -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth[/\\]mesh[/\\]access.rst):(?P[0-9]+): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*bt_mesh_model_pub.* -^[- \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*bt_mesh_model_pub.* -^[- \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*bt_mesh_model_pub.* -^[- \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*bt_mesh_model_pub.* -^[- \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*bt_mesh_model_pub.* -^[- \t]*\^ diff --git a/.known-issues/doc/crypto.conf b/.known-issues/doc/crypto.conf deleted file mode 100644 index 062470552578ee..00000000000000 --- a/.known-issues/doc/crypto.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# crypto unnamed struct definition -#doc/reference/crypto/index.rst -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]crypto[/\\]index.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*cipher_ctx.mode_params.* -^[- \t]*\^ -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]crypto[/\\]index.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*cipher_ctx.key.* -^[- \t]*\^ diff --git a/.known-issues/doc/display.conf b/.known-issues/doc/display.conf deleted file mode 100644 index 50d07de818cf9f..00000000000000 --- a/.known-issues/doc/display.conf +++ /dev/null @@ -1,15 +0,0 @@ -# -# Display -# -# -# include -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]display_api.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*mb_image.__unnamed__ -^[- \t]*\^ diff --git a/.known-issues/doc/duplicate.conf b/.known-issues/doc/duplicate.conf index e3d75a60121f21..b738dfcb2bed4c 100644 --- a/.known-issues/doc/duplicate.conf +++ b/.known-issues/doc/duplicate.conf @@ -1,6 +1,39 @@ # -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]file_system[/\\]index.rst):(?P[0-9]+): WARNING: Duplicate declaration(.*) +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]file_system[/\\]index.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ # -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]peripherals[/\\]dma.rst):(?P[0-9]+): WARNING: Duplicate declaration(.*) +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]peripherals[/\\]dma.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ # -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]peripherals[/\\]sensor.rst):(?P[0-9]+): WARNING: Duplicate declaration(.*) +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]audio[/\\]dmic.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking[/\\]net_if.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking[/\\]ieee802154.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking[/\\]sockets.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth[/\\]uuid.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth[/\\]sdp.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth[/\\]rfcomm.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth[/\\]hci_raw.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth[/\\]hci_drivers.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth[/\\]gatt.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth[/\\]gap.rst):(?P[0-9]+): WARNING: Duplicate C declaration, also defined at (.*)\.$ +^Declaration is \'.*\'\.$ diff --git a/.known-issues/doc/misc.conf b/.known-issues/doc/misc.conf index 48323bee0bbe8d..6cb7946770325b 100644 --- a/.known-issues/doc/misc.conf +++ b/.known-issues/doc/misc.conf @@ -1,15 +1,14 @@ -# -# Display -# -# -# include -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]misc_api.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*json_obj_descr.__unnamed__ -^[- \t]*\^ +# multiple section 'index' +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]custom-doxygen[/\\]mainpage.md):[0-9]+: warning: multiple use of section label 'index' for main page, \(first occurrence: .*$ +# +^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]bluetooth[/\\]gatt.rst):(?P[0-9]+): WARNING: Error in declarator$ +^[ \t]*If.*:$ +^[ \t]*Invalid C declaration: .* \[error at [0-9]+\]$ +^[ \t]*ATOMIC_DEFINE.*$ +^[- \t]*\^$ +^[ \t]*If.*:$ +^[ \t]*Error in declarator or parameters$ +^[ \t]*Invalid C declaration: .* \[error at [0-9]+\]$ +^[ \t]*ATOMIC_DEFINE.*$ +^[- \t]*\^$ +^[ \t]*$ diff --git a/.known-issues/doc/networking.conf b/.known-issues/doc/networking.conf deleted file mode 100644 index 0976c12f6c71e5..00000000000000 --- a/.known-issues/doc/networking.conf +++ /dev/null @@ -1,70 +0,0 @@ -# -# Networking -# -# -# include/net/net_ip.h warnings -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*in[_6]+addr.in[46]_u -^[- \t]*\^ -# -# include/net/net_mgmt.h -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*net_mgmt_event_callback.__unnamed__ -^[- \t]*\^ -# -# include/net/buf.h -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*net_buf.__unnamed__ -^[- \t]*\^ -# -# include/net/ieee802154.h -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*ieee802154_req_params.__unnamed__ -^[- \t]*\^ -# -# include/net/net_context.h -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking[/\\]net_context.rst):(?P[0-9]+): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*net_context.options -^[- \t]*\^ -# -# include/net/net_stats.h -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking[/\\]net_stats.rst):(?P[0-9]+): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*net_stats_tc.[a-z]+ -^[- \t]*\^ -# -# stray duplicate definition warnings -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]networking[/\\]net_if.rst):(?P[0-9]+): WARNING: Duplicate declaration(.*) diff --git a/.known-issues/doc/uart.conf b/.known-issues/doc/uart.conf deleted file mode 100644 index 002f12acd209b0..00000000000000 --- a/.known-issues/doc/uart.conf +++ /dev/null @@ -1,31 +0,0 @@ -# -# UART unnamed struct definition -#doc/api/peripherals/uart.rst -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]peripherals[/\\]uart.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*uart_device_config.__unnamed__.* -^[- \t]*\^ -# -^(?P([\-:\\/\w\.])+[/\\]doc[/\\]reference[/\\]peripherals[/\\]uart.rst):(?P[0-9]+): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected identifier in nested name. \[error at [0-9]+] -^[ \t]* -^[ \t]*\^ -^(?P=filename):(?P=lineno): WARNING: Invalid definition: Expected end of definition. \[error at [0-9]+] -^.*uart_event.data -^[- \t]*\^ diff --git a/.shippable.yml b/.shippable.yml deleted file mode 100644 index 76ff58de2ac73a..00000000000000 --- a/.shippable.yml +++ /dev/null @@ -1,75 +0,0 @@ -language: c - -compiler: gcc - -env: - global: - - ZEPHYR_SDK_INSTALL_DIR=/opt/sdk/zephyr-sdk-0.11.3 - - ZEPHYR_TOOLCHAIN_VARIANT=zephyr - - MATRIX_BUILDS="5" - matrix: - - MATRIX_BUILD="1" - - MATRIX_BUILD="2" - - MATRIX_BUILD="3" - - MATRIX_BUILD="4" - - MATRIX_BUILD="5" - -build: - cache: false - cache_dir_list: - - ${SHIPPABLE_BUILD_DIR}/ccache - pre_ci_boot: - image_name: zephyrprojectrtos/ci - image_tag: v0.11.8 - pull: true - options: "-e HOME=/home/buildslave --privileged=true --tty --net=bridge --user buildslave" - - ci: - - export CCACHE_DIR=${SHIPPABLE_BUILD_DIR}/ccache/.ccache - - > - if [ "$IS_PULL_REQUEST" = "true" ]; then - ./scripts/ci/run_ci.sh -c -b ${PULL_REQUEST_BASE_BRANCH} -r origin -m ${MATRIX_BUILD} -M ${MATRIX_BUILDS} -p ${PULL_REQUEST}; - else - ./scripts/ci/run_ci.sh -c -b ${BRANCH} -r origin -m ${MATRIX_BUILD} -M ${MATRIX_BUILDS}; - fi; - - ccache -s - on_failure: - - > - if [ "$IS_PULL_REQUEST" = "true" ]; then - ./scripts/ci/run_ci.sh -f -b ${PULL_REQUEST_BASE_BRANCH} -r origin -m ${MATRIX_BUILD} -M ${MATRIX_BUILDS} -p ${PULL_REQUEST}; - else - ./scripts/ci/run_ci.sh -f -b ${BRANCH} -r origin -m ${MATRIX_BUILD} -M ${MATRIX_BUILDS}; - fi; - on_success: - - > - if [ "$IS_PULL_REQUEST" = "true" ]; then - ./scripts/ci/run_ci.sh -s -b ${PULL_REQUEST_BASE_BRANCH} -r origin -m ${MATRIX_BUILD} -M ${MATRIX_BUILDS} -p ${PULL_REQUEST}; - else - ./scripts/ci/run_ci.sh -s -b ${BRANCH} -r origin -m ${MATRIX_BUILD} -M ${MATRIX_BUILDS}; - fi; -branches: - only: - - master - - v*-branch - - topic-* -integrations: - notifications: - - integrationName: slack_integration - type: slack - recipients: - - "#ci" - branches: - only: - - master - on_success: never - on_failure: never - - integrationName: email - type: email - recipients: - - builds@zephyrproject.org - branches: - only: - - master - on_success: never - on_failure: always - on_pull_request: never diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ee341157ce457..9ed7c187331696 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ foreach(optional_include_dir ${SOC_DIR}/${ARCH}/${SOC_PATH} ${SOC_DIR}/${ARCH}/${SOC_PATH}/include ${SOC_DIR}/${ARCH}/${SOC_FAMILY}/include + ${SOC_DIR}/${ARCH}/${SOC_FAMILY}/common/include ) if(EXISTS ${optional_include_dir}) zephyr_include_directories(${optional_include_dir}) @@ -97,11 +98,11 @@ zephyr_compile_definitions( # @Intent: Set compiler flags to enable buffer overflow checks in libc functions # @config in CONFIG_NO_OPTIMIZATIONS optional : Optimizations may affect security -toolchain_cc_security_fortify() +zephyr_compile_definitions($ ) # @Intent: Set compiler flags to detect general stack overflows across all functions if(CONFIG_STACK_CANARIES) - toolchain_cc_security_canaries() + zephyr_compile_options($) endif() if(BUILD_VERSION) @@ -123,10 +124,10 @@ endif() # 1) Using EXTRA_CFLAGS which is applied regardless of kconfig choice, or # 2) Rely on override support being implemented by your toolchain_cc_optimize_*() # -toolchain_cc_optimize_for_no_optimizations_flag(OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG) -toolchain_cc_optimize_for_debug_flag(OPTIMIZE_FOR_DEBUG_FLAG) -toolchain_cc_optimize_for_speed_flag(OPTIMIZE_FOR_SPEED_FLAG) -toolchain_cc_optimize_for_size_flag(OPTIMIZE_FOR_SIZE_FLAG) +get_property(OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG TARGET compiler PROPERTY no_optimization) +get_property(OPTIMIZE_FOR_DEBUG_FLAG TARGET compiler PROPERTY optimization_debug) +get_property(OPTIMIZE_FOR_SPEED_FLAG TARGET compiler PROPERTY optimization_speed) +get_property(OPTIMIZE_FOR_SIZE_FLAG TARGET compiler PROPERTY optimization_size) # From kconfig choice, pick the actual OPTIMIZATION_FLAG to use. # Kconfig choice ensures only one of these CONFIG_*_OPTIMIZATIONS is set. @@ -153,93 +154,75 @@ endif() zephyr_compile_options(${OPTIMIZATION_FLAG}) # @Intent: Obtain compiler specific flags related to C++ that are not influenced by kconfig -toolchain_cc_cpp_base_flags(CPP_BASE_FLAGS) -foreach(flag ${CPP_BASE_FLAGS}) - zephyr_compile_options( - $<$:${flag}> - ) -endforeach() +zephyr_compile_options($<$:$>) # @Intent: Obtain compiler specific flags for compiling under different ISO standards of C++ -toolchain_cc_cpp_dialect_std_98_flags(CPP_DIALECT_STD_98_FLAGS) -toolchain_cc_cpp_dialect_std_11_flags(CPP_DIALECT_STD_11_FLAGS) -toolchain_cc_cpp_dialect_std_14_flags(CPP_DIALECT_STD_14_FLAGS) -toolchain_cc_cpp_dialect_std_17_flags(CPP_DIALECT_STD_17_FLAGS) -toolchain_cc_cpp_dialect_std_2a_flags(CPP_DIALECT_STD_2A_FLAGS) - if(CONFIG_CPLUSPLUS) # From kconfig choice, pick a single dialect. # Kconfig choice ensures only one of these CONFIG_STD_CPP* is set. if(CONFIG_STD_CPP98) - set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_98_FLAGS}) + set(STD_CPP_DIALECT_FLAGS $) elseif(CONFIG_STD_CPP11) - set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_11_FLAGS}) # Default in kconfig + set(STD_CPP_DIALECT_FLAGS $) # Default in kconfig elseif(CONFIG_STD_CPP14) - set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_14_FLAGS}) + set(STD_CPP_DIALECT_FLAGS $) elseif(CONFIG_STD_CPP17) - set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_17_FLAGS}) + set(STD_CPP_DIALECT_FLAGS $) elseif(CONFIG_STD_CPP2A) - set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_2A_FLAGS}) + set(STD_CPP_DIALECT_FLAGS $) else() assert(0 "Unreachable code. Expected C++ standard to have been chosen. See Kconfig.zephyr.") endif() - foreach(flag ${STD_CPP_DIALECT_FLAGS}) - zephyr_compile_options( - $<$:${flag}> - ) - endforeach() + zephyr_compile_options($<$:${STD_CPP_DIALECT_FLAGS}>) endif() if(NOT CONFIG_EXCEPTIONS) # @Intent: Obtain compiler specific flags related to C++ Exceptions - toolchain_cc_cpp_no_exceptions_flag(CPP_NO_EXCEPTIONS_FLAG) - zephyr_compile_options( - $<$:${CPP_NO_EXCEPTIONS_FLAG}> - ) + zephyr_compile_options($<$:$>) endif() if(NOT CONFIG_RTTI) # @Intent: Obtain compiler specific flags related to C++ Run Time Type Information - toolchain_cc_cpp_no_rtti_flag(CPP_NO_RTTI_FLAG) - zephyr_compile_options( - $<$:${CPP_NO_RTTI_FLAG}> - ) + zephyr_compile_options($<$:$>) endif() if(CONFIG_MISRA_SANE) # @Intent: Obtain toolchain compiler flags relating to MISRA. - toolchain_cc_warning_error_misra_sane(CC_MISRA_SANE_FLAG) - toolchain_cc_cpp_warning_error_misra_sane(CPP_MISRA_SANE_FLAG) - zephyr_compile_options($<$:${CC_MISRA_SANE_FLAG}>) - zephyr_compile_options($<$:${CPP_MISRA_SANE_FLAG}>) + zephyr_compile_options($<$:$>) + zephyr_compile_options($<$:$>) +endif() + +# This is intend to be temporary. Once we have fixed the violations that +# prevents build Zephyr, these flags shall be part of the default flags. +if(CONFIG_CODING_GUIDELINE_CHECK) + # @Intent: Obtain toolchain compiler flags relating to coding guideline + zephyr_compile_options($<$:$>) endif() # @Intent: Set compiler specific macro inclusion of AUTOCONF_H -toolchain_cc_imacros(${AUTOCONF_H}) +zephyr_compile_options("SHELL: $ ${AUTOCONF_H}") # @Intent: Set compiler specific flag for bare metal freestanding option -toolchain_cc_freestanding() +zephyr_compile_options($) # @Intent: Set compiler specific flag for tentative definitions, no-common -toolchain_cc_nocommon() +zephyr_compile_options($) # @Intent: Set compiler specific flag for production of debug information -toolchain_cc_produce_debug_info() +zephyr_compile_options($) zephyr_compile_options( ${TOOLCHAIN_C_FLAGS} ) # @Intent: Obtain compiler specific flags related to assembly -toolchain_cc_asm_base_flags(ASM_BASE_FLAG) -zephyr_compile_options( - $<$:${ASM_BASE_FLAG}> -) +# ToDo: Remember to get feedback from Oticon on this, as they might use the `ASM_BASE_FLAG` since this is done this way. +zephyr_compile_options($<$:$>) # @Intent: Enforce standard integer type correspondance to match Zephyr usage. # (must be after compiler specific flags) -toolchain_cc_imacros(${ZEPHYR_BASE}/include/toolchain/zephyr_stdint.h) +zephyr_compile_options("SHELL: $ ${ZEPHYR_BASE}/include/toolchain/zephyr_stdint.h") # Common toolchain-agnostic assembly flags zephyr_compile_options( @@ -265,7 +248,8 @@ if(CONFIG_LIB_CPLUSPLUS) endif() # @Intent: Add the basic toolchain warning flags -toolchain_cc_warning_base() +zephyr_compile_options($<$:$>) +zephyr_compile_options($<$:$>) # ========================================================================== # @@ -277,22 +261,26 @@ toolchain_cc_warning_base() # ========================================================================== # @Intent: Add cmake -DW toolchain supported warnings, if any if(W MATCHES "1") - toolchain_cc_warning_dw_1() + zephyr_compile_options($<$:$>) + zephyr_compile_options($<$:$>) endif() if(W MATCHES "2") - toolchain_cc_warning_dw_2() + zephyr_compile_options($<$:$>) + zephyr_compile_options($<$:$>) endif() if(W MATCHES "3") - toolchain_cc_warning_dw_3() + zephyr_compile_options($<$:$>) + zephyr_compile_options($<$:$>) endif() # @Intent: Add extended, more specific, toolchain warning flags -toolchain_cc_warning_extended() +zephyr_compile_options($) # @Intent: Trigger an error when a declaration does not specify a type -toolchain_cc_warning_error_implicit_int() +zephyr_compile_options($<$:$>) +zephyr_compile_options($<$:$>) # Allow the user to inject options when calling cmake, e.g. # 'cmake -DEXTRA_CFLAGS="-Werror -Wno-deprecated-declarations" ..' @@ -303,6 +291,11 @@ zephyr_cc_option(-fno-pie) zephyr_cc_option(-fno-pic) zephyr_cc_option(-fno-strict-overflow) +if(CONFIG_THREAD_LOCAL_STORAGE) +# Only support local exec TLS model at this point. +zephyr_cc_option(-ftls-model=local-exec) +endif() + if(CONFIG_OVERRIDE_FRAME_POINTER_DEFAULT) if(CONFIG_OMIT_FRAME_POINTER) zephyr_cc_option(-fomit-frame-pointer) @@ -376,13 +369,6 @@ if(NOT EXISTS ${LINKER_SCRIPT}) message(FATAL_ERROR "Could not find linker script: '${LINKER_SCRIPT}'. Corrupted configuration?") endif() -# Custom section support in linker scripts requires that the application source -# directory is in the preprocessor search path, in order to find the custom -# linker script fragments. -if(CONFIG_CUSTOM_RODATA_LD OR CONFIG_CUSTOM_RWDATA_LD OR CONFIG_CUSTOM_SECTIONS_LD) - zephyr_include_directories(${APPLICATION_SOURCE_DIR}) -endif() - configure_file(version.h.in ${PROJECT_BINARY_DIR}/include/generated/version.h) # Error-out when the deprecated naming convention is found (until @@ -462,42 +448,26 @@ add_subdirectory(subsys) add_subdirectory(drivers) # Include zephyr modules generated CMake file. -if(EXISTS ${CMAKE_BINARY_DIR}/zephyr_modules.txt) - file(STRINGS ${CMAKE_BINARY_DIR}/zephyr_modules.txt ZEPHYR_MODULES_TXT - ENCODING UTF-8) - set(module_names) - - foreach(module ${ZEPHYR_MODULES_TXT}) - # Match "":"" for each line of file, each corresponding to - # one module. The use of quotes is required due to CMake not supporting - # lazy regexes (it supports greedy only). - string(REGEX REPLACE "\"(.*)\":\".*\"" "\\1" module_name ${module}) - string(REGEX REPLACE "\".*\":\"(.*)\"" "\\1" module_path ${module}) - - list(APPEND module_names ${module_name}) - - string(TOUPPER ${module_name} MODULE_NAME_UPPER) - set(ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR ${module_path}) - set(ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR ${module_path} PARENT_SCOPE) - endforeach() - - foreach(module_name ${module_names}) - # Note the second, binary_dir parameter requires the added - # subdirectory to have its own, local cmake target(s). If not then - # this binary_dir is created but stays empty. Object files land in - # the main binary dir instead. - # https://cmake.org/pipermail/cmake/2019-June/069547.html - string(TOUPPER ${module_name} MODULE_NAME_UPPER) +foreach(module_name ${ZEPHYR_MODULE_NAMES}) + # Note the second, binary_dir parameter requires the added + # subdirectory to have its own, local cmake target(s). If not then + # this binary_dir is created but stays empty. Object files land in + # the main binary dir instead. + # https://cmake.org/pipermail/cmake/2019-June/069547.html + string(TOUPPER ${module_name} MODULE_NAME_UPPER) + if(NOT ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR} STREQUAL "") set(ZEPHYR_CURRENT_MODULE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR}) - add_subdirectory(${ZEPHYR_CURRENT_MODULE_DIR} ${CMAKE_BINARY_DIR}/modules/${module_name}) - endforeach() - # Done processing modules, clear ZEPHYR_CURRENT_MODULE_DIR. - set(ZEPHYR_CURRENT_MODULE_DIR) -endif() + set(ZEPHYR_CURRENT_CMAKE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR}) + add_subdirectory(${ZEPHYR_CURRENT_CMAKE_DIR} ${CMAKE_BINARY_DIR}/modules/${module_name}) + endif() +endforeach() +# Done processing modules, clear ZEPHYR_CURRENT_MODULE_DIR and ZEPHYR_CURRENT_CMAKE_DIR. +set(ZEPHYR_CURRENT_MODULE_DIR) +set(ZEPHYR_CURRENT_CMAKE_DIR) -set(syscall_list_h ${CMAKE_CURRENT_BINARY_DIR}/include/generated/syscall_list.h) -set(syscalls_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls.json) -set(subsys_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/subsystems.json) +set(syscall_list_h ${CMAKE_CURRENT_BINARY_DIR}/include/generated/syscall_list.h) +set(syscalls_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls.json) +set(struct_tags_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/struct_tags.json) # The syscalls subdirs txt file is constructed by python containing a list of folders to use for # dependency handling, including empty folders. @@ -589,20 +559,25 @@ endforeach() add_custom_command( OUTPUT ${syscalls_json} - ${subsys_json} + ${struct_tags_json} COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/parse_syscalls.py --include ${ZEPHYR_BASE}/include # Read files from this dir + --include ${ZEPHYR_BASE}/drivers # For net sockets + --include ${ZEPHYR_BASE}/subsys/net # More net sockets ${parse_syscalls_include_args} # Read files from these dirs also --json-file ${syscalls_json} # Write this file - --subsystem-file ${subsys_json} # Write subsystem list to this file + --tag-struct-file ${struct_tags_json} # Write subsystem list to this file DEPENDS ${syscalls_subdirs_trigger} ${PARSE_SYSCALLS_HEADER_DEPENDS} ) -add_custom_target(${SYSCALL_LIST_H_TARGET} DEPENDS ${syscall_list_h}) +add_custom_target(${SYSCALL_LIST_H_TARGET} DEPENDS ${syscall_list_h}) add_custom_target(${PARSE_SYSCALLS_TARGET} - DEPENDS ${syscalls_json} ${subsys_json}) + DEPENDS + ${syscalls_json} + ${struct_tags_json} + ) # 64-bit systems do not require special handling of 64-bit system call # parameters or return values, indicate this to the system call boilerplate @@ -628,11 +603,10 @@ add_custom_command(OUTPUT include/generated/syscall_dispatch.c ${syscall_list_h} ${SYSCALL_SPLIT_TIMEOUT_ARG} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${PARSE_SYSCALLS_TARGET} - ${syscalls_json} ) # This is passed into all calls to the gen_kobject_list.py script. -set(gen_kobject_list_include_args --include ${subsys_json}) +set(gen_kobject_list_include_args --include ${struct_tags_json}) set(DRV_VALIDATION ${PROJECT_BINARY_DIR}/include/generated/driver-validation.h) add_custom_command( @@ -646,7 +620,6 @@ add_custom_command( DEPENDS ${ZEPHYR_BASE}/scripts/gen_kobject_list.py ${PARSE_SYSCALLS_TARGET} - ${subsys_json} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) add_custom_target(${DRIVER_VALIDATION_H_TARGET} DEPENDS ${DRV_VALIDATION}) @@ -676,7 +649,7 @@ target_include_directories(${OFFSETS_LIB} PRIVATE ${ARCH_DIR}/${ARCH}/include ) target_link_libraries(${OFFSETS_LIB} zephyr_interface) -add_dependencies( ${OFFSETS_LIB} +add_dependencies(zephyr_interface ${SYSCALL_LIST_H_TARGET} ${DRIVER_VALIDATION_H_TARGET} ${KOBJ_TYPES_H_TARGET} @@ -751,18 +724,16 @@ if(CONFIG_GEN_ISR_TABLES) # isr_tables.c is generated from ${ZEPHYR_PREBUILT_EXECUTABLE} by # gen_isr_tables.py - set(obj_copy_cmd "") - bintools_objcopy( - RESULT_CMD_LIST obj_copy_cmd - TARGET_INPUT ${OUTPUT_FORMAT} - TARGET_OUTPUT "binary" - SECTION_ONLY ".intList" - FILE_INPUT $ - FILE_OUTPUT "isrList.bin" - ) add_custom_command( OUTPUT isr_tables.c - ${obj_copy_cmd} + COMMAND $ + $ + $${OUTPUT_FORMAT} + $binary + $.intList + $$ + $isrList.bin + $ COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/arch/common/gen_isr_tables.py --output-source isr_tables.c @@ -772,6 +743,7 @@ if(CONFIG_GEN_ISR_TABLES) $<$:--debug> ${GEN_ISR_TABLE_EXTRA_ARG} DEPENDS ${ZEPHYR_PREBUILT_EXECUTABLE} + COMMAND_EXPAND_LISTS ) set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_SOURCE_FILES isr_tables.c) endif() @@ -783,9 +755,9 @@ endif() if(CONFIG_USERSPACE) zephyr_get_compile_options_for_lang_as_string(C compiler_flags_priv) - string(REPLACE "-ftest-coverage" "" NO_COVERAGE_FLAGS "${compiler_flags_priv}") - string(REPLACE "-fprofile-arcs" "" NO_COVERAGE_FLAGS "${NO_COVERAGE_FLAGS}") - string(REPLACE "-fno-inline" "" NO_COVERAGE_FLAGS "${NO_COVERAGE_FLAGS}") + string(REPLACE "$" "" + NO_COVERAGE_FLAGS "${compiler_flags_priv}" + ) get_property(include_dir_in_interface TARGET zephyr_interface PROPERTY INTERFACE_INCLUDE_DIRECTORIES) @@ -891,23 +863,19 @@ if(CONFIG_USERSPACE) set(OUTPUT_OBJ_PATH ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/output_lib.dir/${OUTPUT_OBJ}) - set(obj_copy_cmd "") - set(obj_copy_sections_rename - .data=.kobject_data.data - .text=.kobject_data.text - .rodata=.kobject_data.rodata - ) - bintools_objcopy( - RESULT_CMD_LIST obj_copy_cmd - SECTION_RENAME ${obj_copy_sections_rename} - FILE_INPUT ${OUTPUT_OBJ_PATH} - FILE_OUTPUT ${OUTPUT_OBJ_RENAMED} - ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_OBJ_RENAMED} - ${obj_copy_cmd} + COMMAND $ + $ + $.data=.kobject_data.data + $.text=.kobject_data.text + $.rodata=.kobject_data.rodata + $${OUTPUT_OBJ_PATH} + $${OUTPUT_OBJ_RENAMED} + $ DEPENDS output_lib WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND_EXPAND_LISTS ) add_custom_target(output_obj_renamed DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_OBJ_RENAMED}) @@ -934,9 +902,8 @@ get_property(CSTD GLOBAL PROPERTY CSTD) set_ifndef(CSTD c99) # @Intent: Obtain compiler specific flag for specifying the c standard -toolchain_cc_cstd_flag(CC_CSTD ${CSTD}) zephyr_compile_options( - $<$:${CC_CSTD}> + $<$:$${CSTD}> ) # @Intent: Configure linker scripts, i.e. generate linker scripts with variables substituted @@ -1110,178 +1077,175 @@ set(post_build_byproducts "") list(APPEND post_build_commands COMMAND - cmake -E rename ${logical_target_for_zephyr_elf}.map ${KERNEL_MAP_NAME} + ${CMAKE_COMMAND} -E rename ${logical_target_for_zephyr_elf}.map ${KERNEL_MAP_NAME} ) if(NOT CONFIG_BUILD_NO_GAP_FILL) # Use ';' as separator to get proper space in resulting command. - set(GAP_FILL "0xff") + set(GAP_FILL "$0xff") endif() if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE) - # @Intent: Use the toolchain bintools method for printing memory usage - set(memUsageCmd "") - set(memUsageByProd "") - bintools_print_mem_usage( - RESULT_CMD_LIST memUsageCmd - RESULT_BYPROD_LIST memUsageByProd - ) - list(APPEND - post_build_commands - ${memUsageCmd} - ) - list(APPEND - post_build_byproducts - ${memUsageByProd} - ) + target_link_libraries(${ZEPHYR_PREBUILT_EXECUTABLE} $) + + get_property(memusage_build_command TARGET bintools PROPERTY memusage_command) + if(memusage_build_command) + # Note: The use of generator expressions allows downstream extensions to add/change the post build. + # Unfortunately, the BYPRODUCTS does not allow for generator expression, so question is if we + # should remove the downstream ability from start. + # Or fix the output name, by the use of `get_property` + list(APPEND + post_build_commands + COMMAND $ + $ + $${KERNEL_ELF_NAME} + ) + + # For now, the byproduct can only be supported upstream on byproducts name, + # cause byproduct does not support generator expressions + get_property(memusage_byproducts TARGET bintools PROPERTY memusage_byproducts) + list(APPEND + post_build_byproducts + ${memusage_byproducts} + ) + endif() endif() if(CONFIG_BUILD_OUTPUT_HEX OR BOARD_FLASH_RUNNER STREQUAL openocd) - set(out_hex_cmd "") - set(out_hex_byprod "") - set(out_hex_sections_remove - .comment - COMMON - .eh_frame - ) - bintools_objcopy( - RESULT_CMD_LIST out_hex_cmd - RESULT_BYPROD_LIST out_hex_byprod - STRIP_ALL - GAP_FILL ${GAP_FILL} - TARGET_OUTPUT "ihex" - SECTION_REMOVE ${out_hex_sections_remove} - FILE_INPUT ${KERNEL_ELF_NAME} - FILE_OUTPUT ${KERNEL_HEX_NAME} - ) - list(APPEND - post_build_commands - ${out_hex_cmd} - ) - list(APPEND - post_build_byproducts - ${KERNEL_HEX_NAME} - ${out_hex_byprod} - ) + get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) + if(ihex IN_LIST elfconvert_formats) + list(APPEND + post_build_commands + COMMAND $ + $ + ${GAP_FILL} + $ihex + $.comment + $COMMON + $.eh_frame + $${KERNEL_ELF_NAME} + $${KERNEL_HEX_NAME} + $ + ) + list(APPEND + post_build_byproducts + ${KERNEL_HEX_NAME} + # ${out_hex_byprod} # Is this needed ? + ) + endif() endif() if(CONFIG_BUILD_OUTPUT_BIN) - set(out_bin_cmd "") - set(out_bin_byprod "") - set(out_bin_sections_remove - .comment - COMMON - .eh_frame - ) - bintools_objcopy( - RESULT_CMD_LIST out_bin_cmd - RESULT_BYPROD_LIST out_bin_byprod - STRIP_ALL - GAP_FILL ${GAP_FILL} - TARGET_OUTPUT "binary" - SECTION_REMOVE ${out_bin_sections_remove} - FILE_INPUT ${KERNEL_ELF_NAME} - FILE_OUTPUT ${KERNEL_BIN_NAME} - ) - list(APPEND - post_build_commands - ${out_bin_cmd} - ) - list(APPEND - post_build_byproducts - ${KERNEL_BIN_NAME} - ${out_bin_byprod} - ) + get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) + if(binary IN_LIST elfconvert_formats) + list(APPEND + post_build_commands + COMMAND $ + $ + ${GAP_FILL} + $binary + $.comment + $COMMON + $.eh_frame + $${KERNEL_ELF_NAME} + $${KERNEL_BIN_NAME} + $ + ) + list(APPEND + post_build_byproducts + ${KERNEL_BIN_NAME} + # ${out_hex_byprod} # Is this needed ? + ) + endif() +endif() + + +# Cleanup intermediate files +if(CONFIG_CLEANUP_INTERMEDIATE_FILES) + list(APPEND + post_build_commands + COMMAND + # This file can be very large in some cases, delete it as we do not need it. + ${CMAKE_COMMAND} -E remove ${ZEPHYR_PREBUILT_EXECUTABLE}.elf + ) endif() if(CONFIG_BUILD_OUTPUT_S19) - set(out_S19_cmd "") - set(out_S19_byprod "") - bintools_objcopy( - RESULT_CMD_LIST out_S19_cmd - RESULT_BYPROD_LIST out_S19_byprod - GAP_FILL ${GAP_FILL} - TARGET_OUTPUT "srec" - SREC_LEN 1 - FILE_INPUT ${KERNEL_ELF_NAME} - FILE_OUTPUT ${KERNEL_S19_NAME} - ) - list(APPEND - post_build_commands - ${out_S19_cmd} - ) - list(APPEND - post_build_byproducts - ${KERNEL_S19_NAME} - ${out_S19_byprod} - ) + get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) + if(srec IN_LIST elfconvert_formats) + # Should we print a warning if case the tools does not support converting to s19 ? + list(APPEND + post_build_commands + COMMAND $ + $ + ${GAP_FILL} + $srec + $1 + $${KERNEL_ELF_NAME} + $${KERNEL_S19_NAME} + $ + ) + list(APPEND + post_build_byproducts + ${KERNEL_S19_NAME} + # ${out_S19_byprod} # Is this needed ? + + ) + endif() endif() if(CONFIG_OUTPUT_DISASSEMBLY) - set(out_disassembly_cmd "") - set(out_disassembly_byprod "") - if(CONFIG_OUTPUT_DISASSEMBLE_ALL) - set(disassembly_type DISASSEMBLE_ALL) +if(CONFIG_OUTPUT_DISASSEMBLE_ALL) + set(disassembly_type "$") else() - set(disassembly_type DISASSEMBLE_SOURCE) + set(disassembly_type "$") endif() - bintools_objdump( - RESULT_CMD_LIST out_disassembly_cmd - RESULT_BYPROD_LIST out_disassembly_byprod - ${disassembly_type} - FILE_INPUT ${KERNEL_ELF_NAME} - FILE_OUTPUT ${KERNEL_LST_NAME} - ) list(APPEND post_build_commands - ${out_disassembly_cmd} + COMMAND $ + $ + ${disassembly_type} + $${KERNEL_ELF_NAME} + $${KERNEL_LST_NAME} + $ ) list(APPEND post_build_byproducts ${KERNEL_LST_NAME} - ${out_disassembly_byprod} +# ${out_disassembly_byprod} # Needed ?? ) endif() if(CONFIG_OUTPUT_STAT) - set(out_stat_cmd "") - set(out_stat_byprod "") - bintools_readelf( - RESULT_CMD_LIST out_stat_cmd - RESULT_BYPROD_LIST out_stat_byprod - HEADERS - FILE_INPUT ${KERNEL_ELF_NAME} - FILE_OUTPUT ${KERNEL_STAT_NAME} - ) +# zephyr_post_build(TOOLS bintools COMMAND readelf FLAGS headers INFILE file OUTFILE outfile) list(APPEND post_build_commands - ${out_stat_cmd} + COMMAND $ + $ + $ + $ ${KERNEL_ELF_NAME} + $ ${KERNEL_STAT_NAME} + $ ) list(APPEND post_build_byproducts ${KERNEL_STAT_NAME} - ${out_stat_byprod} ) endif() if(CONFIG_BUILD_OUTPUT_STRIPPED) - set(out_stripped_cmd "") - set(out_stripped_byprod "") - bintools_strip( - RESULT_CMD_LIST out_stripped_cmd - RESULT_BYPROD_LIST out_stripped_byprod - STRIP_ALL - FILE_INPUT ${KERNEL_ELF_NAME} - FILE_OUTPUT ${KERNEL_STRIP_NAME} - ) list(APPEND post_build_commands - ${out_stripped_cmd} + COMMAND $ + $ + $ + $${KERNEL_ELF_NAME} + $${KERNEL_STRIP_NAME} + $ ) list(APPEND post_build_byproducts ${KERNEL_STRIP_NAME} - ${out_stripped_byprod} ) endif() @@ -1297,6 +1261,11 @@ if(CONFIG_BUILD_OUTPUT_EXE) ) endif() +# Generate and use MCUboot related artifacts as needed. +if(CONFIG_BOOTLOADER_MCUBOOT) + include(${CMAKE_CURRENT_LIST_DIR}/cmake/mcuboot.cmake) +endif() + get_property(extra_post_build_commands GLOBAL PROPERTY extra_post_build_commands @@ -1327,6 +1296,7 @@ add_custom_command( BYPRODUCTS ${post_build_byproducts} COMMENT "Generating files from ${KERNEL_ELF_NAME} for board: ${BOARD}" + COMMAND_EXPAND_LISTS # NB: COMMENT only works for some CMake-Generators ) @@ -1349,7 +1319,7 @@ if(HEX_FILES_TO_MERGE) ) add_custom_target(mergehex ALL DEPENDS ${MERGED_HEX_NAME}) - list(APPEND FLASH_DEPS mergehex) + list(APPEND RUNNERS_DEPS mergehex) message(VERBOSE "Merging hex files: ${HEX_FILES_TO_MERGE}") endif() @@ -1370,11 +1340,6 @@ add_subdirectory(cmake/flash) add_subdirectory(cmake/usage) add_subdirectory(cmake/reports) -add_subdirectory_ifdef( - CONFIG_MAKEFILE_EXPORTS - cmake/makefile_exports - ) - if(NOT CONFIG_TEST) if(CONFIG_ASSERT AND (NOT CONFIG_FORCE_NO_ASSERT)) message(WARNING "__ASSERT() statements are globally ENABLED") @@ -1415,4 +1380,12 @@ endif() # @Intent: Set compiler specific flags for standard C includes # Done at the very end, so any other system includes which may # be added by Zephyr components were first in list. -toolchain_cc_nostdinc() +# Note, the compile flags are moved, but the system include is still present here. +zephyr_compile_options($) +target_include_directories(zephyr_interface SYSTEM INTERFACE $) + +# Finally export all build flags from Zephyr +add_subdirectory_ifdef( + CONFIG_MAKEFILE_EXPORTS + cmake/makefile_exports + ) diff --git a/CODEOWNERS b/CODEOWNERS index 499e7f23601945..4ca4db31ed672f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -16,7 +16,9 @@ /.known-issues/ @nashif /.github/ @nashif /.github/workflows/ @galak @nashif -/arch/arc/ @vonhust @ruuddw +/.buildkite/ @galak +/MAINTAINERS.yml @ioannisg @MaureenHelm +/arch/arc/ @abrodkin @ruuddw /arch/arm/ @MaureenHelm @galak @ioannisg /arch/arm/core/aarch32/cortex_m/cmse/ @ioannisg /arch/arm/core/aarch64/ @carlocaione @@ -24,39 +26,48 @@ /arch/arm/include/aarch64/ @carlocaione /arch/arm/core/aarch32/cortex_a_r/ @MaureenHelm @galak @ioannisg @bbolen @stephanosio /arch/common/ @andrewboie @ioannisg @andyross -/soc/arc/snps_*/ @vonhust @ruuddw +/soc/arc/snps_*/ @abrodkin @ruuddw /soc/nios2/ @nashif @wentongwu /soc/arm/ @MaureenHelm @galak @ioannisg /soc/arm/arm/mps2/ @fvincenzo +/soc/arm/atmel_sam/common/*_sam4l_*.c @nandojve /soc/arm/atmel_sam/sam3x/ @ioannisg /soc/arm/atmel_sam/sam4e/ @nandojve +/soc/arm/atmel_sam/sam4l/ @nandojve /soc/arm/atmel_sam/sam4s/ @fallrisk /soc/arm/atmel_sam/same70/ @nandojve /soc/arm/atmel_sam/samv71/ @nandojve +/soc/arm/cypress/ @nandojve /soc/arm/bcm*/ @sbranden /soc/arm/infineon_xmc/ @parthitce /soc/arm/nxp*/ @MaureenHelm /soc/arm/nordic_nrf/ @ioannisg +/soc/arm/nuvoton/ @ssekar15 +/soc/arm/nuvoton_npcx/ @MulinChao /soc/arm/qemu_cortex_a53/ @carlocaione +/soc/arm/quicklogic_eos_s3/ @kowalewskijan @kgugala +/soc/arm/silabs_exx32/efr32mg21/ @l-alfred /soc/arm/st_stm32/ @erwango -/soc/arm/st_stm32/stm32f4/ @idlethread +/soc/arm/st_stm32/*/power.c @FRASTM /soc/arm/st_stm32/stm32mp1/ @arnopo /soc/arm/ti_simplelink/cc13x2_cc26x2/ @bwitherspoon /soc/arm/ti_simplelink/cc32xx/ @vanti /soc/arm/ti_simplelink/msp432p4xx/ @Mani-Sadhasivam /soc/arm/xilinx_zynqmp/ @stephanosio /soc/xtensa/intel_s1000/ @sathishkuttan @dcpleung -/arch/x86/ @andrewboie +/arch/x86/ @jhedberg @andrewboie @jenmwms @aasthagr /arch/nios2/ @andrewboie @wentongwu /arch/posix/ @aescolar @daor-oti /arch/riscv/ @kgugala @pgielda @nategraff-sifive /soc/posix/ @aescolar @daor-oti /soc/riscv/ @kgugala @pgielda @nategraff-sifive /soc/riscv/openisa*/ @MaureenHelm -/soc/x86/ @andrewboie +/soc/x86/ @andrewboie @jenmwms @aasthagr /arch/xtensa/ @andrewboie @dcpleung @andyross /soc/xtensa/ @andrewboie @dcpleung @andyross -/boards/arc/ @vonhust @ruuddw +/arch/sparc/ @martin-aberg +/soc/sparc/ @martin-aberg +/boards/arc/ @abrodkin @ruuddw /boards/arm/ @MaureenHelm @galak /boards/arm/96b_argonkey/ @avisconti /boards/arm/96b_avenger96/ @Mani-Sadhasivam @@ -70,7 +81,9 @@ /boards/arm/cc1352r1_launchxl/ @bwitherspoon /boards/arm/cc26x2r1_launchxl/ @bwitherspoon /boards/arm/cc3220sf_launchxl/ @vanti +/boards/arm/cy8* @nandojve /boards/arm/disco_l475_iot1/ @erwango +/boards/arm/faze/ @mbittan @simonguinot /boards/arm/frdm*/ @MaureenHelm /boards/arm/frdm*/doc/ @MaureenHelm @MeganHansen /boards/arm/google_*/ @jackrosenthal @@ -79,18 +92,24 @@ /boards/arm/ip_k66f/ @parthitce /boards/arm/lpcxpresso*/ @MaureenHelm /boards/arm/lpcxpresso*/doc/ @MaureenHelm @MeganHansen +/boards/arm/mimx8mm_evk/ @Mani-Sadhasivam /boards/arm/mimxrt*/ @MaureenHelm /boards/arm/mimxrt*/doc/ @MaureenHelm @MeganHansen /boards/arm/mps2_an385/ @fvincenzo /boards/arm/msp_exp432p401r_launchxl/ @Mani-Sadhasivam +/boards/arm/npcx7m6fb_evb/ @MulinChao /boards/arm/nrf*/ @carlescufi @lemrey @ioannisg -/boards/arm/nucleo*/ @erwango +/boards/arm/nucleo*/ @erwango @ABOSTM @FRASTM /boards/arm/nucleo_f401re/ @idlethread +/boards/arm/nuvoton_pfm_m487/ @ssekar15 /boards/arm/qemu_cortex_a53/ @carlocaione /boards/arm/qemu_cortex_r*/ @stephanosio /boards/arm/qemu_cortex_m*/ @ioannisg +/boards/arm/quick_feather/ @kowalewskijan @kgugala +/boards/arm/rak5010_nrf52840/ @gpaquet85 /boards/arm/xmc45_relax_kit/ @parthitce /boards/arm/sam4e_xpro/ @nandojve +/boards/arm/sam4l_ek/ @nandojve /boards/arm/sam4s_xplained/ @fallrisk /boards/arm/sam_e70_xplained/ @nandojve /boards/arm/sam_v71_xult/ @nandojve @@ -99,9 +118,9 @@ /boards/arm/sensortile_box/ @avisconti /boards/arm/steval_fcu001v1/ @Navin-Sankar /boards/arm/stm32l1_disco/ @karlp -/boards/arm/stm32*_disco/ @erwango +/boards/arm/stm32*_disco/ @erwango @ABOSTM @FRASTM /boards/arm/stm32f3_disco/ @ydamigos -/boards/arm/stm32*_eval/ @erwango +/boards/arm/stm32*_eval/ @erwango @ABOSTM @FRASTM /boards/common/ @mbolivar-nordic /boards/deprecated.cmake @tejlmand /boards/nios2/ @wentongwu @@ -112,12 +131,17 @@ /boards/riscv/ @kgugala @pgielda @nategraff-sifive /boards/riscv/rv32m1_vega/ @MaureenHelm /boards/shields/ @erwango -/boards/x86/ @andrewboie @nashif +/boards/shields/atmel_rf2xx/ @nandojve +/boards/shields/esp_8266/ @nandojve +/boards/shields/inventek_eswifi/ @nandojve +/boards/x86/ @andrewboie @nashif @jenmwms @aasthagr /boards/xtensa/ @nashif @dcpleung /boards/xtensa/intel_s1000_crb/ @sathishkuttan @dcpleung /boards/xtensa/odroid_go/ @ydamigos +/boards/sparc/ @martin-aberg # All cmake related files /cmake/ @tejlmand @nashif +/cmake/*/arcmwdt/ @abrodkin @evgeniy-paltsev @tejlmand /CMakeLists.txt @tejlmand @nashif /doc/ @dbkinder /doc/guides/coccinelle.rst @himanshujha199640 @JuliaLawall @@ -129,18 +153,25 @@ /doc/reference/devicetree/ @galak @mbolivar-nordic /doc/reference/resource_management/ @pabigot /doc/reference/networking/can* @alexanderwachter +/doc/security/ @ceolin @d3zd3z /drivers/debug/ @nashif +/drivers/*/*sam4l* @nandojve /drivers/*/*cc13xx_cc26xx* @bwitherspoon +/drivers/*/*litex* @mateusz-holenko @kgugala @pgielda /drivers/*/*mcux* @MaureenHelm -/drivers/*/*stm32* @erwango +/drivers/*/*stm32* @erwango @ABOSTM @FRASTM /drivers/*/*native_posix* @aescolar @daor-oti +/drivers/*/*lpc11u6x* @mbittan @simonguinot +/drivers/*/*npcx* @MulinChao /drivers/adc/ @anangl /drivers/adc/adc_stm32.c @cybertale /drivers/bluetooth/ @joerchan @jhedberg @Vudentz /drivers/can/ @alexanderwachter /drivers/can/*mcp2515* @karstenkoenig /drivers/clock_control/*nrf* @nordic-krch +/drivers/clock_control/*esp32* @extremegtx /drivers/counter/ @nordic-krch +/drivers/console/ipm_console.c @finikorg /drivers/console/semihost_console.c @luozhongyao /drivers/counter/counter_cmos.c @andrewboie /drivers/counter/maxim_ds3231.c @pabigot @@ -151,51 +182,62 @@ /drivers/dac/ @martinjaeger /drivers/dma/*dw* @tbursztyka /drivers/dma/*sam0* @Sizurka -/drivers/dma/dma_stm32* @cybertale +/drivers/dma/dma_stm32* @cybertale @lowlander +/drivers/dma/*pl330* @raveenp +/drivers/ec_host_cmd_periph/ @jettr /drivers/eeprom/ @henrikbrixandersen /drivers/eeprom/eeprom_stm32.c @KwonTae-young /drivers/entropy/*rv32m1* @MaureenHelm /drivers/entropy/*gecko* @chrta +/drivers/entropy/*litex* @mateusz-holenko @kgugala @pgielda /drivers/espi/ @albertofloyd @franciscomunoz @scottwcpg -/drivers/ps2/ @albertofloyd @franciscomunoz @scottwcpg -/drivers/kscan/ @albertofloyd @franciscomunoz @scottwcpg -/drivers/peci/ @albertofloyd @franciscomunoz @scottwcpg /drivers/ethernet/ @jukkar @tbursztyka @pfalcon -/drivers/entropy/*litex* @mateusz-holenko @kgugala @pgielda +/drivers/ethernet/*stm32* @Nukersson @lochej +/drivers/ethernet/*w5500* @parthitce /drivers/flash/ @nashif @nvlsianpu /drivers/flash/*nrf* @nvlsianpu /drivers/flash/*spi_nor* @pabigot -/drivers/flash/*stm32* @superna9999 /drivers/gpio/ @mnkp @pabigot /drivers/gpio/*ht16k33* @henrikbrixandersen /drivers/gpio/*lmp90xxx* @henrikbrixandersen /drivers/gpio/*stm32* @erwango /drivers/gpio/*sx1509b* @pabigot -/drivers/gpio/*litex* @mateusz-holenko @kgugala @pgielda /drivers/hwinfo/ @alexanderwachter -/drivers/i2c/*litex* @mateusz-holenko @kgugala @pgielda /drivers/i2s/i2s_ll_stm32* @avisconti +/drivers/i2c/i2c_common.c @sjg20 +/drivers/i2c/i2c_emul.c @sjg20 /drivers/i2c/i2c_shell.c @nashif +/drivers/i2c/Kconfig.i2c_emul @sjg20 +/drivers/i2s/*litex* @mateusz-holenko @kgugala @pgielda /drivers/ieee802154/ @jukkar @tbursztyka /drivers/ieee802154/ieee802154_rf2xx* @jukkar @tbursztyka @nandojve +/drivers/ieee802154/ieee802154_cc13xx* @bwitherspoon @cfriedt /drivers/interrupt_controller/ @andrewboie /drivers/interrupt_controller/intc_gic.c @stephanosio -/drivers/*/intc_vexriscv_litex.c @mateusz-holenko @kgugala @pgielda /drivers/ipm/ipm_mhu* @karl-zh /drivers/ipm/Kconfig.nrfx @masz-nordic @ioannisg /drivers/ipm/Kconfig.nrfx_ipc_channel @masz-nordic @ioannisg +/drivers/ipm/ipm_intel_adsp.c @finikorg /drivers/ipm/ipm_cavs_idc* @dcpleung /drivers/ipm/ipm_nrfx_ipc.c @masz-nordic @ioannisg /drivers/ipm/ipm_nrfx_ipc.h @masz-nordic @ioannisg /drivers/ipm/ipm_stm32_ipcc.c @arnopo +/drivers/kscan/ @albertofloyd @franciscomunoz @scottwcpg /drivers/led/ @Mani-Sadhasivam /drivers/led_strip/ @mbolivar-nordic /drivers/lora/ @Mani-Sadhasivam -/drivers/modem/ @mike-scott +/drivers/memc/ @gmarull +/drivers/modem/*gsm* @jukkar +/drivers/modem/hl7800.c @rerickson1 +/drivers/modem/Kconfig.hl7800 @rerickson1 /drivers/pcie/ @andrewboie -/drivers/pinmux/stm32/ @idlethread +/drivers/peci/ @albertofloyd @franciscomunoz @scottwcpg /drivers/pinmux/*hsdk* @iriszzw -/drivers/pwm/*litex* @mateusz-holenko @kgugala @pgielda +/drivers/ps2/ @albertofloyd @franciscomunoz @scottwcpg +/drivers/pwm/*sam0* @nzmichaelh +/drivers/pwm/*stm32* @gmarull +/drivers/pwm/*xlnx* @henrikbrixandersen +/drivers/regulator/ @pabigot /drivers/sensor/ @MaureenHelm /drivers/sensor/ams_iAQcore/ @alexanderwachter /drivers/sensor/ens210/ @alexanderwachter @@ -203,37 +245,42 @@ /drivers/sensor/lis*/ @avisconti /drivers/sensor/lps*/ @avisconti /drivers/sensor/lsm*/ @avisconti +/drivers/sensor/mpr/ @sven-hm /drivers/sensor/st*/ @avisconti /drivers/serial/uart_altera_jtag_hal.c @wentongwu -/drivers/serial/*ns16550* @andrewboie +/drivers/serial/*ns16550* @andrewboie @jenmwms @aasthagr /drivers/serial/*nrfx* @Mierunski @anangl -/drivers/serial/Kconfig.litex @mateusz-holenko @kgugala @pgielda /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 /drivers/serial/uart_rtt.c @carlescufi @pkral78 /drivers/serial/Kconfig.xlnx @wjliang /drivers/serial/uart_xlnx_ps.c @wjliang +/drivers/serial/uart_xlnx_uartlite.c @henrikbrixandersen /drivers/serial/*xmc4xxx* @parthitce +/drivers/serial/*nuvoton* @ssekar15 +/drivers/serial/*apbuart* @martin-aberg /drivers/net/ @jukkar @tbursztyka /drivers/ptp_clock/ @jukkar /drivers/pwm/*rv32m1* @henrikbrixandersen /drivers/pwm/pwm_shell.c @henrikbrixandersen /drivers/spi/ @tbursztyka -/drivers/spi/spi_ll_stm32.* @superna9999 /drivers/spi/spi_rv32m1_lpspi* @karstenkoenig /drivers/timer/apic_timer.c @andrewboie /drivers/timer/arm_arch_timer.c @carlocaione /drivers/timer/cortex_m_systick.c @ioannisg /drivers/timer/altera_avalon_timer_hal.c @wentongwu /drivers/timer/riscv_machine_timer.c @nategraff-sifive @kgugala @pgielda -/drivers/timer/litex_timer.c @mateusz-holenko @kgugala @pgielda /drivers/timer/xlnx_psttc_timer* @wjliang @stephanosio /drivers/timer/cc13x2_cc26x2_rtc_timer.c @vanti /drivers/timer/cavs_timer.c @dcpleung -/drivers/usb/ @jfischer-phytec-iot @finikorg +/drivers/timer/stm32_lptim_timer.c @FRASTM +/drivers/timer/leon_gptimer.c @martin-aberg +/drivers/usb/ @jfischer-no @finikorg /drivers/usb/device/usb_dc_stm32.c @ydamigos @loicpoulain /drivers/video/ @loicpoulain -/drivers/i2c/i2c_ll_stm32* @ldts @ydamigos +/drivers/i2c/i2c_ll_stm32* @ydamigos /drivers/i2c/i2c_rv32m1_lpi2c* @henrikbrixandersen /drivers/i2c/*sam0* @Sizurka /drivers/i2c/i2c_dw* @dcpleung @@ -241,9 +288,11 @@ /drivers/watchdog/*gecko* @oanerer /drivers/watchdog/wdt_handlers.c @andrewboie /drivers/wifi/ @jukkar @tbursztyka @pfalcon -/drivers/wifi/eswifi/ @loicpoulain -/dts/arc/ @vonhust @ruuddw @iriszzw +/drivers/wifi/eswifi/ @loicpoulain @nandojve +/drivers/wifi/winc1500/ @kludentwo +/dts/arc/ @abrodkin @ruuddw @iriszzw /dts/arm/atmel/sam4e* @nandojve +/dts/arm/atmel/sam4l* @nandojve /dts/arm/atmel/samr21.dtsi @benpicco /dts/arm/atmel/sam*5*.dtsi @benpicco /dts/arm/atmel/same70* @nandojve @@ -252,11 +301,14 @@ /dts/arm/broadcom/ @sbranden /dts/arm/infineon/ @parthitce /dts/arm/qemu-virt/ @carlocaione +/dts/arm/quicklogic/ @wtatarski @kowalewskijan @kgugala /dts/arm/st/ @erwango /dts/arm/ti/cc13?2* @bwitherspoon /dts/arm/ti/cc26?2* @bwitherspoon /dts/arm/ti/cc3235* @vanti /dts/arm/nordic/ @ioannisg @carlescufi +/dts/arm/nuvoton/ @ssekar15 +/dts/arm/nuvoton/npcx/ @MulinChao /dts/arm/nxp/ @MaureenHelm /dts/arm/microchip/ @franciscomunoz @albertofloyd @scottwcpg /dts/arm/silabs/efm32gg11b* @oanerer @@ -264,6 +316,7 @@ /dts/arm/silabs/efr32bg13p* @mnkp /dts/arm/silabs/efm32jg12b* @chrta /dts/arm/silabs/efm32pg12b* @chrta +/dts/arm/silabs/efr32mg21* @l-alfred /dts/riscv/microsemi-miv.dtsi @galak /dts/riscv/rv32m1* @MaureenHelm /dts/riscv/riscv32-fe310.dtsi @nategraff-sifive @@ -271,12 +324,17 @@ /dts/arm/armv7-r.dtsi @bbolen @stephanosio /dts/arm/armv8-a.dtsi @carlocaione /dts/arm/xilinx/ @bbolen @stephanosio +/dts/x86/ @jhedberg /dts/xtensa/xtensa.dtsi @ydamigos /dts/xtensa/intel/ @dcpleung +/dts/sparc/ @martin-aberg /dts/bindings/ @galak /dts/bindings/can/ @alexanderwachter -/dts/bindings/iio/adc/st*stm32-adc.yaml @cybertale +/dts/bindings/i2c/zephyr*i2c-emul.yaml @sjg20 +/dts/bindings/adc/st*stm32-adc.yaml @cybertale +/dts/bindings/modem/*hl7800.yaml @rerickson1 /dts/bindings/serial/ns16550.yaml @andrewboie +/dts/bindings/*/*npcx* @MulinChao /dts/bindings/*/nordic* @anangl /dts/bindings/*/nxp* @MaureenHelm /dts/bindings/*/openisa* @MaureenHelm @@ -289,6 +347,7 @@ /dts/bindings/sensor/*bme680* @BoschSensortec /dts/bindings/sensor/st* @avisconti /include/ @nashif @carlescufi @galak @MaureenHelm +/include/drivers/*/*litex* @mateusz-holenko @kgugala @pgielda /include/drivers/adc.h @anangl /include/drivers/can.h @alexanderwachter /include/drivers/counter.h @nordic-krch @@ -297,9 +356,11 @@ /include/drivers/espi.h @albertofloyd @franciscomunoz @scottwcpg /include/drivers/bluetooth/ @joerchan @jhedberg @Vudentz /include/drivers/flash.h @nashif @carlescufi @galak @MaureenHelm @nvlsianpu +/include/drivers/i2c_emul.h @sjg20 /include/drivers/led/ht16k33.h @henrikbrixandersen /include/drivers/interrupt_controller/ @andrewboie /include/drivers/interrupt_controller/gic.h @stephanosio +/include/drivers/modem/hl7800.h @rerickson1 /include/drivers/pcie/ @andrewboie /include/drivers/hwinfo.h @alexanderwachter /include/drivers/led.h @Mani-Sadhasivam @@ -309,7 +370,7 @@ /include/drivers/lora.h @Mani-Sadhasivam /include/drivers/peci.h @albertofloyd @franciscomunoz @scottwcpg /include/app_memory/ @andrewboie -/include/arch/arc/ @vonhust @ruuddw +/include/arch/arc/ @abrodkin @ruuddw /include/arch/arc/arch.h @andrewboie /include/arch/arc/v2/irq.h @andrewboie /include/arch/arm/aarch32/ @MaureenHelm @galak @ioannisg @@ -323,12 +384,15 @@ /include/arch/x86/ @andrewboie @wentongwu /include/arch/common/ @andrewboie @andyross @nashif /include/arch/xtensa/ @andrewboie +/include/arch/sparc/ @martin-aberg /include/sys/atomic.h @andrewboie @andyross /include/bluetooth/ @joerchan @jhedberg @Vudentz /include/cache.h @andrewboie @andyross /include/canbus/ @alexanderwachter /include/tracing/ @wentongwu @nashif /include/debug/ @nashif +/include/debug/coredump.h @dcpleung +/include/debug/gdbstub.h @ceolin /include/device.h @wentongwu @nashif /include/devicetree.h @galak /include/display/ @vanwinkeljan @@ -337,6 +401,7 @@ /include/dt-bindings/dma/stm32_dma.h @cybertale /include/dt-bindings/pcie/ @andrewboie /include/dt-bindings/usb/usb.h @galak @finikorg +/include/emul.h @sjg20 /include/fs/ @nashif @wentongwu /include/init.h @andrewboie @andyross /include/irq.h @andrewboie @andyross @@ -346,16 +411,22 @@ /include/linker/app_smem*.ld @andrewboie /include/linker/ @andrewboie @andyross /include/logging/ @nordic-krch +/include/lorawan/lorawan.h @Mani-Sadhasivam +/include/mgmt/osdp.h @cbsiddharth /include/net/ @jukkar @tbursztyka @pfalcon /include/net/buf.h @jukkar @jhedberg @tbursztyka @pfalcon +/include/net/coap*.h @jukkar @rlubos +/include/net/lwm2m*.h @jukkar @rlubos +/include/net/mqtt.h @jukkar @rlubos /include/posix/ @pfalcon -/include/power/power.h @wentongwu @nashif +/include/power/power.h @wentongwu @nashif @ceolin /include/ptp_clock.h @jukkar /include/shared_irq.h @andrewboie @andyross /include/shell/ @jakub-uC @nordic-krch /include/sw_isr_table.h @andrewboie @andyross /include/sys_clock.h @andrewboie @andyross /include/sys/sys_io.h @andrewboie @andyross +/include/sys/kobject.h @andrewboie /include/toolchain.h @andrewboie @andyross @nashif /include/toolchain/ @andrewboie @andyross /include/zephyr.h @andrewboie @andyross @@ -369,55 +440,65 @@ /lib/cmsis_rtos_v1/ @nashif /lib/libc/ @nashif @andrewboie /modules/ @nashif +/modules/Kconfig.tfm @ioannisg @microbuilder /kernel/device.c @andrewboie @andyross @nashif /kernel/idle.c @andrewboie @andyross @nashif /samples/ @nashif /samples/basic/minimal/ @carlescufi /samples/basic/servo_motor/boards/*microbit* @jhe -/lib/updatehub/ @nandojve @otavio /samples/bluetooth/ @jhedberg @Vudentz @joerchan /samples/boards/intel_s1000_crb/ @sathishkuttan @dcpleung @nashif /samples/display/ @vanwinkeljan /samples/drivers/can/ @alexanderwachter +/samples/drivers/clock_control_litex/ @mateusz-holenko @kgugala @pgielda /samples/drivers/display/ @vanwinkeljan /samples/drivers/ht16k33/ @henrikbrixandersen /samples/drivers/lora/ @Mani-Sadhasivam /samples/drivers/counter/maxim_ds3231/ @pabigot +/samples/lorawan/ @Mani-Sadhasivam /samples/net/ @jukkar @tbursztyka @pfalcon +/samples/net/cloud/tagoio_http_post/ @nandojve /samples/net/dns_resolve/ @jukkar @tbursztyka @pfalcon /samples/net/lwm2m_client/ @rlubos /samples/net/mqtt_publisher/ @jukkar @tbursztyka -/samples/net/sockets/coap_*/ @rveerama1 +/samples/net/sockets/coap_*/ @rlubos /samples/net/sockets/ @jukkar @tbursztyka @pfalcon -/samples/net/updatehub/ @nandojve @otavio +/samples/net/*civetweb* @Nukersson /samples/sensor/ @MaureenHelm /samples/shields/ @avisconti /samples/subsys/logging/ @nordic-krch @jakub-uC /samples/subsys/shell/ @jakub-uC @nordic-krch /samples/subsys/mgmt/mcumgr/smp_svr/ @aunsbjerg @nvlsianpu -/samples/subsys/usb/ @jfischer-phytec-iot @finikorg -/samples/subsys/power/ @wentongwu @pabigot +/samples/subsys/mgmt/updatehub/ @nandojve @otavio +/samples/subsys/mgmt/osdp/ @cbsiddharth +/samples/subsys/usb/ @jfischer-no @finikorg +/samples/subsys/power/ @wentongwu @pabigot @ceolin +/samples/tfm_integration/ @ioannisg @microbuilder /samples/userspace/ @andrewboie /scripts/coccicheck @himanshujha199640 @JuliaLawall /scripts/coccinelle/ @himanshujha199640 @JuliaLawall +/scripts/coredump/ @dcpleung /scripts/kconfig/ @ulfalizer -/scripts/sanity_chk/expr_parser.py @nashif +/scripts/pylib/twister/expr_parser.py @nashif +/scripts/schemas/twister/ @nashif /scripts/gen_app_partitions.py @andrewboie -/scripts/dts/ @ulfalizer @galak +/scripts/get_maintainer.py @nashif +/scripts/dts/ @mbolivar-nordic @galak /scripts/release/ @nashif /scripts/ci/ @nashif /arch/x86/gen_gdt.py @andrewboie /arch/x86/gen_idt.py @andrewboie /scripts/gen_kobject_list.py @andrewboie /scripts/gen_syscalls.py @andrewboie -/scripts/net/ @jukkar @pfl +/scripts/net/ @jukkar /scripts/process_gperf.py @andrewboie /scripts/gen_relocate_app.py @wentongwu -/scripts/requirements*.txt @mbolivar @galak @nashif -/scripts/tests/sanitycheck/ @aasthagr +/scripts/requirements*.txt @mbolivar-nordic @galak @nashif +/scripts/tests/twister/ @aasthagr +/scripts/tests/build/test_subfolder_list.py @rmstoi /scripts/tracing/ @wentongwu -/scripts/sanity_chk/ @nashif -/scripts/sanitycheck @nashif +/scripts/pylib/twister/ @nashif +/scripts/twister @nashif /scripts/series-push-hook.sh @erwango /scripts/west_commands/ @mbolivar-nordic /scripts/west-commands.yml @mbolivar-nordic @@ -427,11 +508,14 @@ /share/zephyr-package/ @tejlmand /share/zephyrunittest-package/ @tejlmand /subsys/bluetooth/ @joerchan @jhedberg @Vudentz -/subsys/bluetooth/controller/ @carlescufi @cvinayak @thoh-ot +/subsys/bluetooth/controller/ @carlescufi @cvinayak @thoh-ot @kruithofa /subsys/bluetooth/mesh/ @jhedberg @trond-snekvik @joerchan @Vudentz /subsys/canbus/ @alexanderwachter /subsys/cpp/ @pabigot @vanwinkeljan /subsys/debug/ @nashif +/subsys/debug/coredump/ @dcpleung +/subsys/debug/gdbstub/ @ceolin +/subsys/debug/gdbstub.c @ceolin /subsys/dfu/ @nvlsianpu /subsys/tracing/ @nashif @wentongwu /subsys/debug/asan_hacks.c @vanwinkeljan @aescolar @daor-oti @@ -439,7 +523,8 @@ /subsys/disk/disk_access_sdhc.h @JunYangNXP /subsys/disk/disk_access_usdhc.c @JunYangNXP /subsys/disk/disk_access_stm32_sdmmc.c @anthonybrandon -/subsys/fb/ @jfischer-phytec-iot +/subsys/emul/ @sjg20 +/subsys/fb/ @jfischer-no /subsys/fs/ @nashif /subsys/fs/fcb/ @nvlsianpu /subsys/fs/fuse_fs_access.c @vanwinkeljan @@ -447,29 +532,37 @@ /subsys/fs/nvs/ @Laczen /subsys/logging/ @nordic-krch /subsys/logging/log_backend_net.c @nordic-krch @jukkar -/subsys/mgmt/ @carlescufi @nvlsianpu -/subsys/mgmt/smp_udp.c @aunsbjerg +/subsys/lorawan/ @Mani-Sadhasivam +/subsys/mgmt/ec_host_cmd/ @jettr +/subsys/mgmt/mcumgr/ @carlescufi @nvlsianpu +/subsys/mgmt/hawkbit/ @Navin-Sankar +/subsys/mgmt/mcumgr/smp_udp.c @aunsbjerg +/subsys/mgmt/updatehub/ @nandojve @otavio +/subsys/mgmt/osdp/ @cbsiddharth /subsys/net/buf.c @jukkar @jhedberg @tbursztyka @pfalcon /subsys/net/ip/ @jukkar @tbursztyka @pfalcon /subsys/net/lib/ @jukkar @tbursztyka @pfalcon -/subsys/net/lib/dns/ @jukkar @tbursztyka @pfalcon +/subsys/net/lib/dns/ @jukkar @tbursztyka @pfalcon @cfriedt /subsys/net/lib/lwm2m/ @rlubos /subsys/net/lib/config/ @jukkar @tbursztyka @pfalcon /subsys/net/lib/mqtt/ @jukkar @tbursztyka @rlubos -/subsys/net/lib/coap/ @rveerama1 +/subsys/net/lib/coap/ @rlubos /subsys/net/lib/sockets/socketpair.c @cfriedt /subsys/net/lib/sockets/ @jukkar @tbursztyka @pfalcon /subsys/net/lib/tls_credentials/ @rlubos /subsys/net/l2/ @jukkar @tbursztyka /subsys/net/l2/canbus/ @alexanderwachter @jukkar /subsys/net/*/openthread/ @rlubos -/subsys/power/ @wentongwu @pabigot +/subsys/power/ @wentongwu @pabigot @ceolin /subsys/random/ @dleach02 /subsys/settings/ @nvlsianpu /subsys/shell/ @jakub-uC @nordic-krch +/subsys/stats/ @nvlsianpu /subsys/storage/ @nvlsianpu /subsys/testsuite/ @nashif -/subsys/usb/ @jfischer-phytec-iot @finikorg +/subsys/timing/ @nashif @dcpleung +/subsys/usb/ @jfischer-no @finikorg +/subsys/usb/class/usb_dfu.c @nvlsianpu /tests/ @nashif /tests/application_development/libcxx/ @pabigot /tests/arch/arm/ @ioannisg @stephanosio @@ -484,6 +577,7 @@ /tests/drivers/can/ @alexanderwachter /tests/drivers/counter/ @nordic-krch /tests/drivers/counter/maxim_ds3231_api/ @pabigot +/tests/drivers/eeprom/ @henrikbrixandersen @sjg20 /tests/drivers/flash_simulator/ @nvlsianpu /tests/drivers/gpio/ @mnkp @pabigot /tests/drivers/hwinfo/ @alexanderwachter @@ -497,12 +591,14 @@ /tests/net/lib/ @jukkar @tbursztyka @pfalcon /tests/net/lib/http_header_fields/ @jukkar @tbursztyka /tests/net/lib/mqtt_packet/ @jukkar @tbursztyka -/tests/net/lib/coap/ @rveerama1 +/tests/net/lib/coap/ @rlubos /tests/net/socket/socketpair/ @cfriedt /tests/net/socket/ @jukkar @tbursztyka @pfalcon +/tests/subsys/debug/coredump/ @dcpleung /tests/subsys/fs/ @nashif @wentongwu /tests/subsys/settings/ @nvlsianpu /tests/subsys/shell/ @jakub-uC @nordic-krch # Get all docs reviewed *.rst @nashif +/doc/reference/kernel/ @andrewboie @andyross @nashif *posix*.rst @aescolar @daor-oti diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 4043e771104c2b..2f5093bed4d71a 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -4,12 +4,6 @@ # Copyright (c) 2016 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -menu "Modules" - -source "$(CMAKE_BINARY_DIR)/Kconfig.modules" -source "modules/Kconfig" - -endmenu # Include Kconfig.defconfig files first so that they can override defaults and # other symbol/choice properties by adding extra symbol/choice definitions. @@ -20,12 +14,19 @@ endmenu # precedence over SoC defaults, so include them in that order. # # $ARCH and $BOARD_DIR will be glob patterns when building documentation. -source "boards/shields/*/Kconfig.defconfig" +source "$(KCONFIG_BINARY_DIR)/Kconfig.shield.defconfig" source "$(BOARD_DIR)/Kconfig.defconfig" -source "$(SOC_DIR)/$(ARCH)/*/Kconfig.defconfig" +source "$(KCONFIG_BINARY_DIR)/Kconfig.soc.defconfig" + +menu "Modules" + +source "$(KCONFIG_BINARY_DIR)/Kconfig.modules" +source "modules/Kconfig" + +endmenu source "boards/Kconfig" -source "$(SOC_DIR)/Kconfig" +source "soc/Kconfig" source "arch/Kconfig" source "kernel/Kconfig" source "dts/Kconfig" @@ -118,15 +119,15 @@ config FLASH_LOAD_SIZE endif # HAS_FLASH_LOAD_OFFSET -config TEXT_SECTION_OFFSET +config ROM_START_OFFSET hex - prompt "TEXT section offset" if !BOOTLOADER_MCUBOOT + prompt "ROM start offset" if !BOOTLOADER_MCUBOOT default 0x200 if BOOTLOADER_MCUBOOT default 0 help If the application is built for chain-loading by a bootloader this variable is required to be set to value that leaves sufficient - space between the beginning of the image and the start of the .text + space between the beginning of the image and the start of the first section to store an image header or any other metadata. In the particular case of the MCUboot bootloader this reserves enough space to store the image header, which should also meet vector table @@ -153,27 +154,6 @@ config CUSTOM_LINKER_SCRIPT linker script and avoid having to change the script provided by Zephyr. -config CUSTOM_RODATA_LD - bool "(DEPRECATED) Include custom-rodata.ld" - help - Note: This is deprecated, use Cmake function zephyr_linker_sources() instead. - Include a customized linker script fragment for inserting additional - data and linker directives into the rodata section. - -config CUSTOM_RWDATA_LD - bool "(DEPRECATED) Include custom-rwdata.ld" - help - Note: This is deprecated, use Cmake function zephyr_linker_sources() instead. - Include a customized linker script fragment for inserting additional - data and linker directives into the data section. - -config CUSTOM_SECTIONS_LD - bool "(DEPRECATED) Include custom-sections.ld" - help - Note: This is deprecated, use Cmake function zephyr_linker_sources() instead. - Include a customized linker script fragment for inserting additional - arbitrary sections. - config KERNEL_ENTRY string "Kernel entry symbol" default "__start" @@ -192,6 +172,12 @@ endmenu menu "Compiler Options" +config CODING_GUIDELINE_CHECK + bool "Enforce coding guideline rules" + help + Use available compiler flags to check coding guideline rules during + the build. + config NATIVE_APPLICATION bool "Build as a native host application" help @@ -310,39 +296,46 @@ config OUTPUT_PRINT_MEMORY_USAGE ram_report and https://sourceware.org/binutils/docs/ld/MEMORY.html +config CLEANUP_INTERMEDIATE_FILES + bool "Remove all intermediate files" + help + Delete intermediate files to save space and cleanup clutter resulting + from the build process. + +config BUILD_NO_GAP_FILL + bool "Don't fill gaps in generated hex/bin/s19 files." + config BUILD_OUTPUT_HEX bool "Build a binary in HEX format" help - Build a binary in HEX format. This will build a zephyr.hex file need - by some platforms. + Build an Intel HEX binary zephyr/zephyr.hex in the build directory. + The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. config BUILD_OUTPUT_BIN bool "Build a binary in BIN format" default y help - Build a binary in BIN format. This will build a zephyr.bin file need - by some platforms. + Build a "raw" binary zephyr/zephyr.bin in the build directory. + The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. config BUILD_OUTPUT_EXE bool "Build a binary in ELF format with .exe extension" help - Build a binary in ELF format that can run in the host system. This - will build a zephyr.exe file. + Build an ELF binary that can run in the host system at + zephyr/zephyr.exe in the build directory. + The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. config BUILD_OUTPUT_S19 bool "Build a binary in S19 format" help - Build a binary in S19 format. This will build a zephyr.s19 file need - by some platforms. - -config BUILD_NO_GAP_FILL - bool "Don't fill gaps in generated hex/bin/s19 files." + Build an S19 binary zephyr/zephyr.s19 in the build directory. + The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. config BUILD_OUTPUT_STRIPPED bool "Build a stripped binary" help - Build a stripped binary. This will build a zephyr.stripped file need - by some platforms. + Build a stripped binary zephyr/zephyr.strip in the build directory. + The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. config APPLICATION_DEFINED_SYSCALL bool "Scan application folder for any syscall definition" @@ -356,12 +349,12 @@ config MAKEFILE_EXPORTS Generates a file with build information that can be read by third party Makefile-based build systems. -config LEGACY_DEVICETREE_MACROS - bool "Allow use of legacy devicetree macros" +config DEPRECATED_ZEPHYR_INT_TYPES + bool "Allow the use of the deprecated zephyr integer types" help - Allows use of legacy devicetree macros which were used in - Zephyr 2.2 and previous versions, rather than the devicetree.h - API introduced during the Zephyr 2.3 development cycle. + Allows the use of the deprecated Zephyr integer typedefs defined in + Zephyr 2.3 and previous versions. These types are: + u8_t, u16_t, u32_t, u64_t, s8_t, s16_t, s32_t, and s64_t. endmenu endmenu @@ -392,6 +385,7 @@ config BOOTLOADER_SRAM_SIZE config BOOTLOADER_MCUBOOT bool "MCUboot bootloader support" select USE_DT_CODE_PARTITION + imply INIT_ARCH_HW_AT_BOOT if ARCH_SUPPORTS_ARCH_HW_INIT help This option signifies that the target uses MCUboot as a bootloader, or in other words that the image is to be chain-loaded by MCUboot. @@ -399,10 +393,65 @@ config BOOTLOADER_MCUBOOT order for the image generated to be bootable using the MCUboot open source bootloader. Currently this includes: - * Setting TEXT_SECTION_OFFSET to a default value that allows space + * Setting ROM_START_OFFSET to a default value that allows space for the MCUboot image header - * Activating SW_VECTOR_RELAY on Cortex-M0 (or Armv8-M baseline) - targets with no built-in vector relocation mechanisms + * Activating SW_VECTOR_RELAY_CLIENT on Cortex-M0 + (or Armv8-M baseline) targets with no built-in vector relocation + mechanisms + + By default, this option instructs Zephyr to initialize the core + architecture HW registers during boot, when this is supported by + the application. This removes the need by MCUboot to reset + the core registers' state itself. + +if BOOTLOADER_MCUBOOT + +config MCUBOOT_SIGNATURE_KEY_FILE + string "Path to the mcuboot signing key file" + default "" + help + The file contains a key pair whose public half is verified + by your target's MCUboot image. The file is in PEM format. + + If set to a non-empty value, the build system tries to + sign the final binaries using a 'west sign -t imgtool' command. + The signed binaries are placed in the build directory + at zephyr/zephyr.signed.bin and zephyr/zephyr.signed.hex. + + The file names can be customized with CONFIG_KERNEL_BIN_NAME. + The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN + and CONFIG_BUILD_OUTPUT_HEX. + + This option should contain an absolute path to the same file + as the BOOT_SIGNATURE_KEY_FILE option in your MCUboot + .config. (The MCUboot config option is used for the MCUboot + bootloader image; this option is for your application which + is to be loaded by MCUboot. The MCUboot config option can be + a relative path from the MCUboot repository root; this option's + behavior is undefined for relative paths.) + + If left empty, you must sign the Zephyr binaries manually. + +config MCUBOOT_EXTRA_IMGTOOL_ARGS + string "Extra arguments to pass to imgtool" + default "" + help + If CONFIG_MCUBOOT_SIGNATURE_KEY_FILE is a non-empty string, + you can use this option to pass extra options to imgtool. + For example, you could set this to "--version 1.2". + +config MCUBOOT_GENERATE_CONFIRMED_IMAGE + bool "Also generate a padded, confirmed image" + help + The signed, padded, and confirmed binaries are placed in the build + directory at zephyr/zephyr.signed.confirmed.bin and + zephyr/zephyr.signed.confirmed.hex. + + The file names can be customized with CONFIG_KERNEL_BIN_NAME. + The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN + and CONFIG_BUILD_OUTPUT_HEX. + +endif # BOOTLOADER_MCUBOOT config BOOTLOADER_ESP_IDF bool "ESP-IDF bootloader support" @@ -412,17 +461,45 @@ config BOOTLOADER_ESP_IDF inside the build folder. At flash time, the bootloader will be flashed with the zephyr image -config BOOTLOADER_KEXEC - bool "Boot using Linux kexec() system call" - depends on X86 +config BOOTLOADER_BOSSA + bool "BOSSA bootloader support" + select USE_DT_CODE_PARTITION + depends on SOC_FAMILY_SAM0 + help - This option signifies that Linux boots the kernel using kexec system call - and utility. This method is used to boot the kernel over the network. + Signifies that the target uses a BOSSA compatible bootloader. If CDC + ACM USB support is also enabled then the board will reboot into the + bootloader automatically when bossac is run. + +config BOOTLOADER_BOSSA_DEVICE_NAME + string "BOSSA CDC ACM device name" + depends on BOOTLOADER_BOSSA && CDC_ACM_DTE_RATE_CALLBACK_SUPPORT + default "CDC_ACM_0" + help + Sets the CDC ACM port to watch for reboot commands. + +choice + prompt "BOSSA bootloader variant" + depends on BOOTLOADER_BOSSA + +config BOOTLOADER_BOSSA_ARDUINO + bool "Arduino" + help + Select the Arduino variant of the BOSSA bootloader. Uses 0x07738135 + as the magic value to enter the bootloader. + +config BOOTLOADER_BOSSA_ADAFRUIT_UF2 + bool "Adafruit UF2" + help + Select the Adafruit UF2 variant of the BOSSA bootloader. Uses + 0xf01669ef as the magic value to enter the bootloader. + +endchoice config BOOTLOADER_CONTEXT_RESTORE bool "Boot loader has context restore support" default y - depends on SYS_POWER_DEEP_SLEEP_STATES && BOOTLOADER_CONTEXT_RESTORE_SUPPORTED + depends on PM_DEEP_SLEEP_STATES && BOOTLOADER_CONTEXT_RESTORE_SUPPORTED help This option signifies that the target has a bootloader that restores CPU context upon resuming from deep sleep diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml new file mode 100644 index 00000000000000..c09132919f9609 --- /dev/null +++ b/MAINTAINERS.yml @@ -0,0 +1,1240 @@ +# This file contains information on who maintains what. It is parsed by +# get_maintainer.py. +# +# File format +# ########### +# +# "Area title" (the quotes are only needed for titles with special characters, +# like colons): +# status: +# One of the following: +# +# * maintained: +# The area has a Maintainer (approved by the TSC) who +# looks after the area. +# +# * orphaned: +# No current maintainer (but maybe you could take the role as you +# write your new code). +# +# * obsolete: +# Old code. Something being marked obsolete generally means it has +# been replaced by something better that you should be using +# instead. +# +# maintainers: +# List of GitHub handles for the people who maintain the area. Usually, +# there's only one maintainer. +# +# collaborators (not to be confused with the GitHub collaborator role): +# Very involved contributors, who know the area well and contribute +# significantly to it. +# +# labels: +# List of GitHub labels to add to pull requests that modify the area. +# +# files: +# List of paths and/or glob patterns giving the files in the area, +# relative to the root directory. +# +# If a path or glob pattern ends in a '/', it matches all files within +# the given directory or directories. Otherwise, an exact match is +# required. +# +# Paths to directories should always have a trailing '/'. +# +# files-regex: +# List of regular expressions applied to paths to determine if they +# belong to the area. The regular expression may match anywhere within +# the path, but can be anchored with ^ and $ as usual. +# +# Can be combined with a 'files' key. +# +# Note: Prefer plain 'files' patterns where possible. get_maintainer.py +# will check that they match some file, but won't check regexes +# (because it might be slow). +# +# files-exclude: +# Like 'files', but any matching files will be excluded from the area. +# +# files-regex-exclude: +# Like 'files-regex', but any matching files will be excluded from the +# area. +# +# description: >- +# Plain-English description. Describe what the system is about, from an +# outsider's perspective. +# +# +# All areas must have a 'files' and/or 'files-regex' key. The other keys are +# optional. +# +# It is very advisable to have a `status` key in all entries. Exceptions to +# this would be sub-areas which add extra fields (for ex. more `collaborators` +# who work only in that sub-area) to other areas. +# +# +# Workflow +# ######## +# +# Ideally, any file in the tree will be covered by some area. +# +# When a GitHub pull request is sent, this happens: +# +# * A user mentioned in 'maintainers' is added as Assignee to +# the pull request +# +# * Users mentioned in 'maintainers' and 'collaborators' are added as +# reviewers to the pull request +# +# * The labels listed in 'labels' are automatically added to the pull +# request +# +# * The bot posts this comment: +# +# This PR affects the following areas: +# : +# Status: ... +# Maintainers: +# Collaborators: +# +# : +# ... +# +# +# Changes to MAINTAINERS.yml need to be approved as follows: +# +# * Changing the 'maintainers' for an area needs approval from the +# Technical Steering Committee +# +# * Changing the 'collaborators' lines requires the maintainer and +# collaborators of that area to agree (or vote on it) + +# Areas are sorted by name + +ARC arch: + status: maintained + maintainers: + - ruuddw + collaborators: + - abrodkin + - evgeniy-paltsev + - IRISZZW + files: + - arch/arc/ + - include/arch/arc/ + labels: + - "area: ARC" + +ARM arch: + status: maintained + maintainers: + - ioannisg + collaborators: + - carlocaione + - galak + - MaureenHelm + - stephanosio + files: + - arch/arm/ + - include/arch/arm/ + - tests/arch/arm/ + labels: + - "area: ARM" + +Bluetooth: + status: maintained + maintainers: + - jhedberg + collaborators: + - joerchan + - Vudentz + files: + - doc/reference/bluetooth/ + - doc/guides/bluetooth/ + - drivers/bluetooth/ + - include/bluetooth/ + - include/drivers/bluetooth/ + - samples/bluetooth/ + - subsys/bluetooth/ + - tests/bluetooth/ + labels: + - "area: Bluetooth" + +Bluetooth controller: + status: maintained + maintainers: + - cvinayak + collaborators: + - carlescufi + - thoh-ot + files: + - subsys/bluetooth/controller/ + labels: + - "area: Bluetooth Controller" + +Bluetooth Mesh: + status: maintained + maintainers: + - trond-snekvik + collaborators: + - jhedberg + files: + - subsys/bluetooth/mesh/ + - include/bluetooth/mesh/ + labels: + - "area: Bluetooth Mesh" + +Build system: + status: maintained + maintainers: + - tejlmand + collaborators: + - nashif + files: + - cmake/ + files-regex: + - CMakeLists.txt$ + - \.cmake$ + labels: + - "area: Build System" + +C library: + status: orphaned + collaborators: + - nashif + - andrewboie + files: + - lib/libc/ + - tests/lib/c_lib/ + labels: + - "area: C Library" + +CMSIS API layer: + status: orphaned + collaborators: + - nashif + files: + - lib/cmsis_rtos_v*/ + labels: + - "area: Portability" + +Common arch: + status: maintained + maintainers: + - andrewboie + files: + - arch/common/ + - include/arch/common/ + labels: + - "area: Architectures" + +Console: + status: maintained + maintainers: + - pfalcon + files: + - include/console/ + - subsys/console/ + labels: + - "area: Console" + +Debug: + status: maintained + maintainers: + - nashif + files: + - include/debug/ + - subsys/debug/ + labels: + - "area: Debugging" + +DFU: + status: maintained + maintainers: + - nvlsianpu + files: + - include/dfu/ + - subsys/dfu/ + - tests/subsys/dfu/ + labels: + - "area: DFU" + +Devicetree: + status: maintained + maintainers: + - galak + collaborators: + - mbolivar-nordic + files: + - scripts/dts/ + - dts/bindings/ + - dts/common/ + labels: + - "area: Device Tree" + +Disk: + status: orphaned + files: + - subsys/disk/ + - include/disk/ + labels: + - "area: Disk Access" + +Display drivers: + status: maintained + maintainers: + - vanwinkeljan + collaborators: + - jfischer-no + files: + - drivers/display/ + - dts/bindings/display/ + - include/drivers/display.h + - include/display/ + - include/drivers/display.h + - lib/gui/ + - subsys/fb/ + labels: + - "area: Display" + +Documentation: + status: maintained + maintainers: + - carlescufi + collaborators: + - nashif + files: + - doc/ + files-regex: + - \.rst$ + - /doc/ + labels: + - "area: Documentation" + +"Drivers: ADC": + status: maintained + maintainers: + - anangl + files: + - drivers/adc/ + - include/drivers/adc.h + - tests/drivers/adc/ + labels: + - "area: ADC" + +"Drivers: Audio": + status: maintained + maintainers: + - Vudentz + files: + - drivers/audio/ + - include/audio/ + labels: + - "area: Audio" + +"Drivers: CAN": + status: maintained + maintainers: + - alexanderwachter + collaborators: + - henrikbrixandersen + - karstenkoenig + files: + - drivers/can/ + - dts/bindings/can/ + - include/drivers/can.h + - samples/drivers/can/ + - tests/drivers/can/ + labels: + - "area: CAN" + +"Drivers: Clock control": + status: maintained + maintainers: + - nordic-krch + files: + - drivers/clock_control/ + - dts/bindings/clock/ + - include/drivers/clock_control.h + - include/dt-bindings/clock/ + - tests/drivers/clock_control/ + labels: + - "area: Clock control" + +"Drivers: Console": + status: orphaned + collaborators: + - pfalcon + files: + - drivers/console/ + - include/drivers/console/ + - tests/drivers/console/ + labels: + - "area: Console" + +"Drivers: Counter": + status: maintained + maintainers: + - nordic-krch + files: + - drivers/counter/ + - include/drivers/counter.h + - tests/drivers/counter/ + labels: + - "area: Counter" + +"Drivers: Crypto": + status: orphaned + files: + - drivers/crypto/ + - dts/bindings/crypto/ + - include/crypto/ + - samples/drivers/crypto/ + labels: + - "area: Crypto / RNG" + +"Drivers: DAC": + status: maintained + maintainers: + - martinjaeger + files: + - drivers/dac/ + - include/drivers/dac.h + - tests/drivers/dac/ + labels: + - "area: DAC" + +"Drivers: DMA": + status: orphaned + files: + - drivers/dma/ + - include/dt-bindings/dma/ + - tests/drivers/dma/ + labels: + - "area: DMA" + +"Drivers: EEPROM": + status: maintained + maintainers: + - henrikbrixandersen + files: + - drivers/eeprom/ + - dts/bindings/mtd/*eeprom* + - include/drivers/eeprom.h + - tests/drivers/eeprom/ + labels: + - "area: EEPROM" + +"Drivers: Entropy": + status: maintained + maintainers: + - ceolin + files: + - drivers/entropy/ + - include/drivers/entropy.h + - samples/drivers/entropy/ + - tests/drivers/entropy/ + labels: + - "area: Crypto / RNG" + +"Drivers: ESPI": + status: orphaned + files: + - drivers/espi/ + - include/drivers/espi.h + - samples/drivers/espi/ + labels: + - "area: eSPI" + +"Drivers: Ethernet": + status: maintained + maintainers: + - tbursztyka + collaborators: + - jukkar + - pfalcon + files: + - drivers/ethernet/ + labels: + - "area: Ethernet" + +"Drivers: Flash": + status: maintained + maintainers: + - nvlsianpu + files: + - drivers/flash/ + - dts/bindings/flash_controller/ + - include/drivers/flash.h + - samples/drivers/flash_shell/ + labels: + - "area: Flash" + +"Drivers: GPIO": + status: maintained + maintainers: + - mnkp + files: + - doc/reference/peripherals/gpio.rst + - drivers/gpio/ + - include/drivers/gpio/ + - include/drivers/gpio.h + - include/dt-bindings/gpio/ + - tests/drivers/gpio/ + - samples/drivers/gpio/ + labels: + - "area: GPIO" + +"Drivers: HW Info": + status: maintained + maintainers: + - alexanderwachter + files: + - drivers/hwinfo/ + - dts/bindings/hwinfo/ + - include/drivers/hwinfo.h + - tests/drivers/hwinfo/ + labels: + - "area: HWINFO" + +"Drivers: I2C": + status: maintained + maintainers: + - pabigot + files: + - drivers/i2c/ + - dts/bindings/i2c/ + - include/drivers/i2c.h + labels: + - "area: I2C" + +"Drivers: I2S": + status: maintained + maintainers: + - anangl + files: + - doc/reference/audio/i2s.rst + - drivers/i2s/ + - dts/bindings/i2s/ + - include/drivers/i2s.h + - tests/drivers/i2s/ + labels: + - "area: I2S" + +"Drivers: IEEE 802.15.4": + status: maintained + maintainers: + - tbursztyka + collaborators: + - jukkar + files: + - drivers/ieee802154/ + labels: + - "area: IEEE 802.15.4" + +"Drivers: Interrupt controllers": + status: orphaned + files: + - drivers/interrupt_controller/ + - dts/bindings/interrupt-controller/ + - include/drivers/interrupt_controller/ + - include/dt-bindings/interrupt-controller/ + labels: + - "area: Interrupt Controller" + +"Drivers: IPM": + status: maintained + maintainers: + - andrewboie + files: + - drivers/ipm/ + description: >- + Inter-processor mailboxes + labels: + - "area: IPM" + +"Drivers: kscan": + status: orphaned + files: + - drivers/kscan/ + - include/drivers/kscan.h + - samples/drivers/espi/ + - tests/drivers/kscan/ + labels: + - "area: Kscan" + +"Drivers: LED": + status: maintained + maintainers: + - Mani-Sadhasivam + files: + - drivers/led/ + - include/drivers/led/ + - include/drivers/led.h + - samples/drivers/led_*/ + labels: + - "area: LED" + +"Drivers: LED Strip": + status: maintained + maintainers: + - mbolivar-nordic + files: + - drivers/led_strip/ + - dts/bindings/led_strip/ + - include/drivers/led_strip.h + labels: + - "area: LED" + +"Drivers: lora": + status: maintained + maintainers: + - Mani-Sadhasivam + files: + - drivers/lora/ + - include/drivers/lora.h + - samples/drivers/lora/ + labels: + - "area: LoRa" + +"Drivers: Modem": + status: orphaned + files: + - drivers/modem/ + labels: + - "area: Modem" + +"Drivers: Neural Networks": + status: orphaned + files: + - drivers/neural_net/ + labels: + - "area: Neural Networks" + +"Drivers: PCI": + status: maintained + maintainers: + - dcpleung + collaborators: + - andrewboie + files: + - drivers/pcie/ + - include/drivers/pcie/ + labels: + - "area: PCI" + +"Drivers: PECI": + status: orphaned + files: + - drivers/peci/ + - include/drivers/peci.h + - samples/drivers/peci/ + labels: + - "area: PECI" + +"Drivers: Pinmux": + status: maintained + maintainers: + - mnkp + files: + - doc/reference/peripherals/pinmux.rst + - drivers/pinmux/ + - include/drivers/pinmux.h + labels: + - "area: Pinmux" + +"Drivers: PTP Clock": + status: maintained + maintainers: + - jukkar + files: + - drivers/ptp_clock/ + - include/ptp_clock.h + labels: + - "area: Clocks" + +"Drivers: PWM": + status: maintained + maintainers: + - anangl + files: + - drivers/pwm/ + - dts/bindings/pwm/ + - include/drivers/pwm.h + - tests/drivers/pwm/ + labels: + - "area: PWM" + +"Drivers: Serial/UART": + status: maintained + maintainers: + - dcpleung + files: + - drivers/serial/ + - dts/bindings/serial/ + labels: + - "area: UART" + +"Drivers: Sensors": + status: maintained + maintainers: + - MaureenHelm + collaborators: + - avisconti + files: + - drivers/sensor/ + - include/drivers/sensor.h + - samples/sensor/ + labels: + - "area: Sensors" + +"Drivers: SPI": + status: maintained + maintainers: + - tbursztyka + files: + - drivers/spi/ + - include/drivers/spi.h + - tests/drivers/spi/ + labels: + - "area: SPI" + +"Drivers: System timer": + status: maintained + maintainers: + - andyross + files: + - drivers/timer/ + - include/drivers/timer/ + labels: + - "area: Timer" + +"Drivers: video": + status: orphaned + collaborators: + - loicpoulain + files: + - drivers/video/ + - include/drivers/video.h + - include/drivers/video-controls.h + labels: + - "area: Video" + +"Drivers: Watchdog": + status: orphaned + collaborators: + - katsuster + files: + - doc/reference/peripherals/watchdog.rst + - drivers/watchdog/ + - dts/bindings/watchdog/ + - include/drivers/watchdog.h + - samples/drivers/watchdog/ + - tests/drivers/watchdog/ + labels: + - "area: Watchdog" + +"Drivers: WiFi": + status: maintained + maintainers: + - tbursztyka + collaborators: + - jukkar + - kludentwo + files: + - drivers/wifi/ + labels: + - "area: Wifi" + +"Drivers: WiFi es-WiFi": + status: orphaned + collaborators: + - loicpoulain + files: + - drivers/wifi/eswifi/ + description: >- + Inventek es-WiFi + + labels: + - "area: Wifi" + +Filesystems: + status: maintained + maintainers: + - nvlsianpu + collaborators: + - de-nordic + - Laczen + - nashif + - pabigot + - vanwinkeljan + - wentongwu + files: + - include/fs/ + - samples/subsys/fs/ + - subsys/fs/ + - tests/subsys/fs/ + labels: + - "area: File System" + +JSON Web Token: + status: orphaned + collaborators: + - mrfuchs + files: + - subsys/jwt/ + + labels: + - "area: JSON" + +Kconfig: + status: orphaned + files: + - scripts/kconfig/ + - doc/guides/kconfig/ + labels: + - "area: Kconfig" + description: >- + See https://docs.zephyrproject.org/latest/guides/kconfig/index.html and + https://docs.zephyrproject.org/latest/guides/porting/board_porting.html#default-board-configuration + +Kernel: + status: maintained + maintainers: + - andyross + collaborators: + - andrewboie + files: + - doc/reference/kernel/ + - include/kernel*.h + - kernel/ + - tests/kernel/ + labels: + - "area: Kernel" + +Little FS: + status: maintained + maintainers: + - pabigot + files: + - subsys/fs/Kconfig.littlefs + - subsys/fs/littlefs_fs.c + - tests/subsys/fs/littlefs/ + description: >- + Little FS + + labels: + - "area: File System" + +Logging: + status: maintained + maintainers: + - nordic-krch + files: + - include/logging/ + - samples/subsys/logging/ + - subsys/logging/ + - tests/subsys/logging/ + labels: + - "area: Logging" + +MAINTAINERS file: + status: maintained + maintainers: + - MaureenHelm + collaborators: + - ioannisg + files: + - MAINTAINERS.yml + labels: + - "area: Process" + description: >- + Zephyr Maintainers File + +MCU Manager: + status: maintained + maintainers: + - de-nordic + files: + - subsys/mgmt/mcumgr/ + - include/mgmt/mcumgr/ + - samples/subsys/mgmt/mcumgr/ + labels: + - "area: mcumgr" + +OSDP: + status: maintained + collaborators: + - cbsiddharth + files: + - subsys/mgmt/osdp/ + - include/mgmt/osdp.h + - samples/subsys/mgmt/osdp/ + labels: + - "area: OSDP" + +Native POSIX and POSIX arch: + status: maintained + maintainers: + - aescolar + files: + - arch/posix/ + - boards/posix/native_posix/ + - drivers/*/*native_posix* + - drivers/*/*/*native_posix* + - dts/posix/ + - include/arch/posix/ + - scripts/valgrind.supp + - soc/posix/ + - tests/boards/native_posix/ + labels: + - "area: native port" + description: >- + POSIX architecture and SOC, native_posix board, and related drivers + +Networking: + status: maintained + maintainers: + - jukkar + collaborators: + - tbursztyka + - pfalcon + files: + - drivers/net/ + - include/net/ + - samples/net/ + - subsys/net/ + files-exclude: + - samples/net/sockets/coap_*/ + - samples/net/lwm2m_client/ + - subsys/net/lib/coap/ + - subsys/net/lib/lwm2m/ + - subsys/net/lib/openthread/ + - subsys/net/lib/tls_credentials/ + labels: + - "area: Networking" + +"Networking: BSD sockets": + status: maintained + maintainers: + - pfalcon + collaborators: + - jukkar + files: + - samples/net/sockets/ + - subsys/net/lib/sockets/ + - tests/net/socket/ + labels: + - "area: Sockets" + +"Networking: Buffers": + status: maintained + maintainers: + - jhedberg + collaborators: + - jukkar + - tbursztyka + files: + - include/net/buf.h + - subsys/net/buf.c + - tests/net/buf/ + + labels: + - "area: Networking" + +"Networking: CoAP": + status: maintained + maintainers: + - rlubos + collaborators: + - jukkar + files: + - subsys/net/lib/coap/ + - samples/net/sockets/coap_*/ + - tests/net/lib/coap/ + labels: + - "area: Networking" +"Networking: LWM2M": + status: maintained + maintainers: + - rlubos + collaborators: + - jukkar + files: + - samples/net/lwm2m_client/ + - subsys/net/lib/lwm2m/ + labels: + - "area: LWM2M" + +"Networking: MQTT": + status: maintained + maintainers: + - rlubos + collaborators: + - jukkar + files: + - subsys/net/lib/mqtt/ + - tests/net/lib/mqtt_packet/ + - samples/net/mqtt_publisher/ + labels: + - "area: Networking" + +NIOS-2 arch: + status: maintained + maintainers: + - nashif + files: + - arch/nios2/ + - include/arch/nios2/ + labels: + - "area: NIOS2" + +nRF52 BSIM: + status: maintained + maintainers: + - aescolar + files: + - boards/posix/nrf52_bsim/ + labels: + - "platform: nrf52_bsim" + +POSIX API layer: + status: orphaned + collaborators: + - pfalcon + files: + - include/posix/ + - lib/posix/ + - tests/posix/ + labels: + - "area: POSIX" + +Power management: + status: maintained + maintainers: + - wentongwu + files: + - include/power/power.h + - samples/subsys/power/ + - subsys/power/ + labels: + - "area: Power Management" + +RISCV arch: + status: orphaned + collaborators: + - mgielda + - nategraff-sifive + - katsuster + files: + - arch/riscv/ + - boards/riscv/ + - dts/bindings/riscv/ + - include/arch/riscv/ + - soc/riscv/ + labels: + - "area: RISCV" + +Twister: + status: maintained + maintainers: + - nashif + files: + - scripts/twister + - scripts/pylib/twister + labels: + - "area: Twister" + +Settings: + status: maintained + maintainers: + - nvlsianpu + files: + - include/settings/ + - subsys/settings/ + - tests/subsys/settings/ + labels: + - "area: Settings" + +Shell: + status: maintained + maintainers: + - jakub-uC + collaborators: + - carlescufi + files: + - include/shell/ + - samples/subsys/shell/ + - subsys/shell/ + - tests/subsys/shell/ + labels: + - "area: Shell" + +Shields: + status: maintained + maintainers: + - erwango + collaborators: + - avisconti + - jfischer-no + files: + - boards/shields/ + labels: + - "area: Shields" + +SPARC arch: + status: maintained + collaborators: + - martin-aberg + files: + - arch/sparc/ + - include/arch/sparc/ + labels: + - "area: SPARC" + +STM32: + status: maintained + maintainers: + - erwango + files: + - boards/arm/nucleo_*/ + - boards/arm/stm32*_disco/ + - boards/arm/stm32*_eval/ + - drivers/*/*stm32*/ + - drivers/*/*/*stm32* + - dts/arm/st/ + - dts/bindings/*/*stm32* + - soc/arm/st_stm32/ + labels: + - "platform: STM32" + description: >- + STM32 SOCs, dts files and related drivers. ST nucleo, disco and eval + boards. + +Storage: + status: maintained + maintainers: + - nvlsianpu + files: + - subsys/storage/ + - include/storage/ + - tests/subsys/storage/ + labels: + - "area: Storage" + +TF-M Integration: + status: maintained + maintainers: + - microbuilder + collaborators: + - ioannisg + files: + - samples/tfm_integration/ + labels: + - "area: TF-M" + +Tracing: + status: maintained + maintainers: + - nashif + collaborators: + - wentongwu + files: + - subsys/tracing/ + - include/tracing/ + labels: + - "area: tracing" + +USB: + status: maintained + maintainers: + - jfischer-no + collaborators: + - finikorg + files: + - drivers/usb/ + - dts/bindings/usb/ + - include/*/usb/ + - include/usb/ + - samples/subsys/usb/ + - subsys/usb/ + - tests/subsys/usb/ + labels: + - "area: USB" + +Userspace: + status: maintained + maintainers: + - andrewboie + files: + - doc/reference/usermode/kernelobjects.rst + - include/app_memory/ + - include/linker/app_smem*.ld + labels: + - "area: Userspace" + +VFS: + status: maintained + maintainers: + - de-nordic + files: + - subsys/fs/fat_fs.c + - tests/subsys/fs/fat_fs_api/ + description: >- + VFS implementation + + labels: + - "area: File System" + + +West: + status: maintained + maintainers: + - mbolivar-nordic + collaborators: + - carlescufi + files: + - scripts/west-commands.yml + - scripts/west_commands/ + labels: + - "area: West" + +Xtensa arch: + status: maintained + maintainers: + - dcpleung + collaborators: + - andyross + - andrewboie + files: + - arch/xtensa/ + - include/arch/xtensa/ + - dts/xtensa/ + - tests/arch/xtensa_asm2/ + labels: + - "area: Xtensa" + +x86 arch: + status: maintained + maintainers: + - ceolin + collaborators: + - andyross + files: + - arch/x86/ + - include/arch/x86/ + - tests/arch/x86/ + labels: + - "area: X86" + +ZTest: + status: maintained + maintainers: + - nashif + files: + - subsys/testsuite/ + - tests/ztest/ + - tests/unit/util/ + labels: + - "area: Testsuite" diff --git a/README.rst b/README.rst index 3b2d87091eeee2..fb02a0bd233765 100644 --- a/README.rst +++ b/README.rst @@ -8,8 +8,9 @@ + + src="https://badge.buildkite.com/f5bd0dc88306cee17c9b38e78d11bb74a6291e3f40e7d13f31.svg?branch=master"> The Zephyr Project is a scalable real-time operating system (RTOS) supporting diff --git a/VERSION b/VERSION index 7f34cd1859c77a..3c0c9329518dde 100644 --- a/VERSION +++ b/VERSION @@ -1,5 +1,5 @@ VERSION_MAJOR = 2 -VERSION_MINOR = 3 -PATCHLEVEL = 0 +VERSION_MINOR = 4 +PATCHLEVEL = 99 VERSION_TWEAK = 0 -EXTRAVERSION = rc1 +EXTRAVERSION = diff --git a/arch/CMakeLists.txt b/arch/CMakeLists.txt index 3ebb9ccebffdad..ef30d760bb86d7 100644 --- a/arch/CMakeLists.txt +++ b/arch/CMakeLists.txt @@ -4,7 +4,7 @@ add_definitions(-D__ZEPHYR_SUPERVISOR__) include_directories( ${ZEPHYR_BASE}/kernel/include - ${ZEPHYR_BASE}/arch/${ARCH}/include + ${ARCH_DIR}/${ARCH}/include ) add_subdirectory(common) diff --git a/arch/Kconfig b/arch/Kconfig index 2b1c9cbf2a5893..45c418d5a98e89 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -20,25 +20,48 @@ config ARC bool select ARCH_IS_SET select HAS_DTS + imply XIP + select ARCH_HAS_THREAD_LOCAL_STORAGE help ARC architecture config ARM bool select ARCH_IS_SET + select ARCH_SUPPORTS_COREDUMP if CPU_CORTEX_M select HAS_DTS # 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 + select ARCH_HAS_THREAD_LOCAL_STORAGE if ARM64 || CPU_CORTEX_R || CPU_CORTEX_M help ARM architecture +config SPARC + bool + select ARCH_IS_SET + select USE_SWITCH + select USE_SWITCH_SUPPORTED + select BIG_ENDIAN + select ATOMIC_OPERATIONS_BUILTIN if SPARC_CASA + select ATOMIC_OPERATIONS_C if !SPARC_CASA + select ARCH_HAS_THREAD_LOCAL_STORAGE + help + SPARC architecture + config X86 bool select ARCH_IS_SET select ATOMIC_OPERATIONS_BUILTIN select HAS_DTS select ARCH_HAS_CUSTOM_SWAP_TO_MAIN if !X86_64 + select ARCH_SUPPORTS_COREDUMP + select CPU_HAS_MMU + select ARCH_MEM_DOMAIN_DATA if USERSPACE && !X86_COMMON_PAGE_TABLE + select ARCH_MEM_DOMAIN_SYNCHRONOUS_API if USERSPACE + select ARCH_HAS_GDBSTUB if !X86_64 + select ARCH_HAS_TIMING_FUNCTIONS + select ARCH_HAS_THREAD_LOCAL_STORAGE help x86 architecture @@ -47,6 +70,8 @@ config NIOS2 select ARCH_IS_SET select ATOMIC_OPERATIONS_C select HAS_DTS + imply XIP + select ARCH_HAS_TIMING_FUNCTIONS help Nios II Gen 2 architecture @@ -54,6 +79,8 @@ config RISCV bool select ARCH_IS_SET select HAS_DTS + select ARCH_HAS_THREAD_LOCAL_STORAGE + imply XIP help RISCV architecture @@ -202,6 +229,8 @@ config USERSPACE bool "User mode threads" depends on ARCH_HAS_USERSPACE depends on RUNTIME_ERROR_CHECKS + depends on SRAM_REGION_PERMISSIONS + select THREAD_STACK_INFO help When enabled, threads may be created or dropped down to user mode, which has significantly restricted permissions and must interact @@ -229,6 +258,7 @@ config KOBJECT_TEXT_AREA int "Size if kobject text area" default 512 if COVERAGE_GCOV default 512 if NO_OPTIMIZATIONS + default 512 if STACK_CANARIES && RISCV default 256 depends on ARCH_HAS_USERSPACE help @@ -359,14 +389,44 @@ config IRQ_OFFLOAD run in interrupt context. Only useful for test cases that need to validate the correctness of kernel objects in IRQ context. + +config EXTRA_EXCEPTION_INFO + bool "Collect extra exception info" + depends on ARCH_HAS_EXTRA_EXCEPTION_INFO + help + This option enables the collection of extra information, such as + register state, when a fault occurs. This information can be useful + to collect for post-mortem analysis and debug of issues. + endmenu # Interrupt configuration +config INIT_ARCH_HW_AT_BOOT + bool "Initialize internal architecture state at boot" + depends on ARCH_SUPPORTS_ARCH_HW_INIT + help + This option instructs Zephyr to force the initialization + of the internal architectural state (for example ARCH-level + HW registers and system control blocks) during boot to + the reset values as specified by the corresponding + architecture manual. The option is useful when the Zephyr + firmware image is chain-loaded, for example, by a debugger + or a bootloader, and we need to guarantee that the internal + states of the architecture core blocks are restored to the + reset values (as specified by the architecture). + + Note: the functionality is architecture-specific. For the + implementation details refer to each architecture where + this feature is supported. + endmenu # # Architecture Capabilities # +config ARCH_HAS_TIMING_FUNCTIONS + bool + config ARCH_HAS_TRUSTED_EXECUTION bool @@ -388,53 +448,34 @@ config ARCH_HAS_RAMFUNC_SUPPORT config ARCH_HAS_NESTED_EXCEPTION_DETECTION bool -# -# Other architecture related options -# - -config ARCH_HAS_THREAD_ABORT +config ARCH_SUPPORTS_COREDUMP bool -# -# Hidden PM feature configs which are to be selected by -# individual SoC. -# - -config HAS_SYS_POWER_STATE_SLEEP_1 +config ARCH_SUPPORTS_ARCH_HW_INIT bool - help - This option signifies that the target supports the SYS_POWER_STATE_SLEEP_1 - configuration option. -config HAS_SYS_POWER_STATE_SLEEP_2 +config ARCH_HAS_EXTRA_EXCEPTION_INFO bool - help - This option signifies that the target supports the SYS_POWER_STATE_SLEEP_2 - configuration option. -config HAS_SYS_POWER_STATE_SLEEP_3 +config ARCH_HAS_GDBSTUB bool - help - This option signifies that the target supports the SYS_POWER_STATE_SLEEP_3 - configuration option. -config HAS_SYS_POWER_STATE_DEEP_SLEEP_1 +config ARCH_HAS_COHERENCE bool help - This option signifies that the target supports the SYS_POWER_STATE_DEEP_SLEEP_1 - configuration option. + When selected, the architecture supports the + arch_mem_coherent() API and can link into incoherent/cached + memory using the ".cached" linker section. -config HAS_SYS_POWER_STATE_DEEP_SLEEP_2 +config ARCH_HAS_THREAD_LOCAL_STORAGE bool - help - This option signifies that the target supports the SYS_POWER_STATE_DEEP_SLEEP_2 - configuration option. -config HAS_SYS_POWER_STATE_DEEP_SLEEP_3 +# +# Other architecture related options +# + +config ARCH_HAS_THREAD_ABORT bool - help - This option signifies that the target supports the SYS_POWER_STATE_DEEP_SLEEP_3 - configuration option. config BOOTLOADER_CONTEXT_RESTORE_SUPPORTED bool @@ -477,13 +518,101 @@ config CPU_HAS_MPU help This option is enabled when the CPU has a Memory Protection Unit (MPU). -config MEMORY_PROTECTION +config CPU_HAS_MMU bool help - This option is enabled when Memory Protection features are supported. - Memory protection support is currently available on ARC, ARM, and x86 - architectures. + This hidden option is selected when the CPU has a Memory Management Unit + (MMU). + +menuconfig MMU + bool "Enable MMU features" + depends on CPU_HAS_MMU + help + This option is enabled when the CPU's memory management unit is active + and the arch_mem_map() API is available. + +if MMU +config MMU_PAGE_SIZE + hex "Size of smallest granularity MMU page" + default 0x1000 + help + Size of memory pages. Varies per MMU but 4K is common. For MMUs that + support multiple page sizes, put the smallest one here. +config KERNEL_VM_BASE + hex "Base virtual address to link the kernel" + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_SRAM)) + help + Define the base virtual memory address for the core kernel. + + The kernel expects a mappings for all physical RAM regions starting at + this virtual address, with any unused space up to the size denoted by + KERNEL_VM_SIZE available for memory mappings. This base address denotes + the start of the RAM mapping and may not be the base address of the + kernel itself, but the offset of the kernel here will be the same as the + offset from the beginning of physical memory where it was loaded. + + If there are multiple physical RAM regions which are discontinuous in + the physical memory map, they should all be mapped in a continuous + virtual region, with bounds defined by KERNEL_RAM_SIZE. + + By default, this is the same as the DT_CHOSEN_Z_SRAM physical base SRAM + address from DTS, in which case RAM will be identity-mapped. Some + architectures may require RAM to be mapped in this way; they may have + just one RAM region and doing this makes linking much simpler, as + at least when the kernel boots all virtual RAM addresses are the same + as their physical address (demand paging at runtime may later modify + this for some subset of non-pinned pages). + + Otherwise, if RAM isn't identity-mapped: + 1. It is the architecture's responsibility to transition the + instruction pointer to virtual addresses at early boot before + entering the kernel at z_cstart(). + 2. The underlying architecture may impose constraints on the bounds of + the kernel's address space, such as not overlapping physical RAM + regions if RAM is not identity-mapped, or the virtual and physical + base addresses being aligned to some common value (which allows + double-linking of paging structures to make the instruction pointer + transition simpler). + +config KERNEL_RAM_SIZE + hex "Total size of RAM mappings in bytes" + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_SRAM)) + help + Indicates to the kernel the total size of RAM that is mapped. The + kernel expects that all physical RAM has a memory mapping in the virtual + address space, and that these RAM mappings are all within the virtual + region [KERNEL_VM_BASE..KERNEL_VM_BASE + KERNEL_RAM_SIZE). + +config KERNEL_VM_SIZE + hex "Size of kernel address space in bytes" + default 0xC0000000 + help + Size of the kernel's address space. Constraining this helps control + how much total memory can be used for page tables. + + The difference between KERNEL_RAM_SIZE and KERNEL_VM_SIZE indicates the + size of the virtual region for runtime memory mappings. This is needed + for mapping driver MMIO regions, as well as special RAM mapping use-cases + such as VSDO pages, memory mapped thread stacks, and anonymous memory + mappings. + + The system currently assumes all RAM can be mapped in the virtual address + space. Systems with very large amounts of memory (such as 512M or more) + will want to use a 64-bit build of Zephyr, there are no plans to + implement a notion of "high" memory in Zephyr to work around physical + RAM which can't have a boot-time mapping due to a too-small address space. + +endif # MMU + +menuconfig MPU + bool "Enable MPU features" + depends on CPU_HAS_MPU + help + This option, when enabled, indicates to the core kernel that an MPU + is enabled. + +if MPU config MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT bool help @@ -521,12 +650,46 @@ config MPU_GAP_FILLING documentation for more information on how this option is used. +endif # MPU + +config SRAM_REGION_PERMISSIONS + bool "Assign appropriate permissions to kernel areas in SRAM" + depends on MMU || MPU + default y + help + This option indicates that memory protection hardware + is present, enabled, and regions have been configured at boot for memory + ranges within the kernel image. + + If this option is turned on, certain areas of the kernel image will + have the following access policies applied for all threads, including + supervisor threads: + + 1) All program text will be have read-only, execute memory permission + 2) All read-only data will have read-only permission, and execution + disabled if the hardware supports it. + 3) All other RAM addresses will have read-write permission, and + execution disabled if the hardware supports it. + + Options such as USERSPACE or HW_STACK_PROTECTION may additionally + impose additional policies on the memory map, which may be global + or local to the current running thread. + + This option may consume additional memory to satisfy memory protection + hardware alignment constraints. + + If this option is disabled, the entire kernel will have default memory + access permissions set, typically read/write/execute. It may be desirable + to turn this off on MMU systems which are using the MMU for demand + paging, do not need memory protection, and would rather not use up + RAM for the alignment between regions. + menu "Floating Point Options" config FPU bool "Enable floating point unit (FPU)" depends on CPU_HAS_FPU - depends on ARC || ARM || RISCV || X86 + depends on ARC || ARM || RISCV || SPARC || X86 help This option enables the hardware Floating Point Unit (FPU), in order to support using the floating point registers and instructions. diff --git a/arch/arc/CMakeLists.txt b/arch/arc/CMakeLists.txt index 8697bbe1659a97..8135d072f10b5b 100644 --- a/arch/arc/CMakeLists.txt +++ b/arch/arc/CMakeLists.txt @@ -12,4 +12,8 @@ zephyr_cc_option(-fno-delete-null-pointer-checks) zephyr_cc_option_ifdef(CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS -munaligned-access) +# Instruct compiler to use register R26 as thread pointer +# for thread local storage. +zephyr_cc_option_ifdef(CONFIG_THREAD_LOCAL_STORAGE -mtp-regno=26) + add_subdirectory(core) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 6602aa77ce26ab..456c100f7d94d0 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -189,9 +189,6 @@ config FAULT_DUMP 0: Off. -config XIP - default y if !UART_NSIM - config GEN_ISR_TABLES default y diff --git a/arch/arc/core/CMakeLists.txt b/arch/arc/core/CMakeLists.txt index 73d8c709d1af19..44fb70dd2072fe 100644 --- a/arch/arc/core/CMakeLists.txt +++ b/arch/arc/core/CMakeLists.txt @@ -2,6 +2,11 @@ zephyr_library() +if(CONFIG_COVERAGE) + zephyr_compile_options($) + zephyr_link_libraries($) +endif() + zephyr_library_sources( thread.c thread_entry_wrapper.S @@ -22,12 +27,14 @@ zephyr_library_sources( zephyr_library_sources_ifdef(CONFIG_CACHE_FLUSHING cache.c) zephyr_library_sources_ifdef(CONFIG_ARC_FIRQ fast_irq.S) -zephyr_library_sources_if_kconfig(irq_offload.c) +zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) zephyr_library_sources_ifdef(CONFIG_ARC_CONNECT arc_connect.c) zephyr_library_sources_ifdef(CONFIG_ARC_CONNECT arc_smp.c) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) + add_subdirectory_ifdef(CONFIG_ARC_CORE_MPU mpu) add_subdirectory_ifdef(CONFIG_ARC_SECURE_FIRMWARE secureshield) diff --git a/arch/arc/core/arc_connect.c b/arch/arc/core/arc_connect.c index 030f0e52b05b0a..76a4e5a7131d66 100644 --- a/arch/arc/core/arc_connect.c +++ b/arch/arc/core/arc_connect.c @@ -24,7 +24,7 @@ static struct k_spinlock arc_connect_spinlock; /* Generate an inter-core interrupt to the target core */ -void z_arc_connect_ici_generate(u32_t core) +void z_arc_connect_ici_generate(uint32_t core) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_INTRPT_GENERATE_IRQ, core); @@ -32,7 +32,7 @@ void z_arc_connect_ici_generate(u32_t core) } /* Acknowledge the inter-core interrupt raised by core */ -void z_arc_connect_ici_ack(u32_t core) +void z_arc_connect_ici_ack(uint32_t core) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_INTRPT_GENERATE_ACK, core); @@ -40,9 +40,9 @@ void z_arc_connect_ici_ack(u32_t core) } /* Read inter-core interrupt status */ -u32_t z_arc_connect_ici_read_status(u32_t core) +uint32_t z_arc_connect_ici_read_status(uint32_t core) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_INTRPT_READ_STATUS, core); @@ -53,9 +53,9 @@ u32_t z_arc_connect_ici_read_status(u32_t core) } /* Check the source of inter-core interrupt */ -u32_t z_arc_connect_ici_check_src(void) +uint32_t z_arc_connect_ici_check_src(void) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_INTRPT_CHECK_SOURCE, 0); @@ -68,7 +68,7 @@ u32_t z_arc_connect_ici_check_src(void) /* Clear the inter-core interrupt */ void z_arc_connect_ici_clear(void) { - u32_t cpu, c; + uint32_t cpu, c; LOCKED(&arc_connect_spinlock) { @@ -89,7 +89,7 @@ void z_arc_connect_ici_clear(void) } /* Reset the cores in core_mask */ -void z_arc_connect_debug_reset(u32_t core_mask) +void z_arc_connect_debug_reset(uint32_t core_mask) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_RESET, @@ -98,7 +98,7 @@ void z_arc_connect_debug_reset(u32_t core_mask) } /* Halt the cores in core_mask */ -void z_arc_connect_debug_halt(u32_t core_mask) +void z_arc_connect_debug_halt(uint32_t core_mask) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_HALT, @@ -107,7 +107,7 @@ void z_arc_connect_debug_halt(u32_t core_mask) } /* Run the cores in core_mask */ -void z_arc_connect_debug_run(u32_t core_mask) +void z_arc_connect_debug_run(uint32_t core_mask) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_RUN, @@ -116,7 +116,7 @@ void z_arc_connect_debug_run(u32_t core_mask) } /* Set core mask */ -void z_arc_connect_debug_mask_set(u32_t core_mask, u32_t mask) +void z_arc_connect_debug_mask_set(uint32_t core_mask, uint32_t mask) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_SET_MASK, @@ -125,9 +125,9 @@ void z_arc_connect_debug_mask_set(u32_t core_mask, u32_t mask) } /* Read core mask */ -u32_t z_arc_connect_debug_mask_read(u32_t core_mask) +uint32_t z_arc_connect_debug_mask_read(uint32_t core_mask) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_READ_MASK, @@ -141,7 +141,7 @@ u32_t z_arc_connect_debug_mask_read(u32_t core_mask) /* * Select cores that should be halted if the core issuing the command is halted */ -void z_arc_connect_debug_select_set(u32_t core_mask) +void z_arc_connect_debug_select_set(uint32_t core_mask) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_DEBUG_SET_SELECT, @@ -150,9 +150,9 @@ void z_arc_connect_debug_select_set(u32_t core_mask) } /* Read the select value */ -u32_t z_arc_connect_debug_select_read(void) +uint32_t z_arc_connect_debug_select_read(void) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_DEBUG_READ_SELECT, 0); @@ -163,9 +163,9 @@ u32_t z_arc_connect_debug_select_read(void) } /* Read the status, halt or run of all cores in the system */ -u32_t z_arc_connect_debug_en_read(void) +uint32_t z_arc_connect_debug_en_read(void) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_DEBUG_READ_EN, 0); @@ -176,9 +176,9 @@ u32_t z_arc_connect_debug_en_read(void) } /* Read the last command sent */ -u32_t z_arc_connect_debug_cmd_read(void) +uint32_t z_arc_connect_debug_cmd_read(void) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_DEBUG_READ_CMD, 0); @@ -189,9 +189,9 @@ u32_t z_arc_connect_debug_cmd_read(void) } /* Read the value of internal MCD_CORE register */ -u32_t z_arc_connect_debug_core_read(void) +uint32_t z_arc_connect_debug_core_read(void) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_DEBUG_READ_CORE, 0); @@ -210,11 +210,11 @@ void z_arc_connect_gfrc_clear(void) } /* Read total 64 bits of global free running counter */ -u64_t z_arc_connect_gfrc_read(void) +uint64_t z_arc_connect_gfrc_read(void) { - u32_t low; - u32_t high; - u32_t key; + uint32_t low; + uint32_t high; + uint32_t key; /* * each core has its own arc connect interface, i.e., @@ -233,7 +233,7 @@ u64_t z_arc_connect_gfrc_read(void) arch_irq_unlock(key); - return (((u64_t)high) << 32) | low; + return (((uint64_t)high) << 32) | low; } /* Enable global free running counter */ @@ -253,7 +253,7 @@ void z_arc_connect_gfrc_disable(void) } /* Disable global free running counter */ -void z_arc_connect_gfrc_core_set(u32_t core_mask) +void z_arc_connect_gfrc_core_set(uint32_t core_mask) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_GFRC_SET_CORE, @@ -262,9 +262,9 @@ void z_arc_connect_gfrc_core_set(u32_t core_mask) } /* Set the relevant cores to halt global free running counter */ -u32_t z_arc_connect_gfrc_halt_read(void) +uint32_t z_arc_connect_gfrc_halt_read(void) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_GFRC_READ_HALT, 0); @@ -275,9 +275,9 @@ u32_t z_arc_connect_gfrc_halt_read(void) } /* Read the internal CORE register */ -u32_t z_arc_connect_gfrc_core_read(void) +uint32_t z_arc_connect_gfrc_core_read(void) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_GFRC_READ_CORE, 0); @@ -304,9 +304,9 @@ void z_arc_connect_idu_disable(void) } /* Read enable status of interrupt distribute unit */ -u32_t z_arc_connect_idu_read_enable(void) +uint32_t z_arc_connect_idu_read_enable(void) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_READ_ENABLE, 0); @@ -320,8 +320,8 @@ u32_t z_arc_connect_idu_read_enable(void) * Set the triggering mode and distribution mode for the specified common * interrupt */ -void z_arc_connect_idu_set_mode(u32_t irq_num, - u16_t trigger_mode, u16_t distri_mode) +void z_arc_connect_idu_set_mode(uint32_t irq_num, + uint16_t trigger_mode, uint16_t distri_mode) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_IDU_SET_MODE, @@ -330,9 +330,9 @@ void z_arc_connect_idu_set_mode(u32_t irq_num, } /* Read the internal MODE register of the specified common interrupt */ -u32_t z_arc_connect_idu_read_mode(u32_t irq_num) +uint32_t z_arc_connect_idu_read_mode(uint32_t irq_num) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_READ_MODE, irq_num); @@ -346,7 +346,7 @@ u32_t z_arc_connect_idu_read_mode(u32_t irq_num) * Set the target cores to receive the specified common interrupt * when it is triggered */ -void z_arc_connect_idu_set_dest(u32_t irq_num, u32_t core_mask) +void z_arc_connect_idu_set_dest(uint32_t irq_num, uint32_t core_mask) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_IDU_SET_DEST, @@ -355,9 +355,9 @@ void z_arc_connect_idu_set_dest(u32_t irq_num, u32_t core_mask) } /* Read the internal DEST register of the specified common interrupt */ -u32_t z_arc_connect_idu_read_dest(u32_t irq_num) +uint32_t z_arc_connect_idu_read_dest(uint32_t irq_num) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_READ_DEST, irq_num); @@ -368,7 +368,7 @@ u32_t z_arc_connect_idu_read_dest(u32_t irq_num) } /* Assert the specified common interrupt */ -void z_arc_connect_idu_gen_cirq(u32_t irq_num) +void z_arc_connect_idu_gen_cirq(uint32_t irq_num) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_GEN_CIRQ, irq_num); @@ -376,7 +376,7 @@ void z_arc_connect_idu_gen_cirq(u32_t irq_num) } /* Acknowledge the specified common interrupt */ -void z_arc_connect_idu_ack_cirq(u32_t irq_num) +void z_arc_connect_idu_ack_cirq(uint32_t irq_num) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_ACK_CIRQ, irq_num); @@ -384,9 +384,9 @@ void z_arc_connect_idu_ack_cirq(u32_t irq_num) } /* Read the internal STATUS register of the specified common interrupt */ -u32_t z_arc_connect_idu_check_status(u32_t irq_num) +uint32_t z_arc_connect_idu_check_status(uint32_t irq_num) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_CHECK_STATUS, irq_num); @@ -397,9 +397,9 @@ u32_t z_arc_connect_idu_check_status(u32_t irq_num) } /* Read the internal SOURCE register of the specified common interrupt */ -u32_t z_arc_connect_idu_check_source(u32_t irq_num) +uint32_t z_arc_connect_idu_check_source(uint32_t irq_num) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_CHECK_SOURCE, irq_num); @@ -410,7 +410,7 @@ u32_t z_arc_connect_idu_check_source(u32_t irq_num) } /* Mask or unmask the specified common interrupt */ -void z_arc_connect_idu_set_mask(u32_t irq_num, u32_t mask) +void z_arc_connect_idu_set_mask(uint32_t irq_num, uint32_t mask) { LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd_data(ARC_CONNECT_CMD_IDU_SET_MASK, @@ -419,9 +419,9 @@ void z_arc_connect_idu_set_mask(u32_t irq_num, u32_t mask) } /* Read the internal MASK register of the specified common interrupt */ -u32_t z_arc_connect_idu_read_mask(u32_t irq_num) +uint32_t z_arc_connect_idu_read_mask(uint32_t irq_num) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_READ_MASK, irq_num); @@ -435,9 +435,9 @@ u32_t z_arc_connect_idu_read_mask(u32_t irq_num) * Check if it is the first-acknowledging core to the common interrupt * if IDU is programmed in the first-acknowledged mode */ -u32_t z_arc_connect_idu_check_first(u32_t irq_num) +uint32_t z_arc_connect_idu_check_first(uint32_t irq_num) { - u32_t ret = 0; + uint32_t ret = 0; LOCKED(&arc_connect_spinlock) { z_arc_connect_cmd(ARC_CONNECT_CMD_IDU_CHECK_FIRST, irq_num); diff --git a/arch/arc/core/arc_smp.c b/arch/arc/core/arc_smp.c index 35069be880c594..e3b3c8a2d5dfe6 100644 --- a/arch/arc/core/arc_smp.c +++ b/arch/arc/core/arc_smp.c @@ -35,7 +35,7 @@ volatile struct { * master core that it's waken * */ -volatile u32_t arc_cpu_wake_flag; +volatile uint32_t arc_cpu_wake_flag; volatile char *arc_cpu_sp; /* @@ -87,7 +87,7 @@ void z_arc_slave_start(int cpu_num) #ifdef CONFIG_SMP -static void sched_ipi_handler(void *unused) +static void sched_ipi_handler(const void *unused) { ARG_UNUSED(unused); @@ -98,7 +98,7 @@ static void sched_ipi_handler(void *unused) /* arch implementation of sched_ipi */ void arch_sched_ipi(void) { - u32_t i; + uint32_t i; /* broadcast sched_ipi request to other cores * if the target is current core, hardware will ignore it @@ -108,7 +108,7 @@ void arch_sched_ipi(void) } } -static int arc_smp_init(struct device *dev) +static int arc_smp_init(const struct device *dev) { ARG_UNUSED(dev); struct arc_connect_bcr bcr; @@ -131,6 +131,17 @@ static int arc_smp_init(struct device *dev) return -ENODEV; } + if (bcr.dbg) { + /* configure inter-core debug unit if available */ + uint32_t core_mask = (1 << CONFIG_MP_NUM_CPUS) - 1; + z_arc_connect_debug_select_set(core_mask); + /* Debugger halt cores at conditions */ + z_arc_connect_debug_mask_set(core_mask, (ARC_CONNECT_CMD_DEBUG_MASK_SH + | ARC_CONNECT_CMD_DEBUG_MASK_BH | ARC_CONNECT_CMD_DEBUG_MASK_AH + | ARC_CONNECT_CMD_DEBUG_MASK_H)); + + } + if (bcr.gfrc) { /* global free running count init */ z_arc_connect_gfrc_enable(); diff --git a/arch/arc/core/cache.c b/arch/arc/core/cache.c index 3c0d466fb3d128..d78abdbea4d073 100644 --- a/arch/arc/core/cache.c +++ b/arch/arc/core/cache.c @@ -55,7 +55,7 @@ static bool dcache_available(void) return (val == 0) ? false : true; } -static void dcache_dc_ctrl(u32_t dcache_en_mask) +static void dcache_dc_ctrl(uint32_t dcache_en_mask) { if (dcache_available()) { z_arc_v2_aux_reg_write(_ARC_V2_DC_CTRL, dcache_en_mask); @@ -67,42 +67,27 @@ static void dcache_enable(void) dcache_dc_ctrl(DC_CTRL_DC_ENABLE); } - -/** - * - * @brief Flush multiple d-cache lines to memory - * - * No alignment is required for either or , but since - * dcache_flush_mlines() iterates on the d-cache lines, a cache line - * alignment for both is optimal. - * - * The d-cache line size is specified either via the CONFIG_CACHE_LINE_SIZE - * kconfig option or it is detected at runtime. - * - * @param start_addr the pointer to start the multi-line flush - * @param size the number of bytes that are to be flushed - * - * @return N/A - */ -static void dcache_flush_mlines(u32_t start_addr, u32_t size) +void arch_dcache_flush(void *start_addr_ptr, size_t size) { - u32_t end_addr; + uintptr_t start_addr = (uintptr_t)start_addr_ptr; + uintptr_t end_addr; unsigned int key; if (!dcache_available() || (size == 0U)) { return; } - end_addr = start_addr + size - 1; - start_addr &= (u32_t)(~(DCACHE_LINE_SIZE - 1)); + end_addr = start_addr + size; + + start_addr = ROUND_DOWN(start_addr, DCACHE_LINE_SIZE); key = arch_irq_lock(); /* --enter critical section-- */ do { z_arc_v2_aux_reg_write(_ARC_V2_DC_FLDL, start_addr); - __asm__ volatile("nop_s"); - __asm__ volatile("nop_s"); - __asm__ volatile("nop_s"); + __builtin_arc_nop(); + __builtin_arc_nop(); + __builtin_arc_nop(); /* wait for flush completion */ do { if ((z_arc_v2_aux_reg_read(_ARC_V2_DC_CTRL) & @@ -111,41 +96,41 @@ static void dcache_flush_mlines(u32_t start_addr, u32_t size) } } while (1); start_addr += DCACHE_LINE_SIZE; - } while (start_addr <= end_addr); + } while (start_addr < end_addr); arch_irq_unlock(key); /* --exit critical section-- */ } +void arch_dcache_invd(void *start_addr_ptr, size_t size) +{ + uintptr_t start_addr = (uintptr_t)start_addr_ptr; + uintptr_t end_addr; + unsigned int key; -/** - * - * @brief Flush d-cache lines to main memory - * - * No alignment is required for either or , but since - * sys_cache_flush() iterates on the d-cache lines, a d-cache line alignment for - * both is optimal. - * - * The d-cache line size is specified either via the CONFIG_CACHE_LINE_SIZE - * kconfig option or it is detected at runtime. - * - * @param start_addr the pointer to start the multi-line flush - * @param size the number of bytes that are to be flushed - * - * @return N/A - */ + if (!dcache_available() || (size == 0U)) { + return; + } + end_addr = start_addr + size; + start_addr = ROUND_DOWN(start_addr, DCACHE_LINE_SIZE); -void sys_cache_flush(vaddr_t start_addr, size_t size) -{ - dcache_flush_mlines((u32_t)start_addr, (u32_t)size); -} + key = arch_irq_lock(); /* -enter critical section- */ + do { + z_arc_v2_aux_reg_write(_ARC_V2_DC_IVDL, start_addr); + __builtin_arc_nop(); + __builtin_arc_nop(); + __builtin_arc_nop(); + start_addr += DCACHE_LINE_SIZE; + } while (start_addr < end_addr); + irq_unlock(key); /* -exit critical section- */ +} #if defined(CONFIG_CACHE_LINE_SIZE_DETECT) size_t sys_cache_line_size; static void init_dcache_line_size(void) { - u32_t val; + uint32_t val; val = z_arc_v2_aux_reg_read(_ARC_V2_D_CACHE_BUILD); __ASSERT((val&0xff) != 0U, "d-cache is not present"); @@ -155,7 +140,16 @@ static void init_dcache_line_size(void) } #endif -static int init_dcache(struct device *unused) +size_t arch_cache_line_size_get(void) +{ +#if defined(CONFIG_CACHE_LINE_SIZE_DETECT) + return sys_cache_line_size; +#else + return 0; +#endif +} + +static int init_dcache(const struct device *unused) { ARG_UNUSED(unused); diff --git a/arch/arc/core/cpu_idle.S b/arch/arc/core/cpu_idle.S index 149498333d782e..d1bb0bd85f679e 100644 --- a/arch/arc/core/cpu_idle.S +++ b/arch/arc/core/cpu_idle.S @@ -22,7 +22,7 @@ GTEXT(arch_cpu_atomic_idle) GDATA(z_arc_cpu_sleep_mode) SECTION_VAR(BSS, z_arc_cpu_sleep_mode) - .balign 4 + .align 4 .word 0 /* @@ -43,20 +43,7 @@ SECTION_FUNC(TEXT, arch_cpu_idle) ld r1, [z_arc_cpu_sleep_mode] or r1, r1, (1 << 4) /* set IRQ-enabled bit */ -/* - * It's found that (in nsim_hs_smp), when cpu - * is sleeping, no response to inter-processor interrupt - * although it's pending and interrupts are enabled. - * (Here fire SNPS JIRA issue P10019563-41294 to trace) - * here is a workround - */ -#if defined(CONFIG_SOC_NSIM) && defined(CONFIG_SMP) - seti r1 -_z_arc_idle_loop: - b _z_arc_idle_loop -#else sleep r1 -#endif j_s [blink] nop diff --git a/arch/arc/core/fast_irq.S b/arch/arc/core/fast_irq.S index eebfa1c23b06cd..7d07ff0e5906ae 100644 --- a/arch/arc/core/fast_irq.S +++ b/arch/arc/core/fast_irq.S @@ -126,7 +126,7 @@ firq_nest_1: firq_nest: #endif push_s r0 - j @_isr_demux + j _isr_demux @@ -158,16 +158,15 @@ SECTION_FUNC(TEXT, _firq_exit) */ _get_next_switch_handle - /* restore interrupted context' sp */ - pop sp - cmp r0, r2 bne _firq_switch /* fall to no switch */ -.balign 4 +.align 4 _firq_no_switch: + /* restore interrupted context' sp */ + pop sp /* * Keeping this code block close to those that use it allows using brxx * instruction instead of a pair of cmp and bxx @@ -177,8 +176,10 @@ _firq_no_switch: #endif rtie -.balign 4 +.align 4 _firq_switch: + /* restore interrupted context' sp */ + pop sp #if CONFIG_RGF_NUM_BANKS != 1 /* @@ -260,21 +261,28 @@ _firq_create_irq_stack_frame: /* fall through */ -.balign 4 +.align 4 _firq_switch_from_coop: _set_misc_regs_irq_switch_from_coop /* pc into ilink */ pop_s r0 - mov_s ilink, r0 + mov ilink, r0 pop_s r0 /* status32 into r0 */ sr r0, [_ARC_V2_STATUS32_P0] +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + push_s blink + + bl z_thread_mark_switched_in + + pop_s blink +#endif rtie -.balign 4 +.align 4 _firq_switch_from_rirq: _firq_switch_from_firq: @@ -286,5 +294,12 @@ _firq_switch_from_firq: sr ilink, [_ARC_V2_STATUS32_P0] ld ilink, [sp, -8] /* pc into ilink */ +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + push_s blink + + bl z_thread_mark_switched_in + + pop_s blink +#endif /* LP registers are already restored, just switch back to bank 0 */ rtie diff --git a/arch/arc/core/fatal.c b/arch/arc/core/fatal.c index a6ad1edb7dba79..31d56fc1060d71 100644 --- a/arch/arc/core/fatal.c +++ b/arch/arc/core/fatal.c @@ -16,21 +16,45 @@ #include #include #include -LOG_MODULE_DECLARE(os); +#include +#include + +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); + +#ifdef CONFIG_ARC_EXCEPTION_DEBUG +static void dump_arc_esf(const z_arch_esf_t *esf) +{ + LOG_ERR(" r0: 0x%08x r1: 0x%08x r2: 0x%08x r3: 0x%08x", + esf->r0, esf->r1, esf->r2, esf->r3); + LOG_ERR(" r4: 0x%08x r5: 0x%08x r6: 0x%08x r7: 0x%08x", + esf->r4, esf->r5, esf->r6, esf->r7); + LOG_ERR(" r8: 0x%08x r9: 0x%08x r10: 0x%08x r11: 0x%08x", + esf->r8, esf->r9, esf->r10, esf->r11); + LOG_ERR("r12: 0x%08x r13: 0x%08x pc: 0x%08x", + esf->r12, esf->r13, esf->pc); + LOG_ERR(" blink: 0x%08x status32: 0x%08x", esf->blink, esf->status32); + LOG_ERR("lp_end: 0x%08x lp_start: 0x%08x lp_count: 0x%08x", + esf->lp_end, esf->lp_start, esf->lp_count); +} +#endif void z_arc_fatal_error(unsigned int reason, const z_arch_esf_t *esf) { - if (reason == K_ERR_CPU_EXCEPTION) { - LOG_ERR("Faulting instruction address = 0x%lx", - z_arc_v2_aux_reg_read(_ARC_V2_ERET)); +#ifdef CONFIG_ARC_EXCEPTION_DEBUG + if (esf != NULL) { + dump_arc_esf(esf); } +#endif /* CONFIG_ARC_EXCEPTION_DEBUG */ z_fatal_error(reason, esf); } FUNC_NORETURN void arch_syscall_oops(void *ssf_ptr) { - z_arc_fatal_error(K_ERR_KERNEL_OOPS, ssf_ptr); + /* TODO: convert ssf_ptr contents into an esf, they are not the same */ + ARG_UNUSED(ssf_ptr); + + z_arc_fatal_error(K_ERR_KERNEL_OOPS, NULL); CODE_UNREACHABLE; } diff --git a/arch/arc/core/fault.c b/arch/arc/core/fault.c index 32b988842666a7..c344051247cf2f 100644 --- a/arch/arc/core/fault.c +++ b/arch/arc/core/fault.c @@ -20,7 +20,7 @@ #include #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #ifdef CONFIG_USERSPACE Z_EXC_DECLARE(z_arc_user_string_nlen); @@ -31,95 +31,73 @@ static const struct z_exc_handle exceptions[] = { #endif #if defined(CONFIG_MPU_STACK_GUARD) - -#define IS_MPU_GUARD_VIOLATION(guard_start, fault_addr, stack_ptr) \ - ((fault_addr >= guard_start) && \ - (fault_addr < (guard_start + STACK_GUARD_SIZE)) && \ - (stack_ptr <= (guard_start + STACK_GUARD_SIZE))) - /** * @brief Assess occurrence of current thread's stack corruption * - * This function performs an assessment whether a memory fault (on a - * given memory address) is the result of stack memory corruption of - * the current thread. - * - * Thread stack corruption for supervisor threads or user threads in - * privilege mode (when User Space is supported) is reported upon an - * attempt to access the stack guard area (if MPU Stack Guard feature - * is supported). Additionally the current thread stack pointer - * must be pointing inside or below the guard area. - * - * Thread stack corruption for user threads in user mode is reported, - * if the current stack pointer is pointing below the start of the current - * thread's stack. + * This function performs an assessment whether a memory fault (on a given + * memory address) is the result of a stack overflow of the current thread. * - * Notes: - * - we assume a fully descending stack, - * - we assume a stacking error has occurred, - * - the function shall be called when handling MPU privilege violation - * - * If stack corruption is detected, the function returns the lowest - * allowed address where the Stack Pointer can safely point to, to - * prevent from errors when un-stacking the corrupted stack frame - * upon exception return. + * When called, we know at this point that we received an ARC + * protection violation, with any cause code, with the protection access + * error either "MPU" or "Secure MPU". In other words, an MPU fault of + * some kind. Need to determine whether this is a general MPU access + * exception or the specific case of a stack overflow. * * @param fault_addr memory address on which memory access violation * has been reported. * @param sp stack pointer when exception comes out - * - * @return The lowest allowed stack frame pointer, if error is a - * thread stack corruption, otherwise return 0. + * @retval True if this appears to be a stack overflow + * @retval False if this does not appear to be a stack overflow */ -static u32_t z_check_thread_stack_fail(const u32_t fault_addr, u32_t sp) +static bool z_check_thread_stack_fail(const uint32_t fault_addr, uint32_t sp) { const struct k_thread *thread = _current; + uint32_t guard_end, guard_start; if (!thread) { - return 0; + /* TODO: Under what circumstances could we get here ? */ + return false; } -#if defined(CONFIG_USERSPACE) - if (thread->arch.priv_stack_start) { - /* User thread */ - if (z_arc_v2_aux_reg_read(_ARC_V2_ERSTATUS) - & _ARC_V2_STATUS32_U) { - /* Thread's user stack corruption */ -#ifdef CONFIG_ARC_HAS_SECURE - sp = z_arc_v2_aux_reg_read(_ARC_V2_SEC_U_SP); -#else - sp = z_arc_v2_aux_reg_read(_ARC_V2_USER_SP); -#endif - if (sp <= (u32_t)thread->stack_obj) { - return (u32_t)thread->stack_obj; - } + +#ifdef CONFIG_USERSPACE + if ((thread->base.user_options & K_USER) != 0) { + if ((z_arc_v2_aux_reg_read(_ARC_V2_ERSTATUS) & + _ARC_V2_STATUS32_U) != 0) { + /* Normal user mode context. There is no specific + * "guard" installed in this case, instead what's + * happening is that the stack pointer is crashing + * into the privilege mode stack buffer which + * immediately precededs it. + */ + guard_end = thread->stack_info.start; + guard_start = (uint32_t)thread->stack_obj; } else { - /* User thread in privilege mode */ - if (IS_MPU_GUARD_VIOLATION( - thread->arch.priv_stack_start - STACK_GUARD_SIZE, - fault_addr, sp)) { - /* Thread's privilege stack corruption */ - return thread->arch.priv_stack_start; - } + /* Special case: handling a syscall on privilege stack. + * There is guard memory reserved immediately before + * it. + */ + guard_end = thread->arch.priv_stack_start; + guard_start = guard_end - Z_ARC_STACK_GUARD_SIZE; } - } else { + } else +#endif /* CONFIG_USERSPACE */ + { /* Supervisor thread */ - if (IS_MPU_GUARD_VIOLATION((u32_t)thread->stack_obj, - fault_addr, sp)) { - /* Supervisor thread stack corruption */ - return (u32_t)thread->stack_obj + STACK_GUARD_SIZE; - } + guard_end = thread->stack_info.start; + guard_start = guard_end - Z_ARC_STACK_GUARD_SIZE; } -#else /* CONFIG_USERSPACE */ - if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start, - fault_addr, sp)) { - /* Thread stack corruption */ - return thread->stack_info.start + STACK_GUARD_SIZE; + + /* treat any MPU exceptions within the guard region as a stack + * overflow if the stack pointer is at or below the end of the guard + * region. + */ + if (sp <= guard_end && fault_addr < guard_end && + fault_addr >= guard_start) { + return true; } -#endif /* CONFIG_USERSPACE */ - return 0; + return false; } - #endif #ifdef CONFIG_ARC_EXCEPTION_DEBUG @@ -129,7 +107,7 @@ static u32_t z_check_thread_stack_fail(const u32_t fault_addr, u32_t sp) * These codes and parameters do not have associated* names in * the technical manual, just switch on the values in Table 6-5 */ -static const char *get_protv_access_err(u32_t parameter) +static const char *get_protv_access_err(uint32_t parameter) { switch (parameter) { case 0x1: @@ -151,7 +129,7 @@ static const char *get_protv_access_err(u32_t parameter) } } -static void dump_protv_exception(u32_t cause, u32_t parameter) +static void dump_protv_exception(uint32_t cause, uint32_t parameter) { switch (cause) { case 0x0: @@ -185,7 +163,7 @@ static void dump_protv_exception(u32_t cause, u32_t parameter) } } -static void dump_machine_check_exception(u32_t cause, u32_t parameter) +static void dump_machine_check_exception(uint32_t cause, uint32_t parameter) { switch (cause) { case 0x0: @@ -233,7 +211,7 @@ static void dump_machine_check_exception(u32_t cause, u32_t parameter) } } -static void dump_privilege_exception(u32_t cause, u32_t parameter) +static void dump_privilege_exception(uint32_t cause, uint32_t parameter) { switch (cause) { case 0x0: @@ -289,7 +267,7 @@ static void dump_privilege_exception(u32_t cause, u32_t parameter) } } -static void dump_exception_info(u32_t vector, u32_t cause, u32_t parameter) +static void dump_exception_info(uint32_t vector, uint32_t cause, uint32_t parameter) { if (vector >= 0x10 && vector <= 0xFF) { LOG_ERR("interrupt %u", vector); @@ -363,19 +341,19 @@ static void dump_exception_info(u32_t vector, u32_t cause, u32_t parameter) * invokes the user provided routine k_sys_fatal_error_handler() which is * responsible for implementing the error handling policy. */ -void _Fault(z_arch_esf_t *esf, u32_t old_sp) +void _Fault(z_arch_esf_t *esf, uint32_t old_sp) { - u32_t vector, cause, parameter; - u32_t exc_addr = z_arc_v2_aux_reg_read(_ARC_V2_EFA); - u32_t ecr = z_arc_v2_aux_reg_read(_ARC_V2_ECR); + uint32_t vector, cause, parameter; + uint32_t exc_addr = z_arc_v2_aux_reg_read(_ARC_V2_EFA); + uint32_t ecr = z_arc_v2_aux_reg_read(_ARC_V2_ECR); #ifdef CONFIG_USERSPACE for (int i = 0; i < ARRAY_SIZE(exceptions); i++) { - u32_t start = (u32_t)exceptions[i].start; - u32_t end = (u32_t)exceptions[i].end; + uint32_t start = (uint32_t)exceptions[i].start; + uint32_t end = (uint32_t)exceptions[i].end; if (esf->pc >= start && esf->pc < end) { - esf->pc = (u32_t)(exceptions[i].fixup); + esf->pc = (uint32_t)(exceptions[i].fixup); return; } } diff --git a/arch/arc/core/fault_s.S b/arch/arc/core/fault_s.S index f76219bf516da2..5285f9a5ed36ae 100644 --- a/arch/arc/core/fault_s.S +++ b/arch/arc/core/fault_s.S @@ -84,7 +84,7 @@ _exc_entry: * and exception is raised, then here it's guaranteed that * exception handling has necessary stack to use */ - mov_s ilink, sp + mov ilink, sp _get_curr_cpu_irq_stack sp sub sp, sp, (CONFIG_ISR_STACK_SIZE - CONFIG_ARC_EXCEPTION_STACK_SIZE) @@ -104,7 +104,7 @@ _exc_entry: /* sp is parameter of _Fault */ mov_s r0, sp /* ilink is the thread's original sp */ - mov_s r1, ilink + mov r1, ilink jl _Fault _exc_return: @@ -143,7 +143,7 @@ _exc_return: /* save r2 in ilink because of the possible following reg * bank switch */ - mov_s ilink, r2 + mov ilink, r2 #endif lr r3, [_ARC_V2_STATUS32] and r3,r3,(~(_ARC_V2_STATUS32_AE | _ARC_V2_STATUS32_RB(7))) @@ -187,7 +187,7 @@ _exc_return_from_exc: sr r0, [_ARC_V2_ERET] _pop_irq_stack_frame - mov_s sp, ilink + mov sp, ilink rtie /* separated entry for trap which may be used by irq_offload, USERPSACE */ @@ -199,7 +199,7 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap) cmp ilink, _TRAP_S_CALL_SYSTEM_CALL bne _do_non_syscall_trap /* do sys_call */ - mov_s ilink, K_SYSCALL_LIMIT + mov ilink, K_SYSCALL_LIMIT cmp r6, ilink blo valid_syscall_id diff --git a/arch/arc/core/irq_manage.c b/arch/arc/core/irq_manage.c index c1db189b825e6c..6abdc41bceb453 100644 --- a/arch/arc/core/irq_manage.c +++ b/arch/arc/core/irq_manage.c @@ -32,10 +32,10 @@ */ #if defined(CONFIG_ARC_FIRQ_STACK) #if defined(CONFIG_SMP) -K_THREAD_STACK_ARRAY_DEFINE(_firq_interrupt_stack, CONFIG_MP_NUM_CPUS, +K_KERNEL_STACK_ARRAY_DEFINE(_firq_interrupt_stack, CONFIG_MP_NUM_CPUS, CONFIG_ARC_FIRQ_STACK_SIZE); #else -K_THREAD_STACK_DEFINE(_firq_interrupt_stack, CONFIG_ARC_FIRQ_STACK_SIZE); +K_KERNEL_STACK_DEFINE(_firq_interrupt_stack, CONFIG_ARC_FIRQ_STACK_SIZE); #endif /* @@ -46,11 +46,11 @@ K_THREAD_STACK_DEFINE(_firq_interrupt_stack, CONFIG_ARC_FIRQ_STACK_SIZE); void z_arc_firq_stack_set(void) { #ifdef CONFIG_SMP - char *firq_sp = Z_THREAD_STACK_BUFFER( + char *firq_sp = Z_KERNEL_STACK_BUFFER( _firq_interrupt_stack[z_arc_v2_core_id()]) + CONFIG_ARC_FIRQ_STACK_SIZE; #else - char *firq_sp = Z_THREAD_STACK_BUFFER(_firq_interrupt_stack) + + char *firq_sp = Z_KERNEL_STACK_BUFFER(_firq_interrupt_stack) + CONFIG_ARC_FIRQ_STACK_SIZE; #endif @@ -63,17 +63,17 @@ void z_arc_firq_stack_set(void) /* only ilink will not be banked, so use ilink as channel * between 2 banks */ - "mov ilink, %0 \n\t" - "lr %0, [%1] \n\t" - "or %0, %0, %2 \n\t" - "kflag %0 \n\t" - "mov sp, ilink \n\t" + "mov %%ilink, %0\n\t" + "lr %0, [%1]\n\t" + "or %0, %0, %2\n\t" + "kflag %0\n\t" + "mov %%sp, %%ilink\n\t" /* switch back to bank0, use ilink to avoid the pollution of * bank1's gp regs. */ - "lr ilink, [%1] \n\t" - "and ilink, ilink, %3 \n\t" - "kflag ilink \n\t" + "lr %%ilink, [%1]\n\t" + "and %%ilink, %%ilink, %3\n\t" + "kflag %%ilink\n\t" : : "r"(firq_sp), "i"(_ARC_V2_STATUS32), "i"(_ARC_V2_STATUS32_RB(1)), @@ -137,7 +137,7 @@ int arch_irq_is_enabled(unsigned int irq) * @return N/A */ -void z_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags) +void z_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { ARG_UNUSED(flags); @@ -165,7 +165,7 @@ void z_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags) * @return N/A */ -void z_irq_spurious(void *unused) +void z_irq_spurious(const void *unused) { ARG_UNUSED(unused); z_fatal_error(K_ERR_SPURIOUS_IRQ, NULL); @@ -173,8 +173,8 @@ void z_irq_spurious(void *unused) #ifdef CONFIG_DYNAMIC_INTERRUPTS int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *parameter), void *parameter, - u32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { z_isr_install(irq, routine, parameter); z_irq_priority_set(irq, priority, flags); diff --git a/arch/arc/core/irq_offload.c b/arch/arc/core/irq_offload.c index 9523d2a49d8fba..0c8de0901dba4e 100644 --- a/arch/arc/core/irq_offload.c +++ b/arch/arc/core/irq_offload.c @@ -12,7 +12,7 @@ #include static irq_offload_routine_t offload_routine; -static void *offload_param; +static const void *offload_param; /* Called by trap_s exception handler */ void z_irq_do_offload(void) @@ -20,7 +20,7 @@ void z_irq_do_offload(void) offload_routine(offload_param); } -void arch_irq_offload(irq_offload_routine_t routine, void *parameter) +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { offload_routine = routine; diff --git a/arch/arc/core/isr_wrapper.S b/arch/arc/core/isr_wrapper.S index 01f4ae1e75ae88..344402c4dfb708 100644 --- a/arch/arc/core/isr_wrapper.S +++ b/arch/arc/core/isr_wrapper.S @@ -24,8 +24,8 @@ GTEXT(_isr_wrapper) GTEXT(_isr_demux) -#if defined(CONFIG_SYS_POWER_MANAGEMENT) -GTEXT(z_sys_power_save_idle_exit) +#if defined(CONFIG_PM) +GTEXT(z_pm_save_idle_exit) #endif /* @@ -201,32 +201,32 @@ From RIRQ: */ SECTION_FUNC(TEXT, _isr_wrapper) -#if defined(CONFIG_ARC_FIRQ) +#ifdef CONFIG_ARC_FIRQ #if CONFIG_RGF_NUM_BANKS == 1 /* free r0 here, use r0 to check whether irq is firq. * for rirq, as sp will not change and r0 already saved, this action - * in fact is an action like nop. + * in fact is useless * for firq, r0 will be restored later */ - st_s r0, [sp] + push r0 #endif lr r0, [_ARC_V2_AUX_IRQ_ACT] ffs r0, r0 cmp r0, 0 #if CONFIG_RGF_NUM_BANKS == 1 bnz rirq_path - ld_s r0, [sp] + pop r0 /* 1-register bank FIRQ handling must save registers on stack */ _create_irq_stack_frame lr r0, [_ARC_V2_STATUS32_P0] st_s r0, [sp, ___isf_t_status32_OFFSET] - lr r0, [_ARC_V2_ERET] - st_s r0, [sp, ___isf_t_pc_OFFSET] + st ilink, [sp, ___isf_t_pc_OFFSET] mov_s r3, _firq_exit mov_s r2, _firq_enter j_s [r2] rirq_path: + add sp, sp, 4 mov_s r3, _rirq_exit mov_s r2, _rirq_enter j_s [r2] @@ -243,24 +243,23 @@ rirq_path: j_s [r2] #endif -#if defined(CONFIG_SYS_POWER_MANAGEMENT) +/* r0, r1, and r3 will be used in exit_tickless_idle macro */ .macro exit_tickless_idle +#if defined(CONFIG_PM) clri r0 /* do not interrupt exiting tickless idle operations */ mov_s r1, _kernel - ld_s r0, [r1, _kernel_offset_to_idle] /* requested idle duration */ - breq r0, 0, _skip_sys_power_save_idle_exit + ld_s r3, [r1, _kernel_offset_to_idle] /* requested idle duration */ + breq r3, 0, _skip_pm_save_idle_exit st 0, [r1, _kernel_offset_to_idle] /* zero idle duration */ push_s blink - jl z_sys_power_save_idle_exit + jl z_pm_save_idle_exit pop_s blink -_skip_sys_power_save_idle_exit: +_skip_pm_save_idle_exit: seti r0 -.endm -#else - #define exit_tickless_idle #endif +.endm /* when getting here, r3 contains the interrupt exit stub to call */ SECTION_FUNC(TEXT, _isr_demux) @@ -276,15 +275,10 @@ SECTION_FUNC(TEXT, _isr_demux) push r59 #endif -#ifdef CONFIG_EXECUTION_BENCHMARKING - bl read_timer_start_of_isr -#endif - -#if defined(CONFIG_TRACING) +#ifdef CONFIG_TRACING_ISR bl sys_trace_isr_enter #endif /* cannot be done before this point because we must be able to run C */ - /* r0 is available to be stomped here, and exit_tickless_idle uses it */ exit_tickless_idle lr r0, [_ARC_V2_ICAUSE] @@ -300,13 +294,6 @@ irq_hint_handled: add3 r0, r1, r0 /* table entries are 8-bytes wide */ ld_s r1, [r0, 4] /* ISR into r1 */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - push_s r0 - push_s r1 - bl read_timer_end_of_isr - pop_s r1 - pop_s r0 -#endif jl_s.d [r1] ld_s r0, [r0] /* delay slot: ISR parameter into r0 */ diff --git a/arch/arc/core/mpu/CMakeLists.txt b/arch/arc/core/mpu/CMakeLists.txt index a81e4ebdb2cd31..c3ec9a3f1a1bbc 100644 --- a/arch/arc/core/mpu/CMakeLists.txt +++ b/arch/arc/core/mpu/CMakeLists.txt @@ -2,5 +2,5 @@ zephyr_library() -zephyr_library_sources_if_kconfig(arc_core_mpu.c) -zephyr_library_sources_if_kconfig(arc_mpu.c) +zephyr_library_sources_ifdef(CONFIG_ARC_CORE_MPU arc_core_mpu.c) +zephyr_library_sources_ifdef(CONFIG_ARC_MPU arc_mpu.c) diff --git a/arch/arc/core/mpu/Kconfig b/arch/arc/core/mpu/Kconfig index 6a1dbd3473b989..65745a5d40f71e 100644 --- a/arch/arc/core/mpu/Kconfig +++ b/arch/arc/core/mpu/Kconfig @@ -27,9 +27,10 @@ config MPU_STACK_GUARD config ARC_MPU bool "ARC MPU Support" + select MPU + select SRAM_REGION_PERMISSIONS select ARC_CORE_MPU select THREAD_STACK_INFO - select MEMORY_PROTECTION select GEN_PRIV_STACKS if ARC_MPU_VER = 2 select MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT if ARC_MPU_VER = 2 select MPU_REQUIRES_NON_OVERLAPPING_REGIONS if ARC_MPU_VER = 3 diff --git a/arch/arc/core/mpu/arc_core_mpu.c b/arch/arc/core/mpu/arc_core_mpu.c index db4c7d6f0be689..0cf1e8081bd313 100644 --- a/arch/arc/core/mpu/arc_core_mpu.c +++ b/arch/arc/core/mpu/arc_core_mpu.c @@ -32,64 +32,6 @@ int arch_mem_domain_max_partitions_get(void) return arc_core_mpu_get_max_domain_partition_regions(); } -/* - * Reset MPU region for a single memory partition - */ -void arch_mem_domain_partition_remove(struct k_mem_domain *domain, - u32_t partition_id) -{ - if (_current->mem_domain_info.mem_domain != domain) { - return; - } - - arc_core_mpu_disable(); - arc_core_mpu_remove_mem_partition(domain, partition_id); - arc_core_mpu_enable(); -} - -/* - * Configure MPU memory domain - */ -void arch_mem_domain_thread_add(struct k_thread *thread) -{ - if (_current != thread) { - return; - } - - arc_core_mpu_disable(); - arc_core_mpu_configure_mem_domain(thread); - arc_core_mpu_enable(); -} - -/* - * Destroy MPU regions for the mem domain - */ -void arch_mem_domain_destroy(struct k_mem_domain *domain) -{ - if (_current->mem_domain_info.mem_domain != domain) { - return; - } - - arc_core_mpu_disable(); - arc_core_mpu_remove_mem_domain(domain); - arc_core_mpu_enable(); -} - -void arch_mem_domain_partition_add(struct k_mem_domain *domain, - u32_t partition_id) -{ - /* No-op on this architecture */ -} - -void arch_mem_domain_thread_remove(struct k_thread *thread) -{ - if (_current != thread) { - return; - } - - arch_mem_domain_destroy(thread->mem_domain_info.mem_domain); -} - /* * Validate the given buffer is user accessible or not */ diff --git a/arch/arc/core/mpu/arc_mpu.c b/arch/arc/core/mpu/arc_mpu.c index 53051d4671f3f4..f031a7e79fb512 100644 --- a/arch/arc/core/mpu/arc_mpu.c +++ b/arch/arc/core/mpu/arc_mpu.c @@ -21,20 +21,20 @@ LOG_MODULE_REGISTER(mpu); * @brief Get the number of supported MPU regions * */ -static inline u8_t get_num_regions(void) +static inline uint8_t get_num_regions(void) { - u32_t num = z_arc_v2_aux_reg_read(_ARC_V2_MPU_BUILD); + uint32_t num = z_arc_v2_aux_reg_read(_ARC_V2_MPU_BUILD); num = (num & 0xFF00U) >> 8U; - return (u8_t)num; + return (uint8_t)num; } /** * This internal function is utilized by the MPU driver to parse the intent * type (i.e. THREAD_STACK_REGION) and return the correct parameter set. */ -static inline u32_t get_region_attr_by_type(u32_t type) +static inline uint32_t get_region_attr_by_type(uint32_t type) { switch (type) { case THREAD_STACK_USER_REGION: diff --git a/arch/arc/core/mpu/arc_mpu_v2_internal.h b/arch/arc/core/mpu/arc_mpu_v2_internal.h index 640ce8666f791b..20f8cea4b14340 100644 --- a/arch/arc/core/mpu/arc_mpu_v2_internal.h +++ b/arch/arc/core/mpu/arc_mpu_v2_internal.h @@ -16,32 +16,28 @@ #define AUX_MPU_RDP_ATTR_MASK (0x1FC) #define AUX_MPU_RDP_SIZE_MASK (0xE03) -#define _ARC_V2_MPU_EN (0x409) -#define _ARC_V2_MPU_RDB0 (0x422) -#define _ARC_V2_MPU_RDP0 (0x423) - /* For MPU version 2, the minimum protection region size is 2048 bytes */ #define ARC_FEATURE_MPU_ALIGNMENT_BITS 11 /** * This internal function initializes a MPU region */ -static inline void _region_init(u32_t index, u32_t region_addr, u32_t size, - u32_t region_attr) +static inline void _region_init(uint32_t index, uint32_t region_addr, uint32_t size, + uint32_t region_attr) { - u8_t bits = find_msb_set(size) - 1; - index = index * 2U; - if (bits < ARC_FEATURE_MPU_ALIGNMENT_BITS) { - bits = ARC_FEATURE_MPU_ALIGNMENT_BITS; - } + if (size > 0) { + uint8_t bits = find_msb_set(size) - 1; - if ((1 << bits) < size) { - bits++; - } + if (bits < ARC_FEATURE_MPU_ALIGNMENT_BITS) { + bits = ARC_FEATURE_MPU_ALIGNMENT_BITS; + } + + if ((1 << bits) < size) { + bits++; + } - if (size > 0) { region_attr &= ~(AUX_MPU_RDP_SIZE_MASK); region_attr |= AUX_MPU_RDP_REGION_SIZE(bits); region_addr |= AUX_MPU_RDB_VALID_MASK; @@ -57,7 +53,7 @@ static inline void _region_init(u32_t index, u32_t region_addr, u32_t size, * This internal function is utilized by the MPU driver to parse the intent * type (i.e. THREAD_STACK_REGION) and return the correct region index. */ -static inline int get_region_index_by_type(u32_t type) +static inline int get_region_index_by_type(uint32_t type) { /* * The new MPU regions are allocated per type after the statically @@ -90,7 +86,7 @@ static inline int get_region_index_by_type(u32_t type) /** * This internal function checks if region is enabled or not */ -static inline bool _is_enabled_region(u32_t r_index) +static inline bool _is_enabled_region(uint32_t r_index) { return ((z_arc_v2_aux_reg_read(_ARC_V2_MPU_RDB0 + r_index * 2U) & AUX_MPU_RDB_VALID_MASK) == AUX_MPU_RDB_VALID_MASK); @@ -99,11 +95,11 @@ static inline bool _is_enabled_region(u32_t r_index) /** * This internal function check if the given buffer in in the region */ -static inline bool _is_in_region(u32_t r_index, u32_t start, u32_t size) +static inline bool _is_in_region(uint32_t r_index, uint32_t start, uint32_t size) { - u32_t r_addr_start; - u32_t r_addr_end; - u32_t r_size_lshift; + uint32_t r_addr_start; + uint32_t r_addr_end; + uint32_t r_size_lshift; r_addr_start = z_arc_v2_aux_reg_read(_ARC_V2_MPU_RDB0 + r_index * 2U) & (~AUX_MPU_RDB_VALID_MASK); @@ -122,9 +118,9 @@ static inline bool _is_in_region(u32_t r_index, u32_t start, u32_t size) /** * This internal function check if the region is user accessible or not */ -static inline bool _is_user_accessible_region(u32_t r_index, int write) +static inline bool _is_user_accessible_region(uint32_t r_index, int write) { - u32_t r_ap; + uint32_t r_ap; r_ap = z_arc_v2_aux_reg_read(_ARC_V2_MPU_RDP0 + r_index * 2U); @@ -146,10 +142,10 @@ static inline bool _is_user_accessible_region(u32_t r_index, int write) * @param base base address in RAM * @param size size of the region */ -static inline int _mpu_configure(u8_t type, u32_t base, u32_t size) +static inline int _mpu_configure(uint8_t type, uint32_t base, uint32_t size) { - s32_t region_index = get_region_index_by_type(type); - u32_t region_attr = get_region_attr_by_type(type); + int32_t region_index = get_region_index_by_type(type); + uint32_t region_attr = get_region_attr_by_type(type); LOG_DBG("Region info: 0x%x 0x%x", base, size); @@ -200,7 +196,8 @@ void arc_core_mpu_configure_thread(struct k_thread *thread) if (thread->base.user_options & K_USER) { LOG_DBG("configure user thread %p's stack", thread); if (_mpu_configure(THREAD_STACK_USER_REGION, - (u32_t)thread->stack_obj, thread->stack_info.size) < 0) { + (uint32_t)thread->stack_info.start, + thread->stack_info.size) < 0) { LOG_ERR("user thread %p's stack failed", thread); return; } @@ -217,9 +214,9 @@ void arc_core_mpu_configure_thread(struct k_thread *thread) * * @param region_attr region attribute of default region */ -void arc_core_mpu_default(u32_t region_attr) +void arc_core_mpu_default(uint32_t region_attr) { - u32_t val = z_arc_v2_aux_reg_read(_ARC_V2_MPU_EN) & + uint32_t val = z_arc_v2_aux_reg_read(_ARC_V2_MPU_EN) & (~AUX_MPU_RDP_ATTR_MASK); region_attr &= AUX_MPU_RDP_ATTR_MASK; @@ -234,8 +231,8 @@ void arc_core_mpu_default(u32_t region_attr) * @param base base address * @param region_attr region attribute */ -int arc_core_mpu_region(u32_t index, u32_t base, u32_t size, - u32_t region_attr) +int arc_core_mpu_region(uint32_t index, uint32_t base, uint32_t size, + uint32_t region_attr) { if (index >= get_num_regions()) { return -EINVAL; @@ -259,7 +256,7 @@ void arc_core_mpu_configure_mem_domain(struct k_thread *thread) { int region_index = get_region_index_by_type(THREAD_DOMAIN_PARTITION_REGION); - u32_t num_partitions; + uint32_t num_partitions; struct k_mem_partition *pparts; struct k_mem_domain *mem_domain = NULL; @@ -316,7 +313,7 @@ void arc_core_mpu_remove_mem_domain(struct k_mem_domain *mem_domain) * @param partition_id memory partition id */ void arc_core_mpu_remove_mem_partition(struct k_mem_domain *domain, - u32_t part_id) + uint32_t part_id) { ARG_UNUSED(domain); @@ -351,7 +348,7 @@ int arc_core_mpu_buffer_validate(void *addr, size_t size, int write) */ for (r_index = 0; r_index < get_num_regions(); r_index++) { if (!_is_enabled_region(r_index) || - !_is_in_region(r_index, (u32_t)addr, size)) { + !_is_in_region(r_index, (uint32_t)addr, size)) { continue; } @@ -373,12 +370,12 @@ int arc_core_mpu_buffer_validate(void *addr, size_t size, int write) * This function provides the default configuration mechanism for the Memory * Protection Unit (MPU). */ -static int arc_mpu_init(struct device *arg) +static int arc_mpu_init(const struct device *arg) { ARG_UNUSED(arg); - u32_t num_regions; - u32_t i; + uint32_t num_regions; + uint32_t i; num_regions = get_num_regions(); diff --git a/arch/arc/core/mpu/arc_mpu_v3_internal.h b/arch/arc/core/mpu/arc_mpu_v3_internal.h index 6d1d80d5ace30a..3bf826b5455aa4 100644 --- a/arch/arc/core/mpu/arc_mpu_v3_internal.h +++ b/arch/arc/core/mpu/arc_mpu_v3_internal.h @@ -12,16 +12,6 @@ #define AUX_MPU_RPER_ATTR_MASK (0x1FF) -#define _ARC_V2_MPU_EN (0x409) - -/* aux regs added in MPU version 3 */ -#define _ARC_V2_MPU_INDEX (0x448) /* MPU index */ -#define _ARC_V2_MPU_RSTART (0x449) /* MPU region start address */ -#define _ARC_V2_MPU_REND (0x44A) /* MPU region end address */ -#define _ARC_V2_MPU_RPER (0x44B) /* MPU region permission register */ -#define _ARC_V2_MPU_PROBE (0x44C) /* MPU probe register */ - - /* For MPU version 3, the minimum protection region size is 32 bytes */ #define ARC_FEATURE_MPU_ALIGNMENT_BITS 5 @@ -62,14 +52,14 @@ * memory areas where dynamic MPU programming is allowed. */ struct dynamic_region_info { - u8_t index; - u32_t base; - u32_t size; - u32_t attr; + uint8_t index; + uint32_t base; + uint32_t size; + uint32_t attr; }; -static u8_t dynamic_regions_num; -static u8_t dynamic_region_index; +static uint8_t dynamic_regions_num; +static uint8_t dynamic_region_index; /** * Global array, holding the MPU region index of @@ -79,41 +69,41 @@ static u8_t dynamic_region_index; static struct dynamic_region_info dyn_reg_info[MPU_DYNAMIC_REGION_AREAS_NUM]; #endif /* CONFIG_MPU_GAP_FILLING */ -static u8_t static_regions_num; +static uint8_t static_regions_num; #ifdef CONFIG_ARC_NORMAL_FIRMWARE /* \todo through secure service to access mpu */ -static inline void _region_init(u32_t index, u32_t region_addr, u32_t size, - u32_t region_attr) +static inline void _region_init(uint32_t index, uint32_t region_addr, uint32_t size, + uint32_t region_attr) { } -static inline void _region_set_attr(u32_t index, u32_t attr) +static inline void _region_set_attr(uint32_t index, uint32_t attr) { } -static inline u32_t _region_get_attr(u32_t index) +static inline uint32_t _region_get_attr(uint32_t index) { return 0; } -static inline u32_t _region_get_start(u32_t index) +static inline uint32_t _region_get_start(uint32_t index) { return 0; } -static inline void _region_set_start(u32_t index, u32_t start) +static inline void _region_set_start(uint32_t index, uint32_t start) { } -static inline u32_t _region_get_end(u32_t index) +static inline uint32_t _region_get_end(uint32_t index) { return 0; } -static inline void _region_set_end(u32_t index, u32_t end) +static inline void _region_set_end(uint32_t index, uint32_t end) { } @@ -121,7 +111,7 @@ static inline void _region_set_end(u32_t index, u32_t end) * This internal function probes the given addr's MPU index.if not * in MPU, returns error */ -static inline int _mpu_probe(u32_t addr) +static inline int _mpu_probe(uint32_t addr) { return -EINVAL; } @@ -129,7 +119,7 @@ static inline int _mpu_probe(u32_t addr) /** * This internal function checks if MPU region is enabled or not */ -static inline bool _is_enabled_region(u32_t r_index) +static inline bool _is_enabled_region(uint32_t r_index) { return false; } @@ -137,14 +127,14 @@ static inline bool _is_enabled_region(u32_t r_index) /** * This internal function check if the region is user accessible or not */ -static inline bool _is_user_accessible_region(u32_t r_index, int write) +static inline bool _is_user_accessible_region(uint32_t r_index, int write) { return false; } #else /* CONFIG_ARC_NORMAL_FIRMWARE */ /* the following functions are prepared for SECURE_FRIMWARE */ -static inline void _region_init(u32_t index, u32_t region_addr, u32_t size, - u32_t region_attr) +static inline void _region_init(uint32_t index, uint32_t region_addr, uint32_t size, + uint32_t region_attr) { if (size < (1 << ARC_FEATURE_MPU_ALIGNMENT_BITS)) { size = (1 << ARC_FEATURE_MPU_ALIGNMENT_BITS); @@ -162,34 +152,34 @@ static inline void _region_init(u32_t index, u32_t region_addr, u32_t size, z_arc_v2_aux_reg_write(_ARC_V2_MPU_RPER, region_attr); } -static inline void _region_set_attr(u32_t index, u32_t attr) +static inline void _region_set_attr(uint32_t index, uint32_t attr) { z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index); z_arc_v2_aux_reg_write(_ARC_V2_MPU_RPER, attr | AUX_MPU_RPER_VALID_MASK); } -static inline u32_t _region_get_attr(u32_t index) +static inline uint32_t _region_get_attr(uint32_t index) { z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index); return z_arc_v2_aux_reg_read(_ARC_V2_MPU_RPER); } -static inline u32_t _region_get_start(u32_t index) +static inline uint32_t _region_get_start(uint32_t index) { z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index); return z_arc_v2_aux_reg_read(_ARC_V2_MPU_RSTART); } -static inline void _region_set_start(u32_t index, u32_t start) +static inline void _region_set_start(uint32_t index, uint32_t start) { z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index); z_arc_v2_aux_reg_write(_ARC_V2_MPU_RSTART, start); } -static inline u32_t _region_get_end(u32_t index) +static inline uint32_t _region_get_end(uint32_t index) { z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index); @@ -197,7 +187,7 @@ static inline u32_t _region_get_end(u32_t index) (1 << ARC_FEATURE_MPU_ALIGNMENT_BITS); } -static inline void _region_set_end(u32_t index, u32_t end) +static inline void _region_set_end(uint32_t index, uint32_t end) { z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index); z_arc_v2_aux_reg_write(_ARC_V2_MPU_REND, end - @@ -208,9 +198,9 @@ static inline void _region_set_end(u32_t index, u32_t end) * This internal function probes the given addr's MPU index.if not * in MPU, returns error */ -static inline int _mpu_probe(u32_t addr) +static inline int _mpu_probe(uint32_t addr) { - u32_t val; + uint32_t val; z_arc_v2_aux_reg_write(_ARC_V2_MPU_PROBE, addr); val = z_arc_v2_aux_reg_read(_ARC_V2_MPU_INDEX); @@ -226,7 +216,7 @@ static inline int _mpu_probe(u32_t addr) /** * This internal function checks if MPU region is enabled or not */ -static inline bool _is_enabled_region(u32_t r_index) +static inline bool _is_enabled_region(uint32_t r_index) { z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, r_index); return ((z_arc_v2_aux_reg_read(_ARC_V2_MPU_RPER) & @@ -236,9 +226,9 @@ static inline bool _is_enabled_region(u32_t r_index) /** * This internal function check if the region is user accessible or not */ -static inline bool _is_user_accessible_region(u32_t r_index, int write) +static inline bool _is_user_accessible_region(uint32_t r_index, int write) { - u32_t r_ap; + uint32_t r_ap; z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, r_index); r_ap = z_arc_v2_aux_reg_read(_ARC_V2_MPU_RPER); @@ -259,7 +249,7 @@ static inline bool _is_user_accessible_region(u32_t r_index, int write) * This internal function checks the area given by (start, size) * and returns the index if the area match one MPU entry */ -static inline int _get_region_index(u32_t start, u32_t size) +static inline int _get_region_index(uint32_t start, uint32_t size) { int index = _mpu_probe(start); @@ -295,8 +285,8 @@ static inline int _dynamic_region_allocate_index(void) * @param attr region attribute * @return <0 failure, >0 allocated dynamic region index */ -static int _dynamic_region_allocate_and_init(u32_t base, u32_t size, - u32_t attr) +static int _dynamic_region_allocate_and_init(uint32_t base, uint32_t size, + uint32_t attr) { int u_region_index = _get_region_index(base, size); int region_index; @@ -321,10 +311,10 @@ static int _dynamic_region_allocate_and_init(u32_t base, u32_t size, * region, possibly splitting the underlying region into two. */ - u32_t u_region_start = _region_get_start(u_region_index); - u32_t u_region_end = _region_get_end(u_region_index); - u32_t u_region_attr = _region_get_attr(u_region_index); - u32_t end = base + size; + uint32_t u_region_start = _region_get_start(u_region_index); + uint32_t u_region_end = _region_get_end(u_region_index); + uint32_t u_region_attr = _region_get_attr(u_region_index); + uint32_t end = base + size; if ((base == u_region_start) && (end == u_region_end)) { @@ -397,8 +387,8 @@ static int _dynamic_region_allocate_and_init(u32_t base, u32_t size, */ static void _mpu_reset_dynamic_regions(void) { - u32_t i; - u32_t num_regions = get_num_regions(); + uint32_t i; + uint32_t num_regions = get_num_regions(); for (i = static_regions_num; i < num_regions; i++) { _region_init(i, 0, 0, 0); @@ -423,9 +413,9 @@ static void _mpu_reset_dynamic_regions(void) * @param base base address in RAM * @param size size of the region */ -static inline int _mpu_configure(u8_t type, u32_t base, u32_t size) +static inline int _mpu_configure(uint8_t type, uint32_t base, uint32_t size) { - u32_t region_attr = get_region_attr_by_type(type); + uint32_t region_attr = get_region_attr_by_type(type); return _dynamic_region_allocate_and_init(base, size, region_attr); } @@ -434,7 +424,7 @@ static inline int _mpu_configure(u8_t type, u32_t base, u32_t size) * This internal function is utilized by the MPU driver to parse the intent * type (i.e. THREAD_STACK_REGION) and return the correct region index. */ -static inline int get_region_index_by_type(u32_t type) +static inline int get_region_index_by_type(uint32_t type) { /* * The new MPU regions are allocated per type after the statically @@ -476,10 +466,10 @@ static inline int get_region_index_by_type(u32_t type) * @param base base address in RAM * @param size size of the region */ -static inline int _mpu_configure(u8_t type, u32_t base, u32_t size) +static inline int _mpu_configure(uint8_t type, uint32_t base, uint32_t size) { int region_index = get_region_index_by_type(type); - u32_t region_attr = get_region_attr_by_type(type); + uint32_t region_attr = get_region_attr_by_type(type); LOG_DBG("Region info: 0x%x 0x%x", base, size); @@ -545,57 +535,45 @@ void arc_core_mpu_configure_thread(struct k_thread *thread) _mpu_reset_dynamic_regions(); #endif #if defined(CONFIG_MPU_STACK_GUARD) + uint32_t guard_start; + + /* Set location of guard area when the thread is running in + * supervisor mode. For a supervisor thread, this is just low + * memory in the stack buffer. For a user thread, it only runs + * in supervisor mode when handling a system call on the privilege + * elevation stack. + */ #if defined(CONFIG_USERSPACE) if ((thread->base.user_options & K_USER) != 0U) { - /* the areas before and after the user stack of thread is - * kernel only. These area can be used as stack guard. - * ----------------------- - * | kernel only area | - * |---------------------| - * | user stack | - * |---------------------| - * |privilege stack guard| - * |---------------------| - * | privilege stack | - * ----------------------- - */ - if (_mpu_configure(THREAD_STACK_GUARD_REGION, - thread->arch.priv_stack_start - STACK_GUARD_SIZE, - STACK_GUARD_SIZE) < 0) { - LOG_ERR("thread %p's stack guard failed", thread); - return; - } - } else { - if (_mpu_configure(THREAD_STACK_GUARD_REGION, - thread->stack_info.start - STACK_GUARD_SIZE, - STACK_GUARD_SIZE) < 0) { - LOG_ERR("thread %p's stack guard failed", thread); - return; - } + guard_start = thread->arch.priv_stack_start; + } else +#endif + { + guard_start = thread->stack_info.start; } -#else - if (_mpu_configure(THREAD_STACK_GUARD_REGION, - thread->stack_info.start - STACK_GUARD_SIZE, - STACK_GUARD_SIZE) < 0) { + guard_start -= Z_ARC_STACK_GUARD_SIZE; + + if (_mpu_configure(THREAD_STACK_GUARD_REGION, guard_start, + Z_ARC_STACK_GUARD_SIZE) < 0) { LOG_ERR("thread %p's stack guard failed", thread); return; } -#endif -#endif +#endif /* CONFIG_MPU_STACK_GUARD */ #if defined(CONFIG_USERSPACE) /* configure stack region of user thread */ if (thread->base.user_options & K_USER) { LOG_DBG("configure user thread %p's stack", thread); if (_mpu_configure(THREAD_STACK_USER_REGION, - (u32_t)thread->stack_obj, thread->stack_info.size) < 0) { + (uint32_t)thread->stack_info.start, + thread->stack_info.size) < 0) { LOG_ERR("thread %p's stack failed", thread); return; } } #if defined(CONFIG_MPU_GAP_FILLING) - u32_t num_partitions; + uint32_t num_partitions; struct k_mem_partition *pparts; struct k_mem_domain *mem_domain = thread->mem_domain_info.mem_domain; @@ -610,7 +588,7 @@ void arc_core_mpu_configure_thread(struct k_thread *thread) pparts = NULL; } - for (u32_t i = 0; i < num_partitions; i++) { + for (uint32_t i = 0; i < num_partitions; i++) { if (pparts->size) { if (_dynamic_region_allocate_and_init(pparts->start, pparts->size, pparts->attr) < 0) { @@ -633,7 +611,7 @@ void arc_core_mpu_configure_thread(struct k_thread *thread) * * @param region_attr region attribute of default region */ -void arc_core_mpu_default(u32_t region_attr) +void arc_core_mpu_default(uint32_t region_attr) { #ifdef CONFIG_ARC_NORMAL_FIRMWARE /* \todo through secure service to access mpu */ @@ -650,8 +628,8 @@ void arc_core_mpu_default(u32_t region_attr) * @param size region size * @param region_attr region attribute */ -int arc_core_mpu_region(u32_t index, u32_t base, u32_t size, - u32_t region_attr) +int arc_core_mpu_region(uint32_t index, uint32_t base, uint32_t size, + uint32_t region_attr) { if (index >= get_num_regions()) { return -EINVAL; @@ -678,9 +656,9 @@ void arc_core_mpu_configure_mem_domain(struct k_thread *thread) #else void arc_core_mpu_configure_mem_domain(struct k_thread *thread) { - u32_t region_index; - u32_t num_partitions; - u32_t num_regions; + uint32_t region_index; + uint32_t num_partitions; + uint32_t num_regions; struct k_mem_partition *pparts; struct k_mem_domain *mem_domain = NULL; @@ -728,7 +706,7 @@ void arc_core_mpu_configure_mem_domain(struct k_thread *thread) */ void arc_core_mpu_remove_mem_domain(struct k_mem_domain *mem_domain) { - u32_t num_partitions; + uint32_t num_partitions; struct k_mem_partition *pparts; int index; @@ -742,7 +720,7 @@ void arc_core_mpu_remove_mem_domain(struct k_mem_domain *mem_domain) pparts = NULL; } - for (u32_t i = 0; i < num_partitions; i++) { + for (uint32_t i = 0; i < num_partitions; i++) { if (pparts->size) { index = _get_region_index(pparts->start, pparts->size); @@ -765,7 +743,7 @@ void arc_core_mpu_remove_mem_domain(struct k_mem_domain *mem_domain) * @param partition_id memory partition id */ void arc_core_mpu_remove_mem_partition(struct k_mem_domain *domain, - u32_t partition_id) + uint32_t partition_id) { struct k_mem_partition *partition = &domain->partitions[partition_id]; @@ -811,9 +789,9 @@ int arc_core_mpu_buffer_validate(void *addr, size_t size, int write) * we can stop the iteration immediately once we find the * matched region that grants permission or denies access. */ - r_index = _mpu_probe((u32_t)addr); + r_index = _mpu_probe((uint32_t)addr); /* match and the area is in one region */ - if (r_index >= 0 && r_index == _mpu_probe((u32_t)addr + (size - 1))) { + if (r_index >= 0 && r_index == _mpu_probe((uint32_t)addr + (size - 1))) { if (_is_user_accessible_region(r_index, write)) { r_index = 0; } else { @@ -836,11 +814,11 @@ int arc_core_mpu_buffer_validate(void *addr, size_t size, int write) * This function provides the default configuration mechanism for the Memory * Protection Unit (MPU). */ -static int arc_mpu_init(struct device *arg) +static int arc_mpu_init(const struct device *arg) { ARG_UNUSED(arg); - u32_t num_regions; - u32_t i; + uint32_t num_regions; + uint32_t i; num_regions = get_num_regions(); diff --git a/arch/arc/core/prep_c.c b/arch/arc/core/prep_c.c index 408eb9d53d7766..ebe4a1d323d1e1 100644 --- a/arch/arc/core/prep_c.c +++ b/arch/arc/core/prep_c.c @@ -46,7 +46,7 @@ static void disable_icache(void) return; /* skip if i-cache is not present */ } z_arc_v2_aux_reg_write(_ARC_V2_IC_IVIC, 0); - __asm__ __volatile__ ("nop"); + __builtin_arc_nop(); z_arc_v2_aux_reg_write(_ARC_V2_IC_CTRL, 1); } diff --git a/arch/arc/core/regular_irq.S b/arch/arc/core/regular_irq.S index 709282801c92b8..b3d9601efe8c94 100644 --- a/arch/arc/core/regular_irq.S +++ b/arch/arc/core/regular_irq.S @@ -269,7 +269,7 @@ SECTION_FUNC(TEXT, _rirq_exit) mov r2, r0 /* _rirq_newthread_switch required by exception handling */ -.balign 4 +.align 4 _rirq_newthread_switch: _load_new_thread_callee_regs @@ -281,7 +281,7 @@ _rirq_newthread_switch: /* fall through */ -.balign 4 +.align 4 _rirq_switch_from_coop: /* for a cooperative switch, it's not in irq, so @@ -309,15 +309,29 @@ _rirq_switch_from_coop: */ st_s r13, [sp, ___isf_t_r13_OFFSET] +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + push_s blink + + bl z_thread_mark_switched_in + + pop_s blink +#endif /* stack now has the IRQ stack frame layout, pointing to sp */ /* rtie will pop the rest from the stack */ rtie -.balign 4 +.align 4 _rirq_switch_from_firq: _rirq_switch_from_rirq: _set_misc_regs_irq_switch_from_irq +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + push_s blink + + bl z_thread_mark_switched_in + + pop_s blink +#endif _rirq_no_switch: rtie diff --git a/arch/arc/core/reset.S b/arch/arc/core/reset.S index 96a11d427e5407..05565266e0bb35 100644 --- a/arch/arc/core/reset.S +++ b/arch/arc/core/reset.S @@ -121,9 +121,42 @@ invalidate_dcache: done_cache_invalidate: -#if defined(CONFIG_SYS_POWER_DEEP_SLEEP_STATES) && \ +/* + * Init ARC internal architecture state + * Force to initialize internal architecture state to reset values + * For scenarios where board hardware is not re-initialized between tests, + * some settings need to be restored to its default initial states as a + * substitution of normal hardware reset sequence. + */ +#ifdef CONFIG_INIT_ARCH_HW_AT_BOOT + /* Set MPU (v3) registers to default */ +#if CONFIG_ARC_MPU_VER == 3 + /* Set default reset value to _ARC_V2_MPU_EN register */ +#define ARC_MPU_EN_RESET_VALUE 0x400181C0 + mov_s r1, ARC_MPU_EN_RESET_VALUE + sr r1, [_ARC_V2_MPU_EN] + /* Get MPU region numbers */ + lr r3, [_ARC_V2_MPU_BUILD] + lsr_s r3, r3, 8 + and r3, r3, 0xff + mov_s r1, 0 + mov_s r2, 0 + /* Set all MPU regions by iterating index */ +mpu_regions_reset: + brge r2, r3, done_mpu_regions_reset + sr r2, [_ARC_V2_MPU_INDEX] + sr r1, [_ARC_V2_MPU_RSTART] + sr r1, [_ARC_V2_MPU_REND] + sr r1, [_ARC_V2_MPU_RPER] + add_s r2, r2, 1 + b_s mpu_regions_reset +done_mpu_regions_reset: +#endif +#endif + +#if defined(CONFIG_PM_DEEP_SLEEP_STATES) && \ !defined(CONFIG_BOOTLOADER_CONTEXT_RESTORE) - jl @_sys_resume_from_deep_sleep + jl @pm_system_resume_from_deep_sleep #endif #if defined(CONFIG_SMP) || CONFIG_MP_NUM_CPUS > 1 @@ -177,4 +210,4 @@ _master_core_startup: jl z_arc_firq_stack_set #endif - j @_PrepC + j _PrepC diff --git a/arch/arc/core/secureshield/arc_sjli.c b/arch/arc/core/secureshield/arc_sjli.c index 02d8c5b9f7d281..c82eab2ecffde9 100644 --- a/arch/arc/core/secureshield/arc_sjli.c +++ b/arch/arc/core/secureshield/arc_sjli.c @@ -19,9 +19,9 @@ static void _default_sjli_entry(void); * \todo: how to let user to install customized sjli entry easily, e.g. * through macros or with the help of compiler? */ -const static u32_t _sjli_vector_table[CONFIG_SJLI_TABLE_SIZE] = { - [0] = (u32_t)_arc_do_secure_call, - [1 ... (CONFIG_SJLI_TABLE_SIZE - 1)] = (u32_t)_default_sjli_entry, +const static uint32_t _sjli_vector_table[CONFIG_SJLI_TABLE_SIZE] = { + [0] = (uint32_t)_arc_do_secure_call, + [1 ... (CONFIG_SJLI_TABLE_SIZE - 1)] = (uint32_t)_default_sjli_entry, }; /* @@ -48,7 +48,7 @@ static void sjli_table_init(void) /* * @brief initializaiton of secureshield related functions. */ -static int arc_secureshield_init(struct device *arg) +static int arc_secureshield_init(const struct device *arg) { sjli_table_init(); diff --git a/arch/arc/core/secureshield/secure_sys_services.c b/arch/arc/core/secureshield/secure_sys_services.c index 34ab80068a2121..c284c87a063dd0 100644 --- a/arch/arc/core/secureshield/secure_sys_services.c +++ b/arch/arc/core/secureshield/secure_sys_services.c @@ -22,7 +22,7 @@ * an secure service to access secure aux regs. Check should be done * to decide whether the access is valid. */ -static s32_t arc_s_aux_read(u32_t aux_reg) +static int32_t arc_s_aux_read(uint32_t aux_reg) { return -1; } @@ -37,7 +37,7 @@ static s32_t arc_s_aux_read(u32_t aux_reg) * an secure service to access secure aux regs. Check should be done * to decide whether the access is valid. */ -static s32_t arc_s_aux_write(u32_t aux_reg, u32_t val) +static int32_t arc_s_aux_write(uint32_t aux_reg, uint32_t val) { if (aux_reg == _ARC_V2_AUX_IRQ_ACT) { /* 0 -> CONFIG_NUM_IRQ_PRIO_LEVELS allocated to secure world @@ -64,7 +64,7 @@ static s32_t arc_s_aux_write(u32_t aux_reg, u32_t val) * apply one. Necessary check should be done to decide whether the apply is * valid */ -static s32_t arc_s_irq_alloc(u32_t intno) +static int32_t arc_s_irq_alloc(uint32_t intno) { z_arc_v2_irq_uinit_secure_set(intno, 0); return 0; diff --git a/arch/arc/core/switch.S b/arch/arc/core/switch.S index 07fede25159386..8e6ecf030305fc 100644 --- a/arch/arc/core/switch.S +++ b/arch/arc/core/switch.S @@ -22,7 +22,7 @@ #include #include -GTEXT(arch_switch) +GTEXT(z_arc_switch) /** * @@ -52,19 +52,8 @@ GTEXT(arch_switch) * */ -SECTION_FUNC(TEXT, arch_switch) +SECTION_FUNC(TEXT, z_arc_switch) -#ifdef CONFIG_EXECUTION_BENCHMARKING - push_s r0 - push_s r1 - push_s blink - - bl read_timer_start_of_swap - - pop_s blink - pop_s r1 - pop_s r0 -#endif /* * r0 = new_thread->switch_handle = switch_to thread, * r1 = &old_thread->switch_handle @@ -112,7 +101,7 @@ SECTION_FUNC(TEXT, arch_switch) /* fall through to _switch_return_from_coop */ -.balign 4 +.align 4 _switch_return_from_coop: pop_s blink /* pc into blink */ @@ -125,17 +114,17 @@ _switch_return_from_coop: pop_s r3 /* status32 into r3 */ kflag r3 /* write status32 */ -#ifdef CONFIG_EXECUTION_BENCHMARKING +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING push_s blink - bl read_timer_end_of_swap + bl z_thread_mark_switched_in pop_s blink -#endif /* CONFIG_EXECUTION_BENCHMARKING */ +#endif j_s [blink] -.balign 4 +.align 4 _switch_return_from_rirq: _switch_return_from_firq: @@ -160,5 +149,12 @@ _switch_return_from_firq: sjli SJLI_CALL_ARC_SECURE #else sr r3, [_ARC_V2_AUX_IRQ_ACT] +#endif +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + push_s blink + + bl z_thread_mark_switched_in + + pop_s blink #endif rtie diff --git a/arch/arc/core/thread.c b/arch/arc/core/thread.c index ab044ea10478b3..5598607b9625b3 100644 --- a/arch/arc/core/thread.c +++ b/arch/arc/core/thread.c @@ -22,196 +22,169 @@ /* initial stack frame */ struct init_stack_frame { - u32_t pc; + uint32_t pc; #ifdef CONFIG_ARC_HAS_SECURE - u32_t sec_stat; + uint32_t sec_stat; #endif - u32_t status32; - u32_t r3; - u32_t r2; - u32_t r1; - u32_t r0; + uint32_t status32; + uint32_t r3; + uint32_t r2; + uint32_t r1; + uint32_t r0; }; -/* - * @brief Initialize a new thread from its stack space - * - * The thread control structure is put at the lower address of the stack. An - * initial context, to be "restored" by __return_from_coop(), is put at - * the other end of the stack, and thus reusable by the stack when not - * needed anymore. - * - * The initial context is a basic stack frame that contains arguments for - * z_thread_entry() return address, that points at z_thread_entry() - * and status register. - * - * is currently unused. - * - * @param pStackmem the pointer to aligned stack memory - * @param stackSize the stack size in bytes - * @param pEntry thread entry point routine - * @param parameter1 first param to entry point - * @param parameter2 second param to entry point - * @param parameter3 third param to entry point - * @param priority thread priority - * @param options thread options: K_ESSENTIAL - * - * @return N/A - */ -void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - size_t stackSize, k_thread_entry_t pEntry, - void *parameter1, void *parameter2, void *parameter3, - int priority, unsigned int options) -{ - char *pStackMem = Z_THREAD_STACK_BUFFER(stack); - - char *stackEnd; - char *priv_stack_end; - struct init_stack_frame *pInitCtx; - #ifdef CONFIG_USERSPACE +struct user_init_stack_frame { + struct init_stack_frame iframe; + uint32_t user_sp; +}; - size_t stackAdjSize; - size_t offset = 0; - - - stackAdjSize = Z_ARC_MPU_SIZE_ALIGN(stackSize); - - stackEnd = pStackMem + stackAdjSize; - -#ifdef CONFIG_STACK_POINTER_RANDOM - offset = stackAdjSize - stackSize; +static bool is_user(struct k_thread *thread) +{ + return (thread->base.user_options & K_USER) != 0; +} #endif - if (options & K_USER) { +/* Set all stack-related architecture variables for the provided thread */ +static void setup_stack_vars(struct k_thread *thread) +{ +#ifdef CONFIG_USERSPACE + if (is_user(thread)) { #ifdef CONFIG_GEN_PRIV_STACKS thread->arch.priv_stack_start = - (u32_t)z_priv_stack_find(thread->stack_obj); + (uint32_t)z_priv_stack_find(thread->stack_obj); #else - thread->arch.priv_stack_start = - (u32_t)(stackEnd + STACK_GUARD_SIZE); -#endif + thread->arch.priv_stack_start = (uint32_t)(thread->stack_obj); +#endif /* CONFIG_GEN_PRIV_STACKS */ + thread->arch.priv_stack_start += Z_ARC_STACK_GUARD_SIZE; + } else { + thread->arch.priv_stack_start = 0; + } +#endif /* CONFIG_USERSPACE */ - priv_stack_end = (char *)Z_STACK_PTR_ALIGN( - thread->arch.priv_stack_start + - CONFIG_PRIVILEGED_STACK_SIZE); - - /* reserve 4 bytes for the start of user sp */ - priv_stack_end -= 4; - (*(u32_t *)priv_stack_end) = Z_STACK_PTR_ALIGN( - (u32_t)stackEnd - offset); - -#ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA - /* reserve stack space for the userspace local data struct */ - thread->userspace_local_data = - (struct _thread_userspace_local_data *) - Z_STACK_PTR_ALIGN(stackEnd - - sizeof(*thread->userspace_local_data) - offset); - /* update the start of user sp */ - (*(u32_t *)priv_stack_end) = - (u32_t) thread->userspace_local_data; +#ifdef CONFIG_ARC_STACK_CHECKING +#ifdef CONFIG_USERSPACE + if (is_user(thread)) { + thread->arch.k_stack_top = thread->arch.priv_stack_start; + thread->arch.k_stack_base = (thread->arch.priv_stack_start + + CONFIG_PRIVILEGED_STACK_SIZE); + thread->arch.u_stack_top = thread->stack_info.start; + thread->arch.u_stack_base = (thread->stack_info.start + + thread->stack_info.size); + } else +#endif /* CONFIG_USERSPACE */ + { + thread->arch.k_stack_top = (uint32_t)thread->stack_info.start; + thread->arch.k_stack_base = (uint32_t)(thread->stack_info.start + + thread->stack_info.size); +#ifdef CONFIG_USERSPACE + thread->arch.u_stack_top = 0; + thread->arch.u_stack_base = 0; +#endif /* CONFIG_USERSPACE */ + } +#endif /* CONFIG_ARC_STACK_CHECKING */ +} + +/* Get the initial stack frame pointer from the thread's stack buffer. */ +static struct init_stack_frame *get_iframe(struct k_thread *thread, + char *stack_ptr) +{ +#ifdef CONFIG_USERSPACE + if (is_user(thread)) { + /* Initial stack frame for a user thread is slightly larger; + * we land in z_user_thread_entry_wrapper on the privilege + * stack, and pop off an additional value for the user + * stack pointer. + */ + struct user_init_stack_frame *uframe; + + uframe = Z_STACK_PTR_TO_FRAME(struct user_init_stack_frame, + thread->arch.priv_stack_start + + CONFIG_PRIVILEGED_STACK_SIZE); + uframe->user_sp = (uint32_t)stack_ptr; + return &uframe->iframe; + } #endif + return Z_STACK_PTR_TO_FRAME(struct init_stack_frame, stack_ptr); +} - } else { - pStackMem += STACK_GUARD_SIZE; - stackEnd += STACK_GUARD_SIZE; +/* + * Pre-populate values in the registers inside _callee_saved_stack struct + * so these registers have pre-defined values when new thread begins + * execution. For example, setting up the thread pointer for thread local + * storage here so the thread starts with thread pointer already set up. + */ +static inline void arch_setup_callee_saved_regs(struct k_thread *thread, + uintptr_t stack_ptr) +{ + _callee_saved_stack_t *regs = UINT_TO_POINTER(stack_ptr); - thread->arch.priv_stack_start = 0; + ARG_UNUSED(regs); -#ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA - /* reserve stack space for the userspace local data struct */ - priv_stack_end = (char *)Z_STACK_PTR_ALIGN(stackEnd - - sizeof(*thread->userspace_local_data) - offset); - thread->userspace_local_data = - (struct _thread_userspace_local_data *)priv_stack_end; -#else - priv_stack_end = (char *)Z_STACK_PTR_ALIGN(stackEnd - offset); +#ifdef CONFIG_THREAD_LOCAL_STORAGE + /* R26 is used for thread pointer */ + regs->r26 = thread->tls; #endif - } +} - z_new_thread_init(thread, pStackMem, stackAdjSize); +/* + * The initial context is a basic stack frame that contains arguments for + * z_thread_entry() return address, that points at z_thread_entry() + * and status register. + */ +void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) +{ + struct init_stack_frame *iframe; - /* carve the thread entry struct from the "base" of - the privileged stack */ - pInitCtx = (struct init_stack_frame *)( - priv_stack_end - sizeof(struct init_stack_frame)); + setup_stack_vars(thread); - /* fill init context */ - pInitCtx->status32 = 0U; - if (options & K_USER) { - pInitCtx->pc = ((u32_t)z_user_thread_entry_wrapper); - } else { - pInitCtx->pc = ((u32_t)z_thread_entry_wrapper); - } + /* Set up initial stack frame */ + iframe = get_iframe(thread, stack_ptr); - /* - * enable US bit, US is read as zero in user mode. This will allow use +#ifdef CONFIG_USERSPACE + /* enable US bit, US is read as zero in user mode. This will allow user * mode sleep instructions, and it enables a form of denial-of-service * attack by putting the processor in sleep mode, but since interrupt * level/mask can't be set from user space that's not worse than * executing a loop without yielding. */ - pInitCtx->status32 |= _ARC_V2_STATUS32_US; -#else /* For no USERSPACE feature */ - pStackMem += STACK_GUARD_SIZE; - stackEnd = pStackMem + stackSize; - - z_new_thread_init(thread, pStackMem, stackSize); - - priv_stack_end = stackEnd; - - pInitCtx = (struct init_stack_frame *)( - Z_STACK_PTR_ALIGN(priv_stack_end) - - sizeof(struct init_stack_frame)); - - pInitCtx->status32 = 0U; - pInitCtx->pc = ((u32_t)z_thread_entry_wrapper); -#endif - + iframe->status32 = _ARC_V2_STATUS32_US; + if (is_user(thread)) { + iframe->pc = (uint32_t)z_user_thread_entry_wrapper; + } else { + iframe->pc = (uint32_t)z_thread_entry_wrapper; + } +#else + iframe->status32 = 0; + iframe->pc = ((uint32_t)z_thread_entry_wrapper); +#endif /* CONFIG_USERSPACE */ #ifdef CONFIG_ARC_SECURE_FIRMWARE - pInitCtx->sec_stat = z_arc_v2_aux_reg_read(_ARC_V2_SEC_STAT); + iframe->sec_stat = z_arc_v2_aux_reg_read(_ARC_V2_SEC_STAT); #endif + iframe->r0 = (uint32_t)entry; + iframe->r1 = (uint32_t)p1; + iframe->r2 = (uint32_t)p2; + iframe->r3 = (uint32_t)p3; - pInitCtx->r0 = (u32_t)pEntry; - pInitCtx->r1 = (u32_t)parameter1; - pInitCtx->r2 = (u32_t)parameter2; - pInitCtx->r3 = (u32_t)parameter3; - -/* stack check configuration */ #ifdef CONFIG_ARC_STACK_CHECKING #ifdef CONFIG_ARC_SECURE_FIRMWARE - pInitCtx->sec_stat |= _ARC_V2_SEC_STAT_SSC; + iframe->sec_stat |= _ARC_V2_SEC_STAT_SSC; #else - pInitCtx->status32 |= _ARC_V2_STATUS32_SC; -#endif -#ifdef CONFIG_USERSPACE - if (options & K_USER) { - thread->arch.u_stack_top = (u32_t)pStackMem; - thread->arch.u_stack_base = (u32_t)stackEnd; - thread->arch.k_stack_top = - (u32_t)(thread->arch.priv_stack_start); - thread->arch.k_stack_base = (u32_t) - (thread->arch.priv_stack_start + CONFIG_PRIVILEGED_STACK_SIZE); - } else { - thread->arch.k_stack_top = (u32_t)pStackMem; - thread->arch.k_stack_base = (u32_t)stackEnd; - thread->arch.u_stack_top = 0; - thread->arch.u_stack_base = 0; - } -#else - thread->arch.k_stack_top = (u32_t) pStackMem; - thread->arch.k_stack_base = (u32_t) stackEnd; -#endif -#endif - + iframe->status32 |= _ARC_V2_STATUS32_SC; +#endif /* CONFIG_ARC_SECURE_FIRMWARE */ +#endif /* CONFIG_ARC_STACK_CHECKING */ #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS - pInitCtx->status32 |= _ARC_V2_STATUS32_AD; + iframe->status32 |= _ARC_V2_STATUS32_AD; #endif - + /* Set required thread members */ thread->switch_handle = thread; thread->arch.relinquish_cause = _CAUSE_COOP; thread->callee_saved.sp = - (u32_t)pInitCtx - ___callee_saved_stack_t_SIZEOF; + (uint32_t)iframe - ___callee_saved_stack_t_SIZEOF; + + arch_setup_callee_saved_regs(thread, thread->callee_saved.sp); /* initial values in all other regs/k_thread entries are irrelevant */ } @@ -224,42 +197,21 @@ void *z_arch_get_next_switch_handle(struct k_thread **old_thread) } #ifdef CONFIG_USERSPACE - FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, void *p1, void *p2, void *p3) { - - - _current->stack_info.start = (u32_t)_current->stack_obj; -#ifdef CONFIG_GEN_PRIV_STACKS - _current->arch.priv_stack_start = - (u32_t)z_priv_stack_find(_current->stack_obj); -#else - _current->arch.priv_stack_start = - (u32_t)(_current->stack_info.start + - _current->stack_info.size + STACK_GUARD_SIZE); -#endif - - -#ifdef CONFIG_ARC_STACK_CHECKING - _current->arch.k_stack_top = _current->arch.priv_stack_start; - _current->arch.k_stack_base = _current->arch.priv_stack_start + - CONFIG_PRIVILEGED_STACK_SIZE; - _current->arch.u_stack_top = _current->stack_info.start; - _current->arch.u_stack_base = _current->stack_info.start + - _current->stack_info.size; -#endif + setup_stack_vars(_current); /* possible optimizaiton: no need to load mem domain anymore */ /* need to lock cpu here ? */ configure_mpu_thread(_current); z_arc_userspace_enter(user_entry, p1, p2, p3, - (u32_t)_current->stack_obj, - _current->stack_info.size, _current); + (uint32_t)_current->stack_info.start, + (_current->stack_info.size - + _current->stack_info.delta), _current); CODE_UNREACHABLE; } - #endif #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) diff --git a/arch/arc/core/timestamp.c b/arch/arc/core/timestamp.c index 87dbfd2fcf0f73..a2ba64b54c4da8 100644 --- a/arch/arc/core/timestamp.c +++ b/arch/arc/core/timestamp.c @@ -23,17 +23,17 @@ * * @return 64-bit time stamp value */ -u64_t z_tsc_read(void) +uint64_t z_tsc_read(void) { unsigned int key; - u64_t t; - u32_t count; + uint64_t t; + uint32_t count; key = arch_irq_lock(); - t = (u64_t)z_tick_get(); + t = (uint64_t)z_tick_get(); count = z_arc_v2_aux_reg_read(_ARC_V2_TMR0_COUNT); arch_irq_unlock(key); t *= k_ticks_to_cyc_floor64(1); - t += (u64_t)count; + t += (uint64_t)count; return t; } diff --git a/arch/arc/core/tls.c b/arch/arc/core/tls.c new file mode 100644 index 00000000000000..4f2a9ed97a6770 --- /dev/null +++ b/arch/arc/core/tls.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) +{ + /* + * TLS area for ARC has some data fields following by + * thread data and bss. These fields are supposed to be + * used by toolchain and OS TLS code to aid in locating + * the TLS data/bss. Zephyr currently has no use for + * this so we can simply skip these. However, since GCC + * is generating code assuming these fields are there, + * we simply skip them when setting the TLS pointer. + */ + + /* + * Since we are populating things backwards, + * setup the TLS data/bss area first. + */ + stack_ptr -= z_tls_data_size(); + z_tls_copy(stack_ptr); + + /* Skip two pointers due to toolchain */ + stack_ptr -= sizeof(uintptr_t) * 2; + + /* + * Set thread TLS pointer which is used in + * context switch to point to TLS area. + */ + new_thread->tls = POINTER_TO_UINT(stack_ptr); + + return (z_tls_data_size() + (sizeof(uintptr_t) * 2)); +} diff --git a/arch/arc/core/userspace.S b/arch/arc/core/userspace.S index 0721f270f89069..f3e0465b24f1df 100644 --- a/arch/arc/core/userspace.S +++ b/arch/arc/core/userspace.S @@ -174,14 +174,10 @@ _arc_go_to_user_space: clear_scratch_regs - mov_s fp, 0 - mov_s r29, 0 - mov_s r30, 0 - mov_s blink, 0 - -#ifdef CONFIG_EXECUTION_BENCHMARKING - bl read_timer_end_of_userspace_enter -#endif + mov fp, 0 + mov r29, 0 + mov r30, 0 + mov blink, 0 rtie @@ -218,8 +214,8 @@ SECTION_FUNC(TEXT, _arc_do_syscall) /* save return value */ st_s r0, [sp, ___isf_t_r0_OFFSET] - mov_s r29, 0 - mov_s r30, 0 + mov r29, 0 + mov r30, 0 /* through fake exception return, go back to the caller */ lr r0, [_ARC_V2_STATUS32] diff --git a/arch/arc/core/vector_table.c b/arch/arc/core/vector_table.c index 3f68f0a541f67c..9f85f3c837834b 100644 --- a/arch/arc/core/vector_table.c +++ b/arch/arc/core/vector_table.c @@ -28,39 +28,39 @@ #include "vector_table.h" struct vector_table { - u32_t reset; - u32_t memory_error; - u32_t instruction_error; - u32_t ev_machine_check; - u32_t ev_tlb_miss_i; - u32_t ev_tlb_miss_d; - u32_t ev_prot_v; - u32_t ev_privilege_v; - u32_t ev_swi; - u32_t ev_trap; - u32_t ev_extension; - u32_t ev_div_zero; - u32_t ev_dc_error; - u32_t ev_maligned; - u32_t unused_1; - u32_t unused_2; + uint32_t reset; + uint32_t memory_error; + uint32_t instruction_error; + uint32_t ev_machine_check; + uint32_t ev_tlb_miss_i; + uint32_t ev_tlb_miss_d; + uint32_t ev_prot_v; + uint32_t ev_privilege_v; + uint32_t ev_swi; + uint32_t ev_trap; + uint32_t ev_extension; + uint32_t ev_div_zero; + uint32_t ev_dc_error; + uint32_t ev_maligned; + uint32_t unused_1; + uint32_t unused_2; }; struct vector_table _VectorTable Z_GENERIC_SECTION(.exc_vector_table) = { - (u32_t)__reset, - (u32_t)__memory_error, - (u32_t)__instruction_error, - (u32_t)__ev_machine_check, - (u32_t)__ev_tlb_miss_i, - (u32_t)__ev_tlb_miss_d, - (u32_t)__ev_prot_v, - (u32_t)__ev_privilege_v, - (u32_t)__ev_swi, - (u32_t)__ev_trap, - (u32_t)__ev_extension, - (u32_t)__ev_div_zero, - (u32_t)__ev_dc_error, - (u32_t)__ev_maligned, + (uint32_t)__reset, + (uint32_t)__memory_error, + (uint32_t)__instruction_error, + (uint32_t)__ev_machine_check, + (uint32_t)__ev_tlb_miss_i, + (uint32_t)__ev_tlb_miss_d, + (uint32_t)__ev_prot_v, + (uint32_t)__ev_privilege_v, + (uint32_t)__ev_swi, + (uint32_t)__ev_trap, + (uint32_t)__ev_extension, + (uint32_t)__ev_div_zero, + (uint32_t)__ev_dc_error, + (uint32_t)__ev_maligned, 0, 0 }; diff --git a/arch/arc/include/kernel_arch_data.h b/arch/arc/include/kernel_arch_data.h index cbf747e92ad73e..49b1cd7708de77 100644 --- a/arch/arc/include/kernel_arch_data.h +++ b/arch/arc/include/kernel_arch_data.h @@ -37,70 +37,70 @@ extern "C" { #ifdef CONFIG_ARC_HAS_SECURE struct _irq_stack_frame { - u32_t lp_end; - u32_t lp_start; - u32_t lp_count; + uint32_t lp_end; + uint32_t lp_start; + uint32_t lp_count; #ifdef CONFIG_CODE_DENSITY /* * Currently unsupported. This is where those registers are * automatically pushed on the stack by the CPU when taking a regular * IRQ. */ - u32_t ei_base; - u32_t ldi_base; - u32_t jli_base; + uint32_t ei_base; + uint32_t ldi_base; + uint32_t jli_base; #endif - u32_t r0; - u32_t r1; - u32_t r2; - u32_t r3; - u32_t r4; - u32_t r5; - u32_t r6; - u32_t r7; - u32_t r8; - u32_t r9; - u32_t r10; - u32_t r11; - u32_t r12; - u32_t r13; - u32_t blink; - u32_t pc; - u32_t sec_stat; - u32_t status32; + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t r13; + uint32_t blink; + uint32_t pc; + uint32_t sec_stat; + uint32_t status32; }; #else struct _irq_stack_frame { - u32_t r0; - u32_t r1; - u32_t r2; - u32_t r3; - u32_t r4; - u32_t r5; - u32_t r6; - u32_t r7; - u32_t r8; - u32_t r9; - u32_t r10; - u32_t r11; - u32_t r12; - u32_t r13; - u32_t blink; - u32_t lp_end; - u32_t lp_start; - u32_t lp_count; + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t r13; + uint32_t blink; + uint32_t lp_end; + uint32_t lp_start; + uint32_t lp_count; #ifdef CONFIG_CODE_DENSITY /* * Currently unsupported. This is where those registers are * automatically pushed on the stack by the CPU when taking a regular * IRQ. */ - u32_t ei_base; - u32_t ldi_base; - u32_t jli_base; + uint32_t ei_base; + uint32_t ldi_base; + uint32_t jli_base; #endif - u32_t pc; - u32_t status32; + uint32_t pc; + uint32_t status32; }; #endif @@ -110,47 +110,47 @@ typedef struct _irq_stack_frame _isf_t; /* callee-saved registers pushed on the stack, not in k_thread */ struct _callee_saved_stack { - u32_t r13; - u32_t r14; - u32_t r15; - u32_t r16; - u32_t r17; - u32_t r18; - u32_t r19; - u32_t r20; - u32_t r21; - u32_t r22; - u32_t r23; - u32_t r24; - u32_t r25; - u32_t r26; - u32_t fp; /* r27 */ + uint32_t r13; + uint32_t r14; + uint32_t r15; + uint32_t r16; + uint32_t r17; + uint32_t r18; + uint32_t r19; + uint32_t r20; + uint32_t r21; + uint32_t r22; + uint32_t r23; + uint32_t r24; + uint32_t r25; + uint32_t r26; + uint32_t fp; /* r27 */ #ifdef CONFIG_USERSPACE #ifdef CONFIG_ARC_HAS_SECURE - u32_t user_sp; - u32_t kernel_sp; + uint32_t user_sp; + uint32_t kernel_sp; #else - u32_t user_sp; + uint32_t user_sp; #endif #endif /* r28 is the stack pointer and saved separately */ /* r29 is ILINK and does not need to be saved */ - u32_t r30; + uint32_t r30; #ifdef CONFIG_ARC_HAS_ACCL_REGS - u32_t r58; - u32_t r59; + uint32_t r58; + uint32_t r59; #endif #ifdef CONFIG_FPU_SHARING - u32_t fpu_status; - u32_t fpu_ctrl; + uint32_t fpu_status; + uint32_t fpu_ctrl; #ifdef CONFIG_FP_FPU_DA - u32_t dpfp2h; - u32_t dpfp2l; - u32_t dpfp1h; - u32_t dpfp1l; + uint32_t dpfp2h; + uint32_t dpfp2l; + uint32_t dpfp1h; + uint32_t dpfp1l; #endif #endif diff --git a/arch/arc/include/kernel_arch_func.h b/arch/arc/include/kernel_arch_func.h index a5ad448ba3d3a6..2b2e6006190b78 100644 --- a/arch/arc/include/kernel_arch_func.h +++ b/arch/arc/include/kernel_arch_func.h @@ -48,7 +48,7 @@ static ALWAYS_INLINE void arch_kernel_init(void) */ static ALWAYS_INLINE int Z_INTERRUPT_CAUSE(void) { - u32_t irq_num = z_arc_v2_aux_reg_read(_ARC_V2_ICAUSE); + uint32_t irq_num = z_arc_v2_aux_reg_read(_ARC_V2_ICAUSE); return irq_num; } @@ -62,15 +62,20 @@ extern void z_thread_entry_wrapper(void); extern void z_user_thread_entry_wrapper(void); extern void z_arc_userspace_enter(k_thread_entry_t user_entry, void *p1, - void *p2, void *p3, u32_t stack, u32_t size, + void *p2, void *p3, uint32_t stack, uint32_t size, struct k_thread *thread); - -extern void arch_switch(void *switch_to, void **switched_from); extern void z_arc_fatal_error(unsigned int reason, const z_arch_esf_t *esf); extern void arch_sched_ipi(void); +extern void z_arc_switch(void *switch_to, void **switched_from); + +static inline void arch_switch(void *switch_to, void **switched_from) +{ + z_arc_switch(switch_to, switched_from); +} + #ifdef __cplusplus } #endif diff --git a/arch/arc/include/swap_macros.h b/arch/arc/include/swap_macros.h index e846ec08ff7595..dbffcce3a36025 100644 --- a/arch/arc/include/swap_macros.h +++ b/arch/arc/include/swap_macros.h @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef _ASMLANGUAGE @@ -300,42 +301,42 @@ * the result will be EQ bit of status32 * two temp regs are needed */ -.macro _check_and_inc_int_nest_counter reg1 reg2 +.macro _check_and_inc_int_nest_counter, reg1, reg2 #ifdef CONFIG_SMP - _get_cpu_id \reg1 - ld.as \reg1, [@_curr_cpu, \reg1] - ld \reg2, [\reg1, ___cpu_t_nested_OFFSET] + _get_cpu_id MACRO_ARG(reg1) + ld.as MACRO_ARG(reg1), [_curr_cpu, MACRO_ARG(reg1)] + ld MACRO_ARG(reg2), [MACRO_ARG(reg1), ___cpu_t_nested_OFFSET] #else - mov \reg1, _kernel - ld \reg2, [\reg1, _kernel_offset_to_nested] + mov MACRO_ARG(reg1), _kernel + ld MACRO_ARG(reg2), [MACRO_ARG(reg1), _kernel_offset_to_nested] #endif - add \reg2, \reg2, 1 + add MACRO_ARG(reg2), MACRO_ARG(reg2), 1 #ifdef CONFIG_SMP - st \reg2, [\reg1, ___cpu_t_nested_OFFSET] + st MACRO_ARG(reg2), [MACRO_ARG(reg1), ___cpu_t_nested_OFFSET] #else - st \reg2, [\reg1, _kernel_offset_to_nested] + st MACRO_ARG(reg2), [MACRO_ARG(reg1), _kernel_offset_to_nested] #endif - cmp \reg2, 1 + cmp MACRO_ARG(reg2), 1 .endm /* decrease interrupt stack nest counter * the counter > 0, interrupt stack is used, or * not used */ -.macro _dec_int_nest_counter reg1 reg2 +.macro _dec_int_nest_counter, reg1, reg2 #ifdef CONFIG_SMP - _get_cpu_id \reg1 - ld.as \reg1, [@_curr_cpu, \reg1] - ld \reg2, [\reg1, ___cpu_t_nested_OFFSET] + _get_cpu_id MACRO_ARG(reg1) + ld.as MACRO_ARG(reg1), [_curr_cpu, MACRO_ARG(reg1)] + ld MACRO_ARG(reg2), [MACRO_ARG(reg1), ___cpu_t_nested_OFFSET] #else - mov \reg1, _kernel - ld \reg2, [\reg1, _kernel_offset_to_nested] + mov MACRO_ARG(reg1), _kernel + ld MACRO_ARG(reg2), [MACRO_ARG(reg1), _kernel_offset_to_nested] #endif - sub \reg2, \reg2, 1 + sub MACRO_ARG(reg2), MACRO_ARG(reg2), 1 #ifdef CONFIG_SMP - st \reg2, [\reg1, ___cpu_t_nested_OFFSET] + st MACRO_ARG(reg2), [MACRO_ARG(reg1), ___cpu_t_nested_OFFSET] #else - st \reg2, [\reg1, _kernel_offset_to_nested] + st MACRO_ARG(reg2), [MACRO_ARG(reg1), _kernel_offset_to_nested] #endif .endm @@ -343,51 +344,51 @@ * in nest interrupt. The result will be EQ bit of status32 * need two temp reg to do this */ -.macro _check_nest_int_by_irq_act reg1, reg2 - lr \reg1, [_ARC_V2_AUX_IRQ_ACT] +.macro _check_nest_int_by_irq_act, reg1, reg2 + lr MACRO_ARG(reg1), [_ARC_V2_AUX_IRQ_ACT] #ifdef CONFIG_ARC_SECURE_FIRMWARE - and \reg1, \reg1, ((1 << ARC_N_IRQ_START_LEVEL) - 1) + and MACRO_ARG(reg1), MACRO_ARG(reg1), ((1 << ARC_N_IRQ_START_LEVEL) - 1) #else - and \reg1, \reg1, 0xffff + and MACRO_ARG(reg1), MACRO_ARG(reg1), 0xffff #endif - ffs \reg2, \reg1 - fls \reg1, \reg1 - cmp \reg1, \reg2 + ffs MACRO_ARG(reg2), MACRO_ARG(reg1) + fls MACRO_ARG(reg1), MACRO_ARG(reg1) + cmp MACRO_ARG(reg1), MACRO_ARG(reg2) .endm /* macro to get id of current cpu * the result will be in reg (a reg) */ -.macro _get_cpu_id reg - lr \reg, [_ARC_V2_IDENTITY] - xbfu \reg, \reg, 0xe8 +.macro _get_cpu_id, reg + lr MACRO_ARG(reg), [_ARC_V2_IDENTITY] + xbfu MACRO_ARG(reg), MACRO_ARG(reg), 0xe8 .endm /* macro to get the interrupt stack of current cpu * the result will be in irq_sp (a reg) */ -.macro _get_curr_cpu_irq_stack irq_sp +.macro _get_curr_cpu_irq_stack, irq_sp #ifdef CONFIG_SMP - _get_cpu_id \irq_sp - ld.as \irq_sp, [@_curr_cpu, \irq_sp] - ld \irq_sp, [\irq_sp, ___cpu_t_irq_stack_OFFSET] + _get_cpu_id MACRO_ARG(irq_sp) + ld.as MACRO_ARG(irq_sp), [_curr_cpu, MACRO_ARG(irq_sp)] + ld MACRO_ARG(irq_sp), [MACRO_ARG(irq_sp), ___cpu_t_irq_stack_OFFSET] #else - mov \irq_sp, _kernel - ld \irq_sp, [\irq_sp, _kernel_offset_to_irq_stack] + mov MACRO_ARG(irq_sp), _kernel + ld MACRO_ARG(irq_sp), [MACRO_ARG(irq_sp), _kernel_offset_to_irq_stack] #endif .endm /* macro to push aux reg through reg */ -.macro PUSHAX reg aux - lr \reg, [\aux] - st.a \reg, [sp, -4] +.macro PUSHAX, reg, aux + lr MACRO_ARG(reg), [MACRO_ARG(aux)] + st.a MACRO_ARG(reg), [sp, -4] .endm /* macro to pop aux reg through reg */ -.macro POPAX reg aux - ld.ab \reg, [sp, 4] - sr \reg, [\aux] +.macro POPAX, reg, aux + ld.ab MACRO_ARG(reg), [sp, 4] + sr MACRO_ARG(reg), [MACRO_ARG(aux)] .endm @@ -487,17 +488,17 @@ /* macro to disable stack checking in assembly, need a GPR * to do this */ -.macro _disable_stack_checking reg +.macro _disable_stack_checking, reg #ifdef CONFIG_ARC_STACK_CHECKING #ifdef CONFIG_ARC_SECURE_FIRMWARE - lr \reg, [_ARC_V2_SEC_STAT] - bclr \reg, \reg, _ARC_V2_SEC_STAT_SSC_BIT - sflag \reg + lr MACRO_ARG(reg), [_ARC_V2_SEC_STAT] + bclr MACRO_ARG(reg), MACRO_ARG(reg), _ARC_V2_SEC_STAT_SSC_BIT + sflag MACRO_ARG(reg) #else - lr \reg, [_ARC_V2_STATUS32] - bclr \reg, \reg, _ARC_V2_STATUS32_SC_BIT - kflag \reg + lr MACRO_ARG(reg), [_ARC_V2_STATUS32] + bclr MACRO_ARG(reg), MACRO_ARG(reg), _ARC_V2_STATUS32_SC_BIT + kflag MACRO_ARG(reg) #endif #endif .endm @@ -505,16 +506,16 @@ /* macro to enable stack checking in assembly, need a GPR * to do this */ -.macro _enable_stack_checking reg +.macro _enable_stack_checking, reg #ifdef CONFIG_ARC_STACK_CHECKING #ifdef CONFIG_ARC_SECURE_FIRMWARE - lr \reg, [_ARC_V2_SEC_STAT] - bset \reg, \reg, _ARC_V2_SEC_STAT_SSC_BIT - sflag \reg + lr MACRO_ARG(reg), [_ARC_V2_SEC_STAT] + bset MACRO_ARG(reg), MACRO_ARG(reg), _ARC_V2_SEC_STAT_SSC_BIT + sflag MACRO_ARG(reg) #else - lr \reg, [_ARC_V2_STATUS32] - bset \reg, \reg, _ARC_V2_STATUS32_SC_BIT - kflag \reg + lr MACRO_ARG(reg), [_ARC_V2_STATUS32] + bset MACRO_ARG(reg), MACRO_ARG(reg), _ARC_V2_STATUS32_SC_BIT + kflag MACRO_ARG(reg) #endif #endif .endm diff --git a/arch/arc/include/v2/cache.h b/arch/arc/include/v2/cache.h index 747a08932fe851..43414225297112 100644 --- a/arch/arc/include/v2/cache.h +++ b/arch/arc/include/v2/cache.h @@ -36,11 +36,11 @@ extern "C" { */ static ALWAYS_INLINE void z_icache_setup(void) { - u32_t icache_config = ( + uint32_t icache_config = ( IC_CACHE_DIRECT | /* direct mapping (one-way assoc.) */ IC_CACHE_ENABLE /* i-cache enabled */ ); - u32_t val; + uint32_t val; val = z_arc_v2_aux_reg_read(_ARC_V2_I_CACHE_BUILD); val &= 0xff; diff --git a/arch/arc/include/v2/irq.h b/arch/arc/include/v2/irq.h index 870f7d8cf435ee..1f2a1a63deb564 100644 --- a/arch/arc/include/v2/irq.h +++ b/arch/arc/include/v2/irq.h @@ -53,7 +53,7 @@ extern "C" { */ static ALWAYS_INLINE void z_irq_setup(void) { - u32_t aux_irq_ctrl_value = ( + uint32_t aux_irq_ctrl_value = ( _ARC_V2_AUX_IRQ_CTRL_LOOP_REGS | /* save lp_xxx registers */ #ifdef CONFIG_CODE_DENSITY _ARC_V2_AUX_IRQ_CTRL_LP | /* save code density registers */ diff --git a/arch/arm/core/aarch32/CMakeLists.txt b/arch/arm/core/aarch32/CMakeLists.txt index 00b0a477e9e98f..121969faf20e28 100644 --- a/arch/arm/core/aarch32/CMakeLists.txt +++ b/arch/arm/core/aarch32/CMakeLists.txt @@ -3,7 +3,8 @@ zephyr_library() if (CONFIG_COVERAGE) - toolchain_cc_coverage() + zephyr_compile_options($) + zephyr_link_libraries($) endif () zephyr_library_sources( @@ -21,7 +22,8 @@ zephyr_library_sources( zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) zephyr_library_sources_ifdef(CONFIG_CPLUSPLUS __aeabi_atexit.c) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) -zephyr_library_sources_ifdef(CONFIG_CPU_CORTEX_M0 irq_relay.S) +zephyr_library_sources_ifdef(CONFIG_SW_VECTOR_RELAY irq_relay.S) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE ../common/tls.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) add_subdirectory_ifdef(CONFIG_CPU_CORTEX_M cortex_m) diff --git a/arch/arm/core/aarch32/Kconfig b/arch/arm/core/aarch32/Kconfig index b996b7ec5f8ef5..856cf34c39df82 100644 --- a/arch/arm/core/aarch32/Kconfig +++ b/arch/arm/core/aarch32/Kconfig @@ -17,6 +17,10 @@ config CPU_CORTEX_M select ARCH_HAS_RAMFUNC_SUPPORT select ARCH_HAS_NESTED_EXCEPTION_DETECTION select SWAP_NONATOMIC + select ARCH_HAS_EXTRA_EXCEPTION_INFO + select ARCH_HAS_TIMING_FUNCTIONS if CPU_CORTEX_M_HAS_DWT + select ARCH_SUPPORTS_ARCH_HW_INIT + imply XIP help This option signifies the use of a CPU of the Cortex-M family. @@ -25,7 +29,6 @@ config CPU_CORTEX_R select CPU_CORTEX select HAS_CMSIS_CORE select HAS_FLASH_LOAD_OFFSET - select ARCH_HAS_THREAD_ABORT help This option signifies the use of a CPU of the Cortex-R family. diff --git a/arch/arm/core/aarch32/cortex_a_r/CMakeLists.txt b/arch/arm/core/aarch32/cortex_a_r/CMakeLists.txt index 04b729c2abb051..a959649a0080dc 100644 --- a/arch/arm/core/aarch32/cortex_a_r/CMakeLists.txt +++ b/arch/arm/core/aarch32/cortex_a_r/CMakeLists.txt @@ -11,5 +11,4 @@ zephyr_library_sources( irq_init.c reboot.c stacks.c - thread_abort.c ) diff --git a/arch/arm/core/aarch32/cortex_a_r/fault.c b/arch/arm/core/aarch32/cortex_a_r/fault.c index b5dccecc5686a9..007ee29505632a 100644 --- a/arch/arm/core/aarch32/cortex_a_r/fault.c +++ b/arch/arm/core/aarch32/cortex_a_r/fault.c @@ -8,12 +8,12 @@ #include #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #define FAULT_DUMP_VERBOSE (CONFIG_FAULT_DUMP == 2) #if FAULT_DUMP_VERBOSE -static const char *get_dbgdscr_moe_string(u32_t moe) +static const char *get_dbgdscr_moe_string(uint32_t moe) { switch (moe) { case DBGDSCR_MOE_HALT_REQUEST: @@ -40,14 +40,14 @@ static const char *get_dbgdscr_moe_string(u32_t moe) static void dump_debug_event(void) { /* Read and parse debug mode of entry */ - u32_t dbgdscr = __get_DBGDSCR(); - u32_t moe = (dbgdscr & DBGDSCR_MOE_Msk) >> DBGDSCR_MOE_Pos; + uint32_t dbgdscr = __get_DBGDSCR(); + uint32_t moe = (dbgdscr & DBGDSCR_MOE_Msk) >> DBGDSCR_MOE_Pos; /* Print debug event information */ LOG_ERR("Debug Event (%s)", get_dbgdscr_moe_string(moe)); } -static void dump_fault(u32_t status, u32_t addr) +static void dump_fault(uint32_t status, uint32_t addr) { /* * Dump fault status and, if applicable, tatus-specific information. @@ -110,11 +110,11 @@ bool z_arm_fault_undef_instruction(z_arch_esf_t *esf) bool z_arm_fault_prefetch(z_arch_esf_t *esf) { /* Read and parse Instruction Fault Status Register (IFSR) */ - u32_t ifsr = __get_IFSR(); - u32_t fs = ((ifsr & IFSR_FS1_Msk) >> 6) | (ifsr & IFSR_FS0_Msk); + uint32_t ifsr = __get_IFSR(); + uint32_t fs = ((ifsr & IFSR_FS1_Msk) >> 6) | (ifsr & IFSR_FS0_Msk); /* Read Instruction Fault Address Register (IFAR) */ - u32_t ifar = __get_IFAR(); + uint32_t ifar = __get_IFAR(); /* Print fault information*/ LOG_ERR("***** PREFETCH ABORT *****"); @@ -137,11 +137,11 @@ bool z_arm_fault_prefetch(z_arch_esf_t *esf) bool z_arm_fault_data(z_arch_esf_t *esf) { /* Read and parse Data Fault Status Register (DFSR) */ - u32_t dfsr = __get_DFSR(); - u32_t fs = ((dfsr & DFSR_FS1_Msk) >> 6) | (dfsr & DFSR_FS0_Msk); + uint32_t dfsr = __get_DFSR(); + uint32_t fs = ((dfsr & DFSR_FS1_Msk) >> 6) | (dfsr & DFSR_FS0_Msk); /* Read Data Fault Address Register (DFAR) */ - u32_t dfar = __get_DFAR(); + uint32_t dfar = __get_DFAR(); /* Print fault information*/ LOG_ERR("***** DATA ABORT *****"); diff --git a/arch/arm/core/aarch32/cortex_a_r/irq_init.c b/arch/arm/core/aarch32/cortex_a_r/irq_init.c index e6a96bf3957965..16619e7f67c381 100644 --- a/arch/arm/core/aarch32/cortex_a_r/irq_init.c +++ b/arch/arm/core/aarch32/cortex_a_r/irq_init.c @@ -23,10 +23,7 @@ void z_arm_interrupt_init(void) /* * Initialise interrupt controller. */ -#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) - /* Initialise the Generic Interrupt Controller (GIC) driver */ - arm_gic_init(); -#else +#ifdef CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER /* Invoke SoC-specific interrupt controller initialisation */ z_soc_irq_init(); #endif diff --git a/arch/arm/core/aarch32/cortex_a_r/stacks.c b/arch/arm/core/aarch32/cortex_a_r/stacks.c index 59499e694d28b6..2c95ba97742f0a 100644 --- a/arch/arm/core/aarch32/cortex_a_r/stacks.c +++ b/arch/arm/core/aarch32/cortex_a_r/stacks.c @@ -9,11 +9,11 @@ #include #include -K_THREAD_STACK_DEFINE(z_arm_fiq_stack, CONFIG_ARMV7_FIQ_STACK_SIZE); -K_THREAD_STACK_DEFINE(z_arm_abort_stack, CONFIG_ARMV7_EXCEPTION_STACK_SIZE); -K_THREAD_STACK_DEFINE(z_arm_undef_stack, CONFIG_ARMV7_EXCEPTION_STACK_SIZE); -K_THREAD_STACK_DEFINE(z_arm_svc_stack, CONFIG_ARMV7_SVC_STACK_SIZE); -K_THREAD_STACK_DEFINE(z_arm_sys_stack, CONFIG_ARMV7_SYS_STACK_SIZE); +K_KERNEL_STACK_DEFINE(z_arm_fiq_stack, CONFIG_ARMV7_FIQ_STACK_SIZE); +K_KERNEL_STACK_DEFINE(z_arm_abort_stack, CONFIG_ARMV7_EXCEPTION_STACK_SIZE); +K_KERNEL_STACK_DEFINE(z_arm_undef_stack, CONFIG_ARMV7_EXCEPTION_STACK_SIZE); +K_KERNEL_STACK_DEFINE(z_arm_svc_stack, CONFIG_ARMV7_SVC_STACK_SIZE); +K_KERNEL_STACK_DEFINE(z_arm_sys_stack, CONFIG_ARMV7_SYS_STACK_SIZE); #if defined(CONFIG_INIT_STACKS) void z_arm_init_stacks(void) @@ -22,7 +22,7 @@ void z_arm_init_stacks(void) memset(z_arm_svc_stack, 0xAA, CONFIG_ARMV7_SVC_STACK_SIZE); memset(z_arm_abort_stack, 0xAA, CONFIG_ARMV7_EXCEPTION_STACK_SIZE); memset(z_arm_undef_stack, 0xAA, CONFIG_ARMV7_EXCEPTION_STACK_SIZE); - memset(Z_THREAD_STACK_BUFFER(z_interrupt_stacks[0]), 0xAA, - CONFIG_ISR_STACK_SIZE); + memset(Z_KERNEL_STACK_BUFFER(z_interrupt_stacks[0]), 0xAA, + K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[0])); } #endif diff --git a/arch/arm/core/aarch32/cortex_a_r/thread_abort.c b/arch/arm/core/aarch32/cortex_a_r/thread_abort.c deleted file mode 100644 index 7836f0394ca6cd..00000000000000 --- a/arch/arm/core/aarch32/cortex_a_r/thread_abort.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2020 Stephanos Ioannidis - * Copyright (c) 2016 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief ARM Cortex-A and Cortex-R k_thread_abort() routine - * - * The ARM Cortex-A and Cortex-R architectures provide their own - * k_thread_abort() to deal with different CPU modes when a thread aborts. - */ - -#include -#include - -extern void z_thread_single_abort(struct k_thread *thread); - -void z_impl_k_thread_abort(k_tid_t thread) -{ - __ASSERT(!(thread->base.user_options & K_ESSENTIAL), - "essential thread aborted"); - - z_thread_single_abort(thread); - z_thread_monitor_exit(thread); - - /* - * Swap context if and only if the thread is not aborted inside an - * interrupt/exception handler; it is not necessary to swap context - * inside an interrupt/exception handler because the handler swaps - * context when exiting. - */ - if (!arch_is_in_isr()) { - if (thread == _current) { - /* Direct use of swap: reschedule doesn't have a test - * for "is _current dead" and we don't want one for - * performance reasons. - */ - z_swap_unlocked(); - } else { - z_reschedule_unlocked(); - } - } -} diff --git a/arch/arm/core/aarch32/cortex_a_r/vector_table.S b/arch/arm/core/aarch32/cortex_a_r/vector_table.S index bfc022ac69d967..f7f419398825f3 100644 --- a/arch/arm/core/aarch32/cortex_a_r/vector_table.S +++ b/arch/arm/core/aarch32/cortex_a_r/vector_table.S @@ -23,5 +23,9 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table) ldr pc, =z_arm_prefetch_abort /* prefetch abort offset 0xc */ ldr pc, =z_arm_data_abort /* data abort offset 0x10 */ nop /* offset 0x14 */ +#ifdef CONFIG_GEN_SW_ISR_TABLE ldr pc, =_isr_wrapper /* IRQ offset 0x18 */ +#else + ldr pc, =z_irq_spurious +#endif ldr pc, =z_arm_nmi /* FIQ offset 0x1c */ diff --git a/arch/arm/core/aarch32/cortex_a_r/vector_table.h b/arch/arm/core/aarch32/cortex_a_r/vector_table.h index 9abbec1c8d9580..e83bc167c74f3c 100644 --- a/arch/arm/core/aarch32/cortex_a_r/vector_table.h +++ b/arch/arm/core/aarch32/cortex_a_r/vector_table.h @@ -29,7 +29,7 @@ #include GTEXT(__start) -GTEXT(_vector_table) +GDATA(_vector_table) GTEXT(z_arm_nmi) GTEXT(z_arm_undef_instruction) diff --git a/arch/arm/core/aarch32/cortex_m/CMakeLists.txt b/arch/arm/core/aarch32/cortex_m/CMakeLists.txt index 52d84ba2b7ab6a..42c80368c79bdf 100644 --- a/arch/arm/core/aarch32/cortex_m/CMakeLists.txt +++ b/arch/arm/core/aarch32/cortex_m/CMakeLists.txt @@ -13,13 +13,36 @@ zephyr_library_sources( thread_abort.c ) -zephyr_linker_sources_ifdef(CONFIG_SW_VECTOR_RELAY +zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) + +if(CONFIG_CORTEX_M_DWT) + if (CONFIG_TIMING_FUNCTIONS) + zephyr_library_sources(timing.c) + endif() +endif() + +if (CONFIG_SW_VECTOR_RELAY) +if (CONFIG_CPU_CORTEX_M_HAS_VTOR) + set(relay_vector_table_sort_key relay_vectors) +else() +# Using 0x0 prefix will result in placing the relay vector table section +# at the beginning of ROM_START (i.e before other sections in ROM_START); +# required for CPUs without VTOR, which need to have the exception vector +# table starting at a fixed address at the beginning of ROM. + set(relay_vector_table_sort_key 0x0relay_vectors) +endif() + +zephyr_linker_sources( ROM_START - SORT_KEY 0x0relay_vectors + SORT_KEY ${relay_vector_table_sort_key} relay_vector_table.ld ) +endif() -zephyr_linker_sources_ifdef(CONFIG_SW_VECTOR_RELAY +if (CONFIG_SW_VECTOR_RELAY OR CONFIG_SW_VECTOR_RELAY_CLIENT) +zephyr_linker_sources( RAM_SECTIONS vt_pointer_section.ld ) +endif() diff --git a/arch/arm/core/aarch32/cortex_m/Kconfig b/arch/arm/core/aarch32/cortex_m/Kconfig index ceba210c859fc7..325d7bfef6df5d 100644 --- a/arch/arm/core/aarch32/cortex_m/Kconfig +++ b/arch/arm/core/aarch32/cortex_m/Kconfig @@ -23,6 +23,13 @@ config CPU_CORTEX_M0PLUS help This option signifies the use of a Cortex-M0+ CPU +config CPU_CORTEX_M1 + bool + select CPU_CORTEX_M + select ARMV6_M_ARMV8_M_BASELINE + help + This option signifies the use of a Cortex-M1 CPU + config CPU_CORTEX_M3 bool select CPU_CORTEX_M @@ -72,7 +79,7 @@ config CPU_CORTEX_M_HAS_SYSTICK config CPU_CORTEX_M_HAS_DWT bool - depends on !CPU_CORTEX_M0 && !CPU_CORTEX_M0PLUS + depends on !CPU_CORTEX_M0 && !CPU_CORTEX_M0PLUS && !CPU_CORTEX_M1 help This option signifies that the CPU implements the Data Watchpoint and Trace (DWT) unit specified by the ARMv7-M and above. @@ -96,14 +103,14 @@ config CPU_CORTEX_M_HAS_BASEPRI config CPU_CORTEX_M_HAS_VTOR bool - depends on !CPU_CORTEX_M0 + depends on !CPU_CORTEX_M0 && !CPU_CORTEX_M1 help This option signifies the CPU has the VTOR register. The VTOR indicates the offset of the vector table base address from memory address 0x00000000. Always present in CPUs implementing the ARMv7-M or ARMv8-M architectures. Optional in CPUs implementing ARMv6-M, ARMv8-M Baseline - architectures (except for Cortex-M0, where it is never + architectures (except for Cortex-M0/M1, where it is never implemented). config CPU_CORTEX_M_HAS_SPLIM @@ -132,6 +139,7 @@ config CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS config CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP bool + depends on ARMV6_M_ARMV8_M_BASELINE help This option signifies the Cortex-M0 has some mechanisms that can map the vector table to SRAM @@ -229,10 +237,7 @@ config ARMV8_M_DSP This option signifies the use of an ARMv8-M processor implementation supporting the DSP Extension. -config XIP - default y - -menu "ARM Cortex-M0/M0+/M3/M4/M7/M23/M33 options" +menu "ARM Cortex-M0/M0+/M1/M3/M4/M7/M23/M33 options" depends on ARMV6_M_ARMV8_M_BASELINE || ARMV7_M_ARMV8_M_MAINLINE config GEN_ISR_TABLES @@ -267,16 +272,30 @@ config DYNAMIC_DIRECT_INTERRUPTS config SW_VECTOR_RELAY bool "Enable Software Vector Relay" - default y if BOOTLOADER_MCUBOOT - depends on ARMV6_M_ARMV8_M_BASELINE && !(CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP || CPU_CORTEX_M_HAS_VTOR) help - Add Vector Table relay handler and relay vector table, to - relay interrupts based on a vector table pointer. This is only - required for Cortex-M0 (or an Armv8-M baseline core) with no hardware - vector table relocation mechanisms or for Cortex-M0+ - (or an Armv8-M baseline core) with no VTOR and no other hardware - relocation table mechanisms. - + When building a bootloader firmware this option adds a + vector table relay handler and a vector relay table, to + relay interrupts based on a vector table pointer. + This is only required but not limited to Cortex-M Baseline CPUs + with no hardware vector table relocation mechanisms (e.g. VTOR). + +config SW_VECTOR_RELAY_CLIENT + bool "Enable Software Vector Relay (client)" + default y if BOOTLOADER_MCUBOOT && !CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP + depends on !CPU_CORTEX_M_HAS_VTOR + help + Another image has enabled SW_VECTOR_RELAY, and will be forwarding + exceptions and HW interrupts to this image. Enable this option to make + sure the vector table pointer in RAM is set properly by the image upon + initialization. + +config CORTEX_M_DWT + bool "Enable and use the DWT" + depends on CPU_CORTEX_M_HAS_DWT + default y if TIMING_FUNCTIONS + help + Enable and use the Data Watchpoint and Trace (DWT) unit for + timing functions. endmenu rsource "mpu/Kconfig" diff --git a/arch/arm/core/aarch32/cortex_m/__aeabi_read_tp.S b/arch/arm/core/aarch32/cortex_m/__aeabi_read_tp.S new file mode 100644 index 00000000000000..bb13290d38c6b0 --- /dev/null +++ b/arch/arm/core/aarch32/cortex_m/__aeabi_read_tp.S @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +_ASM_FILE_PROLOGUE + +GTEXT(__aeabi_read_tp) + +GDATA(z_arm_tls_ptr) + +SECTION_FUNC(TEXT, __aeabi_read_tp) + /* Grab the TLS pointer and store in R0 */ + ldr r0, =z_arm_tls_ptr + ldr r0, [r0] + bx lr diff --git a/arch/arm/core/aarch32/cortex_m/cmse/arm_core_cmse.c b/arch/arm/core/aarch32/cortex_m/cmse/arm_core_cmse.c index 19ea839ac50e7b..acf1e889be1acf 100644 --- a/arch/arm/core/aarch32/cortex_m/cmse/arm_core_cmse.c +++ b/arch/arm/core/aarch32/cortex_m/cmse/arm_core_cmse.c @@ -7,7 +7,7 @@ #include #include -int arm_cmse_mpu_region_get(u32_t addr) +int arm_cmse_mpu_region_get(uint32_t addr) { cmse_address_info_t addr_info = cmse_TT((void *)addr); @@ -18,7 +18,7 @@ int arm_cmse_mpu_region_get(u32_t addr) return -EINVAL; } -static int arm_cmse_addr_read_write_ok(u32_t addr, int force_npriv, int rw) +static int arm_cmse_addr_read_write_ok(uint32_t addr, int force_npriv, int rw) { cmse_address_info_t addr_info; if (force_npriv) { @@ -30,17 +30,17 @@ static int arm_cmse_addr_read_write_ok(u32_t addr, int force_npriv, int rw) return rw ? addr_info.flags.readwrite_ok : addr_info.flags.read_ok; } -int arm_cmse_addr_read_ok(u32_t addr, int force_npriv) +int arm_cmse_addr_read_ok(uint32_t addr, int force_npriv) { return arm_cmse_addr_read_write_ok(addr, force_npriv, 0); } -int arm_cmse_addr_readwrite_ok(u32_t addr, int force_npriv) +int arm_cmse_addr_readwrite_ok(uint32_t addr, int force_npriv) { return arm_cmse_addr_read_write_ok(addr, force_npriv, 1); } -static int arm_cmse_addr_range_read_write_ok(u32_t addr, u32_t size, +static int arm_cmse_addr_range_read_write_ok(uint32_t addr, uint32_t size, int force_npriv, int rw) { int flags = 0; @@ -60,19 +60,19 @@ static int arm_cmse_addr_range_read_write_ok(u32_t addr, u32_t size, } } -int arm_cmse_addr_range_read_ok(u32_t addr, u32_t size, int force_npriv) +int arm_cmse_addr_range_read_ok(uint32_t addr, uint32_t size, int force_npriv) { return arm_cmse_addr_range_read_write_ok(addr, size, force_npriv, 0); } -int arm_cmse_addr_range_readwrite_ok(u32_t addr, u32_t size, int force_npriv) +int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv) { return arm_cmse_addr_range_read_write_ok(addr, size, force_npriv, 1); } #if defined(CONFIG_ARM_SECURE_FIRMWARE) -int arm_cmse_mpu_nonsecure_region_get(u32_t addr) +int arm_cmse_mpu_nonsecure_region_get(uint32_t addr) { cmse_address_info_t addr_info = cmse_TTA((void *)addr); @@ -83,7 +83,7 @@ int arm_cmse_mpu_nonsecure_region_get(u32_t addr) return -EINVAL; } -int arm_cmse_sau_region_get(u32_t addr) +int arm_cmse_sau_region_get(uint32_t addr) { cmse_address_info_t addr_info = cmse_TT((void *)addr); @@ -94,7 +94,7 @@ int arm_cmse_sau_region_get(u32_t addr) return -EINVAL; } -int arm_cmse_idau_region_get(u32_t addr) +int arm_cmse_idau_region_get(uint32_t addr) { cmse_address_info_t addr_info = cmse_TT((void *)addr); @@ -105,14 +105,14 @@ int arm_cmse_idau_region_get(u32_t addr) return -EINVAL; } -int arm_cmse_addr_is_secure(u32_t addr) +int arm_cmse_addr_is_secure(uint32_t addr) { cmse_address_info_t addr_info = cmse_TT((void *)addr); return addr_info.flags.secure; } -static int arm_cmse_addr_nonsecure_read_write_ok(u32_t addr, +static int arm_cmse_addr_nonsecure_read_write_ok(uint32_t addr, int force_npriv, int rw) { cmse_address_info_t addr_info; @@ -126,17 +126,17 @@ static int arm_cmse_addr_nonsecure_read_write_ok(u32_t addr, addr_info.flags.nonsecure_read_ok; } -int arm_cmse_addr_nonsecure_read_ok(u32_t addr, int force_npriv) +int arm_cmse_addr_nonsecure_read_ok(uint32_t addr, int force_npriv) { return arm_cmse_addr_nonsecure_read_write_ok(addr, force_npriv, 0); } -int arm_cmse_addr_nonsecure_readwrite_ok(u32_t addr, int force_npriv) +int arm_cmse_addr_nonsecure_readwrite_ok(uint32_t addr, int force_npriv) { return arm_cmse_addr_nonsecure_read_write_ok(addr, force_npriv, 1); } -static int arm_cmse_addr_range_nonsecure_read_write_ok(u32_t addr, u32_t size, +static int arm_cmse_addr_range_nonsecure_read_write_ok(uint32_t addr, uint32_t size, int force_npriv, int rw) { int flags = CMSE_NONSECURE; @@ -156,14 +156,14 @@ static int arm_cmse_addr_range_nonsecure_read_write_ok(u32_t addr, u32_t size, } } -int arm_cmse_addr_range_nonsecure_read_ok(u32_t addr, u32_t size, +int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size, int force_npriv) { return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size, force_npriv, 0); } -int arm_cmse_addr_range_nonsecure_readwrite_ok(u32_t addr, u32_t size, +int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv) { return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size, diff --git a/arch/arm/core/aarch32/cortex_m/coredump.c b/arch/arm/core/aarch32/cortex_m/coredump.c new file mode 100644 index 00000000000000..58255e0327d064 --- /dev/null +++ b/arch/arm/core/aarch32/cortex_m/coredump.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define ARCH_HDR_VER 1 + +uint32_t z_arm_coredump_fault_sp; + +struct arm_arch_block { + struct { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t xpsr; + uint32_t sp; + } r; +} __packed; + +/* + * This might be too large for stack space if defined + * inside function. So do it here. + */ +static struct arm_arch_block arch_blk; + +void arch_coredump_info_dump(const z_arch_esf_t *esf) +{ + struct z_coredump_arch_hdr_t hdr = { + .id = Z_COREDUMP_ARCH_HDR_ID, + .hdr_version = ARCH_HDR_VER, + .num_bytes = sizeof(arch_blk), + }; + + /* Nothing to process */ + if (esf == NULL) { + return; + } + + (void)memset(&arch_blk, 0, sizeof(arch_blk)); + + /* + * 17 registers expected by GDB. + * Not all are in ESF but the GDB stub + * will need to send all 17 as one packet. + * The stub will need to send undefined + * for registers not presented in coredump. + */ + arch_blk.r.r0 = esf->basic.r0; + arch_blk.r.r1 = esf->basic.r1; + arch_blk.r.r2 = esf->basic.r2; + arch_blk.r.r3 = esf->basic.r3; + arch_blk.r.r12 = esf->basic.ip; + arch_blk.r.lr = esf->basic.lr; + arch_blk.r.pc = esf->basic.pc; + arch_blk.r.xpsr = esf->basic.xpsr; + + arch_blk.r.sp = z_arm_coredump_fault_sp; + + /* Send for output */ + z_coredump_buffer_output((uint8_t *)&hdr, sizeof(hdr)); + z_coredump_buffer_output((uint8_t *)&arch_blk, sizeof(arch_blk)); +} + +uint16_t arch_coredump_tgt_code_get(void) +{ + return COREDUMP_TGT_ARM_CORTEX_M; +} diff --git a/arch/arm/core/aarch32/cortex_m/fault.c b/arch/arm/core/aarch32/cortex_m/fault.c index c1f09216ee6c86..4eb2b0aae43beb 100644 --- a/arch/arm/core/aarch32/cortex_m/fault.c +++ b/arch/arm/core/aarch32/cortex_m/fault.c @@ -17,11 +17,11 @@ #include #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #if defined(CONFIG_PRINTK) || defined(CONFIG_LOG) #define PR_EXC(...) LOG_ERR(__VA_ARGS__) -#define STORE_xFAR(reg_var, reg) u32_t reg_var = (u32_t)reg +#define STORE_xFAR(reg_var, reg) uint32_t reg_var = (uint32_t)reg #else #define PR_EXC(...) #define STORE_xFAR(reg_var, reg) @@ -175,11 +175,11 @@ static bool memory_fault_recoverable(z_arch_esf_t *esf) #ifdef CONFIG_USERSPACE for (int i = 0; i < ARRAY_SIZE(exceptions); i++) { /* Mask out instruction mode */ - u32_t start = (u32_t)exceptions[i].start & ~0x1; - u32_t end = (u32_t)exceptions[i].end & ~0x1; + uint32_t start = (uint32_t)exceptions[i].start & ~0x1U; + uint32_t end = (uint32_t)exceptions[i].end & ~0x1U; if (esf->basic.pc >= start && esf->basic.pc < end) { - esf->basic.pc = (u32_t)(exceptions[i].fixup); + esf->basic.pc = (uint32_t)(exceptions[i].fixup); return true; } } @@ -193,8 +193,8 @@ static bool memory_fault_recoverable(z_arch_esf_t *esf) #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) #if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) -u32_t z_check_thread_stack_fail(const u32_t fault_addr, - const u32_t psp); +uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, + const uint32_t psp); #endif /* CONFIG_MPU_STACK_GUARD || defined(CONFIG_USERSPACE) */ /** @@ -205,11 +205,11 @@ u32_t z_check_thread_stack_fail(const u32_t fault_addr, * * @return error code to identify the fatal error reason */ -static u32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault, +static uint32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable) { - u32_t reason = K_ERR_CPU_EXCEPTION; - u32_t mmfar = -EINVAL; + uint32_t reason = K_ERR_CPU_EXCEPTION; + uint32_t mmfar = -EINVAL; PR_FAULT_INFO("***** MPU FAULT *****"); @@ -276,8 +276,8 @@ static u32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault, * handle the case of 'mmfar' holding the -EINVAL value. */ if (SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) { - u32_t min_stack_ptr = z_check_thread_stack_fail(mmfar, - ((u32_t) &esf[0])); + uint32_t min_stack_ptr = z_check_thread_stack_fail(mmfar, + ((uint32_t) &esf[0])); if (min_stack_ptr) { /* When MemManage Stacking Error has occurred, @@ -339,7 +339,7 @@ static u32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault, */ static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable) { - u32_t reason = K_ERR_CPU_EXCEPTION; + uint32_t reason = K_ERR_CPU_EXCEPTION; PR_FAULT_INFO("***** BUS FAULT *****"); @@ -383,10 +383,10 @@ static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable) #endif /* !defined(CONFIG_ARMV7_M_ARMV8_M_FP) */ #if defined(CONFIG_ARM_MPU) && defined(CONFIG_CPU_HAS_NXP_MPU) - u32_t sperr = SYSMPU->CESR & SYSMPU_CESR_SPERR_MASK; - u32_t mask = BIT(31); + uint32_t sperr = SYSMPU->CESR & SYSMPU_CESR_SPERR_MASK; + uint32_t mask = BIT(31); int i; - u32_t ear = -EINVAL; + uint32_t ear = -EINVAL; if (sperr) { for (i = 0; i < SYSMPU_EAR_COUNT; i++, mask >>= 1) { @@ -426,9 +426,9 @@ static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable) * inspecting the RETTOBASE flag. */ if (SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) { - u32_t min_stack_ptr = + uint32_t min_stack_ptr = z_check_thread_stack_fail(ear, - ((u32_t) &esf[0])); + ((uint32_t) &esf[0])); if (min_stack_ptr) { /* When BusFault Stacking Error @@ -491,9 +491,9 @@ static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable) * * @return error code to identify the fatal error reason */ -static u32_t usage_fault(const z_arch_esf_t *esf) +static uint32_t usage_fault(const z_arch_esf_t *esf) { - u32_t reason = K_ERR_CPU_EXCEPTION; + uint32_t reason = K_ERR_CPU_EXCEPTION; PR_FAULT_INFO("***** USAGE FAULT *****"); @@ -606,9 +606,9 @@ static void debug_monitor(const z_arch_esf_t *esf) * * @return error code to identify the fatal error reason */ -static u32_t hard_fault(z_arch_esf_t *esf, bool *recoverable) +static uint32_t hard_fault(z_arch_esf_t *esf, bool *recoverable) { - u32_t reason = K_ERR_CPU_EXCEPTION; + uint32_t reason = K_ERR_CPU_EXCEPTION; PR_FAULT_INFO("***** HARD FAULT *****"); @@ -621,14 +621,14 @@ static u32_t hard_fault(z_arch_esf_t *esf, bool *recoverable) * priority. We handle the case of Kernel OOPS and Stack * Fail here. */ - u16_t *ret_addr = (u16_t *)esf->basic.pc; + uint16_t *ret_addr = (uint16_t *)esf->basic.pc; /* SVC is a 16-bit instruction. On a synchronous SVC * escalated to Hard Fault, the return address is the * next instruction, i.e. after the SVC. */ #define _SVC_OPCODE 0xDF00 - u16_t fault_insn = *(ret_addr - 1); + uint16_t fault_insn = *(ret_addr - 1); if (((fault_insn & 0xff00) == _SVC_OPCODE) && ((fault_insn & 0x00ff) == _SVC_CALL_RUNTIME_EXCEPT)) { @@ -682,9 +682,9 @@ static void reserved_exception(const z_arch_esf_t *esf, int fault) } /* Handler function for ARM fault conditions. */ -static u32_t fault_handle(z_arch_esf_t *esf, int fault, bool *recoverable) +static uint32_t fault_handle(z_arch_esf_t *esf, int fault, bool *recoverable) { - u32_t reason = K_ERR_CPU_EXCEPTION; + uint32_t reason = K_ERR_CPU_EXCEPTION; *recoverable = false; @@ -747,8 +747,8 @@ static void secure_stack_dump(const z_arch_esf_t *secure_esf) * In case of a Non-Secure function call the top of the * stack contains the return address to Secure state. */ - u32_t *top_of_sec_stack = (u32_t *)secure_esf; - u32_t sec_ret_addr; + uint32_t *top_of_sec_stack = (uint32_t *)secure_esf; + uint32_t sec_ret_addr; #if defined(CONFIG_ARMV7_M_ARMV8_M_FP) if ((*top_of_sec_stack == INTEGRITY_SIGNATURE_STD) || (*top_of_sec_stack == INTEGRITY_SIGNATURE_EXT)) { @@ -790,7 +790,7 @@ static void secure_stack_dump(const z_arch_esf_t *secure_esf) * * @return ESF pointer on success, otherwise return NULL */ -static inline z_arch_esf_t *get_esf(u32_t msp, u32_t psp, u32_t exc_return, +static inline z_arch_esf_t *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_return, bool *nested_exc) { bool alternative_state_exc = false; @@ -929,11 +929,13 @@ static inline z_arch_esf_t *get_esf(u32_t msp, u32_t psp, u32_t exc_return, * @param msp MSP value immediately after the exception occurred * @param psp PSP value immediately after the exception occurred * @param exc_return EXC_RETURN value present in LR after exception entry. + * @param callee_regs Callee-saved registers (R4-R11, PSP) * */ -void z_arm_fault(u32_t msp, u32_t psp, u32_t exc_return) +void z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, + _callee_saved_t *callee_regs) { - u32_t reason = K_ERR_CPU_EXCEPTION; + uint32_t reason = K_ERR_CPU_EXCEPTION; int fault = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk; bool recoverable, nested_exc; z_arch_esf_t *esf; @@ -953,13 +955,30 @@ void z_arm_fault(u32_t msp, u32_t psp, u32_t exc_return) __ASSERT(esf != NULL, "ESF could not be retrieved successfully. Shall never occur."); +#ifdef CONFIG_DEBUG_COREDUMP + z_arm_coredump_fault_sp = POINTER_TO_UINT(esf); +#endif + reason = fault_handle(esf, fault, &recoverable); if (recoverable) { return; } /* Copy ESF */ +#if !defined(CONFIG_EXTRA_EXCEPTION_INFO) memcpy(&esf_copy, esf, sizeof(z_arch_esf_t)); + ARG_UNUSED(callee_regs); +#else + /* the extra exception info is not present in the original esf + * so we only copy the fields before those. + */ + memcpy(&esf_copy, esf, offsetof(z_arch_esf_t, extra_info)); + esf_copy.extra_info = (struct __extra_esf_info) { + .callee = callee_regs, + .exc_return = exc_return, + .msp = msp + }; +#endif /* CONFIG_EXTRA_EXCEPTION_INFO */ /* Overwrite stacked IPSR to mark a nested exception, * or a return to Thread mode. Note that this may be diff --git a/arch/arm/core/aarch32/cortex_m/fault_s.S b/arch/arm/core/aarch32/cortex_m/fault_s.S index b691807ad1a489..e4a1b247754f0d 100644 --- a/arch/arm/core/aarch32/cortex_m/fault_s.S +++ b/arch/arm/core/aarch32/cortex_m/fault_s.S @@ -46,9 +46,10 @@ GTEXT(z_arm_exc_spurious) * - the MSP * - the PSP * - the EXC_RETURN value + * - callee saved register state (r4-r11, psp) * as parameters to the z_arm_fault() C function that will perform the - * rest of the fault handling (i.e. z_arm_fault(MSP, PSP, EXC_RETURN)). - + * rest of the fault handling: + * (i.e. z_arm_fault(MSP, PSP, EXC_RETURN, CALLEE_REGS)). * Provides these symbols: * * z_arm_hard_fault @@ -78,12 +79,35 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_exc_spurious) mrs r0, MSP mrs r1, PSP - mov r2, lr /* EXC_RETURN */ - push {r0, lr} - +#if defined(CONFIG_EXTRA_EXCEPTION_INFO) + /* Build _callee_saved_t. To match the struct + * definition we push the psp & then r11-r4 + */ + push { r1, r2 } +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + mov r3, r11 + mov r2, r10 + push {r2, r3} + mov r3, r9 + mov r2, r8 + push {r2, r3} + push {r4-r7} +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + push {r4-r11} +#endif + mov r3, sp /* pointer to _callee_saved_t */ +#endif /* CONFIG_EXTRA_EXCEPTION_INFO */ + mov r2, lr /* EXC_RETURN */ bl z_arm_fault - +#if defined(CONFIG_EXTRA_EXCEPTION_INFO) + /* We do not need to restore any register state here + * because we did not use any callee-saved registers + * in this routine. Therefore, we can just reset + * the MSP to its value prior to entering the function + */ + add sp, #40 +#endif pop {r0, pc} .end diff --git a/arch/arm/core/aarch32/cortex_m/mpu/CMakeLists.txt b/arch/arm/core/aarch32/cortex_m/mpu/CMakeLists.txt index 5a552e22b6234d..8c7aa7e3c9deb6 100644 --- a/arch/arm/core/aarch32/cortex_m/mpu/CMakeLists.txt +++ b/arch/arm/core/aarch32/cortex_m/mpu/CMakeLists.txt @@ -5,8 +5,3 @@ zephyr_library() zephyr_library_sources( arm_core_mpu.c) zephyr_library_sources_ifdef(CONFIG_CPU_HAS_ARM_MPU arm_mpu.c) zephyr_library_sources_ifdef(CONFIG_CPU_HAS_NXP_MPU nxp_mpu.c) - -zephyr_library_include_directories( - . - ../../../include/cortex_m -) diff --git a/arch/arm/core/aarch32/cortex_m/mpu/Kconfig b/arch/arm/core/aarch32/cortex_m/mpu/Kconfig index fd6bebbb6dc1af..b0c4215694329b 100644 --- a/arch/arm/core/aarch32/cortex_m/mpu/Kconfig +++ b/arch/arm/core/aarch32/cortex_m/mpu/Kconfig @@ -7,7 +7,8 @@ if CPU_HAS_MPU config ARM_MPU bool "ARM MPU Support" - select MEMORY_PROTECTION + select MPU + select SRAM_REGION_PERMISSIONS select THREAD_STACK_INFO select ARCH_HAS_EXECUTABLE_PAGE_BIT select MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT if !(CPU_HAS_NXP_MPU || ARMV8_M_BASELINE || ARMV8_M_MAINLINE) diff --git a/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu.c b/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu.c index 117fd7ef054812..2520543c612e03 100644 --- a/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu.c +++ b/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu.c @@ -39,13 +39,61 @@ LOG_MODULE_REGISTER(mpu); * memory area, where dynamic memory regions may be programmed at run-time. */ #if defined(CONFIG_USERSPACE) -#define _MPU_DYNAMIC_REGIONS_AREA_START ((u32_t)&_app_smem_start) +#define _MPU_DYNAMIC_REGIONS_AREA_START ((uint32_t)&_app_smem_start) #else -#define _MPU_DYNAMIC_REGIONS_AREA_START ((u32_t)&__kernel_ram_start) +#define _MPU_DYNAMIC_REGIONS_AREA_START ((uint32_t)&__kernel_ram_start) #endif /* CONFIG_USERSPACE */ -#define _MPU_DYNAMIC_REGIONS_AREA_SIZE ((u32_t)&__kernel_ram_end - \ +#define _MPU_DYNAMIC_REGIONS_AREA_SIZE ((uint32_t)&__kernel_ram_end - \ _MPU_DYNAMIC_REGIONS_AREA_START) +#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_MPU_STACK_GUARD) +extern K_THREAD_STACK_DEFINE(z_main_stack, CONFIG_MAIN_STACK_SIZE); +#endif + +static const struct z_arm_mpu_partition static_regions[] = { +#if defined(CONFIG_COVERAGE_GCOV) && defined(CONFIG_USERSPACE) + { + /* GCOV code coverage accounting area. Needs User permissions + * to function + */ + .start = (uint32_t)&__gcov_bss_start, + .size = (uint32_t)&__gcov_bss_size, + .attr = K_MEM_PARTITION_P_RW_U_RW, + }, +#endif /* CONFIG_COVERAGE_GCOV && CONFIG_USERSPACE */ +#if defined(CONFIG_NOCACHE_MEMORY) + { + /* Special non-cacheable RAM area */ + .start = (uint32_t)&_nocache_ram_start, + .size = (uint32_t)&_nocache_ram_size, + .attr = K_MEM_PARTITION_P_RW_U_NA_NOCACHE, + }, +#endif /* CONFIG_NOCACHE_MEMORY */ +#if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) + { + /* Special RAM area for program text */ + .start = (uint32_t)&_ramfunc_ram_start, + .size = (uint32_t)&_ramfunc_ram_size, + .attr = K_MEM_PARTITION_P_RX_U_RX, + }, +#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */ +#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_MPU_STACK_GUARD) + /* Main stack MPU guard to detect overflow. + * Note: + * FPU_SHARING and USERSPACE are not supported features + * under CONFIG_MULTITHREADING=n, so the MPU guard (if + * exists) is reserved aside of CONFIG_MAIN_STACK_SIZE + * and there is no requirement for larger guard area (FP + * context is not stacked). + */ + { + .start = (uint32_t)z_main_stack, + .size = (uint32_t)MPU_GUARD_ALIGN_AND_SIZE, + .attr = K_MEM_PARTITION_P_RO_U_NA, + }, +#endif /* !CONFIG_MULTITHREADING && CONFIG_MPU_STACK_GUARD */ +}; + /** * @brief Use the HW-specific MPU driver to program * the static MPU regions. @@ -61,47 +109,6 @@ LOG_MODULE_REGISTER(mpu); */ void z_arm_configure_static_mpu_regions(void) { -#if defined(CONFIG_COVERAGE_GCOV) && defined(CONFIG_USERSPACE) - const struct k_mem_partition gcov_region = - { - .start = (u32_t)&__gcov_bss_start, - .size = (u32_t)&__gcov_bss_size, - .attr = K_MEM_PARTITION_P_RW_U_RW, - }; -#endif /* CONFIG_COVERAGE_GCOV && CONFIG_USERSPACE */ -#if defined(CONFIG_NOCACHE_MEMORY) - const struct k_mem_partition nocache_region = - { - .start = (u32_t)&_nocache_ram_start, - .size = (u32_t)&_nocache_ram_size, - .attr = K_MEM_PARTITION_P_RW_U_NA_NOCACHE, - }; -#endif /* CONFIG_NOCACHE_MEMORY */ -#if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) - const struct k_mem_partition ramfunc_region = - { - .start = (u32_t)&_ramfunc_ram_start, - .size = (u32_t)&_ramfunc_ram_size, - .attr = K_MEM_PARTITION_P_RX_U_RX, - }; -#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */ - - /* Define a constant array of k_mem_partition objects - * to hold the configuration of the respective static - * MPU regions. - */ - const struct k_mem_partition *static_regions[] = { -#if defined(CONFIG_COVERAGE_GCOV) && defined(CONFIG_USERSPACE) - &gcov_region, -#endif /* CONFIG_COVERAGE_GCOV && CONFIG_USERSPACE */ -#if defined(CONFIG_NOCACHE_MEMORY) - &nocache_region, -#endif /* CONFIG_NOCACHE_MEMORY */ -#if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) - &ramfunc_region -#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */ - }; - /* Configure the static MPU regions within firmware SRAM boundaries. * Start address of the image is given by _image_ram_start. The end * of the firmware SRAM area is marked by __kernel_ram_end, taking @@ -109,16 +116,17 @@ void z_arm_configure_static_mpu_regions(void) */ arm_core_mpu_configure_static_mpu_regions(static_regions, ARRAY_SIZE(static_regions), - (u32_t)&_image_ram_start, - (u32_t)&__kernel_ram_end); + (uint32_t)&_image_ram_start, + (uint32_t)&__kernel_ram_end); -#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) - /* Define a constant array of k_mem_partition objects that holds the +#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) && \ + defined(CONFIG_MULTITHREADING) + /* Define a constant array of z_arm_mpu_partition objects that holds the * boundaries of the areas, inside which dynamic region programming * is allowed. The information is passed to the underlying driver at * initialization. */ - const struct k_mem_partition dyn_region_areas[] = { + const struct z_arm_mpu_partition dyn_region_areas[] = { { .start = _MPU_DYNAMIC_REGIONS_AREA_START, .size = _MPU_DYNAMIC_REGIONS_AREA_SIZE, @@ -141,47 +149,66 @@ void z_arm_configure_static_mpu_regions(void) * * For some MPU architectures, such as the unmodified ARMv8-M MPU, * the function must execute with MPU enabled. + * + * This function is not inherently thread-safe, but the memory domain + * spinlock needs to be held anyway. */ void z_arm_configure_dynamic_mpu_regions(struct k_thread *thread) { - /* Define an array of k_mem_partition objects to hold the configuration + /* Define an array of z_arm_mpu_partition objects to hold the configuration * of the respective dynamic MPU regions to be programmed for * the given thread. The array of partitions (along with its * actual size) will be supplied to the underlying MPU driver. + * + * The drivers of what regions get configured are CONFIG_USERSPACE, + * CONFIG_MPU_STACK_GUARD, and K_USER/supervisor threads. + * + * If CONFIG_USERSPACE is defined and the thread is a member of any + * memory domain then any partitions defined within that domain get a + * defined region. + * + * If CONFIG_USERSPACE is defined and the thread is a user thread + * (K_USER) the usermode thread stack is defined a region. + * + * IF CONFIG_MPU_STACK_GUARD is defined the thread is a supervisor + * thread, the stack guard will be defined in front of the + * thread->stack_info.start. On a K_USER thread, the guard is defined + * in front of the privilege mode stack, thread->arch.priv_stack_start. */ - struct k_mem_partition *dynamic_regions[_MAX_DYNAMIC_MPU_REGIONS_NUM]; + static struct z_arm_mpu_partition + dynamic_regions[_MAX_DYNAMIC_MPU_REGIONS_NUM]; - u8_t region_num = 0U; + uint8_t region_num = 0U; #if defined(CONFIG_USERSPACE) - struct k_mem_partition thread_stack; - /* Memory domain */ LOG_DBG("configure thread %p's domain", thread); struct k_mem_domain *mem_domain = thread->mem_domain_info.mem_domain; if (mem_domain) { LOG_DBG("configure domain: %p", mem_domain); - u32_t num_partitions = mem_domain->num_partitions; - struct k_mem_partition partition; + uint32_t num_partitions = mem_domain->num_partitions; + struct k_mem_partition *partition; int i; LOG_DBG("configure domain: %p", mem_domain); for (i = 0; i < CONFIG_MAX_DOMAIN_PARTITIONS; i++) { - partition = mem_domain->partitions[i]; - if (partition.size == 0) { + partition = &mem_domain->partitions[i]; + if (partition->size == 0) { /* Zero size indicates a non-existing * memory partition. */ continue; } LOG_DBG("set region 0x%lx 0x%x", - partition.start, partition.size); + partition->start, partition->size); __ASSERT(region_num < _MAX_DYNAMIC_MPU_REGIONS_NUM, "Out-of-bounds error for dynamic region map."); - dynamic_regions[region_num] = - &mem_domain->partitions[i]; + + dynamic_regions[region_num].start = partition->start; + dynamic_regions[region_num].size = partition->size; + dynamic_regions[region_num].attr = partition->attr; region_num++; num_partitions--; @@ -193,27 +220,31 @@ void z_arm_configure_dynamic_mpu_regions(struct k_thread *thread) /* Thread user stack */ LOG_DBG("configure user thread %p's context", thread); if (thread->arch.priv_stack_start) { - u32_t base = (u32_t)thread->stack_obj; - u32_t size = thread->stack_info.size + + /* K_USER thread stack needs a region */ + uintptr_t base = (uintptr_t)thread->stack_obj; + size_t size = thread->stack_info.size + (thread->stack_info.start - base); __ASSERT(region_num < _MAX_DYNAMIC_MPU_REGIONS_NUM, "Out-of-bounds error for dynamic region map."); - thread_stack = (const struct k_mem_partition) - {base, size, K_MEM_PARTITION_P_RW_U_RW}; - dynamic_regions[region_num] = &thread_stack; + dynamic_regions[region_num].start = base; + dynamic_regions[region_num].size = size; + dynamic_regions[region_num].attr = K_MEM_PARTITION_P_RW_U_RW; region_num++; } #endif /* CONFIG_USERSPACE */ #if defined(CONFIG_MPU_STACK_GUARD) - struct k_mem_partition guard; + /* Define a stack guard region for either the thread stack or the + * supervisor/privilege mode stack depending on the type of thread + * being mapped. + */ /* Privileged stack guard */ - u32_t guard_start; - u32_t guard_size = MPU_GUARD_ALIGN_AND_SIZE; + uintptr_t guard_start; + size_t guard_size = MPU_GUARD_ALIGN_AND_SIZE; #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) if ((thread->base.user_options & K_FP_REGS) != 0) { @@ -223,39 +254,42 @@ void z_arm_configure_dynamic_mpu_regions(struct k_thread *thread) #if defined(CONFIG_USERSPACE) if (thread->arch.priv_stack_start) { + /* A K_USER thread has the stack guard protecting the privilege + * stack and not on the usermode stack because the user mode + * stack already has its own defined memory region. + */ guard_start = thread->arch.priv_stack_start - guard_size; - __ASSERT((u32_t)&z_priv_stacks_ram_start <= guard_start, - "Guard start: (0x%x) below privilege stacks boundary: (0x%x)", - guard_start, (u32_t)&z_priv_stacks_ram_start); - } else { + __ASSERT((uintptr_t)&z_priv_stacks_ram_start <= guard_start, + "Guard start: (0x%lx) below privilege stacks boundary: (%p)", + guard_start, &z_priv_stacks_ram_start); + } else +#endif /* CONFIG_USERSPACE */ + { + /* A supervisor thread only has the normal thread stack to + * protect with a stack guard. + */ guard_start = thread->stack_info.start - guard_size; - - __ASSERT((u32_t)thread->stack_obj == guard_start, - "Guard start (0x%x) not beginning at stack object (0x%x)\n", - guard_start, (u32_t)thread->stack_obj); - } -#else - guard_start = thread->stack_info.start - guard_size; +#ifdef CONFIG_USERSPACE + __ASSERT((uintptr_t)thread->stack_obj == guard_start, + "Guard start (0x%lx) not beginning at stack object (%p)\n", + guard_start, thread->stack_obj); #endif /* CONFIG_USERSPACE */ + } __ASSERT(region_num < _MAX_DYNAMIC_MPU_REGIONS_NUM, "Out-of-bounds error for dynamic region map."); - guard = (const struct k_mem_partition) - { - guard_start, - guard_size, - K_MEM_PARTITION_P_RO_U_NA - }; - dynamic_regions[region_num] = &guard; + + dynamic_regions[region_num].start = guard_start; + dynamic_regions[region_num].size = guard_size; + dynamic_regions[region_num].attr = K_MEM_PARTITION_P_RO_U_NA; region_num++; #endif /* CONFIG_MPU_STACK_GUARD */ /* Configure the dynamic MPU regions */ - arm_core_mpu_configure_dynamic_mpu_regions( - (const struct k_mem_partition **)dynamic_regions, - region_num); + arm_core_mpu_configure_dynamic_mpu_regions(dynamic_regions, + region_num); } #if defined(CONFIG_USERSPACE) @@ -274,81 +308,6 @@ int arch_mem_domain_max_partitions_get(void) return ARM_CORE_MPU_MAX_DOMAIN_PARTITIONS_GET(available_regions); } -void arch_mem_domain_thread_add(struct k_thread *thread) -{ - if (_current != thread) { - return; - } - - /* Request to configure memory domain for a thread. - * This triggers re-programming of the entire dynamic - * memory map. - */ - z_arm_configure_dynamic_mpu_regions(thread); -} - -void arch_mem_domain_destroy(struct k_mem_domain *domain) -{ - /* This function will reset the access permission configuration - * of the active partitions of the memory domain. - */ - int i; - struct k_mem_partition partition; - - if (_current->mem_domain_info.mem_domain != domain) { - return; - } - - /* Partitions belonging to the memory domain will be reset - * to default (Privileged RW, Unprivileged NA) permissions. - */ - k_mem_partition_attr_t reset_attr = K_MEM_PARTITION_P_RW_U_NA; - - for (i = 0; i < CONFIG_MAX_DOMAIN_PARTITIONS; i++) { - partition = domain->partitions[i]; - if (partition.size == 0U) { - /* Zero size indicates a non-existing - * memory partition. - */ - continue; - } - arm_core_mpu_mem_partition_config_update(&partition, - &reset_attr); - } -} - -void arch_mem_domain_partition_remove(struct k_mem_domain *domain, - u32_t partition_id) -{ - /* Request to remove a partition from a memory domain. - * This resets the access permissions of the partition - * to default (Privileged RW, Unprivileged NA). - */ - k_mem_partition_attr_t reset_attr = K_MEM_PARTITION_P_RW_U_NA; - - if (_current->mem_domain_info.mem_domain != domain) { - return; - } - - arm_core_mpu_mem_partition_config_update( - &domain->partitions[partition_id], &reset_attr); -} - -void arch_mem_domain_partition_add(struct k_mem_domain *domain, - u32_t partition_id) -{ - /* No-op on this architecture */ -} - -void arch_mem_domain_thread_remove(struct k_thread *thread) -{ - if (_current != thread) { - return; - } - - arch_mem_domain_destroy(thread->mem_domain_info.mem_domain); -} - int arch_buffer_validate(void *addr, size_t size, int write) { return arm_core_mpu_buffer_validate(addr, size, write); diff --git a/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu_dev.h b/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu_dev.h index 7b43cceab77c4c..57cf13532fe128 100644 --- a/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu_dev.h +++ b/arch/arm/core/aarch32/cortex_m/mpu/arm_core_mpu_dev.h @@ -7,14 +7,13 @@ #define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_CORTEX_M_MPU_ARM_CORE_MPU_DEV_H_ #include +#include #ifdef __cplusplus extern "C" { #endif #if defined(CONFIG_ARM_MPU) -struct k_mem_domain; -struct k_mem_partition; struct k_thread; #if defined(CONFIG_USERSPACE) @@ -133,8 +132,9 @@ struct k_thread; * requirements of the MPU hardware. */ void arm_core_mpu_configure_static_mpu_regions( - const struct k_mem_partition *static_regions[], const u8_t regions_num, - const u32_t background_area_start, const u32_t background_area_end); + const struct z_arm_mpu_partition static_regions[], + const uint8_t regions_num, const uint32_t background_area_start, + const uint32_t background_area_end); #if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) @@ -153,7 +153,7 @@ void arm_core_mpu_configure_static_mpu_regions( * * The function shall be invoked once, upon system initialization. * - * @param dyn_region_areas an array of k_mem_partition objects declaring the + * @param dyn_region_areas an array of z_arm_mpu_partition objects declaring the * eligible memory areas for dynamic programming * @param dyn_region_areas_num the number of eligible areas for dynamic * programming. @@ -164,8 +164,8 @@ void arm_core_mpu_configure_static_mpu_regions( * arm_core_mpu_configure_static_mpu_regions(). */ void arm_core_mpu_mark_areas_for_dynamic_regions( - const struct k_mem_partition dyn_region_areas[], - const u8_t dyn_region_areas_num); + const struct z_arm_mpu_partition dyn_region_areas[], + const uint8_t dyn_region_areas_num); #endif /* CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS */ @@ -185,7 +185,8 @@ void arm_core_mpu_mark_areas_for_dynamic_regions( * not exceed the number of (currently) available MPU indices. */ void arm_core_mpu_configure_dynamic_mpu_regions( - const struct k_mem_partition *dynamic_regions[], u8_t regions_num); + const struct z_arm_mpu_partition dynamic_regions[], + uint8_t regions_num); #if defined(CONFIG_USERSPACE) /** @@ -203,7 +204,7 @@ void arm_core_mpu_configure_dynamic_mpu_regions( * successfully (e.g. the given partition can not be found). */ void arm_core_mpu_mem_partition_config_update( - struct k_mem_partition *partition, + struct z_arm_mpu_partition *partition, k_mem_partition_attr_t *new_attr); #endif /* CONFIG_USERSPACE */ @@ -215,7 +216,7 @@ void arm_core_mpu_mem_partition_config_update( * @param base base address in RAM * @param size size of the region */ -void arm_core_mpu_configure(u8_t type, u32_t base, u32_t size); +void arm_core_mpu_configure(uint8_t type, uint32_t base, uint32_t size); /** * @brief configure MPU regions for the memory partitions of the memory domain @@ -237,15 +238,15 @@ void arm_core_mpu_configure_user_context(struct k_thread *thread); * @param part_index memory partition index * @param part memory partition info */ -void arm_core_mpu_configure_mem_partition(u32_t part_index, - struct k_mem_partition *part); +void arm_core_mpu_configure_mem_partition(uint32_t part_index, + struct z_arm_mpu_partition *part); /** * @brief Reset MPU region for a single memory partition * * @param part_index memory partition index */ -void arm_core_mpu_mem_partition_remove(u32_t part_index); +void arm_core_mpu_mem_partition_remove(uint32_t part_index); /** * @brief Get the maximum number of available (free) MPU region indices diff --git a/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu.c b/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu.c index 88c6ff0d3d341d..9c01eebecf3e4b 100644 --- a/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu.c +++ b/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu.c @@ -10,6 +10,7 @@ #include #include "arm_core_mpu_dev.h" #include +#include #define LOG_LEVEL CONFIG_MPU_LOG_LEVEL #include @@ -36,12 +37,12 @@ LOG_MODULE_DECLARE(mpu); * have been reserved by the MPU driver to program the static (fixed) memory * regions. */ -static u8_t static_regions_num; +static uint8_t static_regions_num; /** * Get the number of supported MPU regions. */ -static inline u8_t get_num_regions(void) +static inline uint8_t get_num_regions(void) { #if defined(CONFIG_CPU_CORTEX_M0PLUS) || \ defined(CONFIG_CPU_CORTEX_M3) || \ @@ -55,11 +56,11 @@ static inline u8_t get_num_regions(void) return NUM_MPU_REGIONS; #else - u32_t type = MPU->TYPE; + uint32_t type = MPU->TYPE; type = (type & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; - return (u8_t)type; + return (uint8_t)type; #endif /* CPU_CORTEX_M0PLUS | CPU_CORTEX_M3 | CPU_CORTEX_M4 */ } @@ -68,19 +69,19 @@ static inline u8_t get_num_regions(void) defined(CONFIG_CPU_CORTEX_M3) || \ defined(CONFIG_CPU_CORTEX_M4) || \ defined(CONFIG_CPU_CORTEX_M7) -#include +#include "arm_mpu_v7_internal.h" #elif defined(CONFIG_CPU_CORTEX_M23) || \ defined(CONFIG_CPU_CORTEX_M33) -#include +#include "arm_mpu_v8_internal.h" #else #error "Unsupported ARM CPU" #endif -static int region_allocate_and_init(const u8_t index, +static int region_allocate_and_init(const uint8_t index, const struct arm_mpu_region *region_conf) { /* Attempt to allocate new region index. */ - if (index > (get_num_regions() - 1)) { + if (index > (get_num_regions() - 1U)) { /* No available MPU region index. */ LOG_ERR("Failed to allocate new MPU region %u\n", index); @@ -98,8 +99,8 @@ static int region_allocate_and_init(const u8_t index, /* This internal function programs an MPU region * of a given configuration at a given MPU index. */ -static int mpu_configure_region(const u8_t index, - const struct k_mem_partition *new_region) +static int mpu_configure_region(const uint8_t index, + const struct z_arm_mpu_partition *new_region) { struct arm_mpu_region region_conf; @@ -107,7 +108,7 @@ static int mpu_configure_region(const u8_t index, /* Populate internal ARM MPU region configuration structure. */ region_conf.base = new_region->start; - get_region_attr_from_k_mem_partition_info(®ion_conf.attr, + get_region_attr_from_mpu_partition_info(®ion_conf.attr, &new_region->attr, new_region->start, new_region->size); /* Allocate and program region */ @@ -121,26 +122,26 @@ static int mpu_configure_region(const u8_t index, * over a background memory area, optionally performing a * sanity check of the memory regions to be programmed. */ -static int mpu_configure_regions(const struct k_mem_partition - *regions[], u8_t regions_num, u8_t start_reg_index, +static int mpu_configure_regions(const struct z_arm_mpu_partition + regions[], uint8_t regions_num, uint8_t start_reg_index, bool do_sanity_check) { int i; int reg_index = start_reg_index; for (i = 0; i < regions_num; i++) { - if (regions[i]->size == 0U) { + if (regions[i].size == 0U) { continue; } /* Non-empty region. */ if (do_sanity_check && - (!mpu_partition_is_valid(regions[i]))) { + (!mpu_partition_is_valid(®ions[i]))) { LOG_ERR("Partition %u: sanity check failed.", i); return -EINVAL; } - reg_index = mpu_configure_region(reg_index, regions[i]); + reg_index = mpu_configure_region(reg_index, ®ions[i]); if (reg_index == -EINVAL) { return reg_index; @@ -188,25 +189,25 @@ void arm_core_mpu_disable(void) * @brief update configuration of an active memory partition */ void arm_core_mpu_mem_partition_config_update( - struct k_mem_partition *partition, + struct z_arm_mpu_partition *partition, k_mem_partition_attr_t *new_attr) { /* Find the partition. ASSERT if not found. */ - u8_t i; - u8_t reg_index = get_num_regions(); + uint8_t i; + uint8_t reg_index = get_num_regions(); for (i = get_dyn_region_min_index(); i < get_num_regions(); i++) { if (!is_enabled_region(i)) { continue; } - u32_t base = mpu_region_get_base(i); + uint32_t base = mpu_region_get_base(i); if (base != partition->start) { continue; } - u32_t size = mpu_region_get_size(i); + uint32_t size = mpu_region_get_size(i); if (size != partition->size) { continue; @@ -217,7 +218,8 @@ void arm_core_mpu_mem_partition_config_update( break; } __ASSERT(reg_index != get_num_regions(), - "Memory domain partition not found\n"); + "Memory domain partition %p size %zu not found\n", + (void *)partition->start, partition->size); /* Modify the permissions */ partition->attr = *new_attr; @@ -248,9 +250,9 @@ int arm_core_mpu_buffer_validate(void *addr, size_t size, int write) /** * @brief configure fixed (static) MPU regions. */ -void arm_core_mpu_configure_static_mpu_regions(const struct k_mem_partition - *static_regions[], const u8_t regions_num, - const u32_t background_area_start, const u32_t background_area_end) +void arm_core_mpu_configure_static_mpu_regions(const struct z_arm_mpu_partition + static_regions[], const uint8_t regions_num, + const uint32_t background_area_start, const uint32_t background_area_end) { if (mpu_configure_static_mpu_regions(static_regions, regions_num, background_area_start, background_area_end) == -EINVAL) { @@ -265,8 +267,8 @@ void arm_core_mpu_configure_static_mpu_regions(const struct k_mem_partition * @brief mark memory areas for dynamic region configuration */ void arm_core_mpu_mark_areas_for_dynamic_regions( - const struct k_mem_partition dyn_region_areas[], - const u8_t dyn_region_areas_num) + const struct z_arm_mpu_partition dyn_region_areas[], + const uint8_t dyn_region_areas_num) { if (mpu_mark_areas_for_dynamic_regions(dyn_region_areas, dyn_region_areas_num) == -EINVAL) { @@ -280,8 +282,8 @@ void arm_core_mpu_mark_areas_for_dynamic_regions( /** * @brief configure dynamic MPU regions. */ -void arm_core_mpu_configure_dynamic_mpu_regions(const struct k_mem_partition - *dynamic_regions[], u8_t regions_num) +void arm_core_mpu_configure_dynamic_mpu_regions(const struct z_arm_mpu_partition + dynamic_regions[], uint8_t regions_num) { if (mpu_configure_dynamic_mpu_regions(dynamic_regions, regions_num) == -EINVAL) { @@ -299,9 +301,9 @@ void arm_core_mpu_configure_dynamic_mpu_regions(const struct k_mem_partition * This function provides the default configuration mechanism for the Memory * Protection Unit (MPU). */ -static int arm_mpu_init(struct device *arg) +static int arm_mpu_init(const struct device *arg) { - u32_t r_index; + uint32_t r_index; if (mpu_config.num_regions > get_num_regions()) { /* Attempt to configure more MPU regions than @@ -322,6 +324,15 @@ static int arm_mpu_init(struct device *arg) arm_core_mpu_disable(); +#if defined(CONFIG_NOCACHE_MEMORY) + /* Clean and invalidate data cache if + * that was not already done at boot + */ +#if !defined(CONFIG_INIT_ARCH_HW_AT_BOOT) + SCB_CleanInvalidateDCache(); +#endif +#endif /* CONFIG_NOCACHE_MEMORY */ + /* Architecture-specific configuration */ mpu_init(); diff --git a/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu_v7_internal.h b/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu_v7_internal.h index 08d903808c512a..53a98339b78f0c 100644 --- a/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu_v7_internal.h +++ b/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu_v7_internal.h @@ -25,7 +25,7 @@ static void mpu_init(void) * Note: * The caller must provide a valid region index. */ -static void region_init(const u32_t index, +static void region_init(const uint32_t index, const struct arm_mpu_region *region_conf) { /* Select the region you want to access */ @@ -46,7 +46,7 @@ static void region_init(const u32_t index, * @param part Pointer to the data structure holding the partition * information (must be valid). */ -static int mpu_partition_is_valid(const struct k_mem_partition *part) +static int mpu_partition_is_valid(const struct z_arm_mpu_partition *part) { /* Partition size must be power-of-two, * and greater or equal to the minimum @@ -54,11 +54,11 @@ static int mpu_partition_is_valid(const struct k_mem_partition *part) * partition must align with size. */ int partition_is_valid = - ((part->size & (part->size - 1)) == 0U) + ((part->size & (part->size - 1U)) == 0U) && (part->size >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE) && - ((part->start & (part->size - 1)) == 0U); + ((part->start & (part->size - 1U)) == 0U); return partition_is_valid; } @@ -71,7 +71,7 @@ static int mpu_partition_is_valid(const struct k_mem_partition *part) * power-of-two value, and the returned SIZE field value corresponds * to that power-of-two value. */ -static inline u32_t size_to_mpu_rasr_size(u32_t size) +static inline uint32_t size_to_mpu_rasr_size(uint32_t size) { /* The minimal supported region size is 32 bytes */ if (size <= 32U) { @@ -87,7 +87,7 @@ static inline u32_t size_to_mpu_rasr_size(u32_t size) return REGION_4G; } - return ((32 - __builtin_clz(size - 1) - 2 + 1) << MPU_RASR_SIZE_Pos) & + return ((32 - __builtin_clz(size - 1U) - 2 + 1) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk; } @@ -96,9 +96,9 @@ static inline u32_t size_to_mpu_rasr_size(u32_t size) * region attribute configuration and size and fill-in a driver-specific * structure with the correct MPU region configuration. */ -static inline void get_region_attr_from_k_mem_partition_info( +static inline void get_region_attr_from_mpu_partition_info( arm_mpu_region_attr_t *p_attr, - const k_mem_partition_attr_t *attr, u32_t base, u32_t size) + const k_mem_partition_attr_t *attr, uint32_t base, uint32_t size) { /* in ARMv7-M MPU the base address is not required * to determine region attributes @@ -126,21 +126,21 @@ static inline int get_dyn_region_min_index(void) * This internal function converts the SIZE field value of MPU_RASR * to the region size (in bytes). */ -static inline u32_t mpu_rasr_size_to_size(u32_t rasr_size) +static inline uint32_t mpu_rasr_size_to_size(uint32_t rasr_size) { - return 1 << (rasr_size + 1); + return 1 << (rasr_size + 1U); } -static inline u32_t mpu_region_get_base(u32_t index) +static inline uint32_t mpu_region_get_base(uint32_t index) { MPU->RNR = index; return MPU->RBAR & MPU_RBAR_ADDR_Msk; } -static inline u32_t mpu_region_get_size(u32_t index) +static inline uint32_t mpu_region_get_size(uint32_t index) { MPU->RNR = index; - u32_t rasr_size = (MPU->RASR & MPU_RASR_SIZE_Msk) >> MPU_RASR_SIZE_Pos; + uint32_t rasr_size = (MPU->RASR & MPU_RASR_SIZE_Msk) >> MPU_RASR_SIZE_Pos; return mpu_rasr_size_to_size(rasr_size); } @@ -151,11 +151,11 @@ static inline u32_t mpu_region_get_size(u32_t index) * Note: * The caller must provide a valid region number. */ -static inline int is_enabled_region(u32_t index) +static inline int is_enabled_region(uint32_t index) { /* Lock IRQs to ensure RNR value is correct when reading RASR. */ unsigned int key; - u32_t rasr; + uint32_t rasr; key = irq_lock(); MPU->RNR = index; @@ -177,11 +177,11 @@ static inline int is_enabled_region(u32_t index) * Note: * The caller must provide a valid region number. */ -static inline u32_t get_region_ap(u32_t r_index) +static inline uint32_t get_region_ap(uint32_t r_index) { /* Lock IRQs to ensure RNR value is correct when reading RASR. */ unsigned int key; - u32_t rasr; + uint32_t rasr; key = irq_lock(); MPU->RNR = r_index; @@ -197,16 +197,16 @@ static inline u32_t get_region_ap(u32_t r_index) * Note: * The caller must provide a valid region number. */ -static inline int is_in_region(u32_t r_index, u32_t start, u32_t size) +static inline int is_in_region(uint32_t r_index, uint32_t start, uint32_t size) { - u32_t r_addr_start; - u32_t r_size_lshift; - u32_t r_addr_end; - u32_t end; + uint32_t r_addr_start; + uint32_t r_size_lshift; + uint32_t r_addr_end; + uint32_t end; /* Lock IRQs to ensure RNR value is correct when reading RBAR, RASR. */ unsigned int key; - u32_t rbar, rasr; + uint32_t rbar, rasr; key = irq_lock(); MPU->RNR = r_index; @@ -216,10 +216,10 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size) r_addr_start = rbar & MPU_RBAR_ADDR_Msk; r_size_lshift = ((rasr & MPU_RASR_SIZE_Msk) >> - MPU_RASR_SIZE_Pos) + 1; - r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1; + MPU_RASR_SIZE_Pos) + 1U; + r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1UL; - size = size == 0 ? 0 : size - 1; + size = size == 0U ? 0U : size - 1U; if (u32_add_overflow(start, size, &end)) { return 0; } @@ -237,9 +237,9 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size) * Note: * The caller must provide a valid region number. */ -static inline int is_user_accessible_region(u32_t r_index, int write) +static inline int is_user_accessible_region(uint32_t r_index, int write) { - u32_t r_ap = get_region_ap(r_index); + uint32_t r_ap = get_region_ap(r_index); if (write) { @@ -255,12 +255,12 @@ static inline int is_user_accessible_region(u32_t r_index, int write) */ static inline int mpu_buffer_validate(void *addr, size_t size, int write) { - s32_t r_index; + int32_t r_index; /* Iterate all mpu regions in reversed order */ - for (r_index = get_num_regions() - 1; r_index >= 0; r_index--) { + for (r_index = get_num_regions() - 1U; r_index >= 0; r_index--) { if (!is_enabled_region(r_index) || - !is_in_region(r_index, (u32_t)addr, size)) { + !is_in_region(r_index, (uint32_t)addr, size)) { continue; } @@ -282,11 +282,11 @@ static inline int mpu_buffer_validate(void *addr, size_t size, int write) #endif /* CONFIG_USERSPACE */ -static int mpu_configure_region(const u8_t index, - const struct k_mem_partition *new_region); +static int mpu_configure_region(const uint8_t index, + const struct z_arm_mpu_partition *new_region); -static int mpu_configure_regions(const struct k_mem_partition - *regions[], u8_t regions_num, u8_t start_reg_index, +static int mpu_configure_regions(const struct z_arm_mpu_partition + regions[], uint8_t regions_num, uint8_t start_reg_index, bool do_sanity_check); /* This internal function programs the static MPU regions. @@ -297,10 +297,10 @@ static int mpu_configure_regions(const struct k_mem_partition * If the static MPU regions configuration has not been successfully * performed, the error signal is propagated to the caller of the function. */ -static int mpu_configure_static_mpu_regions(const struct k_mem_partition - *static_regions[], const u8_t regions_num, - const u32_t background_area_base, - const u32_t background_area_end) +static int mpu_configure_static_mpu_regions(const struct z_arm_mpu_partition + static_regions[], const uint8_t regions_num, + const uint32_t background_area_base, + const uint32_t background_area_end) { int mpu_reg_index = static_regions_num; @@ -326,8 +326,8 @@ static int mpu_configure_static_mpu_regions(const struct k_mem_partition * If the dynamic MPU regions configuration has not been successfully * performed, the error signal is propagated to the caller of the function. */ -static int mpu_configure_dynamic_mpu_regions(const struct k_mem_partition - *dynamic_regions[], u8_t regions_num) +static int mpu_configure_dynamic_mpu_regions(const struct z_arm_mpu_partition + dynamic_regions[], uint8_t regions_num) { int mpu_reg_index = static_regions_num; diff --git a/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu_v8_internal.h b/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu_v8_internal.h index 81d0d9bc432f4e..01cf1e7fa62053 100644 --- a/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu_v8_internal.h +++ b/arch/arm/core/aarch32/cortex_m/mpu/arm_mpu_v8_internal.h @@ -57,7 +57,7 @@ static void mpu_init(void) * Note: * The caller must provide a valid region index. */ -static void region_init(const u32_t index, +static void region_init(const uint32_t index, const struct arm_mpu_region *region_conf) { ARM_MPU_SetRegion( @@ -87,7 +87,7 @@ static void region_init(const u32_t index, * @param part Pointer to the data structure holding the partition * information (must be valid). * */ -static int mpu_partition_is_valid(const struct k_mem_partition *part) +static int mpu_partition_is_valid(const struct z_arm_mpu_partition *part) { /* Partition size must be a multiple of the minimum MPU region * size. Start address of the partition must align with the @@ -116,10 +116,10 @@ static int mpu_partition_is_valid(const struct k_mem_partition *part) * needs to be enabled. * */ -static inline int get_region_index(u32_t start, u32_t size) +static inline int get_region_index(uint32_t start, uint32_t size) { - u32_t region_start_addr = arm_cmse_mpu_region_get(start); - u32_t region_end_addr = arm_cmse_mpu_region_get(start + size - 1); + uint32_t region_start_addr = arm_cmse_mpu_region_get(start); + uint32_t region_end_addr = arm_cmse_mpu_region_get(start + size - 1); /* MPU regions are contiguous so return the region number, * if both start and end address are in the same region. @@ -130,33 +130,33 @@ static inline int get_region_index(u32_t start, u32_t size) return -EINVAL; } -static inline u32_t mpu_region_get_base(const u32_t index) +static inline uint32_t mpu_region_get_base(const uint32_t index) { MPU->RNR = index; return MPU->RBAR & MPU_RBAR_BASE_Msk; } -static inline void mpu_region_set_base(const u32_t index, const u32_t base) +static inline void mpu_region_set_base(const uint32_t index, const uint32_t base) { MPU->RNR = index; MPU->RBAR = (MPU->RBAR & (~MPU_RBAR_BASE_Msk)) | (base & MPU_RBAR_BASE_Msk); } -static inline u32_t mpu_region_get_last_addr(const u32_t index) +static inline uint32_t mpu_region_get_last_addr(const uint32_t index) { MPU->RNR = index; return (MPU->RLAR & MPU_RLAR_LIMIT_Msk) | (~MPU_RLAR_LIMIT_Msk); } -static inline void mpu_region_set_limit(const u32_t index, const u32_t limit) +static inline void mpu_region_set_limit(const uint32_t index, const uint32_t limit) { MPU->RNR = index; MPU->RLAR = (MPU->RLAR & (~MPU_RLAR_LIMIT_Msk)) | (limit & MPU_RLAR_LIMIT_Msk); } -static inline void mpu_region_get_access_attr(const u32_t index, +static inline void mpu_region_get_access_attr(const uint32_t index, arm_mpu_region_attr_t *attr) { MPU->RNR = index; @@ -167,7 +167,7 @@ static inline void mpu_region_get_access_attr(const u32_t index, MPU_RLAR_AttrIndx_Pos; } -static inline void mpu_region_get_conf(const u32_t index, +static inline void mpu_region_get_conf(const uint32_t index, struct arm_mpu_region *region_conf) { MPU->RNR = index; @@ -191,9 +191,9 @@ static inline void mpu_region_get_conf(const u32_t index, * region attribute configuration and size and fill-in a driver-specific * structure with the correct MPU region configuration. */ -static inline void get_region_attr_from_k_mem_partition_info( +static inline void get_region_attr_from_mpu_partition_info( arm_mpu_region_attr_t *p_attr, - const k_mem_partition_attr_t *attr, u32_t base, u32_t size) + const k_mem_partition_attr_t *attr, uint32_t base, uint32_t size) { p_attr->rbar = attr->rbar & (MPU_RBAR_XN_Msk | MPU_RBAR_AP_Msk | MPU_RBAR_SH_Msk); @@ -228,7 +228,7 @@ static inline int get_dyn_region_min_index(void) return dyn_reg_min_index; } -static inline u32_t mpu_region_get_size(u32_t index) +static inline uint32_t mpu_region_get_size(uint32_t index) { return mpu_region_get_last_addr(index) + 1 - mpu_region_get_base(index); @@ -240,7 +240,7 @@ static inline u32_t mpu_region_get_size(u32_t index) * Note: * The caller must provide a valid region number. */ -static inline int is_enabled_region(u32_t index) +static inline int is_enabled_region(uint32_t index) { MPU->RNR = index; @@ -272,8 +272,8 @@ static inline int is_enabled_region(u32_t index) */ static inline int mpu_buffer_validate(void *addr, size_t size, int write) { - u32_t _addr = (u32_t)addr; - u32_t _size = (u32_t)size; + uint32_t _addr = (uint32_t)addr; + uint32_t _size = (uint32_t)size; if (write) { if (arm_cmse_addr_range_readwrite_ok(_addr, _size, 1)) { @@ -290,8 +290,8 @@ static inline int mpu_buffer_validate(void *addr, size_t size, int write) * Validation failure may be due to SAU/IDAU presence. * We re-check user accessibility based on MPU only. */ - s32_t r_index_base = arm_cmse_mpu_region_get(_addr); - s32_t r_index_last = arm_cmse_mpu_region_get(_addr + _size - 1); + int32_t r_index_base = arm_cmse_mpu_region_get(_addr); + int32_t r_index_last = arm_cmse_mpu_region_get(_addr + _size - 1); if ((r_index_base != -EINVAL) && (r_index_base == r_index_last)) { /* Valid MPU region, check permissions on base address only. */ @@ -312,15 +312,15 @@ static inline int mpu_buffer_validate(void *addr, size_t size, int write) #endif /* CONFIG_USERSPACE */ -static int region_allocate_and_init(const u8_t index, +static int region_allocate_and_init(const uint8_t index, const struct arm_mpu_region *region_conf); -static int mpu_configure_region(const u8_t index, - const struct k_mem_partition *new_region); +static int mpu_configure_region(const uint8_t index, + const struct z_arm_mpu_partition *new_region); #if !defined(CONFIG_MPU_GAP_FILLING) -static int mpu_configure_regions(const struct k_mem_partition - *regions[], u8_t regions_num, u8_t start_reg_index, +static int mpu_configure_regions(const struct z_arm_mpu_partition + regions[], uint8_t regions_num, uint8_t start_reg_index, bool do_sanity_check); #endif @@ -331,21 +331,21 @@ static int mpu_configure_regions(const struct k_mem_partition * The function performs a full partition of the background memory * area, effectively, leaving no space in this area uncovered by MPU. */ -static int mpu_configure_regions_and_partition(const struct k_mem_partition - *regions[], u8_t regions_num, u8_t start_reg_index, +static int mpu_configure_regions_and_partition(const struct z_arm_mpu_partition + regions[], uint8_t regions_num, uint8_t start_reg_index, bool do_sanity_check) { int i; int reg_index = start_reg_index; for (i = 0; i < regions_num; i++) { - if (regions[i]->size == 0U) { + if (regions[i].size == 0U) { continue; } /* Non-empty region. */ if (do_sanity_check && - (!mpu_partition_is_valid(regions[i]))) { + (!mpu_partition_is_valid(®ions[i]))) { LOG_ERR("Partition %u: sanity check failed.", i); return -EINVAL; } @@ -354,7 +354,7 @@ static int mpu_configure_regions_and_partition(const struct k_mem_partition * inside which the new region will be configured. */ int u_reg_index = - get_region_index(regions[i]->start, regions[i]->size); + get_region_index(regions[i].start, regions[i].size); if ((u_reg_index == -EINVAL) || (u_reg_index > (reg_index - 1))) { @@ -367,11 +367,11 @@ static int mpu_configure_regions_and_partition(const struct k_mem_partition * The new memory region is to be placed inside the underlying * region, possibly splitting the underlying region into two. */ - u32_t u_reg_base = mpu_region_get_base(u_reg_index); - u32_t u_reg_last = mpu_region_get_last_addr(u_reg_index); - u32_t reg_last = regions[i]->start + regions[i]->size - 1; + uint32_t u_reg_base = mpu_region_get_base(u_reg_index); + uint32_t u_reg_last = mpu_region_get_last_addr(u_reg_index); + uint32_t reg_last = regions[i].start + regions[i].size - 1; - if ((regions[i]->start == u_reg_base) && + if ((regions[i].start == u_reg_base) && (reg_last == u_reg_last)) { /* The new region overlaps entirely with the * underlying region. In this case we simply @@ -379,17 +379,17 @@ static int mpu_configure_regions_and_partition(const struct k_mem_partition * underlying region with those of the new * region. */ - mpu_configure_region(u_reg_index, regions[i]); - } else if (regions[i]->start == u_reg_base) { + mpu_configure_region(u_reg_index, ®ions[i]); + } else if (regions[i].start == u_reg_base) { /* The new region starts exactly at the start of the * underlying region; the start of the underlying * region needs to be set to the end of the new region. */ mpu_region_set_base(u_reg_index, - regions[i]->start + regions[i]->size); + regions[i].start + regions[i].size); reg_index = - mpu_configure_region(reg_index, regions[i]); + mpu_configure_region(reg_index, ®ions[i]); if (reg_index == -EINVAL) { return reg_index; @@ -403,10 +403,10 @@ static int mpu_configure_regions_and_partition(const struct k_mem_partition * new region. */ mpu_region_set_limit(u_reg_index, - regions[i]->start - 1); + regions[i].start - 1); reg_index = - mpu_configure_region(reg_index, regions[i]); + mpu_configure_region(reg_index, ®ions[i]); if (reg_index == -EINVAL) { return reg_index; @@ -419,10 +419,10 @@ static int mpu_configure_regions_and_partition(const struct k_mem_partition * into two regions. */ mpu_region_set_limit(u_reg_index, - regions[i]->start - 1); + regions[i].start - 1); reg_index = - mpu_configure_region(reg_index, regions[i]); + mpu_configure_region(reg_index, ®ions[i]); if (reg_index == -EINVAL) { return reg_index; @@ -437,11 +437,11 @@ static int mpu_configure_regions_and_partition(const struct k_mem_partition mpu_region_get_access_attr(u_reg_index, &fill_region.attr); - fill_region.base = regions[i]->start + - regions[i]->size; + fill_region.base = regions[i].start + + regions[i].size; fill_region.attr.r_limit = - REGION_LIMIT_ADDR((regions[i]->start + - regions[i]->size), (u_reg_last - reg_last)); + REGION_LIMIT_ADDR((regions[i].start + + regions[i].size), (u_reg_last - reg_last)); reg_index = region_allocate_and_init(reg_index, @@ -467,10 +467,10 @@ static int mpu_configure_regions_and_partition(const struct k_mem_partition * If the static MPU regions configuration has not been successfully * performed, the error signal is propagated to the caller of the function. */ -static int mpu_configure_static_mpu_regions(const struct k_mem_partition - *static_regions[], const u8_t regions_num, - const u32_t background_area_base, - const u32_t background_area_end) +static int mpu_configure_static_mpu_regions(const struct z_arm_mpu_partition + static_regions[], const uint8_t regions_num, + const uint32_t background_area_base, + const uint32_t background_area_end) { int mpu_reg_index = static_regions_num; @@ -494,8 +494,8 @@ static int mpu_configure_static_mpu_regions(const struct k_mem_partition * -EINVAL on error. */ static int mpu_mark_areas_for_dynamic_regions( - const struct k_mem_partition dyn_region_areas[], - const u8_t dyn_region_areas_num) + const struct z_arm_mpu_partition dyn_region_areas[], + const uint8_t dyn_region_areas_num) { /* In ARMv8-M architecture we need to store the index values * and the default configuration of the MPU regions, inside @@ -538,8 +538,8 @@ static int mpu_mark_areas_for_dynamic_regions( * If the dynamic MPU regions configuration has not been successfully * performed, the error signal is propagated to the caller of the function. */ -static int mpu_configure_dynamic_mpu_regions(const struct k_mem_partition - *dynamic_regions[], u8_t regions_num) +static int mpu_configure_dynamic_mpu_regions(const struct z_arm_mpu_partition + dynamic_regions[], uint8_t regions_num) { int mpu_reg_index = static_regions_num; diff --git a/arch/arm/core/aarch32/cortex_m/mpu/nxp_mpu.c b/arch/arm/core/aarch32/cortex_m/mpu/nxp_mpu.c index 6451591e2a50f5..313a18130b92b9 100644 --- a/arch/arm/core/aarch32/cortex_m/mpu/nxp_mpu.c +++ b/arch/arm/core/aarch32/cortex_m/mpu/nxp_mpu.c @@ -22,7 +22,7 @@ LOG_MODULE_DECLARE(mpu); * have been reserved by the MPU driver to program the static (fixed) memory * regions. */ -static u8_t static_regions_num; +static uint8_t static_regions_num; /* Global MPU configuration at system initialization. */ static void mpu_init(void) @@ -34,7 +34,7 @@ static void mpu_init(void) /** * Get the number of supported MPU regions. */ -static inline u8_t get_num_regions(void) +static inline uint8_t get_num_regions(void) { return FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT; } @@ -47,7 +47,7 @@ static inline u8_t get_num_regions(void) * @param part Pointer to the data structure holding the partition * information (must be valid). */ -static int mpu_partition_is_valid(const struct k_mem_partition *part) +static int mpu_partition_is_valid(const struct z_arm_mpu_partition *part) { /* Partition size must be a multiple of the minimum MPU region * size. Start address of the partition must align with the @@ -71,12 +71,12 @@ static int mpu_partition_is_valid(const struct k_mem_partition *part) * Note: * The caller must provide a valid region index. */ -static void region_init(const u32_t index, +static void region_init(const uint32_t index, const struct nxp_mpu_region *region_conf) { - u32_t region_base = region_conf->base; - u32_t region_end = region_conf->end; - u32_t region_attr = region_conf->attr.attr; + uint32_t region_base = region_conf->base; + uint32_t region_end = region_conf->end; + uint32_t region_attr = region_conf->attr.attr; if (index == 0U) { /* The MPU does not allow writes from the core to affect the @@ -88,11 +88,11 @@ static void region_init(const u32_t index, */ __ASSERT(region_base == SYSMPU->WORD[index][0], "Region %d base address got 0x%08x expected 0x%08x", - index, region_base, (u32_t)SYSMPU->WORD[index][0]); + index, region_base, (uint32_t)SYSMPU->WORD[index][0]); __ASSERT(region_end == SYSMPU->WORD[index][1], "Region %d end address got 0x%08x expected 0x%08x", - index, region_end, (u32_t)SYSMPU->WORD[index][1]); + index, region_end, (uint32_t)SYSMPU->WORD[index][1]); /* Changes to the RGD0_WORD2 alterable fields should be done * via a write to RGDAAC0. @@ -106,15 +106,15 @@ static void region_init(const u32_t index, SYSMPU->WORD[index][3] = SYSMPU_WORD_VLD_MASK; } - LOG_DBG("[%d] 0x%08x 0x%08x 0x%08x 0x%08x", index, - (u32_t)SYSMPU->WORD[index][0], - (u32_t)SYSMPU->WORD[index][1], - (u32_t)SYSMPU->WORD[index][2], - (u32_t)SYSMPU->WORD[index][3]); + LOG_DBG("[%02d] 0x%08x 0x%08x 0x%08x 0x%08x", index, + (uint32_t)SYSMPU->WORD[index][0], + (uint32_t)SYSMPU->WORD[index][1], + (uint32_t)SYSMPU->WORD[index][2], + (uint32_t)SYSMPU->WORD[index][3]); } -static int region_allocate_and_init(const u8_t index, +static int region_allocate_and_init(const uint8_t index, const struct nxp_mpu_region *region_conf) { /* Attempt to allocate new region index. */ @@ -138,9 +138,9 @@ static int region_allocate_and_init(const u8_t index, * region attribute configuration and size and fill-in a driver-specific * structure with the correct MPU region attribute configuration. */ -static inline void get_region_attr_from_k_mem_partition_info( +static inline void get_region_attr_from_mpu_partition_info( nxp_mpu_region_attr_t *p_attr, - const k_mem_partition_attr_t *attr, u32_t base, u32_t size) + const k_mem_partition_attr_t *attr, uint32_t base, uint32_t size) { /* in NXP MPU the base address and size are not required * to determine region attributes @@ -154,8 +154,8 @@ static inline void get_region_attr_from_k_mem_partition_info( /* This internal function programs an MPU region * of a given configuration at a given MPU index. */ -static int mpu_configure_region(const u8_t index, - const struct k_mem_partition *new_region) +static int mpu_configure_region(const uint8_t index, + const struct z_arm_mpu_partition *new_region) { struct nxp_mpu_region region_conf; @@ -164,7 +164,7 @@ static int mpu_configure_region(const u8_t index, /* Populate internal NXP MPU region configuration structure. */ region_conf.base = new_region->start; region_conf.end = (new_region->start + new_region->size - 1); - get_region_attr_from_k_mem_partition_info(®ion_conf.attr, + get_region_attr_from_mpu_partition_info(®ion_conf.attr, &new_region->attr, new_region->start, new_region->size); /* Allocate and program region */ @@ -174,8 +174,8 @@ static int mpu_configure_region(const u8_t index, #if defined(CONFIG_MPU_STACK_GUARD) /* This internal function partitions the SRAM MPU region */ -static int mpu_sram_partitioning(u8_t index, - const struct k_mem_partition *p_region) +static int mpu_sram_partitioning(uint8_t index, + const struct z_arm_mpu_partition *p_region) { /* * The NXP MPU manages the permissions of the overlapping regions @@ -233,27 +233,27 @@ static int mpu_sram_partitioning(u8_t index, * over a background memory area, optionally performing a * sanity check of the memory regions to be programmed. */ -static int mpu_configure_regions(const struct k_mem_partition - *regions[], u8_t regions_num, u8_t start_reg_index, - bool do_sanity_check) +static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], + uint8_t regions_num, uint8_t start_reg_index, + bool do_sanity_check) { int i; int reg_index = start_reg_index; for (i = 0; i < regions_num; i++) { - if (regions[i]->size == 0U) { + if (regions[i].size == 0U) { continue; } /* Non-empty region. */ if (do_sanity_check && - (!mpu_partition_is_valid(regions[i]))) { + (!mpu_partition_is_valid(®ions[i]))) { LOG_ERR("Partition %u: sanity check failed.", i); return -EINVAL; } #if defined(CONFIG_MPU_STACK_GUARD) - if (regions[i]->attr.ap_attr == MPU_REGION_SU_RX) { + if (regions[i].attr.ap_attr == MPU_REGION_SU_RX) { unsigned int key; /* Attempt to configure an MPU Stack Guard region; this @@ -263,7 +263,7 @@ static int mpu_configure_regions(const struct k_mem_partition */ key = irq_lock(); reg_index = - mpu_sram_partitioning(reg_index, regions[i]); + mpu_sram_partitioning(reg_index, ®ions[i]); irq_unlock(key); } #endif /* CONFIG_MPU_STACK_GUARD */ @@ -272,7 +272,7 @@ static int mpu_configure_regions(const struct k_mem_partition return reg_index; } - reg_index = mpu_configure_region(reg_index, regions[i]); + reg_index = mpu_configure_region(reg_index, ®ions[i]); if (reg_index == -EINVAL) { return reg_index; @@ -293,10 +293,10 @@ static int mpu_configure_regions(const struct k_mem_partition * If the static MPU regions configuration has not been successfully * performed, the error signal is propagated to the caller of the function. */ -static int mpu_configure_static_mpu_regions(const struct k_mem_partition - *static_regions[], const u8_t regions_num, - const u32_t background_area_base, - const u32_t background_area_end) +static int mpu_configure_static_mpu_regions( + const struct z_arm_mpu_partition static_regions[], + const uint8_t regions_num, const uint32_t background_area_base, + const uint32_t background_area_end) { int mpu_reg_index = static_regions_num; @@ -322,20 +322,41 @@ static int mpu_configure_static_mpu_regions(const struct k_mem_partition * If the dynamic MPU regions configuration has not been successfully * performed, the error signal is propagated to the caller of the function. */ -static int mpu_configure_dynamic_mpu_regions(const struct k_mem_partition - *dynamic_regions[], u8_t regions_num) +static int mpu_configure_dynamic_mpu_regions( + const struct z_arm_mpu_partition dynamic_regions[], + uint8_t regions_num) { unsigned int key; - /* Reset MPU regions inside which dynamic memory regions may - * be programmed. + /* + * Programming the NXP MPU has to be done with care to avoid race + * conditions that will cause memory faults. The NXP MPU is composed + * of a number of memory region descriptors. The number of descriptors + * varies depending on the SOC. Each descriptor has a start addr, end + * addr, attribute, and valid. When the MPU is enabled, access to + * memory space is checked for access protection errors through an + * OR operation of all of the valid MPU descriptors. + * + * Writing the start/end/attribute descriptor register will clear the + * valid bit for that descriptor. This presents a problem because if + * the current program stack is in that region or if an ISR occurs + * that switches state and uses that region a memory fault will be + * triggered. Note that local variable access can also cause stack + * accesses while programming these registers depending on the compiler + * optimization level. * - * Re-programming these regions will temporarily leave memory areas - * outside all MPU regions. - * This might trigger memory faults if ISRs occurring during - * re-programming perform access in those areas. + * To avoid the race condition a temporary descriptor is set to enable + * access to all of memory before the call to mpu_configure_regions() + * to configure the dynamic memory regions. After, the temporary + * descriptor is invalidated if the mpu_configure_regions() didn't + * overwrite it. */ key = irq_lock(); + /* Use last descriptor region as temporary descriptor */ + region_init(get_num_regions()-1, (const struct nxp_mpu_region *) + &mpu_config.mpu_regions[mpu_config.sram_region]); + + /* Now reset the main SRAM region */ region_init(mpu_config.sram_region, (const struct nxp_mpu_region *) &mpu_config.mpu_regions[mpu_config.sram_region]); irq_unlock(key); @@ -397,12 +418,12 @@ void arm_core_mpu_disable(void) #if defined(CONFIG_USERSPACE) -static inline u32_t mpu_region_get_base(u32_t r_index) +static inline uint32_t mpu_region_get_base(uint32_t r_index) { return SYSMPU->WORD[r_index][0]; } -static inline u32_t mpu_region_get_size(u32_t r_index) +static inline uint32_t mpu_region_get_size(uint32_t r_index) { /* + 1 - */ return (SYSMPU->WORD[r_index][1] + 1) - SYSMPU->WORD[r_index][0]; @@ -414,7 +435,7 @@ static inline u32_t mpu_region_get_size(u32_t r_index) * Note: * The caller must provide a valid region number. */ -static inline int is_enabled_region(u32_t r_index) +static inline int is_enabled_region(uint32_t r_index) { return SYSMPU->WORD[r_index][3] & SYSMPU_WORD_VLD_MASK; } @@ -425,11 +446,11 @@ static inline int is_enabled_region(u32_t r_index) * Note: * The caller must provide a valid region number. */ -static inline int is_in_region(u32_t r_index, u32_t start, u32_t size) +static inline int is_in_region(uint32_t r_index, uint32_t start, uint32_t size) { - u32_t r_addr_start; - u32_t r_addr_end; - u32_t end; + uint32_t r_addr_start; + uint32_t r_addr_end; + uint32_t end; r_addr_start = SYSMPU->WORD[r_index][0]; r_addr_end = SYSMPU->WORD[r_index][1]; @@ -450,25 +471,25 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size) * @brief update configuration of an active memory partition */ void arm_core_mpu_mem_partition_config_update( - struct k_mem_partition *partition, + struct z_arm_mpu_partition *partition, k_mem_partition_attr_t *new_attr) { /* Find the partition. ASSERT if not found. */ - u8_t i; - u8_t reg_index = get_num_regions(); + uint8_t i; + uint8_t reg_index = get_num_regions(); for (i = static_regions_num; i < get_num_regions(); i++) { if (!is_enabled_region(i)) { continue; } - u32_t base = mpu_region_get_base(i); + uint32_t base = mpu_region_get_base(i); if (base != partition->start) { continue; } - u32_t size = mpu_region_get_size(i); + uint32_t size = mpu_region_get_size(i); if (size != partition->size) { continue; @@ -501,9 +522,9 @@ int arm_core_mpu_get_max_available_dyn_regions(void) * Note: * The caller must provide a valid region number. */ -static inline int is_user_accessible_region(u32_t r_index, int write) +static inline int is_user_accessible_region(uint32_t r_index, int write) { - u32_t r_ap = SYSMPU->WORD[r_index][2]; + uint32_t r_ap = SYSMPU->WORD[r_index][2]; if (write) { return (r_ap & MPU_REGION_WRITE) == MPU_REGION_WRITE; @@ -517,12 +538,12 @@ static inline int is_user_accessible_region(u32_t r_index, int write) */ int arm_core_mpu_buffer_validate(void *addr, size_t size, int write) { - u8_t r_index; + uint8_t r_index; /* Iterate through all MPU regions */ for (r_index = 0U; r_index < get_num_regions(); r_index++) { if (!is_enabled_region(r_index) || - !is_in_region(r_index, (u32_t)addr, size)) { + !is_in_region(r_index, (uint32_t)addr, size)) { continue; } @@ -544,12 +565,14 @@ int arm_core_mpu_buffer_validate(void *addr, size_t size, int write) /** * @brief configure fixed (static) MPU regions. */ -void arm_core_mpu_configure_static_mpu_regions(const struct k_mem_partition - *static_regions[], const u8_t regions_num, - const u32_t background_area_start, const u32_t background_area_end) +void arm_core_mpu_configure_static_mpu_regions( + const struct z_arm_mpu_partition static_regions[], + const uint8_t regions_num, const uint32_t background_area_start, + const uint32_t background_area_end) { if (mpu_configure_static_mpu_regions(static_regions, regions_num, - background_area_start, background_area_end) == -EINVAL) { + background_area_start, + background_area_end) == -EINVAL) { __ASSERT(0, "Configuring %u static MPU regions failed\n", regions_num); @@ -559,11 +582,11 @@ void arm_core_mpu_configure_static_mpu_regions(const struct k_mem_partition /** * @brief configure dynamic MPU regions. */ -void arm_core_mpu_configure_dynamic_mpu_regions(const struct k_mem_partition - *dynamic_regions[], u8_t regions_num) +void arm_core_mpu_configure_dynamic_mpu_regions( + const struct z_arm_mpu_partition dynamic_regions[], uint8_t regions_num) { - if (mpu_configure_dynamic_mpu_regions(dynamic_regions, regions_num) - == -EINVAL) { + if (mpu_configure_dynamic_mpu_regions(dynamic_regions, + regions_num) == -EINVAL) { __ASSERT(0, "Configuring %u dynamic MPU regions failed\n", regions_num); @@ -578,11 +601,11 @@ void arm_core_mpu_configure_dynamic_mpu_regions(const struct k_mem_partition * This function provides the default configuration mechanism for the Memory * Protection Unit (MPU). */ -static int nxp_mpu_init(struct device *arg) +static int nxp_mpu_init(const struct device *arg) { ARG_UNUSED(arg); - u32_t r_index; + uint32_t r_index; if (mpu_config.num_regions > get_num_regions()) { /* Attempt to configure more MPU regions than diff --git a/arch/arm/core/aarch32/cortex_m/relay_vector_table.ld b/arch/arm/core/aarch32/cortex_m/relay_vector_table.ld index 4c13ce9411ed13..151bfce9aa7c99 100644 --- a/arch/arm/core/aarch32/cortex_m/relay_vector_table.ld +++ b/arch/arm/core/aarch32/cortex_m/relay_vector_table.ld @@ -1,10 +1,32 @@ /* - * Copyright (c) 2019 Nordic Semiconductor ASA + * Copyright (c) 2019 - 2020 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ +#if defined(CONFIG_CPU_CORTEX_M_HAS_VTOR) +/* + * In an MCU with VTOR, the VTOR.TBLOFF is set to the start address of the + * vector_relay_table, when building with support for interrupt relaying. + * Therefore, vector_relay_table must respect the alignment requirements + * of VTOR.TBLOFF described below. + */ + +/* VTOR bits 0:6 are reserved (RES0). This requires that the base address + * of the vector table is 32-word aligned. + */ +. = ALIGN( 1 << LOG2CEIL(4 * 32) ); + +/* When setting TBLOFF in VTOR we must align the offset to the number of + * exception entries in the vector table. The minimum alignment of 32 words + * is sufficient for the 16 ARM Core exceptions and up to 16 HW interrupts. + * For more than 16 HW interrupts, we adjust the alignment by rounding up + * to the next power of two; this restriction guarantees a functional VTOR + * setting in any Cortex-M implementation (might not be required in every + * Cortex-M processor). + */ +. = ALIGN( 1 << LOG2CEIL(4 * (16 + CONFIG_NUM_IRQS)) ); +#endif + KEEP(*(.vector_relay_table)) KEEP(*(".vector_relay_table.*")) -KEEP(*(.vector_relay_handler)) -KEEP(*(".vector_relay_handler.*")) diff --git a/arch/arm/core/aarch32/cortex_m/reset.S b/arch/arm/core/aarch32/cortex_m/reset.S index d59de2bb816308..c7ed3c2742cd33 100644 --- a/arch/arm/core/aarch32/cortex_m/reset.S +++ b/arch/arm/core/aarch32/cortex_m/reset.S @@ -24,14 +24,20 @@ GDATA(z_interrupt_stacks) #if defined(CONFIG_PLATFORM_SPECIFIC_INIT) GTEXT(z_platform_init) #endif +#if defined(CONFIG_INIT_ARCH_HW_AT_BOOT) +GTEXT(z_arm_init_arch_hw_at_boot) +GDATA(z_main_stack) +#endif + /** * * @brief Reset vector * - * Ran when the system comes out of reset. The processor is in thread mode with - * privileged level. At this point, the main stack pointer (MSP) is already - * pointing to a valid area in SRAM. + * Ran when the system comes out of reset, or when the firmware image is chain- + * loaded by another application (for instance, a bootloader). At minimum, the + * processor must be in thread mode with privileged level. At this point, the + * main stack pointer (MSP) should be already pointing to a valid area in SRAM. * * Locking interrupts prevents anything but NMIs and hard faults from * interrupting the CPU. A default NMI handler is already in place in the @@ -58,10 +64,39 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,z_arm_reset) */ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) +#if defined(CONFIG_INIT_ARCH_HW_AT_BOOT) + /* Reset CONTROL register */ + movs.n r0, #0 + msr CONTROL, r0 + isb +#if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM) + /* Clear SPLIM registers */ + movs.n r0, #0 + msr MSPLIM, r0 + msr PSPLIM, r0 +#endif /* CONFIG_CPU_CORTEX_M_HAS_SPLIM */ + +#endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */ + #if defined(CONFIG_PLATFORM_SPECIFIC_INIT) bl z_platform_init #endif +#if defined(CONFIG_INIT_ARCH_HW_AT_BOOT) +#if defined(CONFIG_CPU_HAS_ARM_MPU) + /* Disable MPU */ + movs.n r0, #0 + ldr r1, =_SCS_MPU_CTRL + str r0, [r1] + dsb +#endif /* CONFIG_CPU_HAS_ARM_MPU */ + ldr r0, =z_main_stack + CONFIG_MAIN_STACK_SIZE + msr msp, r0 + + /* Initialize core architecture registers and system blocks */ + bl z_arm_init_arch_hw_at_boot +#endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */ + /* lock interrupts: will get unlocked when switch to main task */ #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) cpsid i @@ -77,10 +112,18 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) bl z_arm_watchdog_init #endif +/* + * + * Note: in all Cortex-M variants the interrupt stack area is at + * least equal to CONFIG_ISR_STACK_SIZE + MPU_GUARD_ALIGN_AND_SIZE + * (may be larger due to rounding up for stack pointer aligning + * purposes but this is sufficient during initialization). + */ + #ifdef CONFIG_INIT_STACKS ldr r0, =z_interrupt_stacks ldr r1, =0xaa - ldr r2, =CONFIG_ISR_STACK_SIZE + ldr r2, =CONFIG_ISR_STACK_SIZE + MPU_GUARD_ALIGN_AND_SIZE bl memset #endif @@ -89,7 +132,7 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) * gets set to z_interrupt_stacks during initialization. */ ldr r0, =z_interrupt_stacks - ldr r1, =CONFIG_ISR_STACK_SIZE + ldr r1, =CONFIG_ISR_STACK_SIZE + MPU_GUARD_ALIGN_AND_SIZE adds r0, r0, r1 msr PSP, r0 mrs r0, CONTROL diff --git a/arch/arm/core/aarch32/cortex_m/scb.c b/arch/arm/core/aarch32/cortex_m/scb.c index 2e10437fdb03c9..f310d247168b07 100644 --- a/arch/arm/core/aarch32/cortex_m/scb.c +++ b/arch/arm/core/aarch32/cortex_m/scb.c @@ -18,7 +18,7 @@ #include #include #include - +#include /** * * @brief Reset the system @@ -34,3 +34,75 @@ void __weak sys_arch_reboot(int type) NVIC_SystemReset(); } + +#if defined(CONFIG_CPU_HAS_ARM_MPU) +/** + * + * @brief Clear all MPU region configuration + * + * This routine clears all ARM MPU region configuration. + * + * @return N/A + */ +void z_arm_clear_arm_mpu_config(void) +{ + int i; + + int num_regions = + ((MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos); + + for (i = 0; i < num_regions; i++) { + ARM_MPU_ClrRegion(i); + } +} +#endif /* CONFIG_CPU_HAS_ARM_MPU */ + +#if defined(CONFIG_INIT_ARCH_HW_AT_BOOT) +/** + * + * @brief Reset system control blocks and core registers + * + * This routine resets Cortex-M system control block + * components and core registers. + * + * @return N/A + */ +void z_arm_init_arch_hw_at_boot(void) +{ + /* Disable interrupts */ + __disable_irq(); + +#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + __set_FAULTMASK(0); +#endif + + /* Initialize System Control Block components */ + +#if defined(CONFIG_CPU_HAS_ARM_MPU) + /* Clear MPU region configuration */ + z_arm_clear_arm_mpu_config(); +#endif /* CONFIG_CPU_HAS_ARM_MPU */ + + /* Disable NVIC interrupts */ + for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICER); i++) { + NVIC->ICER[i] = 0xFFFFFFFF; + } + /* Clear pending NVIC interrupts */ + for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICPR); i++) { + NVIC->ICPR[i] = 0xFFFFFFFF; + } + +#if defined(CONFIG_CPU_CORTEX_M7) + /* Reset Cache settings */ + SCB_CleanInvalidateDCache(); + SCB_DisableDCache(); + SCB_DisableICache(); +#endif /* CONFIG_CPU_CORTEX_M7 */ + + /* Restore Interrupts */ + __enable_irq(); + + __DSB(); + __ISB(); +} +#endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */ diff --git a/arch/arm/core/aarch32/cortex_m/thread_abort.c b/arch/arm/core/aarch32/cortex_m/thread_abort.c index 2189bfb8b4aa9c..941d3baa4151b8 100644 --- a/arch/arm/core/aarch32/cortex_m/thread_abort.c +++ b/arch/arm/core/aarch32/cortex_m/thread_abort.c @@ -24,29 +24,29 @@ #include #include -extern void z_thread_single_abort(struct k_thread *thread); - void z_impl_k_thread_abort(k_tid_t thread) { - unsigned int key; - - key = irq_lock(); - - __ASSERT(!(thread->base.user_options & K_ESSENTIAL), - "essential thread aborted"); - - z_thread_single_abort(thread); - z_thread_monitor_exit(thread); - if (_current == thread) { - if ((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) == 0) { - (void)z_swap_irqlock(key); - CODE_UNREACHABLE; - } else { + if (arch_is_in_isr()) { + /* ARM is unlike most arches in that this is true + * even for non-peripheral interrupts, even though + * for these types of faults there is not an implicit + * reschedule on the way out. See #21923. + * + * We have to reschedule since the current thread + * should no longer run after we return, so + * Trigger PendSV, in case we are in one of the + * situations where the isr check is true but there + * is not an implicit scheduler invocation. + */ SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; + } else { + z_self_abort(); /* Never returns */ } } + z_thread_single_abort(thread); + /* The abort handler might have altered the ready queue. */ - z_reschedule_irqlock(key); + z_reschedule_unlocked(); } diff --git a/arch/arm/core/aarch32/cortex_m/timing.c b/arch/arm/core/aarch32/cortex_m/timing.c new file mode 100644 index 00000000000000..c9f63b559deedc --- /dev/null +++ b/arch/arm/core/aarch32/cortex_m/timing.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * Copyright (c) 2020 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ARM Cortex-M Timing functions interface based on DWT + * + */ + +#include +#include +#include + +/* Define DWT LSR masks which are currently not defined by the CMSIS V5.1.2. + * (LSR register is defined but not its bitfields). + * Reuse ITM LSR mask as it is the same offset than DWT LSR one. + */ +#if !defined DWT_LSR_Present_Msk +#define DWT_LSR_Present_Msk ITM_LSR_Present_Msk +#endif +#if !defined DWT_LSR_Access_Msk +#define DWT_LSR_Access_Msk ITM_LSR_Access_Msk +#endif + +static void dwt_access(bool ena) +{ +#if defined(CONFIG_CPU_CORTEX_M7) + /* + * In case of Cortex M7, we need to check the optional presence of + * Lock Access Register (LAR) which is indicated in Lock Status + * Register (LSR). When present, a special access token must be written + * to unlock DWT registers. + */ + uint32_t lsr = DWT->LSR; + + if ((lsr & DWT_LSR_Present_Msk) != 0) { + if (ena) { + if ((lsr & DWT_LSR_Access_Msk) != 0) { + /* Access is locked. unlock it */ + DWT->LAR = 0xC5ACCE55; + } + } else { + if ((lsr & DWT_LSR_Access_Msk) == 0) { + /* Acess is unlocked. Lock it */ + DWT->LAR = 0; + } + } + } +#else /* CONFIG_CPU_CORTEX_M7 */ + ARG_UNUSED(ena); +#endif /* CONFIG_CPU_CORTEX_M7 */ +} + +/** + * @brief Initialize and Enable the DWT cycle counter + * + * This routine enables the cycle counter and initializes its value to zero. + * + * @return 0 + */ +static inline int z_arm_dwt_init(const struct device *arg) +{ + /* Enable tracing */ + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + + /* Unlock DWT access if any */ + dwt_access(true); + + /* Clear and enable the cycle counter */ + DWT->CYCCNT = 0; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + + /* Assert that the cycle counter is indeed implemented. */ + __ASSERT(DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk != 0, + "DWT implements no cycle counter. " + "Cannot be used for cycle counting\n"); + + return 0; +} + +/** + * @brief Return the current value of the cycle counter + * + * This routine returns the current value of the DWT Cycle Counter (DWT.CYCCNT) + * + * @return the cycle counter value + */ +static inline uint32_t z_arm_dwt_get_cycles(void) +{ + return DWT->CYCCNT; +} + +/** + * @brief Reset and start the DWT cycle counter + * + * This routine starts the cycle counter and resets its value to zero. + * + * @return 0 + */ +static inline void z_arm_dwt_cycle_count_start(void) +{ + DWT->CYCCNT = 0; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; +} + +/** + * @brief Return the current frequency of the cycle counter + * + * This routine returns the current frequency of the DWT Cycle Counter + * in DWT cycles per second (Hz). + * + * @return the cycle counter frequency value + */ +static inline uint64_t z_arm_dwt_freq_get(void) +{ +#if defined(CONFIG_SOC_FAMILY_NRF) + /* + * DWT frequency is taken directly from the + * System Core clock (CPU) frequency, if the + * CMSIS SystemCoreClock symbols is available. + */ + SystemCoreClockUpdate(); + + return SystemCoreClock; +#elif defined(CONFIG_CORTEX_M_SYSTICK) + /* SysTick and DWT both run at CPU frequency, + * reflected in the system timer HW cycles/sec. + */ + return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; +#else + static uint64_t dwt_frequency; + + if (!dwt_frequency) { + + z_arm_dwt_init(NULL); + + uint32_t cyc_start = k_cycle_get_32(); + uint64_t dwt_start = z_arm_dwt_get_cycles(); + + k_busy_wait(10 * USEC_PER_MSEC); + + uint32_t cyc_end = k_cycle_get_32(); + uint64_t dwt_end = z_arm_dwt_get_cycles(); + + uint64_t cyc_freq = sys_clock_hw_cycles_per_sec(); + + /* + * cycles are in 32-bit, and delta must be + * calculated in 32-bit percision. Or it would + * wrapping around in 64-bit. + */ + uint64_t dcyc = (uint32_t)cyc_end - (uint32_t)cyc_start; + + uint64_t dtsc = dwt_end - dwt_start; + + dwt_frequency = (cyc_freq * dtsc) / dcyc; + + } + return dwt_frequency; +#endif /* CONFIG_SOC_FAMILY_NRF */ +} + +void arch_timing_init(void) +{ + z_arm_dwt_init(NULL); +} + +void arch_timing_start(void) +{ + z_arm_dwt_cycle_count_start(); +} + +void arch_timing_stop(void) +{ + DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; +} + +timing_t arch_timing_counter_get(void) +{ + return (timing_t)z_arm_dwt_get_cycles(); +} + +uint64_t arch_timing_cycles_get(volatile timing_t *const start, + volatile timing_t *const end) +{ + return (*end - *start); +} + +uint64_t arch_timing_freq_get(void) +{ + return z_arm_dwt_freq_get(); +} + +uint64_t arch_timing_cycles_to_ns(uint64_t cycles) +{ + return (cycles) * (NSEC_PER_USEC) / arch_timing_freq_get_mhz(); +} + +uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) +{ + return arch_timing_cycles_to_ns(cycles) / count; +} + +uint32_t arch_timing_freq_get_mhz(void) +{ + return (uint32_t)(arch_timing_freq_get() / 1000000); +} diff --git a/arch/arm/core/aarch32/cortex_m/tz/arm_core_tz.c b/arch/arm/core/aarch32/cortex_m/tz/arm_core_tz.c index 125d9177779ac7..ddebeff4590e3d 100644 --- a/arch/arm/core/aarch32/cortex_m/tz/arm_core_tz.c +++ b/arch/arm/core/aarch32/cortex_m/tz/arm_core_tz.c @@ -8,24 +8,24 @@ #include #include -static void configure_nonsecure_vtor_offset(u32_t vtor_ns) +static void configure_nonsecure_vtor_offset(uint32_t vtor_ns) { SCB_NS->VTOR = vtor_ns; } -static void configure_nonsecure_msp(u32_t msp_ns) +static void configure_nonsecure_msp(uint32_t msp_ns) { __TZ_set_MSP_NS(msp_ns); } -static void configure_nonsecure_psp(u32_t psp_ns) +static void configure_nonsecure_psp(uint32_t psp_ns) { __TZ_set_PSP_NS(psp_ns); } -static void configure_nonsecure_control(u32_t spsel_ns, u32_t npriv_ns) +static void configure_nonsecure_control(uint32_t spsel_ns, uint32_t npriv_ns) { - u32_t control_ns = __TZ_get_CONTROL_NS(); + uint32_t control_ns = __TZ_get_CONTROL_NS(); /* Only nPRIV and SPSEL bits are banked between security states. */ control_ns &= ~(CONTROL_SPSEL_Msk | CONTROL_nPRIV_Msk); @@ -46,12 +46,12 @@ static void configure_nonsecure_control(u32_t spsel_ns, u32_t npriv_ns) * Stack Pointer Limit registers. */ -void tz_nonsecure_msplim_set(u32_t val) +void tz_nonsecure_msplim_set(uint32_t val) { __TZ_set_MSPLIM_NS(val); } -void tz_nonsecure_psplim_set(u32_t val) +void tz_nonsecure_psplim_set(uint32_t val) { __TZ_set_PSPLIM_NS(val); } @@ -71,7 +71,7 @@ void tz_nonsecure_state_setup(const tz_nonsecure_setup_conf_t *p_ns_conf) void tz_nbanked_exception_target_state_set(int secure_state) { - u32_t aircr_payload = SCB->AIRCR & (~(SCB_AIRCR_VECTKEY_Msk)); + uint32_t aircr_payload = SCB->AIRCR & (~(SCB_AIRCR_VECTKEY_Msk)); if (secure_state) { aircr_payload &= ~(SCB_AIRCR_BFHFNMINS_Msk); } else { @@ -84,7 +84,7 @@ void tz_nbanked_exception_target_state_set(int secure_state) void tz_nonsecure_exception_prio_config(int secure_boost) { - u32_t aircr_payload = SCB->AIRCR & (~(SCB_AIRCR_VECTKEY_Msk)); + uint32_t aircr_payload = SCB->AIRCR & (~(SCB_AIRCR_VECTKEY_Msk)); if (secure_boost) { aircr_payload |= SCB_AIRCR_PRIS_Msk; } else { @@ -97,7 +97,7 @@ void tz_nonsecure_exception_prio_config(int secure_boost) void tz_nonsecure_system_reset_req_block(int block) { - u32_t aircr_payload = SCB->AIRCR & (~(SCB_AIRCR_VECTKEY_Msk)); + uint32_t aircr_payload = SCB->AIRCR & (~(SCB_AIRCR_VECTKEY_Msk)); if (block) { aircr_payload |= SCB_AIRCR_SYSRESETREQS_Msk; } else { @@ -130,7 +130,7 @@ void tz_sau_configure(int enable, int allns) } } -u32_t tz_sau_number_of_regions_get(void) +uint32_t tz_sau_number_of_regions_get(void) { return SAU->TYPE & SAU_TYPE_SREGION_Msk; } @@ -139,7 +139,7 @@ u32_t tz_sau_number_of_regions_get(void) #if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) int tz_sau_region_configure_enable(tz_sau_conf_t *p_sau_conf) { - u32_t regions = tz_sau_number_of_regions_get(); + uint32_t regions = tz_sau_number_of_regions_get(); if ((p_sau_conf->region_num == 0) || (p_sau_conf->region_num > (regions - 1))) { diff --git a/arch/arm/core/aarch32/cortex_m/tz/secure_entry_functions.ld b/arch/arm/core/aarch32/cortex_m/tz/secure_entry_functions.ld index a0a2c1dbaccb7d..facd7d07cbc6e7 100644 --- a/arch/arm/core/aarch32/cortex_m/tz/secure_entry_functions.ld +++ b/arch/arm/core/aarch32/cortex_m/tz/secure_entry_functions.ld @@ -5,23 +5,27 @@ */ /* nRF-specific defines. */ -#ifdef CONFIG_CPU_HAS_NRF_IDAU +#if defined(CONFIG_CPU_HAS_NRF_IDAU) && CONFIG_ARM_NSC_REGION_BASE_ADDRESS == 0 /* This SOC needs the NSC region to be at the end of an SPU region. */ + #define __NSC_ALIGN (ALIGN(CONFIG_NRF_SPU_FLASH_REGION_SIZE) \ + - MAX(32, (1 << LOG2CEIL(__sg_size)))) #define NSC_ALIGN \ - . = ALIGN(CONFIG_NRF_SPU_FLASH_REGION_SIZE) \ - - (1 << LOG2CEIL(__sg_size)) + . = (__NSC_ALIGN + ((ABSOLUTE(.) > __NSC_ALIGN) \ + ? CONFIG_NRF_SPU_FLASH_REGION_SIZE : 0)) #define NSC_ALIGN_END . = ALIGN(CONFIG_NRF_SPU_FLASH_REGION_SIZE) -#endif /* CONFIG_CPU_HAS_NRF_IDAU */ - +#endif /* CONFIG_CPU_HAS_NRF_IDAU && CONFIG_ARM_NSC_REGION_BASE_ADDRESS != 0 */ +#ifndef NSC_ALIGN #if CONFIG_ARM_NSC_REGION_BASE_ADDRESS != 0 #define NSC_ALIGN . = ABSOLUTE(CONFIG_ARM_NSC_REGION_BASE_ADDRESS) -#elif !defined(NSC_ALIGN) - #define NSC_ALIGN . = ALIGN(4) +#else + /* The ARM SAU requires regions to be 32-byte-aligned. */ + #define NSC_ALIGN . = ALIGN(32) #endif /* CONFIG_ARM_NSC_REGION_BASE_ADDRESS */ +#endif /* !NSC_ALIGN */ #ifndef NSC_ALIGN_END - #define NSC_ALIGN_END . = ALIGN(4) + #define NSC_ALIGN_END . = ALIGN(32) #endif SECTION_PROLOGUE(.gnu.sgstubs,,) diff --git a/arch/arm/core/aarch32/cortex_m/vector_table.h b/arch/arm/core/aarch32/cortex_m/vector_table.h index 1e85938e29fb3e..3fbe6593b72bb7 100644 --- a/arch/arm/core/aarch32/cortex_m/vector_table.h +++ b/arch/arm/core/aarch32/cortex_m/vector_table.h @@ -28,7 +28,7 @@ #include GTEXT(__start) -GTEXT(_vector_table) +GDATA(_vector_table) GTEXT(z_arm_reset) GTEXT(z_arm_nmi) diff --git a/arch/arm/core/aarch32/cortex_m/vt_pointer_section.ld b/arch/arm/core/aarch32/cortex_m/vt_pointer_section.ld index a00f7e8d4bcbec..c3d06847b6e6d9 100644 --- a/arch/arm/core/aarch32/cortex_m/vt_pointer_section.ld +++ b/arch/arm/core/aarch32/cortex_m/vt_pointer_section.ld @@ -5,4 +5,4 @@ { *(.vt_pointer_section) *(".vt_pointer_section.*") - } + } GROUP_LINK_IN(RAMABLE_REGION) diff --git a/arch/arm/core/aarch32/fatal.c b/arch/arm/core/aarch32/fatal.c index 849a4ee69c658f..71c92850a6a459 100644 --- a/arch/arm/core/aarch32/fatal.c +++ b/arch/arm/core/aarch32/fatal.c @@ -14,7 +14,7 @@ #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); static void esf_dump(const z_arch_esf_t *esf) { @@ -27,13 +27,25 @@ static void esf_dump(const z_arch_esf_t *esf) for (int i = 0; i < 16; i += 4) { LOG_ERR("s[%2d]: 0x%08x s[%2d]: 0x%08x" " s[%2d]: 0x%08x s[%2d]: 0x%08x", - i, (u32_t)esf->s[i], - i + 1, (u32_t)esf->s[i + 1], - i + 2, (u32_t)esf->s[i + 2], - i + 3, (u32_t)esf->s[i + 3]); + i, (uint32_t)esf->s[i], + i + 1, (uint32_t)esf->s[i + 1], + i + 2, (uint32_t)esf->s[i + 2], + i + 3, (uint32_t)esf->s[i + 3]); } LOG_ERR("fpscr: 0x%08x", esf->fpscr); #endif +#if defined(CONFIG_EXTRA_EXCEPTION_INFO) + const struct _callee_saved *callee = esf->extra_info.callee; + + if (callee != NULL) { + LOG_ERR("r4/v1: 0x%08x r5/v2: 0x%08x r6/v3: 0x%08x", + callee->v1, callee->v2, callee->v3); + LOG_ERR("r7/v4: 0x%08x r8/v5: 0x%08x r9/v6: 0x%08x", + callee->v4, callee->v5, callee->v6); + LOG_ERR("r10/v7: 0x%08x r11/v8: 0x%08x psp: 0x%08x", + callee->v7, callee->v8, callee->psp); + } +#endif /* CONFIG_EXTRA_EXCEPTION_INFO */ LOG_ERR("Faulting instruction address (r15/pc): 0x%08x", esf->basic.pc); } @@ -83,12 +95,25 @@ void z_do_kernel_oops(const z_arch_esf_t *esf) } #endif /* CONFIG_USERSPACE */ + +#if !defined(CONFIG_EXTRA_EXCEPTION_INFO) z_arm_fatal_error(reason, esf); +#else + /* extra exception info is not collected for kernel oops + * path today so we make a copy of the ESF and zero out + * that information + */ + z_arch_esf_t esf_copy; + + memcpy(&esf_copy, esf, offsetof(z_arch_esf_t, extra_info)); + esf_copy.extra_info = (struct __extra_esf_info) { 0 }; + z_arm_fatal_error(reason, &esf_copy); +#endif /* CONFIG_EXTRA_EXCEPTION_INFO */ } FUNC_NORETURN void arch_syscall_oops(void *ssf_ptr) { - u32_t *ssf_contents = ssf_ptr; + uint32_t *ssf_contents = ssf_ptr; z_arch_esf_t oops_esf = { 0 }; /* TODO: Copy the rest of the register set out of ssf_ptr */ diff --git a/arch/arm/core/aarch32/irq_manage.c b/arch/arm/core/aarch32/irq_manage.c index 7fdcfec332cd74..1576c072088af0 100644 --- a/arch/arm/core/aarch32/irq_manage.c +++ b/arch/arm/core/aarch32/irq_manage.c @@ -27,6 +27,7 @@ #include #include #include +#include extern void z_arm_reserved(void); @@ -61,7 +62,7 @@ int arch_irq_is_enabled(unsigned int irq) * * @return N/A */ -void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags) +void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { /* The kernel may reserve some of the highest priority levels. * So we offset the requested priority level with the number @@ -135,7 +136,7 @@ int arch_irq_is_enabled(unsigned int irq) * * @return N/A */ -void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags) +void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { arm_gic_irq_set_priority(irq, prio, flags); } @@ -154,14 +155,14 @@ void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); * * @return N/A */ -void z_irq_spurious(void *unused) +void z_irq_spurious(const void *unused) { ARG_UNUSED(unused); z_arm_fatal_error(K_ERR_SPURIOUS_IRQ, NULL); } -#ifdef CONFIG_SYS_POWER_MANAGEMENT +#ifdef CONFIG_PM void _arch_isr_direct_pm(void) { #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) \ @@ -181,10 +182,10 @@ void _arch_isr_direct_pm(void) #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ if (_kernel.idle) { - s32_t idle_val = _kernel.idle; + int32_t idle_val = _kernel.idle; _kernel.idle = 0; - z_sys_power_save_idle_exit(idle_val); + z_pm_save_idle_exit(idle_val); } #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) \ @@ -211,25 +212,31 @@ void _arch_isr_direct_pm(void) * to NVIC.ITNS register is write-ignored(WI), as the ITNS register is not * banked between security states and, therefore, has no Non-Secure instance. * - * It shall assert if the operation is not performed successfully. + * It shall return the resulting target state of the given IRQ, indicating + * whether the operation has been performed successfully. * * @param irq IRQ line - * @param secure_state 1 if target state is Secure, 0 otherwise. + * @param irq_target_state the desired IRQ target state * - * @return N/A + * @return The resulting target state of the given IRQ */ -void irq_target_state_set(unsigned int irq, int secure_state) +irq_target_state_t irq_target_state_set(unsigned int irq, + irq_target_state_t irq_target_state) { - if (secure_state) { + uint32_t result; + + if (irq_target_state == IRQ_TARGET_STATE_SECURE) { /* Set target to Secure */ - if (NVIC_ClearTargetState(irq) != 0) { - __ASSERT(0, "NVIC SetTargetState error"); - } + result = NVIC_ClearTargetState(irq); + } else { + /* Set target to Non-Secure */ + result = NVIC_SetTargetState(irq); + } + + if (result) { + return IRQ_TARGET_STATE_NON_SECURE; } else { - /* Set target state to Non-Secure */ - if (NVIC_SetTargetState(irq) != 1) { - __ASSERT(0, "NVIC SetTargetState error"); - } + return IRQ_TARGET_STATE_SECURE; } } @@ -253,12 +260,44 @@ int irq_target_state_is_secure(unsigned int irq) return NVIC_GetTargetState(irq) == 0; } +/** + * + * @brief Disable and set all interrupt lines to target Non-Secure state. + * + * The function is used to set all HW NVIC interrupt lines to target the + * Non-Secure state. The function shall only be called fron Secure state. + * + * Notes: + * - All NVIC interrupts are disabled before being routed to Non-Secure. + * - Bits corresponding to un-implemented interrupts are RES0, so writes + * will be ignored. + * + * @return N/A +*/ +void irq_target_state_set_all_non_secure(void) +{ + int i; + + /* Disable (Clear) all NVIC interrupt lines. */ + for (i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) { + NVIC->ICER[i] = 0xFFFFFFFF; + } + + __DSB(); + __ISB(); + + /* Set all NVIC interrupt lines to target Non-Secure */ + for (i = 0; i < sizeof(NVIC->ITNS) / sizeof(NVIC->ITNS[0]); i++) { + NVIC->ITNS[i] = 0xFFFFFFFF; + } +} + #endif /* CONFIG_ARM_SECURE_FIRMWARE */ #ifdef CONFIG_DYNAMIC_INTERRUPTS int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *parameter), void *parameter, - u32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { z_isr_install(irq, routine, parameter); z_arm_irq_priority_set(irq, priority, flags); @@ -268,7 +307,7 @@ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, #ifdef CONFIG_DYNAMIC_DIRECT_INTERRUPTS static inline void z_arm_irq_dynamic_direct_isr_dispatch(void) { - u32_t irq = __get_IPSR() - 16; + uint32_t irq = __get_IPSR() - 16; if (irq < IRQ_TABLE_SIZE) { struct _isr_table_entry *isr_entry = &_sw_isr_table[irq]; diff --git a/arch/arm/core/aarch32/irq_offload.c b/arch/arm/core/aarch32/irq_offload.c index df6011623ee950..445a1154b43b01 100644 --- a/arch/arm/core/aarch32/irq_offload.c +++ b/arch/arm/core/aarch32/irq_offload.c @@ -12,7 +12,7 @@ #include volatile irq_offload_routine_t offload_routine; -static void *offload_param; +static const void *offload_param; /* Called by z_arm_svc */ void z_irq_do_offload(void) @@ -20,7 +20,7 @@ void z_irq_do_offload(void) offload_routine(offload_param); } -void arch_irq_offload(irq_offload_routine_t routine, void *parameter) +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && defined(CONFIG_ASSERT) /* ARMv6-M/ARMv8-M Baseline HardFault if you make a SVC call with diff --git a/arch/arm/core/aarch32/irq_relay.S b/arch/arm/core/aarch32/irq_relay.S index 745a788bfba237..8111b4d484057f 100644 --- a/arch/arm/core/aarch32/irq_relay.S +++ b/arch/arm/core/aarch32/irq_relay.S @@ -26,12 +26,10 @@ _ASM_FILE_PROLOGUE -#if defined(CONFIG_SW_VECTOR_RELAY) - GDATA(_vector_table_pointer) GDATA(z_main_stack) -SECTION_FUNC(vector_relay_handler, __vector_relay_handler) +SECTION_FUNC(TEXT, __vector_relay_handler) mrs r0, ipsr; lsls r0, r0, $0x02; @@ -72,37 +70,8 @@ SECTION_FUNC(vector_relay_table, __vector_relay_table) .word __vector_relay_handler /* End of system exception */ + .rept CONFIG_NUM_IRQS .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler - .word __vector_relay_handler + .endr -#endif +GDATA(__vector_relay_table) diff --git a/arch/arm/core/aarch32/isr_wrapper.S b/arch/arm/core/aarch32/isr_wrapper.S index bcafac75ec6e11..9dfc8a19af3689 100644 --- a/arch/arm/core/aarch32/isr_wrapper.S +++ b/arch/arm/core/aarch32/isr_wrapper.S @@ -80,21 +80,17 @@ SECTION_FUNC(TEXT, _isr_wrapper) str r0, [r2, #_kernel_offset_to_nested] #endif /* CONFIG_CPU_CORTEX_M */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - bl read_timer_start_of_isr -#endif - #ifdef CONFIG_TRACING_ISR bl sys_trace_isr_enter #endif -#ifdef CONFIG_SYS_POWER_MANAGEMENT +#ifdef CONFIG_PM /* * All interrupts are disabled when handling idle wakeup. For tickless * idle, this ensures that the calculation and programming of the * device for the next timer deadline is not interrupted. For * non-tickless idle, this ensures that the clearing of the kernel idle - * state is not interrupted. In each case, z_sys_power_save_idle_exit + * state is not interrupted. In each case, z_pm_save_idle_exit * is called with interrupts disabled. */ @@ -119,7 +115,7 @@ SECTION_FUNC(TEXT, _isr_wrapper) movs.n r1, #0 /* clear kernel idle state */ str r1, [r2, #_kernel_offset_to_idle] - bl z_sys_power_save_idle_exit + bl z_pm_save_idle_exit _idle_state_cleared: #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) @@ -127,13 +123,13 @@ _idle_state_cleared: movne r1, #0 /* clear kernel idle state */ strne r1, [r2, #_kernel_offset_to_idle] - blne z_sys_power_save_idle_exit + blne z_pm_save_idle_exit #elif defined(CONFIG_ARMV7_R) beq _idle_state_cleared movs r1, #0 /* clear kernel idle state */ str r1, [r2, #_kernel_offset_to_idle] - bl z_sys_power_save_idle_exit + bl z_pm_save_idle_exit _idle_state_cleared: #else #error Unknown ARM architecture @@ -143,7 +139,7 @@ _idle_state_cleared: cpsie i /* re-enable interrupts (PRIMASK = 0) */ #endif -#endif /* CONFIG_SYS_POWER_MANAGEMENT */ +#endif /* CONFIG_PM */ #if defined(CONFIG_CPU_CORTEX_M) mrs r0, IPSR /* get exception number */ @@ -187,11 +183,6 @@ _idle_state_cleared: * in thumb mode */ ldm r1!,{r0,r3} /* arg in r0, ISR in r3 */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - push {r0, r3} /* Save r0 and r3 into stack */ - bl read_timer_end_of_isr - pop {r0, r3} /* Restore r0 and r3 regs */ -#endif /* CONFIG_EXECUTION_BENCHMARKING */ blx r3 /* call ISR */ #if defined(CONFIG_CPU_CORTEX_R) diff --git a/arch/arm/core/aarch32/prep_c.c b/arch/arm/core/aarch32/prep_c.c index a34cc2bc82d17e..924764e8bb76cc 100644 --- a/arch/arm/core/aarch32/prep_c.c +++ b/arch/arm/core/aarch32/prep_c.c @@ -37,6 +37,11 @@ #include +#if defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) +Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used)) +void *_vector_table_pointer; +#endif + #ifdef CONFIG_CPU_CORTEX_M_HAS_VTOR #ifdef CONFIG_XIP @@ -53,10 +58,6 @@ static inline void relocate_vector_table(void) #else -#if defined(CONFIG_SW_VECTOR_RELAY) -Z_GENERIC_SECTION(.vt_pointer_section) void *_vector_table_pointer; -#endif - #define VECTOR_ADDRESS 0 void __weak relocate_vector_table(void) @@ -65,7 +66,7 @@ void __weak relocate_vector_table(void) !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) size_t vector_size = (size_t)_vector_end - (size_t)_vector_start; (void)memcpy(VECTOR_ADDRESS, _vector_start, vector_size); -#elif defined(CONFIG_SW_VECTOR_RELAY) +#elif defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) _vector_table_pointer = _vector_start; #endif } diff --git a/arch/arm/core/aarch32/swap.c b/arch/arm/core/aarch32/swap.c index 3811d819108a5d..f2fb9fe24ae875 100644 --- a/arch/arm/core/aarch32/swap.c +++ b/arch/arm/core/aarch32/swap.c @@ -7,9 +7,6 @@ #include #include -#ifdef CONFIG_EXECUTION_BENCHMARKING -extern void read_timer_start_of_swap(void); -#endif extern const int _k_neg_eagain; /* The 'key' actually represents the BASEPRI register @@ -35,10 +32,6 @@ extern const int _k_neg_eagain; */ int arch_swap(unsigned int key) { -#ifdef CONFIG_EXECUTION_BENCHMARKING - read_timer_start_of_swap(); -#endif - /* store off key and return value */ _current->arch.basepri = key; _current->arch.swap_return_value = _k_neg_eagain; diff --git a/arch/arm/core/aarch32/swap_helper.S b/arch/arm/core/aarch32/swap_helper.S index c9ffe96b4983bb..7a7172cb149d8d 100644 --- a/arch/arm/core/aarch32/swap_helper.S +++ b/arch/arm/core/aarch32/swap_helper.S @@ -30,6 +30,10 @@ GDATA(_k_neg_eagain) GDATA(_kernel) +#if defined(CONFIG_THREAD_LOCAL_STORAGE) && defined(CONFIG_CPU_CORTEX_M) +GDATA(z_arm_tls_ptr) +#endif + /** * * @brief PendSV exception handler, handling context switches @@ -51,10 +55,10 @@ GDATA(_kernel) SECTION_FUNC(TEXT, z_arm_pendsv) -#ifdef CONFIG_TRACING +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING /* Register the context switch */ push {r0, lr} - bl sys_trace_thread_switched_out + bl z_thread_mark_switched_out #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r0, r1} mov lr, r1 @@ -165,13 +169,38 @@ out_fp_endif: /* _SCS_ICSR is still in v4 and _SCS_ICSR_UNPENDSV in v3 */ #if defined(CONFIG_CPU_CORTEX_M) str v3, [v4, #0] +#endif + +#if defined(CONFIG_THREAD_LOCAL_STORAGE) + /* Grab the TLS pointer */ + ldr r4, =_thread_offset_to_tls + adds r4, r2, r4 + ldr r0, [r4] + +#if defined(CONFIG_CPU_CORTEX_R) + /* Store TLS pointer in the "Process ID" register. + * This register is used as a base pointer to all + * thread variables with offsets added by toolchain. + */ + mcr 15, 0, r0, cr13, cr0, 3 +#endif + +#if defined(CONFIG_CPU_CORTEX_M) + /* For Cortex-M, store TLS pointer in a global variable, + * as it lacks the process ID or thread ID register + * to be used by toolchain to access thread data. + */ + ldr r4, =z_arm_tls_ptr + str r0, [r4] +#endif + #endif /* Restore previous interrupt disable state (irq_lock key) * (We clear the arch.basepri field after restoring state) */ -#if (defined(CONFIG_CPU_CORTEX_M0PLUS) || defined(CONFIG_CPU_CORTEX_M0)) && \ - _thread_offset_to_basepri > 124 +#if (defined(CONFIG_CPU_CORTEX_M0PLUS) || defined(CONFIG_CPU_CORTEX_M0) || \ + defined(CONFIG_CPU_CORTEX_M1)) && _thread_offset_to_basepri > 124 /* Doing it this way since the offset to thread->arch.basepri can in * some configurations be larger than the maximum of 124 for ldr/str * immediate offsets. @@ -337,22 +366,10 @@ _thread_irq_disabled: pop {r2, lr} #endif /* CONFIG_BUILTIN_STACK_GUARD */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - push {r0, lr} - bl read_timer_end_of_swap -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) - pop {r0, r1} - mov lr,r1 -#else - pop {r0, lr} -#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ - -#endif /* CONFIG_EXECUTION_BENCHMARKING */ - -#ifdef CONFIG_TRACING +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING /* Register the context switch */ push {r0, lr} - bl sys_trace_thread_switched_in + bl z_thread_mark_switched_in #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) pop {r0, r1} mov lr, r1 diff --git a/arch/arm/core/aarch32/thread.c b/arch/arm/core/aarch32/thread.c index bd72b44f61ae39..d4be2f2ca79021 100644 --- a/arch/arm/core/aarch32/thread.c +++ b/arch/arm/core/aarch32/thread.c @@ -16,6 +16,17 @@ #include #include +#if (MPU_GUARD_ALIGN_AND_SIZE_FLOAT > MPU_GUARD_ALIGN_AND_SIZE) +#define FP_GUARD_EXTRA_SIZE (MPU_GUARD_ALIGN_AND_SIZE_FLOAT - \ + MPU_GUARD_ALIGN_AND_SIZE) +#else +#define FP_GUARD_EXTRA_SIZE 0 +#endif + +#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_CPU_CORTEX_M) +extern K_THREAD_STACK_DEFINE(z_main_stack, CONFIG_MAIN_STACK_SIZE); +#endif + /* An initial context, to be "restored" by z_arm_pendsv(), is put at the other * end of the stack, and thus reusable by the stack when not needed anymore. * @@ -29,112 +40,65 @@ * of the ESF. */ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - size_t stackSize, k_thread_entry_t pEntry, - void *parameter1, void *parameter2, void *parameter3, - int priority, unsigned int options) + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) { - char *pStackMem = Z_THREAD_STACK_BUFFER(stack); - char *stackEnd; - /* Offset between the top of stack and the high end of stack area. */ - u32_t top_of_stack_offset = 0U; - -#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT) \ - && defined(CONFIG_USERSPACE) - /* This is required to work-around the case where the thread - * is created without using K_THREAD_STACK_SIZEOF() macro in - * k_thread_create(). If K_THREAD_STACK_SIZEOF() is used, the - * Guard size has already been take out of stackSize. - */ - stackSize -= MPU_GUARD_ALIGN_AND_SIZE; -#endif + struct __basic_sf *iframe; +#ifdef CONFIG_MPU_STACK_GUARD #if defined(CONFIG_USERSPACE) - /* Truncate the stack size to align with the MPU region granularity. - * This is done proactively to account for the case when the thread - * switches to user mode (thus, its stack area will need to be MPU- - * programmed to be assigned unprivileged RW access permission). - */ - stackSize &= ~(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE - 1); - -#ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA - /* Reserve space on top of stack for local data. */ - u32_t p_local_data = Z_STACK_PTR_ALIGN(pStackMem + stackSize - - sizeof(*thread->userspace_local_data)); - - thread->userspace_local_data = - (struct _thread_userspace_local_data *)(p_local_data); - - /* Top of actual stack must be moved below the user local data. */ - top_of_stack_offset = (u32_t) - (pStackMem + stackSize - ((char *)p_local_data)); - -#endif /* CONFIG_THREAD_USERSPACE_LOCAL_DATA */ + if (z_stack_is_user_capable(stack)) { + /* Guard area is carved-out of the buffer instead of reserved + * for stacks that can host user threads + */ + thread->stack_info.start += MPU_GUARD_ALIGN_AND_SIZE; + thread->stack_info.size -= MPU_GUARD_ALIGN_AND_SIZE; + } #endif /* CONFIG_USERSPACE */ - -#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) \ - && defined(CONFIG_MPU_STACK_GUARD) - /* For a thread which intends to use the FP services, it is required to - * allocate a wider MPU guard region, to always successfully detect an - * overflow of the stack. - * - * Note that the wider MPU regions requires re-adjusting the stack_info - * .start and .size. - * - */ - if ((options & K_FP_REGS) != 0) { - pStackMem += MPU_GUARD_ALIGN_AND_SIZE_FLOAT - - MPU_GUARD_ALIGN_AND_SIZE; - stackSize -= MPU_GUARD_ALIGN_AND_SIZE_FLOAT - - MPU_GUARD_ALIGN_AND_SIZE; +#if FP_GUARD_EXTRA_SIZE > 0 + if ((thread->base.user_options & K_FP_REGS) != 0) { + /* Larger guard needed due to lazy stacking of FP regs may + * overshoot the guard area without writing anything. We + * carve it out of the stack buffer as-needed instead of + * unconditionally reserving it. + */ + thread->stack_info.start += FP_GUARD_EXTRA_SIZE; + thread->stack_info.size -= FP_GUARD_EXTRA_SIZE; } -#endif - stackEnd = pStackMem + stackSize; - - struct __esf *pInitCtx; - - z_new_thread_init(thread, pStackMem, stackSize); - - /* Carve the thread entry struct from the "base" of the stack - * - * The initial carved stack frame only needs to contain the basic - * stack frame (state context), because no FP operations have been - * performed yet for this thread. - */ - pInitCtx = (struct __esf *)(Z_STACK_PTR_ALIGN(stackEnd - - (char *)top_of_stack_offset - sizeof(struct __basic_sf))); +#endif /* FP_GUARD_EXTRA_SIZE */ +#endif /* CONFIG_MPU_STACK_GUARD */ + iframe = Z_STACK_PTR_TO_FRAME(struct __basic_sf, stack_ptr); #if defined(CONFIG_USERSPACE) - if ((options & K_USER) != 0) { - pInitCtx->basic.pc = (u32_t)arch_user_mode_enter; + if ((thread->base.user_options & K_USER) != 0) { + iframe->pc = (uint32_t)arch_user_mode_enter; } else { - pInitCtx->basic.pc = (u32_t)z_thread_entry; + iframe->pc = (uint32_t)z_thread_entry; } #else - pInitCtx->basic.pc = (u32_t)z_thread_entry; + iframe->pc = (uint32_t)z_thread_entry; #endif #if defined(CONFIG_CPU_CORTEX_M) /* force ARM mode by clearing LSB of address */ - pInitCtx->basic.pc &= 0xfffffffe; + iframe->pc &= 0xfffffffe; #endif - - pInitCtx->basic.a1 = (u32_t)pEntry; - pInitCtx->basic.a2 = (u32_t)parameter1; - pInitCtx->basic.a3 = (u32_t)parameter2; - pInitCtx->basic.a4 = (u32_t)parameter3; + iframe->a1 = (uint32_t)entry; + iframe->a2 = (uint32_t)p1; + iframe->a3 = (uint32_t)p2; + iframe->a4 = (uint32_t)p3; #if defined(CONFIG_CPU_CORTEX_M) - pInitCtx->basic.xpsr = + iframe->xpsr = 0x01000000UL; /* clear all, thumb bit is 1, even if RO */ #else - pInitCtx->basic.xpsr = A_BIT | MODE_SYS; + iframe->xpsr = A_BIT | MODE_SYS; #if defined(CONFIG_COMPILER_ISA_THUMB2) - pInitCtx->basic.xpsr |= T_BIT; + iframe->xpsr |= T_BIT; #endif /* CONFIG_COMPILER_ISA_THUMB2 */ #endif /* CONFIG_CPU_CORTEX_M */ - thread->callee_saved.psp = (u32_t)pInitCtx; - + thread->callee_saved.psp = (uint32_t)iframe; thread->arch.basepri = 0; #if defined(CONFIG_USERSPACE) || defined(CONFIG_FPU_SHARING) @@ -143,9 +107,6 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, thread->arch.priv_stack_start = 0; #endif #endif - - /* swap_return_value can contain garbage */ - /* * initial values in all other registers/thread entries are * irrelevant. @@ -153,15 +114,30 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, } #ifdef CONFIG_USERSPACE - FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, void *p1, void *p2, void *p3) { /* Set up privileged stack before entering user mode */ _current->arch.priv_stack_start = - (u32_t)z_priv_stack_find(_current->stack_obj); + (uint32_t)z_priv_stack_find(_current->stack_obj); #if defined(CONFIG_MPU_STACK_GUARD) +#if defined(CONFIG_THREAD_STACK_INFO) + /* We're dropping to user mode which means the guard area is no + * longer used here, it instead is moved to the privilege stack + * to catch stack overflows there. Un-do the calculations done + * which accounted for memory borrowed from the thread stack. + */ +#if FP_GUARD_EXTRA_SIZE > 0 + if ((_current->base.user_options & K_FP_REGS) != 0) { + _current->stack_info.start -= FP_GUARD_EXTRA_SIZE; + _current->stack_info.size += FP_GUARD_EXTRA_SIZE; + } +#endif /* FP_GUARD_EXTRA_SIZE */ + _current->stack_info.start -= MPU_GUARD_ALIGN_AND_SIZE; + _current->stack_info.size += MPU_GUARD_ALIGN_AND_SIZE; +#endif /* CONFIG_THREAD_STACK_INFO */ + /* Stack guard area reserved at the bottom of the thread's * privileged stack. Adjust the available (writable) stack * buffer area accordingly. @@ -176,8 +152,9 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, #endif /* CONFIG_MPU_STACK_GUARD */ z_arm_userspace_enter(user_entry, p1, p2, p3, - (u32_t)_current->stack_info.start, - _current->stack_info.size); + (uint32_t)_current->stack_info.start, + _current->stack_info.size - + _current->stack_info.delta); CODE_UNREACHABLE; } @@ -211,17 +188,17 @@ void configure_builtin_stack_guard(struct k_thread *thread) * thread privileged stack being allocated in higher memory area * than the default thread stack (ensured by design). */ - u32_t guard_start = + uint32_t guard_start = ((thread->arch.priv_stack_start) && (__get_PSP() >= thread->arch.priv_stack_start)) ? - (u32_t)thread->arch.priv_stack_start : - (u32_t)thread->stack_obj; + (uint32_t)thread->arch.priv_stack_start : + (uint32_t)thread->stack_obj; - __ASSERT(thread->stack_info.start == ((u32_t)thread->stack_obj), + __ASSERT(thread->stack_info.start == ((uint32_t)thread->stack_obj), "stack_info.start does not point to the start of the" "thread allocated area."); #else - u32_t guard_start = thread->stack_info.start; + uint32_t guard_start = thread->stack_info.start; #endif #if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM) __set_PSPLIM(guard_start); @@ -277,25 +254,27 @@ void configure_builtin_stack_guard(struct k_thread *thread) * @return The lowest allowed stack frame pointer, if error is a * thread stack corruption, otherwise return 0. */ -u32_t z_check_thread_stack_fail(const u32_t fault_addr, const u32_t psp) +uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp) { +#if defined(CONFIG_MULTITHREADING) const struct k_thread *thread = _current; if (!thread) { return 0; } +#endif #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - u32_t guard_len = (thread->base.user_options & K_FP_REGS) ? + uint32_t guard_len = (thread->base.user_options & K_FP_REGS) ? MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; #else - u32_t guard_len = MPU_GUARD_ALIGN_AND_SIZE; + uint32_t guard_len = MPU_GUARD_ALIGN_AND_SIZE; #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ #if defined(CONFIG_USERSPACE) if (thread->arch.priv_stack_start) { /* User thread */ - if ((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0) { + if ((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0U) { /* User thread in privilege mode */ if (IS_MPU_GUARD_VIOLATION( thread->arch.priv_stack_start - guard_len, @@ -305,9 +284,9 @@ u32_t z_check_thread_stack_fail(const u32_t fault_addr, const u32_t psp) return thread->arch.priv_stack_start; } } else { - if (psp < (u32_t)thread->stack_obj) { + if (psp < (uint32_t)thread->stack_obj) { /* Thread's user stack corruption */ - return (u32_t)thread->stack_obj; + return (uint32_t)thread->stack_obj; } } } else { @@ -321,12 +300,21 @@ u32_t z_check_thread_stack_fail(const u32_t fault_addr, const u32_t psp) } } #else /* CONFIG_USERSPACE */ +#if defined(CONFIG_MULTITHREADING) if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - guard_len, guard_len, fault_addr, psp)) { /* Thread stack corruption */ return thread->stack_info.start; } +#else + if (IS_MPU_GUARD_VIOLATION((uint32_t)z_main_stack, + guard_len, + fault_addr, psp)) { + /* Thread stack corruption */ + return (uint32_t)Z_THREAD_STACK_BUFFER(z_main_stack); + } +#endif #endif /* CONFIG_USERSPACE */ return 0; @@ -367,10 +355,11 @@ int arch_float_disable(struct k_thread *thread) } #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ -void arch_switch_to_main_thread(struct k_thread *main_thread, - k_thread_stack_t *main_stack, - size_t main_stack_size, - k_thread_entry_t _main) +/* Internal function for Cortex-M initialization, + * applicable to either case of running Zephyr + * with or without multi-threading support. + */ +static void z_arm_prepare_switch_to_main(void) { #if defined(CONFIG_FPU) /* Initialize the Floating Point Status and Control Register when in @@ -394,18 +383,16 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, */ z_arm_configure_static_mpu_regions(); #endif +} - /* get high address of the stack, i.e. its start (stack grows down) */ - char *start_of_main_stack; - - start_of_main_stack = - Z_THREAD_STACK_BUFFER(main_stack) + main_stack_size; - - start_of_main_stack = (char *)Z_STACK_PTR_ALIGN(start_of_main_stack); +void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, + k_thread_entry_t _main) +{ + z_arm_prepare_switch_to_main(); _current = main_thread; -#ifdef CONFIG_TRACING - sys_trace_thread_switched_in(); +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + z_thread_mark_switched_in(); #endif /* the ready queue cache already contains the main thread */ @@ -421,7 +408,7 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, #if defined(CONFIG_BUILTIN_STACK_GUARD) /* Set PSPLIM register for built-in stack guarding of main thread. */ #if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM) - __set_PSPLIM((u32_t)main_stack); + __set_PSPLIM(main_thread->stack_info.start); #else #error "Built-in PSP limit checks not supported by HW" #endif @@ -434,7 +421,7 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, __asm__ volatile ( "mov r0, %0\n\t" /* Store _main in R0 */ #if defined(CONFIG_CPU_CORTEX_M) - "msr PSP, %1\n\t" /* __set_PSP(start_of_main_stack) */ + "msr PSP, %1\n\t" /* __set_PSP(stack_ptr) */ #endif "movs r1, #0\n\t" @@ -452,9 +439,72 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, "movs r3, #0\n\t" "bl z_thread_entry\n\t" /* z_thread_entry(_main, 0, 0, 0); */ : - : "r" (_main), "r" (start_of_main_stack) + : "r" (_main), "r" (stack_ptr) : "r0" /* not to be overwritten by msr PSP, %1 */ ); CODE_UNREACHABLE; } + +#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_CPU_CORTEX_M) + +FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( + k_thread_entry_t main_entry, void *p1, void *p2, void *p3) +{ + z_arm_prepare_switch_to_main(); + + /* Set PSP to the highest address of the main stack. */ + char *psp = Z_THREAD_STACK_BUFFER(z_main_stack) + + K_THREAD_STACK_SIZEOF(z_main_stack); + +#if defined(CONFIG_BUILTIN_STACK_GUARD) + char *psplim = (Z_THREAD_STACK_BUFFER(z_main_stack)); + /* Clear PSPLIM before setting it to guard the main stack area. */ + __set_PSPLIM(0); +#endif + + /* Store all required input in registers, to be accesible + * after stack pointer change. The function is not going + * to return, so callee-saved registers do not need to be + * stacked. + */ + register void *p1_inreg __asm__("r0") = p1; + register void *p2_inreg __asm__("r1") = p2; + register void *p3_inreg __asm__("r2") = p3; + + __asm__ volatile ( +#ifdef CONFIG_BUILTIN_STACK_GUARD + "msr PSPLIM, %[_psplim]\n\t" +#endif + "msr PSP, %[_psp]\n\t" /* __set_PSP(psp) */ +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + "cpsie i\n\t" /* enable_irq() */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + "cpsie if\n\t" /* __enable_irq(); __enable_fault_irq() */ + "mov r3, #0\n\t" + "msr BASEPRI, r3\n\t" /* __set_BASEPRI(0) */ +#endif + "isb\n\t" + "blx %[_main_entry]\n\t" /* main_entry(p1, p2, p3) */ +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) + "cpsid i\n\t" /* disable_irq() */ +#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + "msr BASEPRI, %[basepri]\n\t"/* __set_BASEPRI(_EXC_IRQ_DEFAULT_PRIO) */ + "isb\n\t" +#endif + "loop: b loop\n\t" /* while (true); */ + : + : "r" (p1_inreg), "r" (p2_inreg), "r" (p3_inreg), + [_psp]"r" (psp), [_main_entry]"r" (main_entry) +#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + , [basepri] "r" (_EXC_IRQ_DEFAULT_PRIO) +#endif +#ifdef CONFIG_BUILTIN_STACK_GUARD + , [_psplim]"r" (psplim) +#endif + : + ); + + CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ +} +#endif /* !CONFIG_MULTITHREADING && CONFIG_CPU_CORTEX_M */ diff --git a/arch/arm/core/aarch32/userspace.S b/arch/arm/core/aarch32/userspace.S index c5f4b3b93abad1..10c7ec3f123681 100644 --- a/arch/arm/core/aarch32/userspace.S +++ b/arch/arm/core/aarch32/userspace.S @@ -216,20 +216,6 @@ SECTION_FUNC(TEXT,z_arm_userspace_enter) /* restore r0 */ mov r0, lr -#ifdef CONFIG_EXECUTION_BENCHMARKING - stm sp!,{r0-r3} /* Save regs r0 to r4 on stack */ - push {r0, lr} - bl read_timer_end_of_userspace_enter -#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) - pop {r0, r3} - mov lr,r3 -#else - pop {r0, lr} -#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ - ldm sp!,{r0-r3} /* Restore r0 to r3 regs */ - -#endif /* CONFIG_EXECUTION_BENCHMARKING */ - /* change processor mode to unprivileged */ #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) push {r0, r1, r2, r3} @@ -388,6 +374,9 @@ SECTION_FUNC(TEXT, z_arm_do_syscall) mov r1, lr b dispatch_syscall valid_syscall: + /* push ssf to privileged stack */ + mov r1, sp + push {r1} /* push args to complete stack frame */ push {r4,r5} @@ -410,8 +399,7 @@ dispatch_syscall: */ mov ip, r0 mov r0, sp - adds r0, #12 - ldr r0, [r0] + ldr r0, [r0,#16] mov lr, r0 /* Restore r0 */ mov r0, ip @@ -429,7 +417,8 @@ dispatch_syscall: valid_syscall: /* push args to complete stack frame */ - push {r4,r5} + mov ip, sp + push {r4,r5,ip} dispatch_syscall: ldr ip, =_k_syscall_table @@ -440,7 +429,7 @@ dispatch_syscall: blx ip /* restore LR */ - ldr lr, [sp,#12] + ldr lr, [sp,#16] #endif @@ -481,14 +470,14 @@ dispatch_syscall: /* set stack back to unprivileged stack */ mov ip, r0 mov r0, sp - ldr r0, [r0,#8] + ldr r0, [r0,#12] msr PSP, r0 /* Restore r0 */ mov r0, ip #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* set stack back to unprivileged stack */ - ldr ip, [sp,#8] + ldr ip, [sp,#12] msr PSP, ip #endif diff --git a/arch/arm/core/aarch32/vector_table.ld b/arch/arm/core/aarch32/vector_table.ld index 37a66ab77c107f..09c5dfd7216e79 100644 --- a/arch/arm/core/aarch32/vector_table.ld +++ b/arch/arm/core/aarch32/vector_table.ld @@ -1,9 +1,33 @@ /* - * Copyright (c) 2019 Nordic Semiconductor ASA + * Copyright (c) 2019 - 2020 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ +#if defined(CONFIG_CPU_CORTEX_M_HAS_VTOR) +/* + * In an MCU with VTOR, the VTOR.TBLOFF is set to the start address of the + * exc_vector_table (i.e. _vector_start) during initialization. Therefore, + * exc_vector_table must respect the alignment requirements of VTOR.TBLOFF + * described below. + */ + +/* VTOR bits 0:6 are reserved (RES0). This requires that the base address + * of the vector table is 32-word aligned. + */ +. = ALIGN( 1 << LOG2CEIL(4 * 32) ); + +/* When setting TBLOFF in VTOR we must align the offset to the number of + * exception entries in the vector table. The minimum alignment of 32 words + * is sufficient for the 16 ARM Core exceptions and up to 16 HW interrupts. + * For more than 16 HW interrupts, we adjust the alignment by rounding up + * to the next power of two; this restriction guarantees a functional VTOR + * setting in any Cortex-M implementation (might not be required in every + * Cortex-M processor). + */ +. = ALIGN( 1 << LOG2CEIL(4 * (16 + CONFIG_NUM_IRQS)) ); +#endif + _vector_start = .; KEEP(*(.exc_vector_table)) KEEP(*(".exc_vector_table.*")) diff --git a/arch/arm/core/aarch64/CMakeLists.txt b/arch/arm/core/aarch64/CMakeLists.txt index f29703e81237b1..3ce4a174971eb7 100644 --- a/arch/arm/core/aarch64/CMakeLists.txt +++ b/arch/arm/core/aarch64/CMakeLists.txt @@ -3,22 +3,32 @@ zephyr_library() if (CONFIG_COVERAGE) - toolchain_cc_coverage() + zephyr_compile_options($) + zephyr_link_libraries($) endif () zephyr_library_sources( - cpu_idle.S fatal.c irq_init.c irq_manage.c prep_c.c reset.S - swap.c - swap_helper.S + switch.S thread.c vector_table.S ) +# Workaround aarch64 QEMU not responding to host OS signals +# during 'wfi'. +# See https://github.com/zephyrproject-rtos/sdk-ng/issues/255 +if (CONFIG_SOC_QEMU_CORTEX_A53) + zephyr_library_sources(cpu_idle_qemu.c) +else () + zephyr_library_sources(cpu_idle.S) +endif () + zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) -zephyr_library_sources_ifdef(CONFIG_ARM_MMU arm_mmu.c) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE ../common/tls.c) + +add_subdirectory_ifdef(CONFIG_ARM_MMU mmu) diff --git a/arch/arm/core/aarch64/Kconfig b/arch/arm/core/aarch64/Kconfig index 4e4222857a06ed..6a1ca5ec96ad3c 100644 --- a/arch/arm/core/aarch64/Kconfig +++ b/arch/arm/core/aarch64/Kconfig @@ -7,6 +7,8 @@ config CPU_CORTEX_A bool select CPU_CORTEX select HAS_FLASH_LOAD_OFFSET + select USE_SWITCH + select USE_SWITCH_SUPPORTED help This option signifies the use of a CPU of the Cortex-A family. @@ -24,13 +26,6 @@ config CPU_CORTEX_A72 help This option signifies the use of a Cortex-A72 CPU -config SWITCH_TO_EL1 - bool "Switch to EL1 at boot" - default y - help - This option indicates that we want to switch to EL1 at boot. Only - switching to EL1 from EL3 is supported. - config NUM_IRQS int @@ -66,6 +61,7 @@ if CPU_CORTEX_A config ARMV8_A bool select ATOMIC_OPERATIONS_BUILTIN + select CPU_HAS_MMU help This option signifies the use of an ARMv8-A processor implementation. @@ -93,6 +89,15 @@ config ARM_MMU help Memory Management Unit support. +config EXCEPTION_DEBUG + bool "Unhandled exception debugging information" + default y + depends on LOG + help + Print human-readable information about exception vectors, cause codes, + and parameters, at a cost of code/data size for the human-readable + strings. + if ARM_MMU config MAX_XLAT_TABLES diff --git a/arch/arm/core/aarch64/arm_mmu.c b/arch/arm/core/aarch64/arm_mmu.c deleted file mode 100644 index 1ee25f3c800787..00000000000000 --- a/arch/arm/core/aarch64/arm_mmu.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright 2019 Broadcom - * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include - -/* Set below flag to get debug prints */ -#define MMU_DEBUG_PRINTS 0 -/* To get prints from MMU driver, it has to initialized after console driver */ -#define MMU_DEBUG_PRIORITY 70 - -#if MMU_DEBUG_PRINTS -/* To dump page table entries while filling them, set DUMP_PTE macro */ -#define DUMP_PTE 0 -#define MMU_DEBUG(fmt, ...) printk(fmt, ##__VA_ARGS__) -#else -#define MMU_DEBUG(...) -#endif - -/* We support only 4kB translation granule */ -#define PAGE_SIZE_SHIFT 12U -#define PAGE_SIZE (1U << PAGE_SIZE_SHIFT) -#define XLAT_TABLE_SIZE_SHIFT PAGE_SIZE_SHIFT /* Size of one complete table */ -#define XLAT_TABLE_SIZE (1U << XLAT_TABLE_SIZE_SHIFT) - -#define XLAT_TABLE_ENTRY_SIZE_SHIFT 3U /* Each table entry is 8 bytes */ -#define XLAT_TABLE_LEVEL_MAX 3U - -#define XLAT_TABLE_ENTRIES_SHIFT \ - (XLAT_TABLE_SIZE_SHIFT - XLAT_TABLE_ENTRY_SIZE_SHIFT) -#define XLAT_TABLE_ENTRIES (1U << XLAT_TABLE_ENTRIES_SHIFT) - -/* Address size covered by each entry at given translation table level */ -#define L3_XLAT_VA_SIZE_SHIFT PAGE_SIZE_SHIFT -#define L2_XLAT_VA_SIZE_SHIFT \ - (L3_XLAT_VA_SIZE_SHIFT + XLAT_TABLE_ENTRIES_SHIFT) -#define L1_XLAT_VA_SIZE_SHIFT \ - (L2_XLAT_VA_SIZE_SHIFT + XLAT_TABLE_ENTRIES_SHIFT) -#define L0_XLAT_VA_SIZE_SHIFT \ - (L1_XLAT_VA_SIZE_SHIFT + XLAT_TABLE_ENTRIES_SHIFT) - -#define LEVEL_TO_VA_SIZE_SHIFT(level) \ - (PAGE_SIZE_SHIFT + (XLAT_TABLE_ENTRIES_SHIFT * \ - (XLAT_TABLE_LEVEL_MAX - (level)))) - -/* Virtual Address Index within given translation table level */ -#define XLAT_TABLE_VA_IDX(va_addr, level) \ - ((va_addr >> LEVEL_TO_VA_SIZE_SHIFT(level)) & (XLAT_TABLE_ENTRIES - 1)) - -/* - * Calculate the initial translation table level from CONFIG_ARM64_VA_BITS - * For a 4 KB page size, - * (va_bits <= 21) - base level 3 - * (22 <= va_bits <= 30) - base level 2 - * (31 <= va_bits <= 39) - base level 1 - * (40 <= va_bits <= 48) - base level 0 - */ -#define GET_XLAT_TABLE_BASE_LEVEL(va_bits) \ - ((va_bits > L0_XLAT_VA_SIZE_SHIFT) \ - ? 0U \ - : (va_bits > L1_XLAT_VA_SIZE_SHIFT) \ - ? 1U \ - : (va_bits > L2_XLAT_VA_SIZE_SHIFT) \ - ? 2U : 3U) - -#define XLAT_TABLE_BASE_LEVEL GET_XLAT_TABLE_BASE_LEVEL(CONFIG_ARM64_VA_BITS) - -#define GET_NUM_BASE_LEVEL_ENTRIES(va_bits) \ - (1U << (va_bits - LEVEL_TO_VA_SIZE_SHIFT(XLAT_TABLE_BASE_LEVEL))) - -#define NUM_BASE_LEVEL_ENTRIES GET_NUM_BASE_LEVEL_ENTRIES(CONFIG_ARM64_VA_BITS) - -#if DUMP_PTE -#define L0_SPACE "" -#define L1_SPACE " " -#define L2_SPACE " " -#define L3_SPACE " " -#define XLAT_TABLE_LEVEL_SPACE(level) \ - (((level) == 0) ? L0_SPACE : \ - ((level) == 1) ? L1_SPACE : \ - ((level) == 2) ? L2_SPACE : L3_SPACE) -#endif - -static u64_t base_xlat_table[NUM_BASE_LEVEL_ENTRIES] - __aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(u64_t)); - -static u64_t xlat_tables[CONFIG_MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES] - __aligned(XLAT_TABLE_ENTRIES * sizeof(u64_t)); - -/* Translation table control register settings */ -static u64_t get_tcr(int el) -{ - u64_t tcr; - u64_t pa_bits = CONFIG_ARM64_PA_BITS; - u64_t va_bits = CONFIG_ARM64_VA_BITS; - u64_t tcr_ps_bits; - - switch (pa_bits) { - case 48: - tcr_ps_bits = TCR_PS_BITS_256TB; - break; - case 44: - tcr_ps_bits = TCR_PS_BITS_16TB; - break; - case 42: - tcr_ps_bits = TCR_PS_BITS_4TB; - break; - case 40: - tcr_ps_bits = TCR_PS_BITS_1TB; - break; - case 36: - tcr_ps_bits = TCR_PS_BITS_64GB; - break; - default: - tcr_ps_bits = TCR_PS_BITS_4GB; - break; - } - - if (el == 1) { - tcr = (tcr_ps_bits << TCR_EL1_IPS_SHIFT); - /* - * TCR_EL1.EPD1: Disable translation table walk for addresses - * that are translated using TTBR1_EL1. - */ - tcr |= TCR_EPD1_DISABLE; - } else - tcr = (tcr_ps_bits << TCR_EL3_PS_SHIFT); - - tcr |= TCR_T0SZ(va_bits); - /* - * Translation table walk is cacheable, inner/outer WBWA and - * inner shareable - */ - tcr |= TCR_TG0_4K | TCR_SHARED_INNER | TCR_ORGN_WBWA | TCR_IRGN_WBWA; - - return tcr; -} - -static int pte_desc_type(u64_t *pte) -{ - return *pte & PTE_DESC_TYPE_MASK; -} - -static u64_t *calculate_pte_index(u64_t addr, int level) -{ - int base_level = XLAT_TABLE_BASE_LEVEL; - u64_t *pte; - u64_t idx; - unsigned int i; - - /* Walk through all translation tables to find pte index */ - pte = (u64_t *)base_xlat_table; - for (i = base_level; i <= XLAT_TABLE_LEVEL_MAX; i++) { - idx = XLAT_TABLE_VA_IDX(addr, i); - pte += idx; - - /* Found pte index */ - if (i == level) - return pte; - /* if PTE is not table desc, can't traverse */ - if (pte_desc_type(pte) != PTE_TABLE_DESC) - return NULL; - /* Move to the next translation table level */ - pte = (u64_t *)(*pte & 0x0000fffffffff000ULL); - } - - return NULL; -} - -static void set_pte_table_desc(u64_t *pte, u64_t *table, unsigned int level) -{ -#if DUMP_PTE - MMU_DEBUG("%s", XLAT_TABLE_LEVEL_SPACE(level)); - MMU_DEBUG("%p: [Table] %p\n", pte, table); -#endif - /* Point pte to new table */ - *pte = PTE_TABLE_DESC | (u64_t)table; -} - -static void set_pte_block_desc(u64_t *pte, u64_t addr_pa, - unsigned int attrs, unsigned int level) -{ - u64_t desc = addr_pa; - unsigned int mem_type; - - desc |= (level == 3) ? PTE_PAGE_DESC : PTE_BLOCK_DESC; - - /* NS bit for security memory access from secure state */ - desc |= (attrs & MT_NS) ? PTE_BLOCK_DESC_NS : 0; - - /* AP bits for Data access permission */ - desc |= (attrs & MT_RW) ? PTE_BLOCK_DESC_AP_RW : PTE_BLOCK_DESC_AP_RO; - - /* the access flag */ - desc |= PTE_BLOCK_DESC_AF; - - /* memory attribute index field */ - mem_type = MT_TYPE(attrs); - desc |= PTE_BLOCK_DESC_MEMTYPE(mem_type); - - switch (mem_type) { - case MT_DEVICE_nGnRnE: - case MT_DEVICE_nGnRE: - case MT_DEVICE_GRE: - /* Access to Device memory and non-cacheable memory are coherent - * for all observers in the system and are treated as - * Outer shareable, so, for these 2 types of memory, - * it is not strictly needed to set shareability field - */ - desc |= PTE_BLOCK_DESC_OUTER_SHARE; - /* Map device memory as execute-never */ - desc |= PTE_BLOCK_DESC_PXN; - desc |= PTE_BLOCK_DESC_UXN; - break; - case MT_NORMAL_NC: - case MT_NORMAL: - /* Make Normal RW memory as execute never */ - if ((attrs & MT_RW) || (attrs & MT_EXECUTE_NEVER)) - desc |= PTE_BLOCK_DESC_PXN; - if (mem_type == MT_NORMAL) - desc |= PTE_BLOCK_DESC_INNER_SHARE; - else - desc |= PTE_BLOCK_DESC_OUTER_SHARE; - } - -#if DUMP_PTE - MMU_DEBUG("%s", XLAT_TABLE_LEVEL_SPACE(level)); - MMU_DEBUG("%p: ", pte); - MMU_DEBUG((mem_type == MT_NORMAL) ? "MEM" : - ((mem_type == MT_NORMAL_NC) ? "NC" : "DEV")); - MMU_DEBUG((attrs & MT_RW) ? "-RW" : "-RO"); - MMU_DEBUG((attrs & MT_NS) ? "-NS" : "-S"); - MMU_DEBUG((attrs & MT_EXECUTE_NEVER) ? "-XN" : "-EXEC"); - MMU_DEBUG("\n"); -#endif - - *pte = desc; -} - -/* Returns a new reallocated table */ -static u64_t *new_prealloc_table(void) -{ - static unsigned int table_idx; - - __ASSERT(table_idx < CONFIG_MAX_XLAT_TABLES, - "Enough xlat tables not allocated"); - - return (u64_t *)(xlat_tables[table_idx++]); -} - -/* Splits a block into table with entries spanning the old block */ -static void split_pte_block_desc(u64_t *pte, int level) -{ - u64_t old_block_desc = *pte; - u64_t *new_table; - unsigned int i = 0; - /* get address size shift bits for next level */ - int levelshift = LEVEL_TO_VA_SIZE_SHIFT(level + 1); - - MMU_DEBUG("Splitting existing PTE %p(L%d)\n", pte, level); - - new_table = new_prealloc_table(); - - for (i = 0; i < XLAT_TABLE_ENTRIES; i++) { - new_table[i] = old_block_desc | (i << levelshift); - - if ((level + 1) == 3) - new_table[i] |= PTE_PAGE_DESC; - } - - /* Overwrite existing PTE set the new table into effect */ - set_pte_table_desc(pte, new_table, level); -} - -/* Create/Populate translation table(s) for given region */ -static void init_xlat_tables(const struct arm_mmu_region *region) -{ - u64_t *pte; - u64_t virt = region->base_va; - u64_t phys = region->base_pa; - u64_t size = region->size; - u64_t attrs = region->attrs; - u64_t level_size; - u64_t *new_table; - unsigned int level = XLAT_TABLE_BASE_LEVEL; - - MMU_DEBUG("mmap: virt %llx phys %llx size %llx\n", virt, phys, size); - /* check minimum alignment requirement for given mmap region */ - __ASSERT(((virt & (PAGE_SIZE - 1)) == 0) && - ((size & (PAGE_SIZE - 1)) == 0), - "address/size are not page aligned\n"); - - while (size) { - __ASSERT(level <= XLAT_TABLE_LEVEL_MAX, - "max translation table level exceeded\n"); - - /* Locate PTE for given virtual address and page table level */ - pte = calculate_pte_index(virt, level); - __ASSERT(pte != NULL, "pte not found\n"); - - level_size = 1ULL << LEVEL_TO_VA_SIZE_SHIFT(level); - - if (size >= level_size && !(virt & (level_size - 1))) { - /* Given range fits into level size, - * create block/page descriptor - */ - set_pte_block_desc(pte, phys, attrs, level); - virt += level_size; - phys += level_size; - size -= level_size; - /* Range is mapped, start again for next range */ - level = XLAT_TABLE_BASE_LEVEL; - } else if (pte_desc_type(pte) == PTE_INVALID_DESC) { - /* Range doesn't fit, create subtable */ - new_table = new_prealloc_table(); - set_pte_table_desc(pte, new_table, level); - level++; - } else if (pte_desc_type(pte) == PTE_BLOCK_DESC) { - split_pte_block_desc(pte, level); - level++; - } else if (pte_desc_type(pte) == PTE_TABLE_DESC) - level++; - } -} - -/* zephyr execution regions with appropriate attributes */ -static const struct arm_mmu_region mmu_zephyr_regions[] = { - - /* Mark text segment cacheable,read only and executable */ - MMU_REGION_FLAT_ENTRY("zephyr_code", - (uintptr_t)_image_text_start, - (uintptr_t)_image_text_size, - MT_CODE | MT_SECURE), - - /* Mark rodata segment cacheable, read only and execute-never */ - MMU_REGION_FLAT_ENTRY("zephyr_rodata", - (uintptr_t)_image_rodata_start, - (uintptr_t)_image_rodata_size, - MT_RODATA | MT_SECURE), - - /* Mark rest of the zephyr execution regions (data, bss, noinit, etc.) - * cacheable, read-write - * Note: read-write region is marked execute-ever internally - */ - MMU_REGION_FLAT_ENTRY("zephyr_data", - (uintptr_t)__kernel_ram_start, - (uintptr_t)__kernel_ram_size, - MT_NORMAL | MT_RW | MT_SECURE), -}; - -static void setup_page_tables(void) -{ - unsigned int index; - const struct arm_mmu_region *region; - u64_t max_va = 0, max_pa = 0; - - for (index = 0; index < mmu_config.num_regions; index++) { - region = &mmu_config.mmu_regions[index]; - max_va = MAX(max_va, region->base_va + region->size); - max_pa = MAX(max_pa, region->base_pa + region->size); - } - - __ASSERT(max_va <= (1ULL << CONFIG_ARM64_VA_BITS), - "Maximum VA not supported\n"); - __ASSERT(max_pa <= (1ULL << CONFIG_ARM64_PA_BITS), - "Maximum PA not supported\n"); - - /* create translation tables for user provided platform regions */ - for (index = 0; index < mmu_config.num_regions; index++) { - region = &mmu_config.mmu_regions[index]; - if (region->size || region->attrs) - init_xlat_tables(region); - } - - /* setup translation table for zephyr execution regions */ - for (index = 0; index < ARRAY_SIZE(mmu_zephyr_regions); index++) { - region = &mmu_zephyr_regions[index]; - if (region->size || region->attrs) - init_xlat_tables(region); - } -} - -static void enable_mmu_el1(unsigned int flags) -{ - ARG_UNUSED(flags); - u64_t val; - - /* Set MAIR, TCR and TBBR registers */ - __asm__ volatile("msr mair_el1, %0" - : - : "r" (MEMORY_ATTRIBUTES) - : "memory", "cc"); - __asm__ volatile("msr tcr_el1, %0" - : - : "r" (get_tcr(1)) - : "memory", "cc"); - __asm__ volatile("msr ttbr0_el1, %0" - : - : "r" ((u64_t)base_xlat_table) - : "memory", "cc"); - - /* Ensure these changes are seen before MMU is enabled */ - __ISB(); - - /* Enable the MMU and data cache */ - __asm__ volatile("mrs %0, sctlr_el1" : "=r" (val)); - __asm__ volatile("msr sctlr_el1, %0" - : - : "r" (val | SCTLR_M_BIT | SCTLR_C_BIT) - : "memory", "cc"); - - /* Ensure the MMU enable takes effect immediately */ - __ISB(); - - MMU_DEBUG("MMU enabled with dcache\n"); -} - -/* ARM MMU Driver Initial Setup */ - -/* - * @brief MMU default configuration - * - * This function provides the default configuration mechanism for the Memory - * Management Unit (MMU). - */ -static int arm_mmu_init(struct device *arg) -{ - u64_t val; - unsigned int idx, flags = 0; - - /* Current MMU code supports only EL1 */ - __asm__ volatile("mrs %0, CurrentEL" : "=r" (val)); - - __ASSERT(GET_EL(val) == MODE_EL1, - "Exception level not EL1, MMU not enabled!\n"); - - /* Ensure that MMU is already not enabled */ - __asm__ volatile("mrs %0, sctlr_el1" : "=r" (val)); - __ASSERT((val & SCTLR_M_BIT) == 0, "MMU is already enabled\n"); - - MMU_DEBUG("xlat tables:\n"); - MMU_DEBUG("base table(L%d): %p, %d entries\n", XLAT_TABLE_BASE_LEVEL, - (u64_t *)base_xlat_table, NUM_BASE_LEVEL_ENTRIES); - for (idx = 0; idx < CONFIG_MAX_XLAT_TABLES; idx++) - MMU_DEBUG("%d: %p\n", idx, (u64_t *)(xlat_tables + idx)); - - setup_page_tables(); - - /* currently only EL1 is supported */ - enable_mmu_el1(flags); - - return 0; -} - -SYS_INIT(arm_mmu_init, PRE_KERNEL_1, -#if MMU_DEBUG_PRINTS - MMU_DEBUG_PRIORITY -#else - CONFIG_KERNEL_INIT_PRIORITY_DEVICE -#endif -); diff --git a/arch/arm/core/aarch64/cpu_idle.S b/arch/arm/core/aarch64/cpu_idle.S index 35fe80e302a14d..0d8961f90d3ac0 100644 --- a/arch/arm/core/aarch64/cpu_idle.S +++ b/arch/arm/core/aarch64/cpu_idle.S @@ -4,9 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -/** - * @file - * @brief ARM64 Cortex-A power management +/* + * ARM64 Cortex-A power management */ #include diff --git a/arch/arm/core/aarch64/cpu_idle_qemu.c b/arch/arm/core/aarch64/cpu_idle_qemu.c new file mode 100644 index 00000000000000..1af5eeaa757523 --- /dev/null +++ b/arch/arm/core/aarch64/cpu_idle_qemu.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + + /** + * @file + * + * @brief Workaround aarch64 QEMU not responding to host OS signals + * during 'wfi'. + * See https://github.com/zephyrproject-rtos/sdk-ng/issues/255 + */ + +#include + +void arch_cpu_idle(void) +{ + /* Do nothing but unconditionally unlock interrupts and return to the + * caller. + */ + + __asm__ volatile("msr daifclr, %0\n\t" + : : "i" (DAIFSET_IRQ) + : "memory", "cc"); +} + +void arch_cpu_atomic_idle(unsigned int key) +{ + /* Do nothing but restore IRQ state */ + arch_irq_unlock(key); +} diff --git a/arch/arm/core/aarch64/fatal.c b/arch/arm/core/aarch64/fatal.c index b06100e12b0e50..4cce8019f53bb6 100644 --- a/arch/arm/core/aarch64/fatal.c +++ b/arch/arm/core/aarch64/fatal.c @@ -9,155 +9,176 @@ * @brief Kernel fatal error handler for ARM64 Cortex-A * * This module provides the z_arm64_fatal_error() routine for ARM64 Cortex-A - * CPUs + * CPUs and z_arm64_do_kernel_oops() routine to manage software-generated fatal + * exceptions */ #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); -static void print_EC_cause(u64_t esr) +#ifdef CONFIG_EXCEPTION_DEBUG +static void dump_esr(uint64_t esr, bool *dump_far) { - u32_t EC = (u32_t)esr >> 26; + const char *err; - switch (EC) { - case 0b000000: - LOG_ERR("Unknown reason"); + switch (ESR_EC(esr)) { + case 0b000000: /* 0x00 */ + err = "Unknown reason"; break; - case 0b000001: - LOG_ERR("Trapped WFI or WFE instruction execution"); + case 0b000001: /* 0x01 */ + err = "Trapped WFI or WFE instruction execution"; break; - case 0b000011: - LOG_ERR("Trapped MCR or MRC access with (coproc==0b1111) that " - "is not reported using EC 0b000000"); + case 0b000011: /* 0x03 */ + err = "Trapped MCR or MRC access with (coproc==0b1111) that " + "is not reported using EC 0b000000"; break; - case 0b000100: - LOG_ERR("Trapped MCRR or MRRC access with (coproc==0b1111) " - "that is not reported using EC 0b000000"); + case 0b000100: /* 0x04 */ + err = "Trapped MCRR or MRRC access with (coproc==0b1111) " + "that is not reported using EC 0b000000"; break; - case 0b000101: - LOG_ERR("Trapped MCR or MRC access with (coproc==0b1110)"); + case 0b000101: /* 0x05 */ + err = "Trapped MCR or MRC access with (coproc==0b1110)"; break; - case 0b000110: - LOG_ERR("Trapped LDC or STC access"); + case 0b000110: /* 0x06 */ + err = "Trapped LDC or STC access"; break; - case 0b000111: - LOG_ERR("Trapped access to SVE, Advanced SIMD, or " - "floating-point functionality"); + case 0b000111: /* 0x07 */ + err = "Trapped access to SVE, Advanced SIMD, or " + "floating-point functionality"; break; - case 0b001100: - LOG_ERR("Trapped MRRC access with (coproc==0b1110)"); + case 0b001100: /* 0x0c */ + err = "Trapped MRRC access with (coproc==0b1110)"; break; - case 0b001101: - LOG_ERR("Branch Target Exception"); + case 0b001101: /* 0x0d */ + err = "Branch Target Exception"; break; - case 0b001110: - LOG_ERR("Illegal Execution state"); + case 0b001110: /* 0x0e */ + err = "Illegal Execution state"; break; - case 0b010001: - LOG_ERR("SVC instruction execution in AArch32 state"); + case 0b010001: /* 0x11 */ + err = "SVC instruction execution in AArch32 state"; break; - case 0b011000: - LOG_ERR("Trapped MSR, MRS or System instruction execution in " - "AArch64 state, that is not reported using EC " - "0b000000, 0b000001 or 0b000111"); + case 0b011000: /* 0x18 */ + err = "Trapped MSR, MRS or System instruction execution in " + "AArch64 state, that is not reported using EC " + "0b000000, 0b000001 or 0b000111"; break; - case 0b011001: - LOG_ERR("Trapped access to SVE functionality"); + case 0b011001: /* 0x19 */ + err = "Trapped access to SVE functionality"; break; - case 0b100000: - LOG_ERR("Instruction Abort from a lower Exception level, that " - "might be using AArch32 or AArch64"); + case 0b100000: /* 0x20 */ + *dump_far = true; + err = "Instruction Abort from a lower Exception level, that " + "might be using AArch32 or AArch64"; break; - case 0b100001: - LOG_ERR("Instruction Abort taken without a change in Exception " - "level."); + case 0b100001: /* 0x21 */ + *dump_far = true; + err = "Instruction Abort taken without a change in Exception " + "level."; break; - case 0b100010: - LOG_ERR("PC alignment fault exception."); + case 0b100010: /* 0x22 */ + *dump_far = true; + err = "PC alignment fault exception."; break; - case 0b100100: - LOG_ERR("Data Abort from a lower Exception level, that might " - "be using AArch32 or AArch64"); + case 0b100100: /* 0x24 */ + *dump_far = true; + err = "Data Abort from a lower Exception level, that might " + "be using AArch32 or AArch64"; break; - case 0b100101: - LOG_ERR("Data Abort taken without a change in Exception level"); + case 0b100101: /* 0x25 */ + *dump_far = true; + err = "Data Abort taken without a change in Exception level"; break; - case 0b100110: - LOG_ERR("SP alignment fault exception"); + case 0b100110: /* 0x26 */ + err = "SP alignment fault exception"; break; - case 0b101000: - LOG_ERR("Trapped floating-point exception taken from AArch32 " - "state"); + case 0b101000: /* 0x28 */ + err = "Trapped floating-point exception taken from AArch32 " + "state"; break; - case 0b101100: - LOG_ERR("Trapped floating-point exception taken from AArch64 " - "state."); + case 0b101100: /* 0x2c */ + err = "Trapped floating-point exception taken from AArch64 " + "state."; break; - case 0b101111: - LOG_ERR("SError interrupt"); + case 0b101111: /* 0x2f */ + err = "SError interrupt"; break; - case 0b110000: - LOG_ERR("Breakpoint exception from a lower Exception level, " - "that might be using AArch32 or AArch64"); + case 0b110000: /* 0x30 */ + err = "Breakpoint exception from a lower Exception level, " + "that might be using AArch32 or AArch64"; break; - case 0b110001: - LOG_ERR("Breakpoint exception taken without a change in " - "Exception level"); + case 0b110001: /* 0x31 */ + err = "Breakpoint exception taken without a change in " + "Exception level"; break; - case 0b110010: - LOG_ERR("Software Step exception from a lower Exception level, " - "that might be using AArch32 or AArch64"); + case 0b110010: /* 0x32 */ + err = "Software Step exception from a lower Exception level, " + "that might be using AArch32 or AArch64"; break; - case 0b110011: - LOG_ERR("Software Step exception taken without a change in " - "Exception level"); + case 0b110011: /* 0x33 */ + err = "Software Step exception taken without a change in " + "Exception level"; break; - case 0b110100: - LOG_ERR("Watchpoint exception from a lower Exception level, " - "that might be using AArch32 or AArch64"); + case 0b110100: /* 0x34 */ + *dump_far = true; + err = "Watchpoint exception from a lower Exception level, " + "that might be using AArch32 or AArch64"; break; - case 0b110101: - LOG_ERR("Watchpoint exception taken without a change in " - "Exception level."); + case 0b110101: /* 0x35 */ + *dump_far = true; + err = "Watchpoint exception taken without a change in " + "Exception level."; break; - case 0b111000: - LOG_ERR("BKPT instruction execution in AArch32 state"); + case 0b111000: /* 0x38 */ + err = "BKPT instruction execution in AArch32 state"; break; - case 0b111100: - LOG_ERR("BRK instruction execution in AArch64 state."); + case 0b111100: /* 0x3c */ + err = "BRK instruction execution in AArch64 state."; break; + default: + err = "Unknown"; } + + LOG_ERR("ESR_ELn: 0x%016llx", esr); + LOG_ERR(" EC: 0x%llx (%s)", ESR_EC(esr), err); + LOG_ERR(" IL: 0x%llx", ESR_IL(esr)); + LOG_ERR(" ISS: 0x%llx", ESR_ISS(esr)); } static void esf_dump(const z_arch_esf_t *esf) { - LOG_ERR("x1: %-8llx x0: %llx", - esf->basic.regs[18], esf->basic.regs[19]); - LOG_ERR("x2: %-8llx x3: %llx", - esf->basic.regs[16], esf->basic.regs[17]); - LOG_ERR("x4: %-8llx x5: %llx", - esf->basic.regs[14], esf->basic.regs[15]); - LOG_ERR("x6: %-8llx x7: %llx", - esf->basic.regs[12], esf->basic.regs[13]); - LOG_ERR("x8: %-8llx x9: %llx", - esf->basic.regs[10], esf->basic.regs[11]); - LOG_ERR("x10: %-8llx x11: %llx", - esf->basic.regs[8], esf->basic.regs[9]); - LOG_ERR("x12: %-8llx x13: %llx", - esf->basic.regs[6], esf->basic.regs[7]); - LOG_ERR("x14: %-8llx x15: %llx", - esf->basic.regs[4], esf->basic.regs[5]); - LOG_ERR("x16: %-8llx x17: %llx", - esf->basic.regs[2], esf->basic.regs[3]); - LOG_ERR("x18: %-8llx x30: %llx", - esf->basic.regs[0], esf->basic.regs[1]); + LOG_ERR("x0: 0x%016llx x1: 0x%016llx", esf->x0, esf->x1); + LOG_ERR("x2: 0x%016llx x3: 0x%016llx", esf->x2, esf->x3); + LOG_ERR("x4: 0x%016llx x5: 0x%016llx", esf->x4, esf->x5); + LOG_ERR("x6: 0x%016llx x7: 0x%016llx", esf->x6, esf->x7); + LOG_ERR("x8: 0x%016llx x9: 0x%016llx", esf->x8, esf->x9); + LOG_ERR("x10: 0x%016llx x11: 0x%016llx", esf->x10, esf->x11); + LOG_ERR("x12: 0x%016llx x13: 0x%016llx", esf->x12, esf->x13); + LOG_ERR("x14: 0x%016llx x15: 0x%016llx", esf->x14, esf->x15); + LOG_ERR("x16: 0x%016llx x17: 0x%016llx", esf->x16, esf->x17); + LOG_ERR("x18: 0x%016llx x30: 0x%016llx", esf->x18, esf->x30); +} +#endif /* CONFIG_EXCEPTION_DEBUG */ + +static bool is_recoverable(z_arch_esf_t *esf, uint64_t esr, uint64_t far, + uint64_t elr) +{ + if (!esf) + return false; + + /* Empty */ + + return false; } -void z_arm64_fatal_error(unsigned int reason, const z_arch_esf_t *esf) +void z_arm64_fatal_error(unsigned int reason, z_arch_esf_t *esf) { - u64_t el, esr, elr, far; + uint64_t esr = 0; + uint64_t elr = 0; + uint64_t far = 0; + uint64_t el; if (reason != K_ERR_SPURIOUS_IRQ) { __asm__ volatile("mrs %0, CurrentEL" : "=r" (el)); @@ -168,36 +189,51 @@ void z_arm64_fatal_error(unsigned int reason, const z_arch_esf_t *esf) __asm__ volatile("mrs %0, far_el1" : "=r" (far)); __asm__ volatile("mrs %0, elr_el1" : "=r" (elr)); break; - case MODE_EL2: - __asm__ volatile("mrs %0, esr_el2" : "=r" (esr)); - __asm__ volatile("mrs %0, far_el2" : "=r" (far)); - __asm__ volatile("mrs %0, elr_el2" : "=r" (elr)); - break; case MODE_EL3: __asm__ volatile("mrs %0, esr_el3" : "=r" (esr)); __asm__ volatile("mrs %0, far_el3" : "=r" (far)); __asm__ volatile("mrs %0, elr_el3" : "=r" (elr)); break; - default: - /* Just to keep the compiler happy */ - esr = elr = far = 0; - break; } if (GET_EL(el) != MODE_EL0) { - LOG_ERR("ESR_ELn: %llx", esr); - LOG_ERR("FAR_ELn: %llx", far); - LOG_ERR("ELR_ELn: %llx", elr); +#ifdef CONFIG_EXCEPTION_DEBUG + bool dump_far = false; - print_EC_cause(esr); - } + LOG_ERR("ELR_ELn: 0x%016llx", elr); + + dump_esr(esr, &dump_far); + if (dump_far) + LOG_ERR("FAR_ELn: 0x%016llx", far); +#endif /* CONFIG_EXCEPTION_DEBUG */ + + if (is_recoverable(esf, esr, far, elr)) + return; + } } +#ifdef CONFIG_EXCEPTION_DEBUG if (esf != NULL) { esf_dump(esf); } +#endif /* CONFIG_EXCEPTION_DEBUG */ + z_fatal_error(reason, esf); CODE_UNREACHABLE; } + +/** + * @brief Handle a software-generated fatal exception + * (e.g. kernel oops, panic, etc.). + * + * @param esf exception frame + */ +void z_arm64_do_kernel_oops(z_arch_esf_t *esf) +{ + /* x8 holds the exception reason */ + unsigned int reason = esf->x8; + + z_arm64_fatal_error(reason, esf); +} diff --git a/arch/arm/core/aarch64/irq_init.c b/arch/arm/core/aarch64/irq_init.c index 2f2b8306a08ffc..85cda0171ed3dd 100644 --- a/arch/arm/core/aarch64/irq_init.c +++ b/arch/arm/core/aarch64/irq_init.c @@ -24,10 +24,7 @@ */ void z_arm64_interrupt_init(void) { -#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) - /* Initialise the Generic Interrupt Controller (GIC) driver */ - arm_gic_init(); -#else +#ifdef CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER /* Invoke SoC-specific interrupt controller initialisation */ z_soc_irq_init(); #endif diff --git a/arch/arm/core/aarch64/irq_manage.c b/arch/arm/core/aarch64/irq_manage.c index 8219d0132f3d28..32136c19722342 100644 --- a/arch/arm/core/aarch64/irq_manage.c +++ b/arch/arm/core/aarch64/irq_manage.c @@ -18,7 +18,7 @@ #include #include -void z_arm64_fatal_error(unsigned int reason, const z_arch_esf_t *esf); +void z_arm64_fatal_error(unsigned int reason, z_arch_esf_t *esf); #if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) /* @@ -47,7 +47,7 @@ int arch_irq_is_enabled(unsigned int irq) return arm_gic_irq_is_enabled(irq); } -void z_arm64_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags) +void z_arm64_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { arm_gic_irq_set_priority(irq, prio, flags); } @@ -55,8 +55,8 @@ void z_arm64_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags) #ifdef CONFIG_DYNAMIC_INTERRUPTS int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *parameter), void *parameter, - u32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { z_isr_install(irq, routine, parameter); z_arm64_irq_priority_set(irq, priority, flags); @@ -64,7 +64,7 @@ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, } #endif -void z_irq_spurious(void *unused) +void z_irq_spurious(const void *unused) { ARG_UNUSED(unused); diff --git a/arch/arm/core/aarch64/irq_offload.c b/arch/arm/core/aarch64/irq_offload.c index 1b77f733c076a7..1a6b6e2c3dd88b 100644 --- a/arch/arm/core/aarch64/irq_offload.c +++ b/arch/arm/core/aarch64/irq_offload.c @@ -14,14 +14,14 @@ #include volatile irq_offload_routine_t offload_routine; -static void *offload_param; +static const void *offload_param; void z_irq_do_offload(void) { offload_routine(offload_param); } -void arch_irq_offload(irq_offload_routine_t routine, void *parameter) +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { k_sched_lock(); offload_routine = routine; diff --git a/arch/arm/core/aarch64/isr_wrapper.S b/arch/arm/core/aarch64/isr_wrapper.S index 59bc53646b2b50..7cabbffdfeade5 100644 --- a/arch/arm/core/aarch64/isr_wrapper.S +++ b/arch/arm/core/aarch64/isr_wrapper.S @@ -4,9 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -/** - * @file - * @brief ARM64 Cortex-A ISRs wrapper +/* + * ARM64 Cortex-A ISRs wrapper */ #include @@ -20,26 +19,21 @@ _ASM_FILE_PROLOGUE GDATA(_sw_isr_table) -/** - * @brief Wrapper around ISRs when inserted in software ISR table +/* + * Wrapper around ISRs when inserted in software ISR table * * When inserted in the vector table, _isr_wrapper() demuxes the ISR table * using the running interrupt number as the index, and invokes the registered * ISR with its corresponding argument. When returning from the ISR, it * determines if a context switch needs to happen. - * - * @return N/A */ GTEXT(_isr_wrapper) SECTION_FUNC(TEXT, _isr_wrapper) - z_arm64_enter_exc + z_arm64_enter_exc x0, x1 /* ++(_kernel->nested) to be checked by arch_is_in_isr() */ - ldr x1, =_kernel - ldr x2, [x1, #_kernel_offset_to_nested] - add x2, x2, #1 - str x2, [x1, #_kernel_offset_to_nested] + inc_nest_counter x0, x1 #ifdef CONFIG_TRACING bl sys_trace_isr_enter @@ -47,12 +41,12 @@ SECTION_FUNC(TEXT, _isr_wrapper) /* Get active IRQ number from the interrupt controller */ #if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) - bl arm_gic_get_active + bl arm_gic_get_active #else - bl z_soc_irq_get_active + bl z_soc_irq_get_active #endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ - stp x0, x1, [sp, #-16]! - lsl x0, x0, #4 /* table is 16-byte wide */ + stp x0, x1, [sp, #-16]! + lsl x0, x0, #4 /* table is 16-byte wide */ /* Retrieve the interrupt service routine */ ldr x1, =_sw_isr_table @@ -68,11 +62,11 @@ SECTION_FUNC(TEXT, _isr_wrapper) msr daifset, #(DAIFSET_IRQ) /* Signal end-of-interrupt */ - ldp x0, x1, [sp], #16 + ldp x0, x1, [sp], #16 #if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) - bl arm_gic_eoi + bl arm_gic_eoi #else - bl z_soc_irq_eoi + bl z_soc_irq_eoi #endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ #ifdef CONFIG_TRACING @@ -80,33 +74,37 @@ SECTION_FUNC(TEXT, _isr_wrapper) #endif /* --(_kernel->nested) */ - ldr x1, =_kernel - ldr x2, [x1, #_kernel_offset_to_nested] - sub x2, x2, #1 - str x2, [x1, #_kernel_offset_to_nested] + dec_nest_counter x0, x1 - cmp x2, #0 + cmp x1, #0 bne exit - /* Check if we need to context switch */ - ldr x2, [x1, #_kernel_offset_to_current] - ldr x3, [x1, #_kernel_offset_to_ready_q_cache] - cmp x2, x3 + /* + * z_arch_get_next_switch_handle() is returning: + * + * - The next thread to schedule in x0 + * - The current thread in x1. This value is returned using the + * **old_thread parameter, so we need to make space on the stack for + * that. + */ + stp x1, xzr, [sp, #-16]! + mov x0, sp + bl z_arch_get_next_switch_handle + ldp x1, xzr, [sp], #16 + + /* + * x0: 1st thread in the ready queue + * x1: _current thread + */ + cmp x0, x1 beq exit /* Switch thread */ bl z_arm64_context_switch - /* We return here in two cases: - * - * - The ISR was taken and no context switch was performed. - * - A context-switch was performed during the ISR in the past and now - * the thread has been switched in again and we return here from the - * ret in z_arm64_context_switch() because x30 was saved and restored. - */ exit: #ifdef CONFIG_STACK_SENTINEL bl z_check_stack_sentinel #endif - z_arm64_exit_exc + z_arm64_exit_exc x0, x1 diff --git a/arch/arm/core/aarch64/macro_priv.inc b/arch/arm/core/aarch64/macro_priv.inc index f1bf63e76138ee..7810399a2dc93c 100644 --- a/arch/arm/core/aarch64/macro_priv.inc +++ b/arch/arm/core/aarch64/macro_priv.inc @@ -9,112 +9,72 @@ #ifdef _ASMLANGUAGE -/** - * @brief Save volatile registers +/* + * Save volatile registers, x30, SPSR_EL1 and ELR_EL1 * * Save the volatile registers and x30 on the process stack. This is * needed if the thread is switched out because they can be clobbered by the * ISR and/or context switch. - * - * @return N/A */ -.macro z_arm64_enter_exc +.macro z_arm64_enter_exc xreg0, xreg1 + /* Switch to SP_EL0 */ + msr spsel, #0 + /* - * Two things can happen: + * Two things can happen to the remaining registers: * * - No context-switch: in this case x19-x28 are callee-saved register * so we can be sure they are not going to be clobbered by ISR. * - Context-switch: the callee-saved registers are saved by - * z_arm64_pendsv() in the kernel structure. + * z_arm64_context_switch() in the kernel structure. */ - stp x0, x1, [sp, #-16]! - stp x2, x3, [sp, #-16]! - stp x4, x5, [sp, #-16]! - stp x6, x7, [sp, #-16]! - stp x8, x9, [sp, #-16]! - stp x10, x11, [sp, #-16]! - stp x12, x13, [sp, #-16]! - stp x14, x15, [sp, #-16]! - stp x16, x17, [sp, #-16]! - stp x18, x30, [sp, #-16]! - /* - * Store SPSR_ELn and ELR_ELn. This is needed to support nested - * exception handlers - */ - switch_el x3, 3f, 2f, 1f -3: - mrs x0, spsr_el3 - mrs x1, elr_el3 - b 0f -2: - mrs x0, spsr_el2 - mrs x1, elr_el2 - b 0f -1: - mrs x0, spsr_el1 - mrs x1, elr_el1 -0: - stp x0, x1, [sp, #-16]! + sub sp, sp, ___esf_t_SIZEOF + + stp x0, x1, [sp, ___esf_t_x0_x1_OFFSET] + stp x2, x3, [sp, ___esf_t_x2_x3_OFFSET] + stp x4, x5, [sp, ___esf_t_x4_x5_OFFSET] + stp x6, x7, [sp, ___esf_t_x6_x7_OFFSET] + stp x8, x9, [sp, ___esf_t_x8_x9_OFFSET] + stp x10, x11, [sp, ___esf_t_x10_x11_OFFSET] + stp x12, x13, [sp, ___esf_t_x12_x13_OFFSET] + stp x14, x15, [sp, ___esf_t_x14_x15_OFFSET] + stp x16, x17, [sp, ___esf_t_x16_x17_OFFSET] + stp x18, x30, [sp, ___esf_t_x18_x30_OFFSET] + + mrs \xreg0, spsr_el1 + mrs \xreg1, elr_el1 + stp \xreg0, \xreg1, [sp, ___esf_t_spsr_elr_OFFSET] .endm -/** - * @brief Restore volatile registers and x30 - * - * This is the common exit point for z_arm64_pendsv() and _isr_wrapper(). We - * restore the registers saved on the process stack including X30. The return - * address used by eret (in ELR_ELn) is either restored by z_arm64_pendsv() if - * a context-switch happened or not touched at all by the ISR if there was no - * context-switch. +/* + * Restore volatile registers, x30, SPSR_EL1 and ELR_EL1 * - * @return N/A + * This is the common exit point for z_arm64_sync_exc() and _isr_wrapper(). */ -.macro z_arm64_exit_exc - /* - * Restore SPSR_ELn and ELR_ELn. This is needed to support nested - * exception handlers - */ - ldp x0, x1, [sp], #16 - switch_el x3, 3f, 2f, 1f -3: - msr spsr_el3, x0 - msr elr_el3, x1 - b 0f -2: - msr spsr_el2, x0 - msr elr_el2, x1 - b 0f -1: - msr spsr_el1, x0 - msr elr_el1, x1 -0: - /* - * In x30 we can have: - * - * - The address of irq_unlock() in swap.c when swapping in a thread - * that was cooperatively swapped out (used by ret in - * z_arm64_call_svc()) - * - A previos generic value if the thread that we are swapping in was - * swapped out preemptively by the ISR. - */ - ldp x18, x30, [sp], #16 - ldp x16, x17, [sp], #16 - ldp x14, x15, [sp], #16 - ldp x12, x13, [sp], #16 - ldp x10, x11, [sp], #16 - ldp x8, x9, [sp], #16 - ldp x6, x7, [sp], #16 - ldp x4, x5, [sp], #16 - ldp x2, x3, [sp], #16 - ldp x0, x1, [sp], #16 +.macro z_arm64_exit_exc xreg0, xreg1 + ldp \xreg0, \xreg1, [sp, ___esf_t_spsr_elr_OFFSET] + msr spsr_el1, \xreg0 + msr elr_el1, \xreg1 + + ldp x18, x30, [sp, ___esf_t_x18_x30_OFFSET] + ldp x16, x17, [sp, ___esf_t_x16_x17_OFFSET] + ldp x14, x15, [sp, ___esf_t_x14_x15_OFFSET] + ldp x12, x13, [sp, ___esf_t_x12_x13_OFFSET] + ldp x10, x11, [sp, ___esf_t_x10_x11_OFFSET] + ldp x8, x9, [sp, ___esf_t_x8_x9_OFFSET] + ldp x6, x7, [sp, ___esf_t_x6_x7_OFFSET] + ldp x4, x5, [sp, ___esf_t_x4_x5_OFFSET] + ldp x2, x3, [sp, ___esf_t_x2_x3_OFFSET] + ldp x0, x1, [sp, ___esf_t_x0_x1_OFFSET] + add sp, sp, ___esf_t_SIZEOF /* - * In general in the ELR_ELn register we can find: + * In general in the ELR_EL1 register we can find: * - * - The address of ret in z_arm64_call_svc() in case of arch_swap() - * (see swap.c) + * - The address of ret in z_arm64_call_svc() * - The address of the next instruction at the time of the IRQ when the * thread was switched out. * - The address of z_thread_entry() for new threads (see thread.c). @@ -122,6 +82,28 @@ eret .endm +/* + * Increment nested counter + */ + +.macro inc_nest_counter xreg0, xreg1 + ldr \xreg0, =_kernel + ldr \xreg1, [\xreg0, #_kernel_offset_to_nested] + add \xreg1, \xreg1, #1 + str \xreg1, [\xreg0, #_kernel_offset_to_nested] +.endm + +/* + * Decrement nested counter + */ + +.macro dec_nest_counter xreg0, xreg1 + ldr \xreg0, =_kernel + ldr \xreg1, [\xreg0, #_kernel_offset_to_nested] + sub \xreg1, \xreg1, #1 + str \xreg1, [\xreg0, #_kernel_offset_to_nested] +.endm + #endif /* _ASMLANGUAGE */ #endif /* _MACRO_PRIV_INC_ */ diff --git a/arch/arm/core/aarch64/mmu/CMakeLists.txt b/arch/arm/core/aarch64/mmu/CMakeLists.txt new file mode 100644 index 00000000000000..5356b078bc3b9c --- /dev/null +++ b/arch/arm/core/aarch64/mmu/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(arm_mmu.c) diff --git a/arch/arm/core/aarch64/mmu/arm_mmu.c b/arch/arm/core/aarch64/mmu/arm_mmu.c new file mode 100644 index 00000000000000..6472d0949c39ac --- /dev/null +++ b/arch/arm/core/aarch64/mmu/arm_mmu.c @@ -0,0 +1,402 @@ +/* + * Copyright 2019 Broadcom + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "arm_mmu.h" + +static uint64_t base_xlat_table[BASE_XLAT_NUM_ENTRIES] + __aligned(BASE_XLAT_NUM_ENTRIES * sizeof(uint64_t)); + +static uint64_t xlat_tables[CONFIG_MAX_XLAT_TABLES][Ln_XLAT_NUM_ENTRIES] + __aligned(Ln_XLAT_NUM_ENTRIES * sizeof(uint64_t)); + +/* Translation table control register settings */ +static uint64_t get_tcr(int el) +{ + uint64_t tcr; + uint64_t va_bits = CONFIG_ARM64_VA_BITS; + uint64_t tcr_ps_bits; + + tcr_ps_bits = TCR_PS_BITS; + + if (el == 1) { + tcr = (tcr_ps_bits << TCR_EL1_IPS_SHIFT); + /* + * TCR_EL1.EPD1: Disable translation table walk for addresses + * that are translated using TTBR1_EL1. + */ + tcr |= TCR_EPD1_DISABLE; + } else + tcr = (tcr_ps_bits << TCR_EL3_PS_SHIFT); + + tcr |= TCR_T0SZ(va_bits); + /* + * Translation table walk is cacheable, inner/outer WBWA and + * inner shareable + */ + tcr |= TCR_TG0_4K | TCR_SHARED_INNER | TCR_ORGN_WBWA | TCR_IRGN_WBWA; + + return tcr; +} + +static int pte_desc_type(uint64_t *pte) +{ + return *pte & PTE_DESC_TYPE_MASK; +} + +static uint64_t *calculate_pte_index(uint64_t addr, int level) +{ + int base_level = BASE_XLAT_LEVEL; + uint64_t *pte; + uint64_t idx; + unsigned int i; + + /* Walk through all translation tables to find pte index */ + pte = (uint64_t *)base_xlat_table; + for (i = base_level; i < XLAT_LEVEL_MAX; i++) { + idx = XLAT_TABLE_VA_IDX(addr, i); + pte += idx; + + /* Found pte index */ + if (i == level) + return pte; + /* if PTE is not table desc, can't traverse */ + if (pte_desc_type(pte) != PTE_TABLE_DESC) + return NULL; + /* Move to the next translation table level */ + pte = (uint64_t *)(*pte & 0x0000fffffffff000ULL); + } + + return NULL; +} + +static void set_pte_table_desc(uint64_t *pte, uint64_t *table, unsigned int level) +{ +#if DUMP_PTE + MMU_DEBUG("%s", XLAT_TABLE_LEVEL_SPACE(level)); + MMU_DEBUG("%p: [Table] %p\n", pte, table); +#endif + /* Point pte to new table */ + *pte = PTE_TABLE_DESC | (uint64_t)table; +} + +static void set_pte_block_desc(uint64_t *pte, uint64_t addr_pa, + unsigned int attrs, unsigned int level) +{ + uint64_t desc = addr_pa; + unsigned int mem_type; + + desc |= (level == 3) ? PTE_PAGE_DESC : PTE_BLOCK_DESC; + + /* NS bit for security memory access from secure state */ + desc |= (attrs & MT_NS) ? PTE_BLOCK_DESC_NS : 0; + + /* + * AP bits for EL0 / ELh Data access permission + * + * AP[2:1] ELh EL0 + * +--------------------+ + * 00 RW NA + * 01 RW RW + * 10 RO NA + * 11 RO RO + */ + + /* AP bits for Data access permission */ + desc |= (attrs & MT_RW) ? PTE_BLOCK_DESC_AP_RW : PTE_BLOCK_DESC_AP_RO; + + /* Mirror permissions to EL0 */ + desc |= (attrs & MT_RW_AP_ELx) ? + PTE_BLOCK_DESC_AP_ELx : PTE_BLOCK_DESC_AP_EL_HIGHER; + + /* the access flag */ + desc |= PTE_BLOCK_DESC_AF; + + /* memory attribute index field */ + mem_type = MT_TYPE(attrs); + desc |= PTE_BLOCK_DESC_MEMTYPE(mem_type); + + switch (mem_type) { + case MT_DEVICE_nGnRnE: + case MT_DEVICE_nGnRE: + case MT_DEVICE_GRE: + /* Access to Device memory and non-cacheable memory are coherent + * for all observers in the system and are treated as + * Outer shareable, so, for these 2 types of memory, + * it is not strictly needed to set shareability field + */ + desc |= PTE_BLOCK_DESC_OUTER_SHARE; + /* Map device memory as execute-never */ + desc |= PTE_BLOCK_DESC_PXN; + desc |= PTE_BLOCK_DESC_UXN; + break; + case MT_NORMAL_NC: + case MT_NORMAL: + /* Make Normal RW memory as execute never */ + if ((attrs & MT_RW) || (attrs & MT_P_EXECUTE_NEVER)) + desc |= PTE_BLOCK_DESC_PXN; + + if (((attrs & MT_RW) && (attrs & MT_RW_AP_ELx)) || + (attrs & MT_U_EXECUTE_NEVER)) + desc |= PTE_BLOCK_DESC_UXN; + + if (mem_type == MT_NORMAL) + desc |= PTE_BLOCK_DESC_INNER_SHARE; + else + desc |= PTE_BLOCK_DESC_OUTER_SHARE; + } + +#if DUMP_PTE + MMU_DEBUG("%s", XLAT_TABLE_LEVEL_SPACE(level)); + MMU_DEBUG("%p: ", pte); + MMU_DEBUG((mem_type == MT_NORMAL) ? "MEM" : + ((mem_type == MT_NORMAL_NC) ? "NC" : "DEV")); + MMU_DEBUG((attrs & MT_RW) ? "-RW" : "-RO"); + MMU_DEBUG((attrs & MT_NS) ? "-NS" : "-S"); + MMU_DEBUG((attrs & MT_RW_AP_ELx) ? "-ELx" : "-ELh"); + MMU_DEBUG((attrs & MT_P_EXECUTE_NEVER) ? "-PXN" : "-PX"); + MMU_DEBUG((attrs & MT_U_EXECUTE_NEVER) ? "-UXN" : "-UX"); + MMU_DEBUG("\n"); +#endif + + *pte = desc; +} + +/* Returns a new reallocated table */ +static uint64_t *new_prealloc_table(void) +{ + static unsigned int table_idx; + + __ASSERT(table_idx < CONFIG_MAX_XLAT_TABLES, + "Enough xlat tables not allocated"); + + return (uint64_t *)(xlat_tables[table_idx++]); +} + +/* Splits a block into table with entries spanning the old block */ +static void split_pte_block_desc(uint64_t *pte, int level) +{ + uint64_t old_block_desc = *pte; + uint64_t *new_table; + unsigned int i = 0; + /* get address size shift bits for next level */ + int levelshift = LEVEL_TO_VA_SIZE_SHIFT(level + 1); + + MMU_DEBUG("Splitting existing PTE %p(L%d)\n", pte, level); + + new_table = new_prealloc_table(); + + for (i = 0; i < Ln_XLAT_NUM_ENTRIES; i++) { + new_table[i] = old_block_desc | (i << levelshift); + + if ((level + 1) == 3) + new_table[i] |= PTE_PAGE_DESC; + } + + /* Overwrite existing PTE set the new table into effect */ + set_pte_table_desc(pte, new_table, level); +} + +/* Create/Populate translation table(s) for given region */ +static void init_xlat_tables(const struct arm_mmu_region *region) +{ + uint64_t *pte; + uint64_t virt = region->base_va; + uint64_t phys = region->base_pa; + uint64_t size = region->size; + uint64_t attrs = region->attrs; + uint64_t level_size; + uint64_t *new_table; + unsigned int level = BASE_XLAT_LEVEL; + + MMU_DEBUG("mmap: virt %llx phys %llx size %llx\n", virt, phys, size); + /* check minimum alignment requirement for given mmap region */ + __ASSERT(((virt & (PAGE_SIZE - 1)) == 0) && + ((size & (PAGE_SIZE - 1)) == 0), + "address/size are not page aligned\n"); + + while (size) { + __ASSERT(level < XLAT_LEVEL_MAX, + "max translation table level exceeded\n"); + + /* Locate PTE for given virtual address and page table level */ + pte = calculate_pte_index(virt, level); + __ASSERT(pte != NULL, "pte not found\n"); + + level_size = 1ULL << LEVEL_TO_VA_SIZE_SHIFT(level); + + if (size >= level_size && !(virt & (level_size - 1))) { + /* Given range fits into level size, + * create block/page descriptor + */ + set_pte_block_desc(pte, phys, attrs, level); + virt += level_size; + phys += level_size; + size -= level_size; + /* Range is mapped, start again for next range */ + level = BASE_XLAT_LEVEL; + } else if (pte_desc_type(pte) == PTE_INVALID_DESC) { + /* Range doesn't fit, create subtable */ + new_table = new_prealloc_table(); + set_pte_table_desc(pte, new_table, level); + level++; + } else if (pte_desc_type(pte) == PTE_BLOCK_DESC) { + split_pte_block_desc(pte, level); + level++; + } else if (pte_desc_type(pte) == PTE_TABLE_DESC) + level++; + } +} + +/* zephyr execution regions with appropriate attributes */ +static const struct arm_mmu_region mmu_zephyr_regions[] = { + + /* Mark the whole SRAM as read-write */ + MMU_REGION_FLAT_ENTRY("SRAM", + (uintptr_t)CONFIG_SRAM_BASE_ADDRESS, + (uintptr_t)KB(CONFIG_SRAM_SIZE), + MT_NORMAL | MT_P_RW_U_NA | MT_SECURE), + + /* Mark rest of the zephyr execution regions (data, bss, noinit, etc.) + * cacheable, read-write + * Note: read-write region is marked execute-ever internally + */ + MMU_REGION_FLAT_ENTRY("zephyr_data", + (uintptr_t)__kernel_ram_start, + (uintptr_t)__kernel_ram_size, + MT_NORMAL | MT_P_RW_U_NA | MT_SECURE), + + /* Mark text segment cacheable,read only and executable */ + MMU_REGION_FLAT_ENTRY("zephyr_code", + (uintptr_t)_image_text_start, + (uintptr_t)_image_text_size, + MT_NORMAL | MT_P_RX_U_NA | MT_SECURE), + + /* Mark rodata segment cacheable, read only and execute-never */ + MMU_REGION_FLAT_ENTRY("zephyr_rodata", + (uintptr_t)_image_rodata_start, + (uintptr_t)_image_rodata_size, + MT_NORMAL | MT_P_RO_U_NA | MT_SECURE), +}; + +static void setup_page_tables(void) +{ + unsigned int index; + const struct arm_mmu_region *region; + uint64_t max_va = 0, max_pa = 0; + + for (index = 0; index < mmu_config.num_regions; index++) { + region = &mmu_config.mmu_regions[index]; + max_va = MAX(max_va, region->base_va + region->size); + max_pa = MAX(max_pa, region->base_pa + region->size); + } + + __ASSERT(max_va <= (1ULL << CONFIG_ARM64_VA_BITS), + "Maximum VA not supported\n"); + __ASSERT(max_pa <= (1ULL << CONFIG_ARM64_PA_BITS), + "Maximum PA not supported\n"); + + /* create translation tables for user provided platform regions */ + for (index = 0; index < mmu_config.num_regions; index++) { + region = &mmu_config.mmu_regions[index]; + if (region->size || region->attrs) + init_xlat_tables(region); + } + + /* setup translation table for zephyr execution regions */ + for (index = 0; index < ARRAY_SIZE(mmu_zephyr_regions); index++) { + region = &mmu_zephyr_regions[index]; + if (region->size || region->attrs) + init_xlat_tables(region); + } +} + +static void enable_mmu_el1(unsigned int flags) +{ + ARG_UNUSED(flags); + uint64_t val; + + /* Set MAIR, TCR and TBBR registers */ + __asm__ volatile("msr mair_el1, %0" + : + : "r" (MEMORY_ATTRIBUTES) + : "memory", "cc"); + __asm__ volatile("msr tcr_el1, %0" + : + : "r" (get_tcr(1)) + : "memory", "cc"); + __asm__ volatile("msr ttbr0_el1, %0" + : + : "r" ((uint64_t)base_xlat_table) + : "memory", "cc"); + + /* Ensure these changes are seen before MMU is enabled */ + __ISB(); + + /* Enable the MMU and data cache */ + __asm__ volatile("mrs %0, sctlr_el1" : "=r" (val)); + __asm__ volatile("msr sctlr_el1, %0" + : + : "r" (val | SCTLR_M | SCTLR_C) + : "memory", "cc"); + + /* Ensure the MMU enable takes effect immediately */ + __ISB(); + + MMU_DEBUG("MMU enabled with dcache\n"); +} + +/* ARM MMU Driver Initial Setup */ + +/* + * @brief MMU default configuration + * + * This function provides the default configuration mechanism for the Memory + * Management Unit (MMU). + */ +static int arm_mmu_init(const struct device *arg) +{ + uint64_t val; + unsigned int idx, flags = 0; + + /* Current MMU code supports only EL1 */ + __asm__ volatile("mrs %0, CurrentEL" : "=r" (val)); + + __ASSERT(GET_EL(val) == MODE_EL1, + "Exception level not EL1, MMU not enabled!\n"); + + /* Ensure that MMU is already not enabled */ + __asm__ volatile("mrs %0, sctlr_el1" : "=r" (val)); + __ASSERT((val & SCTLR_M) == 0, "MMU is already enabled\n"); + + MMU_DEBUG("xlat tables:\n"); + MMU_DEBUG("base table(L%d): %p, %d entries\n", BASE_XLAT_LEVEL, + (uint64_t *)base_xlat_table, BASE_XLAT_NUM_ENTRIES); + for (idx = 0; idx < CONFIG_MAX_XLAT_TABLES; idx++) + MMU_DEBUG("%d: %p\n", idx, (uint64_t *)(xlat_tables + idx)); + + setup_page_tables(); + + /* currently only EL1 is supported */ + enable_mmu_el1(flags); + + return 0; +} + +SYS_INIT(arm_mmu_init, PRE_KERNEL_1, +#if MMU_DEBUG_PRINTS + MMU_DEBUG_PRIORITY +#else + CONFIG_KERNEL_INIT_PRIORITY_DEVICE +#endif +); diff --git a/arch/arm/core/aarch64/mmu/arm_mmu.h b/arch/arm/core/aarch64/mmu/arm_mmu.h new file mode 100644 index 00000000000000..b40131a18f6a62 --- /dev/null +++ b/arch/arm/core/aarch64/mmu/arm_mmu.h @@ -0,0 +1,111 @@ +/* + * Copyright 2019 Broadcom + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Set below flag to get debug prints */ +#define MMU_DEBUG_PRINTS 0 + +/* To get prints from MMU driver, it has to initialized after console driver */ +#define MMU_DEBUG_PRIORITY 70 + +#if MMU_DEBUG_PRINTS +/* To dump page table entries while filling them, set DUMP_PTE macro */ +#define DUMP_PTE 0 +#define MMU_DEBUG(fmt, ...) printk(fmt, ##__VA_ARGS__) +#else +#define MMU_DEBUG(...) +#endif + +#if DUMP_PTE +#define L0_SPACE "" +#define L1_SPACE " " +#define L2_SPACE " " +#define L3_SPACE " " +#define XLAT_TABLE_LEVEL_SPACE(level) \ + (((level) == 0) ? L0_SPACE : \ + ((level) == 1) ? L1_SPACE : \ + ((level) == 2) ? L2_SPACE : L3_SPACE) +#endif + +/* + * 48-bit address with 4KB granule size: + * + * +------------+------------+------------+------------+-----------+ + * | VA [47:39] | VA [38:30] | VA [29:21] | VA [20:12] | VA [11:0] | + * +---------------------------------------------------------------+ + * | L0 | L1 | L2 | L3 | block off | + * +------------+------------+------------+------------+-----------+ + */ + +/* Only 4K granule is supported */ +#define PAGE_SIZE_SHIFT 12U +#define PAGE_SIZE (1U << PAGE_SIZE_SHIFT) + +/* 48-bit VA address */ +#define VA_SIZE_SHIFT_MAX 48U + +/* Maximum 4 XLAT table (L0 - L3) */ +#define XLAT_LEVEL_MAX 4U + +/* The VA shift of L3 depends on the granule size */ +#define L3_XLAT_VA_SIZE_SHIFT PAGE_SIZE_SHIFT + +/* Number of VA bits to assign to each table (9 bits) */ +#define Ln_XLAT_VA_SIZE_SHIFT ((VA_SIZE_SHIFT_MAX - L3_XLAT_VA_SIZE_SHIFT) / \ + XLAT_LEVEL_MAX) + +/* Starting bit in the VA address for each level */ +#define L2_XLAT_VA_SIZE_SHIFT (L3_XLAT_VA_SIZE_SHIFT + Ln_XLAT_VA_SIZE_SHIFT) +#define L1_XLAT_VA_SIZE_SHIFT (L2_XLAT_VA_SIZE_SHIFT + Ln_XLAT_VA_SIZE_SHIFT) +#define L0_XLAT_VA_SIZE_SHIFT (L1_XLAT_VA_SIZE_SHIFT + Ln_XLAT_VA_SIZE_SHIFT) + +#define LEVEL_TO_VA_SIZE_SHIFT(level) \ + (PAGE_SIZE_SHIFT + (Ln_XLAT_VA_SIZE_SHIFT * \ + ((XLAT_LEVEL_MAX - 1) - (level)))) + +/* Number of entries for each table (512) */ +#define Ln_XLAT_NUM_ENTRIES (1U << Ln_XLAT_VA_SIZE_SHIFT) + +/* Virtual Address Index within a given translation table level */ +#define XLAT_TABLE_VA_IDX(va_addr, level) \ + ((va_addr >> LEVEL_TO_VA_SIZE_SHIFT(level)) & (Ln_XLAT_NUM_ENTRIES - 1)) + +/* + * Calculate the initial translation table level from CONFIG_ARM64_VA_BITS + * For a 4 KB page size: + * + * (va_bits <= 20) - base level 3 + * (21 <= va_bits <= 29) - base level 2 + * (30 <= va_bits <= 38) - base level 1 + * (39 <= va_bits <= 47) - base level 0 + */ +#define GET_BASE_XLAT_LEVEL(va_bits) \ + ((va_bits > L0_XLAT_VA_SIZE_SHIFT) ? 0U \ + : (va_bits > L1_XLAT_VA_SIZE_SHIFT) ? 1U \ + : (va_bits > L2_XLAT_VA_SIZE_SHIFT) ? 2U : 3U) + +/* Level for the base XLAT */ +#define BASE_XLAT_LEVEL GET_BASE_XLAT_LEVEL(CONFIG_ARM64_VA_BITS) + +#define GET_BASE_XLAT_NUM_ENTRIES(va_bits) \ + (1U << (va_bits - LEVEL_TO_VA_SIZE_SHIFT(BASE_XLAT_LEVEL))) + +/* Table size for the first level XLAT */ +#define BASE_XLAT_NUM_ENTRIES GET_BASE_XLAT_NUM_ENTRIES(CONFIG_ARM64_VA_BITS) + +#if (CONFIG_ARM64_PA_BITS == 48) +#define TCR_PS_BITS TCR_PS_BITS_256TB +#elif (CONFIG_ARM64_PA_BITS == 44) +#define TCR_PS_BITS TCR_PS_BITS_16TB +#elif (CONFIG_ARM64_PA_BITS == 42) +#define TCR_PS_BITS TCR_PS_BITS_4TB +#elif (CONFIG_ARM64_PA_BITS == 40) +#define TCR_PS_BITS TCR_PS_BITS_1TB +#elif (CONFIG_ARM64_PA_BITS == 36) +#define TCR_PS_BITS TCR_PS_BITS_64GB +#else +#define TCR_PS_BITS TCR_PS_BITS_4GB +#endif diff --git a/arch/arm/core/aarch64/reset.S b/arch/arm/core/aarch64/reset.S index 0d968f60c4cf2a..3a97be8a6da211 100644 --- a/arch/arm/core/aarch64/reset.S +++ b/arch/arm/core/aarch64/reset.S @@ -4,9 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -/** - * @file - * @brief Reset handler +/* + * Reset handler * * Reset handler that prepares the system for running C code. */ @@ -22,15 +21,15 @@ _ASM_FILE_PROLOGUE /* * Platform may do platform specific init at EL3. * The function implementation must preserve callee saved registers as per - * Aarch64 ABI PCS. + * AArch64 ABI PCS. */ + WTEXT(z_arch_el3_plat_init) SECTION_FUNC(TEXT,z_arch_el3_plat_init) ret -/** - * - * @brief Reset vector +/* + * Reset vector * * Ran when the system comes out of reset. The processor is in thread mode with * privileged level. At this point, neither SP_EL0 nor SP_ELx point to a valid @@ -38,18 +37,11 @@ ret * * When these steps are completed, jump to z_arm64_prep_c(), which will finish * setting up the system for running C code. - * - * @return N/A */ + GTEXT(__reset) SECTION_SUBSEC_FUNC(TEXT,_reset_section,__reset) -/* - * The entry point is located at the __reset symbol, which is fetched by a XIP - * image playing the role of a bootloader, which jumps to it, not through the - * reset vector mechanism. Such bootloaders might want to search for a __start - * symbol instead, so create that alias here. - */ GTEXT(__start) SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) @@ -58,26 +50,33 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) switch_el x1, 3f, 2f, 1f 3: + /* + * Zephyr entry happened in EL3. Do EL3 specific init before + * dropping to lower EL. + */ + /* Initialize VBAR */ msr vbar_el3, x19 isb - /* Initialize sctlr_el3 to reset value */ + /* Switch to SP_EL0 and setup the stack */ + msr spsel, #0 + + ldr x0, =(z_interrupt_stacks) + add x0, x0, #(CONFIG_ISR_STACK_SIZE) + mov sp, x0 + + /* Initialize SCTLR_EL3 to reset value */ mov_imm x1, SCTLR_EL3_RES1 mrs x0, sctlr_el3 orr x0, x0, x1 msr sctlr_el3, x0 isb - /* SError, IRQ and FIQ routing enablement in EL3 */ - mrs x0, scr_el3 - orr x0, x0, #(SCR_EL3_IRQ | SCR_EL3_FIQ | SCR_EL3_EA) - msr scr_el3, x0 - /* - * Disable access traps to EL3 for CPACR, Trace, FP, ASIMD, - * SVE from lower EL. - */ + * Disable access traps to EL3 for CPACR, Trace, FP, ASIMD, + * SVE from lower EL. + */ mov_imm x0, CPTR_EL3_RES_VAL mov_imm x1, (CPTR_EL3_TTA | CPTR_EL3_TFP | CPTR_EL3_TCPAC) bic x0, x0, x1 @@ -88,11 +87,6 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) /* Platform specific configurations needed in EL3 */ bl z_arch_el3_plat_init -#ifdef CONFIG_SWITCH_TO_EL1 - /* - * Zephyr entry happened in EL3. Do EL3 specific init before - * dropping to lower EL. - */ /* Enable access control configuration from lower EL */ mrs x0, actlr_el3 orr x0, x0, #(ACTLR_EL3_L2ACTLR | ACTLR_EL3_L2ECTLR \ @@ -100,7 +94,7 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) orr x0, x0, #(ACTLR_EL3_CPUACTLR | ACTLR_EL3_CPUECTLR) msr actlr_el3, x0 - /* Initialize sctlr_el1 to reset value */ + /* Initialize SCTLR_EL1 to reset value */ mov_imm x0, SCTLR_EL1_RES1 msr sctlr_el1, x0 @@ -119,52 +113,29 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) adr x0, 1f msr elr_el3, x0 eret -#endif - /* - * Enable the instruction cache, stack pointer and data access - * alignment checks. - */ - mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT) - mrs x0, sctlr_el3 - orr x0, x0, x1 - msr sctlr_el3, x0 - isb - b 0f 2: - /* Initialize VBAR */ - msr vbar_el2, x19 - - /* SError, IRQ and FIQ routing enablement in EL2 */ - mrs x0, hcr_el2 - orr x0, x0, #(HCR_EL2_FMO | HCR_EL2_IMO | HCR_EL2_AMO) - msr hcr_el2, x0 - - /* Disable access trapping in EL2 for NEON/FP */ - msr cptr_el2, xzr - - /* - * Enable the instruction cache, stack pointer and data access - * alignment checks. - */ - mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT) - mrs x0, sctlr_el2 - orr x0, x0, x1 - msr sctlr_el2, x0 - b 0f + /* Booting from EL2 is not supported */ + b . 1: /* Initialize VBAR */ msr vbar_el1, x19 + isb + + /* Switch to SP_EL0 and setup the stack */ + msr spsel, #0 + + ldr x0, =(z_interrupt_stacks) + add x0, x0, #(CONFIG_ISR_STACK_SIZE) + mov sp, x0 /* Disable access trapping in EL1 for NEON/FP */ - mov x0, #(CPACR_EL1_FPEN_NOTRAP) + mov_imm x0, CPACR_EL1_FPEN_NOTRAP msr cpacr_el1, x0 - /* - * Enable the instruction cache and el1 stack alignment check. - */ - mov x1, #(SCTLR_I_BIT | SCTLR_SA_BIT) + /* Enable the instruction cache and EL1 stack alignment check. */ + mov_imm x1, (SCTLR_I | SCTLR_SA) mrs x0, sctlr_el1 orr x0, x0, x1 msr sctlr_el1, x0 @@ -175,10 +146,4 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) /* Enable the SError interrupt */ msr daifclr, #(DAIFSET_ABT) - /* Switch to SP_ELn and setup the stack */ - msr spsel, #1 - ldr x0, =(z_interrupt_stacks) - add x0, x0, #(CONFIG_ISR_STACK_SIZE) - mov sp, x0 - bl z_arm64_prep_c diff --git a/arch/arm/core/aarch64/swap.c b/arch/arm/core/aarch64/swap.c deleted file mode 100644 index 32cffd9cd392ce..00000000000000 --- a/arch/arm/core/aarch64/swap.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2019 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -extern const int _k_neg_eagain; - -int arch_swap(unsigned int key) -{ - _current->arch.swap_return_value = _k_neg_eagain; - - z_arm64_call_svc(); - irq_unlock(key); - - /* Context switch is performed here. Returning implies the - * thread has been context-switched-in again. - */ - return _current->arch.swap_return_value; -} diff --git a/arch/arm/core/aarch64/swap_helper.S b/arch/arm/core/aarch64/swap_helper.S deleted file mode 100644 index 0496157d0c7b0e..00000000000000 --- a/arch/arm/core/aarch64/swap_helper.S +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2019 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Thread context switching for ARM64 Cortex-A - * - * This module implements the routines necessary for thread context switching - * on ARM64 Cortex-A. - */ - -#include -#include -#include -#include -#include -#include "macro_priv.inc" - -_ASM_FILE_PROLOGUE - -GDATA(_kernel) -GDATA(_k_neg_eagain) - -/** - * @brief Routine to handle context switches - * - * This function is directly called either by _isr_wrapper() in case of - * preemption, or z_arm64_svc() in case of cooperative switching. - */ - -GTEXT(z_arm64_context_switch) -SECTION_FUNC(TEXT, z_arm64_context_switch) -#ifdef CONFIG_TRACING - stp xzr, x30, [sp, #-16]! - bl sys_trace_thread_switched_in - ldp xzr, x30, [sp], #16 -#endif - /* load _kernel into x1 and current k_thread into x2 */ - ldr x1, =_kernel - ldr x2, [x1, #_kernel_offset_to_current] - - /* addr of callee-saved regs in thread in x0 */ - ldr x0, =_thread_offset_to_callee_saved - add x0, x0, x2 - - /* Store rest of process context including x30 */ - stp x19, x20, [x0], #16 - stp x21, x22, [x0], #16 - stp x23, x24, [x0], #16 - stp x25, x26, [x0], #16 - stp x27, x28, [x0], #16 - stp x29, x30, [x0], #16 - - /* Save the current SP */ - mov x6, sp - str x6, [x0] - - /* fetch the thread to run from the ready queue cache */ - ldr x2, [x1, #_kernel_offset_to_ready_q_cache] - str x2, [x1, #_kernel_offset_to_current] - - /* addr of callee-saved regs in thread in x0 */ - ldr x0, =_thread_offset_to_callee_saved - add x0, x0, x2 - - /* Restore x19-x29 plus x30 */ - ldp x19, x20, [x0], #16 - ldp x21, x22, [x0], #16 - ldp x23, x24, [x0], #16 - ldp x25, x26, [x0], #16 - ldp x27, x28, [x0], #16 - ldp x29, x30, [x0], #16 - - ldr x6, [x0] - mov sp, x6 - -#ifdef CONFIG_TRACING - stp xzr, x30, [sp, #-16]! - bl sys_trace_thread_switched_out - ldp xzr, x30, [sp], #16 -#endif - - /* We restored x30 from the process stack. There are three possible - * cases: - * - * - We return to z_arm64_svc() when swapping in a thread that was - * swapped out by z_arm64_svc() before jumping into - * z_arm64_exit_exc() - * - We return to _isr_wrapper() when swapping in a thread that was - * swapped out by _isr_wrapper() before jumping into - * z_arm64_exit_exc() - * - We return (jump) into z_thread_entry_wrapper() for new threads - * (see thread.c) - */ - ret - -/** - * - * @brief Entry wrapper for new threads - * - * @return N/A - */ - -GTEXT(z_thread_entry_wrapper) -SECTION_FUNC(TEXT, z_thread_entry_wrapper) - /* - * Restore SPSR_ELn and ELR_ELn saved in the temporary stack by - * arch_new_thread() - */ - ldp x0, x1, [sp], #16 - switch_el x3, 3f, 2f, 1f -3: - msr spsr_el3, x0 - msr elr_el3, x1 - b 0f -2: - msr spsr_el2, x0 - msr elr_el2, x1 - b 0f -1: - msr spsr_el1, x0 - msr elr_el1, x1 -0: - /* - * z_thread_entry_wrapper is called for every new thread upon the return - * of arch_swap() or ISR. Its address, as well as its input function - * arguments thread_entry_t, void *, void *, void * are restored from - * the thread stack (see thread.c). - * In this case, thread_entry_t, * void *, void * and void * are stored - * in registers x0, x1, x2 and x3. These registers are used as arguments - * to function z_thread_entry. - */ - ldp x0, x1, [sp], #16 - ldp x2, x3, [sp], #16 - - /* ELR_ELn was set in thread.c to z_thread_entry() */ - eret - -/** - * - * @brief Service call handler - * - * The service call (SVC) is used in the following occasions: - * - Cooperative context switching - * - IRQ offloading - * - * @return N/A - */ - -GTEXT(z_arm64_svc) -SECTION_FUNC(TEXT, z_arm64_svc) - z_arm64_enter_exc - - switch_el x3, 3f, 2f, 1f -3: - mrs x0, esr_el3 - b 0f -2: - mrs x0, esr_el2 - b 0f -1: - mrs x0, esr_el1 -0: - lsr x1, x0, #26 - - cmp x1, #0x15 /* 0x15 = SVC */ - bne inv - - /* Demux the SVC call */ - and x2, x0, #0xff - cmp x2, #_SVC_CALL_CONTEXT_SWITCH - beq context_switch - -#ifdef CONFIG_IRQ_OFFLOAD - cmp x2, #_SVC_CALL_IRQ_OFFLOAD - beq offload - b inv -offload: - /* ++(_kernel->nested) to be checked by arch_is_in_isr() */ - ldr x1, =_kernel - ldr x2, [x1, #_kernel_offset_to_nested] - add x2, x2, #1 - str x2, [x1, #_kernel_offset_to_nested] - - bl z_irq_do_offload - - /* --(_kernel->nested) */ - ldr x1, =_kernel - ldr x2, [x1, #_kernel_offset_to_nested] - sub x2, x2, #1 - str x2, [x1, #_kernel_offset_to_nested] - b exit -#endif - b inv - -context_switch: - /* Check if we need to context switch */ - ldr x1, =_kernel - ldr x2, [x1, #_kernel_offset_to_current] - ldr x3, [x1, #_kernel_offset_to_ready_q_cache] - cmp x2, x3 - beq exit - - /* Switch thread */ - bl z_arm64_context_switch - -exit: - z_arm64_exit_exc - -inv: - mov x1, sp - mov x0, #0 /* K_ERR_CPU_EXCEPTION */ - b z_arm64_fatal_error - -GTEXT(z_arm64_call_svc) -SECTION_FUNC(TEXT, z_arm64_call_svc) - svc #_SVC_CALL_CONTEXT_SWITCH - ret - -#ifdef CONFIG_IRQ_OFFLOAD -GTEXT(z_arm64_offload) -SECTION_FUNC(TEXT, z_arm64_offload) - svc #_SVC_CALL_IRQ_OFFLOAD - ret -#endif - diff --git a/arch/arm/core/aarch64/switch.S b/arch/arm/core/aarch64/switch.S new file mode 100644 index 00000000000000..29a53d5a532d58 --- /dev/null +++ b/arch/arm/core/aarch64/switch.S @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2019 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Thread context switching for ARM64 Cortex-A (AArch64) + * + * This module implements the routines necessary for thread context switching + * on ARM64 Cortex-A (AArch64) + */ + +#include +#include +#include +#include +#include +#include "macro_priv.inc" + +_ASM_FILE_PROLOGUE + +GDATA(_kernel) + +/* + * Routine to handle context switches + * + * This function is directly called either by _isr_wrapper() in case of + * preemption, or z_arm64_sync_exc() in case of cooperative switching. + */ + +GTEXT(z_arm64_context_switch) +SECTION_FUNC(TEXT, z_arm64_context_switch) + /* addr of callee-saved regs in thread in x2 */ + ldr x2, =_thread_offset_to_callee_saved + add x2, x2, x1 + + /* Save the current SP */ + mov x1, sp + + stp x19, x20, [x2, ___callee_saved_t_x19_x20_OFFSET] + stp x21, x22, [x2, ___callee_saved_t_x21_x22_OFFSET] + stp x23, x24, [x2, ___callee_saved_t_x23_x24_OFFSET] + stp x25, x26, [x2, ___callee_saved_t_x25_x26_OFFSET] + stp x27, x28, [x2, ___callee_saved_t_x27_x28_OFFSET] + stp x29, x1, [x2, ___callee_saved_t_x29_sp_OFFSET] + +#ifdef CONFIG_THREAD_LOCAL_STORAGE + /* Grab the TLS pointer */ + ldr x2, =_thread_offset_to_tls + add x2, x2, x0 + ldr x2, [x2] + + /* Store in the "Thread ID" register. + * This register is used as a base pointer to all + * thread variables with offsets added by toolchain. + */ + msr tpidr_el0, x2 +#endif + + /* addr of callee-saved regs in thread in x2 */ + ldr x2, =_thread_offset_to_callee_saved + add x2, x2, x0 + + ldp x19, x20, [x2, ___callee_saved_t_x19_x20_OFFSET] + ldp x21, x22, [x2, ___callee_saved_t_x21_x22_OFFSET] + ldp x23, x24, [x2, ___callee_saved_t_x23_x24_OFFSET] + ldp x25, x26, [x2, ___callee_saved_t_x25_x26_OFFSET] + ldp x27, x28, [x2, ___callee_saved_t_x27_x28_OFFSET] + ldp x29, x1, [x2, ___callee_saved_t_x29_sp_OFFSET] + + mov sp, x1 + +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + stp xzr, x30, [sp, #-16]! + bl z_thread_mark_switched_in + ldp xzr, x30, [sp], #16 +#endif + + /* Return to z_arm64_sync_exc() or _isr_wrapper() */ + ret + +/* + * Synchronous exceptions handler + * + * The service call (SVC) is used in the following occasions: + * - Cooperative context switching + * - IRQ offloading + */ + +GTEXT(z_arm64_sync_exc) +SECTION_FUNC(TEXT, z_arm64_sync_exc) + z_arm64_enter_exc x2, x3 + + mrs x0, esr_el1 + lsr x1, x0, #26 + + cmp x1, #0x15 /* 0x15 = SVC */ + bne inv + + /* Demux the SVC call */ + and x1, x0, #0xff + + cmp x1, #_SVC_CALL_CONTEXT_SWITCH + beq context_switch + + cmp x1, #_SVC_CALL_RUNTIME_EXCEPT + beq oops + +#ifdef CONFIG_IRQ_OFFLOAD + cmp x1, #_SVC_CALL_IRQ_OFFLOAD + beq offload + b inv +offload: + /* ++(_kernel->nested) to be checked by arch_is_in_isr() */ + inc_nest_counter x0, x1 + + bl z_irq_do_offload + + /* --(_kernel->nested) */ + dec_nest_counter x0, x1 + b exit +#endif + b inv + +oops: + mov x0, sp + b z_arm64_do_kernel_oops + +context_switch: + /* + * Retrieve x0 and x1 from the stack: + * + * - x0 = new_thread->switch_handle = switch_to thread + * - x1 = &old_thread->switch_handle = current thread + */ + ldp x0, x1, [sp, ___esf_t_x0_x1_OFFSET] + + /* Get old thread from x1 */ + sub x1, x1, ___thread_t_switch_handle_OFFSET + + /* Switch thread */ + bl z_arm64_context_switch + +exit: + z_arm64_exit_exc x0, x1 + +inv: + mov x0, #0 /* K_ERR_CPU_EXCEPTION */ + mov x1, sp + bl z_arm64_fatal_error + + /* Return here only in case of recoverable error */ + z_arm64_exit_exc x0, x1 + +GTEXT(z_arm64_call_svc) +SECTION_FUNC(TEXT, z_arm64_call_svc) + svc #_SVC_CALL_CONTEXT_SWITCH + ret + +#ifdef CONFIG_IRQ_OFFLOAD +GTEXT(z_arm64_offload) +SECTION_FUNC(TEXT, z_arm64_offload) + svc #_SVC_CALL_IRQ_OFFLOAD + ret +#endif + diff --git a/arch/arm/core/aarch64/thread.c b/arch/arm/core/aarch64/thread.c index 633359290b1c20..66e0aca00d4fa1 100644 --- a/arch/arm/core/aarch64/thread.c +++ b/arch/arm/core/aarch64/thread.c @@ -16,90 +16,45 @@ #include #include -/** - * - * @brief Initialize a new thread from its stack space - * - * The control structure (thread) is put at the lower address of the stack. An - * initial context, to be "restored" by z_arm64_context_switch(), is put at the - * other end of the stack, and thus reusable by the stack when not needed +/* + * An initial context, to be "restored" by z_arm64_context_switch(), is put at + * the other end of the stack, and thus reusable by the stack when not needed * anymore. - * - * is currently unused. - * - * @param stack pointer to the aligned stack memory - * @param stackSize size of the available stack memory in bytes - * @param pEntry the entry point - * @param parameter1 entry point to the first param - * @param parameter2 entry point to the second param - * @param parameter3 entry point to the third param - * @param priority thread priority - * @param options thread options: K_ESSENTIAL, K_FP_REGS - * - * @return N/A */ - -void z_thread_entry_wrapper(k_thread_entry_t k, void *p1, void *p2, void *p3); - -struct init_stack_frame { - /* top of the stack / most recently pushed */ - - /* SPSL_ELn and ELR_ELn */ - u64_t spsr; - u64_t elr; - - /* - * Used by z_thread_entry_wrapper. pulls these off the stack and - * into argument registers before calling z_thread_entry() - */ - u64_t entry_point; - u64_t arg1; - u64_t arg2; - u64_t arg3; - - /* least recently pushed */ -}; - void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - size_t stackSize, k_thread_entry_t pEntry, - void *parameter1, void *parameter2, void *parameter3, - int priority, unsigned int options) + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) { - char *pStackMem = Z_THREAD_STACK_BUFFER(stack); - char *stackEnd; - struct init_stack_frame *pInitCtx; - - stackEnd = pStackMem + stackSize; + z_arch_esf_t *pInitCtx; - z_new_thread_init(thread, pStackMem, stackSize); + pInitCtx = Z_STACK_PTR_TO_FRAME(struct __esf, stack_ptr); - pInitCtx = (struct init_stack_frame *)(Z_STACK_PTR_ALIGN(stackEnd - - sizeof(struct init_stack_frame))); - - pInitCtx->entry_point = (u64_t)pEntry; - pInitCtx->arg1 = (u64_t)parameter1; - pInitCtx->arg2 = (u64_t)parameter2; - pInitCtx->arg3 = (u64_t)parameter3; + pInitCtx->x0 = (uint64_t)entry; + pInitCtx->x1 = (uint64_t)p1; + pInitCtx->x2 = (uint64_t)p2; + pInitCtx->x3 = (uint64_t)p3; /* - * - ELR_ELn: to be used by eret in z_thread_entry_wrapper() to return - * to z_thread_entry() with pEntry in x0(entry_point) and the parameters - * already in place in x1(arg1), x2(arg2), x3(arg3). - * - SPSR_ELn: to enable IRQs (we are masking debug exceptions, SError - * interrupts and FIQs). + * - ELR_ELn: to be used by eret in z_arm64_exit_exc() to return + * to z_thread_entry() with entry in x0(entry_point) and the + * parameters already in place in x1(arg1), x2(arg2), x3(arg3). + * - SPSR_ELn: to enable IRQs (we are masking FIQs). */ - pInitCtx->elr = (u64_t)z_thread_entry; - pInitCtx->spsr = SPSR_MODE_EL1H | DAIF_FIQ; + pInitCtx->elr = (uint64_t)z_thread_entry; + pInitCtx->spsr = SPSR_MODE_EL1T | DAIF_FIQ; /* - * We are saving: - * - * - SP: to pop out pEntry and parameters when going through - * z_thread_entry_wrapper(). - * - x30: to be used by ret in z_arm64_context_switch() when the new - * task is first scheduled. + * We are saving SP to pop out entry and parameters when going through + * z_arm64_exit_exc() */ + thread->callee_saved.sp = (uint64_t)pInitCtx; + + thread->switch_handle = thread; +} + +void *z_arch_get_next_switch_handle(struct k_thread **old_thread) +{ + *old_thread = _current; - thread->callee_saved.sp = (u64_t)pInitCtx; - thread->callee_saved.x30 = (u64_t)z_thread_entry_wrapper; + return z_get_next_switch_handle(*old_thread); } diff --git a/arch/arm/core/aarch64/vector_table.S b/arch/arm/core/aarch64/vector_table.S index cdaf54d003e7a4..5a0153fd373b52 100644 --- a/arch/arm/core/aarch64/vector_table.S +++ b/arch/arm/core/aarch64/vector_table.S @@ -4,14 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -/** - * @file - * @brief Populated vector table +/* + * Populated vector table */ #include #include #include +#include #include "vector_table.h" #include "macro_priv.inc" @@ -44,12 +44,12 @@ _ASM_FILE_PROLOGUE * | + 0x300 | FIQ / vFIQ | | * | + 0x380 | SError / vSError | | * +------------------+------------------+-------------------------+ - * | + 0x400 | Synchronous | Lower EL using AArch64 | + * | + 0x400 | Synchronous | Lower EL using AArch64 | * | + 0x480 | IRQ / vIRQ | | * | + 0x500 | FIQ / vFIQ | | * | + 0x580 | SError / vSError | | * +------------------+------------------+-------------------------+ - * | + 0x600 | Synchronous | Lower EL using AArch64 | + * | + 0x600 | Synchronous | Lower EL using AArch32 | * | + 0x680 | IRQ / vIRQ | | * | + 0x700 | FIQ / vFIQ | | * | + 0x780 | SError / vSError | | @@ -57,16 +57,21 @@ _ASM_FILE_PROLOGUE */ /* The whole table must be 2K aligned */ - .align 11 SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table) + .align 11 /* Current EL with SP0 / Synchronous */ .align 7 - b . + b z_arm64_sync_exc /* Current EL with SP0 / IRQ */ .align 7 - b . + +#ifdef CONFIG_GEN_SW_ISR_TABLE + b _isr_wrapper +#else + b z_irq_spurious +#endif /* Current EL with SP0 / FIQ */ .align 7 @@ -74,15 +79,20 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table) /* Current EL with SP0 / SError */ .align 7 - b . + b z_arm64_serror /* Current EL with SPx / Synchronous */ .align 7 - b z_arm64_svc + b z_arm64_sync_exc /* Current EL with SPx / IRQ */ .align 7 - b _isr_wrapper + +#ifdef CONFIG_GEN_SW_ISR_TABLE + b _isr_wrapper +#else + b z_irq_spurious +#endif /* Current EL with SPx / FIQ */ .align 7 @@ -90,10 +100,48 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table) /* Current EL with SPx / SError */ .align 7 - z_arm64_enter_exc + b z_arm64_serror + + /* Lower EL using AArch64 / Synchronous */ + .align 7 + b . + + /* Lower EL using AArch64 / IRQ */ + .align 7 + b . + + /* Lower EL using AArch64 / FIQ */ + .align 7 + b . + + /* Lower EL using AArch64 / SError */ + .align 7 + b . + + /* Lower EL using AArch32 / Synchronous */ + .align 7 + b . + + /* Lower EL using AArch32 / IRQ */ + .align 7 + b . + + /* Lower EL using AArch32 / FIQ */ + .align 7 + b . + + /* Lower EL using AArch32 / SError */ + .align 7 + b . + +GTEXT(z_arm64_serror) +SECTION_FUNC(TEXT, z_arm64_serror) + z_arm64_enter_exc x0, x1 mov x1, sp mov x0, #0 /* K_ERR_CPU_EXCEPTION */ - b z_arm64_fatal_error + bl z_arm64_fatal_error + /* Return here only in case of recoverable error */ + z_arm64_exit_exc x0, x1 diff --git a/arch/arm/core/aarch64/vector_table.h b/arch/arm/core/aarch64/vector_table.h index 056b10e96b94d1..35699d5d896914 100644 --- a/arch/arm/core/aarch64/vector_table.h +++ b/arch/arm/core/aarch64/vector_table.h @@ -27,7 +27,7 @@ #include GTEXT(__start) -GTEXT(_vector_table) +GDATA(_vector_table) GTEXT(_isr_wrapper) #else /* _ASMLANGUAGE */ diff --git a/arch/arm/core/common/tls.c b/arch/arm/core/common/tls.c new file mode 100644 index 00000000000000..37baeeedef1fb2 --- /dev/null +++ b/arch/arm/core/common/tls.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_CPU_CORTEX_M +/* + * Since Cortex-M does not have the thread ID or process ID + * register needed to store TLS pointer at runtime for + * toolchain to access thread data. Use a global variable + * instead. + */ +K_APP_DMEM(z_libc_partition) uintptr_t z_arm_tls_ptr; +#endif + +size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) +{ + /* + * TLS area for ARM has some data fields following by + * thread data and bss. These fields are supposed to be + * used by toolchain and OS TLS code to aid in locating + * the TLS data/bss. Zephyr currently has no use for + * this so we can simply skip these. However, since GCC + * is generating code assuming these fields are there, + * we simply skip them when setting the TLS pointer. + */ + + /* + * Since we are populating things backwards, + * setup the TLS data/bss area first. + */ + stack_ptr -= z_tls_data_size(); + z_tls_copy(stack_ptr); + + /* Skip two pointers due to toolchain */ + stack_ptr -= sizeof(uintptr_t) * 2; + + /* + * Set thread TLS pointer which is used in + * context switch to point to TLS area. + */ + new_thread->tls = POINTER_TO_UINT(stack_ptr); + + return (z_tls_data_size() + (sizeof(uintptr_t) * 2)); +} diff --git a/arch/arm/core/offsets/offsets_aarch32.c b/arch/arm/core/offsets/offsets_aarch32.c index 4a93a0ac647ea7..3ff2ecf15bb513 100644 --- a/arch/arm/core/offsets/offsets_aarch32.c +++ b/arch/arm/core/offsets/offsets_aarch32.c @@ -22,6 +22,9 @@ * completeness. */ +#ifndef _ARM_OFFSETS_INC_ +#define _ARM_OFFSETS_INC_ + #include #include #include @@ -88,3 +91,5 @@ GEN_ABSOLUTE_SYM(_K_THREAD_NO_FLOAT_SIZEOF, sizeof(struct k_thread) - #else GEN_ABSOLUTE_SYM(_K_THREAD_NO_FLOAT_SIZEOF, sizeof(struct k_thread)); #endif + +#endif /* _ARM_OFFSETS_INC_ */ diff --git a/arch/arm/core/offsets/offsets_aarch64.c b/arch/arm/core/offsets/offsets_aarch64.c index de20eac416d77f..13d3e020a5cd18 100644 --- a/arch/arm/core/offsets/offsets_aarch64.c +++ b/arch/arm/core/offsets/offsets_aarch64.c @@ -22,8 +22,34 @@ * completeness. */ +#ifndef _ARM_OFFSETS_INC_ +#define _ARM_OFFSETS_INC_ + #include #include #include -GEN_OFFSET_SYM(_thread_arch_t, swap_return_value); +GEN_NAMED_OFFSET_SYM(_callee_saved_t, x19, x19_x20); +GEN_NAMED_OFFSET_SYM(_callee_saved_t, x21, x21_x22); +GEN_NAMED_OFFSET_SYM(_callee_saved_t, x23, x23_x24); +GEN_NAMED_OFFSET_SYM(_callee_saved_t, x25, x25_x26); +GEN_NAMED_OFFSET_SYM(_callee_saved_t, x27, x27_x28); +GEN_NAMED_OFFSET_SYM(_callee_saved_t, x29, x29_sp); + +GEN_ABSOLUTE_SYM(___callee_saved_t_SIZEOF, sizeof(struct _callee_saved)); + +GEN_NAMED_OFFSET_SYM(_esf_t, spsr, spsr_elr); +GEN_NAMED_OFFSET_SYM(_esf_t, x18, x18_x30); +GEN_NAMED_OFFSET_SYM(_esf_t, x16, x16_x17); +GEN_NAMED_OFFSET_SYM(_esf_t, x14, x14_x15); +GEN_NAMED_OFFSET_SYM(_esf_t, x12, x12_x13); +GEN_NAMED_OFFSET_SYM(_esf_t, x10, x10_x11); +GEN_NAMED_OFFSET_SYM(_esf_t, x8, x8_x9); +GEN_NAMED_OFFSET_SYM(_esf_t, x6, x6_x7); +GEN_NAMED_OFFSET_SYM(_esf_t, x4, x4_x5); +GEN_NAMED_OFFSET_SYM(_esf_t, x2, x2_x3); +GEN_NAMED_OFFSET_SYM(_esf_t, x0, x0_x1); + +GEN_ABSOLUTE_SYM(___esf_t_SIZEOF, sizeof(_esf_t)); + +#endif /* _ARM_OFFSETS_INC_ */ diff --git a/arch/arm/include/aarch32/cortex_a_r/exc.h b/arch/arm/include/aarch32/cortex_a_r/exc.h index 155990be319b0d..1bc6fc9f463cc4 100644 --- a/arch/arm/include/aarch32/cortex_a_r/exc.h +++ b/arch/arm/include/aarch32/cortex_a_r/exc.h @@ -35,7 +35,7 @@ extern volatile irq_offload_routine_t offload_routine; /* Check the CPSR mode bits to see if we are in IRQ or FIQ mode */ static ALWAYS_INLINE bool arch_is_in_isr(void) { - return (_kernel.cpus[0].nested != 0); + return (_kernel.cpus[0].nested != 0U); } /** diff --git a/arch/arm/include/aarch32/cortex_m/cmse.h b/arch/arm/include/aarch32/cortex_m/cmse.h index 6aed9a520cd3dc..ff5e5120d8d392 100644 --- a/arch/arm/include/aarch32/cortex_m/cmse.h +++ b/arch/arm/include/aarch32/cortex_m/cmse.h @@ -50,7 +50,7 @@ extern "C" { * * @return a valid MPU region number or -EINVAL */ -int arm_cmse_mpu_region_get(u32_t addr); +int arm_cmse_mpu_region_get(uint32_t addr); /** * @brief Read accessibility of an address @@ -69,7 +69,7 @@ int arm_cmse_mpu_region_get(u32_t addr); * * @return 1 if address is readable, 0 otherwise. */ -int arm_cmse_addr_read_ok(u32_t addr, int force_npriv); +int arm_cmse_addr_read_ok(uint32_t addr, int force_npriv); /** * @brief Read and Write accessibility of an address @@ -89,7 +89,7 @@ int arm_cmse_addr_read_ok(u32_t addr, int force_npriv); * * @return 1 if address is Read and Writable, 0 otherwise. */ -int arm_cmse_addr_readwrite_ok(u32_t addr, int force_npriv); +int arm_cmse_addr_readwrite_ok(uint32_t addr, int force_npriv); /** * @brief Read accessibility of an address range @@ -111,7 +111,7 @@ int arm_cmse_addr_readwrite_ok(u32_t addr, int force_npriv); * * @return 1 if address range is readable, 0 otherwise. */ -int arm_cmse_addr_range_read_ok(u32_t addr, u32_t size, int force_npriv); +int arm_cmse_addr_range_read_ok(uint32_t addr, uint32_t size, int force_npriv); /** * @brief Read and Write accessibility of an address range @@ -133,7 +133,7 @@ int arm_cmse_addr_range_read_ok(u32_t addr, u32_t size, int force_npriv); * * @return 1 if address range is Read and Writable, 0 otherwise. */ -int arm_cmse_addr_range_readwrite_ok(u32_t addr, u32_t size, int force_npriv); +int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv); /* Required for C99 compilation (required for GCC-8.x version, * where typeof is used instead of __typeof__) @@ -232,7 +232,7 @@ int arm_cmse_addr_range_readwrite_ok(u32_t addr, u32_t size, int force_npriv); * * @return a valid MPU region number or -EINVAL */ -int arm_cmse_mpu_nonsecure_region_get(u32_t addr); +int arm_cmse_mpu_nonsecure_region_get(uint32_t addr); /** * @brief Get the SAU region number of an address @@ -250,7 +250,7 @@ int arm_cmse_mpu_nonsecure_region_get(u32_t addr); * * @return a valid SAU region number or -EINVAL */ -int arm_cmse_sau_region_get(u32_t addr); +int arm_cmse_sau_region_get(uint32_t addr); /** * @brief Get the IDAU region number of an address @@ -268,7 +268,7 @@ int arm_cmse_sau_region_get(u32_t addr); * * @return a valid IDAU region number or -EINVAL */ -int arm_cmse_idau_region_get(u32_t addr); +int arm_cmse_idau_region_get(uint32_t addr); /** * @brief Security attribution of an address @@ -280,7 +280,7 @@ int arm_cmse_idau_region_get(u32_t addr); * * @return 1 if address is Secure, 0 otherwise. */ -int arm_cmse_addr_is_secure(u32_t addr); +int arm_cmse_addr_is_secure(uint32_t addr); /** * @brief Non-Secure Read accessibility of an address @@ -300,7 +300,7 @@ int arm_cmse_addr_is_secure(u32_t addr); * * @return 1 if address is readable from Non-Secure state, 0 otherwise. */ -int arm_cmse_addr_nonsecure_read_ok(u32_t addr, int force_npriv); +int arm_cmse_addr_nonsecure_read_ok(uint32_t addr, int force_npriv); /** * @brief Non-Secure Read and Write accessibility of an address @@ -320,7 +320,7 @@ int arm_cmse_addr_nonsecure_read_ok(u32_t addr, int force_npriv); * * @return 1 if address is Read and Writable from Non-Secure state, 0 otherwise */ -int arm_cmse_addr_nonsecure_readwrite_ok(u32_t addr, int force_npriv); +int arm_cmse_addr_nonsecure_readwrite_ok(uint32_t addr, int force_npriv); /** * @brief Non-Secure Read accessibility of an address range @@ -342,7 +342,7 @@ int arm_cmse_addr_nonsecure_readwrite_ok(u32_t addr, int force_npriv); * * @return 1 if address range is readable, 0 otherwise. */ -int arm_cmse_addr_range_nonsecure_read_ok(u32_t addr, u32_t size, +int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size, int force_npriv); /** @@ -365,7 +365,7 @@ int arm_cmse_addr_range_nonsecure_read_ok(u32_t addr, u32_t size, * * @return 1 if address range is readable, 0 otherwise. */ -int arm_cmse_addr_range_nonsecure_readwrite_ok(u32_t addr, u32_t size, +int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv); /** diff --git a/arch/arm/include/aarch32/cortex_m/stack.h b/arch/arm/include/aarch32/cortex_m/stack.h index 6a0613aea20969..c6c6f57e5ef400 100644 --- a/arch/arm/include/aarch32/cortex_m/stack.h +++ b/arch/arm/include/aarch32/cortex_m/stack.h @@ -26,7 +26,7 @@ extern "C" { #endif -extern K_THREAD_STACK_ARRAY_DEFINE(z_interrupt_stacks, CONFIG_MP_NUM_CPUS, +extern K_KERNEL_STACK_ARRAY_DEFINE(z_interrupt_stacks, CONFIG_MP_NUM_CPUS, CONFIG_ISR_STACK_SIZE); /** @@ -40,13 +40,14 @@ extern K_THREAD_STACK_ARRAY_DEFINE(z_interrupt_stacks, CONFIG_MP_NUM_CPUS, */ static ALWAYS_INLINE void z_arm_interrupt_stack_setup(void) { - u32_t msp = (u32_t)(Z_THREAD_STACK_BUFFER(z_interrupt_stacks[0])) + - K_THREAD_STACK_SIZEOF(z_interrupt_stacks[0]); + uint32_t msp = + (uint32_t)(Z_KERNEL_STACK_BUFFER(z_interrupt_stacks[0])) + + K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[0]); __set_MSP(msp); #if defined(CONFIG_BUILTIN_STACK_GUARD) #if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM) - __set_MSPLIM((u32_t)z_interrupt_stacks[0]); + __set_MSPLIM((uint32_t)z_interrupt_stacks[0]); #else #error "Built-in MSP limit checks not supported by HW" #endif diff --git a/arch/arm/include/aarch32/cortex_m/tz.h b/arch/arm/include/aarch32/cortex_m/tz.h index dab11cd34c72f8..119a7316eb16a0 100644 --- a/arch/arm/include/aarch32/cortex_m/tz.h +++ b/arch/arm/include/aarch32/cortex_m/tz.h @@ -35,13 +35,13 @@ extern "C" { * state configuration. */ typedef struct tz_nonsecure_setup_conf { - u32_t msp_ns; - u32_t psp_ns; - u32_t vtor_ns; + uint32_t msp_ns; + uint32_t psp_ns; + uint32_t vtor_ns; struct { - u32_t npriv:1; - u32_t spsel:1; - u32_t reserved:30; + uint32_t npriv:1; + uint32_t spsel:1; + uint32_t reserved:30; } control_ns; } tz_nonsecure_setup_conf_t; @@ -84,7 +84,7 @@ void tz_nonsecure_state_setup(const tz_nonsecure_setup_conf_t *p_ns_conf); * * @return N/A */ -void tz_nonsecure_msplim_set(u32_t val); +void tz_nonsecure_msplim_set(uint32_t val); /** * @@ -101,7 +101,7 @@ void tz_nonsecure_msplim_set(u32_t val); * * @return N/A */ -void tz_nonsecure_psplim_set(u32_t val); +void tz_nonsecure_psplim_set(uint32_t val); #endif /* CONFIG_ARMV8_M_MAINLINE */ @@ -229,7 +229,7 @@ void tz_sau_configure(int enable, int allns); * * @return The number of configured SAU regions. */ -u32_t tz_sau_number_of_regions_get(void); +uint32_t tz_sau_number_of_regions_get(void); #if defined(CONFIG_CPU_HAS_ARM_SAU) /** @@ -240,11 +240,11 @@ u32_t tz_sau_number_of_regions_get(void); * for a SAU region configuration. */ typedef struct { - u8_t region_num; - u8_t enable:1; - u8_t nsc:1; - u32_t base_addr; - u32_t limit_addr; + uint8_t region_num; + uint8_t enable:1; + uint8_t nsc:1; + uint32_t base_addr; + uint32_t limit_addr; } tz_sau_conf_t; diff --git a/arch/arm/include/aarch32/cortex_m/tz_ns.h b/arch/arm/include/aarch32/cortex_m/tz_ns.h new file mode 100644 index 00000000000000..2bb081e644474a --- /dev/null +++ b/arch/arm/include/aarch32/cortex_m/tz_ns.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief TrustZone API for use in nonsecure firmware + * + * TrustZone API for Cortex-M CPUs implementing the Security Extension. + * The following API can be used by the nonsecure firmware to interact with the + * secure firmware. + */ + +#ifndef ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_TZ_NS_H_ +#define ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_TZ_NS_H_ + +#ifdef _ASMLANGUAGE + +/* nothing */ + +#else + +/** + * @brief Macro for "sandwiching" a function call (@p name) between two other + * calls + * + * This macro should be called via @ref __TZ_WRAP_FUNC. + * + * This macro creates the function body of an "outer" function which behaves + * exactly like the wrapped function (@p name), except that the preface function + * is called before, and the postface function afterwards. + * + * @param preface The function to call first. Must have no parameters and no + * return value. + * @param name The main function, i.e. the function to wrap. This function + * will receive the arguments, and its return value will be + * returned. + * @param postface The function to call last. Must have no parameters and no + * return value. + * @param store_lr The assembly instruction for storing away the LR value + * before the functions are called. This instruction must leave + * r0-r3 unmodified. + * @param load_lr The assembly instruction for restoring the LR value after + * the functions have been called. This instruction must leave + * r0-r3 unmodified. + */ +#define __TZ_WRAP_FUNC_RAW(preface, name, postface, store_lr, load_lr) \ + do { \ + __asm__ volatile( \ + ".global "#preface"; .type "#preface", %function"); \ + __asm__ volatile( \ + ".global "#name"; .type "#name", %function"); \ + __asm__ volatile( \ + ".global "#postface"; .type "#postface", %function"); \ + __asm__ volatile( \ + store_lr "\n\t" \ + "push {r0-r3}\n\t" \ + "bl " #preface "\n\t" \ + "pop {r0-r3}\n\t" \ + "bl " #name " \n\t" \ + "push {r0-r3}\n\t" \ + "bl " #postface "\n\t" \ + "pop {r0-r3}\n\t" \ + load_lr "\n\t" \ + ::); \ + } while (0) + +/** + * @brief Macro for "sandwiching" a function call (@p name) in two other calls + * + * @pre The wrapped function MUST not pass arguments or return values via + * the stack. I.e. the arguments and return values must each fit within 4 + * words, after accounting for alignment. + * Since nothing is passed on the stack, the stack can safely be used to + * store LR. + * + * Usage example: + * + * int foo(char *arg); // Implemented elsewhere. + * int __attribute__((naked)) foo_wrapped(char *arg) + * { + * __TZ_WRAP_FUNC(bar, foo, baz) + * } + * + * is equivalent to + * + * int foo(char *arg); // Implemented elsewhere. + * int foo_wrapped(char *arg) + * { + * bar(); + * int res = foo(arg); + * baz(); + * return res; + * } + * + * @note __attribute__((naked)) is not mandatory, but without it, GCC gives a + * warning for functions with a return value. It also reduces flash use. + * + * See @ref __TZ_WRAP_FUNC_RAW for more information. + */ +#define __TZ_WRAP_FUNC(preface, name, postface) \ + __TZ_WRAP_FUNC_RAW(preface, name, postface, "push {r4, lr}", \ + "pop {r4, pc}") + + +#ifdef CONFIG_ARM_FIRMWARE_USES_SECURE_ENTRY_FUNCS +/** + * @brief Create a thread safe wrapper function for a non-secure entry function + * + * This locks the scheduler before calling the function by wrapping the NS entry + * function in @ref k_sched_lock / @ref k_sched_unlock, using + * @ref __TZ_WRAP_FUNC. + * + * In non-secure code: + * + * int foo(char *arg); // Declaration of entry function. + * TZ_THREAD_SAFE_NONSECURE_ENTRY_FUNC(foo_safe, int, foo, char *arg) + * + * Usage in non-secure code: + * + * int ret = foo_safe("my arg"); + * + * If NS entry functions are called without such a wrapper, and a thread switch + * happens while execution is in the secure binary, the app will possibly crash + * upon returning to the non-secure binary. + * + * @param ret The return type of the NS entry function. + * @param name The desired name of the safe function. This assumes there is a + * corresponding NS entry function called nsc_name. + * @param ... The rest of the signature of the function. This must be the same + * signature as the corresponding NS entry function. + */ +#define TZ_THREAD_SAFE_NONSECURE_ENTRY_FUNC(name, ret, nsc_name, ...) \ + ret __attribute__((naked)) name(__VA_ARGS__) \ + { \ + __TZ_WRAP_FUNC(k_sched_lock, nsc_name, k_sched_unlock); \ + } + +#endif /* CONFIG_ARM_FIRMWARE_USES_SECURE_ENTRY_FUNCS */ + +#endif /* _ASMLANGUAGE */ +#endif /* ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_TZ_NS_H_ */ diff --git a/arch/arm/include/aarch32/kernel_arch_func.h b/arch/arm/include/aarch32/kernel_arch_func.h index ddc4fa911fa561..5829c88b19a983 100644 --- a/arch/arm/include/aarch32/kernel_arch_func.h +++ b/arch/arm/include/aarch32/kernel_arch_func.h @@ -50,10 +50,20 @@ arch_thread_return_value_set(struct k_thread *thread, unsigned int value) thread->arch.swap_return_value = value; } +#if !defined(CONFIG_MULTITHREADING) && defined(CONFIG_CPU_CORTEX_M) +extern FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( + k_thread_entry_t main_func, + void *p1, void *p2, void *p3); + +#define ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING \ + z_arm_switch_to_main_no_multithreading + +#endif /* !CONFIG_MULTITHREADING && CONFIG_CPU_CORTEX_M */ + extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, void *p1, void *p2, void *p3, - u32_t stack_end, - u32_t stack_start); + uint32_t stack_end, + uint32_t stack_start); extern void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf); diff --git a/arch/arm/include/aarch64/exc.h b/arch/arm/include/aarch64/exc.h index e75fade192e572..937ef6bfb43153 100644 --- a/arch/arm/include/aarch64/exc.h +++ b/arch/arm/include/aarch64/exc.h @@ -38,7 +38,7 @@ static ALWAYS_INLINE bool arch_is_in_isr(void) } -extern void z_arm64_call_svc(void); +extern void z_arm64_call_svc(void *switch_to, void **switched_from); #ifdef __cplusplus } diff --git a/arch/arm/include/aarch64/kernel_arch_func.h b/arch/arm/include/aarch64/kernel_arch_func.h index 762e48377ba6fc..430a0d8a4178f6 100644 --- a/arch/arm/include/aarch64/kernel_arch_func.h +++ b/arch/arm/include/aarch64/kernel_arch_func.h @@ -32,13 +32,14 @@ static ALWAYS_INLINE void arch_kernel_init(void) { } -static ALWAYS_INLINE void -arch_thread_return_value_set(struct k_thread *thread, unsigned int value) +static inline void arch_switch(void *switch_to, void **switched_from) { - thread->arch.swap_return_value = value; + z_arm64_call_svc(switch_to, switched_from); + + return; } -extern void z_arm64_fatal_error(const z_arch_esf_t *esf, unsigned int reason); +extern void z_arm64_fatal_error(z_arch_esf_t *esf, unsigned int reason); #endif /* _ASMLANGUAGE */ diff --git a/arch/arm/include/aarch64/offsets_short_arch.h b/arch/arm/include/aarch64/offsets_short_arch.h index acdd61beb2d925..3b519f109a5a3c 100644 --- a/arch/arm/include/aarch64/offsets_short_arch.h +++ b/arch/arm/include/aarch64/offsets_short_arch.h @@ -9,7 +9,4 @@ #include -#define _thread_offset_to_swap_return_value \ - (___thread_t_arch_OFFSET + ___thread_arch_t_swap_return_value_OFFSET) - #endif /* ZEPHYR_ARCH_ARM_INCLUDE_AARCH64_OFFSETS_SHORT_ARCH_H_ */ diff --git a/arch/arm/include/kernel_arch_data.h b/arch/arm/include/kernel_arch_data.h index 3f3c66e8eb6674..7dab6758d95e9e 100644 --- a/arch/arm/include/kernel_arch_data.h +++ b/arch/arm/include/kernel_arch_data.h @@ -47,6 +47,14 @@ extern "C" { typedef struct __esf _esf_t; typedef struct __basic_sf _basic_sf_t; +#ifdef CONFIG_ARM_MPU +struct z_arm_mpu_partition { + uintptr_t start; + size_t size; + k_mem_partition_attr_t attr; +}; +#endif + #ifdef __cplusplus } #endif diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index 084c0241c0fbd7..cc11ed34a526fd 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -1,18 +1,18 @@ # SPDX-License-Identifier: Apache-2.0 -if(CONFIG_GEN_ISR_TABLES OR CONFIG_EXECUTION_BENCHMARKING) +if(CONFIG_GEN_ISR_TABLES) zephyr_library() zephyr_library_sources_ifdef( CONFIG_GEN_ISR_TABLES - isr_tables.c sw_isr_common.c ) +endif() - zephyr_library_sources_ifdef( - CONFIG_EXECUTION_BENCHMARKING - timing_info_bench.c - ) +if(NOT CONFIG_ARCH_HAS_TIMING_FUNCTIONS AND + NOT CONFIG_SOC_HAS_TIMING_FUNCTIONS AND + NOT CONFIG_BOARD_HAS_TIMING_FUNCTIONS) +zephyr_library_sources_ifdef(CONFIG_TIMING_FUNCTIONS timing.c) endif() # Put functions and data in their own binary sections so that ld can @@ -34,8 +34,21 @@ zephyr_linker_sources_ifdef(CONFIG_NOCACHE_MEMORY nocache.ld ) -# Only ARM, X86 and OPENISA_RV32M1_RISCV32 use TEXT_SECTION_OFFSET. +# Only ARM, X86 and OPENISA_RV32M1_RISCV32 use ROM_START_OFFSET. if (DEFINED CONFIG_ARM OR DEFINED CONFIG_X86 OR DEFINED CONFIG_SOC_OPENISA_RV32M1_RISCV32) - zephyr_linker_sources(ROM_START SORT_KEY 0x0 text_section_offset.ld) + zephyr_linker_sources(ROM_START SORT_KEY 0x0 rom_start_offset.ld) +endif() + + +# isr_tables is a normal CMake library and not a zephyr_library because it +# should not be --whole-archive'd +if (CONFIG_GEN_ISR_TABLES) + add_library(isr_tables + isr_tables.c + ) + + add_dependencies(isr_tables zephyr_generated_headers) + target_link_libraries(isr_tables zephyr_interface) + zephyr_library_link_libraries(isr_tables) endif() diff --git a/arch/common/gen_isr_tables.py b/arch/common/gen_isr_tables.py index cfb46516b879d3..cfcfaf36207a72 100755 --- a/arch/common/gen_isr_tables.py +++ b/arch/common/gen_isr_tables.py @@ -46,7 +46,7 @@ def read_intlist(intlist_path, syms): include/linker/intlist.ld: struct { - u32_t num_vectors; <- typically CONFIG_NUM_IRQS + uint32_t num_vectors; <- typically CONFIG_NUM_IRQS struct _isr_list isrs[]; <- Usually of smaller size than num_vectors } @@ -55,13 +55,13 @@ def read_intlist(intlist_path, syms): struct _isr_list { /** IRQ line number */ - s32_t irq; + int32_t irq; /** Flags for this IRQ, see ISR_FLAG_* definitions */ - s32_t flags; + int32_t flags; /** ISR to call */ void *func; /** Parameter for non-direct IRQs */ - void *param; + const void *param; }; """ @@ -134,11 +134,12 @@ def parse_args(): #include #if defined(CONFIG_GEN_SW_ISR_TABLE) && defined(CONFIG_GEN_IRQ_VECTOR_TABLE) -#define ISR_WRAPPER ((u32_t)&_isr_wrapper) +#define ISR_WRAPPER ((uint32_t)&_isr_wrapper) #else #define ISR_WRAPPER NULL #endif +typedef void (* ISR)(const void *); """ def write_source_file(fp, vt, swt, intlist, syms): @@ -147,7 +148,7 @@ def write_source_file(fp, vt, swt, intlist, syms): nv = intlist["num_vectors"] if vt: - fp.write("u32_t __irq_vector_table _irq_vector_table[%d] = {\n" % nv) + fp.write("uint32_t __irq_vector_table _irq_vector_table[%d] = {\n" % nv) for i in range(nv): fp.write("\t{},\n".format(vt[i])) fp.write("};\n") @@ -175,7 +176,7 @@ def write_source_file(fp, vt, swt, intlist, syms): fp.write("\t/* Level 3 interrupts start here (offset: {}) */\n". format(level3_offset)) - fp.write("\t{{(void *){0:#x}, (void *){1}}},\n".format(param, func_as_string)) + fp.write("\t{{(const void *){0:#x}, (ISR){1}}},\n".format(param, func_as_string)) fp.write("};\n") def get_symbols(obj): diff --git a/arch/common/isr_tables.c b/arch/common/isr_tables.c index f7d11ce04b627c..b9a28bbdbb205c 100644 --- a/arch/common/isr_tables.c +++ b/arch/common/isr_tables.c @@ -13,8 +13,8 @@ * which indicates the number of interrupts specified */ struct int_list_header { - u32_t table_size; - u32_t offset; + uint32_t table_size; + uint32_t offset; }; /* These values are not included in the resulting binary, but instead form the @@ -50,8 +50,8 @@ Z_GENERIC_SECTION(.irq_info) struct int_list_header _iheader = { #define IRQ_VECTOR_TABLE_DEFAULT_ISR z_irq_spurious #endif /* CONFIG_GEN_SW_ISR_TABLE */ -u32_t __irq_vector_table _irq_vector_table[IRQ_TABLE_SIZE] = { - [0 ...(IRQ_TABLE_SIZE - 1)] = (u32_t)&IRQ_VECTOR_TABLE_DEFAULT_ISR, +uint32_t __irq_vector_table _irq_vector_table[IRQ_TABLE_SIZE] = { + [0 ...(IRQ_TABLE_SIZE - 1)] = (uint32_t)&IRQ_VECTOR_TABLE_DEFAULT_ISR, }; #endif /* CONFIG_GEN_IRQ_VECTOR_TABLE */ @@ -60,6 +60,7 @@ u32_t __irq_vector_table _irq_vector_table[IRQ_TABLE_SIZE] = { */ #ifdef CONFIG_GEN_SW_ISR_TABLE struct _isr_table_entry __sw_isr_table _sw_isr_table[IRQ_TABLE_SIZE] = { - [0 ...(IRQ_TABLE_SIZE - 1)] = {(void *)0x42, (void *)&z_irq_spurious}, + [0 ...(IRQ_TABLE_SIZE - 1)] = {(const void *)0x42, + (void *)&z_irq_spurious}, }; #endif diff --git a/arch/common/rom_start_offset.ld b/arch/common/rom_start_offset.ld new file mode 100644 index 00000000000000..2e82f30d71886e --- /dev/null +++ b/arch/common/rom_start_offset.ld @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2019 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +. = CONFIG_ROM_START_OFFSET; +. = ALIGN(4); diff --git a/arch/common/sw_isr_common.c b/arch/common/sw_isr_common.c index 11ce42d41e355d..b0b68f9c9b6e50 100644 --- a/arch/common/sw_isr_common.c +++ b/arch/common/sw_isr_common.c @@ -70,7 +70,8 @@ unsigned int get_parent_offset(unsigned int parent_irq, #endif /* CONFIG_MULTI_LEVEL_INTERRUPTS */ -void z_isr_install(unsigned int irq, void (*routine)(void *), void *param) +void z_isr_install(unsigned int irq, void (*routine)(const void *), + const void *param) { unsigned int table_idx; @@ -127,9 +128,9 @@ void z_isr_install(unsigned int irq, void (*routine)(void *), void *param) */ int __weak arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *), - void *parameter, - u32_t flags) + void (*routine)(const void *), + const void *parameter, + uint32_t flags) { ARG_UNUSED(flags); ARG_UNUSED(priority); diff --git a/arch/common/text_section_offset.ld b/arch/common/text_section_offset.ld deleted file mode 100644 index 15e511eadad7bd..00000000000000 --- a/arch/common/text_section_offset.ld +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2019 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -. = CONFIG_TEXT_SECTION_OFFSET; -. = ALIGN(4); diff --git a/arch/common/timing.c b/arch/common/timing.c new file mode 100644 index 00000000000000..72b0f053e3aea9 --- /dev/null +++ b/arch/common/timing.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +void arch_timing_init(void) +{ +} + +void arch_timing_start(void) +{ +} + +void arch_timing_stop(void) +{ +} + +timing_t arch_timing_counter_get(void) +{ + return k_cycle_get_32(); +} + +uint64_t arch_timing_cycles_get(volatile timing_t *const start, + volatile timing_t *const end) +{ + return (*end - *start); +} + + +uint64_t arch_timing_freq_get(void) +{ + return sys_clock_hw_cycles_per_sec(); +} + +uint64_t arch_timing_cycles_to_ns(uint64_t cycles) +{ + return k_cyc_to_ns_floor64(cycles); +} + +uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) +{ + return arch_timing_cycles_to_ns(cycles) / count; +} + +uint32_t arch_timing_freq_get_mhz(void) +{ + return (uint32_t)(arch_timing_freq_get() / 1000000); +} diff --git a/arch/common/timing_info_bench.c b/arch/common/timing_info_bench.c deleted file mode 100644 index 1a6860b2a5ac01..00000000000000 --- a/arch/common/timing_info_bench.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include - -u64_t arch_timing_swap_start; -u64_t arch_timing_swap_end; -u64_t arch_timing_irq_start; -u64_t arch_timing_irq_end; -u64_t arch_timing_tick_start; -u64_t arch_timing_tick_end; -u64_t arch_timing_enter_user_mode_end; - -/* location of the time stamps*/ -u32_t arch_timing_value_swap_end; -u64_t arch_timing_value_swap_common; -u64_t arch_timing_value_swap_temp; - -#if defined(CONFIG_NRF_RTC_TIMER) -#include - -/* To get current count of timer, first 1 need to be written into - * Capture Register and Current Count will be copied into corresponding - * current count register. - */ -#define TIMING_INFO_PRE_READ() (NRF_TIMER2->TASKS_CAPTURE[0] = 1) -#define TIMING_INFO_OS_GET_TIME() (NRF_TIMER2->CC[0]) -#define TIMING_INFO_GET_TIMER_VALUE() (TIMING_INFO_OS_GET_TIME()) -#define SUBTRACT_CLOCK_CYCLES(val) (val) - -#elif defined(CONFIG_SOC_SERIES_MEC1501X) -#define TIMING_INFO_PRE_READ() -#define TIMING_INFO_OS_GET_TIME() (B32TMR1_REGS->CNT) -#define TIMING_INFO_GET_TIMER_VALUE() (TIMING_INFO_OS_GET_TIME()) -#define SUBTRACT_CLOCK_CYCLES(val) (val) - -#elif defined(CONFIG_X86) -#define TIMING_INFO_PRE_READ() -#define TIMING_INFO_OS_GET_TIME() (z_tsc_read()) -#define TIMING_INFO_GET_TIMER_VALUE() (TIMING_INFO_OS_GET_TIME()) -#define SUBTRACT_CLOCK_CYCLES(val) (val) - -#elif defined(CONFIG_CPU_CORTEX_M) -#include -#define TIMING_INFO_PRE_READ() -#define TIMING_INFO_OS_GET_TIME() (k_cycle_get_32()) -#define TIMING_INFO_GET_TIMER_VALUE() (SysTick->VAL) -#define SUBTRACT_CLOCK_CYCLES(val) (SysTick->LOAD - (u32_t)val) - -#elif defined(CONFIG_ARC) -#define TIMING_INFO_PRE_READ() -#define TIMING_INFO_OS_GET_TIME() (k_cycle_get_32()) -#define TIMING_INFO_GET_TIMER_VALUE() (z_arc_v2_aux_reg_read(_ARC_V2_TMR0_COUNT)) -#define SUBTRACT_CLOCK_CYCLES(val) ((u32_t)val) - -#elif defined(CONFIG_NIOS2) -#include "altera_avalon_timer_regs.h" -#define TIMING_INFO_PRE_READ() \ - (IOWR_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE, 10)) - -#define TIMING_INFO_OS_GET_TIME() (SUBTRACT_CLOCK_CYCLES(\ - ((u32_t)IORD_ALTERA_AVALON_TIMER_SNAPH(TIMER_0_BASE) << 16)\ - | ((u32_t)IORD_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE)))) - -#define TIMING_INFO_GET_TIMER_VALUE() (\ - ((u32_t)IORD_ALTERA_AVALON_TIMER_SNAPH(TIMER_0_BASE) << 16)\ - | ((u32_t)IORD_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE))) - -#define SUBTRACT_CLOCK_CYCLES(val) \ - ((IORD_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE) \ - << 16 | \ - (IORD_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE))) \ - - ((u32_t)val)) - -#else -#define TIMING_INFO_PRE_READ() -#define TIMING_INFO_OS_GET_TIME() (k_cycle_get_32()) -#define TIMING_INFO_GET_TIMER_VALUE() (k_cycle_get_32()) -#define SUBTRACT_CLOCK_CYCLES(val) ((u32_t)val) -#endif /* CONFIG_NRF_RTC_TIMER */ - - -void read_timer_start_of_swap(void) -{ - if (arch_timing_value_swap_end == 1U) { - TIMING_INFO_PRE_READ(); - arch_timing_swap_start = (u32_t) TIMING_INFO_OS_GET_TIME(); - } -} - -void read_timer_end_of_swap(void) -{ - if (arch_timing_value_swap_end == 1U) { - TIMING_INFO_PRE_READ(); - arch_timing_value_swap_end = 2U; - arch_timing_value_swap_common = - (u64_t)TIMING_INFO_OS_GET_TIME(); - } -} - -/* ARM processors read current value of time through sysTick timer - * and nrf soc read it though timer - */ -void read_timer_start_of_isr(void) -{ - TIMING_INFO_PRE_READ(); - arch_timing_irq_start = (u32_t) TIMING_INFO_GET_TIMER_VALUE(); -} - -void read_timer_end_of_isr(void) -{ - TIMING_INFO_PRE_READ(); - arch_timing_irq_end = (u32_t) TIMING_INFO_GET_TIMER_VALUE(); -} - -void read_timer_start_of_tick_handler(void) -{ - TIMING_INFO_PRE_READ(); - arch_timing_tick_start = (u32_t)TIMING_INFO_GET_TIMER_VALUE(); -} - -void read_timer_end_of_tick_handler(void) -{ - TIMING_INFO_PRE_READ(); - arch_timing_tick_end = (u32_t) TIMING_INFO_GET_TIMER_VALUE(); -} - -void read_timer_end_of_userspace_enter(void) -{ - TIMING_INFO_PRE_READ(); - arch_timing_enter_user_mode_end = (u32_t)TIMING_INFO_GET_TIMER_VALUE(); -} diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index f64fd7ad71035a..6e147119421a4b 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig @@ -14,6 +14,7 @@ config CPU_NIOS2_GEN2 bool default y select BUILD_OUTPUT_HEX + select ARCH_HAS_EXTRA_EXCEPTION_INFO help This option signifies the use of a Nios II Gen 2 CPU @@ -21,9 +22,6 @@ endmenu menu "Nios II Family Options" -config XIP - default y - config GEN_ISR_TABLES default y diff --git a/arch/nios2/core/CMakeLists.txt b/arch/nios2/core/CMakeLists.txt index cfda508543e3c0..84fa0b49b3f3ec 100644 --- a/arch/nios2/core/CMakeLists.txt +++ b/arch/nios2/core/CMakeLists.txt @@ -15,4 +15,5 @@ zephyr_library_sources( crt0.S ) -zephyr_library_sources_if_kconfig(irq_offload.c) +zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) +zephyr_library_sources_ifdef(CONFIG_TIMING_FUNCTIONS timing.c) diff --git a/arch/nios2/core/cache.c b/arch/nios2/core/cache.c index bdf1f499d6864a..58027cbda96f4d 100644 --- a/arch/nios2/core/cache.c +++ b/arch/nios2/core/cache.c @@ -24,7 +24,7 @@ #if ALT_CPU_ICACHE_SIZE > 0 void z_nios2_icache_flush_all(void) { - u32_t i; + uint32_t i; for (i = 0U; i < ALT_CPU_ICACHE_SIZE; i += ALT_CPU_ICACHE_LINE_SIZE) { z_nios2_icache_flush(i); @@ -53,7 +53,7 @@ void z_nios2_icache_flush_all(void) #if ALT_CPU_DCACHE_SIZE > 0 void z_nios2_dcache_flush_all(void) { - u32_t i; + uint32_t i; for (i = 0U; i < ALT_CPU_DCACHE_SIZE; i += ALT_CPU_DCACHE_LINE_SIZE) { z_nios2_dcache_flush(i); @@ -70,10 +70,10 @@ void z_nios2_dcache_flush_all(void) * use the z_nios2_dcache_flush() routine instead. */ #if ALT_CPU_DCACHE_SIZE > 0 -void z_nios2_dcache_flush_no_writeback(void *start, u32_t len) +void z_nios2_dcache_flush_no_writeback(void *start, uint32_t len) { - u8_t *i; - u8_t *end = ((char *) start) + len; + uint8_t *i; + uint8_t *end = ((char *) start) + len; for (i = start; i < end; i += ALT_CPU_DCACHE_LINE_SIZE) { __asm__ volatile ("initda (%0)" :: "r" (i)); @@ -85,7 +85,7 @@ void z_nios2_dcache_flush_no_writeback(void *start, u32_t len) * multiple of 2 (which it always is). */ - if (((u32_t) start) & (ALT_CPU_DCACHE_LINE_SIZE - 1)) { + if (((uint32_t) start) & (ALT_CPU_DCACHE_LINE_SIZE - 1)) { __asm__ volatile ("initda (%0)" :: "r" (i)); } } diff --git a/arch/nios2/core/crt0.S b/arch/nios2/core/crt0.S index a24ce74f2db8eb..c9ce8de9184b65 100644 --- a/arch/nios2/core/crt0.S +++ b/arch/nios2/core/crt0.S @@ -113,7 +113,7 @@ SECTION_FUNC(TEXT, __start) ori r3, r3, 0xaaaa 1: /* Loop through the z_interrupt_stacks treating it as an array of - * u32_t, setting each element to r3 */ + * uint32_t, setting each element to r3 */ stw r3, (r1) subi r2, r2, 4 addi r1, r1, 4 diff --git a/arch/nios2/core/fatal.c b/arch/nios2/core/fatal.c index eef778eef138e9..aaff1fe5d35fa3 100644 --- a/arch/nios2/core/fatal.c +++ b/arch/nios2/core/fatal.c @@ -9,7 +9,7 @@ #include #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); FUNC_NORETURN void z_nios2_fatal_error(unsigned int reason, const z_arch_esf_t *esf) @@ -41,7 +41,7 @@ FUNC_NORETURN void z_nios2_fatal_error(unsigned int reason, #if defined(CONFIG_EXTRA_EXCEPTION_INFO) && \ (defined(CONFIG_PRINTK) || defined(CONFIG_LOG)) \ && defined(ALT_CPU_HAS_EXTRA_EXCEPTION_INFO) -static char *cause_str(u32_t cause_code) +static char *cause_str(uint32_t cause_code) { switch (cause_code) { case 0: @@ -105,7 +105,7 @@ FUNC_NORETURN void _Fault(const z_arch_esf_t *esf) #if defined(CONFIG_PRINTK) || defined(CONFIG_LOG) /* Unfortunately, completely unavailable on Nios II/e cores */ #ifdef ALT_CPU_HAS_EXTRA_EXCEPTION_INFO - u32_t exc_reg, badaddr_reg, eccftl; + uint32_t exc_reg, badaddr_reg, eccftl; enum nios2_exception_cause cause; exc_reg = z_nios2_creg_read(NIOS2_CR_EXCEPTION); diff --git a/arch/nios2/core/irq_manage.c b/arch/nios2/core/irq_manage.c index c8c666114d2f49..26f92ef23bb09e 100644 --- a/arch/nios2/core/irq_manage.c +++ b/arch/nios2/core/irq_manage.c @@ -20,9 +20,9 @@ #include #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); -FUNC_NORETURN void z_irq_spurious(void *unused) +FUNC_NORETURN void z_irq_spurious(const void *unused) { ARG_UNUSED(unused); LOG_ERR("Spurious interrupt detected! ipending: %x", @@ -33,7 +33,7 @@ FUNC_NORETURN void z_irq_spurious(void *unused) void arch_irq_enable(unsigned int irq) { - u32_t ienable; + uint32_t ienable; unsigned int key; key = irq_lock(); @@ -49,7 +49,7 @@ void arch_irq_enable(unsigned int irq) void arch_irq_disable(unsigned int irq) { - u32_t ienable; + uint32_t ienable; unsigned int key; key = irq_lock(); @@ -63,7 +63,7 @@ void arch_irq_disable(unsigned int irq) int arch_irq_is_enabled(unsigned int irq) { - u32_t ienable; + uint32_t ienable; ienable = z_nios2_creg_read(NIOS2_CR_IENABLE); return ienable & BIT(irq); @@ -76,15 +76,10 @@ int arch_irq_is_enabled(unsigned int irq) * * @param ipending Bitfield of interrupts */ -void _enter_irq(u32_t ipending) +void _enter_irq(uint32_t ipending) { int index; -#ifdef CONFIG_EXECUTION_BENCHMARKING - extern void read_timer_start_of_isr(void); - read_timer_start_of_isr(); -#endif - _kernel.cpus[0].nested++; #ifdef CONFIG_IRQ_OFFLOAD @@ -103,10 +98,6 @@ void _enter_irq(u32_t ipending) ite = &_sw_isr_table[index]; -#ifdef CONFIG_EXECUTION_BENCHMARKING - extern void read_timer_end_of_isr(void); - read_timer_end_of_isr(); -#endif ite->isr(ite->arg); #ifdef CONFIG_TRACING_ISR sys_trace_isr_exit(); @@ -121,8 +112,8 @@ void _enter_irq(u32_t ipending) #ifdef CONFIG_DYNAMIC_INTERRUPTS int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *parameter), void *parameter, - u32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { ARG_UNUSED(flags); ARG_UNUSED(priority); diff --git a/arch/nios2/core/irq_offload.c b/arch/nios2/core/irq_offload.c index d6cbe39bf63b44..5229af8b2a9e02 100644 --- a/arch/nios2/core/irq_offload.c +++ b/arch/nios2/core/irq_offload.c @@ -9,7 +9,7 @@ #include volatile irq_offload_routine_t _offload_routine; -static volatile void *offload_param; +static volatile const void *offload_param; /* Called by _enter_irq if it was passed 0 for ipending. * Just in case the offload routine itself generates an unhandled @@ -26,10 +26,10 @@ void z_irq_do_offload(void) tmp = _offload_routine; _offload_routine = NULL; - tmp((void *)offload_param); + tmp((const void *)offload_param); } -void arch_irq_offload(irq_offload_routine_t routine, void *parameter) +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { unsigned int key; diff --git a/arch/nios2/core/swap.S b/arch/nios2/core/swap.S index e26acfd96c72b3..1e460a2cb84d7d 100644 --- a/arch/nios2/core/swap.S +++ b/arch/nios2/core/swap.S @@ -13,7 +13,6 @@ GTEXT(arch_swap) GTEXT(z_thread_entry_wrapper) /* imports */ -GTEXT(sys_trace_thread_switched_in) GTEXT(_k_neg_eagain) /* unsigned int arch_swap(unsigned int key) @@ -22,33 +21,21 @@ GTEXT(_k_neg_eagain) */ SECTION_FUNC(exception.other, arch_swap) -#ifdef CONFIG_EXECUTION_BENCHMARKING - /* Get a reference to _kernel in r10 */ - movhi r10, %hi(_kernel) - ori r10, r10, %lo(_kernel) +#if defined(CONFIG_INSTRUMENT_THREAD_SWITCHING) + /* Need to preserve r4 as it has the function argument. */ + addi sp, sp, -12 + stw ra, 8(sp) + stw fp, 4(sp) + stw r4, 0(sp) - /* Get the pointer to kernel->current */ - ldw r11, _kernel_offset_to_current(r10) - stw r2, _thread_offset_to_r16(r11) - stw r3, _thread_offset_to_r17(r11) - stw r4, _thread_offset_to_r18(r11) - stw ra, _thread_offset_to_ra(r11) - stw sp, _thread_offset_to_sp(r11) - - call read_timer_start_of_swap - /* Get a reference to _kernel in r10 */ - movhi r10, %hi(_kernel) - ori r10, r10, %lo(_kernel) - - /* Get the pointer to kernel->current */ - ldw r11, _kernel_offset_to_current(r10) - ldw r2, _thread_offset_to_r16(r11) - ldw r3, _thread_offset_to_r17(r11) - ldw r4, _thread_offset_to_r18(r11) - ldw ra, _thread_offset_to_ra(r11) - ldw sp, _thread_offset_to_sp(r11) + call z_thread_mark_switched_out + ldw r4, 0(sp) + ldw fp, 4(sp) + ldw ra, 8(sp) + addi sp, sp, 12 #endif + /* Get a reference to _kernel in r10 */ movhi r10, %hi(_kernel) ori r10, r10, %lo(_kernel) @@ -84,13 +71,6 @@ SECTION_FUNC(exception.other, arch_swap) ldw r4, (r5) stw r4, _thread_offset_to_retval(r11) -#if CONFIG_TRACING - call sys_trace_thread_switched_in - /* restore caller-saved r10 */ - movhi r10, %hi(_kernel) - ori r10, r10, %lo(_kernel) -#endif - /* get cached thread to run */ ldw r2, _kernel_offset_to_ready_q_cache(r10) @@ -142,31 +122,23 @@ no_unlock: wrctl status, r3 #endif -#ifdef CONFIG_EXECUTION_BENCHMARKING - /* Get a reference to _kernel in r10 */ - movhi r10, %hi(_kernel) - ori r10, r10, %lo(_kernel) - - ldw r11, _kernel_offset_to_current(r10) - stw r2, _thread_offset_to_r16(r11) - stw r3, _thread_offset_to_r17(r11) - stw r4, _thread_offset_to_r18(r11) - stw ra, _thread_offset_to_ra(r11) - stw sp, _thread_offset_to_sp(r11) - - call read_timer_end_of_swap - - /* Get a reference to _kernel in r10 */ - movhi r10, %hi(_kernel) - ori r10, r10, %lo(_kernel) - - /* Get the pointer to kernel->current */ - ldw r11, _kernel_offset_to_current(r10) - ldw r2, _thread_offset_to_r16(r11) - ldw r3, _thread_offset_to_r17(r11) - ldw r4, _thread_offset_to_r18(r11) - ldw ra, _thread_offset_to_ra(r11) - ldw sp, _thread_offset_to_sp(r11) +#if defined(CONFIG_INSTRUMENT_THREAD_SWITCHING) + /* Also need to preserve r2, r3 as return values */ + addi sp, sp, -20 + stw ra, 16(sp) + stw fp, 12(sp) + stw r4, 8(sp) + stw r3, 4(sp) + stw r2, 0(sp) + + call z_thread_mark_switched_in + + ldw r2, 0(sp) + ldw r3, 4(sp) + ldw r4, 8(sp) + ldw fp, 12(sp) + ldw ra, 16(sp) + addi sp, sp, 20 #endif ret diff --git a/arch/nios2/core/thread.c b/arch/nios2/core/thread.c index f20fe219718a0c..c38f25ef104cba 100644 --- a/arch/nios2/core/thread.c +++ b/arch/nios2/core/thread.c @@ -29,27 +29,22 @@ struct init_stack_frame { void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - size_t stack_size, k_thread_entry_t thread_func, - void *arg1, void *arg2, void *arg3, - int priority, unsigned int options) + char *stack_ptr, k_thread_entry_t entry, + void *arg1, void *arg2, void *arg3) { - char *stack_memory = Z_THREAD_STACK_BUFFER(stack); struct init_stack_frame *iframe; - z_new_thread_init(thread, stack_memory, stack_size); - /* Initial stack frame data, stored at the base of the stack */ - iframe = (struct init_stack_frame *) - Z_STACK_PTR_ALIGN(stack_memory + stack_size - sizeof(*iframe)); + iframe = Z_STACK_PTR_TO_FRAME(struct init_stack_frame, stack_ptr); /* Setup the initial stack frame */ - iframe->entry_point = thread_func; + iframe->entry_point = entry; iframe->arg1 = arg1; iframe->arg2 = arg2; iframe->arg3 = arg3; - thread->callee_saved.sp = (u32_t)iframe; - thread->callee_saved.ra = (u32_t)z_thread_entry_wrapper; + thread->callee_saved.sp = (uint32_t)iframe; + thread->callee_saved.ra = (uint32_t)z_thread_entry_wrapper; thread->callee_saved.key = NIOS2_STATUS_PIE_MSK; /* Leave the rest of thread->callee_saved junk */ } diff --git a/arch/nios2/core/timing.c b/arch/nios2/core/timing.c new file mode 100644 index 00000000000000..bae3320aaa5d76 --- /dev/null +++ b/arch/nios2/core/timing.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "altera_avalon_timer_regs.h" + +#define NIOS2_SUBTRACT_CLOCK_CYCLES(val) \ + ((IORD_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE) << 16 | \ + (IORD_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE))) - \ + ((uint32_t)val)) + +#define TIMING_INFO_OS_GET_TIME() \ + (NIOS2_SUBTRACT_CLOCK_CYCLES( \ + ((uint32_t)IORD_ALTERA_AVALON_TIMER_SNAPH(TIMER_0_BASE) \ + << 16) | \ + ((uint32_t)IORD_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE)))) + +void arch_timing_init(void) +{ +} + +void arch_timing_start(void) +{ +} + +void arch_timing_stop(void) +{ +} + +timing_t arch_timing_counter_get(void) +{ + IOWR_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE, 10); + return TIMING_INFO_OS_GET_TIME(); +} + +uint64_t arch_timing_cycles_get(volatile timing_t *const start, + volatile timing_t *const end) +{ + return (*end - *start); +} + +uint64_t arch_timing_freq_get(void) +{ + return sys_clock_hw_cycles_per_sec(); +} + +uint64_t arch_timing_cycles_to_ns(uint64_t cycles) +{ + return k_cyc_to_ns_floor64(cycles); +} + +uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) +{ + return arch_timing_cycles_to_ns(cycles) / count; +} + +uint32_t arch_timing_freq_get_mhz(void) +{ + return (uint32_t)(arch_timing_freq_get() / 1000000); +} diff --git a/arch/nios2/include/kernel_arch_func.h b/arch/nios2/include/kernel_arch_func.h index 588728eaf5ca60..efb3582c90bde9 100644 --- a/arch/nios2/include/kernel_arch_func.h +++ b/arch/nios2/include/kernel_arch_func.h @@ -58,7 +58,7 @@ void z_nios2_icache_flush_all(void); #if ALT_CPU_DCACHE_SIZE > 0 void z_nios2_dcache_flush_all(void); -void z_nios2_dcache_flush_no_writeback(void *start, u32_t len); +void z_nios2_dcache_flush_no_writeback(void *start, uint32_t len); #else #define z_nios2_dcache_flush_all() do { } while (0) #define z_nios2_dcache_flush_no_writeback(x, y) do { } while (0) diff --git a/arch/posix/CMakeLists.txt b/arch/posix/CMakeLists.txt index b8d2e1ec36fb7a..664c7a3a3a613f 100644 --- a/arch/posix/CMakeLists.txt +++ b/arch/posix/CMakeLists.txt @@ -20,20 +20,23 @@ zephyr_compile_options( ) # @Intent: Obtain compiler specific flags for no freestanding compilation -toolchain_cc_no_freestanding_options() +zephyr_compile_options($) zephyr_include_directories(${BOARD_DIR}) if (CONFIG_COVERAGE) - toolchain_cc_coverage() + zephyr_compile_options($) + zephyr_link_libraries($) endif () if (CONFIG_ASAN) - toolchain_cc_asan() + zephyr_compile_options($) + zephyr_link_libraries($) endif () if (CONFIG_UBSAN) - toolchain_cc_ubsan() + zephyr_compile_options($) + zephyr_link_libraries($) endif () zephyr_compile_definitions(_POSIX_C_SOURCE=200809 _XOPEN_SOURCE=600 _XOPEN_SOURCE_EXTENDED) diff --git a/arch/posix/core/cpuhalt.c b/arch/posix/core/cpuhalt.c index f43f0ed1864a53..c5970aff2904c3 100644 --- a/arch/posix/core/cpuhalt.c +++ b/arch/posix/core/cpuhalt.c @@ -11,7 +11,7 @@ * * An implementation of the architecture-specific * arch_cpu_idle() primitive required by the kernel idle loop component. - * It can be called within an implementation of _sys_power_save_idle(), + * It can be called within an implementation of _pm_save_idle(), * which is provided for the kernel by the platform. * * An implementation of arch_cpu_atomic_idle(), which @@ -21,6 +21,7 @@ */ #include "posix_core.h" +#include "posix_board_if.h" #include #include @@ -48,6 +49,8 @@ void arch_cpu_atomic_idle(unsigned int key) */ void __weak sys_arch_reboot(int type) { - ARG_UNUSED(type); + posix_print_warning("%s called with type %d. Exiting\n", + __func__, type); + posix_exit(1); } #endif /* CONFIG_REBOOT */ diff --git a/arch/posix/core/irq.c b/arch/posix/core/irq.c index 0a4c00f6668ff3..8722757cff85e2 100644 --- a/arch/posix/core/irq.c +++ b/arch/posix/core/irq.c @@ -10,7 +10,7 @@ #ifdef CONFIG_IRQ_OFFLOAD #include "irq_offload.h" -void arch_irq_offload(irq_offload_routine_t routine, void *parameter) +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { posix_irq_offload(routine, parameter); } @@ -46,8 +46,8 @@ int arch_irq_is_enabled(unsigned int irq) * @return The vector assigned to this interrupt */ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *parameter), - void *parameter, u32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { posix_isr_declare(irq, (int)flags, routine, parameter); posix_irq_priority_set(irq, priority, flags); diff --git a/arch/posix/core/posix_core.c b/arch/posix/core/posix_core.c index 9ee87626323ddf..d32fb85b8f994c 100644 --- a/arch/posix/core/posix_core.c +++ b/arch/posix/core/posix_core.c @@ -477,9 +477,6 @@ void posix_abort_thread(int thread_idx) #if defined(CONFIG_ARCH_HAS_THREAD_ABORT) - -extern void z_thread_single_abort(struct k_thread *thread); - void z_impl_k_thread_abort(k_tid_t thread) { unsigned int key; @@ -493,12 +490,6 @@ void z_impl_k_thread_abort(k_tid_t thread) key = irq_lock(); - __ASSERT(!(thread->base.user_options & K_ESSENTIAL), - "essential thread aborted"); - - z_thread_single_abort(thread); - z_thread_monitor_exit(thread); - if (_current == thread) { if (tstatus->aborted == 0) { /* LCOV_EXCL_BR_LINE */ tstatus->aborted = 1; @@ -516,10 +507,17 @@ void z_impl_k_thread_abort(k_tid_t thread) thread_idx, __func__); - (void)z_swap_irqlock(key); + if (arch_is_in_isr()) { + z_thread_single_abort(thread); + return; + } + + z_self_abort(); CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ } + z_thread_single_abort(thread); + if (tstatus->aborted == 0) { PC_DEBUG("%s aborting now [%i] %i\n", __func__, diff --git a/arch/posix/core/swap.c b/arch/posix/core/swap.c index a1631eaa552a37..5877e2ec87056d 100644 --- a/arch/posix/core/swap.c +++ b/arch/posix/core/swap.c @@ -18,6 +18,7 @@ #include "posix_core.h" #include "irq.h" #include "kswap.h" +#include int arch_swap(unsigned int key) { @@ -30,6 +31,9 @@ int arch_swap(unsigned int key) * and so forth. But we do not need to do so because we use posix * threads => those are all nicely kept by the native OS kernel */ +#if CONFIG_INSTRUMENT_THREAD_SWITCHING + z_thread_mark_switched_out(); +#endif _current->callee_saved.key = key; _current->callee_saved.retval = -EAGAIN; @@ -47,6 +51,9 @@ int arch_swap(unsigned int key) _current = _kernel.ready_q.cache; +#if CONFIG_INSTRUMENT_THREAD_SWITCHING + z_thread_mark_switched_in(); +#endif /* * Here a "real" arch would load all processor registers for the thread @@ -73,35 +80,41 @@ int arch_swap(unsigned int key) * Note that we will never come back to this thread: posix_main_thread_start() * does never return. */ -void arch_switch_to_main_thread(struct k_thread *main_thread, - k_thread_stack_t *main_stack, - size_t main_stack_size, k_thread_entry_t _main) +void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, + k_thread_entry_t _main) { + ARG_UNUSED(stack_ptr); + ARG_UNUSED(_main); + posix_thread_status_t *ready_thread_ptr = (posix_thread_status_t *) _kernel.ready_q.cache->callee_saved.thread_status; - sys_trace_thread_switched_out(); +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + z_thread_mark_switched_out(); +#endif _current = _kernel.ready_q.cache; - sys_trace_thread_switched_in(); +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + z_thread_mark_switched_in(); +#endif posix_main_thread_start(ready_thread_ptr->thread_idx); } /* LCOV_EXCL_LINE */ #endif -#ifdef CONFIG_SYS_POWER_MANAGEMENT +#ifdef CONFIG_PM /** * If the kernel is in idle mode, take it out */ void posix_irq_check_idle_exit(void) { if (_kernel.idle) { - s32_t idle_val = _kernel.idle; + int32_t idle_val = _kernel.idle; _kernel.idle = 0; - z_sys_power_save_idle_exit(idle_val); + z_pm_save_idle_exit(idle_val); } } #endif diff --git a/arch/posix/core/thread.c b/arch/posix/core/thread.c index dc1122a9da76e3..46840cb4133f3d 100644 --- a/arch/posix/core/thread.c +++ b/arch/posix/core/thread.c @@ -25,29 +25,22 @@ * pthreads stack and therefore we ignore the stack size */ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - size_t stack_size, k_thread_entry_t thread_func, - void *arg1, void *arg2, void *arg3, - int priority, unsigned int options) + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) { - char *stack_memory = Z_THREAD_STACK_BUFFER(stack); - posix_thread_status_t *thread_status; - z_new_thread_init(thread, stack_memory, stack_size); - /* We store it in the same place where normal archs store the * "initial stack frame" */ - thread_status = (posix_thread_status_t *) - Z_STACK_PTR_ALIGN(stack_memory + stack_size - - sizeof(*thread_status)); + thread_status = Z_STACK_PTR_TO_FRAME(posix_thread_status_t, stack_ptr); /* z_thread_entry() arguments */ - thread_status->entry_point = thread_func; - thread_status->arg1 = arg1; - thread_status->arg2 = arg2; - thread_status->arg3 = arg3; + thread_status->entry_point = entry; + thread_status->arg1 = p1; + thread_status->arg2 = p2; + thread_status->arg3 = p3; #if defined(CONFIG_ARCH_HAS_THREAD_ABORT) thread_status->aborted = 0; #endif diff --git a/arch/posix/include/kernel_arch_func.h b/arch/posix/include/kernel_arch_func.h index 553315a0fe1961..bb8d36a089c624 100644 --- a/arch/posix/include/kernel_arch_func.h +++ b/arch/posix/include/kernel_arch_func.h @@ -18,12 +18,6 @@ extern "C" { #endif -#if defined(CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN) -void arch_switch_to_main_thread(struct k_thread *main_thread, - k_thread_stack_t *main_stack, - size_t main_stack_size, k_thread_entry_t _main); -#endif - static inline void arch_kernel_init(void) { /* Nothing to be done */ diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index b7300cb31cfb8e..a2f310b688cd64 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -23,6 +23,15 @@ config FLOAT_HARD menu "RISCV Processor Options" +config CORE_E31 + bool "Use E31 core" + select RISCV_PMP + select ARCH_HAS_USERSPACE + select ARCH_HAS_STACK_PROTECTION if PMP_STACK_GUARD + default n + help + This option signifies the use of a core of the E31 family. + config INCLUDE_RESET_VECTOR bool "Include Reset vector" help @@ -104,6 +113,24 @@ config GEN_IRQ_VECTOR_TABLE config NUM_IRQS int +menuconfig RISCV_PMP + bool "RISC-V PMP Support" + default n + select THREAD_STACK_INFO + select CPU_HAS_MPU + select MPU + select SRAM_REGION_PERMISSIONS + select ARCH_MEM_DOMAIN_SYNCHRONOUS_API if USERSPACE + select PMP_POWER_OF_TWO_ALIGNMENT if USERSPACE + help + MCU implements Physical Memory Protection. + Memory protection against read-only area writing + is natively supported on real HW. + +if RISCV_PMP +source "arch/riscv/core/pmp/Kconfig" +endif #RISCV_PMP + endmenu endmenu diff --git a/arch/riscv/core/CMakeLists.txt b/arch/riscv/core/CMakeLists.txt index 653f2b4cf8a32f..5c485faddd5661 100644 --- a/arch/riscv/core/CMakeLists.txt +++ b/arch/riscv/core/CMakeLists.txt @@ -1,5 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 +add_subdirectory_ifdef(CONFIG_RISCV_PMP pmp) + zephyr_library() zephyr_library_sources( @@ -13,4 +15,6 @@ zephyr_library_sources( thread.c ) -zephyr_library_sources_if_kconfig(irq_offload.c) +zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) +zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) diff --git a/arch/riscv/core/fatal.c b/arch/riscv/core/fatal.c index 2380f22fa29c39..e52baa498f2f2c 100644 --- a/arch/riscv/core/fatal.c +++ b/arch/riscv/core/fatal.c @@ -7,8 +7,17 @@ #include #include #include +#include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); + +#ifdef CONFIG_USERSPACE +Z_EXC_DECLARE(z_riscv_user_string_nlen); + +static const struct z_exc_handle exceptions[] = { + Z_EXC_HANDLE(z_riscv_user_string_nlen), +}; +#endif /* CONFIG_USERSPACE */ FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason, const z_arch_esf_t *esf) @@ -52,8 +61,23 @@ static char *cause_str(ulong_t cause) } } -FUNC_NORETURN void _Fault(const z_arch_esf_t *esf) +void _Fault(z_arch_esf_t *esf) { +#ifdef CONFIG_USERSPACE + /* + * Perform an assessment whether an PMP fault shall be + * treated as recoverable. + */ + for (int i = 0; i < ARRAY_SIZE(exceptions); i++) { + uint32_t start = (uint32_t)exceptions[i].start; + uint32_t end = (uint32_t)exceptions[i].end; + + if (esf->mepc >= start && esf->mepc < end) { + esf->mepc = (uint32_t)exceptions[i].fixup; + return; + } + } +#endif /* CONFIG_USERSPACE */ ulong_t mcause; __asm__ volatile("csrr %0, mcause" : "=r" (mcause)); @@ -63,3 +87,30 @@ FUNC_NORETURN void _Fault(const z_arch_esf_t *esf) z_riscv_fatal_error(K_ERR_CPU_EXCEPTION, esf); } + +#ifdef CONFIG_USERSPACE +FUNC_NORETURN void arch_syscall_oops(void *ssf_ptr) +{ + user_fault(K_ERR_KERNEL_OOPS); + CODE_UNREACHABLE; +} + +void z_impl_user_fault(unsigned int reason) +{ + z_arch_esf_t *oops_esf = _current->syscall_frame; + + if (((_current->base.user_options & K_USER) != 0) && + reason != K_ERR_STACK_CHK_FAIL) { + reason = K_ERR_KERNEL_OOPS; + } + z_riscv_fatal_error(reason, oops_esf); +} + +static void z_vrfy_user_fault(unsigned int reason) +{ + z_impl_user_fault(reason); +} + +#include + +#endif /* CONFIG_USERSPACE */ diff --git a/arch/riscv/core/irq_manage.c b/arch/riscv/core/irq_manage.c index b852433e9ed04f..d7a9b18796412f 100644 --- a/arch/riscv/core/irq_manage.c +++ b/arch/riscv/core/irq_manage.c @@ -7,9 +7,9 @@ #include #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); -FUNC_NORETURN void z_irq_spurious(void *unused) +FUNC_NORETURN void z_irq_spurious(const void *unused) { ulong_t mcause; @@ -31,8 +31,8 @@ FUNC_NORETURN void z_irq_spurious(void *unused) #ifdef CONFIG_DYNAMIC_INTERRUPTS int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *parameter), void *parameter, - u32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { ARG_UNUSED(flags); diff --git a/arch/riscv/core/irq_offload.c b/arch/riscv/core/irq_offload.c index 2ba4d413f750e0..22b22431c46243 100644 --- a/arch/riscv/core/irq_offload.c +++ b/arch/riscv/core/irq_offload.c @@ -9,7 +9,7 @@ #include volatile irq_offload_routine_t _offload_routine; -static volatile void *offload_param; +static volatile const void *offload_param; /* * Called by _enter_irq @@ -28,10 +28,10 @@ void z_irq_do_offload(void) tmp = _offload_routine; _offload_routine = NULL; - tmp((void *)offload_param); + tmp((const void *)offload_param); } -void arch_irq_offload(irq_offload_routine_t routine, void *parameter) +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { unsigned int key; diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index ff912f79adccb5..eeabab751a1c01 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -1,6 +1,7 @@ /* * Copyright (c) 2016 Jean-Paul Etienne * Copyright (c) 2018 Foundries.io Ltd + * Copyright (c) 2020 BayLibre, SAS * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +12,8 @@ #include #include #include +#include +#include /* Convenience macros for loading/storing register states. */ @@ -66,6 +69,156 @@ fscsr x0, t2 ;\ DO_FP_CALLEE_SAVED(RV_OP_LOADFPREG, reg) +#define COPY_ESF_FP_STATE(to_reg, from_reg, temp) \ + RV_OP_LOADREG temp, __z_arch_esf_t_fp_state_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_fp_state_OFFSET(to_reg) ; + +#define COPY_ESF_FP(to_reg, from_reg, temp) \ + RV_OP_LOADREG temp, __z_arch_esf_t_ft0_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft0_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft1_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft1_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft2_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft2_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft3_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft3_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft4_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft4_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft5_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft5_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft6_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft6_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft7_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft7_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft8_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft8_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft9_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft9_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft10_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft10_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ft11_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ft11_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_fa0_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_fa0_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_fa1_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_fa1_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_fa2_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_fa2_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_fa3_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_fa3_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_fa4_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_fa4_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_fa5_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_fa5_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_fa6_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_fa6_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_fa7_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_fa7_OFFSET(to_reg) ; + +#define COPY_ESF(to_reg, from_reg, temp) \ + RV_OP_LOADREG temp, __z_arch_esf_t_mepc_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_mepc_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_mstatus_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_mstatus_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_ra_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_ra_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_gp_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_gp_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_tp_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_tp_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_t0_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_t0_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_t1_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_t1_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_t2_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_t2_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_t3_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_t3_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_t4_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_t4_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_t5_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_t5_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_t6_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_t6_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_a0_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_a0_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_a1_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_a1_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_a2_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_a2_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_a3_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_a3_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_a4_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_a4_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_a5_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_a5_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_a6_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_a6_OFFSET(to_reg) ;\ + RV_OP_LOADREG temp, __z_arch_esf_t_a7_OFFSET(from_reg) ;\ + RV_OP_STOREREG temp, __z_arch_esf_t_a7_OFFSET(to_reg) ; + +#define DO_CALLEE_SAVED(op, reg) \ + op s0, _thread_offset_to_s0(reg) ;\ + op s1, _thread_offset_to_s1(reg) ;\ + op s2, _thread_offset_to_s2(reg) ;\ + op s3, _thread_offset_to_s3(reg) ;\ + op s4, _thread_offset_to_s4(reg) ;\ + op s5, _thread_offset_to_s5(reg) ;\ + op s6, _thread_offset_to_s6(reg) ;\ + op s7, _thread_offset_to_s7(reg) ;\ + op s8, _thread_offset_to_s8(reg) ;\ + op s9, _thread_offset_to_s9(reg) ;\ + op s10, _thread_offset_to_s10(reg) ;\ + op s11, _thread_offset_to_s11(reg) ; + +#define STORE_CALLEE_SAVED(reg) \ + DO_CALLEE_SAVED(RV_OP_STOREREG, reg) + +#define LOAD_CALLER_SAVED(reg) \ + DO_CALLEE_SAVED(RV_OP_LOADREG, reg) + +#define DO_CALLER_SAVED(op) \ + op ra, __z_arch_esf_t_ra_OFFSET(sp) ;\ + op gp, __z_arch_esf_t_gp_OFFSET(sp) ;\ + op tp, __z_arch_esf_t_tp_OFFSET(sp) ;\ + op t0, __z_arch_esf_t_t0_OFFSET(sp) ;\ + op t1, __z_arch_esf_t_t1_OFFSET(sp) ;\ + op t2, __z_arch_esf_t_t2_OFFSET(sp) ;\ + op t3, __z_arch_esf_t_t3_OFFSET(sp) ;\ + op t4, __z_arch_esf_t_t4_OFFSET(sp) ;\ + op t5, __z_arch_esf_t_t5_OFFSET(sp) ;\ + op t6, __z_arch_esf_t_t6_OFFSET(sp) ;\ + op a0, __z_arch_esf_t_a0_OFFSET(sp) ;\ + op a1, __z_arch_esf_t_a1_OFFSET(sp) ;\ + op a2, __z_arch_esf_t_a2_OFFSET(sp) ;\ + op a3, __z_arch_esf_t_a3_OFFSET(sp) ;\ + op a4, __z_arch_esf_t_a4_OFFSET(sp) ;\ + op a5, __z_arch_esf_t_a5_OFFSET(sp) ;\ + op a6, __z_arch_esf_t_a6_OFFSET(sp) ;\ + op a7, __z_arch_esf_t_a7_OFFSET(sp) ; + +#define STORE_CALLER_SAVED() \ + addi sp, sp, -__z_arch_esf_t_SIZEOF ;\ + DO_CALLER_SAVED(RV_OP_STOREREG) ; + +#define LOAD_CALLEE_SAVED() \ + DO_CALLER_SAVED(RV_OP_LOADREG) ;\ + addi sp, sp, __z_arch_esf_t_SIZEOF ; + +/* + * @brief Check previous mode. + * + * @param ret Register to return value. + * @param temp Register used foor temporary value. + * + * @return 0 if previous mode is user. + */ +#define WAS_NOT_USER(ret, temp) \ + RV_OP_LOADREG ret, __z_arch_esf_t_mstatus_OFFSET(sp) ;\ + li temp, MSTATUS_MPP ;\ + and ret, ret, temp ; + + /* imports */ GDATA(_sw_isr_table) GTEXT(__soc_is_irq) @@ -80,15 +233,30 @@ GTEXT(_k_neg_eagain) GTEXT(_is_next_thread_current) GTEXT(z_get_next_ready_thread) +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING +GTEXT(z_thread_mark_switched_in) +GTEXT(z_thread_mark_switched_out) #ifdef CONFIG_TRACING -GTEXT(sys_trace_thread_switched_in) GTEXT(sys_trace_isr_enter) #endif +#endif #ifdef CONFIG_IRQ_OFFLOAD GTEXT(_offload_routine) #endif +#ifdef CONFIG_USERSPACE +GTEXT(z_riscv_do_syscall) +GTEXT(z_riscv_configure_user_allowed_stack) +GTEXT(z_interrupt_stacks) +GTEXT(z_riscv_do_syscall_start) +GTEXT(z_riscv_do_syscall_end) +#endif + +#ifdef CONFIG_PMP_STACK_GUARD +GTEXT(z_riscv_configure_stack_guard) +#endif + /* exports */ GTEXT(__irq_wrapper) @@ -121,28 +289,19 @@ GTEXT(__irq_wrapper) * switching or IRQ offloading (when enabled). */ SECTION_FUNC(exception.entry, __irq_wrapper) - /* Allocate space on thread stack to save registers */ - addi sp, sp, -__z_arch_esf_t_SIZEOF - /* Save caller-saved registers on current thread stack. */ - RV_OP_STOREREG ra, __z_arch_esf_t_ra_OFFSET(sp) - RV_OP_STOREREG gp, __z_arch_esf_t_gp_OFFSET(sp) - RV_OP_STOREREG tp, __z_arch_esf_t_tp_OFFSET(sp) - RV_OP_STOREREG t0, __z_arch_esf_t_t0_OFFSET(sp) - RV_OP_STOREREG t1, __z_arch_esf_t_t1_OFFSET(sp) - RV_OP_STOREREG t2, __z_arch_esf_t_t2_OFFSET(sp) - RV_OP_STOREREG t3, __z_arch_esf_t_t3_OFFSET(sp) - RV_OP_STOREREG t4, __z_arch_esf_t_t4_OFFSET(sp) - RV_OP_STOREREG t5, __z_arch_esf_t_t5_OFFSET(sp) - RV_OP_STOREREG t6, __z_arch_esf_t_t6_OFFSET(sp) - RV_OP_STOREREG a0, __z_arch_esf_t_a0_OFFSET(sp) - RV_OP_STOREREG a1, __z_arch_esf_t_a1_OFFSET(sp) - RV_OP_STOREREG a2, __z_arch_esf_t_a2_OFFSET(sp) - RV_OP_STOREREG a3, __z_arch_esf_t_a3_OFFSET(sp) - RV_OP_STOREREG a4, __z_arch_esf_t_a4_OFFSET(sp) - RV_OP_STOREREG a5, __z_arch_esf_t_a5_OFFSET(sp) - RV_OP_STOREREG a6, __z_arch_esf_t_a6_OFFSET(sp) - RV_OP_STOREREG a7, __z_arch_esf_t_a7_OFFSET(sp) +#ifdef CONFIG_PMP_STACK_GUARD + /* Jump at the beginning of IRQ stack to avoid stack overflow */ + csrrw sp, mscratch, sp +#endif /* CONFIG_PMP_STACK_GUARD */ + + /* + * Save caller-saved registers on current thread stack. + * NOTE: need to be updated to account for floating-point registers + * floating-point registers should be accounted for when corresponding + * config variable is set + */ + STORE_CALLER_SAVED() #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) /* Assess whether floating-point registers need to be saved. */ @@ -155,7 +314,7 @@ SECTION_FUNC(exception.entry, __irq_wrapper) STORE_FP_CALLER_SAVED(sp) skip_store_fp_caller_saved: -#endif +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ /* Save MEPC register */ csrr t0, mepc @@ -171,9 +330,43 @@ skip_store_fp_caller_saved: jal ra, __soc_save_context #endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - call read_timer_start_of_isr -#endif +#ifdef CONFIG_USERSPACE + /* Check if we are in user stack by checking previous privilege mode */ + WAS_NOT_USER(t0, t1) + bnez t0, is_priv_sp + + la t0, _kernel + RV_OP_LOADREG t1, _kernel_offset_to_current(t0) + + /* Save user stack pointer */ +#ifdef CONFIG_PMP_STACK_GUARD + csrr t2, mscratch +#else + mv t2, sp +#endif /* CONFIG_PMP_STACK_GUARD */ + RV_OP_STOREREG t2, _thread_offset_to_user_sp(t1) + /* + * Save callee-saved registers of user thread here + * because rescheduling will occur in nested ecall, + * that mean these registers will be out of context + * at reschedule time. + */ + STORE_CALLEE_SAVED(t1) + +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + /* Assess whether floating-point registers need to be saved. */ + RV_OP_LOADREG t2, _thread_offset_to_user_options(t1) + andi t2, t2, K_FP_REGS + beqz t2, skip_store_fp_callee_saved_user + STORE_FP_CALLEE_SAVED(t1) +skip_store_fp_callee_saved_user: +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + +is_priv_sp: + /* Clear user mode variable */ + la t0, is_user_mode + sb zero, 0x00(t0) +#endif /* CONFIG_USERSPACE */ /* * Check if exception is the result of an interrupt or not. @@ -191,6 +384,12 @@ skip_store_fp_caller_saved: addi t1, x0, 0 bnez a0, is_interrupt +#ifdef CONFIG_USERSPACE + /* Reset IRQ flag */ + la t1, irq_flag + sb zero, 0x00(t1) +#endif /* CONFIG_USERSPACE */ + /* * If the exception is the result of an ECALL, check whether to * perform a context-switch or an IRQ offload. Otherwise call _Fault @@ -202,23 +401,54 @@ skip_store_fp_caller_saved: li t1, SOC_MCAUSE_ECALL_EXP /* - * If mcause == SOC_MCAUSE_ECALL_EXP, handle system call, - * otherwise handle fault + * If mcause == SOC_MCAUSE_ECALL_EXP, handle system call from + * kernel thread. + */ + beq t0, t1, is_kernel_syscall + +#ifdef CONFIG_USERSPACE + li t1, SOC_MCAUSE_USER_ECALL_EXP + + /* + * If mcause == SOC_MCAUSE_USER_ECALL_EXP, handle system call from + * user thread, otherwise handle fault. */ - beq t0, t1, is_syscall + beq t0, t1, is_user_syscall +#endif /* CONFIG_USERSPACE */ /* * Call _Fault to handle exception. * Stack pointer is pointing to a z_arch_esf_t structure, pass it * to _Fault (via register a0). - * If _Fault shall return, set return address to no_reschedule - * to restore stack. + * If _Fault shall return, set return address to + * no_reschedule to restore stack. */ addi a0, sp, 0 + +#ifdef CONFIG_USERSPACE + la ra, no_reschedule_from_fault + /* Switch to privilege stack */ + la t0, _kernel + RV_OP_LOADREG t1, _kernel_offset_to_current(t0) + RV_OP_LOADREG t0, _thread_offset_to_priv_stack_start(t1) + RV_OP_STOREREG sp, _thread_offset_to_user_sp(t1) /* Update user SP */ + addi sp, t0, CONFIG_PRIVILEGED_STACK_SIZE +#else la ra, no_reschedule +#endif /* CONFIG_USERSPACE */ + tail _Fault -is_syscall: +is_kernel_syscall: +#ifdef CONFIG_USERSPACE + /* Check if it is a return from user syscall */ + csrr t0, mepc + la t1, z_riscv_do_syscall_start + bltu t0, t1, not_user_syscall + la t1, z_riscv_do_syscall_end + bleu t0, t1, return_from_syscall +not_user_syscall: +#endif /* CONFIG_USERSPACE */ /* * A syscall is the result of an ecall instruction, in which case the * MEPC will contain the address of the ecall instruction. @@ -242,14 +472,186 @@ is_syscall: la t0, _offload_routine RV_OP_LOADREG t1, 0x00(t0) bnez t1, is_interrupt -#endif +#endif /* CONFIG_IRQ_OFFLOAD */ + +#ifdef CONFIG_PMP_STACK_GUARD + li t0, MSTATUS_MPRV + csrs mstatus, t0 + + /* Move to current thread SP and move ESF */ + csrrw sp, mscratch, sp + csrr t0, mscratch + addi sp, sp, -__z_arch_esf_t_SIZEOF +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + RV_OP_LOADREG t1, __z_arch_esf_t_fp_state_OFFSET(t0) + beqz t1, skip_fp_move_kernel_syscall + COPY_ESF_FP(sp, t0, t1) +skip_fp_move_kernel_syscall: + COPY_ESF_FP_STATE(sp, t0, t1) +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + + COPY_ESF(sp, t0, t1) + addi t0, t0, __z_arch_esf_t_SIZEOF + csrw mscratch, t0 +#endif /* CONFIG_PMP_STACK_GUARD */ + +#ifdef CONFIG_USERSPACE + /* + * Check for forced syscall, + * otherwise go to reschedule to handle context-switch + */ + li t0, FORCE_SYSCALL_ID + bne a7, t0, reschedule + + RV_OP_LOADREG a0, __z_arch_esf_t_a0_OFFSET(sp) + + /* Check for user_mode_enter function */ + la t0, arch_user_mode_enter + bne t0, a0, reschedule + + RV_OP_LOADREG a0, __z_arch_esf_t_a1_OFFSET(sp) + RV_OP_LOADREG a1, __z_arch_esf_t_a2_OFFSET(sp) + RV_OP_LOADREG a2, __z_arch_esf_t_a3_OFFSET(sp) + RV_OP_LOADREG a3, __z_arch_esf_t_a4_OFFSET(sp) + /* + * MRET will be done in the following function because + * restore caller-saved registers is not need anymore + * due to user mode jump (new stack/context). + */ + j z_riscv_user_mode_enter_syscall +#endif /* CONFIG_USERSPACE */ /* * Go to reschedule to handle context-switch */ j reschedule +#ifdef CONFIG_USERSPACE +is_user_syscall: + +#ifdef CONFIG_PMP_STACK_GUARD + la t0, _kernel + RV_OP_LOADREG a0, _kernel_offset_to_current(t0) + jal ra, z_riscv_configure_stack_guard +#endif /* CONFIG_PMP_STACK_GUARD */ + + /* + * A syscall is the result of an ecall instruction, in which case the + * MEPC will contain the address of the ecall instruction. + * Increment saved MEPC by 4 to prevent triggering the same ecall + * again upon exiting the ISR. + * + * It is safe to always increment by 4, even with compressed + * instructions, because the ecall instruction is always 4 bytes. + */ + RV_OP_LOADREG t1, __z_arch_esf_t_mepc_OFFSET(sp) + addi t1, t1, 4 + RV_OP_STOREREG t1, __z_arch_esf_t_mepc_OFFSET(sp) +#ifdef CONFIG_PMP_STACK_GUARD + /* + * Copy ESF to user stack in case of rescheduling + * directly from kernel ECALL (nested ECALL) + */ + csrrw sp, mscratch, sp + csrr t0, mscratch + addi sp, sp, -__z_arch_esf_t_SIZEOF +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + RV_OP_LOADREG t1, __z_arch_esf_t_fp_state_OFFSET(t0) + beqz t1, skip_fp_copy_user_syscall + COPY_ESF_FP(sp, t0, t1) +skip_fp_copy_user_syscall: + COPY_ESF_FP_STATE(sp, t0, t1) +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + COPY_ESF(sp, t0, t1) +#endif /* CONFIG_PMP_STACK_GUARD */ + /* Restore argument registers from user stack */ + RV_OP_LOADREG a0, __z_arch_esf_t_a0_OFFSET(sp) + RV_OP_LOADREG a1, __z_arch_esf_t_a1_OFFSET(sp) + RV_OP_LOADREG a2, __z_arch_esf_t_a2_OFFSET(sp) + RV_OP_LOADREG a3, __z_arch_esf_t_a3_OFFSET(sp) + RV_OP_LOADREG a4, __z_arch_esf_t_a4_OFFSET(sp) + RV_OP_LOADREG a5, __z_arch_esf_t_a5_OFFSET(sp) + mv a6, sp + RV_OP_LOADREG a7, __z_arch_esf_t_a7_OFFSET(sp) + + /* Switch to privilege stack */ + la t0, _kernel + RV_OP_LOADREG t1, _kernel_offset_to_current(t0) + RV_OP_LOADREG t0, _thread_offset_to_priv_stack_start(t1) + RV_OP_STOREREG sp, _thread_offset_to_user_sp(t1) /* Update user SP */ + addi sp, t0, CONFIG_PRIVILEGED_STACK_SIZE + + /* validate syscall limit */ + li t0, K_SYSCALL_LIMIT + bltu a7, t0, valid_syscall_id + + /* bad syscall id. Set arg1 to bad id and set call_id to SYSCALL_BAD */ + mv a0, a7 + li a7, K_SYSCALL_BAD + +valid_syscall_id: + + /* Prepare to jump into do_syscall function */ + la t0, z_riscv_do_syscall + csrw mepc, t0 + + /* Force kernel mode for syscall execution */ + li t0, MSTATUS_MPP + csrs mstatus, t0 + SOC_ERET + +return_from_syscall: + /* + * Retrieve a0 (returned value) from privilege stack + * (or IRQ stack if stack guard is enabled). + */ + RV_OP_LOADREG a0, __z_arch_esf_t_a0_OFFSET(sp) + +no_reschedule_from_fault: + /* Restore User SP */ + la t0, _kernel + RV_OP_LOADREG t1, _kernel_offset_to_current(t0) + RV_OP_LOADREG sp, _thread_offset_to_user_sp(t1) + + /* Update a0 (return value) */ + RV_OP_STOREREG a0, __z_arch_esf_t_a0_OFFSET(sp) + +#ifdef CONFIG_PMP_STACK_GUARD + /* Move to IRQ stack start */ + csrw mscratch, sp /* Save user sp */ + la t2, z_interrupt_stacks + li t3, CONFIG_ISR_STACK_SIZE + add sp, t2, t3 + + /* + * Copy ESF to IRQ stack from user stack + * to execute "no_reschedule" properly. + */ + csrr t0, mscratch + addi sp, sp, -__z_arch_esf_t_SIZEOF +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + RV_OP_LOADREG t1, __z_arch_esf_t_fp_state_OFFSET(t0) + beqz t1, skip_fp_copy_return_user_syscall + COPY_ESF_FP(sp, t0, t1) +skip_fp_copy_return_user_syscall: + COPY_ESF_FP_STATE(sp, t0, t1) +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + COPY_ESF(sp, t0, t1) + +#endif /* CONFIG_PMP_STACK_GUARD */ + + j no_reschedule + +#endif /* CONFIG_USERSPACE */ + is_interrupt: +#ifdef CONFIG_USERSPACE + la t0, irq_flag + li t2, 0x1 + sb t2, 0x00(t0) +#endif /* CONFIG_USERSPACE */ + +#if (CONFIG_USERSPACE == 0) && (CONFIG_PMP_STACK_GUARD == 0) /* * Save current thread stack pointer and switch * stack pointer to interrupt stack. @@ -268,6 +670,9 @@ is_interrupt: */ addi sp, sp, -16 RV_OP_STOREREG t0, 0x00(sp) +#else + la t2, _kernel +#endif /* !CONFIG_USERSPACE && !CONFIG_PMP_STACK_GUARD */ on_irq_stack: /* Increment _kernel.cpus[0].nested variable */ @@ -321,15 +726,6 @@ call_irq: /* Load ISR function address in register t1 */ RV_OP_LOADREG t1, RV_REGSIZE(t0) -#ifdef CONFIG_EXECUTION_BENCHMARKING - addi sp, sp, -16 - RV_OP_STOREREG a0, 0x00(sp) - RV_OP_STOREREG t1, RV_REGSIZE(sp) - call read_timer_end_of_isr - RV_OP_LOADREG t1, RV_REGSIZE(sp) - RV_OP_LOADREG a0, 0x00(sp) - addi sp, sp, 16 -#endif /* Call ISR function */ jalr ra, t1 @@ -342,9 +738,11 @@ on_thread_stack: addi t2, t2, -1 sw t2, _kernel_offset_to_nested(t1) +#if !defined(CONFIG_USERSPACE) && !defined(CONFIG_PMP_STACK_GUARD) /* Restore thread stack pointer */ RV_OP_LOADREG t0, 0x00(sp) addi sp, t0, 0 +#endif /* !CONFIG_USERSPACE && !CONFIG_PMP_STACK_GUARD */ #ifdef CONFIG_STACK_SENTINEL call z_check_stack_sentinel @@ -369,9 +767,56 @@ on_thread_stack: j no_reschedule #endif /* CONFIG_PREEMPT_ENABLED */ +#ifdef CONFIG_PMP_STACK_GUARD + RV_OP_LOADREG a0, _kernel_offset_to_current(t1) + jal ra, z_riscv_configure_stack_guard + + /* + * Move to saved SP and move ESF to retrieve it + * after reschedule. + */ + csrrw sp, mscratch, sp + csrr t0, mscratch + addi sp, sp, -__z_arch_esf_t_SIZEOF +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + RV_OP_LOADREG t1, __z_arch_esf_t_fp_state_OFFSET(t0) + beqz t1, skip_fp_move_irq + COPY_ESF_FP(sp, t0, t1) +skip_fp_move_irq: + COPY_ESF_FP_STATE(sp, t0, t1) +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + COPY_ESF(sp, t0, t1) + addi t0, t0, __z_arch_esf_t_SIZEOF + csrw mscratch, t0 +#endif /* CONFIG_PMP_STACK_GUARD */ + +#ifdef CONFIG_USERSPACE + /* Check if we are in user thread */ + WAS_NOT_USER(t3, t4) + bnez t3, reschedule + + /* + * Switch to privilege stack because we want + * this starting point after reschedule. + */ + RV_OP_LOADREG t3, _thread_offset_to_priv_stack_start(t2) + RV_OP_STOREREG sp, _thread_offset_to_user_sp(t2) /* Save user SP */ + mv t0, sp + addi sp, t3, CONFIG_PRIVILEGED_STACK_SIZE + + /* + * Copy Saved ESF to priv stack, that will allow us to know during + * rescheduling if the thread was working on user mode. + */ + addi sp, sp, -__z_arch_esf_t_SIZEOF + COPY_ESF(sp, t0, t1) + +#endif /* CONFIG_USERSPACE */ + reschedule: -#if CONFIG_TRACING - call sys_trace_thread_switched_in + +#if CONFIG_INSTRUMENT_THREAD_SWITCHING + call z_thread_mark_switched_out #endif /* Get reference to _kernel */ la t0, _kernel @@ -379,22 +824,20 @@ reschedule: /* Get pointer to _kernel.current */ RV_OP_LOADREG t1, _kernel_offset_to_current(t0) +#ifdef CONFIG_USERSPACE /* - * Save callee-saved registers of current thread + * Check the thread mode and skip callee saved storing + * because it is already done for user + */ + WAS_NOT_USER(t6, t4) + beqz t6, skip_callee_saved_reg +#endif /* CONFIG_USERSPACE */ + + /* + * Save callee-saved registers of current kernel thread * prior to handle context-switching */ - RV_OP_STOREREG s0, _thread_offset_to_s0(t1) - RV_OP_STOREREG s1, _thread_offset_to_s1(t1) - RV_OP_STOREREG s2, _thread_offset_to_s2(t1) - RV_OP_STOREREG s3, _thread_offset_to_s3(t1) - RV_OP_STOREREG s4, _thread_offset_to_s4(t1) - RV_OP_STOREREG s5, _thread_offset_to_s5(t1) - RV_OP_STOREREG s6, _thread_offset_to_s6(t1) - RV_OP_STOREREG s7, _thread_offset_to_s7(t1) - RV_OP_STOREREG s8, _thread_offset_to_s8(t1) - RV_OP_STOREREG s9, _thread_offset_to_s9(t1) - RV_OP_STOREREG s10, _thread_offset_to_s10(t1) - RV_OP_STOREREG s11, _thread_offset_to_s11(t1) + STORE_CALLEE_SAVED(t1) #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) /* Assess whether floating-point registers need to be saved. */ @@ -404,7 +847,20 @@ reschedule: STORE_FP_CALLEE_SAVED(t1) skip_store_fp_callee_saved: -#endif +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + +skip_callee_saved_reg: +#ifdef CONFIG_PMP_STACK_GUARD + /* + * Reset mscratch value because is simpler + * than remove user ESF, and prevent unknown corner cases + */ + la t2, z_interrupt_stacks + li t3, CONFIG_ISR_STACK_SIZE + add t2, t2, t3 + csrw mscratch, t2 + +#endif /* CONFIG_PMP_STACK_GUARD */ /* * Save stack pointer of current thread and set the default return value @@ -427,18 +883,7 @@ skip_store_fp_callee_saved: RV_OP_LOADREG sp, _thread_offset_to_sp(t1) /* Restore callee-saved registers of new thread */ - RV_OP_LOADREG s0, _thread_offset_to_s0(t1) - RV_OP_LOADREG s1, _thread_offset_to_s1(t1) - RV_OP_LOADREG s2, _thread_offset_to_s2(t1) - RV_OP_LOADREG s3, _thread_offset_to_s3(t1) - RV_OP_LOADREG s4, _thread_offset_to_s4(t1) - RV_OP_LOADREG s5, _thread_offset_to_s5(t1) - RV_OP_LOADREG s6, _thread_offset_to_s6(t1) - RV_OP_LOADREG s7, _thread_offset_to_s7(t1) - RV_OP_LOADREG s8, _thread_offset_to_s8(t1) - RV_OP_LOADREG s9, _thread_offset_to_s9(t1) - RV_OP_LOADREG s10, _thread_offset_to_s10(t1) - RV_OP_LOADREG s11, _thread_offset_to_s11(t1) + LOAD_CALLER_SAVED(t1) #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) /* Determine if we need to restore floating-point registers. */ @@ -458,76 +903,107 @@ skip_store_fp_callee_saved: LOAD_FP_CALLEE_SAVED(t1) skip_load_fp_callee_saved: -#endif +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - addi sp, sp, -__z_arch_esf_t_SIZEOF +#ifdef CONFIG_PMP_STACK_GUARD + mv a0, t1 /* kernel current */ + jal ra, z_riscv_configure_stack_guard +#endif // CONFIG_PMP_STACK_GUARD - RV_OP_STOREREG ra, __z_arch_esf_t_ra_OFFSET(sp) - RV_OP_STOREREG gp, __z_arch_esf_t_gp_OFFSET(sp) - RV_OP_STOREREG tp, __z_arch_esf_t_tp_OFFSET(sp) - RV_OP_STOREREG t0, __z_arch_esf_t_t0_OFFSET(sp) - RV_OP_STOREREG t1, __z_arch_esf_t_t1_OFFSET(sp) - RV_OP_STOREREG t2, __z_arch_esf_t_t2_OFFSET(sp) - RV_OP_STOREREG t3, __z_arch_esf_t_t3_OFFSET(sp) - RV_OP_STOREREG t4, __z_arch_esf_t_t4_OFFSET(sp) - RV_OP_STOREREG t5, __z_arch_esf_t_t5_OFFSET(sp) - RV_OP_STOREREG t6, __z_arch_esf_t_t6_OFFSET(sp) - RV_OP_STOREREG a0, __z_arch_esf_t_a0_OFFSET(sp) - RV_OP_STOREREG a1, __z_arch_esf_t_a1_OFFSET(sp) - RV_OP_STOREREG a2, __z_arch_esf_t_a2_OFFSET(sp) - RV_OP_STOREREG a3, __z_arch_esf_t_a3_OFFSET(sp) - RV_OP_STOREREG a4, __z_arch_esf_t_a4_OFFSET(sp) - RV_OP_STOREREG a5, __z_arch_esf_t_a5_OFFSET(sp) - RV_OP_STOREREG a6, __z_arch_esf_t_a6_OFFSET(sp) - RV_OP_STOREREG a7, __z_arch_esf_t_a7_OFFSET(sp) +#ifdef CONFIG_USERSPACE + /* t0 still reference to _kernel */ + /* t1 still pointer to _kernel.current */ -#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - /* Assess whether floating-point registers need to be saved. */ - RV_OP_LOADREG t2, _thread_offset_to_user_options(sp) - andi t2, t2, K_FP_REGS - RV_OP_STOREREG t2, __z_arch_esf_t_fp_state_OFFSET(sp) - beqz t2, skip_store_fp_caller_saved_benchmark - STORE_FP_CALLER_SAVED(sp) + /* Check the thread mode */ + WAS_NOT_USER(t2, t4) + bnez t2, kernel_swap + + /* Switch to user stack */ + RV_OP_LOADREG sp, _thread_offset_to_user_sp(t1) + + /* Setup User allowed stack */ + li t0, MSTATUS_MPRV + csrc mstatus, t0 + mv a0, t1 + jal ra, z_riscv_configure_user_allowed_stack -skip_store_fp_caller_saved_benchmark: + /* Set user mode variable */ + li t2, 0x1 + la t3, is_user_mode + sb t2, 0x00(t3) + +kernel_swap: +#endif /* CONFIG_USERSPACE */ + +#if CONFIG_INSTRUMENT_THREAD_SWITCHING + call z_thread_mark_switched_in #endif - call read_timer_end_of_swap +#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE + /* Restore context at SOC level */ + addi a0, sp, __z_arch_esf_t_soc_context_OFFSET + jal ra, __soc_restore_context +#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */ + + /* Restore MEPC register */ + RV_OP_LOADREG t0, __z_arch_esf_t_mepc_OFFSET(sp) + csrw mepc, t0 + + /* Restore SOC-specific MSTATUS register */ + RV_OP_LOADREG t0, __z_arch_esf_t_mstatus_OFFSET(sp) + csrw mstatus, t0 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - /* Determine if we need to restore floating-point registers. */ - RV_OP_LOADREG t2, __z_arch_esf_t_fp_state_OFFSET(sp) - beqz t2, skip_load_fp_caller_saved_benchmark + /* + * Determine if we need to restore floating-point registers. This needs + * to happen before restoring integer registers to avoid stomping on + * t0. + */ + RV_OP_LOADREG t0, __z_arch_esf_t_fp_state_OFFSET(sp) + beqz t0, skip_load_fp_caller_saved_resched LOAD_FP_CALLER_SAVED(sp) -skip_load_fp_caller_saved_benchmark: -#endif +skip_load_fp_caller_saved_resched: +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ - RV_OP_LOADREG ra, __z_arch_esf_t_ra_OFFSET(sp) - RV_OP_LOADREG gp, __z_arch_esf_t_gp_OFFSET(sp) - RV_OP_LOADREG tp, __z_arch_esf_t_tp_OFFSET(sp) - RV_OP_LOADREG t0, __z_arch_esf_t_t0_OFFSET(sp) - RV_OP_LOADREG t1, __z_arch_esf_t_t1_OFFSET(sp) - RV_OP_LOADREG t2, __z_arch_esf_t_t2_OFFSET(sp) - RV_OP_LOADREG t3, __z_arch_esf_t_t3_OFFSET(sp) - RV_OP_LOADREG t4, __z_arch_esf_t_t4_OFFSET(sp) - RV_OP_LOADREG t5, __z_arch_esf_t_t5_OFFSET(sp) - RV_OP_LOADREG t6, __z_arch_esf_t_t6_OFFSET(sp) - RV_OP_LOADREG a0, __z_arch_esf_t_a0_OFFSET(sp) - RV_OP_LOADREG a1, __z_arch_esf_t_a1_OFFSET(sp) - RV_OP_LOADREG a2, __z_arch_esf_t_a2_OFFSET(sp) - RV_OP_LOADREG a3, __z_arch_esf_t_a3_OFFSET(sp) - RV_OP_LOADREG a4, __z_arch_esf_t_a4_OFFSET(sp) - RV_OP_LOADREG a5, __z_arch_esf_t_a5_OFFSET(sp) - RV_OP_LOADREG a6, __z_arch_esf_t_a6_OFFSET(sp) - RV_OP_LOADREG a7, __z_arch_esf_t_a7_OFFSET(sp) + /* Restore caller-saved registers from thread stack */ + LOAD_CALLEE_SAVED() - /* Release stack space */ - addi sp, sp, __z_arch_esf_t_SIZEOF -#endif + /* Call SOC_ERET to exit ISR */ + SOC_ERET no_reschedule: + +#ifdef CONFIG_USERSPACE + + /* Check if we are in user thread */ + WAS_NOT_USER(t2, t4) + bnez t2, no_enter_user + + li t0, MSTATUS_MPRV + csrc mstatus, t0 + + la t0, _kernel + RV_OP_LOADREG a0, _kernel_offset_to_current(t0) + jal ra, z_riscv_configure_user_allowed_stack + + /* Set user mode variable */ + li t1, 0x1 + la t0, is_user_mode + sb t1, 0x00(t0) + + la t0, irq_flag + lb t0, 0x00(t0) + bnez t0, no_enter_user + + /* Clear ESF saved in User Stack */ + csrr t0, mscratch + addi t0, t0, __z_arch_esf_t_SIZEOF + csrw mscratch, t0 + +no_enter_user: +#endif /* CONFIG_USERSPACE */ + #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE /* Restore context at SOC level */ addi a0, sp, __z_arch_esf_t_soc_context_OFFSET @@ -553,30 +1029,13 @@ no_reschedule: LOAD_FP_CALLER_SAVED(sp) skip_load_fp_caller_saved: -#endif +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ /* Restore caller-saved registers from thread stack */ - RV_OP_LOADREG ra, __z_arch_esf_t_ra_OFFSET(sp) - RV_OP_LOADREG gp, __z_arch_esf_t_gp_OFFSET(sp) - RV_OP_LOADREG tp, __z_arch_esf_t_tp_OFFSET(sp) - RV_OP_LOADREG t0, __z_arch_esf_t_t0_OFFSET(sp) - RV_OP_LOADREG t1, __z_arch_esf_t_t1_OFFSET(sp) - RV_OP_LOADREG t2, __z_arch_esf_t_t2_OFFSET(sp) - RV_OP_LOADREG t3, __z_arch_esf_t_t3_OFFSET(sp) - RV_OP_LOADREG t4, __z_arch_esf_t_t4_OFFSET(sp) - RV_OP_LOADREG t5, __z_arch_esf_t_t5_OFFSET(sp) - RV_OP_LOADREG t6, __z_arch_esf_t_t6_OFFSET(sp) - RV_OP_LOADREG a0, __z_arch_esf_t_a0_OFFSET(sp) - RV_OP_LOADREG a1, __z_arch_esf_t_a1_OFFSET(sp) - RV_OP_LOADREG a2, __z_arch_esf_t_a2_OFFSET(sp) - RV_OP_LOADREG a3, __z_arch_esf_t_a3_OFFSET(sp) - RV_OP_LOADREG a4, __z_arch_esf_t_a4_OFFSET(sp) - RV_OP_LOADREG a5, __z_arch_esf_t_a5_OFFSET(sp) - RV_OP_LOADREG a6, __z_arch_esf_t_a6_OFFSET(sp) - RV_OP_LOADREG a7, __z_arch_esf_t_a7_OFFSET(sp) - - /* Release stack space */ - addi sp, sp, __z_arch_esf_t_SIZEOF + LOAD_CALLEE_SAVED() +#ifdef CONFIG_PMP_STACK_GUARD + csrrw sp, mscratch, sp +#endif /* CONFIG_PMP_STACK_GUARD */ /* Call SOC_ERET to exit ISR */ SOC_ERET diff --git a/arch/riscv/core/offsets/offsets.c b/arch/riscv/core/offsets/offsets.c index 95935c4cfdcd00..8702d00f1f4201 100644 --- a/arch/riscv/core/offsets/offsets.c +++ b/arch/riscv/core/offsets/offsets.c @@ -27,6 +27,10 @@ /* thread_arch_t member offsets */ GEN_OFFSET_SYM(_thread_arch_t, swap_return_value); +#if defined(CONFIG_USERSPACE) +GEN_OFFSET_SYM(_thread_arch_t, priv_stack_start); +GEN_OFFSET_SYM(_thread_arch_t, user_sp); +#endif /* struct coop member offsets */ GEN_OFFSET_SYM(_callee_saved_t, sp); diff --git a/arch/riscv/core/pmp/CMakeLists.txt b/arch/riscv/core/pmp/CMakeLists.txt new file mode 100644 index 00000000000000..e190dce664d118 --- /dev/null +++ b/arch/riscv/core/pmp/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# Copyright (c) 2020 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_RISCV_PMP core_pmp.c) + +zephyr_library_include_directories( + . + ../../include +) diff --git a/arch/riscv/core/pmp/Kconfig b/arch/riscv/core/pmp/Kconfig new file mode 100644 index 00000000000000..0a858e656239cc --- /dev/null +++ b/arch/riscv/core/pmp/Kconfig @@ -0,0 +1,38 @@ +# Physical Memory Protection (PMP) configuration options + +# Copyright (c) 2020 BayLibre, SAS +# SPDX-License-Identifier: Apache-2.0 + +config PMP_SLOT + int "Number of PMP slot" + default 8 + help + Depend of the arch/board. Take care to don't put value higher + than the Hardware allow you. + +config PMP_POWER_OF_TWO_ALIGNMENT + bool "Enable power of two alignment" + default n + select MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT + select GEN_PRIV_STACKS + help + This option will reduce the PMP slot number usage but increase + the memory consumption. + +config PMP_STACK_GUARD + bool "Thread Stack Guard" + default n + help + Enable Thread Stack Guards via PMP + +if PMP_STACK_GUARD + +config PMP_STACK_GUARD_MIN_SIZE + int "Guard size" + default 16 + help + Minimum size (and alignment when applicable) of an stack guard + region, which guards the stack of a thread. The width of the + guard is set to 4, to accommodate the riscv granularity. + +endif # PMP_STACK_GUARD diff --git a/arch/riscv/core/pmp/core_pmp.c b/arch/riscv/core/pmp/core_pmp.c new file mode 100644 index 00000000000000..387ed22af90c52 --- /dev/null +++ b/arch/riscv/core/pmp/core_pmp.c @@ -0,0 +1,651 @@ +/* + * Copyright (c) 2020 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "core_pmp.h" +#include +#include + +#define PMP_SLOT_NUMBER CONFIG_PMP_SLOT + +#ifdef CONFIG_USERSPACE +extern ulong_t is_user_mode; +#endif + +enum { + CSR_PMPCFG0, + CSR_PMPCFG1, + CSR_PMPCFG2, + CSR_PMPCFG3, + CSR_PMPADDR0, + CSR_PMPADDR1, + CSR_PMPADDR2, + CSR_PMPADDR3, + CSR_PMPADDR4, + CSR_PMPADDR5, + CSR_PMPADDR6, + CSR_PMPADDR7, + CSR_PMPADDR8, + CSR_PMPADDR9, + CSR_PMPADDR10, + CSR_PMPADDR11, + CSR_PMPADDR12, + CSR_PMPADDR13, + CSR_PMPADDR14, + CSR_PMPADDR15 +}; + +ulong_t csr_read_enum(int pmp_csr_enum) +{ + ulong_t res = -1; + + switch (pmp_csr_enum) { + case CSR_PMPCFG0: + res = csr_read(0x3A0); break; + case CSR_PMPCFG1: + res = csr_read(0x3A1); break; + case CSR_PMPCFG2: + res = csr_read(0x3A2); break; + case CSR_PMPCFG3: + res = csr_read(0x3A3); break; + case CSR_PMPADDR0: + res = csr_read(0x3B0); break; + case CSR_PMPADDR1: + res = csr_read(0x3B1); break; + case CSR_PMPADDR2: + res = csr_read(0x3B2); break; + case CSR_PMPADDR3: + res = csr_read(0x3B3); break; + case CSR_PMPADDR4: + res = csr_read(0x3B4); break; + case CSR_PMPADDR5: + res = csr_read(0x3B5); break; + case CSR_PMPADDR6: + res = csr_read(0x3B6); break; + case CSR_PMPADDR7: + res = csr_read(0x3B7); break; + case CSR_PMPADDR8: + res = csr_read(0x3B8); break; + case CSR_PMPADDR9: + res = csr_read(0x3B9); break; + case CSR_PMPADDR10: + res = csr_read(0x3BA); break; + case CSR_PMPADDR11: + res = csr_read(0x3BB); break; + case CSR_PMPADDR12: + res = csr_read(0x3BC); break; + case CSR_PMPADDR13: + res = csr_read(0x3BD); break; + case CSR_PMPADDR14: + res = csr_read(0x3BE); break; + case CSR_PMPADDR15: + res = csr_read(0x3BF); break; + default: + break; + } + return res; +} + +void csr_write_enum(int pmp_csr_enum, ulong_t value) +{ + switch (pmp_csr_enum) { + case CSR_PMPCFG0: + csr_write(0x3A0, value); break; + case CSR_PMPCFG1: + csr_write(0x3A1, value); break; + case CSR_PMPCFG2: + csr_write(0x3A2, value); break; + case CSR_PMPCFG3: + csr_write(0x3A3, value); break; + case CSR_PMPADDR0: + csr_write(0x3B0, value); break; + case CSR_PMPADDR1: + csr_write(0x3B1, value); break; + case CSR_PMPADDR2: + csr_write(0x3B2, value); break; + case CSR_PMPADDR3: + csr_write(0x3B3, value); break; + case CSR_PMPADDR4: + csr_write(0x3B4, value); break; + case CSR_PMPADDR5: + csr_write(0x3B5, value); break; + case CSR_PMPADDR6: + csr_write(0x3B6, value); break; + case CSR_PMPADDR7: + csr_write(0x3B7, value); break; + case CSR_PMPADDR8: + csr_write(0x3B8, value); break; + case CSR_PMPADDR9: + csr_write(0x3B9, value); break; + case CSR_PMPADDR10: + csr_write(0x3BA, value); break; + case CSR_PMPADDR11: + csr_write(0x3BB, value); break; + case CSR_PMPADDR12: + csr_write(0x3BC, value); break; + case CSR_PMPADDR13: + csr_write(0x3BD, value); break; + case CSR_PMPADDR14: + csr_write(0x3BE, value); break; + case CSR_PMPADDR15: + csr_write(0x3BF, value); break; + default: + break; + } +} + +int z_riscv_pmp_set(unsigned int index, ulong_t cfg_val, ulong_t addr_val) +{ + ulong_t reg_val; + ulong_t shift, mask; + int pmpcfg_csr; + int pmpaddr_csr; + + if ((index >= PMP_SLOT_NUMBER) | (index < 0)) { + return -1; + } + + /* Calculate PMP config/addr register, shift and mask */ +#ifdef CONFIG_64BIT + pmpcfg_csr = CSR_PMPCFG0 + ((index >> 3) << 1); + shift = (index & 0x7) << 3; +#else + pmpcfg_csr = CSR_PMPCFG0 + (index >> 2); + shift = (index & 0x3) << 3; +#endif /* CONFIG_64BIT */ + pmpaddr_csr = CSR_PMPADDR0 + index; + + /* Mask = 0x000000FF<<((index%4)*8) */ + mask = 0x000000FF << shift; + + cfg_val = cfg_val << shift; + addr_val = TO_PMP_ADDR(addr_val); + + reg_val = csr_read_enum(pmpcfg_csr); + reg_val = reg_val & ~mask; + reg_val = reg_val | cfg_val; + + csr_write_enum(pmpaddr_csr, addr_val); + csr_write_enum(pmpcfg_csr, reg_val); + return 0; +} + +int pmp_get(unsigned int index, ulong_t *cfg_val, ulong_t *addr_val) +{ + ulong_t shift; + int pmpcfg_csr; + int pmpaddr_csr; + + if ((index >= PMP_SLOT_NUMBER) | (index < 0)) { + return -1; + } + + /* Calculate PMP config/addr register and shift */ +#ifdef CONFIG_64BIT + pmpcfg_csr = CSR_PMPCFG0 + (index >> 4); + shift = (index & 0x0007) << 3; +#else + pmpcfg_csr = CSR_PMPCFG0 + (index >> 2); + shift = (index & 0x0003) << 3; +#endif /* CONFIG_64BIT */ + pmpaddr_csr = CSR_PMPADDR0 + index; + + *cfg_val = (csr_read_enum(pmpcfg_csr) >> shift) & 0xFF; + *addr_val = FROM_PMP_ADDR(csr_read_enum(pmpaddr_csr)); + + return 0; +} + +void z_riscv_pmp_clear_config(void) +{ + for (unsigned int i = 0; i < RISCV_PMP_CFG_NUM; i++) + csr_write_enum(CSR_PMPCFG0 + i, 0); +} + +/* Function to help debug */ +void z_riscv_pmp_print(unsigned int index) +{ + ulong_t cfg_val; + ulong_t addr_val; + + if (pmp_get(index, &cfg_val, &addr_val)) { + return; + } +#ifdef CONFIG_64BIT + printf("PMP[%d] :\t%02lX %16lX\n", index, cfg_val, addr_val); +#else + printf("PMP[%d] :\t%02lX %08lX\n", index, cfg_val, addr_val); +#endif /* CONFIG_64BIT */ +} + +#if defined(CONFIG_USERSPACE) +#include +void z_riscv_init_user_accesses(struct k_thread *thread) +{ + unsigned char index; + unsigned char *uchar_pmpcfg; + ulong_t rom_start = (ulong_t) _image_rom_start; +#if defined(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT) + ulong_t rom_size = (ulong_t) _image_rom_size; +#else /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT */ + ulong_t rom_end = (ulong_t) _image_rom_end; +#endif /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT */ + index = 0; + uchar_pmpcfg = (unsigned char *) thread->arch.u_pmpcfg; + +#ifdef CONFIG_PMP_STACK_GUARD + index++; +#endif /* CONFIG_PMP_STACK_GUARD */ + + /* MCU state */ + thread->arch.u_pmpaddr[index] = TO_PMP_ADDR((ulong_t) &is_user_mode); + uchar_pmpcfg[index++] = PMP_NA4 | PMP_R; +#if defined(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT) + /* Program and RO data */ + thread->arch.u_pmpaddr[index] = TO_PMP_NAPOT(rom_start, rom_size); + uchar_pmpcfg[index++] = PMP_NAPOT | PMP_R | PMP_X; + + /* RAM */ + thread->arch.u_pmpaddr[index] = TO_PMP_NAPOT(thread->stack_info.start, + thread->stack_info.size); + + uchar_pmpcfg[index++] = PMP_NAPOT | PMP_R | PMP_W; +#else /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT */ + /* Program and RO data */ + thread->arch.u_pmpaddr[index] = TO_PMP_ADDR(rom_start); + uchar_pmpcfg[index++] = PMP_NA4 | PMP_R | PMP_X; + thread->arch.u_pmpaddr[index] = TO_PMP_ADDR(rom_end); + uchar_pmpcfg[index++] = PMP_TOR | PMP_R | PMP_X; + + /* RAM */ + thread->arch.u_pmpaddr[index] = TO_PMP_ADDR(thread->stack_info.start); + uchar_pmpcfg[index++] = PMP_NA4 | PMP_R | PMP_W; + thread->arch.u_pmpaddr[index] = TO_PMP_ADDR(thread->stack_info.start + + thread->stack_info.size); + uchar_pmpcfg[index++] = PMP_TOR | PMP_R | PMP_W; +#endif /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT */ +} + +void z_riscv_configure_user_allowed_stack(struct k_thread *thread) +{ + unsigned int i; + + z_riscv_pmp_clear_config(); + + for (i = 0; i < CONFIG_PMP_SLOT; i++) + csr_write_enum(CSR_PMPADDR0 + i, thread->arch.u_pmpaddr[i]); + + for (i = 0; i < RISCV_PMP_CFG_NUM; i++) + csr_write_enum(CSR_PMPCFG0 + i, thread->arch.u_pmpcfg[i]); +} + +void z_riscv_pmp_add_dynamic(struct k_thread *thread, + ulong_t addr, + ulong_t size, + unsigned char flags) +{ + unsigned char index = 0; + unsigned char *uchar_pmpcfg; + + /* Check 4 bytes alignment */ + __ASSERT(((addr & 0x3) == 0) && ((size & 0x3) == 0) && size, + "address/size are not 4 bytes aligned\n"); + + /* Get next free entry */ + uchar_pmpcfg = (unsigned char *) thread->arch.u_pmpcfg; + + index = PMP_REGION_NUM_FOR_U_THREAD; + + while ((index < CONFIG_PMP_SLOT) && uchar_pmpcfg[index]) { + index++; + } + + __ASSERT((index < CONFIG_PMP_SLOT), "no free PMP entry\n"); + + /* Select the best type */ + if (size == 4) { + thread->arch.u_pmpaddr[index] = TO_PMP_ADDR(addr); + uchar_pmpcfg[index] = flags | PMP_NA4; + } +#if !defined(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT) + else if ((addr & (size - 1)) || (size & (size - 1))) { + __ASSERT(((index + 1) < CONFIG_PMP_SLOT), + "not enough free PMP entries\n"); + thread->arch.u_pmpaddr[index] = TO_PMP_ADDR(addr); + uchar_pmpcfg[index++] = flags | PMP_NA4; + thread->arch.u_pmpaddr[index] = TO_PMP_ADDR(addr + size); + uchar_pmpcfg[index++] = flags | PMP_TOR; + } +#endif /* !CONFIG_PMP_POWER_OF_TWO_ALIGNMENT */ + else { + thread->arch.u_pmpaddr[index] = TO_PMP_NAPOT(addr, size); + uchar_pmpcfg[index] = flags | PMP_NAPOT; + } +} + +int arch_buffer_validate(void *addr, size_t size, int write) +{ + uint32_t index, i; + ulong_t pmp_type, pmp_addr_start, pmp_addr_stop; + unsigned char *uchar_pmpcfg; + struct k_thread *thread = _current; + ulong_t start = (ulong_t) addr; + ulong_t access_type = PMP_R; + ulong_t napot_mask; +#ifdef CONFIG_64BIT + ulong_t max_bit = 64; +#else + ulong_t max_bit = 32; +#endif /* CONFIG_64BIT */ + + if (write) { + access_type |= PMP_W; + } + + uchar_pmpcfg = (unsigned char *) thread->arch.u_pmpcfg; + +#ifdef CONFIG_PMP_STACK_GUARD + index = 1; +#else + index = 0; +#endif /* CONFIG_PMP_STACK_GUARD */ + +#if !defined(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT) || defined(CONFIG_PMP_STACK_GUARD) +__ASSERT((uchar_pmpcfg[index] & PMP_TYPE_MASK) != PMP_TOR, + "The 1st PMP entry shouldn't configured as TOR"); +#endif /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT || CONFIG_PMP_STACK_GUARD */ + + for (; (index < CONFIG_PMP_SLOT) && uchar_pmpcfg[index]; index++) { + if ((uchar_pmpcfg[index] & access_type) != access_type) { + continue; + } + + pmp_type = uchar_pmpcfg[index] & PMP_TYPE_MASK; + +#if !defined(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT) || defined(CONFIG_PMP_STACK_GUARD) + if (pmp_type == PMP_TOR) { + continue; + } +#endif /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT || CONFIG_PMP_STACK_GUARD */ + + if (pmp_type == PMP_NA4) { + pmp_addr_start = + FROM_PMP_ADDR(thread->arch.u_pmpaddr[index]); + + if ((index == CONFIG_PMP_SLOT - 1) || + ((uchar_pmpcfg[index + 1] & PMP_TYPE_MASK) + != PMP_TOR)) { + pmp_addr_stop = pmp_addr_start + 4; + } else { + pmp_addr_stop = FROM_PMP_ADDR( + thread->arch.u_pmpaddr[index + 1]); + index++; + } + } else { /* pmp_type == PMP_NAPOT */ + for (i = 0; i < max_bit; i++) { + if (!(thread->arch.u_pmpaddr[index] & (1 << i))) { + break; + } + } + + napot_mask = (1 << i) - 1; + pmp_addr_start = FROM_PMP_ADDR( + thread->arch.u_pmpaddr[index] & ~napot_mask); + pmp_addr_stop = pmp_addr_start + (1 << (i + 3)); + } + + if ((start >= pmp_addr_start) && ((start + size - 1) < + pmp_addr_stop)) { + return 0; + } + } + + return 1; +} + +int arch_mem_domain_max_partitions_get(void) +{ + return PMP_MAX_DYNAMIC_REGION; +} + +void arch_mem_domain_partition_remove(struct k_mem_domain *domain, + uint32_t partition_id) +{ + sys_dnode_t *node, *next_node; + uint32_t index, i, num; + ulong_t pmp_type, pmp_addr; + unsigned char *uchar_pmpcfg; + struct k_thread *thread; + ulong_t size = (ulong_t) domain->partitions[partition_id].size; + ulong_t start = (ulong_t) domain->partitions[partition_id].start; + + if (size == 4) { + pmp_type = PMP_NA4; + pmp_addr = TO_PMP_ADDR(start); + num = 1; + } +#if !defined(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT) || defined(CONFIG_PMP_STACK_GUARD) + else if ((start & (size - 1)) || (size & (size - 1))) { + pmp_type = PMP_TOR; + pmp_addr = TO_PMP_ADDR(start + size); + num = 2; + } +#endif /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT || CONFIG_PMP_STACK_GUARD */ + else { + pmp_type = PMP_NAPOT; + pmp_addr = TO_PMP_NAPOT(start, size); + num = 1; + } + + node = sys_dlist_peek_head(&domain->mem_domain_q); + if (!node) { + return; + } + + thread = CONTAINER_OF(node, struct k_thread, mem_domain_info); + + uchar_pmpcfg = (unsigned char *) thread->arch.u_pmpcfg; + for (index = PMP_REGION_NUM_FOR_U_THREAD; + index < CONFIG_PMP_SLOT; + index++) { + if (((uchar_pmpcfg[index] & PMP_TYPE_MASK) == pmp_type) && + (pmp_addr == thread->arch.u_pmpaddr[index])) { + break; + } + } + + __ASSERT((index < CONFIG_PMP_SLOT), "partition not found\n"); + +#if !defined(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT) || defined(CONFIG_PMP_STACK_GUARD) + if (pmp_type == PMP_TOR) { + index--; + } +#endif /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT || CONFIG_PMP_STACK_GUARD */ + + SYS_DLIST_FOR_EACH_NODE_SAFE(&domain->mem_domain_q, node, next_node) { + thread = CONTAINER_OF(node, struct k_thread, mem_domain_info); + + uchar_pmpcfg = (unsigned char *) thread->arch.u_pmpcfg; + + for (i = index + num; i < CONFIG_PMP_SLOT; i++) { + uchar_pmpcfg[i - num] = uchar_pmpcfg[i]; + thread->arch.u_pmpaddr[i - num] = + thread->arch.u_pmpaddr[i]; + } + + uchar_pmpcfg[CONFIG_PMP_SLOT - 1] = 0; + if (num == 2) { + uchar_pmpcfg[CONFIG_PMP_SLOT - 2] = 0; + } + } +} + +void arch_mem_domain_thread_add(struct k_thread *thread) +{ + struct k_mem_partition *partition; + + for (int i = 0, pcount = 0; + pcount < thread->mem_domain_info.mem_domain->num_partitions; + i++) { + partition = &thread->mem_domain_info.mem_domain->partitions[i]; + if (partition->size == 0) { + continue; + } + pcount++; + + z_riscv_pmp_add_dynamic(thread, (ulong_t) partition->start, + (ulong_t) partition->size, partition->attr.pmp_attr); + } +} + +void arch_mem_domain_destroy(struct k_mem_domain *domain) +{ + sys_dnode_t *node, *next_node; + struct k_thread *thread; + + SYS_DLIST_FOR_EACH_NODE_SAFE(&domain->mem_domain_q, node, next_node) { + thread = CONTAINER_OF(node, struct k_thread, mem_domain_info); + + arch_mem_domain_thread_remove(thread); + } +} + +void arch_mem_domain_partition_add(struct k_mem_domain *domain, + uint32_t partition_id) +{ + sys_dnode_t *node, *next_node; + struct k_thread *thread; + struct k_mem_partition *partition; + + partition = &domain->partitions[partition_id]; + + SYS_DLIST_FOR_EACH_NODE_SAFE(&domain->mem_domain_q, node, next_node) { + thread = CONTAINER_OF(node, struct k_thread, mem_domain_info); + + z_riscv_pmp_add_dynamic(thread, (ulong_t) partition->start, + (ulong_t) partition->size, partition->attr.pmp_attr); + } +} + +void arch_mem_domain_thread_remove(struct k_thread *thread) +{ + uint32_t i; + unsigned char *uchar_pmpcfg; + + uchar_pmpcfg = (unsigned char *) thread->arch.u_pmpcfg; + + for (i = PMP_REGION_NUM_FOR_U_THREAD; i < CONFIG_PMP_SLOT; i++) { + uchar_pmpcfg[i] = 0; + } +} + +#endif /* CONFIG_USERSPACE */ + +#ifdef CONFIG_PMP_STACK_GUARD + +void z_riscv_init_stack_guard(struct k_thread *thread) +{ + unsigned char index = 0; + unsigned char *uchar_pmpcfg; + ulong_t stack_guard_addr; + + uchar_pmpcfg = (unsigned char *) thread->arch.s_pmpcfg; + + uchar_pmpcfg++; + + /* stack guard: None */ + thread->arch.s_pmpaddr[index] = TO_PMP_ADDR(thread->stack_info.start); + uchar_pmpcfg[index++] = PMP_NA4; + thread->arch.s_pmpaddr[index] = + TO_PMP_ADDR(thread->stack_info.start + + PMP_GUARD_ALIGN_AND_SIZE); + uchar_pmpcfg[index++] = PMP_TOR; + +#ifdef CONFIG_USERSPACE + if (thread->arch.priv_stack_start) { +#ifdef CONFIG_PMP_POWER_OF_TWO_ALIGNMENT + stack_guard_addr = thread->arch.priv_stack_start; +#else + stack_guard_addr = (ulong_t) thread->stack_obj; +#endif /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT */ + thread->arch.s_pmpaddr[index] = + TO_PMP_ADDR(stack_guard_addr); + uchar_pmpcfg[index++] = PMP_NA4; + thread->arch.s_pmpaddr[index] = + TO_PMP_ADDR(stack_guard_addr + + PMP_GUARD_ALIGN_AND_SIZE); + uchar_pmpcfg[index++] = PMP_TOR; + } +#endif /* CONFIG_USERSPACE */ + + /* RAM: RW */ + thread->arch.s_pmpaddr[index] = TO_PMP_ADDR(CONFIG_SRAM_BASE_ADDRESS | + TO_NAPOT_RANGE(KB(CONFIG_SRAM_SIZE))); + uchar_pmpcfg[index++] = (PMP_NAPOT | PMP_R | PMP_W); + + /* All other memory: RWX */ +#ifdef CONFIG_64BIT + thread->arch.s_pmpaddr[index] = 0x1FFFFFFFFFFFFFFF; +#else + thread->arch.s_pmpaddr[index] = 0x1FFFFFFF; +#endif /* CONFIG_64BIT */ + uchar_pmpcfg[index] = PMP_NAPOT | PMP_R | PMP_W | PMP_X; +} + +void z_riscv_configure_stack_guard(struct k_thread *thread) +{ + unsigned int i; + + /* Disable PMP for machine mode */ + csr_clear(mstatus, MSTATUS_MPRV); + + z_riscv_pmp_clear_config(); + + for (i = 0; i < PMP_REGION_NUM_FOR_STACK_GUARD; i++) + csr_write_enum(CSR_PMPADDR1 + i, thread->arch.s_pmpaddr[i]); + + for (i = 0; i < PMP_CFG_CSR_NUM_FOR_STACK_GUARD; i++) + csr_write_enum(CSR_PMPCFG0 + i, thread->arch.s_pmpcfg[i]); + + /* Enable PMP for machine mode */ + csr_set(mstatus, MSTATUS_MPRV); +} + +void z_riscv_configure_interrupt_stack_guard(void) +{ + if (PMP_GUARD_ALIGN_AND_SIZE > 4) { + z_riscv_pmp_set(0, PMP_NAPOT | PMP_L, + (ulong_t) z_interrupt_stacks[0] | + TO_NAPOT_RANGE(PMP_GUARD_ALIGN_AND_SIZE)); + } else { + z_riscv_pmp_set(0, PMP_NA4 | PMP_L, + (ulong_t) z_interrupt_stacks[0]); + } +} +#endif /* CONFIG_PMP_STACK_GUARD */ + +#if defined(CONFIG_PMP_STACK_GUARD) || defined(CONFIG_USERSPACE) + +void z_riscv_pmp_init_thread(struct k_thread *thread) +{ + unsigned char i; + ulong_t *pmpcfg; + +#if defined(CONFIG_PMP_STACK_GUARD) + pmpcfg = thread->arch.s_pmpcfg; + for (i = 0; i < PMP_CFG_CSR_NUM_FOR_STACK_GUARD; i++) + pmpcfg[i] = 0; +#endif /* CONFIG_PMP_STACK_GUARD */ + +#if defined(CONFIG_USERSPACE) + pmpcfg = thread->arch.u_pmpcfg; + for (i = 0; i < RISCV_PMP_CFG_NUM; i++) + pmpcfg[i] = 0; +#endif /* CONFIG_USERSPACE */ +} +#endif /* CONFIG_PMP_STACK_GUARD || CONFIG_USERSPACE */ diff --git a/arch/riscv/core/prep_c.c b/arch/riscv/core/prep_c.c index cc6cb85f1c0e12..25618994862b0c 100644 --- a/arch/riscv/core/prep_c.c +++ b/arch/riscv/core/prep_c.c @@ -19,6 +19,7 @@ #include #include #include +#include /** * @@ -37,6 +38,9 @@ void _PrepC(void) #endif #if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) soc_interrupt_init(); +#endif +#ifdef CONFIG_PMP_STACK_GUARD + z_riscv_configure_interrupt_stack_guard(); #endif z_cstart(); CODE_UNREACHABLE; diff --git a/arch/riscv/core/reset.S b/arch/riscv/core/reset.S index ff2e17c7ec1502..da43d852cfabfd 100644 --- a/arch/riscv/core/reset.S +++ b/arch/riscv/core/reset.S @@ -82,6 +82,8 @@ aa_loop: li t0, CONFIG_ISR_STACK_SIZE add sp, sp, t0 + csrw mscratch, sp + #ifdef CONFIG_WDOG_INIT call _WdogInit #endif diff --git a/arch/riscv/core/swap.S b/arch/riscv/core/swap.S index d98071b40710e7..e95f3e367c37ec 100644 --- a/arch/riscv/core/swap.S +++ b/arch/riscv/core/swap.S @@ -24,52 +24,6 @@ GTEXT(z_thread_entry_wrapper) SECTION_FUNC(exception.other, arch_swap) /* Make a system call to perform context switch */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - addi sp, sp, -__z_arch_esf_t_SIZEOF - - RV_OP_STOREREG ra, __z_arch_esf_t_ra_OFFSET(sp) - RV_OP_STOREREG gp, __z_arch_esf_t_gp_OFFSET(sp) - RV_OP_STOREREG tp, __z_arch_esf_t_tp_OFFSET(sp) - RV_OP_STOREREG t0, __z_arch_esf_t_t0_OFFSET(sp) - RV_OP_STOREREG t1, __z_arch_esf_t_t1_OFFSET(sp) - RV_OP_STOREREG t2, __z_arch_esf_t_t2_OFFSET(sp) - RV_OP_STOREREG t3, __z_arch_esf_t_t3_OFFSET(sp) - RV_OP_STOREREG t4, __z_arch_esf_t_t4_OFFSET(sp) - RV_OP_STOREREG t5, __z_arch_esf_t_t5_OFFSET(sp) - RV_OP_STOREREG t6, __z_arch_esf_t_t6_OFFSET(sp) - RV_OP_STOREREG a0, __z_arch_esf_t_a0_OFFSET(sp) - RV_OP_STOREREG a1, __z_arch_esf_t_a1_OFFSET(sp) - RV_OP_STOREREG a2, __z_arch_esf_t_a2_OFFSET(sp) - RV_OP_STOREREG a3, __z_arch_esf_t_a3_OFFSET(sp) - RV_OP_STOREREG a4, __z_arch_esf_t_a4_OFFSET(sp) - RV_OP_STOREREG a5, __z_arch_esf_t_a5_OFFSET(sp) - RV_OP_STOREREG a6, __z_arch_esf_t_a6_OFFSET(sp) - RV_OP_STOREREG a7, __z_arch_esf_t_a7_OFFSET(sp) - - call read_timer_start_of_swap - - RV_OP_LOADREG ra, __z_arch_esf_t_ra_OFFSET(sp) - RV_OP_LOADREG gp, __z_arch_esf_t_gp_OFFSET(sp) - RV_OP_LOADREG tp, __z_arch_esf_t_tp_OFFSET(sp) - RV_OP_LOADREG t0, __z_arch_esf_t_t0_OFFSET(sp) - RV_OP_LOADREG t1, __z_arch_esf_t_t1_OFFSET(sp) - RV_OP_LOADREG t2, __z_arch_esf_t_t2_OFFSET(sp) - RV_OP_LOADREG t3, __z_arch_esf_t_t3_OFFSET(sp) - RV_OP_LOADREG t4, __z_arch_esf_t_t4_OFFSET(sp) - RV_OP_LOADREG t5, __z_arch_esf_t_t5_OFFSET(sp) - RV_OP_LOADREG t6, __z_arch_esf_t_t6_OFFSET(sp) - RV_OP_LOADREG a0, __z_arch_esf_t_a0_OFFSET(sp) - RV_OP_LOADREG a1, __z_arch_esf_t_a1_OFFSET(sp) - RV_OP_LOADREG a2, __z_arch_esf_t_a2_OFFSET(sp) - RV_OP_LOADREG a3, __z_arch_esf_t_a3_OFFSET(sp) - RV_OP_LOADREG a4, __z_arch_esf_t_a4_OFFSET(sp) - RV_OP_LOADREG a5, __z_arch_esf_t_a5_OFFSET(sp) - RV_OP_LOADREG a6, __z_arch_esf_t_a6_OFFSET(sp) - RV_OP_LOADREG a7, __z_arch_esf_t_a7_OFFSET(sp) - - /* Release stack space */ - addi sp, sp, __z_arch_esf_t_SIZEOF -#endif ecall /* diff --git a/arch/riscv/core/thread.c b/arch/riscv/core/thread.c index 253c3a1f706183..0513b070301911 100644 --- a/arch/riscv/core/thread.c +++ b/arch/riscv/core/thread.c @@ -1,11 +1,25 @@ /* * Copyright (c) 2016 Jean-Paul Etienne + * Copyright (c) 2020 BayLibre, SAS * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include +#include +#include + +#ifdef CONFIG_USERSPACE + +/* + * Glogal variable used to know the current mode running. + * Is not boolean because it must match the PMP granularity of the arch. + */ +ulong_t is_user_mode; +bool irq_flag; +#endif void z_thread_entry_wrapper(k_thread_entry_t thread, void *arg1, @@ -13,26 +27,28 @@ void z_thread_entry_wrapper(k_thread_entry_t thread, void *arg3); void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - size_t stack_size, k_thread_entry_t thread_func, - void *arg1, void *arg2, void *arg3, - int priority, unsigned int options) + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) { - char *stack_memory = Z_THREAD_STACK_BUFFER(stack); - struct __esf *stack_init; - z_new_thread_init(thread, stack_memory, stack_size); +#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE + const struct soc_esf soc_esf_init = {SOC_ESF_INIT}; +#endif /* Initial stack frame for thread */ - stack_init = (struct __esf *) - Z_STACK_PTR_ALIGN(stack_memory + - stack_size - sizeof(struct __esf)); + stack_init = Z_STACK_PTR_TO_FRAME(struct __esf, stack_ptr); /* Setup the initial stack frame */ - stack_init->a0 = (ulong_t)thread_func; - stack_init->a1 = (ulong_t)arg1; - stack_init->a2 = (ulong_t)arg2; - stack_init->a3 = (ulong_t)arg3; + stack_init->a0 = (ulong_t)entry; + stack_init->a1 = (ulong_t)p1; + stack_init->a2 = (ulong_t)p2; + stack_init->a3 = (ulong_t)p3; + +#ifdef CONFIG_THREAD_LOCAL_STORAGE + stack_init->tp = (ulong_t)thread->tls; +#endif + /* * Following the RISC-V architecture, * the MSTATUS register (used to globally enable/disable interrupt), @@ -57,13 +73,48 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, * thread stack. */ stack_init->mstatus = MSTATUS_DEF_RESTORE; + +#if defined(CONFIG_PMP_STACK_GUARD) || defined(CONFIG_USERSPACE) + z_riscv_pmp_init_thread(thread); +#endif /* CONFIG_PMP_STACK_GUARD || CONFIG_USERSPACE */ + +#if defined(CONFIG_PMP_STACK_GUARD) + if ((thread->base.user_options & K_USER) == 0) { + /* Enable pmp for machine mode if thread isn't a user*/ + stack_init->mstatus |= MSTATUS_MPRV; + } +#endif /* CONFIG_PMP_STACK_GUARD */ + #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) if ((thread->base.user_options & K_FP_REGS) != 0) { stack_init->mstatus |= MSTATUS_FS_INIT; } stack_init->fp_state = 0; #endif + + stack_init->mepc = (ulong_t)z_thread_entry_wrapper; + +#if defined(CONFIG_USERSPACE) + thread->arch.priv_stack_start = 0; + thread->arch.user_sp = 0; + if ((thread->base.user_options & K_USER) != 0) { + stack_init->mepc = (ulong_t)k_thread_user_mode_enter; + } else { + stack_init->mepc = (ulong_t)z_thread_entry_wrapper; +#if defined(CONFIG_PMP_STACK_GUARD) + z_riscv_init_stack_guard(thread); +#endif /* CONFIG_PMP_STACK_GUARD */ + } +#else stack_init->mepc = (ulong_t)z_thread_entry_wrapper; +#if defined(CONFIG_PMP_STACK_GUARD) + z_riscv_init_stack_guard(thread); +#endif /* CONFIG_PMP_STACK_GUARD */ +#endif /* CONFIG_USERSPACE */ + +#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE + stack_init->soc_context = soc_esf_init; +#endif thread->callee_saved.sp = (ulong_t)stack_init; } @@ -132,3 +183,97 @@ int arch_float_enable(struct k_thread *thread) return 0; } #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ + +#ifdef CONFIG_USERSPACE + +/* Function used by Zephyr to switch a supervisor thread to a user thread */ +FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, + void *p1, void *p2, void *p3) +{ + arch_syscall_invoke5((uintptr_t) arch_user_mode_enter, + (uintptr_t) user_entry, + (uintptr_t) p1, + (uintptr_t) p2, + (uintptr_t) p3, + FORCE_SYSCALL_ID); + + CODE_UNREACHABLE; +} + +/* + * User space entry function + * + * This function is the entry point to user mode from privileged execution. + * The conversion is one way, and threads which transition to user mode do + * not transition back later, unless they are doing system calls. + */ +FUNC_NORETURN void z_riscv_user_mode_enter_syscall(k_thread_entry_t user_entry, + void *p1, void *p2, void *p3) +{ + ulong_t top_of_user_stack = 0U; + uintptr_t status; + + /* Set up privileged stack */ +#ifdef CONFIG_GEN_PRIV_STACKS + _current->arch.priv_stack_start = + (uint32_t)z_priv_stack_find(_current->stack_obj); +#else + _current->arch.priv_stack_start = + (uint32_t)(_current->stack_obj) + + Z_RISCV_STACK_GUARD_SIZE; +#endif /* CONFIG_GEN_PRIV_STACKS */ + + top_of_user_stack = Z_STACK_PTR_ALIGN( + _current->stack_info.start + + _current->stack_info.size - + _current->stack_info.delta); + + /* Set next CPU status to user mode */ + status = csr_read(mstatus); + status = INSERT_FIELD(status, MSTATUS_MPP, PRV_U); + status = INSERT_FIELD(status, MSTATUS_MPRV, 0); + + csr_write(mstatus, status); + csr_write(mepc, z_thread_entry_wrapper); + + /* Set up Physical Memory Protection */ +#if defined(CONFIG_PMP_STACK_GUARD) + z_riscv_init_stack_guard(_current); +#endif + + z_riscv_init_user_accesses(_current); + z_riscv_configure_user_allowed_stack(_current); + + is_user_mode = true; + + __asm__ volatile ("mv a0, %1" + : "=r" (user_entry) + : "r" (user_entry) + : "memory"); + + __asm__ volatile ("mv a1, %1" + : "=r" (p1) + : "r" (p1) + : "memory"); + + __asm__ volatile ("mv a2, %1" + : "=r" (p2) + : "r" (p2) + : "memory"); + + __asm__ volatile ("mv a3, %1" + : "=r" (p3) + : "r" (p3) + : "memory"); + + __asm__ volatile ("mv sp, %1" + : "=r" (top_of_user_stack) + : "r" (top_of_user_stack) + : "memory"); + + __asm__ volatile ("mret"); + + CODE_UNREACHABLE; +} + +#endif /* CONFIG_USERSPACE */ diff --git a/arch/riscv/core/tls.c b/arch/riscv/core/tls.c new file mode 100644 index 00000000000000..b533ec60fa0c6d --- /dev/null +++ b/arch/riscv/core/tls.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) +{ + /* + * TLS area for RISC-V is simple without any extra + * data. + */ + + /* + * Since we are populating things backwards, + * setup the TLS data/bss area first. + */ + stack_ptr -= z_tls_data_size(); + z_tls_copy(stack_ptr); + + /* + * Set thread TLS pointer which is used in + * context switch to point to TLS area. + */ + new_thread->tls = POINTER_TO_UINT(stack_ptr); + + return z_tls_data_size(); +} diff --git a/arch/riscv/core/userspace.S b/arch/riscv/core/userspace.S new file mode 100644 index 00000000000000..383a157453c853 --- /dev/null +++ b/arch/riscv/core/userspace.S @@ -0,0 +1,71 @@ +/* + * Userspace and service handler hooks + * + * Copyright (c) 2020 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +/* exports */ +GTEXT(z_riscv_do_syscall) +GTEXT(arch_user_string_nlen) +GTEXT(z_riscv_user_string_nlen_fault_start) +GTEXT(z_riscv_user_string_nlen_fault_end) +GTEXT(z_riscv_user_string_nlen_fixup) +GTEXT(z_riscv_do_syscall_start) +GTEXT(z_riscv_do_syscall_end) + +/* Imports */ +GDATA(_k_syscall_table) + +SECTION_FUNC(TEXT,z_riscv_do_syscall) + la t0, _k_syscall_table + + slli t1, a7, RV_REGSHIFT # Determine offset from indice value + add t0, t0, t1 # Table addr + offset = function addr + RV_OP_LOADREG t3, 0x00(t0) # Load function address + + /* Execute syscall function */ + jalr t3 + + /* Return to ISR environment to switch-back in user mode */ +z_riscv_do_syscall_start: + ECALL +z_riscv_do_syscall_end: + +/* + * size_t arch_user_string_nlen(const char *s, size_t maxsize, int *err_arg) + */ +SECTION_FUNC(TEXT, arch_user_string_nlen) + li a5, 0 # Counter + sw a5, 0(a2) # Init error value to 0 + +loop: + add a4, a0, a5 # Determine character address +z_riscv_user_string_nlen_fault_start: + lbu a4, 0(a4) # Load string's character +z_riscv_user_string_nlen_fault_end: + beqz a4, exit # Test string's end of line + + bne a5, a1, continue # Check if max length is reached + +exit: + mv a0, a5 # Return counter value (length) + ret + +continue: + addi a5, a5, 1 # Increment counter + j loop + +z_riscv_user_string_nlen_fixup: + li a4, -1 # Put error to -1 + sw a4, 0(a2) + j exit diff --git a/arch/riscv/include/core_pmp.h b/arch/riscv/include/core_pmp.h new file mode 100644 index 00000000000000..071eb7e5c845fe --- /dev/null +++ b/arch/riscv/include/core_pmp.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2020 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CORE_PMP_H_ +#define CORE_PMP_H_ + +/* Configuration register flags (cfg_val)*/ +#define PMP_R 0x01 /* Allow read */ +#define PMP_W 0x02 /* Allow write */ +#define PMP_X 0x04 /* Allow execute */ +#define PMP_A 0x18 /* Address-matching mode field */ +#define PMP_L 0x80 /* PMP entry is locked */ +#define PMP_OFF 0x00 /* Null region */ +#define PMP_TOR 0x08 /* Top of range */ +#define PMP_NA4 0x10 /* Naturally aligned four-byte region */ +#define PMP_NAPOT 0x18 /* Naturally aligned power-of-two region */ + +#define PMP_SHIFT_ADDR 2 +#define PMP_TYPE_MASK 0x18 +#define TO_PMP_ADDR(addr) ((addr) >> PMP_SHIFT_ADDR) +#define FROM_PMP_ADDR(addr) ((addr) << PMP_SHIFT_ADDR) +#define TO_NAPOT_RANGE(size) (((size) - 1) >> 1) +#define TO_PMP_NAPOT(addr, size) TO_PMP_ADDR(addr | \ + TO_NAPOT_RANGE(size)) + +#ifdef CONFIG_PMP_STACK_GUARD + +#define PMP_GUARD_ALIGN_AND_SIZE CONFIG_PMP_STACK_GUARD_MIN_SIZE + +#else + +#define PMP_GUARD_ALIGN_AND_SIZE 0 + +#endif /* CONFIG_PMP_STACK_GUARD */ + +#ifdef CONFIG_RISCV_PMP + +/* + * @brief Set a Physical Memory Protection slot + * + * Configure a memory region to be secured by one of the 16 PMP entries. + * + * @param index Number of the targeted PMP entrie (0 to 15 only). + * @param cfg_val Configuration value (cf datasheet or defined flags) + * @param addr_val Address register value + * + * This function shall only be called from Secure state. + * + * @return -1 if bad argument, 0 otherwise. + */ +int z_riscv_pmp_set(unsigned int index, ulong_t cfg_val, ulong_t addr_val); + +/* + * @brief Reset to 0 all PMP setup registers + */ +void z_riscv_pmp_clear_config(void); + +/* + * @brief Print PMP setup register for info/debug + */ +void z_riscv_pmp_print(unsigned int index); +#endif /* CONFIG_RISCV_PMP */ + +#if defined(CONFIG_USERSPACE) + +/* + * @brief Configure RISCV user thread access to the stack + * + * Determine and save allow access setup in thread structure. + * + * @param thread Thread info data pointer. + */ +void z_riscv_init_user_accesses(struct k_thread *thread); + +/* + * @brief Apply RISCV user thread access to the stack + * + * Write user access setup saved in this thread structure. + * + * @param thread Thread info data pointer. + */ +void z_riscv_configure_user_allowed_stack(struct k_thread *thread); + +/* + * @brief Add a new RISCV stack access + * + * Add a new memory permission area in the existing + * pmp setup of the thread. + * + * @param thread Thread info data pointer. + * @param addr Start address of the memory area. + * @param size Size of the memory area. + * @param flags Pemissions: PMP_R, PMP_W, PMP_X, PMP_L + */ +void z_riscv_pmp_add_dynamic(struct k_thread *thread, + ulong_t addr, + ulong_t size, + unsigned char flags); +#endif /* CONFIG_USERSPACE */ + +#ifdef CONFIG_PMP_STACK_GUARD + +/* + * @brief Configure RISCV stack guard for interrupt stack + * + * Write PMP registers to prevent RWX access from all privilege mode. + */ +void z_riscv_configure_interrupt_stack_guard(void); + +/* + * @brief Configure RISCV stack guard + * + * Determine and save stack guard setup in thread structure. + * + * @param thread Thread info data pointer. + */ +void z_riscv_init_stack_guard(struct k_thread *thread); + +/* + * @brief Apply RISCV stack guard + * + * Write stack guard setup saved in this thread structure. + * + * @param thread Thread info data pointer. + */ +void z_riscv_configure_stack_guard(struct k_thread *thread); +#endif /* CONFIG_PMP_STACK_GUARD */ + +#if defined(CONFIG_PMP_STACK_GUARD) || defined(CONFIG_USERSPACE) + +/* + * @brief Initialize thread PMP setup value to 0 + * + * @param thread Thread info data pointer. + */ +void z_riscv_pmp_init_thread(struct k_thread *thread); +#endif /* CONFIG_PMP_STACK_GUARD || CONFIG_USERSPACE */ + +#endif /* CORE_PMP_H_ */ diff --git a/arch/riscv/include/kernel_arch_data.h b/arch/riscv/include/kernel_arch_data.h index 13f0d60dc17bd0..9ee4ac24156cb0 100644 --- a/arch/riscv/include/kernel_arch_data.h +++ b/arch/riscv/include/kernel_arch_data.h @@ -29,8 +29,6 @@ extern "C" { #endif -extern K_THREAD_STACK_DEFINE(_interrupt_stack, CONFIG_ISR_STACK_SIZE); - #ifdef __cplusplus } #endif diff --git a/arch/riscv/include/kernel_arch_func.h b/arch/riscv/include/kernel_arch_func.h index 8c436dc62962bc..24c2a5a5c5a939 100644 --- a/arch/riscv/include/kernel_arch_func.h +++ b/arch/riscv/include/kernel_arch_func.h @@ -40,6 +40,11 @@ static inline bool arch_is_in_isr(void) return _kernel.cpus[0].nested != 0U; } +extern FUNC_NORETURN void z_riscv_userspace_enter(k_thread_entry_t user_entry, + void *p1, void *p2, void *p3, + uint32_t stack_end, + uint32_t stack_start); + #ifdef CONFIG_IRQ_OFFLOAD int z_irq_do_offload(void); #endif diff --git a/arch/riscv/include/offsets_short_arch.h b/arch/riscv/include/offsets_short_arch.h index 9851a9953a9513..2cc167fd5d7310 100644 --- a/arch/riscv/include/offsets_short_arch.h +++ b/arch/riscv/include/offsets_short_arch.h @@ -102,6 +102,13 @@ #endif /* defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) */ +#ifdef CONFIG_USERSPACE +#define _thread_offset_to_priv_stack_start \ + (___thread_t_arch_OFFSET + ___thread_arch_t_priv_stack_start_OFFSET) +#define _thread_offset_to_user_sp \ + (___thread_t_arch_OFFSET + ___thread_arch_t_user_sp_OFFSET) +#endif + /* end - threads */ #endif /* ZEPHYR_ARCH_RISCV_INCLUDE_OFFSETS_SHORT_ARCH_H_ */ diff --git a/arch/sparc/CMakeLists.txt b/arch/sparc/CMakeLists.txt new file mode 100644 index 00000000000000..a14cb31af441c2 --- /dev/null +++ b/arch/sparc/CMakeLists.txt @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT "elf32-sparc") +add_subdirectory(core) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig new file mode 100644 index 00000000000000..c729b5d0892e0d --- /dev/null +++ b/arch/sparc/Kconfig @@ -0,0 +1,73 @@ +# Copyright (c) 2019-2020 Cobham Gaisler AB +# SPDX-License-Identifier: Apache-2.0 + +menu "SPARC Options" + depends on SPARC + +config ARCH + default "sparc" + +config SPARC_NWIN + int "Number of register windows" + default 8 + help + Number of implemented register windows. + +config GEN_ISR_TABLES + default y + +config GEN_IRQ_VECTOR_TABLE + default n + +config GEN_SW_ISR_TABLE + default y + +config NUM_IRQS + int + default 32 + +config SPARC_CASA + bool "CASA instructions" + help + Use CASA atomic instructions. Defined by SPARC V9 and available + in some LEON processors. + +# The SPARC V8 ABI allocates a stack frame of minimum 96 byte for each SAVE +# instruction so we bump the kernel default values. +config MAIN_STACK_SIZE + default 4096 if COVERAGE_GCOV + default 2048 + +config IDLE_STACK_SIZE + default 1024 + +config ISR_STACK_SIZE + default 4096 + +config TEST_EXTRA_STACKSIZE + default 4096 if COVERAGE_GCOV + default 2048 + +config SYSTEM_WORKQUEUE_STACK_SIZE + default 4096 + +config CMSIS_THREAD_MAX_STACK_SIZE + default 2048 + +config CMSIS_V2_THREAD_MAX_STACK_SIZE + default 2048 + +config CMSIS_V2_THREAD_DYNAMIC_STACK_SIZE + default 2048 + +config IPM_CONSOLE_STACK_SIZE + default 4096 if COVERAGE + default 1024 + +config NET_TX_STACK_SIZE + default 2048 + +config NET_RX_STACK_SIZE + default 2048 + +endmenu diff --git a/arch/sparc/core/CMakeLists.txt b/arch/sparc/core/CMakeLists.txt new file mode 100644 index 00000000000000..82ff7906638fd2 --- /dev/null +++ b/arch/sparc/core/CMakeLists.txt @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources( + fatal.c + reset_trap.S + prep_c.c + switch.S + interrupt_trap.S + fault_trap.S + irq_manage.c + thread.c + window_trap.S + sw_trap_set_pil.S + trap_table_mvt.S +) + +zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) diff --git a/arch/sparc/core/fatal.c b/arch/sparc/core/fatal.c new file mode 100644 index 00000000000000..fc685024e74f9e --- /dev/null +++ b/arch/sparc/core/fatal.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); + +FUNC_NORETURN void z_sparc_fatal_error(unsigned int reason, + const z_arch_esf_t *esf) +{ + if (esf != NULL) { + LOG_ERR(" pc: %08x", esf->pc); + LOG_ERR("npc: %08x", esf->npc); + LOG_ERR("psr: %08x", esf->psr); + LOG_ERR("tbr: %08x", esf->tbr); + LOG_ERR(" sp: %08x", esf->sp); + LOG_ERR(" y: %08x", esf->y); + } + + z_fatal_error(reason, esf); + CODE_UNREACHABLE; +} + +FUNC_NORETURN void _Fault(const z_arch_esf_t *esf) +{ + LOG_ERR("Trap tt=0x%02x", (esf->tbr >> 4) & 0xff); + + z_sparc_fatal_error(K_ERR_CPU_EXCEPTION, esf); +} diff --git a/arch/sparc/core/fault_trap.S b/arch/sparc/core/fault_trap.S new file mode 100644 index 00000000000000..e9ac058f0c4c71 --- /dev/null +++ b/arch/sparc/core/fault_trap.S @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +GTEXT(__sparc_trap_fault) + +/* + * Fault trap handler + * + * - IU state is saved and restored + * + * On entry: + * %l0: psr (set by trap code) + * %l1: pc + * %l2: npc + * %l6: tbr (set by trap code) + * %fp: %sp of current register window at trap time + * + * This trap handler will trash some of the global registers, which is OK since + * we will not return to where we trapped. + */ +SECTION_FUNC(TEXT, __sparc_trap_fault) + /* We may have trapped into the invalid window. If so, make it valid. */ + rd %wim, %g2 + srl %g2, %l0, %g3 + cmp %g3, 1 + bne .Lwodone + nop + + /* Do the window overflow. */ + sll %g2, (CONFIG_SPARC_NWIN-1), %g3 + srl %g2, 1, %g2 + or %g2, %g3, %g2 + + /* Enter window to save. */ + save + /* Install new wim calculated above. */ + mov %g2, %wim + nop + nop + nop + /* Put registers on the dedicated save area of the ABI stack frame. */ + std %l0, [%sp + 0x00] + std %l2, [%sp + 0x08] + std %l4, [%sp + 0x10] + std %l6, [%sp + 0x18] + std %i0, [%sp + 0x20] + std %i2, [%sp + 0x28] + std %i4, [%sp + 0x30] + std %i6, [%sp + 0x38] + /* Leave saved window. */ + restore + +.Lwodone: + /* Allocate an ABI stack frame and exception stack frame */ + sub %fp, 96 + __z_arch_esf_t_SIZEOF, %sp + /* + * %fp: %sp of interrupted task + * %sp: %sp of interrupted task - ABI_frame - esf + */ + + /* Fill in the content of the exception stack frame */ + st %l1, [%sp + 96 + __z_arch_esf_t_pc_OFFSET] + st %l2, [%sp + 96 + __z_arch_esf_t_npc_OFFSET] + st %l0, [%sp + 96 + __z_arch_esf_t_psr_OFFSET] + st %l6, [%sp + 96 + __z_arch_esf_t_tbr_OFFSET] + st %fp, [%sp + 96 + __z_arch_esf_t_sp_OFFSET] + rd %y, %g1 + st %g1, [%sp + 96 + __z_arch_esf_t_y_OFFSET] + + /* Enable traps, raise PIL to mask all maskable interrupts. */ + or %l0, PSR_PIL, %o0 + wr %o0, PSR_ET, %psr + nop + nop + nop + /* Exception stack frame prepared earlier is the first argument. */ + call _Fault + add %sp, 96, %o0 diff --git a/arch/sparc/core/interrupt_trap.S b/arch/sparc/core/interrupt_trap.S new file mode 100644 index 00000000000000..8c9b90860381e7 --- /dev/null +++ b/arch/sparc/core/interrupt_trap.S @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "stack_offsets.h" + +GTEXT(__sparc_trap_interrupt) +GTEXT(__sparc_trap_irq_offload) + +/* + * Interrupt trap handler + * + * - IU state is saved and restored + * + * On entry: + * %l0: psr (set by trap code) + * %l1: pc + * %l2: npc + * %l3: SPARC interrupt request level (bp_IRL) + * %fp: %sp of current register window at trap time + * + * This module also implements the IRQ offload support. The handling is the + * same as for asynchronous maskable interrupts, with the following exceptions: + * - Do not re-execute the causing (ta) instruction at trap exit. + * - A dedicated interrupt request level (0x8d) is used. + * - z_sparc_enter_irq() knows how to interpret this interrupt request level. + */ +SECTION_SUBSEC_FUNC(TEXT, __sparc_trap_interrupt, __sparc_trap_irq_offload) + /* Preparation in the case of synchronous IRQ offload. */ + mov %l2, %l1 + add %l2, 4, %l2 + set 0x8d, %l3 + +__sparc_trap_interrupt: + /* %g2, %g3 are used at manual window overflow so save temporarily */ + mov %g2, %l4 + mov %g3, %l5 + + /* We may have trapped into the invalid window. If so, make it valid. */ + rd %wim, %g2 + srl %g2, %l0, %g3 + cmp %g3, 1 + bne .Lwodone + nop + + /* Do the window overflow. */ + sll %g2, (CONFIG_SPARC_NWIN-1), %g3 + srl %g2, 1, %g2 + or %g2, %g3, %g2 + + /* Enter window to save. */ + save + /* Install new wim calculated above. */ + mov %g2, %wim + nop + nop + nop + /* Put registers on the dedicated save area of the ABI stack frame. */ + std %l0, [%sp + 0x00] + std %l2, [%sp + 0x08] + std %l4, [%sp + 0x10] + std %l6, [%sp + 0x18] + std %i0, [%sp + 0x20] + std %i2, [%sp + 0x28] + std %i4, [%sp + 0x30] + std %i6, [%sp + 0x38] + /* Leave saved window. */ + restore + +.Lwodone: + /* + * %l4: %g2 at trap time + * %l5: %g3 at trap time + * + * Save the state of the interrupted task including global registers on + * the task stack. + * + * IMPORTANT: Globals are saved here as well on the task stack, since a + * context switch might happen before the context of this interrupted + * task is restored. + */ + + /* Allocate stack for isr context. */ + sub %fp, ISF_SIZE, %sp + /* + * %fp: %sp of interrupted task + * %sp: %sp of interrupted task - ISF_SIZE. + * (fits what we store here) + * + * Save the interrupted context. + */ + std %l0, [%sp + ISF_PSR_OFFSET] /* psr pc */ + st %l2, [%sp + ISF_NPC_OFFSET] /* npc */ + st %g1, [%sp + ISF_G1_OFFSET] /* g1 */ + std %l4, [%sp + ISF_G2_OFFSET] /* g2 g3 */ + st %g4, [%sp + ISF_G4_OFFSET] /* g4 */ + rd %y, %g1 + st %g1, [%sp + ISF_Y_OFFSET] /* y */ + + /* %l5: reference to _kernel */ + set _kernel, %l5 + /* Switch to interrupt stack. */ + mov %sp, %fp + ld [%l5 + _kernel_offset_to_irq_stack], %sp + + /* Allocate a full C stack frame */ + sub %sp, STACK_FRAME_SIZE, %sp + /* + * %fp: %sp of interrupted task - ISF_SIZE. + * %sp: irq stack - 96. An ABI frame + */ + + /* Enable traps, raise PIL to mask all maskable interrupts. */ + or %l0, PSR_PIL, %l6 + +#if defined(CONFIG_FPU) + /* + * We now check if the interrupted context was using the FPU. The + * result is stored in register l5 which will either get the value 0 + * (FPU not used) or PSR_EF (FPU used). + * + * If the FPU was used by the interrupted context, then we do two + * things: + * 1. Store FSR to memory. This has the side-effect of completing all + * pending FPU operations. + * 2. Disable FPU. Floating point instructions in the ISR will trap. + * + * The FPU is be enabled again if needed after the ISR has returned. + */ + set PSR_EF, %l5 + andcc %l0, %l5, %l5 + bne,a 1f + st %fsr, [%sp] +1: + andn %l6, %l5, %l6 +#endif + wr %l6, PSR_ET, %psr + nop + nop + nop + +#ifdef CONFIG_TRACING_ISR + call sys_trace_isr_enter + nop +#endif + + /* SPARC interrupt request level is the first argument */ + call z_sparc_enter_irq + mov %l3, %o0 + +#ifdef CONFIG_TRACING_ISR + call sys_trace_isr_exit + nop +#endif + + /* + * %fp: %sp of interrupted task - ISF_SIZE. + * %sp: irq stack - 96. An ABI frame + */ + +#ifdef CONFIG_PREEMPT_ENABLED + /* allocate stack for calling C function and for its output value */ + sub %fp, (96+8), %sp + /* + * %fp: %sp of interrupted task - ISF_SIZE. + * %sp: %sp of interrupted task - ISF_SIZE - STACK_FRAME_SIZE - 8. + */ + call z_arch_get_next_switch_handle + add %sp, 96, %o0 + /* we get old thread as "return value" on stack */ + ld [%sp + 96], %o1 + /* + * o0: new thread + * o1: old thread + */ + cmp %o0, %o1 + beq .Lno_reschedule + /* z_sparc_context_switch() is a leaf function not using stack. */ + add %sp, (96+8-64), %sp + +#if defined(CONFIG_FPU_SHARING) + /* IF PSR_EF at trap time then store the FP context. */ + cmp %l5, 0 + be .Lno_fp_context + nop + + /* + * PSR_EF was 1 at trap time so save the FP registers on stack. + * - Set PSR_EF so we can access the FP registers. + * - Allocate space for the FP registers above the save area used for + * the z_sparc_context_switch() call. + */ + wr %l6, %l5, %psr + nop + nop + nop + + sub %sp, 34 * 4, %sp + std %f0, [%sp + 64 + 0x00] + std %f2, [%sp + 64 + 0x08] + std %f4, [%sp + 64 + 0x10] + std %f6, [%sp + 64 + 0x18] + std %f8, [%sp + 64 + 0x20] + std %f10, [%sp + 64 + 0x28] + std %f12, [%sp + 64 + 0x30] + std %f14, [%sp + 64 + 0x38] + std %f16, [%sp + 64 + 0x40] + std %f18, [%sp + 64 + 0x48] + std %f20, [%sp + 64 + 0x50] + std %f22, [%sp + 64 + 0x58] + std %f24, [%sp + 64 + 0x60] + std %f26, [%sp + 64 + 0x68] + std %f28, [%sp + 64 + 0x70] + std %f30, [%sp + 64 + 0x78] + + call z_sparc_context_switch + st %fsr, [%sp + 64 + 0x80] + + ldd [%sp + 64 + 0x00], %f0 + ldd [%sp + 64 + 0x08], %f2 + ldd [%sp + 64 + 0x10], %f4 + ldd [%sp + 64 + 0x18], %f6 + ldd [%sp + 64 + 0x20], %f8 + ldd [%sp + 64 + 0x28], %f10 + ldd [%sp + 64 + 0x30], %f12 + ldd [%sp + 64 + 0x38], %f14 + ldd [%sp + 64 + 0x40], %f16 + ldd [%sp + 64 + 0x48], %f18 + ldd [%sp + 64 + 0x50], %f20 + ldd [%sp + 64 + 0x58], %f22 + ldd [%sp + 64 + 0x60], %f24 + ldd [%sp + 64 + 0x68], %f26 + ldd [%sp + 64 + 0x70], %f28 + ldd [%sp + 64 + 0x78], %f30 + ld [%sp + 64 + 0x80], %fsr + ba .Lno_reschedule + add %sp, 34 * 4, %sp +.Lno_fp_context: +#endif /* CONFIG_FPU_SHARING */ + + call z_sparc_context_switch + nop +.Lno_reschedule: +#endif /* CONFIG_PREEMPT_ENABLED */ + + /* Restore the interrupted context. */ + ld [%fp + ISF_Y_OFFSET], %g1 + wr %g1, 0, %y + + ldd [%fp + ISF_PSR_OFFSET], %l0 /* psr, pc */ + ld [%fp + ISF_NPC_OFFSET], %l2 /* npc */ + /* NOTE: %g1 will be restored later */ + + /* %g1 is used to access the stack frame later */ + mov %fp, %g1 + ldd [%fp + ISF_G2_OFFSET], %g2 + ld [%fp + ISF_G4_OFFSET], %g4 + add %fp, ISF_SIZE, %fp + + /* + * Install the PSR we got from the interrupt context. Current PSR.CWP + * is preserved. Keep PSR.ET=0 until we do "rett". + */ + rd %psr, %l3 + and %l3, PSR_CWP, %l3 + andn %l0, (PSR_CWP | PSR_ET), %l0 + or %l3, %l0, %l0 + mov %l0, %psr + nop + nop + nop + + /* Calculate %l6 := (cwp+1) % NWIN */ + rd %wim, %l3 + set (CONFIG_SPARC_NWIN), %l7 + add %l0, 1, %l6 + and %l6, PSR_CWP, %l6 + cmp %l6, %l7 + bge,a .Lwrapok + mov 0, %l6 + +.Lwrapok: + /* Determine if we must prepare the return window. */ + /* %l5 := %wim >> (cwp+1) */ + srl %l3, %l6, %l5 + /* %l5 is 1 if (cwp+1) is an invalid window */ + cmp %l5, 1 + bne .Lwudone + sub %l7, 1, %l7 /* %l7 := NWIN - 1 */ + + /* Do the window underflow. */ + sll %l3, 1, %l4 + srl %l3, %l7, %l5 + wr %l4, %l5, %wim + nop + nop + nop + + restore + ldd [%g1 + 0x00], %l0 + ldd [%g1 + 0x08], %l2 + ldd [%g1 + 0x10], %l4 + ldd [%g1 + 0x18], %l6 + ldd [%g1 + 0x20], %i0 + ldd [%g1 + 0x28], %i2 + ldd [%g1 + 0x30], %i4 + ldd [%g1 + 0x38], %i6 + save + +.Lwudone: + /* + * Restore %psr since we may have trashed condition codes. PSR.ET is + * still 0. + */ + wr %l0, %psr + nop + nop + nop + + /* restore g1 */ + ld [%g1 + ISF_G1_OFFSET], %g1 + + jmp %l1 + rett %l2 diff --git a/arch/sparc/core/irq_manage.c b/arch/sparc/core/irq_manage.c new file mode 100644 index 00000000000000..95d0523b5186c2 --- /dev/null +++ b/arch/sparc/core/irq_manage.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); + +FUNC_NORETURN void z_irq_spurious(const void *unused) +{ + uint32_t tbr; + + ARG_UNUSED(unused); + + __asm__ volatile ( + "rd %%tbr, %0" : + "=r" (tbr) + ); + LOG_ERR("Spurious interrupt detected! IRQ: %d", (tbr >> 4) & 0xf); + z_sparc_fatal_error(K_ERR_SPURIOUS_IRQ, NULL); +} + +void z_sparc_enter_irq(uint32_t irl) +{ + struct _isr_table_entry *ite; + + _current_cpu->nested++; + +#ifdef CONFIG_IRQ_OFFLOAD + if (irl != 141) { + irl = z_sparc_int_get_source(irl); + ite = &_sw_isr_table[irl]; + ite->isr(ite->arg); + } else { + z_irq_do_offload(); + } +#else + /* Get the actual interrupt source from the interrupt controller */ + irl = z_sparc_int_get_source(irl); + ite = &_sw_isr_table[irl]; + ite->isr(ite->arg); +#endif + + _current_cpu->nested--; +#ifdef CONFIG_STACK_SENTINEL + z_check_stack_sentinel(); +#endif +} diff --git a/arch/sparc/core/irq_offload.c b/arch/sparc/core/irq_offload.c new file mode 100644 index 00000000000000..cd75963dec73a9 --- /dev/null +++ b/arch/sparc/core/irq_offload.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +volatile irq_offload_routine_t _offload_routine; +static volatile const void *offload_param; + +void z_irq_do_offload(void) +{ + irq_offload_routine_t tmp; + + if (!_offload_routine) { + return; + } + + tmp = _offload_routine; + _offload_routine = NULL; + + tmp((const void *)offload_param); +} + +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) +{ + unsigned int key; + + key = irq_lock(); + _offload_routine = routine; + offload_param = parameter; + + /* Generate irq offload trap */ + __asm__ volatile ("ta 13"); + + irq_unlock(key); +} diff --git a/arch/sparc/core/offsets/offsets.c b/arch/sparc/core/offsets/offsets.c new file mode 100644 index 00000000000000..cb4e2a8a4859c5 --- /dev/null +++ b/arch/sparc/core/offsets/offsets.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief SPARC kernel structure member offset definition file + * + * This module is responsible for the generation of the absolute symbols whose + * value represents the member offsets for various SPARC kernel structures. + */ + +#include +#include +#include +#include + +GEN_OFFSET_SYM(_callee_saved_t, y); +GEN_OFFSET_SYM(_callee_saved_t, psr); + +GEN_OFFSET_SYM(_callee_saved_t, l0_and_l1); +GEN_OFFSET_SYM(_callee_saved_t, l2); +GEN_OFFSET_SYM(_callee_saved_t, l3); +GEN_OFFSET_SYM(_callee_saved_t, l4); +GEN_OFFSET_SYM(_callee_saved_t, l5); +GEN_OFFSET_SYM(_callee_saved_t, l6); +GEN_OFFSET_SYM(_callee_saved_t, l7); +GEN_OFFSET_SYM(_callee_saved_t, i0); +GEN_OFFSET_SYM(_callee_saved_t, i1); +GEN_OFFSET_SYM(_callee_saved_t, i2); +GEN_OFFSET_SYM(_callee_saved_t, i3); +GEN_OFFSET_SYM(_callee_saved_t, i4); +GEN_OFFSET_SYM(_callee_saved_t, i5); +GEN_OFFSET_SYM(_callee_saved_t, i6); +GEN_OFFSET_SYM(_callee_saved_t, i7); +GEN_OFFSET_SYM(_callee_saved_t, o6); +GEN_OFFSET_SYM(_callee_saved_t, o7); + +/* esf member offsets */ +GEN_OFFSET_SYM(z_arch_esf_t, pc); +GEN_OFFSET_SYM(z_arch_esf_t, npc); +GEN_OFFSET_SYM(z_arch_esf_t, psr); +GEN_OFFSET_SYM(z_arch_esf_t, tbr); +GEN_OFFSET_SYM(z_arch_esf_t, sp); +GEN_OFFSET_SYM(z_arch_esf_t, y); +GEN_ABSOLUTE_SYM(__z_arch_esf_t_SIZEOF, STACK_ROUND_UP(sizeof(z_arch_esf_t))); + +/* + * size of the struct k_thread structure sans save area for floating + * point regs + */ +GEN_ABSOLUTE_SYM(_K_THREAD_NO_FLOAT_SIZEOF, sizeof(struct k_thread)); + +GEN_ABS_SYM_END diff --git a/arch/sparc/core/prep_c.c b/arch/sparc/core/prep_c.c new file mode 100644 index 00000000000000..54c9eed513bb86 --- /dev/null +++ b/arch/sparc/core/prep_c.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Full C support initialization + */ + +#include + +/** + * + * @brief Prepare to and run C code + * + * This routine prepares for the execution of and runs C code. + * + * @return N/A + */ + +void _PrepC(void) +{ +#ifdef CONFIG_XIP + z_data_copy(); +#endif + z_cstart(); + CODE_UNREACHABLE; +} diff --git a/arch/sparc/core/reset_trap.S b/arch/sparc/core/reset_trap.S new file mode 100644 index 00000000000000..095a70357fd96c --- /dev/null +++ b/arch/sparc/core/reset_trap.S @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/* The trap table reset entry jumps to here. */ + +GTEXT(__sparc_trap_reset) +SECTION_FUNC(TEXT, __sparc_trap_reset) + set __sparc_trap_table, %g1 + wr %g1, %tbr + wr %g0, 4, %wim + /* %psr := pil=0, et=0, cwp=1 */ + set (PSR_S | PSR_PS | 1), %g7 + wr %g7, %psr + nop + nop + nop + /* NOTE: wrpsr above may have changed the current register window. */ + + /* + * According to SPARC ABI, Chapter 3: The system marks the deepest + * stack frame by setting the frame pointer to zero. No other frame's + * %fp has a zero value. + */ + set z_interrupt_stacks, %o0 + set CONFIG_ISR_STACK_SIZE, %o2 + add %o0, %o2, %l2 + and %l2, 0xfffffff0, %l3 + sub %l3, 96, %sp + clr %fp + clr %i7 + +#ifdef CONFIG_INIT_STACKS + /* already have z_interrupt_stacks and CONFIG_ISR_STACK_SIZE in place */ + call memset + mov 0xaa, %o1 +#endif + + call z_bss_zero + nop + + /* Enable traps for the first time */ + /* %psr := pil=0, et=1, cwp=1 */ + wr %g7, PSR_ET, %psr + nop + nop + nop + + call _PrepC + nop + +/* We halt the system by generating a "trap in trap" condition. */ +GTEXT(arch_system_halt) +SECTION_FUNC(TEXT, arch_system_halt) + mov %o0, %g0 + mov %g1, %g0 + set 1, %g1 + ta 0x00 diff --git a/arch/sparc/core/stack_offsets.h b/arch/sparc/core/stack_offsets.h new file mode 100644 index 00000000000000..0c32e3cfc69337 --- /dev/null +++ b/arch/sparc/core/stack_offsets.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_SPARC_CORE_STACK_H_ +#define ZEPHYR_ARCH_SPARC_CORE_STACK_H_ + +/* + * Offsets for SPARC ABI stack frame. + * + * Reference: System V Application Binary Interface, SPARC Processor + * Supplement, Third Edition, Page 3-35. + */ +#define STACK_FRAME_L0_OFFSET 0x00 +#define STACK_FRAME_L1_OFFSET 0x04 +#define STACK_FRAME_L2_OFFSET 0x08 +#define STACK_FRAME_L3_OFFSET 0x0c +#define STACK_FRAME_L4_OFFSET 0x10 +#define STACK_FRAME_L5_OFFSET 0x14 +#define STACK_FRAME_L6_OFFSET 0x18 +#define STACK_FRAME_L7_OFFSET 0x1c +#define STACK_FRAME_I0_OFFSET 0x20 +#define STACK_FRAME_I1_OFFSET 0x24 +#define STACK_FRAME_I2_OFFSET 0x28 +#define STACK_FRAME_I3_OFFSET 0x2c +#define STACK_FRAME_I4_OFFSET 0x30 +#define STACK_FRAME_I5_OFFSET 0x34 +#define STACK_FRAME_I6_OFFSET 0x38 +#define STACK_FRAME_I7_OFFSET 0x3c +#define STACK_FRAME_STRUCTURE_RETURN_ADDRESS_OFFSET 0x40 +#define STACK_FRAME_SAVED_ARG0_OFFSET 0x44 +#define STACK_FRAME_SAVED_ARG1_OFFSET 0x48 +#define STACK_FRAME_SAVED_ARG2_OFFSET 0x4c +#define STACK_FRAME_SAVED_ARG3_OFFSET 0x50 +#define STACK_FRAME_SAVED_ARG4_OFFSET 0x54 +#define STACK_FRAME_SAVED_ARG5_OFFSET 0x58 +#define STACK_FRAME_PAD0_OFFSET 0x5c +#define STACK_FRAME_SIZE 0x60 + + +/* Interrupt stack frame */ +#define ISF_PSR_OFFSET (0x40 + 0x00) +#define ISF_PC_OFFSET (0x40 + 0x04) +#define ISF_NPC_OFFSET (0x40 + 0x08) +#define ISF_G1_OFFSET (0x40 + 0x0c) +#define ISF_G2_OFFSET (0x40 + 0x10) +#define ISF_G3_OFFSET (0x40 + 0x14) +#define ISF_G4_OFFSET (0x40 + 0x18) +#define ISF_Y_OFFSET (0x40 + 0x1c) + +#if !defined(_FLAT) + #define ISF_SIZE (0x20) +#else +/* + * The flat ABI stores and loads "local" and "in" registers in the save area as + * part of function prologue and epilogue. So we allocate space for a new save + * area (0x40 byte) as part of the interrupt stack frame. + */ + #define ISF_SIZE (0x40 + 0x20) +#endif + +#endif /* ZEPHYR_ARCH_SPARC_CORE_STACK_H_ */ diff --git a/arch/sparc/core/sw_trap_set_pil.S b/arch/sparc/core/sw_trap_set_pil.S new file mode 100644 index 00000000000000..08ecf751002cbb --- /dev/null +++ b/arch/sparc/core/sw_trap_set_pil.S @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +GTEXT(__sparc_trap_sw_set_pil) + +/* + * Set processor interrupt level + * + * Handler for SPARC trap 0x89: trap_instruction, defined as "Reserved for the + * operating system" by SPARC-ABI. + * + * entry: + * - %l0: psr + * - %l1: pc + * - %l2: npc + * - %i0: New processor interrupt level + * + * return: + * - %i0: Old processor interrupt level + */ +SECTION_FUNC(TEXT, __sparc_trap_sw_set_pil) + /* %l5: new %psr */ + sll %i0, PSR_PIL_BIT, %i0 + andn %l0, PSR_PIL, %l5 + or %l5, %i0, %l5 + + wr %l5, %psr + nop + nop + nop + + and %l0, PSR_PIL, %l3 + srl %l3, PSR_PIL_BIT, %i0 + + jmp %l2 + rett %l2 + 4 diff --git a/arch/sparc/core/switch.S b/arch/sparc/core/switch.S new file mode 100644 index 00000000000000..1fe71edb52d9e5 --- /dev/null +++ b/arch/sparc/core/switch.S @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +GTEXT(z_sparc_arch_switch) +GTEXT(z_sparc_context_switch) +GTEXT(z_thread_entry_wrapper) + +/* In this implementation, switch_handle is the thread itself. */ +SECTION_FUNC(TEXT, z_sparc_arch_switch) + ba z_sparc_context_switch + sub %o1, ___thread_t_switch_handle_OFFSET, %o1 + +/* + * This is a leaf function, so only out registers + * can be used without saving their context first. + * + * o0: new thread to restore + * o1: old thread to save + */ +SECTION_FUNC(TEXT, z_sparc_context_switch) + mov %y, %o4 + st %o4, [%o1 + _thread_offset_to_y] + std %l0, [%o1 + _thread_offset_to_l0_and_l1] + std %l2, [%o1 + _thread_offset_to_l2] + std %l4, [%o1 + _thread_offset_to_l4] + std %l6, [%o1 + _thread_offset_to_l6] + std %i0, [%o1 + _thread_offset_to_i0] + std %i2, [%o1 + _thread_offset_to_i2] + std %i4, [%o1 + _thread_offset_to_i4] + std %i6, [%o1 + _thread_offset_to_i6] + + std %o6, [%o1 + _thread_offset_to_o6] + + rd %psr, %o4 + st %o4, [%o1 + _thread_offset_to_psr] + + and %o4, PSR_CWP, %g3 /* %g3 = CWP */ + andn %o4, PSR_ET, %g1 /* %g1 = psr with traps disabled */ + wr %g1, %psr /* disable traps */ + nop + nop + nop + + rd %wim, %g2 /* %g2 = wim */ + mov 1, %g4 + sll %g4, %g3, %g4 /* %g4 = wim mask for CW invalid */ + +.Lsave_frame_loop: + sll %g4, 1, %g5 /* rotate wim left by 1 */ + srl %g4, (CONFIG_SPARC_NWIN-1), %g4 + or %g4, %g5, %g4 /* %g4 = wim if we do one restore */ + + /* if restore would not underflow, continue */ + andcc %g4, %g2, %g0 /* window to flush? */ + bnz .Ldone_flushing /* continue */ + nop + restore /* go one window back */ + + /* essentially the same as window overflow */ + /* sp still points to task stack */ + std %l0, [%sp + 0x00] + std %l2, [%sp + 0x08] + std %l4, [%sp + 0x10] + std %l6, [%sp + 0x18] + std %i0, [%sp + 0x20] + std %i2, [%sp + 0x28] + std %i4, [%sp + 0x30] + std %i6, [%sp + 0x38] + ba .Lsave_frame_loop + nop + +.Ldone_flushing: + /* + * "wrpsr" is a delayed write instruction so wait three instructions + * after the write before using non-global registers or instructions + * affecting the CWP. + */ + wr %g1, %psr /* restore cwp */ + nop + nop + nop + add %g3, 1, %g2 /* calculate desired wim */ + cmp %g2, (CONFIG_SPARC_NWIN-1) /* check if wim is in range */ + bg,a .Lwim_overflow + mov 0, %g2 + +.Lwim_overflow: + + mov 1, %g4 + sll %g4, %g2, %g4 /* %g4 = new wim */ + wr %g4, %wim + nop + nop + nop + + ldd [%o0 + _thread_offset_to_y], %o4 + mov %o4, %y + + /* restore local registers */ + ldd [%o0 + _thread_offset_to_l0_and_l1], %l0 + ldd [%o0 + _thread_offset_to_l2], %l2 + ldd [%o0 + _thread_offset_to_l4], %l4 + ldd [%o0 + _thread_offset_to_l6], %l6 + + /* restore input registers */ + ldd [%o0 + _thread_offset_to_i0], %i0 + ldd [%o0 + _thread_offset_to_i2], %i2 + ldd [%o0 + _thread_offset_to_i4], %i4 + ldd [%o0 + _thread_offset_to_i6], %i6 + + /* restore output registers */ + ldd [%o0 + _thread_offset_to_o6], %o6 +#ifdef CONFIG_THREAD_LOCAL_STORAGE + ld [%o0 + _thread_offset_to_tls], %g7 +#endif + + ld [%o0 + _thread_offset_to_psr], %g1 /* %g1 = new thread psr */ + + andn %g1, PSR_CWP, %g1 /* psr without cwp */ + or %g1, %g3, %g1 /* psr with new cwp */ + wr %g1, %psr /* restore status register and ET */ + nop + nop + nop + + /* jump into thread */ + jmp %o7 + 8 + nop + +SECTION_FUNC(TEXT, z_thread_entry_wrapper) + mov %g0, %o7 + ld [%sp + 0x40], %o0 + ld [%sp + 0x44], %o1 + ld [%sp + 0x48], %o2 + ld [%sp + 0x4C], %o3 + call z_thread_entry + nop diff --git a/arch/sparc/core/thread.c b/arch/sparc/core/thread.c new file mode 100644 index 00000000000000..ee7e4e9b6380ee --- /dev/null +++ b/arch/sparc/core/thread.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +void z_thread_entry_wrapper(k_thread_entry_t thread, + void *arg1, + void *arg2, + void *arg3); + +/* + * Frame used by _thread_entry_wrapper + * + * Allocate a 16 register window save area at bottom of the stack. This is + * required if we need to taken a trap (interrupt) in the thread entry wrapper. + */ +struct init_stack_frame { + uint32_t window_save_area[16]; + k_thread_entry_t entry_point; + void *arg1; + void *arg2; + void *arg3; + uint32_t pad[8]; +}; + +#if defined(CONFIG_FPU_SHARING) + #define USER_FP_MASK K_FP_REGS +#else + #define USER_FP_MASK 0 +#endif + +void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) +{ + struct init_stack_frame *iframe; + + /* Initial stack frame data, stored at base of the stack */ + iframe = Z_STACK_PTR_TO_FRAME(struct init_stack_frame, stack_ptr); + + iframe->entry_point = entry; + iframe->arg1 = p1; + iframe->arg2 = p2; + iframe->arg3 = p3; + + /* Put values for debugging purposes */ + thread->callee_saved.i6 = 0; /* frame pointer */ + thread->callee_saved.o6 = (uint32_t) iframe; /* stack pointer */ + thread->callee_saved.o7 = (uint32_t) z_thread_entry_wrapper - 8; + thread->callee_saved.psr = PSR_S | PSR_PS | PSR_ET; + + if (IS_ENABLED(CONFIG_FPU_SHARING)) { + /* Selected threads can use the FPU */ + if (thread->base.user_options & USER_FP_MASK) { + thread->callee_saved.psr |= PSR_EF; + } + } else if (IS_ENABLED(CONFIG_FPU)) { + /* Any thread can use the FPU */ + thread->callee_saved.psr |= PSR_EF; + } + + thread->switch_handle = thread; +} + +void *z_arch_get_next_switch_handle(struct k_thread **old_thread) +{ + *old_thread = _current; + + return z_get_next_switch_handle(*old_thread); +} + +#if defined(CONFIG_FPU_SHARING) +int arch_float_disable(struct k_thread *thread) +{ + return -ENOSYS; +} +#endif /* CONFIG_FPU_SHARING */ diff --git a/arch/sparc/core/tls.c b/arch/sparc/core/tls.c new file mode 100644 index 00000000000000..8e9d5bee1b8d84 --- /dev/null +++ b/arch/sparc/core/tls.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) +{ + new_thread->tls = POINTER_TO_UINT(stack_ptr); + + stack_ptr -= z_tls_data_size(); + z_tls_copy(stack_ptr); + + return z_tls_data_size(); +} diff --git a/arch/sparc/core/trap_table_mvt.S b/arch/sparc/core/trap_table_mvt.S new file mode 100644 index 00000000000000..9e44caf82508a9 --- /dev/null +++ b/arch/sparc/core/trap_table_mvt.S @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This file contains a full SPARC V8 trap table. The processor redirects + * exection to the trap table on trap events. Each trap table entrys is four + * instructions. + */ + +#include +#include + +#define BAD_TRAP \ + rd %psr, %l0; \ + sethi %hi(__sparc_trap_fault), %l4; \ + jmp %l4+%lo(__sparc_trap_fault); \ + rd %tbr, %l6; + +#define INTERRUPT_TRAP(level) \ + rd %psr, %l0; \ + sethi %hi(INT_HANDLER), %l4; \ + jmp %l4+%lo(INT_HANDLER); \ + mov (0xf & level), %l3; + +#define TRAP(handler) \ + rd %psr, %l0; \ + sethi %hi(handler), %l4; \ + jmp %l4+%lo(handler); \ + nop; + +#define RESET_TRAP(handler) \ + mov %g0, %g4; \ + sethi %hi(handler), %g4; \ + jmp %g4+%lo(handler); \ + nop; + +#define SOFT_TRAP \ + ta 0x00; \ + nop; \ + nop; \ + nop; + +#define WOF_TRAP TRAP(__sparc_trap_window_overflow) +#define WUF_TRAP TRAP(__sparc_trap_window_underflow) +#define FLW_TRAP BAD_TRAP +#define INT_HANDLER __sparc_trap_interrupt + +#ifdef CONFIG_IRQ_OFFLOAD + #define IRQ_OFFLOAD_TRAP TRAP(__sparc_trap_irq_offload) +#else + #define IRQ_OFFLOAD_TRAP BAD_TRAP +#endif + +GTEXT(__sparc_trap_table) +GTEXT(__start) + +SECTION_SUBSEC_FUNC(TEXT, traptable, __sparc_trap_table) +__start: + /* + * Values in the range 0 to 0x5F that are not assigned in SPARC V8 + * specification Table 7-1 are reserved for future versions of the + * architecture. + */ + RESET_TRAP(__sparc_trap_reset); ! 00 reset + BAD_TRAP; ! 01 instruction_access_exception + BAD_TRAP; ! 02 illegal_instruction + BAD_TRAP; ! 03 priveleged_instruction + BAD_TRAP; ! 04 fp_disabled + WOF_TRAP; ! 05 window_overflow + WUF_TRAP; ! 06 window_underflow + BAD_TRAP; ! 07 mem_address_not_aligned + BAD_TRAP; ! 08 fp_exception + BAD_TRAP; ! 09 data_access_exception + BAD_TRAP; ! 0A tag_overflow + BAD_TRAP; ! 0B watchpoint_detected + BAD_TRAP; ! 0C reserved + BAD_TRAP; ! 0D reserved + BAD_TRAP; ! 0E reserved + BAD_TRAP; ! 0F reserved + BAD_TRAP; ! 10 reserved + + /* Interrupt traps */ + INTERRUPT_TRAP(1); ! 11 interrupt_level_1 + INTERRUPT_TRAP(2); ! 12 interrupt_level_2 + INTERRUPT_TRAP(3); ! 13 interrupt_level_3 + INTERRUPT_TRAP(4); ! 14 interrupt_level_4 + INTERRUPT_TRAP(5); ! 15 interrupt_level_5 + INTERRUPT_TRAP(6); ! 16 interrupt_level_6 + INTERRUPT_TRAP(7); ! 17 interrupt_level_7 + INTERRUPT_TRAP(8); ! 18 interrupt_level_8 + INTERRUPT_TRAP(9); ! 19 interrupt_level_9 + INTERRUPT_TRAP(10); ! 1A interrupt_level_1 + INTERRUPT_TRAP(11); ! 1B interrupt_level_11 + INTERRUPT_TRAP(12); ! 1C interrupt_level_12 + INTERRUPT_TRAP(13); ! 1D interrupt_level_13 + INTERRUPT_TRAP(14); ! 1E interrupt_level_14 + INTERRUPT_TRAP(15); ! 1F interrupt_level_15 + BAD_TRAP; ! 20 r_register_access_error + BAD_TRAP; ! 21 instruction_access_error + BAD_TRAP; ! 22 reserved + BAD_TRAP; ! 23 reserved + BAD_TRAP; ! 24 cp_disabled + BAD_TRAP; ! 25 unimplemented_FLUSH + BAD_TRAP; ! 26 reserved + BAD_TRAP; ! 27 reserved + BAD_TRAP; ! 28 cp_exception + BAD_TRAP; ! 29 data_access_error + BAD_TRAP; ! 2A division_by_zero + BAD_TRAP; ! 2B data_store_error + BAD_TRAP; ! 2C data_access_MMU_miss + BAD_TRAP; ! 2D reserved + BAD_TRAP; ! 2E reserved + BAD_TRAP; ! 2F reserved + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30 - 33 reserved + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34 - 37 reserved + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38 - 3B reserved + BAD_TRAP; ! 3C instruction_access_MMU_miss + BAD_TRAP; ! 3D reserved + BAD_TRAP; ! 3E reserved + BAD_TRAP; ! 3F reserved + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40 - 43 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44 - 47 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48 - 4B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4C - 4F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50 - 53 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54 - 57 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58 - 5B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5C - 5F undefined + + /* + * tt values 0x60 to 0x7F are reserved for implementation-dependent + * exceptions. + */ + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60 - 63 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64 - 67 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68 - 6B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6C - 6F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70 - 73 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74 - 77 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78 - 7B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7C - 7F undefined + + /* trap_instruction 0x80 - 0xFF */ + /* NOTE: "ta 5" can be generated by compiler. */ + SOFT_TRAP; ! 0 System calls + SOFT_TRAP; ! 1 Breakpoints + SOFT_TRAP; ! 2 Division by zero + FLW_TRAP; ! 3 Flush windows + SOFT_TRAP; ! 4 Clean windows + SOFT_TRAP; ! 5 Range checking + SOFT_TRAP; ! 6 Fix alignment + SOFT_TRAP; ! 7 Integer overflow + SOFT_TRAP ! 8 System calls + TRAP(__sparc_trap_sw_set_pil); ! 9 Reserved for the os + SOFT_TRAP; ! 10 Reserved for the os + SOFT_TRAP; ! 11 Reserved for the os + /* See SPARC-ABI for purpose of the following software traps */ + SOFT_TRAP; ! 12 + IRQ_OFFLOAD_TRAP; ! 13 + SOFT_TRAP; ! 14 + SOFT_TRAP; ! 15 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90 - 93 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94 - 97 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98 - 9B + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9C - 9F + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A0 - A3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A4 - A7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A8 - AB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! AC - AF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B0 - B3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B4 - B7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B8 - BB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! BC - BF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C0 - C3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C4 - C7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C8 - CB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! CC - CF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D0 - D3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D4 - D7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D8 - DB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! DC - DF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E0 - E3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E4 - E7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E8 - EB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! EC - EF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F0 - F3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F4 - F7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F8 - FB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! FC - FF diff --git a/arch/sparc/core/window_trap.S b/arch/sparc/core/window_trap.S new file mode 100644 index 00000000000000..a348340e669125 --- /dev/null +++ b/arch/sparc/core/window_trap.S @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This file contains standard handlers for the SPARC V8 window overflow and + * underflow traps. + */ + +#include +#include + +GTEXT(__sparc_trap_window_overflow) +GTEXT(__sparc_trap_window_underflow) + +SECTION_FUNC(TEXT, __sparc_trap_window_overflow) + /* Enter the window to be stored. */ + save + /* Save local register set. */ + std %l0, [%sp + 0x00] + std %l2, [%sp + 0x08] + std %l4, [%sp + 0x10] + rd %wim, %l3 + std %l6, [%sp + 0x18] + /* l2 := WIM << (NWIN-1) */ + sll %l3, (CONFIG_SPARC_NWIN-1), %l2 + /* Save input register set. */ + std %i0, [%sp + 0x20] + /* l3 := WIM >> 1 */ + srl %l3, 1, %l3 + std %i2, [%sp + 0x28] + /* WIM := (WIM >> 1) ^ (WIM << (NWIN-1)) */ + wr %l3, %l2, %wim + /* NOTE: 3 instruction before restore (delayed write instruction) */ + std %i4, [%sp + 0x30] + nop + std %i6, [%sp + 0x38] + /* Go back to trap window. */ + restore + /* Re-execute save. */ + jmp %l1 + rett %l2 + +SECTION_FUNC(TEXT, __sparc_trap_window_underflow) + rd %wim, %l3 + /* l4 := WIM << 1 */ + sll %l3, 1, %l4 + /* l5 := WIM >> (NWIN-1) */ + srl %l3, (CONFIG_SPARC_NWIN-1), %l5 + /* WIM := (WIM << 1) ^ (WIM >> (NWIN-1)) */ + wr %l4, %l5, %wim + /* WIM is implicitly read so nops are needed. */ + nop + nop + nop + + /* Enter the window to restore requires two restore instructions. */ + restore + restore + ldd [%sp + 0x00], %l0 + ldd [%sp + 0x08], %l2 + ldd [%sp + 0x10], %l4 + ldd [%sp + 0x18], %l6 + ldd [%sp + 0x20], %i0 + ldd [%sp + 0x28], %i2 + ldd [%sp + 0x30], %i4 + ldd [%sp + 0x38], %i6 + /* Go back to the trap window. */ + save + save + /* Re-execute restore. */ + jmp %l1 + rett %l2 diff --git a/arch/sparc/include/kernel_arch_data.h b/arch/sparc/include/kernel_arch_data.h new file mode 100644 index 00000000000000..ff3dbfc6324b8a --- /dev/null +++ b/arch/sparc/include/kernel_arch_data.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Private kernel definitions + * + * This file contains private kernel structures definitions and various + * other definitions for the SPARC processor architecture. + */ + +#ifndef ZEPHYR_ARCH_SPARC_INCLUDE_KERNEL_ARCH_DATA_H_ +#define ZEPHYR_ARCH_SPARC_INCLUDE_KERNEL_ARCH_DATA_H_ + +#include +#include +#include + +#ifndef _ASMLANGUAGE +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_ARCH_SPARC_INCLUDE_KERNEL_ARCH_DATA_H_ */ diff --git a/arch/sparc/include/kernel_arch_func.h b/arch/sparc/include/kernel_arch_func.h new file mode 100644 index 00000000000000..889048e463ac0c --- /dev/null +++ b/arch/sparc/include/kernel_arch_func.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Private kernel definitions + * + * This file contains private kernel function/macro definitions and various + * other definitions for the SPARC processor architecture. + */ + +#ifndef ZEPHYR_ARCH_SPARC_INCLUDE_KERNEL_ARCH_FUNC_H_ +#define ZEPHYR_ARCH_SPARC_INCLUDE_KERNEL_ARCH_FUNC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ASMLANGUAGE +static ALWAYS_INLINE void arch_kernel_init(void) +{ +} + +void z_sparc_arch_switch(void *switch_to, void **switched_from); + +static inline void arch_switch(void *switch_to, void **switched_from) +{ + z_sparc_arch_switch(switch_to, switched_from); +} + +FUNC_NORETURN void z_sparc_fatal_error(unsigned int reason, + const z_arch_esf_t *esf); + +static inline bool arch_is_in_isr(void) +{ + return _current_cpu->nested != 0U; +} + +#ifdef CONFIG_IRQ_OFFLOAD +void z_irq_do_offload(void); +#endif + +#endif /* _ASMLANGUAGE */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_ARCH_SPARC_INCLUDE_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/sparc/include/offsets_short_arch.h b/arch/sparc/include/offsets_short_arch.h new file mode 100644 index 00000000000000..074f82ae71f5b1 --- /dev/null +++ b/arch/sparc/include/offsets_short_arch.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_SPARC_INCLUDE_OFFSETS_SHORT_ARCH_H_ +#define ZEPHYR_ARCH_SPARC_INCLUDE_OFFSETS_SHORT_ARCH_H_ + +#include + +#define _thread_offset_to_y \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_y_OFFSET) + +#define _thread_offset_to_l0_and_l1 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_l0_and_l1_OFFSET) + +#define _thread_offset_to_l2 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_l2_OFFSET) + +#define _thread_offset_to_l3 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_l3_OFFSET) + +#define _thread_offset_to_l4 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_l4_OFFSET) + +#define _thread_offset_to_l5 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_l5_OFFSET) + +#define _thread_offset_to_l6 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_l6_OFFSET) + +#define _thread_offset_to_l7 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_l7_OFFSET) + +#define _thread_offset_to_i0 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_i0_OFFSET) + +#define _thread_offset_to_i1 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_i1_OFFSET) + +#define _thread_offset_to_i2 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_i2_OFFSET) + +#define _thread_offset_to_i3 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_i3_OFFSET) + +#define _thread_offset_to_i4 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_i4_OFFSET) + +#define _thread_offset_to_i5 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_i5_OFFSET) + +#define _thread_offset_to_i6 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_i6_OFFSET) + +#define _thread_offset_to_i7 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_i7_OFFSET) + +#define _thread_offset_to_o6 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_o6_OFFSET) + +#define _thread_offset_to_o7 \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_o7_OFFSET) + +#define _thread_offset_to_psr \ + (___thread_t_callee_saved_OFFSET + ___callee_saved_t_psr_OFFSET) + +#endif /* ZEPHYR_ARCH_SPARC_INCLUDE_OFFSETS_SHORT_ARCH_H_ */ diff --git a/arch/x86/CMakeLists.txt b/arch/x86/CMakeLists.txt index 555f12431cce57..5d70317b672efc 100644 --- a/arch/x86/CMakeLists.txt +++ b/arch/x86/CMakeLists.txt @@ -1,8 +1,62 @@ # Copyright (c) 2019 Intel Corp. # SPDX-License-Identifier: Apache-2.0 +# Convert the .bin file argument to a .o file, create a wrapper +# library for the .o file, and register the library as a generated +# file that is to be linked in after the first link. +function(add_bin_file_to_the_next_link target_dependency bin) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${bin}.o + COMMAND + ${CMAKE_OBJCOPY} + -I binary + -B ${OUTPUT_ARCH} + -O ${OUTPUT_FORMAT} + --rename-section .data=${bin},CONTENTS,ALLOC,LOAD,READONLY,DATA + ${bin}.bin + ${bin}.o + DEPENDS ${target_dependency} ${bin}.bin + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + add_custom_target(${bin}_o DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${bin}.o) + add_library(${bin} STATIC IMPORTED GLOBAL) + set_property(TARGET ${bin} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${bin}.o) + add_dependencies(${bin} ${bin}_o) + set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_OBJECT_FILES ${bin}) +endfunction() + if(CONFIG_X86_64) include(intel64.cmake) else() include(ia32.cmake) endif() + +# Always set for 64-bit (long mode requires page tables), optional for 32-bit +if (CONFIG_MMU) + set(GEN_MMU ${ZEPHYR_BASE}/arch/x86/gen_mmu.py) + + add_custom_target( + pagetables_bin_target + DEPENDS + pagetables.bin + ) + add_custom_command( + OUTPUT pagetables.bin + COMMAND + ${PYTHON_EXECUTABLE} + ${GEN_MMU} + --kernel $ + --output pagetables.bin + $<$:--verbose> + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${ZEPHYR_PREBUILT_EXECUTABLE} ${GEN_MMU} + ) + + add_bin_file_to_the_next_link(pagetables_bin_target pagetables) +endif() + +if(CONFIG_ARCH_HAS_TIMING_FUNCTIONS AND + NOT CONFIG_SOC_HAS_TIMING_FUNCTIONS AND + NOT CONFIG_BOARD_HAS_TIMING_FUNCTIONS) +zephyr_library_sources_ifdef(CONFIG_TIMING_FUNCTIONS timing.c) +endif() diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 860e1143cdeb0c..2b4c5eb1cdbdc1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -46,6 +46,21 @@ config X86_64 select USE_SWITCH select USE_SWITCH_SUPPORTED select SCHED_IPI_SUPPORTED + select X86_MMU + +config X86_KERNEL_OFFSET + int "Kernel offset from beginning of RAM" + default 1048576 + help + A lot of x86 that resemble PCs have many reserved physical memory + regions within the first megabyte. Specify an offset from the + beginning of RAM to load the kernel in physical memory, avoiding these + regions. + + Note that this does not include the "locore" which contains real mode + bootstrap code within the first 64K of physical memory. + + This value normally need to be page-aligned. config MAX_IRQ_LINES int "Number of IRQ lines" @@ -62,9 +77,6 @@ config IRQ_OFFLOAD_VECTOR range 32 255 depends on IRQ_OFFLOAD -config XIP - default n - config PIC_DISABLE bool "Disable PIC" help @@ -86,6 +98,14 @@ config ACPI help Allow retrieval of platform configuration at runtime. +config PCIE_MMIO_CFG + bool "Use MMIO PCI configuration space access" + select ACPI + help + Selects the use of the memory-mapped PCI Express Extended + Configuration Space instead of the traditional 0xCF8/0xCFC + IO Port registers. + config X86_MEMMAP_ENTRIES int "Number of memory map entries" range 1 256 @@ -152,6 +172,7 @@ config EXCEPTION_DEBUG config X86_VERY_EARLY_CONSOLE bool "Support very early boot printk" depends on PRINTK + default y help Non-emulated X86 devices often require special hardware to attach a debugger, which may not be easily available. This option adds a @@ -162,7 +183,7 @@ config X86_VERY_EARLY_CONSOLE config X86_MMU bool "Enable Memory Management Unit" - select MEMORY_PROTECTION + select MMU help This options enables the memory management unit present in x86 and creates a set of page tables at boot time that is runtime- @@ -170,12 +191,38 @@ config X86_MMU config X86_MMU_PAGE_POOL_PAGES int "Number of pages to reserve for building page tables" - default 16 + default 0 depends on X86_MMU help - Building page tables at boot requires a pool of free memory pages - to construct it. This can't be derived at build time, tune this - to your SoC's specific memory map. + Define the number of pages in the pool used to allocate page table + data structures at runtime. + + Pages might need to be drawn from the pool during memory mapping + operations, unless the address space has been completely pre-allocated. + + Pages will need to drawn from the pool to initialize memory domains. + This does not include the default memory domain if KPTI=n. + + The specific value used here depends on the size of physical RAM, + how much additional virtual memory will be mapped at runtime, and + how many memory domains need to be initialized. + + The current suite of Zephyr test cases may initialize at most two + additional memory domains besides the default domain. + + Unused pages in this pool cannot be used for other purposes. + +config X86_COMMON_PAGE_TABLE + bool "Use a single page table for all threads" + default n + depends on USERSPACE + depends on !SMP + depends on !X86_KPTI + help + If this option is enabled, userspace memory domains will not have their + own page tables. Instead, context switching operations will modify + page tables in place. This is much slower, but uses much less RAM + for page tables. config X86_NO_MELTDOWN bool diff --git a/arch/x86/core/CMakeLists.txt b/arch/x86/core/CMakeLists.txt index e05a2ed034b710..cc4d4d26d710fe 100644 --- a/arch/x86/core/CMakeLists.txt +++ b/arch/x86/core/CMakeLists.txt @@ -4,7 +4,8 @@ zephyr_library() if (CONFIG_COVERAGE) - toolchain_cc_coverage() + zephyr_compile_options($) + zephyr_link_libraries($) endif () zephyr_library_sources(cpuhalt.c) @@ -13,15 +14,17 @@ zephyr_library_sources(prep_c.c) zephyr_library_sources(fatal.c) zephyr_library_sources(spec_ctrl.c) -zephyr_library_sources_if_kconfig(pcie.c) -zephyr_library_sources_if_kconfig(reboot_rst_cnt.c) -zephyr_library_sources_if_kconfig(multiboot.c) -zephyr_library_sources_if_kconfig(acpi.c) -zephyr_library_sources_if_kconfig(x86_mmu.c) -zephyr_library_sources_if_kconfig(userspace.c) +zephyr_library_sources_ifdef(CONFIG_PCIE pcie.c) +zephyr_library_sources_ifdef(CONFIG_REBOOT_RST_CNT reboot_rst_cnt.c) +zephyr_library_sources_ifdef(CONFIG_MULTIBOOT multiboot.c) +zephyr_library_sources_ifdef(CONFIG_ACPI acpi.c) +zephyr_library_sources_ifdef(CONFIG_X86_MMU x86_mmu.c) +zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.c) zephyr_library_sources_ifdef(CONFIG_X86_VERY_EARLY_CONSOLE early_serial.c) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) + if(CONFIG_X86_64) include(intel64.cmake) else() diff --git a/arch/x86/core/Kconfig.ia32 b/arch/x86/core/Kconfig.ia32 index 8f1e9b9d00ac50..5f9972bb01322c 100644 --- a/arch/x86/core/Kconfig.ia32 +++ b/arch/x86/core/Kconfig.ia32 @@ -55,6 +55,7 @@ config X86_ENABLE_TSS config X86_STACK_PROTECTION bool default y if HW_STACK_PROTECTION + select THREAD_STACK_INFO select SET_GDT select GDT_DYNAMIC select X86_ENABLE_TSS @@ -75,6 +76,15 @@ config X86_USERSPACE supporting user-level threads that are protected from each other and from crashing the kernel. +config X86_PAE + bool "Use PAE page tables" + default y + depends on X86_MMU + help + If enabled, use PAE-style page tables instead of 32-bit page tables. + The advantage is support for the Execute Disable bit, at a cost of + more memory for paging structures. + menu "Architecture Floating Point Options" depends on CPU_HAS_FPU @@ -205,4 +215,12 @@ config X86_EXCEPTION_STACK_TRACE help Internal config to enable runtime stack traces on fatal exceptions. +config X86_USE_THREAD_LOCAL_STORAGE + bool + default y if THREAD_LOCAL_STORAGE + select SET_GDT + select GDT_DYNAMIC + help + Internal config to enable thread local storage. + endif # !X86_64 diff --git a/arch/x86/core/Kconfig.intel64 b/arch/x86/core/Kconfig.intel64 index a2e7fd9732a2a0..59e40751a522bb 100644 --- a/arch/x86/core/Kconfig.intel64 +++ b/arch/x86/core/Kconfig.intel64 @@ -20,9 +20,9 @@ config TEST_EXTRA_STACKSIZE config SYSTEM_WORKQUEUE_STACK_SIZE default 8192 -config EXCEPTION_STACK_SIZE +config X86_EXCEPTION_STACK_SIZE int "Size of the exception stack(s)" - default 2048 + default 4096 help The exception stack(s) (one per CPU) are used both for exception processing and early kernel/CPU initialization. They need only @@ -43,6 +43,12 @@ config SCHED_IPI_VECTOR range 33 255 depends on SMP +config TLB_IPI_VECTOR + int "IDT vector to use for TLB shootdown IPI" + default 35 + range 33 255 + depends on SMP + # We should really only have to provide one of the following two values, # but a bug in the Zephyr SDK for x86 precludes the use of division in # the assembler. For now, we require that these values be specified manually, diff --git a/arch/x86/core/acpi.c b/arch/x86/core/acpi.c index 166c70808240ca..6e553e711a4d98 100644 --- a/arch/x86/core/acpi.c +++ b/arch/x86/core/acpi.c @@ -1,103 +1,127 @@ /* - * Copyright (c) 2019 Intel Corporation + * Copyright (c) 2020 Intel Corporation * SPDX-License-Identifier: Apache-2.0 */ - #include #include -/* - * Finding and walking the ACPI tables can be time consuming, so we do - * it once, early, and then cache the "interesting" results for later. - */ - -static struct acpi_madt *madt; - -/* - * ACPI structures use a simple checksum, such that - * summing all the bytes in the structure yields 0. - */ +static struct acpi_rsdp *rsdp; +bool is_rdsp_searched = false; +static struct acpi_dmar *dmar; +bool is_dmar_searched; -static bool validate_checksum(void *buf, int len) +static bool check_sum(struct acpi_sdt *t) { - u8_t *cp = buf; - u8_t checksum = 0; + uint8_t sum = 0, *p = (uint8_t *)t; - while (len--) { - checksum += *(cp++); + for (int i = 0; i < t->length; i++) { + sum += p[i]; } - return (checksum == 0); + return sum == 0; } -/* - * Called very early during initialization to find ACPI tables of interest. - * First, we find the RDSP, and if found, use that to find the RSDT, which - * we then use to find the MADT. (This function is long, but easy to follow.) - */ -void z_acpi_init(void) -{ - /* - * First, find the RSDP by probing "well-known" areas of memory. - */ +/* We never identity map the NULL page, but may need to read some BIOS data */ +static uint8_t *zero_page_base; - struct acpi_rsdp *rsdp = NULL; +static void find_rsdp(void) +{ + uint8_t *bda_seg; - static const struct { - uintptr_t base; - uintptr_t top; - } area[] = { - { 0x000E0000, 0x00100000 }, /* BIOS ROM */ - { 0, 0 } - }; + if (is_rdsp_searched) { + /* Looking up for RSDP has already been done */ + return; + } - for (int i = 0; area[i].base && area[i].top && !rsdp; ++i) { - uintptr_t addr = area[i].base; + if (zero_page_base == NULL) { + z_mem_map(&zero_page_base, 0, 4096, K_MEM_PERM_RW); + } - while (addr < area[i].top) { - struct acpi_rsdp *probe = UINT_TO_POINTER(addr); + /* Physical (real mode!) address 0000:040e stores a (real + * mode!!) segment descriptor pointing to the 1kb Extended + * BIOS Data Area. Look there first. + * + * We had to memory map this segment descriptor since it is in + * the NULL page. The remaining structures (EBDA etc) are identity + * mapped somewhere within the minefield of reserved regions in the + * first megabyte and are directly accessible. + */ + bda_seg = 0x040e + zero_page_base; + uint64_t *search = (void *)(long)(((int)*(uint16_t *)bda_seg) << 4); - if ((probe->signature == ACPI_RSDP_SIGNATURE) && - (validate_checksum(probe, sizeof(*probe)))) { - rsdp = probe; - break; + /* Might be nothing there, check before we inspect */ + if (search != NULL) { + for (int i = 0; i < 1024/8; i++) { + if (search[i] == ACPI_RSDP_SIGNATURE) { + rsdp = (void *)&search[i]; + goto out; } - - addr += 0x10; } } - if (rsdp == NULL) { - return; + /* If it's not there, then look for it in the last 128kb of + * real mode memory. + */ + search = (uint64_t *)0xe0000; + + for (int i = 0; i < 128*1024/8; i++) { + if (search[i] == ACPI_RSDP_SIGNATURE) { + rsdp = (void *)&search[i]; + goto out; + } } - /* - * Then, validate the RSDT fingered by the RSDP. + /* Now we're supposed to look in the UEFI system table, which + * is passed as a function argument to the bootloader and long + * forgotten by now... */ + rsdp = NULL; +out: + is_rdsp_searched = true; +} - struct acpi_rsdt *rsdt = UINT_TO_POINTER(rsdp->rsdt); - if ((rsdt->sdt.signature != ACPI_RSDT_SIGNATURE) || - !validate_checksum(rsdt, rsdt->sdt.length)) { - rsdt = NULL; - return; +void *z_acpi_find_table(uint32_t signature) +{ + find_rsdp(); + + if (!rsdp) { + return NULL; } - /* - * Finally, probe each SDT listed in the RSDT to find the MADT. - * If it's valid, then remember it for later. - */ + struct acpi_rsdt *rsdt = (void *)(long)rsdp->rsdt_ptr; - int nr_sdts = (rsdt->sdt.length - sizeof(rsdt)) / sizeof(u32_t); - for (int i = 0; i < nr_sdts; ++i) { - struct acpi_sdt *sdt = UINT_TO_POINTER(rsdt->sdts[i]); + if (rsdt && check_sum(&rsdt->sdt)) { + uint32_t *end = (uint32_t *)((char *)rsdt + rsdt->sdt.length); - if ((sdt->signature == ACPI_MADT_SIGNATURE) - && validate_checksum(sdt, sdt->length)) { - madt = (struct acpi_madt *) sdt; - break; + for (uint32_t *tp = &rsdt->table_ptrs[0]; tp < end; tp++) { + struct acpi_sdt *t = (void *)(long)*tp; + + if (t->signature == signature && check_sum(t)) { + return t; + } } } + + if (rsdp->revision < 2) { + return NULL; + } + + struct acpi_xsdt *xsdt = (void *)(long)rsdp->xsdt_ptr; + + if (xsdt && check_sum(&xsdt->sdt)) { + uint64_t *end = (uint64_t *)((char *)xsdt + xsdt->sdt.length); + + for (uint64_t *tp = &xsdt->table_ptrs[0]; tp < end; tp++) { + struct acpi_sdt *t = (void *)(long)*tp; + + if (t->signature == signature && check_sum(t)) { + return t; + } + } + } + + return NULL; } /* @@ -106,28 +130,151 @@ void z_acpi_init(void) struct acpi_cpu *z_acpi_get_cpu(int n) { + struct acpi_madt *madt = z_acpi_find_table(ACPI_MADT_SIGNATURE); uintptr_t base = POINTER_TO_UINT(madt); uintptr_t offset; - if (madt) { - offset = POINTER_TO_UINT(madt->entries) - base; + if (!madt) { + return NULL; + } + + offset = POINTER_TO_UINT(madt->entries) - base; - while (offset < madt->sdt.length) { - struct acpi_madt_entry *entry; + while (offset < madt->sdt.length) { + struct acpi_madt_entry *entry; - entry = (struct acpi_madt_entry *) (offset + base); + entry = (struct acpi_madt_entry *)(offset + base); + if (entry->type == ACPI_MADT_ENTRY_CPU) { + struct acpi_cpu *cpu = (struct acpi_cpu *)entry; - if (entry->type == ACPI_MADT_ENTRY_CPU) { - if (n) { - --n; - } else { - return (struct acpi_cpu *) entry; + if (cpu->flags & ACPI_CPU_FLAGS_ENABLED) { + if (n == 0) { + return cpu; } - } - offset += entry->length; + --n; + } } + + offset += entry->length; } return NULL; } + +static void find_dmar(void) +{ + if (is_dmar_searched) { + return; + } + + dmar = z_acpi_find_table(ACPI_DMAR_SIGNATURE); + is_dmar_searched = true; +} + +struct acpi_dmar *z_acpi_find_dmar(void) +{ + find_dmar(); + return dmar; +} + +struct acpi_drhd *z_acpi_find_drhds(int *n) +{ + struct acpi_drhd *drhds = NULL; + uintptr_t offset; + uintptr_t base; + + find_dmar(); + + if (dmar == NULL) { + return NULL; + } + + *n = 0; + base = POINTER_TO_UINT(dmar); + + offset = POINTER_TO_UINT(dmar->remap_entries) - base; + while (offset < dmar->sdt.length) { + struct acpi_dmar_entry *entry; + + entry = (struct acpi_dmar_entry *)(offset + base); + if (entry->type == ACPI_DMAR_TYPE_DRHD) { + if (*n == 0) { + drhds = (struct acpi_drhd *)entry; + } + + (*n)++; + } else { + /* DMAR entries are found packed by type so + * if type is not DRHD, we will not encounter one, + * anymore. + */ + break; + } + + offset += entry->length; + } + + return drhds; +} + +struct acpi_dmar_dev_scope *z_acpi_get_drhd_dev_scopes(struct acpi_drhd *drhd, + int *n) +{ + uintptr_t offset; + uintptr_t base; + + if (drhd->entry.length <= ACPI_DRHD_MIN_SIZE) { + return NULL; + } + + *n = 0; + base = POINTER_TO_UINT(drhd); + + offset = POINTER_TO_UINT(drhd->device_scope) - base; + while (offset < drhd->entry.length) { + struct acpi_dmar_dev_scope *dev_scope; + + dev_scope = (struct acpi_dmar_dev_scope *)(offset + base); + + (*n)++; + + offset += dev_scope->length; + } + + return (*n == 0) ? NULL : drhd->device_scope; +} + +struct acpi_dmar_dev_path * +z_acpi_get_dev_scope_paths(struct acpi_dmar_dev_scope *dev_scope, int *n) +{ + switch (dev_scope->type) { + case ACPI_DRHD_DEV_SCOPE_PCI_EPD: + /* Fall through */ + case ACPI_DRHD_DEV_SCOPE_PCI_SUB_H: + /* Fall through */ + case ACPI_DRHD_DEV_SCOPE_IOAPIC: + if (dev_scope->length < (ACPI_DMAR_DEV_SCOPE_MIN_SIZE + + ACPI_DMAR_DEV_PATH_SIZE)) { + return NULL; + } + + break; + case ACPI_DRHD_DEV_SCOPE_MSI_CAP_HPET: + /* Fall through */ + case ACPI_DRHD_DEV_SCOPE_NAMESPACE_DEV: + if (dev_scope->length != (ACPI_DMAR_DEV_SCOPE_MIN_SIZE + + ACPI_DMAR_DEV_PATH_SIZE)) { + return NULL; + } + + break; + default: + return NULL; + } + + *n = (dev_scope->length - ACPI_DMAR_DEV_SCOPE_MIN_SIZE) / + ACPI_DMAR_DEV_PATH_SIZE; + + return dev_scope->path; +} diff --git a/arch/x86/core/early_serial.c b/arch/x86/core/early_serial.c index c4d9cc4f29a12b..d828e7cf115752 100644 --- a/arch/x86/core/early_serial.c +++ b/arch/x86/core/early_serial.c @@ -1,102 +1,73 @@ /* - * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2020 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include #include - -#include - -#if DT_PROP(DT_CHOSEN(zephyr_console), pcie) -BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE"); -#define UART_NS16550_PCIE_ENABLED #include +#include -#define UART_PCIE_BDF (DT_REG_ADDR(DT_CHOSEN(zephyr_console))) -#define UART_PCIE_ID (DT_REG_SIZE(DT_CHOSEN(zephyr_console))) -#endif - -/* Super-primitive 8250/16550 serial output-only driver, 115200 8n1 */ -#define REG_OFFSET_THR 0x00 /* Transmitter holding reg. */ -#define REG_OFFSET_IER 0x01 /* Interrupt enable reg. */ -#define REG_OFFSET_FCR 0x02 /* FIFO control reg. */ -#define REG_OFFSET_LCR 0x03 /* Line control reg. */ -#define REG_OFFSET_MCR 0x04 /* Modem control reg. */ -#define REG_OFFSET_LSR 0x05 /* Line status reg. */ -#define REG_OFFSET_BRDL 0x00 /* Baud rate divisor (LSB) */ -#define REG_OFFSET_BRDH 0x01 /* Baud rate divisor (MSB) */ - -#define IER_DISABLE 0x00 -#define LCR_8N1 (BIT(0) | BIT(1)) -#define LCR_DLAB_SELECT BIT(7) -#define MCR_DTR BIT(0) -#define MCR_RTS BIT(1) -#define LSR_THRE BIT(5) - -#define FCR_FIFO BIT(0) /* enable XMIT and RCVR FIFO */ -#define FCR_RCVRCLR BIT(1) /* clear RCVR FIFO */ -#define FCR_XMITCLR BIT(2) /* clear XMIT FIFO */ -#define FCR_FIFO_1 0 /* 1 byte in RCVR FIFO */ - -/* convenience defines */ -#define REG_THR(x) (x + REG_OFFSET_THR * UART_REG_ADDR_INTERVAL) -#define REG_IER(x) (x + REG_OFFSET_IER * UART_REG_ADDR_INTERVAL) -#define REG_FCR(x) (x + REG_OFFSET_FCR * UART_REG_ADDR_INTERVAL) -#define REG_LCR(x) (x + REG_OFFSET_LCR * UART_REG_ADDR_INTERVAL) -#define REG_MCR(x) (x + REG_OFFSET_MCR * UART_REG_ADDR_INTERVAL) -#define REG_LSR(x) (x + REG_OFFSET_LSR * UART_REG_ADDR_INTERVAL) -#define REG_BRDL(x) (x + REG_OFFSET_BRDL * UART_REG_ADDR_INTERVAL) -#define REG_BRDH(x) (x + REG_OFFSET_BRDH * UART_REG_ADDR_INTERVAL) - -#if DT_NODE_HAS_PROP(DT_CHOSEN(zephyr_console), reg_shift) -#define UART_REG_ADDR_INTERVAL \ - (1 << DT_PROP(DT_CHOSEN(zephyr_console), reg_shift)) -#endif #ifdef UART_NS16550_ACCESS_IOPORT -#define PORT ((io_port_t)DT_REG_ADDR(DT_CHOSEN(zephyr_console))) -#define INBYTE(x) sys_in8(x) -#define INWORD(x) sys_in32(x) -#define OUTBYTE(x, d) sys_out8(d, x) -#define OUTWORD(x, d) sys_out32(d, x) -#ifndef UART_REG_ADDR_INTERVAL -#define UART_REG_ADDR_INTERVAL 1 /* address diff of adjacent regs. */ -#endif /* UART_REG_ADDR_INTERVAL */ +/* Legacy I/O Port Access to a NS16550 UART */ +#define IN(reg) sys_in8(reg + UART_NS16550_ACCESS_IOPORT) +#define OUT(reg, val) sys_out8(val, reg + UART_NS16550_ACCESS_IOPORT) +#elif defined(X86_SOC_EARLY_SERIAL_PCIDEV) +/* "Modern" mapping of a UART into a PCI MMIO device. The registers + * are still bytes, but spaced at a 32 bit stride instead of packed + * together. + */ +static mm_reg_t mmio; +#define IN(reg) (sys_read32(mmio + reg * 4) & 0xff) +#define OUT(reg, val) sys_write32((val) & 0xff, mmio + reg * 4) +#elif defined(X86_SOC_EARLY_SERIAL_MMIO8_ADDR) +/* Still other devices use a MMIO region containing packed byte + * registers + */ +#if DEVICE_MMIO_IS_IN_RAM +static mm_reg_t mmio; +#define BASE mmio #else -#define PORT ((mm_reg_t)DT_REG_ADDR(DT_CHOSEN(zephyr_console))) -#define INBYTE(x) sys_read8(x) -#define INWORD(x) sys_read32(x) -#define OUTBYTE(x, d) sys_write8(d, x) -#define OUTWORD(x, d) sys_write32(d, x) -#ifndef UART_REG_ADDR_INTERVAL -#define UART_REG_ADDR_INTERVAL 4 /* address diff of adjacent regs. */ -#endif -#endif /* UART_NS16550_ACCESS_IOPORT */ - -#ifdef CONFIG_UART_NS16550_ACCESS_WORD_ONLY -#undef INBYTE -#define INBYTE(x) INWORD(x) -#undef OUTBYTE -#define OUTBYTE(x, d) OUTWORD(x, d) -#endif - -#ifdef UART_NS16550_PCIE_ENABLED -static mm_reg_t base; +#define BASE X86_SOC_EARLY_SERIAL_MMIO8_ADDR +#endif /* DEVICE_MMIO_IS_IN_RAM */ +#define IN(reg) sys_read8(BASE + reg) +#define OUT(reg, val) sys_write8(val, BASE + reg) #else -#define base PORT +#error "Unsupported configuration" #endif +#define REG_THR 0x00 /* Transmitter holding reg. */ +#define REG_IER 0x01 /* Interrupt enable reg. */ +#define REG_FCR 0x02 /* FIFO control reg. */ +#define REG_LCR 0x03 /* Line control reg. */ +#define REG_MCR 0x04 /* Modem control reg. */ +#define REG_LSR 0x05 /* Line status reg. */ +#define REG_BRDL 0x00 /* Baud rate divisor (LSB) */ +#define REG_BRDH 0x01 /* Baud rate divisor (MSB) */ + +#define IER_DISABLE 0x00 +#define LCR_8N1 (BIT(0) | BIT(1)) +#define LCR_DLAB_SELECT BIT(7) +#define MCR_DTR BIT(0) +#define MCR_RTS BIT(1) +#define LSR_THRE BIT(5) + +#define FCR_FIFO BIT(0) /* enable XMIT and RCVR FIFO */ +#define FCR_RCVRCLR BIT(1) /* clear RCVR FIFO */ +#define FCR_XMITCLR BIT(2) /* clear XMIT FIFO */ +#define FCR_FIFO_1 0 /* 1 byte in RCVR FIFO */ + static void serout(int c) { - while ((INBYTE(REG_LSR(base)) & LSR_THRE) == 0) { + while ((IN(REG_LSR) & LSR_THRE) == 0) { } - OUTBYTE(REG_THR(base), c); + OUT(REG_THR, c); } -static int console_out(int c) +int arch_printk_char_out(int c) { if (c == '\n') { serout('\r'); @@ -105,30 +76,27 @@ static int console_out(int c) return c; } -extern void __printk_hook_install(int (*fn)(int)); - void z_x86_early_serial_init(void) { -#ifdef UART_NS16550_PCIE_ENABLED - if (!pcie_probe(UART_PCIE_BDF, UART_PCIE_ID)) { - return; - } - - base = pcie_get_mbar(UART_PCIE_BDF, 0); - pcie_set_cmd(UART_PCIE_BDF, PCIE_CONF_CMDSTAT_MEM, true); +#if defined(DEVICE_MMIO_IS_IN_RAM) && !defined(UART_NS16550_ACCESS_IOPORT) +#ifdef X86_SOC_EARLY_SERIAL_PCIDEV + struct pcie_mbar mbar; + pcie_get_mbar(X86_SOC_EARLY_SERIAL_PCIDEV, 0, &mbar); + pcie_set_cmd(X86_SOC_EARLY_SERIAL_PCIDEV, PCIE_CONF_CMDSTAT_MEM, true); + device_map(&mmio, mbar.phys_addr, mbar.size, K_MEM_CACHE_NONE); +#else + device_map(&mmio, X86_SOC_EARLY_SERIAL_MMIO8_ADDR, 0x1000, K_MEM_CACHE_NONE); #endif - OUTBYTE(REG_IER(base), IER_DISABLE); /* Disable interrupts */ - OUTBYTE(REG_LCR(base), LCR_DLAB_SELECT);/* DLAB select */ - OUTBYTE(REG_BRDL(base), 1); /* Baud divisor = 1 */ - OUTBYTE(REG_BRDH(base), 0); - OUTBYTE(REG_LCR(base), LCR_8N1); /* LCR = 8n1 + DLAB off */ - OUTBYTE(REG_MCR(base), MCR_DTR | MCR_RTS); +#endif /* DEVICE_MMIO_IS_IN_RAM */ - /* Turn on FIFO. Some hardware needs this before transmitting */ - OUTBYTE(REG_FCR(base), - FCR_FIFO | FCR_FIFO_1 | FCR_RCVRCLR | FCR_XMITCLR); + OUT(REG_IER, IER_DISABLE); /* Disable interrupts */ + OUT(REG_LCR, LCR_DLAB_SELECT); /* DLAB select */ + OUT(REG_BRDL, 1); /* Baud divisor = 1 */ + OUT(REG_BRDH, 0); + OUT(REG_LCR, LCR_8N1); /* LCR = 8n1 + DLAB off */ + OUT(REG_MCR, MCR_DTR | MCR_RTS); - /* Will be replaced later when a real serial driver comes up */ - __printk_hook_install(console_out); + /* Turn on FIFO. Some hardware needs this before transmitting */ + OUT(REG_FCR, FCR_FIFO | FCR_FIFO_1 | FCR_RCVRCLR | FCR_XMITCLR); } diff --git a/arch/x86/core/fatal.c b/arch/x86/core/fatal.c index 8a3001adfd091d..0737f40e7ae009 100644 --- a/arch/x86/core/fatal.c +++ b/arch/x86/core/fatal.c @@ -9,7 +9,8 @@ #include #include #include -LOG_MODULE_DECLARE(os); +#include +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #if defined(CONFIG_BOARD_QEMU_X86) || defined(CONFIG_BOARD_QEMU_X86_64) FUNC_NORETURN void arch_system_halt(unsigned int reason) @@ -18,8 +19,15 @@ FUNC_NORETURN void arch_system_halt(unsigned int reason) /* Causes QEMU to exit. We passed the following on the command line: * -device isa-debug-exit,iobase=0xf4,iosize=0x04 + * + * For any value of the first argument X, the return value of the + * QEMU process is (X * 2) + 1. + * + * It has been observed that if the emulator exits for a triple-fault + * (often due to bad page tables or other CPU structures) it will + * terminate with 0 error code. */ - sys_out32(0, 0xf4); + sys_out32(reason, 0xf4); CODE_UNREACHABLE; } #endif @@ -43,12 +51,13 @@ static inline uintptr_t esf_get_code(const z_arch_esf_t *esf) } #ifdef CONFIG_THREAD_STACK_INFO -bool z_x86_check_stack_bounds(uintptr_t addr, size_t size, u16_t cs) +bool z_x86_check_stack_bounds(uintptr_t addr, size_t size, uint16_t cs) { uintptr_t start, end; - if (arch_is_in_isr()) { - /* We were servicing an interrupt */ + if (_current == NULL || arch_is_in_isr()) { + /* We were servicing an interrupt or in early boot environment + * and are supposed to be on the interrupt stack */ int cpu_id; #ifdef CONFIG_SMP @@ -56,21 +65,27 @@ bool z_x86_check_stack_bounds(uintptr_t addr, size_t size, u16_t cs) #else cpu_id = 0; #endif - start = (uintptr_t)Z_THREAD_STACK_BUFFER( + start = (uintptr_t)Z_KERNEL_STACK_BUFFER( z_interrupt_stacks[cpu_id]); end = start + CONFIG_ISR_STACK_SIZE; - } else if ((cs & 0x3U) != 0U || - (_current->base.user_options & K_USER) == 0) { - /* Thread was in user mode, or is not a user mode thread. - * The normal stack buffer is what we will check. +#ifdef CONFIG_USERSPACE + } else if ((cs & 0x3U) == 0 && + (_current->base.user_options & K_USER) != 0) { + /* The low two bits of the CS register is the privilege + * level. It will be 0 in supervisor mode and 3 in user mode + * corresponding to ring 0 / ring 3. + * + * If we get here, we must have been doing a syscall, check + * privilege elevation stack bounds */ + start = _current->stack_info.start - CONFIG_MMU_PAGE_SIZE; + end = _current->stack_info.start; +#endif /* CONFIG_USERSPACE */ + } else { + /* Normal thread operation, check its stack buffer */ start = _current->stack_info.start; end = Z_STACK_PTR_ALIGN(_current->stack_info.start + - _current->stack_info.size); - } else { - /* User thread was doing a syscall, check kernel stack bounds */ - start = _current->stack_info.start - MMU_PAGE_SIZE; - end = _current->stack_info.start; + _current->stack_info.size); } return (addr <= start) || (addr + size > end); @@ -89,7 +104,7 @@ struct stack_frame { #define MAX_STACK_FRAMES 8 -static void unwind_stack(uintptr_t base_ptr, u16_t cs) +static void unwind_stack(uintptr_t base_ptr, uint16_t cs) { struct stack_frame *frame; int i; @@ -134,19 +149,27 @@ static void unwind_stack(uintptr_t base_ptr, u16_t cs) } #endif /* CONFIG_X86_EXCEPTION_STACK_TRACE */ -static inline struct x86_page_tables *get_ptables(const z_arch_esf_t *esf) +static inline uintptr_t get_cr3(const z_arch_esf_t *esf) { #if defined(CONFIG_USERSPACE) && defined(CONFIG_X86_KPTI) /* If the interrupted thread was in user mode, we did a page table * switch when we took the exception via z_x86_trampoline_to_kernel */ if ((esf->cs & 0x3) != 0) { - return z_x86_thread_page_tables_get(_current); + return _current->arch.ptables; } #else ARG_UNUSED(esf); #endif - return z_x86_page_tables_get(); + /* Return the current CR3 value, it didn't change when we took + * the exception + */ + return z_x86_cr3_get(); +} + +static inline pentry_t *get_ptables(const z_arch_esf_t *esf) +{ + return (pentry_t *)get_cr3(esf); } #ifdef CONFIG_X86_64 @@ -160,8 +183,8 @@ static void dump_regs(const z_arch_esf_t *esf) esf->r8, esf->r9, esf->r10, esf->r11); LOG_ERR("R12: 0x%016lx R13: 0x%016lx R14: 0x%016lx R15: 0x%016lx", esf->r12, esf->r13, esf->r14, esf->r15); - LOG_ERR("RSP: 0x%016lx RFLAGS: 0x%016lx CS: 0x%04lx CR3: %p", esf->rsp, - esf->rflags, esf->cs & 0xFFFFU, get_ptables(esf)); + LOG_ERR("RSP: 0x%016lx RFLAGS: 0x%016lx CS: 0x%04lx CR3: 0x%016lx", + esf->rsp, esf->rflags, esf->cs & 0xFFFFU, get_cr3(esf)); #ifdef CONFIG_X86_EXCEPTION_STACK_TRACE LOG_ERR("call trace:"); @@ -178,8 +201,8 @@ static void dump_regs(const z_arch_esf_t *esf) esf->eax, esf->ebx, esf->ecx, esf->edx); LOG_ERR("ESI: 0x%08x, EDI: 0x%08x, EBP: 0x%08x, ESP: 0x%08x", esf->esi, esf->edi, esf->ebp, esf->esp); - LOG_ERR("EFLAGS: 0x%08x CS: 0x%04x CR3: %p", esf->eflags, - esf->cs & 0xFFFFU, get_ptables(esf)); + LOG_ERR("EFLAGS: 0x%08x CS: 0x%04x CR3: 0x%08lx", esf->eflags, + esf->cs & 0xFFFFU, get_cr3(esf)); #ifdef CONFIG_X86_EXCEPTION_STACK_TRACE LOG_ERR("call trace:"); @@ -260,38 +283,29 @@ static void log_exception(uintptr_t vector, uintptr_t code) } } -/* Page fault error code flags */ -#define PRESENT BIT(0) -#define WR BIT(1) -#define US BIT(2) -#define RSVD BIT(3) -#define ID BIT(4) -#define PK BIT(5) -#define SGX BIT(15) - static void dump_page_fault(z_arch_esf_t *esf) { - uintptr_t err, cr2; - - /* See Section 6.15 of the IA32 Software Developer's Manual vol 3 */ - __asm__ ("mov %%cr2, %0" : "=r" (cr2)); + uintptr_t err; + void *cr2; + cr2 = z_x86_cr2_get(); err = esf_get_code(esf); - LOG_ERR("Page fault at address 0x%lx (error code 0x%lx)", cr2, err); + LOG_ERR("Page fault at address %p (error code 0x%lx)", cr2, err); - if ((err & RSVD) != 0) { + if ((err & PF_RSVD) != 0) { LOG_ERR("Reserved bits set in page tables"); - } else if ((err & PRESENT) == 0) { - LOG_ERR("Linear address not present in page tables"); } else { + if ((err & PF_P) == 0) { + LOG_ERR("Linear address not present in page tables"); + } LOG_ERR("Access violation: %s thread not allowed to %s", - (err & US) != 0U ? "user" : "supervisor", - (err & ID) != 0U ? "execute" : ((err & WR) != 0U ? - "write" : - "read")); - if ((err & PK) != 0) { + (err & PF_US) != 0U ? "user" : "supervisor", + (err & PF_ID) != 0U ? "execute" : ((err & PF_WR) != 0U ? + "write" : + "read")); + if ((err & PF_PK) != 0) { LOG_ERR("Protection key disallowed"); - } else if ((err & SGX) != 0) { + } else if ((err & PF_SGX) != 0) { LOG_ERR("SGX access control violation"); } } @@ -305,11 +319,21 @@ static void dump_page_fault(z_arch_esf_t *esf) FUNC_NORETURN void z_x86_fatal_error(unsigned int reason, const z_arch_esf_t *esf) { -#ifdef CONFIG_EXCEPTION_DEBUG if (esf != NULL) { +#ifdef CONFIG_EXCEPTION_DEBUG dump_regs(esf); - } #endif +#if defined(CONFIG_ASSERT) && defined(CONFIG_X86_64) + if (esf->rip == 0xb9) { + /* See implementation of __resume in locore.S. This is + * never a valid RIP value. Treat this as a kernel + * panic. + */ + LOG_ERR("Attempt to resume un-suspended thread object"); + reason = K_ERR_KERNEL_PANIC; + } +#endif + } z_fatal_error(reason, esf); CODE_UNREACHABLE; } @@ -335,6 +359,10 @@ static const struct z_exc_handle exceptions[] = { void z_x86_page_fault_handler(z_arch_esf_t *esf) { +#if !defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_COREDUMP) + z_x86_exception_vector = IV_PAGE_FAULT; +#endif + #ifdef CONFIG_USERSPACE int i; @@ -342,7 +370,7 @@ void z_x86_page_fault_handler(z_arch_esf_t *esf) #ifdef CONFIG_X86_64 if ((void *)esf->rip >= exceptions[i].start && (void *)esf->rip < exceptions[i].end) { - esf->rip = (u64_t)(exceptions[i].fixup); + esf->rip = (uint64_t)(exceptions[i].fixup); return; } #else diff --git a/arch/x86/core/ia32.cmake b/arch/x86/core/ia32.cmake index cc89fcd67ef412..f10276052fe408 100644 --- a/arch/x86/core/ia32.cmake +++ b/arch/x86/core/ia32.cmake @@ -22,6 +22,14 @@ zephyr_library_sources( zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD ia32/irq_offload.c) zephyr_library_sources_ifdef(CONFIG_X86_USERSPACE ia32/userspace.S) zephyr_library_sources_ifdef(CONFIG_LAZY_FPU_SHARING ia32/float.c) +zephyr_library_sources_ifdef(CONFIG_GDBSTUB ia32/gdbstub.c) + +zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP ia32/coredump.c) + +zephyr_library_sources_ifdef( + CONFIG_X86_USE_THREAD_LOCAL_STORAGE + ia32/tls.c +) # Last since we declare default exception handlers here zephyr_library_sources(ia32/fatal.c) diff --git a/arch/x86/core/ia32/cache.c b/arch/x86/core/ia32/cache.c index b04290d8a13118..b9ce24fd794502 100644 --- a/arch/x86/core/ia32/cache.c +++ b/arch/x86/core/ia32/cache.c @@ -26,6 +26,10 @@ extern int z_is_clflush_available(void); extern void z_cache_flush_wbinvd(vaddr_t addr, size_t len); extern size_t z_cache_line_size_get(void); +#if defined(CONFIG_CACHE_LINE_SIZE_DETECT) +size_t sys_cache_line_size; +#endif + #if defined(CONFIG_CLFLUSH_INSTRUCTION_SUPPORTED) || \ defined(CONFIG_CLFLUSH_DETECT) @@ -33,6 +37,12 @@ extern size_t z_cache_line_size_get(void); #error Cannot use this implementation with a cache line size of 0 #endif +#if defined(CONFIG_CACHE_LINE_SIZE_DETECT) +#define DCACHE_LINE_SIZE sys_cache_line_size +#else +#define DCACHE_LINE_SIZE CONFIG_CACHE_LINE_SIZE +#endif + /** * * @brief Flush cache lines to main memory @@ -47,15 +57,16 @@ extern size_t z_cache_line_size_get(void); * @return N/A */ -_sys_cache_flush_sig(_cache_flush_clflush) +void arch_dcache_flush(void *start_addr, size_t size) { - int end; + uintptr_t start = (uintptr_t)start_addr; + uintptr_t end; - size = ROUND_UP(size, sys_cache_line_size); - end = virt + size; + size = ROUND_UP(size, DCACHE_LINE_SIZE); + end = start + size; - for (; virt < end; virt += sys_cache_line_size) { - __asm__ volatile("clflush %0;\n\t" : : "m"(virt)); + for (; start < end; start += DCACHE_LINE_SIZE) { + __asm__ volatile("clflush %0;\n\t" : : "m"(start)); } __asm__ volatile("mfence;\n\t"); @@ -67,43 +78,29 @@ _sys_cache_flush_sig(_cache_flush_clflush) #include -#if defined(CONFIG_CLFLUSH_DETECT) -_sys_cache_flush_t *sys_cache_flush; -static void init_cache_flush(void) -{ - if (z_is_clflush_available()) { - sys_cache_flush = _cache_flush_clflush; - } else { - sys_cache_flush = z_cache_flush_wbinvd; - } -} -#else -#define init_cache_flush() do { } while (false) - -#if defined(CONFIG_CLFLUSH_INSTRUCTION_SUPPORTED) -FUNC_ALIAS(_cache_flush_clflush, sys_cache_flush, void); -#endif - -#endif /* CONFIG_CLFLUSH_DETECT */ - - #if defined(CONFIG_CACHE_LINE_SIZE_DETECT) -size_t sys_cache_line_size; static void init_cache_line_size(void) { sys_cache_line_size = z_cache_line_size_get(); } +#endif + +size_t arch_cache_line_size_get(void) +{ +#if defined(CONFIG_CACHE_LINE_SIZE_DETECT) + return sys_cache_line_size; #else -#define init_cache_line_size() do { } while ((0)) + return 0; #endif +} -static int init_cache(struct device *unused) +static int init_cache(const struct device *unused) { ARG_UNUSED(unused); - init_cache_flush(); - init_cache_line_size(); - +#if defined(CONFIG_CACHE_LINE_SIZE_DETECT) + init_cache_line_size(); +#endif return 0; } diff --git a/arch/x86/core/ia32/coredump.c b/arch/x86/core/ia32/coredump.c new file mode 100644 index 00000000000000..bc60ce020f4f64 --- /dev/null +++ b/arch/x86/core/ia32/coredump.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define ARCH_HDR_VER 1 + +struct x86_arch_block { + uint32_t vector; + uint32_t code; + + struct { + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t eip; + uint32_t eflags; + uint32_t cs; + } r; +} __packed; + +/* + * This might be too large for stack space if defined + * inside function. So do it here. + */ +static struct x86_arch_block arch_blk; + +void arch_coredump_info_dump(const z_arch_esf_t *esf) +{ + struct z_coredump_arch_hdr_t hdr = { + .id = Z_COREDUMP_ARCH_HDR_ID, + .hdr_version = ARCH_HDR_VER, + .num_bytes = sizeof(arch_blk), + }; + + /* Nothing to process */ + if (esf == NULL) { + return; + } + + (void)memset(&arch_blk, 0, sizeof(arch_blk)); + + arch_blk.vector = z_x86_exception_vector; + arch_blk.code = esf->errorCode; + + /* + * 16 registers expected by GDB. + * Not all are in ESF but the GDB stub + * will need to send all 16 as one packet. + * The stub will need to send undefined + * for registers not presented in coredump. + */ + arch_blk.r.eax = esf->eax; + arch_blk.r.ebx = esf->ebx; + arch_blk.r.ecx = esf->ecx; + arch_blk.r.edx = esf->edx; + arch_blk.r.esp = esf->esp; + arch_blk.r.ebp = esf->ebp; + arch_blk.r.esi = esf->esi; + arch_blk.r.edi = esf->edi; + arch_blk.r.eip = esf->eip; + arch_blk.r.eflags = esf->eflags; + arch_blk.r.cs = esf->cs & 0xFFFFU; + + /* Send for output */ + z_coredump_buffer_output((uint8_t *)&hdr, sizeof(hdr)); + z_coredump_buffer_output((uint8_t *)&arch_blk, sizeof(arch_blk)); +} + +uint16_t arch_coredump_tgt_code_get(void) +{ + return COREDUMP_TGT_X86; +} diff --git a/arch/x86/core/ia32/crt0.S b/arch/x86/core/ia32/crt0.S index ac1b43126feacb..ed924d0ee9fe5a 100644 --- a/arch/x86/core/ia32/crt0.S +++ b/arch/x86/core/ia32/crt0.S @@ -37,8 +37,8 @@ GDATA(_sse_mxcsr_default_value) #endif -#ifdef CONFIG_SYS_POWER_DEEP_SLEEP_STATES - GTEXT(_sys_resume_from_deep_sleep) +#ifdef CONFIG_PM_DEEP_SLEEP_STATES + GTEXT(pm_system_resume_from_deep_sleep) #endif SECTION_FUNC(TEXT_START, __start) @@ -64,11 +64,7 @@ SECTION_FUNC(TEXT_START, __start) */ #if CONFIG_SET_GDT lgdt _gdt_rom /* load 32-bit operand size GDT */ -#endif - - -#ifdef CONFIG_SET_GDT /* If we set our own GDT, update the segment registers as well. */ movw $DATA_SEG, %ax /* data segment selector (entry = 3) */ @@ -84,7 +80,6 @@ SECTION_FUNC(TEXT_START, __start) __csSet: #endif /* CONFIG_SET_GDT */ - #if !defined(CONFIG_FPU) /* * Force an #NM exception for floating point instructions @@ -139,13 +134,13 @@ __csSet: * the ISR stack size are some multiple of ARCH_STACK_PTR_ALIGN, which * is at least 4. * - * This is also used to call the _sys_resume_from_deep_sleep() + * This is also used to call the pm_system_resume_from_deep_sleep() * routine to avoid memory corruption if the system is resuming from - * deep sleep. It is important that _sys_resume_from_deep_sleep() + * deep sleep. It is important that pm_system_resume_from_deep_sleep() * restores the stack pointer to what it was at deep sleep before * enabling interrupts. This is necessary to avoid * interfering with interrupt handler use of this stack. - * If it is a cold boot then _sys_resume_from_deep_sleep() should + * If it is a cold boot then pm_system_resume_from_deep_sleep() should * not do anything and must return immediately. */ #ifdef CONFIG_INIT_STACKS @@ -168,10 +163,10 @@ __csSet: #else addl $CONFIG_ISR_STACK_SIZE, %esp #endif -#if defined(CONFIG_SYS_POWER_DEEP_SLEEP_STATES) && \ +#if defined(CONFIG_PM_DEEP_SLEEP_STATES) && \ !defined(CONFIG_BOOTLOADER_CONTEXT_RESTORE) /* - * Invoke _sys_resume_from_deep_sleep() hook to handle resume from + * Invoke pm_system_resume_from_deep_sleep() hook to handle resume from * deep sleep. It should first check whether system is recovering from * deep sleep state. If it is, then this function should restore * states and resume at the point system went to deep sleep. @@ -182,7 +177,7 @@ __csSet: * return and execution falls through to cold boot path. */ - call _sys_resume_from_deep_sleep + call pm_system_resume_from_deep_sleep #endif @@ -205,7 +200,6 @@ __csSet: call _x86_data_copy #endif /* CONFIG_USERSPACE */ - #endif /* CONFIG_XIP */ /* @@ -235,6 +229,30 @@ __csSet: #endif lidt z_x86_idt /* load 32-bit operand size IDT */ +#ifdef CONFIG_X86_MMU + /* Install page tables */ + movl $z_x86_kernel_ptables, %eax + movl %eax, %cr3 + +#ifdef CONFIG_X86_PAE + /* Enable PAE */ + movl %cr4, %eax + orl $CR4_PAE, %eax + movl %eax, %cr4 + + /* IA32_EFER NXE bit set */ + movl $0xC0000080, %ecx + rdmsr + orl $0x800, %eax + wrmsr +#endif /* CONFIG_X86_PAE */ + + /* Enable paging (CR0.PG, bit 31) / write protect (CR0.WP, bit 16) */ + movl %cr0, %eax + orl $(CR0_PG | CR0_WP), %eax + movl %eax, %cr0 +#endif /* CONFIG_X86_MMU */ + #ifdef CONFIG_LOAPIC /* For BSP, cpu_number is 0 */ xorl %eax, %eax @@ -308,30 +326,6 @@ dataWords: ret #endif /* CONFIG_XIP */ -#ifdef CONFIG_X86_MMU -z_x86_enable_paging: - /* load the page directory address into the registers*/ - movl $z_x86_kernel_ptables, %eax - movl %eax, %cr3 - - /* Enable PAE */ - movl %cr4, %eax - orl $CR4_PAE, %eax - movl %eax, %cr4 - - /* IA32_EFER NXE bit set */ - movl $0xC0000080, %ecx - rdmsr - orl $0x800, %eax - wrmsr - - /* Enable paging (CR0.PG, bit 31) / write protect (CR0.WP, bit 16) */ - movl %cr0, %eax - orl $(CR0_PG | CR0_WP), %eax - movl %eax, %cr0 - - ret -#endif /* CONFIG_X86_MMU */ #if defined(CONFIG_SSE) diff --git a/arch/x86/core/ia32/excstub.S b/arch/x86/core/ia32/excstub.S index 16cec0fa48b164..891c55e3807c57 100644 --- a/arch/x86/core/ia32/excstub.S +++ b/arch/x86/core/ia32/excstub.S @@ -49,7 +49,7 @@ * * C function prototype: * - * void _exception_enter(u32_t error_code, void *handler) + * void _exception_enter(uint32_t error_code, void *handler) * */ @@ -121,6 +121,14 @@ SECTION_FUNC(TEXT, _exception_enter) pushl %eax /* Save calculated ESP */ #ifdef CONFIG_USERSPACE 2: +#endif + +#ifdef CONFIG_GDBSTUB + pushl %ds + pushl %es + pushl %fs + pushl %gs + pushl %ss #endif /* ESP is pointing to the ESF at this point */ @@ -196,6 +204,13 @@ allDone: nestedException: #endif /* CONFIG_LAZY_FPU_SHARING */ +#ifdef CONFIG_GDBSTUB + popl %ss + popl %gs + popl %fs + popl %es + popl %ds +#endif /* * Pop the non-volatile registers from the stack. * Note that debug tools may have altered the saved register values while diff --git a/arch/x86/core/ia32/fatal.c b/arch/x86/core/ia32/fatal.c index 1c7d1c80122c87..2f781de574deee 100644 --- a/arch/x86/core/ia32/fatal.c +++ b/arch/x86/core/ia32/fatal.c @@ -18,7 +18,14 @@ #include #include #include -LOG_MODULE_DECLARE(os); +#include +#include + +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); + +#ifdef CONFIG_DEBUG_COREDUMP +unsigned int z_x86_exception_vector; +#endif __weak void z_debug_fatal_hook(const z_arch_esf_t *esf) { ARG_UNUSED(esf); } @@ -58,51 +65,55 @@ NANO_CPU_INT_REGISTER(_kernel_oops_handler, NANO_SOFT_IRQ, FUNC_NORETURN static void generic_exc_handle(unsigned int vector, const z_arch_esf_t *pEsf) { +#ifdef CONFIG_DEBUG_COREDUMP + z_x86_exception_vector = vector; +#endif + z_x86_unhandled_cpu_exception(vector, pEsf); } #define _EXC_FUNC(vector) \ -FUNC_NORETURN void handle_exc_##vector(const z_arch_esf_t *pEsf) \ +FUNC_NORETURN __used static void handle_exc_##vector(const z_arch_esf_t *pEsf) \ { \ generic_exc_handle(vector, pEsf); \ } -#define Z_EXC_FUNC_CODE(vector) \ +#define Z_EXC_FUNC_CODE(vector, dpl) \ _EXC_FUNC(vector) \ - _EXCEPTION_CONNECT_CODE(handle_exc_##vector, vector) + _EXCEPTION_CONNECT_CODE(handle_exc_##vector, vector, dpl) -#define Z_EXC_FUNC_NOCODE(vector) \ +#define Z_EXC_FUNC_NOCODE(vector, dpl) \ _EXC_FUNC(vector) \ - _EXCEPTION_CONNECT_NOCODE(handle_exc_##vector, vector) + _EXCEPTION_CONNECT_NOCODE(handle_exc_##vector, vector, dpl) /* Necessary indirection to ensure 'vector' is expanded before we expand * the handle_exc_##vector */ -#define EXC_FUNC_NOCODE(vector) \ - Z_EXC_FUNC_NOCODE(vector) - -#define EXC_FUNC_CODE(vector) \ - Z_EXC_FUNC_CODE(vector) - -EXC_FUNC_NOCODE(IV_DIVIDE_ERROR); -EXC_FUNC_NOCODE(IV_NON_MASKABLE_INTERRUPT); -EXC_FUNC_NOCODE(IV_OVERFLOW); -EXC_FUNC_NOCODE(IV_BOUND_RANGE); -EXC_FUNC_NOCODE(IV_INVALID_OPCODE); -EXC_FUNC_NOCODE(IV_DEVICE_NOT_AVAILABLE); +#define EXC_FUNC_NOCODE(vector, dpl) \ + Z_EXC_FUNC_NOCODE(vector, dpl) + +#define EXC_FUNC_CODE(vector, dpl) \ + Z_EXC_FUNC_CODE(vector, dpl) + +EXC_FUNC_NOCODE(IV_DIVIDE_ERROR, 0); +EXC_FUNC_NOCODE(IV_NON_MASKABLE_INTERRUPT, 0); +EXC_FUNC_NOCODE(IV_OVERFLOW, 0); +EXC_FUNC_NOCODE(IV_BOUND_RANGE, 0); +EXC_FUNC_NOCODE(IV_INVALID_OPCODE, 0); +EXC_FUNC_NOCODE(IV_DEVICE_NOT_AVAILABLE, 0); #ifndef CONFIG_X86_ENABLE_TSS -EXC_FUNC_NOCODE(IV_DOUBLE_FAULT); +EXC_FUNC_NOCODE(IV_DOUBLE_FAULT, 0); #endif -EXC_FUNC_CODE(IV_INVALID_TSS); -EXC_FUNC_CODE(IV_SEGMENT_NOT_PRESENT); -EXC_FUNC_CODE(IV_STACK_FAULT); -EXC_FUNC_CODE(IV_GENERAL_PROTECTION); -EXC_FUNC_NOCODE(IV_X87_FPU_FP_ERROR); -EXC_FUNC_CODE(IV_ALIGNMENT_CHECK); -EXC_FUNC_NOCODE(IV_MACHINE_CHECK); +EXC_FUNC_CODE(IV_INVALID_TSS, 0); +EXC_FUNC_CODE(IV_SEGMENT_NOT_PRESENT, 0); +EXC_FUNC_CODE(IV_STACK_FAULT, 0); +EXC_FUNC_CODE(IV_GENERAL_PROTECTION, 0); +EXC_FUNC_NOCODE(IV_X87_FPU_FP_ERROR, 0); +EXC_FUNC_CODE(IV_ALIGNMENT_CHECK, 0); +EXC_FUNC_NOCODE(IV_MACHINE_CHECK, 0); #endif -_EXCEPTION_CONNECT_CODE(z_x86_page_fault_handler, IV_PAGE_FAULT); +_EXCEPTION_CONNECT_CODE(z_x86_page_fault_handler, IV_PAGE_FAULT, 0); #ifdef CONFIG_X86_ENABLE_TSS static __noinit volatile z_arch_esf_t _df_esf; @@ -127,20 +138,20 @@ struct task_state_segment _main_tss = { * In a special kernel page that, unlike all other kernel pages, * is marked present in the user page table. */ - .esp0 = (u32_t)&z_trampoline_stack_end + .esp0 = (uint32_t)&z_trampoline_stack_end #endif }; /* Special TSS for handling double-faults with a known good stack */ Z_GENERIC_SECTION(.tss) struct task_state_segment _df_tss = { - .esp = (u32_t)(_df_stack + sizeof(_df_stack)), + .esp = (uint32_t)(_df_stack + sizeof(_df_stack)), .cs = CODE_SEG, .ds = DATA_SEG, .es = DATA_SEG, .ss = DATA_SEG, - .eip = (u32_t)df_handler_top, - .cr3 = (u32_t)&z_x86_kernel_ptables + .eip = (uint32_t)df_handler_top, + .cr3 = (uint32_t)&z_x86_kernel_ptables }; static __used void df_handler_bottom(void) @@ -149,8 +160,8 @@ static __used void df_handler_bottom(void) int reason = K_ERR_CPU_EXCEPTION; /* Restore the top half so it is runnable again */ - _df_tss.esp = (u32_t)(_df_stack + sizeof(_df_stack)); - _df_tss.eip = (u32_t)df_handler_top; + _df_tss.esp = (uint32_t)(_df_stack + sizeof(_df_stack)); + _df_tss.eip = (uint32_t)df_handler_top; LOG_ERR("Double Fault"); #ifdef CONFIG_THREAD_STACK_INFO @@ -181,14 +192,14 @@ static FUNC_NORETURN __used void df_handler_top(void) _df_esf.eflags = _main_tss.eflags; /* Restore the main IA task to a runnable state */ - _main_tss.esp = (u32_t)(ARCH_THREAD_STACK_BUFFER( + _main_tss.esp = (uint32_t)(Z_KERNEL_STACK_BUFFER( z_interrupt_stacks[0]) + CONFIG_ISR_STACK_SIZE); _main_tss.cs = CODE_SEG; _main_tss.ds = DATA_SEG; _main_tss.es = DATA_SEG; _main_tss.ss = DATA_SEG; - _main_tss.eip = (u32_t)df_handler_bottom; - _main_tss.cr3 = (u32_t)&z_x86_kernel_ptables; + _main_tss.eip = (uint32_t)df_handler_bottom; + _main_tss.cr3 = (uint32_t)(&z_x86_kernel_ptables); _main_tss.eflags = 0U; /* NT bit is set in EFLAGS so we will task switch back to _main_tss diff --git a/arch/x86/core/ia32/float.c b/arch/x86/core/ia32/float.c index b807ae6e8bb6bb..ea860aa70fc881 100644 --- a/arch/x86/core/ia32/float.c +++ b/arch/x86/core/ia32/float.c @@ -47,7 +47,7 @@ #include /* SSE control/status register default value (used by assembler code) */ -extern u32_t _sse_mxcsr_default_value; +extern uint32_t _sse_mxcsr_default_value; /** * @@ -190,7 +190,7 @@ void k_float_enable(struct k_thread *thread, unsigned int options) /* Indicate thread requires floating point context saving */ - thread->base.user_options |= (u8_t)options; + thread->base.user_options |= (uint8_t)options; /* * The current thread might not allow FP instructions, so clear CR0[TS] @@ -328,4 +328,5 @@ void _FpNotAvailableExcHandler(z_arch_esf_t *pEsf) k_float_enable(_current, _FP_USER_MASK); } -_EXCEPTION_CONNECT_NOCODE(_FpNotAvailableExcHandler, IV_DEVICE_NOT_AVAILABLE); +_EXCEPTION_CONNECT_NOCODE(_FpNotAvailableExcHandler, + IV_DEVICE_NOT_AVAILABLE, 0); diff --git a/arch/x86/core/ia32/gdbstub.c b/arch/x86/core/ia32/gdbstub.c new file mode 100644 index 00000000000000..bf1f08a4d8e5aa --- /dev/null +++ b/arch/x86/core/ia32/gdbstub.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + + +static struct gdb_ctx ctx; +static bool start; + +/** + * Currently we just handle vectors 1 and 3 but lets keep it generic + * to be able to notify other exceptions in the future + */ +static unsigned int get_exception(unsigned int vector) +{ + unsigned int exception; + + switch (vector) { + case IV_DIVIDE_ERROR: + exception = GDB_EXCEPTION_DIVIDE_ERROR; + break; + case IV_DEBUG: + exception = GDB_EXCEPTION_BREAKPOINT; + break; + case IV_BREAKPOINT: + exception = GDB_EXCEPTION_BREAKPOINT; + break; + case IV_OVERFLOW: + exception = GDB_EXCEPTION_OVERFLOW; + break; + case IV_BOUND_RANGE: + exception = GDB_EXCEPTION_OVERFLOW; + break; + case IV_INVALID_OPCODE: + exception = GDB_EXCEPTION_INVALID_INSTRUCTION; + break; + case IV_DEVICE_NOT_AVAILABLE: + exception = GDB_EXCEPTION_DIVIDE_ERROR; + break; + case IV_DOUBLE_FAULT: + exception = GDB_EXCEPTION_MEMORY_FAULT; + break; + case IV_COPROC_SEGMENT_OVERRUN: + exception = GDB_EXCEPTION_INVALID_MEMORY; + break; + case IV_INVALID_TSS: + exception = GDB_EXCEPTION_INVALID_MEMORY; + break; + case IV_SEGMENT_NOT_PRESENT: + exception = GDB_EXCEPTION_INVALID_MEMORY; + break; + case IV_STACK_FAULT: + exception = GDB_EXCEPTION_INVALID_MEMORY; + break; + case IV_GENERAL_PROTECTION: + exception = GDB_EXCEPTION_INVALID_MEMORY; + break; + case IV_PAGE_FAULT: + exception = GDB_EXCEPTION_INVALID_MEMORY; + break; + case IV_X87_FPU_FP_ERROR: + exception = GDB_EXCEPTION_MEMORY_FAULT; + break; + default: + exception = GDB_EXCEPTION_MEMORY_FAULT; + break; + } + + return exception; +} + +/* + * Debug exception handler. + */ +static void z_gdb_interrupt(unsigned int vector, z_arch_esf_t *esf) +{ + ctx.exception = get_exception(vector); + + ctx.registers[GDB_EAX] = esf->eax; + ctx.registers[GDB_ECX] = esf->ecx; + ctx.registers[GDB_EDX] = esf->edx; + ctx.registers[GDB_EBX] = esf->ebx; + ctx.registers[GDB_ESP] = esf->esp; + ctx.registers[GDB_EBP] = esf->ebp; + ctx.registers[GDB_ESI] = esf->esi; + ctx.registers[GDB_EDI] = esf->edi; + ctx.registers[GDB_PC] = esf->eip; + ctx.registers[GDB_CS] = esf->cs; + ctx.registers[GDB_EFLAGS] = esf->eflags; + ctx.registers[GDB_SS] = esf->ss; + ctx.registers[GDB_DS] = esf->ds; + ctx.registers[GDB_ES] = esf->es; + ctx.registers[GDB_FS] = esf->fs; + ctx.registers[GDB_GS] = esf->gs; + + z_gdb_main_loop(&ctx, start); + start = false; + + esf->eax = ctx.registers[GDB_EAX]; + esf->ecx = ctx.registers[GDB_ECX]; + esf->edx = ctx.registers[GDB_EDX]; + esf->ebx = ctx.registers[GDB_EBX]; + esf->esp = ctx.registers[GDB_ESP]; + esf->ebp = ctx.registers[GDB_EBP]; + esf->esi = ctx.registers[GDB_ESI]; + esf->edi = ctx.registers[GDB_EDI]; + esf->eip = ctx.registers[GDB_PC]; + esf->cs = ctx.registers[GDB_CS]; + esf->eflags = ctx.registers[GDB_EFLAGS]; + esf->ss = ctx.registers[GDB_SS]; + esf->ds = ctx.registers[GDB_DS]; + esf->es = ctx.registers[GDB_ES]; + esf->fs = ctx.registers[GDB_FS]; + esf->gs = ctx.registers[GDB_GS]; +} + +void arch_gdb_continue(void) +{ + /* Clear the TRAP FLAG bit */ + ctx.registers[GDB_EFLAGS] &= ~BIT(8); +} + +void arch_gdb_step(void) +{ + /* Set the TRAP FLAG bit */ + ctx.registers[GDB_EFLAGS] |= BIT(8); +} + +static __used void z_gdb_debug_isr(z_arch_esf_t *esf) +{ + z_gdb_interrupt(IV_DEBUG, esf); +} + +static __used void z_gdb_break_isr(z_arch_esf_t *esf) +{ + z_gdb_interrupt(IV_BREAKPOINT, esf); +} + +void arch_gdb_init(void) +{ + start = true; + __asm__ volatile ("int3"); +} + +/* Hook current IDT. */ +_EXCEPTION_CONNECT_NOCODE(z_gdb_debug_isr, IV_DEBUG, 3); +_EXCEPTION_CONNECT_NOCODE(z_gdb_break_isr, IV_BREAKPOINT, 3); diff --git a/arch/x86/core/ia32/intstub.S b/arch/x86/core/ia32/intstub.S index f0e016a3e24342..3e8d32908fa818 100644 --- a/arch/x86/core/ia32/intstub.S +++ b/arch/x86/core/ia32/intstub.S @@ -31,11 +31,10 @@ GTEXT(arch_swap) -#ifdef CONFIG_SYS_POWER_MANAGEMENT - GTEXT(z_sys_power_save_idle_exit) +#ifdef CONFIG_PM + GTEXT(z_pm_save_idle_exit) #endif - /** * * @brief Inform the kernel of an interrupt @@ -79,15 +78,6 @@ SECTION_FUNC(TEXT, _interrupt_enter) * 0 isr <-- stack pointer */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - pushl %eax - pushl %edx - rdtsc - mov %eax, arch_timing_irq_start - mov %edx, arch_timing_irq_start+4 - pop %edx - pop %eax -#endif /* * The gen_idt tool creates an interrupt-gate descriptor for * all connections. The processor will automatically clear the IF @@ -129,19 +119,6 @@ SECTION_FUNC(TEXT, _interrupt_enter) */ pushl %edi - -#if defined(CONFIG_TRACING_ISR) - - /* Save these as we are using to keep track of isr and isr_param */ - pushl %eax - pushl %edx - - call sys_trace_isr_enter - - popl %edx - popl %eax -#endif - /* load %ecx with &_kernel */ movl $_kernel, %ecx @@ -167,11 +144,11 @@ SECTION_FUNC(TEXT, _interrupt_enter) pushl %edi /* Save stack pointer */ -#ifdef CONFIG_SYS_POWER_MANAGEMENT +#ifdef CONFIG_PM cmpl $0, _kernel_offset_to_idle(%ecx) jne handle_idle /* fast path is !idle, in the pipeline */ -#endif /* CONFIG_SYS_POWER_MANAGEMENT */ +#endif /* CONFIG_PM */ /* fall through to nested case */ @@ -179,17 +156,13 @@ alreadyOnIntStack: push %eax /* interrupt handler argument */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - /* Save the eax and edx registers before reading the time stamp - * once done pop the values - */ - pushl %eax - pushl %edx - rdtsc - mov %eax,arch_timing_irq_end - mov %edx,arch_timing_irq_end+4 - pop %edx - pop %eax +#if defined(CONFIG_TRACING_ISR) + /* Save these as we are using to keep track of isr and isr_param */ + pushl %eax + pushl %edx + call sys_trace_isr_enter + popl %edx + popl %eax #endif #ifdef CONFIG_NESTED_INTERRUPTS @@ -203,21 +176,31 @@ alreadyOnIntStack: cli /* disable interrupts again */ #endif +#if defined(CONFIG_TRACING_ISR) + pushl %eax + call sys_trace_isr_exit + popl %eax +#endif + xorl %eax, %eax #if defined(CONFIG_X2APIC) xorl %edx, %edx movl $(X86_X2APIC_BASE_MSR + (LOAPIC_EOI >> 4)), %ecx wrmsr #else /* xAPIC */ +#ifdef DEVICE_MMIO_IS_IN_RAM + movl z_loapic_regs, %edx + movl %eax, LOAPIC_EOI(%edx) +#else movl %eax, (CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI) -#endif +#endif /* DEVICE_MMIO_IS_IN_RAM */ +#endif /* CONFIG_X2APIC */ /* determine whether exiting from a nested interrupt */ movl $_kernel, %ecx decl _kernel_offset_to_nested(%ecx) /* dec interrupt nest count */ jne nestedInterrupt /* 'iret' if nested case */ - #ifdef CONFIG_PREEMPT_ENABLED movl _kernel_offset_to_current(%ecx), %edx @@ -314,29 +297,29 @@ nestedInterrupt: KPTI_IRET -#ifdef CONFIG_SYS_POWER_MANAGEMENT +#ifdef CONFIG_PM handle_idle: pushl %eax pushl %edx - /* Populate 'ticks' argument to z_sys_power_save_idle_exit */ + /* Populate 'ticks' argument to z_pm_save_idle_exit */ push _kernel_offset_to_idle(%ecx) /* Zero out _kernel.idle */ movl $0, _kernel_offset_to_idle(%ecx) /* - * Beware that a timer driver's z_sys_power_save_idle_exit() implementation might + * Beware that a timer driver's z_pm_save_idle_exit() implementation might * expect that interrupts are disabled when invoked. This ensures that * the calculation and programming of the device for the next timer * deadline is not interrupted. */ - call z_sys_power_save_idle_exit + call z_pm_save_idle_exit /* discard 'ticks' argument passed on the stack */ add $0x4, %esp popl %edx popl %eax jmp alreadyOnIntStack -#endif /* CONFIG_SYS_POWER_MANAGEMENT */ +#endif /* CONFIG_PM */ /** * diff --git a/arch/x86/core/ia32/irq_manage.c b/arch/x86/core/ia32/irq_manage.c index 25a87a10eb36dd..8fc4035abeb169 100644 --- a/arch/x86/core/ia32/irq_manage.c +++ b/arch/x86/core/ia32/irq_manage.c @@ -56,9 +56,9 @@ extern unsigned int z_interrupt_vectors_allocated[]; struct dyn_irq_info { /** IRQ handler */ - void (*handler)(void *param); + void (*handler)(const void *param); /** Parameter to pass to the handler */ - void *param; + const void *param; }; /* @@ -169,7 +169,7 @@ static unsigned int priority_to_free_vector(unsigned int requested_priority) */ static void *get_dynamic_stub(int stub_idx) { - u32_t offset; + uint32_t offset; /* * Because we want the sizes of the stubs to be consistent and minimized, @@ -181,7 +181,7 @@ static void *get_dynamic_stub(int stub_idx) ((stub_idx / Z_DYN_STUB_PER_BLOCK) * Z_DYN_STUB_LONG_JMP_EXTRA_SIZE); - return (void *)((u32_t)&z_dynamic_stubs_begin + offset); + return (void *)((uint32_t)&z_dynamic_stubs_begin + offset); } extern const struct pseudo_descriptor z_x86_idt; @@ -192,13 +192,13 @@ static void idt_vector_install(int vector, void *irq_handler) key = irq_lock(); z_init_irq_gate(&z_x86_idt.entries[vector], CODE_SEG, - (u32_t)irq_handler, 0); + (uint32_t)irq_handler, 0); irq_unlock(key); } int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *parameter), void *parameter, - u32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { int vector, stub_idx, key; @@ -233,7 +233,7 @@ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, * * @param stub_idx Index into the dyn_irq_list array */ -void z_x86_dynamic_irq_handler(u8_t stub_idx) +void z_x86_dynamic_irq_handler(uint8_t stub_idx) { dyn_irq_list[stub_idx].handler(dyn_irq_list[stub_idx].param); } diff --git a/arch/x86/core/ia32/irq_offload.c b/arch/x86/core/ia32/irq_offload.c index c6a26b349300e7..121df49e4b1457 100644 --- a/arch/x86/core/ia32/irq_offload.c +++ b/arch/x86/core/ia32/irq_offload.c @@ -17,7 +17,7 @@ NANO_CPU_INT_REGISTER(_irq_sw_handler, NANO_SOFT_IRQ, CONFIG_IRQ_OFFLOAD_VECTOR, 0); static irq_offload_routine_t offload_routine; -static void *offload_param; +static const void *offload_param; /* Called by asm stub */ void z_irq_do_offload(void) @@ -25,7 +25,7 @@ void z_irq_do_offload(void) offload_routine(offload_param); } -void arch_irq_offload(irq_offload_routine_t routine, void *parameter) +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { unsigned int key; diff --git a/arch/x86/core/ia32/swap.S b/arch/x86/core/ia32/swap.S index a3888e8ae4476d..1fb132ab45db91 100644 --- a/arch/x86/core/ia32/swap.S +++ b/arch/x86/core/ia32/swap.S @@ -65,27 +65,11 @@ * unsigned int arch_swap (unsigned int eflags); */ -.macro read_tsc var_name - push %eax - push %edx - rdtsc - mov %eax,\var_name - mov %edx,\var_name+4 - pop %edx - pop %eax -.endm SECTION_FUNC(TEXT, arch_swap) -#ifdef CONFIG_EXECUTION_BENCHMARKING - /* Save the eax and edx registers before reading the time stamp - * once done pop the values. - */ - push %eax - push %edx - rdtsc - mov %eax,arch_timing_swap_start - mov %edx,arch_timing_swap_start+4 - pop %edx - pop %eax +#if defined(CONFIG_INSTRUMENT_THREAD_SWITCHING) + pushl %eax + call z_thread_mark_switched_out + popl %eax #endif /* * Push all non-volatile registers onto the stack; do not copy @@ -116,13 +100,6 @@ SECTION_FUNC(TEXT, arch_swap) movl _kernel_offset_to_current(%edi), %edx movl %esp, _thread_offset_to_esp(%edx) - -#ifdef CONFIG_TRACING - /* Register the context switch */ - push %edx - call sys_trace_thread_switched_in - pop %edx -#endif movl _kernel_offset_to_ready_q_cache(%edi), %eax /* @@ -326,6 +303,18 @@ CROHandlingDone: movl %eax, _kernel_offset_to_current(%edi) +#if defined(CONFIG_X86_USE_THREAD_LOCAL_STORAGE) + pushl %eax + + call z_x86_tls_update_gdt + + /* Since segment descriptor has changed, need to reload */ + movw $GS_TLS_SEG, %ax + movw %ax, %gs + + popl %eax +#endif + /* recover thread stack pointer from k_thread */ movl _thread_offset_to_esp(%eax), %esp @@ -355,14 +344,10 @@ CROHandlingDone: pushl 4(%esp) popfl -#ifdef CONFIG_EXECUTION_BENCHMARKING - cmp $0x1,arch_timing_value_swap_end - jne time_read_not_needed - movw $0x2,arch_timing_value_swap_end - read_tsc arch_timing_value_swap_common - pushl arch_timing_swap_start - popl arch_timing_value_swap_temp -time_read_not_needed: +#if defined(CONFIG_INSTRUMENT_THREAD_SWITCHING) + pushl %eax + call z_thread_mark_switched_in + popl %eax #endif ret diff --git a/arch/x86/core/ia32/thread.c b/arch/x86/core/ia32/thread.c index 409c8b13c395eb..7d579f527ab834 100644 --- a/arch/x86/core/ia32/thread.c +++ b/arch/x86/core/ia32/thread.c @@ -16,6 +16,7 @@ #include #include #include +#include /* forward declaration */ @@ -23,13 +24,13 @@ * for when z_swap() switches to it for the first time. */ struct _x86_initial_frame { - u32_t swap_retval; - u32_t ebp; - u32_t ebx; - u32_t esi; - u32_t edi; + uint32_t swap_retval; + uint32_t ebp; + uint32_t ebx; + uint32_t esi; + uint32_t edi; void *thread_entry; - u32_t eflags; + uint32_t eflags; k_thread_entry_t entry; void *p1; void *p2; @@ -61,26 +62,14 @@ int arch_float_disable(struct k_thread *thread) #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - size_t stack_size, k_thread_entry_t entry, - void *parameter1, void *parameter2, void *parameter3, - int priority, unsigned int options) + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) { - char *stack_buf; - char *stack_high; void *swap_entry; struct _x86_initial_frame *initial_frame; - stack_buf = Z_THREAD_STACK_BUFFER(stack); - z_new_thread_init(thread, stack_buf, stack_size); - #if CONFIG_X86_STACK_PROTECTION - struct z_x86_thread_stack_header *header = - (struct z_x86_thread_stack_header *)stack; - - /* Set guard area to read-only to catch stack overflows */ - z_x86_mmu_set_flags(&z_x86_kernel_ptables, &header->guard_page, - MMU_PAGE_SIZE, MMU_ENTRY_READ, Z_X86_MMU_RW, - true); + z_x86_set_stack_guard(stack); #endif #ifdef CONFIG_USERSPACE @@ -89,19 +78,18 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, swap_entry = z_thread_entry; #endif - stack_high = (char *)Z_STACK_PTR_ALIGN(stack_buf + stack_size); - /* Create an initial context on the stack expected by z_swap() */ - initial_frame = (struct _x86_initial_frame *) - (stack_high - sizeof(struct _x86_initial_frame)); + initial_frame = Z_STACK_PTR_TO_FRAME(struct _x86_initial_frame, + stack_ptr); + /* z_thread_entry() arguments */ initial_frame->entry = entry; - initial_frame->p1 = parameter1; - initial_frame->p2 = parameter2; - initial_frame->p3 = parameter3; + initial_frame->p1 = p1; + initial_frame->p2 = p2; + initial_frame->p3 = p3; initial_frame->eflags = EFLAGS_INITIAL; #ifdef _THREAD_WRAPPER_REQUIRED - initial_frame->edi = (u32_t)swap_entry; + initial_frame->edi = (uint32_t)swap_entry; initial_frame->thread_entry = z_x86_thread_entry_wrapper; #else initial_frame->thread_entry = swap_entry; @@ -124,13 +112,11 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, * Use some sufficiently aligned bytes in the lower memory of the interrupt * stack instead, otherwise the logic is more or less the same. */ -void arch_switch_to_main_thread(struct k_thread *main_thread, - k_thread_stack_t *main_stack, - size_t main_stack_size, +void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, k_thread_entry_t _main) { struct k_thread *dummy_thread = (struct k_thread *) - ROUND_UP(Z_THREAD_STACK_BUFFER(z_interrupt_stacks[0]), + ROUND_UP(Z_KERNEL_STACK_BUFFER(z_interrupt_stacks[0]), FP_REG_SET_ALIGN); __ASSERT(((uintptr_t)(&dummy_thread->arch.preempFloatReg) % diff --git a/arch/x86/core/ia32/tls.c b/arch/x86/core/ia32/tls.c new file mode 100644 index 00000000000000..3cb2361acbf54c --- /dev/null +++ b/arch/x86/core/ia32/tls.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define ENTRY_NUM (GS_TLS_SEG >> 3) + +void z_x86_tls_update_gdt(struct k_thread *thread) +{ + /* + * GS is used for thread local storage to pointer to + * the TLS storage area in stack. Here we update one + * of the descriptor so GS has the new address. + * + * The re-loading of descriptor into GS is taken care + * of inside the assembly swap code just before + * swapping into the new thread. + */ + + struct segment_descriptor *sd = &_gdt.entries[ENTRY_NUM]; + + sd->base_low = thread->tls & 0xFFFFU; + sd->base_mid = (thread->tls >> 16) & 0xFFU; + sd->base_hi = (thread->tls >> 24) & 0xFFU; +} diff --git a/arch/x86/core/ia32/userspace.S b/arch/x86/core/ia32/userspace.S index 05d43d6878814c..7c1277446c07f9 100644 --- a/arch/x86/core/ia32/userspace.S +++ b/arch/x86/core/ia32/userspace.S @@ -8,6 +8,7 @@ #include #include #include +#include /* Exports */ GTEXT(z_x86_syscall_entry_stub) @@ -279,8 +280,8 @@ z_x86_user_string_nlen_fixup: /* FUNC_NORETURN void z_x86_userspace_enter(k_thread_entry_t user_entry, * void *p1, void *p2, void *p3, - * u32_t stack_end, - * u32_t stack_start) + * uint32_t stack_end, + * uint32_t stack_start) * * A one-way trip to userspace. */ @@ -304,39 +305,18 @@ SECTION_FUNC(TEXT, z_x86_userspace_enter) * want to leak any information. */ mov %edi, %esp - subl $Z_X86_PDPT_SIZE, %esp - /* Stash some registers we are going to need to erase the user - * stack. - */ + /* Erase and enable US bit in page tables for the stack buffer */ push %ecx - push %edi push %eax - - /* Compute size of user stack in 4-byte chunks and put in ECX */ - mov %ebx, %ecx - sub %edi, %ecx - shr $2, %ecx /* Divide by 4 */ - -#ifdef CONFIG_INIT_STACKS - mov $0xAAAAAAAA, %eax -#else - xor %eax, %eax -#endif - /* Copy 4 bytes of memory at a time, starting at ES:EDI, with whatever - * is in EAX. Repeat this ECX times. Stack sizes are always at least - * 4-byte aligned. - */ - cld - rep stosl - - /* Restore registers */ + push %edx + call z_x86_current_stack_perms + pop %edx pop %eax - pop %edi pop %ecx - /* Now set stack pointer to the base of the user stack. Now that this - * is set we won't need EBX any more. + /* Set stack pointer to the base of the freshly-erased user stack. + * Now that this is set we won't need EBX any more. */ mov %ebx, %esp @@ -370,18 +350,5 @@ SECTION_FUNC(TEXT, z_x86_userspace_enter) push $USER_CODE_SEG /* CS */ push $z_thread_entry /* EIP */ -#ifdef CONFIG_EXECUTION_BENCHMARKING - /* Save the eax and edx registers before reading the time stamp - * once done pop the values. - */ - push %eax - push %edx - rdtsc - mov %eax,arch_timing_enter_user_mode_end - mov %edx,arch_timing_enter_user_mode_end+4 - pop %edx - pop %eax -#endif - /* We will land in z_thread_entry() in user mode after this */ KPTI_IRET_USER diff --git a/arch/x86/core/intel64.cmake b/arch/x86/core/intel64.cmake index 5fc04a49699e0b..a50a173268132d 100644 --- a/arch/x86/core/intel64.cmake +++ b/arch/x86/core/intel64.cmake @@ -17,3 +17,5 @@ zephyr_library_sources( ) zephyr_library_sources_ifdef(CONFIG_USERSPACE intel64/userspace.S) + +zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP intel64/coredump.c) diff --git a/arch/x86/core/intel64/coredump.c b/arch/x86/core/intel64/coredump.c new file mode 100644 index 00000000000000..42837792a80046 --- /dev/null +++ b/arch/x86/core/intel64/coredump.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define ARCH_HDR_VER 1 + +struct x86_64_arch_block { + uint64_t vector; + uint64_t code; + + struct { + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rsi; + uint64_t rdi; + uint64_t rsp; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t rip; + uint64_t eflags; + uint64_t cs; + uint64_t ss; + uint64_t rbp; + +#ifdef CONFIG_EXCEPTION_DEBUG + uint64_t rbx; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; +#endif + } r; +} __packed; + +/* + * Register block takes up too much stack space + * if defined within function. So define it here. + */ +static struct x86_64_arch_block arch_blk; + +void arch_coredump_info_dump(const z_arch_esf_t *esf) +{ + struct z_coredump_arch_hdr_t hdr = { + .id = Z_COREDUMP_ARCH_HDR_ID, + .hdr_version = ARCH_HDR_VER, + .num_bytes = sizeof(arch_blk), + }; + + /* Nothing to process */ + if (esf == NULL) { + return; + } + + (void)memset(&arch_blk, 0, sizeof(arch_blk)); + + arch_blk.vector = esf->vector; + arch_blk.code = esf->code; + + /* + * 34 registers expected by GDB. + * Not all are in ESF but the GDB stub + * will need to send all 34 as one packet. + * The stub will need to send undefined + * for registers not presented in coredump. + */ + arch_blk.r.rax = esf->rax; + arch_blk.r.rcx = esf->rcx; + arch_blk.r.rdx = esf->rdx; + arch_blk.r.rsi = esf->rsi; + arch_blk.r.rdi = esf->rdi; + arch_blk.r.rsp = esf->rsp; + arch_blk.r.rip = esf->rip; + arch_blk.r.r8 = esf->r8; + arch_blk.r.r9 = esf->r9; + arch_blk.r.r10 = esf->r10; + arch_blk.r.r11 = esf->r11; + + arch_blk.r.eflags = esf->rflags; + arch_blk.r.cs = esf->cs & 0xFFFFU; + arch_blk.r.ss = esf->ss; + + arch_blk.r.rbp = esf->rbp; + +#ifdef CONFIG_EXCEPTION_DEBUG + arch_blk.r.rbx = esf->rbx; + arch_blk.r.r12 = esf->r12; + arch_blk.r.r13 = esf->r13; + arch_blk.r.r14 = esf->r14; + arch_blk.r.r15 = esf->r15; +#endif + + /* Send for output */ + z_coredump_buffer_output((uint8_t *)&hdr, sizeof(hdr)); + z_coredump_buffer_output((uint8_t *)&arch_blk, sizeof(arch_blk)); +} + +uint16_t arch_coredump_tgt_code_get(void) +{ + return COREDUMP_TGT_X86_64; +} diff --git a/arch/x86/core/intel64/cpu.c b/arch/x86/core/intel64/cpu.c index b98a328bf27255..6df0735e52cf7c 100644 --- a/arch/x86/core/intel64/cpu.c +++ b/arch/x86/core/intel64/cpu.c @@ -9,8 +9,9 @@ #include #include #include -#include +#include #include +#include /* * Map of CPU logical IDs to CPU local APIC IDs. By default, @@ -18,28 +19,34 @@ * The symbol is weak so that boards/SoC files can override. */ -__weak u8_t x86_cpu_loapics[] = { 0, 1, 2, 3 }; +__weak uint8_t x86_cpu_loapics[] = { 0, 1, 2, 3 }; extern char x86_ap_start[]; /* AP entry point in locore.S */ -extern u8_t _exception_stack[]; -extern u8_t _exception_stack1[]; -extern u8_t _exception_stack2[]; -extern u8_t _exception_stack3[]; +extern uint8_t z_x86_exception_stack[]; +extern uint8_t z_x86_exception_stack1[]; +extern uint8_t z_x86_exception_stack2[]; +extern uint8_t z_x86_exception_stack3[]; + +extern uint8_t z_x86_nmi_stack[]; +extern uint8_t z_x86_nmi_stack1[]; +extern uint8_t z_x86_nmi_stack2[]; +extern uint8_t z_x86_nmi_stack3[]; #ifdef CONFIG_X86_KPTI -extern u8_t z_x86_trampoline_stack[]; -extern u8_t z_x86_trampoline_stack1[]; -extern u8_t z_x86_trampoline_stack2[]; -extern u8_t z_x86_trampoline_stack3[]; +extern uint8_t z_x86_trampoline_stack[]; +extern uint8_t z_x86_trampoline_stack1[]; +extern uint8_t z_x86_trampoline_stack2[]; +extern uint8_t z_x86_trampoline_stack3[]; #endif /* CONFIG_X86_KPTI */ Z_GENERIC_SECTION(.tss) struct x86_tss64 tss0 = { #ifdef CONFIG_X86_KPTI - .ist2 = (u64_t) z_x86_trampoline_stack + Z_X86_TRAMPOLINE_STACK_SIZE, + .ist2 = (uint64_t) z_x86_trampoline_stack + Z_X86_TRAMPOLINE_STACK_SIZE, #endif - .ist7 = (u64_t) _exception_stack + CONFIG_EXCEPTION_STACK_SIZE, + .ist6 = (uint64_t) z_x86_nmi_stack + CONFIG_X86_EXCEPTION_STACK_SIZE, + .ist7 = (uint64_t) z_x86_exception_stack + CONFIG_X86_EXCEPTION_STACK_SIZE, .iomapb = 0xFFFF, .cpu = &(_kernel.cpus[0]) }; @@ -48,9 +55,10 @@ struct x86_tss64 tss0 = { Z_GENERIC_SECTION(.tss) struct x86_tss64 tss1 = { #ifdef CONFIG_X86_KPTI - .ist2 = (u64_t) z_x86_trampoline_stack1 + Z_X86_TRAMPOLINE_STACK_SIZE, + .ist2 = (uint64_t) z_x86_trampoline_stack1 + Z_X86_TRAMPOLINE_STACK_SIZE, #endif - .ist7 = (u64_t) _exception_stack1 + CONFIG_EXCEPTION_STACK_SIZE, + .ist6 = (uint64_t) z_x86_nmi_stack1 + CONFIG_X86_EXCEPTION_STACK_SIZE, + .ist7 = (uint64_t) z_x86_exception_stack1 + CONFIG_X86_EXCEPTION_STACK_SIZE, .iomapb = 0xFFFF, .cpu = &(_kernel.cpus[1]) }; @@ -60,9 +68,10 @@ struct x86_tss64 tss1 = { Z_GENERIC_SECTION(.tss) struct x86_tss64 tss2 = { #ifdef CONFIG_X86_KPTI - .ist2 = (u64_t) z_x86_trampoline_stack2 + Z_X86_TRAMPOLINE_STACK_SIZE, + .ist2 = (uint64_t) z_x86_trampoline_stack2 + Z_X86_TRAMPOLINE_STACK_SIZE, #endif - .ist7 = (u64_t) _exception_stack2 + CONFIG_EXCEPTION_STACK_SIZE, + .ist6 = (uint64_t) z_x86_nmi_stack2 + CONFIG_X86_EXCEPTION_STACK_SIZE, + .ist7 = (uint64_t) z_x86_exception_stack2 + CONFIG_X86_EXCEPTION_STACK_SIZE, .iomapb = 0xFFFF, .cpu = &(_kernel.cpus[2]) }; @@ -72,26 +81,24 @@ struct x86_tss64 tss2 = { Z_GENERIC_SECTION(.tss) struct x86_tss64 tss3 = { #ifdef CONFIG_X86_KPTI - .ist2 = (u64_t) z_x86_trampoline_stack3 + Z_X86_TRAMPOLINE_STACK_SIZE, + .ist2 = (uint64_t) z_x86_trampoline_stack3 + Z_X86_TRAMPOLINE_STACK_SIZE, #endif - .ist7 = (u64_t) _exception_stack3 + CONFIG_EXCEPTION_STACK_SIZE, + .ist6 = (uint64_t) z_x86_nmi_stack3 + CONFIG_X86_EXCEPTION_STACK_SIZE, + .ist7 = (uint64_t) z_x86_exception_stack3 + CONFIG_X86_EXCEPTION_STACK_SIZE, .iomapb = 0xFFFF, .cpu = &(_kernel.cpus[3]) }; #endif -extern struct x86_page_tables z_x86_flat_ptables; - struct x86_cpuboot x86_cpuboot[] = { { .tr = X86_KERNEL_CPU0_TR, .gs_base = &tss0, - .sp = (u64_t) (z_interrupt_stacks[0] + CONFIG_ISR_STACK_SIZE + - ARCH_THREAD_STACK_RESERVED), + .sp = (uint64_t) z_interrupt_stacks[0] + + Z_KERNEL_STACK_SIZE_ADJUST(CONFIG_ISR_STACK_SIZE), + .stack_size = + Z_KERNEL_STACK_SIZE_ADJUST(CONFIG_ISR_STACK_SIZE), .fn = z_x86_prep_c, -#ifdef CONFIG_X86_MMU - .ptables = &z_x86_flat_ptables, -#endif }, #if CONFIG_MP_NUM_CPUS > 1 { @@ -121,15 +128,25 @@ struct x86_cpuboot x86_cpuboot[] = { void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, arch_cpustart_t fn, void *arg) { - u8_t vector = ((unsigned long) x86_ap_start) >> 12; - u8_t apic_id = x86_cpu_loapics[cpu_num]; + uint8_t vector = ((unsigned long) x86_ap_start) >> 12; + uint8_t apic_id; + + if (IS_ENABLED(CONFIG_ACPI)) { + struct acpi_cpu *cpu; + + cpu = z_acpi_get_cpu(cpu_num); + if (cpu != NULL) { + /* We update the apic_id, x86_ap_start will need it. */ + x86_cpu_loapics[cpu_num] = cpu->apic_id; + } + } + + apic_id = x86_cpu_loapics[cpu_num]; - x86_cpuboot[cpu_num].sp = (u64_t) Z_THREAD_STACK_BUFFER(stack) + sz; + x86_cpuboot[cpu_num].sp = (uint64_t) Z_KERNEL_STACK_BUFFER(stack) + sz; + x86_cpuboot[cpu_num].stack_size = sz; x86_cpuboot[cpu_num].fn = fn; x86_cpuboot[cpu_num].arg = arg; -#ifdef CONFIG_X86_MMU - x86_cpuboot[cpu_num].ptables = &z_x86_kernel_ptables; -#endif /* CONFIG_X86_MMU */ z_loapic_ipi(apic_id, LOAPIC_ICR_IPI_INIT, 0); k_busy_wait(10000); @@ -151,10 +168,10 @@ FUNC_NORETURN void z_x86_cpu_init(struct x86_cpuboot *cpuboot) #ifdef CONFIG_USERSPACE /* Set landing site for 'syscall' instruction */ - z_x86_msr_write(X86_LSTAR_MSR, (u64_t)z_x86_syscall_entry_stub); + z_x86_msr_write(X86_LSTAR_MSR, (uint64_t)z_x86_syscall_entry_stub); /* Set segment descriptors for syscall privilege transitions */ - z_x86_msr_write(X86_STAR_MSR, (u64_t)X86_STAR_UPPER << 32); + z_x86_msr_write(X86_STAR_MSR, (uint64_t)X86_STAR_UPPER << 32); /* Mask applied to RFLAGS when making a syscall */ z_x86_msr_write(X86_FMASK_MSR, EFLAGS_SYSCALL); diff --git a/arch/x86/core/intel64/fatal.c b/arch/x86/core/intel64/fatal.c index 15580fa2215da4..0174d229121278 100644 --- a/arch/x86/core/intel64/fatal.c +++ b/arch/x86/core/intel64/fatal.c @@ -8,7 +8,15 @@ #include #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); + +/* NMI handlers should override weak implementation + * return true if NMI is handled, false otherwise + */ +__weak bool z_x86_do_kernel_nmi(const z_arch_esf_t *esf) +{ + return false; +} void z_x86_exception(z_arch_esf_t *esf) { @@ -19,6 +27,12 @@ void z_x86_exception(z_arch_esf_t *esf) case IV_PAGE_FAULT: z_x86_page_fault_handler(esf); break; + case IV_NON_MASKABLE_INTERRUPT: + if (!z_x86_do_kernel_nmi(esf)) { + z_x86_unhandled_cpu_exception(esf->vector, esf); + CODE_UNREACHABLE; + } + break; default: z_x86_unhandled_cpu_exception(esf->vector, esf); CODE_UNREACHABLE; diff --git a/arch/x86/core/intel64/irq.c b/arch/x86/core/intel64/irq.c index 9077906542a739..2c8c86a4380d3e 100644 --- a/arch/x86/core/intel64/irq.c +++ b/arch/x86/core/intel64/irq.c @@ -7,9 +7,14 @@ #include #include #include +#include #include #include #include +#include +#include + +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); unsigned char _irq_to_interrupt_vector[CONFIG_MAX_IRQ_LINES]; @@ -17,36 +22,47 @@ unsigned char _irq_to_interrupt_vector[CONFIG_MAX_IRQ_LINES]; * The low-level interrupt code consults these arrays to dispatch IRQs, so * so be sure to keep locore.S up to date with any changes. Note the indices: * use (vector - IV_IRQS), since exception vectors do not appear here. - * - * Entries which are NULL in x86_irq_funcs[] correspond to unassigned vectors. - * The locore IRQ handler should (read: doesn't currently) raise an exception - * rather than attempt to dispatch to a NULL x86_irq_func[]. FIXME. */ #define NR_IRQ_VECTORS (IV_NR_VECTORS - IV_IRQS) /* # vectors free for IRQs */ -void (*x86_irq_funcs[NR_IRQ_VECTORS])(void *); -void *x86_irq_args[NR_IRQ_VECTORS]; +void (*x86_irq_funcs[NR_IRQ_VECTORS])(const void *); +const void *x86_irq_args[NR_IRQ_VECTORS]; -/* - * Find a free IRQ vector at the specified priority, or return -1 if none left. - */ +static void irq_spurious(const void *arg) +{ + LOG_ERR("Spurious interrupt, vector %d\n", (uint32_t)(uint64_t)arg); + z_fatal_error(K_ERR_SPURIOUS_IRQ, NULL); +} -static int allocate_vector(unsigned int priority) +void x86_64_irq_init(void) +{ + for (int i = 0; i < NR_IRQ_VECTORS; i++) { + x86_irq_funcs[i] = irq_spurious; + x86_irq_args[i] = (const void *)(long)(i + IV_IRQS); + } +} + +int z_x86_allocate_vector(unsigned int priority, int prev_vector) { const int VECTORS_PER_PRIORITY = 16; const int MAX_PRIORITY = 13; - - int vector; + int vector = prev_vector; int i; if (priority >= MAX_PRIORITY) { priority = MAX_PRIORITY; } - vector = (priority * VECTORS_PER_PRIORITY) + IV_IRQS; + if (vector == -1) { + vector = (priority * VECTORS_PER_PRIORITY) + IV_IRQS; + } for (i = 0; i < VECTORS_PER_PRIORITY; ++i, ++vector) { + if (prev_vector != 1 && vector == prev_vector) { + continue; + } + #ifdef CONFIG_IRQ_OFFLOAD if (vector == CONFIG_IRQ_OFFLOAD_VECTOR) { continue; @@ -55,7 +71,8 @@ static int allocate_vector(unsigned int priority) if (vector == Z_X86_OOPS_VECTOR) { continue; } - if (x86_irq_funcs[vector - IV_IRQS] == NULL) { + + if (x86_irq_funcs[vector - IV_IRQS] == irq_spurious) { return vector; } } @@ -63,6 +80,17 @@ static int allocate_vector(unsigned int priority) return -1; } +void z_x86_irq_connect_on_vector(unsigned int irq, + uint8_t vector, + void (*func)(const void *arg), + const void *arg, uint32_t flags) +{ + _irq_to_interrupt_vector[irq] = vector; + z_irq_controller_irq_config(vector, irq, flags); + x86_irq_funcs[vector - IV_IRQS] = func; + x86_irq_args[vector - IV_IRQS] = arg; +} + /* * N.B.: the API docs don't say anything about returning error values, but * this function returns -1 if a vector at the specific priority can't be @@ -70,21 +98,19 @@ static int allocate_vector(unsigned int priority) */ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*func)(void *arg), void *arg, u32_t flags) + void (*func)(const void *arg), + const void *arg, uint32_t flags) { - u32_t key; + uint32_t key; int vector; __ASSERT(irq <= CONFIG_MAX_IRQ_LINES, "IRQ %u out of range", irq); key = irq_lock(); - vector = allocate_vector(priority); + vector = z_x86_allocate_vector(priority, -1); if (vector >= 0) { - _irq_to_interrupt_vector[irq] = vector; - z_irq_controller_irq_config(vector, irq, flags); - x86_irq_funcs[vector - IV_IRQS] = func; - x86_irq_args[vector - IV_IRQS] = arg; + z_x86_irq_connect_on_vector(irq, vector, func, arg, flags); } irq_unlock(key); @@ -94,7 +120,7 @@ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, #ifdef CONFIG_IRQ_OFFLOAD #include -void arch_irq_offload(irq_offload_routine_t routine, void *parameter) +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { x86_irq_funcs[CONFIG_IRQ_OFFLOAD_VECTOR - IV_IRQS] = routine; x86_irq_args[CONFIG_IRQ_OFFLOAD_VECTOR - IV_IRQS] = parameter; @@ -116,6 +142,9 @@ void z_x86_ipi_setup(void) x86_irq_funcs[CONFIG_SCHED_IPI_VECTOR - IV_IRQS] = (void *) z_sched_ipi; + + /* TLB shootdown handling */ + x86_irq_funcs[CONFIG_TLB_IPI_VECTOR - IV_IRQS] = z_x86_tlb_ipi; } /* diff --git a/arch/x86/core/intel64/locore.S b/arch/x86/core/intel64/locore.S index c7b04105548c64..72fa56c50d1f51 100644 --- a/arch/x86/core/intel64/locore.S +++ b/arch/x86/core/intel64/locore.S @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include @@ -10,19 +11,71 @@ #include #include #include +#include -.macro read_tsc var_name - push %rax - push %rdx - rdtsc - mov %eax,\var_name - mov %edx,\var_name+4 - pop %rdx - pop %rax +/* + * Definitions/macros for enabling paging + */ + +/* Long mode, no-execute, syscall */ +#define EFER_BITS (X86_EFER_MSR_LME | X86_EFER_MSR_NXE | X86_EFER_MSR_SCE) + +/* Paging, write-protect */ +#define CR0_BITS (CR0_PG | CR0_WP) + +/* PAE, SSE */ +#define CR4_BITS (CR4_PAE | CR4_OSFXSR) + +.macro set_efer + movl $X86_EFER_MSR, %ecx + rdmsr + orl $EFER_BITS, %eax + wrmsr +.endm + +.macro install_pagetables_32 + movl %cr4, %eax + orl $CR4_BITS, %eax + movl %eax, %cr4 + clts + + /* Page tables created at build time by gen_mmu.py */ + movl $z_x86_kernel_ptables, %eax + movl %eax, %cr3 + + set_efer + + movl %cr0, %eax + orl $CR0_BITS, %eax + movl %eax, %cr0 +.endm + +.macro install_pagetables_64 + /* Here, we are already in long mode with paging enabled and + * just need to switch to our own page tables, but let's be + * paranoid and ensure CR4, CR0, and EFER_MSR are set up + * exactly how we expect. Logic is the same as install_pagetables_32 + */ + movq %cr4, %rax + orq $CR4_BITS, %rax + movq %rax, %cr4 + clts + + movq $z_x86_kernel_ptables, %rax + movq %rax, %cr3 + + set_efer + + movq %cr0, %rax + /* Use 32-bit instructions due to assembler fussiness with large + * immediate values with `orq`, CR0_PG is bit 31. We don't ever set any + * high bits in cr0 anyway. + */ + orl $CR0_BITS, %eax + movq %rax, %cr0 .endm .section .locore,"ax" -.code32 #if CONFIG_MP_NUM_CPUS > 1 @@ -79,7 +132,6 @@ unknown_loapic_id: .code32 .globl __start __start: - /* * kernel execution begins here in 32-bit mode, with flat-mode * descriptors in all segment registers, interrupts disabled. @@ -98,7 +150,6 @@ __start: * next, clear the BSS. note we're still in 32-bit mode, * so the BSS must fit entirely in the first 4GB of RAM. */ - cld xorl %eax, %eax movl $__bss_start, %edi @@ -108,35 +159,21 @@ __start: movl $x86_cpuboot, %ebp /* BSP is always logical CPU id 0 */ movl %ebx, __x86_cpuboot_t_arg_OFFSET(%ebp) /* multiboot info */ - /* - * transition to long mode, reload the segment registers, - * and configure per-CPU stuff: GS, task register, stack. - */ -go64: movl %cr4, %eax /* enable PAE and SSE */ - orl $(CR4_PAE | CR4_OSFXSR), %eax - movl %eax, %cr4 - clts +go64: /* Install page tables and transition to long mode */ + install_pagetables_32 + jmpl $X86_KERNEL_CS, $enter_code64 -#ifdef CONFIG_X86_MMU - movl __x86_cpuboot_t_ptables_OFFSET(%ebp), %eax -#else - movl $z_x86_flat_ptables, %eax -#endif - movl %eax, %cr3 - - movl $X86_EFER_MSR, %ecx /* enable long mode, no-execute, syscall */ - rdmsr - orl $(X86_EFER_MSR_LME | X86_EFER_MSR_NXE | X86_EFER_MSR_SCE), %eax - wrmsr - - movl %cr0, %eax /* enable paging */ - orl $(CR0_PG | CR0_WP), %eax - movl %eax, %cr0 - - jmpl $X86_KERNEL_CS, $1f -.code64 -1: movl $X86_KERNEL_DS, %eax + /* Long mode entry point. Arrive here from the code + * immediately above (shared between main CPU startup and AP + * startup), or from EFI entry in __start64. + * + * Here we reload the segment registers, + * and configure per-CPU stuff: GS, task register, stack. + */ + .code64 +enter_code64: + movl $X86_KERNEL_DS, %eax movw %ax, %ds movw %ax, %es movw %ax, %ss @@ -167,8 +204,9 @@ go64: movl %cr4, %eax /* enable PAE and SSE */ #ifdef CONFIG_INIT_STACKS movq $0xAAAAAAAAAAAAAAAA, %rax movq %rsp, %rdi - subq $CONFIG_ISR_STACK_SIZE, %rdi - movq $(CONFIG_ISR_STACK_SIZE >> 3), %rcx + subq __x86_cpuboot_t_stack_size_OFFSET(%rbp), %rdi + movq __x86_cpuboot_t_stack_size_OFFSET(%rbp), %rcx + shr $3, %rcx /* moving 8 bytes a time, so fewer repeats */ rep stosq #endif @@ -176,6 +214,41 @@ go64: movl %cr4, %eax /* enable PAE and SSE */ movq %rbp, %rdi call z_x86_cpu_init + /* 64 bit OS entry point, used by EFI support. UEFI + * guarantees an identity-mapped page table that covers + * physical memory, and the loader stub already used it to + * write all of the Zephyr image, so we know it works for what + * we need. Other things need fixups to match what multiboot + * 32 bit startup does. + */ +.globl __start64 +__start64: + /* Zero the TSC */ + xorq %rax, %rax + xorq %rdx, %rdx + movq $X86_TIME_STAMP_COUNTER_MSR, %rcx + wrmsr + + lidt idt80 + lgdt gdt80 + + install_pagetables_64 + + /* Disable 8259 PIT. Almost certainly not needed on modern + * UEFI platforms taking this code path, but... + */ + movb $0xff, %al + outb %al, $0x21 + outb %al, $0xA1 + + /* Far call into the Zephyr code segment */ + movq $x86_cpuboot, %rbp + mov jmpdesc, %rax + jmp *%rax +jmpdesc: + .quad enter_code64 + .short X86_KERNEL_CS + /* * void x86_sse_init(struct k_thread *thread); * @@ -206,10 +279,6 @@ mxcsr: .long X86_MXCSR_SANE .globl z_x86_switch z_x86_switch: -#ifdef CONFIG_EXECUTION_BENCHMARKING - read_tsc arch_timing_swap_start -#endif - /* RSI contains the switch_handle field to which we are * notionally supposed to store. Offset it to get back to the * thread handle instead. @@ -255,17 +324,24 @@ z_x86_switch: */ __resume: -#ifdef CONFIG_USERSPACE -#ifndef CONFIG_X86_KPTI +#if (!defined(CONFIG_X86_KPTI) && defined(CONFIG_USERSPACE)) \ + || defined(CONFIG_INSTRUMENT_THREAD_SWITCHING) + pushq %rdi /* Caller-saved, stash it */ +#if !defined(CONFIG_X86_KPTI) && defined(CONFIG_USERSPACE) /* If KPTI is enabled we're always on the kernel's page tables in * this context and the appropriate page table switch takes place * when trampolining back to user mode */ - pushq %rdi /* Caller-saved, stash it */ call z_x86_swap_update_page_tables +#endif +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + call z_thread_mark_switched_in +#endif popq %rdi -#endif /* CONFIG_X86_KPTI */ +#endif /* (!CONFIG_X86_KPTI && CONFIG_USERSPACE) || \ + CONFIG_INSTRUMENT_THREAD_SWITCHING */ +#ifdef CONFIG_USERSPACE /* Set up exception return stack frame */ pushq _thread_offset_to_ss(%rdi) /* SS */ #else @@ -290,6 +366,23 @@ __resume: movq $0xB9, _thread_offset_to_rip(%rdi) #endif +#ifdef CONFIG_THREAD_LOCAL_STORAGE + /* + * Write the TLS base pointer to FS_BASE MSR, + * where GCC emits code to access TLS data via + * offset to FS. + * Since wrmsr write EDX:EAX to MSR indicated by + * ECX, the high 32-bit needs to be loaded into + * RDX and right shifted by 32 bits so EDX has + * the higher 32-bit value. + */ + movl $X86_FS_BASE, %ecx + movq _thread_offset_to_tls(%rdi), %rax + movq _thread_offset_to_tls(%rdi), %rdx + shrq $32, %rdx + wrmsr +#endif + movq _thread_offset_to_rbx(%rdi), %rbx movq _thread_offset_to_rbp(%rdi), %rbp movq _thread_offset_to_r12(%rdi), %r12 @@ -333,24 +426,23 @@ __resume: /* swapgs variant of Spectre V1. Disable speculation past this point */ lfence #endif /* CONFIG_X86_BOUNDS_CHECK_BYPASS_MITIGATION */ - -#ifdef CONFIG_EXECUTION_BENCHMARKING - cmp $0x1,arch_timing_value_swap_end - jne time_read_not_needed - movw $0x2,arch_timing_value_swap_end - read_tsc arch_timing_value_swap_common - pushq arch_timing_swap_start - popq arch_timing_value_swap_temp -time_read_not_needed: -#endif - iretq - - +#ifdef CONFIG_X86_KPTI +#define EXCEPT_CODE(nr, ist) \ + vector_ ## nr: pushq %gs:__x86_tss64_t_ist ## ist ## _OFFSET; \ + pushq $nr; \ + jmp except +#define EXCEPT(nr, ist) \ + vector_ ## nr: pushq $0; \ + pushq %gs:__x86_tss64_t_ist ## ist ## _OFFSET; \ + pushq $nr; \ + jmp except +#else #define EXCEPT_CODE(nr) vector_ ## nr: pushq $nr; jmp except #define EXCEPT(nr) vector_ ## nr: pushq $0; pushq $nr; jmp except +#endif /* * When we arrive at 'except' from one of the EXCEPT(X) stubs, @@ -363,6 +455,7 @@ time_read_not_needed: * CS * RIP * Error Code if pushed by CPU, else 0 + * IST index in TSS * Vector number <- RSP points here * */ @@ -376,7 +469,7 @@ except: /* #ifdef CONFIG_USERSPACE /* Swap GS register values and page tables if we came from user mode */ - testb $0x3, 32(%rsp) + testb $0x3, 40(%rsp) jz 1f swapgs #ifdef CONFIG_X86_KPTI @@ -393,18 +486,18 @@ except: /* /* Save old trampoline stack pointer in R11 */ movq %rsp, %r11 - /* Switch to the exception stack */ - movq %gs:__x86_tss64_t_ist7_OFFSET, %rsp + /* Switch to the correct stack */ + movq 16(%r11), %rsp /* Transplant trampoline stack contents */ - pushq 56(%r11) /* SS */ - pushq 48(%r11) /* RSP */ - pushq 40(%r11) /* RFLAGS */ - pushq 32(%r11) /* CS */ - pushq 24(%r11) /* RIP */ - pushq 16(%r11) /* Error code */ + pushq 64(%r11) /* SS */ + pushq 56(%r11) /* RSP */ + pushq 48(%r11) /* RFLAGS */ + pushq 40(%r11) /* CS */ + pushq 32(%r11) /* RIP */ + pushq 24(%r11) /* Error code */ pushq 8(%r11) /* Vector */ - pushq (%r11) /* Stashed R15 */ + pushq (%r11) /* Stashed R11 */ movq $0, (%r11) /* Cover our tracks */ /* We're done, it's safe to re-enable interrupts. */ @@ -426,13 +519,13 @@ except: /* pushq %rdx pushq %rcx pushq %rax + pushq %rbp #ifdef CONFIG_EXCEPTION_DEBUG /* Callee saved regs */ pushq %r15 pushq %r14 pushq %r13 pushq %r12 - pushq %rbp pushq %rbx #endif /* CONFIG_EXCEPTION_DEBUG */ movq %rsp, %rdi @@ -444,12 +537,12 @@ except: /* */ #ifdef CONFIG_EXCEPTION_DEBUG popq %rbx - popq %rbp popq %r12 popq %r13 popq %r14 popq %r15 #endif /* CONFIG_EXCEPTION_DEBUG */ + popq %rbp popq %rax popq %rcx popq %rdx @@ -480,6 +573,21 @@ except: /* iretq +#ifdef CONFIG_X86_KPTI +EXCEPT ( 0, 7); EXCEPT ( 1, 7); EXCEPT (2, 6); EXCEPT ( 3, 7) +EXCEPT ( 4, 7); EXCEPT ( 5, 7); EXCEPT (6, 7); EXCEPT ( 7, 7) +EXCEPT_CODE ( 8, 7); EXCEPT ( 9, 7); EXCEPT_CODE (10, 7); EXCEPT_CODE (11, 7) +EXCEPT_CODE (12, 7); EXCEPT_CODE (13, 7); EXCEPT_CODE (14, 7); EXCEPT (15, 7) +EXCEPT (16, 7); EXCEPT_CODE (17, 7); EXCEPT (18, 7); EXCEPT (19, 7) +EXCEPT (20, 7); EXCEPT (21, 7); EXCEPT (22, 7); EXCEPT (23, 7) +EXCEPT (24, 7); EXCEPT (25, 7); EXCEPT (26, 7); EXCEPT (27, 7) +EXCEPT (28, 7); EXCEPT (29, 7); EXCEPT (30, 7); EXCEPT (31, 7) + +/* Vector reserved for handling a kernel oops; treat as an exception + * and not an interrupt + */ +EXCEPT(Z_X86_OOPS_VECTOR, 7); +#else EXCEPT ( 0); EXCEPT ( 1); EXCEPT ( 2); EXCEPT ( 3) EXCEPT ( 4); EXCEPT ( 5); EXCEPT ( 6); EXCEPT ( 7) EXCEPT_CODE ( 8); EXCEPT ( 9); EXCEPT_CODE (10); EXCEPT_CODE (11) @@ -493,6 +601,7 @@ EXCEPT (28); EXCEPT (29); EXCEPT (30); EXCEPT (31) * and not an interrupt */ EXCEPT(Z_X86_OOPS_VECTOR); +#endif /* CONFIG_X86_KPTI */ /* * When we arrive at 'irq' from one of the IRQ(X) stubs, @@ -511,10 +620,6 @@ EXCEPT(Z_X86_OOPS_VECTOR); .globl x86_irq_args /* .. for these definitions */ irq: -#ifdef CONFIG_EXECUTION_BENCHMARKING - read_tsc arch_timing_irq_start -#endif - pushq %rsi #ifdef CONFIG_USERSPACE @@ -630,22 +735,19 @@ irq_enter_unnested: /* Not nested: dump state to thread struct for __resume */ #endif irq_dispatch: -#ifdef CONFIG_EXECUTION_BENCHMARKING - read_tsc arch_timing_irq_end -#endif - - movq x86_irq_funcs(,%rcx,8), %rbx + movq x86_irq_funcs(,%rcx,8), %rax movq x86_irq_args(,%rcx,8), %rdi - call *%rbx + call *%rax - xorl %eax, %eax + xorq %rax, %rax #ifdef CONFIG_X2APIC xorl %edx, %edx movl $(X86_X2APIC_BASE_MSR + (LOAPIC_EOI >> 4)), %ecx wrmsr #else /* xAPIC */ - movl %eax, (CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI) -#endif + movq z_loapic_regs, %rdx + movl %eax, LOAPIC_EOI(%rdx) +#endif /* CONFIG_X2APIC */ movq %gs:__x86_tss64_t_cpu_OFFSET, %rsi @@ -746,16 +848,18 @@ IRQ(248); IRQ(249); IRQ(250); IRQ(251); IRQ(252); IRQ(253); IRQ(254); IRQ(255) #define IRQ_STACK 2 #define EXC_STACK 2 #define BAD_STACK 2 +#define NMI_STACK 2 #else #define IRQ_STACK 1 +#define NMI_STACK 6 /* NMI stack */ #define EXC_STACK 7 -#define BAD_STACK 7 /* Horrible things: NMIs, double faults, MCEs */ +#define BAD_STACK 7 /* Horrible things: double faults, MCEs */ #endif .align 16 idt: IDT( 0, TRAP, EXC_STACK); IDT( 1, TRAP, EXC_STACK) - IDT( 2, TRAP, BAD_STACK); IDT( 3, TRAP, EXC_STACK) + IDT( 2, TRAP, NMI_STACK); IDT( 3, TRAP, EXC_STACK) IDT( 4, TRAP, EXC_STACK); IDT( 5, TRAP, EXC_STACK) IDT( 6, TRAP, EXC_STACK); IDT( 7, TRAP, EXC_STACK) IDT( 8, TRAP, BAD_STACK); IDT( 9, TRAP, EXC_STACK) @@ -884,33 +988,15 @@ idt: IDT(250, INTR, IRQ_STACK); IDT(251, INTR, IRQ_STACK) IDT(252, INTR, IRQ_STACK); IDT(253, INTR, IRQ_STACK) IDT(254, INTR, IRQ_STACK); IDT(255, INTR, IRQ_STACK) +idt_end: -idt48: - .word (idt48 - idt - 1) +idt48: /* LIDT descriptor for 32 bit mode */ + .word (idt_end - idt - 1) .long idt -/* - * Page tables. Long mode requires them, but we don't implement any memory - * protection yet, so these simply identity-map the first 4GB w/ 1GB pages. - */ - -.align 4096 - -.globl z_x86_flat_ptables -z_x86_flat_ptables: - .long pdp + 0x03 /* 0x03 = R/W, P */ - .long 0 - .fill 4088, 1, 0 - -pdp: .long 0x00000083 /* 0x83 = 1GB, R/W, P */ - .long 0 - .long 0x40000083 - .long 0 - .long 0x80000083 - .long 0 - .long 0xC0000083 - .long 0 - .fill 4064, 1, 0 +idt80: /* LIDT descriptor for 64 bit mode */ + .word (idt_end - idt - 1) + .quad idt .section .gdt,"ad" @@ -965,40 +1051,61 @@ gdt: .word 0, 0, 0, 0, 0 #endif -gdt48: - .word (gdt48 - gdt - 1) +gdt_end: + +gdt48: /* LGDT descriptor for 32 bit mode */ + .word (gdt_end - gdt - 1) .long gdt +gdt80: /* LGDT descriptor for long mode */ + .word (gdt_end - gdt - 1) + .quad gdt .section .lodata,"ad" /* * Known-good stack for handling CPU exceptions. */ -.global _exception_stack +.global z_x86_exception_stack +.align 16 +z_x86_exception_stack: + .fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA +.global z_x86_nmi_stack .align 16 -_exception_stack: - .fill CONFIG_EXCEPTION_STACK_SIZE, 1, 0xAA +z_x86_nmi_stack: + .fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA #if CONFIG_MP_NUM_CPUS > 1 -.global _exception_stack1 +.global z_x86_exception_stack1 .align 16 -_exception_stack1: - .fill CONFIG_EXCEPTION_STACK_SIZE, 1, 0xAA +z_x86_exception_stack1: + .fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA +.global z_x86_nmi_stack1 +.align 16 +z_x86_nmi_stack1: + .fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA #endif #if CONFIG_MP_NUM_CPUS > 2 -.global _exception_stack2 +.global z_x86_exception_stack2 +.align 16 +z_x86_exception_stack2: + .fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA +.global z_x86_nmi_stack2 .align 16 -_exception_stack2: - .fill CONFIG_EXCEPTION_STACK_SIZE, 1, 0xAA +z_x86_nmi_stack2: + .fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA #endif #if CONFIG_MP_NUM_CPUS > 3 -.global _exception_stack3 +.global z_x86_exception_stack3 +.align 16 +z_x86_exception_stack3: + .fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA +.global z_x86_nmi_stack3 .align 16 -_exception_stack3: - .fill CONFIG_EXCEPTION_STACK_SIZE, 1, 0xAA +z_x86_nmi_stack3: + .fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA #endif #ifdef CONFIG_X86_KPTI diff --git a/arch/x86/core/intel64/thread.c b/arch/x86/core/intel64/thread.c index ac67d8cdb53c13..451f34b50caef5 100644 --- a/arch/x86/core/intel64/thread.c +++ b/arch/x86/core/intel64/thread.c @@ -8,26 +8,24 @@ #include #include #include +#include extern void x86_sse_init(struct k_thread *); /* in locore.S */ +struct x86_initial_frame { + /* zeroed return address for ABI */ + uint64_t rip; +}; + void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - size_t stack_size, k_thread_entry_t entry, - void *parameter1, void *parameter2, void *parameter3, - int priority, unsigned int options) + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) { void *switch_entry; - - z_new_thread_init(thread, Z_THREAD_STACK_BUFFER(stack), stack_size); + struct x86_initial_frame *iframe; #if CONFIG_X86_STACK_PROTECTION - struct z_x86_thread_stack_header *header = - (struct z_x86_thread_stack_header *)stack; - - /* Set guard area to read-only to catch stack overflows */ - z_x86_mmu_set_flags(&z_x86_kernel_ptables, &header->guard_page, - MMU_PAGE_SIZE, MMU_ENTRY_READ, Z_X86_MMU_RW, - true); + z_x86_set_stack_guard(stack); #endif #ifdef CONFIG_USERSPACE switch_entry = z_x86_userspace_prepare_thread(thread); @@ -36,8 +34,9 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, #else switch_entry = z_thread_entry; #endif - thread->callee_saved.rsp = (long) Z_THREAD_STACK_BUFFER(stack); - thread->callee_saved.rsp += (stack_size - 8); /* fake RIP for ABI */ + iframe = Z_STACK_PTR_TO_FRAME(struct x86_initial_frame, stack_ptr); + iframe->rip = 0; + thread->callee_saved.rsp = (long) iframe; thread->callee_saved.rip = (long) switch_entry; thread->callee_saved.rflags = EFLAGS_INITIAL; @@ -45,9 +44,9 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, * thread->callee_saved.rip */ thread->arch.rdi = (long) entry; - thread->arch.rsi = (long) parameter1; - thread->arch.rdx = (long) parameter2; - thread->arch.rcx = (long) parameter3; + thread->arch.rsi = (long) p1; + thread->arch.rdx = (long) p2; + thread->arch.rcx = (long) p3; x86_sse_init(thread); diff --git a/arch/x86/core/intel64/userspace.S b/arch/x86/core/intel64/userspace.S index d6aaa7512a9989..8fd9297f9cf8a7 100644 --- a/arch/x86/core/intel64/userspace.S +++ b/arch/x86/core/intel64/userspace.S @@ -4,9 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include +#include #ifdef CONFIG_X86_KPTI /* Copy interrupt return stack context to the trampoline stack, switch back @@ -284,24 +286,20 @@ z_x86_userspace_enter: */ movq %r9, %rsp - /* Need RDI temporarily */ - pushq %rdi - - /* Compute size of user stack in 8-byte chunks and put in RCX */ - movq %r9, %rdi /* Start address for rep stosq in RDI */ - movq %r8, %rcx /* Ending address */ - subq %rdi, %rcx /* Subtract starting address */ - shrq $3, %rcx /* Divide by 8 */ - - movq $0xAAAAAAAAAAAAAAAA, %rax /* Fill value */ - /* Copy 8 bytes of memory at a time, starting at ES:RDI, with whatever - * is in RAX. Repeat this RCX times. Stack sizes are always at least - * 8-byte aligned. + /* Push callee-saved regs and go back into C code to erase the stack + * buffer and set US bit in page tables for it */ - cld - rep stosq - + pushq %rdx + pushq %rsi + pushq %rdi + pushq %r8 + pushq %r10 + callq z_x86_current_stack_perms + popq %r10 + popq %r8 popq %rdi + popq %rsi + popq %rdx /* Reset to the beginning of the user stack */ movq %r8, %rsp @@ -324,19 +322,6 @@ z_x86_userspace_enter: cli -#ifdef CONFIG_EXECUTION_BENCHMARKING - /* Save the eax and edx registers before reading the time stamp - * once done pop the values. - */ - push %rax - push %rdx - rdtsc - mov %eax,arch_timing_enter_user_mode_end - mov %edx,arch_timing_enter_user_mode_end+4 - pop %rdx - pop %rax -#endif - #ifdef CONFIG_X86_KPTI /* Switch to thread's page table. We have free registers so no need * to involve the trampoline stack. diff --git a/arch/x86/core/memmap.c b/arch/x86/core/memmap.c index 5e33047d59c19e..b47996c46e4fcd 100644 --- a/arch/x86/core/memmap.c +++ b/arch/x86/core/memmap.c @@ -13,7 +13,9 @@ struct x86_memmap_exclusion x86_memmap_exclusions[] = { #ifdef CONFIG_X86_64 { "locore", _locore_start, _locore_end }, #endif +#ifdef CONFIG_XIP { "rom", _image_rom_start, _image_rom_end }, +#endif { "ram", _image_ram_start, _image_ram_end }, #ifdef CONFIG_USERSPACE { "app_smem", _app_smem_start, _app_smem_end }, diff --git a/arch/x86/core/multiboot.c b/arch/x86/core/multiboot.c index e9150195ad5b51..2cb81fed2efc76 100644 --- a/arch/x86/core/multiboot.c +++ b/arch/x86/core/multiboot.c @@ -42,10 +42,10 @@ void z_multiboot_init(struct multiboot_info *info) if ((info->flags & MULTIBOOT_INFO_FLAGS_MMAP) && (x86_memmap_source < X86_MEMMAP_SOURCE_MULTIBOOT_MMAP)) { - u32_t address = info->mmap_addr; + uint32_t address = info->mmap_addr; struct multiboot_mmap *mmap; int index = 0; - u32_t type; + uint32_t type; while ((address < (info->mmap_addr + info->mmap_length)) && (index < CONFIG_X86_MEMMAP_ENTRIES)) { @@ -109,7 +109,7 @@ static struct framebuf_dev_data multiboot_framebuf_data = { .height = CONFIG_MULTIBOOT_FRAMEBUF_Y }; -static int multiboot_framebuf_init(struct device *dev) +static int multiboot_framebuf_init(const struct device *dev) { struct framebuf_dev_data *data = FRAMEBUF_DATA(dev); struct multiboot_info *info = &multiboot_info; @@ -124,9 +124,9 @@ static int multiboot_framebuf_init(struct device *dev) * the pitch and adjust the start address center our canvas. */ - u16_t adj_x; - u16_t adj_y; - u32_t *buffer; + uint16_t adj_x; + uint16_t adj_y; + uint32_t *buffer; adj_x = info->fb_width - CONFIG_MULTIBOOT_FRAMEBUF_X; adj_y = info->fb_height - CONFIG_MULTIBOOT_FRAMEBUF_Y; diff --git a/arch/x86/core/offsets/ia32_offsets.c b/arch/x86/core/offsets/ia32_offsets.c index 1b962e23ebbc61..3ac11219b7b25f 100644 --- a/arch/x86/core/offsets/ia32_offsets.c +++ b/arch/x86/core/offsets/ia32_offsets.c @@ -24,6 +24,9 @@ /* list of headers that define whose structure offsets will be generated */ +#ifndef _X86_OFFSETS_INC_ +#define _X86_OFFSETS_INC_ + #include #if defined(CONFIG_LAZY_FPU_SHARING) @@ -32,8 +35,9 @@ GEN_OFFSET_SYM(_thread_arch_t, excNestCount); #ifdef CONFIG_USERSPACE GEN_OFFSET_SYM(_thread_arch_t, psp); +#ifndef CONFIG_X86_COMMON_PAGE_TABLE GEN_OFFSET_SYM(_thread_arch_t, ptables); -GEN_ABSOLUTE_SYM(Z_X86_PDPT_SIZE, sizeof(struct x86_mmu_pdpt)); +#endif #endif GEN_OFFSET_SYM(_thread_arch_t, preempFloatReg); @@ -62,7 +66,4 @@ GEN_OFFSET_SYM(z_arch_esf_t, errorCode); GEN_OFFSET_SYM(z_arch_esf_t, eip); GEN_OFFSET_SYM(z_arch_esf_t, cs); GEN_OFFSET_SYM(z_arch_esf_t, eflags); - -/* size of the MMU_REGION structure. Used by linker scripts */ - -GEN_ABSOLUTE_SYM(__MMU_REGION_SIZEOF, sizeof(struct mmu_region)); +#endif /* _X86_OFFSETS_INC_ */ diff --git a/arch/x86/core/offsets/intel64_offsets.c b/arch/x86/core/offsets/intel64_offsets.c index 8edc8eb8b506fd..8b351b1fa91d75 100644 --- a/arch/x86/core/offsets/intel64_offsets.c +++ b/arch/x86/core/offsets/intel64_offsets.c @@ -3,6 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef _X86_OFFSETS_INC_ +#define _X86_OFFSETS_INC_ + GEN_OFFSET_SYM(_callee_saved_t, rsp); GEN_OFFSET_SYM(_callee_saved_t, rbp); GEN_OFFSET_SYM(_callee_saved_t, rbx); @@ -27,11 +30,14 @@ GEN_OFFSET_SYM(_thread_arch_t, sse); GEN_OFFSET_SYM(_thread_arch_t, ss); GEN_OFFSET_SYM(_thread_arch_t, cs); GEN_OFFSET_SYM(_thread_arch_t, psp); +#ifndef CONFIG_X86_COMMON_PAGE_TABLE GEN_OFFSET_SYM(_thread_arch_t, ptables); +#endif #endif /* CONFIG_USERSPACE */ GEN_OFFSET_SYM(x86_tss64_t, ist1); GEN_OFFSET_SYM(x86_tss64_t, ist2); +GEN_OFFSET_SYM(x86_tss64_t, ist6); GEN_OFFSET_SYM(x86_tss64_t, ist7); GEN_OFFSET_SYM(x86_tss64_t, cpu); #ifdef CONFIG_USERSPACE @@ -44,9 +50,9 @@ GEN_OFFSET_SYM(x86_cpuboot_t, ready); GEN_OFFSET_SYM(x86_cpuboot_t, tr); GEN_OFFSET_SYM(x86_cpuboot_t, gs_base); GEN_OFFSET_SYM(x86_cpuboot_t, sp); +GEN_OFFSET_SYM(x86_cpuboot_t, stack_size); GEN_OFFSET_SYM(x86_cpuboot_t, fn); GEN_OFFSET_SYM(x86_cpuboot_t, arg); -#ifdef CONFIG_X86_MMU -GEN_OFFSET_SYM(x86_cpuboot_t, ptables); -#endif /* CONFIG_X86_MMU */ GEN_ABSOLUTE_SYM(__X86_CPUBOOT_SIZEOF, sizeof(x86_cpuboot_t)); + +#endif /* _X86_OFFSETS_INC_ */ diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c index 6bf284bff2c023..71db9a5b977166 100644 --- a/arch/x86/core/pcie.c +++ b/arch/x86/core/pcie.c @@ -5,20 +5,87 @@ */ #include +#include #include +#ifdef CONFIG_ACPI +#include +#endif + #ifdef CONFIG_PCIE_MSI +#include +#include #include #endif -/* - * The Configuration Mechanism (previously, Configuration Mechanism #1) - * uses two 32-bit ports in the I/O space, here called CAP and CDP. - * - * N.B.: this code relies on the fact that the PCIE_BDF() format (as - * defined in dt-bindings/pcie/pcie.h) and the CAP agree on the bus/dev/func - * bitfield positions and sizes. - */ +/* PCI Express Extended Configuration Mechanism (MMIO) */ +#ifdef CONFIG_PCIE_MMIO_CFG + +#define MAX_PCI_BUS_SEGMENTS 4 + +static struct { + uint32_t start_bus; + uint32_t n_buses; + uint8_t *mmio; +} bus_segs[MAX_PCI_BUS_SEGMENTS]; + +static bool do_pcie_mmio_cfg; + +static void pcie_mm_init(void) +{ +#ifdef CONFIG_ACPI + struct acpi_mcfg *m = z_acpi_find_table(ACPI_MCFG_SIGNATURE); + + if (m != NULL) { + int n = (m->sdt.length - sizeof(*m)) / sizeof(m->pci_segs[0]); + + for (int i = 0; i < n && i < MAX_PCI_BUS_SEGMENTS; i++) { + size_t size; + uintptr_t phys_addr; + + bus_segs[i].start_bus = m->pci_segs[i].start_bus; + bus_segs[i].n_buses = 1 + m->pci_segs[i].end_bus + - m->pci_segs[i].start_bus; + + phys_addr = m->pci_segs[i].base_addr; + /* 32 devices & 8 functions per bus, 4k per device */ + size = bus_segs[i].n_buses * (32 * 8 * 4096); + + device_map((mm_reg_t *)&bus_segs[i].mmio, phys_addr, + size, K_MEM_CACHE_NONE); + } + + do_pcie_mmio_cfg = true; + } +#endif +} + +static inline void pcie_mm_conf(pcie_bdf_t bdf, unsigned int reg, + bool write, uint32_t *data) +{ + for (int i = 0; i < ARRAY_SIZE(bus_segs); i++) { + int off = PCIE_BDF_TO_BUS(bdf) - bus_segs[i].start_bus; + + if (off >= 0 && off < bus_segs[i].n_buses) { + bdf = PCIE_BDF(off, + PCIE_BDF_TO_DEV(bdf), + PCIE_BDF_TO_FUNC(bdf)); + + volatile uint32_t *regs + = (void *)&bus_segs[i].mmio[bdf << 4]; + + if (write) { + regs[reg] = *data; + } else { + *data = regs[reg]; + } + } + } +} + +#endif /* CONFIG_PCIE_MMIO_CFG */ + +/* Traditional Configuration Mechanism */ #define PCIE_X86_CAP 0xCF8U /* Configuration Address Port */ #define PCIE_X86_CAP_BDF_MASK 0x00FFFF00U /* b/d/f bits */ @@ -32,7 +99,8 @@ * Helper function for exported configuration functions. Configuration access * ain't atomic, so spinlock to keep drivers from clobbering each other. */ -static void pcie_conf(pcie_bdf_t bdf, unsigned int reg, bool write, u32_t *data) +static inline void pcie_io_conf(pcie_bdf_t bdf, unsigned int reg, + bool write, uint32_t *data) { static struct k_spinlock lock; k_spinlock_key_t k; @@ -54,36 +122,197 @@ static void pcie_conf(pcie_bdf_t bdf, unsigned int reg, bool write, u32_t *data) k_spin_unlock(&lock, k); } +static inline void pcie_conf(pcie_bdf_t bdf, unsigned int reg, + bool write, uint32_t *data) + +{ +#ifdef CONFIG_PCIE_MMIO_CFG + if (bus_segs[0].mmio == NULL) { + pcie_mm_init(); + } + + if (do_pcie_mmio_cfg) { + pcie_mm_conf(bdf, reg, write, data); + } else +#endif + { + pcie_io_conf(bdf, reg, write, data); + } +} + /* these functions are explained in include/drivers/pcie/pcie.h */ -u32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg) +uint32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg) { - u32_t data; + uint32_t data = 0; pcie_conf(bdf, reg, false, &data); return data; } -void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, u32_t data) +void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, uint32_t data) { pcie_conf(bdf, reg, true, &data); } #ifdef CONFIG_PCIE_MSI +#ifdef CONFIG_INTEL_VTD_ICTL + +#include + +static const struct device *vtd; + +static bool get_vtd(void) +{ + if (vtd != NULL) { + return true; + } +#define DT_DRV_COMPAT intel_vt_d + vtd = device_get_binding(DT_INST_LABEL(0)); +#undef DT_DRV_COMPAT + + return vtd == NULL ? false : true; +} + +#endif /* CONFIG_INTEL_VTD_ICTL */ + /* these functions are explained in include/drivers/pcie/msi.h */ -u32_t pcie_msi_map(unsigned int irq) +uint32_t pcie_msi_map(unsigned int irq, + msi_vector_t *vector) { + uint32_t map; + ARG_UNUSED(irq); - return 0xFEE00000U; /* standard delivery to BSP local APIC */ +#if defined(CONFIG_INTEL_VTD_ICTL) +#if !defined(CONFIG_PCIE_MSI_X) + if (vector != NULL) { + map = vtd_remap_msi(vtd, vector); + } else +#else + if (vector != NULL && !vector->msix) { + map = vtd_remap_msi(vtd, vector); + } else +#endif +#endif + { + map = 0xFEE00000U; /* standard delivery to BSP local APIC */ + } + + return map; +} + +uint16_t pcie_msi_mdr(unsigned int irq, + msi_vector_t *vector) +{ +#ifdef CONFIG_PCIE_MSI_X + if ((vector != NULL) && (vector->msix)) { + return 0x4000U | vector->arch.vector; + } +#endif + + if (vector == NULL) { + /* edge triggered */ + return 0x4000U | Z_IRQ_TO_INTERRUPT_VECTOR(irq); + } + + /* VT-D requires it to be 0, so let's return 0 by default */ + return 0; } -u16_t pcie_msi_mdr(unsigned int irq) +#if defined(CONFIG_INTEL_VTD_ICTL) || defined(CONFIG_PCIE_MSI_X) + +static inline uint32_t _read_pcie_irq_data(pcie_bdf_t bdf) { - unsigned char vector = Z_IRQ_TO_INTERRUPT_VECTOR(irq); + uint32_t data; + + data = pcie_conf_read(bdf, PCIE_CONF_INTR); + + pcie_conf_write(bdf, PCIE_CONF_INTR, data | PCIE_CONF_INTR_IRQ_NONE); - return 0x4000U | vector; /* edge triggered */ + return data; } +static inline void _write_pcie_irq_data(pcie_bdf_t bdf, uint32_t data) +{ + pcie_conf_write(bdf, PCIE_CONF_INTR, data); +} + +uint8_t arch_pcie_msi_vectors_allocate(unsigned int priority, + msi_vector_t *vectors, + uint8_t n_vector) +{ + if (n_vector > 1) { + int prev_vector = -1; + int i; +#ifdef CONFIG_INTEL_VTD_ICTL +#ifdef CONFIG_PCIE_MSI_X + if (!vectors[0].msix) #endif + { + int irte; + + if (!get_vtd()) { + return 0; + } + + irte = vtd_allocate_entries(vtd, n_vector); + if (irte < 0) { + return 0; + } + + for (i = irte; i < (irte + n_vector); i++) { + vectors[i].arch.irte = i; + vectors[i].arch.remap = true; + } + } +#endif /* CONFIG_INTEL_VTD_ICTL */ + + for (i = 0; i < n_vector; i++) { + uint32_t data; + + data = _read_pcie_irq_data(vectors[i].bdf); + + vectors[i].arch.irq = pcie_alloc_irq(vectors[i].bdf); + + _write_pcie_irq_data(vectors[i].bdf, data); + + vectors[i].arch.vector = + z_x86_allocate_vector(priority, prev_vector); + if (vectors[i].arch.vector < 0) { + return 0; + } + + prev_vector = vectors[i].arch.vector; + } + } else { + vectors[0].arch.vector = z_x86_allocate_vector(priority, -1); + } + + return n_vector; +} + +bool arch_pcie_msi_vector_connect(msi_vector_t *vector, + void (*routine)(const void *parameter), + const void *parameter, + uint32_t flags) +{ +#ifdef CONFIG_INTEL_VTD_ICTL + if (vector->arch.remap) { + if (!get_vtd()) { + return false; + } + + vtd_remap(vtd, vector); + } +#endif /* CONFIG_INTEL_VTD_ICTL */ + + z_x86_irq_connect_on_vector(vector->arch.irq, vector->arch.vector, + routine, parameter, flags); + + return true; +} + +#endif /* CONFIG_INTEL_VTD_ICTL || CONFIG_PCIE_MSI_X */ +#endif /* CONFIG_PCIE_MSI */ diff --git a/arch/x86/core/prep_c.c b/arch/x86/core/prep_c.c index dfb6cfda048d08..a45e2a0fd94d09 100644 --- a/arch/x86/core/prep_c.c +++ b/arch/x86/core/prep_c.c @@ -8,8 +8,10 @@ #include #include #include +#include extern FUNC_NORETURN void z_cstart(void); +extern void x86_64_irq_init(void); /* Early global initialization functions, C domain. This runs only on the first * CPU for SMP systems. @@ -24,24 +26,20 @@ FUNC_NORETURN void z_x86_prep_c(void *arg) z_x86_early_serial_init(); #endif +#ifdef CONFIG_X86_64 + x86_64_irq_init(); +#endif + #ifdef CONFIG_MULTIBOOT_INFO z_multiboot_init(info); #else ARG_UNUSED(info); #endif -#ifdef CONFIG_ACPI - z_acpi_init(); -#endif - -#ifdef CONFIG_X86_MMU - z_x86_paging_init(); -#endif - #if CONFIG_X86_STACK_PROTECTION - z_x86_mmu_set_flags(&z_x86_kernel_ptables, z_interrupt_stacks[0], - MMU_PAGE_SIZE, MMU_ENTRY_READ, Z_X86_MMU_RW, - true); + for (int i = 0; i < CONFIG_MP_NUM_CPUS; i++) { + z_x86_set_stack_guard(z_interrupt_stacks[i]); + } #endif #if defined(CONFIG_SMP) diff --git a/arch/x86/core/reboot_rst_cnt.c b/arch/x86/core/reboot_rst_cnt.c index a4fa94529a25ab..1de24fbb348944 100644 --- a/arch/x86/core/reboot_rst_cnt.c +++ b/arch/x86/core/reboot_rst_cnt.c @@ -22,7 +22,7 @@ static inline void cold_reboot(void) { - u8_t reset_value = X86_RST_CNT_CPU_RST | X86_RST_CNT_SYS_RST | + uint8_t reset_value = X86_RST_CNT_CPU_RST | X86_RST_CNT_SYS_RST | X86_RST_CNT_FULL_RST; sys_out8(reset_value, X86_RST_CNT_REG); } diff --git a/arch/x86/core/spec_ctrl.c b/arch/x86/core/spec_ctrl.c index 8603dba6e4302d..6e19953ee59001 100644 --- a/arch/x86/core/spec_ctrl.c +++ b/arch/x86/core/spec_ctrl.c @@ -25,9 +25,9 @@ #define CPUID_SPEC_CTRL_IBRS BIT(26) #if defined(CONFIG_DISABLE_SSBD) || defined(CONFIG_ENABLE_EXTENDED_IBRS) -static u32_t cpuid_extended_features(void) +static uint32_t cpuid_extended_features(void) { - u32_t eax, ebx, ecx = 0U, edx; + uint32_t eax, ebx, ecx = 0U, edx; if (__get_cpuid(CPUID_EXTENDED_FEATURES_LVL, &eax, &ebx, &ecx, &edx) == 0) { @@ -37,12 +37,12 @@ static u32_t cpuid_extended_features(void) return edx; } -static int spec_ctrl_init(struct device *dev) +static int spec_ctrl_init(const struct device *dev) { ARG_UNUSED(dev); - u32_t enable_bits = 0U; - u32_t cpuid7 = cpuid_extended_features(); + uint32_t enable_bits = 0U; + uint32_t cpuid7 = cpuid_extended_features(); #ifdef CONFIG_DISABLE_SSBD if ((cpuid7 & CPUID_SPEC_CTRL_SSBD) != 0U) { @@ -55,7 +55,7 @@ static int spec_ctrl_init(struct device *dev) } #endif if (enable_bits != 0U) { - u64_t cur = z_x86_msr_read(X86_SPEC_CTRL_MSR); + uint64_t cur = z_x86_msr_read(X86_SPEC_CTRL_MSR); z_x86_msr_write(X86_SPEC_CTRL_MSR, cur | enable_bits); diff --git a/arch/x86/core/tls.c b/arch/x86/core/tls.c new file mode 100644 index 00000000000000..6e5afcf4424600 --- /dev/null +++ b/arch/x86/core/tls.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) +{ + /* + * TLS area for x86 and x86_64 has the data/bss first, + * then a pointer pointing to itself. The address to + * this pointer needs to be stored in register GS (x86) + * or FS (x86_64). GCC generates code which reads this + * pointer and offsets from this pointer are used to + * access data. + */ + + uintptr_t *self_ptr; + + /* + * Since we are populating things backwards, store + * the pointer to the TLS area at top of stack. + */ + stack_ptr -= sizeof(uintptr_t); + self_ptr = (void *)stack_ptr; + *self_ptr = POINTER_TO_UINT(stack_ptr); + + /* + * Set thread TLS pointer as this is used to populate + * FS/GS at context switch. + */ + new_thread->tls = POINTER_TO_UINT(self_ptr); + + /* Setup the TLS data */ + stack_ptr -= z_tls_data_size(); + z_tls_copy(stack_ptr); + + return (z_tls_data_size() + sizeof(uintptr_t)); +} diff --git a/arch/x86/core/userspace.c b/arch/x86/core/userspace.c index 2e737d406489f4..98027ff50fa1b1 100644 --- a/arch/x86/core/userspace.c +++ b/arch/x86/core/userspace.c @@ -9,31 +9,17 @@ #include #include #include +#include #ifndef CONFIG_X86_KPTI -/* Change to new set of page tables. ONLY intended for use from - * z_x88_swap_update_page_tables(). This changes CR3, no memory access - * afterwards is legal unless it is known for sure that the relevant - * mappings are identical wrt supervisor mode until we iret out. - */ -static inline void page_tables_set(struct x86_page_tables *ptables) -{ -#ifdef CONFIG_X86_64 - __asm__ volatile("movq %0, %%cr3\n\t" : : "r" (ptables) : "memory"); -#else - __asm__ volatile("movl %0, %%cr3\n\t" : : "r" (ptables) : "memory"); -#endif -} - /* Update the to the incoming thread's page table, and update the location of * the privilege elevation stack. * - * May be called ONLY during context switch and when supervisor threads drop - * synchronously to user mode. Hot code path! + * May be called ONLY during context switch. Hot code path! * * Nothing to do here if KPTI is enabled. We are in supervisor mode, so the * active page tables are the kernel's page tables. If the incoming thread is - * in user mode we are going to switch CR3 to the thread-specific tables when + * in user mode we are going to switch CR3 to the domain-specific tables when * we go through z_x86_trampoline_to_user. * * We don't need to update the privilege mode initial stack pointer either, @@ -43,44 +29,31 @@ static inline void page_tables_set(struct x86_page_tables *ptables) */ void z_x86_swap_update_page_tables(struct k_thread *incoming) { - struct x86_page_tables *ptables; - #ifndef CONFIG_X86_64 - /* 64-bit uses syscall/sysret which switches stacks manually, - * tss64.psp is updated unconditionally in __resume + /* Set initial stack pointer when elevating privileges from Ring 3 + * to Ring 0. */ - if ((incoming->base.user_options & K_USER) != 0) { - _main_tss.esp0 = (uintptr_t)incoming->arch.psp; - } + _main_tss.esp0 = (uintptr_t)incoming->arch.psp; #endif +#ifdef CONFIG_X86_COMMON_PAGE_TABLE + z_x86_swap_update_common_page_table(incoming); +#else /* Check first that we actually need to do this, since setting * CR3 involves an expensive full TLB flush. */ - ptables = z_x86_thread_page_tables_get(incoming); + uintptr_t ptables_phys = incoming->arch.ptables; - if (ptables != z_x86_page_tables_get()) { - page_tables_set(ptables); + __ASSERT(ptables_phys != 0, "NULL page tables for thread %p\n", + incoming); + + if (ptables_phys != z_x86_cr3_get()) { + z_x86_cr3_set(ptables_phys); } +#endif /* CONFIG_X86_COMMON_PAGE_TABLE */ } #endif /* CONFIG_X86_KPTI */ -FUNC_NORETURN static void drop_to_user(k_thread_entry_t user_entry, - void *p1, void *p2, void *p3) -{ - u32_t stack_end; - - /* Transition will reset stack pointer to initial, discarding - * any old context since this is a one-way operation - */ - stack_end = Z_STACK_PTR_ALIGN(_current->stack_info.start + - _current->stack_info.size); - - z_x86_userspace_enter(user_entry, p1, p2, p3, stack_end, - _current->stack_info.start); - CODE_UNREACHABLE; -} - /* Preparation steps needed for all threads if user mode is turned on. * * Returns the initial entry point to swap into. @@ -94,11 +67,17 @@ void *z_x86_userspace_prepare_thread(struct k_thread *thread) thread->arch.psp = header->privilege_stack + sizeof(header->privilege_stack); +#ifndef CONFIG_X86_COMMON_PAGE_TABLE + /* Important this gets cleared, so that arch_mem_domain_* APIs + * can distinguish between new threads, and threads migrating + * between domains + */ + thread->arch.ptables = (uintptr_t)NULL; +#endif /* CONFIG_X86_COMMON_PAGE_TABLE */ + if ((thread->base.user_options & K_USER) != 0U) { - z_x86_thread_pt_init(thread); - initial_entry = drop_to_user; + initial_entry = arch_user_mode_enter; } else { - thread->arch.ptables = &z_x86_kernel_ptables; initial_entry = z_thread_entry; } @@ -108,31 +87,16 @@ void *z_x86_userspace_prepare_thread(struct k_thread *thread) FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, void *p1, void *p2, void *p3) { - z_x86_thread_pt_init(_current); - - /* Apply memory domain configuration, if assigned. Threads that - * started in user mode already had this done via z_setup_new_thread() - */ - if (_current->mem_domain_info.mem_domain != NULL) { - z_x86_apply_mem_domain(_current->arch.ptables, - _current->mem_domain_info.mem_domain); - } + uint32_t stack_end; -#ifndef CONFIG_X86_KPTI - /* We're synchronously dropping into user mode from a thread that - * used to be in supervisor mode. K_USER flag has now been set, but - * Need to swap from the kernel's page tables to the per-thread page - * tables. - * - * Safe to update page tables from here, all tables are identity- - * mapped and memory areas used before the ring 3 transition all - * have the same attributes wrt supervisor mode access. - * - * Threads that started in user mode already had this applied on - * initial context switch. + /* Transition will reset stack pointer to initial, discarding + * any old context since this is a one-way operation */ - z_x86_swap_update_page_tables(_current); -#endif + stack_end = Z_STACK_PTR_ALIGN(_current->stack_info.start + + _current->stack_info.size - + _current->stack_info.delta); - drop_to_user(user_entry, p1, p2, p3); + z_x86_userspace_enter(user_entry, p1, p2, p3, stack_end, + _current->stack_info.start); + CODE_UNREACHABLE; } diff --git a/arch/x86/core/x86_mmu.c b/arch/x86/core/x86_mmu.c index f06c97114382f9..4a8d1bb48ed126 100644 --- a/arch/x86/core/x86_mmu.c +++ b/arch/x86/core/x86_mmu.c @@ -1,189 +1,478 @@ /* * Copyright (c) 2011-2014 Wind River Systems, Inc. - * Copyright (c) 2017 Intel Corporation + * Copyright (c) 2017-2020 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ + #include #include -#include -#include -#include -#include -#include -#include +#include +#include #include -LOG_MODULE_DECLARE(os); +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); -#define PHYS_RAM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) -#define PHYS_RAM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) +/* We will use some ignored bits in the PTE to backup permission settings + * when the mapping was made. This is used to un-apply memory domain memory + * partitions to page tables when the partitions are removed. + */ +#define MMU_RW_ORIG MMU_IGNORED0 +#define MMU_US_ORIG MMU_IGNORED1 +#define MMU_XD_ORIG MMU_IGNORED2 + +/* Bits in the PTE that form the set of permission bits, when resetting */ +#define MASK_PERM (MMU_RW | MMU_US | MMU_XD) -/* Despite our use of PAE page tables, we do not (and will never) actually - * support PAE. Use a 64-bit x86 target if you have that much RAM. +/* When we want to set up a new mapping, discarding any previous state */ +#define MASK_ALL (~((pentry_t)0U)) + +/* Bits to set at mapping time for particular permissions. We set the actual + * page table bit effecting the policy and also the backup bit. + */ +#define ENTRY_RW (MMU_RW | MMU_RW_ORIG) +#define ENTRY_US (MMU_US | MMU_US_ORIG) +#define ENTRY_XD (MMU_XD | MMU_XD_ORIG) + +/* Bit position which is always zero in a PTE. We'll use the PAT bit. + * This helps disambiguate PTEs that do not have the Present bit set (MMU_P): + * - If the entire entry is zero, it's an un-mapped virtual page + * - If PTE_ZERO is set, we flipped this page due to KPTI + * - Otherwise, this was a page-out */ -BUILD_ASSERT(PHYS_RAM_ADDR + PHYS_RAM_SIZE - 1ULL <= - (unsigned long long)UINTPTR_MAX); +#define PTE_ZERO MMU_PAT -/* Common regions for all x86 processors. - * Peripheral I/O ranges configured at the SOC level +/* Protects x86_domain_list and serializes instantiation of intermediate + * paging structures. */ +static struct k_spinlock x86_mmu_lock; -/* Mark text and rodata as read-only. - * Userspace may read all text and rodata. +#if defined(CONFIG_USERSPACE) && !defined(CONFIG_X86_COMMON_PAGE_TABLE) +/* List of all active and initialized memory domains. This is used to make + * sure all memory mappings are the same across all page tables when invoking + * range_map() */ -MMU_BOOT_REGION(&_image_text_start, &_image_text_size, - Z_X86_MMU_US); +static sys_slist_t x86_domain_list; +#endif -MMU_BOOT_REGION(&_image_rodata_start, &_image_rodata_size, - Z_X86_MMU_US | Z_X86_MMU_XD); +/* + * Definitions for building an ontology of paging levels and capabilities + * at each level + */ -#ifdef CONFIG_USERSPACE -MMU_BOOT_REGION(&_app_smem_start, &_app_smem_size, - Z_X86_MMU_RW | Z_X86_MMU_XD); +/* Data structure describing the characteristics of a particular paging + * level + */ +struct paging_level { + /* What bits are used to store physical address */ + pentry_t mask; + + /* Number of entries in this paging structure */ + size_t entries; + + /* How many bits to right-shift a virtual address to obtain the + * appropriate entry within this table. + * + * The memory scope of each entry in this table is 1 << shift. + */ + unsigned int shift; +#ifdef CONFIG_EXCEPTION_DEBUG + /* Name of this level, for debug purposes */ + const char *name; +#endif +}; + +/* Flags for all entries in intermediate paging levels. + * Fortunately, the same bits are set for all intermediate levels for all + * three paging modes. + * + * Obviously P is set. + * + * We want RW and US bit always set; actual access control will be + * done at the leaf level. + * + * XD (if supported) always 0. Disabling execution done at leaf level. + * + * PCD/PWT always 0. Caching properties again done at leaf level. + */ +#define INT_FLAGS (MMU_P | MMU_RW | MMU_US) + +/* Paging level ontology for the selected paging mode. + * + * See Figures 4-4, 4-7, 4-11 in the Intel SDM, vol 3A + */ +static const struct paging_level paging_levels[] = { +#ifdef CONFIG_X86_64 + /* Page Map Level 4 */ + { + .mask = 0x7FFFFFFFFFFFF000ULL, + .entries = 512U, + .shift = 39U, +#ifdef CONFIG_EXCEPTION_DEBUG + .name = "PML4" #endif + }, +#endif /* CONFIG_X86_64 */ +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) + /* Page Directory Pointer Table */ + { + .mask = 0x7FFFFFFFFFFFF000ULL, +#ifdef CONFIG_X86_64 + .entries = 512U, +#else + /* PAE version */ + .entries = 4U, +#endif + .shift = 30U, +#ifdef CONFIG_EXCEPTION_DEBUG + .name = "PDPT" +#endif + }, +#endif /* CONFIG_X86_64 || CONFIG_X86_PAE */ + /* Page Directory */ + { +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) + .mask = 0x7FFFFFFFFFFFF000ULL, + .entries = 512U, + .shift = 21U, +#else + /* 32-bit */ + .mask = 0xFFFFF000U, + .entries = 1024U, + .shift = 22U, +#endif /* CONFIG_X86_64 || CONFIG_X86_PAE */ +#ifdef CONFIG_EXCEPTION_DEBUG + .name = "PD" +#endif + }, + /* Page Table */ + { +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) + .mask = 0x07FFFFFFFFFFF000ULL, + .entries = 512U, + .shift = 12U, +#else + /* 32-bit */ + .mask = 0xFFFFF000U, + .entries = 1024U, + .shift = 12U, +#endif /* CONFIG_X86_64 || CONFIG_X86_PAE */ +#ifdef CONFIG_EXCEPTION_DEBUG + .name = "PT" +#endif + } +}; + +#define NUM_LEVELS ARRAY_SIZE(paging_levels) +#define PTE_LEVEL (NUM_LEVELS - 1) + +/* + * Macros for reserving space for page tables + * + * We need to reserve a block of memory equal in size to the page tables + * generated by gen_mmu.py so that memory addresses do not shift between + * build phases. These macros ultimately specify INITIAL_PAGETABLE_SIZE. + */ +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) +#ifdef CONFIG_X86_64 +#define NUM_PML4_ENTRIES 512U +#define NUM_PDPT_ENTRIES 512U +#else +#define NUM_PDPT_ENTRIES 4U +#endif /* CONFIG_X86_64 */ +#define NUM_PD_ENTRIES 512U +#define NUM_PT_ENTRIES 512U +#else +#define NUM_PD_ENTRIES 1024U +#define NUM_PT_ENTRIES 1024U +#endif /* !CONFIG_X86_64 && !CONFIG_X86_PAE */ +/* Memory range covered by an instance of various table types */ +#define PT_AREA ((uintptr_t)(CONFIG_MMU_PAGE_SIZE * NUM_PT_ENTRIES)) +#define PD_AREA (PT_AREA * NUM_PD_ENTRIES) +#ifdef CONFIG_X86_64 +#define PDPT_AREA (PD_AREA * NUM_PDPT_ENTRIES) +#endif + +#define VM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) +#define VM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) + +/* Define a range [PT_START, PT_END) which is the memory range + * covered by all the page tables needed for system RAM + */ +#define PT_START ((uintptr_t)ROUND_DOWN(VM_ADDR, PT_AREA)) +#define PT_END ((uintptr_t)ROUND_UP(VM_ADDR + VM_SIZE, PT_AREA)) -#ifdef CONFIG_COVERAGE_GCOV -MMU_BOOT_REGION(&__gcov_bss_start, &__gcov_bss_size, - Z_X86_MMU_RW | Z_X86_MMU_US | Z_X86_MMU_XD); +/* Number of page tables needed to cover system RAM. Depends on the specific + * bounds of system RAM, but roughly 1 page table per 2MB of RAM + */ +#define NUM_PT ((PT_END - PT_START) / PT_AREA) + +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) +/* Same semantics as above, but for the page directories needed to cover + * system RAM. + */ +#define PD_START ((uintptr_t)ROUND_DOWN(VM_ADDR, PD_AREA)) +#define PD_END ((uintptr_t)ROUND_UP(VM_ADDR + VM_SIZE, PD_AREA)) +/* Number of page directories needed to cover system RAM. Depends on the + * specific bounds of system RAM, but roughly 1 page directory per 1GB of RAM + */ +#define NUM_PD ((PD_END - PD_START) / PD_AREA) +#else +/* 32-bit page tables just have one toplevel page directory */ +#define NUM_PD 1 #endif #ifdef CONFIG_X86_64 -extern char _locore_start[]; -extern char _locore_size[]; -extern char _lorodata_start[]; -extern char _lorodata_size[]; -extern char _lodata_start[]; -extern char _lodata_size[]; - -/* Early boot regions that need to be in low memory to be comprehensible - * by the CPU in 16-bit mode +/* Same semantics as above, but for the page directory pointer tables needed + * to cover system RAM. On 32-bit there is just one 4-entry PDPT. + */ +#define PDPT_START ((uintptr_t)ROUND_DOWN(VM_ADDR, PDPT_AREA)) +#define PDPT_END ((uintptr_t)ROUND_UP(VM_ADDR + VM_SIZE, PDPT_AREA)) +/* Number of PDPTs needed to cover system RAM. Depends on the + * specific bounds of system RAM, but roughly 1 PDPT per 512GB of RAM + */ +#define NUM_PDPT ((PDPT_END - PDPT_START) / PDPT_AREA) + +/* All pages needed for page tables, using computed values plus one more for + * the top-level PML4 */ +#define NUM_TABLE_PAGES (NUM_PT + NUM_PD + NUM_PDPT + 1) +#else /* !CONFIG_X86_64 */ +/* Number of pages we need to reserve in the stack for per-thread page tables */ +#define NUM_TABLE_PAGES (NUM_PT + NUM_PD) +#endif /* CONFIG_X86_64 */ -MMU_BOOT_REGION(&_locore_start, &_locore_size, 0); -MMU_BOOT_REGION(&_lorodata_start, &_lorodata_size, Z_X86_MMU_XD); -MMU_BOOT_REGION(&_lodata_start, &_lodata_size, Z_X86_MMU_RW | Z_X86_MMU_XD); +#ifdef CONFIG_X86_PAE +/* Toplevel PDPT wasn't included as it is not a page in size */ +#define INITIAL_PTABLE_SIZE ((NUM_TABLE_PAGES * CONFIG_MMU_PAGE_SIZE) + 0x20) +#else +#define INITIAL_PTABLE_SIZE (NUM_TABLE_PAGES * CONFIG_MMU_PAGE_SIZE) #endif -/* __kernel_ram_size includes all unused memory, which is used for heaps. - * User threads cannot access this unless granted at runtime. This is done - * automatically for stacks. +/* "dummy" pagetables for the first-phase build. The real page tables + * are produced by gen-mmu.py based on data read in zephyr-prebuilt.elf, + * and this dummy array is discarded. */ -MMU_BOOT_REGION(&__kernel_ram_start, &__kernel_ram_size, - Z_X86_MMU_RW | Z_X86_MMU_XD); +Z_GENERIC_SECTION(.dummy_pagetables) +static __used char dummy_pagetables[INITIAL_PTABLE_SIZE]; /* - * Inline functions for setting memory addresses in page table structures + * Utility functions */ -#ifdef CONFIG_X86_64 -static inline void pml4e_update_pdpt(u64_t *pml4e, struct x86_mmu_pdpt *pdpt) +/* For a table at a particular level, get the entry index that corresponds to + * the provided virtual address + */ +static inline int get_index(void *virt, int level) { - uintptr_t pdpt_addr = (uintptr_t)pdpt; + return (((uintptr_t)virt >> paging_levels[level].shift) % + paging_levels[level].entries); +} - *pml4e = ((*pml4e & ~Z_X86_MMU_PML4E_PDPT_MASK) | - (pdpt_addr & Z_X86_MMU_PML4E_PDPT_MASK)); +static inline pentry_t *get_entry_ptr(pentry_t *ptables, void *virt, int level) +{ + return &ptables[get_index(virt, level)]; } -#endif /* CONFIG_X86_64 */ -static inline void pdpte_update_pd(u64_t *pdpte, struct x86_mmu_pd *pd) +static inline pentry_t get_entry(pentry_t *ptables, void *virt, int level) { - uintptr_t pd_addr = (uintptr_t)pd; + return ptables[get_index(virt, level)]; +} -#ifdef CONFIG_X86_64 - __ASSERT((*pdpte & Z_X86_MMU_PS) == 0, "PDPT is for 1GB page"); -#endif - *pdpte = ((*pdpte & ~Z_X86_MMU_PDPTE_PD_MASK) | - (pd_addr & Z_X86_MMU_PDPTE_PD_MASK)); +/* Get the physical memory address associated with this table entry */ +static inline uintptr_t get_entry_phys(pentry_t entry, int level) +{ + return entry & paging_levels[level].mask; } -static inline void pde_update_pt(u64_t *pde, struct x86_mmu_pt *pt) +/* Return the virtual address of a linked table stored in the provided entry */ +static inline pentry_t *next_table(pentry_t entry, int level) { - uintptr_t pt_addr = (uintptr_t)pt; + return (pentry_t *)(get_entry_phys(entry, level)); +} - __ASSERT((*pde & Z_X86_MMU_PS) == 0, "pde is for 2MB page"); +/* Number of table entries at this level */ +static inline size_t get_num_entries(int level) +{ + return paging_levels[level].entries; +} - *pde = ((*pde & ~Z_X86_MMU_PDE_PT_MASK) | - (pt_addr & Z_X86_MMU_PDE_PT_MASK)); +/* 4K for everything except PAE PDPTs */ +static inline size_t table_size(int level) +{ + return get_num_entries(level) * sizeof(pentry_t); } -static inline void pte_update_addr(u64_t *pte, uintptr_t addr) +/* For a table at a particular level, size of the amount of virtual memory + * that an entry within the table covers + */ +static inline size_t get_entry_scope(int level) { - *pte = ((*pte & ~Z_X86_MMU_PTE_ADDR_MASK) | - (addr & Z_X86_MMU_PTE_ADDR_MASK)); + return (1UL << paging_levels[level].shift); } -/* - * Functions for dumping page tables to console +/* For a table at a particular level, size of the amount of virtual memory + * that this entire table covers */ +static inline size_t get_table_scope(int level) +{ + return get_entry_scope(level) * get_num_entries(level); +} -/* Works for PDPT, PD, PT entries, the bits we check here are all the same. - * - * Not trying to capture every flag, just the most interesting stuff, - * Present, write, XD, user, in typically encountered combinations. +/* Must have checked Present bit first! Non-present entries may have OS data + * stored in any other bits */ -static bool dump_entry_flags(const char *name, u64_t flags) +static inline bool is_leaf(int level, pentry_t entry) { - if ((flags & Z_X86_MMU_P) == 0) { - LOG_ERR("%s: Non-present", name); - return false; + if (level == PTE_LEVEL) { + /* Always true for PTE */ + return true; } - LOG_ERR("%s: 0x%016llx %s, %s, %s", name, flags, - flags & MMU_ENTRY_WRITE ? - "Writable" : "Read-only", - flags & MMU_ENTRY_USER ? - "User" : "Supervisor", - flags & MMU_ENTRY_EXECUTE_DISABLE ? - "Execute Disable" : "Execute Enabled"); - return true; + return ((entry & MMU_PS) != 0U); } -void z_x86_dump_mmu_flags(struct x86_page_tables *ptables, uintptr_t addr) +/* This does NOT (by design) un-flip KPTI PTEs, it's just the raw PTE value */ +static inline void pentry_get(int *paging_level, pentry_t *val, + pentry_t *ptables, void *virt) { - u64_t entry; + pentry_t *table = ptables; -#ifdef CONFIG_X86_64 - entry = *z_x86_get_pml4e(ptables, addr); - if (!dump_entry_flags("PML4E", entry)) { - return; - } + for (int level = 0; level < NUM_LEVELS; level++) { + pentry_t entry = get_entry(table, virt, level); - entry = *z_x86_pdpt_get_pdpte(z_x86_pml4e_get_pdpt(entry), addr); - if (!dump_entry_flags("PDPTE", entry)) { - return; + if ((entry & MMU_P) == 0 || is_leaf(level, entry)) { + *val = entry; + if (paging_level != NULL) { + *paging_level = level; + } + break; + } else { + table = next_table(entry, level); + } } +} + +static inline void tlb_flush_page(void *addr) +{ + /* Invalidate TLB entries corresponding to the page containing the + * specified address + */ + char *page = (char *)addr; + + __asm__ ("invlpg %0" :: "m" (*page)); +} + +#ifdef CONFIG_X86_KPTI +static inline bool is_flipped_pte(pentry_t pte) +{ + return (pte & MMU_P) == 0 && (pte & PTE_ZERO) != 0; +} +#endif + +#if defined(CONFIG_SMP) +void z_x86_tlb_ipi(const void *arg) +{ + uintptr_t ptables; + + ARG_UNUSED(arg); + +#ifdef CONFIG_X86_KPTI + /* We're always on the kernel's set of page tables in this context + * if KPTI is turned on + */ + ptables = z_x86_cr3_get(); + __ASSERT(ptables == (uintptr_t)&z_x86_kernel_ptables, ""); #else - /* 32-bit doesn't have anything interesting in the PDPTE except - * the present bit + /* We might have been moved to another memory domain, so always invoke + * z_x86_thread_page_tables_get() instead of using current CR3 value. */ - entry = *z_x86_get_pdpte(ptables, addr); - if ((entry & Z_X86_MMU_P) == 0) { - LOG_ERR("PDPTE: Non-present"); - return; - } + ptables = (uintptr_t)z_x86_thread_page_tables_get(_current); #endif + /* + * In the future, we can consider making this smarter, such as + * propagating which page tables were modified (in case they are + * not active on this CPU) or an address range to call + * tlb_flush_page() on. + */ + LOG_DBG("%s on CPU %d\n", __func__, arch_curr_cpu()->id); - entry = *z_x86_pd_get_pde(z_x86_pdpte_get_pd(entry), addr); - if (!dump_entry_flags(" PDE", entry)) { - return; - } + z_x86_cr3_set(ptables); +} - entry = *z_x86_pt_get_pte(z_x86_pde_get_pt(entry), addr); - if (!dump_entry_flags(" PTE", entry)) { - return; - } +/* NOTE: This is not synchronous and the actual flush takes place some short + * time after this exits. + */ +static inline void tlb_shootdown(void) +{ + z_loapic_ipi(0, LOAPIC_ICR_IPI_OTHERS, CONFIG_TLB_IPI_VECTOR); +} +#endif /* CONFIG_SMP */ + +static inline void assert_addr_aligned(uintptr_t addr) +{ +#if __ASSERT_ON + __ASSERT((addr & (CONFIG_MMU_PAGE_SIZE - 1)) == 0U, + "unaligned address 0x%" PRIxPTR, addr); +#endif +} + +static inline void assert_virt_addr_aligned(void *addr) +{ + assert_addr_aligned((uintptr_t)addr); +} + +static inline void assert_region_page_aligned(void *addr, size_t size) +{ + assert_virt_addr_aligned(addr); +#if __ASSERT_ON + __ASSERT((size & (CONFIG_MMU_PAGE_SIZE - 1)) == 0U, + "unaligned size %zu", size); +#endif } -static char get_entry_code(u64_t value) +/* + * Debug functions. All conditionally compiled with CONFIG_EXCEPTION_DEBUG. + */ +#ifdef CONFIG_EXCEPTION_DEBUG + +/* Add colors to page table dumps to indicate mapping type */ +#define COLOR_PAGE_TABLES 1 + +#if COLOR_PAGE_TABLES +#define ANSI_DEFAULT "\x1B[0m" +#define ANSI_RED "\x1B[1;31m" +#define ANSI_GREEN "\x1B[1;32m" +#define ANSI_YELLOW "\x1B[1;33m" +#define ANSI_BLUE "\x1B[1;34m" +#define ANSI_MAGENTA "\x1B[1;35m" +#define ANSI_CYAN "\x1B[1;36m" +#define ANSI_GREY "\x1B[1;90m" + +#define COLOR(x) printk(_CONCAT(ANSI_, x)) +#else +#define COLOR(x) do { } while (0) +#endif + +static char get_entry_code(pentry_t value) { char ret; - if ((value & Z_X86_MMU_P) == 0) { + if (value == 0U) { + /* Unmapped entry */ ret = '.'; } else { - if ((value & Z_X86_MMU_RW) != 0) { + if ((value & MMU_RW) != 0U) { /* Writable page */ - if ((value & Z_X86_MMU_XD) != 0) { + if ((value & MMU_XD) != 0U) { /* RW */ ret = 'w'; } else { @@ -191,7 +480,7 @@ static char get_entry_code(u64_t value) ret = 'a'; } } else { - if ((value & Z_X86_MMU_XD) != 0) { + if ((value & MMU_XD) != 0U) { /* R */ ret = 'r'; } else { @@ -200,7 +489,7 @@ static char get_entry_code(u64_t value) } } - if ((value & Z_X86_MMU_US) != 0) { + if ((value & MMU_US) != 0U) { /* Uppercase indicates user mode access */ ret = toupper(ret); } @@ -209,12 +498,61 @@ static char get_entry_code(u64_t value) return ret; } -static void print_entries(u64_t entries_array[], size_t count) +static void print_entries(pentry_t entries_array[], uint8_t *base, int level, + size_t count) { int column = 0; for (int i = 0; i < count; i++) { - printk("%c", get_entry_code(entries_array[i])); + pentry_t entry = entries_array[i]; + + uintptr_t phys = get_entry_phys(entry, level); + uintptr_t virt = + (uintptr_t)base + (get_entry_scope(level) * i); + + if (entry & MMU_P) { + if (is_leaf(level, entry)) { + if (phys == virt) { + /* Identity mappings */ + COLOR(YELLOW); + } else { + /* Other mappings */ + COLOR(GREEN); + } + } else { + /* Intermediate entry */ + COLOR(MAGENTA); + } + } else { + if (is_leaf(level, entry)) { + if (entry == 0U) { + /* Unmapped */ + COLOR(GREY); +#ifdef CONFIG_X86_KPTI + } else if (is_flipped_pte(entry)) { + /* KPTI, un-flip it */ + COLOR(BLUE); + entry = ~entry; + phys = get_entry_phys(entry, level); + if (phys == virt) { + /* Identity mapped */ + COLOR(CYAN); + } else { + /* Non-identity mapped */ + COLOR(BLUE); + } +#endif + } else { + /* Paged out */ + COLOR(RED); + } + } else { + /* Un-mapped intermediate entry */ + COLOR(GREY); + } + } + + printk("%c", get_entry_code(entry)); column++; if (column == 64) { @@ -222,1043 +560,1216 @@ static void print_entries(u64_t entries_array[], size_t count) printk("\n"); } } + COLOR(DEFAULT); if (column != 0) { printk("\n"); } } -static void z_x86_dump_pt(struct x86_mmu_pt *pt, uintptr_t base, int index) +static void dump_ptables(pentry_t *table, uint8_t *base, int level) { - printk("Page table %d for 0x%016lX - 0x%016lX at %p\n", - index, base, base + Z_X86_PT_AREA - 1, pt); + const struct paging_level *info = &paging_levels[level]; - print_entries(pt->entry, Z_X86_NUM_PT_ENTRIES); -} +#ifdef CONFIG_X86_64 + /* Account for the virtual memory "hole" with sign-extension */ + if (((uintptr_t)base & BITL(47)) != 0) { + base = (uint8_t *)((uintptr_t)base | (0xFFFFULL << 48)); + } +#endif -static void z_x86_dump_pd(struct x86_mmu_pd *pd, uintptr_t base, int index) -{ - printk("Page directory %d for 0x%016lX - 0x%016lX at %p\n", - index, base, base + Z_X86_PD_AREA - 1, pd); + printk("%s at %p: ", info->name, table); + if (level == 0) { + printk("entire address space\n"); + } else { + printk("for %p - %p\n", base, + base + get_table_scope(level) - 1); + } + + print_entries(table, base, level, info->entries); - print_entries(pd->entry, Z_X86_NUM_PD_ENTRIES); + /* Check if we're a page table */ + if (level == PTE_LEVEL) { + return; + } - for (int i = 0; i < Z_X86_NUM_PD_ENTRIES; i++) { - struct x86_mmu_pt *pt; - u64_t pde = pd->entry[i]; + /* Dump all linked child tables */ + for (int j = 0; j < info->entries; j++) { + pentry_t entry = table[j]; + pentry_t *next; - if (((pde & Z_X86_MMU_P) == 0) || ((pde & Z_X86_MMU_PS) != 0)) { - /* Skip non-present, or 2MB directory entries, there's - * no page table to examine */ + if ((entry & MMU_P) == 0U || + (entry & MMU_PS) != 0U) { + /* Not present or big page, skip */ continue; } - pt = z_x86_pde_get_pt(pde); - z_x86_dump_pt(pt, base + (i * Z_X86_PT_AREA), i); + next = next_table(entry, level); + dump_ptables(next, base + (j * get_entry_scope(level)), + level + 1); } } -static void z_x86_dump_pdpt(struct x86_mmu_pdpt *pdpt, uintptr_t base, - int index) +void z_x86_dump_page_tables(pentry_t *ptables) { - printk("Page directory pointer table %d for 0x%0816lX - 0x%016lX at %p\n", - index, base, base + Z_X86_PDPT_AREA - 1, pdpt); - - print_entries(pdpt->entry, Z_X86_NUM_PDPT_ENTRIES); - - for (int i = 0; i < Z_X86_NUM_PDPT_ENTRIES; i++) { - struct x86_mmu_pd *pd; - u64_t pdpte = pdpt->entry[i]; - - if ((pdpte & Z_X86_MMU_P) == 0) { - continue; - } -#ifdef CONFIG_X86_64 - if ((pdpte & Z_X86_MMU_PS) != 0) { - continue; - } -#endif - pd = z_x86_pdpte_get_pd(pdpte); - z_x86_dump_pd(pd, base + (i * Z_X86_PD_AREA), i); - } + dump_ptables(ptables, NULL, 0); } -#ifdef CONFIG_X86_64 -static void z_x86_dump_pml4(struct x86_mmu_pml4 *pml4) +/* Enable to dump out the kernel's page table right before main() starts, + * sometimes useful for deep debugging. May overwhelm twister. + */ +#define DUMP_PAGE_TABLES 0 + +#if DUMP_PAGE_TABLES +static int dump_kernel_tables(const struct device *unused) { - printk("Page mapping level 4 at %p for all memory addresses\n", pml4); + z_x86_dump_page_tables(z_x86_kernel_ptables); - print_entries(pml4->entry, Z_X86_NUM_PML4_ENTRIES); + return 0; +} - for (int i = 0; i < Z_X86_NUM_PML4_ENTRIES; i++) { - struct x86_mmu_pdpt *pdpt; - u64_t pml4e = pml4->entry[i]; +SYS_INIT(dump_kernel_tables, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +#endif - if ((pml4e & Z_X86_MMU_P) == 0) { - continue; - } +static void str_append(char **buf, size_t *size, const char *str) +{ + int ret = snprintk(*buf, *size, "%s", str); - pdpt = z_x86_pml4e_get_pdpt(pml4e); - z_x86_dump_pdpt(pdpt, i * Z_X86_PDPT_AREA, i); + if (ret >= *size) { + /* Truncated */ + *size = 0U; + } else { + *size -= ret; + *buf += ret; } + } -void z_x86_dump_page_tables(struct x86_page_tables *ptables) +static void dump_entry(int level, void *virt, pentry_t entry) { - z_x86_dump_pml4(z_x86_get_pml4(ptables)); + const struct paging_level *info = &paging_levels[level]; + char buf[24] = { 0 }; + char *pos = buf; + size_t sz = sizeof(buf); + uint8_t *virtmap = (uint8_t *)ROUND_DOWN(virt, get_entry_scope(level)); + + #define DUMP_BIT(bit) do { \ + if ((entry & MMU_##bit) != 0U) { \ + str_append(&pos, &sz, #bit " "); \ + } \ + } while (0) + + DUMP_BIT(RW); + DUMP_BIT(US); + DUMP_BIT(PWT); + DUMP_BIT(PCD); + DUMP_BIT(A); + DUMP_BIT(D); + DUMP_BIT(G); + DUMP_BIT(XD); + + LOG_ERR("%sE: %p -> " PRI_ENTRY ": %s", info->name, + virtmap, entry & info->mask, log_strdup(buf)); + + #undef DUMP_BIT } -#else -void z_x86_dump_page_tables(struct x86_page_tables *ptables) +void z_x86_pentry_get(int *paging_level, pentry_t *val, pentry_t *ptables, + void *virt) { - z_x86_dump_pdpt(z_x86_get_pdpt(ptables, 0), 0, 0); + pentry_get(paging_level, val, ptables, virt); } -#endif -void z_x86_mmu_get_flags(struct x86_page_tables *ptables, void *addr, - u64_t *pde_flags, u64_t *pte_flags) +/* + * Debug function for dumping out MMU table information to the LOG for a + * specific virtual address, such as when we get an unexpected page fault. + */ +void z_x86_dump_mmu_flags(pentry_t *ptables, void *virt) { - *pde_flags = *z_x86_get_pde(ptables, (uintptr_t)addr) & - ~Z_X86_MMU_PDE_PT_MASK; + pentry_t entry = 0; + int level = 0; - if ((*pde_flags & Z_X86_MMU_P) != 0) { - *pte_flags = *z_x86_get_pte(ptables, (uintptr_t)addr) & - ~Z_X86_MMU_PTE_ADDR_MASK; + pentry_get(&level, &entry, ptables, virt); + + if ((entry & MMU_P) == 0) { + LOG_ERR("%sE: not present", paging_levels[level].name); } else { - *pte_flags = 0; + dump_entry(level, virt, entry); } } +#endif /* CONFIG_EXCEPTION_DEBUG */ -/* Given an address/size pair, which corresponds to some memory address - * within a table of table_size, return the maximum number of bytes to - * examine so we look just to the end of the table and no further. +/* + * Pool of free memory pages for creating new page tables, as needed. * - * If size fits entirely within the table, just return size. + * XXX: This is very crude, once obtained, pages may not be returned. Tuning + * the optimal value of CONFIG_X86_MMU_PAGE_POOL_PAGES is not intuitive, + * Better to have a kernel managed page pool of unused RAM that can be used for + * this, sbrk(), and other anonymous mappings. See #29526 */ -static size_t get_table_max(uintptr_t addr, size_t size, size_t table_size) -{ - size_t table_remaining; +static uint8_t __noinit + page_pool[CONFIG_MMU_PAGE_SIZE * CONFIG_X86_MMU_PAGE_POOL_PAGES] + __aligned(CONFIG_MMU_PAGE_SIZE); + +static uint8_t *page_pos = page_pool + sizeof(page_pool); - addr &= (table_size - 1); - table_remaining = table_size - addr; +/* Return a zeroed and suitably aligned memory page for page table data + * from the global page pool + */ +static void *page_pool_get(void) +{ + void *ret; - if (size < table_remaining) { - return size; + if (page_pos == page_pool) { + ret = NULL; } else { - return table_remaining; + page_pos -= CONFIG_MMU_PAGE_SIZE; + ret = page_pos; + } + + if (ret != NULL) { + memset(ret, 0, CONFIG_MMU_PAGE_SIZE); } + + return ret; } -/* Range [addr, addr + size) must fall within the bounds of the pt */ -static int x86_mmu_validate_pt(struct x86_mmu_pt *pt, uintptr_t addr, - size_t size, bool write) +/* Debugging function to show how many pages are free in the pool */ +static inline unsigned int pages_free(void) { - uintptr_t pos = addr; - size_t remaining = size; - int ret = 0; - - while (true) { - u64_t pte = *z_x86_pt_get_pte(pt, pos); + return (page_pos - page_pool) / CONFIG_MMU_PAGE_SIZE; +} - if ((pte & Z_X86_MMU_P) == 0 || (pte & Z_X86_MMU_US) == 0 || - (write && (pte & Z_X86_MMU_RW) == 0)) { - ret = -1; - break; - } +/* Reset permissions on a PTE to original state when the mapping was made */ +static inline pentry_t reset_pte(pentry_t old_val) +{ + pentry_t new_val; - if (remaining <= MMU_PAGE_SIZE) { - break; - } + /* Clear any existing state in permission bits */ + new_val = old_val & (~K_MEM_PARTITION_PERM_MASK); - remaining -= MMU_PAGE_SIZE; - pos += MMU_PAGE_SIZE; + /* Now set permissions based on the stashed original values */ + if ((old_val & MMU_RW_ORIG) != 0) { + new_val |= MMU_RW; } - - return ret; + if ((old_val & MMU_US_ORIG) != 0) { + new_val |= MMU_US; + } +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) + if ((old_val & MMU_XD_ORIG) != 0) { + new_val |= MMU_XD; + } +#endif + return new_val; } -/* Range [addr, addr + size) must fall within the bounds of the pd */ -static int x86_mmu_validate_pd(struct x86_mmu_pd *pd, uintptr_t addr, - size_t size, bool write) +/* Wrapper functionsfor some gross stuff we have to do for Kernel + * page table isolation. If these are User mode page tables, the user bit + * isn't set, and this is not the shared page, all the bits in the PTE + * are flipped. This serves three purposes: + * - The page isn't present, implementing page table isolation + * - Flipping the physical address bits cheaply mitigates L1TF + * - State is preserved; to get original PTE, just complement again + */ +static inline pentry_t pte_finalize_value(pentry_t val, bool user_table) { - uintptr_t pos = addr; - size_t remaining = size; - int ret = 0; - size_t to_examine; +#ifdef CONFIG_X86_KPTI + /* Ram is identity-mapped at boot, so phys=virt for this pinned page */ + static const uintptr_t shared_phys_addr = + (uintptr_t)&z_shared_kernel_page_start; - while (remaining) { - u64_t pde = *z_x86_pd_get_pde(pd, pos); + if (user_table && (val & MMU_US) == 0 && (val & MMU_P) != 0 && + get_entry_phys(val, PTE_LEVEL) != shared_phys_addr) { + val = ~val; + } +#endif + return val; +} - if ((pde & Z_X86_MMU_P) == 0 || (pde & Z_X86_MMU_US) == 0 || - (write && (pde & Z_X86_MMU_RW) == 0)) { - ret = -1; - break; - } +/* Atomic functions for modifying PTEs. These don't map nicely to Zephyr's + * atomic API since the only types supported are 'int' and 'void *' and + * the size of pentry_t depends on other factors like PAE. + */ +#ifndef CONFIG_X86_PAE +/* Non-PAE, pentry_t is same size as void ptr so use atomic_ptr_* APIs */ +static inline pentry_t atomic_pte_get(const pentry_t *target) +{ + return (pentry_t)atomic_ptr_get((atomic_ptr_t *)target); +} - to_examine = get_table_max(pos, remaining, Z_X86_PT_AREA); +static inline bool atomic_pte_cas(pentry_t *target, pentry_t old_value, + pentry_t new_value) +{ + return atomic_ptr_cas((atomic_ptr_t *)target, (void *)old_value, + (void *)new_value); +} +#else +/* Atomic builtins for 64-bit values on 32-bit x86 require floating point. + * Don't do this, just lock local interrupts. Needless to say, this + * isn't workable if someone ever adds SMP to the 32-bit x86 port. + */ +BUILD_ASSERT(!IS_ENABLED(CONFIG_SMP)); - if ((pde & Z_X86_MMU_PS) == 0) { - /* Not a 2MB PDE. Need to check all the linked - * tables for this entry - */ - struct x86_mmu_pt *pt; +static inline pentry_t atomic_pte_get(const pentry_t *target) +{ + return *target; +} - pt = z_x86_pde_get_pt(pde); - ret = x86_mmu_validate_pt(pt, pos, to_examine, write); - if (ret != 0) { - break; - } - } else { - ret = 0; - } +static inline bool atomic_pte_cas(pentry_t *target, pentry_t old_value, + pentry_t new_value) +{ + bool ret = false; + int key = arch_irq_lock(); - remaining -= to_examine; - pos += to_examine; + if (*target == old_value) { + *target = new_value; + ret = true; } + arch_irq_unlock(key); return ret; } +#endif /* CONFIG_X86_PAE */ + +/* Indicates that the target page tables will be used by user mode threads. + * This only has implications for CONFIG_X86_KPTI where user thread facing + * page tables need nearly all pages that don't have the US bit to also + * not be Present. + */ +#define OPTION_USER BIT(0) + +/* Indicates that the operation requires TLBs to be flushed as we are altering + * existing mappings. Not needed for establishing new mappings + */ +#define OPTION_FLUSH BIT(1) + +/* Indicates that each PTE's permission bits should be restored to their + * original state when the memory was mapped. All other bits in the PTE are + * preserved. + */ +#define OPTION_RESET BIT(2) + +/* Indicates that allocations from the page pool are allowed to instantiate + * new paging structures. Only necessary when establishing new mappings + * and the entire address space isn't pre-allocated. + */ +#define OPTION_ALLOC BIT(3) -/* Range [addr, addr + size) must fall within the bounds of the pdpt */ -static int x86_mmu_validate_pdpt(struct x86_mmu_pdpt *pdpt, uintptr_t addr, - size_t size, bool write) +/** + * Atomically update bits in a page table entry + * + * This is atomic with respect to modifications by other CPUs or preempted + * contexts, which can be very important when making decisions based on + * the PTE's prior "dirty" state. + * + * @param pte Pointer to page table entry to update + * @param update_val Updated bits to set/clear in PTE. Ignored with + * OPTION_RESET. + * @param update_mask Which bits to modify in the PTE. Ignored with + * OPTION_RESET + * @param options Control flags + * @retval Old PTE value + */ +static inline pentry_t pte_atomic_update(pentry_t *pte, pentry_t update_val, + pentry_t update_mask, + uint32_t options) { - uintptr_t pos = addr; - size_t remaining = size; - int ret = 0; - size_t to_examine; + bool user_table = (options & OPTION_USER) != 0U; + bool reset = (options & OPTION_RESET) != 0U; + pentry_t old_val, new_val; - while (remaining) { - u64_t pdpte = *z_x86_pdpt_get_pdpte(pdpt, pos); + do { + old_val = atomic_pte_get(pte); - if ((pdpte & Z_X86_MMU_P) == 0) { - /* Non-present */ - ret = -1; - break; + new_val = old_val; +#ifdef CONFIG_X86_KPTI + if (is_flipped_pte(new_val)) { + /* Page was flipped for KPTI. Un-flip it */ + new_val = ~new_val; } +#endif /* CONFIG_X86_KPTI */ -#ifdef CONFIG_X86_64 - if ((pdpte & Z_X86_MMU_US) == 0 || - (write && (pdpte & Z_X86_MMU_RW) == 0)) { - ret = -1; - break; + if (reset) { + new_val = reset_pte(new_val); + } else { + new_val = ((new_val & ~update_mask) | + (update_val & update_mask)); } -#endif - to_examine = get_table_max(pos, remaining, Z_X86_PD_AREA); -#ifdef CONFIG_X86_64 - /* Check if 1GB page, if not, examine linked page directory */ - if ((pdpte & Z_X86_MMU_PS) == 0) { -#endif - struct x86_mmu_pd *pd = z_x86_pdpte_get_pd(pdpte); + new_val = pte_finalize_value(new_val, user_table); + } while (atomic_pte_cas(pte, old_val, new_val) == false); - ret = x86_mmu_validate_pd(pd, pos, to_examine, write); - if (ret != 0) { - break; - } -#ifdef CONFIG_X86_64 - } else { - ret = 0; - } -#endif - remaining -= to_examine; - pos += to_examine; +#ifdef CONFIG_X86_KPTI + if (is_flipped_pte(old_val)) { + /* Page was flipped for KPTI. Un-flip it */ + old_val = ~old_val; } +#endif /* CONFIG_X86_KPTI */ - return ret; + return old_val; } -#ifdef CONFIG_X86_64 -static int x86_mmu_validate_pml4(struct x86_mmu_pml4 *pml4, uintptr_t addr, - size_t size, bool write) +/** + * Low level page table update function for a virtual page + * + * For the provided set of page tables, update the PTE associated with the + * virtual address to a new value, using the mask to control what bits + * need to be preserved. + * + * It is permitted to set up mappings without the Present bit set, in which + * case all other bits may be used for OS accounting. + * + * This function is atomic with respect to the page table entries being + * modified by another CPU, using atomic operations to update the requested + * bits and return the previous PTE value. + * + * This function is NOT atomic with respect to allocating intermediate + * paging structures, and this must be called with x86_mmu_lock held if + * OPTION_ALLOC is used. + * + * Common mask values: + * MASK_ALL - Update all PTE bits. Exitsing state totally discarded. + * MASK_PERM - Only update permission bits. All other bits and physical + * mapping preserved. + * + * @param ptables Page tables to modify + * @param virt Virtual page table entry to update + * @param entry_val Value to update in the PTE (ignored if OPTION_RESET) + * @param [out] old_val_ptr Filled in with previous PTE value. May be NULL. + * @param mask What bits to update in the PTE (ignored if OPTION_RESET) + * @param options Control options, described above + * @retval 0 Success + * @retval -ENOMEM allocation required and no free pages (only if OPTION_ALLOC) + */ +static int page_map_set(pentry_t *ptables, void *virt, pentry_t entry_val, + pentry_t *old_val_ptr, pentry_t mask, uint32_t options) { - uintptr_t pos = addr; - size_t remaining = size; - int ret = 0; - size_t to_examine; + pentry_t *table = ptables; + bool flush = (options & OPTION_FLUSH) != 0U; - while (remaining) { - u64_t pml4e = *z_x86_pml4_get_pml4e(pml4, pos); - struct x86_mmu_pdpt *pdpt; + assert_virt_addr_aligned(virt); - if ((pml4e & Z_X86_MMU_P) == 0 || (pml4e & Z_X86_MMU_US) == 0 || - (write && (pml4e & Z_X86_MMU_RW) == 0)) { - ret = -1; - break; - } + for (int level = 0; level < NUM_LEVELS; level++) { + int index; + pentry_t *entryp; - to_examine = get_table_max(pos, remaining, Z_X86_PDPT_AREA); - pdpt = z_x86_pml4e_get_pdpt(pml4e); + index = get_index(virt, level); + entryp = &table[index]; - ret = x86_mmu_validate_pdpt(pdpt, pos, to_examine, write); - if (ret != 0) { + /* Check if we're a PTE */ + if (level == PTE_LEVEL) { + pentry_t old_val = pte_atomic_update(entryp, entry_val, + mask, options); + if (old_val_ptr != NULL) { + *old_val_ptr = old_val; + } break; } - remaining -= to_examine; - pos += to_examine; - } - - return ret; -} -#endif /* CONFIG_X86_64 */ - -int z_x86_mmu_validate(struct x86_page_tables *ptables, void *addr, size_t size, - bool write) -{ - int ret; + /* This is a non-leaf entry */ + if ((*entryp & MMU_P) == 0U) { + /* Not present. Never done a mapping here yet, need + * some RAM for linked tables + */ + void *new_table; -#ifdef CONFIG_X86_64 - struct x86_mmu_pml4 *pml4 = z_x86_get_pml4(ptables); + __ASSERT((options & OPTION_ALLOC) != 0, + "missing page table and allocations disabled"); - ret = x86_mmu_validate_pml4(pml4, (uintptr_t)addr, size, write); -#else - struct x86_mmu_pdpt *pdpt = z_x86_get_pdpt(ptables, (uintptr_t)addr); + new_table = page_pool_get(); - ret = x86_mmu_validate_pdpt(pdpt, (uintptr_t)addr, size, write); -#endif + if (new_table == NULL) { + return -ENOMEM; + } + *entryp = ((pentry_t)(uintptr_t)new_table) | INT_FLAGS; + table = new_table; + } else { + /* We fail an assertion here due to no support for + * splitting existing bigpage mappings. + * If the PS bit is not supported at some level (like + * in a PML4 entry) it is always reserved and must be 0 + */ + __ASSERT((*entryp & MMU_PS) == 0U, + "large page encountered"); + table = next_table(*entryp, level); + } + } -#ifdef CONFIG_X86_BOUNDS_CHECK_BYPASS_MITIGATION - __asm__ volatile ("lfence" : : : "memory"); -#endif + if (flush) { + tlb_flush_page(virt); + } - return ret; + return 0; } -static inline void tlb_flush_page(void *addr) +/** + * Map a physical region in a specific set of page tables. + * + * See documentation for page_map_set() for additional notes about masks and + * supported options. + * + * Must call this with x86_mmu_lock held if OPTION_ALLOC is used. + * + * It is vital to remember that all virtual-to-physical mappings must be + * the same with respect to supervisor mode regardless of what thread is + * scheduled (and therefore, if multiple sets of page tables exist, which one + * is active). + * + * It is permitted to set up mappings without the Present bit set. + * + * @param ptables Page tables to modify + * @param virt Base page-aligned virtual memory address to map the region. + * @param phys Base page-aligned physical memory address for the region. + * Ignored if OPTION_RESET. Also affected by the mask parameter. This + * address is not directly examined, it will simply be programmed into + * the PTE. + * @param size Size of the physical region to map + * @param entry_flags Non-address bits to set in every PTE. Ignored if + * OPTION_RESET. Also affected by the mask parameter. + * @param mask What bits to update in each PTE. Un-set bits will never be + * modified. Ignored if OPTION_RESET. + * @param options Control options, described above + * @retval 0 Success + * @retval -ENOMEM allocation required and no free pages (only if OPTION_ALLOC) + */ +static int range_map_ptables(pentry_t *ptables, void *virt, uintptr_t phys, + size_t size, pentry_t entry_flags, pentry_t mask, + uint32_t options) { - /* Invalidate TLB entries corresponding to the page containing the - * specified address + int ret; + bool reset = (options & OPTION_RESET) != 0U; + + assert_addr_aligned(phys); + __ASSERT((size & (CONFIG_MMU_PAGE_SIZE - 1)) == 0U, + "unaligned size %zu", size); + __ASSERT((entry_flags & paging_levels[0].mask) == 0U, + "entry_flags " PRI_ENTRY " overlaps address area", + entry_flags); + + /* This implementation is stack-efficient but not particularly fast. + * We do a full page table walk for every page we are updating. + * Recursive approaches are possible, but use much more stack space. */ - char *page = (char *)addr; - - __asm__ ("invlpg %0" :: "m" (*page)); -} - -#ifdef CONFIG_X86_64 -#define PML4E_FLAGS_MASK (Z_X86_MMU_RW | Z_X86_MMU_US | Z_X86_MMU_P) - -#define PDPTE_FLAGS_MASK PML4E_FLAGS_MASK - -#define PDE_FLAGS_MASK PDPTE_FLAGS_MASK -#else -#define PDPTE_FLAGS_MASK Z_X86_MMU_P - -#define PDE_FLAGS_MASK (Z_X86_MMU_RW | Z_X86_MMU_US | \ - PDPTE_FLAGS_MASK) -#endif + for (size_t offset = 0; offset < size; offset += CONFIG_MMU_PAGE_SIZE) { + uint8_t *dest_virt = (uint8_t *)virt + offset; + pentry_t entry_val; -#define PTE_FLAGS_MASK (PDE_FLAGS_MASK | Z_X86_MMU_XD | \ - Z_X86_MMU_PWT | \ - Z_X86_MMU_PCD) - -void z_x86_mmu_set_flags(struct x86_page_tables *ptables, void *ptr, - size_t size, u64_t flags, u64_t mask, bool flush) -{ - uintptr_t addr = (uintptr_t)ptr; - - __ASSERT((addr & MMU_PAGE_MASK) == 0U, "unaligned address provided"); - __ASSERT((size & MMU_PAGE_MASK) == 0U, "unaligned size provided"); + if (reset) { + entry_val = 0; + } else { + entry_val = (phys + offset) | entry_flags; + } - /* L1TF mitigation: non-present PTEs will have address fields - * zeroed. Expand the mask to include address bits if we are changing - * the present bit. - */ - if ((mask & Z_X86_MMU_P) != 0) { - mask |= Z_X86_MMU_PTE_ADDR_MASK; + ret = page_map_set(ptables, dest_virt, entry_val, NULL, mask, + options); + if (ret != 0) { + return ret; + } } - /* NOTE: All of this code assumes that 2MB or 1GB pages are not being - * modified. - */ - while (size != 0) { - u64_t *pte; - u64_t *pde; - u64_t *pdpte; -#ifdef CONFIG_X86_64 - u64_t *pml4e; -#endif - u64_t cur_flags = flags; - bool exec = (flags & Z_X86_MMU_XD) == 0; + return 0; +} -#ifdef CONFIG_X86_64 - pml4e = z_x86_pml4_get_pml4e(z_x86_get_pml4(ptables), addr); - __ASSERT((*pml4e & Z_X86_MMU_P) != 0, - "set flags on non-present PML4e"); - *pml4e |= (flags & PML4E_FLAGS_MASK); +/** + * Establish or update a memory mapping for all page tables + * + * The physical region noted from phys to phys + size will be mapped to + * an equal sized virtual region starting at virt, with the provided flags. + * The mask value denotes what bits in PTEs will actually be modified. + * + * See range_map_ptables() for additional details. + * + * @param virt Page-aligned starting virtual address + * @param phys Page-aligned starting physical address. Ignored if the mask + * parameter does not enable address bits or OPTION_RESET used. + * This region is not directly examined, it will simply be + * programmed into the page tables. + * @param size Size of the physical region to map + * @param entry_flags Desired state of non-address PTE bits covered by mask, + * ignored if OPTION_RESET + * @param mask What bits in the PTE to actually modifiy; unset bits will + * be preserved. Ignored if OPTION_RESET. + * @param options Control options. Do not set OPTION_USER here. OPTION_FLUSH + * will trigger a TLB shootdown after all tables are updated. + * @retval 0 Success + * @retval -ENOMEM page table allocation required, but no free pages + */ +static int range_map(void *virt, uintptr_t phys, size_t size, + pentry_t entry_flags, pentry_t mask, uint32_t options) +{ + int ret = 0; - if (exec) { - *pml4e &= ~Z_X86_MMU_XD; - } + LOG_DBG("%s: %p -> %p (%zu) flags " PRI_ENTRY " mask " + PRI_ENTRY " opt 0x%x", __func__, (void *)phys, virt, size, + entry_flags, mask, options); - pdpte = z_x86_pdpt_get_pdpte(z_x86_pml4e_get_pdpt(*pml4e), - addr); -#else - pdpte = z_x86_pdpt_get_pdpte(z_x86_get_pdpt(ptables, addr), - addr); -#endif - __ASSERT((*pdpte & Z_X86_MMU_P) != 0, - "set flags on non-present PDPTE"); - *pdpte |= (flags & PDPTE_FLAGS_MASK); #ifdef CONFIG_X86_64 - if (exec) { - *pdpte &= ~Z_X86_MMU_XD; - } -#endif - pde = z_x86_pd_get_pde(z_x86_pdpte_get_pd(*pdpte), addr); - __ASSERT((*pde & Z_X86_MMU_P) != 0, - "set flags on non-present PDE"); - *pde |= (flags & PDE_FLAGS_MASK); + /* There's a gap in the "64-bit" address space, as 4-level paging + * requires bits 48 to 63 to be copies of bit 47. Test this + * by treating as a signed value and shifting. + */ + __ASSERT(((((intptr_t)virt) << 16) >> 16) == (intptr_t)virt, + "non-canonical virtual address mapping %p (size %zu)", + virt, size); +#endif /* CONFIG_X86_64 */ - /* If any flags enable execution, clear execute disable at the - * page directory level - */ - if (exec) { - *pde &= ~Z_X86_MMU_XD; - } + __ASSERT((options & OPTION_USER) == 0U, "invalid option for function"); - pte = z_x86_pt_get_pte(z_x86_pde_get_pt(*pde), addr); + /* All virtual-to-physical mappings are the same in all page tables. + * What can differ is only access permissions, defined by the memory + * domain associated with the page tables, and the threads that are + * members of that domain. + * + * Any new mappings need to be applied to all page tables. + */ +#if defined(CONFIG_USERSPACE) && !defined(CONFIG_X86_COMMON_PAGE_TABLE) + sys_snode_t *node; - /* If we're setting the present bit, restore the address - * field. If we're clearing it, then the address field - * will be zeroed instead, mapping the PTE to the NULL page. - */ - if ((mask & Z_X86_MMU_P) != 0 && ((flags & Z_X86_MMU_P) != 0)) { - cur_flags |= addr; - } + SYS_SLIST_FOR_EACH_NODE(&x86_domain_list, node) { + struct arch_mem_domain *domain = + CONTAINER_OF(node, struct arch_mem_domain, node); - *pte = (*pte & ~mask) | cur_flags; - if (flush) { - tlb_flush_page((void *)addr); + ret = range_map_ptables(domain->ptables, virt, phys, size, + entry_flags, mask, + options | OPTION_USER); + if (ret != 0) { + /* NOTE: Currently we do not un-map a partially + * completed mapping. + */ + goto out_unlock; } + } +#endif /* CONFIG_USERSPACE */ + ret = range_map_ptables(z_x86_kernel_ptables, virt, phys, size, + entry_flags, mask, options); +#if defined(CONFIG_USERSPACE) && !defined(CONFIG_X86_COMMON_PAGE_TABLE) +out_unlock: +#endif /* CONFIG_USERSPACE */ + if (ret == 0 && (options & OPTION_ALLOC) != 0) { + LOG_DBG("page pool pages free: %u / %u", pages_free(), + CONFIG_X86_MMU_PAGE_POOL_PAGES); + } - size -= MMU_PAGE_SIZE; - addr += MMU_PAGE_SIZE; +#ifdef CONFIG_SMP + if ((options & OPTION_FLUSH) != 0U) { + tlb_shootdown(); } +#endif /* CONFIG_SMP */ + return ret; } -static char __aligned(MMU_PAGE_SIZE) - page_pool[MMU_PAGE_SIZE * CONFIG_X86_MMU_PAGE_POOL_PAGES]; +static inline int range_map_unlocked(void *virt, uintptr_t phys, size_t size, + pentry_t entry_flags, pentry_t mask, + uint32_t options) +{ + int ret; + k_spinlock_key_t key; -static char *page_pos = page_pool + sizeof(page_pool); + key = k_spin_lock(&x86_mmu_lock); + ret = range_map(virt, phys, size, entry_flags, mask, options); + k_spin_unlock(&x86_mmu_lock, key); + + return ret; +} -static void *get_page(void) +static pentry_t flags_to_entry(uint32_t flags) { - page_pos -= MMU_PAGE_SIZE; + pentry_t entry_flags = MMU_P; - __ASSERT(page_pos >= page_pool, "out of MMU pages\n"); + /* Translate flags argument into HW-recognized entry flags. + * + * Support for PAT is not implemented yet. Many systems may have + * BIOS-populated MTRR values such that these cache settings are + * redundant. + */ + switch (flags & K_MEM_CACHE_MASK) { + case K_MEM_CACHE_NONE: + entry_flags |= MMU_PCD; + break; + case K_MEM_CACHE_WT: + entry_flags |= MMU_PWT; + break; + case K_MEM_CACHE_WB: + break; + default: + return -ENOTSUP; + } - return page_pos; -} + if ((flags & K_MEM_PERM_RW) != 0U) { + entry_flags |= ENTRY_RW; + } -#ifdef CONFIG_X86_64 -#define PTABLES_ALIGN 4096 -#else -#define PTABLES_ALIGN 32 -#endif + if ((flags & K_MEM_PERM_USER) != 0U) { + entry_flags |= ENTRY_US; + } -__aligned(PTABLES_ALIGN) struct x86_page_tables z_x86_kernel_ptables; -#ifdef CONFIG_X86_KPTI -__aligned(PTABLES_ALIGN) struct x86_page_tables z_x86_user_ptables; -#endif + if ((flags & K_MEM_PERM_EXEC) == 0U) { + entry_flags |= ENTRY_XD; + } -extern char z_shared_kernel_page_start[]; + return entry_flags; +} -static inline bool is_within_system_ram(uintptr_t addr) +/* map new region virt..virt+size to phys with provided arch-neutral flags */ +int arch_mem_map(void *virt, uintptr_t phys, size_t size, uint32_t flags) { -#ifdef CONFIG_X86_64 - /* FIXME: locore not included in CONFIG_SRAM_BASE_ADDRESS */ - return addr < (PHYS_RAM_ADDR + PHYS_RAM_SIZE); -#else - return (addr >= PHYS_RAM_ADDR) && - (addr < (PHYS_RAM_ADDR + PHYS_RAM_SIZE)); -#endif + return range_map_unlocked(virt, phys, size, flags_to_entry(flags), + MASK_ALL, OPTION_ALLOC); } -/* Ignored bit posiition at all levels */ -#define IGNORED BIT64(11) - -static void maybe_clear_xd(u64_t *entry, bool exec) +#if CONFIG_X86_STACK_PROTECTION +void z_x86_set_stack_guard(k_thread_stack_t *stack) { - /* Execute disable bit needs special handling, we should only set it at - * intermediate levels if ALL containing pages have XD set (instead of - * just one). + /* Applied to all page tables as this affects supervisor mode. + * XXX: This never gets reset when the thread exits, which can + * cause problems if the memory is later used for something else. + * See #29499 * - * Use an ignored bit position in the PDE to store a marker on whether - * any configured region allows execution. + * Guard page is always the first page of the stack object for both + * kernel and thread stacks. */ - if (exec) { - *entry |= IGNORED; - *entry &= ~Z_X86_MMU_XD; - } else if ((*entry & IGNORED) == 0) { - *entry |= Z_X86_MMU_XD; - } + (void)range_map_unlocked(stack, 0, CONFIG_MMU_PAGE_SIZE, + MMU_P | ENTRY_XD, MASK_PERM, OPTION_FLUSH); } +#endif /* CONFIG_X86_STACK_PROTECTION */ -static void add_mmu_region_page(struct x86_page_tables *ptables, - uintptr_t addr, u64_t flags, bool user_table) +#ifdef CONFIG_USERSPACE +static bool page_validate(pentry_t *ptables, uint8_t *addr, bool write) { -#ifdef CONFIG_X86_64 - u64_t *pml4e; -#endif - struct x86_mmu_pdpt *pdpt; - u64_t *pdpte; - struct x86_mmu_pd *pd; - u64_t *pde; - struct x86_mmu_pt *pt; - u64_t *pte; - bool exec = (flags & Z_X86_MMU_XD) == 0; + pentry_t *table = (pentry_t *)ptables; + + for (int level = 0; level < NUM_LEVELS; level++) { + pentry_t entry = get_entry(table, addr, level); + if (is_leaf(level, entry)) { #ifdef CONFIG_X86_KPTI - /* If we are generating a page table for user mode, and this address - * does not have the user flag set, and this address falls outside - * of system RAM, then don't bother generating any tables for it, - * we will never need them later as memory domains are limited to - * regions within system RAM. - */ - if (user_table && (flags & Z_X86_MMU_US) == 0 && - !is_within_system_ram(addr)) { - return; - } + if (is_flipped_pte(entry)) { + /* We flipped this to prevent user access + * since just clearing US isn't sufficient + */ + return false; + } #endif - -#ifdef CONFIG_X86_64 - pml4e = z_x86_pml4_get_pml4e(z_x86_get_pml4(ptables), addr); - if ((*pml4e & Z_X86_MMU_P) == 0) { - pdpt = get_page(); - pml4e_update_pdpt(pml4e, pdpt); - } else { - pdpt = z_x86_pml4e_get_pdpt(*pml4e); + /* US and RW bits still carry meaning if non-present. + * If the data page is paged out, access bits are + * preserved. If un-mapped, the whole entry is 0. + */ + if (((entry & MMU_US) == 0U) || + (write && ((entry & MMU_RW) == 0U))) { + return false; + } + } else { + if ((entry & MMU_P) == 0U) { + /* Missing intermediate table, address is + * un-mapped + */ + return false; + } + table = next_table(entry, level); + } } - *pml4e |= (flags & PML4E_FLAGS_MASK); - maybe_clear_xd(pml4e, exec); -#else - pdpt = z_x86_get_pdpt(ptables, addr); -#endif - /* Setup the PDPTE entry for the address, creating a page directory - * if one didn't exist - */ - pdpte = z_x86_pdpt_get_pdpte(pdpt, addr); - if ((*pdpte & Z_X86_MMU_P) == 0) { - pd = get_page(); - pdpte_update_pd(pdpte, pd); - } else { - pd = z_x86_pdpte_get_pd(*pdpte); - } - *pdpte |= (flags & PDPTE_FLAGS_MASK); -#ifdef CONFIG_X86_64 - maybe_clear_xd(pdpte, exec); -#endif - - /* Setup the PDE entry for the address, creating a page table - * if necessary - */ - pde = z_x86_pd_get_pde(pd, addr); - if ((*pde & Z_X86_MMU_P) == 0) { - pt = get_page(); - pde_update_pt(pde, pt); - } else { - pt = z_x86_pde_get_pt(*pde); - } - *pde |= (flags & PDE_FLAGS_MASK); - maybe_clear_xd(pde, exec); + return true; +} -#ifdef CONFIG_X86_KPTI - if (user_table && (flags & Z_X86_MMU_US) == 0 && -#ifdef CONFIG_X86_64 - addr >= (uintptr_t)&_lodata_start && -#endif - addr != (uintptr_t)(&z_shared_kernel_page_start)) { - /* All non-user accessible pages except the shared page - * are marked non-present in the page table. - * - * For x86_64 we also make the locore text/rodata areas - * present even though they don't have user mode access, - * they contain necessary tables and program text for - * successfully handling exceptions and interrupts. - */ - return; - } -#else - ARG_UNUSED(user_table); +static inline void bcb_fence(void) +{ +#ifdef CONFIG_X86_BOUNDS_CHECK_BYPASS_MITIGATION + __asm__ volatile ("lfence" : : : "memory"); #endif - - /* Finally set up the page table entry */ - pte = z_x86_pt_get_pte(pt, addr); - pte_update_addr(pte, addr); - *pte |= (flags & PTE_FLAGS_MASK); } -static void add_mmu_region(struct x86_page_tables *ptables, - struct mmu_region *rgn, - bool user_table) +int arch_buffer_validate(void *addr, size_t size, int write) { - size_t size; - u64_t flags; - uintptr_t addr; + pentry_t *ptables = z_x86_thread_page_tables_get(_current); + uint8_t *virt; + size_t aligned_size; + int ret = 0; - __ASSERT((rgn->address & MMU_PAGE_MASK) == 0U, - "unaligned address provided"); - __ASSERT((rgn->size & MMU_PAGE_MASK) == 0U, - "unaligned size provided"); - addr = rgn->address; - flags = rgn->flags | Z_X86_MMU_P; + /* addr/size arbitrary, fix this up into an aligned region */ + k_mem_region_align((uintptr_t *)&virt, &aligned_size, + (uintptr_t)addr, size, CONFIG_MMU_PAGE_SIZE); - /* Iterate through the region a page at a time, creating entries as - * necessary. - */ - size = rgn->size; - while (size > 0) { - add_mmu_region_page(ptables, addr, flags, user_table); - - size -= MMU_PAGE_SIZE; - addr += MMU_PAGE_SIZE; + for (size_t offset = 0; offset < aligned_size; + offset += CONFIG_MMU_PAGE_SIZE) { + if (!page_validate(ptables, virt + offset, write)) { + ret = -1; + break; + } } -} + bcb_fence(); -void z_x86_add_mmu_region(uintptr_t addr, size_t size, u64_t flags) -{ - struct mmu_region rgn = { - .address = addr, - .size = size, - .flags = flags, - }; + return ret; +} +#ifdef CONFIG_X86_COMMON_PAGE_TABLE +/* Very low memory configuration. A single set of page tables is used for + * all threads. This relies on some assumptions: + * + * - No KPTI. If that were supported, we would need both a kernel and user + * set of page tables. + * - No SMP. If that were supported, we would need per-core page tables. + * - Memory domains don't affect supervisor mode. + * - All threads have the same virtual-to-physical mappings. + * - Memory domain APIs can't be called by user mode. + * + * Because there is no SMP, only one set of page tables, and user threads can't + * modify their own memory domains, we don't have to do much when + * arch_mem_domain_* APIs are called. We do use a caching scheme to avoid + * updating page tables if the last user thread scheduled was in the same + * domain. + * + * We don't set CONFIG_ARCH_MEM_DOMAIN_DATA, since we aren't setting + * up any arch-specific memory domain data (per domain page tables.) + * + * This is all nice and simple and saves a lot of memory. The cost is that + * context switching is not trivial CR3 update. We have to reset all partitions + * for the current domain configuration and then apply all the partitions for + * the incoming thread's domain if they are not the same. We also need to + * update permissions similarly on the thread stack region. + */ - add_mmu_region(&z_x86_kernel_ptables, &rgn, false); -#ifdef CONFIG_X86_KPTI - add_mmu_region(&z_x86_user_ptables, &rgn, true); -#endif +static inline void reset_region(uintptr_t start, size_t size) +{ + (void)range_map_unlocked((void *)start, 0, size, 0, 0, + OPTION_FLUSH | OPTION_RESET); } -void __weak z_x86_soc_add_mmu_regions(void) +static inline void apply_region(uintptr_t start, size_t size, pentry_t attr) { + (void)range_map_unlocked((void *)start, 0, size, attr, MASK_PERM, + OPTION_FLUSH); } -/* Called from x86's arch_kernel_init() */ -void z_x86_paging_init(void) +/* Cache of the current memory domain applied to the common page tables and + * the stack buffer region that had User access granted. + */ +static struct k_mem_domain *current_domain; +static uintptr_t current_stack_start; +static size_t current_stack_size; + +void z_x86_swap_update_common_page_table(struct k_thread *incoming) { - size_t pages_free; + k_spinlock_key_t key; - Z_STRUCT_SECTION_FOREACH(mmu_region, rgn) { - add_mmu_region(&z_x86_kernel_ptables, rgn, false); -#ifdef CONFIG_X86_KPTI - add_mmu_region(&z_x86_user_ptables, rgn, true); -#endif + if ((incoming->base.user_options & K_USER) == 0) { + /* Incoming thread is not a user thread. Memory domains don't + * affect supervisor threads and we don't need to enable User + * bits for its stack buffer; do nothing. + */ + return; } - z_x86_soc_add_mmu_regions(); + /* Step 1: Make sure the thread stack is set up correctly for the + * for the incoming thread + */ + if (incoming->stack_info.start != current_stack_start || + incoming->stack_info.size != current_stack_size) { + if (current_stack_size != 0U) { + reset_region(current_stack_start, current_stack_size); + } - pages_free = (page_pos - page_pool) / MMU_PAGE_SIZE; + /* The incoming thread's stack region needs User permissions */ + apply_region(incoming->stack_info.start, + incoming->stack_info.size, + K_MEM_PARTITION_P_RW_U_RW); - if (pages_free != 0) { - printk("Optimal CONFIG_X86_MMU_PAGE_POOL_PAGES %zu\n", - CONFIG_X86_MMU_PAGE_POOL_PAGES - pages_free); + /* Update cache */ + current_stack_start = incoming->stack_info.start; + current_stack_size = incoming->stack_info.size; } -#ifdef CONFIG_X86_64 - /* MMU already enabled at boot for long mode, we just need to - * program CR3 with our newly generated page tables. + /* Step 2: The page tables always have some memory domain applied to + * them. If the incoming thread's memory domain is different, + * update the page tables */ - __asm__ volatile("movq %0, %%cr3\n\t" - : : "r" (&z_x86_kernel_ptables) : "memory"); -#else - z_x86_enable_paging(); -#endif -} + key = k_spin_lock(&z_mem_domain_lock); + if (incoming->mem_domain_info.mem_domain == current_domain) { + /* The incoming thread's domain is already applied */ + goto out_unlock; + } -#ifdef CONFIG_X86_USERSPACE -int arch_buffer_validate(void *addr, size_t size, int write) -{ - return z_x86_mmu_validate(z_x86_thread_page_tables_get(_current), addr, - size, write != 0); -} + /* Reset the current memory domain regions... */ + if (current_domain != NULL) { + for (int i = 0; i < CONFIG_MAX_DOMAIN_PARTITIONS; i++) { + struct k_mem_partition *ptn = + ¤t_domain->partitions[i]; -#ifdef CONFIG_X86_64 -static uintptr_t thread_pdpt_create(uintptr_t pages, - struct x86_page_tables *thread_ptables, - struct x86_page_tables *master_ptables) -{ - uintptr_t pos = pages, phys_addr = Z_X86_PDPT_START; + if (ptn->size == 0) { + continue; + } + reset_region(ptn->start, ptn->size); + } + } - for (int i = 0; i < Z_X86_NUM_PDPT; i++, phys_addr += Z_X86_PDPT_AREA) { - u64_t *pml4e; - struct x86_mmu_pdpt *master_pdpt, *dest_pdpt; + /* ...and apply all the incoming domain's regions */ + for (int i = 0; i < CONFIG_MAX_DOMAIN_PARTITIONS; i++) { + struct k_mem_partition *ptn = + &incoming->mem_domain_info.mem_domain->partitions[i]; - /* obtain master PDPT tables for the address range and copy - * into per-thread PDPT for this range - */ - master_pdpt = z_x86_get_pdpt(master_ptables, phys_addr); - dest_pdpt = (struct x86_mmu_pdpt *)pos; - (void)memcpy(dest_pdpt, master_pdpt, - sizeof(struct x86_mmu_pdpt)); - - /* And then wire this up to the relevant per-thread PML4E */ - pml4e = z_x86_get_pml4e(thread_ptables, phys_addr); - pml4e_update_pdpt(pml4e, dest_pdpt); - pos += MMU_PAGE_SIZE; + if (ptn->size == 0) { + continue; + } + apply_region(ptn->start, ptn->size, ptn->attr); } - - return pos; + current_domain = incoming->mem_domain_info.mem_domain; +out_unlock: + k_spin_unlock(&z_mem_domain_lock, key); } -#endif /* CONFIG_X86_64 */ -static uintptr_t thread_pd_create(uintptr_t pages, - struct x86_page_tables *thread_ptables, - struct x86_page_tables *master_ptables) +/* If a partition was added or removed in the cached domain, update the + * page tables. + */ +void arch_mem_domain_partition_remove(struct k_mem_domain *domain, + uint32_t partition_id) { - uintptr_t pos = pages, phys_addr = Z_X86_PD_START; + struct k_mem_partition *ptn; - for (int i = 0; i < Z_X86_NUM_PD; i++, phys_addr += Z_X86_PD_AREA) { - u64_t *pdpte; - struct x86_mmu_pd *master_pd, *dest_pd; + if (domain != current_domain) { + return; + } - /* Obtain PD in master tables for the address range and copy - * into the per-thread PD for this range - */ - master_pd = z_x86_get_pd(master_ptables, phys_addr); - dest_pd = (struct x86_mmu_pd *)pos; + ptn = &domain->partitions[partition_id]; + reset_region(ptn->start, ptn->size); +} - (void)memcpy(dest_pd, master_pd, sizeof(struct x86_mmu_pd)); +void arch_mem_domain_partition_add(struct k_mem_domain *domain, + uint32_t partition_id) +{ + struct k_mem_partition *ptn; - /* Update pointer in per-thread pdpt to point to the per-thread - * directory we just copied - */ - pdpte = z_x86_get_pdpte(thread_ptables, phys_addr); - pdpte_update_pd(pdpte, dest_pd); - pos += MMU_PAGE_SIZE; + if (domain != current_domain) { + return; } - return pos; + ptn = &domain->partitions[partition_id]; + apply_region(ptn->start, ptn->size, ptn->attr); } -/* thread_ptables must be initialized, as well as all the page directories */ -static uintptr_t thread_pt_create(uintptr_t pages, - struct x86_page_tables *thread_ptables, - struct x86_page_tables *master_ptables) +/* Rest of the APIs don't need to do anything */ +void arch_mem_domain_thread_add(struct k_thread *thread) { - uintptr_t pos = pages, phys_addr = Z_X86_PT_START; - for (int i = 0; i < Z_X86_NUM_PT; i++, phys_addr += Z_X86_PT_AREA) { - u64_t *pde; - struct x86_mmu_pt *master_pt, *dest_pt; +} - /* Same as we did with the directories, obtain PT in master - * tables for the address range and copy into per-thread PT - * for this range - */ - master_pt = z_x86_get_pt(master_ptables, phys_addr); - dest_pt = (struct x86_mmu_pt *)pos; - (void)memcpy(dest_pt, master_pt, sizeof(struct x86_mmu_pt)); +void arch_mem_domain_thread_remove(struct k_thread *thread) +{ - /* And then wire this up to the relevant per-thread - * page directory entry - */ - pde = z_x86_get_pde(thread_ptables, phys_addr); - pde_update_pt(pde, dest_pt); - pos += MMU_PAGE_SIZE; - } +} + +void arch_mem_domain_destroy(struct k_mem_domain *domain) +{ - return pos; } +#else +/* Memory domains each have a set of page tables assigned to them */ -/* Initialize the page tables for a thread. This will contain, once done, - * the boot-time configuration for a user thread page tables. There are - * no pre-conditions on the existing state of the per-thread tables. - * - * pos represents the page we are working with in the reserved area - * in the stack buffer for per-thread tables. As we create tables in - * this area, pos is incremented to the next free page. - * - * The layout of the stack object, when this is done: +/** +* Duplicate an entire set of page tables * - * For 32-bit: + * Uses recursion, but depth at any given moment is limited by the number of + * paging levels. * - * +---------------------------+ <- thread->stack_obj - * | PDE(0) | - * +---------------------------+ - * | ... | - * +---------------------------+ - * | PDE(Z_X86_NUM_PD - 1) | - * +---------------------------+ - * | PTE(0) | - * +---------------------------+ - * | ... | - * +---------------------------+ - * | PTE(Z_X86_NUM_PT - 1) | - * +---------------------------+ <- pos once this logic completes - * | Stack guard | - * +---------------------------+ - * | Privilege elevation stack | - * | PDPT | - * +---------------------------+ <- thread->stack_info.start - * | Thread stack | - * | ... | + * x86_mmu_lock must be held. * - * For 64-bit: - * - * +---------------------------+ <- thread->stack_obj - * | PML4 | - * +---------------------------| - * | PDPT(0) | - * +---------------------------| - * | ... | - * +---------------------------| - * | PDPT(Z_X86_NUM_PDPT - 1) | - * +---------------------------+ - * | PDE(0) | - * +---------------------------+ - * | ... | - * +---------------------------+ - * | PDE(Z_X86_NUM_PD - 1) | - * +---------------------------+ - * | PTE(0) | - * +---------------------------+ - * | ... | - * +---------------------------+ - * | PTE(Z_X86_NUM_PT - 1) | - * +---------------------------+ <- pos once this logic completes - * | Stack guard | - * +---------------------------+ - * | Privilege elevation stack | - * +---------------------------+ <- thread->stack_info.start - * | Thread stack | - * | ... | + * @param dst a zeroed out chunk of memory of sufficient size for the indicated + * paging level. + * @param src some paging structure from within the source page tables to copy + * at the indicated paging level + * @param level Current paging level + * @retval 0 Success + * @retval -ENOMEM Insufficient page pool memory */ -static void copy_page_tables(struct k_thread *thread, - struct x86_page_tables *thread_ptables, - struct x86_page_tables *master_ptables) -{ - uintptr_t pos, start; - struct z_x86_thread_stack_header *header = - (struct z_x86_thread_stack_header *)thread->stack_obj; - - __ASSERT(thread->stack_obj != NULL, "no stack object assigned"); - __ASSERT(z_x86_page_tables_get() != thread_ptables, - "tables are active"); - __ASSERT(((uintptr_t)thread_ptables & 0x1f) == 0, - "unaligned page tables at %p", thread_ptables); - - (void)memcpy(thread_ptables, master_ptables, - sizeof(struct x86_page_tables)); - - start = (uintptr_t)(&header->page_tables); -#ifdef CONFIG_X86_64 - pos = start + sizeof(struct x86_mmu_pml4); - pos = thread_pdpt_create(pos, thread_ptables, master_ptables); -#else - pos = start; -#endif - pos = thread_pd_create(pos, thread_ptables, master_ptables); - pos = thread_pt_create(pos, thread_ptables, master_ptables); - - __ASSERT(pos == (start + Z_X86_THREAD_PT_AREA), - "wrong amount of stack object memory used"); -} - -static void reset_mem_partition(struct x86_page_tables *thread_ptables, - struct k_mem_partition *partition) +static int copy_page_table(pentry_t *dst, pentry_t *src, int level) { - uintptr_t addr = partition->start; - size_t size = partition->size; + if (level == PTE_LEVEL) { + /* Base case: leaf page table */ + for (int i = 0; i < get_num_entries(level); i++) { + dst[i] = pte_finalize_value(reset_pte(src[i]), true); + } + } else { + /* Recursive case: allocate sub-structures as needed and + * make recursive calls on them + */ + for (int i = 0; i < get_num_entries(level); i++) { + pentry_t *child_dst; + int ret; - __ASSERT((addr & MMU_PAGE_MASK) == 0U, "unaligned address provided"); - __ASSERT((size & MMU_PAGE_MASK) == 0U, "unaligned size provided"); + if ((src[i] & MMU_P) == 0) { + /* Non-present, skip */ + continue; + } - while (size != 0) { - u64_t *thread_pte, *master_pte; + __ASSERT((src[i] & MMU_PS) == 0, + "large page encountered"); - thread_pte = z_x86_get_pte(thread_ptables, addr); - master_pte = z_x86_get_pte(&USER_PTABLES, addr); + child_dst = page_pool_get(); + if (child_dst == NULL) { + return -ENOMEM; + } - *thread_pte = *master_pte; + /* Page table links are by physical address. RAM + * for page tables is identity-mapped, but double- + * cast needed for PAE case where sizeof(void *) and + * sizeof(pentry_t) are not the same. + */ + dst[i] = ((pentry_t)(uintptr_t)child_dst) | INT_FLAGS; - size -= MMU_PAGE_SIZE; - addr += MMU_PAGE_SIZE; + ret = copy_page_table(child_dst, + next_table(src[i], level), + level + 1); + if (ret != 0) { + return ret; + } + } } + + return 0; } -static void apply_mem_partition(struct x86_page_tables *ptables, - struct k_mem_partition *partition) +static void region_map_update(pentry_t *ptables, void *start, + size_t size, pentry_t flags, bool reset) { - u64_t x86_attr; - u64_t mask; + uint32_t options = OPTION_USER; + k_spinlock_key_t key; - if (IS_ENABLED(CONFIG_X86_KPTI)) { - x86_attr = partition->attr | Z_X86_MMU_P; - mask = K_MEM_PARTITION_PERM_MASK | Z_X86_MMU_P; - } else { - x86_attr = partition->attr; - mask = K_MEM_PARTITION_PERM_MASK; + if (reset) { + options |= OPTION_RESET; + } + if (ptables == z_x86_page_tables_get()) { + options |= OPTION_FLUSH; } - __ASSERT(partition->start >= PHYS_RAM_ADDR, - "region at %08lx[%zu] extends below system ram start 0x%08lx", - partition->start, partition->size, (uintptr_t)PHYS_RAM_ADDR); - __ASSERT(((partition->start + partition->size) <= - (PHYS_RAM_ADDR + PHYS_RAM_SIZE)), - "region at %08lx[%zu] end at %08lx extends beyond system ram end 0x%08lx", - partition->start, partition->size, - partition->start + partition->size, - ((uintptr_t)PHYS_RAM_ADDR) + (size_t)PHYS_RAM_SIZE); + key = k_spin_lock(&x86_mmu_lock); + (void)range_map_ptables(ptables, start, 0, size, flags, MASK_PERM, + options); + k_spin_unlock(&x86_mmu_lock, key); - z_x86_mmu_set_flags(ptables, (void *)partition->start, partition->size, - x86_attr, mask, false); +#ifdef CONFIG_SMP + tlb_shootdown(); +#endif } -void z_x86_apply_mem_domain(struct x86_page_tables *ptables, - struct k_mem_domain *mem_domain) +static inline void reset_region(pentry_t *ptables, void *start, size_t size) { - for (int i = 0, pcount = 0; pcount < mem_domain->num_partitions; i++) { - struct k_mem_partition *partition; + LOG_DBG("%s(%p, %p, %zu)", __func__, ptables, start, size); + region_map_update(ptables, start, size, 0, true); +} - partition = &mem_domain->partitions[i]; - if (partition->size == 0) { - continue; - } - pcount++; +static inline void apply_region(pentry_t *ptables, void *start, + size_t size, pentry_t attr) +{ + LOG_DBG("%s(%p, %p, %zu, " PRI_ENTRY ")", __func__, ptables, start, + size, attr); + region_map_update(ptables, start, size, attr, false); +} - apply_mem_partition(ptables, partition); - } +static void set_stack_perms(struct k_thread *thread, pentry_t *ptables) +{ + LOG_DBG("update stack for thread %p's ptables at %p: %p (size %zu)", + thread, ptables, (void *)thread->stack_info.start, + thread->stack_info.size); + apply_region(ptables, (void *)thread->stack_info.start, + thread->stack_info.size, + MMU_P | MMU_XD | MMU_RW | MMU_US); } -/* Called on creation of a user thread or when a supervisor thread drops to - * user mode. - * - * Sets up the per-thread page tables, such that when they are activated on - * context switch, everything is ready to go. thread->arch.ptables is updated - * to the thread-level tables instead of the kernel's page tbales. +/* + * Arch interface implementations for memory domains and userspace */ -void z_x86_thread_pt_init(struct k_thread *thread) + +int arch_mem_domain_init(struct k_mem_domain *domain) { - struct x86_page_tables *ptables; - struct z_x86_thread_stack_header *header = - (struct z_x86_thread_stack_header *)thread->stack_obj; + int ret; + k_spinlock_key_t key = k_spin_lock(&x86_mmu_lock); -#ifdef CONFIG_X86_64 - ptables = (struct x86_page_tables *)(&header->page_tables); -#else - ptables = &header->kernel_data.ptables; -#endif - thread->arch.ptables = ptables; + LOG_DBG("%s(%p)", __func__, domain); +#if __ASSERT_ON + sys_snode_t *node; - /* USER_PDPT contains the page tables with the boot time memory - * policy. We use it as a template to set up the per-thread page - * tables. + /* Assert that we have not already initialized this domain */ + SYS_SLIST_FOR_EACH_NODE(&x86_domain_list, node) { + struct arch_mem_domain *list_domain = + CONTAINER_OF(node, struct arch_mem_domain, node); + + __ASSERT(list_domain != &domain->arch, + "%s(%p) called multiple times", __func__, domain); + } +#endif /* __ASSERT_ON */ +#ifndef CONFIG_X86_KPTI + /* If we're not using KPTI then we can use the build time page tables + * (which are mutable) as the set of page tables for the default + * memory domain, saving us some memory. * - * With KPTI, this is a distinct set of tables z_x86_user_pdpt from the - * kernel page tables in z_x86_kernel_pdpt; it has all non user - * accessible pages except the trampoline page marked as non-present. - * Without KPTI, they are the same object. + * We skip adding this domain to x86_domain_list since we already + * update z_x86_kernel_ptables directly in range_map(). */ - copy_page_tables(thread, ptables, &USER_PTABLES); + if (domain == &k_mem_domain_default) { + domain->arch.ptables = z_x86_kernel_ptables; + k_spin_unlock(&x86_mmu_lock, key); + return 0; + } +#endif /* CONFIG_X86_KPTI */ +#ifdef CONFIG_X86_PAE + /* PDPT is stored within the memory domain itself since it is + * much smaller than a full page + */ + (void)memset(domain->arch.pdpt, 0, sizeof(domain->arch.pdpt)); + domain->arch.ptables = domain->arch.pdpt; +#else + /* Allocate a page-sized top-level structure, either a PD or PML4 */ + domain->arch.ptables = page_pool_get(); + if (domain->arch.ptables == NULL) { + k_spin_unlock(&x86_mmu_lock, key); + return -ENOMEM; + } +#endif /* CONFIG_X86_PAE */ + + LOG_DBG("copy_page_table(%p, %p, 0)", domain->arch.ptables, + z_x86_kernel_ptables); + + /* Make a copy of the boot page tables created by gen_mmu.py */ + ret = copy_page_table(domain->arch.ptables, z_x86_kernel_ptables, 0); + if (ret == 0) { + sys_slist_append(&x86_domain_list, &domain->arch.node); + } + + LOG_DBG("page pool pages free: %u / %u\n", pages_free(), + CONFIG_X86_MMU_PAGE_POOL_PAGES); + k_spin_unlock(&x86_mmu_lock, key); - /* Enable access to the thread's own stack buffer */ - z_x86_mmu_set_flags(ptables, (void *)thread->stack_info.start, - ROUND_UP(thread->stack_info.size, MMU_PAGE_SIZE), - Z_X86_MMU_P | K_MEM_PARTITION_P_RW_U_RW, - Z_X86_MMU_P | K_MEM_PARTITION_PERM_MASK, - false); + return ret; } -/* - * Memory domain interface - * - * In all cases, if one of these APIs is called on a supervisor thread, - * we don't need to do anything. If the thread later drops into supervisor - * mode the per-thread page tables will be generated and the memory domain - * configuration applied. - */ void arch_mem_domain_partition_remove(struct k_mem_domain *domain, - u32_t partition_id) + uint32_t partition_id) { - sys_dnode_t *node, *next_node; - - /* Removing a partition. Need to reset the relevant memory range - * to the defaults in USER_PDPT for each thread. - */ - SYS_DLIST_FOR_EACH_NODE_SAFE(&domain->mem_domain_q, node, next_node) { - struct k_thread *thread = - CONTAINER_OF(node, struct k_thread, mem_domain_info); + struct k_mem_partition *partition = &domain->partitions[partition_id]; - if ((thread->base.user_options & K_USER) == 0) { - continue; - } - - reset_mem_partition(z_x86_thread_page_tables_get(thread), - &domain->partitions[partition_id]); - } + /* Reset the partition's region back to defaults */ + reset_region(domain->arch.ptables, (void *)partition->start, + partition->size); } void arch_mem_domain_destroy(struct k_mem_domain *domain) { - for (int i = 0, pcount = 0; pcount < domain->num_partitions; i++) { - struct k_mem_partition *partition; - - partition = &domain->partitions[i]; - if (partition->size == 0) { - continue; - } - pcount++; - - arch_mem_domain_partition_remove(domain, i); - } + /* No-op, this is eventually getting removed in 2.5 */ } +/* Called on thread exit or when moving it to a different memory domain */ void arch_mem_domain_thread_remove(struct k_thread *thread) { struct k_mem_domain *domain = thread->mem_domain_info.mem_domain; - /* Non-user threads don't have per-thread page tables set up */ if ((thread->base.user_options & K_USER) == 0) { return; } - for (int i = 0, pcount = 0; pcount < domain->num_partitions; i++) { - struct k_mem_partition *partition; - - partition = &domain->partitions[i]; - if (partition->size == 0) { - continue; - } - pcount++; - - reset_mem_partition(z_x86_thread_page_tables_get(thread), - partition); + if ((thread->base.thread_state & _THREAD_DEAD) == 0) { + /* Thread is migrating to another memory domain and not + * exiting for good; we weren't called from + * z_thread_single_abort(). Resetting the stack region will + * take place in the forthcoming thread_add() call. + */ + return; } + + /* Restore permissions on the thread's stack area since it is no + * longer a member of the domain. + */ + reset_region(domain->arch.ptables, (void *)thread->stack_info.start, + thread->stack_info.size); } void arch_mem_domain_partition_add(struct k_mem_domain *domain, - u32_t partition_id) + uint32_t partition_id) { - sys_dnode_t *node, *next_node; - - SYS_DLIST_FOR_EACH_NODE_SAFE(&domain->mem_domain_q, node, next_node) { - struct k_thread *thread = - CONTAINER_OF(node, struct k_thread, mem_domain_info); - - if ((thread->base.user_options & K_USER) == 0) { - continue; - } + struct k_mem_partition *partition = &domain->partitions[partition_id]; - apply_mem_partition(z_x86_thread_page_tables_get(thread), - &domain->partitions[partition_id]); - } + /* Update the page tables with the partition info */ + apply_region(domain->arch.ptables, (void *)partition->start, + partition->size, partition->attr | MMU_P); } +/* Invoked from memory domain API calls, as well as during thread creation */ void arch_mem_domain_thread_add(struct k_thread *thread) { - if ((thread->base.user_options & K_USER) == 0) { - return; + /* New memory domain we are being added to */ + struct k_mem_domain *domain = thread->mem_domain_info.mem_domain; + /* This is only set for threads that were migrating from some other + * memory domain; new threads this is NULL + */ + pentry_t *old_ptables = (pentry_t *)thread->arch.ptables; + bool is_user = (thread->base.user_options & K_USER) != 0; + bool is_migration = (old_ptables != NULL) && is_user; + + /* Allow US access to the thread's stack in its new domain if + * we are migrating. If we are not migrating this is done in + * z_x86_current_stack_perms() + */ + if (is_migration) { + set_stack_perms(thread, domain->arch.ptables); + } + + thread->arch.ptables = (uintptr_t)domain->arch.ptables; + LOG_DBG("set thread %p page tables to %p", thread, + (void *)thread->arch.ptables); + + /* Check if we're doing a migration from a different memory domain + * and have to remove permissions from its old domain. + * + * XXX: The checks we have to do here and in + * arch_mem_domain_thread_remove() are clumsy, it may be worth looking + * into adding a specific arch_mem_domain_thread_migrate() API. + * See #29601 + */ + if (is_migration) { + reset_region(old_ptables, (void *)thread->stack_info.start, + thread->stack_info.size); } - z_x86_apply_mem_domain(z_x86_thread_page_tables_get(thread), - thread->mem_domain_info.mem_domain); +#if !defined(CONFIG_X86_KPTI) && !defined(CONFIG_X86_COMMON_PAGE_TABLE) + /* Need to switch to using these new page tables, in case we drop + * to user mode before we are ever context switched out. + * IPI takes care of this if the thread is currently running on some + * other CPU. + */ + if (thread == _current && thread->arch.ptables != z_x86_cr3_get()) { + z_x86_cr3_set(thread->arch.ptables); + } +#endif /* CONFIG_X86_KPTI */ } +#endif /* !CONFIG_X86_COMMON_PAGE_TABLE */ int arch_mem_domain_max_partitions_get(void) { return CONFIG_MAX_DOMAIN_PARTITIONS; } -#endif /* CONFIG_X86_USERSPACE*/ + +/* Invoked from z_x86_userspace_enter */ +void z_x86_current_stack_perms(void) +{ + /* Clear any previous context in the stack buffer to prevent + * unintentional data leakage. + */ + (void)memset((void *)_current->stack_info.start, 0xAA, + _current->stack_info.size - _current->stack_info.delta); + + /* Only now is it safe to grant access to the stack buffer since any + * previous context has been erased. + */ +#ifdef CONFIG_X86_COMMON_PAGE_TABLE + /* Re run swap page table update logic since we're entering User mode. + * This will grant stack and memory domain access if it wasn't set + * already (in which case this returns very quickly). + */ + z_x86_swap_update_common_page_table(_current); +#else + /* Memory domain access is already programmed into the page tables. + * Need to enable access to this new user thread's stack buffer in + * its domain-specific page tables. + */ + set_stack_perms(_current, z_x86_thread_page_tables_get(_current)); +#endif +} +#endif /* CONFIG_USERSPACE */ diff --git a/arch/x86/gen_gdt.py b/arch/x86/gen_gdt.py index 70fe90adb41c74..3465499b5f55b5 100755 --- a/arch/x86/gen_gdt.py +++ b/arch/x86/gen_gdt.py @@ -16,6 +16,15 @@ these data structures will not disturb the memory addresses of other symbols. +The input kernel ELF binary is used to obtain the following +information: + +- Memory addresses of the Main and Double Fault TSS structures + so GDT descriptors can be created for them +- Memory addresses of where the GDT lives in memory, so that this + address can be populated in the GDT pseudo descriptor +- whether userspace or HW stack protection are enabled in Kconfig + The output is a GDT whose contents depend on the kernel configuration. With no memory protection features enabled, we generate flat 32-bit code and data segments. If hardware- @@ -171,6 +180,13 @@ def main(): else: num_entries = 3 + use_tls = False + if ("CONFIG_THREAD_LOCAL_STORAGE" in syms) and ("CONFIG_X86_64" not in syms): + use_tls = True + + # x86_64 does not use descriptor for thread local storage + num_entries += 1 + gdt_base = syms["_gdt"] with open(args.output_gdt, "wb") as fp: @@ -196,7 +212,7 @@ def main(): # Selector 0x20: double-fault TSS fp.write(create_tss_entry(df_tss, 0x67, 0)) - if num_entries == 7: + if num_entries >= 7: # Selector 0x28: code descriptor, dpl = 3 fp.write(create_code_data_entry(0, 0xFFFFF, 3, FLAGS_GRAN, ACCESS_EX | ACCESS_RW)) @@ -205,6 +221,15 @@ def main(): fp.write(create_code_data_entry(0, 0xFFFFF, 3, FLAGS_GRAN, ACCESS_RW)) + if use_tls: + # Selector 0x18, 0x28 or 0x38 (depending on entries above): + # data descriptor, dpl = 3 + # + # for use with thread local storage while this will be + # modified at runtime. + fp.write(create_code_data_entry(0, 0xFFFFF, 3, + FLAGS_GRAN, ACCESS_RW)) + if __name__ == "__main__": main() diff --git a/arch/x86/gen_mmu.py b/arch/x86/gen_mmu.py new file mode 100755 index 00000000000000..6afbd877df13d1 --- /dev/null +++ b/arch/x86/gen_mmu.py @@ -0,0 +1,502 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2020 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +"""Create the kernel's page tables for x86 CPUs. + +For additional detail on paging and x86 memory management, please +consult the IA Architecture SW Developer Manual, volume 3a, chapter 4. + +This script produces the initial page tables installed into the CPU +at early boot. These pages will have an identity mapping at +CONFIG_SRAM_BASE_ADDRESS of size CONFIG_SRAM_SIZE. The script takes +the 'zephyr_prebuilt.elf' as input to obtain region sizes, certain +memory addresses, and configuration values. + +If CONFIG_SRAM_REGION_PERMISSIONS is not enabled, all RAM will be +mapped with the Present and Write bits set. The linker scripts shouldn't +add page alignment padding between sections. + +If CONFIG_SRAM_REGION_PERMISSIONS is enabled, the access permissions +vary: + - By default, the Present, Write, and Execute Disable bits are + set. + - The _image_text region will have Present and User bits set + - The _image_rodata region will have Present, User, and Execute + Disable bits set + - On x86_64, the _locore region will have Present set and + the _lorodata region will have Present and Execute Disable set. + +Because the set of page tables are linked together by physical address, +we must know a priori the physical address of each table. The linker +script must define a z_x86_pagetables_start symbol where the page +tables will be placed, and this memory address must not shift between +prebuilt and final ELF builds. This script will not work on systems +where the physical load address of the kernel is unknown at build time. + +64-bit systems will always build IA-32e page tables. 32-bit systems +build PAE page tables if CONFIG_X86_PAE is set, otherwise standard +32-bit page tables are built. + +The kernel will expect to find the top-level structure of the produced +page tables at the physical address corresponding to the symbol +z_x86_kernel_ptables. The linker script will need to set that symbol +to the end of the binary produced by this script, minus the size of the +top-level paging structure as it is written out last. +""" + +import sys +import array +import argparse +import os +import struct +import elftools +from distutils.version import LooseVersion +from elftools.elf.elffile import ELFFile +from elftools.elf.sections import SymbolTableSection + +if LooseVersion(elftools.__version__) < LooseVersion('0.24'): + sys.exit("pyelftools is out of date, need version 0.24 or later") + + +def bit(pos): + return 1 << pos + + +# Page table entry flags +FLAG_P = bit(0) +FLAG_RW = bit(1) +FLAG_US = bit(2) +FLAG_G = bit(8) +FLAG_XD = bit(63) + +FLAG_IGNORED0 = bit(9) +FLAG_IGNORED1 = bit(10) +FLAG_IGNORED2 = bit(11) + +ENTRY_RW = FLAG_RW | FLAG_IGNORED0 +ENTRY_US = FLAG_US | FLAG_IGNORED1 +ENTRY_XD = FLAG_XD | FLAG_IGNORED2 + +def debug(text): + if not args.verbose: + return + sys.stdout.write(os.path.basename(sys.argv[0]) + ": " + text + "\n") + + +def error(text): + sys.exit(os.path.basename(sys.argv[0]) + ": " + text) + + +def align_check(base, size): + if (base % 4096) != 0: + error("unaligned base address %x" % base) + if (size % 4096) != 0: + error("Unaligned region size %d for base %x" % (size, base)) + + +def dump_flags(flags): + ret = "" + + if flags & FLAG_P: + ret += "P " + + if flags & FLAG_RW: + ret += "RW " + + if flags & FLAG_US: + ret += "US " + + if flags & FLAG_G: + ret += "G " + + if flags & FLAG_XD: + ret += "XD " + + return ret.strip() + +# Hard-coded flags for intermediate paging levels. Permissive, we only control +# access or set caching properties at leaf levels. +INT_FLAGS = FLAG_P | FLAG_RW | FLAG_US + +class MMUTable(object): + """Represents a particular table in a set of page tables, at any level""" + + def __init__(self): + self.entries = array.array(self.type_code, + [0 for i in range(self.num_entries)]) + + def get_binary(self): + """Return a bytearray representation of this table""" + # Always little-endian + ctype = "<" + self.type_code + entry_size = struct.calcsize(ctype) + ret = bytearray(entry_size * self.num_entries) + + for i in range(self.num_entries): + struct.pack_into(ctype, ret, entry_size * i, self.entries[i]) + return ret + + @property + def supported_flags(self): + """Class property indicating what flag bits are supported""" + raise NotImplementedError() + + @property + def addr_shift(self): + """Class property for how much to shift virtual addresses to obtain + the appropriate index in the table for it""" + raise NotImplementedError() + + @property + def addr_mask(self): + """Mask to apply to an individual entry to get the physical address + mapping""" + raise NotImplementedError() + + @property + def type_code(self): + """Struct packing letter code for table entries. Either I for + 32-bit entries, or Q for PAE/IA-32e""" + raise NotImplementedError() + + @property + def num_entries(self): + """Number of entries in the table. Varies by table type and paging + mode""" + raise NotImplementedError() + + def entry_index(self, virt_addr): + """Get the index of the entry in this table that corresponds to the + provided virtual address""" + return (virt_addr >> self.addr_shift) & (self.num_entries - 1) + + def has_entry(self, virt_addr): + """Indicate whether an entry is present in this table for the provided + virtual address""" + index = self.entry_index(virt_addr) + + return (self.entries[index] & FLAG_P) != 0 + + def lookup(self, virt_addr): + """Look up the physical mapping for a virtual address. + + If this is a leaf table, this is the physical address mapping. If not, + this is the physical address of the next level table""" + index = self.entry_index(virt_addr) + + return self.entries[index] & self.addr_mask + + def map(self, virt_addr, phys_addr, entry_flags): + """For the table entry corresponding to the provided virtual address, + set the corresponding physical entry in the table. Unsupported flags + will be filtered out. + + If this is a leaf table, this is the physical address mapping. If not, + this is the physical address of the next level table""" + index = self.entry_index(virt_addr) + + self.entries[index] = ((phys_addr & self.addr_mask) | + (entry_flags & self.supported_flags)) + + def set_perms(self, virt_addr, entry_flags): + """"For the table entry corresponding to the provided virtual address, + update just the flags, leaving the physical mapping alone. + Unsupported flags will be filtered out.""" + index = self.entry_index(virt_addr) + + self.entries[index] = ((self.entries[index] & self.addr_mask) | + (entry_flags & self.supported_flags)) + + +# Specific supported table types +class Pml4(MMUTable): + """Page mapping level 4 for IA-32e""" + addr_shift = 39 + addr_mask = 0x7FFFFFFFFFFFF000 + type_code = 'Q' + num_entries = 512 + supported_flags = INT_FLAGS + +class Pdpt(MMUTable): + """Page directory pointer table for IA-32e""" + addr_shift = 30 + addr_mask = 0x7FFFFFFFFFFFF000 + type_code = 'Q' + num_entries = 512 + supported_flags = INT_FLAGS + +class PdptPAE(Pdpt): + """Page directory pointer table for PAE""" + num_entries = 4 + +class Pd(MMUTable): + """Page directory for 32-bit""" + addr_shift = 22 + addr_mask = 0xFFFFF000 + type_code = 'I' + num_entries = 1024 + supported_flags = INT_FLAGS + +class PdXd(Pd): + """Page directory for either PAE or IA-32e""" + addr_shift = 21 + addr_mask = 0x7FFFFFFFFFFFF000 + num_entries = 512 + type_code = 'Q' + +class Pt(MMUTable): + """Page table for 32-bit""" + addr_shift = 12 + addr_mask = 0xFFFFF000 + type_code = 'I' + num_entries = 1024 + supported_flags = (FLAG_P | FLAG_RW | FLAG_US | FLAG_G | + FLAG_IGNORED0 | FLAG_IGNORED1) + +class PtXd(Pt): + """Page table for either PAE or IA-32e""" + addr_mask = 0x07FFFFFFFFFFF000 + type_code = 'Q' + num_entries = 512 + supported_flags = (FLAG_P | FLAG_RW | FLAG_US | FLAG_G | FLAG_XD | + FLAG_IGNORED0 | FLAG_IGNORED1 | FLAG_IGNORED2) + + +class PtableSet(object): + """Represents a complete set of page tables for any paging mode""" + + def __init__(self, pages_start): + """Instantiate a set of page tables which will be located in the + image starting at the provided physical memory location""" + self.page_pos = pages_start + self.toplevel = self.levels[0]() + + debug("%s starting at physical address 0x%x" % + (self.__class__.__name__, pages_start)) + + # Database of page table pages. Maps physical memory address to + # MMUTable objects, excluding the top-level table which is tracked + # separately. Starts out empty as we haven't mapped anything and + # the top-level table is tracked separately. + self.tables = {} + + def get_new_mmutable_addr(self): + """If we need to instantiate a new MMUTable, return a physical + address location for it""" + ret = self.page_pos + self.page_pos += 4096 + return ret + + @property + def levels(self): + """Class hierarchy of paging levels, with the first entry being + the toplevel table class, and the last entry always being + some kind of leaf page table class (Pt or PtXd)""" + raise NotImplementedError() + + def map_page(self, virt_addr, phys_addr, flags): + """Map a virtual address to a physical address in the page tables, + with provided access flags""" + table = self.toplevel + + # Create and link up intermediate tables if necessary + for depth in range(1, len(self.levels)): + # Create child table if needed + if not table.has_entry(virt_addr): + new_table_addr = self.get_new_mmutable_addr() + new_table = self.levels[depth]() + debug("new %s at physical addr 0x%x" + % (self.levels[depth].__name__, new_table_addr)) + self.tables[new_table_addr] = new_table + table.map(virt_addr, new_table_addr, INT_FLAGS) + table = new_table + else: + table = self.tables[table.lookup(virt_addr)] + + # Set up entry in leaf page table + table.map(virt_addr, phys_addr, flags) + + def map(self, phys_base, size, flags): + """Identity map an address range in the page tables, with provided + access flags. + """ + debug("Identity-mapping 0x%x (%d): %s" % + (phys_base, size, dump_flags(flags))) + + align_check(phys_base, size) + for addr in range(phys_base, phys_base + size, 4096): + if addr == 0: + # Never map the NULL page + continue + + self.map_page(addr, addr, flags) + + def set_region_perms(self, name, flags): + """Set access permissions for a named region that is already mapped + + The bounds of the region will be looked up in the symbol table + with _start and _size suffixes. The physical address mapping + is unchanged and this will not disturb any double-mapping.""" + + # Doesn't matter if this is a virtual address, we have a + # either dual mapping or it's the same as physical + base = syms[name + "_start"] + size = syms[name + "_size"] + + debug("change flags for %s at 0x%x (%d): %s" % + (name, base, size, dump_flags(flags))) + align_check(base, size) + + try: + for addr in range(base, base + size, 4096): + # Never map the NULL page + if addr == 0: + continue + + table = self.toplevel + for _ in range(1, len(self.levels)): + table = self.tables[table.lookup(addr)] + table.set_perms(addr, flags) + except KeyError: + error("no mapping for %s region 0x%x (size 0x%x)" % + (name, base, size)) + + def write_output(self, filename): + """Write the page tables to the output file in binary format""" + with open(filename, "wb") as fp: + for addr in sorted(self.tables): + mmu_table = self.tables[addr] + fp.write(mmu_table.get_binary()) + + # We always have the top-level table be last. This is because + # in PAE, the top-level PDPT has only 4 entries and is not a + # full page in size. We do not put it in the tables dictionary + # and treat it as a special case. + debug("top-level %s at physical addr 0x%x" % + (self.toplevel.__class__.__name__, + self.get_new_mmutable_addr())) + fp.write(self.toplevel.get_binary()) + +# Paging mode classes, we'll use one depending on configuration +class Ptables32bit(PtableSet): + levels = [Pd, Pt] + +class PtablesPAE(PtableSet): + levels = [PdptPAE, PdXd, PtXd] + +class PtablesIA32e(PtableSet): + levels = [Pml4, Pdpt, PdXd, PtXd] + + +def parse_args(): + global args + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + + parser.add_argument("-k", "--kernel", required=True, + help="path to prebuilt kernel ELF binary") + parser.add_argument("-o", "--output", required=True, + help="output file") + parser.add_argument("-v", "--verbose", action="store_true", + help="Print extra debugging information") + args = parser.parse_args() + if "VERBOSE" in os.environ: + args.verbose = True + + +def get_symbols(obj): + for section in obj.iter_sections(): + if isinstance(section, SymbolTableSection): + return {sym.name: sym.entry.st_value + for sym in section.iter_symbols()} + + raise LookupError("Could not find symbol table") + +def isdef(sym_name): + return sym_name in syms + +def main(): + global syms + parse_args() + + with open(args.kernel, "rb") as fp: + kernel = ELFFile(fp) + syms = get_symbols(kernel) + + if isdef("CONFIG_X86_64"): + pclass = PtablesIA32e + elif isdef("CONFIG_X86_PAE"): + pclass = PtablesPAE + else: + pclass = Ptables32bit + + debug("building %s" % pclass.__name__) + + ram_base = syms["CONFIG_SRAM_BASE_ADDRESS"] + ram_size = syms["CONFIG_SRAM_SIZE"] * 1024 + ptables_phys = syms["z_x86_pagetables_start"] + + debug("Base addresses: physical 0x%x size %d" % (ram_base, ram_size)) + + is_perm_regions = isdef("CONFIG_SRAM_REGION_PERMISSIONS") + + if is_perm_regions: + # Don't allow execution by default for any pages. We'll adjust this + # in later calls to pt.set_region_perms() + map_flags = FLAG_P | ENTRY_XD + else: + map_flags = FLAG_P + + pt = pclass(ptables_phys) + pt.map(ram_base, ram_size, map_flags | ENTRY_RW) + + if isdef("CONFIG_XIP"): + # Additionally identity-map all ROM as read-only + pt.map(syms["CONFIG_FLASH_BASE_ADDRESS"], + syms["CONFIG_FLASH_SIZE"] * 1024, map_flags) + + # Adjust mapped region permissions if configured + if is_perm_regions: + # Need to accomplish the following things: + # - Text regions need the XD flag cleared and RW flag removed + # if not built with gdbstub support + # - Rodata regions need the RW flag cleared + # - User mode needs access as we currently do not separate application + # text/rodata from kernel text/rodata + if isdef("CONFIG_GDBSTUB"): + pt.set_region_perms("_image_text", FLAG_P | ENTRY_US | ENTRY_RW) + else: + pt.set_region_perms("_image_text", FLAG_P | ENTRY_US) + pt.set_region_perms("_image_rodata", FLAG_P | ENTRY_US | ENTRY_XD) + + if isdef("CONFIG_COVERAGE_GCOV") and isdef("CONFIG_USERSPACE"): + # If GCOV is enabled, user mode must be able to write to its + # common data area + pt.set_region_perms("__gcov_bss", + FLAG_P | ENTRY_RW | ENTRY_US | ENTRY_XD) + + if isdef("CONFIG_X86_64"): + # Set appropriate permissions for locore areas much like we did + # with the main text/rodata regions + + if isdef("CONFIG_X86_KPTI"): + # Set the User bit for the read-only locore/lorodata areas. + # This ensures they get mapped into the User page tables if + # KPTI is turned on. There is no sensitive data in them, and + # they contain text/data needed to take an exception or + # interrupt. + flag_user = ENTRY_US + else: + flag_user = 0 + + pt.set_region_perms("_locore", FLAG_P | flag_user) + pt.set_region_perms("_lorodata", FLAG_P | ENTRY_XD | flag_user) + + pt.write_output(args.output) + +if __name__ == "__main__": + main() diff --git a/arch/x86/ia32.cmake b/arch/x86/ia32.cmake index a14acdcc61b0a6..1f8134b872b4df 100644 --- a/arch/x86/ia32.cmake +++ b/arch/x86/ia32.cmake @@ -65,29 +65,7 @@ add_subdirectory(core) get_property(OUTPUT_ARCH GLOBAL PROPERTY PROPERTY_OUTPUT_ARCH) get_property(OUTPUT_FORMAT GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT) -# Convert the .bin file argument to a .o file, create a wrapper -# library for the .o file, and register the library as a generated -# file that is to be linked in after the first link. -function(add_bin_file_to_the_next_link target_dependency bin) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${bin}.o - COMMAND - ${CMAKE_OBJCOPY} - -I binary - -B ${OUTPUT_ARCH} - -O ${OUTPUT_FORMAT} - --rename-section .data=${bin},CONTENTS,ALLOC,LOAD,READONLY,DATA - ${bin}.bin - ${bin}.o - DEPENDS ${target_dependency} ${bin}.bin - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - add_custom_target(${bin}_o DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${bin}.o) - add_library(${bin} STATIC IMPORTED GLOBAL) - set_property(TARGET ${bin} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${bin}.o) - add_dependencies(${bin} ${bin}_o) - set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_OBJECT_FILES ${bin}) -endfunction() + add_bin_file_to_the_next_link(gen_idt_output staticIdt) add_bin_file_to_the_next_link(gen_idt_output irq_int_vector_map) diff --git a/arch/x86/include/ia32/exception.h b/arch/x86/include/ia32/exception.h index 3a519ab15d910e..4853f4e0264104 100644 --- a/arch/x86/include/ia32/exception.h +++ b/arch/x86/include/ia32/exception.h @@ -11,13 +11,13 @@ #include -#define _EXCEPTION_INTLIST(vector) \ +#define _EXCEPTION_INTLIST(vector, dpl) \ ".pushsection .gnu.linkonce.intList.exc_" #vector "\n\t" \ ".long 1f\n\t" /* ISR_LIST.fnc */ \ ".long -1\n\t" /* ISR_LIST.irq */ \ ".long -1\n\t" /* ISR_LIST.priority */ \ ".long " STRINGIFY(vector) "\n\t" /* ISR_LIST.vec */ \ - ".long 0\n\t" /* ISR_LIST.dpl */ \ + ".long " STRINGIFY(dpl) "\n\t" /* ISR_LIST.dpl */ \ ".long 0\n\t" /* ISR_LIST.tss */ \ ".popsection\n\t" \ @@ -41,9 +41,9 @@ * handlers without having to #ifdef out previous instances such as in * arch/x86/core/fatal.c */ -#define __EXCEPTION_CONNECT(handler, vector, codepush) \ +#define __EXCEPTION_CONNECT(handler, vector, dpl, codepush) \ __asm__ ( \ - _EXCEPTION_INTLIST(vector) \ + _EXCEPTION_INTLIST(vector, dpl) \ ".pushsection .gnu.linkonce.t.exc_" STRINGIFY(vector) \ "_stub, \"ax\"\n\t" \ ".global " STRINGIFY(_EXCEPTION_STUB_NAME(handler, vector)) "\n\t" \ @@ -65,8 +65,8 @@ * void handler(const z_arch_esf_t *esf) * @param vector Vector index in the IDT */ -#define _EXCEPTION_CONNECT_NOCODE(handler, vector) \ - __EXCEPTION_CONNECT(handler, vector, "push $0\n\t") +#define _EXCEPTION_CONNECT_NOCODE(handler, vector, dpl) \ + __EXCEPTION_CONNECT(handler, vector, dpl, "push $0\n\t") /** * @brief Connect an exception handler that does expect error code @@ -78,8 +78,8 @@ * void handler(const z_arch_esf_t *esf) * @param vector Vector index in the IDT */ -#define _EXCEPTION_CONNECT_CODE(handler, vector) \ - __EXCEPTION_CONNECT(handler, vector, "") +#define _EXCEPTION_CONNECT_CODE(handler, vector, dpl) \ + __EXCEPTION_CONNECT(handler, vector, dpl, "") #endif /* _ASMLANGUAGE */ diff --git a/arch/x86/include/ia32/kernel_arch_data.h b/arch/x86/include/ia32/kernel_arch_data.h index ebec7a7525dd36..49dc1981fe9c5b 100644 --- a/arch/x86/include/ia32/kernel_arch_data.h +++ b/arch/x86/include/ia32/kernel_arch_data.h @@ -63,6 +63,10 @@ extern void z_x86_thread_entry_wrapper(k_thread_entry_t entry, void *p1, void *p2, void *p3); #endif /* _THREAD_WRAPPER_REQUIRED */ +#ifdef CONFIG_THREAD_LOCAL_STORAGE +extern void z_x86_tls_update_gdt(struct k_thread *thread); +#endif + #ifdef __cplusplus } #endif diff --git a/arch/x86/include/intel64/kernel_arch_data.h b/arch/x86/include/intel64/kernel_arch_data.h index c46cddadefc76f..ff0618f9a34c70 100644 --- a/arch/x86/include/intel64/kernel_arch_data.h +++ b/arch/x86/include/intel64/kernel_arch_data.h @@ -20,19 +20,17 @@ extern char _locore_start[], _locore_end[]; struct x86_cpuboot { volatile int ready; /* CPU has started */ - u16_t tr; /* selector for task register */ + uint16_t tr; /* selector for task register */ struct x86_tss64 *gs_base; /* Base address for GS segment */ - u64_t sp; /* initial stack pointer */ + uint64_t sp; /* initial stack pointer */ + size_t stack_size; /* size of stack */ arch_cpustart_t fn; /* kernel entry function */ void *arg; /* argument for above function */ -#ifdef CONFIG_X86_MMU - struct x86_page_tables *ptables; /* Runtime page tables to install */ -#endif /* CONFIG_X86_MMU */ }; typedef struct x86_cpuboot x86_cpuboot_t; -extern u8_t x86_cpu_loapics[]; /* CPU logical ID -> local APIC ID */ +extern uint8_t x86_cpu_loapics[]; /* CPU logical ID -> local APIC ID */ #endif /* _ASMLANGUAGE */ diff --git a/arch/x86/include/intel64/kernel_arch_func.h b/arch/x86/include/intel64/kernel_arch_func.h index 1fbc9d32a6fa16..0ed9d513b74010 100644 --- a/arch/x86/include/intel64/kernel_arch_func.h +++ b/arch/x86/include/intel64/kernel_arch_func.h @@ -36,6 +36,8 @@ void x86_sse_init(struct k_thread *thread); void z_x86_syscall_entry_stub(void); +bool z_x86_do_kernel_nmi(const z_arch_esf_t *esf); + #endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/x86/include/kernel_arch_func.h b/arch/x86/include/kernel_arch_func.h index eef7dfd1a85c11..a0919e61e3e21f 100644 --- a/arch/x86/include/kernel_arch_func.h +++ b/arch/x86/include/kernel_arch_func.h @@ -44,20 +44,6 @@ extern FUNC_NORETURN void z_x86_prep_c(void *arg); void z_x86_early_serial_init(void); #endif /* CONFIG_X86_VERY_EARLY_CONSOLE */ -#ifdef CONFIG_X86_MMU -/* Create all page tables with boot configuration and enable paging */ -void z_x86_paging_init(void); - -static inline struct x86_page_tables * -z_x86_thread_page_tables_get(struct k_thread *thread) -{ -#ifdef CONFIG_USERSPACE - return thread->arch.ptables; -#else - return &z_x86_kernel_ptables; -#endif -} -#endif /* CONFIG_X86_MMU */ /* Called upon CPU exception that is unhandled and hence fatal; dump * interesting info and call z_x86_fatal_error() @@ -87,7 +73,7 @@ void z_x86_page_fault_handler(z_arch_esf_t *esf); * @param cs Code segment of faulting context * @return true if addr/size region is not within the thread stack */ -bool z_x86_check_stack_bounds(uintptr_t addr, size_t size, u16_t cs); +bool z_x86_check_stack_bounds(uintptr_t addr, size_t size, uint16_t cs); #endif /* CONFIG_THREAD_STACK_INFO */ #ifdef CONFIG_USERSPACE @@ -102,15 +88,26 @@ extern FUNC_NORETURN void z_x86_userspace_enter(k_thread_entry_t user_entry, */ void *z_x86_userspace_prepare_thread(struct k_thread *thread); -void z_x86_thread_pt_init(struct k_thread *thread); - -void z_x86_apply_mem_domain(struct x86_page_tables *ptables, - struct k_mem_domain *mem_domain); - #endif /* CONFIG_USERSPACE */ void z_x86_do_kernel_oops(const z_arch_esf_t *esf); +/* + * Find a free IRQ vector at the specified priority, or return -1 if none left. + * For multiple vector allocated one after another, prev_vector can be used to + * speed up the allocation: it only needs to be filled with the previous + * allocated vector, or -1 to start over. + */ +int z_x86_allocate_vector(unsigned int priority, int prev_vector); + +/* + * Connect a vector + */ +void z_x86_irq_connect_on_vector(unsigned int irq, + uint8_t vector, + void (*func)(const void *arg), + const void *arg, uint32_t flags); + #endif /* !_ASMLANGUAGE */ #endif /* ZEPHYR_ARCH_X86_INCLUDE_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/x86/include/x86_mmu.h b/arch/x86/include/x86_mmu.h new file mode 100644 index 00000000000000..df580e8c460924 --- /dev/null +++ b/arch/x86/include/x86_mmu.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2011-2014 Wind River Systems, Inc. + * Copyright (c) 2017-2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Internal memory management interfaces implemented in x86_mmu.c. + * None of these are application-facing, use only if you know what you are + * doing! + */ + +#ifndef ZEPHYR_ARCH_X86_INCLUDE_X86_MMU_H +#define ZEPHYR_ARCH_X86_INCLUDE_X86_MMU_H + +#include +#include + +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) +#define XD_SUPPORTED +#define BITL BIT64 +#define PRI_ENTRY "0x%016llx" +#else +#define BITL BIT +#define PRI_ENTRY "0x%08x" +#endif + +/* + * Common flags in the same bit position regardless of which structure level, + * although not every flag is supported at every level, and some may be + * ignored depending on the state of other bits (such as P or PS) + * + * These flags indicate bit position, and can be used for setting flags or + * masks as needed. + */ + +#define MMU_P BITL(0) /** Present */ +#define MMU_RW BITL(1) /** Read-Write */ +#define MMU_US BITL(2) /** User-Supervisor */ +#define MMU_PWT BITL(3) /** Page Write Through */ +#define MMU_PCD BITL(4) /** Page Cache Disable */ +#define MMU_A BITL(5) /** Accessed */ +#define MMU_D BITL(6) /** Dirty */ +#define MMU_PS BITL(7) /** Page Size (non PTE)*/ +#define MMU_PAT BITL(7) /** Page Attribute (PTE) */ +#define MMU_G BITL(8) /** Global */ +#ifdef XD_SUPPORTED +#define MMU_XD BITL(63) /** Execute Disable */ +#else +#define MMU_XD 0 +#endif + +/* Unused PTE bits ignored by the CPU, which we use for our own OS purposes. + * These bits ignored for all paging modes. + */ +#define MMU_IGNORED0 BITL(9) +#define MMU_IGNORED1 BITL(10) +#define MMU_IGNORED2 BITL(11) + +/* Page fault error code flags. See Chapter 4.7 of the Intel SDM vol. 3A. */ +#define PF_P BIT(0) /* 0 Non-present page 1 Protection violation */ +#define PF_WR BIT(1) /* 0 Read 1 Write */ +#define PF_US BIT(2) /* 0 Supervisor mode 1 User mode */ +#define PF_RSVD BIT(3) /* 1 reserved bit set */ +#define PF_ID BIT(4) /* 1 instruction fetch */ +#define PF_PK BIT(5) /* 1 protection-key violation */ +#define PF_SGX BIT(15) /* 1 SGX-specific access control requirements */ + +#ifdef CONFIG_EXCEPTION_DEBUG +/** + * Dump out page table entries for a particular virtual memory address + * + * For the provided memory address, dump out interesting information about + * its mapping to the error log + * + * @param ptables Page tables to walk + * @param virt Virtual address to inspect + */ +void z_x86_dump_mmu_flags(pentry_t *ptables, void *virt); + +/** + * Fetch the page table entry for a virtual memory address + * + * @param paging_level [out] what paging level the entry was found at. + * 0=toplevel + * @param val Value stored in page table entry, with address and flags + * @param ptables Toplevel pointer to page tables + * @param virt Virtual address to lookup + */ +void z_x86_pentry_get(int *paging_level, pentry_t *val, pentry_t *ptables, + void *virt); + +/** + * Debug function for dumping out page tables + * + * Iterates through the entire linked set of page table structures, + * dumping out codes for the configuration of each table entry. + * + * Entry codes: + * + * . - not present + * w - present, writable, not executable + * a - present, writable, executable + * r - present, read-only, not executable + * x - present, read-only, executable + * + * Entry codes in uppercase indicate that user mode may access. + * + * Color is used to indicate the physical mapping characteristics: + * + * yellow - Identity mapping (virt = phys) + * green - Fixed virtual memory mapping (virt = phys + constant) + * magenta - entry is child page table + * cyan - General mapped memory + * + * @param ptables Top-level pointer to the page tables, as programmed in CR3 + */ +void z_x86_dump_page_tables(pentry_t *ptables); +#endif /* CONFIG_EXCEPTION_DEBUG */ + +#ifdef CONFIG_HW_STACK_PROTECTION +/* Legacy function - set identity-mapped MMU stack guard page to RO in the + * kernel's page tables to prevent writes and generate an exception + */ +void z_x86_set_stack_guard(k_thread_stack_t *stack); +#endif + +#ifdef CONFIG_USERSPACE +#ifdef CONFIG_X86_KPTI +/* Defined in linker script. Contains all the data that must be mapped + * in a KPTI table even though US bit is not set (trampoline stack, GDT, + * IDT, etc) + */ +extern uint8_t z_shared_kernel_page_start; +#endif /* CONFIG_X86_KPTI */ +#endif /* CONFIG_USERSPACE */ + +#ifdef CONFIG_X86_PAE +#define PTABLES_ALIGN 0x1fU +#else +#define PTABLES_ALIGN 0xfffU +#endif + +/* Set CR3 to a physical address. There must be a valid top-level paging + * structure here or the CPU will triple fault. The incoming page tables must + * have the same kernel mappings wrt supervisor mode. Don't use this function + * unless you know exactly what you are doing. + */ +static inline void z_x86_cr3_set(uintptr_t phys) +{ + __ASSERT((phys & PTABLES_ALIGN) == 0U, "unaligned page tables"); +#ifdef CONFIG_X86_64 + __asm__ volatile("movq %0, %%cr3\n\t" : : "r" (phys) : "memory"); +#else + __asm__ volatile("movl %0, %%cr3\n\t" : : "r" (phys) : "memory"); +#endif +} + +/* Return cr3 value, which is the physical (not virtual) address of the + * current set of page tables + */ +static inline uintptr_t z_x86_cr3_get(void) +{ + uintptr_t cr3; +#ifdef CONFIG_X86_64 + __asm__ volatile("movq %%cr3, %0\n\t" : "=r" (cr3)); +#else + __asm__ volatile("movl %%cr3, %0\n\t" : "=r" (cr3)); +#endif + return cr3; +} + +/* Return the virtual address of the page tables installed in this CPU in CR3 */ +static inline pentry_t *z_x86_page_tables_get(void) +{ + return (pentry_t *)z_x86_cr3_get(); +} + +/* Return cr2 value, which contains the page fault linear address. + * See Section 6.15 of the IA32 Software Developer's Manual vol 3. + * Used by page fault handling code. + */ +static inline void *z_x86_cr2_get(void) +{ + void *cr2; +#ifdef CONFIG_X86_64 + __asm__ volatile("movq %%cr2, %0\n\t" : "=r" (cr2)); +#else + __asm__ volatile("movl %%cr2, %0\n\t" : "=r" (cr2)); +#endif + return cr2; +} + +/* Kernel's page table. This is in CR3 for all supervisor threads. + * if KPTI is enabled, we switch to this when handling exceptions or syscalls + */ +extern pentry_t z_x86_kernel_ptables[]; + +/* Get the page tables used by this thread during normal execution */ +static inline pentry_t *z_x86_thread_page_tables_get(struct k_thread *thread) +{ +#if defined(CONFIG_USERSPACE) && !defined(CONFIG_X86_COMMON_PAGE_TABLE) + if (!IS_ENABLED(CONFIG_X86_KPTI) || + (thread->base.user_options & K_USER) != 0U) { + /* If KPTI is enabled, supervisor threads always use + * the kernel's page tables and not the page tables associated + * with their memory domain. + */ + return (pentry_t *)(thread->arch.ptables); + } +#endif + return z_x86_kernel_ptables; +} + +#ifdef CONFIG_SMP +/* Handling function for TLB shootdown inter-processor interrupts. */ +void z_x86_tlb_ipi(const void *arg); +#endif + +#ifdef CONFIG_X86_COMMON_PAGE_TABLE +void z_x86_swap_update_common_page_table(struct k_thread *incoming); +#endif +#endif /* ZEPHYR_ARCH_X86_INCLUDE_X86_MMU_H */ diff --git a/arch/x86/intel64.cmake b/arch/x86/intel64.cmake index 24062d27f4f15c..a2a9f73b88922c 100644 --- a/arch/x86/intel64.cmake +++ b/arch/x86/intel64.cmake @@ -3,4 +3,9 @@ zephyr_cc_option(-m64) +set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_ARCH "i386:x86-64") +set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT "elf64-x86-64") +get_property(OUTPUT_ARCH GLOBAL PROPERTY PROPERTY_OUTPUT_ARCH) +get_property(OUTPUT_FORMAT GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT) + add_subdirectory(core) diff --git a/arch/x86/timing.c b/arch/x86/timing.c new file mode 100644 index 00000000000000..f608fac539cf43 --- /dev/null +++ b/arch/x86/timing.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +static uint64_t tsc_freq; + +void arch_timing_x86_init(void) +{ + uint32_t cyc_start = k_cycle_get_32(); + uint64_t tsc_start = z_tsc_read(); + + k_busy_wait(10 * USEC_PER_MSEC); + + uint32_t cyc_end = k_cycle_get_32(); + uint64_t tsc_end = z_tsc_read(); + + uint64_t cyc_freq = sys_clock_hw_cycles_per_sec(); + + /* + * cycles are in 32-bit, and delta must be + * calculated in 32-bit percision. Or it would + * wrapping around in 64-bit. + */ + uint64_t dcyc = (uint32_t)cyc_end - (uint32_t)cyc_start; + + uint64_t dtsc = tsc_end - tsc_start; + + tsc_freq = (cyc_freq * dtsc) / dcyc; +} + +uint64_t arch_timing_x86_freq_get(void) +{ + return tsc_freq; +} + +void arch_timing_init(void) +{ + arch_timing_x86_init(); +} + +void arch_timing_start(void) +{ +} + +void arch_timing_stop(void) +{ +} + +timing_t arch_timing_counter_get(void) +{ + return k_cycle_get_32(); +} + +uint64_t arch_timing_cycles_get(volatile timing_t *const start, + volatile timing_t *const end) +{ + return (*end - *start); +} + + +uint64_t arch_timing_freq_get(void) +{ + return arch_timing_x86_freq_get(); +} + +uint64_t arch_timing_cycles_to_ns(uint64_t cycles) +{ + return k_cyc_to_ns_floor64(cycles); +} + +uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) +{ + return arch_timing_cycles_to_ns(cycles) / count; +} + +uint32_t arch_timing_freq_get_mhz(void) +{ + return (uint32_t)(arch_timing_freq_get() / 1000000); +} diff --git a/arch/x86/zefi/README.txt b/arch/x86/zefi/README.txt new file mode 100644 index 00000000000000..85f0125829a592 --- /dev/null +++ b/arch/x86/zefi/README.txt @@ -0,0 +1,91 @@ +Operation +========= + +Run the "zefi.py" script, passing a path to a built zephyr.elf file +(NOT a "zephyr.strip" intended for grub/multiboot loading -- we need +the symbol table) for the target as its sole argument. It will emit a +"zephyr.efi" file in the current directory. Copy this to your target +device's EFI boot partition via whatever means you like and run it +from the EFI shell. + +Theory +====== + +This works by creating a "zephyr.efi" EFI binary containing a zephyr +image extracted from a built zephyr.elf file. EFI applications are +relocatable, and cannot be placed at specific locations in memory. +Instead, the stub code will copy the embedded zephyr sections to the +appropriate locations at startup, clear any zero-filled (BSS, etc...) +areas, then jump into the 64 bit entry point. + +Arguably this is needlessly inefficient, having to load the whole +binary into memory and copy it vs. a bootloader like grub that will +load it from the EFI boot filesystem into its correct location with no +copies. But then, the biggest Zephyr application binaries we have on +any platform top out at 200kb or so, and grub is at minimum about 5x +that size, and potentially MUCH more if you start enabling the default +modules. + +Source Code & Linkage +===================== + +The code and link environment here is non-obvious. The simple rules +are: + +1. All code must live in a single C file +2. All symbols must be declared static + +And if you forget this and use a global by mistake, the build will +work fine and then fail inexplicably at runtime with a garbage +address. The sole exception is the "efi_entry()" function, whose +address is not generated at runtime by the C code here (it's address +goes into the PE file header instead). + +The reason is that we're building an EFI Application Binary with a +Linux toolchain. EFI binaries are relocatable PE-COFF files -- +basically Windows DLLs. But our compiler only generates code for ELF +targets. + +These environments differ in the way they implemenqt position +independent code. Non-static global variables and function addresses +in ELF get found via GOT and PLT tables that are populated at load +time by a system binary (ld-linux.so). But there is no ld-linux.so in +EFI firmware, and the EFI loader only knows how to fill in the PE +relocation fields, which are a different data structure. + +So we can only rely on the C file's internal linkage, which is done +via the x86_64 RIP-relative addressing mode and doesn't rely on any +support from the environment. But that only works for symbols that +the compiler (not the linker) knows a-priori will never be in +externally linked shared libraries. Which is to say: only static +symbols work. + +You might ask: why build a position-independent executable in the +first place? Why not just link to a specific address? The PE-COFF +format certainly allows that, and the UEFI specification doesn't +clearly rule it out. But my experience with real EFI loaders is that +they ignore the preferred load address and will put the image at +arbitrary locations in memory. I couldn't make it work, basically. + +Bugs +==== + +No support for 32 bit EFI environments. This would be a very tall +order given the linker constraints described above (i386 doesn't have +a IP-relative addressing mode, so we'd have to do some kind of +relocation of our own). Will probably never happen unless we move to +a proper PE-COFF toolchain. + +There is no protection against colliding mappings. We just assume +that the EFI environment will load our image at an address that +doesn't overlap with the target Zephyr memory. In practice on the +systems I've tried, EFI uses memory near the top of 32-bit-accessible +physical memory, while Zephyr prefers to load into the bottom of RAM +at 0x10000. Even given collisions, this is probably tolerable, as we +could control the Zephyr mapping addresses per-platform if needed to +sneak around EFI areas. But the Zephyr loader should at least detect +the overlap and warn about it. + +It runs completely standalone, writing output to the current +directory, and uses the (x86_64 linux) host toolchain right now, when +it should be integrated with the Zephyr toolchain and build system. diff --git a/arch/x86/zefi/efi.h b/arch/x86/zefi/efi.h new file mode 100644 index 00000000000000..a7b6654ce45e6b --- /dev/null +++ b/arch/x86/zefi/efi.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _EFI_H +#define _EFI_H + +/* Minimal restatement of a minimal subset of the EFI runtime API */ + +#define __abi __attribute__((ms_abi)) + +typedef uintptr_t __abi (*efi_fn1_t)(void *); +typedef uintptr_t __abi (*efi_fn2_t)(void *, void *); +typedef uintptr_t __abi (*efi_fn3_t)(void *, void *, void *); +typedef uintptr_t __abi (*efi_fn4_t)(void *, void *, void *, void *); + +struct efi_simple_text_output { + efi_fn2_t Reset; + efi_fn2_t OutputString; + efi_fn2_t TestString; + efi_fn4_t QueryMode; + efi_fn2_t SetMode; + efi_fn2_t SetAttribute; + efi_fn1_t ClearScreen; + efi_fn3_t SetCursorPosition; + efi_fn2_t EnableCursor; + struct simple_text_output_mode *Mode; +}; + +struct efi_system_table { + uint64_t Signature; + uint32_t Revision; + uint32_t HeaderSize; + uint32_t CRC32; + uint32_t Reserved; + uint16_t *FirmwareVendor; + uint32_t FirmwareRevision; + void *ConsoleInHandle; + struct efi_simple_input *ConIn; + void *ConsoleOutHandle; + struct efi_simple_text_output *ConOut; + void *StandardErrorHandle; + struct efi_simple_text_output *StdErr; + struct efi_runtime_services *RuntimeServices; + struct efi_boot_services *BootServices; + uint64_t NumberOfTableEntries; + struct efi_configuration_table *ConfigurationTable; +}; + +#endif /* _EFI_H */ diff --git a/arch/x86/zefi/efi.ld b/arch/x86/zefi/efi.ld new file mode 100644 index 00000000000000..644a357557f17e --- /dev/null +++ b/arch/x86/zefi/efi.ld @@ -0,0 +1,49 @@ +ENTRY(efi_entry) + +SECTIONS { + + /* Pick a reasonable base address, EFI won't load us there anyway */ + . = 0x4000000; + .text : { + *(.text) + *(.rodata) + } + + /* Must be a separately visible section to the EFI loader, doesn't + * need to be page-aligned and can be immediately after text/rodata */ + .reloc : { *(.reloc) } + + /* Must be page-aligned or EFI balks */ + . = ALIGN(4096); + .data : { + *(.data) + *(COMMON) + *(.bss) + + *(.runtime_data_end) /* Must be last. Obviously. */ + } + + /* Because binutils ld really likes to "helpfully" ignore the section + * directives and drop junk in weird places. + */ + .trash_bin : { + *(.comment) + *(.data.rel*) + *(.dynamic) + *(.dynbss) + *(.dynstr) + *(.dynsym) + *(.eh_frame) + *(.gnu.hash) + *(.gnu.version*) + *(.got) + *(.got.plt) + *(.hash) + *(.note.*) + *(.plt) + *(.plt.*) + *(.rela.*) + *(.rel.local) + } + +} /* SECTIONS */ diff --git a/arch/x86/zefi/printf.h b/arch/x86/zefi/printf.h new file mode 100644 index 00000000000000..12e5182be21420 --- /dev/null +++ b/arch/x86/zefi/printf.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +/* Tiny, but not-as-primitive-as-it-looks implementation of something + * like s/n/printf(). Handles %d, %x, %p, %c and %s only, allows a + * "l" qualifier on %d and %x (and silently ignores one %s/%c/%p). + * Accepts, but ignores, field width and precision values that match: + * the regex: [0-9]*\.?[0-9]* + */ + +struct _pfr { + char *buf; + int len; + int idx; +}; + +/* Set this function pointer to something that generates output */ +static void (*z_putchar)(int c); + +static void pc(struct _pfr *r, int c) +{ + if (r->buf) { + if (r->idx <= r->len) { + r->buf[r->idx] = c; + } + } else { + z_putchar(c); + } + r->idx++; +} + +static void prdec(struct _pfr *r, long v) +{ + if (v < 0) { + pc(r, '-'); + v = -v; + } + + char digs[11 * sizeof(long)/4]; + int i = sizeof(digs) - 1; + + digs[i--] = 0; + while (v || i == 9) { + digs[i--] = '0' + (v % 10); + v /= 10; + } + + while (digs[++i]) { + pc(r, digs[i]); + } +} + +static void endrec(struct _pfr *r) +{ + if (r->buf && r->idx < r->len) { + r->buf[r->idx] = 0; + } +} + +static int vpf(struct _pfr *r, const char *f, va_list ap) +{ + for (/**/; *f; f++) { + bool islong = false; + + if (*f != '%') { + pc(r, *f); + continue; + } + + if (f[1] == 'l') { + islong = sizeof(long) > 4; + f++; + } + + /* Ignore (but accept) field width and precision values */ + while (f[1] >= '0' && f[1] <= '9') { + f++; + } + if (f[1] == '.') { + f++; + } + while (f[1] >= '0' && f[1] <= '9') { + f++; + } + + switch (*(++f)) { + case 0: + return r->idx; + case '%': + pc(r, '%'); + break; + case 'c': + pc(r, va_arg(ap, int)); + break; + case 's': { + char *s = va_arg(ap, char *); + + while (*s) + pc(r, *s++); + break; + } + case 'p': + pc(r, '0'); + pc(r, 'x'); /* fall through... */ + islong = sizeof(long) > 4; + case 'x': { + int sig = 0; + unsigned long v = islong ? va_arg(ap, unsigned long) + : va_arg(ap, unsigned int); + for (int i = 2*sizeof(long) - 1; i >= 0; i--) { + int d = (v >> (i*4)) & 0xf; + + sig += !!d; + if (sig || i == 0) + pc(r, "0123456789abcdef"[d]); + } + break; + } + case 'd': + prdec(r, va_arg(ap, int)); + break; + default: + pc(r, '%'); + pc(r, *f); + } + } + endrec(r); + return r->idx; +} + +#define CALL_VPF(rec) \ + va_list ap; \ + va_start(ap, f); \ + ret = vpf(&r, f, ap); \ + va_end(ap); + +static inline int snprintf(char *buf, unsigned long len, const char *f, ...) +{ + int ret = 0; + struct _pfr r = { .buf = buf, .len = len }; + + CALL_VPF(&r); + return ret; +} + +static inline int sprintf(char *buf, const char *f, ...) +{ + int ret = 0; + struct _pfr r = { .buf = buf, .len = 0x7fffffff }; + + CALL_VPF(&r); + return ret; +} + +static inline int printf(const char *f, ...) +{ + int ret = 0; + struct _pfr r = {0}; + + CALL_VPF(&r); + return ret; +} diff --git a/arch/x86/zefi/zefi.c b/arch/x86/zefi/zefi.c new file mode 100644 index 00000000000000..b12dcca3aeab52 --- /dev/null +++ b/arch/x86/zefi/zefi.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "efi.h" +#include "printf.h" +#include + +#define PUTCHAR_BUFSZ 128 + +/* The linker places this dummy last in the data memory. We can't use + * traditional linker address symbols because we're relocatable; the + * linker doesn't know what the runtime address will be. The compiler + * has to emit code to find this thing's address at runtime via an + * offset from RIP. It's a qword so we can guarantee alignment of the + * stuff after. + */ +static __attribute__((section(".runtime_data_end"))) +uint64_t runtime_data_end[1] = { 0x1111aa8888aa1111L }; + +#define EXT_DATA_START ((void *) &runtime_data_end[1]) + +static struct efi_system_table *efi; + +static void efi_putchar(int c) +{ + static uint16_t efibuf[PUTCHAR_BUFSZ + 1]; + static int n; + + if (c == '\n') { + efi_putchar('\r'); + } + + efibuf[n++] = c; + + if (c == '\n' || n == PUTCHAR_BUFSZ) { + efibuf[n] = 0; + efi->ConOut->OutputString(efi->ConOut, efibuf); + n = 0; + } +} + +/* Existing x86_64 EFI environments have a bad habit of leaving the + * HPET timer running. This then fires later on, once the OS has + * started. If the timing isn't right, it can happen before the OS + * HPET driver gets a chance to disable it. And because we do the + * handoff (necessarily) with interrupts disabled, it's not actually + * possible for the OS to reliably disable it in time anyway. + * + * Basically: it's our job as the bootloader to ensure that no + * interrupt sources are live before entering the OS. Clear the + * interrupt enable bit of HPET timer zero. + */ +static void disable_hpet(void) +{ + uint64_t *hpet = (uint64_t *)0xfed00000L; + + hpet[32] &= ~4; +} + +/* FIXME: if you check the generated code, "ms_abi" calls like this + * have to SPILL HALF OF THE SSE REGISTER SET TO THE STACK on entry + * because of the way the conventions collide. Is there a way to + * prevent/suppress that? + */ +uintptr_t __abi efi_entry(void *img_handle, struct efi_system_table *sys_tab) +{ + efi = sys_tab; + z_putchar = efi_putchar; + printf("*** Zephyr EFI Loader ***\n"); + + for (int i = 0; i < sizeof(zefi_zsegs)/sizeof(zefi_zsegs[0]); i++) { + int bytes = zefi_zsegs[i].sz; + uint8_t *dst = (uint8_t *)zefi_zsegs[i].addr; + + printf("Zeroing %d bytes of memory at %p\n", bytes, dst); + for (int j = 0; j < bytes; j++) { + dst[j] = 0; + } + } + + for (int i = 0; i < sizeof(zefi_dsegs)/sizeof(zefi_dsegs[0]); i++) { + int bytes = zefi_dsegs[i].sz; + int off = zefi_dsegs[i].off; + uint8_t *dst = (uint8_t *)zefi_dsegs[i].addr; + uint8_t *src = &((uint8_t *)EXT_DATA_START)[off]; + + printf("Copying %d data bytes to %p from image offset %d\n", + bytes, dst, zefi_dsegs[i].off); + for (int j = 0; j < bytes; j++) { + dst[j] = src[j]; + } + } + + unsigned char *code = (void *)zefi_entry; + + printf("Jumping to Entry Point: %p (%x %x %x %x %x %x %x)\n", + code, code[0], code[1], code[2], code[3], + code[4], code[5], code[6]); + + disable_hpet(); + + /* The EFI console seems to be buffered, give it a little time + * to drain before we start banging on the same UART from the + * OS. + */ + for (volatile int i = 0; i < 50000000; i++) { + } + + __asm__ volatile("cli; jmp *%0" :: "r"(code)); + + return 0; +} + +/* Trick cribbed shamelessly from gnu-efi. We need to emit a ".reloc" + * section into the image with a single dummy entry for the EFI loader + * to think we're a valid PE file, gcc won't because it thinks we're + * ELF. + */ +uint32_t relocation_dummy; +__asm__(".section .reloc\n" + "base_relocation_block:\n" + ".long relocation_dummy - base_relocation_block\n" + ".long 0x0a\n" + ".word 0\n"); diff --git a/arch/x86/zefi/zefi.py b/arch/x86/zefi/zefi.py new file mode 100755 index 00000000000000..ee57e5cd192027 --- /dev/null +++ b/arch/x86/zefi/zefi.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import os.path +import subprocess +import elftools.elf.elffile +import argparse + +ENTRY_SYM = "__start64" +GCC = "gcc" +OBJCOPY = "objcopy" + +def verbose(msg): + if args.verbose: + print(msg) + +def build_elf(elf_file): + base_dir = os.path.dirname(os.path.abspath(__file__)) + + cfile = os.path.join(base_dir, "zefi.c") + ldscript = os.path.join(base_dir, "efi.ld") + + assert os.path.isfile(cfile) + assert os.path.isfile(ldscript) + + # + # Open the ELF file up and find our entry point + # + fp = open(elf_file, "rb") + ef = elftools.elf.elffile.ELFFile(fp) + + symtab = ef.get_section_by_name(".symtab") + entry_addr = symtab.get_symbol_by_name(ENTRY_SYM)[0].entry.st_value + + verbose("Entry point address (symbol: %s) 0x%x" % (ENTRY_SYM, entry_addr)) + + # + # Parse the ELF file and extract segment data + # + + data_blob = b'' + data_segs = [] + zero_segs = [] + + for seg in ef.iter_segments(): + h = seg.header + if h.p_type != "PT_LOAD": + continue + + assert h.p_memsz >= h.p_filesz + assert len(seg.data()) == h.p_filesz + + if h.p_filesz > 0: + sd = seg.data() + verbose("%d bytes of data at 0x%x, data offset %d" + % (len(sd), h.p_vaddr, len(data_blob))) + data_segs.append((h.p_vaddr, len(sd), len(data_blob))) + data_blob = data_blob + sd + + if h.p_memsz > h.p_filesz: + bytesz = h.p_memsz - h.p_filesz + addr = h.p_vaddr + h.p_filesz + verbose("%d bytes of zero-fill at 0x%x" % (bytesz, addr)) + zero_segs.append((addr, bytesz)) + + verbose(f"{len(data_blob)} bytes of data to include in image") + + # + # Emit a C header containing the metadata + # + cf = open("zefi-segments.h", "w") + + cf.write("/* GENERATED CODE. DO NOT EDIT. */\n\n") + + cf.write("/* Sizes and offsets specified in 4-byte units.\n") + cf.write(" * All addresses 4-byte aligned.\n") + cf.write(" */\n") + + cf.write("struct data_seg { uint64_t addr; uint32_t sz; uint32_t off; };\n\n") + + cf.write("static struct data_seg zefi_dsegs[] = {\n") + for s in data_segs: + cf.write(" { 0x%x, %d, %d },\n" + % (s[0], s[1], s[2])) + cf.write("};\n\n") + + cf.write("struct zero_seg { uint64_t addr; uint32_t sz; };\n\n") + + cf.write("static struct zero_seg zefi_zsegs[] = {\n") + for s in zero_segs: + cf.write(" { 0x%x, %d },\n" + % (s[0], s[1])) + cf.write("};\n\n") + + cf.write("static uintptr_t zefi_entry = 0x%xUL;\n" % (entry_addr)) + + cf.close() + + verbose("Metadata header generated.") + + # + # Build + # + + # First stage ELF binary. Flag notes: + # + Stack protector is default on some distros and needs library support + # + We need pic to enforce that the linker adds no relocations + # + UEFI can take interrupts on our stack, so no red zone + # + UEFI API assumes 16-bit wchar_t + cmd = [GCC, "-shared", "-Wall", "-Werror", "-I.", + "-fno-stack-protector", "-fpic", "-mno-red-zone", "-fshort-wchar", + "-Wl,-nostdlib", "-T", ldscript, "-o", "zefi.elf", cfile] + verbose(" ".join(cmd)) + subprocess.run(cmd, check = True) + + # Extract the .data segment and append our extra blob + cmd = [OBJCOPY, "-O", "binary", "-j", ".data", "zefi.elf", "data.dat"] + verbose(" ".join(cmd)) + subprocess.run(cmd, check = True) + + assert (os.stat("data.dat").st_size % 8) == 0 + df = open("data.dat", "ab") + df.write(data_blob) + df.close() + + # FIXME: this generates warnings about our unused trash section having to be moved to make room. Set its address far away... + subprocess.run([OBJCOPY, "--update-section", ".data=data.dat", + "zefi.elf"], check = True) + + # Convert it to a PE-COFF DLL. + cmd = [OBJCOPY, "--target=efi-app-x86_64", + "-j", ".text", "-j", ".reloc", "-j", ".data", + "zefi.elf", "zephyr.efi"] + verbose(" ".join(cmd)) + subprocess.run(cmd, check = True) + + verbose("Build complete; zephyr.efi wrapper binary is ready") + + +def parse_args(): + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + + parser.add_argument("-f", "--elf-file", required=True, help="Input file") + parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output") + + return parser.parse_args() + +if __name__ == "__main__": + + args = parse_args() + verbose(f"Working on {args.elf_file}...") + build_elf(args.elf_file) diff --git a/arch/xtensa/core/CMakeLists.txt b/arch/xtensa/core/CMakeLists.txt index 5fc828758ed0ae..f8e62262610d69 100644 --- a/arch/xtensa/core/CMakeLists.txt +++ b/arch/xtensa/core/CMakeLists.txt @@ -16,5 +16,6 @@ zephyr_library_sources( zephyr_library_sources_ifndef(CONFIG_ATOMIC_OPERATIONS_C atomic.S) zephyr_library_sources_ifdef(CONFIG_XTENSA_USE_CORE_CRT1 crt1.S) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) add_subdirectory(startup) diff --git a/arch/xtensa/core/crt1.S b/arch/xtensa/core/crt1.S index 29881f707cc004..bcbcd2f1b56226 100644 --- a/arch/xtensa/core/crt1.S +++ b/arch/xtensa/core/crt1.S @@ -138,7 +138,7 @@ _start: movi a0, 0 # endif -# ifdef CONFIG_SMP +# if CONFIG_MP_NUM_CPUS > 1 /* Only clear BSS when running on core 0 */ rsr a3, PRID extui a3, a3, 0, 8 /* extract core ID */ @@ -186,7 +186,7 @@ _start: #endif /* !XCHAL_HAVE_BOOTLOADER */ -#ifdef CONFIG_SMP +#if CONFIG_MP_NUM_CPUS > 1 /* * z_cstart() is only for CPU #0. * Other CPUs have different entry point. @@ -197,10 +197,9 @@ _start: CALL z_mp_entry 2: -#endif /* CONFIG_SMP */ +#endif /* Enter C domain, never returns from here */ CALL z_cstart .size _start, . - _start - diff --git a/arch/xtensa/core/fatal.c b/arch/xtensa/core/fatal.c index 1576ece0f7e8f6..cea4c4f8203b05 100644 --- a/arch/xtensa/core/fatal.c +++ b/arch/xtensa/core/fatal.c @@ -11,7 +11,7 @@ #include #include #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #ifdef XT_SIMULATOR #include diff --git a/arch/xtensa/core/irq_manage.c b/arch/xtensa/core/irq_manage.c index 4f6c97a8fbac31..b38d8d95aabe35 100644 --- a/arch/xtensa/core/irq_manage.c +++ b/arch/xtensa/core/irq_manage.c @@ -27,7 +27,7 @@ * @return N/A */ -void z_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags) +void z_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { __ASSERT(prio < XCHAL_EXCM_LEVEL + 1, "invalid priority %d! values must be less than %d\n", @@ -40,8 +40,8 @@ void z_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags) #ifdef CONFIG_DYNAMIC_INTERRUPTS #ifndef CONFIG_MULTI_LEVEL_INTERRUPTS int z_arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *parameter), - void *parameter, u32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { ARG_UNUSED(flags); ARG_UNUSED(priority); @@ -51,8 +51,8 @@ int z_arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, } #else /* !CONFIG_MULTI_LEVEL_INTERRUPTS */ int z_arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(void *parameter), - void *parameter, u32_t flags) + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags) { return z_soc_irq_connect_dynamic(irq, priority, routine, parameter, flags); diff --git a/arch/xtensa/core/irq_offload.c b/arch/xtensa/core/irq_offload.c index 9fcfb1be568d5e..a3d1a3cc619786 100644 --- a/arch/xtensa/core/irq_offload.c +++ b/arch/xtensa/core/irq_offload.c @@ -14,16 +14,16 @@ */ static irq_offload_routine_t offload_routine; -static void *offload_param; +static const void *offload_param; /* Called by ISR dispatcher */ -void z_irq_do_offload(void *unused) +void z_irq_do_offload(const void *unused) { ARG_UNUSED(unused); offload_routine(offload_param); } -void arch_irq_offload(irq_offload_routine_t routine, void *parameter) +void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { IRQ_CONNECT(CONFIG_IRQ_OFFLOAD_INTNUM, XCHAL_EXCM_LEVEL, z_irq_do_offload, NULL, 0); diff --git a/arch/xtensa/core/tls.c b/arch/xtensa/core/tls.c new file mode 100644 index 00000000000000..9f22cafad31798 --- /dev/null +++ b/arch/xtensa/core/tls.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#if XCHAL_HAVE_THREADPTR == 0 +#error SoC does not support THREADPTR for thread local storage. +#endif + +size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) +{ + /* + * TLS area has some data fields following by + * thread data and bss. These fields are supposed to be + * used by toolchain and OS TLS code to aid in locating + * the TLS data/bss. Zephyr currently has no use for + * this so we can simply skip these. However, since GCC + * is generating code assuming these fields are there, + * we simply skip them when setting the TLS pointer. + */ + + /* + * Since we are populating things backwards, + * setup the TLS data/bss area first. + */ + stack_ptr -= z_tls_data_size(); + z_tls_copy(stack_ptr); + + /* Skip two pointers due to toolchain */ + stack_ptr -= sizeof(uintptr_t) * 2; + + /* + * Set thread TLS pointer which is used in + * context switch to point to TLS area. + */ + new_thread->tls = POINTER_TO_UINT(stack_ptr); + + return (z_tls_data_size() + (sizeof(uintptr_t) * 2)); +} diff --git a/arch/xtensa/core/xtensa-asm2-util.S b/arch/xtensa/core/xtensa-asm2-util.S index e14d4cf970a6e7..436c691f1fcb68 100644 --- a/arch/xtensa/core/xtensa-asm2-util.S +++ b/arch/xtensa/core/xtensa-asm2-util.S @@ -167,6 +167,10 @@ _restore_context: #if XCHAL_HAVE_S32C1I l32i a0, a1, BSA_SCOMPARE1_OFF wsr.SCOMPARE1 a0 +#endif +#if XCHAL_HAVE_THREADPTR && defined(CONFIG_THREAD_LOCAL_STORAGE) + l32i a0, a1, BSA_THREADPTR_OFF + wur.THREADPTR a0 #endif rsync @@ -210,6 +214,18 @@ xtensa_switch: /* Now the high registers */ call0 xtensa_save_high_regs +#ifdef CONFIG_KERNEL_COHERENCE + /* Flush the stack. The top of stack was stored for us in + * EXCSAVE3 (FIXME: shouldn't be hardcoded!) by arch_cohere_stacks(). + */ + rsr.EXCSAVE3 a0 + mov a3, a1 +flushloop: + dhwb a3, 0 + addi a3, a3, XCHAL_DCACHE_LINESIZE + blt a3, a0, flushloop +#endif + /* Restore the A3 argument we spilled earlier (via the base * save pointer pushed at the bottom of the stack) and set the * stack to the "new" context out of the A2 spill slot. @@ -225,8 +241,8 @@ xtensa_switch: */ l32i a1, a2, BSA_A2_OFF -#ifdef CONFIG_EXECUTION_BENCHMARKING - call4 read_timer_end_of_swap +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + call4 z_thread_mark_switched_in #endif j _restore_context _switch_restore_pc: diff --git a/arch/xtensa/core/xtensa-asm2.c b/arch/xtensa/core/xtensa-asm2.c index aba74df6e1247f..16ee3578828a0e 100644 --- a/arch/xtensa/core/xtensa-asm2.c +++ b/arch/xtensa/core/xtensa-asm2.c @@ -13,9 +13,9 @@ #include <_soc_inthandlers.h> #include -LOG_MODULE_DECLARE(os); +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); -void *xtensa_init_stack(int *stack_top, +void *xtensa_init_stack(struct k_thread *thread, int *stack_top, void (*entry)(void *, void *, void *), void *arg1, void *arg2, void *arg3) { @@ -27,13 +27,17 @@ void *xtensa_init_stack(int *stack_top, * start will decrement the stack pointer by 16. */ const int bsasz = BASE_SAVE_AREA_SIZE - 16; - void **bsa = (void **) (((char *) stack_top) - bsasz); + void *ret, **bsa = (void **) (((char *) stack_top) - bsasz); (void)memset(bsa, 0, bsasz); bsa[BSA_PC_OFF/4] = z_thread_entry; bsa[BSA_PS_OFF/4] = (void *)(PS_WOE | PS_UM | PS_CALLINC(1)); +#if XCHAL_HAVE_THREADPTR && defined(CONFIG_THREAD_LOCAL_STORAGE) + bsa[BSA_THREADPTR_OFF/4] = UINT_TO_POINTER(thread->tls); +#endif + /* Arguments to z_thread_entry(). Remember these start at A6, * which will be rotated into A2 by the ENTRY instruction that * begins the C function. And A4-A7 and A8-A11 are optional @@ -53,27 +57,24 @@ void *xtensa_init_stack(int *stack_top, * as the handle */ bsa[-9] = bsa; - return &bsa[-9]; + ret = &bsa[-9]; + +#ifdef CONFIG_KERNEL_COHERENCE + xthal_dcache_region_writeback(ret, (char *)stack_top - (char *)ret); +#endif + return ret; } void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - size_t sz, k_thread_entry_t entry, - void *p1, void *p2, void *p3, - int prio, unsigned int opts) + char *stack_ptr, k_thread_entry_t entry, + void *p1, void *p2, void *p3) { - char *base = Z_THREAD_STACK_BUFFER(stack); - char *top = base + sz; - - /* Align downward. The API as specified requires a runtime check. */ - top = (char *)(((unsigned int)top) & ~3); - - z_new_thread_init(thread, base, sz); - - thread->switch_handle = xtensa_init_stack((void *)top, entry, + thread->switch_handle = xtensa_init_stack(thread, + (int *)stack_ptr, entry, p1, p2, p3); } -void z_irq_spurious(void *arg) +void z_irq_spurious(const void *arg) { int irqs, ie; @@ -139,7 +140,7 @@ static inline unsigned int get_bits(int offset, int num_bits, unsigned int val) #define DEF_INT_C_HANDLER(l) \ void *xtensa_int##l##_c(void *interrupted_stack) \ { \ - u32_t irqs, intenable, m; \ + uint32_t irqs, intenable, m; \ __asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \ __asm__ volatile("rsr.intenable %0" : "=r"(intenable)); \ irqs &= intenable; \ @@ -188,7 +189,7 @@ void *xtensa_excint1_c(int *interrupted_stack) bsa[BSA_PC_OFF/4] += 3; } else { - u32_t ps = bsa[BSA_PS_OFF/4]; + uint32_t ps = bsa[BSA_PS_OFF/4]; __asm__ volatile("rsr.excvaddr %0" : "=r"(vaddr)); @@ -219,7 +220,7 @@ void *xtensa_excint1_c(int *interrupted_stack) int z_xtensa_irq_is_enabled(unsigned int irq) { - u32_t ie; + uint32_t ie; __asm__ volatile("rsr.intenable %0" : "=r"(ie)); diff --git a/arch/xtensa/include/kernel_arch_func.h b/arch/xtensa/include/kernel_arch_func.h index 6217f142d85f02..8485969e7ab49b 100644 --- a/arch/xtensa/include/kernel_arch_func.h +++ b/arch/xtensa/include/kernel_arch_func.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2016 Wind River Systems, Inc. * Copyright (c) 2016 Cadence Design Systems, Inc. + * Copyright (c) 2020 Intel Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -25,13 +26,20 @@ extern void z_xtensa_fatal_error(unsigned int reason, const z_arch_esf_t *esf); /* Defined in xtensa_context.S */ extern void z_xt_coproc_init(void); -extern K_THREAD_STACK_ARRAY_DEFINE(z_interrupt_stacks, CONFIG_MP_NUM_CPUS, +extern K_KERNEL_STACK_ARRAY_DEFINE(z_interrupt_stacks, CONFIG_MP_NUM_CPUS, CONFIG_ISR_STACK_SIZE); 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 + */ + xthal_dcache_all_writeback_inv(); +#endif + cpu0->nested = 0; /* The asm2 scheme keeps the kernel pointer in MISC0 for easy @@ -43,8 +51,8 @@ static ALWAYS_INLINE void arch_kernel_init(void) WSR(CONFIG_XTENSA_KERNEL_CPU_PTR_SR, cpu0); #ifdef CONFIG_INIT_STACKS - memset(Z_THREAD_STACK_BUFFER(z_interrupt_stacks[0]), 0xAA, - CONFIG_ISR_STACK_SIZE); + memset(Z_KERNEL_STACK_BUFFER(z_interrupt_stacks[0]), 0xAA, + K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[0])); #endif } @@ -55,6 +63,60 @@ static inline void arch_switch(void *switch_to, void **switched_from) return xtensa_switch(switch_to, switched_from); } +/* FIXME: we don't have a framework for including this from the SoC + * layer, so we define it in the arch code here. + */ +#ifdef CONFIG_SOC_FAMILY_INTEL_ADSP +static inline bool arch_mem_coherent(void *ptr) +{ + size_t addr = (size_t) ptr; + + return addr >= 0x80000000 && addr < 0xa0000000; +} +#endif + +#ifdef CONFIG_KERNEL_COHERENCE +static inline void arch_cohere_stacks(struct k_thread *old_thread, + void *old_switch_handle, + struct k_thread *new_thread) +{ + size_t ostack = old_thread->stack_info.start; + size_t osz = old_thread->stack_info.size; + size_t osp = (size_t) old_switch_handle; + + size_t nstack = new_thread->stack_info.start; + size_t nsz = new_thread->stack_info.size; + size_t nsp = (size_t) new_thread->switch_handle; + + xthal_dcache_region_invalidate((void *)nsp, (nstack + nsz) - nsp); + + /* FIXME: dummy initializion threads don't have stack info set + * up and explode the logic above. Find a way to get this + * test out of the hot paths! + */ + if (old_thread->base.thread_state & _THREAD_DUMMY) { + return; + } + + /* In interrupt context, we have a valid frame already from + * the interrupt entry code, but for arch_switch() that hasn't + * happened yet. It will do the flush itself, we just have to + * calculate the boundary for it. + */ + if (old_switch_handle != NULL) { + xthal_dcache_region_writeback((void *)osp, + (ostack + osz) - osp); + } else { + /* FIXME: hardcoding EXCSAVE3 is bad, should be + * configurable a-la XTENSA_KERNEL_CPU_PTR_SR. + */ + uint32_t end = ostack + osz; + + __asm__ volatile("wsr.EXCSAVE3 %0" :: "r"(end)); + } +} +#endif + #ifdef __cplusplus } #endif @@ -63,6 +125,7 @@ static inline bool arch_is_in_isr(void) { return arch_curr_cpu()->nested != 0U; } + #endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/xtensa/include/xtensa-asm2-context.h b/arch/xtensa/include/xtensa-asm2-context.h index 620e256a916e34..1f21c03774a2a1 100644 --- a/arch/xtensa/include/xtensa-asm2-context.h +++ b/arch/xtensa/include/xtensa-asm2-context.h @@ -78,10 +78,17 @@ #define BASE_SAVE_AREA_SIZE_SCOMPARE 0 #endif +#if XCHAL_HAVE_THREADPTR && defined(CONFIG_THREAD_LOCAL_STORAGE) +#define BASE_SAVE_AREA_SIZE_THREADPTR 4 +#else +#define BASE_SAVE_AREA_SIZE_THREADPTR 0 +#endif + #define BASE_SAVE_AREA_SIZE \ (BASE_SAVE_AREA_SIZE_COMMON + \ BASE_SAVE_AREA_SIZE_LOOPS + \ - BASE_SAVE_AREA_SIZE_SCOMPARE) + BASE_SAVE_AREA_SIZE_SCOMPARE + \ + BASE_SAVE_AREA_SIZE_THREADPTR) #define BSA_A3_OFF (BASE_SAVE_AREA_SIZE - 20) #define BSA_A2_OFF (BASE_SAVE_AREA_SIZE - 24) @@ -94,9 +101,21 @@ #define BSA_LEND_OFF (BASE_SAVE_AREA_SIZE - 52) #define BSA_LCOUNT_OFF (BASE_SAVE_AREA_SIZE - 56) +#if XCHAL_HAVE_S32C1I #define BSA_SCOMPARE1_OFF \ (BASE_SAVE_AREA_SIZE - \ (BASE_SAVE_AREA_SIZE_COMMON + \ - BASE_SAVE_AREA_SIZE_LOOPS + 4)) + BASE_SAVE_AREA_SIZE_LOOPS + \ + BASE_SAVE_AREA_SIZE_SCOMPARE)) +#endif + +#if XCHAL_HAVE_THREADPTR && defined(CONFIG_THREAD_LOCAL_STORAGE) +#define BSA_THREADPTR_OFF \ + (BASE_SAVE_AREA_SIZE - \ + (BASE_SAVE_AREA_SIZE_COMMON + \ + BASE_SAVE_AREA_SIZE_LOOPS + \ + BASE_SAVE_AREA_SIZE_SCOMPARE + \ + BASE_SAVE_AREA_SIZE_THREADPTR)) +#endif #endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_ */ diff --git a/arch/xtensa/include/xtensa-asm2-s.h b/arch/xtensa/include/xtensa-asm2-s.h index 9f85e7d0caec5d..f7848814eac5c4 100644 --- a/arch/xtensa/include/xtensa-asm2-s.h +++ b/arch/xtensa/include/xtensa-asm2-s.h @@ -114,6 +114,10 @@ rsr.SCOMPARE1 a0 s32i a0, a1, BSA_SCOMPARE1_OFF #endif +#if XCHAL_HAVE_THREADPTR && defined(CONFIG_THREAD_LOCAL_STORAGE) + rur.THREADPTR a0 + s32i a0, a1, BSA_THREADPTR_OFF +#endif .endm /* diff --git a/arch/xtensa/include/xtensa-asm2.h b/arch/xtensa/include/xtensa-asm2.h index a51f9f8524354b..6b4d928a3dee90 100644 --- a/arch/xtensa/include/xtensa-asm2.h +++ b/arch/xtensa/include/xtensa-asm2.h @@ -6,6 +6,7 @@ #ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_H_ #define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_H_ +#include #include "xtensa-asm2-context.h" /** @@ -16,7 +17,7 @@ * INTLEVEL set to zero (i.e. it's a user thread, we don't start with * anything masked, so don't assume that!). */ -void *xtensa_init_stack(int *stack_top, +void *xtensa_init_stack(struct k_thread *thread, int *stack_top, void (*entry)(void *, void *, void *), void *arg1, void *arg2, void *arg3); diff --git a/boards/Kconfig b/boards/Kconfig index 6e4af598f3f5ad..5fb5cf87f9f87e 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -25,18 +25,31 @@ endchoice # Parse shields references # Don't do it as a menuconfig, as shield selection is a CMake feature. -rsource "shields/*/Kconfig.shield" +source "$(KCONFIG_BINARY_DIR)/Kconfig.shield" menu "Board Options" config QEMU_ICOUNT bool "QEMU icount mode" depends on QEMU_TARGET - default y if !NETWORKING + default y if !NETWORKING && !BT help Enable QEMU virtual instruction counter. The virtual cpu will execute one instruction every 2^N ns of virtual time. This will give deterministic execution times from the guest point of view. +config QEMU_ICOUNT_SHIFT + int "QEMU icount shift value" + depends on QEMU_ICOUNT + help + The virtual CPU will execute one instruction every 2^N nanoseconds + of virtual time, where N is the value provided here. + # There might not be any board options, hence the optional source osource "$(BOARD_DIR)/Kconfig" endmenu + +config BOARD_HAS_TIMING_FUNCTIONS + bool + help + Should be selected if board provides custom method for retrieving + timestamps and cycle count. diff --git a/boards/arc/em_starterkit/board.cmake b/boards/arc/em_starterkit/board.cmake index 3e3df1c01f394b..292253eb64e8e4 100644 --- a/boards/arc/em_starterkit/board.cmake +++ b/boards/arc/em_starterkit/board.cmake @@ -1,4 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(openocd "--use-elf") +board_runner_args(mdb-hw "--jtag=digilent") include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/mdb-hw.board.cmake) diff --git a/boards/arc/em_starterkit/em_starterkit_em7d_defconfig b/boards/arc/em_starterkit/em_starterkit_em7d_defconfig index d2f93b16ac2031..729e58e2b0ebea 100644 --- a/boards/arc/em_starterkit/em_starterkit_em7d_defconfig +++ b/boards/arc/em_starterkit/em_starterkit_em7d_defconfig @@ -20,3 +20,4 @@ CONFIG_GPIO=y CONFIG_ARC_MPU_ENABLE=y CONFIG_ARC_HAS_SECURE=y CONFIG_TRUSTED_EXECUTION_SECURE=y +CONFIG_INIT_ARCH_HW_AT_BOOT=y diff --git a/boards/arc/em_starterkit/pmodmux.c b/boards/arc/em_starterkit/pmodmux.c index 3c4d9e1e2ee4bd..7c875b1967e9a7 100644 --- a/boards/arc/em_starterkit/pmodmux.c +++ b/boards/arc/em_starterkit/pmodmux.c @@ -124,9 +124,9 @@ #define PM6_LR_CSS_STAT ((1 << BIT2) << PM6_OFFSET) -static int pmod_mux_init(struct device *device) +static int pmod_mux_init(const struct device *device) { - volatile u32_t *mux_regs = (u32_t *)(PMODMUX_BASE_ADDR); + volatile uint32_t *mux_regs = (uint32_t *)(PMODMUX_BASE_ADDR); mux_regs[SPI_MAP_CTRL] = SPI_MAP_CTRL_DEFAULT; mux_regs[UART_MAP_CTRL] = UART_MAP_CTRL_DEFAULT; diff --git a/boards/arc/emsdp/board.cmake b/boards/arc/emsdp/board.cmake index 3e3df1c01f394b..292253eb64e8e4 100644 --- a/boards/arc/emsdp/board.cmake +++ b/boards/arc/emsdp/board.cmake @@ -1,4 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(openocd "--use-elf") +board_runner_args(mdb-hw "--jtag=digilent") include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/mdb-hw.board.cmake) diff --git a/boards/arc/emsdp/emsdp_em7d_esp_defconfig b/boards/arc/emsdp/emsdp_em7d_esp_defconfig index a2853c0974e4f6..1b54a6cdfffde2 100644 --- a/boards/arc/emsdp/emsdp_em7d_esp_defconfig +++ b/boards/arc/emsdp/emsdp_em7d_esp_defconfig @@ -17,3 +17,5 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_ARC_MPU_ENABLE=y CONFIG_GPIO=y +CONFIG_ARC_HAS_SECURE=y +CONFIG_TRUSTED_EXECUTION_SECURE=y diff --git a/boards/arc/hsdk/board.cmake b/boards/arc/hsdk/board.cmake index 3e3df1c01f394b..5e4948e37f6868 100644 --- a/boards/arc/hsdk/board.cmake +++ b/boards/arc/hsdk/board.cmake @@ -1,4 +1,10 @@ # SPDX-License-Identifier: Apache-2.0 - board_runner_args(openocd "--use-elf") + +if(${CONFIG_MP_NUM_CPUS} EQUAL 2) +board_runner_args(openocd "--config=${CMAKE_CURRENT_LIST_DIR}/support/openocd-2-cores.cfg") +endif() + +board_runner_args(mdb-hw "--jtag=digilent" "--cores=${CONFIG_MP_NUM_CPUS}") include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/mdb-hw.board.cmake) diff --git a/boards/arc/hsdk/hsdk.dts b/boards/arc/hsdk/hsdk.dts index 0c47fdefa52aec..9a99a09a9d2a9c 100644 --- a/boards/arc/hsdk/hsdk.dts +++ b/boards/arc/hsdk/hsdk.dts @@ -6,53 +6,9 @@ /dts-v1/; -#include +#include "hsdk.dtsi" / { model = "hsdk"; compatible = "snps,hsdk"; - - aliases { - uart-0 = &uart0; - }; - - chosen { - zephyr,sram = &ddr0; - zephyr,console = &uart0; - zephyr,shell-uart = &uart0; - }; -}; - -&uart0 { - status = "okay"; - current-speed = <115200>; -}; - -&gpio0 { - status = "okay"; - interrupts = <56 1>; -}; - -&spi0 { - status = "okay"; - clock-frequency = <33333333>; -}; - -&spi1 { - status = "okay"; - clock-frequency = <33333333>; -}; - -&spi2 { - status = "okay"; - clock-frequency = <33333333>; - - cs-gpios = <&gpio0 9 0>; - ili9340@0 { - compatible = "ilitek,ili9340"; - cmd-data-gpios = <&gpio0 21 0>; - reg = <0>; - spi-max-frequency = <12000000>; - label = "DISPLAY"; - }; }; diff --git a/boards/arc/hsdk/hsdk.dtsi b/boards/arc/hsdk/hsdk.dtsi new file mode 100644 index 00000000000000..54933f7aced963 --- /dev/null +++ b/boards/arc/hsdk/hsdk.dtsi @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + + aliases { + uart-0 = &uart0; + }; + + chosen { + zephyr,sram = &ddr0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; +}; + +&gpio0 { + status = "okay"; + interrupts = <56 1>; +}; + +&spi0 { + status = "okay"; + clock-frequency = <33333333>; +}; + +&spi1 { + status = "okay"; + clock-frequency = <33333333>; +}; + +&spi2 { + status = "okay"; + clock-frequency = <33333333>; + + cs-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; + ili9340@0 { + compatible = "ilitek,ili9340"; + cmd-data-gpios = <&gpio0 21 0>; + reg = <0>; + spi-max-frequency = <12000000>; + label = "DISPLAY"; + pwctrl1 = [1b 00]; + vmctrl1 = [3f 3c]; + vmctrl2 = [b7]; + pgamctrl = [0f 2a 28 08 0e 08 54 a9 43 0a 0f 00 00 00 00]; + ngamctrl = [00 15 17 07 11 06 2b 56 3c 05 10 0f 3f 3f 0f]; + }; +}; diff --git a/boards/arc/hsdk/hsdk_2cores.dts b/boards/arc/hsdk/hsdk_2cores.dts new file mode 100644 index 00000000000000..6dd7974a5db016 --- /dev/null +++ b/boards/arc/hsdk/hsdk_2cores.dts @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "hsdk.dtsi" + +/ { + model = "hsdk_2cores"; + compatible = "snps,hsdk_2cores"; +}; diff --git a/boards/arc/hsdk/hsdk_2cores.yaml b/boards/arc/hsdk/hsdk_2cores.yaml new file mode 100644 index 00000000000000..de3ecd00fbde93 --- /dev/null +++ b/boards/arc/hsdk/hsdk_2cores.yaml @@ -0,0 +1,11 @@ +identifier: hsdk_2cores +name: HS Development Kit(2 cores) +type: mcu +arch: arc +toolchain: + - zephyr + - xtools +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/arc/hsdk/hsdk_2cores_defconfig b/boards/arc/hsdk/hsdk_2cores_defconfig new file mode 100644 index 00000000000000..0bdfb6bef37ade --- /dev/null +++ b/boards/arc/hsdk/hsdk_2cores_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CPU_ARCHS=y +CONFIG_SOC_ARC_HSDK=y +CONFIG_BOARD_HSDK=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 +CONFIG_XIP=y +CONFIG_BUILD_NO_GAP_FILL=y +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_PRINTK=y +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_PINMUX=y +CONFIG_PINMUX_HSDK=y +CONFIG_GPIO=y +CONFIG_SPI=y +CONFIG_SMP=y +CONFIG_MP_NUM_CPUS=2 diff --git a/boards/arc/hsdk/pinmux.c b/boards/arc/hsdk/pinmux.c index 9c38130d150533..1927fbc25eaf19 100644 --- a/boards/arc/hsdk/pinmux.c +++ b/boards/arc/hsdk/pinmux.c @@ -8,11 +8,11 @@ #include #include -static int board_pinmux_init(struct device *device) +static int board_pinmux_init(const struct device *device) { ARG_UNUSED(device); - struct device *pinmux = device_get_binding(CONFIG_PINMUX_NAME); + const struct device *pinmux = device_get_binding(CONFIG_PINMUX_NAME); if (pinmux == NULL) { return -ENXIO; diff --git a/boards/arc/hsdk/support/openocd-2-cores.cfg b/boards/arc/hsdk/support/openocd-2-cores.cfg new file mode 100644 index 00000000000000..4de2ff322e28bf --- /dev/null +++ b/boards/arc/hsdk/support/openocd-2-cores.cfg @@ -0,0 +1,81 @@ +# Copyright (C) 2020 Synopsys, Inc. +# SPDX-License-Identifier: Apache-2.0 +# + +# Configure JTAG cable +# SDP has built-in FT2232 chip, which is similar to Digilent HS-1, except that +# it uses channgel B for JTAG, instead of channel A. +interface ftdi + +# Only specify FTDI serial number if it is specified via +# "set _ZEPHYR_BOARD_SERIAL 12345" before reading this script +if { [info exists _ZEPHYR_BOARD_SERIAL] } { + ftdi_serial $_ZEPHYR_BOARD_SERIAL +} + +ftdi_vid_pid 0x0403 0x6010 +ftdi_layout_init 0x0088 0x008b +ftdi_channel 1 + + +adapter_khz 10000 + +# ARCs supports only JTAG. +transport select jtag + + +# +# HS Development Kit SoC. +# +# Contains quad-core ARC HS38. +# + +source [find cpu/arc/hs.tcl] + +set _coreid 0 +set _dbgbase [expr 0x00000000 | ($_coreid << 13)] + +# CHIPNAME will be used to choose core family (600, 700 or EM). As far as +# OpenOCD is concerned EM and HS are identical. +set _CHIPNAME arc-em + +# OpenOCD discovers JTAG TAPs in reverse order. + +set _TARGETNAME2 $_CHIPNAME.cpu2 +jtag newtap $_CHIPNAME cpu2 -irlen 4 -ircapture 0x1 -expected-id 0x200424b1 +set _TARGETNAME1 $_CHIPNAME.cpu1 +jtag newtap $_CHIPNAME cpu1 -irlen 4 -ircapture 0x1 -expected-id 0x200024b1 + +################################ +# ARC HS38 core 2 +################################ + +target create $_TARGETNAME2 arcv2 -chain-position $_TARGETNAME2 +$_TARGETNAME2 configure -coreid $_coreid +$_TARGETNAME2 configure -dbgbase $_dbgbase +$_TARGETNAME2 configure -event reset-assert "arc_common_reset $_TARGETNAME2" +set _coreid [expr $_coreid + 1] +set _dbgbase [expr 0x00000000 | ($_coreid << 13)] +arc_hs_init_regs + +# Enable L2 cache support for core 2. +$_TARGETNAME2 arc has-l2cache true + +################################ +# ARC HS38 core 1 +################################ + +target create $_TARGETNAME1 arcv2 -chain-position $_TARGETNAME1 +$_TARGETNAME1 configure -coreid $_coreid +$_TARGETNAME1 configure -dbgbase $_dbgbase +$_TARGETNAME1 configure -event reset-assert "arc_common_reset $_TARGETNAME1" +set _coreid [expr $_coreid + 1] +set _dbgbase [expr 0x00000000 | ($_coreid << 13)] +arc_hs_init_regs + +# Enable L2 cache support for core 1. +$_TARGETNAME1 arc has-l2cache true + +target smp $_TARGETNAME1 $_TARGETNAME2 + +# vi:ft=tcl diff --git a/boards/arc/hsdk/support/openocd.cfg b/boards/arc/hsdk/support/openocd.cfg index 28a59e953c6c7b..0a6f5d636aec71 100644 --- a/boards/arc/hsdk/support/openocd.cfg +++ b/boards/arc/hsdk/support/openocd.cfg @@ -112,4 +112,6 @@ arc_hs_init_regs # Enable L2 cache support for core 1. $_TARGETNAME1 arc has-l2cache true +target smp $_TARGETNAME1 $_TARGETNAME2 $_TARGETNAME3 $_TARGETNAME4 + # vi:ft=tcl diff --git a/boards/arc/iotdk/board.cmake b/boards/arc/iotdk/board.cmake index 3e3df1c01f394b..292253eb64e8e4 100644 --- a/boards/arc/iotdk/board.cmake +++ b/boards/arc/iotdk/board.cmake @@ -1,4 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(openocd "--use-elf") +board_runner_args(mdb-hw "--jtag=digilent") include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/mdb-hw.board.cmake) diff --git a/boards/arc/nsim/Kconfig.board b/boards/arc/nsim/Kconfig.board index 39acb48bc7d0df..61ecfc890cbdcb 100644 --- a/boards/arc/nsim/Kconfig.board +++ b/boards/arc/nsim/Kconfig.board @@ -9,4 +9,4 @@ config BOARD_NSIM help The DesignWare ARC nSIM board is a virtual board based on the ARC nSIM simulator. It demonstrates the ARC core features - and a console based on the legacy ARC UART model. + and a console based on the ns16550 UART model. diff --git a/boards/arc/nsim/Kconfig.defconfig b/boards/arc/nsim/Kconfig.defconfig index 7b2e56393ed155..bc88b869e3a4e3 100644 --- a/boards/arc/nsim/Kconfig.defconfig +++ b/boards/arc/nsim/Kconfig.defconfig @@ -5,7 +5,7 @@ if BOARD_NSIM config BOARD default "nsim" -config UART_NSIM +config UART_NS16550 default y depends on SERIAL diff --git a/boards/arc/nsim/board.cmake b/boards/arc/nsim/board.cmake index 33668b32bf7990..e58a7beb9de619 100644 --- a/boards/arc/nsim/board.cmake +++ b/boards/arc/nsim/board.cmake @@ -1,22 +1,27 @@ # SPDX-License-Identifier: Apache-2.0 - -if(${CONFIG_SOC_NSIM_HS_SMP}) -set(EMU_PLATFORM mdb) -else() set(EMU_PLATFORM nsim) -endif() -if(NOT ${CONFIG_SOC_NSIM_HS_SMP}) +if(NOT CONFIG_SOC_NSIM_HS_SMP) board_set_flasher_ifnset(arc-nsim) board_set_debugger_ifnset(arc-nsim) endif() if(${CONFIG_SOC_NSIM_EM}) board_runner_args(arc-nsim "--props=nsim_em.props") +board_runner_args(mdb-nsim "--nsim_args=mdb_em.args") +elseif(${CONFIG_SOC_NSIM_EM7D_V22}) +board_runner_args(arc-nsim "--props=nsim_em7d_v22.props") +board_runner_args(mdb-nsim "--nsim_args=mdb_em7d_v22.args") elseif(${CONFIG_SOC_NSIM_SEM}) board_runner_args(arc-nsim "--props=nsim_sem.props") +board_runner_args(mdb-nsim "--nsim_args=mdb_sem.args") elseif(${CONFIG_SOC_NSIM_HS}) board_runner_args(arc-nsim "--props=nsim_hs.props") +board_runner_args(mdb-nsim "--nsim_args=mdb_hs.args") +elseif(${CONFIG_SOC_NSIM_HS_SMP}) +board_runner_args(mdb-nsim "--cores=${CONFIG_MP_NUM_CPUS}" "--nsim_args=mdb_hs_smp.args") endif() board_finalize_runner_args(arc-nsim) +include(${ZEPHYR_BASE}/boards/common/mdb-nsim.board.cmake) +include(${ZEPHYR_BASE}/boards/common/mdb-hw.board.cmake) diff --git a/boards/arc/nsim/doc/index.rst b/boards/arc/nsim/doc/index.rst index b975c88d5baf23..43a7b7a209966d 100644 --- a/boards/arc/nsim/doc/index.rst +++ b/boards/arc/nsim/doc/index.rst @@ -6,22 +6,25 @@ DesignWare(R) ARC(R) Emulation (nsim) Overview ******** -This board configuration will use `Designware ARC nSIM`_ to emulate a virtual -ARC EM or ARC HS based board including the following features: +This board configuration can be used to run ARC EM / ARC HS based images in +simulation with `Designware ARC nSIM`_ or run same images on FPGA based HW +platform `HAPS`_. The board includes the following features: * ARC EM or ARC HS processor * ARC internal timer -* a virtual output only console (uart-nsim) +* a virtual console (ns16550 based UART model) There are four supported board sub-configurations: * ``nsim_em`` which includes normal ARC EM features and ARC MPUv2 +* ``nsim_em_em7d_v22`` which includes normal ARC EM features and ARC MPUv2, specially with one register bank and fast irq * ``nsim_sem`` which includes secure ARC EM features and ARC MPUv3 * ``nsim_hs`` which includes base ARC HS features, i.e. w/o PMU and MMU * ``nsim_hs_smp`` which includes base ARC HS features in multi-core cluster, still w/o PMU and MMU For detailed arc features, please refer to :zephyr_file:`boards/arc/nsim/support/nsim_em.props`, +:zephyr_file:`boards/arc/nsim/support/nsim_em7d_v22.props`, :zephyr_file:`boards/arc/nsim/support/nsim_sem.props`, :zephyr_file:`boards/arc/nsim/support/nsim_hs.props` and :zephyr_file:`boards/arc/nsim/support/mdb_hs_smp.args` @@ -39,7 +42,7 @@ The following hardware features are supported: +===========+============+=====+=======+=====+=======================+ | INT | on-chip | Y | Y | Y | interrupt_controller | +-----------+------------+-----+-------+-----+-----------------------+ -| UART | nsim uart | Y | Y | Y | serial port-polling | +| UART | ns16550 | Y | Y | Y | serial port | +-----------+------------+-----+-------+-----+-----------------------+ | TIMER | on-chip | Y | Y | Y | system clock | +-----------+------------+-----+-------+-----+-----------------------+ @@ -51,8 +54,14 @@ Programming and Debugging Required Hardware and Software ============================== -To use Zephyr RTOS applications on this board, `Designware ARC nSIM`_ or -`Designware ARC nSIM Lite`_ is required. +To run single-core Zephyr RTOS applications in simulation on this board, +`Designware ARC nSIM`_ or `Designware ARC nSIM Lite`_ is required. + +To run multi-core Zephyr RTOS applications in simulation on this board, +`Designware ARC nSIM`_ and MetaWare Debugger from `ARC MWDT`_ are required. + +To run Zephyr RTOS applications on FPGA-based `HAPS`_ platform, +MetaWare Debugger from `ARC MWDT`_ is required. Building Sample Applications ============================== @@ -81,6 +90,14 @@ nsim, and display the following console output: .. note:: To exit the simulator, use Ctrl+], then Ctrl+c +Use this configuration to run same application on `HAPS`_ platform: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: nsim_em + :goals: flash --runner mdb-hw + Debugging ========= @@ -119,3 +136,5 @@ References .. _Designware ARC nSIM: https://www.synopsys.com/dw/ipdir.php?ds=sim_nsim .. _Designware ARC nSIM Lite: https://www.synopsys.com/cgi-bin/dwarcnsim/req1.cgi +.. _HAPS: https://www.synopsys.com/verification/prototyping/haps.html +.. _ARC MWDT: https://www.synopsys.com/dw/ipdir.php?ds=sw_metaware diff --git a/boards/arc/nsim/nsim.dtsi b/boards/arc/nsim/nsim.dtsi index 4564e6c96910e5..bb149b8844ab43 100644 --- a/boards/arc/nsim/nsim.dtsi +++ b/boards/arc/nsim/nsim.dtsi @@ -38,21 +38,23 @@ }; iccm0: iccm@ICCM_ADDR { - device_type = "memory"; compatible = "arc,iccm"; reg = ; }; dccm0: dccm@DCCM_ADDR { compatible = "arc,dccm"; - device_type = "memory"; reg = ; }; uart0: uart@f0000000 { - compatible = "snps,nsim-uart"; - reg = <0xf0000000 0x100>; + compatible = "ns16550"; + clock-frequency = <50000000>; + reg = <0xf0000000 0x400>; + current-speed = <115200>; label = "UART_0"; + interrupt-parent = <&intc>; + interrupts = <24 1>; }; chosen { diff --git a/boards/arc/nsim/nsim_em.yaml b/boards/arc/nsim/nsim_em.yaml index ac1807ce6b7828..c965ad20619f5f 100644 --- a/boards/arc/nsim/nsim_em.yaml +++ b/boards/arc/nsim/nsim_em.yaml @@ -5,6 +5,7 @@ simulation: nsim arch: arc toolchain: - zephyr + - arcmwdt testing: default: true ignore_tags: diff --git a/boards/arc/nsim/nsim_em7d_v22.dts b/boards/arc/nsim/nsim_em7d_v22.dts new file mode 100644 index 00000000000000..4b52355589a466 --- /dev/null +++ b/boards/arc/nsim/nsim_em7d_v22.dts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018, 2019, 2020, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "nsim_em.dtsi" + +/ { + model = "snps,nsim_em"; + compatible = "snps,nsim_em"; +}; + +&cpu0 { + clock-frequency = <5000000>; +}; diff --git a/boards/arc/nsim/nsim_em7d_v22.yaml b/boards/arc/nsim/nsim_em7d_v22.yaml new file mode 100644 index 00000000000000..9f02d526ad400a --- /dev/null +++ b/boards/arc/nsim/nsim_em7d_v22.yaml @@ -0,0 +1,12 @@ +identifier: nsim_em7d_v22 +name: EM Nsim simulator +type: mcu +simulation: nsim +arch: arc +toolchain: + - zephyr +testing: + default: true + ignore_tags: + - net + - bluetooth diff --git a/boards/arc/nsim/nsim_em7d_v22_defconfig b/boards/arc/nsim/nsim_em7d_v22_defconfig new file mode 100644 index 00000000000000..279827ea29b256 --- /dev/null +++ b/boards/arc/nsim/nsim_em7d_v22_defconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CPU_ARCEM=y +CONFIG_SOC_NSIM=y +CONFIG_SOC_NSIM_EM7D_V22=y +CONFIG_BOARD_NSIM=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 +CONFIG_XIP=n +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_PRINTK=y +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_ARC_MPU_ENABLE=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_ARC_EXCEPTION_DEBUG=y +CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS=y diff --git a/boards/arc/nsim/nsim_hs.yaml b/boards/arc/nsim/nsim_hs.yaml index f072efcdfce76b..ee0784156d2c01 100644 --- a/boards/arc/nsim/nsim_hs.yaml +++ b/boards/arc/nsim/nsim_hs.yaml @@ -5,6 +5,7 @@ simulation: nsim arch: arc toolchain: - zephyr + - arcmwdt testing: ignore_tags: - net diff --git a/boards/arc/nsim/nsim_hs_smp.yaml b/boards/arc/nsim/nsim_hs_smp.yaml index 7907c2061b661f..808706bbc4ea8a 100644 --- a/boards/arc/nsim/nsim_hs_smp.yaml +++ b/boards/arc/nsim/nsim_hs_smp.yaml @@ -1,10 +1,11 @@ identifier: nsim_hs_smp name: Multi-core HS nSIM simulator type: mcu -simulation: mdb +simulation: mdb-nsim arch: arc toolchain: - zephyr + - arcmwdt testing: ignore_tags: - net diff --git a/boards/arc/nsim/nsim_sem.dts b/boards/arc/nsim/nsim_sem.dts index 61358c9210c4b7..15f42e9a9ecb6e 100644 --- a/boards/arc/nsim/nsim_sem.dts +++ b/boards/arc/nsim/nsim_sem.dts @@ -15,13 +15,11 @@ compatible = "snps,nsim_sem"; iccm0: iccm@0 { - device_type = "memory"; compatible = "arc,iccm"; reg = <0x0 0x40000>; }; dccm0: dccm@80000000 { - device_type = "memory"; compatible = "arc,dccm"; reg = <0x80000000 0x40000>; }; diff --git a/boards/arc/nsim/nsim_sem.yaml b/boards/arc/nsim/nsim_sem.yaml index 202dc2b7922b48..4c573e3740bd43 100644 --- a/boards/arc/nsim/nsim_sem.yaml +++ b/boards/arc/nsim/nsim_sem.yaml @@ -5,6 +5,7 @@ arch: arc simulation: nsim toolchain: - zephyr + - arcmwdt testing: ignore_tags: - net diff --git a/boards/arc/nsim/nsim_sem_mpu_stack_guard.yaml b/boards/arc/nsim/nsim_sem_mpu_stack_guard.yaml index 215151d4e77377..c901c002d650a2 100644 --- a/boards/arc/nsim/nsim_sem_mpu_stack_guard.yaml +++ b/boards/arc/nsim/nsim_sem_mpu_stack_guard.yaml @@ -5,6 +5,7 @@ arch: arc simulation: nsim toolchain: - zephyr + - arcmwdt testing: ignore_tags: - net diff --git a/boards/arc/nsim/support/mdb_em.args b/boards/arc/nsim/support/mdb_em.args new file mode 100644 index 00000000000000..2d6884c26ed254 --- /dev/null +++ b/boards/arc/nsim/support/mdb_em.args @@ -0,0 +1,63 @@ + -arcv2em + -core3 + -rgf_num_banks=2 + -rgf_banked_regs=32 + -rgf_num_wr_ports=2 + -Xcode_density + -Xdiv_rem=radix2 + -turbo_boost + -Xswap + -Xbitscan + -Xmpy_option=mpyd + -mpu + -mpu_regions=16 + -Xshift_assist + -Xbarrel_shifter + -Xdsp2 + -Xdsp_complex + -Xdsp_divsqrt=radix2 + -Xdsp_itu + -Xdsp_accshift=full + -Xagu_large + -Xagu_wb_depth=4 + -Xagu_accord + -Xxy + -Xxy_config=dccm_y + -Xxy_size=8K + -Xxy_interleave + -Xxy_y_base=0xe0000000 + -Xfpus_div + -Xfpu_mac + -Xfpuda + -Xfpus_mpy_slow + -Xfpus_div_slow + -Xtimer0 + -Xtimer0_level=1 + -Xtimer1 + -Xtimer1_level=0 + -action_points=2 + -Xstack_check + -dmp_peripheral + -smart_stack_entries=8 + -interrupts=20 + -interrupt_priorities=4 + -ext_interrupts=16 + -firq + -interrupt_base=0x0 + -dcache=16384,32,2,a + -dcache_feature=2 + -icache=16384,32,2,a + -icache_feature=2 + -dccm_size=0x80000 + -dccm_base=0x80000000 + -dccm_interleave + -iccm0_size=0x80000 + -iccm0_base=0x00000000 + -Xpct_counters=8 + -dmac + -dmac_channels=2 + -dmac_registers=0 + -dmac_fifo_depth=2 + -dmac_int_config=single_internal + -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 + -noprofile diff --git a/boards/arc/nsim/support/mdb_em7d_v22.args b/boards/arc/nsim/support/mdb_em7d_v22.args new file mode 100644 index 00000000000000..d4d2060a4ba6df --- /dev/null +++ b/boards/arc/nsim/support/mdb_em7d_v22.args @@ -0,0 +1,48 @@ + -arcv2em + -core2 + -rgf_num_banks=1 + -rgf_num_wr_ports=1 + -Xcode_density + -Xdiv_rem=radix2 + -turbo_boost + -Xswap + -Xbitscan + -Xmpy_option=mpyd + -Xshift_assist + -Xbarrel_shifter + -Xdsp2 + -Xdsp_complex + -Xdsp_divsqrt=radix2 + -Xdsp_accshift=limited + -Xtimer0 + -Xtimer0_level=1 + -Xtimer1 + -Xtimer1_level=0 + -action_points=2 + -Xstack_check + -dmp_peripheral + -smart_stack_entries=8 + -mpu + -mpu_regions=8 + -interrupts=20 + -interrupt_priorities=4 + -ext_interrupts=16 + -firq + -interrupt_base=0x0 + -dcache=16384,32,2,a + -dcache_feature=2 + -icache=16384,32,2,a + -icache_feature=2 + -dccm_size=0x80000 + -dccm_base=0x80000000 + -dccm_interleave + -iccm0_size=0x80000 + -iccm0_base=0x00000000 + -Xpct_counters=8 + -dmac + -dmac_channels=2 + -dmac_registers=0 + -dmac_fifo_depth=2 + -dmac_int_config=single_internal + -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 + -noprofile diff --git a/boards/arc/nsim/support/mdb_hs.args b/boards/arc/nsim/support/mdb_hs.args new file mode 100644 index 00000000000000..ee01dad06b9fcd --- /dev/null +++ b/boards/arc/nsim/support/mdb_hs.args @@ -0,0 +1,43 @@ + -arcv2hs + -core2 + -arcnum=3 + -rgf_num_banks=2 + -rgf_banked_regs=32 + -rgf_num_wr_ports=2 + -Xatomic + -Xll64 + -Xunaligned + -Xcode_density + -Xdiv_rem=radix4 + -Xswap + -Xbitscan + -Xmpy_option=qmpyh + -Xshift_assist + -Xbarrel_shifter + -Xfpud_div + -Xfpu_mac + -Xtimer0 + -Xtimer0_level=1 + -Xtimer1 + -Xtimer1_level=0 + -Xrtc + -action_points=8 + -Xstack_check + -interrupts=72 + -interrupt_priorities=2 + -ext_interrupts=70 + -firq + -interrupt_base=0x0 + -dcache=65536,64,2,a + -dcache_feature=2 + -dcache_uncached_region + -dcache_mem_cycles=2 + -icache=65536,64,4,a + -icache_feature=2 + -dccm_size=0x40000 + -dccm_base=0x80000000 + -dccm_mem_cycles=2 + -iccm0_size=0x40000 + -iccm0_base=0x70000000 + -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 + -noprofile diff --git a/boards/arc/nsim/support/mdb_hs_smp.args b/boards/arc/nsim/support/mdb_hs_smp.args index f04802153cbf8a..6f57c11fe3e41b 100644 --- a/boards/arc/nsim/support/mdb_hs_smp.args +++ b/boards/arc/nsim/support/mdb_hs_smp.args @@ -45,8 +45,8 @@ -connect_gfrc=1 -connect_icd=2 -connect_ici=2 - -prop=nsim_mem-dev=uart0,base=0xf0000000,irq=0,use_connect=1 + -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=0,use_connect=1 -on=nsim_print-sys-arch -noprofile -nogoifmain - -instrs_per_pass=10 + -instrs_per_pass=512 diff --git a/boards/arc/nsim/support/mdb_sem.args b/boards/arc/nsim/support/mdb_sem.args new file mode 100644 index 00000000000000..eff65ee8170982 --- /dev/null +++ b/boards/arc/nsim/support/mdb_sem.args @@ -0,0 +1,54 @@ + -arcv2em + -core3 + -rgf_num_banks=1 + -rgf_num_wr_ports=1 + -Xcode_density + -Xdiv_rem=radix2 + -turbo_boost + -Xswap + -Xbitscan + -Xmpy_option=mpyd + -Xshift_assist + -Xbarrel_shifter + -Xdsp2 + -Xdsp_complex + -Xdsp_divsqrt=radix2 + -Xdsp_accshift=limited + -Xtimer0 + -Xtimer0_level=1 + -Xtimer1 + -Xtimer1_level=0 + -Xsec_timer0 + -Xsec_timer0_level=1 + -action_points=2 + -Xstack_check + -smart_stack_entries=8 + -mpuv4 + -mpu_sid + -mpu_regions=16 + -interrupts=22 + -interrupt_priorities=4 + -ext_interrupts=17 + -interrupt_base=0x0 + -sec_interrupt_base=0x0 + -dcache=16384,32,2,a + -dcache_feature=2 + -icache=16384,32,2,a + -icache_feature=2 + -dccm_size=0x80000 + -dccm_base=0x80000000 + -dccm_interleave + -iccm0_size=0x80000 + -iccm0_base=0x00000000 + -esp_encrypt + -Xsec_modes + -iccm0_sec_lvl=NS + -dccm_sec_lvl=NS + -Xpct_counters=8 + -dmac + -dmac_channels=2 + -dmac_registers=0 + -dmac_fifo_depth=2 + -dmac_int_config=single_internal + -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 + -noprofile diff --git a/boards/arc/nsim/support/nsim_em.props b/boards/arc/nsim/support/nsim_em.props index a1dfdbca0e0420..66d2494b6f2440 100644 --- a/boards/arc/nsim/support/nsim_em.props +++ b/boards/arc/nsim/support/nsim_em.props @@ -66,5 +66,5 @@ nsim_isa_dmac_registers=0 nsim_isa_dmac_fifo_depth=2 nsim_isa_dmac_int_config=single_internal - nsim_mem-dev=uart0,base=0xf0000000,irq=24 + nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 nsim_isa_unaligned_option=1 diff --git a/boards/arc/nsim/support/nsim_em7d_v22.props b/boards/arc/nsim/support/nsim_em7d_v22.props new file mode 100644 index 00000000000000..37d35ffb552b6f --- /dev/null +++ b/boards/arc/nsim/support/nsim_em7d_v22.props @@ -0,0 +1,53 @@ + nsim_isa_family=av2em + nsim_isa_core=2 + arcver=0x42 + nsim_isa_rgf_num_banks=1 + nsim_isa_rgf_num_regs=32 + nsim_isa_rgf_num_wr_ports=1 + nsim_isa_big_endian=0 + nsim_isa_lpc_size=32 + nsim_isa_pc_size=32 + nsim_isa_addr_size=32 + nsim_isa_code_density_option=2 + nsim_isa_div_rem_option=1 + nsim_isa_turbo_boost=1 + nsim_isa_swap_option=1 + nsim_isa_bitscan_option=1 + nsim_isa_mpy_option=8 + nsim_isa_shift_option=3 + nsim_isa_dsp_option=2 + nsim_isa_dsp_complex_option=1 + nsim_isa_dsp_divsqrt_option=1 + nsim_isa_dsp_accshift_option=1 + nsim_isa_enable_timer_0=1 + nsim_isa_timer_0_int_level=1 + nsim_isa_enable_timer_1=1 + nsim_isa_timer_1_int_level=0 + nsim_isa_num_actionpoints=2 + nsim_isa_stack_checking=1 + nsim_isa_has_dmp_peripheral=1 + nsim_isa_smart_stack_entries=8 + mpu_regions=8 + mpu_version=2 + nsim_isa_number_of_interrupts=20 + nsim_isa_number_of_levels=4 + nsim_isa_number_of_external_interrupts=16 + nsim_isa_fast_irq=1 + nsim_isa_intvbase_preset=0x0 + dcache=16384,32,2,a + nsim_isa_dc_feature_level=2 + icache=16384,32,2,a + nsim_isa_ic_feature_level=2 + dccm_size=0x20000 + dccm_base=0x80000000 + nsim_isa_dccm_interleave=1 + iccm0_size=0x40000 + iccm0_base=0x00000000 + nsim_isa_pct_counters=8 + nsim_isa_dmac_option=1 + nsim_isa_dmac_channels=2 + nsim_isa_dmac_registers=0 + nsim_isa_dmac_fifo_depth=2 + nsim_isa_dmac_int_config=single_internal + nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 + nsim_isa_unaligned_option=1 diff --git a/boards/arc/nsim/support/nsim_hs.props b/boards/arc/nsim/support/nsim_hs.props index 759ccc297ff709..59a4f6a9c57fb2 100644 --- a/boards/arc/nsim/support/nsim_hs.props +++ b/boards/arc/nsim/support/nsim_hs.props @@ -43,4 +43,4 @@ nsim_isa_dccm_mem_cycles=2 iccm0_size=0x40000 iccm0_base=0x70000000 - nsim_mem-dev=uart0,base=0xf0000000,irq=24 + nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 diff --git a/boards/arc/nsim/support/nsim_sem.props b/boards/arc/nsim/support/nsim_sem.props index 5d3357ee6e026c..857168a9ea8013 100644 --- a/boards/arc/nsim/support/nsim_sem.props +++ b/boards/arc/nsim/support/nsim_sem.props @@ -55,4 +55,4 @@ nsim_isa_dmac_registers=0 nsim_isa_dmac_fifo_depth=2 nsim_isa_dmac_int_config=single_internal - nsim_mem-dev=uart0,base=0xf0000000,irq=24 \ No newline at end of file + nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 diff --git a/boards/arc/qemu_arc/Kconfig.board b/boards/arc/qemu_arc/Kconfig.board new file mode 100644 index 00000000000000..1ea1a6bd77efd6 --- /dev/null +++ b/boards/arc/qemu_arc/Kconfig.board @@ -0,0 +1,9 @@ +# Copyright (c) 2020 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_QEMU_ARC + bool "ARC QEMU for EM & HS cores" + depends on SOC_QEMU_ARC + select QEMU_TARGET + select HAS_COVERAGE_SUPPORT diff --git a/boards/arc/qemu_arc/Kconfig.defconfig b/boards/arc/qemu_arc/Kconfig.defconfig new file mode 100644 index 00000000000000..4d19859754d1d8 --- /dev/null +++ b/boards/arc/qemu_arc/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2020 Synopsys, Inc. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_QEMU_ARC + +config BOARD + default "qemu_arc" + +endif diff --git a/boards/arc/qemu_arc/board.cmake b/boards/arc/qemu_arc/board.cmake new file mode 100644 index 00000000000000..1f0205acdd76ca --- /dev/null +++ b/boards/arc/qemu_arc/board.cmake @@ -0,0 +1,28 @@ +set(EMU_PLATFORM qemu) + +set(QEMU_CPU_TYPE_${ARCH} arc) + +if(${CONFIG_SOC_QEMU_ARC_EM}) +set(QEMU_CPU_TYPE_${ARCH} arcem) +set(QEMU_FLAGS_${ARCH} -cpu arcem) +elseif(${CONFIG_SOC_QEMU_ARC_HS}) +set(QEMU_CPU_TYPE_${ARCH} archs) +set(QEMU_FLAGS_${ARCH} -cpu archs) +endif() + +list(APPEND QEMU_FLAGS_${ARCH} + -M simhs + -m 8M + -nographic + -no-reboot + -monitor none + -global cpu.firq=false + -global cpu.num-irqlevels=15 + -global cpu.num-irq=25 + -global cpu.ext-irq=20 + -global cpu.freq_hz=1000000 + -global cpu.timer0=true + -global cpu.timer1=true + ) + +set(BOARD_DEBUG_RUNNER qemu) diff --git a/boards/arc/qemu_arc/doc/index.rst b/boards/arc/qemu_arc/doc/index.rst new file mode 100644 index 00000000000000..673ef8125d2af9 --- /dev/null +++ b/boards/arc/qemu_arc/doc/index.rst @@ -0,0 +1,98 @@ +.. _qemu_arc: + +ARC EM & HS Emulation (QEMU) +############################### + +Overview +******** + +This board configuration will use QEMU to emulate a generic ARC EM & +ARC HS hardware platform. + +The following features of ARCv2 ISA cores are currently supported: + +* ARC EM or ARC HS core (both belong to ARCv2 ISA family still + they are binary incompatible) +* Only little-endian configurations +* Full 32 register set +* ARC core free-running timers/counters Timer0 & Timer1 +* ARC core interrupt controller with multiple priority levels +* DW UART +* 5 slots for MMIO Virtio devices + +Hardware +******** +Supported Features +================== + +The following hardware features are supported: + ++--------------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++==============+============+======================+ +| ARCv2 INTC | on-chip | interrupt controller | ++--------------+------------+----------------------+ +| DW UART | on-chip | serial port | ++--------------+------------+----------------------+ +| ARC TIMER0 | on-chip | system clock | ++--------------+------------+----------------------+ + +The kernel currently does not support other hardware features on this platform. + +Devices +======== +System Clock +------------ + +This board configuration uses a system clock frequency of 1 MHz. + +Serial Port +----------- + +This board configuration uses a single serial communication channel with the +DesignWare UART. + +Known Problems or Limitations +============================== + +The following platform features are unsupported: + +* Memory-protection unit (MPU) +* MMIO Virtio Ethernet + +Programming and Debugging +************************* + +Use this configuration to run basic Zephyr applications and kernel tests in the QEMU +emulated environment, for example, with the :ref:`synchronization_sample` +(note you may use ``qemu_arc_em`` or ``qemu_arc_hs`` depending on target CPU): + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: qemu_arc_em + :goals: run + +This will build an image with the synchronization sample app, boot it using +QEMU, and display the following console output: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v2.2.0-2486-g7dbfcf4bab57 *** + threadA: Hello World from qemu_arc! + threudB: Hello World from qemu_arc! + threadA: Hello World from qemu_arc! + threadB: Hello World from qemu_arc! + +Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`. + +Debugging +========= + +Refer to the detailed overview about :ref:`application_debugging`. + +References +********** + +1.`Programmer’s Reference Manual for ARC HS + `_ diff --git a/boards/arc/qemu_arc/qemu_arc.dtsi b/boards/arc/qemu_arc/qemu_arc.dtsi new file mode 100644 index 00000000000000..22a5bd7120df5e --- /dev/null +++ b/boards/arc/qemu_arc/qemu_arc.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "skeleton.dtsi" + +#define DT_FLASH_SIZE DT_SIZE_M(4) +#define DT_SRAM_SIZE DT_SIZE_M(4) + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + }; + + intc: arcv2-intc { + compatible = "snps,arcv2-intc"; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* We are carving out of DRAM for a pseudo flash and sram region */ + flash0: flash@80000000 { + compatible = "soc-nv-flash"; + reg = <0x80000000 DT_FLASH_SIZE>; + }; + + sram0: sram@80400000 { + device_type = "memory"; + reg = <0x80400000 DT_SRAM_SIZE>; + }; + + ns16550_uart: uart@f0000000 { + compatible = "ns16550"; + clock-frequency = <10000000>; + reg = <0xf0000000 0x400>; + current-speed = <115200>; + label = "UART_0"; + interrupt-parent = <&intc>; + interrupts = <24 1>; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &ns16550_uart; + zephyr,shell-uart = &ns16550_uart; + }; +}; diff --git a/boards/arc/qemu_arc/qemu_arc_em.dts b/boards/arc/qemu_arc/qemu_arc_em.dts new file mode 100644 index 00000000000000..290f7eb73087a9 --- /dev/null +++ b/boards/arc/qemu_arc/qemu_arc_em.dts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "qemu_arc.dtsi" + +/ { + model = "QEMU ARC EM"; + compatible = "qemu,arcem"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "snps,arcem"; + reg = <0>; + }; + }; +}; diff --git a/boards/arc/qemu_arc/qemu_arc_em.yaml b/boards/arc/qemu_arc/qemu_arc_em.yaml new file mode 100644 index 00000000000000..f139f3a393edca --- /dev/null +++ b/boards/arc/qemu_arc/qemu_arc_em.yaml @@ -0,0 +1,11 @@ +identifier: qemu_arc_em +name: QEMU Emulation for ARC EM +type: qemu +simulation: qemu +arch: arc +toolchain: + - zephyr +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/arc/qemu_arc/qemu_arc_em_defconfig b/boards/arc/qemu_arc/qemu_arc_em_defconfig new file mode 100644 index 00000000000000..11fa2d265392e0 --- /dev/null +++ b/boards/arc/qemu_arc/qemu_arc_em_defconfig @@ -0,0 +1,14 @@ +CONFIG_CPU_ARCEM=y +CONFIG_SOC_QEMU_ARC=y +CONFIG_SOC_QEMU_ARC_EM=y +CONFIG_XIP=y +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_PRINTK=y +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_ARC_HAS_STACK_CHECKING=n +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_QEMU_ICOUNT=n diff --git a/boards/arc/qemu_arc/qemu_arc_hs.dts b/boards/arc/qemu_arc/qemu_arc_hs.dts new file mode 100644 index 00000000000000..751e42ea1ad98c --- /dev/null +++ b/boards/arc/qemu_arc/qemu_arc_hs.dts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "qemu_arc.dtsi" + +/ { + model = "QEMU ARC HS"; + compatible = "qemu,archs"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "snps,archs"; + reg = <0>; + }; + }; +}; diff --git a/boards/arc/qemu_arc/qemu_arc_hs.yaml b/boards/arc/qemu_arc/qemu_arc_hs.yaml new file mode 100644 index 00000000000000..a471e8c77908d4 --- /dev/null +++ b/boards/arc/qemu_arc/qemu_arc_hs.yaml @@ -0,0 +1,11 @@ +identifier: qemu_arc_hs +name: QEMU Emulation for ARC HS +type: qemu +simulation: qemu +arch: arc +toolchain: + - zephyr +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/arc/qemu_arc/qemu_arc_hs_defconfig b/boards/arc/qemu_arc/qemu_arc_hs_defconfig new file mode 100644 index 00000000000000..a0971d2591fc0c --- /dev/null +++ b/boards/arc/qemu_arc/qemu_arc_hs_defconfig @@ -0,0 +1,14 @@ +CONFIG_CPU_ARCHS=y +CONFIG_SOC_QEMU_ARC=y +CONFIG_SOC_QEMU_ARC_HS=y +CONFIG_XIP=y +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_PRINTK=y +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_ARC_HAS_STACK_CHECKING=n +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_QEMU_ICOUNT=n diff --git a/boards/arm/96b_aerocore2/96b_aerocore2.dts b/boards/arm/96b_aerocore2/96b_aerocore2.dts index 8678dabadf37c1..d1c09083e20fc8 100644 --- a/boards/arm/96b_aerocore2/96b_aerocore2.dts +++ b/boards/arm/96b_aerocore2/96b_aerocore2.dts @@ -7,10 +7,11 @@ /dts-v1/; #include +#include / { model = "96Boards Gumstix AeroCore 2"; - compatible = "gumstix,aerocore2", "st,stm32f427"; + compatible = "gumstix,aerocore2"; chosen { zephyr,console = &uart7; @@ -40,52 +41,72 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &uart7 { + pinctrl-0 = <&uart7_tx_pe8 &uart7_rx_pe7>; current-speed = <115200>; status = "okay"; }; &uart8 { + pinctrl-0 = <&uart8_tx_pe1 &uart8_rx_pe0>; current-speed = <115200>; status = "okay"; }; +&spi1_nss_pa4 { slew-rate = "very-high-speed"; }; + &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; +&spi2_nss_pb12 { slew-rate = "very-high-speed"; }; + &spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; &spi3 { + pinctrl-0 = <&spi3_sck_pc10 &spi3_miso_pc11 &spi3_mosi_pc12>; status = "okay"; }; +&spi4_nss_pe11 { slew-rate = "very-high-speed"; }; + &spi4 { + pinctrl-0 = <&spi4_nss_pe11 &spi4_sck_pe12 + &spi4_miso_pe13 &spi4_mosi_pe14>; status = "okay"; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; status = "okay"; clock-frequency = ; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; @@ -94,6 +115,10 @@ pwm4: pwm { status = "okay"; + pinctrl-0 = <&tim4_ch1_pd12 + &tim4_ch2_pd13 + &tim4_ch3_pd14 + &tim4_ch4_pd15>; }; }; @@ -102,10 +127,16 @@ pwm5: pwm { status = "okay"; + pinctrl-0 = <&tim5_ch1_pa0 + &tim5_ch2_pa1 + &tim5_ch3_pa2 + &tim5_ch4_pa3>; }; }; &adc1 { + pinctrl-0 = <&adc1_in10_pc0 &adc1_in11_pc1 + &adc1_in12_pc2 &adc1_in13_pc3>; status = "okay"; }; diff --git a/boards/arm/96b_aerocore2/96b_aerocore2_defconfig b/boards/arm/96b_aerocore2/96b_aerocore2_defconfig index 3675b4ac82907c..8cb6c9d04a04bd 100644 --- a/boards/arm/96b_aerocore2/96b_aerocore2_defconfig +++ b/boards/arm/96b_aerocore2/96b_aerocore2_defconfig @@ -9,6 +9,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/96b_aerocore2/CMakeLists.txt b/boards/arm/96b_aerocore2/CMakeLists.txt deleted file mode 100644 index 176bea9e17c018..00000000000000 --- a/boards/arm/96b_aerocore2/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2020 Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/96b_aerocore2/pinmux.c b/boards/arm/96b_aerocore2/pinmux.c deleted file mode 100644 index 023dfe1ab216bf..00000000000000 --- a/boards/arm/96b_aerocore2/pinmux.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2020 Linaro Limited. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PD5, STM32F4_PINMUX_FUNC_PD5_USART2_TX}, - {STM32_PIN_PD6, STM32F4_PINMUX_FUNC_PD6_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PD8, STM32F4_PINMUX_FUNC_PD8_USART3_TX}, - {STM32_PIN_PD9, STM32F4_PINMUX_FUNC_PD9_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart7), okay) && CONFIG_SERIAL - {STM32_PIN_PE8, STM32F4_PINMUX_FUNC_PE8_UART7_TX}, - {STM32_PIN_PE7, STM32F4_PINMUX_FUNC_PE7_UART7_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart8), okay) && CONFIG_SERIAL - {STM32_PIN_PE1, STM32F4_PINMUX_FUNC_PE1_UART8_TX}, - {STM32_PIN_PE0, STM32F4_PINMUX_FUNC_PE0_UART8_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm4), okay) && CONFIG_PWM - {STM32_PIN_PD12, STM32F4_PINMUX_FUNC_PD12_PWM4_CH1}, - {STM32_PIN_PD13, STM32F4_PINMUX_FUNC_PD13_PWM4_CH2}, - {STM32_PIN_PD14, STM32F4_PINMUX_FUNC_PD14_PWM4_CH3}, - {STM32_PIN_PD15, STM32F4_PINMUX_FUNC_PD15_PWM4_CH4}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm5), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32F4_PINMUX_FUNC_PA0_PWM5_CH1}, - {STM32_PIN_PA1, STM32F4_PINMUX_FUNC_PA1_PWM5_CH2}, - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_PWM5_CH3}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_PWM5_CH4}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS | - STM32_OSPEEDR_VERY_HIGH_SPEED}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F4_PINMUX_FUNC_PB12_SPI2_NSS | - STM32_OSPEEDR_VERY_HIGH_SPEED}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F4_PINMUX_FUNC_PB13_SPI2_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PB14, STM32F4_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F4_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi3), okay) && CONFIG_SPI - {STM32_PIN_PC10, STM32F4_PINMUX_FUNC_PC10_SPI3_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PC11, STM32F4_PINMUX_FUNC_PC11_SPI3_MISO}, - {STM32_PIN_PC12, STM32F4_PINMUX_FUNC_PC12_SPI3_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi4), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PE11, STM32F4_PINMUX_FUNC_PE11_SPI4_NSS | - STM32_OSPEEDR_VERY_HIGH_SPEED}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PE12, STM32F4_PINMUX_FUNC_PE12_SPI4_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PE13, STM32F4_PINMUX_FUNC_PE13_SPI4_MISO}, - {STM32_PIN_PE14, STM32F4_PINMUX_FUNC_PE14_SPI4_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB11, STM32F4_PINMUX_FUNC_PB11_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PC0, STM32F4_PINMUX_FUNC_PC0_ADC123_IN10}, - {STM32_PIN_PC1, STM32F4_PINMUX_FUNC_PC1_ADC123_IN11}, - {STM32_PIN_PC2, STM32F4_PINMUX_FUNC_PC2_ADC123_IN12}, - {STM32_PIN_PC3, STM32F4_PINMUX_FUNC_PC3_ADC123_IN13}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/96b_argonkey/96b_argonkey.dts b/boards/arm/96b_argonkey/96b_argonkey.dts index 1b13110b5f8d94..92a27a1fbd3455 100644 --- a/boards/arm/96b_argonkey/96b_argonkey.dts +++ b/boards/arm/96b_argonkey/96b_argonkey.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "Tocoding Argonkey 96boards"; - compatible = "tocoding,argonkey", "st,stm32f412"; + compatible = "tocoding,argonkey"; chosen { zephyr,console = &usart1; @@ -46,15 +47,24 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; +&spi1_nss_pa4 { slew-rate = "very-high-speed"; }; + &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; +&spi2_nss_pb12 { slew-rate = "very-high-speed"; }; + &spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; /* ST Microelectronics LSM6DSL accel/gyro sensor */ @@ -73,6 +83,7 @@ &i2s5 { status = "okay"; + pinctrl-0 = <&i2s5_ck_pb0 &i2s5_sd_pb8>; mp34dt05@0 { compatible = "st,mpxxdtyy"; @@ -82,11 +93,13 @@ }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb9>; status = "okay"; clock-frequency = ; @@ -111,6 +124,7 @@ }; &i2c3 { + pinctrl-0 = <&i2c3_scl_pa8 &i2c3_sda_pb4>; status = "okay"; clock-frequency = ; diff --git a/boards/arm/96b_argonkey/96b_argonkey_defconfig b/boards/arm/96b_argonkey/96b_argonkey_defconfig index 40ca925c22125c..b5bbffb224cab6 100644 --- a/boards/arm/96b_argonkey/96b_argonkey_defconfig +++ b/boards/arm/96b_argonkey/96b_argonkey_defconfig @@ -6,6 +6,12 @@ CONFIG_SOC_STM32F412CG=y # 84MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=84000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/96b_argonkey/CMakeLists.txt b/boards/arm/96b_argonkey/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/96b_argonkey/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/96b_argonkey/pinmux.c b/boards/arm/96b_argonkey/pinmux.c deleted file mode 100644 index 6ab9fec42fa00e..00000000000000 --- a/boards/arm/96b_argonkey/pinmux.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2018 STMicroelectronics. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for 96boards Argonkey board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F4_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F4_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PA8, STM32F4_PINMUX_FUNC_PA8_I2C3_SCL}, - {STM32_PIN_PB4, STM32F4_PINMUX_FUNC_PB4_I2C3_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS | - STM32_OSPEEDR_VERY_HIGH_SPEED}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F4_PINMUX_FUNC_PB12_SPI2_NSS | - STM32_OSPEEDR_VERY_HIGH_SPEED}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F4_PINMUX_FUNC_PB13_SPI2_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PB14, STM32F4_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F4_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2s5), okay) && CONFIG_I2S - {STM32_PIN_PB0, STM32F4_PINMUX_FUNC_PB0_I2S5_CK}, - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_I2S5_SD}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/96b_avenger96/96b_avenger96.dts b/boards/arm/96b_avenger96/96b_avenger96.dts index c186004f667f3b..de6fccea9f13c4 100644 --- a/boards/arm/96b_avenger96/96b_avenger96.dts +++ b/boards/arm/96b_avenger96/96b_avenger96.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "Arrow Electronics STM32MP157A Avenger96 board"; - compatible = "arrow,stm32mp157a-avenger96", "st,stm32mp15"; + compatible = "arrow,stm32mp157a-avenger96"; chosen { /* @@ -53,11 +54,13 @@ }; &uart4 { + pinctrl-0 = <&uart4_tx_pd1 &uart4_rx_pb2>; current-speed = <115200>; status = "okay"; }; &uart7 { + pinctrl-0 = <&uart7_tx_pe8 &uart7_rx_pe7>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/96b_avenger96/96b_avenger96.yaml b/boards/arm/96b_avenger96/96b_avenger96.yaml index d5c03853bcc329..2b1c86243efe42 100644 --- a/boards/arm/96b_avenger96/96b_avenger96.yaml +++ b/boards/arm/96b_avenger96/96b_avenger96.yaml @@ -4,7 +4,7 @@ type: mcu arch: arm toolchain: - zephyr - - gccarmemb + - gnuarmemb - xtools supported: - gpio diff --git a/boards/arm/96b_avenger96/96b_avenger96_defconfig b/boards/arm/96b_avenger96/96b_avenger96_defconfig index f746cc1be4f5da..b4e7e7c36ff6b7 100644 --- a/boards/arm/96b_avenger96/96b_avenger96_defconfig +++ b/boards/arm/96b_avenger96/96b_avenger96_defconfig @@ -3,6 +3,12 @@ CONFIG_SOC_STM32MP15_M4=y # 209 MHz system clock (mlhclk_ck) CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=209000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable GPIO CONFIG_GPIO=y diff --git a/boards/arm/96b_avenger96/CMakeLists.txt b/boards/arm/96b_avenger96/CMakeLists.txt deleted file mode 100644 index 4e477d26df8909..00000000000000 --- a/boards/arm/96b_avenger96/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2019 Linaro Ltd. -# -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/96b_avenger96/pinmux.c b/boards/arm/96b_avenger96/pinmux.c deleted file mode 100644 index 992bbb0e58de86..00000000000000 --- a/boards/arm/96b_avenger96/pinmux.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2019 Linaro Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for Avenger96 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart4), okay) && CONFIG_SERIAL - { STM32_PIN_PB2, STM32MP1X_PINMUX_FUNC_PB2_UART4_RX }, - { STM32_PIN_PD1, STM32MP1X_PINMUX_FUNC_PD1_UART4_TX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart7), okay) && CONFIG_SERIAL - { STM32_PIN_PE7, STM32MP1X_PINMUX_FUNC_PE7_UART7_RX }, - { STM32_PIN_PE8, STM32MP1X_PINMUX_FUNC_PE8_UART7_TX }, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/96b_carbon/96b_carbon.dts b/boards/arm/96b_carbon/96b_carbon.dts index f1e41cf402523d..a92bc85b727caa 100644 --- a/boards/arm/96b_carbon/96b_carbon.dts +++ b/boards/arm/96b_carbon/96b_carbon.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "96b_lscon.dtsi" / { model = "Seeed Studio Carbon 96boards"; - compatible = "seeed,carbon", "st,stm32f401"; + compatible = "seeed,carbon"; chosen { zephyr,console = &usart1; @@ -53,26 +54,31 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pc6 &usart6_rx_pc7>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb3>; status = "okay"; clock-frequency = ; }; @@ -80,6 +86,9 @@ &spi1 { status = "okay"; + pinctrl-0 = <&spi1_miso_pa6 &spi1_mosi_pa7 + &spi1_sck_pa5 &spi1_nss_pa4>; + /* Nordic nRF51822-QFAC */ bt-hci@0 { compatible = "zephyr,bt-hci-spi"; @@ -92,18 +101,18 @@ }; &spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/96b_carbon/96b_carbon_defconfig b/boards/arm/96b_carbon/96b_carbon_defconfig index 2e60f8d5395419..af56ae0e386850 100644 --- a/boards/arm/96b_carbon/96b_carbon_defconfig +++ b/boards/arm/96b_carbon/96b_carbon_defconfig @@ -9,6 +9,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=84000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/96b_carbon/CMakeLists.txt b/boards/arm/96b_carbon/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/96b_carbon/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/96b_carbon/pinmux.c b/boards/arm/96b_carbon/pinmux.c deleted file mode 100644 index d283af8b9cf731..00000000000000 --- a/boards/arm/96b_carbon/pinmux.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2016 Linaro Limited. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for 96boards Carbon board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F4_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F4_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PC6, STM32F4_PINMUX_FUNC_PC6_USART6_TX}, - {STM32_PIN_PC7, STM32F4_PINMUX_FUNC_PC7_USART6_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB3, STM32F4_PINMUX_FUNC_PB3_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F4_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F4_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32F4_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F4_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/96b_meerkat96/CMakeLists.txt b/boards/arm/96b_meerkat96/CMakeLists.txt deleted file mode 100644 index f42562cc6ef052..00000000000000 --- a/boards/arm/96b_meerkat96/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2019, Linaro Ltd. -# -# SPDX-License-Identifier: Apache-2.0 -# - -zephyr_library() -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -zephyr_library_sources(pinmux.c) diff --git a/boards/arm/96b_meerkat96/pinmux.c b/boards/arm/96b_meerkat96/pinmux.c index b985c10b81d8e9..ad797875c27427 100644 --- a/boards/arm/96b_meerkat96/pinmux.c +++ b/boards/arm/96b_meerkat96/pinmux.c @@ -7,7 +7,7 @@ #include #include "device_imx.h" -static int meerakt96_pinmux_init(struct device *dev) +static int meerakt96_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/96b_neonkey/96b_neonkey.dts b/boards/arm/96b_neonkey/96b_neonkey.dts index d6b9fa1904c953..a3a489e01c5b07 100644 --- a/boards/arm/96b_neonkey/96b_neonkey.dts +++ b/boards/arm/96b_neonkey/96b_neonkey.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "Tocoding Neonkey 96boards"; - compatible = "tocoding,neonkey", "st,stm32f411"; + compatible = "tocoding,neonkey"; chosen { zephyr,console = &usart1; @@ -56,21 +57,25 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb3>; status = "okay"; clock-frequency = ; }; &i2c3 { + pinctrl-0 = <&i2c3_scl_pa8 &i2c3_sda_pb4>; status = "okay"; clock-frequency = ; @@ -82,6 +87,8 @@ }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; diff --git a/boards/arm/96b_neonkey/96b_neonkey_defconfig b/boards/arm/96b_neonkey/96b_neonkey_defconfig index f66bd454a5e1c7..fe685811a2d886 100644 --- a/boards/arm/96b_neonkey/96b_neonkey_defconfig +++ b/boards/arm/96b_neonkey/96b_neonkey_defconfig @@ -6,6 +6,12 @@ CONFIG_SOC_STM32F411XE=y # 84MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=84000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/96b_neonkey/CMakeLists.txt b/boards/arm/96b_neonkey/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/96b_neonkey/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/96b_neonkey/pinmux.c b/boards/arm/96b_neonkey/pinmux.c deleted file mode 100644 index fbed1837c4fb6d..00000000000000 --- a/boards/arm/96b_neonkey/pinmux.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2017 Linaro Limited. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for 96boards Neonkey board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F4_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F4_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB3, STM32F4_PINMUX_FUNC_PB3_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PA8, STM32F4_PINMUX_FUNC_PA8_I2C3_SCL}, - {STM32_PIN_PB4, STM32F4_PINMUX_FUNC_PB4_I2C3_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/96b_nitrogen/96b_nitrogen.dts b/boards/arm/96b_nitrogen/96b_nitrogen.dts index 979a380eb06ca5..f5f8fde032788d 100644 --- a/boards/arm/96b_nitrogen/96b_nitrogen.dts +++ b/boards/arm/96b_nitrogen/96b_nitrogen.dts @@ -88,10 +88,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez.dts b/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez.dts index 10365b38ccb701..6e03720f09f220 100644 --- a/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez.dts +++ b/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics 96Boards STM32 Sensor Mezzanine board"; - compatible = "st,stm32f446-b96b-f446ve", "st,stm32f446"; + compatible = "st,stm32f446-b96b-f446ve"; chosen { zephyr,console = &uart4; @@ -61,6 +62,7 @@ }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; @@ -80,6 +82,7 @@ }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pc12>; status = "okay"; clock-frequency = ; }; @@ -89,18 +92,31 @@ }; &i2s2 { + pinctrl-0 = <&i2s2_ck_pc7 &i2s2_sd_pc1>; status = "okay"; }; +&spi1_nss_pa4 { slew-rate = "very-high-speed"; }; + &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; +&spi2_nss_pb9 { slew-rate = "very-high-speed"; }; + &spi2 { + pinctrl-0 = <&spi2_nss_pb9 &spi2_sck_pd3 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; +&spi4_nss_pe11 { slew-rate = "very-high-speed"; }; + &spi4 { + pinctrl-0 = <&spi4_nss_pe11 &spi4_sck_pe12 + &spi4_miso_pe13 &spi4_mosi_pe14>; status = "okay"; }; @@ -109,6 +125,7 @@ pwm3: pwm { status = "okay"; + pinctrl-0 = <&tim3_ch1_pb4 &tim3_ch3_pc8>; }; }; @@ -117,6 +134,7 @@ pwm4: pwm { status = "okay"; + pinctrl-0 = <&tim4_ch3_pd14 &tim4_ch4_pd15>; }; }; @@ -125,25 +143,30 @@ pwm9: pwm { status = "okay"; + pinctrl-0 = <&tim9_ch1_pe5 &tim9_ch2_pe6>; }; }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &uart4 { + pinctrl-0 = <&uart4_tx_pc10 &uart4_rx_pc11>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez_defconfig b/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez_defconfig index 7db13fa1b426c7..e21fb2b7bd5a30 100644 --- a/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez_defconfig +++ b/boards/arm/96b_stm32_sensor_mez/96b_stm32_sensor_mez_defconfig @@ -9,6 +9,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=84000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/96b_stm32_sensor_mez/CMakeLists.txt b/boards/arm/96b_stm32_sensor_mez/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/96b_stm32_sensor_mez/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/96b_stm32_sensor_mez/pinmux.c b/boards/arm/96b_stm32_sensor_mez/pinmux.c deleted file mode 100644 index a0225ace59d0e0..00000000000000 --- a/boards/arm/96b_stm32_sensor_mez/pinmux.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2018 Linaro Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for 96b_stm32_sensor_mez board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F4_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F4_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PD5, STM32F4_PINMUX_FUNC_PD5_USART2_TX}, - {STM32_PIN_PD6, STM32F4_PINMUX_FUNC_PD6_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PD8, STM32F4_PINMUX_FUNC_PD8_USART3_TX}, - {STM32_PIN_PD9, STM32F4_PINMUX_FUNC_PD9_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart4), okay) && CONFIG_SERIAL - {STM32_PIN_PC10, STM32F4_PINMUX_FUNC_PC10_UART4_TX}, - {STM32_PIN_PC11, STM32F4_PINMUX_FUNC_PC11_UART4_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PC12, STM32F4_PINMUX_FUNC_PC12_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS | - STM32_OSPEEDR_VERY_HIGH_SPEED}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_SPI2_NSS | - STM32_OSPEEDR_VERY_HIGH_SPEED}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PD3, STM32F4_PINMUX_FUNC_PD3_SPI2_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PB14, STM32F4_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F4_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi4), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PE11, STM32F4_PINMUX_FUNC_PE11_SPI4_NSS | - STM32_OSPEEDR_VERY_HIGH_SPEED}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PE12, STM32F4_PINMUX_FUNC_PE12_SPI4_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PE13, STM32F4_PINMUX_FUNC_PE13_SPI4_MISO}, - {STM32_PIN_PE14, STM32F4_PINMUX_FUNC_PE14_SPI4_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2s2), okay) && CONFIG_I2S - {STM32_PIN_PC7, STM32F4_PINMUX_FUNC_PC7_I2S2_CK}, - {STM32_PIN_PC1, STM32F4_PINMUX_FUNC_PC1_I2S2_SD}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm3), okay) && CONFIG_PWM - { STM32_PIN_PB4, STM32F4_PINMUX_FUNC_PB4_PWM3_CH1 }, - { STM32_PIN_PC8, STM32F4_PINMUX_FUNC_PC8_PWM3_CH3 }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm4), okay) && CONFIG_PWM - { STM32_PIN_PD14, STM32F4_PINMUX_FUNC_PD14_PWM4_CH3 }, - { STM32_PIN_PD15, STM32F4_PINMUX_FUNC_PD15_PWM4_CH4 }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm9), okay) && CONFIG_PWM - { STM32_PIN_PE5, STM32F4_PINMUX_FUNC_PE5_PWM9_CH1 }, - { STM32_PIN_PE6, STM32F4_PINMUX_FUNC_PE6_PWM9_CH2 }, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/96b_wistrio/96b_wistrio.dts b/boards/arm/96b_wistrio/96b_wistrio.dts index fb35b811c01998..43649c1b118cdf 100644 --- a/boards/arm/96b_wistrio/96b_wistrio.dts +++ b/boards/arm/96b_wistrio/96b_wistrio.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "96b_lscon.dtsi" / { model = "RAKWireless 96boards WisTrio board"; - compatible = "rak,wistrio", "st,stm32l151"; + compatible = "rak,wistrio"; chosen { zephyr,console = &usart1; @@ -39,16 +40,19 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; -&usart3 { +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; lis3dh@32 { @@ -59,8 +63,9 @@ }; &spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; - cs-gpios = <&gpiob 0 0>; + cs-gpios = <&gpiob 0 GPIO_ACTIVE_LOW>; lora: sx1276@0 { compatible = "semtech,sx1276"; @@ -73,6 +78,7 @@ <&gpioh 0 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, <&gpioc 13 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; spi-max-frequency = <1000000>; + power-amplifier-output = "pa-boost"; }; }; diff --git a/boards/arm/96b_wistrio/96b_wistrio_defconfig b/boards/arm/96b_wistrio/96b_wistrio_defconfig index fd66095580fc4d..7dfd676c92522b 100644 --- a/boards/arm/96b_wistrio/96b_wistrio_defconfig +++ b/boards/arm/96b_wistrio/96b_wistrio_defconfig @@ -3,6 +3,12 @@ CONFIG_SOC_STM32L151XBA=y # 32MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/96b_wistrio/pinmux.c b/boards/arm/96b_wistrio/pinmux.c index 9606c80df83dc5..068d12a819654c 100644 --- a/boards/arm/96b_wistrio/pinmux.c +++ b/boards/arm/96b_wistrio/pinmux.c @@ -14,24 +14,6 @@ #include static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32L1X_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32L1X_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L1X_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA15, STM32L1X_PINMUX_FUNC_PA15_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32L1X_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32L1X_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PA5, STM32L1X_PINMUX_FUNC_PA5_SPI1_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PA6, STM32L1X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L1X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif /* RF_CTX_PA */ {STM32_PIN_PA4, STM32_PUSHPULL_PULLUP}, /* RF_CRX_RX */ @@ -40,10 +22,10 @@ static const struct pin_config pinconf[] = { {STM32_PIN_PB7, STM32_PUSHPULL_PULLUP}, }; -static int pinmux_stm32_init(struct device *port) +static int pinmux_stm32_init(const struct device *port) { ARG_UNUSED(port); - struct device *gpioa, *gpiob, *gpioh; + const struct device *gpioa, *gpiob, *gpioh; stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); diff --git a/boards/arm/actinius_icarus/actinius_icarus.dts b/boards/arm/actinius_icarus/actinius_icarus.dts index 883f040c1e4932..7566929aff7a0d 100644 --- a/boards/arm/actinius_icarus/actinius_icarus.dts +++ b/boards/arm/actinius_icarus/actinius_icarus.dts @@ -10,8 +10,10 @@ / { chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram0_s; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,sram-secure-partition = &sram0_s; + zephyr,sram-non-secure-partition = &sram0_ns; }; }; diff --git a/boards/arm/actinius_icarus/actinius_icarus.yaml b/boards/arm/actinius_icarus/actinius_icarus.yaml index 52ce305bed16c5..7e910822371baa 100644 --- a/boards/arm/actinius_icarus/actinius_icarus.yaml +++ b/boards/arm/actinius_icarus/actinius_icarus.yaml @@ -9,7 +9,14 @@ toolchain: ram: 64 flash: 256 supported: + - gpio - i2c - pwm + - spi - watchdog - counter + - feather_serial + - feather_i2c + - feather_spi + - arduino_i2c + - arduino_spi diff --git a/boards/arm/actinius_icarus/actinius_icarus_common.dts b/boards/arm/actinius_icarus/actinius_icarus_common.dts index 5fd3c5e2408e26..a8b3c204cfaf81 100644 --- a/boards/arm/actinius_icarus/actinius_icarus_common.dts +++ b/boards/arm/actinius_icarus/actinius_icarus_common.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Actinius + * Copyright (c) 2019-2020 Actinius * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,6 +73,13 @@ blue-pwm-led = &blue_pwm_led; sw0 = &button0; }; + + vbatt { + compatible = "voltage-divider"; + io-channels = <&adc 0>; + output-ohms = <10000000>; + full-ohms = <(10000000 + 4700000)>; + }; }; &adc { @@ -120,7 +127,7 @@ scl-pin = <27>; lis2dh12-accel@19 { - compatible = "st,lis2dh"; + compatible = "st,lis2dh12", "st,lis2dh"; reg = <0x19>; irq-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>, <&gpio0 29 GPIO_ACTIVE_HIGH>; @@ -187,13 +194,13 @@ slot0_partition: partition@10000 { label = "image-0"; }; - slot0_ns_partition: partition@40000 { + slot0_ns_partition: partition@50000 { label = "image-0-nonsecure"; }; slot1_partition: partition@80000 { label = "image-1"; }; - slot1_ns_partition: partition@b0000 { + slot1_ns_partition: partition@c0000 { label = "image-1-nonsecure"; }; scratch_partition: partition@f0000 { @@ -208,16 +215,28 @@ }; / { - /* SRAM allocated and used by the BSD library */ - sram0_bsd: memory@20010000 { - compatible = "mmio-sram"; - }; - /* SRAM allocated to the Non-Secure image */ - sram0_ns: memory@20020000 { - compatible = "mmio-sram"; + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + }; + + sram0_bsd: image_bsd@20010000 { + /* BSD (shared) memory */ + }; + + sram0_ns: image_ns@20020000 { + /* Non-Secure image memory */ + }; }; }; +/* Include file with mappings and aliases for feather compatibility */ +#include "feather_connector.dtsi" + /* Include partition configuration file */ #include "actinius_icarus_partition_conf.dts" diff --git a/boards/arm/actinius_icarus/actinius_icarus_defconfig b/boards/arm/actinius_icarus/actinius_icarus_defconfig index 68056757f5e07a..58d15739a954cf 100644 --- a/boards/arm/actinius_icarus/actinius_icarus_defconfig +++ b/boards/arm/actinius_icarus/actinius_icarus_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_ACTINIUS_ICARUS=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable TrustZone-M CONFIG_ARM_TRUSTZONE_M=y diff --git a/boards/arm/actinius_icarus/actinius_icarus_ns.yaml b/boards/arm/actinius_icarus/actinius_icarus_ns.yaml index 09336b5fe0e341..57eef9a4849b3c 100644 --- a/boards/arm/actinius_icarus/actinius_icarus_ns.yaml +++ b/boards/arm/actinius_icarus/actinius_icarus_ns.yaml @@ -7,8 +7,16 @@ toolchain: - xtools - zephyr ram: 128 -flash: 256 +flash: 192 supported: + - gpio - i2c - pwm + - spi - watchdog + - counter + - feather_serial + - feather_i2c + - feather_spi + - arduino_i2c + - arduino_spi diff --git a/boards/arm/actinius_icarus/actinius_icarus_ns_defconfig b/boards/arm/actinius_icarus/actinius_icarus_ns_defconfig index dec8dda5c6cf17..e2e6e11584be8d 100644 --- a/boards/arm/actinius_icarus/actinius_icarus_ns_defconfig +++ b/boards/arm/actinius_icarus/actinius_icarus_ns_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_ACTINIUS_ICARUS_NS=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable TrustZone-M CONFIG_ARM_TRUSTZONE_M=y diff --git a/boards/arm/actinius_icarus/actinius_icarus_partition_conf.dts b/boards/arm/actinius_icarus/actinius_icarus_partition_conf.dts index f121f603f77252..d1ea9cac1b3da1 100644 --- a/boards/arm/actinius_icarus/actinius_icarus_partition_conf.dts +++ b/boards/arm/actinius_icarus/actinius_icarus_partition_conf.dts @@ -22,30 +22,30 @@ */ &slot0_partition { - reg = <0x00010000 0x30000>; + reg = <0x00010000 0x40000>; }; &slot0_ns_partition { - reg = <0x00040000 0x40000>; + reg = <0x00050000 0x30000>; }; &slot1_partition { - reg = <0x00080000 0x30000>; + reg = <0x00080000 0x40000>; }; &slot1_ns_partition { - reg = <0x000b0000 0x40000>; + reg = <0x000c0000 0x30000>; }; /* Default SRAM planning when building for nRF9160 with * ARM TrustZone-M support - * - Lowest 64 kB SRAM allocated to Secure image (sram0). + * - Lowest 64 kB SRAM allocated to Secure image (sram0_s). * - 64 kB SRAM reserved for and used by the BSD socket - * library. + * library (sram0_bsd). * - Upper 128 kB allocated to Non-Secure image (sram0_ns). */ -&sram0 { +&sram0_s { reg = <0x20000000 DT_SIZE_K(64)>; }; diff --git a/boards/arm/actinius_icarus/board.c b/boards/arm/actinius_icarus/board.c index b34f02432353b1..2579469b8ae1e2 100644 --- a/boards/arm/actinius_icarus/board.c +++ b/boards/arm/actinius_icarus/board.c @@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(board_control, CONFIG_BOARD_ICARUS_LOG_LEVEL); static void select_sim(void) { - struct device *port = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0))); + const struct device *port = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0))); if (!port) { LOG_ERR("Could not get GPIO Device Binding"); @@ -31,7 +31,7 @@ static void select_sim(void) #endif } -static int board_actinius_icarus_init(struct device *dev) +static int board_actinius_icarus_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/actinius_icarus/board.cmake b/boards/arm/actinius_icarus/board.cmake index 3d655f4e90c0ea..4556a8aa9b2eba 100644 --- a/boards/arm/actinius_icarus/board.cmake +++ b/boards/arm/actinius_icarus/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF91") board_runner_args(jlink "--device=cortex-m33" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/actinius_icarus/doc/img/Icarus_front.png b/boards/arm/actinius_icarus/doc/img/Icarus_front.png new file mode 100644 index 00000000000000..4534a5c922e7a3 Binary files /dev/null and b/boards/arm/actinius_icarus/doc/img/Icarus_front.png differ diff --git a/boards/arm/actinius_icarus/doc/index.rst b/boards/arm/actinius_icarus/doc/index.rst index d4473f0e5310a1..8fb4001cc315b2 100644 --- a/boards/arm/actinius_icarus/doc/index.rst +++ b/boards/arm/actinius_icarus/doc/index.rst @@ -6,9 +6,17 @@ Actinius Icarus Overview ******** -The Icarus IoT Dev Board is a complete development board for developing -LTE-M/NB-IoT applications, with GPS, Accelerometer, battery management -and others. +.. figure:: img/Icarus_front.png + :width: 450px + :align: center + :alt: Icarus IoT Dev Board + + Icarus IoT Dev Board (nRF9160 Feather) + +The Icarus is a cost-effective cellular IoT board in Adafruit's Feather/FeatherWing +form factor. It is built around Nordic Semi's nRF9160 modem and combines +LTE-M, NB-IoT, GPS, accelerometer, USB, LiPo charger as well as +an eSIM and a nano SIM connector. The main uController is the Nordic Semiconductor nRF9160, with ARM Cortex-M33F CPU, ARMv8-M Security Extension and the @@ -110,7 +118,8 @@ have to set the IDAU (SPU) configuration to allow Non-Secure access to all CPU resources utilized by the Non-Secure application firmware. SPU configuration shall take place before jumping to the Non-Secure application. -More information can be found in the `Icarus "Get Started" Guide`_. +More information can be found in the `Icarus "Get Started" Guide`_ or the +`Actinius Documentation Portal`_. References ********** @@ -125,3 +134,6 @@ References .. _Icarus "Get Started" Guide: https://www.actinius.com/get-started + +.. _Actinius Documentation Portal: + https://docs.actinius.com diff --git a/boards/arm/actinius_icarus/feather_connector.dtsi b/boards/arm/actinius_icarus/feather_connector.dtsi new file mode 100644 index 00000000000000..6d99f051ea43fc --- /dev/null +++ b/boards/arm/actinius_icarus/feather_connector.dtsi @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 Actinius + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + feather_header: feather_connector { + compatible = "adafruit-feather-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 14 0>, /* A1 */ + <1 0 &gpio0 15 0>, /* A2 */ + <2 0 &gpio0 16 0>, /* A3 */ + <3 0 &gpio0 17 0>, /* A4 */ + <4 0 &gpio0 18 0>, /* A5 */ + <5 0 &gpio0 19 0>, /* A6 */ + <6 0 &gpio0 20 0>, /* SCK */ + <7 0 &gpio0 21 0>, /* MOSI */ + <8 0 &gpio0 22 0>, /* MISO */ + <9 0 &gpio0 23 0>, /* RX */ + <10 0 &gpio0 24 0>, /* TX */ + /* 11 is VIN */ + <12 0 &gpio0 26 0>, /* SDA */ + <13 0 &gpio0 27 0>, /* SCL */ + <14 0 &gpio0 31 0>, /* 31 */ + <15 0 &gpio0 30 0>, /* 30 */ + <16 0 &gpio0 0 0>, /* 0 */ + <17 0 &gpio0 1 0>, /* 1 */ + <18 0 &gpio0 2 0>, /* 2 */ + <19 0 &gpio0 3 0>, /* 3 */ + <20 0 &gpio0 4 0>; /* 4 */ + }; +}; + +feather_adc: &adc { }; +feather_serial: &uart0 { }; +feather_i2c: &i2c2 { }; +feather_spi: &spi3 { }; + +arduino_adc: &adc { }; +arduino_serial: &uart0 { }; +arduino_i2c: &i2c2 { }; +arduino_spi: &spi3 { }; diff --git a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts index c63733b55557bc..0995726d678130 100644 --- a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts +++ b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto.dts @@ -7,6 +7,8 @@ /dts-v1/; #include +#include "feather_connector.dtsi" + / { model = "Adafruit Feather M0 Basic Proto"; compatible = "adafruit,feather-m0-basic-proto", "atmel,samd21g18a", @@ -46,6 +48,14 @@ txpo = <1>; }; +&sercom3 { + status = "okay"; + compatible = "atmel,sam0-i2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; +}; + &sercom4 { status = "okay"; compatible = "atmel,sam0-spi"; diff --git a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto_defconfig b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto_defconfig index 87c6821334e22c..c5e974851e97ab 100644 --- a/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto_defconfig +++ b/boards/arm/adafruit_feather_m0_basic_proto/adafruit_feather_m0_basic_proto_defconfig @@ -22,3 +22,5 @@ CONFIG_PINMUX_SAM0=y CONFIG_USB=y CONFIG_USB_DC_SAM0=y CONFIG_USE_DT_CODE_PARTITION=y +CONFIG_I2C=y +CONFIG_I2C_SAM0=y diff --git a/boards/arm/adafruit_feather_m0_basic_proto/board.cmake b/boards/arm/adafruit_feather_m0_basic_proto/board.cmake index cb8bfd7c096599..05695a86d92a9a 100644 --- a/boards/arm/adafruit_feather_m0_basic_proto/board.cmake +++ b/boards/arm/adafruit_feather_m0_basic_proto/board.cmake @@ -2,6 +2,4 @@ # # SPDX-License-Identifier: Apache-2.0 -board_runner_args(bossac "--offset=0x2000") - include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake) diff --git a/boards/arm/adafruit_feather_m0_basic_proto/doc/index.rst b/boards/arm/adafruit_feather_m0_basic_proto/doc/index.rst index c3f9c9854825bb..2344e200383628 100644 --- a/boards/arm/adafruit_feather_m0_basic_proto/doc/index.rst +++ b/boards/arm/adafruit_feather_m0_basic_proto/doc/index.rst @@ -49,6 +49,8 @@ following hardware features: +-----------+------------+------------------------------------------+ | USART | on-chip | Serial port | +-----------+------------+------------------------------------------+ +| I2C | on-chip | Inter-Integrated Circuit | ++-----------+------------+------------------------------------------+ | SPI | on-chip | Serial Peripheral Interface port | +-----------+------------+------------------------------------------+ | USB | on-chip | USB device | @@ -78,6 +80,12 @@ The SAMD21 MCU has 6 SERCOM based USARTs. On the Adafruit Feather M0 Basic Proto, SERCOM0 is the Zephyr console and is available on pins 0 (RX) and 1 (TX). +I2C Port +======== + +The SAMD21 MCU has 6 SERCOM based USARTs. On the Adafruit Feather M0 +Basic Proto, SERCOM3 is available on pin 20 (SDA) and pin 21 (SCL). + SPI Port ======== diff --git a/boards/arm/adafruit_feather_m0_basic_proto/feather_connector.dtsi b/boards/arm/adafruit_feather_m0_basic_proto/feather_connector.dtsi new file mode 100644 index 00000000000000..842da758f9bfb3 --- /dev/null +++ b/boards/arm/adafruit_feather_m0_basic_proto/feather_connector.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2020 Richard Osterloh + * Copyright (c) 2020 Jacek Ozimek + * + * SPDX-License-Identifier: Apache-2.0 + */ + +feather_i2c: &sercom3 {}; diff --git a/boards/arm/adafruit_feather_m0_basic_proto/pinmux.c b/boards/arm/adafruit_feather_m0_basic_proto/pinmux.c index c3a8caa570d0fa..b7af0dc123b5d5 100644 --- a/boards/arm/adafruit_feather_m0_basic_proto/pinmux.c +++ b/boards/arm/adafruit_feather_m0_basic_proto/pinmux.c @@ -8,11 +8,11 @@ #include #include -static int board_pinmux_init(struct device *dev) +static int board_pinmux_init(const struct device *dev) { - struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + const struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); #if (ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_spi) && CONFIG_SPI_SAM0) - struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); + const struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); #endif ARG_UNUSED(dev); @@ -61,6 +61,27 @@ static int board_pinmux_init(struct device *dev) #warning Pin mapping may not be configured #endif +#if (ATMEL_SAM0_DT_SERCOM_CHECK(3, atmel_sam0_i2c) && CONFIG_I2C_SAM0) + /* SERCOM3 on SDA=PA22/pad 0, SCL=PA23/pad 1 */ + pinmux_pin_set(muxa, 22, PINMUX_FUNC_C); + pinmux_pin_set(muxa, 23, PINMUX_FUNC_C); +#endif +#if (ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_i2c) && CONFIG_I2C_SAM0) +#warning Pin mapping may not be configured +#endif +#if (ATMEL_SAM0_DT_SERCOM_CHECK(1, atmel_sam0_i2c) && CONFIG_I2C_SAM0) +#warning Pin mapping may not be configured +#endif +#if (ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_i2c) && CONFIG_I2C_SAM0) +#warning Pin mapping may not be configured +#endif +#if (ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_i2c) && CONFIG_I2C_SAM0) +#warning Pin mapping may not be configured +#endif +#if (ATMEL_SAM0_DT_SERCOM_CHECK(5, atmel_sam0_i2c) && CONFIG_I2C_SAM0) +#warning Pin mapping may not be configured +#endif + #ifdef CONFIG_USB_DC_SAM0 /* USB DP on PA25, USB DM on PA24 */ pinmux_pin_set(muxa, 25, PINMUX_FUNC_G); diff --git a/boards/arm/adafruit_feather_nrf52840/Kconfig.defconfig b/boards/arm/adafruit_feather_nrf52840/Kconfig.defconfig index 4b194bdc2d5a0c..f09ae11e464451 100644 --- a/boards/arm/adafruit_feather_nrf52840/Kconfig.defconfig +++ b/boards/arm/adafruit_feather_nrf52840/Kconfig.defconfig @@ -18,10 +18,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts index b3f9854a70bf4a..da7f5087546983 100644 --- a/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts +++ b/boards/arm/adafruit_feather_nrf52840/adafruit_feather_nrf52840.dts @@ -82,17 +82,38 @@ }; &spi1 { + compatible = "nordic,nrf-spi"; status = "okay"; sck-pin = <14>; mosi-pin = <13>; miso-pin = <15>; }; +&qspi { + status = "okay"; + sck-pin = <19>; + io-pins = <17>, <22>, <23>, <21>; + csn-pins = <20>; + gd25q16: gd25q16@0 { + /* NOTE: Quad mode not supported as driver does not handle + * QE bit setting in SR2. Ref. GD25Q16C, Rev 3.0, p. 12. + */ + compatible = "nordic,qspi-nor"; + reg = <0>; + writeoc = "pp2o"; + readoc = "read2io"; + sck-frequency = <16000000>; + label = "GD25Q16"; + jedec-id = [c8 40 15]; + size = <16777216>; + has-dpd; + t-enter-dpd = <20000>; + t-exit-dpd = <20000>; + }; +}; + &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/adafruit_feather_stm32f405/CMakeLists.txt b/boards/arm/adafruit_feather_stm32f405/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/adafruit_feather_stm32f405/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.dts b/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.dts index c4653b3945718b..138e2729df8ba1 100644 --- a/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.dts +++ b/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "feather_connector.dtsi" / { @@ -23,7 +24,7 @@ leds { compatible = "gpio-leds"; led: led { - gpios = <&gpioc 1 GPIO_INT_ACTIVE_HIGH>; + gpios = <&gpioc 1 GPIO_ACTIVE_HIGH>; label = "User LED"; }; }; @@ -34,16 +35,22 @@ }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; }; +&spi1_nss_pa15 { slew-rate = "very-high-speed"; }; + &spi1 { + pinctrl-0 = <&spi1_nss_pa15 &spi1_sck_pb3 + &spi1_miso_pb4 &spi1_mosi_pb5>; status = "okay"; cs-gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; gd25q16: gd25q16c@0 { @@ -61,6 +68,7 @@ }; &spi2 { + pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; @@ -69,5 +77,6 @@ }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; diff --git a/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405_defconfig b/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405_defconfig index 4ab0e3bf88f6cd..11907bac572c99 100644 --- a/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405_defconfig +++ b/boards/arm/adafruit_feather_stm32f405/adafruit_feather_stm32f405_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/adafruit_feather_stm32f405/pinmux.c b/boards/arm/adafruit_feather_stm32f405/pinmux.c deleted file mode 100644 index 501785290092b8..00000000000000 --- a/boards/arm/adafruit_feather_stm32f405/pinmux.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2020 Lucian Copeland for Adafruit Industries - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for Feather STM32F405 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32F4_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA15, STM32F4_PINMUX_FUNC_PA15_SPI1_NSS | - STM32_OSPEEDR_VERY_HIGH_SPEED}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB3, STM32F4_PINMUX_FUNC_PB3_SPI1_SCK | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PB4, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PB5, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - {STM32_PIN_PB13, STM32F4_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32F4_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F4_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/adafruit_itsybitsy_m4_express/CMakeLists.txt b/boards/arm/adafruit_itsybitsy_m4_express/CMakeLists.txt new file mode 100644 index 00000000000000..69ff5e8fbf8390 --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_PINMUX_SAM0) + zephyr_library() + zephyr_library_sources(pinmux.c) +endif() diff --git a/boards/arm/adafruit_itsybitsy_m4_express/Kconfig.board b/boards/arm/adafruit_itsybitsy_m4_express/Kconfig.board new file mode 100644 index 00000000000000..79fd1eb629337d --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/Kconfig.board @@ -0,0 +1,8 @@ +# Adafruit ItsyBitsy M4 Express board configuration + +# Copyright (c) 2020 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ADAFRUIT_ITSYBITSY_M4_EXPRESS + bool "Adafruit ItsyBitsy M4 Express" + depends on SOC_PART_NUMBER_SAMD51G19A diff --git a/boards/arm/adafruit_itsybitsy_m4_express/Kconfig.defconfig b/boards/arm/adafruit_itsybitsy_m4_express/Kconfig.defconfig new file mode 100644 index 00000000000000..922a2ab58bddbb --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Adafruit ItsyBitsy M4 Express board configuration + +# Copyright (c) 2020 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "adafruit_itsybitsy_m4_express" + depends on BOARD_ADAFRUIT_ITSYBITSY_M4_EXPRESS diff --git a/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.dts b/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.dts new file mode 100644 index 00000000000000..054f1a25b9b0e6 --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.dts @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2020 Google LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Adafruit ItsyBitsy M4 Express"; + compatible = "adafruit,itsybitsy-m4-express"; + + chosen { + zephyr,console = &sercom3; + zephyr,shell-uart = &sercom3; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &code_partition; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + pwm-led0 = &pwm_led0; + pwm-0 = &tcc0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&porta 22 0>; + label = "LED"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&tcc0 2>; + }; + }; +}; + +&cpu0 { + clock-frequency = <120000000>; +}; + +&sercom3 { + status = "okay"; + compatible = "atmel,sam0-uart"; + current-speed = <115200>; + rxpo = <1>; + txpo = <0>; +}; + +&sercom1 { + status = "okay"; + compatible = "atmel,sam0-spi"; + dipo = <3>; + dopo = <0>; + + #address-cells = <1>; + #size-cells = <0>; +}; + +&tcc0 { + status = "okay"; + compatible = "atmel,sam0-tcc-pwm"; + prescaler = <8>; + + #pwm-cells = <1>; +}; + +&usb0 { + status = "okay"; +}; + +&dmac { + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "uf2"; + reg = <0x00000000 DT_SIZE_K(16)>; + read-only; + }; + + code_partition: partition@4000 { + label = "code"; + reg = <0x4000 DT_SIZE_K(512-16-16)>; + read-only; + }; + + /* + * The final 16 KiB is reserved for the application. + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@7c000 { + label = "storage"; + reg = <0x7c000 DT_SIZE_K(16)>; + }; + }; +}; diff --git a/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml b/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml new file mode 100644 index 00000000000000..c8c88d2bcd68e3 --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml @@ -0,0 +1,20 @@ +identifier: adafruit_itsybitsy_m4_express +name: Adafruit ItsyBitsy M4 Express +type: mcu +arch: arm +ram: 192 +flash: 512 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - dma + - gpio + - hwinfo + - pinmux + - pwm + - spi + - uart + - usb_device + - watchdog diff --git a/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express_defconfig b/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express_defconfig new file mode 100644 index 00000000000000..c8db92c982a533 --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express_defconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_SAMD51=y +CONFIG_SOC_PART_NUMBER_SAMD51G19A=y +CONFIG_BOARD_ADAFRUIT_ITSYBITSY_M4_EXPRESS=y +CONFIG_SOC_ATMEL_SAMD5X_OSCULP32K_AS_MAIN=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_SERIAL=y +CONFIG_PINMUX=y +CONFIG_BOOTLOADER_BOSSA=y +CONFIG_BOOTLOADER_BOSSA_ADAFRUIT_UF2=y diff --git a/boards/arm/adafruit_itsybitsy_m4_express/board.cmake b/boards/arm/adafruit_itsybitsy_m4_express/board.cmake new file mode 100644 index 00000000000000..e240a42f36a39c --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2020 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/adafruit_itsybitsy_m4_express/doc/img/adafruit_itsybitsy_m4_express.png b/boards/arm/adafruit_itsybitsy_m4_express/doc/img/adafruit_itsybitsy_m4_express.png new file mode 100644 index 00000000000000..ba04458e3960c3 Binary files /dev/null and b/boards/arm/adafruit_itsybitsy_m4_express/doc/img/adafruit_itsybitsy_m4_express.png differ diff --git a/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst b/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst new file mode 100644 index 00000000000000..06a0691d299efb --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/doc/index.rst @@ -0,0 +1,209 @@ +.. _adafruit_itsybitsy_m4_express: + +Adafruit ItsyBitsy M4 Express +############################# + +Overview +******** + +The Adafruit ItsyBitsy M4 express is a small (36 mm x 18 mm) ARM development +board with an onboard RGB LED, USB port, 2 MiB of SPI flash, and range of I/O +broken out onto 23 GPIO pins. + +.. image:: img/adafruit_itsybitsy_m4_express.png + :width: 500px + :align: center + :alt: Adafruit ItsyBitsy M4 Express + +Hardware +******** + +- ATSAMD51G19A ARM Cortex-M4 processor at 120 MHz +- 512 KiB of flash memory and 192 KiB of RAM +- 2 MiB of SPI flash +- Internal trimmed 8 MHz oscillator +- A user LED +- An RGB DotStar LED +- Native USB port +- One reset button + +Supported Features +================== + +The adafruit_itsybitsy_m4_express board configuration supports the following +hardware features: + ++-----------+------------+------------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+==========================================+ +| NVIC | on-chip | Nested vector interrupt controller | ++-----------+------------+------------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+------------------------------------------+ +| WDT | on-chip | Watchdog | ++-----------+------------+------------------------------------------+ +| GPIO | on-chip | I/O ports | ++-----------+------------+------------------------------------------+ +| USART | on-chip | Serial ports | ++-----------+------------+------------------------------------------+ +| SPI | on-chip | Serial Peripheral Interface ports | ++-----------+------------+------------------------------------------+ +| TRNG | on-chip | True Random Number Generator | ++-----------+------------+------------------------------------------+ +| HWINFO | on-chip | Unique 128 bit serial number | ++-----------+------------+------------------------------------------+ +| RTC | on-chip | Real-Time Counter | ++-----------+------------+------------------------------------------+ +| USB | on-chip | USB device | ++-----------+------------+------------------------------------------+ +| WDT | on-chip | Watchdog Timer | ++-----------+------------+------------------------------------------+ +| PWM | on-chip | PWM | ++-----------+------------+------------------------------------------+ + +Other hardware features are not currently supported by Zephyr. + +The default configuration can be found in the Kconfig file +:zephyr_file:`boards/arm/adafruit_itsybitsy_m4_express/adafruit_itsybitsy_m4_express_defconfig`. + +Zephyr can use the default Cortex-M SYSTICK timer or the SAM0 specific RTC. +To use the RTC, set :code:`CONFIG_CORTEX_M_SYSTICK=n` and set +:code:`CONFIG_SYS_CLOCK_TICKS_PER_SEC` to no more than 32 kHZ divided by 7, +i.e. no more than 4500. + +Connections and IOs +=================== + +The `Adafruit Learning System`_ has detailed information about +the board including `pinouts`_ and the `schematic`_. + +System Clock +============ + +The SAMD51 MCU is configured to use the 32 kHz internal oscillator +with the on-chip PLL generating the 120 MHz system clock. + +Serial Port +=========== + +The SAMD51 MCU has 6 SERCOM based USARTs. On the ItsyBitsy, SERCOM3 is +the Zephyr console and is available on pins 0 (RX) and 1 (TX). + +SPI Port +======== + +The SAMD51 MCU has 6 SERCOM based SPIs. On the ItsyBitsy, SERCOM1 can be put +into SPI mode and used to connect to devices over the SCK (SCLK), MO (MOSI), and +MI (MISO) pins. + +PWM +=== + +The SAMD51 has three PWM generators with up to six channels each. :code:`TCC_0` +has a resolution of 24 bits and all other generators are 16 bit. :code:`TCC_1` +pin 2 is mapped to PA18 (D7) and pin 3 is mapped to PA19 (D9). + +USB Device Port +=============== + +The SAMD51 MCU has a USB device port that can be used to communicate +with a host PC. See the :ref:`usb-samples` sample applications for +more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +serial port that echos characters back to the host PC. + +Programming and Debugging +************************* + +The ItsyBitsy ships with a the BOSSA compatible UF2 bootloader. The +bootloader can be entered by quickly tapping the reset button twice. + +Additionally, if :code:`CONFIG_USB_CDC_ACM` is enabled then the bootloader +will be entered automatically when you run :code:`west flash`. + +Flashing +======== + +#. Build the Zephyr kernel and the :ref:`hello_world` sample application: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_itsybitsy_m4_express + :goals: build + :compact: + +#. Connect the ItsyBitsy to your host computer using USB + +#. Connect a 3.3 V USB to serial adapter to the board and to the + host. See the `Serial Port`_ section above for the board's pin + connections. + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyUSB0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyUSB0 -o + + The -o option tells minicom not to send the modem initialization + string. Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + +#. Tap the reset button twice quickly to enter bootloader mode + +#. Flash the image: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_itsybitsy_m4_express + :goals: flash + :compact: + + You should see "Hello World! arm" in your terminal. + +Debugging +========= + +In addition to the built-in bootloader, the ItsyBitsy can be flashed and +debugged using a SWD probe such as the Segger J-Link. + +#. Connect the board to the probe by connecting the :code:`SWCLK`, + :code:`SWDIO`, :code:`RESET`, :code:`GND`, and :code:`3V3` pins on the + ItsyBitsy to the :code:`SWCLK`, :code:`SWDIO`, :code:`RESET`, :code:`GND`, + and :code:`VTref` pins on the `J-Link`_. + +#. Flash the image: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_itsybitsy_m4_express + :goals: flash -r openocd + :compact: + +#. Start debugging: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_itsybitsy_m4_express + :goals: debug + :compact: + +References +********** + +.. target-notes:: + +.. _Adafruit Learning System: + https://learn.adafruit.com/introducing-adafruit-itsybitsy-m4 + +.. _pinouts: + https://learn.adafruit.com/introducing-adafruit-itsybitsy-m4/pinouts + +.. _schematic: + https://learn.adafruit.com/introducing-adafruit-itsybitsy-m4/downloads + +.. _J-Link: + https://www.segger.com/products/debug-probes/j-link/technology/interface-description/ diff --git a/boards/arm/adafruit_itsybitsy_m4_express/pinmux.c b/boards/arm/adafruit_itsybitsy_m4_express/pinmux.c new file mode 100644 index 00000000000000..7599c0e93d8fe7 --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/pinmux.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020 Google LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static int board_pinmux_init(const struct device *dev) +{ + const struct device *muxa = + device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + const struct device *muxb = + device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); + + ARG_UNUSED(dev); + (void)muxa; + (void)muxb; + +#if ATMEL_SAM0_DT_SERCOM_CHECK(3, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) + /* SERCOM3 on RX=PA16/pad 1, TX=PA17/pad 0 */ + pinmux_pin_set(muxa, 16, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 17, PINMUX_FUNC_D); +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(1, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(5, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif + +#if ATMEL_SAM0_DT_SERCOM_CHECK(1, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) + /* SPI SERCOM1 on MISO=PB23/pad 3, MOSI=PA0/pad 0, SCK=PA1/pad 1 */ + pinmux_pin_set(muxa, 0, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 1, PINMUX_FUNC_D); + pinmux_pin_set(muxb, 23, PINMUX_FUNC_C); +#endif + +#if ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(5, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) +#warning Pin mapping may not be configured +#endif + +#if defined(CONFIG_PWM_SAM0_TCC) +#if ATMEL_SAM0_DT_TCC_CHECK(0, atmel_sam0_tcc_pwm) + /* TCC0/WO[2] on PA22 (LED) */ + pinmux_pin_set(muxa, 22, PINMUX_FUNC_G); +#endif +#if ATMEL_SAM0_DT_TCC_CHECK(1, atmel_sam0_tcc_pwm) + /* TCC1/WO[2] on PA18 (D7) */ + pinmux_pin_set(muxa, 18, PINMUX_FUNC_F); + /* TCC1/WO[3] on PA19 (D9) */ + pinmux_pin_set(muxa, 19, PINMUX_FUNC_F); +#endif +#endif + + if (IS_ENABLED(CONFIG_USB_DC_SAM0)) { + /* USB DP on PA25, USB DM on PA24 */ + pinmux_pin_set(muxa, 25, PINMUX_FUNC_H); + pinmux_pin_set(muxa, 24, PINMUX_FUNC_H); + } + + return 0; +} + +SYS_INIT(board_pinmux_init, PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY); diff --git a/boards/arm/adafruit_itsybitsy_m4_express/support/openocd.cfg b/boards/arm/adafruit_itsybitsy_m4_express/support/openocd.cfg new file mode 100644 index 00000000000000..096e396efc5f9f --- /dev/null +++ b/boards/arm/adafruit_itsybitsy_m4_express/support/openocd.cfg @@ -0,0 +1,21 @@ +source [find interface/jlink.cfg] + +transport select swd + +set CHIPNAME atsamd51g19a +source [find target/atsame5x.cfg] + +# TODO(http://openocd.zylin.com/#/c/5706/): lower the clock speed to workaround +# an erase timeout. +adapter_khz 500 +reset_config srst_only + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts index adbae9fd868ef2..ecaf358017e44e 100644 --- a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts +++ b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.dts @@ -22,6 +22,7 @@ /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; + pwm-led0 = &pwm_led0; }; leds { @@ -31,6 +32,14 @@ label = "LED"; }; }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&tcc0 2>; + }; + }; }; &cpu0 { @@ -70,6 +79,15 @@ }; }; +&tcc0 { + status = "okay"; + compatible = "atmel,sam0-tcc-pwm"; + /* Gives a maximum period of 1.4 s */ + prescaler = <4>; + + #pwm-cells = <1>; +}; + &flash0 { partitions { compatible = "fixed-partitions"; diff --git a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml index 643849aff15ddf..ecbb3eb68b6804 100644 --- a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml +++ b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0.yaml @@ -8,3 +8,15 @@ toolchain: - zephyr - gnuarmemb - xtools +supported: + - adc + - counter + - dma + - gpio + - hwinfo + - pinmux + - pwm + - spi + - uart + - usb_device + - watchdog diff --git a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0_defconfig b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0_defconfig index 04a891996b5c81..addca050df6190 100644 --- a/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0_defconfig +++ b/boards/arm/adafruit_trinket_m0/adafruit_trinket_m0_defconfig @@ -7,17 +7,9 @@ CONFIG_SOC_ATMEL_SAMD_OSC8M_AS_MAIN=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_UART_SAM0=y CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_GPIO=y -CONFIG_GPIO_SAM0=y -CONFIG_WATCHDOG=y -CONFIG_WDT_SAM0=y -CONFIG_SPI=y -CONFIG_SPI_SAM0=y +CONFIG_SERIAL=y CONFIG_PINMUX=y -CONFIG_PINMUX_SAM0=y -CONFIG_USB=y -CONFIG_USB_DC_SAM0=y CONFIG_USE_DT_CODE_PARTITION=y +CONFIG_BOOTLOADER_BOSSA=y +CONFIG_BOOTLOADER_BOSSA_ADAFRUIT_UF2=y diff --git a/boards/arm/adafruit_trinket_m0/board.cmake b/boards/arm/adafruit_trinket_m0/board.cmake index 85df6ffab987bf..9525725939c62d 100644 --- a/boards/arm/adafruit_trinket_m0/board.cmake +++ b/boards/arm/adafruit_trinket_m0/board.cmake @@ -1,6 +1,4 @@ # Copyright (c) 2018 Google LLC. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(bossac "--offset=0x2000") - include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake) diff --git a/boards/arm/adafruit_trinket_m0/doc/index.rst b/boards/arm/adafruit_trinket_m0/doc/index.rst index a56265e5e7e083..7aeea8a6461b1b 100644 --- a/boards/arm/adafruit_trinket_m0/doc/index.rst +++ b/boards/arm/adafruit_trinket_m0/doc/index.rst @@ -45,6 +45,8 @@ features: +-----------+------------+------------------------------------------+ | GPIO | on-chip | I/O ports | +-----------+------------+------------------------------------------+ +| PWM | on-chip | Pulse Width Modulation | ++-----------+------------+------------------------------------------+ | USART | on-chip | Serial ports | +-----------+------------+------------------------------------------+ | SPI | on-chip | Serial Peripheral Interface ports | @@ -78,6 +80,13 @@ The SAMD21 MCU has 6 SERCOM based USARTs. On the Trinket, SERCOM0 is the Zephyr console and is available on pins 3 (RX) and 4 (TX). SERCOM2 is available on pins 2 (RX) and 0 (TX). +PWM +=== + +The SAMD21 MCU has 3 TCC based PWM units with up to 4 outputs each and a period +of 24 bits or 16 bits. If :code:`CONFIG_PWM_SAM0_TCC` is enabled then LED0 is +driven by TCC0 instead of by GPIO. + SPI Port ======== @@ -100,6 +109,9 @@ Programming and Debugging The Trinket M0 ships the BOSSA compatible UF2 bootloader. The bootloader can be entered by quickly tapping the reset button twice. +Additionally, if :code:`CONFIG_USB_CDC_ACM` is enabled then the bootloader +will be entered automatically when you run :code:`west flash`. + Flashing ======== diff --git a/boards/arm/adafruit_trinket_m0/pinmux.c b/boards/arm/adafruit_trinket_m0/pinmux.c index d085862fdad79d..60d7b1ad361f2e 100644 --- a/boards/arm/adafruit_trinket_m0/pinmux.c +++ b/boards/arm/adafruit_trinket_m0/pinmux.c @@ -8,9 +8,9 @@ #include #include -static int board_pinmux_init(struct device *dev) +static int board_pinmux_init(const struct device *dev) { - struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + const struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); ARG_UNUSED(dev); @@ -65,6 +65,12 @@ static int board_pinmux_init(struct device *dev) #warning Pin mapping may not be configured #endif +#if ATMEL_SAM0_DT_TCC_CHECK(0, atmel_sam0_tcc_pwm) && \ + defined(CONFIG_PWM_SAM0_TCC) + /* LED0 on PA10/TCC0/WO[2] */ + pinmux_pin_set(muxa, 10, PINMUX_FUNC_F); +#endif + #ifdef CONFIG_USB_DC_SAM0 /* USB DP on PA25, USB DM on PA24 */ pinmux_pin_set(muxa, 25, PINMUX_FUNC_G); diff --git a/boards/arm/arduino_due/arduino_due.dts b/boards/arm/arduino_due/arduino_due.dts index 186712d1c6ad1c..0a778bf2255d08 100644 --- a/boards/arm/arduino_due/arduino_due.dts +++ b/boards/arm/arduino_due/arduino_due.dts @@ -52,3 +52,7 @@ status = "okay"; current-speed = <115200>; }; + +&pa8a_uart_urxd { + bias-pull-up; +}; diff --git a/boards/arm/arduino_due/arduino_due_defconfig b/boards/arm/arduino_due/arduino_due_defconfig index 9651d88447cf27..99aed74e0691c1 100644 --- a/boards/arm/arduino_due/arduino_due_defconfig +++ b/boards/arm/arduino_due/arduino_due_defconfig @@ -11,3 +11,6 @@ CONFIG_SERIAL=y CONFIG_UART_SAM=y CONFIG_SOC_ATMEL_SAM3X_EXT_MAINCK=y CONFIG_WDT_DISABLE_AT_BOOT=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/arduino_nano_33_iot/CMakeLists.txt b/boards/arm/arduino_nano_33_iot/CMakeLists.txt new file mode 100644 index 00000000000000..69ff5e8fbf8390 --- /dev/null +++ b/boards/arm/arduino_nano_33_iot/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_PINMUX_SAM0) + zephyr_library() + zephyr_library_sources(pinmux.c) +endif() diff --git a/boards/arm/arduino_nano_33_iot/Kconfig.board b/boards/arm/arduino_nano_33_iot/Kconfig.board new file mode 100644 index 00000000000000..87c65a0f142842 --- /dev/null +++ b/boards/arm/arduino_nano_33_iot/Kconfig.board @@ -0,0 +1,8 @@ +# Arduino Nano 33 IOT board configuration + +# Copyright (c) 2020 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ARDUINO_NANO_33_IOT + bool "Arduino Nano 33 IOT" + depends on SOC_PART_NUMBER_SAMD21G18A diff --git a/boards/arm/arduino_nano_33_iot/Kconfig.defconfig b/boards/arm/arduino_nano_33_iot/Kconfig.defconfig new file mode 100644 index 00000000000000..b4fc2bbc21fe1f --- /dev/null +++ b/boards/arm/arduino_nano_33_iot/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Arduino Nano 33 IOT board configuration + +# Copyright (c) 2020 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "arduino_nano_33_iot" + depends on BOARD_ARDUINO_NANO_33_IOT diff --git a/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.dts b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.dts new file mode 100644 index 00000000000000..f3d84d416d26a0 --- /dev/null +++ b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.dts @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2020 Google LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Arduino Nano 33 IOT"; + compatible = "arduino,nano-33-iot"; + + chosen { + zephyr,console = &sercom5; + zephyr,shell-uart = &sercom5; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &code_partition; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&porta 17 0>; + label = "LED"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&tcc2 1>; + }; + }; + + aliases { + led0 = &led0; + pwm-led0 = &pwm_led0; + }; +}; + +&cpu0 { + clock-frequency = <48000000>; +}; + +&sercom1 { + status = "okay"; + compatible = "atmel,sam0-spi"; + dipo = <0>; + dopo = <1>; + #address-cells = <1>; + #size-cells = <0>; +}; + +&sercom2 { + status = "okay"; + compatible = "atmel,sam0-spi"; + label = "NINA_SPI"; + dipo = <1>; + dopo = <3>; + #address-cells = <1>; + #size-cells = <0>; + + cs-gpios = <&porta 14 GPIO_ACTIVE_LOW>; + + nina_w102@0 { + compatible = "u-blox,nina"; + reg = <0>; + label = "NINA_W102"; + spi-max-frequency = <8000000>; + ready-gpios = <&porta 28 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + reset-gpios = <&porta 8 GPIO_ACTIVE_LOW>; + irq-gpios = <&porta 27 GPIO_PULL_DOWN>; + }; +}; + +&sercom3 { + status = "okay"; + compatible = "atmel,sam0-uart"; + current-speed = <115200>; + rxpo = <1>; + txpo = <0>; + + nina_prog { + compatible = "espressif,esp"; + label = "NINA_PROG"; + reset-gpios = <&porta 8 GPIO_ACTIVE_LOW>; + }; +}; + +&sercom4 { + status = "okay"; + compatible = "atmel,sam0-i2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + + lsm6ds3@6a { + compatible = "st,lsm6ds3"; + reg = <0x6a>; + label = "LSM6DS3"; + }; + + atecc608a@15 { + compatible = "atmel,atecc608"; + reg = <0x6a>; + label = "ATECC608A"; + }; +}; + +&sercom5 { + status = "okay"; + compatible = "atmel,sam0-uart"; + current-speed = <115200>; + rxpo = <3>; + txpo = <1>; +}; + +&tcc2 { + status = "okay"; + compatible = "atmel,sam0-tcc-pwm"; + prescaler = <1024>; + #pwm-cells = <1>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "uf2"; + reg = <0x00000000 0x2000>; + read-only; + }; + + code_partition: partition@2000 { + label = "code"; + reg = <0x2000 0x3A000>; + read-only; + }; + + /* + * The final 16 KiB is reserved for the application. + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@3c000 { + label = "storage"; + reg = <0x0003c000 0x00004000>; + }; + }; +}; + +&usb0 { + status = "okay"; +}; diff --git a/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.yaml b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.yaml new file mode 100644 index 00000000000000..027e9f5b57bab1 --- /dev/null +++ b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot.yaml @@ -0,0 +1,22 @@ +identifier: arduino_nano_33_iot +name: Arduino Nano 33 IOT +type: mcu +arch: arm +ram: 32 +flash: 256 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - counter + - dma + - gpio + - hwinfo + - pinmux + - pwm + - spi + - uart + - usb_device + - watchdog diff --git a/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot_defconfig b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot_defconfig new file mode 100644 index 00000000000000..c0eda653a2e09a --- /dev/null +++ b/boards/arm/arduino_nano_33_iot/arduino_nano_33_iot_defconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_SAMD21=y +CONFIG_SOC_PART_NUMBER_SAMD21G18A=y +CONFIG_BOARD_ARDUINO_NANO_33_IOT=y +CONFIG_SOC_ATMEL_SAMD_OSC8M_AS_MAIN=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_SERIAL=y +CONFIG_PINMUX=y +CONFIG_BOOTLOADER_BOSSA=y +CONFIG_BOOTLOADER_BOSSA_ARDUINO=y diff --git a/boards/arm/arduino_nano_33_iot/board.cmake b/boards/arm/arduino_nano_33_iot/board.cmake new file mode 100644 index 00000000000000..d1bf3453502870 --- /dev/null +++ b/boards/arm/arduino_nano_33_iot/board.cmake @@ -0,0 +1,4 @@ +# Copyright (c) 2020 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake) diff --git a/boards/arm/arduino_nano_33_iot/doc/img/nano_33_iot.png b/boards/arm/arduino_nano_33_iot/doc/img/nano_33_iot.png new file mode 100644 index 00000000000000..d5beace56dd721 Binary files /dev/null and b/boards/arm/arduino_nano_33_iot/doc/img/nano_33_iot.png differ diff --git a/boards/arm/arduino_nano_33_iot/doc/index.rst b/boards/arm/arduino_nano_33_iot/doc/index.rst new file mode 100644 index 00000000000000..51b41165196c4d --- /dev/null +++ b/boards/arm/arduino_nano_33_iot/doc/index.rst @@ -0,0 +1,172 @@ +.. _arduino_nano_33_iot: + +Arduino Nano 33 IOT +################### + +Overview +******** + +The Arduino Nano 33 IOT is a a small form factor development board with USB, +Wifi, Bluetooth, a 6 axis IMU, and secure element. + +.. image:: img/nano_33_iot.png + :width: 500px + :align: center + :alt: Arduino Nano 33 IOT + +Hardware +******** + +- ATSAMD21G18A ARM Cortex-M0+ processor at 48 MHz +- 256 KiB flash memory and 32 KiB of RAM +- One user LED +- One reset button +- Native USB port +- Wifi and Bluetooth via a u-blox NINA-W102 +- ATECC608A secure element +- LSM6DS3 six axis accelerometer and gyro + +Supported Features +================== + +The arduino_nano_33_iot board configuration supports the following hardware +features: + ++-----------+------------+------------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+==========================================+ +| ADC | on-chip | Analog to digital converter | ++-----------+------------+------------------------------------------+ +| COUNTER | on-chip | Pulse counter | ++-----------+------------+------------------------------------------+ +| DMA | on-chip | Direct memory access unit | ++-----------+------------+------------------------------------------+ +| Flash | on-chip | Can be used with LittleFS to store files | ++-----------+------------+------------------------------------------+ +| GPIO | on-chip | I/O ports | ++-----------+------------+------------------------------------------+ +| HWINFO | on-chip | Hardware info and serial number | ++-----------+------------+------------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+------------------------------------------+ +| PWM | on-chip | Pulse Width Modulation | ++-----------+------------+------------------------------------------+ +| SPI | on-chip | Serial Peripheral Interface ports | ++-----------+------------+------------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+------------------------------------------+ +| USART | on-chip | Serial ports | ++-----------+------------+------------------------------------------+ +| USB | on-chip | USB device | ++-----------+------------+------------------------------------------+ +| WDT | on-chip | Watchdog | ++-----------+------------+------------------------------------------+ + +Other hardware features are not currently supported by Zephyr. + +The default configuration can be found in the Kconfig +:zephyr_file:`boards/arm/arduino_nano_33_iot/arduino_nano_33_iot_defconfig`. + +Connections and IOs +=================== + +The `Arduino store`_ has detailed information about board +connections. Download the `schematic`_ for more detail. + +System Clock +============ + +The SAMD21 MCU is configured to use the 8 MHz internal oscillator +with the on-chip PLL generating the 48 MHz system clock. The internal +APB and GCLK unit are set up in the same way as the upstream Arduino +libraries. + +Serial Port +=========== + +The SAMD21 MCU has 6 SERCOM based USARTs. SERCOM5 is available on pins 1 and 2. + +PWM +=== + +The SAMD21 MCU has 3 TCC based PWM units with up to 4 outputs each and a period +of 24 bits or 16 bits. If :code:`CONFIG_PWM_SAM0_TCC` is enabled then LED0 is +driven by TCC2 instead of by GPIO. + +SPI Port +======== + +The SAMD21 MCU has 6 SERCOM based SPIs. SERCOM1 is available on pins 1, 14, +and 15. + +USB Device Port +=============== + +The SAMD21 MCU has a USB device port that can be used to communicate +with a host PC. See the :ref:`usb-samples` sample applications for +more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +serial port that echos characters back to the host PC. + +Programming and Debugging +************************* + +The Nano 33 IOT ships the BOSSA compatible UF2 bootloader. The +bootloader can be entered by quickly tapping the reset button twice. + +Additionally, if :code:`CONFIG_USB_CDC_ACM` is enabled then the bootloader +will be entered automatically when you run :code:`west flash`. + +Flashing +======== + +#. Build the Zephyr kernel and the :ref:`hello_world` sample application: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: arduino_nano_33_iot + :goals: build + :compact: + +#. Connect the Nano 33 IOT to your host computer using USB + +#. Connect a 3.3 V USB to serial adapter to the board and to the + host. See the `Serial Port`_ section above for the board's pin + connections. + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyACM0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyACM0 -o + + The -o option tells minicom not to send the modem initialization + string. Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + +#. Tap the reset button twice quickly to enter bootloader mode + +#. Flash the image: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: arduino_nano_33_iot + :goals: flash + :compact: + + You should see "Hello World! arduino_nano_33_iot" in your terminal. + +References +********** + +.. target-notes:: + +.. _Arduino Store: + https://store.arduino.cc/arduino-nano-33-iot + +.. _schematic: + https://content.arduino.cc/assets/NANO33IoTV2.0_sch.pdf diff --git a/boards/arm/arduino_nano_33_iot/pinmux.c b/boards/arm/arduino_nano_33_iot/pinmux.c new file mode 100644 index 00000000000000..fd283cc7d564d0 --- /dev/null +++ b/boards/arm/arduino_nano_33_iot/pinmux.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2020 Google LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static int board_pinmux_init(const struct device *dev) +{ + const struct device *muxa = + device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + const struct device *muxb = + device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); + + ARG_UNUSED(dev); + +#if defined(CONFIG_UART_SAM0) +#if ATMEL_SAM0_DT_SERCOM_CHECK(3, atmel_sam0_uart) + /* SERCOM3 on RX=PA23/pad 1, TX=PA22/pad 0 */ + pinmux_pin_set(muxa, 22, PINMUX_FUNC_C); + pinmux_pin_set(muxa, 23, PINMUX_FUNC_C); +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(5, atmel_sam0_uart) + /* SERCOM5 on RX=PB23/pad 3, TX=PB22/pad 2 */ + pinmux_pin_set(muxb, 23, PINMUX_FUNC_D); + pinmux_pin_set(muxb, 22, PINMUX_FUNC_D); +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_uart) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(1, atmel_sam0_uart) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_uart) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_uart) +#warning Pin mapping may not be configured +#endif +#endif + +#if defined(CONFIG_SPI_SAM0) +#if ATMEL_SAM0_DT_SERCOM_CHECK(1, atmel_sam0_spi) + /* SPI SERCOM1 on MISO=PA19/pad 3, MOSI=PA16/pad 0, SCK=PA17/pad 1 */ + pinmux_pin_set(muxa, 16, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 17, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 19, PINMUX_FUNC_D); +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_spi) + /* SPI SERCOM2 on MISO=PA13/pad 1, MOSI=PA12/pad 0, SCK=PA15/pad 3 */ + pinmux_pin_set(muxa, 12, PINMUX_FUNC_C); + pinmux_pin_set(muxa, 13, PINMUX_FUNC_C); + pinmux_pin_set(muxa, 15, PINMUX_FUNC_C); +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_spi) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(3, atmel_sam0_spi) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_spi) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(5, atmel_sam0_spi) +#warning Pin mapping may not be configured +#endif +#endif /* CONFIG_SPI_SAM0 */ + +#if defined(CONFIG_I2C_SAM0) +#if ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_i2c) + /* SDA on PB8/pad 0 SCL on PB9/pad 1 */ + pinmux_pin_set(muxb, 8, PINMUX_FUNC_D); + pinmux_pin_set(muxb, 9, PINMUX_FUNC_D); +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_i2c) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(1, atmel_sam0_i2c) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_i2c) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(3, atmel_sam0_i2c) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(5, atmel_sam0_i2c) +#warning Pin mapping may not be configured +#endif +#endif + +#if defined(CONFIG_PWM_SAM0_TCC) +#if ATMEL_SAM0_DT_TCC_CHECK(2, atmel_sam0_tcc_pwm) + /* LED0 on PA17/TCC2/WO[1] */ + pinmux_pin_set(muxa, 17, PINMUX_FUNC_E); +#endif +#endif + + if (IS_ENABLED(CONFIG_USB_DC_SAM0)) { + /* USB DP on PA25, USB DM on PA24 */ + pinmux_pin_set(muxa, 25, PINMUX_FUNC_G); + pinmux_pin_set(muxa, 24, PINMUX_FUNC_G); + } + + return 0; +} + +SYS_INIT(board_pinmux_init, PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY); diff --git a/boards/arm/arduino_zero/arduino_zero.dts b/boards/arm/arduino_zero/arduino_zero.dts index 07e12244b21cca..73832e4ace1a54 100644 --- a/boards/arm/arduino_zero/arduino_zero.dts +++ b/boards/arm/arduino_zero/arduino_zero.dts @@ -23,6 +23,7 @@ led0 = &led0; led1 = &led1; led2 = &led2; + pwm-led0 = &pwm_led0; }; leds { @@ -41,6 +42,13 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&tcc2 1>; + }; + }; }; &cpu0 { @@ -72,6 +80,19 @@ #size-cells = <0>; }; +&tcc2 { + status = "okay"; + compatible = "atmel,sam0-tcc-pwm"; + /* Gives a maximum period of 1.4 s */ + prescaler = <1024>; + + #pwm-cells = <1>; +}; + +&dac0 { + status = "okay"; +}; + &flash0 { partitions { compatible = "fixed-partitions"; diff --git a/boards/arm/arduino_zero/arduino_zero.yaml b/boards/arm/arduino_zero/arduino_zero.yaml index ac6b01622e8324..813c0300cf1e02 100644 --- a/boards/arm/arduino_zero/arduino_zero.yaml +++ b/boards/arm/arduino_zero/arduino_zero.yaml @@ -8,3 +8,16 @@ toolchain: - zephyr - gnuarmemb - xtools +supported: + - adc + - counter + - dac + - dma + - gpio + - hwinfo + - pinmux + - pwm + - spi + - uart + - usb_device + - watchdog diff --git a/boards/arm/arduino_zero/arduino_zero_defconfig b/boards/arm/arduino_zero/arduino_zero_defconfig index c1a9ba2e7c0339..34e70675704502 100644 --- a/boards/arm/arduino_zero/arduino_zero_defconfig +++ b/boards/arm/arduino_zero/arduino_zero_defconfig @@ -3,22 +3,12 @@ CONFIG_SOC_SERIES_SAMD21=y CONFIG_SOC_PART_NUMBER_SAMD21G18A=y CONFIG_BOARD_ARDUINO_ZERO=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_UART_SAM0=y CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_GPIO=y -CONFIG_GPIO_SAM0=y -CONFIG_WATCHDOG=y -CONFIG_WDT_SAM0=y +CONFIG_SERIAL=y +CONFIG_PINMUX=y CONFIG_SOC_ATMEL_SAMD_XOSC32K=y CONFIG_SOC_ATMEL_SAMD_XOSC32K_AS_MAIN=y -CONFIG_SPI=y -CONFIG_SPI_SAM0=y -CONFIG_SPI_4=y -CONFIG_PINMUX=y -CONFIG_PINMUX_SAM0=y -CONFIG_USB=y -CONFIG_USB_DC_SAM0=y diff --git a/boards/arm/arduino_zero/doc/index.rst b/boards/arm/arduino_zero/doc/index.rst index d41f1b4df1cf8a..1952c3fd28aca7 100644 --- a/boards/arm/arduino_zero/doc/index.rst +++ b/boards/arm/arduino_zero/doc/index.rst @@ -45,12 +45,16 @@ features: +-----------+------------+------------------------------------------+ | GPIO | on-chip | I/O ports | +-----------+------------+------------------------------------------+ +| PWM | on-chip | Pulse Width Modulation | ++-----------+------------+------------------------------------------+ | USART | on-chip | Serial ports | +-----------+------------+------------------------------------------+ | SPI | on-chip | Serial Peripheral Interface ports | +-----------+------------+------------------------------------------+ | USB | on-chip | USB device | +-----------+------------+------------------------------------------+ +| DAC | on-chip | Digital to analogue converter | ++-----------+------------+------------------------------------------+ Other hardware features are not currently supported by Zephyr. @@ -78,6 +82,13 @@ The SAMD21 MCU has 6 SERCOM based USARTs. One of the USARTs (SERCOM5) is connected to the onboard Atmel Embedded Debugger (EDBG). SERCOM0 is available on the D0/D1 pins. +PWM +=== + +The SAMD21 MCU has 3 TCC based PWM units with up to 4 outputs each and a period +of 24 bits or 16 bits. If :code:`CONFIG_PWM_SAM0_TCC` is enabled then LED0 is +driven by TCC2 instead of by GPIO. + SPI Port ======== @@ -92,6 +103,12 @@ with a host PC. See the :ref:`usb-samples` sample applications for more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual serial port that echos characters back to the host PC. +DAC +=== + +The SAMD21 MCU has a single channel DAC with 10 bits of resolution. On the +Arduino Zero, the DAC is available on pin A0. + Programming and Debugging ************************* diff --git a/boards/arm/arduino_zero/pinmux.c b/boards/arm/arduino_zero/pinmux.c index fea501ab4dd24a..15f84e18393ddb 100644 --- a/boards/arm/arduino_zero/pinmux.c +++ b/boards/arm/arduino_zero/pinmux.c @@ -8,10 +8,10 @@ #include #include -static int board_pinmux_init(struct device *dev) +static int board_pinmux_init(const struct device *dev) { - struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); - struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); + const struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + const struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); ARG_UNUSED(dev); @@ -63,12 +63,22 @@ static int board_pinmux_init(struct device *dev) #warning Pin mapping may not be configured #endif +#if ATMEL_SAM0_DT_TCC_CHECK(2, atmel_sam0_tcc_pwm) && \ + defined(CONFIG_PWM_SAM0_TCC) + /* LED0 on PA17/TCC2/WO[1] */ + pinmux_pin_set(muxa, 17, PINMUX_FUNC_E); +#endif + #ifdef CONFIG_USB_DC_SAM0 /* USB DP on PA25, USB DM on PA24 */ pinmux_pin_set(muxa, 25, PINMUX_FUNC_G); pinmux_pin_set(muxa, 24, PINMUX_FUNC_G); #endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(dac0), okay) && defined(CONFIG_DAC_SAM0) + /* DAC on PA02 */ + pinmux_pin_set(muxa, 2, PINMUX_FUNC_B); +#endif return 0; } diff --git a/boards/arm/arty/CMakeLists.txt b/boards/arm/arty/CMakeLists.txt new file mode 100644 index 00000000000000..1c060b9bbac2f1 --- /dev/null +++ b/boards/arm/arty/CMakeLists.txt @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(board.c) + +if((CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1) AND (CONFIG_BUILD_OUTPUT_BIN)) + # Generate zephyr.mem verilog memory hex dump file for initialising ITCM in + # Xilinx Vivado. + # + # This ought to be done using the objcopy verilog bfd, but it contains a bug + # affecting endianness: https://sourceware.org/bugzilla/show_bug.cgi?id=25202 + # + # Instead we use bin2hex from the SiFive elf2hex package, if available. + # https://github.com/sifive/elf2hex + find_program(BIN2HEX ${CROSS_COMPILE_TARGET}-bin2hex) + + if(NOT ${BIN2HEX} STREQUAL BIN2HEX-NOTFOUND) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${BIN2HEX} + ARGS --bit-width 32 + ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin + ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.mem + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + message(STATUS "Verilog memory hex dump will be written to: ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.mem") + else() + message(STATUS "The bin2hex (${CROSS_COMPILE_TARGET}-bin2hex) utility was not found, verilog memory hex dump file cannot be generated") + endif() +endif() diff --git a/boards/arm/arty/Kconfig b/boards/arm/arty/Kconfig new file mode 100644 index 00000000000000..78b1d148b51538 --- /dev/null +++ b/boards/arm/arty/Kconfig @@ -0,0 +1,13 @@ +# Digilent Arty board configuration + +# Copyright (c) 2020 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_INIT_PRIORITY + int "Board initialization priority" + default 50 + depends on BOARD_ARTY_A7_ARM_DESIGNSTART_M1 || BOARD_ARTY_A7_ARM_DESIGNSTART_M3 + depends on "$(dt_nodelabel_enabled,daplink_qspi_mux)" + help + Board initialization priority. The board initialization must take + place after the GPIO driver is initialized. diff --git a/boards/arm/arty/Kconfig.board b/boards/arm/arty/Kconfig.board new file mode 100644 index 00000000000000..17a6e659748897 --- /dev/null +++ b/boards/arm/arty/Kconfig.board @@ -0,0 +1,12 @@ +# Digilent Arty board configuration + +# Copyright (c) 2020 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ARTY_A7_ARM_DESIGNSTART_M1 + bool "Digilent Arty A7 ARM DesignStart Cortex-M1" + depends on SOC_SERIES_ARM_DESIGNSTART + +config BOARD_ARTY_A7_ARM_DESIGNSTART_M3 + bool "Digilent Arty A7 ARM DesignStart Cortex-M3" + depends on SOC_SERIES_ARM_DESIGNSTART diff --git a/boards/arm/arty/Kconfig.defconfig b/boards/arm/arty/Kconfig.defconfig new file mode 100644 index 00000000000000..da33497682833c --- /dev/null +++ b/boards/arm/arty/Kconfig.defconfig @@ -0,0 +1,55 @@ +# Digilent Arty board configuration + +# Copyright (c) 2020 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ARTY_A7_ARM_DESIGNSTART_M1 || BOARD_ARTY_A7_ARM_DESIGNSTART_M3 + +config BOARD + default "arty_a7_arm_designstart_m1" if BOARD_ARTY_A7_ARM_DESIGNSTART_M1 + default "arty_a7_arm_designstart_m3" if BOARD_ARTY_A7_ARM_DESIGNSTART_M3 + +config CPU_CORTEX_M_HAS_SYSTICK + default y + +config CPU_HAS_ARM_MPU + default y if BOARD_ARTY_A7_ARM_DESIGNSTART_M3 + +config NUM_IRQS + default 7 + +if SERIAL + +config UART_XLNX_UARTLITE + default y + +endif # SERIAL + +config GPIO + default y if "$(dt_nodelabel_enabled,daplink_qspi_mux)" + +if GPIO + +config GPIO_XLNX_AXI + default y + +endif # GPIO + +if SPI + +config SPI_XLNX_AXI_QUADSPI + default y + +endif # SPI + +if FLASH + +config SPI + default y + +config SPI_NOR + default y if SPI_XLNX_AXI_QUADSPI + +endif # FLASH + +endif # BOARD_ARTY_A7_ARM_DESIGNSTART_M1 || BOARD_ARTY_A7_ARM_DESIGNSTART_M3 diff --git a/boards/arm/arty/arty_a7_arm_designstart_m1.dts b/boards/arm/arty/arty_a7_arm_designstart_m1.dts new file mode 100644 index 00000000000000..d198b2c758aeed --- /dev/null +++ b/boards/arm/arty/arty_a7_arm_designstart_m1.dts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "arty_a7_arm_designstart.dtsi" + +/ { + model = "Digilent Arty A7 ARM DesignStart Cortex-M1"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m1"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + }; + }; + + soc { + itcm: memory@0 { + compatible = "arm,itcm"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + dtcm: memory@20000000 { + compatible = "arm,dtcm"; + reg = <0x20000000 DT_SIZE_K(32)>; + }; + + bram0: memory@60000000 { + compatible = "mmio-sram"; + reg = <0x60000000 DT_SIZE_K(64)>; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <2>; +}; diff --git a/boards/arm/arty/arty_a7_arm_designstart_m1.yaml b/boards/arm/arty/arty_a7_arm_designstart_m1.yaml new file mode 100644 index 00000000000000..22068def69007e --- /dev/null +++ b/boards/arm/arty/arty_a7_arm_designstart_m1.yaml @@ -0,0 +1,14 @@ +identifier: arty_a7_arm_designstart_m1 +name: Digilent Arty A7 ARM DesignStart Cortex-M1 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 32 +flash: 64 +supported: + - flash + - spi + - gpio diff --git a/boards/arm/arty/arty_a7_arm_designstart_m1_defconfig b/boards/arm/arty/arty_a7_arm_designstart_m1_defconfig new file mode 100644 index 00000000000000..ebb6fa895bf74b --- /dev/null +++ b/boards/arm/arty/arty_a7_arm_designstart_m1_defconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_SOC_SERIES_ARM_DESIGNSTART=y +CONFIG_SOC_ARM_DESIGNSTART_FPGA_CORTEX_M1=y +CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=100000000 + +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/arty/arty_a7_arm_designstart_m3.dts b/boards/arm/arty/arty_a7_arm_designstart_m3.dts new file mode 100644 index 00000000000000..cd6ec1c6b20b7f --- /dev/null +++ b/boards/arm/arty/arty_a7_arm_designstart_m3.dts @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "arty_a7_arm_designstart.dtsi" + +/ { + model = "Digilent Arty A7 ARM DesignStart Cortex-M3"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m3"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv7m-mpu"; + reg = <0xe000ed90 0x40>; + arm,num-mpu-regions = <8>; + }; + }; + }; + + soc { + itcm: memory@0 { + compatible = "arm,itcm"; + reg = <0x00000000 DT_SIZE_K(32)>; + }; + + dtcm: memory@20000000 { + compatible = "arm,dtcm"; + reg = <0x20000000 DT_SIZE_K(32)>; + }; + + bram0: memory@60000000 { + compatible = "mmio-sram"; + reg = <0x60000000 DT_SIZE_K(8)>; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/boards/arm/arty/arty_a7_arm_designstart_m3.yaml b/boards/arm/arty/arty_a7_arm_designstart_m3.yaml new file mode 100644 index 00000000000000..3ea0ebbe1b09e1 --- /dev/null +++ b/boards/arm/arty/arty_a7_arm_designstart_m3.yaml @@ -0,0 +1,14 @@ +identifier: arty_a7_arm_designstart_m3 +name: Digilent Arty A7 ARM DesignStart Cortex-M3 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 32 +flash: 32 +supported: + - flash + - spi + - gpio diff --git a/boards/arm/arty/arty_a7_arm_designstart_m3_defconfig b/boards/arm/arty/arty_a7_arm_designstart_m3_defconfig new file mode 100644 index 00000000000000..af629dc028e455 --- /dev/null +++ b/boards/arm/arty/arty_a7_arm_designstart_m3_defconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_SOC_SERIES_ARM_DESIGNSTART=y +CONFIG_SOC_ARM_DESIGNSTART_FPGA_CORTEX_M3=y +CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M3=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=50000000 +CONFIG_ARM_MPU=y + +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/arty/board.c b/boards/arm/arty/board.c new file mode 100644 index 00000000000000..04a46800483c90 --- /dev/null +++ b/boards/arm/arty/board.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(board, CONFIG_LOG_DEFAULT_LEVEL); + +#include "board.h" + +#define DAPLINK_QSPI_MUX_NODE DT_NODELABEL(daplink_qspi_mux) + +#if DT_NODE_HAS_STATUS(DAPLINK_QSPI_MUX_NODE, okay) +int board_daplink_qspi_mux_select(enum board_daplink_qspi_mux_mode mode) +{ + const struct device *gpio; + gpio_flags_t flags; + int err; + + switch (mode) { + case BOARD_DAPLINK_QSPI_MUX_MODE_XIP: + flags = GPIO_OUTPUT_LOW; + break; + case BOARD_DAPLINK_QSPI_MUX_MODE_NORMAL: + flags = GPIO_OUTPUT_HIGH; + break; + default: + __ASSERT(0, "invalid mode"); + return -EINVAL; + }; + + gpio = device_get_binding(DT_GPIO_LABEL(DAPLINK_QSPI_MUX_NODE, + mux_gpios)); + if (!gpio) { + LOG_ERR("DAPLink QSPI MUX GPIO device '%s' not found", + DT_GPIO_LABEL(DAPLINK_QSPI_MUX_NODE, mux_gpios)); + return -EINVAL; + } + + err = gpio_config(gpio, DT_GPIO_PIN(DAPLINK_QSPI_MUX_NODE, mux_gpios), + DT_GPIO_FLAGS(DAPLINK_QSPI_MUX_NODE, mux_gpios) | + flags); + if (err) { + LOG_ERR("failed to configure DAPLink QSPI MUX GPIO (err %d)", + err); + return err; + } + + return 0; +} + +bool board_daplink_is_fitted(void) +{ + /* + * The DAPLINK_fitted_n signal is routed to an IRQ line. It is used as a + * level-detect non-interrupt signal to determine if the DAPLink shield + * is fitted. + */ + return !NVIC_GetPendingIRQ(DT_IRQN(DAPLINK_QSPI_MUX_NODE)); +} + +static int board_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + /* + * Automatically select normal mode unless the DAPLink shield is fitted + * in which case the CPU will have the off-board QSPI NOR flash + * memory-mapped at 0x0. + */ + if (!board_daplink_is_fitted()) { + board_daplink_qspi_mux_select( + BOARD_DAPLINK_QSPI_MUX_MODE_NORMAL); + } + + return 0; +} + +SYS_INIT(board_init, POST_KERNEL, CONFIG_BOARD_INIT_PRIORITY); +#endif /* DT_NODE_HAS_STATUS(DAPLINK_QSPI_MUX_NODE, okay) */ diff --git a/boards/arm/arty/board.cmake b/boards/arm/arty/board.cmake new file mode 100644 index 00000000000000..529c142aa287db --- /dev/null +++ b/boards/arm/arty/board.cmake @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1) + board_runner_args(openocd "--use-elf" "--config=${BOARD_DIR}/support/openocd_arty_a7_arm_designstart_m1.cfg") + board_runner_args(jlink "--device=Cortex-M1" "--reset-after-load") + + include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +elseif(CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M3) + board_runner_args(openocd "--use-elf" "--config=${BOARD_DIR}/support/openocd_arty_a7_arm_designstart_m3.cfg") + board_runner_args(jlink "--device=Cortex-M3" "--reset-after-load") + + include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +endif() diff --git a/boards/arm/arty/board.h b/boards/arm/arty/board.h new file mode 100644 index 00000000000000..3cee697ec4d1fd --- /dev/null +++ b/boards/arm/arty/board.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INC_BOARD_H +#define __INC_BOARD_H + +enum board_daplink_qspi_mux_mode { + /* eXecute-In-Place mode */ + BOARD_DAPLINK_QSPI_MUX_MODE_XIP, + /* Normal mode */ + BOARD_DAPLINK_QSPI_MUX_MODE_NORMAL, +}; + +/** + * @brief Select the mode of the DAPlink QSPI multiplexer. + * + * Note: The multiplexer mode must not be changed while executing code from the + * off-board QSPI flash in XIP mode. + * + * @param mode The multiplexer mode to be selected. + * + * @retval 0 If successful, negative errno otherwise. + */ +int board_daplink_qspi_mux_select(enum board_daplink_qspi_mux_mode mode); + +/** + * @brief Determine if the DAPlink shield is fitted. + * + * Determine if the DAPlink shield is fitted based on the state of the + * DAPLINK_fitted_n signal. + * + * @retval true If the DAPlink shield is fitted. + * @retval false If the DAPlink shield is not fitted. + */ +bool board_daplink_is_fitted(void); + +#endif /* __INC_BOARD_H */ diff --git a/boards/arm/arty/doc/arty_a7-35.png b/boards/arm/arty/doc/arty_a7-35.png new file mode 100644 index 00000000000000..99d11a76774b28 Binary files /dev/null and b/boards/arm/arty/doc/arty_a7-35.png differ diff --git a/boards/arm/arty/doc/index.rst b/boards/arm/arty/doc/index.rst new file mode 100644 index 00000000000000..cd893197f5fc65 --- /dev/null +++ b/boards/arm/arty/doc/index.rst @@ -0,0 +1,229 @@ +.. _arty: + +Digilent Arty +############# + +Overview +******** + +The `Digilent Arty`_ is a line of FPGA-based development boards aimed for makers +and hobbyists. The Arty is available in several configurations, each with a +different Xilinx FPGA (Spartan-7, Artix-7, or Zynq-7000 series). + +Each board is equipped with on-board JTAG for FPGA programming and debugging, +LEDs, switches, buttons, DDR3 RAM, and QSPI flash for storing the FPGA +bitstream. + +.. figure:: ./arty_a7-35.png + :width: 500px + :align: center + :alt: Digilent Arty A7-35 + + Digilent Arty A7-35 (Credit: Digilent Inc) + +The Spartan-7 and Artix-7 based Arty board do not contain a CPU, but require a +so-called soft processor to be instantiated within the FPGA in order to run +Zephyr. The Zynq-7000 based Arty boards are not yet supported by Zephyr. + +ARM Cortex-M1/M3 DesignStart FPGA +********************************* + +One way of instantiating soft processors on the Arty is using the `ARM +DesignStart FPGA`_ Xilinx edition reference designs from ARM. Zephyr supports +both the Cortex-M1 and the Cortex-M3 reference designs. The Cortex-M1 design +targets either the Spartan-7 or Artix-7 based Arty boards, whereas the Cortex-M3 +design only targets the Artix-7 based boards. Zephyr only supports the Artix-7 +targetted designs for now. + +For more information about the ARM Cortex-M1/M3 DesignStart FPGA, see the +following websites: + +- `Technical Resources for DesignStart FPGA`_ +- `Technical Resources for DesignStart FPGA on Xilinx`_ +- `ARM DesignStart FPGA Xilinx FAQs`_ + +Supported Features +================== + +The ``arty_a7_arm_designstart_m1`` board configuration supports the following +hardware features of the Cortex-M1 reference design: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio, non-interrupt | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| QSPI | on-chip | QSPI flash | ++-----------+------------+-------------------------------------+ + +The default configuration for the Cortex-M1 can be found in the defconfig file: +:file:`boards/arm/arty/arty_a7_arm_designstart_m1_defconfig`. + +In addition to the above, the ``arty_a7_arm_designstart_m3`` board configuration +supports the following hardware features of the Cortex-M3 reference design: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | Memory Protection Unit | ++-----------+------------+-------------------------------------+ + +The default configuration for the Cortex-M3 can be found in the defconfig file: +:file:`boards/arm/arty/arty_a7_arm_designstart_m3_defconfig`. + +Other hardware features are not currently supported by the port. + +System Clock +============ + +The Cortex-M1 reference design is configured to use the 100 MHz external +oscillator on the board as CPU system clock whereas the Cortex-M3 reference +design is configured for 50MHz CPU system clock. + +Serial Port +=========== + +The reference design contains one Xilinx UART Lite. This UART is configured as +console and is accessible through the on-board JTAG adapter via USB connector +``J10``. + +Connecting the Debug Probes +=========================== + +Two different debug probes are needed in order to program the board; the +on-board Digilent JTAG connected to the FPGA, and an external Serial Wire Debug +(SWD) capable debug probe connected to the ARM Cortex-M1 CPU. + +The on-board JTAG is used for configuring and debugging the Xilinx FPGA +itself. It is available on USB connector ``J10``. + +The external SWD debug probe can be connected to connector ``J4`` (``nSRST`` on +``IO39``, ``SWDIO`` on ``IO40``, and ``SWCLK`` on ``IO41``). Another option is +to use the dedicated :ref:`v2c_daplink_shield`. + +Programming and Debugging +************************* + +First, configure the FPGA with the selected reference design FPGA bitstream +using Xilinx Vivado as described in the ARM Cortex-M1/Cortex-M3 DesignStart FPGA +Xilinx edition user guide (available as part of the reference design download +from `Technical Resources for DesignStart FPGA on Xilinx`_). + +Another option for configuring the FPGA with the reference design bitstream is +to use the :ref:`openocd-debug-host-tools`: + +.. code-block:: console + + openocd -f board/arty_s7.cfg -c "init;\ + pld load 0 m1_for_arty_a7_reference.bit;\ + shutdown" + +or: + +.. code-block:: console + + openocd -f board/arty_s7.cfg -c "init;\ + pld load 0 m3_for_arty_a7_reference.bit;\ + shutdown" + +.. note:: + + The pre-built FPGA bitstream only works for Arty boards equipped with an + Artix-35T FPGA. For other Arty variants (e.g. the Arty A7-100) the bitstream + must be rebuilt. + +Next, build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Configuring a Console +===================== + +The UART console is available via the on-board JTAG on USB connector +``J10``. The on-board JTAG will enumerate as two USB serial ports. The UART is +typically available on the second serial port. + +Use the following settings with your serial terminal of choice (minicom, putty, +etc.): + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Flashing +======== + +Here is an example for building and flashing the :ref:`hello_world` application +for the Cortex-M1 reference design: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: arty_a7_arm_designstart_m1 + :goals: flash + +After flashing, you should see message similar to the following in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v2.3.99 *** + Hello World! arty_a7_arm_designstart_m1 + +The same procedure can be used for the Cortex-M3 reference design. + +Note, however, that the application was not persisted in flash memory by the +above steps. It was merely written to internal block RAM in the FPGA. It will +revert to the application stored in the block RAM within the FPGA bitstream +the next time the FPGA is configured. + +The steps to persist the application within the FPGA bitstream are covered by +the ARM Cortex-M1/M3 DesignStart FPGA Xilinx edition user guide. If the +:option:`CONFIG_BUILD_OUTPUT_BIN` is enabled and the `SiFive elf2hex`_ package +is available, the build system will automatically generate a Verilog memory hex +dump :file:`zephyr.mem` file suitable for initialising the block RAM using +`Xilinx Vivado`_. + +Debugging +========= + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: arty_a7_arm_designstart_m1 + :goals: debug + +Step through the application in your debugger, and you should see a message +similar to the following in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v2.3.99 *** + Hello World! arty_a7_arm_designstart_m1 + +.. _Digilent Arty: + https://store.digilentinc.com/arty + +.. _ARM DesignStart FPGA: + https://www.arm.com/resources/designstart/designstart-fpga + +.. _Technical Resources for DesignStart FPGA: + https://developer.arm.com/ip-products/designstart/fpga + +.. _Technical Resources for DesignStart FPGA on Xilinx: + https://developer.arm.com/ip-products/designstart/fpga/fpga-xilinx + +.. _ARM DesignStart FPGA Xilinx FAQs: + https://developer.arm.com/ip-products/designstart/fpga/fpga-xilinx-faqs + +.. _SiFive elf2hex: + https://github.com/sifive/elf2hex + +.. _Xilinx Vivado: + https://www.xilinx.com/products/design-tools/vivado.html diff --git a/boards/arm/arty/dts/arty_a7_arm_designstart.dtsi b/boards/arm/arty/dts/arty_a7_arm_designstart.dtsi new file mode 100644 index 00000000000000..a3385e41c6828d --- /dev/null +++ b/boards/arm/arty/dts/arty_a7_arm_designstart.dtsi @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + chosen { + zephyr,console = &uartlite0; + zephyr,shell-uart = &uartlite0; + zephyr,flash = &itcm; + /* Use DTCM as SRAM by default */ + zephyr,sram = &dtcm; + }; + + aliases { + led0 = &led_ld4; + led1 = &led_ld5; + led2 = &led_ld6; + led3 = &led_ld7; + sw0 = &sw0; + sw1 = &sw1; + sw2 = &sw2; + sw3 = &sw3; + }; + + leds { + compatible = "gpio-leds"; + led_ld0_red: led_ld0_red { + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + label = "LED LD0 RED"; + }; + led_ld0_green: led_ld0_green { + gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + label = "LED LD0 GREEN"; + }; + led_ld0_blue: led_ld0_blue { + gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>; + label = "LED LD0 BLUE"; + }; + + led_ld1_red: led_ld1_red { + gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; + label = "LED LD1 RED"; + }; + led_ld1_green: led_ld1_green { + gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + label = "LED LD1 GREEN"; + }; + led_ld1_blue: led_ld1_blue { + gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; + label = "LED LD1 BLUE"; + }; + + led_ld2_red: led_ld2_red { + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + label = "LED LD2 RED"; + }; + led_ld2_green: led_ld2_green { + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + label = "LED LD2 GREEN"; + }; + led_ld2_blue: led_ld2_blue { + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + label = "LED LD2 BLUE"; + }; + + led_ld3_red: led_ld3_red { + gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; + label = "LED LD3 RED"; + }; + led_ld3_green: led_ld3_green { + gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + label = "LED LD3 GREEN"; + }; + led_ld3_blue: led_ld3_blue { + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + label = "LED LD3 BLUE"; + }; + + led_ld4: led_ld4 { + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + label = "LED LD4"; + }; + led_ld5: led_ld5 { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + label = "LED LD5"; + }; + led_ld6: led_ld6 { + gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + label = "LED LD6"; + }; + led_ld7: led_ld7 { + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + label = "LED LD7"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + sw0: sw0 { + gpios = <&gpio0_2 0 GPIO_ACTIVE_HIGH>; + label = "SW0"; + }; + sw1: sw1 { + gpios = <&gpio0_2 1 GPIO_ACTIVE_HIGH>; + label = "SW1"; + }; + sw2: sw2 { + gpios = <&gpio0_2 2 GPIO_ACTIVE_HIGH>; + label = "SW2"; + }; + sw3: sw3 { + gpios = <&gpio0_2 3 GPIO_ACTIVE_HIGH>; + label = "SW3"; + }; + btn0: btn0 { + gpios = <&gpio1_2 0 GPIO_ACTIVE_HIGH>; + label = "BTN0"; + }; + btn1: btn1 { + gpios = <&gpio1_2 1 GPIO_ACTIVE_HIGH>; + label = "BTN1"; + }; + btn2: btn2 { + gpios = <&gpio1_2 2 GPIO_ACTIVE_HIGH>; + label = "BTN2"; + }; + btn3: btn3 { + gpios = <&gpio1_2 3 GPIO_ACTIVE_HIGH>; + label = "BTN3"; + }; + }; + + daplink_qspi_mux: daplink_qspi_mux { + compatible = "arm,daplink-qspi-mux"; + status = "disabled"; + interrupt-parent = <&nvic>; + interrupts = <7 0>; + mux-gpios = <&daplink_gpio0 0 GPIO_ACTIVE_HIGH>; + }; + + soc { + daplink_gpio0: gpio@40010000 { + compatible = "xlnx,xps-gpio-1.00.a"; + status = "disabled"; + reg = <0x40010000 0x10000>; + label = "DAPLINK_GPIO_0"; + gpio-controller; + #gpio-cells = <2>; + + xlnx,all-inputs = <0x0>; + xlnx,all-outputs = <0x0>; + xlnx,dout-default = <0x0>; + xlnx,gpio-width = <0x20>; + xlnx,is-dual = <0x0>; + xlnx,tri-default = <0xffffffff>; + }; + + daplink_quad_spi0: spi@40020000 { + compatible = "xlnx,xps-spi-2.00.a"; + status = "disabled"; + reg = <0x40020000 0x10000>; + interrupts = <4 0>; + #address-cells = <1>; + #size-cells = <0>; + label = "DAPLINK_QUAD_SPI_0"; + + xlnx,num-ss-bits = <0x1>; + xlnx,num-transfer-bits = <0x8>; + }; + + daplink_single_spi0: spi@40030000 { + compatible = "xlnx,xps-spi-2.00.a"; + status = "disabled"; + reg = <0x40030000 0x10000>; + interrupts = <5 0>; + label = "DAPLINK_SINGLE_SPI_0"; + #address-cells = <1>; + #size-cells = <0>; + + xlnx,num-ss-bits = <0x1>; + xlnx,num-transfer-bits = <0x8>; + }; + + uartlite0: uartlite@40100000 { + compatible = "xlnx,xps-uartlite-1.00.a"; + interrupts = <0 0>; + reg = <0x40100000 0x10000>; + label = "UART_0"; + }; + + gpio0: gpio@40110000 { + compatible = "xlnx,xps-gpio-1.00.a"; + interrupts = <1 0>; + reg = <0x40110000 0x10000>; + label = "GPIO_0"; + gpio-controller; + #gpio-cells = <2>; + + xlnx,all-inputs = <0x0>; + xlnx,all-inputs-2 = <0x1>; + xlnx,all-outputs = <0x0>; + xlnx,all-outputs-2 = <0x0>; + xlnx,dout-default = <0x0>; + xlnx,dout-default-2 = <0x0>; + xlnx,gpio-width = <0x4>; + xlnx,gpio2-width = <0x4>; + xlnx,is-dual = <0x1>; + xlnx,tri-default = <0xffffffff>; + xlnx,tri-default-2 = <0xffffffff>; + + gpio0_2: gpio2 { + compatible = "xlnx,xps-gpio-1.00.a-gpio2"; + label = "GPIO_0_2"; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + gpio1: gpio@40120000 { + compatible = "xlnx,xps-gpio-1.00.a"; + interrupts = <2 0>; + reg = <0x40120000 0x10000>; + label = "GPIO_1"; + gpio-controller; + #gpio-cells = <2>; + + xlnx,all-inputs = <0x0>; + xlnx,all-inputs-2 = <0x1>; + xlnx,all-outputs = <0x0>; + xlnx,all-outputs-2 = <0x0>; + xlnx,dout-default = <0x0>; + xlnx,dout-default-2 = <0x0>; + xlnx,gpio-width = <0xc>; + xlnx,gpio2-width = <0x4>; + xlnx,is-dual = <0x1>; + xlnx,tri-default = <0xffffffff>; + xlnx,tri-default-2 = <0xffffffff>; + + gpio1_2: gpio2 { + compatible = "xlnx,xps-gpio-1.00.a-gpio2"; + label = "GPIO_1_2"; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + quad_spi0: spi@40130000 { + compatible = "xlnx,xps-spi-2.00.a"; + reg = <0x40130000 0x10000>; + interrupts = <3 0>; + #address-cells = <1>; + #size-cells = <0>; + label = "QUAD_SPI_0"; + + xlnx,num-ss-bits = <0x1>; + xlnx,num-transfer-bits = <0x8>; + + flash0: flash@0 { + compatible = "micron,n25q128a","jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <108000000>; + size = ; + jedec-id = [20 ba 18]; + label = "FLASH_0"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + fpga_bitstream_partition: partition@0 { + label = "fpga_bitstream"; + /* From Xilinx 7 Series FPGA User Guide (UG470) + * Table 1-1: Bitstream Length + * Bits Bytes (sector multiple) + * A35T: 17,536,096 0x218000 + * A100T: 30,606,304 0x3a8000 + */ + reg = <0x00000000 0x218000>; + }; + }; + }; + }; + }; +}; diff --git a/boards/arm/arty/dts/bindings/arm,daplink-qspi-mux.yaml b/boards/arm/arty/dts/bindings/arm,daplink-qspi-mux.yaml new file mode 100644 index 00000000000000..99392bf8829782 --- /dev/null +++ b/boards/arm/arty/dts/bindings/arm,daplink-qspi-mux.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2020 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +description: ARM DesignStart FPGA DAPLink QSPI bus multiplexer + +compatible: "arm,daplink-qspi-mux" + +include: base.yaml + +properties: + interrupts: + required: true + description: | + IRQ line connected to the level-detect non-interrupt DAPLink shield + fitted signal + + mux-gpios: + type: phandle-array + required: true + description: | + GPIO for controlling the DAPLink QSPI bus multiplexer diff --git a/boards/arm/arty/support/openocd_arty_a7_arm_designstart.cfg b/boards/arm/arty/support/openocd_arty_a7_arm_designstart.cfg new file mode 100644 index 00000000000000..b2d10aa00f7f59 --- /dev/null +++ b/boards/arm/arty/support/openocd_arty_a7_arm_designstart.cfg @@ -0,0 +1,10 @@ +swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +if {![using_hla]} { + cortex_m reset_config sysresetreq +} diff --git a/boards/arm/arty/support/openocd_arty_a7_arm_designstart_m1.cfg b/boards/arm/arty/support/openocd_arty_a7_arm_designstart_m1.cfg new file mode 100644 index 00000000000000..cf9f88347ecbbf --- /dev/null +++ b/boards/arm/arty/support/openocd_arty_a7_arm_designstart_m1.cfg @@ -0,0 +1,11 @@ +source [find interface/cmsis-dap.cfg] +source [find target/swj-dp.tcl] + +adapter_khz 5000 + +set _CHIPNAME cortex_m1 +set _ENDIAN little +set _WORKAREASIZE 0x4000 +set _CPUTAPID 0x411CC210 + +source [find openocd_arty_a7_arm_designstart.cfg] diff --git a/boards/arm/arty/support/openocd_arty_a7_arm_designstart_m3.cfg b/boards/arm/arty/support/openocd_arty_a7_arm_designstart_m3.cfg new file mode 100644 index 00000000000000..17dbbb997ffd46 --- /dev/null +++ b/boards/arm/arty/support/openocd_arty_a7_arm_designstart_m3.cfg @@ -0,0 +1,11 @@ +source [find interface/cmsis-dap.cfg] +source [find target/swj-dp.tcl] + +adapter_khz 5000 + +set _CHIPNAME cortex_m3 +set _ENDIAN little +set _WORKAREASIZE 0x4000 +set _CPUTAPID 0x412FC231 + +source [find openocd_arty_a7_arm_designstart.cfg] diff --git a/boards/arm/atsamd20_xpro/atsamd20_xpro.dts b/boards/arm/atsamd20_xpro/atsamd20_xpro.dts index 59a3a039b3f686..8d9042554f17f3 100644 --- a/boards/arm/atsamd20_xpro/atsamd20_xpro.dts +++ b/boards/arm/atsamd20_xpro/atsamd20_xpro.dts @@ -52,7 +52,7 @@ dopo = <1>; #address-cells = <1>; #size-cells = <0>; - cs-gpios = <&porta 5 0>; + cs-gpios = <&porta 5 GPIO_ACTIVE_LOW>; }; &sercom2 { diff --git a/boards/arm/atsamd20_xpro/atsamd20_xpro_defconfig b/boards/arm/atsamd20_xpro/atsamd20_xpro_defconfig index d80f5323368e72..26b29a110b8459 100644 --- a/boards/arm/atsamd20_xpro/atsamd20_xpro_defconfig +++ b/boards/arm/atsamd20_xpro/atsamd20_xpro_defconfig @@ -3,6 +3,7 @@ CONFIG_SOC_SERIES_SAMD20=y CONFIG_SOC_PART_NUMBER_SAMD20J18=y CONFIG_BOARD_ATSAMD20_XPRO=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y diff --git a/boards/arm/atsamd20_xpro/pinmux.c b/boards/arm/atsamd20_xpro/pinmux.c index 0d5791419ca2aa..f7095ec6c8d5eb 100644 --- a/boards/arm/atsamd20_xpro/pinmux.c +++ b/boards/arm/atsamd20_xpro/pinmux.c @@ -8,10 +8,10 @@ #include #include -static int board_pinmux_init(struct device *dev) +static int board_pinmux_init(const struct device *dev) { - struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); - struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); + const struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + const struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); ARG_UNUSED(dev); diff --git a/boards/arm/atsamd21_xpro/atsamd21_xpro.dts b/boards/arm/atsamd21_xpro/atsamd21_xpro.dts index fe10bb8d885b31..2e8e38f6135d8a 100644 --- a/boards/arm/atsamd21_xpro/atsamd21_xpro.dts +++ b/boards/arm/atsamd21_xpro/atsamd21_xpro.dts @@ -21,6 +21,7 @@ /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; + pwm-led0 = &pwm_led0; sw0 = &user_button; i2c-0 = &sercom2; }; @@ -33,6 +34,13 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&tcc0 0>; + }; + }; + buttons { compatible = "gpio-keys"; user_button: button_0 { @@ -46,6 +54,14 @@ clock-frequency = <48000000>; }; +&tcc0 { + status = "okay"; + compatible = "atmel,sam0-tcc-pwm"; + /* Gives a maximum period of 1.4s */ + prescaler = <4>; + #pwm-cells = <1>; +}; + &sercom0 { status = "okay"; compatible = "atmel,sam0-uart"; diff --git a/boards/arm/atsamd21_xpro/atsamd21_xpro.yaml b/boards/arm/atsamd21_xpro/atsamd21_xpro.yaml index d18d270d5ab4f2..732fba0ccdad49 100644 --- a/boards/arm/atsamd21_xpro/atsamd21_xpro.yaml +++ b/boards/arm/atsamd21_xpro/atsamd21_xpro.yaml @@ -16,6 +16,7 @@ supported: - dma - gpio - i2c + - pwm - spi - usb_cdc - usb_device diff --git a/boards/arm/atsamd21_xpro/atsamd21_xpro_defconfig b/boards/arm/atsamd21_xpro/atsamd21_xpro_defconfig index ab30860ea9e47c..5692e3901d88af 100644 --- a/boards/arm/atsamd21_xpro/atsamd21_xpro_defconfig +++ b/boards/arm/atsamd21_xpro/atsamd21_xpro_defconfig @@ -3,6 +3,7 @@ CONFIG_SOC_SERIES_SAMD21=y CONFIG_SOC_PART_NUMBER_SAMD21J18A=y CONFIG_BOARD_ATSAMD21_XPRO=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y diff --git a/boards/arm/atsamd21_xpro/doc/index.rst b/boards/arm/atsamd21_xpro/doc/index.rst index 196b101924d80a..cfc056b0cc7756 100644 --- a/boards/arm/atsamd21_xpro/doc/index.rst +++ b/boards/arm/atsamd21_xpro/doc/index.rst @@ -47,6 +47,8 @@ features: +-----------+------------+------------------------------------------+ | GPIO | on-chip | I/O ports | +-----------+------------+------------------------------------------+ +| PWM | on-chip | Pulse Width Modulation | ++-----------+------------+------------------------------------------+ | USART | on-chip | Serial ports | +-----------+------------+------------------------------------------+ | I2C | on-chip | I2C ports | @@ -91,7 +93,7 @@ Default Zephyr Peripheral Mapping: - USB DP : PA25 - USB DM : PA24 - GPIO SPI CS : PB17 -- GPIO LED0 : PB30 +- GPIO/PWM LED0 : PB30 System Clock ============ @@ -109,6 +111,13 @@ this BSP. SERCOM3 is the default Zephyr console. - SERCOM1 115200 8n1 - SERCOM3 115200 8n1 connected to the onboard Atmel Embedded Debugger (EDBG) +PWM +=== + +The SAMD21 MCU has 3 TCC based PWM units with up to 4 outputs each and a period +of 24 bits or 16 bits. If :code:`CONFIG_PWM_SAM0_TCC` is enabled then LED0 is +driven by TCC0 instead of by GPIO. + SPI Port ======== diff --git a/boards/arm/atsamd21_xpro/pinmux.c b/boards/arm/atsamd21_xpro/pinmux.c index ecd37cf6a172ba..d34d34594eadc3 100644 --- a/boards/arm/atsamd21_xpro/pinmux.c +++ b/boards/arm/atsamd21_xpro/pinmux.c @@ -8,10 +8,10 @@ #include #include -static int board_pinmux_init(struct device *dev) +static int board_pinmux_init(const struct device *dev) { - struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); - struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); + const struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + const struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); ARG_UNUSED(dev); @@ -83,6 +83,11 @@ static int board_pinmux_init(struct device *dev) #warning Pin mapping may not be configured #endif +#if (ATMEL_SAM0_DT_TCC_CHECK(0, atmel_sam0_tcc_pwm) && CONFIG_PWM_SAM0_TCC) + /* TCC0 on WO0=PB30 */ + pinmux_pin_set(muxb, 30, PINMUX_FUNC_E); +#endif + #ifdef CONFIG_USB_DC_SAM0 /* USB DP on PA25, USB DM on PA24 */ pinmux_pin_set(muxa, 25, PINMUX_FUNC_G); diff --git a/boards/arm/atsame54_xpro/atsame54_xpro.dts b/boards/arm/atsame54_xpro/atsame54_xpro.dts index e666ec92a85aae..73a922f4076633 100644 --- a/boards/arm/atsame54_xpro/atsame54_xpro.dts +++ b/boards/arm/atsame54_xpro/atsame54_xpro.dts @@ -21,6 +21,7 @@ /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; + pwm-led0 = &pwm_led0; sw0 = &button0; i2c-0 = &sercom7; }; @@ -33,6 +34,13 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&tcc0 2>; + }; + }; + buttons { compatible = "gpio-keys"; button0: button_0 { @@ -42,6 +50,14 @@ }; }; +&tcc0 { + status = "okay"; + compatible = "atmel,sam0-tcc-pwm"; + /* Gives a maximum period of 1.1s for 120MHz main clock */ + prescaler = <8>; + #pwm-cells = <1>; +}; + &sercom2 { status = "okay"; compatible = "atmel,sam0-uart"; diff --git a/boards/arm/atsame54_xpro/atsame54_xpro.yaml b/boards/arm/atsame54_xpro/atsame54_xpro.yaml index de741bd14842bb..48dcc0263242f7 100644 --- a/boards/arm/atsame54_xpro/atsame54_xpro.yaml +++ b/boards/arm/atsame54_xpro/atsame54_xpro.yaml @@ -12,6 +12,7 @@ toolchain: - xtools supported: - gpio + - pwm - spi - i2c - usb_device diff --git a/boards/arm/atsame54_xpro/atsame54_xpro_defconfig b/boards/arm/atsame54_xpro/atsame54_xpro_defconfig index 3a3178a77319c8..2511f95be21ab8 100644 --- a/boards/arm/atsame54_xpro/atsame54_xpro_defconfig +++ b/boards/arm/atsame54_xpro/atsame54_xpro_defconfig @@ -3,6 +3,7 @@ CONFIG_SOC_SERIES_SAME54=y CONFIG_SOC_PART_NUMBER_SAME54P20A=y CONFIG_BOARD_ATSAME54_XPRO=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_ARM_MPU=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_SOC_ATMEL_SAMD5X_XOSC32K=y @@ -18,3 +19,6 @@ CONFIG_WATCHDOG=y CONFIG_WDT_SAM0=y CONFIG_PINMUX=y CONFIG_PINMUX_SAM0=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/atsame54_xpro/doc/index.rst b/boards/arm/atsame54_xpro/doc/index.rst index de4d91cb846582..ca8e1742e8337d 100644 --- a/boards/arm/atsame54_xpro/doc/index.rst +++ b/boards/arm/atsame54_xpro/doc/index.rst @@ -58,6 +58,8 @@ features: +-----------+------------+--------------------------------------+ | GPIO | on-chip | I/O ports | +-----------+------------+--------------------------------------+ +| PWM | on-chip | Pulse Width Modulation | ++-----------+------------+--------------------------------------+ | USART | on-chip | Serial ports | +-----------+------------+--------------------------------------+ | SPI | on-chip | Serial Peripheral Interface ports | @@ -88,7 +90,7 @@ Default Zephyr Peripheral Mapping: ---------------------------------- - SERCOM2 USART TX : PB24 - SERCOM2 USART RX : PB25 -- GPIO LED0 : PC18 +- GPIO/PWM LED0 : PC18 - GPIO SW0 : PB31 System Clock @@ -105,6 +107,13 @@ this BSP. SERCOM2 is the default Zephyr console. - SERCOM2 115200 8n1 connected to the onboard Atmel Embedded Debugger (EDBG) +PWM +=== + +The SAME54 MCU has 5 TCC based PWM units with up to 6 outputs each and a period +of 24 bits or 16 bits. If :code:`CONFIG_PWM_SAM0_TCC` is enabled then LED0 is +driven by TCC0 instead of by GPIO. + SPI Port ======== diff --git a/boards/arm/atsame54_xpro/pinmux.c b/boards/arm/atsame54_xpro/pinmux.c index 56a17eefc8461b..28581770ce791b 100644 --- a/boards/arm/atsame54_xpro/pinmux.c +++ b/boards/arm/atsame54_xpro/pinmux.c @@ -8,12 +8,12 @@ #include #include -static int board_pinmux_init(struct device *dev) +static int board_pinmux_init(const struct device *dev) { - struct device *muxa = device_get_binding("PINMUX_A"); - struct device *muxb = device_get_binding("PINMUX_B"); - struct device *muxc = device_get_binding("PINMUX_C"); - struct device *muxd = device_get_binding("PINMUX_D"); + const struct device *muxa = device_get_binding("PINMUX_A"); + const struct device *muxb = device_get_binding("PINMUX_B"); + const struct device *muxc = device_get_binding("PINMUX_C"); + const struct device *muxd = device_get_binding("PINMUX_D"); ARG_UNUSED(dev); ARG_UNUSED(muxa); @@ -105,6 +105,11 @@ static int board_pinmux_init(struct device *dev) pinmux_pin_set(muxd, 9, PINMUX_FUNC_C); #endif +#if (ATMEL_SAM0_DT_TCC_CHECK(0, atmel_sam0_tcc_pwm) && CONFIG_PWM_SAM0_TCC) + /* TCC0 on WO2=PC18 */ + pinmux_pin_set(muxc, 18, PINMUX_FUNC_F); +#endif + #ifdef CONFIG_USB_DC_SAM0 /* USB DP on PA25, USB DM on PA24 */ pinmux_pin_set(muxa, 25, PINMUX_FUNC_H); diff --git a/boards/arm/atsamr21_xpro/atsamr21_xpro.dts b/boards/arm/atsamr21_xpro/atsamr21_xpro.dts index c77e87e9a4e4fe..26a18c76db34b0 100644 --- a/boards/arm/atsamr21_xpro/atsamr21_xpro.dts +++ b/boards/arm/atsamr21_xpro/atsamr21_xpro.dts @@ -21,6 +21,7 @@ /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; + pwm-led0 = &pwm_led0; sw0 = &user_button; i2c-0 = &sercom1; }; @@ -33,6 +34,13 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&tcc0 3>; + }; + }; + buttons { compatible = "gpio-keys"; user_button: button_0 { @@ -40,12 +48,65 @@ label = "SW0"; }; }; + + ext1_header: xplained-pro-connector1 { + compatible = "atmel-xplained-pro-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &porta 6 0>, /* ADC6 */ + <1 0 &porta 7 0>, /* ADC7 */ + <2 0 &porta 13 0>, /* GPIO */ + <3 0 &porta 28 0>, /* GPIO */ + <4 0 &porta 18 0>, /* PWM_T0_W2 */ + <5 0 &porta 19 0>, /* PWM_T0_W3 */ + <6 0 &porta 22 0>, /* GPIO */ + <7 0 &porta 23 0>, /* GPIO */ + <8 0 &porta 16 0>, /* TWD1 EXT2 */ + <9 0 &porta 17 0>, /* TWCK1 EXT2 */ + <10 0 &porta 5 0>, /* RXD0 */ + <11 0 &porta 4 0>, /* TXD0 */ + <12 0 &portb 3 0>, /* SPI5(SS) */ + <13 0 &portb 22 0>, /* SPI5(MOSI) EXTx */ + <14 0 &portb 2 0>, /* SPI5(MISO) EXTx */ + <15 0 &portb 23 0>; /* SPI5(SCK) EXTx */ + }; + + ext2_header: xplained-pro-connector2 { + compatible = "atmel-xplained-pro-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = /*<0 0 - - 0>, - */ + /*<1 0 - - 0>, - */ + <2 0 &porta 15 0>, /* GPIO */ + /*<3 0 - - 0>, - */ + /*<4 0 - - 0>, - */ + /*<5 0 - - 0>, - */ + /*<6 0 - - 0>, - */ + <7 0 &porta 8 0>, /* GPIO */ + <8 0 &porta 16 0>, /* TWD1 EXT1 */ + <9 0 &porta 17 0>, /* TWCK1 EXT1 */ + /*<11 0 - - 0>, - */ + /*<12 0 - - 0>, - */ + <12 0 &porta 14 0>, /* GPIO */ + <13 0 &portb 22 0>, /* SPI5(MOSI) EXTx */ + <14 0 &portb 2 0>, /* SPI5(MISO) EXTx */ + <15 0 &portb 23 0>; /* SPI5(SCK) EXTx */ + }; }; &cpu0 { clock-frequency = <48000000>; }; +&tcc0 { + status = "okay"; + compatible = "atmel,sam0-tcc-pwm"; + prescaler = <4>; + #pwm-cells = <1>; +}; + &sercom0 { status = "okay"; compatible = "atmel,sam0-uart"; @@ -76,7 +137,7 @@ #address-cells = <1>; #size-cells = <0>; - cs-gpios = <&portb 31 0>; + cs-gpios = <&portb 31 GPIO_ACTIVE_LOW>; rf2xx@0 { compatible = "atmel,rf2xx"; @@ -108,3 +169,18 @@ &rtc { status = "okay"; }; + +ext1_spi: &sercom5 { +}; + +ext1_i2c: &sercom1 { +}; + +ext1_serial: &sercom0 { +}; + +ext2_spi: &sercom5 { +}; + +ext2_i2c: &sercom1 { +}; diff --git a/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml b/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml index 8c0caebad47693..c2d0c19bca2a71 100644 --- a/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml +++ b/boards/arm/atsamr21_xpro/atsamr21_xpro.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2019 Gerson Fernando Budke +# Copyright (c) 2019-2020 Gerson Fernando Budke # Copyright (c) 2019 Benjamin Valentin # SPDX-License-Identifier: Apache-2.0 identifier: atsamr21_xpro @@ -13,7 +13,13 @@ toolchain: - xtools supported: - gpio - - spi - i2c - ieee802154 + - netif + - pwm + - spi - usb_device + - xpro_gpio + - xpro_i2c + - xpro_serial + - xpro_spi diff --git a/boards/arm/atsamr21_xpro/atsamr21_xpro_defconfig b/boards/arm/atsamr21_xpro/atsamr21_xpro_defconfig index caeb06be7e5af6..405c5a4984c7af 100644 --- a/boards/arm/atsamr21_xpro/atsamr21_xpro_defconfig +++ b/boards/arm/atsamr21_xpro/atsamr21_xpro_defconfig @@ -4,6 +4,7 @@ CONFIG_SOC_SERIES_SAMR21=y CONFIG_SOC_PART_NUMBER_SAMR21G18A=y CONFIG_BOARD_ATSAMR21_XPRO=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y diff --git a/boards/arm/atsamr21_xpro/doc/index.rst b/boards/arm/atsamr21_xpro/doc/index.rst index b9b227b449e215..cf35140a2b72ab 100644 --- a/boards/arm/atsamr21_xpro/doc/index.rst +++ b/boards/arm/atsamr21_xpro/doc/index.rst @@ -45,6 +45,8 @@ features: +-----------+------------+--------------------------------------+ | GPIO | on-chip | I/O ports | +-----------+------------+--------------------------------------+ +| PWM | on-chip | Pulse Width Modulation | ++-----------+------------+--------------------------------------+ | USART | on-chip | Serial ports | +-----------+------------+--------------------------------------+ | SPI | on-chip | Serial Peripheral Interface ports | @@ -81,7 +83,7 @@ Default Zephyr Peripheral Mapping: - SERCOM5 SPI MOSI : PB22 - SERCOM5 SPI SCK : PB23 - GPIO SPI CS : PB03 -- GPIO LED0 : PB17 +- GPIO/PWM LED0 : PA19 System Clock ============ @@ -97,6 +99,13 @@ this BSP. SERCOM0 is the default Zephyr console. - SERCOM0 115200 8n1 connected to the onboard Atmel Embedded Debugger (EDBG) +PWM +=== + +The SAMR21 MCU has 3 TCC based PWM units with up to 4 outputs each and a +period of 24 bits or 16 bits. If :code:`CONFIG_PWM_SAM0_TCC` is enabled then +LED0 is driven by TCC0 instead of by GPIO. + SPI Port ======== diff --git a/boards/arm/atsamr21_xpro/pinmux.c b/boards/arm/atsamr21_xpro/pinmux.c index 9f81d73efc763c..2b5cc97b6b69ac 100644 --- a/boards/arm/atsamr21_xpro/pinmux.c +++ b/boards/arm/atsamr21_xpro/pinmux.c @@ -9,11 +9,11 @@ #include #include -static int board_pinmux_init(struct device *dev) +static int board_pinmux_init(const struct device *dev) { - struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); - struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); - struct device *muxc = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_c))); + const struct device *muxa = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + const struct device *muxb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); + const struct device *muxc = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_c))); ARG_UNUSED(dev); @@ -95,6 +95,13 @@ static int board_pinmux_init(struct device *dev) #warning Pin mapping may not be configured #endif +#if (ATMEL_SAM0_DT_TCC_CHECK(0, atmel_sam0_tcc_pwm) && \ + defined(CONFIG_PWM_SAM0_TCC)) + + /* TCC0 on WO3=PA19 */ + pinmux_pin_set(muxa, 19, PINMUX_FUNC_F); +#endif + #ifdef CONFIG_USB_DC_SAM0 /* USB DP on PA25, USB DM on PA24 */ pinmux_pin_set(muxa, 25, PINMUX_FUNC_G); diff --git a/boards/arm/b_l072z_lrwan1/CMakeLists.txt b/boards/arm/b_l072z_lrwan1/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/b_l072z_lrwan1/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.dts b/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.dts index a197ced794e4e3..14cbe6b33a43db 100644 --- a/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.dts +++ b/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics B-L072Z-LRWAN1 Discovery kit"; - compatible = "st,stm32l072z-lrwan1", "st,stm32l072"; + compatible = "st,stm32l072z-lrwan1"; chosen { zephyr,console = &usart2; @@ -53,6 +54,8 @@ led2 = &blue_led; led3 = &red_led; sw0 = &user_button; + eeprom-0 = &eeprom; + lora0 = &lora; }; }; @@ -61,24 +64,51 @@ arduino_spi: &spi2 {}; arduino_i2c: &i2c1 {}; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa15 &spi1_sck_pb3 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; + cs-gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; + + lora: sx1276@0 { + compatible = "semtech,sx1276"; + reg = <0>; + label = "sx1276"; + reset-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>; + dio-gpios = <&gpiob 4 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + <&gpiob 1 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + <&gpiob 0 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + <&gpioc 13 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + <&gpioa 5 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, + <&gpioa 4 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + rfi-enable-gpios = <&gpioa 1 GPIO_ACTIVE_HIGH>; + rfo-enable-gpios = <&gpioc 2 GPIO_ACTIVE_HIGH>; + pa-boost-enable-gpios = <&gpioc 1 GPIO_ACTIVE_HIGH>; + tcxo-power-gpios = <&gpioa 12 GPIO_ACTIVE_HIGH>; + tcxo-power-startup-delay-ms = <5>; + spi-max-frequency = <1000000>; + }; }; &spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; @@ -86,3 +116,30 @@ arduino_i2c: &i2c1 {}; &rtc { status = "okay"; }; + +&rng { + status = "okay"; +}; + +&eeprom { + status = "okay"; +}; + +&usb { + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Set aside 32KiB for data at the end of the 192KiB flash */ + storage_partition: partition@28000 { + label = "storage"; + reg = <0x00028000 0x00008000>; + }; + }; +}; diff --git a/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.yaml b/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.yaml index d692c45bcb07e1..9f2bdaf86d90c9 100644 --- a/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.yaml +++ b/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1.yaml @@ -18,3 +18,5 @@ supported: - gpio - pinmux - counter + - eeprom + - nvs diff --git a/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1_defconfig b/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1_defconfig index 52cb0f43168c97..993c34aee6a74b 100644 --- a/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1_defconfig +++ b/boards/arm/b_l072z_lrwan1/b_l072z_lrwan1_defconfig @@ -10,6 +10,9 @@ CONFIG_BOARD_B_L072Z_LRWAN1=y # General Kernel Options CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32000000 +# Enable MPU +CONFIG_ARM_MPU=y + # Clock configuration CONFIG_CLOCK_CONTROL=y # SYSCLK selection diff --git a/boards/arm/b_l072z_lrwan1/doc/index.rst b/boards/arm/b_l072z_lrwan1/doc/index.rst index b2711899f4ed73..d94123c051824f 100644 --- a/boards/arm/b_l072z_lrwan1/doc/index.rst +++ b/boards/arm/b_l072z_lrwan1/doc/index.rst @@ -15,7 +15,7 @@ This kit provides: - Embedded ultra-low-power STM32L072CZ Series MCUs, based on Arm* Cortex* -M0+ core, with 192 Kbytes of Flash - memory, 20 Kbytes of RAM, 20 Kbytes of EEPROM + memory, 20 Kbytes of RAM, 6 Kbytes of EEPROM - Frequency range: 860 MHz - 930 MHz - USB 2.0 FS - 4-channel,12-bit ADC, 2xDAC @@ -99,7 +99,7 @@ The STM32L072CZ SoC provides the following hardware IPs: - 2x ultra-low-power comparators - 11x communication interfaces - - USB OTG 2.0 full-speed, LPM and BCD + - USB 2.0 full-speed device, LPM and BCD - 3x I2C FM+(1 Mbit/s), SMBus/PMBus - 4x USARTs (ISO 7816, LIN, IrDA, modem) - 6x SPIs (4x SPIs with the Quad SPI) @@ -135,6 +135,16 @@ The Zephyr B-L072Z-LRWAN1 Discovery board configuration supports the following h +-----------+------------+-------------------------------------+ | RTC | on-chip | counter | +-----------+------------+-------------------------------------+ +| TRNG | on-chip | true random number generator | ++-----------+------------+-------------------------------------+ +| EEPROM | on-chip | eeprom | ++-----------+------------+-------------------------------------+ +| USB | on-chip | usb | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash | ++-----------+------------+-------------------------------------+ +| LoRa | on-module | sx1276 | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -173,6 +183,13 @@ Serial Port B-L072Z-LRWAN1 Discovery board has 2 U(S)ARTs. The Zephyr console output is assigned to UART2. Default settings are 115200 8N1. +USB device +---------- + +B-L072Z-LRWAN1 Discovery board has 1 USB device controller. However, +the USB data lines are not connected to the MCU by default. To connect +the USB data lines to the MCU, short solder bridges SB15 and SB16. + Programming and Debugging ************************* diff --git a/boards/arm/b_l072z_lrwan1/pinmux.c b/boards/arm/b_l072z_lrwan1/pinmux.c deleted file mode 100644 index 4a86c98b7e3bfd..00000000000000 --- a/boards/arm/b_l072z_lrwan1/pinmux.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2018 Aleksandr Makarov - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include "pinmux/stm32/pinmux_stm32.h" - -/* pin assignments for STMicroelectronics B-L072Z-LRWAN1 Discovery board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32L0_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32L0_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L0_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L0_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA15, STM32L0_PINMUX_FUNC_PA15_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB3, STM32L0_PINMUX_FUNC_PB3_SPI1_SCK}, - {STM32_PIN_PA6, STM32L0_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L0_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32L0_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32L0_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32L0_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32L0_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32L0_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32L0_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/b_l4s5i_iot01a/Kconfig.board b/boards/arm/b_l4s5i_iot01a/Kconfig.board new file mode 100644 index 00000000000000..927b683f71e188 --- /dev/null +++ b/boards/arm/b_l4s5i_iot01a/Kconfig.board @@ -0,0 +1,8 @@ +# B_L4S5I_IOT01A discovery kit configuration + +# Copyright (c) 2020 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_B_L4S5I_IOT01A + bool "STM32L4S5I IOT Discovery kit" + depends on SOC_STM32L4S5XX diff --git a/boards/arm/b_l4s5i_iot01a/Kconfig.defconfig b/boards/arm/b_l4s5i_iot01a/Kconfig.defconfig new file mode 100644 index 00000000000000..c46e35d5fc360d --- /dev/null +++ b/boards/arm/b_l4s5i_iot01a/Kconfig.defconfig @@ -0,0 +1,60 @@ +# B_L4S5I_IOT01A discovery kit board configuration + +# Copyright (c) 2020 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_B_L4S5I_IOT01A + +config BOARD + default "b_l4s5i_iot01a" + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +choice LIS3MDL_TRIGGER_MODE + default LIS3MDL_TRIGGER_NONE +endchoice + +choice HTS221_TRIGGER_MODE + default HTS221_TRIGGER_NONE +endchoice + +choice LSM6DSL_TRIGGER_MODE + default LSM6DSL_TRIGGER_GLOBAL_THREAD + depends on LSM6DSL +endchoice + +if BT + +config SPI + default y + +choice BT_HCI_BUS_TYPE + default BT_SPI +endchoice + +config BT_SPI_BLUENRG + default y + +config BT_BLUENRG_ACI + default y +# Disable Flow control +config BT_HCI_ACL_FLOW_CONTROL + default n +config BT_HCI_VS_EXT + default n + +endif # BT + +if WIFI + +config SPI + default y + +config WIFI_ESWIFI + default y + +endif # WIFI + +endif # BOARD_B_L4S5I_IOT01A diff --git a/boards/arm/b_l4s5i_iot01a/arduino_r3_connector.dtsi b/boards/arm/b_l4s5i_iot01a/arduino_r3_connector.dtsi new file mode 100644 index 00000000000000..085c7292febfc1 --- /dev/null +++ b/boards/arm/b_l4s5i_iot01a/arduino_r3_connector.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioc 5 0>, /* A0 */ + <1 0 &gpioc 4 0>, /* A1 */ + <2 0 &gpioc 3 0>, /* A2 */ + <3 0 &gpioc 2 0>, /* A3 */ + <4 0 &gpioc 1 0>, /* A4 */ + <5 0 &gpioc 0 0>, /* A5 */ + <6 0 &gpioa 1 0>, /* D0 */ + <7 0 &gpioa 0 0>, /* D1 */ + <8 0 &gpiod 14 0>, /* D2 */ + <9 0 &gpiob 0 0>, /* D3 */ + <10 0 &gpioa 3 0>, /* D4 */ + <11 0 &gpiob 4 0>, /* D5 */ + <12 0 &gpiob 1 0>, /* D6 */ + <13 0 &gpioa 4 0>, /* D7 */ + <14 0 &gpiob 2 0>, /* D8 */ + <15 0 &gpioa 15 0>, /* D9 */ + <16 0 &gpioa 2 0>, /* D10 */ + <17 0 &gpioa 7 0>, /* D11 */ + <18 0 &gpioa 6 0>, /* D12 */ + <19 0 &gpioa 5 0>, /* D13 */ + <20 0 &gpiob 9 0>, /* D14 */ + <21 0 &gpiob 8 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c1 {}; +arduino_spi: &spi1 {}; +arduino_serial: &uart4 {}; diff --git a/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.dts b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.dts new file mode 100644 index 00000000000000..2d9a3bd7acb84f --- /dev/null +++ b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.dts @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2020 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "arduino_r3_connector.dtsi" + +/ { + model = "STMicroelectronics B-L4S5I-IOT01A discovery kit"; + compatible = "st,b-l4s5i-iot01a"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + green_led_1: led_1 { + gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + green_led_2: led_2 { + gpios = <&gpiob 14 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + }; + }; + + aliases { + led0 = &green_led_1; + sw0 = &user_button; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; + current-speed = <115200>; + status = "okay"; +}; + +&uart4 { + pinctrl-0 = <&uart4_tx_pa0 &uart4_rx_pa1>; + current-speed = <115200>; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + status = "okay"; + clock-frequency = ; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; + status = "okay"; + clock-frequency = ; + + lis3mdl-magn@1e { + compatible = "st,lis3mdl-magn"; + reg = <0x1e>; + label = "LIS3MDL"; + }; + + hts221@5f { + compatible = "st,hts221"; + reg = <0x5f>; + label = "HTS221"; + }; + + lps22hb-press@5d { + compatible = "st,lps22hb-press"; + reg = <0x5d>; + label = "LPS22HB"; + }; + + lsm6dsl@6a { + compatible = "st,lsm6dsl"; + reg = <0x6a>; + irq-gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; + label = "LSM6DSL"; + }; + + vl53l0x@29 { + compatible = "st,vl53l0x"; + reg = <0x29>; + label = "VL53L0X"; + xshut-gpios = <&gpioc 6 GPIO_ACTIVE_HIGH>; + }; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&spi3 { + pinctrl-0 = <&spi3_sck_pc10 &spi3_miso_pc11 &spi3_mosi_pc12>; + status = "okay"; + + cs-gpios = <&gpiod 13 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>, + <&gpioe 0 GPIO_ACTIVE_HIGH>; + + spbtle-rf@0 { + compatible = "zephyr,bt-hci-spi"; + reg = <0>; + reset-gpios = <&gpioa 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + irq-gpios = <&gpioe 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; + spi-max-frequency = <2000000>; + label = "SPBTLE-RF"; + }; + + wifi0: ism43362@1 { + compatible = "inventek,eswifi"; + spi-max-frequency = <2000000>; + reg = <1>; + resetn-gpios = <&gpioe 8 GPIO_ACTIVE_HIGH>; + boot0-gpios = <&gpiob 12 GPIO_ACTIVE_HIGH>; + wakeup-gpios = <&gpiob 13 GPIO_ACTIVE_HIGH>; + data-gpios = <&gpioe 1 GPIO_ACTIVE_HIGH>; + label = "ESWIFI0"; + }; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00010000>; + read-only; + }; + + /* + * The flash starting at offset 0x10000 and ending at + * offset 0x1ffff is reserved for use by the application. + */ + + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 0x0006C000>; + }; + slot1_partition: partition@8c000 { + label = "image-1"; + reg = <0x0008C000 0x0006C000>; + }; + scratch_partition: partition@f8000 { + label = "image-scratch"; + reg = <0x000F8000 0x00004000>; + }; + + storage_partition: partition@fc000 { + label = "storage"; + reg = <0x000fc000 0x00004000>; + }; + }; +}; + +&timers2 { + status = "okay"; + + pwm2: pwm { + status = "okay"; + pinctrl-0 = <&tim2_ch1_pa15>; + }; +}; + +&rtc { + status = "okay"; +}; + +&lptim1 { + status = "okay"; +}; + +&usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12 + &usb_otg_fs_id_pa10>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&rng { + status = "okay"; +}; diff --git a/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml new file mode 100644 index 00000000000000..01c99a436409d6 --- /dev/null +++ b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml @@ -0,0 +1,23 @@ +identifier: b_l4s5i_iot01a +name: ST B_L4S5I_IOT01A Discovery kit +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 640 +flash: 2048 +supported: + - arduino_gpio + - arduino_i2c + - i2c + - hts221 + - lps22hb + - lsm6dsl + - pwm + - gpio + - ble + - spi + - vl53l0x + - watchdog diff --git a/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a_defconfig b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a_defconfig new file mode 100644 index 00000000000000..9a5800df261974 --- /dev/null +++ b/boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a_defconfig @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32L4X=y +CONFIG_SOC_STM32L4S5XX=y +# 80MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=80000000 + +# enable uart driver +CONFIG_SERIAL=y + +# enable pinmux +CONFIG_PINMUX=y + +# enable GPIO +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y + +# Use HSI (16MHz) to feed into PLL +CONFIG_CLOCK_STM32_PLL_SRC_HSI=y + +# PLL configuration +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=4 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_R_DIVISOR=2 + +# Produce 80MHz clock at PLLCLK output +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=40 + +# Produce Max (80MHz) HCLK +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 + +# Produce Max (80MHz) APB1 clocks and APB2 clocks +CONFIG_CLOCK_STM32_APB1_PRESCALER=1 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 + +# console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/b_l4s5i_iot01a/board.cmake b/boards/arm/b_l4s5i_iot01a/board.cmake new file mode 100644 index 00000000000000..d3088e3404d584 --- /dev/null +++ b/boards/arm/b_l4s5i_iot01a/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32L4S5VI" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/b_l4s5i_iot01a/doc/img/b-l4s5i_iot01a.jpg b/boards/arm/b_l4s5i_iot01a/doc/img/b-l4s5i_iot01a.jpg new file mode 100644 index 00000000000000..4331b958b1f3ce Binary files /dev/null and b/boards/arm/b_l4s5i_iot01a/doc/img/b-l4s5i_iot01a.jpg differ diff --git a/boards/arm/b_l4s5i_iot01a/doc/index.rst b/boards/arm/b_l4s5i_iot01a/doc/index.rst new file mode 100644 index 00000000000000..fb4f9e04102deb --- /dev/null +++ b/boards/arm/b_l4s5i_iot01a/doc/index.rst @@ -0,0 +1,235 @@ +.. _b_l4s5i_iot01a_board: + +ST B_L4S5I_IOT01A Discovery kit +############################### + +Overview +******** + +The B_L4S5I_IOT01A Discovery kit features an ARM Cortex-M4 based STM32L4S5VI MCU +with a wide range of connectivity support and configurations. Here are +some highlights of the B_L4S5I_IOT01A Discovery kit: + + +- STM32L4S5VIT6 microcontroller featuring 2 Mbyte of Flash memory, 640 Kbytes of RAM in LQFP100 package +- On-board ST-LINK/V2-1 supporting USB re-enumeration capability +- Three different interfaces supported on USB: + + - Virtual com port + - Mass storage + - Debug port + +- ARDUINO ® Uno V3 and Pmod TM expansion connector +- 4 LEDs (2 for user, wifi, BLE) +- 2 push-buttons (user and reset) +- USB OTG FS with micro-AB connector +- Dynamic NFC tag +- 2 digital omnidirectional microphones +- Capacitive digital sensor for relative humidity and temperature +- Time-of-flight and gesture-detection sensors +- High-performance 3-axis magnetometer +- 3D accelerometer and 3D gyroscope +- 64-Mbit Quad-SPI Flash memory +- Bluetooth ® 4.1 module +- 802.11 b/g/n compliant Wi‐Fi ® module +- MCU current ammeter with 4 ranges and auto-calibration + +- Flexible power supply options: + - ST-LINK/V2-1 + - USB FS connector + - External 5 V + + +.. image:: img/b-l4s5i_iot01a.jpg + :width: 450px + :align: center + :height: 394px + :alt: B_L4S5I_IOT01A Discovery kit + +More information about the board can be found at the `B L4S5I IOT01A Discovery kit website`_. + +Hardware +******** + +The STM32L4S5VI SoC provides the following hardware features: + +- Ultra-low-power with FlexPowerControl (down to 130 nA Standby mode and 100 uA/MHz run mode) +- Core: ARM |reg| 32-bit Cortex |reg|-M4 CPU with FPU, frequency up to 120 MHz, 100DMIPS/1.25DMIPS/MHz (Dhrystone 2.1) +- Clock Sources: + - 4 to 48 MHz crystal oscillator + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) + - Internal low-power 32 kHz RC ( |plusminus| 5%) + - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by + LSE (better than |plusminus| 0.25 % accuracy) + - 3 PLLs for system clock, USB, audio, ADC +- RTC with HW calendar, alarms and calibration +- Up to 21 capacitive sensing channels: support touchkey, linear and rotary touch sensors +- 16x timers: + - 2x 16-bit advanced control + - 2x 32-bit and 5x 16-bit general purpose + - 2x 16-bit basic + - 2x low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - SysTick timer +- Up to 83 fast I/Os, most 5 V-tolerant +- Memories + - Up to 2 MB Flash, 2 banks read-while-write, proprietary code readout protection + - Up to 640 KB of SRAM including 32 KB with hardware parity check + - External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories + - Octo SPI memory interface +- 4x digital filters for sigma delta modulator +- Rich analog peripherals (independent supply) + - 1x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS + - 2x 12-bit DAC, low-power sample and hold + - 2x operational amplifiers with built-in PGA + - 2x ultra-low-power comparators +- 18x communication interfaces + - USB OTG 2.0 full-speed, LPM and BCD + - 2x SAIs (serial audio interface) + - 4x I2C FM+(1 Mbit/s), SMBus/PMBus + - 6x USARTs (ISO 7816, LIN, IrDA, modem) + - 3x SPIs (4x SPIs with the Quad SPI) + - CAN (2.0B Active) and SDMMC interface + - SDMMC I/F + - DCMI camera interface +- 14-channel DMA controller with multiplex request router +- True random number generator +- CRC calculation unit, 96-bit unique ID +- AES and HASH hardware accelerators +- Development support: serial wire debug (SWD), JTAG, Embedded Trace Macrocell |trade| + + +More information about STM32L4S5VI can be found here: + - `STM32L4S5VI on www.st.com`_ + - `STM32L4S5 reference manual`_ + + +Supported Features +================== + +The Zephyr b_l4s5i_iot01a board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ +| BLE | module | bluetooth | ++-----------+------------+-------------------------------------+ +| WIFI | module | es-wifi | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: + + ``boards/arm/b_l4s5i_iot01a/b_l4s5i_iot01a_defconfig`` + + +Connections and IOs +=================== + +B_L4S5I_IOT01A Discovery kit has 9 GPIO controllers (from A to I). These controllers are responsible for pin muxing, +input/output, pull-up, etc. + +For mode details please refer to `B L47S5I IOT01A board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_1 TX/RX : PB6/PB7 (ST-Link Virtual Port Com) +- UART_4 TX/RX : PA0/PA1 (Arduino Serial) +- I2C1 SCL/SDA : PB8/PB9 (Arduino I2C) +- I2C2 SCL/SDA : PB10/PB11 (Sensor I2C bus) +- SPI1 SCK/MISO/MOSI : PA5/PA6/PA7 (Arduino SPI) +- SPI3 SCK/MISO/MOSI : PC10/PC11/PC12 (BT SPI bus) +- PWM_2_CH1 : PA15 +- LD1 : PA5 +- LD2 : PB14 +- user button : PC13 + +System Clock +------------ + +B_L4S5I_IOT01A Discovery System Clock could be driven by an internal or external oscillator, +as well as the main PLL clock. By default the System clock is driven by the PLL clock at 80MHz, +driven by 16MHz high speed internal oscillator. + +Serial Port +----------- + +B_L4S5I_IOT01A Discovery kit has 4 U(S)ARTs. The Zephyr console output is assigned to UART1. +Default settings are 115200 8N1. + + +Programming and Debugging +************************* + +Flashing +======== + +B_L4S5I_IOT01A Discovery kit includes an ST-LINK/V2-1 embedded debug tool interface. +This interface is supported by the openocd version included in Zephyr SDK. + +Flashing an application to B_L4S5I_IOT01A Discovery kit +------------------------------------------------------- + +Connect the B_L4S5I_IOT01A Discovery kit to your host computer using the USB +port, then run a serial host program to connect with your Discovery +board. For example: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +Then, build and flash in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: b_l4s5i_iot01a + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + Hello World! arm + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: b_l4s5i_iot01a + :maybe-skip-config: + :goals: debug + +.. _B L4S5I IOT01A Discovery kit website: + https://www.st.com/en/evaluation-tools/b-l4s5i-iot01a.html + +.. _B L47S5I IOT01A board User Manual: + https://www.st.com/resource/en/user_manual/dm00698410.pdf + +.. _STM32L4S5VI on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32l4s5vi.html + +.. _STM32L4S5 reference manual: + https://www.st.com/resource/en/reference_manual/dm00310109.pdf diff --git a/boards/arm/b_l4s5i_iot01a/support/openocd.cfg b/boards/arm/b_l4s5i_iot01a/support/openocd.cfg new file mode 100644 index 00000000000000..295299f2fbec9f --- /dev/null +++ b/boards/arm/b_l4s5i_iot01a/support/openocd.cfg @@ -0,0 +1,12 @@ +source [find board/stm32l4discovery.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/bbc_microbit/bbc_microbit.dts b/boards/arm/bbc_microbit/bbc_microbit.dts index 37e2387867278e..bfdbc5c6b1b4a8 100644 --- a/boards/arm/bbc_microbit/bbc_microbit.dts +++ b/boards/arm/bbc_microbit/bbc_microbit.dts @@ -94,10 +94,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/bbc_microbit/board.cmake b/boards/arm/bbc_microbit/board.cmake index 097d499ad219f8..fabb7e6bc16473 100644 --- a/boards/arm/bbc_microbit/board.cmake +++ b/boards/arm/bbc_microbit/board.cmake @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(pyocd "--target=nrf51") -board_runner_args(nrfjprog "--nrf-family=NRF51") board_runner_args(jlink "--device=nrf51" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/bcm958402m2_a72/bcm958402m2_a72_defconfig b/boards/arm/bcm958402m2_a72/bcm958402m2_a72_defconfig index ce424269718d11..ad7a1370a79c44 100644 --- a/boards/arm/bcm958402m2_a72/bcm958402m2_a72_defconfig +++ b/boards/arm/bcm958402m2_a72/bcm958402m2_a72_defconfig @@ -4,6 +4,8 @@ CONFIG_SOC_SERIES_VIPER=y CONFIG_SOC_BCM58402_A72=y CONFIG_BOARD_BCM958402M2_A72=y +CONFIG_ARM64_VA_BITS_36=y +CONFIG_ARM64_PA_BITS_36=y # Zephyr Kernel Configuration CONFIG_XIP=n @@ -18,3 +20,8 @@ CONFIG_UART_NS16550=y # Enable Console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y + +# Enable PCIe EP +CONFIG_PCIE_ENDPOINT=y +CONFIG_PCIE_EP_IPROC=y +CONFIG_PCIE_EP_IPROC_V2=y diff --git a/boards/arm/bl652_dvk/bl652_dvk.dts b/boards/arm/bl652_dvk/bl652_dvk.dts index d22b9fc278de4a..c9169feee28164 100644 --- a/boards/arm/bl652_dvk/bl652_dvk.dts +++ b/boards/arm/bl652_dvk/bl652_dvk.dts @@ -95,7 +95,7 @@ sck-pin = <25>; mosi-pin = <23>; miso-pin = <24>; - cs-gpios = <&gpio0 22 0>; + cs-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; }; &spi1 { @@ -104,14 +104,11 @@ sck-pin = <16>; mosi-pin = <20>; miso-pin = <14>; - cs-gpios = <&gpio0 12 0>; + cs-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/bl652_dvk/board.cmake b/boards/arm/bl652_dvk/board.cmake index ceef68ad051067..d99bc793000e7f 100644 --- a/boards/arm/bl652_dvk/board.cmake +++ b/boards/arm/bl652_dvk/board.cmake @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +board_runner_args(nrfjprog "--softreset") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/bl653_dvk/Kconfig b/boards/arm/bl653_dvk/Kconfig new file mode 100644 index 00000000000000..aad8c62992cd7b --- /dev/null +++ b/boards/arm/bl653_dvk/Kconfig @@ -0,0 +1,10 @@ +# BL653 DVK board configuration + +# Copyright (c) 2020 Laird Connectivity +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on BOARD_BL653_DVK diff --git a/boards/arm/bl653_dvk/Kconfig.board b/boards/arm/bl653_dvk/Kconfig.board new file mode 100644 index 00000000000000..4a6ca61c3e6acd --- /dev/null +++ b/boards/arm/bl653_dvk/Kconfig.board @@ -0,0 +1,8 @@ +# BL653 DVK board configuration + +# Copyright (c) 2020 Laird Connectivity +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_BL653_DVK + bool "BL653 DVK" + depends on SOC_NRF52833_QIAA diff --git a/boards/arm/bl653_dvk/Kconfig.defconfig b/boards/arm/bl653_dvk/Kconfig.defconfig new file mode 100644 index 00000000000000..4c9b61430e7a59 --- /dev/null +++ b/boards/arm/bl653_dvk/Kconfig.defconfig @@ -0,0 +1,28 @@ +# BL653 DVK board configuration + +# Copyright (c) 2020 Laird Connectivity +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_BL653_DVK + +config BOARD + default "bl653_dvk" + +if USB + +config USB_NRFX + default y + +config USB_DEVICE_STACK + default y + +endif # USB + +config IEEE802154_NRF5 + default y + depends on IEEE802154 + +config BT_CTLR + default BT + +endif # BOARD_BL653_DVK diff --git a/boards/arm/bl653_dvk/bl653_dvk.dts b/boards/arm/bl653_dvk/bl653_dvk.dts new file mode 100644 index 00000000000000..753c5be46e8a0e --- /dev/null +++ b/boards/arm/bl653_dvk/bl653_dvk.dts @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2020 Laird Connectivity + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Laird BL653 Dev Kit"; + compatible = "lairdconnect,bl653_dvk"; + + 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; + }; + + leds { + compatible = "gpio-leds"; + led1: led_1 { + gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; + label = "Blue LED 1"; + }; + led2: led_2 { + gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; + label = "Blue LED 2"; + }; + led3: led_3 { + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + label = "Blue LED 3"; + }; + led4: led_4 { + gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; + label = "Blue LED 4"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button1: button_1 { + gpios = <&gpio0 11 GPIO_PULL_UP>; + label = "Push button switch 1 (SW1)"; + }; + button2: button_2 { + gpios = <&gpio0 12 GPIO_PULL_UP>; + label = "Push button switch 2 (SW2)"; + }; + button3: button_3 { + gpios = <&gpio0 24 GPIO_PULL_UP>; + label = "Push button switch 3 (SW9)"; + }; + button4: button_4 { + gpios = <&gpio0 22 GPIO_PULL_UP>; + label = "Push button switch 4 (SW10)"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + led2 = &led3; + led3 = &led4; + sw0 = &button1; + sw1 = &button2; + sw2 = &button3; + sw3 = &button4; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <115200>; + status = "okay"; + tx-pin = <6>; + rx-pin = <8>; + rts-pin = <5>; + cts-pin = <7>; +}; + +&i2c0 { + compatible = "nordic,nrf-twi"; + status = "okay"; + sda-pin = <26>; + scl-pin = <27>; +}; + +&pwm0 { + status = "okay"; + ch0-pin = <13>; +}; + +&spi1 { + compatible = "nordic,nrf-spi"; + status = "okay"; + sck-pin = <41>; + mosi-pin = <40>; + miso-pin = <4>; + cs-gpios = <&gpio1 23 0>; +}; + +&flash0 { + /* + * For more information, see: + * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x000000000 0xC000>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0x32000>; + }; + slot1_partition: partition@3e000 { + label = "image-1"; + reg = <0x0003E000 0x32000>; + }; + scratch_partition: partition@70000 { + label = "image-scratch"; + reg = <0x00070000 0xA000>; + }; + storage_partition: partition@7a000 { + label = "storage"; + reg = <0x0007A000 0x00006000>; + }; + }; +}; + +&usbd { + compatible = "nordic,nrf-usbd"; + status = "okay"; +}; diff --git a/boards/arm/bl653_dvk/bl653_dvk.yaml b/boards/arm/bl653_dvk/bl653_dvk.yaml new file mode 100644 index 00000000000000..193592cb67256c --- /dev/null +++ b/boards/arm/bl653_dvk/bl653_dvk.yaml @@ -0,0 +1,19 @@ +identifier: bl653_dvk +name: BL653_DVK +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - usb_device + - ble + - ieee802154 + - pwm + - watchdog + - gpio + - counter + - spi + - i2c diff --git a/boards/arm/bl653_dvk/bl653_dvk_defconfig b/boards/arm/bl653_dvk/bl653_dvk_defconfig new file mode 100644 index 00000000000000..29bd61e40f8afb --- /dev/null +++ b/boards/arm/bl653_dvk/bl653_dvk_defconfig @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52833_QIAA=y +CONFIG_BOARD_BL653_DVK=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable RTT +CONFIG_USE_SEGGER_RTT=y + +# enable GPIO +CONFIG_GPIO=y + +# enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# additional board options +CONFIG_GPIO_AS_PINRESET=y + +# 32kHz clock source +CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y +CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y diff --git a/boards/arm/bl653_dvk/board.cmake b/boards/arm/bl653_dvk/board.cmake new file mode 100644 index 00000000000000..0590105afd5d89 --- /dev/null +++ b/boards/arm/bl653_dvk/board.cmake @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(nrfjprog "--softreset") +board_runner_args(jlink "--device=nrf52" "--speed=4000") +board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/bl653_dvk/doc/bl653_dvk.rst b/boards/arm/bl653_dvk/doc/bl653_dvk.rst new file mode 100644 index 00000000000000..64e703f4712a2d --- /dev/null +++ b/boards/arm/bl653_dvk/doc/bl653_dvk.rst @@ -0,0 +1,231 @@ +.. _bl653_dvk: + +Laird Connectivity BL653 DVK +############################ + +Overview +******** + +The BL653 Development Kit (453-00039-K1, 453-00041-K1) hardware provides +support for the Laird Connectivity BL653 module powered by a Nordic Semiconductor nRF52833 ARM Cortex-M4F CPU. + +This development kit has the following features: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UART (Universal Asynchronous Receiver-Transmitter)` +* :abbr:`USB (Universal Serial Bus)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/bl653_dvk.jpg + :width: 500px + :align: center + :alt: BL653 Development Kit + + BL653 Development Kit Board + +More information about the board can be found at the +`BL653 website`_. + +Hardware +******** + +Supported Features +================== + +The BL653 DVK board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth, | +| | | ieee802154 | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| USB | on-chip | usb | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Other hardware features are not supported by the Zephyr kernel. +See `BL653 website`_ +for a complete list of BL653 Development Kit board hardware features. + +Connections and IOs +=================== + +LED +--- + +* LED1 (blue) = P0.13 +* LED2 (blue) = P0.14 +* LED3 (blue) = P0.15 +* LED4 (blue) = P0.16 + +Push buttons +------------ + +* BUTTON1 = SW1 = P0.11 +* BUTTON2 = SW2 = P0.12 +* BUTTON3 = SW9 = P0.24 +* BUTTON4 = SW10 = P0.25 +* RESET = SW3 = nReset/IF BOOT + +Programming and Debugging +************************* + +Applications for the ``bl653_dvk`` board configuration can be +built and flashed in the usual way (see :ref:`build_an_application` +and :ref:`application_run` for more details); however, the standard +debugging targets are not currently available. + +Flashing +======== + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. Then build and flash +applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :ref:`hello_world` application. + +First, run your favorite terminal program to listen for output. + +NOTE: On the BL653 development board, the FTDI USB should be used to access the UART console. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the BL653 development kit +can be found. For example, under Linux, :code:`/dev/ttyUSB0`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: bl653_dvk + :goals: build flash + +Debugging +========= + +Refer to the :ref:`nordic_segger` page to learn about debugging Nordic based boards with a +Segger IC. + +Testing Bluetooth on the BL653 DVK +*********************************** +Many of the Bluetooth examples will work on the BL653 DVK. +Try them out: + +* :ref:`ble_peripheral` +* :ref:`bluetooth-eddystone-sample` +* :ref:`bluetooth-ibeacon-sample` + + +Testing the LEDs and buttons on the BL653 DVK +************************************************ + +There are 2 samples that allow you to test that the buttons (switches) and LEDs on +the board are working properly with Zephyr: + +* :ref:`blinky-sample` +* :ref:`button-sample` + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in +:zephyr_file:`boards/arm/bl653_dvk/bl653_dvk.dts`. + +Using UART1 +*********** + +The following approach can be used when an application needs to use +more than one UART for connecting peripheral devices: + +1. Add devicetree overlay file to the main directory of your application: + + .. code-block:: console + + $ cat bl653_dvk.overlay + &uart1 { + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + status = "okay"; + tx-pin = <14>; + rx-pin = <16>; + }; + + In the overlay file above, pin P0.16 is used for RX and P0.14 is used for TX + +2. Use the UART1 as ``device_get_binding(DT_LABEL(DT_NODELABEL(uart1)))`` + +Overlay file naming +=================== + +The file has to be named ``.overlay`` and placed in the app main directory to be +picked up automatically by the build system. + +See :ref:`set-devicetree-overlays` for further details. + +Selecting the pins +================== +To select the pin numbers for tx-pin and rx-pin: + +.. code-block:: console + + tx-pin = + +Open the `nRF52833 Product Specification`_, chapter 7 'Hardware and Layout'. +In the table 7.1.1 'aQFN73 ball assignments' select the pins marked +'General purpose I/O'. Note that pins marked as 'low frequency I/O only' can only be used +in under-10KHz applications. They are not suitable for 115200 speed of UART. + +Translate the 'Pin' into number for devicetree by using the following formula:: + + pin_no = b*32 + a + +where ``a`` and ``b`` are from the Pin value in the table (Pb.a). +For example, for P0.1, ``pin_no = 1`` and for P1.0, ``pin_no = 32``. + +References +********** + +.. target-notes:: + +.. _BL653 website: https://www.lairdconnect.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl653-series-bluetooth-51-802154-nfc-module +.. _nRF52833 Product Specification: https://infocenter.nordicsemi.com/pdf/nRF52833_OPS_v0.7.pdf diff --git a/boards/arm/bl653_dvk/doc/img/bl653_dvk.jpg b/boards/arm/bl653_dvk/doc/img/bl653_dvk.jpg new file mode 100644 index 00000000000000..a1c80bae69f9b3 Binary files /dev/null and b/boards/arm/bl653_dvk/doc/img/bl653_dvk.jpg differ diff --git a/boards/arm/bl654_dvk/Kconfig.defconfig b/boards/arm/bl654_dvk/Kconfig.defconfig index fb134dca52ef75..12ef2bd1048f31 100644 --- a/boards/arm/bl654_dvk/Kconfig.defconfig +++ b/boards/arm/bl654_dvk/Kconfig.defconfig @@ -18,10 +18,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/bl654_dvk/bl654_dvk.dts b/boards/arm/bl654_dvk/bl654_dvk.dts index 4b96f02753b61f..8e490dfdf3b1e4 100644 --- a/boards/arm/bl654_dvk/bl654_dvk.dts +++ b/boards/arm/bl654_dvk/bl654_dvk.dts @@ -119,7 +119,7 @@ sck-pin = <41>; mosi-pin = <40>; miso-pin = <4>; - cs-gpios = <&gpio1 12 0>; + cs-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; }; &spi1 { @@ -128,7 +128,7 @@ sck-pin = <19>; mosi-pin = <20>; miso-pin = <21>; - cs-gpios = <&gpio0 17 0>; + cs-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; mx25r6435f@0 { compatible = "jedec,spi-nor"; reg = <0>; @@ -142,10 +142,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/bl654_dvk/board.cmake b/boards/arm/bl654_dvk/board.cmake index ceef68ad051067..d99bc793000e7f 100644 --- a/boards/arm/bl654_dvk/board.cmake +++ b/boards/arm/bl654_dvk/board.cmake @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +board_runner_args(nrfjprog "--softreset") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/black_f407ve/CMakeLists.txt b/boards/arm/black_f407ve/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/black_f407ve/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/black_f407ve/black_f407ve.dts b/boards/arm/black_f407ve/black_f407ve.dts index 3a4b34e26dadf6..84964de8ff0dcd 100644 --- a/boards/arm/black_f407ve/black_f407ve.dts +++ b/boards/arm/black_f407ve/black_f407ve.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include / { model = "black_f407ve board"; @@ -56,11 +57,13 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; @@ -70,6 +73,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; @@ -78,20 +82,24 @@ }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; &can1 { + pinctrl-0 = <&can1_rx_pd0 &can1_tx_pd1>; bus-speed = <125000>; status = "disabled"; }; &can2 { + pinctrl-0 = <&can2_rx_pb12 &can2_tx_pb13>; bus-speed = <125000>; status = "okay"; }; &spi1 { + pinctrl-0 = <&spi1_sck_pb3 &spi1_miso_pb4 &spi1_mosi_pb5>; status = "okay"; cs-gpios = <&gpiob 0 GPIO_ACTIVE_LOW>; w25q16cv: w25q16cv@0 { @@ -109,5 +117,6 @@ }; &spi2 { + pinctrl-0 = <&spi2_sck_pb10 &spi2_miso_pc2 &spi2_mosi_pc3>; status = "okay"; }; diff --git a/boards/arm/black_f407ve/black_f407ve_defconfig b/boards/arm/black_f407ve/black_f407ve_defconfig index d57200a20ace6f..0ade8eafd25b10 100644 --- a/boards/arm/black_f407ve/black_f407ve_defconfig +++ b/boards/arm/black_f407ve/black_f407ve_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable UART CONFIG_SERIAL=y diff --git a/boards/arm/black_f407ve/pinmux.c b/boards/arm/black_f407ve/pinmux.c deleted file mode 100644 index aa961a91e43e45..00000000000000 --- a/boards/arm/black_f407ve/pinmux.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for black_f407ve board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32F4_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PD0, STM32F4_PINMUX_FUNC_PD0_CAN1_RX}, - {STM32_PIN_PD1, STM32F4_PINMUX_FUNC_PD1_CAN1_TX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can2), okay) && CONFIG_CAN - {STM32_PIN_PB12, STM32F4_PINMUX_FUNC_PB12_CAN2_RX}, - {STM32_PIN_PB13, STM32F4_PINMUX_FUNC_PB13_CAN2_TX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PB3, STM32F4_PINMUX_FUNC_PB3_SPI1_SCK}, - {STM32_PIN_PB4, STM32F4_PINMUX_FUNC_PB4_SPI1_MISO}, - {STM32_PIN_PB5, STM32F4_PINMUX_FUNC_PB5_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_SPI2_SCK}, - {STM32_PIN_PC2, STM32F4_PINMUX_FUNC_PC2_SPI2_MISO}, - {STM32_PIN_PC3, STM32F4_PINMUX_FUNC_PC3_SPI2_MOSI}, -#endif -}; - -static int pinmux_black_f407ve_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_black_f407ve_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/black_f407zg_pro/CMakeLists.txt b/boards/arm/black_f407zg_pro/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/black_f407zg_pro/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/black_f407zg_pro/black_f407zg_pro.dts b/boards/arm/black_f407zg_pro/black_f407zg_pro.dts index ba9900b24c78be..f6eb0f2f14d06a 100644 --- a/boards/arm/black_f407zg_pro/black_f407zg_pro.dts +++ b/boards/arm/black_f407zg_pro/black_f407zg_pro.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include / { model = "black_f407zg_pro board"; @@ -56,11 +57,13 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; @@ -70,6 +73,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; @@ -78,19 +82,23 @@ }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; &can1 { + pinctrl-0 = <&can1_rx_pd0 &can1_tx_pd1>; bus-speed = <125000>; status = "disabled"; }; &can2 { + pinctrl-0 = <&can2_rx_pb12 &can2_tx_pb13>; bus-speed = <125000>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_sck_pb10 &spi2_miso_pc2 &spi2_mosi_pc3>; status = "okay"; }; diff --git a/boards/arm/black_f407zg_pro/black_f407zg_pro_defconfig b/boards/arm/black_f407zg_pro/black_f407zg_pro_defconfig index 8ef87ac324f289..50b5d1e3dca2a2 100644 --- a/boards/arm/black_f407zg_pro/black_f407zg_pro_defconfig +++ b/boards/arm/black_f407zg_pro/black_f407zg_pro_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable UART CONFIG_SERIAL=y diff --git a/boards/arm/black_f407zg_pro/pinmux.c b/boards/arm/black_f407zg_pro/pinmux.c deleted file mode 100644 index d6d0e4e3945403..00000000000000 --- a/boards/arm/black_f407zg_pro/pinmux.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignment for black_f407zg_pro board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32F4_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PD0, STM32F4_PINMUX_FUNC_PD0_CAN1_RX}, - {STM32_PIN_PD1, STM32F4_PINMUX_FUNC_PD1_CAN1_TX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can2), okay) && CONFIG_CAN - {STM32_PIN_PB12, STM32F4_PINMUX_FUNC_PB12_CAN2_RX}, - {STM32_PIN_PB13, STM32F4_PINMUX_FUNC_PB13_CAN2_TX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PB3, STM32F4_PINMUX_FUNC_PB3_SPI1_SCK}, - {STM32_PIN_PB4, STM32F4_PINMUX_FUNC_PB4_SPI1_MISO}, - {STM32_PIN_PB5, STM32F4_PINMUX_FUNC_PB5_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_SPI2_SCK}, - {STM32_PIN_PC2, STM32F4_PINMUX_FUNC_PC2_SPI2_MISO}, - {STM32_PIN_PC3, STM32F4_PINMUX_FUNC_PC3_SPI2_MOSI}, -#endif -}; - - -static int pinmux_black_f407zg_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_black_f407zg_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/blackpill_f401ce/Kconfig.board b/boards/arm/blackpill_f401ce/Kconfig.board new file mode 100644 index 00000000000000..666a12a157d60c --- /dev/null +++ b/boards/arm/blackpill_f401ce/Kconfig.board @@ -0,0 +1,8 @@ +# Copyright (c) 2020 Kalyan Sriram +# SPDX-License-Identifier: Apache-2.0 + +# STM32F401CE based Black Pill V3.0+ board configuration + +config BOARD_BLACKPILL_F401CE + bool "WeAct Studio Black Pill V3.0+ Board" + depends on SOC_STM32F401XE diff --git a/boards/arm/blackpill_f401ce/Kconfig.defconfig b/boards/arm/blackpill_f401ce/Kconfig.defconfig new file mode 100644 index 00000000000000..739c5512170ede --- /dev/null +++ b/boards/arm/blackpill_f401ce/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2020 Kalyan Sriram +# SPDX-License-Identifier: Apache-2.0 + +# F401CE based Black Pill V3.0+ board board configuration + +if BOARD_BLACKPILL_F401CE + +config BOARD + default "blackpill_f401ce" + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +endif # BOARD_BLACKPILL_F401CE diff --git a/boards/arm/blackpill_f401ce/blackpill_f401ce.dts b/boards/arm/blackpill_f401ce/blackpill_f401ce.dts new file mode 100644 index 00000000000000..ed875b4639dff2 --- /dev/null +++ b/boards/arm/blackpill_f401ce/blackpill_f401ce.dts @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2020 Kalyan Sriram + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "WeAct Studio Black Pill V3.0 Board"; + compatible = "weact,blackpill-f401ce"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + user_led: led { + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + label = "User LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "KEY"; + gpios = <&gpioa 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + }; + + aliases { + led0 = &user_led; + sw0 = &user_button; + }; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00008000>; + read-only; + }; + + /* + * The flash starting at offset 0x00008000 and ending at + * offset 0x0001ffff (sectors 2 through 4) is reserved for + * use by the application. + */ + + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 0x00020000>; + }; + slot1_partition: partition@40000 { + label = "image-1"; + reg = <0x00040000 0x00020000>; + }; + scratch_partition: partition@60000 { + label = "image-scratch"; + reg = <0x00060000 0x00020000>; + }; + }; +}; + +&timers4 { + status = "okay"; + + pwm4: pwm { + status = "okay"; + pinctrl-0 = <&tim4_ch1_pb6 &tim4_ch2_pb7>; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + status = "okay"; + current-speed = <115200>; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_nss_pa4 + &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc1_in1_pa1>; + status = "okay"; +}; diff --git a/boards/arm/blackpill_f401ce/blackpill_f401ce.yaml b/boards/arm/blackpill_f401ce/blackpill_f401ce.yaml new file mode 100644 index 00000000000000..8c2c1955710dbf --- /dev/null +++ b/boards/arm/blackpill_f401ce/blackpill_f401ce.yaml @@ -0,0 +1,16 @@ +identifier: blackpill_f401ce +name: WeAct Studio Black Pill V3.0 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - counter + - spi + - usb + - i2c + - uart + - pwm + - adc diff --git a/boards/arm/blackpill_f401ce/blackpill_f401ce_defconfig b/boards/arm/blackpill_f401ce/blackpill_f401ce_defconfig new file mode 100644 index 00000000000000..f69969a9569718 --- /dev/null +++ b/boards/arm/blackpill_f401ce/blackpill_f401ce_defconfig @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32F4X=y +CONFIG_SOC_STM32F401XE=y +# 84MHz system clock (highest value to get a precise USB clock should be 84MHz) +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=84000000 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable pinmux +CONFIG_PINMUX=y + +# Enable GPIO +CONFIG_GPIO=y + +# Clock configuration +CONFIG_CLOCK_CONTROL=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# HSE configuration +CONFIG_CLOCK_STM32_HSE_CLOCK=25000000 +# use HSE as PLL input +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# Produce 84MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=25 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=336 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=4 +# Produce 42 MHz clock for USB +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=7 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=2 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 diff --git a/boards/arm/blackpill_f401ce/board.cmake b/boards/arm/blackpill_f401ce/board.cmake new file mode 100644 index 00000000000000..0a9dc09da93be1 --- /dev/null +++ b/boards/arm/blackpill_f401ce/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(dfu-util "--pid=0483:df11" "--alt=0" "--dfuse") +board_runner_args(jlink "--device=STM32F401CE" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) diff --git a/boards/arm/blackpill_f401ce/doc/img/Blackpill_Pinout.png b/boards/arm/blackpill_f401ce/doc/img/Blackpill_Pinout.png new file mode 100644 index 00000000000000..3f15c620d208ef Binary files /dev/null and b/boards/arm/blackpill_f401ce/doc/img/Blackpill_Pinout.png differ diff --git a/boards/arm/blackpill_f401ce/doc/img/blackpill-v3.jpg b/boards/arm/blackpill_f401ce/doc/img/blackpill-v3.jpg new file mode 100644 index 00000000000000..d4687d8e0c8515 Binary files /dev/null and b/boards/arm/blackpill_f401ce/doc/img/blackpill-v3.jpg differ diff --git a/boards/arm/blackpill_f401ce/doc/index.rst b/boards/arm/blackpill_f401ce/doc/index.rst new file mode 100644 index 00000000000000..a252d244e75840 --- /dev/null +++ b/boards/arm/blackpill_f401ce/doc/index.rst @@ -0,0 +1,179 @@ +.. _blackpill_f401ce: + +WeAct Studio Black Pill V3.0 +############################ + +Overview +******** + +The WeAct Black Pill V3.0 Board is an extremely low cost and bare-bones +development board featuring the STM32F401CE, see `STM32F401CE website`_. +This is the 48-pin variant of the STM32F401x series, +see `STM32F401x reference manual`_. More info about the board available +`here `_ and on `WeAct Github`_. + +.. image:: img/blackpill-v3.jpg + :align: center + :alt: Black Pill V3.0+ + +Hardware +******** + +The STM32F401CE based Black Pill V3.0+ Board provides the following +hardware components: + +- STM32F401CEU6 in UFQFPN48 package +- ARM |reg| 32-bit Cortex |reg| -M4 CPU with FPU +- 84 MHz max CPU frequency +- VDD from 1.7 V to 3.6 V +- 512 KB Flash +- 96 KB SRAM +- GPIO with external interrupt capability +- 1x12-bit, 2.4 MSPS ADC with 16 channels +- DMA Controller +- Up to 11 Timers (six 16-bit, two 32-bit, two watchdog timers and a SysTick timer) +- USART/UART (3) +- I2C (3) +- SPI/I2S (5) +- SDIO +- USB 2.0 full-speed device/host/OTG controller with on-chip PHY +- CRC calculation unit +- 96-bit unique ID +- RTC + +Supported Features +================== + +The Zephyr blackpill_f401ce board configuration supports the following +hardware features: + ++------------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++============+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++------------+------------+-------------------------------------+ +| SYSTICK | on-chip | system clock | ++------------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++------------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++------------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++------------+------------+-------------------------------------+ +| FLASH | on-chip | flash | ++------------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++------------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++------------+------------+-------------------------------------+ +| ADC | on-chip | ADC Controller | ++------------+------------+-------------------------------------+ +| USB OTG FS | on-chip | USB device | ++------------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: + + ``boards/arm/blackpill_f401ce/blackpill_f401ce_defconfig`` + +Pin Mapping +=========== + +Available pins: +--------------- +.. image:: img/Blackpill_Pinout.png + :align: center + :alt: Black Pill V3.0+ Pinout + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_1 TX/RX : PA9/PA10 +- I2C1 SCL/SDA : PB8/PB9 +- SPI1 CS/SCK/MISO/MOSI : PA4/PA5/PA6/PA7 (Routed to footprint for external flash) +- PWM_4_CH1 : PB6 +- PWM_4_CH2 : PB7 +- ADC_1 : PA1 +- USER_PB : PA0 +- USER_LED : PC13 + +Note on SPI pin mapping: According to the `board release notes`_, there was a brief +change for V2.0 specifically where MISO was routed to PB4 for the flash footprint. +This was reverted for V2.1+ so that the flash DO pin was routed back to PA6. If using +V2.0 and en external flash, the pinmux will need to be modified accordingly. + +Clock Sources +------------- + +The board has two external oscillators. The frequency of the slow clock (LSE) is +32.768 kHz. The frequency of the main clock (HSE) is 25 MHz. + +The default configuration sources the system clock from the PLL, which is +derived from HSE, and is set at 84MHz, which is the maximum possible frequency +to achieve a stable USB clock (42MHz). + +Programming and Debugging +************************* + +There are 2 main entry points for flashing STM32F4X SoCs, one using the ROM +bootloader, and another by using the SWD debug port (which requires additional +hardware). Flashing using the ROM bootloader requires a special activation +pattern, which can be triggered by using the BOOT0 pin. + +Flashing +======== + +Installing dfu-util +------------------- + +It is recommended to use at least v0.8 of `dfu-util`_. The package available in +debian/ubuntu can be quite old, so you might have to build dfu-util from source. + +There is also a Windows version which works, but you may have to install the +right USB drivers with a tool like `Zadig`_. + +Flashing an Application +----------------------- + +Connect a USB-C cable and the board should power ON. Force the board into DFU mode +by keeping the BOOT0 switch pressed while pressing and releasing the NRST switch. + +The dfu-util runner is supported on this board and so a sample can be built and +tested easily. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: blackpill_f401ce + :goals: build flash + +Debugging +========= + +The board can be debugged by installing the included 100 mil (0.1 inch) header, +and attaching an SWD debugger to the 3V3 (3.3V), GND, SCK, and DIO +pins on that header. + +References +********** + +.. target-notes:: + +.. _board release notes: + https://github.com/WeActTC/MiniF4-STM32F4x1/blob/master/HDK/README.md + +.. _Zadig: + https://zadig.akeo.ie/ + +.. _WeAct Github: + https://github.com/WeActTC/MiniF4-STM32F4x1 + +.. _stm32-base-board-page: + https://stm32-base.org/boards/STM32F401CEU6-WeAct-Black-Pill-V3.0.html + +.. _dfu-util: + http://dfu-util.sourceforge.net/build.html + +.. _STM32F401CE website: + http://www.st.com/en/microcontrollers/stm32f401ce.html + +.. _STM32F401x reference manual: + http://www.st.com/resource/en/reference_manual/dm00096844.pdf diff --git a/boards/arm/blackpill_f401ce/support/openocd.cfg b/boards/arm/blackpill_f401ce/support/openocd.cfg new file mode 100644 index 00000000000000..451853a38bdb23 --- /dev/null +++ b/boards/arm/blackpill_f401ce/support/openocd.cfg @@ -0,0 +1,18 @@ +source [find interface/stlink.cfg] + +transport select hla_swd + +source [find target/stm32f4x.cfg] + +reset_config srst_only + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/blackpill_f411ce/Kconfig.board b/boards/arm/blackpill_f411ce/Kconfig.board new file mode 100644 index 00000000000000..c636f2af74a0ed --- /dev/null +++ b/boards/arm/blackpill_f411ce/Kconfig.board @@ -0,0 +1,8 @@ +# Copyright (c) 2020 Brian Bradley +# SPDX-License-Identifier: Apache-2.0 + +# STM32F411CE based Black Pill V2.0+ board configuration + +config BOARD_BLACKPILL_F411CE + bool "WeAct Studio Black Pill V2.0+ Board" + depends on SOC_STM32F411XE diff --git a/boards/arm/blackpill_f411ce/Kconfig.defconfig b/boards/arm/blackpill_f411ce/Kconfig.defconfig new file mode 100644 index 00000000000000..e54fc87004e640 --- /dev/null +++ b/boards/arm/blackpill_f411ce/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2020 Brian Bradley +# SPDX-License-Identifier: Apache-2.0 + +# F411CE based Black Pill V2.0+ board board configuration + +if BOARD_BLACKPILL_F411CE + +config BOARD + default "blackpill_f411ce" + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +endif # BOARD_BLACKPILL_F411CE diff --git a/boards/arm/blackpill_f411ce/blackpill_f411ce.dts b/boards/arm/blackpill_f411ce/blackpill_f411ce.dts new file mode 100644 index 00000000000000..d0bc58e5a2e49e --- /dev/null +++ b/boards/arm/blackpill_f411ce/blackpill_f411ce.dts @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2020 Brian Bradley + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "WeAct Studio Black Pill V2.0 Board"; + compatible = "weact,blackpill-f411ce"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + user_led: led { + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + label = "User LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "KEY"; + gpios = <&gpioa 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + }; + + aliases { + led0 = &user_led; + sw0 = &user_button; + }; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00008000>; + read-only; + }; + + /* + * The flash starting at offset 0x00008000 and ending at + * offset 0x0001ffff (sectors 2 through 4) is reserved for + * use by the application. + */ + + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 0x00020000>; + }; + slot1_partition: partition@40000 { + label = "image-1"; + reg = <0x00040000 0x00020000>; + }; + scratch_partition: partition@60000 { + label = "image-scratch"; + reg = <0x00060000 0x00020000>; + }; + }; +}; + +&timers4 { + status = "okay"; + + pwm4: pwm { + status = "okay"; + pinctrl-0 = <&tim4_ch1_pb6 &tim4_ch2_pb7>; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + status = "okay"; + current-speed = <115200>; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_nss_pa4 + &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc1_in1_pa1>; + status = "okay"; +}; diff --git a/boards/arm/blackpill_f411ce/blackpill_f411ce.yaml b/boards/arm/blackpill_f411ce/blackpill_f411ce.yaml new file mode 100644 index 00000000000000..b6729fa9bc5314 --- /dev/null +++ b/boards/arm/blackpill_f411ce/blackpill_f411ce.yaml @@ -0,0 +1,16 @@ +identifier: blackpill_f411ce +name: WeAct Studio Black Pill V2.0 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - counter + - spi + - usb + - i2c + - uart + - pwm + - adc diff --git a/boards/arm/blackpill_f411ce/blackpill_f411ce_defconfig b/boards/arm/blackpill_f411ce/blackpill_f411ce_defconfig new file mode 100644 index 00000000000000..6fbd0fe3527a3b --- /dev/null +++ b/boards/arm/blackpill_f411ce/blackpill_f411ce_defconfig @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32F4X=y +CONFIG_SOC_STM32F411XE=y +# 96MHz system clock (highest value to get a precise USB clock should be 96MHz) +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable pinmux +CONFIG_PINMUX=y + +# Enable GPIO +CONFIG_GPIO=y + +# Clock configuration +CONFIG_CLOCK_CONTROL=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# HSE configuration +CONFIG_CLOCK_STM32_HSE_CLOCK=25000000 +# use HSE as PLL input +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# Produce 96MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=25 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=192 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=2 +# Produce 48 MHz clock for USB +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=4 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=2 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 diff --git a/boards/arm/blackpill_f411ce/board.cmake b/boards/arm/blackpill_f411ce/board.cmake new file mode 100644 index 00000000000000..521072ffb8baa8 --- /dev/null +++ b/boards/arm/blackpill_f411ce/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(dfu-util "--pid=0483:df11" "--alt=0" "--dfuse") +board_runner_args(jlink "--device=STM32F411CE" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) diff --git a/boards/arm/blackpill_f411ce/doc/img/Blackpill_Pinout.png b/boards/arm/blackpill_f411ce/doc/img/Blackpill_Pinout.png new file mode 100644 index 00000000000000..3f15c620d208ef Binary files /dev/null and b/boards/arm/blackpill_f411ce/doc/img/Blackpill_Pinout.png differ diff --git a/boards/arm/blackpill_f411ce/doc/img/blackpill-v2.jpg b/boards/arm/blackpill_f411ce/doc/img/blackpill-v2.jpg new file mode 100644 index 00000000000000..d4687d8e0c8515 Binary files /dev/null and b/boards/arm/blackpill_f411ce/doc/img/blackpill-v2.jpg differ diff --git a/boards/arm/blackpill_f411ce/doc/index.rst b/boards/arm/blackpill_f411ce/doc/index.rst new file mode 100644 index 00000000000000..32ee1e9159e378 --- /dev/null +++ b/boards/arm/blackpill_f411ce/doc/index.rst @@ -0,0 +1,179 @@ +.. _blackpill_f411ce: + +WeAct Studio Black Pill V2.0 +############################ + +Overview +******** + +The WeAct Black Pill V2.0 Board is an extremely low cost and bare-bones +development board featuring the STM32F411CE, see `STM32F411CE website`_. +This is the 48-pin variant of the STM32F411x series, +see `STM32F411x reference manual`_. More info about the board available +`here `_ and on `WeAct Github`_. + +.. image:: img/blackpill-v2.jpg + :align: center + :alt: Black Pill V2.0+ + +Hardware +******** + +The STM32F411CE based Black Pill V2.0+ Board provides the following +hardware components: + +- STM32F411CEU6 in UFQFPN48 package +- ARM |reg| 32-bit Cortex |reg| -M4 CPU with FPU +- 100 MHz max CPU frequency +- VDD from 1.7 V to 3.6 V +- 512 KB Flash +- 128 KB SRAM +- GPIO with external interrupt capability +- 1x12-bit, 2.4 MSPS ADC with 16 channels +- DMA Controller +- Up to 11 Timers (six 16-bit, two 32-bit, two watchdog timers and a SysTick timer) +- USART/UART (3) +- I2C (3) +- SPI/I2S (5) +- SDIO +- USB 2.0 full-speed device/host/OTG controller with on-chip PHY +- CRC calculation unit +- 96-bit unique ID +- RTC + +Supported Features +================== + +The Zephyr blackpill_f411ce board configuration supports the following +hardware features: + ++------------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++============+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++------------+------------+-------------------------------------+ +| SYSTICK | on-chip | system clock | ++------------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++------------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++------------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++------------+------------+-------------------------------------+ +| FLASH | on-chip | flash | ++------------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++------------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++------------+------------+-------------------------------------+ +| ADC | on-chip | ADC Controller | ++------------+------------+-------------------------------------+ +| USB OTG FS | on-chip | USB device | ++------------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: + + ``boards/arm/stm32_blackpill_v2/stm32_blackpill_v2_defconfig`` + +Pin Mapping +=========== + +Available pins: +--------------- +.. image:: img/Blackpill_Pinout.png + :align: center + :alt: Black Pill V2.0+ Pinout + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_1 TX/RX : PA9/PA10 +- I2C1 SCL/SDA : PB8/PB9 +- SPI1 CS/SCK/MISO/MOSI : PA4/PA5/PA6/PA7 (Routed to footprint for external flash) +- PWM_4_CH1 : PB6 +- PWM_4_CH2 : PB7 +- ADC_1 : PA1 +- USER_PB : PA0 +- USER_LED : PC13 + +Note on SPI pin mapping: According to the `board release notes`_, there was a brief +change for V2.0 specifically where MISO was routed to PB4 for the flash footprint. +This was reverted for V2.1+ so that the flash DO pin was routed back to PA6. If using +V2.0 and en external flash, the pinmux will need to be modified accordingly. + +Clock Sources +------------- + +The board has two external oscillators. The frequency of the slow clock (LSE) is +32.768 kHz. The frequency of the main clock (HSE) is 25 MHz. + +The default configuration sources the system clock from the PLL, which is +derived from HSE, and is set at 96MHz, which is the maximum possible frequency +to achieve a stable USB clock (48MHz). + +Programming and Debugging +************************* + +There are 2 main entry points for flashing STM32F4X SoCs, one using the ROM +bootloader, and another by using the SWD debug port (which requires additional +hardware). Flashing using the ROM bootloader requires a special activation +pattern, which can be triggered by using the BOOT0 pin. + +Flashing +======== + +Installing dfu-util +------------------- + +It is recommended to use at least v0.8 of `dfu-util`_. The package available in +debian/ubuntu can be quite old, so you might have to build dfu-util from source. + +There is also a Windows version which works, but you may have to install the +right USB drivers with a tool like `Zadig`_. + +Flashing an Application +----------------------- + +Connect a USB-C cable and the board should power ON. Force the board into DFU mode +by keeping the BOOT0 switch pressed while pressing and releasing the NRST switch. + +The dfu-util runner is supported on this board and so a sample can be built and +tested easily. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: blackpill_f411ce + :goals: build flash + +Debugging +========= + +The board can be debugged by installing the included 100 mil (0.1 inch) header, +and attaching an SWD debugger to the 3V3 (3.3V), GND, SCK, and DIO +pins on that header. + +References +********** + +.. target-notes:: + +.. _board release notes: + https://github.com/WeActTC/MiniF4-STM32F4x1/blob/master/HDK/README.md + +.. _Zadig: + https://zadig.akeo.ie/ + +.. _WeAct Github: + https://github.com/WeActTC/MiniF4-STM32F4x1 + +.. _stm32-base-board-page: + https://stm32-base.org/boards/STM32F411CEU6-WeAct-Black-Pill-V2.0.html + +.. _dfu-util: + http://dfu-util.sourceforge.net/build.html + +.. _STM32F411CE website: + http://www.st.com/en/microcontrollers/stm32f411ce.html + +.. _STM32F411x reference manual: + http://www.st.com/resource/en/reference_manual/dm00119316.pdf diff --git a/boards/arm/blackpill_f411ce/support/openocd.cfg b/boards/arm/blackpill_f411ce/support/openocd.cfg new file mode 100644 index 00000000000000..451853a38bdb23 --- /dev/null +++ b/boards/arm/blackpill_f411ce/support/openocd.cfg @@ -0,0 +1,18 @@ +source [find interface/stlink.cfg] + +transport select hla_swd + +source [find target/stm32f4x.cfg] + +reset_config srst_only + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/bt510/Kconfig b/boards/arm/bt510/Kconfig new file mode 100644 index 00000000000000..52e3d3ddcbc20d --- /dev/null +++ b/boards/arm/bt510/Kconfig @@ -0,0 +1,10 @@ +# BT510 board configuration + +# Copyright (c) 2020 Laird Connectivity +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on BOARD_BT510 diff --git a/boards/arm/bt510/Kconfig.board b/boards/arm/bt510/Kconfig.board new file mode 100644 index 00000000000000..e1654936f5fabb --- /dev/null +++ b/boards/arm/bt510/Kconfig.board @@ -0,0 +1,8 @@ +# BT510 DVK board configuration + +# Copyright (c) 2020 Laird Connectivity +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_BT510 + bool "BT510" + depends on SOC_NRF52840_QIAA diff --git a/boards/arm/bt510/Kconfig.defconfig b/boards/arm/bt510/Kconfig.defconfig new file mode 100644 index 00000000000000..576afb00df974b --- /dev/null +++ b/boards/arm/bt510/Kconfig.defconfig @@ -0,0 +1,18 @@ +# BT510 Sensor configuration + +# Copyright (c) 2020 Laird Connectivity +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_BT510 + +config BOARD + default "bt510" + +config IEEE802154_NRF5 + default y + depends on IEEE802154 + +config BT_CTLR + default BT + +endif # BOARD_BT510 diff --git a/boards/arm/bt510/board.cmake b/boards/arm/bt510/board.cmake new file mode 100644 index 00000000000000..d99bc793000e7f --- /dev/null +++ b/boards/arm/bt510/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(nrfjprog "--softreset") +board_runner_args(jlink "--device=nrf52" "--speed=4000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/bt510/bt510.dts b/boards/arm/bt510/bt510.dts new file mode 100644 index 00000000000000..63a36f16f0b3f7 --- /dev/null +++ b/boards/arm/bt510/bt510.dts @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2020 Laird Connectivity + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Laird Sentrius BT510 Sensor"; + compatible = "lairdconnect,bt510"; + + 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; + }; + + leds { + compatible = "gpio-leds"; + led1a: led_1a { + gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; + label = "Red LED 1A"; + }; + led1b: led_1b { + gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>; + label = "Green LED 1B"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button1: button_1 { + gpios = <&gpio1 10 GPIO_PULL_UP>; + label = "Push button switch 1 (SW1)"; + }; + }; + + ids { + compatible = "gpio-keys"; + id0: id_0 { + gpios = <&gpio1 2 GPIO_PULL_UP>; + label = "ID 0"; + }; + id1: id_1 { + gpios = <&gpio1 1 GPIO_PULL_UP>; + label = "ID 1"; + }; + id2: id_2 { + gpios = <&gpio0 25 GPIO_PULL_UP>; + label = "ID 2"; + }; + }; + + tm { + compatible = "gpio-keys"; + tm0: tm_0 { + gpios = <&gpio0 3 GPIO_PULL_UP>; + label = "Test mode (TM)"; + }; + }; + + mag { + compatible = "gpio-keys"; + mag0: mag_0 { + compatible = "honeywell,sm351lt"; + gpios = <&gpio1 14 0>; + label = "SM351LT_0"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1a; + led1 = &led1b; + sw0 = &button1; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <115200>; + status = "okay"; + tx-pin = <6>; + rx-pin = <8>; +}; + +&i2c0 { + compatible = "nordic,nrf-twi"; + status = "okay"; + sda-pin = <26>; + scl-pin = <27>; + + lis2dh12@18 { + compatible = "st,lis2dh12", "st,lis2dh"; + reg = <0x18>; + irq-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>, + <&gpio1 12 GPIO_ACTIVE_HIGH>; + label = "LIS2DH12"; + }; + + si7055@40 { + compatible = "silabs,si7055"; + reg = <0x40>; + label = "SI7055"; + }; +}; + +&flash0 { + /* + * For more information, see: + * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* 96K */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x000000000 0x00018000>; + }; + /* 396K */ + slot0_partition: partition@18000 { + label = "image-0"; + reg = <0x00018000 0x000063000>; + }; + /* 396K */ + slot1_partition: partition@7b000 { + label = "image-1"; + reg = <0x0007b000 0x000063000>; + }; + /* 8K */ + scratch_partition: partition@de000 { + label = "image-scratch"; + reg = <0x000de000 0x00002000>; + }; + + /* + * The flash starting at 0x000e0000 and ending at + * 0x000fffff is reserved for use by the application. + */ + + /* + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + /* 128K */ + storage_partition: partition@e0000 { + label = "storage"; + reg = <0x000e0000 0x00020000>; + }; + }; +}; diff --git a/boards/arm/bt510/bt510.yaml b/boards/arm/bt510/bt510.yaml new file mode 100644 index 00000000000000..d44abc5765a10b --- /dev/null +++ b/boards/arm/bt510/bt510.yaml @@ -0,0 +1,16 @@ +identifier: bt510 +name: BT510 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - ble + - ieee802154 + - pwm + - watchdog + - i2c + - sm351lt diff --git a/boards/arm/bt510/bt510_defconfig b/boards/arm/bt510/bt510_defconfig new file mode 100644 index 00000000000000..f97b87430efd1b --- /dev/null +++ b/boards/arm/bt510/bt510_defconfig @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_BT510=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable RTT +CONFIG_USE_SEGGER_RTT=y + +# enable GPIO +CONFIG_GPIO=y + +# enable uart driver +CONFIG_SERIAL=y + +# enable accelerometer & temperature sensor +CONFIG_I2C=y +CONFIG_SENSOR=y +CONFIG_LIS2DH=y +CONFIG_LIS2DH_TRIGGER_GLOBAL_THREAD=y +CONFIG_LIS2DH_OPER_MODE_LOW_POWER=y +CONFIG_SI7055=y + +# enable magnetoresistive driver +CONFIG_SM351LT=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_RTT_CONSOLE=y + +# additional board options +CONFIG_GPIO_AS_PINRESET=y + +# 32kHz clock source +CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y +CONFIG_CLOCK_CONTROL_NRF_K32SRC_20PPM=y diff --git a/boards/arm/bt510/doc/bt510.rst b/boards/arm/bt510/doc/bt510.rst new file mode 100644 index 00000000000000..f560e5e061f33b --- /dev/null +++ b/boards/arm/bt510/doc/bt510.rst @@ -0,0 +1,219 @@ +.. _bt510: + +Laird Connectivity Sentrius BT510 Sensor +######################################## + +Overview +******** + +The Sentrius™ BT510 Sensor is a battery powered, Bluetooth v5 Long Range integrated sensor that uses a Nordic Semiconductor nRF52840 ARM Cortex-M4F CPU. + +The sensor has the following features: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`UART (Universal Asynchronous Receiver-Transmitter)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/bt510.jpg + :width: 250px + :align: center + :alt: Sentrius BT510 Sensor, front view + + Sentrius BT510 Sensor, front view + +.. figure:: img/bt510_back.jpg + :width: 250px + :align: center + :alt: Sentrius BT510 Sensor, rear view + + Sentrius BT510 Sensor, rear view + +More information about the board can be found at the +`Sentrius BT510 website`_. + +Hardware +******** + +Supported Features +================== + +The BT510 Sensor supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth, | +| | | ieee802154 | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Other hardware features are not supported by the Zephyr kernel. +See the `Sentrius BT510 website`_ +for a complete list of BT510 Sensor features. + +Connections and IOs +=================== + +LED +--- + +* LED1A (green) = P0.22 +* LED1B (red) = P0.20 + +Push button +------------ + +* BUTTON = SW1 = P1.10 + +Programming and Debugging +************************* + +Applications for the ``bt510`` board configuration can be +built and flashed in the usual way (see :ref:`build_an_application` +and :ref:`application_run` for more details); however, the standard +debugging targets are not currently available. + +The BT510 features a TagConnect 10 way socket for connection of a +programmer/debugger, refer to `TagConnect TC2050 product page`_ +for details of an appropriate TagConnect cable. + +A non-standard layout is used to include access to the sensor debug UART. + ++-----------+------------+----------------------+ +| Pin No. | Name | Description | ++===========+============+======================+ +| 1 | Vcc | Power Supply, 3.3V | ++-----------+------------+----------------------+ +| 2 | SWDIO | SWD Data | ++-----------+------------+----------------------+ +| 3 | RXD | Debug UART RX Data | ++-----------+------------+----------------------+ +| 4 | SWDCLK | SWD Clock | ++-----------+------------+----------------------+ +| 5 | TM | Spare GPIO | ++-----------+------------+----------------------+ +| 6 | SWO | SWD Output | ++-----------+------------+----------------------+ +| 7 | N/C | Not Connected | ++-----------+------------+----------------------+ +| 8 | TXD | Debug UART TX Data | ++-----------+------------+----------------------+ +| 9 | GND | Ground | ++-----------+------------+----------------------+ +| 10 | RESET | Reset, Active Low | ++-----------+------------+----------------------+ + +Connectivity to the programmer/debugger must be modified to match +the pinout shown above. + +Laird Connectivity provide the USB-SWD programming board that supports +this connector layout, refer to the `USB SWD Programmer product page`_ +. + +Flashing +======== + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. Then build and flash +applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :ref:`hello_world` application. + +First, run your favorite terminal program to listen for output. + +NOTE: On the BT510, the UART lines are at TTL levels and must be passed through +an appropriate line driver circuit for translation to RS232 levels. Refer to the `MAX3232 datasheet`_ +for a suitable driver IC. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the bt510 can be found. For example, under Linux, :code:`/dev/ttyUSB0`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: bt510 + :goals: build flash + +Note that an external debugger is required to perform application flashing. + +Debugging +========= + +The ``bt510`` board does not have an on-board J-Link debug IC +as some nRF5x development boards, however, instructions from the +:ref:`nordic_segger` page also apply to this board, with the additional step +of connecting an external debugger. + +Testing Bluetooth on the BT510 +*********************************** +Many of the Bluetooth examples will work on the BT510. +Try them out: + +* :ref:`ble_peripheral` +* :ref:`bluetooth-eddystone-sample` +* :ref:`bluetooth-ibeacon-sample` + + +Testing the LEDs and buttons on the BT510 +***************************************** + +There are 2 samples that allow you to test that the buttons (switches) and LEDs on +the board are working properly with Zephyr: + +* :ref:`blinky-sample` +* :ref:`button-sample` + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in +:zephyr_file:`boards/arm/bt510/bt510.dts`. + + +References +********** + +.. target-notes:: + +.. _Sentrius BT510 website: https://www.lairdconnect.com/iot-devices/iot-sensors/bt510-bluetooth-5-long-range-ip67-multi-sensor +.. _TagConnect TC2050 product page: https://www.tag-connect.com/product/tc2050-idc-050 +.. _USB SWD Programmer product page: https://www.lairdconnect.com/usb-swd-programmer/ +.. _MAX3232 datasheet: https://www.ti.com/lit/ds/symlink/max3232.pdf diff --git a/boards/arm/bt510/doc/img/bt510.jpg b/boards/arm/bt510/doc/img/bt510.jpg new file mode 100644 index 00000000000000..0c51c4a05409bb Binary files /dev/null and b/boards/arm/bt510/doc/img/bt510.jpg differ diff --git a/boards/arm/bt510/doc/img/bt510_back.jpg b/boards/arm/bt510/doc/img/bt510_back.jpg new file mode 100644 index 00000000000000..56d657ed389e26 Binary files /dev/null and b/boards/arm/bt510/doc/img/bt510_back.jpg differ diff --git a/boards/arm/cc1352r1_launchxl/Kconfig.defconfig b/boards/arm/cc1352r1_launchxl/Kconfig.defconfig index 875d975fa8c298..25a8e7ea1a2f26 100644 --- a/boards/arm/cc1352r1_launchxl/Kconfig.defconfig +++ b/boards/arm/cc1352r1_launchxl/Kconfig.defconfig @@ -8,12 +8,12 @@ if BOARD_CC1352R1_LAUNCHXL config BOARD default "cc1352r1_launchxl" -if SYS_POWER_MANAGEMENT +if PM # Ideally this value could be made to less than 1 ms, as there is # essentially no delay to come out of IDLE mode. However Zephyr only # supports millisecond precision here, so 1 ms is the best approximation. -config SYS_PM_MIN_RESIDENCY_SLEEP_1 +config PM_MIN_RESIDENCY_SLEEP_1 default 1 # The default here is deliberately made higher to be less agressive, to @@ -25,8 +25,8 @@ config SYS_PM_MIN_RESIDENCY_SLEEP_1 # given application, weighing tradeoffs between a lower value that leads to # higher power savings vs. a higher value that would accommodate for a higher # wakeup latency. -config SYS_PM_MIN_RESIDENCY_SLEEP_2 +config PM_MIN_RESIDENCY_SLEEP_2 default 5 -endif # SYS_POWER_MANAGEMENT +endif # PM endif # BOARD_CC1352R1_LAUNCHXL diff --git a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts index 510fe9cd098a59..e0e3e268aafe2a 100644 --- a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts +++ b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts @@ -92,7 +92,7 @@ mosi-pin = <9>; miso-pin = <8>; cs-pin = <11>; - cs-gpios = <&gpio0 11 0>; + cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; }; &rtc { diff --git a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl_defconfig b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl_defconfig index cdf79fcc4da3a7..2c74d8b8919c47 100644 --- a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl_defconfig +++ b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl_defconfig @@ -7,6 +7,7 @@ CONFIG_SOC_SERIES_CC13X2_CC26X2=y CONFIG_SOC_CC1352R=y CONFIG_BOARD_CC1352R1_LAUNCHXL=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_CC13X2_CC26X2_BOOTLOADER_ENABLE=y CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_ENABLE=y diff --git a/boards/arm/cc1352r1_launchxl/doc/index.rst b/boards/arm/cc1352r1_launchxl/doc/index.rst index cdb1ce2599e13b..e4172318f0a0da 100644 --- a/boards/arm/cc1352r1_launchxl/doc/index.rst +++ b/boards/arm/cc1352r1_launchxl/doc/index.rst @@ -128,6 +128,31 @@ Before flashing or debugging ensure the RESET, TMS, TCK, TDO, and TDI jumpers are in place. Also place jumpers on the the TXD and RXD signals for a serial console using the XDS110 application serial port. +Prerequisites: +============== + +#. Ensure the XDS-110 emulation firmware on the board is updated. + + Download and install the latest `XDS-110 emulation package`_. + + Follow these `xds110 firmware update directions + `_ + + Note that the emulation package install may place the xdsdfu utility + in ``/ccs_base/common/uscif/xds110/``. + +#. Install OpenOCD + + You can obtain OpenOCD by following these + :ref:`installing the latest Zephyr SDK instructions `. + + After the installation, add the directory containing the OpenOCD executable + to your environment's PATH variable. For example, use this command in Linux: + + .. code-block:: console + + export PATH=$ZEPHYR_SDK_INSTALL_DIR/sysroots/x86_64-pokysdk-linux/usr/bin/openocd:$PATH + Flashing ======== @@ -180,11 +205,11 @@ Power Management and UART System and device power management are supported on this platform, and can be enabled via the standard Kconfig options in Zephyr, such as -:option:`CONFIG_SYS_POWER_MANAGEMENT`, :option:`CONFIG_DEVICE_POWER_MANAGEMENT`, -:option:`CONFIG_SYS_POWER_SLEEP_STATES`, and -:option:`CONFIG_SYS_POWER_DEEP_SLEEP_STATES`. +:option:`CONFIG_PM`, :option:`CONFIG_PM_DEVICE`, +:option:`CONFIG_PM_SLEEP_STATES`, and +:option:`CONFIG_PM_DEEP_SLEEP_STATES`. -When system power management is turned on (CONFIG_SYS_POWER_MANAGEMENT=y), +When system power management is turned on (CONFIG_PM=y), sleep state 2 (standby mode) is allowed, and polling is used to retrieve input by calling uart_poll_in(), it is possible for characters to be missed if the system enters standby mode between calls to uart_poll_in(). This is because @@ -193,9 +218,9 @@ disable sleep state 2 while polling: .. code-block:: c - sys_pm_ctrl_disable_state(SYS_POWER_STATE_SLEEP_2); + pm_ctrl_disable_state(POWER_STATE_SLEEP_2); - sys_pm_ctrl_enable_state(SYS_POWER_STATE_SLEEP_2); + pm_ctrl_enable_state(POWER_STATE_SLEEP_2); References @@ -212,3 +237,6 @@ CC1352R1 LaunchPad Quick Start Guide: .. _TI CC13x2 / CC26x2 Technical Reference Manual: http://www.ti.com/lit/pdf/swcu185 + +.. _XDS-110 emulation package: + http://processors.wiki.ti.com/index.php/XDS_Emulation_Software_Package#XDS_Emulation_Software_.28emupack.29_Download diff --git a/boards/arm/cc1352r_sensortag/Kconfig.board b/boards/arm/cc1352r_sensortag/Kconfig.board new file mode 100644 index 00000000000000..6364142ac0b996 --- /dev/null +++ b/boards/arm/cc1352r_sensortag/Kconfig.board @@ -0,0 +1,9 @@ +# TI CC1352R SensorTag board + +# Copyright (c) 2019 Brett Witherspoon +# Copyright (c) 2020 Friedt Professional Engineering Services, Inc +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CC1352R_SENSORTAG + bool "TI CC1352R SensorTag" + depends on SOC_CC1352R diff --git a/boards/arm/cc1352r_sensortag/Kconfig.defconfig b/boards/arm/cc1352r_sensortag/Kconfig.defconfig new file mode 100644 index 00000000000000..1a3ecaf0d09bd8 --- /dev/null +++ b/boards/arm/cc1352r_sensortag/Kconfig.defconfig @@ -0,0 +1,33 @@ +# TI CC1352R SensorTag board + +# Copyright (c) 2019 Brett Witherspoon +# Copyright (c) 2020 Friedt Professional Engineering Services, Inc +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_CC1352R_SENSORTAG + +config BOARD + default "cc1352r_sensortag" + +if PM + +# Ideally this value could be made to less than 1 ms, as there is +# essentially no delay to come out of IDLE mode. However Zephyr only +# supports millisecond precision here, so 1 ms is the best approximation. +config PM_MIN_RESIDENCY_SLEEP_1 + default 1 + +# The default here is deliberately made higher to be less agressive, to +# accommodate for systems that may wish to do some extra work on resume, +# which is possible given some power domains without retention are turned +# out while in STANDBY mode. +# +# It is important to set this value to one that is appropriate for a +# given application, weighing tradeoffs between a lower value that leads to +# higher power savings vs. a higher value that would accommodate for a higher +# wakeup latency. +config PM_MIN_RESIDENCY_SLEEP_2 + default 5 + +endif # PM +endif # BOARD_CC1352R_SENSORTAG diff --git a/boards/arm/cc1352r_sensortag/board.cmake b/boards/arm/cc1352r_sensortag/board.cmake new file mode 100644 index 00000000000000..02fa2ee20ba41a --- /dev/null +++ b/boards/arm/cc1352r_sensortag/board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2020 Erik Larson +# Copyright (c) 2020 Friedt Professional Engineering Services, Inc +# +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=CC1352R1F3" "--iface=jtag" "--tool-opt=-jtagconf -1,-1 -autoconnect 1") +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts new file mode 100644 index 00000000000000..25d49ef7756158 --- /dev/null +++ b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.dts @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2019 Brett Witherspoon + * Copyright (c) 2020 Friedt Professional Engineering Services, Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "../cc1352r1_launchxl/boosterpack_connector.dtsi" + +/* + * Define some constants from driverlib/ioc.h in TI HAL, + * since we don't have a way to include the file directly. + */ +#define IOC_PORT_MCU_UART0_TX 0x00000010 +#define IOC_PORT_MCU_UART0_RX 0x0000000F + +#define BTN_GPIO_FLAGS (GPIO_ACTIVE_LOW | GPIO_PULL_UP) + +/ { + model = "TI CC1352R1 SensorTag"; + compatible = "ti,sensortag-cc1352r"; + + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + sw0 = &btn0; + sw1 = &btn1; + sensor0 = &sensor0; + sensor1 = &sensor1; + /* TODO: add support for hdc2080 */ + }; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + zephyr,flash-controller = &flash_controller; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + led1: led_1 { + gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + led2: led_2 { + gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + }; + + keys { + compatible = "gpio-keys"; + btn0: btn_0 { + gpios = <&gpio0 15 BTN_GPIO_FLAGS>; + label = "Push button 1"; + }; + btn1: btn_1 { + gpios = <&gpio0 14 BTN_GPIO_FLAGS>; + label = "Push button 2"; + }; + }; +}; + +&cpu0 { + clock-frequency = <48000000>; +}; + +&trng { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + tx-pin = <13 IOC_PORT_MCU_UART0_TX>; + rx-pin = <12 IOC_PORT_MCU_UART0_RX>; +}; + +&i2c0 { + status = "okay"; + scl-pin = <4>; + sda-pin = <5>; + + sensor0: sensor@44 { + compatible = "ti,opt3001"; + reg = <0x44>; + label = "OPT3001"; + }; + + /* TODO: add hdc2080 at 0x41 */ +}; + +&spi0 { + status = "okay"; + sck-pin = <10>; + mosi-pin = <9>; + miso-pin = <8>; + cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + + sensor1: sensor@0 { + compatible = "adi,adxl362"; + reg = <0>; + label = "ADXL362"; + int1-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; + spi-max-frequency = <8000000>; + }; + + /* TODO: "jedec,spi-nor" for the mx25r8035 */ +}; + +&rtc { + status = "okay"; +}; diff --git a/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml new file mode 100644 index 00000000000000..5c4fdf9473c8b9 --- /dev/null +++ b/boards/arm/cc1352r_sensortag/cc1352r_sensortag.yaml @@ -0,0 +1,14 @@ +identifier: cc1352r_sensortag +name: TI SimpleLink CC1352R SensorTag +type: mcu +arch: arm +ram: 80 +flash: 352 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - i2c + - spi diff --git a/boards/arm/cc1352r_sensortag/cc1352r_sensortag_defconfig b/boards/arm/cc1352r_sensortag/cc1352r_sensortag_defconfig new file mode 100644 index 00000000000000..68867260f6fc32 --- /dev/null +++ b/boards/arm/cc1352r_sensortag/cc1352r_sensortag_defconfig @@ -0,0 +1,22 @@ +# +# Copyright (c) 2019 Brett Witherspoon +# Copyright (c) 2020 Friedt Professional Engineering Services, Inc +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_CC13X2_CC26X2=y +CONFIG_SOC_CC1352R=y +CONFIG_BOARD_CC1352R_SENSORTAG=y + +CONFIG_CC13X2_CC26X2_BOOTLOADER_ENABLE=y +CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_ENABLE=y +CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_PIN=15 + +CONFIG_PINMUX=y +CONFIG_GPIO=y +CONFIG_SERIAL=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_BUILD_OUTPUT_HEX=y diff --git a/boards/arm/cc1352r_sensortag/doc/img/cc1352r_sensortag.jpg b/boards/arm/cc1352r_sensortag/doc/img/cc1352r_sensortag.jpg new file mode 100644 index 00000000000000..ad1ae2304d2719 Binary files /dev/null and b/boards/arm/cc1352r_sensortag/doc/img/cc1352r_sensortag.jpg differ diff --git a/boards/arm/cc1352r_sensortag/doc/img/launchpad-lpstk-debug.jpg b/boards/arm/cc1352r_sensortag/doc/img/launchpad-lpstk-debug.jpg new file mode 100644 index 00000000000000..0cf75446c8b380 Binary files /dev/null and b/boards/arm/cc1352r_sensortag/doc/img/launchpad-lpstk-debug.jpg differ diff --git a/boards/arm/cc1352r_sensortag/doc/index.rst b/boards/arm/cc1352r_sensortag/doc/index.rst new file mode 100644 index 00000000000000..fdc5d76c8271b8 --- /dev/null +++ b/boards/arm/cc1352r_sensortag/doc/index.rst @@ -0,0 +1,271 @@ +.. _cc1352r_sensortag: + +CC1352R SensorTag +################# + +Overview +******** + +The Texas Instruments CC1352R SensorTag |trade| (LPSTK-CC1352R) is a +development kit for the SimpleLink |trade| multi-Standard CC1352R wireless MCU. + +See the `TI CC1352R SensorTag Product Page`_ for details. + +.. figure:: img/cc1352r_sensortag.jpg + :width: 400px + :align: center + :alt: TI CC1352R SensorTag + + Texas Instruments CC1352R SensorTag |trade| + +Hardware +******** + +The CC1352R SensorTag |trade| development kit features the CC1352R wireless MCU. +The board is equipped with three LEDs, two push buttons and BoosterPack connectors +for expansion. + +The CC13522 wireless MCU has a 48 MHz Arm |reg| Cortex |reg|-M4F SoC and an +integrated Sub-1 and 2.4 GHz transceiver supporting multiple protocols including +Bluetooth |reg| Low Energy and IEEE |reg| 802.15.4. + +See the `TI CC1352R Product Page`_ for additional details. + +Supported Features +================== + +The CC1352R SensorTag board configuration supports the following hardware +features: + ++-----------+------------+------------------+ +| Interface | Controller | Driver/Component | ++===========+============+==================+ +| GPIO | on-chip | gpio | ++-----------+------------+------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+------------------+ +| UART | on-chip | serial | ++-----------+------------+------------------+ +| I2C | on-chip | i2c | ++-----------+------------+------------------+ +| SPI | on-chip | spi | ++-----------+------------+------------------+ +| DIO23 | off-chip | DRV5032 | ++-----------+------------+------------------+ +| I2C | off-chip | HDC2080 | ++-----------+------------+------------------+ +| I2C | off-chip | OPT3001 | ++-----------+------------+------------------+ +| SPI | off-chip | ADXL362 | ++-----------+------------+------------------+ + +Other hardware features are not supported by the Zephyr kernel. + +Connections and IOs +=================== + +All I/O signals are accessible from the BoosterPack connectors. Pin function +aligns with the SensorTag standard. + ++-------+-----------+---------------------+ +| Pin | Function | Usage | ++=======+===========+=====================+ +| DIO3 | GPIO | GPIO / PWM1 | ++-------+-----------+---------------------+ +| DIO4 | I2C_MSSCL | I2C SCL | ++-------+-----------+---------------------+ +| DIO5 | I2C_MSSDA | I2C SDA | ++-------+-----------+---------------------+ +| DIO6 | GPIO | Red LED | ++-------+-----------+---------------------+ +| DIO7 | GPIO | Green LED | ++-------+-----------+---------------------+ +| DIO8 | SSI0_RX | SPI MISO | ++-------+-----------+---------------------+ +| DIO9 | SSI0_TX | SPI MOSI | ++-------+-----------+---------------------+ +| DIO10 | SSI0_CLK | SPI CLK | ++-------+-----------+---------------------+ +| DIO11 | SSIO_CS | SPI CS | ++-------+-----------+---------------------+ +| DIO12 | UART0_RX | UART RXD | ++-------+-----------+---------------------+ +| DIO13 | UART0_TX | UART TXD | ++-------+-----------+---------------------+ +| DIO14 | GPIO | Button 2 | ++-------+-----------+---------------------+ +| DIO15 | GPIO | Button 1 | ++-------+-----------+---------------------+ +| DIO16 | | JTAG TDO | ++-------+-----------+---------------------+ +| DIO17 | | JTAG TDI | ++-------+-----------+---------------------+ +| DIO18 | UART0_RTS | UART RTS / JTAG SWO | ++-------+-----------+---------------------+ +| DIO19 | UART0_CTS | UART CTS | ++-------+-----------+---------------------+ +| DIO20 | GPIO | Flash CS | ++-------+-----------+---------------------+ +| DIO21 | GPIO | Blue LED | ++-------+-----------+---------------------+ +| DIO22 | GPIO | | ++-------+-----------+---------------------+ +| DIO23 | AUX_IO | A0 (DRV5032) | ++-------+-----------+---------------------+ +| DIO24 | AUX_IO | A1 | ++-------+-----------+---------------------+ +| DIO25 | GPIO | HDC2080 INT | ++-------+-----------+---------------------+ +| DIO26 | AUX_IO | A3 | ++-------+-----------+---------------------+ +| DIO27 | GPIO | OPT3001 INT | ++-------+-----------+---------------------+ +| DIO28 | AUX_IO | A5 | ++-------+-----------+---------------------+ +| DIO29 | AUX_IO | A6 | ++-------+-----------+---------------------+ +| DIO30 | AUX_IO | ADXL362 INT | ++-------+-----------+---------------------+ + +Programming and Debugging +************************* + +TI's supported method of programming and debugging the ``CC1352R SensorTag`` is +to use it in tandem with a ``CC1352R LaunchPad``, making use of the integrated +(XDS110) debugger and serial console over USB. + +#. Disconnect the debug isolation jumpers on your LaunchPad +#. Connect the ARM 10-pin JTAG cable to XDS110 OUT header on your LaunchPad +#. Connect the other end of the ARM10-pin cable to the JTAG header on your LaunchPad SensorTag +#. Connect the 2-pin jumper cable to the top pins of RXD and TXD (grey wire to RXD, white wire to TXD) +#. Connect the other end of the 2-pin jumper to pins 12/RX and 13/TX on the LaunchPad SensorTag (Grey to 12/RX, white to 13/TX) +#. Connect your XDS110 LaunchPad to your PC! + +.. figure:: img/launchpad-lpstk-debug.jpg + :width: 400px + :align: center + :alt: Debugging the TI CC1352R SensorTag + +See `Debugging the LaunchPad SensorTag`_ for additional details. + +Prerequisites: +============== + +#. Ensure the XDS-110 emulation firmware on the board is updated. + + Download and install the latest `XDS-110 emulation package`_. + + Follow these `xds110 firmware update directions + `_ + + Note that the emulation package install may place the xdsdfu utility + in ``/ccs_base/common/uscif/xds110/``. + +#. Install OpenOCD + + You can obtain OpenOCD by following these + :ref:`installing the latest Zephyr SDK instructions `. + + After the installation, add the directory containing the OpenOCD executable + to your environment's PATH variable. For example, use this command in Linux: + + .. code-block:: console + + export PATH=$ZEPHYR_SDK_INSTALL_DIR/sysroots/x86_64-pokysdk-linux/usr/bin/openocd:$PATH + +Flashing +======== + +Applications for the ``CC1352R SensorTag`` board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :ref:`hello_world` application. + +First, run your favorite terminal program to listen for output. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the XDS110 application +serial device can be found. For example, :code:`/dev/ttyACM0`. Once in +minicom Pres :code:`Ctrl+A, U` to add a carriage return, and +:code:`Ctrl+A, W` to wrap long lines. + +Then build and flash the application in the usual way. + +For the :code:`Hello, world!` application, follow the instructions below. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cc1352r_sensortag + :goals: build flash + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cc1352r_sensortag + :maybe-skip-config: + :goals: debug + +Bootloader +========== + +The ROM bootloader on CC13x2 and CC26x2 devices is enabled by default. The +bootloader will start if there is no valid application image in flash or the +so-called backdoor is enabled (via option +:option:`CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_ENABLE`) and BTN-1 is held +down during reset. See the bootloader documentation in chapter 10 of the `TI +CC13x2 / CC26x2 Technical Reference Manual`_ for additional information. + +Power Management and UART +========================= + +System and device power management are supported on this platform, and +can be enabled via the standard Kconfig options in Zephyr, such as +:option:`CONFIG_PM`, :option:`CONFIG_PM_DEVICE`, +:option:`CONFIG_PM_SLEEP_STATES`, and +:option:`CONFIG_PM_DEEP_SLEEP_STATES`. + +When system power management is turned on (CONFIG_PM=y), +sleep state 2 (standby mode) is allowed, and polling is used to retrieve input +by calling uart_poll_in(), it is possible for characters to be missed if the +system enters standby mode between calls to uart_poll_in(). This is because +the UART is inactive while the system is in standby mode. The workaround is to +disable sleep state 2 while polling: + +.. code-block:: c + + pm_ctrl_disable_state(SYS_POWER_STATE_SLEEP_2); + + pm_ctrl_enable_state(SYS_POWER_STATE_SLEEP_2); + + +References +********** + +CC1352R1 SensorTag Quick Start Guide: + https://www.ti.com/lit/pdf/swau127 + +.. _TI CC1352R SensorTag Product Page: + http://www.ti.com/tool/lpstk-cc1352r + +.. _TI CC1352R Product Page: + http://www.ti.com/product/cc1352r + +.. _TI CC13x2 / CC26x2 Technical Reference Manual: + http://www.ti.com/lit/pdf/swcu185 + +.. _Debugging the LaunchPad SensorTag: + https://dev.ti.com/tirex/explore/content/simplelink_academy_cc13x2_26x2sdk_4_20_03_00/modules/lpstk/lpstk_oobe/lpstk_oobe.html#-debugging-the-launchpad-sensortag- + +.. _XDS-110 emulation package: + http://processors.wiki.ti.com/index.php/XDS_Emulation_Software_Package#XDS_Emulation_Software_.28emupack.29_Download diff --git a/boards/arm/cc1352r_sensortag/support/openocd.cfg b/boards/arm/cc1352r_sensortag/support/openocd.cfg new file mode 100644 index 00000000000000..16a135a531a071 --- /dev/null +++ b/boards/arm/cc1352r_sensortag/support/openocd.cfg @@ -0,0 +1,4 @@ +source [find board/ti_cc13x2_launchpad.cfg] +# Workaround for #21372. This allows OpenOCD to flash correctly +# with newer 3.x XDS firmware +adapter_khz 1500 diff --git a/boards/arm/cc26x2r1_launchxl/Kconfig.defconfig b/boards/arm/cc26x2r1_launchxl/Kconfig.defconfig index c3e675f865e288..3e7e738f0ff0a8 100644 --- a/boards/arm/cc26x2r1_launchxl/Kconfig.defconfig +++ b/boards/arm/cc26x2r1_launchxl/Kconfig.defconfig @@ -8,12 +8,12 @@ if BOARD_CC26X2R1_LAUNCHXL config BOARD default "cc26x2r1_launchxl" -if SYS_POWER_MANAGEMENT +if PM # Ideally this value could be made to less than 1 ms, as there is # essentially no delay to come out of IDLE mode. However Zephyr only # supports millisecond precision here, so 1 ms is the best approximation. -config SYS_PM_MIN_RESIDENCY_SLEEP_1 +config PM_MIN_RESIDENCY_SLEEP_1 default 1 # The default here is deliberately made higher to be less agressive, to @@ -25,8 +25,8 @@ config SYS_PM_MIN_RESIDENCY_SLEEP_1 # given application, weighing tradeoffs between a lower value that leads to # higher power savings vs. a higher value that would accommodate for a higher # wakeup latency. -config SYS_PM_MIN_RESIDENCY_SLEEP_2 +config PM_MIN_RESIDENCY_SLEEP_2 default 5 -endif # SYS_POWER_MANAGEMENT +endif # PM endif # BOARD_CC26X2R1_LAUNCHXL diff --git a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts index 5d996275d29b27..c07c4a409bf4e6 100644 --- a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts +++ b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts @@ -92,7 +92,7 @@ mosi-pin = <9>; miso-pin = <8>; cs-pin = <11>; - cs-gpios = <&gpio0 11 0>; + cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; }; &rtc { diff --git a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl_defconfig b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl_defconfig index 438b2a319f2a85..df84e891c50c81 100644 --- a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl_defconfig +++ b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl_defconfig @@ -7,6 +7,7 @@ CONFIG_SOC_SERIES_CC13X2_CC26X2=y CONFIG_SOC_CC2652R=y CONFIG_BOARD_CC26X2R1_LAUNCHXL=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_CC13X2_CC26X2_BOOTLOADER_ENABLE=y CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_ENABLE=y diff --git a/boards/arm/cc26x2r1_launchxl/doc/index.rst b/boards/arm/cc26x2r1_launchxl/doc/index.rst index 0ae0cff70e38b5..9a55d5e7af0b69 100644 --- a/boards/arm/cc26x2r1_launchxl/doc/index.rst +++ b/boards/arm/cc26x2r1_launchxl/doc/index.rst @@ -134,6 +134,31 @@ Before flashing or debugging ensure the RESET, TMS, TCK, TDO, and TDI jumpers are in place. Also place jumpers on the the TXD and RXD signals for a serial console using the XDS110 application serial port. +Prerequisites: +============== + +#. Ensure the XDS-110 emulation firmware on the board is updated. + + Download and install the latest `XDS-110 emulation package`_. + + Follow these `xds110 firmware update directions + `_ + + Note that the emulation package install may place the xdsdfu utility + in ``/ccs_base/common/uscif/xds110/``. + +#. Install OpenOCD + + You can obtain OpenOCD by following these + :ref:`installing the latest Zephyr SDK instructions `. + + After the installation, add the directory containing the OpenOCD executable + to your environment's PATH variable. For example, use this command in Linux: + + .. code-block:: console + + export PATH=$ZEPHYR_SDK_INSTALL_DIR/sysroots/x86_64-pokysdk-linux/usr/bin/openocd:$PATH + Flashing ======== @@ -186,11 +211,11 @@ Power Management and UART System and device power management are supported on this platform, and can be enabled via the standard Kconfig options in Zephyr, such as -:option:`CONFIG_SYS_POWER_MANAGEMENT`, :option:`CONFIG_DEVICE_POWER_MANAGEMENT`, -:option:`CONFIG_SYS_POWER_SLEEP_STATES`, and -:option:`CONFIG_SYS_POWER_DEEP_SLEEP_STATES`. +:option:`CONFIG_PM`, :option:`CONFIG_PM_DEVICE`, +:option:`CONFIG_PM_SLEEP_STATES`, and +:option:`CONFIG_PM_DEEP_SLEEP_STATES`. -When system power management is turned on (CONFIG_SYS_POWER_MANAGEMENT=y), +When system power management is turned on (CONFIG_PM=y), sleep state 2 (standby mode) is allowed, and polling is used to retrieve input by calling uart_poll_in(), it is possible for characters to be missed if the system enters standby mode between calls to uart_poll_in(). This is because @@ -199,9 +224,9 @@ disable sleep state 2 while polling: .. code-block:: c - sys_pm_ctrl_disable_state(SYS_POWER_STATE_SLEEP_2); + pm_ctrl_disable_state(POWER_STATE_SLEEP_2); - sys_pm_ctrl_enable_state(SYS_POWER_STATE_SLEEP_2); + pm_ctrl_enable_state(POWER_STATE_SLEEP_2); References @@ -224,3 +249,6 @@ CC26X2R1 LaunchPad Quick Start Guide: .. _TI CC13x2 / CC26x2 Technical Reference Manual: http://www.ti.com/lit/pdf/swcu185 + +.. _XDS-110 emulation package: + http://processors.wiki.ti.com/index.php/XDS_Emulation_Software_Package#XDS_Emulation_Software_.28emupack.29_Download diff --git a/boards/arm/cc3220sf_launchxl/cc3220sf_launchxl_defconfig b/boards/arm/cc3220sf_launchxl/cc3220sf_launchxl_defconfig index b69fac066e0e05..50b23684570c99 100644 --- a/boards/arm/cc3220sf_launchxl/cc3220sf_launchxl_defconfig +++ b/boards/arm/cc3220sf_launchxl/cc3220sf_launchxl_defconfig @@ -3,6 +3,7 @@ CONFIG_BOARD_CC3220SF_LAUNCHXL=y CONFIG_SOC_SERIES_CC32XX=y CONFIG_SOC_CC3220SF=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_PRINTK=y diff --git a/boards/arm/cc3220sf_launchxl/doc/index.rst b/boards/arm/cc3220sf_launchxl/doc/index.rst index 876be9f278febc..d1ee87146ad350 100644 --- a/boards/arm/cc3220sf_launchxl/doc/index.rst +++ b/boards/arm/cc3220sf_launchxl/doc/index.rst @@ -214,7 +214,7 @@ To see program output from UART0, connect a separate terminal window: Then press the reset button (SW1) on the board to run the program. -When using OpenOCD from Zephyr SDK 0.10.3 to flash the device, you may notice +When using OpenOCD from Zephyr SDK to flash the device, you may notice the program hangs when starting the network processor on the device, if the program uses it. There is a known issue with how that version of OpenOCD resets the network processor. You would need to manually hit the reset button @@ -291,11 +291,6 @@ example. See the document `Simplelink Wi-Fi Certificates Handling`_ for details on using the TI UniFlash tool for certificate programming. -Limitations -*********** -- While the hardware supports it, IPv6 has yet to be fully implemented - in the SimpleLink Wi-Fi device driver in Zephyr. - References ********** diff --git a/boards/arm/cc3220sf_launchxl/pinmux.c b/boards/arm/cc3220sf_launchxl/pinmux.c index 3b2c13ed2376be..80ffb514204b35 100644 --- a/boards/arm/cc3220sf_launchxl/pinmux.c +++ b/boards/arm/cc3220sf_launchxl/pinmux.c @@ -91,7 +91,7 @@ #define I2C_CC32XX_PIN_16_I2C_SCL 0x90F /*!< PIN 16 is used for I2C_SCL */ #define I2C_CC32XX_PIN_17_I2C_SDA 0x910 /*!< PIN 17 is used for I2C_SDA */ -int pinmux_initialize(struct device *port) +int pinmux_initialize(const struct device *port) { ARG_UNUSED(port); diff --git a/boards/arm/cc3235sf_launchxl/cc3235sf_launchxl_defconfig b/boards/arm/cc3235sf_launchxl/cc3235sf_launchxl_defconfig index b0c1b5bd2a163d..9c35397b31eac9 100644 --- a/boards/arm/cc3235sf_launchxl/cc3235sf_launchxl_defconfig +++ b/boards/arm/cc3235sf_launchxl/cc3235sf_launchxl_defconfig @@ -3,6 +3,7 @@ CONFIG_BOARD_CC3235SF_LAUNCHXL=y CONFIG_SOC_SERIES_CC32XX=y CONFIG_SOC_CC3235SF=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_PRINTK=y diff --git a/boards/arm/cc3235sf_launchxl/doc/index.rst b/boards/arm/cc3235sf_launchxl/doc/index.rst index c35f88a3a4828e..7dc7ccc75195b5 100644 --- a/boards/arm/cc3235sf_launchxl/doc/index.rst +++ b/boards/arm/cc3235sf_launchxl/doc/index.rst @@ -214,7 +214,7 @@ To see program output from UART0, connect a separate terminal window: Then press the reset button (SW1) on the board to run the program. -When using OpenOCD from Zephyr SDK 0.10.2 to flash the device, you may notice +When using OpenOCD from Zephyr SDK to flash the device, you may notice the program hangs when starting the network processor on the device, if the program uses it. There is a known issue with how that version of OpenOCD resets the network processor. You would need to manually hit the reset button diff --git a/boards/arm/cc3235sf_launchxl/pinmux.c b/boards/arm/cc3235sf_launchxl/pinmux.c index 7892075cc13f56..032a42fb01f28d 100644 --- a/boards/arm/cc3235sf_launchxl/pinmux.c +++ b/boards/arm/cc3235sf_launchxl/pinmux.c @@ -66,7 +66,7 @@ #define I2C_CC32XX_PIN_16_I2C_SCL 0x90F /*!< PIN 16 is used for I2C_SCL */ #define I2C_CC32XX_PIN_17_I2C_SDA 0x910 /*!< PIN 17 is used for I2C_SDA */ -int pinmux_initialize(struct device *port) +int pinmux_initialize(const struct device *port) { ARG_UNUSED(port); diff --git a/boards/arm/circuitdojo_feather_nrf9160/CMakeLists.txt b/boards/arm/circuitdojo_feather_nrf9160/CMakeLists.txt new file mode 100644 index 00000000000000..218a0602483ab4 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/CMakeLists.txt @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(board.c) diff --git a/boards/arm/circuitdojo_feather_nrf9160/Kconfig b/boards/arm/circuitdojo_feather_nrf9160/Kconfig new file mode 100644 index 00000000000000..78e7bbd4530c07 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/Kconfig @@ -0,0 +1,5 @@ +# Circuit Dojo nRF9160 Feather configuration + +# Copyright (c) 2018-2020 Nordic Semiconductor ASA +# Copyright (c) 2020 Circuit Dojo LLC +# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/arm/circuitdojo_feather_nrf9160/Kconfig.board b/boards/arm/circuitdojo_feather_nrf9160/Kconfig.board new file mode 100644 index 00000000000000..302f47c058b00c --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/Kconfig.board @@ -0,0 +1,15 @@ +# Circuit Dojo nRF9160 Feather configuration + +# Copyright (c) 2018-2020 Nordic Semiconductor ASA +# Copyright (c) 2020 Circuit Dojo LLC +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF9160_SICA + +config BOARD_CIRCUITDOJO_FEATHER_NRF9160 + bool "Circuit Dojo nRF9160 Feather" + +config BOARD_CIRCUITDOJO_FEATHER_NRF9160NS + bool "Circuit Dojo nRF9160 Feather non-secure" + +endif # SOC_NRF9160_SICA diff --git a/boards/arm/circuitdojo_feather_nrf9160/Kconfig.defconfig b/boards/arm/circuitdojo_feather_nrf9160/Kconfig.defconfig new file mode 100644 index 00000000000000..100da17fd25ab3 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/Kconfig.defconfig @@ -0,0 +1,39 @@ +# Circuit Dojo nRF9160 Feather configuration + +# Copyright (c) 2018-2020 Nordic Semiconductor ASA +# Copyright (c) 2020 Circuit Dojo LLC +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_CIRCUITDOJO_FEATHER_NRF9160 || BOARD_CIRCUITDOJO_FEATHER_NRF9160NS + +config BOARD + default "circuitdojo_feather_nrf9160" + +# For the secure version of the board the firmware is linked at the beginning +# of the flash, or into the code-partition defined in DT if it is intended to +# be loaded by MCUboot. If the secure firmware is to be combined with a non- +# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always +# be restricted to the size of its code partition. +# For the non-secure version of the board, the firmware +# must be linked into the code-partition (non-secure) defined in DT, regardless. +# Apply this configuration below by setting the Kconfig symbols used by +# the linker according to the information extracted from DT partitions. + +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + depends on BOARD_CIRCUITDOJO_FEATHER_NRF9160 && TRUSTED_EXECUTION_SECURE + +if BOARD_CIRCUITDOJO_FEATHER_NRF9160NS + +config FLASH_LOAD_OFFSET + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +endif # BOARD_CIRCUITDOJO_FEATHER_NRF9160NS + +endif # BOARD_CIRCUITDOJO_FEATHER_NRF9160 || BOARD_CIRCUITDOJO_FEATHER_NRF9160NS diff --git a/boards/arm/circuitdojo_feather_nrf9160/board.c b/boards/arm/circuitdojo_feather_nrf9160/board.c new file mode 100644 index 00000000000000..097d5d498a64ce --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/board.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 Circuit Dojo LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define GPIO0 DT_LABEL(DT_NODELABEL(gpio0)) +#define POWER_LATCH_PIN 31 + +static int board_circuitdojo_feather_nrf9160_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + /* Get the device binding */ + const struct device *gpio = device_get_binding(GPIO0); + if (gpio == NULL) { + return -ENODEV; + } + + /* Configure latch pin as output. */ + gpio_pin_configure(gpio, POWER_LATCH_PIN, GPIO_OUTPUT_HIGH); + + return 0; +} + +/* needs to be done after GPIO driver init */ +SYS_INIT(board_circuitdojo_feather_nrf9160_init, POST_KERNEL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/boards/arm/circuitdojo_feather_nrf9160/board.cmake b/boards/arm/circuitdojo_feather_nrf9160/board.cmake new file mode 100644 index 00000000000000..4556a8aa9b2eba --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=cortex-m33" "--speed=4000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160.dts b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160.dts new file mode 100644 index 00000000000000..e32332c27eea13 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-2020 Nordic Semiconductor ASA + * Copyright (c) 2020 Circuit Dojo LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "circuitdojo_feather_nrf9160_common.dts" + +/ { + chosen { + zephyr,sram = &sram0_s; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,sram-secure-partition = &sram0_s; + zephyr,sram-non-secure-partition = &sram0_ns; + }; +}; diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160.yaml b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160.yaml new file mode 100644 index 00000000000000..05fd7a44189965 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160.yaml @@ -0,0 +1,15 @@ +identifier: circuitdojo_feather_nrf9160 +name: CircuitDojo-Feather-nRF9160 +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 64 +flash: 256 +supported: + - i2c + - pwm + - watchdog + - counter diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dts b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dts new file mode 100644 index 00000000000000..78081106b6cdd0 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dts @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2018-2020 Nordic Semiconductor ASA + * Copyright (c) 2020 Circuit Dojo LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + model = "Circuit Dojo nRF9160 Feather"; + compatible = "circuitdojo,feather-nrf9160"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + }; + + leds { + compatible = "gpio-leds"; + blue_led: led_0 { + gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; + label = "Blue LED (D7)"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm0 3>; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Switch 1"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &blue_led; + pwm-led0 = &pwm_led0; + sw0 = &button0; + }; + + /* Used for accessing other pins */ + feather_header: feather_connector { + compatible = "adafruit-feather-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <12 0 &gpio0 26 0>, /* SDA */ + <13 0 &gpio0 27 0>, /* SCL */ + <14 0 &gpio0 29 0>, /* PWM3 */ + <15 0 &gpio0 30 0>, /* PWM3 */ + <16 0 &gpio0 0 0>, /* PWM1 */ + <17 0 &gpio0 1 0>, /* PWM1 */ + <18 0 &gpio0 2 0>, /* PWM1 */ + <19 0 &gpio0 3 0>, /* PWM0 */ + <20 0 &gpio0 4 0>, /* PWM1 */ + /* 11 not connected */ + <10 0 &gpio0 24 0>, /* TX */ + <9 0 &gpio0 23 0>, /* RX */ + <8 0 &gpio0 22 0>, /* MISO */ + <7 0 &gpio0 21 0>, /* MOSI */ + <6 0 &gpio0 19 0>, /* SCK */ + <5 0 &gpio0 18 0>, /* SS */ + <4 0 &gpio0 17 0>, /* ADC4 = AIN6 */ + <3 0 &gpio0 16 0>, /* ADC3 = AIN5 */ + <2 0 &gpio0 15 0>, /* ADC2 = AIN4 */ + <1 0 &gpio0 14 0>, /* ADC1 = AIN2 */ + <0 0 &gpio0 13 0>; /* ADC0 = AIN1 */ + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + tx-pin = <6>; + rx-pin = <5>; +}; + +&uart1 { + current-speed = <115200>; + tx-pin = <0>; + rx-pin = <1>; +}; + +&uart2 { + tx-pin = <24>; + rx-pin = <23>; +}; + +&i2c1 { + compatible = "nordic,nrf-twim"; + status = "okay"; + sda-pin = <26>; + scl-pin = <27>; + + pcf85063a@51 { + compatible = "nxp,pcf85063a"; + label = "PCF85063A"; + reg = <0x51>; + }; + +}; + +&pwm0 { + status = "okay"; + ch0-pin = <3>; +}; + +&spi3 { + compatible = "nordic,nrf-spim"; + status = "okay"; + sck-pin = <11>; + mosi-pin = <9>; + miso-pin = <28>; + cs-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; + w25q16jv: w25q16jv@0 { + compatible = "jedec,spi-nor"; + label = "W25Q16JV"; + reg = <0>; + spi-max-frequency = <40000000>; + wp-gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; + hold-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + size = <0x1000000>; + has-dpd; + t-enter-dpd = <4000>; + t-exit-dpd = <25000>; + jedec-id = [ef 40 15]; + has-be32k; + }; +}; + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&timer2 { + status = "okay"; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x10000>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + }; + slot0_ns_partition: partition@40000 { + label = "image-0-nonsecure"; + }; + slot1_partition: partition@80000 { + label = "image-1"; + }; + slot1_ns_partition: partition@b0000 { + label = "image-1-nonsecure"; + }; + scratch_partition: partition@f0000 { + label = "image-scratch"; + reg = <0x000f0000 0xa000>; + }; + storage_partition: partition@fa000 { + label = "storage"; + reg = <0x000fa000 0x00006000>; + }; + }; +}; + +/ { + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + }; + + sram0_bsd: image_bsd@20010000 { + /* BSD (shared) memory */ + }; + + sram0_ns: image_ns@20020000 { + /* Non-Secure image memory */ + }; + }; +}; + +/ { + vbatt { + compatible = "voltage-divider"; + io-channels = <&adc 7>; + output-ohms = <100000>; + full-ohms = <(100000 + 100000)>; + power-gpios = <&gpio0 25 0>; + }; +}; + +/* Include partition configuration file */ +#include "circuitdojo_feather_nrf9160_partition_conf.dts" diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_defconfig b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_defconfig new file mode 100644 index 00000000000000..e19cf6c4df1138 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF91X=y +CONFIG_SOC_NRF9160_SICA=y +CONFIG_BOARD_CIRCUITDOJO_FEATHER_NRF9160=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dts b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dts new file mode 100644 index 00000000000000..e8cb6fc586e237 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_partition_conf.dts @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018-2020 Nordic Semiconductor ASA + * Copyright (c) 2020 Circuit Dojo LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Default Flash planning for circuitdojo_feather_nrf9160. + * + * Zephyr build for nRF9160 with ARM TrustZone-M support, + * implies building Secure and Non-Secure Zephyr images. + * + * Secure image will be placed, by default, in flash0 + * (or in slot0, if MCUboot is present). + * Secure image will use sram0 for system memory. + * + * Non-Secure image will be placed in slot0_ns, and use + * sram0_ns for system memory. + * + * Note that the Secure image only requires knowledge of + * the beginning of the Non-Secure image (not its size). + */ + +&slot0_partition { + reg = <0x00010000 0x30000>; +}; + +&slot0_ns_partition { + reg = <0x00040000 0x40000>; +}; + +&slot1_partition { + reg = <0x00080000 0x30000>; +}; + +&slot1_ns_partition { + reg = <0x000b0000 0x40000>; +}; + +/* Default SRAM planning when building for nRF9160 with + * ARM TrustZone-M support + * - Lowest 64 kB SRAM allocated to Secure image (sram0_s). + * - 64 kB SRAM reserved for and used by the BSD socket + * library (sram0_bsd). + * - Upper 128 kB allocated to Non-Secure image (sram0_ns). + */ + +&sram0_s { + reg = <0x20000000 DT_SIZE_K(64)>; +}; + +&sram0_bsd { + reg = <0x20010000 DT_SIZE_K(64)>; +}; + +&sram0_ns { + reg = <0x20020000 DT_SIZE_K(128)>; +}; diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160ns.dts b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160ns.dts new file mode 100644 index 00000000000000..5a0df90c0cf2bf --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160ns.dts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018-2020 Nordic Semiconductor ASA + * Copyright (c) 2020 Circuit Dojo LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "circuitdojo_feather_nrf9160_common.dts" + +/ { + chosen { + zephyr,flash = &flash0; + zephyr,sram = &sram0_ns; + zephyr,code-partition = &slot0_ns_partition; + }; +}; diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160ns.yaml b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160ns.yaml new file mode 100644 index 00000000000000..2b550df02ffbae --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160ns.yaml @@ -0,0 +1,14 @@ +identifier: circuitdojo_feather_nrf9160ns +name: CircuitDojo-Feather-nRF9160-Non-Secure +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 128 +flash: 256 +supported: + - i2c + - pwm + - watchdog diff --git a/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160ns_defconfig b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160ns_defconfig new file mode 100644 index 00000000000000..0df8c97ff4a7e0 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160ns_defconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF91X=y +CONFIG_SOC_NRF9160_SICA=y +CONFIG_BOARD_CIRCUITDOJO_FEATHER_NRF9160NS=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# This Board implies building Non-Secure firmware +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/circuitdojo_feather_nrf9160/doc/img/circuitdojo_feather_nrf9160.png b/boards/arm/circuitdojo_feather_nrf9160/doc/img/circuitdojo_feather_nrf9160.png new file mode 100644 index 00000000000000..238a06e09733cb Binary files /dev/null and b/boards/arm/circuitdojo_feather_nrf9160/doc/img/circuitdojo_feather_nrf9160.png differ diff --git a/boards/arm/circuitdojo_feather_nrf9160/doc/img/nrf9160-feather-v31-features.png b/boards/arm/circuitdojo_feather_nrf9160/doc/img/nrf9160-feather-v31-features.png new file mode 100644 index 00000000000000..6b21a746620d28 Binary files /dev/null and b/boards/arm/circuitdojo_feather_nrf9160/doc/img/nrf9160-feather-v31-features.png differ diff --git a/boards/arm/circuitdojo_feather_nrf9160/doc/index.rst b/boards/arm/circuitdojo_feather_nrf9160/doc/index.rst new file mode 100644 index 00000000000000..ffd1d6a44ea0b1 --- /dev/null +++ b/boards/arm/circuitdojo_feather_nrf9160/doc/index.rst @@ -0,0 +1,159 @@ +.. _circuitdojo_feather_nrf9160: + +nRF9160 Feather +############### + +.. figure:: img/circuitdojo_feather_nrf9160.png + :width: 711px + :align: center + :alt: Circuit Dojo nRF9160 Feather + + nRF9160 Feather (Credit: Circuit Dojo) + +Overview +******** + +The nRF9160 Feather by Circuit Dojo is a single-board development +for bringing your LTE-M and NB-IoT applications to life. The circuitdojo_feather_nrf9160 +board configuration leverages the pre-existing support for the Nordic Semiconductor +nRF9160. Supported nRF9160 peripherals include: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UARTE (Universal asynchronous receiver-transmitter with EasyDMA)` +* :abbr:`WDT (Watchdog Timer)` +* :abbr:`IDAU (Implementation Defined Attribution Unit)` + +More information about the board can be found at the +`nRF9160 Feather Documentation`_. + + +Hardware +******** + +.. figure:: img/nrf9160-feather-v31-features.png + :width: 711px + :align: center + :alt: nRF9160 Feather Features + +Connections and IOs +=================== + +The nRF9160 Feather has everything you know and love about +the Feather platform. Here are some of the highlights: + +LED +--- + +* D7 (blue) = P0.03 + +Push buttons and Switches +------------------------- + +* MODE = P0.12 +* RESET + +USB +--- + +Contains a USB/UART connection for both debugging and loading new +code using a UART Enabled MCUBoot. + +Standard Battery Connection +---------------------------- + +The nRF9160 Feather has a 2 pin battery connector on board. Lithium Polymer batteries > +300mA required. + +Nano SIM Holder +--------------- + +The nRF9160 Feather has a built-in nano SIM (4FF) holder located +on the bottom side. + + +Programming and Debugging +************************* + +circuitdojo_feather_nrf9160 has a Tag Connect TC2030-CTX-NL. It can be used +by most programmers like: + +* J-Link (the nRF53-DK is recommended) +* CMSIS-DAP based programmers + +Check out `Getting Started`_ for more info. + +Building an application +======================= + +In most cases you'll want to use the ``ns`` target with any of the Zephyr +or Nordic based examples. Some of the examples do not use secure mode, +so they do not required the ``ns`` suffix. A great example of this is the +`hello_world` below: + +Flashing +======== + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. Then build and flash +applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :ref:`hello_world` application. + +First, run your favorite terminal program to listen for output. + +.. code-block:: console + + $ screen /dev/ 115200 + +Replace :code:`` with the port where the nRF9160 Feather +can be found. In most cases (On Linux/Mac) it will be: :code:`/dev/tty.SLAB_USBtoUART`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: circuitdojo_feather_nrf9160 + :goals: build flash + +Debugging +========= + +Refer to the :ref:`nordic_segger` page to learn about debugging Nordic boards with a +Segger IC. + + +Testing the LEDs and buttons on the nRF9160 Feather +*************************************************** + +There are 2 samples that allow you to test that the buttons (switches) and LEDs on +the board are working properly with Zephyr: + +* :ref:`blinky-sample` +* :ref:`button-sample` + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in +:zephyr_file:`boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dts`. + +References +********** + +.. target-notes:: + +**Side note** This page was based on the documentation for the nRF9160 DK. Thanks to Nordic for +developing a great platform! + +.. _nRF9160 Feather Documentation: https://docs.jaredwolff.com/nrf9160-introduction.html +.. _Getting Started: https://docs.jaredwolff.com/nrf9160-getting-started.html diff --git a/boards/arm/colibri_imx7d_m4/pinmux.c b/boards/arm/colibri_imx7d_m4/pinmux.c index 3ce4a3ba07c4bb..833a2685dfb610 100644 --- a/boards/arm/colibri_imx7d_m4/pinmux.c +++ b/boards/arm/colibri_imx7d_m4/pinmux.c @@ -7,7 +7,7 @@ #include #include "device_imx.h" -static int colibri_imx7d_m4_pinmux_init(struct device *dev) +static int colibri_imx7d_m4_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/cy8ckit_062_ble/Kconfig.board b/boards/arm/cy8ckit_062_ble/Kconfig.board new file mode 100644 index 00000000000000..6b7dd89566f6e0 --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/Kconfig.board @@ -0,0 +1,13 @@ +# PSoC6 BLE Pioneer Kit configuration + +# Copyright (c) 2018 Cypress +# Copyright (c) 2020 ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CY8CKIT_062_BLE_M0 + bool "PSoC6 BLE Pioneer Kit [M0 CPU0]" + depends on SOC_PART_NUMBER_CY8C6347BZI_BLD53 + +config BOARD_CY8CKIT_062_BLE_M4 + bool "PSoC6 BLE Pioneer Kit [M4 CPU1]" + depends on SOC_PART_NUMBER_CY8C6347BZI_BLD53 diff --git a/boards/arm/cy8ckit_062_ble/Kconfig.defconfig b/boards/arm/cy8ckit_062_ble/Kconfig.defconfig new file mode 100644 index 00000000000000..3b8d280572dffc --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/Kconfig.defconfig @@ -0,0 +1,23 @@ +# PSoC6 BLE Pioneer Kit configuration + +# Copyright (c) 2018 Cypress +# Copyright (c) 2020 ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_CY8CKIT_062_BLE_M0 || \ + BOARD_CY8CKIT_062_BLE_M4 + +config BOARD + default "cy8ckit_062_ble_m0" if BOARD_CY8CKIT_062_BLE_M0 + default "cy8ckit_062_ble_m4" if BOARD_CY8CKIT_062_BLE_M4 + +config UART_PSOC6_UART_5 + default y + depends on UART_PSOC6 + +config UART_PSOC6_UART_6 + default y + depends on UART_PSOC6 + +endif # BOARD_CY8CKIT_062_BLE_M0 || \ + # BOARD_CY8CKIT_062_BLE_M4 diff --git a/boards/arm/cy8ckit_062_ble/board.cmake b/boards/arm/cy8ckit_062_ble/board.cmake new file mode 100644 index 00000000000000..f04a18a669790d --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/board.cmake @@ -0,0 +1,16 @@ +# +# Copyright (c) 2018, Cypress +# Copyright (c) 2020, ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +if(CONFIG_BOARD_CY8CKIT_062_BLE_M0) +board_runner_args(jlink "--device=CY8C6xx7_CM0p" "--speed=2000") +endif() +if(CONFIG_BOARD_CY8CKIT_062_BLE_M4) +board_runner_args(jlink "--device=CY8C6xx7_CM4" "--speed=2000") +endif() + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.dts b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.dts new file mode 100644 index 00000000000000..47fd2ca56cc4ab --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.dts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018, Cypress + * Copyright (c) 2020, ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "Cypress PSoC6 BLE Pioneer Kit"; + compatible = "cypress,cy8c6xx7_cm0p", "cypress,psoc6"; + + aliases { + uart-5 = &uart5; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart5; + zephyr,shell-uart = &uart5; + }; +}; + +&uart5 { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.yaml b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.yaml new file mode 100644 index 00000000000000..807c3ea2c986b2 --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0.yaml @@ -0,0 +1,17 @@ +# +# Copyright (c) 2018, Cypress +# Copyright (c) 2020, ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: cy8ckit_062_ble_m0 +name: Cypress PSoC6 BLE Pioneer Kit +type: mcu +arch: arm +ram: 288 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb + - xtools diff --git a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0_defconfig b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0_defconfig new file mode 100644 index 00000000000000..8a059702b63ece --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0_defconfig @@ -0,0 +1,19 @@ +# +# Copyright (c) 2018, Cypress +# Copyright (c) 2020, ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_PSOC63=y +CONFIG_SOC_PSOC6_M0=y +CONFIG_SOC_PART_NUMBER_CY8C6347BZI_BLD53=y +CONFIG_BOARD_CY8CKIT_062_BLE_M0=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_PRINTK=y +CONFIG_BUILD_OUTPUT_HEX=y + +# UART driver +CONFIG_SERIAL=y diff --git a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.dts b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.dts new file mode 100644 index 00000000000000..2966ff21fb3cc6 --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.dts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018, Cypress + * Copyright (c) 2020, ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "Cypress PSoC6 BLE Pioneer Kit"; + compatible = "cypress,cy8c6xx7_cm4", "cypress,psoc6"; + + aliases { + uart-6 = &uart6; + }; + + chosen { + zephyr,sram = &sram2; + zephyr,flash = &flash1; + zephyr,console = &uart6; + zephyr,shell-uart = &uart6; + }; +}; + +&uart6 { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.yaml b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.yaml new file mode 100644 index 00000000000000..fb179209eb5e35 --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4.yaml @@ -0,0 +1,17 @@ +# +# Copyright (c) 2018, Cypress +# Copyright (c) 2020, ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: cy8ckit_062_ble_m4 +name: Cypress PSoC6 BLE Pioneer Kit +type: mcu +arch: arm +ram: 288 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb + - xtools diff --git a/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4_defconfig b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4_defconfig new file mode 100644 index 00000000000000..d373a49ea6157e --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4_defconfig @@ -0,0 +1,19 @@ +# +# Copyright (c) 2018, Cypress +# Copyright (c) 2020, ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_PSOC63=y +CONFIG_SOC_PSOC6_M4=y +CONFIG_SOC_PART_NUMBER_CY8C6347BZI_BLD53=y +CONFIG_BOARD_CY8CKIT_062_BLE_M4=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_PRINTK=y +CONFIG_BUILD_OUTPUT_HEX=y + +# UART driver +CONFIG_SERIAL=y diff --git a/boards/arm/cy8ckit_062_ble/doc/img/cy8ckit-062-ble.jpg b/boards/arm/cy8ckit_062_ble/doc/img/cy8ckit-062-ble.jpg new file mode 100644 index 00000000000000..82f2996df957d8 Binary files /dev/null and b/boards/arm/cy8ckit_062_ble/doc/img/cy8ckit-062-ble.jpg differ diff --git a/boards/arm/cy8ckit_062_ble/doc/index.rst b/boards/arm/cy8ckit_062_ble/doc/index.rst new file mode 100644 index 00000000000000..7084f45e6d072a --- /dev/null +++ b/boards/arm/cy8ckit_062_ble/doc/index.rst @@ -0,0 +1,194 @@ +.. _cy8ckit_062_ble: + +PSoC63 BLE Pioneer Kit +###################### + +Overview +******** + +The PSoC 6 BLE Pioneer Kit (CY8CKIT-062-BLE) is a hardware platform that +enables design and debug of the Cypress PSoC 63 BLE MCU. + +The PSoC 6 BLE Pioneer Kit features the PSoC 63 MCU: a dual-core MCU, with a +150-MHz Arm Cortex-M4 as the primary application processor and a 100-MHz Arm +Cortex-M0+ that supports low-power operations, 1MB of Flash, 288KB of SRAM, +an integrated BLE 4.2 radio, 78 GPIO, 7 programmable analog blocks, 12 +programmable digital blocks, and capacitive-sensing with CapSense. + +The PSoC 6 BLE Pioneer board offers compatibility with Arduino shields, a +512-Mb NOR flash, onboard programmer/debugger (KitProg2), USB Type-C power +delivery system (EZ-PD™ CCG3), 5-segment CapSense slider, two CapSense +buttons, one CapSense proximity sensing header, an RGB LED, two user LEDs, +and one push button. + +The CY8CKIT-062-BLE package includes a CY8CKIT-028-EPD E-INK Display Shield +that contains a 2.7-inch E-INK display, a motion sensor, a thermistor, and a +PDM microphone. The kit package also contains a CY5677 CySmart BLE 4.2 USB +Dongle that is factory-programmed to emulate a BLE GAP Central device, +enabling you to emulate a BLE host on your computer. + +The Cortex-M0+ is a primary core on the board's SoC. It starts first and +enables the CM4 core. + +.. image:: img/cy8ckit-062-ble.jpg + :width: 887px + :align: center + :alt: CY8CKIT_062_BLE + +1. Battery charging indicator (LED6) +2. USB PD output voltage availability indicator (LED7) +3. KitProg2 USB Type-C connector (J10) +4. Cypress EZ-PD™ CCG3 Type-C Port Controller with PD (CYPD3125-40LQXI, U3) +5. KitProg2 programming mode selection button (SW3) +6. KitProg2 I/O header (J6)1 +7. KitProg2 programming/custom application header (J7)1 +8. External power supply connector (J9) +9. PSoC 6 BLE user button (SW2) +10. KitProg2 application selection button (SW4) +11. Digilent® Pmod™ compatible I/O header (J14)1 +12. Power LED (LED4) +13. KitProg2 status LEDs (LED1, LED2, and LED3) +14. PSoC 6 reset button (SW1) +15. PSoC 6 I/O header (J18, J19 and J20) +16. Arduino™ Uno R3 compatible power header (J1) +17. PSoC 6 debug and trace header (J12) +18. Arduino Uno R3 compatible PSoC 6 I/O header (J2, J3 and J4) +19. PSoC 6 program and debug header (J11) +20. KitProg2 programming target selection switch (SW6) +21. CapSense slider and buttons +22. CapSense proximity header (J13) +23. PSoC 6 BLE VDD selection switch (SW5) +24. PSoC 6 BLE power monitoring jumper (J8)2 +25. Arduino Uno R3 compatible ICSP header (J5)1 +26. PSoC 6 user LEDs (LED8 and LED9) +27. RGB LED (LED5) +28. Cypress 512-Mbit serial NOR Flash memory (S25FL512S, U4) +29. Cypress serial Ferroelectric RAM (U5)1 +30. VBACKUP and PMIC control selection switch (SW7)2 +31. Cypress PSoC 6 BLE (CY8C6347BZI-BLD53, U1) +32. BLE Antenna +33. U.FL connector for external antenna (J17)1 +34. Cypress main voltage regulator (MB39C022G, U6) +35. KitProg2 (PSoC 5LP) programmer and debugger(CY8C5868LTI-LP039, U2) +36. Battery connector (J15)1,2 +37. USB PD output voltage (9V/12V) connector (J16) + +Hardware +******** + +For more information about the PSoC 63 BLE MCU SoC and CY8CKIT-062-BLE board: + +- `PSoC 63 BLE MCU SoC Website`_ +- `PSoC 63 BLE MCU Datasheet`_ +- `PSoC 63 BLE MCU Architecture Reference Manual`_ +- `PSoC 63 BLE MCU Register Reference Manual`_ +- `CY8CKIT-062-BLE Website`_ +- `CY8CKIT-062-BLE User Guide`_ +- `CY8CKIT-062-BLE Schematics`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| NVIC | on-chip | nested vectored | +| | | interrupt controller | ++-----------+------------+----------------------+ +| SYSTICK | on-chip | system clock | ++-----------+------------+----------------------+ +| UART | on-chip | serial port-polling | ++-----------+------------+----------------------+ + + +The default configurations can be found in the Kconfig +:zephyr_file:`boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m0_defconfig` for +Cortex-M0+ and on the Kconfig +:zephyr_file:`boards/arm/cy8ckit_062_ble/cy8ckit_062_ble_m4_defconfig` for +Cortex-M4 + +System Clock +============ + +The PSoC 63 BLE MCU SoC is configured to use the internal IMO+FLL as a source for +the system clock. CM0+ works at 50MHz, CM4 - at 100MHz. Other sources for the +system clock are provided in the SOC, depending on your system requirements. + +Serial Port +=========== + +The PSoC 63 BLE MCU SoC has 8 SCB blocks and each one can be configured as +UART/SPI/I2C interfaces for serial communication. At the moment UART5 on SCB5 +and UART6 on SCB6 are configured. SCB5 is connected to the onboard KitProg2's +USB-UART Bridge working as a serial console interface. SCB6 to P13_0, P13_1 +pins on the J3 of the Arduino Uno R3 compatible PSoC6 I/O header for general +purposes. + +Programming and Debugging +************************* + +The CY8CKIT-062-BLE includes an onboard programmer/debugger (KitProg2) with +mass storage programming to provide debugging, flash programming, and serial +communication over USB. There are also PSoC 6 program and debug headers J11 +and J12 that can be used with Segger J-Link [default]. +A watchdog timer is enabled by default. To disable it call Cy_WDT_Unlock() and +Cy_WDT_Disable(). + +#. Build the Zephyr kernel and the :ref:`hello_world` sample application: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cy8ckit_062_ble_m0 + :goals: build + :compact: + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyACM0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyACM0 -o + + The -o option tells minicom not to send the modem initialization + string. Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + +#. To flash an image: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cy8ckit_062_ble_m0 + :goals: flash + :compact: + + You should see "Hello World! cy8ckit_062_ble_m0" in your terminal. + +References +********** + +.. _PSoC 63 BLE MCU SoC Website: + https://www.cypress.com/products/32-bit-arm-cortex-m4-cortex-m0-psoc-63-connectivity-line + +.. _PSoC 63 BLE MCU Datasheet: + https://www.cypress.com/documentation/datasheets/psoc-6-mcu-psoc-63-ble-datasheet-programmable-system-chip-psoc + +.. _PSoC 63 BLE MCU Architecture Reference Manual: + https://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-63-ble-architecture-technical-reference + +.. _PSoC 63 BLE MCU Register Reference Manual: + https://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-cy8c63x6-cy8c63x7-cy8c63x6-cy8c63x7-registers + +.. _CY8CKIT-062-BLE Website: + https://www.cypress.com/documentation/development-kitsboards/psoc-6-ble-pioneer-kit-cy8ckit-062-ble + +.. _CY8CKIT-062-BLE User Guide: + https://www.cypress.com/file/390496/download + +.. _CY8CKIT-062-BLE Schematics: + https://www.cypress.com/file/417021/download diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/support/openocd.cfg b/boards/arm/cy8ckit_062_ble/support/openocd.cfg similarity index 100% rename from boards/arm/cy8ckit_062_wifi_bt_m0/support/openocd.cfg rename to boards/arm/cy8ckit_062_ble/support/openocd.cfg diff --git a/boards/arm/cy8ckit_062_wifi_bt/Kconfig.board b/boards/arm/cy8ckit_062_wifi_bt/Kconfig.board new file mode 100644 index 00000000000000..62f30b443d2171 --- /dev/null +++ b/boards/arm/cy8ckit_062_wifi_bt/Kconfig.board @@ -0,0 +1,13 @@ +# PSoC6 WiFi-BT Pioneer Kit configuration + +# Copyright (c) 2018 Cypress +# Copyright (c) 2020 ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CY8CKIT_062_WIFI_BT_M0 + bool "PSoC6 WiFi-BT Pioneer Kit M0" + depends on SOC_PART_NUMBER_CY8C6247BZI_D54 + +config BOARD_CY8CKIT_062_WIFI_BT_M4 + bool "PSoC6 WiFi-BT Pioneer Kit M4" + depends on SOC_PART_NUMBER_CY8C6247BZI_D54 diff --git a/boards/arm/cy8ckit_062_wifi_bt/Kconfig.defconfig b/boards/arm/cy8ckit_062_wifi_bt/Kconfig.defconfig new file mode 100644 index 00000000000000..c54e8908e3c883 --- /dev/null +++ b/boards/arm/cy8ckit_062_wifi_bt/Kconfig.defconfig @@ -0,0 +1,22 @@ +# PSoC6 WiFi-BT Pioneer Kit configuration + +# Copyright (c) 2020 ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_CY8CKIT_062_WIFI_BT_M0 || \ + BOARD_CY8CKIT_062_WIFI_BT_M4 + +config BOARD + default "cy8ckit_062_wifi_bt_m0" if BOARD_CY8CKIT_062_WIFI_BT_M0 + default "cy8ckit_062_wifi_bt_m4" if BOARD_CY8CKIT_062_WIFI_BT_M4 + +config UART_PSOC6_UART_5 + default y + depends on UART_PSOC6 + +config UART_PSOC6_UART_6 + default y + depends on UART_PSOC6 + +endif # BOARD_CY8CKIT_062_WIFI_BT_M0 || \ + # BOARD_CY8CKIT_062_WIFI_BT_M4 diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/board.cmake b/boards/arm/cy8ckit_062_wifi_bt/board.cmake similarity index 100% rename from boards/arm/cy8ckit_062_wifi_bt_m0/board.cmake rename to boards/arm/cy8ckit_062_wifi_bt/board.cmake diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/cy8ckit_062_wifi_bt_m0.dts b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.dts similarity index 100% rename from boards/arm/cy8ckit_062_wifi_bt_m0/cy8ckit_062_wifi_bt_m0.dts rename to boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.dts diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/cy8ckit_062_wifi_bt_m0.yaml b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.yaml similarity index 100% rename from boards/arm/cy8ckit_062_wifi_bt_m0/cy8ckit_062_wifi_bt_m0.yaml rename to boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0.yaml diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/cy8ckit_062_wifi_bt_m0_defconfig b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0_defconfig similarity index 92% rename from boards/arm/cy8ckit_062_wifi_bt_m0/cy8ckit_062_wifi_bt_m0_defconfig rename to boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0_defconfig index f79205f40df912..c5c95112527764 100644 --- a/boards/arm/cy8ckit_062_wifi_bt_m0/cy8ckit_062_wifi_bt_m0_defconfig +++ b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m0_defconfig @@ -9,10 +9,10 @@ CONFIG_SOC_PSOC6_M0=y CONFIG_SOC_PART_NUMBER_CY8C6247BZI_D54=y CONFIG_BOARD_CY8CKIT_062_WIFI_BT_M0=y CONFIG_CORTEX_M_SYSTICK=y -CONFIG_PINMUX=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_PRINTK=y +CONFIG_BUILD_OUTPUT_HEX=y # UART driver CONFIG_SERIAL=y diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/cy8ckit_062_wifi_bt_m4.dts b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.dts similarity index 100% rename from boards/arm/cy8ckit_062_wifi_bt_m4/cy8ckit_062_wifi_bt_m4.dts rename to boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.dts diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/cy8ckit_062_wifi_bt_m4.yaml b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.yaml similarity index 100% rename from boards/arm/cy8ckit_062_wifi_bt_m4/cy8ckit_062_wifi_bt_m4.yaml rename to boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4.yaml diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/cy8ckit_062_wifi_bt_m4_defconfig b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4_defconfig similarity index 92% rename from boards/arm/cy8ckit_062_wifi_bt_m4/cy8ckit_062_wifi_bt_m4_defconfig rename to boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4_defconfig index 2c977eab0d4284..360b63d8016f2a 100644 --- a/boards/arm/cy8ckit_062_wifi_bt_m4/cy8ckit_062_wifi_bt_m4_defconfig +++ b/boards/arm/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_m4_defconfig @@ -9,10 +9,10 @@ CONFIG_SOC_PSOC6_M4=y CONFIG_SOC_PART_NUMBER_CY8C6247BZI_D54=y CONFIG_BOARD_CY8CKIT_062_WIFI_BT_M4=y CONFIG_CORTEX_M_SYSTICK=y -CONFIG_PINMUX=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_PRINTK=y +CONFIG_BUILD_OUTPUT_HEX=y # UART driver CONFIG_SERIAL=y diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/doc/img/cy8ckit_062_wifi_bt_m0.png b/boards/arm/cy8ckit_062_wifi_bt/doc/img/cy8ckit_062_wifi_bt_m0.png similarity index 100% rename from boards/arm/cy8ckit_062_wifi_bt_m0/doc/img/cy8ckit_062_wifi_bt_m0.png rename to boards/arm/cy8ckit_062_wifi_bt/doc/img/cy8ckit_062_wifi_bt_m0.png diff --git a/boards/arm/cy8ckit_062_wifi_bt/doc/index.rst b/boards/arm/cy8ckit_062_wifi_bt/doc/index.rst new file mode 100644 index 00000000000000..24b334d08c40b5 --- /dev/null +++ b/boards/arm/cy8ckit_062_wifi_bt/doc/index.rst @@ -0,0 +1,193 @@ +.. _cy8ckit_062_wifi_bt: + +PSoC6 WiFi-BT Pioneer Kit +######################### + +Overview +******** + +The PSoC 6 WiFi-BT Pioneer Kit (CY8CKIT-062-WiFi-BT) is a low-cost hardware +platform that enables design and debug of the PSoC 62 MCU and the Murata +LBEE5KL1DX Module (CYW4343W WiFi + Bluetooth Combo Chip). + +The PSoC 6 WiFi-BT Pioneer Kit features the PSoC 62 MCU: a +dual-core MCU, with a 150-MHz Arm Cortex-M4 as the primary application +processor and a 100-MHz Arm Cortex-M0+ that supports low-power operations, +1MB of Flash, 288KB of SRAM, 104 GPIO, 7 programmable analog blocks, +56 programmable digital blocks, Full-Speed USB, a serial memory interface, +a PDM-PCM digital microphone interface, and industry-leading capacitive-sensing +with CapSense. + +The PSoC 6 WiFi-BT Pioneer board offers compatibility with Arduino shields. + +The Cortex-M0+ is a primary core on the board's SoC. It starts first and +enables the CM4 core. + +.. image:: img/cy8ckit_062_wifi_bt_m0.png + :width: 887px + :align: center + :alt: CY8CKIT_062_WIFI_BT + +1. USB PD output voltage availability indicator (LED7) +2. Battery charging indicator (LED6) +3. KitProg2 USB Type-C connector (J10) +4. Cypress EZ-PD™ CCG3 Type-C Port Controller with PD (CYPD3125-40LQXI, U3) +5. KitProg2 programming mode selection button (SW3) +6. KitProg2 I/O header (J6)1 +7. KitProg2 programming/custom application header (J7)1 +8. External power supply connector (J9) +9. PSoC 6 user button (SW2) +10. KitProg2 application selection button (SW4) +11. Digilent® Pmod™ compatible I/O header (J14)1 +12. Power LED (LED4) +13. KitProg2 status LEDs (LED1, LED2, and LED3) +14. PSoC 6 reset button (SW1) +15. PSoC 6 I/O header (J18, J19 and J20) +16. Arduino™ Uno R3 compatible power header (J1) +17. PSoC 6 debug and trace header (J12) +18. Arduino Uno R3 compatible PSoC 6 I/O header (J2, J3 and J4) +19. PSoC 6 program and debug header (J11) +20. CapSense proximity header (J13) +21. CapSense slider and buttons +22. PSoC 6 VDD selection switch (SW5) +23. Cypress 512-Mbit serial NOR Flash memory (S25-FL512S, U4) +24. PSoC 6 user LEDs (LED8 and LED9) +25. RGB LED (LED5) +26. WiFi/BT module (LBEE5KL 1DX, U6) +27. Cypress serial Ferroelectric RAM (U5)1 +28. WiFi-BT Antenna +29. VBACKUP and PMIC control selection switch (SW7)2 +30. PSoC 6 USB device Type-C connector (J28) +31. Cypress PSoC 6 (CY8C6247BZI-D54, U1) +32. PSoC 6 USB Host Type-A connector (J27) +33. Arduino Uno R3 compatible ICSP header (J5)1 +34. PSoC 6 power monitoring jumper (J8)2 +35. KitProg2 (PSoC 5LP) programmer and debugger(CY8C5868LTI-LP039, U2) +36. Battery connector (J15)1,2 +37. USB PD output voltage (9V/12V) connector (J16) + +Hardware +******** + +For more information about the PSoC 62 MCU SoC and CY8CKIT-062-WiFi-BT board: + +- `PSoC 62 MCU SoC Website`_ +- `PSoC 62 MCU Datasheet`_ +- `PSoC 62 MCU Architecture Reference Manual`_ +- `PSoC 62 MCU Register Reference Manual`_ +- `CY8CKIT-062-WiFi-BT Website`_ +- `CY8CKIT-062-WiFi-BT User Guide`_ +- `CY8CKIT-062-WiFi-BT Schematics`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| NVIC | on-chip | nested vectored | +| | | interrupt controller | ++-----------+------------+----------------------+ +| SYSTICK | on-chip | system clock | ++-----------+------------+----------------------+ +| UART | on-chip | serial port | ++-----------+------------+----------------------+ + + +The default configuration can be found in the Kconfig +:zephyr_file:`boards/arm/cy8ckit_062_wifi_bt_m0/cy8ckit_062_wifi_bt_m0_defconfig`. + + +System Clock +============ + +The PSoC 62 MCU SoC is configured to use the internal IMO+FLL as a source for +the system clock. CM0+ works at 50MHz, CM4 - at 100MHz. Other sources for the +system clock are provided in the SOC, depending on your system requirements. + +Serial Port +=========== + +The PSoC 62 MCU SoC has 9 SCB blocks 8 of each can be configured as UART +interfaces for serial communication. At the moment UART5 on SCB5 and UART6 on +SCB6 are configured. SCB5 is connected to the onboard KitProg2's USB-UART +Bridge, SCB6 to P12_0, P12_1 pins on the J3 of the Arduino Uno R3 compatible +PSoC6 I/O header. + +Programming and Debugging +************************* + +The CY8CKIT-062-WiFi-BT includes an onboard programmer/debugger (KitProg2) with +mass storage programming to provide debugging, flash programming, and serial +communication over USB. There are also PSoC 6 program and debug headers J11 +and J12 that can be used with Segger J-Link. +A watchdog timer is enabled by default. To disable it call Cy_WDT_Unlock() and +Cy_WDT_Disable(). + +Only the CM0+ core starts by default after the MCU reset. In order to have +CM4 core working FW for both cores should be written into Flash. CM0+ FW +should starts the CM4 core at one point using +Cy_SysEnableCM4(CM4_START_ADDRESS); call. CM4_START_ADDRESS is 0x10060000 in +the current configuration. The CM0+/CM4 Flash/SRAM areas are defined in +:zephyr_file:`dts/arm/cypress/psoc6.dtsi`. + +Build the project for CM0+ + +.. zephyr-app-commands:: + :board: cy8ckit_062_wifi_bt_m0 + :goals: build + +Switch the DevKit into CMSIS-DAP mode using SW3 (LED2 should blink) and flash +the board: + +.. code-block:: console + + $\bin\openocd -c "source [find interface/cmsis-dap.cfg]" \ + -c "transport select swd" -c "source [find target/psoc6.cfg]" \ + -c "if [catch {program {\samples\hello_world\build\zephyr\zephyr.elf}} ] \ + { echo {** Program operation failed **} } \ + else { echo {** Program operation completed successfully **} }" \ + -c "reset_config srst_only;reset run;psoc6.dap dpreg 0x04 0x00;shutdown" + +Switch the DevKit back using SW3. Open a serial terminal (minicom, putty, +etc.) and connect to the board with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and the following message will appear on the corresponding +serial port: + +.. code-block:: console + + ***** Booting Zephyr OS zephyr-v1.13.0-1877-g9d14874db1 ***** + Hello World! cy8ckit_062_wifi_bt_m0 + + +References +********** + +.. _PSoC 62 MCU SoC Website: + http://www.cypress.com/products/32-bit-arm-cortex-m4-psoc-6 + +.. _PSoC 62 MCU Datasheet: + http://www.cypress.com/documentation/datasheets/psoc-6-mcu-psoc-62-datasheet-programmable-system-chip-psoc-preliminary + +.. _PSoC 62 MCU Architecture Reference Manual: + http://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-architecture-technical-reference-manual + +.. _PSoC 62 MCU Register Reference Manual: + http://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-register-technical-reference-manual-trm + +.. _CY8CKIT-062-WiFi-BT Website: + http://www.cypress.com/documentation/development-kitsboards/psoc-6-wifi-bt-pioneer-kit + +.. _CY8CKIT-062-WiFi-BT User Guide: + http://www.cypress.com/file/407731/download + +.. _CY8CKIT-062-WiFi-BT Schematics: + http://www.cypress.com/file/420846/download diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/support/openocd.cfg b/boards/arm/cy8ckit_062_wifi_bt/support/openocd.cfg similarity index 100% rename from boards/arm/cy8ckit_062_wifi_bt_m4/support/openocd.cfg rename to boards/arm/cy8ckit_062_wifi_bt/support/openocd.cfg diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/CMakeLists.txt b/boards/arm/cy8ckit_062_wifi_bt_m0/CMakeLists.txt deleted file mode 100644 index 5fedb5f3030a48..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m0/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2018, Cypress -# -# SPDX-License-Identifier: Apache-2.0 -# - -zephyr_library() -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -zephyr_library_sources_if_kconfig(pinmux.c) diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/Kconfig.board b/boards/arm/cy8ckit_062_wifi_bt_m0/Kconfig.board deleted file mode 100644 index 564868ddf315a1..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m0/Kconfig.board +++ /dev/null @@ -1,8 +0,0 @@ -# PSoC6 WiFi-BT Pioneer Kit configuration - -# Copyright (c) 2018 Cypress -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_CY8CKIT_062_WIFI_BT_M0 - bool "PSoC6 WiFi-BT Pioneer Kit M0" - depends on SOC_PART_NUMBER_CY8C6247BZI_D54 diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/Kconfig.defconfig b/boards/arm/cy8ckit_062_wifi_bt_m0/Kconfig.defconfig deleted file mode 100644 index d46f22ab509253..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m0/Kconfig.defconfig +++ /dev/null @@ -1,15 +0,0 @@ -# PSoC6 WiFi-BT Pioneer Kit configuration - -# Copyright (c) 2018 Cypress -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_CY8CKIT_062_WIFI_BT_M0 - -config BOARD - default "cy8ckit_062_wifi_bt_m0" - -config UART_PSOC6_UART_6 - default y - depends on UART_PSOC6 - -endif # BOARD_CY8CKIT_062_WIFI_BT_M0 diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/doc/index.rst b/boards/arm/cy8ckit_062_wifi_bt_m0/doc/index.rst deleted file mode 100644 index c53ff9479c4a82..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m0/doc/index.rst +++ /dev/null @@ -1,186 +0,0 @@ -.. _cy8ckit_062_wifi_bt: - -PSoC6 WiFi-BT Pioneer Kit (CM0+ Core) -##################################### - -Overview -******** - -The PSoC 6 WiFi-BT Pioneer Kit (CY8CKIT-062-WiFi-BT) is a low-cost hardware -platform that enables design and debug of the PSoC 62 MCU and the Murata -LBEE5KL1DX Module (CYW4343W WiFi + Bluetooth Combo Chip). - -The PSoC 6 WiFi-BT Pioneer Kit features the PSoC 62 MCU: a -dual-core MCU, with a 150-MHz Arm Cortex-M4 as the primary application -processor and a 100-MHz Arm Cortex-M0+ that supports low-power operations, -1MB of Flash, 288KB of SRAM, 104 GPIO, 7 programmable analog blocks, -56 programmable digital blocks, Full-Speed USB, a serial memory interface, -a PDM-PCM digital microphone interface, and industry-leading capacitive-sensing -with CapSense. - -The PSoC 6 WiFi-BT Pioneer board offers compatibility with Arduino shields. - -The Cortex-M0+ is a primary core on the board's SoC. It starts first and -enables the CM4 core. - -.. image:: img/cy8ckit_062_wifi_bt_m0.png - :width: 887px - :align: center - :alt: CY8CKIT_062_WIFI_BT - -1. USB PD output voltage availability indicator (LED7) -2. Battery charging indicator (LED6) -3. KitProg2 USB Type-C connector (J10) -4. Cypress EZ-PD™ CCG3 Type-C Port Controller with PD (CYPD3125-40LQXI, U3) -5. KitProg2 programming mode selection button (SW3) -6. KitProg2 I/O header (J6)1 -7. KitProg2 programming/custom application header (J7)1 -8. External power supply connector (J9) -9. PSoC 6 user button (SW2) -10. KitProg2 application selection button (SW4) -11. Digilent® Pmod™ compatible I/O header (J14)1 -12. Power LED (LED4) -13. KitProg2 status LEDs (LED1, LED2, and LED3) -14. PSoC 6 reset button (SW1) -15. PSoC 6 I/O header (J18, J19 and J20) -16. Arduino™ Uno R3 compatible power header (J1) -17. PSoC 6 debug and trace header (J12) -18. Arduino Uno R3 compatible PSoC 6 I/O header (J2, J3 and J4) -19. PSoC 6 program and debug header (J11) -20. CapSense proximity header (J13) -21. CapSense slider and buttons -22. PSoC 6 VDD selection switch (SW5) -23. Cypress 512-Mbit serial NOR Flash memory (S25-FL512S, U4) -24. PSoC 6 user LEDs (LED8 and LED9) -25. RGB LED (LED5) -26. WiFi/BT module (LBEE5KL 1DX, U6) -27. Cypress serial Ferroelectric RAM (U5)1 -28. WiFi-BT Antenna -29. VBACKUP and PMIC control selection switch (SW7)2 -30. PSoC 6 USB device Type-C connector (J28) -31. Cypress PSoC 6 (CY8C6247BZI-D54, U1) -32. PSoC 6 USB Host Type-A connector (J27) -33. Arduino Uno R3 compatible ICSP header (J5)1 -34. PSoC 6 power monitoring jumper (J8)2 -35. KitProg2 (PSoC 5LP) programmer and debugger(CY8C5868LTI-LP039, U2) -36. Battery connector (J15)1,2 -37. USB PD output voltage (9V/12V) connector (J16) - -Hardware -******** - -For more information about the PSoC 62 MCU SoC and CY8CKIT-062-WiFi-BT board: - -- `PSoC 62 MCU SoC Website`_ -- `PSoC 62 MCU Datasheet`_ -- `PSoC 62 MCU Architecture Reference Manual`_ -- `PSoC 62 MCU Register Reference Manual`_ -- `CY8CKIT-062-WiFi-BT Website`_ -- `CY8CKIT-062-WiFi-BT User Guide`_ -- `CY8CKIT-062-WiFi-BT Schematics`_ - -Supported Features -================== - -The board configuration supports the following hardware features: - -+-----------+------------+----------------------+ -| Interface | Controller | Driver/Component | -+===========+============+======================+ -| NVIC | on-chip | nested vectored | -| | | interrupt controller | -+-----------+------------+----------------------+ -| SYSTICK | on-chip | system clock | -+-----------+------------+----------------------+ -| UART | on-chip | serial port | -+-----------+------------+----------------------+ - - -The default configuration can be found in the Kconfig -:zephyr_file:`boards/arm/cy8ckit_062_wifi_bt_m0/cy8ckit_062_wifi_bt_m0_defconfig`. - - -System Clock -============ - -The PSoC 62 MCU SoC is configured to use the internal IMO+FLL as a source for -the system clock. CM0+ works at 50MHz, CM4 - at 100MHz. Other sources for the -system clock are provided in the SOC, depending on your system requirements. - -Serial Port -=========== - -The PSoC 62 MCU SoC has 9 SCB blocks 8 of each can be configured as UART -interfaces for serial communication. At the moment UART5 on SCB5 and UART6 on -SCB6 are configured. SCB5 is connected to the onboard KitProg2's USB-UART -Bridge, SCB6 to P12_0, P12_1 pins on the J3 of the Arduino Uno R3 compatible -PSoC6 I/O header. - -Programming and Debugging -************************* - -The CY8CKIT-062-WiFi-BT includes an onboard programmer/debugger (KitProg2) with -mass storage programming to provide debugging, flash programming, and serial -communication over USB. There are also PSoC 6 program and debug headers J11 -and J12 that can be used with Segger J-Link. -A watchdog timer is enabled by default. To disable it call Cy_WDT_Unlock() and -Cy_WDT_Disable(). - -Build the project for CM0+ - -.. zephyr-app-commands:: - :board: cy8ckit_062_wifi_bt_m0 - :goals: build - -Switch the DevKit into CMSIS-DAP mode using SW3 (LED2 should blink) and flash -the board: - -.. code-block:: console - - $\bin\openocd -c "source [find interface/cmsis-dap.cfg]" \ - -c "transport select swd" -c "source [find target/psoc6.cfg]" \ - -c "if [catch {program {\samples\hello_world\build\zephyr\zephyr.elf}} ] \ - { echo {** Program operation failed **} } \ - else { echo {** Program operation completed successfully **} }" \ - -c "reset_config srst_only;reset run;psoc6.dap dpreg 0x04 0x00;shutdown" - -Switch the DevKit back using SW3. Open a serial terminal (minicom, putty, -etc.) and connect to the board with the following settings: - -- Speed: 115200 -- Data: 8 bits -- Parity: None -- Stop bits: 1 - -Reset the board and the following message will appear on the corresponding -serial port: - -.. code-block:: console - - ***** Booting Zephyr OS zephyr-v1.13.0-1877-g9d14874db1 ***** - Hello World! cy8ckit_062_wifi_bt_m0 - - -References -********** - -.. _PSoC 62 MCU SoC Website: - http://www.cypress.com/products/32-bit-arm-cortex-m4-psoc-6 - -.. _PSoC 62 MCU Datasheet: - http://www.cypress.com/documentation/datasheets/psoc-6-mcu-psoc-62-datasheet-programmable-system-chip-psoc-preliminary - -.. _PSoC 62 MCU Architecture Reference Manual: - http://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-architecture-technical-reference-manual - -.. _PSoC 62 MCU Register Reference Manual: - http://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-register-technical-reference-manual-trm - -.. _CY8CKIT-062-WiFi-BT Website: - http://www.cypress.com/documentation/development-kitsboards/psoc-6-wifi-bt-pioneer-kit - -.. _CY8CKIT-062-WiFi-BT User Guide: - http://www.cypress.com/file/407731/download - -.. _CY8CKIT-062-WiFi-BT Schematics: - http://www.cypress.com/file/420846/download diff --git a/boards/arm/cy8ckit_062_wifi_bt_m0/pinmux.c b/boards/arm/cy8ckit_062_wifi_bt_m0/pinmux.c deleted file mode 100644 index 24aec0a958f4b0..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m0/pinmux.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2018 Cypress - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include - -#include "pinmux/pinmux.h" - -static int pinmux_init(struct device *port) -{ - ARG_UNUSED(port); - - return 0; -} - -SYS_INIT(pinmux_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/CMakeLists.txt b/boards/arm/cy8ckit_062_wifi_bt_m4/CMakeLists.txt deleted file mode 100644 index 5fedb5f3030a48..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m4/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2018, Cypress -# -# SPDX-License-Identifier: Apache-2.0 -# - -zephyr_library() -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -zephyr_library_sources_if_kconfig(pinmux.c) diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/Kconfig.board b/boards/arm/cy8ckit_062_wifi_bt_m4/Kconfig.board deleted file mode 100644 index 767624dad8f69e..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m4/Kconfig.board +++ /dev/null @@ -1,8 +0,0 @@ -# PSoC6 WiFi-BT Pioneer Kit configuration - -# Copyright (c) 2018 Cypress -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_CY8CKIT_062_WIFI_BT_M4 - bool "PSoC6 WiFi-BT Pioneer Kit M4" - depends on SOC_PART_NUMBER_CY8C6247BZI_D54 diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/Kconfig.defconfig b/boards/arm/cy8ckit_062_wifi_bt_m4/Kconfig.defconfig deleted file mode 100644 index 2aee9c6dd3f395..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m4/Kconfig.defconfig +++ /dev/null @@ -1,15 +0,0 @@ -# PSoC6 WiFi-BT Pioneer Kit configuration - -# Copyright (c) 2018 Cypress -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_CY8CKIT_062_WIFI_BT_M4 - -config BOARD - default "cy8ckit_062_wifi_bt_m4" - -config UART_PSOC6_UART_5 - default y - depends on UART_PSOC6 - -endif # BOARD_CY8CKIT_062_WIFI_BT_M4 diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/board.cmake b/boards/arm/cy8ckit_062_wifi_bt_m4/board.cmake deleted file mode 100644 index 7ee70a2ca393d2..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m4/board.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2018, Cypress -# -# SPDX-License-Identifier: Apache-2.0 -# - -include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) -include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/doc/img/cy8ckit_062_wifi_bt.png b/boards/arm/cy8ckit_062_wifi_bt_m4/doc/img/cy8ckit_062_wifi_bt.png deleted file mode 100644 index 1f573f748d7a51..00000000000000 Binary files a/boards/arm/cy8ckit_062_wifi_bt_m4/doc/img/cy8ckit_062_wifi_bt.png and /dev/null differ diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/doc/index.rst b/boards/arm/cy8ckit_062_wifi_bt_m4/doc/index.rst deleted file mode 100644 index 75fcb608f8f245..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m4/doc/index.rst +++ /dev/null @@ -1,22 +0,0 @@ -.. _cy8ckit_062_wifi_bt_m4: - -PSoC6 WiFi-BT Pioneer Kit (CM4 Core) -#################################### - -Overview -******** - -See :ref:`cy8ckit_062_wifi_bt` for a general overview of the -CY8CKIT_062_WIFI_BT board. -The Cortex-M4 is a secondary core on the board's SoC. It should be started from -the CM0+ core. - -Programming and Debugging -************************* - -Only the CM0+ core starts by default after the MCU reset. -In order to have CM4 core working FW for both cores should be written into -Flash. CM0+ FW should starts the CM4 core at one point using -Cy_SysEnableCM4(CM4_START_ADDRESS); call. CM4_START_ADDRESS is 0x10060000 in -the current configuration. The CM0+/CM4 Flash/SRAM areas are defined in -:zephyr_file:`dts/arm/cypress/psoc6.dtsi`. diff --git a/boards/arm/cy8ckit_062_wifi_bt_m4/pinmux.c b/boards/arm/cy8ckit_062_wifi_bt_m4/pinmux.c deleted file mode 100644 index 24aec0a958f4b0..00000000000000 --- a/boards/arm/cy8ckit_062_wifi_bt_m4/pinmux.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2018 Cypress - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include - -#include "pinmux/pinmux.h" - -static int pinmux_init(struct device *port) -{ - ARG_UNUSED(port); - - return 0; -} - -SYS_INIT(pinmux_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/boards/arm/decawave_dwm1001_dev/board.cmake b/boards/arm/decawave_dwm1001_dev/board.cmake index 2746201f22e584..8aa5af6f2d99c8 100644 --- a/boards/arm/decawave_dwm1001_dev/board.cmake +++ b/boards/arm/decawave_dwm1001_dev/board.cmake @@ -2,6 +2,7 @@ board_runner_args(jlink "--device=nrf52" "--speed=4000") board_runner_args(pyocd "--target=nrf52") +set(OPENOCD_NRF5_SUBFAMILY "nrf52") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) -include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts index 683bd64095f95a..c7e6527982b17d 100644 --- a/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts +++ b/boards/arm/decawave_dwm1001_dev/decawave_dwm1001_dev.dts @@ -53,7 +53,7 @@ buttons { compatible = "gpio-keys"; button0: button_0 { - gpios = <&gpio0 2 GPIO_PULL_UP>; + gpios = <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button switch 0"; }; }; @@ -124,7 +124,7 @@ sck-pin = <16>; mosi-pin = <20>; miso-pin = <18>; - cs-gpios = <&gpio0 17 0>; + cs-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; dw1000@0 { compatible = "decawave,dw1000"; @@ -144,10 +144,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/decawave_dwm1001_dev/support/openocd.cfg b/boards/arm/decawave_dwm1001_dev/support/openocd.cfg deleted file mode 100644 index d385bf428efe63..00000000000000 --- a/boards/arm/decawave_dwm1001_dev/support/openocd.cfg +++ /dev/null @@ -1,4 +0,0 @@ -source [find interface/jlink.cfg] -adapter_khz 1000 -transport select swd -source [find target/nrf52.cfg] diff --git a/boards/arm/degu_evk/Kconfig.defconfig b/boards/arm/degu_evk/Kconfig.defconfig index db34cb3d7b1852..f05f4d8b6bf401 100644 --- a/boards/arm/degu_evk/Kconfig.defconfig +++ b/boards/arm/degu_evk/Kconfig.defconfig @@ -36,10 +36,6 @@ config UART_SHELL_ON_DEV_NAME endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - if DISK_ACCESS_FLASH config DISK_FLASH_DEV_NAME diff --git a/boards/arm/degu_evk/board.c b/boards/arm/degu_evk/board.c index 1b53d47c6fde16..52b2f01f3df717 100644 --- a/boards/arm/degu_evk/board.c +++ b/boards/arm/degu_evk/board.c @@ -7,13 +7,13 @@ #include #include -static int board_degu_evk_init(struct device *dev) +static int board_degu_evk_init(const struct device *dev) { ARG_UNUSED(dev); - struct device *gpio0 = + const struct device *gpio0 = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0))); - struct device *gpio1 = + const struct device *gpio1 = device_get_binding(DT_LABEL(DT_NODELABEL(gpio1))); /* diff --git a/boards/arm/degu_evk/board.cmake b/boards/arm/degu_evk/board.cmake index c34c04406c8098..f191a11bdbb6b1 100644 --- a/boards/arm/degu_evk/board.cmake +++ b/boards/arm/degu_evk/board.cmake @@ -1,7 +1,6 @@ # Copyright (c) 2019 Atmark Techno, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/degu_evk/degu_evk.dts b/boards/arm/degu_evk/degu_evk.dts index 31e1d0cb1eb958..992109bae3d830 100644 --- a/boards/arm/degu_evk/degu_evk.dts +++ b/boards/arm/degu_evk/degu_evk.dts @@ -108,7 +108,7 @@ &flash0 { /* * For more information, see: - * http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html + * https://docs.zephyrproject.org/latest/reference/devicetree/index.html#fixed-flash-partitions */ partitions { compatible = "fixed-partitions"; diff --git a/boards/arm/disco_l475_iot1/CMakeLists.txt b/boards/arm/disco_l475_iot1/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/disco_l475_iot1/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/disco_l475_iot1/disco_l475_iot1.dts b/boards/arm/disco_l475_iot1/disco_l475_iot1.dts index a4f1e1dc067978..a69ae20346bddf 100644 --- a/boards/arm/disco_l475_iot1/disco_l475_iot1.dts +++ b/boards/arm/disco_l475_iot1/disco_l475_iot1.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics B-L475E-IOT01Ax board"; - compatible = "st,stm32l475-disco-iot", "st,stm32l475"; + compatible = "st,stm32l475-disco-iot"; chosen { zephyr,console = &usart1; @@ -50,6 +51,8 @@ &usart1 { current-speed = <115200>; + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; + pinctrl-names = "default"; status = "okay"; }; @@ -59,16 +62,19 @@ }; &uart4 { + pinctrl-0 = <&uart4_tx_pa0 &uart4_rx_pa1>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; status = "okay"; clock-frequency = ; @@ -106,19 +112,25 @@ }; &i2c3 { + pinctrl-0 = <&i2c3_scl_pc0 &i2c3_sda_pc1>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; +&spi3_miso_pc11 { slew-rate = "very-high-speed"; }; + &spi3 { status = "okay"; + pinctrl-0 = <&spi3_sck_pc10 &spi3_miso_pc11 &spi3_mosi_pc12>; + cs-gpios = <&gpiod 13 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>, - <&gpioe 0 GPIO_ACTIVE_HIGH>; + <&gpioe 0 GPIO_ACTIVE_LOW>; spbtle-rf@0 { compatible = "zephyr,bt-hci-spi"; @@ -142,10 +154,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -172,7 +181,7 @@ }; scratch_partition: partition@f8000 { label = "image-scratch"; - reg = <0x000F8000 0x00006000>; + reg = <0x000F8000 0x00004000>; }; storage_partition: partition@fc000 { @@ -187,6 +196,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa15>; }; }; @@ -199,6 +209,8 @@ }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12 + &usb_otg_fs_id_pa10>; status = "okay"; }; @@ -209,3 +221,10 @@ &rng { status = "okay"; }; + +&adc1 { + pinctrl-0 = <&adc1_in5_pa0 &adc1_in3_pc2 + &adc1_in4_pc3 &adc1_in13_pc4 + &adc1_in14_pc5>; + status = "okay"; +}; diff --git a/boards/arm/disco_l475_iot1/disco_l475_iot1.yaml b/boards/arm/disco_l475_iot1/disco_l475_iot1.yaml index 9e1c997ea1f55e..f7191a2632d82d 100644 --- a/boards/arm/disco_l475_iot1/disco_l475_iot1.yaml +++ b/boards/arm/disco_l475_iot1/disco_l475_iot1.yaml @@ -20,5 +20,6 @@ supported: - nvs - vl53l0x - watchdog + - adc ram: 96 flash: 1024 diff --git a/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig b/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig index 1a119864629a2b..2110585cb90fd0 100644 --- a/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig +++ b/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig @@ -44,3 +44,6 @@ CONFIG_UART_CONSOLE=y # enable MPU CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/disco_l475_iot1/doc/index.rst b/boards/arm/disco_l475_iot1/doc/index.rst index 1608421a3ba2fd..9eb77fe7f25850 100644 --- a/boards/arm/disco_l475_iot1/doc/index.rst +++ b/boards/arm/disco_l475_iot1/doc/index.rst @@ -123,6 +123,8 @@ The Zephyr Disco L475 IoT board configuration supports the following hardware fe +-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | independent watchdog | +-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -155,6 +157,11 @@ Default Zephyr Peripheral Mapping: - PWM_2_CH1 : PA15 - USER_PB : PC13 - LD2 : PA5 +- ADC12_IN5 : PA0 +- ADC123_IN3 : PC2 +- ADC123_IN4 : PC3 +- ADC12_IN13 : PC4 +- ADC12_IN14 : PC5 System Clock ------------ diff --git a/boards/arm/disco_l475_iot1/pinmux.c b/boards/arm/disco_l475_iot1/pinmux.c deleted file mode 100644 index 122e2931cca0af..00000000000000 --- a/boards/arm/disco_l475_iot1/pinmux.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2017 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for Disco L475 IOT1 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32L4X_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32L4X_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart4), okay) && CONFIG_SERIAL - {STM32_PIN_PA0, STM32L4X_PINMUX_FUNC_PA0_UART4_TX}, - {STM32_PIN_PA1, STM32L4X_PINMUX_FUNC_PA1_UART4_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32L4X_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32L4X_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - /* I2C2 is used for NFC, STSAFE, ToF & MEMS sensors */ - {STM32_PIN_PB10, STM32L4X_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB11, STM32L4X_PINMUX_FUNC_PB11_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PC0, STM32L4X_PINMUX_FUNC_PC0_I2C3_SCL}, - {STM32_PIN_PC1, STM32L4X_PINMUX_FUNC_PC1_I2C3_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PA5, STM32L4X_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi3), okay) && CONFIG_SPI - /* SPI3 is used for BT/WIFI, Sub GHZ communication */ - {STM32_PIN_PC10, STM32L4X_PINMUX_FUNC_PC10_SPI3_SCK}, - {STM32_PIN_PC11, STM32L4X_PINMUX_FUNC_PC11_SPI3_MISO | \ - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PC12, STM32L4X_PINMUX_FUNC_PC12_SPI3_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA15, STM32L4X_PINMUX_FUNC_PA15_PWM2_CH1}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA10, STM32L4X_PINMUX_FUNC_PA10_OTG_FS_ID}, - {STM32_PIN_PA11, STM32L4X_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32L4X_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ - -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/dragino_lsn50/CMakeLists.txt b/boards/arm/dragino_lsn50/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/dragino_lsn50/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/dragino_lsn50/dragino_lsn50.dts b/boards/arm/dragino_lsn50/dragino_lsn50.dts index 92f60c85f0bc8a..0c3e4c06b46755 100644 --- a/boards/arm/dragino_lsn50/dragino_lsn50.dts +++ b/boards/arm/dragino_lsn50/dragino_lsn50.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "Dragino LSN50 LoRA Sensor Node"; - compatible = "vendor,dragino", "st,stm32l072"; + compatible = "vendor,dragino"; chosen { zephyr,console = &usart1; @@ -20,7 +21,13 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + current-speed = <115200>; + status = "okay"; +}; diff --git a/boards/arm/dragino_lsn50/pinmux.c b/boards/arm/dragino_lsn50/pinmux.c deleted file mode 100644 index 3135092c02d82a..00000000000000 --- a/boards/arm/dragino_lsn50/pinmux.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2018 Endre Karlson - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include "pinmux/stm32/pinmux_stm32.h" - -/* pin assignments for Dragino LSN50 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32L0_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32L0_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L0_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L0_PINMUX_FUNC_PA3_USART2_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/efm32gg_slwstk6121a/CMakeLists.txt b/boards/arm/efm32gg_slwstk6121a/CMakeLists.txt new file mode 100644 index 00000000000000..e9d5b43e34f3a1 --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2019 Interay Solutions B.V. +# Copyright (c) 2019 Oane Kingma +# Copyright (c) 2020 Thorvald Natvig +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_ETH_GECKO) + zephyr_library() + zephyr_library_sources(board.c) + zephyr_library_include_directories(${ZEPHYR_BASE}}/drivers) +endif() diff --git a/boards/arm/efm32gg_slwstk6121a/Kconfig.board b/boards/arm/efm32gg_slwstk6121a/Kconfig.board new file mode 100644 index 00000000000000..e15929d5a0a808 --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/Kconfig.board @@ -0,0 +1,10 @@ +# EFM32GG SLWSTK6121A board configuration +# Copyright (c) 2019 Interay Solutions B.V. +# Copyright (c) 2019 Oane Kingma +# Copyright (c) 2020 Thorvald Natvig +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_EFM32GG_SLWSTK6121A + bool "SiLabs EFM32GG-SLWSTK6121A (WGM160P)" + depends on SOC_SERIES_EFM32GG11B + select SOC_PART_NUMBER_EFM32GG11B820F2048GM64 diff --git a/boards/arm/efm32gg_slwstk6121a/Kconfig.defconfig b/boards/arm/efm32gg_slwstk6121a/Kconfig.defconfig new file mode 100644 index 00000000000000..b88b580ff299b9 --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/Kconfig.defconfig @@ -0,0 +1,43 @@ +# EFM32GG SLWSTK6121A default board configuration +# Copyright (c) 2019 Interay Solutions B.V. +# Copyright (c) 2019 Oane Kingma +# Copyright (c) 2020 Thorvald Natvig +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_EFM32GG_SLWSTK6121A + +config BOARD + string + default "efm32gg_slwstk6121a" + +config CMU_HFXO_FREQ + default 50000000 + +config CMU_HFRCO_FREQ + default 72000000 + +config CMU_LFXO_FREQ + default 32768 + +config COUNTER_GECKO_RTCC + default y + depends on COUNTER + +config LEUART_GECKO + default n + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +if NETWORKING + +config NET_L2_ETHERNET + default y + +config ETH_GECKO + default y if NET_L2_ETHERNET + +endif # NETWORKING + +endif # BOARD_EFM32GG_SLWSTK6121A diff --git a/boards/arm/efm32gg_slwstk6121a/board.c b/boards/arm/efm32gg_slwstk6121a/board.c new file mode 100644 index 00000000000000..156a9658883e49 --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/board.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019 Interay Solutions B.V. + * Copyright (c) 2019 Oane Kingma + * Copyright (c) 2020 Thorvald Natvig + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "em_cmu.h" +#include "board.h" + +static int efm32gg_slwstk6121a_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + const struct device *cur_dev; + + /* Configure ethernet reference clock */ + cur_dev = device_get_binding(ETH_REF_CLK_GPIO_NAME); + if (!cur_dev) { + printk("Ethernet reference clock gpio port was not found!\n"); + return -ENODEV; + } + + gpio_pin_configure(cur_dev, ETH_REF_CLK_GPIO_PIN, GPIO_OUTPUT); + gpio_pin_set(cur_dev, ETH_REF_CLK_GPIO_PIN, 0); + + CMU_OscillatorEnable(cmuOsc_HFXO, true, true); + + /* enable CMU_CLK2 as RMII reference clock */ + CMU->CTRL |= CMU_CTRL_CLKOUTSEL2_HFXO; + CMU->ROUTELOC0 = (CMU->ROUTELOC0 & ~_CMU_ROUTELOC0_CLKOUT2LOC_MASK) | + (ETH_REF_CLK_LOCATION << _CMU_ROUTELOC0_CLKOUT2LOC_SHIFT); + CMU->ROUTEPEN |= CMU_ROUTEPEN_CLKOUT2PEN; + + return 0; +} + +/* needs to be done after GPIO driver init and device tree available */ +SYS_INIT(efm32gg_slwstk6121a_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/boards/arm/efm32gg_slwstk6121a/board.cmake b/boards/arm/efm32gg_slwstk6121a/board.cmake new file mode 100644 index 00000000000000..0f0250335b6f7f --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/board.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2019 Interay Solutions B.V. +# Copyright (c) 2019 Oane Kingma +# Copyright (c) 2020 Thorvald Natvig +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFM32GG11B820F2048") +board_runner_args(openocd) + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/efm32gg_slwstk6121a/board.h b/boards/arm/efm32gg_slwstk6121a/board.h new file mode 100644 index 00000000000000..145d0ac2928ba0 --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/board.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2019 Interay Solutions B.V. + * Copyright (c) 2019 Oane Kingma + * Copyright (c) 2020 Thorvald Natvig + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INC_BOARD_H +#define __INC_BOARD_H + +/* Ethernet specific pins */ +#define ETH_REF_CLK_GPIO_NAME "GPIO_A" +#define ETH_REF_CLK_GPIO_PIN DT_PROP_BY_IDX(DT_INST(0, silabs_gecko_ethernet), location_rmii_refclk, 2) +/* The driver ties CMU_CLK2 to the refclk, and pin A3 is CMU_CLK2 #1 */ +#define ETH_REF_CLK_LOCATION 1 + +#endif /* __INC_BOARD_H */ diff --git a/boards/arm/efm32gg_slwstk6121a/doc/index.rst b/boards/arm/efm32gg_slwstk6121a/doc/index.rst new file mode 100644 index 00000000000000..61b5995b4ec87f --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/doc/index.rst @@ -0,0 +1,188 @@ +.. _efm32gg_slwstk6121a: + +WGM160P Starter Kit +################### + +Overview +******** + +The WGM160P Starter Kit SLWSTK6121A comes with the BRD4321A radio board. +This radio boards contains a WGM160P module, which combines the WF200 Wi-Fi +transceiver with an EFM32GG11 microcontroller. + +.. figure:: ./wgm160p-starter-kit.jpg + :width: 300px + :align: center + :alt: SLWSTK6121A + + SLWSTK6121A (image courtesy of Silicon Labs) + +Hardware +******** + +- Advanced Energy Monitoring provides real-time information about the energy + consumption of an application or prototype design. +- Ultra low power 128x128 pixel color Memory-LCD +- 2 user buttons and 2 LEDs +- Si7021 Humidity and Temperature Sensor +- On-board Segger J-Link USB and Ethernet debugger +- 10/100Base-TX ethernet PHY and RJ-45 jack (on included expansion board) +- MicroSD card slot +- USB Micro-AB connector + +For more information about the WGM160P and SLWSTK6121A board: + +- `WGM160P Website`_ +- `WGM160P Datasheet`_ +- `SLWSTK6121A Website`_ +- `SLWSTK6121A User Guide`_ +- `EFM32GG11 Datasheet`_ +- `EFM32GG11 Reference Manual`_ +- `WF200 Datasheet`_ + +Supported Features +================== + +The efm32gg_slwstk6121a board configuration supports the following hardware +features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtcc | ++-----------+------------+-------------------------------------+ +| ETHERNET | on-chip | ethernet | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c port-polling | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: + + ``boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a_defconfig`` + +Other hardware features, including the WF200 WiFi transceiver, are +currently not supported by the port. + +Connections and IOs +=================== + +The WGM160P's EFM32GG11 SoC has six GPIO controllers (PORTA to PORTF), all of which are +currently enabled for the SLWSTK6121A board. + +In the following table, the column **Name** contains pin names. For example, PE1 +means pin number 1 on PORTE, as used in the board's datasheets and manuals. + ++-------+-------------+-------------------------------------+ +| Name | Function | Usage | ++=======+=============+=====================================+ +| PA4 | GPIO | LED0 | ++-------+-------------+-------------------------------------+ +| PA5 | GPIO | LED1 | ++-------+-------------+-------------------------------------+ +| PD6 | GPIO | Push Button PB0 | ++-------+-------------+-------------------------------------+ +| PD8 | GPIO | Push Button PB1 | ++-------+-------------+-------------------------------------+ +| PE7 | UART_TX | UART TX Console VCOM_TX US0_TX #1 | ++-------+-------------+-------------------------------------+ +| PE6 | UART_RX | UART RX Console VCOM_RX US0_RX #1 | ++-------+-------------+-------------------------------------+ +| PB11 | I2C_SDA | SENSOR_I2C_SDA I2C1_SDA #1 | ++-------+-------------+-------------------------------------+ +| PB12 | I2C_SCL | SENSOR_I2C_SCL I2C1_SCL #1 | ++-------+-------------+-------------------------------------+ + + +System Clock +============ + +The EFM32GG11 SoC is configured to use the 50 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFM32GG11 SoC has four USARTs, two UARTs and two Low Energy UARTs (LEUART). +USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +.. note:: + Before using the kit the first time, you should update the J-Link firmware + from `J-Link-Downloads`_ + +Flashing +======== + +The SLWSTK6121A includes an `J-Link`_ serial and debug adaptor built into the +board. The adaptor provides: + +- A USB connection to the host computer +- A physical UART connection which is relayed over interface USB serial port. + +Flashing an application to SLWSTK6121A +-------------------------------------- + +Connect the SLWSTK6121A to your host computer using the USB port. + +Here is an example to build and flash the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: efm32gg_slwstk6121a + :goals: flash + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you'll see the following message on the corresponding serial port +terminal session: + +.. code-block:: console + + Hello World! efm32gg_slwstk6121a + +.. _WGM160P Website: + https://www.silabs.com/wireless/wi-fi/wfm160-series-1-modules + +.. _WGM160P Datasheet: + https://www.silabs.com/documents/public/data-sheets/wgm160p-datasheet.pdf + +.. _SLWSTK6121A Website: + https://www.silabs.com/development-tools/wireless/wi-fi/wgm160p-wifi-module-starter-kit + +.. _SLWSTK6121A User Guide: + https://www.silabs.com/documents/public/user-guides/ug351-brd4321a-user-guide.pdf + +.. _EFM32GG11 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efm32gg11-datasheet.pdf + +.. _EFM32GG11 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efm32gg11-rm.pdf + +.. _WF200 Datasheet: + https://www.silabs.com/documents/public/data-sheets/wf200-datasheet.pdf + +.. _J-Link: + https://www.segger.com/jlink-debug-probes.html + +.. _J-Link-Downloads: + https://www.segger.com/downloads/jlink diff --git a/boards/arm/efm32gg_slwstk6121a/doc/wgm160p-starter-kit.jpg b/boards/arm/efm32gg_slwstk6121a/doc/wgm160p-starter-kit.jpg new file mode 100644 index 00000000000000..68be3359845e17 Binary files /dev/null and b/boards/arm/efm32gg_slwstk6121a/doc/wgm160p-starter-kit.jpg differ diff --git a/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts new file mode 100644 index 00000000000000..0cceed52437c58 --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.dts @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2019 Interay Solutions B.V. + * Copyright (c) 2019 Oane Kingma + * Copyright (c) 2020 Thorvald Natvig + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Silicon Labs EFM32GG SLWSTK6121A board"; + compatible = "silabs,efm32gg_slwstk6121a", "silabs,efm32gg11b"; + + chosen { + zephyr,console = &usart0; + zephyr,shell-uart = &usart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + sw1 = &button1; + watchdog0 = &wdog0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpioa 4 0>; + label = "LED 0"; + }; + led1: led_1 { + gpios = <&gpioa 5 0>; + label = "LED 1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + /* gpio flags need validation */ + gpios = <&gpiod 6 GPIO_ACTIVE_LOW>; + label = "User Push Button 0"; + }; + button1: button_1 { + /* gpio flags need validation */ + gpios = <&gpiod 8 GPIO_ACTIVE_LOW>; + label = "User Push Button 1"; + }; + }; +}; + +/* Connected to the WSTK VCOM */ +&usart0 { + current-speed = <115200>; + location-rx = ; + location-tx = ; + status = "okay"; +}; + +/* i2c unit 0 is not used on the board, but must be defined for i2c unit 1 + * to work properly. + */ +&i2c0 { + location-sda = ; + location-scl = ; + status = "okay"; +}; + +/* Connected to Si7021 sensor on WSTK */ +&i2c1 { + location-sda = ; + location-scl = ; + status = "okay"; +}; + +&rtcc0 { + prescaler = <1>; + status = "okay"; +}; + +&gpio { + location-swo = <0>; + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&gpioe { + status = "okay"; +}; + +&gpiof { + status = "okay"; +}; + +ð0 { + /* PHY address = 0 */ + phy-address = <0>; + + /* PHY management pins */ + location-mdio = ; + location-phy_mdc = ; + location-phy_mdio = ; + + /* RMII interface pins */ + location-rmii = ; + location-rmii_refclk = ; + location-rmii_crs_dv = ; + location-rmii_txd0 = ; + location-rmii_txd1 = ; + location-rmii_tx_en = ; + location-rmii_rxd0 = ; + location-rmii_rxd1 = ; + location-rmii_rx_er = ; + + status = "okay"; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Set 12Kb of storage at the end of the 2048Kb of flash */ + storage_partition: partition@1fd000 { + label = "storage"; + reg = <0x001fd000 0x00003000>; + }; + }; +}; + +&wdog0 { + status = "okay"; +}; + +&trng0 { + status = "okay"; +}; + +&cpu0 { + clock-frequency = <72000000>; +}; diff --git a/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml new file mode 100644 index 00000000000000..057e565b9a4eac --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a.yaml @@ -0,0 +1,20 @@ +identifier: efm32gg_slwstk6121a +name: EFM32GG-SLWSTK6121A +type: mcu +arch: arm +ram: 512 +flash: 2048 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - counter + - i2c + - gpio + - netif:eth + - nvs + - uart +testing: + ignore_tags: + - bluetooth diff --git a/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a_defconfig b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a_defconfig new file mode 100644 index 00000000000000..9f02be339d43ef --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/efm32gg_slwstk6121a_defconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2019 Interay Solutions B.V. +# Copyright (c) 2019 Oane Kingma +# Copyright (c) 2020 Thorvald Natvig +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_EFM32GG11B=y +CONFIG_BOARD_EFM32GG_SLWSTK6121A=y +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_GPIO=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 +CONFIG_CMU_HFCLK_HFRCO=y +CONFIG_SOC_GECKO_EMU_DCDC=y +CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y diff --git a/boards/arm/efm32gg_slwstk6121a/support/openocd.cfg b/boards/arm/efm32gg_slwstk6121a/support/openocd.cfg new file mode 100644 index 00000000000000..ca9df38110000b --- /dev/null +++ b/boards/arm/efm32gg_slwstk6121a/support/openocd.cfg @@ -0,0 +1,27 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port using the J-Link interface + set INTERFACE "jlink" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +set CHIPNAME efm32 + +source [find target/efm32.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +$_TARGETNAME configure -rtos auto diff --git a/boards/arm/efm32gg_stk3701a/Kconfig.defconfig b/boards/arm/efm32gg_stk3701a/Kconfig.defconfig index 9c9fd662c60350..f87f9b7e877ce2 100644 --- a/boards/arm/efm32gg_stk3701a/Kconfig.defconfig +++ b/boards/arm/efm32gg_stk3701a/Kconfig.defconfig @@ -12,6 +12,9 @@ config BOARD config CMU_HFXO_FREQ default 50000000 +config CMU_HFRCO_FREQ + default 72000000 + config CMU_LFXO_FREQ default 32768 @@ -19,6 +22,10 @@ config COUNTER_GECKO_RTCC default y depends on COUNTER +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + if NETWORKING config NET_L2_ETHERNET diff --git a/boards/arm/efm32gg_stk3701a/board.c b/boards/arm/efm32gg_stk3701a/board.c index 2cbbd64f50dcfe..6f31d4a49ef7eb 100644 --- a/boards/arm/efm32gg_stk3701a/board.c +++ b/boards/arm/efm32gg_stk3701a/board.c @@ -11,9 +11,9 @@ #include #include "em_cmu.h" -static int efm32gg_stk3701a_init(struct device *dev) +static int efm32gg_stk3701a_init(const struct device *dev) { - struct device *cur_dev; + const struct device *cur_dev; ARG_UNUSED(dev); @@ -48,6 +48,8 @@ static int efm32gg_stk3701a_init(struct device *dev) gpio_pin_configure(cur_dev, ETH_REF_CLK_GPIO_PIN, GPIO_OUTPUT); gpio_pin_set(cur_dev, ETH_REF_CLK_GPIO_PIN, 0); + CMU_OscillatorEnable(cmuOsc_HFXO, true, true); + /* enable CMU_CLK2 as RMII reference clock */ CMU->CTRL |= CMU_CTRL_CLKOUTSEL2_HFXO; CMU->ROUTELOC0 = (CMU->ROUTELOC0 & ~_CMU_ROUTELOC0_CLKOUT2LOC_MASK) | diff --git a/boards/arm/efm32gg_stk3701a/board.cmake b/boards/arm/efm32gg_stk3701a/board.cmake index a3ced2516fa877..d56bbf2a97f43e 100644 --- a/boards/arm/efm32gg_stk3701a/board.cmake +++ b/boards/arm/efm32gg_stk3701a/board.cmake @@ -3,4 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(jlink "--device=EFM32GG11B820F2048") +board_runner_args(openocd) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/efm32gg_stk3701a/doc/index.rst b/boards/arm/efm32gg_stk3701a/doc/index.rst index 9ae36169909a21..20ffece0991e3a 100644 --- a/boards/arm/efm32gg_stk3701a/doc/index.rst +++ b/boards/arm/efm32gg_stk3701a/doc/index.rst @@ -50,6 +50,8 @@ features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | +===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ | COUNTER | on-chip | rtcc | +-----------+------------+-------------------------------------+ | ETHERNET | on-chip | ethernet | diff --git a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.dts b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.dts index 4c11a2a62541a9..017cc90759ce64 100644 --- a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.dts +++ b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.dts @@ -25,6 +25,7 @@ led1 = &led1; sw0 = &button0; sw1 = &button1; + watchdog0 = &wdog0; }; leds { @@ -134,8 +135,6 @@ }; ð0 { - /* local-mac-address = <>;*/ - /* PHY address = 0 */ phy-address = <0>; @@ -159,10 +158,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -175,3 +171,15 @@ }; }; }; + +&wdog0 { + status = "okay"; +}; + +&trng0 { + status = "okay"; +}; + +&cpu0 { + clock-frequency = <72000000>; +}; diff --git a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.yaml b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.yaml index 2f59628591e641..c2cad793872a02 100644 --- a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.yaml +++ b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a.yaml @@ -6,7 +6,7 @@ ram: 512 flash: 2048 toolchain: - zephyr - - gccarmemb + - gnuarmemb - xtools supported: - i2c diff --git a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a_defconfig b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a_defconfig index 8d145bd27782ca..b3bbcee02e0a9c 100644 --- a/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a_defconfig +++ b/boards/arm/efm32gg_stk3701a/efm32gg_stk3701a_defconfig @@ -4,10 +4,11 @@ CONFIG_SOC_SERIES_EFM32GG11B=y CONFIG_BOARD_EFM32GG_STK3701A=y +CONFIG_ARM_MPU=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=50000000 -CONFIG_CMU_HFCLK_HFXO=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 +CONFIG_CMU_HFCLK_HFRCO=y diff --git a/boards/arm/efm32gg_stk3701a/support/openocd.cfg b/boards/arm/efm32gg_stk3701a/support/openocd.cfg new file mode 100644 index 00000000000000..ca9df38110000b --- /dev/null +++ b/boards/arm/efm32gg_stk3701a/support/openocd.cfg @@ -0,0 +1,27 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port using the J-Link interface + set INTERFACE "jlink" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +set CHIPNAME efm32 + +source [find target/efm32.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +$_TARGETNAME configure -rtos auto diff --git a/boards/arm/efm32hg_slstk3400a/board.c b/boards/arm/efm32hg_slstk3400a/board.c index f8485af46861e0..e6b5bc5d423fda 100644 --- a/boards/arm/efm32hg_slstk3400a/board.c +++ b/boards/arm/efm32hg_slstk3400a/board.c @@ -9,9 +9,9 @@ #include #include -static int efm32hg_slstk3400a_init(struct device *dev) +static int efm32hg_slstk3400a_init(const struct device *dev) { - struct device *bce_dev; /* Board Controller Enable Gpio Device */ + const struct device *bce_dev; /* Board Controller Enable Gpio Device */ ARG_UNUSED(dev); diff --git a/boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.dts b/boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.dts index 57dd0d5e622722..c86cda085cc8f3 100644 --- a/boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.dts +++ b/boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.dts @@ -78,10 +78,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/efm32pg_stk3402a/board.c b/boards/arm/efm32pg_stk3402a/board.c index 65ffc219ad73bc..99eea511e2a614 100644 --- a/boards/arm/efm32pg_stk3402a/board.c +++ b/boards/arm/efm32pg_stk3402a/board.c @@ -9,9 +9,9 @@ #include #include -static int efm32pg_stk3402a_init(struct device *dev) +static int efm32pg_stk3402a_init(const struct device *dev) { - struct device *bce_dev; /* Board Controller Enable Gpio Device */ + const struct device *bce_dev; /* Board Controller Enable Gpio Device */ ARG_UNUSED(dev); diff --git a/boards/arm/efm32pg_stk3402a/doc/index.rst b/boards/arm/efm32pg_stk3402a/doc/index.rst index 5d91d7d615c179..1a6de113ec9bf3 100644 --- a/boards/arm/efm32pg_stk3402a/doc/index.rst +++ b/boards/arm/efm32pg_stk3402a/doc/index.rst @@ -44,6 +44,8 @@ The efm32pg_stk3402a board configuration supports the following hardware feature +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | +===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ | NVIC | on-chip | nested vector interrupt controller | +-----------+------------+-------------------------------------+ | SYSTICK | on-chip | systick | diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.yaml b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.yaml index 476b6e08893e94..707e1b02169a36 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.yaml +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a.yaml @@ -6,7 +6,7 @@ ram: 256 flash: 1024 toolchain: - zephyr - - gccarmemb + - gnuarmemb - xtools supported: - i2c diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi index 35a646482130de..2e9adc8ddee0ef 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi @@ -112,10 +112,7 @@ &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_defconfig b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_defconfig index e026177a824ea0..2263ae6c20de08 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_defconfig +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_defconfig @@ -2,6 +2,7 @@ CONFIG_SOC_SERIES_EFM32PG12B=y CONFIG_BOARD_EFM32PG_STK3402A=y +CONFIG_ARM_MPU=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg.yaml b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg.yaml index 91f6297575f6d3..66e272e8cefbf2 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg.yaml +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg.yaml @@ -6,7 +6,7 @@ ram: 256 flash: 1024 toolchain: - zephyr - - gccarmemb + - gnuarmemb - xtools supported: - i2c diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg_defconfig b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg_defconfig index 7977b54e13eef5..4d2beb29e4b440 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg_defconfig +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_jg_defconfig @@ -2,6 +2,7 @@ CONFIG_SOC_SERIES_EFM32JG12B=y CONFIG_BOARD_EFM32PG_STK3402A_JG=y +CONFIG_ARM_MPU=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/arm/efm32wg_stk3800/board.c b/boards/arm/efm32wg_stk3800/board.c index 26ce8287f21591..de6960a7ad3e7b 100644 --- a/boards/arm/efm32wg_stk3800/board.c +++ b/boards/arm/efm32wg_stk3800/board.c @@ -9,9 +9,9 @@ #include #include -static int efm32wg_stk3800_init(struct device *dev) +static int efm32wg_stk3800_init(const struct device *dev) { - struct device *bce_dev; /* Board Controller Enable Gpio Device */ + const struct device *bce_dev; /* Board Controller Enable Gpio Device */ ARG_UNUSED(dev); diff --git a/boards/arm/efm32wg_stk3800/doc/index.rst b/boards/arm/efm32wg_stk3800/doc/index.rst index c6eabb674a854e..19f4b73f83f354 100644 --- a/boards/arm/efm32wg_stk3800/doc/index.rst +++ b/boards/arm/efm32wg_stk3800/doc/index.rst @@ -46,6 +46,8 @@ The efm32wg_stk3800oard configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | +===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ | NVIC | on-chip | nested vector interrupt controller | +-----------+------------+-------------------------------------+ | SYSTICK | on-chip | systick | diff --git a/boards/arm/efm32wg_stk3800/efm32wg_stk3800.dts b/boards/arm/efm32wg_stk3800/efm32wg_stk3800.dts index 83850f72a56db1..99f42c1f6c8c8b 100644 --- a/boards/arm/efm32wg_stk3800/efm32wg_stk3800.dts +++ b/boards/arm/efm32wg_stk3800/efm32wg_stk3800.dts @@ -81,10 +81,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/efm32wg_stk3800/efm32wg_stk3800_defconfig b/boards/arm/efm32wg_stk3800/efm32wg_stk3800_defconfig index 41996d8b1c42c9..1ccfdeec16bf83 100644 --- a/boards/arm/efm32wg_stk3800/efm32wg_stk3800_defconfig +++ b/boards/arm/efm32wg_stk3800/efm32wg_stk3800_defconfig @@ -2,6 +2,7 @@ CONFIG_SOC_SERIES_EFM32WG=y CONFIG_BOARD_EFM32WG_STK3800=y +CONFIG_ARM_MPU=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/arm/efr32_radio/Kconfig b/boards/arm/efr32_radio/Kconfig index 11a97d8067321b..5bbe58fba84da8 100644 --- a/boards/arm/efr32_radio/Kconfig +++ b/boards/arm/efr32_radio/Kconfig @@ -6,13 +6,10 @@ config BOARD_EFR32_RADIO bool -if BOARD_EFR32_RADIO - config BOARD_INIT_PRIORITY int default KERNEL_INIT_PRIORITY_DEFAULT + depends on BOARD_EFR32_RADIO help Board initialization priority. This must be bigger than GPIO_GECKO_COMMON_INIT_PRIORITY. - -endif # BOARD_EFR32_RADIO diff --git a/boards/arm/efr32_radio/Kconfig.board b/boards/arm/efr32_radio/Kconfig.board index 84f734efdb6207..d3675dcd40fad1 100644 --- a/boards/arm/efr32_radio/Kconfig.board +++ b/boards/arm/efr32_radio/Kconfig.board @@ -1,6 +1,7 @@ -# EFR32BG13 BRD4104A board +# EFR32BG13 BRD4104A / EFR32MG21 BRD4180A board # Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH # SPDX-License-Identifier: Apache-2.0 config BOARD_EFR32_RADIO_BRD4104A @@ -14,3 +15,9 @@ config BOARD_EFR32_RADIO_BRD4250B depends on SOC_SERIES_EFR32FG1P select BOARD_EFR32_RADIO select SOC_PART_NUMBER_EFR32FG1P133F256GM48 + +config BOARD_EFR32_RADIO_BRD4180A + bool "Silicon Labs BRD4180A (Mighty Gecko Radio Board)" + depends on SOC_SERIES_EFR32MG21 + select BOARD_EFR32_RADIO + select SOC_PART_NUMBER_EFR32MG21A020F1024IM32 diff --git a/boards/arm/efr32_radio/Kconfig.defconfig b/boards/arm/efr32_radio/Kconfig.defconfig index 44b471b8cdb069..9d7184e9912378 100644 --- a/boards/arm/efr32_radio/Kconfig.defconfig +++ b/boards/arm/efr32_radio/Kconfig.defconfig @@ -1,6 +1,7 @@ # EFR32 radio board # Copyright (c) 2020 Piotr Mienkowski +# Copyright (c) 2020 TriaGnoSys GmbH # SPDX-License-Identifier: Apache-2.0 if BOARD_EFR32_RADIO @@ -8,6 +9,7 @@ if BOARD_EFR32_RADIO config BOARD default "efr32_radio_brd4104a" if BOARD_EFR32_RADIO_BRD4104A default "efr32_radio_brd4250b" if BOARD_EFR32_RADIO_BRD4250B + default "efr32_radio_brd4180a" if BOARD_EFR32_RADIO_BRD4180A config CMU_HFXO_FREQ default 38400000 @@ -15,25 +17,16 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -if LOG_BACKEND_SWO - config LOG_BACKEND_SWO_FREQ_HZ default 875000 - -endif # LOG_BACKEND_SWO - -if SERIAL + depends on LOG_BACKEND_SWO config UART_GECKO default y - -endif # SERIAL - -if COUNTER + depends on SERIAL config COUNTER_GECKO_RTCC default y - -endif # COUNTER + depends on COUNTER endif # BOARD_EFR32_RADIO diff --git a/boards/arm/efr32_radio/board.c b/boards/arm/efr32_radio/board.c index 4299a0a37f3aec..7b9f6833aa70a3 100644 --- a/boards/arm/efr32_radio/board.c +++ b/boards/arm/efr32_radio/board.c @@ -9,12 +9,17 @@ #include /* This pin is used to enable the serial port using the board controller */ +#ifdef CONFIG_BOARD_EFR32_RADIO_BRD4180A +#define VCOM_ENABLE_GPIO_NAME "GPIO_D" +#define VCOM_ENABLE_GPIO_PIN 4 +#else #define VCOM_ENABLE_GPIO_NAME "GPIO_A" #define VCOM_ENABLE_GPIO_PIN 5 +#endif /* CONFIG_BOARD_EFR32_RADIO_BRD4180A */ -static int efr32_radio_init(struct device *dev) +static int efr32_radio_init(const struct device *dev) { - struct device *vce_dev; /* Virtual COM Port Enable GPIO Device */ + const struct device *vce_dev; /* Virtual COM Port Enable GPIO Device */ ARG_UNUSED(dev); diff --git a/boards/arm/efr32_radio/board.cmake b/boards/arm/efr32_radio/board.cmake index 64189d0732b03c..a18647742ece9f 100644 --- a/boards/arm/efr32_radio/board.cmake +++ b/boards/arm/efr32_radio/board.cmake @@ -6,6 +6,8 @@ if(CONFIG_BOARD_EFR32_RADIO_BRD4104A) board_runner_args(jlink "--device=EFR32BG13PxxxF512") elseif(CONFIG_BOARD_EFR32_RADIO_BRD4250B) board_runner_args(jlink "--device=EFR32FG1PxxxF256") +elseif(CONFIG_BOARD_EFR32_RADIO_BRD4180A) +board_runner_args(jlink "--device=EFR32MG21AxxxF1024") endif() include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/efr32_radio/doc/brd4180a.rst b/boards/arm/efr32_radio/doc/brd4180a.rst new file mode 100644 index 00000000000000..ab6f9370c78952 --- /dev/null +++ b/boards/arm/efr32_radio/doc/brd4180a.rst @@ -0,0 +1,162 @@ +.. _efr32_radio_brd4180a: + +EFR32 BRD4180A (SLWRB4180A) +########################### + +Overview +******** + +The EFR32MG21 Mighty Gecko Radio Board is one of the two +radio boards delivered with `EFR32-SLWSTK6006A Website`_. It contains +a Wireless System-On-Chip from the EFR32MG21 family built on an +ARM Cortex®-M33F processor with excellent low power capabilities. + +.. figure:: ./efr32mg21-slwrb4180a.jpg + :height: 260px + :align: center + :alt: SLWRB4180A Mighty Gecko Radio Board + + SLWRB4180A (image courtesy of Silicon Labs) + +The BRD4180A a.k.a. SLWRB4180A radio board plugs into the Wireless Starter Kit +Mainboard BRD4001A and is supported as one of :ref:`efr32_radio`. + +Hardware +******** + +- EFR32MG21A020F1024IM32 Mighty Gecko SoC +- CPU core: ARM Cortex®-M33 with FPU +- Flash memory: 1024 kB +- RAM: 96 kB +- Transmit power: up to +20 dBm +- Operation frequency: 2.4 GHz +- Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). + +For more information about the EFR32MG21 SoC and BRD4180A board, refer to these +documents: + +- `EFR32MG21 Website`_ +- `EFR32MG21 Datasheet`_ +- `EFR32xG21 Reference Manual`_ +- `EFR32-SLWSTK6006A Website`_ +- `BRD4180A User Guide`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtcc | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c port-polling | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ + +Other hardware features are currently not supported by the port. + +Connections and IOs +=================== + +In the following table, the column **Name** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + ++-------+-------------+-------------------------------------+ +| Name | Function | Usage | ++=======+=============+=====================================+ +| PB0 | GPIO | LED0 | ++-------+-------------+-------------------------------------+ +| PB1 | GPIO | LED1 | ++-------+-------------+-------------------------------------+ +| PD2 | GPIO | Push Button PB0 | ++-------+-------------+-------------------------------------+ +| PD3 | GPIO | Push Button PB1 | ++-------+-------------+-------------------------------------+ +| PD4 | GPIO | Board Controller Enable | +| | | EFM_BC_EN | ++-------+-------------+-------------------------------------+ +| PA5 | USART1_TX | UART Console EFM_BC_TX US1_TX | ++-------+-------------+-------------------------------------+ +| PA6 | USART1_RX | UART Console EFM_BC_RX US1_RX | ++-------+-------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: + + ``boards/arm/efr32_radio/efr32_radio_brd4180a_defconfig`` + +System Clock +============ + +The EFR32MG21 SoC is configured to use the 38.4 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFR32MG21 SoC has three USARTs. +USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Please refer to +:ref:`Programming and Debugging EFR32 Radio Board ` +for details on the supported debug interfaces. + +Flashing +======== + +Connect the BRD4001A board with a mounted BRD4180A radio module to your host +computer using the USB port. + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: efr32_radio_brd4180a + :goals: flash + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should see the following message in the terminal: + +.. code-block:: console + + Hello World! efr32_radio_brd4180a + + +.. _EFR32-SLWSTK6006A Website: + https://www.silabs.com/products/development-tools/wireless/efr32xg21-wireless-starter-kit + +.. _BRD4180A User Guide: + https://www.silabs.com/documents/public/user-guides/ug385-brd4180a-user-guide.pdf + +.. _EFR32MG21 Website: + https://www.silabs.com/products/wireless/mesh-networking/efr32mg21-series-2-socs + +.. _EFR32MG21 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32mg21-datasheet.pdf + +.. _EFR32xG21 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg21-rm.pdf diff --git a/boards/arm/efr32_radio/doc/efr32mg21-slwrb4180a.jpg b/boards/arm/efr32_radio/doc/efr32mg21-slwrb4180a.jpg new file mode 100644 index 00000000000000..1bf01c580802bf Binary files /dev/null and b/boards/arm/efr32_radio/doc/efr32mg21-slwrb4180a.jpg differ diff --git a/boards/arm/efr32_radio/doc/index.rst b/boards/arm/efr32_radio/doc/index.rst index 7a134700239af3..2aae6df2c175dc 100644 --- a/boards/arm/efr32_radio/doc/index.rst +++ b/boards/arm/efr32_radio/doc/index.rst @@ -8,6 +8,7 @@ EFR32 Radio Boards brd4104a.rst brd4250b.rst + brd4180a.rst Overview ******** @@ -17,6 +18,7 @@ Support for EFR32 Radio boards is provided by one of the starter kits - `SLWSTK6020B Bluetooth SoC Starter Kit`_ - `SLWSTK6000B Mighty Gecko Wireless Starter Kit`_ - `SLWSTK6061B Proprietary Wireless Starter Kit`_ +- `SLWSTK6006A Mighty Gecko Wireless Starter Kit`_ .. figure:: ./efr32_slwstk6020b.jpg :width: 490px @@ -34,12 +36,14 @@ Wireless Starter Kit Mainboard: consumption of an application or prototype design. - Ultra-low power 128x128 pixel memory LCD - 2 user buttons and 2 LEDs +- 20 pin expansion header - Si7021 Humidity and Temperature Sensor - On-board Segger J-Link USB and Ethernet debugger For more information about the BRD4001A board, refer to these documents: - `EFR32BG13 Blue Gecko Bluetooth Starter Kit User's Guide`_ +- `EFR32MG21 Mighty Gecko Wireless Starter Kit User's Guide`_ - `WSTK Main Board BRD4001A Schematics`_ .. _efr32_radio_supported_features: @@ -52,6 +56,8 @@ The board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | Interface | Controller | Driver/Component | +===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ | NVIC | on-chip | nested vector interrupt controller | +-----------+------------+-------------------------------------+ | SYSTICK | on-chip | systick | @@ -163,9 +169,15 @@ Reset the board and you should see the following message in the terminal: .. _SLWSTK6061B Proprietary Wireless Starter Kit: https://www.silabs.com/products/development-tools/wireless/proprietary/slwstk6061b-efr32-flex-gecko-868-mhz-2-4-ghz-and-sub-ghz-starter-kit +.. _SLWSTK6006A Mighty Gecko Wireless Starter Kit: + https://www.silabs.com/products/development-tools/wireless/efr32xg21-wireless-starter-kit + .. _EFR32BG13 Blue Gecko Bluetooth Starter Kit User's Guide: https://www.silabs.com/documents/public/user-guides/ug279-brd4104a-user-guide.pdf +.. _EFR32MG21 Mighty Gecko Wireless Starter Kit User's Guide: + https://www.silabs.com/documents/public/user-guides/ug385-brd4180a-user-guide.pdf + .. _WSTK Main Board BRD4001A Schematics: https://www.silabs.com/documents/public/schematic-files/WSTK-Main-BRD4001A-A01-schematic.pdf diff --git a/boards/arm/efr32_radio/efr32_radio.dtsi b/boards/arm/efr32_radio/efr32_radio.dtsi index 16f49665f36a33..39779c9e3e1c7c 100644 --- a/boards/arm/efr32_radio/efr32_radio.dtsi +++ b/boards/arm/efr32_radio/efr32_radio.dtsi @@ -67,7 +67,7 @@ location-tx = ; location-clk = ; - cs-gpios = <&gpioa 4 0>; + cs-gpios = <&gpioa 4 GPIO_ACTIVE_LOW>; status = "okay"; diff --git a/boards/arm/efr32_radio/efr32_radio_brd4180a.dts b/boards/arm/efr32_radio/efr32_radio_brd4180a.dts new file mode 100644 index 00000000000000..ee91772dc41928 --- /dev/null +++ b/boards/arm/efr32_radio/efr32_radio_brd4180a.dts @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2020 TriaGnoSys GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Silicon Labs BRD4180A (Mighty Gecko Radio Board)"; + compatible = "silabs,efr32mg21_brd4180a", "silabs,efr32mg21"; + + chosen { + zephyr,console = &usart0; + zephyr,shell-uart = &usart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + sw1 = &button1; + watchdog0 = &wdog0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpiob 0 0>; + label = "LED 0"; + }; + led1: led_1 { + gpios = <&gpiob 1 0>; + label = "LED 1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + /* gpio flags need validation */ + gpios = <&gpiod 2 GPIO_ACTIVE_LOW>; + label = "User Push Button 0"; + }; + button1: button_1 { + /* gpio flags need validation */ + gpios = <&gpiod 3 GPIO_ACTIVE_LOW>; + label = "User Push Button 1"; + }; + }; + +}; + +&cpu0 { + clock-frequency = <38400000>; +}; + +&usart0 { + current-speed = <115200>; + location-rx = ; + location-tx = ; + status = "okay"; +}; + +&rtcc0 { + prescaler = <1>; + status = "okay"; +}; + +&gpio { + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&wdog0 { + status = "okay"; +}; + +&flash0 { + /* + * If the chosen node has no zephyr,code-partition property, the + * application image link uses the entire flash device. If a + * zephyr,code-partition property is defined, the application link + * will be restricted to that partition. + * + * For more information, see: + * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 48 kB for the bootloader */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 0x0000c000>; + read-only; + }; + + /* Reserve 464 kB for the application in slot 0 */ + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000c000 0x00074000>; + }; + + /* Reserve 464 kB for the application in slot 1 */ + slot1_partition: partition@80000 { + label = "image-1"; + reg = <0x00080000 0x00074000>; + }; + + /* Reserve 32 kB for the scratch partition */ + scratch_partition: partition@f4000 { + label = "image-scratch"; + reg = <0x000f4000 0x00008000>; + }; + + /* Set 16Kb of storage at the end of the 1024Kb of flash */ + storage_partition: partition@fc000 { + label = "storage"; + reg = <0x000fc000 0x00004000>; + }; + + }; +}; diff --git a/boards/arm/efr32_radio/efr32_radio_brd4180a.yaml b/boards/arm/efr32_radio/efr32_radio_brd4180a.yaml new file mode 100644 index 00000000000000..93681703fde510 --- /dev/null +++ b/boards/arm/efr32_radio/efr32_radio_brd4180a.yaml @@ -0,0 +1,20 @@ +identifier: efr32_radio_brd4180a +name: BRD4180A +type: mcu +arch: arm +ram: 96 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - counter + - gpio + - nvs + - uart + - watchdog +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/arm/efr32_radio/efr32_radio_brd4180a_defconfig b/boards/arm/efr32_radio/efr32_radio_brd4180a_defconfig new file mode 100644 index 00000000000000..d224ce2a9dc517 --- /dev/null +++ b/boards/arm/efr32_radio/efr32_radio_brd4180a_defconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_EFR32MG21=y +CONFIG_BOARD_EFR32_RADIO_BRD4180A=y +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_GPIO=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=38400000 +CONFIG_CMU_HFCLK_HFXO=y diff --git a/boards/arm/efr32_radio/efr32_radio_brd4250b_defconfig b/boards/arm/efr32_radio/efr32_radio_brd4250b_defconfig index 96fab5eee81671..7afa548a68164a 100644 --- a/boards/arm/efr32_radio/efr32_radio_brd4250b_defconfig +++ b/boards/arm/efr32_radio/efr32_radio_brd4250b_defconfig @@ -2,6 +2,7 @@ CONFIG_SOC_SERIES_EFR32FG1P=y CONFIG_BOARD_EFR32_RADIO_BRD4250B=y +CONFIG_ARM_MPU=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/arm/efr32mg_sltb004a/CMakeLists.txt b/boards/arm/efr32mg_sltb004a/CMakeLists.txt new file mode 100644 index 00000000000000..95981bef099af7 --- /dev/null +++ b/boards/arm/efr32mg_sltb004a/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2020 Christian Taedcke +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_CCS811) + zephyr_library() + zephyr_library_sources(board.c) + zephyr_library_include_directories(${PROJECT_SOURCE_DIR}/drivers) +endif() diff --git a/boards/arm/efr32mg_sltb004a/board.c b/boards/arm/efr32mg_sltb004a/board.c new file mode 100644 index 00000000000000..aff8fbd5706992 --- /dev/null +++ b/boards/arm/efr32mg_sltb004a/board.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Christian Taedcke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "board.h" +#include +#include + +static int efr32mg_sltb004a_init(const struct device *dev) +{ + const struct device *cur_dev; + + ARG_UNUSED(dev); + +#ifdef CONFIG_CCS811 + /* Enable the CCS811 power */ + cur_dev = device_get_binding(CCS811_PWR_ENABLE_GPIO_NAME); + if (!cur_dev) { + printk("CCS811 power gpio port was not found!\n"); + return -ENODEV; + } + + gpio_pin_configure(cur_dev, CCS811_PWR_ENABLE_GPIO_PIN, GPIO_OUTPUT); + gpio_pin_set(cur_dev, CCS811_PWR_ENABLE_GPIO_PIN, 1); + +#endif /* CONFIG_CCS811 */ + + return 0; +} + +/* needs to be done after GPIO driver init */ +SYS_INIT(efr32mg_sltb004a_init, PRE_KERNEL_1, CONFIG_BOARD_INIT_PRIORITY); diff --git a/boards/arm/efr32mg_sltb004a/board.h b/boards/arm/efr32mg_sltb004a/board.h new file mode 100644 index 00000000000000..8b98abdb41719f --- /dev/null +++ b/boards/arm/efr32mg_sltb004a/board.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020 Christian Taedcke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INC_BOARD_H +#define __INC_BOARD_H + +/* CCS811 specific pins */ +#ifdef CONFIG_CCS811 +#define CCS811_PWR_ENABLE_GPIO_NAME "GPIO_F" +#define CCS811_PWR_ENABLE_GPIO_PIN 14 +#endif /* CONFIG_CCS811 */ + +#endif /* __INC_BOARD_H */ diff --git a/boards/arm/efr32mg_sltb004a/doc/index.rst b/boards/arm/efr32mg_sltb004a/doc/index.rst index c5cdc14c34b7d0..2d992a2c34f04f 100644 --- a/boards/arm/efr32mg_sltb004a/doc/index.rst +++ b/boards/arm/efr32mg_sltb004a/doc/index.rst @@ -120,9 +120,9 @@ in the board's and microcontroller's datasheets and manuals. +------+-------------+-----------------------------------+ | PC11 | I2C_SCL | EXP15_I2C_SCL I2C0_SCL #15 | +------+-------------+-----------------------------------+ -| PC4 | I2C_SDA | ENV_I2C_SDA I2C1_SDA #17 | +| PB6 | I2C_SDA | CCS811_I2C_SDA I2C1_SDA #6 | +------+-------------+-----------------------------------+ -| PC5 | I2C_SCL | ENV_I2C_SCL I2C1_SCL #17 | +| PB7 | I2C_SCL | CCS811_I2C_SCL I2C1_SCL #6 | +------+-------------+-----------------------------------+ | PK0 | SPI_MOSI | Flash MOSI US2_TX #29 | +------+-------------+-----------------------------------+ diff --git a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts index e1925faa377802..9ae63b0e18a3b1 100644 --- a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts +++ b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts @@ -76,7 +76,7 @@ location-tx = ; location-clk = ; - cs-gpios = <&gpiok 1 0>; + cs-gpios = <&gpiok 1 GPIO_ACTIVE_LOW>; status = "okay"; @@ -86,8 +86,13 @@ reg = <0>; spi-max-frequency = <80000000>; size = <0x800000>; - has-be32k; jedec-id = [c2 28 14]; + sfdp-bfp = [ + e5 20 f1 ff ff ff 7f 00 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f5 00 82 ed 04 b7 44 83 38 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; }; }; @@ -105,9 +110,16 @@ }; &i2c1 { - location-sda = ; - location-scl = ; - status = "okay"; + location-sda = ; + location-scl = ; + + ccs811: ccs811@5a { + compatible = "ams,ccs811"; + reg = <0x5a>; + label = "CCS811"; + irq-gpios = <&gpiof 13 GPIO_ACTIVE_LOW>; + wake-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; + }; }; &rtcc0 { @@ -145,10 +157,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/faze/CMakeLists.txt b/boards/arm/faze/CMakeLists.txt new file mode 100644 index 00000000000000..bbd703a42031d7 --- /dev/null +++ b/boards/arm/faze/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2020 Seagate Technology LLC +# +# SPDX-License-Identifier: Apache-2.0 +# + +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + # Insert checksum (verified by the bootloader) into the zephyr.bin + # and zephyr.hex images. + COMMAND lpc_checksum -f hex ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME} + COMMAND lpc_checksum -f bin ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} + ) diff --git a/boards/arm/faze/Kconfig.board b/boards/arm/faze/Kconfig.board new file mode 100644 index 00000000000000..22f5bc769c1bc1 --- /dev/null +++ b/boards/arm/faze/Kconfig.board @@ -0,0 +1,9 @@ +# Seagate FireCuda Gaming SSD (FaZe) board + +# Copyright (c) 2020, Seagate Technology LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FAZE + bool "Seagate FireCuda Gaming SSD (FaZe)" + depends on SOC_SERIES_LPC11U6X + select SOC_PART_NUMBER_LPC11U67JBD48 diff --git a/boards/arm/faze/Kconfig.defconfig b/boards/arm/faze/Kconfig.defconfig new file mode 100644 index 00000000000000..39135dabeb84ff --- /dev/null +++ b/boards/arm/faze/Kconfig.defconfig @@ -0,0 +1,11 @@ +# Seagate FireCuda Gaming SSD (FaZe) board + +# Copyright (c) 2020, Seagate Technology LLC +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_FAZE + +config BOARD + default "faze" + +endif # BOARD_FAZE diff --git a/boards/arm/faze/board.cmake b/boards/arm/faze/board.cmake new file mode 100644 index 00000000000000..f56bad2ca394bb --- /dev/null +++ b/boards/arm/faze/board.cmake @@ -0,0 +1,7 @@ +# +# Copyright (c) 2020 Seagate Technology LLC +# +# SPDX-License-Identifier: Apache-2.0 +# + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/faze/doc/firecuda-gaming-ssd.jpg b/boards/arm/faze/doc/firecuda-gaming-ssd.jpg new file mode 100644 index 00000000000000..645c118cc3813e Binary files /dev/null and b/boards/arm/faze/doc/firecuda-gaming-ssd.jpg differ diff --git a/boards/arm/faze/doc/index.rst b/boards/arm/faze/doc/index.rst new file mode 100644 index 00000000000000..9abfe13debb6c2 --- /dev/null +++ b/boards/arm/faze/doc/index.rst @@ -0,0 +1,133 @@ +.. _faze: + +Seagate FireCuda Gaming SSD (FaZe) board +######################################## + +Overview +******** + +The FaZe board can be found in the Seagate FireCuda Gaming SSD devices. A NVMe +SSD and two chips are embedded: an ASMedia ASM2364 USB-to-PCIe bridge controller +and a NXP LPC11U67 MCU. The former is handling the USB type-C to SSD I/Os while +the latter is dedicated to the LED effects. The two chips are connected together +through I2C and GPIOs. + +This Zephyr port is running on the NXP LPC11U67 MCU. + +.. image:: firecuda-gaming-ssd.jpg + :width: 1000px + :align: center + :alt: Seagate FireCuda Gaming SSD + +Hardware +******** + +- NXP LPC11U67 MCU (LQFP48 package): + + - ARM Cortex-M0+ + - 20 KB SRAM: 16 KB (SRAM0) + 2 KB (SRAM1) + 2KB (USB SRAM) + - 128 KB on-chip flash + - 4 KB on-chip EEPROM + +- External devices connected to the NXP LPC11U67 MCU: + + - ASMedia ASM2364 USB-to-PCIe bridge (I2C master on port O). + - 6 RGB LEDs connected connected to a TI LP5030 LED controller (I2C device on + port 1). + - 1 white LED (SSD activity blinking). + +More information can be found here: + +- `LPC11UXX SoC Website`_ +- `LPC11U6X Datasheet`_ +- `LPC11U6X Reference Manual`_ + +Supported Features +================== + +All the hardware features available on the FaZe board are supported in Zephyr. + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| IOCON | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c master/slave controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port interrupt | ++-----------+------------+-------------------------------------+ +| EEPROM | on-chip | eeprom | ++-----------+------------+-------------------------------------+ + +Connections and IOs +=================== + +The IOCON controller can be used to configure the LPC11U67 pins. + ++---------+-----------------+----------------------------+ +| Name | Function | Usage | ++=========+=================+============================+ +| PIO0_2 | GPIO | ASM2364 interrupt | ++---------+-----------------+----------------------------+ +| PIO0_4 | I2C0 | I2C0 SCL | ++---------+-----------------+----------------------------+ +| PIO0_5 | I2C0 | I2C0 SDA | ++---------+-----------------+----------------------------+ +| PIO0_7 | I2C1 | I2C1 SCL | ++---------+-----------------+----------------------------+ +| PIO0_18 | UART | USART0 RX | ++---------+-----------------+----------------------------+ +| PIO0_19 | UART | USART0 TX | ++---------+-----------------+----------------------------+ +| PIO0_20 | GPIO | USB sleep | ++---------+-----------------+----------------------------+ +| PIO1_23 | GPIO | SSD activity white LED | ++---------+-----------------+----------------------------+ +| PIO1_24 | I2C1 | I2C1 SDA | ++---------+-----------------+----------------------------+ + +Programming and Debugging +************************* + +Flashing +======== + +The NXP LPC11U67 MCU can be flashed by connecting an external debug probe to +the SWD port (on-board 4-pins J2 header). In the default OpenOCD configuration +(``boards/arm/faze/support/openocd.cfg``) the ST Link interface is selected. +You may need to replace it with the interface of your debug probe. + +Once the debug probe is connected to both the FaZe board and your host computer +then you can simply run the ``west flash`` command to write a firmware image you +built into flash. + +Debugging +========= + +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `LPC11UXX SoC Website`_ +- `LPC11U6X Datasheet`_ +- `LPC11U6X Reference Manual`_ + +.. _LPC11UXX SoC Website: + https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpc1100-cortex-m0-plus-m0/scalable-entry-level-32-bit-microcontroller-mcu-based-on-arm-cortex-m0-plus-and-cortex-m0-cores:LPC11U00 + +.. _LPC11U6X Datasheet: + https://www.nxp.com/docs/en/data-sheet/LPC11U6X.pdf + +.. _LPC11U6x Reference Manual: + https://www.nxp.com/webapp/Download?colCode=UM10732 diff --git a/boards/arm/faze/faze.dts b/boards/arm/faze/faze.dts new file mode 100644 index 00000000000000..bf1abc5bbf76f0 --- /dev/null +++ b/boards/arm/faze/faze.dts @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2020 Seagate Technology LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include + +/ { + model = "Seagate FireCuda Gaming SSD (FaZe)"; + compatible = "faze", "seagate,faze"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; + + /* These aliases are provided for compatibility with samples. */ + aliases { + led0 = &sata_led; + sw0 = &usb_sleep_button; + eeprom-0 = &eeprom0; + led-controller-0 = &led_controller_0; + }; + + gpio_keys { + compatible = "gpio-keys"; + + /* Handle the USB_SLEEP GPIO as a button. */ + usb_sleep_button: button_0 { + gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; + label = "USB sleep button"; + }; + }; + + leds { + compatible = "gpio-leds"; + + sata_led: led_0 { + gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; + label = "SSD activity LED"; + }; + }; +}; + +&uart0 { + pinmuxs = <&pinmux0 18 IOCON_FUNC1>, <&pinmux0 19 IOCON_FUNC1>; + pinmux-names = "RXD", "TXD"; + current-speed = <115200>; + status = "okay"; +}; + +&i2c0 { + pinmuxs = <&pinmux0 4 IOCON_FUNC1>, + <&pinmux0 5 IOCON_FUNC1>; + pinmux-names = "SCL", "SDA"; + status = "okay"; + + asm2364: asm2364@30 { + compatible = "asmedia,asm2364"; + int-gpios = <&gpio0 2 0>; + reg = <0x30>; + }; +}; + +&i2c1 { + pinmuxs = <&pinmux0 7 (IOCON_FUNC3| IOCON_OPENDRAIN_EN)>, + <&pinmux1 24 (IOCON_FUNC2 | IOCON_OPENDRAIN_EN)>; + pinmux-names = "SCL", "SDA"; + status = "okay"; + + /* TI LP5030 LED controller connected to I2C1. */ + led_controller_0: lp5030@30 { + compatible = "ti,lp5030", "ti,lp503x"; + reg = <0x30>; + label = "LP5030"; + + led0: led_0 { + label = "LED LP5030 0"; + index = <0>; + color-mapping = + , + , + ; + }; + led1: led_1 { + label = "LED LP5030 1"; + index = <1>; + color-mapping = + , + , + ; + }; + led2: led_2 { + label = "LED LP5030 2"; + index = <2>; + color-mapping = + , + , + ; + }; + led3: led_3 { + label = "LED LP5030 3"; + index = <3>; + color-mapping = + , + , + ; + }; + led4: led_4 { + label = "LED LP5030 4"; + index = <4>; + color-mapping = + , + , + ; + }; + led5: led_5 { + label = "LED LP5030 5"; + index = <5>; + color-mapping = + , + , + ; + }; + }; +}; + +&cpu0 { + clock-frequency = <48000000>; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; diff --git a/boards/arm/faze/faze.yaml b/boards/arm/faze/faze.yaml new file mode 100644 index 00000000000000..f4dff699a7ae4f --- /dev/null +++ b/boards/arm/faze/faze.yaml @@ -0,0 +1,21 @@ +# +# Seagate FireCuda Gaming SSD (FaZe) board +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: faze +name: Seagate FireCuda Gaming SSD (FaZe) +type: mcu +arch: arm +ram: 16 +flash: 128 +toolchain: + - zephyr +supported: + - clock_controller + - eeprom + - gpio + - i2c + - pinmux + - serial diff --git a/boards/arm/faze/faze_defconfig b/boards/arm/faze/faze_defconfig new file mode 100644 index 00000000000000..f7c56b87c37a0e --- /dev/null +++ b/boards/arm/faze/faze_defconfig @@ -0,0 +1,23 @@ +# +# Seagate FireCuda Gaming SSD (FaZe) board +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_I2C=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000 +CONFIG_GPIO=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SOC_SERIES_LPC11U6X=y +CONFIG_SOC_LPC11U67=y +CONFIG_MAIN_STACK_SIZE=512 +CONFIG_ISR_STACK_SIZE=768 +CONFIG_GPIO_LPC11U6X=y +CONFIG_I2C_0=y +CONFIG_I2C_1=y +CONFIG_CLOCK_CONTROL_LPC11U6X_ENABLE_SRAM1=y +CONFIG_CLOCK_CONTROL_LPC11U6X_ENABLE_USB_RAM=y +CONFIG_CLOCK_CONTROL_LPC11U6X_PLL_SRC_SYSOSC=y +CONFIG_LED=y +CONFIG_LP503X=y +CONFIG_EEPROM=y diff --git a/boards/arm/faze/pre_dt_board.cmake b/boards/arm/faze/pre_dt_board.cmake new file mode 100644 index 00000000000000..d34042bb2c268a --- /dev/null +++ b/boards/arm/faze/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2019, NXP +# SPDX-License-Identifier: Apache-2.0 + +# Suppress DTC warnings due to all GPIO nodes sharing the same register address. +list(APPEND EXTRA_DTC_FLAGS "-Wno-simple_bus_reg") diff --git a/boards/arm/faze/support/openocd.cfg b/boards/arm/faze/support/openocd.cfg new file mode 100644 index 00000000000000..d7dc6d82c0d4b2 --- /dev/null +++ b/boards/arm/faze/support/openocd.cfg @@ -0,0 +1,39 @@ +# +# Seagate FireCuda Gaming SSD (FaZe) board +# + +# An external debug probe must be connected to the SWD port (4-pins J2 header). +# Here we assume that a ST-LINK in-circuit debugger/programmer is used. You may +# have to replace it with your own interface here. +source [find interface/stlink.cfg] + +# NXP LPC11U24 Cortex-M0 with 128KB Flash and 20KB + 4KB SRAM +set WORKAREASIZE 0x5000 + +set CPUTAPID 0x0bc11477 + +source [find target/lpc11xx.cfg] + +# This ensures that the interrupt vectors (0x0000-0x0200) are re-mapped to +# flash after the "reset halt" command. Else the load/verify functions won't +# work correctly. +# +# Table 8. System memory remap register (SYSMEMREMAP, address 0x40048000) bit +# description +# Bit Symbol Value Description +# 1:0 MAP System memory remap +# 0x0 Boot Loader Mode. Interrupt vectors are re-mapped to +# Boot ROM. +# 0x1 User RAM Mode. Interrupt vectors are re-mapped to +# Static RAM. +# 0x2 User Flash Mode. Interrupt vectors are not re-mapped +# and reside in Flash. +# 31:2 - - Reserved. +$_TARGETNAME configure -event reset-end { + mww 0x40048000 0x02 +} + +# Enable Zephyr thread awareness. +$_TARGETNAME configure -rtos Zephyr + +adapter_khz 100 diff --git a/boards/arm/frdm_k22f/board.cmake b/boards/arm/frdm_k22f/board.cmake index 5904d15768b16b..debe44fba369cd 100644 --- a/boards/arm/frdm_k22f/board.cmake +++ b/boards/arm/frdm_k22f/board.cmake @@ -1,15 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -set_ifndef(OPENSDA_FW daplink) - -if(OPENSDA_FW STREQUAL jlink) - set_ifndef(BOARD_DEBUG_RUNNER jlink) - set_ifndef(BOARD_FLASH_RUNNER jlink) -elseif(OPENSDA_FW STREQUAL daplink) - set_ifndef(BOARD_DEBUG_RUNNER pyocd) - set_ifndef(BOARD_FLASH_RUNNER pyocd) -endif() - board_runner_args(jlink "--device=MK22FN512xxx12") board_runner_args(pyocd "--target=k22f") diff --git a/boards/arm/frdm_k22f/doc/index.rst b/boards/arm/frdm_k22f/doc/index.rst index b90992b5a0868d..73f7b4161610dc 100644 --- a/boards/arm/frdm_k22f/doc/index.rst +++ b/boards/arm/frdm_k22f/doc/index.rst @@ -199,8 +199,15 @@ the `Segger J-Link OpenSDA V2.1 Firmware`_. Note that Segger does provide an OpenSDA J-Link Board-Specific Firmware for this board, however it is not compatible with the DAPLink bootloader. -Add the argument ``-DOPENSDA_FW=jlink`` when you invoke ``west build`` to -override the default runner from pyOCD to J-Link: +Add the arguments ``-DBOARD_FLASH_RUNNER=jlink`` and +``-DBOARD_DEBUG_RUNNER=jlink`` when you invoke ``west build`` to override the +default runner from pyOCD to J-Link: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_k22f + :gen-args: -DBOARD_FLASH_RUNNER=jlink -DBOARD_DEBUG_RUNNER=jlink + :goals: build Configuring a Console ===================== diff --git a/boards/arm/frdm_k22f/frdm_k22f.dts b/boards/arm/frdm_k22f/frdm_k22f.dts index b09c86d496831b..904823da905966 100644 --- a/boards/arm/frdm_k22f/frdm_k22f.dts +++ b/boards/arm/frdm_k22f/frdm_k22f.dts @@ -87,6 +87,11 @@ }; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + &adc0 { status = "okay"; }; @@ -94,9 +99,9 @@ &i2c0 { status = "okay"; - fxos8700@1d { + fxos8700@1c { compatible = "nxp,fxos8700"; - reg = <0x1d>; + reg = <0x1c>; label = "FXOS8700"; int1-gpios = <&gpiod 0 GPIO_ACTIVE_LOW>; int2-gpios = <&gpiod 1 GPIO_ACTIVE_LOW>; @@ -147,7 +152,7 @@ arduino_spi: &spi0 { &flash0 { /* * For more information, see: - * http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html + * https://docs.zephyrproject.org/latest/reference/devicetree/index.html#fixed-flash-partitions */ partitions { compatible = "fixed-partitions"; diff --git a/boards/arm/frdm_k22f/pinmux.c b/boards/arm/frdm_k22f/pinmux.c index 477470fc06b4b6..5cf1427434feca 100644 --- a/boards/arm/frdm_k22f/pinmux.c +++ b/boards/arm/frdm_k22f/pinmux.c @@ -8,28 +8,28 @@ #include #include -static int frdm_k22f_pinmux_init(struct device *dev) +static int frdm_k22f_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTA - struct device *porta = + const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTB - struct device *portb = + const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTC - struct device *portc = + const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTD - struct device *portd = + const struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTE - struct device *porte = + const struct device *porte = device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME); #endif diff --git a/boards/arm/frdm_k64f/Kconfig.defconfig b/boards/arm/frdm_k64f/Kconfig.defconfig index bc5f3cd2e33779..380051685ce850 100644 --- a/boards/arm/frdm_k64f/Kconfig.defconfig +++ b/boards/arm/frdm_k64f/Kconfig.defconfig @@ -42,7 +42,7 @@ endif # PINMUX_MCUX config TEMP_KINETIS default y if "$(dt_nodelabel_enabled,adc1)" - depends on SENSOR + depends on SENSOR && ADC config SPI_0 default y @@ -53,9 +53,6 @@ if NETWORKING config NET_L2_ETHERNET default y if !MODEM -config ETH_MCUX_0 - default y if NET_L2_ETHERNET - endif # NETWORKING endif # BOARD_FRDM_K64F diff --git a/boards/arm/frdm_k64f/board.cmake b/boards/arm/frdm_k64f/board.cmake index c4340c1481c8b1..a7302350a26d2d 100644 --- a/boards/arm/frdm_k64f/board.cmake +++ b/boards/arm/frdm_k64f/board.cmake @@ -1,15 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -set_ifndef(OPENSDA_FW daplink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - board_runner_args(jlink "--device=MK64FN1M0xxx12") board_runner_args(pyocd "--target=k64f") diff --git a/boards/arm/frdm_k64f/doc/index.rst b/boards/arm/frdm_k64f/doc/index.rst index 2dedef32a8a1e0..f045dc195f5778 100644 --- a/boards/arm/frdm_k64f/doc/index.rst +++ b/boards/arm/frdm_k64f/doc/index.rst @@ -239,13 +239,14 @@ the `OpenSDA J-Link Generic Firmware for V3.2 Bootloader`_. Note that Segger does provide an OpenSDA J-Link Board-Specific Firmware for this board, however it is not compatible with the DAPLink bootloader. -Add the argument ``-DOPENSDA_FW=jlink`` when you invoke ``west build`` to -override the default runner from pyOCD to J-Link: +Add the arguments ``-DBOARD_FLASH_RUNNER=jlink`` and +``-DBOARD_DEBUG_RUNNER=jlink`` when you invoke ``west build`` to override the +default runner from pyOCD to J-Link: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: frdm_k64f - :gen-args: -DOPENSDA_FW=jlink + :gen-args: -DBOARD_FLASH_RUNNER=jlink -DBOARD_DEBUG_RUNNER=jlink :goals: build Configuring a Console @@ -300,6 +301,29 @@ should see the following message in the terminal: ***** Booting Zephyr OS v1.14.0-rc1 ***** Hello World! frdm_k64f +Troubleshooting +=============== + +If pyocd raises an uncaught ``DAPAccessIntf.TransferFaultError()`` exception +when you try to flash or debug, it's possible that the K64F flash may have been +locked by a corrupt application. You can unlock it with the following sequence +of pyocd commands: + +.. code-block:: console + + $ pyocd cmd + 0001915:WARNING:target_kinetis:Forcing halt on connect in order to gain control of device + Connected to K64F [Halted]: 0240000026334e450028400d5e0e000e4eb1000097969900 + >>> unlock + 0016178:WARNING:target_kinetis:K64F secure state: unlocked successfully + >>> reinit + 0034584:WARNING:target_kinetis:Forcing halt on connect in order to gain control of device + >>> load build/zephyr/zephyr.bin + [====================] 100% + >>> reset + Resetting target + >>> quit + .. _FRDM-K64F Website: https://www.nxp.com/support/developer-resources/evaluation-and-development-boards/freedom-development-boards/mcu-boards/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F diff --git a/boards/arm/frdm_k64f/frdm_k64f.dts b/boards/arm/frdm_k64f/frdm_k64f.dts index ec2152672f9431..7f717ef336f79b 100644 --- a/boards/arm/frdm_k64f/frdm_k64f.dts +++ b/boards/arm/frdm_k64f/frdm_k64f.dts @@ -87,6 +87,11 @@ }; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + arduino_serial: &uart3 { status = "okay"; current-speed = <115200>; @@ -167,10 +172,7 @@ arduino_spi: &spi0 { }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -218,3 +220,11 @@ arduino_spi: &spi0 { status = "okay"; bus-speed = <125000>; }; + +&edma0 { + status = "okay"; +}; + +&pit0 { + status = "okay"; +}; diff --git a/boards/arm/frdm_k64f/frdm_k64f_defconfig b/boards/arm/frdm_k64f/frdm_k64f_defconfig index 2b10a978edc686..ccc33805b16ea6 100644 --- a/boards/arm/frdm_k64f/frdm_k64f_defconfig +++ b/boards/arm/frdm_k64f/frdm_k64f_defconfig @@ -13,3 +13,4 @@ CONFIG_OSC_EXTERNAL=y # Enable MPU CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/frdm_k64f/pinmux.c b/boards/arm/frdm_k64f/pinmux.c index 2438f5b4fe5cb9..8f798e446ce388 100644 --- a/boards/arm/frdm_k64f/pinmux.c +++ b/boards/arm/frdm_k64f/pinmux.c @@ -8,28 +8,28 @@ #include #include -static int frdm_k64f_pinmux_init(struct device *dev) +static int frdm_k64f_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTA - struct device *porta = + const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTB - struct device *portb = + const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTC - struct device *portc = + const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTD - struct device *portd = + const struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTE - struct device *porte = + const struct device *porte = device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME); #endif @@ -155,6 +155,13 @@ static int frdm_k64f_pinmux_init(struct device *dev) PORT_PCR_PE_MASK | PORT_PCR_PS_MASK); #endif +#if CONFIG_SHIELD_ADAFRUIT_WINC1500 + /* IRQ, ENable, RST */ + pinmux_pin_set(portc, 3, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(portc, 2, PORT_PCR_MUX(kPORT_MuxAsGpio)); + pinmux_pin_set(porta, 2, PORT_PCR_MUX(kPORT_MuxAsGpio)); +#endif + return 0; } diff --git a/boards/arm/frdm_k82f/Kconfig.defconfig b/boards/arm/frdm_k82f/Kconfig.defconfig index 6eac7d33424051..7abd18a82d8c22 100644 --- a/boards/arm/frdm_k82f/Kconfig.defconfig +++ b/boards/arm/frdm_k82f/Kconfig.defconfig @@ -32,7 +32,7 @@ endif # FXOS8700 config FXOS8700_DRDY_INT1 default y - depends on FXOS8700 + depends on FXOS8700_TRIGGER if PINMUX_MCUX diff --git a/boards/arm/frdm_k82f/board.cmake b/boards/arm/frdm_k82f/board.cmake index 17ff7dc35e675e..c420975108d99c 100644 --- a/boards/arm/frdm_k82f/board.cmake +++ b/boards/arm/frdm_k82f/board.cmake @@ -1,15 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -set_ifndef(OPENSDA_FW daplink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - board_runner_args(jlink "--device=MK82FN256xxx15") board_runner_args(pyocd "--target=k82f25615") diff --git a/boards/arm/frdm_k82f/doc/index.rst b/boards/arm/frdm_k82f/doc/index.rst index 616405591be863..797f90a0b9620b 100644 --- a/boards/arm/frdm_k82f/doc/index.rst +++ b/boards/arm/frdm_k82f/doc/index.rst @@ -156,14 +156,14 @@ path. Follow the instructions in :ref:`opensda-jlink-onboard-debug-probe` to program the `OpenSDA J-Link Firmware for FRDM-K82F`_. -Add the argument ``-DOPENSDA_FW=jlink`` when you invoke ``west build`` or -``cmake`` to override the default runner from pyOCD to J-Link: +Add the arguments ``-DBOARD_FLASH_RUNNER=jlink`` and +``-DBOARD_DEBUG_RUNNER=jlink`` when you invoke ``west build`` to override the +default runner from pyOCD to J-Link: .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :tool: all :board: frdm_k82f - :gen-args: -DOPENSDA_FW=jlink + :gen-args: -DBOARD_FLASH_RUNNER=jlink -DBOARD_DEBUG_RUNNER=jlink :goals: build Configuring a Console diff --git a/boards/arm/frdm_k82f/frdm_k82f.dts b/boards/arm/frdm_k82f/frdm_k82f.dts index de20ad46d98a71..e556908104fcee 100644 --- a/boards/arm/frdm_k82f/frdm_k82f.dts +++ b/boards/arm/frdm_k82f/frdm_k82f.dts @@ -106,6 +106,11 @@ }; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + &adc0 { status = "okay"; }; @@ -131,10 +136,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -204,3 +206,7 @@ &usbotg { status = "okay"; }; + +&pit0 { + status = "okay"; +}; diff --git a/boards/arm/frdm_k82f/frdm_k82f.yaml b/boards/arm/frdm_k82f/frdm_k82f.yaml index 1d2f1fe0c32b2a..857ae8e596c105 100644 --- a/boards/arm/frdm_k82f/frdm_k82f.yaml +++ b/boards/arm/frdm_k82f/frdm_k82f.yaml @@ -11,6 +11,7 @@ flash: 256 supported: - adc - arduino_gpio + - counter - gpio - i2c - nvs diff --git a/boards/arm/frdm_k82f/frdm_k82f_defconfig b/boards/arm/frdm_k82f/frdm_k82f_defconfig index 5b7565207f527a..547fa979d27468 100644 --- a/boards/arm/frdm_k82f/frdm_k82f_defconfig +++ b/boards/arm/frdm_k82f/frdm_k82f_defconfig @@ -14,3 +14,4 @@ CONFIG_OSC_LOW_POWER=y # Enable MPU CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/frdm_k82f/pinmux.c b/boards/arm/frdm_k82f/pinmux.c index 89a433eef17927..3a59b8e9a42238 100644 --- a/boards/arm/frdm_k82f/pinmux.c +++ b/boards/arm/frdm_k82f/pinmux.c @@ -8,28 +8,28 @@ #include #include -static int frdm_k82f_pinmux_init(struct device *dev) +static int frdm_k82f_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTA - __unused struct device *porta = + __unused const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTB - __unused struct device *portb = + __unused const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTC - __unused struct device *portc = + __unused const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTD - __unused struct device *portd = + __unused const struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTE - __unused struct device *porte = + __unused const struct device *porte = device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME); #endif diff --git a/boards/arm/frdm_kl25z/board.cmake b/boards/arm/frdm_kl25z/board.cmake index 9c397b36c51924..7f7a37db23f18e 100644 --- a/boards/arm/frdm_kl25z/board.cmake +++ b/boards/arm/frdm_kl25z/board.cmake @@ -1,15 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -set_ifndef(OPENSDA_FW daplink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - board_runner_args(jlink "--device=MKL25Z128xxx4") board_runner_args(pyocd "--target=kl25z") diff --git a/boards/arm/frdm_kl25z/doc/index.rst b/boards/arm/frdm_kl25z/doc/index.rst index 775c1ed1d0c91b..dd845bf245ddb9 100644 --- a/boards/arm/frdm_kl25z/doc/index.rst +++ b/boards/arm/frdm_kl25z/doc/index.rst @@ -149,13 +149,14 @@ path. Follow the instructions in :ref:`opensda-jlink-onboard-debug-probe` to program the `OpenSDA J-Link FRDM-KL25Z Firmware`_. -Add the argument ``-DOPENSDA_FW=jlink`` when you invoke ``west build`` to -override the default runner from pyOCD to J-Link: +Add the arguments ``-DBOARD_FLASH_RUNNER=jlink`` and +``-DBOARD_DEBUG_RUNNER=jlink`` when you invoke ``west build`` to override the +default runner from pyOCD to J-Link: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: frdm_kl25z - :gen-args: -DOPENSDA_FW=jlink + :gen-args: -DBOARD_FLASH_RUNNER=jlink -DBOARD_DEBUG_RUNNER=jlink :goals: build Configuring a Console diff --git a/boards/arm/frdm_kl25z/frdm_kl25z.dts b/boards/arm/frdm_kl25z/frdm_kl25z.dts index cf45332eb514cf..10d986463d61b3 100644 --- a/boards/arm/frdm_kl25z/frdm_kl25z.dts +++ b/boards/arm/frdm_kl25z/frdm_kl25z.dts @@ -81,6 +81,11 @@ }; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + &cpu0 { clock-frequency = <48000000>; }; diff --git a/boards/arm/frdm_kl25z/pinmux.c b/boards/arm/frdm_kl25z/pinmux.c index 936639a4ead261..e0f8489b2f0c8e 100644 --- a/boards/arm/frdm_kl25z/pinmux.c +++ b/boards/arm/frdm_kl25z/pinmux.c @@ -8,28 +8,28 @@ #include #include -static int frdm_kl25z_pinmux_init(struct device *dev) +static int frdm_kl25z_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTA - struct device *porta = + const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTB - struct device *portb = + const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #if defined(CONFIG_PINMUX_MCUX_PORTC) - struct device *portc = + const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTD - struct device *portd = + const struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME); #endif #if defined(CONFIG_PINMUX_MCUX_PORTE) - struct device *porte = + const struct device *porte = device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME); #endif diff --git a/boards/arm/frdm_kw41z/Kconfig.defconfig b/boards/arm/frdm_kw41z/Kconfig.defconfig index 18379993387906..7f5d1933538b11 100644 --- a/boards/arm/frdm_kw41z/Kconfig.defconfig +++ b/boards/arm/frdm_kw41z/Kconfig.defconfig @@ -33,7 +33,7 @@ endif # PINMUX_MCUX config FXOS8700_DRDY_INT1 default y - depends on FXOS8700 + depends on FXOS8700_TRIGGER config SPI_0 default y diff --git a/boards/arm/frdm_kw41z/board.cmake b/boards/arm/frdm_kw41z/board.cmake index f6ed395c8222e8..c0f79373c8cf6e 100644 --- a/boards/arm/frdm_kw41z/board.cmake +++ b/boards/arm/frdm_kw41z/board.cmake @@ -1,17 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -set_ifndef(OPENSDA_FW daplink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - board_runner_args(jlink "--device=MKW41Z512xxx4") board_runner_args(pyocd "--target=kw41z4") -include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/frdm_kw41z/doc/index.rst b/boards/arm/frdm_kw41z/doc/index.rst index 6e9459231d67e2..acf96cea39872f 100644 --- a/boards/arm/frdm_kw41z/doc/index.rst +++ b/boards/arm/frdm_kw41z/doc/index.rst @@ -170,13 +170,14 @@ path. Follow the instructions in :ref:`opensda-jlink-onboard-debug-probe` to program the `OpenSDA J-Link FRDM-KW41Z Firmware`_. -Add the argument ``-DOPENSDA_FW=jlink`` when you invoke ``west build`` to -override the default runner from pyOCD to J-Link: +Add the arguments ``-DBOARD_FLASH_RUNNER=jlink`` and +``-DBOARD_DEBUG_RUNNER=jlink`` when you invoke ``west build`` to override the +default runner from pyOCD to J-Link: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: frdm_kw41z - :gen-args: -DOPENSDA_FW=jlink + :gen-args: -DBOARD_FLASH_RUNNER=jlink -DBOARD_DEBUG_RUNNER=jlink :goals: build Configuring a Console diff --git a/boards/arm/frdm_kw41z/frdm_kw41z.dts b/boards/arm/frdm_kw41z/frdm_kw41z.dts index 62be8e3170b642..66a1794ebb9cf5 100644 --- a/boards/arm/frdm_kw41z/frdm_kw41z.dts +++ b/boards/arm/frdm_kw41z/frdm_kw41z.dts @@ -102,6 +102,11 @@ }; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + &adc0 { status = "okay"; }; diff --git a/boards/arm/frdm_kw41z/pinmux.c b/boards/arm/frdm_kw41z/pinmux.c index c27637da47a5f5..2cf28ab3d0b148 100644 --- a/boards/arm/frdm_kw41z/pinmux.c +++ b/boards/arm/frdm_kw41z/pinmux.c @@ -8,20 +8,20 @@ #include #include -static int frdm_kw41z_pinmux_init(struct device *dev) +static int frdm_kw41z_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTA - struct device *porta = + const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTB - struct device *portb = + const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTC - struct device *portc = + const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif diff --git a/boards/arm/google_kukui/CMakeLists.txt b/boards/arm/google_kukui/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/google_kukui/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/google_kukui/google_kukui.dts b/boards/arm/google_kukui/google_kukui.dts index dde8dd3e4c4851..e4968a2011278b 100644 --- a/boards/arm/google_kukui/google_kukui.dts +++ b/boards/arm/google_kukui/google_kukui.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "Google Kukui EC"; - compatible = "st,stm32f098rc", "st,stm32f098"; + compatible = "google,kukui-ec", "st,stm32f098"; chosen { zephyr,console = &usart1; @@ -20,6 +21,7 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; @@ -39,11 +41,13 @@ }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pa11 &i2c2_sda_pa12>; status = "okay"; clock-frequency = ; }; diff --git a/boards/arm/google_kukui/pinmux.c b/boards/arm/google_kukui/pinmux.c deleted file mode 100644 index a2edcc7db88db9..00000000000000 --- a/boards/arm/google_kukui/pinmux.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2019 The Chromium OS Authors - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F0_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F0_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F0_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F0_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PA11, STM32F0_PINMUX_FUNC_PA11_I2C2_SCL}, - {STM32_PIN_PA12, STM32F0_PINMUX_FUNC_PA12_I2C2_SDA}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/hexiwear_k64/Kconfig.defconfig b/boards/arm/hexiwear_k64/Kconfig.defconfig index 2f7f7a9e34f655..9ed25781ac920e 100644 --- a/boards/arm/hexiwear_k64/Kconfig.defconfig +++ b/boards/arm/hexiwear_k64/Kconfig.defconfig @@ -59,8 +59,4 @@ config SPI_2 endif # SPI -config ETH_MCUX_0 - default y - depends on NET_L2_ETHERNET - endif # BOARD_HEXIWEAR_K64 diff --git a/boards/arm/hexiwear_k64/board.cmake b/boards/arm/hexiwear_k64/board.cmake index ba5ff43c34076c..487cfeb0d0d7ca 100644 --- a/boards/arm/hexiwear_k64/board.cmake +++ b/boards/arm/hexiwear_k64/board.cmake @@ -1,17 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - board_runner_args(pyocd "--target=k64f") board_runner_args(jlink "--device=MK64FN1M0xxx12") -include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/hexiwear_k64/doc/index.rst b/boards/arm/hexiwear_k64/doc/index.rst index a0030e2a742e37..1e80b10b1b3678 100644 --- a/boards/arm/hexiwear_k64/doc/index.rst +++ b/boards/arm/hexiwear_k64/doc/index.rst @@ -189,13 +189,14 @@ program the `OpenSDA DAPLink Hexiwear Firmware`_. Check that switches SW1 and SW2 are **on**, and SW3 and SW4 are **off** to ensure K64F SWD signals are connected to the OpenSDA microcontroller. -Add the argument ``-DOPENSDA_FW=daplink`` when you invoke ``west build`` to -override the default runner from J-Link to pyOCD: +Add the arguments ``-DBOARD_FLASH_RUNNER=pyocd`` and +``-DBOARD_DEBUG_RUNNER=pyocd`` when you invoke ``west build`` to override the +default runner from J-Link to pyOCD: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: hexiwear_k64 - :gen-args: -DOPENSDA_FW=daplink + :gen-args: -DBOARD_FLASH_RUNNER=pyocd -DBOARD_DEBUG_RUNNER=pyocd :goals: build Configuring a Console diff --git a/boards/arm/hexiwear_k64/hexiwear_k64.dts b/boards/arm/hexiwear_k64/hexiwear_k64.dts index 4b919f33e1b79a..0ab61e888ddc89 100644 --- a/boards/arm/hexiwear_k64/hexiwear_k64.dts +++ b/boards/arm/hexiwear_k64/hexiwear_k64.dts @@ -59,6 +59,11 @@ }; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + &cpu0 { clock-frequency = <120000000>; }; @@ -135,10 +140,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/hexiwear_k64/hexiwear_k64_defconfig b/boards/arm/hexiwear_k64/hexiwear_k64_defconfig index 7411925dab4461..5f3c7e633fa271 100644 --- a/boards/arm/hexiwear_k64/hexiwear_k64_defconfig +++ b/boards/arm/hexiwear_k64/hexiwear_k64_defconfig @@ -11,3 +11,5 @@ CONFIG_GPIO=y CONFIG_PINMUX=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 CONFIG_OSC_LOW_POWER=y +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/hexiwear_k64/pinmux.c b/boards/arm/hexiwear_k64/pinmux.c index ad37ab157395d1..91fbb86432525f 100644 --- a/boards/arm/hexiwear_k64/pinmux.c +++ b/boards/arm/hexiwear_k64/pinmux.c @@ -9,24 +9,24 @@ #include #include -static int hexiwear_k64_pinmux_init(struct device *dev) +static int hexiwear_k64_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTB - struct device *portb = + const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTC - struct device *portc = + const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTD - struct device *portd = + const struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTE - struct device *porte = + const struct device *porte = device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME); #endif @@ -52,7 +52,7 @@ static int hexiwear_k64_pinmux_init(struct device *dev) /* 3V3B_EN */ pinmux_pin_set(portb, 12, PORT_PCR_MUX(kPORT_MuxAsGpio)); - struct device *gpiob = + const struct device *gpiob = device_get_binding(DT_LABEL(DT_NODELABEL(gpiob))); gpio_pin_configure(gpiob, 12, GPIO_OUTPUT_LOW); @@ -84,13 +84,13 @@ static int hexiwear_k64_pinmux_init(struct device *dev) #endif #if defined(CONFIG_MAX30101) && DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) - struct device *porta = + const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); /* LDO - MAX30101 power supply */ pinmux_pin_set(porta, 29, PORT_PCR_MUX(kPORT_MuxAsGpio)); - struct device *gpioa = + const struct device *gpioa = device_get_binding(DT_LABEL(DT_NODELABEL(gpioa))); gpio_pin_configure(gpioa, 29, GPIO_OUTPUT_HIGH); @@ -99,7 +99,7 @@ static int hexiwear_k64_pinmux_init(struct device *dev) #ifdef CONFIG_BATTERY_SENSE pinmux_pin_set(portc, 14, PORT_PCR_MUX(kPORT_MuxAsGpio)); - struct device *gpioc = + const struct device *gpioc = device_get_binding(DT_LABEL(DT_NODELABEL(gpioc))); gpio_pin_configure(gpioc, 14, GPIO_OUTPUT_LOW); diff --git a/boards/arm/hexiwear_kw40z/board.cmake b/boards/arm/hexiwear_kw40z/board.cmake index cb76035c506d92..a93baa325e6f33 100644 --- a/boards/arm/hexiwear_kw40z/board.cmake +++ b/boards/arm/hexiwear_kw40z/board.cmake @@ -1,15 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - board_runner_args(jlink "--device=MKW40Z160xxx4") board_runner_args(pyocd "--target=kw40z4") diff --git a/boards/arm/hexiwear_kw40z/hexiwear_kw40z.dts b/boards/arm/hexiwear_kw40z/hexiwear_kw40z.dts index 2c43ff55a6b881..26e0aa5ff906a0 100644 --- a/boards/arm/hexiwear_kw40z/hexiwear_kw40z.dts +++ b/boards/arm/hexiwear_kw40z/hexiwear_kw40z.dts @@ -14,6 +14,11 @@ }; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + &adc0 { status = "okay"; }; diff --git a/boards/arm/hexiwear_kw40z/pinmux.c b/boards/arm/hexiwear_kw40z/pinmux.c index 76c2c8af6c693a..6a578f6d77f333 100644 --- a/boards/arm/hexiwear_kw40z/pinmux.c +++ b/boards/arm/hexiwear_kw40z/pinmux.c @@ -8,17 +8,17 @@ #include #include -static int hexiwear_kw40z_pinmux_init(struct device *dev) +static int hexiwear_kw40z_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTB - struct device *portb = + const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTC - struct device *portc = + const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif diff --git a/boards/arm/holyiot_yj16019/Kconfig.defconfig b/boards/arm/holyiot_yj16019/Kconfig.defconfig index c06046fa0f1fa2..a3dec522615499 100644 --- a/boards/arm/holyiot_yj16019/Kconfig.defconfig +++ b/boards/arm/holyiot_yj16019/Kconfig.defconfig @@ -14,10 +14,6 @@ config GPIO_AS_PINRESET config UART_NRFX default n -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/holyiot_yj16019/board.cmake b/boards/arm/holyiot_yj16019/board.cmake index e1d56a343e75bf..ed0c908e741abd 100644 --- a/boards/arm/holyiot_yj16019/board.cmake +++ b/boards/arm/holyiot_yj16019/board.cmake @@ -1,4 +1,4 @@ -board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +board_runner_args(nrfjprog "--softreset") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/holyiot_yj16019/holyiot_yj16019.dts b/boards/arm/holyiot_yj16019/holyiot_yj16019.dts index 1e9f2cd109ca4c..0ffa22c5de717d 100644 --- a/boards/arm/holyiot_yj16019/holyiot_yj16019.dts +++ b/boards/arm/holyiot_yj16019/holyiot_yj16019.dts @@ -54,10 +54,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/ip_k66f/Kconfig.defconfig b/boards/arm/ip_k66f/Kconfig.defconfig index 468b511b7088a8..56845b8a1b093e 100644 --- a/boards/arm/ip_k66f/Kconfig.defconfig +++ b/boards/arm/ip_k66f/Kconfig.defconfig @@ -9,24 +9,43 @@ config BOARD default "ip_k66f" config OSC_XTAL0_FREQ - default 50000000 + default 12000000 config MCG_PRDIV0 default 0x0 config MCG_VDIV0 - default 0x4 + default 0xe config MCG_FCRDIV default 1 +if NETWORKING + +config NET_L2_ETHERNET + default y + +config ETH_MCUX + default y if NET_L2_ETHERNET + +config ETH_MCUX_RMII_EXT_CLK + default y if ETH_MCUX + +config ETH_MCUX_NO_PHY_SMI + default y if ETH_MCUX + +endif # NETWORKING + if PINMUX_MCUX config PINMUX_MCUX_PORTA default y config PINMUX_MCUX_PORTB - default y if SPI_1 + default y if "$(dt_nodelabel_enabled,spi1)" && SPI + +config PINMUX_MCUX_PORTE + default y if "$(dt_nodelabel_enabled,enet)" && NET_L2_ETHERNET endif # PINMUX_MCUX diff --git a/boards/arm/ip_k66f/doc/index.rst b/boards/arm/ip_k66f/doc/index.rst index 7eaeb674d4cd8e..38acc3dc1dcc37 100644 --- a/boards/arm/ip_k66f/doc/index.rst +++ b/boards/arm/ip_k66f/doc/index.rst @@ -160,3 +160,17 @@ Step through the application in your debugger. .. _OpenSDA J-Link Generic Firmware for V3.2 Bootloader: https://www.segger.com/downloads/jlink/OpenSDA_V3_2 + +Serial console +============== + +The ``ip_k66f`` board only uses Segger's RTT console for providing serial +console. There is no physical serial port available. + +- To communicate with this board one needs in one console: + +``/opt/SEGGER/JLink_V664/JLinkRTTLogger -Device MK66FN2M0XXX18 -RTTChannel 1 -if SWD -Speed 4000 ~/rtt.log`` + +- In another one: + +``nc localhost 19021`` diff --git a/boards/arm/ip_k66f/ip_k66f.dts b/boards/arm/ip_k66f/ip_k66f.dts index f365105449f3d4..1f6e933bfe8f0e 100644 --- a/boards/arm/ip_k66f/ip_k66f.dts +++ b/boards/arm/ip_k66f/ip_k66f.dts @@ -15,6 +15,7 @@ aliases { led0 = &red0_led; led2 = &red2_led; + dsa-spi = &spi1; }; chosen { @@ -41,6 +42,11 @@ clock-frequency = <120000000>; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + &gpioa { status = "okay"; }; @@ -50,10 +56,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -89,3 +92,30 @@ }; }; }; + +&enet { + status = "okay"; + + fixed-link { + speed = <100>; + full-duplex; + }; +}; + +&spi1 { + status = "okay"; + + clock-frequency = <44000000>; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioe { + status = "okay"; +}; diff --git a/boards/arm/ip_k66f/ip_k66f_defconfig b/boards/arm/ip_k66f/ip_k66f_defconfig index bb7ca931363b4c..29c4e30430cfe2 100644 --- a/boards/arm/ip_k66f/ip_k66f_defconfig +++ b/boards/arm/ip_k66f/ip_k66f_defconfig @@ -8,9 +8,19 @@ CONFIG_GPIO=y CONFIG_PINMUX=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=180000000 CONFIG_OSC_LOW_POWER=y -CONFIG_OSC_XTAL0_FREQ=12000000 -CONFIG_K6X_FLEXBUS_CLOCK_DIVIDER=2 +CONFIG_K6X_BUS_CLOCK_DIVIDER=3 +CONFIG_K6X_FLEXBUS_CLOCK_DIVIDER=3 +CONFIG_K6X_FLASH_CLOCK_DIVIDER=7 CONFIG_USE_SEGGER_RTT=y +# Add RTT console support +CONFIG_CONSOLE=y +CONFIG_RTT_CONSOLE=y +CONFIG_SEGGER_RTT_BUFFER_SIZE_DOWN=64 + # Enable MPU CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y + +# The KSZ8794 needs SPI to get MII registers data +CONFIG_SPI=y diff --git a/boards/arm/ip_k66f/pinmux.c b/boards/arm/ip_k66f/pinmux.c index 1557df90e34c6d..1d1e7f4e239fc7 100644 --- a/boards/arm/ip_k66f/pinmux.c +++ b/boards/arm/ip_k66f/pinmux.c @@ -8,19 +8,53 @@ #include #include -static int ip_k66f_pinmux_init(struct device *dev) +static int ip_k66f_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTA - struct device *porta = + const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); #endif +#ifdef CONFIG_PINMUX_MCUX_PORTB + const struct device *portb = + device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); +#endif + +#ifdef CONFIG_PINMUX_MCUX_PORTE + const struct device *porte = + device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME); +#endif + /* Red0, Red2 LEDs */ pinmux_pin_set(porta, 8, PORT_PCR_MUX(kPORT_MuxAsGpio)); pinmux_pin_set(porta, 10, PORT_PCR_MUX(kPORT_MuxAsGpio)); +#if DT_NODE_HAS_STATUS(DT_NODELABEL(enet), okay) && CONFIG_NET_L2_ETHERNET + pinmux_pin_set(porta, 12, PORT_PCR_MUX(kPORT_MuxAlt4));/* RMII_RXD1 */ + pinmux_pin_set(porta, 13, PORT_PCR_MUX(kPORT_MuxAlt4));/* RMII_RXD0 */ + pinmux_pin_set(porta, 14, PORT_PCR_MUX(kPORT_MuxAlt4));/* RMII_CRS_DV */ + pinmux_pin_set(porta, 15, PORT_PCR_MUX(kPORT_MuxAlt4));/* RMII_RX_EN */ + pinmux_pin_set(porta, 16, PORT_PCR_MUX(kPORT_MuxAlt4));/* RMII_TXD0 */ + pinmux_pin_set(porta, 17, PORT_PCR_MUX(kPORT_MuxAlt4));/* RMII_TXD1 */ + pinmux_pin_set(porta, 24, PORT_PCR_MUX(kPORT_MuxAsGpio));/* !ETH_RST */ + pinmux_pin_set(porta, 25, PORT_PCR_MUX(kPORT_MuxAsGpio));/* !ETH_PME */ + pinmux_pin_set(porta, 26, PORT_PCR_MUX(kPORT_MuxAsGpio));/* !ETH_INT */ +#ifdef CONFIG_PINMUX_MCUX_PORTE + /* RMII_REF_CLK */ + pinmux_pin_set(porte, 26, PORT_PCR_MUX(kPORT_MuxAlt2)); +#endif +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI + /* SPI1 CS0, SCK, SOUT, SIN - Control of KSZ8794 */ + pinmux_pin_set(portb, 10, PORT_PCR_MUX(kPORT_MuxAlt2)); + pinmux_pin_set(portb, 11, PORT_PCR_MUX(kPORT_MuxAlt2)); + pinmux_pin_set(portb, 16, PORT_PCR_MUX(kPORT_MuxAlt2)); + pinmux_pin_set(portb, 17, PORT_PCR_MUX(kPORT_MuxAlt2)); +#endif + return 0; } diff --git a/boards/arm/lpcxpresso11u68/CMakeLists.txt b/boards/arm/lpcxpresso11u68/CMakeLists.txt new file mode 100644 index 00000000000000..9ea073580e2a96 --- /dev/null +++ b/boards/arm/lpcxpresso11u68/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + # Insert checksum (verified by the bootloader) into the zephyr.bin + # and zephyr.hex images. + COMMAND lpc_checksum -f hex ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME} + COMMAND lpc_checksum -f bin ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} + ) diff --git a/boards/arm/lpcxpresso11u68/Kconfig.board b/boards/arm/lpcxpresso11u68/Kconfig.board new file mode 100644 index 00000000000000..721104975a2ded --- /dev/null +++ b/boards/arm/lpcxpresso11u68/Kconfig.board @@ -0,0 +1,9 @@ +# LPCXpresso11U68 board + +# Copyright (c) 2020, Seagate +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LPCXPRESSO11U68 + bool "NXP LPCXPRESSO-11U68" + depends on SOC_SERIES_LPC11U6X + select SOC_PART_NUMBER_LPC11U68JBD100 diff --git a/boards/arm/lpcxpresso11u68/Kconfig.defconfig b/boards/arm/lpcxpresso11u68/Kconfig.defconfig new file mode 100644 index 00000000000000..da0fd7aacacdf8 --- /dev/null +++ b/boards/arm/lpcxpresso11u68/Kconfig.defconfig @@ -0,0 +1,11 @@ +# LPCXpresso11U68 board + +# Copyright (c) 2020, Seagate +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_LPCXPRESSO11U68 + +config BOARD + default "lpcxpresso11u68" + +endif # BOARD_LPCXPRESSO11U68 diff --git a/boards/arm/lpcxpresso11u68/board.cmake b/boards/arm/lpcxpresso11u68/board.cmake new file mode 100644 index 00000000000000..02b54f7ca0d0ee --- /dev/null +++ b/boards/arm/lpcxpresso11u68/board.cmake @@ -0,0 +1,5 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/lpcxpresso11u68/doc/index.rst b/boards/arm/lpcxpresso11u68/doc/index.rst new file mode 100644 index 00000000000000..aa880af08cb827 --- /dev/null +++ b/boards/arm/lpcxpresso11u68/doc/index.rst @@ -0,0 +1,164 @@ +.. _lpcxpresso11u68: + +NXP LPCXpresso11U68 +################### + +Overview +******** + +The LPCXpresso11u68 development board uses an NXP LPC11U68 MCU based +on an ARM Cortex-M0+ core. + +.. figure:: lpcxpresso11u68.png + :width: 800px + :align: center + :alt: LPCXpresso11U68 + +Hardware +******** + +The LPCxpresso 11U68 board provides the following hardware components: + +- LPC11U68 microcontroller in LQFP100 package +- ARM Cortex-M0+ +- Memory: + + - 256KB of flash memory + - 32KB of SRAM + - 2x2KB of additional SRAM + - 4 KB EEPROM +- USB: + + - USB 2.0 Full-Speed device controller +- DMA controller +- 5x USART +- 2x I2C +- 2x SSP with DMA support +- Board power supply: through USB bus or external power supply (3V and 5V) +- Arduino connectors compatible with the 'Arduino UNO' platform +- Tri-color user LED, Power On Led, Reset LED +- Three push buttons: target reset, ISP and user + +More information can be found here: + +- `LPC11UXX SoC Website`_ +- `LPC11U6X Datasheet`_ +- `LPC11U6X Reference Manual`_ +- `LPCXPRESSO11U68 Website`_ +- `LPCXPRESSO11U68 Schematics`_ + +Supported Features +================== + +The lpcxpresso11U68 supports the following features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| IOCON | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c master/slave controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port interrupt | ++-----------+------------+-------------------------------------+ +| EEPROM | on-chip | eeprom | ++-----------+------------+-------------------------------------+ + +Other hardware is not yet supported on Zephyr. + +Connections and IOs +=================== + +The IOCON controller can be used to configure the LPC11U68 pins. + ++---------+-----------------+----------------------------+ +| Name | Function | Usage | ++=========+=================+============================+ +| PIO2_11 | UART | USART RX | ++---------+-----------------+----------------------------+ +| PIO2_12 | UART | USART TX | ++---------+-----------------+----------------------------+ +| PIO2_16 | GPIO | GREEN LED | ++---------+-----------------+----------------------------+ +| PIO2_17 | GPIO | RED LED | ++---------+-----------------+----------------------------+ +| PIO2_18 | GPIO | BLUE_LED | ++---------+-----------------+----------------------------+ +| PIO0_4 | I2C | I2C SCL | ++---------+-----------------+----------------------------+ +| PIO0_5 | I2C | I2C SDA | ++---------+-----------------+----------------------------+ + + +Programming and Debugging +************************* + +Flashing +======== + +The LPCXpresso11U68 board can be flashed by using the on-board LPC-Link2 debug +probe (based on a NXP LPC43xx MCU). This MCU provides either a CMSIS-DAP or +a J-Link interface. It depends on the embedded firmware image. The default +OpenOCD configuration supports the the CMSIS-DAP interface. If you want to +switch to J-Link, then you need to edit the +``boards/arm/lpcxpresso11u68/support/openocd.cfg`` file and to replace:: + + source [find interface/cmsis-dap.cfg] + +with:: + + source [find interface/jlink.cfg] + +.. note:: + The firmware image of the LPC-Link2 can be updated using the + `LPCScrypt tool `_. + +.. note:: + The `Mbed project `_ also provides some firmware images + `here `_. + In addition to a CMSIS-DAP interface, they also provide a convenient update + mechanism through a pseudo USB disk. + +Here are the steps to flash a firmware you built into a LPCXpresso11U68 board: + +#. Connect the "Link" micro-B USB port to your host computer. +#. Next, simply run the ``west flash`` command + +Debugging +========= + +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `LPC11UXX SoC Website`_ +- `LPC11U6X Datasheet`_ +- `LPC11U6X Reference Manual`_ +- `LPCXPRESSO11U68 Website`_ +- `LPCXPRESSO11U68 Schematics`_ + +.. _LPC11UXX SoC Website: + https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpc1100-cortex-m0-plus-m0/scalable-entry-level-32-bit-microcontroller-mcu-based-on-arm-cortex-m0-plus-and-cortex-m0-cores:LPC11U00 + +.. _LPC11U6X Datasheet: + https://www.nxp.com/docs/en/data-sheet/LPC11U6X.pdf + +.. _LPC11U6x Reference Manual: + https://www.nxp.com/webapp/Download?colCode=UM10732 + +.. _LPCXPRESSO11U68 Website: + https://www.nxp.com/design/microcontrollers-developer-resources/lpc-microcontroller-utilities/lpcxpresso-board-for-lpc11u68:OM13058 + +.. _LPCXPRESSO11U68 Schematics: + https://www.nxp.com/downloads/en/schematics/LPC11U68_Xpresso_v2_Schematic_RevC_1.pdf diff --git a/boards/arm/lpcxpresso11u68/doc/lpcxpresso11u68.png b/boards/arm/lpcxpresso11u68/doc/lpcxpresso11u68.png new file mode 100644 index 00000000000000..6c247f766de3e8 Binary files /dev/null and b/boards/arm/lpcxpresso11u68/doc/lpcxpresso11u68.png differ diff --git a/boards/arm/lpcxpresso11u68/lpcxpresso11u68.dts b/boards/arm/lpcxpresso11u68/lpcxpresso11u68.dts new file mode 100644 index 00000000000000..7fcebd2fe746f4 --- /dev/null +++ b/boards/arm/lpcxpresso11u68/lpcxpresso11u68.dts @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2020 Seagate Technology LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +/ { + model = "NXP LPCXPRESSO11U68 board"; + compatible = "lpcxpresso11u68", "nxp,lpc"; + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart4; + }; + + /* These aliases are provided for compatibility with samples. */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + sw0 = &isp_button; + sw1 = &wake_up_button; + eeprom-0 = &eeprom0; + }; + + gpio_keys { + compatible = "gpio-keys"; + isp_button: button_0 { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + label = "ISP enable button"; + }; + wake_up_button: button_1 { + gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; + label = "Wake-up button"; + }; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio2 16 GPIO_ACTIVE_LOW>; + label = "Green LED 0"; + }; + led1: led_1 { + gpios = <&gpio2 17 GPIO_ACTIVE_LOW>; + label = "Red LED 1"; + }; + led2: led_2 { + gpios = <&gpio2 18 GPIO_ACTIVE_LOW>; + label = "Blue LED 2"; + }; + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio1 9 0>, /* A0 */ + <1 0 &gpio0 14 0>, /* A1 */ + <2 0 &gpio0 13 0>, /* A2 */ + <3 0 &gpio0 12 0>, /* A3 */ + <4 0 &gpio0 23 0>, /* A4 */ + <5 0 &gpio0 11 0>, /* A5 */ + <6 0 &gpio2 11 0>, /* D0 */ + <7 0 &gpio2 12 0>, /* D1 */ + <8 0 &gpio1 18 0>, /* D2 */ + <9 0 &gpio1 24 0>, /* D3 */ + <10 0 &gpio1 19 0>, /* D4 */ + <11 0 &gpio1 26 0>, /* D5 */ + <12 0 &gpio1 27 0>, /* D6 */ + <13 0 &gpio1 25 0>, /* D7 */ + <14 0 &gpio1 28 0>, /* D8 */ + <15 0 &gpio2 3 0>, /* D9 */ + <16 0 &gpio0 2 0>, /* D10 */ + <17 0 &gpio0 9 0>, /* D11 */ + <18 0 &gpio0 9 0>, /* D12 */ + <19 0 &gpio1 29 0>, /* D13 */ + <20 0 &gpio0 5 0>, /* D14 */ + <21 0 &gpio0 4 0>; /* D15 */ + }; + +}; + +&uart0 { + pinmuxs = <&pinmux1 26 IOCON_FUNC2>, <&pinmux1 27 IOCON_FUNC2>; + pinmux-names = "RXD", "TXD"; + current-speed = <115200>; + status = "okay"; +}; + +arduino_serial: &uart4 { + pinmuxs = <&pinmux2 11 IOCON_FUNC1>, <&pinmux2 12 IOCON_FUNC1>; + pinmux-names = "RXD", "TXD"; + current-speed = <115200>; + status = "okay"; +}; + +arduino_i2c: &i2c0 { + pinmuxs = <&pinmux0 4 IOCON_FUNC1>, + <&pinmux0 5 IOCON_FUNC1>; + pinmux-names = "SCL", "SDA"; + status = "okay"; +}; + +&cpu0 { + clock-frequency = <48000000>; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; diff --git a/boards/arm/lpcxpresso11u68/lpcxpresso11u68.yaml b/boards/arm/lpcxpresso11u68/lpcxpresso11u68.yaml new file mode 100644 index 00000000000000..dd8b3e681bd7e1 --- /dev/null +++ b/boards/arm/lpcxpresso11u68/lpcxpresso11u68.yaml @@ -0,0 +1,13 @@ +identifier: lpcxpresso11u68 +name: NXP LPCxpresso 11U68 +type: mcu +arch: arm +toolchain: + - zephyr +supported: + - clock_controller + - pinmux + - gpio + - i2c + - serial + - eeprom diff --git a/boards/arm/lpcxpresso11u68/lpcxpresso11u68_defconfig b/boards/arm/lpcxpresso11u68/lpcxpresso11u68_defconfig new file mode 100644 index 00000000000000..26f920c5742fd7 --- /dev/null +++ b/boards/arm/lpcxpresso11u68/lpcxpresso11u68_defconfig @@ -0,0 +1,17 @@ +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000 +CONFIG_GPIO=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SOC_SERIES_LPC11U6X=y +# Since the board has little memory (32k), stack sizes are lowered +# so that the application has more RAM for itself. +CONFIG_MAIN_STACK_SIZE=512 +CONFIG_ISR_STACK_SIZE=768 +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO_LPC11U6X=y +CONFIG_CLOCK_CONTROL_LPC11U6X_ENABLE_SRAM1=y +CONFIG_CLOCK_CONTROL_LPC11U6X_ENABLE_USB_RAM=y +CONFIG_CLOCK_CONTROL_LPC11U6X_PLL_SRC_SYSOSC=y +CONFIG_EEPROM=y diff --git a/boards/arm/lpcxpresso11u68/pre_dt_board.cmake b/boards/arm/lpcxpresso11u68/pre_dt_board.cmake new file mode 100644 index 00000000000000..d34042bb2c268a --- /dev/null +++ b/boards/arm/lpcxpresso11u68/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2019, NXP +# SPDX-License-Identifier: Apache-2.0 + +# Suppress DTC warnings due to all GPIO nodes sharing the same register address. +list(APPEND EXTRA_DTC_FLAGS "-Wno-simple_bus_reg") diff --git a/boards/arm/lpcxpresso11u68/support/openocd.cfg b/boards/arm/lpcxpresso11u68/support/openocd.cfg new file mode 100644 index 00000000000000..3a59e2b51a5008 --- /dev/null +++ b/boards/arm/lpcxpresso11u68/support/openocd.cfg @@ -0,0 +1,42 @@ +# +# NXP LPCXpresso11U68 (evaluation board OM13058) +# +# http://www.nxp.com/board/OM13058.html +# https://www.embeddedartists.com/products/lpc11u68-lpcxpresso/ +# https://os.mbed.com/platforms/LPCXpresso11U68/ +# + +# The on-board LPC-Link2 debug probe (based on a NXP LPC43xx MCU) provides +# either a CMSIS-DAP or a J-Link interface. It depends on the version of the +# embedded firmware. Uncomment the line corresponding to yours. +source [find interface/cmsis-dap.cfg] +# source [find interface/jlink.cfg] + +# NXP LPC11U68 Cortex-M0 with 256kB flash and 32kB + 4kB SRAM. +set WORKAREASIZE 0x5000 + +source [find target/lpc11xx.cfg] + +# This ensures that the interrupt vectors (0x0000-0x0200) are re-mapped to +# flash after the "reset halt" command. Else the load/verify functions won't +# work correctly. +# +# Table 8. System memory remap register (SYSMEMREMAP, address 0x40048000) bit +# description +# Bit Symbol Value Description +# 1:0 MAP System memory remap +# 0x0 Boot Loader Mode. Interrupt vectors are re-mapped to +# Boot ROM. +# 0x1 User RAM Mode. Interrupt vectors are re-mapped to +# Static RAM. +# 0x2 User Flash Mode. Interrupt vectors are not re-mapped +# and reside in Flash. +# 31:2 - - Reserved. +$_TARGETNAME configure -event reset-end { + mww 0x40048000 0x02 +} + +# Enable Zephyr thread awareness. +$_TARGETNAME configure -rtos Zephyr + +adapter_khz 100 diff --git a/boards/arm/lpcxpresso54114/board.cmake b/boards/arm/lpcxpresso54114/board.cmake index dcedd71f11aaf7..6c59415aee9651 100644 --- a/boards/arm/lpcxpresso54114/board.cmake +++ b/boards/arm/lpcxpresso54114/board.cmake @@ -4,13 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -set_ifndef(LPCLINK_FW jlink) - -if(LPCLINK_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -endif() - if(CONFIG_BOARD_LPCXPRESSO54114_M4) board_runner_args(jlink "--device=LPC54114J256_M4" "--reset-after-load") elseif(CONFIG_BOARD_LPCXPRESSO54114_M0) diff --git a/boards/arm/lpcxpresso54114/doc/index.rst b/boards/arm/lpcxpresso54114/doc/index.rst index ee3a6b67e48aae..2c0840d570c46a 100644 --- a/boards/arm/lpcxpresso54114/doc/index.rst +++ b/boards/arm/lpcxpresso54114/doc/index.rst @@ -68,6 +68,8 @@ features: +-----------+------------+-------------------------------------+ | USART | on-chip | serial port-polling | +-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------------+ The default configuration for each core can be found in the defconfig files: diff --git a/boards/arm/lpcxpresso54114/lpcxpresso54114_m4_defconfig b/boards/arm/lpcxpresso54114/lpcxpresso54114_m4_defconfig index de477c38ff1b54..8fbb0b209750ac 100644 --- a/boards/arm/lpcxpresso54114/lpcxpresso54114_m4_defconfig +++ b/boards/arm/lpcxpresso54114/lpcxpresso54114_m4_defconfig @@ -16,3 +16,4 @@ CONFIG_GPIO=y CONFIG_PINMUX=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/lpcxpresso54114/pinmux.c b/boards/arm/lpcxpresso54114/pinmux.c index 9ad0dc2b608eb7..c47e2029c031de 100644 --- a/boards/arm/lpcxpresso54114/pinmux.c +++ b/boards/arm/lpcxpresso54114/pinmux.c @@ -9,23 +9,23 @@ #include #include -static int lpcxpresso_54114_pinmux_init(struct device *dev) +static int lpcxpresso_54114_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_LPC_PORT0 - struct device *port0 = + const struct device *port0 = device_get_binding(CONFIG_PINMUX_MCUX_LPC_PORT0_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_LPC_PORT1 - struct device *port1 = + const struct device *port1 = device_get_binding(CONFIG_PINMUX_MCUX_LPC_PORT1_NAME); #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm0), nxp_lpc_usart, okay) && CONFIG_SERIAL /* USART0 RX, TX */ - const u32_t port0_pin0_config = ( + const uint32_t port0_pin0_config = ( IOCON_PIO_FUNC1 | IOCON_PIO_MODE_INACT | IOCON_PIO_INV_DI | @@ -35,7 +35,7 @@ static int lpcxpresso_54114_pinmux_init(struct device *dev) IOCON_PIO_OPENDRAIN_DI ); - const u32_t port0_pin1_config = ( + const uint32_t port0_pin1_config = ( IOCON_PIO_FUNC1 | IOCON_PIO_MODE_INACT | IOCON_PIO_INV_DI | @@ -51,7 +51,7 @@ static int lpcxpresso_54114_pinmux_init(struct device *dev) #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio0), okay) - const u32_t port0_pin29_config = ( + const uint32_t port0_pin29_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | @@ -62,7 +62,7 @@ static int lpcxpresso_54114_pinmux_init(struct device *dev) pinmux_pin_set(port0, 29, port0_pin29_config); - const u32_t port0_pin24_config = ( + const uint32_t port0_pin24_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | @@ -71,7 +71,7 @@ static int lpcxpresso_54114_pinmux_init(struct device *dev) ); pinmux_pin_set(port0, 24, port0_pin24_config); - const u32_t port0_pin31_config = ( + const uint32_t port0_pin31_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | @@ -81,7 +81,7 @@ static int lpcxpresso_54114_pinmux_init(struct device *dev) ); pinmux_pin_set(port0, 31, port0_pin31_config); - const u32_t port0_pin4_config = ( + const uint32_t port0_pin4_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | @@ -94,7 +94,7 @@ static int lpcxpresso_54114_pinmux_init(struct device *dev) #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay) - const u32_t port1_pin10_config = ( + const uint32_t port1_pin10_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | diff --git a/boards/arm/lpcxpresso55s16/board.cmake b/boards/arm/lpcxpresso55s16/board.cmake index a7ba1c38f22022..7daaf7d25c108f 100644 --- a/boards/arm/lpcxpresso55s16/board.cmake +++ b/boards/arm/lpcxpresso55s16/board.cmake @@ -4,9 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -board_set_debugger_ifnset(jlink) -board_set_flasher_ifnset(jlink) - -board_runner_args(jlink "--device=LPC55S16") +board_runner_args(jlink "--device=LPC55S16" "--reset-after-load") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/lpcxpresso55s16/doc/index.rst b/boards/arm/lpcxpresso55s16/doc/index.rst index 57ad3771e1fe73..4752ef85e13898 100644 --- a/boards/arm/lpcxpresso55s16/doc/index.rst +++ b/boards/arm/lpcxpresso55s16/doc/index.rst @@ -71,6 +71,8 @@ hardware features: +-----------+------------+-------------------------------------+ | SENSOR | off-chip | fxos8700 trigger | +-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------------+ Other hardware features are not currently enabled. @@ -210,7 +212,7 @@ should see the following message in the terminal: https://www.nxp.com/docs/en/nxp/data-sheets/LPC55S1x_PDS.pdf .. _LPC55S16 User Manual: - https://www.nxp.com/docs/en/nxp/user-guides/UM11295.pdf + https://www.nxp.com/webapp/Download?colCode=UM11295 .. _LPCxpresso55S16 Website: https://www.nxp.com/design/development-boards/lpcxpresso-boards/lpcxpresso55s16-development-board:LPC55S16-EVK diff --git a/boards/arm/lpcxpresso55s16/lpcxpresso55s16_common.dtsi b/boards/arm/lpcxpresso55s16/lpcxpresso55s16_common.dtsi index 8ad51583f22d66..e85b20fdd4dd02 100644 --- a/boards/arm/lpcxpresso55s16/lpcxpresso55s16_common.dtsi +++ b/boards/arm/lpcxpresso55s16/lpcxpresso55s16_common.dtsi @@ -55,6 +55,59 @@ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; }; }; + + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 16 0>, /* AN */ + /* Not a GPIO*/ /* RST */ + <2 0 &gpio1 1 0>, /* CS */ + <3 0 &gpio1 2 0>, /* SCK */ + <4 0 &gpio1 3 0>, /* MISO */ + <5 0 &gpio0 26 0>, /* MOSI */ + /* +3.3V */ + /* GND */ + <6 0 &gpio1 5 0>, /* PWM */ + <7 0 &gpio1 18 0>, /* INT */ + <8 0 &gpio1 24 0>, /* RX */ + <9 0 &gpio0 27 0>, /* TX */ + <10 0 &gpio1 20 0>, /* SCL */ + <11 0 &gpio1 21 0>; /* SDA */ + /* +5V */ + /* GND */ + }; + + arduino_header: arduino-connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 16 0>, /* A0 */ + <1 0 &gpio0 23 0>, /* A1 */ + <2 0 &gpio0 0 0>, /* A2 */ + /* R63 DNP, A3 not connected */ + /* <3 0 &gpio1 31 0>,*/ /* A3 */ + <4 0 &gpio0 13 0>, /* A4 */ + <5 0 &gpio0 14 0>, /* A5 */ + <6 0 &gpio1 24 0>, /* D0 */ + <7 0 &gpio0 27 0>, /* D1 */ + <8 0 &gpio0 15 0>, /* D2 */ + <9 0 &gpio1 6 0>, /* D3 */ + <10 0 &gpio1 7 0>, /* D4 */ + <11 0 &gpio1 4 0>, /* D5 */ + <12 0 &gpio1 10 0>, /* D6 */ + <13 0 &gpio1 9 0>, /* D7 */ + <14 0 &gpio1 8 0>, /* D8 */ + <15 0 &gpio1 5 0>, /* D9 */ + <16 0 &gpio1 1 0>, /* D10 */ + <17 0 &gpio0 26 0>, /* D11 */ + <18 0 &gpio1 3 0>, /* D12 */ + <19 0 &gpio1 2 0>, /* D13 */ + <20 0 &gpio1 21 0>, /* D14 */ + <21 0 &gpio1 20 0>; /* D15 */ + }; }; &flexcomm0 { @@ -63,7 +116,7 @@ current-speed = <115200>; }; -arduino_i2c: &flexcomm4 { +&flexcomm4 { status = "okay"; compatible = "nxp,lpc-i2c"; clock-frequency = ; @@ -78,6 +131,14 @@ arduino_i2c: &flexcomm4 { }; }; -arduino_spi: &hs_lspi { +&hs_lspi { status = "okay"; }; + +arduino_i2c: &flexcomm4 {}; + +arduino_spi: &hs_lspi {}; + +mikrobus_i2c: &flexcomm4 {}; + +mikrobus_spi: &hs_lspi {}; diff --git a/boards/arm/lpcxpresso55s16/lpcxpresso55s16_ns.yaml b/boards/arm/lpcxpresso55s16/lpcxpresso55s16_ns.yaml index 759881e4109c33..4d872b10a0417a 100644 --- a/boards/arm/lpcxpresso55s16/lpcxpresso55s16_ns.yaml +++ b/boards/arm/lpcxpresso55s16/lpcxpresso55s16_ns.yaml @@ -15,6 +15,7 @@ toolchain: - gnuarmemb - xtools supported: + - arduino_gpio - arduino_i2c - arduino_spi - gpio diff --git a/boards/arm/lpcxpresso55s16/pinmux.c b/boards/arm/lpcxpresso55s16/pinmux.c index 2bd22bd25a6fe0..de71c9d25ea37f 100644 --- a/boards/arm/lpcxpresso55s16/pinmux.c +++ b/boards/arm/lpcxpresso55s16/pinmux.c @@ -9,23 +9,23 @@ #include #include -static int lpcxpresso_55s16_pinmux_init(struct device *dev) +static int lpcxpresso_55s16_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_LPC_PORT0 - __unused struct device *port0 = + __unused const struct device *port0 = device_get_binding(CONFIG_PINMUX_MCUX_LPC_PORT0_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_LPC_PORT1 - __unused struct device *port1 = + __unused const struct device *port1 = device_get_binding(CONFIG_PINMUX_MCUX_LPC_PORT1_NAME); #endif #if DT_PHA_HAS_CELL(DT_ALIAS(sw0), gpios, pin) /* Wakeup button */ - const u32_t sw0_config = ( + const uint32_t sw0_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | @@ -37,7 +37,7 @@ static int lpcxpresso_55s16_pinmux_init(struct device *dev) #if DT_PHA_HAS_CELL(DT_ALIAS(sw1), gpios, pin) /* USR button */ - const u32_t sw1_config = ( + const uint32_t sw1_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | @@ -49,7 +49,7 @@ static int lpcxpresso_55s16_pinmux_init(struct device *dev) #if DT_PHA_HAS_CELL(DT_ALIAS(sw2), gpios, pin) /* ISP button */ - const u32_t sw2_config = ( + const uint32_t sw2_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | @@ -61,7 +61,7 @@ static int lpcxpresso_55s16_pinmux_init(struct device *dev) #if DT_PHA_HAS_CELL(DT_ALIAS(led0), gpios, pin) /* Red LED */ - const u32_t led0_config = ( + const uint32_t led0_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | @@ -73,7 +73,7 @@ static int lpcxpresso_55s16_pinmux_init(struct device *dev) #if DT_PHA_HAS_CELL(DT_ALIAS(led1), gpios, pin) /* Green LED */ - const u32_t led1_config = ( + const uint32_t led1_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | @@ -85,7 +85,7 @@ static int lpcxpresso_55s16_pinmux_init(struct device *dev) #if DT_PHA_HAS_CELL(DT_ALIAS(led2), gpios, pin) /* Blue LED */ - const u32_t led2_config = ( + const uint32_t led2_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | @@ -97,7 +97,7 @@ static int lpcxpresso_55s16_pinmux_init(struct device *dev) #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm0), nxp_lpc_usart, okay) && CONFIG_SERIAL /* USART0 RX, TX */ - const u32_t port0_pin29_config = ( + const uint32_t port0_pin29_config = ( IOCON_PIO_FUNC1 | IOCON_PIO_MODE_INACT | IOCON_PIO_INV_DI | @@ -105,7 +105,7 @@ static int lpcxpresso_55s16_pinmux_init(struct device *dev) IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI ); - const u32_t port0_pin30_config = ( + const uint32_t port0_pin30_config = ( IOCON_PIO_FUNC1 | IOCON_PIO_MODE_INACT | IOCON_PIO_INV_DI | diff --git a/boards/arm/lpcxpresso55s69/CMakeLists.txt b/boards/arm/lpcxpresso55s69/CMakeLists.txt index b748498d01629e..c48fe259d0f474 100644 --- a/boards/arm/lpcxpresso55s69/CMakeLists.txt +++ b/boards/arm/lpcxpresso55s69/CMakeLists.txt @@ -1,5 +1,6 @@ # # Copyright (c) 2019, NXP +# Copyright (c) 2020, Linaro Limited # # SPDX-License-Identifier: Apache-2.0 # @@ -9,3 +10,91 @@ if(CONFIG_PINMUX_MCUX_LPC) zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_library_sources(pinmux.c) endif() + +if (CONFIG_BUILD_WITH_TFM) + # Set default image versions if not defined elsewhere + if (NOT DEFINED TFM_IMAGE_VERSION_S) + set(TFM_IMAGE_VERSION_S 0.0.0+0) + endif() + + if (NOT DEFINED TFM_IMAGE_VERSION_NS) + set(TFM_IMAGE_VERSION_NS 0.0.0+0) + endif() + + if (NOT CONFIG_TFM_BL2_FALSE) + set(PREPROCESSED_FILE_S "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.o") + set(PREPROCESSED_FILE_NS "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_ns.dir/signing_layout_ns.o") + set(TFM_MCUBOOT_DIR "${ZEPHYR_TFM_MODULE_DIR}/trusted-firmware-m/bl2/ext/mcuboot") + endif() + + # Configure which format (full or hash) to include the public key in + # the image manifest + set(TFM_PUBLIC_KEY_FORMAT "full") + + # Set srec_cat binary name + find_program(SREC_CAT srec_cat) + if(${SREC_CAT} STREQUAL SREC_CAT-NOTFOUND) + message(FATAL_ERROR "'srec_cat' not found. Please install it, or add it to $PATH.") + endif() + + if (CONFIG_TFM_BL2_FALSE) + #merge tfm_s and zephyr_ns to a single image + #offset needs to be the same value as flash_layout.h in TFM + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${SREC_CAT} + ARGS ${CMAKE_BINARY_DIR}/tfm/bin/tfm_s.bin -Binary + ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} -Binary + -offset ${CONFIG_FLASH_LOAD_OFFSET} + -o ${CMAKE_BINARY_DIR}/tfm_merged.bin -Binary + ) + else() + #Create and sign for concatenated binary image, should align with the TF-M BL2 + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + + #Sign secure binary image with public key + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_S} + -k ${CONFIG_TFM_KEY_FILE_S} + --public-key-format ${TFM_PUBLIC_KEY_FORMAT} + --align 1 + -v ${TFM_IMAGE_VERSION_S} + --pad + --pad-header + ${ADD_NS_IMAGE_MIN_VER} + -s auto + -H ${CONFIG_ROM_START_OFFSET} + ${CMAKE_BINARY_DIR}/tfm/bin/tfm_s.bin + ${CMAKE_BINARY_DIR}/tfm_s_signed.bin + + #Sign non-secure binary image with public key + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_NS} + -k ${CONFIG_TFM_KEY_FILE_NS} + --public-key-format ${TFM_PUBLIC_KEY_FORMAT} + --align 1 + -v ${TFM_IMAGE_VERSION_NS} + -s auto + ${ADD_S_IMAGE_MIN_VER} + -H ${CONFIG_ROM_START_OFFSET} + ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} + ${CMAKE_BINARY_DIR}/zephyr_ns_signed.bin + + #Create concatenated binary image from the two independently signed binary file + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/assemble.py + --layout ${PREPROCESSED_FILE_S} + -s ${CMAKE_BINARY_DIR}/tfm_s_signed.bin + -n ${CMAKE_BINARY_DIR}/zephyr_ns_signed.bin + -o ${CMAKE_BINARY_DIR}/tfm_sign.bin + + #Copy mcuboot.bin + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm/bin/bl2.bin ${CMAKE_BINARY_DIR}/mcuboot.bin + + #Merge mcuboot.bin and tfm_sign.bin for flashing + COMMAND ${SREC_CAT} + ARGS ${CMAKE_BINARY_DIR}/mcuboot.bin -Binary + ${CMAKE_BINARY_DIR}/tfm_sign.bin -Binary + -offset 0x8000 #slot0_partition + -o ${CMAKE_BINARY_DIR}/tfm_merged.bin -Binary + ) + endif() +endif() diff --git a/boards/arm/lpcxpresso55s69/Kconfig.defconfig b/boards/arm/lpcxpresso55s69/Kconfig.defconfig index fccce2ca933d24..35efe4e6350ce9 100644 --- a/boards/arm/lpcxpresso55s69/Kconfig.defconfig +++ b/boards/arm/lpcxpresso55s69/Kconfig.defconfig @@ -37,4 +37,47 @@ config FXOS8700_DRDY_INT1 default y depends on FXOS8700_TRIGGER +# For the secure version of the board the firmware is linked at the beginning +# of the flash, or into the code-partition defined in DT if it is intended to +# be loaded by MCUboot. If the secure firmware is to be combined with a non- +# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always +# be restricted to the size of its code partition. +# For the non-secure version of the board, the firmware +# must be linked into the code-partition (non-secure) defined in DT, regardless. +# Apply this configuration below by setting the Kconfig symbols used by +# the linker according to the information extracted from DT partitions. + +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + depends on BOARD_LPCXPRESSO55S69_CPU0 && TRUSTED_EXECUTION_SECURE + +if TRUSTED_EXECUTION_NONSECURE || BOARD_LPCXPRESSO55S69_CPU1 + +config FLASH_LOAD_OFFSET + default 0x40000 if TFM_BL2_FALSE + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config FLASH_LOAD_SIZE + default 0x40000 if TFM_BL2_FALSE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +endif # TRUSTED_EXECUTION_NONSECURE || BOARD_LPCXPRESSO55S69_CPU1 + +config TFM_PROFILE + default "profile_medium" + depends on BUILD_WITH_TFM + endif # BOARD_LPCXPRESSO55S69_CPU0 || BOARD_LPCXPRESSO55S69_CPU1 + +if DMA_MCUX_LPC + +# Memory from the heap pool is used to allocate DMA descriptors for +# channels that use multiple blocks for a DMA transfer. +# Adjust HEAP_MEM_POOL_SIZE in case you need more memory. +config HEAP_MEM_POOL_SIZE + default 4096 + +endif # DMA_MCUX_LPC diff --git a/boards/arm/lpcxpresso55s69/board.cmake b/boards/arm/lpcxpresso55s69/board.cmake index 9b480330e1e35c..791f33a031c290 100644 --- a/boards/arm/lpcxpresso55s69/board.cmake +++ b/boards/arm/lpcxpresso55s69/board.cmake @@ -8,13 +8,6 @@ ## DAP Link implementation in pyocd is underway, ## until then jlink can be used or copy image to storage -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -endif() - if(CONFIG_BOARD_LPCXPRESSO55S69_CPU0) board_runner_args(jlink "--device=LPC55S69_core0") endif() diff --git a/boards/arm/lpcxpresso55s69/doc/index.rst b/boards/arm/lpcxpresso55s69/doc/index.rst index 0bd4e9a0f6a209..c1cf91073b2d9d 100644 --- a/boards/arm/lpcxpresso55s69/doc/index.rst +++ b/boards/arm/lpcxpresso55s69/doc/index.rst @@ -68,6 +68,14 @@ features: +-----------+------------+-------------------------------------+ | USART | on-chip | serial port-polling | +-----------+------------+-------------------------------------+ +| WWDT | on-chip | windowed watchdog timer | ++-----------+------------+-------------------------------------+ +| TrustZone | on-chip | Trusted Firmware-M | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------------+ The default configuration file ``boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig`` @@ -81,6 +89,8 @@ Targets available for this board are: - *lpcxpresso55s69_ns* non-secure (NS) address space for CPU0 - *lpcxpresso55s69_cpu1* CPU1 target, NS only +CPU0 is the only target that can run standalone. +NS target for CPU0 does not work correctly without a secure image enabling it. CPU1 does not work without CPU0 enabling it. Connections and IOs @@ -189,6 +199,21 @@ see the following message in the terminal: ***** Booting Zephyr OS v1.14.0 ***** Hello World! lpcxpresso55s69_cpu0 +Building and flashing secure/non-secure with Arm |reg| TrustZone |reg| +---------------------------------------------------------------------- +The TF-M integration samples can be run using the ``lpcxpresso55s69_ns`` target. +To run we need to manually flash the resulting image (``tfm_merged.bin``) with a +J-Link as follows (reset and erase are for recovering a locked core): + + .. code-block:: console + + JLinkExe -device lpc55s69 -if swd -speed 2000 -autoconnect 1 + J-Link>r + J-Link>erase + J-Link>loadfile build/tfm_merged.bin + +We need to reset the board manually after flashing the image to run this code. + Debugging ========= diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69.dtsi b/boards/arm/lpcxpresso55s69/lpcxpresso55s69.dtsi index 76a694b7853bd4..e7b4bb356a9025 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69.dtsi +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69.dtsi @@ -45,10 +45,10 @@ <5 0 &gpio0 26 0>, /* MOSI */ /* +3.3V */ /* GND */ - <6 0 &gpio1 15 0>, /* PWM */ + <6 0 &gpio1 5 0>, /* PWM */ <7 0 &gpio1 18 0>, /* INT */ - <8 0 &gpio0 27 0>, /* RX */ - <9 0 &gpio1 24 0>, /* TX */ + <8 0 &gpio1 24 0>, /* RX */ + <9 0 &gpio0 27 0>, /* TX */ <10 0 &gpio1 20 0>, /* SCL */ <11 0 &gpio1 21 0>; /* SDA */ /* +5V */ @@ -60,7 +60,7 @@ #gpio-cells = <2>; gpio-map-mask = <0xffffffff 0xffffffc0>; gpio-map-pass-thru = <0 0x3f>; - gpio-map = <0 0 &gpio0 15 0>, /* A0 */ + gpio-map = <0 0 &gpio0 16 0>, /* A0 */ <1 0 &gpio0 23 0>, /* A1 */ <2 0 &gpio0 0 0>, /* A2 */ <3 0 &gpio1 31 0>, /* A3 */ @@ -69,13 +69,13 @@ <6 0 &gpio1 24 0>, /* D0 */ <7 0 &gpio0 27 0>, /* D1 */ <8 0 &gpio0 15 0>, /* D2 */ - <9 0 &gpio1 15 0>, /* D3 */ - <10 0 &gpio1 17 0>, /* D4 */ - <11 0 &gpio1 14 0>, /* D5 */ + <9 0 &gpio1 6 0>, /* D3 */ + <10 0 &gpio1 7 0>, /* D4 */ + <11 0 &gpio1 4 0>, /* D5 */ <12 0 &gpio1 10 0>, /* D6 */ <13 0 &gpio1 9 0>, /* D7 */ - <14 0 &gpio1 5 0>, /* D8 */ - <15 0 &gpio1 8 0>, /* D9 */ + <14 0 &gpio1 8 0>, /* D8 */ + <15 0 &gpio1 5 0>, /* D9 */ <16 0 &gpio1 1 0>, /* D10 */ <17 0 &gpio0 26 0>, /* D11 */ <18 0 &gpio1 3 0>, /* D12 */ @@ -90,6 +90,65 @@ current-speed = <115200>; }; +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + /* Please enable mcuboot's swap move, no scratch */ + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00008000>; + read-only; + }; + slot0_partition: partition@8000 { + label = "image-0"; + reg = <0x00008000 0x00028000>; + }; + slot1_partition: partition@30000 { + label = "image-1"; + reg = <0x00030000 0x00018000>; + }; + slot2_partition: partition@48000 { + label = "image-2"; + reg = <0x00048000 0x00028000>; + }; + slot3_partition: partition@70000 { + label = "image-3"; + reg = <0x00070000 0x00018000>; + }; + /* + * The flash starting at 0x88000 and ending at + * 0x949FF is reserved for the application. + */ + storage_partition: partition@88000 { + label = "storage"; + reg = <0x00088000 0x0000ca00>; + }; + }; +}; + +&sram { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* RAM split used by TFM */ + secure_ram: partition@20000000 { + label = "secure-memory"; + reg = <0x20000000 DT_SIZE_K(136)>; + }; + + non_secure_ram: partition@20022000 { + label = "non-secure-memory"; + reg = <0x20022000 DT_SIZE_K(136)>; + }; + }; +}; + arduino_i2c: &flexcomm4 { compatible = "nxp,lpc-i2c"; clock-frequency = ; diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts index 3c8d13aaac9a41..02c857dbfc8ffa 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts @@ -26,7 +26,7 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,code-partition = &sramx; + zephyr,code-partition = &slot0_partition; zephyr,console = &flexcomm0; zephyr,shell-uart = &flexcomm0; zephyr,entropy = &rng; @@ -75,43 +75,27 @@ &hs_lspi { status = "okay"; + dmas = <&dma0 2>, <&dma0 3>; + dma-names = "rx", "tx"; }; -&flash0 { +&wwdt0 { + status = "okay"; +}; + +&adc0 { + status = "okay"; +}; + +&dma0 { /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions + * The total number of dma channels available is defined by + * FSL_FEATURE_DMA_NUMBER_OF_CHANNELS in the SoC features file. + * Since memory from the heap pool is allocated based on the number + * of DMA channels, set this property to as many channels is needed + * for the platform. Adjust HEAP_MEM_POOL_SIZE in case you need more + * memory. */ - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@10000000 { - label = "mcuboot"; - reg = <0x10000000 0x00010000>; - read-only; - }; - /* - * The flash starting at 0x10010000 and ending at - * 0x1001ffff (sectors 16-31) is reserved for use - * by the application. - */ - storage_partition: partition@1001e000 { - label = "storage"; - reg = <0x1001e000 0x00002000>; - }; - slot0_partition: partition@10020000 { - label = "image-0"; - reg = <0x10020000 0x00020000>; - }; - slot1_partition: partition@10040000 { - label = "image-1"; - reg = <0x10040000 0x00020000>; - }; - scratch_partition: partition@10060000 { - label = "image-scratch"; - reg = <0x10060000 0x0003d800>; - }; - }; + dma-channels = <20>; + status = "okay"; }; diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml index 6ccba958447c58..b193c24aecbcf7 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml @@ -15,8 +15,10 @@ toolchain: - gnuarmemb - xtools supported: + - adc - arduino_i2c - arduino_spi - gpio - i2c - spi + - watchdog diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig index d8e140dd1e1e9d..85c43ed8d072a2 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0_defconfig @@ -15,6 +15,8 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_PINMUX=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y # Enable TrustZone-M CONFIG_TRUSTED_EXECUTION_SECURE=y diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.dts b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.dts index 80a44525afdca3..444ea0f35eb22b 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.dts +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.dts @@ -20,6 +20,7 @@ chosen { zephyr,sram = &sram1; zephyr,flash = &flash0; + zephyr,entropy = &rng; }; }; diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.yaml b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.yaml index 10d6b49ec594d4..95217750e026d2 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.yaml +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1.yaml @@ -4,7 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 # -identifier: lpcxpresso55s69_cpu0 +identifier: lpcxpresso55s69_cpu1 name: NXP LPCXpresso55S69 type: mcu arch: arm diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1_defconfig b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1_defconfig index 105a083799ce6e..be7a1158eb9d98 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1_defconfig +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu1_defconfig @@ -4,16 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 # -CONFIG_ARM=y CONFIG_SOC_SERIES_LPC55XXX=y CONFIG_SOC_LPC55S69_CPU1=y CONFIG_BOARD_LPCXPRESSO55S69_CPU1=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y +CONFIG_GPIO_MCUX_LPC=y CONFIG_PINMUX=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 -# Enable TrustZone-M -CONFIG_TRUSTED_EXECUTION_NONSECURE=y - CONFIG_RUNTIME_NMI=y diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.dts b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.dts index 2632f7318e58eb..82daf1b3ffe761 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.dts +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.dts @@ -24,8 +24,9 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &non_secure_ram; zephyr,flash = &flash0; + zephyr,code-partition = &slot1_partition; zephyr,console = &flexcomm0; zephyr,shell-uart = &flexcomm0; zephyr,entropy = &rng; @@ -35,15 +36,15 @@ compatible = "gpio-keys"; user_button_1: button_0 { label = "User SW1"; - gpios = <&gpio0 5 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; }; user_button_2: button_1 { label = "User SW2"; - gpios = <&gpio1 18 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; }; user_button_3: button_2 { label = "User SW3"; - gpios = <&gpio1 9 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; }; }; }; @@ -78,4 +79,27 @@ &hs_lspi { status = "okay"; + dmas = <&dma0 2>, <&dma0 3>; + dma-names = "rx", "tx"; +}; + +&wwdt0 { + status = "okay"; +}; + +&adc0 { + status = "okay"; +}; + +&dma0 { + /* + * The total number of dma channels available is defined by + * FSL_FEATURE_DMA_NUMBER_OF_CHANNELS in the SoC features file. + * Since memory from the heap pool is allocated based on the number + * of DMA channels, set this property to as many channels is needed + * for the platform. Adjust HEAP_MEM_POOL_SIZE in case you need more + * memory. + */ + dma-channels = <20>; + status = "okay"; }; diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.yaml b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.yaml index 09ac80fc330b9e..3c966a98a5b7e9 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.yaml +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns.yaml @@ -15,6 +15,9 @@ toolchain: - gnuarmemb - xtools supported: + - adc - arduino_spi + - dma - gpio - spi + - watchdog diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns_defconfig b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns_defconfig index 6b95e441f1a10e..b8e81398d0cb56 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns_defconfig +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_ns_defconfig @@ -15,9 +15,12 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_PINMUX=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 -CONFIG_ARM_MPU=y + +# TFM sets up MPU_NS, can't correctly change this configuration yet +CONFIG_ARM_MPU=n # Enable TrustZone-M CONFIG_TRUSTED_EXECUTION_NONSECURE=y - CONFIG_RUNTIME_NMI=y + +CONFIG_BUILD_OUTPUT_HEX=y diff --git a/boards/arm/lpcxpresso55s69/pinmux.c b/boards/arm/lpcxpresso55s69/pinmux.c index e212474884515d..8dbce690327775 100644 --- a/boards/arm/lpcxpresso55s69/pinmux.c +++ b/boards/arm/lpcxpresso55s69/pinmux.c @@ -9,23 +9,23 @@ #include #include -static int lpcxpresso_55s69_pinmux_init(struct device *dev) +static int lpcxpresso_55s69_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_LPC_PORT0 - struct device *port0 = + const struct device *port0 = device_get_binding(CONFIG_PINMUX_MCUX_LPC_PORT0_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_LPC_PORT1 - struct device *port1 = + const struct device *port1 = device_get_binding(CONFIG_PINMUX_MCUX_LPC_PORT1_NAME); #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm0), nxp_lpc_usart, okay) && CONFIG_SERIAL /* USART0 RX, TX */ - const u32_t port0_pin29_config = ( + const uint32_t port0_pin29_config = ( IOCON_PIO_FUNC1 | IOCON_PIO_MODE_INACT | IOCON_PIO_INV_DI | @@ -34,7 +34,7 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) IOCON_PIO_OPENDRAIN_DI ); - const u32_t port0_pin30_config = ( + const uint32_t port0_pin30_config = ( IOCON_PIO_FUNC1 | IOCON_PIO_MODE_INACT | IOCON_PIO_INV_DI | @@ -49,7 +49,7 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) #endif #if DT_PHA_HAS_CELL(DT_ALIAS(sw0), gpios, pin) - const u32_t sw0_config = ( + const uint32_t sw0_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | @@ -63,7 +63,7 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) #if DT_PHA_HAS_CELL(DT_ALIAS(sw1), gpios, pin) - const u32_t sw1_config = ( + const uint32_t sw1_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | @@ -76,7 +76,7 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) #endif #if DT_PHA_HAS_CELL(DT_ALIAS(sw2), gpios, pin) - const u32_t sw2_config = ( + const uint32_t sw2_config = ( IOCON_PIO_FUNC0 | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | @@ -125,8 +125,12 @@ static int lpcxpresso_55s69_pinmux_init(struct device *dev) IOCON_PIO_SLEW_STANDARD | IOCON_PIO_OPENDRAIN_DI); + uint32_t pio_func = IOCON_PIO_FUNC5; /* Flexcomm controlled CS*/ +#if DT_NODE_HAS_PROP(DT_NODELABEL(hs_lspi), cs_gpios) + pio_func = IOCON_PIO_FUNC0; /* GPIO controlled CS*/ +#endif /* PORT1 PIN1 is configured as HS_SPI_SSEL1 */ - pinmux_pin_set(port1, 1, IOCON_PIO_FUNC5 | + pinmux_pin_set(port1, 1, pio_func | IOCON_PIO_MODE_PULLUP | IOCON_PIO_INV_DI | IOCON_PIO_DIGITAL_EN | diff --git a/boards/arm/mec1501modular_assy6885/CMakeLists.txt b/boards/arm/mec1501modular_assy6885/CMakeLists.txt index 7b0c4c7898bd4c..f96a887b053ce8 100644 --- a/boards/arm/mec1501modular_assy6885/CMakeLists.txt +++ b/boards/arm/mec1501modular_assy6885/CMakeLists.txt @@ -24,7 +24,7 @@ else() set(EVERGLADES_SPI_GEN_FILENAME everglades_spi_gen.exe) endif() - find_file(EVERGLADES_SPI_GEN_FINDFILE ${EVERGLADES_SPI_GEN_FILENAME}) + find_file(EVERGLADES_SPI_GEN_FINDFILE ${EVERGLADES_SPI_GEN_FILENAME} NO_DEFAULT_PATH) if(EVERGLADES_SPI_GEN_FINDFILE STREQUAL EVERGLADES_SPI_GEN_FINDFILE-NOTFOUND) message(WARNING "Microchip SPI Image Generation tool (${EVERGLADES_SPI_GEN_FILENAME}) is not available. SPI Image will not be generated.") else() diff --git a/boards/arm/mec1501modular_assy6885/Kconfig.defconfig b/boards/arm/mec1501modular_assy6885/Kconfig.defconfig index f82829b78bac0e..8585e09f172328 100644 --- a/boards/arm/mec1501modular_assy6885/Kconfig.defconfig +++ b/boards/arm/mec1501modular_assy6885/Kconfig.defconfig @@ -54,13 +54,13 @@ config TACH_XEC depends on SENSOR # power management stuff -if SYS_POWER_MANAGEMENT +if PM -config SYS_PM_MIN_RESIDENCY_SLEEP_1 +config PM_MIN_RESIDENCY_SLEEP_1 default 1000 -config SYS_PM_MIN_RESIDENCY_DEEP_SLEEP_1 +config PM_MIN_RESIDENCY_DEEP_SLEEP_1 default 2000 -endif # SYS_POWER_MANAGEMENT +endif # PM endif # BOARD_MEC1501MODULAR_ASSY6885 diff --git a/boards/arm/mec1501modular_assy6885/doc/index.rst b/boards/arm/mec1501modular_assy6885/doc/index.rst index 67c1c448e082a5..381613ca84dd34 100644 --- a/boards/arm/mec1501modular_assy6885/doc/index.rst +++ b/boards/arm/mec1501modular_assy6885/doc/index.rst @@ -7,7 +7,7 @@ Overview ******** The MEC1501 Modular card ASSY6885 is a development board to evaluate the Microchip -MEC15XX series microcontrollers. This board can work standalone or be mated with +MEC152X series microcontrollers. This board can work standalone or be mated with any platform that complies with MECC specification. .. image:: ./mec1501modular_assy6885.png @@ -18,7 +18,7 @@ any platform that complies with MECC specification. Hardware ******** -- MEC1501HB0SZ ARM Cortex-M4 Processor +- MEC1521HA0SZ ARM Cortex-M4 Processor - 256 KB RAM and 64 KB boot ROM - GPIO headers - UART1 using microUSB @@ -28,7 +28,7 @@ Hardware - VCI interface - Independent Hardware Driven PS/2 Ports -At difference from MEC15xx evaluation board, modular MEC1501 exposes the pins +At difference from MEC15xx evaluation board, modular MEC1521 exposes the pins in 2 different ways: 1) Standalone mode via headers @@ -48,7 +48,7 @@ in 2 different ways: The board is powered through the +5V USB Micro A connector or from the MECC connector. -For more information about the SOC please see the `MEC1501 Reference Manual`_ +For more information about the SOC please see the `MEC152x Reference Manual`_ Supported Features ================== @@ -236,8 +236,9 @@ Programming and Debugging Setup ===== -#. Clone the `SPI Image Gen`_ repository or download the files within - that directory. +#. Clone the `MEC152x SPI Image Gen`_ repository or download the files within + that directory. For the pre-production MEC150x use the `MEC150x SPI Image Gen`_ + repository. #. Make the image generation available for Zephyr, by making the tool searchable by path, or by setting an environment variable @@ -245,9 +246,10 @@ Setup .. code-block:: console - export EVERGLADES_SPI_GEN=/everglades_spi_gen_lin64 + export EVERGLADES_SPI_GEN=/everglades_spi_gen_RomE Note that the tools for Linux and Windows have different file names. + For the pre-production MEC1501 SOC use everglades_spi_gen_lin64. #. If needed, a custom SPI image configuration file can be specified to override the default one. @@ -259,10 +261,9 @@ Setup Building ========== - #. Build :ref:`hello_world` application as you would normally do. -#. Once you have ``zephyr.bin``, use the `SPI Image Gen`_ microchip tool +#. Once you have ``zephyr.bin``, use the `MEC152x SPI Image Gen`_ microchip tool to create the final binary. You need the output from this tool to flash in the SHD SPI memory. @@ -309,11 +310,13 @@ References ********** .. target-notes:: -.. _MEC1501 Preliminary Data Sheet: - https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC1501/MEC1501_Datasheet.pdf -.. _MEC1501 Reference Manual: - https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC1501/MEC1501_Datasheet.pdf +.. _MEC152x Preliminary Data Sheet: + https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC152x/MEC152x_Datasheet.pdf +.. _MEC152x Reference Manual: + https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC152x/MEC152x_Datasheet.pdf .. _MEC1501 Modular EC Card - Assy_6885 Rev A0p1: https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC1501/MEC1501%20Modular%20EC%20Card%20-%20Assy_6885%20Rev%20A0p1%20-%20SCH.pdf -.. _SPI Image Gen: +.. _MEC152x SPI Image Gen: + https://github.com/MicrochipTech/CPGZephyrDocs/tree/master/MEC152x/SPI_image_gen +.. _MEC150x SPI Image Gen: https://github.com/MicrochipTech/CPGZephyrDocs/tree/master/MEC1501/SPI_image_gen diff --git a/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885_defconfig b/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885_defconfig index bc351cd6a4b76e..9818b0c11fd6b3 100644 --- a/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885_defconfig +++ b/boards/arm/mec1501modular_assy6885/mec1501modular_assy6885_defconfig @@ -8,6 +8,7 @@ CONFIG_SOC_MEC1501_HSZ=y CONFIG_SOC_SERIES_MEC1501X=y # Make sure external power management setup is as indicated in documentation CONFIG_SOC_MEC1501_VTR3_1_8V=y +CONFIG_SOC_MEC1501_VCI_PINS_AS_GPIOS=n CONFIG_BOARD_MEC1501MODULAR_ASSY6885=y CONFIG_RTOS_TIMER=y diff --git a/boards/arm/mec1501modular_assy6885/pinmux.c b/boards/arm/mec1501modular_assy6885/pinmux.c index d264d26a42614c..cedc84488459c4 100644 --- a/boards/arm/mec1501modular_assy6885/pinmux.c +++ b/boards/arm/mec1501modular_assy6885/pinmux.c @@ -13,22 +13,22 @@ struct pinmux_ports_t { #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay) - struct device *porta; + const struct device *porta; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay) - struct device *portb; + const struct device *portb; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay) - struct device *portc; + const struct device *portc; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay) - struct device *portd; + const struct device *portd; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay) - struct device *porte; + const struct device *porte; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay) - struct device *portf; + const struct device *portf; #endif }; @@ -98,38 +98,62 @@ static void i2c_pinmux(struct pinmux_ports_t *p, uint8_t port_sel) } } -static int board_pinmux_init(struct device *dev) +static void configure_debug_interface(void) +{ + /* No debug support */ + ECS_REGS->DEBUG_CTRL = 0; + ECS_REGS->ETM_CTRL = 0; + +#ifdef CONFIG_SOC_MEC1501_DEBUG_WITHOUT_TRACING + /* Release JTAG TDI and JTAG TDO pins so they can be + * controlled by their respective PCR register (UART2). + * For more details see table 44-1 + */ + ECS_REGS->DEBUG_CTRL = (MCHP_ECS_DCTRL_DBG_EN | + MCHP_ECS_DCTRL_MODE_SWD); +#elif defined(CONFIG_SOC_MEC1501_DEBUG_AND_TRACING) + #if defined(CONFIG_SOC_MEC1501_DEBUG_AND_ETM_TRACING) + #pragma error "TRACE DATA are not exposed in HW connector" + #elif defined(CONFIG_SOC_MEC1501_DEBUG_AND_SWV_TRACING) + ECS_REGS->DEBUG_CTRL = (MCHP_ECS_DCTRL_DBG_EN | + MCHP_ECS_DCTRL_MODE_SWD_SWV); + #endif /* CONFIG_SOC_MEC1501_DEBUG_AND_TRACING */ + +#endif /* CONFIG_SOC_MEC1501_DEBUG_WITHOUT_TRACING */ +} + +static int board_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); struct pinmux_ports_t pinmux_ports; #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay) - struct device *porta = + const struct device *porta = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_000_036))); pinmux_ports.porta = porta; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay) - struct device *portb = + const struct device *portb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_040_076))); pinmux_ports.portb = portb; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay) - struct device *portc = + const struct device *portc = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_100_136))); pinmux_ports.portc = portc; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay) - struct device *portd = + const struct device *portd = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_140_176))); pinmux_ports.portd = portd; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay) - struct device *porte = + const struct device *porte = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_200_236))); pinmux_ports.porte = porte; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay) - struct device *portf = + const struct device *portf = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_240_276))); pinmux_ports.portf = portf; #endif @@ -141,23 +165,33 @@ static int board_pinmux_init(struct device *dev) #ifdef CONFIG_SOC_MEC1501_VTR3_1_8V ECS_REGS->GPIO_BANK_PWR |= MCHP_ECS_VTR3_LVL_18; #endif - /* Release JTAG TDI and JTAG TDO pins so they can be - * controlled by their respective PCR register (UART2). - * For more details see table 44-1 - */ - ECS_REGS->DEBUG_CTRL = (MCHP_ECS_DCTRL_DBG_EN | - MCHP_ECS_DCTRL_MODE_SWD); + + configure_debug_interface(); /* Configure pins that are not GPIOS by default */ +#ifdef CONFIG_SOC_MEC1501_VCI_PINS_AS_GPIOS pinmux_pin_set(porta, MCHP_GPIO_000, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portd, MCHP_GPIO_161, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portd, MCHP_GPIO_162, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portd, MCHP_GPIO_163, MCHP_GPIO_CTRL_MUX_F0); - pinmux_pin_set(portd, MCHP_GPIO_170, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portd, MCHP_GPIO_172, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portf, MCHP_GPIO_250, MCHP_GPIO_CTRL_MUX_F0); +#endif + pinmux_pin_set(portd, MCHP_GPIO_170, MCHP_GPIO_CTRL_MUX_F0); /* See table 2-4 from the data sheet for pin multiplexing*/ +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) + /* Set muxing, for UART 0 TX/RX and power up */ + mchp_pcr_periph_slp_ctrl(PCR_UART0, MCHP_PCR_SLEEP_DIS); + + UART0_REGS->CFG_SEL = (MCHP_UART_LD_CFG_INTCLK + + MCHP_UART_LD_CFG_RESET_SYS + MCHP_UART_LD_CFG_NO_INVERT); + UART0_REGS->ACTV = MCHP_UART_LD_ACTIVATE; + + pinmux_pin_set(portc, MCHP_GPIO_104, MCHP_GPIO_CTRL_MUX_F1); + pinmux_pin_set(portc, MCHP_GPIO_105, MCHP_GPIO_CTRL_MUX_F1); +#endif + #if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay) /* Set muxing, for UART 1 TX/RX and power up */ mchp_pcr_periph_slp_ctrl(PCR_UART1, MCHP_PCR_SLEEP_DIS); @@ -176,10 +210,12 @@ static int board_pinmux_init(struct device *dev) /* ADC pin muxes, ADC00 - ADC07 */ /* Note, by default ETM is enabled ADC00-ADC03 are not available */ +#ifndef CONFIG_SOC_MEC1501_DEBUG_AND_ETM_TRACING pinmux_pin_set(porte, MCHP_GPIO_200, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_201, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_202, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_203, MCHP_GPIO_CTRL_MUX_F1); +#endif pinmux_pin_set(porte, MCHP_GPIO_204, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_205, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_206, MCHP_GPIO_CTRL_MUX_F1); @@ -412,7 +448,7 @@ static int board_pinmux_init(struct device *dev) #endif /* DT_NODE_HAS_STATUS(DT_INST(0, microchip_xec_qmspi), okay) */ #endif /* CONFIG_SPI_XEC_QMSPI */ -#ifdef CONFIG_SYS_PM_DEBUG +#ifdef CONFIG_PM_DEBUG /* * Deep sleep testing: Enable TEST_CLK_OUT on GPIO_060 function 2. * TEST_CLK_OUT is the PLL 48MHz conditioned output. diff --git a/boards/arm/mec1501modular_assy6885/support/spi_cfg.txt b/boards/arm/mec1501modular_assy6885/support/spi_cfg.txt index 95536f911aada4..3ef59d99e414db 100644 --- a/boards/arm/mec1501modular_assy6885/support/spi_cfg.txt +++ b/boards/arm/mec1501modular_assy6885/support/spi_cfg.txt @@ -34,6 +34,5 @@ FwEntryAddress = 0 UseECDSA = false ECDSAPrivKeyFile = ecprivkey001.pem ECDSAPrivKeyPassword = ECPRIVKEY001 -ECDSAPubKeyFile = ecpubkey001_crt.pem FwEncrypt = false AesGenECPubKeyFile = ecpubkey002_crt.pem diff --git a/boards/arm/mec15xxevb_assy6853/Kconfig.defconfig b/boards/arm/mec15xxevb_assy6853/Kconfig.defconfig index 786a4083c55c95..5de03d90be628c 100644 --- a/boards/arm/mec15xxevb_assy6853/Kconfig.defconfig +++ b/boards/arm/mec15xxevb_assy6853/Kconfig.defconfig @@ -71,14 +71,14 @@ config TACH_XEC depends on SENSOR # power management stuff -if SYS_POWER_MANAGEMENT +if PM -config SYS_PM_MIN_RESIDENCY_SLEEP_1 +config PM_MIN_RESIDENCY_SLEEP_1 default 1000 -config SYS_PM_MIN_RESIDENCY_DEEP_SLEEP_1 +config PM_MIN_RESIDENCY_DEEP_SLEEP_1 default 2000 -endif # SYS_POWER_MANAGEMENT +endif # PM endif # BOARD_MEC15XXEVB_ASSY6853 diff --git a/boards/arm/mec15xxevb_assy6853/doc/index.rst b/boards/arm/mec15xxevb_assy6853/doc/index.rst index 1a34b7b7ceab60..a78325f9c4e2e3 100644 --- a/boards/arm/mec15xxevb_assy6853/doc/index.rst +++ b/boards/arm/mec15xxevb_assy6853/doc/index.rst @@ -9,6 +9,11 @@ Overview The MEC15xxEVB_ASSY6853 kit is a future development platform to evaluate the Microchip MEC15XX series microcontrollers. This board needs to be mated with part number MEC1501 144WFBA SOLDER DC ASSY 6860(cpu board) in order to operate. +The MEC152x has superceded the MEC1501 in production. MEC152x is identical to +MEC150x except for an enhanced Boot-ROM SPI loader. The SPI image format has +been updated requiring a new SPI image tool. MEC1501 and MEC152x SPI image +formats are not compatible with each other. Evaluation and cpu boards are +compatible. .. image:: ./mec15xxevb_assy6853.png :width: 600px @@ -18,7 +23,7 @@ part number MEC1501 144WFBA SOLDER DC ASSY 6860(cpu board) in order to operate. Hardware ******** -- MEC1501HB0SZ ARM Cortex-M4 Processor +- MEC1521HA0SZ ARM Cortex-M4 Processor - 256 KB RAM and 64 KB boot ROM - Keyboard interface - ADC & GPIO headers @@ -40,7 +45,7 @@ Hardware - One external LTC2489 delta-sigma ADC with jumper selectable I2C address. - Board power jumper selectable from +5V 2.1mm/5.5mm barrel connector or USB Micro A connector. -For more information about the SOC please see the `MEC1501 Reference Manual`_ +For more information about the SOC's please see `MEC152x Reference Manual`_ Supported Features ================== @@ -84,13 +89,13 @@ Connections and IOs This evaluation board kit is comprised of the following HW blocks: - MEC15xx EVB ASSY 6853 Rev A `MEC15xx EVB Schematic`_ -- MEC1501 144WFBA SOLDER DC ASSY 6860 `MEC1501 Daughter Card Schematic`_ +- MEC1501 144WFBA SOLDER DC ASSY 6883 with MEC152x silicon `MEC1501 Daughter Card Schematic`_ - SPI DONGLE ASSY 6791 `SPI Dongle Schematic`_ System Clock ============ -The MEC1501 MCU is configured to use the 48Mhz internal oscillator with the +The MEC1521 MCU is configured to use the 48Mhz internal oscillator with the on-chip PLL to generate a resulting EC clock rate of 12 MHz. See Processor clock control register in chapter 4 "4.0 POWER, CLOCKS, and RESETS" of the data sheet in the references at the end of this document. @@ -256,8 +261,9 @@ Setup Add directory with program ``dpcmd`` (on Linux) or ``dpcmd.exe`` (on Windows) to your ``PATH``. -#. Clone the `SPI Image Gen`_ repository or download the files within - that directory. +#. Clone the `MEC152x SPI Image Gen`_ repository or download the files within + that directory. For the pre-production MEC150x use `MEC150x SPI Image Gen`_ + repository. #. Make the image generation available for Zephyr, by making the tool searchable by path, or by setting an environment variable @@ -265,9 +271,10 @@ Setup .. code-block:: console - export EVERGLADES_SPI_GEN=/everglades_spi_gen_lin64 + export EVERGLADES_SPI_GEN=/everglades_spi_gen_RomE Note that the tools for Linux and Windows have different file names. + For the pre-production MEC1501 SOC use everglades_spi_gen_lin64. #. If needed, a custom SPI image configuration file can be specified to override the default one. @@ -427,6 +434,10 @@ References https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC1501/MEC1501_Datasheet.pdf .. _MEC1501 Reference Manual: https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC1501/MEC1501_Datasheet.pdf +.. _MEC152x Preliminary Data Sheet: + https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC152x/MEC152x_Datasheet.pdf +.. _MEC152x Reference Manual: + https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC152x/MEC152x_Datasheet.pdf .. _MEC15xx EVB Schematic: https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC1501/Everglades%20EVB%20-%20Assy_6853%20Rev%20A1p1%20-%20SCH.pdf .. _MEC1501 Daughter Card Schematic: @@ -435,7 +446,9 @@ References https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC1501/MEC1503%20Socket%20DC%20for%20EVERGLADES%20EVB%20-%20Assy_6856%20Rev%20A1p0%20-%20SCH.pdf .. _SPI Dongle Schematic: https://github.com/MicrochipTech/CPGZephyrDocs/blob/master/MEC1501/SPI%20Dongles%20and%20Aardvark%20Interposer%20Assy%206791%20Rev%20A1p1%20-%20SCH.pdf -.. _SPI Image Gen: +.. _MEC152x SPI Image Gen: + https://github.com/MicrochipTech/CPGZephyrDocs/tree/master/MEC152x/SPI_image_gen +.. _MEC150x SPI Image Gen: https://github.com/MicrochipTech/CPGZephyrDocs/tree/master/MEC1501/SPI_image_gen .. _SF100 Linux GitHub: https://github.com/DediProgSW/SF100Linux diff --git a/boards/arm/mec15xxevb_assy6853/pinmux.c b/boards/arm/mec15xxevb_assy6853/pinmux.c index ceef9b27e1a9f6..e56ca77a3a1d72 100644 --- a/boards/arm/mec15xxevb_assy6853/pinmux.c +++ b/boards/arm/mec15xxevb_assy6853/pinmux.c @@ -13,22 +13,22 @@ struct pinmux_ports_t { #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay) - struct device *porta; + const struct device *porta; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay) - struct device *portb; + const struct device *portb; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay) - struct device *portc; + const struct device *portc; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay) - struct device *portd; + const struct device *portd; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay) - struct device *porte; + const struct device *porte; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay) - struct device *portf; + const struct device *portf; #endif }; @@ -98,38 +98,64 @@ static void i2c_pinmux(struct pinmux_ports_t *p, uint8_t port_sel) } } -static int board_pinmux_init(struct device *dev) +static void configure_debug_interface(void) +{ + /* No debug support */ + ECS_REGS->DEBUG_CTRL = 0; + ECS_REGS->ETM_CTRL = 0; + +#ifdef CONFIG_SOC_MEC1501_DEBUG_WITHOUT_TRACING + /* Release JTAG TDI and JTAG TDO pins so they can be + * controlled by their respective PCR register (UART2). + * For more details see table 44-1 + */ + ECS_REGS->DEBUG_CTRL = (MCHP_ECS_DCTRL_DBG_EN | + MCHP_ECS_DCTRL_MODE_SWD); +#elif defined(CONFIG_SOC_MEC1501_DEBUG_AND_TRACING) + #if defined(CONFIG_SOC_MEC1501_DEBUG_AND_ETM_TRACING) + ECS_REGS->ETM_CTRL = MCHP_ECS_ETM_CTRL_EN; + ECS_REGS->DEBUG_CTRL = (MCHP_ECS_DCTRL_DBG_EN | + MCHP_ECS_DCTRL_MODE_SWD); + #elif defined(CONFIG_SOC_MEC1501_DEBUG_AND_SWV_TRACING) + ECS_REGS->DEBUG_CTRL = (MCHP_ECS_DCTRL_DBG_EN | + MCHP_ECS_DCTRL_MODE_SWD_SWV); + #endif /* CONFIG_SOC_MEC1501_DEBUG_AND_TRACING */ + +#endif /* CONFIG_SOC_MEC1501_DEBUG_WITHOUT_TRACING */ +} + +static int board_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); struct pinmux_ports_t pinmux_ports; #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_000_036), okay) - struct device *porta = + const struct device *porta = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_000_036))); pinmux_ports.porta = porta; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_040_076), okay) - struct device *portb = + const struct device *portb = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_040_076))); pinmux_ports.portb = portb; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_100_136), okay) - struct device *portc = + const struct device *portc = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_100_136))); pinmux_ports.portc = portc; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_140_176), okay) - struct device *portd = + const struct device *portd = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_140_176))); pinmux_ports.portd = portd; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_200_236), okay) - struct device *porte = + const struct device *porte = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_200_236))); pinmux_ports.porte = porte; #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(pinmux_240_276), okay) - struct device *portf = + const struct device *portf = device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_240_276))); pinmux_ports.portf = portf; #endif @@ -141,21 +167,19 @@ static int board_pinmux_init(struct device *dev) #ifdef CONFIG_SOC_MEC1501_VTR3_1_8V ECS_REGS->GPIO_BANK_PWR |= MCHP_ECS_VTR3_LVL_18; #endif - /* Release JTAG TDI and JTAG TDO pins so they can be - * controlled by their respective PCR register (UART2). - * For more details see table 44-1 - */ - ECS_REGS->DEBUG_CTRL = (MCHP_ECS_DCTRL_DBG_EN | - MCHP_ECS_DCTRL_MODE_SWD); + + configure_debug_interface(); /* Configure pins that are not GPIOS by default */ +#ifdef CONFIG_SOC_MEC1501_VCI_PINS_AS_GPIOS pinmux_pin_set(porta, MCHP_GPIO_000, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portd, MCHP_GPIO_161, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portd, MCHP_GPIO_162, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portd, MCHP_GPIO_163, MCHP_GPIO_CTRL_MUX_F0); - pinmux_pin_set(portd, MCHP_GPIO_170, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portd, MCHP_GPIO_172, MCHP_GPIO_CTRL_MUX_F0); pinmux_pin_set(portf, MCHP_GPIO_250, MCHP_GPIO_CTRL_MUX_F0); +#endif + pinmux_pin_set(portd, MCHP_GPIO_170, MCHP_GPIO_CTRL_MUX_F0); /* See table 2-4 from the data sheet for pin multiplexing*/ #if DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) @@ -176,10 +200,12 @@ static int board_pinmux_init(struct device *dev) /* ADC pin muxes, ADC00 - ADC07 */ /* Note, by default ETM is enabled ADC00-ADC03 are not available */ +#ifndef CONFIG_SOC_MEC1501_DEBUG_AND_ETM_TRACING pinmux_pin_set(porte, MCHP_GPIO_200, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_201, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_202, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_203, MCHP_GPIO_CTRL_MUX_F1); +#endif pinmux_pin_set(porte, MCHP_GPIO_204, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_205, MCHP_GPIO_CTRL_MUX_F1); pinmux_pin_set(porte, MCHP_GPIO_206, MCHP_GPIO_CTRL_MUX_F1); @@ -249,47 +275,47 @@ static int board_pinmux_init(struct device *dev) #endif #ifdef CONFIG_PWM_XEC -#if DT_NODE_HAS_STATUS(DT_INST(0, microchip_xec_pwm), okay) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm0), okay) mchp_pcr_periph_slp_ctrl(PCR_PWM0, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(portb, MCHP_GPIO_053, MCHP_GPIO_CTRL_MUX_F1); #endif -#if DT_NODE_HAS_STATUS(DT_INST(1, microchip_xec_pwm), okay) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) mchp_pcr_periph_slp_ctrl(PCR_PWM1, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(portb, MCHP_GPIO_054, MCHP_GPIO_CTRL_MUX_F1); #endif -#if DT_NODE_HAS_STATUS(DT_INST(2, microchip_xec_pwm), okay) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) mchp_pcr_periph_slp_ctrl(PCR_PWM2, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(portb, MCHP_GPIO_055, MCHP_GPIO_CTRL_MUX_F1); #endif -#if DT_NODE_HAS_STATUS(DT_INST(3, microchip_xec_pwm), okay) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm3), okay) mchp_pcr_periph_slp_ctrl(PCR_PWM3, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(portb, MCHP_GPIO_056, MCHP_GPIO_CTRL_MUX_F1); #endif -#if DT_NODE_HAS_STATUS(DT_INST(4, microchip_xec_pwm), okay) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm4), okay) mchp_pcr_periph_slp_ctrl(PCR_PWM4, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(porta, MCHP_GPIO_011, MCHP_GPIO_CTRL_MUX_F2); #endif -#if DT_NODE_HAS_STATUS(DT_INST(5, microchip_xec_pwm), okay) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm5), okay) mchp_pcr_periph_slp_ctrl(PCR_PWM5, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(porta, MCHP_GPIO_002, MCHP_GPIO_CTRL_MUX_F1); #endif -#if DT_NODE_HAS_STATUS(DT_INST(6, microchip_xec_pwm), okay) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm6), okay) mchp_pcr_periph_slp_ctrl(PCR_PWM6, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(porta, MCHP_GPIO_014, MCHP_GPIO_CTRL_MUX_F1); #endif -#if DT_NODE_HAS_STATUS(DT_INST(7, microchip_xec_pwm), okay) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm7), okay) mchp_pcr_periph_slp_ctrl(PCR_PWM7, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(porta, MCHP_GPIO_015, MCHP_GPIO_CTRL_MUX_F1); #endif -#if DT_NODE_HAS_STATUS(DT_INST(8, microchip_xec_pwm), okay) +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm8), okay) mchp_pcr_periph_slp_ctrl(PCR_PWM8, MCHP_PCR_SLEEP_DIS); pinmux_pin_set(porta, MCHP_GPIO_035, MCHP_GPIO_CTRL_MUX_F1); #endif @@ -412,7 +438,7 @@ static int board_pinmux_init(struct device *dev) #endif /* DT_NODE_HAS_STATUS(DT_INST(0, microchip_xec_qmspi), okay) */ #endif /* CONFIG_SPI_XEC_QMSPI */ -#ifdef CONFIG_SYS_PM_DEBUG +#ifdef CONFIG_PM_DEBUG /* * Deep sleep testing: Enable TEST_CLK_OUT on GPIO_060 function 2. * TEST_CLK_OUT is the PLL 48MHz conditioned output. diff --git a/boards/arm/mec15xxevb_assy6853/support/spi_cfg.txt b/boards/arm/mec15xxevb_assy6853/support/spi_cfg.txt index a33907b078188b..9b97595fde3855 100644 --- a/boards/arm/mec15xxevb_assy6853/support/spi_cfg.txt +++ b/boards/arm/mec15xxevb_assy6853/support/spi_cfg.txt @@ -34,6 +34,5 @@ FwEntryAddress = 0 UseECDSA = false ECDSAPrivKeyFile = ecprivkey001.pem ECDSAPrivKeyPassword = ECPRIVKEY001 -ECDSAPubKeyFile = ecpubkey001_crt.pem FwEncrypt = false AesGenECPubKeyFile = ecpubkey002_crt.pem diff --git a/boards/arm/mec2016evb_assy6797/pinmux.c b/boards/arm/mec2016evb_assy6797/pinmux.c index 6f3e93bc2489e4..93a4057719e8ad 100644 --- a/boards/arm/mec2016evb_assy6797/pinmux.c +++ b/boards/arm/mec2016evb_assy6797/pinmux.c @@ -10,7 +10,7 @@ #include "soc.h" -static int board_pinmux_init(struct device *dev) +static int board_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/mikroe_clicker_2/Kconfig.board b/boards/arm/mikroe_clicker_2/Kconfig.board new file mode 100644 index 00000000000000..81e95e3fd3b45c --- /dev/null +++ b/boards/arm/mikroe_clicker_2/Kconfig.board @@ -0,0 +1,8 @@ +# MikroE Clicker 2 board configuration + +# Copyright (c) 2020 Trifork +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MIKROE_CLICKER_2 + bool "MikroE Clicker 2 for STM32 board" + depends on SOC_STM32F407XG diff --git a/boards/arm/mikroe_clicker_2/Kconfig.defconfig b/boards/arm/mikroe_clicker_2/Kconfig.defconfig new file mode 100644 index 00000000000000..08a87aeca7607b --- /dev/null +++ b/boards/arm/mikroe_clicker_2/Kconfig.defconfig @@ -0,0 +1,15 @@ +# MikroE Clicker 2 board configuration + +# Copyright (c) 2020 Trifork +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_MIKROE_CLICKER_2 + +config BOARD + default "mikroe_clicker_2" + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +endif #BOARD_MIKROE_CLICKER_2 diff --git a/boards/arm/mikroe_clicker_2/board.cmake b/boards/arm/mikroe_clicker_2/board.cmake new file mode 100644 index 00000000000000..e86f26ab719427 --- /dev/null +++ b/boards/arm/mikroe_clicker_2/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32F407VG" "--speed=4000") +board_runner_args(openocd --cmd-pre-init "source [find interface/jlink.cfg]") +board_runner_args(openocd --cmd-pre-init "source [find target/stm32f4x.cfg]") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + diff --git a/boards/arm/mikroe_clicker_2/doc/img/clicker-2-stm32f4-thickbox_default-2.jpg b/boards/arm/mikroe_clicker_2/doc/img/clicker-2-stm32f4-thickbox_default-2.jpg new file mode 100644 index 00000000000000..b65ad4517ff545 Binary files /dev/null and b/boards/arm/mikroe_clicker_2/doc/img/clicker-2-stm32f4-thickbox_default-2.jpg differ diff --git a/boards/arm/mikroe_clicker_2/doc/mikroe_clicker_2.rst b/boards/arm/mikroe_clicker_2/doc/mikroe_clicker_2.rst new file mode 100644 index 00000000000000..7874f661f6bb9a --- /dev/null +++ b/boards/arm/mikroe_clicker_2/doc/mikroe_clicker_2.rst @@ -0,0 +1,130 @@ +.. _mikroe_clicker_2: + +MikroE Clicker 2 for STM32 +########################## + +Overview +******** +MikroE Clicker 2 for STM32 is a development board containing an `STM32F407`_ +microcontroller. It is equipped with two mikrobus sockets and furthermore has +two headers for general signal break out. +The board also has battery connection and a battery management unit on board. +It can be powered either from a battery pack, such as a LiPo or from USB. +The board is equipped with a 25MHz crystal as well as a 32.768kHz clock crystal. + + +.. figure:: img/clicker-2-stm32f4-thickbox_default-2.jpg + :align: center + :alt: Clicker 2 For STM32 + + Clicker 2 For STM32 (Credit: MikroElektronika d.o.o.) + +Hardware +******** +The Clicker 2 board contains the following connections: + + - Two MikroBUS connectors + - Two headers with general connections + +Furthermore the board contains two LEDs and two push buttons that are connected +to the microcontroller. + +Supported Features +================== +The Zephyr MikroE Clicker 2 configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| USB | on-chip | usb | ++-----------+------------+-------------------------------------+ + +Other hardware features are not supported by the Zephyr kernel. + +The default configuration can be found in the defconfig file: + + ``boards/arm/mikroe_clicker_2/mikroe_cliker_2_defconfig`` + +Connections and IOs +=================== + +The two mikroBUS interfaces are aliased in the device tree so that their +peripherals can be accessed using ``mikrobus_N_INTERFACE`` so e.g. the spi on +bus 2 can be found by the alias ``mikrobus_2_spi``. The counting corresponds +with the marking on the board. + +For connections on the edge connectors, please refer to `Clicker 2 for STM32 User Manual`_. + +Programming and Debugging +************************* +Applications for the ``mikroe_clicker_2`` board configuration can +be built and flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + + +Flashing +======== +The initial state of the board is set to lock. +When you flash, it will fail with the message: + +.. code-block:: console + + Error: stm32x device protected + +Unlocking with openocd makes it possible to flash. + +.. code-block:: console + + $ openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg \ + -f /usr/share/openocd/scripts/target/stm32f4x.cfg -c init\ + -c "reset halt" -c "stm32f4x unlock 0" -c "reset run" -c shutdown + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mikroe_clicker_2 + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + Hello World! mikroe_clicker_2 + + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mikroe_clicker_2 + :maybe-skip-config: + :goals: debug + +References +********** +.. _Clicker 2 website: + https://www.mikroe.com/clicker-2-stm32f4 +.. _Clicker 2 for STM32 User Manual: + https://download.mikroe.com/documents/starter-boards/clicker-2/stm32f4/clicker2-stm32-manual-v100.pdf +.. _STM32F407VG Website: + https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32f4-series/stm32f407-417/stm32f407vg.html +.. _STM32F407: + https://www.st.com/resource/en/datasheet/stm32f407vg.pdf diff --git a/boards/arm/mikroe_clicker_2/mikroe_clicker_2.dts b/boards/arm/mikroe_clicker_2/mikroe_clicker_2.dts new file mode 100644 index 00000000000000..654807f0355fa5 --- /dev/null +++ b/boards/arm/mikroe_clicker_2/mikroe_clicker_2.dts @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020 Trifork + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "MikroE clicker 2 for STM32"; + compatible = "mikroe,stm32-e407", "st,stm32f407"; + + chosen { + zephyr,console = &uart4; + zephyr,shell-uart = &uart4; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,ccm = &ccm0; + }; + + + leds { + compatible = "gpio-leds"; + ld1: led_1 { + gpios = <&gpioe 12 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + ld2: led_2 { + gpios = <&gpioe 15 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_0: key_0 { + label = "Key PE0"; + gpios = <&gpioe 0 GPIO_ACTIVE_LOW>; + }; + user_button_1: key_1 { + label = "Key K1"; + gpios = <&gpioe 10 GPIO_ACTIVE_LOW>; + }; + }; + + aliases { + led0 = &ld1; + led1 = &ld2; + sw0 = &user_button_0; + sw1 = &user_button_1; + }; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>; + current-speed = <9600>; + status = "okay"; +}; + +&usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; + current-speed = <9600>; + status = "okay"; +}; + +&uart4 { + pinctrl-0 = <&uart4_tx_pa0 &uart4_rx_pa1>; + current-speed = <115200>; + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; + status = "okay"; +}; + + +&spi2 { + pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>; + cs-gpios = <&gpioe 11 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&spi3 { + pinctrl-0 = <&spi3_sck_pc10 &spi3_miso_pc11 &spi3_mosi_pc12>; + cs-gpios = <&gpioe 8 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; + status = "okay"; +}; + +&i2c3 { + pinctrl-0 = <&i2c3_scl_pa8 &i2c3_sda_pc9>; + status = "okay"; +}; + +&adc1 { + status ="okay"; + pinctrl-0 = <&adc1_in2_pa2 &adc1_in3_pa3>; +}; + + +mikrobus_1_i2c: &i2c3 {}; + +mikrobus_1_spi: &spi3 {}; + +mikrobus_1_uart: &usart2 {}; + +mikrobus_2_i2c: &i2c2 {}; + +mikrobus_2_spi: &spi2 {}; + +mikrobus_2_uart: &usart3 {}; diff --git a/boards/arm/mikroe_clicker_2/mikroe_clicker_2.yaml b/boards/arm/mikroe_clicker_2/mikroe_clicker_2.yaml new file mode 100644 index 00000000000000..695407a13eadd2 --- /dev/null +++ b/boards/arm/mikroe_clicker_2/mikroe_clicker_2.yaml @@ -0,0 +1,14 @@ +identifier: mikroe_clicker_2 +name: MikroE Clicker 2 for STM32 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 192 +flash: 1024 +supported: + - spi + - i2c + - adc diff --git a/boards/arm/mikroe_clicker_2/mikroe_clicker_2_defconfig b/boards/arm/mikroe_clicker_2/mikroe_clicker_2_defconfig new file mode 100644 index 00000000000000..e1929314179d1f --- /dev/null +++ b/boards/arm/mikroe_clicker_2/mikroe_clicker_2_defconfig @@ -0,0 +1,36 @@ +CONFIG_BOARD_MIKROE_CLICKER_2=y +CONFIG_SOC_SERIES_STM32F4X=y +CONFIG_SOC_STM32F407XG=y +# 168MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 + +# Enable MPU +CONFIG_ARM_MPU=y + +CONFIG_SERIAL=y + +# console +CONFIG_CONSOLE=y + +# enable pinmux +CONFIG_PINMUX=y + +# enable GPIO +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y + +# Clock configuration for Cube Clock control driver +CONFIG_CLOCK_STM32_HSE_CLOCK=25000000 +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# use HSE as PLL input +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# produce 168MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=25 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=336 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=7 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=4 +CONFIG_CLOCK_STM32_APB2_PRESCALER=2 diff --git a/boards/arm/mikroe_mini_m4_for_stm32/CMakeLists.txt b/boards/arm/mikroe_mini_m4_for_stm32/CMakeLists.txt deleted file mode 100644 index dc81fa6296024a..00000000000000 --- a/boards/arm/mikroe_mini_m4_for_stm32/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2019, Kwon Tae-young -# -# SPDX-License-Identifier: Apache-2.0 -# -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32.dts b/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32.dts index 84085fb6c3b9b3..cfd9d2be6a3b2f 100644 --- a/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32.dts +++ b/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "Mikroe MINI-M4 for STM32 board"; - compatible = "mikroe,mini-m4-for-stm32", "st,stm32f415rg"; + compatible = "mikroe,mini-m4-for-stm32"; chosen { zephyr,console = &usart2; @@ -38,15 +39,19 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; status = "okay"; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; @@ -55,10 +60,12 @@ pwm3: pwm { status = "okay"; + pinctrl-0 = <&tim3_ch1_pb4>; }; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; diff --git a/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32_defconfig b/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32_defconfig index 6bc8c944bdc2cd..fd6685d86abde0 100644 --- a/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32_defconfig +++ b/boards/arm/mikroe_mini_m4_for_stm32/mikroe_mini_m4_for_stm32_defconfig @@ -7,6 +7,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/mikroe_mini_m4_for_stm32/pinmux.c b/boards/arm/mikroe_mini_m4_for_stm32/pinmux.c deleted file mode 100644 index ddb144e787bf35..00000000000000 --- a/boards/arm/mikroe_mini_m4_for_stm32/pinmux.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2019, Kwon Tae-young - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for MINI-M4 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB11, STM32F4_PINMUX_FUNC_PB11_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm3), okay) && CONFIG_PWM - {STM32_PIN_PB4, STM32F4_PINMUX_FUNC_PB4_PWM3_CH1}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/mimx8mm_evk/CMakeLists.txt b/boards/arm/mimx8mm_evk/CMakeLists.txt new file mode 100644 index 00000000000000..20adfdbf5298a4 --- /dev/null +++ b/boards/arm/mimx8mm_evk/CMakeLists.txt @@ -0,0 +1,9 @@ +# +# Copyright (c) 2020, Manivannan Sadhasivam +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_library() +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) +zephyr_library_sources(pinmux.c) diff --git a/boards/arm/mimx8mm_evk/Kconfig.board b/boards/arm/mimx8mm_evk/Kconfig.board new file mode 100644 index 00000000000000..0e7c9865cf1b2c --- /dev/null +++ b/boards/arm/mimx8mm_evk/Kconfig.board @@ -0,0 +1,9 @@ +# MIMX8MM EVK board + +# Copyright (c) 2020, Manivannan Sadhasivam +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MIMX8MM_EVK + bool "NXP i.MX8M Mini EVK" + depends on SOC_SERIES_IMX8MM_M4 + select SOC_PART_NUMBER_MIMX8MM6DVTLZ diff --git a/boards/arm/mimx8mm_evk/Kconfig.defconfig b/boards/arm/mimx8mm_evk/Kconfig.defconfig new file mode 100644 index 00000000000000..aee76b9834b99f --- /dev/null +++ b/boards/arm/mimx8mm_evk/Kconfig.defconfig @@ -0,0 +1,18 @@ +# MIMX8MM EVK board defconfig + +# Copyright (c) 2020, Manivannan Sadhasivam +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_MIMX8MM_EVK + +config BOARD + default "mimx8mm_evk" + +if !XIP +config FLASH_SIZE + default 0 +config FLASH_BASE_ADDRESS + default 0 +endif + +endif # BOARD_MIMX8MM_EVK diff --git a/boards/arm/mimx8mm_evk/board.cmake b/boards/arm/mimx8mm_evk/board.cmake new file mode 100644 index 00000000000000..3b202648575d9d --- /dev/null +++ b/boards/arm/mimx8mm_evk/board.cmake @@ -0,0 +1,11 @@ +# +# Copyright (c) 2020, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_set_debugger_ifnset(jlink) +board_set_flasher_ifnset(jlink) + +board_runner_args(jlink "--device=MIMX8MD6_M4") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/mimx8mm_evk/doc/img/mimx8mm_evk.jpg b/boards/arm/mimx8mm_evk/doc/img/mimx8mm_evk.jpg new file mode 100644 index 00000000000000..1cae9e42e777dd Binary files /dev/null and b/boards/arm/mimx8mm_evk/doc/img/mimx8mm_evk.jpg differ diff --git a/boards/arm/mimx8mm_evk/doc/index.rst b/boards/arm/mimx8mm_evk/doc/index.rst new file mode 100644 index 00000000000000..81d16b73329248 --- /dev/null +++ b/boards/arm/mimx8mm_evk/doc/index.rst @@ -0,0 +1,184 @@ +.. _mimx8mm_evk: + +NXP MIMX8MM EVK +############### + +Overview +******** + +i.MX8M Mini LPDDR4 EVK board is based on NXP i.MX8M Mini applications +processor, composed of a quad Cortex®-A53 cluster and a single Cortex®-M4 core. +Zephyr OS is ported to run on the Cortex®-M4 core. + +- Board features: + + - RAM: 2GB LPDDR4 + - Storage: + + - SanDisk 16GB eMMC5.1 + - Micron 32MB QSPI NOR + - microSD Socket + - Wireless: + + - WiFi: 2.4/5GHz IEEE 802.11b/g/n + - Bluetooth: v4.1 + - USB: + + - OTG - 2x type C + - Ethernet + - PCI-E M.2 + - Connectors: + + - 40-Pin Dual Row Header + - LEDs: + + - 1x Power status LED + - 1x UART LED + - Debug + + - JTAG 20-pin connector + - MicroUSB for UART debug, two COM ports for A53 and M4 + +.. image:: img/mimx8mm_evk.jpg + :width: 720px + :align: center + :height: 405px + :alt: MIMX8MM EVK + +More information about the board can be found at the +`NXP website`_. + +Supported Features +================== + +The Zephyr mimx8mm_evk board configuration supports the following hardware +features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: +:zephyr_file:`boards/arm/mimx8mm_evk/mimx8mm_evk_defconfig`. + +Other hardware features are not currently supported by the port. + +Connections and IOs +=================== + +MIMX8MM EVK board was tested with the following pinmux controller +configuration. + ++---------------+-----------------+---------------------------+ +| Board Name | SoC Name | Usage | ++===============+=================+===========================+ +| UART4 RXD | UART4_TXD | UART Console | ++---------------+-----------------+---------------------------+ +| UART4 TXD | UART4_RXD | UART Console | ++---------------+-----------------+---------------------------+ + +System Clock +============ + +The M4 Core is configured to run at a 400 MHz clock speed. + +Serial Port +=========== + +The i.MX8M Mini SoC has four UARTs. UART_4 is configured for the console and +the remaining are not used/tested. + +Programming and Debugging +************************* + +The MIMX8MM EVK board doesn't have QSPI flash for the M4 and it needs +to be started by the A53 core. The A53 core is responsible to load the M4 binary +application into the RAM, put the M4 in reset, set the M4 Program Counter and +Stack Pointer, and get the M4 out of reset. The A53 can perform these steps at +bootloader level or after the Linux system has booted. + +The M4 can use up to 3 different RAMs. These are the memory mapping for A53 and M4: + ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| Region | Cortex-A53 | Cortex-M4 (System Bus) | Cortex-M4 (Code Bus) | Size | ++============+=========================+========================+=======================+======================+ +| OCRAM | 0x00900000-0x0093FFFF | 0x20200000-0x2023FFFF | 0x00900000-0x0093FFFF | 256KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| TCMU | 0x00800000-0x0081FFFF | 0x20000000-0x2001FFFF | | 128KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| TCML | 0x007E0000-0x007FFFFF | | 0x1FFE0000-0x1FFFFFFF | 128KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| OCRAM_S | 0x00180000-0x00187FFF | 0x20180000-0x20187FFF | 0x00180000-0x00187FFF | 32KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ + +For more information about memory mapping see the +`i.MX 8M Applications Processor Reference Manual`_ (section 2.1.2 and 2.1.3) + +At compilation time you have to choose which RAM will be used. This +configuration is done in the file ``boards/arm/mimx8mm_evk/mimx8mm_evk.dts`` +with "zephyr,flash" (when CONFIG_XIP=y) and "zephyr,sram" properties. +The available configurations are: + +.. code-block:: none + + "zephyr,flash" + - &tcml_code + - &ocram_code + - &ocram_s_code + + "zephyr,sram" + - &tcmu_sys + - &ocram_sys + - &ocram_s_sys + +Load and run Zephyr on M4 from A53 using u-boot by copying the compiled +``zephyr.bin`` to the first FAT partition of the SD card and plug the SD +card into the board. Power it up and stop the u-boot execution at prompt. + +Load the M4 binary onto the desired memory and start its execution using: + +.. code-block:: console + + fatload mmc 0:1 0x7e0000 zephyr.bin;bootaux 0x7e0000 + +Debugging +========= + +MIMX8MM EVK board can be debugged by connecting an external JLink +JTAG debugger to the J902 debug connector and to the PC. Then +the application can be debugged using the usual way. + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimx8mm_evk + :goals: debug + +Open a serial terminal, step through the application in your debugger, and you +should see the following message in the terminal: + +.. code-block:: console + + ***** Booting Zephyr OS build zephyr-v2.0.0-1859-g292afe8533c0 ***** + Hello World! mimx8mm_evk + +References +========== + +.. _NXP website: + https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/evaluation-kit-for-thebr-i.mx-8m-mini-applications-processor:8MMINILPD4-EVK + +.. _i.MX 8M Applications Processor Reference Manual: + https://www.nxp.com/webapp/Download?colCode=IMX8MMRM diff --git a/boards/arm/mimx8mm_evk/mimx8mm_evk.dts b/boards/arm/mimx8mm_evk/mimx8mm_evk.dts new file mode 100644 index 00000000000000..d1a256604b07c8 --- /dev/null +++ b/boards/arm/mimx8mm_evk/mimx8mm_evk.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, Manivannan Sadhasivam + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "NXP i.MX8M Mini EVK board"; + compatible = "nxp,mimx8mm_evk"; + + aliases { + uart-4 = &uart4; + }; + + chosen { + zephyr,flash = &tcml_code; + zephyr,sram = &tcmu_sys; + zephyr,console = &uart4; + zephyr,shell-uart = &uart4; + }; +}; + +&uart4 { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/arm/mimx8mm_evk/mimx8mm_evk.yaml b/boards/arm/mimx8mm_evk/mimx8mm_evk.yaml new file mode 100644 index 00000000000000..1bec3704872af9 --- /dev/null +++ b/boards/arm/mimx8mm_evk/mimx8mm_evk.yaml @@ -0,0 +1,20 @@ +# +# Copyright (c) 2020, Manivannan Sadhasivam +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: mimx8mm_evk +name: NXP i.MX8M Mini EVK +type: mcu +arch: arm +ram: 32 +flash: 32 +toolchain: + - zephyr + - gnuarmemb + - xtools +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/arm/mimx8mm_evk/mimx8mm_evk_defconfig b/boards/arm/mimx8mm_evk/mimx8mm_evk_defconfig new file mode 100644 index 00000000000000..0bb9b7678f50c8 --- /dev/null +++ b/boards/arm/mimx8mm_evk/mimx8mm_evk_defconfig @@ -0,0 +1,16 @@ +# +# Copyright (c) 2020, Manivannan Sadhasivam +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_IMX8MM_M4=y +CONFIG_SOC_MIMX8MM6=y +CONFIG_BOARD_MIMX8MM_EVK=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_CLOCK_CONTROL=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y +CONFIG_XIP=y diff --git a/boards/arm/mimx8mm_evk/pinmux.c b/boards/arm/mimx8mm_evk/pinmux.c new file mode 100644 index 00000000000000..f2a72b18121273 --- /dev/null +++ b/boards/arm/mimx8mm_evk/pinmux.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020, Manivannan Sadhasivam + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +static int mimx8mm_evk_pinmux_init(const struct device *dev) +{ + ARG_UNUSED(dev); + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart4), okay) + IOMUXC_SetPinMux(IOMUXC_UART4_RXD_UART4_RX, 0U); + IOMUXC_SetPinConfig(IOMUXC_UART4_RXD_UART4_RX, + IOMUXC_SW_PAD_CTL_PAD_DSE(6U) | + IOMUXC_SW_PAD_CTL_PAD_FSEL(2U)); + IOMUXC_SetPinMux(IOMUXC_UART4_TXD_UART4_TX, 0U); + IOMUXC_SetPinConfig(IOMUXC_UART4_TXD_UART4_TX, + IOMUXC_SW_PAD_CTL_PAD_DSE(6U) | + IOMUXC_SW_PAD_CTL_PAD_FSEL(2U)); +#endif + + return 0; + +} + +SYS_INIT(mimx8mm_evk_pinmux_init, PRE_KERNEL_1, 0); diff --git a/boards/arm/mimxrt1010_evk/board.cmake b/boards/arm/mimxrt1010_evk/board.cmake index 68e0f2621f2de1..d482b24e322a48 100644 --- a/boards/arm/mimxrt1010_evk/board.cmake +++ b/boards/arm/mimxrt1010_evk/board.cmake @@ -3,12 +3,8 @@ # # SPDX-License-Identifier: Apache-2.0 # -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -endif() +board_runner_args(pyocd "--target=mimxrt1010") board_runner_args(jlink "--device=MIMXRT1011") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/mimxrt1010_evk/mimxrt1010_evk.dts b/boards/arm/mimxrt1010_evk/mimxrt1010_evk.dts index 1f560ec26f522f..fbca23eac72696 100644 --- a/boards/arm/mimxrt1010_evk/mimxrt1010_evk.dts +++ b/boards/arm/mimxrt1010_evk/mimxrt1010_evk.dts @@ -18,6 +18,7 @@ }; chosen { + zephyr,sram = &dtcm; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; }; @@ -42,7 +43,7 @@ arduino_serial: &lpuart1 {}; &flexspi { - reg = <0x402a8000 0x4000>, <0x60000000 0x1000000>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(16)>; at25sf128a: at25sf128a@0 { compatible = "adesto,at25sf128a", "jedec,spi-nor"; size = <134217728>; diff --git a/boards/arm/mimxrt1010_evk/mimxrt1010_evk_defconfig b/boards/arm/mimxrt1010_evk/mimxrt1010_evk_defconfig index 9b1e5bf541b448..b84a33561629ec 100644 --- a/boards/arm/mimxrt1010_evk/mimxrt1010_evk_defconfig +++ b/boards/arm/mimxrt1010_evk/mimxrt1010_evk_defconfig @@ -13,3 +13,4 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=500000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mimxrt1010_evk/pinmux.c b/boards/arm/mimxrt1010_evk/pinmux.c index 2d941cb9be341e..dc5c52c8f640fe 100644 --- a/boards/arm/mimxrt1010_evk/pinmux.c +++ b/boards/arm/mimxrt1010_evk/pinmux.c @@ -8,7 +8,7 @@ #include #include -static int mimxrt1010_evk_init(struct device *dev) +static int mimxrt1010_evk_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/mimxrt1015_evk/board.cmake b/boards/arm/mimxrt1015_evk/board.cmake index e04bc6d965f357..be9b7ba10e12d8 100644 --- a/boards/arm/mimxrt1015_evk/board.cmake +++ b/boards/arm/mimxrt1015_evk/board.cmake @@ -3,12 +3,8 @@ # # SPDX-License-Identifier: Apache-2.0 # -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -endif() +board_runner_args(pyocd "--target=mimxrt1015") board_runner_args(jlink "--device=MIMXRT1015") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts index 2540b008caa17f..8716b2bde7551e 100644 --- a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts +++ b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts @@ -18,6 +18,7 @@ }; chosen { + zephyr,sram = &dtcm; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; }; @@ -71,7 +72,7 @@ arduino_serial: &lpuart4 {}; &flexspi { - reg = <0x402a8000 0x4000>, <0x60000000 0x1000000>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(16)>; at25sf128a: at25sf128a@0 { compatible = "adesto,at25sf128a", "jedec,spi-nor"; size = <134217728>; diff --git a/boards/arm/mimxrt1015_evk/mimxrt1015_evk_defconfig b/boards/arm/mimxrt1015_evk/mimxrt1015_evk_defconfig index f33588fa94e458..634a9e0bf0d67f 100644 --- a/boards/arm/mimxrt1015_evk/mimxrt1015_evk_defconfig +++ b/boards/arm/mimxrt1015_evk/mimxrt1015_evk_defconfig @@ -13,3 +13,4 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=500000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mimxrt1015_evk/pinmux.c b/boards/arm/mimxrt1015_evk/pinmux.c index d96148e1ac90a7..5adad957f6f970 100644 --- a/boards/arm/mimxrt1015_evk/pinmux.c +++ b/boards/arm/mimxrt1015_evk/pinmux.c @@ -8,7 +8,7 @@ #include #include -static int mimxrt1015_evk_init(struct device *dev) +static int mimxrt1015_evk_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/mimxrt1020_evk/Kconfig.defconfig b/boards/arm/mimxrt1020_evk/Kconfig.defconfig index a9f3508ad14ec0..e4c58f0cd67559 100644 --- a/boards/arm/mimxrt1020_evk/Kconfig.defconfig +++ b/boards/arm/mimxrt1020_evk/Kconfig.defconfig @@ -12,18 +12,11 @@ choice CODE_LOCATION default CODE_FLEXSPI endchoice -choice DATA_LOCATION - default DATA_SEMC -endchoice - if NETWORKING config NET_L2_ETHERNET default y -config ETH_MCUX_0 - default y if NET_L2_ETHERNET - endif # NETWORKING endif # BOARD_MIMXRT1020_EVK diff --git a/boards/arm/mimxrt1020_evk/board.cmake b/boards/arm/mimxrt1020_evk/board.cmake index faacd6864b8119..f3c9ac623ed95f 100644 --- a/boards/arm/mimxrt1020_evk/board.cmake +++ b/boards/arm/mimxrt1020_evk/board.cmake @@ -4,18 +4,8 @@ # SPDX-License-Identifier: Apache-2.0 # -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - board_runner_args(pyocd "--target=mimxrt1020") board_runner_args(jlink "--device=MIMXRT1021xxx5A") -include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts index 6e63c0b698e28e..223ff49824ecb6 100644 --- a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts +++ b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts @@ -18,6 +18,8 @@ }; chosen { + zephyr,sram = &sdram0; + zephyr,dtcm = &dtcm; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; }; @@ -25,8 +27,7 @@ sdram0: memory@80000000 { /* ISSI IS42S16160J-6TLI */ device_type = "memory"; - compatible = "mmio-sram"; - reg = <0x80000000 0x2000000>; + reg = <0x80000000 DT_SIZE_M(32)>; }; leds { @@ -78,7 +79,7 @@ arduino_serial: &lpuart2 {}; &flexspi { - reg = <0x402a8000 0x4000>, <0x60000000 0x800000>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; is25wp064: is25wp064@0 { compatible = "issi,is25wp064", "jedec,spi-nor"; size = <67108864>; diff --git a/boards/arm/mimxrt1020_evk/mimxrt1020_evk_defconfig b/boards/arm/mimxrt1020_evk/mimxrt1020_evk_defconfig index 598bec0439828f..8bd73d28bc0a19 100644 --- a/boards/arm/mimxrt1020_evk/mimxrt1020_evk_defconfig +++ b/boards/arm/mimxrt1020_evk/mimxrt1020_evk_defconfig @@ -13,3 +13,4 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=500000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mimxrt1020_evk/pinmux.c b/boards/arm/mimxrt1020_evk/pinmux.c index 5a0781c2752b38..db4806d49e0a57 100644 --- a/boards/arm/mimxrt1020_evk/pinmux.c +++ b/boards/arm/mimxrt1020_evk/pinmux.c @@ -16,7 +16,7 @@ static gpio_pin_config_t enet_gpio_config = { }; #endif -static int mimxrt1020_evk_init(struct device *dev) +static int mimxrt1020_evk_init(const struct device *dev) { ARG_UNUSED(dev); @@ -148,7 +148,7 @@ static int mimxrt1020_evk_init(struct device *dev) } #if DT_NODE_HAS_STATUS(DT_NODELABEL(enet), okay) && CONFIG_NET_L2_ETHERNET -static int mimxrt1020_evk_phy_reset(struct device *dev) +static int mimxrt1020_evk_phy_reset(const struct device *dev) { /* RESET PHY chip. */ k_busy_wait(USEC_PER_MSEC * 10U); diff --git a/boards/arm/mimxrt1050_evk/CMakeLists.txt b/boards/arm/mimxrt1050_evk/CMakeLists.txt index a0d4d39d9434d3..f6e7a1463c9666 100644 --- a/boards/arm/mimxrt1050_evk/CMakeLists.txt +++ b/boards/arm/mimxrt1050_evk/CMakeLists.txt @@ -7,3 +7,9 @@ zephyr_library() zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_library_sources(pinmux.c) + +if (CONFIG_DISPLAY) +message(WARNING " +CONFIG_DISPLAY: Running this firmware on a board without a display may damage the board +") +endif() diff --git a/boards/arm/mimxrt1050_evk/Kconfig.defconfig b/boards/arm/mimxrt1050_evk/Kconfig.defconfig index 8f7eb17e01abdf..1608367d08e0e6 100644 --- a/boards/arm/mimxrt1050_evk/Kconfig.defconfig +++ b/boards/arm/mimxrt1050_evk/Kconfig.defconfig @@ -12,10 +12,6 @@ choice CODE_LOCATION default CODE_FLEXSPI endchoice -choice DATA_LOCATION - default DATA_SEMC -endchoice - config DISK_ACCESS_USDHC1 default y depends on DISK_ACCESS_USDHC @@ -48,9 +44,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_MCUX_0 - default y if NET_L2_ETHERNET - endif # NETWORKING if LVGL @@ -64,10 +57,10 @@ config LVGL_POINTER_KSCAN config LVGL_POINTER_KSCAN_DEV_NAME default "FT5336" -config LVGL_HOR_RES +config LVGL_HOR_RES_MAX default 480 -config LVGL_VER_RES +config LVGL_VER_RES_MAX default 272 config LVGL_VDB_SIZE diff --git a/boards/arm/mimxrt1050_evk/board.cmake b/boards/arm/mimxrt1050_evk/board.cmake index 5541cfe69010ca..4955f0753b649a 100644 --- a/boards/arm/mimxrt1050_evk/board.cmake +++ b/boards/arm/mimxrt1050_evk/board.cmake @@ -4,18 +4,8 @@ # SPDX-License-Identifier: Apache-2.0 # -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - board_runner_args(pyocd "--target=mimxrt1050_hyperflash") board_runner_args(jlink "--device=MCIMXRT1052") -include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/mimxrt1050_evk/doc/index.rst b/boards/arm/mimxrt1050_evk/doc/index.rst index 4403ff4ad8745d..83f68f1f2bea88 100644 --- a/boards/arm/mimxrt1050_evk/doc/index.rst +++ b/boards/arm/mimxrt1050_evk/doc/index.rst @@ -354,6 +354,37 @@ should see the following message in the terminal: ***** Booting Zephyr OS v1.14.0-rc1 ***** Hello World! mimxrt1050_evk +Troubleshooting +=============== + +If the debug probe fails to connect with the following error, it's possible +that the boot header in HyperFlash is invalid or corrupted. The boot header is +configured by :option:`CONFIG_NXP_IMX_RT_BOOT_HEADER`. + +.. code-block:: console + + Remote debugging using :2331 + Remote communication error. Target disconnected.: Connection reset by peer. + "monitor" command not supported by this target. + "monitor" command not supported by this target. + You can't do that when your target is `exec' + (gdb) Could not connect to target. + Please check power, connection and settings. + +You can fix it by erasing and reprogramming the HyperFlash with the following +steps: + +#. Set the SW7 DIP switches to ON-ON-ON-OFF to prevent booting from HyperFlash. + +#. Reset by pressing SW4 + +#. Run ``west debug`` or ``west flash`` again with a known working Zephyr + application. + +#. Set the SW7 DIP switches to OFF-ON-ON-OFF to boot from HyperFlash. + +#. Reset by pressing SW4 + Board Revisions *************** diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts index d614a904b459bb..0a33503d56fd1d 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts @@ -16,9 +16,12 @@ led0 = &green_led; sw0 = &user_button; kscan0 = &touch_controller; + watchdog0 = &wdog0; }; chosen { + zephyr,sram = &sdram0; + zephyr,dtcm = &dtcm; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; }; @@ -26,8 +29,7 @@ sdram0: memory@80000000 { /* Micron MT48LC16M16A2B4-6AIT:G */ device_type = "memory"; - compatible = "mmio-sram"; - reg = <0x80000000 0x2000000>; + reg = <0x80000000 DT_SIZE_M(32)>; }; leds { @@ -88,7 +90,7 @@ arduino_serial: &lpuart3 {}; &flexspi { - reg = <0x402a8000 0x4000>, <0x60000000 0x4000000>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(64)>; hyperflash0: hyperflash@0 { compatible = "cypress,s26ks512s"; reg = <0>; @@ -155,3 +157,7 @@ arduino_serial: &lpuart3 {}; pwr-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; }; + +&wdog0 { + status = "okay"; +}; diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.yaml b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.yaml index df5514d89bc77c..8210e3316dc6a1 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.yaml +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.yaml @@ -25,3 +25,4 @@ supported: - spi - usb_device - kscan:touch + - watchdog diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_defconfig b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_defconfig index 6894ed1e333d1d..d7fd4dd692ee30 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_defconfig +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_defconfig @@ -14,3 +14,4 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=600000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.dts b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.dts index c846aa606f254c..5b84cfc601c112 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.dts +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.dts @@ -9,7 +9,7 @@ /delete-node/ &hyperflash0; &flexspi { - reg = <0x402a8000 0x4000>, <0x60000000 0x800000>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; is25wp064: is25wp064@0 { compatible = "issi,is25wp064", "jedec,spi-nor"; size = <67108864>; diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.yaml b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.yaml index 60fe3df9b31702..9104eb727c96c6 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.yaml +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.yaml @@ -24,3 +24,4 @@ supported: - sdhc - spi - usb_device + - watchdog diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi_defconfig b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi_defconfig index 1a038e6c83c8af..aed6db26496c9c 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi_defconfig +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi_defconfig @@ -14,3 +14,4 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=600000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mimxrt1050_evk/pinmux.c b/boards/arm/mimxrt1050_evk/pinmux.c index 8afad26686a7bd..f0cdd4b7420df0 100644 --- a/boards/arm/mimxrt1050_evk/pinmux.c +++ b/boards/arm/mimxrt1050_evk/pinmux.c @@ -29,17 +29,17 @@ static gpio_pin_config_t enet_gpio_config = { */ static void mimxrt1050_evk_usdhc_pinmux( - u16_t nusdhc, bool init, - u32_t speed, u32_t strength) + uint16_t nusdhc, bool init, + uint32_t speed, uint32_t strength) { - u32_t cmd_data = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + uint32_t cmd_data = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) | IOMUXC_SW_PAD_CTL_PAD_DSE(strength); - u32_t clk = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + uint32_t clk = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) | @@ -102,7 +102,7 @@ static void mimxrt1050_evk_usdhc_pinmux( } #endif -static int mimxrt1050_evk_init(struct device *dev) +static int mimxrt1050_evk_init(const struct device *dev) { ARG_UNUSED(dev); @@ -118,8 +118,8 @@ static int mimxrt1050_evk_init(struct device *dev) IOMUXC_SW_PAD_CTL_PAD_DSE(6)); #endif -#if !DT_NODE_HAS_STATUS(DT_NODELABEL(enet), okay) - /* LED */ +#if !CONFIG_NET_L2_ETHERNET + /* Shared GPIO between USER_LED and ENET_RST */ IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, @@ -225,7 +225,9 @@ static int mimxrt1050_evk_init(struct device *dev) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0); + /* Shared GPIO between USER_LED and ENET_RST */ IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0xB0A9u); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, 0xB0A9u); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0xB0E9); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0xB0E9); @@ -317,7 +319,7 @@ static int mimxrt1050_evk_init(struct device *dev) } #if DT_NODE_HAS_STATUS(DT_NODELABEL(enet), okay) && CONFIG_NET_L2_ETHERNET -static int mimxrt1050_evk_phy_reset(struct device *dev) +static int mimxrt1050_evk_phy_reset(const struct device *dev) { /* RESET PHY chip. */ k_busy_wait(USEC_PER_MSEC * 10U); diff --git a/boards/arm/mimxrt1060_evk/CMakeLists.txt b/boards/arm/mimxrt1060_evk/CMakeLists.txt index c797d3ce3858eb..24846045ab7114 100644 --- a/boards/arm/mimxrt1060_evk/CMakeLists.txt +++ b/boards/arm/mimxrt1060_evk/CMakeLists.txt @@ -7,3 +7,9 @@ zephyr_library() zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_library_sources(pinmux.c) + +if (CONFIG_DISPLAY) +message(WARNING " +CONFIG_DISPLAY: Running this firmware on a board without a display may damage the board +") +endif() diff --git a/boards/arm/mimxrt1060_evk/Kconfig.defconfig b/boards/arm/mimxrt1060_evk/Kconfig.defconfig index bab453585fd330..b2022257cf222a 100644 --- a/boards/arm/mimxrt1060_evk/Kconfig.defconfig +++ b/boards/arm/mimxrt1060_evk/Kconfig.defconfig @@ -13,10 +13,6 @@ choice CODE_LOCATION default CODE_FLEXSPI endchoice -choice DATA_LOCATION - default DATA_SEMC -endchoice - config DISK_ACCESS_USDHC1 default y depends on DISK_ACCESS_USDHC @@ -45,9 +41,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_MCUX_0 - default y if NET_L2_ETHERNET - endif # NETWORKING if LVGL @@ -61,10 +54,10 @@ config LVGL_POINTER_KSCAN config LVGL_POINTER_KSCAN_DEV_NAME default "FT5336" -config LVGL_HOR_RES +config LVGL_HOR_RES_MAX default 480 -config LVGL_VER_RES +config LVGL_VER_RES_MAX default 272 config LVGL_VDB_SIZE diff --git a/boards/arm/mimxrt1060_evk/board.cmake b/boards/arm/mimxrt1060_evk/board.cmake index 2ef5a2ba122929..6afb8ba22d225a 100644 --- a/boards/arm/mimxrt1060_evk/board.cmake +++ b/boards/arm/mimxrt1060_evk/board.cmake @@ -4,18 +4,8 @@ # SPDX-License-Identifier: Apache-2.0 # -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - -board_runner_args(pyocd "--target=cortex_m") +board_runner_args(pyocd "--target=mimxrt1060") board_runner_args(jlink "--device=MIMXRT1062xxx6A") -include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/mimxrt1060_evk/doc/index.rst b/boards/arm/mimxrt1060_evk/doc/index.rst index 43fa4af20a3bf6..95936a9fff3113 100644 --- a/boards/arm/mimxrt1060_evk/doc/index.rst +++ b/boards/arm/mimxrt1060_evk/doc/index.rst @@ -323,6 +323,37 @@ should see the following message in the terminal: ***** Booting Zephyr OS v1.14.0-rc1 ***** Hello World! mimxrt1060_evk +Troubleshooting +=============== + +If the debug probe fails to connect with the following error, it's possible +that the boot header in QSPI flash is invalid or corrupted. The boot header is +configured by :option:`CONFIG_NXP_IMX_RT_BOOT_HEADER`. + +.. code-block:: console + + Remote debugging using :2331 + Remote communication error. Target disconnected.: Connection reset by peer. + "monitor" command not supported by this target. + "monitor" command not supported by this target. + You can't do that when your target is `exec' + (gdb) Could not connect to target. + Please check power, connection and settings. + +You can fix it by erasing and reprogramming the QSPI flash with the following +steps: + +#. Set the SW7 DIP switches to ON-OFF-ON-OFF to prevent booting from QSPI flash. + +#. Reset by pressing SW9 + +#. Run ``west debug`` or ``west flash`` again with a known working Zephyr + application. + +#. Set the SW7 DIP switches to OFF-OFF-ON-OFF to boot from QSPI flash. + +#. Reset by pressing SW9 + .. _MIMXRT1060-EVK Website: https://www.nxp.com/support/developer-resources/software-development-tools/mcuxpresso-software-and-tools/mimxrt1060-evk-i.mx-rt1060-evaluation-kit:MIMXRT1060-EVK diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts index e9793d55b1e2ac..7af897f98d09da 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts @@ -16,18 +16,21 @@ led0 = &green_led; sw0 = &user_button; kscan0 = &touch_controller; + watchdog0 = &wdog0; }; chosen { + zephyr,sram = &sdram0; + zephyr,dtcm = &dtcm; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; + zephyr,can-primary = &flexcan2; }; sdram0: memory@80000000 { /* Micron MT48LC16M16A2B4-6AIT:G */ device_type = "memory"; - compatible = "mmio-sram"; - reg = <0x80000000 0x2000000>; + reg = <0x80000000 DT_SIZE_M(32)>; }; leds { @@ -88,7 +91,7 @@ arduino_serial: &lpuart3 {}; &flexspi { - reg = <0x402a8000 0x4000>, <0x60000000 0x800000>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; is25wp064: is25wp064@0 { compatible = "issi,is25wp064", "jedec,spi-nor"; size = <67108864>; @@ -140,4 +143,18 @@ arduino_serial: &lpuart3 {}; status = "okay"; pwr-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&edma0 { + status = "okay"; +}; + +&flexcan2 { + status = "okay"; + bus-speed = <125000>; +}; + +&wdog0 { + status = "okay"; }; diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.yaml b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.yaml index 984769869ea6ff..6335b130b2d80b 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.yaml +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.yaml @@ -24,3 +24,6 @@ supported: - sdhc - usb_device - kscan:touch + - dma + - can + - watchdog diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_defconfig b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_defconfig index 2f417d515c0799..8a32442e5ce012 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_defconfig +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_defconfig @@ -14,3 +14,4 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=600000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.dts b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.dts index bea21d50e373fa..867b34c071024c 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.dts +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.dts @@ -8,7 +8,7 @@ /delete-node/ &is25wp064; &flexspi { - reg = <0x402a8000 0x4000>, <0x60000000 0x4000000>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(64)>; hyperflash0: hyperflash@0 { compatible = "cypress,s26ks512s"; reg = <0>; diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.yaml b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.yaml index 7acc4148b4ef98..421df62d65e1ef 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.yaml +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.yaml @@ -23,3 +23,4 @@ supported: - netif:eth - sdhc - usb_device + - watchdog diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash_defconfig b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash_defconfig index 4dcad3e7300d03..257a0bd794dc86 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash_defconfig +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash_defconfig @@ -14,3 +14,4 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=600000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mimxrt1060_evk/pinmux.c b/boards/arm/mimxrt1060_evk/pinmux.c index 961ea3c4d2a60d..7115f4cb98bb0b 100644 --- a/boards/arm/mimxrt1060_evk/pinmux.c +++ b/boards/arm/mimxrt1060_evk/pinmux.c @@ -31,10 +31,10 @@ static gpio_pin_config_t enet_gpio_config = { *Hyst. Enable Field: Hysteresis Enabled. */ -static void mimxrt1060_evk_usdhc_pinmux(u16_t nusdhc, bool init, u32_t speed, - u32_t strength) +static void mimxrt1060_evk_usdhc_pinmux(uint16_t nusdhc, bool init, uint32_t speed, + uint32_t strength) { - u32_t cmd_data = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + uint32_t cmd_data = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | @@ -42,7 +42,7 @@ static void mimxrt1060_evk_usdhc_pinmux(u16_t nusdhc, bool init, u32_t speed, IOMUXC_SW_PAD_CTL_PAD_PUS(1) | IOMUXC_SW_PAD_CTL_PAD_DSE(strength); - u32_t clk = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + uint32_t clk = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) | @@ -85,7 +85,7 @@ static void mimxrt1060_evk_usdhc_pinmux(u16_t nusdhc, bool init, u32_t speed, } #endif -static int mimxrt1060_evk_init(struct device *dev) +static int mimxrt1060_evk_init(const struct device *dev) { ARG_UNUSED(dev); @@ -101,8 +101,8 @@ static int mimxrt1060_evk_init(struct device *dev) IOMUXC_SW_PAD_CTL_PAD_DSE(6)); #endif -#if !DT_NODE_HAS_STATUS(DT_NODELABEL(enet), okay) - /* LED */ +#if !CONFIG_NET_L2_ETHERNET + /* Shared GPIO between USER_LED and ENET_RST */ IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, @@ -180,7 +180,9 @@ static int mimxrt1060_evk_init(struct device *dev) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0); + /* Shared GPIO between USER_LED and ENET_RST */ IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0xB0A9u); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, 0xB0A9u); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0xB0E9); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0xB0E9); @@ -263,6 +265,33 @@ static int mimxrt1060_evk_init(struct device *dev) GPIO_PinInit(GPIO2, 31, &config); #endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan1), okay) && CONFIG_CAN + /* FLEXCAN1 TX, RX */ + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_FLEXCAN1_TX, 1); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_FLEXCAN1_RX, 1); + + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_08_FLEXCAN1_TX, 0x10B0u); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_09_FLEXCAN1_RX, 0x10B0u); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan2), okay) && CONFIG_CAN + /* FLEXCAN2 TX, RX */ + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 1); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 1); + + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 0x10B0u); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 0x10B0u); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan3), okay) && CONFIG_CAN + /* FLEXCAN3 TX, RX */ + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_FLEXCAN3_TX, 1); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_FLEXCAN3_RX, 1); + + IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_36_FLEXCAN3_TX, 0x10B0u); + IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_37_FLEXCAN3_RX, 0x10B0u); +#endif + #if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc1), okay) && CONFIG_DISK_ACCESS_USDHC1 mimxrt1060_evk_usdhc_pinmux(0, true, 2, 1); imxrt_usdhc_pinmux_cb_register(mimxrt1060_evk_usdhc_pinmux); @@ -272,7 +301,7 @@ static int mimxrt1060_evk_init(struct device *dev) } #if DT_NODE_HAS_STATUS(DT_NODELABEL(enet), okay) && CONFIG_NET_L2_ETHERNET -static int mimxrt1060_evk_phy_reset(struct device *dev) +static int mimxrt1060_evk_phy_reset(const struct device *dev) { /* RESET PHY chip. */ k_busy_wait(USEC_PER_MSEC * 10U); diff --git a/boards/arm/mimxrt1064_evk/CMakeLists.txt b/boards/arm/mimxrt1064_evk/CMakeLists.txt index c797d3ce3858eb..24846045ab7114 100644 --- a/boards/arm/mimxrt1064_evk/CMakeLists.txt +++ b/boards/arm/mimxrt1064_evk/CMakeLists.txt @@ -7,3 +7,9 @@ zephyr_library() zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_library_sources(pinmux.c) + +if (CONFIG_DISPLAY) +message(WARNING " +CONFIG_DISPLAY: Running this firmware on a board without a display may damage the board +") +endif() diff --git a/boards/arm/mimxrt1064_evk/Kconfig.defconfig b/boards/arm/mimxrt1064_evk/Kconfig.defconfig index e4a952ac3c5397..52e87780bf2a56 100644 --- a/boards/arm/mimxrt1064_evk/Kconfig.defconfig +++ b/boards/arm/mimxrt1064_evk/Kconfig.defconfig @@ -12,10 +12,6 @@ choice CODE_LOCATION default CODE_FLEXSPI2 endchoice -choice DATA_LOCATION - default DATA_SEMC -endchoice - config DISK_ACCESS_USDHC1 default y depends on DISK_ACCESS_USDHC @@ -44,9 +40,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_MCUX_0 - default y if NET_L2_ETHERNET - endif # NETWORKING if LVGL @@ -60,10 +53,10 @@ config LVGL_POINTER_KSCAN config LVGL_POINTER_KSCAN_DEV_NAME default "FT5336" -config LVGL_HOR_RES +config LVGL_HOR_RES_MAX default 480 -config LVGL_VER_RES +config LVGL_VER_RES_MAX default 272 config LVGL_VDB_SIZE diff --git a/boards/arm/mimxrt1064_evk/board.cmake b/boards/arm/mimxrt1064_evk/board.cmake index 17deca053362f4..b7da66ef1d48b7 100644 --- a/boards/arm/mimxrt1064_evk/board.cmake +++ b/boards/arm/mimxrt1064_evk/board.cmake @@ -4,18 +4,8 @@ # SPDX-License-Identifier: Apache-2.0 # -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - -board_runner_args(pyocd "--target=cortex_m") +board_runner_args(pyocd "--target=mimxrt1064") board_runner_args(jlink "--device=MIMXRT1064") -include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts index 5be3c30083bfbf..d1b92c00439789 100644 --- a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts +++ b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts @@ -20,15 +20,17 @@ }; chosen { + zephyr,sram = &sdram0; + zephyr,dtcm = &dtcm; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; + zephyr,can-primary = &flexcan2; }; sdram0: memory@80000000 { /* Micron MT48LC16M16A2B4-6AIT:G */ device_type = "memory"; - compatible = "mmio-sram"; - reg = <0x80000000 0x2000000>; + reg = <0x80000000 DT_SIZE_M(32)>; }; leds { @@ -165,3 +167,8 @@ arduino_i2c: &lpi2c1 {}; pwr-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; }; + +&flexcan2 { + status = "okay"; + bus-speed = <125000>; +}; diff --git a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.yaml b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.yaml index e94cf74584f905..b5ace3a8170980 100644 --- a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.yaml +++ b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.yaml @@ -26,3 +26,4 @@ supported: - usb_device - video - kscan:touch + - can diff --git a/boards/arm/mimxrt1064_evk/mimxrt1064_evk_defconfig b/boards/arm/mimxrt1064_evk/mimxrt1064_evk_defconfig index 38cc03e2254b7e..fa99c094ecd8f9 100644 --- a/boards/arm/mimxrt1064_evk/mimxrt1064_evk_defconfig +++ b/boards/arm/mimxrt1064_evk/mimxrt1064_evk_defconfig @@ -13,3 +13,4 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=600000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mimxrt1064_evk/pinmux.c b/boards/arm/mimxrt1064_evk/pinmux.c index 829c7f12e80962..5e80c3e5454182 100644 --- a/boards/arm/mimxrt1064_evk/pinmux.c +++ b/boards/arm/mimxrt1064_evk/pinmux.c @@ -31,10 +31,10 @@ static gpio_pin_config_t enet_gpio_config = { *Hyst. Enable Field: Hysteresis Enabled. */ -static void mimxrt1064_evk_usdhc_pinmux(u16_t nusdhc, bool init, u32_t speed, - u32_t strength) +static void mimxrt1064_evk_usdhc_pinmux(uint16_t nusdhc, bool init, uint32_t speed, + uint32_t strength) { - u32_t cmd_data = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + uint32_t cmd_data = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | @@ -42,7 +42,7 @@ static void mimxrt1064_evk_usdhc_pinmux(u16_t nusdhc, bool init, u32_t speed, IOMUXC_SW_PAD_CTL_PAD_PUS(1) | IOMUXC_SW_PAD_CTL_PAD_DSE(strength); - u32_t clk = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + uint32_t clk = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) | @@ -85,7 +85,7 @@ static void mimxrt1064_evk_usdhc_pinmux(u16_t nusdhc, bool init, u32_t speed, } #endif -static int mimxrt1064_evk_init(struct device *dev) +static int mimxrt1064_evk_init(const struct device *dev) { ARG_UNUSED(dev); @@ -101,8 +101,8 @@ static int mimxrt1064_evk_init(struct device *dev) IOMUXC_SW_PAD_CTL_PAD_DSE(6)); #endif -#if !DT_NODE_HAS_STATUS(DT_NODELABEL(enet), okay) - /* LED */ +#if !CONFIG_NET_L2_ETHERNET + /* Shared GPIO between USER_LED and ENET_RST */ IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0); IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, @@ -223,7 +223,9 @@ static int mimxrt1064_evk_init(struct device *dev) IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0); IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0); + /* Shared GPIO between USER_LED and ENET_RST */ IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0xB0A9u); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, 0xB0A9u); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0xB0E9); IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0xB0E9); @@ -267,6 +269,33 @@ static int mimxrt1064_evk_init(struct device *dev) IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_CSI_DATA02, 0); #endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan1), okay) && CONFIG_CAN + /* FLEXCAN1 TX, RX */ + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_FLEXCAN1_TX, 1); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_FLEXCAN1_RX, 1); + + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_08_FLEXCAN1_TX, 0x10B0u); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_09_FLEXCAN1_RX, 0x10B0u); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan2), okay) && CONFIG_CAN + /* FLEXCAN2 TX, RX */ + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 1); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 1); + + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 0x10B0u); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 0x10B0u); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan3), okay) && CONFIG_CAN + /* FLEXCAN3 TX, RX */ + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_FLEXCAN3_TX, 1); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_FLEXCAN3_RX, 1); + + IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_36_FLEXCAN3_TX, 0x10B0u); + IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_37_FLEXCAN3_RX, 0x10B0u); +#endif + #if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc1), okay) && CONFIG_DISK_ACCESS_USDHC1 mimxrt1064_evk_usdhc_pinmux(0, true, 2, 1); imxrt_usdhc_pinmux_cb_register(mimxrt1064_evk_usdhc_pinmux); @@ -276,7 +305,7 @@ static int mimxrt1064_evk_init(struct device *dev) } #if DT_NODE_HAS_STATUS(DT_NODELABEL(enet), okay) && CONFIG_NET_L2_ETHERNET -static int mimxrt1064_evk_phy_reset(struct device *dev) +static int mimxrt1064_evk_phy_reset(const struct device *dev) { /* RESET PHY chip. */ k_busy_wait(USEC_PER_MSEC * 10U); diff --git a/boards/arm/mimxrt685_evk/CMakeLists.txt b/boards/arm/mimxrt685_evk/CMakeLists.txt new file mode 100644 index 00000000000000..b9d7865bf893f3 --- /dev/null +++ b/boards/arm/mimxrt685_evk/CMakeLists.txt @@ -0,0 +1,9 @@ +# +# Copyright (c) 2020, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_library() +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) +zephyr_library_sources(pinmux.c) diff --git a/boards/arm/mimxrt685_evk/Kconfig.board b/boards/arm/mimxrt685_evk/Kconfig.board new file mode 100644 index 00000000000000..65999c057e5993 --- /dev/null +++ b/boards/arm/mimxrt685_evk/Kconfig.board @@ -0,0 +1,8 @@ +# Copyright (c) 2020, NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MIMXRT685_EVK + bool "NXP MIMXRT685-EVK" + depends on SOC_SERIES_IMX_RT6XX + select SOC_PART_NUMBER_MIMXRT685SFVKB + select NXP_IMX_RT6XX_BOOT_HEADER diff --git a/boards/arm/mimxrt685_evk/Kconfig.defconfig b/boards/arm/mimxrt685_evk/Kconfig.defconfig new file mode 100644 index 00000000000000..8eab98d79a8333 --- /dev/null +++ b/boards/arm/mimxrt685_evk/Kconfig.defconfig @@ -0,0 +1,51 @@ +# MIMXRT685-EVK board + +# Copyright (c) 2020, NXP +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_MIMXRT685_EVK + +config BOARD + default "mimxrt685_evk_cm33" + +config XTAL_SYS_CLK_HZ + default 24000000 + +config SYSOSC_SETTLING_US + default 260 + +if PINMUX_MCUX_LPC + +config PINMUX_MCUX_LPC_PORT0 + default y + +config PINMUX_MCUX_LPC_PORT1 + default y + +endif # PINMUX_MCUX_LPC + +if GPIO_MCUX_LPC + +config GPIO_MCUX_LPC_PORT0 + default y + +config GPIO_MCUX_LPC_PORT1 + default y + +endif # GPIO_MCUX_LPC + +config FXOS8700_DRDY_INT1 + default y + depends on FXOS8700_TRIGGER + +if DMA_MCUX_LPC + +# Memory from the heap pool is used to allocate DMA descriptors for +# channels that use multiple blocks for a DMA transfer. +# Adjust HEAP_MEM_POOL_SIZE in case you need more memory. +config HEAP_MEM_POOL_SIZE + default 4096 + +endif # DMA_MCUX_LPC + +endif # BOARD_MIMXRT685_EVK diff --git a/boards/arm/mimxrt685_evk/board.cmake b/boards/arm/mimxrt685_evk/board.cmake new file mode 100644 index 00000000000000..a399d5f6398e23 --- /dev/null +++ b/boards/arm/mimxrt685_evk/board.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) 2020, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_runner_args(jlink "--device=MIMXRT685S_M33" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/mimxrt685_evk/doc/index.rst b/boards/arm/mimxrt685_evk/doc/index.rst new file mode 100644 index 00000000000000..cbefa0049aea73 --- /dev/null +++ b/boards/arm/mimxrt685_evk/doc/index.rst @@ -0,0 +1,219 @@ +.. _mimxrt685_evk: + +NXP MIMXRT685-EVK +################## + +Overview +******** + +The i.MX RT600 is a crossover MCU family optimized for 32-bit immersive audio +playback and voice user interface applications combining a high-performance +Cadence Tensilica HiFi 4 audio DSP core with a next-generation Cortex-M33 +core. The i.MX RT600 family of crossover MCUs is designed to unlock the +potential of voice-assisted end nodes with a secure, power-optimized embedded +processor. + +The i.MX RT600 family provides up to 4.5MB of on-chip SRAM and several +high-bandwidth interfaces to access off-chip flash, including an Octal/Quad SPI +interface with an on-the-fly decryption engine. + +.. image:: ./mimxrt685_evk.jpg + :width: 720px + :align: center + :alt: MIMXRT685-EVK + +Hardware +******** + +- MIMXRT685SFVKB Cortex-M33 (300 MHz, 128 KB TCM) core processor with Cadence Xtensa HiFi4 DSP +- Onboard, high-speed USB, Link2 debug probe with CMSIS-DAP protocol (supporting Cortex M33 debug only) +- High speed USB port with micro A/B connector for the host or device functionality +- UART, I2C and SPI port bridging from i.MX RT685 target to USB via the on-board debug probe +- 512 MB Macronix Octal SPI Flash operating at 1.8 V +- 4.5 MB Apmemory PSRAM +- Full size SD card slot (SDIO) +- NXP PCA9420UK PMIC +- User LEDs +- Reset and User buttons +- Arduino and PMod/Host expansion connectors +- NXP FXOS8700CQ accelerometer +- Stereo audio codec with line in/out and electret microphone +- Stereo NXP TFA9894 digital amplifiers, with option for external +5V power for higher performance speakers +- Support for up to eight off-board digital microphones via 12-pin header +- Two on-board DMICS + +For more information about the MIMXRT685 SoC and MIMXRT685-EVK board, see +these references: + +- `i.MX RT685 Website`_ +- `i.MX RT685 Datasheet`_ +- `i.MX RT685 Reference Manual`_ +- `MIMXRT685-EVK Website`_ +- `MIMXRT685-EVK User Guide`_ +- `MIMXRT685-EVK Schematics`_ + +Supported Features +================== + +The mimxrt685_evk board configuration supports the following hardware +features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| IOCON | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| USART | on-chip | serial port-polling | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: + + ``boards/arm/mimxrt685_evk/mimxrt685_evk_cm33_defconfig`` + +Other hardware features are not currently supported by the port. + +Connections and IOs +=================== + +The MIMXRT685 SoC has IOCON registers, which can be used to configure the +functionality of a pin. + ++---------+-----------------+----------------------------+ +| Name | Function | Usage | ++=========+=================+============================+ +| PIO0_2 | USART | USART RX | ++---------+-----------------+----------------------------+ +| PIO0_1 | USART | USART TX | ++---------+-----------------+----------------------------+ +| PIO0_14 | GPIO | GREEN LED | ++---------+-----------------+----------------------------+ +| PIO1_1 | GPIO | SW0 | ++---------+-----------------+----------------------------+ +| PIO0_17 | I2C | I2C SDA | ++---------+-----------------+----------------------------+ +| PIO0_18 | I2C | I2C SCL | ++---------+-----------------+----------------------------+ +| PIO1_5 | GPIO | FXOS8700 TRIGGER | ++---------+-----------------+----------------------------+ +| PIO1_5 | SPI | SPI MOSI | ++---------+-----------------+----------------------------+ +| PIO1_4 | SPI | SPI MISO | ++---------+-----------------+----------------------------+ +| PIO1_3 | SPI | SPI SCK | ++---------+-----------------+----------------------------+ +| PIO1_6 | SPI | SPI SSEL | ++---------+-----------------+----------------------------+ + +System Clock +============ + +The MIMXRT685 SoC is configured to use the main system PLL at 250MHz +as a source for the system clock. Other sources for the system clock +are provided in the SOC, depending on your system requirements. + +Serial Port +=========== + +The MIMXRT685 SoC has 8 FLEXCOMM interfaces for serial communication. One is +configured as USART for the console and the remaining are not used. + +Programming and Debugging +************************* + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Configuring a Debug Probe +========================= + +A debug probe is used for both flashing and debugging the board. This board is +configured by default to use the LPC-Link2. + +:ref:`lpclink2-jlink-onboard-debug-probe` +----------------------------------------- + +Install the :ref:`jlink-debug-host-tools` and make sure they are in your search +path. + +Follow the instructions in :ref:`lpclink2-jlink-onboard-debug-probe` to program +the J-Link firmware. Please make sure you have the latest firmware for this +board. + +Configuring a Console +===================== + +Connect a USB cable from your PC to J16, and use the serial terminal of your choice +(minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Flashing +======== + +Here is an example for the :ref:`hello_world` application. This example uses the +:ref:`jlink-debug-host-tools` as default. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt685_evk_cm33 + :goals: flash + +Open a serial terminal, reset the board (press the RESET button), and you should +see the following message in the terminal: + +.. code-block:: console + + ***** Booting Zephyr OS v1.14.0 ***** + Hello World! mimxrt685_evk_cm33 + +Debugging +========= + +Here is an example for the :ref:`hello_world` application. This example uses the +:ref:`jlink-debug-host-tools` as default. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt685_evk_cm33 + :goals: debug + +Open a serial terminal, step through the application in your debugger, and you +should see the following message in the terminal: + +.. code-block:: console + + ***** Booting Zephyr OS zephyr-v2.3.0 ***** + Hello World! mimxrt685_evk_cm33 + +.. _MIMXRT685-EVK Website: + https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt600-evaluation-kit:MIMXRT685-EVK + +.. _MIMXRT685-EVK User Guide: + https://www.nxp.com/docs/en/user-guide/UM11159.pdf + +.. _MIMXRT685-EVK Schematics: + https://www.nxp.com/downloads/en/design-support/RT685-DESIGNFILES.zip + +.. _i.MX RT685 Website: + https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/i-mx-rt-crossover-mcus/i-mx-rt600-crossover-mcu-with-arm-cortex-m33-and-dsp-cores:i.MX-RT600 + +.. _i.MX RT685 Datasheet: + https://www.nxp.com/docs/en/data-sheet/DS-RT600.pdf + +.. _i.MX RT685 Reference Manual: + https://www.nxp.com/docs/en/user-guide/UM11147.pdf diff --git a/boards/arm/mimxrt685_evk/doc/mimxrt685_evk.jpg b/boards/arm/mimxrt685_evk/doc/mimxrt685_evk.jpg new file mode 100644 index 00000000000000..e7c3886641f378 Binary files /dev/null and b/boards/arm/mimxrt685_evk/doc/mimxrt685_evk.jpg differ diff --git a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts new file mode 100644 index 00000000000000..882f18b20bac4e --- /dev/null +++ b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2020, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "NXP MIMXRT685-EVK board"; + compatible = "nxp,mimxrt685"; + + aliases { + sw0 = &user_button_1; + sw1 = &user_button_2; + led0 = &green_led; + led1 = &blue_led; + led2 = &red_led; + usart-0 = &flexcomm0; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &flexcomm0; + zephyr,shell-uart = &flexcomm0; + }; + + flash0: flash@18000000 { + /* Octal flash MX25UM51345G */ + reg = <0x18000000 DT_SIZE_K(65536)>; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_1: button_0 { + label = "User SW1"; + gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + }; + user_button_2: button_1 { + label = "User SW2"; + gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + green_led: led_1 { + gpios = <&gpio0 14 0>; + label = "User LED_GREEN"; + }; + blue_led: led_2 { + gpios = <&gpio0 26 0>; + label = "User LED_BLUE"; + }; + red_led: led_3 { + gpios = <&gpio0 31 0>; + label = "User LED_RED"; + }; + }; +}; + +&flexcomm0 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; +}; + +arduino_i2c: &flexcomm2 { + compatible = "nxp,lpc-i2c"; + status = "okay"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + + fxos8700@1e { + compatible = "nxp,fxos8700"; + reg = <0x1e>; + label = "FXOS8700"; + int1-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + }; +}; + +arduino_spi: &flexcomm5 { + compatible = "nxp,lpc-spi"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + dmas = <&dma0 10>, <&dma0 11>; + dma-names = "rx", "tx"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&dma0 { + /* + * The total number of dma channels available is defined by + * FSL_FEATURE_DMA_NUMBER_OF_CHANNELS in the SoC features file. + * Since memory from the heap pool is allocated based on the number + * of DMA channels, set this property to as many channels is needed + * for the platform. Adjust HEAP_MEM_POOL_SIZE in case you need more + * memory. + */ + dma-channels = <20>; + status = "okay"; +}; + +&user_button_1 { + status = "okay"; +}; + +&user_button_2 { + status = "okay"; +}; + +&green_led { + status = "okay"; +}; + +&blue_led { + status = "okay"; +}; + +&red_led { + status = "okay"; +}; diff --git a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.yaml b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.yaml new file mode 100644 index 00000000000000..a21e8d950f17b7 --- /dev/null +++ b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.yaml @@ -0,0 +1,25 @@ +# +# Copyright (c) 2020, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: mimxrt685_evk_cm33 +name: NXP MIMXRT685-EVK +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 4608 +flash: 65536 +supported: + - arduino_i2c + - arduino_spi + - counter + - dma + - gpio + - hwinfo + - i2c + - spi diff --git a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33_defconfig b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33_defconfig new file mode 100644 index 00000000000000..d1ba8ff3a6250b --- /dev/null +++ b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33_defconfig @@ -0,0 +1,22 @@ +# +# Copyright (c) 2020, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_MIMXRT685S_CM33=y +CONFIG_SOC_SERIES_IMX_RT6XX=y +CONFIG_BOARD_MIMXRT685_EVK=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_GPIO=y +CONFIG_PINMUX=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=250105263 +# Enable TrustZone-M +CONFIG_TRUSTED_EXECUTION_SECURE=y + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mimxrt685_evk/pinmux.c b/boards/arm/mimxrt685_evk/pinmux.c new file mode 100644 index 00000000000000..3abf2220e67547 --- /dev/null +++ b/boards/arm/mimxrt685_evk/pinmux.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2020, NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static int mimxrt685_evk_pinmux_init(const struct device *dev) +{ + ARG_UNUSED(dev); + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm0), nxp_lpc_usart, okay) && CONFIG_SERIAL + /* USART0 RX, TX */ + const uint32_t port0_pin1_config = (/* Pin is configured as FC0_TXD_SCL_MISO_WS */ + IOPCTL_PIO_FUNC1 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Disable input buffer function */ + IOPCTL_PIO_INBUF_DI | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT0 PIN1 (coords: G2) is configured as FC0_TXD_SCL_MISO_WS */ + IOPCTL_PinMuxSet(IOPCTL, 0U, 1U, port0_pin1_config); + + const uint32_t port0_pin2_config = (/* Pin is configured as FC0_RXD_SDA_MOSI_DATA */ + IOPCTL_PIO_FUNC1 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT0 PIN2 (coords: G4) is configured as FC0_RXD_SDA_MOSI_DATA */ + IOPCTL_PinMuxSet(IOPCTL, 0U, 2U, port0_pin2_config); +#endif + +#if DT_PHA_HAS_CELL(DT_ALIAS(sw0), gpios, pin) + const uint32_t port1_pin1_config = (/* Pin is configured as PIO1_1 */ + IOPCTL_PIO_FUNC0 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT1 PIN1 (coords: G15) is configured as PIO1_1 */ + IOPCTL_PinMuxSet(IOPCTL, 1U, 1U, port1_pin1_config); +#endif + +#if DT_PHA_HAS_CELL(DT_ALIAS(sw1), gpios, pin) + const uint32_t port0_pin10_config = (/* Pin is configured as PIO0_10 */ + IOPCTL_PIO_FUNC0 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT0 PIN10 (coords: J3) is configured as PIO0_10 */ + IOPCTL_PinMuxSet(IOPCTL, 0U, 10U, port0_pin10_config); +#endif + +#ifdef DT_GPIO_LEDS_LED_1_GPIOS_CONTROLLER + const uint32_t port0_pin14_config = (/* Pin is configured as PIO0_14 */ + IOPCTL_PIO_FUNC0 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Disable input buffer function */ + IOPCTL_PIO_INBUF_DI | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT0 PIN14 (coords: A3) is configured as PIO0_14 */ + IOPCTL_PinMuxSet(IOPCTL, 0U, 14U, port0_pin14_config); +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm2), nxp_lpc_i2c, okay) && CONFIG_I2C + const uint32_t port0_pin17_config = (/* Pin is configured as FC2_CTS_SDA_SSEL0 */ + IOPCTL_PIO_FUNC1 | + /* Enable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_EN | + /* Enable pull-up function */ + IOPCTL_PIO_PULLUP_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Full drive enable */ + IOPCTL_PIO_FULLDRIVE_EN | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is enabled */ + IOPCTL_PIO_PSEDRAIN_EN | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT0 PIN17 (coords: D7) is configured as FC2_CTS_SDA_SSEL0 */ + IOPCTL_PinMuxSet(IOPCTL, 0U, 17U, port0_pin17_config); + + const uint32_t port0_pin18_config = (/* Pin is configured as FC2_RTS_SCL_SSEL1 */ + IOPCTL_PIO_FUNC1 | + /* Enable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_EN | + /* Enable pull-up function */ + IOPCTL_PIO_PULLUP_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Full drive enable */ + IOPCTL_PIO_FULLDRIVE_EN | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is enabled */ + IOPCTL_PIO_PSEDRAIN_EN | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT0 PIN18 (coords: B7) is configured as FC2_RTS_SCL_SSEL1 */ + IOPCTL_PinMuxSet(IOPCTL, 0U, 18U, port0_pin18_config); +#endif + +#ifdef CONFIG_FXOS8700_TRIGGER + const uint32_t port1_pin5_config = (/* Pin is configured as PIO1_5 */ + IOPCTL_PIO_FUNC0 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT1 PIN5 (coords: J16) is configured as PIO1_5 */ + IOPCTL_PinMuxSet(IOPCTL, 1U, 5U, port1_pin5_config); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm5), okay) && CONFIG_SPI + const uint32_t port1_pin3_config = (/* Pin is configured as FC5_SCK */ + IOPCTL_PIO_FUNC1 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT1 PIN3 (coords: G16) is configured as FC5_SCK */ + IOPCTL_PinMuxSet(IOPCTL, 1U, 3U, port1_pin3_config); + + const uint32_t port1_pin4_config = (/* Pin is configured as FC5_MISO */ + IOPCTL_PIO_FUNC1 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT1 PIN4 (coords: G17) is configured as FC5_TXD_SCL_MISO_WS */ + IOPCTL_PinMuxSet(IOPCTL, 1U, 4U, port1_pin4_config); + + const uint32_t port1_pin5_config = (/* Pin is configured as FC5_MOSI */ + IOPCTL_PIO_FUNC1 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT1 PIN5 (coords: J16) is configured as FC5_RXD_SDA_MOSI_DATA */ + IOPCTL_PinMuxSet(IOPCTL, 1U, 5U, port1_pin5_config); + + const uint32_t port1_pin6_config = (/* Pin is configured as FC5_SSEL0 */ + IOPCTL_PIO_FUNC1 | + /* Disable pull-up / pull-down function */ + IOPCTL_PIO_PUPD_DI | + /* Enable pull-down function */ + IOPCTL_PIO_PULLDOWN_EN | + /* Enables input buffer function */ + IOPCTL_PIO_INBUF_EN | + /* Normal mode */ + IOPCTL_PIO_SLEW_RATE_NORMAL | + /* Normal drive */ + IOPCTL_PIO_FULLDRIVE_DI | + /* Analog mux is disabled */ + IOPCTL_PIO_ANAMUX_DI | + /* Pseudo Output Drain is disabled */ + IOPCTL_PIO_PSEDRAIN_DI | + /* Input function is not inverted */ + IOPCTL_PIO_INV_DI); + /* PORT1 PIN6 (coords: J17) is configured as FC5_CTS_SDA_SSEL0 */ + IOPCTL_PinMuxSet(IOPCTL, 1U, 6U, port1_pin6_config); +#endif + + return 0; +} + +SYS_INIT(mimxrt685_evk_pinmux_init, PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY); diff --git a/boards/arm/mimxrt685_evk/pre_dt_board.cmake b/boards/arm/mimxrt685_evk/pre_dt_board.cmake new file mode 100644 index 00000000000000..e23600abc77326 --- /dev/null +++ b/boards/arm/mimxrt685_evk/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2020, NXP +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "simple_bus_reg" on RT6XX boards as all GPIO ports use the same register. +list(APPEND EXTRA_DTC_FLAGS "-Wno-simple_bus_reg") diff --git a/boards/arm/mm_swiftio/Kconfig.defconfig b/boards/arm/mm_swiftio/Kconfig.defconfig index e24ab5ea213543..9bcc4d73609282 100644 --- a/boards/arm/mm_swiftio/Kconfig.defconfig +++ b/boards/arm/mm_swiftio/Kconfig.defconfig @@ -12,10 +12,6 @@ choice CODE_LOCATION default CODE_FLEXSPI endchoice -choice DATA_LOCATION - default DATA_SEMC -endchoice - config DISK_ACCESS_USDHC1 default y depends on DISK_ACCESS_USDHC diff --git a/boards/arm/mm_swiftio/mm_swiftio.dts b/boards/arm/mm_swiftio/mm_swiftio.dts index 828e2152c067e3..1766cb16af8d31 100644 --- a/boards/arm/mm_swiftio/mm_swiftio.dts +++ b/boards/arm/mm_swiftio/mm_swiftio.dts @@ -19,6 +19,8 @@ }; chosen { + zephyr,sram = &sdram0; + zephyr,dtcm = &dtcm; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; }; @@ -26,8 +28,7 @@ sdram0: memory@80000000 { /* Micron MT48LC16M16A2B4-6AIT:G */ device_type = "memory"; - compatible = "mmio-sram"; - reg = <0x80000000 0x2000000>; + reg = <0x80000000 DT_SIZE_M(32)>; }; leds { @@ -51,7 +52,7 @@ &flexspi { - reg = <0x402a8000 0x4000>, <0x60000000 0x800000>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; is25wp064: is25wp064@0 { compatible = "issi,is25wp064", "jedec,spi-nor"; size = <67108864>; @@ -68,12 +69,89 @@ current-speed = <115200>; }; +&lpuart2 { + status = "okay"; + current-speed = <115200>; +}; + +&lpuart4 { + status = "okay"; + current-speed = <115200>; +}; + +&lpuart6 { + status = "okay"; + current-speed = <115200>; +}; + +&lpuart8 { + status = "okay"; + current-speed = <115200>; +}; + +&lpi2c1 { + status = "okay"; +}; + +&lpi2c3 { + status = "okay"; +}; + +&lpspi3 { + status = "okay"; + pcs-sck-delay = <50>; + sck-pcs-delay = <50>; + transfer-delay = <50>; +}; + +&lpspi4 { + status = "okay"; + pcs-sck-delay = <50>; + sck-pcs-delay = <50>; + transfer-delay = <50>; +}; + +&flexpwm1_pwm3 { + status = "okay"; +}; + +&flexpwm2_pwm0 { + status = "okay"; +}; + +&flexpwm2_pwm1 { + status = "okay"; +}; + +&flexpwm2_pwm2 { + status = "okay"; +}; + +&flexpwm2_pwm3 { + status = "okay"; +}; + +&flexpwm4_pwm0 { + status = "okay"; +}; + +&flexpwm4_pwm1 { + status = "okay"; +}; + +&flexpwm4_pwm2 { + status = "okay"; +}; + +&flexpwm4_pwm3 { + status = "okay"; +}; + &usb1 { status = "okay"; }; &usdhc1 { status = "okay"; - pwr-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; }; diff --git a/boards/arm/mm_swiftio/mm_swiftio.yaml b/boards/arm/mm_swiftio/mm_swiftio.yaml index 0c0c9a546f6119..943268dece1dfb 100644 --- a/boards/arm/mm_swiftio/mm_swiftio.yaml +++ b/boards/arm/mm_swiftio/mm_swiftio.yaml @@ -16,3 +16,4 @@ ram: 32768 flash: 8192 supported: - counter + - sdhc diff --git a/boards/arm/mm_swiftio/mm_swiftio_defconfig b/boards/arm/mm_swiftio/mm_swiftio_defconfig index 489e279e4306e3..cb78d7c1a6b3b1 100644 --- a/boards/arm/mm_swiftio/mm_swiftio_defconfig +++ b/boards/arm/mm_swiftio/mm_swiftio_defconfig @@ -13,3 +13,4 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=600000000 CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/mm_swiftio/mmswiftio_flexspi_nor_config.h b/boards/arm/mm_swiftio/mmswiftio_flexspi_nor_config.h index 4aba23b694f787..58c8c3caa4decf 100644 --- a/boards/arm/mm_swiftio/mmswiftio_flexspi_nor_config.h +++ b/boards/arm/mm_swiftio/mmswiftio_flexspi_nor_config.h @@ -114,9 +114,9 @@ enum { kSerialFlash_1Pad = 1, struct flexspi_lut_seq_t { - u8_t seqNum; - u8_t seqId; - u16_t reserved; + uint8_t seqNum; + uint8_t seqId; + uint16_t reserved; }; @@ -129,54 +129,54 @@ enum { kDeviceConfigCmdType_Generic, struct flexspi_mem_config_t { - u32_t tag; - u32_t version; - u32_t reserved0; - u8_t readSampleClkSrc; - u8_t csHoldTime; - u8_t csSetupTime; - u8_t columnAddressWidth; + uint32_t tag; + uint32_t version; + uint32_t reserved0; + uint8_t readSampleClkSrc; + uint8_t csHoldTime; + uint8_t csSetupTime; + uint8_t columnAddressWidth; - u8_t deviceModeCfgEnable; - u8_t deviceModeType; + uint8_t deviceModeCfgEnable; + uint8_t deviceModeType; - u16_t waitTimeCfgCommands; + uint16_t waitTimeCfgCommands; struct flexspi_lut_seq_t deviceModeSeq; - u32_t deviceModeArg; - u8_t configCmdEnable; - u8_t configModeType[3]; + uint32_t deviceModeArg; + uint8_t configCmdEnable; + uint8_t configModeType[3]; struct flexspi_lut_seq_t configCmdSeqs[3]; - u32_t reserved1; - u32_t configCmdArgs[3]; - u32_t reserved2; - u32_t controllerMiscOption; - - u8_t deviceType; - u8_t sflashPadType; - u8_t serialClkFreq; - - u8_t lutCustomSeqEnable; - - u32_t reserved3[2]; - u32_t sflashA1Size; - u32_t sflashA2Size; - u32_t sflashB1Size; - u32_t sflashB2Size; - u32_t csPadSettingOverride; - u32_t sclkPadSettingOverride; - u32_t dataPadSettingOverride; - u32_t dqsPadSettingOverride; - u32_t timeoutInMs; - u32_t commandInterval; - u16_t dataValidTime[2]; - u16_t busyOffset; - u16_t busyBitPolarity; - - u32_t lookupTable[64]; + uint32_t reserved1; + uint32_t configCmdArgs[3]; + uint32_t reserved2; + uint32_t controllerMiscOption; + + uint8_t deviceType; + uint8_t sflashPadType; + uint8_t serialClkFreq; + + uint8_t lutCustomSeqEnable; + + uint32_t reserved3[2]; + uint32_t sflashA1Size; + uint32_t sflashA2Size; + uint32_t sflashB1Size; + uint32_t sflashB2Size; + uint32_t csPadSettingOverride; + uint32_t sclkPadSettingOverride; + uint32_t dataPadSettingOverride; + uint32_t dqsPadSettingOverride; + uint32_t timeoutInMs; + uint32_t commandInterval; + uint16_t dataValidTime[2]; + uint16_t busyOffset; + uint16_t busyBitPolarity; + + uint32_t lookupTable[64]; struct flexspi_lut_seq_t lutCustomSeq[12]; - u32_t reserved4[4]; + uint32_t reserved4[4]; }; @@ -217,17 +217,17 @@ struct flexspi_mem_config_t { struct flexspi_nor_config_t { struct flexspi_mem_config_t memConfig; - u32_t pageSize; - u32_t sectorSize; - u8_t ipcmdSerialClkFreq; - u8_t isUniformBlockSize; - u8_t reserved0[2]; - u8_t serialNorType; - u8_t needExitNoCmdMode; - u8_t halfClkForNonReadCmd; - u8_t needRestoreNoCmdMode; - u32_t blockSize; - u32_t reserve2[11]; + uint32_t pageSize; + uint32_t sectorSize; + uint8_t ipcmdSerialClkFreq; + uint8_t isUniformBlockSize; + uint8_t reserved0[2]; + uint8_t serialNorType; + uint8_t needExitNoCmdMode; + uint8_t halfClkForNonReadCmd; + uint8_t needRestoreNoCmdMode; + uint32_t blockSize; + uint32_t reserve2[11]; }; #ifdef __cplusplus diff --git a/boards/arm/mm_swiftio/mmswiftio_sdram_ini_dcd.c b/boards/arm/mm_swiftio/mmswiftio_sdram_ini_dcd.c index ff1074c12b23dc..cac7fa33ccf1bf 100644 --- a/boards/arm/mm_swiftio/mmswiftio_sdram_ini_dcd.c +++ b/boards/arm/mm_swiftio/mmswiftio_sdram_ini_dcd.c @@ -16,7 +16,7 @@ __attribute__((section(".boot_hdr.dcd_data"))) #pragma location = ".boot_hdr.dcd_data" #endif -const u8_t dcd_data[] = { +const uint8_t dcd_data[] = { 0xD2, 0x04, 0x30, @@ -289,6 +289,6 @@ const u8_t dcd_data[] = { }; #else -const u8_t dcd_data[] = { 0x00 }; +const uint8_t dcd_data[] = { 0x00 }; #endif #endif diff --git a/boards/arm/mm_swiftio/pinmux.c b/boards/arm/mm_swiftio/pinmux.c index 0d0531b3ba1708..44a01315956037 100644 --- a/boards/arm/mm_swiftio/pinmux.c +++ b/boards/arm/mm_swiftio/pinmux.c @@ -29,17 +29,17 @@ static gpio_pin_config_t enet_gpio_config = { */ static void mm_swiftio_usdhc_pinmux( - u16_t nusdhc, bool init, - u32_t speed, u32_t strength) + uint16_t nusdhc, bool init, + uint32_t speed, uint32_t strength) { - u32_t cmd_data = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + uint32_t cmd_data = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) | IOMUXC_SW_PAD_CTL_PAD_DSE(strength); - u32_t clk = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | + uint32_t clk = IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) | @@ -102,7 +102,7 @@ static void mm_swiftio_usdhc_pinmux( } #endif -static int mm_swiftio_init(struct device *dev) +static int mm_swiftio_init(const struct device *dev) { ARG_UNUSED(dev); @@ -187,34 +187,6 @@ static int mm_swiftio_init(struct device *dev) IOMUXC_SW_PAD_CTL_PAD_DSE(6)); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi3), okay) && CONFIG_SPI - /* LPSPI3 SCK, SDO, SDI, PCS0 */ - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_00_LPSPI3_SCK, 0); - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_01_LPSPI3_SDO, 0); - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_LPSPI3_SDI, 0); - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_03_LPSPI3_PCS0, 0); - - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_00_LPSPI3_SCK, - IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | - IOMUXC_SW_PAD_CTL_PAD_SPEED(2) | - IOMUXC_SW_PAD_CTL_PAD_DSE(6)); - - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_01_LPSPI3_SDO, - IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | - IOMUXC_SW_PAD_CTL_PAD_SPEED(2) | - IOMUXC_SW_PAD_CTL_PAD_DSE(6)); - - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_02_LPSPI3_SDI, - IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | - IOMUXC_SW_PAD_CTL_PAD_SPEED(2) | - IOMUXC_SW_PAD_CTL_PAD_DSE(6)); - - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_03_LPSPI3_PCS0, - IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | - IOMUXC_SW_PAD_CTL_PAD_SPEED(2) | - IOMUXC_SW_PAD_CTL_PAD_DSE(6)); -#endif - #if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc1), okay) && CONFIG_DISK_ACCESS_USDHC1 mm_swiftio_usdhc_pinmux(0, true, 2, 1); imxrt_usdhc_pinmux_cb_register(mm_swiftio_usdhc_pinmux); diff --git a/boards/arm/mps2_an385/board.cmake b/boards/arm/mps2_an385/board.cmake index 2ad29676e955ed..0ae7ec0e7a25f0 100644 --- a/boards/arm/mps2_an385/board.cmake +++ b/boards/arm/mps2_an385/board.cmake @@ -10,7 +10,4 @@ set(QEMU_FLAGS_${ARCH} -vga none ) -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=7,align=off,sleep=off -rtc clock=vm) -endif() board_set_debugger_ifnset(qemu) diff --git a/boards/arm/mps2_an385/mps2_an385_defconfig b/boards/arm/mps2_an385/mps2_an385_defconfig index 5f8aabbcc4bc32..a0ad7feeb71b3e 100644 --- a/boards/arm/mps2_an385/mps2_an385_defconfig +++ b/boards/arm/mps2_an385/mps2_an385_defconfig @@ -9,6 +9,7 @@ CONFIG_SOC_MPS2_AN385=y CONFIG_BOARD_MPS2_AN385=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_RUNTIME_NMI=y +CONFIG_QEMU_ICOUNT_SHIFT=7 # GPIOs CONFIG_GPIO=y @@ -27,11 +28,4 @@ CONFIG_WATCHDOG=y CONFIG_I2C=y -#Enable MPU CONFIG_ARM_MPU=y -CONFIG_MAIN_STACK_SIZE=8192 -CONFIG_IDLE_STACK_SIZE=8192 -CONFIG_PRIVILEGED_STACK_SIZE=8192 -CONFIG_TEST_EXTRA_STACKSIZE=4096 -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 -CONFIG_ISR_STACK_SIZE=4096 diff --git a/boards/arm/mps2_an385/pinmux.c b/boards/arm/mps2_an385/pinmux.c index ebe1cc1cb151c7..56a62a856a293a 100644 --- a/boards/arm/mps2_an385/pinmux.c +++ b/boards/arm/mps2_an385/pinmux.c @@ -117,9 +117,9 @@ */ static void arm_mps2_pinmux_defaults(void) { - u32_t gpio_0 = 0U; - u32_t gpio_1 = 0U; - u32_t gpio_2 = 0U; + uint32_t gpio_0 = 0U; + uint32_t gpio_1 = 0U; + uint32_t gpio_2 = 0U; /* Set GPIO Alternate Functions */ @@ -155,7 +155,7 @@ static void arm_mps2_pinmux_defaults(void) CMSDK_AHB_GPIO2_DEV->altfuncset = gpio_2; } -static int arm_mps2_pinmux_init(struct device *port) +static int arm_mps2_pinmux_init(const struct device *port) { ARG_UNUSED(port); diff --git a/boards/arm/mps2_an521/CMakeLists.txt b/boards/arm/mps2_an521/CMakeLists.txt index 39913a0915b816..bd6f7fc4ca4247 100644 --- a/boards/arm/mps2_an521/CMakeLists.txt +++ b/boards/arm/mps2_an521/CMakeLists.txt @@ -18,8 +18,9 @@ if (CONFIG_BUILD_WITH_TFM) set(TFM_IMAGE_VERSION_NS 0.0.0+0) endif() - set(PREPROCESSED_FILE "${CMAKE_BINARY_DIR}/tfm/image_macros_preprocessed") - set(TFM_MCUBOOT_DIR "${ZEPHYR_BASE}/../modules/tee/tfm/trusted-firmware-m/bl2/ext/mcuboot") + set(PREPROCESSED_FILE_S "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.o") + set(PREPROCESSED_FILE_NS "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_ns.dir/signing_layout_ns.o") + set(TFM_MCUBOOT_DIR "${ZEPHYR_TFM_MODULE_DIR}/trusted-firmware-m/bl2/ext/mcuboot") # Configure which format (full or hash) to include the public key in # the image manifest @@ -35,42 +36,42 @@ if (CONFIG_BUILD_WITH_TFM) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands #Sign secure binary image with public key - COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/imgtool.py - ARGS sign - --layout ${PREPROCESSED_FILE}_s.c + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_S} -k ${CONFIG_TFM_KEY_FILE_S} --public-key-format ${TFM_PUBLIC_KEY_FORMAT} --align 1 -v ${TFM_IMAGE_VERSION_S} + --pad + --pad-header ${ADD_NS_IMAGE_MIN_VER} - ${ADD_SECURITY_COUNTER_S} + -s auto -H 0x400 - ${CMAKE_BINARY_DIR}/tfm/install/outputs/AN521/tfm_s.bin + ${CMAKE_BINARY_DIR}/tfm/install/outputs/MPS2/AN521/tfm_s.bin ${CMAKE_BINARY_DIR}/tfm_s_signed.bin #Sign non-secure binary image with public key - COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/imgtool.py - ARGS sign - --layout ${PREPROCESSED_FILE}_ns.c + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_NS} -k ${CONFIG_TFM_KEY_FILE_NS} --public-key-format ${TFM_PUBLIC_KEY_FORMAT} --align 1 -v ${TFM_IMAGE_VERSION_NS} + -s auto ${ADD_S_IMAGE_MIN_VER} - ${ADD_SECURITY_COUNTER_NS} -H 0x400 - ${CMAKE_BINARY_DIR}/zephyr/zephyr.bin + ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} ${CMAKE_BINARY_DIR}/zephyr_ns_signed.bin #Create concatenated binary image from the two independently signed binary file COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/assemble.py - ARGS --layout ${PREPROCESSED_FILE}_s.c + --layout ${PREPROCESSED_FILE_S} -s ${CMAKE_BINARY_DIR}/tfm_s_signed.bin -n ${CMAKE_BINARY_DIR}/zephyr_ns_signed.bin -o ${CMAKE_BINARY_DIR}/tfm_sign.bin #Copy mcuboot.bin - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/mcuboot.bin ${CMAKE_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm/bin/bl2.bin ${CMAKE_BINARY_DIR}/mcuboot.bin #Merge mcuboot.bin and tfm_sign.bin for QEMU COMMAND ${SREC_CAT} diff --git a/boards/arm/mps2_an521/board.cmake b/boards/arm/mps2_an521/board.cmake index a2871264699c5c..7baa879c84c509 100644 --- a/boards/arm/mps2_an521/board.cmake +++ b/boards/arm/mps2_an521/board.cmake @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 set(EMU_PLATFORM qemu) -set(TFM_TARGET_PLATFORM "AN521") set(QEMU_CPU_TYPE_${ARCH} cortex-m33) set(QEMU_FLAGS_${ARCH} @@ -11,8 +10,4 @@ set(QEMU_FLAGS_${ARCH} -m 16 -vga none ) - -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=7,align=off,sleep=off -rtc clock=vm) -endif() board_set_debugger_ifnset(qemu) diff --git a/boards/arm/mps2_an521/mps2_an521_defconfig b/boards/arm/mps2_an521/mps2_an521_defconfig index 1e8408bd7bdab7..9e167b94e4f099 100644 --- a/boards/arm/mps2_an521/mps2_an521_defconfig +++ b/boards/arm/mps2_an521/mps2_an521_defconfig @@ -11,6 +11,7 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_RUNTIME_NMI=y CONFIG_ARM_TRUSTZONE_M=y CONFIG_ARM_MPU=y +CONFIG_QEMU_ICOUNT_SHIFT=7 # GPIOs CONFIG_GPIO=y diff --git a/boards/arm/mps2_an521/mps2_an521_nonsecure.dts b/boards/arm/mps2_an521/mps2_an521_nonsecure.dts index 2cdc8f5c16252f..30ca1f83a167a1 100644 --- a/boards/arm/mps2_an521/mps2_an521_nonsecure.dts +++ b/boards/arm/mps2_an521/mps2_an521_nonsecure.dts @@ -77,8 +77,8 @@ reg = <0x28100000 0x100000>; }; - flash0: flash@100400 { - reg = <0x100400 0xDF00000>; + flash0: flash@100000 { + reg = <0x100000 0xDF00000>; }; soc { diff --git a/boards/arm/mps2_an521/mps2_an521_nonsecure_defconfig b/boards/arm/mps2_an521/mps2_an521_nonsecure_defconfig index 1ebb6f99fff6c8..691eea92e1219b 100644 --- a/boards/arm/mps2_an521/mps2_an521_nonsecure_defconfig +++ b/boards/arm/mps2_an521/mps2_an521_nonsecure_defconfig @@ -12,6 +12,7 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_RUNTIME_NMI=y CONFIG_TRUSTED_EXECUTION_NONSECURE=y CONFIG_ARM_MPU=y +CONFIG_QEMU_ICOUNT_SHIFT=7 # GPIOs CONFIG_GPIO=y diff --git a/boards/arm/mps2_an521/pinmux.c b/boards/arm/mps2_an521/pinmux.c index ebc279745699ea..5bd038bd211707 100644 --- a/boards/arm/mps2_an521/pinmux.c +++ b/boards/arm/mps2_an521/pinmux.c @@ -117,9 +117,9 @@ */ static void arm_mps2_pinmux_defaults(void) { - u32_t gpio_0 = 0; - u32_t gpio_1 = 0; - u32_t gpio_2 = 0; + uint32_t gpio_0 = 0; + uint32_t gpio_1 = 0; + uint32_t gpio_2 = 0; /* Set GPIO Alternate Functions */ @@ -155,7 +155,7 @@ static void arm_mps2_pinmux_defaults(void) CMSDK_AHB_GPIO2_DEV->altfuncset = gpio_2; } -static int arm_mps2_pinmux_init(struct device *port) +static int arm_mps2_pinmux_init(const struct device *port) { ARG_UNUSED(port); diff --git a/boards/arm/npcx7m6fb_evb/CMakeLists.txt b/boards/arm/npcx7m6fb_evb/CMakeLists.txt new file mode 100644 index 00000000000000..b3336ce2764d40 --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# Copyright (c) 2020 Nuvoton Technology Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# find ECST tool for generating npcx header used by ROM code + +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${BOARD_DIR}/support/ecst.py + -i ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin + -o ${TARGET_IMAGE_FILE} -nohcrc -nofcrc + -chip npcx7m6 -flashsize 8 -spimaxclk 50 -spireadmode dual +) diff --git a/boards/arm/npcx7m6fb_evb/Kconfig.board b/boards/arm/npcx7m6fb_evb/Kconfig.board new file mode 100644 index 00000000000000..84b39c5a9ae6c9 --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2020 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NPCX7M6FB_EVB + bool "Nuvoton NPCX7M6FB EVB Development board" + depends on SOC_NPCX7M6FB diff --git a/boards/arm/npcx7m6fb_evb/Kconfig.defconfig b/boards/arm/npcx7m6fb_evb/Kconfig.defconfig new file mode 100644 index 00000000000000..fed7b694229ac1 --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2020 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NPCX7M6FB_EVB + +config BOARD + default "npcx7m6fb_evb" + +endif # BOARD_NPCX7M6FB_EVB + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 diff --git a/boards/arm/npcx7m6fb_evb/board.cmake b/boards/arm/npcx7m6fb_evb/board.cmake new file mode 100644 index 00000000000000..e5030013405cd7 --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/board.cmake @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(TARGET_IMAGE_FILE ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}_${BOARD}.bin) + +set(TARGET_IMAGE_ADDR ${CONFIG_FLASH_BASE_ADDRESS}) +set(TARGET_IMAGE_SIZE ${CONFIG_FLASH_SIZE}) + +board_set_flasher_ifnset(openocd) +board_set_debugger_ifnset(openocd) + +board_finalize_runner_args(openocd + --cmd-load "flash_npcx ${MONITOR_IMAGE_FILE} ${TARGET_IMAGE_FILE} ${TARGET_IMAGE_ADDR} ${TARGET_IMAGE_SIZE}" + --cmd-verify "verify_npcx" + ) diff --git a/boards/arm/npcx7m6fb_evb/doc/index.rst b/boards/arm/npcx7m6fb_evb/doc/index.rst new file mode 100644 index 00000000000000..cf8617dea6e20a --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/doc/index.rst @@ -0,0 +1,98 @@ +.. _npcx7m6fb_evb: + +NPCX7M6FB_EVB +################### + +Overview +******** + +The NPCX7M6FB_EVB kit is a development platform to evaluate the +Nuvoton NPCX7 series microcontrollers. This board needs to be mated with +part number NPCX796FB. + +.. image:: ./npcx7m6fb_evb.png + :width: 800px + :align: center + :alt: NPCX7M6FB Evaluation Board + +Hardware +******** + +- ARM Cortex-M4F Processor +- 256 KB RAM and 64 KB boot ROM +- ADC & GPIO headers +- UART0 and UART1 +- FAN PWM interface +- Jtag interface +- Intel Modular Embedded Controller Card (MECC) headers + +Supported Features +================== + +The following features are supported: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ + +Other hardware features are not currently supported by Zephyr (at the moment) + +The default configuration can be found in the defconfig file: +``boards/arm/npcx7m6fb_evb/npcx7m6fb_evb_defconfig`` + + +Connections and IOs +=================== + +Nuvoton to provide the schematic for this board. + +System Clock +============ + +The NPCX7M6FB MCU is configured to use the 90Mhz internal oscillator with the +on-chip PLL to generate a resulting EC clock rate of 15 MHz. See Processor clock +control register (chapter 4 in user manual) + +Serial Port +=========== + +UART1 is configured for serial logs. + + +Programming and Debugging +************************* + +This board comes with a Cortex ETM port which facilitates tracing and debugging +using a single physical connection. In addition, it comes with sockets for +JTAG only sessions. + +Flashing +======== + +Build application as usual for the ``npcx7m6fb_evb`` board, and flash +using Servo V2, μServo, or Servo V4 (CCD). See the +`Chromium EC Flashing Documentation`_ for more information. + + +Debugging +========= + +Use JTAG/SWD with a J-Link + +References +********** +.. target-notes:: + +.. _Chromium EC Flashing Documentation: + https://chromium.googlesource.com/chromiumos/platform/ec#Flashing-via-the-servo-debug-board diff --git a/boards/arm/npcx7m6fb_evb/doc/npcx7m6fb_evb.png b/boards/arm/npcx7m6fb_evb/doc/npcx7m6fb_evb.png new file mode 100644 index 00000000000000..ede49b20aaa25d Binary files /dev/null and b/boards/arm/npcx7m6fb_evb/doc/npcx7m6fb_evb.png differ diff --git a/boards/arm/npcx7m6fb_evb/npcx7m6fb_evb.dts b/boards/arm/npcx7m6fb_evb/npcx7m6fb_evb.dts new file mode 100644 index 00000000000000..0442a96d89d575 --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/npcx7m6fb_evb.dts @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "Nuvoton NPCX7M6FB evaluation board"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart1; + zephyr,flash = &flash0; + }; + + aliases { + /* For samples/basic/blinky_pwm */ + pwm-led0 = &pwm_led0_green; + /* For pwm test suites */ + pwm-0 = &pwm6; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0_green: pwm_led_0 { + pwms = <&pwm6 0 PWM_POLARITY_INVERTED>; + label = "User D7 green"; + }; + }; +}; + +/* Overwirte default device properties with overlays in board dt file here. */ +&uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&altc_uart1_sl2>; /* Use UART1_SL2 ie. PIN64.65 */ +}; + +&pwm6 { + status = "okay"; +}; + +&adc0 { + /* ADC pinmux is changed only if related channel is configured. */ + status = "okay"; +}; + +&espi0 { + status = "okay"; +}; diff --git a/boards/arm/npcx7m6fb_evb/npcx7m6fb_evb.yaml b/boards/arm/npcx7m6fb_evb/npcx7m6fb_evb.yaml new file mode 100644 index 00000000000000..c6e34655361166 --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/npcx7m6fb_evb.yaml @@ -0,0 +1,17 @@ +# +# Copyright (c) 2020 Nuvoton Technology Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: npcx7m6fb_evb +name: Nuvoton NPCX7M6FB EVB +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 64 +flash: 192 +supported: + - adc diff --git a/boards/arm/npcx7m6fb_evb/npcx7m6fb_evb_defconfig b/boards/arm/npcx7m6fb_evb/npcx7m6fb_evb_defconfig new file mode 100644 index 00000000000000..28dc513e34412a --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/npcx7m6fb_evb_defconfig @@ -0,0 +1,48 @@ +# +# Copyright (c) 2020 Nuvoton Technology Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_NPCX7M6FB=y +CONFIG_SOC_SERIES_NPCX7=y +CONFIG_BOARD_NPCX7M6FB_EVB=y +CONFIG_CORTEX_M_SYSTICK=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# General Kernel Options +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=15000000 + +# Clock configuration +CONFIG_CLOCK_CONTROL=y + +# PLL configuration +CONFIG_CLOCK_NPCX_OSC_CYCLES_PER_SEC=90000000 +CONFIG_CLOCK_NPCX_APB1_PRESCALER=6 +CONFIG_CLOCK_NPCX_APB2_PRESCALER=6 +CONFIG_CLOCK_NPCX_APB3_PRESCALER=6 + +# Pinmux Driver +CONFIG_PINMUX=y + +# UART Driver +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# GPIO Driver +CONFIG_GPIO=y + +# PWM Driver +CONFIG_PWM=y + +# ADC Driver +CONFIG_ADC=y + +# ESPI Driver +CONFIG_ESPI=y + +# Console Driver +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/npcx7m6fb_evb/support/ecst.py b/boards/arm/npcx7m6fb_evb/support/ecst.py new file mode 100755 index 00000000000000..33c2fe1c401bfa --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/support/ecst.py @@ -0,0 +1,1004 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2020 Nuvoton Technology Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +# This script will append/paste specific header to tell ROM code (Booter) of +# NPCX EC series how to load the firmware from flash to code ram +# Usage python3 ${ZEPHYR_BASE}/scripts/ecst.py +# -i in_file.bin -o out_file.bin +# [-chip ] [-v|-vv] +# [-nohcrc] [-nofcrc] [-ph ] +# [-flashsize <1|2|4|8|16>] +# [-spimaxclk <20|25|33|40|50>] +# [-spireadmode ] + +import sys +from colorama import init, Fore +from ecst_args import EcstArgs, exit_with_failure +from pathlib import Path + +# ECST Version +ECST_VER = "2.0.1" + +# Offsets inside the header +HDR_ANCHOR_OFFSET = 0 +HDR_EXTENDED_ANCHOR_OFFSET = 4 +HDR_SPI_MAX_CLK_OFFSET = 6 +HDR_SPI_READ_MODE_OFFSET = 7 +HDR_ERR_DETECTION_CONF_OFFSET = 8 +HDR_FW_LOAD_START_ADDR_OFFSET = 9 +HDR_FW_ENTRY_POINT_OFFSET = 13 +HDR_FW_ERR_DETECT_START_ADDR_OFFSET = 17 +HDR_FW_ERR_DETECT_END_ADDR_OFFSET = 21 +HDR_FW_LENGTH_OFFSET = 25 +HDR_FLASH_SIZE_OFFSET = 29 +OTP_WRITE_PROTECT_OFFSET = 30 +KEY_VALID_OFFSET = 31 +FIRMWARE_VALID_OFFSET = 32 +RESERVED_BYTES_OFFSET = 33 +HDR_FW_HEADER_SIG_OFFSET = 56 +HDR_FW_IMAGE_SIG_OFFSET = 60 +FW_IMAGE_OFFSET = 64 + +SIGNATURE_OFFSET = 0 +POINTER_OFFSET = 4 +ARM_FW_ENTRY_POINT_OFFSET = 4 + +# Header field known values +FW_HDR_ANCHOR = 0x2A3B4D5E +FW_HDR_EXT_ANCHOR_ENABLE = 0xAB1E +FW_HDR_EXT_ANCHOR_DISABLE = 0x54E1 +FW_HDR_CRC_DISABLE = 0x00 +FW_HDR_CRC_ENABLE = 0x02 +FW_CRC_DISABLE = 0x00 +FW_CRC_ENABLE = 0x02 +HDR_PTR_SIGNATURE = 0x55AA650E + +BOOTLOADER_TABLE_MODE = "bt" + +# SPI related values +SPI_MAX_CLOCK_20_MHZ_VAL = "20" +SPI_MAX_CLOCK_25_MHZ_VAL = "25" +SPI_MAX_CLOCK_33_MHZ_VAL = "33" +SPI_MAX_CLOCK_40_MHZ_VAL = "40" +SPI_MAX_CLOCK_50_MHZ_VAL = "50" + +SPI_MAX_CLOCK_20_MHZ = 0x00 +SPI_MAX_CLOCK_25_MHZ = 0x01 +SPI_MAX_CLOCK_33_MHZ = 0x02 +SPI_MAX_CLOCK_40_MHZ = 0x03 +SPI_MAX_CLOCK_50_MHZ = 0x04 + +SPI_CLOCK_RATIO_1_VAL = 1 +SPI_CLOCK_RATIO_2_VAL = 2 + +SPI_CLOCK_RATIO_1 = 0x00 +SPI_CLOCK_RATIO_2 = 0x08 + +SPI_NORMAL_MODE_VAL = 'normal' +SPI_SINGLE_MODE_VAL = 'fast' +SPI_DUAL_MODE_VAL = 'dual' +SPI_QUAD_MODE_VAL = 'quad' + +SPI_NORMAL_MODE = 0x00 +SPI_SINGLE_MODE = 0x01 +SPI_DUAL_MODE = 0x03 +SPI_QUAD_MODE = 0x04 + +# Flash related values +FLASH_SIZE_1_MBYTES_VAL = "1" +FLASH_SIZE_2_MBYTES_VAL = "2" +FLASH_SIZE_4_MBYTES_VAL = "4" +FLASH_SIZE_8_MBYTES_VAL = "8" +FLASH_SIZE_16_MBYTES_VAL = "16" + +FLASH_SIZE_1_MBYTES = 0x01 +FLASH_SIZE_2_MBYTES = 0x03 +FLASH_SIZE_4_MBYTES = 0x07 +FLASH_SIZE_8_MBYTES = 0x0f +FLASH_SIZE_8_MBYTES = 0x0f +FLASH_SIZE_16_MBYTES = 0x1f + +MAX_FLASH_SIZE = 0x03ffffff + +# Header fields default values. +ADDR_16_BYTES_ALIGNED_MASK = 0x0000000f +ADDR_4_BYTES_ALIGNED_MASK = 0x00000003 +ADDR_4K_BYTES_ALIGNED_MASK = 0x00000fff + +NUM_OF_BYTES = 32 +INVALID_INPUT = -1 +HEADER_SIZE = 64 +PAD_BYTE = b'\x00' +BYTES_TO_PAD = HDR_FW_HEADER_SIG_OFFSET - RESERVED_BYTES_OFFSET + +# Verbose related values +NO_VERBOSE = 0 +REG_VERBOSE = 1 +SUPER_VERBOSE = 1 + +# Success/failure codes +EXIT_SUCCESS_STATUS = 0 +EXIT_FAILURE_STATUS = 1 + +def _bt_mode_handler(ecst_args): + """creates the bootloader table using the provided arguments. + + :param ecst_args: the object representing the command line arguments. + """ + + output_file = _set_input_and_output(ecst_args) + _check_chip(output_file, ecst_args) + + if ecst_args.paste_firmware_header != 0: + _check_firmware_header_offset(output_file, ecst_args) + + _copy_image(output_file, ecst_args) + _set_anchor(output_file, ecst_args) + _set_extended_anchor(output_file, ecst_args) + _set_spi_flash_maximum_clock(output_file, ecst_args) + _set_spi_flash_mode(output_file, ecst_args) + _set_error_detection_configuration(output_file, ecst_args) + _set_firmware_load_start_address(output_file, ecst_args) + _set_firmware_entry_point(output_file, ecst_args) + _set_firmware_crc_start_and_size(output_file, ecst_args) + _set_firmware_length(output_file, ecst_args) + _set_flash_size(output_file, ecst_args) + _set_reserved_bytes(output_file, ecst_args) + _set_firmware_header_crc_signature(output_file, ecst_args) + _set_firmware_image_crc_signature(output_file, ecst_args) + + _exit_with_success() + +def _set_input_and_output(ecst_args): + """checks the input file and output and sets the output file. + + checks input file existence, creates an output file according + to the 'output' argument. + + Note: input file size has to be greater than 0, and named differently + from output file + + :param ecst_args: the object representing the command line arguments. + + :returns: output file path object, or -1 if fails + """ + input_file = ecst_args.input + output = ecst_args.output + input_file_size = 0 + + if not input_file: + exit_with_failure("Define input file, using -i flag") + + input_file_path = Path(input_file) + + if not input_file_path.exists(): + exit_with_failure(f'Cannot open {input_file}') + elif input_file_path.stat().st_size == 0: + exit_with_failure(f'BIN Input file ({input_file}) is empty') + else: + input_file_size = input_file_path.stat().st_size + + if not output: + output_file = Path("out_" + input_file_path.name) + else: + output_file = Path(output) + + if output_file.exists(): + if output_file.samefile(input_file_path): + exit_with_failure(f'Input file name {input_file} ' + f'should be differed from' + f' Output file name {output}') + output_file.unlink() + + output_file.touch() + + if ecst_args.verbose == REG_VERBOSE: + print(Fore.LIGHTCYAN_EX + f'\nBIN file: {input_file}, size:' + f' {input_file_size} bytes') + print(f'Output file name: {output_file.name} \n') + + return output_file + +def _check_chip(output, ecst_args): + """checks if the chip entered is a legal chip, generates an error + and closes the application, deletes the output file if the chip name + is illegal. + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + + if ecst_args.chip_name == INVALID_INPUT: + message = f'Invalid chip name, ' + message += "should be npcx9m8, npcx9m7, npcx9m6, npcx7m7," \ + " npcx7m6, npcx7m5, npcx5m5 or npcx5m6." + _exit_with_failure_delete_file(output, message) + +def _set_anchor(output, ecst_args): + """writes the anchor value to the output file + + :param output: the output file object. + :param ecst_args: the object representing the command line arguments. + """ + + with output.open("r+b") as output_file: + output_file.seek(HDR_ANCHOR_OFFSET + ecst_args.paste_firmware_header) + output_file.write(FW_HDR_ANCHOR.to_bytes(4, "little")) + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - FW Header ANCHOR - Offset ' + f'{HDR_ANCHOR_OFFSET} - {_hex_print_format(FW_HDR_ANCHOR)}') + + output_file.close() + +def _set_extended_anchor(output, ecst_args): + """writes the extended anchor value to the output file + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + + with output.open("r+b") as output_file: + output_file.seek(HDR_EXTENDED_ANCHOR_OFFSET + \ + ecst_args.paste_firmware_header) + if ecst_args.firmware_header_crc is FW_HDR_CRC_ENABLE: + output_file.write(FW_HDR_EXT_ANCHOR_ENABLE.to_bytes(2, "little")) + anchor_to_print = _hex_print_format(FW_HDR_EXT_ANCHOR_ENABLE) + else: + output_file.write(FW_HDR_EXT_ANCHOR_DISABLE.to_bytes(2, "little")) + anchor_to_print = _hex_print_format(FW_HDR_EXT_ANCHOR_DISABLE) + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - Header EXTENDED ANCHOR - Offset' + f' {HDR_EXTENDED_ANCHOR_OFFSET} - {anchor_to_print}') + output_file.close() + + +def _check_firmware_header_offset(output, ecst_args): + """checks if the firmware header offset entered is valid. + proportions: + + firmware header offset is a non-negative integer. + firmware header offset is 16 bytes aligned + firmware header offset equals/smaller than input file minus + FW HEADER SIZE (64 KB) + input file size is bigger than FW HEADER SIZE (64 KB) + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + + input_file = Path(ecst_args.input) + paste_fw_offset = ecst_args.paste_firmware_header + input_file_size = input_file.stat().st_size + + if paste_fw_offset == INVALID_INPUT: + _exit_with_failure_delete_file(output, "Cannot read paste" + " firmware offset") + + paste_fw_offset_to_print = _hex_print_format(paste_fw_offset) + + if paste_fw_offset & ADDR_16_BYTES_ALIGNED_MASK != 0: + message = f'Paste firmware address ({paste_fw_offset_to_print}) ' \ + f'is not 16 bytes aligned' + _exit_with_failure_delete_file(output, message) + + if input_file_size <= HEADER_SIZE: + message = f' input file size ({input_file_size} bytes) ' \ + f'should be bigger than fw header size ({HEADER_SIZE} bytes)' + _exit_with_failure_delete_file(output, message) + + if input_file_size - HEADER_SIZE < paste_fw_offset: + message = f'FW offset ({paste_fw_offset_to_print})should be less ' \ + f'than input file size ({input_file_size}) minus fw header size' \ + f' {HEADER_SIZE}' + _exit_with_failure_delete_file(output, message) + +def _set_spi_flash_maximum_clock(output, ecst_args): + """Sets the maximum allowable clock frequency (for firmware loading); + also sets the ratio between the Core clock + and the SPI clock for the specified mode. + writes the data into the output file. + the application is closed, and an error is generated + if the fields are not valid. + + Bits 2-0 - SPI MAX Clock + Bit 3: SPI Clock Ratio + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + spi_max_clock_to_write = 0 + + with output.open("r+b") as output_file: + output_file.seek(HDR_SPI_MAX_CLK_OFFSET + + ecst_args.paste_firmware_header) + spi_max_clock = ecst_args.spi_flash_maximum_clock + spi_clock_ratio = ecst_args.spi_flash_clock_ratio + + if spi_clock_ratio == SPI_CLOCK_RATIO_1_VAL: + spi_clock_ratio = SPI_CLOCK_RATIO_1 + elif spi_clock_ratio == SPI_CLOCK_RATIO_2_VAL: + spi_clock_ratio = SPI_CLOCK_RATIO_2 + elif spi_clock_ratio == INVALID_INPUT: + message = f'Cannot read SPI Clock Ratio' + output_file.close() + _exit_with_failure_delete_file(output, message) + else: + message = f'Invalid SPI Core Clock Ratio (3) - it should be 1 or 2' + output_file.close() + _exit_with_failure_delete_file(output, message) + + if spi_max_clock == SPI_MAX_CLOCK_20_MHZ_VAL: + spi_max_clock_to_write = SPI_MAX_CLOCK_20_MHZ | spi_clock_ratio + output_file.write(spi_max_clock_to_write.to_bytes(1, "little")) + + elif spi_max_clock == SPI_MAX_CLOCK_25_MHZ_VAL: + spi_max_clock_to_write = SPI_MAX_CLOCK_25_MHZ | spi_clock_ratio + output_file.write(spi_max_clock_to_write.to_bytes(1, "little")) + + elif spi_max_clock == SPI_MAX_CLOCK_33_MHZ_VAL: + spi_max_clock_to_write = SPI_MAX_CLOCK_33_MHZ | spi_clock_ratio + output_file.write(spi_max_clock_to_write.to_bytes(1, "little")) + + elif spi_max_clock == SPI_MAX_CLOCK_40_MHZ_VAL: + spi_max_clock_to_write = SPI_MAX_CLOCK_40_MHZ | spi_clock_ratio + output_file.write(spi_max_clock_to_write.to_bytes(1, "little")) + + elif spi_max_clock == SPI_MAX_CLOCK_50_MHZ_VAL: + spi_max_clock_to_write = SPI_MAX_CLOCK_50_MHZ | spi_clock_ratio + output_file.write(spi_max_clock_to_write.to_bytes(1, "little")) + + elif not str(spi_max_clock).isdigit(): + output_file.close() + _exit_with_failure_delete_file(output, + "Cannot read SPI Flash Max Clock") + else: + message = f'Invalid SPI Flash MAX Clock size ({spi_max_clock}) ' + message += '- it should be 20, 25, 33, 40 or 50 MHz' + output_file.close() + _exit_with_failure_delete_file(output, message) + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - SPI flash MAX Clock - Offset ' + f'{HDR_SPI_MAX_CLK_OFFSET} - ' + f'{_hex_print_format(spi_max_clock_to_write)}') + output_file.close() + +def _set_spi_flash_mode(output, ecst_args): + """Sets the read mode used for firmware loading and enables + the Unlimited Burst functionality. + writes the data into the output file. + the application is closed, and an error is generated + if the fields are not valid. + + Bits 2-0 - SPI Flash Read Mode + Bit 3: Unlimited Burst Mode + + Note: unlimburst is not relevant for npcx5mn chips family. + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + + spi_flash_read_mode = ecst_args.spi_flash_read_mode + spi_unlimited_burst_mode = ecst_args.unlimited_burst_mode + spi_read_mode_to_write = 0 + + with output.open("r+b") as output_file: + output_file.seek(HDR_SPI_READ_MODE_OFFSET + + ecst_args.paste_firmware_header) + if spi_flash_read_mode == SPI_NORMAL_MODE_VAL: + spi_read_mode_to_write = SPI_NORMAL_MODE | spi_unlimited_burst_mode + output_file.write(spi_read_mode_to_write.to_bytes(1, "little")) + elif spi_flash_read_mode == SPI_SINGLE_MODE_VAL: + spi_read_mode_to_write = SPI_SINGLE_MODE | spi_unlimited_burst_mode + output_file.write(spi_read_mode_to_write.to_bytes(1, "little")) + elif spi_flash_read_mode == SPI_DUAL_MODE_VAL: + spi_read_mode_to_write = SPI_DUAL_MODE | spi_unlimited_burst_mode + output_file.write(spi_read_mode_to_write.to_bytes(1, "little")) + elif spi_flash_read_mode == SPI_QUAD_MODE_VAL: + spi_read_mode_to_write = SPI_QUAD_MODE | spi_unlimited_burst_mode + output_file.write(spi_read_mode_to_write.to_bytes(1, "little")) + else: + message = f'Invalid SPI Flash Read Mode ({spi_flash_read_mode}),' + message += 'it should be normal, fast, dual, quad' + output_file.close() + _exit_with_failure_delete_file(output, message) + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - SPI flash Read Mode - Offset ' + f'{HDR_SPI_READ_MODE_OFFSET} - ' + f'{_hex_print_format(spi_read_mode_to_write)}') + + output_file.close() + +def _set_error_detection_configuration(output, ecst_args): + """writes the error detection configuration value (enabled/disabled) + to the output file + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + with output.open("r+b") as output_file: + output_file.seek(HDR_ERR_DETECTION_CONF_OFFSET + + ecst_args.paste_firmware_header) + if ecst_args.firmware_crc == FW_CRC_ENABLE: + err_detect_config_to_print = _hex_print_format(FW_CRC_ENABLE) + output_file.write(FW_CRC_ENABLE.to_bytes(1, "little")) + else: + err_detect_config_to_print = _hex_print_format(FW_CRC_DISABLE) + output_file.write(FW_CRC_DISABLE.to_bytes(1, "little")) + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - FW CRC Enabled - Offset ' + f'{HDR_ERR_DETECTION_CONF_OFFSET} - ' + f'{err_detect_config_to_print}') + + output_file.close() + +def _set_firmware_load_start_address(output, ecst_args): + """writes the fw load address to the output file + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + start_ram = ecst_args.chip_ram_address + end_ram = start_ram + ecst_args.chip_ram_size + fw_load_addr = ecst_args.firmware_load_address + fw_length = ecst_args.firmware_length + fw_end_addr = fw_load_addr + fw_length + + start_ram_to_print = _hex_print_format(start_ram) + end_ram_to_print = _hex_print_format(end_ram) + fw_load_addr_to_print = _hex_print_format(fw_load_addr) + fw_length_to_print = _hex_print_format(fw_length) + fw_end_addr_to_print = _hex_print_format(fw_end_addr) + + if fw_length == INVALID_INPUT: + message = f'Cannot read firmware length' + _exit_with_failure_delete_file(output, message) + + if fw_length & ADDR_16_BYTES_ALIGNED_MASK != 0: + message = f'Firmware length ({fw_length_to_print}) ' \ + f'is not 16 bytes aligned' + _exit_with_failure_delete_file(output, message) + + if fw_load_addr is INVALID_INPUT: + message = f'Cannot read FW Load start address' + _exit_with_failure_delete_file(output, message) + + if fw_load_addr & ADDR_16_BYTES_ALIGNED_MASK != 0: + message = f'Firmware load address ({fw_load_addr_to_print}) ' \ + f'is not 16 bytes aligned' + _exit_with_failure_delete_file(output, message) + + if (fw_load_addr > end_ram) or (fw_load_addr < start_ram): + message = f'Firmware load address ({fw_load_addr_to_print}) ' \ + f'should be between start ({start_ram_to_print}) '\ + f'and end ({end_ram_to_print}) of RAM' + _exit_with_failure_delete_file(output, message) + + if fw_end_addr > end_ram: + message = f'Firmware end address ({fw_end_addr_to_print}) should be ' + message += f'less than end of RAM address ({end_ram_to_print})' + _exit_with_failure_delete_file(output, message) + + with output.open("r+b") as output_file: + output_file.seek(HDR_FW_LOAD_START_ADDR_OFFSET + + ecst_args.paste_firmware_header) + output_file.write(ecst_args.firmware_load_address. + to_bytes(4, "little")) + + output_file.seek(HDR_FW_LENGTH_OFFSET + + ecst_args.paste_firmware_header) + output_file.write(fw_length.to_bytes(4, "little")) + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - FW load start address - Offset ' + f'{HDR_FW_LOAD_START_ADDR_OFFSET} - ' + f'{fw_load_addr_to_print}') + output_file.close() + +def _set_firmware_entry_point(output, ecst_args): + """writes the fw entry point to the output file. + proportions: + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + entry_pt_none = False + input_file_path = Path(ecst_args.input) + fw_entry_pt = ecst_args.firmware_entry_point + fw_use_arm_reset = ecst_args.use_arm_reset + fw_length = ecst_args.firmware_length + fw_load_addr = ecst_args.firmware_load_address + fw_end_addr = fw_load_addr + fw_length + + # check if fwep flag wasn't set and set it to fw load address if needed + if fw_entry_pt is None: + entry_pt_none = True + fw_entry_pt = ecst_args.firmware_load_address + + if not entry_pt_none and fw_use_arm_reset: + message = f'-usearmrst not allowed, FW entry point already set using '\ + f'-fwep !' + _exit_with_failure_delete_file(output, message) + + with input_file_path.open("r+b") as input_file: + with output.open("r+b") as output_file: + if fw_use_arm_reset: + input_file.seek(ARM_FW_ENTRY_POINT_OFFSET + + ecst_args.paste_firmware_header) + fw_entry_byte = input_file.read(4) + fw_entry_pt = int.from_bytes(fw_entry_byte, "little") + + if fw_entry_pt < fw_load_addr or fw_entry_pt > fw_end_addr: + output_file.close() + input_file.close() + message = f'Firmware entry point ' \ + f'({_hex_print_format(fw_entry_pt)}) ' \ + f'should be between the FW load address ' \ + f'({_hex_print_format(fw_load_addr)})' \ + f' and FW end address ({_hex_print_format(fw_end_addr)})' + + _exit_with_failure_delete_file(output, message) + + output_file.seek(HDR_FW_ENTRY_POINT_OFFSET + + ecst_args.paste_firmware_header) + output_file.write(fw_entry_pt.to_bytes(4, "little")) + output_file.close() + input_file.close() + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - FW Entry point - Offset ' + f'{HDR_FW_ENTRY_POINT_OFFSET} - ' + f'{_hex_print_format(fw_entry_pt)}') + +def _set_firmware_crc_start_and_size(output, ecst_args): + """writes the fw crc start address and the crc size to the output file. + proportions: + --crc start address should be 4 byte aligned, bigger than crc end address + --crc size should be 4 byte aligned, and be set to firmware length minus + crc start offset by default + --crc end address is crc start address + crc size bytes + + the application is closed, and an error is generated if the mentioned + fields not comply with the proportions. + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + fw_crc_size = ecst_args.firmware_crc_size + fw_crc_start = ecst_args.firmware_crc_start + + if fw_crc_size is None: + fw_crc_end = ecst_args.firmware_length - 1 + # default value for crc size + fw_crc_size = ecst_args.firmware_length - fw_crc_start + ecst_args.firmware_crc_size = fw_crc_size + else: + fw_crc_end = fw_crc_start + fw_crc_size - 1 + + fw_crc_start_to_print = _hex_print_format(fw_crc_start) + fw_crc_end_to_print = _hex_print_format(fw_crc_end) + fw_length_to_print = _hex_print_format(ecst_args.firmware_length) + fw_crc_size_to_print = _hex_print_format(fw_crc_size) + + if fw_crc_start & ADDR_4_BYTES_ALIGNED_MASK != 0: + message = f'Firmware crc offset address ' \ + f'({fw_crc_start_to_print}) is not 4 bytes aligned' + _exit_with_failure_delete_file(output, message) + + if fw_crc_start > fw_crc_end: + message = f'CRC start address ({fw_crc_start_to_print}) should' \ + f' be less or equal to CRC end address ({fw_crc_end_to_print}) \n' + _exit_with_failure_delete_file(output, message) + + if fw_crc_size & ADDR_4_BYTES_ALIGNED_MASK != 0: + message = f'Firmware crc size ({fw_crc_size_to_print}) ' \ + f'is not 4 bytes aligned' + _exit_with_failure_delete_file(output, message) + + if fw_crc_end > ecst_args.firmware_length - 1: + message = f'CRC end address ({fw_crc_end_to_print}) should be less' \ + f' than the FW length ({fw_length_to_print}) \n' + _exit_with_failure_delete_file(output, message) + + with output.open("r+b") as output_file: + output_file.seek(HDR_FW_ERR_DETECT_START_ADDR_OFFSET + + ecst_args.paste_firmware_header) + output_file.write(fw_crc_start.to_bytes(4, "little")) + + output_file.seek(HDR_FW_ERR_DETECT_END_ADDR_OFFSET + + ecst_args.paste_firmware_header) + output_file.write(fw_crc_end.to_bytes(4, "little")) + output_file.close() + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - FW CRC Start - Offset ' + f'{HDR_FW_ERR_DETECT_START_ADDR_OFFSET} - ' + f'{fw_crc_start_to_print}') + + print(f'- HDR - FW CRC End - Offset ' + f'{HDR_FW_ERR_DETECT_END_ADDR_OFFSET} - ' + f'{fw_crc_end_to_print}') + +def _set_firmware_length(output, ecst_args): + """writes the flash size value to the output file + Note: the firmware length value has already been checked before + this method + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + + fw_length = ecst_args.firmware_length + fw_length_to_print = _hex_print_format(fw_length) + + with output.open("r+b") as output_file: + output_file.seek(HDR_FW_LENGTH_OFFSET + + ecst_args.paste_firmware_header) + output_file.write(fw_length.to_bytes(4, "little")) + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - FW Length - Offset ' + f'{HDR_FW_LENGTH_OFFSET} - ' + f'{fw_length_to_print}') + output_file.close() + +def _set_flash_size(output, ecst_args): + """writes the flash size value to the output file + valid values are 1,2,4,8 or 16 (default is 16). + the application is closed and the output file is deleted + if the flash size is invalid + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + flash_size_to_print = "" + + with output.open("r+b") as output_file: + output_file.seek(HDR_FLASH_SIZE_OFFSET + + ecst_args.paste_firmware_header) + flash_size = ecst_args.flash_size + + if flash_size == FLASH_SIZE_1_MBYTES_VAL: + output_file.write(FLASH_SIZE_1_MBYTES.to_bytes(4, "little")) + flash_size_to_print = _hex_print_format(FLASH_SIZE_1_MBYTES) + elif flash_size == FLASH_SIZE_2_MBYTES_VAL: + output_file.write(FLASH_SIZE_2_MBYTES.to_bytes(4, "little")) + flash_size_to_print = _hex_print_format(FLASH_SIZE_2_MBYTES) + elif flash_size == FLASH_SIZE_4_MBYTES_VAL: + output_file.write(FLASH_SIZE_4_MBYTES.to_bytes(4, "little")) + flash_size_to_print = _hex_print_format(FLASH_SIZE_4_MBYTES) + elif flash_size == FLASH_SIZE_8_MBYTES_VAL: + output_file.write(FLASH_SIZE_8_MBYTES.to_bytes(4, "little")) + flash_size_to_print = _hex_print_format(FLASH_SIZE_8_MBYTES) + elif flash_size == FLASH_SIZE_16_MBYTES_VAL: + output_file.write(FLASH_SIZE_16_MBYTES.to_bytes(4, "little")) + flash_size_to_print = _hex_print_format(FLASH_SIZE_16_MBYTES) + elif not flash_size.isdigit(): + output_file.close() + _exit_with_failure_delete_file(output, "Cannot read Flash size") + else: + message = f'Invalid flash size ({flash_size} MBytes), ' \ + f' it should be 0.5, 1, 2, 4, 8, 16 MBytes \n' \ + f' please note - for 0.5 MBytes flash, enter \'1\' ' + output_file.close() + _exit_with_failure_delete_file(output, message) + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - Flash size - Offset ' + f'{HDR_FLASH_SIZE_OFFSET} - ' + f' {flash_size_to_print}') + output_file.close() + +def _set_reserved_bytes(output, ecst_args): + """fills the reserved part of the image at the relevant offset + with the PAD_BYTE + + :param output: the output file object + :param ecst_args: the object representing the command line arguments. + """ + with output.open("r+b") as output_file: + for i in range(BYTES_TO_PAD): + output_file.seek(RESERVED_BYTES_OFFSET + + ecst_args.paste_firmware_header + i) + output_file.write(PAD_BYTE) + output_file.close() + +def _set_firmware_header_crc_signature(output, ecst_args): + """writes the firmware header crc signature (4 bytes) + to the output file + + :param output: the output file object + :param ecst_args: the object representing the command line arguments. + """ + crc_to_print = _hex_print_format(0) + + # calculating crc only if the header crc check is enabled + if ecst_args.firmware_header_crc != FW_HDR_CRC_DISABLE: + + with output.open("r+b") as output_file: + crc_calc = 0xffffffff + table = _create_table() + + for i in range(HDR_FW_HEADER_SIG_OFFSET): + output_file.seek(ecst_args.paste_firmware_header + i) + current = output_file.read(1) + crc_calc = _crc_update( + int.from_bytes(current, "little"), crc_calc, table) + + crc = _finalize_crc(crc_calc) + crc_to_write = crc.to_bytes(4, "little") + crc_to_print = _hex_print_format(crc) + output_file.seek(ecst_args.paste_firmware_header + + HDR_FW_HEADER_SIG_OFFSET) + output_file.write(crc_to_write) + + output_file.close() + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - Header CRC - Offset ' + f'{HDR_FW_HEADER_SIG_OFFSET} - ' + f' {crc_to_print}') + +def _set_firmware_image_crc_signature(output, ecst_args): + """writes the firmware image crc signature (4 bytes) + to the output file. + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + # calculating crc only if the image crc check is enabled + crc_to_print = _hex_print_format(0) + if ecst_args.firmware_crc != FW_CRC_DISABLE: + + with output.open("r+b") as output_file: + crc_calc = 0xffffffff + table = _create_table() + + output_file.seek(FW_IMAGE_OFFSET + ecst_args.paste_firmware_header + + ecst_args.firmware_crc_start) + for _ in range(ecst_args.firmware_crc_size): + current = output_file.read(1) + crc_calc = _crc_update(int.from_bytes(current, "little"), \ + crc_calc, table) + + crc = _finalize_crc(crc_calc) + crc_to_write = crc.to_bytes(4, "little") + crc_to_print = _hex_print_format(crc) + output_file.seek(HDR_FW_IMAGE_SIG_OFFSET + + ecst_args.paste_firmware_header) + output_file.write(crc_to_write) + + output_file.close() + + if ecst_args.verbose == REG_VERBOSE: + print(f'- HDR - Header CRC - Offset ' + f'{HDR_FW_IMAGE_SIG_OFFSET} - ' + f' {crc_to_print}') + +def _copy_image(output, ecst_args): + """copies the fw image from the input file to the output file + if firmware header offset is defined, just copies the input file to the + output file + + :param output: the output file object, + :param ecst_args: the object representing the command line arguments. + """ + with open(ecst_args.input, "rb") as firmware_image: + with open(output, "r+b") as output_file: + if ecst_args.paste_firmware_header == 0: + output_file.seek(FW_IMAGE_OFFSET) + else: + output_file.seek(0) + for line in firmware_image: + output_file.write(line) + output_file.close() + firmware_image.close() + + # pad fw image to be 16 byte aligned if needed + input_file_size = Path(ecst_args.input).stat().st_size + bytes_to_pad_num = abs((16 - input_file_size) % 16) + + with open(output, "r+b") as output_file: + i = bytes_to_pad_num + while i != 0: + output_file.seek(0, 2) # seek end of file + output_file.write(PAD_BYTE) + i -= 1 + output_file.close() + + # update firmware length if needed + fw_length = ecst_args.firmware_length + if fw_length is None: + if ecst_args.paste_firmware_header == 0: + ecst_args.firmware_length = input_file_size + bytes_to_pad_num + else: + ecst_args.firmware_length = input_file_size - HEADER_SIZE - \ + ecst_args.paste_firmware_header + +def _merge_file_with_bt_header(ecst_args): + """Merge the BT with the BH according to the bhoffset and pointer flags + + :param ecst_args: the object representing the command line arguments. + """ + bh_index = ecst_args.bh_offset + file_name_to_print = "" + + if not ecst_args.input: + exit_with_failure('No input BIN file selected for' + 'Bootloader header file.') + else: + input_file = Path(ecst_args.input) + if not input_file.exists(): + exit_with_failure(f'Cannot open {ecst_args.input}') + + if input_file.stat().st_size < bh_index: + + message = f'Bootloader header offset ({bh_index} bytes) should be ' + message += f'less than file size ' \ + f'({input_file.stat().st_size } bytes)' + exit_with_failure(message) + + # create a file if the output parameter is not None, + # otherwise write to the input file + if ecst_args.output is not None: + output_file = Path(ecst_args.output) + output_file.touch() + with input_file.open("r+b") as firmware_image: + with output_file.open("r+b") as output_file: + file_name_to_print = output_file.name + for line in firmware_image: + output_file.write(line) + output_file.seek(bh_index) + output_file.write(HDR_PTR_SIGNATURE.to_bytes(4, "little")) + output_file.seek(bh_index + 4) + output_file.write(ecst_args.pointer.to_bytes(4, "little")) + output_file.close() + firmware_image.close() + + else: + with input_file.open("r+b") as file_to_merge: + file_name_to_print = file_to_merge.name + file_to_merge.seek(bh_index + SIGNATURE_OFFSET) + file_to_merge.write(HDR_PTR_SIGNATURE.to_bytes(4, "little")) + file_to_merge.seek(bh_index + POINTER_OFFSET) + file_to_merge.write(ecst_args.pointer.to_bytes(4, "little")) + file_to_merge.close() + + if ecst_args.verbose == REG_VERBOSE: + print(Fore.LIGHTCYAN_EX + f'BootLoader Header file:' + f' {file_name_to_print}') + print(f'Offset: {_hex_print_format(ecst_args.bh_offset)},' + f' Signature: {_hex_print_format(HDR_PTR_SIGNATURE)},' + f' Pointer: {_hex_print_format(ecst_args.pointer)}') + +def _create_bt_header(ecst_args): + """create bootloader table header, consist of 4 bytes signature and + 4 bytes pointer + + :param ecst_args: the object representing the command line arguments. + """ + if not ecst_args.output: + exit_with_failure("No output file selected for " + "Bootloader header file.") + else: + output_file = Path(ecst_args.output) + if not output_file.exists(): + output_file.touch() + with open(output_file, "r+b") as boot_loader_header_file: + boot_loader_header_file.seek(SIGNATURE_OFFSET) + boot_loader_header_file.write(HDR_PTR_SIGNATURE.to_bytes(4, \ + "little")) + boot_loader_header_file.seek(POINTER_OFFSET) + boot_loader_header_file.write(ecst_args.pointer.to_bytes(4, \ + "little")) + boot_loader_header_file.close() + if ecst_args.verbose == REG_VERBOSE: + print(Fore.LIGHTCYAN_EX + f'BootLoader Header file:' + f' {output_file.name}') + print(f'Signature: {_hex_print_format(HDR_PTR_SIGNATURE)}, ' + f'Pointer: {_hex_print_format(ecst_args.pointer)}') + +def _create_table(): + """helper for crc calculation""" + table = [] + for i in range(256): + k = i + for _ in range(8): + if k & 1: + k = (k >> 1) ^ 0xEDB88320 + else: + k >>= 1 + table.append(k) + return table + +def _crc_update(cur, crc, table): + """helper for crc calculation + + :param cur + :param crc + :param table + """ + l_crc = (0x000000ff & cur) + + tmp = crc ^ l_crc + crc = (crc >> 8) ^ table[(tmp & 0xff)] + return crc + +def _finalize_crc(crc): + """helper for crc calculation + + :param crc + """ + final_crc = 0 + for j in range(NUM_OF_BYTES): + current_bit = crc & (1 << j) + current_bit = current_bit >> j + final_crc |= current_bit << (NUM_OF_BYTES - 1) - j + return final_crc + +def _hex_print_format(value): + """hex representation of an integer + + :param value: an integer to be represented in hex + """ + return "0x{:08x}".format(value) + +def _exit_with_failure_delete_file(output, message): + """formatted failure message printer, prints the + relevant error message, deletes the output file, + and exits the application. + + :param message: the error message to be printed + """ + output_file = Path(output) + if output_file.exists(): + output_file.unlink() + + message = '\n' + message + message += '\n' + message += '******************************\n' + message += '*** FAILED ***\n' + message += '******************************\n' + print(Fore.RED + message) + + sys.exit(EXIT_FAILURE_STATUS) + +def _exit_with_success(): + """formatted success message printer, prints the + success message and exits the application. + """ + message = '\n' + message += '******************************\n' + message += '*** SUCCESS ***\n' + message += '******************************\n' + print(Fore.GREEN + message) + + sys.exit(EXIT_SUCCESS_STATUS) + +def main(): + """main of the application + """ + init() # colored print initialization for windows + + if len(sys.argv) < 2: + sys.exit(EXIT_FAILURE_STATUS) + + ecst_obj = EcstArgs() + + if ecst_obj.error_args: + for err_arg in ecst_obj.error_args: + message = f'unKnown flag: {err_arg}' + exit_with_failure(message) + sys.exit(EXIT_SUCCESS_STATUS) + + # Start to handle booter header table + _bt_mode_handler(ecst_obj) + +if __name__ == '__main__': + main() diff --git a/boards/arm/npcx7m6fb_evb/support/ecst_args.py b/boards/arm/npcx7m6fb_evb/support/ecst_args.py new file mode 100755 index 00000000000000..e6764eb4994ce6 --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/support/ecst_args.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2020 Nuvoton Technology Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +# This file contains general functions for ECST application + +import sys +import argparse +from colorama import Fore + +INVALID_INPUT = -1 +EXIT_FAILURE_STATUS = 1 + +# Header common fields +FW_HDR_CRC_DISABLE = 0x00 +FW_HDR_CRC_ENABLE = 0x02 +FW_CRC_DISABLE = 0x00 +FW_CRC_ENABLE = 0x02 + +SPI_CLOCK_RATIO_1 = 0x00 +SPI_CLOCK_RATIO_2 = 0x08 + +SPI_UNLIMITED_BURST_DISABLE = 0x00 +SPI_UNLIMITED_BURST_ENABLE = 0x08 + +# Verbose related values +NO_VERBOSE = 0 +REG_VERBOSE = 1 +SUPER_VERBOSE = 1 + +# argument default values. +DEFAULT_MODE = "bt" +SPI_MAX_CLOCK_DEFAULT = "20" +FLASH_SIZE_DEFAULT = "16" +SPI_CLOCK_RATIO_DEFAULT = 1 +PASTE_FIRMWARE_HEADER_DEFAULT = 0x00000000 +DEFAULT_VERBOSE = NO_VERBOSE +SPI_MODE_VAL_DEFAULT = 'normal' +SPI_UNLIMITED_BURST_DEFAULT = SPI_UNLIMITED_BURST_DISABLE +FW_HDR_CRC_DEFAULT = FW_HDR_CRC_ENABLE +FW_CRC_DEFAULT = FW_CRC_ENABLE +FW_CRC_START_OFFSET_DEFAULT = 0x0 +POINTER_OFFSET_DEFAULT = 0x0 + +# Chips: convert from name to index. +CHIPS_INFO = {'npcx7m5': {'ram_address': 0x100A8000, 'ram_size': 0x20000}, + 'npcx7m6': {'ram_address': 0x10090000, 'ram_size': 0x40000}, + 'npcx7m7': {'ram_address': 0x10070000, 'ram_size': 0x60000}} +DEFAULT_CHIP = 'npcx7m6' + +# RAM related values +RAM_ADDR = 0x00 +RAM_SIZE = 0x01 + +class EcstArgs: + """creates an arguments object for the ECST, + the arguments are taken from the command line and/or + argument file + """ + error_args = None + + mode = DEFAULT_MODE + help = False + verbose = DEFAULT_VERBOSE + super_verbose = False + input = None + output = None + args_file = None + chip_name = DEFAULT_CHIP + chip_ram_address = CHIPS_INFO[DEFAULT_CHIP]['ram_address'] + chip_ram_size = CHIPS_INFO[DEFAULT_CHIP]['ram_address'] + firmware_header_crc = FW_HDR_CRC_DEFAULT + firmware_crc = FW_CRC_DEFAULT + spi_flash_maximum_clock = SPI_MAX_CLOCK_DEFAULT + spi_flash_clock_ratio = SPI_CLOCK_RATIO_DEFAULT + unlimited_burst_mode = SPI_UNLIMITED_BURST_DEFAULT + spi_flash_read_mode = SPI_MODE_VAL_DEFAULT + firmware_load_address = None + firmware_entry_point = None + use_arm_reset = True + firmware_crc_start = FW_CRC_START_OFFSET_DEFAULT + firmware_crc_size = None + firmware_length = None + flash_size = FLASH_SIZE_DEFAULT + paste_firmware_header = PASTE_FIRMWARE_HEADER_DEFAULT + pointer = POINTER_OFFSET_DEFAULT + bh_offset = None + + def __init__(self): + + arguments = _create_parser("") + valid_arguments = arguments[0] + invalid_arguments = arguments[1] + self.error_args = invalid_arguments + + _populate_args(self, valid_arguments) + _populate_chip_fields(self) + +def _populate_chip_fields(self): + """populate the chip related fields for the ecst""" + self.chip_name = self.chip_name + chip = str(self.chip_name).lower() + + if chip not in CHIPS_INFO: + self.chip_name = INVALID_INPUT + return + + self.chip_ram_address = CHIPS_INFO[chip]['ram_address'] + self.chip_ram_size = CHIPS_INFO[chip]['ram_size'] + if self.firmware_load_address is None: + self.firmware_load_address = self.chip_ram_address + +def _populate_args(self, argument_list): + """populate the ecst arguments according to the command line/ args file""" + for arg in vars(argument_list): + if (arg == "input") & (argument_list.input is not None): + self.input = argument_list.input + + elif (arg == "output") & (argument_list.output is not None): + self.output = argument_list.output + + elif (arg == "chip") & (argument_list.chip is not None): + self.chip_name = argument_list.chip + _populate_chip_fields(self) + + elif (arg == "verbose") & argument_list.verbose: + self.verbose = REG_VERBOSE + + elif (arg == "super_verbose") & argument_list.super_verbose: + self.verbose = SUPER_VERBOSE + + elif (arg == "spi_flash_maximum_clock") & \ + (argument_list.spi_flash_maximum_clock is not None): + self.spi_flash_maximum_clock =\ + argument_list.spi_flash_maximum_clock + + elif (arg == "spi_flash_clock_ratio") & \ + (argument_list.spi_flash_clock_ratio is not None): + if argument_list.spi_flash_clock_ratio.isdigit(): + self.spi_flash_clock_ratio =\ + int(argument_list.spi_flash_clock_ratio) + else: + self.spi_flash_clock_ratio = INVALID_INPUT + + elif (arg == "firmware_header_crc") &\ + argument_list.firmware_header_crc: + self.firmware_header_crc = FW_HDR_CRC_DISABLE + + elif (arg == "firmware_crc") & argument_list.firmware_crc: + self.firmware_crc = FW_CRC_DISABLE + + elif (arg == "spi_read_mode") &\ + (argument_list.spi_read_mode is not None): + + self.spi_flash_read_mode = argument_list.spi_read_mode + + elif (arg == "flash_size") & (argument_list.flash_size is not None): + self.flash_size = argument_list.flash_size + + elif (arg == "paste_firmware_header") & \ + (argument_list.paste_firmware_header is not None): + if _is_hex(argument_list.paste_firmware_header): + self.paste_firmware_header =\ + int(argument_list.paste_firmware_header, 16) + else: + self.paste_firmware_header = INVALID_INPUT + +def _create_parser(arg_list): + """create argument parser according to pre-defined arguments + + :param arg_list: when empty, parses command line arguments, + else parses the given string + """ + + parser = argparse.ArgumentParser(conflict_handler='resolve') + parser.add_argument("-i", nargs='?', dest="input") + parser.add_argument("-o", nargs='?', dest="output") + parser.add_argument("-chip", dest="chip") + parser.add_argument("-v", action="store_true", dest="verbose") + parser.add_argument("-vv", action="store_true", dest="super_verbose") + parser.add_argument("-nohcrc", action="store_true", + dest="firmware_header_crc") + parser.add_argument("-nofcrc", action="store_true", dest="firmware_crc") + parser.add_argument("-spimaxclk", nargs='?', + dest="spi_flash_maximum_clock") + parser.add_argument("-spiclkratio", nargs='?', + dest="spi_flash_clock_ratio") + parser.add_argument("-spireadmode", nargs='?', dest="spi_read_mode") + parser.add_argument("-flashsize", nargs='?', dest="flash_size") + parser.add_argument("-ph", nargs='?', dest="paste_firmware_header") + + args = parser.parse_known_args(arg_list.split()) + + if arg_list == "": + args = parser.parse_known_args() + + return args + +def _file_to_line(arg_file): + """helper to convert a text file to one line string + used to parse the arguments in a given argfile + + :param arg_file: the file to manipulate + """ + with open(arg_file, "r") as arg_file_to_read: + data = arg_file_to_read.read().strip() + arg_file_to_read.close() + + return data + +def _is_hex(val): + """helper to determine whether an input is a hex + formatted number + + :param val: input to be checked + """ + if val.startswith("0x") or val.startswith("0X"): + val = val[2:] + hex_digits = set("0123456789abcdefABCDEF") + for char in val: + if char not in hex_digits: + return False + return True + +def exit_with_failure(message): + """formatted failure message printer, prints the + relevant error message and exits the application. + + :param message: the error message to be printed + """ + + message = '\n' + message + message += '\n' + message += '******************************\n' + message += '*** FAILED ***\n' + message += '******************************\n' + print(Fore.RED + message) + + sys.exit(EXIT_FAILURE_STATUS) diff --git a/boards/arm/npcx7m6fb_evb/support/openocd.cfg b/boards/arm/npcx7m6fb_evb/support/openocd.cfg new file mode 100644 index 00000000000000..8804709150351d --- /dev/null +++ b/boards/arm/npcx7m6fb_evb/support/openocd.cfg @@ -0,0 +1,4 @@ +# script for Nuvoton NPCX Cortex-M4 Series + +source [find interface/jlink.cfg] +source [find target/npcx.cfg] diff --git a/boards/arm/nrf21540dk_nrf52840/Kconfig b/boards/arm/nrf21540dk_nrf52840/Kconfig new file mode 100644 index 00000000000000..ce77a4c58eb0e6 --- /dev/null +++ b/boards/arm/nrf21540dk_nrf52840/Kconfig @@ -0,0 +1,10 @@ +# nRF21540 DK NRF52840 board configuration + +# Copyright (c) 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on BOARD_NRF21540DK_NRF52840 diff --git a/boards/arm/nrf21540dk_nrf52840/Kconfig.board b/boards/arm/nrf21540dk_nrf52840/Kconfig.board new file mode 100644 index 00000000000000..b2c9c86d53eb00 --- /dev/null +++ b/boards/arm/nrf21540dk_nrf52840/Kconfig.board @@ -0,0 +1,8 @@ +# nRF21540 DK NRF52840 board configuration + +# Copyright (c) 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NRF21540DK_NRF52840 + bool "nRF21540 DK NRF52840" + depends on SOC_NRF52840_QIAA diff --git a/boards/arm/nrf21540dk_nrf52840/Kconfig.defconfig b/boards/arm/nrf21540dk_nrf52840/Kconfig.defconfig new file mode 100644 index 00000000000000..c3794d369350ab --- /dev/null +++ b/boards/arm/nrf21540dk_nrf52840/Kconfig.defconfig @@ -0,0 +1,26 @@ +# nRF21540 DK NRF52840 board configuration + +# Copyright (c) 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF21540DK_NRF52840 + +config BOARD + default "nrf21540dk_nrf52840" + +if USB + +config USB_NRFX + default y + +config USB_DEVICE_STACK + default y + +endif # USB + +config BT_CTLR + # Disabled until PA/LNA support for nRF21540 front-end is added + # in Zephyr Bluetooth Controller + # default BT + +endif # BOARD_NRF21540DK_NRF52840 diff --git a/boards/arm/nrf21540dk_nrf52840/board.cmake b/boards/arm/nrf21540dk_nrf52840/board.cmake new file mode 100644 index 00000000000000..ef822795fe59ed --- /dev/null +++ b/boards/arm/nrf21540dk_nrf52840/board.cmake @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=nrf52" "--speed=4000") +board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/boards/arm/nrf21540dk_nrf52840/doc/img/nrf21540dk_nrf52840.jpg b/boards/arm/nrf21540dk_nrf52840/doc/img/nrf21540dk_nrf52840.jpg new file mode 100644 index 00000000000000..5f39f708144b01 Binary files /dev/null and b/boards/arm/nrf21540dk_nrf52840/doc/img/nrf21540dk_nrf52840.jpg differ diff --git a/boards/arm/nrf21540dk_nrf52840/doc/index.rst b/boards/arm/nrf21540dk_nrf52840/doc/index.rst new file mode 100644 index 00000000000000..741c35f3b29812 --- /dev/null +++ b/boards/arm/nrf21540dk_nrf52840/doc/index.rst @@ -0,0 +1,238 @@ +.. _nrf21540dk_nrf52840: + +nRF21540 DK +########### + +Overview +******** +The nRF21540 DK (PCA10112) shows possibility of the Nordic Semiconductor +nRF21540 Front End Module connected with nRF52840 ARM Cortex-M4F CPU. +The CPU provides support for the following devices: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UART (Universal asynchronous receiver-transmitter)` +* :abbr:`USB (Universal Serial Bus)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/nrf21540dk_nrf52840.jpg + :width: 442px + :align: center + :alt: nRF21540 DK + + nRF21540 DK (Credit: Nordic Semiconductor) + +More information about the board can be found at the `nRF21540 website`_. +The `Nordic Semiconductor Infocenter`_ contains the processor'sand front end +module's information and the datasheet. + +Hardware +******** + +The nRF52840 on the nRF21540 DK has two external oscillators. The frequency +of the slow clock is 32.768 kHz. The frequency of the main clock is 32 MHz. + +Supported Features +================== + +The nrf21540dk_nrf52840 board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth, | +| | | ieee802154 | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| USB | on-chip | usb | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Other hardware features are not supported by the Zephyr kernel. +See `nRF52840 Product Specification`_ and `Nordic Semiconductor Infocenter`_ +for a complete list of nRF21540 Development Kit board hardware features. + +Connections and IOs +=================== + +LED +--- + +* LED1 (green) = P0.13 +* LED2 (green) = P0.14 +* LED3 (green) = P0.15 +* LED4 (green) = P0.16 + +Push buttons +------------ + +* BUTTON1 = SW1 = P0.11 +* BUTTON2 = SW2 = P0.12 +* BUTTON3 = SW3 = P0.24 +* BUTTON4 = SW4 = P0.25 +* BOOT = SW5 = boot/reset + +Front End Module +---------------- + +* MISO = P1.13 +* MOSI = P1.14 +* CLOCK = P1.15 +* CHIP SELECT = P0.21 +* PDN = P0.23 +* MODE = P0.17 +* RXEN = P0.19 +* ANTSEL = P0.20 +* TXEN = P0.22 + +Programming and Debugging +************************* + +Applications for the ``nrf21540dk_nrf52840`` board configuration can be +built and flashed in the usual way (see :ref:`build_an_application` +and :ref:`application_run` for more details); however, the standard +debugging targets are not currently available. + +Flashing +======== + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. Then build and flash +applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :ref:`hello_world` application. + +First, run your favorite terminal program to listen for output. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the board nRF52840 DK +can be found. For example, under Linux, :code:`/dev/ttyACM0`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nrf21540dk_nrf52840 + :goals: build flash + +Debugging +========= + +Refer to the :ref:`nordic_segger` page to learn about debugging Nordic boards with a +Segger IC. + + +Testing the LEDs and buttons in the nRF21540 DK +*********************************************** + +There are 2 samples that allow you to test that the buttons (switches) and LEDs on +the board are working properly with Zephyr: + +.. code-block:: console + + samples/basic/blinky + samples/basic/button + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in +:zephyr_file:`boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts`. + +Using UART1 +*********** + +The following approach can be used when an application needs to use +more than one UART for connecting peripheral devices: + +1. Add devicetree overlay file to the main directory of your application: + + .. code-block:: console + + $ cat nrf21540dk_nrf52840.overlay + &uart1 { + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + status = "okay"; + tx-pin = <14>; + rx-pin = <16>; + }; + + In the overlay file above, pin P0.16 is used for RX and P0.14 is used for TX + +2. Use the UART1 as ``device_get_binding(DT_LABEL(DT_NODELABEL(uart1)))`` + +Overlay file naming +=================== + +The file has to be named ``.overlay`` and placed in the app main directory to be +picked up automatically by the build system. + +Selecting the pins +================== +To select the pin numbers for tx-pin and rx-pin: + +.. code-block:: console + + tx-pin = + +Open the `nRF52840 Product Specification`_, chapter 7 'Hardware and Layout'. +In the table 7.1.1 'aQFN73 ball assignments' select the pins marked +'General purpose I/O'. Note that pins marked as 'low frequency I/O only' can only be used +in under-10KHz applications. They are not suitable for 115200 speed of UART. + +Translate the 'Pin' into number for devicetree by using the following formula:: + + pin_no = b\*32 + a + +where ``a`` and ``b`` are from the Pin value in the table (Pb.a). +For example, for P0.1, ``pin_no = 1`` and for P1.0, ``pin_no = 32``. + +References +********** + +.. target-notes:: + +.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html +.. _nRF21540 website: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF21540 +.. _nRF52840 Product Specification: http://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.0.pdf +.. _nRF21540 Product Specification: http://infocenter.nordicsemi.com/pdf/nRF21540_PS_v1.0.pdf diff --git a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts new file mode 100644 index 00000000000000..f2f04a38d6aa51 --- /dev/null +++ b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.dts @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * Copyright (c) 2017 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Nordic nRF21540 DK NRF52840"; + compatible = "nordic,nrf21540-dk-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; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + label = "Green LED 0"; + }; + led1: led_1 { + gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; + label = "Green LED 1"; + }; + led2: led_2 { + gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; + label = "Green LED 2"; + }; + led3: led_3 { + gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; + label = "Green LED 3"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm0 13>; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 0"; + }; + button1: button_1 { + gpios = <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + }; + button2: button_2 { + gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + }; + button3: button_3 { + gpios = <&gpio0 25 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 3"; + }; + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 3 0>, /* A0 */ + <1 0 &gpio0 4 0>, /* A1 */ + <2 0 &gpio0 28 0>, /* A2 */ + <3 0 &gpio0 29 0>, /* A3 */ + <4 0 &gpio0 30 0>, /* A4 */ + <5 0 &gpio0 31 0>, /* A5 */ + <6 0 &gpio1 1 0>, /* D0 */ + <7 0 &gpio1 2 0>, /* D1 */ + <8 0 &gpio1 3 0>, /* D2 */ + <9 0 &gpio1 4 0>, /* D3 */ + <10 0 &gpio1 5 0>, /* D4 */ + <11 0 &gpio1 6 0>, /* D5 */ + <12 0 &gpio1 7 0>, /* D6 */ + <13 0 &gpio1 8 0>, /* D7 */ + <14 0 &gpio1 10 0>, /* D8 */ + <15 0 &gpio1 11 0>, /* D9 */ + <16 0 &gpio1 12 0>, /* D10 */ + <17 0 &gpio1 13 0>, /* D11 */ + <18 0 &gpio1 14 0>, /* D12 */ + <19 0 &gpio1 15 0>, /* D13 */ + <20 0 &gpio0 26 0>, /* D14 */ + <21 0 &gpio0 27 0>; /* D15 */ + }; + + arduino_adc: analog-connector { + compatible = "arduino,uno-adc"; + #io-channel-cells = <1>; + io-channel-map = <0 &adc 1>, /* A0 = P0.3 = AIN1 */ + <1 &adc 2>, /* A1 = P0.4 = AIN2 */ + <2 &adc 4>, /* A2 = P0.28 = AIN4 */ + <3 &adc 5>, /* A3 = P0.29 = AIN5 */ + <4 &adc 6>, /* A4 = P0.30 = AIN6 */ + <5 &adc 7>; /* A5 = P0.31 = AIN7 */ + }; + + nrf_radio_fem: nrf21540_fem { + compatible = "nordic,nrf21540-fem"; + tx-en-gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>; + rx-en-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>; + pdn-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; + ant-sel-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + pwm-led0 = &pwm_led0; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&uart0 { + compatible = "nordic,nrf-uarte"; + status = "okay"; + current-speed = <115200>; + tx-pin = <6>; + rx-pin = <8>; + rts-pin = <5>; + cts-pin = <7>; +}; + +arduino_serial: &uart1 { + status = "okay"; + current-speed = <115200>; + rx-pin = <33>; + tx-pin = <34>; +}; + +arduino_i2c: &i2c0 { + compatible = "nordic,nrf-twi"; + status = "okay"; + sda-pin = <26>; + scl-pin = <27>; +}; + +&i2c1 { + compatible = "nordic,nrf-twi"; + /* Cannot be used together with spi1. */ + /* status = "okay"; */ + sda-pin = <30>; + scl-pin = <31>; +}; + +&pwm0 { + status = "okay"; + ch0-pin = <13>; + ch0-inverted; +}; + +&spi0 { + compatible = "nordic,nrf-spi"; + /* Cannot be used together with i2c0. */ + /* status = "okay"; */ + sck-pin = <27>; + mosi-pin = <26>; + miso-pin = <29>; +}; + +&spi1 { + compatible = "nordic,nrf-spi"; + status = "okay"; + sck-pin = <31>; + mosi-pin = <30>; + miso-pin = <40>; +}; + +&spi2 { + compatible = "nordic,nrf-spi"; + status = "disabled"; + sck-pin = <19>; + mosi-pin = <20>; + miso-pin = <21>; +}; + +arduino_spi: &spi3 { + status = "okay"; + sck-pin = <47>; + miso-pin = <46>; + mosi-pin = <45>; + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x000000000 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/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@f8000 { + label = "storage"; + reg = <0x000f8000 0x00008000>; + }; + }; +}; + +&usbd { + compatible = "nordic,nrf-usbd"; + status = "okay"; +}; diff --git a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.yaml b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.yaml new file mode 100644 index 00000000000000..aac5c3241475e7 --- /dev/null +++ b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840.yaml @@ -0,0 +1,26 @@ +identifier: nrf21540dk_nrf52840 +name: nRF21540-DK-NRF52840 +type: mcu +arch: arm +ram: 256 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - arduino_gpio + - arduino_i2c + - arduino_spi + - ble + - counter + - gpio + - i2c + - ieee802154 + - pwm + - spi + - usb_cdc + - usb_device + - watchdog + - netif:openthread diff --git a/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig new file mode 100644 index 00000000000000..442513d8f5cb6c --- /dev/null +++ b/boards/arm/nrf21540dk_nrf52840/nrf21540dk_nrf52840_defconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_NRF21540DK_NRF52840=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable RTT +CONFIG_USE_SEGGER_RTT=y + +# enable GPIO +CONFIG_GPIO=y + +# enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# additional board options +CONFIG_GPIO_AS_PINRESET=y diff --git a/boards/arm/nrf51_ble400/board.cmake b/boards/arm/nrf51_ble400/board.cmake index a29fa16976c205..e8c51da0a5e725 100644 --- a/boards/arm/nrf51_ble400/board.cmake +++ b/boards/arm/nrf51_ble400/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF51") board_runner_args(jlink "--device=nrf51" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf51_ble400/nrf51_ble400.dts b/boards/arm/nrf51_ble400/nrf51_ble400.dts index 69cded44b6492e..961aacb5bf6390 100644 --- a/boards/arm/nrf51_ble400/nrf51_ble400.dts +++ b/boards/arm/nrf51_ble400/nrf51_ble400.dts @@ -92,7 +92,7 @@ sck-pin = <25>; mosi-pin = <24>; miso-pin = <23>; - cs-gpios = <&gpio0 30 0>; + cs-gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; }; &uart0 { diff --git a/boards/arm/nrf51_ble400/nrf51_ble400.yaml b/boards/arm/nrf51_ble400/nrf51_ble400.yaml index a8560999b107d2..d3d455c27d1a35 100644 --- a/boards/arm/nrf51_ble400/nrf51_ble400.yaml +++ b/boards/arm/nrf51_ble400/nrf51_ble400.yaml @@ -9,6 +9,7 @@ toolchain: ram: 16 supported: - ble + - gpio - i2c testing: ignore_tags: diff --git a/boards/arm/nrf51dk_nrf51422/board.cmake b/boards/arm/nrf51dk_nrf51422/board.cmake index 62012e8d50399f..87c9b918a201fd 100644 --- a/boards/arm/nrf51dk_nrf51422/board.cmake +++ b/boards/arm/nrf51dk_nrf51422/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF51") board_runner_args(jlink "--device=nrf51" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf51dk_nrf51422/doc/index.rst b/boards/arm/nrf51dk_nrf51422/doc/index.rst index 02c23bc9030b03..15433a2ba6c60d 100644 --- a/boards/arm/nrf51dk_nrf51422/doc/index.rst +++ b/boards/arm/nrf51dk_nrf51422/doc/index.rst @@ -33,9 +33,6 @@ More information about the board can be found at the `nRF51 DK website`_. The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. -.. note:: - - In previous Zephyr releases this board was named *nrf51_pca10028*. Hardware ******** diff --git a/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.dts b/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.dts index fb39c085f0d9df..e30b5118cb5174 100644 --- a/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.dts +++ b/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.dts @@ -134,10 +134,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.yaml b/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.yaml index 2218bc8f13385b..08fbcd5b7e5573 100644 --- a/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.yaml +++ b/boards/arm/nrf51dk_nrf51422/nrf51dk_nrf51422.yaml @@ -11,6 +11,7 @@ supported: - adc - ble - counter + - gpio - i2c - nvs - pwm diff --git a/boards/arm/nrf51dongle_nrf51422/board.cmake b/boards/arm/nrf51dongle_nrf51422/board.cmake index a29fa16976c205..e8c51da0a5e725 100644 --- a/boards/arm/nrf51dongle_nrf51422/board.cmake +++ b/boards/arm/nrf51dongle_nrf51422/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF51") board_runner_args(jlink "--device=nrf51" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf51dongle_nrf51422/doc/index.rst b/boards/arm/nrf51dongle_nrf51422/doc/index.rst index 8c1fc4f298539a..c523f1ec47760b 100644 --- a/boards/arm/nrf51dongle_nrf51422/doc/index.rst +++ b/boards/arm/nrf51dongle_nrf51422/doc/index.rst @@ -33,9 +33,6 @@ More information about the board can be found at the `nRF51 Dongle website`_. The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. -.. note:: - - In previous Zephyr releases this board was named *nrf51_pca10031*. Hardware ******** diff --git a/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422.dts b/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422.dts index 96d9deb3dd21a4..a762c29bd89767 100644 --- a/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422.dts +++ b/boards/arm/nrf51dongle_nrf51422/nrf51dongle_nrf51422.dts @@ -76,10 +76,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52832_mdk/nrf52832_mdk.dts b/boards/arm/nrf52832_mdk/nrf52832_mdk.dts index 46954eb7d9402e..8a36945d1642ea 100644 --- a/boards/arm/nrf52832_mdk/nrf52832_mdk.dts +++ b/boards/arm/nrf52832_mdk/nrf52832_mdk.dts @@ -125,10 +125,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52833dk_nrf52820/CMakeLists.txt b/boards/arm/nrf52833dk_nrf52820/CMakeLists.txt new file mode 100644 index 00000000000000..413dee8fe2a044 --- /dev/null +++ b/boards/arm/nrf52833dk_nrf52820/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +# The nrf52833dk_nrf52820 board mirrors the nRF52833 DK hardware. This +# needs to be considered by certain system initialization functionality +# residing in system_nrf52820.c and SoC dependent routines in nrfx_coredep.h. +zephyr_compile_definitions(DEVELOP_IN_NRF52833) +zephyr_compile_definitions(NRFX_COREDEP_DELAY_US_LOOP_CYCLES=3) diff --git a/boards/arm/nrf52833dk_nrf52820/board.cmake b/boards/arm/nrf52833dk_nrf52820/board.cmake index bbf54151d760bf..f3829f81189700 100644 --- a/boards/arm/nrf52833dk_nrf52820/board.cmake +++ b/boards/arm/nrf52833dk_nrf52820/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") board_runner_args(pyocd "--target=nrf52820" "--frequency=4000000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts index 15f8228fe5e5cc..068ffe90895513 100644 --- a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts +++ b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820.dts @@ -91,7 +91,7 @@ }; &uart0 { - compatible = "nordic,nrf-uart"; + compatible = "nordic,nrf-uarte"; status = "okay"; current-speed = <115200>; tx-pin = <6>; @@ -127,10 +127,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig index f95ad04e8bd580..c2d612de5824f0 100644 --- a/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig +++ b/boards/arm/nrf52833dk_nrf52820/nrf52833dk_nrf52820_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF52833DK_NRF52820=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable RTT CONFIG_USE_SEGGER_RTT=y diff --git a/boards/arm/nrf52833dk_nrf52833/Kconfig.defconfig b/boards/arm/nrf52833dk_nrf52833/Kconfig.defconfig index 9e796a2d8724d4..b1f86e06e42050 100644 --- a/boards/arm/nrf52833dk_nrf52833/Kconfig.defconfig +++ b/boards/arm/nrf52833dk_nrf52833/Kconfig.defconfig @@ -18,10 +18,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/nrf52833dk_nrf52833/board.cmake b/boards/arm/nrf52833dk_nrf52833/board.cmake index 11d3ce2106c6b8..8f33a5c7ac3c00 100644 --- a/boards/arm/nrf52833dk_nrf52833/board.cmake +++ b/boards/arm/nrf52833dk_nrf52833/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf52833dk_nrf52833/doc/index.rst b/boards/arm/nrf52833dk_nrf52833/doc/index.rst index 02b5fe1c1bbd67..45deee945b7f30 100644 --- a/boards/arm/nrf52833dk_nrf52833/doc/index.rst +++ b/boards/arm/nrf52833dk_nrf52833/doc/index.rst @@ -30,9 +30,6 @@ More information about the board can be found at the `nRF52833 DK website`_. The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. -.. note:: - - In previous Zephyr releases this board was named *nrf52833_pca10100*. Hardware ******** diff --git a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts index 96dcb732a7b52a..9b9afbaf85fb9b 100644 --- a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts +++ b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833.dts @@ -129,7 +129,7 @@ }; &uart0 { - compatible = "nordic,nrf-uart"; + compatible = "nordic,nrf-uarte"; status = "okay"; current-speed = <115200>; tx-pin = <6>; @@ -188,14 +188,11 @@ arduino_spi: &spi3 { sck-pin = <23>; miso-pin = <22>; mosi-pin = <21>; - cs-gpios = <&arduino_header 16 0>; /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig index 184b161f4d0805..0f88c92bc5fb6c 100644 --- a/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig +++ b/boards/arm/nrf52833dk_nrf52833/nrf52833dk_nrf52833_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF52833DK_NRF52833=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable RTT CONFIG_USE_SEGGER_RTT=y diff --git a/boards/arm/nrf52840_blip/Kconfig.defconfig b/boards/arm/nrf52840_blip/Kconfig.defconfig index aef423294de7a9..bad6dec42ea645 100644 --- a/boards/arm/nrf52840_blip/Kconfig.defconfig +++ b/boards/arm/nrf52840_blip/Kconfig.defconfig @@ -18,10 +18,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/nrf52840_blip/nrf52840_blip.dts b/boards/arm/nrf52840_blip/nrf52840_blip.dts index fd056888655e8e..add674e56b2666 100644 --- a/boards/arm/nrf52840_blip/nrf52840_blip.dts +++ b/boards/arm/nrf52840_blip/nrf52840_blip.dts @@ -131,10 +131,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52840_mdk/Kconfig.defconfig b/boards/arm/nrf52840_mdk/Kconfig.defconfig index e37edc3276cc70..4c77821fc518bf 100644 --- a/boards/arm/nrf52840_mdk/Kconfig.defconfig +++ b/boards/arm/nrf52840_mdk/Kconfig.defconfig @@ -18,10 +18,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/nrf52840_mdk/board.cmake b/boards/arm/nrf52840_mdk/board.cmake index 8cb21acfaffd37..3c5a7e17a4000b 100644 --- a/boards/arm/nrf52840_mdk/board.cmake +++ b/boards/arm/nrf52840_mdk/board.cmake @@ -1,4 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(pyocd "--target=nrf52840") +set(OPENOCD_NRF5_INTERFACE "cmsis-dap") include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/boards/arm/nrf52840_mdk/nrf52840_mdk.dts b/boards/arm/nrf52840_mdk/nrf52840_mdk.dts index ca520fafa9d3cd..2f7438a0af0608 100644 --- a/boards/arm/nrf52840_mdk/nrf52840_mdk.dts +++ b/boards/arm/nrf52840_mdk/nrf52840_mdk.dts @@ -130,11 +130,34 @@ ch2-inverted; }; +&qspi { + status = "okay"; + sck-pin = <35>; + io-pins = <37>, <36>, <34>, <33>; + csn-pins = <38>; + mx25r64: mx25r6435f@0 { + compatible = "nordic,qspi-nor"; + reg = <0>; + writeoc = "pp4io"; + readoc = "read4io"; + sck-frequency = <8000000>; + label = "MX25R64"; + jedec-id = [c2 28 17]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 03 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f5 00 82 ed 04 cc 44 83 68 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; + size = <67108864>; + has-dpd; + t-enter-dpd = <10000>; + t-exit-dpd = <35000>; + }; +}; + &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52840_papyr/Kconfig.defconfig b/boards/arm/nrf52840_papyr/Kconfig.defconfig index ec659e0ccbdbd8..f9a421796b1370 100644 --- a/boards/arm/nrf52840_papyr/Kconfig.defconfig +++ b/boards/arm/nrf52840_papyr/Kconfig.defconfig @@ -18,10 +18,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/nrf52840_papyr/board.cmake b/boards/arm/nrf52840_papyr/board.cmake index 12a1d93b789105..65580b0fef5348 100644 --- a/boards/arm/nrf52840_papyr/board.cmake +++ b/boards/arm/nrf52840_papyr/board.cmake @@ -1,5 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +board_runner_args(nrfjprog "--softreset") include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf52840_papyr/nrf52840_papyr.dts b/boards/arm/nrf52840_papyr/nrf52840_papyr.dts index 22514cee10cea7..901c1a18a10389 100644 --- a/boards/arm/nrf52840_papyr/nrf52840_papyr.dts +++ b/boards/arm/nrf52840_papyr/nrf52840_papyr.dts @@ -128,7 +128,7 @@ &flash0 { /* * For more information, see: - * http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html + * https://docs.zephyrproject.org/latest/reference/devicetree/index.html#fixed-flash-partitions */ partitions { compatible = "fixed-partitions"; diff --git a/boards/arm/nrf52840dk_nrf52811/Kconfig.defconfig b/boards/arm/nrf52840dk_nrf52811/Kconfig.defconfig index 15aaa72ad91508..2d933bf12b3d17 100644 --- a/boards/arm/nrf52840dk_nrf52811/Kconfig.defconfig +++ b/boards/arm/nrf52840dk_nrf52811/Kconfig.defconfig @@ -11,8 +11,4 @@ config BOARD config BT_CTLR default BT -config IEEE802154_NRF5 - default y - depends on IEEE802154 - endif # BOARD_NRF52840DK_NRF52811 diff --git a/boards/arm/nrf52840dk_nrf52811/board.cmake b/boards/arm/nrf52840dk_nrf52811/board.cmake index 7f7930e70de091..f0b658fc9fdf2e 100644 --- a/boards/arm/nrf52840dk_nrf52811/board.cmake +++ b/boards/arm/nrf52840dk_nrf52811/board.cmake @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf52840dk_nrf52811/doc/index.rst b/boards/arm/nrf52840dk_nrf52811/doc/index.rst index 318a16f1499dfd..b33d1caea4e0ce 100644 --- a/boards/arm/nrf52840dk_nrf52811/doc/index.rst +++ b/boards/arm/nrf52840dk_nrf52811/doc/index.rst @@ -15,9 +15,6 @@ while using the nRF52840 Development Kit (PCA10056). See :ref:`nrf52840dk_nrf52840` for more information about the development board and `nRF52811 website`_ for the official reference on the IC itself. -.. note:: - - In earlier Zephyr releases this board was known as ``nrf52811_pca10056``. References ********** diff --git a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts index cad55e4ce0993d..1b4a3c6a483830 100644 --- a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts +++ b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811.dts @@ -96,7 +96,7 @@ }; &uart0 { - compatible = "nordic,nrf-uart"; + compatible = "nordic,nrf-uarte"; status = "okay"; current-speed = <115200>; tx-pin = <6>; @@ -136,10 +136,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig index 919c69c6472966..15c6757a8c3a7f 100644 --- a/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig +++ b/boards/arm/nrf52840dk_nrf52811/nrf52840dk_nrf52811_defconfig @@ -9,6 +9,9 @@ CONFIG_BOARD_NRF52840DK_NRF52811=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable UART CONFIG_SERIAL=y diff --git a/boards/arm/nrf52840dk_nrf52840/Kconfig.defconfig b/boards/arm/nrf52840dk_nrf52840/Kconfig.defconfig index 78a619ae34db31..bc06b9074f9e9b 100644 --- a/boards/arm/nrf52840dk_nrf52840/Kconfig.defconfig +++ b/boards/arm/nrf52840dk_nrf52840/Kconfig.defconfig @@ -18,10 +18,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/nrf52840dk_nrf52840/board.cmake b/boards/arm/nrf52840dk_nrf52840/board.cmake index 5990fda82aed1c..ef822795fe59ed 100644 --- a/boards/arm/nrf52840dk_nrf52840/board.cmake +++ b/boards/arm/nrf52840dk_nrf52840/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf52840dk_nrf52840/doc/index.rst b/boards/arm/nrf52840dk_nrf52840/doc/index.rst index 80700aee2761b6..ec45182aa0f646 100644 --- a/boards/arm/nrf52840dk_nrf52840/doc/index.rst +++ b/boards/arm/nrf52840dk_nrf52840/doc/index.rst @@ -36,9 +36,6 @@ More information about the board can be found at the `nRF52840 DK website`_. The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. -.. note:: - - In earlier Zephyr releases this board was known as ``nrf52840_pca10056``. Hardware ******** diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts index b6be4fc7c07c65..b76b648c2ec516 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts @@ -140,7 +140,7 @@ }; &uart0 { - compatible = "nordic,nrf-uart"; + compatible = "nordic,nrf-uarte"; status = "okay"; current-speed = <115200>; tx-pin = <6>; @@ -210,13 +210,20 @@ arduino_i2c: &i2c0 { mx25r64: mx25r6435f@0 { compatible = "nordic,qspi-nor"; reg = <0>; + /* MX24R64 supports only pp and pp4io */ writeoc = "pp4io"; + /* MX24R64 supports all readoc options */ readoc = "read4io"; sck-frequency = <8000000>; label = "MX25R64"; jedec-id = [c2 28 17]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 03 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f5 00 82 ed 04 cc 44 83 68 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; size = <67108864>; - has-be32k; has-dpd; t-enter-dpd = <10000>; t-exit-dpd = <35000>; @@ -228,14 +235,11 @@ arduino_spi: &spi3 { sck-pin = <47>; miso-pin = <46>; mosi-pin = <45>; - cs-gpios = <&arduino_header 16 0>; /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.yaml b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.yaml index 39a0cd7ccb41d1..3d08a71a07ab78 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.yaml +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.yaml @@ -15,6 +15,7 @@ supported: - arduino_spi - ble - counter + - gpio - i2c - ieee802154 - pwm @@ -22,3 +23,4 @@ supported: - usb_cdc - usb_device - watchdog + - netif:openthread diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig index 903e1b1208d883..0202d7ba16da30 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF52840DK_NRF52840=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable RTT CONFIG_USE_SEGGER_RTT=y diff --git a/boards/arm/nrf52840dongle_nrf52840/Kconfig.defconfig b/boards/arm/nrf52840dongle_nrf52840/Kconfig.defconfig index b7e1d131d2fd82..c4219d7df4efa5 100644 --- a/boards/arm/nrf52840dongle_nrf52840/Kconfig.defconfig +++ b/boards/arm/nrf52840dongle_nrf52840/Kconfig.defconfig @@ -32,11 +32,14 @@ config USB_NRFX config USB_DEVICE_STACK default y -endif # USB +# Enable UART driver, needed for CDC ACM +config SERIAL + default USB_CDC_ACM -config IEEE802154_NRF5 - default y - depends on IEEE802154 +config UART_INTERRUPT_DRIVEN + default USB_CDC_ACM + +endif # USB config BT_CTLR default BT diff --git a/boards/arm/nrf52840dongle_nrf52840/board.c b/boards/arm/nrf52840dongle_nrf52840/board.c index dd0f0d44bdcc2b..fb614b2fc30d3b 100644 --- a/boards/arm/nrf52840dongle_nrf52840/board.c +++ b/boards/arm/nrf52840dongle_nrf52840/board.c @@ -7,7 +7,7 @@ #include #include -static int board_nrf52840dongle_nrf52840_init(struct device *dev) +static int board_nrf52840dongle_nrf52840_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/nrf52840dongle_nrf52840/board.cmake b/boards/arm/nrf52840dongle_nrf52840/board.cmake index f9e8b2677284f1..49400cd244e176 100644 --- a/boards/arm/nrf52840dongle_nrf52840/board.cmake +++ b/boards/arm/nrf52840dongle_nrf52840/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf52840dongle_nrf52840/doc/index.rst b/boards/arm/nrf52840dongle_nrf52840/doc/index.rst index 859c0a09fb8e43..e822d12b412f16 100644 --- a/boards/arm/nrf52840dongle_nrf52840/doc/index.rst +++ b/boards/arm/nrf52840dongle_nrf52840/doc/index.rst @@ -35,9 +35,6 @@ More information about the board can be found at the `nRF52840 Dongle website`_. The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. -.. note:: - - In previous Zephyr releases this board was named *nrf52840_pca10059*. Hardware ******** @@ -295,6 +292,10 @@ Locate the DTS file for the board under: boards/arm/nrf52840dongle_nrf52840. This file requires a small modification to use a different partition table. Edit the include directive to include "fstab-debugger" instead of "fstab-stock". +In addition, the Kconfig file in the same directory must be modified by setting +``BOARD_HAS_NRF5_BOOTLOADER`` to be default ``n``, otherwise the code will be +flashed with an offset. + Then build and flash applications as usual (see :ref:`build_an_application` and :ref:`application_run` for more details). diff --git a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig index a5e5f12bfdcb69..37b621689bab0c 100644 --- a/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig +++ b/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840_defconfig @@ -7,13 +7,12 @@ CONFIG_BOARD_NRF52840DONGLE_NRF52840=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable GPIO CONFIG_GPIO=y -# Enable UART driver, needed for CDC ACM -CONFIG_SERIAL=y -CONFIG_UART_INTERRUPT_DRIVEN=y - # enable console CONFIG_CONSOLE=y diff --git a/boards/arm/nrf52_adafruit_feather/board.cmake b/boards/arm/nrf52_adafruit_feather/board.cmake index c7ab9b4254f829..af59a08bbda8b2 100644 --- a/boards/arm/nrf52_adafruit_feather/board.cmake +++ b/boards/arm/nrf52_adafruit_feather/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") board_runner_args(pyocd "--target=nrf52" "--frequency=4000000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts index 6d7cd1fb14af28..3dd577fb7e51f6 100644 --- a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts +++ b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather.dts @@ -13,6 +13,10 @@ model = "nRF52 Adafruit Feather"; compatible = "adafruit,nrf52_adafruit_feather"; + aliases { + pwm-led0 = &red_pwm_led; + }; + chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; @@ -43,6 +47,16 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + red_pwm_led: pwm_led_0 { + pwms = <&pwm0 17>; + }; + blue_pwm_led: pwm_led_1 { + pwms = <&pwm0 19>; + }; + }; + buttons { compatible = "gpio-keys"; button0: button_0 { @@ -75,10 +89,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -106,3 +117,9 @@ }; }; }; + +&pwm0 { + status = "okay"; + ch0-pin = <17>; + ch0-inverted; +}; diff --git a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig index e6f314f2dcdfec..440d326ccb5630 100644 --- a/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig +++ b/boards/arm/nrf52_adafruit_feather/nrf52_adafruit_feather_defconfig @@ -12,7 +12,6 @@ CONFIG_GPIO=y # enable uart driver CONFIG_SERIAL=y -CONFIG_UART_0_NRF_FLOW_CONTROL=n # enable console CONFIG_CONSOLE=y diff --git a/boards/arm/nrf52_blenano2/nrf52_blenano2.dts b/boards/arm/nrf52_blenano2/nrf52_blenano2.dts index 73ae483ddd4310..3c9f87fa0f2cbb 100644 --- a/boards/arm/nrf52_blenano2/nrf52_blenano2.dts +++ b/boards/arm/nrf52_blenano2/nrf52_blenano2.dts @@ -61,10 +61,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts b/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts index deb1c2a2895324..5714501c072c52 100644 --- a/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts +++ b/boards/arm/nrf52_sparkfun/nrf52_sparkfun.dts @@ -63,10 +63,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52dk_nrf52805/CMakeLists.txt b/boards/arm/nrf52dk_nrf52805/CMakeLists.txt new file mode 100644 index 00000000000000..d708ea8ca2169e --- /dev/null +++ b/boards/arm/nrf52dk_nrf52805/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +# The nrf52dk_nrf52805 board mirrors the nRF52 DK hardware. This needs +# to be considered by certain system initialization functionality residing +# in system_nrf52805.c and SoC dependent routines in nrfx_coredep.h. +zephyr_compile_definitions(DEVELOP_IN_NRF52832) +zephyr_compile_definitions(NRFX_COREDEP_DELAY_US_LOOP_CYCLES=3) diff --git a/boards/arm/nrf52dk_nrf52805/Kconfig b/boards/arm/nrf52dk_nrf52805/Kconfig new file mode 100644 index 00000000000000..50d0096e6de8b8 --- /dev/null +++ b/boards/arm/nrf52dk_nrf52805/Kconfig @@ -0,0 +1,10 @@ +# nRF52 DK nRF52805 board configuration + +# Copyright (c) 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on BOARD_NRF52DK_NRF52805 diff --git a/boards/arm/nrf52dk_nrf52805/Kconfig.board b/boards/arm/nrf52dk_nrf52805/Kconfig.board new file mode 100644 index 00000000000000..cf5fede2872659 --- /dev/null +++ b/boards/arm/nrf52dk_nrf52805/Kconfig.board @@ -0,0 +1,8 @@ +# nRF52 DK nRF52805 board configuration + +# Copyright (c) 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NRF52DK_NRF52805 + bool "nRF52 DK NRF52805" + depends on SOC_NRF52805_CAAA diff --git a/boards/arm/nrf52dk_nrf52805/Kconfig.defconfig b/boards/arm/nrf52dk_nrf52805/Kconfig.defconfig new file mode 100644 index 00000000000000..6fa1686219e0ff --- /dev/null +++ b/boards/arm/nrf52dk_nrf52805/Kconfig.defconfig @@ -0,0 +1,14 @@ +# nRF52 DK nRF52805 board configuration + +# Copyright (c) 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF52DK_NRF52805 + +config BOARD + default "nrf52dk_nrf52805" + +config BT_CTLR + default BT + +endif # BOARD_NRF52DK_NRF52805 diff --git a/boards/arm/nrf52dk_nrf52805/board.cmake b/boards/arm/nrf52dk_nrf52805/board.cmake new file mode 100644 index 00000000000000..87251af52c077a --- /dev/null +++ b/boards/arm/nrf52dk_nrf52805/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=nrf52" "--speed=4000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/boards/arm/nrf52dk_nrf52805/doc/index.rst b/boards/arm/nrf52dk_nrf52805/doc/index.rst new file mode 100644 index 00000000000000..121d1d508d04b2 --- /dev/null +++ b/boards/arm/nrf52dk_nrf52805/doc/index.rst @@ -0,0 +1,23 @@ +.. _nrf52dk_nrf52805: + +nRF52805 emulation on nRF52 DK +############################## + +Overview +******** + +The nrf52dk_nrf52805 board is a modified version of the :ref:`nrf52dk_nrf52832` +that enforces the limitations imposed by the nRF52805 IC, which is a +cost-reduced variant of the original nRF52832. Since Nordic does not offer a +development kit for the nRF52805, you can use this board to develop for this +IC while using the nRF52 Development Kit (PCA10040). + +See :ref:`nrf52dk_nrf52832` for more information about the development board and +`nRF52805 website`_ for the official reference on the IC itself. + +References +********** + +.. target-notes:: + +.. _nRF52805 website: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52805 diff --git a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts new file mode 100644 index 00000000000000..340035e32a2558 --- /dev/null +++ b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.dts @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Nordic nRF52 DK NRF52805"; + compatible = "nordic,nrf52-dk-nrf52805"; + + 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; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; + label = "Green LED 0"; + }; + led1: led_1 { + gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + label = "Green LED 1"; + }; + led2: led_2 { + gpios = <&gpio0 19 GPIO_ACTIVE_LOW>; + label = "Green LED 2"; + }; + led3: led_3 { + gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; + label = "Green LED 3"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + button0: button_0 { + label = "Push button switch 0"; + gpios = <&gpio0 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + button1: button_1 { + label = "Push button switch 1"; + gpios = <&gpio0 14 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + button2: button_2 { + label = "Push button switch 2"; + gpios = <&gpio0 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + button3: button_3 { + label = "Push button switch 3"; + gpios = <&gpio0 16 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + }; +}; + +&adc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&i2c0 { + compatible = "nordic,nrf-twi"; + status = "okay"; + sda-pin = <26>; + scl-pin = <27>; +}; + +&spi0 { + compatible = "nordic,nrf-spi"; + status = "okay"; + sck-pin = <29>; + mosi-pin = <31>; + miso-pin = <30>; +}; + +&uart0 { + compatible = "nordic,nrf-uarte"; + status = "okay"; + current-speed = <115200>; + tx-pin = <6>; + rx-pin = <8>; + rts-pin = <5>; + cts-pin = <7>; +}; + +&flash0 { + /* + * For more information, see: + * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0xc000>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0xd000>; + }; + slot1_partition: partition@19000 { + label = "image-1"; + reg = <0x00019000 0xd000>; + }; + scratch_partition: partition@26000 { + label = "image-scratch"; + reg = <0x00026000 0x3000>; + }; + storage_partition: partition@29000 { + label = "storage"; + reg = <0x00029000 0x00007000>; + }; + }; +}; diff --git a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.yaml b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.yaml new file mode 100644 index 00000000000000..cfbb098535a004 --- /dev/null +++ b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805.yaml @@ -0,0 +1,12 @@ +identifier: nrf52dk_nrf52805 +name: nRF52-DK-NRF52805 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - counter +ram: 24 +flash: 192 diff --git a/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig new file mode 100644 index 00000000000000..3372224a750d11 --- /dev/null +++ b/boards/arm/nrf52dk_nrf52805/nrf52dk_nrf52805_defconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52805_CAAA=y +CONFIG_BOARD_NRF52DK_NRF52805=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Additional board options +CONFIG_GPIO_AS_PINRESET=y + +# Bluetooth not enabled by default on nRF52805 due to RAM limitations when +# running the default set of kernel tests. diff --git a/boards/arm/nrf52dk_nrf52810/board.cmake b/boards/arm/nrf52dk_nrf52810/board.cmake index ca0a3abd7dcd55..87251af52c077a 100644 --- a/boards/arm/nrf52dk_nrf52810/board.cmake +++ b/boards/arm/nrf52dk_nrf52810/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf52dk_nrf52810/doc/index.rst b/boards/arm/nrf52dk_nrf52810/doc/index.rst index ed4a79cc805ded..8a767ca1b5b25d 100644 --- a/boards/arm/nrf52dk_nrf52810/doc/index.rst +++ b/boards/arm/nrf52dk_nrf52810/doc/index.rst @@ -15,9 +15,6 @@ IC while using the nRF52 Development Kit (PCA10040). See :ref:`nrf52dk_nrf52832` for more information about the development board and `nRF52810 website`_ for the official reference on the IC itself. -.. note:: - - In previous Zephyr releases this board was named *nrf52810_pca10040*. References ********** diff --git a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts index eb889a70d6cefc..842d31c27e2b83 100644 --- a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts +++ b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810.dts @@ -115,10 +115,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig index f506ac44525b7b..a12e283e8252eb 100644 --- a/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig +++ b/boards/arm/nrf52dk_nrf52810/nrf52dk_nrf52810_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF52DK_NRF52810=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable GPIO CONFIG_GPIO=y diff --git a/boards/arm/nrf52dk_nrf52832/board.cmake b/boards/arm/nrf52dk_nrf52832/board.cmake index 6963c54221771f..f99446d144d069 100644 --- a/boards/arm/nrf52dk_nrf52832/board.cmake +++ b/boards/arm/nrf52dk_nrf52832/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") board_runner_args(pyocd "--target=nrf52" "--frequency=4000000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf52dk_nrf52832/doc/index.rst b/boards/arm/nrf52dk_nrf52832/doc/index.rst index ec2ba272acf915..ffbc470f9a1411 100644 --- a/boards/arm/nrf52dk_nrf52832/doc/index.rst +++ b/boards/arm/nrf52dk_nrf52832/doc/index.rst @@ -36,9 +36,6 @@ More information about the board can be found at the `nRF52 DK website`_. The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. -.. note:: - - In previous Zephyr releases this board was named *nrf52_pca10040*. Hardware ******** diff --git a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts index 10eb9112c2da9a..3500294dd72e77 100644 --- a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts +++ b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts @@ -138,7 +138,7 @@ arduino_serial: &uart0 { status = "okay"; - compatible = "nordic,nrf-uart"; + compatible = "nordic,nrf-uarte"; current-speed = <115200>; tx-pin = <6>; rx-pin = <8>; @@ -190,14 +190,11 @@ arduino_spi: &spi2 { sck-pin = <25>; mosi-pin = <23>; miso-pin = <24>; - cs-gpios = <&arduino_header 16 0>; /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.yaml b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.yaml index be40a5b85c4c18..5a5337412c66de 100644 --- a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.yaml +++ b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.yaml @@ -13,6 +13,7 @@ supported: - arduino_gpio - arduino_i2c - arduino_spi + - gpio - counter - nvs - i2c diff --git a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig index 4d6bbee1b91965..2cabd8fe1c46d3 100644 --- a/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig +++ b/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF52DK_NRF52832=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable RTT CONFIG_USE_SEGGER_RTT=y diff --git a/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt b/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt new file mode 100644 index 00000000000000..c7665ec6dbec7a --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt @@ -0,0 +1,110 @@ +# Copyright (c) 2019 Nordic Semiconductor ASA. +# SPDX-License-Identifier: Apache-2.0 + +if (((CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPPNS) + OR (CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPPNS)) + AND CONFIG_BOARD_ENABLE_CPUNET) +zephyr_library() +zephyr_library_sources(nrf5340_cpunet_reset.c) +endif() + +if (CONFIG_BUILD_WITH_TFM) + # Set default image versions if not defined elsewhere + if (NOT DEFINED TFM_IMAGE_VERSION_S) + set(TFM_IMAGE_VERSION_S 0.0.0+0) + endif() + + if (NOT DEFINED TFM_IMAGE_VERSION_NS) + set(TFM_IMAGE_VERSION_NS 0.0.0+0) + endif() + + if (NOT CONFIG_TFM_BL2_FALSE) + set(PREPROCESSED_FILE_S "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.o") + set(PREPROCESSED_FILE_NS "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_ns.dir/signing_layout_ns.o") + set(TFM_MCUBOOT_DIR "${ZEPHYR_TFM_MODULE_DIR}/trusted-firmware-m/bl2/ext/mcuboot") + endif() + + # Configure which format (full or hash) to include the public key in + # the image manifest + if(NOT DEFINED TFM_PUBLIC_KEY_FORMAT) + set(TFM_PUBLIC_KEY_FORMAT "full") + endif() + + if(CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPPNS) + set(TFM_INSTALL_DIR ${CMAKE_BINARY_DIR}/tfm/install/outputs/NORDIC_NRF/NRF5340PDK_NRF5340_CPUAPP) + elseif(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPPNS) + set(TFM_INSTALL_DIR ${CMAKE_BINARY_DIR}/tfm/install/outputs/NORDIC_NRF/NRF5340DK_NRF5340_CPUAPP) + endif() + + # Set srec_cat binary name + find_program(SREC_CAT srec_cat) + if(${SREC_CAT} STREQUAL SREC_CAT-NOTFOUND) + message(FATAL_ERROR "'srec_cat' not found. Please install it, or add it to $PATH.") + endif() + + if (CONFIG_TFM_BL2_FALSE) + # Merge tfm_s and zephyr (NS) image to a single binary. + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${SREC_CAT} + ARGS ${CMAKE_BINARY_DIR}/tfm/bin/tfm_s.bin -Binary + ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} -Binary + -offset ${CONFIG_FLASH_LOAD_OFFSET} + -o ${CMAKE_BINARY_DIR}/tfm_merged.hex -intel + + # Copy tfm_sign.hex to zephyr + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm_merged.hex ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME} + ) + else() + #Create and sign for concatenated binary image, should align with the TF-M BL2 + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + + #Sign secure binary image with public key + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_S} + -k ${CONFIG_TFM_KEY_FILE_S} + --public-key-format ${TFM_PUBLIC_KEY_FORMAT} + --align 1 + -v ${TFM_IMAGE_VERSION_S} + --pad + --pad-header + ${ADD_NS_IMAGE_MIN_VER} + -s auto + -H 0x400 + ${TFM_INSTALL_DIR}/tfm_s.bin + ${CMAKE_BINARY_DIR}/tfm_s_signed.bin + + #Sign non-secure binary image with public key + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_NS} + -k ${CONFIG_TFM_KEY_FILE_NS} + --public-key-format ${TFM_PUBLIC_KEY_FORMAT} + --align 1 + -v ${TFM_IMAGE_VERSION_NS} + -s auto + ${ADD_S_IMAGE_MIN_VER} + -H 0x400 + ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} + ${CMAKE_BINARY_DIR}/zephyr_ns_signed.bin + + #Create concatenated binary image from the two independently signed binary files + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/assemble.py + --layout ${PREPROCESSED_FILE_S} + -s ${CMAKE_BINARY_DIR}/tfm_s_signed.bin + -n ${CMAKE_BINARY_DIR}/zephyr_ns_signed.bin + -o ${CMAKE_BINARY_DIR}/tfm_sign.bin + + #Copy mcuboot.bin + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm/bin/bl2.bin ${CMAKE_BINARY_DIR}/mcuboot.bin + + # Generate an intel hex file from the signed output binary + COMMAND srec_cat ${CMAKE_BINARY_DIR}/tfm_sign.bin + -binary + -offset 0x10000 + -o ${CMAKE_BINARY_DIR}/tfm_sign.hex + -intel + + # Copy tfm_sign.hex to zephyr + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm_sign.hex ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME} + ) + endif() +endif() diff --git a/boards/arm/nrf5340dk_nrf5340/Kconfig b/boards/arm/nrf5340dk_nrf5340/Kconfig new file mode 100644 index 00000000000000..f2cf86257b97ff --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/Kconfig @@ -0,0 +1,79 @@ +# nRF5340 (P)DK board configuration + +# Copyright (c) 2019 - 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS || BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPPNS + +config BOARD_ENABLE_DCDC_APP + bool "Enable Application MCU DCDC converter" + select SOC_DCDC_NRF53X_APP + default y + +config BOARD_ENABLE_DCDC_NET + bool "Enable Network MCU DCDC converter" + select SOC_DCDC_NRF53X_NET + default y + +config BOARD_ENABLE_DCDC_HV + bool "Enable High Voltage DCDC converter" + select SOC_DCDC_NRF53X_HV + default y + +choice BT_HCI_BUS_TYPE + default BT_RPMSG if BT +endchoice + +config HEAP_MEM_POOL_SIZE + default 4096 if BT_RPMSG + +config BT_HAS_HCI_VS + default y if BT + +config BOARD_ENABLE_CPUNET + bool "Enable nRF53 Network MCU" + help + This option enables releasing the Network 'force off' signal, which + as a consequence will power up the Network MCU during system boot. + Additionally, the option allocates GPIO pins that will be used by UARTE + of the Network MCU. + Note: GPIO pin allocation can only be configured by the secure Application + MCU firmware, so when this option is used with the non-secure version of + the board, the application needs to take into consideration, that the + secure firmware image must already have configured GPIO allocation for the + Network MCU. + default y if (BT || NRF_802154_SER_HOST) + +config DOMAIN_CPUNET_BOARD + string + default "nrf5340pdk_nrf5340_cpunet" if BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS + default "nrf5340dk_nrf5340_cpunet" if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPPNS + depends on BOARD_ENABLE_CPUNET + help + The board which will be used for CPUNET domain when creating a multi + image application where one or more images should be located on + another board. For example hci_rpmsg on the nRF5340_cpunet for + Bluetooth applications. + +endif # BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS || BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPPNS + +if BOARD_NRF5340PDK_NRF5340_CPUNET || BOARD_NRF5340DK_NRF5340_CPUNET + +# BT_CTLR depends on BT. When BT is enabled we should default to also +# enabling the controller. +config BT_CTLR + default y if BT + +config BT_ECC + default y if BT + +config DOMAIN_CPUAPP_BOARD + string + default "nrf5340pdk_nrf5340_cpuapp" if BOARD_NRF5340PDK_NRF5340_CPUNET + default "nrf5340dk_nrf5340_cpuapp" if BOARD_NRF5340DK_NRF5340_CPUNET + help + The board which will be used for CPUAPP domain when creating a multi + image application where one or more images should be located on + another board. + +endif # BOARD_NRF5340PDK_NRF5340_CPUNET || BOARD_NRF5340DK_NRF5340_CPUNET diff --git a/boards/arm/nrf5340dk_nrf5340/Kconfig.board b/boards/arm/nrf5340dk_nrf5340/Kconfig.board new file mode 100644 index 00000000000000..3031db8f4f71ef --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/Kconfig.board @@ -0,0 +1,28 @@ +# nRF5340 (P)DK NRF5340 board configuration + +# Copyright (c) 2019-2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF5340_CPUAPP_QKAA + +config BOARD_NRF5340PDK_NRF5340_CPUAPP + bool "nRF5340 PDK nRF5340 Application MCU" + +config BOARD_NRF5340PDK_NRF5340_CPUAPPNS + bool "nRF5340 PDK nRF5340 Application MCU non-secure" + +config BOARD_NRF5340DK_NRF5340_CPUAPP + bool "nRF5340 DK nRF5340 Application MCU" + +config BOARD_NRF5340DK_NRF5340_CPUAPPNS + bool "nRF5340 DK nRF5340 Application MCU non-secure" + +endif # SOC_NRF5340_CPUAPP_QKAA + +config BOARD_NRF5340PDK_NRF5340_CPUNET + bool "nRF5340 PDK NRF5340 Network MCU" + depends on SOC_NRF5340_CPUNET_QKAA + +config BOARD_NRF5340DK_NRF5340_CPUNET + bool "nRF5340 DK NRF5340 Network MCU" + depends on SOC_NRF5340_CPUNET_QKAA diff --git a/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig b/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig new file mode 100644 index 00000000000000..412707ac22d3a2 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/Kconfig.defconfig @@ -0,0 +1,99 @@ +# nRF5340 (P)DK nRF5340 board configuration + +# Copyright (c) 2019-2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS || BOARD_NRF5340PDK_NRF5340_CPUNET + +config BOARD_DEPRECATED_RELEASE + default "v2.6.0" + +endif # BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS || BOARD_NRF5340PDK_NRF5340_CPUNET + +if BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS || BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPPNS + +config BOARD + default "nrf5340pdk_nrf5340_cpuapp" if BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS + default "nrf5340dk_nrf5340_cpuapp" if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPPNS + +# By default, if we build for a Non-Secure version of the board, +# force building with TF-M as the Secure Execution Environment. + +config BUILD_WITH_TFM + default y if BOARD_NRF5340DK_NRF5340_CPUAPPNS || BOARD_NRF5340PDK_NRF5340_CPUAPPNS + +if BUILD_WITH_TFM + +# By default, force building TF-M without bootloader support. + +choice TFM_BL2 + bool + prompt "BL2 configuration, should TFM build with MCUboot support" + default TFM_BL2_FALSE +endchoice + +endif # BUILD_WITH_TFM + +# Code Partition: +# +# For the secure version of the board the firmware is linked at the beginning +# of the flash, or into the code-partition defined in DT if it is intended to +# be loaded by MCUboot. If the secure firmware is to be combined with a non- +# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always +# be restricted to the size of its code partition. +# +# For the non-secure version of the board, the firmware +# must be linked into the code-partition (non-secure) defined in DT, regardless. +# Apply this configuration below by setting the Kconfig symbols used by +# the linker according to the information extracted from DT partitions. + +# SRAM Partition: +# +# If the secure firmware is to be combined with a non-secure image +# (TRUSTED_EXECUTION_SECURE=y), the secure FW image SRAM shall always +# be restricted to the secure image SRAM partition (sram-secure-partition). +# Otherwise (if TRUSTED_EXECUTION_SECURE is not set) the whole zephyr,sram +# may be used by the image. +# +# For the non-secure version of the board, the firmware image SRAM is +# always restricted to the allocated non-secure SRAM partition. +# +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition +DT_CHOSEN_Z_SRAM_PARTITION := zephyr,sram-secure-partition + +if (BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP) && TRUSTED_EXECUTION_SECURE + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config SRAM_SIZE + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_SRAM_PARTITION),0,K) + +endif # (BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP) && TRUSTED_EXECUTION_SECURE + +if BOARD_NRF5340PDK_NRF5340_CPUAPPNS || BOARD_NRF5340DK_NRF5340_CPUAPPNS + +config FLASH_LOAD_OFFSET + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +endif # BOARD_NRF5340PDK_NRF5340_CPUAPPNS || BOARD_NRF5340DK_NRF5340_CPUAPPNS + +if (BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPPNS) && USB + +config USB_NRFX + default y + +config USB_DEVICE_STACK + default y + +endif # (BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPPNS) && USB + +endif # BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS || BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPPNS + +config BOARD + default "nrf5340pdk_nrf5340_cpunet" if BOARD_NRF5340PDK_NRF5340_CPUNET + default "nrf5340dk_nrf5340_cpunet" if BOARD_NRF5340DK_NRF5340_CPUNET diff --git a/boards/arm/nrf5340dk_nrf5340/board.cmake b/boards/arm/nrf5340dk_nrf5340/board.cmake new file mode 100644 index 00000000000000..d651125937cc9d --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/board.cmake @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPPNS OR CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPPNS) + set(TFM_PUBLIC_KEY_FORMAT "full") +endif() + +if((CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPPNS) OR + (CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPPNS)) +board_runner_args(jlink "--device=nrf5340_xxaa_app" "--speed=4000") +endif() + +if(CONFIG_BOARD_NRF5340PDK_NRF5340_CPUNET OR CONFIG_BOARD_NRF5340DK_NRF5340_CPUNET) +board_runner_args(jlink "--device=nrf5340_xxaa_net" "--speed=4000") +endif() + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf5340dk_nrf5340/doc/img/nrf5340dk.jpg b/boards/arm/nrf5340dk_nrf5340/doc/img/nrf5340dk.jpg new file mode 100644 index 00000000000000..c9ac685e4a1080 Binary files /dev/null and b/boards/arm/nrf5340dk_nrf5340/doc/img/nrf5340dk.jpg differ diff --git a/boards/arm/nrf5340dk_nrf5340/doc/index.rst b/boards/arm/nrf5340dk_nrf5340/doc/index.rst new file mode 100644 index 00000000000000..bae6819a89f3a4 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/doc/index.rst @@ -0,0 +1,337 @@ +.. _nrf5340dk_nrf5340: + +nRF5340 DK +########## + +Overview +******** + +The nRF5340 DK (PCA10095) is a single-board development kit for evaluation +and development on the Nordic nRF5340 System-on-Chip (SoC). + +The nRF5340 is a dual-core SoC based on the Arm® Cortex®-M33 architecture, with: + +* a full-featured Arm Cortex-M33F core with DSP instructions, FPU, and + Armv8-M Security Extension, running at up to 128 MHz, referred to as + the **application core** +* a secondary Arm Cortex-M33 core, with a reduced feature set, running at + a fixed 64 MHz, referred to as the **network core**. + +The nrf5340dk_nrf5340_cpuapp build target provides support for the application +core on the nRF5340 SoC. The nrf5340dk_nrf5340_cpunet build target provides +support for the network core on the nRF5340 SoC. + +nRF5340 SoC provides support for the following devices: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`IDAU (Implementation Defined Attribution Unit)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UARTE (Universal asynchronous receiver-transmitter)` +* :abbr:`USB (Universal Serial Bus)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/nrf5340dk.jpg + :width: 711px + :align: center + :alt: nRF5340 DK + + nRF5340 DK (Credit: Nordic Semiconductor) + +More information about the board can be found at the +`nRF5340 DK website`_. +The `Nordic Semiconductor Infocenter`_ +contains the processor's information and the datasheet. + +.. note:: + + nRF5340 PDK (preview development kit) is an earlier version of the + nRF5340 DK. nRF5340 PDK board is deprecated and is replaced by nRF5340 DK. + The support for nRF5340 PDK will be removed in Zephyr v2.6.0 release. + + +Hardware +******** + +nRF5340 DK has two external oscillators. The frequency of +the slow clock is 32.768 kHz. The frequency of the main clock +is 32 MHz. + +Supported Features +================== + +The nrf5340dk_nrf5340_cpuapp board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| SPU | on-chip | system protection | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| USB | on-chip | usb | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +The nrf5340dk_nrf5340_cpunet board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth, | +| | | ieee802154 | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Other hardware features are not supported by the Zephyr kernel. +See `Nordic Semiconductor Infocenter`_ +for a complete list of nRF5340 DK board hardware features. + +Connections and IOs +=================== + +LED +--- + +* LED1 (green) = P0.28 +* LED2 (green) = P0.29 +* LED3 (green) = P0.30 +* LED4 (green) = P0.31 + +Push buttons +------------ + +* BUTTON1 = SW1 = P0.23 +* BUTTON2 = SW2 = P0.24 +* BUTTON3 = SW3 = P0.8 +* BUTTON4 = SW4 = P0.9 +* BOOT = SW5 = boot/reset + +Security components +=================== + +- Implementation Defined Attribution Unit (`IDAU`_) on the application core. + The IDAU is implemented with the System Protection Unit and is used to + define secure and non-secure memory maps. By default, all of the memory + space (Flash, SRAM, and peripheral address space) is defined to be secure + accessible only. +- Secure boot. + +Programming and Debugging +************************* + +nRF5340 application core supports the Armv8-M Security Extension. +Applications build for the nrf5340dk_nrf5340_cpuapp board by default +boot in the Secure state. + +nRF5340 network core does not support the Armv8-M Security Extension. +nRF5340 IDAU may configure bus accesses by the nRF5340 network core +to have Secure attribute set; the latter allows to build and run +Secure only applications on the nRF5340 SoC. + +Building Secure/Non-Secure Zephyr applications with Arm |reg| TrustZone |reg| +============================================================================= + +Applications on the nRF5340 may contain a Secure and a Non-Secure firmware +image for the application core. The Secure image can be built using either +Zephyr or `Trusted Firmware M`_ (TF-M). Non-Secure firmware +images are always built using Zephyr. The two alternatives are described below. + +.. note:: + + By default the the Secure image for nRF5340 application core is built + using TF-M. + + +Building the Secure firmware with TF-M +-------------------------------------- + +The process to build the Secure firmware image using TF-M and the Non-Secure +firmware image using Zephyr requires the following steps: + +1. Build the Non-Secure Zephyr application + for the application core using ``-DBOARD=nrf5340dk_nrf5340_cpuappns``. + To invoke the building of TF-M the Zephyr build system requires the + Kconfig option ``BUILD_WITH_TFM`` to be enabled, which is done by + default when building Zephyr as a Non-Secure application. + The Zephyr build system will perform the following steps automatically: + + * Build the Non-Secure firmware image as a regular Zephyr application + * Build a TF-M (secure) firmware image + * Merge the output image binaries together + * Optionally build a bootloader image (MCUboot) + +.. note:: + + Depending on the TF-M configuration, an application DTS overlay may be + required, to adjust the Non-Secure image Flash and SRAM starting address + and sizes. + +2. Build the application firmware for the network core using + ``-DBOARD=nrf5340dk_nrf5340_cpunet``. + + +Building the Secure firmware using Zephyr +----------------------------------------- + +The process to build the Secure and the Non-Secure firmware images +using Zephyr requires the following steps: + +1. Build the Secure Zephyr application for the application core + using ``-DBOARD=nrf5340dk_nrf5340_cpuapp`` and + ``CONFIG_TRUSTED_EXECUTION_SECURE=y`` and ``CONFIG_BUILD_WITH_TFM=n`` + in the application project configuration file. +2. Build the Non-Secure Zephyr application for the application core + using ``-DBOARD=nrf5340dk_nrf5340_cpuappns``. +3. Merge the two binaries together. +4. Build the application firmware for the network core using + ``-DBOARD=nrf5340dk_nrf5340_cpunet``. + + +When building a Secure/Non-Secure application for the nRF5340 application core, +the Secure application will have to set the IDAU (SPU) configuration to allow +Non-Secure access to all CPU resources utilized by the Non-Secure application +firmware. SPU configuration shall take place before jumping to the Non-Secure +application. + +Building a Secure only application +================================== + +Build the Zephyr app in the usual way (see :ref:`build_an_application` +and :ref:`application_run`), using ``-DBOARD=nrf5340dk_nrf5340_cpuapp`` for +the firmware running on the nRF5340 application core, and using +``-DBOARD=nrf5340dk_nrf5340_cpunet`` for the firmware running +on the nRF5340 network core. + +Flashing +======== + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. Then you can build and flash +applications as usual (:ref:`build_an_application` and +:ref:`application_run` for more details). + +.. warning:: + + The nRF5340 has a flash read-back protection feature. When flash read-back + protection is active, you will need to recover the chip before reflashing. + If you are flashing with :ref:`west `, run + this command for more details on the related ``--recover`` option: + + .. code-block:: console + + west flash -H -r nrfjprog --skip-rebuild + +.. note:: + + Flashing and debugging applications on the nRF5340 DK requires + upgrading the nRF Command Line Tools to version 10.12.0. Further + information on how to install the nRF Command Line Tools can be + found in :ref:`nordic_segger_flashing`. + +Here is an example for the :ref:`hello_world` application running on the +nRF5340 application core. + +First, run your favorite terminal program to listen for output. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the board nRF5340 DK +can be found. For example, under Linux, :code:`/dev/ttyACM0`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nrf5340dk_nrf5340_cpuapp + :goals: build flash + +Debugging +========= + +Refer to the :ref:`nordic_segger` page to learn about debugging Nordic +boards with a Segger IC. + + +Testing the LEDs and buttons in the nRF5340 DK +********************************************** + +There are 2 samples that allow you to test that the buttons (switches) and +LEDs on the board are working properly with Zephyr: + +* :ref:`blinky-sample` +* :ref:`button-sample` + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in +:zephyr_file:`boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dts`. + +References +********** + +.. target-notes:: + +.. _IDAU: + https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau +.. _nRF5340 DK website: + https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF5340-PDK +.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dts new file mode 100644 index 00000000000000..bd624bac93ad3f --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dts @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2019-2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + label = "Green LED 0"; + }; + led1: led_1 { + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; + label = "Green LED 1"; + }; + led2: led_2 { + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + label = "Green LED 2"; + }; + led3: led_3 { + gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; + label = "Green LED 3"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + }; + button1: button_1 { + gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + }; + button2: button_2 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + }; + button3: button_3 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 4"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c1 { + compatible = "nordic,nrf-twim"; + status = "okay"; + sda-pin = <34>; + scl-pin = <35>; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + tx-pin = <20>; + rx-pin = <22>; + rts-pin = <19>; + cts-pin = <21>; +}; + +&pwm0 { + status = "okay"; + ch0-pin = <28>; +}; + +&qspi { + status = "okay"; + sck-pin = <17>; + io-pins = <13>, <14>, <15>, <16>; + csn-pins = <18>; + mx25r64: mx25r6435f@0 { + compatible = "nordic,qspi-nor"; + reg = <0>; + /* MX24R64 supports only pp and pp4io */ + writeoc = "pp4io"; + /* MX24R64 supports all readoc options */ + readoc = "read4io"; + sck-frequency = <8000000>; + label = "MX25R64"; + jedec-id = [c2 28 17]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 03 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f5 00 82 ed 04 cc 44 83 68 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; + size = <67108864>; + has-dpd; + t-enter-dpd = <10000>; + t-exit-dpd = <35000>; + }; +}; + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&timer2 { + status = "okay"; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x00010000>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + }; + slot0_ns_partition: partition@50000 { + label = "image-0-nonsecure"; + }; + slot1_partition: partition@80000 { + label = "image-1"; + }; + slot1_ns_partition: partition@c0000 { + label = "image-1-nonsecure"; + }; + scratch_partition: partition@f0000 { + label = "image-scratch"; + reg = <0x000f0000 0xa000>; + }; + storage_partition: partition@fa000 { + label = "storage"; + reg = <0x000fa000 0x00006000>; + }; + }; +}; + +/ { + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_image: image@20000000 { + /* Zephyr image(s) memory */ + }; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + }; + + sram0_ns: image_ns@20040000 { + /* Non-Secure image memory */ + }; + }; +}; + +/* Include partition configuration file */ +#include "nrf5340_cpuapp_partition_conf.dts" diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_partition_conf.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_partition_conf.dts new file mode 100644 index 00000000000000..b0cd4dcdc667ad --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_partition_conf.dts @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019-2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Default Flash planning for nrf5340pdk_nrf5340 CPUAPP (Application MCU). + * + * Zephyr build for nRF5340 with ARM TrustZone-M support, + * implies building Secure and Non-Secure Zephyr images. + * + * Secure image will be placed, by default, in flash0 + * (or in slot0, if MCUboot is present). + * Secure image will use sram0 for system memory. + * + * Non-Secure image will be placed in slot0_ns, and use + * sram0_ns for system memory. + * + * Note that the Secure image only requires knowledge of + * the beginning of the Non-Secure image (not its size). + */ + +&slot0_partition { + reg = <0x00010000 0x40000>; +}; + +&slot0_ns_partition { + reg = <0x00050000 0x30000>; +}; + +&slot1_partition { + reg = <0x00080000 0x40000>; +}; + +&slot1_ns_partition { + reg = <0x000c0000 0x30000>; +}; + +/* Default SRAM planning when building for nRF5340 with + * ARM TrustZone-M support + * - Lowest 256 kB SRAM allocated to Secure image (sram0_s) + * - Middle 192 kB allocated to Non-Secure image (sram0_ns) + * - Upper 64 kB SRAM allocated as Shared memory (sram0_shared) + * (see nrf5340_shared_sram_planning_conf.dts) + */ +&sram0_image { + reg = <0x20000000 DT_SIZE_K(448)>; +}; + +&sram0_s { + reg = <0x20000000 0x40000>; +}; + +&sram0_ns { + reg = <0x20040000 0x30000>; +}; + +/* Include shared RAM configuration file */ +#include "nrf5340_shared_sram_planning_conf.dts" diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c new file mode 100644 index 00000000000000..a09bfe4cf58c3c --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019-2020 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(nrf5340pdk_nrf5340_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); + +/* Shared memory definitions */ +#if DT_HAS_CHOSEN(zephyr_ipc_shm) +#define SHM_NODE DT_CHOSEN(zephyr_ipc_shm) +#define SHM_BASE_ADDRESS DT_REG_ADDR(SHM_NODE) +#define SHM_SIZE DT_REG_SIZE(SHM_NODE) +#endif + +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) + +/* This should come from DTS, possibly an overlay. */ +#if defined(CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPP) +#define CPUNET_UARTE_PIN_TX 25 +#define CPUNET_UARTE_PIN_RX 26 +#define CPUNET_UARTE_PORT_TRX NRF_P0 +#define CPUNET_UARTE_PIN_RTS 10 +#define CPUNET_UARTE_PIN_CTS 12 +#elif defined(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP) +#define CPUNET_UARTE_PIN_TX 1 +#define CPUNET_UARTE_PIN_RX 0 +#define CPUNET_UARTE_PORT_TRX NRF_P1 +#define CPUNET_UARTE_PIN_RTS 11 +#define CPUNET_UARTE_PIN_CTS 10 +#endif + +#if defined(CONFIG_BT_CTLR_DEBUG_PINS_CPUAPP) +#include <../subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/debug.h> +#else +#define DEBUG_SETUP() +#endif + +static void remoteproc_mgr_config(void) +{ + /* UARTE */ + /* Assign specific GPIOs that will be used to get UARTE from + * nRF5340 Network MCU. + */ + CPUNET_UARTE_PORT_TRX->PIN_CNF[CPUNET_UARTE_PIN_TX] = + GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos; + CPUNET_UARTE_PORT_TRX->PIN_CNF[CPUNET_UARTE_PIN_RX] = + GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos; + NRF_P0->PIN_CNF[CPUNET_UARTE_PIN_RTS] = + GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos; + NRF_P0->PIN_CNF[CPUNET_UARTE_PIN_CTS] = + GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos; + + /* Route Bluetooth Controller Debug Pins */ + DEBUG_SETUP(); + + /* Retain nRF5340 Network MCU in Secure domain (bus + * accesses by Network MCU will have Secure attribute set). + */ + NRF_SPU->EXTDOMAIN[0].PERM = 1 << 4; +} +#endif /* !CONFIG_TRUSTED_EXECUTION_NONSECURE */ + +static int remoteproc_mgr_boot(const struct device *dev) +{ + ARG_UNUSED(dev); + +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) + /* Secure domain may configure permissions for the Network MCU. */ + remoteproc_mgr_config(); +#endif /* !CONFIG_TRUSTED_EXECUTION_NONSECURE */ + +#if !defined(CONFIG_TRUSTED_EXECUTION_SECURE) + /* + * Building Zephyr with CONFIG_TRUSTED_EXECUTION_SECURE=y implies + * building also a Non-Secure image. The Non-Secure image will, in + * this case do the remainder of actions to properly configure and + * boot the Network MCU. + */ +#if defined(SHM_BASE_ADDRESS) && (SHM_BASE_ADDRESS != 0) + + /* Initialize inter-processor shared memory block to zero. It is + * assumed that the application image has access to the shared + * memory at this point (see #24147). + */ + memset((void *) SHM_BASE_ADDRESS, 0, SHM_SIZE); +#endif + + /* Release the Network MCU, 'Release force off signal' */ + NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; + + LOG_DBG("Network MCU released."); +#endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ + + return 0; +} + +SYS_INIT(remoteproc_mgr_boot, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_shared_sram_planning_conf.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340_shared_sram_planning_conf.dts similarity index 100% rename from boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_shared_sram_planning_conf.dts rename to boards/arm/nrf5340dk_nrf5340/nrf5340_shared_sram_planning_conf.dts diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.dts new file mode 100644 index 00000000000000..8a5f87e432b319 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.dts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf5340_cpuapp_common.dts" + +/ { + model = "Nordic NRF5340 DK NRF5340 Application"; + compatible = "nordic,nrf5340-dk-nrf5340-cpuapp"; + + chosen { + zephyr,sram = &sram0_image; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,sram-secure-partition = &sram0_s; + zephyr,sram-non-secure-partition = &sram0_ns; + }; +}; + +&spi2 { + compatible = "nordic,nrf-spim"; + status = "okay"; + sck-pin = <47>; + miso-pin = <46>; + mosi-pin = <45>; +}; + +&usbd { + compatible = "nordic,nrf-usbd"; + status = "okay"; +}; diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.yaml b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.yaml new file mode 100644 index 00000000000000..2e468327694ed2 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.yaml @@ -0,0 +1,17 @@ +identifier: nrf5340dk_nrf5340_cpuapp +name: NRF5340-DK-NRF5340-application-MCU +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 64 +flash: 256 +supported: + - gpio + - i2c + - pwm + - watchdog + - usb_cdc + - usb_device diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig new file mode 100644 index 00000000000000..22e8f52ff31cb5 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUAPP_QKAA=y +CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuappns.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuappns.dts new file mode 100644 index 00000000000000..5e3189d7dc35d0 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuappns.dts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf5340_cpuapp_common.dts" + +/ { + model = "Nordic NRF5340 DK NRF5340 Application"; + compatible = "nordic,nrf5340-dk-nrf5340-cpuapp"; + + chosen { + zephyr,sram = &sram0_ns; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_ns_partition; + }; +}; + +&usbd { + compatible = "nordic,nrf-usbd"; + status = "okay"; +}; diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuappns.yaml b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuappns.yaml new file mode 100644 index 00000000000000..d1eb88396a453a --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuappns.yaml @@ -0,0 +1,16 @@ +identifier: nrf5340dk_nrf5340_cpuappns +name: NRF5340-DK-NRF5340-application-MCU-Non-Secure +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 192 +flash: 192 +supported: + - i2c + - pwm + - watchdog + - usb_cdc + - usb_device diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuappns_defconfig b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuappns_defconfig new file mode 100644 index 00000000000000..49c78ba60a67b5 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuappns_defconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUAPP_QKAA=y +CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPPNS=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# This Board implies building Non-Secure firmware +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.dts new file mode 100644 index 00000000000000..64a87a733104cf --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.dts @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Nordic NRF5340 DK NRF5340 Network"; + compatible = "nordic,nrf5340-dk-nrf5340-cpunet"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + zephyr,sram = &sram1; + zephyr,flash = &flash1; + zephyr,code-partition = &slot0_partition; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + label = "Green LED 0"; + }; + led1: led_1 { + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; + label = "Green LED 1"; + }; + led2: led_2 { + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + label = "Green LED 2"; + }; + led3: led_3 { + gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; + label = "Green LED 3"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + }; + button1: button_1 { + gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + }; + button2: button_2 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + }; + button3: button_3 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 4"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + }; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + tx-pin = <33>; + rx-pin = <32>; + rts-pin = <11>; + cts-pin = <10>; +}; + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&timer2 { + status = "okay"; +}; + +&flash1 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0xc000>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0x12000>; + }; + slot1_partition: partition@1e000 { + label = "image-1"; + reg = <0x0001E000 0x12000>; + }; + scratch_partition: partition@30000 { + label = "image-scratch"; + reg = <0x00030000 0xa000>; + }; + storage_partition: partition@3a000 { + label = "storage"; + reg = <0x0003a000 0x6000>; + }; + }; +}; + +/* Include shared RAM configuration file */ +#include "nrf5340_shared_sram_planning_conf.dts" diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.yaml b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.yaml new file mode 100644 index 00000000000000..06770d5b610f10 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.yaml @@ -0,0 +1,12 @@ +identifier: nrf5340dk_nrf5340_cpunet +name: NRF5340-DK-NRF5340-network-MCU +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 64 +flash: 256 +supported: + - watchdog diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet_defconfig b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet_defconfig new file mode 100644 index 00000000000000..47f7b157d06c26 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF53X=y +CONFIG_SOC_NRF5340_CPUNET_QKAA=y +CONFIG_BOARD_NRF5340DK_NRF5340_CPUNET=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable GPIO +CONFIG_GPIO=y + +# Enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuapp.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuapp.dts new file mode 100644 index 00000000000000..6c94620bb3f0d8 --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuapp.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019-2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf5340_cpuapp_common.dts" + +/ { + model = "Nordic NRF5340 PDK NRF5340 Application"; + compatible = "nordic,nrf5340-pdk-nrf5340-cpuapp"; + + chosen { + zephyr,sram = &sram0_image; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,sram-secure-partition = &sram0_s; + zephyr,sram-non-secure-partition = &sram0_ns; + }; +}; diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp.yaml b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuapp.yaml similarity index 95% rename from boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp.yaml rename to boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuapp.yaml index fb2d266065390c..2eaeee1af6df66 100644 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp.yaml +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuapp.yaml @@ -9,6 +9,7 @@ toolchain: ram: 64 flash: 256 supported: + - gpio - i2c - pwm - watchdog diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_defconfig b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuapp_defconfig similarity index 77% rename from boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_defconfig rename to boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuapp_defconfig index 430a0dfb40c107..4a4b938b5739a2 100644 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_defconfig +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuapp_defconfig @@ -4,9 +4,14 @@ CONFIG_SOC_SERIES_NRF53X=y CONFIG_SOC_NRF5340_CPUAPP_QKAA=y CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPP=y +CONFIG_NRF5340_CPUAPP_ERRATUM19=y + # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable TrustZone-M CONFIG_ARM_TRUSTZONE_M=y diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuappns.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuappns.dts new file mode 100644 index 00000000000000..1276185f7886cb --- /dev/null +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuappns.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2019-2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf5340_cpuapp_common.dts" + +/ { + model = "Nordic NRF5340 PDK NRF5340 Application"; + compatible = "nordic,nrf5340-pdk-nrf5340-cpuapp"; + + chosen { + zephyr,sram = &sram0_ns; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_ns_partition; + }; +}; diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuappns.yaml b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuappns.yaml similarity index 90% rename from boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuappns.yaml rename to boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuappns.yaml index ddf4547455ddcd..8b888601bc5e41 100644 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuappns.yaml +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuappns.yaml @@ -6,8 +6,8 @@ toolchain: - gnuarmemb - xtools - zephyr -ram: 384 -flash: 256 +ram: 192 +flash: 192 supported: - i2c - pwm diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuappns_defconfig b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuappns_defconfig similarity index 86% rename from boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuappns_defconfig rename to boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuappns_defconfig index 8f30acd0a7864c..757e6b7e1a3350 100644 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuappns_defconfig +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpuappns_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPPNS=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable TrustZone-M CONFIG_ARM_TRUSTZONE_M=y diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpunet.dts b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpunet.dts similarity index 88% rename from boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpunet.dts rename to boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpunet.dts index e513e3e3968f6e..2355512312583b 100644 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpunet.dts +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpunet.dts @@ -5,12 +5,11 @@ */ /dts-v1/; -#include +#include / { model = "Nordic NRF5340 PDK NRF5340 Network"; - compatible = "nordic,nrf5340-pdk-nrf5340-cpunet", - "nordic,nrf5340-cpunet-qkaa", "nordic,nrf5340-cpunet"; + compatible = "nordic,nrf5340-pdk-nrf5340-cpunet"; chosen { zephyr,console = &uart0; @@ -110,10 +109,7 @@ }; &flash1 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -143,4 +139,4 @@ }; /* Include shared RAM configuration file */ -#include "nrf5340pdk_nrf5340_shared_sram_planning_conf.dts" +#include "nrf5340_shared_sram_planning_conf.dts" diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpunet.yaml b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpunet.yaml similarity index 100% rename from boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpunet.yaml rename to boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpunet.yaml diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpunet_defconfig b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpunet_defconfig similarity index 81% rename from boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpunet_defconfig rename to boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpunet_defconfig index 2965fd90ab0571..8d37bbce5b8fbf 100644 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpunet_defconfig +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340pdk_nrf5340_cpunet_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF5340PDK_NRF5340_CPUNET=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable GPIO CONFIG_GPIO=y diff --git a/boards/arm/nrf5340pdk_nrf5340/CMakeLists.txt b/boards/arm/nrf5340pdk_nrf5340/CMakeLists.txt deleted file mode 100644 index 8a7937720ceeb3..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2019 Nordic Semiconductor ASA. -# SPDX-License-Identifier: Apache-2.0 - -if ((CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPPNS) - AND CONFIG_BOARD_ENABLE_CPUNET) -zephyr_library() -zephyr_library_sources(nrf5340_cpunet_reset.c) -endif() diff --git a/boards/arm/nrf5340pdk_nrf5340/Kconfig b/boards/arm/nrf5340pdk_nrf5340/Kconfig deleted file mode 100644 index 790ee0d574d916..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/Kconfig +++ /dev/null @@ -1,58 +0,0 @@ -# nRF5340 PDK board configuration - -# Copyright (c) 2019 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS - -config BOARD_ENABLE_DCDC_APP - bool "Enable Application MCU DCDC converter" - select SOC_DCDC_NRF53X_APP - default y - -config BOARD_ENABLE_DCDC_NET - bool "Enable Network MCU DCDC converter" - select SOC_DCDC_NRF53X_NET - default y - -config BOARD_ENABLE_DCDC_HV - bool "Enable High Voltage DCDC converter" - select SOC_DCDC_NRF53X_HV - default y - -choice BT_HCI_BUS_TYPE - default BT_RPMSG if BT -endchoice - -config HEAP_MEM_POOL_SIZE - default 4096 if BT_RPMSG - -config BT_HAS_HCI_VS - default y if BT - -config BOARD_ENABLE_CPUNET - bool "Enable nRF53 Network MCU" - help - This option enables releasing the Network 'force off' signal, which - as a consequence will power up the Network MCU during system boot. - Additionally, the option allocates GPIO pins that will be used by UARTE - of the Network MCU. - Note: The non-secure image can only be started by the secure firmware, - so when this option is used with the non-secure version of the board, - the application needs to take into consideration, that the secure firmware - may already have started the Network MCU. - default y if (BT || NET_L2_IEEE802154) - -endif # BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS - -if BOARD_NRF5340PDK_NRF5340_CPUNET - -# BT_CTLR depends on BT. When BT is enabled we should default to also -# enabling the controller. -config BT_CTLR - default y if BT - -config BT_ECC - default y if BT - -endif # BOARD_NRF5340PDK_NRF5340_CPUNET diff --git a/boards/arm/nrf5340pdk_nrf5340/Kconfig.board b/boards/arm/nrf5340pdk_nrf5340/Kconfig.board deleted file mode 100644 index 9695483a283981..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/Kconfig.board +++ /dev/null @@ -1,18 +0,0 @@ -# nRF5340 PDK NRF5340 board configuration - -# Copyright (c) 2019-2020 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -if SOC_NRF5340_CPUAPP_QKAA - -config BOARD_NRF5340PDK_NRF5340_CPUAPP - bool "nRF5340 PDK nRF5340 Application MCU" - -config BOARD_NRF5340PDK_NRF5340_CPUAPPNS - bool "nRF5340 PDK nRF5340 Application MCU non-secure" - -endif # SOC_NRF5340_CPUAPP_QKAA - -config BOARD_NRF5340PDK_NRF5340_CPUNET - bool "nRF5340 PDK NRF5340 Network MCU" - depends on SOC_NRF5340_CPUNET_QKAA diff --git a/boards/arm/nrf5340pdk_nrf5340/Kconfig.defconfig b/boards/arm/nrf5340pdk_nrf5340/Kconfig.defconfig deleted file mode 100644 index 67980ca4080b1e..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/Kconfig.defconfig +++ /dev/null @@ -1,63 +0,0 @@ -# nRF5340 PDK nRF5340 board configuration - -# Copyright (c) 2019-2020 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS - -config BOARD - default "nrf5340pdk_nrf5340_cpuapp" - -# Code Partition: -# -# For the secure version of the board the firmware is linked at the beginning -# of the flash, or into the code-partition defined in DT if it is intended to -# be loaded by MCUboot. If the secure firmware is to be combined with a non- -# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always -# be restricted to the size of its code partition. -# -# For the non-secure version of the board, the firmware -# must be linked into the code-partition (non-secure) defined in DT, regardless. -# Apply this configuration below by setting the Kconfig symbols used by -# the linker according to the information extracted from DT partitions. - -# SRAM Partition: -# -# If the secure firmware is to be combined with a non-secure image -# (TRUSTED_EXECUTION_SECURE=y), the secure FW image SRAM shall always -# be restricted to the secure image SRAM partition (sram-secure-partition). -# Otherwise (if TRUSTED_EXECUTION_SECURE is not set) the whole zephyr,sram -# may be used by the image. -# -# For the non-secure version of the board, the firmware image SRAM is -# always restricted to the allocated non-secure SRAM partition. -# -# Workaround for not being able to have commas in macro arguments -DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition -DT_CHOSEN_Z_SRAM_PARTITION := zephyr,sram-secure-partition - -if BOARD_NRF5340PDK_NRF5340_CPUAPP && TRUSTED_EXECUTION_SECURE - -config FLASH_LOAD_SIZE - default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) - -config SRAM_SIZE - default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_SRAM_PARTITION),0,K) - -endif # BOARD_NRF5340PDK_NRF5340_CPUAPP && TRUSTED_EXECUTION_SECURE - -if BOARD_NRF5340PDK_NRF5340_CPUAPPNS - -config FLASH_LOAD_OFFSET - default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) - -config FLASH_LOAD_SIZE - default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) - -endif # BOARD_NRF5340PDK_NRF5340_CPUAPPNS - -endif # BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS - -config BOARD - default "nrf5340pdk_nrf5340_cpunet" - depends on BOARD_NRF5340PDK_NRF5340_CPUNET diff --git a/boards/arm/nrf5340pdk_nrf5340/board.cmake b/boards/arm/nrf5340pdk_nrf5340/board.cmake deleted file mode 100644 index 5ef6648bddd444..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/board.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340PDK_NRF5340_CPUAPPNS) -board_runner_args(nrfjprog "--nrf-family=NRF53" "--tool-opt=--coprocessor CP_APPLICATION") -board_runner_args(jlink "--device=cortex-m33" "--speed=4000") -endif() - -if(CONFIG_BOARD_NRF5340PDK_NRF5340_CPUNET) -board_runner_args(nrfjprog "--nrf-family=NRF53" "--tool-opt=--coprocessor CP_NETWORK") -endif() - -include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) -include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf5340pdk_nrf5340/doc/img/nrf5340pdk.png b/boards/arm/nrf5340pdk_nrf5340/doc/img/nrf5340pdk.png deleted file mode 100644 index 34832eeb393e8e..00000000000000 Binary files a/boards/arm/nrf5340pdk_nrf5340/doc/img/nrf5340pdk.png and /dev/null differ diff --git a/boards/arm/nrf5340pdk_nrf5340/doc/index.rst b/boards/arm/nrf5340pdk_nrf5340/doc/index.rst deleted file mode 100644 index 6cdb586eb1e90f..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/doc/index.rst +++ /dev/null @@ -1,275 +0,0 @@ -.. _nrf5340pdk_nrf5340: - -nRF5340 PDK -########### - -Overview -******** - -The nRF5340 PDK (PCA10095) is a single-board development kit for evaluation -and development on the Nordic nRF5340 System-on-Chip (SoC). - -The nRF5340 is a dual-core SoC based on the Arm® Cortex®-M33 architecture, with: - -* a full-featured ARM Cortex-M33F core with DSP instructions, FPU, and - ARMv8-M Security Extension, running at up to 128 MHz, referred to as - the **Application MCU** -* a secondary ARM Cortex-M33 core, with a reduced feature set, running at - a fixed 64 MHz, referred to as the **Network MCU**. - -The nrf5340pdk_nrf5340_cpuapp provides support for the Application MCU on -nRF5340 SoC. The nrf5340pdk_nrf5340_cpunet provides support for the Network -MCU on nRF5340 SoC. - -nRF5340 SoC provides support for the following devices: - -* :abbr:`ADC (Analog to Digital Converter)` -* CLOCK -* FLASH -* :abbr:`GPIO (General Purpose Input Output)` -* :abbr:`IDAU (Implementation Defined Attribution Unit)` -* :abbr:`I2C (Inter-Integrated Circuit)` -* :abbr:`MPU (Memory Protection Unit)` -* :abbr:`NVIC (Nested Vectored Interrupt Controller)` -* :abbr:`PWM (Pulse Width Modulation)` -* RADIO (Bluetooth Low Energy and 802.15.4) -* :abbr:`RTC (nRF RTC System Clock)` -* Segger RTT (RTT Console) -* :abbr:`SPI (Serial Peripheral Interface)` -* :abbr:`UARTE (Universal asynchronous receiver-transmitter)` -* :abbr:`USB (Universal Serial Bus)` -* :abbr:`WDT (Watchdog Timer)` - -.. figure:: img/nrf5340pdk.png - :width: 711px - :align: center - :alt: nRF5340 PDK - - nRF5340 PDK (Credit: Nordic Semiconductor) - -More information about the board can be found at the -`nRF5340 PDK website`_. -The `Nordic Semiconductor Infocenter`_ -contains the processor's information and the datasheet. - -.. note:: - - In previous Zephyr releases this board was named *nrf5340_dk_nrf5340*. - -Hardware -******** - -nRF5340 PDK has two external oscillators. The frequency of -the slow clock is 32.768 kHz. The frequency of the main clock -is 32 MHz. - -Supported Features -================== - -The nrf5340pdk_nrf5340_cpuapp board configuration supports the following -hardware features: - -+-----------+------------+----------------------+ -| Interface | Controller | Driver/Component | -+===========+============+======================+ -| ADC | on-chip | adc | -+-----------+------------+----------------------+ -| CLOCK | on-chip | clock_control | -+-----------+------------+----------------------+ -| FLASH | on-chip | flash | -+-----------+------------+----------------------+ -| GPIO | on-chip | gpio | -+-----------+------------+----------------------+ -| I2C(M) | on-chip | i2c | -+-----------+------------+----------------------+ -| MPU | on-chip | arch/arm | -+-----------+------------+----------------------+ -| NVIC | on-chip | arch/arm | -+-----------+------------+----------------------+ -| PWM | on-chip | pwm | -+-----------+------------+----------------------+ -| RTC | on-chip | system clock | -+-----------+------------+----------------------+ -| RTT | Segger | console | -+-----------+------------+----------------------+ -| SPI(M/S) | on-chip | spi | -+-----------+------------+----------------------+ -| SPU | on-chip | system protection | -+-----------+------------+----------------------+ -| UARTE | on-chip | serial | -+-----------+------------+----------------------+ -| USB | on-chip | usb | -+-----------+------------+----------------------+ -| WDT | on-chip | watchdog | -+-----------+------------+----------------------+ - -The nrf5340pdk_nrf5340_cpunet board configuration supports the following -hardware features: - -+-----------+------------+----------------------+ -| Interface | Controller | Driver/Component | -+===========+============+======================+ -| ADC | on-chip | adc | -+-----------+------------+----------------------+ -| CLOCK | on-chip | clock_control | -+-----------+------------+----------------------+ -| FLASH | on-chip | flash | -+-----------+------------+----------------------+ -| GPIO | on-chip | gpio | -+-----------+------------+----------------------+ -| I2C(M) | on-chip | i2c | -+-----------+------------+----------------------+ -| MPU | on-chip | arch/arm | -+-----------+------------+----------------------+ -| NVIC | on-chip | arch/arm | -+-----------+------------+----------------------+ -| PWM | on-chip | pwm | -+-----------+------------+----------------------+ -| RADIO | on-chip | Bluetooth, | -| | | ieee802154 | -+-----------+------------+----------------------+ -| RTC | on-chip | system clock | -+-----------+------------+----------------------+ -| RTT | Segger | console | -+-----------+------------+----------------------+ -| SPI(M/S) | on-chip | spi | -+-----------+------------+----------------------+ -| UARTE | on-chip | serial | -+-----------+------------+----------------------+ -| WDT | on-chip | watchdog | -+-----------+------------+----------------------+ - -Other hardware features are not supported by the Zephyr kernel. -See `Nordic Semiconductor Infocenter`_ -for a complete list of nRF5340 Development Kit board hardware features. - -Connections and IOs -=================== - -LED ---- - -* LED1 (green) = P0.28 -* LED2 (green) = P0.29 -* LED3 (green) = P0.30 -* LED4 (green) = P0.31 - -Push buttons ------------- - -* BUTTON1 = SW1 = P0.23 -* BUTTON2 = SW2 = P0.24 -* BUTTON3 = SW3 = P0.8 -* BUTTON4 = SW4 = P0.9 -* BOOT = SW5 = boot/reset - -Security components -=================== - -- Implementation Defined Attribution Unit (`IDAU`_) on the Application MCU. - The IDAU is implemented with the System Protection Unit and is used to - define secure and non-secure memory maps. By default, all of the memory - space (Flash, SRAM, and peripheral address space) is defined to be secure - accessible only. -- Secure boot. - -Programming and Debugging -************************* - -nRF5340 Application MCU supports the Armv8m Security Extension. -Applications build for the nrf5340pdk_nrf5340_cpuapp board by default -boot in the Secure state. - -nRF5340 Network MCU does not support the Armv8m Security Extension. -nRF5340 IDAU may configure bus accesses by the nRF5340 Network MCU -to have Secure attribute set; the latter allows to build and run -Secure only applications on the nRF5340 SoC. - -Building Secure/Non-Secure Zephyr applications -============================================== - -The process requires the following steps: - -1. Build the Secure Zephyr application for the Application MCU - using ``-DBOARD=nrf5340pdk_nrf5340_cpuapp`` and - ``CONFIG_TRUSTED_EXECUTION_SECURE=y`` in the application - project configuration file. -2. Build the Non-Secure Zephyr application for the Application MCU - using ``-DBOARD=nrf5340pdk_nrf5340_cpuappns``. -3. Merge the two binaries together. -4. Build the application firmware for the Network MCU using - ``-DBOARD=nrf5340pdk_nrf5340_cpunet``. - -When building a Secure/Non-Secure application for the nRF5340 Application MCU, -the Secure application will have to set the IDAU (SPU) configuration to allow -Non-Secure access to all CPU resources utilized by the Non-Secure application -firmware. SPU configuration shall take place before jumping to the Non-Secure -application. - -Building a Secure only application -================================== - -Build the Zephyr app in the usual way (see :ref:`build_an_application` -and :ref:`application_run`), using ``-DBOARD=nrf5340pdk_nrf5340_cpuapp`` for -the firmware running on the nRF5340 Application MCU, and using -``-DBOARD=nrf5340pdk_nrf5340_cpunet`` for the firmware running -on the nRF5340 Network MCU. - -Flashing -======== - -Follow the instructions in the :ref:`nordic_segger` page to install -and configure all the necessary software. Further information can be -found in :ref:`nordic_segger_flashing`. Then build and flash -applications as usual (see :ref:`build_an_application` and -:ref:`application_run` for more details). - -Here is an example for the :ref:`hello_world` application running on the -nRF5340 Application MCU. - -First, run your favorite terminal program to listen for output. - -.. code-block:: console - - $ minicom -D -b 115200 - -Replace :code:`` with the port where the board nRF5340 PDK -can be found. For example, under Linux, :code:`/dev/ttyACM0`. - -Then build and flash the application in the usual way. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: nrf5340pdk_nrf5340_cpuapp - :goals: build flash - -Debugging -========= - -Refer to the :ref:`nordic_segger` page to learn about debugging Nordic -boards with a Segger IC. - - -Testing the LEDs and buttons in the nRF5340 PDK -*********************************************** - -There are 2 samples that allow you to test that the buttons (switches) and -LEDs on the board are working properly with Zephyr: - -* :ref:`blinky-sample` -* :ref:`button-sample` - -You can build and flash the examples to make sure Zephyr is running correctly on -your board. The button and LED definitions can be found in -:zephyr_file:`boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_common.dts`. - -References -********** - -.. target-notes:: - -.. _IDAU: - https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau -.. _nRF5340 PDK website: - https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF5340-PDK -.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340_cpunet_reset.c b/boards/arm/nrf5340pdk_nrf5340/nrf5340_cpunet_reset.c deleted file mode 100644 index fad030dfb9818d..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340_cpunet_reset.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2019 Nordic Semiconductor ASA. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include - -LOG_MODULE_REGISTER(nrf5340pdk_nrf5340_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); - -/* Shared memory definitions */ -#if DT_HAS_CHOSEN(zephyr_ipc_shm) -#define SHM_NODE DT_CHOSEN(zephyr_ipc_shm) -#define SHM_BASE_ADDRESS DT_REG_ADDR(SHM_NODE) -#define SHM_SIZE DT_REG_SIZE(SHM_NODE) -#endif - -#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) - -/* This should come from DTS, possibly an overlay. */ -#define CPUNET_UARTE_PIN_TX 25 -#define CPUNET_UARTE_PIN_RX 26 -#define CPUNET_UARTE_PIN_RTS 10 -#define CPUNET_UARTE_PIN_CTS 12 - -static void remoteproc_mgr_config(void) -{ - /* UARTE */ - /* Assign specific GPIOs that will be used to get UARTE from - * nRF5340 Network MCU. - */ - NRF_P0->PIN_CNF[CPUNET_UARTE_PIN_TX] = - GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos; - NRF_P0->PIN_CNF[CPUNET_UARTE_PIN_RX] = - GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos; - NRF_P0->PIN_CNF[CPUNET_UARTE_PIN_RTS] = - GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos; - NRF_P0->PIN_CNF[CPUNET_UARTE_PIN_CTS] = - GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos; - - /* Retain nRF5340 Network MCU in Secure domain (bus - * accesses by Network MCU will have Secure attribute set). - */ - NRF_SPU->EXTDOMAIN[0].PERM = 1 << 4; -} -#endif /* !CONFIG_TRUSTED_EXECUTION_NONSECURE */ - -static int remoteproc_mgr_boot(struct device *dev) -{ - ARG_UNUSED(dev); - -#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) - /* Secure domain may configure permissions for the Network MCU. */ - remoteproc_mgr_config(); -#endif /* !CONFIG_TRUSTED_EXECUTION_NONSECURE */ - -#if defined(SHM_BASE_ADDRESS) && (SHM_BASE_ADDRESS != 0) - - /* Initialize inter-processor shared memory block to zero. It is - * assumed that the application image has access to the shared - * memory at this point (see #24147). - */ - memset((void *) SHM_BASE_ADDRESS, 0, SHM_SIZE); -#endif - - /* Release the Network MCU, 'Release force off signal' */ - NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; - - LOG_DBG("Network MCU released."); - - return 0; -} - -SYS_INIT(remoteproc_mgr_boot, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp.dts b/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp.dts deleted file mode 100644 index 3c3175f0e96d76..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp.dts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2019-2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; -#include -#include "nrf5340pdk_nrf5340_cpuapp_common.dts" - -/ { - chosen { - zephyr,sram = &sram0_image; - zephyr,flash = &flash0; - zephyr,code-partition = &slot0_partition; - zephyr,sram-secure-partition = &sram0_s; - zephyr,sram-non-secure-partition = &sram0_ns; - }; -}; diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_common.dts b/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_common.dts deleted file mode 100644 index 65c3a323f91035..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_common.dts +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2019-2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - model = "Nordic NRF5340 PDK NRF5340 Application"; - compatible = "nordic,nrf5340-pdk-nrf5340-cpuapp"; - - chosen { - zephyr,console = &uart0; - zephyr,shell-uart = &uart0; - zephyr,uart-mcumgr = &uart0; - zephyr,bt-mon-uart = &uart0; - zephyr,bt-c2h-uart = &uart0; - }; - - leds { - compatible = "gpio-leds"; - led0: led_0 { - gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; - label = "Green LED 0"; - }; - led1: led_1 { - gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; - label = "Green LED 1"; - }; - led2: led_2 { - gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; - label = "Green LED 2"; - }; - led3: led_3 { - gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; - label = "Green LED 3"; - }; - }; - - buttons { - compatible = "gpio-keys"; - button0: button_0 { - gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - label = "Push button 1"; - }; - button1: button_1 { - gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - label = "Push button 2"; - }; - button2: button_2 { - gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - label = "Push button 3"; - }; - button3: button_3 { - gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - label = "Push button 4"; - }; - }; - - /* These aliases are provided for compatibility with samples */ - aliases { - led0 = &led0; - led1 = &led1; - led2 = &led2; - led3 = &led3; - sw0 = &button0; - sw1 = &button1; - sw2 = &button2; - sw3 = &button3; - }; -}; - -&adc { - status = "okay"; -}; - -&gpiote { - status = "okay"; -}; - -&gpio0 { - status = "okay"; -}; - -&gpio1 { - status = "okay"; -}; - -&i2c1 { - compatible = "nordic,nrf-twim"; - status = "okay"; - sda-pin = <34>; - scl-pin = <35>; -}; - -&uart0 { - status = "okay"; - current-speed = <115200>; - tx-pin = <20>; - rx-pin = <22>; - rts-pin = <19>; - cts-pin = <21>; -}; - -&pwm0 { - status = "okay"; - ch0-pin = <28>; -}; - -&spi2 { - compatible = "nordic,nrf-spim"; - status = "okay"; - sck-pin = <47>; - miso-pin = <46>; - mosi-pin = <45>; -}; - -&timer0 { - status = "okay"; -}; - -&timer1 { - status = "okay"; -}; - -&timer2 { - status = "okay"; -}; - -&flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 0x10000>; - }; - slot0_partition: partition@10000 { - label = "image-0"; - }; - slot0_ns_partition: partition@40000 { - label = "image-0-nonsecure"; - }; - slot1_partition: partition@80000 { - label = "image-1"; - }; - slot1_ns_partition: partition@b0000 { - label = "image-1-nonsecure"; - }; - scratch_partition: partition@f0000 { - label = "image-scratch"; - reg = <0x000f0000 0xa000>; - }; - storage_partition: partition@fa000 { - label = "storage"; - reg = <0x000fa000 0x00006000>; - }; - }; -}; - -/ { - - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_image: image@20000000 { - /* Zephyr image(s) memory */ - }; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - }; - - sram0_ns: image_ns@20010000 { - /* Non-Secure image memory */ - }; - }; -}; - -/* Include partition configuration file */ -#include "nrf5340pdk_nrf5340_cpuapp_partition_conf.dts" diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_partition_conf.dts b/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_partition_conf.dts deleted file mode 100644 index 73c200f1c09a49..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuapp_partition_conf.dts +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2019-2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - * Default Flash planning for nrf5340pdk_nrf5340 CPUAPP (Application MCU). - * - * Zephyr build for nRF5340 with ARM TrustZone-M support, - * implies building Secure and Non-Secure Zephyr images. - * - * Secure image will be placed, by default, in flash0 - * (or in slot0, if MCUboot is present). - * Secure image will use sram0 for system memory. - * - * Non-Secure image will be placed in slot0_ns, and use - * sram0_ns for system memory. - * - * Note that the Secure image only requires knowledge of - * the beginning of the Non-Secure image (not its size). - */ - -&slot0_partition { - reg = <0x00010000 0x30000>; -}; - -&slot0_ns_partition { - reg = <0x00040000 0x40000>; -}; - -&slot1_partition { - reg = <0x00080000 0x30000>; -}; - -&slot1_ns_partition { - reg = <0x000b0000 0x40000>; -}; - -/* Default SRAM planning when building for nRF5340 with - * ARM TrustZone-M support - * - Lowest 64 kB SRAM allocated to Secure image (sram0_s) - * - Middle 384 kB allocated to Non-Secure image (sram0_ns) - * - Upper 64 kB SRAM allocated as Shared memory (sram0_shared) - * (see nrf5340pdk_nrf5340_shared_sram_planning_conf.dts) - */ -&sram0_image { - reg = <0x20000000 DT_SIZE_K(448)>; -}; - -&sram0_s { - reg = <0x20000000 0x10000>; -}; - -&sram0_ns { - reg = <0x20010000 0x60000>; -}; - -/* Include shared RAM configuration file */ -#include "nrf5340pdk_nrf5340_shared_sram_planning_conf.dts" diff --git a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuappns.dts b/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuappns.dts deleted file mode 100644 index af4a0fb9c3c1c1..00000000000000 --- a/boards/arm/nrf5340pdk_nrf5340/nrf5340pdk_nrf5340_cpuappns.dts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2019-2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; -#include -#include "nrf5340pdk_nrf5340_cpuapp_common.dts" - -/ { - chosen { - zephyr,sram = &sram0_ns; - zephyr,flash = &flash0; - zephyr,code-partition = &slot0_ns_partition; - }; -}; diff --git a/boards/arm/nrf9160_innblue21/board.cmake b/boards/arm/nrf9160_innblue21/board.cmake index 007118c7bf1197..9bfe907a466d49 100644 --- a/boards/arm/nrf9160_innblue21/board.cmake +++ b/boards/arm/nrf9160_innblue21/board.cmake @@ -1,7 +1,6 @@ # Copyright (c) 2020 InnBlue # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF91") board_runner_args(jlink "--device=cortex-m33" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf9160_innblue21/innblue21_board_init.c b/boards/arm/nrf9160_innblue21/innblue21_board_init.c index 7db1bf2387a028..590c4b4acba591 100644 --- a/boards/arm/nrf9160_innblue21/innblue21_board_init.c +++ b/boards/arm/nrf9160_innblue21/innblue21_board_init.c @@ -11,7 +11,7 @@ #define VDD_5V0_PWR_CTRL_GPIO_PIN 21 /* ENABLE_5V0_BOOST --> speed sensor */ /* Configures the pin as output and sets them high. */ -static void config_pin(struct device *gpio, int pin) +static void config_pin(const struct device *gpio, int pin) { int err; @@ -26,9 +26,9 @@ static void config_pin(struct device *gpio, int pin) k_sleep(K_MSEC(10)); } -static int pwr_ctrl_init(struct device *dev) +static int pwr_ctrl_init(const struct device *dev) { - struct device *gpio; + const struct device *gpio; /* Get handle of the GPIO device. */ gpio = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0))); diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dts b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dts index dbf006f1a0bdcf..ad273d7724c23a 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dts +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_common.dts @@ -39,7 +39,7 @@ compatible = "gpio-keys"; button0: button_0 { - gpios = <&gpio0 31 GPIO_PUD_PULL_UP>; + gpios = <&gpio0 31 GPIO_PULL_UP>; label = "Button 0"; }; }; @@ -102,7 +102,7 @@ hts221@5f { compatible = "st,hts221"; reg = <0x5f>; - drdy-gpios = <&gpio0 3 GPIO_INT_ACTIVE_HIGH>; + drdy-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; label = "HTS221"; }; @@ -156,10 +156,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -167,15 +164,15 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x10000>; + reg = <0x00000000 0xc000>; }; - slot0_partition: partition@10000 { + slot0_partition: partition@c000 { label = "image-0"; }; - slot0_ns_partition: partition@40000 { + slot0_ns_partition: partition@3e000 { label = "image-0-nonsecure"; }; - slot1_partition: partition@80000 { + slot1_partition: partition@7e000 { label = "image-1"; }; slot1_ns_partition: partition@b0000 { @@ -195,13 +192,11 @@ / { /* SRAM allocated and used by the BSD library */ sram0_bsd: memory@20010000 { - device_type = "memory"; compatible = "mmio-sram"; }; /* SRAM allocated to the Non-Secure image */ sram0_ns: memory@20020000 { - device_type = "memory"; compatible = "mmio-sram"; }; }; diff --git a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dts b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dts index 45e5474051fab0..d3a30abdc76876 100644 --- a/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dts +++ b/boards/arm/nrf9160_innblue21/nrf9160_innblue21_partition_conf.dts @@ -22,15 +22,15 @@ */ &slot0_partition { - reg = <0x00010000 0x30000>; + reg = <0x0000c000 0x30000>; }; &slot0_ns_partition { - reg = <0x00040000 0x40000>; + reg = <0x0003e000 0x40000>; }; &slot1_partition { - reg = <0x00080000 0x30000>; + reg = <0x0007e000 0x30000>; }; &slot1_ns_partition { diff --git a/boards/arm/nrf9160_innblue22/board.cmake b/boards/arm/nrf9160_innblue22/board.cmake index 007118c7bf1197..9bfe907a466d49 100644 --- a/boards/arm/nrf9160_innblue22/board.cmake +++ b/boards/arm/nrf9160_innblue22/board.cmake @@ -1,7 +1,6 @@ # Copyright (c) 2020 InnBlue # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF91") board_runner_args(jlink "--device=cortex-m33" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf9160_innblue22/innblue22_board_init.c b/boards/arm/nrf9160_innblue22/innblue22_board_init.c index 732625ea826fb1..5c9f9fb6b34c9c 100644 --- a/boards/arm/nrf9160_innblue22/innblue22_board_init.c +++ b/boards/arm/nrf9160_innblue22/innblue22_board_init.c @@ -9,9 +9,9 @@ #define VDD_5V0_PWR_CTRL_GPIO_PIN 21 /* ENABLE_5V0_BOOST --> speed sensor */ -static int pwr_ctrl_init(struct device *dev) +static int pwr_ctrl_init(const struct device *dev) { - struct device *gpio; + const struct device *gpio; int err = -ENODEV; /* Get handle of the GPIO device. */ diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dts b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dts index 89ce1b9775fe26..5b9898a5ca3d46 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dts +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_common.dts @@ -98,6 +98,10 @@ compatible = "ti,bq274xx"; label = "BQ274XX"; reg = <0x55>; + design-voltage = <3700>; + design-capacity = <1800>; + taper-current = <45>; + terminate-voltage = <3000>; }; lis2dh12-accel@19 { @@ -164,10 +168,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -175,15 +176,15 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x10000>; + reg = <0x00000000 0xc000>; }; - slot0_partition: partition@10000 { + slot0_partition: partition@c000 { label = "image-0"; }; - slot0_ns_partition: partition@40000 { + slot0_ns_partition: partition@3e000 { label = "image-0-nonsecure"; }; - slot1_partition: partition@80000 { + slot1_partition: partition@7e000 { label = "image-1"; }; slot1_ns_partition: partition@b0000 { @@ -203,13 +204,11 @@ / { /* SRAM allocated and used by the BSD library */ sram0_bsd: memory@20010000 { - device_type = "memory"; compatible = "mmio-sram"; }; /* SRAM allocated to the Non-Secure image */ sram0_ns: memory@20020000 { - device_type = "memory"; compatible = "mmio-sram"; }; }; diff --git a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dts b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dts index 2fbfab076b8e0d..3588a6a7ce16c7 100644 --- a/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dts +++ b/boards/arm/nrf9160_innblue22/nrf9160_innblue22_partition_conf.dts @@ -22,15 +22,15 @@ */ &slot0_partition { - reg = <0x00010000 0x30000>; + reg = <0x0000c000 0x30000>; }; &slot0_ns_partition { - reg = <0x00040000 0x40000>; + reg = <0x0003e000 0x40000>; }; &slot1_partition { - reg = <0x00080000 0x30000>; + reg = <0x0007e000 0x30000>; }; &slot1_ns_partition { diff --git a/boards/arm/nrf9160dk_nrf52840/Kconfig.defconfig b/boards/arm/nrf9160dk_nrf52840/Kconfig.defconfig index 86139b653c10ca..477277d8064fd8 100644 --- a/boards/arm/nrf9160dk_nrf52840/Kconfig.defconfig +++ b/boards/arm/nrf9160dk_nrf52840/Kconfig.defconfig @@ -8,10 +8,6 @@ if BOARD_NRF9160DK_NRF52840 config BOARD default "nrf9160dk_nrf52840" -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/nrf9160dk_nrf52840/board.c b/boards/arm/nrf9160dk_nrf52840/board.c index 44147c712318b8..3cb162e64444b5 100644 --- a/boards/arm/nrf9160dk_nrf52840/board.c +++ b/boards/arm/nrf9160dk_nrf52840/board.c @@ -56,8 +56,8 @@ LOG_MODULE_REGISTER(board_control, CONFIG_BOARD_NRF9160DK_LOG_LEVEL); */ __packed struct pin_config { - u8_t pin; - u8_t val; + uint8_t pin; + uint8_t val; }; /* The following tables specify the configuration of each pin based on the @@ -171,7 +171,8 @@ static void config_print(void) IS_ENABLED(CONFIG_BOARD_NRF9160DK_SWITCH1_ARDUINO)); } -static int pins_configure(struct device *port, const struct pin_config cfg[], +static int pins_configure(const struct device *port, + const struct pin_config cfg[], size_t pins) { int err; @@ -183,7 +184,7 @@ static int pins_configure(struct device *port, const struct pin_config cfg[], * so configure the pin as output with the proper initial * state. */ - u32_t flag = (cfg[i].val ? GPIO_OUTPUT_LOW + uint32_t flag = (cfg[i].val ? GPIO_OUTPUT_LOW : GPIO_OUTPUT_HIGH); err = gpio_pin_configure(port, cfg[i].pin, flag); if (err) { @@ -197,10 +198,10 @@ static int pins_configure(struct device *port, const struct pin_config cfg[], return 0; } -static void chip_reset(struct device *gpio, - struct gpio_callback *cb, u32_t pins) +static void chip_reset(const struct device *gpio, + struct gpio_callback *cb, uint32_t pins) { - const u32_t stamp = k_cycle_get_32(); + const uint32_t stamp = k_cycle_get_32(); printk("GPIO reset line asserted, device reset.\n"); printk("Bye @ cycle32 %u\n", stamp); @@ -208,7 +209,7 @@ static void chip_reset(struct device *gpio, NVIC_SystemReset(); } -static void reset_pin_wait_low(struct device *port, u32_t pin) +static void reset_pin_wait_low(const struct device *port, uint32_t pin) { int val; @@ -218,11 +219,12 @@ static void reset_pin_wait_low(struct device *port, u32_t pin) } while (val > 0); } -static int reset_pin_configure(struct device *p0, struct device *p1) +static int reset_pin_configure(const struct device *p0, + const struct device *p1) { int err; - u32_t pin = 0; - struct device *port = NULL; + uint32_t pin = 0; + const struct device *port = NULL; static struct gpio_callback gpio_ctx; @@ -283,11 +285,11 @@ static int reset_pin_configure(struct device *p0, struct device *p1) return 0; } -static int init(struct device *dev) +static int init(const struct device *dev) { int rc; - struct device *p0; - struct device *p1; + const struct device *p0; + const struct device *p1; p0 = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0))); if (!p0) { diff --git a/boards/arm/nrf9160dk_nrf52840/board.cmake b/boards/arm/nrf9160dk_nrf52840/board.cmake index ca0a3abd7dcd55..87251af52c077a 100644 --- a/boards/arm/nrf9160dk_nrf52840/board.cmake +++ b/boards/arm/nrf9160dk_nrf52840/board.cmake @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf9160dk_nrf52840/doc/index.rst b/boards/arm/nrf9160dk_nrf52840/doc/index.rst index fb8c980fea80a6..0adffb98e86376 100644 --- a/boards/arm/nrf9160dk_nrf52840/doc/index.rst +++ b/boards/arm/nrf9160dk_nrf52840/doc/index.rst @@ -31,9 +31,6 @@ the `Nordic Low power cellular IoT`_ website. The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. -.. note:: - - In previous Zephyr releases this board was named *nrf52840_pca10090*. Hardware ******** diff --git a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts index edfd08e5495a9d..bf0753a1812c3a 100644 --- a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts +++ b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840.dts @@ -39,7 +39,7 @@ */ &uart0 { - compatible = "nordic,nrf-uart"; + compatible = "nordic,nrf-uarte"; current-speed = <115200>; status = "okay"; tx-pin = <5>; @@ -49,10 +49,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig index d785f6b03cc80c..7704b958d84757 100644 --- a/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig +++ b/boards/arm/nrf9160dk_nrf52840/nrf9160dk_nrf52840_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF9160DK_NRF52840=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y CONFIG_UART_NRFX=y diff --git a/boards/arm/nrf9160dk_nrf9160/CMakeLists.txt b/boards/arm/nrf9160dk_nrf9160/CMakeLists.txt index 55667d7bb40611..2030c1c62ea09d 100644 --- a/boards/arm/nrf9160dk_nrf9160/CMakeLists.txt +++ b/boards/arm/nrf9160dk_nrf9160/CMakeLists.txt @@ -5,3 +5,82 @@ if(CONFIG_BOARD_NRF52840_GPIO_RESET) zephyr_library() zephyr_library_sources(nrf52840_reset.c) endif() + +if (CONFIG_BUILD_WITH_TFM) + # Set default image versions if not defined elsewhere + if (NOT DEFINED TFM_IMAGE_VERSION_S) + set(TFM_IMAGE_VERSION_S 0.0.0+0) + endif() + + if (NOT DEFINED TFM_IMAGE_VERSION_NS) + set(TFM_IMAGE_VERSION_NS 0.0.0+0) + endif() + + set(PREPROCESSED_FILE_S "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.o") + set(PREPROCESSED_FILE_NS "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_ns.dir/signing_layout_ns.o") + set(TFM_MCUBOOT_DIR "${ZEPHYR_TFM_MODULE_DIR}/trusted-firmware-m/bl2/ext/mcuboot") + + # Configure which format (full or hash) to include the public key in + # the image manifest + if(NOT DEFINED TFM_PUBLIC_KEY_FORMAT) + set(TFM_PUBLIC_KEY_FORMAT "full") + endif() + + # Set srec_cat binary name + find_program(SREC_CAT srec_cat) + if(${SREC_CAT} STREQUAL SREC_CAT-NOTFOUND) + message(FATAL_ERROR "'srec_cat' not found. Please install it, or add it to $PATH.") + endif() + + #Create and sign for concatenated binary image, should align with the TF-M BL2 + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + + #Sign secure binary image with public key + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_S} + -k ${CONFIG_TFM_KEY_FILE_S} + --public-key-format ${TFM_PUBLIC_KEY_FORMAT} + --align 1 + -v ${TFM_IMAGE_VERSION_S} + --pad + --pad-header + ${ADD_NS_IMAGE_MIN_VER} + -s auto + -H 0x400 + ${CMAKE_BINARY_DIR}/tfm/install/outputs/NORDIC_NRF/NRF9160DK_NRF9160/tfm_s.bin + ${CMAKE_BINARY_DIR}/tfm_s_signed.bin + + #Sign non-secure binary image with public key + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_NS} + -k ${CONFIG_TFM_KEY_FILE_NS} + --public-key-format ${TFM_PUBLIC_KEY_FORMAT} + --align 1 + -v ${TFM_IMAGE_VERSION_NS} + -s auto + ${ADD_S_IMAGE_MIN_VER} + -H 0x400 + ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} + ${CMAKE_BINARY_DIR}/zephyr_ns_signed.bin + + #Create concatenated binary image from the two independently signed binary files + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/assemble.py + --layout ${PREPROCESSED_FILE_S} + -s ${CMAKE_BINARY_DIR}/tfm_s_signed.bin + -n ${CMAKE_BINARY_DIR}/zephyr_ns_signed.bin + -o ${CMAKE_BINARY_DIR}/tfm_sign.bin + + #Copy mcuboot.bin + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm/bin/bl2.bin ${CMAKE_BINARY_DIR}/mcuboot.bin + + # Generate an intel hex file from the signed output binary + COMMAND srec_cat ${CMAKE_BINARY_DIR}/tfm_sign.bin + -binary + -offset 0x10000 + -o ${CMAKE_BINARY_DIR}/tfm_sign.hex + -intel + + # Copy tfm_sign.hex to zephyr + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm_sign.hex ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME} + ) +endif() diff --git a/boards/arm/nrf9160dk_nrf9160/board.cmake b/boards/arm/nrf9160dk_nrf9160/board.cmake index 3d655f4e90c0ea..a7561fdae2b563 100644 --- a/boards/arm/nrf9160dk_nrf9160/board.cmake +++ b/boards/arm/nrf9160dk_nrf9160/board.cmake @@ -1,6 +1,9 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF91") +if(CONFIG_BOARD_NRF9160DK_NRF9160NS) + set(TFM_PUBLIC_KEY_FORMAT "full") +endif() + board_runner_args(jlink "--device=cortex-m33" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nrf9160dk_nrf9160/doc/index.rst b/boards/arm/nrf9160dk_nrf9160/doc/index.rst index 6cb2d2120e0bf0..d7a5fcefffba44 100644 --- a/boards/arm/nrf9160dk_nrf9160/doc/index.rst +++ b/boards/arm/nrf9160dk_nrf9160/doc/index.rst @@ -37,9 +37,6 @@ More information about the board can be found at the `nRF9160 DK website`_. The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. -.. note:: - - In previous Zephyr releases this board was named *nrf9160_pca10090*. Hardware ******** @@ -126,8 +123,16 @@ Programming and Debugging nrf9160dk_nrf9160 supports the Armv8m Security Extension, and by default boots in the Secure state. -Building Secure/Non-Secure Zephyr applications -============================================== +Building Secure/Non-Secure Zephyr applications with Arm |reg| TrustZone |reg| +============================================================================= + +Applications on the nRF9160 may contain a Secure and a Non-Secure firmware +image. The Secure image can be built using either Zephyr or +`Trusted Firmware M`_ (TF-M). Non-Secure firmware images are always built +using Zephyr. The two alternatives are described below. + +Building the Secure firmware using Zephyr +----------------------------------------- The process requires the following steps: @@ -136,6 +141,28 @@ The process requires the following steps: 2. Build the Non-Secure Zephyr application using ``-DBOARD=nrf9160dk_nrf9160ns``. 3. Merge the two binaries together. +Building the Secure firmware with TF-M +-------------------------------------- + +The process to build the Secure firmware image using TF-M and the Non-Secure +firmware image using Zephyr requires the following action: + +* Build the Non-Secure Zephyr application + using ``-DBOARD=nrf9160dk_nrf9160ns`` and + ``CONFIG_BUILD_WITH_TFM=y`` in the application project configuration file. + The Zephyr build system will perform the following steps automatically: + + * Build the Non-Secure firmware image as a regular Zephyr application + * Build a TF-M (secure) firmware image + * Merge the output binaries together + * Optionally build a bootloader image (MCUboot) + +.. note:: + + Depending on the TF-M configuration, an application DTS overlay may be + required, to adjust the Non-Secure image Flash and SRAM starting address + and sizes. + When building a Secure/Non-Secure application, the Secure application will have to set the IDAU (SPU) configuration to allow Non-Secure access to all CPU resources utilized by the Non-Secure application firmware. SPU @@ -204,3 +231,4 @@ References https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau .. _nRF9160 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF9160-DK .. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/arm/nrf9160dk_nrf9160/nrf52840_reset.c b/boards/arm/nrf9160dk_nrf9160/nrf52840_reset.c index bd0516644ee345..3227ec5dfe6c6a 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf52840_reset.c +++ b/boards/arm/nrf9160dk_nrf9160/nrf52840_reset.c @@ -16,11 +16,11 @@ BUILD_ASSERT(RESET_PIN > 16 && RESET_PIN < 24, "Selected pin is not connected to nRF52840"); -int bt_hci_transport_setup(struct device *h4) +int bt_hci_transport_setup(const struct device *h4) { int err; char c; - struct device *port; + const struct device *port; port = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0))); if (!port) { diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160.yaml b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160.yaml index 888a5000c1c85a..e9149753a2ae70 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160.yaml +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160.yaml @@ -9,7 +9,9 @@ toolchain: ram: 64 flash: 256 supported: + - gpio - i2c - pwm + - spi - watchdog - counter diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common.dts b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common.dts index afaf1678d7a5c7..e72a63acd11906 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common.dts +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common.dts @@ -143,10 +143,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -159,13 +156,13 @@ slot0_partition: partition@10000 { label = "image-0"; }; - slot0_ns_partition: partition@40000 { + slot0_ns_partition: partition@50000 { label = "image-0-nonsecure"; }; slot1_partition: partition@80000 { label = "image-1"; }; - slot1_ns_partition: partition@b0000 { + slot1_ns_partition: partition@c0000 { label = "image-1-nonsecure"; }; scratch_partition: partition@f0000 { diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_defconfig b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_defconfig index e6d0d0df7ffaa7..aa61cc4ca3549e 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_defconfig +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF9160DK_NRF9160=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable TrustZone-M CONFIG_ARM_TRUSTZONE_M=y diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_partition_conf.dts b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_partition_conf.dts index 4b97632cf6f081..673a8c3a382939 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_partition_conf.dts +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_partition_conf.dts @@ -22,19 +22,19 @@ */ &slot0_partition { - reg = <0x00010000 0x30000>; + reg = <0x00010000 0x40000>; }; &slot0_ns_partition { - reg = <0x00040000 0x40000>; + reg = <0x00050000 0x30000>; }; &slot1_partition { - reg = <0x00080000 0x30000>; + reg = <0x00080000 0x40000>; }; &slot1_ns_partition { - reg = <0x000b0000 0x40000>; + reg = <0x000c0000 0x30000>; }; /* Default SRAM planning when building for nRF9160 with diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160ns.yaml b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160ns.yaml index ac967a3915cb6b..7197df7445b140 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160ns.yaml +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160ns.yaml @@ -7,7 +7,7 @@ toolchain: - xtools - zephyr ram: 128 -flash: 256 +flash: 192 supported: - i2c - pwm diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160ns_defconfig b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160ns_defconfig index 49e7a7b05cfb08..918eee97f4ee9a 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160ns_defconfig +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160ns_defconfig @@ -7,6 +7,9 @@ CONFIG_BOARD_NRF9160DK_NRF9160NS=y # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable TrustZone-M CONFIG_ARM_TRUSTZONE_M=y diff --git a/boards/arm/nucleo_f030r8/CMakeLists.txt b/boards/arm/nucleo_f030r8/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f030r8/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f030r8/doc/index.rst b/boards/arm/nucleo_f030r8/doc/index.rst index 8d2faf20e0b127..d9d8250533f076 100644 --- a/boards/arm/nucleo_f030r8/doc/index.rst +++ b/boards/arm/nucleo_f030r8/doc/index.rst @@ -123,7 +123,7 @@ Default Zephyr Peripheral Mapping: - UART_1 TX/RX : PA9/PA10 - UART_2 TX/RX : PA2/PA3 (ST-Link Virtual COM Port) - I2C1 SCL/SDA : PB8/PB9 (Arduino I2C) -- I2C2 SCL/SDA : PA11/PA12 +- I2C2 SCL/SDA : PB10/PB11 - SPI1 NSS/SCK/MISO/MOSI : PA4/PA5/PA6/PA7 (Arduino SPI) - SPI2 NSS/SCK/MISO/MOSI : PB12/PB13/PB14/PB15 - USER_PB : PC13 diff --git a/boards/arm/nucleo_f030r8/nucleo_f030r8.dts b/boards/arm/nucleo_f030r8/nucleo_f030r8.dts index be256b5a91eab7..b319456a3e9674 100644 --- a/boards/arm/nucleo_f030r8/nucleo_f030r8.dts +++ b/boards/arm/nucleo_f030r8/nucleo_f030r8.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F030R8-NUCLEO board"; - compatible = "st,stm32f030r8-nucleo", "st,stm32f030"; + compatible = "st,stm32f030r8-nucleo"; chosen { zephyr,console = &usart2; @@ -47,30 +48,38 @@ &gpiof {status = "disabled";}; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; diff --git a/boards/arm/nucleo_f030r8/pinmux.c b/boards/arm/nucleo_f030r8/pinmux.c deleted file mode 100644 index 3c7c0684f427af..00000000000000 --- a/boards/arm/nucleo_f030r8/pinmux.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2017 RnDity Sp. z o.o. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include "pinmux/pinmux.h" - -#include "pinmux/stm32/pinmux_stm32.h" - -/* pin assignments for NUCLEO-F030R8 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F0_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F0_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F0_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F0_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F0_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F0_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PA11, STM32F0_PINMUX_FUNC_PA11_I2C2_SCL}, - {STM32_PIN_PA12, STM32F0_PINMUX_FUNC_PA12_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F0_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F0_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F0_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F0_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F0_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F0_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32F0_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F0_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f070rb/CMakeLists.txt b/boards/arm/nucleo_f070rb/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f070rb/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f070rb/nucleo_f070rb.dts b/boards/arm/nucleo_f070rb/nucleo_f070rb.dts index 9f5923d36d57ba..ae16d8fdb16b22 100644 --- a/boards/arm/nucleo_f070rb/nucleo_f070rb.dts +++ b/boards/arm/nucleo_f070rb/nucleo_f070rb.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics NUCLEO-F070RB board"; - compatible = "st,stm32f070rb-nucleo", "st,stm32f070"; + compatible = "st,stm32f070rb-nucleo"; chosen { zephyr,console = &usart2; @@ -42,30 +43,36 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; diff --git a/boards/arm/nucleo_f070rb/nucleo_f070rb_defconfig b/boards/arm/nucleo_f070rb/nucleo_f070rb_defconfig index 282b780cb8c19f..efa96b95f9c381 100644 --- a/boards/arm/nucleo_f070rb/nucleo_f070rb_defconfig +++ b/boards/arm/nucleo_f070rb/nucleo_f070rb_defconfig @@ -25,14 +25,16 @@ CONFIG_GPIO=y # Clock configuration CONFIG_CLOCK_CONTROL=y # SYSCLK selection -CONFIG_CLOCK_STM32_HSE_CLOCK=8000000 CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y -# PLL configuration -CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# HSE configuration +CONFIG_CLOCK_STM32_HSE_CLOCK=8000000 # however, the board does not have an external oscillator, so just use # the 8MHz clock signal coming from integrated STLink CONFIG_CLOCK_STM32_HSE_BYPASS=y - +# PLL configuration +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# produce 48MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_PREDIV1=1 CONFIG_CLOCK_STM32_PLL_MULTIPLIER=6 CONFIG_CLOCK_STM32_AHB_PRESCALER=1 CONFIG_CLOCK_STM32_APB1_PRESCALER=1 diff --git a/boards/arm/nucleo_f070rb/pinmux.c b/boards/arm/nucleo_f070rb/pinmux.c deleted file mode 100644 index a553dddce2c9da..00000000000000 --- a/boards/arm/nucleo_f070rb/pinmux.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2018 qianfan Zhao - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include "pinmux/pinmux.h" - -#include - -/* pin assignments for NUCLEO_F070RB board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F0_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F0_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F0_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F0_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F0_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F0_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F0_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB11, STM32F0_PINMUX_FUNC_PB11_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PA5, STM32F0_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F0_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F0_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - {STM32_PIN_PB13, STM32F0_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32F0_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F0_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f091rc/CMakeLists.txt b/boards/arm/nucleo_f091rc/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f091rc/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f091rc/doc/index.rst b/boards/arm/nucleo_f091rc/doc/index.rst index 740a14180107fc..7db29a93ac7f34 100644 --- a/boards/arm/nucleo_f091rc/doc/index.rst +++ b/boards/arm/nucleo_f091rc/doc/index.rst @@ -92,12 +92,16 @@ The Zephyr nucleo_f091rc board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | independent watchdog | +-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtc | ++-----------+------------+-------------------------------------+ | I2C | on-chip | i2c controller | +-----------+------------+-------------------------------------+ | SPI | on-chip | SPI controller | +-----------+------------+-------------------------------------+ | ADC | on-chip | ADC controller | +-----------+------------+-------------------------------------+ +| DAC | on-chip | DAC controller | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported in this Zephyr port. @@ -131,6 +135,7 @@ Default Zephyr Peripheral Mapping: - SPI2 SCK/MISO/MOSI : PB13/PB14/PB15 - USER_PB : PC13 - LD1 : PA5 +- DAC_OUT1 : PA4 For mode details please refer to `STM32 Nucleo-64 board User Manual`_. diff --git a/boards/arm/nucleo_f091rc/nucleo_f091rc.dts b/boards/arm/nucleo_f091rc/nucleo_f091rc.dts index 124b3b1ea80fd3..92ea21df15642e 100644 --- a/boards/arm/nucleo_f091rc/nucleo_f091rc.dts +++ b/boards/arm/nucleo_f091rc/nucleo_f091rc.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F091RC-NUCLEO board"; - compatible = "st,stm32f091rc-nucleo", "st,stm32f091"; + compatible = "st,stm32f091rc-nucleo"; chosen { zephyr,console = &usart2; @@ -42,29 +43,35 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pa11 &i2c2_sda_pa12>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; @@ -72,11 +79,12 @@ status = "okay"; }; +&rtc { + status = "okay"; +}; + &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -91,5 +99,11 @@ }; &adc1 { + pinctrl-0 = <&adc_in0_pa0>; + status = "okay"; +}; + +&dac1 { status = "okay"; + pinctrl-0 = <&dac_out1_pa4>; }; diff --git a/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml b/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml index 560c6559062a62..306d7f710f6fb9 100644 --- a/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml +++ b/boards/arm/nucleo_f091rc/nucleo_f091rc.yaml @@ -16,8 +16,10 @@ supported: - i2c - nvs - spi + - counter - watchdog - adc + - dac testing: ignore_tags: - net diff --git a/boards/arm/nucleo_f091rc/pinmux.c b/boards/arm/nucleo_f091rc/pinmux.c deleted file mode 100644 index 84c0dfd04a9241..00000000000000 --- a/boards/arm/nucleo_f091rc/pinmux.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2017 RnDity Sp. z o.o. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F091RC board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F0_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F0_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F0_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F0_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F0_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F0_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PA11, STM32F0_PINMUX_FUNC_PA11_I2C2_SCL}, - {STM32_PIN_PA12, STM32F0_PINMUX_FUNC_PA12_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PA5, STM32F0_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F0_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F0_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - {STM32_PIN_PB13, STM32F0_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32F0_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F0_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PA0, STM32F0_PINMUX_FUNC_PA0_ADC_IN0}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f103rb/CMakeLists.txt b/boards/arm/nucleo_f103rb/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f103rb/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f103rb/arduino_r3_connector.dtsi b/boards/arm/nucleo_f103rb/arduino_r3_connector.dtsi index b866a53b6ce542..3e887efebe2700 100644 --- a/boards/arm/nucleo_f103rb/arduino_r3_connector.dtsi +++ b/boards/arm/nucleo_f103rb/arduino_r3_connector.dtsi @@ -36,3 +36,4 @@ }; arduino_spi: &spi1 {}; +arduino_i2c: &i2c1 {}; diff --git a/boards/arm/nucleo_f103rb/doc/index.rst b/boards/arm/nucleo_f103rb/doc/index.rst index 2cdf51ca08d4c8..350b39854ac0e4 100644 --- a/boards/arm/nucleo_f103rb/doc/index.rst +++ b/boards/arm/nucleo_f103rb/doc/index.rst @@ -124,6 +124,7 @@ Default Zephyr Peripheral Mapping: - UART_2 TX/RX : PA2/PA3 (ST-Link Virtual COM Port) - SPI1 NSS/SCK/MISO/MOSI : PA4/PA5/PA6/PA7 (Arduino SPI) - SPI2 SCK/MISO/MOSI : PB12/PB13/PB14/PB15 +- I2C1 SDA/SCL: PB9/PB8 (Arduino I2C) - PWM1_CH1: PA8 - USER_PB : PC13 - LD1 : PA5 diff --git a/boards/arm/nucleo_f103rb/nucleo_f103rb.dts b/boards/arm/nucleo_f103rb/nucleo_f103rb.dts index 6685db86cbb47f..9a734903643b1b 100644 --- a/boards/arm/nucleo_f103rb/nucleo_f103rb.dts +++ b/boards/arm/nucleo_f103rb/nucleo_f103rb.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F103RB-NUCLEO board"; - compatible = "st,stm32f103rb-nucleo", "st,stm32f103rb"; + compatible = "st,stm32f103rb-nucleo"; chosen { zephyr,console = &usart2; @@ -42,23 +43,36 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; }; +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + status = "okay"; + clock-frequency = ; +}; + &spi1 { + pinctrl-0 = <&spi1_nss_master_pa4 &spi1_sck_master_pa5 + &spi1_miso_master_pa6 &spi1_mosi_master_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_nss_master_pb12 &spi2_sck_master_pb13 + &spi2_miso_master_pb14 &spi2_mosi_master_pb15>; status = "okay"; }; @@ -67,6 +81,7 @@ pwm1: pwm { status = "okay"; + pinctrl-0 = <&tim1_ch1_pwm_pa8>; }; }; @@ -75,5 +90,6 @@ }; &adc1 { + pinctrl-0 = <&adc1_in0_pa0>; status = "okay"; }; diff --git a/boards/arm/nucleo_f103rb/nucleo_f103rb.yaml b/boards/arm/nucleo_f103rb/nucleo_f103rb.yaml index 790b7c9cec0fbd..19ba971ea9582e 100644 --- a/boards/arm/nucleo_f103rb/nucleo_f103rb.yaml +++ b/boards/arm/nucleo_f103rb/nucleo_f103rb.yaml @@ -11,6 +11,7 @@ flash: 128 supported: - arduino_gpio - arduino_spi + - arduino_i2c - gpio - spi - pwm diff --git a/boards/arm/nucleo_f103rb/nucleo_f103rb_defconfig b/boards/arm/nucleo_f103rb/nucleo_f103rb_defconfig index 959ea3fbc2770b..1592bf8722b5a3 100644 --- a/boards/arm/nucleo_f103rb/nucleo_f103rb_defconfig +++ b/boards/arm/nucleo_f103rb/nucleo_f103rb_defconfig @@ -28,7 +28,6 @@ CONFIG_CLOCK_STM32_PLL_SRC_HSE=y # the 8MHz clock signal coming from integrated STLink CONFIG_CLOCK_STM32_HSE_BYPASS=y # produce 72MHz clock at PLL output -CONFIG_CLOCK_STM32_PLL_XTPRE=n CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9 CONFIG_CLOCK_STM32_AHB_PRESCALER=1 # APB1 clock must not to exceed 36MHz limit diff --git a/boards/arm/nucleo_f103rb/pinmux.c b/boards/arm/nucleo_f103rb/pinmux.c deleted file mode 100644 index b1bda2fbefbcd5..00000000000000 --- a/boards/arm/nucleo_f103rb/pinmux.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016 Open-RnD Sp. z o.o. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F103RB board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F1_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F1_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F1_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F1_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32F1_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32F1_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - {STM32_PIN_PA8, STM32F1_PINMUX_FUNC_PA8_PWM1_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F1_PINMUX_FUNC_PA4_SPI1_MASTER_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F1_PINMUX_FUNC_PA5_SPI1_MASTER_SCK}, - {STM32_PIN_PA6, STM32F1_PINMUX_FUNC_PA6_SPI1_MASTER_MISO}, - {STM32_PIN_PA7, STM32F1_PINMUX_FUNC_PA7_SPI1_MASTER_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F1_PINMUX_FUNC_PB12_SPI2_MASTER_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F1_PINMUX_FUNC_PB13_SPI2_MASTER_SCK}, - {STM32_PIN_PB14, STM32F1_PINMUX_FUNC_PB14_SPI2_MASTER_MISO}, - {STM32_PIN_PB15, STM32F1_PINMUX_FUNC_PB15_SPI2_MASTER_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PA0, STM32F1_PINMUX_FUNC_PA0_ADC123_IN0}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f207zg/CMakeLists.txt b/boards/arm/nucleo_f207zg/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f207zg/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f207zg/Kconfig.defconfig b/boards/arm/nucleo_f207zg/Kconfig.defconfig index 5f821e3e7f9aa4..b3b48232483acb 100644 --- a/boards/arm/nucleo_f207zg/Kconfig.defconfig +++ b/boards/arm/nucleo_f207zg/Kconfig.defconfig @@ -13,9 +13,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_STM32_HAL - default y - endif # NETWORKING endif # BOARD_NUCLEO_F207ZG diff --git a/boards/arm/nucleo_f207zg/doc/index.rst b/boards/arm/nucleo_f207zg/doc/index.rst index b1f818d03b688b..5264ab8efc2e8d 100644 --- a/boards/arm/nucleo_f207zg/doc/index.rst +++ b/boards/arm/nucleo_f207zg/doc/index.rst @@ -92,6 +92,8 @@ The Zephyr nucleo_207zg board configuration supports the following hardware feat +-----------+------------+-------------------------------------+ | ADC | on-chip | ADC Controller | +-----------+------------+-------------------------------------+ +| DAC | on-chip | DAC Controller | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -142,6 +144,8 @@ Default Zephyr Peripheral Mapping: - LD1 : PB0 - LD2 : PB7 - LD3 : PB14 +- DAC: PA4 +- ADC: PA0 System Clock ------------ diff --git a/boards/arm/nucleo_f207zg/nucleo_f207zg.dts b/boards/arm/nucleo_f207zg/nucleo_f207zg.dts index 52c531caaedf93..237dde8b0cb27b 100644 --- a/boards/arm/nucleo_f207zg/nucleo_f207zg.dts +++ b/boards/arm/nucleo_f207zg/nucleo_f207zg.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F207ZG-NUCLEO board"; - compatible = "st,stm32f207zg-nucleo", "st,stm32f207"; + compatible = "st,stm32f207zg-nucleo"; chosen { zephyr,console = &usart3; @@ -52,16 +53,19 @@ }; &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>; current-speed = <115200>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; @@ -69,6 +73,29 @@ status = "okay"; }; +&rtc { + status = "okay"; +}; + &adc1 { + pinctrl-0 = <&adc1_in0_pa0>; + status = "okay"; +}; + +&mac { + status = "okay"; + pinctrl-0 = <ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pb13>; +}; + +&dac1 { status = "okay"; + pinctrl-0 = <&dac_out1_pa4>; }; diff --git a/boards/arm/nucleo_f207zg/nucleo_f207zg.yaml b/boards/arm/nucleo_f207zg/nucleo_f207zg.yaml index cfcf25e130172c..3db246f0517347 100644 --- a/boards/arm/nucleo_f207zg/nucleo_f207zg.yaml +++ b/boards/arm/nucleo_f207zg/nucleo_f207zg.yaml @@ -13,4 +13,6 @@ supported: - gpio - usb_device - watchdog + - counter - adc + - dac diff --git a/boards/arm/nucleo_f207zg/nucleo_f207zg_defconfig b/boards/arm/nucleo_f207zg/nucleo_f207zg_defconfig index a7eb49192ed7d1..b14e83ffbd790a 100644 --- a/boards/arm/nucleo_f207zg/nucleo_f207zg_defconfig +++ b/boards/arm/nucleo_f207zg/nucleo_f207zg_defconfig @@ -6,6 +6,12 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 CONFIG_SERIAL=y +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nucleo_f207zg/pinmux.c b/boards/arm/nucleo_f207zg/pinmux.c deleted file mode 100644 index 26c66b401ef3d8..00000000000000 --- a/boards/arm/nucleo_f207zg/pinmux.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2018 qianfan Zhao - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F207ZG board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PD8, STM32F2_PINMUX_FUNC_PD8_USART3_TX}, - {STM32_PIN_PD9, STM32F2_PINMUX_FUNC_PD9_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PG14, STM32F2_PINMUX_FUNC_PG14_USART6_TX}, - {STM32_PIN_PG9, STM32F2_PINMUX_FUNC_PG9_USART6_RX}, -#endif -#ifdef CONFIG_ETH_STM32_HAL - {STM32_PIN_PC1, STM32F2_PINMUX_FUNC_PC1_ETH}, - {STM32_PIN_PC4, STM32F2_PINMUX_FUNC_PC4_ETH}, - {STM32_PIN_PC5, STM32F2_PINMUX_FUNC_PC5_ETH}, - - {STM32_PIN_PA1, STM32F2_PINMUX_FUNC_PA1_ETH}, - {STM32_PIN_PA2, STM32F2_PINMUX_FUNC_PA2_ETH}, - {STM32_PIN_PA7, STM32F2_PINMUX_FUNC_PA7_ETH}, - - {STM32_PIN_PG11, STM32F2_PINMUX_FUNC_PG11_ETH}, - {STM32_PIN_PG13, STM32F2_PINMUX_FUNC_PG13_ETH}, - {STM32_PIN_PB13, STM32F2_PINMUX_FUNC_PB13_ETH}, -#endif /* CONFIG_ETH_STM32_HAL */ -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F2_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F2_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PA0, STM32F2_PINMUX_FUNC_PA0_ADC123_IN0}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f302r8/CMakeLists.txt b/boards/arm/nucleo_f302r8/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f302r8/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f302r8/nucleo_f302r8.dts b/boards/arm/nucleo_f302r8/nucleo_f302r8.dts index b35d7e1a743540..f3866934d56b42 100644 --- a/boards/arm/nucleo_f302r8/nucleo_f302r8.dts +++ b/boards/arm/nucleo_f302r8/nucleo_f302r8.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F302R8-NUCLEO board"; - compatible = "st,stm32f302r8-nucleo", "st,stm32f302"; + compatible = "st,stm32f302r8-nucleo"; chosen { zephyr,console = &usart2; @@ -42,23 +43,29 @@ }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pc10 &usart3_rx_pc11>; current-speed = <115200>; status = "okay"; }; @@ -68,6 +75,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; @@ -76,5 +84,6 @@ }; &adc1 { + pinctrl-0 = <&adc1_in1_pa0>; status = "okay"; }; diff --git a/boards/arm/nucleo_f302r8/pinmux.c b/boards/arm/nucleo_f302r8/pinmux.c deleted file mode 100644 index 22212bf776eaf2..00000000000000 --- a/boards/arm/nucleo_f302r8/pinmux.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2018 Seitz & Associates - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F302R8 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F3_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F3_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F3_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F3_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PC10, STM32F3_PINMUX_FUNC_PC10_USART3_TX}, - {STM32_PIN_PC11, STM32F3_PINMUX_FUNC_PC11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F3_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F3_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F3_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F3_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32F3_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F3_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32F3_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PA0, STM32F3_PINMUX_FUNC_PA0_ADC1_IN1}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f303re/CMakeLists.txt b/boards/arm/nucleo_f303re/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f303re/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f303re/nucleo_f303re.dts b/boards/arm/nucleo_f303re/nucleo_f303re.dts index a539b6eaf881d4..746058b9c5a7f4 100644 --- a/boards/arm/nucleo_f303re/nucleo_f303re.dts +++ b/boards/arm/nucleo_f303re/nucleo_f303re.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F303RE-NUCLEO board"; - compatible = "st,stm32f303re-nucleo", "st,stm32f303"; + compatible = "st,stm32f303re-nucleo"; chosen { zephyr,console = &usart2; @@ -42,6 +43,7 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/nucleo_f303re/nucleo_f303re_defconfig b/boards/arm/nucleo_f303re/nucleo_f303re_defconfig index c86c6a387ffaac..9e23e811e5058b 100644 --- a/boards/arm/nucleo_f303re/nucleo_f303re_defconfig +++ b/boards/arm/nucleo_f303re/nucleo_f303re_defconfig @@ -7,6 +7,12 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 CONFIG_SERIAL=y +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y @@ -29,7 +35,7 @@ CONFIG_CLOCK_STM32_PLL_SRC_HSE=y # the 8MHz clock signal coming from integrated STLink CONFIG_CLOCK_STM32_HSE_BYPASS=y # produce 72MHz clock at PLL output -CONFIG_CLOCK_STM32_PLL_PREDIV=1 +CONFIG_CLOCK_STM32_PLL_PREDIV1=1 CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9 CONFIG_CLOCK_STM32_AHB_PRESCALER=1 CONFIG_CLOCK_STM32_APB1_PRESCALER=2 diff --git a/boards/arm/nucleo_f303re/pinmux.c b/boards/arm/nucleo_f303re/pinmux.c deleted file mode 100644 index 5405094d0306da..00000000000000 --- a/boards/arm/nucleo_f303re/pinmux.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2020 Paul M. Bendixen - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F303RE board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F3_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F3_PINMUX_FUNC_PA3_USART2_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f334r8/CMakeLists.txt b/boards/arm/nucleo_f334r8/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f334r8/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f334r8/nucleo_f334r8.dts b/boards/arm/nucleo_f334r8/nucleo_f334r8.dts index 4015ac5ae3340c..6a2d9297e82d22 100644 --- a/boards/arm/nucleo_f334r8/nucleo_f334r8.dts +++ b/boards/arm/nucleo_f334r8/nucleo_f334r8.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F334R8-NUCLEO board"; - compatible = "st,stm32f334r8-nucleo", "st,stm32f334"; + compatible = "st,stm32f334r8-nucleo"; chosen { zephyr,console = &usart2; @@ -42,25 +43,31 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; @@ -69,6 +76,7 @@ pwm1: pwm { status = "okay"; + pinctrl-0 = <&tim1_ch1_pa8>; }; }; @@ -81,10 +89,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nucleo_f334r8/pinmux.c b/boards/arm/nucleo_f334r8/pinmux.c deleted file mode 100644 index fbb9548cdef793..00000000000000 --- a/boards/arm/nucleo_f334r8/pinmux.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 RnDity Sp. z o.o. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F334RB board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F3_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F3_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F3_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F3_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32F3_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32F3_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F3_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F3_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F3_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F3_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F3_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F3_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - {STM32_PIN_PA8, STM32F3_PINMUX_FUNC_PA8_PWM1_CH1}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f401re/CMakeLists.txt b/boards/arm/nucleo_f401re/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f401re/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f401re/nucleo_f401re.dts b/boards/arm/nucleo_f401re/nucleo_f401re.dts index ff50828bc04ffd..21d2b873427e52 100644 --- a/boards/arm/nucleo_f401re/nucleo_f401re.dts +++ b/boards/arm/nucleo_f401re/nucleo_f401re.dts @@ -7,11 +7,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F401RE-NUCLEO board"; - compatible = "st,stm32f401re-nucleo", "st,stm32f401"; + compatible = "st,stm32f401re-nucleo"; chosen { zephyr,console = &usart2; @@ -29,6 +30,13 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + green_pwm_led: green_pwm_led { + pwms = <&pwm2 1 0 PWM_POLARITY_NORMAL>; + }; + }; + gpio_keys { compatible = "gpio-keys"; user_button: button { @@ -40,37 +48,42 @@ aliases { led0 = &green_led_2; sw0 = &user_button; + pwm-led0 = &green_pwm_led; }; }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -107,6 +120,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa5>; }; }; @@ -115,6 +129,7 @@ }; &adc1 { + pinctrl-0 = <&adc1_in0_pa0>; status = "okay"; }; diff --git a/boards/arm/nucleo_f401re/nucleo_f401re_defconfig b/boards/arm/nucleo_f401re/nucleo_f401re_defconfig index a238a6607ca4f3..413afe1523b0e0 100644 --- a/boards/arm/nucleo_f401re/nucleo_f401re_defconfig +++ b/boards/arm/nucleo_f401re/nucleo_f401re_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=84000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/nucleo_f401re/pinmux.c b/boards/arm/nucleo_f401re/pinmux.c deleted file mode 100644 index 8970e2bc1c3834..00000000000000 --- a/boards/arm/nucleo_f401re/pinmux.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016 Linaro Limited. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F401RE board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32F4_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F4_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F4_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32F4_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F4_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PA0, STM32F4_PINMUX_FUNC_PA0_ADC123_IN0}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f411re/CMakeLists.txt b/boards/arm/nucleo_f411re/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f411re/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f411re/nucleo_f411re.dts b/boards/arm/nucleo_f411re/nucleo_f411re.dts index 720e4481aa4100..1bd86637ce9831 100644 --- a/boards/arm/nucleo_f411re/nucleo_f411re.dts +++ b/boards/arm/nucleo_f411re/nucleo_f411re.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F411RE-NUCLEO board"; - compatible = "st,stm32f411re-nucleo", "st,stm32f411"; + compatible = "st,stm32f411re-nucleo"; chosen { zephyr,console = &usart2; @@ -42,29 +43,40 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb3>; clock-frequency = ; }; &i2c3 { + pinctrl-0 = <&i2c3_scl_pa8 &i2c3_sda_pb4>; clock-frequency = ; }; +&i2s1 { + pinctrl-0 = <&i2s1_ck_pa5 &i2s1_sd_pa7>; +}; + &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; diff --git a/boards/arm/nucleo_f411re/nucleo_f411re_defconfig b/boards/arm/nucleo_f411re/nucleo_f411re_defconfig index 2c5935566820be..e353de9f119b3e 100644 --- a/boards/arm/nucleo_f411re/nucleo_f411re_defconfig +++ b/boards/arm/nucleo_f411re/nucleo_f411re_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/nucleo_f411re/pinmux.c b/boards/arm/nucleo_f411re/pinmux.c deleted file mode 100644 index c9bebe4d040775..00000000000000 --- a/boards/arm/nucleo_f411re/pinmux.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2016 Linaro Limited. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F411RE board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB3, STM32F4_PINMUX_FUNC_PB3_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PA8, STM32F4_PINMUX_FUNC_PA8_I2C3_SCL}, - {STM32_PIN_PB4, STM32F4_PINMUX_FUNC_PB4_I2C3_SDA}, -#endif -#if (DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI) || \ - (DT_NODE_HAS_STATUS(DT_NODELABEL(i2s1), okay) && CONFIG_I2S) -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f412zg/CMakeLists.txt b/boards/arm/nucleo_f412zg/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f412zg/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f412zg/nucleo_f412zg.dts b/boards/arm/nucleo_f412zg/nucleo_f412zg.dts index 5bdfd31a4ed1c1..d61bd82b381dd3 100644 --- a/boards/arm/nucleo_f412zg/nucleo_f412zg.dts +++ b/boards/arm/nucleo_f412zg/nucleo_f412zg.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F412ZG-NUCLEO board"; - compatible = "st,stm32f412zg-nucleo", "st,stm32f412"; + compatible = "st,stm32f412zg-nucleo"; chosen { zephyr,console = &usart3; @@ -52,25 +53,31 @@ }; &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; @@ -79,6 +86,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; diff --git a/boards/arm/nucleo_f412zg/nucleo_f412zg_defconfig b/boards/arm/nucleo_f412zg/nucleo_f412zg_defconfig index 29a9e375a4653a..374079a418da9d 100644 --- a/boards/arm/nucleo_f412zg/nucleo_f412zg_defconfig +++ b/boards/arm/nucleo_f412zg/nucleo_f412zg_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/nucleo_f412zg/pinmux.c b/boards/arm/nucleo_f412zg/pinmux.c deleted file mode 100644 index e4e2353065761c..00000000000000 --- a/boards/arm/nucleo_f412zg/pinmux.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 Florian Vaussard, HEIG-VD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F412ZG board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PD8, STM32F4_PINMUX_FUNC_PD8_USART3_TX}, - {STM32_PIN_PD9, STM32F4_PINMUX_FUNC_PD9_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PG14, STM32F4_PINMUX_FUNC_PG14_USART6_TX}, - {STM32_PIN_PG9, STM32F4_PINMUX_FUNC_PG9_USART6_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32F4_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f413zh/CMakeLists.txt b/boards/arm/nucleo_f413zh/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f413zh/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f413zh/nucleo_f413zh.dts b/boards/arm/nucleo_f413zh/nucleo_f413zh.dts index fbcc283155bfbc..e2119baa6f6126 100644 --- a/boards/arm/nucleo_f413zh/nucleo_f413zh.dts +++ b/boards/arm/nucleo_f413zh/nucleo_f413zh.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F413ZH-NUCLEO board"; - compatible = "st,stm32f413zh-nucleo", "st,stm32f413"; + compatible = "st,stm32f413zh-nucleo"; chosen { zephyr,console = &usart3; @@ -52,25 +53,31 @@ }; &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; @@ -79,6 +86,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; diff --git a/boards/arm/nucleo_f413zh/nucleo_f413zh_defconfig b/boards/arm/nucleo_f413zh/nucleo_f413zh_defconfig index bc7d036ea353e3..e9a82e993f7ec9 100644 --- a/boards/arm/nucleo_f413zh/nucleo_f413zh_defconfig +++ b/boards/arm/nucleo_f413zh/nucleo_f413zh_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/nucleo_f413zh/pinmux.c b/boards/arm/nucleo_f413zh/pinmux.c deleted file mode 100644 index 17bfc1fc5974b7..00000000000000 --- a/boards/arm/nucleo_f413zh/pinmux.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 Florian Vaussard, HEIG-VD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F413ZH board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PD8, STM32F4_PINMUX_FUNC_PD8_USART3_TX}, - {STM32_PIN_PD9, STM32F4_PINMUX_FUNC_PD9_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PG14, STM32F4_PINMUX_FUNC_PG14_USART6_TX}, - {STM32_PIN_PG9, STM32F4_PINMUX_FUNC_PG9_USART6_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32F4_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f429zi/CMakeLists.txt b/boards/arm/nucleo_f429zi/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f429zi/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f429zi/Kconfig.defconfig b/boards/arm/nucleo_f429zi/Kconfig.defconfig index b194ab79760d8b..99fdd74ade1162 100644 --- a/boards/arm/nucleo_f429zi/Kconfig.defconfig +++ b/boards/arm/nucleo_f429zi/Kconfig.defconfig @@ -13,9 +13,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_STM32_HAL - default y - endif # NETWORKING endif # BOARD_NUCLEO_F429ZI diff --git a/boards/arm/nucleo_f429zi/arduino_r3_connector.dtsi b/boards/arm/nucleo_f429zi/arduino_r3_connector.dtsi index f7291f9b8d4ae7..067c3c6c676549 100644 --- a/boards/arm/nucleo_f429zi/arduino_r3_connector.dtsi +++ b/boards/arm/nucleo_f429zi/arduino_r3_connector.dtsi @@ -20,7 +20,7 @@ <7 0 &gpiog 14 0>, /* D1 */ <8 0 &gpiof 15 0>, /* D2 */ <9 0 &gpioe 13 0>, /* D3 */ - <10 0 &gpioe 14 0>, /* D4 */ + <10 0 &gpiof 14 0>, /* D4 */ <11 0 &gpioe 11 0>, /* D5 */ <12 0 &gpioe 9 0>, /* D6 */ <13 0 &gpiof 13 0>, /* D7 */ diff --git a/boards/arm/nucleo_f429zi/doc/index.rst b/boards/arm/nucleo_f429zi/doc/index.rst index dbd44b7ecd10af..55ec85f301d9fe 100644 --- a/boards/arm/nucleo_f429zi/doc/index.rst +++ b/boards/arm/nucleo_f429zi/doc/index.rst @@ -105,6 +105,8 @@ The Zephyr nucleo_f429zi board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | independent watchdog | +-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -161,6 +163,7 @@ and a ST morpho connector. Board is configured as follows - LD3 : PB14 - USB DM : PA11 - USB DP : PA12 +- ADC1 : PA0 System Clock ------------ @@ -186,7 +189,7 @@ Flash partitions for MCUBoot bootloader *************************************** The on-board STM32F429ZI MCU has 2MBs of internal flash memory. To use `MCUboot`_, -define a :ref:`Zephyr partition table ` for the flash memory in +define a :ref:`Zephyr partition table ` for the flash memory in its devicetree file ``nucleo_f429zi.dts``. As a reference, a partition table for MCUBoot is already defined in the devicetree file, with these settings: diff --git a/boards/arm/nucleo_f429zi/nucleo_f429zi.dts b/boards/arm/nucleo_f429zi/nucleo_f429zi.dts index 2c30073d2c4bde..1bb11de28f65ac 100644 --- a/boards/arm/nucleo_f429zi/nucleo_f429zi.dts +++ b/boards/arm/nucleo_f429zi/nucleo_f429zi.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F429ZI-NUCLEO board"; - compatible = "st,stm32f429zi-nucleo", "st,stm32f429"; + compatible = "st,stm32f429zi-nucleo"; chosen { zephyr,console = &usart3; @@ -53,25 +54,36 @@ }; }; +&adc1 { + pinctrl-0 = <&adc1_in0_pa0>; + status = "okay"; +}; + &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>; current-speed = <115200>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; @@ -80,6 +92,7 @@ pwm1: pwm { status = "okay"; + pinctrl-0 = <&tim1_ch3_pe13>; }; }; @@ -95,10 +108,23 @@ status = "okay"; }; +&mac { + status = "okay"; + pinctrl-0 = <ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pb13>; +}; + &flash0 { /* * For more information, see: - * http://docs.zephyrproject.org/devices/dts/flash_partitions.html + * https://docs.zephyrproject.org/latest/reference/devicetree/index.html#fixed-flash-partitions */ partitions { compatible = "fixed-partitions"; diff --git a/boards/arm/nucleo_f429zi/nucleo_f429zi.yaml b/boards/arm/nucleo_f429zi/nucleo_f429zi.yaml index 0ecb71d65f4e9e..9d1268bbcb1470 100644 --- a/boards/arm/nucleo_f429zi/nucleo_f429zi.yaml +++ b/boards/arm/nucleo_f429zi/nucleo_f429zi.yaml @@ -20,3 +20,4 @@ supported: - counter - usb_device - watchdog + - adc diff --git a/boards/arm/nucleo_f429zi/nucleo_f429zi_defconfig b/boards/arm/nucleo_f429zi/nucleo_f429zi_defconfig index e8a47cef6f9bf9..9d1d10d2ec1e64 100644 --- a/boards/arm/nucleo_f429zi/nucleo_f429zi_defconfig +++ b/boards/arm/nucleo_f429zi/nucleo_f429zi_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/nucleo_f429zi/old.CMakeLists.txt b/boards/arm/nucleo_f429zi/old.CMakeLists.txt new file mode 100644 index 00000000000000..0875f8d23a9d2a --- /dev/null +++ b/boards/arm/nucleo_f429zi/old.CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_PINMUX) +zephyr_library() +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) +endif() diff --git a/boards/arm/nucleo_f429zi/pinmux.c b/boards/arm/nucleo_f429zi/pinmux.c deleted file mode 100644 index d38a271990d3dc..00000000000000 --- a/boards/arm/nucleo_f429zi/pinmux.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2017 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-F429ZI board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PD8, STM32F4_PINMUX_FUNC_PD8_USART3_TX}, - {STM32_PIN_PD9, STM32F4_PINMUX_FUNC_PD9_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PG14, STM32F4_PINMUX_FUNC_PG14_USART6_TX}, - {STM32_PIN_PG9, STM32F4_PINMUX_FUNC_PG9_USART6_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - {STM32_PIN_PE13, STM32F4_PINMUX_FUNC_PE13_PWM1_CH3}, -#endif -#ifdef CONFIG_ETH_STM32_HAL - {STM32_PIN_PC1, STM32F4_PINMUX_FUNC_PC1_ETH}, - {STM32_PIN_PC4, STM32F4_PINMUX_FUNC_PC4_ETH}, - {STM32_PIN_PC5, STM32F4_PINMUX_FUNC_PC5_ETH}, - - {STM32_PIN_PA1, STM32F4_PINMUX_FUNC_PA1_ETH}, - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_ETH}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_ETH}, - - {STM32_PIN_PG11, STM32F4_PINMUX_FUNC_PG11_ETH}, - {STM32_PIN_PG13, STM32F4_PINMUX_FUNC_PG13_ETH}, - {STM32_PIN_PB13, STM32F4_PINMUX_FUNC_PB13_ETH}, -#endif /* CONFIG_ETH_STM32_HAL */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f446re/CMakeLists.txt b/boards/arm/nucleo_f446re/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f446re/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f446re/nucleo_f446re.dts b/boards/arm/nucleo_f446re/nucleo_f446re.dts index a28c101e07dfad..32aeb9b67a9412 100644 --- a/boards/arm/nucleo_f446re/nucleo_f446re.dts +++ b/boards/arm/nucleo_f446re/nucleo_f446re.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F446RE-NUCLEO board"; - compatible = "st,stm32f446re-nucleo", "st,stm32f446"; + compatible = "st,stm32f446re-nucleo"; chosen { zephyr,console = &usart2; @@ -42,31 +43,38 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb3>; status = "okay"; clock-frequency = ; }; &i2c3 { + pinctrl-0 = <&i2c3_scl_pa8 &i2c3_sda_pb4>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; @@ -75,10 +83,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/nucleo_f446re/nucleo_f446re_defconfig b/boards/arm/nucleo_f446re/nucleo_f446re_defconfig index 89cef54ef78223..c2af883a35d5f0 100644 --- a/boards/arm/nucleo_f446re/nucleo_f446re_defconfig +++ b/boards/arm/nucleo_f446re/nucleo_f446re_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/nucleo_f446re/pinmux.c b/boards/arm/nucleo_f446re/pinmux.c deleted file mode 100644 index bd4ae68bac643e..00000000000000 --- a/boards/arm/nucleo_f446re/pinmux.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2018 Philémon Jaermann - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for stm32F446RE Nucleo board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB3, STM32F4_PINMUX_FUNC_PB3_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PA8, STM32F4_PINMUX_FUNC_PA8_I2C3_SCL}, - {STM32_PIN_PB4, STM32F4_PINMUX_FUNC_PB4_I2C3_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F4_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F4_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F4_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f746zg/CMakeLists.txt b/boards/arm/nucleo_f746zg/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f746zg/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f746zg/Kconfig.defconfig b/boards/arm/nucleo_f746zg/Kconfig.defconfig index c448b825e97e38..8e021fdf61af2e 100644 --- a/boards/arm/nucleo_f746zg/Kconfig.defconfig +++ b/boards/arm/nucleo_f746zg/Kconfig.defconfig @@ -13,9 +13,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_STM32_HAL - default y - endif # NETWORKING endif # BOARD_NUCLEO_F746ZG diff --git a/boards/arm/nucleo_f746zg/nucleo_f746zg.dts b/boards/arm/nucleo_f746zg/nucleo_f746zg.dts index df81518d389f20..f493ccee3a75dd 100644 --- a/boards/arm/nucleo_f746zg/nucleo_f746zg.dts +++ b/boards/arm/nucleo_f746zg/nucleo_f746zg.dts @@ -6,11 +6,19 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" +/* + * WARNING: The pin PA7 will conflict on selection of SPI_1 and ETH_STM32_HAL. + * If you require both peripherals, and you do not need Arduino Uno v3 + * comaptability, the pin PB5 (also on ST Zio connector) can be used + * for the SPI_1 MOSI signal. + */ + / { model = "STMicroelectronics STM32F746ZG-NUCLEO board"; - compatible = "st,stm32f746zg-nucleo", "st,stm32f746"; + compatible = "st,stm32f746zg-nucleo"; chosen { zephyr,console = &usart3; @@ -53,21 +61,31 @@ }; }; +&usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6 + &usart2_rts_pd4 &usart2_cts_pd3>; + current-speed = <115200>; +}; + &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>; current-speed = <115200>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; @@ -77,14 +95,13 @@ pwm1: pwm { status = "okay"; + pinctrl-0 = <&tim1_ch3_pe13>; }; }; &spi1 { - /* - * WARNING: The pin PA7 will conflict on selection of SPI_1 and - * ETH_STM32_HAL. See pinmux.c for further details. - */ + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; @@ -97,6 +114,7 @@ }; &can1 { + pinctrl-0 = <&can1_rx_pd0 &can1_tx_pd1>; bus-speed = <125000>; sjw = <1>; prop-seg = <0>; @@ -106,9 +124,23 @@ }; &adc1 { + pinctrl-0 = <&adc1_in0_pa0>; status = "okay"; }; &rng { status = "okay"; }; + +&mac { + status = "okay"; + pinctrl-0 = <ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pb13>; +}; diff --git a/boards/arm/nucleo_f746zg/nucleo_f746zg_defconfig b/boards/arm/nucleo_f746zg/nucleo_f746zg_defconfig index a21a12186eee85..fb8a70e4089097 100644 --- a/boards/arm/nucleo_f746zg/nucleo_f746zg_defconfig +++ b/boards/arm/nucleo_f746zg/nucleo_f746zg_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable UART CONFIG_SERIAL=y diff --git a/boards/arm/nucleo_f746zg/pinmux.c b/boards/arm/nucleo_f746zg/pinmux.c deleted file mode 100644 index 86a40c3745d595..00000000000000 --- a/boards/arm/nucleo_f746zg/pinmux.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2018 AJ Palmer - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* NUCLEO-F746ZG pin configurations - * - * WARNING: The pin PA7 will conflict on selection of SPI_1 and ETH_STM32_HAL. - * If you require both peripherals, and you do not need Arduino Uno v3 - * comaptability, the pin PB5 (also on ST Zio connector) can be used - * for the SPI_1 MOSI signal. - */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - { STM32_PIN_PD5, STM32F7_PINMUX_FUNC_PD5_USART2_TX }, - { STM32_PIN_PD6, STM32F7_PINMUX_FUNC_PD6_USART2_RX }, - { STM32_PIN_PD4, STM32F7_PINMUX_FUNC_PD4_USART2_RTS }, - { STM32_PIN_PD3, STM32F7_PINMUX_FUNC_PD3_USART2_CTS }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - { STM32_PIN_PD8, STM32F7_PINMUX_FUNC_PD8_USART3_TX }, - { STM32_PIN_PD9, STM32F7_PINMUX_FUNC_PD9_USART3_RX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - { STM32_PIN_PG14, STM32F7_PINMUX_FUNC_PG14_USART6_TX }, - { STM32_PIN_PG9, STM32F7_PINMUX_FUNC_PG9_USART6_RX }, -#endif -#ifdef CONFIG_ETH_STM32_HAL - { STM32_PIN_PC1, STM32F7_PINMUX_FUNC_PC1_ETH }, - { STM32_PIN_PC4, STM32F7_PINMUX_FUNC_PC4_ETH }, - { STM32_PIN_PC5, STM32F7_PINMUX_FUNC_PC5_ETH }, - { STM32_PIN_PA1, STM32F7_PINMUX_FUNC_PA1_ETH }, - { STM32_PIN_PA2, STM32F7_PINMUX_FUNC_PA2_ETH }, - { STM32_PIN_PA7, STM32F7_PINMUX_FUNC_PA7_ETH }, - { STM32_PIN_PG11, STM32F7_PINMUX_FUNC_PG11_ETH }, - { STM32_PIN_PG13, STM32F7_PINMUX_FUNC_PG13_ETH }, - { STM32_PIN_PB13, STM32F7_PINMUX_FUNC_PB13_ETH }, -#endif /* CONFIG_ETH_STM32_HAL */ -#ifdef CONFIG_USB_DC_STM32 - { STM32_PIN_PA11, STM32F7_PINMUX_FUNC_PA11_OTG_FS_DM }, - { STM32_PIN_PA12, STM32F7_PINMUX_FUNC_PA12_OTG_FS_DP }, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - { STM32_PIN_PB8, STM32F7_PINMUX_FUNC_PB8_I2C1_SCL }, - { STM32_PIN_PB9, STM32F7_PINMUX_FUNC_PB9_I2C1_SDA }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - { STM32_PIN_PE13, STM32F7_PINMUX_FUNC_PE13_PWM1_CH3 }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - { STM32_PIN_PA4, STM32F7_PINMUX_FUNC_PA4_SPI1_NSS }, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - { STM32_PIN_PA5, STM32F7_PINMUX_FUNC_PA5_SPI1_SCK }, - { STM32_PIN_PA6, STM32F7_PINMUX_FUNC_PA6_SPI1_MISO }, - { STM32_PIN_PA7, STM32F7_PINMUX_FUNC_PA7_SPI1_MOSI }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PD0, STM32F7_PINMUX_FUNC_PD0_CAN_RX}, - {STM32_PIN_PD1, STM32F7_PINMUX_FUNC_PD1_CAN_TX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - { STM32_PIN_PA0, STM32F7_PINMUX_FUNC_PA0_ADC123_IN0 }, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f756zg/CMakeLists.txt b/boards/arm/nucleo_f756zg/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f756zg/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f756zg/Kconfig.defconfig b/boards/arm/nucleo_f756zg/Kconfig.defconfig index 8b330e10b6eca3..d6b1759beb51de 100644 --- a/boards/arm/nucleo_f756zg/Kconfig.defconfig +++ b/boards/arm/nucleo_f756zg/Kconfig.defconfig @@ -13,9 +13,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_STM32_HAL - default y - endif # NETWORKING endif # BOARD_NUCLEO_F756ZG diff --git a/boards/arm/nucleo_f756zg/nucleo_f756zg.dts b/boards/arm/nucleo_f756zg/nucleo_f756zg.dts index 6d02b6aaa8c1c7..847150491ccb27 100644 --- a/boards/arm/nucleo_f756zg/nucleo_f756zg.dts +++ b/boards/arm/nucleo_f756zg/nucleo_f756zg.dts @@ -6,11 +6,19 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" +/* + * WARNING: The pin PA7 will conflict on selection of SPI_1 and ETH_STM32_HAL. + * If you require both peripherals, and you do not need Arduino Uno v3 + * comaptability, the pin PB5 (also on ST Zio connector) can be used + * for the SPI_1 MOSI signal. + */ + / { model = "STMicroelectronics STM32F756ZG-NUCLEO board"; - compatible = "st,stm32f756zg-nucleo", "st,stm32f756"; + compatible = "st,stm32f756zg-nucleo"; chosen { zephyr,console = &usart3; @@ -53,25 +61,31 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6 + &usart2_rts_pd4 &usart2_cts_pd3>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>; current-speed = <115200>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; @@ -81,13 +95,25 @@ pwm1: pwm { status = "okay"; + pinctrl-0 = <&tim1_ch3_pe13>; }; }; &spi1 { - /* - * WARNING: The pin PA7 will conflict on selection of SPI_1 and - * ETH_STM32_HAL. See pinmux.c for further details. - */ + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&mac { status = "okay"; + pinctrl-0 = <ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pb13>; }; diff --git a/boards/arm/nucleo_f756zg/nucleo_f756zg_defconfig b/boards/arm/nucleo_f756zg/nucleo_f756zg_defconfig index 5c779428f20e15..3559d2f1430889 100644 --- a/boards/arm/nucleo_f756zg/nucleo_f756zg_defconfig +++ b/boards/arm/nucleo_f756zg/nucleo_f756zg_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable UART CONFIG_SERIAL=y diff --git a/boards/arm/nucleo_f756zg/pinmux.c b/boards/arm/nucleo_f756zg/pinmux.c deleted file mode 100644 index eb6a8e6a9d2f89..00000000000000 --- a/boards/arm/nucleo_f756zg/pinmux.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2018 AJ Palmer - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* NUCLEO-F756ZG pin configurations - * - * WARNING: The pin PA7 will conflict on selection of SPI_1 and ETH_STM32_HAL. - * If you require both peripherals, and you do not need Arduino Uno v3 - * comaptability, the pin PB5 (also on ST Zio connector) can be used - * for the SPI_1 MOSI signal. - */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - { STM32_PIN_PD5, STM32F7_PINMUX_FUNC_PD5_USART2_TX }, - { STM32_PIN_PD6, STM32F7_PINMUX_FUNC_PD6_USART2_RX }, - { STM32_PIN_PD4, STM32F7_PINMUX_FUNC_PD4_USART2_RTS }, - { STM32_PIN_PD3, STM32F7_PINMUX_FUNC_PD3_USART2_CTS }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - { STM32_PIN_PD8, STM32F7_PINMUX_FUNC_PD8_USART3_TX }, - { STM32_PIN_PD9, STM32F7_PINMUX_FUNC_PD9_USART3_RX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - { STM32_PIN_PG14, STM32F7_PINMUX_FUNC_PG14_USART6_TX }, - { STM32_PIN_PG9, STM32F7_PINMUX_FUNC_PG9_USART6_RX }, -#endif -#ifdef CONFIG_ETH_STM32_HAL - { STM32_PIN_PC1, STM32F7_PINMUX_FUNC_PC1_ETH }, - { STM32_PIN_PC4, STM32F7_PINMUX_FUNC_PC4_ETH }, - { STM32_PIN_PC5, STM32F7_PINMUX_FUNC_PC5_ETH }, - { STM32_PIN_PA1, STM32F7_PINMUX_FUNC_PA1_ETH }, - { STM32_PIN_PA2, STM32F7_PINMUX_FUNC_PA2_ETH }, - { STM32_PIN_PA7, STM32F7_PINMUX_FUNC_PA7_ETH }, - { STM32_PIN_PG11, STM32F7_PINMUX_FUNC_PG11_ETH }, - { STM32_PIN_PG13, STM32F7_PINMUX_FUNC_PG13_ETH }, - { STM32_PIN_PB13, STM32F7_PINMUX_FUNC_PB13_ETH }, -#endif /* CONFIG_ETH_STM32_HAL */ -#ifdef CONFIG_USB_DC_STM32 - { STM32_PIN_PA11, STM32F7_PINMUX_FUNC_PA11_OTG_FS_DM }, - { STM32_PIN_PA12, STM32F7_PINMUX_FUNC_PA12_OTG_FS_DP }, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - { STM32_PIN_PB8, STM32F7_PINMUX_FUNC_PB8_I2C1_SCL }, - { STM32_PIN_PB9, STM32F7_PINMUX_FUNC_PB9_I2C1_SDA }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - { STM32_PIN_PE13, STM32F7_PINMUX_FUNC_PE13_PWM1_CH3 }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - { STM32_PIN_PA4, STM32F7_PINMUX_FUNC_PA4_SPI1_NSS }, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - { STM32_PIN_PA5, STM32F7_PINMUX_FUNC_PA5_SPI1_SCK }, - { STM32_PIN_PA6, STM32F7_PINMUX_FUNC_PA6_SPI1_MISO }, - { STM32_PIN_PA7, STM32F7_PINMUX_FUNC_PA7_SPI1_MOSI }, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_f767zi/CMakeLists.txt b/boards/arm/nucleo_f767zi/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_f767zi/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_f767zi/Kconfig.defconfig b/boards/arm/nucleo_f767zi/Kconfig.defconfig index 1c19a38c338660..b53353b2b06602 100644 --- a/boards/arm/nucleo_f767zi/Kconfig.defconfig +++ b/boards/arm/nucleo_f767zi/Kconfig.defconfig @@ -13,9 +13,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_STM32_HAL - default y - endif # NETWORKING endif # BOARD_NUCLEO_F767ZI diff --git a/boards/arm/nucleo_f767zi/doc/index.rst b/boards/arm/nucleo_f767zi/doc/index.rst index 214013886f83a8..561812622a97d0 100644 --- a/boards/arm/nucleo_f767zi/doc/index.rst +++ b/boards/arm/nucleo_f767zi/doc/index.rst @@ -104,7 +104,7 @@ features: +-----------+------------+-------------------------------------+ | GPIO | on-chip | gpio | +-----------+------------+-------------------------------------+ -| ETHERNET | on-chip | ethernet | +| ETHERNET | on-chip | ethernet (*) | +-----------+------------+-------------------------------------+ | USB | on-chip | usb_device | +-----------+------------+-------------------------------------+ @@ -120,6 +120,14 @@ features: +-----------+------------+-------------------------------------+ | ADC | on-chip | ADC Controller | +-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ + +(*) nucleo_f767zi with soc cut-A (Device marking A) has some ethernet + instability (https://github.com/zephyrproject-rtos/zephyr/issues/26519). + Use of cut-Z is advised. + see restrictions errata: + https://www.st.com/content/ccc/resource/technical/document/errata_sheet/group0/23/a6/11/0b/30/24/46/a5/DM00257543/files/DM00257543.pdf/jcr:content/translations/en.DM00257543.pdf Other hardware features are not yet supported on this Zephyr port. diff --git a/boards/arm/nucleo_f767zi/nucleo_f767zi.dts b/boards/arm/nucleo_f767zi/nucleo_f767zi.dts index df56af1ab78236..54cf17deac9930 100644 --- a/boards/arm/nucleo_f767zi/nucleo_f767zi.dts +++ b/boards/arm/nucleo_f767zi/nucleo_f767zi.dts @@ -6,17 +6,26 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" +/* + * WARNING: The pin PA7 will conflict on selection of SPI_1 and ETH_STM32_HAL. + * If you require both peripherals, and you do not need Arduino Uno v3 + * comaptability, the pin PB5 (also on ST Zio connector) can be used + * for the SPI_1 MOSI signal. + */ + / { model = "STMicroelectronics STM32F767ZI-NUCLEO board"; - compatible = "st,stm32f767zi-nucleo", "st,stm32f767"; + compatible = "st,stm32f767zi-nucleo"; chosen { zephyr,console = &usart3; zephyr,shell-uart = &usart3; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; zephyr,dtcm = &dtcm; zephyr,can-primary = &can1; }; @@ -53,21 +62,33 @@ }; }; +&usart2 { + pinctrl-0 = <&usart2_tx_pd5 + &usart2_rx_pd6 + &usart2_rts_pd4 + &usart2_cts_pd3>; + current-speed = <115200>; +}; + &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>; current-speed = <115200>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; @@ -77,13 +98,16 @@ pwm1: pwm { status = "okay"; + pinctrl-0 = <&tim1_ch3_pe13>; }; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; /* * WARNING: The pin PA7 will conflict on selection of SPI_1 and - * ETH_STM32_HAL. See pinmux.c for further details. + * ETH_STM32_HAL. */ status = "okay"; }; @@ -97,6 +121,7 @@ }; &can1 { + pinctrl-0 = <&can1_rx_pd0 &can1_tx_pd1>; bus-speed = <125000>; sjw = <1>; prop-seg = <0>; @@ -106,5 +131,79 @@ }; &adc1 { + pinctrl-0 = <&adc1_in0_pa0>; status = "okay"; }; + +&rng { + status = "okay"; +}; + +&mac { + status = "okay"; + pinctrl-0 = <ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pb13>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * The two sectors 0-1 (32+32 kbytes) are reserved for + * the bootloader. + */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 0x00010000>; + read-only; + }; + + /* + * The flash starting at offset 0x10000 and ending at + * offset 0x1ffff is reserved for use by the application. + * This represents sectors 2-3 (32+32 kbytes) + */ + storage_partition: partition@10000 { + label = "storage"; + reg = <0x00010000 0x00010000>; + }; + + /* + * Sector 4 (128 kbytes) unallocated. + */ + + /* + * Allocated 3 (256k x 3) sectors for image-0. Sectors 5-7. + */ + slot0_partition: partition@40000 { + label = "image-0"; + reg = <0x00040000 0x000C0000>; + }; + + /* + * Allocated 3 (256k x 3) sectors for image-1. Sectors 8-10. + */ + slot1_partition: partition@100000 { + label = "image-1"; + reg = <0x00100000 0x000C0000>; + }; + + /* + * Allocated 1 (256k) sector for image-scratch. Sector 11. + */ + scratch_partition: partition@1C0000 { + label = "image-scratch"; + reg = <0x001C0000 0x00040000>; + }; + }; +}; diff --git a/boards/arm/nucleo_f767zi/nucleo_f767zi.yaml b/boards/arm/nucleo_f767zi/nucleo_f767zi.yaml index 0018c423858704..ca3646d3285198 100644 --- a/boards/arm/nucleo_f767zi/nucleo_f767zi.yaml +++ b/boards/arm/nucleo_f767zi/nucleo_f767zi.yaml @@ -19,6 +19,7 @@ supported: - i2c - pwm - spi + - nvs - watchdog - counter - can diff --git a/boards/arm/nucleo_f767zi/nucleo_f767zi_defconfig b/boards/arm/nucleo_f767zi/nucleo_f767zi_defconfig index 285ed18479a5c0..ebacc2d03c18b2 100644 --- a/boards/arm/nucleo_f767zi/nucleo_f767zi_defconfig +++ b/boards/arm/nucleo_f767zi/nucleo_f767zi_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable UART CONFIG_SERIAL=y diff --git a/boards/arm/nucleo_f767zi/pinmux.c b/boards/arm/nucleo_f767zi/pinmux.c deleted file mode 100644 index 273d38e9c2e9b9..00000000000000 --- a/boards/arm/nucleo_f767zi/pinmux.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2019 Roland Ma - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* NUCLEO-F767ZI pin configurations - * - * WARNING: The pin PA7 will conflict on selection of SPI_1 and ETH_STM32_HAL. - * If you require both peripherals, and you do not need Arduino Uno v3 - * comaptability, the pin PB5 (also on ST Zio connector) can be used - * for the SPI_1 MOSI signal. - */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - { STM32_PIN_PD5, STM32F7_PINMUX_FUNC_PD5_USART2_TX }, - { STM32_PIN_PD6, STM32F7_PINMUX_FUNC_PD6_USART2_RX }, - { STM32_PIN_PD4, STM32F7_PINMUX_FUNC_PD4_USART2_RTS }, - { STM32_PIN_PD3, STM32F7_PINMUX_FUNC_PD3_USART2_CTS }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - { STM32_PIN_PD8, STM32F7_PINMUX_FUNC_PD8_USART3_TX }, - { STM32_PIN_PD9, STM32F7_PINMUX_FUNC_PD9_USART3_RX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - { STM32_PIN_PG14, STM32F7_PINMUX_FUNC_PG14_USART6_TX }, - { STM32_PIN_PG9, STM32F7_PINMUX_FUNC_PG9_USART6_RX }, -#endif -#ifdef CONFIG_ETH_STM32_HAL - { STM32_PIN_PC1, STM32F7_PINMUX_FUNC_PC1_ETH }, - { STM32_PIN_PC4, STM32F7_PINMUX_FUNC_PC4_ETH }, - { STM32_PIN_PC5, STM32F7_PINMUX_FUNC_PC5_ETH }, - { STM32_PIN_PA1, STM32F7_PINMUX_FUNC_PA1_ETH }, - { STM32_PIN_PA2, STM32F7_PINMUX_FUNC_PA2_ETH }, - { STM32_PIN_PA7, STM32F7_PINMUX_FUNC_PA7_ETH }, - { STM32_PIN_PG11, STM32F7_PINMUX_FUNC_PG11_ETH }, - { STM32_PIN_PG13, STM32F7_PINMUX_FUNC_PG13_ETH }, - { STM32_PIN_PB13, STM32F7_PINMUX_FUNC_PB13_ETH }, -#endif /* CONFIG_ETH_STM32_HAL */ -#ifdef CONFIG_USB_DC_STM32 - { STM32_PIN_PA11, STM32F7_PINMUX_FUNC_PA11_OTG_FS_DM }, - { STM32_PIN_PA12, STM32F7_PINMUX_FUNC_PA12_OTG_FS_DP }, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - { STM32_PIN_PB8, STM32F7_PINMUX_FUNC_PB8_I2C1_SCL }, - { STM32_PIN_PB9, STM32F7_PINMUX_FUNC_PB9_I2C1_SDA }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - { STM32_PIN_PE13, STM32F7_PINMUX_FUNC_PE13_PWM1_CH3 }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - { STM32_PIN_PA4, STM32F7_PINMUX_FUNC_PA4_SPI1_NSS }, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - { STM32_PIN_PA5, STM32F7_PINMUX_FUNC_PA5_SPI1_SCK }, - { STM32_PIN_PA6, STM32F7_PINMUX_FUNC_PA6_SPI1_MISO }, - { STM32_PIN_PA7, STM32F7_PINMUX_FUNC_PA7_SPI1_MOSI }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PD0, STM32F7_PINMUX_FUNC_PD0_CAN_RX}, - {STM32_PIN_PD1, STM32F7_PINMUX_FUNC_PD1_CAN_TX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - { STM32_PIN_PA0, STM32F7_PINMUX_FUNC_PA0_ADC123_IN0 }, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_g071rb/CMakeLists.txt b/boards/arm/nucleo_g071rb/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_g071rb/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_g071rb/board.cmake b/boards/arm/nucleo_g071rb/board.cmake index 7eb383fb056b1e..88bba735ff9b15 100644 --- a/boards/arm/nucleo_g071rb/board.cmake +++ b/boards/arm/nucleo_g071rb/board.cmake @@ -1,5 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(pyocd "--target=stm32g071rb") +board_runner_args(pyocd "--target=stm32g071rbtx") board_runner_args(pyocd "--flash-opt=-O reset_type=hw") board_runner_args(pyocd "--flash-opt=-O connect_mode=under-reset") diff --git a/boards/arm/nucleo_g071rb/doc/index.rst b/boards/arm/nucleo_g071rb/doc/index.rst index 5bf6acfc23669b..5219c8a52711ee 100644 --- a/boards/arm/nucleo_g071rb/doc/index.rst +++ b/boards/arm/nucleo_g071rb/doc/index.rst @@ -98,6 +98,8 @@ The Zephyr nucleo_g071rb board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | independent watchdog | +-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported in this Zephyr port. @@ -119,6 +121,7 @@ Default Zephyr Peripheral Mapping: - UART_2 TX/RX : PA2/PA3 (ST-Link Virtual Port Com) - USER_PB : PC13 - LD4 : PA5 +- PWM : PA6 For mode details please refer to `STM32 Nucleo-64 board User Manual`_. @@ -141,6 +144,7 @@ the following pyocd command: .. code-block:: console + $ pyocd pack --update $ pyocd pack --install stm32g071rb Note: diff --git a/boards/arm/nucleo_g071rb/nucleo_g071rb.dts b/boards/arm/nucleo_g071rb/nucleo_g071rb.dts index add420d9592241..b715826d6064d6 100644 --- a/boards/arm/nucleo_g071rb/nucleo_g071rb.dts +++ b/boards/arm/nucleo_g071rb/nucleo_g071rb.dts @@ -7,11 +7,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32G071RB-NUCLEO board"; - compatible = "st,stm32g071rb-nucleo", "st,stm32g071"; + compatible = "st,stm32g071rb-nucleo"; chosen { zephyr,console = &usart2; @@ -43,6 +44,7 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; @@ -50,3 +52,11 @@ &iwdg { status = "okay"; }; + +&timers3 { + status = "okay"; + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&tim3_ch1_pa6>; + }; +}; diff --git a/boards/arm/nucleo_g071rb/nucleo_g071rb.yaml b/boards/arm/nucleo_g071rb/nucleo_g071rb.yaml index 67ed6be3622b7b..2f690dae313dfb 100644 --- a/boards/arm/nucleo_g071rb/nucleo_g071rb.yaml +++ b/boards/arm/nucleo_g071rb/nucleo_g071rb.yaml @@ -13,3 +13,4 @@ supported: - uart - gpio - watchdog + - pwm diff --git a/boards/arm/nucleo_g071rb/pinmux.c b/boards/arm/nucleo_g071rb/pinmux.c deleted file mode 100644 index 4f45c5ebe75099..00000000000000 --- a/boards/arm/nucleo_g071rb/pinmux.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2019 Philippe Retornaz - * Copyright (c) 2019 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-G071RB board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32G0_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32G0_PINMUX_FUNC_PA3_USART2_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_g431rb/CMakeLists.txt b/boards/arm/nucleo_g431rb/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_g431rb/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_g431rb/doc/index.rst b/boards/arm/nucleo_g431rb/doc/index.rst index 416b5f35d2788e..4cfce550dece5d 100644 --- a/boards/arm/nucleo_g431rb/doc/index.rst +++ b/boards/arm/nucleo_g431rb/doc/index.rst @@ -115,6 +115,8 @@ The Zephyr nucleo_g431rb board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | PWM | on-chip | pwm | +-----------+------------+-------------------------------------+ +| DAC | on-chip | dac | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -156,8 +158,7 @@ Default Zephyr Peripheral Mapping: - PWM_3_CH1 : PB4 - USER_PB : PC13 - LD2 : PA5 -- USB DM : PA11 -- USB DP : PA12 +- DAC1_OUT1 : PA4 System Clock ------------ @@ -195,6 +196,7 @@ the following pyocd command: .. code-block:: console + $ pyocd pack --update $ pyocd pack --install stm32g431rb Note: diff --git a/boards/arm/nucleo_g431rb/nucleo_g431rb.dts b/boards/arm/nucleo_g431rb/nucleo_g431rb.dts index 7808186fc7da5f..1f779f1c8ae29c 100644 --- a/boards/arm/nucleo_g431rb/nucleo_g431rb.dts +++ b/boards/arm/nucleo_g431rb/nucleo_g431rb.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32G431RB-NUCLEO board"; - compatible = "st,stm32g431rb-nucleo", "st,stm32g431"; + compatible = "st,stm32g431rb-nucleo"; chosen { zephyr,console = &lpuart1; @@ -31,7 +32,7 @@ compatible = "pwm-leds"; green_pwm_led: green_pwm_led { - pwms = <&pwm2 1 4>; + pwms = <&pwm2 1 4 PWM_POLARITY_NORMAL>; }; }; @@ -51,20 +52,38 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pc4 &usart1_rx_pc5>; current-speed = <115200>; status = "okay"; }; &lpuart1 { + pinctrl-0 = <&lpuart1_tx_pa2 &lpuart1_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pb3 + &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; + status = "okay"; +}; + +&spi3 { + /* SPI3 on the ST Morpho Connector CN7 pins 17, 1, 2, 3*/ + pinctrl-0 = <&spi3_nss_pa15 &spi3_sck_pc10 + &spi3_miso_pc11 &spi3_mosi_pc12>; status = "okay"; }; @@ -73,22 +92,16 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa5>; }; }; -&usb { - status = "okay"; -}; - &rtc { status = "okay"; }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -105,3 +118,8 @@ &iwdg { status = "okay"; }; + +&dac1 { + status = "okay"; + pinctrl-0 = <&dac1_out1_pa4>; +}; diff --git a/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml b/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml index 3a866c59500a9d..e4ca85ff30f546 100644 --- a/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml +++ b/boards/arm/nucleo_g431rb/nucleo_g431rb.yaml @@ -19,3 +19,4 @@ supported: - usb device - counter - spi + - dac diff --git a/boards/arm/nucleo_g431rb/nucleo_g431rb_defconfig b/boards/arm/nucleo_g431rb/nucleo_g431rb_defconfig index 03d1445cfef255..0b3c108c5ca0c2 100644 --- a/boards/arm/nucleo_g431rb/nucleo_g431rb_defconfig +++ b/boards/arm/nucleo_g431rb/nucleo_g431rb_defconfig @@ -55,3 +55,6 @@ CONFIG_UART_CONSOLE=y # Enable MPU CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/nucleo_g431rb/pinmux.c b/boards/arm/nucleo_g431rb/pinmux.c deleted file mode 100644 index 13aabe1e720064..00000000000000 --- a/boards/arm/nucleo_g431rb/pinmux.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2019 Richard Osterloh - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-G431RB board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PC4, STM32G4X_PINMUX_FUNC_PC4_USART1_TX}, - {STM32_PIN_PC5, STM32G4X_PINMUX_FUNC_PC5_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpuart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32G4X_PINMUX_FUNC_PA2_LPUART1_TX}, - {STM32_PIN_PA3, STM32G4X_PINMUX_FUNC_PA3_LPUART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32G4X_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32G4X_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA5, STM32G4X_PINMUX_FUNC_PA5_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - /* SPI1 on the Arduino connectors pins A2, D3, D11, D12 */ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32G4X_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - /* SPI1_SCK should output on PA5, but is used for LD2 */ - {STM32_PIN_PB3, STM32G4X_PINMUX_FUNC_PB3_SPI1_SCK}, - {STM32_PIN_PA6, STM32G4X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32G4X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - /* SPI2 on the ST Morpho Connector CN10 pins 16, 30, 28, 26*/ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32G4X_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32G4X_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32G4X_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32G4X_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi3), okay) && CONFIG_SPI - /* SPI3 on the ST Morpho Connector CN7 pins 17, 1, 2, 3*/ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA15, STM32G4X_PINMUX_FUNC_PA15_SPI3_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PC10, STM32G4X_PINMUX_FUNC_PC10_SPI3_SCK}, - {STM32_PIN_PC11, STM32G4X_PINMUX_FUNC_PC11_SPI3_MISO}, - {STM32_PIN_PC12, STM32G4X_PINMUX_FUNC_PC12_SPI3_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32G4X_PINMUX_FUNC_PA11_USB_DM}, - {STM32_PIN_PA12, STM32G4X_PINMUX_FUNC_PA12_USB_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_g474re/CMakeLists.txt b/boards/arm/nucleo_g474re/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_g474re/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_g474re/doc/index.rst b/boards/arm/nucleo_g474re/doc/index.rst index 601f6b6c80d035..3f3cfd567d0516 100644 --- a/boards/arm/nucleo_g474re/doc/index.rst +++ b/boards/arm/nucleo_g474re/doc/index.rst @@ -113,8 +113,12 @@ The Zephyr nucleo_g474re board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | I2C | on-chip | i2c | +-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ | PWM | on-chip | pwm | +-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -156,8 +160,7 @@ Default Zephyr Peripheral Mapping: - PWM_3_CH1 : PB4 - USER_PB : PC13 - LD2 : PA5 -- USB DM : PA11 -- USB DP : PA12 +- ADC1_IN1 : PA0 System Clock ------------ @@ -195,6 +198,7 @@ the following pyocd command: .. code-block:: console + $ pyocd pack --update $ pyocd pack --install stm32g474re Note: diff --git a/boards/arm/nucleo_g474re/nucleo_g474re.dts b/boards/arm/nucleo_g474re/nucleo_g474re.dts index 774203ecb6bf52..e3023f9b17483b 100644 --- a/boards/arm/nucleo_g474re/nucleo_g474re.dts +++ b/boards/arm/nucleo_g474re/nucleo_g474re.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32G474RE-NUCLEO board"; - compatible = "st,stm32g474re-nucleo", "st,stm32g474"; + compatible = "st,stm32g474re-nucleo"; chosen { zephyr,console = &lpuart1; @@ -31,7 +32,7 @@ compatible = "pwm-leds"; green_pwm_led: green_pwm_led { - pwms = <&pwm2 1 4>; + pwms = <&pwm2 1 4 PWM_POLARITY_NORMAL>; }; }; @@ -51,20 +52,38 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pc4 &usart1_rx_pc5>; current-speed = <115200>; status = "okay"; }; &lpuart1 { + pinctrl-0 = <&lpuart1_tx_pa2 &lpuart1_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pb3 + &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; + status = "okay"; +}; + +&spi3 { + /* SPI3 on the ST Morpho Connector CN7 pins 17, 1, 2, 3*/ + pinctrl-0 = <&spi3_nss_pa15 &spi3_sck_pc10 + &spi3_miso_pc11 &spi3_mosi_pc12>; status = "okay"; }; @@ -73,13 +92,10 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa5>; }; }; -&usb { - status = "okay"; -}; - &rtc { status = "okay"; }; @@ -105,3 +121,12 @@ &iwdg { status = "okay"; }; + +&rng { + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc1_in1_pa0>; + status = "okay"; +}; diff --git a/boards/arm/nucleo_g474re/nucleo_g474re.yaml b/boards/arm/nucleo_g474re/nucleo_g474re.yaml index a24dc95e5d4f7b..5fcc7a8f813523 100644 --- a/boards/arm/nucleo_g474re/nucleo_g474re.yaml +++ b/boards/arm/nucleo_g474re/nucleo_g474re.yaml @@ -19,3 +19,5 @@ supported: - usb device - counter - spi + - watchdog + - adc diff --git a/boards/arm/nucleo_g474re/nucleo_g474re_defconfig b/boards/arm/nucleo_g474re/nucleo_g474re_defconfig index 6356dba1b6c3fc..493cec1f7c6db9 100644 --- a/boards/arm/nucleo_g474re/nucleo_g474re_defconfig +++ b/boards/arm/nucleo_g474re/nucleo_g474re_defconfig @@ -55,3 +55,6 @@ CONFIG_UART_CONSOLE=y # Enable MPU CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/nucleo_g474re/pinmux.c b/boards/arm/nucleo_g474re/pinmux.c deleted file mode 100644 index 8242e0abd982ca..00000000000000 --- a/boards/arm/nucleo_g474re/pinmux.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2019 STMicroelectronics. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-G474RE board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PC4, STM32G4X_PINMUX_FUNC_PC4_USART1_TX}, - {STM32_PIN_PC5, STM32G4X_PINMUX_FUNC_PC5_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpuart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32G4X_PINMUX_FUNC_PA2_LPUART1_TX}, - {STM32_PIN_PA3, STM32G4X_PINMUX_FUNC_PA3_LPUART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32G4X_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32G4X_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA5, STM32G4X_PINMUX_FUNC_PA5_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - /* SPI1 on the Arduino connectors pins A2, D3, D11, D12 */ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32G4X_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - /* SPI1_SCK should output on PA5, but is used for LD2 */ - {STM32_PIN_PB3, STM32G4X_PINMUX_FUNC_PB3_SPI1_SCK}, - {STM32_PIN_PA6, STM32G4X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32G4X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - /* SPI2 on the ST Morpho Connector CN10 pins 16, 30, 28, 26*/ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32G4X_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32G4X_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32G4X_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32G4X_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi3), okay) && CONFIG_SPI - /* SPI3 on the ST Morpho Connector CN7 pins 17, 1, 2, 3*/ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA15, STM32G4X_PINMUX_FUNC_PA15_SPI3_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PC10, STM32G4X_PINMUX_FUNC_PC10_SPI3_SCK}, - {STM32_PIN_PC11, STM32G4X_PINMUX_FUNC_PC11_SPI3_MISO}, - {STM32_PIN_PC12, STM32G4X_PINMUX_FUNC_PC12_SPI3_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32G4X_PINMUX_FUNC_PA11_USB_DM}, - {STM32_PIN_PA12, STM32G4X_PINMUX_FUNC_PA12_USB_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_h723zg/Kconfig.board b/boards/arm/nucleo_h723zg/Kconfig.board new file mode 100644 index 00000000000000..da658f90c6d068 --- /dev/null +++ b/boards/arm/nucleo_h723zg/Kconfig.board @@ -0,0 +1,8 @@ +# STM32H723ZG Nucleo board configuration + +# Copyright (c) 2020 Alexander Kozhinov +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_H723ZG + bool "NUCLEO-H723ZG Development Board" + depends on SOC_STM32H723XX diff --git a/boards/arm/nucleo_h723zg/Kconfig.defconfig b/boards/arm/nucleo_h723zg/Kconfig.defconfig new file mode 100644 index 00000000000000..7b5c327e97d83b --- /dev/null +++ b/boards/arm/nucleo_h723zg/Kconfig.defconfig @@ -0,0 +1,18 @@ +# STM32H723ZG Nucleo board configuration + +# Copyright (c) 2020 Alexander Kozhinov +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NUCLEO_H723ZG + +config BOARD + default "nucleo_h723zg" + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +endif # BOARD_NUCLEO_H723ZG diff --git a/boards/arm/nucleo_h723zg/arduino_r3_connector.dtsi b/boards/arm/nucleo_h723zg/arduino_r3_connector.dtsi new file mode 100644 index 00000000000000..172fadfabee8cc --- /dev/null +++ b/boards/arm/nucleo_h723zg/arduino_r3_connector.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 Alexander Kozhinov + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 3 0>, /* A0 */ + <1 0 &gpioc 0 0>, /* A1 */ + <2 0 &gpioc 3 0>, /* A2 */ + <3 0 &gpiob 1 0>, /* A3 */ + <4 0 &gpioc 2 0>, /* A4 */ + <5 0 &gpiof 10 0>, /* A5 */ + <6 0 &gpiob 7 0>, /* D0 */ + <7 0 &gpiob 6 0>, /* D1 */ + <8 0 &gpiog 14 0>, /* D2 */ + <9 0 &gpioe 13 0>, /* D3 */ + <10 0 &gpioe 14 0>, /* D4 */ + <11 0 &gpioe 11 0>, /* D5 */ + <12 0 &gpioe 9 0>, /* D6 */ + <13 0 &gpiog 12 0>, /* D7 */ + <14 0 &gpiof 3 0>, /* D8 */ + <15 0 &gpiod 15 0>, /* D9 */ + <16 0 &gpiod 14 0>, /* D10 */ + <17 0 &gpiob 5 0>, /* D11 */ + <18 0 &gpioa 6 0>, /* D12 */ + <19 0 &gpioa 5 0>, /* D13 */ + <20 0 &gpiob 9 0>, /* D14 */ + <21 0 &gpiob 8 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c1 {}; + +arduino_serial: &uart8 {}; diff --git a/boards/arm/nucleo_h723zg/board.cmake b/boards/arm/nucleo_h723zg/board.cmake new file mode 100644 index 00000000000000..686a893fd5ccfb --- /dev/null +++ b/boards/arm/nucleo_h723zg/board.cmake @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32H723ZG" "--speed=4000") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset=hw") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) \ No newline at end of file diff --git a/boards/arm/nucleo_h723zg/doc/img/nucleo_h723zg.jpg b/boards/arm/nucleo_h723zg/doc/img/nucleo_h723zg.jpg new file mode 100644 index 00000000000000..ae9b6ba7300585 Binary files /dev/null and b/boards/arm/nucleo_h723zg/doc/img/nucleo_h723zg.jpg differ diff --git a/boards/arm/nucleo_h723zg/doc/index.rst b/boards/arm/nucleo_h723zg/doc/index.rst new file mode 100644 index 00000000000000..8770037c9aa06c --- /dev/null +++ b/boards/arm/nucleo_h723zg/doc/index.rst @@ -0,0 +1,239 @@ +.. _nucleo_h723zg_board: + +ST Nucleo H723ZG +################ + +Overview +******** + +The STM32 Nucleo-144 board provides an affordable and flexible way for users +to try out new concepts and build prototypes by choosing from the various combinations +of performance and power consumption features, provided by the STM32 microcontroller. +For the compatible boards, the internal or external SMPS significantly reduces power +consumption in Run mode. + +The ST Zio connector, which extends the ARDUINO® Uno V3 connectivity, and +the ST morpho headers provide an easy means of expanding the functionality of the Nucleo +open development platform with a wide choice of specialized shields. +The STM32 Nucleo-144 board does not require any separate probe as it integrates +the ST-LINK V3 debugger/programmer. + +The STM32 Nucleo-144 board comes with the STM32 comprehensive free software +libraries and examples available with the STM32Cube MCU Package. + +Key Features + +- STM32 microcontroller in LQFP144 package +- Ethernet compliant with IEEE-802.3-2002 (depending on STM32 support) +- USB OTG or full-speed device (depending on STM32 support) +- 3 user LEDs +- 2 user and reset push-buttons +- 32.768 kHz crystal oscillator +- Board connectors: + + - USB with Micro-AB + - Ethernet RJ45 (depending on STM32 support) + - SWDST Zio connector including Arduino* Uno V3ST + - ST morpho expansion + +- Flexible power-supply options: ST-LINK USB VBUS or external sources +- External or internal SMPS to generate Vcore logic supply +- On-board ST-LINK/V3 debugger/programmer with USB re-enumeration +- capability: mass storage, virtual COM port and debug port +- USB OTG full speed or device only + +.. image:: img/nucleo_h723zg.jpg + :width: 720px + :align: center + :height: 560px + :alt: Nucleo H723ZG + +More information about the board can be found at the `Nucleo H723ZG website`_. + +Hardware +******** + +Nucleo H723ZG provides the following hardware components: + +- STM32H723ZG in LQFP144 package +- ARM 32-bit Cortex-M7 CPU with FPU +- Chrom-ART Accelerator +- Hardware JPEG Codec +- 550 MHz max CPU frequency +- VDD from 1.62 V to 3.6 V +- 1 MB Flash +- 562 kB SRAM max (376 kb used currently) +- High-resolution timer (2.1 ns) +- 32-bit timers(2) +- 16-bit timers(12) +- SPI(6) +- I2C(4) +- I2S (3) +- USART(4) +- UART(4) +- USB OTG Full Speed and High Speed(1) +- USB OTG Full Speed(1) +- CAN-FD(2) +- SAI(2) +- SPDIF_Rx(4) +- HDMI_CEC(1) +- Dual Mode Quad SPI(1) +- Camera Interface +- GPIO (up to 114) with external interrupt capability +- 16-bit ADC(3) with 36 channels / 3.6 MSPS +- 12-bit DAC with 2 channels(2) +- True Random Number Generator (RNG) +- 16-channel DMA +- LCD-TFT Controller with XGA resolution + +Supported Features +================== + +The Zephyr nucleo_h723zg board configuration supports the following hardware +features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | counter | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| ETHERNET | on-chip | ethernet | ++-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration per core can be found in the defconfig files: +``boards/arm/nucleo_h723zg/nucleo_h723zg_defconfig`` + +For mode details please refer to `STM32 Nucleo-144 board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +The Nucleo H723ZG board features a ST Zio connector (extended Arduino Uno V3) +and a ST morpho connector. Board is configured as follows: + +- UART_3 TX/RX : PD8/PD9 (ST-Link Virtual Port Com) +- USER_PB : PC13 +- LD1 : PB0 +- LD2 : PB7 +- LD3 : PB14 +- I2C : PB8, PB9 + +System Clock +------------ + +Nucleo H723ZG System Clock could be driven by an internal or external +oscillator, as well as the main PLL clock. By default, the System clock is +driven by the PLL clock at 550MHz, driven by an 8MHz high-speed external clock. + +Serial Port +----------- + +Nucleo H723ZG board has 4 UARTs and 4 USARTs. The Zephyr console output is +assigned to UART3. Default settings are 115200 8N1. + +Programming and Debugging +************************* + +Currently the ``nucleo_h723zg`` board supports stm32cubeprogrammer (default), OpenOCD and J-Link debuggers. + +.. note:: + + Official OpenOCD support for this board was added on October '20. + Make sure your openocd version is older than that. + Following links may be helpful: `OpenOCD installing Debug Version`_ + and `OpenOCD installing with ST-LINK V3 support`_ + +.. note:: + + Check if your ST-LINK V3 has newest FW version. It can be done with `STM32CubeIDE`_ + +Flashing +======== + +Nucleo H723ZG board includes an ST-LINK/V3 embedded debug tool interface. + +First, connect the NUCLEO-H723ZG to your host computer using +the USB port to prepare it for flashing. Then build and flash your application. + +Here is an example for the :ref:`hello_world` application. + +Run a serial host program to connect with your NUCLEO-H723ZG board. + +.. code-block:: console + + $ minicom -b 115200 -D /dev/ttyACM0 + +or use screen: + +.. code-block:: console + + $ screen /dev/ttyACM0 115200 + +Build and flash the application: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_h723zg + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + $ Hello World! nucleo_h723zg + +Blinky example can also be used: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_h723zg + :goals: build flash + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_h723zg + :maybe-skip-config: + :goals: debug + +.. _Nucleo H723ZG website: + https://www.st.com/en/evaluation-tools/nucleo-h723zg.html + +.. _STM32 Nucleo-144 board User Manual: + https://www.st.com/resource/en/user_manual/dm00499160-stm32h7-nucleo144-boards-mb1364-stmicroelectronics.pdf + +.. _STM32H723ZG on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32h723zg.html + +.. _STM32H723 reference manual: + https://www.st.com/resource/en/reference_manual/dm00603761-stm32h723733-stm32h725735-and-stm32h730-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _OpenOCD installing Debug Version: + https://github.com/zephyrproject-rtos/openocd + +.. _OpenOCD installing with ST-LINK V3 support: + https://mbd.kleier.net/integrating-st-link-v3.html + +.. _STM32CubeIDE: + https://www.st.com/en/development-tools/stm32cubeide.html diff --git a/boards/arm/nucleo_h723zg/nucleo_h723zg.dts b/boards/arm/nucleo_h723zg/nucleo_h723zg.dts new file mode 100644 index 00000000000000..8bb0733f70e818 --- /dev/null +++ b/boards/arm/nucleo_h723zg/nucleo_h723zg.dts @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2020 Alexander Kozhinov + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "arduino_r3_connector.dtsi" + +/* + * WARNING: + * JP6 and SB72 must be ON when using Ethernet. + */ + +/ { + model = "STMicroelectronics STM32H723ZG-NUCLEO board"; + compatible = "st,stm32h723zg-nucleo"; + + chosen { + zephyr,console = &usart3; + zephyr,shell-uart = &usart3; + zephyr,dtcm = &dtcm; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + green_led: led_0 { + gpios = <&gpiob 0 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + yellow_led: led_1 { + gpios = <&gpioe 1 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + red_pwm_led: red_pwm_led { + pwms = <&pwm12 1 4 PWM_POLARITY_NORMAL>; + label = "User LD3 - PWM12"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button_0 { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + }; + }; + + aliases { + led0 = &green_led; + led1 = &yellow_led; + pwm-led0 = &red_pwm_led; + sw0 = &user_button; + }; +}; + +&usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; + current-speed = <115200>; + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + status = "okay"; + clock-frequency = ; +}; + +&timers12 { + status = "okay"; + + pwm12: pwm { + status = "okay"; + pinctrl-0 = <&tim12_ch1_pb14>; + }; +}; + +&mac { + status = "okay"; + pinctrl-0 = <ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pb13>; +}; + +&rng { + status = "okay"; +}; diff --git a/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml b/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml new file mode 100644 index 00000000000000..0d380ddc2b9923 --- /dev/null +++ b/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml @@ -0,0 +1,19 @@ +identifier: nucleo_h723zg +name: ST Nucleo H723ZG +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 372 +flash: 1024 +supported: + - arduino_gpio + - arduino_i2c + - uart + - gpio + - counter + - i2c + - pwm + - netif:eth diff --git a/boards/arm/nucleo_h723zg/nucleo_h723zg_defconfig b/boards/arm/nucleo_h723zg/nucleo_h723zg_defconfig new file mode 100644 index 00000000000000..742f3906dd8a8b --- /dev/null +++ b/boards/arm/nucleo_h723zg/nucleo_h723zg_defconfig @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32H7X=y +CONFIG_SOC_STM32H723XX=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=550000000 + +CONFIG_BOARD_NUCLEO_H723ZG=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable UART +CONFIG_SERIAL=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable Pinmux +CONFIG_PINMUX=y + +# Enable GPIO +CONFIG_GPIO=y + +# Clock Configuration +CONFIG_CLOCK_CONTROL=y + +CONFIG_CLOCK_STM32_D1CPRE=1 + +# HCLK: 275MHz +CONFIG_CLOCK_STM32_HPRE=2 + +# APB1: 137.5MHz +CONFIG_CLOCK_STM32_D2PPRE1=2 + +# APB2: 137.5MHz +CONFIG_CLOCK_STM32_D2PPRE2=2 + +# APB3: 137.5MHz +CONFIG_CLOCK_STM32_D1PPRE=2 + +# APB4: 137.5MHz +CONFIG_CLOCK_STM32_D3PPRE=2 + +# STLINK provides 8MHz clock input +CONFIG_CLOCK_STM32_HSE_CLOCK=8000000 +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y + +# Use HSE (bypass) as PLL input +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +CONFIG_CLOCK_STM32_HSE_BYPASS=y + +# Produce 550MHz clock at PLL1 output +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=4 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=275 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=1 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=4 +CONFIG_CLOCK_STM32_PLL_R_DIVISOR=2 diff --git a/boards/arm/nucleo_h723zg/support/openocd.cfg b/boards/arm/nucleo_h723zg/support/openocd.cfg new file mode 100644 index 00000000000000..fa8097598db0f4 --- /dev/null +++ b/boards/arm/nucleo_h723zg/support/openocd.cfg @@ -0,0 +1,36 @@ +# STM32H745ZI Nucleo board OpenOCD ST-LLINK V3 configuration +# +# Copyright (c) 2020 Alexander Kozhinov +# SPDX-License-Identifier: Apache-2.0 +# + +source [find interface/stlink-dap.cfg] +transport select dapdirect_swd + +set WORKAREASIZE 0x3000 +set CHIPNAME STM32H723ZG +set BOARDNAME NUCLEO-H723ZG + +source [find target/stm32h7x.cfg] + +# Use connect_assert_srst here to be able to programm +# even when core is in sleep mode +reset_config srst_only srst_nogate connect_assert_srst + +$_CHIPNAME.cpu0 configure -event gdb-attach { + echo "Debugger attaching: halting execution" + gdb_breakpoint_override hard +} + +$_CHIPNAME.cpu0 configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +# Due to the use of connect_assert_srst, running gdb requires +# to reset halt just after openocd init. +rename init old_init +proc init {} { + old_init + reset halt +} diff --git a/boards/arm/nucleo_h743zi/CMakeLists.txt b/boards/arm/nucleo_h743zi/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_h743zi/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_h743zi/Kconfig.defconfig b/boards/arm/nucleo_h743zi/Kconfig.defconfig index 0b82edf6f64596..e426be48d7f113 100644 --- a/boards/arm/nucleo_h743zi/Kconfig.defconfig +++ b/boards/arm/nucleo_h743zi/Kconfig.defconfig @@ -8,4 +8,11 @@ if BOARD_NUCLEO_H743ZI config BOARD default "nucleo_h743zi" +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + endif # BOARD_NUCLEO_H743ZI diff --git a/boards/arm/nucleo_h743zi/arduino_r3_connector.dtsi b/boards/arm/nucleo_h743zi/arduino_r3_connector.dtsi index 71eaecb2e4b2b1..0c6754fc8c39a7 100644 --- a/boards/arm/nucleo_h743zi/arduino_r3_connector.dtsi +++ b/boards/arm/nucleo_h743zi/arduino_r3_connector.dtsi @@ -37,3 +37,4 @@ }; arduino_i2c: &i2c1 {}; +arduino_spi: &spi1 {}; diff --git a/boards/arm/nucleo_h743zi/board.cmake b/boards/arm/nucleo_h743zi/board.cmake index 10a6e77a61eff3..7509c5aef3024c 100644 --- a/boards/arm/nucleo_h743zi/board.cmake +++ b/boards/arm/nucleo_h743zi/board.cmake @@ -1,6 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(jlink "--device=STM32H743ZI" "--speed=4000") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset=hw") include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) diff --git a/boards/arm/nucleo_h743zi/doc/index.rst b/boards/arm/nucleo_h743zi/doc/index.rst index 90c051adbde48f..c1fd5cac64e7c4 100644 --- a/boards/arm/nucleo_h743zi/doc/index.rst +++ b/boards/arm/nucleo_h743zi/doc/index.rst @@ -113,6 +113,12 @@ features: +-----------+------------+-------------------------------------+ | ADC | on-chip | adc | +-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ +| ETHERNET | on-chip | ethernet | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -133,7 +139,9 @@ and a ST morpho connector. Board is configured as follows: - LD2 : PB7 - LD3 : PB14 - I2C : PB8, PB9 -- ADC12_INP15 : PA3 +- ADC1_INP15 : PA3 +- ETH : PA1, PA2, PA7, PB13, PC1, PC4, PC5, PG11, PG13 +- SPI1 SCK/MISO/MOSI : PA5/PA6/PB5 (Arduino SPI) System Clock ------------ @@ -158,7 +166,8 @@ flashed in the usual way (see :ref:`build_an_application` and .. note:: If using OpenOCD you will need a recent development version as the last - official release does not support H7 series yet. + official release does not support H7 series yet. You can also choose the + ``stm32cubeprogrammer`` runner. Flashing ======== diff --git a/boards/arm/nucleo_h743zi/nucleo_h743zi.dts b/boards/arm/nucleo_h743zi/nucleo_h743zi.dts index 288255118bbde0..0be14f650ac797 100644 --- a/boards/arm/nucleo_h743zi/nucleo_h743zi.dts +++ b/boards/arm/nucleo_h743zi/nucleo_h743zi.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32H743ZI-NUCLEO board"; - compatible = "st,stm32h743zi-nucleo", "st,stm32h743"; + compatible = "st,stm32h743zi-nucleo"; chosen { zephyr,console = &usart3; @@ -36,7 +37,7 @@ compatible = "pwm-leds"; red_pwm_led: red_pwm_led { - pwms = <&pwm12 1 4>; + pwms = <&pwm12 1 4 PWM_POLARITY_NORMAL>; }; }; @@ -57,6 +58,7 @@ }; &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; @@ -66,6 +68,7 @@ }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; @@ -75,9 +78,41 @@ pwm12: pwm { status = "okay"; + pinctrl-0 = <&tim12_ch1_pb14>; }; }; -&adc1_2 { +&adc1 { + pinctrl-0 = <&adc1_inp15_pa3>; status = "okay"; }; + +&rng { + status = "okay"; +}; + +/* + * WARNING: + * Possible pin conflicts: + * The pins PA2 and PB13 may conflict on selection of ETH_STM32_HAL, + * since they are used in ST Zio or ST morpho connectors. + * To avoid conflicting states the jumpers JP6 and JP7 + * must be in ON state. + */ +&mac { + status = "okay"; + pinctrl-0 = <ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pb13>; +}; + +&spi1 { + status = "okay"; + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pb5>; +}; diff --git a/boards/arm/nucleo_h743zi/nucleo_h743zi.yaml b/boards/arm/nucleo_h743zi/nucleo_h743zi.yaml index 164fa2d387df6c..c699ab25499867 100644 --- a/boards/arm/nucleo_h743zi/nucleo_h743zi.yaml +++ b/boards/arm/nucleo_h743zi/nucleo_h743zi.yaml @@ -17,3 +17,5 @@ supported: - i2c - pwm - adc + - netif:eth + - spi diff --git a/boards/arm/nucleo_h743zi/nucleo_h743zi_defconfig b/boards/arm/nucleo_h743zi/nucleo_h743zi_defconfig index b4b17b0443482d..f8fbb5446926dc 100644 --- a/boards/arm/nucleo_h743zi/nucleo_h743zi_defconfig +++ b/boards/arm/nucleo_h743zi/nucleo_h743zi_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # Enable UART CONFIG_SERIAL=y diff --git a/boards/arm/nucleo_h743zi/pinmux.c b/boards/arm/nucleo_h743zi/pinmux.c deleted file mode 100644 index d57669d2109774..00000000000000 --- a/boards/arm/nucleo_h743zi/pinmux.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2020 Teslabs Engineering S.L. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* NUCLEO-H743ZI pin configurations */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - { STM32_PIN_PD8, STM32H7_PINMUX_FUNC_PD8_USART3_TX }, - { STM32_PIN_PD9, STM32H7_PINMUX_FUNC_PD9_USART3_RX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - { STM32_PIN_PB8, STM32H7_PINMUX_FUNC_PB8_I2C1_SCL }, - { STM32_PIN_PB9, STM32H7_PINMUX_FUNC_PB9_I2C1_SDA }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm12), okay) && CONFIG_PWM - { STM32_PIN_PB14, STM32H7_PINMUX_FUNC_PB14_PWM12_CH1 }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1_2), okay) && CONFIG_ADC - { STM32_PIN_PA3, STM32H7_PINMUX_FUNC_PA3_ADC12_INP15 }, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_h743zi/support/openocd.cfg b/boards/arm/nucleo_h743zi/support/openocd.cfg index fb22d864b67774..89d4f7ab5948a9 100644 --- a/boards/arm/nucleo_h743zi/support/openocd.cfg +++ b/boards/arm/nucleo_h743zi/support/openocd.cfg @@ -1,8 +1,9 @@ source [find board/st_nucleo_h743zi.cfg] +reset_config srst_only srst_nogate connect_assert_srst + $_CHIPNAME.cpu0 configure -event gdb-attach { echo "Debugger attaching: halting execution" - reset halt gdb_breakpoint_override hard } @@ -10,3 +11,11 @@ $_CHIPNAME.cpu0 configure -event gdb-detach { echo "Debugger detaching: resuming execution" resume } + +# Due to the use of connect_assert_srst, running gdb requires +# to reset halt just after openocd init. +rename init old_init +proc init {} { + old_init + reset halt +} diff --git a/boards/arm/nucleo_h745zi_q/Kconfig.board b/boards/arm/nucleo_h745zi_q/Kconfig.board new file mode 100644 index 00000000000000..0b5c572861077b --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/Kconfig.board @@ -0,0 +1,14 @@ +# STM32H745ZI Nucleo board configuration + +# Copyright (c) 2020 Alexander Kozhinov +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_H745ZI_Q_M7 + bool "NUCLEO-H745ZI-Q Development Board" + depends on SOC_STM32H745XX + select CPU_CORTEX_M7 + +config BOARD_NUCLEO_H745ZI_Q_M4 + bool "NUCLEO-H745ZI-Q Development Board" + depends on SOC_STM32H745XX + select CPU_CORTEX_M4 diff --git a/boards/arm/nucleo_h745zi_q/Kconfig.defconfig b/boards/arm/nucleo_h745zi_q/Kconfig.defconfig new file mode 100644 index 00000000000000..05e1afacd74f4d --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/Kconfig.defconfig @@ -0,0 +1,42 @@ +# STM32H745ZI Nucleo board configuration + +# Copyright (c) 2020 Alexander Kozhinov +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NUCLEO_H745ZI_Q_M7 || BOARD_NUCLEO_H745ZI_Q_M4 + +config BOARD + default "nucleo_h745zi_q_m7" if BOARD_NUCLEO_H745ZI_Q_M7 + default "nucleo_h745zi_q_m4" if BOARD_NUCLEO_H745ZI_Q_M4 + +config CLOCK_STM32_D1CPRE + default 1 + +config CLOCK_STM32_HPRE + # HCLK: 240MHz + default 2 + +config CLOCK_STM32_D2PPRE1 + # APBX: 120MHz + default 2 + +config CLOCK_STM32_D2PPRE2 + default 2 + +config CLOCK_STM32_D1PPRE + default 2 + +config CLOCK_STM32_D3PPRE + default 2 + +config STM32H7_DUAL_CORE + default y + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +endif # BOARD_NUCLEO_H745ZI_Q_M7 or BOARD_NUCLEO_H745ZI_Q_M4 diff --git a/boards/arm/nucleo_h745zi_q/arduino_r3_connector.dtsi b/boards/arm/nucleo_h745zi_q/arduino_r3_connector.dtsi new file mode 100644 index 00000000000000..d7b3dc5dc94333 --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/arduino_r3_connector.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 Alexander Kozhinov + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 3 0>, /* A0 */ + <1 0 &gpioc 0 0>, /* A1 */ + <2 0 &gpioc 3 0>, /* A2 */ + <3 0 &gpiob 1 0>, /* A3 */ + <4 0 &gpioc 2 0>, /* A4 */ + <5 0 &gpiof 11 0>, /* A5 */ + <6 0 &gpiob 7 0>, /* D0 */ + <7 0 &gpiob 6 0>, /* D1 */ + <8 0 &gpiog 14 0>, /* D2 */ + <9 0 &gpioe 13 0>, /* D3 */ + <10 0 &gpioe 14 0>, /* D4 */ + <11 0 &gpioe 11 0>, /* D5 */ + <12 0 &gpioa 8 0>, /* D6 */ + <13 0 &gpiog 12 0>, /* D7 */ + <14 0 &gpiog 9 0>, /* D8 */ + <15 0 &gpiod 15 0>, /* D9 */ + <16 0 &gpiod 14 0>, /* D10 */ + <17 0 &gpiob 5 0>, /* D11 */ + <18 0 &gpioa 6 0>, /* D12 */ + <19 0 &gpioa 5 0>, /* D13 */ + <20 0 &gpiob 9 0>, /* D14 */ + <21 0 &gpiob 8 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c1 {}; + +arduino_serial: &uart8 {}; diff --git a/boards/arm/nucleo_h745zi_q/board.cmake b/boards/arm/nucleo_h745zi_q/board.cmake new file mode 100644 index 00000000000000..c728554808fa2c --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32H745ZI" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nucleo_h745zi_q/doc/img/nucleo_h745zi_q.jpg b/boards/arm/nucleo_h745zi_q/doc/img/nucleo_h745zi_q.jpg new file mode 100644 index 00000000000000..f97400174ae4a9 Binary files /dev/null and b/boards/arm/nucleo_h745zi_q/doc/img/nucleo_h745zi_q.jpg differ diff --git a/boards/arm/nucleo_h745zi_q/doc/index.rst b/boards/arm/nucleo_h745zi_q/doc/index.rst new file mode 100644 index 00000000000000..5ca6b0eace758b --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/doc/index.rst @@ -0,0 +1,283 @@ +.. _nucleo_h745zi_q_board: + +ST Nucleo H745ZI-Q +################### + +Overview +******** + +The STM32 Nucleo-144 board provides an affordable and flexible way for users +to try out new concepts and build prototypes by choosing from the various combinations +of performance and power consumption features, provided by the STM32 microcontroller. +For the compatible boards, the internal or external SMPS significantly reduces power +consumption in Run mode. + +The ST Zio connector, which extends the ARDUINO® Uno V3 connectivity, and +the ST morpho headers provide an easy means of expanding the functionality of the Nucleo +open development platform with a wide choice of specialized shields. +The STM32 Nucleo-144 board does not require any separate probe as it integrates +the ST-LINK V3 debugger/programmer. + +The STM32 Nucleo-144 board comes with the STM32 comprehensive free software +libraries and examples available with the STM32Cube MCU Package. + +Key Features + +- STM32 microcontroller in LQFP144 package +- Ethernet compliant with IEEE-802.3-2002 (depending on STM32 support) +- USB OTG or full-speed device (depending on STM32 support) +- 3 user LEDs +- 2 user and reset push-buttons +- 32.768 kHz crystal oscillator +- Board connectors: + + - USB with Micro-AB + - Ethernet RJ45 (depending on STM32 support) + - SWDST Zio connector including Arduino* Uno V3ST + - ST morpho expansion + +- Flexible power-supply options: ST-LINK USB VBUS or external sources +- External or internal SMPS to generate Vcore logic supply +- On-board ST-LINK/V3 debugger/programmer with USB re-enumeration +- capability: mass storage, virtual COM port and debug port +- USB OTG full speed or device only +- Comprehensive free software libraries and examples available with the + STM32Cube MCU package. +- Arm* Mbed Enabled* compliant (only for some Nucleo part numbers) + +.. image:: img/nucleo_h745zi_q.jpg + :width: 720px + :align: center + :height: 560px + :alt: Nucleo H745ZI-Q + +More information about the board can be found at the `Nucleo H745ZI-Q website`_. + +Hardware +******** + +Nucleo H745ZI-Q provides the following hardware components: + +- STM32H745ZI in LQFP144 package +- ARM 32-bit Cortex-M7 CPU with FPU +- ARM 32-bit Cortex-M4 CPU with FPU +- Chrom-ART Accelerator +- Hardware JPEG Codec +- 480 MHz max CPU frequency +- VDD from 1.62 V to 3.6 V +- 2 MB Flash +- 1 MB SRAM +- High-resolution timer (2.1 ns) +- 32-bit timers(2) +- 16-bit timers(12) +- SPI(6) +- I2C(4) +- I2S (3) +- USART(4) +- UART(4) +- USB OTG Full Speed and High Speed(1) +- USB OTG Full Speed(1) +- CAN-FD(2) +- SAI(2) +- SPDIF_Rx(4) +- HDMI_CEC(1) +- Dual Mode Quad SPI(1) +- Camera Interface +- GPIO (up to 114) with external interrupt capability +- 16-bit ADC(3) with 36 channels / 3.6 MSPS +- 12-bit DAC with 2 channels(2) +- True Random Number Generator (RNG) +- 16-channel DMA +- LCD-TFT Controller with XGA resolution + +Supported Features +================== + +The Zephyr nucleo_h745zi_q board configuration supports the following hardware +features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | counter | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| ETHERNET | on-chip | ethernet | ++-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration per core can be found in the defconfig files: +``boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7_defconfig`` and +``boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4_defconfig`` + +For mode details please refer to `STM32 Nucleo-144 board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +The Nucleo H745ZI board features a ST Zio connector (extended Arduino Uno V3) +and a ST morpho connector. Board is configured as follows: + +- UART_3 TX/RX : PD8/PD9 (ST-Link Virtual Port Com) +- USER_PB : PC13 +- LD1 : PB0 +- LD2 : PB7 +- LD3 : PB14 +- I2C : PB8, PB9 + +System Clock +------------ + +Nucleo H745ZI-Q System Clock could be driven by an internal or external +oscillator, as well as the main PLL clock. By default, the System clock is +driven by the PLL clock at 480MHz, driven by an 8MHz high-speed external clock. + +Serial Port +----------- + +Nucleo H745ZI-Q board has 4 UARTs and 4 USARTs. The Zephyr console output is +assigned to UART3. Default settings are 115200 8N1. + +Resources sharing +----------------- + +The dual core nature of STM32H745 SoC requires sharing HW resources between the +two cores. This is done in 3 ways: + +- **Compilation**: Clock configuration is only accessible to M7 core. M4 core only + has access to bus clock activation and deactivation. +- **Static pre-compilation assignment**: Peripherals such as a UART are assigned in + devicetree before compilation. The user must ensure peripherals are not assigned + to both cores at the same time. +- **Run time protection**: Interrupt-controller and GPIO configurations could be + accessed by both cores at run time. Accesses are protected by a hardware semaphore + to avoid potential concurrent access issues. + +Programming and Debugging +************************* + +Applications for the ``nucleo_h745zi_q`` board should be built per core target, +using either ``nucleo_h745zi_q_m7`` or ```nucleo_h745zi_q_m4`` as the target +(see :ref:`build_an_application` and :ref:`application_run` for more details). + +.. note:: + + If using OpenOCD you will need a recent development version as the last + official release does not support H7 series and ST-LINK V3 yet. + Following links may be helpful: `OpenOCD installing Debug Version`_ + and `OpenOCD installing with ST-LINK V3 support`_ + +.. note:: + + Check if your ST-LINK V3 has newest FW version. It can be done with `STM32CubeIDE`_ + +Flashing +======== + +Nucleo H745ZI-Q board includes an ST-LINK/V3 embedded debug tool interface. + +Flashing operation will depend on the target to be flashed and the SoC +option bytes configuration. + +By default: + + - CPU0 (Cortex-M7) boot address is set to 0x80000000 (OB: BOOT_CM7_ADD0) + - CPU1 (Cortex-M4) boot address is set to 0x81000000 (OB: BOOT_CM4_ADD0) + +Also, default out of the box board configuration enables CM7 and CM4 boot when +board is powered (Option bytes BCM7 and BCM4 are checked). +In that configuration, Kconfig boot option ``STM32H7_BOOT_CM4_CM7`` should be selected. +Zephyr flash configuration has been set to meet these default settings. + +Flashing an application to STM32H745ZI M7 Core +---------------------------------------------- +First, connect the NUCLEO-H745ZI-Q to your host computer using +the USB port to prepare it for flashing. Then build and flash your application. + +Here is an example for the :ref:`hello_world` application. + +Run a serial host program to connect with your NUCLEO-H745ZI-Q board. + +.. code-block:: console + + $ minicom -b 115200 -D /dev/ttyACM0 + +or use scrreen: + +.. code-block:: console + + $ screen /dev/ttyACM0 115200 + +Build and flash the application: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_h745zi_q_m7 + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + $ Hello World! nucleo_h745zi_q_m7 + +Blinky example can also be used: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_h745zi_q_m7 + :goals: build flash + +Same way M4 core can be flashed. + +.. note:: + + Flashing both M4 and M7 and pushing RESTART button on the board leads + to LD1 and LD2 flashing simultaneously. + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_h745zi_q_m7 + :maybe-skip-config: + :goals: debug + +.. _Nucleo H745ZI-Q website: + https://www.st.com/en/evaluation-tools/nucleo-h745zi-q.html + +.. _STM32 Nucleo-144 board User Manual: + https://www.st.com/resource/en/user_manual/dm00499171-stm32h7-nucleo144-boards-mb1363-stmicroelectronics.pdf + +.. _STM32H745ZI on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32h745zi.html + +.. _STM32H745 reference manual: + https://www.st.com/resource/en/reference_manual/dm00176879-stm32h745755-and-stm32h747757-advanced-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _OpenOCD installing Debug Version: + https://github.com/zephyrproject-rtos/openocd + +.. _OpenOCD installing with ST-LINK V3 support: + https://mbd.kleier.net/integrating-st-link-v3.html + +.. _STM32CubeIDE: + https://www.st.com/en/development-tools/stm32cubeide.html diff --git a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q.dtsi b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q.dtsi new file mode 100644 index 00000000000000..4635fdea5a1f83 --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q.dtsi @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "arduino_r3_connector.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + green_led: led_1 { + gpios = <&gpiob 0 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + yellow_led: led_2 { + gpios = <&gpioe 1 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button_0 { + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + label = "User SB1"; + }; + }; +}; diff --git a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.dts b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.dts new file mode 100644 index 00000000000000..78609570eaab8d --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.dts @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020 Alexander Kozhinov + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nucleo_h745zi_q.dtsi" + +/ { + model = "STMicroelectronics STM32H745ZI-Q-NUCLEO board"; + compatible = "st,stm32h745zi-q-nucleo"; + + /* HW resources belonging to CM4 */ + chosen { + zephyr,console = &uart8; + zephyr,shell-uart = &uart8; + zephyr,sram = &sram1; + zephyr,flash = &flash1; + }; + + aliases { + led0 = &yellow_led; + }; +}; + +&uart8 { + pinctrl-0 = <&uart8_tx_pe1 &uart8_rx_pe0>; + current-speed = <115200>; + status = "okay"; +}; diff --git a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.yaml b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.yaml new file mode 100644 index 00000000000000..d31dff37370dee --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4.yaml @@ -0,0 +1,18 @@ +identifier: nucleo_h745zi_q_m4 +name: ST Nucleo H745ZI-Q +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 288 +flash: 1024 +supported: + - arduino_gpio + - gpio + - netif:eth +testing: + ignore_tags: + - mpu + - nfc diff --git a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4_defconfig b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4_defconfig new file mode 100644 index 00000000000000..641543706931ae --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m4_defconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32H7X=y +CONFIG_SOC_STM32H745XX=y +# SYS_CLOCK_M4 = SYS_CLOCK_M7 / CLOCK_STM32_HPRE +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=240000000 + +# Board config should be specified since there are 2 possible targets +CONFIG_BOARD_NUCLEO_H745ZI_Q_M4=y + +# Enable Pinmux +CONFIG_PINMUX=y + +# Enable GPIO +CONFIG_GPIO=y + +# Clock Configuration +CONFIG_CLOCK_CONTROL=y + +# By default SERIAL peripherals are assigned to m7 + +# Enable uart driver +#CONFIG_SERIAL=y + +# Console +#CONFIG_CONSOLE=y +#CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.dts b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.dts new file mode 100644 index 00000000000000..4e5f1f24f68ef8 --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.dts @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020 Alexander Kozhinov + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "nucleo_h745zi_q.dtsi" + +/* + * WARNING: + * Possible pin conflicts: The pins PA2 and PB13 may conflict on selection of + * ETH_STM32_HAL, since they are used in ST Zio or ST morpho connectors. To + * avoid conflicting states the jumpers JP6 and JP7 must be in ON state. + */ + +/ { + model = "STMicroelectronics STM32H745ZI-Q-NUCLEO board"; + compatible = "st,stm32h745zi-q-nucleo"; + + /* HW resources belonging to CM7 */ + chosen { + zephyr,console = &usart3; + zephyr,shell-uart = &usart3; + zephyr,dtcm = &dtcm; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + pwmleds { + compatible = "pwm-leds"; + + red_pwm_led: red_pwm_led { + pwms = <&pwm12 1 4 PWM_POLARITY_NORMAL>; + label = "User LD3 - PWM12"; + }; + }; + + aliases { + led0 = &green_led; + pwm-led0 = &red_pwm_led; + sw0 = &user_button; + }; +}; + +&usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; + current-speed = <115200>; + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + status = "okay"; + clock-frequency = ; +}; + +&timers12 { + status = "okay"; + + pwm12: pwm { + status = "okay"; + pinctrl-0 = <&tim12_ch1_pb14>; + }; +}; + +&mac { + status = "okay"; + pinctrl-0 = <ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pb13>; +}; + +&rng { + status = "okay"; +}; diff --git a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.yaml b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.yaml new file mode 100644 index 00000000000000..deb17d43df6c65 --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7.yaml @@ -0,0 +1,19 @@ +identifier: nucleo_h745zi_q_m7 +name: ST Nucleo H745ZI-Q +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 512 +flash: 1024 +supported: + - arduino_gpio + - arduino_i2c + - uart + - gpio + - counter + - i2c + - pwm + - netif:eth diff --git a/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7_defconfig b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7_defconfig new file mode 100644 index 00000000000000..57ce81f5a07814 --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/nucleo_h745zi_q_m7_defconfig @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32H7X=y +CONFIG_SOC_STM32H745XX=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=480000000 + +# Board config should be specified since there are 2 possible targets +CONFIG_BOARD_NUCLEO_H745ZI_Q_M7=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable UART ( disable to assign to M4 core) +CONFIG_SERIAL=y + +# Console ( disable to assign to M4 core) +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable Pinmux +CONFIG_PINMUX=y + +# Enable GPIO +CONFIG_GPIO=y + +# Clock Configuration +CONFIG_CLOCK_CONTROL=y + +# STLINK provides 8MHz clock input +CONFIG_CLOCK_STM32_HSE_CLOCK=8000000 +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y + +# Use HSE (bypass) as PLL input +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +CONFIG_CLOCK_STM32_HSE_BYPASS=y + +# Produce 480MHz clock at PLL1 output +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=1 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=120 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_R_DIVISOR=2 diff --git a/boards/arm/nucleo_h745zi_q/support/openocd.cfg b/boards/arm/nucleo_h745zi_q/support/openocd.cfg new file mode 100644 index 00000000000000..391d0d917a1211 --- /dev/null +++ b/boards/arm/nucleo_h745zi_q/support/openocd.cfg @@ -0,0 +1,29 @@ +# STM32H745ZI Nucleo board OpenOCD ST-LINK V3 configuration +# +# Copyright (c) 2020 Alexander Kozhinov +# SPDX-License-Identifier: Apache-2.0 +# + +source [find board/st_nucleo_h745zi.cfg] + +# Use connect_assert_srst here to be able to programm +# even when core is in sleep mode +reset_config srst_only srst_nogate connect_assert_srst + +$_CHIPNAME.cpu0 configure -event gdb-attach { + echo "Debugger attaching: halting execution" + gdb_breakpoint_override hard +} + +$_CHIPNAME.cpu0 configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +# Due to the use of connect_assert_srst, running gdb requires +# to reset halt just after openocd init. +rename init old_init +proc init {} { + old_init + reset halt +} diff --git a/boards/arm/nucleo_l011k4/Kconfig.board b/boards/arm/nucleo_l011k4/Kconfig.board new file mode 100644 index 00000000000000..aa6401045f7e4b --- /dev/null +++ b/boards/arm/nucleo_l011k4/Kconfig.board @@ -0,0 +1,8 @@ +# STM32 Nucleo-32 development board with STM32L011K4 MCU configuration + +# Copyright (c) 2020 Steven Daglish +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_L011K4 + bool "NUCLEO-32 L011K4 Development Board" + depends on SOC_STM32L011XX diff --git a/boards/arm/nucleo_l011k4/Kconfig.defconfig b/boards/arm/nucleo_l011k4/Kconfig.defconfig new file mode 100644 index 00000000000000..527a93140cb065 --- /dev/null +++ b/boards/arm/nucleo_l011k4/Kconfig.defconfig @@ -0,0 +1,15 @@ +# STM32 Nucleo-32 development board with STM32L011K4 MCU + +# Copyright (c) 2020 Steven Daglish +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NUCLEO_L011K4 + +config BOARD + default "nucleo_l011k4" + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +endif # BOARD_NUCLEO_L011K4 diff --git a/boards/arm/nucleo_l011k4/board.cmake b/boards/arm/nucleo_l011k4/board.cmake new file mode 100644 index 00000000000000..7c88105a59a8af --- /dev/null +++ b/boards/arm/nucleo_l011k4/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32L011K4" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nucleo_l011k4/doc/img/nucleo_l011k4.jpg b/boards/arm/nucleo_l011k4/doc/img/nucleo_l011k4.jpg new file mode 100644 index 00000000000000..ca0471e4fa3dd3 Binary files /dev/null and b/boards/arm/nucleo_l011k4/doc/img/nucleo_l011k4.jpg differ diff --git a/boards/arm/nucleo_l011k4/doc/index.rst b/boards/arm/nucleo_l011k4/doc/index.rst new file mode 100644 index 00000000000000..d6bb446fff3e96 --- /dev/null +++ b/boards/arm/nucleo_l011k4/doc/index.rst @@ -0,0 +1,169 @@ +.. _nucleo_l011k4_board: + +ST Nucleo L011K4 +################ + +Overview +******** +The STM32 Nucleo-32 development board with STM32L011K4 MCU, supports Arduino Nano V3 connectivity. + +The STM32 Nucleo board provides an affordable, and flexible way for users to try out new concepts, +and build prototypes with the STM32 microcontroller, choosing from the various +combinations of performance, power consumption, and features. + +The Arduino* Nano V3 connectivity support allow easy functionality +expansion of the STM32 Nucleo open development platform with a wide choice of +specialized shields. + +The STM32 Nucleo board integrates the ST-LINK/V2-1 debugger and programmer. + +The STM32 Nucleo board comes with the STM32 comprehensive software HAL library together +with various packaged software examples. + +.. image:: img/nucleo_l011k4.jpg + :width: 426px + :height: 319px + :align: center + :alt: Nucleo L011K4 + +More information about the board can be found at the `Nucleo L011K4 website`_. + +Hardware +******** +Nucleo L011K4 provides the following hardware components: + +- STM32 microcontroller in LQFP32 package +- Extension resource: + + - Arduino* Nano V3 connectivity + +- ARM* mbed* +- On-board ST-LINK/V2-1 debugger/programmer with SWD connector: + + - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 + +- Flexible board power supply: + + - USB VBUS or external source (3.3V, 5V, 7 - 12V) + - Power management access point + +- Three LEDs: + + - USB communication (LD1), user LED (LD2), power LED (LD3) + +- One push-button: RESET +- USB re-enumeration capability. Three different interfaces supported on USB: + + - Virtual COM port + - Mass storage + - Debug port + +- Support of wide choice of Integrated Development Environments (IDEs) including: + + - IAR + - ARM Keil + - GCC-based IDEs + +More information about STM32L011K4 can be found in the +`STM32L0x1 reference manual`_ + + +Supported Features +================== + +The Zephyr nucleo_l011k4 board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c controller | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi controller | ++-----------+------------+-------------------------------------+ +| EEPROM | on-chip | eeprom | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported in this Zephyr port. + +The default configuration can be found in the defconfig file: +``boards/arm/nucleo_l011k4/nucleo_l011k4_defconfig`` + +Connections and IOs +=================== + +Each of the GPIO pins can be configured by software as output (push-pull or open-drain), as +input (with or without pull-up or pull-down), or as peripheral alternate function. Most of the +GPIO pins are shared with digital or analog alternate functions. All GPIOs are high current +capable except for analog inputs. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_2 TX/RX : PA2/PA15 (ST-Link Virtual Port Com) +- I2C1 SCL/SDA : PA4/PA10 (Arduino I2C) +- SPI1 SCK/MISO/MOSI : PA5/PA6/PA7 (Arduino SPI) +- LD2 : PB3 + +For mode details please refer to `STM32 Nucleo-32 board User Manual`_. + +Programming and Debugging +************************* + +Applications for the ``nucleo_l011k4`` board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +Nucleo L011K4 board includes an ST-LINK/V2-1 embedded debug tool interface. +This interface is supported by the openocd version included in the Zephyr SDK. + +Flashing an application to Nucleo L011K4 +---------------------------------------- + +Here is an example for the :ref:`blinky-sample` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_l011k4 + :goals: build flash + +You will see the LED blinking every second. + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_l011k4 + :maybe-skip-config: + :goals: debug + +References +********** + +.. target-notes:: + +.. _Nucleo L011K4 website: + http://www.st.com/en/evaluation-tools/nucleo-l011k4.html + +.. _STM32L0x1 reference manual: + https://www.st.com/resource/en/reference_manual/dm00108282-ultralowpower-stm32l0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _STM32 Nucleo-32 board User Manual: + https://www.st.com/resource/en/user_manual/dm00231744-stm32-nucleo32-boards-mb1180-stmicroelectronics.pdf diff --git a/boards/arm/nucleo_l011k4/nucleo_l011k4.dts b/boards/arm/nucleo_l011k4/nucleo_l011k4.dts new file mode 100644 index 00000000000000..6268d9ae6eb0e5 --- /dev/null +++ b/boards/arm/nucleo_l011k4/nucleo_l011k4.dts @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 Steven Daglish + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "STMicroelectronics STM32L011K4-NUCLEO board"; + compatible = "st,stm32l011k4-nucleo"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + green_led_2: led_2 { + gpios = <&gpiob 3 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioa 12 GPIO_ACTIVE_LOW>; + }; + }; + + aliases { + led0 = &green_led_2; + eeprom-0 = &eeprom; + }; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa15>; + current-speed = <115200>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pa4 &i2c1_sda_pa10>; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + status = "okay"; +}; + +&eeprom { + status = "okay"; +}; diff --git a/boards/arm/nucleo_l011k4/nucleo_l011k4.yaml b/boards/arm/nucleo_l011k4/nucleo_l011k4.yaml new file mode 100644 index 00000000000000..482dc095abb2fe --- /dev/null +++ b/boards/arm/nucleo_l011k4/nucleo_l011k4.yaml @@ -0,0 +1,15 @@ +identifier: nucleo_l011k4 +name: ST Nucleo L011K4 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - i2c + - spi + - eeprom +ram: 2 +flash: 16 diff --git a/boards/arm/nucleo_l011k4/nucleo_l011k4_defconfig b/boards/arm/nucleo_l011k4/nucleo_l011k4_defconfig new file mode 100644 index 00000000000000..2f11cccf64bf8c --- /dev/null +++ b/boards/arm/nucleo_l011k4/nucleo_l011k4_defconfig @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Zephyr Kernel Configuration +CONFIG_SOC_SERIES_STM32L0X=y + +# Platform Configuration +CONFIG_SOC_STM32L011XX=y + +# General Kernel Options +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32000000 + +# Kernel Options due to Low Memory (2k) +CONFIG_MAIN_STACK_SIZE=320 +CONFIG_IDLE_STACK_SIZE=100 +CONFIG_ISR_STACK_SIZE=256 + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Pinmux Driver +CONFIG_PINMUX=y + +# GPIO Controller +CONFIG_GPIO=y + +# Clock configuration +CONFIG_CLOCK_CONTROL=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# PLL configuration +CONFIG_CLOCK_STM32_PLL_SRC_HSI=y +# produce 32MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_MULTIPLIER=4 +CONFIG_CLOCK_STM32_PLL_DIVISOR=2 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=1 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 diff --git a/boards/arm/nucleo_l011k4/support/openocd.cfg b/boards/arm/nucleo_l011k4/support/openocd.cfg new file mode 100644 index 00000000000000..399b76d1e2f4b9 --- /dev/null +++ b/boards/arm/nucleo_l011k4/support/openocd.cfg @@ -0,0 +1,23 @@ +# This is an ST NUCLEO-L011K4 board with single STM32L011K4 chip. +# http://www.st.com/en/evaluation-tools/nucleo-l011k4.html +source [find interface/stlink.cfg] + +transport select hla_swd + +#set WORKAREASIZE 0x2000 + +source [find target/stm32l0.cfg] + +# There is only system reset line and JTAG/SWD command can be issued when SRST +reset_config srst_only + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/nucleo_l031k6/Kconfig.board b/boards/arm/nucleo_l031k6/Kconfig.board new file mode 100644 index 00000000000000..43b52d42020a03 --- /dev/null +++ b/boards/arm/nucleo_l031k6/Kconfig.board @@ -0,0 +1,8 @@ +# STM32 Nucleo-32 development board with STM32L031K6 MCU configuration + +# Copyright (c) 2020 Steven Daglish +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_L031K6 + bool "NUCLEO-32 L031K6 Development Board" + depends on SOC_STM32L031XX diff --git a/boards/arm/nucleo_l031k6/Kconfig.defconfig b/boards/arm/nucleo_l031k6/Kconfig.defconfig new file mode 100644 index 00000000000000..0c84a21c58795f --- /dev/null +++ b/boards/arm/nucleo_l031k6/Kconfig.defconfig @@ -0,0 +1,15 @@ +# STM32 Nucleo-32 development board with STM32L031K6 MCU + +# Copyright (c) 2020 Steven Daglish +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NUCLEO_L031K6 + +config BOARD + default "nucleo_l031k6" + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +endif # BOARD_NUCLEO_L031K6 diff --git a/boards/arm/nucleo_l031k6/board.cmake b/boards/arm/nucleo_l031k6/board.cmake new file mode 100644 index 00000000000000..7451e6df477c97 --- /dev/null +++ b/boards/arm/nucleo_l031k6/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32L031K6" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/nucleo_l031k6/doc/img/nucleo_l031k6.jpg b/boards/arm/nucleo_l031k6/doc/img/nucleo_l031k6.jpg new file mode 100644 index 00000000000000..ca0471e4fa3dd3 Binary files /dev/null and b/boards/arm/nucleo_l031k6/doc/img/nucleo_l031k6.jpg differ diff --git a/boards/arm/nucleo_l031k6/doc/index.rst b/boards/arm/nucleo_l031k6/doc/index.rst new file mode 100644 index 00000000000000..de456941dd6c5c --- /dev/null +++ b/boards/arm/nucleo_l031k6/doc/index.rst @@ -0,0 +1,162 @@ +.. _nucleo_l031k6_board: + +ST Nucleo L031K6 +################ + +Overview +******** +The STM32 Nucleo-32 development board with STM32L031K6 MCU, supports Arduino Nano V3 connectivity. + +The STM32 Nucleo board provides an affordable, and flexible way for users to try out new concepts, +and build prototypes with the STM32 microcontroller, choosing from the various +combinations of performance, power consumption, and features. + +The Arduino* Nano V3 connectivity support allow easy functionality +expansion of the STM32 Nucleo open development platform with a wide choice of +specialized shields. + +The STM32 Nucleo board integrates the ST-LINK/V2-1 debugger and programmer. + +The STM32 Nucleo board comes with the STM32 comprehensive software HAL library together +with various packaged software examples. + +.. image:: img/nucleo_l031k6.jpg + :width: 426px + :height: 319px + :align: center + :alt: Nucleo L031K6 + +More information about the board can be found at the `Nucleo L031K6 website`_. + +Hardware +******** +Nucleo L031K6 provides the following hardware components: + +- STM32 microcontroller in LQFP32 package +- Extension resource: + + - Arduino* Nano V3 connectivity + +- On-board ST-LINK/V2-1 debugger/programmer with SWD connector: + + - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 + +- Flexible board power supply: + + - USB VBUS or external source (3.3V, 5V, 7 - 12V) + - Power management access point + +- Three LEDs: + + - USB communication (LD1), user LED (LD2), power LED (LD3) + +- One push-button: RESET + +- USB re-enumeration capability. Three different interfaces supported on USB: + + - Virtual COM port + - Mass storage + - Debug port + +More information about STM32L031K6 can be found in the +`STM32L0x1 reference manual`_ + +Supported Features +================== + +The Zephyr nucleo_l031k6 board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c controller | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi controller | ++-----------+------------+-------------------------------------+ +| EEPROM | on-chip | eeprom | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported in this Zephyr port. + +The default configuration can be found in the defconfig file: +``boards/arm/nucleo_l031k6/nucleo_l031k6_defconfig`` + +Connections and IOs +=================== + +Each of the GPIO pins can be configured by software as output (push-pull or open-drain), as +input (with or without pull-up or pull-down), or as peripheral alternate function. Most of the +GPIO pins are shared with digital or analog alternate functions. All GPIOs are high current +capable except for analog inputs. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_2 TX/RX : PA2/PA15 (ST-Link Virtual Port Com) +- I2C1 SCL/SDA : PA9/PA10 (Arduino I2C) +- SPI1 SCK/MISO/MOSI : PA5/PA6/PA7 (Arduino SPI) +- LD2 : PB3 + +For mode details please refer to `STM32 Nucleo-32 board User Manual`_. + +Programming and Debugging +************************* + +Applications for the ``nucleo_l031k6`` board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +Nucleo L031K6 board includes an ST-LINK/V2-1 embedded debug tool interface. +This interface is supported by the openocd version included in the Zephyr SDK. + +Flashing an application to Nucleo L031K6 +---------------------------------------- + +Here is an example for the :ref:`blinky-sample` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_l031k6 + :goals: build flash + +You will see the LED blinking every second. + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_l031k6 + :maybe-skip-config: + :goals: debug + +References +********** + +.. target-notes:: + +.. _Nucleo L031K6 website: + http://www.st.com/en/evaluation-tools/nucleo-l031k6.html + +.. _STM32L0x1 reference manual: + https://www.st.com/resource/en/reference_manual/dm00108282-ultralowpower-stm32l0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _STM32 Nucleo-32 board User Manual: + https://www.st.com/resource/en/user_manual/dm00231744-stm32-nucleo32-boards-mb1180-stmicroelectronics.pdf diff --git a/boards/arm/nucleo_l031k6/nucleo_l031k6.dts b/boards/arm/nucleo_l031k6/nucleo_l031k6.dts new file mode 100644 index 00000000000000..9d0883b6798741 --- /dev/null +++ b/boards/arm/nucleo_l031k6/nucleo_l031k6.dts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020 Steven Daglish + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "STMicroelectronics STM32L031K6-NUCLEO board"; + compatible = "st,stm32l031k6-nucleo"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + green_led_2: led_2 { + gpios = <&gpiob 3 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + aliases { + led0 = &green_led_2; + eeprom-0 = &eeprom; + }; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa15>; + current-speed = <115200>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pa9 &i2c1_sda_pa10>; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&eeprom { + status = "okay"; +}; diff --git a/boards/arm/nucleo_l031k6/nucleo_l031k6.yaml b/boards/arm/nucleo_l031k6/nucleo_l031k6.yaml new file mode 100644 index 00000000000000..650438636a6cd6 --- /dev/null +++ b/boards/arm/nucleo_l031k6/nucleo_l031k6.yaml @@ -0,0 +1,15 @@ +identifier: nucleo_l031k6 +name: ST Nucleo L031K6 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - i2c + - spi + - eeprom +ram: 8 +flash: 32 diff --git a/boards/arm/nucleo_l031k6/nucleo_l031k6_defconfig b/boards/arm/nucleo_l031k6/nucleo_l031k6_defconfig new file mode 100644 index 00000000000000..4cd5dad43dac31 --- /dev/null +++ b/boards/arm/nucleo_l031k6/nucleo_l031k6_defconfig @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Zephyr Kernel Configuration +CONFIG_SOC_SERIES_STM32L0X=y + +# Platform Configuration +CONFIG_SOC_STM32L031XX=y + +# General Kernel Options +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32000000 + +# Kernel Options due to Low Memory (8k) +CONFIG_MAIN_STACK_SIZE=640 +CONFIG_IDLE_STACK_SIZE=200 +CONFIG_ISR_STACK_SIZE=512 +# Prevent Interrupt Vector Table in RAM +CONFIG_IS_BOOTLOADER=y +CONFIG_BOOTLOADER_SRAM_SIZE=8 + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Pinmux Driver +CONFIG_PINMUX=y + +# GPIO Controller +CONFIG_GPIO=y + +# Clock configuration +CONFIG_CLOCK_CONTROL=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# PLL configuration +CONFIG_CLOCK_STM32_PLL_SRC_HSI=y +# produce 32MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_MULTIPLIER=4 +CONFIG_CLOCK_STM32_PLL_DIVISOR=2 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=1 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 diff --git a/boards/arm/nucleo_l031k6/support/openocd.cfg b/boards/arm/nucleo_l031k6/support/openocd.cfg new file mode 100644 index 00000000000000..c93941718841bd --- /dev/null +++ b/boards/arm/nucleo_l031k6/support/openocd.cfg @@ -0,0 +1,21 @@ +# This is an ST NUCLEO-L031K6 board with single STM32L031K6 chip. +# http://www.st.com/en/evaluation-tools/nucleo-l031k6.html +source [find interface/stlink.cfg] + +transport select hla_swd + +source [find target/stm32l0.cfg] + +# There is only system reset line and JTAG/SWD command can be issued when SRST +reset_config srst_only + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/nucleo_l053r8/CMakeLists.txt b/boards/arm/nucleo_l053r8/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_l053r8/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_l053r8/nucleo_l053r8.dts b/boards/arm/nucleo_l053r8/nucleo_l053r8.dts index da862ca7b0aff8..464b1abe9e9511 100644 --- a/boards/arm/nucleo_l053r8/nucleo_l053r8.dts +++ b/boards/arm/nucleo_l053r8/nucleo_l053r8.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32L053R8-NUCLEO board"; - compatible = "st,stm32l053r8-nucleo", "st,stm32l053"; + compatible = "st,stm32l053r8-nucleo"; chosen { zephyr,console = &usart2; @@ -48,20 +49,24 @@ &gpioh {status = "disabled";}; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; diff --git a/boards/arm/nucleo_l053r8/nucleo_l053r8_defconfig b/boards/arm/nucleo_l053r8/nucleo_l053r8_defconfig index 3201a1c3ee0d3f..0f7af17aeb98bc 100644 --- a/boards/arm/nucleo_l053r8/nucleo_l053r8_defconfig +++ b/boards/arm/nucleo_l053r8/nucleo_l053r8_defconfig @@ -9,6 +9,9 @@ CONFIG_SOC_STM32L053XX=y # General Kernel Options CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32000000 +# Enable MPU +CONFIG_ARM_MPU=y + # Kernel Options due to Low Memory (8k) CONFIG_MAIN_STACK_SIZE=640 CONFIG_IDLE_STACK_SIZE=200 diff --git a/boards/arm/nucleo_l053r8/pinmux.c b/boards/arm/nucleo_l053r8/pinmux.c deleted file mode 100644 index 9e46dc821970c3..00000000000000 --- a/boards/arm/nucleo_l053r8/pinmux.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018 Anthony Kreft - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-L053R8 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32L0_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32L0_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L0_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L0_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32L0_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32L0_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PA5, STM32L0_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32L0_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L0_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_l073rz/CMakeLists.txt b/boards/arm/nucleo_l073rz/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_l073rz/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_l073rz/nucleo_l073rz.dts b/boards/arm/nucleo_l073rz/nucleo_l073rz.dts index 377816c4deb4e1..2fb87e2a619119 100644 --- a/boards/arm/nucleo_l073rz/nucleo_l073rz.dts +++ b/boards/arm/nucleo_l073rz/nucleo_l073rz.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32L073RZ-NUCLEO board"; - compatible = "st,stm32l073rz-nucleo", "st,stm32l073"; + compatible = "st,stm32l073rz-nucleo"; chosen { zephyr,console = &usart2; @@ -38,26 +39,28 @@ aliases { led0 = &green_led_2; sw0 = &user_button; - adc1 = &adc1; - dac1 = &dac1; }; }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; @@ -66,9 +69,11 @@ }; &adc1 { + pinctrl-0 = <&adc_in0_pa0>; status = "okay"; }; &dac1 { status = "okay"; + pinctrl-0 = <&dac_out1_pa4>; }; diff --git a/boards/arm/nucleo_l073rz/nucleo_l073rz_defconfig b/boards/arm/nucleo_l073rz/nucleo_l073rz_defconfig index c6ff97ef4ecc22..1a4091324a88e2 100644 --- a/boards/arm/nucleo_l073rz/nucleo_l073rz_defconfig +++ b/boards/arm/nucleo_l073rz/nucleo_l073rz_defconfig @@ -9,6 +9,9 @@ CONFIG_SOC_STM32L073XX=y # General Kernel Options CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32000000 +# Enable MPU +CONFIG_ARM_MPU=y + # Serial Drivers CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/arm/nucleo_l073rz/pinmux.c b/boards/arm/nucleo_l073rz/pinmux.c deleted file mode 100644 index 3f4cff174fefe0..00000000000000 --- a/boards/arm/nucleo_l073rz/pinmux.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2018 Ilya Tagunov - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-L073RZ board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32L0_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32L0_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L0_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L0_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32L0_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32L0_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PA5, STM32L0_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32L0_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L0_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PA0, STM32L0_PINMUX_FUNC_PA0_ADC_IN0}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(dac1), okay) && CONFIG_DAC - {STM32_PIN_PA4, STM32L0_PINMUX_FUNC_PA4_DAC_OUT1}, -#endif /* dac1 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_l152re/CMakeLists.txt b/boards/arm/nucleo_l152re/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_l152re/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_l152re/doc/index.rst b/boards/arm/nucleo_l152re/doc/index.rst index c42fef2e4a1a6f..891211cadf2bd6 100644 --- a/boards/arm/nucleo_l152re/doc/index.rst +++ b/boards/arm/nucleo_l152re/doc/index.rst @@ -88,8 +88,12 @@ The Zephyr nucleo_l152re board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | independent watchdog | +-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtc | ++-----------+------------+-------------------------------------+ | ADC | on-chip | ADC Controller | +-----------+------------+-------------------------------------+ +| DAC | on-chip | DAC Controller | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported in this Zephyr port. @@ -119,6 +123,7 @@ Default Zephyr Peripheral Mapping: - I2C1 SCL/SDA : PB8/PB9 (Arduino I2C) - B1 (USER/blue) : PC13 - LD1 : PA5 +- DAC : PA4 For mode details please refer to `STM32 Nucleo-64 board User Manual`_. diff --git a/boards/arm/nucleo_l152re/nucleo_l152re.dts b/boards/arm/nucleo_l152re/nucleo_l152re.dts index d5d4bae40654ee..187ec05622721f 100644 --- a/boards/arm/nucleo_l152re/nucleo_l152re.dts +++ b/boards/arm/nucleo_l152re/nucleo_l152re.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32L152RE-NUCLEO board"; - compatible = "st,stm32l152re-nucleo", "st,stm32l152"; + compatible = "st,stm32l152re-nucleo"; chosen { zephyr,console = &usart2; @@ -43,11 +44,13 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; }; @@ -59,6 +62,16 @@ status = "okay"; }; +&rtc { + status = "okay"; +}; + &adc1 { + pinctrl-0 = <&adc_in0_pa0>; + status = "okay"; +}; + +&dac1 { status = "okay"; + pinctrl-0 = <&dac_out1_pa4>; }; diff --git a/boards/arm/nucleo_l152re/nucleo_l152re.yaml b/boards/arm/nucleo_l152re/nucleo_l152re.yaml index f77a9575096536..61525b569c28ec 100644 --- a/boards/arm/nucleo_l152re/nucleo_l152re.yaml +++ b/boards/arm/nucleo_l152re/nucleo_l152re.yaml @@ -15,4 +15,6 @@ supported: - i2c - uart - watchdog + - counter - adc + - dac diff --git a/boards/arm/nucleo_l152re/nucleo_l152re_defconfig b/boards/arm/nucleo_l152re/nucleo_l152re_defconfig index 46aa0f0706287e..7a1b237f519677 100644 --- a/boards/arm/nucleo_l152re/nucleo_l152re_defconfig +++ b/boards/arm/nucleo_l152re/nucleo_l152re_defconfig @@ -6,6 +6,12 @@ CONFIG_CORTEX_M_SYSTICK=y # 32MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y # enable console diff --git a/boards/arm/nucleo_l152re/pinmux.c b/boards/arm/nucleo_l152re/pinmux.c deleted file mode 100644 index 3e2577eaee2dce..00000000000000 --- a/boards/arm/nucleo_l152re/pinmux.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2019 Antony Pavlov - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L1X_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L1X_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32L1X_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32L1X_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PA0, STM32L1X_PINMUX_FUNC_PA0_ADC1_IN0}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_l152re/support/openocd.cfg b/boards/arm/nucleo_l152re/support/openocd.cfg index 7d566761fc7026..64b57ff0e2cd20 100644 --- a/boards/arm/nucleo_l152re/support/openocd.cfg +++ b/boards/arm/nucleo_l152re/support/openocd.cfg @@ -1,4 +1,15 @@ -source [find board/st_nucleo_l1.cfg] +# TODO: Once official oepnOCD fix merged and available in zephyr: +# http://openocd.zylin.com/#/c/5829/ +# revert to board/st_nucleo_l1.cfg +# source [find board/st_nucleo_l1.cfg] + +source [find interface/stlink.cfg] + +transport select hla_swd + +source [find target/stm32l1x_dual_bank.cfg] + +reset_config srst_only $_TARGETNAME configure -event gdb-attach { echo "Debugger attaching: halting execution" diff --git a/boards/arm/nucleo_l432kc/CMakeLists.txt b/boards/arm/nucleo_l432kc/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_l432kc/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_l432kc/nucleo_l432kc.dts b/boards/arm/nucleo_l432kc/nucleo_l432kc.dts index ac6604331907f7..2602c3e4372f09 100644 --- a/boards/arm/nucleo_l432kc/nucleo_l432kc.dts +++ b/boards/arm/nucleo_l432kc/nucleo_l432kc.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32L432KC-NUCLEO board"; - compatible = "st,stm32l432kc-nucleo", "st,stm32l432"; + compatible = "st,stm32l432kc-nucleo"; chosen { zephyr,console = &usart2; @@ -33,15 +34,25 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa15>; current-speed = <115200>; status = "okay"; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; + clock-frequency = ; status = "okay"; }; @@ -50,10 +61,12 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; &can1 { + pinctrl-0 = <&can1_rx_pa11 &can1_tx_pa12>; bus-speed = <125000>; status = "okay"; }; diff --git a/boards/arm/nucleo_l432kc/nucleo_l432kc_defconfig b/boards/arm/nucleo_l432kc/nucleo_l432kc_defconfig index 958c327482f6c8..a9a1ac904bd545 100644 --- a/boards/arm/nucleo_l432kc/nucleo_l432kc_defconfig +++ b/boards/arm/nucleo_l432kc/nucleo_l432kc_defconfig @@ -5,6 +5,12 @@ CONFIG_SOC_STM32L432XX=y # 80MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=80000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/nucleo_l432kc/pinmux.c b/boards/arm/nucleo_l432kc/pinmux.c deleted file mode 100644 index eea2ba83bb4545..00000000000000 --- a/boards/arm/nucleo_l432kc/pinmux.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016 Open-RnD Sp. z o.o. - * Copyright (c) 2016 BayLibre, SAS - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-L432KC board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32L4X_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32L4X_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L4X_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA15, STM32L4X_PINMUX_FUNC_PA15_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32L4X_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32L4X_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32L4X_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32L4X_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32L4X_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PA11, STM32L4X_PINMUX_FUNC_PA11_CAN_RX}, - {STM32_PIN_PA12, STM32L4X_PINMUX_FUNC_PA12_CAN_TX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_l452re/CMakeLists.txt b/boards/arm/nucleo_l452re/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_l452re/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_l452re/Kconfig.board b/boards/arm/nucleo_l452re/Kconfig.board index 82b0af36f89e93..ba69b24e6e6ed2 100644 --- a/boards/arm/nucleo_l452re/Kconfig.board +++ b/boards/arm/nucleo_l452re/Kconfig.board @@ -7,3 +7,7 @@ config BOARD_NUCLEO_L452RE bool "Nucleo L452RE Development Board" depends on SOC_STM32L452XX + +config BOARD_NUCLEO_L452RE_P + bool "Nucleo L452RE-P Development Board" + depends on SOC_STM32L452XX diff --git a/boards/arm/nucleo_l452re/Kconfig.defconfig b/boards/arm/nucleo_l452re/Kconfig.defconfig index ca87af158d23c8..3da8b18ec74239 100644 --- a/boards/arm/nucleo_l452re/Kconfig.defconfig +++ b/boards/arm/nucleo_l452re/Kconfig.defconfig @@ -4,13 +4,14 @@ # # SPDX-License-Identifier: Apache-2.0 -if BOARD_NUCLEO_L452RE +if BOARD_NUCLEO_L452RE || BOARD_NUCLEO_L452RE_P config BOARD - default "nucleo_l452re" + default "nucleo_l452re" if BOARD_NUCLEO_L452RE + default "nucleo_l452re_p" if BOARD_NUCLEO_L452RE_P config SPI_STM32_INTERRUPT default y depends on SPI -endif # BOARD_NUCLEO_L452RE +endif # BOARD_NUCLEO_L452RE || BOARD_NUCLEO_L452RE_P diff --git a/boards/arm/nucleo_l452re/doc/img/nucleo_l452re.jpg b/boards/arm/nucleo_l452re/doc/img/nucleo_l452re.jpg deleted file mode 100644 index d6158cfa60ca3a..00000000000000 Binary files a/boards/arm/nucleo_l452re/doc/img/nucleo_l452re.jpg and /dev/null differ diff --git a/boards/arm/nucleo_l452re/doc/img/nucleo_l452re_p.jpg b/boards/arm/nucleo_l452re/doc/img/nucleo_l452re_p.jpg new file mode 100644 index 00000000000000..173eb5b6a68e05 Binary files /dev/null and b/boards/arm/nucleo_l452re/doc/img/nucleo_l452re_p.jpg differ diff --git a/boards/arm/nucleo_l452re/doc/img/nucleo_l452re_p_pinout.png b/boards/arm/nucleo_l452re/doc/img/nucleo_l452re_p_pinout.png new file mode 100644 index 00000000000000..54a64e8901c8be Binary files /dev/null and b/boards/arm/nucleo_l452re/doc/img/nucleo_l452re_p_pinout.png differ diff --git a/boards/arm/nucleo_l452re/doc/img/nucleo-l452re-pinout.png b/boards/arm/nucleo_l452re/doc/img/nucleo_l452re_pinout.png similarity index 100% rename from boards/arm/nucleo_l452re/doc/img/nucleo-l452re-pinout.png rename to boards/arm/nucleo_l452re/doc/img/nucleo_l452re_pinout.png diff --git a/boards/arm/nucleo_l452re/doc/index.rst b/boards/arm/nucleo_l452re/doc/index.rst index eef44462f1e5bc..ef7013a6aa649b 100644 --- a/boards/arm/nucleo_l452re/doc/index.rst +++ b/boards/arm/nucleo_l452re/doc/index.rst @@ -6,11 +6,15 @@ ST Nucleo L452RE Overview ******** -The Nucleo L452RE board features an ARM Cortex-M4 based STM32L452RE MCU -with a wide range of connectivity support and configurations. Here are -some highlights of the Nucleo L452RE board: +The Nucleo L452RE(-P) boards feature an ARM Cortex-M4 based STM32L452RE MCU +with a wide range of connectivity support and configurations. There are two variants: -- STM32 microcontroller in UFQFPN32 package +- ST Nucleo L452RE +- ST Nucleo L452RE-P + +Here some highlights of these boards: + +- STM32 microcontroller in LQFP64 package - Arduino Uno V3 connectivity - On-board ST-LINK/V2-1 debugger/programmer with SWD connector - Flexible board power supply: @@ -21,13 +25,18 @@ some highlights of the Nucleo L452RE board: - Three LEDs: USB communication (LD1), user LED (LD2), power LED (LD3) - One push-button: RESET -.. image:: img/nucleo_l452re.jpg - :width: 250px +.. image:: img/nucleo_l452re_p.jpg + :width: 363px :align: center - :height: 188px - :alt: Nucleo L452RE + :height: 408px + :alt: Nucleo L452RE-P -More information about the board can be found at the `Nucleo L452RE website`_. +The main difference between the ST Nucleo L452RE and the L452RE-P (note the missing +"-P" at the end) lays in the External Switched Mode Power Supply (SMPS) included in +the P series. + +More information about the boards can be found at the `Nucleo L452RE website`_ and +the `Nucleo L452RE-P website`_. Hardware ******** @@ -136,13 +145,20 @@ input/output, pull-up, etc. Available pins: --------------- -.. image:: img/nucleo-l452re-pinout.png +.. image:: img/nucleo_l452re_pinout.png :width: 496px :align: center :height: 446px :alt: Nucleo L452RE Pinout -For mode details please refer to `STM32 Nucleo-32 board User Manual`_. +.. image:: img/nucleo_l452re_p_pinout.png + :width: 537px + :align: center + :height: 446px + :alt: Nucleo L452RE-P Pinout + +For more details please refer to `ST Nucleo L452RE User Manual`_ or +`ST Nucleo L452RE-P User Manual`_. Default Zephyr Peripheral Mapping: ---------------------------------- @@ -150,10 +166,15 @@ Default Zephyr Peripheral Mapping: - UART_1_TX : PA9 - UART_1_RX : PA10 - UART_2_TX : PA2 -- UART_2_RX : PA15 +- UART_2_RX : PA3 - I2C_1_SCL : PB6 - I2C_1_SDA : PB7 - PWM_2_CH1 : PA0 +- SPI_SCK : PA5 +- SPI_MISO : PA6 +- SPI_MOSI : PA7 +- CAN_TX : PA11 +- CAN_RX : PA12 - LD2 : PA5 System Clock @@ -224,9 +245,15 @@ You can debug an application in the usual way. Here is an example for the .. _Nucleo L452RE website: https://www.st.com/en/evaluation-tools/nucleo-l452re.html -.. _STM32 Nucleo-32 board User Manual: +.. _Nucleo L452RE-P website: + https://www.st.com/en/evaluation-tools/nucleo-l452re-p.html + +.. _ST Nucleo L452RE User Manual: https://www.st.com/resource/en/user_manual/dm00105823.pdf +.. _ST Nucleo L452RE-P User Manual: + https://www.st.com/resource/en/user_manual/dm00387966.pdf + .. _STM32L452RE on www.st.com: https://www.st.com/en/microcontrollers-microprocessors/stm32l452re.html diff --git a/boards/arm/nucleo_l452re/nucleo_l452re.dts b/boards/arm/nucleo_l452re/nucleo_l452re.dts index a107557ab84773..5dbac905201d4a 100644 --- a/boards/arm/nucleo_l452re/nucleo_l452re.dts +++ b/boards/arm/nucleo_l452re/nucleo_l452re.dts @@ -1,24 +1,18 @@ /* * Copyright (c) 2019 Libre Solar Technologies GmbH + * Copyright (c) 2020 Sparks, Circuits and Robotics SL * * SPDX-License-Identifier: Apache-2.0 */ /dts-v1/; -#include +#include "nucleo_l452re_common.dtsi" +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32L452RE-NUCLEO board"; - compatible = "st,stm32l452re-nucleo", "st,stm32l452"; - - chosen { - zephyr,console = &usart2; - zephyr,shell-uart = &usart2; - zephyr,sram = &sram0; - zephyr,flash = &flash0; - zephyr,can-primary = &can1; - }; + compatible = "st,stm32l452re-nucleo"; leds { compatible = "gpio-leds"; @@ -28,65 +22,7 @@ }; }; - gpio_keys { - compatible = "gpio-keys"; - user_button: button { - label = "User"; - gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; - }; - }; - aliases { led0 = &green_led; - sw0 = &user_button; - }; -}; - -&usart1 { - current-speed = <115200>; -}; - -&usart2 { - current-speed = <115200>; - status = "okay"; -}; - -&spi1 { - status = "okay"; -}; - -&timers2 { - status = "okay"; - - pwm2: pwm { - status = "okay"; - }; -}; - -&can1 { - bus-speed = <125000>; - status = "okay"; -}; - -&rtc { - status = "okay"; -}; - -&flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - /* - * Reserve the final 16 KiB for file system partition - */ - storage_partition: partition@7c000 { - label = "storage"; - reg = <0x0007c000 0x00008000>; - }; }; }; diff --git a/boards/arm/nucleo_l452re/nucleo_l452re_common.dtsi b/boards/arm/nucleo_l452re/nucleo_l452re_common.dtsi new file mode 100644 index 00000000000000..583ea99a044381 --- /dev/null +++ b/boards/arm/nucleo_l452re/nucleo_l452re_common.dtsi @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2019 Libre Solar Technologies GmbH + * Copyright (c) 2020 Sparks, Circuits and Robotics SL + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "arduino_r3_connector.dtsi" + +/ { + model = "STMicroelectronics STM32L452RE-NUCLEO board"; + compatible = "st,stm32l452re-nucleo"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,can-primary = &can1; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + }; + }; + + aliases { + sw0 = &user_button; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + current-speed = <115200>; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + current-speed = <115200>; + status = "okay"; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; + clock-frequency = ; + status = "okay"; +}; + +&timers2 { + status = "okay"; + + pwm2: pwm { + status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; + }; +}; + +&can1 { + pinctrl-0 = <&can1_rx_pa11 &can1_tx_pa12>; + bus-speed = <125000>; + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&flash0 { + /* + * For more information, see: + * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + /* + * Reserve the final 16 KiB for file system partition + */ + storage_partition: partition@7c000 { + label = "storage"; + reg = <0x0007c000 0x00008000>; + }; + }; +}; diff --git a/boards/arm/nucleo_l452re/nucleo_l452re_defconfig b/boards/arm/nucleo_l452re/nucleo_l452re_defconfig index 503620ee57a2a2..a4f29fa62b60bf 100644 --- a/boards/arm/nucleo_l452re/nucleo_l452re_defconfig +++ b/boards/arm/nucleo_l452re/nucleo_l452re_defconfig @@ -8,6 +8,12 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=80000000 # enable uart driver CONFIG_SERIAL=y +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable pinmux CONFIG_PINMUX=y diff --git a/boards/arm/nucleo_l452re/nucleo_l452re_p.dts b/boards/arm/nucleo_l452re/nucleo_l452re_p.dts new file mode 100644 index 00000000000000..02ecac35e42b18 --- /dev/null +++ b/boards/arm/nucleo_l452re/nucleo_l452re_p.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019 Libre Solar Technologies GmbH + * Copyright (c) 2020 Sparks, Circuits and Robotics SL + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "nucleo_l452re_common.dtsi" +#include +#include "arduino_r3_connector.dtsi" + +/ { + model = "STMicroelectronics STM32L452RE-P-NUCLEO board"; + compatible = "st,stm32l452re-nucleo"; + + leds { + compatible = "gpio-leds"; + green_led: led_0 { + gpios = <&gpiob 13 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + aliases { + led0 = &green_led; + }; +}; diff --git a/boards/arm/nucleo_l452re/nucleo_l452re_p.yaml b/boards/arm/nucleo_l452re/nucleo_l452re_p.yaml new file mode 100644 index 00000000000000..0f02e07d1a46b0 --- /dev/null +++ b/boards/arm/nucleo_l452re/nucleo_l452re_p.yaml @@ -0,0 +1,16 @@ +identifier: nucleo_l452re_p +name: ST Nucleo L452RE-P +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 160 +flash: 512 +supported: + - nvs + - pwm + - can + - counter + - spi diff --git a/boards/arm/nucleo_l452re/nucleo_l452re_p_defconfig b/boards/arm/nucleo_l452re/nucleo_l452re_p_defconfig new file mode 100644 index 00000000000000..a4f29fa62b60bf --- /dev/null +++ b/boards/arm/nucleo_l452re/nucleo_l452re_p_defconfig @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32L4X=y +CONFIG_SOC_STM32L452XX=y +# 80MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=80000000 + +# enable uart driver +CONFIG_SERIAL=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# enable pinmux +CONFIG_PINMUX=y + +# enable GPIO +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# PLL configuration +CONFIG_CLOCK_STM32_PLL_SRC_HSI=y +# produce 80MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=1 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=20 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=7 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_R_DIVISOR=4 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=1 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 + +# console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nucleo_l452re/pinmux.c b/boards/arm/nucleo_l452re/pinmux.c deleted file mode 100644 index 61d0b8b8384db0..00000000000000 --- a/boards/arm/nucleo_l452re/pinmux.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2019 Libre Solar Technologies GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-L452RE board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32L4X_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32L4X_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L4X_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L4X_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32L4X_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32L4X_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32L4X_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32L4X_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32L4X_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PA11, STM32L4X_PINMUX_FUNC_PA11_CAN_RX}, - {STM32_PIN_PA12, STM32L4X_PINMUX_FUNC_PA12_CAN_TX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_l476rg/CMakeLists.txt b/boards/arm/nucleo_l476rg/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_l476rg/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_l476rg/nucleo_l476rg.dts b/boards/arm/nucleo_l476rg/nucleo_l476rg.dts index 1ac7b8b38d6c64..4c8a22ab41a40a 100644 --- a/boards/arm/nucleo_l476rg/nucleo_l476rg.dts +++ b/boards/arm/nucleo_l476rg/nucleo_l476rg.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32L476RG-NUCLEO board"; - compatible = "st,stm32l476rg-nucleo", "st,stm32l476"; + compatible = "st,stm32l476rg-nucleo"; chosen { zephyr,console = &usart2; @@ -42,34 +43,60 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; +&usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; + current-speed = <115200>; +}; + &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c3 { + pinctrl-0 = <&i2c3_scl_pc0 &i2c3_sda_pc1>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pb3 + &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; +&spi3 { + /* SPI3 on the ST Morpho Connector CN7 pins 17, 1, 2, 3*/ + pinctrl-0 = <&spi3_nss_pa15 &spi3_sck_pc10 + &spi3_miso_pc11 &spi3_mosi_pc12>; + status = "okay"; +}; + + &timers2 { status = "okay"; pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; @@ -78,5 +105,6 @@ }; &adc1 { + pinctrl-0 = <&adc1_in1_pc0>; status = "okay"; }; diff --git a/boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig b/boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig index e8d8cb546f3270..d6716669c4b573 100644 --- a/boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig +++ b/boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig @@ -39,3 +39,6 @@ CONFIG_PWM=y #enable MPU CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/nucleo_l476rg/pinmux.c b/boards/arm/nucleo_l476rg/pinmux.c deleted file mode 100644 index a6e7b837c16721..00000000000000 --- a/boards/arm/nucleo_l476rg/pinmux.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016 Open-RnD Sp. z o.o. - * Copyright (c) 2016 BayLibre, SAS - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-L476RG board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32L4X_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32L4X_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L4X_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L4X_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32L4X_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32L4X_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32L4X_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32L4X_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PC0, STM32L4X_PINMUX_FUNC_PC0_I2C3_SCL}, - {STM32_PIN_PC1, STM32L4X_PINMUX_FUNC_PC1_I2C3_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32L4X_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - /* SPI1 on the Arduino connectors pins A2, D3, D12, D11 */ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32L4X_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - /* SPI1_SCK should output on PA5, but is used for LD2 */ - {STM32_PIN_PB3, STM32L4X_PINMUX_FUNC_PB3_SPI1_SCK}, - {STM32_PIN_PA6, STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - /* SPI2 on the ST Morpho Connector CN10 pins 16, 30, 28, 26*/ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32L4X_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32L4X_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32L4X_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32L4X_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi3), okay) && CONFIG_SPI - /* SPI3 on the ST Morpho Connector CN7 pins 17, 1, 2, 3*/ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA15, STM32L4X_PINMUX_FUNC_PA15_SPI3_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PC10, STM32L4X_PINMUX_FUNC_PC10_SPI3_SCK}, - {STM32_PIN_PC11, STM32L4X_PINMUX_FUNC_PC11_SPI3_MISO}, - {STM32_PIN_PC12, STM32L4X_PINMUX_FUNC_PC12_SPI3_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PC0, STM32L4X_PINMUX_FUNC_PC0_ADC123_IN1}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_l496zg/CMakeLists.txt b/boards/arm/nucleo_l496zg/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_l496zg/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_l496zg/nucleo_l496zg.dts b/boards/arm/nucleo_l496zg/nucleo_l496zg.dts index 8b124999c682ea..2cc6942c4bc147 100644 --- a/boards/arm/nucleo_l496zg/nucleo_l496zg.dts +++ b/boards/arm/nucleo_l496zg/nucleo_l496zg.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32L496ZG-NUCLEO board"; - compatible = "st,stm32l496zg-nucleo", "st,stm32l496"; + compatible = "st,stm32l496zg-nucleo"; chosen { zephyr,console = &lpuart1; @@ -39,7 +40,7 @@ compatible = "pwm-leds"; red_pwm_led: red_pwm_led { - pwms = <&pwm15 1 4>; + pwms = <&pwm15 1 4 PWM_POLARITY_NORMAL>; }; }; @@ -61,6 +62,7 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>; current-speed = <115200>; status = "okay"; }; @@ -71,6 +73,7 @@ }; &lpuart1 { + pinctrl-0 = <&lpuart1_tx_pg7 &lpuart1_rx_pg8>; current-speed = <115200>; status = "okay"; }; @@ -80,6 +83,9 @@ pwm1: pwm { status = "okay"; + pinctrl-0 = <&tim1_ch1_pe9 + &tim1_ch2_pe11 + &tim1_ch3_pe13>; }; }; @@ -88,14 +94,7 @@ pwm2: pwm { status = "okay"; - }; -}; - -&timers4 { - status = "okay"; - - pwm4: pwm { - status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; @@ -104,15 +103,18 @@ pwm15: pwm { status = "okay"; + pinctrl-0 = <&tim15_ch1_pb14>; }; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; diff --git a/boards/arm/nucleo_l496zg/nucleo_l496zg_defconfig b/boards/arm/nucleo_l496zg/nucleo_l496zg_defconfig index 0b0cbec31bcff1..87ea9d73683922 100644 --- a/boards/arm/nucleo_l496zg/nucleo_l496zg_defconfig +++ b/boards/arm/nucleo_l496zg/nucleo_l496zg_defconfig @@ -36,3 +36,6 @@ CONFIG_UART_CONSOLE=y #enable MPU CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/nucleo_l496zg/pinmux.c b/boards/arm/nucleo_l496zg/pinmux.c deleted file mode 100644 index 840bc0b39b1539..00000000000000 --- a/boards/arm/nucleo_l496zg/pinmux.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2018 Centaur Analytics, Inc - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-L496ZG board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PD5, STM32L4X_PINMUX_FUNC_PD5_USART2_TX}, - {STM32_PIN_PD6, STM32L4X_PINMUX_FUNC_PD6_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpuart1), okay) && CONFIG_SERIAL - {STM32_PIN_PG7, STM32L4X_PINMUX_FUNC_PG7_LPUART1_TX}, - {STM32_PIN_PG8, STM32L4X_PINMUX_FUNC_PG8_LPUART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32L4X_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32L4X_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PA5, STM32L4X_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - {STM32_PIN_PE9, STM32L4X_PINMUX_FUNC_PE9_PWM1_CH1}, - {STM32_PIN_PE11, STM32L4X_PINMUX_FUNC_PE11_PWM1_CH2}, - {STM32_PIN_PE13, STM32L4X_PINMUX_FUNC_PE13_PWM1_CH3}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32L4X_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm15), okay) && CONFIG_PWM - {STM32_PIN_PB14, STM32L4X_PINMUX_FUNC_PB14_PWM15_CH1}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_l4r5zi/CMakeLists.txt b/boards/arm/nucleo_l4r5zi/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/nucleo_l4r5zi/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_l4r5zi/doc/index.rst b/boards/arm/nucleo_l4r5zi/doc/index.rst index c98f07205fdd5c..0507e22e3096bc 100644 --- a/boards/arm/nucleo_l4r5zi/doc/index.rst +++ b/boards/arm/nucleo_l4r5zi/doc/index.rst @@ -141,6 +141,8 @@ hardware features: +-----------+------------+-------------------------------------+ | USB | on-chip | usb | +-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -178,7 +180,7 @@ Default Zephyr Peripheral Mapping: - I2C_1_SCL : PB6 - I2C_1_SDA : PB7 - SPI_1_NSS : PA4 -- SPI_1_SCK : PB3 +- SPI_1_SCK : PA5 - SPI_1_MISO : PA6 - SPI_1_MOSI : PA7 - SPI_2_NSS : PB12 @@ -196,6 +198,7 @@ Default Zephyr Peripheral Mapping: - LD3 : PB14 - USB DM : PA11 - USB DP : PA12 +- ADC1 : PC0 System Clock ------------ diff --git a/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.dts b/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.dts index b5b3730a9f7f3f..b105af3a87f91b 100644 --- a/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.dts +++ b/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32L4R5ZI-NUCLEO board"; - compatible = "st,stm32l4r5zi-nucleo", "st,stm32l4r5"; + compatible = "st,stm32l4r5zi-nucleo"; chosen { zephyr,console = &lpuart1; @@ -54,34 +55,56 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; current-speed = <115200>; status = "okay"; }; &lpuart1 { + pinctrl-0 = <&lpuart1_tx_pg7 &lpuart1_rx_pg8>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; + status = "okay"; +}; + +&spi3 { + /* SPI3 on the ST Morpho Connector CN7 pins 17, 1, 2, 3*/ + pinctrl-0 = <&spi3_nss_pa15 &spi3_sck_pc10 + &spi3_miso_pc11 &spi3_mosi_pc12>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12 + &usb_otg_fs_id_pa10>; status = "okay"; }; @@ -90,6 +113,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; @@ -114,3 +138,8 @@ }; }; }; + +&adc1 { + pinctrl-0 = <&adc1_in1_pc0>; + status = "okay"; +}; diff --git a/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.yaml b/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.yaml index 75bb9f49a5ab2f..5c1cb0e1e7612a 100644 --- a/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.yaml +++ b/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi.yaml @@ -17,5 +17,6 @@ supported: - usb device - nvs - counter + - adc ram: 640 flash: 2048 diff --git a/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi_defconfig b/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi_defconfig index 6ccbca3cff73bb..cb4a0832496600 100644 --- a/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi_defconfig +++ b/boards/arm/nucleo_l4r5zi/nucleo_l4r5zi_defconfig @@ -55,3 +55,6 @@ CONFIG_UART_CONSOLE=y # Enable MPU CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/nucleo_l4r5zi/pinmux.c b/boards/arm/nucleo_l4r5zi/pinmux.c deleted file mode 100644 index a55c871386629b..00000000000000 --- a/boards/arm/nucleo_l4r5zi/pinmux.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2018 Pushpal Sidhu - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-L4R5ZI board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32L4X_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32L4X_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpuart1), okay) && CONFIG_SERIAL - {STM32_PIN_PG7, STM32L4X_PINMUX_FUNC_PG7_LPUART1_TX}, - {STM32_PIN_PG8, STM32L4X_PINMUX_FUNC_PG8_LPUART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L4X_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L4X_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PD8, STM32L4X_PINMUX_FUNC_PD8_USART3_TX}, - {STM32_PIN_PD9, STM32L4X_PINMUX_FUNC_PD9_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32L4X_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32L4X_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32L4X_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - /* SPI1 on the Arduino connectors pins A2, D3, D12, D11 */ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32L4X_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - /* SPI1_SCK should output on PA5, but is used for LD2 */ - {STM32_PIN_PB3, STM32L4X_PINMUX_FUNC_PB3_SPI1_SCK}, - {STM32_PIN_PA6, STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - /* SPI2 on the ST Morpho Connector CN10 pins 16, 30, 28, 26*/ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32L4X_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32L4X_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32L4X_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32L4X_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi3), okay) && CONFIG_SPI - /* SPI3 on the ST Morpho Connector CN7 pins 17, 1, 2, 3*/ -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA15, STM32L4X_PINMUX_FUNC_PA15_SPI3_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PC10, STM32L4X_PINMUX_FUNC_PC10_SPI3_SCK}, - {STM32_PIN_PC11, STM32L4X_PINMUX_FUNC_PC11_SPI3_MISO}, - {STM32_PIN_PC12, STM32L4X_PINMUX_FUNC_PC12_SPI3_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA10, STM32L4X_PINMUX_FUNC_PA10_OTG_FS_ID}, - {STM32_PIN_PA11, STM32L4X_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32L4X_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_l552ze_q/CMakeLists.txt b/boards/arm/nucleo_l552ze_q/CMakeLists.txt index d1b8108cfed55b..696a175a7794af 100644 --- a/boards/arm/nucleo_l552ze_q/CMakeLists.txt +++ b/boards/arm/nucleo_l552ze_q/CMakeLists.txt @@ -1,7 +1,68 @@ # SPDX-License-Identifier: Apache-2.0 if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) endif() + +if(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "zephyr") + set(COMPILER_FULL_PATH ${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc) +elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "gnuarmemb") + set(COMPILER_FULL_PATH ${GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc) +endif() + +if (CONFIG_BUILD_WITH_TFM) + # Set default image versions if not defined elsewhere + if (NOT DEFINED TFM_IMAGE_VERSION_S) + set(TFM_IMAGE_VERSION_S 0.0.0+0) + endif() + + if (NOT DEFINED TFM_IMAGE_VERSION_NS) + set(TFM_IMAGE_VERSION_NS 0.0.0+0) + endif() + + set(PREPROCESSED_FILE_S "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.o") + set(PREPROCESSED_FILE_NS "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_ns.dir/signing_layout_ns.o") + set(TFM_MCUBOOT_DIR "${ZEPHYR_TFM_MODULE_DIR}/trusted-firmware-m/bl2/ext/mcuboot") + + # Configure which format (full or hash) to include the public key in + # the image manifest + set(TFM_PUBLIC_KEY_FORMAT "full") + + #Create and sign for concatenated binary image, should align with the TF-M BL2 + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + + #Sign secure binary image with public key + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_S} + -k ${CONFIG_TFM_KEY_FILE_S} + --public-key-format ${TFM_PUBLIC_KEY_FORMAT} + --align 1 + -v ${TFM_IMAGE_VERSION_S} + --pad + --pad-header + ${ADD_NS_IMAGE_MIN_VER} + -s auto + -H 0x400 + ${CMAKE_BINARY_DIR}/tfm/install/outputs/STM/NUCLEO_L552ZE_Q/tfm_s.bin + ${CMAKE_BINARY_DIR}/tfm_s_signed.bin + + #Sign non-secure binary image with public key + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_NS} + -k ${CONFIG_TFM_KEY_FILE_NS} + --public-key-format ${TFM_PUBLIC_KEY_FORMAT} + --align 1 + -v ${TFM_IMAGE_VERSION_NS} + -s auto + ${ADD_S_IMAGE_MIN_VER} + -H 0x400 + ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} + ${CMAKE_BINARY_DIR}/zephyr_ns_signed.bin + + #Copy mcuboot.bin + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm/bin/bl2.bin ${CMAKE_BINARY_DIR}/mcuboot.bin + + #Execute post build script postbuild.sh + COMMAND ${CMAKE_BINARY_DIR}/tfm/postbuild.sh ${COMPILER_FULL_PATH} + ) +endif() diff --git a/boards/arm/nucleo_l552ze_q/Kconfig.defconfig b/boards/arm/nucleo_l552ze_q/Kconfig.defconfig index ee7b795d4cb6a3..935fa80cc99681 100644 --- a/boards/arm/nucleo_l552ze_q/Kconfig.defconfig +++ b/boards/arm/nucleo_l552ze_q/Kconfig.defconfig @@ -8,4 +8,16 @@ if BOARD_NUCLEO_L552ZE_Q config BOARD default "nucleo_l552ze_q" +if TRUSTED_EXECUTION_NONSECURE + +# Get flash configuration for NS image from dts flash partition +config USE_DT_CODE_PARTITION + default y + +config TFM_ISOLATION_LEVEL + default 2 + depends on BUILD_WITH_TFM + +endif # TRUSTED_EXECUTION_NONSECURE + endif # BOARD_NUCLEO_L552ZE_Q diff --git a/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_arduino.png b/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_arduino.png deleted file mode 100644 index 7e76836a502359..00000000000000 Binary files a/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_arduino.png and /dev/null differ diff --git a/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_morpho.png b/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_morpho.png deleted file mode 100644 index 2767e85bc65eb0..00000000000000 Binary files a/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_morpho.png and /dev/null differ diff --git a/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_zio_left_2020_2_11.png b/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_zio_left_2020_2_11.png new file mode 100644 index 00000000000000..6ffbdaddbb9858 Binary files /dev/null and b/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_zio_left_2020_2_11.png differ diff --git a/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_zio_right_2020_2_11.png b/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_zio_right_2020_2_11.png new file mode 100644 index 00000000000000..addb782a86afdd Binary files /dev/null and b/boards/arm/nucleo_l552ze_q/doc/img/nucleo_l552ze_q_zio_right_2020_2_11.png differ diff --git a/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst b/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst index 0cd6616ac767ba..561126992afc69 100644 --- a/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst +++ b/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst @@ -152,6 +152,8 @@ The Zephyr nucleo_l552ze_q board configuration supports the following hardware f +-----------+------------+-------------------------------------+ | SPI | on-chip | spi | +-----------+------------+-------------------------------------+ +| TrustZone | on-chip | Trusted Firmware-M | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -167,16 +169,16 @@ input/output, pull-up, etc. Available pins: --------------- -.. image:: img/nucleo_l552ze_q_arduino.png +.. image:: img/nucleo_l552ze_q_zio_left_2020_2_11.png :width: 720px :align: center :height: 540px - :alt: Nucleo L552ZE Q Arduino connectors -.. image:: img/nucleo_l552ze_q_morpho.png + :alt: Nucleo L552ZE Q Zio left connector +.. image:: img/nucleo_l552ze_q_zio_right_2020_2_11.png :width: 720px :align: center :height: 540px - :alt: Nucleo L552ZE Q Morpho connectors + :alt: Nucleo L552ZE Q Zio right connector For mode details please refer to `STM32 Nucleo-144 board User Manual`_. @@ -238,6 +240,7 @@ the following pyocd command: .. code-block:: console + $ pyocd pack --update $ pyocd pack --install stm32l552ze Nucleo L552ZE Q board includes an ST-LINK/V2-1 embedded debug tool @@ -270,6 +273,11 @@ You should see the following message on the console: Hello World! arm +Building a secure/non-secure with Arm |reg| TrustZone |reg| +----------------------------------------------------------- + +The TF-M integration sample :ref:`tfm_ipc` can be run by a Nucleo L552ZE Q, using the ``nucleo_l552ze_q_ns`` target. When building a ``*_ns`` image with TF-M, a ``build/tfm/install/postbuild.sh`` bash script will be run as a post-build step to make some required flash layout changes. The ``build/tfm/install/postbuild.sh`` script will also be used to flash the board. Check the ``build/tfm/install`` directory to ensure that the commands required by these scripts (``readlink``, etc.) are available on your system. + Debugging ========= diff --git a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q-common.dtsi b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q-common.dtsi new file mode 100644 index 00000000000000..560f56331dcdf9 --- /dev/null +++ b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q-common.dtsi @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "arduino_r3_connector.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + green_led_1: led_1 { + gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + blue_led_1: led_2 { + gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + red_led_1: led_3 { + gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>; + label = "User LD3"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + }; + }; +}; diff --git a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q.dts b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q.dts index a746379184339d..d9f0ed693438aa 100644 --- a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q.dts +++ b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q.dts @@ -5,12 +5,11 @@ */ /dts-v1/; -#include -#include "arduino_r3_connector.dtsi" +#include "nucleo_l552ze_q-common.dtsi" / { model = "STMicroelectronics STM32L552ZE-NUCLEO-Q board"; - compatible = "st,stm32l552ze-nucleo-q", "st,stm32l552"; + compatible = "st,stm32l552ze-nucleo-q"; #address-cells = <1>; #size-cells = <1>; @@ -22,30 +21,6 @@ zephyr,flash = &flash0; }; - leds { - compatible = "gpio-leds"; - green_led_1: led_1 { - gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; - label = "User LD1"; - }; - blue_led_1: led_2 { - gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>; - label = "User LD2"; - }; - red_led_1: led_3 { - gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>; - label = "User LD3"; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - user_button: button { - label = "User"; - gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; - }; - }; - aliases { led0 = &blue_led_1; sw0 = &user_button; @@ -53,6 +28,7 @@ }; &lpuart1 { + pinctrl-0 = <&lpuart1_tx_pg7 &lpuart1_rx_pg8>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_defconfig b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_defconfig index bae121b61afe2c..11ea9125e658cc 100644 --- a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_defconfig +++ b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_defconfig @@ -40,3 +40,6 @@ CONFIG_UART_CONSOLE=y # Enable MPU CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.dts b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.dts new file mode 100644 index 00000000000000..6c83139ffccd2c --- /dev/null +++ b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.dts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "nucleo_l552ze_q-common.dtsi" + +/ { + model = "STMicroelectronics STM32L552ZE-NUCLEO-Q board"; + compatible = "st,stm32l552ze-nucleo-q"; + + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + aliases { + led0 = &blue_led_1; + sw0 = &user_button; + }; +}; + +&lpuart1 { + current-speed = <115200>; + status = "okay"; +}; diff --git a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.yaml b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.yaml new file mode 100644 index 00000000000000..e94bf758ae1c8a --- /dev/null +++ b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns.yaml @@ -0,0 +1,11 @@ +identifier: nucleo_l552ze_q_ns +name: ST Nucleo L552ZE Q non secure +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio +ram: 192 +flash: 328 diff --git a/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns_defconfig b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns_defconfig new file mode 100644 index 00000000000000..736fdc081f7f5a --- /dev/null +++ b/boards/arm/nucleo_l552ze_q/nucleo_l552ze_q_ns_defconfig @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32L5X=y +CONFIG_SOC_STM32L552XX=y +# 110MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=110000000 + +# enable uart driver +CONFIG_SERIAL=y + +# enable pinmux +CONFIG_PINMUX=y + +# enable GPIO +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# PLL configuration +CONFIG_CLOCK_STM32_PLL_SRC_MSI=y +CONFIG_CLOCK_STM32_MSI_RANGE=6 +#CONFIG_CLOCK_STM32_LSE=y +#CONFIG_CLOCK_STM32_MSI_PLL_MODE=y +# produce 110MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=1 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=55 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=7 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_R_DIVISOR=2 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=1 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 + +# console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +CONFIG_ARM_TRUSTZONE_M=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_RUNTIME_NMI=y +CONFIG_TRUSTED_EXECUTION_NONSECURE=y diff --git a/boards/arm/nucleo_l552ze_q/pinmux.c b/boards/arm/nucleo_l552ze_q/pinmux.c deleted file mode 100644 index 4bf853eec6b0b6..00000000000000 --- a/boards/arm/nucleo_l552ze_q/pinmux.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2020 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-L552ZE-Q board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpuart1), okay) && CONFIG_SERIAL - {STM32_PIN_PG7, STM32L5X_PINMUX_FUNC_PG7_LPUART1_TX}, - {STM32_PIN_PG8, STM32L5X_PINMUX_FUNC_PG8_LPUART1_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nucleo_wb55rg/CMakeLists.txt b/boards/arm/nucleo_wb55rg/CMakeLists.txt deleted file mode 100644 index 3b22ab6d84fd84..00000000000000 --- a/boards/arm/nucleo_wb55rg/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.rst b/boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.rst index f0f50091bbfc5c..e301d0aaa86497 100644 --- a/boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.rst +++ b/boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.rst @@ -250,6 +250,7 @@ the following pyocd command: .. code-block:: console + $ pyocd pack --update $ pyocd pack --install stm32wb55rg diff --git a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts index 002fe8d8fc6674..df8e3babbb3f48 100644 --- a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts +++ b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32WB55RG-NUCLEO board"; - compatible = "st,stm32wb55rg-nucleo", "st,stm32wb55rg"; + compatible = "st,stm32wb55rg-nucleo"; chosen { zephyr,console = &usart1; @@ -62,16 +63,19 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c3 { + pinctrl-0 = <&i2c3_scl_pc0 &i2c3_sda_pc1>; status = "okay"; clock-frequency = ; }; @@ -81,6 +85,8 @@ }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; @@ -88,15 +94,18 @@ status = "okay"; pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; &lpuart1 { + pinctrl-0 = <&lpuart1_tx_pa2 &lpuart1_rx_pa3>; current-speed = <115200>; status = "okay"; }; &adc1 { + pinctrl-0 = <&adc1_in3_pc2>; status = "okay"; }; @@ -110,12 +119,13 @@ &usb { status = "okay"; + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; }; &flash0 { /* * For more information, see: - * http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html + * https://docs.zephyrproject.org/latest/reference/devicetree/index.html#fixed-flash-partitions */ partitions { compatible = "fixed-partitions"; diff --git a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.yaml b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.yaml index 33a619e3551264..52381029f62e6e 100644 --- a/boards/arm/nucleo_wb55rg/nucleo_wb55rg.yaml +++ b/boards/arm/nucleo_wb55rg/nucleo_wb55rg.yaml @@ -4,7 +4,7 @@ type: mcu arch: arm toolchain: - zephyr - - gccarmemb + - gnuarmemb - xtools ram: 96 flash: 1024 diff --git a/boards/arm/nucleo_wb55rg/nucleo_wb55rg_defconfig b/boards/arm/nucleo_wb55rg/nucleo_wb55rg_defconfig index d1b49636f7adb6..7d69240ccb967d 100644 --- a/boards/arm/nucleo_wb55rg/nucleo_wb55rg_defconfig +++ b/boards/arm/nucleo_wb55rg/nucleo_wb55rg_defconfig @@ -31,3 +31,6 @@ CONFIG_UART_CONSOLE=y # Enable MPU CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/nucleo_wb55rg/pinmux.c b/boards/arm/nucleo_wb55rg/pinmux.c deleted file mode 100644 index f94a36cd920336..00000000000000 --- a/boards/arm/nucleo_wb55rg/pinmux.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2018 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for NUCLEO-WB55RG board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB7, STM32WBX_PINMUX_FUNC_PB7_USART1_RX}, - {STM32_PIN_PB6, STM32WBX_PINMUX_FUNC_PB6_USART1_TX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpuart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32WBX_PINMUX_FUNC_PA2_LPUART1_TX}, - {STM32_PIN_PA3, STM32WBX_PINMUX_FUNC_PA3_LPUART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32WBX_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32WBX_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PC0, STM32WBX_PINMUX_FUNC_PC0_I2C3_SCL}, - {STM32_PIN_PC1, STM32WBX_PINMUX_FUNC_PC1_I2C3_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32WBX_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32WBX_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32WBX_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32WBX_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32WBX_PINMUX_FUNC_PA0_TMR2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PC2, STM32WBX_PINMUX_FUNC_PC2_ADC1_IN3}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usb), okay) - {STM32_PIN_PA11, STM32WBX_PINMUX_FUNC_PA11_USB_DM}, - {STM32_PIN_PA12, STM32WBX_PINMUX_FUNC_PA12_USB_DP}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/nuvoton_pfm_m487/Kconfig.board b/boards/arm/nuvoton_pfm_m487/Kconfig.board new file mode 100644 index 00000000000000..ab31e205a3a6d1 --- /dev/null +++ b/boards/arm/nuvoton_pfm_m487/Kconfig.board @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Nuvoton PFM M487 board configuration +# +# Copyright (c) 2020 Linumiz +# Author: Saravanan Sekar + +config BOARD_NUVOTON_PFM_M487 + bool "NUVOTON PFM MP487 Development Board" + depends on SOC_M487 diff --git a/boards/arm/nuvoton_pfm_m487/Kconfig.defconfig b/boards/arm/nuvoton_pfm_m487/Kconfig.defconfig new file mode 100644 index 00000000000000..d9657b64fa4296 --- /dev/null +++ b/boards/arm/nuvoton_pfm_m487/Kconfig.defconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Nuvoton PFM M487 board configuration +# +# Copyright (c) 2020 Linumiz +# Author: Saravanan Sekar + +if BOARD_NUVOTON_PFM_M487 + +config BOARD + default "nuvoton_pfm_m487" + +endif # BOARD_NUVOTON_PFM_M487 diff --git a/boards/arm/nuvoton_pfm_m487/board.cmake b/boards/arm/nuvoton_pfm_m487/board.cmake new file mode 100644 index 00000000000000..7d4b9ea15655e5 --- /dev/null +++ b/boards/arm/nuvoton_pfm_m487/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(nulink "-f") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/nulink.board.cmake) diff --git a/boards/arm/nuvoton_pfm_m487/doc/index.rst b/boards/arm/nuvoton_pfm_m487/doc/index.rst new file mode 100644 index 00000000000000..f998cb3d012ee1 --- /dev/null +++ b/boards/arm/nuvoton_pfm_m487/doc/index.rst @@ -0,0 +1,99 @@ +.. _nuvoton_pfm_m487: + +NUVOTON NUMAKER PFM M487 +######################## + +Overview +******** + +The NuMaker PFM M487 is an Internet of Things (IoT) application focused platform +specially developed by Nuvoton. The PFM-M487 is based on the NuMicro® M487 +Ethernet series MCU with ARM® -Cortex®-M4F core. + +.. image:: ./pfm_m487.jpeg + :width: 720px + :align: center + :alt: PFM-M487 + +Features: +========= +- 32-bit Arm Cortex®-M4 M487JIDAE MCU +- Core clock upto 192 MHz +- 512 KB embedded Dual Bank Flash and 160 KB SRAM +- Audio codec (NAU88L25) with Microphone In and Headphone Out +- Ethernet (IP101GR) for network application +- USB 2.0 High-Speed OTG / Host / Device +- USB 1.1 Full-Speed OTG / Host / Device +- External SPI Flash (Winbond W25Q20) which can be regarded as ROM module +- MicroSD Card slot for T-Flash +- M487 extended interface 4 connector with 36 pins each +- Arduino UNO compatible interface +- Three push-buttons: one is for reset and the other two are for user-defined +- Four LEDs: one is for power indication and the other three are for user-defined +- On-board NU-Link-Me ICE debugger/programmer with SWD connector + +More information about the board can be found at the `PFM M487 User Manual`_. + +Supported Features +================== + +* The on-board 12-MHz crystal allows the device to run at its maximum operating speed of 192MHz. + +The development board configuration supports the following hardware features: + ++-----------+------------+-----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=======================+ +| NVIC | on-chip | nested vectored | +| | | interrupt controller | ++-----------+------------+-----------------------+ +| SYSTICK | on-chip | system clock | ++-----------+------------+-----------------------+ +| UART | on-chip | serial port | ++-----------+------------+-----------------------+ + +Other hardware features are not yet supported on Zephyr porting. + +More details about the supported peripherals are available in `M480 TRM`_ +Other hardware features are not currently supported by the Zephyr kernel. + +Building and Flashing +********************* +Flashing +======== + +Here is an example for the :ref:`hello_world` application. + +On board debugger Nu-link-Me can emulate UART0 as a virtual COM port over usb, +To enable this, set ISW1 DIP switch 1-3 (TXD RXD VOM) to ON. +Connect the PFM M487 IoT to your host computer using the USB port, then +run a serial host program to connect with your board. For example: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nuvoton_pfm_m487 + :goals: flash + +Debugging +========= + +Here is an example for the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nuvoton_pfm_m487 + :goals: debug + +Step through the application in your debugger. + +References +********** + +.. _PFM M487 User Manual: + https://www.nuvoton.com/export/resource-files/UM_NuMaker-PFM-M487_User_Manual_EN_Rev1.01.pdf +.. _M480 TRM: + https://www.nuvoton.com/export/resource-files/TRM_M480_Series_EN_Rev2.02.pdf diff --git a/boards/arm/nuvoton_pfm_m487/doc/pfm_m487.jpeg b/boards/arm/nuvoton_pfm_m487/doc/pfm_m487.jpeg new file mode 100644 index 00000000000000..e8d755a3d1ecb5 Binary files /dev/null and b/boards/arm/nuvoton_pfm_m487/doc/pfm_m487.jpeg differ diff --git a/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.dts b/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.dts new file mode 100644 index 00000000000000..1bc2e83e4ef2ce --- /dev/null +++ b/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.dts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020 Linumiz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Nuvoton PFM M487 board"; + compatible = "nuvoton,pfm-m487", "nuvoton,m487"; + + chosen { + zephyr,console = &uart0; + zephyr,shell = &uart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; +}; + +&flash0 { + reg = <0x0 DT_SIZE_K(512)>; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(160)>; +}; + +&uart0 { + current-speed = <115200>; + status = "okay"; +}; diff --git a/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.yaml b/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.yaml new file mode 100644 index 00000000000000..33af96d6bc9e75 --- /dev/null +++ b/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487.yaml @@ -0,0 +1,10 @@ +identifier: nuvoton_pfm_m487 +name: NUVOTON-PFM-M487 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 160 +flash: 512 diff --git a/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487_defconfig b/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487_defconfig new file mode 100644 index 00000000000000..7efb83ea74d587 --- /dev/null +++ b/boards/arm/nuvoton_pfm_m487/nuvoton_pfm_m487_defconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_M48X=y +CONFIG_SOC_M487=y +CONFIG_BOARD_NUVOTON_PFM_M487=y + +# Enable MPU +CONFIG_ARM_MPU=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=192000000 + +# enable uart driver +CONFIG_SERIAL=y +CONFIG_UART_NUVOTON=y + +# console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nuvoton_pfm_m487/support/openocd.cfg b/boards/arm/nuvoton_pfm_m487/support/openocd.cfg new file mode 100644 index 00000000000000..81a7ce1cbc599e --- /dev/null +++ b/boards/arm/nuvoton_pfm_m487/support/openocd.cfg @@ -0,0 +1,2 @@ +source [find interface/nulink.cfg] +source [find target/numicroM4.cfg] diff --git a/boards/arm/olimex_stm32_e407/CMakeLists.txt b/boards/arm/olimex_stm32_e407/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/olimex_stm32_e407/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/olimex_stm32_e407/olimex_stm32_e407.dts b/boards/arm/olimex_stm32_e407/olimex_stm32_e407.dts index eaca8dde9410c1..8f11df7da01d7e 100644 --- a/boards/arm/olimex_stm32_e407/olimex_stm32_e407.dts +++ b/boards/arm/olimex_stm32_e407/olimex_stm32_e407.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "Olimex STM32-E407 board"; - compatible = "olimex,stm32-e407", "st,stm32f407"; + compatible = "olimex,stm32-e407"; chosen { zephyr,console = &usart1; @@ -42,16 +43,19 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pc6 &usart6_rx_pc7>; current-speed = <115200>; status = "okay"; }; @@ -66,9 +70,25 @@ /* Only one interface should be enabled at a time: usbotg_fs or usbotg_hs */ usb_otg1: &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "disabled"; }; usb_otg2: &usbotg_hs { + pinctrl-0 = <&usb_otg_hs_dm_pb14 &usb_otg_hs_dp_pb15>; status = "okay"; }; + +&mac { + status = "okay"; + pinctrl-0 = <ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_ref_clk_pa1 + ð_mdio_pa2 + ð_col_pa3 + ð_crs_dv_pa7 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pg14>; +}; diff --git a/boards/arm/olimex_stm32_e407/olimex_stm32_e407_defconfig b/boards/arm/olimex_stm32_e407/olimex_stm32_e407_defconfig index dd207468ca22a6..2c271f40edfaed 100644 --- a/boards/arm/olimex_stm32_e407/olimex_stm32_e407_defconfig +++ b/boards/arm/olimex_stm32_e407/olimex_stm32_e407_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/olimex_stm32_e407/pinmux.c b/boards/arm/olimex_stm32_e407/pinmux.c deleted file mode 100644 index 17e2e03b6c9fd0..00000000000000 --- a/boards/arm/olimex_stm32_e407/pinmux.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2017 Erwin Rol - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for OLIMEX-STM32-E407 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32F4_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PC6, STM32F4_PINMUX_FUNC_PC6_USART6_TX}, - {STM32_PIN_PC7, STM32F4_PINMUX_FUNC_PC7_USART6_RX}, -#endif -#ifdef CONFIG_ETH_STM32_HAL - {STM32_PIN_PC1, STM32F4_PINMUX_FUNC_PC1_ETH}, - {STM32_PIN_PC4, STM32F4_PINMUX_FUNC_PC4_ETH}, - {STM32_PIN_PC5, STM32F4_PINMUX_FUNC_PC5_ETH}, - - {STM32_PIN_PA1, STM32F4_PINMUX_FUNC_PA1_ETH}, - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_ETH}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_ETH}, - {STM32_PIN_PA7, STM32F4_PINMUX_FUNC_PA7_ETH}, - - {STM32_PIN_PG11, STM32F4_PINMUX_FUNC_PG11_ETH}, - {STM32_PIN_PG13, STM32F4_PINMUX_FUNC_PG13_ETH}, - {STM32_PIN_PG14, STM32F4_PINMUX_FUNC_PG14_ETH}, -#endif /* CONFIG_ETH_STM32_HAL */ -#ifdef CONFIG_USB_DC_STM32 -#if DT_NODE_HAS_STATUS(DT_INST(0, st_stm32_otgfs), okay) - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* DT_NODE_HAS_STATUS(DT_INST(0, st_stm32_otgfs), okay) */ -#if DT_NODE_HAS_STATUS(DT_INST(0, st_stm32_otghs), okay) - {STM32_PIN_PB14, STM32F4_PINMUX_FUNC_PB14_OTG_HS_DM}, - {STM32_PIN_PB15, STM32F4_PINMUX_FUNC_PB15_OTG_HS_DP}, -#endif /* DT_NODE_HAS_STATUS(DT_INST(0, st_stm32_otghs), okay) */ -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/olimex_stm32_h103/Kconfig.board b/boards/arm/olimex_stm32_h103/Kconfig.board new file mode 100644 index 00000000000000..d2f9e76ae4a5ca --- /dev/null +++ b/boards/arm/olimex_stm32_h103/Kconfig.board @@ -0,0 +1,8 @@ +# OLIMEX-STM32-H103 board configuration + +# Copyright (c) 2020, Josep Puigdemont +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_OLIMEX_STM32_H103 + bool "OLIMEX-STM32-H103 Development Board" + depends on SOC_STM32F103XB diff --git a/boards/arm/olimex_stm32_h103/Kconfig.defconfig b/boards/arm/olimex_stm32_h103/Kconfig.defconfig new file mode 100644 index 00000000000000..5dd2426b5f6288 --- /dev/null +++ b/boards/arm/olimex_stm32_h103/Kconfig.defconfig @@ -0,0 +1,11 @@ +# OLIMEX-STM32-H103 board configuration + +# Copyright (c) 2020, Josep Puigdemont +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_OLIMEX_STM32_H103 + +config BOARD + default "olimex_stm32_h103" + +endif # BOARD_OLIMEX_STM32_H103 diff --git a/boards/arm/olimex_stm32_h103/board.cmake b/boards/arm/olimex_stm32_h103/board.cmake new file mode 100644 index 00000000000000..51a6e9ef3bdc05 --- /dev/null +++ b/boards/arm/olimex_stm32_h103/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32F103RB" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/olimex_stm32_h103/doc/img/olimex_stm32_h103_bottom.jpg b/boards/arm/olimex_stm32_h103/doc/img/olimex_stm32_h103_bottom.jpg new file mode 100644 index 00000000000000..e48e08dcec13b4 Binary files /dev/null and b/boards/arm/olimex_stm32_h103/doc/img/olimex_stm32_h103_bottom.jpg differ diff --git a/boards/arm/olimex_stm32_h103/doc/img/olimex_stm32_h103_top.jpg b/boards/arm/olimex_stm32_h103/doc/img/olimex_stm32_h103_top.jpg new file mode 100644 index 00000000000000..fbf0e21f121604 Binary files /dev/null and b/boards/arm/olimex_stm32_h103/doc/img/olimex_stm32_h103_top.jpg differ diff --git a/boards/arm/olimex_stm32_h103/doc/index.rst b/boards/arm/olimex_stm32_h103/doc/index.rst new file mode 100644 index 00000000000000..6254da45368153 --- /dev/null +++ b/boards/arm/olimex_stm32_h103/doc/index.rst @@ -0,0 +1,259 @@ +.. _olimex_stm32_h103: + +OLIMEX-STM32-H103 +################# + +Overview +******** + +The OLIMEX-STM32-H103 is a simple development board based on the +STMicroelectronics STM32F103RBT6 ARM Cortex-M3 CPU, with all the MCU pins +populated and accessible through two male 26-pin connectors. + +.. figure:: img/olimex_stm32_h103_top.jpg + :width: 800px + :align: center + :alt: OLIMEX-STM32-H103 top + +.. figure:: img/olimex_stm32_h103_bottom.jpg + :width: 800px + :align: center + :alt: OLIMEX-STM32-H103 bottom + + OLIMEX-STM32-H103 + +Hardware +******** + +Information about the board can be found at the +`OLIMEX-STM32-H103 website`_ and `OLIMEX-STM32-H103 user manual`_. +The `OLIMEX-STM32-H103 schematic`_ is also available. + +The `ST STM32F103RB Datasheet`_ contains the processor's +information and the datasheet. + +Supported Features +================== + +The OLIMEX STM32-H103 supports the following hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| NVIC | on-chip | nested vectored | +| | | interrupt controller | ++-----------+------------+----------------------+ +| SYSTICK | on-chip | system clock | ++-----------+------------+----------------------+ +| UART | on-chip | serial port | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C | on-chip | i2c | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| SPI | on-chip | spi | ++-----------+------------+----------------------+ +| USB | on-chip | USB device | ++-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ + +Other hardware features are not supported by the Zephyr kernel. + +Connections and IOs +=================== + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_1 TX/RX: PA9/PA10 +- UART_2 TX/RX: PA2/PA3 +- UART_3 TX/RX: PC10/PC11 (not enabled) +- I2C_1 SCL/SDA : PB6/PB7 +- I2C_2 SCL/SDA : PB10/PB11 +- PWM_1_CH1: PA8 +- SPI_1 NSS_OE/SCK/MISO/MOSI: PA4/PA5/PA6/PA7 +- SPI_2 NSS_OE/SCK/MISO/MOSI: PB12/PB13/PB14/PB15 +- USB_DC DM/DP/DISC/PWR: PA11/PA12/PC11/PC4 (not enabled) +- ADC_1: PA1 + +System Clock +------------ + +The on-board 8 MHz crystal is used to produce a 72 MHz system clock with PLL. + +Serial Port +----------- + +The board has 3 U(S)ARTs, UART1 and UART2 are enabled by default, with UART2 +used as Zephyr's console. Default settings are 115200 8N1. + +On-Board LEDs +------------- + +The board has one on-board green LED that is connected to PC12, which +is active low. + +There is also a red power LED neither connected nor controlled by the MCU. + +On-Board Button +--------------- + +The board has one user button connected to PA0. + +USB +--- + +USB is not enabled by default, however PC4 is configured by default as an ADC +input to sense the USB voltage (see schematic). It is possible to disconnect +it by desoldering the appropriate pad in the PCB. + +The board uses PC11 to disconnect the pull-up resistor on the USB-DP line. + +External Connectors +------------------- + +JTAG/SWD debug + ++-------+----------------------+-------+--------------+ +| PIN # | Signal Name | PIN # | Signal Name | ++=======+======================+=======+==============+ +| 1 | +3.3V | 2 | TVCC 3.3V | ++-------+----------------------+-------+--------------+ +| 3 | PB4 / TRST | 4 | GND | ++-------+----------------------+-------+--------------+ +| 5 | PA15 / TDI | 6 | GND | ++-------+----------------------+-------+--------------+ +| 7 | PA13 / TMS / SWDIO | 8 | GND | ++-------+----------------------+-------+--------------+ +| 9 | PA14 / TCK / SWCLK | 10 | GND | ++-------+----------------------+-------+--------------+ +| 11 | NC | 12 | GND | ++-------+----------------------+-------+--------------+ +| 13 | PB3 / TDO | 14 | GND | ++-------+----------------------+-------+--------------+ +| 15 | RST | 16 | GND | ++-------+----------------------+-------+--------------+ +| 17 | NC | 18 | GND | ++-------+----------------------+-------+--------------+ +| 19 | NC | 20 | GND | ++-------+----------------------+-------+--------------+ + +EXTENSION 1 + ++-------+-----------------------+-------+-----------------------+ +| PIN # | Name / STM32F103 Port | PIN # | Name / STM32F103 Port | ++=======+=======================+=======+=======================+ +| 1 | PA11 / USB_DM | 2 | PA8 / **PWM_1_CH1** | ++-------+-----------------------+-------+-----------------------+ +| 3 | PA12 / USB_DP | 4 | PA9 / **UART1_TX** | ++-------+-----------------------+-------+-----------------------+ +| 5 | +3.3V | 6 | GND | ++-------+-----------------------+-------+-----------------------+ +| 7 | PA10 / **UART1_RX** | 8 | PC10 | ++-------+-----------------------+-------+-----------------------+ +| 9 | PC11 / **USB_DISC** | 10 | PC12 / **LED** | ++-------+-----------------------+-------+-----------------------+ +| 11 | PD2 | 12 | PB5/I2C1_SMBA | ++-------+-----------------------+-------+-----------------------+ +| 13 | PB6 / **I2C1_SCL** | 14 | PA6 / **SPI1_MISO** | ++-------+-----------------------+-------+-----------------------+ +| 15 | PB7 / **I2C1_SDA** | 16 | PB8 | ++-------+-----------------------+-------+-----------------------+ +| 17 | PB9 | 18 | PA5 / **SPI1_SCK** | ++-------+-----------------------+-------+-----------------------+ +| 19 | PC0 | 20 | PC1 | ++-------+-----------------------+-------+-----------------------+ +| 21 | PB0 | 22 | PA7 / **SPI1_MOSI** | ++-------+-----------------------+-------+-----------------------+ +| 23 | VBAT | 24 | PC13 | ++-------+-----------------------+-------+-----------------------+ +| 25 | RST | 26 | PB1 | ++-------+-----------------------+-------+-----------------------+ + +EXTENSION 2 + ++-------+------------------------+-------+-----------------------+ +| PIN # | Name / STM32F103 Port | PIN # | Name / STM32F103 Port | ++=======+========================+=======+=======================+ +| 1 | VDDA | 2 | PC2 | ++-------+------------------------+-------+-----------------------+ +| 3 | GNDA | 4 | PA0 / **BUTTON** | ++-------+------------------------+-------+-----------------------+ +| 5 | +3.3V | 6 | GND | ++-------+------------------------+-------+-----------------------+ +| 7 | PA2 / **USART2_TX** | 8 | PA1 / **ADC_1** | ++-------+------------------------+-------+-----------------------+ +| 9 | PC3 | 10 | PA3 / **USART2_RX** | ++-------+------------------------+-------+-----------------------+ +| 11 | PA4 / **SPI1_NSS** | 12 | PC4 / **USB-P** | ++-------+------------------------+-------+-----------------------+ +| 13 | PC5 | 14 | PB10 / **I2C2_SCL** | ++-------+------------------------+-------+-----------------------+ +| 15 | P11 / **I2C2_SDA** | 16 | PB13 / **SPI2_SCK** | ++-------+------------------------+-------+-----------------------+ +| 17 | PB12 / **SPI2_NSS** | 18 | PB14 / **SPI2_MISO** | ++-------+------------------------+-------+-----------------------+ +| 19 | PB15 / **SPI2_MOSI** | 20 | PC6 | ++-------+------------------------+-------+-----------------------+ +| 21 | PC7 | 22 | PC8 | ++-------+------------------------+-------+-----------------------+ +| 23 | +5V USB | 24 | PC9 | ++-------+------------------------+-------+-----------------------+ +| 25 | GND | 26 | VIN | ++-------+------------------------+-------+-----------------------+ + + +Programming and Debugging +************************* + +This board does not include any embedded debug tool interface, instead you +will have to use an external probe connected to the available 20-pin JTAG +connector to progran and debug the board. Both JTAG and SWD are supported. + +By default when using ``west debug`` ST-Link will be used with OpenOCD's +SWD transport, but it is also possible to use JTAG with the Olimex ARM-USB-OCD-H +probe, for instance. For the latter, you should replace the file ``openocd.cfg`` +by ``openocd_olimex_jtag.cfg``, located in the board's support directory. + +Flashing +======== + +Here is an example for the :ref:`button-sample` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/button + :board: olimex_stm32_h103 + :goals: build flash + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: olimex_stm32_h103 + :maybe-skip-config: + :goals: debug + +References +********** + +.. _OLIMEX-STM32-H103 website: + https://www.olimex.com/Products/ARM/ST/STM32-H103/ + +.. _OLIMEX-STM32-H103 user manual: + https://www.olimex.com/Products/ARM/ST/STM32-H103/resources/STM32-H103.pdf + +.. _OLIMEX-STM32-H103 schematic: + https://www.olimex.com/Products/ARM/ST/STM32-H405/resources/STM32-H405_sch.pdf + +.. _ST STM32F103RB Datasheet: + https://www.st.com/resource/en/datasheet/stm32f103rb.pdf + +.. _STM32f103RB: + https://www.st.com/en/microcontrollers-microprocessors/stm32f103rb.html diff --git a/boards/arm/olimex_stm32_h103/olimex_stm32_h103.dts b/boards/arm/olimex_stm32_h103/olimex_stm32_h103.dts new file mode 100644 index 00000000000000..d2ff28e672bf66 --- /dev/null +++ b/boards/arm/olimex_stm32_h103/olimex_stm32_h103.dts @@ -0,0 +1,106 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2020, Josep Puigdemont + */ + +/dts-v1/; +#include +#include + +/ { + model = "Olimex STM32-H103 board"; + compatible = "olimex,stm32-h103"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + green_led_2: led_2 { + gpios = <&gpioc 12 GPIO_ACTIVE_LOW>; + label = "User LD2"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioa 0 GPIO_ACTIVE_LOW>; + }; + }; + + aliases { + led0 = &green_led_2; + sw0 = &user_button; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + current-speed = <115200>; + status = "okay"; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + current-speed = <115200>; + status = "okay"; +}; + +&usart3 { + pinctrl-0 = <&usart3_tx_pc10 &usart3_rx_pc11>; + current-speed = <115200>; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; + status = "okay"; + clock-frequency = ; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_master_pa4 &spi1_sck_master_pa5 + &spi1_miso_master_pa6 &spi1_mosi_master_pa7>; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_nss_master_pb12 &spi2_sck_master_pb13 + &spi2_miso_master_pb14 &spi2_mosi_master_pb15>; + status = "okay"; +}; + +&timers1 { + status = "okay"; + + pwm1: pwm { + status = "okay"; + pinctrl-0 = <&tim1_ch1_pwm_pa8>; + }; +}; + +&iwdg { + status = "okay"; +}; + +&adc1 { + /* adc1_in14_pc4 is used to sense the USB voltage */ + pinctrl-0 = <&adc1_in1_pa1 &adc1_in14_pc4>; + status = "okay"; +}; + +&usb { + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; + disconnect-gpios = <&gpioc 11 GPIO_ACTIVE_LOW>; +}; diff --git a/boards/arm/olimex_stm32_h103/olimex_stm32_h103.yaml b/boards/arm/olimex_stm32_h103/olimex_stm32_h103.yaml new file mode 100644 index 00000000000000..3dd7361b19bcf7 --- /dev/null +++ b/boards/arm/olimex_stm32_h103/olimex_stm32_h103.yaml @@ -0,0 +1,22 @@ +identifier: olimex_stm32_h103 +name: OLIMEX-STM32-H103 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 20 +flash: 128 +supported: + - adc + - gpio + - i2c + - pwm + - spi + - uart + - watchdog +testing: + ignore_tags: + - bluetooth + - net diff --git a/boards/arm/olimex_stm32_h103/olimex_stm32_h103_defconfig b/boards/arm/olimex_stm32_h103/olimex_stm32_h103_defconfig new file mode 100644 index 00000000000000..0d68fe524cf366 --- /dev/null +++ b/boards/arm/olimex_stm32_h103/olimex_stm32_h103_defconfig @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32F1X=y +CONFIG_SOC_STM32F103XB=y +# 72MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 + +# enable uart driver +CONFIG_SERIAL=y +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# enable pinmux +CONFIG_PINMUX=y + +# enable GPIO +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y +CONFIG_CLOCK_STM32_HSE_CLOCK=8000000 +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# use HSE as PLL input +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# produce 72MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +# APB1 clock must not to exceed 36MHz limit +CONFIG_CLOCK_STM32_APB1_PRESCALER=2 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 diff --git a/boards/arm/olimex_stm32_h103/support/openocd.cfg b/boards/arm/olimex_stm32_h103/support/openocd.cfg new file mode 100644 index 00000000000000..a4c831b8bbc84d --- /dev/null +++ b/boards/arm/olimex_stm32_h103/support/openocd.cfg @@ -0,0 +1,16 @@ +source [find interface/stlink.cfg] + +transport select hla_swd + +source [find board/olimex_stm32_h103.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/olimex_stm32_h103/support/openocd_olimex_jtag.cfg b/boards/arm/olimex_stm32_h103/support/openocd_olimex_jtag.cfg new file mode 100644 index 00000000000000..e953fd32a05c8c --- /dev/null +++ b/boards/arm/olimex_stm32_h103/support/openocd_olimex_jtag.cfg @@ -0,0 +1,22 @@ +source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] + +transport select jtag + +source [find board/olimex_stm32_h103.cfg] + +adapter_khz 1000 +adapter_nsrst_delay 100 +jtag_ntrst_delay 100 + +reset_config srst_only srst_nogate + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/olimex_stm32_h103/support/openocd_stlink.cfg b/boards/arm/olimex_stm32_h103/support/openocd_stlink.cfg new file mode 100644 index 00000000000000..a4c831b8bbc84d --- /dev/null +++ b/boards/arm/olimex_stm32_h103/support/openocd_stlink.cfg @@ -0,0 +1,16 @@ +source [find interface/stlink.cfg] + +transport select hla_swd + +source [find board/olimex_stm32_h103.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/olimex_stm32_h407/CMakeLists.txt b/boards/arm/olimex_stm32_h407/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/olimex_stm32_h407/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/olimex_stm32_h407/olimex_stm32_h407.dts b/boards/arm/olimex_stm32_h407/olimex_stm32_h407.dts index 50cd9d26283b0d..1df14435745309 100644 --- a/boards/arm/olimex_stm32_h407/olimex_stm32_h407.dts +++ b/boards/arm/olimex_stm32_h407/olimex_stm32_h407.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "Olimex STM32-H407 board"; - compatible = "olimex,stm32-h407", "st,stm32f407"; + compatible = "olimex,stm32-h407"; chosen { zephyr,console = &usart2; @@ -42,16 +43,19 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pc6 &usart6_rx_pc7>; current-speed = <115200>; status = "okay"; }; @@ -63,3 +67,7 @@ &rng { status = "okay"; }; + +&usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; +}; diff --git a/boards/arm/olimex_stm32_h407/olimex_stm32_h407_defconfig b/boards/arm/olimex_stm32_h407/olimex_stm32_h407_defconfig index dd207468ca22a6..2c271f40edfaed 100644 --- a/boards/arm/olimex_stm32_h407/olimex_stm32_h407_defconfig +++ b/boards/arm/olimex_stm32_h407/olimex_stm32_h407_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/olimex_stm32_h407/pinmux.c b/boards/arm/olimex_stm32_h407/pinmux.c deleted file mode 100644 index bd330bdff57859..00000000000000 --- a/boards/arm/olimex_stm32_h407/pinmux.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2018, Reto Schneider - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for OLIMEX-STM32-H407 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32F4_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PC6, STM32F4_PINMUX_FUNC_PC6_USART6_TX}, - {STM32_PIN_PC7, STM32F4_PINMUX_FUNC_PC7_USART6_RX}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/olimex_stm32_p405/CMakeLists.txt b/boards/arm/olimex_stm32_p405/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/olimex_stm32_p405/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/olimex_stm32_p405/olimex_stm32_p405.dts b/boards/arm/olimex_stm32_p405/olimex_stm32_p405.dts index 7d6fca157eb851..10b5bc91e5f2a5 100644 --- a/boards/arm/olimex_stm32_p405/olimex_stm32_p405.dts +++ b/boards/arm/olimex_stm32_p405/olimex_stm32_p405.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "Olimex STM32-P405 board"; - compatible = "olimex,stm32-p405", "st,stm32f405"; + compatible = "olimex,stm32-p405"; chosen { zephyr,console = &usart2; @@ -43,6 +44,7 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; @@ -52,6 +54,7 @@ }; &can1 { + pinctrl-0 = <&can1_rx_pb8 &can1_tx_pb9>; bus-speed = <125000>; status = "okay"; }; diff --git a/boards/arm/olimex_stm32_p405/olimex_stm32_p405_defconfig b/boards/arm/olimex_stm32_p405/olimex_stm32_p405_defconfig index 3212fd4f730162..7be06f05bcdc35 100644 --- a/boards/arm/olimex_stm32_p405/olimex_stm32_p405_defconfig +++ b/boards/arm/olimex_stm32_p405/olimex_stm32_p405_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/olimex_stm32_p405/pinmux.c b/boards/arm/olimex_stm32_p405/pinmux.c deleted file mode 100644 index ac9babb61cc0dc..00000000000000 --- a/boards/arm/olimex_stm32_p405/pinmux.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017 Erwin Rol - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for OLIMEX-STM32-P405 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_CAN1_RX}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_CAN1_TX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/olimexino_stm32/CMakeLists.txt b/boards/arm/olimexino_stm32/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/olimexino_stm32/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/olimexino_stm32/olimexino_stm32.dts b/boards/arm/olimexino_stm32/olimexino_stm32.dts index 642d3fc19ee213..3648a577d0ba9c 100644 --- a/boards/arm/olimexino_stm32/olimexino_stm32.dts +++ b/boards/arm/olimexino_stm32/olimexino_stm32.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include / { model = "Olimex OLIMEXINO-STM32 board"; @@ -51,33 +52,42 @@ uext_spi: &spi1 {}; uext_serial: &usart1 {}; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_master_pa4 &spi1_sck_master_pa5 + &spi1_miso_master_pa6 &spi1_mosi_master_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_nss_master_pb12 &spi2_sck_master_pb13 + &spi2_miso_master_pb14 &spi2_mosi_master_pb15>; status = "okay"; cs-gpios = <&gpiod 2 GPIO_ACTIVE_HIGH>; @@ -93,6 +103,7 @@ uext_serial: &usart1 {}; &usb { status = "okay"; disconnect-gpios = <&gpioc 12 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; }; &timers1 { @@ -100,6 +111,7 @@ uext_serial: &usart1 {}; pwm1: pwm { status = "okay"; + pinctrl-0 = <&tim1_ch1_pwm_pa8>; }; }; @@ -108,6 +120,7 @@ uext_serial: &usart1 {}; }; &can1 { + pinctrl-0 = <&can_rx_pb8 &can_tx_pb9>; bus-speed = <125000>; sjw = <1>; prop-seg = <0>; diff --git a/boards/arm/olimexino_stm32/olimexino_stm32_defconfig b/boards/arm/olimexino_stm32/olimexino_stm32_defconfig index ad521a2b50ffed..25e902ce7b206b 100644 --- a/boards/arm/olimexino_stm32/olimexino_stm32_defconfig +++ b/boards/arm/olimexino_stm32/olimexino_stm32_defconfig @@ -5,6 +5,12 @@ CONFIG_SOC_STM32F103XB=y # 72MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y @@ -26,7 +32,6 @@ CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y # use HSE as PLL input CONFIG_CLOCK_STM32_PLL_SRC_HSE=y # produce 72MHz clock at PLL output -CONFIG_CLOCK_STM32_PLL_XTPRE=n CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9 CONFIG_CLOCK_STM32_AHB_PRESCALER=1 # APB1 clock must not to exceed 36MHz limit diff --git a/boards/arm/olimexino_stm32/pinmux.c b/boards/arm/olimexino_stm32/pinmux.c deleted file mode 100644 index 641d700a0712f4..00000000000000 --- a/boards/arm/olimexino_stm32/pinmux.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2016 Open-RnD Sp. z o.o. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include - -#include - -/* pin assignments for OLIMEXINO-STM32 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F1_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F1_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F1_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F1_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32F1_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32F1_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32F1_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32F1_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F1_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB11, STM32F1_PINMUX_FUNC_PB11_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F1_PINMUX_FUNC_PA4_SPI1_MASTER_NSS_OE}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F1_PINMUX_FUNC_PA5_SPI1_MASTER_SCK}, - {STM32_PIN_PA6, STM32F1_PINMUX_FUNC_PA6_SPI1_MASTER_MISO}, - {STM32_PIN_PA7, STM32F1_PINMUX_FUNC_PA7_SPI1_MASTER_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F1_PINMUX_FUNC_PB12_SPI2_MASTER_NSS_OE}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F1_PINMUX_FUNC_PB13_SPI2_MASTER_SCK}, - {STM32_PIN_PB14, STM32F1_PINMUX_FUNC_PB14_SPI2_MASTER_MISO}, - {STM32_PIN_PB15, STM32F1_PINMUX_FUNC_PB15_SPI2_MASTER_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - {STM32_PIN_PA8, STM32F1_PINMUX_FUNC_PA8_PWM1_CH1}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F1_PINMUX_FUNC_PA11_USB_DM}, - {STM32_PIN_PA12, STM32F1_PINMUX_FUNC_PA12_USB_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PB8, STM32F1_PINMUX_FUNC_PB8_CAN_RX}, - {STM32_PIN_PB9, STM32F1_PINMUX_FUNC_PB9_CAN_TX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - /* Set pin-mux so that CAN1 is on PB8 and PB9 */ - AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP2; -#endif - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/particle_argon/Kconfig.defconfig b/boards/arm/particle_argon/Kconfig.defconfig index 1a8fe9bc979150..58be02e64555a2 100644 --- a/boards/arm/particle_argon/Kconfig.defconfig +++ b/boards/arm/particle_argon/Kconfig.defconfig @@ -18,10 +18,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/particle_argon/board.c b/boards/arm/particle_argon/board.c index e0ed973704f02e..a6d559cb34023a 100644 --- a/boards/arm/particle_argon/board.c +++ b/boards/arm/particle_argon/board.c @@ -11,7 +11,7 @@ static inline void external_antenna(bool on) { - struct device *ufl_gpio_dev, *pcb_gpio_dev; + const struct device *ufl_gpio_dev, *pcb_gpio_dev; ufl_gpio_dev = device_get_binding(SKY_UFLn_GPIO_NAME); if (!ufl_gpio_dev) { @@ -35,7 +35,7 @@ static inline void external_antenna(bool on) : GPIO_OUTPUT_ACTIVE)); } -static int board_particle_argon_init(struct device *dev) +static int board_particle_argon_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/particle_argon/board.cmake b/boards/arm/particle_argon/board.cmake index aef57e561453bc..7651b19a7638e1 100644 --- a/boards/arm/particle_argon/board.cmake +++ b/boards/arm/particle_argon/board.cmake @@ -4,7 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/particle_argon/dts/mesh_feather.dtsi b/boards/arm/particle_argon/dts/mesh_feather.dtsi index 05991ec4b51df7..4ab1ee7c6c7640 100644 --- a/boards/arm/particle_argon/dts/mesh_feather.dtsi +++ b/boards/arm/particle_argon/dts/mesh_feather.dtsi @@ -185,7 +185,7 @@ arduino_i2c: &i2c0 { /* feather I2C */ feather_i2c: &i2c0 { }; -/* TWI1 used on Boron; also see mesh_feather_spi1_spi1.dtsi */ +/* TWI1 used on Boron; also see mesh_feather_spi_spi1.dtsi */ &spi2 { /* dedicated MX25L */ compatible = "nordic,nrf-spi"; @@ -193,7 +193,7 @@ feather_i2c: &i2c0 { }; sck-pin = <19>; mosi-pin = <20>; miso-pin = <21>; - cs-gpios = <&gpio0 17 0>; + cs-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; mx25l32: mx25l3233f@0 { compatible = "jedec,spi-nor"; label = "MX25L3233F"; @@ -202,11 +202,15 @@ feather_i2c: &i2c0 { }; wp-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; hold-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; size = <0x2000000>; - has-be32k; has-dpd; t-enter-dpd = <10000>; t-exit-dpd = <100000>; jedec-id = [c2 20 16]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 01 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff + ]; }; }; diff --git a/boards/arm/particle_argon/dts/mesh_feather_spi1_spi3.dtsi b/boards/arm/particle_argon/dts/mesh_feather_spi1_spi3.dtsi index 5e66109e6e7775..7760ecbca283fc 100644 --- a/boards/arm/particle_argon/dts/mesh_feather_spi1_spi3.dtsi +++ b/boards/arm/particle_argon/dts/mesh_feather_spi1_spi3.dtsi @@ -10,6 +10,7 @@ * Changes should be made in all instances. */ &spi3 { /* feather SPI */ + compatible = "nordic,nrf-spim"; status = "okay"; sck-pin = <33>; mosi-pin = <34>; diff --git a/boards/arm/particle_argon/dts/mesh_feather_spi_spi1.dtsi b/boards/arm/particle_argon/dts/mesh_feather_spi_spi1.dtsi index 8086045e2510e4..a67bf11236622d 100644 --- a/boards/arm/particle_argon/dts/mesh_feather_spi_spi1.dtsi +++ b/boards/arm/particle_argon/dts/mesh_feather_spi_spi1.dtsi @@ -10,6 +10,7 @@ * Changes should be made in all instances. */ feather_spi: &spi1 { /* feather SPI */ + compatible = "nordic,nrf-spim"; status = "okay"; sck-pin = <47>; mosi-pin = <45>; diff --git a/boards/arm/particle_argon/dts/mesh_feather_spi_spi3.dtsi b/boards/arm/particle_argon/dts/mesh_feather_spi_spi3.dtsi index 6adf2bd210c207..0c017ea4d20472 100644 --- a/boards/arm/particle_argon/dts/mesh_feather_spi_spi3.dtsi +++ b/boards/arm/particle_argon/dts/mesh_feather_spi_spi3.dtsi @@ -10,6 +10,7 @@ * Changes should be made in all instances. */ feather_spi: &spi3 { /* feather SPI */ + compatible = "nordic,nrf-spim"; status = "okay"; sck-pin = <47>; mosi-pin = <45>; diff --git a/boards/arm/particle_boron/Kconfig.defconfig b/boards/arm/particle_boron/Kconfig.defconfig index 7deb4af2899502..e386f02a122b3b 100644 --- a/boards/arm/particle_boron/Kconfig.defconfig +++ b/boards/arm/particle_boron/Kconfig.defconfig @@ -18,18 +18,11 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT if MODEM -config UART_1_NRF_FLOW_CONTROL - default y - config MODEM_UBLOX_SARA default y diff --git a/boards/arm/particle_boron/board.c b/boards/arm/particle_boron/board.c index bcfa7183a94dfd..0e5714a3efa555 100644 --- a/boards/arm/particle_boron/board.c +++ b/boards/arm/particle_boron/board.c @@ -11,7 +11,7 @@ static inline void external_antenna(bool on) { - struct device *gpio_dev; + const struct device *gpio_dev; /* * On power-up the SKY13351 is left uncontrolled, so neither @@ -30,14 +30,14 @@ static inline void external_antenna(bool on) : GPIO_OUTPUT_INACTIVE)); } -static int board_particle_boron_init(struct device *dev) +static int board_particle_boron_init(const struct device *dev) { ARG_UNUSED(dev); external_antenna(false); #if defined(CONFIG_MODEM_UBLOX_SARA) - struct device *gpio_dev; + const struct device *gpio_dev; /* Enable the serial buffer for SARA-R4 modem */ gpio_dev = device_get_binding(SERIAL_BUFFER_ENABLE_GPIO_NAME); diff --git a/boards/arm/particle_boron/board.cmake b/boards/arm/particle_boron/board.cmake index aef57e561453bc..7651b19a7638e1 100644 --- a/boards/arm/particle_boron/board.cmake +++ b/boards/arm/particle_boron/board.cmake @@ -4,7 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/particle_boron/dts/mesh_feather.dtsi b/boards/arm/particle_boron/dts/mesh_feather.dtsi index 05991ec4b51df7..4ab1ee7c6c7640 100644 --- a/boards/arm/particle_boron/dts/mesh_feather.dtsi +++ b/boards/arm/particle_boron/dts/mesh_feather.dtsi @@ -185,7 +185,7 @@ arduino_i2c: &i2c0 { /* feather I2C */ feather_i2c: &i2c0 { }; -/* TWI1 used on Boron; also see mesh_feather_spi1_spi1.dtsi */ +/* TWI1 used on Boron; also see mesh_feather_spi_spi1.dtsi */ &spi2 { /* dedicated MX25L */ compatible = "nordic,nrf-spi"; @@ -193,7 +193,7 @@ feather_i2c: &i2c0 { }; sck-pin = <19>; mosi-pin = <20>; miso-pin = <21>; - cs-gpios = <&gpio0 17 0>; + cs-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; mx25l32: mx25l3233f@0 { compatible = "jedec,spi-nor"; label = "MX25L3233F"; @@ -202,11 +202,15 @@ feather_i2c: &i2c0 { }; wp-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; hold-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; size = <0x2000000>; - has-be32k; has-dpd; t-enter-dpd = <10000>; t-exit-dpd = <100000>; jedec-id = [c2 20 16]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 01 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff + ]; }; }; diff --git a/boards/arm/particle_boron/dts/mesh_feather_spi1_spi3.dtsi b/boards/arm/particle_boron/dts/mesh_feather_spi1_spi3.dtsi index 5e66109e6e7775..7760ecbca283fc 100644 --- a/boards/arm/particle_boron/dts/mesh_feather_spi1_spi3.dtsi +++ b/boards/arm/particle_boron/dts/mesh_feather_spi1_spi3.dtsi @@ -10,6 +10,7 @@ * Changes should be made in all instances. */ &spi3 { /* feather SPI */ + compatible = "nordic,nrf-spim"; status = "okay"; sck-pin = <33>; mosi-pin = <34>; diff --git a/boards/arm/particle_boron/dts/mesh_feather_spi_spi3.dtsi b/boards/arm/particle_boron/dts/mesh_feather_spi_spi3.dtsi index 6adf2bd210c207..0c017ea4d20472 100644 --- a/boards/arm/particle_boron/dts/mesh_feather_spi_spi3.dtsi +++ b/boards/arm/particle_boron/dts/mesh_feather_spi_spi3.dtsi @@ -10,6 +10,7 @@ * Changes should be made in all instances. */ feather_spi: &spi3 { /* feather SPI */ + compatible = "nordic,nrf-spim"; status = "okay"; sck-pin = <47>; mosi-pin = <45>; diff --git a/boards/arm/particle_boron/particle_boron.dts b/boards/arm/particle_boron/particle_boron.dts index 1f3c26cff0d006..ceb94b33da78c7 100644 --- a/boards/arm/particle_boron/particle_boron.dts +++ b/boards/arm/particle_boron/particle_boron.dts @@ -40,6 +40,7 @@ rx-pin = <36>; rts-pin = <39>; cts-pin = <38>; + hw-flow-control; sara_r4 { compatible = "ublox,sara-r4"; diff --git a/boards/arm/particle_xenon/Kconfig.defconfig b/boards/arm/particle_xenon/Kconfig.defconfig index 7828f436c46ae5..760b5d06e60d24 100644 --- a/boards/arm/particle_xenon/Kconfig.defconfig +++ b/boards/arm/particle_xenon/Kconfig.defconfig @@ -19,10 +19,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default BT diff --git a/boards/arm/particle_xenon/board.c b/boards/arm/particle_xenon/board.c index 9b9246b4f80308..dc10fdcc08ced8 100644 --- a/boards/arm/particle_xenon/board.c +++ b/boards/arm/particle_xenon/board.c @@ -11,7 +11,7 @@ static inline void external_antenna(bool on) { - struct device *ufl_gpio_dev, *pcb_gpio_dev; + const struct device *ufl_gpio_dev, *pcb_gpio_dev; ufl_gpio_dev = device_get_binding(SKY_UFLn_GPIO_NAME); if (!ufl_gpio_dev) { @@ -35,7 +35,7 @@ static inline void external_antenna(bool on) : GPIO_OUTPUT_ACTIVE)); } -static int board_particle_xenon_init(struct device *dev) +static int board_particle_xenon_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/particle_xenon/board.cmake b/boards/arm/particle_xenon/board.cmake index a2fdf84849f818..c29f334e5cdc3c 100644 --- a/boards/arm/particle_xenon/board.cmake +++ b/boards/arm/particle_xenon/board.cmake @@ -5,7 +5,6 @@ # SPDX-License-Identifier: Apache-2.0 board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") -board_runner_args(nrfjprog "--nrf-family=NRF52") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/particle_xenon/dts/mesh_feather.dtsi b/boards/arm/particle_xenon/dts/mesh_feather.dtsi index 05991ec4b51df7..4ab1ee7c6c7640 100644 --- a/boards/arm/particle_xenon/dts/mesh_feather.dtsi +++ b/boards/arm/particle_xenon/dts/mesh_feather.dtsi @@ -185,7 +185,7 @@ arduino_i2c: &i2c0 { /* feather I2C */ feather_i2c: &i2c0 { }; -/* TWI1 used on Boron; also see mesh_feather_spi1_spi1.dtsi */ +/* TWI1 used on Boron; also see mesh_feather_spi_spi1.dtsi */ &spi2 { /* dedicated MX25L */ compatible = "nordic,nrf-spi"; @@ -193,7 +193,7 @@ feather_i2c: &i2c0 { }; sck-pin = <19>; mosi-pin = <20>; miso-pin = <21>; - cs-gpios = <&gpio0 17 0>; + cs-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; mx25l32: mx25l3233f@0 { compatible = "jedec,spi-nor"; label = "MX25L3233F"; @@ -202,11 +202,15 @@ feather_i2c: &i2c0 { }; wp-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; hold-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; size = <0x2000000>; - has-be32k; has-dpd; t-enter-dpd = <10000>; t-exit-dpd = <100000>; jedec-id = [c2 20 16]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 01 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff + ]; }; }; diff --git a/boards/arm/particle_xenon/dts/mesh_feather_spi1_spi3.dtsi b/boards/arm/particle_xenon/dts/mesh_feather_spi1_spi3.dtsi index 5e66109e6e7775..7760ecbca283fc 100644 --- a/boards/arm/particle_xenon/dts/mesh_feather_spi1_spi3.dtsi +++ b/boards/arm/particle_xenon/dts/mesh_feather_spi1_spi3.dtsi @@ -10,6 +10,7 @@ * Changes should be made in all instances. */ &spi3 { /* feather SPI */ + compatible = "nordic,nrf-spim"; status = "okay"; sck-pin = <33>; mosi-pin = <34>; diff --git a/boards/arm/particle_xenon/dts/mesh_feather_spi_spi1.dtsi b/boards/arm/particle_xenon/dts/mesh_feather_spi_spi1.dtsi index 8086045e2510e4..a67bf11236622d 100644 --- a/boards/arm/particle_xenon/dts/mesh_feather_spi_spi1.dtsi +++ b/boards/arm/particle_xenon/dts/mesh_feather_spi_spi1.dtsi @@ -10,6 +10,7 @@ * Changes should be made in all instances. */ feather_spi: &spi1 { /* feather SPI */ + compatible = "nordic,nrf-spim"; status = "okay"; sck-pin = <47>; mosi-pin = <45>; diff --git a/boards/arm/particle_xenon/dts/mesh_feather_spi_spi3.dtsi b/boards/arm/particle_xenon/dts/mesh_feather_spi_spi3.dtsi index 6adf2bd210c207..0c017ea4d20472 100644 --- a/boards/arm/particle_xenon/dts/mesh_feather_spi_spi3.dtsi +++ b/boards/arm/particle_xenon/dts/mesh_feather_spi_spi3.dtsi @@ -10,6 +10,7 @@ * Changes should be made in all instances. */ feather_spi: &spi3 { /* feather SPI */ + compatible = "nordic,nrf-spim"; status = "okay"; sck-pin = <47>; mosi-pin = <45>; diff --git a/boards/arm/particle_xenon/dts/mesh_feather_uart2_rtscts.dtsi b/boards/arm/particle_xenon/dts/mesh_feather_uart2_rtscts.dtsi new file mode 100644 index 00000000000000..0dfa0a648f0512 --- /dev/null +++ b/boards/arm/particle_xenon/dts/mesh_feather_uart2_rtscts.dtsi @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020 Peter Bigot Consulting, LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Add hardware flow control to UART2, which is exposed only on Xenon + * mesh boards. + */ +&uart1 { + rts-pin = <35>; + cts-pin = <43>; + /* optional mesh_feather_uart2_rtscts.dtsi */ +}; diff --git a/boards/arm/particle_xenon/particle_xenon.dts b/boards/arm/particle_xenon/particle_xenon.dts index e9ad0e2490bd20..1e82a83388231b 100644 --- a/boards/arm/particle_xenon/particle_xenon.dts +++ b/boards/arm/particle_xenon/particle_xenon.dts @@ -26,3 +26,12 @@ full-ohms = <(2100000 + 806000)>; }; }; + +&uart1 { /* feather UART2 */ + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + status = "disabled"; + tx-pin = <40>; + rx-pin = <42>; + /* optional mesh_feather_uart2_rtscts.dtsi */ +}; diff --git a/boards/arm/pico_pi_m4/pinmux.c b/boards/arm/pico_pi_m4/pinmux.c index b448408455855f..0c43e45df1b1a3 100644 --- a/boards/arm/pico_pi_m4/pinmux.c +++ b/boards/arm/pico_pi_m4/pinmux.c @@ -8,7 +8,7 @@ #include #include "device_imx.h" -static int pico_pi_m4_pinmux_init(struct device *dev) +static int pico_pi_m4_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/pinetime_devkit0/Kconfig.board b/boards/arm/pinetime_devkit0/Kconfig.board new file mode 100644 index 00000000000000..7b4cd93e7181b4 --- /dev/null +++ b/boards/arm/pinetime_devkit0/Kconfig.board @@ -0,0 +1,8 @@ +# PineTime DevKit0 board configuration + +# Copyright (c) 2020 Stephane Dorre +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PINETIME_DEVKIT0 + bool "PineTime DevKit0" + depends on SOC_NRF52832_QFAA diff --git a/boards/arm/pinetime_devkit0/Kconfig.defconfig b/boards/arm/pinetime_devkit0/Kconfig.defconfig new file mode 100644 index 00000000000000..e7748604771a45 --- /dev/null +++ b/boards/arm/pinetime_devkit0/Kconfig.defconfig @@ -0,0 +1,14 @@ +# PineTime DevKit0 board configuration + +# Copyright (c) 2020 Stephane Dorre +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_PINETIME_DEVKIT0 + +config BOARD + default "pinetime_devkit0" + +config BT_CTLR + default BT + +endif # BOARD_PINETIME_DEVKIT0 diff --git a/boards/arm/pinetime_devkit0/board.cmake b/boards/arm/pinetime_devkit0/board.cmake new file mode 100644 index 00000000000000..89ca29f0ac9940 --- /dev/null +++ b/boards/arm/pinetime_devkit0/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(pyocd "--target=nrf52") +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) diff --git a/boards/arm/pinetime_devkit0/doc/img/PineTime_DevKit0.jpg b/boards/arm/pinetime_devkit0/doc/img/PineTime_DevKit0.jpg new file mode 100644 index 00000000000000..6c5f2dcec517aa Binary files /dev/null and b/boards/arm/pinetime_devkit0/doc/img/PineTime_DevKit0.jpg differ diff --git a/boards/arm/pinetime_devkit0/doc/img/PineTime_SWD_location.jpg b/boards/arm/pinetime_devkit0/doc/img/PineTime_SWD_location.jpg new file mode 100644 index 00000000000000..bdb3a03a1bd2f3 Binary files /dev/null and b/boards/arm/pinetime_devkit0/doc/img/PineTime_SWD_location.jpg differ diff --git a/boards/arm/pinetime_devkit0/doc/img/PineTime_leaflet.jpg b/boards/arm/pinetime_devkit0/doc/img/PineTime_leaflet.jpg new file mode 100644 index 00000000000000..3b48af59a51a8f Binary files /dev/null and b/boards/arm/pinetime_devkit0/doc/img/PineTime_leaflet.jpg differ diff --git a/boards/arm/pinetime_devkit0/doc/index.rst b/boards/arm/pinetime_devkit0/doc/index.rst new file mode 100644 index 00000000000000..ce0b4560b8cced --- /dev/null +++ b/boards/arm/pinetime_devkit0/doc/index.rst @@ -0,0 +1,214 @@ +.. _pinetime_devkit0: + +Pine64 PineTime DevKit0 +####################### + +Overview +******** + +.. figure:: img/PineTime_leaflet.jpg + :width: 600px + :align: center + :alt: Pine64 PineTime + + PineTime leaflet (Credit: Pine64) + + +The Pine64 smartwatch, dubbed "PineTime", is a product of a community effort +for an open source smartwatch in collaboration with wearable RTOS and Linux +app developers/communities. + +.. figure:: img/PineTime_DevKit0.jpg + :width: 600px + :align: center + :alt: Pine64 PineTime + + PineTime Dev Kit (Credit: Pine64) + +Hardware +******** + +The PineTime is based on a Nordic NRF52832 chip and features: + +- 64 MHz Cortex-M4 with FPU +- 64KB SRAM +- 512KB on board Flash +- 1.3 inches (33mm), 240x240 pixels display with ST7789 driver +- 170-180mAh LiPo battery +- XT25F32B 32Mb (4MB) SPI NOR Flash +- CST816S Capacitive Touch +- BMA421 Triaxial Acceleration Sensor +- HRS3300 PPG Heart Rate Sensor + +PineTime Port Assignment +======================== + +See `PineTime schematics`_ ++----------------------+---------------------------------+-----------+ +| NRF52 pins | Function | Direction | ++======================+=================================+===========+ +| P0.00/XL1 | 32.768 kHz –XL1 | | ++----------------------+---------------------------------+-----------+ +| P0.01/XL2 | 32.768 kHz –XL2 | | ++----------------------+---------------------------------+-----------+ +| P0.02/AIN0 | SPI-SCK, LCD_SCK | OUT | ++----------------------+---------------------------------+-----------+ +| P0.03/AIN1 | SPI-MOSI, LCD_SDI | OUT | ++----------------------+---------------------------------+-----------+ +| P0.04/AIN2 | SPI-MISO | IN | ++----------------------+---------------------------------+-----------+ +| P0.05/AIN3 | SPI-CE# (SPI-NOR) | OUT | ++----------------------+---------------------------------+-----------+ +| P0.06 | BMA421-SDA, HRS3300-SDA, TP-SDA | I/O | ++----------------------+---------------------------------+-----------+ +| P0.07 | BMA421-SCL, HRS3300-SCL, TP-SCL | OUT | ++----------------------+---------------------------------+-----------+ +| P0.08 | BMA421-INT | IN | ++----------------------+---------------------------------+-----------+ +| P0.09/NFC1 | LCD_DET | OUT | ++----------------------+---------------------------------+-----------+ +| P0.10/NFC2 | TP_RESET | OUT | ++----------------------+---------------------------------+-----------+ +| P0.11 | | | ++----------------------+---------------------------------+-----------+ +| P0.12 | CHARGE INDICATION | IN | ++----------------------+---------------------------------+-----------+ +| P0.13 | PUSH BUTTON_IN | IN | ++----------------------+---------------------------------+-----------+ +| P0.14/TRACEDATA3 | LCD_BACKLIGHT_LOW | OUT | ++----------------------+---------------------------------+-----------+ +| P0.15/TRACEDATA2 | PUSH BUTTON_OUT | OUT | ++----------------------+---------------------------------+-----------+ +| P0.16/TRACEDATA1 | VIBRATOR OUT | OUT | ++----------------------+---------------------------------+-----------+ +| P0.17 | | | ++----------------------+---------------------------------+-----------+ +| P0.18/TRACEDATA0/SWO | LCD_RS OUT | | ++----------------------+---------------------------------+-----------+ +| P0.19 | POWER PRESENCE INDICATION | IN | ++----------------------+---------------------------------+-----------+ +| P0.20/TRACECLK | | | ++----------------------+---------------------------------+-----------+ +| P0.21/nRESET | | | ++----------------------+---------------------------------+-----------+ +| P0.22 | LCD_BACKLIGHT_MID | OUT | ++----------------------+---------------------------------+-----------+ +| P0.23 | LCD_BACKLIGHT_HIGH | OUT | ++----------------------+---------------------------------+-----------+ +| P0.24 | 3V3 POWER CONTROL | OUT | ++----------------------+---------------------------------+-----------+ +| P0.25 | LCD_CS | OUT | ++----------------------+---------------------------------+-----------+ +| P0.26 | LCD_RESET | OUT | ++----------------------+---------------------------------+-----------+ +| P0.27 | STATUS LED (NOT STAFF) | OUT | ++----------------------+---------------------------------+-----------+ +| P0.28/AIN4 | TP_INT | IN | ++----------------------+---------------------------------+-----------+ +| P0.29/AIN5 | | | ++----------------------+---------------------------------+-----------+ +| P0.30/AIN6 | HRS3300-TEST | IN | ++----------------------+---------------------------------+-----------+ +| P0.31/AIN7 | BATTERY VOLTAGE (Analog) | IN | ++----------------------+---------------------------------+-----------+ + +Building +******** + +In order to get started with Zephyr on the PineTime, you can use the +board-specific sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/pine64_pinetime + :board: pinetime_devkit0 + :goals: build + +Programming and Debugging +************************* + +The PineTime Dev Kit comes with the back not glued down to allow it to be +easily reprogrammed. + +The kit does not include a hardware programmer, but existing debuggers +supporting SWD can be used. + +These are the necessary steps for debugging: + +- Unlock the device +- Upload new software +- Run a debugger + +More infos to be found in the `Wiki Reprogramming the PineTime`_ page. + +Debugger connection +=================== + +The dev kits have exposed SWD pins for flashing and debugging. + +Only a few devs have soldered to these pins, most just use friction to make +contact with the programming cable. + +The pinout is: + +.. figure:: img/PineTime_SWD_location.jpg + :width: 300px + :align: center + :alt: PineTime SWD location + +Unlocking the Flash memory +========================== + +Unlocking the device is a one-time action that is needed to enable to debug +port and provide full access to the device. This will erase all existing +software from the internal flash. + +.. code-block:: console + + $ nrfjprog -f NRF52 --recover + +Flashing +======== + +Using nrfjprog, flashing the PineTime is done with the command: + +.. code-block:: console + + $ nrfjprog -f NRF52 --program firmware.hex --sectorerase + +Debugging +========= + +Using Segger Ozone debugger, debugging and flashing is made easy. + +Simply load the .elf file containing the final firmware and +setup the debbuger to use SWD over USB for the chip nRF52832_xxAA. +This setup can be done using the menu Tools/J-Link Settings. or by directly +typing the following in the debugger console: + +.. code-block:: console + + $ Project.SetDevice ("nRF52832_xxAA"); + $ Project.SetHostIF ("USB", ""); + $ Project.SetTargetIF ("SWD"); + $ Project.SetTIFSpeed ("4 MHz"); + $ File.Open ("path/to/your/build/zephyr/zephyr.elf"); + +References +********** + +.. target-notes:: + +.. _Pine64 PineTime presentation: + https://www.pine64.org/pinetime + +.. _Pine64 PineTime wiki page: + https://wiki.pine64.org/index.php/PineTime + +.. _Pine64 forum: + https://forum.pine64.org + +.. _PineTime schematics: + http://files.pine64.org/doc/PineTime/PineTime%20Schematic-V1.0a-20191103.pdf + +.. _Wiki Reprogramming the PineTime: + https://wiki.pine64.org/index.php/Reprogramming_the_PineTime diff --git a/boards/arm/pinetime_devkit0/pinetime-devkit0.yaml b/boards/arm/pinetime_devkit0/pinetime-devkit0.yaml new file mode 100644 index 00000000000000..245346b1db8935 --- /dev/null +++ b/boards/arm/pinetime_devkit0/pinetime-devkit0.yaml @@ -0,0 +1,10 @@ +identifier: pinetime_devkit0 +name: Pine64 PineTime DevKit0 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 64 +flash: 512 diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0.dts b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts new file mode 100644 index 00000000000000..e69df67df63647 --- /dev/null +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0.dts @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2020 Stephane Dorre + * + * SPDX-License-Identifier: Apache-2.0 + * + * DTS for Pine64 PineTime DevKit-0 board + * Further info: https://wiki.pine64.org/index.php/PineTime + * + */ + +/dts-v1/; +#include + +/ { + model = "Pine64 PineTime DevKit0"; + compatible = "pine64,pinetime-devkit0"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + aliases { + led0 = &blled0; /* backlight low */ + led1 = &blled1; /* backlight mid */ + led2 = &blled2; /* backlight high */ + led3 = &statusled; /* status led, may be not populated */ + sw0 = &key_in; /* key in */ + sw1 = &key_out; /* key out */ + }; + + leds { + compatible = "gpio-leds"; + blled0: bl_led_0 { + gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; + label = "Backlight LED 0"; + }; + blled1: bl_led_1 { + gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; + label = "Backlight LED 1"; + }; + blled2: bl_led_2 { + gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; + label = "Backlight LED 2"; + }; + statusled: led_3 { + gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; + label = "Status Led"; + }; + }; + + buttons { + compatible = "gpio-keys"; + key_in: button_0 { + gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; + label = "Key in"; + }; + key_out: button_1 { + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + label = "Key out"; + }; + }; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <115200>; + status = "okay"; + tx-pin = <11>; + rx-pin = <30>; +}; + +&i2c0 { + compatible = "nordic,nrf-twim"; + status = "okay"; + sda-pin = <6>; + scl-pin = <7>; + clock-frequency = ; /* 400KHz */ + + /* BOSCH BMA421 Triaxial Acceleration Sensor (1000KHz) */ + bma421: bma421@18 { + compatible = "bosch,bma4xx"; + reg = <0x18>; + label = "BMA421"; + int1-gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; + }; + + /* TianYiHeXin HRS3300 PPG Hear Rate Sensor (800KHz) */ + hrs3300: hrs3300@44 { + compatible = "tian-yi-he-xin,hrs3300"; + reg = <0x44>; + label = "HRS3300"; + }; + + /* Hynitron CST816S Capacitive Touch Controller (400KHz) */ + cst816s: cst816s@15 { + compatible = "hynitron,cst816s"; + reg = <0x15>; + label = "CST816S"; + irq-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + rst-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + }; +}; + +&spi1 { + compatible = "nordic,nrf-spi"; + status = "okay"; + sck-pin = <2>; + mosi-pin = <3>; + miso-pin = <4>; + + cs-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>, <&gpio0 25 GPIO_ACTIVE_LOW>; + + /* Macronix MX25L CMOS Flash Memory */ + mx25l: mx25l@0 { + compatible = "macronix,cmos-mx25l"; + reg = <0>; + spi-max-frequency = <8000000>; /* 8MHz */ + label = "CMOS MX25L"; + }; + + /* Sitronix ST7789V LCD */ + st7789v: st7789v@1 { + compatible = "sitronix,st7789v"; + reg = <1>; + spi-max-frequency = <8000000>; /* 8MHz */ + label = "ST7789V"; + cmd-data-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; /* DET */ + reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; /* RESX reset */ + width = <240>; + height = <240>; + x-offset = <0>; + y-offset = <0>; + vcom = <0x19>; + gctrl = <0x35>; + vrhs = <0x12>; + vdvs = <0x20>; + mdac = <0x00>; + gamma = <0x01>; + colmod = <0x05>; + lcm = <0x2c>; + porch-param = [0c 0c 00 33 33]; + cmd2en-param = [5a 69 02 01]; + pwctrl1-param = [a4 a1]; + pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23]; + nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23]; + ram-param = [00 F0]; + rgb-param = [CD 08 14]; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* MCUboot bootloader */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0xc000>; + }; + + /* main firmware partition */ + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0x32000>; + }; + + /* next firmware update */ + slot1_partition: partition@3e000 { + label = "image-1"; + reg = <0x0003E000 0x32000>; + }; + + /* needed to slot0-slot1 swapping */ + scratch_partition: partition@70000 { + label = "image-scratch"; + reg = <0x00070000 0xa000>; + }; + + /* to be used in firmware */ + storage_partition: partition@7a000 { + label = "storage"; + reg = <0x0007a000 0x00006000>; + }; + }; +}; diff --git a/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig new file mode 100644 index 00000000000000..35773791b59262 --- /dev/null +++ b/boards/arm/pinetime_devkit0/pinetime_devkit0_defconfig @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52832_QFAA=y +CONFIG_BOARD_PINETIME_DEVKIT0=y +CONFIG_HWINFO=y +CONFIG_HWINFO_NRF=y + +CONFIG_ARM_MPU=y + +CONFIG_GPIO=y + +CONFIG_SERIAL=y + +CONFIG_I2C=y + +CONFIG_SPI=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# use P0.09 and P0.10 as GPIOs +CONFIG_NFCT_PINS_AS_GPIOS=y + +# use P0.21 as RST +CONFIG_GPIO_AS_PINRESET=y diff --git a/boards/arm/pinnacle_100_dvk/Kconfig b/boards/arm/pinnacle_100_dvk/Kconfig new file mode 100644 index 00000000000000..c0186c068044c3 --- /dev/null +++ b/boards/arm/pinnacle_100_dvk/Kconfig @@ -0,0 +1,10 @@ +# Pinnacle(TM) 100 DVK board configuration +# +# Copyright (c) 2020 Laird Connectivity +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on BOARD_PINNACLE_100_DVK diff --git a/boards/arm/pinnacle_100_dvk/Kconfig.board b/boards/arm/pinnacle_100_dvk/Kconfig.board new file mode 100644 index 00000000000000..adbb23e41d8683 --- /dev/null +++ b/boards/arm/pinnacle_100_dvk/Kconfig.board @@ -0,0 +1,8 @@ +# Pinnacle(TM) 100 DVK board configuration +# +# Copyright (c) 2020 Laird Connectivity +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PINNACLE_100_DVK + bool "Pinnacle 100 DVK" + depends on SOC_NRF52840_QIAA diff --git a/boards/arm/pinnacle_100_dvk/Kconfig.defconfig b/boards/arm/pinnacle_100_dvk/Kconfig.defconfig new file mode 100644 index 00000000000000..90d1ee2af708db --- /dev/null +++ b/boards/arm/pinnacle_100_dvk/Kconfig.defconfig @@ -0,0 +1,31 @@ +# Pinnacle(TM) 100 DVK board configuration + +# Copyright (c) 2019 Laird Connectivity +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_PINNACLE_100_DVK + +config BOARD + default "pinnacle_100_dvk" + +config MODEM_HL7800 + default NETWORKING + +if USB + +config USB_NRFX + default y + +config USB_DEVICE_STACK + default y + +endif # USB + +config IEEE802154_NRF5 + default y + depends on IEEE802154 + +config BT_CTLR + default BT + +endif # BOARD_PINNACLE_100_DVK diff --git a/boards/arm/pinnacle_100_dvk/board.cmake b/boards/arm/pinnacle_100_dvk/board.cmake new file mode 100644 index 00000000000000..9557d63c627852 --- /dev/null +++ b/boards/arm/pinnacle_100_dvk/board.cmake @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(nrfjprog "--softreset") +board_runner_args(jlink "--device=nrf52" "--speed=4000") +board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/arm/pinnacle_100_dvk/doc/img/pinnacle_100_dvk.jpg b/boards/arm/pinnacle_100_dvk/doc/img/pinnacle_100_dvk.jpg new file mode 100644 index 00000000000000..0da7273786f6ef Binary files /dev/null and b/boards/arm/pinnacle_100_dvk/doc/img/pinnacle_100_dvk.jpg differ diff --git a/boards/arm/pinnacle_100_dvk/doc/index.rst b/boards/arm/pinnacle_100_dvk/doc/index.rst new file mode 100644 index 00000000000000..9a8ad738f191db --- /dev/null +++ b/boards/arm/pinnacle_100_dvk/doc/index.rst @@ -0,0 +1,250 @@ +.. _pinnacle_100_dvk: + +Laird Connectivity Pinnacle 100 DVK +################################### + +Overview +******** +The Pinnacle™ 100 cellular modem seamlessly incorporates a powerful Cortex M4F +controller, full Bluetooth 5 and LTE-M/NB-IoT capabilities – all with full +regulatory certifications and LTE carrier approvals. The Pinnacle 100 also +delivers complete antenna flexibility, with pre-integrated internal or external +antenna options such as the Revie Flex family of LTE and NB-IoT +internal antennas. + +Develop your application directly on the M4F controller using Zephyr RTOS to +cut BOM costs and power consumption. Take advantage of the Zephyr community, +Laird Connectivity’s sample code (cellular, Bluetooth) and hardware interfaces, +or use our hosted mode AT commands set firmware. + +Extremely power conscious, the Pinnacle 100 is ideal for battery-powered +devices operating at the edge of your IoT networks, seamlessly bridging the +cellular WAN to BLE. It’s never been easier to bridge wireless +Bluetooth 5 sensor data to cloud services like AWS IoT over a +low-power LTE connection. + +More information about the board can be found at the `Pinnacle 100 website`_. + +The Pinnacle 100 Development Kit (453-00010-K1 or 453-00011-K1) hardware +provides support for the +Nordic Semiconductor nRF52840 ARM Cortex-M4F CPU, `Sierra Wireless HL7800`_ (Altair ALT1250) +and the following devices: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UART (Universal asynchronous receiver-transmitter)` +* :abbr:`USB (Universal Serial Bus)` +* :abbr:`WDT (Watchdog Timer)` +* :abbr:`QSPI (Quad Serial Peripheral Interface)` +* :abbr:`BME680 (Bosch Sensortec BME680 environmental sensor)` +* :abbr:`HL7800 (Sierra Wireless HL7800 LTE-M1/NB-IoT modem)` + +.. figure:: img/pinnacle_100_dvk.jpg + :width: 1000px + :align: center + :alt: Pinnacle 100 DVK + + Pinnacle 100 DVK (453-00010-K1) + +Hardware +******** + +Supported Features +================== + +The Pinnacle 100 development board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth, | +| | | ieee802154 | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| USB | on-chip | usb | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ +| QSPI | on-chip | qspi/MX25R64(8MB) | ++-----------+------------+----------------------+ +| BME680 | I2C(M) | sensor/bme680 | ++-----------+------------+----------------------+ +| HL7800 | UART | HL7800 modem driver | ++-----------+------------+----------------------+ + +See `Pinnacle 100 website`_ for a complete list +of Pinnacle 100 Development Kit hardware features. + +Connections and IOs +=================== + +LED +--- + +* LED1 (blue) = P1.4 +* LED2 (green) = P1.5 +* LED3 (red) = P1.6 +* LED4 (green) = P1.7 + +Push buttons +------------ + +* BUTTON1 = SW1 = P0.31 +* BUTTON2 = SW2 = P0.3 +* BUTTON3 = SW3 = P0.4 +* BUTTON4 = SW4 = P0.2 +* NRF RESET = SW5 = reset + +Programming and Debugging +************************* + +Applications for the ``pinnacle_100_dvk`` board configuration can be +built and flashed in the usual way. (see :ref:`build_an_application` +and :ref:`application_run` for more details) + +Flashing +======== + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. Then build and flash +applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :ref:`hello_world` application. + +First, run your favorite terminal program to listen for output. + +.. note:: On the Pinnacle 100 development board, + the FTDI USB should be used to access the UART console. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the board Pinnacle 100 DVK +can be found. For example, under Linux, :code:`/dev/ttyUSB0`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: pinnacle_100_dvk + :goals: build flash + +Debugging +========= + +Refer to the :ref:`nordic_segger` page to learn about debugging Nordic boards with a +Segger IC. + +Software +******** + +Pinnacle 100 Out-of-Box Demo Software +===================================== +The Pinnacle 100 development kit ships with an out of the box software demo. +Check out the `Pinnacle 100 OOB Demo`_ source code and documentation. + +Sample Applications +=================== +`Pinnacle 100 Sample Applications`_ are available. + +Testing Bluetooth on the Pinnacle 100 DVK +========================================= +Many of the Bluetooth examples will work on the Pinnacle 100 DVK. +Try them out: + +* :ref:`ble_peripheral` +* :ref:`bluetooth-eddystone-sample` +* :ref:`bluetooth-ibeacon-sample` + +Testing the LEDs and buttons in the Pinnacle 100 DVK +==================================================== + +There are 2 samples that allow you to test that the buttons (switches) and LEDs on +the board are working properly with Zephyr: + +.. code-block:: console + + samples/basic/blinky + samples/basic/button + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in +:zephyr_file:`boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts`. + + +Overlay file naming +=================== + +The file has to be named ``.overlay`` and placed in the app main directory to be +picked up automatically by the build system. + +See :ref:`set-devicetree-overlays` for further details. + +Selecting the pins +================== +To select the pin numbers for tx-pin and rx-pin: + +.. code-block:: console + + tx-pin = + +Open the `nRF52840 Product Specification`_, chapter 7 'Hardware and Layout'. +In the table 7.1.1 'aQFN73 ball assignments' select the pins marked +'General purpose I/O'. Note that pins marked as 'low frequency I/O only' can only be used +in under-10KHz applications. They are not suitable for 115200 speed of UART. + +Translate the 'Pin' into number for devicetree by using the following formula:: + + pin_no = b\*32 + a + +where ``a`` and ``b`` are from the Pin value in the table (Pb.a). +For example, for P0.1, ``pin_no = 1`` and for P1.0, ``pin_no = 32``. + +References +********** + +.. target-notes:: + +.. _Pinnacle 100 website: https://www.lairdconnect.com/wireless-modules/cellular-solutions/pinnacle-100-cellular-modem +.. _nRF52840 Product Specification: https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.1.pdf +.. _Sierra Wireless HL7800: https://source.sierrawireless.com/devices/hl-series/hl7800/#sthash.641qTTwA.dpbs +.. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html +.. _Pinnacle 100 OOB Demo: https://github.com/LairdCP/Pinnacle_100_oob_demo +.. _Pinnacle 100 Sample Applications: https://github.com/LairdCP/Pinnacle_100_Sample_Applications diff --git a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts new file mode 100644 index 00000000000000..b3f9b45fbcf2db --- /dev/null +++ b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.dts @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2019 Laird Connectivity + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Pinnacle 100 Dev Kit"; + compatible = "lairdconnect,pinnacle-100-dvk"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + leds { + compatible = "gpio-leds"; + led1: led_1 { + gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + label = "Blue LED 1"; + }; + led2: led_2 { + gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + led3: led_3 { + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + label = "Red LED 3"; + }; + led4: led_4 { + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + label = "Green LED 4"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button1: button_1 { + gpios = <&gpio0 31 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + }; + button2: button_2 { + gpios = <&gpio0 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + }; + button3: button_3 { + gpios = <&gpio0 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 3"; + }; + button4: button_4 { + gpios = <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 4"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + led2 = &led3; + led3 = &led4; + sw0 = &button1; + sw1 = &button2; + sw2 = &button3; + sw3 = &button4; + }; +}; + +&adc { + status ="okay"; +}; + +&gpiote { + status ="okay"; +}; + +&gpio0 { + status ="okay"; +}; + +&gpio1 { + status ="okay"; +}; + +&uart0 { + compatible = "nordic,nrf-uart"; + status = "okay"; + current-speed = <115200>; + tx-pin = <6>; + rx-pin = <8>; + rts-pin = <5>; + cts-pin = <7>; +}; + +&uart1 { + compatible = "nordic,nrf-uarte"; + status = "okay"; + current-speed = <115200>; + tx-pin = <14>; + rx-pin = <16>; + rts-pin = <13>; + cts-pin = <15>; + hl7800 { + compatible = "swir,hl7800"; + status = "okay"; + label = "hl7800"; + mdm-reset-gpios = <&gpio1 15 0>; + mdm-wake-gpios = <&gpio1 13 0>; + mdm-pwr-on-gpios = <&gpio1 2 0>; + mdm-fast-shutd-gpios = <&gpio1 14 0>; + mdm-uart-dtr-gpios = <&gpio0 24 0>; + mdm-vgpio-gpios = <&gpio1 11 0>; + mdm-uart-dsr-gpios = <&gpio0 25 0>; + mdm-uart-cts-gpios = <&gpio0 15 0>; + mdm-gpio6-gpios = <&gpio1 12 0>; + }; +}; + +&i2c0 { + compatible = "nordic,nrf-twi"; + status = "okay"; + sda-pin = <26>; + scl-pin = <27>; + + bme680@76 { + compatible = "bosch,bme680"; + status = "okay"; + label = "BME680"; + reg = <0x76>; + }; +}; + +&spi0 { + compatible = "nordic,nrf-spi"; + /* Cannot be used together with i2c0. */ + /* status = "okay"; */ + sck-pin = <27>; + mosi-pin = <26>; + miso-pin = <29>; +}; + +&spi1 { + compatible = "nordic,nrf-spi"; + status = "okay"; + sck-pin = <11>; + mosi-pin = <32>; + miso-pin = <12>; +}; + +&qspi { + status = "okay"; + sck-pin = <19>; + io-pins = <20>, <21>, <22>, <23>; + csn-pins = <17>; + mx25r64: mx25r6435f@0 { + compatible = "nordic,qspi-nor"; + reg = <0>; + writeoc = "pp4io"; + readoc = "read4io"; + sck-frequency = <8000000>; + label = "MX25R64"; + jedec-id = [c2 28 17]; + size = <67108864>; + has-be32k; + has-dpd; + t-enter-dpd = <10000>; + t-exit-dpd = <35000>; + }; +}; + +&flash0 { + /* + * For more information, see: + * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* 96K */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x000000000 0x00018000>; + }; + /* 896K */ + slot0_partition: partition@18000 { + label = "image-0"; + reg = <0x00018000 0x000E0000>; + }; + + /* + * The flash starting at 0x000f8000 and ending at + * 0x000fffff is reserved for use by the application. + */ + + /* + * Storage partition will be used by FCB/NVS + * if enabled. 32K + */ + storage_partition: partition@f8000 { + label = "storage"; + reg = <0x000f8000 0x00008000>; + }; + }; +}; + +&mx25r64 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* 896K */ + slot1_partition: partition@0 { + label = "image-1"; + reg = <0x0000000 0x000E0000>; + }; + /* 128K */ + scratch_partition: partition@E0000 { + label = "image-scratch"; + reg = <0x000E0000 0x00020000>; + }; + /* 7MB */ + lfs_partition: partition@100000 { + label = "lfs_storage"; + reg = <0x00100000 0x000700000>; + }; + }; +}; + +&usbd { + compatible = "nordic,nrf-usbd"; + status = "okay"; +}; diff --git a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.yaml b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.yaml new file mode 100644 index 00000000000000..3a2cf2a11a90e8 --- /dev/null +++ b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk.yaml @@ -0,0 +1,23 @@ +identifier: pinnacle_100_dvk +name: pinnacle-100-dvk +type: mcu +arch: arm +ram: 256 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - ble + - counter + - gpio + - i2c + - ieee802154 + - pwm + - spi + - usb_cdc + - usb_device + - watchdog + - netif:modem diff --git a/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig new file mode 100644 index 00000000000000..c236401132955d --- /dev/null +++ b/boards/arm/pinnacle_100_dvk/pinnacle_100_dvk_defconfig @@ -0,0 +1,26 @@ +# Copyright (c) 2020 Laird Connectivity + +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_PINNACLE_100_DVK=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable RTT +CONFIG_USE_SEGGER_RTT=y + +# enable GPIO +CONFIG_GPIO=y + +# enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# additional board options +CONFIG_GPIO_AS_PINRESET=y diff --git a/boards/arm/qemu_cortex_a53/board.cmake b/boards/arm/qemu_cortex_a53/board.cmake index 87e760189effe5..02f349c82bfafe 100644 --- a/boards/arm/qemu_cortex_a53/board.cmake +++ b/boards/arm/qemu_cortex_a53/board.cmake @@ -8,10 +8,6 @@ set(QEMU_CPU_TYPE_${ARCH} cortex-a53) set(QEMU_FLAGS_${ARCH} -cpu ${QEMU_CPU_TYPE_${ARCH}} -nographic - -machine virt + -machine virt,secure=on,gic-version=3 ) - -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=4,align=off,sleep=off -rtc clock=vm) -endif() board_set_debugger_ifnset(qemu) diff --git a/boards/arm/qemu_cortex_a53/qemu_cortex_a53.dts b/boards/arm/qemu_cortex_a53/qemu_cortex_a53.dts index 43d84f942317a7..ee7358df6a8225 100644 --- a/boards/arm/qemu_cortex_a53/qemu_cortex_a53.dts +++ b/boards/arm/qemu_cortex_a53/qemu_cortex_a53.dts @@ -13,6 +13,7 @@ compatible = "qemu,arm-cortex-a53"; chosen { + zephyr,sram = &sram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/arm/qemu_cortex_a53/qemu_cortex_a53.yaml b/boards/arm/qemu_cortex_a53/qemu_cortex_a53.yaml index 2a9c6be454af6e..b82675797e1882 100644 --- a/boards/arm/qemu_cortex_a53/qemu_cortex_a53.yaml +++ b/boards/arm/qemu_cortex_a53/qemu_cortex_a53.yaml @@ -9,3 +9,6 @@ toolchain: ram: 128 testing: default: true + ignore_tags: + - net + - bluetooth diff --git a/boards/arm/qemu_cortex_a53/qemu_cortex_a53_defconfig b/boards/arm/qemu_cortex_a53/qemu_cortex_a53_defconfig index 564ca87c73b10a..f37de02c00434b 100644 --- a/boards/arm/qemu_cortex_a53/qemu_cortex_a53_defconfig +++ b/boards/arm/qemu_cortex_a53/qemu_cortex_a53_defconfig @@ -2,10 +2,7 @@ CONFIG_SOC_QEMU_CORTEX_A53=y CONFIG_BOARD_QEMU_CORTEX_A53=y CONFIG_ARM_ARCH_TIMER=y CONFIG_XIP=n - -# QEMU settings -CONFIG_SRAM_BASE_ADDRESS=0x40000000 -CONFIG_SRAM_SIZE=131072 +CONFIG_QEMU_ICOUNT_SHIFT=4 # Enable UART driver CONFIG_SERIAL=y diff --git a/boards/arm/qemu_cortex_m0/CMakeLists.txt b/boards/arm/qemu_cortex_m0/CMakeLists.txt index d5670359eda1cf..3381afa71dc5dc 100644 --- a/boards/arm/qemu_cortex_m0/CMakeLists.txt +++ b/boards/arm/qemu_cortex_m0/CMakeLists.txt @@ -4,4 +4,4 @@ # SPDX-License-Identifier: Apache-2.0 # -zephyr_sources_if_kconfig( nrf_timer_timer.c) +zephyr_sources_ifdef(CONFIG_NRF_TIMER_TIMER nrf_timer_timer.c) diff --git a/boards/arm/qemu_cortex_m0/Kconfig.defconfig b/boards/arm/qemu_cortex_m0/Kconfig.defconfig index 033f5405515eac..58eff6fa4bfd95 100644 --- a/boards/arm/qemu_cortex_m0/Kconfig.defconfig +++ b/boards/arm/qemu_cortex_m0/Kconfig.defconfig @@ -32,9 +32,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config SYS_CLOCK_TICKS_PER_SEC default 100 -config ENTROPY_NRF_FORCE_ALT - default y - config LOG_BUFFER_SIZE default 128 if LOG diff --git a/boards/arm/qemu_cortex_m0/board.cmake b/boards/arm/qemu_cortex_m0/board.cmake index 974d4b698581d1..8543b74f7966e1 100644 --- a/boards/arm/qemu_cortex_m0/board.cmake +++ b/boards/arm/qemu_cortex_m0/board.cmake @@ -12,8 +12,4 @@ set(QEMU_FLAGS_${ARCH} -nographic -vga none ) - -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=6,align=off,sleep=off -rtc clock=vm) -endif() board_set_debugger_ifnset(qemu) diff --git a/boards/arm/qemu_cortex_m0/nrf_timer_timer.c b/boards/arm/qemu_cortex_m0/nrf_timer_timer.c index e654a28119f3ed..25d642578bcf0e 100644 --- a/boards/arm/qemu_cortex_m0/nrf_timer_timer.c +++ b/boards/arm/qemu_cortex_m0/nrf_timer_timer.c @@ -15,80 +15,158 @@ #define TIMER NRF_TIMER0 -#define COUNTER_MAX 0xffffffff +#define COUNTER_MAX 0xFFFFFFFFUL +#define COUNTER_HALF_SPAN 0x80000000UL #define CYC_PER_TICK (sys_clock_hw_cycles_per_sec() \ / CONFIG_SYS_CLOCK_TICKS_PER_SEC) -#define MAX_TICKS ((COUNTER_MAX - CYC_PER_TICK) / CYC_PER_TICK) +#define MAX_TICKS ((COUNTER_HALF_SPAN - CYC_PER_TICK) / CYC_PER_TICK) +#define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK) static struct k_spinlock lock; -static u32_t last_count; +static uint32_t last_count; -static u32_t counter_sub(u32_t a, u32_t b) +static uint32_t counter_sub(uint32_t a, uint32_t b) { return (a - b) & COUNTER_MAX; } -static void set_comparator(u32_t cyc) +static void set_comparator(uint32_t cyc) { - nrf_timer_cc_set(TIMER, 0, cyc & COUNTER_MAX); + nrf_timer_cc_set(TIMER, NRF_TIMER_CC_CHANNEL0, cyc & COUNTER_MAX); } -static u32_t counter(void) +static uint32_t get_comparator(void) { - nrf_timer_task_trigger(TIMER, nrf_timer_capture_task_get(1)); + return nrf_timer_cc_get(TIMER, NRF_TIMER_CC_CHANNEL0); +} - return nrf_timer_cc_get(TIMER, 1); +static void event_clear(void) +{ + nrf_timer_event_clear(TIMER, NRF_TIMER_EVENT_COMPARE0); } -void timer0_nrf_isr(void *arg) +static void int_disable(void) { - ARG_UNUSED(arg); - TIMER->EVENTS_COMPARE[0] = 0; + nrf_timer_int_disable(TIMER, NRF_TIMER_INT_COMPARE0_MASK); +} - k_spinlock_key_t key = k_spin_lock(&lock); - u32_t t = counter(); - u32_t dticks = counter_sub(t, last_count) / CYC_PER_TICK; +static void int_enable(void) +{ + nrf_timer_int_enable(TIMER, NRF_TIMER_INT_COMPARE0_MASK); +} - last_count += dticks * CYC_PER_TICK; +static uint32_t counter(void) +{ + nrf_timer_task_trigger(TIMER, + nrf_timer_capture_task_get(NRF_TIMER_CC_CHANNEL1)); - if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { - u32_t next = last_count + CYC_PER_TICK; + return nrf_timer_cc_get(TIMER, NRF_TIMER_CC_CHANNEL1); +} + +/* Function ensures that previous CC value will not set event */ +static void prevent_false_prev_evt(void) +{ + uint32_t now = counter(); + uint32_t prev_val; + + /* First take care of a risk of an event coming from CC being set to + * next tick. Reconfigure CC to future (now tick is the furtherest + * future). If CC was set to next tick we need to wait for up to 0.5us + * (half of 1M tick) and clean potential event. After that time there + * is no risk of unwanted event. + */ + prev_val = get_comparator(); + event_clear(); + set_comparator(now); + + if (counter_sub(prev_val, now) == 1) { + k_busy_wait(1); + event_clear(); + } - /* As below: we're guaranteed to get an interrupt as - * long as it's set two or more cycles in the future + /* Clear interrupt that may have fired as we were setting the + * comparator. + */ + NVIC_ClearPendingIRQ(TIMER0_IRQn); +} + +/* If settings is next tick from now, function attempts to set next tick. If + * counter progresses during that time it means that 1 tick elapsed and + * interrupt is set pending. + */ +static void handle_next_tick_case(uint32_t t) +{ + set_comparator(t + 2U); + while (t != counter()) { + /* already expired, tick elapsed but event might not be + * generated. Trigger interrupt. */ - if (counter_sub(next, t) < 3) { - next += CYC_PER_TICK; - } - set_comparator(next); + t = counter(); + set_comparator(t + 2U); } +} - k_spin_unlock(&lock, key); - z_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1); +/* Function safely sets absolute alarm. It assumes that provided value is + * less than MAX_TICKS from now. It detects late setting and also handles + * +1 tick case. + */ +static void set_absolute_ticks(uint32_t abs_val) +{ + uint32_t diff; + uint32_t t = counter(); + + diff = counter_sub(abs_val, t); + if (diff == 1U) { + handle_next_tick_case(t); + return; + } + + set_comparator(abs_val); } -int z_clock_driver_init(struct device *device) +/* Sets relative ticks alarm from any context. Function is lockless. It only + * blocks TIMER interrupt. + */ +static void set_protected_absolute_ticks(uint32_t ticks) { - struct device *clock; + int_disable(); - ARG_UNUSED(device); + prevent_false_prev_evt(); + + set_absolute_ticks(ticks); + + int_enable(); +} - clock = device_get_binding(DT_LABEL(DT_INST(0, nordic_nrf_clock))); - if (!clock) { - return -1; +void timer0_nrf_isr(void *arg) +{ + ARG_UNUSED(arg); + event_clear(); + + + uint32_t t = get_comparator(); + uint32_t dticks = counter_sub(t, last_count) / CYC_PER_TICK; + + last_count += dticks * CYC_PER_TICK; + + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + /* protection is not needed because we are in the TIMER interrupt + * so it won't get preempted by the interrupt. + */ + set_absolute_ticks(last_count + CYC_PER_TICK); } - clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF); + z_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : (dticks > 0)); +} - nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_1MHz); - nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32); - nrf_timer_cc_set(TIMER, 0, CYC_PER_TICK); - nrf_timer_int_enable(TIMER, TIMER_INTENSET_COMPARE0_Msk); +int z_clock_driver_init(const struct device *device) +{ + ARG_UNUSED(device); - /* Clear the event flag and possible pending interrupt */ - nrf_timer_event_clear(TIMER, NRF_TIMER_EVENT_COMPARE0); - NVIC_ClearPendingIRQ(TIMER0_IRQn); + /* FIXME switch to 1 MHz once this is fixed in QEMU */ + nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_2MHz); + nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32); IRQ_CONNECT(TIMER0_IRQn, 1, timer0_nrf_isr, 0, 0); irq_enable(TIMER0_IRQn); @@ -100,87 +178,79 @@ int z_clock_driver_init(struct device *device) set_comparator(counter() + CYC_PER_TICK); } + event_clear(); + NVIC_ClearPendingIRQ(TIMER0_IRQn); + int_enable(); + return 0; } -void z_clock_set_timeout(s32_t ticks, bool idle) +void z_clock_set_timeout(int32_t ticks, bool idle) { ARG_UNUSED(idle); + uint32_t cyc; + + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + return; + } -#ifdef CONFIG_TICKLESS_KERNEL ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks; - ticks = MAX(MIN(ticks - 1, (s32_t)MAX_TICKS), 0); + ticks = CLAMP(ticks - 1, 0, (int32_t)MAX_TICKS); + + uint32_t unannounced = counter_sub(counter(), last_count); + + /* If we haven't announced for more than half the 24-bit wrap + * duration, then force an announce to avoid loss of a wrap + * event. This can happen if new timeouts keep being set + * before the existing one triggers the interrupt. + */ + if (unannounced >= COUNTER_HALF_SPAN) { + ticks = 0; + } - k_spinlock_key_t key = k_spin_lock(&lock); - u32_t cyc, dt, t = counter(); - bool zli_fixup = IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS); - /* Round up to next tick boundary */ - cyc = ticks * CYC_PER_TICK + 1 + counter_sub(t, last_count); + /* Get the cycles from last_count to the tick boundary after + * the requested ticks have passed starting now. + */ + cyc = ticks * CYC_PER_TICK + 1 + unannounced; cyc += (CYC_PER_TICK - 1); cyc = (cyc / CYC_PER_TICK) * CYC_PER_TICK; - cyc += last_count; - if (counter_sub(cyc, t) > 2) { - set_comparator(cyc); - } else { - set_comparator(cyc); - dt = counter_sub(cyc, counter()); - if (dt == 0 || dt > 0x7fffff) { - /* Missed it! */ - NVIC_SetPendingIRQ(TIMER0_IRQn); - if (IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS)) { - zli_fixup = false; - } - } else if (dt == 1) { - /* Too soon, interrupt won't arrive. */ - set_comparator(cyc + 2); - } - /* Otherwise it was two cycles out, we're fine */ - } - -#ifdef CONFIG_ZERO_LATENCY_IRQS - /* Failsafe. ZLIs can preempt us even though interrupts are - * masked, blowing up the sensitive timing above. If the - * feature is enabled and we haven't recorded the presence of - * a pending interrupt then we need a final check (in a loop! - * because this too can be interrupted) to confirm that the - * comparator is still in the future. Don't bother being - * fancy with cycle counting here, just set an interrupt - * "soon" that we know will get the timer back to a known - * state. This handles (via some hairy modular expressions) - * the wraparound cases where we are preempted for as much as - * half the counter space. + /* Due to elapsed time the calculation above might produce a + * duration that laps the counter. Don't let it. */ - if (zli_fixup && counter_sub(cyc, counter()) <= 0x7fffff) { - while (counter_sub(cyc, counter() + 2) > 0x7fffff) { - cyc = counter() + 3; - set_comparator(cyc); - } + if (cyc > MAX_CYCLES) { + cyc = MAX_CYCLES; } -#endif - k_spin_unlock(&lock, key); -#endif /* CONFIG_TICKLESS_KERNEL */ + cyc += last_count; + set_protected_absolute_ticks(cyc); + + /* FIXME - QEMU requires clearing the events when setting the comparator, + * but the TIMER peripheral HW does not need this. Remove when fixed in + * QEMU. + */ + event_clear(); + NVIC_ClearPendingIRQ(TIMER0_IRQn); } -u32_t z_clock_elapsed(void) +uint32_t z_clock_elapsed(void) { if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { return 0; } k_spinlock_key_t key = k_spin_lock(&lock); - u32_t ret = counter_sub(counter(), last_count) / CYC_PER_TICK; + uint32_t ret = counter_sub(counter(), last_count) / CYC_PER_TICK; k_spin_unlock(&lock, key); return ret; } -u32_t z_timer_cycle_get_32(void) +uint32_t z_timer_cycle_get_32(void) { k_spinlock_key_t key = k_spin_lock(&lock); - u32_t ret = counter_sub(counter(), last_count) + last_count; + uint32_t ret = counter_sub(counter(), last_count) + last_count; k_spin_unlock(&lock, key); return ret; diff --git a/boards/arm/qemu_cortex_m0/qemu_cortex_m0.dts b/boards/arm/qemu_cortex_m0/qemu_cortex_m0.dts index a1b3044275f6fd..7f201729531d6c 100644 --- a/boards/arm/qemu_cortex_m0/qemu_cortex_m0.dts +++ b/boards/arm/qemu_cortex_m0/qemu_cortex_m0.dts @@ -39,10 +39,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/qemu_cortex_m0/qemu_cortex_m0_defconfig b/boards/arm/qemu_cortex_m0/qemu_cortex_m0_defconfig index 269d195c6aa813..528560cc01e9e8 100644 --- a/boards/arm/qemu_cortex_m0/qemu_cortex_m0_defconfig +++ b/boards/arm/qemu_cortex_m0/qemu_cortex_m0_defconfig @@ -3,6 +3,7 @@ CONFIG_SOC_SERIES_NRF51X=y CONFIG_SOC_NRF51822_QFAA=y CONFIG_BOARD_QEMU_CORTEX_M0=y +CONFIG_QEMU_ICOUNT_SHIFT=6 # enable GPIO CONFIG_GPIO=y diff --git a/boards/arm/qemu_cortex_m3/board.cmake b/boards/arm/qemu_cortex_m3/board.cmake index 2e24740e033e67..fcb7956d10a0d9 100644 --- a/boards/arm/qemu_cortex_m3/board.cmake +++ b/boards/arm/qemu_cortex_m3/board.cmake @@ -9,8 +9,4 @@ set(QEMU_FLAGS_${ARCH} -nographic -vga none ) - -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=6,align=off,sleep=off -rtc clock=vm) -endif() board_set_debugger_ifnset(qemu) diff --git a/boards/arm/qemu_cortex_m3/qemu_cortex_m3_defconfig b/boards/arm/qemu_cortex_m3/qemu_cortex_m3_defconfig index 27481c6cb34763..fffd328a99cce8 100644 --- a/boards/arm/qemu_cortex_m3/qemu_cortex_m3_defconfig +++ b/boards/arm/qemu_cortex_m3/qemu_cortex_m3_defconfig @@ -9,3 +9,4 @@ CONFIG_SERIAL=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_UART_STELLARIS=y CONFIG_SCHED_MULTIQ=y +CONFIG_QEMU_ICOUNT_SHIFT=6 diff --git a/boards/arm/qemu_cortex_r5/board.cmake b/boards/arm/qemu_cortex_r5/board.cmake index 74c2d91f1a4b0e..92ead46b5ca37a 100644 --- a/boards/arm/qemu_cortex_r5/board.cmake +++ b/boards/arm/qemu_cortex_r5/board.cmake @@ -12,10 +12,6 @@ set(QEMU_FLAGS_${ARCH} -dtb ${ZEPHYR_BASE}/boards/${ARCH}/${BOARD}/fdt-single_arch-zcu102-arm.dtb ) -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=3,align=off,sleep=off -rtc clock=vm) -endif() - set(QEMU_KERNEL_OPTION "-device;loader,file=\$,cpu-num=4" "-device;loader,addr=0xff5e023c,data=0x80008fde,data-len=4" diff --git a/boards/arm/qemu_cortex_r5/qemu_cortex_r5.dts b/boards/arm/qemu_cortex_r5/qemu_cortex_r5.dts index 577da3ce4fbc86..c5843ea1bc325c 100644 --- a/boards/arm/qemu_cortex_r5/qemu_cortex_r5.dts +++ b/boards/arm/qemu_cortex_r5/qemu_cortex_r5.dts @@ -28,5 +28,5 @@ &ttc0 { status = "okay"; - clock-frequency = <12000000>; + clock-frequency = <5000000>; }; diff --git a/boards/arm/qemu_cortex_r5/qemu_cortex_r5_defconfig b/boards/arm/qemu_cortex_r5/qemu_cortex_r5_defconfig index f7efc7296edeaf..2d02b2c9254fd0 100644 --- a/boards/arm/qemu_cortex_r5/qemu_cortex_r5_defconfig +++ b/boards/arm/qemu_cortex_r5/qemu_cortex_r5_defconfig @@ -1,6 +1,7 @@ CONFIG_SOC_XILINX_ZYNQMP_RPU=y CONFIG_BOARD_QEMU_CORTEX_R5=y CONFIG_XIP=n +CONFIG_QEMU_ICOUNT_SHIFT=3 CONFIG_ISR_STACK_SIZE=512 CONFIG_THREAD_STACK_INFO=y @@ -15,4 +16,4 @@ CONFIG_UART_CONSOLE=y # enable serial port CONFIG_UART_XLNX_PS=y -CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 diff --git a/boards/arm/quick_feather/CMakeLists.txt b/boards/arm/quick_feather/CMakeLists.txt new file mode 100644 index 00000000000000..907a7cd5b581ef --- /dev/null +++ b/boards/arm/quick_feather/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2020 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) +zephyr_library_sources(board.c) +zephyr_include_directories(.) diff --git a/boards/arm/quick_feather/Kconfig b/boards/arm/quick_feather/Kconfig new file mode 100644 index 00000000000000..c06e73df40a73a --- /dev/null +++ b/boards/arm/quick_feather/Kconfig @@ -0,0 +1,10 @@ +# Quick Feather board + +# Copyright (c) 2020 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_INIT_PRIORITY + int + default KERNEL_INIT_PRIORITY_DEFAULT + help + Board initialization priority. diff --git a/boards/arm/quick_feather/Kconfig.board b/boards/arm/quick_feather/Kconfig.board new file mode 100644 index 00000000000000..e85b49bc4e48ad --- /dev/null +++ b/boards/arm/quick_feather/Kconfig.board @@ -0,0 +1,8 @@ +# Quick Feather board + +# Copyright (c) 2020 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_QUICK_FEATHER + bool "QuickLogic Quick Feather target" + depends on SOC_EOS_S3 diff --git a/boards/arm/quick_feather/Kconfig.defconfig b/boards/arm/quick_feather/Kconfig.defconfig new file mode 100644 index 00000000000000..cf328e50b1b3ea --- /dev/null +++ b/boards/arm/quick_feather/Kconfig.defconfig @@ -0,0 +1,11 @@ +# QuickLogic Quick Feather board + +# Copyright (c) 2020 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_QUICK_FEATHER + +config BOARD + default "quick_feather" + +endif # BOARD_QUICK_FEATHER diff --git a/boards/arm/quick_feather/board.c b/boards/arm/quick_feather/board.c new file mode 100644 index 00000000000000..3a729aa66be9ec --- /dev/null +++ b/boards/arm/quick_feather/board.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static int eos_s3_board_init(const struct device *arg) +{ + ARG_UNUSED(arg); + + /* IO MUX setup for UART */ + eos_s3_io_mux(UART_TX_PAD, UART_TX_PAD_CFG); + eos_s3_io_mux(UART_RX_PAD, UART_RX_PAD_CFG); + + IO_MUX->UART_rxd_SEL = UART_RX_SEL; + + return 0; +} + +SYS_INIT(eos_s3_board_init, PRE_KERNEL_1, CONFIG_BOARD_INIT_PRIORITY); diff --git a/boards/arm/quick_feather/board.h b/boards/arm/quick_feather/board.h new file mode 100644 index 00000000000000..857a6edd037270 --- /dev/null +++ b/boards/arm/quick_feather/board.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INC_BOARD_H +#define __INC_BOARD_H + +#include + +#define UART_TX_PAD 44 +#define UART_TX_PAD_CFG UART_TXD_PAD44 +#define UART_RX_PAD 45 +#define UART_RX_PAD_CFG UART_RXD_PAD45 + +#define UART_RX_SEL UART_RXD_SEL_PAD45 + +#endif /* __INC_BOARD_H */ diff --git a/boards/arm/quick_feather/quick_feather.dts b/boards/arm/quick_feather/quick_feather.dts new file mode 100644 index 00000000000000..d393fc62e2e342 --- /dev/null +++ b/boards/arm/quick_feather/quick_feather.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "QuickLogic Quick Feather board"; + compatible = "quicklogic,eos_s3"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-pipe = &uart0; + }; + +}; + +&cpu0 { + clock-frequency = <61440000>; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/arm/quick_feather/quick_feather.yaml b/boards/arm/quick_feather/quick_feather.yaml new file mode 100644 index 00000000000000..7f92a190b6420a --- /dev/null +++ b/boards/arm/quick_feather/quick_feather.yaml @@ -0,0 +1,12 @@ +identifier: quick_feather +name: QuickLogic Quick Feather +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/arm/quick_feather/quick_feather_defconfig b/boards/arm/quick_feather/quick_feather_defconfig new file mode 100644 index 00000000000000..360c5fee9ef384 --- /dev/null +++ b/boards/arm/quick_feather/quick_feather_defconfig @@ -0,0 +1,28 @@ +# Copyright (c) 2020 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=n +CONFIG_SOC_EOS_S3=y +CONFIG_BOARD_QUICK_FEATHER=y + +# system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=61440000 +CONFIG_CORTEX_M_SYSTICK=y + +# console +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_PRINTK=y +CONFIG_UART_CONSOLE=y + +# misc +CONFIG_BOOT_BANNER=y + +# EOS S3 Configuartion Manager copies software from external flash to MCU +# memory using preconfigured DMA and execute it there. +# Thus we do not use flash directly. + +CONFIG_XIP=n +CONFIG_FLASH=n +CONFIG_FLASH_SIZE=0 +CONFIG_FLASH_BASE_ADDRESS=0x0 diff --git a/boards/arm/rak5010_nrf52840/Kconfig.board b/boards/arm/rak5010_nrf52840/Kconfig.board new file mode 100644 index 00000000000000..c5a5ab2d3a1e30 --- /dev/null +++ b/boards/arm/rak5010_nrf52840/Kconfig.board @@ -0,0 +1,8 @@ +# RAKWIRELESS RAK5010 selection + +# Copyright (c) 2020 Guillaume Paquet +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RAK5010_NRF52840 + bool "RAK5010 DK NRF52840" + depends on SOC_NRF52840_QIAA diff --git a/boards/arm/rak5010_nrf52840/Kconfig.defconfig b/boards/arm/rak5010_nrf52840/Kconfig.defconfig new file mode 100644 index 00000000000000..f640e81927e109 --- /dev/null +++ b/boards/arm/rak5010_nrf52840/Kconfig.defconfig @@ -0,0 +1,24 @@ +# RAKWIRELESS RAK5010 Board configuration + +# Copyright (c) 2020 Guillaume Paquet +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RAK5010_NRF52840 + +config BOARD + default "rak5010_nrf52840" + +if USB + +config USB_NRFX + default y + +config USB_DEVICE_STACK + default y + +endif # USB + +config BT_CTLR + default BT + +endif # BOARD_RAK5010_NRF52840 diff --git a/boards/arm/rak5010_nrf52840/board.cmake b/boards/arm/rak5010_nrf52840/board.cmake new file mode 100644 index 00000000000000..13dac038711be9 --- /dev/null +++ b/boards/arm/rak5010_nrf52840/board.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2020 Guillaume Paquet +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(nrfjprog "--nrf-family=NRF52") +board_runner_args(jlink "--device=nrf52" "--speed=4000") +board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/boards/arm/rak5010_nrf52840/doc/img/rak5010-front-parts.jpeg b/boards/arm/rak5010_nrf52840/doc/img/rak5010-front-parts.jpeg new file mode 100644 index 00000000000000..62b7e283ebe019 Binary files /dev/null and b/boards/arm/rak5010_nrf52840/doc/img/rak5010-front-parts.jpeg differ diff --git a/boards/arm/rak5010_nrf52840/doc/index.rst b/boards/arm/rak5010_nrf52840/doc/index.rst new file mode 100644 index 00000000000000..3ceccc1db9a858 --- /dev/null +++ b/boards/arm/rak5010_nrf52840/doc/index.rst @@ -0,0 +1,160 @@ +.. _rak5010_nrf52840: + +RAK5010 +####### + +Overview +******** + +WisTrio NB-IoT Tracker Pro (RAK5010) is a tracker +with integrated LTE CAT M1 & NB1, GPS, BLE, and sensors. +It is built on the Quectel BG96 LTE CAT M1 & NB1 module, +which has an integrated GPS receiver. The MCU running +the board is a Nordic nRF52840 controller. + +As it has both GPS and BLE it can be used for outdoor +and indoor scenarios, where location-based services need be present. + +The built-in sensors for RAK5010 are temperature and +humidity sensor, motion sensor, pressure sensor, and light sensor. +The extension IOs allow adding more sensors in addition to the on-board ones. + +This board is particularly suitable to be used as a +quick testing and prototyping tool for applications +requiring NB-IoT connectivity. Application development +supports the GCC environment. + +.. image:: img/rak5010-front-parts.jpeg + :width: 500px + :align: center + :alt: RAK5010-NRF52840 + +Hardware +******** + +- nRF52840 ARM Cortex-M4F Processor +- 32.768 kHz crystal oscillator +- 1 Micro-AB USB OTG host/device +- Quectel BG96, with LTE CAT M1, LTE NB1, and GNSS +- iPEX connectors for the LTE and GPS antenna and an on-board ceramic antenna for the BLE. +- nano-SIM and ESIM options. +- Multiple interfaces, I2C, UART, GPIO, ADC +- 1 user LED +- 1 SHTC3 Humidity and Temperature Sensor +- 1 OPT3001DNPR Ambient Light Sensor +- 1 LPS22HB Pressure Sensor +- 1 LIS3DH Motion Sensor +- Powered by either Micro USB, 3.7V rechargeable battery or a 5V Solar Panel Port + +Supported Features +================== + +The rak5010_nrf52840 board configuration supports the following hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth, | +| | | ieee802154 | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| USB | on-chip | usb | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Other hardware features are not supported by the Zephyr kernel. + +Connections and IOs +=================== + +LED +--- + +* LED0 (green) = P0.12 + + +Programming and Debugging +************************* + +The RAK5010 board shall be connected to a Segger Embedded Debugger Unit +`J-Link OB `_. This provides a debug +interface to the NRF52840 chip. You can use JLink to communicate with +the NRF52840. + +Flashing +======== + +#. Download JLink from the Segger `JLink Downloads Page`_. Go to the section + "J-Link Software and Documentation Pack" and install the "J-Link Software + and Documentation pack for Linux". The application JLinkExe needs to be + accessible from your path. + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyACM0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyACM0 -o + + The -o option tells minicom not to send the modem initialization string. + Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + +#. Connect the RAK5010 board to your host computer using the USB debug port. +Then build and flash the :ref:`hello_world` application. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rak5010_nrf52840 + :goals: build flash + + You should see "Hello World! rak5010_nrf52840" in your terminal. + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rak5010_nrf52840 + :maybe-skip-config: + :goals: debug + +References +********** + +.. target-notes:: + +.. _RAK5010 Product Description: + https://doc.rakwireless.com/datasheet/rakproducts/rak5010-wistrio-nb-iot-tracker-datasheet + +.. _JLink Downloads Page: + https://www.segger.com/downloads/jlink diff --git a/boards/arm/rak5010_nrf52840/rak5010_nrf52840.dts b/boards/arm/rak5010_nrf52840/rak5010_nrf52840.dts new file mode 100644 index 00000000000000..61f301dcc58a89 --- /dev/null +++ b/boards/arm/rak5010_nrf52840/rak5010_nrf52840.dts @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2020 Guillaume Paquet + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "RAKWireless RAK5010 Wistrio Board with a Nordic NRF52840 SoC"; + compatible = "nordic,rak5010_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; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + label = "Green LED 0"; + }; + }; + + /* Declaration of aliases */ + aliases { + led0 = &led0; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&uart0 { + compatible = "nordic,nrf-uart"; + current-speed = <115200>; + status = "okay"; + tx-pin = <33>; + rx-pin = <34>; +}; + +&uart1 { + compatible = "nordic,nrf-uart"; + status = "okay"; + current-speed = <115200>; + tx-pin = <8>; + rx-pin = <6>; + rts-pin = <7>; + cts-pin = <11>; +}; + +&i2c1 { + compatible = "nordic,nrf-twi"; + status = "okay"; + sda-pin = <14>; + scl-pin = <13>; + + /* TI OPT3001 light sensor */ + opt3001@44 { + compatible = "ti,opt3001"; + label = "OPT3001"; + reg = <0x44>; + }; + + /* ST Microelectronics LIS3DH motion sensor */ + lis3dh@19 { + compatible = "st,lis3dh"; + label = "LIS3DH"; + reg = <0x19>; + irq-gpios = <&gpio0 15 0>; + }; + + /* ST Microelectronics LPS22HB pressure sensor */ + lps22hb-press@5c { + compatible = "st,lps22hb-press"; + reg = <0x5c>; + label = "LPS22HB"; + }; +}; + +&qspi { + status = "okay"; + sck-pin = <43>; + io-pins = <47>, <46>, <45>, <44>; + csn-pins = <42>; + is25wp064a: is25wp064a@0 { + compatible = "nordic,qspi-nor"; + reg = <0>; + writeoc = "pp4io"; + readoc = "read4io"; + sck-frequency = <16000000>; + label = "IS25WP064A"; + jedec-id = [9d 70 17]; + size = <67108864>; + has-dpd; + t-enter-dpd = <3000>; + t-exit-dpd = <5000>; + }; +}; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x000000000 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/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@f8000 { + label = "storage"; + reg = <0x000f8000 0x00008000>; + }; + }; +}; + +&usbd { + compatible = "nordic,nrf-usbd"; + status = "okay"; +}; diff --git a/boards/arm/rak5010_nrf52840/rak5010_nrf52840.yaml b/boards/arm/rak5010_nrf52840/rak5010_nrf52840.yaml new file mode 100644 index 00000000000000..c32726dccec071 --- /dev/null +++ b/boards/arm/rak5010_nrf52840/rak5010_nrf52840.yaml @@ -0,0 +1,20 @@ +identifier: rak5010_nrf52840 +name: RAK5010-NRF52840 +type: mcu +arch: arm +flash: 1024 +ram: 256 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - ble + - counter + - gpio + - i2c + - pwm + - usb_cdc + - usb_device + - watchdog diff --git a/boards/arm/rak5010_nrf52840/rak5010_nrf52840_defconfig b/boards/arm/rak5010_nrf52840/rak5010_nrf52840_defconfig new file mode 100644 index 00000000000000..b7e873c3f03656 --- /dev/null +++ b/boards/arm/rak5010_nrf52840/rak5010_nrf52840_defconfig @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_RAK5010_NRF52840=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable RTT +CONFIG_USE_SEGGER_RTT=y + +# enable GPIO +CONFIG_GPIO=y + +# enable uart driver +CONFIG_SERIAL=y + +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/reel_board/Kconfig.defconfig b/boards/arm/reel_board/Kconfig.defconfig index 926a884d18aebc..149404d3d53f49 100644 --- a/boards/arm/reel_board/Kconfig.defconfig +++ b/boards/arm/reel_board/Kconfig.defconfig @@ -12,10 +12,6 @@ config BOARD config I2C default y -config SPI_NRFX_RAM_BUFFER_SIZE - default 8 - depends on SPI - if USB config USB_NRFX @@ -26,10 +22,6 @@ config USB_DEVICE_STACK endif # USB -config IEEE802154_NRF5 - default y - depends on IEEE802154 - config BT_CTLR default y depends on BT diff --git a/boards/arm/reel_board/board.c b/boards/arm/reel_board/board.c index e3b409d0a77629..3e9b649b5927b0 100644 --- a/boards/arm/reel_board/board.c +++ b/boards/arm/reel_board/board.c @@ -10,7 +10,7 @@ /* Peripheral voltage ON/OFF GPIO */ #define PERIPH_PON_PIN 0 -static int board_reel_board_init(struct device *dev) +static int board_reel_board_init(const struct device *dev) { ARG_UNUSED(dev); volatile NRF_GPIO_Type *gpio = NRF_P1; diff --git a/boards/arm/reel_board/dts/reel_board.dtsi b/boards/arm/reel_board/dts/reel_board.dtsi index a712c420575a5a..691fe8c418d653 100644 --- a/boards/arm/reel_board/dts/reel_board.dtsi +++ b/boards/arm/reel_board/dts/reel_board.dtsi @@ -159,14 +159,11 @@ arduino_spi: &spi3 { sck-pin = <47>; miso-pin = <46>; mosi-pin = <45>; - cs-gpios = <&arduino_header 16 0>; /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/reel_board/reel_board.dts b/boards/arm/reel_board/reel_board.dts index b328de88330f63..50fd3d1f04ace0 100644 --- a/boards/arm/reel_board/reel_board.dts +++ b/boards/arm/reel_board/reel_board.dts @@ -55,7 +55,7 @@ sck-pin = <19>; mosi-pin = <20>; miso-pin = <21>; - cs-gpios = <&gpio0 17 0>; + cs-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; ssd16xxfb@0 { compatible = "solomon,ssd16xxfb", "gooddisplay,gdeh0213b1"; diff --git a/boards/arm/reel_board/reel_board_v2.dts b/boards/arm/reel_board/reel_board_v2.dts index 03b48481d74016..f7ed6d8372913c 100644 --- a/boards/arm/reel_board/reel_board_v2.dts +++ b/boards/arm/reel_board/reel_board_v2.dts @@ -31,7 +31,7 @@ sck-pin = <19>; mosi-pin = <20>; miso-pin = <21>; - cs-gpios = <&gpio0 17 0>; + cs-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; ssd16xxfb@0 { compatible = "solomon,ssd16xxfb", "gooddisplay,gdeh0213b72"; diff --git a/boards/arm/ruuvi_ruuvitag/Kconfig b/boards/arm/ruuvi_ruuvitag/Kconfig new file mode 100644 index 00000000000000..0077a92a221f00 --- /dev/null +++ b/boards/arm/ruuvi_ruuvitag/Kconfig @@ -0,0 +1,10 @@ +# Ruuvi-RuuviTag board configuration + +# Copyright (c) 2020 Ruuvi Innovations Ltd (Oy) +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on BOARD_RUUVI_RUUVITAG diff --git a/boards/arm/ruuvi_ruuvitag/Kconfig.board b/boards/arm/ruuvi_ruuvitag/Kconfig.board new file mode 100644 index 00000000000000..39a7af5dee9442 --- /dev/null +++ b/boards/arm/ruuvi_ruuvitag/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2020 Ruuvi Innovations Ltd (Oy) +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RUUVI_RUUVITAG + bool "Ruuvi-RuuviTag" + depends on SOC_NRF52832_QFAA diff --git a/boards/arm/ruuvi_ruuvitag/Kconfig.defconfig b/boards/arm/ruuvi_ruuvitag/Kconfig.defconfig new file mode 100644 index 00000000000000..fb5618995ff24b --- /dev/null +++ b/boards/arm/ruuvi_ruuvitag/Kconfig.defconfig @@ -0,0 +1,17 @@ +# Ruuvi RuuviTag configuration + +# Copyright (c) 2020 Ruuvi Innovations Ltd (Oy) +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RUUVI_RUUVITAG + +config BOARD + default "ruuvi_ruuvitag" + +config SPI + default y + +config BT_CTLR + default BT + +endif # BOARD_RUUVI_RUUVITAG diff --git a/boards/arm/ruuvi_ruuvitag/board.cmake b/boards/arm/ruuvi_ruuvitag/board.cmake new file mode 100644 index 00000000000000..0124d8f7f082e4 --- /dev/null +++ b/boards/arm/ruuvi_ruuvitag/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2020 Ruuvi Innovations Ltd (Oy) +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=nrf52" "--speed=4000") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/ruuvi_ruuvitag/doc/img/pinout.jpg b/boards/arm/ruuvi_ruuvitag/doc/img/pinout.jpg new file mode 100644 index 00000000000000..43e132274713b5 Binary files /dev/null and b/boards/arm/ruuvi_ruuvitag/doc/img/pinout.jpg differ diff --git a/boards/arm/ruuvi_ruuvitag/doc/img/ruuvitag.jpg b/boards/arm/ruuvi_ruuvitag/doc/img/ruuvitag.jpg new file mode 100644 index 00000000000000..ced2abf8f2148a Binary files /dev/null and b/boards/arm/ruuvi_ruuvitag/doc/img/ruuvitag.jpg differ diff --git a/boards/arm/ruuvi_ruuvitag/doc/index.rst b/boards/arm/ruuvi_ruuvitag/doc/index.rst new file mode 100644 index 00000000000000..7db00096ca10f9 --- /dev/null +++ b/boards/arm/ruuvi_ruuvitag/doc/index.rst @@ -0,0 +1,186 @@ +.. _ruuvi_ruuvitag: + +Ruuvi RuuviTag +############## + +Overview +******** + +RuuviTag is an advanced battery-operated open-source Bluetooth +enabled sensor beacon platform capable of sending temperature, humidity, +pressure, and motion information over Bluetooth Low Energy. + +.. figure:: img/ruuvitag.jpg + :width: 442px + :align: center + :alt: RUUVI RuuviTag + + RUUVI RuuviTag (Credit: https://ruuvi.com/) + +More information about the board can be found at the +`ruuvitag website`_. + +Hardware +******** + +RuuviTag's have the following physical features: + +* Nordic Semiconductor nRF52832 System-on-Chip +* STMicroelectronics LIS2DH12 accelerometer +* Bosch BME 280 temperature + relative air humidity + air pressure sensor +* NFC™-A tag antenna +* 1000mAh CR2477 battery +* 2 buttons +* 1 Green LED +* 1 Red LED +* IP67 Enclosure +* Long range RF antenna + +Supported Features +================== + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| SPI | on-chip | spi | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ +| Humidity, | on-board | bme280 | +| Temp & Air| | | +| Pressure | | | ++-----------+------------+----------------------+ +| Acc | on-board | lis2dh12 | ++-----------+------------+----------------------+ + +Connections and IOs +=================== + +LED +--- + +* LED0 (red) = P0.17 +* LED1 (green) = P0.19 + +Push buttons +------------ + +* BUTTON0 = SW1 = P0.13 + +Pin descriptions +---------------- + +.. figure:: img/pinout.jpg + :width: 442px + :align: center + :alt: RUUVI Pinout + +* 2 = P0.29 = SPI_SCK +* 3 = P0.28 = SPI_MISO +* 10 = P0.04 = GPIO (can be used as a GPIO / ADC pin) +* 11 = P0.05 = GPIO (can be used as a GPIO / ADC pin) +* 12 = P0.25 = SPI_MOSI +* 13 = P0.19 = LED2 (green) / GPIO (can be used as a GPIO pin but the LED will blink) +* 14 = P0.17 = LED1 (red) / GPIO (can be used as a GPIO pin but the LED will blink) +* 15 = P0.13 = Button / GPIO (can be used as a GPIO pin) +* 16 = GND (Battery's negative contact) +* 17 = Battery's positive contact +* 18 = Battery's positive contact +* 19 = SWDIO +* 20 = SWDCLK +* 21 = P0.18 = SWO / GPIO (can be used as a GPIO pin) +* 22 = P0.21 = Reset / GPIO (can be used as a GPIO pin if no need to reset the device) +* 23 = GND (Battery's negative contact) +* 24 = P0.31 = GPIO (can be used as a GPIO / ADC pin) +* 25 = P0.30 = GPIO (can be used as a GPIO / ADC pin) + +GPIO = General Purpose Input Output pin + +P1 = Standard 10-pin ARM Cortex debug connector (on RuuviTag Rev.B1-B5) + +* 1 = VDD +* 2 = SWDIO +* 3 = GND (Battery's negative contact) +* 4 = SWDCLK +* 5 = GND (Battery's negative contact) +* 6 = SWO +* 7 = No Connect +* 8 = No Connect +* 9 = GND (Battery's negative contact) +* 10 = Reset + +P1 = TC2030 TagConnect (on RuuviTag Rev.B6) + +* 1 = Battery's positive contact +* 2 = SWDIO +* 3 = Reset +* 4 = SWDCLK +* 5 = GND (Battery's negative contact) +* 6 = SWO + + +Programming and Debugging +************************* + +Flashing +======== + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +The easiest way to flash Zephyr onto a RuuviTag requires an external Ruuvi DEVKIT. More information about the board can be found at the +`ruuvitag devkit`_. + +Once your tag is conencted to the DEVKIT and conencted to your PC, build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: ruuvi_ruuvitag + :goals: build flash + +Advanced users may want to program the RuuviTag without the DEVKIT, this can be achieved via the SWDIO and SWDCLK pins located on the back of the RuuviTag. + +Debugging +========= + +If using the Ruuvi DEVKIT refer to the :ref:`nordic_segger` page to learn about debugging Nordic boards with a +Segger IC. + +Testing the LEDs and buttons on the RuuviTag +******************************************** + +There are 2 samples that allow you to test that the buttons (switches) and LEDs on +the board are working properly with Zephyr: + +* :ref:`blinky-sample` +* :ref:`button-sample` + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The button and LED definitions can be found in :file:`boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.dts`. + +References +********** + +.. target-notes:: + +.. _ruuvitag website: https://ruuvi.com +.. _ruuvitag datasheet: https://ruuvi.com/files/ruuvitag-tech-spec-2019-7.pdf +.. _ruuvitag devkit: https://lab.ruuvi.com/devshield/ diff --git a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.dts b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.dts new file mode 100644 index 00000000000000..d0b91ecc9ee2d8 --- /dev/null +++ b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.dts @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2020 Ruuvi Innovations Ltd (Oy) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Ruuvi RuuviTag"; + compatible = "ruuvi,ruuvitag"; + + 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; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; + label = "Red LED 0"; + }; + led1: led_1 { + gpios = <&gpio0 19 GPIO_ACTIVE_LOW>; + label = "Green LED 1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 0"; + }; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + compatible = "nordic,nrf-uart"; + current-speed = <115200>; + tx-pin = <5>; + rx-pin = <4>; + cts-pin = <31>; + rts-pin = <30>; +}; + +&spi0 { + compatible = "nordic,nrf-spi"; + status = "okay"; + sck-pin = <29>; + mosi-pin = <25>; + miso-pin = <28>; + cs-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>, <&gpio0 8 GPIO_ACTIVE_LOW>; + + bme280@0 { + compatible = "bosch,bme280"; + reg = <0>; + spi-max-frequency = <10000000>; + label= "BME280"; + }; + + lis2dh12: lis2dh12@1 { + compatible = "st,lis2dh", "st,lis2dh12"; + reg = <1>; + spi-max-frequency = <10000000>; + irq-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>, <&gpio0 6 GPIO_ACTIVE_HIGH>; + label = "LIS2DH12-ACCEL"; + }; +}; + + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0xc000>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0x32000>; + }; + slot1_partition: partition@3e000 { + label = "image-1"; + reg = <0x0003E000 0x32000>; + }; + scratch_partition: partition@70000 { + label = "image-scratch"; + reg = <0x00070000 0xa000>; + }; + + /* + * The flash starting at 0x0007a000 and ending at + * 0x0007ffff (sectors 122-127) is reserved for use + * by the application. + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@7a000 { + label = "storage"; + reg = <0x0007a000 0x00006000>; + }; + }; +}; diff --git a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.yaml b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.yaml new file mode 100644 index 00000000000000..43bbfae0fc6f81 --- /dev/null +++ b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag.yaml @@ -0,0 +1,18 @@ +identifier: ruuvi_ruuvitag +name: Ruuvi-RuuviTag +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 64 +flash: 512 +supported: + - ble + - adc + - gpio + - spi + - counter + - nvs + - watchdog diff --git a/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig new file mode 100644 index 00000000000000..b2c684785a8929 --- /dev/null +++ b/boards/arm/ruuvi_ruuvitag/ruuvi_ruuvitag_defconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2020 Ruuvi Innovations Ltd (Oy) +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52832_QFAA=y +CONFIG_BOARD_RUUVI_RUUVITAG=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable RTT +CONFIG_USE_SEGGER_RTT=y + +# Enable GPIO +CONFIG_GPIO=y + +# additional board options +# set y to disable R button +CONFIG_GPIO_AS_PINRESET=n diff --git a/boards/arm/sam4e_xpro/Kconfig.defconfig b/boards/arm/sam4e_xpro/Kconfig.defconfig index 8bd01e73d20626..e11bd8b37eeea6 100644 --- a/boards/arm/sam4e_xpro/Kconfig.defconfig +++ b/boards/arm/sam4e_xpro/Kconfig.defconfig @@ -8,26 +8,4 @@ if BOARD_SAM4E_XPRO config BOARD default "sam4e_xpro" -config GPIO_SAM - default y - depends on GPIO - -config I2C_SAM_TWI - default y - depends on I2C - -config SPI_SAM - default y - depends on SPI - -if NETWORKING - -config NET_L2_ETHERNET - default y - -config ETH_SAM_GMAC - default y if NET_L2_ETHERNET - -endif # NETWORKING - endif # BOARD_SAM4E_XPRO diff --git a/boards/arm/sam4e_xpro/board.cmake b/boards/arm/sam4e_xpro/board.cmake index a1aa73b41e8794..50ce23d906cd48 100644 --- a/boards/arm/sam4e_xpro/board.cmake +++ b/boards/arm/sam4e_xpro/board.cmake @@ -2,3 +2,5 @@ board_runner_args(openocd --cmd-post-verify "at91sam4 gpnvm set 1") include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + +include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake) diff --git a/boards/arm/sam4e_xpro/doc/index.rst b/boards/arm/sam4e_xpro/doc/index.rst index f6eb5258240d44..8dadd1d8b723a5 100644 --- a/boards/arm/sam4e_xpro/doc/index.rst +++ b/boards/arm/sam4e_xpro/doc/index.rst @@ -106,6 +106,43 @@ contents of the SAM4E flash memory: Flashing ======== +For flash the board Zephyr provides two paths. One uses the default OpenOCD +tool and the second one uses :ref:`atmel_sam_ba_bootloader`. + +Using OpenOCD +------------- + +#. Connect the SAM4E Xplained Pro board to your host computer using the USB + debug port. Then build and flash the :ref:`hello_world` application. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: sam4e_xpro + :goals: build flash + +Using SAM-BA bootloader +----------------------- + +#. Close the ``ERASE`` jumper on the SAM4E Xplained Pro board. Power on the + board for 10s. + +#. Open the ``ERASE`` jumper. + +#. Connect the SAM4E Xplained Pro board to your host computer using the SoC + USB port. Then build and flash the :ref:`hello_world` application. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: sam4e_xpro + :goals: build + + .. code-block:: console + + $ west flash -r bossac + +Visualizing the message +----------------------- + #. Run your favorite terminal program to listen for output. Under Linux the terminal should be :code:`/dev/ttyACM0`. For example: @@ -113,22 +150,15 @@ Flashing $ minicom -D /dev/ttyACM0 -o - The -o option tells minicom not to send the modem initialization - string. Connection should be configured as follows: + The -o option tells minicom not to send the modem initialization string. + Connection should be configured as follows: - Speed: 115200 - Data: 8 bits - Parity: None - Stop bits: 1 -#. Connect the SAM4E Xplained Pro board to your host computer using the - USB debug port. Then build and flash the :ref:`hello_world` - application. - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: sam4e_xpro - :goals: build flash +#. Press reset button You should see "Hello World! arm" in your terminal. diff --git a/boards/arm/sam4e_xpro/pinmux.c b/boards/arm/sam4e_xpro/pinmux.c index 244a68893a086a..961f522f3cf7e1 100644 --- a/boards/arm/sam4e_xpro/pinmux.c +++ b/boards/arm/sam4e_xpro/pinmux.c @@ -6,7 +6,7 @@ #include -static int sam4e_xpro_init(struct device *dev) +static int sam4e_xpro_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/sam4e_xpro/sam4e_xpro.dts b/boards/arm/sam4e_xpro/sam4e_xpro.dts index 3239476799d1f5..6c071fd5ee1330 100644 --- a/boards/arm/sam4e_xpro/sam4e_xpro.dts +++ b/boards/arm/sam4e_xpro/sam4e_xpro.dts @@ -42,6 +42,81 @@ GPIO_ACTIVE_LOW)>; }; }; + + ext1_header: xplained-pro-connector1 { + compatible = "atmel-xplained-pro-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &piob 2 0>, /* AFE AD0 */ + <1 0 &piob 3 0>, /* AFE AD1 */ + <2 0 &pioa 24 0>, /* GPIO */ + <3 0 &pioa 25 0>, /* GPIO */ + <4 0 &pioa 15 0>, /* TIOA1 */ + <5 0 &pioa 16 0>, /* TIOB1 */ + <6 0 &pioa 11 0>, /* WKUP7 */ + <7 0 &piod 25 0>, /* GPIO */ + <8 0 &pioa 3 0>, /* TWD0 EXTx */ + <9 0 &pioa 4 0>, /* TWCK0 EXTx */ + <10 0 &pioa 21 0>, /* RXD1 */ + <11 0 &pioa 22 0>, /* TXD1 */ + <12 0 &piob 14 0>, /* SPI(NPCS1) */ + <13 0 &pioa 13 0>, /* SPI(MOSI) EXTx */ + <14 0 &pioa 12 0>, /* SPI(MISO) EXTx */ + <15 0 &pioa 14 0>; /* SPI(SCK) EXTx */ + /* GND */ + /* +3.3V */ + }; + + ext2_header: xplained-pro-connector2 { + compatible = "atmel-xplained-pro-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = /*<0 0 - - 0>, - */ + /*<1 0 - - 0>, - */ + <2 0 &pioe 2 0>, /* GPIO EBDG */ + <3 0 &piob 5 0>, /* GPIO EDBG */ + <4 0 &piod 21 0>, /* PWMHI1 */ + /*<5 0 - - 0>, - */ + <6 0 &piod 29 0>, /* GPIO ETH */ + <7 0 &piob 4 0>, /* GPIO */ + <8 0 &pioa 3 0>, /* TWD0 EXTx */ + <9 0 &pioa 4 0>, /* TWCK0 EXTx */ + <10 0 &pioa 5 0>, /* URXD1 EXT3 */ + <11 0 &pioa 6 0>, /* UTXD1 EXT3 */ + <12 0 &piod 23 0>, /* GPIO */ + <13 0 &pioa 13 0>, /* SPI(MOSI) EXTx */ + <14 0 &pioa 12 0>, /* SPI(MISO) EXTx */ + <15 0 &pioa 14 0>; /* SPI(SCK) EXTx */ + /* GND */ + /* +3.3V */ + }; + + ext3_header: xplained-pro-connector3 { + compatible = "atmel-xplained-pro-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &pioa 17 0>, /* AFE AD0 */ + <1 0 &pioc 13 0>, /* AFE AD6 */ + <2 0 &piod 28 0>, /* GPIO */ + <3 0 &piod 17 0>, /* GPIO */ + <4 0 &piod 20 0>, /* PWMH0 */ + <5 0 &piod 24 0>, /* PWML0 */ + <6 0 &pioe 1 0>, /* GPIO */ + <7 0 &piod 26 0>, /* GPIO */ + <8 0 &pioa 3 0>, /* TWD0 EXTx */ + <9 0 &pioa 4 0>, /* TWCK0 EXTx */ + <10 0 &pioa 5 0>, /* URXD1 EXT2 */ + <11 0 &pioa 6 0>, /* UTXD1 EXT2 */ + <12 0 &piod 30 0>, /* GPIO */ + <13 0 &pioa 13 0>, /* SPI(MOSI) EXTx */ + <14 0 &pioa 12 0>, /* SPI(MISO) EXTx */ + <15 0 &pioa 14 0>; /* SPI(SCK) EXTx */ + /* GND */ + /* +3.3V */ + }; }; &cpu0 { @@ -50,6 +125,13 @@ &spi0 { status = "okay"; + pinctrl-0 = <&pa12a_spi_miso + &pa13a_spi_mosi + &pa14a_spi_spck + &pb14a_spi_npcs1>; + cs-gpios = <&piob 14 GPIO_ACTIVE_LOW>, + <&piod 23 GPIO_ACTIVE_LOW>, + <&piod 30 GPIO_ACTIVE_LOW>; }; &uart0 { @@ -57,6 +139,12 @@ status = "okay"; }; +&usart1 { + pinctrl-0 = <&pa21a_usart1_rxd1 &pa22a_usart1_txd1>; + current-speed = <115200>; + status = "okay"; +}; + &gmac { status = "okay"; zephyr,random-mac-address; @@ -65,3 +153,30 @@ &wdt { status = "okay"; }; + +ext1_spi: &spi0 { +}; + +ext1_i2c: &twi0 { +}; + +ext1_serial: &usart1 { +}; + +ext2_spi: &spi0 { +}; + +ext2_i2c: &twi0 { +}; + +ext2_serial: &uart1 { +}; + +ext3_spi: &spi0 { +}; + +ext3_i2c: &twi0 { +}; + +ext3_serial: &uart1 { +}; diff --git a/boards/arm/sam4e_xpro/sam4e_xpro.yaml b/boards/arm/sam4e_xpro/sam4e_xpro.yaml index 5896262d35d724..b9392fc5089c76 100644 --- a/boards/arm/sam4e_xpro/sam4e_xpro.yaml +++ b/boards/arm/sam4e_xpro/sam4e_xpro.yaml @@ -11,3 +11,7 @@ supported: - gpio - spi - watchdog + - xpro_gpio + - xpro_i2c + - xpro_serial + - xpro_spi diff --git a/boards/arm/sam4e_xpro/sam4e_xpro_defconfig b/boards/arm/sam4e_xpro/sam4e_xpro_defconfig index 71cc9eefa6f58a..a55e40f37daf69 100644 --- a/boards/arm/sam4e_xpro/sam4e_xpro_defconfig +++ b/boards/arm/sam4e_xpro/sam4e_xpro_defconfig @@ -9,7 +9,11 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_SAM=y CONFIG_BOARD_SAM4E_XPRO=y +CONFIG_BUILD_OUTPUT_HEX=y CONFIG_SOC_ATMEL_SAM4E_EXT_MAINCK=y CONFIG_GPIO_SAM=y CONFIG_GPIO=y CONFIG_WDT_DISABLE_AT_BOOT=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/sam4l_ek/Kconfig.board b/boards/arm/sam4l_ek/Kconfig.board new file mode 100644 index 00000000000000..1c0987a045f80c --- /dev/null +++ b/boards/arm/sam4l_ek/Kconfig.board @@ -0,0 +1,8 @@ +# Atmel SAM4L-EK selection + +# Copyright (c) 2020 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SAM4L_EK + bool "Atmel SAM4L-EK" + depends on SOC_PART_NUMBER_SAM4LC4C diff --git a/boards/arm/sam4l_ek/Kconfig.defconfig b/boards/arm/sam4l_ek/Kconfig.defconfig new file mode 100644 index 00000000000000..315afa1b31261c --- /dev/null +++ b/boards/arm/sam4l_ek/Kconfig.defconfig @@ -0,0 +1,11 @@ +# Atmel SAM4L-EK Board configuration + +# Copyright (c) 2020 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SAM4L_EK + +config BOARD + default "sam4l_ek" + +endif # BOARD_SAM4L_EK diff --git a/boards/arm/sam4l_ek/board.cmake b/boards/arm/sam4l_ek/board.cmake new file mode 100644 index 00000000000000..c21d98807f4026 --- /dev/null +++ b/boards/arm/sam4l_ek/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2020 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=atsam4lc4c") +board_runner_args(jlink "--speed=4000") +board_runner_args(jlink "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/sam4l_ek/doc/img/atmel-sam4l-ek-callouts.jpeg b/boards/arm/sam4l_ek/doc/img/atmel-sam4l-ek-callouts.jpeg new file mode 100644 index 00000000000000..9cd04e49a2927e Binary files /dev/null and b/boards/arm/sam4l_ek/doc/img/atmel-sam4l-ek-callouts.jpeg differ diff --git a/boards/arm/sam4l_ek/doc/index.rst b/boards/arm/sam4l_ek/doc/index.rst new file mode 100644 index 00000000000000..bcf42d9635eebb --- /dev/null +++ b/boards/arm/sam4l_ek/doc/index.rst @@ -0,0 +1,173 @@ +.. _sam4l_ek: + +SAM4L-EK +######## + +Overview +******** + +The SAM4L series embeds picoPower technology for ultra-low power consumption. +Combined power control techniques are used to bring active current consumption +down to 90μA/MHz. The device allows a wide range of configurations giving the +user the ability to balance between the lowest possible power consumption and +the feature set selected for the application. The WAIT and RETENTION modes +provide full logic and RAM retention, associated with fast wake-up capability +(<1.5μs) and a very low consumption of, respectively, 3 μA and 1.5 μA. In +addition, WAIT mode supports SleepWalking features. In BACKUP mode, CPU, +peripherals and RAM are powered off consuming less than 0.9μA with external +interrupt wake-up support. + +The SAM4L-EK is a full featured design to develop for Atmel SAM4L SoC series. +The kit is equipped with a rich set of peripherals that make the ATSAM4L-EK a +perfect evaluation platform. Download the `SAM4L-EK Online User Guide`_ for +more details. + +.. image:: img/atmel-sam4l-ek-callouts.jpeg + :width: 500px + :align: center + :alt: SAM4L-EK + +Hardware +******** + +- ATSAM4LC4C ARM Cortex-M4 Processor +- 12 MHz crystal oscillator +- 32.768 kHz crystal oscillator +- 1 Micro-AB USB OTG host/device +- 1 AT86RF2xx IEEE 802.15.4 transceiver connector +- 1 RS-485 full duplex interface +- 1 Sensor Xplained board connector +- 1 Audio Jack connector 3.5mm +- 1 Dedicated Board Monitor MCU + + - Power measurement (VDDIN, VDDIO, VDDANA) + - 1 OLED Display (128x64) + - 5 LEDs + - 1 Joystick + - 1 USART + - 1 TWI +- 1 40x4 LCD Segment Display +- 1 user touch button and One user pushbutton +- 1 user LED +- 1 QTouch Slider +- 1 QTouch Button +- 1 TEMT6000 Light Sensor +- 1 AT25DF641A Serial NOR Flash + +Supported Features +================== + +The sam4l_ek board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| HWINFO | on-chip | Unique 120 bit serial number | ++-----------+------------+-------------------------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| TRNG | on-chip | 32-bit True Random Number Generator | ++-----------+------------+-------------------------------------+ +| TWIM | on-chip | i2c master port-interrupt | ++-----------+------------+-------------------------------------+ +| USART | on-chip | serial port | ++-----------+------------+-------------------------------------+ + +Other hardware features are not currently supported by Zephyr. + +The default configuration can be found in the Kconfig +:zephyr_file:`boards/arm/sam4l_ek/sam4l_ek_defconfig`. + +Connections and IOs +=================== + +The `SAM4L-EK Design Documentation`_ has detailed information about board +connections. Download the `SAM4L-EK Design Documentation`_ for more details. + +System Clock +============ + +The SAM4L MCU is configured to use the 12 MHz internal oscillator on the board +with the on-chip PLL to generate an 48 MHz system clock. + +Serial Port +=========== + +The ATSAM4LC4C MCU has 4 USARTs. One of the USARTs (USART2) is connected on +the embedded debug unit and can works as a console. The USART0 is shared +between all others headers and RS-485 port. + +Programming and Debugging +************************* + +The SAM4L-EK board have a Segger Embedded Debugger Unit +`J-Link OB `_. This provides a debug +interface to the SAM4LC4C chip. You can use Ozone or JLink to communicate with +the SAM4LC4C. + +Flashing +======== + +#. Download JLink from the Segger `JLink Downloads Page`_. Go to the section + "J-Link Software and Documentation Pack" and install the "J-Link Software + and Documentation pack for Linux". The application JLinkExe needs to be + accessible from your path. + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyACM0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyACM0 -o + + The -o option tells minicom not to send the modem initialization string. + Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + +#. Connect the SAM4L-EK board to your host computer using the USB debug port. +Then build and flash the :ref:`hello_world` application. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: sam4l_ek + :goals: build flash + + You should see "Hello World! sam4l_ek" in your terminal. + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: sam4l_ek + :maybe-skip-config: + :goals: debug + +References +********** + +.. target-notes:: + +.. _SAM4L-EK Online User Guide: + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42026-ATSAM4L-EK-User-Guide_ApplicationNote_AVR32850.pdf + +.. _SAM4L-EK Design Documentation: + http://ww1.microchip.com/downloads/en/DeviceDoc/doc42027_SAM4L-EK_Design_Documentation.PDF + +.. _JLink Downloads Page: + https://www.segger.com/downloads/jlink diff --git a/boards/arm/sam4l_ek/sam4l_ek.dts b/boards/arm/sam4l_ek/sam4l_ek.dts new file mode 100644 index 00000000000000..63823e2149eb71 --- /dev/null +++ b/boards/arm/sam4l_ek/sam4l_ek.dts @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020 Gerson Fernando Budke + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "Atmel SAM4L-EK Board with an Atmel SAM4LC4C SoC"; + compatible = "atmel,sam4l_ek"; + + aliases { + led0 = &user_led; + sw0 = &sw0_dfu; + }; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + user_led: led_0 { + gpios = <&gpioc 10 GPIO_ACTIVE_HIGH>; + label = "LED_0"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + sw0_dfu: button_1 { + label = "SW0_DFU"; + gpios = <&gpioc 3 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&cpu0 { + clock-frequency = <48000000>; +}; + +&usart2 { + current-speed = <115200>; + pinctrl-0 = <&pc11b_usart2_rxd2 &pc12b_usart2_txd2>; + status = "okay"; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&pc4a_spi_miso + &pc5a_spi_mosi + &pc6a_spi_sck + &pa2b_spi_npcs0 + &pc0a_spi_npcs2>; + cs-gpios = <&gpioa 2 GPIO_ACTIVE_LOW>, + <&gpioc 0 GPIO_ACTIVE_LOW>; +}; + +&twim0 { + status = "okay"; + + std-clk-slew-lim = <0>; + std-clk-strength-low = "0.5"; + std-data-slew-lim = <0>; + std-data-strength-low = "0.5"; + + hs-clk-slew-lim = <0>; + hs-clk-strength-high = "0.5"; + hs-clk-strength-low = "0.5"; + hs-data-slew-lim = <0>; + hs-data-strength-low = "0.5"; + + hs-master-code = <0>; +}; diff --git a/boards/arm/sam4l_ek/sam4l_ek.yaml b/boards/arm/sam4l_ek/sam4l_ek.yaml new file mode 100644 index 00000000000000..eec21aa7c2f242 --- /dev/null +++ b/boards/arm/sam4l_ek/sam4l_ek.yaml @@ -0,0 +1,15 @@ +identifier: sam4l_ek +name: SAM4L-EK +type: mcu +arch: arm +flash: 256 +ram: 32 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - i2c + - spi + - usart diff --git a/boards/arm/sam4l_ek/sam4l_ek_defconfig b/boards/arm/sam4l_ek/sam4l_ek_defconfig new file mode 100644 index 00000000000000..11e6258fed0ea5 --- /dev/null +++ b/boards/arm/sam4l_ek/sam4l_ek_defconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_SAM4L=y +CONFIG_SOC_PART_NUMBER_SAM4LC4C=y +CONFIG_ARM_MPU=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_BOARD_SAM4L_EK=y +CONFIG_WATCHDOG=n +CONFIG_SPI=y +CONFIG_GPIO=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/sam4s_xplained/Kconfig.defconfig b/boards/arm/sam4s_xplained/Kconfig.defconfig index e41a9a7ece2e17..d201fa44209e67 100644 --- a/boards/arm/sam4s_xplained/Kconfig.defconfig +++ b/boards/arm/sam4s_xplained/Kconfig.defconfig @@ -8,11 +8,4 @@ if BOARD_SAM4S_XPLAINED config BOARD default "sam4s_xplained" -if I2C - -config I2C_SAM_TWI - default y - -endif # I2C - endif # BOARD_SAM4S_XPLAINED diff --git a/boards/arm/sam4s_xplained/board.cmake b/boards/arm/sam4s_xplained/board.cmake index e0129740842e77..06760832d32d27 100644 --- a/boards/arm/sam4s_xplained/board.cmake +++ b/boards/arm/sam4s_xplained/board.cmake @@ -2,3 +2,5 @@ board_runner_args(jlink "--device=atsam4s16c" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake) diff --git a/boards/arm/sam4s_xplained/doc/index.rst b/boards/arm/sam4s_xplained/doc/index.rst index 4fd582d5c17f38..471a26556f23a0 100644 --- a/boards/arm/sam4s_xplained/doc/index.rst +++ b/boards/arm/sam4s_xplained/doc/index.rst @@ -89,10 +89,49 @@ the SAM4S16C. Flashing ======== +For flash the board Zephyr provides two paths. One uses the default JLink +tool and the second one uses :ref:`atmel_sam_ba_bootloader`. + +Using JLink +------------- + #. Download JLink from the Segger `JLink Downloads Page`_. Go to the section - "J-Link Software and Documentation Pack" and install the "J-Link Software and - Documentation pack for Linux". The application JLinkExe needs to be accessible - from your path. + "J-Link Software and Documentation Pack" and install the "J-Link Software + and Documentation pack for Linux". The application JLinkExe needs to be + accessible from your path. + +#. Connect the SAM4S Xplained board to your host computer using the USB debug + port. Then build and flash the :ref:`hello_world` application. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: sam4s_xplained + :goals: build flash + + +Using SAM-BA bootloader +----------------------- + +#. Close the ``J25`` jumper on the SAM4S Xplained board. Power on the board + for 10s. + +#. Open the ``J25`` jumper. + +#. Connect the SAM4S Xplained board to your host computer using the SoC USB + port. Then build and flash the :ref:`hello_world` application. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: sam4s_xplained + :goals: build + + .. code-block:: console + + $ west flash -r bossac + + +Visualizing the message +----------------------- #. Run your favorite terminal program to listen for output. Under Linux the terminal should be :code:`/dev/ttyACM0`. For example: @@ -101,25 +140,19 @@ Flashing $ minicom -D /dev/ttyACM0 -o - The -o option tells minicom not to send the modem initialization - string. Connection should be configured as follows: + The -o option tells minicom not to send the modem initialization string. + Connection should be configured as follows: - Speed: 115200 - Data: 8 bits - Parity: None - Stop bits: 1 -#. Connect the SAM4S Xplained board to your host computer using the - USB debug port. Then build and flash the :ref:`hello_world` - application. - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: sam4s_xplained - :goals: build flash +#. Press reset button You should see "Hello World! arm" in your terminal. + Debugging ========= diff --git a/boards/arm/sam4s_xplained/sam4s_xplained.dts b/boards/arm/sam4s_xplained/sam4s_xplained.dts index 1f822e2d27fb05..05ff92f84bb883 100644 --- a/boards/arm/sam4s_xplained/sam4s_xplained.dts +++ b/boards/arm/sam4s_xplained/sam4s_xplained.dts @@ -45,6 +45,74 @@ gpios = <&pioa 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; }; }; + + xplained1_header: xplained-connector1 { + compatible = "atmel-xplained-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &pioa 3 0>, /* TWD0 y */ + <1 0 &pioa 4 0>, /* TWCK0 y */ + <2 0 &piob 2 0>, /* URXD1 */ + <3 0 &piob 3 0>, /* UTXD1 */ + <4 0 &pioa 31 0>, /* SPI(CS) */ + <5 0 &pioa 13 0>, /* SPI(MOSI) y */ + <6 0 &pioa 12 0>, /* SPI(MISO) y */ + <7 0 &pioa 14 0>; /* SPI(SCK) y */ + /* GND */ + /* +3.3V */ + }; + + xplained2_header: xplained-connector2 { + compatible = "atmel-xplained-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &pioa 22 0>, /* GPIO */ + <1 0 &pioc 12 0>, /* GPIO */ + <2 0 &piob 0 0>, /* GPIO */ + <3 0 &piob 1 0>, /* GPIO */ + <4 0 &pioa 17 0>, /* GPIO */ + <5 0 &pioa 21 0>, /* GPIO */ + <6 0 &pioc 13 0>, /* GPIO */ + <7 0 &pioc 15 0>; /* GPIO */ + /* GND */ + /* +3.3V */ + }; + + xplained3_header: xplained-connector3 { + compatible = "atmel-xplained-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &pioa 20 0>, /* GPIO */ + <1 0 &pioa 11 0>, /* GPIO */ + <2 0 &pioa 23 0>, /* GPIO */ + <3 0 &pioa 18 0>, /* GPIO */ + <4 0 &pioa 15 0>, /* GPIO */ + <5 0 &pioa 16 0>, /* GPIO */ + <6 0 &pioa 2 0>, /* GPIO */ + <7 0 &pioc 2 0>; /* GPIO */ + /* GND */ + /* +3.3V */ + }; + + xplained4_header: xplained-connector4 { + compatible = "atmel-xplained-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &pioa 3 0>, /* TWD0 y */ + <1 0 &pioa 4 0>, /* TWCK0 y */ + <2 0 &piob 2 0>, /* URXD1 */ + <3 0 &piob 3 0>, /* UTXD1 */ + <4 0 &pioa 30 0>, /* SPI(CS) */ + <5 0 &pioa 13 0>, /* SPI(MOSI) y */ + <6 0 &pioa 12 0>, /* SPI(MISO) y */ + <7 0 &pioa 14 0>; /* SPI(SCK) y */ + /* GND */ + /* +3.3V */ + }; }; &cpu0 { @@ -56,6 +124,13 @@ }; &spi0 { + pinctrl-0 = <&pa12a_spi_miso + &pa13a_spi_mosi + &pa14a_spi_spck + &pa31a_spi_npcs1 + &pa30b_spi_npcs2>; + cs-gpios = <&pioa 31 GPIO_ACTIVE_LOW>, + <&pioa 30 GPIO_ACTIVE_LOW>; status = "okay"; }; @@ -72,3 +147,21 @@ &wdt { status = "okay"; }; + +xplained1_i2c: &twi0 { +}; + +xplained1_spi: &spi0 { +}; + +xplained1_serial: &uart1 { +}; + +xplained4_i2c: &twi0 { +}; + +xplained4_spi: &spi0 { +}; + +xplained4_serial: &uart1 { +}; diff --git a/boards/arm/sam4s_xplained/sam4s_xplained.yaml b/boards/arm/sam4s_xplained/sam4s_xplained.yaml index 0a23797a582ef4..436f53f103d355 100644 --- a/boards/arm/sam4s_xplained/sam4s_xplained.yaml +++ b/boards/arm/sam4s_xplained/sam4s_xplained.yaml @@ -10,3 +10,7 @@ supported: - gpio - spi - watchdog + - xplained_gpio + - xplained_i2c + - xplained_serial + - xplained_spi diff --git a/boards/arm/sam4s_xplained/sam4s_xplained_defconfig b/boards/arm/sam4s_xplained/sam4s_xplained_defconfig index afed370f6bf7c7..c28a4b0de901a5 100644 --- a/boards/arm/sam4s_xplained/sam4s_xplained_defconfig +++ b/boards/arm/sam4s_xplained/sam4s_xplained_defconfig @@ -12,3 +12,6 @@ CONFIG_BOARD_SAM4S_XPLAINED=y CONFIG_SOC_ATMEL_SAM4S_EXT_MAINCK=y CONFIG_GPIO=y CONFIG_WDT_DISABLE_AT_BOOT=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/sam_e70_xplained/pinmux.c b/boards/arm/sam_e70_xplained/pinmux.c index 70fc506692bd59..301207e1f2282d 100644 --- a/boards/arm/sam_e70_xplained/pinmux.c +++ b/boards/arm/sam_e70_xplained/pinmux.c @@ -23,7 +23,7 @@ static const struct soc_gpio_pin pwm_ext2_pin8 = { }; #endif -static int sam_e70_xplained_init(struct device *dev) +static int sam_e70_xplained_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/sam_e70_xplained/sam_e70_xplained_defconfig b/boards/arm/sam_e70_xplained/sam_e70_xplained_defconfig index b71a0b51495f38..93f8e7b3317ec6 100644 --- a/boards/arm/sam_e70_xplained/sam_e70_xplained_defconfig +++ b/boards/arm/sam_e70_xplained/sam_e70_xplained_defconfig @@ -15,3 +15,6 @@ CONFIG_USART_SAM=y CONFIG_BOARD_SAM_E70_XPLAINED=y CONFIG_WDT_DISABLE_AT_BOOT=y CONFIG_BUILD_OUTPUT_HEX=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/sam_e70_xplained/sam_e70b_xplained_defconfig b/boards/arm/sam_e70_xplained/sam_e70b_xplained_defconfig index 988ce473c23a37..6c8ebd3e818620 100644 --- a/boards/arm/sam_e70_xplained/sam_e70b_xplained_defconfig +++ b/boards/arm/sam_e70_xplained/sam_e70b_xplained_defconfig @@ -13,4 +13,5 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_USART_SAM=y CONFIG_BOARD_SAM_E70_XPLAINED=y +CONFIG_WDT_DISABLE_AT_BOOT=y CONFIG_BUILD_OUTPUT_HEX=y diff --git a/boards/arm/sam_v71_xult/pinmux.c b/boards/arm/sam_v71_xult/pinmux.c index 60be81fe83205e..452cdc087a0da0 100644 --- a/boards/arm/sam_v71_xult/pinmux.c +++ b/boards/arm/sam_v71_xult/pinmux.c @@ -24,7 +24,7 @@ static const struct soc_gpio_pin pwm_ext2_pin8 = { }; #endif -static int sam_v71_xplained_init(struct device *dev) +static int sam_v71_xplained_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi b/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi index 9353709c893884..70e752f2cba863 100644 --- a/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi +++ b/boards/arm/sam_v71_xult/sam_v71_xult-common.dtsi @@ -54,6 +54,85 @@ gpios = <&piob 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; }; }; + + ext1_header: xplained-pro-connector1 { + compatible = "atmel-xplained-pro-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &pioc 31 0>, /* AFE1 AD6 */ + <1 0 &pioa 19 0>, /* AFE0 AD8 */ + <2 0 &piob 3 0>, /* RTS0 */ + <3 0 &piob 2 0>, /* CTS0 */ + <4 0 &pioa 0 0>, /* PWMC0_H0 */ + <5 0 &pioc 30 0>, /* TIOB5 */ + <6 0 &piod 28 0>, /* WKUP5 */ + <7 0 &pioa 5 0>, /* GPIO */ + <8 0 &pioa 3 0>, /* TWD0 EXT2 */ + <9 0 &pioa 4 0>, /* TWCK0 EXT2 */ + <10 0 &piob 0 0>, /* RXD0 */ + <11 0 &piob 1 0>, /* TXD0 */ + <12 0 &piod 25 0>, /* SPI0(NPCS1) */ + <13 0 &piod 21 0>, /* SPI0(MOSI) EXT2 */ + <14 0 &piod 20 0>, /* SPI0(MISO) EXT2 */ + <15 0 &piod 22 0>; /* SPI0(SCK) EXT2 */ + /* GND */ + /* +3.3V */ + }; + + ext2_header: xplained-pro-connector2 { + compatible = "atmel-xplained-pro-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &piod 30 0>, /* AFE0 AD0 */ + <1 0 &pioc 13 0>, /* AFE1 AD1 */ + <2 0 &pioa 6 0>, /* GPIO */ + <3 0 &piod 11 0>, /* GPIO */ + <4 0 &pioc 19 0>, /* PWMC0_H2 */ + <5 0 &piod 26 0>, /* PWMC0_L2 */ + <6 0 &pioa 2 0>, /* WKUP2 */ + <7 0 &pioa 24 0>, /* GPIO */ + <8 0 &pioa 3 0>, /* TWD0 EXT1 */ + <9 0 &pioa 4 0>, /* TWCK0 EXT1 */ + <10 0 &pioa 21 0>, /* RXD1 */ + <11 0 &piob 4 0>, /* TXD1 */ + <12 0 &piod 27 0>, /* SPI0(NPCS3) */ + <13 0 &piod 21 0>, /* SPI0(MOSI) EXT1 */ + <14 0 &piod 20 0>, /* SPI0(MISO) EXT1 */ + <15 0 &piod 22 0>; /* SPI0(SCK) EXT1 */ + /* GND */ + /* +3.3V */ + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; /* Shared */ + gpio-map = <0 0 &piod 26 0>, /* A0-TD */ + <1 0 &pioc 31 0>, /* A1-AFE1 AD6 y */ + <2 0 &pioa 19 0>, /* A2-AFE0 AD8 y */ + <3 0 &piod 30 0>, /* A3-AFE0 AD0 y */ + <4 0 &pioc 13 0>, /* A4-AFE1 AD1 y */ + <5 0 &pioe 0 0>, /* A5-AFE1 AD11 */ + <6 0 &piod 28 0>, /* D0-URXD3 */ + <7 0 &piod 30 0>, /* D1-UTXD3 */ + <8 0 &pioa 0 0>, /* D2-PWMC0_H0 */ + <9 0 &pioa 6 0>, /* D3-GPIO */ + <10 0 &piod 27 0>, /* D4-SPI0_NPCS3 y */ + <11 0 &piod 11 0>, /* D5-PWMC0_H0 */ + <12 0 &pioc 19 0>, /* D6-PWMC0_H2 */ + <13 0 &pioa 2 0>, /* D7-PWMC0_H1 */ + <14 0 &pioa 5 0>, /* D8-PWMC1_PWML3 */ + <15 0 &pioc 9 0>, /* D9-TIOB7 */ + <16 0 &piod 25 0>, /* D10-SPI0_NPCS1 y */ + <17 0 &piod 21 0>, /* D11-SPI0_MOSI y */ + <18 0 &piod 20 0>, /* D12-SPI0_MISO y */ + <19 0 &piod 22 0>, /* D13-SPI0_SPCK y */ + <20 0 &pioa 3 0>, /* D14-TWD0 y */ + <21 0 &pioa 4 0>; /* D15-TWCK0 y */ + }; }; &cpu0 { @@ -78,6 +157,15 @@ &spi0 { status = "okay"; + + pinctrl-0 = <&pd20b_spi0_miso + &pd21b_spi0_mosi + &pd22b_spi0_spck + &pd25b_spi0_npcs1 + &pd27b_spi0_npcs3>; + + cs-gpios = <&piod 25 GPIO_ACTIVE_LOW>, + <&piod 27 GPIO_ACTIVE_LOW>; }; &usart1 { @@ -85,6 +173,13 @@ status = "okay"; }; +&uart3 { + status = "okay"; + + pinctrl-0 = <&pd28a_uart3_urxd3 &pd30a_uart3_utxd3>; + current-speed = <115200>; +}; + &wdt { status = "okay"; }; @@ -165,3 +260,30 @@ pinctrl-0 = <&pd24b_ssc_rf &pa22a_ssc_rk &pa10c_ssc_rd &pb0d_ssc_tf &pb1d_ssc_tk &pb5d_ssc_td>; }; + +ext1_spi: &spi0 { +}; + +ext1_i2c: &twihs0 { +}; + +ext1_serial: &usart0 { +}; + +ext2_spi: &spi0 { +}; + +ext2_i2c: &twihs0 { +}; + +ext2_serial: &usart1 { +}; + +arduino_spi: &spi0 { +}; + +arduino_i2c: &twihs0 { +}; + +arduino_serial: &uart3 { +}; diff --git a/boards/arm/sam_v71_xult/sam_v71_xult.yaml b/boards/arm/sam_v71_xult/sam_v71_xult.yaml index f9f05b5840bfd9..276259babbc71c 100644 --- a/boards/arm/sam_v71_xult/sam_v71_xult.yaml +++ b/boards/arm/sam_v71_xult/sam_v71_xult.yaml @@ -9,8 +9,15 @@ toolchain: supported: - netif:eth - adc + - arduino_gpio + - arduino_i2c + - arduino_spi - gpio - spi - watchdog - usb_device - pwm + - xpro_gpio + - xpro_i2c + - xpro_serial + - xpro_spi diff --git a/boards/arm/sam_v71_xult/sam_v71_xult_defconfig b/boards/arm/sam_v71_xult/sam_v71_xult_defconfig index d101f5e0987b22..1f55d364fa1ab5 100644 --- a/boards/arm/sam_v71_xult/sam_v71_xult_defconfig +++ b/boards/arm/sam_v71_xult/sam_v71_xult_defconfig @@ -12,4 +12,9 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_USART_SAM=y +CONFIG_BOARD_SAM_V71_XULT=y CONFIG_WDT_DISABLE_AT_BOOT=y +CONFIG_BUILD_OUTPUT_HEX=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/sam_v71_xult/sam_v71b_xult.yaml b/boards/arm/sam_v71_xult/sam_v71b_xult.yaml index 30c539a6b35ce0..c23d48c313f406 100644 --- a/boards/arm/sam_v71_xult/sam_v71b_xult.yaml +++ b/boards/arm/sam_v71_xult/sam_v71b_xult.yaml @@ -9,8 +9,15 @@ toolchain: supported: - netif:eth - adc + - arduino_gpio + - arduino_i2c + - arduino_spi - gpio - spi - watchdog - usb_device - pwm + - xpro_gpio + - xpro_i2c + - xpro_serial + - xpro_spi diff --git a/boards/arm/sam_v71_xult/sam_v71b_xult_defconfig b/boards/arm/sam_v71_xult/sam_v71b_xult_defconfig index f782e75864a552..e808a2d6b52ebb 100644 --- a/boards/arm/sam_v71_xult/sam_v71b_xult_defconfig +++ b/boards/arm/sam_v71_xult/sam_v71b_xult_defconfig @@ -12,3 +12,6 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_USART_SAM=y +CONFIG_BOARD_SAM_V71_XULT=y +CONFIG_WDT_DISABLE_AT_BOOT=y +CONFIG_BUILD_OUTPUT_HEX=y diff --git a/boards/arm/seeeduino_xiao/CMakeLists.txt b/boards/arm/seeeduino_xiao/CMakeLists.txt new file mode 100644 index 00000000000000..69ff5e8fbf8390 --- /dev/null +++ b/boards/arm/seeeduino_xiao/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_PINMUX_SAM0) + zephyr_library() + zephyr_library_sources(pinmux.c) +endif() diff --git a/boards/arm/seeeduino_xiao/Kconfig.board b/boards/arm/seeeduino_xiao/Kconfig.board new file mode 100644 index 00000000000000..fb5a3d971b5ad8 --- /dev/null +++ b/boards/arm/seeeduino_xiao/Kconfig.board @@ -0,0 +1,8 @@ +# Seeeduino XIAO board configuration + +# Copyright (c) 2020 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SEEEDUINO_XIAO + bool "Seeeduino XIAO" + depends on SOC_PART_NUMBER_SAMD21G18A diff --git a/boards/arm/seeeduino_xiao/Kconfig.defconfig b/boards/arm/seeeduino_xiao/Kconfig.defconfig new file mode 100644 index 00000000000000..fb8f07b2e9da57 --- /dev/null +++ b/boards/arm/seeeduino_xiao/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Seeedunio XIAO board configuration + +# Copyright (c) 2020 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "seeeduino_xiao" + depends on BOARD_SEEEDUINO_XIAO diff --git a/boards/arm/seeeduino_xiao/board.cmake b/boards/arm/seeeduino_xiao/board.cmake new file mode 100644 index 00000000000000..e240a42f36a39c --- /dev/null +++ b/boards/arm/seeeduino_xiao/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2020 Google LLC. +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/seeeduino_xiao/doc/img/seeeduino_xiao.png b/boards/arm/seeeduino_xiao/doc/img/seeeduino_xiao.png new file mode 100644 index 00000000000000..910a9f08a3b557 Binary files /dev/null and b/boards/arm/seeeduino_xiao/doc/img/seeeduino_xiao.png differ diff --git a/boards/arm/seeeduino_xiao/doc/index.rst b/boards/arm/seeeduino_xiao/doc/index.rst new file mode 100644 index 00000000000000..eec366cdd97290 --- /dev/null +++ b/boards/arm/seeeduino_xiao/doc/index.rst @@ -0,0 +1,161 @@ +.. _seeeduino_xiao: + +Seeeduino XIAO +############## + +Overview +******** + +The Seeeduino XIAO is a tiny (20 mm x 17.5 mm) ARM development +board with onboard LEDs, USB port, and range of I/O broken out +onto 14 pins. + +.. image:: img/seeeduino_xiao.png + :width: 500px + :align: center + :alt: Seeeduino XIAO + +Hardware +******** + +- ATSAMD21G18A ARM Cortex-M0+ processor at 48 MHz +- 256 KiB flash memory and 32 KiB of RAM +- Three user LEDs +- Native USB port + +Supported Features +================== + +The seeeduino_xiao board configuration supports the following hardware +features: + ++-----------+------------+------------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+==========================================+ +| DMA | on-chip | Direct memory access | ++-----------+------------+------------------------------------------+ +| Flash | on-chip | Can be used with LittleFS to store files | ++-----------+------------+------------------------------------------+ +| GPIO | on-chip | I/O ports | ++-----------+------------+------------------------------------------+ +| HWINFO | on-chip | Hardware info | ++-----------+------------+------------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+------------------------------------------+ +| SPI | on-chip | Serial Peripheral Interface ports | ++-----------+------------+------------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+------------------------------------------+ +| USART | on-chip | Serial ports | ++-----------+------------+------------------------------------------+ +| USB | on-chip | USB device | ++-----------+------------+------------------------------------------+ +| WDT | on-chip | Watchdog | ++-----------+------------+------------------------------------------+ + +Other hardware features are not currently supported by Zephyr. + +The default configuration can be found in the Kconfig file +:zephyr_file:`boards/arm/seeeduino_xiao/seeeduino_xiao_defconfig`. + +Connections and IOs +=================== + +The `Seeeduino XIAO wiki`_ has detailed information about +the board including `pinouts`_ and the `schematic`_. + +System Clock +============ + +The SAMD21 MCU is configured to use the 32 kHz external crystal +with the on-chip PLL generating the 48 MHz system clock. The internal +APB and GCLK unit are set up in the same way as the upstream Arduino +libraries. + +SPI Port +======== + +The SAMD21 MCU has 6 SERCOM based SPIs. On the XIAO, SERCOM0 can be put +into SPI mode and used to connect to devices over pin 9 (MISO), pin 10 +(MOSI), and pin 8 (SCK). + +Serial Port +=========== + +The SAMD21 MCU has 6 SERCOM based USARTs. On the XIAO, SERCOM4 is +the Zephyr console and is available on pins 7 (RX) and 6 (TX). + +USB Device Port +=============== + +The SAMD21 MCU has a USB device port that can be used to communicate +with a host PC. See the :ref:`usb-samples` sample applications for +more, such as the :ref:`usb_cdc-acm` sample which sets up a virtual +serial port that echos characters back to the host PC. + +Programming and Debugging +************************* + +The XIAO ships the BOSSA compatible UF2 bootloader. The bootloader can be +entered by shorting the RST and GND pads twice. + +Additionally, if :code:`CONFIG_USB_CDC_ACM` is enabled then the bootloader +will be entered automatically when you run :code:`west flash`. + +Flashing +======== + +#. Build the Zephyr kernel and the :ref:`hello_world` sample application: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: seeeduino_xiao + :goals: build + :compact: + +#. Connect the XIAO to your host computer using USB + +#. Connect a 3.3 V USB to serial adapter to the board and to the + host. See the `Serial Port`_ section above for the board's pin + connections. + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyUSB0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyUSB0 -o + + The -o option tells minicom not to send the modem initialization + string. Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + +#. Short the RST and GND pads twice quickly to enter bootloader mode + +#. Flash the image: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: seeeduino_xiao + :goals: flash + :compact: + + You should see "Hello World! seeeduino_xiao" in your terminal. + +References +********** + +.. target-notes:: + +.. _Seeeduino XIAO wiki: + https://wiki.seeedstudio.com/Seeeduino-XIAO/ + +.. _pinouts: + https://wiki.seeedstudio.com/Seeeduino-XIAO/#hardware-overview + +.. _schematic: + https://wiki.seeedstudio.com/Seeeduino-XIAO/#resourses diff --git a/boards/arm/seeeduino_xiao/pinmux.c b/boards/arm/seeeduino_xiao/pinmux.c new file mode 100644 index 00000000000000..3a7ec75bf0afb8 --- /dev/null +++ b/boards/arm/seeeduino_xiao/pinmux.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020 Google LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static int board_pinmux_init(const struct device *dev) +{ + const struct device *muxa = + device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + const struct device *muxb = + device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_b))); + + ARG_UNUSED(dev); + /* Prevent an unused variable error if all peripherals are disabled */ + (void)muxa; + (void)muxb; + +#if ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) + /* SERCOM4 on RX=PB9/pad 1, TX=PB8/pad 0 */ + pinmux_pin_set(muxb, 9, PINMUX_FUNC_D); + pinmux_pin_set(muxb, 8, PINMUX_FUNC_D); +#endif + +#if ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(1, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(3, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(5, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) +#warning Pin mapping may not be configured +#endif + +#if ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) + /* SPI SERCOM0 on MISO=PA5/pad 1, MOSI=PA6/pad 2, SCK=PA7/pad 3 */ + pinmux_pin_set(muxa, 5, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 6, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 7, PINMUX_FUNC_D); +#endif + +#if ATMEL_SAM0_DT_SERCOM_CHECK(1, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(3, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) +#warning Pin mapping may not be configured +#endif +#if ATMEL_SAM0_DT_SERCOM_CHECK(5, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) +#warning Pin mapping may not be configured +#endif + +#if defined(CONFIG_USB_DC_SAM0) + /* USB DP on PA25, USB DM on PA24 */ + pinmux_pin_set(muxa, 25, PINMUX_FUNC_G); + pinmux_pin_set(muxa, 24, PINMUX_FUNC_G); +#endif + + return 0; +} + +SYS_INIT(board_pinmux_init, PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY); diff --git a/boards/arm/seeeduino_xiao/seeeduino_xiao.dts b/boards/arm/seeeduino_xiao/seeeduino_xiao.dts new file mode 100644 index 00000000000000..910b80f336b501 --- /dev/null +++ b/boards/arm/seeeduino_xiao/seeeduino_xiao.dts @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020 Google LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Seeeduino XIAO"; + compatible = "seeedstudio,seeeduino-xiao"; + + chosen { + zephyr,console = &sercom4; + zephyr,shell-uart = &sercom4; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &code_partition; + }; + + leds { + compatible = "gpio-leds"; + led: led_0 { + gpios = <&porta 17 0>; + label = "LED"; + }; + rx_led: led_1 { + gpios = <&porta 18 0>; + label = "RX_LED"; + }; + tx_led: led_2 { + gpios = <&porta 19 0>; + label = "TX_LED"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led; + led1 = &rx_led; + led2 = &tx_led; + }; +}; + +&cpu0 { + clock-frequency = <48000000>; +}; + +&sercom4 { + status = "okay"; + compatible = "atmel,sam0-uart"; + current-speed = <115200>; + rxpo = <1>; + txpo = <0>; +}; + +&sercom0 { + status = "okay"; + compatible = "atmel,sam0-spi"; + dipo = <1>; + dopo = <1>; + #address-cells = <1>; + #size-cells = <0>; +}; + +&usb0 { + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "uf2"; + reg = <0x00000000 DT_SIZE_K(8)>; + read-only; + }; + + code_partition: partition@2000 { + label = "code"; + reg = <0x2000 DT_SIZE_K(256-8-16)>; + read-only; + }; + + /* + * The final 16 KiB is reserved for the application. + * Storage partition may be used by FCB or LittleFS. + */ + storage_partition: partition@3c000 { + label = "storage"; + reg = <0x0003c000 DT_SIZE_K(16)>; + }; + }; +}; diff --git a/boards/arm/seeeduino_xiao/seeeduino_xiao.yaml b/boards/arm/seeeduino_xiao/seeeduino_xiao.yaml new file mode 100644 index 00000000000000..6c1c47b2e0e73e --- /dev/null +++ b/boards/arm/seeeduino_xiao/seeeduino_xiao.yaml @@ -0,0 +1,19 @@ +identifier: seeeduino_xiao +name: Seeeduino XIAO +type: mcu +arch: arm +ram: 32 +flash: 256 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - dma + - gpio + - hwinfo + - pinmux + - spi + - uart + - usb_device + - watchdog diff --git a/boards/arm/seeeduino_xiao/seeeduino_xiao_defconfig b/boards/arm/seeeduino_xiao/seeeduino_xiao_defconfig new file mode 100644 index 00000000000000..5742083de58b6d --- /dev/null +++ b/boards/arm/seeeduino_xiao/seeeduino_xiao_defconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_SAMD21=y +CONFIG_SOC_PART_NUMBER_SAMD21G18A=y +CONFIG_BOARD_SEEEDUINO_XIAO=y +CONFIG_SOC_ATMEL_SAMD_XOSC32K=y +CONFIG_SOC_ATMEL_SAMD_XOSC32K_AS_MAIN=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_SERIAL=y +CONFIG_PINMUX=y +CONFIG_BOOTLOADER_BOSSA=y +CONFIG_BOOTLOADER_BOSSA_ADAFRUIT_UF2=y diff --git a/boards/arm/seeeduino_xiao/support/openocd.cfg b/boards/arm/seeeduino_xiao/support/openocd.cfg new file mode 100644 index 00000000000000..bf169676693b0e --- /dev/null +++ b/boards/arm/seeeduino_xiao/support/openocd.cfg @@ -0,0 +1,18 @@ +source [find interface/jlink.cfg] + +transport select swd + +set CHIPNAME atsamd21g18a +source [find target/at91samdXX.cfg] + +reset_config trst_only + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/segger_trb_stm32f407/CMakeLists.txt b/boards/arm/segger_trb_stm32f407/CMakeLists.txt new file mode 100644 index 00000000000000..9881313609aae2 --- /dev/null +++ b/boards/arm/segger_trb_stm32f407/CMakeLists.txt @@ -0,0 +1 @@ +# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/arm/segger_trb_stm32f407/Kconfig.board b/boards/arm/segger_trb_stm32f407/Kconfig.board new file mode 100644 index 00000000000000..2c1251e0bd6adc --- /dev/null +++ b/boards/arm/segger_trb_stm32f407/Kconfig.board @@ -0,0 +1,8 @@ +# SEGGER-TRB-STM32F407 board configuration + +# Copyright (c) 2020, Erwin Rol +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SEGGER_TRB_STM32F407 + bool "SEGGER STM32F407 Trace Reference Board" + depends on SOC_STM32F407XE diff --git a/boards/arm/segger_trb_stm32f407/Kconfig.defconfig b/boards/arm/segger_trb_stm32f407/Kconfig.defconfig new file mode 100644 index 00000000000000..a519fbf853f409 --- /dev/null +++ b/boards/arm/segger_trb_stm32f407/Kconfig.defconfig @@ -0,0 +1,11 @@ +# SEGGER-TRB-STM32F407 board configuration + +# Copyright (c) 2020, Erwin Rol +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SEGGER_TRB_STM32F407 + +config BOARD + default "segger_trb_stm32f407" + +endif # BOARD_SEGGER_TRB_STM32F407 diff --git a/boards/arm/segger_trb_stm32f407/board.cmake b/boards/arm/segger_trb_stm32f407/board.cmake new file mode 100644 index 00000000000000..5f3e8d288283a0 --- /dev/null +++ b/boards/arm/segger_trb_stm32f407/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32F407VE" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/segger_trb_stm32f407/doc/img/segger_trb_stm32f407.png b/boards/arm/segger_trb_stm32f407/doc/img/segger_trb_stm32f407.png new file mode 100644 index 00000000000000..4d026b1dfd773f Binary files /dev/null and b/boards/arm/segger_trb_stm32f407/doc/img/segger_trb_stm32f407.png differ diff --git a/boards/arm/segger_trb_stm32f407/doc/index.rst b/boards/arm/segger_trb_stm32f407/doc/index.rst new file mode 100644 index 00000000000000..3c48bcbb1734ed --- /dev/null +++ b/boards/arm/segger_trb_stm32f407/doc/index.rst @@ -0,0 +1,138 @@ +.. _segger_trb_stm32f407: + +Cortex-M Trace Reference Board V1.2 +################################### + +Overview +******** + +The Cortex-M Trace Reference Board V1.2 (SEGGER-TRB-STM32F407 for short) +board is a reference board, based on the ST Microelectronics STM32F407VE +ARM Cortex-M4 CPU, to test hardware tracing with the SEGGER Trace-Pro +debuggers. It is not meant for general prototype development because +it is extremely limited when it comes to IO, and only has 3 LEDs. + +.. figure:: img/segger_trb_stm32f407.png + :width: 500px + :align: center + :height: 365px + :alt: SEGGER-TRB-STM32F407 + + SEGGER-TRB-STM32F407 + +Hardware +******** + +Information about the board can be found at the `SEGGER website`_ . +The `ST STM32F407VE website`_ contains the processor's information +and the datasheet. + +Supported Features +================== + +The SEGGER-TRB-STM32F407 board configuration supports the following +hardware features: + ++------------+------------+------------------------------+ +| Interface | Controller | Driver/Component | ++============+============+==============================+ +| NVIC | on-chip | nested vectored | +| | | interrupt controller | ++------------+------------+------------------------------+ +| SYSTICK | on-chip | system clock | ++------------+------------+------------------------------+ +| GPIO | on-chip | gpio | ++------------+------------+------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++------------+------------+------------------------------+ +| COUNTER | on-chip | rtc | ++------------+------------+------------------------------+ +| RNG | on-chip | True Random number generator | ++------------+------------+------------------------------+ + + +Other hardware features are not supported by the Zephyr kernel. + +Pin Mapping +=========== + +LED +--- + +* LED0 (green) = PA8 +* LED1 (green) = PA9 +* LED2 (green) = PA10 + +External Connectors +------------------- + +JTAG/SWD debug + ++-------+--------------+-------+--------------+ +| PIN # | Signal Name | Pin # | Signal Name | ++=======+==============+=======+==============+ +| 1 | VTref | 2 | SWDIO/TMS | ++-------+--------------+-------+--------------+ +| 3 | GND | 4 | SWCLK/TCK | ++-------+--------------+-------+--------------+ +| 5 | GND | 6 | SWO/TDO | ++-------+--------------+-------+--------------+ +| 7 | --- | 8 | TDI | ++-------+--------------+-------+--------------+ +| 9 | NC | 10 | nRESET | ++-------+--------------+-------+--------------+ +| 11 | 5V-Supply | 12 | TRACECLK | ++-------+--------------+-------+--------------+ +| 13 | 5V-Supply | 14 | TRACEDATA[0] | ++-------+--------------+-------+--------------+ +| 15 | GND | 16 | TRACEDATA[1] | ++-------+--------------+-------+--------------+ +| 17 | GND | 18 | TRACEDATA[2] | ++-------+--------------+-------+--------------+ +| 19 | GND | 20 | TRACEDATA[3] | ++-------+--------------+-------+--------------+ + + +System Clock +============ + +SEGGER-STM32F407-TRB has one external oscillator. The frequency of +the main clock is 12 MHz. The processor can setup HSE to drive the +master clock, which can be set as high as 168 MHz. + +Programming and Debugging +************************* +The SEGGER-TRB-STM32F407 board is specially designed to test the SEGGER +Trace-Pro debuggers, so this example assumes a J-Trace or J-Link is used. + +Flashing an application to the SEGGER-TRB-STM32F407 +=================================================== + +Connect the J-Trace/J-Link USB dongle to your host computer and to the JTAG +port of the SEGGER-TRB-STM32F407 board. Then build and flash an application. + +Here is an example for the :ref:`blinky-sample` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: segger_trb_stm32f407 + :goals: build flash + +After resetting the board, you should see LED0 blink with a 1 second interval. + +Debugging +========= + +Here is an example for the :ref:`blinky-sample` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: segger_trb_stm32f407 + :maybe-skip-config: + :goals: debug + +.. _SEGGER website: + https://www.segger.com/products/debug-probes/j-trace/accessories/trace-reference-boards/overview/ + +.. _ST STM32F407VE website: + https://www.st.com/en/microcontrollers-microprocessors/stm32f407ve.html diff --git a/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.dts b/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.dts new file mode 100644 index 00000000000000..9f6882990064e7 --- /dev/null +++ b/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.dts @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, Erwin Rol + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "SEGGER STM32F407 Trace Reference Board"; + compatible = "segger,trb-stm32f407"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,ccm = &ccm0; + }; + + aliases { + led0 = &led_0_green; + led1 = &led_1_green; + led2 = &led_2_green; + }; + + leds { + compatible = "gpio-leds"; + led_0_green: led_0_green { + gpios = <&gpioa 8 GPIO_ACTIVE_HIGH>; + label = "LED0"; + }; + led_1_green: led_1_green { + gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>; + label = "LED1"; + }; + led_2_green: led_2_green { + gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>; + label = "LED2"; + }; + }; +}; + +&rtc { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; diff --git a/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.yaml b/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.yaml new file mode 100644 index 00000000000000..594663d6a39c14 --- /dev/null +++ b/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407.yaml @@ -0,0 +1,19 @@ +identifier: segger_trb_stm32f407 +name: Cortex-M Trace Reference Board V1.2 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 192 +flash: 512 +supported: + - counter + - gpio + - watchdog +testing: + ignore_tags: + - net + - shell + - console diff --git a/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407_defconfig b/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407_defconfig new file mode 100644 index 00000000000000..cf0a79c008dd9b --- /dev/null +++ b/boards/arm/segger_trb_stm32f407/segger_trb_stm32f407_defconfig @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32F4X=y +CONFIG_SOC_STM32F407XE=y +# 168MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable RTT +CONFIG_USE_SEGGER_RTT=y + +CONFIG_CONSOLE=y +CONFIG_RTT_CONSOLE=y + +# no serial port +CONFIG_SERIAL=n +CONFIG_UART_STM32=n + +# enable GPIO +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y + +# Clock configuration for Cube Clock control driver +CONFIG_CLOCK_STM32_HSE_CLOCK=12000000 +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# use HSE as PLL input +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# produce 168MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=6 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=168 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=7 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=4 +CONFIG_CLOCK_STM32_APB2_PRESCALER=2 diff --git a/boards/arm/sensortile_box/CMakeLists.txt b/boards/arm/sensortile_box/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/sensortile_box/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/sensortile_box/pinmux.c b/boards/arm/sensortile_box/pinmux.c deleted file mode 100644 index eea15a0ec2b0bb..00000000000000 --- a/boards/arm/sensortile_box/pinmux.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2019 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for SensorTile.box board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32L4X_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32L4X_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L4X_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L4X_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32L4X_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32L4X_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PG7, STM32L4X_PINMUX_FUNC_PG7_I2C3_SCL}, - {STM32_PIN_PG8, STM32L4X_PINMUX_FUNC_PG8_I2C3_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PE12, STM32L4X_PINMUX_FUNC_PE12_SPI1_NSS}, - {STM32_PIN_PE13, STM32L4X_PINMUX_FUNC_PE13_SPI1_SCK}, - {STM32_PIN_PE14, STM32L4X_PINMUX_FUNC_PE14_SPI1_MISO}, - {STM32_PIN_PE15, STM32L4X_PINMUX_FUNC_PE15_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - /* SPI2 on the ST Morpho Connector CN10 pins 16, 30, 28, 26*/ - {STM32_PIN_PB12, STM32L4X_PINMUX_FUNC_PB12_SPI2_NSS}, - {STM32_PIN_PB13, STM32L4X_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32L4X_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32L4X_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi3), okay) && CONFIG_SPI - {STM32_PIN_PA15, STM32L4X_PINMUX_FUNC_PA15_SPI3_NSS}, - {STM32_PIN_PB3, STM32L4X_PINMUX_FUNC_PB3_SPI3_SCK}, - {STM32_PIN_PB4, STM32L4X_PINMUX_FUNC_PB4_SPI3_MISO}, - {STM32_PIN_PB5, STM32L4X_PINMUX_FUNC_PB5_SPI3_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32L4X_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32L4X_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/sensortile_box/sensortile_box.dts b/boards/arm/sensortile_box/sensortile_box.dts index e1214bb6bf89c2..8418f5fc84b8e9 100644 --- a/boards/arm/sensortile_box/sensortile_box.dts +++ b/boards/arm/sensortile_box/sensortile_box.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics SensorTile.box board"; - compatible = "st,sensortile-box", "st,stm32l4r9"; + compatible = "st,sensortile-box"; chosen { zephyr,console = &usart1; @@ -31,23 +32,35 @@ }; }; + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User PB1"; + gpios = <&gpiog 1 GPIO_ACTIVE_LOW>; + }; + }; + aliases { led0 = &blue_led; led1 = &green_led; + sw0 = &user_button; }; }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; @@ -67,6 +80,7 @@ }; &i2c3 { + pinctrl-0 = <&i2c3_scl_pg7 &i2c3_sda_pg8>; status = "okay"; clock-frequency = ; @@ -79,9 +93,11 @@ }; &spi1 { + pinctrl-0 = <&spi1_nss_pe12 &spi1_sck_pe13 + &spi1_miso_pe14 &spi1_mosi_pe15>; status = "okay"; - cs-gpios = <&gpioe 11 0>, <&gpioe 12 0>, <&gpioe 10 0>; + cs-gpios = <&gpioe 11 GPIO_ACTIVE_LOW>, <&gpioe 12 GPIO_ACTIVE_LOW>, <&gpioe 10 GPIO_ACTIVE_LOW>; lis2dw12@0 { compatible = "st,lis2dw12"; @@ -109,9 +125,11 @@ }; &spi3 { + pinctrl-0 = <&spi3_nss_pa15 &spi3_sck_pb3 + &spi3_miso_pb4 &spi3_mosi_pb5>; status = "okay"; - cs-gpios = <&gpioa 15 0>; + cs-gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; lis2mdl@0 { compatible = "st,lis2mdl"; @@ -122,6 +140,7 @@ }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; @@ -138,10 +157,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/sensortile_box/sensortile_box_defconfig b/boards/arm/sensortile_box/sensortile_box_defconfig index 043a31d0c18af6..2c1d1f321c51fd 100644 --- a/boards/arm/sensortile_box/sensortile_box_defconfig +++ b/boards/arm/sensortile_box/sensortile_box_defconfig @@ -57,3 +57,6 @@ CONFIG_UART_CONSOLE=y # Enable MPU CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/serpente/CMakeLists.txt b/boards/arm/serpente/CMakeLists.txt new file mode 100644 index 00000000000000..69ff5e8fbf8390 --- /dev/null +++ b/boards/arm/serpente/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_PINMUX_SAM0) + zephyr_library() + zephyr_library_sources(pinmux.c) +endif() diff --git a/boards/arm/serpente/Kconfig.board b/boards/arm/serpente/Kconfig.board new file mode 100644 index 00000000000000..5c2cb6dc83ef05 --- /dev/null +++ b/boards/arm/serpente/Kconfig.board @@ -0,0 +1,7 @@ +# Serpente board configuration +# Copyright (c) 2020 Alexander Falb +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SERPENTE + bool "Serpente" + depends on SOC_PART_NUMBER_SAMD21E18A diff --git a/boards/arm/serpente/Kconfig.defconfig b/boards/arm/serpente/Kconfig.defconfig new file mode 100644 index 00000000000000..911f7021ff7cc6 --- /dev/null +++ b/boards/arm/serpente/Kconfig.defconfig @@ -0,0 +1,7 @@ +# Serpente board configuration +# Copyright (c) 2020 Alexander Falb +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "serpente" + depends on BOARD_SERPENTE diff --git a/boards/arm/serpente/board.cmake b/boards/arm/serpente/board.cmake new file mode 100644 index 00000000000000..cb4ff22b5cc222 --- /dev/null +++ b/boards/arm/serpente/board.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake) diff --git a/boards/arm/serpente/doc/img/serpente.jpg b/boards/arm/serpente/doc/img/serpente.jpg new file mode 100644 index 00000000000000..e2cd4b52304c06 Binary files /dev/null and b/boards/arm/serpente/doc/img/serpente.jpg differ diff --git a/boards/arm/serpente/doc/index.rst b/boards/arm/serpente/doc/index.rst new file mode 100644 index 00000000000000..3c4a3a746c1d84 --- /dev/null +++ b/boards/arm/serpente/doc/index.rst @@ -0,0 +1,126 @@ +.. _serpente: + +Arturo182 Serpente +################## + +Overview +******** + +The Serpente is a very small low-cost development and prototyping +board equipped with 4MiB flash storage, a PWM enabled RGB led and 6 I/O pins. +The board comes with 3 different USB connector options: USB Type-C plug, +USB Type-C socket and USB Type-A plug. + +.. image:: img/serpente.jpg + :width: 640px + :align: center + :alt: Serpente Baords + +Hardware +******** + +- ATSAMD21E18A ARM Cortex-M0+ processor at 48 MHz +- 256 KiB flash memory and 32 KiB of RAM +- Extra 4MiB SPI flash memory +- RGB User LED +- Reset button +- Native USB port + +Supported Features +================== + +The Serpente board configuration supports the +following hardware features: + ++-----------+------------+------------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+==========================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+------------------------------------------+ +| Flash | on-chip | Can be used with LittleFS to store files | ++-----------+------------+------------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+------------------------------------------+ +| WDT | on-chip | Watchdog | ++-----------+------------+------------------------------------------+ +| GPIO | on-chip | I/O ports | ++-----------+------------+------------------------------------------+ +| PWM | on-chip | Pulse Width Modulation | ++-----------+------------+------------------------------------------+ +| USART | on-chip | Serial ports | ++-----------+------------+------------------------------------------+ +| SPI | on-chip | Serial Peripheral Interface ports | ++-----------+------------+------------------------------------------+ +| USB | on-chip | USB device | ++-----------+------------+------------------------------------------+ + +Other hardware features are not currently supported by Zephyr. + +The default configuration can be found in the Kconfig file +:zephyr_file:`boards/arm/serpente/serpente_defconfig`. + +Connections and IOs +=================== + +The `Serpente documentation`_ has detailed information about the board +including `pinouts`_ and the `schematic`_. + +System Clock +============ + +The SAMD21 MCU is configured to use the 8MHz internal oscillator +with the on-chip PLL generating the 48 MHz system clock. + +USB Device Port +=============== + +The SAMD21 MCU has a USB device port that can be used to communicate +with a host PC. See the :ref:`usb-samples` sample applications for +more, such as the :ref:`usb_cdc-acm` sample which prints "Hello World!" +to the host PC. + +Programming and Debugging +========================= + +The Serpente ships the BOSSA compatible UF2 bootloader. The bootloader +can be entered by quickly tapping the reset button twice. + +Flashing +======== + +#. Build the Zephyr kernel and the :ref:`blinky-sample` sample application: + + .. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: serpente + :goals: build + :compact: + +#. Connect the Serpente to your host computer using USB + + +#. Tap the reset button twice quickly to enter bootloader mode + +#. Flash the image: + + .. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: serpente + :goals: flash + :compact: + + You should see the User LED blink. + +References +********** + +.. target-notes:: + +.. _Serpente documentation: + https://serpente.solder.party/r2/ + +.. _pinouts: + https://serpente.solder.party/r2/docs/pinout/ + +.. _schematic: + https://serpente.solder.party/r2/docs/downloads/ diff --git a/boards/arm/serpente/pinmux.c b/boards/arm/serpente/pinmux.c new file mode 100644 index 00000000000000..db646bb0c50aeb --- /dev/null +++ b/boards/arm/serpente/pinmux.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 Alexander Falb + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static int board_pinmux_init(const struct device *dev) +{ + const struct device *muxa = + device_get_binding(DT_LABEL(DT_NODELABEL(pinmux_a))); + + ARG_UNUSED(dev); + + /* sercom 3 is always spi - it is the onboard flash */ + /* SPI SERCOM3 on MISO=PA18, MOSI=PA16, SCK=PA17, CS=PA15*/ + pinmux_pin_set(muxa, 18, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 16, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 17, PINMUX_FUNC_D); + + +#if ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_spi) && defined(CONFIG_SPI_SAM0) + /* SPI SERCOM0 on MISO=PA6, MOSI=PA4, SCK=PA5 */ + pinmux_pin_set(muxa, 6, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 4, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 5, PINMUX_FUNC_D); +#endif + +#if ATMEL_SAM0_DT_SERCOM_CHECK(0, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) + /* SERCOM0 on RX=PA5, TX=PA4 */ + pinmux_pin_set(muxa, 5, PINMUX_FUNC_C); + pinmux_pin_set(muxa, 4, PINMUX_FUNC_C); +#endif + +#if ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_i2c) && defined(CONFIG_I2C_SAM0) + /* SERCOM2 on SDA=PA08, SCL=PA09 */ + pinmux_pin_set(muxa, 4, PINMUX_FUNC_D); + pinmux_pin_set(muxa, 5, PINMUX_FUNC_D); +#endif + +#if ATMEL_SAM0_DT_SERCOM_CHECK(2, atmel_sam0_uart) && defined(CONFIG_UART_SAM0) + /* SERCOM0 on RX=PA9, TX=PA8 */ + pinmux_pin_set(muxa, 9, PINMUX_FUNC_C); + pinmux_pin_set(muxa, 8, PINMUX_FUNC_C); +#endif + +#ifdef CONFIG_USB_DC_SAM0 + /* USB DP on PA25, USB DM on PA24 */ + pinmux_pin_set(muxa, 25, PINMUX_FUNC_G); + pinmux_pin_set(muxa, 24, PINMUX_FUNC_G); +#endif + +#if (ATMEL_SAM0_DT_TCC_CHECK(0, atmel_sam0_tcc_pwm) && CONFIG_PWM_SAM0_TCC) + /* TCC0 on WO4=PA22 (red), WO3=PA19 (green), WO5=PA23 (blue) */ + pinmux_pin_set(muxa, 22, PINMUX_FUNC_F); + pinmux_pin_set(muxa, 19, PINMUX_FUNC_F); + pinmux_pin_set(muxa, 23, PINMUX_FUNC_F); +#endif + + return 0; +} + +SYS_INIT(board_pinmux_init, PRE_KERNEL_1, CONFIG_PINMUX_INIT_PRIORITY); diff --git a/boards/arm/serpente/serpente.dts b/boards/arm/serpente/serpente.dts new file mode 100644 index 00000000000000..7d454ce026e0e1 --- /dev/null +++ b/boards/arm/serpente/serpente.dts @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2020 Alexander Falb + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Serpente"; + compatible = "arturo182,serpente"; + + chosen { + zephyr,console = &sercom2; + zephyr,shell-uart = &sercom2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &code_partition; + }; + + aliases { + led0 = &red_led; + led1 = &green_led; + led2 = &blue_led; + red-led = &red_led; + green-led = &green_led; + blue-led = &blue_led; + + pwm-led0 = &red_pwm_led; + pwm-led1 = &green_pwm_led; + pwm-led2 = &blue_pwm_led; + red-pwm-led = &red_pwm_led; + green-pwm-led = &green_pwm_led; + blue-pwm-led = &blue_pwm_led; + }; + + leds { + compatible = "gpio-leds"; + red_led: led_0 { + gpios = <&porta 22 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + green_led: led_1 { + gpios = <&porta 19 GPIO_ACTIVE_LOW>; + label = "Green LED"; + }; + blue_led: led_2 { + gpios = <&porta 23 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + red_pwm_led: pwm_led_0 { + pwms = <&tcc0 0>; + label = "Red PWM LED"; + }; + green_pwm_led: pwm_led_1 { + pwms = <&tcc0 3>; + label = "Green PWM LED"; + }; + blue_pwm_led: pwm_led_2 { + pwms = <&tcc0 1>; + label = "Blue PWM LED"; + }; + }; +}; + +&cpu0 { + clock-frequency = <48000000>; +}; + +&sercom0 { + status = "okay"; +}; + +&sercom2 { + status = "okay"; + compatible = "atmel,sam0-uart"; + current-speed = <115200>; + rxpo = <1>; + txpo = <0>; +}; + +&sercom3 { + status = "okay"; + compatible = "atmel,sam0-spi"; + dipo = <1>; + dopo = <1>; + #address-cells = <1>; + #size-cells = <0>; +}; + +&usb0 { + status = "okay"; +}; + +&tcc0 { + status = "okay"; + compatible = "atmel,sam0-tcc-pwm"; + prescaler = <4>; + #pwm-cells = <1>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "uf2"; + reg = <0x00000000 DT_SIZE_K(8)>; + read-only; + }; + + code_partition: partition@2000 { + label = "code"; + reg = <0x2000 DT_SIZE_K(256-8)>; + read-only; + }; + }; +}; diff --git a/boards/arm/serpente/serpente.yaml b/boards/arm/serpente/serpente.yaml new file mode 100644 index 00000000000000..724f8c7d1e32f6 --- /dev/null +++ b/boards/arm/serpente/serpente.yaml @@ -0,0 +1,22 @@ +identifier: serpente +name: SERPENTE +type: mcu +arch: arm +ram: 32 +flash: 256 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - counter + - gpio + - hwinfo + - i2c + - pinmux + - pwm + - spi + - uart + - usb_device + - watchdog diff --git a/boards/arm/serpente/serpente_defconfig b/boards/arm/serpente/serpente_defconfig new file mode 100644 index 00000000000000..5400ebc314b830 --- /dev/null +++ b/boards/arm/serpente/serpente_defconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_SAMD21=y +CONFIG_SOC_PART_NUMBER_SAMD21E18A=y +CONFIG_BOARD_SERPENTE=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_PINMUX=y +CONFIG_SPI=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USB=y +CONFIG_BOOTLOADER_BOSSA=y +CONFIG_BOOTLOADER_BOSSA_ADAFRUIT_UF2=y +CONFIG_WATCHDOG=y diff --git a/boards/arm/steval_fcu001v1/CMakeLists.txt b/boards/arm/steval_fcu001v1/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/steval_fcu001v1/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/steval_fcu001v1/pinmux.c b/boards/arm/steval_fcu001v1/pinmux.c deleted file mode 100644 index 1533ace21271da..00000000000000 --- a/boards/arm/steval_fcu001v1/pinmux.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2019 Linumiz - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STEVAL-FCU001V1 */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F4_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F4_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32F4_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB3, STM32F4_PINMUX_FUNC_PB3_I2C2_SDA}, - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/steval_fcu001v1/steval_fcu001v1.dts b/boards/arm/steval_fcu001v1/steval_fcu001v1.dts index 3179f9a302acc8..0f5d45f2ff4cbd 100644 --- a/boards/arm/steval_fcu001v1/steval_fcu001v1.dts +++ b/boards/arm/steval_fcu001v1/steval_fcu001v1.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics Flight Controller Board"; - compatible = "st,flight-controller-board", "st,stm32f401"; + compatible = "st,flight-controller-board"; chosen { zephyr,console = &usart1; @@ -38,11 +39,13 @@ }; &i2c2 { + pinctrl-0 = <&i2c2_sda_pb3 &i2c2_scl_pb10>; status = "okay"; clock-frequency = ; }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; @@ -52,6 +55,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; diff --git a/boards/arm/stm3210c_eval/CMakeLists.txt b/boards/arm/stm3210c_eval/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm3210c_eval/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm3210c_eval/pinmux.c b/boards/arm/stm3210c_eval/pinmux.c deleted file mode 100644 index 522389fd779fd1..00000000000000 --- a/boards/arm/stm3210c_eval/pinmux.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017 RnDity Sp. z o.o. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM3210C-EVAL board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PD5, STM32F1_PINMUX_FUNC_PD5_USART2_TX}, - {STM32_PIN_PD6, STM32F1_PINMUX_FUNC_PD6_USART2_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm3210c_eval/stm3210c_eval.dts b/boards/arm/stm3210c_eval/stm3210c_eval.dts index 68dfbea11173ff..d540a972d9aa1c 100644 --- a/boards/arm/stm3210c_eval/stm3210c_eval.dts +++ b/boards/arm/stm3210c_eval/stm3210c_eval.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM3210C-EVAL board"; - compatible = "st,stm3210c-eval", "st,stm32f107"; + compatible = "st,stm3210c-eval"; chosen { zephyr,console = &usart2; @@ -41,6 +42,7 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/stm32373c_eval/CMakeLists.txt b/boards/arm/stm32373c_eval/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32373c_eval/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32373c_eval/pinmux.c b/boards/arm/stm32373c_eval/pinmux.c deleted file mode 100644 index 1081edb9f3deda..00000000000000 --- a/boards/arm/stm32373c_eval/pinmux.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017 RnDity Sp. z o.o. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32373C-EVAL board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PD5, STM32F3_PINMUX_FUNC_PD5_USART2_TX}, - {STM32_PIN_PD6, STM32F3_PINMUX_FUNC_PD6_USART2_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32373c_eval/stm32373c_eval.dts b/boards/arm/stm32373c_eval/stm32373c_eval.dts index ef2fefdc18096d..09436011e59144 100644 --- a/boards/arm/stm32373c_eval/stm32373c_eval.dts +++ b/boards/arm/stm32373c_eval/stm32373c_eval.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32373C-EVAL board"; - compatible = "st,stm32373c-eval", "st,stm32f373"; + compatible = "st,stm32373c-eval"; chosen { zephyr,console = &usart2; @@ -41,6 +42,7 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/stm32373c_eval/stm32373c_eval_defconfig b/boards/arm/stm32373c_eval/stm32373c_eval_defconfig index 2774aecd5f458e..a2a72e16722c78 100644 --- a/boards/arm/stm32373c_eval/stm32373c_eval_defconfig +++ b/boards/arm/stm32373c_eval/stm32373c_eval_defconfig @@ -9,6 +9,12 @@ CONFIG_SOC_STM32F373XC=y # Floating Point Options CONFIG_FPU=y +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # General Kernel Options CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 diff --git a/boards/arm/stm32_min_dev/CMakeLists.txt b/boards/arm/stm32_min_dev/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32_min_dev/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32_min_dev/pinmux.c b/boards/arm/stm32_min_dev/pinmux.c deleted file mode 100644 index 216e7c4c7c8e64..00000000000000 --- a/boards/arm/stm32_min_dev/pinmux.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2017, embedjournal.com - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32_MIN_DEV board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F1_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F1_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F1_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F1_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32F1_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32F1_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32F1_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32F1_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F1_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB11, STM32F1_PINMUX_FUNC_PB11_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - {STM32_PIN_PA8, STM32F1_PINMUX_FUNC_PA8_PWM1_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F1_PINMUX_FUNC_PA4_SPI1_MASTER_NSS_OE}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F1_PINMUX_FUNC_PA5_SPI1_MASTER_SCK}, - {STM32_PIN_PA6, STM32F1_PINMUX_FUNC_PA6_SPI1_MASTER_MISO}, - {STM32_PIN_PA7, STM32F1_PINMUX_FUNC_PA7_SPI1_MASTER_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F1_PINMUX_FUNC_PB12_SPI2_MASTER_NSS_OE}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F1_PINMUX_FUNC_PB13_SPI2_MASTER_SCK}, - {STM32_PIN_PB14, STM32F1_PINMUX_FUNC_PB14_SPI2_MASTER_MISO}, - {STM32_PIN_PB15, STM32F1_PINMUX_FUNC_PB15_SPI2_MASTER_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F1_PINMUX_FUNC_PA11_USB_DM}, - {STM32_PIN_PA12, STM32F1_PINMUX_FUNC_PA12_USB_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC - {STM32_PIN_PA0, STM32F1_PINMUX_FUNC_PA0_ADC123_IN0}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32_min_dev/stm32_min_dev.dtsi b/boards/arm/stm32_min_dev/stm32_min_dev.dtsi index 873215bf70940b..61926fd86ae2c8 100644 --- a/boards/arm/stm32_min_dev/stm32_min_dev.dtsi +++ b/boards/arm/stm32_min_dev/stm32_min_dev.dtsi @@ -6,6 +6,7 @@ /dts-v1/; #include +#include / { model = "STM32 Minimum Development Board"; @@ -14,6 +15,7 @@ chosen { zephyr,console = &usart1; zephyr,shell-uart = &usart1; + zephyr,osdp-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; }; @@ -32,35 +34,44 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = < &i2c1_scl_pb6 &i2c1_sda_pb7 >; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = < &i2c2_scl_pb10 &i2c2_sda_pb11 >; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_master_pa4 &spi1_sck_master_pa5 + &spi1_miso_master_pa6 &spi1_mosi_master_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_nss_master_pb12 &spi2_sck_master_pb13 + &spi2_miso_master_pb14 &spi2_mosi_master_pb15>; status = "okay"; }; @@ -69,13 +80,16 @@ pwm1: pwm { status = "okay"; + pinctrl-0 = <&tim1_ch1_pwm_pa8>; }; }; &usb { + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; status = "okay"; }; &adc1 { + pinctrl-0 = <&adc1_in0_pa0>; status = "okay"; }; diff --git a/boards/arm/stm32_min_dev/stm32_min_dev_black.dts b/boards/arm/stm32_min_dev/stm32_min_dev_black.dts index f07fc1e8453058..8df88f45052fe7 100644 --- a/boards/arm/stm32_min_dev/stm32_min_dev_black.dts +++ b/boards/arm/stm32_min_dev/stm32_min_dev_black.dts @@ -13,7 +13,7 @@ leds { led: led { - gpios = <&gpiob 12 GPIO_ACTIVE_HIGH>; + gpios = <&gpiob 12 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/boards/arm/stm32_min_dev/stm32_min_dev_black_defconfig b/boards/arm/stm32_min_dev/stm32_min_dev_black_defconfig index 1d76bd4fb1b82f..f584392ba22f83 100644 --- a/boards/arm/stm32_min_dev/stm32_min_dev_black_defconfig +++ b/boards/arm/stm32_min_dev/stm32_min_dev_black_defconfig @@ -11,6 +11,12 @@ CONFIG_SOC_STM32F103X8=y # 72MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y @@ -32,7 +38,6 @@ CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y # use HSE as PLL input CONFIG_CLOCK_STM32_PLL_SRC_HSE=y # produce 72MHz clock at PLL output -CONFIG_CLOCK_STM32_PLL_XTPRE=n CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9 CONFIG_CLOCK_STM32_AHB_PRESCALER=1 diff --git a/boards/arm/stm32_min_dev/stm32_min_dev_blue.dts b/boards/arm/stm32_min_dev/stm32_min_dev_blue.dts index e158288dd4ca19..fe3c23e34810f0 100644 --- a/boards/arm/stm32_min_dev/stm32_min_dev_blue.dts +++ b/boards/arm/stm32_min_dev/stm32_min_dev_blue.dts @@ -13,7 +13,7 @@ leds { led: led { - gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/boards/arm/stm32_min_dev/stm32_min_dev_blue_defconfig b/boards/arm/stm32_min_dev/stm32_min_dev_blue_defconfig index 235040832a8c94..83f874138332b5 100644 --- a/boards/arm/stm32_min_dev/stm32_min_dev_blue_defconfig +++ b/boards/arm/stm32_min_dev/stm32_min_dev_blue_defconfig @@ -6,6 +6,12 @@ CONFIG_SOC_STM32F103X8=y # 72MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y @@ -27,7 +33,6 @@ CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y # use HSE as PLL input CONFIG_CLOCK_STM32_PLL_SRC_HSE=y # produce 72MHz clock at PLL output -CONFIG_CLOCK_STM32_PLL_XTPRE=n CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9 CONFIG_CLOCK_STM32_AHB_PRESCALER=1 diff --git a/boards/arm/stm32f030_demo/CMakeLists.txt b/boards/arm/stm32f030_demo/CMakeLists.txt deleted file mode 100644 index 72a40c9ca4cc3f..00000000000000 --- a/boards/arm/stm32f030_demo/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# -# Copyright (c) 2019 Antony Pavlov -# -# SPDX-License-Identifier: Apache-2.0 -# - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f030_demo/board.cmake b/boards/arm/stm32f030_demo/board.cmake index b01732ca8e9f0d..938f2ad8e50fd0 100644 --- a/boards/arm/stm32f030_demo/board.cmake +++ b/boards/arm/stm32f030_demo/board.cmake @@ -4,4 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 # +board_runner_args(stm32flash "--start-addr=0x08000000") + include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stm32flash.board.cmake) diff --git a/boards/arm/stm32f030_demo/pinmux.c b/boards/arm/stm32f030_demo/pinmux.c deleted file mode 100644 index f7e0b734085b3f..00000000000000 --- a/boards/arm/stm32f030_demo/pinmux.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2019 Antony Pavlov - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include "pinmux/pinmux.h" - -#include "pinmux/stm32/pinmux_stm32.h" - -/* pin assignments for STM32F030 DEMO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F0_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F0_PINMUX_FUNC_PA10_USART1_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f030_demo/stm32f030_demo.dts b/boards/arm/stm32f030_demo/stm32f030_demo.dts index 365769b9ed53de..4f04968bf3fb25 100644 --- a/boards/arm/stm32f030_demo/stm32f030_demo.dts +++ b/boards/arm/stm32f030_demo/stm32f030_demo.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STM32F030 DEMO board"; - compatible = "st,stm32f030-demo", "st,stm32f030f4p6", "st,stm32f030"; + compatible = "st,stm32f030-demo"; chosen { zephyr,console = &usart1; @@ -37,6 +38,7 @@ &gpiof {status = "disabled";}; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/stm32f072_eval/CMakeLists.txt b/boards/arm/stm32f072_eval/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f072_eval/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f072_eval/pinmux.c b/boards/arm/stm32f072_eval/pinmux.c deleted file mode 100644 index 94ba344ac1e9b9..00000000000000 --- a/boards/arm/stm32f072_eval/pinmux.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017 BayLibre, SAS - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include "pinmux/stm32/pinmux_stm32.h" - -/* pin assignments for STM32F072-EVAL board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PD5, STM32F0_PINMUX_FUNC_PD5_USART2_TX}, - {STM32_PIN_PD6, STM32F0_PINMUX_FUNC_PD6_USART2_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f072_eval/stm32f072_eval.dts b/boards/arm/stm32f072_eval/stm32f072_eval.dts index 268358daaf2ccb..5e072e5d559773 100644 --- a/boards/arm/stm32f072_eval/stm32f072_eval.dts +++ b/boards/arm/stm32f072_eval/stm32f072_eval.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F072-EVAL board"; - compatible = "st,stm32f072-eval", "st,stm32f072"; + compatible = "st,stm32f072-eval"; chosen { zephyr,console = &usart2; @@ -46,23 +47,23 @@ }; joy_sel: joystick_selection { label = "joystick selection"; - gpios = <&gpioa 0 GPIO_ACTIVE_LOW>; + gpios = <&gpioa 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_down: joystick_down { label = "joystick down"; - gpios = <&gpiof 10 GPIO_ACTIVE_LOW>; + gpios = <&gpiof 10 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_up: joystick_up { label = "joystick up"; - gpios = <&gpiof 9 GPIO_ACTIVE_LOW>; + gpios = <&gpiof 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_left: joystick_left { label = "joystick left"; - gpios = <&gpiof 2 GPIO_ACTIVE_LOW>; + gpios = <&gpiof 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_right: joystick_right { label = "joystick right"; - gpios = <&gpioe 3 GPIO_ACTIVE_LOW>; + gpios = <&gpioe 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; }; @@ -76,6 +77,7 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/stm32f072b_disco/CMakeLists.txt b/boards/arm/stm32f072b_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f072b_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f072b_disco/pinmux.c b/boards/arm/stm32f072b_disco/pinmux.c deleted file mode 100644 index d2383c4e0448ec..00000000000000 --- a/boards/arm/stm32f072b_disco/pinmux.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017 Clage GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include "pinmux/pinmux.h" - -#include - -/* pin assignments for STM32F072B-DISCO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F0_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F0_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F0_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F0_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F0_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB11, STM32F0_PINMUX_FUNC_PB11_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PB3, STM32F0_PINMUX_FUNC_PB3_SPI1_SCK}, - {STM32_PIN_PB4, STM32F0_PINMUX_FUNC_PB4_SPI1_MISO}, - {STM32_PIN_PB5, STM32F0_PINMUX_FUNC_PB5_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PB8, STM32F0_PINMUX_FUNC_PB8_CAN_RX}, - {STM32_PIN_PB9, STM32F0_PINMUX_FUNC_PB9_CAN_TX}, -#endif - -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f072b_disco/stm32f072b_disco.dts b/boards/arm/stm32f072b_disco/stm32f072b_disco.dts index 82939de6a1235a..55c7b8308a42e5 100644 --- a/boards/arm/stm32f072b_disco/stm32f072b_disco.dts +++ b/boards/arm/stm32f072b_disco/stm32f072b_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F072B-DISCO board"; - compatible = "st,stm32f072b-disco", "st,stm32f072"; + compatible = "st,stm32f072b-disco"; chosen { zephyr,console = &usart1; @@ -57,25 +58,30 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_sck_pb3 &spi1_miso_pb4 &spi1_mosi_pb5>; status = "okay"; }; &can1 { + pinctrl-0 = <&can_rx_pb8 &can_tx_pb9>; bus-speed = <125000>; status = "okay"; }; diff --git a/boards/arm/stm32f0_disco/CMakeLists.txt b/boards/arm/stm32f0_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f0_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f0_disco/pinmux.c b/boards/arm/stm32f0_disco/pinmux.c deleted file mode 100644 index 95365d90e6c371..00000000000000 --- a/boards/arm/stm32f0_disco/pinmux.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018 Nathan Tsoi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include "pinmux/pinmux.h" - -#include "pinmux/stm32/pinmux_stm32.h" - -/* pin assignments for STM32F0DISCOVERY board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F0_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F0_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F0_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F0_PINMUX_FUNC_PA3_USART2_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f0_disco/stm32f0_disco.dts b/boards/arm/stm32f0_disco/stm32f0_disco.dts index 4c387b8509ae1c..bc3f32d9b36b2f 100644 --- a/boards/arm/stm32f0_disco/stm32f0_disco.dts +++ b/boards/arm/stm32f0_disco/stm32f0_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F0DISCOVERY board"; - compatible = "st,stm32f058r8-discovery", "st,stm32f051"; + compatible = "st,stm32f058r8-discovery"; chosen { zephyr,console = &usart1; @@ -51,11 +52,13 @@ &gpiof {status = "disabled";}; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/stm32f103_mini/Kconfig.board b/boards/arm/stm32f103_mini/Kconfig.board new file mode 100644 index 00000000000000..c719f989076c51 --- /dev/null +++ b/boards/arm/stm32f103_mini/Kconfig.board @@ -0,0 +1,8 @@ +# STM32F103RCT6 Mini board configuration + +# Copyright (c) 2020 WuhanStudio +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_STM32F103_MINI + bool "STM32F103RCT6 Mini Board" + depends on SOC_STM32F103XE diff --git a/boards/arm/stm32f103_mini/Kconfig.defconfig b/boards/arm/stm32f103_mini/Kconfig.defconfig new file mode 100644 index 00000000000000..294d123ccb1702 --- /dev/null +++ b/boards/arm/stm32f103_mini/Kconfig.defconfig @@ -0,0 +1,11 @@ +# STM32F103RCT6 Mini board configuration + +# Copyright (c) 2020 WuhanStudio +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_STM32F103_MINI + +config BOARD + default "stm32f103_mini" + +endif # BOARD_STM32F103_mini diff --git a/boards/arm/stm32f103_mini/board.cmake b/boards/arm/stm32f103_mini/board.cmake new file mode 100644 index 00000000000000..20016aaba8e7ed --- /dev/null +++ b/boards/arm/stm32f103_mini/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32F103RC" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/stm32f103_mini/doc/img/stm32f103_mini_blue.jpg b/boards/arm/stm32f103_mini/doc/img/stm32f103_mini_blue.jpg new file mode 100644 index 00000000000000..5190c82e89559b Binary files /dev/null and b/boards/arm/stm32f103_mini/doc/img/stm32f103_mini_blue.jpg differ diff --git a/boards/arm/stm32f103_mini/doc/img/stm32f103_mini_pin.jpg b/boards/arm/stm32f103_mini/doc/img/stm32f103_mini_pin.jpg new file mode 100644 index 00000000000000..1108e0344af880 Binary files /dev/null and b/boards/arm/stm32f103_mini/doc/img/stm32f103_mini_pin.jpg differ diff --git a/boards/arm/stm32f103_mini/doc/img/stm32f103_mini_yellow.jpg b/boards/arm/stm32f103_mini/doc/img/stm32f103_mini_yellow.jpg new file mode 100644 index 00000000000000..2e1fcd471ae0cb Binary files /dev/null and b/boards/arm/stm32f103_mini/doc/img/stm32f103_mini_yellow.jpg differ diff --git a/boards/arm/stm32f103_mini/doc/index.rst b/boards/arm/stm32f103_mini/doc/index.rst new file mode 100644 index 00000000000000..f337bac1b9ecad --- /dev/null +++ b/boards/arm/stm32f103_mini/doc/index.rst @@ -0,0 +1,160 @@ +.. _stm32f103_mini_board: + +STM32F103 Mini +################ + +Overview +******** + +The STM32F103_MINI board features an ARM Cortex-M3 based STM32F103RC MCU +with a wide range of connectivity support and configurations. There are +multiple version of this board like ``stm32f103_mini``. + +.. image:: img/stm32f103_mini_yellow.jpg + :width: 500px + :height: 367px + :align: center + :alt: STM32F103 Mini Yellow + +.. image:: img/stm32f103_mini_blue.jpg + :width: 500px + :height: 367px + :align: center + :alt: STM32F103 Mini Blue + +Hardware +******** +STM32F103 Mini provides the following hardware components: + +- STM32 microcontroller in QFP64 package + +- Flexible board power supply: + + - USB VBUS or external source (3.3V, 5V, 7 - 12V) + - Power management access point + +- Two LEDs: + + - User LED (LD1), power LED (LD2) + +- USB re-enumeration capability: + + - Mass storage + +More information about STM32F103RC can be found here: + +- `STM32F103 reference manual`_ +- `STM32F103 data sheet`_ + +Supported Features +================== + +The Zephyr stm32f103_mini board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | ADC Controller | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported in this Zephyr port. + +The default configuration can be found in the defconfig file: +``boards/arm/stm32f103_mini/stm32f103_mini_defconfig`` + +Connections and IOs +=================== + +Each of the GPIO pins can be configured by software as output (push-pull or open-drain), as +input (with or without pull-up or pull-down), or as peripheral alternate function. Most of the +GPIO pins are shared with digital or analog alternate functions. All GPIOs are high current +capable except for analog inputs. + +Board connectors: +----------------- +.. image:: img/stm32f103_mini_pin.jpg + :width: 800px + :align: center + :height: 619px + :alt: Nucleo F103RB connectors + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_1 TX/RX : PA9/PA10 +- UART_2 TX/RX : PA2/PA3 (ST-Link Virtual COM Port) +- SPI1 NSS/SCK/MISO/MOSI : PA4/PA5/PA6/PA7 +- SPI2 NSS/SCK/MISO/MOSI : PB12/PB13/PB14/PB15 +- I2C1 SDA/SCL: PB9/PB8 +- PWM1_CH1: PA8 +- USER_PB : PC13 +- LD1 : PA5 + +Programming and Debugging +************************* + +Applications for the ``stm32f103_mini`` board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +There are 2 main entry points for flashing STM32F1X SoCs, one using the ROM +bootloader, and another by using the SWD debug port (which requires additional +hardware such as ST-Link). Flashing using the ROM bootloader requires a special activation +pattern, which can be triggered by using the BOOT0 pin. + +Flashing an application to stm32f103 mini +----------------------------------------- + +Here is an example for the :ref:`blinky-sample` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: stm32f103_mini + :goals: build flash + +You will see the LED blinking every second. + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`blinky-sample` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: stm32f103_mini + :maybe-skip-config: + :goals: debug + +References +********** + +.. target-notes:: + +.. _STM32F103 reference manual: + http://www.st.com/resource/en/reference_manual/cd00171190.pdf + +.. _STM32F103 data sheet: + http://www.st.com/resource/en/datasheet/stm32f103rc.pdf diff --git a/boards/arm/stm32f103_mini/stm32f103_mini.dts b/boards/arm/stm32f103_mini/stm32f103_mini.dts new file mode 100644 index 00000000000000..c5e3a328a898f1 --- /dev/null +++ b/boards/arm/stm32f103_mini/stm32f103_mini.dts @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020 WuhanStudio + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "stm32f103_mini board"; + compatible = "st,stm32f103"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + green_led_1: led_1 { + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + label = "User LD1"; + }; + }; + + aliases { + led0 = &green_led_1; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + current-speed = <115200>; + status = "okay"; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + current-speed = <115200>; +}; + +&usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; + current-speed = <115200>; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_master_pa4 &spi1_sck_master_pa5 + &spi1_miso_master_pa6 &spi1_mosi_master_pa7>; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_nss_master_pb12 &spi2_sck_master_pb13 + &spi2_miso_master_pb14 &spi2_mosi_master_pb15>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&timers1 { + status = "okay"; + + pwm1: pwm { + status = "okay"; + pinctrl-0 = <&tim1_ch1_pwm_pa8>; + }; +}; + +&adc1 { + pinctrl-0 = <&adc1_in0_pa0>; + status = "okay"; +}; diff --git a/boards/arm/stm32f103_mini/stm32f103_mini.yaml b/boards/arm/stm32f103_mini/stm32f103_mini.yaml new file mode 100644 index 00000000000000..0a931e6193e9f8 --- /dev/null +++ b/boards/arm/stm32f103_mini/stm32f103_mini.yaml @@ -0,0 +1,17 @@ +identifier: stm32f103_mini +name: STM32F103RCT6 Mini Board +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 48 +flash: 256 +supported: + - gpio + - i2c + - spi + - pwm + - watchdog + - adc diff --git a/boards/arm/stm32f103_mini/stm32f103_mini_defconfig b/boards/arm/stm32f103_mini/stm32f103_mini_defconfig new file mode 100644 index 00000000000000..54e1a4d4531edf --- /dev/null +++ b/boards/arm/stm32f103_mini/stm32f103_mini_defconfig @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32F1X=y +CONFIG_SOC_STM32F103XE=y +# 72MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 + +# enable uart driver +CONFIG_SERIAL=y +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# enable pinmux +CONFIG_PINMUX=y + +# enable GPIO +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# Use the internal 8MHz clock +CONFIG_CLOCK_STM32_PLL_SRC_HSI=y +# produce 72MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +# APB1 clock must not to exceed 36MHz limit +CONFIG_CLOCK_STM32_APB1_PRESCALER=2 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 diff --git a/boards/arm/stm32f103_mini/support/openocd.cfg b/boards/arm/stm32f103_mini/support/openocd.cfg new file mode 100644 index 00000000000000..2f6d623fa3a911 --- /dev/null +++ b/boards/arm/stm32f103_mini/support/openocd.cfg @@ -0,0 +1,18 @@ +source [find interface/stlink.cfg] + +transport select hla_swd + +source [find target/stm32f1x.cfg] + +reset_config srst_only + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/stm32f3_disco/CMakeLists.txt b/boards/arm/stm32f3_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f3_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f3_disco/doc/index.rst b/boards/arm/stm32f3_disco/doc/index.rst index e6e972854692da..fbebf4adbb4abf 100644 --- a/boards/arm/stm32f3_disco/doc/index.rst +++ b/boards/arm/stm32f3_disco/doc/index.rst @@ -96,6 +96,12 @@ features: +-----------+------------+-------------------------------------+ | CAN | on-chip | CAN | +-----------+------------+-------------------------------------+ +| IWDG | on-chip | Independent WatchDoG | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on Zephyr porting. @@ -146,6 +152,8 @@ Default Zephyr Peripheral Mapping: - LD8 : PE14 - LD9 : PE12 - LD10 : PE13 +- PWM : PA8 +- ADC1 : PA0 System Clock ============ diff --git a/boards/arm/stm32f3_disco/pinmux.c b/boards/arm/stm32f3_disco/pinmux.c deleted file mode 100644 index 09f3a3491b130f..00000000000000 --- a/boards/arm/stm32f3_disco/pinmux.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2017 I-SENSE group of ICCS - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32F3DISCOVERY board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PC4, STM32F3_PINMUX_FUNC_PC4_USART1_TX}, - {STM32_PIN_PC5, STM32F3_PINMUX_FUNC_PC5_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F3_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F3_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32F3_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32F3_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PA9, STM32F3_PINMUX_FUNC_PA9_I2C2_SCL}, - {STM32_PIN_PA10, STM32F3_PINMUX_FUNC_PA10_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32F3_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32F3_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32F3_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32F3_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32F3_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32F3_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32F3_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F3_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F3_PINMUX_FUNC_PA11_USB_DM}, - {STM32_PIN_PA12, STM32F3_PINMUX_FUNC_PA12_USB_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PD0, STM32F3_PINMUX_FUNC_PD0_CAN1_RX}, - {STM32_PIN_PD1, STM32F3_PINMUX_FUNC_PD1_CAN1_TX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f3_disco/stm32f3_disco.dts b/boards/arm/stm32f3_disco/stm32f3_disco.dts index 6fde431d0d7054..1a9b87d4c5b84e 100644 --- a/boards/arm/stm32f3_disco/stm32f3_disco.dts +++ b/boards/arm/stm32f3_disco/stm32f3_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F3DISCOVERY board"; - compatible = "st,stm32f3discovery", "st,stm32f303"; + compatible = "st,stm32f3discovery"; chosen { zephyr,console = &usart1; @@ -71,16 +72,19 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pc4 &usart1_rx_pc5>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; @@ -100,19 +104,25 @@ }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pa9 &i2c2_sda_pa10>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; &usb { + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; status = "okay"; }; @@ -121,14 +131,12 @@ }; &can1 { + pinctrl-0 = <&can_rx_pd0 &can_tx_pd1>; status = "okay"; }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; @@ -141,3 +149,20 @@ }; }; }; + +&iwdg { + status = "okay"; +}; + +&timers1 { + status = "okay"; + pwm1: pwm { + status = "okay"; + pinctrl-0 = <&tim1_ch1_pa8>; + }; +}; + +&adc1 { + pinctrl-0 = <&adc1_in1_pa0>; + status = "okay"; +}; diff --git a/boards/arm/stm32f3_disco/stm32f3_disco.yaml b/boards/arm/stm32f3_disco/stm32f3_disco.yaml index fe333bd87dab3e..6c03e599a090c3 100644 --- a/boards/arm/stm32f3_disco/stm32f3_disco.yaml +++ b/boards/arm/stm32f3_disco/stm32f3_disco.yaml @@ -12,7 +12,10 @@ supported: - i2c - counter - spi + - watchdog - usb_device - lsm303dlhc - nvs - can + - pwm + - adc diff --git a/boards/arm/stm32f3_disco/stm32f3_disco_defconfig b/boards/arm/stm32f3_disco/stm32f3_disco_defconfig index ce469b5ea025b7..d549d707fbe1db 100644 --- a/boards/arm/stm32f3_disco/stm32f3_disco_defconfig +++ b/boards/arm/stm32f3_disco/stm32f3_disco_defconfig @@ -8,6 +8,12 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 # Floating Point Options CONFIG_FPU=y +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/stm32f411e_disco/CMakeLists.txt b/boards/arm/stm32f411e_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f411e_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f411e_disco/pinmux.c b/boards/arm/stm32f411e_disco/pinmux.c deleted file mode 100644 index 5afca03f1da500..00000000000000 --- a/boards/arm/stm32f411e_disco/pinmux.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017 Fenix Engineering Solutions - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32F411E-DISCO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm4), okay) && CONFIG_PWM - {STM32_PIN_PD12, STM32F4_PINMUX_FUNC_PD12_PWM4_CH1 }, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts index 1c50f310259015..8274d279d91f0d 100644 --- a/boards/arm/stm32f411e_disco/stm32f411e_disco.dts +++ b/boards/arm/stm32f411e_disco/stm32f411e_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F411E-DISCO board"; - compatible = "st,stm32f411e-disco", "st,stm32f411"; + compatible = "st,stm32f411e-disco"; chosen { zephyr,console = &usart2; @@ -41,7 +42,7 @@ pwmleds { compatible = "pwm-leds"; green_pwm_led: green_pwm_led { - pwms = <&pwm4 1 0>; + pwms = <&pwm4 1 0 PWM_POLARITY_NORMAL>; }; }; @@ -68,10 +69,12 @@ pwm4: pwm { status = "okay"; + pinctrl-0 = <&tim4_ch1_pd12>; }; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; @@ -79,3 +82,8 @@ &rtc { status = "okay"; }; + +&usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; + status = "okay"; +}; diff --git a/boards/arm/stm32f411e_disco/stm32f411e_disco_defconfig b/boards/arm/stm32f411e_disco/stm32f411e_disco_defconfig index 11baa65455cb48..ec87e12466d14f 100644 --- a/boards/arm/stm32f411e_disco/stm32f411e_disco_defconfig +++ b/boards/arm/stm32f411e_disco/stm32f411e_disco_defconfig @@ -2,12 +2,15 @@ CONFIG_SOC_SERIES_STM32F4X=y CONFIG_SOC_STM32F411XE=y -# 100MHz system clock (highest value to get a precise USB clock should be 96MHz) -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=100000000 +# 96MHz system clock (highest value to get a precise USB clock should be 96MHz) +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # Serial Drivers CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y @@ -28,11 +31,11 @@ CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y CONFIG_CLOCK_STM32_HSE_CLOCK=8000000 # use HSE as PLL input CONFIG_CLOCK_STM32_PLL_SRC_HSE=y -# produce 100MHz clock at PLL output +# produce 96MHz clock at PLL output CONFIG_CLOCK_STM32_PLL_M_DIVISOR=4 -CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=100 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=96 CONFIG_CLOCK_STM32_PLL_P_DIVISOR=2 -CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=8 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=4 CONFIG_CLOCK_STM32_AHB_PRESCALER=1 CONFIG_CLOCK_STM32_APB1_PRESCALER=2 CONFIG_CLOCK_STM32_APB2_PRESCALER=1 diff --git a/boards/arm/stm32f412g_disco/CMakeLists.txt b/boards/arm/stm32f412g_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f412g_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f412g_disco/pinmux.c b/boards/arm/stm32f412g_disco/pinmux.c deleted file mode 100644 index 2bfcac9286307c..00000000000000 --- a/boards/arm/stm32f412g_disco/pinmux.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017 Powersoft. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32F412G-DISCO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f412g_disco/stm32f412g_disco.dts b/boards/arm/stm32f412g_disco/stm32f412g_disco.dts index 22641cd7ae8ef8..7de30c716f2d2f 100644 --- a/boards/arm/stm32f412g_disco/stm32f412g_disco.dts +++ b/boards/arm/stm32f412g_disco/stm32f412g_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F412G-DISCO board"; - compatible = "st,stm32f412g-disco", "st,stm32f412"; + compatible = "st,stm32f412g-disco"; chosen { zephyr,console = &usart2; @@ -42,23 +43,23 @@ compatible = "gpio-keys"; joy_sel: joystick_selection { label = "joystick selection"; - gpios = <&gpioa 0 GPIO_ACTIVE_LOW>; + gpios = <&gpioa 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_down: joystick_down { label = "joystick down"; - gpios = <&gpiog 1 GPIO_ACTIVE_LOW>; + gpios = <&gpiog 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_up: joystick_up { label = "joystick up"; - gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; + gpios = <&gpiog 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_left: joystick_left { label = "joystick left"; - gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; + gpios = <&gpiof 15 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_right: joystick_right { label = "joystick right"; - gpios = <&gpiof 14 GPIO_ACTIVE_LOW>; + gpios = <&gpiof 14 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; }; @@ -72,6 +73,7 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/stm32f412g_disco/stm32f412g_disco_defconfig b/boards/arm/stm32f412g_disco/stm32f412g_disco_defconfig index 0c3225906e9f23..b561ad19ec2e77 100644 --- a/boards/arm/stm32f412g_disco/stm32f412g_disco_defconfig +++ b/boards/arm/stm32f412g_disco/stm32f412g_disco_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=100000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/stm32f429i_disc1/CMakeLists.txt b/boards/arm/stm32f429i_disc1/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f429i_disc1/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f429i_disc1/pinmux.c b/boards/arm/stm32f429i_disc1/pinmux.c deleted file mode 100644 index 08d055fb8c286f..00000000000000 --- a/boards/arm/stm32f429i_disc1/pinmux.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016 Linaro Limited. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32F429I-DISC1 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F4_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F4_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi5), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PF6, STM32F4_PINMUX_FUNC_PF6_SPI5_MASTER_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PF7, STM32F4_PINMUX_FUNC_PF7_SPI5_MASTER_SCK}, - {STM32_PIN_PF8, STM32F4_PINMUX_FUNC_PF8_SPI5_MASTER_MISO}, - {STM32_PIN_PF9, STM32F4_PINMUX_FUNC_PF9_SPI5_MASTER_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB11, STM32F4_PINMUX_FUNC_PB11_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PA8, STM32F4_PINMUX_FUNC_PA8_I2C3_SCL}, - {STM32_PIN_PC9, STM32F4_PINMUX_FUNC_PC9_I2C3_SDA}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f429i_disc1/stm32f429i_disc1.dts b/boards/arm/stm32f429i_disc1/stm32f429i_disc1.dts index ac0c2ef0b3dbdd..821f9345e52848 100644 --- a/boards/arm/stm32f429i_disc1/stm32f429i_disc1.dts +++ b/boards/arm/stm32f429i_disc1/stm32f429i_disc1.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F429I_DISC1 board"; - compatible = "st,stm32f4discovery", "st,stm32f429"; + compatible = "st,stm32f4discovery"; chosen { zephyr,console = &usart1; @@ -46,11 +47,13 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; @@ -59,14 +62,31 @@ status = "okay"; }; +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + status = "okay"; + clock-frequency = ; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; + status = "okay"; + clock-frequency = ; +}; + &i2c3 { + pinctrl-0 = <&i2c3_scl_pa8 &i2c3_sda_pc9>; status = "okay"; clock-frequency = ; }; + + &spi5 { + pinctrl-0 = <&spi5_nss_pf6 &spi5_sck_pf7 + &spi5_miso_pf8 &spi5_mosi_pf9>; status = "okay"; - cs-gpios = <&gpioc 2 0>; + cs-gpios = <&gpioc 2 GPIO_ACTIVE_LOW>; ili9340@0 { compatible = "ilitek,ili9340"; label = "DISPLAY"; diff --git a/boards/arm/stm32f429i_disc1/stm32f429i_disc1_defconfig b/boards/arm/stm32f429i_disc1/stm32f429i_disc1_defconfig index 7b8538e1258ca5..7910646b14a868 100644 --- a/boards/arm/stm32f429i_disc1/stm32f429i_disc1_defconfig +++ b/boards/arm/stm32f429i_disc1/stm32f429i_disc1_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/stm32f469i_disco/CMakeLists.txt b/boards/arm/stm32f469i_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f469i_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f469i_disco/pinmux.c b/boards/arm/stm32f469i_disco/pinmux.c deleted file mode 100644 index 5928a2276acbb9..00000000000000 --- a/boards/arm/stm32f469i_disco/pinmux.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2016 Linaro Limited. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32F469I-DISCO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32F4_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32F4_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PG14, STM32F4_PINMUX_FUNC_PG14_USART6_TX}, - {STM32_PIN_PG9, STM32F4_PINMUX_FUNC_PG9_USART6_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - {STM32_PIN_PD3, STM32F4_PINMUX_FUNC_PD3_SPI2_SCK}, - {STM32_PIN_PB14, STM32F4_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F4_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ - -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f469i_disco/stm32f469i_disco.dts b/boards/arm/stm32f469i_disco/stm32f469i_disco.dts index 2978fe9d0568a8..636292be518ca4 100644 --- a/boards/arm/stm32f469i_disco/stm32f469i_disco.dts +++ b/boards/arm/stm32f469i_disco/stm32f469i_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F469I-DISCO board"; - compatible = "st,stm32f469i-disco", "st,stm32f469"; + compatible = "st,stm32f469i-disco"; chosen { zephyr,console = &usart3; @@ -61,24 +62,29 @@ arduino_spi: &spi2 {}; arduino_serial: &usart6 {}; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_sck_pd3 &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; diff --git a/boards/arm/stm32f469i_disco/stm32f469i_disco_defconfig b/boards/arm/stm32f469i_disco/stm32f469i_disco_defconfig index 4fb939f0725da7..836a0026da730c 100644 --- a/boards/arm/stm32f469i_disco/stm32f469i_disco_defconfig +++ b/boards/arm/stm32f469i_disco/stm32f469i_disco_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=180000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/stm32f4_disco/CMakeLists.txt b/boards/arm/stm32f4_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f4_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f4_disco/pinmux.c b/boards/arm/stm32f4_disco/pinmux.c deleted file mode 100644 index c64836a15fd3d8..00000000000000 --- a/boards/arm/stm32f4_disco/pinmux.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016 Linaro Limited. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32F4DISCOVERY board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32F4_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PB7, STM32F4_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F4_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F4_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32F4_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F4_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F4_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay) && CONFIG_CAN - {STM32_PIN_PB8, STM32F4_PINMUX_FUNC_PB8_CAN1_RX}, - {STM32_PIN_PB9, STM32F4_PINMUX_FUNC_PB9_CAN1_TX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(can2), okay) && CONFIG_CAN - {STM32_PIN_PB5, STM32F4_PINMUX_FUNC_PB5_CAN2_RX}, - {STM32_PIN_PB13, STM32F4_PINMUX_FUNC_PB13_CAN2_TX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f4_disco/stm32f4_disco.dts b/boards/arm/stm32f4_disco/stm32f4_disco.dts index 0f9ffd6070c4af..58501b981ffc9a 100644 --- a/boards/arm/stm32f4_disco/stm32f4_disco.dts +++ b/boards/arm/stm32f4_disco/stm32f4_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F4DISCOVERY board"; - compatible = "st,stm32f4discovery", "st,stm32f407"; + compatible = "st,stm32f4discovery"; chosen { zephyr,console = &usart2; @@ -44,7 +45,7 @@ compatible = "gpio-keys"; user_button: button { label = "Key"; - gpios = <&gpioa 0 GPIO_ACTIVE_LOW>; + gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; }; }; @@ -58,11 +59,13 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; @@ -72,6 +75,7 @@ pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; @@ -80,15 +84,18 @@ }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; &can1 { + pinctrl-0 = <&can1_rx_pb8 &can1_tx_pb9>; bus-speed = <125000>; status = "disabled"; }; &can2 { + pinctrl-0 = <&can2_rx_pb5 &can2_tx_pb13>; bus-speed = <125000>; status = "okay"; }; diff --git a/boards/arm/stm32f4_disco/stm32f4_disco_defconfig b/boards/arm/stm32f4_disco/stm32f4_disco_defconfig index 5fdec37340b78b..12de34076029d9 100644 --- a/boards/arm/stm32f4_disco/stm32f4_disco_defconfig +++ b/boards/arm/stm32f4_disco/stm32f4_disco_defconfig @@ -8,6 +8,9 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=168000000 # Enable MPU CONFIG_ARM_MPU=y +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/stm32f723e_disco/CMakeLists.txt b/boards/arm/stm32f723e_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f723e_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f723e_disco/pinmux.c b/boards/arm/stm32f723e_disco/pinmux.c deleted file mode 100644 index dc12651ba2e104..00000000000000 --- a/boards/arm/stm32f723e_disco/pinmux.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2018 Aurelien Jarno - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32F723E-DISCO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32F7_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32F7_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PC6, STM32F7_PINMUX_FUNC_PC6_USART6_TX}, - {STM32_PIN_PC7, STM32F7_PINMUX_FUNC_PC7_USART6_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F7_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F7_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PH4, STM32F7_PINMUX_FUNC_PH4_I2C2_SCL}, - {STM32_PIN_PH5, STM32F7_PINMUX_FUNC_PH5_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PA8, STM32F7_PINMUX_FUNC_PA8_I2C3_SCL}, - {STM32_PIN_PH8, STM32F7_PINMUX_FUNC_PH8_I2C3_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PA5, STM32F7_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PB4, STM32F7_PINMUX_FUNC_PB4_SPI1_MISO}, - {STM32_PIN_PB5, STM32F7_PINMUX_FUNC_PB5_SPI1_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F7_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F7_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f723e_disco/stm32f723e_disco.dts b/boards/arm/stm32f723e_disco/stm32f723e_disco.dts index 97bb70b00d5c15..2eb86b8ab7a5c2 100644 --- a/boards/arm/stm32f723e_disco/stm32f723e_disco.dts +++ b/boards/arm/stm32f723e_disco/stm32f723e_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F723E DISCOVERY board"; - compatible = "st,stm32f723e-disco", "st,stm32f723"; + compatible = "st,stm32f723e-disco"; chosen { zephyr,console = &usart6; @@ -55,31 +56,38 @@ arduino_spi: &spi1 {}; arduino_serial: &usart2 {}; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pc6 &usart6_rx_pc7>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_ph4 &i2c2_sda_ph5>; status = "okay"; }; &i2c3 { + pinctrl-0 = <&i2c3_scl_pa8 &i2c3_sda_ph8>; status = "okay"; }; &spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pb4 &spi1_mosi_pb5>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; diff --git a/boards/arm/stm32f723e_disco/stm32f723e_disco_defconfig b/boards/arm/stm32f723e_disco/stm32f723e_disco_defconfig index 1cb1cf9ada7cfb..ee9df36247814b 100644 --- a/boards/arm/stm32f723e_disco/stm32f723e_disco_defconfig +++ b/boards/arm/stm32f723e_disco/stm32f723e_disco_defconfig @@ -5,6 +5,12 @@ CONFIG_SOC_STM32F723XX=y # 216MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=216000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/stm32f746g_disco/CMakeLists.txt b/boards/arm/stm32f746g_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f746g_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f746g_disco/Kconfig.defconfig b/boards/arm/stm32f746g_disco/Kconfig.defconfig index 308da105aacbc4..a359ca903ffd8f 100644 --- a/boards/arm/stm32f746g_disco/Kconfig.defconfig +++ b/boards/arm/stm32f746g_disco/Kconfig.defconfig @@ -13,9 +13,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_STM32_HAL - default y - endif # NETWORKING config I2C diff --git a/boards/arm/stm32f746g_disco/arduino_r3_connector.dtsi b/boards/arm/stm32f746g_disco/arduino_r3_connector.dtsi new file mode 100644 index 00000000000000..1f00baef82a285 --- /dev/null +++ b/boards/arm/stm32f746g_disco/arduino_r3_connector.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 Marco Peter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 0 0>, /* A0 */ + <1 0 &gpiof 10 0>, /* A1 */ + <2 0 &gpiof 9 0>, /* A2 */ + <3 0 &gpiof 8 0>, /* A3 */ + <4 0 &gpiof 7 0>, /* A4 */ + <5 0 &gpiof 6 0>, /* A5 */ + <6 0 &gpioc 7 0>, /* D0 */ + <7 0 &gpioc 6 0>, /* D1 */ + <8 0 &gpiog 6 0>, /* D2 */ + <9 0 &gpiob 4 0>, /* D3 */ + <10 0 &gpiog 7 0>, /* D4 */ + <11 0 &gpioi 0 0>, /* D5 */ + <12 0 &gpioh 6 0>, /* D6 */ + <13 0 &gpioi 3 0>, /* D7 */ + <14 0 &gpioi 2 0>, /* D8 */ + <15 0 &gpioa 15 0>, /* D9 */ + <16 0 &gpioa 8 0>, /* D10 */ + <17 0 &gpiob 15 0>, /* D11 */ + <18 0 &gpiob 14 0>, /* D12 */ + <19 0 &gpioi 1 0>, /* D13 */ + <20 0 &gpiob 9 0>, /* D14 */ + <21 0 &gpiob 8 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c1 {}; +arduino_spi: &spi2 {}; +arduino_serial: &usart6 {}; diff --git a/boards/arm/stm32f746g_disco/pinmux.c b/boards/arm/stm32f746g_disco/pinmux.c deleted file mode 100644 index beb1036736fed1..00000000000000 --- a/boards/arm/stm32f746g_disco/pinmux.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2018 Yurii Hamann - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32F746G-DISCO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F7_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PB7, STM32F7_PINMUX_FUNC_PB7_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PC6, STM32F7_PINMUX_FUNC_PC6_USART6_TX}, - {STM32_PIN_PC7, STM32F7_PINMUX_FUNC_PC7_USART6_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm3), okay) && CONFIG_PWM - {STM32_PIN_PB4, STM32F7_PINMUX_FUNC_PB4_PWM3_CH1}, -#endif -#ifdef CONFIG_ETH_STM32_HAL - {STM32_PIN_PC1, STM32F7_PINMUX_FUNC_PC1_ETH}, - {STM32_PIN_PC4, STM32F7_PINMUX_FUNC_PC4_ETH}, - {STM32_PIN_PC5, STM32F7_PINMUX_FUNC_PC5_ETH}, - - {STM32_PIN_PA1, STM32F7_PINMUX_FUNC_PA1_ETH}, - {STM32_PIN_PA2, STM32F7_PINMUX_FUNC_PA2_ETH}, - {STM32_PIN_PA7, STM32F7_PINMUX_FUNC_PA7_ETH}, - - {STM32_PIN_PG11, STM32F7_PINMUX_FUNC_PG11_ETH}, - {STM32_PIN_PG13, STM32F7_PINMUX_FUNC_PG13_ETH}, - {STM32_PIN_PG14, STM32F7_PINMUX_FUNC_PG14_ETH}, -#endif /* CONFIG_ETH_STM32_HAL */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F7_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F7_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C - {STM32_PIN_PH7, STM32F7_PINMUX_FUNC_PH7_I2C3_SCL}, - {STM32_PIN_PH8, STM32F7_PINMUX_FUNC_PH8_I2C3_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PI0, STM32F7_PINMUX_FUNC_PI0_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PI1, STM32F7_PINMUX_FUNC_PI1_SPI2_SCK}, - {STM32_PIN_PB14, STM32F7_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F7_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#ifdef CONFIG_USB_DC_STM32 - {STM32_PIN_PA11, STM32F7_PINMUX_FUNC_PA11_OTG_FS_DM}, - {STM32_PIN_PA12, STM32F7_PINMUX_FUNC_PA12_OTG_FS_DP}, -#endif /* CONFIG_USB_DC_STM32 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(sdmmc1), okay) && \ - CONFIG_DISK_ACCESS_STM32_SDMMC - {STM32_PIN_PC8, STM32F7_PINMUX_FUNC_PC8_SDMMC1_D0}, - {STM32_PIN_PC9, STM32F7_PINMUX_FUNC_PC9_SDMMC1_D1}, - {STM32_PIN_PC10, STM32F7_PINMUX_FUNC_PC10_SDMMC1_D2}, - {STM32_PIN_PC11, STM32F7_PINMUX_FUNC_PC11_SDMMC1_D3}, - {STM32_PIN_PC12, STM32F7_PINMUX_FUNC_PC12_SDMMC1_CK}, - {STM32_PIN_PC13, STM32_MODER_INPUT_MODE}, - {STM32_PIN_PD2, STM32F7_PINMUX_FUNC_PD2_SDMMC1_CMD}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f746g_disco/stm32f746g_disco.dts b/boards/arm/stm32f746g_disco/stm32f746g_disco.dts index 5ed27e4495b001..5996bf4750a7a2 100644 --- a/boards/arm/stm32f746g_disco/stm32f746g_disco.dts +++ b/boards/arm/stm32f746g_disco/stm32f746g_disco.dts @@ -6,10 +6,12 @@ /dts-v1/; #include +#include +#include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32F746G DISCOVERY board"; - compatible = "st,stm32f746g-disco", "st,stm32f746"; + compatible = "st,stm32f746g-disco"; chosen { zephyr,console = &usart1; @@ -42,16 +44,14 @@ }; }; -arduino_i2c: &i2c1 {}; -arduino_spi: &spi2 {}; -arduino_serial: &usart6 {}; - &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &i2c3 { + pinctrl-0 = <&i2c3_scl_ph7 &i2c3_sda_ph8>; status = "okay"; clock-frequency = ; @@ -64,28 +64,34 @@ arduino_serial: &usart6 {}; }; &spi2 { + pinctrl-0 = <&spi2_nss_pi0 &spi2_sck_pi1 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pc6 &usart6_rx_pc7>; current-speed = <115200>; status = "okay"; }; &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; status = "okay"; }; -&timers1 { +&timers3 { status = "okay"; - pwm1: pwm { + pwm3: pwm { status = "okay"; + pinctrl-0 = <&tim3_ch1_pb4>; }; }; @@ -95,5 +101,21 @@ arduino_serial: &usart6 {}; &sdmmc1 { status = "okay"; + pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9 + &sdmmc1_d2_pc10 &sdmmc1_d3_pc11 + &sdmmc1_ck_pc12 &sdmmc1_cmd_pd2>; cd-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; }; + +&mac { + status = "okay"; + pinctrl-0 = <ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pg14>; +}; diff --git a/boards/arm/stm32f746g_disco/stm32f746g_disco_defconfig b/boards/arm/stm32f746g_disco/stm32f746g_disco_defconfig index fe179939513912..35ba3a94c17f54 100644 --- a/boards/arm/stm32f746g_disco/stm32f746g_disco_defconfig +++ b/boards/arm/stm32f746g_disco/stm32f746g_disco_defconfig @@ -5,6 +5,12 @@ CONFIG_SOC_STM32F746XX=y # 216MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=216000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/stm32f769i_disco/CMakeLists.txt b/boards/arm/stm32f769i_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32f769i_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32f769i_disco/Kconfig.defconfig b/boards/arm/stm32f769i_disco/Kconfig.defconfig index d0dd00667cf5f6..ae76044e9e5ec1 100644 --- a/boards/arm/stm32f769i_disco/Kconfig.defconfig +++ b/boards/arm/stm32f769i_disco/Kconfig.defconfig @@ -17,9 +17,6 @@ if NETWORKING config NET_L2_ETHERNET default y -config ETH_STM32_HAL - default y - endif # NETWORKING endif # BOARD_STM32F769I_DISCO diff --git a/boards/arm/stm32f769i_disco/pinmux.c b/boards/arm/stm32f769i_disco/pinmux.c deleted file mode 100644 index 1e566ed6d34885..00000000000000 --- a/boards/arm/stm32f769i_disco/pinmux.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2018 Yong Jin - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32F769I-DISCO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32F7_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32F7_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart6), okay) && CONFIG_SERIAL - {STM32_PIN_PC6, STM32F7_PINMUX_FUNC_PC6_USART6_TX}, - {STM32_PIN_PC7, STM32F7_PINMUX_FUNC_PC7_USART6_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32F7_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB9, STM32F7_PINMUX_FUNC_PB9_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI - {STM32_PIN_PA12, STM32F7_PINMUX_FUNC_PA12_SPI2_SCK}, - {STM32_PIN_PB14, STM32F7_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32F7_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -#ifdef CONFIG_ETH_STM32_HAL - {STM32_PIN_PC1, STM32F7_PINMUX_FUNC_PC1_ETH}, - {STM32_PIN_PC4, STM32F7_PINMUX_FUNC_PC4_ETH}, - {STM32_PIN_PC5, STM32F7_PINMUX_FUNC_PC5_ETH}, - - {STM32_PIN_PA1, STM32F7_PINMUX_FUNC_PA1_ETH}, - {STM32_PIN_PA2, STM32F7_PINMUX_FUNC_PA2_ETH}, - {STM32_PIN_PA7, STM32F7_PINMUX_FUNC_PA7_ETH}, - - {STM32_PIN_PG11, STM32F7_PINMUX_FUNC_PG11_ETH}, - {STM32_PIN_PG13, STM32F7_PINMUX_FUNC_PG13_ETH}, - {STM32_PIN_PG14, STM32F7_PINMUX_FUNC_PG14_ETH}, -#endif /* CONFIG_ETH_STM32_HAL */ -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32f769i_disco/stm32f769i_disco.dts b/boards/arm/stm32f769i_disco/stm32f769i_disco.dts index 951b94fda3d4b4..311d5e1703624a 100644 --- a/boards/arm/stm32f769i_disco/stm32f769i_disco.dts +++ b/boards/arm/stm32f769i_disco/stm32f769i_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32F769I DISCOVERY board"; - compatible = "st,stm32f769I-disco", "st,stm32f769"; + compatible = "st,stm32f769I-disco"; chosen { zephyr,console = &usart1; @@ -61,20 +62,45 @@ arduino_spi: &spi2 {}; arduino_serial: &usart6 {}; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart6 { + pinctrl-0 = <&usart6_tx_pc6 &usart6_rx_pc7>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; status = "okay"; clock-frequency = ; }; &spi2 { + pinctrl-0 = <&spi2_sck_pa12 &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; + +&mac { + status = "okay"; + pinctrl-0 = <ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pg14>; +}; + +&sdmmc2 { + status = "okay"; + pinctrl-0 = <&sdmmc2_d0_pg9 &sdmmc2_d1_pg10 + &sdmmc2_d2_pb3 &sdmmc2_d3_pb4 + &sdmmc2_ck_pd6 &sdmmc2_cmd_pd7>; + cd-gpios = <&gpioi 15 GPIO_ACTIVE_LOW>; +}; diff --git a/boards/arm/stm32f769i_disco/stm32f769i_disco_defconfig b/boards/arm/stm32f769i_disco/stm32f769i_disco_defconfig index 13a88661475ff2..4cd9e6e701cc37 100644 --- a/boards/arm/stm32f769i_disco/stm32f769i_disco_defconfig +++ b/boards/arm/stm32f769i_disco/stm32f769i_disco_defconfig @@ -5,6 +5,12 @@ CONFIG_SOC_STM32F769XX=y # 216MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=216000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + CONFIG_SERIAL=y # console diff --git a/boards/arm/stm32g0316_disco/doc/index.rst b/boards/arm/stm32g0316_disco/doc/index.rst index f1a82d04fe0a06..303a6d63c5be05 100644 --- a/boards/arm/stm32g0316_disco/doc/index.rst +++ b/boards/arm/stm32g0316_disco/doc/index.rst @@ -95,6 +95,7 @@ the following pyocd command: .. code-block:: console + $ pyocd pack --update $ pyocd pack --install stm32g031j6 Flashing an application to the STM32G0316-DISCO diff --git a/boards/arm/stm32g0316_disco/pinmux.c b/boards/arm/stm32g0316_disco/pinmux.c index 7f926060572f11..14388485b06c72 100644 --- a/boards/arm/stm32g0316_disco/pinmux.c +++ b/boards/arm/stm32g0316_disco/pinmux.c @@ -6,18 +6,16 @@ #include #include +#include +#include #include /* pin assignments for STM32G0316-DISCO board */ static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32G0_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PB7, STM32G0_PINMUX_FUNC_PB7_USART1_RX}, -#endif }; -static int pinmux_stm32_init(struct device *port) +static int pinmux_stm32_init(const struct device *port) { ARG_UNUSED(port); diff --git a/boards/arm/stm32g0316_disco/stm32g0316_disco.dts b/boards/arm/stm32g0316_disco/stm32g0316_disco.dts index 6ecf8c8aef965b..751af84c191910 100644 --- a/boards/arm/stm32g0316_disco/stm32g0316_disco.dts +++ b/boards/arm/stm32g0316_disco/stm32g0316_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32G0316 Discovery board"; - compatible = "st,stm32g0316-disco", "st,stm32g031"; + compatible = "st,stm32g0316-disco"; aliases { led0 = &green_led_1; @@ -41,6 +42,7 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pb7>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/stm32h747i_disco/CMakeLists.txt b/boards/arm/stm32h747i_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32h747i_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32h747i_disco/Kconfig.defconfig b/boards/arm/stm32h747i_disco/Kconfig.defconfig index 73be30506d8b74..43589e94951fae 100644 --- a/boards/arm/stm32h747i_disco/Kconfig.defconfig +++ b/boards/arm/stm32h747i_disco/Kconfig.defconfig @@ -38,13 +38,11 @@ config CLOCK_STM32_D3PPRE config STM32H7_DUAL_CORE default y -# Dual core boot configuration. Boot method is selected in common file to avoid -# desync issues. -choice STM32H7_DUAL_CORE_BOOT - # Use out of the box config by default - # default STM32H7_BOOT_CM4_CM7 - default STM32H7_BOOT_CM7_CM4GATED - depends on STM32H7_DUAL_CORE -endchoice +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING endif # BOARD_STM32H747I_DISCO_M7 diff --git a/boards/arm/stm32h747i_disco/doc/img/disco_h747i_ethernet_modification_1.jpg b/boards/arm/stm32h747i_disco/doc/img/disco_h747i_ethernet_modification_1.jpg new file mode 100644 index 00000000000000..684fcc09ae8812 Binary files /dev/null and b/boards/arm/stm32h747i_disco/doc/img/disco_h747i_ethernet_modification_1.jpg differ diff --git a/boards/arm/stm32h747i_disco/doc/img/disco_h747i_ethernet_modification_2.jpg b/boards/arm/stm32h747i_disco/doc/img/disco_h747i_ethernet_modification_2.jpg new file mode 100644 index 00000000000000..cabea3778c5719 Binary files /dev/null and b/boards/arm/stm32h747i_disco/doc/img/disco_h747i_ethernet_modification_2.jpg differ diff --git a/boards/arm/stm32h747i_disco/doc/index.rst b/boards/arm/stm32h747i_disco/doc/index.rst index dbbe0a0a9d1357..b4f1366bd2d729 100644 --- a/boards/arm/stm32h747i_disco/doc/index.rst +++ b/boards/arm/stm32h747i_disco/doc/index.rst @@ -63,6 +63,17 @@ The current Zephyr stm32h747i_disco board configuration supports the following h +-----------+------------+-------------------------------------+ | GPIO | on-chip | gpio | +-----------+------------+-------------------------------------+ +| ETHERNET | on-chip | ethernet (*) | ++-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ +| FMC | on-chip | memc (SDRAM) | ++-----------+------------+-------------------------------------+ + +(*) From UM2411 Rev 4: + With the default setting, the Ethernet feature is not working because of + a conflict between ETH_MDC and SAI4_D1 of the MEMs digital microphone. + Make sure you have SB8 closed and SB21 open to get Ethernet working. Other hardware features are not yet supported on Zephyr porting. @@ -110,6 +121,33 @@ Default configuration assigns USART1 and UART8 to the CPU1. The Zephyr console output is assigned to UART1 which connected to the onboard ST-LINK/V3.0. Virtual COM port interface. Default communication settings are 115200 8N1. +Ethernet +======== + +**Disclaimer:** This section is mostly copy-paste of corresponding +`DISCO_H747I modifications for Ethernet`_ mbed blog post. The author of this +article sincerely allowed to use the images and his knowledge about necessary +HW modifications to get Ethernet working with this board. + +To get Ethernet working following HW modifications are required: + +- **SB21**, **SB45** and **R87** should be opened +- **SB22**, **SB44**, **SB17** and **SB8** should be closed + +Following two images shows necessary changes on the board marked: + +.. image:: img/disco_h747i_ethernet_modification_1.jpg + :width: 271px + :align: center + :height: 596px + :alt: STM32H747I-DISCO - Ethernet modification 1 (**SB44**, **SB45**) + +.. image:: img/disco_h747i_ethernet_modification_2.jpg + :width: 344px + :align: center + :height: 520px + :alt: STM32H747I-DISCO - Ethernet modification 2 (**SB21**, **R87**, **SB22**, **SB17** and **SB8**) + Resources sharing ================= @@ -157,7 +195,11 @@ By default: Also, default out of the box board configuration enables CM7 and CM4 boot when board is powered (Option bytes BCM7 and BCM4 are checked). -In that configuration, Kconfig boot option ``STM32H7_BOOT_CM4_CM7`` should be selected. +It is possible to change Option Bytes so that CM7 boots first in stand alone, +and CM7 will wakeup CM4 after clock initialization. +Drivers are able to take into account both Option Bytes configurations +automatically. + Zephyr flash configuration has been set to meet these default settings. Flashing an application to STM32H747I M7 Core @@ -229,3 +271,6 @@ You can debug an application in the usual way. Here is an example for the .. _STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html + +.. _DISCO_H747I modifications for Ethernet: + https://os.mbed.com/teams/ST/wiki/DISCO_H747I-modifications-for-Ethernet diff --git a/boards/arm/stm32h747i_disco/pinmux.c b/boards/arm/stm32h747i_disco/pinmux.c deleted file mode 100644 index 11c2282f32246e..00000000000000 --- a/boards/arm/stm32h747i_disco/pinmux.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2019 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32H747I-DISCO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32H7_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32H7_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart8), okay) && CONFIG_SERIAL - {STM32_PIN_PJ8, STM32H7_PINMUX_FUNC_PJ8_UART8_TX}, - {STM32_PIN_PJ9, STM32H7_PINMUX_FUNC_PJ9_UART8_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco.dtsi b/boards/arm/stm32h747i_disco/stm32h747i_disco.dtsi index e8737bfc8919a0..efe5e72bf40961 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco.dtsi +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco.dtsi @@ -35,32 +35,32 @@ compatible = "gpio-keys"; wake_up: button { label = "Wakeup"; - gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; status = "disabled"; }; joy_center: joystick_center { label = "joystick center"; - gpios = <&gpiok 2 GPIO_ACTIVE_LOW>; + gpios = <&gpiok 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; status = "disabled"; }; joy_down: joystick_down { label = "joystick down"; - gpios = <&gpiok 3 GPIO_ACTIVE_LOW>; + gpios = <&gpiok 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; status = "disabled"; }; joy_up: joystick_up { label = "joystick up"; - gpios = <&gpiok 6 GPIO_ACTIVE_LOW>; + gpios = <&gpiok 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; status = "disabled"; }; joy_left: joystick_left { label = "joystick left"; - gpios = <&gpiok 4 GPIO_ACTIVE_LOW>; + gpios = <&gpiok 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; status = "disabled"; }; joy_right: joystick_right { label = "joystick right"; - gpios = <&gpiok 5 GPIO_ACTIVE_LOW>; + gpios = <&gpiok 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; status = "disabled"; }; }; diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m4.dts b/boards/arm/stm32h747i_disco/stm32h747i_disco_m4.dts index 6a10686ca629d8..36e3d8cf0ec1d9 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m4.dts +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m4.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "stm32h747i_disco.dtsi" / { model = "STMicroelectronics STM32H747I DISCOVERY board"; - compatible = "st,stm32h747i-disco", "st,stm32h747"; + compatible = "st,stm32h747i-disco"; /* HW resources are split between CM7 and CM4 */ chosen { @@ -43,11 +44,13 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; /* status = "okay"; */ }; &uart8 { + pinctrl-0 = <&uart8_tx_pj8 &uart8_rx_pj9>; current-speed = <115200>; - /* status = "okay"; */ + status = "okay"; }; diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m4_defconfig b/boards/arm/stm32h747i_disco/stm32h747i_disco_m4_defconfig index 57612947f699b0..49e3780ca13d2e 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m4_defconfig +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m4_defconfig @@ -15,10 +15,15 @@ CONFIG_GPIO=y # clock configuration CONFIG_CLOCK_CONTROL=y -# By default SERIAL peripherals are assigned to m7 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y # enable uart driver -#CONFIG_SERIAL=y -# console +CONFIG_SERIAL=y + +# By default CONSOLE is assigned to m7 #CONFIG_CONSOLE=y #CONFIG_UART_CONSOLE=y diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts index 369a18e6927035..bef2cd923909c8 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "stm32h747i_disco.dtsi" / { model = "STMicroelectronics STM32H747I DISCOVERY board"; - compatible = "st,stm32h747i-disco", "st,stm32h747"; + compatible = "st,stm32h747i-disco"; /* HW resources are split between CM7 and CM4 */ chosen { @@ -20,6 +21,11 @@ zephyr,flash = &flash0; }; + sdram2: sdram@d0000000 { + device_type = "memory"; + reg = <0xd0000000 DT_SIZE_M(32)>; + }; + leds { green_led_1:led_1 { status = "okay"; @@ -43,11 +49,81 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &uart8 { + pinctrl-0 = <&uart8_tx_pj8 &uart8_rx_pj9>; current-speed = <115200>; status = "okay"; }; + + +&mac { + /* + * From UM2411 Rev 4: + * With the default setting, the Ethernet feature is not working due + * of a pin conflict between ETH_MDC and SAI4_D1 of the MEMs digital + * microphone. + * Cf Ethernet section in board documentation for more information on + * the hw modification to be done to enable it. + */ + status = "okay"; + pinctrl-0 = <ð_ref_clk_pa1 + ð_mdio_pa2 + ð_crs_dv_pa7 + ð_mdc_pc1 + ð_rxd0_pc4 + ð_rxd1_pc5 + ð_tx_en_pg11 + ð_txd0_pg13 + ð_txd1_pg12>; +}; + +&rng { + status = "okay"; +}; + +&fmc { + status = "okay"; + pinctrl-0 = <&fmc_nbl0_pe0 &fmc_nbl1_pe1 &fmc_nbl2_pi4 &fmc_nbl3_pi5 + &fmc_sdclk_pg8 &fmc_sdnwe_ph5 &fmc_sdcke1_ph7 + &fmc_sdne1_ph6 &fmc_sdnras_pf11 &fmc_sdncas_pg15 + &fmc_a0_pf0 &fmc_a1_pf1 &fmc_a2_pf2 &fmc_a3_pf3 &fmc_a4_pf4 + &fmc_a5_pf5 &fmc_a6_pf12 &fmc_a7_pf13 &fmc_a8_pf14 + &fmc_a9_pf15 &fmc_a10_pg0 &fmc_a11_pg1 &fmc_a12_pg2 + &fmc_a13_pg3 &fmc_a14_pg4 &fmc_a15_pg5 &fmc_d0_pd14 + &fmc_d1_pd15 &fmc_d2_pd0 &fmc_d3_pd1 &fmc_d4_pe7 + &fmc_d5_pe8 &fmc_d6_pe9 &fmc_d7_pe10 &fmc_d8_pe11 + &fmc_d9_pe12 &fmc_d10_pe13 &fmc_d11_pe14 &fmc_d12_pe15 + &fmc_d13_pd8 &fmc_d14_pd9 &fmc_d15_pd10 &fmc_d16_ph8 + &fmc_d17_ph9 &fmc_d18_ph10 &fmc_d19_ph11 &fmc_d20_ph12 + &fmc_d21_ph13 &fmc_d22_ph14 &fmc_d23_ph15 &fmc_d24_pi0 + &fmc_d26_pi2 &fmc_d27_pi3 &fmc_d28_pi6 &fmc_d29_pi7 + &fmc_d30_pi9 &fmc_d31_pi10>; + + sdram { + status = "okay"; + + power-up-delay = <100>; + num-auto-refresh = <8>; + mode-register = <0x220>; + refresh-rate = <603>; + + bank@1 { + reg = <1>; + + st,sdram-control = ; + st,sdram-timing = <2 6 4 6 2 2 2>; + }; + }; +}; diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.yaml b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.yaml index 1717f36ad6bddf..d9dd1f5c24b9b6 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.yaml +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7.yaml @@ -11,3 +11,5 @@ flash: 1024 supported: - arduino_gpio - gpio + - netif:eth + - memc diff --git a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7_defconfig b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7_defconfig index cbd8a7758b6347..d0239ba4a7d798 100644 --- a/boards/arm/stm32h747i_disco/stm32h747i_disco_m7_defconfig +++ b/boards/arm/stm32h747i_disco/stm32h747i_disco_m7_defconfig @@ -30,6 +30,12 @@ CONFIG_CLOCK_STM32_PLL_P_DIVISOR=2 CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=4 CONFIG_CLOCK_STM32_PLL_R_DIVISOR=2 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # Disable following to assign serial ports to m4 core # enable uart driver diff --git a/boards/arm/stm32h747i_disco/support/openocd_stm32h747i_disco_m4.cfg b/boards/arm/stm32h747i_disco/support/openocd_stm32h747i_disco_m4.cfg index 4cac90f4fc028e..ddceef92cb1919 100644 --- a/boards/arm/stm32h747i_disco/support/openocd_stm32h747i_disco_m4.cfg +++ b/boards/arm/stm32h747i_disco/support/openocd_stm32h747i_disco_m4.cfg @@ -9,4 +9,4 @@ set DUAL_CORE 1 source [find target/stm32h7x.cfg] -reset_config srst_only +reset_config srst_only srst_nogate connect_assert_srst diff --git a/boards/arm/stm32h747i_disco/support/openocd_stm32h747i_disco_m7.cfg b/boards/arm/stm32h747i_disco/support/openocd_stm32h747i_disco_m7.cfg index 3da92a1fc58ff2..040feadc02ec66 100644 --- a/boards/arm/stm32h747i_disco/support/openocd_stm32h747i_disco_m7.cfg +++ b/boards/arm/stm32h747i_disco/support/openocd_stm32h747i_disco_m7.cfg @@ -5,5 +5,24 @@ transport select hla_swd source [find target/stm32h7x.cfg] -reset_config srst_only +# Use connect_assert_srst here to be able to programm +# even when core is in sleep mode +reset_config srst_only srst_nogate connect_assert_srst +$_CHIPNAME.cpu0 configure -event gdb-attach { + echo "Debugger attaching: halting execution" + gdb_breakpoint_override hard +} + +$_CHIPNAME.cpu0 configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +# Due to the use of connect_assert_srst, running gdb requires +# to reset halt just after openocd init. +rename init old_init +proc init {} { + old_init + reset halt +} diff --git a/boards/arm/stm32l1_disco/CMakeLists.txt b/boards/arm/stm32l1_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32l1_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32l1_disco/pinmux.c b/boards/arm/stm32l1_disco/pinmux.c deleted file mode 100644 index 4f97759c4c76cb..00000000000000 --- a/boards/arm/stm32l1_disco/pinmux.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2019 eTactica ehf - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PA9, STM32L1X_PINMUX_FUNC_PA9_USART1_TX}, - {STM32_PIN_PA10, STM32L1X_PINMUX_FUNC_PA10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L1X_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PA3, STM32L1X_PINMUX_FUNC_PA3_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - {STM32_PIN_PB10, STM32L1X_PINMUX_FUNC_PB10_USART3_TX}, - {STM32_PIN_PB11, STM32L1X_PINMUX_FUNC_PB11_USART3_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB6, STM32L1X_PINMUX_FUNC_PB6_I2C1_SCL}, - {STM32_PIN_PB7, STM32L1X_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - {STM32_PIN_PB10, STM32L1X_PINMUX_FUNC_PB10_I2C2_SCL}, - {STM32_PIN_PB11, STM32L1X_PINMUX_FUNC_PB11_I2C2_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PA4, STM32L1X_PINMUX_FUNC_PA4_SPI1_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PA5, STM32L1X_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PA6, STM32L1X_PINMUX_FUNC_PA6_SPI1_MISO}, - {STM32_PIN_PA7, STM32L1X_PINMUX_FUNC_PA7_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PB12, STM32L1X_PINMUX_FUNC_PB12_SPI2_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PB13, STM32L1X_PINMUX_FUNC_PB13_SPI2_SCK}, - {STM32_PIN_PB14, STM32L1X_PINMUX_FUNC_PB14_SPI2_MISO}, - {STM32_PIN_PB15, STM32L1X_PINMUX_FUNC_PB15_SPI2_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32l1_disco/stm32l1_disco.dts b/boards/arm/stm32l1_disco/stm32l1_disco.dts index 1eb2652635b163..6036224084b390 100644 --- a/boards/arm/stm32l1_disco/stm32l1_disco.dts +++ b/boards/arm/stm32l1_disco/stm32l1_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32L1DISCOVERY board"; - compatible = "st,stm32l1discovery", "st,stm32l151"; + compatible = "st,stm32l1discovery"; chosen { zephyr,console = &usart1; @@ -46,34 +47,43 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; status = "okay"; }; diff --git a/boards/arm/stm32l476g_disco/CMakeLists.txt b/boards/arm/stm32l476g_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32l476g_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32l476g_disco/pinmux.c b/boards/arm/stm32l476g_disco/pinmux.c deleted file mode 100644 index dca866d90df24e..00000000000000 --- a/boards/arm/stm32l476g_disco/pinmux.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017 Arthur Sfez - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32L476G DISCOVERY board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PD5, STM32L4X_PINMUX_FUNC_PD5_USART2_TX}, - {STM32_PIN_PD6, STM32L4X_PINMUX_FUNC_PD6_USART2_RX}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32l476g_disco/stm32l476g_disco.dts b/boards/arm/stm32l476g_disco/stm32l476g_disco.dts index ab147e560c8951..f563c658bfc1b0 100644 --- a/boards/arm/stm32l476g_disco/stm32l476g_disco.dts +++ b/boards/arm/stm32l476g_disco/stm32l476g_disco.dts @@ -10,10 +10,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32L476G-DISCO board"; - compatible = "st,stm32l476g-disco", "st,stm32l476"; + compatible = "st,stm32l476g-disco"; chosen { zephyr,console = &usart2; @@ -38,23 +39,23 @@ compatible = "gpio-keys"; joy_center: joystick_center { label = "joystick center"; - gpios = <&gpioa 0 GPIO_ACTIVE_LOW>; + gpios = <&gpioa 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_down: joystick_down { label = "joystick down"; - gpios = <&gpioa 5 GPIO_ACTIVE_LOW>; + gpios = <&gpioa 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_up: joystick_up { label = "joystick up"; - gpios = <&gpioa 3 GPIO_ACTIVE_LOW>; + gpios = <&gpioa 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_left: joystick_left { label = "joystick left"; - gpios = <&gpioa 1 GPIO_ACTIVE_LOW>; + gpios = <&gpioa 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_right: joystick_right { label = "joystick right"; - gpios = <&gpioa 2 GPIO_ACTIVE_LOW>; + gpios = <&gpioa 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; }; @@ -65,6 +66,7 @@ }; &usart2 { + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>; current-speed = <115200>; status = "okay"; }; diff --git a/boards/arm/stm32l476g_disco/stm32l476g_disco_defconfig b/boards/arm/stm32l476g_disco/stm32l476g_disco_defconfig index 82cefc799757e9..4642f74bdf12d4 100644 --- a/boards/arm/stm32l476g_disco/stm32l476g_disco_defconfig +++ b/boards/arm/stm32l476g_disco/stm32l476g_disco_defconfig @@ -5,6 +5,12 @@ CONFIG_SOC_STM32L476XX=y # 80MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=80000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/stm32l496g_disco/CMakeLists.txt b/boards/arm/stm32l496g_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32l496g_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32l496g_disco/pinmux.c b/boards/arm/stm32l496g_disco/pinmux.c deleted file mode 100644 index f7a2c1a127b606..00000000000000 --- a/boards/arm/stm32l496g_disco/pinmux.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016 Open-RnD Sp. z o.o. - * Copyright (c) 2016 BayLibre, SAS - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32L476G-DISCO board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - {STM32_PIN_PB6, STM32L4X_PINMUX_FUNC_PB6_USART1_TX}, - {STM32_PIN_PG10, STM32L4X_PINMUX_FUNC_PG10_USART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - {STM32_PIN_PA2, STM32L4X_PINMUX_FUNC_PA2_USART2_TX}, - {STM32_PIN_PD6, STM32L4X_PINMUX_FUNC_PD6_USART2_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpuart1), okay) && CONFIG_SERIAL - {STM32_PIN_PG7, STM32L4X_PINMUX_FUNC_PG7_LPUART1_TX}, - {STM32_PIN_PG8, STM32L4X_PINMUX_FUNC_PG8_LPUART1_RX}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - {STM32_PIN_PB8, STM32L4X_PINMUX_FUNC_PB8_I2C1_SCL}, - {STM32_PIN_PB7, STM32L4X_PINMUX_FUNC_PB7_I2C1_SDA}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI - {STM32_PIN_PA5, STM32L4X_PINMUX_FUNC_PA5_SPI1_SCK}, - {STM32_PIN_PB4, STM32L4X_PINMUX_FUNC_PB4_SPI1_MISO}, - {STM32_PIN_PB5, STM32L4X_PINMUX_FUNC_PB5_SPI1_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay) && CONFIG_PWM - {STM32_PIN_PA0, STM32L4X_PINMUX_FUNC_PA0_PWM2_CH1}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(sdmmc1), okay) && \ - CONFIG_DISK_ACCESS_STM32_SDMMC - {STM32_PIN_PC8, STM32L4X_PINMUX_FUNC_PC8_SDMMC1_D0}, - {STM32_PIN_PC9, STM32L4X_PINMUX_FUNC_PC9_SDMMC1_D1}, - {STM32_PIN_PC10, STM32L4X_PINMUX_FUNC_PC10_SDMMC1_D2}, - {STM32_PIN_PC11, STM32L4X_PINMUX_FUNC_PC11_SDMMC1_D3}, - {STM32_PIN_PC12, STM32L4X_PINMUX_FUNC_PC12_SDMMC1_CK}, - {STM32_PIN_PD2, STM32L4X_PINMUX_FUNC_PD2_SDMMC1_CMD}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32l496g_disco/stm32l496g_disco.dts b/boards/arm/stm32l496g_disco/stm32l496g_disco.dts index cfb28a561b4dda..8b4ccc8ad9619d 100644 --- a/boards/arm/stm32l496g_disco/stm32l496g_disco.dts +++ b/boards/arm/stm32l496g_disco/stm32l496g_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32L496G-DISCO board"; - compatible = "st,stm32l496g-disco", "st,stm32l496"; + compatible = "st,stm32l496g-disco"; chosen { zephyr,console = &usart2; @@ -30,23 +31,23 @@ compatible = "gpio-keys"; joy_sel: joystick_select { label = "joystick select"; - gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + gpios = <&gpioc 13 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_down: joystick_down { label = "joystick down"; - gpios = <&gpioi 10 GPIO_ACTIVE_LOW>; + gpios = <&gpioi 10 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_up: joystick_up { label = "joystick up"; - gpios = <&gpioi 8 GPIO_ACTIVE_LOW>; + gpios = <&gpioi 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_left: joystick_left { label = "joystick left"; - gpios = <&gpioi 9 GPIO_ACTIVE_LOW>; + gpios = <&gpioi 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; joy_right: joystick_right { label = "joystick right"; - gpios = <&gpiof 11 GPIO_ACTIVE_LOW>; + gpios = <&gpiof 11 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; }; }; @@ -61,16 +62,19 @@ arduino_spi: &spi1 {}; arduino_serial: &lpuart1 {}; &usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pg10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pd6>; current-speed = <115200>; status = "okay"; }; &lpuart1 { + pinctrl-0 = <&lpuart1_tx_pg7 &lpuart1_rx_pg8>; current-speed = <115200>; status = "okay"; }; @@ -80,15 +84,18 @@ arduino_serial: &lpuart1 {}; pwm2: pwm { status = "okay"; + pinctrl-0 = <&tim2_ch1_pa0>; }; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pb4 &spi1_mosi_pb5>; status = "okay"; }; @@ -97,5 +104,8 @@ arduino_serial: &lpuart1 {}; }; &sdmmc1 { + pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9 + &sdmmc1_d2_pc10 &sdmmc1_d3_pc11 + &sdmmc1_ck_pc12 &sdmmc1_cmd_pd2>; status = "okay"; }; diff --git a/boards/arm/stm32l496g_disco/stm32l496g_disco_defconfig b/boards/arm/stm32l496g_disco/stm32l496g_disco_defconfig index bf20756ecb86b3..3956f0d2137800 100644 --- a/boards/arm/stm32l496g_disco/stm32l496g_disco_defconfig +++ b/boards/arm/stm32l496g_disco/stm32l496g_disco_defconfig @@ -5,6 +5,12 @@ CONFIG_SOC_STM32L496XX=y # 80MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=80000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/stm32l562e_dk/Kconfig.board b/boards/arm/stm32l562e_dk/Kconfig.board new file mode 100644 index 00000000000000..44cabce93d3d5e --- /dev/null +++ b/boards/arm/stm32l562e_dk/Kconfig.board @@ -0,0 +1,8 @@ +# STM32L562E-DK Discovery board configuration + +# Copyright (c) 2020 Yestin Sun +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_STM32L562E_DK + bool "STM32L562E-DK Discovery Development Board" + depends on SOC_STM32L562XX diff --git a/boards/arm/stm32l562e_dk/Kconfig.defconfig b/boards/arm/stm32l562e_dk/Kconfig.defconfig new file mode 100644 index 00000000000000..1a631d7c5106b5 --- /dev/null +++ b/boards/arm/stm32l562e_dk/Kconfig.defconfig @@ -0,0 +1,11 @@ +# STM32L562E-DK Discovery board configuration + +# Copyright (c) 2020 Yestin Sun +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_STM32L562E_DK + +config BOARD + default "stm32l562e_dk" + +endif # BOARD_STM32L562E_DK diff --git a/boards/arm/stm32l562e_dk/arduino_r3_connector.dtsi b/boards/arm/stm32l562e_dk/arduino_r3_connector.dtsi new file mode 100644 index 00000000000000..87ee9535e22693 --- /dev/null +++ b/boards/arm/stm32l562e_dk/arduino_r3_connector.dtsi @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 Yestin Sun + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 0 0>, /* A0 */ + <1 0 &gpioa 1 0>, /* A1 */ + <2 0 &gpioa 4 0>, /* A2 */ + <3 0 &gpioa 5 0>, /* A3 */ + <4 0 &gpioc 4 0>, /* A4 */ + <5 0 &gpioc 5 0>, /* A5 */ + <6 0 &gpiob 10 0>, /* D0 */ + <7 0 &gpiob 11 0>, /* D1 */ + <8 0 &gpiod 11 0>, /* D2 */ + <9 0 &gpiod 12 0>, /* D3 */ + <10 0 &gpiof 4 0>, /* D4 */ + <11 0 &gpiod 13 0>, /* D5 */ + <12 0 &gpiob 8 0>, /* D6 */ + <13 0 &gpioc 6 0>, /* D7 */ + <14 0 &gpiog 0 0>, /* D8 */ + <15 0 &gpiob 9 0>, /* D9 */ + <16 0 &gpioe 0 0>, /* D10 */ + <17 0 &gpiob 5 0>, /* D11 */ + <18 0 &gpiob 4 0>, /* D12 */ + <19 0 &gpiog 9 0>, /* D13 */ + <20 0 &gpiob 7 0>, /* D14 */ + <21 0 &gpiob 6 0>; /* D15 */ + }; +}; diff --git a/boards/arm/stm32l562e_dk/board.cmake b/boards/arm/stm32l562e_dk/board.cmake new file mode 100644 index 00000000000000..4e000bdbf822c9 --- /dev/null +++ b/boards/arm/stm32l562e_dk/board.cmake @@ -0,0 +1,7 @@ +set_ifndef(BOARD_DEBUG_RUNNER pyocd) +set_ifndef(BOARD_FLASH_RUNNER pyocd) + +board_runner_args(pyocd "--target=stm32l562qeixq") + +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/stm32l562e_dk/doc/img/stm32l562e_dk.jpg b/boards/arm/stm32l562e_dk/doc/img/stm32l562e_dk.jpg new file mode 100644 index 00000000000000..4a89f61212b887 Binary files /dev/null and b/boards/arm/stm32l562e_dk/doc/img/stm32l562e_dk.jpg differ diff --git a/boards/arm/stm32l562e_dk/doc/index.rst b/boards/arm/stm32l562e_dk/doc/index.rst new file mode 100644 index 00000000000000..f1399c4dea1c8b --- /dev/null +++ b/boards/arm/stm32l562e_dk/doc/index.rst @@ -0,0 +1,276 @@ +.. _stm32l562e_dk_board: + +ST STM32L562E-DK Discovery +########################## + +Overview +******** + +The STM32L562E-DK Discovery kit is designed as a complete demonstration and +development platform for STMicroelectronics Arm |reg| Cortex |reg|-M33 core-based +STM32L562QEI6QU microcontroller with TrustZone |reg|. Here are some highlights of +the STM32L562E-DK Discovery board: + + +- STM32L562QEI6QU microcontroller featuring 512 Kbytes of Flash memory and 256 Kbytes of SRAM in BGA132 package +- 1.54" 240 x 240 pixel-262K color TFT LCD module with parallel interface and touch-control panel +- USB Type-C |trade| Sink device FS +- On-board energy meter: 300 nA to 150 mA measurement range with a dedicated USB interface +- SAI Audio CODEC +- MEMS digital microphones +- 512-Mbit Octal-SPI Flash memory +- Bluetooth |reg| V4.1 Low Energy module +- iNEMO 3D accelerometer and 3D gyroscope +- Board connectors + + - STMod+ expansion connector with fan-out expansion board for Wi‑Fi |reg|, Grove and mikroBUS |trade| compatible connectors + - Pmod |trade| expansion connector + - Audio MEMS daughterboard expansion connector + - ARDUINO |reg| Uno V3 expansion connector + +- Flexible power-supply options + + - ST-LINK + - USB VBUS + - external sources + +- On-board STLINK-V3E debugger/programmer with USB re-enumeration capability: + + - mass storage + - Virtual COM port + - debug port + +- 2 user LEDs +- User and reset push-buttons + +.. image:: img/stm32l562e_dk.jpg + :width: 460px + :align: center + :height: 474px + :alt: STM32L562E-DK Discovery + +More information about the board can be found at the `STM32L562E-DK Discovery website`_. + +Hardware +******** + +The STM32L562xx devices are an ultra-low-power microcontrollers family (STM32L5 +Series) based on the high-performance Arm |reg| Cortex |reg|-M33 32-bit RISC core. +They operate at a frequency of up to 110 MHz. + +- Ultra-low-power with FlexPowerControl (down to 108 nA Standby mode and 62 uA/MHz run mode) +- Core: ARM |reg| 32-bit Cortex |reg| -M33 CPU with TrustZone |reg| and FPU. +- Performance benchmark: + + - 1.5 DMPIS/MHz (Drystone 2.1) + - 442 CoreMark |reg| (4.02 CoreMark |reg| /MHZ) + +- Security + + - Arm |reg| TrustZone |reg| and securable I/Os memories and peripherals + - Flexible life cycle scheme with RDP (readout protection) + - Root of trust thanks to unique boot entry and hide protection area (HDP) + - Secure Firmware Installation thanks to embedded Root Secure Services + - Secure Firmware Update support with TF-M + - AES coprocessor + - Public key accelerator + - On-the-fly decryption of Octo-SPI external memories + - HASH hardware accelerator + - Active tamper and protection temperature, voltage and frequency attacks + - True Random Number Generator NIST SP800-90B compliant + - 96-bit unique ID + - 512-byte One-Time Programmable for user data + +- Clock management: + + - 4 to 48 MHz crystal oscillator + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) + - Internal low-power 32 kHz RC ( |plusminus| 5%) + - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by + LSE (better than |plusminus| 0.25 % accuracy) + - 3 PLLs for system clock, USB, audio, ADC + +- Power management + + - Embedded regulator (LDO) with three configurable range output to supply the digital circuitry + - Embedded SMPS step-down converter + - External SMPS support + +- RTC with HW calendar, alarms and calibration +- Up to 114 fast I/Os, most 5 V-tolerant, up to 14 I/Os with independent supply down to 1.08 V +- Up to 22 capacitive sensing channels: support touchkey, linear and rotary touch sensors +- Up to 16 timers and 2 watchdogs + + - 2x 16-bit advanced motor-control + - 2x 32-bit and 5x 16-bit general purpose + - 2x 16-bit basic + - 3x low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - 2x SysTick timer + +- Memories + + - Up to 512 MB Flash, 2 banks read-while-write + - 512 KB of SRAM including 64 KB with hardware parity check + - External memory interface for static memories supporting SRAM, PSRAM, NOR, NAND and FRAM memories + - OCTOSPI memory interface + +- Rich analog peripherals (independent supply) + + - 3x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS + - 2x 12-bit DAC, low-power sample and hold + - 2x operational amplifiers with built-in PGA + - 2x ultra-low-power comparators + - 4x digital filters for sigma delta modulator + +- 19x communication interfaces + + - USB Type-C / USB power delivery controller + - 2.0 full-speed crystal less solution, LPM and BCD + - 2x SAIs (serial audio interface) + - 4x I2C FM+(1 Mbit/s), SMBus/PMBus + - 6x USARTs (ISO 7816, LIN, IrDA, modem) + - 3x SPIs (7x SPIs with USART and OCTOSPI in SPI mode) + - 1xFDCAN + - 1xSDMMC interface + - 2x 14 channel DMA controllers + +- CRC calculation unit +- Development support: serial wire debug (SWD), JTAG, Embedded Trace Macrocell |trade| + + +More information about STM32L562QE can be found here: + +- `STM32L562QE on www.st.com`_ +- `STM32L562 reference manual`_ + +Supported Features +================== + +The Zephyr stm32l562e_dk board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration can be found in the defconfig file: +``boards/arm/stm32l562e_dk/stm32l562e_dk_defconfig`` + + +Connections and IOs +=================== + +STM32L562E-DK Discovery Board has 8 GPIO controllers. These controllers are responsible for pin muxing, +input/output, pull-up, etc. + +For mode details please refer to `STM32L562E-DK Discovery board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- USART_1 TX/RX : PA9/PA10 +- I2C_1 SCL/SDA : PB6/PB7 +- USER_PB : PC13 +- LD10 : PG12 + +System Clock +------------ + +STM32L562E-DK System Clock could be driven by internal or external oscillator, +as well as main PLL clock. By default System clock is driven by PLL clock at +110MHz, driven by 4MHz medium speed internal oscillator. + +Serial Port +----------- + +STM32L562E-DK Discovery board has 6 U(S)ARTs. The Zephyr console output is +assigned to USART1. Default settings are 115200 8N1. + + +Programming and Debugging +************************* + +Applications for the ``stm32l562e_dk`` board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +STM32L562E-DK Discovery board includes an ST-LINK/V3E embedded debug tool +interface. This interface is not yet supported by the openocd version. +Instead, support can be enabled on pyocd by adding "pack" support with +the following pyocd command: + +.. code-block:: console + + $ pyocd pack --update + $ pyocd pack --install stm32l562qe + +STM32L562E-DK Discovery board includes an ST-LINK/V2-1 embedded debug tool +interface. This interface is supported by the openocd version +included in the Zephyr SDK since v0.9.2. + +Flashing an application to STM32L562E-DK Discovery +-------------------------------------------------- + +Connect the STM32L562E-DK Discovery to your host computer using the USB port. +Then build and flash an application. Here is an example for the +:ref:`hello_world` application. + +Run a serial host program to connect with your Nucleo board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +Then build and flash the application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32l562e_dk + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + Hello World! stm32l562e_dk + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32l562e_dk + :maybe-skip-config: + :goals: debug + +.. _STM32L562E-DK Discovery website: + https://www.st.com/en/evaluation-tools/stm32l562e-dk.html + +.. _STM32L562E-DK Discovery board User Manual: + https://www.st.com/resource/en/user_manual/dm00635554.pdf + +.. _STM32L562QE on www.st.com: + https://www.st.com/en/microcontrollers/stm32l562qe.html + +.. _STM32L562 reference manual: + http://www.st.com/resource/en/reference_manual/DM00346336.pdf diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk.dts b/boards/arm/stm32l562e_dk/stm32l562e_dk.dts new file mode 100644 index 00000000000000..f18d240a45574b --- /dev/null +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 Yestin Sun + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "stm32l562e_dk_common.dtsi" + +/ { + model = "STMicroelectronics STM32L562E-DK Discovery board"; + compatible = "st,stm32l562e-dk"; + + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + aliases { + led0 = &green_led_10; + sw0 = &user_button; + }; +}; diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml b/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml new file mode 100644 index 00000000000000..c6ab1e87c00ff0 --- /dev/null +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk.yaml @@ -0,0 +1,13 @@ +identifier: stm32l562e_dk +name: ST STM32L562E-DK Discovery +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - i2c + - lsm6dso +ram: 192 +flash: 512 diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi b/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi new file mode 100644 index 00000000000000..5cce9bb993362a --- /dev/null +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk_common.dtsi @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 Yestin Sun + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "arduino_r3_connector.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + red_led_9: led_9 { + gpios = <&gpiod 3 GPIO_ACTIVE_HIGH>; + label = "User LD9"; + }; + green_led_10: led_10 { + gpios = <&gpiog 12 GPIO_ACTIVE_HIGH>; + label = "User LD10"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + current-speed = <115200>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; + status = "okay"; + clock-frequency = ; + + lsm6dso@6a { + compatible = "st,lsm6dso"; + reg = <0x6a>; + irq-gpios = <&gpiof 3 GPIO_ACTIVE_HIGH>; + label = "LSM6DSO"; + }; +}; diff --git a/boards/arm/stm32l562e_dk/stm32l562e_dk_defconfig b/boards/arm/stm32l562e_dk/stm32l562e_dk_defconfig new file mode 100644 index 00000000000000..c2579e2a6ef44e --- /dev/null +++ b/boards/arm/stm32l562e_dk/stm32l562e_dk_defconfig @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32L5X=y +CONFIG_SOC_STM32L562XX=y +# 110MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=110000000 + +# enable uart driver +CONFIG_SERIAL=y + +# enable pinmux +CONFIG_PINMUX=y + +# enable GPIO +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# PLL configuration +CONFIG_CLOCK_STM32_PLL_SRC_MSI=y +CONFIG_CLOCK_STM32_MSI_RANGE=6 +# produce 110MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=1 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=55 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=7 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_R_DIVISOR=2 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=1 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 + +# console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/stm32mp157c_dk2/CMakeLists.txt b/boards/arm/stm32mp157c_dk2/CMakeLists.txt deleted file mode 100644 index 79216cf2ccbb87..00000000000000 --- a/boards/arm/stm32mp157c_dk2/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2019 STMicroelectronics -# -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32mp157c_dk2/pinmux.c b/boards/arm/stm32mp157c_dk2/pinmux.c deleted file mode 100644 index 5f42992f1c74a5..00000000000000 --- a/boards/arm/stm32mp157c_dk2/pinmux.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2019 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32MP157c_dk2 board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - { STM32_PIN_PB10, STM32MP1X_PINMUX_FUNC_PB10_USART3_TX }, - { STM32_PIN_PB12, STM32MP1X_PINMUX_FUNC_PB12_USART3_RX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart7), okay) && CONFIG_SERIAL - { STM32_PIN_PE7, STM32MP1X_PINMUX_FUNC_PE7_UART7_RX }, - { STM32_PIN_PE8, STM32MP1X_PINMUX_FUNC_PE8_UART7_TX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c5), okay) && CONFIG_I2C - { STM32_PIN_PA11, STM32MP1X_PINMUX_FUNC_PA11_I2C5_SCL }, - { STM32_PIN_PA12, STM32MP1X_PINMUX_FUNC_PA12_I2C5_SDA }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi4), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PE11, STM32MP1X_PINMUX_FUNC_PE11_SPI4_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PE12, STM32MP1X_PINMUX_FUNC_PE12_SPI4_SCK}, - {STM32_PIN_PE13, STM32MP1X_PINMUX_FUNC_PE13_SPI4_MISO | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PE14, STM32MP1X_PINMUX_FUNC_PE14_SPI4_MOSI}, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi5), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - {STM32_PIN_PF6, STM32MP1X_PINMUX_FUNC_PF6_SPI5_NSS}, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - {STM32_PIN_PF7, STM32MP1X_PINMUX_FUNC_PF7_SPI5_SCK}, - {STM32_PIN_PF8, STM32MP1X_PINMUX_FUNC_PF8_SPI5_MISO | - STM32_OSPEEDR_VERY_HIGH_SPEED}, - {STM32_PIN_PF9, STM32MP1X_PINMUX_FUNC_PF9_SPI5_MOSI}, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.dts b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.dts index 5065c9d03359d9..e2b44a1f0023ef 100644 --- a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.dts +++ b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.dts @@ -6,11 +6,12 @@ /dts-v1/; #include +#include #include "arduino_r3_connector.dtsi" / { model = "STMicroelectronics STM32MP157-DK2 board"; - compatible = "st,stm32mp157c-dk2", "st,stm32mp15"; + compatible = "st,stm32mp157c-dk2"; chosen { /* * By default, Zephyr console and shell are assigned to @@ -48,20 +49,30 @@ }; +&spi4_miso_pe13{ slew-rate = "very-high-speed"; }; + &spi4{ + pinctrl-0 = <&spi4_nss_pe11 &spi4_sck_pe12 + &spi4_miso_pe13 &spi4_mosi_pe14>; status = "okay"; }; +&spi5_miso_pf8{ slew-rate = "very-high-speed"; }; + &spi5{ + pinctrl-0 = <&spi5_nss_pf6 &spi5_sck_pf7 + &spi5_miso_pf8 &spi5_mosi_pf9>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb12>; current-speed = <115200>; status = "okay"; }; &uart7 { + pinctrl-0 = <&uart7_tx_pe8 &uart7_rx_pe7>; current-speed = <115200>; status = "okay"; }; @@ -71,6 +82,7 @@ }; &i2c5 { + pinctrl-0 = <&i2c5_scl_pa11 &i2c5_sda_pa12>; status = "okay"; clock-frequency = ; }; diff --git a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.yaml b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.yaml index 3507a75630adc0..a78e1d2fb9f2b0 100644 --- a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.yaml +++ b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2.yaml @@ -4,7 +4,7 @@ type: mcu arch: arm toolchain: - zephyr - - gccarmemb + - gnuarmemb - xtools supported: - arduino_i2c diff --git a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2_defconfig b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2_defconfig index f746cc1be4f5da..6695a292855342 100644 --- a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2_defconfig +++ b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2_defconfig @@ -6,6 +6,12 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=209000000 # enable GPIO CONFIG_GPIO=y +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/arm/stm32vl_disco/CMakeLists.txt b/boards/arm/stm32vl_disco/CMakeLists.txt deleted file mode 100644 index d1b8108cfed55b..00000000000000 --- a/boards/arm/stm32vl_disco/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -if(CONFIG_PINMUX) -zephyr_library() -zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() diff --git a/boards/arm/stm32vl_disco/pinmux.c b/boards/arm/stm32vl_disco/pinmux.c deleted file mode 100644 index 0e64c8c307d032..00000000000000 --- a/boards/arm/stm32vl_disco/pinmux.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2020 Jonas Eriksson, Up to Code AB - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#include - -/* pin assignments for STM32 Discovery VL board */ -static const struct pin_config pinconf[] = { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay) && CONFIG_SERIAL - { STM32_PIN_PA9, STM32F1_PINMUX_FUNC_PA9_USART1_TX }, - { STM32_PIN_PA10, STM32F1_PINMUX_FUNC_PA10_USART1_RX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay) && CONFIG_SERIAL - { STM32_PIN_PA2, STM32F1_PINMUX_FUNC_PA2_USART2_TX }, - { STM32_PIN_PA3, STM32F1_PINMUX_FUNC_PA3_USART2_RX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay) && CONFIG_SERIAL - { STM32_PIN_PB10, STM32F1_PINMUX_FUNC_PB10_USART3_TX }, - { STM32_PIN_PB11, STM32F1_PINMUX_FUNC_PB11_USART3_RX }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay) && CONFIG_PWM - { STM32_PIN_PA8, STM32F1_PINMUX_FUNC_PA8_PWM1_CH1 }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - { STM32_PIN_PA4, STM32F1_PINMUX_FUNC_PA4_SPI1_MASTER_NSS }, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - { STM32_PIN_PA5, STM32F1_PINMUX_FUNC_PA5_SPI1_MASTER_SCK }, - { STM32_PIN_PA6, STM32F1_PINMUX_FUNC_PA6_SPI1_MASTER_MISO }, - { STM32_PIN_PA7, STM32F1_PINMUX_FUNC_PA7_SPI1_MASTER_MOSI }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI -#ifdef CONFIG_SPI_STM32_USE_HW_SS - { STM32_PIN_PB12, STM32F1_PINMUX_FUNC_PB12_SPI2_MASTER_NSS }, -#endif /* CONFIG_SPI_STM32_USE_HW_SS */ - { STM32_PIN_PB13, STM32F1_PINMUX_FUNC_PB13_SPI2_MASTER_SCK }, - { STM32_PIN_PB14, STM32F1_PINMUX_FUNC_PB14_SPI2_MASTER_MISO }, - { STM32_PIN_PB15, STM32F1_PINMUX_FUNC_PB15_SPI2_MASTER_MOSI }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C - { STM32_PIN_PB6, STM32F1_PINMUX_FUNC_PB6_I2C1_SCL }, - { STM32_PIN_PB7, STM32F1_PINMUX_FUNC_PB7_I2C1_SDA }, -#endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C - { STM32_PIN_PB10, STM32F1_PINMUX_FUNC_PB10_I2C2_SCL }, - { STM32_PIN_PB11, STM32F1_PINMUX_FUNC_PB11_I2C2_SDA }, -#endif -}; - -static int pinmux_stm32_init(struct device *port) -{ - ARG_UNUSED(port); - - stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf)); - - return 0; -} - -SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, - CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY); diff --git a/boards/arm/stm32vl_disco/stm32vl_disco.dts b/boards/arm/stm32vl_disco/stm32vl_disco.dts index 270d9f7e2ea221..3c8998b021f912 100644 --- a/boards/arm/stm32vl_disco/stm32vl_disco.dts +++ b/boards/arm/stm32vl_disco/stm32vl_disco.dts @@ -6,10 +6,11 @@ /dts-v1/; #include +#include / { model = "STMicroelectronics STM32VLDISCOVERY board"; - compatible = "st,stm32vldiscovery", "st,stm32f100"; + compatible = "st,stm32vldiscovery"; chosen { zephyr,console = &usart1; @@ -46,34 +47,52 @@ }; &usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; current-speed = <115200>; status = "okay"; }; &usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; current-speed = <115200>; status = "okay"; }; &usart3 { + pinctrl-0 = <&usart3_tx_pb10 &usart3_rx_pb11>; current-speed = <115200>; status = "okay"; }; &i2c1 { + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; status = "okay"; clock-frequency = ; }; &i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; status = "okay"; clock-frequency = ; }; &spi1 { + pinctrl-0 = <&spi1_nss_master_pa4 &spi1_sck_master_pa5 + &spi1_miso_master_pa6 &spi1_mosi_master_pa7>; status = "okay"; }; &spi2 { + pinctrl-0 = <&spi2_nss_master_pb12 &spi2_sck_master_pb13 + &spi2_miso_master_pb14 &spi2_mosi_master_pb15>; status = "okay"; }; + +&timers1 { + status = "okay"; + + pwm1: pwm { + status = "okay"; + pinctrl-0 = <&tim1_ch1_pwm_pa8>; + }; +}; diff --git a/boards/arm/stm32vl_disco/stm32vl_disco_defconfig b/boards/arm/stm32vl_disco/stm32vl_disco_defconfig index cf243046b5fc57..92a341ba5c57a4 100644 --- a/boards/arm/stm32vl_disco/stm32vl_disco_defconfig +++ b/boards/arm/stm32vl_disco/stm32vl_disco_defconfig @@ -7,6 +7,12 @@ CONFIG_SOC_STM32F100XB=y # 24MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=24000000 +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable uart driver CONFIG_SERIAL=y diff --git a/boards/arm/thingy52_nrf52832/board.c b/boards/arm/thingy52_nrf52832/board.c index 1d81408bc8669a..9d134e5683a80c 100644 --- a/boards/arm/thingy52_nrf52832/board.c +++ b/boards/arm/thingy52_nrf52832/board.c @@ -13,13 +13,13 @@ struct pwr_ctrl_cfg { const char *port; - u32_t pin; + uint32_t pin; }; -static int pwr_ctrl_init(struct device *dev) +static int pwr_ctrl_init(const struct device *dev) { - const struct pwr_ctrl_cfg *cfg = dev->config_info; - struct device *gpio; + const struct pwr_ctrl_cfg *cfg = dev->config; + const struct device *gpio; gpio = device_get_binding(cfg->port); if (!gpio) { @@ -52,8 +52,10 @@ static const struct pwr_ctrl_cfg vdd_pwr_ctrl_cfg = { .pin = VDD_PWR_CTRL_GPIO_PIN, }; -DEVICE_INIT(vdd_pwr_ctrl_init, "", pwr_ctrl_init, NULL, &vdd_pwr_ctrl_cfg, - POST_KERNEL, CONFIG_BOARD_VDD_PWR_CTRL_INIT_PRIORITY); +DEVICE_DEFINE(vdd_pwr_ctrl_init, "", pwr_ctrl_init, NULL, NULL, + &vdd_pwr_ctrl_cfg, + POST_KERNEL, CONFIG_BOARD_VDD_PWR_CTRL_INIT_PRIORITY, + NULL); #ifdef CONFIG_SENSOR @@ -70,8 +72,8 @@ static const struct pwr_ctrl_cfg ccs_vdd_pwr_ctrl_cfg = { .pin = CCS_VDD_PWR_CTRL_GPIO_PIN, }; -DEVICE_INIT(ccs_vdd_pwr_ctrl_init, "", pwr_ctrl_init, NULL, - &ccs_vdd_pwr_ctrl_cfg, POST_KERNEL, - CONFIG_BOARD_CCS_VDD_PWR_CTRL_INIT_PRIORITY); +DEVICE_DEFINE(ccs_vdd_pwr_ctrl_init, "", pwr_ctrl_init, NULL, NULL, + &ccs_vdd_pwr_ctrl_cfg, POST_KERNEL, + CONFIG_BOARD_CCS_VDD_PWR_CTRL_INIT_PRIORITY, NULL); #endif diff --git a/boards/arm/thingy52_nrf52832/board.cmake b/boards/arm/thingy52_nrf52832/board.cmake index dd51220a30ef94..1105d66dabd6f7 100644 --- a/boards/arm/thingy52_nrf52832/board.cmake +++ b/boards/arm/thingy52_nrf52832/board.cmake @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +board_runner_args(nrfjprog "--softreset") board_runner_args(jlink "--device=nrf52" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/thingy52_nrf52832/doc/index.rst b/boards/arm/thingy52_nrf52832/doc/index.rst index 27e3197432f265..bc42dea8b6d7a4 100644 --- a/boards/arm/thingy52_nrf52832/doc/index.rst +++ b/boards/arm/thingy52_nrf52832/doc/index.rst @@ -40,9 +40,6 @@ More information about the board can be found at the `nRF52 DK website`_. The `Nordic Semiconductor Infocenter`_ contains the processor's information and the datasheet. -.. note:: - - In previous Zephyr releases this board was named *nrf52_pca20020*. Hardware ******** diff --git a/boards/arm/thingy52_nrf52832/thingy52_nrf52832.dts b/boards/arm/thingy52_nrf52832/thingy52_nrf52832.dts index 002cbfd6da328d..0e7a44f493d040 100644 --- a/boards/arm/thingy52_nrf52832/thingy52_nrf52832.dts +++ b/boards/arm/thingy52_nrf52832/thingy52_nrf52832.dts @@ -35,14 +35,17 @@ led0: led_0 { gpios = <&sx1509b 5 GPIO_ACTIVE_LOW>; label = "Green LED"; + //vin-supply = <&vdd_pwr>; }; led1: led_1 { gpios = <&sx1509b 6 GPIO_ACTIVE_LOW>; label = "Blue LED"; + //vin-supply = <&vdd_pwr>; }; led2: led_2 { gpios = <&sx1509b 7 GPIO_ACTIVE_LOW>; label = "Red LED"; + //vin-supply = <&vdd_pwr>; }; }; @@ -62,6 +65,42 @@ full-ohms = <(1500000 + 180000)>; power-gpios = <&sx1509b 4 0>; }; + + vdd_pwr: vdd-pwr-ctrl { + compatible = "regulator-fixed-sync", "regulator-fixed"; + label = "vdd-pwr-ctrl"; + regulator-name = "vdd-pwr-ctrl"; + enable-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + }; + + spk_pwr: spk-pwr-ctrl { + compatible = "regulator-fixed-sync", "regulator-fixed"; + label = "spk-pwr-ctrl"; + regulator-name = "spk-pwr-ctrl"; + enable-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; + }; + + mpu_pwr: mpu-pwr-ctrl { + compatible = "regulator-fixed"; + label = "mpu-pwr-ctrl"; + regulator-name = "mpu-pwr-ctrl"; + enable-gpios = <&sx1509b 8 GPIO_ACTIVE_HIGH>; + }; + + mic_pwr: mic-pwr-ctrl { + compatible = "regulator-fixed"; + label = "mic-pwr-ctrl"; + regulator-name = "mic-pwr-ctrl"; + enable-gpios = <&sx1509b 9 GPIO_ACTIVE_HIGH>; + }; + + ccs_pwr: ccs-pwr-ctrl { + compatible = "regulator-fixed"; + label = "ccs-pwr-ctrl"; + regulator-name = "ccs-pwr-ctrl"; + enable-gpios = <&sx1509b 10 GPIO_ACTIVE_HIGH>; + }; }; &adc { @@ -77,7 +116,7 @@ }; &uart0 { - compatible = "nordic,nrf-uart"; + compatible = "nordic,nrf-uarte"; status = "okay"; current-speed = <115200>; tx-pin = <3>; @@ -95,6 +134,7 @@ compatible = "semtech,sx1509b"; reg = <0x3e>; label = "GPIO_P0"; + vin-supply = <&vdd_pwr>; gpio-controller; #gpio-cells = <2>; ngpios = <16>; @@ -107,12 +147,14 @@ compatible = "st,lps22hb-press"; reg = <0x5c>; label = "LPS22HB"; + vin-supply = <&vdd_pwr>; }; hts221: hts221@5f { compatible = "st,hts221"; reg = <0x5f>; label = "HTS221"; + vin-supply = <&vdd_pwr>; drdy-gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>; }; @@ -120,6 +162,7 @@ compatible = "ams,ccs811"; reg = <0x5a>; label = "CCS811"; + vin-supply = <&ccs_pwr>; irq-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; reset-gpios = <&sx1509b 11 GPIO_ACTIVE_LOW>; wake-gpios = <&sx1509b 12 GPIO_ACTIVE_LOW>; diff --git a/boards/arm/thingy52_nrf52832/thingy52_nrf52832_defconfig b/boards/arm/thingy52_nrf52832/thingy52_nrf52832_defconfig index 86b2e857e763df..dcf4787fa15b21 100644 --- a/boards/arm/thingy52_nrf52832/thingy52_nrf52832_defconfig +++ b/boards/arm/thingy52_nrf52832/thingy52_nrf52832_defconfig @@ -4,9 +4,16 @@ CONFIG_SOC_SERIES_NRF52X=y CONFIG_SOC_NRF52832_QFAA=y CONFIG_BOARD_THINGY52_NRF52832=y +# Enable regulators +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED=y + # Enable MPU CONFIG_ARM_MPU=y +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + # enable GPIO CONFIG_GPIO=y diff --git a/boards/arm/twr_ke18f/Kconfig.defconfig b/boards/arm/twr_ke18f/Kconfig.defconfig index 08d51813d62e33..c2df29cc4f143f 100644 --- a/boards/arm/twr_ke18f/Kconfig.defconfig +++ b/boards/arm/twr_ke18f/Kconfig.defconfig @@ -39,6 +39,6 @@ endif # PINMUX_MCUX config TEMP_KINETIS default y if "$(dt_nodelabel_enabled,adc0)" - depends on SENSOR + depends on SENSOR && ADC endif # BOARD_TWR_KE18F diff --git a/boards/arm/twr_ke18f/board.cmake b/boards/arm/twr_ke18f/board.cmake index 8cae7d27051a66..cbe6b2dd7cfac9 100644 --- a/boards/arm/twr_ke18f/board.cmake +++ b/boards/arm/twr_ke18f/board.cmake @@ -1,15 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -set_ifndef(OPENSDA_FW daplink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -elseif(OPENSDA_FW STREQUAL daplink) - board_set_debugger_ifnset(pyocd) - board_set_flasher_ifnset(pyocd) -endif() - board_runner_args(jlink "--device=MKE18F512xxx16") board_runner_args(pyocd "--target=ke18f16") diff --git a/boards/arm/twr_ke18f/doc/index.rst b/boards/arm/twr_ke18f/doc/index.rst index 5d8e1ae6dbe56e..ad1493177b7dde 100644 --- a/boards/arm/twr_ke18f/doc/index.rst +++ b/boards/arm/twr_ke18f/doc/index.rst @@ -163,13 +163,14 @@ path. Follow the instructions in :ref:`opensda-jlink-onboard-debug-probe` to program the `OpenSDA J-Link Firmware for TWR-KE18F`_. -Add the argument ``-DOPENSDA_FW=jlink`` when you invoke ``west build`` to -override the default runner from pyOCD to J-Link: +Add the arguments ``-DBOARD_FLASH_RUNNER=jlink`` and +``-DBOARD_DEBUG_RUNNER=jlink`` when you invoke ``west build`` to override the +default runner from pyOCD to J-Link: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: twr_ke18f - :gen-args: -DOPENSDA_FW=jlink + :gen-args: -DBOARD_FLASH_RUNNER=jlink -DBOARD_DEBUG_RUNNER=jlink :goals: build Configuring a Console diff --git a/boards/arm/twr_ke18f/pinmux.c b/boards/arm/twr_ke18f/pinmux.c index 2b22f29da79c26..d5783d4870b97d 100644 --- a/boards/arm/twr_ke18f/pinmux.c +++ b/boards/arm/twr_ke18f/pinmux.c @@ -8,29 +8,29 @@ #include #include -static int twr_ke18f_pinmux_init(struct device *dev) +static int twr_ke18f_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTA - __unused struct device *porta = + __unused const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTB - __unused struct device *portb = + __unused const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTC - __unused struct device *portc = + __unused const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTD - __unused struct device *portd = + __unused const struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTE - __unused struct device *porte = + __unused const struct device *porte = device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME); #endif diff --git a/boards/arm/twr_ke18f/twr_ke18f.dts b/boards/arm/twr_ke18f/twr_ke18f.dts index e3a65c80842cb5..65a12363b0fc87 100644 --- a/boards/arm/twr_ke18f/twr_ke18f.dts +++ b/boards/arm/twr_ke18f/twr_ke18f.dts @@ -233,11 +233,12 @@ status = "okay"; }; +&edma { + status = "okay"; +}; + &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/twr_ke18f/twr_ke18f.yaml b/boards/arm/twr_ke18f/twr_ke18f.yaml index 44014ef0c847fc..7f55809d69edac 100644 --- a/boards/arm/twr_ke18f/twr_ke18f.yaml +++ b/boards/arm/twr_ke18f/twr_ke18f.yaml @@ -13,6 +13,7 @@ supported: - can - counter - dac + - dma - i2c - pwm - spi diff --git a/boards/arm/twr_ke18f/twr_ke18f_defconfig b/boards/arm/twr_ke18f/twr_ke18f_defconfig index 3980435be07b23..31224270089d56 100644 --- a/boards/arm/twr_ke18f/twr_ke18f_defconfig +++ b/boards/arm/twr_ke18f/twr_ke18f_defconfig @@ -14,3 +14,4 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 # Enable MPU CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/twr_kv58f220m/board.cmake b/boards/arm/twr_kv58f220m/board.cmake index 3121a63089ca6f..cdf53073e8b684 100644 --- a/boards/arm/twr_kv58f220m/board.cmake +++ b/boards/arm/twr_kv58f220m/board.cmake @@ -1,12 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -set_ifndef(OPENSDA_FW jlink) - -if(OPENSDA_FW STREQUAL jlink) - board_set_debugger_ifnset(jlink) - board_set_flasher_ifnset(jlink) -endif() - board_runner_args(jlink "--device=MKV58F1M0xxx24") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/twr_kv58f220m/pinmux.c b/boards/arm/twr_kv58f220m/pinmux.c index f8dd54361869d4..df488ddf046d02 100644 --- a/boards/arm/twr_kv58f220m/pinmux.c +++ b/boards/arm/twr_kv58f220m/pinmux.c @@ -8,28 +8,28 @@ #include #include -static int twr_kv58f220m_pinmux_init(struct device *dev) +static int twr_kv58f220m_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTA - __unused struct device *porta = + __unused const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTB - __unused struct device *portb = + __unused const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTC - __unused struct device *portc = + __unused const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTD - __unused struct device *portd = + __unused const struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTE - __unused struct device *porte = + __unused const struct device *porte = device_get_binding(CONFIG_PINMUX_MCUX_PORTE_NAME); #endif diff --git a/boards/arm/twr_kv58f220m/twr_kv58f220m.dts b/boards/arm/twr_kv58f220m/twr_kv58f220m.dts index 2752b85114c84e..986d4a560ef29e 100644 --- a/boards/arm/twr_kv58f220m/twr_kv58f220m.dts +++ b/boards/arm/twr_kv58f220m/twr_kv58f220m.dts @@ -73,6 +73,12 @@ }; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + + &gpioa { status = "okay"; }; @@ -94,10 +100,7 @@ }; &flash0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/arm/twr_kv58f220m/twr_kv58f220m_defconfig b/boards/arm/twr_kv58f220m/twr_kv58f220m_defconfig index 35232f3bf358e2..99619a0bec3a7c 100644 --- a/boards/arm/twr_kv58f220m/twr_kv58f220m_defconfig +++ b/boards/arm/twr_kv58f220m/twr_kv58f220m_defconfig @@ -14,3 +14,4 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=237500000 # Enable MPU CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/arm/udoo_neo_full_m4/pinmux.c b/boards/arm/udoo_neo_full_m4/pinmux.c index 155990f0a1736c..aab685df25175d 100644 --- a/boards/arm/udoo_neo_full_m4/pinmux.c +++ b/boards/arm/udoo_neo_full_m4/pinmux.c @@ -7,7 +7,7 @@ #include #include "device_imx.h" -static int udoo_neo_full_m4_init(struct device *dev) +static int udoo_neo_full_m4_init(const struct device *dev) { ARG_UNUSED(dev); diff --git a/boards/arm/usb_kw24d512/pinmux.c b/boards/arm/usb_kw24d512/pinmux.c index c9ef4821d0cd06..73bd5c1bb9ac3c 100644 --- a/boards/arm/usb_kw24d512/pinmux.c +++ b/boards/arm/usb_kw24d512/pinmux.c @@ -8,24 +8,24 @@ #include #include -static int usb_kw24d512_pinmux_init(struct device *dev) +static int usb_kw24d512_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #ifdef CONFIG_PINMUX_MCUX_PORTA - struct device *porta = + const struct device *porta = device_get_binding(CONFIG_PINMUX_MCUX_PORTA_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTB - struct device *portb = + const struct device *portb = device_get_binding(CONFIG_PINMUX_MCUX_PORTB_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTC - struct device *portc = + const struct device *portc = device_get_binding(CONFIG_PINMUX_MCUX_PORTC_NAME); #endif #ifdef CONFIG_PINMUX_MCUX_PORTD - struct device *portd = + const struct device *portd = device_get_binding(CONFIG_PINMUX_MCUX_PORTD_NAME); #endif diff --git a/boards/arm/usb_kw24d512/usb_kw24d512.dts b/boards/arm/usb_kw24d512/usb_kw24d512.dts index 66a56aaa6506b1..bdb4d1950001f3 100644 --- a/boards/arm/usb_kw24d512/usb_kw24d512.dts +++ b/boards/arm/usb_kw24d512/usb_kw24d512.dts @@ -43,6 +43,11 @@ }; }; +&sim { + pllfll-select = ; + er32k-select = ; +}; + &cpu0 { clock-frequency = <48000000>; }; diff --git a/boards/arm/v2m_beetle/pinmux.c b/boards/arm/v2m_beetle/pinmux.c index e926db0dfa55fa..3892499cc00c5f 100644 --- a/boards/arm/v2m_beetle/pinmux.c +++ b/boards/arm/v2m_beetle/pinmux.c @@ -94,8 +94,8 @@ */ static void arm_v2m_beetle_pinmux_defaults(void) { - u32_t gpio_0 = 0U; - u32_t gpio_1 = 0U; + uint32_t gpio_0 = 0U; + uint32_t gpio_1 = 0U; /* Set GPIO Alternate Functions */ @@ -135,7 +135,7 @@ static void arm_v2m_beetle_pinmux_defaults(void) CMSDK_AHB_GPIO1_DEV->data |= (0x1 << 15); } -static int arm_v2m_beetle_pinmux_init(struct device *port) +static int arm_v2m_beetle_pinmux_init(const struct device *port) { ARG_UNUSED(port); diff --git a/boards/arm/v2m_musca/Kconfig.defconfig b/boards/arm/v2m_musca/Kconfig.defconfig index 2d3c79b7838878..db88d5c19da294 100644 --- a/boards/arm/v2m_musca/Kconfig.defconfig +++ b/boards/arm/v2m_musca/Kconfig.defconfig @@ -7,6 +7,9 @@ config BOARD default "musca_a" if TRUSTED_EXECUTION_SECURE || !TRUSTED_EXECUTION_NONSECURE default "musca_a_nonsecure" +config BOARD_DEPRECATED_RELEASE + default "v2.6.0" + if GPIO config GPIO_CMSDK_AHB diff --git a/boards/arm/v2m_musca/pinmux.c b/boards/arm/v2m_musca/pinmux.c index cc8f46ce9533a3..3434fb9edeb978 100644 --- a/boards/arm/v2m_musca/pinmux.c +++ b/boards/arm/v2m_musca/pinmux.c @@ -37,7 +37,7 @@ static void arm_musca_pinmux_defaults(void) */ static void arm_musca_pinmux_defaults(void) { - volatile u32_t *scc = (u32_t *)DT_REG_ADDR(DT_INST(0, arm_scc)); + volatile uint32_t *scc = (uint32_t *)DT_REG_ADDR(DT_INST(0, arm_scc)); /* there is only altfunc1, so steer all alt funcs to use 1 */ scc[IOMUX_ALTF1_INSEL] = 0xffff; @@ -58,7 +58,7 @@ static void arm_musca_pinmux_defaults(void) } #endif -static int arm_musca_pinmux_init(struct device *port) +static int arm_musca_pinmux_init(const struct device *port) { ARG_UNUSED(port); diff --git a/boards/arm/v2m_musca_b1/CMakeLists.txt b/boards/arm/v2m_musca_b1/CMakeLists.txt index 488df5fda937a9..eefb0a85051c3c 100644 --- a/boards/arm/v2m_musca_b1/CMakeLists.txt +++ b/boards/arm/v2m_musca_b1/CMakeLists.txt @@ -18,8 +18,9 @@ if (CONFIG_BUILD_WITH_TFM) set(TFM_IMAGE_VERSION_NS 0.0.0+0) endif() - set(PREPROCESSED_FILE "${CMAKE_BINARY_DIR}/tfm/image_macros_preprocessed") - set(TFM_MCUBOOT_DIR "${ZEPHYR_BASE}/../modules/tee/tfm/trusted-firmware-m/bl2/ext/mcuboot") + set(PREPROCESSED_FILE_S "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.o") + set(PREPROCESSED_FILE_NS "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_ns.dir/signing_layout_ns.o") + set(TFM_MCUBOOT_DIR "${ZEPHYR_TFM_MODULE_DIR}/trusted-firmware-m/bl2/ext/mcuboot") # Configure which format (full or hash) to include the public key in # the image manifest @@ -31,35 +32,40 @@ if (CONFIG_BUILD_WITH_TFM) message(FATAL_ERROR "'srec_cat' not found. Please install it, or add it to $PATH.") endif() - #Create and sign for concatenated binary image should align with the TF-M BL2 + # Create and sign for concatenated binary image should align with the TF-M BL2 set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - #Create concatenated binary image from the two binary file + # Create concatenated binary image from the two binary files COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/assemble.py - ARGS --layout ${PREPROCESSED_FILE}.c + --layout ${PREPROCESSED_FILE_NS} -s ${CMAKE_BINARY_DIR}/tfm/install/outputs/MUSCA_B1/tfm_s.bin - -n ${CMAKE_BINARY_DIR}/zephyr/zephyr.bin + -n ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} -o ${CMAKE_BINARY_DIR}/tfm_full.bin #Sign concatenated binary image with default public key in mcuboot folder - COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/imgtool.py - ARGS sign - --layout ${PREPROCESSED_FILE}.c - -k ${CONFIG_TFM_KEY_FILE_S} + COMMAND ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py + --layout ${PREPROCESSED_FILE_NS} + -k ${CONFIG_TFM_KEY_FILE_NS} --public-key-format ${TFM_PUBLIC_KEY_FORMAT} --align 1 - -v ${TFM_IMAGE_VERSION_S} - ${ADD_SECURITY_COUNTER} + -v ${TFM_IMAGE_VERSION_NS} + --pad + --pad-header + ${ADD_NS_IMAGE_MIN_VER} + -s auto -H 0x400 ${CMAKE_BINARY_DIR}/tfm_full.bin ${CMAKE_BINARY_DIR}/tfm_sign.bin + #Copy mcuboot.bin + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/tfm/bin/bl2.bin ${CMAKE_BINARY_DIR}/mcuboot.bin + #srec_cat to combine images into hex for drag and drop COMMAND ${SREC_CAT} - ARGS ${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/mcuboot.bin -binary + ARGS ${CMAKE_BINARY_DIR}/mcuboot.bin -Binary -offset 0xA000000 - ${CMAKE_BINARY_DIR}/tfm_sign.bin -binary + ${CMAKE_BINARY_DIR}/tfm_sign.bin -Binary -offset 0xA020000 - -o ${CMAKE_BINARY_DIR}/tfm_zephyr.hex -Intel --line-length=44 + -o ${CMAKE_BINARY_DIR}/tfm_zephyr.hex -intel --line-length=44 ) endif() diff --git a/boards/arm/v2m_musca_b1/board.cmake b/boards/arm/v2m_musca_b1/board.cmake index ebaa25d0dc9350..3d207249d11a37 100644 --- a/boards/arm/v2m_musca_b1/board.cmake +++ b/boards/arm/v2m_musca_b1/board.cmake @@ -1,7 +1,5 @@ #SPDX-License-Identifier: Apache-2.0 -set(TFM_TARGET_PLATFORM "MUSCA_B1") - board_set_debugger_ifnset(pyocd) board_set_flasher_ifnset(pyocd) diff --git a/boards/arm/v2m_musca_b1/pinmux.c b/boards/arm/v2m_musca_b1/pinmux.c index 71e82ad9265222..f1e45e616b0699 100644 --- a/boards/arm/v2m_musca_b1/pinmux.c +++ b/boards/arm/v2m_musca_b1/pinmux.c @@ -37,7 +37,7 @@ static void arm_musca_b1_pinmux_defaults(void) */ static void arm_musca_b1_pinmux_defaults(void) { - volatile u32_t *scc = (u32_t *)DT_REG_ADDR(DT_INST(0, arm_scc)); + volatile uint32_t *scc = (uint32_t *)DT_REG_ADDR(DT_INST(0, arm_scc)); /* there is only altfunc1, so steer all alt funcs to use 1 */ scc[IOMUX_ALTF1_INSEL] = 0xffff; @@ -59,7 +59,7 @@ static void arm_musca_b1_pinmux_defaults(void) } #endif -static int arm_musca_pinmux_init(struct device *port) +static int arm_musca_pinmux_init(const struct device *port) { ARG_UNUSED(port); diff --git a/boards/arm/v2m_musca_b1/v2m_musca_b1_nonsecure.dts b/boards/arm/v2m_musca_b1/v2m_musca_b1_nonsecure.dts index 31c7664330b119..8964cb950dbf32 100644 --- a/boards/arm/v2m_musca_b1/v2m_musca_b1_nonsecure.dts +++ b/boards/arm/v2m_musca_b1/v2m_musca_b1_nonsecure.dts @@ -42,9 +42,9 @@ }; }; - flash0: flash@0a070400 { + flash0: flash@0a070000 { /* Embedded flash */ - reg = <0x0a070400 0x19fc00>; + reg = <0x0a070000 0x1a0000>; }; sram0: memory@20040000 { diff --git a/boards/arm/warp7_m4/Kconfig.defconfig b/boards/arm/warp7_m4/Kconfig.defconfig index 2a26f3a25c77cd..6086acb474b834 100644 --- a/boards/arm/warp7_m4/Kconfig.defconfig +++ b/boards/arm/warp7_m4/Kconfig.defconfig @@ -10,11 +10,11 @@ config BOARD config FXOS8700_DRDY_INT1 default y - depends on FXOS8700 + depends on FXOS8700_TRIGGER config FXAS21002_DRDY_INT1 default y - depends on FXAS21002 + depends on FXAS21002_TRIGGER if !XIP config FLASH_SIZE diff --git a/boards/arm/warp7_m4/pinmux.c b/boards/arm/warp7_m4/pinmux.c index 0955dab1fd60c2..6ecb5d9edfe54e 100644 --- a/boards/arm/warp7_m4/pinmux.c +++ b/boards/arm/warp7_m4/pinmux.c @@ -7,7 +7,7 @@ #include #include "device_imx.h" -static int warp7_m4_pinmux_init(struct device *dev) +static int warp7_m4_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #if defined(CONFIG_FXOS8700) || defined(CONFIG_FXAS21002) diff --git a/boards/arm/waveshare_open103z/Kconfig.board b/boards/arm/waveshare_open103z/Kconfig.board new file mode 100644 index 00000000000000..ea48f05c767ae3 --- /dev/null +++ b/boards/arm/waveshare_open103z/Kconfig.board @@ -0,0 +1,8 @@ +# Waveshare Open103Z board configuration + +# Copyright (c) 2020 Stefano Manni +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_WAVESHARE_OPEN103Z + bool "Waveshare OPEN103Z Development Board" + depends on SOC_STM32F103XE diff --git a/boards/arm/waveshare_open103z/Kconfig.defconfig b/boards/arm/waveshare_open103z/Kconfig.defconfig new file mode 100644 index 00000000000000..4a2b56b826ae24 --- /dev/null +++ b/boards/arm/waveshare_open103z/Kconfig.defconfig @@ -0,0 +1,11 @@ +# Waveshare Open103Z board configuration + +# Copyright (c) 2020 Stefano Manni +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_WAVESHARE_OPEN103Z + +config BOARD + default "waveshare_open103z" + +endif # BOARD_WAVESHARE_OPEN103Z diff --git a/boards/arm/waveshare_open103z/board.cmake b/boards/arm/waveshare_open103z/board.cmake new file mode 100644 index 00000000000000..fc1ba2c70e09d8 --- /dev/null +++ b/boards/arm/waveshare_open103z/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32F103ZE" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/waveshare_open103z/doc/img/waveshare_connector.PNG b/boards/arm/waveshare_open103z/doc/img/waveshare_connector.PNG new file mode 100644 index 00000000000000..5c3120a75c9da2 Binary files /dev/null and b/boards/arm/waveshare_open103z/doc/img/waveshare_connector.PNG differ diff --git a/boards/arm/waveshare_open103z/doc/img/waveshare_connector_list.PNG b/boards/arm/waveshare_open103z/doc/img/waveshare_connector_list.PNG new file mode 100644 index 00000000000000..5096c3f741c7bc Binary files /dev/null and b/boards/arm/waveshare_open103z/doc/img/waveshare_connector_list.PNG differ diff --git a/boards/arm/waveshare_open103z/doc/img/waveshare_open103z.png b/boards/arm/waveshare_open103z/doc/img/waveshare_open103z.png new file mode 100644 index 00000000000000..dd4fa01eb775f6 Binary files /dev/null and b/boards/arm/waveshare_open103z/doc/img/waveshare_open103z.png differ diff --git a/boards/arm/waveshare_open103z/doc/index.rst b/boards/arm/waveshare_open103z/doc/index.rst new file mode 100644 index 00000000000000..ce9d05240e76d3 --- /dev/null +++ b/boards/arm/waveshare_open103z/doc/index.rst @@ -0,0 +1,82 @@ +.. _waveshare_open103z_board: + +Waveshare Open103Z +################## + +Overview +******** + +The Waveshare Open103Z-64 is a development board equipped with STM32F103ZE MCU. + +.. image:: img/waveshare_open103z.png + +Hardware +******** + +The Waveshare Open103Z provides the following hardware components: + +.. image:: img/waveshare_connector.PNG +.. image:: img/waveshare_connector_list.PNG + +Supported Features +================== + +The Waveshare Open103Z configuration supports the following hardware features: + ++-----------+------------+--------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================================+ +| NVIC | on-chip | nested vectored interrupt controller | ++-----------+------------+--------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+--------------------------------------+ +| UART | on-chip | serial port | ++-----------+------------+--------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+--------------------------------------+ +| FLASH | on-chip | flash | ++-----------+------------+--------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+--------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+--------------------------------------+ +| CAN | on-chip | can | ++-----------+------------+--------------------------------------+ +| USB | on-chip | usb | ++-----------+------------+--------------------------------------+ + +Programming and Debugging +************************* + +Applications for the ``waveshare_open103z`` board configuration can be built and +flashed in the usual way. + +Flashing +======== + +Build and flash applications as usual. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: waveshare_open103z + :goals: build flash + +Debugging +========= + +Debug applications as usual. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: waveshare_open103z + :maybe-skip-config: + :goals: debug + +References +********** + +.. target-notes:: + +.. _Waveshare: https://www.waveshare.com/open103z-standard.htm diff --git a/boards/arm/waveshare_open103z/support/openocd.cfg b/boards/arm/waveshare_open103z/support/openocd.cfg new file mode 100644 index 00000000000000..14aa969fe9704b --- /dev/null +++ b/boards/arm/waveshare_open103z/support/openocd.cfg @@ -0,0 +1,17 @@ +source [find interface/stlink.cfg] + +# Work-area size (RAM size) = 64KB +set WORKAREASIZE 0x10000 + +source [find target/stm32f1x.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/arm/waveshare_open103z/waveshare_open103z.dts b/boards/arm/waveshare_open103z/waveshare_open103z.dts new file mode 100644 index 00000000000000..13fd5db317609b --- /dev/null +++ b/boards/arm/waveshare_open103z/waveshare_open103z.dts @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020 Stefano Manni + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "Waveshare Open103Z"; + compatible = "waveshare,open103z"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,can-primary = &can1; + }; + + leds { + compatible = "gpio-leds"; + led_1: led_1 { + gpios = <&gpiof 6 GPIO_ACTIVE_HIGH>; + label = "User LED1"; + }; + led_2: led_2 { + gpios = <&gpiof 7 GPIO_ACTIVE_HIGH>; + label = "User LED2"; + }; + led_3: led_3 { + gpios = <&gpiof 8 GPIO_ACTIVE_HIGH>; + label = "User LED3"; + }; + led_4: led_4 { + gpios = <&gpiof 9 GPIO_ACTIVE_HIGH>; + label = "User LED4"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + button: button { + label = "User button"; + gpios = <&gpiog 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + joystick_enter: joystick_enter { + label = "User joystick ENTER"; + gpios = <&gpiog 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + joystick_right: joystick_right { + label = "User joystick RIGHT"; + gpios = <&gpioc 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + joystick_up: joystick_up { + label = "User joystick UP"; + gpios = <&gpioc 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + joystick_down: joystick_down { + label = "User joystick DOWN"; + gpios = <&gpioc 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + joystick_left: joystick_left { + label = "User joystick LEFT"; + gpios = <&gpioc 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + }; + + aliases { + led0 = &led_1; + led1 = &led_2; + led2 = &led_3; + led3 = &led_4; + sw0 = &button; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + current-speed = <115200>; + status = "okay"; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + current-speed = <115200>; + status = "okay"; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_master_pa4 &spi1_sck_master_pa5 + &spi1_miso_master_pa6 &spi1_mosi_master_pa7>; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_nss_master_pb12 &spi2_sck_master_pb13 + &spi2_miso_master_pb14 &spi2_mosi_master_pb15>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_sda_pb7 &i2c1_scl_pb6>; + status = "okay"; + clock-frequency = ; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_sda_pb11 &i2c2_scl_pb10>; + status = "okay"; + clock-frequency = ; +}; + +&can1 { + pinctrl-0 = <&can_rx_pb8 &can_tx_pb9>; + /* + * make sure CAN and USB are not enabled at the same time + * because they share interrupts 19, 20 (stm32f103Xb.dtsi) + * reference: RM0008 rev20 page 205 + */ + status = "disabled"; + bus-speed = <125000>; + sjw = <1>; + prop-seg = <0>; + phase-seg1 = <5>; + phase-seg2 = <6>; +}; + +&usb { + /* + * make sure CAN and USB are not enabled at the same time + * because they share interrupts 19, 20 (stm32f103Xb.dtsi) + * reference: RM0008 rev20 page 205 + */ + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; + status = "okay"; + disconnect-gpios = <&gpiog 15 GPIO_ACTIVE_HIGH>; +}; + +&timers1 { + status = "okay"; + + pwm1: pwm { + status = "okay"; + pinctrl-0 = <&tim1_ch1_pwm_pa8>; + }; +}; + +&iwdg { + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc1_in0_pa0>; + status = "okay"; +}; diff --git a/boards/arm/waveshare_open103z/waveshare_open103z.yaml b/boards/arm/waveshare_open103z/waveshare_open103z.yaml new file mode 100644 index 00000000000000..d2bca4e4383ba1 --- /dev/null +++ b/boards/arm/waveshare_open103z/waveshare_open103z.yaml @@ -0,0 +1,19 @@ +identifier: waveshare_open103z +name: Waveshare Open103Z +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 64 +flash: 512 +supported: + - gpio + - spi + - i2c + - pwm + - watchdog + - adc + - usb_device + - can diff --git a/boards/arm/waveshare_open103z/waveshare_open103z_defconfig b/boards/arm/waveshare_open103z/waveshare_open103z_defconfig new file mode 100644 index 00000000000000..dd5e6f9ca95f3e --- /dev/null +++ b/boards/arm/waveshare_open103z/waveshare_open103z_defconfig @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_STM32F1X=y +CONFIG_SOC_STM32F103XE=y +# 72MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 + +# enable uart driver +CONFIG_SERIAL=y +# enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# enable pinmux +CONFIG_PINMUX=y + +# enable GPIO +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y +CONFIG_CLOCK_STM32_HSE_CLOCK=8000000 +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# use HSE as PLL input +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# produce 72MHz clock at PLL output +CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +# APB1 clock must not to exceed 36MHz limit +CONFIG_CLOCK_STM32_APB1_PRESCALER=2 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 diff --git a/boards/common/mdb-hw.board.cmake b/boards/common/mdb-hw.board.cmake new file mode 100644 index 00000000000000..52947e2ed6416e --- /dev/null +++ b/boards/common/mdb-hw.board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(mdb-hw) +board_set_debugger_ifnset(mdb-hw) +board_finalize_runner_args(mdb-hw) diff --git a/boards/common/mdb-nsim.board.cmake b/boards/common/mdb-nsim.board.cmake new file mode 100644 index 00000000000000..6188adcec6f653 --- /dev/null +++ b/boards/common/mdb-nsim.board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(mdb-nsim) +board_set_debugger_ifnset(mdb-nsim) +board_finalize_runner_args(mdb-nsim) diff --git a/boards/common/nulink.board.cmake b/boards/common/nulink.board.cmake new file mode 100644 index 00000000000000..f9967895e7e07d --- /dev/null +++ b/boards/common/nulink.board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(nulink) +board_set_debugger_ifnset(nulink) +board_finalize_runner_args(nulink "-f") diff --git a/boards/common/openocd-nrf5.board.cmake b/boards/common/openocd-nrf5.board.cmake index 59fea934a5b956..8f6f4137ccb13a 100644 --- a/boards/common/openocd-nrf5.board.cmake +++ b/boards/common/openocd-nrf5.board.cmake @@ -15,12 +15,16 @@ if("${OPENOCD_NRF5_SUBFAMILY}" STREQUAL "") "To fix, set CMake variable OPENOCD_NRF5_SUBFAMILY.") endif() +if (NOT DEFINED OPENOCD_NRF5_INTERFACE) + set(OPENOCD_NRF5_INTERFACE "jlink") +endif() + # We can do the right thing for supported subfamilies using a generic # script, at least for openocd 0.10.0 and the openocd shipped with # Zephyr SDK 0.10.3. set(pre_init_cmds "set WORKAREASIZE 0x4000" # 16 kB RAM used for flashing - "source [find interface/jlink.cfg]" + "source [find interface/${OPENOCD_NRF5_INTERFACE}.cfg]" "transport select swd" "source [find target/${OPENOCD_NRF5_SUBFAMILY}.cfg]" "$_TARGETNAME configure -rtos auto" diff --git a/boards/common/stm32cubeprogrammer.board.cmake b/boards/common/stm32cubeprogrammer.board.cmake new file mode 100644 index 00000000000000..38a9cae6e2fa33 --- /dev/null +++ b/boards/common/stm32cubeprogrammer.board.cmake @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(stm32cubeprogrammer) +board_finalize_runner_args(stm32cubeprogrammer) diff --git a/boards/deprecated.cmake b/boards/deprecated.cmake index e053c4c05dd133..893c710766ff91 100644 --- a/boards/deprecated.cmake +++ b/boards/deprecated.cmake @@ -7,20 +7,3 @@ # # To add a board rename, add a line in following format: # set(_DEPRECATED ) - -set(nrf51_pca10028_DEPRECATED nrf51dk_nrf51422) -set(nrf51_pca10031_DEPRECATED nrf51dongle_nrf51422) -set(nrf52_pca10040_DEPRECATED nrf52dk_nrf52832) -set(nrf52_pca20020_DEPRECATED thingy52_nrf52832) -set(nrf52810_pca10040_DEPRECATED nrf52dk_nrf52810) -set(nrf52833_pca10100_DEPRECATED nrf52833dk_nrf52833) -set(nrf52840_pca10056_DEPRECATED nrf52840dk_nrf52840) -set(nrf52840_pca10059_DEPRECATED nrf52840dongle_nrf52840) -set(nrf52811_pca10056_DEPRECATED nrf52840dk_nrf52811) -set(nrf5340_dk_nrf5340_cpuapp_DEPRECATED nrf5340pdk_nrf5340_cpuapp) -set(nrf5340_dk_nrf5340_cpuappns_DEPRECATED nrf5340pdk_nrf5340_cpuappns) -set(nrf5340_dk_nrf5340_cpunet_DEPRECATED nrf5340pdk_nrf5340_cpunet) -set(nrf9160_pca10090_DEPRECATED nrf9160dk_nrf9160) -set(nrf9160_pca10090ns_DEPRECATED nrf9160dk_nrf9160ns) -set(nrf52840_pca10090_DEPRECATED nrf9160dk_nrf52840) -set(efr32_slwstk6061a_DEPRECATED efr32_radio_brd4250b) diff --git a/boards/index.rst b/boards/index.rst index 9d854f42b6aa9d..c1a355f697d811 100644 --- a/boards/index.rst +++ b/boards/index.rst @@ -20,4 +20,5 @@ under :zephyr_file:`doc/templates/board.tmpl` xtensa/index.rst posix/index.rst riscv/index.rst + sparc/index.rst shields/index.rst diff --git a/boards/nios2/altera_max10/altera_max10.dts b/boards/nios2/altera_max10/altera_max10.dts index fa37c83961d051..9b3580fd040e71 100644 --- a/boards/nios2/altera_max10/altera_max10.dts +++ b/boards/nios2/altera_max10/altera_max10.dts @@ -6,7 +6,7 @@ / { model = "altera_max10"; - compatible = "altera,nios2-max10"; + compatible = "altr,nios2-max10"; aliases { uart-0 = &uart0; diff --git a/boards/nios2/qemu_nios2/qemu_nios2_defconfig b/boards/nios2/qemu_nios2/qemu_nios2_defconfig index 54d9f3c0d53952..44325b55ade8d4 100644 --- a/boards/nios2/qemu_nios2/qemu_nios2_defconfig +++ b/boards/nios2/qemu_nios2/qemu_nios2_defconfig @@ -11,3 +11,4 @@ CONFIG_UART_NS16550=y CONFIG_UART_CONSOLE=y CONFIG_INCLUDE_RESET_VECTOR=n CONFIG_EXTRA_EXCEPTION_INFO=y +CONFIG_QEMU_ICOUNT=n diff --git a/boards/posix/native_posix/CMakeLists.txt b/boards/posix/native_posix/CMakeLists.txt index 5fa77d6ca549d7..430518840f0fad 100644 --- a/boards/posix/native_posix/CMakeLists.txt +++ b/boards/posix/native_posix/CMakeLists.txt @@ -14,6 +14,7 @@ zephyr_library_sources( tracing.c cmdline_common.c cmdline.c + hw_counter.c ) zephyr_library_include_directories( diff --git a/boards/posix/native_posix/board_irq.h b/boards/posix/native_posix/board_irq.h index 2eaac01d8556c6..705694d29b8a6c 100644 --- a/boards/posix/native_posix/board_irq.h +++ b/boards/posix/native_posix/board_irq.h @@ -15,9 +15,10 @@ extern "C" { #endif -void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(void *), - void *isr_param_p); -void posix_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags); +void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(const void *), + const void *isr_param_p); +void posix_irq_priority_set(unsigned int irq, unsigned int prio, + uint32_t flags); /** * Configure a static interrupt. @@ -42,8 +43,8 @@ void posix_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags); */ #define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \ { \ - posix_isr_declare(irq_p, ISR_FLAG_DIRECT, (void (*)(void *))isr_p, \ - NULL); \ + posix_isr_declare(irq_p, ISR_FLAG_DIRECT, \ + (void (*)(const void *))isr_p, NULL); \ posix_irq_priority_set(irq_p, priority_p, flags_p); \ } @@ -72,7 +73,7 @@ void posix_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags); #define ARCH_ISR_DIRECT_HEADER() do { } while (0) #define ARCH_ISR_DIRECT_FOOTER(a) do { } while (0) -#ifdef CONFIG_SYS_POWER_MANAGEMENT +#ifdef CONFIG_PM extern void posix_irq_check_idle_exit(void); #define ARCH_ISR_DIRECT_PM() posix_irq_check_idle_exit() #else diff --git a/boards/posix/native_posix/board_soc.h b/boards/posix/native_posix/board_soc.h index e154b0d1d429bf..91b871e1d63f1b 100644 --- a/boards/posix/native_posix/board_soc.h +++ b/boards/posix/native_posix/board_soc.h @@ -25,6 +25,7 @@ extern "C" { #define TIMER_TICK_IRQ 0 #define OFFLOAD_SW_IRQ 1 +#define COUNTER_EVENT_IRQ 2 /* * This interrupt will awake the CPU if IRQs are not locked, diff --git a/boards/posix/native_posix/cmdline_common.c b/boards/posix/native_posix/cmdline_common.c index 2f2cf587901d2f..9528eaa93dbb02 100644 --- a/boards/posix/native_posix/cmdline_common.c +++ b/boards/posix/native_posix/cmdline_common.c @@ -146,16 +146,16 @@ void cmd_read_option_value(const char *str, void *dest, const char type, endptr = (char *)str + strlen(str); break; case 'u': - *(u32_t *)dest = strtoul(str, &endptr, 0); + *(uint32_t *)dest = strtoul(str, &endptr, 0); break; case 'U': - *(u64_t *)dest = strtoull(str, &endptr, 0); + *(uint64_t *)dest = strtoull(str, &endptr, 0); break; case 'i': - *(s32_t *)dest = strtol(str, &endptr, 0); + *(int32_t *)dest = strtol(str, &endptr, 0); break; case 'I': - *(s64_t *)dest = strtoll(str, &endptr, 0); + *(int64_t *)dest = strtoll(str, &endptr, 0); break; case 'd': *(double *)dest = strtod(str, &endptr); @@ -201,16 +201,16 @@ void cmd_args_set_defaults(struct args_struct_t args_struct[]) *(char **)args_struct[count].dest = NULL; break; case 'u': - *(u32_t *)args_struct[count].dest = UINT32_MAX; + *(uint32_t *)args_struct[count].dest = UINT32_MAX; break; case 'U': - *(u64_t *)args_struct[count].dest = UINT64_MAX; + *(uint64_t *)args_struct[count].dest = UINT64_MAX; break; case 'i': - *(s32_t *)args_struct[count].dest = INT32_MAX; + *(int32_t *)args_struct[count].dest = INT32_MAX; break; case 'I': - *(s64_t *)args_struct[count].dest = INT64_MAX; + *(int64_t *)args_struct[count].dest = INT64_MAX; break; case 'd': *(double *)args_struct[count].dest = NAN; diff --git a/boards/posix/native_posix/hw_counter.c b/boards/posix/native_posix/hw_counter.c new file mode 100644 index 00000000000000..77218a7ada41a8 --- /dev/null +++ b/boards/posix/native_posix/hw_counter.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "hw_models_top.h" +#include "board_soc.h" +#include "board_irq.h" +#include "irq_ctrl.h" + +uint64_t hw_counter_timer; + +static bool counter_running; +static uint64_t counter_value; +static uint64_t counter_target; +static uint64_t counter_period; + +/** + * Initialize the counter with prescaler of HW + */ +void hw_counter_init(void) +{ + hw_counter_timer = NEVER; + counter_target = NEVER; + counter_value = 0; + counter_running = false; + counter_period = NEVER; +} + +void hw_counter_triggered(void) +{ + if (!counter_running) { + hw_counter_timer = NEVER; + return; + } + + hw_counter_timer = hwm_get_time() + counter_period; + counter_value = counter_value + 1; + + if (counter_value == counter_target) { + hw_irq_ctrl_set_irq(COUNTER_EVENT_IRQ); + } +} + +/** + * Configures the counter period. + * The counter will be incremented every 'period' microseconds. + */ +void hw_counter_set_period(uint64_t period) +{ + counter_period = period; +} + +/** + * Starts the counter. It must be previously configured with + * hw_counter_set_period() and hw_counter_set_target(). + */ +void hw_counter_start(void) +{ + if (counter_running) { + return; + } + + counter_running = true; + + hw_counter_timer = hwm_get_time() + counter_period; + hwm_find_next_timer(); +} + +/** + * Stops the counter at current value. + * On the next call to hw_counter_start, the counter will + * start from the value at which it was stopped. + */ +void hw_counter_stop(void) +{ + counter_running = false; + hw_counter_timer = NEVER; + hwm_find_next_timer(); +} + +/** + * Returns the current counter value. + */ +uint64_t hw_counter_get_value(void) +{ + return counter_value; +} + +/** + * Configures the counter to generate an interrupt + * when its count value reaches target. + */ +void hw_counter_set_target(uint64_t target) +{ + counter_target = target; +} diff --git a/boards/posix/native_posix/hw_counter.h b/boards/posix/native_posix/hw_counter.h new file mode 100644 index 00000000000000..5cd6dd2e57784b --- /dev/null +++ b/boards/posix/native_posix/hw_counter.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _NATIVE_POSIX_HW_COUNTER_H +#define _NATIVE_POSIX_HW_COUNTER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void hw_counter_init(void); +void hw_counter_triggered(void); + +void hw_counter_set_period(uint64_t period); +void hw_counter_set_target(uint64_t counter_target); +void hw_counter_start(void); +void hw_counter_stop(void); +uint64_t hw_counter_get_value(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _NATIVE_POSIX_HW_COUNTER_H */ diff --git a/boards/posix/native_posix/hw_models_top.c b/boards/posix/native_posix/hw_models_top.c index cc8769590037b0..5f43dd6e880caf 100644 --- a/boards/posix/native_posix/hw_models_top.c +++ b/boards/posix/native_posix/hw_models_top.c @@ -18,25 +18,28 @@ #include "timer_model.h" #include "irq_ctrl.h" #include "posix_board_if.h" +#include "hw_counter.h" #include #include "posix_arch_internal.h" #include "sdl_events.h" #include -static u64_t simu_time; /* The actual time as known by the HW models */ -static u64_t end_of_time = NEVER; /* When will this device stop */ +static uint64_t simu_time; /* The actual time as known by the HW models */ +static uint64_t end_of_time = NEVER; /* When will this device stop */ /* List of HW model timers: */ -extern u64_t hw_timer_timer; /* When should this timer_model be called */ -extern u64_t irq_ctrl_timer; +extern uint64_t hw_timer_timer; /* When should this timer_model be called */ +extern uint64_t irq_ctrl_timer; +extern uint64_t hw_counter_timer; #ifdef CONFIG_HAS_SDL -extern u64_t sdl_event_timer; +extern uint64_t sdl_event_timer; #endif static enum { HWTIMER = 0, IRQCNT, + HW_COUNTER, #ifdef CONFIG_HAS_SDL SDLEVENTTIMER, #endif @@ -44,15 +47,16 @@ static enum { NONE } next_timer_index = NONE; -static u64_t *Timer_list[NUMBER_OF_TIMERS] = { +static uint64_t *Timer_list[NUMBER_OF_TIMERS] = { &hw_timer_timer, &irq_ctrl_timer, + &hw_counter_timer, #ifdef CONFIG_HAS_SDL &sdl_event_timer, #endif }; -static u64_t next_timer_time; +static uint64_t next_timer_time; /* Have we received a SIGTERM or SIGINT */ static volatile sig_atomic_t signaled_end; @@ -149,6 +153,9 @@ void hwm_main_loop(void) case IRQCNT: hw_irq_ctrl_timer_triggered(); break; + case HW_COUNTER: + hw_counter_triggered(); + break; #ifdef CONFIG_HAS_SDL case SDLEVENTTIMER: sdl_handle_events(); @@ -169,7 +176,7 @@ void hwm_main_loop(void) /** * Set the simulated time when the process will stop */ -void hwm_set_end_of_time(u64_t new_end_of_time) +void hwm_set_end_of_time(uint64_t new_end_of_time) { end_of_time = new_end_of_time; } @@ -177,12 +184,12 @@ void hwm_set_end_of_time(u64_t new_end_of_time) /** * Return the current time as known by the device */ -u64_t hwm_get_time(void) +uint64_t hwm_get_time(void) { return simu_time; } -u64_t posix_get_hw_cycle(void) +uint64_t posix_get_hw_cycle(void) { return hwm_get_time(); } @@ -194,6 +201,7 @@ void hwm_init(void) { hwm_set_sig_handler(); hwtimer_init(); + hw_counter_init(); hw_irq_ctrl_init(); hwm_find_next_timer(); diff --git a/boards/posix/native_posix/hw_models_top.h b/boards/posix/native_posix/hw_models_top.h index 2430811015aa04..87ad2f39435218 100644 --- a/boards/posix/native_posix/hw_models_top.h +++ b/boards/posix/native_posix/hw_models_top.h @@ -19,8 +19,8 @@ extern "C" { void hwm_main_loop(void); void hwm_init(void); void hwm_cleanup(void); -void hwm_set_end_of_time(u64_t new_end_of_time); -u64_t hwm_get_time(void); +void hwm_set_end_of_time(uint64_t new_end_of_time); +uint64_t hwm_get_time(void); void hwm_find_next_timer(void); #ifdef __cplusplus diff --git a/boards/posix/native_posix/irq_ctrl.c b/boards/posix/native_posix/irq_ctrl.c index 8cf8ec9b7a4044..76dcaffefece7c 100644 --- a/boards/posix/native_posix/irq_ctrl.c +++ b/boards/posix/native_posix/irq_ctrl.c @@ -16,11 +16,11 @@ #include "posix_soc.h" #include "zephyr/types.h" -u64_t irq_ctrl_timer = NEVER; +uint64_t irq_ctrl_timer = NEVER; -static u64_t irq_status; /* pending interrupts */ -static u64_t irq_premask; /* interrupts before the mask */ +static uint64_t irq_status; /* pending interrupts */ +static uint64_t irq_premask; /* interrupts before the mask */ /* * Mask of which interrupts will actually cause the cpu to vector into its @@ -30,7 +30,7 @@ static u64_t irq_premask; /* interrupts before the mask */ * If the irq_mask enables and interrupt pending in irq_premask, it will cause * the controller to raise the interrupt immediately */ -static u64_t irq_mask; +static uint64_t irq_mask; /* * Interrupts lock/disable. When set, interrupts are registered @@ -40,7 +40,7 @@ static u64_t irq_mask; static bool irqs_locked; static bool lock_ignore; /* For the hard fake IRQ, temporarily ignore lock */ -static u8_t irq_prio[N_IRQS]; /* Priority of each interrupt */ +static uint8_t irq_prio[N_IRQS]; /* Priority of each interrupt */ /* note that prio = 0 == highest, prio=255 == lowest */ static int currently_running_prio = 256; /* 255 is the lowest prio interrupt */ @@ -77,7 +77,7 @@ void hw_irq_ctrl_prio_set(unsigned int irq, unsigned int prio) irq_prio[irq] = prio; } -u8_t hw_irq_ctrl_get_prio(unsigned int irq) +uint8_t hw_irq_ctrl_get_prio(unsigned int irq) { return irq_prio[irq]; } @@ -94,14 +94,14 @@ int hw_irq_ctrl_get_highest_prio_irq(void) return -1; } - u64_t irq_status = hw_irq_ctrl_get_irq_status(); + uint64_t irq_status = hw_irq_ctrl_get_irq_status(); int winner = -1; int winner_prio = 256; while (irq_status != 0U) { int irq_nbr = find_lsb_set(irq_status) - 1; - irq_status &= ~((u64_t) 1 << irq_nbr); + irq_status &= ~((uint64_t) 1 << irq_nbr); if ((winner_prio > (int)irq_prio[irq_nbr]) && (currently_running_prio > (int)irq_prio[irq_nbr])) { winner = irq_nbr; @@ -112,14 +112,14 @@ int hw_irq_ctrl_get_highest_prio_irq(void) } -u32_t hw_irq_ctrl_get_current_lock(void) +uint32_t hw_irq_ctrl_get_current_lock(void) { return irqs_locked; } -u32_t hw_irq_ctrl_change_lock(u32_t new_lock) +uint32_t hw_irq_ctrl_change_lock(uint32_t new_lock) { - u32_t previous_lock = irqs_locked; + uint32_t previous_lock = irqs_locked; irqs_locked = new_lock; @@ -150,23 +150,23 @@ void hw_irq_ctrl_clear_all_irqs(void) void hw_irq_ctrl_disable_irq(unsigned int irq) { - irq_mask &= ~((u64_t)1< -typedef void (*normal_irq_f_ptr)(void *); +typedef void (*normal_irq_f_ptr)(const void *); typedef int (*direct_irq_f_ptr)(void); typedef struct _isr_list isr_table_entry_t; @@ -43,7 +43,7 @@ static inline void vector_to_irq(int irq_nbr, int *may_swap) *may_swap |= ((direct_irq_f_ptr) irq_vector_table[irq_nbr].func)(); } else { -#ifdef CONFIG_SYS_POWER_MANAGEMENT +#ifdef CONFIG_PM posix_irq_check_idle_exit(); #endif ((normal_irq_f_ptr)irq_vector_table[irq_nbr].func) @@ -229,8 +229,8 @@ int posix_get_current_irq(void) * @param isr_param_p ISR parameter * @param flags_p IRQ options */ -void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(void *), - void *isr_param_p) +void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(const void *), + const void *isr_param_p) { irq_vector_table[irq_p].irq = irq_p; irq_vector_table[irq_p].func = isr_p; @@ -278,13 +278,13 @@ void posix_sw_clear_pending_IRQ(unsigned int IRQn) /** * Storage for functions offloaded to IRQ */ -static void (*off_routine)(void *); -static void *off_parameter; +static void (*off_routine)(const void *); +static const void *off_parameter; /** * IRQ handler for the SW interrupt assigned to irq_offload() */ -static void offload_sw_irq_handler(void *a) +static void offload_sw_irq_handler(const void *a) { ARG_UNUSED(a); off_routine(off_parameter); @@ -295,7 +295,7 @@ static void offload_sw_irq_handler(void *a) * * Raise the SW IRQ assigned to handled this */ -void posix_irq_offload(void (*routine)(void *), void *parameter) +void posix_irq_offload(void (*routine)(const void *), const void *parameter) { off_routine = routine; off_parameter = parameter; diff --git a/boards/posix/native_posix/native_posix.dts b/boards/posix/native_posix/native_posix.dts index 17a8cc62333b88..a6ea0110f195b2 100644 --- a/boards/posix/native_posix/native_posix.dts +++ b/boards/posix/native_posix/native_posix.dts @@ -6,6 +6,8 @@ /dts-v1/; #include +#include +#include / { model = "Native POSIX Board"; @@ -18,10 +20,22 @@ zephyr,flash = &flash0; zephyr,entropy = &rng; zephyr,flash-controller = &flashcontroller0; + zephyr,ec-host-interface = &hcp; }; aliases { eeprom-0 = &eeprom0; + i2c-0 = &i2c0; + spi-0 = &spi0; + led0 = &led0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; }; flashcontroller0: flash-controller@0 { @@ -30,6 +44,7 @@ #address-cells = <1>; #size-cells = <1>; + erase-value = <0xff>; label = "flash_ctrl"; @@ -77,6 +92,26 @@ size = ; }; + i2c0: i2c@100 { + status = "okay"; + compatible = "zephyr,i2c-emul-controller"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x100 4>; + label = "I2C_0"; + }; + + spi0: spi@200 { + status = "okay"; + compatible = "zephyr,spi-emul-controller"; + clock-frequency = <50000000>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x200 4>; + label = "SPI_0"; + }; + uart0: uart { status = "okay"; compatible = "zephyr,native-posix-uart"; @@ -93,4 +128,30 @@ label = "ENTROPY_0"; }; + counter0: counter { + status = "okay"; + compatible = "zephyr,native-posix-counter"; + label = "COUNTER_0"; + }; + + hcp: ec-host-cmd-periph { + status = "okay"; + compatible = "zephyr,sim-ec-host-cmd-periph"; + label = "EC_HOST_CMD_SIM"; + }; + + gpio0: gpio@800 { + status = "okay"; + compatible = "zephyr,gpio-emul"; + reg = <0x800 0x4>; + label = "GPIO_0"; + rising-edge; + falling-edge; + dual-edge; + high-level; + low-level; + dual-level; + gpio-controller; + #gpio-cells = <2>; + }; }; diff --git a/boards/posix/native_posix/native_rtc.c b/boards/posix/native_posix/native_rtc.c index 7715e3b8359a7b..f8a3c152ca7573 100644 --- a/boards/posix/native_posix/native_rtc.c +++ b/boards/posix/native_posix/native_rtc.c @@ -17,15 +17,15 @@ * Return the (simulation) time in microseconds * where clock_type is one of RTC_CLOCK_* */ -u64_t native_rtc_gettime_us(int clock_type) +uint64_t native_rtc_gettime_us(int clock_type) { if (clock_type == RTC_CLOCK_BOOT) { return hwm_get_time(); } else if (clock_type == RTC_CLOCK_REALTIME) { /* RTC_CLOCK_REALTIME */ return hwtimer_get_simu_rtc_time(); } else if (clock_type == RTC_CLOCK_PSEUDOHOSTREALTIME) { - u32_t nsec; - u64_t sec; + uint32_t nsec; + uint64_t sec; hwtimer_get_pseudohost_rtc_time(&nsec, &sec); return sec * 1000000UL + nsec / 1000U; @@ -41,10 +41,10 @@ u64_t native_rtc_gettime_us(int clock_type) * get the simulation time split in nsec and seconds * where clock_type is one of RTC_CLOCK_* */ -void native_rtc_gettime(int clock_type, u32_t *nsec, u64_t *sec) +void native_rtc_gettime(int clock_type, uint32_t *nsec, uint64_t *sec) { if (clock_type == RTC_CLOCK_BOOT || clock_type == RTC_CLOCK_REALTIME) { - u64_t us = native_rtc_gettime_us(clock_type); + uint64_t us = native_rtc_gettime_us(clock_type); *nsec = (us % 1000000UL) * 1000U; *sec = us / 1000000UL; } else { /* RTC_CLOCK_PSEUDOHOSTREALTIME */ @@ -57,7 +57,7 @@ void native_rtc_gettime(int clock_type, u32_t *nsec, u64_t *sec) * Note that this only affects the RTC_CLOCK_REALTIME and * RTC_CLOCK_PSEUDOHOSTREALTIME clocks. */ -void native_rtc_offset(s64_t delta_us) +void native_rtc_offset(int64_t delta_us) { hwtimer_adjust_rtc_offset(delta_us); } diff --git a/boards/posix/native_posix/native_rtc.h b/boards/posix/native_posix/native_rtc.h index 7adbc45cfdf90e..aaff5ae9d9257b 100644 --- a/boards/posix/native_posix/native_rtc.h +++ b/boards/posix/native_posix/native_rtc.h @@ -41,7 +41,7 @@ extern "C" { * * @return Number of microseconds */ -u64_t native_rtc_gettime_us(int clock_type); +uint64_t native_rtc_gettime_us(int clock_type); /** * @brief Get the value of a clock split in in nsec and seconds @@ -50,7 +50,7 @@ u64_t native_rtc_gettime_us(int clock_type); * @param nsec Pointer to store the nanoseconds * @param nsec Pointer to store the seconds */ -void native_rtc_gettime(int clock_type, u32_t *nsec, u64_t *sec); +void native_rtc_gettime(int clock_type, uint32_t *nsec, uint64_t *sec); /** * @brief Offset the real time clock by a number of microseconds. @@ -60,7 +60,7 @@ void native_rtc_gettime(int clock_type, u32_t *nsec, u64_t *sec); * @param delta_us Number of microseconds to offset. The value is added to all * offsetable clocks. */ -void native_rtc_offset(s64_t delta_us); +void native_rtc_offset(int64_t delta_us); /** * @brief Adjust the speed of the clock source by a multiplicative factor diff --git a/boards/posix/native_posix/sdl_events.c b/boards/posix/native_posix/sdl_events.c index 8b2511e01d7682..0e0bda454113e8 100644 --- a/boards/posix/native_posix/sdl_events.c +++ b/boards/posix/native_posix/sdl_events.c @@ -11,7 +11,7 @@ #include "soc.h" #include "hw_models_top.h" -u64_t sdl_event_timer; +uint64_t sdl_event_timer; static void sdl_handle_window_event(const SDL_Event *event) { diff --git a/boards/posix/native_posix/timer_model.c b/boards/posix/native_posix/timer_model.c index aa97dde7ff8faf..d74d7cb9aa1b94 100644 --- a/boards/posix/native_posix/timer_model.c +++ b/boards/posix/native_posix/timer_model.c @@ -42,7 +42,7 @@ * Note: the caller has to allocate the destination buffer (at least 17 chars) */ #include -static char *us_time_to_str(char *dest, u64_t time) +static char *us_time_to_str(char *dest, uint64_t time) { if (time != NEVER) { unsigned int hour; @@ -64,13 +64,13 @@ static char *us_time_to_str(char *dest, u64_t time) } #endif -u64_t hw_timer_timer; +uint64_t hw_timer_timer; -u64_t hw_timer_tick_timer; -u64_t hw_timer_awake_timer; +uint64_t hw_timer_tick_timer; +uint64_t hw_timer_awake_timer; -static u64_t tick_p; /* Period of the ticker */ -static s64_t silent_ticks; +static uint64_t tick_p; /* Period of the ticker */ +static int64_t silent_ticks; static bool real_time_mode = #if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME) @@ -85,7 +85,7 @@ static bool reset_rtc; /*"Reset" the RTC on boot*/ * When this executable started running, this value shall not be changed after * boot */ -static u64_t boot_time; +static uint64_t boot_time; /* * Ratio of the simulated clock to the real host time @@ -103,21 +103,21 @@ static double clock_ratio = 1.0; * * This variable is only kept for debugging purposes */ -static s64_t last_drift_offset; +static int64_t last_drift_offset; #endif /* * Offsets of the RTC relative to the hardware models simu_time * "simu_time" == simulated time which starts at 0 on boot */ -static s64_t rtc_offset; +static int64_t rtc_offset; /* Last host/real time when the ratio was adjusted */ -static u64_t last_radj_rtime; +static uint64_t last_radj_rtime; /* Last simulated time when the ratio was adjusted */ -static u64_t last_radj_stime; +static uint64_t last_radj_stime; -extern u64_t posix_get_hw_cycle(void); +extern uint64_t posix_get_hw_cycle(void); void hwtimer_set_real_time_mode(bool new_rt) { @@ -138,12 +138,12 @@ static inline void host_clock_gettime(struct timespec *tv) #endif } -u64_t get_host_us_time(void) +uint64_t get_host_us_time(void) { struct timespec tv; host_clock_gettime(&tv); - return (u64_t)tv.tv_sec * 1e6 + tv.tv_nsec / 1000; + return (uint64_t)tv.tv_sec * 1e6 + tv.tv_nsec / 1000; } void hwtimer_init(void) @@ -159,10 +159,10 @@ void hwtimer_init(void) } if (!reset_rtc) { struct timespec tv; - u64_t realhosttime; + uint64_t realhosttime; clock_gettime(CLOCK_REALTIME, &tv); - realhosttime = (u64_t)tv.tv_sec * 1e6 + tv.tv_nsec / 1000; + realhosttime = (uint64_t)tv.tv_sec * 1e6 + tv.tv_nsec / 1000; rtc_offset += realhosttime; } @@ -176,7 +176,7 @@ void hwtimer_cleanup(void) /** * Enable the HW timer tick interrupts with a period in micoseconds */ -void hwtimer_enable(u64_t period) +void hwtimer_enable(uint64_t period) { tick_p = period; hw_timer_tick_timer = hwm_get_time() + tick_p; @@ -187,12 +187,12 @@ void hwtimer_enable(u64_t period) static void hwtimer_tick_timer_reached(void) { if (real_time_mode) { - u64_t expected_rt = (hw_timer_tick_timer - last_radj_stime) + uint64_t expected_rt = (hw_timer_tick_timer - last_radj_stime) / clock_ratio + last_radj_rtime; - u64_t real_time = get_host_us_time(); + uint64_t real_time = get_host_us_time(); - s64_t diff = expected_rt - real_time; + int64_t diff = expected_rt - real_time; #if DEBUG_NP_TIMER char es[30]; @@ -213,7 +213,7 @@ static void hwtimer_tick_timer_reached(void) requested_time.tv_nsec = (diff - requested_time.tv_sec*1e6)*1e3; - nanosleep(&requested_time, &remaining); + (void) nanosleep(&requested_time, &remaining); } } @@ -236,7 +236,7 @@ static void hwtimer_awake_timer_reached(void) void hwtimer_timer_reached(void) { - u64_t Now = hw_timer_timer; + uint64_t Now = hw_timer_timer; if (hw_timer_awake_timer == Now) { hwtimer_awake_timer_reached(); @@ -255,7 +255,7 @@ void hwtimer_timer_reached(void) * * This is meant for k_busy_wait() like functionality */ -void hwtimer_wake_in_time(u64_t time) +void hwtimer_wake_in_time(uint64_t time) { if (hw_timer_awake_timer > time) { hw_timer_awake_timer = time; @@ -267,12 +267,12 @@ void hwtimer_wake_in_time(u64_t time) * The kernel wants to skip the next sys_ticks tick interrupts * If sys_ticks == 0, the next interrupt will be raised. */ -void hwtimer_set_silent_ticks(s64_t sys_ticks) +void hwtimer_set_silent_ticks(int64_t sys_ticks) { silent_ticks = sys_ticks; } -s64_t hwtimer_get_pending_silent_ticks(void) +int64_t hwtimer_get_pending_silent_ticks(void) { return silent_ticks; } @@ -291,7 +291,7 @@ void hwtimer_reset_rtc(void) * Set a time offset (microseconds) of the RTC simulated time * Note: This should not be used after starting */ -void hwtimer_set_rtc_offset(s64_t offset) +void hwtimer_set_rtc_offset(int64_t offset) { rtc_offset = offset; } @@ -308,7 +308,7 @@ void hwtimer_set_rt_ratio(double ratio) /** * Increase or decrease the RTC simulated time by offset_delta */ -void hwtimer_adjust_rtc_offset(s64_t offset_delta) +void hwtimer_adjust_rtc_offset(int64_t offset_delta) { rtc_offset += offset_delta; } @@ -318,8 +318,8 @@ void hwtimer_adjust_rtc_offset(s64_t offset_delta) */ void hwtimer_adjust_rt_ratio(double ratio_correction) { - u64_t current_stime = hwm_get_time(); - s64_t s_diff = current_stime - last_radj_stime; + uint64_t current_stime = hwm_get_time(); + int64_t s_diff = current_stime - last_radj_stime; /* Accumulated real time drift time since last adjustment: */ last_radj_rtime += s_diff / clock_ratio; @@ -327,7 +327,7 @@ void hwtimer_adjust_rt_ratio(double ratio_correction) #if DEBUG_NP_TIMER char ct[30]; - s64_t r_drift = (long double)(clock_ratio-1.0)/(clock_ratio)*s_diff; + int64_t r_drift = (long double)(clock_ratio-1.0)/(clock_ratio)*s_diff; last_drift_offset += r_drift; us_time_to_str(ct, current_stime); @@ -351,7 +351,7 @@ void hwtimer_adjust_rt_ratio(double ratio_correction) /** * Return the current simulated RTC time in microseconds */ -s64_t hwtimer_get_simu_rtc_time(void) +int64_t hwtimer_get_simu_rtc_time(void) { return hwm_get_time() + rtc_offset; } @@ -367,7 +367,7 @@ s64_t hwtimer_get_simu_rtc_time(void) * This will be the case in general if native_posix is not able to run at or * faster than real time. */ -void hwtimer_get_pseudohost_rtc_time(u32_t *nsec, u64_t *sec) +void hwtimer_get_pseudohost_rtc_time(uint32_t *nsec, uint64_t *sec) { /* * Note: long double has a 64bits mantissa in x86. @@ -396,8 +396,8 @@ void hwtimer_get_pseudohost_rtc_time(u32_t *nsec, u64_t *sec) host_clock_gettime(&tv); - u64_t rt_us = (u64_t)tv.tv_sec * 1000000ULL + tv.tv_nsec / 1000; - u32_t rt_ns = tv.tv_nsec % 1000; + uint64_t rt_us = (uint64_t)tv.tv_sec * 1000000ULL + tv.tv_nsec / 1000; + uint32_t rt_ns = tv.tv_nsec % 1000; long double drt_us = (long double)rt_us - last_radj_rtime; long double drt_ns = drt_us * 1000.0 + (long double)rt_ns; diff --git a/boards/posix/native_posix/timer_model.h b/boards/posix/native_posix/timer_model.h index 2bcdfbe35f6c34..2c782d69daa296 100644 --- a/boards/posix/native_posix/timer_model.h +++ b/boards/posix/native_posix/timer_model.h @@ -18,19 +18,19 @@ void hwtimer_init(void); void hwtimer_cleanup(void); void hwtimer_set_real_time_mode(bool new_rt); void hwtimer_timer_reached(void); -void hwtimer_wake_in_time(u64_t time); -void hwtimer_set_silent_ticks(s64_t sys_ticks); -void hwtimer_enable(u64_t period); -s64_t hwtimer_get_pending_silent_ticks(void); +void hwtimer_wake_in_time(uint64_t time); +void hwtimer_set_silent_ticks(int64_t sys_ticks); +void hwtimer_enable(uint64_t period); +int64_t hwtimer_get_pending_silent_ticks(void); void hwtimer_reset_rtc(void); -void hwtimer_set_rtc_offset(s64_t offset); +void hwtimer_set_rtc_offset(int64_t offset); void hwtimer_set_rt_ratio(double ratio); -void hwtimer_adjust_rtc_offset(s64_t offset_delta); +void hwtimer_adjust_rtc_offset(int64_t offset_delta); void hwtimer_adjust_rt_ratio(double ratio_correction); -s64_t hwtimer_get_simu_rtc_time(void); -void hwtimer_get_pseudohost_rtc_time(u32_t *nsec, u64_t *sec); +int64_t hwtimer_get_simu_rtc_time(void); +void hwtimer_get_pseudohost_rtc_time(uint32_t *nsec, uint64_t *sec); #ifdef __cplusplus } diff --git a/boards/posix/nrf52_bsim/CMakeLists.txt b/boards/posix/nrf52_bsim/CMakeLists.txt index ade14e3951a1c6..7c47b162463111 100644 --- a/boards/posix/nrf52_bsim/CMakeLists.txt +++ b/boards/posix/nrf52_bsim/CMakeLists.txt @@ -29,6 +29,7 @@ zephyr_library_sources( main.c time_machine.c trace_hook.c + cmsis.c ) zephyr_library_include_directories( diff --git a/boards/posix/nrf52_bsim/Kconfig.board b/boards/posix/nrf52_bsim/Kconfig.board index c29cf83ec90940..10074c709fe4aa 100644 --- a/boards/posix/nrf52_bsim/Kconfig.board +++ b/boards/posix/nrf52_bsim/Kconfig.board @@ -14,6 +14,16 @@ config BOARD_NRF52_BSIM # of it), so that the corresponding driver becomes available (see # dependencies of the ENTROPY_NRF5_RNG option). select HAS_HW_NRF_RNG + # Indicate that CCM supports 8 bit length field, to support full + # length LL PDUs. + select HAS_HW_NRF_CCM_LFLEN_8BIT + # Indicate 2M support so that Phy procedure can be enabled. + select HAS_HW_NRF_RADIO_BLE_2M + # Do the same for the CLOCK and POWER peripherals, so that the nrfx + # drivers for them can be used. + select HAS_HW_NRF_CLOCK + select HAS_HW_NRF_POWER + select HAS_NRFX help Will produce a console Linux process which can be executed natively. It needs the BabbleSim simulator both in compile time and to execute diff --git a/boards/posix/nrf52_bsim/board_irq.h b/boards/posix/nrf52_bsim/board_irq.h index d590d5d243272d..80b3008de68765 100644 --- a/boards/posix/nrf52_bsim/board_irq.h +++ b/boards/posix/nrf52_bsim/board_irq.h @@ -15,9 +15,10 @@ extern "C" { #endif -void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(void *), - void *isr_param_p); -void posix_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags); +void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(const void *), + const void *isr_param_p); +void posix_irq_priority_set(unsigned int irq, unsigned int prio, + uint32_t flags); /** * Configure a static interrupt. @@ -42,8 +43,8 @@ void posix_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags); */ #define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \ { \ - posix_isr_declare(irq_p, ISR_FLAG_DIRECT, (void (*)(void *))isr_p, \ - NULL); \ + posix_isr_declare(irq_p, ISR_FLAG_DIRECT, \ + (void (*)(const void *))isr_p, NULL); \ posix_irq_priority_set(irq_p, priority_p, flags_p); \ } @@ -72,7 +73,7 @@ void posix_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags); #define ARCH_ISR_DIRECT_HEADER() do { } while (0) #define ARCH_ISR_DIRECT_FOOTER(a) do { } while (0) -#ifdef CONFIG_SYS_POWER_MANAGEMENT +#ifdef CONFIG_PM extern void posix_irq_check_idle_exit(void); #define ARCH_ISR_DIRECT_PM() posix_irq_check_idle_exit() #else diff --git a/boards/posix/nrf52_bsim/board_soc.h b/boards/posix/nrf52_bsim/board_soc.h index bba01937dd77f6..e5c904eb7cc0b8 100644 --- a/boards/posix/nrf52_bsim/board_soc.h +++ b/boards/posix/nrf52_bsim/board_soc.h @@ -28,8 +28,8 @@ #include #include "irq.h" #include "irq_sources.h" -#include "NRF_regs.h" -#include "nrf_soc_if.h" +#include +#include "cmsis.h" #define OFFLOAD_SW_IRQ SWI0_EGU0_IRQn diff --git a/boards/posix/nrf52_bsim/bstests_entry.c b/boards/posix/nrf52_bsim/bstests_entry.c index d192f53e37d444..1e1cf4216f4a01 100644 --- a/boards/posix/nrf52_bsim/bstests_entry.c +++ b/boards/posix/nrf52_bsim/bstests_entry.c @@ -191,7 +191,7 @@ bool bst_irq_sniffer(int irq_number) } } -static int bst_fake_device_driver_pre2_init(struct device *arg) +static int bst_fake_device_driver_pre2_init(const struct device *arg) { ARG_UNUSED(arg); if (current_test && current_test->test_fake_ddriver_prekernel_f) { @@ -200,7 +200,7 @@ static int bst_fake_device_driver_pre2_init(struct device *arg) return 0; } -static int bst_fake_device_driver_post_init(struct device *arg) +static int bst_fake_device_driver_post_init(const struct device *arg) { ARG_UNUSED(arg); if (current_test && current_test->test_fake_ddriver_postkernel_f) { diff --git a/boards/posix/nrf52_bsim/cmsis.c b/boards/posix/nrf52_bsim/cmsis.c new file mode 100644 index 00000000000000..5f7c162ba91144 --- /dev/null +++ b/boards/posix/nrf52_bsim/cmsis.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * Copyright (c) 2020 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "irq_ctrl.h" +#include "posix_core.h" +#include "posix_board_if.h" +#include "board_soc.h" + +/* + * Replacement for ARMs NVIC functions() + */ +void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + hw_irq_ctrl_raise_im_from_sw(IRQn); +} + +void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + hw_irq_ctrl_clear_irq(IRQn); +} + +void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + hw_irq_ctrl_disable_irq(IRQn); +} + +void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + hw_irq_ctrl_enable_irq(IRQn); +} + +void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + hw_irq_ctrl_prio_set(IRQn, priority); +} + +uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + return hw_irq_ctrl_get_prio(IRQn); +} + +void NVIC_SystemReset(void) +{ + posix_print_warning("%s called. Exiting\n", __func__); + posix_exit(1); +} + +/* + * Replacements for some other CMSIS functions + */ +void __enable_irq(void) +{ + hw_irq_ctrl_change_lock(false); +} + +void __disable_irq(void) +{ + hw_irq_ctrl_change_lock(true); +} + +uint32_t __get_PRIMASK(void) +{ + return hw_irq_ctrl_get_current_lock(); +} diff --git a/boards/posix/nrf52_bsim/cmsis.h b/boards/posix/nrf52_bsim/cmsis.h new file mode 100644 index 00000000000000..e999a5deaf43e4 --- /dev/null +++ b/boards/posix/nrf52_bsim/cmsis.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * This header defines replacements for inline + * ARM Cortex-M CMSIS intrinsics. + */ + +#ifndef BOARDS_POSIX_NRF52_BSIM_CMSIS_H +#define BOARDS_POSIX_NRF52_BSIM_CMSIS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Implement the following ARM intrinsics as no-op: + * - ARM Data Synchronization Barrier + * - ARM Data Memory Synchronization Barrier + * - ARM Instruction Synchronization Barrier + * - ARM No Operation + */ +#ifndef __DMB +#define __DMB() +#endif + +#ifndef __DSB +#define __DSB() +#endif + +#ifndef __ISB +#define __ISB() +#endif + +#ifndef __NOP +#define __NOP() +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* BOARDS_POSIX_NRF52_BSIM_CMSIS_H */ diff --git a/boards/posix/nrf52_bsim/irq_handler.c b/boards/posix/nrf52_bsim/irq_handler.c index 16ea4feebac77c..d8b83cdc8e2626 100644 --- a/boards/posix/nrf52_bsim/irq_handler.c +++ b/boards/posix/nrf52_bsim/irq_handler.c @@ -22,7 +22,7 @@ static bool CPU_will_be_awaken_from_WFE; -typedef void (*normal_irq_f_ptr)(void *); +typedef void (*normal_irq_f_ptr)(const void *); typedef int (*direct_irq_f_ptr)(void); static struct _isr_list irq_vector_table[NRF_HW_NBR_IRQs]; @@ -98,7 +98,7 @@ static inline void vector_to_irq(int irq_nbr, int *may_swap) *may_swap |= ((direct_irq_f_ptr) irq_vector_table[irq_nbr].func)(); } else { -#ifdef CONFIG_SYS_POWER_MANAGEMENT +#ifdef CONFIG_PM posix_irq_check_idle_exit(); #endif ((normal_irq_f_ptr)irq_vector_table[irq_nbr].func) @@ -122,7 +122,7 @@ static inline void vector_to_irq(int irq_nbr, int *may_swap) */ void posix_irq_handler(void) { - u64_t irq_lock; + uint64_t irq_lock; int irq_nbr; static int may_swap; @@ -288,8 +288,8 @@ int posix_get_current_irq(void) * @param isr_param_p ISR parameter * @param flags_p IRQ options */ -void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(void *), - void *isr_param_p) +void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(const void *), + const void *isr_param_p) { irq_vector_table[irq_p].irq = irq_p; irq_vector_table[irq_p].func = isr_p; @@ -337,13 +337,13 @@ void posix_sw_clear_pending_IRQ(unsigned int IRQn) /** * Storage for functions offloaded to IRQ */ -static void (*off_routine)(void *); -static void *off_parameter; +static void (*off_routine)(const void *); +static const void *off_parameter; /** * IRQ handler for the SW interrupt assigned to irq_offload() */ -static void offload_sw_irq_handler(void *a) +static void offload_sw_irq_handler(const void *a) { ARG_UNUSED(a); off_routine(off_parameter); @@ -354,7 +354,7 @@ static void offload_sw_irq_handler(void *a) * * Raise the SW IRQ assigned to handled this */ -void posix_irq_offload(void (*routine)(void *), void *parameter) +void posix_irq_offload(void (*routine)(const void *), const void *parameter) { off_routine = routine; off_parameter = parameter; @@ -365,29 +365,6 @@ void posix_irq_offload(void (*routine)(void *), void *parameter) } #endif -/** - * Replacement for ARMs NVIC_SetPendingIRQ() - * - * Sets the interrupt IRQn as pending - * Note: - * This will interrupt immediately if the interrupt - * is not masked and irqs are not locked, and this interrupt is higher - * priority than a possibly currently running interrupt - */ -void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - hw_irq_ctrl_raise_im_from_sw(IRQn); -} - -/** - * Replacement for ARMs NVIC_ClearPendingIRQ() - * Clear pending interrupt IRQn - */ -void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - hw_irq_ctrl_clear_irq(IRQn); -} - /* * Very simple model of the WFE and SEV ARM instructions * which seems good enough for the Nordic controller @@ -404,6 +381,11 @@ void __WFE(void) CPU_event_set_flag = false; } +void __WFI(void) +{ + __WFE(); +} + void __SEV(void) { CPU_event_set_flag = true; diff --git a/boards/posix/nrf52_bsim/k_busy_wait.c b/boards/posix/nrf52_bsim/k_busy_wait.c index 5dcb68824bacc0..cc85a50fafac4f 100644 --- a/boards/posix/nrf52_bsim/k_busy_wait.c +++ b/boards/posix/nrf52_bsim/k_busy_wait.c @@ -16,7 +16,7 @@ * Note that interrupts may be received in the meanwhile and that therefore this * thread may lose context */ -void arch_busy_wait(u32_t usec_to_wait) +void arch_busy_wait(uint32_t usec_to_wait) { bs_time_t time_end = tm_get_hw_time() + usec_to_wait; diff --git a/boards/posix/nrf52_bsim/main.c b/boards/posix/nrf52_bsim/main.c index fcf64d4f875ff0..7e1d2f740c138f 100644 --- a/boards/posix/nrf52_bsim/main.c +++ b/boards/posix/nrf52_bsim/main.c @@ -38,7 +38,7 @@ uint8_t inner_main_clean_up(int exit_code) bs_clean_back_channels(); - u8_t bst_result = bst_delete(); + uint8_t bst_result = bst_delete(); if (bst_result != 0U) { bs_trace_raw_time(2, "main: The TESTCASE FAILED with return " diff --git a/boards/posix/nrf52_bsim/trace_hook.c b/boards/posix/nrf52_bsim/trace_hook.c index 89436c1d404b1f..b2feb9590b8ddd 100644 --- a/boards/posix/nrf52_bsim/trace_hook.c +++ b/boards/posix/nrf52_bsim/trace_hook.c @@ -59,7 +59,7 @@ void posix_flush_stdout(void) * * @return 0 if successful, otherwise failed. */ -static int printk_init(struct device *arg) +static int printk_init(const struct device *arg) { ARG_UNUSED(arg); diff --git a/boards/riscv/hifive1/board.cmake b/boards/riscv/hifive1/board.cmake index 44c8763b67696e..9c7c650a9947ac 100644 --- a/boards/riscv/hifive1/board.cmake +++ b/boards/riscv/hifive1/board.cmake @@ -9,10 +9,6 @@ set(QEMU_FLAGS_${ARCH} -machine sifive_e ) -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=6,align=off,sleep=off -rtc clock=vm) -endif() - board_set_debugger_ifnset(qemu) board_set_flasher_ifnset(hifive1) board_finalize_runner_args(hifive1) diff --git a/boards/riscv/hifive1/hifive1_defconfig b/boards/riscv/hifive1/hifive1_defconfig index 7f205ec79f1572..7447127c863f81 100644 --- a/boards/riscv/hifive1/hifive1_defconfig +++ b/boards/riscv/hifive1/hifive1_defconfig @@ -18,3 +18,4 @@ CONFIG_GPIO_SIFIVE=y CONFIG_SPI=y CONFIG_SPI_SIFIVE=y CONFIG_BOOT_BANNER=y +CONFIG_QEMU_ICOUNT_SHIFT=6 diff --git a/boards/riscv/hifive1/pinmux.c b/boards/riscv/hifive1/pinmux.c index 6e36f159fc63f8..9be8df7e651b34 100644 --- a/boards/riscv/hifive1/pinmux.c +++ b/boards/riscv/hifive1/pinmux.c @@ -8,11 +8,11 @@ #include #include -static int hifive1_pinmux_init(struct device *dev) +static int hifive1_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); - struct device *p = device_get_binding(CONFIG_PINMUX_SIFIVE_0_NAME); + const struct device *p = device_get_binding(CONFIG_PINMUX_SIFIVE_0_NAME); /* UART0 RX */ pinmux_pin_set(p, 16, SIFIVE_PINMUX_IOF0); diff --git a/boards/riscv/hifive1_revb/hifive1_revb_defconfig b/boards/riscv/hifive1_revb/hifive1_revb_defconfig index a5464213de5c5f..b20f61f0e09c9f 100644 --- a/boards/riscv/hifive1_revb/hifive1_revb_defconfig +++ b/boards/riscv/hifive1_revb/hifive1_revb_defconfig @@ -14,3 +14,4 @@ CONFIG_UART_SIFIVE=y CONFIG_UART_SIFIVE_PORT_0=y CONFIG_UART_CONSOLE=y CONFIG_BOOT_BANNER=y +CONFIG_CORE_E31=y diff --git a/boards/riscv/hifive1_revb/pinmux.c b/boards/riscv/hifive1_revb/pinmux.c index 605645da960bc0..6ff750e5ca0eeb 100644 --- a/boards/riscv/hifive1_revb/pinmux.c +++ b/boards/riscv/hifive1_revb/pinmux.c @@ -8,11 +8,11 @@ #include #include -static int hifive1_revb_pinmux_init(struct device *dev) +static int hifive1_revb_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); - struct device *p = device_get_binding(CONFIG_PINMUX_SIFIVE_0_NAME); + const struct device *p = device_get_binding(CONFIG_PINMUX_SIFIVE_0_NAME); #ifdef CONFIG_UART_SIFIVE #ifdef CONFIG_UART_SIFIVE_PORT_0 diff --git a/boards/riscv/litex_vexriscv/litex_vexriscv.dts b/boards/riscv/litex_vexriscv/litex_vexriscv.dts index 9b5b409bfbe4c2..4d4f2725e82e2a 100644 --- a/boards/riscv/litex_vexriscv/litex_vexriscv.dts +++ b/boards/riscv/litex_vexriscv/litex_vexriscv.dts @@ -19,7 +19,6 @@ ram0: memory@40000000 { device_type = "memory"; - compatible = "mmio-sram"; reg = <0x40000000 0x10000000>; }; }; @@ -65,3 +64,23 @@ &gpio_in { status = "okay"; }; + +&i2s_rx { + status = "okay"; +}; + +&i2s_tx { + status = "okay"; +}; + +&clk0 { + status = "okay"; +}; + +&clk1 { + status = "okay"; +}; + +&clock0 { + status = "okay"; +}; diff --git a/boards/riscv/litex_vexriscv/litex_vexriscv_defconfig b/boards/riscv/litex_vexriscv/litex_vexriscv_defconfig index 4a42305657f3dd..95213a57bdad19 100644 --- a/boards/riscv/litex_vexriscv/litex_vexriscv_defconfig +++ b/boards/riscv/litex_vexriscv/litex_vexriscv_defconfig @@ -27,3 +27,9 @@ CONFIG_I2C=y CONFIG_I2C_LITEX=y CONFIG_PWM=y CONFIG_PWM_LITEX=y +CONFIG_XIP=n +CONFIG_I2S=y +CONFIG_I2S_LITEX=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CLOCK_CONTROL_LITEX=y +CONFIG_HEAP_MEM_POOL_SIZE=4096 diff --git a/boards/riscv/qemu_riscv32/board.cmake b/boards/riscv/qemu_riscv32/board.cmake index 3e7a98c494a6f2..f0e123ec8bad6e 100644 --- a/boards/riscv/qemu_riscv32/board.cmake +++ b/boards/riscv/qemu_riscv32/board.cmake @@ -9,8 +9,4 @@ set(QEMU_FLAGS_${ARCH} -nographic -machine sifive_e ) - -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=6,align=off,sleep=off -rtc clock=vm) -endif() board_set_debugger_ifnset(qemu) diff --git a/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig b/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig index f26eeb53f999ce..1a4d99dfb6ec22 100644 --- a/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig +++ b/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig @@ -16,3 +16,4 @@ CONFIG_RISCV_MACHINE_TIMER=y CONFIG_GPIO=y CONFIG_GPIO_SIFIVE=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=10000000 +CONFIG_QEMU_ICOUNT_SHIFT=6 diff --git a/boards/riscv/qemu_riscv64/board.cmake b/boards/riscv/qemu_riscv64/board.cmake index 70284150255a35..74ebe8e3e0d23e 100644 --- a/boards/riscv/qemu_riscv64/board.cmake +++ b/boards/riscv/qemu_riscv64/board.cmake @@ -9,8 +9,4 @@ set(QEMU_FLAGS_${ARCH} -nographic -machine sifive_e ) - -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=6,align=off,sleep=off -rtc clock=vm) -endif() board_set_debugger_ifnset(qemu) diff --git a/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig b/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig index 804f8f5c84c709..83efa64b430cc5 100644 --- a/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig +++ b/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig @@ -18,3 +18,4 @@ CONFIG_GPIO_SIFIVE=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=10000000 CONFIG_STACK_SENTINEL=y CONFIG_TEST_EXTRA_STACKSIZE=256 +CONFIG_QEMU_ICOUNT_SHIFT=6 diff --git a/boards/riscv/rv32m1_vega/pinmux.c b/boards/riscv/rv32m1_vega/pinmux.c index 365120f4f3f28c..2a13a14d097cc0 100644 --- a/boards/riscv/rv32m1_vega/pinmux.c +++ b/boards/riscv/rv32m1_vega/pinmux.c @@ -10,33 +10,33 @@ #include #ifdef CONFIG_BT_CTLR_DEBUG_PINS -struct device *vega_debug_portb; -struct device *vega_debug_portc; -struct device *vega_debug_portd; +const struct device *vega_debug_portb; +const struct device *vega_debug_portc; +const struct device *vega_debug_portd; #endif -static int rv32m1_vega_pinmux_init(struct device *dev) +static int rv32m1_vega_pinmux_init(const struct device *dev) { ARG_UNUSED(dev); #if DT_NODE_HAS_STATUS(DT_NODELABEL(porta), okay) - __unused struct device *porta = + __unused const struct device *porta = device_get_binding(DT_LABEL(DT_NODELABEL(porta))); #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(portb), okay) - __unused struct device *portb = + __unused const struct device *portb = device_get_binding(DT_LABEL(DT_NODELABEL(portb))); #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(portc), okay) - __unused struct device *portc = + __unused const struct device *portc = device_get_binding(DT_LABEL(DT_NODELABEL(portc))); #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(portd), okay) - __unused struct device *portd = + __unused const struct device *portd = device_get_binding(DT_LABEL(DT_NODELABEL(portd))); #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(porte), okay) - __unused struct device *porte = + __unused const struct device *porte = device_get_binding(DT_LABEL(DT_NODELABEL(porte))); #endif @@ -112,7 +112,7 @@ static int rv32m1_vega_pinmux_init(struct device *dev) pinmux_pin_set(portd, 4, PORT_PCR_MUX(kPORT_MuxAsGpio)); pinmux_pin_set(portd, 5, PORT_PCR_MUX(kPORT_MuxAsGpio)); - struct device *gpio_dev = + const struct device *gpio_dev = device_get_binding(DT_LABEL(DT_NODELABEL(gpiob))); gpio_pin_configure(gpio_dev, 29, GPIO_OUTPUT); diff --git a/boards/riscv/rv32m1_vega/rv32m1_vega.dtsi b/boards/riscv/rv32m1_vega/rv32m1_vega.dtsi index 4539eea2a96b7a..5811ebff0839d5 100644 --- a/boards/riscv/rv32m1_vega/rv32m1_vega.dtsi +++ b/boards/riscv/rv32m1_vega/rv32m1_vega.dtsi @@ -137,7 +137,7 @@ arduino_spi: &lpspi0 { &lpspi1 { status = "okay"; - cs-gpios = <&gpiob 22 0>; + cs-gpios = <&gpiob 22 GPIO_ACTIVE_LOW>; mx25r32: mx25r3235f@0 { compatible = "jedec,spi-nor"; reg = <0>; diff --git a/boards/shields/adafruit_2_8_tft_touch_v2/Kconfig.defconfig b/boards/shields/adafruit_2_8_tft_touch_v2/Kconfig.defconfig index b3b02c1fb7d42e..c87eb720de996c 100644 --- a/boards/shields/adafruit_2_8_tft_touch_v2/Kconfig.defconfig +++ b/boards/shields/adafruit_2_8_tft_touch_v2/Kconfig.defconfig @@ -11,15 +11,32 @@ config SPI config ILI9340 default y +if KSCAN + +config I2C + default y + +config KSCAN_FT5336 + default y + +# NOTE: Enable if IRQ line is available (requires to solder jumper) +config KSCAN_FT5336_INTERRUPT + default n + +config KSCAN_INIT_PRIORITY + default 60 + +endif # KSCAN + if LVGL config LVGL_DISPLAY_DEV_NAME default "ILI9340" -config LVGL_HOR_RES +config LVGL_HOR_RES_MAX default 320 -config LVGL_VER_RES +config LVGL_VER_RES_MAX default 240 config LVGL_VDB_SIZE @@ -28,8 +45,37 @@ config LVGL_VDB_SIZE config LVGL_BITS_PER_PIXEL default 24 +choice LVGL_COLOR_DEPTH + default LVGL_COLOR_DEPTH_32 +endchoice + +config KSCAN + default y + +config LVGL_POINTER_KSCAN + default y + +config LVGL_POINTER_KSCAN_DEV_NAME + default "FT5336" + +config LVGL_POINTER_KSCAN_SWAP_XY + default y + +config LVGL_POINTER_KSCAN_INVERT_X + default y + +config LVGL_POINTER_KSCAN_INVERT_Y + default y + endif # LVGL endif # DISPLAY +if DISK_ACCESS_SDHC + +config DISK_ACCESS_SPI_SDHC + default y + +endif # DISK_ACCESS_SDHC + endif # SHIELD_ADAFRUIT_2_8_TFT_TOUCH_V2 diff --git a/boards/shields/adafruit_2_8_tft_touch_v2/adafruit_2_8_tft_touch_v2.overlay b/boards/shields/adafruit_2_8_tft_touch_v2/adafruit_2_8_tft_touch_v2.overlay index f4b6d52b9279fb..e71a85d7061705 100644 --- a/boards/shields/adafruit_2_8_tft_touch_v2/adafruit_2_8_tft_touch_v2.overlay +++ b/boards/shields/adafruit_2_8_tft_touch_v2/adafruit_2_8_tft_touch_v2.overlay @@ -4,9 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + &arduino_spi { status = "okay"; - cs-gpios = <&arduino_header 16 0>; /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>, /* D10 */ + <&arduino_header 12 GPIO_ACTIVE_LOW>; /* D04 */ ili9340@0 { @@ -15,5 +18,31 @@ spi-max-frequency = <15151515>; reg = <0>; cmd-data-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */ + pixel-format = ; + rotation = <90>; + frmctr1 = [00 18]; + pwctrl1 = [23 00]; + vmctrl1 = [3e 28]; + vmctrl2 = [86]; + pgamctrl = [0f 31 2b 0c 0e 08 4e f1 37 07 10 03 0e 09 00]; + ngamctrl = [00 0e 14 03 11 07 31 c1 48 08 0f 0c 31 36 0f]; + }; + + sdhc0: sdhc@1 { + compatible = "zephyr,mmc-spi-slot"; + reg = <1>; + status = "okay"; + label = "SDHC0"; + spi-max-frequency = <24000000>; + }; +}; + +&arduino_i2c { + touch_controller: ft5336@38 { + compatible = "focaltech,ft5336"; + reg = <0x38>; + label = "FT5336"; + /* Uncomment if IRQ line is available (requires to solder jumper) */ + /* int-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; */ /* D7 */ }; }; diff --git a/boards/shields/adafruit_2_8_tft_touch_v2/doc/index.rst b/boards/shields/adafruit_2_8_tft_touch_v2/doc/index.rst index 6d27dec8d5ba78..ea9b4b61a7e850 100644 --- a/boards/shields/adafruit_2_8_tft_touch_v2/doc/index.rst +++ b/boards/shields/adafruit_2_8_tft_touch_v2/doc/index.rst @@ -11,7 +11,7 @@ resolution of 320x240 pixels, is based on the ILI9341 controller. This shield comes with a resistive (STMPE610 controller) or capacitive (FT6206 controller) touchscreen. While the Zephyr RTOS supports display output to these screens, -it currently does not support touchscreen input. +touchscreen input is supported only on Capacitive Touch version. More information about the shield can be found at the `Adafruit 2.8" TFT Touch Shield v2 website`_. @@ -23,6 +23,8 @@ Pins Assignment of the Adafruit 2.8" TFT Touch Shield v2 +=======================+=============================================+ | D4 | MicroSD SPI CSn | +-----------------------+---------------------------------------------+ +| D7 | Touch Controller IRQ (see note below) | ++-----------------------+---------------------------------------------+ | D8 | STMPE610 SPI CSn (Resistive Touch Version) | +-----------------------+---------------------------------------------+ | D9 | ILI9341 DC (Data/Command) | @@ -40,6 +42,11 @@ Pins Assignment of the Adafruit 2.8" TFT Touch Shield v2 | SCL | FT6206 SCL (Capacitive Touch Version) | +-----------------------+---------------------------------------------+ +.. note:: + Touch controller IRQ line is not connected by default. You will need to + solder the ``ICSP_SI1`` jumper to use it. You will also need to adjust + driver configuration and its Device Tree entry to make use of it. + Requirements ************ diff --git a/boards/shields/adafruit_winc1500/Kconfig.defconfig b/boards/shields/adafruit_winc1500/Kconfig.defconfig new file mode 100644 index 00000000000000..777d77faf4d258 --- /dev/null +++ b/boards/shields/adafruit_winc1500/Kconfig.defconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2020 Kim Bøndergaard , Prevas A/S +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_ADAFRUIT_WINC1500 + +if NETWORKING + +config SPI + default y + +config WIFI_WINC1500 + default y + +config WIFI + default y + +endif #NETWORKING + +endif # SHIELD_ADAFRUIT_WINC1500 diff --git a/boards/shields/adafruit_winc1500/Kconfig.shield b/boards/shields/adafruit_winc1500/Kconfig.shield new file mode 100644 index 00000000000000..a54571b7bbf301 --- /dev/null +++ b/boards/shields/adafruit_winc1500/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2020 Kim Bøndergaard , Prevas A/S +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_ADAFRUIT_WINC1500 + def_bool $(shields_list_contains,adafruit_winc1500) diff --git a/boards/shields/adafruit_winc1500/adafruit_winc1500.overlay b/boards/shields/adafruit_winc1500/adafruit_winc1500.overlay new file mode 100644 index 00000000000000..0e00f6e25ac00e --- /dev/null +++ b/boards/shields/adafruit_winc1500/adafruit_winc1500.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 Kim Bøndergaard, , Prevas A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 16 0>; /* D10 */ + + winc1500@0 { + status = "ok"; + compatible = "atmel,winc1500"; + reg = <0x0>; + label = "winc1500"; + spi-max-frequency = <4000000>; + irq-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */ + reset-gpios = <&arduino_header 11 GPIO_ACTIVE_LOW>; /* D5 */ + enable-gpios = <&arduino_header 12 0>; /* D6 */ + }; +}; diff --git a/boards/shields/adafruit_winc1500/doc/index.rst b/boards/shields/adafruit_winc1500/doc/index.rst new file mode 100644 index 00000000000000..f780ba0a920ef1 --- /dev/null +++ b/boards/shields/adafruit_winc1500/doc/index.rst @@ -0,0 +1,70 @@ +.. _adafruit_winc1500: + +Adafruit WINC1500 Wifi Shield +############################# + +Overview +******** + +The Adafruit WINC1500 Wifi shield is an Arduino +compatible shield based on the ATWINC1500 wifi controller +from Microchip. +The shield also provides a micro SD card socket + +The SD card socket is currently not supported + +More information about the shield can be found +at the `Adafruit WINC1500 website`_. + +Pins Assignment of the Adafruit WINC1500 WiFi Shield +==================================================== + ++-----------------------+---------------------------------------------+ +| Shield Connector Pin | Function | ++=======================+=============================================+ +| D4 | MicroSD SPI CSn (Not supported) | ++-----------------------+---------------------------------------------+ +| D5 | WINC1500 RST (/Reset of winc1500) | ++-----------------------+---------------------------------------------+ +| D6 (b) | WINC1500 EN (Enable of winc1500) | ++-----------------------+---------------------------------------------+ +| D7 | WINC1500 IRQ (IRQ from winc1500) | ++-----------------------+---------------------------------------------+ +| D10 | WINC1500 SPI CSn | ++-----------------------+---------------------------------------------+ +| D11 (a) | SPI MOSI (Serial Data Input) | ++-----------------------+---------------------------------------------+ +| D12 (a) | SPI MISO (Serial Data Out) | ++-----------------------+---------------------------------------------+ +| D13 (a) | SPI SCK (Serial Clock Input) | ++-----------------------+---------------------------------------------+ + +The pins marked (a) must be jumpered to the SPI port at the shield +To enable low power support, wire the pin marked (b) to the En connector +at the shield + +Requirements +************ + +This shield can only be used with a board which provides a configuration +for Arduino connectors and defines node aliases for SPI and GPIO interfaces +(see :ref:`shields` for more details). + +Programming +*********** + +Set ``-DSHIELD=adafruit_winc1500`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/wifi + :board: frdm_k64f + :shield: adafruit_winc1500 + :goals: build + +References +********** + +.. target-notes:: + +.. _Adafruit WINC1500 website: + https://learn.adafruit.com/adafruit-winc1500-wifi-shield-for-arduino diff --git a/boards/shields/atmel_rf2xx/Kconfig.defconfig b/boards/shields/atmel_rf2xx/Kconfig.defconfig new file mode 100644 index 00000000000000..9ea5ee1a47c696 --- /dev/null +++ b/boards/shields/atmel_rf2xx/Kconfig.defconfig @@ -0,0 +1,30 @@ +# Copyright (c) 2020 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_ATMEL_RF2XX || \ + SHIELD_ATMEL_RF2XX_ARDUINO || \ + SHIELD_ATMEL_RF2XX_MIKROBUS || \ + SHIELD_ATMEL_RF2XX_XPRO || \ + SHIELD_ATMEL_RF2XX_LEGACY || \ + SHIELD_ATMEL_RF2XX_XPLAINED + +if NETWORKING + +config IEEE802154_RF2XX + default y + depends on IEEE802154 + +config NET_CONFIG_IEEE802154_DEV_NAME + default "RF2XX_0" + depends on IEEE802154_RF2XX + +orsource "boards/*.defconfig" + +endif # NETWORKING + +endif # SHIELD_ATMEL_RF2XX || \ + # SHIELD_ATMEL_RF2XX_ARDUINO || \ + # SHIELD_ATMEL_RF2XX_MIKROBUS || \ + # SHIELD_ATMEL_RF2XX_XPRO || \ + # SHIELD_ATMEL_RF2XX_LEGACY || \ + # SHIELD_ATMEL_RF2XX_XPLAINED diff --git a/boards/shields/atmel_rf2xx/Kconfig.shield b/boards/shields/atmel_rf2xx/Kconfig.shield new file mode 100644 index 00000000000000..6a4967ef8f2c0d --- /dev/null +++ b/boards/shields/atmel_rf2xx/Kconfig.shield @@ -0,0 +1,20 @@ +# Copyright (c) 2020 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_ATMEL_RF2XX + def_bool $(shields_list_contains,atmel_rf2xx) + +config SHIELD_ATMEL_RF2XX_ARDUINO + def_bool $(shields_list_contains,atmel_rf2xx_arduino) + +config SHIELD_ATMEL_RF2XX_MIKROBUS + def_bool $(shields_list_contains,atmel_rf2xx_mikrobus) + +config SHIELD_ATMEL_RF2XX_XPRO + def_bool $(shields_list_contains,atmel_rf2xx_xpro) + +config SHIELD_ATMEL_RF2XX_LEGACY + def_bool $(shields_list_contains,atmel_rf2xx_legacy) + +config SHIELD_ATMEL_RF2XX_XPLAINED + def_bool $(shields_list_contains,atmel_rf2xx_xplained) diff --git a/boards/shields/atmel_rf2xx/atmel_rf2xx.overlay b/boards/shields/atmel_rf2xx/atmel_rf2xx.overlay new file mode 100644 index 00000000000000..e88e21eb1b10d1 --- /dev/null +++ b/boards/shields/atmel_rf2xx/atmel_rf2xx.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2020 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This file is intentionally empty. Please confer with shield documentation + * for instructions to use this shield. + */ diff --git a/boards/shields/atmel_rf2xx/atmel_rf2xx_arduino.overlay b/boards/shields/atmel_rf2xx/atmel_rf2xx_arduino.overlay new file mode 100644 index 00000000000000..7ab58ff86b75f7 --- /dev/null +++ b/boards/shields/atmel_rf2xx/atmel_rf2xx_arduino.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&arduino_spi { + status = "okay"; + + /* D10 */ + cs-gpios = <&arduino_header 16 + (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + + rf2xx@0 { + compatible = "atmel,rf2xx"; + reg = <0x0>; + label = "RF2XX_0"; + spi-max-frequency = <6000000>; + /* D2 */ + irq-gpios = <&arduino_header 8 + (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + /* D8 */ + reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; + /* D9 */ + slptr-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; diff --git a/boards/shields/atmel_rf2xx/atmel_rf2xx_legacy.overlay b/boards/shields/atmel_rf2xx/atmel_rf2xx_legacy.overlay new file mode 100644 index 00000000000000..6cf6bc630e8463 --- /dev/null +++ b/boards/shields/atmel_rf2xx/atmel_rf2xx_legacy.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ext1_spi { + status = "okay"; + label = "SPI_RF2XX"; + + rf2xx@0 { + compatible = "atmel,rf2xx"; + reg = <0x0>; + label = "RF2XX_0"; + spi-max-frequency = <6000000>; + irq-gpios = <&ext1_header 10 + (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + reset-gpios = <&ext1_header 8 GPIO_ACTIVE_LOW>; + slptr-gpios = <&ext1_header 11 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; diff --git a/boards/shields/atmel_rf2xx/atmel_rf2xx_mikrobus.overlay b/boards/shields/atmel_rf2xx/atmel_rf2xx_mikrobus.overlay new file mode 100644 index 00000000000000..1811b9afb20850 --- /dev/null +++ b/boards/shields/atmel_rf2xx/atmel_rf2xx_mikrobus.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&mikrobus_spi { + status = "okay"; + + /* CS */ + cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; + + rf2xx@0 { + compatible = "atmel,rf2xx"; + reg = <0x0>; + label = "RF2XX_0"; + spi-max-frequency = <6000000>; + /* INT */ + irq-gpios = <&mikrobus_header 7 + (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + /* AN */ + reset-gpios = <&mikrobus_header 0 GPIO_ACTIVE_LOW>; + /* PWM */ + slptr-gpios = <&mikrobus_header 6 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; diff --git a/boards/shields/atmel_rf2xx/atmel_rf2xx_xplained.overlay b/boards/shields/atmel_rf2xx/atmel_rf2xx_xplained.overlay new file mode 100644 index 00000000000000..0c81eb767b854f --- /dev/null +++ b/boards/shields/atmel_rf2xx/atmel_rf2xx_xplained.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&xplained1_spi { + status = "okay"; + label = "SPI_RF2XX"; + + rf2xx@0 { + compatible = "atmel,rf2xx"; + reg = <0x0>; + label = "RF2XX_0"; + spi-max-frequency = <6000000>; + irq-gpios = <&xplained1_header 2 + (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + reset-gpios = <&xplained1_header 0 GPIO_ACTIVE_LOW>; + slptr-gpios = <&xplained1_header 3 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; diff --git a/boards/shields/atmel_rf2xx/atmel_rf2xx_xpro.overlay b/boards/shields/atmel_rf2xx/atmel_rf2xx_xpro.overlay new file mode 100644 index 00000000000000..5bb781a4090006 --- /dev/null +++ b/boards/shields/atmel_rf2xx/atmel_rf2xx_xpro.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ext1_spi { + status = "okay"; + label = "SPI_RF2XX"; + + rf2xx@0 { + compatible = "atmel,rf2xx"; + reg = <0x0>; + label = "RF2XX_0"; + spi-max-frequency = <6000000>; + irq-gpios = <&ext1_header 6 + (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + reset-gpios = <&ext1_header 4 GPIO_ACTIVE_LOW>; + slptr-gpios = <&ext1_header 7 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; diff --git a/boards/shields/atmel_rf2xx/doc/ATAVRRZ600.jpg b/boards/shields/atmel_rf2xx/doc/ATAVRRZ600.jpg new file mode 100644 index 00000000000000..1d5adf11167a63 Binary files /dev/null and b/boards/shields/atmel_rf2xx/doc/ATAVRRZ600.jpg differ diff --git a/boards/shields/atmel_rf2xx/doc/atreb233-xpro-top.jpg b/boards/shields/atmel_rf2xx/doc/atreb233-xpro-top.jpg new file mode 100644 index 00000000000000..73f281892743a8 Binary files /dev/null and b/boards/shields/atmel_rf2xx/doc/atreb233-xpro-top.jpg differ diff --git a/boards/shields/atmel_rf2xx/doc/index.rst b/boards/shields/atmel_rf2xx/doc/index.rst new file mode 100644 index 00000000000000..9d7f01bb35d459 --- /dev/null +++ b/boards/shields/atmel_rf2xx/doc/index.rst @@ -0,0 +1,362 @@ +.. _atmel_at86rf2xx_transceivers: + +Atmel AT86RF2XX Transceivers +############################ + +Overview +******** + +The Atmel AT86RF2xx is a high performance radio transceiver targeted for IEEE +802.15.4, ZigBee, RF4CE, 6LoWPAN, and ISM applications. The AT86RF2xx is a +true SPI-to-antenna solution and can be operated by any external +microcontroller. + +The current IEEE 802.15.4 AT86RF2xx Zephyr driver currently works with any +2.4 Ghz transceiver, except AT86RF230. The RF2xx driver allows use of +:ref:`ieee802154_interface` and :ref:`thread_protocol_interface` network +stacks. + +This is a generic shield focused not only on Atmel Development Boards Kits. +There are compatible designations for `AT AVR-RZ600`_ and `AT REB233-XPRO`_. +This means, any Atmel board with 10-pin Xplained or 20-pin Xplained Pro +extension headers can be used. You can check +`Atmel Xplained Pro Hardware Development Kit User Guide`_ for more information. +Besides that, Arduino and MikroBus standard headers are available to complement +the shield module configurations. For any other project that doesn't fit on +the current available variations an overlay can be created. However, the +overlay is the last resource and is recommended use standard header always +possible. + +RZ600 Module +============ + +The RZ600 Development Kit needs Atmel Xplained or Xplained-Pro header +connector. The modules from this kit are available without any transceiver +advanced features. For Xplained headers the `atmel_rf2xx_xplained`_ must be +selected. For Xplained-Pro header the `atmel_rf2xx_legacy`_ must be enabled. + +.. image:: ./ATAVRRZ600.jpg + :width: 350px + :align: center + :alt: AVR-RZ600 + +Pins Assignment of the RZ600 Module +=================================== + ++---------+--------+-------------------------------------+ +| Pin | Name | Function | ++=========+========+=====================================+ +| 1 | RST | GPIO - Reset | ++---------+--------+-------------------------------------+ +| 2 | MISC | DNU - Do Not Use | ++---------+--------+-------------------------------------+ +| 3 | IRQ | GPIO - Interrupt | ++---------+--------+-------------------------------------+ +| 4 | SLP_TR | GPIO - Multi purpose control signal | ++---------+--------+-------------------------------------+ +| 5 | CS | SPI Chip Select | ++---------+--------+-------------------------------------+ +| 6 | MOSI | SPI Master Out / Slave In | ++---------+--------+-------------------------------------+ +| 7 | MISO | SPI Master In / Slave Out | ++---------+--------+-------------------------------------+ +| 8 | SCLK | SPI Clock | ++---------+--------+-------------------------------------+ +| 9 | GND | | ++---------+--------+-------------------------------------+ +| 10 | VDD | POWER +3.3V | ++---------+--------+-------------------------------------+ + +REB233-XPRO Module +================== + +The REB233-XPRO development kit uses Atmel Xplained Pro header. It is enabled +selecting `atmel_rf2xx_xpro`_ option. + +.. image:: ./atreb233-xpro-top.jpg + :width: 300px + :align: center + :alt: REB233-XPRO Top + +Pins Assignment of the REB233-XPRO Module +========================================= + ++---------+--------+-------------------------------------+ +| Pin | Name | Function | ++=========+========+=====================================+ +| 1 | ID | DNU - Do Not Use | ++---------+--------+-------------------------------------+ +| 2 | GND | | ++---------+--------+-------------------------------------+ +| 3 | DIG1 | DNU - Do Not Use | ++---------+--------+-------------------------------------+ +| 4 | DIG3 | DNU - Do Not Use | ++---------+--------+-------------------------------------+ +| 5 | DIG2 | GPIO - RX Frame Time Stamping | ++---------+--------+-------------------------------------+ +| 6 | CLKM | DNU - Do Not Use | ++---------+--------+-------------------------------------+ +| 7 | RST | GPIO - Reset | ++---------+--------+-------------------------------------+ +| 8 | | | ++---------+--------+-------------------------------------+ +| 9 | IRQ | GPIO - Interrupt | ++---------+--------+-------------------------------------+ +| 10 | SLP_TR | GPIO - Multi purpose control signal | ++---------+--------+-------------------------------------+ +| 11 | SDA | EEPROM - AT24MAC602 | ++---------+--------+-------------------------------------+ +| 12 | SCL | EEPROM - AT24MAC602 | ++---------+--------+-------------------------------------+ +| 13 | | | ++---------+--------+-------------------------------------+ +| 14 | | | ++---------+--------+-------------------------------------+ +| 15 | CS | SPI Chip Select | ++---------+--------+-------------------------------------+ +| 16 | MOSI | SPI Master Out / Slave In | ++---------+--------+-------------------------------------+ +| 17 | MISO | SPI Master In / Slave Out | ++---------+--------+-------------------------------------+ +| 18 | SCLK | SPI Clock | ++---------+--------+-------------------------------------+ +| 19 | GND | | ++---------+--------+-------------------------------------+ +| 20 | VDD | POWER +3.3V | ++---------+--------+-------------------------------------+ + +.. note:: DIG2 is not current implemented on RF2xx driver. + +Arduino Shields +=============== + +Arduino Uno R3 header is available without advanced features. It is enabled +selecting `atmel_rf2xx_arduino`_ variante option. + +Pins Assignment of the Arduino Shield Modules +============================================= + ++---------+--------+-------------------------------------+ +| Pin | Name | Function | ++=========+========+=====================================+ +| D0 | | | ++---------+--------+-------------------------------------+ +| D1 | | | ++---------+--------+-------------------------------------+ +| D2 | IRQ | GPIO - Interrupt | ++---------+--------+-------------------------------------+ +| D3 | | | ++---------+--------+-------------------------------------+ +| D4 | | | ++---------+--------+-------------------------------------+ +| D5 | | | ++---------+--------+-------------------------------------+ +| D6 | | | ++---------+--------+-------------------------------------+ +| D7 | | | ++---------+--------+-------------------------------------+ +| D8 | RST | GPIO - Reset | ++---------+--------+-------------------------------------+ +| D9 | SLP_TR | GPIO - Multi purpose control signal | ++---------+--------+-------------------------------------+ +| D10 | CS | SPI Chip Select | ++---------+--------+-------------------------------------+ +| D11 | MOSI | SPI Master Out / Slave In | ++---------+--------+-------------------------------------+ +| D12 | MISO | SPI Master In / Slave Out | ++---------+--------+-------------------------------------+ +| D13 | SCLK | SPI Clock | ++---------+--------+-------------------------------------+ +| D14 | | | ++---------+--------+-------------------------------------+ +| D15 | | | ++---------+--------+-------------------------------------+ +| | GND | | ++---------+--------+-------------------------------------+ +| | VDD | POWER +3.3V | ++---------+--------+-------------------------------------+ +| | VCC | POWER +5.0V | ++---------+--------+-------------------------------------+ + +MikroBus Shields +================ + +MikroBus header is available available without advanced features. It is +enabled selecting `atmel_rf2xx_mikrobus`_ variante option. + +Pins Assignment of the MikroBus Shield Modules +============================================== + ++---------+--------+-------------------------------------+ +| Pin | Name | Function | ++=========+========+=====================================+ +| AN | RST | GPIO - Reset | ++---------+--------+-------------------------------------+ +| RST | | | ++---------+--------+-------------------------------------+ +| CS | CS | SPI Chip Select | ++---------+--------+-------------------------------------+ +| SCK | SCLK | SPI Clock | ++---------+--------+-------------------------------------+ +| MISO | MISO | SPI Master In / Slave Out | ++---------+--------+-------------------------------------+ +| MOSI | MOSI | SPI Master Out / Slave In | ++---------+--------+-------------------------------------+ +| VCC-3.3 | VDD | POWER +3.3V | ++---------+--------+-------------------------------------+ +| GND | GND | | ++---------+--------+-------------------------------------+ +| GND | GND | | ++---------+--------+-------------------------------------+ +| VCC-5.0 | VCC | POWER +5.0V | ++---------+--------+-------------------------------------+ +| SDA | | | ++---------+--------+-------------------------------------+ +| SCL | | | ++---------+--------+-------------------------------------+ +| TX | | | ++---------+--------+-------------------------------------+ +| RX | | | ++---------+--------+-------------------------------------+ +| INT | IRQ | GPIO - Interrupt | ++---------+--------+-------------------------------------+ +| PWM | SLP_TR | GPIO - Multi purpose control signal | ++---------+--------+-------------------------------------+ + +Supported variations +==================== + +The below table suggests shield variation accordingly with end user +application. When a standard connector (arduino, mikrobus, xplained, +xplained-pro) is available on board, user should select the matching shield +configuration. When atmel_rf2xx shield is used with a board that doesn't +feature a standard connector, a dedicated .overlay file should be +provided. The remaining configurations should be used based on the board +standard headers available. + ++-----------------------------+------------------------------+-----------+ +| Connector Standard | Shield Designation | Variation | ++=============================+==============================+===========+ +| Without standard (overlay) | `atmel_rf2xx`_ | 1 | ++-----------------------------+------------------------------+-----------+ +| Atmel Xplained header | `atmel_rf2xx_xplained`_ | 2 | ++-----------------------------+------------------------------+-----------+ +| Atmel Xplained Pro header | `atmel_rf2xx_xpro`_ | 3 | ++-----------------------------+------------------------------+-----------+ +| Atmel Xplained Pro header | `atmel_rf2xx_legacy`_ | 4 | ++-----------------------------+------------------------------+-----------+ +| Arduino | `atmel_rf2xx_arduino`_ | 5 | ++-----------------------------+------------------------------+-----------+ +| MikroBus | `atmel_rf2xx_mikrobus`_ | 6 | ++-----------------------------+------------------------------+-----------+ + +Requirements +************ + +This shield requires a board which provides a configuration that allows an +SPI interface, an interrupt signal and two GPIO. (see :ref:`shields` for more +details). + +.. note:: + Boards that already have a network interface: Check network + documentation to understand how properly configure both interfaces. + To keep simple, make sure IEEE 802.15.4 is the only interface enabled + at Networking -> Link Layer Options. This will avoid problems running + Zephyr samples. + +Tested Boards +============= + ++-----------------------------+------------------------------+-----------+ +| Board | Disabled Interface | Variation | ++=============================+==============================+===========+ +| ATMEL sam4s_xplained | | 2 | ++-----------------------------+------------------------------+-----------+ +| ATMEL sam4e_xpro | Ethernet | 3 , 4 | ++-----------------------------+------------------------------+-----------+ +| ATMEL sam_v71_xult | Ethernet | 3 , 4 , 5 | ++-----------------------------+------------------------------+-----------+ + +Sample usage +************ + +You can try use IEEE 802.15.4 and/or OpenThread with the Zephyr Echo server +and Echo client samples, which provide out-of-the-box configuration for +both IEEE 802.15.4 and OpenThread. To enable IEEE 802.15.4 support in the +samples, build them with ``overlay-802154.conf`` overlay config file. Same +way, to enable OpenThread support, build them with ``overlay-ot.conf`` overlay +config file. See :ref:`sockets-echo-server-sample` and +:ref:`sockets-echo-client-sample` for details. + +Build and Programming +********************* + +Set ``-DSHIELD=`` when you invoke ``west build``. + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_server + :host-os: unix + :board: sam4s_xplained + :gen-args: -DOVERLAY_CONFIG=overlay-802154.conf + :shield: atmel_rf2xx_xplained + :goals: build flash + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_server + :host-os: unix + :board: [sam4e_xpro | sam_v71_xult] + :gen-args: -DOVERLAY_CONFIG=overlay-802154.conf + :shield: [atmel_rf2xx_xpro | atmel_rf2xx_legacy] + :goals: build flash + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_server + :host-os: unix + :board: [sam_v71_xult | frdm_k64f | nucleo_f767zi] + :gen-args: -DOVERLAY_CONFIG=overlay-802154.conf + :shield: atmel_rf2xx_arduino + :goals: build flash + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_server + :host-os: unix + :board: lpcxpresso55s69_ns + :gen-args: -DOVERLAY_CONFIG=overlay-802154.conf + :shield: atmel_rf2xx_microbus + :goals: build flash + :compact: + +References +********** + +.. target-notes:: + +.. _AT AVR-RZ600: + https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/ATAVRRZ600 + +.. _AT REB233-XPRO: + https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/ATREB233-XPRO + +.. _Atmel Xplained Pro Hardware Development Kit User Guide: + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42091-Atmel-Xplained-Pro-Hardware-Development-Kit_User%20Guide.pdf + +.. _atmel_rf2xx: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/atmel_rf2xx/atmel_rf2xx.overlay + +.. _atmel_rf2xx_xplained: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/atmel_rf2xx/atmel_rf2xx_xplained.overlay + +.. _atmel_rf2xx_xpro: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/atmel_rf2xx/atmel_rf2xx_xpro.overlay + +.. _atmel_rf2xx_legacy: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/atmel_rf2xx/atmel_rf2xx_legacy.overlay + +.. _atmel_rf2xx_arduino: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/atmel_rf2xx/atmel_rf2xx_arduino.overlay + +.. _atmel_rf2xx_mikrobus: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/atmel_rf2xx/atmel_rf2xx_mikrobus.overlay diff --git a/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.defconfig b/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.defconfig new file mode 100644 index 00000000000000..34d9718ecf37db --- /dev/null +++ b/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.defconfig @@ -0,0 +1,77 @@ +# Copyright (c) 2020 Teslabs Engineering S.L. +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_BUYDISPLAY_2_8_TFT_TOUCH_ARDUINO + +if DISPLAY + +config SPI + default y + +config ILI9340 + default y + +if KSCAN + +config I2C + default y + +config KSCAN_FT5336 + default y + +# NOTE: Enable if IRQ line is available (requires to solder jumper) +config KSCAN_FT5336_INTERRUPT + default n + +config KSCAN_INIT_PRIORITY + default 60 + +endif # KSCAN + +if LVGL + +config LVGL_DISPLAY_DEV_NAME + default "DISPLAY" + +config LVGL_HOR_RES_MAX + default 240 + +config LVGL_VER_RES_MAX + default 320 + +config LVGL_VDB_SIZE + default 64 + +config LVGL_BITS_PER_PIXEL + default 16 + +choice LVGL_COLOR_DEPTH + default LVGL_COLOR_DEPTH_16 +endchoice + +config LVGL_COLOR_16_SWAP + default y + +config KSCAN + default y + +config LVGL_POINTER_KSCAN + default y + +config LVGL_POINTER_KSCAN_DEV_NAME + default "TOUCH" + +config LVGL_POINTER_KSCAN_SWAP_XY + default y + +config LVGL_POINTER_KSCAN_INVERT_X + default y + +config LVGL_POINTER_KSCAN_INVERT_Y + default y + +endif # LVGL + +endif # DISPLAY + +endif # SHIELD_BUYDISPLAY_2_8_TFT_TOUCH_ARDUINO diff --git a/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.shield b/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.shield new file mode 100644 index 00000000000000..6f31cdc30e355b --- /dev/null +++ b/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2020 Teslabs Engineering S.L. +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_BUYDISPLAY_2_8_TFT_TOUCH_ARDUINO + def_bool $(shields_list_contains,buydisplay_2_8_tft_touch_arduino) diff --git a/boards/shields/buydisplay_2_8_tft_touch_arduino/boards/nrf52840dk_nrf52840.overlay b/boards/shields/buydisplay_2_8_tft_touch_arduino/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..20cbeb75763340 --- /dev/null +++ b/boards/shields/buydisplay_2_8_tft_touch_arduino/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2020 Teslabs Engineering S.L. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* NOTE: spi1 MISO pin is used by the display for the cmd/data line */ +&spi1 { + status = "disabled"; +}; diff --git a/boards/shields/buydisplay_2_8_tft_touch_arduino/buydisplay_2_8_tft_touch_arduino.overlay b/boards/shields/buydisplay_2_8_tft_touch_arduino/buydisplay_2_8_tft_touch_arduino.overlay new file mode 100644 index 00000000000000..8b99950fd69b47 --- /dev/null +++ b/boards/shields/buydisplay_2_8_tft_touch_arduino/buydisplay_2_8_tft_touch_arduino.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 Teslabs Engineering S.L. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */ + + ili9340@0 { + compatible = "ilitek,ili9340"; + label = "DISPLAY"; + spi-max-frequency = <25000000>; + reg = <0>; + cmd-data-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */ + reset-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ + pixel-format = ; + rotation = <0>; + frmctr1 = [00 18]; + pwctrl1 = [23 00]; + vmctrl1 = [3e 28]; + vmctrl2 = [86]; + pgamctrl = [0f 31 2b 0c 0e 08 4e f1 37 07 10 03 0e 09 00]; + ngamctrl = [00 0e 14 03 11 07 31 c1 48 08 0f 0c 31 36 0f]; + }; +}; + +&arduino_i2c { + ft5336@38 { + compatible = "focaltech,ft5336"; + reg = <0x38>; + label = "TOUCH"; + /* Uncomment if IRQ line is available (requires to solder jumper) */ + /* int-gpios = <&arduino_header 11 GPIO_ACTIVE_LOW>; */ /* D5 */ + }; +}; diff --git a/boards/shields/buydisplay_2_8_tft_touch_arduino/doc/index.rst b/boards/shields/buydisplay_2_8_tft_touch_arduino/doc/index.rst new file mode 100644 index 00000000000000..ca1c4206d7d2e1 --- /dev/null +++ b/boards/shields/buydisplay_2_8_tft_touch_arduino/doc/index.rst @@ -0,0 +1,77 @@ +.. _buydisplay_2_8_tft_touch_arduino: + +Buydisplay 2.8" TFT Touch Shield with Arduino adapter +##################################################### + +Overview +******** + +The Buydisplay 2.8" TFT Touch Shield has a resolution of 320x240 +pixels and is based on the ILI9341 controller. This shield comes with +a capacitive FT6206 controller touchscreen. The Arduino adapter is +required to use this shield. + +More information about the shield and Arduino adapter can be found at +the `Buydisplay 2.8" TFT Touch Shield website`_ and +`Arduino adapter website`_. + +Pin Assignments +=============== + ++-----------------------+---------------------------------------------+ +| Shield Connector Pin | Function | ++=======================+=============================================+ +| D5 | Touch Controller IRQ (see note below) | ++-----------------------+---------------------------------------------+ +| D7 | ILI9341 DC (Data/Command) | ++-----------------------+---------------------------------------------+ +| D10 | ILI9341 Reset | ++-----------------------+---------------------------------------------+ +| D9 | ILI9341 SPI CSn | ++-----------------------+---------------------------------------------+ +| D11 | SPI MOSI (Serial Data Input) | ++-----------------------+---------------------------------------------+ +| D12 | SPI MISO (Serial Data Out) | ++-----------------------+---------------------------------------------+ +| D13 | SPI SCK (Serial Clock Input) | ++-----------------------+---------------------------------------------+ +| SDA | FT6206 SDA | ++-----------------------+---------------------------------------------+ +| SCL | FT6206 SCL | ++-----------------------+---------------------------------------------+ + +.. note:: + Touch controller IRQ line is not connected by default. You will need + to solder the ``5 INT`` jumper to use it. You will also need to + adjust driver configuration and its Device Tree entry to make use of + it. + +Requirements +************ + +This shield can only be used with a board which provides a configuration +for Arduino connectors and defines node aliases for SPI and GPIO interfaces +(see :ref:`shields` for more details). + +Programming +*********** + +Set ``-DSHIELD=buydisplay_2_8_tft_touch_arduino`` when you invoke +``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/gui/lvgl + :board: nrf52840dk_nrf52840 + :shield: buydisplay_2_8_tft_touch_arduino + :goals: build + +References +********** + +.. target-notes:: + +.. _Buydisplay 2.8" TFT Touch Shield website: + https://www.buydisplay.com/2-8-inch-tft-touch-shield-for-arduino-w-capacitive-touch-screen-module + +.. _Arduino adapter website: + https://www.buydisplay.com/arduino-shield-for-tft-lcd-with-ili9341-controller-and-arduino-due-mega-uno diff --git a/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.defconfig b/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.defconfig new file mode 100644 index 00000000000000..a895885afb2852 --- /dev/null +++ b/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.defconfig @@ -0,0 +1,74 @@ +# Copyright (c) 2020 Teslabs Engineering S.L. +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_BUYDISPLAY_3_5_TFT_TOUCH_ARDUINO + +if DISPLAY + +config SPI + default y + +config ILI9488 + default y + +if KSCAN + +config I2C + default y + +config KSCAN_FT5336 + default y + +# NOTE: Enable if IRQ line is available (requires to solder jumper) +config KSCAN_FT5336_INTERRUPT + default n + +config KSCAN_INIT_PRIORITY + default 60 + +endif # KSCAN + +if LVGL + +config LVGL_DISPLAY_DEV_NAME + default "DISPLAY" + +config LVGL_HOR_RES_MAX + default 320 + +config LVGL_VER_RES_MAX + default 480 + +config LVGL_VDB_SIZE + default 32 + +config LVGL_BITS_PER_PIXEL + default 24 + +choice LVGL_COLOR_DEPTH + default LVGL_COLOR_DEPTH_16 +endchoice + +config KSCAN + default y + +config LVGL_POINTER_KSCAN + default y + +config LVGL_POINTER_KSCAN_DEV_NAME + default "TOUCH" + +config LVGL_POINTER_KSCAN_SWAP_XY + default y + +config LVGL_POINTER_KSCAN_INVERT_X + default y + +config LVGL_POINTER_KSCAN_INVERT_Y + default y + +endif # LVGL + +endif # DISPLAY + +endif # SHIELD_BUYDISPLAY_3_5_TFT_TOUCH_ARDUINO diff --git a/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.shield b/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.shield new file mode 100644 index 00000000000000..2515df22d223f3 --- /dev/null +++ b/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2020 Teslabs Engineering S.L. +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_BUYDISPLAY_3_5_TFT_TOUCH_ARDUINO + def_bool $(shields_list_contains,buydisplay_3_5_tft_touch_arduino) diff --git a/boards/shields/buydisplay_3_5_tft_touch_arduino/boards/nrf52840dk_nrf52840.overlay b/boards/shields/buydisplay_3_5_tft_touch_arduino/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..20cbeb75763340 --- /dev/null +++ b/boards/shields/buydisplay_3_5_tft_touch_arduino/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2020 Teslabs Engineering S.L. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* NOTE: spi1 MISO pin is used by the display for the cmd/data line */ +&spi1 { + status = "disabled"; +}; diff --git a/boards/shields/buydisplay_3_5_tft_touch_arduino/buydisplay_3_5_tft_touch_arduino.overlay b/boards/shields/buydisplay_3_5_tft_touch_arduino/buydisplay_3_5_tft_touch_arduino.overlay new file mode 100644 index 00000000000000..f6d2c2c288a45b --- /dev/null +++ b/boards/shields/buydisplay_3_5_tft_touch_arduino/buydisplay_3_5_tft_touch_arduino.overlay @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Teslabs Engineering S.L. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */ + + ili9488@0 { + compatible = "ilitek,ili9488"; + label = "DISPLAY"; + spi-max-frequency = <25000000>; + reg = <0>; + cmd-data-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */ + reset-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ + pixel-format = ; + rotation = <0>; + frmctr1 = [a0 11]; + pwctrl1 = [17 15]; + pwctrl2 = [41]; + pgamctrl = [00 03 09 08 16 0a 3f 78 4c 09 0a 08 16 1a 0f]; + ngamctrl = [00 16 19 03 0f 05 32 45 46 04 0e 0d 35 37 0f]; + }; +}; + +&arduino_i2c { + ft5336@38 { + compatible = "focaltech,ft5336"; + reg = <0x38>; + label = "TOUCH"; + /* Uncomment if IRQ line is available (requires to solder jumper) */ + /* int-gpios = <&arduino_header 11 GPIO_ACTIVE_LOW>; */ /* D5 */ + }; +}; diff --git a/boards/shields/buydisplay_3_5_tft_touch_arduino/doc/index.rst b/boards/shields/buydisplay_3_5_tft_touch_arduino/doc/index.rst new file mode 100644 index 00000000000000..0ebbd394b4a41e --- /dev/null +++ b/boards/shields/buydisplay_3_5_tft_touch_arduino/doc/index.rst @@ -0,0 +1,79 @@ +.. _buydisplay_3_5_tft_touch_arduino: + +Buydisplay 3.5" TFT Touch Shield with Arduino adapter +##################################################### + +Overview +******** + +The Buydisplay 3.5" TFT Touch Shield has a resolution of 320x480 +pixels and is based on the ILI9488 controller. On the capacitive touch +version this shield comes with a FT6236 touch controller. The Arduino +adapter is required to use this shield. Note that both display and +Arduino shields are sold in multiple combinations of interfaces. The +current Zephyr driver only supports the 4-wire SPI interface. + +More information about the shield and Arduino adapter can be found at +the `Buydisplay 3.5" TFT Touch Shield website`_ and +`Arduino adapter website`_. + +Pin Assignments +=============== + ++-----------------------+---------------------------------------------+ +| Shield Connector Pin | Function | ++=======================+=============================================+ +| D5 | Touch Controller IRQ (see note below) | ++-----------------------+---------------------------------------------+ +| D7 | ILI9488 DC (Data/Command) | ++-----------------------+---------------------------------------------+ +| D10 | ILI9488 Reset | ++-----------------------+---------------------------------------------+ +| D9 | ILI9488 SPI CSn | ++-----------------------+---------------------------------------------+ +| D11 | SPI MOSI (Serial Data Input) | ++-----------------------+---------------------------------------------+ +| D12 | SPI MISO (Serial Data Out) | ++-----------------------+---------------------------------------------+ +| D13 | SPI SCK (Serial Clock Input) | ++-----------------------+---------------------------------------------+ +| SDA | FT6236 SDA | ++-----------------------+---------------------------------------------+ +| SCL | FT6236 SCL | ++-----------------------+---------------------------------------------+ + +.. note:: + Touch controller IRQ line is not connected by default. You will need + to solder the ``5 INT`` jumper to use it. You will also need to + adjust driver configuration and its Device Tree entry to make use of + it. + +Requirements +************ + +This shield can only be used with a board which provides a configuration +for Arduino connectors and defines node aliases for SPI and GPIO interfaces +(see :ref:`shields` for more details). + +Programming +*********** + +Set ``-DSHIELD=buydisplay_3_5_tft_touch_arduino`` when you invoke +``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/gui/lvgl + :board: nrf52840dk_nrf52840 + :shield: buydisplay_3_5_tft_touch_arduino + :goals: build + +References +********** + +.. target-notes:: + +.. _Buydisplay 3.5" TFT Touch Shield website: + https://www.buydisplay.com/lcd-3-5-inch-320x480-tft-display-module-optl-touch-screen-w-breakout-board + +.. _Arduino adapter website: + https://www.buydisplay.com/arduino-3-5-tft-lcd-touch-shield-serial-spi-example-for-mega-due diff --git a/boards/shields/dac80508_evm/Kconfig.defconfig b/boards/shields/dac80508_evm/Kconfig.defconfig new file mode 100644 index 00000000000000..97355b56299995 --- /dev/null +++ b/boards/shields/dac80508_evm/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2020 M2I Corporation +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_DAC80508_EVM + +if DAC + +config SPI + default y + +config DAC_DACX0508 + default y + +endif # DAC + +endif # SHIELD_DAC80508_EVM diff --git a/boards/shields/dac80508_evm/Kconfig.shield b/boards/shields/dac80508_evm/Kconfig.shield new file mode 100644 index 00000000000000..6e516fc6f97b99 --- /dev/null +++ b/boards/shields/dac80508_evm/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2020 M2I Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_DAC80508_EVM + def_bool $(shields_list_contains,dac80508_evm) diff --git a/boards/shields/dac80508_evm/dac80508_evm.overlay b/boards/shields/dac80508_evm/dac80508_evm.overlay new file mode 100644 index 00000000000000..f6e9dc2a31da9d --- /dev/null +++ b/boards/shields/dac80508_evm/dac80508_evm.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020 M2I Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ + + dac80508: dac80508@0 { + compatible = "ti,dac80508"; + reg = <0x0>; + label = "DAC80508"; + spi-max-frequency = <1000000>; + #io-channel-cells = <1>; + }; +}; diff --git a/boards/shields/dac80508_evm/doc/dac80508evm-board-photo.jpg b/boards/shields/dac80508_evm/doc/dac80508evm-board-photo.jpg new file mode 100644 index 00000000000000..d8270b90835eb2 Binary files /dev/null and b/boards/shields/dac80508_evm/doc/dac80508evm-board-photo.jpg differ diff --git a/boards/shields/dac80508_evm/doc/dac80508evm_connected.jpg b/boards/shields/dac80508_evm/doc/dac80508evm_connected.jpg new file mode 100644 index 00000000000000..4f0480583a979c Binary files /dev/null and b/boards/shields/dac80508_evm/doc/dac80508evm_connected.jpg differ diff --git a/boards/shields/dac80508_evm/doc/index.rst b/boards/shields/dac80508_evm/doc/index.rst new file mode 100644 index 00000000000000..1aa61378d46783 --- /dev/null +++ b/boards/shields/dac80508_evm/doc/index.rst @@ -0,0 +1,43 @@ +.. _dac80508_evm_shield: + +DAC80508 Evaluation Module +#################################### + +Overview +******** + +The Texas Instruments DAC80508 Evaluation Module (EVM) is a +DAC development module for the TI DAC80508 series. + +.. figure:: ./dac80508evm-board-photo.jpg + :width: 640px + :align: center + :alt: DAC80508 EVM + +Requirements +************ + +This shield can only be used with a development board that provides a +configuration for Arduino connectors and defines a node alias for the +SPI interface (see :ref:`shields` for more details). + +The SPI connector pins on the DAC80508 EVM can be connected to the +Arduino headers of the development board using jumper wires. +In addition, 5V must be connected to the DAC80508 EVM's TP6(VDD). + +.. figure:: ./dac80508evm_connected.jpg + :width: 640px + :align: center + :alt: DAC80508 EVM + STM32F746G_DISCO + +For more information about interfacing the DAC80508 series and the +DACx0508 EVM in particular, see these TI documents: + +- `DACx0508 Evaluation Module User's Guide`_ +- `DAC80508 True 16-bit, 8-channel, SPI`_ + +.. _DACx0508 Evaluation Module User's Guide: + https://www.ti.com/lit/pdf/slau734 + +.. _DAC80508 True 16-bit, 8-channel, SPI: + https://www.ti.com/product/DAC80508 diff --git a/boards/shields/dfrobot_can_bus_v2_0/dfrobot_can_bus_v2_0.overlay b/boards/shields/dfrobot_can_bus_v2_0/dfrobot_can_bus_v2_0.overlay index 27a7621788c835..5b522669cfd862 100644 --- a/boards/shields/dfrobot_can_bus_v2_0/dfrobot_can_bus_v2_0.overlay +++ b/boards/shields/dfrobot_can_bus_v2_0/dfrobot_can_bus_v2_0.overlay @@ -6,7 +6,7 @@ &arduino_spi { status = "okay"; - cs-gpios = <&arduino_header 16 0>; /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ can1: mcp2515@0 { compatible = "microchip,mcp2515"; diff --git a/boards/shields/esp_8266/Kconfig.defconfig b/boards/shields/esp_8266/Kconfig.defconfig index 449d3d821895a9..e8b9da4ad3ed1e 100644 --- a/boards/shields/esp_8266/Kconfig.defconfig +++ b/boards/shields/esp_8266/Kconfig.defconfig @@ -1,7 +1,9 @@ # Copyright (c) 2020 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 -if SHIELD_ESP_8266 +if SHIELD_ESP_8266 || \ + SHIELD_ESP_8266_ARDUINO || \ + SHIELD_ESP_8266_MIKROBUS if NETWORKING @@ -14,8 +16,10 @@ choice WIFI_ESP_AT_VERSION depends on WIFI_ESP endchoice -rsource "boards/*.defconfig" +orsource "boards/*.defconfig" endif # NETWORKING -endif # SHIELD_ESP_8266 +endif # SHIELD_ESP_8266 || \ + # SHIELD_ESP_8266_ARDUINO || \ + # SHIELD_ESP_8266_MIKROBUS diff --git a/boards/shields/esp_8266/Kconfig.shield b/boards/shields/esp_8266/Kconfig.shield index ab4011cfbfa4e5..810d4dcde4b0f9 100644 --- a/boards/shields/esp_8266/Kconfig.shield +++ b/boards/shields/esp_8266/Kconfig.shield @@ -3,3 +3,9 @@ config SHIELD_ESP_8266 def_bool $(shields_list_contains,esp_8266) + +config SHIELD_ESP_8266_ARDUINO + def_bool $(shields_list_contains,esp_8266_arduino) + +config SHIELD_ESP_8266_MIKROBUS + def_bool $(shields_list_contains,esp_8266_mikrobus) diff --git a/boards/shields/esp_8266/boards/frdm_k64f.overlay b/boards/shields/esp_8266/boards/frdm_k64f.overlay index d8aff594e5dc6f..ea5fa47e8aadcb 100644 --- a/boards/shields/esp_8266/boards/frdm_k64f.overlay +++ b/boards/shields/esp_8266/boards/frdm_k64f.overlay @@ -10,14 +10,3 @@ */ status = "disabled"; }; - -&arduino_serial { - status = "okay"; - current-speed = <115200>; - - esp8266 { - compatible = "espressif,esp"; - label = "esp8266"; - status = "okay"; - }; -}; diff --git a/boards/shields/esp_8266/boards/sam4e_xpro.defconfig b/boards/shields/esp_8266/boards/sam4e_xpro.defconfig index cfc8dc8aa538ae..e236d6ab17fe9e 100644 --- a/boards/shields/esp_8266/boards/sam4e_xpro.defconfig +++ b/boards/shields/esp_8266/boards/sam4e_xpro.defconfig @@ -14,7 +14,4 @@ config ETH_SAM_GMAC config USART_SAM default y -config TEST_RANDOM_GENERATOR - default y - endif # BOARD_SAM4E_XPRO diff --git a/boards/shields/esp_8266/doc/index.rst b/boards/shields/esp_8266/doc/index.rst index 803f434cde110f..83805ea7aa6ce9 100644 --- a/boards/shields/esp_8266/doc/index.rst +++ b/boards/shields/esp_8266/doc/index.rst @@ -49,6 +49,11 @@ Requirements This shield requires a board which provides a configuration that allows an UART interface. (see :ref:`shields` for more details). +.. note:: + Sometimes boards declare standard headers like Arduino R3 but not define + all connections. Make sure that the board you are using have all + definitions to avoid build errors. + The ESP-8266 should be loaded with the `ESP8266 AT Bin`_ software which is available at Espressif Systems web site. The ESP-01 module have up to 1MB of flash and the last available stack that fits on this device is ESP8266 AT Bin @@ -76,16 +81,54 @@ to works: - ESP-8266 bootloader won't send garbage. Try connect at 74880 bps if you module have 26MHz crystal to detect boot fails. -Programming -*********** +.. note:: + Boards that already have a network interface: Check network + documentation to understand how properly configure both interfaces. + To keep simple, make sure WiFi is the only interface enabled at + Networking -> Link Layer Options. This will avoid problems running + Zephyr samples. + +Supported variations +==================== + +The below table suggests shield variation accordingly with end user +application. When a standard connector (arduino, mikrobus) is available on +board, user should select the matching shield configuration. When esp_8266 +shield is used with a board that doesn't feature a standard connector, a +dedicated .overlay file should be provided. The remaining +configurations should be used based on the board standard headers available. + ++-----------------------------+------------------------------+-----------+ +| Connector Standard | Shield Designation | Variation | ++=============================+==============================+===========+ +| Without standard (overlay) | `esp_8266`_ | 1 | ++-----------------------------+------------------------------+-----------+ +| Arduino | `esp_8266_arduino`_ | 2 | ++-----------------------------+------------------------------+-----------+ +| MikroBus | `esp_8266_mikrobus`_ | 3 | ++-----------------------------+------------------------------+-----------+ + + +Build and Programming +********************* + +Set ``-DSHIELD=`` when you invoke ``west build``. -Set ``-DSHIELD=esp_8266`` when you invoke ``west build``. For example: +To build shield with specific overlay: .. zephyr-app-commands:: :zephyr-app: samples/net/wifi :board: sam4e_xpro :shield: esp_8266 - :goals: build + :goals: build flash + +To build shield with standard headers: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/wifi + :board: [disco_l475_iot1 | frdm_k64f | lpcxpresso55s69_ns | nucleo_f767zi] + :shield: [esp_8266_arduino | esp_8266_mikrobus] + :goals: build flash References ********** @@ -94,3 +137,12 @@ References .. _ESP8266 AT Bin: https://www.espressif.com/en/support/download/at + +.. _esp_8266: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/esp_8266/esp_8266.overlay + +.. _esp_8266_arduino: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/esp_8266/esp_8266_arduino.overlay + +.. _esp_8266_mikrobus: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/esp_8266/esp_8266_mikrobus.overlay diff --git a/boards/shields/esp_8266/esp_8266.overlay b/boards/shields/esp_8266/esp_8266.overlay index 5c9905465f8628..74664182a9ee7a 100644 --- a/boards/shields/esp_8266/esp_8266.overlay +++ b/boards/shields/esp_8266/esp_8266.overlay @@ -5,8 +5,6 @@ */ /* - * This file can't be used once this shield target all board with - * a free UART port. If there is a &arduino_serial declared here, - * boards that don't have the compatible shield pins won't work. This - * happens because device tree can't handle an inexistent node. + * This file is intentionally empty. Please confer with shield documentation + * for instructions to use this shield. */ diff --git a/boards/shields/esp_8266/boards/disco_l475_iot1.overlay b/boards/shields/esp_8266/esp_8266_arduino.overlay similarity index 100% rename from boards/shields/esp_8266/boards/disco_l475_iot1.overlay rename to boards/shields/esp_8266/esp_8266_arduino.overlay diff --git a/boards/shields/esp_8266/esp_8266_mikrobus.overlay b/boards/shields/esp_8266/esp_8266_mikrobus.overlay new file mode 100644 index 00000000000000..7c805e479daf65 --- /dev/null +++ b/boards/shields/esp_8266/esp_8266_mikrobus.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&mikrobus_serial { + status = "okay"; + current-speed = <115200>; + + esp8266 { + compatible = "espressif,esp"; + label = "esp8266"; + status = "okay"; + }; +}; diff --git a/boards/shields/frdm_kw41z/doc/index.rst b/boards/shields/frdm_kw41z/doc/index.rst index 57b79cd2c5b3ec..7314d1944bd2ae 100644 --- a/boards/shields/frdm_kw41z/doc/index.rst +++ b/boards/shields/frdm_kw41z/doc/index.rst @@ -30,9 +30,9 @@ host controller interface (HCI): #. Open :file:`source/common/app_preinclude.h` and add the following line: -.. code-block:: console + .. code-block:: console - #define gSerialMgrRxBufSize_c 64 + #define gSerialMgrRxBufSize_c 64 #. Build the project to generate a binary :file:`hci_black_box_frdmkw41z.bin`. @@ -44,8 +44,10 @@ host controller interface (HCI): #. Remove the USB cable to power down the board. #. Configure the jumpers J30 and J31 such that: + - J30 pin 1 is attached to J31 pin 2 - J30 pin 2 is attached to J31 pin 1 + The jumpers should be parallel to the Arduino headers. This configuration routes the UART RX and TX signals to the Arduino header, rather than to the OpenSDA circuit. diff --git a/boards/shields/inventek_eswifi/Kconfig.defconfig b/boards/shields/inventek_eswifi/Kconfig.defconfig new file mode 100644 index 00000000000000..7668508208d83b --- /dev/null +++ b/boards/shields/inventek_eswifi/Kconfig.defconfig @@ -0,0 +1,26 @@ +# Copyright (c) 2020 ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_INVENTEK_ESWIFI || \ + SHIELD_INVENTEK_ESWIFI_ARDUINO_SPI || \ + SHIELD_INVENTEK_ESWIFI_ARDUINO_UART + +if NETWORKING + +config WIFI_ESWIFI + default y + depends on WIFI + +orsource "boards/*.defconfig" + +choice WIFI_ESWIFI_BUS + default WIFI_ESWIFI_BUS_SPI if SHIELD_INVENTEK_ESWIFI_ARDUINO_SPI + default WIFI_ESWIFI_BUS_UART if SHIELD_INVENTEK_ESWIFI_ARDUINO_UART + depends on WIFI_ESWIFI +endchoice + +endif # NETWORKING + +endif # SHIELD_INVENTEK_ESWIFI || \ + # SHIELD_INVENTEK_ESWIFI_ARDUINO_SPI || \ + # SHIELD_INVENTEK_ESWIFI_ARDUINO_UART diff --git a/boards/shields/inventek_eswifi/Kconfig.shield b/boards/shields/inventek_eswifi/Kconfig.shield new file mode 100644 index 00000000000000..0dc6d207843295 --- /dev/null +++ b/boards/shields/inventek_eswifi/Kconfig.shield @@ -0,0 +1,11 @@ +# Copyright (c) 2020 ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_INVENTEK_ESWIFI + def_bool $(shields_list_contains,inventek_eswifi) + +config SHIELD_INVENTEK_ESWIFI_ARDUINO_SPI + def_bool $(shields_list_contains,inventek_eswifi_arduino_spi) + +config SHIELD_INVENTEK_ESWIFI_ARDUINO_UART + def_bool $(shields_list_contains,inventek_eswifi_arduino_uart) diff --git a/boards/shields/inventek_eswifi/boards/frdm_k64f.defconfig b/boards/shields/inventek_eswifi/boards/frdm_k64f.defconfig new file mode 100644 index 00000000000000..1a783d715b5af8 --- /dev/null +++ b/boards/shields/inventek_eswifi/boards/frdm_k64f.defconfig @@ -0,0 +1,11 @@ +# +# Copyright (c) 2020 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_FRDM_K64F + +config NET_L2_ETHERNET + default n + +endif # BOARD_FRDM_K64F diff --git a/boards/shields/inventek_eswifi/boards/nucleo_f767zi.defconfig b/boards/shields/inventek_eswifi/boards/nucleo_f767zi.defconfig new file mode 100644 index 00000000000000..20ab107f727754 --- /dev/null +++ b/boards/shields/inventek_eswifi/boards/nucleo_f767zi.defconfig @@ -0,0 +1,11 @@ +# +# Copyright (c) 2020 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NUCLEO_F767ZI + +config NET_L2_ETHERNET + default n + +endif # BOARD_NUCLEO_F767ZI diff --git a/boards/shields/inventek_eswifi/doc/index.rst b/boards/shields/inventek_eswifi/doc/index.rst new file mode 100644 index 00000000000000..8ac391ceb4a394 --- /dev/null +++ b/boards/shields/inventek_eswifi/doc/index.rst @@ -0,0 +1,196 @@ +.. _inventek_eswifi_shield: + +Inventek es-WIFI Shield +####################### + +Overview +******** + +The es-WIFI (embedded Serial-to-WiFi) modules are devices developed by Inventek +Systems. It integrates WIFI and optionaly Bluetooth Low Energy. The es-WIFI +devices can run Cypress WICED or Inventek's IWIN (Inventek Systems Wireless +Interoperability Network) AT commands set. The current es-WIFI driver is able +to use one of two serial interfaces: SPI or UART. + +The Zephyr es-WIFI drivers was implemented using ISM43362-M3G-L44 with SPI +interface. The UART was implemented with ISM4343-WBM-L151. Besides that, +user can reprogram the modules to switch from one interface type to another +by the JTAG pin header. + + +ISMART4343C-EVB +=============== + +The `ISMART4343C-EVB`_ is a development Kit with Arduino Uno R3 compatible +shield. It allows evaluate es-WIFI modules with SPI or UART interface. For +UART interface the `inventek_eswifi_arduino_uart`_ must be selected. For +SPI interface the `inventek_eswifi_arduino_spi`_ must be enabled. The EVB +can use 5V from Arduino header, if board provide it, J17 position 1-2. +Otherwise, J17 2-3 will select USB-5V. More information can be found at +`ISMART4343C-EVB Users Manual`_. + +.. note:: + The Inventek's EVBs signals are 3.3V only. + +.. image:: ./ismart4343c-evb.jpg + :width: 350px + :align: center + :alt: ISMART4343C-EVB + +Pins Assignment of the ISMART EVBs +================================== + +The below table presents signals by interface. The UART switch SW3 must be on +position 3 to enable RX/TX signals when using es-WIFI with UART firmware. + +To enable full control by Arduino header user should do some manual wiring. +The signals from D3 up to D7 are not connected by default on the Inventek's +shield. These signals marked as optional can help on development. The current +driver do not handle that signals and are simple suggestions and can be left +as is. Some arduino boards don't have NRST pin connected to a GPIO pin. The +recomendation is bend the NRST pin and make a wire to D6. WAKE-UP signal is +available at header J26 pin 1 and shield configuration uses D7 to control that +signal, user need do a wire connecting these two terminals. On the below +image is possible see suggested wiring connections. + +.. image:: ./ismart4343c-evb-wiring.jpg + :width: 800px + :align: center + :alt: ISMART4343C-EVB Wiring + ++-----------------------+-----------+---------------------+ +| Arduino Connector Pin | Function | Serial Connection | ++=======================+===========+=====================+ +| D0 | UART RX | UART | ++-----------------------+-----------+---------------------+ +| D1 | UART TX | UART | ++-----------------------+-----------+---------------------+ +| D3 | CFG-1 | UART/SPI [optional] | ++-----------------------+-----------+---------------------+ +| D4 | CFG-0 | UART/SPI [optional] | ++-----------------------+-----------+---------------------+ +| D5 | BOOT-0 | UART/SPI [optional] | ++-----------------------+-----------+---------------------+ +| D6 | NRST | UART/SPI [wiring] | ++-----------------------+-----------+---------------------+ +| D7 | WAKE-UP | UART/SPI [wiring] | ++-----------------------+-----------+---------------------+ +| D9 | CMD/RDY | SPI | ++-----------------------+-----------+---------------------+ +| D10 | SPI CS | SPI | ++-----------------------+-----------+---------------------+ +| D11 | SPI MOSI | SPI | ++-----------------------+-----------+---------------------+ +| D12 | SPI MISO | SPI | ++-----------------------+-----------+---------------------+ +| D13 | SPI SCK | SPI | ++-----------------------+-----------+---------------------+ + + +Supported variations +==================== + +The below table suggests shield variation accordingly with end user +application. When a standard Arduino R3 connector is available on board, user +should select the matching shield configuration based on the serial interface +(SERIAL or SPI). The inventek_eswifi is available to allow users testing a +built-in module with dedicated .overlay and .defconfig files. + ++-----------------------------+---------------------------------+-----------+ +| Connector Standard | Shield Designation | Variation | ++=============================+=================================+===========+ +| Without standard (overlay) | `inventek_eswifi`_ | 1 | ++-----------------------------+---------------------------------+-----------+ +| Arduino by UART | `inventek_eswifi_arduino_uart`_ | 2 | ++-----------------------------+---------------------------------+-----------+ +| Arduino by SPI | `inventek_eswifi_arduino_spi`_ | 3 | ++-----------------------------+---------------------------------+-----------+ + +Requirements +************ + +This shield requires a board which provides a configuration that allows an +UART or SPI interface and two or three GPIO. (see :ref:`shields` for more +details). + +.. note:: + Some boards may already have a network interface: Check network + documentation to understand how properly configure both interfaces. + To keep simple, you can keep only the WIFI interface enabled at + Networking -> Link Layer Options. This will avoid problems running + Zephyr samples. + +Tested Boards +============= + ++-----------------------------+------------------------------+-----------+ +| Board | Disabled Interface | Variation | ++=============================+==============================+===========+ +| ATMEL sam_v71_xult | Ethernet | 2 , 3 | ++-----------------------------+------------------------------+-----------+ +| ST nucleo_f767zi | Ethernet | 2 , 3 | ++-----------------------------+------------------------------+-----------+ +| ST disco_l475_iot1 | | - | ++-----------------------------+------------------------------+-----------+ + +.. note:: + ST disco_l475_iot1 already have an ISM43362 module with IWIN SPI + firmware. It doesn't need this shield to expose es-WIFI. It is only + used here as reference to demonstrate how configure an on-board + module. + +Sample usage +************ + +The reference sample for WIFI is :ref:`wifi_sample`. It allows you use WIFI +shell to scan local Wireless networks. With the password you can pick, +connect and send ping. + +Build and Programming +********************* + +Set ``-DSHIELD=`` when you invoke ``west build``. + +.. zephyr-app-commands:: + :zephyr-app: samples/net/wifi + :host-os: unix + :board: [sam_v71_xult | nucleo_f767zi] + :shield: inventek_eswifi_arduino_uart + :goals: build flash + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/wifi + :host-os: unix + :board: [sam_v71_xult | nucleo_f767zi] + :shield: inventek_eswifi_arduino_spi + :goals: build flash + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/wifi + :host-os: unix + :board: disco_l475_iot1 + :goals: build flash + :compact: + + +References +********** + +.. target-notes:: + +.. _ISMART4343C-EVB: + https://www.inventeksys.com/ismart4343-c-arduino-shield-wi-fi-2ghz-bluetooth-ble/ + +.. _ISMART4343C-EVB Users Manual: + https://www.inventeksys.com/wp-content/uploads/IoT-EVB-Users-Manual.pdf + +.. _inventek_eswifi: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/inventek_eswifi/inventek_eswifi.overlay + +.. _inventek_eswifi_arduino_uart: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/inventek_eswifi/inventek_eswifi_arduino_uart.overlay + +.. _inventek_eswifi_arduino_spi: + https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/shields/inventek_eswifi/inventek_eswifi_arduino_spi.overlay diff --git a/boards/shields/inventek_eswifi/doc/ismart4343c-evb-wiring.jpg b/boards/shields/inventek_eswifi/doc/ismart4343c-evb-wiring.jpg new file mode 100644 index 00000000000000..7996e09544ff24 Binary files /dev/null and b/boards/shields/inventek_eswifi/doc/ismart4343c-evb-wiring.jpg differ diff --git a/boards/shields/inventek_eswifi/doc/ismart4343c-evb.jpg b/boards/shields/inventek_eswifi/doc/ismart4343c-evb.jpg new file mode 100644 index 00000000000000..f225dc20980ede Binary files /dev/null and b/boards/shields/inventek_eswifi/doc/ismart4343c-evb.jpg differ diff --git a/boards/shields/inventek_eswifi/inventek_eswifi.overlay b/boards/shields/inventek_eswifi/inventek_eswifi.overlay new file mode 100644 index 00000000000000..a4eec46077b6de --- /dev/null +++ b/boards/shields/inventek_eswifi/inventek_eswifi.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2020 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This file is intentionally empty. Please refer to shield documentation for + * instructions how to use this shield. + */ diff --git a/boards/shields/inventek_eswifi/inventek_eswifi_arduino_spi.overlay b/boards/shields/inventek_eswifi/inventek_eswifi_arduino_spi.overlay new file mode 100644 index 00000000000000..fa5495d840c683 --- /dev/null +++ b/boards/shields/inventek_eswifi/inventek_eswifi_arduino_spi.overlay @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&arduino_spi { + status = "okay"; + + /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; + + wifi0: iwin@0 { + status = "okay"; + compatible = "inventek,eswifi"; + spi-max-frequency = <2000000>; + reg = <0>; + + /* D9 */ + data-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; + /* D7 */ + wakeup-gpios = <&arduino_header 13 GPIO_ACTIVE_HIGH>; + /* D6 */ + resetn-gpios = <&arduino_header 12 GPIO_ACTIVE_HIGH>; + /* D5 */ + boot0-gpios = <&arduino_header 11 GPIO_ACTIVE_HIGH>; + + label = "ESWIFI0"; + }; +}; diff --git a/boards/shields/inventek_eswifi/inventek_eswifi_arduino_uart.overlay b/boards/shields/inventek_eswifi/inventek_eswifi_arduino_uart.overlay new file mode 100644 index 00000000000000..2ea87c52e9ff69 --- /dev/null +++ b/boards/shields/inventek_eswifi/inventek_eswifi_arduino_uart.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&arduino_serial { + status = "okay"; + + wifi0: iwin { + status = "okay"; + compatible = "inventek,eswifi-uart"; + + /* D7 */ + wakeup-gpios = <&arduino_header 13 GPIO_ACTIVE_HIGH>; + /* D6 */ + resetn-gpios = <&arduino_header 12 GPIO_ACTIVE_HIGH>; + + label = "ESWIFI0"; + }; +}; diff --git a/boards/shields/link_board_eth/link_board_eth.overlay b/boards/shields/link_board_eth/link_board_eth.overlay index 90cb78db509e75..02941f174d34d2 100644 --- a/boards/shields/link_board_eth/link_board_eth.overlay +++ b/boards/shields/link_board_eth/link_board_eth.overlay @@ -6,7 +6,7 @@ &arduino_spi { status = "okay"; - cs-gpios = <&arduino_header 16 0>; /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ enc424j600@0 { compatible = "microchip,enc424j600"; diff --git a/boards/shields/mikroe_adc_click/boards/lpcxpresso55s16_ns.overlay b/boards/shields/mikroe_adc_click/boards/lpcxpresso55s16_ns.overlay new file mode 100644 index 00000000000000..4381d1f2c2935d --- /dev/null +++ b/boards/shields/mikroe_adc_click/boards/lpcxpresso55s16_ns.overlay @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &mcp3204; + +&mikrobus_spi { + status = "okay"; + + /* LPCXpresso55S16 uses SSEL1 for mikroBUS SPI */ + mcp3204: mcp3204@1 { + compatible = "microchip,mcp3204"; + reg = <0x1>; + spi-max-frequency = <100000>; + label = "MCP3204"; + #io-channel-cells = <1>; + }; +}; diff --git a/boards/shields/mikroe_adc_click/doc/index.rst b/boards/shields/mikroe_adc_click/doc/index.rst index 6dd3e20695c8a7..30d8346ecd358c 100644 --- a/boards/shields/mikroe_adc_click/doc/index.rst +++ b/boards/shields/mikroe_adc_click/doc/index.rst @@ -20,13 +20,9 @@ Requirements ************ This shield can only be used with a development board that provides a -configuration for Arduino connectors and defines a node alias for the +configuration for mikroBUS connectors and defines a node alias for the mikroBUS SPI interface (see :ref:`shields` for more details). -The mikroBUS connector pins on the ADC Click can either be connected -to the Arduino headers of the development board using jumper wires or -by using an `Arduino UNO Click Shield`_. - For more information about interfacing the MCP3204 and the ADC Click, see the following documentation: @@ -56,6 +52,3 @@ example: .. _ADC Click: https://www.mikroe.com/adc-click - -.. _Arduino UNO Click Shield: - https://www.mikroe.com/arduino-uno-click-shield diff --git a/boards/shields/mikroe_adc_click/mikroe_adc_click.overlay b/boards/shields/mikroe_adc_click/mikroe_adc_click.overlay index 938c8bd2d2584d..34a3a312a24d83 100644 --- a/boards/shields/mikroe_adc_click/mikroe_adc_click.overlay +++ b/boards/shields/mikroe_adc_click/mikroe_adc_click.overlay @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -&arduino_spi { +&mikrobus_spi { status = "okay"; mcp3204: mcp3204@0 { diff --git a/boards/shields/mikroe_eth_click/Kconfig.defconfig b/boards/shields/mikroe_eth_click/Kconfig.defconfig new file mode 100644 index 00000000000000..abcacd12cf3a96 --- /dev/null +++ b/boards/shields/mikroe_eth_click/Kconfig.defconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2020 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_MIKROE_ETH_CLICK + +if NETWORKING + +# ENC28J60 is L2 chip slave on SPI +config SPI + default y + +config NET_L2_ETHERNET + default y + +# ENC28J60 Ethernet Device +config ETH_ENC28J60 + default y + +config ETH_ENC28J60_0 + default y + +endif # NETWORKING + +endif # SHIELD_MIKROE_ETH_CLICK diff --git a/boards/shields/mikroe_eth_click/boards/lpcxpresso55s69_cpu0.overlay b/boards/shields/mikroe_eth_click/boards/lpcxpresso55s69_cpu0.overlay new file mode 100644 index 00000000000000..aff3b6ee342f20 --- /dev/null +++ b/boards/shields/mikroe_eth_click/boards/lpcxpresso55s69_cpu0.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ ð_click; + +&mikrobus_spi { + status = "okay"; + + /* LPCXpresso55xxx boards all use SSEL1. */ + eth_click: eth_click@1 { + compatible = "microchip,enc28j60"; + reg = <0x1>; + local-mac-address = [00 00 00 01 02 03]; + /* Errata B7/1 specifies min 8Mhz, 20MHz max according to RM */ + spi-max-frequency = <10000000>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; /* INT */ + label = "ETH_CLICK"; + }; +}; diff --git a/boards/shields/mikroe_eth_click/boards/lpcxpresso55s69_ns.overlay b/boards/shields/mikroe_eth_click/boards/lpcxpresso55s69_ns.overlay new file mode 100644 index 00000000000000..aff3b6ee342f20 --- /dev/null +++ b/boards/shields/mikroe_eth_click/boards/lpcxpresso55s69_ns.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ ð_click; + +&mikrobus_spi { + status = "okay"; + + /* LPCXpresso55xxx boards all use SSEL1. */ + eth_click: eth_click@1 { + compatible = "microchip,enc28j60"; + reg = <0x1>; + local-mac-address = [00 00 00 01 02 03]; + /* Errata B7/1 specifies min 8Mhz, 20MHz max according to RM */ + spi-max-frequency = <10000000>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; /* INT */ + label = "ETH_CLICK"; + }; +}; diff --git a/boards/shields/mikroe_eth_click/doc/index.rst b/boards/shields/mikroe_eth_click/doc/index.rst index 25291977198081..334e57fa714bb8 100644 --- a/boards/shields/mikroe_eth_click/doc/index.rst +++ b/boards/shields/mikroe_eth_click/doc/index.rst @@ -1,5 +1,8 @@ .. _mikroe_eth_click: +MikroElektronika ETH Click +########################## + Overview ******** diff --git a/boards/shields/mikroe_eth_click/mikroe_eth_click.conf b/boards/shields/mikroe_eth_click/mikroe_eth_click.conf deleted file mode 100644 index 2ec324354941f1..00000000000000 --- a/boards/shields/mikroe_eth_click/mikroe_eth_click.conf +++ /dev/null @@ -1,7 +0,0 @@ -# ENC28J60 is L2 chip slave on SPI -CONFIG_SPI=y -CONFIG_NET_L2_ETHERNET=y - -# ENC28J60 Ethernet Device -CONFIG_ETH_ENC28J60=y -CONFIG_ETH_ENC28J60_0=y diff --git a/boards/shields/mikroe_eth_click/mikroe_eth_click.overlay b/boards/shields/mikroe_eth_click/mikroe_eth_click.overlay index 0ffa02e81d50ec..28c1f0631b900f 100644 --- a/boards/shields/mikroe_eth_click/mikroe_eth_click.overlay +++ b/boards/shields/mikroe_eth_click/mikroe_eth_click.overlay @@ -4,15 +4,14 @@ &mikrobus_spi { status = "okay"; - cs-gpios = <&mikrobus_header 2 0>; /* CS */ - eth_click@0 { + eth_click: eth_click@0 { compatible = "microchip,enc28j60"; + reg = <0x0>; local-mac-address = [00 00 00 01 02 03]; /* Errata B7/1 specifies min 8Mhz, 20MHz max according to RM */ spi-max-frequency = <10000000>; int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; /* INT */ - label = "ETH_0"; - reg = <0>; + label = "ETH_CLICK"; }; }; diff --git a/boards/shields/ssd1306/Kconfig.defconfig b/boards/shields/ssd1306/Kconfig.defconfig index af832b2e29a6b6..03c0909c6ad87c 100644 --- a/boards/shields/ssd1306/Kconfig.defconfig +++ b/boards/shields/ssd1306/Kconfig.defconfig @@ -1,13 +1,24 @@ # Copyright (c) 2019 Linaro Limited # SPDX-License-Identifier: Apache-2.0 -if SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X32 || SHIELD_SH1106_128X64 +if SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X64_SPI || SHIELD_SSD1306_128X32 || SHIELD_SH1106_128X64 if DISPLAY +if SHIELD_SSD1306_128X64_SPI + +config SPI + default y + +endif # SHIELD_SSD1306_128X64_SPI + +if SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X32 || SHIELD_SH1106_128X64 + config I2C default y +endif # SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X32 || SHIELD_SH1106_128X64 + config SSD1306 default y @@ -20,10 +31,10 @@ if LVGL config LVGL_DISPLAY_DEV_NAME default "SSD1306" -config LVGL_HOR_RES +config LVGL_HOR_RES_MAX default 128 -config LVGL_VER_RES +config LVGL_VER_RES_MAX default 32 if SHIELD_SSD1306_128X32 default 64 @@ -45,4 +56,4 @@ endif # LVGL endif # DISPLAY -endif # SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X32 +endif # SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X64_SPI || SHIELD_SSD1306_128X32 || SHIELD_SH1106_128X64 diff --git a/boards/shields/ssd1306/Kconfig.shield b/boards/shields/ssd1306/Kconfig.shield index 0422c49a658988..5168a667345cf6 100644 --- a/boards/shields/ssd1306/Kconfig.shield +++ b/boards/shields/ssd1306/Kconfig.shield @@ -7,5 +7,8 @@ config SHIELD_SSD1306_128X32 config SHIELD_SSD1306_128X64 def_bool $(shields_list_contains,ssd1306_128x64) +config SHIELD_SSD1306_128X64_SPI + def_bool $(shields_list_contains,ssd1306_128x64_spi) + config SHIELD_SH1106_128X64 def_bool $(shields_list_contains,sh1106_128x64) diff --git a/boards/shields/ssd1306/ssd1306_128x64_spi.overlay b/boards/shields/ssd1306/ssd1306_128x64_spi.overlay new file mode 100644 index 00000000000000..c0a273ab632b9c --- /dev/null +++ b/boards/shields/ssd1306/ssd1306_128x64_spi.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 Marco Peter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&arduino_spi { + status = "okay"; + + ssd1306@0 { + compatible = "solomon,ssd1306fb"; + reg = <0x0>; + label = "SSD1306"; + spi-max-frequency = <10000000>; + width = <128>; + height = <64>; + segment-offset = <0>; + page-offset = <0>; + display-offset = <0>; + multiplex-ratio = <63>; + segment-remap; + com-invdir; + prechargep = <0x22>; + data_cmd-gpios = <&arduino_header 15 0>; + /* reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; */ + }; +}; diff --git a/boards/shields/st7789v_generic/Kconfig.defconfig b/boards/shields/st7789v_generic/Kconfig.defconfig index 4f7298bd132e4e..67f5189290d864 100644 --- a/boards/shields/st7789v_generic/Kconfig.defconfig +++ b/boards/shields/st7789v_generic/Kconfig.defconfig @@ -21,11 +21,11 @@ if LVGL config LVGL_DISPLAY_DEV_NAME default "ST7789V" -config LVGL_HOR_RES +config LVGL_HOR_RES_MAX default 320 if SHIELD_ST7789V_TL019FQV01 default 240 if SHIELD_ST7789V_WAVESHARE_240X240 -config LVGL_VER_RES +config LVGL_VER_RES_MAX default 170 if SHIELD_ST7789V_TL019FQV01 default 240 if SHIELD_ST7789V_WAVESHARE_240X240 @@ -33,6 +33,13 @@ config LVGL_BITS_PER_PIXEL default 24 if SHIELD_ST7789V_TL019FQV01 default 16 if SHIELD_ST7789V_WAVESHARE_240X240 +choice LVGL_COLOR_DEPTH + default LVGL_COLOR_DEPTH_16 if SHIELD_ST7789V_WAVESHARE_240X240 +endchoice + +config LVGL_COLOR_16_SWAP + default y if SHIELD_ST7789V_WAVESHARE_240X240 + endif # LVGL endif # DISPLAY diff --git a/boards/shields/st7789v_generic/st7789v_tl019fqv01.overlay b/boards/shields/st7789v_generic/st7789v_tl019fqv01.overlay index 997c9dbb0d916a..32d144e90b40f4 100644 --- a/boards/shields/st7789v_generic/st7789v_tl019fqv01.overlay +++ b/boards/shields/st7789v_generic/st7789v_tl019fqv01.overlay @@ -6,7 +6,7 @@ &arduino_spi { status = "okay"; - cs-gpios = <&arduino_header 16 0>; /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ st7789v@0 { compatible = "sitronix,st7789v"; diff --git a/boards/shields/st7789v_generic/st7789v_waveshare_240x240.overlay b/boards/shields/st7789v_generic/st7789v_waveshare_240x240.overlay index 756471070ddb3b..0e66cc987f3f96 100644 --- a/boards/shields/st7789v_generic/st7789v_waveshare_240x240.overlay +++ b/boards/shields/st7789v_generic/st7789v_waveshare_240x240.overlay @@ -7,7 +7,7 @@ &arduino_spi { status = "okay"; - cs-gpios = <&arduino_header 16 0>; /* D10 */ + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ st7789v@0 { compatible = "sitronix,st7789v"; diff --git a/boards/shields/v2c_daplink/Kconfig.defconfig b/boards/shields/v2c_daplink/Kconfig.defconfig new file mode 100644 index 00000000000000..e57b9736918392 --- /dev/null +++ b/boards/shields/v2c_daplink/Kconfig.defconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2020 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_V2C_DAPLINK || SHIELD_V2C_DAPLINK_CFG + +if BOARD_ARTY_A7_ARM_DESIGNSTART_M1 || BOARD_ARTY_A7_ARM_DESIGNSTART_M3 + +if DISK_ACCESS + +config SPI + default y + +config DISK_ACCESS_SDHC + default y + +config DISK_ACCESS_SPI_SDHC + default y + +endif # DISK_ACCESS + +endif # BOARD_ARTY_A7_ARM_DESIGNSTART_M1 || BOARD_ARTY_A7_ARM_DESIGNSTART_M3 + +endif # SHIELD_V2C_DAPLINK || SHIELD_V2C_DAPLINK_CFG diff --git a/boards/shields/v2c_daplink/Kconfig.shield b/boards/shields/v2c_daplink/Kconfig.shield new file mode 100644 index 00000000000000..7c11fa527bccd2 --- /dev/null +++ b/boards/shields/v2c_daplink/Kconfig.shield @@ -0,0 +1,8 @@ +# Copyright (c) 2020 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_V2C_DAPLINK + def_bool $(shields_list_contains,v2c_daplink) + +config SHIELD_V2C_DAPLINK_CFG + def_bool $(shields_list_contains,v2c_daplink_cfg) diff --git a/boards/shields/v2c_daplink/doc/index.rst b/boards/shields/v2c_daplink/doc/index.rst new file mode 100644 index 00000000000000..481d452be045a5 --- /dev/null +++ b/boards/shields/v2c_daplink/doc/index.rst @@ -0,0 +1,52 @@ +.. _v2c_daplink_shield: + +ARM V2C-DAPLink for DesignStart FPGA +#################################### + +Overview +******** + +The `ARM V2C-DAPLink for DesignStart FPGA`_ shield can be used to provide +DAPLink debug access to the ARM DesignStart FPGA reference designs implemented +on the :ref:`arty`. + +.. figure:: ./v2c_daplink.png + :width: 600px + :align: center + :alt: V2C-DAPLink + + V2C-DAPLink (Credit: ARM Ltd.) + +In addition to DAPLink debug access, the V2C-DAPLink shield provides the +following hardware features: + +- QSPI NOR flash +- Micro-SD card slot + +Programming +*********** + +When using the V2C-DAPLink shield with the ``Cfg`` jumper (``J2``) open, the CPU +will boot from ITCM and flashing can be performed automatically. The console is +routed to USB connector ``J10`` on the :ref:`arty`. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: arty_a7_arm_designstart_m1 + :shield: v2c_daplink + :goals: flash + +When using the V2C-DAPLink shield with the ``Cfg`` jumper (``J2``) closed, the +CPU will boot from the V2C-DAPLink QSPI NOR flash. The console is routed to USB +connector ``J1`` on the V2C-DAPLink. Flashing needs to be done +manually by copying the resulting ``zephyr/zephyr.bin`` file to the USB mass +storage device provided by the V2C-DAPLink shield: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: arty_a7_arm_designstart_m1 + :shield: v2c_daplink_cfg + :goals: build + +.. _ARM V2C-DAPLink for DesignStart FPGA: + https://developer.arm.com/tools-and-software/development-boards/designstart-daplink-board diff --git a/boards/shields/v2c_daplink/doc/v2c_daplink.png b/boards/shields/v2c_daplink/doc/v2c_daplink.png new file mode 100644 index 00000000000000..ea497f7e07aa76 Binary files /dev/null and b/boards/shields/v2c_daplink/doc/v2c_daplink.png differ diff --git a/boards/shields/v2c_daplink/v2c_daplink.overlay b/boards/shields/v2c_daplink/v2c_daplink.overlay new file mode 100644 index 00000000000000..d38709161b4570 --- /dev/null +++ b/boards/shields/v2c_daplink/v2c_daplink.overlay @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&daplink_gpio0 { + status = "okay"; +}; + +&daplink_qspi_mux { + status = "okay"; +}; + +&flash0 { + /* + * Disable the on-board flash until the jedec,spi-nor driver supports + * multiple instances. + */ + status = "disabled"; +}; + +&daplink_quad_spi0 { + status = "okay"; + + daplink_flash0: flash@0 { + compatible = "spansion,s25fl128s", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <80000000>; + size = ; + jedec-id = [01 20 18]; + label = "DAPLINK_FLASH_0"; + }; +}; + +&daplink_single_spi0 { + status = "okay"; + + sdhc0: sdhc@0 { + compatible = "zephyr,mmc-spi-slot"; + reg = <0>; + label = "SDHC_0"; + spi-max-frequency = <25000000>; + }; +}; diff --git a/boards/shields/v2c_daplink/v2c_daplink_cfg.overlay b/boards/shields/v2c_daplink/v2c_daplink_cfg.overlay new file mode 100644 index 00000000000000..1790607545e29e --- /dev/null +++ b/boards/shields/v2c_daplink/v2c_daplink_cfg.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &itcm; + +/ { + chosen { + zephyr,flash = &daplink_flash0; + }; + + soc { + daplink_flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 DT_SIZE_M(1)>; + }; + + itcm: memory@10000000 { + compatible = "arm,itcm"; + reg = <0x10000000 DT_SIZE_K(64)>; + }; + }; +}; + +&daplink_single_spi0 { + status = "okay"; + + sdhc0: sdhc@0 { + compatible = "zephyr,mmc-spi-slot"; + reg = <0>; + label = "SDHC_0"; + spi-max-frequency = <25000000>; + }; +}; diff --git a/boards/shields/waveshare_epaper/Kconfig.defconfig b/boards/shields/waveshare_epaper/Kconfig.defconfig index 5b828255574028..2f58aecf380671 100644 --- a/boards/shields/waveshare_epaper/Kconfig.defconfig +++ b/boards/shields/waveshare_epaper/Kconfig.defconfig @@ -5,7 +5,8 @@ # SPDX-License-Identifier: Apache-2.0 # -if SHIELD_WAVESHARE_EPAPER_GDEH029A1 || SHIELD_WAVESHARE_EPAPER_GDEH0213B1 || SHIELD_WAVESHARE_EPAPER_GDEH0213B72 || SHIELD_WAVESHARE_EPAPER_GDEW075T7 +if SHIELD_WAVESHARE_EPAPER_GDEH029A1 || SHIELD_WAVESHARE_EPAPER_GDEH0213B1 || SHIELD_WAVESHARE_EPAPER_GDEH0213B72 || SHIELD_WAVESHARE_EPAPER_GDEW075T7 || SHIELD_WAVESHARE_EPAPER_GDEH0154A07 + if DISPLAY @@ -16,6 +17,7 @@ config SSD16XX default y if SHIELD_WAVESHARE_EPAPER_GDEH029A1 default y if SHIELD_WAVESHARE_EPAPER_GDEH0213B1 default y if SHIELD_WAVESHARE_EPAPER_GDEH0213B72 + default y if SHIELD_WAVESHARE_EPAPER_GDEH0154A07 config GD7965 default y if SHIELD_WAVESHARE_EPAPER_GDEW075T7 @@ -26,23 +28,26 @@ config LVGL_DISPLAY_DEV_NAME default "GD7965" if SHIELD_WAVESHARE_EPAPER_GDEW075T7 default "SSD16XX" -config LVGL_HOR_RES +config LVGL_HOR_RES_MAX default 296 if SHIELD_WAVESHARE_EPAPER_GDEH029A1 default 250 if SHIELD_WAVESHARE_EPAPER_GDEH0213B1 default 250 if SHIELD_WAVESHARE_EPAPER_GDEH0213B72 default 800 if SHIELD_WAVESHARE_EPAPER_GDEW075T7 + default 200 if SHIELD_WAVESHARE_EPAPER_GDEH0154A07 -config LVGL_VER_RES +config LVGL_VER_RES_MAX default 128 if SHIELD_WAVESHARE_EPAPER_GDEH029A1 default 120 if SHIELD_WAVESHARE_EPAPER_GDEH0213B1 default 120 if SHIELD_WAVESHARE_EPAPER_GDEH0213B72 default 480 if SHIELD_WAVESHARE_EPAPER_GDEW075T7 + default 200 if SHIELD_WAVESHARE_EPAPER_GDEH0154A07 config LVGL_VDB_SIZE default 16 if SHIELD_WAVESHARE_EPAPER_GDEW075T7 default 16 config LVGL_DPI + default 188 if SHIELD_WAVESHARE_EPAPER_GDEH0154A07 default 130 choice LVGL_COLOR_DEPTH @@ -56,4 +61,11 @@ endif # LVGL endif # DISPLAY +if DISK_ACCESS_SDHC + +config DISK_ACCESS_SPI_SDHC + default y + +endif # DISK_ACCESS_SDHC + endif # SHIELD_WAVESHARE_EPAPER_GDEH02 diff --git a/boards/shields/waveshare_epaper/Kconfig.shield b/boards/shields/waveshare_epaper/Kconfig.shield index 4b10dab3529f52..fe4b0d073cf71b 100644 --- a/boards/shields/waveshare_epaper/Kconfig.shield +++ b/boards/shields/waveshare_epaper/Kconfig.shield @@ -12,3 +12,6 @@ config SHIELD_WAVESHARE_EPAPER_GDEH0213B72 config SHIELD_WAVESHARE_EPAPER_GDEW075T7 def_bool $(shields_list_contains,waveshare_epaper_gdew075t7) + +config SHIELD_WAVESHARE_EPAPER_GDEH0154A07 + def_bool $(shields_list_contains,waveshare_epaper_gdeh0154a07) diff --git a/boards/shields/waveshare_epaper/doc/index.rst b/boards/shields/waveshare_epaper/doc/index.rst index 355d5c17e88e3d..dc01837a52309d 100644 --- a/boards/shields/waveshare_epaper/doc/index.rst +++ b/boards/shields/waveshare_epaper/doc/index.rst @@ -59,6 +59,9 @@ Current supported displays | Good Display | WFT0583CZ61 | GD7965 / | waveshare_epaper_gdew075t7 | | GDEW075T7 | | gd7965 | | +--------------+-----------------+--------------+------------------------------+ +| Good Display | HINK-E0154A07 | SSD1681 / | waveshare_epaper_gdeh0154a07 | +| GDEH0154D67 | | ssd16xx | | ++--------------+-----------------+--------------+------------------------------+ Requirements diff --git a/boards/shields/waveshare_epaper/waveshare_epaper_common.dtsi b/boards/shields/waveshare_epaper/waveshare_epaper_common.dtsi new file mode 100644 index 00000000000000..dc4e4fa2be582f --- /dev/null +++ b/boards/shields/waveshare_epaper/waveshare_epaper_common.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>, /* D10 */ + <&arduino_header 12 GPIO_ACTIVE_LOW>; /* D04 */ + + sdhc0: sdhc@1 { + compatible = "zephyr,mmc-spi-slot"; + reg = <1>; + status = "okay"; + label = "SDHC0"; + spi-max-frequency = <24000000>; + }; +}; diff --git a/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0154a07.overlay b/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0154a07.overlay new file mode 100644 index 00000000000000..3702522a3ae189 --- /dev/null +++ b/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0154a07.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019, PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "waveshare_epaper_common.dtsi" + +&arduino_spi { + ssd16xxfb@0 { + compatible = "solomon,ssd16xxfb", "gooddisplay,gdeh0154a07"; + label = "SSD16XX"; + spi-max-frequency = <4000000>; + reg = <0>; + width = <200>; + height = <200>; + pp-width-bits = <8>; + pp-height-bits = <16>; + dc-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */ + reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ + busy-gpios = <&arduino_header 13 GPIO_ACTIVE_HIGH>; /* D7 */ + gdv = [00]; + sdv = [41 a8 32]; + vcom = <0x00>; + border-waveform = <0x05>; + tssv = <0x80>; + }; +}; diff --git a/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0213b1.overlay b/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0213b1.overlay index a46157a32b4f59..66d40014f6f10b 100644 --- a/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0213b1.overlay +++ b/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0213b1.overlay @@ -4,10 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -&arduino_spi { - status = "okay"; - cs-gpios = <&arduino_header 16 0>; /* D10 */ +#include "waveshare_epaper_common.dtsi" +&arduino_spi { ssd16xxfb@0 { compatible = "solomon,ssd16xxfb", "gooddisplay,gdeh0213b1"; label = "SSD16XX"; diff --git a/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0213b72.overlay b/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0213b72.overlay index 1b8bf378c271b7..b1f915f920d987 100644 --- a/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0213b72.overlay +++ b/boards/shields/waveshare_epaper/waveshare_epaper_gdeh0213b72.overlay @@ -4,10 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -&arduino_spi { - status = "okay"; - cs-gpios = <&arduino_header 16 0>; /* D10 */ +#include "waveshare_epaper_common.dtsi" +&arduino_spi { ssd16xxfb@0 { compatible = "solomon,ssd16xxfb", "gooddisplay,gdeh0213b72"; label = "SSD16XX"; diff --git a/boards/shields/waveshare_epaper/waveshare_epaper_gdeh029a1.overlay b/boards/shields/waveshare_epaper/waveshare_epaper_gdeh029a1.overlay index 224286366622bd..b56a4d780a061d 100644 --- a/boards/shields/waveshare_epaper/waveshare_epaper_gdeh029a1.overlay +++ b/boards/shields/waveshare_epaper/waveshare_epaper_gdeh029a1.overlay @@ -4,10 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -&arduino_spi { - status = "okay"; - cs-gpios = <&arduino_header 16 0>; /* D10 */ +#include "waveshare_epaper_common.dtsi" +&arduino_spi { ssd16xxfb@0 { compatible = "solomon,ssd16xxfb", "gooddisplay,gdeh029a1"; label = "SSD16XX"; diff --git a/boards/shields/waveshare_epaper/waveshare_epaper_gdew075t7.overlay b/boards/shields/waveshare_epaper/waveshare_epaper_gdew075t7.overlay index 52cc0e334f1e39..da3351f2658474 100644 --- a/boards/shields/waveshare_epaper/waveshare_epaper_gdew075t7.overlay +++ b/boards/shields/waveshare_epaper/waveshare_epaper_gdew075t7.overlay @@ -4,10 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -&arduino_spi { - status = "okay"; - cs-gpios = <&arduino_header 16 0>; /* D10 */ +#include "waveshare_epaper_common.dtsi" +&arduino_spi { gd7965@0 { compatible = "gooddisplay,gd7965"; label = "GD7965"; diff --git a/boards/shields/wnc_m14a2a/boards/nrf52840dk_nrf52840.defconfig b/boards/shields/wnc_m14a2a/boards/nrf52840dk_nrf52840.defconfig index 94d6f245337741..78a93bb755c362 100644 --- a/boards/shields/wnc_m14a2a/boards/nrf52840dk_nrf52840.defconfig +++ b/boards/shields/wnc_m14a2a/boards/nrf52840dk_nrf52840.defconfig @@ -6,7 +6,4 @@ if BOARD_NRF52840DK_NRF52840 config GPIO_NRF_P1 default y -config UART_1_NRF_FLOW_CONTROL - default y - endif # BOARD_NRF52840DK_NRF52840 diff --git a/boards/shields/x_nucleo_iks01a2/doc/index.rst b/boards/shields/x_nucleo_iks01a2/doc/index.rst index 95fa64664f2bb8..4cf36ca5f759cb 100644 --- a/boards/shields/x_nucleo_iks01a2/doc/index.rst +++ b/boards/shields/x_nucleo_iks01a2/doc/index.rst @@ -44,13 +44,55 @@ X-NUCLEO-IKS01A2 provides the following key features: More information about X-NUCLEO-IKS01A2 can be found here: - `X-NUCLEO-IKS01A2 databrief`_ +Hardware Configuration +********************** + +X-NUCLEO-IKS01A2 board connects the various devices on two separate I2C bus: + +- LSM6DL is on I2C2 +- LSM303AGR, LPS22HB, HTS221 are on I2C1 + +X-NUCLEO-IKS01A2 board can be configured in two different ways: Mode 1 and Mode 2 + + +Mode 1: Standard Mode +===================== + +In standard I2C mode the two buses are connected together. As a consequence, all devices on the shield +reside on the same I2C bus and are accessible from the main board thru I2C bus. + +The jumper configuration to activate this mode is: + +- JP7 => 1-2, 3-4 (I2C1 = I2C2, I2Cx=GND) +- JP8 => 1-2, 3-4 (I2C1 = I2C2, I2Cx=GND) + + +Mode 2: SensorHub Mode +====================== + +In SensorHub mode LSM6DSL is connected to I2C2 and is accessible from the main board. +All the other devices are connected to LSM6DSL master thru I2C1. + +The jumper configuration to activate this mode is: + +- JP7 => 2-3 (I2C1 = I2Cx) +- JP8 => 2-3 (I2C1 = I2Cx) + +More information about X-NUCLEO-IKS01A2 configuration modes can be found in the +`X-NUCLEO-IKS01A2 databrief`_ + Programming *********** -Using the ``x-nucleo-iks01a2`` shield is quite similar to use the shield -``x-nucleo-iks01a1`` for which the :ref:`x-nucleo-iks01a1-sample` application -is provided (see :ref:`shields` for more details). +Two samples are provided as examples for ``x-nucleo-iks01a2`` shield: + +- :ref:`x-nucleo-iks01a2-std-sample` application, to be used when the shield is configured + in Standard Mode +- :ref:`x-nucleo-iks01a2-shub-sample` application, to be used when the shield is configured + in SensorHub Mode + +See also :ref:`shields` for more details. References ********** diff --git a/boards/shields/x_nucleo_iks01a2/x_nucleo_iks01a2_shub.overlay b/boards/shields/x_nucleo_iks01a2/x_nucleo_iks01a2_shub.overlay new file mode 100644 index 00000000000000..c4a5d2e104bd7d --- /dev/null +++ b/boards/shields/x_nucleo_iks01a2/x_nucleo_iks01a2_shub.overlay @@ -0,0 +1,15 @@ +/* + * + * Copyright (c) 2020 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&arduino_i2c { + lsm6dsl@6b { + compatible = "st,lsm6dsl"; + reg = <0x6b>; + label = "LSM6DSL"; + irq-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 */ + }; +}; diff --git a/boards/shields/x_nucleo_iks01a3/boards/x_nucleo_iks01a3/stm32mp157c_dk2.overlay b/boards/shields/x_nucleo_iks01a3/boards/x_nucleo_iks01a3/stm32mp157c_dk2.overlay index 7f017658f792e2..a7f9a09336ca14 100644 --- a/boards/shields/x_nucleo_iks01a3/boards/x_nucleo_iks01a3/stm32mp157c_dk2.overlay +++ b/boards/shields/x_nucleo_iks01a3/boards/x_nucleo_iks01a3/stm32mp157c_dk2.overlay @@ -13,4 +13,12 @@ lis2dw12@19 { /delete-property/ irq-gpios; /* A3 */ }; + + lis2mdl@1e { + /delete-property/ irq-gpios; /* A3 */ + }; + + lsm6dso@6b { + /delete-property/ irq-gpios; /* A3 */ + }; }; diff --git a/boards/shields/x_nucleo_iks01a3/boards/x_nucleo_iks01a3_shub/stm32mp157c_dk2.overlay b/boards/shields/x_nucleo_iks01a3/boards/x_nucleo_iks01a3_shub/stm32mp157c_dk2.overlay index 7f017658f792e2..ccbe4d38705f73 100644 --- a/boards/shields/x_nucleo_iks01a3/boards/x_nucleo_iks01a3_shub/stm32mp157c_dk2.overlay +++ b/boards/shields/x_nucleo_iks01a3/boards/x_nucleo_iks01a3_shub/stm32mp157c_dk2.overlay @@ -13,4 +13,8 @@ lis2dw12@19 { /delete-property/ irq-gpios; /* A3 */ }; + + lsm6dso@6b { + /delete-property/ irq-gpios; /* A3 */ + }; }; diff --git a/boards/sparc/generic_leon3/Kconfig.board b/boards/sparc/generic_leon3/Kconfig.board new file mode 100644 index 00000000000000..9ba65374a3cd8c --- /dev/null +++ b/boards/sparc/generic_leon3/Kconfig.board @@ -0,0 +1,7 @@ +# Copyright (c) 2019-2020 Cobham Gaisler AB +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_GENERIC_LEON3 + bool "Generic LEON3 system" + depends on SOC_LEON3 diff --git a/boards/sparc/generic_leon3/Kconfig.defconfig b/boards/sparc/generic_leon3/Kconfig.defconfig new file mode 100644 index 00000000000000..79ade4b0e989bf --- /dev/null +++ b/boards/sparc/generic_leon3/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2019-2020 Cobham Gaisler AB +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_GENERIC_LEON3 + +config BOARD + default "generic_leon3" + +config SPARC_CASA + default n + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 50000000 + +endif diff --git a/boards/sparc/generic_leon3/board.cmake b/boards/sparc/generic_leon3/board.cmake new file mode 100644 index 00000000000000..0f2e9350f4ba9b --- /dev/null +++ b/boards/sparc/generic_leon3/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(EMU_PLATFORM tsim) + +find_program(TSIM tsim-leon3) + +set(TSIM_SYS) diff --git a/boards/sparc/generic_leon3/doc/index.rst b/boards/sparc/generic_leon3/doc/index.rst new file mode 100644 index 00000000000000..9ab9c897ce8665 --- /dev/null +++ b/boards/sparc/generic_leon3/doc/index.rst @@ -0,0 +1,124 @@ +.. _generic_leon3: + +Generic LEON3 +############# + +Overview +******** + +This board configuration is designed to work with LEON3 processor template +designs available in the GRLIB GPL distribution. +It can also be used with the evaluation version of the TSIM3 LEON3 simulator. + +Hardware +******** + +The board configuration is compatible with most GRLIB LEON3 FPGA template +designs such as the Digilent Arty A7, Terasic DE0-Nano and Microsemi +M2GL-EVAL-KIT. + +Programming and Debugging +************************* + +Building +======== + +Applications for the ``generic_leon3`` board configuration can be built as usual +(see :ref:`build_an_application`). +In order to build the application for ``generic_leon3``, set the ``BOARD`` variable +to ``generic_leon3``. + +Running on hardware +=================== + +Connect with GRMON, then load and run the application. The example below uses +the Terasic DE2-115 Cyclone IV FPGA board. + +.. code-block:: console + + $ grmon -altjtag -u + GRMON debug monitor v3.2.8 eval version + + Copyright (C) 2020 Cobham Gaisler - All rights reserved. + For latest updates, go to http://www.gaisler.com/ + Comments or bug-reports to support@gaisler.com + + JTAG chain (1): EP3C120/EP4CE115 + GRLIB build version: 4250 + Detected frequency: 50.0 MHz + + Component Vendor + LEON3 SPARC V8 Processor Cobham Gaisler + AHB Debug UART Cobham Gaisler + JTAG Debug Link Cobham Gaisler + GR Ethernet MAC Cobham Gaisler + GRDMAC DMA Controller Cobham Gaisler + LEON2 Memory Controller European Space Agency + AHB/APB Bridge Cobham Gaisler + LEON3 Debug Support Unit Cobham Gaisler + Generic UART Cobham Gaisler + Multi-processor Interrupt Ctrl. Cobham Gaisler + Modular Timer Unit Cobham Gaisler + General Purpose I/O port Cobham Gaisler + SPI Controller Cobham Gaisler + AHB Status Register Cobham Gaisler + + Use command 'info sys' to print a detailed report of attached cores + + grmon3> load zephyr/zephyr.elf + 40000000 text 16.2kB / 16.2kB [===============>] 100% + 400040A8 initlevel 40B [===============>] 100% + 400040D0 rodata 484B [===============>] 100% + 400042B4 datas 20B [===============>] 100% + 400042C8 sw_isr_table 256B [===============>] 100% + 400043C8 devices 36B [===============>] 100% + Total size: 16.98kB (1.91Mbit/s) + Entry point 0x40000000 + Image zephyr/zephyr.elf loaded + + grmon3> run + *** Booting Zephyr OS build zephyr-v2.4.0-30-ga124c31ec4cf *** + Hello World! generic_leon3 + + +Running in simulation +===================== + +The same application binary can be simulated with the TSIM3 LEON3 simulator. + +.. code-block:: console + + $ tsim-leon3 + TSIM3 LEON3 SPARC simulator, version 3.0.2 (evaluation version) + + Copyright (C) 2020, Cobham Gaisler - all rights reserved. + This software may only be used with a valid license. + For latest updates, go to https://www.gaisler.com/ + Comments or bug-reports to support@gaisler.com + + Number of CPUs: 2 + system frequency: 50.000 MHz + icache: 1 * 4 KiB, 16 bytes/line (4 KiB total) + dcache: 1 * 4 KiB, 16 bytes/line (4 KiB total) + Allocated 4096 KiB SRAM memory, in 1 bank at 0x40000000 + Allocated 32 MiB SDRAM memory, in 1 bank at 0x60000000 + Allocated 2048 KiB ROM memory at 0x00000000 + + tsim> load zephyr/zephyr.elf + section: text, addr: 0x40000000, size 16552 bytes + section: initlevel, addr: 0x400040a8, size 40 bytes + section: rodata, addr: 0x400040d0, size 484 bytes + section: datas, addr: 0x400042b4, size 20 bytes + section: sw_isr_table, addr: 0x400042c8, size 256 bytes + section: devices, addr: 0x400043c8, size 36 bytes + Read 436 symbols + tsim> run + Initializing and starting from 0x40000000 + *** Booting Zephyr OS build zephyr-v2.4.0-30-ga124c31ec4cf *** + Hello World! generic_leon3 + +References +********** +* `GRLIB IP Library and LEON3, GPL version `_ +* `TSIM3 LEON3 simulator `_ +* `GRMON3 debug monitor `_ diff --git a/boards/sparc/generic_leon3/generic_leon3.dts b/boards/sparc/generic_leon3/generic_leon3.dts new file mode 100644 index 00000000000000..ffdc45795a6d70 --- /dev/null +++ b/boards/sparc/generic_leon3/generic_leon3.dts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + chosen { + zephyr,console = &uart0; + zephyr,sram = &ram0; + }; +}; + +&ram0 { + reg = <0x40000000 0x00400000>; +}; + +&uart0 { + status = "okay"; +}; diff --git a/boards/sparc/generic_leon3/generic_leon3.yaml b/boards/sparc/generic_leon3/generic_leon3.yaml new file mode 100644 index 00000000000000..b3d72d7d6c2289 --- /dev/null +++ b/boards/sparc/generic_leon3/generic_leon3.yaml @@ -0,0 +1,12 @@ +identifier: generic_leon3 +name: Generic LEON3 system +type: mcu +simulation: tsim +arch: sparc +ram: 4096 +flash: 2048 +toolchain: + - zephyr + - xtools +supported: + - netif diff --git a/boards/sparc/generic_leon3/generic_leon3_defconfig b/boards/sparc/generic_leon3/generic_leon3_defconfig new file mode 100644 index 00000000000000..446ae9e9b309f7 --- /dev/null +++ b/boards/sparc/generic_leon3/generic_leon3_defconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_LEON3=y +CONFIG_BOARD_GENERIC_LEON3=y +CONFIG_CONSOLE=y +CONFIG_PRINTK=y +CONFIG_SERIAL=y +CONFIG_UART_APBUART=y +CONFIG_UART_CONSOLE=y +CONFIG_LEON_GPTIMER=y diff --git a/boards/sparc/gr716a_mini/Kconfig.board b/boards/sparc/gr716a_mini/Kconfig.board new file mode 100644 index 00000000000000..e200d6160c0cc0 --- /dev/null +++ b/boards/sparc/gr716a_mini/Kconfig.board @@ -0,0 +1,7 @@ +# Copyright (c) 2019-2020 Cobham Gaisler AB +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_GR716A_MINI + bool "GR716-MINI Development Board" + depends on SOC_GR716A diff --git a/boards/sparc/gr716a_mini/Kconfig.defconfig b/boards/sparc/gr716a_mini/Kconfig.defconfig new file mode 100644 index 00000000000000..2106481c95eed6 --- /dev/null +++ b/boards/sparc/gr716a_mini/Kconfig.defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2019-2020 Cobham Gaisler AB +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_GR716A_MINI + +config BOARD + default "gr716a_mini" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 20000000 + +endif diff --git a/boards/sparc/gr716a_mini/board.cmake b/boards/sparc/gr716a_mini/board.cmake new file mode 100644 index 00000000000000..51298861987bf3 --- /dev/null +++ b/boards/sparc/gr716a_mini/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(EMU_PLATFORM tsim) + +find_program(TSIM tsim-leon3) + +set(TSIM_SYS -freq 20 -gr716) diff --git a/boards/sparc/gr716a_mini/doc/gr716a_mini.jpg b/boards/sparc/gr716a_mini/doc/gr716a_mini.jpg new file mode 100644 index 00000000000000..c14ffe92e93f61 Binary files /dev/null and b/boards/sparc/gr716a_mini/doc/gr716a_mini.jpg differ diff --git a/boards/sparc/gr716a_mini/doc/index.rst b/boards/sparc/gr716a_mini/doc/index.rst new file mode 100644 index 00000000000000..87fd92993f9e3a --- /dev/null +++ b/boards/sparc/gr716a_mini/doc/index.rst @@ -0,0 +1,216 @@ +.. _gr716a_mini: + +GR716-MINI Development Board +############################ + +Overview +******** + +The GR716-MINI development board provides: + +* GR716 microcontroller +* SPI Flash PROM, 32 MiB +* SRAM, 2 MiB +* FTDI USB interface for UART debug link (AHBUART) and application UART + (APBUART). +* 4x MMCX connectors (2 ADC, 2 DAC) +* Miniature 80 pin mezzanine connector (bottom side) + +.. figure:: gr716a_mini.jpg + :width: 543px + :align: center + :alt: GR716-MINI Development Board + + GR716-MINI Development Board (Credit: Cobham Gaisler AB) + +Hardware +******** + +Console Output +============== + +By default, the kernel is configured to send console output to the +first APBUART peripheral (apbuart0). The UART debug forwarding setting, +if enabled in GRMON, is preserved. + +Programming and Debugging +************************* + +Building +======== + +Applications for the ``gr716a_mini`` board configuration can be built +as usual (see :ref:`build_an_application`). +In order to build the application for ``gr716a_mini``, set the ``BOARD`` +variable to ``gr716a_mini``. + +The application is linked to the on-chip tightly coupled memory by +default. + +Running on hardware +=================== + +Connect with GRMON, then load and run the application. + +.. code-block:: console + + $ grmon -u -cginit 0x00010000 -uart /dev/ttyUSB0 + GRMON debug monitor v3.2.8 + + Copyright (C) 2020 Cobham Gaisler - All rights reserved. + For latest updates, go to http://www.gaisler.com/ + Comments or bug-reports to support@gaisler.com + + Device ID: 0x716 + GRLIB build version: 4204 + Detected system: GR716 + Detected frequency: 20.0 MHz + + Component Vendor + AHB-to-AHB Bridge Cobham Gaisler + MIL-STD-1553B Interface Cobham Gaisler + GRSPW2 SpaceWire Serial Link Cobham Gaisler + SPI to AHB Bridge Cobham Gaisler + I2C to AHB Bridge Cobham Gaisler + CAN Controller with DMA Cobham Gaisler + CAN Controller with DMA Cobham Gaisler + AHB Debug UART Cobham Gaisler + AHB-to-AHB Bridge Cobham Gaisler + PacketWire Receiver with DMA Cobham Gaisler + PacketWire Transmitter with DMA Cobham Gaisler + GRDMAC DMA Controller Cobham Gaisler + GRDMAC DMA Controller Cobham Gaisler + GRDMAC DMA Controller Cobham Gaisler + GRDMAC DMA Controller Cobham Gaisler + Dual-port SPI Slave Cobham Gaisler + LEON3FT SPARC V8 Processor Cobham Gaisler + AHB-to-AHB Bridge Cobham Gaisler + AHB Memory Scrubber Cobham Gaisler + AHB-to-AHB Bridge Cobham Gaisler + AHB Debug UART Cobham Gaisler + Dual-port AHB(/CPU) On-Chip RAM Cobham Gaisler + Dual-port AHB(/CPU) On-Chip RAM Cobham Gaisler + Generic AHB ROM Cobham Gaisler + Memory controller with EDAC Cobham Gaisler + SPI Memory Controller Cobham Gaisler + SPI Memory Controller Cobham Gaisler + AHB/APB Bridge Cobham Gaisler + AHB/APB Bridge Cobham Gaisler + AHB/APB Bridge Cobham Gaisler + AHB/APB Bridge Cobham Gaisler + Memory controller with EDAC Cobham Gaisler + LEON3 Debug Support Unit Cobham Gaisler + AHB/APB Bridge Cobham Gaisler + AMBA Trace Buffer Cobham Gaisler + Multi-processor Interrupt Ctrl. Cobham Gaisler + Modular Timer Unit Cobham Gaisler + Modular Timer Unit Cobham Gaisler + GR716 AMBA Protection unit Cobham Gaisler + Clock gating unit Cobham Gaisler + Clock gating unit Cobham Gaisler + General Purpose Register Cobham Gaisler + LEON3 Statistics Unit Cobham Gaisler + AHB Status Register Cobham Gaisler + CCSDS TDP / SpaceWire I/F Cobham Gaisler + General Purpose Register Bank Cobham Gaisler + General Purpose Register Cobham Gaisler + GR716 AMBA Protection unit Cobham Gaisler + GR716 Bandgap Cobham Gaisler + GR716 Brownout detector Cobham Gaisler + GR716 Phase-locked loop Cobham Gaisler + Generic UART Cobham Gaisler + Generic UART Cobham Gaisler + Generic UART Cobham Gaisler + Generic UART Cobham Gaisler + Generic UART Cobham Gaisler + Generic UART Cobham Gaisler + AHB Status Register Cobham Gaisler + ADC / DAC Interface Cobham Gaisler + SPI Controller Cobham Gaisler + SPI Controller Cobham Gaisler + PWM generator Cobham Gaisler + General Purpose I/O port Cobham Gaisler + General Purpose I/O port Cobham Gaisler + AMBA Wrapper for OC I2C-master Cobham Gaisler + AMBA Wrapper for OC I2C-master Cobham Gaisler + GR716 Analog-to-Digital Conv Cobham Gaisler + GR716 Analog-to-Digital Conv Cobham Gaisler + GR716 Analog-to-Digital Conv Cobham Gaisler + GR716 Analog-to-Digital Conv Cobham Gaisler + GR716 Analog-to-Digital Conv Cobham Gaisler + GR716 Analog-to-Digital Conv Cobham Gaisler + GR716 Analog-to-Digital Conv Cobham Gaisler + GR716 Analog-to-Digital Conv Cobham Gaisler + GR716 Digital-to-Analog Conv Cobham Gaisler + GR716 Digital-to-Analog Conv Cobham Gaisler + GR716 Digital-to-Analog Conv Cobham Gaisler + GR716 Digital-to-Analog Conv Cobham Gaisler + I2C Slave Cobham Gaisler + I2C Slave Cobham Gaisler + PWM generator Cobham Gaisler + LEON3 Statistics Unit Cobham Gaisler + General Purpose Register Cobham Gaisler + + Use command 'info sys' to print a detailed report of attached cores + + grmon3> load zephyr/zephyr.elf + 31000000 text 16.2kB / 16.2kB [===============>] 100% + 300040A8 initlevel 40B [===============>] 100% + 300040D0 rodata 484B [===============>] 100% + 300042B4 datas 20B [===============>] 100% + 300042C8 sw_isr_table 256B [===============>] 100% + 300043C8 devices 36B [===============>] 100% + Total size: 16.98kB (1.91Mbit/s) + Entry point 0x31000000 + Image zephyr/zephyr.elf loaded + + grmon3> run + *** Booting Zephyr OS build zephyr-v2.4.0-788-gc82a8736a65e *** + Hello World! gr716a_mini + + +Running in simulation +===================== + +The same application binary can be simulated with the TSIM3 LEON3 simulator. + +.. code-block:: console + + $ tsim-leon3 -freq 20 -gr716 + + TSIM3 LEON3 SPARC simulator, version v3.0.2 + + Copyright (C) 2020, Cobham Gaisler - all rights reserved. + For latest updates, go to https://www.gaisler.com/ + Comments or bug-reports to support@gaisler.com + + Number of CPUs: 1 + register windows: 31 + system frequency: 20.000 MHz + using 64-bit time + Allocated 128 KiB local instruction RAM memory at 0x31000000 + Allocated 64 KiB local data RAM memory at 0x30000000 + Allocated 4096 KiB SRAM memory, in 1 bank at 0x40000000 + Allocated 2048 KiB ROM memory at 0x01000000 + Allocated 16384 KiB SPIM ROM memory at 0x02000000 + Allocated 16384 KiB SPIM ROM memory at 0x04000000 + + tsim> load zephyr/zephyr.elf + section: text, addr: 0x31000000, size 16956 bytes + section: initlevel, addr: 0x30000000, size 40 bytes + section: rodata, addr: 0x30000028, size 484 bytes + section: datas, addr: 0x3000020c, size 20 bytes + section: sw_isr_table, addr: 0x30000220, size 256 bytes + section: devices, addr: 0x30000320, size 36 bytes + Read 438 symbols + tsim> run + Initializing and starting from 0x31000000 + *** Booting Zephyr OS build zephyr-v2.4.0-788-gc82a8736a65e *** + Hello World! gr716a_mini + + +References +********** +* `GR716 Evaluation and Development Boards `_ +* `TSIM3 LEON3 simulator `_ +* `GRMON3 debug monitor `_ diff --git a/boards/sparc/gr716a_mini/gr716a_mini.dts b/boards/sparc/gr716a_mini/gr716a_mini.dts new file mode 100644 index 00000000000000..3f3db2a7ba6b86 --- /dev/null +++ b/boards/sparc/gr716a_mini/gr716a_mini.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2019-2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + chosen { + zephyr,console = &uart0; + zephyr,sram = &dram; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/boards/sparc/gr716a_mini/gr716a_mini.yaml b/boards/sparc/gr716a_mini/gr716a_mini.yaml new file mode 100644 index 00000000000000..f1483349fb180a --- /dev/null +++ b/boards/sparc/gr716a_mini/gr716a_mini.yaml @@ -0,0 +1,10 @@ +identifier: gr716a_mini +name: GR716-MINI Development Board +type: mcu +simulation: tsim +arch: sparc +toolchain: + - zephyr + - xtools +supported: + - netif diff --git a/boards/sparc/gr716a_mini/gr716a_mini_defconfig b/boards/sparc/gr716a_mini/gr716a_mini_defconfig new file mode 100644 index 00000000000000..8fa136f6416397 --- /dev/null +++ b/boards/sparc/gr716a_mini/gr716a_mini_defconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_GR716A=y +CONFIG_BOARD_GR716A_MINI=y +CONFIG_CONSOLE=y +CONFIG_PRINTK=y +CONFIG_SERIAL=y +CONFIG_UART_APBUART=y +CONFIG_UART_CONSOLE=y +CONFIG_LEON_GPTIMER=y diff --git a/boards/sparc/index.rst b/boards/sparc/index.rst new file mode 100644 index 00000000000000..ef090183645d08 --- /dev/null +++ b/boards/sparc/index.rst @@ -0,0 +1,10 @@ +.. _boards-sparc: + +SPARC Boards +############ + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/sparc/qemu_leon3/Kconfig.board b/boards/sparc/qemu_leon3/Kconfig.board new file mode 100644 index 00000000000000..6ba0234a17a452 --- /dev/null +++ b/boards/sparc/qemu_leon3/Kconfig.board @@ -0,0 +1,9 @@ +# Copyright (c) 2019-2020 Cobham Gaisler AB +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_QEMU_LEON3 + bool "QEMU LEON3 target" + depends on SOC_LEON3 + select QEMU_TARGET + select CPU_HAS_FPU diff --git a/boards/sparc/qemu_leon3/Kconfig.defconfig b/boards/sparc/qemu_leon3/Kconfig.defconfig new file mode 100644 index 00000000000000..f76d0bf9262fc1 --- /dev/null +++ b/boards/sparc/qemu_leon3/Kconfig.defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2019-2020 Cobham Gaisler AB +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_QEMU_LEON3 + +config BOARD + default "qemu_leon3" + +endif diff --git a/boards/sparc/qemu_leon3/board.cmake b/boards/sparc/qemu_leon3/board.cmake new file mode 100644 index 00000000000000..2b8bbea4be7a26 --- /dev/null +++ b/boards/sparc/qemu_leon3/board.cmake @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(EMU_PLATFORM qemu) + +set(QEMU_binary_suffix sparc) +set(QEMU_CPU_TYPE_${ARCH} leon3) + +set(QEMU_FLAGS_${ARCH} + -nographic + -machine leon3_generic + -icount auto + ) +board_set_debugger_ifnset(qemu) diff --git a/boards/sparc/qemu_leon3/doc/index.rst b/boards/sparc/qemu_leon3/doc/index.rst new file mode 100644 index 00000000000000..f64b08adce7e13 --- /dev/null +++ b/boards/sparc/qemu_leon3/doc/index.rst @@ -0,0 +1,60 @@ +.. _qemu_leon3: + +LEON3 Emulation (QEMU) +###################### + +Overview +******** + +The LEON3 QEMU board configuration is used to emulate the LEON3 processor. + +.. figure:: qemu_leon3.png + :width: 600px + :align: center + :alt: Qemu + + Qemu (Credit: qemu.org) + +Programming and Debugging +************************* + +Applications for the ``qemu_leon3`` board configuration can be built and run in +the usual way for emulated boards (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +While this board is emulated and you can't "flash" it, you can use this +configuration to run basic Zephyr applications and kernel tests in the QEMU +emulated environment. For example, with the :ref:`synchronization_sample`: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: qemu_leon3 + :goals: run + +This will build an image with the synchronization sample app, boot it using +QEMU, and display the following console output: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v2.4.0-27-g7b37fdd5303b *** + threadA: Hello World from qemu_leon3! + threadB: Hello World from qemu_leon3! + threadA: Hello World from qemu_leon3! + threadB: Hello World from qemu_leon3! + threadA: Hello World from qemu_leon3! + threadB: Hello World from qemu_leon3! + threadA: Hello World from qemu_leon3! + threadB: Hello World from qemu_leon3! + threadA: Hello World from qemu_leon3! + threadB: Hello World from qemu_leon3! + +Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`. + +Debugging +========= + +Refer to the detailed overview about :ref:`application_debugging`. diff --git a/boards/sparc/qemu_leon3/doc/qemu_leon3.png b/boards/sparc/qemu_leon3/doc/qemu_leon3.png new file mode 100644 index 00000000000000..9dc06ed20e3aaa Binary files /dev/null and b/boards/sparc/qemu_leon3/doc/qemu_leon3.png differ diff --git a/boards/sparc/qemu_leon3/qemu_leon3.dts b/boards/sparc/qemu_leon3/qemu_leon3.dts new file mode 100644 index 00000000000000..0d86eb149a149c --- /dev/null +++ b/boards/sparc/qemu_leon3/qemu_leon3.dts @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 Cobham Gaisler AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + chosen { + zephyr,console = &uart0; + zephyr,sram = &ram0; + }; +}; + +&timer0 { + interrupts = <6>; +}; + +&uart0 { + interrupts = <3>; + status = "okay"; +}; + +&ram0 { + reg = <0x40000000 0x40000000>; +}; diff --git a/boards/sparc/qemu_leon3/qemu_leon3.yaml b/boards/sparc/qemu_leon3/qemu_leon3.yaml new file mode 100644 index 00000000000000..4b0b344975b25d --- /dev/null +++ b/boards/sparc/qemu_leon3/qemu_leon3.yaml @@ -0,0 +1,14 @@ +identifier: qemu_leon3 +name: QEMU Emulation for LEON3 +type: qemu +simulation: qemu +arch: sparc +ram: 1048576 +flash: 524288 +toolchain: + - zephyr + - xtools +supported: + - netif +testing: + default: true diff --git a/boards/sparc/qemu_leon3/qemu_leon3_defconfig b/boards/sparc/qemu_leon3/qemu_leon3_defconfig new file mode 100644 index 00000000000000..8c232b7de88c95 --- /dev/null +++ b/boards/sparc/qemu_leon3/qemu_leon3_defconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_LEON3=y +CONFIG_BOARD_QEMU_LEON3=y +CONFIG_CONSOLE=y +CONFIG_PRINTK=y +CONFIG_SERIAL=y +CONFIG_UART_APBUART=y +CONFIG_UART_CONSOLE=y +CONFIG_LEON_GPTIMER=y +CONFIG_QEMU_ICOUNT_SHIFT=6 diff --git a/boards/x86/acrn/acrn.dts b/boards/x86/acrn/acrn.dts index 671ad6b948958f..b5c3c06cee7504 100644 --- a/boards/x86/acrn/acrn.dts +++ b/boards/x86/acrn/acrn.dts @@ -8,7 +8,7 @@ #include -#define DT_SRAM_SIZE DT_SIZE_K(8192) +#define DT_DRAM_SIZE DT_SIZE_K(8192) #include @@ -22,7 +22,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &dram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; }; diff --git a/boards/x86/acrn/acrn_defconfig b/boards/x86/acrn/acrn_defconfig index f3967609bfa033..d7f8ff81dc12b6 100644 --- a/boards/x86/acrn/acrn_defconfig +++ b/boards/x86/acrn/acrn_defconfig @@ -13,3 +13,4 @@ CONFIG_UART_CONSOLE=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=25000000 CONFIG_BUILD_OUTPUT_BIN=y CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN=n +CONFIG_X86_MMU_PAGE_POOL_PAGES=29 diff --git a/boards/x86/common/scripts/build_grub.sh b/boards/x86/common/scripts/build_grub.sh index 0a66529e41a9d2..bfb42ce0932a8c 100755 --- a/boards/x86/common/scripts/build_grub.sh +++ b/boards/x86/common/scripts/build_grub.sh @@ -16,13 +16,15 @@ fi TARGET_ARCH=$1 +export PYTHON=python3 + prepare() { if [[ ! -d ./src ]]; then git clone http://git.savannah.gnu.org/r/grub.git src fi pushd src - git checkout grub-2.04-rc1-17-g8e8723a6b + git checkout grub-2.04 git clean -fdx popd } @@ -32,7 +34,7 @@ build() { ./bootstrap ./autogen.sh - ./configure --with-platform=efi --target=${TARGET_ARCH} + ./configure --with-platform=efi --target=${TARGET_ARCH} --disable-werror make -j${JOBS} diff --git a/boards/x86/ehl_crb/CMakeLists.txt b/boards/x86/ehl_crb/CMakeLists.txt new file mode 100644 index 00000000000000..46c19fd9d2bec6 --- /dev/null +++ b/boards/x86/ehl_crb/CMakeLists.txt @@ -0,0 +1,9 @@ +# Create an EFI image +if(CONFIG_BOARD_EHL_CRB) +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/arch/x86/zefi/zefi.py + -f ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.elf + $<$:--verbose> + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} +) +endif() diff --git a/boards/x86/ehl_crb/Kconfig.board b/boards/x86/ehl_crb/Kconfig.board new file mode 100644 index 00000000000000..ba93e2715b3c4a --- /dev/null +++ b/boards/x86/ehl_crb/Kconfig.board @@ -0,0 +1,7 @@ +# Copyright (c) 2020 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_EHL_CRB + bool "Elkhart Lake CRB" + depends on SOC_ELKHART_LAKE + select X86_64 diff --git a/boards/x86/ehl_crb/Kconfig.defconfig b/boards/x86/ehl_crb/Kconfig.defconfig new file mode 100644 index 00000000000000..0bae0e040fafc6 --- /dev/null +++ b/boards/x86/ehl_crb/Kconfig.defconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2020 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_EHL_CRB + +config BOARD + default "ehl_crb" + +config BUILD_OUTPUT_STRIPPED + default y + +config MP_NUM_CPUS + default 2 + +config X86_MMU_PAGE_POOL_PAGES + default 3072 if X86_MMU + +endif # BOARD_EHL_CRB diff --git a/boards/xtensa/up_squared_adsp/board.cmake b/boards/x86/ehl_crb/board.cmake similarity index 100% rename from boards/xtensa/up_squared_adsp/board.cmake rename to boards/x86/ehl_crb/board.cmake diff --git a/boards/x86/ehl_crb/doc/index.rst b/boards/x86/ehl_crb/doc/index.rst new file mode 100644 index 00000000000000..d59214fee5089d --- /dev/null +++ b/boards/x86/ehl_crb/doc/index.rst @@ -0,0 +1,309 @@ +.. _ehl_crb: + +Elkhart Lake CRB +################ + +Overview +******** +Elkhart Lake Reference Board (EHL CRB) is an example implementation of a +compact single board computer with high performance for IoT edge devices. + +This board configuration enables kernel support for the `EHL`_ board. + +.. note:: + This board configuration works on the variant of `EHL`_ + boards containing Intel |reg| Atom |trade| SoC. + +Hardware +******** + +General information about the board can be found at the `EHL`_ website. + +.. include:: ../../../../soc/x86/elkhart_lake/doc/supported_features.txt + + +Connections and IOs +=================== + +Refer to the `EHL`_ website for more information. + +Programming and Debugging +************************* +Use the following procedures for booting an image on a EHL CRB board. + +.. contents:: + :depth: 1 + :local: + :backlinks: top + +Creating a GRUB2 Boot Loader Image from a Linux Host +==================================================== + +If you are having problems running an application using the preinstalled +copy of GRUB, follow these steps to test on supported boards using a custom GRUB. + +#. Install the requirements to build GRUB on your host machine. + + On Ubuntu, type: + + .. code-block:: console + + $ sudo apt-get install bison autoconf libopts25-dev flex automake \ + pkg-config gettext autopoint + + On Fedora, type: + + .. code-block:: console + + $ sudo dnf install gnu-efi bison m4 autoconf help2man flex \ + automake texinfo gettext-devel + +#. Clone and build the GRUB repository using the script in Zephyr tree, type: + + .. code-block:: console + + $ cd $ZEPHYR_BASE + $ ./boards/x86/common/scripts/build_grub.sh x86_64 + +#. Find the binary at + :file:`$ZEPHYR_BASE/boards/x86/common/scripts/grub/bin/grub_x86_64.efi`. + +Build Zephyr application +======================== + +#. Build a Zephyr application; for instance, to build the ``hello_world`` + application on Elkhart Lake CRB: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: ehl_crb + :goals: build + + .. note:: + + A stripped project image file named :file:`zephyr.strip` is automatically + created in the build directory after the application is built. This image + has removed debug information from the :file:`zephyr.elf` file. + +Preparing the Boot Device +========================= + +Prepare a USB flash drive to boot the Zephyr application image on +an Elkhart Lake CRB board. + +#. Format the USB flash drive as FAT32. + + On Windows, open ``File Explorer``, and right-click on the USB flash drive. + Select ``Format...``. Make sure in ``File System``, ``FAT32`` is selected. + Click on the ``Format`` button and wait for it to finish. + + On Linux, graphical utilities such as ``gparted`` can be used to format + the USB flash drive as FAT32. Alternatively, under terminal, find out + the corresponding device node for the USB flash drive (for example, + ``/dev/sdd``). Execute the following command: + + .. code-block:: console + + $ mkfs.vfat -F 32 + + .. important:: + Make sure the device node is the actual device node for + the USB flash drive. Or else you may erase other storage devices + on your system, and will render the system unusable afterwards. + +#. Create the following directories + + :file:`efi` + + :file:`efi/boot` + + :file:`kernel` + +#. Copy the kernel file :file:`zephyr/zephyr.strip` to the :file:`$USB/kernel` folder. + +#. Copy your built version of GRUB to :file:`$USB/efi/boot/bootx64.efi` + +#. Create :file:`$USB/efi/boot/grub.cfg` containing the following: + + .. code-block:: console + + set default=0 + set timeout=10 + + menuentry "Zephyr Kernel" { + multiboot /kernel/zephyr.strip + } + +Booting the Elkhart Lake CRB Board +================================== + +Boot the Elkhart Lake CRB board from the boot device using GRUB2 via USB flash drive. + +#. Insert the prepared boot device (USB flash drive) into the Elkhart Lake CRB board. + +#. Connect the board to the host system using the serial cable and + configure your host system to watch for serial data. See + `EHL`_ website for more information. + + .. note:: + On Windows, PuTTY has an option to set up configuration for + serial data. Use a baud rate of 115200. + +#. Power on the Elkhart Lake CRB board. + +#. When the following output appears, press :kbd:`F7`: + + .. code-block:: console + + Press or to enter setup. + +#. From the menu that appears, select the menu entry that describes + that particular type of USB flash drive. + + GRUB2 starts and a menu shows entries for the items you added + to the file :file:`grub.cfg`. + +#. Select the image you want to boot and press :guilabel:`Enter`. + + When the boot process completes, you have finished booting the + Zephyr application image. + + .. note:: + You can safely ignore this message if it appears: + + .. code-block:: console + + WARNING: no console will be available to OS + + +Booting the Elkhart Lake CRB Board over network +=============================================== + +Build Zephyr image +------------------ + +#. Follow `Build Zephyr application`_ steps to build Zephyr image. + +Prepare Linux host +------------------ + +#. Follow `Creating a GRUB2 Boot Loader Image from a Linux Host`_ steps + to create grub binary. + +#. Install DHCP, TFTP servers. For example ``dnsmasq`` + + .. code-block:: console + + $ sudo apt-get install dnsmasq + +#. Configure DHCP server. Configuration for ``dnsmasq`` is below: + + .. code-block:: console + + # Only listen to this interface + interface=eno2 + dhcp-range=10.1.1.20,10.1.1.30,12h + +#. Configure TFTP server. + + .. code-block:: console + + # tftp + enable-tftp + tftp-root=/srv/tftp + dhcp-boot=grub_x86_64.efi + + ``grub_x86_64.efi`` is a grub binary created above. + +#. Create the following directories inside TFTP root :file:`/srv/tftp` + + .. code-block:: console + + $ sudo mkdir -p /srv/tftp/EFI/BOOT + $ sudo mkdir -p /srv/tftp/kernel + +#. Copy the Zephyr image :file:`zephyr/zephyr.strip` to the + :file:`/srv/tftp/kernel` folder. + + .. code-block:: console + + $ sudo cp zephyr/zephyr.strip /srv/tftp/kernel + +#. Copy your built version of GRUB to :file:`/srv/tftp/grub_x86_64.efi` + +#. Create :file:`/srv/tftp/EFI/BOOT/grub.cfg` containing the following: + + .. code-block:: console + + set default=0 + set timeout=10 + + menuentry "Zephyr Kernel" { + multiboot /kernel/zephyr.strip + } + +#. TFTP root should be looking like: + + .. code-block:: console + + $ tree /srv/tftp + /srv/tftp + ├── EFI + │   └── BOOT + │   └── grub.cfg + ├── grub_x86_64.efi + └── kernel + └── zephyr.strip + +#. Restart ``dnsmasq`` service: + + .. code-block:: console + + $ sudo systemctl restart dnsmasq.service + +Prepare Elkhart Lake CRB board for network boot +----------------------------------------------- + +#. Enable PXE network from BIOS settings. + + .. code-block:: console + + Advanced -> Network Stack Configuration -> Enable Network Stack -> Enable Ipv4 PXE Support + +#. Make network boot as the first boot option. + + .. code-block:: console + + Boot -> Boot Option #1 : [Network] + +Booting Elkhart Lake CRB +------------------------ + +#. Connect the board to the host system using the serial cable and + configure your host system to watch for serial data. + +#. Power on the Elkhart Lake CRB board. + +#. Verify that the board got an IP address: + + .. code-block:: console + + $ journalctl -f -u dnsmasq + dnsmasq-dhcp[5386]: DHCPDISCOVER(eno2) 00:07:32:52:25:88 + dnsmasq-dhcp[5386]: DHCPOFFER(eno2) 10.1.1.28 00:07:32:52:25:88 + dnsmasq-dhcp[5386]: DHCPREQUEST(eno2) 10.1.1.28 00:07:32:52:25:88 + dnsmasq-dhcp[5386]: DHCPACK(eno2) 10.1.1.28 00:07:32:52:25:88 + +#. Verify that network booting is started: + + .. code-block:: console + + $ journalctl -f -u dnsmasq + dnsmasq-tftp[5386]: sent /srv/tftp/grub_x86_64.efi to 10.1.1.28 + dnsmasq-tftp[5386]: sent /srv/tftp/EFI/BOOT/grub.cfg to 10.1.1.28 + dnsmasq-tftp[5386]: sent /srv/tftp/kernel/zephyr.strip to 10.1.1.28 + +#. When the boot process completes, you have finished booting the + Zephyr application image. + +.. _EHL: https://www.intel.com/content/www/us/en/products/docs/processors/embedded/enhanced-for-iot-platform-brief.html diff --git a/boards/x86/ehl_crb/ehl_crb.dts b/boards/x86/ehl_crb/ehl_crb.dts new file mode 100644 index 00000000000000..77657fc08bfbad --- /dev/null +++ b/boards/x86/ehl_crb/ehl_crb.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +#define DT_DRAM_SIZE DT_SIZE_M(2048) + +#include + +/ { + model = "ehl_crb"; + compatible = "intel,elkhart_lake"; + + chosen { + zephyr,sram = &dram0; + zephyr,console = &uart2; + zephyr,shell-uart = &uart2; + zephyr,bt-uart = &uart1; + zephyr,uart-pipe = &uart1; + zephyr,bt-mon-uart = &uart1; + }; +}; diff --git a/boards/x86/ehl_crb/ehl_crb.yaml b/boards/x86/ehl_crb/ehl_crb.yaml new file mode 100644 index 00000000000000..32ac58782ae7a8 --- /dev/null +++ b/boards/x86/ehl_crb/ehl_crb.yaml @@ -0,0 +1,11 @@ +identifier: ehl_crb +name: Elkhart Lake CRB +type: mcu +arch: x86 +toolchain: + - zephyr +ram: 2048 +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/x86/ehl_crb/ehl_crb_defconfig b/boards/x86/ehl_crb/ehl_crb_defconfig new file mode 100644 index 00000000000000..def86d2703cb07 --- /dev/null +++ b/boards/x86/ehl_crb/ehl_crb_defconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_ELKHART_LAKE=y +CONFIG_BOARD_EHL_CRB=y +CONFIG_PIC_DISABLE=y +CONFIG_LOAPIC=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_CONSOLE=y +CONFIG_X2APIC=y +CONFIG_SMP=y +CONFIG_X86_MMU_PAGE_POOL_PAGES=3092 diff --git a/boards/x86/gpmrb/Kconfig.board b/boards/x86/gpmrb/Kconfig.board deleted file mode 100644 index 1b6a5e30049726..00000000000000 --- a/boards/x86/gpmrb/Kconfig.board +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2018 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_GPMRB - bool "Gordon Peak MRB" - depends on SOC_APOLLO_LAKE diff --git a/boards/x86/gpmrb/Kconfig.defconfig b/boards/x86/gpmrb/Kconfig.defconfig deleted file mode 100644 index 3ff14f91a1f51c..00000000000000 --- a/boards/x86/gpmrb/Kconfig.defconfig +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2019 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_GPMRB - -config MULTIBOOT - default n - -config BOARD - default "gpmrb" - -config BUILD_OUTPUT_STRIPPED - default y - -endif # BOARD_GPMRB diff --git a/boards/x86/gpmrb/doc/img/gpmrb.jpg b/boards/x86/gpmrb/doc/img/gpmrb.jpg deleted file mode 100644 index 89393d46934e79..00000000000000 Binary files a/boards/x86/gpmrb/doc/img/gpmrb.jpg and /dev/null differ diff --git a/boards/x86/gpmrb/doc/index.rst b/boards/x86/gpmrb/doc/index.rst deleted file mode 100644 index 9f5f6a04bc545a..00000000000000 --- a/boards/x86/gpmrb/doc/index.rst +++ /dev/null @@ -1,131 +0,0 @@ -.. _gpmrb: - -Gordon Peak MRB -############### - -Overview -******** - -The Intel Gordon Peak Module Reference Board (GP MRB) is used in -the automotive industry for the development of in-vehicle applications -such as heads-up displays and entertainment systems. - -.. figure:: img/gpmrb.jpg - :width: 500px - :align: center - :alt: Gordon Peak MRB - - Gordon Peak MRB - -Hardware -******** - -.. include:: ../../../../soc/x86/apollo_lake/doc/supported_features.txt - -Building and Running Zephyr -*************************** - -Use the following procedure to boot a Zephyr application on the Gordon Peak -MRB. - -Build Zephyr Application -======================== - -Build a Zephyr application; for instance, to build the ``hello_world`` -application for the GP MRB: - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: gpmrb - :goals: build - -This will create a standard ELF binary application file named -:file:`zephyr.elf`, and the same binary with debugging information -removed named :file:`zephyr.strip`. Because of the limited firmware -flash area on board, we'll use the smaller, stripped version. - -Move the stripped application to your home directory for use -in the next steps: - -.. code-block:: console - - $ cp zephyr/zephyr.strip ~ - -Get the Leaf Hill Firmware Files -================================ - -The Slim Bootloader (see the next step) requires binary firmware images -specific to the GP MRB: in this instance, the "Leaf Hill" firmware. -This can be downloaded from Intel: - -.. code-block:: console - - $ cd - $ wget https://firmware.intel.com/sites/default/files/leafhill-0.70-firmwareimages.zip - $ unzip leafhill-0.70-firmwareimages.zip - -There will now be two files named :file:`LEAFHILD.X64.0070.D01.1805070344.bin` -and :file:`LEAFHILD.X64.0070.R01.1805070352.bin` or similar in your home -directory, which are the debug (``D``) and release (``R``) versions of the -binary packages, respectively. Make note of the release (:file:`*R01*`) -file name for the next step. - -Build Slim Bootloader -===================== - -Zephyr runs as a direct payload of the Slim Bootloader (SBL). For more -complete information on SBL, including comprehensive build instructions, -see the `Slim Bootloader `_ site. - -.. code-block:: console - - $ cd - $ git clone https://github.com/slimbootloader/slimbootloader.git - $ cd slimbootloader - $ python BuildLoader.py clean - $ python BuildLoader.py build apl -p ~/zephyr.strip - -Now that the SBL has been built with the Zephyr application as the direct -payload, we need to "stitch" together SBL with the board firmware package. -Be sure to replace the release filename with the one noted in the previous -step: - -.. code-block:: console - - $ python Platform/ApollolakeBoardPkg/Script/StitchLoader.py \ - -i ~/LEAFHILD.X64.0070.R01.1805070352.bin \ - -s Outputs/apl/Stitch_Components.zip \ - -o ~/sbl.bin - -Now the file :file:`sbl.bin` in your home directory contains a firmware -image with SBL and the Zephyr application, ready to flash to the GP MRB. - -Flash the Image -=============== - -Connect the IOC to the GP MRB and connect the USB cable to your development -machine. Then, using the Intel Platform Flash tools supplied with your -board, flash the firmware: - -.. code-block:: console - - $ sudo /opt/intel/platformflashtool/bin/ias-spi-programmer --write ~/sbl.bin - -.. note:: - - Refer to the instructions with the IOC and/or GP MRB for further - information on flashing the firmware. - -Launch Zephyr -============= - -Connect to UART 2 on the GP MRB and press the "ignition" button. After -initialization messages, you will see the Zephyr banner: - -.. code-block:: console - - ***** Booting Zephyr OS v1.14.0-rc3-1254-g2a086e4c13ef ***** - Hello World! gpmrb - - -You are running a Zephyr application on your Gordon Peak MRB. diff --git a/boards/x86/gpmrb/gpmrb.dts b/boards/x86/gpmrb/gpmrb.dts deleted file mode 100644 index 16809acffe0b0a..00000000000000 --- a/boards/x86/gpmrb/gpmrb.dts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2019 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; - -#include - -#define DT_SRAM_SIZE DT_SIZE_M(2048) - -#include - -/ { - model = "gpmrb"; - compatible = "intel,apollo_lake"; - - chosen { - zephyr,sram = &sram0; - zephyr,console = &uart2; - zephyr,shell-uart = &uart2; - zephyr,bt-uart = &uart1; - zephyr,uart-pipe = &uart1; - zephyr,bt-mon-uart = &uart1; - }; -}; - -&uart0 { interrupts = <4 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; }; -&uart1 { interrupts = <5 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; }; -&uart2 { interrupts = <6 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; }; -&uart3 { interrupts = <7 IRQ_TYPE_LOWEST_LEVEL_LOW 3>; }; diff --git a/boards/x86/gpmrb/gpmrb.yaml b/boards/x86/gpmrb/gpmrb.yaml deleted file mode 100644 index 8894dde424e5f2..00000000000000 --- a/boards/x86/gpmrb/gpmrb.yaml +++ /dev/null @@ -1,11 +0,0 @@ -identifier: gpmrb -name: Gordon Peak MRB -type: mcu -arch: x86 -toolchain: - - zephyr -ram: 256 -testing: - ignore_tags: - - net - - bluetooth diff --git a/boards/x86/gpmrb/gpmrb_defconfig b/boards/x86/gpmrb/gpmrb_defconfig deleted file mode 100644 index 80456030039b26..00000000000000 --- a/boards/x86/gpmrb/gpmrb_defconfig +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2019 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_SOC_APOLLO_LAKE=y -CONFIG_BOARD_GPMRB=y -CONFIG_PIC_DISABLE=y -CONFIG_LOAPIC=y -CONFIG_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_UART_NS16550=y -CONFIG_UART_CONSOLE=y -CONFIG_I2C=y diff --git a/boards/x86/minnowboard/Kconfig.defconfig b/boards/x86/minnowboard/Kconfig.defconfig index 3f13b9f752e0d0..06e54af6941893 100644 --- a/boards/x86/minnowboard/Kconfig.defconfig +++ b/boards/x86/minnowboard/Kconfig.defconfig @@ -9,6 +9,6 @@ config BUILD_OUTPUT_STRIPPED default y config X86_MMU_PAGE_POOL_PAGES - default 3072 if X86_MMU + default 3086 if X86_MMU endif # BOARD_MINNOWBOARD diff --git a/boards/x86/minnowboard/minnowboard.dts b/boards/x86/minnowboard/minnowboard.dts index 531a17197c6fde..54d3b29a05ed9a 100644 --- a/boards/x86/minnowboard/minnowboard.dts +++ b/boards/x86/minnowboard/minnowboard.dts @@ -4,7 +4,7 @@ #include -#define DT_SRAM_SIZE DT_SIZE_M(2048) +#define DT_DRAM_SIZE DT_SIZE_M(2048) #include @@ -18,7 +18,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &dram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,bt-uart = &uart1; diff --git a/boards/x86/qemu_x86/board.cmake b/boards/x86/qemu_x86/board.cmake index 25c7bbca2c8912..7e7a43987b6b48 100644 --- a/boards/x86/qemu_x86/board.cmake +++ b/boards/x86/qemu_x86/board.cmake @@ -9,11 +9,14 @@ endif() if(CONFIG_X86_64) set(QEMU_binary_suffix x86_64) set(QEMU_CPU_TYPE_${ARCH} qemu64,+x2apic) + if("${CONFIG_MP_NUM_CPUS}" STREQUAL "1") + # icount works with 1 CPU so we can enable it here. + # FIXME: once this works across configs, remove this line and set + # CONFIG_QEMU_ICOUNT_SHIFT in defconfig instead. + list(APPEND QEMU_EXTRA_FLAGS -icount shift=5,align=off,sleep=off -rtc clock=vm) + endif() else() set(QEMU_CPU_TYPE_${ARCH} qemu32,+nx,+pae) -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=5,align=off,sleep=off -rtc clock=vm) -endif() endif() set(QEMU_FLAGS_${ARCH} diff --git a/boards/x86/qemu_x86/qemu_x86.dts b/boards/x86/qemu_x86/qemu_x86.dts index 7a998d1c9932b3..03cfdab115b576 100644 --- a/boards/x86/qemu_x86/qemu_x86.dts +++ b/boards/x86/qemu_x86/qemu_x86.dts @@ -4,7 +4,9 @@ #include -#define DT_SRAM_SIZE DT_SIZE_K(4096) +#ifndef DT_DRAM_SIZE +#define DT_DRAM_SIZE DT_SIZE_K(4096) +#endif #define DT_FLASH_SIZE DT_SIZE_K(4096) #include @@ -25,7 +27,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &dram0; zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; @@ -54,6 +56,7 @@ #address-cells = <1>; #size-cells = <1>; + erase-value = <0xff>; flash_sim0: flash_sim@0 { compatible = "soc-nv-flash"; @@ -87,10 +90,7 @@ }; &flash_sim0 { - /* - * For more information, see: - * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions - */ + partitions { compatible = "fixed-partitions"; #address-cells = <1>; diff --git a/boards/x86/qemu_x86/qemu_x86.yaml b/boards/x86/qemu_x86/qemu_x86.yaml index aa559284595452..5c9d3cca1ea979 100644 --- a/boards/x86/qemu_x86/qemu_x86.yaml +++ b/boards/x86/qemu_x86/qemu_x86.yaml @@ -6,6 +6,7 @@ arch: x86 toolchain: - zephyr - xtools + - llvm supported: - pci - nvs diff --git a/boards/x86/qemu_x86/qemu_x86_64_defconfig b/boards/x86/qemu_x86/qemu_x86_64_defconfig index c0a9ce6b5e60b4..85dda2cb7a19f7 100644 --- a/boards/x86/qemu_x86/qemu_x86_64_defconfig +++ b/boards/x86/qemu_x86/qemu_x86_64_defconfig @@ -16,3 +16,5 @@ CONFIG_SMP=y CONFIG_MP_NUM_CPUS=2 CONFIG_X86_MMU=y CONFIG_X86_VERY_EARLY_CONSOLE=y +CONFIG_QEMU_ICOUNT=n +CONFIG_X86_MMU_PAGE_POOL_PAGES=23 diff --git a/boards/x86/qemu_x86/qemu_x86_64_nokpti.dts b/boards/x86/qemu_x86/qemu_x86_64_nokpti.dts new file mode 100644 index 00000000000000..92522ab8a4ea1c --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_64_nokpti.dts @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2019 Intel Corp. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "qemu_x86.dts" diff --git a/boards/x86/qemu_x86/qemu_x86_64_nokpti.yaml b/boards/x86/qemu_x86/qemu_x86_64_nokpti.yaml new file mode 100644 index 00000000000000..49431fb4bf3e36 --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_64_nokpti.yaml @@ -0,0 +1,13 @@ +identifier: qemu_x86_64_nokpti +name: QEMU Emulation for X86_64 (KPTI disabled) +type: qemu +arch: x86 +toolchain: + - zephyr + - xtools +simulation: qemu +testing: + default: true + only_tags: + - kernel + - userspace diff --git a/boards/x86/qemu_x86/qemu_x86_64_nokpti_defconfig b/boards/x86/qemu_x86/qemu_x86_64_nokpti_defconfig new file mode 100644 index 00000000000000..0f161f8107918a --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_64_nokpti_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_IA32=y +CONFIG_BOARD_QEMU_X86_64=y +CONFIG_HPET_TIMER=y +CONFIG_PIC_DISABLE=y +CONFIG_LOAPIC=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_CONSOLE=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=25000000 +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_DEBUG_INFO=y +CONFIG_SMP=y +CONFIG_MP_NUM_CPUS=2 +CONFIG_X86_MMU=y +CONFIG_X86_VERY_EARLY_CONSOLE=y +CONFIG_QEMU_ICOUNT=n +CONFIG_X86_KPTI=n +CONFIG_X86_MMU_PAGE_POOL_PAGES=16 diff --git a/boards/x86/qemu_x86/qemu_x86_coverage.yaml b/boards/x86/qemu_x86/qemu_x86_coverage.yaml index 0508049c270c45..14197433ac212c 100644 --- a/boards/x86/qemu_x86/qemu_x86_coverage.yaml +++ b/boards/x86/qemu_x86/qemu_x86_coverage.yaml @@ -8,6 +8,6 @@ toolchain: - xtools testing: default: true - ignore_tags: - - net - - bluetooth + only_tags: + - kernel + - userspace diff --git a/boards/x86/qemu_x86/qemu_x86_coverage_defconfig b/boards/x86/qemu_x86/qemu_x86_coverage_defconfig index 8a45c7c63b5b84..7ee9871a78e291 100644 --- a/boards/x86/qemu_x86/qemu_x86_coverage_defconfig +++ b/boards/x86/qemu_x86/qemu_x86_coverage_defconfig @@ -12,9 +12,10 @@ CONFIG_UART_CONSOLE=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=25000000 CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_X86_MMU=y -CONFIG_X86_MMU_PAGE_POOL_PAGES=15 +CONFIG_X86_MMU_PAGE_POOL_PAGES=17 CONFIG_DEBUG_INFO=y CONFIG_SCHED_SCALABLE=y CONFIG_WAITQ_SCALABLE=y CONFIG_COVERAGE=y CONFIG_X86_VERY_EARLY_CONSOLE=y +CONFIG_QEMU_ICOUNT_SHIFT=5 diff --git a/boards/x86/qemu_x86/qemu_x86_defconfig b/boards/x86/qemu_x86/qemu_x86_defconfig index 7f2a6686c794bf..e4fb4151712227 100644 --- a/boards/x86/qemu_x86/qemu_x86_defconfig +++ b/boards/x86/qemu_x86/qemu_x86_defconfig @@ -12,8 +12,9 @@ CONFIG_UART_CONSOLE=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=25000000 CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_X86_MMU=y -CONFIG_X86_MMU_PAGE_POOL_PAGES=15 +CONFIG_X86_MMU_PAGE_POOL_PAGES=17 CONFIG_DEBUG_INFO=y CONFIG_SCHED_SCALABLE=y CONFIG_WAITQ_SCALABLE=y CONFIG_X86_VERY_EARLY_CONSOLE=y +CONFIG_QEMU_ICOUNT_SHIFT=5 diff --git a/boards/x86/qemu_x86/qemu_x86_nokpti.dts b/boards/x86/qemu_x86/qemu_x86_nokpti.dts new file mode 100644 index 00000000000000..707ded4ea8856d --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_nokpti.dts @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "qemu_x86.dts" diff --git a/boards/x86/qemu_x86/qemu_x86_nokpti.yaml b/boards/x86/qemu_x86/qemu_x86_nokpti.yaml new file mode 100644 index 00000000000000..6d1d7764a83330 --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_nokpti.yaml @@ -0,0 +1,13 @@ +identifier: qemu_x86_nokpti +name: QEMU Emulation for X86 (KPTI disabled) +type: qemu +arch: x86 +simulation: qemu +toolchain: + - zephyr + - xtools +testing: + default: true + only_tags: + - kernel + - userspace diff --git a/boards/x86/qemu_x86/qemu_x86_nokpti_defconfig b/boards/x86/qemu_x86/qemu_x86_nokpti_defconfig new file mode 100644 index 00000000000000..31557f2c3eb33a --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_nokpti_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_IA32=y +CONFIG_BOARD_QEMU_X86=y +CONFIG_HPET_TIMER=y +CONFIG_PIC_DISABLE=y +CONFIG_LOAPIC=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_CONSOLE=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=25000000 +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_X86_MMU=y +CONFIG_X86_MMU_PAGE_POOL_PAGES=12 +CONFIG_DEBUG_INFO=y +CONFIG_SCHED_SCALABLE=y +CONFIG_WAITQ_SCALABLE=y +CONFIG_X86_VERY_EARLY_CONSOLE=y +CONFIG_QEMU_ICOUNT_SHIFT=5 +CONFIG_X86_KPTI=n diff --git a/boards/x86/qemu_x86/qemu_x86_nommu.yaml b/boards/x86/qemu_x86/qemu_x86_nommu.yaml index 7e60da256f47b7..2ab0457fa28ba3 100644 --- a/boards/x86/qemu_x86/qemu_x86_nommu.yaml +++ b/boards/x86/qemu_x86/qemu_x86_nommu.yaml @@ -8,6 +8,6 @@ toolchain: - xtools testing: default: true - ignore_tags: - - net - - bluetooth + only_tags: + - kernel + - userspace diff --git a/boards/x86/qemu_x86/qemu_x86_nommu_defconfig b/boards/x86/qemu_x86/qemu_x86_nommu_defconfig index d4bfd61f1db246..ed3b7d4f58667a 100644 --- a/boards/x86/qemu_x86/qemu_x86_nommu_defconfig +++ b/boards/x86/qemu_x86/qemu_x86_nommu_defconfig @@ -12,3 +12,4 @@ CONFIG_UART_CONSOLE=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=25000000 CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_DEBUG_INFO=y +CONFIG_QEMU_ICOUNT_SHIFT=5 diff --git a/boards/x86/qemu_x86/qemu_x86_nopae.dts b/boards/x86/qemu_x86/qemu_x86_nopae.dts new file mode 100644 index 00000000000000..707ded4ea8856d --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_nopae.dts @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "qemu_x86.dts" diff --git a/boards/x86/qemu_x86/qemu_x86_nopae.yaml b/boards/x86/qemu_x86/qemu_x86_nopae.yaml new file mode 100644 index 00000000000000..4adf3ce0d15b7a --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_nopae.yaml @@ -0,0 +1,13 @@ +identifier: qemu_x86_nopae +name: QEMU Emulation for X86 (32-bit page tables) +type: qemu +arch: x86 +simulation: qemu +toolchain: + - zephyr + - xtools +testing: + default: true + only_tags: + - kernel + - userspace diff --git a/boards/x86/qemu_x86/qemu_x86_nopae_defconfig b/boards/x86/qemu_x86/qemu_x86_nopae_defconfig new file mode 100644 index 00000000000000..2724a0dc825fac --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_nopae_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_IA32=y +CONFIG_BOARD_QEMU_X86=y +CONFIG_HPET_TIMER=y +CONFIG_PIC_DISABLE=y +CONFIG_LOAPIC=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_CONSOLE=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=25000000 +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_X86_MMU=y +CONFIG_X86_MMU_PAGE_POOL_PAGES=10 +CONFIG_DEBUG_INFO=y +CONFIG_SCHED_SCALABLE=y +CONFIG_WAITQ_SCALABLE=y +CONFIG_X86_VERY_EARLY_CONSOLE=y +CONFIG_QEMU_ICOUNT_SHIFT=5 +CONFIG_X86_PAE=n diff --git a/boards/x86/qemu_x86/qemu_x86_tiny.dts b/boards/x86/qemu_x86/qemu_x86_tiny.dts new file mode 100644 index 00000000000000..a32afaa5b862c6 --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_tiny.dts @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2020 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRAM_SIZE DT_SIZE_K(2048) +#include "qemu_x86.dts" diff --git a/boards/x86/qemu_x86/qemu_x86_tiny.yaml b/boards/x86/qemu_x86/qemu_x86_tiny.yaml new file mode 100644 index 00000000000000..7903559299674d --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_tiny.yaml @@ -0,0 +1,13 @@ +identifier: qemu_x86_tiny +name: QEMU Emulation for X86 (small VM) +type: qemu +arch: x86 +simulation: qemu +toolchain: + - zephyr + - xtools +testing: + default: true + only_tags: + - kernel + - userspace diff --git a/boards/x86/qemu_x86/qemu_x86_tiny_defconfig b/boards/x86/qemu_x86/qemu_x86_tiny_defconfig new file mode 100644 index 00000000000000..bd2d264b25ffd2 --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_tiny_defconfig @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_IA32=y +CONFIG_BOARD_QEMU_X86=y +CONFIG_HPET_TIMER=y +CONFIG_PIC_DISABLE=y +CONFIG_LOAPIC=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_CONSOLE=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=25000000 +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_X86_MMU=y +CONFIG_DEBUG_INFO=y +CONFIG_SCHED_SCALABLE=y +CONFIG_WAITQ_SCALABLE=y +CONFIG_X86_VERY_EARLY_CONSOLE=y +CONFIG_QEMU_ICOUNT_SHIFT=5 + +CONFIG_X86_PAE=n +CONFIG_X86_COMMON_PAGE_TABLE=y +CONFIG_X86_KPTI=n +CONFIG_KERNEL_VM_SIZE=0x400000 +CONFIG_X86_MMU_PAGE_POOL_PAGES=0 diff --git a/boards/x86/qemu_x86/qemu_x86_xip.dts b/boards/x86/qemu_x86/qemu_x86_xip.dts new file mode 100644 index 00000000000000..707ded4ea8856d --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_xip.dts @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "qemu_x86.dts" diff --git a/boards/x86/qemu_x86/qemu_x86_xip.yaml b/boards/x86/qemu_x86/qemu_x86_xip.yaml new file mode 100644 index 00000000000000..7fb1de7ac4b31a --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_xip.yaml @@ -0,0 +1,12 @@ +identifier: qemu_x86_xip +name: QEMU Emulation for X86 (XIP enabled) +type: qemu +arch: x86 +simulation: qemu +toolchain: + - zephyr + - xtools +testing: + default: true + only_tags: + - xip diff --git a/boards/x86/qemu_x86/qemu_x86_xip_defconfig b/boards/x86/qemu_x86/qemu_x86_xip_defconfig new file mode 100644 index 00000000000000..4f47b5c6390102 --- /dev/null +++ b/boards/x86/qemu_x86/qemu_x86_xip_defconfig @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_IA32=y +CONFIG_BOARD_QEMU_X86=y +CONFIG_HPET_TIMER=y +CONFIG_PIC_DISABLE=y +CONFIG_LOAPIC=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_CONSOLE=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=25000000 +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_DEBUG_INFO=y +CONFIG_SCHED_SCALABLE=y +CONFIG_WAITQ_SCALABLE=y +CONFIG_X86_VERY_EARLY_CONSOLE=y +CONFIG_QEMU_ICOUNT_SHIFT=5 +CONFIG_XIP=y diff --git a/boards/x86/up_squared/CMakeLists.txt b/boards/x86/up_squared/CMakeLists.txt new file mode 100644 index 00000000000000..1e66f12ee48ecf --- /dev/null +++ b/boards/x86/up_squared/CMakeLists.txt @@ -0,0 +1,9 @@ +# Create an EFI image +if(CONFIG_BOARD_UP_SQUARED) +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/arch/x86/zefi/zefi.py + -f ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.elf + $<$:--verbose> + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} +) +endif() diff --git a/boards/x86/up_squared/Kconfig.defconfig b/boards/x86/up_squared/Kconfig.defconfig index f35c4e4d595811..09e127b7962389 100644 --- a/boards/x86/up_squared/Kconfig.defconfig +++ b/boards/x86/up_squared/Kconfig.defconfig @@ -12,7 +12,7 @@ config MP_NUM_CPUS default 2 config X86_MMU_PAGE_POOL_PAGES - default 3072 if X86_MMU + default 3092 if X86_MMU endif # BOARD_UP_SQUARED @@ -26,6 +26,6 @@ config BUILD_OUTPUT_STRIPPED default y config X86_MMU_PAGE_POOL_PAGES - default 3072 if X86_MMU + default 3086 if X86_MMU endif # BOARD_UP_SQUARED_32 diff --git a/boards/x86/up_squared/up_squared.dts b/boards/x86/up_squared/up_squared.dts index 17399864430202..b13cef3c2ee6cc 100644 --- a/boards/x86/up_squared/up_squared.dts +++ b/boards/x86/up_squared/up_squared.dts @@ -8,7 +8,7 @@ #include -#define DT_SRAM_SIZE DT_SIZE_M(2048) +#define DT_DRAM_SIZE DT_SIZE_M(2048) #include @@ -17,7 +17,7 @@ compatible = "intel,apollo_lake"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &dram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,bt-uart = &uart1; @@ -25,3 +25,7 @@ zephyr,bt-mon-uart = &uart1; }; }; + +&vtd { + status = "okay"; +}; diff --git a/boards/x86/up_squared/up_squared_32.dts b/boards/x86/up_squared/up_squared_32.dts index 4c3e0691324adb..a0c9550a36bf1a 100644 --- a/boards/x86/up_squared/up_squared_32.dts +++ b/boards/x86/up_squared/up_squared_32.dts @@ -8,7 +8,7 @@ #include -#define DT_SRAM_SIZE DT_SIZE_M(2048) +#define DT_DRAM_SIZE DT_SIZE_M(2048) #include @@ -17,7 +17,7 @@ compatible = "intel,apollo_lake"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &dram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,bt-uart = &uart1; diff --git a/boards/x86/up_squared/up_squared_defconfig b/boards/x86/up_squared/up_squared_defconfig index 1d99ab8e33729d..4b9fd65c1eca5f 100644 --- a/boards/x86/up_squared/up_squared_defconfig +++ b/boards/x86/up_squared/up_squared_defconfig @@ -8,5 +8,7 @@ CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_NS16550=y CONFIG_UART_CONSOLE=y -CONFIG_I2C=y CONFIG_X2APIC=y +CONFIG_SMP=y +CONFIG_MP_NUM_CPUS=2 +CONFIG_INTEL_VTD_ICTL=y diff --git a/boards/xtensa/esp32/esp32.dts b/boards/xtensa/esp32/esp32.dts index aab8efb17bb1fc..4e9c0bfe2bae72 100644 --- a/boards/xtensa/esp32/esp32.dts +++ b/boards/xtensa/esp32/esp32.dts @@ -24,11 +24,11 @@ }; &cpu0 { - clock-frequency = <40000000>; + clock-frequency = ; }; &cpu1 { - clock-frequency = <40000000>; + clock-frequency = ; }; &uart0 { diff --git a/boards/xtensa/esp32/esp32_defconfig b/boards/xtensa/esp32/esp32_defconfig index be5595cfe9a4d9..56e8482acda341 100644 --- a/boards/xtensa/esp32/esp32_defconfig +++ b/boards/xtensa/esp32/esp32_defconfig @@ -7,7 +7,7 @@ CONFIG_SOC_ESP32=y CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=40000000 +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=240000000 CONFIG_CONSOLE=y CONFIG_SERIAL=y @@ -29,5 +29,4 @@ CONFIG_I2C=y CONFIG_I2C_ESP32=y CONFIG_I2C_0=y CONFIG_I2C_1=y -CONFIG_I2C_2=n -CONFIG_I2C_3=n +CONFIG_CLOCK_CONTROL=y diff --git a/boards/xtensa/intel_adsp_cavs15/Kconfig.board b/boards/xtensa/intel_adsp_cavs15/Kconfig.board new file mode 100644 index 00000000000000..a7742e2b2481be --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs15/Kconfig.board @@ -0,0 +1,8 @@ +# Xtensa board configuration + +# Copyright (c) 2019 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_UP_SQUARED_ADSP + bool "Xtensa on Up Squared" + depends on SOC_SERIES_INTEL_CAVS_V15 diff --git a/boards/xtensa/intel_adsp_cavs15/Kconfig.defconfig b/boards/xtensa/intel_adsp_cavs15/Kconfig.defconfig new file mode 100644 index 00000000000000..f8c2f0138cde21 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs15/Kconfig.defconfig @@ -0,0 +1,46 @@ +# Copyright (c) 2019 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_UP_SQUARED_ADSP + +config BOARD + default "intel_adsp_cavs15" + +config CAVS_ICTL_0_OFFSET + default 6 +config CAVS_ICTL_1_OFFSET + default 10 +config CAVS_ICTL_2_OFFSET + default 13 +config CAVS_ICTL_3_OFFSET + default 16 + +config 2ND_LVL_INTR_00_OFFSET + default CAVS_ICTL_0_OFFSET +config 2ND_LVL_INTR_01_OFFSET + default CAVS_ICTL_1_OFFSET +config 2ND_LVL_INTR_02_OFFSET + default CAVS_ICTL_2_OFFSET +config 2ND_LVL_INTR_03_OFFSET + default CAVS_ICTL_3_OFFSET + +config MAX_IRQ_PER_AGGREGATOR + default 32 +config NUM_2ND_LEVEL_AGGREGATORS + default 4 +config 2ND_LVL_ISR_TBL_OFFSET + default 21 + +config CAVS_ISR_TBL_OFFSET + default 2ND_LVL_ISR_TBL_OFFSET + +config DMA_DW + default y + depends on DMA + +config I2S_CAVS + default y + depends on I2S + +endif # BOARD_UP_SQUARED_ADSP diff --git a/boards/xtensa/intel_adsp_cavs15/board.cmake b/boards/xtensa/intel_adsp_cavs15/board.cmake new file mode 100644 index 00000000000000..6b01bab2aeea87 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs15/board.cmake @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(misc-flasher) +board_finalize_runner_args(misc-flasher) diff --git a/boards/xtensa/intel_adsp_cavs15/doc/index.rst b/boards/xtensa/intel_adsp_cavs15/doc/index.rst new file mode 100644 index 00000000000000..bc27332b7d312f --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs15/doc/index.rst @@ -0,0 +1,104 @@ +.. _Up_Squared_Audio_DSP: + +Up Squared Audio DSP +#################### + +System Requirements +******************* + +Prerequisites +============= + +The Zephyr SDK 0.11 or higher is required. + +Since firmware binary signing for Audio DSP is mandatory on Intel products +form Skylake onwards the signing tool and key are needed. + +``up_squared`` board is running Linux with `SOF Diagnostic Driver`_ built and +loaded. + +Signing tool +------------ + +rimage is Audio DSP firmware image creation and signing tool. The tool is used +by `Sound Open Firmware`_ to generate binary firmware signed images. + +For the building instructions refer to `rimage Build Instructions`_. + +Signing keys +------------ + +The key used is Intel Open Source Technology Center (OTC) community key. +It can be freely used by anyone and intended for firmware developers. +Please download and store private key from the location: +https://github.com/thesofproject/sof/blob/master/rimage/keys/otc_private_key.pem + +For more information about keys refer to `rimage keys`_. + +Setup up_squared board +---------------------- + +To setup Linux on ``up_squared`` board refer to +`Getting Started with Ubuntu Core on an UP Squared Board`_. + +After installing Linux build and install `SOF Diagnostic Driver`_. + +Programming and Debugging +************************* + +Build Zephyr application +======================== + +Applications can be build in the usual way (see :ref:`build_an_application` +for more details). The only additional step required is signing. For example, +for building ``hello_world`` application following steps are needed. + +#. Building Zephyr application ``hello_world`` + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: intel_adsp_cavs15 + :goals: build + +#. Sign and create firmware image + + .. code-block:: console + + west sign -t rimage -- -k + +Loading image to Audio DSP +========================== + +`SOF Diagnostic Driver`_ provide interface for firmware loading. Python tools +in the board support directory use the interface to load firmware to ``ADSP``. + +.. code-block:: console + + $ sudo boards/xtensa/intel_adsp_cavs15/tools/fw_loader.py -f + +Debugging +========= + +The only way to debug application is using logging. Logging and ADSP logging +backend needs to be enabled in the application configuration. + +ADSP logging backend writes logs to the ring buffer in the shared memory. +Python tools are using `SOF Diagnostic Driver`_ interface to get logs. + +.. code-block:: console + + $ sudo boards/xtensa/intel_adsp_cavs15/tools/dump_trace.py + Open HDA device: /dev/hda + 0 : Hello World! intel_adsp_cavs15 + +.. target-notes:: + +.. _Getting Started with Ubuntu Core on an UP Squared Board: https://software.intel.com/en-us/articles/getting-started-with-ubuntu-core-on-an-up-squared-board + +.. _SOF Diagnostic Driver: https://github.com/thesofproject/sof-diagnostic-driver + +.. _Sound Open Firmware: https://github.com/thesofproject/sof + +.. _rimage Build Instructions: https://github.com/thesofproject/rimage#building + +.. _rimage keys: https://github.com/thesofproject/sof/tree/master/rimage/keys diff --git a/boards/xtensa/intel_adsp_cavs15/intel_adsp_cavs15.dts b/boards/xtensa/intel_adsp_cavs15/intel_adsp_cavs15.dts new file mode 100644 index 00000000000000..4a093117276d43 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs15/intel_adsp_cavs15.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "intel_adsp_cavs15"; + compatible = "intel"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &ipm_console; + }; +}; diff --git a/boards/xtensa/intel_adsp_cavs15/intel_adsp_cavs15.yaml b/boards/xtensa/intel_adsp_cavs15/intel_adsp_cavs15.yaml new file mode 100644 index 00000000000000..7a3f01f37c61b7 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs15/intel_adsp_cavs15.yaml @@ -0,0 +1,9 @@ +identifier: intel_adsp_cavs15 +name: Up Squared Audio DSP using CAVS (Connected Audio Voice and Speech) +type: mcu +arch: xtensa +toolchain: + - zephyr +testing: + only_tags: + - kernel diff --git a/boards/xtensa/intel_adsp_cavs15/intel_adsp_cavs15_defconfig b/boards/xtensa/intel_adsp_cavs15/intel_adsp_cavs15_defconfig new file mode 100644 index 00000000000000..0d236123fa9510 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs15/intel_adsp_cavs15_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_SOC_SERIES_INTEL_CAVS_V15=y +CONFIG_BOARD_UP_SQUARED_ADSP=y + +CONFIG_GEN_ISR_TABLES=y +CONFIG_GEN_IRQ_VECTOR_TABLE=n + +CONFIG_XTENSA_RESET_VECTOR=y + +CONFIG_XTENSA_USE_CORE_CRT1=y + +CONFIG_MULTI_LEVEL_INTERRUPTS=y +CONFIG_2ND_LEVEL_INTERRUPTS=y +CONFIG_CAVS_ICTL=y + +CONFIG_BOOTLOADER_SRAM_SIZE=192 +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_CLEANUP_INTERMEDIATE_FILES=y diff --git a/boards/xtensa/intel_adsp_cavs15/tools/adsplog.py b/boards/xtensa/intel_adsp_cavs15/tools/adsplog.py new file mode 100755 index 00000000000000..8df555cf8e559e --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs15/tools/adsplog.py @@ -0,0 +1,85 @@ +#!/usr/bin/python3 +# +# Copyright (c) 2020 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import sys +import time +import struct +import subprocess +import mmap + +MAP_SIZE = 8192 +SLOT_SIZE = 64 + +# Location of the log output window within the DSP BAR on the PCI +# device. The hardware provides 4x 128k "windows" starting at 512kb +# in the BAR which the DSP software can map to 4k-aligned locations +# within its own address space. By convention log output is an 8k +# region at window index 3. +WIN_OFFSET = 0x80000 +WIN_ID = 3 +WIN_SIZE = 0x20000 +LOG_OFFSET = WIN_OFFSET + WIN_ID * WIN_SIZE + +# Find me a way to do this detection as cleanly in python as shell, I +# dare you. +barfile = subprocess.Popen(["sh", "-c", + "echo -n " + "$(dirname " + " $(fgrep PCI_ID=8086:5A98 " + " /sys/bus/pci/devices/*/uevent))" + "/resource4"], + stdout=subprocess.PIPE).stdout.read() +fd = open(barfile) +mem = mmap.mmap(fd.fileno(), MAP_SIZE, offset=LOG_OFFSET, + prot=mmap.PROT_READ) + +# The mapping is an array of 64-byte "slots", each of which is +# prefixed by a magic number, which should be 0x55aa for log data, +# followed a 16 bit "ID" number, followed by a null-terminated string +# in the final 60 bytes. The DSP firmware will write sequential IDs +# into the buffer starting from an ID of zero in the first slot, and +# wrapping at the end. So the algorithm here is to find the smallest +# valid slot, print its data, and then enter a polling loop waiting +# for the next slot to be valid and have the correct next ID before +# printing that too. + +# NOTE: unfortunately there's no easy way to detect a warm reset of +# the device, it will just jump back to the beginning and start +# writing there, where we aren't looking. Really that level of +# robustness needs to be handled in the kernel. + +next_slot = 0 +next_id = 0xffff + +for slot in range(int(MAP_SIZE / SLOT_SIZE)): + off = slot * SLOT_SIZE + (magic, sid) = struct.unpack("HH", mem[off:off+4]) + if magic == 0x55aa: + if sid < next_id: + next_slot = slot + next_id = sid + +while True: + off = next_slot * SLOT_SIZE + (magic, sid) = struct.unpack("HH", mem[off:off+4]) + if magic == 0x55aa and sid == next_id: + # This dance because indexing large variable-length slices of + # the mmap() array seems to produce garbage.... + msgbytes = [] + for i in range(4, SLOT_SIZE): + b = mem[off+i] + if b == 0: + break + msgbytes.append(b) + msg = bytearray(len(msgbytes)) + for i, elem in enumerate(msgbytes): + msg[i] = elem + + sys.stdout.write(msg.decode(encoding="utf-8", errors="ignore")) + next_slot = int((next_slot + 1) % (MAP_SIZE / SLOT_SIZE)) + next_id += 1 + else: + sys.stdout.flush() + time.sleep(0.25) diff --git a/boards/xtensa/up_squared_adsp/tools/dump_trace.py b/boards/xtensa/intel_adsp_cavs15/tools/dump_trace.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/dump_trace.py rename to boards/xtensa/intel_adsp_cavs15/tools/dump_trace.py diff --git a/boards/xtensa/up_squared_adsp/tools/fw_loader.py b/boards/xtensa/intel_adsp_cavs15/tools/fw_loader.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/fw_loader.py rename to boards/xtensa/intel_adsp_cavs15/tools/fw_loader.py diff --git a/boards/xtensa/up_squared_adsp/tools/lib/__init__.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/__init__.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/lib/__init__.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/__init__.py diff --git a/boards/xtensa/up_squared_adsp/tools/lib/device.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/device.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/lib/device.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/device.py diff --git a/boards/xtensa/up_squared_adsp/tools/lib/driver.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/driver.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/lib/driver.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/driver.py diff --git a/boards/xtensa/up_squared_adsp/tools/lib/etrace.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/etrace.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/lib/etrace.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/etrace.py diff --git a/boards/xtensa/up_squared_adsp/tools/lib/ipc.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/ipc.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/lib/ipc.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/ipc.py diff --git a/boards/xtensa/up_squared_adsp/tools/lib/loader.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/loader.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/lib/loader.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/loader.py diff --git a/boards/xtensa/up_squared_adsp/tools/lib/loglist.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/loglist.py similarity index 94% rename from boards/xtensa/up_squared_adsp/tools/lib/loglist.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/loglist.py index 082531a5f0a9c0..a2468abe39654a 100644 --- a/boards/xtensa/up_squared_adsp/tools/lib/loglist.py +++ b/boards/xtensa/intel_adsp_cavs15/tools/lib/loglist.py @@ -16,12 +16,11 @@ def read_bytes(buffer): class Loglist: """Loglist class""" - def __init__(self, argument, debug=False, offset=0): + def __init__(self, argument, debug=False): """Constructor for the loglist takes argument filename or buffer""" if isinstance(argument, str): f = open(argument, "rb") - f.seek(offset) self.buffer = f.read(SLOT_NUM * SLOT_LEN) elif isinstance(argument, int): self.buffer = string_at(argument, SLOT_NUM * SLOT_LEN) diff --git a/boards/xtensa/up_squared_adsp/tools/lib/platforms.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/platforms.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/lib/platforms.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/platforms.py diff --git a/boards/xtensa/up_squared_adsp/tools/lib/registers.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/registers.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/lib/registers.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/registers.py diff --git a/boards/xtensa/up_squared_adsp/tools/lib/stream_desc.py b/boards/xtensa/intel_adsp_cavs15/tools/lib/stream_desc.py similarity index 100% rename from boards/xtensa/up_squared_adsp/tools/lib/stream_desc.py rename to boards/xtensa/intel_adsp_cavs15/tools/lib/stream_desc.py diff --git a/boards/xtensa/up_squared_adsp/tools/logtool.py b/boards/xtensa/intel_adsp_cavs15/tools/logtool.py similarity index 92% rename from boards/xtensa/up_squared_adsp/tools/logtool.py rename to boards/xtensa/intel_adsp_cavs15/tools/logtool.py index cceb5239f8064a..9c0609f7741c62 100755 --- a/boards/xtensa/up_squared_adsp/tools/logtool.py +++ b/boards/xtensa/intel_adsp_cavs15/tools/logtool.py @@ -42,12 +42,10 @@ def main(): else: if args.etrace == 'sof': etrace = SOF_ETRACE - offset = 0 else: etrace = QEMU_ETRACE - offset = 0x8000 - l = Loglist(etrace, offset=offset) + l = Loglist(etrace) l.print() if __name__ == "__main__": diff --git a/boards/xtensa/intel_adsp_cavs15/tools/mbterm.py b/boards/xtensa/intel_adsp_cavs15/tools/mbterm.py new file mode 100755 index 00000000000000..e37181ff6f074c --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs15/tools/mbterm.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2020 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +from time import sleep +from mmap import mmap, ACCESS_COPY +from ctypes import c_uint8 + +from lib.device import Device +import lib.registers as regs + +MBOX = 0x91281000 +LENGTH = 0x1000 + +with open("/dev/mem", "rb") as f: + mem_map = mmap(f.fileno(), LENGTH, access=ACCESS_COPY, offset=MBOX) + mem = (c_uint8 * LENGTH).from_buffer(mem_map) + +def mailbox_poll_mem(dev): + while True: + if dev.dsp_hipct.value & regs.ADSP_IPC_HIPCT_BUSY: + + # Use only id for passing character + line_len = dev.dsp_hipct.value & regs.ADSP_IPC_HIPCT_MSG + + # Mask out internal bits + line_len &= 0x10FFFF + + if line_len: + print(bytes(mem[:line_len]).decode()) + + # Clear interrupt + dev.dsp_hipct.value |= regs.ADSP_IPC_HIPCT_BUSY + else: + sleep(0.005) + +# Character passed in mailbox ID field +def mailbox_poll_char(dev): + while True: + if dev.dsp_hipct.value & regs.ADSP_IPC_HIPCT_BUSY: + + # Use only id for passing character + character = dev.dsp_hipct.value & regs.ADSP_IPC_HIPCT_MSG + + # Get readable character + character &= 0x10FFFF + + print('{}'.format(chr(character)), end='') + + # Clear interrupt + dev.dsp_hipct.value |= regs.ADSP_IPC_HIPCT_BUSY + else: + sleep(0.005) + + +if __name__ == "__main__": + # Clear Done if needed + #dev.dsp_hipct.value |= regs.ADSP_IPC_HIPCT_BUSY + + # Use Device library for controlling registers + device = Device() + device.open_device() + + mailbox_poll_mem(device) diff --git a/boards/xtensa/intel_adsp_cavs18/Kconfig.board b/boards/xtensa/intel_adsp_cavs18/Kconfig.board new file mode 100644 index 00000000000000..765bfe0b095150 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs18/Kconfig.board @@ -0,0 +1,8 @@ +# Xtensa board configuration + +# Copyright (c) 2020 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_INTEL_ADSP_CAVS18 + bool "Intel ADSP CAVS 1.8" + depends on SOC_SERIES_INTEL_CAVS_V18 diff --git a/boards/xtensa/intel_adsp_cavs18/Kconfig.defconfig b/boards/xtensa/intel_adsp_cavs18/Kconfig.defconfig new file mode 100644 index 00000000000000..3bd5423223e31e --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs18/Kconfig.defconfig @@ -0,0 +1,46 @@ +# Copyright (c) 2020 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_INTEL_ADSP_CAVS18 + +config BOARD + default "intel_adsp_cavs18" + +config CAVS_ICTL_0_OFFSET + default 6 +config CAVS_ICTL_1_OFFSET + default 10 +config CAVS_ICTL_2_OFFSET + default 13 +config CAVS_ICTL_3_OFFSET + default 16 + +config 2ND_LVL_INTR_00_OFFSET + default CAVS_ICTL_0_OFFSET +config 2ND_LVL_INTR_01_OFFSET + default CAVS_ICTL_1_OFFSET +config 2ND_LVL_INTR_02_OFFSET + default CAVS_ICTL_2_OFFSET +config 2ND_LVL_INTR_03_OFFSET + default CAVS_ICTL_3_OFFSET + +config MAX_IRQ_PER_AGGREGATOR + default 32 +config NUM_2ND_LEVEL_AGGREGATORS + default 4 +config 2ND_LVL_ISR_TBL_OFFSET + default 21 + +config CAVS_ISR_TBL_OFFSET + default 2ND_LVL_ISR_TBL_OFFSET + +config DMA_DW + default y + depends on DMA + +config I2S_CAVS + default y + depends on I2S + +endif # BOARD_INTEL_ADSP_CAVS18 diff --git a/boards/xtensa/intel_adsp_cavs18/board.cmake b/boards/xtensa/intel_adsp_cavs18/board.cmake new file mode 100644 index 00000000000000..6b01bab2aeea87 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs18/board.cmake @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(misc-flasher) +board_finalize_runner_args(misc-flasher) diff --git a/boards/xtensa/intel_adsp_cavs18/intel_adsp_cavs18.dts b/boards/xtensa/intel_adsp_cavs18/intel_adsp_cavs18.dts new file mode 100644 index 00000000000000..a0f97261415b1b --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs18/intel_adsp_cavs18.dts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "intel_adsp_cavs18"; + compatible = "intel"; + + chosen { + zephyr,sram = &sram0; + }; +}; diff --git a/boards/xtensa/intel_adsp_cavs18/intel_adsp_cavs18.yaml b/boards/xtensa/intel_adsp_cavs18/intel_adsp_cavs18.yaml new file mode 100644 index 00000000000000..611515dd37c3ff --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs18/intel_adsp_cavs18.yaml @@ -0,0 +1,9 @@ +identifier: intel_adsp_cavs18 +name: CAVS 1.8 Audio DSP (Connected Audio Voice and Speech) +type: mcu +arch: xtensa +toolchain: + - zephyr +testing: + only_tags: + - kernel diff --git a/boards/xtensa/intel_adsp_cavs18/intel_adsp_cavs18_defconfig b/boards/xtensa/intel_adsp_cavs18/intel_adsp_cavs18_defconfig new file mode 100644 index 00000000000000..943e7168dcb577 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs18/intel_adsp_cavs18_defconfig @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_SOC_SERIES_INTEL_CAVS_V18=y +CONFIG_BOARD_INTEL_ADSP_CAVS18=y + +CONFIG_GEN_ISR_TABLES=y +CONFIG_GEN_IRQ_VECTOR_TABLE=n + +CONFIG_XTENSA_RESET_VECTOR=y + +CONFIG_XTENSA_USE_CORE_CRT1=y + +CONFIG_MULTI_LEVEL_INTERRUPTS=y +CONFIG_2ND_LEVEL_INTERRUPTS=y +CONFIG_CAVS_ICTL=y + +CONFIG_BOOTLOADER_SRAM_SIZE=192 diff --git a/boards/xtensa/intel_adsp_cavs20/Kconfig.board b/boards/xtensa/intel_adsp_cavs20/Kconfig.board new file mode 100644 index 00000000000000..64e8990dd758bb --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs20/Kconfig.board @@ -0,0 +1,8 @@ +# Xtensa board configuration + +# Copyright (c) 2020 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_INTEL_ADSP_CAVS20 + bool "Intel ADSP CAVS 2.0" + depends on SOC_SERIES_INTEL_CAVS_V20 diff --git a/boards/xtensa/intel_adsp_cavs20/Kconfig.defconfig b/boards/xtensa/intel_adsp_cavs20/Kconfig.defconfig new file mode 100644 index 00000000000000..b7815d91f0244f --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs20/Kconfig.defconfig @@ -0,0 +1,46 @@ +# Copyright (c) 2020 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_INTEL_ADSP_CAVS20 + +config BOARD + default "intel_adsp_cavs20" + +config CAVS_ICTL_0_OFFSET + default 6 +config CAVS_ICTL_1_OFFSET + default 10 +config CAVS_ICTL_2_OFFSET + default 13 +config CAVS_ICTL_3_OFFSET + default 16 + +config 2ND_LVL_INTR_00_OFFSET + default CAVS_ICTL_0_OFFSET +config 2ND_LVL_INTR_01_OFFSET + default CAVS_ICTL_1_OFFSET +config 2ND_LVL_INTR_02_OFFSET + default CAVS_ICTL_2_OFFSET +config 2ND_LVL_INTR_03_OFFSET + default CAVS_ICTL_3_OFFSET + +config MAX_IRQ_PER_AGGREGATOR + default 32 +config NUM_2ND_LEVEL_AGGREGATORS + default 4 +config 2ND_LVL_ISR_TBL_OFFSET + default 21 + +config CAVS_ISR_TBL_OFFSET + default 2ND_LVL_ISR_TBL_OFFSET + +config DMA_DW + default y + depends on DMA + +config I2S_CAVS + default y + depends on I2S + +endif # BOARD_INTEL_ADSP_CAVS20 diff --git a/boards/xtensa/intel_adsp_cavs20/board.cmake b/boards/xtensa/intel_adsp_cavs20/board.cmake new file mode 100644 index 00000000000000..6b01bab2aeea87 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs20/board.cmake @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(misc-flasher) +board_finalize_runner_args(misc-flasher) diff --git a/boards/xtensa/intel_adsp_cavs20/intel_adsp_cavs20.dts b/boards/xtensa/intel_adsp_cavs20/intel_adsp_cavs20.dts new file mode 100644 index 00000000000000..2381c111dbf697 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs20/intel_adsp_cavs20.dts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "intel_adsp_cavs20"; + compatible = "intel"; + + chosen { + zephyr,sram = &sram0; + }; +}; diff --git a/boards/xtensa/intel_adsp_cavs20/intel_adsp_cavs20.yaml b/boards/xtensa/intel_adsp_cavs20/intel_adsp_cavs20.yaml new file mode 100644 index 00000000000000..b5a015fd7ffac6 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs20/intel_adsp_cavs20.yaml @@ -0,0 +1,9 @@ +identifier: intel_adsp_cavs20 +name: CAVS 2.0 Audio DSP (Connected Audio Voice and Speech) +type: mcu +arch: xtensa +toolchain: + - zephyr +testing: + only_tags: + - kernel diff --git a/boards/xtensa/intel_adsp_cavs20/intel_adsp_cavs20_defconfig b/boards/xtensa/intel_adsp_cavs20/intel_adsp_cavs20_defconfig new file mode 100644 index 00000000000000..e677f66de95141 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs20/intel_adsp_cavs20_defconfig @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_SOC_SERIES_INTEL_CAVS_V20=y +CONFIG_BOARD_INTEL_ADSP_CAVS20=y + +CONFIG_GEN_ISR_TABLES=y +CONFIG_GEN_IRQ_VECTOR_TABLE=n + +CONFIG_XTENSA_RESET_VECTOR=y + +CONFIG_XTENSA_USE_CORE_CRT1=y + +CONFIG_MULTI_LEVEL_INTERRUPTS=y +CONFIG_2ND_LEVEL_INTERRUPTS=y +CONFIG_CAVS_ICTL=y + +CONFIG_BOOTLOADER_SRAM_SIZE=192 diff --git a/boards/xtensa/intel_adsp_cavs25/Kconfig.board b/boards/xtensa/intel_adsp_cavs25/Kconfig.board new file mode 100644 index 00000000000000..8b20c419513dec --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs25/Kconfig.board @@ -0,0 +1,8 @@ +# Xtensa board configuration + +# Copyright (c) 2020 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_INTEL_ADSP_CAVS25 + bool "Intel ADSP CAVS 2.5" + depends on SOC_SERIES_INTEL_CAVS_V25 diff --git a/boards/xtensa/intel_adsp_cavs25/Kconfig.defconfig b/boards/xtensa/intel_adsp_cavs25/Kconfig.defconfig new file mode 100644 index 00000000000000..d21aa2710a25ae --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs25/Kconfig.defconfig @@ -0,0 +1,46 @@ +# Copyright (c) 2020 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_INTEL_ADSP_CAVS25 + +config BOARD + default "intel_adsp_cavs25" + +config CAVS_ICTL_0_OFFSET + default 6 +config CAVS_ICTL_1_OFFSET + default 10 +config CAVS_ICTL_2_OFFSET + default 13 +config CAVS_ICTL_3_OFFSET + default 16 + +config 2ND_LVL_INTR_00_OFFSET + default CAVS_ICTL_0_OFFSET +config 2ND_LVL_INTR_01_OFFSET + default CAVS_ICTL_1_OFFSET +config 2ND_LVL_INTR_02_OFFSET + default CAVS_ICTL_2_OFFSET +config 2ND_LVL_INTR_03_OFFSET + default CAVS_ICTL_3_OFFSET + +config MAX_IRQ_PER_AGGREGATOR + default 32 +config NUM_2ND_LEVEL_AGGREGATORS + default 4 +config 2ND_LVL_ISR_TBL_OFFSET + default 21 + +config CAVS_ISR_TBL_OFFSET + default 2ND_LVL_ISR_TBL_OFFSET + +config DMA_DW + default y + depends on DMA + +config I2S_CAVS + default y + depends on I2S + +endif # BOARD_INTEL_ADSP_CAVS25 diff --git a/boards/xtensa/intel_adsp_cavs25/board.cmake b/boards/xtensa/intel_adsp_cavs25/board.cmake new file mode 100644 index 00000000000000..6b01bab2aeea87 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs25/board.cmake @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(misc-flasher) +board_finalize_runner_args(misc-flasher) diff --git a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts new file mode 100644 index 00000000000000..d4c1cac454a4e6 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.dts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "intel_adsp_cavs25"; + compatible = "intel"; + + chosen { + zephyr,sram = &sram0; + }; +}; diff --git a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml new file mode 100644 index 00000000000000..2d65f48742813f --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25.yaml @@ -0,0 +1,9 @@ +identifier: intel_adsp_cavs25 +name: CAVS 2.5 Audio DSP (Connected Audio Voice and Speech) +type: mcu +arch: xtensa +toolchain: + - zephyr +testing: + only_tags: + - kernel diff --git a/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_defconfig b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_defconfig new file mode 100644 index 00000000000000..d762d26c3187ce --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs25/intel_adsp_cavs25_defconfig @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_MAIN_STACK_SIZE=2048 + +CONFIG_SOC_SERIES_INTEL_CAVS_V25=y +CONFIG_BOARD_INTEL_ADSP_CAVS25=y + +CONFIG_GEN_ISR_TABLES=y +CONFIG_GEN_IRQ_VECTOR_TABLE=n + +CONFIG_XTENSA_RESET_VECTOR=y + +CONFIG_XTENSA_USE_CORE_CRT1=y + +CONFIG_MULTI_LEVEL_INTERRUPTS=y +CONFIG_2ND_LEVEL_INTERRUPTS=y +CONFIG_CAVS_ICTL=y + +CONFIG_BOOTLOADER_SRAM_SIZE=192 diff --git a/boards/xtensa/intel_s1000_crb/Kconfig.defconfig b/boards/xtensa/intel_s1000_crb/Kconfig.defconfig index eb1f4aa956c23a..4363039c1250b8 100644 --- a/boards/xtensa/intel_s1000_crb/Kconfig.defconfig +++ b/boards/xtensa/intel_s1000_crb/Kconfig.defconfig @@ -45,11 +45,7 @@ config CAVS_ISR_TBL_OFFSET config DW_ISR_TBL_OFFSET default 3RD_LVL_ISR_TBL_OFFSET -config HEAP_MEM_POOL_SIZE - default 1024 - depends on DMA_DW - -config TEXT_SECTION_OFFSET +config ROM_START_OFFSET default 0x100 depends on BOOTLOADER_MCUBOOT diff --git a/boards/xtensa/intel_s1000_crb/intel_s1000_crb.dts b/boards/xtensa/intel_s1000_crb/intel_s1000_crb.dts index b51395d88bdc76..db306c28e1e86c 100644 --- a/boards/xtensa/intel_s1000_crb/intel_s1000_crb.dts +++ b/boards/xtensa/intel_s1000_crb/intel_s1000_crb.dts @@ -17,6 +17,7 @@ zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; + zephyr,flash-controller = &flash0; }; }; diff --git a/boards/xtensa/intel_s1000_crb/pinmux.c b/boards/xtensa/intel_s1000_crb/pinmux.c index 93fa51738e5465..510f84770419c3 100644 --- a/boards/xtensa/intel_s1000_crb/pinmux.c +++ b/boards/xtensa/intel_s1000_crb/pinmux.c @@ -21,9 +21,9 @@ * Please note that a call to pinmux_pin_set is only needed when a setting * that is not default is required */ -static int intel_s1000_pinmux_init(struct device *dev) +static int intel_s1000_pinmux_init(const struct device *dev) { - struct device *pinmux; + const struct device *pinmux; pinmux = device_get_binding(CONFIG_PINMUX_NAME); diff --git a/boards/xtensa/odroid_go/odroid_go.yaml b/boards/xtensa/odroid_go/odroid_go.yaml index 45127d20eb51c6..7b1c13c18f63bc 100644 --- a/boards/xtensa/odroid_go/odroid_go.yaml +++ b/boards/xtensa/odroid_go/odroid_go.yaml @@ -1,4 +1,4 @@ -identifier: esp32 +identifier: odroid-go name: ODROID-GO type: mcu arch: xtensa diff --git a/boards/xtensa/qemu_xtensa/board.cmake b/boards/xtensa/qemu_xtensa/board.cmake index fd9886d22748c2..822cdb1e2bd400 100644 --- a/boards/xtensa/qemu_xtensa/board.cmake +++ b/boards/xtensa/qemu_xtensa/board.cmake @@ -8,9 +8,6 @@ set(QEMU_FLAGS_${ARCH} -machine sim -semihosting -nographic -cpu sample_controller ) -if(CONFIG_QEMU_ICOUNT) - list(APPEND QEMU_EXTRA_FLAGS -icount shift=6,align=off,sleep=off -rtc clock=vm) -endif() # TODO: Support debug # board_set_debugger_ifnset(qemu) # debugserver: QEMU_EXTRA_FLAGS += -s -S diff --git a/boards/xtensa/qemu_xtensa/qemu_xtensa_defconfig b/boards/xtensa/qemu_xtensa/qemu_xtensa_defconfig index 9af567b1f8e18a..08e8295cc80345 100644 --- a/boards/xtensa/qemu_xtensa/qemu_xtensa_defconfig +++ b/boards/xtensa/qemu_xtensa/qemu_xtensa_defconfig @@ -9,3 +9,4 @@ CONFIG_STACK_SENTINEL=y CONFIG_GEN_ISR_TABLES=y CONFIG_GEN_IRQ_VECTOR_TABLE=n CONFIG_SIMULATOR_XTENSA=y +CONFIG_QEMU_ICOUNT_SHIFT=6 diff --git a/boards/xtensa/up_squared_adsp/Kconfig.board b/boards/xtensa/up_squared_adsp/Kconfig.board deleted file mode 100644 index 0f443f79d8e693..00000000000000 --- a/boards/xtensa/up_squared_adsp/Kconfig.board +++ /dev/null @@ -1,8 +0,0 @@ -# Xtensa board configuration - -# Copyright (c) 2019 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_UP_SQUARED_ADSP - bool "Xtensa on Up Squared" - depends on SOC_INTEL_APL_ADSP diff --git a/boards/xtensa/up_squared_adsp/Kconfig.defconfig b/boards/xtensa/up_squared_adsp/Kconfig.defconfig deleted file mode 100644 index dc1a1999879888..00000000000000 --- a/boards/xtensa/up_squared_adsp/Kconfig.defconfig +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2019 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_UP_SQUARED_ADSP - -config BOARD - default "up_squared_adsp" - -config CAVS_ICTL_0_OFFSET - default 6 -config CAVS_ICTL_1_OFFSET - default 10 -config CAVS_ICTL_2_OFFSET - default 13 -config CAVS_ICTL_3_OFFSET - default 16 - -config 2ND_LVL_INTR_00_OFFSET - default CAVS_ICTL_0_OFFSET -config 2ND_LVL_INTR_01_OFFSET - default CAVS_ICTL_1_OFFSET -config 2ND_LVL_INTR_02_OFFSET - default CAVS_ICTL_2_OFFSET -config 2ND_LVL_INTR_03_OFFSET - default CAVS_ICTL_3_OFFSET - -config MAX_IRQ_PER_AGGREGATOR - default 32 -config NUM_2ND_LEVEL_AGGREGATORS - default 4 -config 2ND_LVL_ISR_TBL_OFFSET - default 21 - -config CAVS_ISR_TBL_OFFSET - default 2ND_LVL_ISR_TBL_OFFSET - -config HEAP_MEM_POOL_SIZE - default 1024 - depends on DMA_DW - -config DMA_DW - default y - depends on DMA - -config I2S_CAVS - default y - depends on I2S - -endif # BOARD_UP_SQUARED_ADSP diff --git a/boards/xtensa/up_squared_adsp/doc/index.rst b/boards/xtensa/up_squared_adsp/doc/index.rst deleted file mode 100644 index bd5651facb031f..00000000000000 --- a/boards/xtensa/up_squared_adsp/doc/index.rst +++ /dev/null @@ -1,104 +0,0 @@ -.. _Up_Squared_Audio_DSP: - -Up Squared Audio DSP -#################### - -System Requirements -******************* - -Prerequisites -============= - -The Zephyr SDK 0.11 or higher is required. - -Since firmware binary signing for Audio DSP is mandatory on Intel products -form Skylake onwards the signing tool and key are needed. - -``up_squared`` board is running Linux with `SOF Diagnostic Driver`_ built and -loaded. - -Signing tool ------------- - -rimage is Audio DSP firmware image creation and signing tool. The tool is used -by `Sound Open Firmware`_ to generate binary firmware signed images. - -For the building instructions refer to `rimage Build Instructions`_. - -Signing keys ------------- - -The key used is Intel Open Source Technology Center (OTC) community key. -It can be freely used by anyone and intended for firmware developers. -Please download and store private key from the location: -https://github.com/thesofproject/sof/blob/master/rimage/keys/otc_private_key.pem - -For more information about keys refer to `rimage keys`_. - -Setup up_squared board ----------------------- - -To setup Linux on ``up_squared`` board refer to -`Getting Started with Ubuntu Core on an UP Squared Board`_. - -After installing Linux build and install `SOF Diagnostic Driver`_. - -Programming and Debugging -************************* - -Build Zephyr application -======================== - -Applications can be build in the usual way (see :ref:`build_an_application` -for more details). The only additional step required is signing. For example, -for building ``hello_world`` application following steps are needed. - -#. Building Zephyr application ``hello_world`` - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: up_squared_adsp - :goals: build - -#. Sign and create firmware image - - .. code-block:: console - - west sign -t rimage -- -k - -Loading image to Audio DSP -========================== - -`SOF Diagnostic Driver`_ provide interface for firmware loading. Python tools -in the board support directory use the interface to load firmware to ``ADSP``. - -.. code-block:: console - - $ sudo boards/xtensa/up_squared_adsp/tools/fw_loader.py -f - -Debugging -========= - -The only way to debug application is using logging. Logging and ADSP logging -backend needs to be enabled in the application configuration. - -ADSP logging backend writes logs to the ring buffer in the shared memory. -Python tools are using `SOF Diagnostic Driver`_ interface to get logs. - -.. code-block:: console - - $ sudo boards/xtensa/up_squared_adsp/tools/dump_trace.py - Open HDA device: /dev/hda - 0 : Hello World! up_squared_adsp - -.. target-notes:: - -.. _Getting Started with Ubuntu Core on an UP Squared Board: https://software.intel.com/en-us/articles/getting-started-with-ubuntu-core-on-an-up-squared-board - -.. _SOF Diagnostic Driver: https://github.com/thesofproject/sof-diagnostic-driver - -.. _Sound Open Firmware: https://github.com/thesofproject/sof - -.. _rimage Build Instructions: https://github.com/thesofproject/rimage#building - -.. _rimage keys: https://github.com/thesofproject/sof/tree/master/rimage/keys diff --git a/boards/xtensa/up_squared_adsp/tools/up_squared_adsp_flash.sh b/boards/xtensa/up_squared_adsp/tools/up_squared_adsp_flash.sh deleted file mode 100755 index 1ee9451fa50c3f..00000000000000 --- a/boards/xtensa/up_squared_adsp/tools/up_squared_adsp_flash.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# Copyright (c) 2020 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -BUILD=$1 -FIRMWARE=${BUILD}/zephyr/zephyr.ri -FLASHER=${ZEPHYR_BASE}/boards/xtensa/up_squared_adsp/tools/fw_loader.py - -if [ -z "$2" ] - then - echo "Signing using default key" - west sign -d ${BUILD} -t rimage -else - echo "Signing with key " $key - west sign -d ${BUILD} -t rimage -- -k $2 -fi - -${FLASHER} -f ${FIRMWARE} 2>&1 diff --git a/boards/xtensa/up_squared_adsp/up_squared_adsp.dts b/boards/xtensa/up_squared_adsp/up_squared_adsp.dts deleted file mode 100644 index 0ec6488fd65ca0..00000000000000 --- a/boards/xtensa/up_squared_adsp/up_squared_adsp.dts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2019 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; - -#include - -/ { - model = "up_squared_adsp"; - compatible = "intel"; - - chosen { - zephyr,sram = &sram0; - }; -}; diff --git a/boards/xtensa/up_squared_adsp/up_squared_adsp.yaml b/boards/xtensa/up_squared_adsp/up_squared_adsp.yaml deleted file mode 100644 index f7088606eed8b4..00000000000000 --- a/boards/xtensa/up_squared_adsp/up_squared_adsp.yaml +++ /dev/null @@ -1,9 +0,0 @@ -identifier: up_squared_adsp -name: Up Squared Audio DSP using CAVS (Connected Audio Voice and Speech) -type: mcu -arch: xtensa -toolchain: - - zephyr -testing: - ignore_tags: - - net diff --git a/boards/xtensa/up_squared_adsp/up_squared_adsp_defconfig b/boards/xtensa/up_squared_adsp/up_squared_adsp_defconfig deleted file mode 100644 index 74469094fb78c2..00000000000000 --- a/boards/xtensa/up_squared_adsp/up_squared_adsp_defconfig +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_MAIN_STACK_SIZE=2048 - -CONFIG_SOC_INTEL_APL_ADSP=y -CONFIG_BOARD_UP_SQUARED_ADSP=y - -CONFIG_GEN_ISR_TABLES=y -CONFIG_GEN_IRQ_VECTOR_TABLE=n - -CONFIG_XTENSA_RESET_VECTOR=y - -CONFIG_XTENSA_USE_CORE_CRT1=y - -CONFIG_MULTI_LEVEL_INTERRUPTS=y -CONFIG_2ND_LEVEL_INTERRUPTS=y -CONFIG_CAVS_ICTL=y - -CONFIG_BOOTLOADER_SRAM_SIZE=192 diff --git a/boards/xtensa/xt-sim/doc/index.rst b/boards/xtensa/xt-sim/doc/index.rst index 72732b3d05d202..81279110c178bf 100644 --- a/boards/xtensa/xt-sim/doc/index.rst +++ b/boards/xtensa/xt-sim/doc/index.rst @@ -132,7 +132,7 @@ The file "soc/xtensa/linker_more.ld" contains Zephyr-specific linker sections that should be added to the default linker script linker.ld (inside SECTIONS region). If you are not using a linker script, you must create one and add these sections. The memory segment and PHDR should be replaced by -appropriate values. See :zephyr_file:`soc/xtensa/hifi3_bd5/linker.ld` for an example. +appropriate values. The linker script should be named ``linker.ld`` and placed in the directory ``soc/xtensa/${XTENSA_CORE}``. @@ -141,7 +141,7 @@ Configuring build ================= .. zephyr-app-commands:: - :zephyr-app: tests/kernel/test_build + :zephyr-app: samples/hello_world :goals: menuconfig Below is an example of usage for typical configuration: diff --git a/cmake/app/boilerplate.cmake b/cmake/app/boilerplate.cmake index babc7c5a5ca062..ce94841885a2df 100644 --- a/cmake/app/boilerplate.cmake +++ b/cmake/app/boilerplate.cmake @@ -9,10 +9,10 @@ # one of those lines: # # find_package(Zephyr) -# find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) +# find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) # -# The `HINTS $ENV{ZEPHYR_BASE}` variant is required for any application inside -# the Zephyr repository. +# The `REQUIRED HINTS $ENV{ZEPHYR_BASE}` variant is required for any application +# inside the Zephyr repository. # # It exists to reduce boilerplate code that Zephyr expects to be in # application CMakeLists.txt code. @@ -71,10 +71,49 @@ set(__build_dir ${CMAKE_CURRENT_BINARY_DIR}/zephyr) set(PROJECT_BINARY_DIR ${__build_dir}) +if(${CMAKE_VERSION} VERSION_EQUAL 3.19.0 OR + ${CMAKE_VERSION} VERSION_EQUAL 3.19.1) + message(WARNING "CMake 3.19.0/3.19.1 contains a bug regarding Toolchain/compiler " + "testing. Consider switching to a different CMake version.\n" + "See more here: \n" + "- https://github.com/zephyrproject-rtos/zephyr/issues/30232\n" + "- https://gitlab.kitware.com/cmake/cmake/-/issues/21497") + # This is a workaround for #30232. + # During Zephyr CMake invocation a plain C compiler is used for DTS. + # This results in the internal `CheckCompilerFlag.cmake` being included by CMake + # Later, when the full toolchain is configured, then `CMakeCheckCompilerFlag.cmake` is included. + # This overloads the `cmake_check_compiler_flag()` function, thus causing #30232. + # By manualy loading `CMakeCheckCompilerFlag.cmake` then `CheckCompilerFlag.cmake` will overload + # the functions (and thus win the battle), and because `include_guard(GLOBAL)` is used in + # `CMakeCheckCompilerFlag.cmake` this file will not be re-included later. + include(${CMAKE_ROOT}/Modules/Internal/CMakeCheckCompilerFlag.cmake) +endif() + message(STATUS "Application: ${APPLICATION_SOURCE_DIR}") add_custom_target(code_data_relocation_target) +# The zephyr/runners.yaml file in the build directory is used to +# configure the scripts/west_commands/runners Python package used +# by 'west flash', 'west debug', etc. +# +# This is a helper target for setting property:value pairs related to +# this file: +# +# Property Description +# -------------- -------------------------------------------------- +# bin_file "zephyr.bin" file for flashing +# hex_file "zephyr.hex" file for flashing +# elf_file "zephyr.elf" file for flashing or debugging +# yaml_contents generated contents of runners.yaml +# +# Note: there are quotes around "zephyr.bin" etc. because the actual +# paths can be changed, e.g. to flash signed versions of these files +# for consumption by bootloaders such as MCUboot. +# +# See cmake/flash/CMakeLists.txt for more details. +add_custom_target(runners_yaml_props_target) + # CMake's 'project' concept has proven to not be very useful for Zephyr # due in part to how Zephyr is organized and in part to it not fitting well # with cross compilation. @@ -115,9 +154,27 @@ include(${ZEPHYR_BASE}/cmake/version.cmake) # depends on hex.cmake # include(${ZEPHYR_BASE}/cmake/python.cmake) +include(${ZEPHYR_BASE}/cmake/west.cmake) include(${ZEPHYR_BASE}/cmake/git.cmake) # depends on version.cmake include(${ZEPHYR_BASE}/cmake/ccache.cmake) +if(ZEPHYR_EXTRA_MODULES) + # ZEPHYR_EXTRA_MODULES has either been specified on the cmake CLI or is + # already in the CMakeCache.txt. This has precedence over the environment + # variable ZEPHYR_EXTRA_MODULES +elseif(DEFINED ENV{ZEPHYR_EXTRA_MODULES}) + set(ZEPHYR_EXTRA_MODULES $ENV{ZEPHYR_EXTRA_MODULES}) +endif() + +# +# Find Zephyr modules. +# Those may contain additional DTS, BOARD, SOC, ARCH ROOTs. +# Also create the Kconfig binary dir for generated Kconf files. +# +set(KCONFIG_BINARY_DIR ${CMAKE_BINARY_DIR}/Kconfig) +file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}) +include(${ZEPHYR_BASE}/cmake/zephyr_module.cmake) + if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) message(FATAL_ERROR "Source directory equals build directory.\ In-source builds are not supported.\ @@ -274,19 +331,18 @@ set(CACHED_SHIELD ${SHIELD} CACHE STRING "Selected shield") # 'BOARD_ROOT' is a prioritized list of directories where boards may # be found. It always includes ${ZEPHYR_BASE} at the lowest priority. +zephyr_file(APPLICATION_ROOT BOARD_ROOT) list(APPEND BOARD_ROOT ${ZEPHYR_BASE}) -if(NOT SOC_ROOT) - set(SOC_DIR ${ZEPHYR_BASE}/soc) -else() - set(SOC_DIR ${SOC_ROOT}/soc) -endif() +# 'SOC_ROOT' is a prioritized list of directories where socs may be +# found. It always includes ${ZEPHYR_BASE}/soc at the lowest priority. +zephyr_file(APPLICATION_ROOT SOC_ROOT) +list(APPEND SOC_ROOT ${ZEPHYR_BASE}) -if(NOT ARCH_ROOT) - set(ARCH_DIR ${ZEPHYR_BASE}/arch) -else() - set(ARCH_DIR ${ARCH_ROOT}/arch) -endif() +# 'ARCH_ROOT' is a prioritized list of directories where archs may be +# found. It always includes ${ZEPHYR_BASE} at the lowest priority. +zephyr_file(APPLICATION_ROOT ARCH_ROOT) +list(APPEND ARCH_ROOT ${ZEPHYR_BASE}) if(DEFINED SHIELD) string(REPLACE " " ";" SHIELD_AS_LIST "${SHIELD}") @@ -332,6 +388,7 @@ foreach(root ${BOARD_ROOT}) # x_nucleo_iks01a1/x_nucleo_iks01a1.overlay;x_nucleo_iks01a2/x_nucleo_iks01a2.overlay # we construct a list of shield names by extracting file name and # removing the extension. + unset(SHIELD_LIST) foreach(shield_path ${shields_refs_list}) get_filename_component(shield ${shield_path} NAME_WE) list(APPEND SHIELD_LIST ${shield}) @@ -425,13 +482,53 @@ if(DEFINED SHIELD AND NOT (SHIELD-NOTFOUND STREQUAL "")) endif() get_filename_component(BOARD_ARCH_DIR ${BOARD_DIR} DIRECTORY) -get_filename_component(BOARD_FAMILY ${BOARD_DIR} NAME) get_filename_component(ARCH ${BOARD_ARCH_DIR} NAME) -if(CONF_FILE) +foreach(root ${ARCH_ROOT}) + if(EXISTS ${root}/arch/${ARCH}/CMakeLists.txt) + set(ARCH_DIR ${root}/arch) + break() + endif() +endforeach() + +if(NOT ARCH_DIR) + message(FATAL_ERROR "Could not find ARCH=${ARCH} for BOARD=${BOARD}, \ +please check your installation. ARCH roots searched: \n\ +${ARCH_ROOT}") +endif() + +if(DEFINED CONF_FILE) + # This ensures that CACHE{CONF_FILE} will be set correctly to current scope + # variable CONF_FILE. An already current scope variable will stay the same. + set(CONF_FILE ${CONF_FILE}) + # CONF_FILE has either been specified on the cmake CLI or is already # in the CMakeCache.txt. This has precedence over the environment # variable CONF_FILE and the default prj.conf + + # In order to support a `prj_.conf pattern for auto inclusion of board + # overlays, then we must first ensure only a single conf file is provided. + string(REPLACE " " ";" CONF_FILE_AS_LIST "${CONF_FILE}") + list(LENGTH CONF_FILE_AS_LIST CONF_FILE_LENGTH) + if(${CONF_FILE_LENGTH} EQUAL 1) + # Need the file name to look for match. + # Need path in order to check if it is absolute. + get_filename_component(CONF_FILE_NAME ${CONF_FILE} NAME) + get_filename_component(CONF_FILE_DIR ${CONF_FILE} DIRECTORY) + if(${CONF_FILE} MATCHES "prj_(.*).conf") + if(NOT IS_ABSOLUTE ${CONF_FILE_DIR}) + set(CONF_FILE_DIR ${APPLICATION_SOURCE_DIR}/${CONF_FILE_DIR}) + endif() + if(EXISTS ${CONF_FILE_DIR}/boards/${BOARD}_${CMAKE_MATCH_1}.conf) + list(APPEND CONF_FILE ${CONF_FILE_DIR}/boards/${BOARD}_${CMAKE_MATCH_1}.conf) + endif() + endif() + endif() +elseif(CACHED_CONF_FILE) + # Cached conf file is present. + # That value has precedence over anything else than a new + # `cmake -DCONF_FILE=` invocation. + set(CONF_FILE ${CACHED_CONF_FILE}) elseif(DEFINED ENV{CONF_FILE}) set(CONF_FILE $ENV{CONF_FILE}) @@ -449,18 +546,13 @@ elseif(EXISTS ${APPLICATION_SOURCE_DIR}/prj.conf) set(CONF_FILE ${APPLICATION_SOURCE_DIR}/prj.conf) endif() -set(CONF_FILE ${CONF_FILE} CACHE STRING "If desired, you can build the application using\ +set(CACHED_CONF_FILE ${CONF_FILE} CACHE STRING "If desired, you can build the application using\ the configuration settings specified in an alternate .conf file using this parameter. \ These settings will override the settings in the application’s .config file or its default .conf file.\ -Multiple files may be listed, e.g. CONF_FILE=\"prj1.conf prj2.conf\"") - -if(ZEPHYR_EXTRA_MODULES) - # ZEPHYR_EXTRA_MODULES has either been specified on the cmake CLI or is - # already in the CMakeCache.txt. This has precedence over the environment - # variable ZEPHYR_EXTRA_MODULES -elseif(DEFINED ENV{ZEPHYR_EXTRA_MODULES}) - set(ZEPHYR_EXTRA_MODULES $ENV{ZEPHYR_EXTRA_MODULES}) -endif() +Multiple files may be listed, e.g. CONF_FILE=\"prj1.confi;prj2.conf\" \ +The CACHED_CONF_FILE is internal Zephyr variable used between CMake runs. \ +To change CONF_FILE, use the CONF_FILE variable.") +unset(CONF_FILE CACHE) if(DTC_OVERLAY_FILE) # DTC_OVERLAY_FILE has either been specified on the cmake CLI or is already @@ -482,6 +574,13 @@ alternate .overlay file using this parameter. These settings will override the \ settings in the board's .dts file. Multiple files may be listed, e.g. \ DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\"") +# Populate USER_CACHE_DIR with a directory that user applications may +# write cache files to. +if(NOT DEFINED USER_CACHE_DIR) + find_appropriate_cache_directory(USER_CACHE_DIR) +endif() +message(STATUS "Cache files will be written to: ${USER_CACHE_DIR}") + # Prevent CMake from testing the toolchain set(CMAKE_C_COMPILER_FORCED 1) set(CMAKE_CXX_COMPILER_FORCED 1) @@ -504,7 +603,6 @@ include(${BOARD_DIR}/pre_dt_board.cmake OPTIONAL) # preprocess DT sources, and then, after we have finished processing # both DT and Kconfig we complete the target-specific configuration, # and possibly change the toolchain. -include(${ZEPHYR_BASE}/cmake/zephyr_module.cmake) include(${ZEPHYR_BASE}/cmake/generic_toolchain.cmake) include(${ZEPHYR_BASE}/cmake/dts.cmake) include(${ZEPHYR_BASE}/cmake/kconfig.cmake) @@ -519,10 +617,31 @@ else() set(SOC_PATH ${SOC_FAMILY}/${SOC_SERIES}) endif() +# Use SOC to search for a 'CMakeLists.txt' file. +# e.g. zephyr/soc/xtense/intel_apl_adsp/CMakeLists.txt. +foreach(root ${SOC_ROOT}) + if(EXISTS ${root}/soc/${ARCH}/${SOC_PATH}) + set(SOC_DIR ${root}/soc) + break() + endif() +endforeach() + +if(NOT SOC_DIR) + message(FATAL_ERROR "Could not find SOC=${SOC_NAME} for BOARD=${BOARD}, \ +please check your installation. SOC roots searched: \n\ +${SOC_ROOT}") +endif() + include(${ZEPHYR_BASE}/cmake/target_toolchain.cmake) project(Zephyr-Kernel VERSION ${PROJECT_VERSION}) enable_language(C CXX ASM) +# The setup / configuration of the toolchain itself and the configuration of +# supported compilation flags are now split, as this allows to use the toolchain +# for generic purposes, for example DTS, and then test the toolchain for +# supported flags at stage two. +# Testing the toolchain flags requires the enable_language() to have been called in CMake. +include(${ZEPHYR_BASE}/cmake/target_toolchain_flags.cmake) # 'project' sets PROJECT_BINARY_DIR to ${CMAKE_CURRENT_BINARY_DIR}, # but for legacy reasons we need it to be set to @@ -542,13 +661,6 @@ set(KERNEL_EXE_NAME ${KERNEL_NAME}.exe) set(KERNEL_STAT_NAME ${KERNEL_NAME}.stat) set(KERNEL_STRIP_NAME ${KERNEL_NAME}.strip) -# Populate USER_CACHE_DIR with a directory that user applications may -# write cache files to. -if(NOT DEFINED USER_CACHE_DIR) - find_appropriate_cache_directory(USER_CACHE_DIR) -endif() -message(STATUS "Cache files will be written to: ${USER_CACHE_DIR}") - include(${BOARD_DIR}/board.cmake OPTIONAL) # If we are using a suitable ethernet driver inside qemu, then these options @@ -584,6 +696,8 @@ endif() # # Currently used properties: # - COMPILES_OPTIONS: Used by application memory partition feature +# - ${TARGET}_DEPENDENCIES: additional dependencies for targets that need them +# like flash (FLASH_DEPENDENCIES), debug (DEBUG_DEPENDENCIES), etc. add_custom_target(zephyr_property_target) # "app" is a CMake library containing all the application code and is diff --git a/cmake/bintools/arcmwdt/elfconvert_command.cmake b/cmake/bintools/arcmwdt/elfconvert_command.cmake new file mode 100644 index 00000000000000..ac04f09c535fc1 --- /dev/null +++ b/cmake/bintools/arcmwdt/elfconvert_command.cmake @@ -0,0 +1,78 @@ +# For MWDT the elfconvert command is made into a script. +# Reason for that is because not a single command covers all use cases, +# and it must therefore be possible to call individual commands, depending +# on the arguments used. + +# Handle stripping +if (STRIP_DEBUG OR STRIP_ALL) + if(STRIP_ALL) + set(obj_copy_strip "-qs") + elseif(STRIP_DEBUG) + set(obj_copy_strip "-ql") + endif() + + execute_process( + COMMAND ${STRIP} ${obj_copy_strip} + ${INFILE} ${FILEOUT}) +endif() + +# no support of --srec-len in mwdt + +# Handle Input and Output target types +if(DEFINED OUTTARGET) + set(obj_copy_target_output "") + set(obj_copy_gap_fill "") + if(GAP_FILL) + set(obj_copy_gap_fill "-f;${GAP_FILL}") + endif() + # only mwdt's elf2hex supports gap fill + if(${OUTTARGET} STREQUAL "srec") + set(obj_copy_target_output "-m") + elseif(${OUTTARGET} STREQUAL "ihex") + set(obj_copy_target_output "-I") + elseif(${OUTTARGET} STREQUAL "binary") + set(obj_copy_target_output "-B") + endif() + execute_process( + COMMAND ${ELF2HEX} ${obj_copy_gap_fill} ${obj_copy_target_output} + -o ${OUTFILE} ${INFILE} + ) +endif() + +# Handle sections, if any +# 1. Section only selection(s) +set(obj_copy_sections_only "") +if(DEFINED ONLY_SECTION) +# There could be more than one, so need to check all args. + foreach(n RANGE ${CMAKE_ARGC}) + foreach(argument ${CMAKE_ARGV${n}}) + if(${argument} MATCHES "-DONLY_SECTION=(.*)") + list(APPEND obj_copy_sections_only "-sn;${CMAKE_MATCH_1}") + endif() + endforeach() + endforeach() + + execute_process( + COMMAND ${ELF2BIN} -q ${obj_copy_sections_only} + ${INFILE} ${OUTFILE} + ) +endif() + +# no support of rename sections in mwdt, here just use arc-elf32-objcopy temporarily +set(obj_copy_sections_rename "") +if(DEFINED RENAME_SECTION) + foreach(n RANGE ${CMAKE_ARGC}) + foreach(argument ${CMAKE_ARGV${n}}) + if(${argument} MATCHES "-DRENAME_SECTION=(.*)") + list(APPEND obj_copy_sections_rename "--rename-section;${CMAKE_MATCH_1}") + endif() + endforeach() + endforeach() + + execute_process( + COMMAND ${OBJCOPY} ${obj_copy_sections_rename} + ${INFILE} ${OUTFILE} + ) +endif() + +# no support of remove sections diff --git a/cmake/bintools/arcmwdt/target.cmake b/cmake/bintools/arcmwdt/target.cmake new file mode 100644 index 00000000000000..f40e9b64f37a51 --- /dev/null +++ b/cmake/bintools/arcmwdt/target.cmake @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Configures binary tools as mwdt binutils + +find_program(CMAKE_ELF2BIN ${CROSS_COMPILE}elf2bin PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_OBJDUMP ${CROSS_COMPILE}elfdumpac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_AS ${CROSS_COMPILE}ccac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_AR ${CROSS_COMPILE}arac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_RANLIB ${CROSS_COMPILE}arac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_READELF ${CROSS_COMPILE}elfdumpac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_NM ${CROSS_COMPILE}nmac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_STRIP ${CROSS_COMPILE}stripac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_SIZE ${CROSS_COMPILE}sizeac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_ELF2HEX ${CROSS_COMPILE}elf2hex PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + +SET(CMAKE_CXX_ARCHIVE_CREATE " -rq ") +SET(CMAKE_C_ARCHIVE_CREATE " -rq ") +SET(CMAKE_CXX_ARCHIVE_FINISH " -sq ") +SET(CMAKE_C_ARCHIVE_FINISH " -sq ") + +find_program(CMAKE_GDB ${CROSS_COMPILE}mdb PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + +# MWDT binutils don't support required features like section renameing, so we +# temporarily had to use GNU objcopy instead +find_program(CMAKE_OBJCOPY arc-elf32-objcopy) +if (NOT CMAKE_OBJCOPY) + find_program(CMAKE_OBJCOPY arc-linux-objcopy) +endif() + +if (NOT CMAKE_OBJCOPY) + find_program(CMAKE_OBJCOPY objcopy) +endif() + +if(NOT CMAKE_OBJCOPY) + message(FATAL_ERROR "Zephyr unable to find any GNU objcopy (ARC or host one)") +endif() + +include(${ZEPHYR_BASE}/cmake/bintools/arcmwdt/target_bintools.cmake) diff --git a/cmake/bintools/arcmwdt/target_bintools.cmake b/cmake/bintools/arcmwdt/target_bintools.cmake new file mode 100644 index 00000000000000..7c3fbadb060a69 --- /dev/null +++ b/cmake/bintools/arcmwdt/target_bintools.cmake @@ -0,0 +1,103 @@ +# - memusage: Name of command for memusage +# In this implementation `sizeac` is used +set_property(TARGET bintools PROPERTY memusage_command "${CMAKE_SIZE}") +set_property(TARGET bintools PROPERTY memusage_flag "-gq") +set_property(TARGET bintools PROPERTY memusage_infile "") + + +# List of format the tool supports for converting, for example, +# GNU tools uses objectcopyy, which supports the following: ihex, srec, binary +set_property(TARGET bintools PROPERTY elfconvert_formats ihex srec binary) + +# MWDT toolchain does not support all options in a single command +# Therefore a CMake script is used, so that multiple commands can be executed +# successively. +set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_COMMAND}) + +set_property(TARGET bintools PROPERTY elfconvert_flag + -DELF2HEX=${CMAKE_ELF2HEX} + -DELF2BIN=${CMAKE_ELF2BIN} + -DSTRIP=${CMAKE_STRIP} + -DOBJCOPY=${CMAKE_OBJCOPY} +) + +set_property(TARGET bintools PROPERTY elfconvert_flag_final + -P ${CMAKE_CURRENT_LIST_DIR}/elfconvert_command.cmake) + +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_all "-DSTRIP_ALL=True") +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_debug "-DSTRIP_DEBUG=True") + +set_property(TARGET bintools PROPERTY elfconvert_flag_intarget "-DINTARGET=") +set_property(TARGET bintools PROPERTY elfconvert_flag_outtarget "-DOUTTARGET=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "-DREMOVE_SECTION=") +set_property(TARGET bintools PROPERTY elfconvert_flag_section_only "-DONLY_SECTION=") + +# mwdt doesn't handle rename, consider adjusting abstraction. +set_property(TARGET bintools PROPERTY elfconvert_flag_section_rename "-DRENAME_SECTION=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_gapfill "-DGAP_FILL=") +set_property(TARGET bintools PROPERTY elfconvert_flag_srec_len "-DSREC_LEN=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_infile "-DINFILE=") +set_property(TARGET bintools PROPERTY elfconvert_flag_outfile "-DOUTFILE=") + +# - disassembly : Name of command for disassembly of files +# In this implementation `elfdumpac` is used +# disassembly_flag : -T +# disassembly_flag_final : empty +# disassembly_flag_inline_source : -S +# disassembly_flag_all : empty +# disassembly_flag_infile : empty +# disassembly_flag_outfile : '>' +set_property(TARGET bintools PROPERTY disassembly_command ${CMAKE_OBJDUMP}) +set_property(TARGET bintools PROPERTY disassembly_flag -T) +set_property(TARGET bintools PROPERTY disassembly_flag_final "") +set_property(TARGET bintools PROPERTY disassembly_flag_inline_source -S) +set_property(TARGET bintools PROPERTY disassembly_flag_all "") # No support for all ? + +set_property(TARGET bintools PROPERTY disassembly_flag_infile "") +set_property(TARGET bintools PROPERTY disassembly_flag_outfile > ) + +# +# - readelf : Name of command for reading elf files. +# In this implementation `elfdumpac ` is used +# readelf_flag : empty +# readelf_flag_final : empty +# readelf_flag_headers : -qshp +# readelf_flag_infile : empty +# readelf_flag_outfile : '>' + +# This is using elfdumpac from mwdt. +set_property(TARGET bintools PROPERTY readelf_command ${CMAKE_READELF}) + +set_property(TARGET bintools PROPERTY readelf_flag "") +set_property(TARGET bintools PROPERTY readelf_flag_final "") +set_property(TARGET bintools PROPERTY readelf_flag_headers -qshp) + +set_property(TARGET bintools PROPERTY readelf_flag_infile "") +set_property(TARGET bintools PROPERTY readelf_flag_outfile > ) + +# +# - strip: Name of command for stripping symbols +# In this implementation `stripac` is used +# strip_flag : empty +# strip_flag_final : empty +# strip_flag_all : -qls +# strip_flag_debug : -ql +# strip_flag_dwo : empty +# strip_flag_infile : empty +# strip_flag_outfile : -o + +# This is using strip from bintools. +set_property(TARGET bintools PROPERTY strip_command ${CMAKE_STRIP}) + +# Any flag the strip command requires for processing +set_property(TARGET bintools PROPERTY strip_flag "") +set_property(TARGET bintools PROPERTY strip_flag_final "") + +set_property(TARGET bintools PROPERTY strip_flag_all -qls) +set_property(TARGET bintools PROPERTY strip_flag_debug -ql) + +set_property(TARGET bintools PROPERTY strip_flag_infile "") +set_property(TARGET bintools PROPERTY strip_flag_outfile -o ) diff --git a/cmake/bintools/bintools_template.cmake b/cmake/bintools/bintools_template.cmake new file mode 100644 index 00000000000000..39eac715404757 --- /dev/null +++ b/cmake/bintools/bintools_template.cmake @@ -0,0 +1,158 @@ +# This template file can be used as a starting point for implementing support +# for additional tools for reading and/or conversion of elf files. +# +# Although GNU bintools is used as name, then the template can be used to +# support other tools. +# +# Overview of bintools used commands: +# - memusage : Tool for reporting target memory usage +# (if linker support memusage reporting leave this property empty) +# - disassembly : Tool for disassemble the target +# - elfconvert : Tool for converting from elf into another format. +# - readelf : Tool for elf file processing +# - strip : Tool for symnbol stripping +# +# Each tool will have the following minimum properties: +# - _command : Name of executable to call +# - _flag : Flags that must always be used with this command +# - _flag_infile : Flag to use when specifying the file to process +# - _flag_outfile : Flag to use to specify the result of the processing. +# +# each tool might require more flags depending on its use, as example: +# - elfconvert_flag_section_remove : Flag to use when specifying sections to remove +# - readelf_flags_headers : Flag to use to specify headers should be displayed +# +# If a given tool / flag / feature is not supported, then keep the property empty. +# As bintools_template.cmake default has empty flags, then it is sufficient to +# only set those flags that a given set of tools support. +# +# Commands will default echo a message if called, but no command has been defined. +# This is done, so that unexpected calls to non-implemented command can be easily detected. +# To disable the message, simply silence the command with: +# set_property(TARGET bintools PROPERTY _command ${CMAKE_COMMAND} -E echo "") +# +# The bintools properties are made generic so that implementing support for an +# additional native tool should be as easy as possible. +# However, there might be tools and/or use cases where the current property +# scheme does not cover the exact needs. For those use-cases it is possible +# to implement the call to a native tool inside a CMake script. +# For example, to call a custom script for elfconvert command, one can specify: +# set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_COMMAND}) +# set_property(TARGET bintools PROPERTY elfconvert_flag "") +# set_property(TARGET bintools PROPERTY elfconvert_flag_final -P custom_elfconvert.cmake) +# set_property(TARGET bintools PROPERTY elfconvert_flag_strip_all "-DSTRIP_ALL=True") +# set_property(TARGET bintools PROPERTY elfconvert_flag_infile "-DINFILE=") +# set_property(TARGET bintools PROPERTY elfconvert_flag_outfile "-DOUT_FILE=") + +# +# +# bintools property overview of all commands: +# +# Command: +# - memusage : Name of command to execute +# Note: For gcc compilers this command is not used, +# instead a linker flag is used for this) +# memusage_flag : Flags that must always be applied when calling memusage command +# memusage_flag_final : Flags that must always be applied last at the memusage command +# memusage_flag_infile: Flag for specifying the input file +# memusage_byproducts : Byproducts (files) generated when calling memusage +# +# +# - elfconvert : Name of command for elf file conversion. +# For GNU binary utilities this is objcopy +# elfconvert_formats : Formats supported by this command. +# elfconvert_flag : Flags that must always be applied when calling elfconvert command +# elfconvert_flag_final : Flags that must always be applied last at the elfconvert command +# elfconvert_flag_strip_all : Flag that is used for stripping all symbols when converting +# elfconvert_flag_strip_debug : Flag that is used to strip debug symbols when converting +# elfconvert_flag_intarget : Flag for specifying target used for infile +# elfconvert_flag_outtarget : Flag for specifying target to use for converted file. +# Target value must be one of those listed described by: elfconvert_formats +# elfconvert_flag_section_remove: Flag for specifying that following section must be removed +# elfconvert_flag_section_only : Flag for specifying that only the following section should be kept +# elfconvert_flag_section_rename: Flag for specifying that following section must be renamed +# elfconvert_flag_gapfill : Flag for specifying the value to fill in gaps between sections +# elfconvert_flag_srec_len : Flag for specifying maximum length of Srecord values +# elfconvert_flag_infile : Flag for specifying the input file +# elfconvert_flag_outfile : Flag for specifying the output file +# For tools that prints to standard out, this should be ">" to indicate redirection +# +# +# - disassembly : Name of command for disassembly of files +# For GNU binary utilities this is objdump +# disassembly_flag : Flags that must always be applied when calling disassembly command +# disassembly_flag_final : Flags that must always be applied last at the disassembly command +# disassembly_flag_inline_source : Flag to use to display source code mixed with disassembly +# disassembly_flag_all : Flag to use for disassemble everything, including zeroes +# disassembly_flag_infile : Flag for specifying the input file +# disassembly_flag_outfile : Flag for specifying the output file +# For tools that prints to standard out, this should be ">" to indicate redirection +# +# +# - readelf : Name of command for reading elf files. +# For GNU binary utilities this is readelf +# readelf_flag : Flags that must always be applied when calling readelf command +# readelf_flag_final : Flags that must always be applied last at the readelf command +# readelf_flag_headers : Flag to use for specifying ELF headers should be read +# readelf_flag_infile : Flag for specifying the input file +# readelf_flag_outfile : Flag for specifying the output file +# For tools that prints to standard out, this should be ">" to indicate redirection +# +# +# - strip: Name of command for stripping symbols +# For GNU binary utilities this is strip +# strip_flag : Flags that must always be applied when calling strip command +# strip_flag_final : Flags that must always be applied last at the strip command +# strip_flag_all : Flag for removing all symbols +# strip_flag_debug : Flag for removing debug symbols +# strip_flag_dwo : Flag for removing dwarf sections +# strip_flag_infile : Flag for specifying the input file +# strip_flag_outfile : Flag for specifying the output file + +set(COMMAND_NOT_SUPPORTED "command not supported on bintools: ") + +# If memusage is supported as post-build command, set memusage_type to: command +# and this value to the command to execute in the form: +# Note: If memusage is supported during linking, please use: +# set_property(TARGET linker ... ) found in cmake/linker/linker_flags.cmake instead +set_property(TARGET bintools PROPERTY memusage_command "") +set_property(TARGET bintools PROPERTY memusage_flag "") +set_property(TARGET bintools PROPERTY memusage_flag_final "") +set_property(TARGET bintools PROPERTY memusage_byproducts "") + +# disassembly command to use for generation of list file. +set_property(TARGET bintools PROPERTY disassembly_command ${CMAKE_COMMAND} -E echo "disassembly ${COMMAND_NOT_SUPPORTED} ${BINTOOLS}") +set_property(TARGET bintools PROPERTY disassembly_flag "") +set_property(TARGET bintools PROPERTY disassembly_flag_final "") +set_property(TARGET bintools PROPERTY disassembly_flag_inline_source "") +set_property(TARGET bintools PROPERTY disassembly_flag_infile "") +set_property(TARGET bintools PROPERTY disassembly_flag_outfile "") + +# elfconvert to use for transforming an elf file into another format, such as intel hex, s-rec, binary, etc. +set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_COMMAND} -E echo "elfconvert ${COMMAND_NOT_SUPPORTED} ${BINTOOLS}") +set_property(TARGET bintools PROPERTY elfconvert_formats "") +set_property(TARGET bintools PROPERTY elfconvert_flag "") +set_property(TARGET bintools PROPERTY elfconvert_flag_final "") +set_property(TARGET bintools PROPERTY elfconvert_flag_outtarget "") +set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "") +set_property(TARGET bintools PROPERTY elfconvert_flag_gapfill "") +set_property(TARGET bintools PROPERTY elfconvert_flag_infile "") +set_property(TARGET bintools PROPERTY elfconvert_flag_outfile "") + +# readelf for processing of elf files. +set_property(TARGET bintools PROPERTY readelf_command ${CMAKE_COMMAND} -E echo "readelf ${COMMAND_NOT_SUPPORTED} ${BINTOOLS}") +set_property(TARGET bintools PROPERTY readelf_flag "") +set_property(TARGET bintools PROPERTY readelf_flag_final "") +set_property(TARGET bintools PROPERTY readelf_flag_headers "") +set_property(TARGET bintools PROPERTY readelf_flag_infile "") +set_property(TARGET bintools PROPERTY readelf_flag_outfile "") + +# strip command for stripping symbols +set_property(TARGET bintools PROPERTY strip_command ${CMAKE_COMMAND} -E echo "strip ${COMMAND_NOT_SUPPORTED} ${BINTOOLS}") +set_property(TARGET bintools PROPERTY strip_flag "") +set_property(TARGET bintools PROPERTY strip_flag_final "") +set_property(TARGET bintools PROPERTY strip_flag_all "") +set_property(TARGET bintools PROPERTY strip_flag_debug "") +set_property(TARGET bintools PROPERTY strip_flag_dwo "") +set_property(TARGET bintools PROPERTY strip_flag_infile "") +set_property(TARGET bintools PROPERTY strip_flag_outfile "") diff --git a/cmake/bintools/gnu/target.cmake b/cmake/bintools/gnu/target.cmake index 85aca7aa4cb9b1..65b63c507ea860 100644 --- a/cmake/bintools/gnu/target.cmake +++ b/cmake/bintools/gnu/target.cmake @@ -9,13 +9,10 @@ find_program(CMAKE_AR ${CROSS_COMPILE}ar PATHS ${TOOLCHAIN_HOME} NO_DE find_program(CMAKE_RANLIB ${CROSS_COMPILE}ranlib PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) find_program(CMAKE_READELF ${CROSS_COMPILE}readelf PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) find_program(CMAKE_NM ${CROSS_COMPILE}nm PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_STRIP ${CROSS_COMPILE}strip PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) find_program(CMAKE_GDB ${CROSS_COMPILE}gdb PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) find_program(CMAKE_GDB gdb-multiarch PATHS ${TOOLCHAIN_HOME} ) -# Include bin tool abstraction macros -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_memusage.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_objcopy.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_objdump.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_readelf.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_strip.cmake) +# Include bin tool properties +include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_bintools.cmake) diff --git a/cmake/bintools/gnu/target_bintools.cmake b/cmake/bintools/gnu/target_bintools.cmake new file mode 100644 index 00000000000000..6cc27b70a90db6 --- /dev/null +++ b/cmake/bintools/gnu/target_bintools.cmake @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# - elfconvert : Name of command for elf file conversion. +# In this implementation `objcopy` is used +# elfconvert_formats : Formats supported: ihex, srec, binary +# elfconvert_flag : empty +# elfconvert_flag_final : empty +# elfconvert_flag_strip_all : -S +# elfconvert_flag_strip_debug : -g +# elfconvert_flag_intarget : --input-target= +# elfconvert_flag_outtarget : --output-target= +# elfconvert_flag_section_remove: --remove-section= +# elfconvert_flag_section_only : --only-section= +# elfconvert_flag_section_rename: --rename-section; +# elfconvert_flag_gapfill : --gap-fill; +# Note: The ';' will be transformed into an +# empty space when executed +# elfconvert_flag_srec_len : --srec-len= +# elfconvert_flag_infile : empty, objcopy doesn't take arguments for filenames +# elfconvert_flag_outfile : empty, objcopy doesn't take arguments for filenames +# + +# elfconvert to use for transforming an elf file into another format, +# such as intel hex, s-rec, binary, etc. +set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_OBJCOPY}) + +# List of format the tool supports for converting, for example, +# GNU tools uses objectcopyy, which supports the following: ihex, srec, binary +set_property(TARGET bintools PROPERTY elfconvert_formats ihex srec binary) + +set_property(TARGET bintools PROPERTY elfconvert_flag "") +set_property(TARGET bintools PROPERTY elfconvert_flag_final "") + +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_all "-S") +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_debug "-g") + +set_property(TARGET bintools PROPERTY elfconvert_flag_intarget "--input-target=") +set_property(TARGET bintools PROPERTY elfconvert_flag_outtarget "--output-target=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "--remove-section=") +set_property(TARGET bintools PROPERTY elfconvert_flag_section_only "--only-section=") +set_property(TARGET bintools PROPERTY elfconvert_flag_section_rename "--rename-section;") + +# Note, placing a ';' at the end results in the following param to be a list, +# and hence space separated. +# Thus the command line argument becomes: +# `--gap-file ` instead of `--gap-fill` (The latter would result in an error) +set_property(TARGET bintools PROPERTY elfconvert_flag_gapfill "--gap-fill;") +set_property(TARGET bintools PROPERTY elfconvert_flag_srec_len "--srec-len=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_infile "") +set_property(TARGET bintools PROPERTY elfconvert_flag_outfile "") + +# +# - disassembly : Name of command for disassembly of files +# In this implementation `objdump` is used +# disassembly_flag : -d +# disassembly_flag_final : empty +# disassembly_flag_inline_source : -S +# disassembly_flag_all : -SDz +# disassembly_flag_infile : empty, objdump doesn't take arguments for filenames +# disassembly_flag_outfile : '>', objdump doesn't take arguments for output file, but result is printed to standard out, and is redirected. + +set_property(TARGET bintools PROPERTY disassembly_command ${CMAKE_OBJDUMP}) +set_property(TARGET bintools PROPERTY disassembly_flag -d) +set_property(TARGET bintools PROPERTY disassembly_flag_final "") +set_property(TARGET bintools PROPERTY disassembly_flag_inline_source -S) +set_property(TARGET bintools PROPERTY disassembly_flag_all -SDz) + +set_property(TARGET bintools PROPERTY disassembly_flag_infile "") +set_property(TARGET bintools PROPERTY disassembly_flag_outfile ">;" ) + +# +# - strip: Name of command for stripping symbols +# In this implementation `strip` is used +# strip_flag : empty +# strip_flag_final : empty +# strip_flag_all : --strip-all +# strip_flag_debug : --strip-debug +# strip_flag_dwo : --strip-dwo +# strip_flag_infile : empty, strip doesn't take arguments for input file +# strip_flag_outfile : -o + +# This is using strip from bintools. +set_property(TARGET bintools PROPERTY strip_command ${CMAKE_STRIP}) + +# Any flag the strip command requires for processing +set_property(TARGET bintools PROPERTY strip_flag "") +set_property(TARGET bintools PROPERTY strip_flag_final "") + +set_property(TARGET bintools PROPERTY strip_flag_all --strip-all) +set_property(TARGET bintools PROPERTY strip_flag_debug --strip-debug) +set_property(TARGET bintools PROPERTY strip_flag_dwo --strip-dwo) + +set_property(TARGET bintools PROPERTY strip_flag_infile "") +set_property(TARGET bintools PROPERTY strip_flag_outfile -o ) + +# +# - readelf : Name of command for reading elf files. +# In this implementation `readelf` is used +# readelf_flag : empty +# readelf_flag_final : empty +# readelf_flag_headers : -e +# readelf_flag_infile : empty, readelf doesn't take arguments for filenames +# readelf_flag_outfile : '>', readelf doesn't take arguments for output +# file, but result is printed to standard out, and +# is redirected. + +# This is using readelf from bintools. +set_property(TARGET bintools PROPERTY readelf_command ${CMAKE_READELF}) + +set_property(TARGET bintools PROPERTY readelf_flag "") +set_property(TARGET bintools PROPERTY readelf_flag_final "") +set_property(TARGET bintools PROPERTY readelf_flag_headers -e) + +set_property(TARGET bintools PROPERTY readelf_flag_infile "") +set_property(TARGET bintools PROPERTY readelf_flag_outfile ">;" ) + +# Example on how to support dwarfdump instead of readelf +#set_property(TARGET bintools PROPERTY readelf_command dwarfdump) +#set_property(TARGET bintools PROPERTY readelf_flag "") +#set_property(TARGET bintools PROPERTY readelf_flag_headers -E) +#set_property(TARGET bintools PROPERTY readelf_flag_infile "") +#set_property(TARGET bintools PROPERTY readelf_flag_outfile "-O file=" ) diff --git a/cmake/bintools/gnu/target_memusage.cmake b/cmake/bintools/gnu/target_memusage.cmake deleted file mode 100644 index 3e3408021a7d02..00000000000000 --- a/cmake/bintools/gnu/target_memusage.cmake +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# Add and/or prepare print of memory usage report -# -# Usage: -# bintools_print_mem_usage( -# RESULT_CMD_LIST -# RESULT_BYPROD_LIST -# ) -# -macro(bintools_print_mem_usage) - - # Here we make use of the linkers ability to produce memory usage output - # and thus we have no need for the above provided arguments, but another - # toolchain with a different set of binary tools, most likely will... - # - # Use --print-memory-usage with the first link. - # - # Don't use this option with the second link because seeing it twice - # could confuse users and using it on the second link would suppress - # it when the first link has a ram/flash-usage issue. - set(option ${LINKERFLAGPREFIX},--print-memory-usage) - string(MAKE_C_IDENTIFIER check${option} check) - - set(SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${option}") - zephyr_check_compiler_flag(C "" ${check}) - set(CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS}) - - target_link_libraries_ifdef(${check} ${ZEPHYR_PREBUILT_EXECUTABLE} ${option}) - -endmacro(bintools_print_mem_usage) diff --git a/cmake/bintools/gnu/target_objcopy.cmake b/cmake/bintools/gnu/target_objcopy.cmake deleted file mode 100644 index 703e06806747e3..00000000000000 --- a/cmake/bintools/gnu/target_objcopy.cmake +++ /dev/null @@ -1,126 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# Construct a commandline suitable for calling the toolchain binary tools -# version of objcopy. -# -# Usage: -# bintools_objcopy( -# RESULT_CMD_LIST -# RESULT_BYPROD_LIST -# -# STRIP_ALL -# STRIP_DEBUG -# -# TARGET_INPUT -# TARGET_OUTPUT -# -# GAP_FILL -# SREC_LEN -# -# SECTION_ONLY -# SECTION_REMOVE -# SECTION_RENAME -# -# FILE_INPUT -# FILE_OUTPUT -# ) -function(bintools_objcopy) - cmake_parse_arguments( - # Prefix of output variables - BINTOOLS_OBJCOPY - # List of argument names without values, hence boolean - "STRIP_ALL;STRIP_DEBUG" - # List of argument names with one value - "RESULT_CMD_LIST;RESULT_BYPROD_LIST;TARGET_INPUT;TARGET_OUTPUT;GAP_FILL;SREC_LEN;FILE_INPUT;FILE_OUTPUT" - # List of argument names with multible values - "SECTION_ONLY;SECTION_RENAME;SECTION_REMOVE" - # Parser input - ${ARGN} - ) - - # Verify arguments - if(NOT DEFINED BINTOOLS_OBJCOPY_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_OBJCOPY_RESULT_CMD_LIST}) - message(FATAL_ERROR "RESULT_CMD_LIST is required.") - elseif(NOT DEFINED BINTOOLS_OBJCOPY_FILE_INPUT OR NOT DEFINED BINTOOLS_OBJCOPY_FILE_OUTPUT) - message(FATAL_ERROR "Both FILE_INPUT and FILE_OUTPUT is required.") - endif() - - # Handle stripping - set(obj_copy_strip "") - if(${BINTOOLS_OBJCOPY_STRIP_ALL}) - set(obj_copy_strip "-S") - elseif(${BINTOOLS_OBJCOPY_STRIP_DEBUG}) - set(obj_copy_strip "-g") - endif() - - # Handle gap filling - set(obj_copy_gap_fill "") - if(DEFINED BINTOOLS_OBJCOPY_GAP_FILL) - set(obj_copy_gap_fill "--gap-fill;${BINTOOLS_OBJCOPY_GAP_FILL}") - endif() - - # Handle srec len, but only if target output is srec - set(obj_copy_srec_len "") - if(DEFINED BINTOOLS_OBJCOPY_SREC_LEN) - if(NOT ${BINTOOLS_OBJCOPY_TARGET_OUTPUT} STREQUAL "srec") - message(WARNING "Ignoring srec len, for non srec target: ${BINTOOLS_OBJCOPY_TARGET_OUTPUT}") - else() - set(obj_copy_srec_len "--srec-len;${BINTOOLS_OBJCOPY_SREC_LEN}") - endif() - endif() - - # Handle Input and Output target types - set(obj_copy_target_input "") - if(DEFINED BINTOOLS_OBJCOPY_TARGET_INPUT) - set(obj_copy_target_input "--input-target=${BINTOOLS_OBJCOPY_TARGET_INPUT}") - endif() - set(obj_copy_target_output "") - if(DEFINED BINTOOLS_OBJCOPY_TARGET_OUTPUT) - set(obj_copy_target_output "--output-target=${BINTOOLS_OBJCOPY_TARGET_OUTPUT}") - endif() - - # Handle sections, if any - # 1. Section only selection(s) - set(obj_copy_sections_only "") - if(DEFINED BINTOOLS_OBJCOPY_SECTION_ONLY) - foreach(section_only ${BINTOOLS_OBJCOPY_SECTION_ONLY}) - list(APPEND obj_copy_sections_only "--only-section=${section_only}") - endforeach() - endif() - - # 2. Section rename selection(s) - set(obj_copy_sections_rename "") - if(DEFINED BINTOOLS_OBJCOPY_SECTION_RENAME) - foreach(section_rename ${BINTOOLS_OBJCOPY_SECTION_RENAME}) - if(NOT ${section_rename} MATCHES "^.*=.*$") - message(FATAL_ERROR "Malformed section renaming. Must be from=to, have ${section_rename}") - else() - list(APPEND obj_copy_sections_rename "--rename-section;${section_rename}") - endif() - endforeach() - endif() - - # 3. Section remove selection(s) - set(obj_copy_sections_remove "") - if(DEFINED BINTOOLS_OBJCOPY_SECTION_REMOVE) - foreach(section_remove ${BINTOOLS_OBJCOPY_SECTION_REMOVE}) - list(APPEND obj_copy_sections_remove "--remove-section=${section_remove}") - endforeach() - endif() - - # Construct the command - set(obj_copy_cmd - # Base command - COMMAND ${CMAKE_OBJCOPY} ${obj_copy_strip} ${obj_copy_gap_fill} ${obj_copy_srec_len} - # Input and Output target types - ${obj_copy_target_input} ${obj_copy_target_output} - # Sections - ${obj_copy_sections_only} ${obj_copy_sections_rename} ${obj_copy_sections_remove} - # Input and output files - ${BINTOOLS_OBJCOPY_FILE_INPUT} ${BINTOOLS_OBJCOPY_FILE_OUTPUT} - ) - - # Place command in the parent provided variable - set(${BINTOOLS_OBJCOPY_RESULT_CMD_LIST} ${obj_copy_cmd} PARENT_SCOPE) - -endfunction(bintools_objcopy) diff --git a/cmake/bintools/gnu/target_objdump.cmake b/cmake/bintools/gnu/target_objdump.cmake deleted file mode 100644 index f223958fd3ea58..00000000000000 --- a/cmake/bintools/gnu/target_objdump.cmake +++ /dev/null @@ -1,66 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# Construct a commandline suitable for calling the toolchain binary tools -# version of objdump. -# -# Usage: -# bintools_objdump( -# RESULT_CMD_LIST -# RESULT_BYPROD_LIST -# -# DISASSEMBLE -# DISASSEMBLE_SOURCE < Display source code intermixed with disassembly, if possible> -# DISASSEMBLE_ALL -# -# FILE_INPUT -# FILE_OUTPUT -# ) -function(bintools_objdump) - cmake_parse_arguments( - # Prefix of output variables - BINTOOLS_OBJDUMP - # List of argument names without values, hence boolean - "DISASSEMBLE;DISASSEMBLE_SOURCE;DISASSEMBLE_ALL" - # List of argument names with one value - "RESULT_CMD_LIST;RESULT_BYPROD_LIST;FILE_INPUT;FILE_OUTPUT" - # List of argument names with multible values - "" - # Parser input - ${ARGN} - ) - - # Verify arguments - if(NOT DEFINED BINTOOLS_OBJDUMP_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_OBJDUMP_RESULT_CMD_LIST}) - message(FATAL_ERROR "RESULT_CMD_LIST is required.") - elseif(NOT DEFINED BINTOOLS_OBJDUMP_FILE_INPUT) - message(FATAL_ERROR "FILE_INPUT is required.") - endif() - - # Handle disassembly - set(obj_dump_disassemble "") - if(${BINTOOLS_OBJDUMP_DISASSEMBLE_SOURCE}) - set(obj_dump_disassemble "-S") # --source - elseif(${BINTOOLS_OBJDUMP_DISASSEMBLE}) - set(obj_dump_disassemble "-d") # --disassemble - elseif(${BINTOOLS_OBJDUMP_DISASSEMBLE_ALL}) - set(obj_dump_disassemble "-SDz") # --source --disassemble-all --disassemble-zeroes - endif() - - # Handle output - set(obj_dump_output "") - if(DEFINED BINTOOLS_OBJDUMP_FILE_OUTPUT) - set(obj_dump_output > ${BINTOOLS_OBJDUMP_FILE_OUTPUT}) - endif() - - # Construct the command - set(obj_dump_cmd - # Base command - COMMAND ${CMAKE_OBJDUMP} ${obj_dump_disassemble} - # Input and Output - ${BINTOOLS_OBJDUMP_FILE_INPUT} ${obj_dump_output} - ) - - # Place command in the parent provided variable - set(${BINTOOLS_OBJDUMP_RESULT_CMD_LIST} ${obj_dump_cmd} PARENT_SCOPE) - -endfunction(bintools_objdump) diff --git a/cmake/bintools/gnu/target_readelf.cmake b/cmake/bintools/gnu/target_readelf.cmake deleted file mode 100644 index 6db3f45c38d10b..00000000000000 --- a/cmake/bintools/gnu/target_readelf.cmake +++ /dev/null @@ -1,60 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# Construct a commandline suitable for calling the toolchain binary tools -# version of readelf. -# -# Usage: -# bintools_readelf( -# RESULT_CMD_LIST -# RESULT_BYPROD_LIST -# -# HEADERS -# -# FILE_INPUT -# FILE_OUTPUT -# ) -function(bintools_readelf) - cmake_parse_arguments( - # Prefix of output variables - BINTOOLS_READELF - # List of argument names without values, hence boolean - "HEADERS" - # List of argument names with one value - "RESULT_CMD_LIST;RESULT_BYPROD_LIST;FILE_INPUT;FILE_OUTPUT" - # List of argument names with multible values - "" - # Parser input - ${ARGN} - ) - - # Verify arguments - if(NOT DEFINED BINTOOLS_READELF_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_READELF_RESULT_CMD_LIST}) - message(FATAL_ERROR "RESULT_CMD_LIST is required.") - elseif(NOT DEFINED BINTOOLS_READELF_FILE_INPUT) - message(FATAL_ERROR "FILE_INPUT is required.") - endif() - - # Handle headers - set(readelf_headers "") - if(${BINTOOLS_READELF_HEADERS}) - set(readelf_headers "-e") # --headers - endif() - - # Handle output - set(readelf_output "") - if(DEFINED BINTOOLS_READELF_FILE_OUTPUT) - set(readelf_output > ${BINTOOLS_READELF_FILE_OUTPUT}) - endif() - - # Construct the command - set(readelf_cmd - # Base command - COMMAND ${CMAKE_READELF} ${readelf_headers} - # Input and Output - ${BINTOOLS_READELF_FILE_INPUT} ${readelf_output} - ) - - # Place command in the parent provided variable - set(${BINTOOLS_READELF_RESULT_CMD_LIST} ${readelf_cmd} PARENT_SCOPE) - -endfunction(bintools_readelf) diff --git a/cmake/bintools/gnu/target_strip.cmake b/cmake/bintools/gnu/target_strip.cmake deleted file mode 100644 index 08244f17f89f00..00000000000000 --- a/cmake/bintools/gnu/target_strip.cmake +++ /dev/null @@ -1,62 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# Construct a commandline suitable for calling the toolchain binary tools -# version of strip. -# -# Usage: -# bintools_strip( -# RESULT_CMD_LIST -# RESULT_BYPROD_LIST -# -# STRIP_ALL -# STRIP_DEBUG -# STRIP_DWO -# -# FILE_INPUT -# FILE_OUTPUT -# ) -function(bintools_strip) - cmake_parse_arguments( - # Prefix of output variables - BINTOOLS_STRIP - # List of argument names without values, hence boolean - "STRIP_ALL;STRIP_DEBUG;STRIP_DWO" - # List of argument names with one value - "RESULT_CMD_LIST;RESULT_BYPROD_LIST;FILE_INPUT;FILE_OUTPUT" - # List of argument names with multible values - "" - # Parser input - ${ARGN} - ) - - if(NOT DEFINED BINTOOLS_STRIP_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_STRIP_RESULT_CMD_LIST}) - message(FATAL_ERROR "RESULT_CMD_LIST is required.") - elseif(NOT DEFINED BINTOOLS_STRIP_FILE_INPUT OR NOT DEFINED BINTOOLS_STRIP_FILE_OUTPUT) - message(FATAL_ERROR "Both FILE_INPUT and FILE_OUTPUT are required.") - endif() - - # Handle stripping - set(strip_what "") - if(${BINTOOLS_STRIP_STRIP_ALL}) - set(strip_what "--strip-all") - elseif(${BINTOOLS_STRIP_STRIP_DEBUG}) - set(strip_what "--strip-debug") - elseif(${BINTOOLS_STRIP_STRIP_DWO}) - set(strip_what "--strip-dwo") - endif() - - # Handle output - set(strip_output -o ${BINTOOLS_STRIP_FILE_OUTPUT}) - - # Construct the command - set(strip_cmd - # Base command - COMMAND ${CMAKE_STRIP} ${strip_what} - # Input and Output - ${BINTOOLS_STRIP_FILE_INPUT} ${strip_output} - ) - - # Place command in the parent provided variable - set(${BINTOOLS_STRIP_RESULT_CMD_LIST} ${strip_cmd} PARENT_SCOPE) - -endfunction(bintools_strip) diff --git a/cmake/bintools/host-gnu/target.cmake b/cmake/bintools/host-gnu/target.cmake index 82da57ccb3f6e1..37d5c942e63963 100644 --- a/cmake/bintools/host-gnu/target.cmake +++ b/cmake/bintools/host-gnu/target.cmake @@ -10,9 +10,5 @@ find_program(CMAKE_READELF readelf) find_program(CMAKE_GDB gdb ) -# Use the gnu binutil abstraction macros -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_memusage.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_objcopy.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_objdump.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_readelf.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_strip.cmake) +# Include bin tool properties +include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_bintools.cmake) diff --git a/cmake/bintools/llvm/target.cmake b/cmake/bintools/llvm/target.cmake index 9a99860abc976a..8aab91f69d916c 100644 --- a/cmake/bintools/llvm/target.cmake +++ b/cmake/bintools/llvm/target.cmake @@ -14,9 +14,5 @@ find_program(CMAKE_RANLIB llvm-ranlib ${find_program_clang_args} ) find_program(CMAKE_OBJCOPY objcopy ${find_program_binutils_args}) find_program(CMAKE_READELF readelf ${find_program_binutils_args}) -# Use the gnu binutil abstraction macros -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_memusage.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_objcopy.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_objdump.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_readelf.cmake) -include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_strip.cmake) +# Use the gnu binutil abstraction +include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_bintools.cmake) diff --git a/cmake/compiler/arcmwdt/compiler_flags.cmake b/cmake/compiler/arcmwdt/compiler_flags.cmake new file mode 100644 index 00000000000000..6fc83e4e1d36dc --- /dev/null +++ b/cmake/compiler/arcmwdt/compiler_flags.cmake @@ -0,0 +1,181 @@ +set_property(GLOBAL PROPERTY CSTD gnu99) + +# List the warnings that are not supported for C++ compilations +list(APPEND CXX_EXCLUDED_OPTIONS + -Werror=implicit-int + -Wold-style-definition + ) + +################################################### +# Setting compiler properties for MWDT compilers. # +################################################### + +##################################################### +# This section covers flags related to optimization # +##################################################### +set_compiler_property(PROPERTY no_optimization -O0) +set_compiler_property(PROPERTY optimization_debug -O0) +set_compiler_property(PROPERTY optimization_speed -O2) +set_compiler_property(PROPERTY optimization_size -Os) + +####################################################### +# This section covers flags related to warning levels # +####################################################### + +# options for warnings +# base options +set_compiler_property(PROPERTY warning_base + -Wformat + -Wformat-security + -Wno-format-zero-length + -Wno-main-return-type + -Wno-unaligned-pointer-conversion + -Wno-incompatible-pointer-types-discards-qualifiers + -Wno-typedef-redefinition +) + +check_set_compiler_property(APPEND PROPERTY warning_base -Wno-pointer-sign) + +# Prohibit void pointer arithmetic. Illegal in C99 +check_set_compiler_property(APPEND PROPERTY warning_base -Wpointer-arith) + +# level 1 warning options +set_compiler_property(PROPERTY warning_dw_1 + -Wextra + -Wunused + -Wno-unused-parameter + -Wmissing-declarations + -Wmissing-format-attribute +) + +check_set_compiler_property(APPEND PROPERTY warning_dw_1 + -Wold-style-definition + -Wmissing-prototypes + -Wmissing-include-dirs + -Wunused-but-set-variable + -Wno-missing-field-initializers +) + +# level 2 warning options +set_compiler_property(PROPERTY warning_dw_2 + -Waggregate-return + -Wcast-align + -Wdisabled-optimization + -Wnested-externs + -Wshadow +) + +check_set_compiler_property(APPEND PROPERTY warning_dw_2 + -Wlogical-op + -Wmissing-field-initializers +) + +# level 3 warning options +set_compiler_property(PROPERTY warning_dw_3 + -Wbad-function-cast + -Wcast-qual + -Wconversion + -Wpacked + -Wpadded + -Wpointer-arith + -Wredundant-decls + -Wswitch-default +) + +check_set_compiler_property(APPEND PROPERTY warning_dw_3 + -Wpacked-bitfield-compat + -Wvla +) + +# extended warning options +check_set_compiler_property(PROPERTY warning_extended + -Wno-sometimes-uninitialized + -Wno-shift-overflow + -Wno-missing-braces + -Wno-self-assign + -Wno-address-of-packed-member + -Wno-unused-function + -Wno-initializer-overrides + -Wno-section + -Wno-unknown-warning-option + -Wno-unused-variable + -Wno-format-invalid-specifier + -Wno-gnu + # comparison of unsigned expression < 0 is always false + -Wno-tautological-compare +) + +check_set_compiler_property(PROPERTY warning_error_implicit_int -Werror=implicit-int) + +set_compiler_property(PROPERTY warning_error_misra_sane -Werror=vla) + +########################################################################### +# This section covers flags related to C or C++ standards / standard libs # +########################################################################### + +set_compiler_property(PROPERTY cstd -std=) + +if (NOT CONFIG_NEWLIB_LIBC AND + NOT CONFIG_NATIVE_APPLICATION) + set_compiler_property(PROPERTY nostdinc -Hno_default_include -Hnoarcexlib) + set_compiler_property(APPEND PROPERTY nostdinc_include ${NOSTDINC}) +endif() + + +# C++ std options +set_property(TARGET compiler-cpp PROPERTY dialect_cpp98 "-std=c++98") +set_property(TARGET compiler-cpp PROPERTY dialect_cpp11 "-std=c++11") + +#no support of C++14, C++17, C++2a +set_property(TARGET compiler-cpp PROPERTY dialect_cpp14 "") +set_property(TARGET compiler-cpp PROPERTY dialect_cpp17 "") +set_property(TARGET compiler-cpp PROPERTY dialect_cpp2a "") + +# Disable exeptions flag in C++ +set_property(TARGET compiler-cpp PROPERTY no_exceptions "-fno-exceptions") + +# Disable rtti in C++ +set_property(TARGET compiler-cpp PROPERTY no_rtti "-fno-rtti") + +################################################### +# This section covers all remaining C / C++ flags # +################################################### + +# mwdt flag for a freestanding application +# do not link in supplied run-time startup files +set_compiler_property(PROPERTY freestanding -Hnocrt) + +# Flag to enable debugging +set_compiler_property(PROPERTY debug -g) + +# compile common globals like normal definitions +set_compiler_property(PROPERTY no_common -fno-common) + +# mwdt's coverage mechanism is different with gnu +# at present, zephyr only support gnu coverage +set_compiler_property(PROPERTY coverage "") + +# mwdt compiler flags for imacros. The specific header must be appended by user. +set_compiler_property(PROPERTY imacros -imacros) + +#no support of -fsanitize=address and -lasan +set_compiler_property(PROPERTY sanitize_address "") + +set_compiler_property(PROPERTY sanitize_undefined "") + +# Security canaries. +#no support of -mstack-protector-guard=global" +set_compiler_property(PROPERTY security_canaries -fstack-protector-all) + +#no support of _FORTIFY_SOURCE" +set_compiler_property(PROPERTY security_fortify "") + +# Required C++ flags when using mwdt +set_property(TARGET compiler-cpp PROPERTY required "") + +################################# +# This section covers asm flags # +################################# + +# Required ASM flags when using mwdt +set_property(TARGET asm PROPERTY required "-Hasmcpp") diff --git a/cmake/compiler/arcmwdt/generic.cmake b/cmake/compiler/arcmwdt/generic.cmake new file mode 100644 index 00000000000000..ceda135f257bea --- /dev/null +++ b/cmake/compiler/arcmwdt/generic.cmake @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Configures CMake for using ccac + +# MWDT compiler (CCAC) can't be used for preprocessing the DTS sources as it has +# weird restrictions about file extensions. Synopsys Jira issue: P10019563-38578 +# Let's temporarily use GNU compiler instead. +find_program(CMAKE_DTS_PREPROCESSOR arc-elf32-gcc) +if (NOT CMAKE_DTS_PREPROCESSOR) + find_program(CMAKE_DTS_PREPROCESSOR arc-linux-gcc) +endif() + +if (NOT CMAKE_DTS_PREPROCESSOR) + find_program(CMAKE_DTS_PREPROCESSOR gcc) +endif() + +if(NOT CMAKE_DTS_PREPROCESSOR) + message(FATAL_ERROR "Zephyr was unable to find any GNU compiler (ARC or host one) for DTS preprocessing") +endif() + +find_program(CMAKE_C_COMPILER ${CROSS_COMPILE}ccac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + +if(CMAKE_C_COMPILER STREQUAL CMAKE_C_COMPILER-NOTFOUND) + message(FATAL_ERROR "Zephyr was unable to find the Metaware compiler") +endif() + +execute_process( + COMMAND ${CMAKE_C_COMPILER} --version + RESULT_VARIABLE ret + OUTPUT_QUIET + ERROR_QUIET + ) + +if(ret) + message(FATAL_ERROR "Executing the below command failed. Are permissions set correctly? + '${CMAKE_C_COMPILER} --version'" + ) +endif() diff --git a/cmake/compiler/arcmwdt/target.cmake b/cmake/compiler/arcmwdt/target.cmake new file mode 100644 index 00000000000000..8c6def51e16dbc --- /dev/null +++ b/cmake/compiler/arcmwdt/target.cmake @@ -0,0 +1,41 @@ +# find the compilers for C, CPP, assembly +find_program(CMAKE_C_COMPILER ${CROSS_COMPILE}ccac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_CXX_COMPILER ${CROSS_COMPILE}ccac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_ASM_COMPILER ${CROSS_COMPILE}ccac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +# The CMAKE_REQUIRED_FLAGS variable is used by check_c_compiler_flag() +# (and other commands which end up calling check_c_source_compiles()) +# to add additional compiler flags used during checking. These flags +# are unused during "real" builds of Zephyr source files linked into +# the final executable. +# +# Appending onto any existing values lets users specify +# toolchain-specific flags at generation time. +list(APPEND CMAKE_REQUIRED_FLAGS + -c + -HL + -Hnosdata + -Hnolib + -Hnocrt + -Hnoentry + -Hldopt=-Bbase=0x0 # Set an entry point to avoid a warning + -Werror + ) +string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + +set(NOSTDINC "") + +list(APPEND NOSTDINC ${TOOLCHAIN_HOME}/arc/inc) + +# For CMake to be able to test if a compiler flag is supported by the +# toolchain we need to give CMake the necessary flags to compile and +# link a dummy C file. +# +# CMake checks compiler flags with check_c_compiler_flag() (Which we +# wrap with target_cc_option() in extentions.cmake) +foreach(isystem_include_dir ${NOSTDINC}) + list(APPEND isystem_include_flags -isystem "\"${isystem_include_dir}\"") +endforeach() + +# common compile options, no copyright msg, little-endian, no small data, +# no MWDT stack checking +list(APPEND TOOLCHAIN_C_FLAGS -Hnocopyr -HL -Hnosdata -Hoff=Stackcheck_alloca) diff --git a/cmake/compiler/clang/compiler_flags.cmake b/cmake/compiler/clang/compiler_flags.cmake new file mode 100644 index 00000000000000..1cae6fb29b54c0 --- /dev/null +++ b/cmake/compiler/clang/compiler_flags.cmake @@ -0,0 +1,104 @@ +# First step is to inherit all properties from gcc, as clang is compatible with most flags. +include(${ZEPHYR_BASE}/cmake/compiler/gcc/compiler_flags.cmake) + +# Now, let's overwrite the flags that are different in clang. + +# No property flag, clang doesn't understand fortify at all +set_compiler_property(PROPERTY security_fortify) + +# No property flag, this is used by the native_posix, clang has problems +# compiling the native_posix with -fno-freestanding. +check_set_compiler_property(PROPERTY hosted) + +# clang flags for coverage generation +set_property(TARGET compiler PROPERTY coverage --coverage -fno-inline) + +####################################################### +# This section covers flags related to warning levels # +####################################################### + +# clang option standard warning base in Zephyr +set_compiler_property(PROPERTY warning_base + -Wall + -Wformat + -Wformat-security + -Wno-format-zero-length + -Wno-main + -Wno-typedef-redefinition +) + +check_set_compiler_property(APPEND PROPERTY warning_base -Wno-pointer-sign) + +# Prohibit void pointer arithmetic. Illegal in C99 +check_set_compiler_property(APPEND PROPERTY warning_base -Wpointer-arith) + +# clang options for warning levels 1, 2, 3, when using `-DW=[1|2|3]` +set_compiler_property(PROPERTY warning_dw_1 + -Wextra + -Wunused + -Wno-unused-parameter + -Wmissing-declarations + -Wmissing-format-attribute +) +check_set_compiler_property(APPEND PROPERTY warning_dw_1 + -Wold-style-definition + -Wmissing-prototypes + -Wmissing-include-dirs + -Wunused-but-set-variable + -Wno-missing-field-initializers +) + +set_compiler_property(PROPERTY warning_dw_2 + -Waggregate-return + -Wcast-align + -Wdisabled-optimization + -Wnested-externs + -Wshadow +) + +check_set_compiler_property(APPEND PROPERTY warning_dw_2 + -Wlogical-op + -Wmissing-field-initializers +) + +set_compiler_property(PROPERTY warning_dw_3 + -Wbad-function-cast + -Wcast-qual + -Wconversion + -Wpacked + -Wpadded + -Wpointer-arith + -Wredundant-decls + -Wswitch-default +) + +check_set_compiler_property(APPEND PROPERTY warning_dw_3 + -Wpacked-bitfield-compat + -Wvla +) + + +check_set_compiler_property(PROPERTY warning_extended + #FIXME: need to fix all of those + -Wno-sometimes-uninitialized + -Wno-shift-overflow + -Wno-missing-braces + -Wno-self-assign + -Wno-address-of-packed-member + -Wno-unused-function + -Wno-initializer-overrides + -Wno-section + -Wno-unknown-warning-option + -Wno-unused-variable + -Wno-format-invalid-specifier + -Wno-gnu + # comparison of unsigned expression < 0 is always false + -Wno-tautological-compare +) + +set_compiler_property(PROPERTY warning_error_coding_guideline + -Werror=vla + -Wimplicit-fallthrough + -Wconversion + -Woverride-init +) diff --git a/cmake/compiler/clang/target.cmake b/cmake/compiler/clang/target.cmake index 45b9d8b2b32c48..945fbce6dc3b9d 100644 --- a/cmake/compiler/clang/target.cmake +++ b/cmake/compiler/clang/target.cmake @@ -32,7 +32,7 @@ if(NOT "${ARCH}" STREQUAL "posix") include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_arm.cmake) endif() - foreach(file_name include/stddef.h include-fixed/limits.h) + foreach(file_name include/stddef.h) execute_process( COMMAND ${CMAKE_C_COMPILER} --print-file-name=${file_name} OUTPUT_VARIABLE _OUTPUT @@ -47,6 +47,14 @@ if(NOT "${ARCH}" STREQUAL "posix") list(APPEND isystem_include_flags -isystem ${isystem_include_dir}) endforeach() + if(CONFIG_X86) + if(CONFIG_64BIT) + string(APPEND TOOLCHAIN_C_FLAGS "-m64") + else() + string(APPEND TOOLCHAIN_C_FLAGS "-m32") + endif() + endif() + # This libgcc code is partially duplicated in compiler/*/target.cmake execute_process( COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} --print-libgcc-file-name @@ -54,16 +62,14 @@ if(NOT "${ARCH}" STREQUAL "posix") OUTPUT_STRIP_TRAILING_WHITESPACE ) - assert_exists(LIBGCC_FILE_NAME) - get_filename_component(LIBGCC_DIR ${LIBGCC_FILE_NAME} DIRECTORY) - assert_exists(LIBGCC_DIR) - list(APPEND LIB_INCLUDE_DIR "-L\"${LIBGCC_DIR}\"") - list(APPEND TOOLCHAIN_LIBS gcc) + if(LIBGCC_DIR) + list(APPEND TOOLCHAIN_LIBS gcc) + endif() - set(CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags} -Wl,--unresolved-symbols=ignore-in-object-files) + set(CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags}) string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") endif() @@ -75,24 +81,3 @@ macro(toolchain_cc_nostdinc) zephyr_compile_options( -nostdinc) endif() endmacro() - -# Clang and GCC are almost feature+flag compatible, so reuse freestanding gcc -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_canaries.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_optimizations.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_cpp.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_asm.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_baremetal.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_warnings.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_imacros.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_base.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_coverage.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_sanitizers.cmake) - -macro(toolchain_cc_security_fortify) - # No op, clang doesn't understand fortify at all -endmacro() - -macro(toolchain_cc_no_freestanding_options) - # No op, this is used by the native_posix, clang has problems - # compiling the native_posix with -fno-freestanding. -endmacro() diff --git a/cmake/compiler/clang/target_coverage.cmake b/cmake/compiler/clang/target_coverage.cmake deleted file mode 100644 index 7cbfa17f7d1c8f..00000000000000 --- a/cmake/compiler/clang/target_coverage.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -macro(toolchain_cc_coverage) - -zephyr_compile_options( - --coverage - -fno-inline -) - -if (NOT CONFIG_COVERAGE_GCOV) - - zephyr_link_libraries( - --coverage - ) - -endif() - -endmacro() diff --git a/cmake/compiler/clang/target_sanitizers.cmake b/cmake/compiler/clang/target_sanitizers.cmake deleted file mode 100644 index 091b6d274d18a0..00000000000000 --- a/cmake/compiler/clang/target_sanitizers.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -macro(toolchain_cc_asan) - -zephyr_compile_options(-fsanitize=address) -zephyr_ld_options(-fsanitize=address) - -endmacro() - -macro(toolchain_cc_ubsan) - -zephyr_compile_options(-fsanitize=undefined) -zephyr_ld_options(-fsanitize=undefined) - -endmacro() diff --git a/cmake/compiler/clang/target_warnings.cmake b/cmake/compiler/clang/target_warnings.cmake deleted file mode 100644 index cd2b9700faae0b..00000000000000 --- a/cmake/compiler/clang/target_warnings.cmake +++ /dev/null @@ -1,124 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# See root CMakeLists.txt for description and expectations of this macro - -macro(toolchain_cc_warning_base) - - zephyr_compile_options( - -Wall - -Wformat - -Wformat-security - -Wno-format-zero-length - -Wno-main - ) - - zephyr_cc_option(-Wno-pointer-sign) - - # Prohibit void pointer arithmetic. Illegal in C99 - zephyr_cc_option(-Wpointer-arith) - -endmacro() - -macro(toolchain_cc_warning_dw_1) - - zephyr_compile_options( - -Wextra - -Wunused - -Wno-unused-parameter - -Wmissing-declarations - -Wmissing-format-attribute - ) - zephyr_cc_option( - -Wold-style-definition - -Wmissing-prototypes - -Wmissing-include-dirs - -Wunused-but-set-variable - -Wno-missing-field-initializers - ) - -endmacro() - -macro(toolchain_cc_warning_dw_2) - - zephyr_compile_options( - -Waggregate-return - -Wcast-align - -Wdisabled-optimization - -Wnested-externs - -Wshadow - ) - zephyr_cc_option( - -Wlogical-op - -Wmissing-field-initializers - ) - -endmacro() - -macro(toolchain_cc_warning_dw_3) - - zephyr_compile_options( - -Wbad-function-cast - -Wcast-qual - -Wconversion - -Wpacked - -Wpadded - -Wpointer-arith - -Wredundant-decls - -Wswitch-default - ) - zephyr_cc_option( - -Wpacked-bitfield-compat - -Wvla - ) - -endmacro() - -macro(toolchain_cc_warning_extended) - - zephyr_cc_option( - #FIXME: need to fix all of those - -Wno-sometimes-uninitialized - -Wno-shift-overflow - -Wno-missing-braces - -Wno-self-assign - -Wno-address-of-packed-member - -Wno-unused-function - -Wno-initializer-overrides - -Wno-section - -Wno-unknown-warning-option - -Wno-unused-variable - -Wno-format-invalid-specifier - -Wno-gnu - # comparison of unsigned expression < 0 is always false - -Wno-tautological-compare - ) - -endmacro() - -macro(toolchain_cc_warning_error_implicit_int) - - # Force an error when things like SYS_INIT(foo, ...) occur with a missing header - zephyr_cc_option(-Werror=implicit-int) - -endmacro() - -# -# The following macros leaves it up to the root CMakeLists.txt to choose -# the variables in which to put the requested flags, and whether or not -# to call the macros -# - -macro(toolchain_cc_warning_error_misra_sane dest_var_name) - set_ifndef(${dest_var_name} "-Werror=vla") -endmacro() - -macro(toolchain_cc_cpp_warning_error_misra_sane dest_var_name) - set_ifndef(${dest_var_name} "-Werror=vla") -endmacro() - -# List the warnings that are not supported for C++ compilations - -list(APPEND CXX_EXCLUDED_OPTIONS - -Werror=implicit-int - -Wold-style-definition - ) diff --git a/cmake/compiler/compiler_flags_template.cmake b/cmake/compiler/compiler_flags_template.cmake new file mode 100644 index 00000000000000..3b431da85b2316 --- /dev/null +++ b/cmake/compiler/compiler_flags_template.cmake @@ -0,0 +1,102 @@ +# Overview of used compiler properties for gcc / g++ compilers. +# +# Define the flags your toolchain support, and keep the unsupported flags empty. + +##################################################### +# This section covers flags related to optimization # +##################################################### +set_compiler_property(PROPERTY no_optimization) + +set_compiler_property(PROPERTY optimization_debug) + +set_compiler_property(PROPERTY optimization_speed) + +set_compiler_property(PROPERTY optimization_size) + +####################################################### +# This section covers flags related to warning levels # +####################################################### + +# Property for standard warning base in Zephyr, this will always bet set when compiling. +set_compiler_property(PROPERTY warning_base) + +# GCC options for warning levels 1, 2, 3, when using `-DW=[1|2|3]` +# Property for warning levels 1, 2, 3 in Zephyr when using `-DW=[1|2|3]` +set_compiler_property(PROPERTY warning_dw_1) + +set_compiler_property(PROPERTY warning_dw_2) + +set_compiler_property(PROPERTY warning_dw_3) + +# Extended warning set supported by the compiler +set_compiler_property(PROPERTY warning_extended) + +# Compiler property that will issue error if a declaration does not specify a type +set_compiler_property(PROPERTY warning_error_implicit_int) + +# Compiler flags to use when compiling according to MISRA +set_compiler_property(PROPERTY warning_error_misra_sane) + +########################################################################### +# This section covers flags related to C or C++ standards / standard libs # +########################################################################### + +# Compiler flags for C standard. The specific standard must be appended by user. +# For example, gcc specifies this as: set_compiler_property(PROPERTY cstd -std=) +set_compiler_property(PROPERTY cstd) + +# Compiler flags for disabling C standard include and instead specify include +# dirs in nostdinc_include to use. +set_compiler_property(PROPERTY nostdinc) +set_compiler_property(PROPERTY nostdinc_include) + +# Required C++ flags when compiling C++ code +set_property(TARGET compiler-cpp PROPERTY required) + +# Compiler flags to use for specific C++ dialects +set_property(TARGET compiler-cpp PROPERTY dialect_cpp98) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp11) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp14) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp17) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp2a) + +# Flag for disabling exeptions in C++ +set_property(TARGET compiler-cpp PROPERTY no_exceptions) + +# Flag for disabling rtti in C++ +set_property(TARGET compiler-cpp PROPERTY no_rtti) + + +################################################### +# This section covers all remaining C / C++ flags # +################################################### + +# Flags for coverage generation +set_compiler_property(PROPERTY coverage) + +# Security canaries flags. +set_compiler_property(PROPERTY security_canaries) + +set_compiler_property(PROPERTY security_fortify) + +# Flag for a hosted (no-freestanding) application +set_compiler_property(PROPERTY hosted) + +# gcc flag for a freestanding application +set_compiler_property(PROPERTY freestanding) + +# Flag to include debugging symbol in compilation +set_compiler_property(PROPERTY debug) + +set_compiler_property(PROPERTY no_common) + +# Flags for imacros. The specific header must be appended by user. +set_compiler_property(PROPERTY imacros) + +# Compiler flags for sanitizing. +set_compiler_property(PROPERTY sanitize_address) + +set_compiler_property(PROPERTY sanitize_undefined) + +# Required ASM flags when compiling +set_property(TARGET asm PROPERTY required) diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake new file mode 100644 index 00000000000000..11377ab54c71bd --- /dev/null +++ b/cmake/compiler/gcc/compiler_flags.cmake @@ -0,0 +1,176 @@ +# Those are flags not to test for CXX compiler. +list(APPEND CXX_EXCLUDED_OPTIONS + -Werror=implicit-int + -Wold-style-definition + -Wno-pointer-sign +) + +######################################################## +# Setting compiler properties for gcc / g++ compilers. # +######################################################## + +##################################################### +# This section covers flags related to optimization # +##################################################### +set_compiler_property(PROPERTY no_optimization -O0) +if(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.8.0") + set_compiler_property(PROPERTY optimization_debug -O0) +else() + set_compiler_property(PROPERTY optimization_debug -Og) +endif() +set_compiler_property(PROPERTY optimization_speed -O2) +set_compiler_property(PROPERTY optimization_size -Os) + +####################################################### +# This section covers flags related to warning levels # +####################################################### + +# GCC Option standard warning base in Zephyr +set_compiler_property(PROPERTY warning_base + -Wall + -Wformat + -Wformat-security + -Wno-format-zero-length + -Wno-main +) + +check_set_compiler_property(APPEND PROPERTY warning_base -Wno-pointer-sign) + +# Prohibit void pointer arithmetic. Illegal in C99 +check_set_compiler_property(APPEND PROPERTY warning_base -Wpointer-arith) + +if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "9.1.0") + set_compiler_property(APPEND PROPERTY warning_base + # FIXME: Remove once #16587 is fixed + -Wno-address-of-packed-member + ) +endif() + + +# GCC options for warning levels 1, 2, 3, when using `-DW=[1|2|3]` +set_compiler_property(PROPERTY warning_dw_1 + -Waggregate-return + -Wcast-align + -Wdisabled-optimization + -Wnested-externs + -Wshadow +) +check_set_compiler_property(APPEND PROPERTY warning_dw_1 + -Wlogical-op + -Wmissing-field-initializers +) + +set_compiler_property(PROPERTY warning_dw_2 + -Wbad-function-cast + -Wcast-qual + -Wconversion + -Wpacked + -Wpadded + -Wpointer-arith + -Wredundant-decls + -Wswitch-default +) +check_set_compiler_property(APPEND PROPERTY warning_dw_2 + -Wpacked-bitfield-compat + -Wvla +) +set_compiler_property(PROPERTY warning_dw_3 + -Wbad-function-cast + -Wcast-qual + -Wconversion + -Wpacked + -Wpadded + -Wpointer-arith + -Wredundant-decls + -Wswitch-default +) +check_set_compiler_property(APPEND PROPERTY warning_dw_3 + -Wpacked-bitfield-compat + -Wvla +) + +check_set_compiler_property(PROPERTY warning_extended -Wno-unused-but-set-variable) + +check_set_compiler_property(PROPERTY warning_error_implicit_int -Werror=implicit-int) + +set_compiler_property(PROPERTY warning_error_misra_sane -Werror=vla) + +set_compiler_property(PROPERTY warning_error_coding_guideline + -Werror=vla + -Wimplicit-fallthrough=2 + -Wconversion + -Woverride-init +) + +########################################################################### +# This section covers flags related to C or C++ standards / standard libs # +########################################################################### + +# GCC compiler flags for C standard. The specific standard must be appended by user. +set_compiler_property(PROPERTY cstd -std=) + +if (NOT CONFIG_NEWLIB_LIBC AND + NOT COMPILER STREQUAL "xcc" AND + NOT CONFIG_NATIVE_APPLICATION) + set_compiler_property(PROPERTY nostdinc -nostdinc) + set_compiler_property(APPEND PROPERTY nostdinc_include ${NOSTDINC}) +endif() + +# Required C++ flags when using gcc +set_property(TARGET compiler-cpp PROPERTY required "-fcheck-new") + +# GCC compiler flags for C++ dialects +set_property(TARGET compiler-cpp PROPERTY dialect_cpp98 "-std=c++98") +set_property(TARGET compiler-cpp PROPERTY dialect_cpp11 "-std=c++11" "-Wno-register") +set_property(TARGET compiler-cpp PROPERTY dialect_cpp14 "-std=c++14" "-Wno-register") +set_property(TARGET compiler-cpp PROPERTY dialect_cpp17 "-std=c++17" "-Wno-register") +set_property(TARGET compiler-cpp PROPERTY dialect_cpp2a "-std=c++2a" "-Wno-register") + +# Disable exeptions flag in C++ +set_property(TARGET compiler-cpp PROPERTY no_exceptions "-fno-exceptions") + +# Disable rtti in C++ +set_property(TARGET compiler-cpp PROPERTY no_rtti "-fno-rtti") + + +################################################### +# This section covers all remaining C / C++ flags # +################################################### + +# gcc flags for coverage generation +set_compiler_property(PROPERTY coverage -fprofile-arcs -ftest-coverage -fno-inline) + +# Security canaries. +set_compiler_property(PROPERTY security_canaries -fstack-protector-all) + +# Only a valid option with GCC 7.x and above, so let's do check and set. +check_set_compiler_property(APPEND PROPERTY security_canaries -mstack-protector-guard=global) + +if(NOT CONFIG_NO_OPTIMIZATIONS) + # _FORTIFY_SOURCE: Detect common-case buffer overflows for certain functions + # _FORTIFY_SOURCE=1 : Compile-time checks (requires -O1 at least) + # _FORTIFY_SOURCE=2 : Additional lightweight run-time checks + set_compiler_property(PROPERTY security_fortify _FORTIFY_SOURCE=2) +endif() + +# gcc flag for a hosted (no-freestanding) application +check_set_compiler_property(APPEND PROPERTY hosted -fno-freestanding) + +# gcc flag for a freestandingapplication +set_compiler_property(PROPERTY freestanding -ffreestanding) + +# Flag to enable debugging +set_compiler_property(PROPERTY debug -g) + +set_compiler_property(PROPERTY no_common -fno-common) + +# GCC compiler flags for imacros. The specific header must be appended by user. +set_compiler_property(PROPERTY imacros -imacros) + +# GCC compiler flags for sanitizing. +set_compiler_property(PROPERTY sanitize_address -fsanitize=address) + +set_compiler_property(PROPERTY sanitize_undefined -fsanitize=undefined) + +# Required ASM flags when using gcc +set_property(TARGET asm PROPERTY required "-xassembler-with-cpp") diff --git a/cmake/compiler/gcc/target.cmake b/cmake/compiler/gcc/target.cmake index 6646c06822b277..a8005a8deefeff 100644 --- a/cmake/compiler/gcc/target.cmake +++ b/cmake/compiler/gcc/target.cmake @@ -55,6 +55,8 @@ elseif("${ARCH}" STREQUAL "riscv") include(${CMAKE_CURRENT_LIST_DIR}/target_riscv.cmake) elseif("${ARCH}" STREQUAL "x86") include(${CMAKE_CURRENT_LIST_DIR}/target_x86.cmake) +elseif("${ARCH}" STREQUAL "sparc") + include(${CMAKE_CURRENT_LIST_DIR}/target_sparc.cmake) endif() if(NOT no_libgcc) @@ -113,17 +115,3 @@ list(APPEND CMAKE_REQUIRED_FLAGS -Wl,--entry=0 # Set an entry point to avoid a warning ) string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - -# Load toolchain_cc-family macros -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_freestanding.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_security_fortify.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_security_canaries.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_optimizations.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_cpp.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_asm.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_baremetal.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_warnings.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_imacros.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_base.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_coverage.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_sanitizers.cmake) diff --git a/cmake/compiler/gcc/target_asm.cmake b/cmake/compiler/gcc/target_asm.cmake deleted file mode 100644 index b3c3d090f791cc..00000000000000 --- a/cmake/compiler/gcc/target_asm.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# See root CMakeLists.txt for description and expectations of this macro - -macro(toolchain_cc_asm_base_flags dest_var_name) - # Specify assembly as the source language for the preprocessor to expect - set_ifndef(${dest_var_name} "-xassembler-with-cpp") -endmacro() diff --git a/cmake/compiler/gcc/target_baremetal.cmake b/cmake/compiler/gcc/target_baremetal.cmake deleted file mode 100644 index 41e6ce877a64b5..00000000000000 --- a/cmake/compiler/gcc/target_baremetal.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# See root CMakeLists.txt for description and expectations of these macros - -macro(toolchain_cc_nostdinc) - - if (NOT CONFIG_NEWLIB_LIBC AND - NOT COMPILER STREQUAL "xcc" AND - NOT CONFIG_NATIVE_APPLICATION) - zephyr_compile_options( -nostdinc) - zephyr_system_include_directories(${NOSTDINC}) - endif() - -endmacro() - -macro(toolchain_cc_freestanding) - - zephyr_compile_options(-ffreestanding) - -endmacro() diff --git a/cmake/compiler/gcc/target_base.cmake b/cmake/compiler/gcc/target_base.cmake deleted file mode 100644 index a180962697b13c..00000000000000 --- a/cmake/compiler/gcc/target_base.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# The intention with this file is, to have a common placeholder for macros -# which does not fit into any of the categories defined by the existing -# target_xxx.cmake files and which have a fairly high commonality between -# toolchains. -# -# See root CMakeLists.txt for description and expectations of this macro - -macro(toolchain_cc_produce_debug_info) - - zephyr_compile_options(-g) # TODO: build configuration enough? - -endmacro() - -macro(toolchain_cc_nocommon) - - zephyr_compile_options(-fno-common) - -endmacro() - -macro(toolchain_cc_cstd_flag dest_var_name c_std) - - set_ifndef(${dest_var_name} "-std=${c_std}") - -endmacro() diff --git a/cmake/compiler/gcc/target_coverage.cmake b/cmake/compiler/gcc/target_coverage.cmake deleted file mode 100644 index 5a7dc74ef03158..00000000000000 --- a/cmake/compiler/gcc/target_coverage.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -macro(toolchain_cc_coverage) - -zephyr_compile_options( - -fprofile-arcs - -ftest-coverage - -fno-inline -) - -if (NOT CONFIG_COVERAGE_GCOV) - - zephyr_link_libraries( - -lgcov - ) - -endif() - -endmacro() diff --git a/cmake/compiler/gcc/target_cpp.cmake b/cmake/compiler/gcc/target_cpp.cmake deleted file mode 100644 index 1fd03c38a95c2a..00000000000000 --- a/cmake/compiler/gcc/target_cpp.cmake +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# See root CMakeLists.txt for description and expectations of these macros - -macro(toolchain_cc_cpp_base_flags dest_list_name) - list(APPEND ${dest_list_name} "-fcheck-new") -endmacro() - -# The "register" keyword was deprecated since C++11, but not for C++98 -macro(toolchain_cc_cpp_dialect_std_98_flags dest_list_name) - list(APPEND ${dest_list_name} "-std=c++98") -endmacro() -macro(toolchain_cc_cpp_dialect_std_11_flags dest_list_name) - list(APPEND ${dest_list_name} "-std=c++11") - list(APPEND ${dest_list_name} "-Wno-register") -endmacro() -macro(toolchain_cc_cpp_dialect_std_14_flags dest_list_name) - list(APPEND ${dest_list_name} "-std=c++14") - list(APPEND ${dest_list_name} "-Wno-register") -endmacro() -macro(toolchain_cc_cpp_dialect_std_17_flags dest_list_name) - list(APPEND ${dest_list_name} "-std=c++17") - list(APPEND ${dest_list_name} "-Wno-register") -endmacro() -macro(toolchain_cc_cpp_dialect_std_2a_flags dest_list_name) - list(APPEND ${dest_list_name} "-std=c++2a") - list(APPEND ${dest_list_name} "-Wno-register") -endmacro() - -macro(toolchain_cc_cpp_no_exceptions_flag dest_var_name) - set_ifndef(${dest_var_name} "-fno-exceptions") -endmacro() - -macro(toolchain_cc_cpp_no_rtti_flag dest_var_name) - set_ifndef(${dest_var_name} "-fno-rtti") -endmacro() diff --git a/cmake/compiler/gcc/target_freestanding.cmake b/cmake/compiler/gcc/target_freestanding.cmake deleted file mode 100644 index 3648ecf8f4566f..00000000000000 --- a/cmake/compiler/gcc/target_freestanding.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2019 Intel Corporation. -# SPDX-License-Identifier: Apache-2.0 - -macro(toolchain_cc_no_freestanding_options) - - zephyr_cc_option(-fno-freestanding) - -endmacro() diff --git a/cmake/compiler/gcc/target_imacros.cmake b/cmake/compiler/gcc/target_imacros.cmake deleted file mode 100644 index 0fba83819afb18..00000000000000 --- a/cmake/compiler/gcc/target_imacros.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# See root CMakeLists.txt for description and expectations of these macros - -macro(toolchain_cc_imacros header_file) - - # We cannot use the "-imacros foo" form here as CMake insists on - # deduplicating arguments, meaning that subsequent usages after the - # first one will see the "-imacros " part removed. - # gcc and clang support the "--imacros=foo" form but not xcc. - # Let's use the "combined" form (without space) which is supported - # by everyone so far. - zephyr_compile_options(-imacros${header_file}) - -endmacro() diff --git a/cmake/compiler/gcc/target_optimizations.cmake b/cmake/compiler/gcc/target_optimizations.cmake deleted file mode 100644 index 4deacc7d46cb52..00000000000000 --- a/cmake/compiler/gcc/target_optimizations.cmake +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# See root CMakeLists.txt for description and expectations of this macro -# -# NOTE: Some GNU toolchains break with plain '-Os' or '-Og', but is fixable -# with tweaks. So allow user to override, via ifndef, the compile flags that -# CONFIG_{NO,DEBUG,SPEED,SIZE}_OPTIMIZATIONS will cause, yet still leaving the -# selection logic in kconfig. -# -# These macros leaves it up to the root CMakeLists.txt to choose the CMake -# variable names to store the optimization flags in. - -macro(toolchain_cc_optimize_for_no_optimizations_flag dest_var_name) - set_ifndef(${dest_var_name} "-O0") -endmacro() - -macro(toolchain_cc_optimize_for_debug_flag dest_var_name) - # -Og optimisation flag is only supported from gcc 4.8.0 and above. - # Fall back to using -O0 flag if running an older gcc version. - if(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.8.0") - set_ifndef(${dest_var_name} "-O0") - else() - set_ifndef(${dest_var_name} "-Og") - endif() -endmacro() - -macro(toolchain_cc_optimize_for_speed_flag dest_var_name) - set_ifndef(${dest_var_name} "-O2") -endmacro() - -macro(toolchain_cc_optimize_for_size_flag dest_var_name) - set_ifndef(${dest_var_name} "-Os") -endmacro() diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index 88c7a901f3d681..0c1c30cfb73c07 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -31,4 +31,4 @@ if(CONFIG_COMPRESSED_ISA) endif() list(APPEND TOOLCHAIN_C_FLAGS -mabi=${riscv_mabi} -march=${riscv_march}) -list(APPEND TOOLCHAIN_LD_FLAGS -mabi=${riscv_mabi} -march=${riscv_march}) +list(APPEND TOOLCHAIN_LD_FLAGS NO_SPLIT -mabi=${riscv_mabi} -march=${riscv_march}) diff --git a/cmake/compiler/gcc/target_sanitizers.cmake b/cmake/compiler/gcc/target_sanitizers.cmake deleted file mode 100644 index 1661307feb4110..00000000000000 --- a/cmake/compiler/gcc/target_sanitizers.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -macro(toolchain_cc_asan) - -zephyr_compile_options(-fsanitize=address) -zephyr_link_libraries(-lasan) -zephyr_ld_options(-fsanitize=address) - -endmacro() - -macro(toolchain_cc_ubsan) - -zephyr_compile_options(-fsanitize=undefined) -zephyr_ld_options(-fsanitize=undefined) - -endmacro() diff --git a/cmake/compiler/gcc/target_security_canaries.cmake b/cmake/compiler/gcc/target_security_canaries.cmake deleted file mode 100644 index 8db8d4856efb8d..00000000000000 --- a/cmake/compiler/gcc/target_security_canaries.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# See root CMakeLists.txt for description and expectations of this macro -macro(toolchain_cc_security_canaries) - - zephyr_compile_options(-fstack-protector-all) - - # Only a valid option with GCC 7.x and above - zephyr_cc_option(-mstack-protector-guard=global) - -endmacro() diff --git a/cmake/compiler/gcc/target_security_fortify.cmake b/cmake/compiler/gcc/target_security_fortify.cmake deleted file mode 100644 index 3aa09440c04ad5..00000000000000 --- a/cmake/compiler/gcc/target_security_fortify.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# See root CMakeLists.txt for description and expectations of this macro -macro(toolchain_cc_security_fortify) - - if(NOT CONFIG_NO_OPTIMIZATIONS) - # _FORTIFY_SOURCE: Detect common-case buffer overflows for certain functions - # _FORTIFY_SOURCE=1 : Compile-time checks (requires -O1 at least) - # _FORTIFY_SOURCE=2 : Additional lightweight run-time checks - zephyr_compile_definitions( - _FORTIFY_SOURCE=2 - ) - endif() - -endmacro() diff --git a/cmake/compiler/gcc/target_sparc.cmake b/cmake/compiler/gcc/target_sparc.cmake new file mode 100644 index 00000000000000..92578dd11d64c3 --- /dev/null +++ b/cmake/compiler/gcc/target_sparc.cmake @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT CONFIG_FPU) + list(APPEND TOOLCHAIN_C_FLAGS -msoft-float) + list(APPEND TOOLCHAIN_LD_FLAGS -msoft-float) +endif() + +if(CONFIG_SPARC_CASA) + # SPARC V8, mul/div, casa + list(APPEND TOOLCHAIN_C_FLAGS -mcpu=leon3) + list(APPEND TOOLCHAIN_LD_FLAGS -mcpu=leon3) +else() + # SPARC V8, mul/div, no casa + list(APPEND TOOLCHAIN_C_FLAGS -mcpu=leon) + list(APPEND TOOLCHAIN_LD_FLAGS -mcpu=leon) +endif() diff --git a/cmake/compiler/gcc/target_warnings.cmake b/cmake/compiler/gcc/target_warnings.cmake deleted file mode 100644 index 34d4406fab22c2..00000000000000 --- a/cmake/compiler/gcc/target_warnings.cmake +++ /dev/null @@ -1,117 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# See root CMakeLists.txt for description and expectations of these macros - -macro(toolchain_cc_warning_base) - - zephyr_compile_options( - -Wall - -Wformat - -Wformat-security - -Wno-format-zero-length - -Wno-main - ) - -if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "9.1.0") - zephyr_compile_options( - # FIXME: Remove once #16587 is fixed - -Wno-address-of-packed-member - ) -endif() - - zephyr_cc_option(-Wno-pointer-sign) - - # Prohibit void pointer arithmetic. Illegal in C99 - zephyr_cc_option(-Wpointer-arith) - -endmacro() - -macro(toolchain_cc_warning_dw_1) - - zephyr_compile_options( - -Wextra - -Wunused - -Wno-unused-parameter - -Wmissing-declarations - -Wmissing-format-attribute - ) - zephyr_cc_option( - -Wold-style-definition - -Wmissing-prototypes - -Wmissing-include-dirs - -Wunused-but-set-variable - -Wno-missing-field-initializers - ) - -endmacro() - -macro(toolchain_cc_warning_dw_2) - - zephyr_compile_options( - -Waggregate-return - -Wcast-align - -Wdisabled-optimization - -Wnested-externs - -Wshadow - ) - zephyr_cc_option( - -Wlogical-op - -Wmissing-field-initializers - ) - -endmacro() - -macro(toolchain_cc_warning_dw_3) - - zephyr_compile_options( - -Wbad-function-cast - -Wcast-qual - -Wconversion - -Wpacked - -Wpadded - -Wpointer-arith - -Wredundant-decls - -Wswitch-default - ) - zephyr_cc_option( - -Wpacked-bitfield-compat - -Wvla - ) - -endmacro() - -macro(toolchain_cc_warning_extended) - - zephyr_cc_option( - -Wno-unused-but-set-variable - ) - -endmacro() - -macro(toolchain_cc_warning_error_implicit_int) - - # Force an error when things like SYS_INIT(foo, ...) occur with a missing header - zephyr_cc_option(-Werror=implicit-int) - -endmacro() - -# -# The following macros leaves it up to the root CMakeLists.txt to choose -# the variables in which to put the requested flags, and whether or not -# to call the macros -# - -macro(toolchain_cc_warning_error_misra_sane dest_var_name) - set_ifndef(${dest_var_name} "-Werror=vla") -endmacro() - -macro(toolchain_cc_cpp_warning_error_misra_sane dest_var_name) - set_ifndef(${dest_var_name} "-Werror=vla") -endmacro() - -# List the warnings that are not supported for C++ compilations - -list(APPEND CXX_EXCLUDED_OPTIONS - -Werror=implicit-int - -Wold-style-definition - ) diff --git a/cmake/compiler/host-gcc/compiler_flags.cmake b/cmake/compiler/host-gcc/compiler_flags.cmake new file mode 100644 index 00000000000000..9203aa320b4b6a --- /dev/null +++ b/cmake/compiler/host-gcc/compiler_flags.cmake @@ -0,0 +1,3 @@ +# Load toolchain_cc-family compiler flags +# Significant overlap with freestanding gcc compiler so reuse it +include(${ZEPHYR_BASE}/cmake/compiler/gcc/compiler_flags.cmake) diff --git a/cmake/compiler/host-gcc/target.cmake b/cmake/compiler/host-gcc/target.cmake index 11c817314bbfe4..648bd314a86f39 100644 --- a/cmake/compiler/host-gcc/target.cmake +++ b/cmake/compiler/host-gcc/target.cmake @@ -51,18 +51,3 @@ foreach(file_name include/stddef.h) list(APPEND NOSTDINC ${_OUTPUT}) endforeach() - -# Load toolchain_cc-family macros -# Significant overlap with freestanding gcc compiler so reuse it -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_freestanding.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_fortify.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_canaries.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_optimizations.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_cpp.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_asm.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_baremetal.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_warnings.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_imacros.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_base.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_coverage.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_sanitizers.cmake) diff --git a/cmake/compiler/xcc/compiler_flags.cmake b/cmake/compiler/xcc/compiler_flags.cmake new file mode 100644 index 00000000000000..b089f3c7b93298 --- /dev/null +++ b/cmake/compiler/xcc/compiler_flags.cmake @@ -0,0 +1,7 @@ +# No special flags are needed for xcc. +# Only select whether gcc or clang flags should be inherited. +if(CC STREQUAL "clang") + include(${ZEPHYR_BASE}/cmake/compiler/clang/compiler_flags.cmake) +else() + include(${ZEPHYR_BASE}/cmake/compiler/gcc/compiler_flags.cmake) +endif() diff --git a/cmake/compiler/xcc/target.cmake b/cmake/compiler/xcc/target.cmake index 01b4da8ecb0de4..b325028e2b38f2 100644 --- a/cmake/compiler/xcc/target.cmake +++ b/cmake/compiler/xcc/target.cmake @@ -65,19 +65,3 @@ endforeach() # toolchain-specific flags at generation time. list(APPEND CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags} -Wl,--unresolved-symbols=ignore-in-object-files) string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - -# Load toolchain_cc-family macros -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_fortify.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_canaries.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_optimizations.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_cpp.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_asm.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_baremetal.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_imacros.cmake) -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_base.cmake) - -if(CC STREQUAL "clang") - include(${ZEPHYR_BASE}/cmake/compiler/clang/target_warnings.cmake) -else() - include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_warnings.cmake) -endif() diff --git a/cmake/dts.cmake b/cmake/dts.cmake index a2203d5af2f919..48394d009bad01 100644 --- a/cmake/dts.cmake +++ b/cmake/dts.cmake @@ -4,21 +4,23 @@ file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include/generated) # Zephyr code can configure itself based on a KConfig'uration with the # header file autoconf.h. There exists an analogous file devicetree_unfixed.h -# that allows configuration based on information encoded in DTS, and a similar -# file with legacy contents called devicetree_unfixed_legacy.h. +# that allows configuration based on information encoded in DTS. # -# Here we call on dtc, the gcc preprocessor, -# scripts/dts/gen_defines.py, and scripts/dts/gen_legacy_defines.py to -# generate various DT-related files at CMake configure-time. -# -# The devicetree.conf file is still needed by some deprecated -# functions in kconfigfunctions.py. +# Here we call on dtc, the gcc preprocessor and +# scripts/dts/gen_defines.py to generate various DT-related files at +# CMake configure-time. # # See the Devicetree user guide in the Zephyr documentation for details. set(GEN_DEFINES_SCRIPT ${ZEPHYR_BASE}/scripts/dts/gen_defines.py) set(ZEPHYR_DTS ${PROJECT_BINARY_DIR}/zephyr.dts) +# This contains the edtlib.EDT object created from zephyr.dts in Python's +# pickle data marshalling format (https://docs.python.org/3/library/pickle.html) +# +# Its existence is an implementation detail used to speed up further +# use of the devicetree by processes that run later on in the build, +# and should not be made part of the documentation. +set(EDT_PICKLE ${PROJECT_BINARY_DIR}/edt.pickle) set(DEVICETREE_UNFIXED_H ${PROJECT_BINARY_DIR}/include/generated/devicetree_unfixed.h) -set(DEVICETREE_UNFIXED_LEGACY_H ${PROJECT_BINARY_DIR}/include/generated/devicetree_legacy_unfixed.h) set(DTS_POST_CPP ${PROJECT_BINARY_DIR}/${BOARD}.dts.pre.tmp) set_ifndef(DTS_SOURCE ${BOARD_DIR}/${BOARD}.dts) @@ -28,6 +30,8 @@ if(DEFINED DTS_COMMON_OVERLAYS) message(FATAL_ERROR "DTS_COMMON_OVERLAYS is no longer supported. Use DTC_OVERLAY_FILE instead.") endif() +zephyr_file(APPLICATION_ROOT DTS_ROOT) + # 'DTS_ROOT' is a list of directories where a directory tree with DT # files may be found. It always includes the application directory, # the board directory, and ${ZEPHYR_BASE}. @@ -41,8 +45,6 @@ list(REMOVE_DUPLICATES DTS_ROOT ) -list(REMOVE_DUPLICATES DTS_ROOT) - set(dts_files ${DTS_SOURCE} ${shield_dts_files} @@ -59,7 +61,11 @@ endif() if(SUPPORTS_DTS) if(DTC_OVERLAY_FILE) # Convert from space-separated files into file list - string(REPLACE " " ";" DTC_OVERLAY_FILE_AS_LIST ${DTC_OVERLAY_FILE}) + string(REPLACE " " ";" DTC_OVERLAY_FILE_RAW_LIST "${DTC_OVERLAY_FILE}") + foreach(file ${DTC_OVERLAY_FILE_RAW_LIST}) + file(TO_CMAKE_PATH "${file}" cmake_path_file) + list(APPEND DTC_OVERLAY_FILE_AS_LIST ${cmake_path_file}) + endforeach() list(APPEND dts_files ${DTC_OVERLAY_FILE_AS_LIST} @@ -89,7 +95,7 @@ if(SUPPORTS_DTS) dts/${ARCH} dts ) - set(full_path ${dts_root}/${dts_root_path}) + get_filename_component(full_path ${dts_root}/${dts_root_path} REALPATH) if(EXISTS ${full_path}) list(APPEND DTS_ROOT_SYSTEM_INCLUDE_DIRS @@ -115,6 +121,10 @@ if(SUPPORTS_DTS) set(CACHED_DTS_ROOT_BINDINGS ${DTS_ROOT_BINDINGS} CACHE INTERNAL "DT bindings root directories") + if(NOT DEFINED CMAKE_DTS_PREPROCESSOR) + set(CMAKE_DTS_PREPROCESSOR ${CMAKE_C_COMPILER}) + endif() + # TODO: Cut down on CMake configuration time by avoiding # regeneration of devicetree_unfixed.h on every configure. How # challenging is this? What are the dts dependencies? We run the @@ -126,13 +136,14 @@ if(SUPPORTS_DTS) # intermediary file *.dts.pre.tmp. Also, generate a dependency file # so that changes to DT sources are detected. execute_process( - COMMAND ${CMAKE_C_COMPILER} + COMMAND ${CMAKE_DTS_PREPROCESSOR} -x assembler-with-cpp -nostdinc ${DTS_ROOT_SYSTEM_INCLUDE_DIRS} ${DTC_INCLUDE_FLAG_FOR_DTS} # include the DTS source and overlays ${NOSYSDEF_CFLAG} -D__DTS__ + ${DTS_EXTRA_CPPFLAGS} -P -E # Stop after preprocessing -MD # Generate a dependency file as a side-effect @@ -197,7 +208,7 @@ if(SUPPORTS_DTS) endif(DTC) # - # Run gen_defines.py to create a header file and zephyr.dts. + # Run gen_defines.py to create a header file, zephyr.dts, and edt.pickle. # set(CMD_EXTRACT ${PYTHON_EXECUTABLE} ${GEN_DEFINES_SCRIPT} @@ -206,18 +217,7 @@ if(SUPPORTS_DTS) --bindings-dirs ${DTS_ROOT_BINDINGS} --header-out ${DEVICETREE_UNFIXED_H} --dts-out ${ZEPHYR_DTS} # As a debugging aid - ) - - # - # Run gen_legacy_defines.py to create a header file with legacy contents - # and a .conf file. - # - - set(CMD_LEGACY_EXTRACT ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/dts/gen_legacy_defines.py - --dts ${BOARD}.dts.pre.tmp - --dtc-flags '${EXTRA_DTC_FLAGS}' - --bindings-dirs ${DTS_ROOT_BINDINGS} - --header-out ${DEVICETREE_UNFIXED_LEGACY_H} + --edt-pickle-out ${EDT_PICKLE} ) execute_process( @@ -232,15 +232,6 @@ if(SUPPORTS_DTS) message(STATUS "Generated devicetree_unfixed.h: ${DEVICETREE_UNFIXED_H}") endif() - execute_process( - COMMAND ${CMD_LEGACY_EXTRACT} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - RESULT_VARIABLE ret - ) - if(NOT "${ret}" STREQUAL "0") - message(FATAL_ERROR "gen_legacy_defines.py failed with return code: ${ret}") - endif() - # A file that used to be generated by 'dtc'. zephyr.dts is the new # equivalent. Will be removed in Zephyr 2.3. file(WRITE ${PROJECT_BINARY_DIR}/${BOARD}.dts_compiled @@ -248,5 +239,4 @@ if(SUPPORTS_DTS) else() file(WRITE ${DEVICETREE_UNFIXED_H} "/* WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! */") - file(WRITE ${DEVICETREE_UNFIXED_LEGACY_H} "/* WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! */") endif(SUPPORTS_DTS) diff --git a/cmake/emu/mdb.cmake b/cmake/emu/mdb.cmake deleted file mode 100644 index d7cae6348e2754..00000000000000 --- a/cmake/emu/mdb.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -find_program( - MDB - mdb - ) - -if(${CONFIG_SOC_NSIM_HS_SMP}) - set(MDB_ARGS mdb_hs_smp.args) -endif() - -add_custom_target(run - COMMAND - ${MDB} -pset=1 -psetname=core0 -prop=ident=0x00000050 -cmpd=soc - @${BOARD_DIR}/support/${MDB_ARGS} ${APPLICATION_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME} && - ${MDB} -pset=2 -psetname=core1 -prop=ident=0x00000150 -cmpd=soc - @${BOARD_DIR}/support/${MDB_ARGS} ${APPLICATION_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME} && - NSIM_MULTICORE=1 ${MDB} -multifiles=core0,core1 -cmpd=soc -run -cl - DEPENDS ${logical_target_for_zephyr_elf} - WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} - USES_TERMINAL - ) diff --git a/cmake/emu/nsim.cmake b/cmake/emu/nsim.cmake index 2f6d2c7a3c046e..25c4121fe23594 100644 --- a/cmake/emu/nsim.cmake +++ b/cmake/emu/nsim.cmake @@ -1,5 +1,27 @@ # SPDX-License-Identifier: Apache-2.0 +if(${CONFIG_SOC_NSIM_HS_SMP}) +# mdb is required to run nsim multicore targets +find_program( + MDB + mdb + ) + +if(${CONFIG_SOC_NSIM_HS_SMP}) + set(MDB_ARGS mdb_hs_smp.args) +endif() +add_custom_target(run + COMMAND + ${MDB} -pset=1 -psetname=core0 -prop=ident=0x00000050 -cmpd=soc + @${BOARD_DIR}/support/${MDB_ARGS} ${APPLICATION_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME} && + ${MDB} -pset=2 -psetname=core1 -prop=download=2 -prop=ident=0x00000150 -cmpd=soc + @${BOARD_DIR}/support/${MDB_ARGS} ${APPLICATION_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME} && + NSIM_MULTICORE=1 ${MDB} -multifiles=core0,core1 -cmpd=soc -run -cl + DEPENDS ${logical_target_for_zephyr_elf} + WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} + USES_TERMINAL + ) +else() find_program( NSIM nsimdrv @@ -7,6 +29,8 @@ find_program( if(${CONFIG_SOC_NSIM_EM}) set(NSIM_PROPS nsim_em.props) +elseif(${CONFIG_SOC_NSIM_EM7D_V22}) + set(NSIM_PROPS nsim_em7d_v22.props) elseif(${CONFIG_SOC_NSIM_SEM}) set(NSIM_PROPS nsim_sem.props) elseif(${CONFIG_SOC_NSIM_HS}) @@ -34,3 +58,4 @@ add_custom_target(debugserver WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} USES_TERMINAL ) +endif() diff --git a/cmake/emu/qemu.cmake b/cmake/emu/qemu.cmake index a05ca93cd3badf..57d8b6788fae8e 100644 --- a/cmake/emu/qemu.cmake +++ b/cmake/emu/qemu.cmake @@ -60,6 +60,12 @@ endif() # Connect monitor to the console chardev. list(APPEND QEMU_FLAGS -mon chardev=con,mode=readline) +if(CONFIG_QEMU_ICOUNT) + list(APPEND QEMU_FLAGS + -icount shift=${CONFIG_QEMU_ICOUNT_SHIFT},align=off,sleep=off + -rtc clock=vm) +endif() + # Add a BT serial device when building for bluetooth, unless the # application explicitly opts out with NO_QEMU_SERIAL_BT_SERVER. if(CONFIG_BT) @@ -238,7 +244,7 @@ if(CONFIG_X86_64) ${CMAKE_OBJCOPY} -O elf32-i386 $ - ${CMAKE_BINARY_DIR}/zephyr-qemu.elf + ${ZEPHYR_BINARY_DIR}/zephyr-qemu.elf DEPENDS ${logical_target_for_zephyr_elf} ) @@ -251,8 +257,8 @@ if(CONFIG_X86_64) COMMAND ${CMAKE_OBJCOPY} -j .locore - ${CMAKE_BINARY_DIR}/zephyr-qemu.elf - ${CMAKE_BINARY_DIR}/zephyr-qemu-locore.elf + ${ZEPHYR_BINARY_DIR}/zephyr-qemu.elf + ${ZEPHYR_BINARY_DIR}/zephyr-qemu-locore.elf 2>&1 | grep -iv \"empty loadable segment detected\" || true DEPENDS qemu_image_target ) @@ -261,8 +267,8 @@ if(CONFIG_X86_64) COMMAND ${CMAKE_OBJCOPY} -R .locore - ${CMAKE_BINARY_DIR}/zephyr-qemu.elf - ${CMAKE_BINARY_DIR}/zephyr-qemu-main.elf + ${ZEPHYR_BINARY_DIR}/zephyr-qemu.elf + ${ZEPHYR_BINARY_DIR}/zephyr-qemu-main.elf 2>&1 | grep -iv \"empty loadable segment detected\" || true DEPENDS qemu_image_target ) @@ -272,10 +278,10 @@ if(CONFIG_X86_64) DEPENDS qemu_locore_image_target qemu_main_image_target ) - set(QEMU_KERNEL_FILE "${CMAKE_BINARY_DIR}/zephyr-qemu-locore.elf") + set(QEMU_KERNEL_FILE "${ZEPHYR_BINARY_DIR}/zephyr-qemu-locore.elf") list(APPEND QEMU_EXTRA_FLAGS - "-device;loader,file=${CMAKE_BINARY_DIR}/zephyr-qemu-main.elf" + "-device;loader,file=${ZEPHYR_BINARY_DIR}/zephyr-qemu-main.elf" ) endif() diff --git a/cmake/emu/tsim.cmake b/cmake/emu/tsim.cmake new file mode 100644 index 00000000000000..be75b607d8e2bc --- /dev/null +++ b/cmake/emu/tsim.cmake @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(TSIM_FLAGS -e run -e exit) + +add_custom_target(run + COMMAND + ${TSIM} + ${TSIM_SYS} + ${TSIM_FLAGS} + ${APPLICATION_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME} + WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} + USES_TERMINAL + ) diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake index 46f28b8fab76eb..09b3cbb901c160 100644 --- a/cmake/extensions.cmake +++ b/cmake/extensions.cmake @@ -11,8 +11,7 @@ # 1.4. board_* # 1.5. Misc. # 2. Kconfig-aware extensions -# 2.1 *_if_kconfig -# 2.2 Misc +# 2.1 Misc # 3. CMake-generic extensions # 3.1. *_ifdef # 3.2. *_ifndef @@ -164,7 +163,7 @@ endfunction() # writes "-Isome_dir;-Isome/other/dir" to x function(zephyr_get_include_directories_for_lang_as_string lang i) - zephyr_get_include_directories_for_lang(${lang} list_of_flags ${ARGN}) + zephyr_get_include_directories_for_lang(${lang} list_of_flags DELIMITER " " ${ARGN}) convert_list_of_flags_to_string_of_flags(list_of_flags str_of_flags) @@ -172,7 +171,7 @@ function(zephyr_get_include_directories_for_lang_as_string lang i) endfunction() function(zephyr_get_system_include_directories_for_lang_as_string lang i) - zephyr_get_system_include_directories_for_lang(${lang} list_of_flags ${ARGN}) + zephyr_get_system_include_directories_for_lang(${lang} list_of_flags DELIMITER " " ${ARGN}) convert_list_of_flags_to_string_of_flags(list_of_flags str_of_flags) @@ -180,7 +179,7 @@ function(zephyr_get_system_include_directories_for_lang_as_string lang i) endfunction() function(zephyr_get_compile_definitions_for_lang_as_string lang i) - zephyr_get_compile_definitions_for_lang(${lang} list_of_flags ${ARGN}) + zephyr_get_compile_definitions_for_lang(${lang} list_of_flags DELIMITER " " ${ARGN}) convert_list_of_flags_to_string_of_flags(list_of_flags str_of_flags) @@ -188,7 +187,7 @@ function(zephyr_get_compile_definitions_for_lang_as_string lang i) endfunction() function(zephyr_get_compile_options_for_lang_as_string lang i) - zephyr_get_compile_options_for_lang(${lang} list_of_flags) + zephyr_get_compile_options_for_lang(${lang} list_of_flags DELIMITER " ") convert_list_of_flags_to_string_of_flags(list_of_flags str_of_flags) @@ -196,44 +195,60 @@ function(zephyr_get_compile_options_for_lang_as_string lang i) endfunction() function(zephyr_get_include_directories_for_lang lang i) - get_property_and_add_prefix(flags zephyr_interface INTERFACE_INCLUDE_DIRECTORIES - "-I" - ${ARGN} - ) + zephyr_get_parse_args(args ${ARGN}) + get_property(flags TARGET zephyr_interface PROPERTY INTERFACE_INCLUDE_DIRECTORIES) process_flags(${lang} flags output_list) - - set(${i} ${output_list} PARENT_SCOPE) + string(REPLACE ";" "$" genexp_output_list "${output_list}") + + if(NOT ARGN) + set(result_output_list "-I$-I>") + elseif(args_STRIP_PREFIX) + # The list has no prefix, so don't add it. + set(result_output_list ${output_list}) + elseif(args_DELIMITER) + set(result_output_list "-I$") + endif() + set(${i} ${result_output_list} PARENT_SCOPE) endfunction() function(zephyr_get_system_include_directories_for_lang lang i) - get_property_and_add_prefix(flags zephyr_interface INTERFACE_SYSTEM_INCLUDE_DIRECTORIES - "-isystem" - ${ARGN} - ) + zephyr_get_parse_args(args ${ARGN}) + get_property(flags TARGET zephyr_interface PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) process_flags(${lang} flags output_list) + string(REPLACE ";" "$" genexp_output_list "${output_list}") + + set_ifndef(args_DELIMITER "$") + set(result_output_list "$<$:-isystem$>") - set(${i} ${output_list} PARENT_SCOPE) + set(${i} ${result_output_list} PARENT_SCOPE) endfunction() function(zephyr_get_compile_definitions_for_lang lang i) - get_property_and_add_prefix(flags zephyr_interface INTERFACE_COMPILE_DEFINITIONS - "-D" - ${ARGN} - ) + zephyr_get_parse_args(args ${ARGN}) + get_property(flags TARGET zephyr_interface PROPERTY INTERFACE_COMPILE_DEFINITIONS) process_flags(${lang} flags output_list) + string(REPLACE ";" "$" genexp_output_list "${output_list}") - set(${i} ${output_list} PARENT_SCOPE) + set_ifndef(args_DELIMITER "$") + set(result_output_list "-D$") + + set(${i} ${result_output_list} PARENT_SCOPE) endfunction() function(zephyr_get_compile_options_for_lang lang i) + zephyr_get_parse_args(args ${ARGN}) get_property(flags TARGET zephyr_interface PROPERTY INTERFACE_COMPILE_OPTIONS) process_flags(${lang} flags output_list) + string(REPLACE ";" "$" genexp_output_list "${output_list}") + + set_ifndef(args_DELIMITER "$") + set(result_output_list "$") - set(${i} ${output_list} PARENT_SCOPE) + set(${i} ${result_output_list} PARENT_SCOPE) endfunction() # This function writes a dict to it's output parameter @@ -244,8 +259,17 @@ endfunction() # print(foo_STRIP_PREFIX) # foo_STRIP_PREFIX might be set to 1 function(zephyr_get_parse_args return_dict) foreach(x ${ARGN}) - if(x STREQUAL STRIP_PREFIX) - set(${return_dict}_STRIP_PREFIX 1 PARENT_SCOPE) + if(DEFINED single_argument) + set(${single_argument} ${x} PARENT_SCOPE) + unset(single_argument) + else() + if(x STREQUAL STRIP_PREFIX) + set(${return_dict}_STRIP_PREFIX 1 PARENT_SCOPE) + elseif(x STREQUAL NO_SPLIT) + set(${return_dict}_NO_SPLIT 1 PARENT_SCOPE) + elseif(x STREQUAL DELIMITER) + set(single_argument ${return_dict}_DELIMITER) + endif() endif() endforeach() endfunction() @@ -254,6 +278,7 @@ function(process_flags lang input output) # The flags might contains compile language generator expressions that # look like this: # $<$:-fno-exceptions> + # $<$:$> # # Flags that don't specify a language like this apply to all # languages. @@ -275,15 +300,34 @@ function(process_flags lang input output) set(is_compile_lang_generator_expression 0) foreach(l ${languages}) if(flag MATCHES ":([^>]+)>") + set(updated_flag ${CMAKE_MATCH_1}) set(is_compile_lang_generator_expression 1) if(${l} STREQUAL ${lang}) - list(APPEND tmp_list ${CMAKE_MATCH_1}) + # This test will match in case there are more generator expressions in the flag. + # As example: $<$:$> + # $<$:something>> + string(REGEX MATCH "(\\\$<)[^\\\$]*(\\\$<)[^\\\$]*(\\\$<)" IGNORE_RESULT ${flag}) + if(CMAKE_MATCH_2) + # Nested generator expressions are used, just substitue `$` to `1` + string(REGEX REPLACE "\\\$" "1" updated_flag ${flag}) + endif() + list(APPEND tmp_list ${updated_flag}) break() endif() endif() endforeach() if(NOT is_compile_lang_generator_expression) + # SHELL is used to avoid de-deplucation, but when process flags + # then this tag must be removed to return real compile/linker flags. + if(flag MATCHES "SHELL:[ ]*(.*)") + separate_arguments(flag UNIX_COMMAND ${CMAKE_MATCH_1}) + endif() + # Flags may be placed inside generator expression, therefore any flag + # which is not already a generator expression must have commas converted. + if(NOT flag MATCHES "\\\$<.*>") + string(REPLACE "," "$" flag "${flag}") + endif() list(APPEND tmp_list ${flag}) endif() endforeach() @@ -817,7 +861,7 @@ function(zephyr_check_compiler_flag lang option check) # This is racy. As often with race conditions, this one can easily be # made worse and demonstrated with a simple delay: # execute_process(COMMAND "sleep" "5") - # Delete the cache, add the sleep above and run sanitycheck with a + # Delete the cache, add the sleep above and run twister with a # large number of JOBS. Once it's done look at the log.txt file # below and you will see that concurrent cmake processes created the # same files multiple times. @@ -986,9 +1030,12 @@ endfunction(zephyr_linker_sources) # Helper function for CONFIG_CODE_DATA_RELOCATION # Call this function with 2 arguments file and then memory location function(zephyr_code_relocate file location) + if(NOT IS_ABSOLUTE ${file}) + set(file ${CMAKE_CURRENT_SOURCE_DIR}/${file}) + endif() set_property(TARGET code_data_relocation_target APPEND PROPERTY COMPILE_DEFINITIONS - "${location}:${CMAKE_CURRENT_SOURCE_DIR}/${file}") + "${location}:${file}") endfunction() # Usage: @@ -1020,42 +1067,8 @@ endfunction() # Kconfig is a configuration language developed for the Linux # kernel. The below functions integrate CMake with Kconfig. # -# 2.1 *_if_kconfig -# -# Functions for conditionally including directories and source files -# that have matching KConfig values. -# -# zephyr_library_sources_if_kconfig(fft.c) -# is the same as -# zephyr_library_sources_ifdef(CONFIG_FFT fft.c) -# -# add_subdirectory_if_kconfig(serial) -# is the same as -# add_subdirectory_ifdef(CONFIG_SERIAL serial) -function(add_subdirectory_if_kconfig dir) - string(TOUPPER config_${dir} UPPER_CASE_CONFIG) - add_subdirectory_ifdef(${UPPER_CASE_CONFIG} ${dir}) -endfunction() - -function(target_sources_if_kconfig target scope item) - get_filename_component(item_basename ${item} NAME_WE) - string(TOUPPER CONFIG_${item_basename} UPPER_CASE_CONFIG) - target_sources_ifdef(${UPPER_CASE_CONFIG} ${target} ${scope} ${item}) -endfunction() -function(zephyr_library_sources_if_kconfig item) - get_filename_component(item_basename ${item} NAME_WE) - string(TOUPPER CONFIG_${item_basename} UPPER_CASE_CONFIG) - zephyr_library_sources_ifdef(${UPPER_CASE_CONFIG} ${item}) -endfunction() - -function(zephyr_sources_if_kconfig item) - get_filename_component(item_basename ${item} NAME_WE) - string(TOUPPER CONFIG_${item_basename} UPPER_CASE_CONFIG) - zephyr_sources_ifdef(${UPPER_CASE_CONFIG} ${item}) -endfunction() - -# 2.2 Misc +# 2.1 Misc # # import_kconfig( []) # @@ -1386,15 +1399,26 @@ function(target_cc_option_fallback target scope option1 option2) endfunction() function(target_ld_options target scope) + zephyr_get_parse_args(args ${ARGN}) + list(REMOVE_ITEM ARGN NO_SPLIT) + foreach(option ${ARGN}) - string(MAKE_C_IDENTIFIER check${option} check) + if(args_NO_SPLIT) + set(option ${ARGN}) + endif() + string(JOIN "" check_identifier "check" ${option}) + string(MAKE_C_IDENTIFIER ${check_identifier} check) set(SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${option}") + string(JOIN " " CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} ${option}) zephyr_check_compiler_flag(C "" ${check}) set(CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS}) target_link_libraries_ifdef(${check} ${target} ${scope} ${option}) + + if(args_NO_SPLIT) + break() + endif() endforeach() endfunction() @@ -1437,6 +1461,111 @@ function(toolchain_parse_make_rule input_file include_files) set(${include_files} ${result} PARENT_SCOPE) endfunction() +# 'check_set_linker_property' is a function that check the provided linker +# flag and only set the linker property if the check succeeds +# +# This function is similar in nature to the CMake set_property function, but +# with the extension that it will check that the linker supports the flag before +# setting the property. +# +# APPEND: Flag indicated that the property should be appended to the existing +# value list for the property. +# TARGET: Name of target on which to add the property (commonly: linker) +# PROPERTY: Name of property with the value(s) following immediately after +# property name +function(check_set_linker_property) + set(options APPEND) + set(single_args TARGET) + set(multi_args PROPERTY) + cmake_parse_arguments(LINKER_PROPERTY "${options}" "${single_args}" "${multi_args}" ${ARGN}) + + if(LINKER_PROPERTY_APPEND) + set(APPEND "APPEND") + endif() + + list(GET LINKER_PROPERTY_PROPERTY 0 property) + list(REMOVE_AT LINKER_PROPERTY_PROPERTY 0) + set(option ${LINKER_PROPERTY_PROPERTY}) + + string(MAKE_C_IDENTIFIER check${option} check) + + set(SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${option}") + zephyr_check_compiler_flag(C "" ${check}) + set(CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS}) + + if(${check}) + set_property(TARGET ${LINKER_PROPERTY_TARGET} ${APPEND} PROPERTY ${property} ${option}) + endif() +endfunction() + +# 'set_compiler_property' is a function that sets the property for the C and +# C++ property targets used for toolchain abstraction. +# +# This function is similar in nature to the CMake set_property function, but +# with the extension that it will set the property on both the compile and +# compiler-cpp targets. +# +# APPEND: Flag indicated that the property should be appended to the existing +# value list for the property. +# PROPERTY: Name of property with the value(s) following immediately after +# property name +function(set_compiler_property) + set(options APPEND) + set(multi_args PROPERTY) + cmake_parse_arguments(COMPILER_PROPERTY "${options}" "${single_args}" "${multi_args}" ${ARGN}) + if(COMPILER_PROPERTY_APPEND) + set(APPEND "APPEND") + set(APPEND-CPP "APPEND") + endif() + + set_property(TARGET compiler ${APPEND} PROPERTY ${COMPILER_PROPERTY_PROPERTY}) + set_property(TARGET compiler-cpp ${APPEND} PROPERTY ${COMPILER_PROPERTY_PROPERTY}) +endfunction() + +# 'check_set_compiler_property' is a function that check the provided compiler +# flag and only set the compiler or compiler-cpp property if the check succeeds +# +# This function is similar in nature to the CMake set_property function, but +# with the extension that it will check that the compiler supports the flag +# before setting the property on compiler or compiler-cpp targets. +# +# APPEND: Flag indicated that the property should be appended to the existing +# value list for the property. +# PROPERTY: Name of property with the value(s) following immediately after +# property name +function(check_set_compiler_property) + set(options APPEND) + set(multi_args PROPERTY) + cmake_parse_arguments(COMPILER_PROPERTY "${options}" "${single_args}" "${multi_args}" ${ARGN}) + if(COMPILER_PROPERTY_APPEND) + set(APPEND "APPEND") + set(APPEND-CPP "APPEND") + endif() + + list(GET COMPILER_PROPERTY_PROPERTY 0 property) + list(REMOVE_AT COMPILER_PROPERTY_PROPERTY 0) + + foreach(option ${COMPILER_PROPERTY_PROPERTY}) + if(CONFIG_CPLUSPLUS) + zephyr_check_compiler_flag(CXX ${option} check) + + if(${check}) + set_property(TARGET compiler-cpp ${APPEND-CPP} PROPERTY ${property} ${option}) + set(APPEND-CPP "APPEND") + endif() + endif() + + zephyr_check_compiler_flag(C ${option} check) + + if(${check}) + set_property(TARGET compiler ${APPEND} PROPERTY ${property} ${option}) + set(APPEND "APPEND") + endif() + endforeach() +endfunction() + + # 3.4. Debugging CMake # Usage: @@ -1483,7 +1612,7 @@ endmacro() function(print_usage) if(NOT CMAKE_MAKE_PROGRAM) # Create dummy project, in order to obtain make program for correct usage printing. - project(NONE) + project(dummy_print_usage) endif() message("see usage:") string(REPLACE ";" " " BOARD_ROOT_SPACE_SEPARATED "${BOARD_ROOT}") @@ -1584,3 +1713,92 @@ function(generate_unique_target_name_from_filename filename target_name) set(${target_name} gen_${x}_${unique_chars} PARENT_SCOPE) endfunction() + +# Usage: +# zephyr_file( ...) +# +# Zephyr file function extension. +# This function currently support the following +# +# APPLICATION_ROOT : Check all paths in provided variable, and convert +# those paths that are defined with `-D=` +# to absolute path, relative from `APPLICATION_SOURCE_DIR` +# Issue an error for any relative path not specified +# by user with `-D` +# +# returns an updated list of absolute paths +function(zephyr_file) + set(options APPLICATION_ROOT) + cmake_parse_arguments(FILE "${options}" "" "" ${ARGN}) + if(NOT FILE_APPLICATION_ROOT) + message(FATAL_ERROR "No given to `zephyr_file( ...)` function,\n \ +Please provide one of following: APPLICATION_ROOT") + endif() + + if(FILE_APPLICATION_ROOT) + if(NOT (${ARGC} EQUAL 2)) + math(EXPR ARGC "${ARGC} - 1") + message(FATAL_ERROR "zephyr_file(APPLICATION_ROOT ) takes exactly 1 argument, ${ARGC} were given") + endif() + + # Note: user can do: `-D=` and app can at same + # time specify `list(APPEND )` + # Thus need to check and update only CACHED variables (-D). + set(CACHED_PATH $CACHE{${ARGV1}}) + foreach(path ${CACHED_PATH}) + # The cached variable is relative path, i.e. provided by `-D` or + # `set( CACHE)`, so let's update current scope variable to absolute + # path from `APPLICATION_SOURCE_DIR`. + if(NOT IS_ABSOLUTE ${path}) + set(abs_path ${APPLICATION_SOURCE_DIR}/${path}) + list(FIND ${ARGV1} ${path} index) + if(NOT ${index} LESS 0) + list(REMOVE_AT ${ARGV1} ${index}) + list(INSERT ${ARGV1} ${index} ${abs_path}) + endif() + endif() + endforeach() + + # Now all cached relative paths has been updated. + # Let's check if anyone uses relative path as scoped variable, and fail + foreach(path ${${ARGV1}}) + if(NOT IS_ABSOLUTE ${path}) + message(FATAL_ERROR +"Relative path encountered in scoped variable: ${ARGV1}, value=${path}\n \ +Please adjust any `set(${ARGV1} ${path})` or `list(APPEND ${ARGV1} ${path})`\n \ +to absolute path using `\${CMAKE_CURRENT_SOURCE_DIR}/${path}` or similar. \n \ +Relative paths are only allowed with `-D${ARGV1}=`") + endif() + endforeach() + + # This updates the provided argument in parent scope (callers scope) + set(${ARGV1} ${${ARGV1}} PARENT_SCOPE) + endif() +endfunction() + +# Usage: +# zephyr_get_targets( ) +# +# Get build targets for a given directory and sub-directories. +# +# This functions will traverse the build tree, starting from . +# It will read the `BUILDSYSTEM_TARGETS` for each directory in the build tree +# and return the build types matching the list. +# Example of types: OBJECT_LIBRARY, STATIC_LIBRARY, INTERFACE_LIBRARY, UTILITY. +# +# returns a list of targets in matching the required . +function(zephyr_get_targets directory types targets) + get_property(sub_directories DIRECTORY ${directory} PROPERTY SUBDIRECTORIES) + get_property(dir_targets DIRECTORY ${directory} PROPERTY BUILDSYSTEM_TARGETS) + foreach(dir_target ${dir_targets}) + get_property(target_type TARGET ${dir_target} PROPERTY TYPE) + if(${target_type} IN_LIST types) + list(APPEND ${targets} ${dir_target}) + endif() + endforeach() + + foreach(directory ${sub_directories}) + zephyr_get_targets(${directory} "${types}" ${targets}) + endforeach() + set(${targets} ${${targets}} PARENT_SCOPE) +endfunction() diff --git a/cmake/flash/CMakeLists.txt b/cmake/flash/CMakeLists.txt index 6cba4e9d94d7f0..3f2c059255370b 100644 --- a/cmake/flash/CMakeLists.txt +++ b/cmake/flash/CMakeLists.txt @@ -1,20 +1,64 @@ # SPDX-License-Identifier: Apache-2.0 -add_custom_target(runner_yml_props_target) - -function(runner_yml_write content) +function(runners_yaml_append content) # Append ${content}\n to a target property which is later evaluated as a # generator expression when writing the flash runner yaml file. # We define this function here to have access to the `flash` target. set_property( - TARGET runner_yml_props_target + TARGET runners_yaml_props_target APPEND_STRING PROPERTY yaml_contents "${content}\n" ) endfunction() +function(get_runners_prop prop out_var default_value) + # Get property 'prop' from runners_yaml_props_target, storing its + # value in 'out_var'. If the property is not found (value is + # ...-NOTFOUND), 'out_var' is set to 'default_value'. + + get_target_property(out runners_yaml_props_target "${prop}") + + if("${out}" STREQUAL "out-NOTFOUND") + set("${out_var}" "${default_value}" PARENT_SCOPE) + else() + set("${out_var}" "${out}" PARENT_SCOPE) + endif() +endfunction() + +function(runners_yaml_append_config) + # Append the common configuration values to the relevant property target. + + runners_yaml_append("\n# Common runner configuration values.") + runners_yaml_append("config:") + runners_yaml_append(" board_dir: ${BOARD_DIR}") + get_runners_prop(elf_file elf "${KERNEL_ELF_NAME}") + runners_yaml_append(" # Build outputs:") + runners_yaml_append(" elf_file: ${elf}") + if(CONFIG_BUILD_OUTPUT_HEX) + get_runners_prop(hex_file hex "${KERNEL_HEX_NAME}") + runners_yaml_append(" hex_file: ${hex}") + endif() + if(CONFIG_BUILD_OUTPUT_BIN) + get_runners_prop(bin_file bin "${KERNEL_BIN_NAME}") + runners_yaml_append(" bin_file: ${bin}") + endif() + + if(CMAKE_GDB OR OPENOCD OR OPENOCD_DEFAULT_PATH) + runners_yaml_append(" # Host tools:") + endif() + if(CMAKE_GDB) + runners_yaml_append(" gdb: ${CMAKE_GDB}") + endif() + if(OPENOCD) + runners_yaml_append(" openocd: ${OPENOCD}") + endif() + if(OPENOCD_DEFAULT_PATH) + runners_yaml_append(" openocd_search: ${OPENOCD_DEFAULT_PATH}") + endif() + runners_yaml_append("") +endfunction() # Save runner state in a YAML file, and put that YAML file's location # in the cache. @@ -23,63 +67,45 @@ function(create_runners_yaml) set(runners_yaml "${PROJECT_BINARY_DIR}/runners.yaml") - runner_yml_write("# Available runners configured by board.cmake.\nrunners:") + runners_yaml_append("# Available runners configured by board.cmake.\nrunners:") foreach(runner ${runners}) - runner_yml_write("- ${runner}") + runners_yaml_append("- ${runner}") endforeach() if(DEFINED BOARD_FLASH_RUNNER) - runner_yml_write("\n# Default flash runner if --runner is not given.") - runner_yml_write("flash-runner: ${BOARD_FLASH_RUNNER}") + runners_yaml_append("\n# Default flash runner if --runner is not given.") + runners_yaml_append("flash-runner: ${BOARD_FLASH_RUNNER}") endif() if(DEFINED BOARD_DEBUG_RUNNER) - runner_yml_write("\n# Default debug runner if --runner is not given.") - runner_yml_write("debug-runner: ${BOARD_DEBUG_RUNNER}") + runners_yaml_append("\n# Default debug runner if --runner is not given.") + runners_yaml_append("debug-runner: ${BOARD_DEBUG_RUNNER}") endif() - runner_yml_write("\n# Default command line arguments. The ones in \"common\" are always given.\n# The other sub-keys give runner-specific arguments.") - runner_yml_write("args:\n common:") - - # Get default settings for common arguments. - # - # TODO: clean up the host tools arguments. These are really runner - # specific; they only continue to exist here out of inertia. - - runner_yml_write("\ - - --board-dir=${BOARD_DIR} - - --elf-file=${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} - - --hex-file=${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME} - - --bin-file=${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}") - if (DEFINED CMAKE_GDB) - runner_yml_write(" - --gdb=${CMAKE_GDB}") - endif() - if (DEFINED OPENOCD) - runner_yml_write(" - --openocd=${OPENOCD}") - endif() - if(DEFINED OPENOCD_DEFAULT_PATH) - runner_yml_write(" - --openocd-search=${OPENOCD_DEFAULT_PATH}") - endif() + # Sets up common runner configuration values. + runners_yaml_append_config() # Get runner-specific arguments set in the board files. + runners_yaml_append("# Runner specific arguments") + runners_yaml_append("args:") foreach(runner ${runners}) string(MAKE_C_IDENTIFIER ${runner} runner_id) - runner_yml_write(" ${runner}:") + runners_yaml_append(" ${runner}:") get_property(args GLOBAL PROPERTY "BOARD_RUNNER_ARGS_${runner_id}") if(args) # Usually, the runner has arguments. Append them to runners.yaml, # one per line. foreach(arg ${args}) - runner_yml_write(" - ${arg}") + runners_yaml_append(" - ${arg}") endforeach() else() # If the runner doesn't need any arguments, just use an empty list. - runner_yml_write(" []\n") + runners_yaml_append(" []\n") endif() endforeach() # Write the final contents and set its location in the cache. file(GENERATE OUTPUT "${runners_yaml}" CONTENT - $) + $) set(ZEPHYR_RUNNERS_YAML "${runners_yaml}" CACHE INTERNAL "a configuration file for the runners Python package") endfunction() @@ -93,65 +119,8 @@ get_property(RUNNERS GLOBAL PROPERTY ZEPHYR_RUNNERS) # # Everything is marked with FORCE so that re-running CMake updates the # configuration if the board files change. -# -# TODO: drop the hack in sign.py that uses cached_runner_config to -# guess the .bin and .hex files, then delete the cache variables. if(RUNNERS) create_runners_yaml(${RUNNERS}) - - set(ZEPHYR_RUNNERS ${RUNNERS} CACHE INTERNAL "Available runners") - - # Runner configuration. This is provided to all runners, and is - # distinct from the free-form arguments provided by e.g. - # board_runner_args(). - # - # Always applicable: - set(ZEPHYR_RUNNER_CONFIG_BOARD_DIR "${BOARD_DIR}" - CACHE STRING "Board definition directory" FORCE) - set(ZEPHYR_RUNNER_CONFIG_KERNEL_ELF "${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" - CACHE STRING "Path to kernel image in ELF format" FORCE) - get_property(HEX_FILES_TO_MERGE GLOBAL PROPERTY HEX_FILES_TO_MERGE) - if(HEX_FILES_TO_MERGE) - set(ZEPHYR_RUNNER_CONFIG_KERNEL_HEX "${PROJECT_BINARY_DIR}/${MERGED_HEX_NAME}" - CACHE STRING "Path to merged image in Intel Hex format" FORCE) - else() - set(ZEPHYR_RUNNER_CONFIG_KERNEL_HEX "${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME}" - CACHE STRING "Path to kernel image in Intel Hex format" FORCE) - endif() - set(ZEPHYR_RUNNER_CONFIG_KERNEL_BIN "${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}" - CACHE STRING "Path to kernel image as raw binary" FORCE) - # Not always applicable, but so often needed that they're provided - # by default: (TODO: clean this up) - if(DEFINED CMAKE_GDB) - set(ZEPHYR_RUNNER_CONFIG_GDB "${CMAKE_GDB}" - CACHE STRING "Path to GDB binary, if applicable" FORCE) - endif() - if(DEFINED OPENOCD) - set(ZEPHYR_RUNNER_CONFIG_OPENOCD "${OPENOCD}" - CACHE STRING "Path to openocd binary, if applicable" FORCE) - endif() - if(DEFINED OPENOCD_DEFAULT_PATH) - set(ZEPHYR_RUNNER_CONFIG_OPENOCD_SEARCH "${OPENOCD_DEFAULT_PATH}" - CACHE STRING "Path to add to openocd search path, if applicable" FORCE) - endif() - - # Runner-specific command line arguments obtained from the board's - # build scripts, the application's scripts, etc. - foreach(runner ${RUNNERS}) - string(MAKE_C_IDENTIFIER ${runner} runner_id) - # E.g. args = BOARD_RUNNER_ARGS_openocd, BOARD_RUNNER_ARGS_dfu_util, etc. - get_property(runner_args GLOBAL PROPERTY "BOARD_RUNNER_ARGS_${runner_id}") - set(ZEPHYR_RUNNER_ARGS_${runner_id} ${runner_args} CACHE STRING - "Runner-specific arguments for ${runner}" FORCE) - endforeach() -endif() -if(BOARD_FLASH_RUNNER) - set(ZEPHYR_BOARD_FLASH_RUNNER ${BOARD_FLASH_RUNNER} CACHE STRING - "Default runner for flashing binaries" FORCE) -endif() -if(BOARD_DEBUG_RUNNER) - set(ZEPHYR_BOARD_DEBUG_RUNNER ${BOARD_DEBUG_RUNNER} CACHE STRING - "Default runner for debugging" FORCE) endif() if(DEFINED ENV{WEST_DIR} AND NOT WEST_DIR) @@ -179,8 +148,9 @@ foreach(target flash debug debugserver attach) elseif(target STREQUAL attach) set(comment "Debugging ${BOARD}") endif() + string(TOUPPER ${target} TARGET_UPPER) - list(APPEND FLASH_DEPS ${logical_target_for_zephyr_elf}) + list(APPEND RUNNERS_DEPS ${logical_target_for_zephyr_elf}) # Enable verbose output, if requested. if(CMAKE_VERBOSE_MAKEFILE) @@ -198,7 +168,8 @@ foreach(target flash debug debugserver attach) ${RUNNER_VERBOSE} ${target} --skip-rebuild - DEPENDS ${FLASH_DEPS} + DEPENDS ${RUNNERS_DEPS} + $ WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} ) @@ -209,6 +180,16 @@ foreach(target flash debug debugserver attach) ${comment} USES_TERMINAL ) + + # This is an artificial target to allow west to ensure all dependencies of + # target is build before carrying out the actual command. + # This allows `west` to run just the dependencies before flashing. + add_custom_target(west_${target}_depends + COMMAND ${CMAKE_COMMAND} -E echo "" + DEPENDS ${RUNNERS_DEPS} + $ + USES_TERMINAL + ) else() add_custom_target(${target} COMMAND ${CMAKE_COMMAND} -E echo \"West was not found in path. To support diff --git a/cmake/gcc-m-cpu.cmake b/cmake/gcc-m-cpu.cmake index 62a51e1fba4c04..8d6f10de023d57 100644 --- a/cmake/gcc-m-cpu.cmake +++ b/cmake/gcc-m-cpu.cmake @@ -8,6 +8,8 @@ if("${ARCH}" STREQUAL "arm") set(GCC_M_CPU cortex-m0) elseif(CONFIG_CPU_CORTEX_M0PLUS) set(GCC_M_CPU cortex-m0plus) + elseif(CONFIG_CPU_CORTEX_M1) + set(GCC_M_CPU cortex-m1) elseif(CONFIG_CPU_CORTEX_M3) set(GCC_M_CPU cortex-m3) elseif(CONFIG_CPU_CORTEX_M4) diff --git a/cmake/generic_toolchain.cmake b/cmake/generic_toolchain.cmake index 1f2b9bfeafd1ba..53d0582309b0bd 100644 --- a/cmake/generic_toolchain.cmake +++ b/cmake/generic_toolchain.cmake @@ -9,9 +9,10 @@ if(NOT TOOLCHAIN_ROOT) set(TOOLCHAIN_ROOT ${ZEPHYR_BASE}) endif() endif() +zephyr_file(APPLICATION_ROOT TOOLCHAIN_ROOT) # Don't inherit compiler flags from the environment -foreach(var CFLAGS CXXFLAGS) +foreach(var AFLAGS CFLAGS CXXFLAGS CPPFLAGS LDFLAGS) if(DEFINED ENV{${var}}) message(WARNING "The environment variable '${var}' was set to $ENV{${var}}, but Zephyr ignores flags from the environment. Use 'cmake -DEXTRA_${var}=$ENV{${var}}' instead.") @@ -47,7 +48,7 @@ if("${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "zephyr") set(TOOLCHAIN_HOME ${HOST_TOOLS_HOME}) endif() -set(TOOLCHAIN_ROOT ${TOOLCHAIN_ROOT} CACHE STRING "Zephyr toolchain root") +set(TOOLCHAIN_ROOT ${TOOLCHAIN_ROOT} CACHE STRING "Zephyr toolchain root" FORCE) assert(TOOLCHAIN_ROOT "Zephyr toolchain root path invalid: please set the TOOLCHAIN_ROOT-variable") # Set cached ZEPHYR_TOOLCHAIN_VARIANT. diff --git a/cmake/host-tools.cmake b/cmake/host-tools.cmake index 63f18ee351308b..cb7bf2e2815ebe 100644 --- a/cmake/host-tools.cmake +++ b/cmake/host-tools.cmake @@ -2,50 +2,6 @@ include(${ZEPHYR_BASE}/cmake/toolchain/zephyr/host-tools.cmake) -# west is an optional dependency -find_program( - WEST - west - ) -if(${WEST} STREQUAL WEST-NOTFOUND) - unset(WEST) -else() - # If west is found, make sure its version matches the minimum - # required one. - set(MIN_WEST_VERSION 0.7.1) - execute_process( - COMMAND - ${PYTHON_EXECUTABLE} - -c - "import west.version; print(west.version.__version__, end='')" - OUTPUT_VARIABLE west_version - RESULT_VARIABLE west_version_output_result - ) - - if(west_version_output_result) - message(FATAL_ERROR "Unable to import west.version from '${PYTHON_EXECUTABLE}'") - endif() - - if(${west_version} VERSION_LESS ${MIN_WEST_VERSION}) - message(FATAL_ERROR "The detected west version is unsupported.\n\ - The version was found to be ${west_version}:\n\ - ${item}\n\ - But the minimum supported version is ${MIN_WEST_VERSION}\n\ - Please upgrade with:\n\ - pip3 install --upgrade west") - endif() - # Just output information for a single version. This will still work - # even after output is one line. - message(STATUS "Found west: ${WEST} (found suitable version \"${west_version}\", minimum required is \"${MIN_WEST_VERSION}\")") - - execute_process( - COMMAND ${WEST} topdir - OUTPUT_VARIABLE WEST_TOPDIR - OUTPUT_STRIP_TRAILING_WHITESPACE - WORKING_DIRECTORY ${ZEPHYR_BASE} - ) -endif() - # dtc is an optional dependency find_program( DTC @@ -59,17 +15,26 @@ if(DTC) COMMAND ${DTC} --version OUTPUT_VARIABLE dtc_version_output + ERROR_VARIABLE dtc_error_output + RESULT_VARIABLE dtc_status ) - string(REGEX MATCH "Version: DTC ([0-9]+[.][0-9]+[.][0-9]+).*" out_var ${dtc_version_output}) - # Since it is optional, an outdated version is not an error. If an - # outdated version is discovered, print a warning and proceed as if - # DTC were not installed. - if(${CMAKE_MATCH_1} VERSION_GREATER ${MIN_DTC_VERSION}) - message(STATUS "Found dtc: ${DTC} (found suitable version \"${CMAKE_MATCH_1}\", minimum required is \"${MIN_DTC_VERSION}\")") + if(${dtc_status} EQUAL 0) + string(REGEX MATCH "Version: DTC ([0-9]+[.][0-9]+[.][0-9]+).*" out_var ${dtc_version_output}) + + # Since it is optional, an outdated version is not an error. If an + # outdated version is discovered, print a warning and proceed as if + # DTC were not installed. + if(${CMAKE_MATCH_1} VERSION_GREATER ${MIN_DTC_VERSION}) + message(STATUS "Found dtc: ${DTC} (found suitable version \"${CMAKE_MATCH_1}\", minimum required is \"${MIN_DTC_VERSION}\")") + else() + message(WARNING + "Could NOT find dtc: Found unsuitable version \"${CMAKE_MATCH_1}\", but required is at least \"${MIN_DTC_VERSION}\" (found ${DTC}). Optional devicetree error checking with dtc will not be performed.") + set(DTC DTC-NOTFOUND) + endif() else() message(WARNING - "Could NOT find dtc: Found unsuitable version \"${CMAKE_MATCH_1}\", but required is at least \"${MIN_DTC_VERSION}\" (found ${DTC}). Optional devicetree error checking with dtc will not be performed.") + "Could NOT find working dtc: Found dtc (${DTC}), but failed to load with:\n ${dtc_error_output}") set(DTC DTC-NOTFOUND) endif() endif() @@ -92,5 +57,13 @@ find_program( bossac ) +# imgtool is an optional dependency (the build may also fall back to +# scripts/imgtool.py in the mcuboot repository if that's present in +# some cases) +find_program( + IMGTOOL + imgtool + ) + # TODO: Should we instead find one qemu binary for each ARCH? # TODO: This will probably need to be re-organized when there exists more than one SDK. diff --git a/cmake/kconfig.cmake b/cmake/kconfig.cmake index ab1b891d17b89e..03aab1a157b1ef 100644 --- a/cmake/kconfig.cmake +++ b/cmake/kconfig.cmake @@ -5,7 +5,36 @@ file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/generated) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/config) +# Support multiple SOC_ROOT +set(OPERATION WRITE) +foreach(root ${SOC_ROOT}) + file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.soc.defconfig + "osource \"${root}/soc/$(ARCH)/*/Kconfig.defconfig\"\n" + ) + file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.soc + "osource \"${root}/soc/$(ARCH)/*/Kconfig.soc\"\n" + ) + file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.soc.arch + "osource \"${root}/soc/$(ARCH)/Kconfig\"\n" + "osource \"${root}/soc/$(ARCH)/*/Kconfig\"\n" + ) + set(OPERATION APPEND) +endforeach() + +# Support multiple shields in BOARD_ROOT +set(OPERATION WRITE) +foreach(root ${BOARD_ROOT}) + file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.shield.defconfig + "osource \"${root}/boards/shields/*/Kconfig.defconfig\"\n" + ) + file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.shield + "osource \"${root}/boards/shields/*/Kconfig.shield\"\n" + ) + set(OPERATION APPEND) +endforeach() + if(KCONFIG_ROOT) + zephyr_file(APPLICATION_ROOT KCONFIG_ROOT) # KCONFIG_ROOT has either been specified as a CMake variable or is # already in the CMakeCache.txt. This has precedence. elseif(EXISTS ${APPLICATION_SOURCE_DIR}/Kconfig) @@ -32,23 +61,36 @@ endif() # separated list instead. string(REPLACE ";" "?" DTS_ROOT_BINDINGS "${DTS_ROOT_BINDINGS}") -set(ENV{srctree} ${ZEPHYR_BASE}) -set(ENV{KERNELVERSION} ${KERNELVERSION}) -set(ENV{KCONFIG_CONFIG} ${DOTCONFIG}) -set(ENV{PYTHON_EXECUTABLE} ${PYTHON_EXECUTABLE}) - -# Set environment variables so that Kconfig can prune Kconfig source -# files for other architectures -set(ENV{ARCH} ${ARCH}) -set(ENV{BOARD_DIR} ${BOARD_DIR}) -set(ENV{SOC_DIR} ${SOC_DIR}) -set(ENV{SHIELD_AS_LIST} "${SHIELD_AS_LIST}") -set(ENV{CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}) -set(ENV{ARCH_DIR} ${ARCH_DIR}) -set(ENV{DTS_POST_CPP} ${DTS_POST_CPP}) -set(ENV{DTS_ROOT_BINDINGS} "${DTS_ROOT_BINDINGS}") -set(ENV{TOOLCHAIN_KCONFIG_DIR} "${TOOLCHAIN_KCONFIG_DIR}") -set(ENV{EXTRA_DTC_FLAGS} ${EXTRA_DTC_FLAGS}) +# Export each `ZEPHYR__MODULE_DIR` to Kconfig. +# This allows Kconfig files to refer relative from a modules root as: +# source "$(ZEPHYR_FOO_MODULE_DIR)/Kconfig" +foreach(module_name ${ZEPHYR_MODULE_NAMES}) + string(TOUPPER ${module_name} MODULE_NAME_UPPER) + list(APPEND + ZEPHYR_KCONFIG_MODULES_DIR + "ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR=${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR}" + ) +endforeach() + +# A list of common environment settings used when invoking Kconfig during CMake +# configure time or menuconfig and related build target. +set(COMMON_KCONFIG_ENV_SETTINGS + PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} + srctree=${ZEPHYR_BASE} + KERNELVERSION=${KERNELVERSION} + KCONFIG_CONFIG=${DOTCONFIG} + # Set environment variables so that Kconfig can prune Kconfig source + # files for other architectures + ARCH=${ARCH} + ARCH_DIR=${ARCH_DIR} + BOARD_DIR=${BOARD_DIR} + SHIELD_AS_LIST=${SHIELD_AS_LIST} + KCONFIG_BINARY_DIR=${KCONFIG_BINARY_DIR} + TOOLCHAIN_KCONFIG_DIR=${TOOLCHAIN_KCONFIG_DIR} + EDT_PICKLE=${EDT_PICKLE} + # Export all Zephyr modules to Kconfig + ${ZEPHYR_KCONFIG_MODULES_DIR} +) # Allow out-of-tree users to add their own Kconfig python frontend # targets by appending targets to the CMake list @@ -80,19 +122,9 @@ foreach(kconfig_target add_custom_target( ${kconfig_target} ${CMAKE_COMMAND} -E env - PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} - srctree=${ZEPHYR_BASE} - KERNELVERSION=${KERNELVERSION} ZEPHYR_BASE=${ZEPHYR_BASE} - KCONFIG_CONFIG=${DOTCONFIG} - ARCH=$ENV{ARCH} - BOARD_DIR=$ENV{BOARD_DIR} - SOC_DIR=$ENV{SOC_DIR} - SHIELD_AS_LIST=$ENV{SHIELD_AS_LIST} - CMAKE_BINARY_DIR=$ENV{CMAKE_BINARY_DIR} ZEPHYR_TOOLCHAIN_VARIANT=${ZEPHYR_TOOLCHAIN_VARIANT} - TOOLCHAIN_KCONFIG_DIR=${TOOLCHAIN_KCONFIG_DIR} - ARCH_DIR=$ENV{ARCH_DIR} + ${COMMON_KCONFIG_ENV_SETTINGS} EXTRA_DTC_FLAGS=${EXTRA_DTC_FLAGS} DTS_POST_CPP=${DTS_POST_CPP} DTS_ROOT_BINDINGS=${DTS_ROOT_BINDINGS} @@ -101,6 +133,7 @@ foreach(kconfig_target ${KCONFIG_ROOT} WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig USES_TERMINAL + COMMAND_EXPAND_LISTS ) endforeach() @@ -198,7 +231,8 @@ else() endif() execute_process( - COMMAND + COMMAND ${CMAKE_COMMAND} -E env + ${COMMON_KCONFIG_ENV_SETTINGS} ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/kconfig/kconfig.py --zephyr-base=${ZEPHYR_BASE} @@ -237,7 +271,7 @@ foreach(kconfig_input set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig_input}) endforeach() -add_custom_target(config-sanitycheck DEPENDS ${DOTCONFIG}) +add_custom_target(config-twister DEPENDS ${DOTCONFIG}) # Remove the CLI Kconfig symbols from the namespace and # CMakeCache.txt. If the symbols end up in DOTCONFIG they will be diff --git a/cmake/linker/arcmwdt/target.cmake b/cmake/linker/arcmwdt/target.cmake new file mode 100644 index 00000000000000..5c2da558297664 --- /dev/null +++ b/cmake/linker/arcmwdt/target.cmake @@ -0,0 +1,212 @@ +# SPDX-License-Identifier: Apache-2.0 + +find_program(CMAKE_LINKER ${CROSS_COMPILE}lldac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + +# the prefix to transfer linker options from compiler +set_ifndef(LINKERFLAGPREFIX -Wl,) + +# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen} +# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time +macro(configure_linker_script linker_script_gen linker_pass_define) + set(extra_dependencies ${ARGN}) + + # Different generators deal with depfiles differently. + if(CMAKE_GENERATOR STREQUAL "Unix Makefiles") + # Note that the IMPLICIT_DEPENDS option is currently supported only + # for Makefile generators and will be ignored by other generators. + set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT}) + elseif(CMAKE_GENERATOR STREQUAL "Ninja") + # Using DEPFILE with other generators than Ninja is an error. + set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep) + else() + # TODO: How would the linker script dependencies work for non-linker + # script generators. + message(STATUS "Warning; this generator is not well supported. The + Linker script may not be regenerated when it should.") + set(linker_script_dep "") + endif() + + zephyr_get_include_directories_for_lang(C current_includes) + get_filename_component(base_name ${CMAKE_CURRENT_BINARY_DIR} NAME) + get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES) + +# the command to generate linker file from template + add_custom_command( + OUTPUT ${linker_script_gen} + DEPENDS + ${LINKER_SCRIPT} + ${extra_dependencies} + # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS' + ${linker_script_dep} + COMMAND ${CMAKE_C_COMPILER} + -x c + ${NOSYSDEF_CFLAG} + -Hnocopyr + -MD -MF ${linker_script_gen}.dep -MT ${base_name}/${linker_script_gen} + -D_LINKER + -D_ASMLANGUAGE + ${current_includes} + ${current_defines} + ${linker_pass_define} + ${LINKER_SCRIPT} + -P + -o ${linker_script_gen} + VERBATIM + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMAND_EXPAND_LISTS +) +endmacro() + +# Force symbols to be entered in the output file as undefined symbols +function(toolchain_ld_force_undefined_symbols) + foreach(symbol ${ARGN}) + zephyr_link_libraries(${LINKERFLAGPREFIX}-u${symbol}) + endforeach() +endfunction() + +# Link a target to given libraries with toolchain-specific argument order +# +# Usage: +# toolchain_ld_link_elf( +# TARGET_ELF +# OUTPUT_MAP +# LIBRARIES_PRE_SCRIPT [libraries_pre_script] +# LINKER_SCRIPT +# LIBRARIES_POST_SCRIPT [libraries_post_script] +# DEPENDENCIES [dependencies] +# ) +function(toolchain_ld_link_elf) + cmake_parse_arguments( + TOOLCHAIN_LD_LINK_ELF # prefix of output variables + "" # list of names of the boolean arguments + "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments + "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments + ${ARGN} # input args to parse + ) + + target_link_libraries( + ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} + ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} + ${LINKERFLAGPREFIX}-T${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} + ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} + ${LINKERFLAGPREFIX}--gc-sections + ${LINKERFLAGPREFIX}--entry=__start + ${LINKERFLAGPREFIX}--Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} + ${LINKERFLAGPREFIX}--whole-archive + ${ZEPHYR_LIBS_PROPERTY} + ${LINKERFLAGPREFIX}--no-whole-archive + kernel + $ + ${LIB_INCLUDE_DIR} + -L${PROJECT_BINARY_DIR} + ${TOOLCHAIN_LIBS} + + ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} + ) +endfunction(toolchain_ld_link_elf) + +# linker options of temporary linkage for code generation +macro(toolchain_ld_baremetal) + zephyr_ld_options( + -Hlld + -Hnocopyr + -Hnosdata + -Hnocrt + -Xtimer0 # to suppress the warning message + -Hnoxcheck + -Hnocplus + -Hcl + -Hheap=0 + -Hnoivt + ) + + # Funny thing is if this is set to =error, some architectures will + # skip this flag even though the compiler flag check passes + # (e.g. ARC and Xtensa). So warning should be the default for now. + # + # Skip this for native application as Zephyr only provides + # additions to the host toolchain linker script. The relocation + # sections (.rel*) requires us to override those provided + # by host toolchain. As we can't account for all possible + # combination of compiler and linker on all machines used + # for development, it is better to turn this off. + # + # CONFIG_LINKER_ORPHAN_SECTION_PLACE is to place the orphan sections + # without any warnings or errors, which is the default behavior. + # So there is no need to explicitly set a linker flag. + if(CONFIG_LINKER_ORPHAN_SECTION_WARN) + message(WARNING "MWDT toolchain does not support + CONFIG_LINKER_ORPHAN_SECTION_WARN") + elseif(CONFIG_LINKER_ORPHAN_SECTION_ERROR) + zephyr_ld_options( + ${LINKERFLAGPREFIX}--orphan-handling=error) + endif() +endmacro() + +# base linker options +macro(toolchain_ld_base) + if(NOT PROPERTY_LINKER_SCRIPT_DEFINES) + set_property(GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES -D__MWDT_LINKER_CMD__) + endif() + + # Sort the common symbols and each input section by alignment + # in descending order to minimize padding between these symbols. + zephyr_ld_option_ifdef( + CONFIG_LINKER_SORT_BY_ALIGNMENT + ${LINKERFLAGPREFIX}--sort-section=alignment + ) +endmacro() + +# generate linker script snippts from configure files +macro(toolchain_ld_configure_files) + configure_file( + $ENV{ZEPHYR_BASE}/include/arch/common/app_data_alignment.ld + ${PROJECT_BINARY_DIR}/include/generated/app_data_alignment.ld) + + configure_file( + $ENV{ZEPHYR_BASE}/include/linker/app_smem.ld + ${PROJECT_BINARY_DIR}/include/generated/app_smem.ld) + + configure_file( + $ENV{ZEPHYR_BASE}/include/linker/app_smem_aligned.ld + ${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld) + + configure_file( + $ENV{ZEPHYR_BASE}/include/linker/app_smem_unaligned.ld + ${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld) +endmacro() + +# link C++ libraries +macro(toolchain_ld_cpp) + zephyr_link_libraries( + -Hcppmw -Hcplus + ) +endmacro() + +# use linker for relocation +macro(toolchain_ld_relocation) + set(MEM_RELOCATION_LD "${PROJECT_BINARY_DIR}/include/generated/linker_relocate.ld") + set(MEM_RELOCATION_SRAM_DATA_LD + "${PROJECT_BINARY_DIR}/include/generated/linker_sram_data_relocate.ld") + set(MEM_RELOCATION_SRAM_BSS_LD + "${PROJECT_BINARY_DIR}/include/generated/linker_sram_bss_relocate.ld") + set(MEM_RELOCATION_CODE "${PROJECT_BINARY_DIR}/code_relocation.c") + + add_custom_command( + OUTPUT ${MEM_RELOCATION_CODE} ${MEM_RELOCATION_LD} + COMMAND + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/gen_relocate_app.py + $<$:--verbose> + -d ${APPLICATION_BINARY_DIR} + -i '$' + -o ${MEM_RELOCATION_LD} + -s ${MEM_RELOCATION_SRAM_DATA_LD} + -b ${MEM_RELOCATION_SRAM_BSS_LD} + -c ${MEM_RELOCATION_CODE} + DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY} + ) + + add_library(code_relocation_source_lib STATIC ${MEM_RELOCATION_CODE}) + target_link_libraries(code_relocation_source_lib zephyr_interface) +endmacro() diff --git a/cmake/linker/ld/clang/linker_flags.cmake b/cmake/linker/ld/clang/linker_flags.cmake new file mode 100644 index 00000000000000..5f4c036b68c807 --- /dev/null +++ b/cmake/linker/ld/clang/linker_flags.cmake @@ -0,0 +1,9 @@ +# The coverage linker flag is specific for clang. +if (NOT CONFIG_COVERAGE_GCOV) + set_property(TARGET linker PROPERTY coverage --coverage) +endif() + +# ld/clang linker flags for sanitizing. +check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address -fsanitize=address) + +check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_undefined -fsanitize=undefined) diff --git a/cmake/linker/ld/gcc/linker_flags.cmake b/cmake/linker/ld/gcc/linker_flags.cmake new file mode 100644 index 00000000000000..82a526a84e40fd --- /dev/null +++ b/cmake/linker/ld/gcc/linker_flags.cmake @@ -0,0 +1,14 @@ +# The coverage linker flag is specific for gcc. + +# Using a config check is ok for now, but in future it would be desired if +# linker flags themselves are not depending on actual configurations. +# All flags should be described, and the caller should now the flag name to use. +if (NOT CONFIG_COVERAGE_GCOV) + set_property(TARGET linker PROPERTY coverage -lgcov) +endif() + +# ld/gcc linker flags for sanitizing. +check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address -lasan) +check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address -fsanitize=address) + +check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_undefined -fsanitize=undefined) diff --git a/cmake/linker/ld/host-gcc/linker_flags.cmake b/cmake/linker/ld/host-gcc/linker_flags.cmake new file mode 100644 index 00000000000000..24b1e2f0cf4b56 --- /dev/null +++ b/cmake/linker/ld/host-gcc/linker_flags.cmake @@ -0,0 +1,2 @@ +# The host-gcc supports the same flags as any other gcc. +include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/gcc/linker_flags.cmake) diff --git a/cmake/linker/ld/linker_flags.cmake b/cmake/linker/ld/linker_flags.cmake new file mode 100644 index 00000000000000..0b16f2b094182b --- /dev/null +++ b/cmake/linker/ld/linker_flags.cmake @@ -0,0 +1,8 @@ +check_set_linker_property(TARGET linker PROPERTY memusage "${LINKERFLAGPREFIX},--print-memory-usage") + +# Some linker flags might not be purely ld specific, but a combination of +# linker and compiler, such as: +# --coverage for clang +# --gcov for gcc +# So load those flags now. +include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/${COMPILER}/linker_flags.cmake OPTIONAL) diff --git a/cmake/linker/ld/target.cmake b/cmake/linker/ld/target.cmake index d8715c08026ff7..5f2cdd07b268f9 100644 --- a/cmake/linker/ld/target.cmake +++ b/cmake/linker/ld/target.cmake @@ -51,6 +51,7 @@ macro(configure_linker_script linker_script_gen linker_pass_define) -o ${linker_script_gen} VERBATIM WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMAND_EXPAND_LISTS ) endmacro() diff --git a/cmake/linker/ld/target_base.cmake b/cmake/linker/ld/target_base.cmake index a96c6d637c989f..0eee30ea85dac0 100644 --- a/cmake/linker/ld/target_base.cmake +++ b/cmake/linker/ld/target_base.cmake @@ -12,6 +12,9 @@ macro(toolchain_ld_base) # LINKERFLAGPREFIX comes from linker/ld/target.cmake zephyr_ld_options( ${TOOLCHAIN_LD_FLAGS} + ) + + zephyr_ld_options( ${LINKERFLAGPREFIX},--gc-sections ${LINKERFLAGPREFIX},--build-id=none ) diff --git a/cmake/linker/linker_flags_template.cmake b/cmake/linker/linker_flags_template.cmake new file mode 100644 index 00000000000000..6cb34fd28427d9 --- /dev/null +++ b/cmake/linker/linker_flags_template.cmake @@ -0,0 +1,16 @@ +# coverage is a property holding the linker flag required for coverage support on the toolchain. +# For example, on ld/gcc this would be: -lgcov +# Set the property for the corresponding flags of the given toolchain. +set_property(TARGET linker PROPERTY coverage) + +# Linker flags for sanitizing. +check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address) + +check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_undefined) + +# Linker flag for printing of memusage. +# Set this flag if the linker supports reporting of memusage as part of link, +# such as ls --print-memory-usage flag. +# If memory reporting is a post build command, please use +# cmake/bintools/bintools.cmake insted. +check_set_linker_property(TARGET linker PROPERTY memusage) diff --git a/cmake/makefile_exports/CMakeLists.txt b/cmake/makefile_exports/CMakeLists.txt index e864c02135ac55..7120c9826f0612 100644 --- a/cmake/makefile_exports/CMakeLists.txt +++ b/cmake/makefile_exports/CMakeLists.txt @@ -1,6 +1,11 @@ # Copyright (c) 2020 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 + +zephyr_get_compile_options_for_lang(ASM ASM_compile_options) +zephyr_get_compile_options_for_lang(C C_compile_options) +zephyr_get_compile_options_for_lang(CXX CXX_compile_options) + set(exports " CC = ${CMAKE_C_COMPILER} @@ -11,7 +16,7 @@ AS = ${CMAKE_AS} AR = ${CMAKE_AR} NM = ${CMAKE_NM} GDB = ${CMAKE_GDB} -Z_CFLAGS = -I$, -I> -isystem $, -isystem > -D$, -D> $, > +Z_CFLAGS = -I$, -I> -isystem $, -isystem > -D$, -D> $<$:${ASM_compile_options}> $<$:${C_compile_options}> $<$:${CXX_compile_options}> " ) diff --git a/cmake/mcuboot.cmake b/cmake/mcuboot.cmake new file mode 100644 index 00000000000000..70df5e5904ba04 --- /dev/null +++ b/cmake/mcuboot.cmake @@ -0,0 +1,142 @@ +# Copyright (c) 2020 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# This file includes extra build system logic that is enabled when +# CONFIG_BOOTLOADER_MCUBOOT=y. +# +# It builds signed binaries using imgtool as a post-processing step +# after zephyr/zephyr.elf is created in the build directory. +# +# Since this file is brought in via include(), we do the work in a +# function to avoid polluting the top-level scope. + +function(zephyr_runner_file type path) + # Property magic which makes west flash choose the signed build + # output of a given type. + set_target_properties(runners_yaml_props_target PROPERTIES "${type}_file" "${path}") +endfunction() + +function(zephyr_mcuboot_tasks) + set(keyfile "${CONFIG_MCUBOOT_SIGNATURE_KEY_FILE}") + + # Check for misconfiguration. + if("${keyfile}" STREQUAL "") + # No signature key file, no signed binaries. No error, though: + # this is the documented behavior. + return() + endif() + + if(NOT WEST) + # This feature requires west. + message(FATAL_ERROR "Can't sign images for MCUboot: west not found. To fix, install west and ensure it's on PATH.") + endif() + + if(NOT IS_ABSOLUTE "${keyfile}") + # Relative paths are relative to 'west topdir'. + set(keyfile "${WEST_TOPDIR}/${keyfile}") + set(keyfile_relative TRUE) + else() + set(keyfile_relative FALSE) + endif() + + if(NOT EXISTS "${keyfile}") + if(keyfile_relative) + set(relative_msg " Note: relative paths are relative to the west workspace topdir \"${WEST_TOPDIR}\".") + else() + set(relative_msg "") + endif() + message(FATAL_ERROR "Can't sign images for MCUboot: CONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"${CONFIG_MCUBOOT_SIGNATURE_KEY_FILE}\" not found.${relative_msg}") + elseif(NOT (CONFIG_BUILD_OUTPUT_BIN OR CONFIG_BUILD_OUTPUT_HEX)) + message(FATAL_ERROR "Can't sign images for MCUboot: Neither CONFIG_BUILD_OUTPUT_BIN nor CONFIG_BUILD_OUTPUT_HEX is enabled, so there's nothing to sign.") + endif() + + # Find imgtool. Even though west is installed, imgtool might not be. + # The user may also have a custom manifest which doesn't include + # MCUboot. + # + # Therefore, go with an explicitly installed imgtool first, falling + # back on mcuboot/scripts/imgtool.py. + if(IMGTOOL) + set(imgtool_path "${IMGTOOL}") + elseif(DEFINED ZEPHYR_MCUBOOT_MODULE_DIR) + set(IMGTOOL_PY "${ZEPHYR_MCUBOOT_MODULE_DIR}/scripts/imgtool.py") + if(EXISTS "${IMGTOOL_PY}") + set(imgtool_path "${IMGTOOL_PY}") + endif() + endif() + + # No imgtool, no signed binaries. + if(NOT DEFINED imgtool_path) + message(FATAL_ERROR "Can't sign images for MCUboot: can't find imgtool. To fix, install imgtool with pip3, or add the mcuboot repository to the west manifest and ensure it has a scripts/imgtool.py file.") + return() + endif() + + # Basic 'west sign' command and output format independent arguments. + set(west_sign ${WEST} sign --quiet --tool imgtool + --tool-path "${imgtool_path}" + --build-dir "${APPLICATION_BINARY_DIR}") + + # Arguments to imgtool. + if(NOT CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS STREQUAL "") + # Separate extra arguments into the proper format for adding to + # extra_post_build_commands. + # + # Use UNIX_COMMAND syntax for uniform results across host + # platforms. + separate_arguments(imgtool_extra UNIX_COMMAND ${CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS}) + else() + set(imgtool_extra) + endif() + set(imgtool_args -- --key "${keyfile}" ${imgtool_extra}) + + # Extensionless prefix of any output file. + set(output ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}) + + # List of additional build byproducts. + set(byproducts) + + # 'west sign' arguments for confirmed and unconfirmed images. + set(unconfirmed_args) + set(confirmed_args) + + # Set up .bin outputs. + if(CONFIG_BUILD_OUTPUT_BIN) + list(APPEND unconfirmed_args --bin --sbin ${output}.signed.bin) + list(APPEND byproducts ${output}.signed.bin) + zephyr_runner_file(bin ${output}.signed.bin) + + if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE) + list(APPEND confirmed_args --bin --sbin ${output}.signed.confirmed.bin) + list(APPEND byproducts ${output}.signed.confirmed.bin) + endif() + endif() + + # Set up .hex outputs. + if(CONFIG_BUILD_OUTPUT_HEX) + list(APPEND unconfirmed_args --hex --shex ${output}.signed.hex) + list(APPEND byproducts ${output}.signed.hex) + zephyr_runner_file(hex ${output}.signed.hex) + + if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE) + list(APPEND confirmed_args --hex --shex ${output}.signed.confirmed.hex) + list(APPEND byproducts ${output}.signed.confirmed.hex) + endif() + endif() + + # Add the west sign calls and their byproducts to the post-processing + # steps for zephyr.elf. + # + # CMake guarantees that multiple COMMANDs given to + # add_custom_command() are run in order, so adding the 'west sign' + # calls to the "extra_post_build_commands" property ensures they run + # after the commands which generate the unsigned versions. + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${west_sign} ${unconfirmed_args} ${imgtool_args}) + if(confirmed_args) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${west_sign} ${confirmed_args} ${imgtool_args} --pad --confirm) + endif() + set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts ${byproducts}) +endfunction() + +zephyr_mcuboot_tasks() diff --git a/cmake/reports/CMakeLists.txt b/cmake/reports/CMakeLists.txt index 53dc33823529e3..5b5e5d7d2ac262 100644 --- a/cmake/reports/CMakeLists.txt +++ b/cmake/reports/CMakeLists.txt @@ -1,20 +1,21 @@ # SPDX-License-Identifier: Apache-2.0 -set(flag_for_ram_report -r) -set(flag_for_rom_report -F) +set(flag_for_ram_report ram) +set(flag_for_rom_report rom) foreach(report ram_report rom_report) add_custom_target( ${report} ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/footprint/size_report + -k ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} + -z ${ZEPHYR_BASE} + -o ${CMAKE_BINARY_DIR} + --json ${CMAKE_BINARY_DIR}/${flag_for_${report}}.json ${flag_for_${report}} - --objdump ${CMAKE_OBJDUMP} - --objcopy ${CMAKE_OBJCOPY} - --nm ${CMAKE_NM} - -o ${PROJECT_BINARY_DIR} DEPENDS ${logical_target_for_zephyr_elf} $ + USES_TERMINAL ) endforeach() @@ -34,3 +35,21 @@ if(NOT ${PUNCOVER} STREQUAL PUNCOVER-NOTFOUND) USES_TERMINAL ) endif() + +find_program(PAHOLE pahole) + +if(NOT ${PAHOLE} STREQUAL PAHOLE-NOTFOUND) + add_custom_target( + pahole + ${PAHOLE} + --anon_include + --nested_anon_include + --show_decl_info + $<$:--verbose> + ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} + DEPENDS ${logical_target_for_zephyr_elf} + $ + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + USES_TERMINAL + ) +endif() diff --git a/cmake/target_toolchain.cmake b/cmake/target_toolchain.cmake index a117538d608070..2db2df3a2c6d6d 100644 --- a/cmake/target_toolchain.cmake +++ b/cmake/target_toolchain.cmake @@ -46,8 +46,11 @@ unset(CMAKE_C_COMPILER CACHE) # In Zephyr, toolchains require a port under cmake/toolchain/. # Each toolchain port must set COMPILER and LINKER. # E.g. toolchain/llvm may pick {clang, ld} or {clang, lld}. +add_custom_target(bintools) + include(${TOOLCHAIN_ROOT}/cmake/compiler/${COMPILER}/target.cmake OPTIONAL) include(${TOOLCHAIN_ROOT}/cmake/linker/${LINKER}/target.cmake OPTIONAL) +include(${CMAKE_CURRENT_LIST_DIR}/bintools/bintools_template.cmake) include(${TOOLCHAIN_ROOT}/cmake/bintools/${BINTOOLS}/target.cmake OPTIONAL) # Uniquely identify the toolchain wrt. it's capabilities. diff --git a/cmake/target_toolchain_flags.cmake b/cmake/target_toolchain_flags.cmake new file mode 100644 index 00000000000000..cc9fdc1d59dc1a --- /dev/null +++ b/cmake/target_toolchain_flags.cmake @@ -0,0 +1,17 @@ +# Custom targets for compiler and linker flags. +add_custom_target(asm) +add_custom_target(compiler) +add_custom_target(compiler-cpp) +add_custom_target(linker) + +# Loading of templates are strictly not needed as they does not set any +# properties. +# They purely provides an overview as well as a starting point for supporting +# a new toolchain. +include(${CMAKE_CURRENT_LIST_DIR}/compiler/compiler_flags_template.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/linker/linker_flags_template.cmake) + +# Configure the toolchain flags based on what toolchain technology is used +# (gcc, host-gcc etc.) +include(${TOOLCHAIN_ROOT}/cmake/compiler/${COMPILER}/compiler_flags.cmake OPTIONAL) +include(${TOOLCHAIN_ROOT}/cmake/linker/${LINKER}/linker_flags.cmake OPTIONAL) diff --git a/cmake/toolchain/arcmwdt/generic.cmake b/cmake/toolchain/arcmwdt/generic.cmake new file mode 100644 index 00000000000000..3c258dfc8c5088 --- /dev/null +++ b/cmake/toolchain/arcmwdt/generic.cmake @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: Apache-2.0 + +set_ifndef(ARCMWDT_TOOLCHAIN_PATH "$ENV{ARCMWDT_TOOLCHAIN_PATH}") +set(ARCMWDT_TOOLCHAIN_PATH ${ARCMWDT_TOOLCHAIN_PATH} CACHE PATH "mwdt tools install directory") +assert(ARCMWDT_TOOLCHAIN_PATH "ARCMWDT_TOOLCHAIN_PATH is not set") + +if(NOT EXISTS ${ARCMWDT_TOOLCHAIN_PATH}) + message(FATAL_ERROR "Nothing found at ARCMWDT_TOOLCHAIN_PATH: '${ARCMWDT_TOOLCHAIN_PATH}'") +endif() + +set(TOOLCHAIN_HOME ${ARCMWDT_TOOLCHAIN_PATH}/MetaWare) + +set(COMPILER arcmwdt) +set(LINKER arcmwdt) +set(BINTOOLS arcmwdt) + +set(SYSROOT_TARGET arc) + +set(CROSS_COMPILE ${TOOLCHAIN_HOME}/arc/bin/) +set(SYSROOT_DIR ${TOOLCHAIN_HOME}/${SYSROOT_TARGET}) + +set(TOOLCHAIN_HAS_NEWLIB OFF CACHE BOOL "True if toolchain supports newlib") diff --git a/cmake/toolchain/arcmwdt/target.cmake b/cmake/toolchain/arcmwdt/target.cmake new file mode 100644 index 00000000000000..2ee9bbd4b71057 --- /dev/null +++ b/cmake/toolchain/arcmwdt/target.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This file intentionally left blank. \ No newline at end of file diff --git a/cmake/toolchain/llvm/generic.cmake b/cmake/toolchain/llvm/generic.cmake index 98ee5a8e14aad2..6739b34cc0ae2d 100644 --- a/cmake/toolchain/llvm/generic.cmake +++ b/cmake/toolchain/llvm/generic.cmake @@ -1,16 +1,12 @@ # SPDX-License-Identifier: Apache-2.0 -find_appropriate_cache_directory(USER_CACHE_DIR) - -if((NOT "${USER_CACHE_DIR}" STREQUAL "") AND (EXISTS "${USER_CACHE_DIR}")) - message(STATUS "Invalidating toolchain capability cache in ${USER_CACHE_DIR}") - execute_process(COMMAND - ${CMAKE_COMMAND} -E remove_directory "${USER_CACHE_DIR}") +set_ifndef(LLVM_TOOLCHAIN_PATH "$ENV{CLANG_ROOT_DIR}") +set_ifndef(LLVM_TOOLCHAIN_PATH "$ENV{LLVM_TOOLCHAIN_PATH}") +if(LLVM_TOOLCHAIN_PATH) + set(TOOLCHAIN_HOME ${LLVM_TOOLCHAIN_PATH}/bin/) endif() -if(DEFINED $ENV{CLANG_ROOT_DIR}) - set(TOOLCHAIN_HOME ${CLANG_ROOT}/bin/) -endif() +set(LLVM_TOOLCHAIN_PATH ${CLANG_ROOT_DIR} CACHE PATH "clang install directory") set(COMPILER clang) set(LINKER ld) # TODO: Use lld eventually rather than GNU ld @@ -20,7 +16,11 @@ if("${ARCH}" STREQUAL "arm") set(triple arm-none-eabi) set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs") elseif("${ARCH}" STREQUAL "x86") - set(triple i686-pc-none-elf) + if(CONFIG_64BIT) + set(triple x86_64-pc-none-elf) + else() + set(triple i686-pc-none-elf) + endif() endif() set(CMAKE_C_COMPILER_TARGET ${triple}) diff --git a/cmake/toolchain/xtools/target.cmake b/cmake/toolchain/xtools/target.cmake index f0bb1ee61d2e84..034a02d661a569 100644 --- a/cmake/toolchain/xtools/target.cmake +++ b/cmake/toolchain/xtools/target.cmake @@ -1,12 +1,17 @@ # SPDX-License-Identifier: Apache-2.0 -set(CROSS_COMPILE_TARGET_arm arm-zephyr-eabi) +if(CONFIG_ARM64) + set(CROSS_COMPILE_TARGET_arm aarch64-zephyr-elf) +else() + set(CROSS_COMPILE_TARGET_arm arm-zephyr-eabi) +endif() set(CROSS_COMPILE_TARGET_nios2 nios2-zephyr-elf) set(CROSS_COMPILE_TARGET_riscv riscv64-zephyr-elf) set(CROSS_COMPILE_TARGET_mips mipsel-zephyr-elf) set(CROSS_COMPILE_TARGET_xtensa xtensa-zephyr-elf) set(CROSS_COMPILE_TARGET_arc arc-zephyr-elf) set(CROSS_COMPILE_TARGET_x86 x86_64-zephyr-elf) +set(CROSS_COMPILE_TARGET_sparc sparc-zephyr-elf) set(CROSS_COMPILE_TARGET ${CROSS_COMPILE_TARGET_${ARCH}}) set(SYSROOT_TARGET ${CROSS_COMPILE_TARGET}) diff --git a/cmake/toolchain/zephyr/0.11/target.cmake b/cmake/toolchain/zephyr/0.11/target.cmake index 78b463c935968b..ee9647001a058c 100644 --- a/cmake/toolchain/zephyr/0.11/target.cmake +++ b/cmake/toolchain/zephyr/0.11/target.cmake @@ -11,14 +11,32 @@ set(CROSS_COMPILE_TARGET_mips mipsel-zephyr-elf) set(CROSS_COMPILE_TARGET_xtensa xtensa-zephyr-elf) set(CROSS_COMPILE_TARGET_arc arc-zephyr-elf) set(CROSS_COMPILE_TARGET_x86 x86_64-zephyr-elf) +set(CROSS_COMPILE_TARGET_sparc sparc-zephyr-elf) set(CROSS_COMPILE_TARGET ${CROSS_COMPILE_TARGET_${ARCH}}) set(SYSROOT_TARGET ${CROSS_COMPILE_TARGET}) if("${ARCH}" STREQUAL "xtensa") - set(SYSROOT_DIR ${TOOLCHAIN_HOME}/xtensa/${SOC_NAME}/${SYSROOT_TARGET}) - set(CROSS_COMPILE ${TOOLCHAIN_HOME}/xtensa/${SOC_NAME}/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMPILE_TARGET}-) + # Xtensa GCC needs a different toolchain per SOC + if("${SOC_SERIES}" STREQUAL "cavs_v15") + set(SR_XT_TC_SOC intel_apl_adsp) + elseif("${SOC_SERIES}" STREQUAL "cavs_v18") + set(SR_XT_TC_SOC intel_s1000) + elseif("${SOC_SERIES}" STREQUAL "cavs_v20") + set(SR_XT_TC_SOC intel_s1000) + elseif("${SOC_SERIES}" STREQUAL "cavs_v25") + set(SR_XT_TC_SOC intel_s1000) + elseif("${SOC_SERIES}" STREQUAL "baytrail_adsp") + set(SR_XT_TC_SOC intel_byt_adsp) + elseif("${SOC_SERIES}" STREQUAL "broadwell_adsp") + set(SR_XT_TC_SOC intel_bdw_adsp) + else() + message(FATAL_ERROR "Not compiler set for SOC_SERIES ${SOC_SERIES}") + endif() + set(SYSROOT_DIR ${TOOLCHAIN_HOME}/xtensa/${SR_XT_TC_SOC}/${SYSROOT_TARGET}) + set(CROSS_COMPILE ${TOOLCHAIN_HOME}/xtensa/${SR_XT_TC_SOC}/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMPILE_TARGET}-) else() + # Non-Xtensa SDK toolchains follow a simpler convention set(SYSROOT_DIR ${TOOLCHAIN_HOME}/${SYSROOT_TARGET}/${SYSROOT_TARGET}) set(CROSS_COMPILE ${TOOLCHAIN_HOME}/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMPILE_TARGET}-) endif() diff --git a/cmake/toolchain/zephyr/host-tools.cmake b/cmake/toolchain/zephyr/host-tools.cmake index 3ba5a3321ffedd..eec64240daf69e 100644 --- a/cmake/toolchain/zephyr/host-tools.cmake +++ b/cmake/toolchain/zephyr/host-tools.cmake @@ -12,7 +12,7 @@ set(MINIMUM_REQUIRED_SDK_VERSION 0.11.3) # This is the minimum required version for Zephyr to work (Old style) set(REQUIRED_SDK_VER 0.11.1) -set(TOOLCHAIN_ARCH x86_64) +cmake_host_system_information(RESULT TOOLCHAIN_ARCH QUERY OS_PLATFORM) set_ifndef(ZEPHYR_TOOLCHAIN_VARIANT $ENV{ZEPHYR_TOOLCHAIN_VARIANT} "") set_ifndef(ZEPHYR_SDK_INSTALL_DIR $ENV{ZEPHYR_SDK_INSTALL_DIR} "") diff --git a/cmake/toolchain/zephyr/target.cmake b/cmake/toolchain/zephyr/target.cmake index d92f01391142c2..29d9b7c7452fd4 100644 --- a/cmake/toolchain/zephyr/target.cmake +++ b/cmake/toolchain/zephyr/target.cmake @@ -4,6 +4,34 @@ if(${SDK_VERSION} VERSION_LESS_EQUAL 0.11.2) # For backward compatibility with 0.11.1 and 0.11.2 # we need to source files from Zephyr repo include(${CMAKE_CURRENT_LIST_DIR}/${SDK_MAJOR_MINOR}/target.cmake) +elseif(("${ARCH}" STREQUAL "sparc") AND (${SDK_VERSION} VERSION_LESS 0.12)) + # SDK 0.11.3, 0.11.4 does not have SPARC target support. + include(${CMAKE_CURRENT_LIST_DIR}/${SDK_MAJOR_MINOR}/target.cmake) else() include(${ZEPHYR_SDK_INSTALL_DIR}/cmake/zephyr/target.cmake) + + # Workaround, FIXME + if("${ARCH}" STREQUAL "xtensa") + if("${SOC_SERIES}" STREQUAL "cavs_v15") + set(SR_XT_TC_SOC intel_apl_adsp) + elseif("${SOC_SERIES}" STREQUAL "cavs_v18") + set(SR_XT_TC_SOC intel_s1000) + elseif("${SOC_SERIES}" STREQUAL "cavs_v20") + set(SR_XT_TC_SOC intel_s1000) + elseif("${SOC_SERIES}" STREQUAL "cavs_v25") + set(SR_XT_TC_SOC intel_s1000) + elseif("${SOC_SERIES}" STREQUAL "baytrail_adsp") + set(SR_XT_TC_SOC intel_byt_adsp) + elseif("${SOC_SERIES}" STREQUAL "broadwell_adsp") + set(SR_XT_TC_SOC intel_bdw_adsp) + elseif("${SOC_SERIES}" STREQUAL "intel_s1000") + set(SR_XT_TC_SOC intel_s1000) + elseif("${SOC_NAME}" STREQUAL "sample_controller") + set(SR_XT_TC_SOC sample_controller) + else() + message(FATAL_ERROR "No compiler set for SOC_SERIES ${SOC_SERIES}") + endif() + set(SYSROOT_DIR ${TOOLCHAIN_HOME}/xtensa/${SR_XT_TC_SOC}/${SYSROOT_TARGET}) + set(CROSS_COMPILE ${TOOLCHAIN_HOME}/xtensa/${SR_XT_TC_SOC}/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMPILE_TARGET}-) + endif() endif() diff --git a/cmake/usage/usage.cmake b/cmake/usage/usage.cmake index 319e3e7834bae0..6ae7e7d6afe8ff 100644 --- a/cmake/usage/usage.cmake +++ b/cmake/usage/usage.cmake @@ -49,8 +49,10 @@ dump_all_boards("" " ") message("") message("Supported Shields:") message("") -foreach(shield ${SHIELD_LIST}) - message(" ${shield}") +set(sorted_shield_list ${SHIELD_LIST}) +list(SORT sorted_shield_list) +foreach(shield ${sorted_shield_list}) + message(" ${shield}") endforeach() message("") message("Build flags:") diff --git a/cmake/west.cmake b/cmake/west.cmake new file mode 100644 index 00000000000000..87349525e3f94a --- /dev/null +++ b/cmake/west.cmake @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: Apache-2.0 + +# west is an optional dependency. We need to run west using the same +# Python interpreter as everything else, though, so we play some extra +# tricks. + +# When west runs cmake, it sets WEST_PYTHON to its interpreter. If +# it's defined, we assume west is installed. We do these checks here +# instead of in the failure paths below to avoid CMake warnings about +# WEST_PYTHON not being used. +if(DEFINED WEST_PYTHON) + # Cut out any symbolic links, e.g. python3.x -> python + get_filename_component(west_realpath ${WEST_PYTHON} REALPATH) + get_filename_component(python_realpath ${PYTHON_EXECUTABLE} REALPATH) + + # If realpaths differ from the variables we're using, add extra + # diagnostics. + if(NOT ("${west_realpath}" STREQUAL "${WEST_PYTHON}")) + set(west_realpath_msg " (real path ${west_realpath})") + else() + set(west_realpath_msg "") + endif() + if(NOT ("${python_realpath}" STREQUAL "${PYTHON_EXECUTABLE}")) + set(python_realpath_msg " (real path ${python_realpath})") + else() + set(python_realpath_msg "") + endif() +endif() + +execute_process( + COMMAND + ${PYTHON_EXECUTABLE} + -c + "import west.version; print(west.version.__version__, end='')" + OUTPUT_VARIABLE west_version + ERROR_VARIABLE west_version_err + RESULT_VARIABLE west_version_output_result + ) + +if(west_version_output_result) + if(DEFINED WEST_PYTHON) + if(NOT (${west_realpath} STREQUAL ${python_realpath})) + set(PYTHON_EXECUTABLE_OUT_OF_SYNC "\nOr verify these installations:\n\ + The Python version used by west is: ${WEST_PYTHON}${west_realpath_msg}\n\ + The Python version used by CMake is: ${PYTHON_EXECUTABLE}${python_realpath_msg}") + endif() + + message(FATAL_ERROR "Unable to import west.version from '${PYTHON_EXECUTABLE}':\n${west_version_err}\ +Please install with:\n\ + ${PYTHON_EXECUTABLE} -m pip install west\ +${PYTHON_EXECUTABLE_OUT_OF_SYNC}") + else() + # WEST_PYTHON is undefined and we couldn't import west. That's + # fine; it's optional. + set(WEST WEST-NOTFOUND CACHE INTERNAL "West") + endif() +else() + # We can import west from PYTHON_EXECUTABLE and have its version. + + # Make sure its version matches the minimum required one. + set(MIN_WEST_VERSION 0.7.1) + if(${west_version} VERSION_LESS ${MIN_WEST_VERSION}) + message(FATAL_ERROR "The detected west version, ${west_version}, is unsupported.\n\ + The minimum supported version is ${MIN_WEST_VERSION}.\n\ + Please upgrade with:\n\ + ${PYTHON_EXECUTABLE} -m pip install --upgrade west\ + ${PYTHON_EXECUTABLE_OUT_OF_SYNC}\n") + endif() + + # Set WEST to a COMMAND prefix as if it were a find_program() + # result. + # + # From west 0.8 forward, you can run 'python -m west' to run + # the command line application. + set(WEST_MODULE west) + if(${west_version} VERSION_LESS 0.8) + # In west 0.7.x, this wasn't supported yet, but it happens to be + # possible to run 'python -m west.app.main'. + string(APPEND WEST_MODULE .app.main) + endif() + + # Need to cache this so the Zephyr Eclipse plugin knows + # how to invoke West. + set(WEST ${PYTHON_EXECUTABLE} -m ${WEST_MODULE} CACHE INTERNAL "West") + + # Print information about the west module we're relying on. This + # will still work even after output is one line. + message(STATUS "Found west (found suitable version \"${west_version}\", minimum required is \"${MIN_WEST_VERSION}\")") + + execute_process( + COMMAND ${WEST} topdir + OUTPUT_VARIABLE WEST_TOPDIR + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${ZEPHYR_BASE} + ) +endif() diff --git a/cmake/zephyr_module.cmake b/cmake/zephyr_module.cmake index 3e6d1678f9345e..b5dd55e1d01758 100644 --- a/cmake/zephyr_module.cmake +++ b/cmake/zephyr_module.cmake @@ -18,10 +18,11 @@ if(ZEPHYR_EXTRA_MODULES) set(ZEPHYR_EXTRA_MODULES_ARG "--extra-modules" ${ZEPHYR_EXTRA_MODULES}) endif() -set(KCONFIG_MODULES_FILE ${CMAKE_BINARY_DIR}/Kconfig.modules) +set(KCONFIG_MODULES_FILE ${KCONFIG_BINARY_DIR}/Kconfig.modules) +set(ZEPHYR_SETTINGS_FILE ${CMAKE_BINARY_DIR}/zephyr_settings.txt) if(WEST) - set(WEST_ARG "--west-path" ${WEST} "--zephyr-base" ${ZEPHYR_BASE}) + set(WEST_ARG "--zephyr-base" ${ZEPHYR_BASE}) endif() if(WEST OR ZEPHYR_MODULES) @@ -35,16 +36,56 @@ if(WEST OR ZEPHYR_MODULES) ${ZEPHYR_EXTRA_MODULES_ARG} --kconfig-out ${KCONFIG_MODULES_FILE} --cmake-out ${CMAKE_BINARY_DIR}/zephyr_modules.txt + --settings-out ${ZEPHYR_SETTINGS_FILE} + WORKING_DIRECTORY ${ZEPHYR_BASE} ERROR_VARIABLE zephyr_module_error_text RESULT_VARIABLE zephyr_module_return ) - if(${zephyr_module_return}) + if(${zephyr_module_return}) message(FATAL_ERROR "${zephyr_module_error_text}") endif() + if(EXISTS ${ZEPHYR_SETTINGS_FILE}) + file(STRINGS ${ZEPHYR_SETTINGS_FILE} ZEPHYR_SETTINGS_TXT ENCODING UTF-8) + foreach(setting ${ZEPHYR_SETTINGS_TXT}) + # Match : for each line of file, each corresponding to + # a setting. The use of quotes is required due to CMake not supporting + # lazy regexes (it supports greedy only). + string(REGEX REPLACE "\"(.*)\":\".*\"" "\\1" key ${setting}) + string(REGEX REPLACE "\".*\":\"(.*)\"" "\\1" value ${setting}) + list(APPEND ${key} ${value}) + endforeach() + endif() + + if(EXISTS ${CMAKE_BINARY_DIR}/zephyr_modules.txt) + file(STRINGS ${CMAKE_BINARY_DIR}/zephyr_modules.txt ZEPHYR_MODULES_TXT + ENCODING UTF-8) + set(ZEPHYR_MODULE_NAMES) + + foreach(module ${ZEPHYR_MODULES_TXT}) + # Match "":"" for each line of file, each corresponding to + # one module. The use of quotes is required due to CMake not supporting + # lazy regexes (it supports greedy only). + string(REGEX REPLACE "\"(.*)\":\".*\":\".*\"" "\\1" module_name ${module}) + string(REGEX REPLACE "\".*\":\"(.*)\":\".*\"" "\\1" module_path ${module}) + string(REGEX REPLACE "\".*\":\".*\":\"(.*)\"" "\\1" cmake_path ${module}) + + list(APPEND ZEPHYR_MODULE_NAMES ${module_name}) + + string(TOUPPER ${module_name} MODULE_NAME_UPPER) + if(NOT ${MODULE_NAME_UPPER} STREQUAL CURRENT) + set(ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR ${module_path}) + set(ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR ${cmake_path}) + else() + message(FATAL_ERROR "Found Zephyr module named: ${module_name}\n\ +${MODULE_NAME_UPPER} is a restricted name for Zephyr modules as it is used for \ +\${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR} CMake variable.") + endif() + endforeach() + endif() else() file(WRITE ${KCONFIG_MODULES_FILE} diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 4db1ce4d5a3898..4c34e20e679d32 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -42,6 +42,8 @@ endif() # Include version info include(${ZEPHYR_BASE}/cmake/version.cmake) # Process modules +set(KCONFIG_BINARY_DIR ${CMAKE_BINARY_DIR}/Kconfig) +file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}) include(${ZEPHYR_BASE}/cmake/zephyr_module.cmake) # Note that this won't force fatal error if latexmk is not found. @@ -138,6 +140,8 @@ add_custom_target( # For incremental builds not to miss any source change this MUST be kept # a superset of INPUT= and FILE_PATTERNS= in zephyr.doxyfile.in +# +# NOTE: any changes here should be reflected in .github/workflows/doc-build.yml file(GLOB_RECURSE DOXY_SOURCES ${ZEPHYR_BASE}/include/*.[c,h,S] ${ZEPHYR_BASE}/kernel/include/kernel_arch_interface.h @@ -195,6 +199,31 @@ else() set(SEP :) endif() +set(KI_SCRIPT ${ZEPHYR_BASE}/scripts/filter-known-issues.py) +set(FIX_TEX_SCRIPT ${ZEPHYR_BASE}/doc/scripts/fix_tex.py) +set(CONF_DIR ${ZEPHYR_BASE}/.known-issues/doc) + +# +# Generated Kconfig .rst documents +# + +file(WRITE ${KCONFIG_BINARY_DIR}/Kconfig.soc.defconfig + "osource \"${ZEPHYR_BASE}/soc/$(ARCH)/*/Kconfig.defconfig\"\n" +) +file(WRITE ${KCONFIG_BINARY_DIR}/Kconfig.soc + "osource \"${ZEPHYR_BASE}/soc/$(ARCH)/*/Kconfig.soc\"\n" +) +file(WRITE ${KCONFIG_BINARY_DIR}/Kconfig.shield.defconfig + "osource \"${ZEPHYR_BASE}/boards/shields/*/Kconfig.defconfig\"\n" +) +file(WRITE ${KCONFIG_BINARY_DIR}/Kconfig.shield + "osource \"${ZEPHYR_BASE}/boards/shields/*/Kconfig.shield\"\n" +) +file(WRITE ${KCONFIG_BINARY_DIR}/Kconfig.soc.arch + "osource \"${ZEPHYR_BASE}/soc/$(ARCH)/Kconfig\"\n" + "osource \"${ZEPHYR_BASE}/soc/$(ARCH)/*/Kconfig\"\n" +) + add_custom_target( kconfig COMMAND ${CMAKE_COMMAND} -E make_directory ${RST_OUT}/doc/reference/kconfig @@ -206,11 +235,11 @@ add_custom_target( ARCH=* ARCH_DIR=arch SOC_DIR=soc - CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR} + KCONFIG_BINARY_DIR=${KCONFIG_BINARY_DIR} KCONFIG_WARN_UNDEF=y KCONFIG_TURBO_MODE=${KCONFIG_TURBO_MODE} KCONFIG_DOC_MODE=1 - ${PYTHON_EXECUTABLE} scripts/genrest.py ${RST_OUT}/doc/reference/kconfig/ + ${PYTHON_EXECUTABLE} scripts/gen_kconfig_rest.py ${RST_OUT}/doc/reference/kconfig/ --separate-all-index --keep-module-paths --modules Architecture,arch,${ZEPHYR_BASE}/arch @@ -222,12 +251,59 @@ add_custom_target( VERBATIM WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - COMMENT "Running genrest.py Kconfig ${RST_OUT}/doc/reference/kconfig/" + COMMENT "Running gen_kconfig_rest.py ${RST_OUT}/doc/reference/kconfig/" ) -set(KI_SCRIPT ${ZEPHYR_BASE}/scripts/filter-known-issues.py) -set(FIX_TEX_SCRIPT ${ZEPHYR_BASE}/doc/scripts/fix_tex.py) -set(CONF_DIR ${ZEPHYR_BASE}/.known-issues/doc) +# +# Generated devicetree .rst documents +# +# The devicetree bindings discovered in ${DTS_ROOTS} are parsed and +# documentation for them is generated in the directory +# ${DTS_BINDINGS_RST_OUT}. +# +# The CMake variable GEN_DEVICETREE_REST_ZEPHYR_DOCSET will +# be passed to the script in the environment. This allows separating +# the bindings documentation into a standalone Sphinx docset that +# nonetheless can link to Zephyr documentation using intersphinx. +# If empty, the variable has no effect on the script. +# +# If not set, these are the default values for these variables: +# +# - DTS_ROOTS: ZEPHYR_BASE +# - DTS_BINDINGS_RST_OUT: ${RST_OUT}/doc/reference/devicetree +# + +set(GEN_DEVICETREE_REST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/scripts/gen_devicetree_rest.py) + +if(NOT DTS_ROOTS) + set(DTS_ROOTS ${ZEPHYR_BASE}) +endif() + +set(DTS_ROOT_ARGS) +foreach(root ${DTS_ROOTS}) + list(APPEND DTS_ROOT_ARGS --dts-root ${root}) +endforeach() + +if(NOT DTS_BINDINGS_RST_OUT) + set(DTS_BINDINGS_RST_OUT ${RST_OUT}/doc/reference/devicetree) +endif() + +add_custom_target( + devicetree + COMMAND ${CMAKE_COMMAND} -E env + PYTHONPATH=${ZEPHYR_BASE}/scripts/dts${SEP}$ENV{PYTHONPATH} + ZEPHYR_BASE=${ZEPHYR_BASE} + GEN_DEVICETREE_REST_ZEPHYR_DOCSET=${GEN_DEVICETREE_REST_ZEPHYR_DOCSET} + ${PYTHON_EXECUTABLE} ${GEN_DEVICETREE_REST_SCRIPT} + --vendor-prefixes ${ZEPHYR_BASE}/dts/bindings/vendor-prefixes.txt + ${DTS_ROOT_ARGS} ${DTS_BINDINGS_RST_OUT} + VERBATIM + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + COMMENT "Running gen_devicetree_rest.py ${DTS_BINDINGS_RST_OUT}" + USES_TERMINAL +) + +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${GEN_DEVICETREE_REST_SCRIPT}) # # HTML section @@ -246,10 +322,11 @@ set(SPHINX_BUILD_HTML_COMMAND add_custom_target( sphinx-html COMMAND ${SPHINX_BUILD_HTML_COMMAND} - DEPENDS ${EXTRACT_CONTENT_OUTPUTS} COMMENT "Just re-generating HTML (USE WITH CAUTION)" + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} USES_TERMINAL ) +add_dependencies(sphinx-html content) # "breathe", the sphinx plugin that parses XML output from doxygen, has # an "everything on everything" dependency issue reported at: @@ -281,10 +358,12 @@ set(SPHINX_BUILD_LATEX_COMMAND add_custom_target( sphinx-latex COMMAND ${SPHINX_BUILD_LATEX_COMMAND} - DEPENDS ${EXTRACT_CONTENT_OUTPUTS} COMMENT "Just re-generating LaTeX (USE WITH CAUTION)" + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} USES_TERMINAL ) +add_dependencies(sphinx-latex content) + add_custom_command( OUTPUT ${SPHINX_OUTPUT_DIR_LATEX}/zephyr.tex @@ -340,7 +419,7 @@ endif() # # Dependencies and final targets # -add_dependencies(html content doxy_real_modified_times kconfig) +add_dependencies(html content doxy_real_modified_times kconfig devicetree) add_custom_target( htmldocs @@ -353,7 +432,7 @@ add_custom_target( ) add_dependencies(doxygen doxy_real_modified_times) -add_dependencies(latex content doxy_real_modified_times kconfig) +add_dependencies(latex content doxy_real_modified_times kconfig devicetree) add_custom_target( latexdocs diff --git a/doc/README.rst b/doc/README.rst index 0c4cc8d9dbd0b9..d7c69be556414c 100644 --- a/doc/README.rst +++ b/doc/README.rst @@ -8,6 +8,8 @@ documentation on your local system using the same documentation sources as we use to create the online documentation found at https://docs.zephyrproject.org +.. _documentation-overview: + Documentation overview ********************** @@ -45,15 +47,17 @@ and make use of the breathe extension for including the doxygen-generated API material. Additional tools are required to generate the documentation locally, as described in the following sections. +.. _documentation-processors: + Installing the documentation processors *************************************** Our documentation processing has been tested to run with: * Doxygen version 1.8.13 -* Sphinx version 1.7.5 -* Breathe version 4.9.1 -* docutils version 0.14 +* Sphinx version 3.2.0 +* Breathe version 4.20.0 +* docutils version 0.16 * sphinx_rtd_theme version 0.4.0 * sphinxcontrib-svg2pdfconverter version 0.1.0 * Latexmk version 4.56 @@ -132,16 +136,15 @@ folder, here are the commands to generate the html content locally: .. code-block:: console # On Linux/macOS - cd ~/zephyr - source zephyr-env.sh - mkdir -p doc/_build && cd doc/_build + cd ~/zephyr/doc # On Windows - cd %userprofile%\zephyr - zephyr-env.cmd - mkdir doc\_build & cd doc/_build + cd %userprofile%\zephyr\doc # Use cmake to configure a Ninja-based build system: - cmake -GNinja .. + cmake -GNinja -B_build . + + # Enter the build directory + cd _build # To generate HTML output, run ninja on the generated build system: ninja htmldocs @@ -181,7 +184,6 @@ there: .. code-block:: console cd ~/zephyr - source zephyr-env.sh # To generate HTML output make htmldocs @@ -227,7 +229,6 @@ To enable this mode, set the following option when invoking cmake:: or invoke make with the following target:: cd ~/zephyr - source zephyr-env.sh # To generate HTML output without detailed Kconfig make htmldocs-fast diff --git a/doc/_templates/zversions.html b/doc/_templates/zversions.html index e611b68819b139..053ce54f6197ff 100644 --- a/doc/_templates/zversions.html +++ b/doc/_templates/zversions.html @@ -2,7 +2,7 @@
Zephyr Project - v: {{ current_version }} + v: latest
diff --git a/doc/application/index.rst b/doc/application/index.rst index fb1c85e5799a30..365489f1d11da5 100644 --- a/doc/application/index.rst +++ b/doc/application/index.rst @@ -251,7 +251,8 @@ should know about. 3 ways (in order of precedence): * As a parameter to the ``west build`` or ``cmake`` invocation via the - ``-D`` command-line switch + ``-D`` command-line switch. If you have multiple overlay files, you should + use quotations, ``"file1.overlay;file2.overlay"`` * As :ref:`env_vars`. * As a ``set( )`` statement in your :file:`CMakeLists.txt` @@ -265,15 +266,20 @@ should know about. built-in boards, and :ref:`board_porting_guide` for information on adding board support. -* :makevar:`CONF_FILE`: Indicates the name of one or more configuration +* :makevar:`CONF_FILE`: Indicates the name of one or more Kconfig configuration fragment files. Multiple filenames can be separated with either spaces or semicolons. Each file includes Kconfig configuration values that override the default configuration values. See :ref:`initial-conf` for more information. +* :makevar:`OVERLAY_CONFIG`: Additional Kconfig configuration fragment files. + Multiple filenames can be separated with either spaces or semicolons. This + can be useful in order to leave :makevar:`CONF_FILE` at its default value, + but "mix in" some additional configuration options. + * :makevar:`DTC_OVERLAY_FILE`: One or more devicetree overlay files to use. - Multiple files can be separated with spaces or semicolons. + Multiple files can be separated with semicolons. See :ref:`set-devicetree-overlays` for examples and :ref:`devicetree-intro` for information about devicetree and Zephyr. @@ -372,6 +378,8 @@ Basics Additionally, ``west`` allows you to :ref:`set a default board `. +.. _build-directory-contents: + Build Directory Contents ======================== @@ -584,11 +592,11 @@ again. .. _application_debugging: .. _custom_board_definition: -Custom Board, DeviceTree and SOC Definitions +Custom Board, Devicetree and SOC Definitions ******************************************** In cases where the board or platform you are developing for is not yet -supported by Zephyr, you can add board, DeviceTree and SOC definitions +supported by Zephyr, you can add board, Devicetree and SOC definitions to your application without having to add them to the Zephyr tree. The structure needed to support out-of-tree board and SOC development @@ -667,8 +675,15 @@ This will use your custom board configuration and will generate the Zephyr binary into your application directory. You can also define the ``BOARD_ROOT`` variable in the application -:file:`CMakeLists.txt` file. +:file:`CMakeLists.txt` file. Make sure to do so **before** pulling in the Zephyr +boilerplate with ``find_package(Zephyr ...)``. + +.. note:: + When specifying ``BOARD_ROOT`` in a CMakeLists.txt, then an absolute path must + be provided, for example ``list(APPEND BOARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/``. + When using ``-DBOARD_ROOT=`` both absolute and relative paths can + be used. Relative paths are treated relatively to the application directory. SOC Definitions =============== @@ -686,27 +701,43 @@ the Zephyr tree, for example: -The paths to any Kconfig files inside the structure needs to prefixed with -$(SOC_DIR) to make Kconfig aware of the location of the Kconfig files related to -the custom SOC. +The file :zephyr_file:`soc/Kconfig` will create the top-level +``SoC/CPU/Configuration Selection`` menu in Kconfig. -In the ``soc`` directory you will need a top-level Kconfig file pointing to the -custom SOC definitions: +Out of tree SoC definitions can be added to this menu using the ``SOC_ROOT`` +CMake variable. This variable contains a semicolon-separated list of directories +which contain SoC support files. +Following the structure above, the following files can be added to load +more SoCs into the menu. .. code-block:: none - choice - prompt "SoC/CPU/Configuration selection" + soc + └── arm + └── st_stm32 + ├── Kconfig + ├── Kconfig.soc + └── Kconfig.defconfig + +The Kconfig files above may describe the SoC or load additional SoC Kconfig files. - source "$(SOC_DIR)/$(ARCH)/*/Kconfig.soc" +An example of loading ``stm31l0`` specific Kconfig files in this structure: + +.. code-block:: none + + soc + └── arm + └── st_stm32 + ├── Kconfig.soc + └── stm32l0 + └── Kconfig.series - endchoice +can be done with the following content in ``st_stm32/Kconfig.soc``: - menu "Hardware Configuration" - osource "$(SOC_DIR)/$(ARCH)/*/Kconfig" +.. code-block:: none - endmenu + rsource "*/Kconfig.series" Once the SOC structure is in place, you can build your application targeting this platform by specifying the location of your custom platform @@ -723,15 +754,26 @@ build system: This will use your custom platform configurations and will generate the Zephyr binary into your application directory. -You can also define the ``SOC_ROOT`` variable in the application -:file:`CMakeLists.txt` file. +See :ref:`modules_build_settings` for information on setting SOC_ROOT in a module's +:file:`zephyr/module.yml` file. + +Or you can define the ``SOC_ROOT`` variable in the application +:file:`CMakeLists.txt` file. Make sure to do so **before** pulling in the +Zephyr boilerplate with ``find_package(Zephyr ...)``. + +.. note:: + + When specifying ``SOC_ROOT`` in a CMakeLists.txt, then an absolute path must + be provided, for example ``list(APPEND SOC_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/``. + When using ``-DSOC_ROOT=`` both absolute and relative paths can be + used. Relative paths are treated relatively to the application directory. .. _dts_root: -DeviceTree Definitions +Devicetree Definitions ====================== -DeviceTree directory trees are found in ``APPLICATION_SOURCE_DIR``, +Devicetree directory trees are found in ``APPLICATION_SOURCE_DIR``, ``BOARD_DIR``, and ``ZEPHYR_BASE``, but additional trees, or DTS_ROOTs, can be added by creating this directory tree:: @@ -755,9 +797,31 @@ its location through the ``DTS_ROOT`` CMake Cache variable: :goals: build :compact: -You can also define the variable in the application -:file:`CMakeLists.txt` file. +You can also define the variable in the application :file:`CMakeLists.txt` +file. Make sure to do so **before** pulling in the Zephyr boilerplate with +``find_package(Zephyr ...)``. + +.. note:: + + When specifying ``DTS_ROOT`` in a CMakeLists.txt, then an absolute path must + be provided, for example ``list(APPEND DTS_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/``. + When using ``-DDTS_ROOT=`` both absolute and relative paths can be + used. Relative paths are treated relatively to the application directory. +Devicetree source are passed through the C preprocessor, so you can +include files that can be located in a ``DTS_ROOT`` directory. By +convention devicetree include files have a ``.dtsi`` extension. + +You can also use the preprocessor to control the content of a devicetree +file, by specifying directives through the ``DTS_EXTRA_CPPFLAGS`` CMake +Cache variable: + +.. zephyr-app-commands:: + :tool: all + :board: + :gen-args: -DDTS_EXTRA_CPPFLAGS=-DTEST_ENABLE_FEATURE + :goals: build + :compact: Application Debugging ********************* diff --git a/doc/conf.py b/doc/conf.py index a421f4630d14c2..da940cc849affb 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -291,144 +291,150 @@ # URLs must be relative to document root (with NO leading slash), # and without the html extension) html_redirect_pages = [ - ('contribute/contribute_guidelines', 'contribute/index'), - ('application/application', 'application/index.rst'), - ('security/security', 'security/index'), - ('boards/boards', 'boards/index'), - ('samples/samples', 'samples/index'), - ('releases/release-notes', 'releases/index'), - ('getting_started/getting_started', 'getting_started/index'), - ('introduction/introducing_zephyr', 'introduction/index'), - ('api/index', 'reference/index'), - ('api/api', 'reference/index'), - ('subsystems/subsystems', 'reference/index'), - ('kernel/kernel', 'reference/kernel/index'), - ('boards/arc/em_starterkit/doc/board', 'boards/arc/em_starterkit/doc/index'), - ('boards/arc/nsim_em/doc/board', 'boards/arc/nsim_em/doc/index'), - ('boards/arm/96b_argonkey/doc/96b_argonkey', 'boards/arm/96b_argonkey/doc/index'), - ('boards/arm/96b_carbon/doc/96b_carbon', 'boards/arm/96b_carbon/doc/index'), - ('boards/arm/96b_carbon_nrf51/doc/96b_carbon_nrf51', 'boards/arm/96b_carbon_nrf51/doc/index'), - ('boards/arm/96b_neonkey/doc/96b_neonkey', 'boards/arm/96b_neonkey/doc/index'), - ('boards/arm/96b_nitrogen/doc/96b_nitrogen', 'boards/arm/96b_nitrogen/doc/index'), - ('boards/arm/adafruit_feather_m0_basic_proto/doc/adafruit_feather_m0_basic_proto', 'boards/arm/adafruit_feather_m0_basic_proto/doc/index'), - ('boards/arm/adafruit_trinket_m0/doc/adafruit_trinket_m0', 'boards/arm/adafruit_trinket_m0/doc/index'), - ('boards/arm/arduino_due/doc/board', 'boards/arm/arduino_due/doc/index'), - ('boards/arm/arduino_zero/doc/arduino_zero', 'boards/arm/arduino_zero/doc/index'), - ('boards/arm/atsamd20_xpro/doc/atsamd20_xpro', 'boards/arm/atsamd20_xpro/doc/index'), - ('boards/arm/bbc_microbit/doc/board', 'boards/arm/bbc_microbit/doc/index'), - ('boards/arm/cc3220sf_launchxl/doc/cc3220sf_launchxl', 'boards/arm/cc3220sf_launchxl/doc/index'), - ('boards/arm/colibri_imx7d_m4/doc/colibri_imx7d_m4', 'boards/arm/colibri_imx7d_m4/doc/index'), - ('boards/arm/disco_l475_iot1/doc/disco_l475_iot1', 'boards/arm/disco_l475_iot1/doc/index'), - ('boards/arm/dragino_lsn50/doc/dragino_lsn50', 'boards/arm/dragino_lsn50/doc/index'), - ('boards/arm/efm32wg_stk3800/doc/efm32wg_stk3800', 'boards/arm/efm32wg_stk3800/doc/index'), - ('boards/arm/efr32_slwstk6061a/doc/efr32_slwstk6061a', 'boards/arm/efr32_slwstk6061a/doc/index'), - ('boards/arm/frdm_k64f/doc/frdm_k64f', 'boards/arm/frdm_k64f/doc/index'), - ('boards/arm/frdm_kl25z/doc/frdm_kl25z', 'boards/arm/frdm_kl25z/doc/index'), - ('boards/arm/frdm_kw41z/doc/frdm_kw41z', 'boards/arm/frdm_kw41z/doc/index'), - ('boards/arm/hexiwear_k64/doc/hexiwear_k64', 'boards/arm/hexiwear_k64/doc/index'), - ('boards/arm/hexiwear_kw40z/doc/hexiwear_kw40z', 'boards/arm/hexiwear_kw40z/doc/index'), - ('boards/arm/lpcxpresso54114_m0/doc/lpcxpresso54114_m0', 'boards/arm/lpcxpresso54114_m0/doc/index'), - ('boards/arm/lpcxpresso54114_m4/doc/lpcxpresso54114', 'boards/arm/lpcxpresso54114_m4/doc/index'), - ('boards/arm/mimxrt1020_evk/doc/mimxrt1020_evk', 'boards/arm/mimxrt1020_evk/doc/index'), - ('boards/arm/mimxrt1050_evk/doc/mimxrt1050_evk', 'boards/arm/mimxrt1050_evk/doc/index'), - ('boards/arm/mimxrt1060_evk/doc/mimxrt1060_evk', 'boards/arm/mimxrt1060_evk/doc/index'), - ('boards/arm/mimxrt1064_evk/doc/mimxrt1064_evk', 'boards/arm/mimxrt1064_evk/doc/index'), - ('boards/arm/mps2_an385/doc/mps2_an385', 'boards/arm/mps2_an385/doc/index'), - ('boards/arm/msp_exp432p401r_launchxl/doc/msp_exp432p401r_launchxl', 'boards/arm/msp_exp432p401r_launchxl/doc/index'), - ('boards/arm/nrf51_ble400/doc/nrf51_ble400', 'boards/arm/nrf51_ble400/doc/index'), - ('boards/arm/nrf51_blenano/doc/nrf51_blenano', 'boards/arm/nrf51_blenano/doc/index'), - ('boards/arm/nrf51_pca10028/doc/nrf51_pca10028', 'boards/arm/nrf51dk_nrf51422/doc/index'), - ('boards/arm/nrf51_pca10028/doc/index', 'boards/arm/nrf51dk_nrf51422/doc/index'), - ('boards/arm/nrf51_pca10031/doc/index', 'boards/arm/nrf51dongle_nrf51422/doc/index'), - ('boards/arm/nrf51_vbluno51/doc/nrf51_vbluno51', 'boards/arm/nrf51_vbluno51/doc/index'), - ('boards/arm/nrf52810_pca10040/doc/nrf52810_pca10040', 'boards/arm/nrf52dk_nrf52810/doc/index'), - ('boards/arm/nrf52810_pca10040/doc/index', 'boards/arm/nrf52dk_nrf52810/doc/index'), - ('boards/arm/nrf52811_pca10056/doc/index', 'boards/arm/nrf52840dk_nrf52811/doc/index'), - ('boards/arm/nrf52833_pca10100/doc/index', 'boards/arm/nrf52833dk_nrf52833/doc/index'), - ('boards/arm/nrf52840_pca10056/doc/nrf52840_pca10056', 'boards/arm/nrf52840dk_nrf52840/doc/index'), - ('boards/arm/nrf52840_pca10056/doc/index', 'boards/arm/nrf52840dk_nrf52840/doc/index'), - ('boards/arm/nrf9160_pca10090/doc/index', 'boards/arm/nrf9160dk_nrf9160/doc/index'), - ('boards/arm/nrf52840_pca10090/doc/index', 'boards/arm/nrf9160dk_nrf52840/doc/index'), - ('boards/arm/nrf52840_pca10059/doc/nrf52840_pca10059', 'boards/arm/nrf52840dongle_nrf52840/doc/index'), - ('boards/arm/nrf52840_pca10059/doc/index', 'boards/arm/nrf52840dongle_nrf52840/doc/index'), - ('boards/arm/nrf52_adafruit_feather/doc/nrf52_adafruit_feather', 'boards/arm/nrf52_adafruit_feather/doc/index'), - ('boards/arm/nrf52_blenano2/doc/nrf52_blenano2', 'boards/arm/nrf52_blenano2/doc/index'), - ('boards/arm/nrf52_pca10040/doc/nrf52_pca10040', 'boards/arm/nrf52dk_nrf52832/doc/index'), - ('boards/arm/nrf52_pca10040/doc/index', 'boards/arm/nrf52dk_nrf52832/doc/index'), - ('boards/arm/nrf52_pca20020/doc/nrf52_pca20020', 'boards/arm/thingy52_nrf52832/doc/index'), - ('boards/arm/nrf52_pca20020/doc/index', 'boards/arm/thingy52_nrf52832/doc/index'), - ('boards/arm/nrf52_vbluno52/doc/nrf52_vbluno52', 'boards/arm/nrf52_vbluno52/doc/index'), - ('boards/arm/nrf5340_dk_nrf5340/doc/index', 'boards/arm/nrf5340pdk_nrf5340/doc/index'), - ('boards/arm/nucleo_f030r8/doc/nucleof030r8', 'boards/arm/nucleo_f030r8/doc/index'), - ('boards/arm/nucleo_f070rb/doc/nucleof070rb', 'boards/arm/nucleo_f070rb/doc/index'), - ('boards/arm/nucleo_f091rc/doc/nucleof091rc', 'boards/arm/nucleo_f091rc/doc/index'), - ('boards/arm/nucleo_f103rb/doc/nucleof103rb', 'boards/arm/nucleo_f103rb/doc/index'), - ('boards/arm/nucleo_f207zg/doc/nucleo_f207zg', 'boards/arm/nucleo_f207zg/doc/index'), - ('boards/arm/nucleo_f334r8/doc/nucleof334r8', 'boards/arm/nucleo_f334r8/doc/index'), - ('boards/arm/nucleo_f401re/doc/nucleof401re', 'boards/arm/nucleo_f401re/doc/index'), - ('boards/arm/nucleo_f411re/doc/nucleof411re', 'boards/arm/nucleo_f411re/doc/index'), - ('boards/arm/nucleo_f412zg/doc/nucleof412zg', 'boards/arm/nucleo_f412zg/doc/index'), - ('boards/arm/nucleo_f413zh/doc/nucleof413zh', 'boards/arm/nucleo_f413zh/doc/index'), - ('boards/arm/nucleo_f429zi/doc/nucleof429zi', 'boards/arm/nucleo_f429zi/doc/index'), - ('boards/arm/nucleo_f446re/doc/nucleof446re', 'boards/arm/nucleo_f446re/doc/index'), - ('boards/arm/nucleo_l053r8/doc/nucleol053r8', 'boards/arm/nucleo_l053r8/doc/index'), - ('boards/arm/nucleo_l073rz/doc/nucleol073rz', 'boards/arm/nucleo_l073rz/doc/index'), - ('boards/arm/nucleo_l432kc/doc/nucleol432kc', 'boards/arm/nucleo_l432kc/doc/index'), - ('boards/arm/nucleo_l476rg/doc/nucleol476rg', 'boards/arm/nucleo_l476rg/doc/index'), - ('boards/arm/olimex_stm32_e407/doc/olimex_stm32_e407', 'boards/arm/olimex_stm32_e407/doc/index'), - ('boards/arm/olimex_stm32_h407/doc/olimex_stm32_h407', 'boards/arm/olimex_stm32_h407/doc/index'), - ('boards/arm/olimex_stm32_p405/doc/olimex_stm32_p405', 'boards/arm/olimex_stm32_p405/doc/index'), - ('boards/arm/olimexino_stm32/doc/olimexino_stm32', 'boards/arm/olimexino_stm32/doc/index'), - ('boards/arm/qemu_cortex_m3/doc/board', 'boards/arm/qemu_cortex_m3/doc/index'), - ('boards/arm/reel_board/doc/reel_board', 'boards/arm/reel_board/doc/index'), - ('boards/arm/sam4s_xplained/doc/sam4s_xplained', 'boards/arm/sam4s_xplained/doc/index'), - ('boards/arm/sam_e70_xplained/doc/sam_e70_xplained', 'boards/arm/sam_e70_xplained/doc/index'), - ('boards/arm/stm3210c_eval/doc/stm3210c_eval', 'boards/arm/stm3210c_eval/doc/index'), - ('boards/arm/stm32373c_eval/doc/stm32373c_eval', 'boards/arm/stm32373c_eval/doc/index'), - ('boards/arm/stm32_min_dev/doc/stm32_min_dev', 'boards/arm/stm32_min_dev/doc/index'), - ('boards/arm/stm32f072_eval/doc/stm32f072_eval', 'boards/arm/stm32f072_eval/doc/index'), - ('boards/arm/stm32f072b_disco/doc/stm32f072b_disco', 'boards/arm/stm32f072b_disco/doc/index'), - ('boards/arm/stm32f0_disco/doc/stm32f0_disco', 'boards/arm/stm32f0_disco/doc/index'), - ('boards/arm/stm32f3_disco/doc/stm32f3_disco', 'boards/arm/stm32f3_disco/doc/index'), - ('boards/arm/stm32f411e_disco/doc/stm32f411e_disco', 'boards/arm/stm32f411e_disco/doc/index'), - ('boards/arm/stm32f412g_disco/doc/stm32f412g_disco', 'boards/arm/stm32f412g_disco/doc/index'), - ('boards/arm/stm32f429i_disc1/doc/stm32f429i_disc1', 'boards/arm/stm32f429i_disc1/doc/index'), - ('boards/arm/stm32f469i_disco/doc/stm32f469i_disco', 'boards/arm/stm32f469i_disco/doc/index'), - ('boards/arm/stm32f4_disco/doc/stm32f4_disco', 'boards/arm/stm32f4_disco/doc/index'), - ('boards/arm/stm32f723e_disco/doc/stm32f723e_disco', 'boards/arm/stm32f723e_disco/doc/index'), - ('boards/arm/stm32f746g_disco/doc/stm32f746g_disco', 'boards/arm/stm32f746g_disco/doc/index'), - ('boards/arm/stm32f769i_disco/doc/stm32f769i_disco', 'boards/arm/stm32f769i_disco/doc/index'), - ('boards/arm/stm32l476g_disco/doc/stm32l476g_disco', 'boards/arm/stm32l476g_disco/doc/index'), - ('boards/arm/stm32l496g_disco/doc/stm32l496g_disco', 'boards/arm/stm32l496g_disco/doc/index'), - ('boards/arm/udoo_neo_full_m4/doc/udoo_neo_full', 'boards/arm/udoo_neo_full_m4/doc/index'), - ('boards/arm/usb_kw24d512/doc/usb_kw24d512', 'boards/arm/usb_kw24d512/doc/index'), - ('boards/arm/v2m_beetle/doc/v2m_beetle', 'boards/arm/v2m_beetle/doc/index'), - ('boards/arm/warp7_m4/doc/warp7_m4', 'boards/arm/warp7_m4/doc/index'), - ('boards/nios2/altera_max10/doc/board', 'boards/nios2/altera_max10/doc/index'), - ('boards/nios2/qemu_nios2/doc/board', 'boards/nios2/qemu_nios2/doc/index'), - ('boards/posix/native_posix/doc/board', 'boards/posix/native_posix/doc/index'), - ('boards/riscv/hifive1/doc/hifive1', 'boards/riscv/hifive1/doc/index'), - ('boards/riscv/m2gl025_miv/doc/m2g1025_miv', 'boards/riscv/m2gl025_miv/doc/index'), - ('boards/riscv/qemu_riscv32/doc/board', 'boards/riscv/qemu_riscv32/doc/index'), - ('boards/riscv/zedboard_pulpino/doc/zedboard_pulpino', 'boards/riscv/zedboard_pulpino/doc/index'), - ('boards/riscv/hifive1/doc/index', 'boards/riscv/hifive1/doc/index'), - ('boards/riscv/hifive1_revb/doc/index', 'boards/riscv/hifive1_revb/doc/index'), - ('boards/riscv/litex_vexriscv/doc/litex_vexriscv', 'boards/riscv/litex_vexriscv/doc/litex_vexriscv'), - ('boards/riscv/m2gl025_miv/doc/index', 'boards/riscv/m2gl025_miv/doc/index'), - ('boards/riscv/qemu_riscv32/doc/index', 'boards/riscv/qemu_riscv32/doc/index'), - ('boards/riscv/rv32m1_vega/doc/index', 'boards/riscv/rv32m1_vega/doc/index'), - ('boards/x86/arduino_101/doc/board', 'boards/x86/arduino_101/doc/index'), - ('boards/x86/galileo/doc/galileo', 'boards/x86/galileo/doc/index'), - ('boards/x86/minnowboard/doc/minnowboard', 'boards/x86/minnowboard/doc/index'), - ('boards/x86/qemu_x86/doc/board', 'boards/x86/qemu_x86/doc/index'), - ('boards/x86/tinytile/doc/board', 'boards/x86/tinytile/doc/index'), - ('boards/x86/up_squared/doc/up_squared', 'boards/x86/up_squared/doc/index'), - ('boards/x86/x86_jailhouse/doc/board', 'boards/x86/x86_jailhouse/doc/index'), - ('boards/xtensa/esp32/doc/esp32', 'boards/xtensa/esp32/doc/index'), - ('boards/xtensa/intel_s1000_crb/doc/intel_s1000', 'boards/xtensa/intel_s1000_crb/doc/index'), - ('boards/xtensa/qemu_xtensa/doc/board', 'boards/xtensa/qemu_xtensa/doc/index'), - ('boards/xtensa/xt-sim/doc/xt-sim', 'boards/xtensa/xt-sim/doc/index'), - ] + ('contribute/contribute_guidelines', 'contribute/index'), + ('application/application', 'application/index.rst'), + ('security/security', 'security/index'), + ('boards/boards', 'boards/index'), + ('samples/samples', 'samples/index'), + ('releases/release-notes', 'releases/index'), + ('getting_started/getting_started', 'getting_started/index'), + ('guides/debugging/coredump', 'guides/flash_debug/coredump'), + ('guides/debugging/gdbstub', 'guides/flash_debug/gdbstub'), + ('guides/debugging/host-tools', 'guides/flash_debug/host-tools'), + ('guides/debugging/index', 'guides/flash_debug/index'), + ('guides/debugging/probes', 'guides/flash_debug/probes'), + ('guides/debugging/thread-analyzer', 'guides/flash_debug/thread-analyzer'), + ('introduction/introducing_zephyr', 'introduction/index'), + ('api/index', 'reference/index'), + ('api/api', 'reference/index'), + ('subsystems/subsystems', 'reference/index'), + ('kernel/kernel', 'reference/kernel/index'), + ('boards/arc/em_starterkit/doc/board', 'boards/arc/em_starterkit/doc/index'), + ('boards/arc/nsim_em/doc/board', 'boards/arc/nsim_em/doc/index'), + ('boards/arm/96b_argonkey/doc/96b_argonkey', 'boards/arm/96b_argonkey/doc/index'), + ('boards/arm/96b_carbon/doc/96b_carbon', 'boards/arm/96b_carbon/doc/index'), + ('boards/arm/96b_carbon_nrf51/doc/96b_carbon_nrf51', 'boards/arm/96b_carbon_nrf51/doc/index'), + ('boards/arm/96b_neonkey/doc/96b_neonkey', 'boards/arm/96b_neonkey/doc/index'), + ('boards/arm/96b_nitrogen/doc/96b_nitrogen', 'boards/arm/96b_nitrogen/doc/index'), + ('boards/arm/adafruit_feather_m0_basic_proto/doc/adafruit_feather_m0_basic_proto', 'boards/arm/adafruit_feather_m0_basic_proto/doc/index'), + ('boards/arm/adafruit_trinket_m0/doc/adafruit_trinket_m0', 'boards/arm/adafruit_trinket_m0/doc/index'), + ('boards/arm/arduino_due/doc/board', 'boards/arm/arduino_due/doc/index'), + ('boards/arm/arduino_zero/doc/arduino_zero', 'boards/arm/arduino_zero/doc/index'), + ('boards/arm/atsamd20_xpro/doc/atsamd20_xpro', 'boards/arm/atsamd20_xpro/doc/index'), + ('boards/arm/bbc_microbit/doc/board', 'boards/arm/bbc_microbit/doc/index'), + ('boards/arm/cc3220sf_launchxl/doc/cc3220sf_launchxl', 'boards/arm/cc3220sf_launchxl/doc/index'), + ('boards/arm/colibri_imx7d_m4/doc/colibri_imx7d_m4', 'boards/arm/colibri_imx7d_m4/doc/index'), + ('boards/arm/disco_l475_iot1/doc/disco_l475_iot1', 'boards/arm/disco_l475_iot1/doc/index'), + ('boards/arm/dragino_lsn50/doc/dragino_lsn50', 'boards/arm/dragino_lsn50/doc/index'), + ('boards/arm/efm32wg_stk3800/doc/efm32wg_stk3800', 'boards/arm/efm32wg_stk3800/doc/index'), + ('boards/arm/efr32_slwstk6061a/doc/efr32_slwstk6061a', 'boards/arm/efr32_slwstk6061a/doc/index'), + ('boards/arm/frdm_k64f/doc/frdm_k64f', 'boards/arm/frdm_k64f/doc/index'), + ('boards/arm/frdm_kl25z/doc/frdm_kl25z', 'boards/arm/frdm_kl25z/doc/index'), + ('boards/arm/frdm_kw41z/doc/frdm_kw41z', 'boards/arm/frdm_kw41z/doc/index'), + ('boards/arm/hexiwear_k64/doc/hexiwear_k64', 'boards/arm/hexiwear_k64/doc/index'), + ('boards/arm/hexiwear_kw40z/doc/hexiwear_kw40z', 'boards/arm/hexiwear_kw40z/doc/index'), + ('boards/arm/lpcxpresso54114_m0/doc/lpcxpresso54114_m0', 'boards/arm/lpcxpresso54114_m0/doc/index'), + ('boards/arm/lpcxpresso54114_m4/doc/lpcxpresso54114', 'boards/arm/lpcxpresso54114_m4/doc/index'), + ('boards/arm/mimxrt1020_evk/doc/mimxrt1020_evk', 'boards/arm/mimxrt1020_evk/doc/index'), + ('boards/arm/mimxrt1050_evk/doc/mimxrt1050_evk', 'boards/arm/mimxrt1050_evk/doc/index'), + ('boards/arm/mimxrt1060_evk/doc/mimxrt1060_evk', 'boards/arm/mimxrt1060_evk/doc/index'), + ('boards/arm/mimxrt1064_evk/doc/mimxrt1064_evk', 'boards/arm/mimxrt1064_evk/doc/index'), + ('boards/arm/mps2_an385/doc/mps2_an385', 'boards/arm/mps2_an385/doc/index'), + ('boards/arm/msp_exp432p401r_launchxl/doc/msp_exp432p401r_launchxl', 'boards/arm/msp_exp432p401r_launchxl/doc/index'), + ('boards/arm/nrf51_ble400/doc/nrf51_ble400', 'boards/arm/nrf51_ble400/doc/index'), + ('boards/arm/nrf51_blenano/doc/nrf51_blenano', 'boards/arm/nrf51_blenano/doc/index'), + ('boards/arm/nrf51_pca10028/doc/nrf51_pca10028', 'boards/arm/nrf51dk_nrf51422/doc/index'), + ('boards/arm/nrf51_pca10028/doc/index', 'boards/arm/nrf51dk_nrf51422/doc/index'), + ('boards/arm/nrf51_pca10031/doc/index', 'boards/arm/nrf51dongle_nrf51422/doc/index'), + ('boards/arm/nrf51_vbluno51/doc/nrf51_vbluno51', 'boards/arm/nrf51_vbluno51/doc/index'), + ('boards/arm/nrf52810_pca10040/doc/nrf52810_pca10040', 'boards/arm/nrf52dk_nrf52810/doc/index'), + ('boards/arm/nrf52810_pca10040/doc/index', 'boards/arm/nrf52dk_nrf52810/doc/index'), + ('boards/arm/nrf52811_pca10056/doc/index', 'boards/arm/nrf52840dk_nrf52811/doc/index'), + ('boards/arm/nrf52833_pca10100/doc/index', 'boards/arm/nrf52833dk_nrf52833/doc/index'), + ('boards/arm/nrf52840_pca10056/doc/nrf52840_pca10056', 'boards/arm/nrf52840dk_nrf52840/doc/index'), + ('boards/arm/nrf52840_pca10056/doc/index', 'boards/arm/nrf52840dk_nrf52840/doc/index'), + ('boards/arm/nrf9160_pca10090/doc/index', 'boards/arm/nrf9160dk_nrf9160/doc/index'), + ('boards/arm/nrf52840_pca10090/doc/index', 'boards/arm/nrf9160dk_nrf52840/doc/index'), + ('boards/arm/nrf52840_pca10059/doc/nrf52840_pca10059', 'boards/arm/nrf52840dongle_nrf52840/doc/index'), + ('boards/arm/nrf52840_pca10059/doc/index', 'boards/arm/nrf52840dongle_nrf52840/doc/index'), + ('boards/arm/nrf52_adafruit_feather/doc/nrf52_adafruit_feather', 'boards/arm/nrf52_adafruit_feather/doc/index'), + ('boards/arm/nrf52_blenano2/doc/nrf52_blenano2', 'boards/arm/nrf52_blenano2/doc/index'), + ('boards/arm/nrf52_pca10040/doc/nrf52_pca10040', 'boards/arm/nrf52dk_nrf52832/doc/index'), + ('boards/arm/nrf52_pca10040/doc/index', 'boards/arm/nrf52dk_nrf52832/doc/index'), + ('boards/arm/nrf52_pca20020/doc/nrf52_pca20020', 'boards/arm/thingy52_nrf52832/doc/index'), + ('boards/arm/nrf52_pca20020/doc/index', 'boards/arm/thingy52_nrf52832/doc/index'), + ('boards/arm/nrf52_vbluno52/doc/nrf52_vbluno52', 'boards/arm/nrf52_vbluno52/doc/index'), + ('boards/arm/nrf5340_dk_nrf5340/doc/index', 'boards/arm/nrf5340pdk_nrf5340/doc/index'), + ('boards/arm/nucleo_f030r8/doc/nucleof030r8', 'boards/arm/nucleo_f030r8/doc/index'), + ('boards/arm/nucleo_f070rb/doc/nucleof070rb', 'boards/arm/nucleo_f070rb/doc/index'), + ('boards/arm/nucleo_f091rc/doc/nucleof091rc', 'boards/arm/nucleo_f091rc/doc/index'), + ('boards/arm/nucleo_f103rb/doc/nucleof103rb', 'boards/arm/nucleo_f103rb/doc/index'), + ('boards/arm/nucleo_f207zg/doc/nucleo_f207zg', 'boards/arm/nucleo_f207zg/doc/index'), + ('boards/arm/nucleo_f334r8/doc/nucleof334r8', 'boards/arm/nucleo_f334r8/doc/index'), + ('boards/arm/nucleo_f401re/doc/nucleof401re', 'boards/arm/nucleo_f401re/doc/index'), + ('boards/arm/nucleo_f411re/doc/nucleof411re', 'boards/arm/nucleo_f411re/doc/index'), + ('boards/arm/nucleo_f412zg/doc/nucleof412zg', 'boards/arm/nucleo_f412zg/doc/index'), + ('boards/arm/nucleo_f413zh/doc/nucleof413zh', 'boards/arm/nucleo_f413zh/doc/index'), + ('boards/arm/nucleo_f429zi/doc/nucleof429zi', 'boards/arm/nucleo_f429zi/doc/index'), + ('boards/arm/nucleo_f446re/doc/nucleof446re', 'boards/arm/nucleo_f446re/doc/index'), + ('boards/arm/nucleo_l053r8/doc/nucleol053r8', 'boards/arm/nucleo_l053r8/doc/index'), + ('boards/arm/nucleo_l073rz/doc/nucleol073rz', 'boards/arm/nucleo_l073rz/doc/index'), + ('boards/arm/nucleo_l432kc/doc/nucleol432kc', 'boards/arm/nucleo_l432kc/doc/index'), + ('boards/arm/nucleo_l476rg/doc/nucleol476rg', 'boards/arm/nucleo_l476rg/doc/index'), + ('boards/arm/olimex_stm32_e407/doc/olimex_stm32_e407', 'boards/arm/olimex_stm32_e407/doc/index'), + ('boards/arm/olimex_stm32_h407/doc/olimex_stm32_h407', 'boards/arm/olimex_stm32_h407/doc/index'), + ('boards/arm/olimex_stm32_p405/doc/olimex_stm32_p405', 'boards/arm/olimex_stm32_p405/doc/index'), + ('boards/arm/olimexino_stm32/doc/olimexino_stm32', 'boards/arm/olimexino_stm32/doc/index'), + ('boards/arm/qemu_cortex_m3/doc/board', 'boards/arm/qemu_cortex_m3/doc/index'), + ('boards/arm/reel_board/doc/reel_board', 'boards/arm/reel_board/doc/index'), + ('boards/arm/sam4s_xplained/doc/sam4s_xplained', 'boards/arm/sam4s_xplained/doc/index'), + ('boards/arm/sam_e70_xplained/doc/sam_e70_xplained', 'boards/arm/sam_e70_xplained/doc/index'), + ('boards/arm/stm3210c_eval/doc/stm3210c_eval', 'boards/arm/stm3210c_eval/doc/index'), + ('boards/arm/stm32373c_eval/doc/stm32373c_eval', 'boards/arm/stm32373c_eval/doc/index'), + ('boards/arm/stm32_min_dev/doc/stm32_min_dev', 'boards/arm/stm32_min_dev/doc/index'), + ('boards/arm/stm32f072_eval/doc/stm32f072_eval', 'boards/arm/stm32f072_eval/doc/index'), + ('boards/arm/stm32f072b_disco/doc/stm32f072b_disco', 'boards/arm/stm32f072b_disco/doc/index'), + ('boards/arm/stm32f0_disco/doc/stm32f0_disco', 'boards/arm/stm32f0_disco/doc/index'), + ('boards/arm/stm32f3_disco/doc/stm32f3_disco', 'boards/arm/stm32f3_disco/doc/index'), + ('boards/arm/stm32f411e_disco/doc/stm32f411e_disco', 'boards/arm/stm32f411e_disco/doc/index'), + ('boards/arm/stm32f412g_disco/doc/stm32f412g_disco', 'boards/arm/stm32f412g_disco/doc/index'), + ('boards/arm/stm32f429i_disc1/doc/stm32f429i_disc1', 'boards/arm/stm32f429i_disc1/doc/index'), + ('boards/arm/stm32f469i_disco/doc/stm32f469i_disco', 'boards/arm/stm32f469i_disco/doc/index'), + ('boards/arm/stm32f4_disco/doc/stm32f4_disco', 'boards/arm/stm32f4_disco/doc/index'), + ('boards/arm/stm32f723e_disco/doc/stm32f723e_disco', 'boards/arm/stm32f723e_disco/doc/index'), + ('boards/arm/stm32f746g_disco/doc/stm32f746g_disco', 'boards/arm/stm32f746g_disco/doc/index'), + ('boards/arm/stm32f769i_disco/doc/stm32f769i_disco', 'boards/arm/stm32f769i_disco/doc/index'), + ('boards/arm/stm32l476g_disco/doc/stm32l476g_disco', 'boards/arm/stm32l476g_disco/doc/index'), + ('boards/arm/stm32l496g_disco/doc/stm32l496g_disco', 'boards/arm/stm32l496g_disco/doc/index'), + ('boards/arm/udoo_neo_full_m4/doc/udoo_neo_full', 'boards/arm/udoo_neo_full_m4/doc/index'), + ('boards/arm/usb_kw24d512/doc/usb_kw24d512', 'boards/arm/usb_kw24d512/doc/index'), + ('boards/arm/v2m_beetle/doc/v2m_beetle', 'boards/arm/v2m_beetle/doc/index'), + ('boards/arm/warp7_m4/doc/warp7_m4', 'boards/arm/warp7_m4/doc/index'), + ('boards/nios2/altera_max10/doc/board', 'boards/nios2/altera_max10/doc/index'), + ('boards/nios2/qemu_nios2/doc/board', 'boards/nios2/qemu_nios2/doc/index'), + ('boards/posix/native_posix/doc/board', 'boards/posix/native_posix/doc/index'), + ('boards/riscv/hifive1/doc/hifive1', 'boards/riscv/hifive1/doc/index'), + ('boards/riscv/m2gl025_miv/doc/m2g1025_miv', 'boards/riscv/m2gl025_miv/doc/index'), + ('boards/riscv/qemu_riscv32/doc/board', 'boards/riscv/qemu_riscv32/doc/index'), + ('boards/riscv/zedboard_pulpino/doc/zedboard_pulpino', 'boards/riscv/zedboard_pulpino/doc/index'), + ('boards/riscv/hifive1/doc/index', 'boards/riscv/hifive1/doc/index'), + ('boards/riscv/hifive1_revb/doc/index', 'boards/riscv/hifive1_revb/doc/index'), + ('boards/riscv/litex_vexriscv/doc/litex_vexriscv', 'boards/riscv/litex_vexriscv/doc/litex_vexriscv'), + ('boards/riscv/m2gl025_miv/doc/index', 'boards/riscv/m2gl025_miv/doc/index'), + ('boards/riscv/qemu_riscv32/doc/index', 'boards/riscv/qemu_riscv32/doc/index'), + ('boards/riscv/rv32m1_vega/doc/index', 'boards/riscv/rv32m1_vega/doc/index'), + ('boards/x86/arduino_101/doc/board', 'boards/x86/arduino_101/doc/index'), + ('boards/x86/galileo/doc/galileo', 'boards/x86/galileo/doc/index'), + ('boards/x86/minnowboard/doc/minnowboard', 'boards/x86/minnowboard/doc/index'), + ('boards/x86/qemu_x86/doc/board', 'boards/x86/qemu_x86/doc/index'), + ('boards/x86/tinytile/doc/board', 'boards/x86/tinytile/doc/index'), + ('boards/x86/up_squared/doc/up_squared', 'boards/x86/up_squared/doc/index'), + ('boards/x86/x86_jailhouse/doc/board', 'boards/x86/x86_jailhouse/doc/index'), + ('boards/xtensa/esp32/doc/esp32', 'boards/xtensa/esp32/doc/index'), + ('boards/xtensa/intel_s1000_crb/doc/intel_s1000', 'boards/xtensa/intel_s1000_crb/doc/index'), + ('boards/xtensa/qemu_xtensa/doc/board', 'boards/xtensa/qemu_xtensa/doc/index'), + ('boards/xtensa/xt-sim/doc/xt-sim', 'boards/xtensa/xt-sim/doc/index'), +] # -- Options for LaTeX output --------------------------------------------- @@ -516,20 +522,24 @@ } breathe_default_project = "Zephyr" -# Changing breathe configuration to force "c" domain doesn't work -# see https://github.com/michaeljones/breathe/issues/282 -#breathe_domain_by_extension = { -# "h" : "c", -# "c" : "c", -# } +breathe_domain_by_extension = { + "h": "c", + "c": "c", +} +breathe_separate_member_pages = True +breathe_show_enumvalue_initializer = True # Qualifiers to a function are causing Sphihx/Breathe to warn about # Error when parsing function declaration and more. This is a list # of strings that the parser additionally should accept as # attributes. -cpp_id_attributes = ['__syscall', '__deprecated', - '__may_alias', '__used', '__unused', '__weak', - '__DEPRECATED_MACRO', 'FUNC_NORETURN'] +cpp_id_attributes = [ + '__syscall', '__deprecated', '__may_alias', + '__used', '__unused', '__weak', + '__DEPRECATED_MACRO', 'FUNC_NORETURN', + '__subsystem', +] +c_id_attributes = cpp_id_attributes # docs_title is used in the breadcrumb title in the zephyr docs theme html_context = { @@ -539,6 +549,8 @@ 'theme_logo_only': False, 'current_version': version, 'versions': (("latest", "/"), + ("2.4.0", "/2.4.0/"), + ("2.3.0", "/2.3.0/"), ("2.2.0", "/2.2.0/"), ("2.1.0", "/2.1.0/"), ("2.0.0", "/2.0.0/"), @@ -564,8 +576,8 @@ linkcheck_anchors = False def setup(app): - app.add_stylesheet("zephyr-custom.css") + app.add_css_file("zephyr-custom.css") - app.add_javascript("https://www.googletagmanager.com/gtag/js?id=UA-831873-47") - app.add_javascript("ga-tracker.js") - app.add_javascript("zephyr-custom.js") + app.add_js_file("https://www.googletagmanager.com/gtag/js?id=UA-831873-47") + app.add_js_file("ga-tracker.js") + app.add_js_file("zephyr-custom.js") diff --git a/doc/contribute/index.rst b/doc/contribute/index.rst index 6f705c70ff8d92..f27373301d9371 100644 --- a/doc/contribute/index.rst +++ b/doc/contribute/index.rst @@ -130,6 +130,22 @@ to add the sign-off you can also amend a previous commit with the sign-off by running ``git commit --amend -s``. If you've pushed your changes to GitHub already you'll need to force push your branch after this with ``git push -f``. +Notes +===== + +Any contributions made as part of submitted pull requests are considered free +for the Project to use. Developers are permitted to cherry-pick patches that +are included in pull requests submitted by other contributors. It is expected +that + +* the content of the patches will not be substantially modified, +* the cherry-picked commits or portions of a commit shall preserve the original + sign-off messages and the author identity. + +:ref:`modifying_contributions` describes additional recommended policies +around working with contributions submitted by other developers. + + Prerequisites ************* @@ -233,6 +249,13 @@ The `builds@lists.zephyrproject.org mailing list `_ archives the CI (shippable) nightly build results. +Coding Guidelines +***************** + +Beyond the :ref:`coding_style` that Zephyr enforces for all code that is +submitted for inclusion, the project targets compliance with a series of +coding guidelines. Refer to the :ref:`coding_guidelines` section of the +documentation for additional details. .. _Contribution Tools: @@ -270,23 +293,23 @@ Note, gitlint only checks HEAD (the most recent commit), so you should run it after each commit, or use the ``--commits`` option to specify a commit range covering all the development patches to be submitted. -sanitycheck -=========== +twister +======= .. note:: - sanitycheck does not currently run on Windows. + twister does not currently run on Windows. To verify that your changes did not break any tests or samples, please run the -``sanitycheck`` script locally before submitting your pull request to GitHub. To +``twister`` script locally before submitting your pull request to GitHub. To run the same tests the CI system runs, follow these steps from within your local Zephyr source working directory: .. code-block:: console source zephyr-env.sh - ./scripts/sanitycheck + ./scripts/twister -The above will execute the basic sanitycheck script, which will run various +The above will execute the basic twister script, which will run various kernel tests using the QEMU emulator. It will also do some build tests on various samples with advanced features that can't run in QEMU. @@ -321,6 +344,8 @@ On Linux systems, you can install uncrustify with For Windows installation instructions see the `sourceforge listing for uncrustify `_. +.. _coding_style: + Coding Style ************ @@ -375,7 +400,7 @@ before pushing on zephyr repo. To do this, make the file while read local_ref local_sha remote_ref remote_sha do args="$remote $url $local_ref $local_sha $remote_ref $remote_sha" - exec ${ZEPHYR_BASE}/series-push-hook.sh $args + exec ${ZEPHYR_BASE}/scripts/series-push-hook.sh $args done exit 0 @@ -449,7 +474,7 @@ workflow here: git checkout -b fix_out_of_date_patch origin/net #. Make changes, test locally, change, test, test again, ... (Check out the - prior chapter on `sanitycheck`_ as well). + prior chapter on `twister`_ as well). #. When things look good, start the pull request process by adding your changed files:: @@ -691,11 +716,16 @@ Contributing non-Apache 2.0 licensed components Importing code into the Zephyr OS from other projects that use a license other than the Apache 2.0 license needs to be fully understood in -context and approved by the `Zephyr governing board`_. +context and approved by the `Zephyr governing board`_. The board will +automatically reject licenses that have not been approved by the `Open Source +Initiative (OSI)`_. .. _Zephyr governing board: https://www.zephyrproject.org/governance/ +.. _Open Source Initiative (OSI): + https://opensource.org/licenses/alphabetical + By carefully reviewing potential contributions and also enforcing a :ref:`DCO` for contributed code, we ensure that the Zephyr community can develop products with the Zephyr Project @@ -769,6 +799,7 @@ Contribution Roles and Responsibilities .. toctree:: :maxdepth: 1 + modifying_contributions.rst project_roles.rst The Zephyr project defines a development process workflow using GitHub diff --git a/doc/contribute/modifying_contributions.rst b/doc/contribute/modifying_contributions.rst new file mode 100644 index 00000000000000..0dd9a24b23c73a --- /dev/null +++ b/doc/contribute/modifying_contributions.rst @@ -0,0 +1,70 @@ +.. _modifying_contributions: + +Modifying Contributions made by other developers +************************************************ + +Scenarios +######### + +Zephyr contributors and collaborators are encouraged to assist +as reviewers in pull requests, so that patches may be approved and merged +to Zephyr's main branch as part of the original pull requests. The authors +of the pull requests are responsible for amending their original commits +following the review process. + +There are occasions, however, when a contributor might need to modify patches +included in pull requests that are submitted by other Zephyr contributors. +For instance, this is the case when: + +* a developer cherry-picks commits submitted by other contributors into their + own pull requests in order to: + + * integrate useful content which is part of a stale pull request, or + * get content merged to the project's main branch as part of a larger + patch + +* a developer pushes to a branch or pull request opened by another + contributor in order to: + + * assist in updating pull requests in order to get the patches merged + to the project's main branch + * drive stale pull requests to completion so they can be merged + + +Accepted policies +################# + +A developer who intends to cherry-pick and potentially modify patches sent by +another contributor shall: + +* clarify in their pull request the reason for cherry-picking the patches, + instead of assisting in getting the patches merged in their original + pull request, and +* invite the original author of the patches to their pull request review. + +A developer who intends to force-push to a branch or pull request of +another Zephyr contributor shall clarify in the pull request the reason +for pushing and for modifying the existing patches (e.g. stating that it +is done to drive the pull request review to completion, when the pull +request author is not able to do so). + +.. note:: + Developers should try to limit the above practice to pull requests identified + as *stale*. Read about how to identify pull requests as stale in + :ref:`development processes and tools ` + +If the original patches are substantially modified, the developer can either: + +* (preferably) reach out to the original author and request them to + acknowledge that the modified patches may be merged while having + the original sign-off line and author identity, or +* submit the modified patches as their *own* work (i.e. with their + *own* sign-off line and author identity). In this case, the developer + shall identify in the commit message(s) the original source the + submitted work is based on (mentioning, for example, the original PR + number). + +.. note:: + Contributors should uncheck the box *“Allow Edits By Maintainers"* + to indicate that they do not wish their patches to be amended, + inside their original branch or pull request, by other Zephyr developers. diff --git a/doc/development_process/api_lifecycle.rst b/doc/development_process/api_lifecycle.rst index 3bca7edf6a7c61..e58f6eef9d65f9 100644 --- a/doc/development_process/api_lifecycle.rst +++ b/doc/development_process/api_lifecycle.rst @@ -201,7 +201,7 @@ The following are the requirements for deprecating an existing API: - Mark as deprecated. This can be done by using the compiler itself (``__deprecated`` for function declarations and ``__DEPRECATED_MACRO`` for macro definitions), or by introducing a Kconfig option (typically one that - contains the ``LEGACY`` word in it) that, when enabled, reverts the APIs + contains the ``DEPRECATED`` word in it) that, when enabled, reverts the APIs back to their previous form - Document the deprecation - Include the deprecation in the "API Changes" of the release notes for the diff --git a/doc/development_process/dev_env_and_tools.rst b/doc/development_process/dev_env_and_tools.rst index 133bde27130f13..08c993160ab09a 100644 --- a/doc/development_process/dev_env_and_tools.rst +++ b/doc/development_process/dev_env_and_tools.rst @@ -210,16 +210,35 @@ Developers are expected to fix issues and rework their patches and submit again. The CI infrastructure currently runs the following tests: -- Run ''checkpatch'' for code style issues (can vote -1 on errors) +- Run ''checkpatch'' for code style issues (can vote -1 on errors; see note) - Gitlint: Git commit style based on project requirements - License Check: Check for conflicting licenses -- Run ''sanitycheck'' script +- Run ''twister'' script - Run kernel tests in QEMU (can vote -1 on errors) - Build various samples for different boards (can vote -1 on errors) - Verify documentation builds correctly. +.. note:: + + ''checkpatch'' is a Perl script that uses regular expressions to + extract information that requires a C language parser to process + accurately. As such it sometimes issues false positives. Known + cases include constructs like:: + + static uint8_t __aligned(PAGE_SIZE) page_pool[PAGE_SIZE * POOL_PAGES]; + IOPCTL_Type *base = config->base; + + Both lines produce a diagnostic regarding spaces around the ``*`` + operator: the first is misidentifed as a pointer type declaration + that would be correct as ``PAGE_SIZE *POOL_PAGES`` while the second + is misidentified as a multiplication expression that would be correct + as ``IOPCTL_Type * base``. + + Maintainers can override the -1 in cases where the CI infrastructure + gets the wrong answer. + .. _gh_labels: diff --git a/doc/development_process/release_process.rst b/doc/development_process/release_process.rst index f8e65373951dde..5c0dad73ca497f 100644 --- a/doc/development_process/release_process.rst +++ b/doc/development_process/release_process.rst @@ -76,7 +76,8 @@ any time). As fixes make their way into the mainline, the patch rate will slow over time. The mainline release owner releases new -rc drops once or twice a week; a normal series will get up to somewhere between -rc4 and -rc6 before the code base is -considered to be sufficiently stable and the final 0.4.x release is made. +considered to be sufficiently stable and the quality metrics have been achieved +at which point the final 0.4.x release is made. At that point, the whole process starts over again. @@ -98,6 +99,27 @@ Here is the description of the various moderation levels: - Bug Fixes: P1 and P2 - Documentation + Test Coverage +.. _release_quality_criteria: + +Release Quality Criteria +************************ + +The current backlog of prioritized bugs shall be used as a quality metric to +gate the final release. The following counts shall be used: + +.. csv-table:: Bug Count Release Thresholds + :header: "High", "Medium", "Low" + :widths: auto + + + "0","<20","<50" + +.. note:: + + The "low" bug count target of <50 will be a phased appoach starting with 150 + for release 2.4.0, 100 for release 2.5.0, and 50 for release 2.6.0 + + Releases ********* @@ -126,7 +148,6 @@ The following syntax should be used for releases and tags in Git: Zephyr Code and Releases - Long Term Support (LTS) ======================= @@ -241,7 +262,8 @@ steps: interface. The GitHub release interface does not generate annotated tags (it generates 'lightweight' tags regardless of release or pre-release). You should also upload your gpg public key to your GitHub account, since the instructions - below involve creating signed tags. + below involve creating signed tags. However, if you do not have a gpg public + key you can opt to remove the ``-s`` option from the commands below. .. tabs:: @@ -265,7 +287,7 @@ steps: #. Tag and push the version, using an annotated tag:: $ git pull - $ git tag -m "Zephyr 1.11.0-rc1" -s v1.11.0-rc1 + $ git tag -s -m "Zephyr 1.11.0-rc1" v1.11.0-rc1 $ git push git@github.com:zephyrproject-rtos/zephyr.git v1.11.0-rc1 #. Create a shortlog of changes between the previous release (use @@ -274,7 +296,7 @@ steps: $ git shortlog v1.10.0..v1.11.0-rc1 #. Find the new tag at the top of the releases page and edit the release - with the ``Draft a new release`` button with the following: + with the ``Edit tag`` button with the following: * Name it ``Zephyr 1.11.0-rc1`` * Copy the shortlog into the release notes textbox (*don't forget @@ -297,9 +319,9 @@ steps: #. Update the version variables in the :zephyr_file:`VERSION` file located in the root of the Git repository. Set ``EXTRAVERSION`` - variable to zero to indicate final release:: + variable to an empty string to indicate final release:: - EXTRAVERSION = 0 + EXTRAVERSION = #. Post a PR with the updated :zephyr_file:`VERSION` file using ``release: Zephyr 1.11.0`` as the commit subject. Merge @@ -307,14 +329,17 @@ steps: #. Tag and push the version, using two annotated tags:: $ git pull - $ git tag -m "Zephyr 1.11.0" -s v1.11.0 + $ git tag -s -m "Zephyr 1.11.0" v1.11.0 $ git push git@github.com:zephyrproject-rtos/zephyr.git v1.11.0 - $ git tag -m "Zephyr 1.11.0" -s zephyr-v1.11.0 + # This is the tag that will represent the release on GitHub, so that + # the file you can download is named ``zephyr-v1.11.0.zip`` and not + # just ``v1.11.0.zip`` + $ git tag -s -m "Zephyr 1.11.0" zephyr-v1.11.0 $ git push git@github.com:zephyrproject-rtos/zephyr.git zephyr-v1.11.0 - #. Find the new tag at the top of the releases page and edit the release - with the ``Draft a new release`` button with the following: + #. Find the new ``zephyr-v1.11.0`` tag at the top of the releases page + and edit the release with the ``Edit tag`` button with the following: * Name it ``Zephyr 1.11.0`` * Copy the full content of ``docs/releases/release-notes-1.11.rst`` diff --git a/doc/extensions/zephyr/link-roles.py b/doc/extensions/zephyr/link-roles.py index 9b827e535654f7..e72796e05b7271 100644 --- a/doc/extensions/zephyr/link-roles.py +++ b/doc/extensions/zephyr/link-roles.py @@ -9,6 +9,14 @@ import re from docutils import nodes from local_util import run_cmd_get_output +try: + import west.manifest + try: + west_manifest = west.manifest.Manifest.from_file() + except west.util.WestNotFound: + west_manifest = None +except ImportError: + west_manifest = None def get_github_rev(): @@ -22,8 +30,17 @@ def get_github_rev(): def setup(app): rev = get_github_rev() - # links to files or folders on the GitHub - baseurl = 'https://github.com/zephyrproject-rtos/zephyr' + # try to get url from West; this adds compatibility with repos + # located elsewhere + if west_manifest is not None: + baseurl = west_manifest.get_projects(['zephyr'])[0].url + else: + baseurl = None + + # or fallback to default + if baseurl is None or baseurl == '': + baseurl = 'https://github.com/zephyrproject-rtos/zephyr' + app.add_role('zephyr_file', autolink('{}/blob/{}/%s'.format(baseurl, rev))) app.add_role('zephyr_raw', autolink('{}/raw/{}/%s'.format(baseurl, rev))) diff --git a/doc/getting_started/img/ReelBoard-Blinky.gif b/doc/getting_started/img/ReelBoard-Blinky.gif index 8d53a33373538a..1374e32ae94d2b 100644 Binary files a/doc/getting_started/img/ReelBoard-Blinky.gif and b/doc/getting_started/img/ReelBoard-Blinky.gif differ diff --git a/doc/getting_started/index.rst b/doc/getting_started/index.rst index 9f01332fb47a48..49a9a5dc91e185 100644 --- a/doc/getting_started/index.rst +++ b/doc/getting_started/index.rst @@ -292,14 +292,14 @@ to build Zephyr applications. .. code-block:: bash cd ~ - wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.11.3/zephyr-sdk-0.11.3-setup.run + wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.11.4/zephyr-sdk-0.11.4-setup.run - #. Run the installer, installing the SDK in :file:`~/zephyr-sdk-0.11.3`: + #. Run the installer, installing the SDK in :file:`~/zephyr-sdk-0.11.4`: .. code-block:: bash - chmod +x zephyr-sdk-0.11.3-setup.run - ./zephyr-sdk-0.11.3-setup.run -- -d ~/zephyr-sdk-0.11.3 + chmod +x zephyr-sdk-0.11.4-setup.run + ./zephyr-sdk-0.11.4-setup.run -- -d ~/zephyr-sdk-0.11.4 .. note:: It is recommended to install the Zephyr SDK at one of the following locations: @@ -312,7 +312,7 @@ to build Zephyr applications. * ``/usr/zephyr-sdk[-x.y.z]`` * ``/usr/local/zephyr-sdk[-x.y.z]`` - where ``[-x.y.z]`` is optional text, and can be any text, for example ``-0.11.3``. + where ``[-x.y.z]`` is optional text, and can be any text, for example ``-0.11.4``. If installing the Zephyr SDK outside any of those locations, please read: :ref:`zephyr_sdk` @@ -323,7 +323,7 @@ to build Zephyr applications. .. code-block:: bash - sudo cp ~/zephyr-sdk-0.11.3/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d + sudo cp ~/zephyr-sdk-0.11.4/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d sudo udevadm control --reload .. group-tab:: macOS @@ -398,7 +398,7 @@ Then flash the sample using :ref:`west flash `: west flash -You may need to install additional :ref:`host tools ` +You may need to install additional :ref:`host tools ` required by your board. The ``west flash`` command will print an error if any required dependencies are missing. @@ -418,7 +418,7 @@ Here are some next steps for exploring Zephyr: * Try other :ref:`samples-and-demos` * Learn about :ref:`application` and the :ref:`west ` tool * Find out about west's :ref:`flashing and debugging ` - features, or more about :ref:`debugging` in general + features, or more about :ref:`flashing_and_debugging` in general * Check out :ref:`beyond-GSG` for additional setup alternatives and ideas * Discover :ref:`project-resources` for getting help from the Zephyr community diff --git a/doc/getting_started/installation_linux.rst b/doc/getting_started/installation_linux.rst index 6ae0a2f93f6030..05eef3fb4d58be 100644 --- a/doc/getting_started/installation_linux.rst +++ b/doc/getting_started/installation_linux.rst @@ -226,10 +226,12 @@ following target architectures: * :abbr:`Nios II` -* :abbr:`Xtensa` - * :abbr:`RISC-V` +* :abbr:`SPARC` + +* :abbr:`Xtensa` + Follow these steps to install the Zephyr SDK: #. Download the `latest SDK diff --git a/doc/getting_started/toolchain_3rd_party_x_compilers.rst b/doc/getting_started/toolchain_3rd_party_x_compilers.rst index 970aa1eb6101ad..04acc2592c679f 100644 --- a/doc/getting_started/toolchain_3rd_party_x_compilers.rst +++ b/doc/getting_started/toolchain_3rd_party_x_compilers.rst @@ -51,6 +51,39 @@ GNU ARM Embedded C:\gnu_arm_embedded +DesignWare ARC MetaWare Development Toolkit (MWDT) +************************************************** + +#. You need to have `ARC MWDT + `_ installed on your + host. + +#. :ref:`Set these environment variables `: + + - Set :envvar:`ZEPHYR_TOOLCHAIN_VARIANT` to ``arcmwdt``. + - Set :envvar:`ARCMWDT_TOOLCHAIN_PATH` to the toolchain installation + directory. MWDT installation provides :envvar:`METAWARE_ROOT` so simply set + :envvar:`ARCMWDT_TOOLCHAIN_PATH` to ``$METAWARE_ROOT/../`` (Linux) + or ``%METAWARE_ROOT%\..\`` (Windows) + +#. To check that you have set these variables correctly in your current + environment, follow these example shell sessions (the + :envvar:`ARCMWDT_TOOLCHAIN_PATH` values may be different on your system): + + .. code-block:: console + + # Linux: + $ echo $ZEPHYR_TOOLCHAIN_VARIANT + arcmwdt + $ echo $ARCMWDT_TOOLCHAIN_PATH + /home/you/ARC/MWDT_2019.12/ + + # Windows + > echo %ZEPHYR_TOOLCHAIN_VARIANT% + arcmwdt + > echo %ARCMWDT_TOOLCHAIN_PATH% + C:\ARC\MWDT_2019.12\ + Crosstool-NG ************ diff --git a/doc/guides/bluetooth/bluetooth-arch.rst b/doc/guides/bluetooth/bluetooth-arch.rst index ef3aa6d85f721c..d73f1ce389a821 100644 --- a/doc/guides/bluetooth/bluetooth-arch.rst +++ b/doc/guides/bluetooth/bluetooth-arch.rst @@ -259,8 +259,8 @@ Peripheral role Most Zephyr-based BLE devices will most likely be peripheral-role devices. This means that they perform connectable advertising and expose one or more GATT services. After registering services using the -:cpp:func:`bt_gatt_service_register` API the application will typically -start connectable advertising using the :cpp:func:`bt_le_adv_start` API. +:c:func:`bt_gatt_service_register` API the application will typically +start connectable advertising using the :c:func:`bt_le_adv_start` API. There are several peripheral sample applications available in the tree, such as :zephyr_file:`samples/bluetooth/peripheral_hr`. @@ -277,12 +277,12 @@ client, first performing discovery of available services and then accessing one or more supported services. To initially discover a device to connect to the application will likely -use the :cpp:func:`bt_le_scan_start` API, wait for an appropriate device +use the :c:func:`bt_le_scan_start` API, wait for an appropriate device to be found (using the scan callback), stop scanning using -:cpp:func:`bt_le_scan_stop` and then connect to the device using -:cpp:func:`bt_conn_create_le`. If the central wants to keep +:c:func:`bt_le_scan_stop` and then connect to the device using +:c:func:`bt_conn_create_le`. If the central wants to keep automatically reconnecting to the peripheral it should use the -:cpp:func:`bt_le_set_auto_conn` API. +:c:func:`bt_le_set_auto_conn` API. There are some sample applications for the central role available in the tree, such as :zephyr_file:`samples/bluetooth/central_hr`. @@ -290,7 +290,7 @@ tree, such as :zephyr_file:`samples/bluetooth/central_hr`. Observer role ============= -An observer role device will use the :cpp:func:`bt_le_scan_start` API to +An observer role device will use the :c:func:`bt_le_scan_start` API to scan for device, but it will not connect to any of them. Instead it will simply utilize the advertising data of found devices, combining it optionally with the received signal strength (RSSI). @@ -298,7 +298,7 @@ optionally with the received signal strength (RSSI). Broadcaster role ================ -A broadcaster role device will use the :cpp:func:`bt_le_adv_start` API to +A broadcaster role device will use the :c:func:`bt_le_adv_start` API to advertise specific advertising data, but the type of advertising will be non-connectable, i.e. other device will not be able to connect to it. @@ -314,14 +314,14 @@ Security To achieve a secure relationship between two Bluetooth devices a process called pairing is used. This process can either be triggered implicitly through the security properties of GATT services, or explicitly using -the :cpp:func:`bt_conn_security` API on a connection object. +the :c:func:`bt_conn_security` API on a connection object. To achieve a higher security level, and protect against Man-In-The-Middle (MITM) attacks, it is recommended to use some out-of-band channel during the pairing. If the devices have a sufficient user interface this "channel" is the user itself. The capabilities of -the device are registered using the :cpp:func:`bt_conn_auth_cb_register` -API. The :c:type:`bt_conn_auth_cb` struct that's passed to this API has +the device are registered using the :c:func:`bt_conn_auth_cb_register` +API. The :c:struct:`bt_conn_auth_cb` struct that's passed to this API has a set of optional callbacks that can be used during the pairing - if the device lacks some feature the corresponding callback may be set to NULL. For example, if the device does not have an input method but does have a @@ -332,17 +332,17 @@ capable of displaying a passkey to the user. Depending on the local and remote security requirements & capabilities, there are four possible security levels that can be reached: - :cpp:enumerator:`BT_SECURITY_LOW` + :c:enumerator:`BT_SECURITY_LOW` No encryption and no authentication. - :cpp:enumerator:`BT_SECURITY_MEDIUM` + :c:enumerator:`BT_SECURITY_MEDIUM` Encryption but no authentication (no MITM protection). - :cpp:enumerator:`BT_SECURITY_HIGH` + :c:enumerator:`BT_SECURITY_HIGH` Encryption and authentication using the legacy pairing method from Bluetooth 4.0 and 4.1. - :cpp:enumerator:`BT_SECURITY_FIPS` + :c:enumerator:`BT_SECURITY_FIPS` Encryption and authentication using the LE Secure Connections feature available since Bluetooth 4.2. @@ -379,6 +379,8 @@ should also be enabled. The API reference for Mesh can be found in the :ref:`Mesh API reference section `. +.. _bluetooth-persistent-storage: + Persistent storage ================== diff --git a/doc/guides/bluetooth/bluetooth-dev.rst b/doc/guides/bluetooth/bluetooth-dev.rst index e778423a6ffb50..3299f1045bbb43 100644 --- a/doc/guides/bluetooth/bluetooth-dev.rst +++ b/doc/guides/bluetooth/bluetooth-dev.rst @@ -156,10 +156,10 @@ another real or simulated device. Initialization ************** -The Bluetooth subsystem is initialized using the :cpp:func:`bt_enable` +The Bluetooth subsystem is initialized using the :c:func:`bt_enable` function. The caller should ensure that function succeeds by checking the return code for errors. If a function pointer is passed to -:cpp:func:`bt_enable`, the initialization happens asynchronously, and the +:c:func:`bt_enable`, the initialization happens asynchronously, and the completion is notified through the given function. Bluetooth Application Example @@ -174,8 +174,8 @@ advertising, effectively acting as a Bluetooth Low Energy broadcaster. :lines: 19- :linenos: -The key APIs employed by the beacon sample are :cpp:func:`bt_enable` -that's used to initialize Bluetooth and then :cpp:func:`bt_le_adv_start` +The key APIs employed by the beacon sample are :c:func:`bt_enable` +that's used to initialize Bluetooth and then :c:func:`bt_le_adv_start` that's used to start advertising a specific combination of advertising and scan response data. diff --git a/doc/guides/bluetooth/bluetooth-qual.rst b/doc/guides/bluetooth/bluetooth-qual.rst index 3c4775b43bdf52..c03d4c97ddc21c 100644 --- a/doc/guides/bluetooth/bluetooth-qual.rst +++ b/doc/guides/bluetooth/bluetooth-qual.rst @@ -20,13 +20,17 @@ Host qualifications - Link - Qualifying Company + * - 2.2.x + - `QDID 151074 `_ + - Demant A/S + * - 1.14.x - `QDID 139258 `__ - The Linux Foundation * - 1.13 - `QDID 119517 `__ - - Nordic + - Nordic Semiconductor Mesh qualifications =================== @@ -53,14 +57,19 @@ Controller qualifications - Qualifying Company - Compatible Hardware + * - 2.2.x + - `QDID 150092 `__ + - Nordic Semiconductor + - nRF52x + * - 1.14.x - `QDID 135679 `__ - - Nordic + - Nordic Semiconductor - nRF52x * - 1.9 to 1.13 - `QDID 101395 `__ - - Nordic + - Nordic Semiconductor - nRF52x ICS Features diff --git a/doc/guides/code-relocation.rst b/doc/guides/code-relocation.rst index 37289d8b00aa9c..9b5fa3d7fc8d6a 100644 --- a/doc/guides/code-relocation.rst +++ b/doc/guides/code-relocation.rst @@ -94,7 +94,7 @@ This section shows additional configuration options that can be set in Sample ====== A sample showcasing this feature is provided at -``$ZEPHYR_BASE/samples/application_development/test_relocation/`` +``$ZEPHYR_BASE/samples/application_development/code_relocation/`` This is an example of using the code relocation feature. diff --git a/doc/guides/coding_guidelines/index.rst b/doc/guides/coding_guidelines/index.rst new file mode 100644 index 00000000000000..d7ac6a97c963b2 --- /dev/null +++ b/doc/guides/coding_guidelines/index.rst @@ -0,0 +1,825 @@ +.. _coding_guidelines: + +Coding Guidelines +################# + +The project TSC and the Safety Committee of the project agreed to implement +a staged and incremental approach for complying with a set of coding rules (AKA +Coding Guidelines) to improve quality and consistency of the code base. Below +are the agreed upon stages and the approximate timelines: + +Stage I + Coding guideline rules are available to be followed and referenced, + but not enforced. Rules are not yet enforced in CI and pull-requests cannot be + blocked by reviewers/approvers due to violations. + +Stage II + Begin enforcement on a limited scope of the code base. Initially this would be + the safety certification scope. For rules easily applied across codebase, we + should not limit compliance to initial scope. This step requires tooling and + CI setup. + This stage will begin during the 2.4 development cycle and end with the Zephyr + LTS2 (2.6) to achieve and LTS2 that is ready for certification. + +Stage III + Revisit the coding guideline rules and based on experience from previous + stages, refine/iterate on selected rules. This stage is to start after LTS2. + +Stage IV + Expand enforcement to the wider codebase. Exceptions may be granted on some + areas of the codebase with a proper justification. Exception would require + TSC approval. + +.. note:: + + Coding guideline rules may be removed/changed at any time by filing a + GH issue/RFC. + +Main rules +********** + +The coding guideline rules are based on MISRA-C 2012 and are a subset of MISRA-C. +The subset is listed in the table below with a summary of the rules, its +severity and the equivlent rules from other standards for reference. + +.. note:: + + For existing Zephyr maintainers and collaborators, if you are unable to + obtain a copy through your employer, a limited number of copies will be made + available through the project. If you need a copy of MISRA-C 2012, please + send email to safety@lists.zephyrproject.org and provide details on reason + why you can't obtain one through other options and expected contributions + once you have one. The safety committee will review all requests. + + +.. list-table:: Main rules + :header-rows: 1 + + * - MISRA C 2012 + - Severity + - Description + - CERT C + - Example + * - Dir 1.1 + - Required + - Any implementation-defined behaviour on which the output of the program depends shall be documented and understood + - `MSC09-C `_ + - `Dir 1.1 `_ + * - Dir 2.1 + - Required + - All source files shall compile without any compilation errors + - N/A + - `Dir 2.1 `_ + * - Dir 3.1 + - Required + - All code shall be traceable to documented requirements + - N/A + - `Dir 3.1 `_ + * - Dir 4.1 + - Required + - Run-time failures shall be minimized + - N/A + - `Dir 4.1 `_ + * - Dir 4.2 + - Advisory + - All usage of assembly language should be documented + - N/A + - `Dir 4.2 `_ + * - Dir 4.4 + - Advisory + - Sections of code should not be “commented out” + - `MSC04-C `_ + - `Dir 4.4 `_ + * - Dir 4.5 + - Advisory + - Identifiers in the same name space with overlapping visibility should be typographically unambiguous + - `DCL02-C `_ + - `Dir 4.5 `_ + * - Dir 4.6 + - Advisory + - typedefs that indicate size and signedness should be used in place of the basic numerical types + - N/A + - `Dir 4.6 `_ + * - Dir 4.7 + - Required + - If a function returns error information, then that error information shall be tested + - N/A + - `Dir 4.7 `_ + * - Dir 4.8 + - Advisory + - If a pointer to a structure or union is never dereferenced within a translation unit, then the implementation of the object should be hidden + - `DCL12-C `_ + - | `Dir 4.8 example 1 `_ + | `Dir 4.8 example 2 `_ + * - Dir 4.9 + - Advisory + - A function should be used in preference to a function-like macro where they are interchangeable + - `PRE00-C `_ + - `Dir 4.9 `_ + * - Dir 4.10 + - Required + - Precautions shall be taken in order to prevent the contents of a header file being included more than once + - `PRE06-C `_ + - `Dir 4.10 `_ + * - Dir 4.11 + - Required + - The validity of values passed to library functions shall be checked + - N/A + - `Dir 4.11 `_ + * - Dir 4.12 + - Required + - Dynamic memory allocation shall not be used + - `STR01-C `_ + - `Dir 4.12 `_ + * - Dir 4.13 + - Advisory + - Functions which are designed to provide operations on a resource should be called in an appropriate sequence + - N/A + - `Dir 4.13 `_ + * - Dir 4.14 + - Required + - The validity of values received from external sources shall be checked + + - N/A + - `Dir 4.14 `_ + * - Rule 1.2 + - Advisory + - Language extensions should not be used + - `MSC04-C `_ + - `Rule 1.2 `_ + * - Rule 1.3 + - Required + - There shall be no occurrence of undefined or critical unspecified behaviour + - N/A + - `Rule 1.3 `_ + * - Rule 2.1 + - Required + - A project shall not contain unreachable code + - `MSC07-C `_ + - | `Rule 2.1 example 1 `_ + | `Rule 2.1 example 2 `_ + * - Rule 2.2 + - Required + - There shall be no dead code + - `MSC12-C `_ + - `Rule 2.2 `_ + * - Rule 2.3 + - Advisory + - A project should not contain unused type declarations + - N/A + - `Rule 2.3 `_ + * - Rule 2.6 + - Advisory + - A function should not contain unused label declarations + - N/A + - `Rule 2.6 `_ + * - Rule 2.7 + - Advisory + - There should be no unused parameters in functions + - N/A + - `Rule 2.7 `_ + * - Rule 3.1 + - Required + - The character sequences /* and // shall not be used within a comment + - `MSC04-C `_ + - `Rule 3.1 `_ + * - Rule 3.2 + - Required + - Line-splicing shall not be used in // comments + - N/A + - `Rule 3.2 `_ + * - Rule 4.1 + - Required + - Octal and hexadecimal escape sequences shall be terminated + - `MSC09-C `_ + - `Rule 4.1 `_ + * - Rule 4.2 + - Advisory + - Trigraphs should not be used + - `PRE07-C `_ + - `Rule 4.2 `_ + * - Rule 5.1 + - Required + - External identifiers shall be distinct + - `DCL23-C `_ + - | `Rule 5.1 example 1 `_ + | `Rule 5.1 example 2 `_ + * - Rule 5.2 + - Required + - Identifiers declared in the same scope and name space shall be distinct + - `DCL23-C `_ + - `Rule 5.2 `_ + * - Rule 5.3 + - Required + - An identifier declared in an inner scope shall not hide an identifier declared in an outer scope + - `DCL23-C `_ + - `Rule 5.3 `_ + * - Rule 5.4 + - Required + - Macro identifiers shall be distinct + - `DCL23-C `_ + - `Rule 5.4 `_ + * - Rule 5.5 + - Required + - Identifiers shall be distinct from macro names + - `DCL23-C `_ + - `Rule 5.5 `_ + * - Rule 5.6 + - Required + - A typedef name shall be a unique identifier + - N/A + - `Rule 5.6 `_ + * - Rule 5.7 + - Required + - A tag name shall be a unique identifier + - N/A + - `Rule 5.7 `_ + * - Rule 5.8 + - Required + - Identifiers that define objects or functions with external linkage shall be unique + - N/A + - | `Rule 5.8 example 1 `_ + | `Rule 5.8 example 2 `_ + * - Rule 5.9 + - Advisory + - Identifiers that define objects or functions with internal linkage should be unique + - N/A + - | `Rule 5.9 example 1 `_ + | `Rule 5.9 example 2 `_ + * - Rule 6.1 + - Required + - Bit-fields shall only be declared with an appropriate type + - `INT14-C `_ + - `Rule 6.1 `_ + * - Rule 6.2 + - Required + - Single-bit named bit fields shall not be of a signed type + - `INT14-C `_ + - `Rule 6.2 `_ + * - Rule 7.1 + - Required + - Octal constants shall not be used + - `DCL18-C `_ + - `Rule 7.1 `_ + * - Rule 7.2 + - Required + - A u or U suffix shall be applied to all integer constants that are represented in an unsigned type + - N/A + - `Rule 7.2 `_ + * - Rule 7.3 + - Required + - The lowercase character l shall not be used in a literal suffix + - `DCL16-C `_ + - `Rule 7.3 `_ + * - Rule 7.4 + - Required + - A string literal shall not be assigned to an object unless the objects type is pointer to const-qualified char + - N/A + - `Rule 7.4 `_ + * - Rule 8.1 + - Required + - Types shall be explicitly specified + - N/A + - `Rule 8.1 `_ + * - Rule 8.2 + - Required + - Function types shall be in prototype form with named parameters + - `DCL20-C `_ + - `Rule 8.2 `_ + * - Rule 8.3 + - Required + - All declarations of an object or function shall use the same names and type qualifiers + - N/A + - `Rule 8.3 `_ + * - Rule 8.4 + - Required + - A compatible declaration shall be visible when an object or function with external linkage is defined + - N/A + - `Rule 8.4 `_ + * - Rule 8.5 + - Required + - An external object or function shall be declared once in one and only one file + - N/A + - | `Rule 8.5 example 1 `_ + | `Rule 8.5 example 2 `_ + * - Rule 8.6 + - Required + - An identifier with external linkage shall have exactly one external definition + - N/A + - | `Rule 8.6 example 1 `_ + | `Rule 8.6 example 2 `_ + * - Rule 8.8 + - Required + - The static storage class specifier shall be used in all declarations of objects and functions that have internal linkage + - `DCL15-C `_ + - `Rule 8.8 `_ + * - Rule 8.9 + - Advisory + - An object should be defined at block scope if its identifier only appears in a single function + - `DCL19-C `_ + - `Rule 8.9 `_ + * - Rule 8.10 + - Required + - An inline function shall be declared with the static storage class + - N/A + - `Rule 8.10 `_ + * - Rule 8.12 + - Required + - Within an enumerator list, the value of an implicitly-specified enumeration constant shall be unique + - `INT09-C `_ + - `Rule 8.12 `_ + * - Rule 8.14 + - Required + - The restrict type qualifier shall not be used + - N/A + - `Rule 8.14 `_ + * - Rule 9.1 + - Mandatory + - The value of an object with automatic storage duration shall not be read before it has been set + - N/A + - `Rule 9.1 `_ + * - Rule 9.2 + - Required + - The initializer for an aggregate or union shall be enclosed in braces + - N/A + - `Rule 9.2 `_ + * - Rule 9.3 + - Required + - Arrays shall not be partially initialized + - N/A + - `Rule 9.3 `_ + * - Rule 9.4 + - Required + - An element of an object shall not be initialized more than once + - N/A + - `Rule 9.4 `_ + * - Rule 9.5 + - Required + - Where designated initializers are used to initialize an array object the size of the array shall be specified explicitly + - N/A + - `Rule 9.5 `_ + * - Rule 10.1 + - Required + - Operands shall not be of an inappropriate essential type + - `STR04-C `_ + - `Rule 10.1 `_ + * - Rule 10.2 + - Required + - Expressions of essentially character type shall not be used inappropriately in addition and subtraction operations + - `STR04-C `_ + - `Rule 10.2 `_ + * - Rule 10.3 + - Required + - The value of an expression shall not be assigned to an object with a narrower essential type or of a dierent essential type category + - `STR04-C `_ + - `Rule 10.3 `_ + * - Rule 10.4 + - Required + - Both operands of an operator in which the usual arithmetic conversions are performed shall have the same essential type category + - `STR04-C `_ + - `Rule 10.4 `_ + * - Rule 10.5 + - Advisory + - The value of an expression should not be cast to an inappropriate essential type + - N/A + - `Rule 10.5 `_ + * - Rule 10.6 + - Required + - The value of a composite expression shall not be assigned to an object with wider essential type + - `INT02-C `_ + - `Rule 10.6 `_ + * - Rule 10.7 + - Required + - If a composite expression is used as one operand of an operator in which the usual arithmetic conversions are performed then the other operand shall not have wider essential type + - `INT02-C `_ + - `Rule 10.7 `_ + * - Rule 10.8 + - Required + - The value of a composite expression shall not be cast to a different essential type category or a wider essential type + - `INT02-C `_ + - `Rule 10.8 `_ + * - Rule 11.2 + - Required + - Conversions shall not be performed between a pointer to an incomplete type and any other type + - N/A + - `Rule 11.2 `_ + * - Rule 11.6 + - Required + - A cast shall not be performed between pointer to void and an arithmetic type + - N/A + - `Rule 11.6 `_ + * - Rule 11.7 + - Required + - A cast shall not be performed between pointer to object and a noninteger arithmetic type + - N/A + - `Rule 11.7 `_ + * - Rule 11.8 + - Required + - A cast shall not remove any const or volatile qualification from the type pointed to by a pointer + - `EXP05-C `_ + - `Rule 11.8 `_ + * - Rule 11.9 + - Required + - The macro NULL shall be the only permitted form of integer null pointer constant + - N/A + - `Rule 11.9 `_ + * - Rule 12.1 + - Advisory + - The precedence of operators within expressions should be made explicit + - `EXP00-C `_ + - `Rule 12.1 `_ + * - Rule 12.2 + - Required + - The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand + - N/A + - `Rule 12.2 `_ + * - Rule 12.4 + - Advisory + - Evaluation of constant expressions should not lead to unsigned integer wrap-around + - N/A + - `Rule 12.4 `_ + * - Rule 12.5 + - Mandatory + - The sizeof operator shall not have an operand which is a function parameter declared as “array of type” + - N/A + - `Rule 12.5 `_ + * - Rule 13.1 + - Required + - Initializer lists shall not contain persistent side effects + - N/A + - | `Rule 13.1 example 1 `_ + | `Rule 13.1 example 2 `_ + * - Rule 13.2 + - Required + - The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders + - N/A + - `Rule 13.2 `_ + * - Rule 13.3 + - Advisory + - A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that caused by the increment or decrement operator + - N/A + - `Rule 13.3 `_ + * - Rule 13.4 + - Advisory + - The result of an assignment operator should not be used + - N/A + - `Rule 13.4 `_ + * - Rule 13.5 + - Required + - The right hand operand of a logical && or || operator shall not contain persistent side effects + - `EXP10-C `_ + - | `Rule 13.5 example 1 `_ + | `Rule 13.5 example 2 `_ + * - Rule 13.6 + - Mandatory + - The operand of the sizeof operator shall not contain any expression which has potential side effects + - N/A + - `Rule 13.6 `_ + * - Rule 14.1 + - Required + - A loop counter shall not have essentially floating type + - N/A + - `Rule 14.1 `_ + * - Rule 14.2 + - Required + - A for loop shall be well-formed + - N/A + - `Rule 14.2 `_ + * - Rule 14.3 + - Required + - Controlling expressions shall not be invariant + - N/A + - `Rule 14.3 `_ + * - Rule 14.4 + - Required + - The controlling expression of an if statement and the controlling expression of an iteration-statement shall have essentially Boolean type + - N/A + - `Rule 14.4 `_ + * - Rule 15.2 + - Required + - The goto statement shall jump to a label declared later in the same function + - N/A + - `Rule 15.2 `_ + * - Rule 15.3 + - Required + - Any label referenced by a goto statement shall be declared in the same block, or in any block enclosing the goto statement + - N/A + - `Rule 15.3 `_ + * - Rule 15.6 + - Required + - The body of an iteration-statement or a selection-statement shall be a compound-statement + - `EXP19-C `_ + - `Rule 15.6 `_ + * - Rule 15.7 + - Required + - All if else if constructs shall be terminated with an else statement + - N/A + - `Rule 15.7 `_ + * - Rule 16.1 + - Required + - All switch statements shall be well-formed + - N/A + - `Rule 16.1 `_ + * - Rule 16.2 + - Required + - A switch label shall only be used when the most closely-enclosing compound statement is the body of a switch statement + - `MSC20-C `_ + - `Rule 16.2 `_ + * - Rule 16.3 + - Required + - An unconditional break statement shall terminate every switch-clause + - N/A + - `Rule 16.3 `_ + * - Rule 16.4 + - Required + - Every switch statement shall have a default label + - N/A + - `Rule 16.4 `_ + * - Rule 16.5 + - Required + - A default label shall appear as either the first or the last switch label of a switch statement + - N/A + - `Rule 16.5 `_ + * - Rule 16.6 + - Required + - Every switch statement shall have at least two switch-clauses + - N/A + - `Rule 16.6 `_ + * - Rule 16.7 + - Required + - A switch-expression shall not have essentially Boolean type + - N/A + - `Rule 16.7 `_ + * - Rule 17.1 + - Required + - The features of shall not be used + - `ERR00-C `_ + - `Rule 17.1 `_ + * - Rule 17.2 + - Required + - Functions shall not call themselves, either directly or indirectly + - `MEM05-C `_ + - `Rule 17.2 `_ + * - Rule 17.3 + - Mandatory + - A function shall not be declared implicitly + - N/A + - `Rule 17.3 `_ + * - Rule 17.4 + - Mandatory + - All exit paths from a function with non-void return type shall have an explicit return statement with an expression + - N/A + - `Rule 17.4 `_ + * - Rule 17.5 + - Advisory + - The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements + - N/A + - `Rule 17.5 `_ + * - Rule 17.6 + - Mandatory + - The declaration of an array parameter shall not contain the static keyword between the [ ] + - N/A + - `Rule 17.6 `_ + * - Rule 17.7 + - Required + - The value returned by a function having non-void return type shall be used + - N/A + - `Rule 17.7 `_ + * - Rule 18.1 + - Required + - A pointer resulting from arithmetic on a pointer operand shall address an element of the same array as that pointer operand + - `EXP08-C `_ + - `Rule 18.1 `_ + * - Rule 18.2 + - Required + - Subtraction between pointers shall only be applied to pointers that address elements of the same array + - `EXP08-C `_ + - `Rule 18.2 `_ + * - Rule 18.3 + - Required + - The relational operators >, >=, < and <= shall not be applied to objects of pointer type except where they point into the same object + - `EXP08-C `_ + - `Rule 18.3 `_ + * - Rule 18.5 + - Advisory + - Declarations should contain no more than two levels of pointer nesting + - N/A + - `Rule 18.5 `_ + * - Rule 18.6 + - Required + - The address of an object with automatic storage shall not be copied to another object that persists after the first object has ceased to exist + - N/A + - | `Rule 18.6 example 1 `_ + | `Rule 18.6 example 2 `_ + * - Rule 18.8 + - Required + - Variable-length array types shall not be used + - N/A + - `Rule 18.8 `_ + * - Rule 19.1 + - Mandatory + - An object shall not be assigned or copied to an overlapping object + - N/A + - `Rule 19.1 `_ + * - Rule 20.2 + - Required + - The ', or \ characters and the /* or // character sequences shall not occur in a header file name" + - N/A + - `Rule 20.2 `_ + * - Rule 20.3 + - Required + - The #include directive shall be followed by either a or "filename" sequence + - N/A + - `Rule 20.3 `_ + * - Rule 20.4 + - Required + - A macro shall not be defined with the same name as a keyword + - N/A + - `Rule 20.4 `_ + * - Rule 20.7 + - Required + - Expressions resulting from the expansion of macro parameters shall be enclosed in parentheses + - `PRE01-C `_ + - `Rule 20.7 `_ + * - Rule 20.8 + - Required + - The controlling expression of a #if or #elif preprocessing directive shall evaluate to 0 or 1 + - N/A + - `Rule 20.8 `_ + * - Rule 20.9 + - Required + - All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be #defined before evaluation + - N/A + - `Rule 20.9 `_ + * - Rule 20.11 + - Required + - A macro parameter immediately following a # operator shall not immediately be followed by a ## operator + - N/A + - `Rule 20.11 `_ + * - Rule 20.12 + - Required + - A macro parameter used as an operand to the # or ## operators, which is itself subject to further macro replacement, shall only be used as an operand to these operators + - N/A + - `Rule 20.12 `_ + * - Rule 20.13 + - Required + - A line whose first token is # shall be a valid preprocessing directive + - N/A + - `Rule 20.13 `_ + * - Rule 20.14 + - Required + - All #else, #elif and #endif preprocessor directives shall reside in the same file as the #if, #ifdef or #ifndef directive to which they are related + - N/A + - `Rule 20.14 `_ + * - Rule 21.1 + - Required + - #define and #undef shall not be used on a reserved identifier or reserved macro name + - N/A + - `Rule 21.1 `_ + * - Rule 21.2 + - Required + - A reserved identifier or macro name shall not be declared + - N/A + - `Rule 21.2 `_ + * - Rule 21.3 + - Required + - The memory allocation and deallocation functions of shall not be used + - `MSC24-C `_ + - `Rule 21.3 `_ + * - Rule 21.4 + - Required + - The standard header file shall not be used + - N/A + - `Rule 21.4 `_ + * - Rule 21.6 + - Required + - The Standard Library input/output functions shall not be used + - N/A + - `Rule 21.6 `_ + * - Rule 21.7 + - Required + - The atof, atoi, atol and atoll functions of shall not be used + - N/A + - `Rule 21.7 `_ + * - Rule 21.9 + - Required + - The library functions bsearch and qsort of shall not be used + - N/A + - `Rule 21.9 `_ + * - Rule 22.1 + - Required + - All resources obtained dynamically by means of Standard Library functions shall be explicitly released + - N/A + - `Rule 22.1 `_ + * - Rule 22.3 + - Required + - The same file shall not be open for read and write access at the same time on different streams + - N/A + - `Rule 22.3 `_ + * - Rule 22.4 + - Mandatory + - There shall be no attempt to write to a stream which has been opened as read-only + - N/A + - `Rule 22.4 `_ + * - Rule 22.5 + - Mandatory + - A pointer to a FILE object shall not be dereferenced + - N/A + - `Rule 22.5 `_ + * - Rule 22.6 + - Mandatory + - The value of a pointer to a FILE shall not be used after the associated stream has been closed + - N/A + - `Rule 22.6 `_ + * - Rule 22.7 + - Required + - The macro EOF shall only be compared with the unmodified return value from any Standard Library function capable of returning EOF + - N/A + - `Rule 22.7 `_ + * - Rule 22.8 + - Required + - The value of errno shall be set to zero prior to a call to an errno-setting-function + - N/A + - `Rule 22.8 `_ + * - Rule 22.9 + - Required + - The value of errno shall be tested against zero after calling an errno-setting-function + - N/A + - `Rule 22.9 `_ + * - Rule 22.10 + - Required + - The value of errno shall only be tested when the last function to be called was an errno-setting-function + - N/A + - `Rule 22.10 `_ + * - Rule 21.11 + - Required + - The standard header file shall not be used + - N/A + - `Rule 21.11 `_ + * - Rule 21.12 + - Advisory + - The exception handling features of should not be used + - N/A + - `Rule 21.12 `_ + * - Rule 21.13 + - Mandatory + - Any value passed to a function in shall be representable as an unsigned char or be the value EO + - N/A + - `Rule 21.13 `_ + * - Rule 21.14 + - Required + - The Standard Library function memcmp shall not be used to compare null terminated strings + - N/A + - `Rule 21.14 `_ + * - Rule 21.15 + - Required + - The pointer arguments to the Standard Library functions memcpy, memmove and memcmp shall be pointers to qualified or unqualified versions of compatible types + - N/A + - `Rule 21.15 `_ + * - Rule 21.16 + - Required + - The pointer arguments to the Standard Library function memcmp shall point to either a pointer type, an essentially signed type, an essentially unsigned type, an essentially Boolean type or an essentially enum type + - N/A + - `Rule 21.16 `_ + * - Rule 21.17 + - Mandatory + - Use of the string handling functions from shall not result in accesses beyond the bounds of the objects referenced by their pointer parameters + - N/A + - `Rule 21.17 `_ + * - Rule 21.18 + - Mandatory + - The size_t argument passed to any function in shall have an appropriate value + - N/A + - `Rule 21.18 `_ + * - Rule 21.20 + - Mandatory + - The pointer returned by the Standard Library functions asctime, ctime, gmtime, localtime, localeconv, getenv, setlocale or strerror shall not be used following a subsequent call to the same function + - N/A + - `Rule 21.20 `_ + +Additional rules +**************** + +Rule A.1: Conditional Compilation +================================= + +Severity +-------- + +Required + +Description +----------- + +Do not conditionally compile function declarations in header files. Do not +conditionally compile structure declarations in header files. You may +conditionally exclude fields within structure definitions to avoid wasting +memory when the feature they support is not enabled. + +Rationale +--------- + +Excluding declarations from the header based on compile-time options may prevent +their documentation from being generated. Their absence also prevents use of +``if (IS_ENABLED(CONFIG_FOO)) {}`` as an alternative to preprocessor +conditionals when the code path should change based on the selected options. diff --git a/doc/guides/coverage.rst b/doc/guides/coverage.rst index f786a461fc9c53..c54ef0be3c7f15 100644 --- a/doc/guides/coverage.rst +++ b/doc/guides/coverage.rst @@ -132,19 +132,26 @@ You may postprocess these with your preferred tools. For example: Sanitycheck coverage reports **************************** -Zephyr's :ref:`sanitycheck script ` can automatically +Zephyr's :ref:`twister script ` can automatically generate a coverage report from the tests which were executed. You just need to invoke it with the ``--coverage`` command line option. For example, you may invoke:: - $ sanitycheck --coverage -p qemu_x86 -T tests/kernel + $ twister --coverage -p qemu_x86 -T tests/kernel or:: - $ sanitycheck --coverage -p native_posix -T tests/bluetooth + $ twister --coverage -p native_posix -T tests/bluetooth -which will produce ``sanity-out/coverage/index.html`` with the report. +which will produce ``twister-out/coverage/index.html`` with the report. + +The process differs for unit tests, which are built with the host +toolchain and require a different board:: + + $ twister --coverage -p unit_testing -T tests/unit + +which produces a report in the same location as non-unit testing. .. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html diff --git a/doc/guides/debugging/host-tools.rst b/doc/guides/debugging/host-tools.rst deleted file mode 100644 index 3fa7fa00d7e75f..00000000000000 --- a/doc/guides/debugging/host-tools.rst +++ /dev/null @@ -1,104 +0,0 @@ -.. _debug-host-tools: - -Debug Host Tools -################ - -This guide describes the software tools you can run on your host workstation to -debug Zephyr applications. - -Zephyr's west tool has built-in support for all of these in its ``debug``, -``debugserver``, and ``attach`` commands, provided your board hardware supports -them and your Zephyr board directory's :file:`board.cmake` file declares that -support properly. See :ref:`west-build-flash-debug` for more information on -these commands. - -.. _jlink-debug-host-tools: - -J-Link Debug Host Tools -*********************** - -Segger provides a suite of debug host tools for Linux, macOS, and Windows -operating systems: - -- J-Link GDB Server: GDB remote debugging -- J-Link Commander: Command-line control and flash programming -- RTT Viewer: RTT terminal input and output -- SystemView: Real-time event visualization and recording - -These debug host tools are compatible with the following debug probes: - -- :ref:`lpclink2-jlink-onboard-debug-probe` -- :ref:`opensda-jlink-onboard-debug-probe` -- :ref:`jlink-external-debug-probe` -- :ref:`stlink-v21-onboard-debug-probe` - -Check if your SoC is listed in `J-Link Supported Devices`_. - -Download and install the `J-Link Software and Documentation Pack`_ to get the -J-Link GDB Server and Commander, and to install the associated USB device -drivers. RTT Viewer and SystemView can be downloaded separately, but are not -required. - -Note that the J-Link GDB server does not yet support Zephyr RTOS-awareness. - -.. _openocd-debug-host-tools: - -OpenOCD Debug Host Tools -************************ - -OpenOCD is a community open source project that provides GDB remote debugging -and flash programming support for a wide range of SoCs. A fork that adds Zephyr -RTOS-awareness is included in the Zephyr SDK; otherwise see `Getting OpenOCD`_ -for options to download OpenOCD from official repositories. - -These debug host tools are compatible with the following debug probes: - -- :ref:`opensda-daplink-onboard-debug-probe` -- :ref:`jlink-external-debug-probe` -- :ref:`stlink-v21-onboard-debug-probe` - -Check if your SoC is listed in `OpenOCD Supported Devices`_. - -.. note:: On Linux, openocd is available though the `Zephyr SDK - `_. - Windows users should use the following steps to install - openocd: - - - Download openocd for Windows from here: `OpenOCD Windows`_ - - Copy bin and share dirs to ``C:\Program Files\OpenOCD\`` - - Add ``C:\Program Files\OpenOCD\bin`` to 'Path' - -.. _pyocd-debug-host-tools: - -pyOCD Debug Host Tools -********************** - -pyOCD is an open source project from Arm that provides GDB remote debugging and -flash programming support for Arm Cortex-M SoCs. It is distributed on PyPi and -installed when you complete the :ref:`gs_python_deps` step in the Getting -Started Guide. pyOCD includes support for Zephyr RTOS-awareness. - -These debug host tools are compatible with the following debug probes: - -- :ref:`opensda-daplink-onboard-debug-probe` -- :ref:`stlink-v21-onboard-debug-probe` - -Check if your SoC is listed in `pyOCD Supported Devices`_. - -.. _J-Link Software and Documentation Pack: - https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack - -.. _J-Link Supported Devices: - https://www.segger.com/downloads/supported-devices.php - -.. _Getting OpenOCD: - http://openocd.org/getting-openocd/ - -.. _OpenOCD Supported Devices: - https://github.com/zephyrproject-rtos/openocd/tree/master/tcl/target - -.. _pyOCD Supported Devices: - https://github.com/mbedmicro/pyOCD/tree/master/pyocd/target/builtin - -.. _OpenOCD Windows: - http://gnutoolchains.com/arm-eabi/openocd/ diff --git a/doc/guides/debugging/index.rst b/doc/guides/debugging/index.rst deleted file mode 100644 index fae592c51aecea..00000000000000 --- a/doc/guides/debugging/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. _debugging: - -Debugging -######### - -.. toctree:: - :maxdepth: 1 - - host-tools.rst - probes.rst - thread-analyzer.rst diff --git a/doc/guides/design_guidelines.rst b/doc/guides/design_guidelines.rst new file mode 100644 index 00000000000000..42413b48269b45 --- /dev/null +++ b/doc/guides/design_guidelines.rst @@ -0,0 +1,103 @@ +.. _design_guidelines: + +API Design Guidelines +##################### + +Zephyr development and evolution is a group effort, and to simplify +maintenance and enhancements there are some general policies that should +be followed when developing a new capability or interface. + +Using Callbacks +*************** + +Many APIs involve passing a callback as a parameter or as a member of a +configuration structure. The following policies should be followed when +specifying the signature of a callback: + +* The first parameter should be a pointer to the object most closely + associated with the callback. In the case of device drivers this + would be ``struct device *dev``. For library functions it may be a + pointer to another object that was referenced when the callback was + provided. + +* The next parameter(s) should be additional information specific to the + callback invocation, such as a channel identifier, new status value, + and/or a message pointer followed by the message length. + +* The final parameter should be a ``void *user_data`` pointer carrying + context that allows a shared callback function to locate additional + material necessary to process the callback. + +An exception to providing ``user_data`` as the last parameter may be +allowed when the callback itself was provided through a structure that +will be embedded in another structure. An example of such a case is +:c:type:`gpio_callback`, normally defined within a data structure +specific to the code that also defines the callback function. In those +cases further context can accessed by the callback indirectly by +:c:macro:`CONTAINER_OF`. + +Examples +======== + +* The requirements of :c:type:`k_timer_expiry_t` invoked when a system + timer alarm fires are satisfied by:: + + void handle_timeout(struct k_timer *timer) + { ... } + + The assumption here, as with :c:type:`gpio_callback`, is that the + timer is embedded in a structure reachable from + :c:macro:`CONTAINER_OF` that can provide additional context to the + callback. + +* The requirements of :c:type:`counter_alarm_callback_t` invoked when a + counter device alarm fires are satisfied by:: + + void handle_alarm(const struct device *dev, + uint8_t chan_id, + uint32_t ticks, + void *user_data) + { ... } + + This provides more complete useful information, including which + counter channel timed-out and the counter value at which the timeout + occurred, as well as user context which may or may not be the + :c:type:`counter_alarm_cfg` used to register the callback, depending + on user needs. + +Conditional Data and APIs +************************* + +APIs and libraries may provide features that are expensive in RAM or +code size but are optional in the sense that some applications can be +implemented without them. Examples of such feature include +:option:`capturing a timestamp ` or +:option:`providing an alternative interface `. The +developer in coordination with the community must determine whether +enabling the features is to be controllable through a Kconfig option. + +In the case where a feature is determined to be optional the following +practices should be followed. + +* Any data that is accessed only when the feature is enabled should be + conditionally included via ``#ifdef CONFIG_MYFEATURE`` in the + structure or union declaration. This reduces memory use for + applications that don't need the capability. +* Function declarations that are available only when the option is + enabled should be provided unconditionally. Add a note in the + description that the function is available only when the specified + feature is enabled, referencing the required Kconfig symbol by name. + (In cases where the function is used but not enabled a link-time error + will be generated.) +* Where code specific to the feature is isolated in a source file that + has no other content that file should be conditionally included in + ``CMakeLists.txt``:: + + zephyr_sources_ifdef(CONFIG_MYFEATURE foo_funcs.c) +* Where code specific to the feature is part of a source file that has + other content the feature-specific code should be conditionally + processed using ``#ifdef CONFIG_MYFEATURE``. + +The Kconfig flag used to enable the feature should be added to the +``PREDEFINED`` variable in :file:`doc/zephyr.doxyfile.in` to ensure the +conditional API and functions appear in generated documentation. diff --git a/doc/guides/device_mgmt/dfu.rst b/doc/guides/device_mgmt/dfu.rst index 015b26f508ea79..732c187520e50f 100644 --- a/doc/guides/device_mgmt/dfu.rst +++ b/doc/guides/device_mgmt/dfu.rst @@ -34,8 +34,8 @@ is the boot loader used with Zephyr. The source code itself is hosted in the In order to use MCUboot with Zephyr you need to take the following into account: -1. You will need to define the :ref:`mcuboot_partitions` required by MCUboot in - the :ref:`legacy_flash_partitions`. +1. You will need to define the flash partitions required by MCUboot; see + :ref:`flash_map_api` for details. 2. Your application's :file:`.conf` file needs to enable the :option:`CONFIG_BOOTLOADER_MCUBOOT` Kconfig option in order for Zephyr to be built in an MCUboot-compatible manner diff --git a/doc/guides/device_mgmt/index.rst b/doc/guides/device_mgmt/index.rst index 47000445be8051..c0cab6f8b892dc 100644 --- a/doc/guides/device_mgmt/index.rst +++ b/doc/guides/device_mgmt/index.rst @@ -13,6 +13,7 @@ The following management operations are available: * File System management * Log management (currently disabled) * OS management +* Shell management over the following transports: diff --git a/doc/guides/documentation/index.rst b/doc/guides/documentation/index.rst index df2f4b13361cc2..3fe58172162394 100644 --- a/doc/guides/documentation/index.rst +++ b/doc/guides/documentation/index.rst @@ -398,10 +398,10 @@ For example:: struct z_object { char *name; - u8_t perms[CONFIG_MAX_THREAD_BYTES]; - u8_t type; - u8_t flags; - u32_t data; + uint8_t perms[CONFIG_MAX_THREAD_BYTES]; + uint8_t type; + uint8_t flags; + uint32_t data; } __packed; Note the blank line between the ``code-block`` directive and the first @@ -414,10 +414,10 @@ This would be rendered as: struct z_object { char *name; - u8_t perms[CONFIG_MAX_THREAD_BYTES]; - u8_t type; - u8_t flags; - u32_t data; + uint8_t perms[CONFIG_MAX_THREAD_BYTES]; + uint8_t type; + uint8_t flags; + uint32_t data; } __packed; diff --git a/doc/guides/dts/api-usage.rst b/doc/guides/dts/api-usage.rst index ea4ed3e24c75b5..5756b086b819e2 100644 --- a/doc/guides/dts/api-usage.rst +++ b/doc/guides/dts/api-usage.rst @@ -5,8 +5,8 @@ Devicetree access from C/C++ This guide describes Zephyr's ```` API for reading the devicetree from C source files. It assumes you're familiar with the concepts in -:ref:`devicetree-intro` and :ref:`dt-bindings`. See :ref:`devicetree_api` for -API reference documentation. +:ref:`devicetree-intro` and :ref:`dt-bindings`. See :ref:`devicetree` for +reference material. A note for Linux developers *************************** @@ -303,8 +303,9 @@ See :ref:`dt-get-device` for ways to do that. Another common use case is accessing specifier values in a phandle array. The general purpose APIs for this are :c:func:`DT_PHA_BY_IDX` and :c:func:`DT_PHA`. -There are also hardware-specific shorthands like :c:func:`DT_GPIO_LABEL_BY_IDX`, -:c:func:`DT_GPIO_LABEL`, :c:func:`DT_GPIO_PIN_BY_IDX`, :c:func:`DT_GPIO_PIN`, +There are also hardware-specific shorthands like :c:func:`DT_GPIO_CTLR_BY_IDX`, +:c:func:`DT_GPIO_CTLR`, :c:func:`DT_GPIO_LABEL_BY_IDX`, :c:func:`DT_GPIO_LABEL`, +:c:func:`DT_GPIO_PIN_BY_IDX`, :c:func:`DT_GPIO_PIN`, :c:func:`DT_GPIO_FLAGS_BY_IDX`, and :c:func:`DT_GPIO_FLAGS`. See :c:func:`DT_PHA_HAS_CELL_AT_IDX` and :c:func:`DT_PROP_HAS_IDX` for ways to diff --git a/doc/guides/dts/bindings.rst b/doc/guides/dts/bindings.rst index c718e7a31d605d..94e06c6079ca7b 100644 --- a/doc/guides/dts/bindings.rst +++ b/doc/guides/dts/bindings.rst @@ -11,8 +11,9 @@ particular devicetree are useful to :ref:`device drivers ` or *Devicetree bindings* provide the other half of this information. Zephyr devicetree bindings are YAML files in a custom format (Zephyr does not use the -dt-schema tools used by the Linux kernel). The build system uses bindings -when generating code for :ref:`dt-from-c`. +dt-schema tools used by the Linux kernel). With one exception in +:ref:`dt-inferred-bindings` the build system uses bindings when generating +code for :ref:`dt-from-c`. .. _dt-binding-compat: @@ -74,80 +75,31 @@ Below is a template that shows the Zephyr bindings file syntax. It is stored in .. literalinclude:: ../../../dts/binding-template.yaml :language: yaml -.. _legacy_binding_syntax: +.. _dt-inferred-bindings: -Legacy bindings syntax -********************** +Inferred bindings +***************** -The bindings syntax described above was introduced in the Zephyr 2.1 release. -This section describes how to update bindings written in the legacy syntax, -starting with this example written in the legacy syntax. +For sample code and applications it can be inconvenient to define a devicetree +binding when only a few simple properties are needed, such as the identify of +a GPIO for an application task. The devicetree syntax allows inference of a +binding for properties based on the value observed. This inference is +supported only for the ``/zephyr,user`` node. The properties referenced can +be accessed through the standard devicetree macros, +e.g. ``DT_PROP(DT_PATH(zephyr_user), bytes)``. -.. code-block:: yaml - - title: ... - description: ... - - inherits: - !include foo.yaml - - parent: - bus: spi - - parent-bus: spi - - properties: - compatible: - constraint: "company,device" - type: string-array - - frequency: - type: int - category: optional - - sub-node: - properties: - child-prop: - type: int - category: required - - # Assume this is a binding for an interrupt controller - "#cells": - - irq - - priority - - flags - -This should now be written like this: - -.. code-block:: yaml - - description: ... - - compatible: "company,device" - - include: foo.yaml - - bus: spi - - properties: - frequency: - type: int - required: false - - child-binding: - description: ... - - properties: - child-prop: - type: int - required: true - - interrupt-cells: - - irq - - priority - - cells +.. code-block:: DTS -The legacy syntax is still supported for backwards compatibility, but generates -deprecation warnings. Support for the legacy bindings syntax was originally -scheduled to be dropped in the Zephyr 2.3 release, but will now be maintained -until Zephyr 2.4. + / { + zephyr,user { + boolean; + bytes = [81 82 83]; + number = <23>; + numbers = <1>, <2>, <3>; + string = "text"; + strings = "a", "b", "c"; + handle = <&gpio0>; + handles = <&gpio0>, <&gpio1>; + signal-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + }; + }; diff --git a/doc/guides/dts/design.rst b/doc/guides/dts/design.rst index 5330e2894c3c16..7ae33f66cefbe1 100644 --- a/doc/guides/dts/design.rst +++ b/doc/guides/dts/design.rst @@ -24,10 +24,12 @@ Examples used in the current build. For example, the :ref:`blinky-sample` uses this to determine the LED to blink. +- Boot-time pin muxing and pin control can be accomplished via devicetree. + Example remaining work ====================== -- Zephyr's :ref:`sanitycheck_script` currently use :file:`board.yaml` files to +- Zephyr's :ref:`twister_script` currently use :file:`board.yaml` files to determine the hardware supported by a board. This should be obtained from devicetree instead. @@ -42,9 +44,6 @@ Example remaining work - Runtime determination of ``struct device`` relationships should be done using information obtained from devicetree, e.g. for device power management. -- Pin muxing and pin control, at least at boot time, should be accomplished via - devicetree. - Source compatibility with other operating systems ************************************************* @@ -82,10 +81,3 @@ Example remaining work set of bindings supported by Linux. - Devicetree source sharing between Zephyr and Linux is not done. - -To be determined -**************** - -The scope and amount of code generation for device instantiation has been the -subject of extended discussion and prototyping without reaching a firm -conclusion. diff --git a/doc/guides/dts/dt-vs-kconfig.rst b/doc/guides/dts/dt-vs-kconfig.rst index d83f05824ed370..80fea425e15f34 100644 --- a/doc/guides/dts/dt-vs-kconfig.rst +++ b/doc/guides/dts/dt-vs-kconfig.rst @@ -45,11 +45,21 @@ supporting both the Bluetooth Low Energy and 802.15.4 wireless technologies. * Kconfig should determine which **software features** should be built for the radio, such as selecting a BLE or 802.15.4 protocol stack. -There are two noteworthy **exceptions** to these rules: +As another example, Kconfig options that formerly enabled a particular +instance of a driver (that is itself enabled by Kconfig) have been +removed. The devices are selected individually using devicetree's +:ref:`status ` keyword on the corresponding hardware +instance. +There are **exceptions** to these rules: + +* Because Kconfig is unable to flexibly control some instance-specific driver + configuration parameters, such as the size of an internal buffer, these + options may be defined in devicetree. However, to make clear that they are + specific to Zephyr drivers and not hardware description or configuration these + properties should be prefixed with ``zephyr,``, + e.g. ``zephyr,random-mac-address`` in the common Ethernet devicetree + properties. * Devicetree's ``chosen`` keyword, which allows the user to select a specific instance of a hardware device to be used for a particular purpose. An example of this is selecting a particular UART for use as the system's console. -* Devicetree's ``status`` keyword, which allows the user to enable or disable a - particular instance of a hardware device. This takes precedence over related - Kconfig options which serve a similar purpose. diff --git a/doc/guides/dts/howtos.rst b/doc/guides/dts/howtos.rst index 33d4175adc44e1..b2ca1e8d17b311 100644 --- a/doc/guides/dts/howtos.rst +++ b/doc/guides/dts/howtos.rst @@ -177,7 +177,7 @@ are included in that order by the C preprocessor. Here are some ways to set it: 1. on the cmake build command line - (``-DDTC_OVERLAY_FILE=file1.overlay;file2.overlay``) + (``-DDTC_OVERLAY_FILE="file1.overlay;file2.overlay"``) #. with the CMake ``set()`` command in the application ``CMakeLists.txt``, before including zephyr's :file:`boilerplate.cmake` file #. using a ``DTC_OVERLAY_FILE`` environment variable (deprecated) @@ -370,13 +370,13 @@ device-specific configuration and data structures and API functions, like this: /* per-device values to store in RAM */ }; struct my_dev_cfg { - u32_t freq; /* Just an example: initial clock frequency in Hz */ + uint32_t freq; /* Just an example: initial clock frequency in Hz */ /* other configuration to store in ROM */ }; /* Implement driver API functions (drivers/some_api.h callbacks): */ - static int my_driver_api_func1(struct device *dev, u32_t *foo) { /* ... */ } - static int my_driver_api_func2(struct device *dev, u64_t bar) { /* ... */ } + static int my_driver_api_func1(const struct device *dev, uint32_t *foo) { /* ... */ } + static int my_driver_api_func2(const struct device *dev, uint64_t bar) { /* ... */ } static struct some_api my_api_funcs = { .func1 = my_driver_api_func1, .func2 = my_driver_api_func2, @@ -566,218 +566,6 @@ done in the :ref:`blinky-sample`. The application can then be configured in :ref:`BOARD.dts ` files or via :ref:`devicetree overlays `. -.. _dt-migrate-legacy: - -Migrate from the legacy macros -****************************** - -This section shows how to migrate from the :ref:`dt-legacy-macros` to the -:ref:`devicetree.h API `. (Please feel free to :ref:`ask for help -` if a use case you need is missing here and existing documentation is -not enough to figure out what to do.) - -This DTS is used for examples: - -.. literalinclude:: ../../../tests/lib/devicetree/legacy_api/app.overlay - :language: DTS - :start-after: start-after-here - :end-before: end-before-here - -The following shows equivalent ways to access this devicetree, using legacy -macros and the new devicetree.h API. - -.. warning:: - - The INST numbers below were carefully chosen to work. Instance numbering - properties have changed in the devicetree.h API compared to the legacy - macros, and are not guaranteed to be the same in all cases. See - :c:func:`DT_INST` for details. - -.. code-block:: c - - /* - * label - * - * These use the label property in /migration/gpio@1000. - * They all expand to "MGR_GPIO". - */ - - /* Legacy: */ - DT_VND_GPIO_1000_LABEL - DT_INST_0_VND_GPIO_LABEL - DT_ALIAS_MGR_GPIO_LABEL - - /* Use these instead: */ - DT_LABEL(DT_PATH(migration, gpio_1000)) - DT_LABEL(DT_INST(0, vnd_gpio)) - DT_LABEL(DT_ALIAS(mgr_gpio)) - DT_LABEL(DT_NODELABEL(migration_gpio)) - - /* - * reg base addresses and sizes - * - * These use the reg property in /migration/gpio@1000. - * The base addresses all expand to 0x1000, and sizes to 0x2000. - */ - - /* Legacy addresses: */ - DT_VND_GPIO_1000_BASE_ADDRESS - DT_INST_0_VND_GPIO_BASE_ADDRESS - DT_ALIAS_MGR_GPIO_BASE_ADDRESS - - /* Use these instead: */ - DT_REG_ADDR(DT_PATH(migration, gpio_1000)) - DT_REG_ADDR(DT_INST(0, vnd_gpio)) - DT_REG_ADDR(DT_ALIAS(mgr_gpio)) - DT_REG_ADDR(DT_NODELABEL(migration_gpio)) - - /* Legacy sizes: */ - DT_VND_GPIO_1000_SIZE - DT_INST_0_VND_GPIO_SIZE - DT_ALIAS_MGR_GPIO_SIZE - - /* Use these instead: */ - DT_REG_SIZE(DT_PATH(migration, gpio_1000)) - DT_REG_SIZE(DT_INST(0, vnd_gpio)) - DT_REG_SIZE(DT_ALIAS(mgr_gpio)) - DT_REG_SIZE(DT_NODELABEL(migration_gpio)) - - /* - * interrupts IRQ numbers and priorities - * - * These use the interrupts property in /migration/gpio@1000. - * The interrupt number is 0, and the priority is 1. - */ - - /* Legacy interrupt numbers: */ - DT_VND_GPIO_1000_IRQ_0 - DT_INST_0_VND_GPIO_IRQ_0 - DT_ALIAS_MGR_GPIO_IRQ_0 - - /* Use these instead: */ - DT_IRQN(DT_PATH(migration, gpio_1000)) - DT_IRQN(DT_INST(0, vnd_gpio)) - DT_IRQN(DT_ALIAS(mgr_gpio)) - DT_IRQN(DT_NODELABEL(migration_gpio)) - - /* Legacy priorities: */ - DT_VND_GPIO_1000_IRQ_0_PRIORITY, - DT_INST_0_VND_GPIO_IRQ_0_PRIORITY, - DT_ALIAS_MGR_GPIO_IRQ_0_PRIORITY, - - /* Use these instead: */ - DT_IRQ(DT_PATH(migration, gpio_1000), priority) - DT_IRQ(DT_INST(0, vnd_gpio), priority) - DT_IRQ(DT_ALIAS(mgr_gpio), priority) - DT_IRQ(DT_NODELABEL(migration_gpio), priority) - - /* - * Other property access - * - * These use the baud-rate property in /migration/serial@3000. - * They all expand to 115200. - */ - - /* Legacy: */ - DT_VND_SERIAL_3000_BAUD_RATE - DT_ALIAS_MGR_SERIAL_BAUD_RATE - DT_INST_0_VND_SERIAL_BAUD_RATE - - /* Use these instead: */ - DT_PROP(DT_PATH(migration, serial_3000), baud_rate) - DT_PROP(DT_ALIAS(mgr_serial), baud_rate) - DT_PROP(DT_NODELABEL(migration_serial), baud_rate) - DT_PROP(DT_INST(0, vnd_serial), baud_rate) - - /* - * I2C bus controller label access for an I2C peripheral device. - * - * These are different ways to get the bus controller label property - * from the peripheral device /migration/i2c@1000/i2c-dev-10. - * - * They all expand to "MGR_I2C". - */ - - /* Legacy: */ - DT_VND_I2C_10000_VND_I2C_DEVICE_10_BUS_NAME - DT_ALIAS_MGR_I2C_DEV_BUS_NAME - DT_INST_0_VND_I2C_DEVICE_BUS_NAME - - /* Use these instead (the extra #defines are just for readability): */ - #define I2C_DEV_PATH DT_PATH(migration, i2c_10000, i2c_dev_10) - #define I2C_DEV_ALIAS DT_ALIAS(mgr_i2c_dev) - #define I2C_DEV_NODELABEL DT_NODELABEL(mgr_i2c_device) - #define I2C_DEV_INST DT_INST(0, vnd_i2c_device) - - DT_LABEL(DT_BUS(I2C_DEV_PATH)) - DT_LABEL(DT_BUS(I2C_DEV_ALIAS))) - DT_LABEL(DT_BUS(I2C_DEV_NODELABEL))) - DT_LABEL(DT_BUS(I2C_DEV_INST))) - - /* - * SPI device chip-select controller. - * - * These use /migration/spi@2000/spi-dev@0. They all expand to - * "MGR_GPIO", which is the label property of /migration/gpio@1000, - * which is the SPI device's chip select pin GPIO controller. This is - * taken from the parent node's cs-gpios property. - */ - - /* Legacy */ - DT_VND_SPI_20000_VND_SPI_DEVICE_0_CS_GPIOS_CONTROLLER - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_CONTROLLER - DT_INST_0_VND_SPI_DEVICE_CS_GPIOS_CONTROLLER - - /* Use these instead (extra #defines just for readability): */ - #define SPI_DEV_PATH DT_PATH(migration, spi_20000, migration_spi_dev_0) - #define SPI_DEV_ALIAS DT_ALIAS(mgr_spi_dev) - #define SPI_DEV_NODELABEL DT_NODELABEL(mgr_spi_device) - #define SPI_DEV_INST DT_INST(0, vnd_spi_device) - - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_PATH) - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_ALIAS) - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_NODELABEL) - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_INST) - - /* - * SPI device chip-select pin. - * - * These use /migration/spi@2000/spi-dev@0. - * They all expand to 17, which is also from cs-gpios. - */ - - /* Legacy: */ - DT_VND_SPI_20000_VND_SPI_DEVICE_0_CS_GPIOS_PIN - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_PIN - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_PIN - DT_INST_0_VND_SPI_DEVICE_CS_GPIOS_PIN - - /* Use these instead (extra #defines from above): */ - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_PATH) - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_ALIAS) - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_NODEPIN) - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_INST) - - /* - * SPI device chip-select pin's flags for the gpio.h API. - * - * These use /migration/spi@2000/spi-dev@0. They all expand to - * GPIO_ACTIVE_LOW (technically, its numeric value after - * preprocessing), which is also from cs-gpios. - */ - - /* Legacy: */ - DT_VND_SPI_20000_VND_SPI_DEVICE_0_CS_GPIOS_FLAGS - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_FLAGS - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_FLAGS - DT_INST_0_VND_SPI_DEVICE_CS_GPIOS_FLAGS - - /* Use these instead (extra #defines from above): */ - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_PATH) - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_ALIAS) - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_NODEFLAGS) - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_INST) - .. _dt-trouble: Troubleshoot devicetree issues diff --git a/doc/guides/dts/index.rst b/doc/guides/dts/index.rst index 80070a4d161d92..bc3747b6f153f6 100644 --- a/doc/guides/dts/index.rst +++ b/doc/guides/dts/index.rst @@ -3,10 +3,8 @@ Devicetree Guide ################ -This is a high-level guide to devicetree and how to use it for Zephyr -development. See :ref:`devicetree_api` for an API reference. - -.. _Devicetree specification: https://www.devicetree.org/ +This is a high-level guide to devicetree as it is used for Zephyr development. +See :ref:`devicetree` for reference material. .. toctree:: :maxdepth: 2 @@ -15,6 +13,5 @@ development. See :ref:`devicetree_api` for an API reference. design.rst bindings.rst api-usage.rst - legacy-macros.rst howtos.rst dt-vs-kconfig.rst diff --git a/doc/guides/dts/intro.rst b/doc/guides/dts/intro.rst index 9a408588bc6a7b..f40d39f5fdba1b 100644 --- a/doc/guides/dts/intro.rst +++ b/doc/guides/dts/intro.rst @@ -250,6 +250,9 @@ Fixed flash partitions Important properties ******************** +.. Documentation maintainers: If you add a property to this list, + make sure it gets linked to from gen_devicetree_rest.py too. + Some important properties are: compatible @@ -336,6 +339,8 @@ interrupts .. _Devicetree Specification release v0.3: https://www.devicetree.org/specifications/ +.. _dt-alias-chosen: + Aliases and chosen nodes ************************ @@ -514,10 +519,6 @@ These are created in your application's build directory. The generated macros and additional comments describing the devicetree. Included by ``devicetree.h``. -:file:`/zephyr/include/generated/devicetree_legacy_unfixed.h` - The generated :ref:`dt-legacy-macros`. - Included by ``devicetree.h``. - :file:`/zephyr/include/generated/devicetree_fixups.h` The concatenated contents of any :file:`dts_fixup.h` files. Included by ``devicetree.h``. diff --git a/doc/guides/dts/legacy-macros.bnf b/doc/guides/dts/legacy-macros.bnf deleted file mode 100644 index 05501d2b4bb34d..00000000000000 --- a/doc/guides/dts/legacy-macros.bnf +++ /dev/null @@ -1,106 +0,0 @@ -; dt-macro is the top level nonterminal. It defines the possible -; macros generated by gen_defines.py. -; -; A dt-macro starts with uppercase "DT_" followed by either: -; -; - a property-macro, generated for a particular node -; property -; - some other-macro, a catch-all for other types of macros, -; which contain either global information about the tree or -; are special cases -; -; This does *not* cover macros pulled out of DT via Kconfig, -; like CONFIG_SRAM_BASE_ADDRESS, etc. -dt-macro = %s"DT_" ( property-macro / other-macro ) - -; -------------------------------------------------------------------- -; A property-macro is a sequence of: -; -; - node-id: a way to identify a node -; - property-id: a way to identify one of the node's properties -; - property-suf: an optional property-specific suffix -property-macro = node-id "_" property-id ["_" property-suf] - -; A node-id is a way to refer to a node within the devicetree. -; There are a few different flavors. - -node-id = compat-unit-id / inst-id / alias-id - -compat-unit-id = [bus-id-part "_"] compat-id-part "_" unit-addr-id-part -inst-id = %s"INST_" 1*DIGIT "_" compat-id-part -alias-id = %s"ALIAS_" alias-id-part - -; Various components of a property-macro are just c-idents, -; which are made of uppercase letters, numbers, and underscores. -; -; This is a problem, because it makes it possible for different nodes -; or properties in a devicetree to generate the same macro twice -; with different values. - -bus-id-part = c-ident ; ID for information about a node's bus -compat-id-part = c-ident ; ID for a node's compatible -unit-addr-id-part = c-ident ; ID for a node's unit-address -alias-id-part = c-ident ; ID for an /aliases node property -property-id = c-ident ; ID for a node property -- this also - ; covers special cases like "reg", - ; "interrupts", and "cs-gpios" for now, - ; as they all collide with non-special - ; cases. -property-suf = c-ident ; a suffix for part of a property value, - ; like an array index or a phandle - ; specifier name converted to a c-ident - -; -------------------------------------------------------------------- -; An other-macro is a grab bag for everything that isn't a -; property-macro. It reuses some of the nonterminals (namely node-id -; and compat-id-part) defined above. -other-macro = existence-flag / bus-macro / flash-macro / chosen-macro - -existence-flag = compat-existence-flag / inst-existence-flag -compat-flag = %s"COMPAT_" c-ident -inst-flag = %s"INST_" 1*DIGIT "_" c-ident - -bus-macro = bus-name-macro / on-bus-macro -bus-name-macro = node-id %s"_BUS_NAME" -on-bus-macro = compat-id-part %s"_BUS_" bus-name -bus-name = c-ident ; a bus name ("i2c") to a DT C - ; identifier ("I2C") - -flash-macro = %s"FLASH_AREA_" node-label-ident "_" flash-suf -flash-suf = %s"ID" / %s"READ_ONLY" / (%s"OFFSET" ["_" 1*DIGIT]) / - (%s"SIZE" ["_" 1*DIGIT]) / %s"DEV" - -; Macros generated from /chosen node properties. -chosen-macro = chosen-flash / - %s"CODE_PARTITION_OFFSET" / %s"CODE_PARTITION_SIZE" / - %s"CCM_BASE_ADDRESS" / %s"CCM_SIZE" / - %s"DTCM_BASE_ADDRESS" / %s"DTCM_SIZE" / - %s"IPC_SHM_BASE_ADDRESS" / %s"IPC_SHM_SIZE" -; These come from the /chosen/zephyr,flash property. -chosen-flash = %s"FLASH_BASE_ADDRESS" / - %s"FLASH_SIZE" / - %s"FLASH_ERASE_BLOCK_SIZE" / - %s"FLASH_WRITE_BLOCK_SIZE" - -; -------------------------------------------------------------------- -; Helper definitions. - -; A c-ident is one or more: -; - uppercase letters (A-Z) -; - numbers (0-9) -; - underscores ("_") -; -; They are the result of converting names or combinations of names -; from devicetree to a valid component of a C identifier by -; uppercasing letters and converting non-alphanumeric characters to -; underscores. -c-ident = 1*( UPPER / DIGIT / "_" ) - -; a node's "label" property value, as an identifier -node-label-ident = c-ident - -; "uppercase ASCII letter" turns out to be pretty annoying to specify -; in RFC-7405 syntax. -; -; This is just ASCII letters A (0x41) through Z (0x5A). -UPPER = %x41-5A diff --git a/doc/guides/dts/legacy-macros.rst b/doc/guides/dts/legacy-macros.rst deleted file mode 100644 index 6cd17018b27900..00000000000000 --- a/doc/guides/dts/legacy-macros.rst +++ /dev/null @@ -1,1154 +0,0 @@ -.. _dt-legacy-macros: - -Legacy devicetree macros -######################## - -.. warning:: - - As of Zephyr v2.3, you can still use these macros if you set - ``CONFIG_LEGACY_DEVICETREE_MACROS=y`` in your application's :ref:`kconfig`. - Legacy macro support will be maintained for at least two releases, including - v2.3 itself. - - See :ref:`dt-from-c` for a usage guide for the new API, and - :ref:`dt-migrate-legacy` for a migration guide for existing code. - -This page describes legacy C preprocessor macros which Zephyr's :ref:`build -system ` generates from a devicetree. It assumes you're -familiar with the concepts in :ref:`devicetree-intro` and :ref:`dt-bindings`. - -These macros have somewhat inconsistent names, and their use in new code is -discouraged. See :ref:`dt-from-c` for the recommended API. - -These macros are generated by the :ref:`devicetree scripts `, -start with ``DT_``, and use all-uppercase. - -.. _dt-legacy-node-identifiers: - -Legacy node identifiers -*********************** - -Macros generated from individual devicetree nodes or their properties start -with ``DT_``, where ```` is a C identifier for the devicetree node. -This section describes the different ```` values in the legacy macros. - -.. _dt-legacy-node-main-ex: - -We'll use the following DTS fragment from the :ref:`FRDM-K64F ` -board's devicetree as the main example throughout this section. - -.. code-block:: DTS - - / { - - aliases { - i2c-0 = &i2c0; - }; - - soc { - i2c0: i2c@40066000 { - compatible = "nxp,kinetis-i2c"; - reg = <0x40066000 0x1000>; - status = "okay"; - /* ... */ - - fxos8700@1d { - compatible = "nxp,fxos8700"; - status = "okay"; - /* ... */ - }; - }; - }; - }; - -The binding for the "nxp,fxos8700" :ref:`compatible property -` contains this line: - -.. code-block:: yaml - - on-bus: i2c - -The generated macros for this example can be found in a build directory for the -:ref:`FXOS8700 sample application ` built for the ``frdm_k64f`` -board, in the file -:file:`build/zephyr/include/generated/devicetree_legacy_unfixed.h`. - -Here is part of :file:`devicetree_legacy_unfixed.h` showing some of the macros -for the node labeled ``i2c0``. Notice the comment with the node's path in the -devicetree and its dependency relationships with other nodes. - -.. code-block:: c - - /* - * Devicetree node: - * /soc/i2c@40066000 - * - * Binding (compatible = nxp,kinetis-i2c): - * $ZEPHYR_BASE/dts/bindings/i2c/nxp,kinetis-i2c.yaml - * - * Dependency Ordinal: 66 - * - * Requires: - * 6 /soc - * ... - * - * Supports: - * 67 /soc/i2c@40066000/fxos8700@1d - * - * Description: - * Kinetis I2C node - */ - #define DT_NXP_KINETIS_I2C_40066000_BASE_ADDRESS 0x40066000 - #define DT_NXP_KINETIS_I2C_40066000_SIZE 4096 - #define DT_ALIAS_I2C_0_BASE_ADDRESS DT_NXP_KINETIS_I2C_40066000_BASE_ADDRESS - #define DT_ALIAS_I2C_0_SIZE DT_NXP_KINETIS_I2C_40066000_SIZE - #define DT_INST_0_NXP_KINETIS_I2C_BASE_ADDRESS DT_NXP_KINETIS_I2C_40066000_BASE_ADDRESS - #define DT_INST_0_NXP_KINETIS_I2C_SIZE DT_NXP_KINETIS_I2C_40066000_SIZE - -Most macros are generated for individual nodes or their properties. Some macros -are generated for "global" information about the entire devicetree. - -In this example, the node identifiers for ``i2c@40066000`` are: - -- ``NXP_KINETIS_I2C_40066000`` -- ``ALIAS_I2C_0`` -- ``INST_0_NXP_KINETIS_I2C`` - -In general, the following ``DT_`` macro prefixes are created for each -node. - -``DT_(_)_`` - The node's compatible property converted to a C identifier, followed by its - :ref:`unit address `. If the node has multiple compatible - strings, the one for its :ref:`matching binding ` is - used. - - If the node appears on a bus (and therefore has ``on-bus:`` in its binding, - like ``fxos8700@1d`` does), then the compatible string and unit address of - the bus node is put before the compatible string for the node itself. If - the node does not appear on a bus (no ``on-bus:`` in the binding, like - ``i2c@40066000``) then there will be no ``_`` portion in the node - identifier. - - The ``i2c@40066000`` node identifier is ``NXP_KINETIS_I2C_40066000``: - - - there is no ``_`` portion - - ```` is ``NXP_KINETIS_I2C``, which is its - compatible ``"nxp,kinetis-i2c"`` converted to a C identifier - by uppercasing and replacing non-alphanumeric characters with underscores - - ```` is ``40066000`` - - The ``fxos8700@1d`` node identifier is - ``NXP_KINETIS_I2C_40066000_NXP_FXOS8700_1D``: - - - ```` is ``NXP_KINETIS_I2C_40066000`` - - ```` is ``NXP_FXOS8700`` - - ```` is ``1D`` - - If the node has no unit address, the unit address of the parent node plus - the node's name converted to a C identifier is used for ```` - instead. If the parent node has no unit address either, the name of the - node is used as a fallback. - - For example, take this DTS fragment: - - .. code-block:: DTS - - ethernet@400c0004 { - compatible = "nxp,kinetis-ethernet"; - reg = <0x400c0004 0x620>; - status = "okay"; - ptp { - compatible = "nxp,kinetis-ptp"; - status = "okay"; - interrupts = <0x52 0x0>; - }; - }; - - The ``ptp`` node identifier is ``NXP_KINETIS_PTP_400C0004_PTP``: - - - there is no ``_`` portion - - ```` is ``NXP_KINETIS_PTP`` - - ```` is ``400C0004_PTP``, which combines its parent's unit - address and the node's name converted to a C identifier - - Here is another example DTS fragment. - - .. code-block:: DTS - - soc { - temp1 { - compatible = "nxp,kinetis-temperature"; - status = "okay"; - }; - }; - - The ``temp1`` node identifier is ``NXP_KINETIS_TEMPERATURE_TEMP1``: - - - there is no ``_`` portion - - ```` is ``NXP_KINETIS_TEMPERATURE`` - - ```` is the fallback value ``TEMP1``, because neither - the node nor its parent have a unit address - -``DT_INST__`` - An instance number for the node, combined with its compatible - converted to a C identifier. - - The instance number is a unique index among all enabled - (``status = "okay"``) nodes that have a particular compatible string, - starting from zero. - - The ``i2c@40066000`` node identifier in the :ref:`main example - ` is ``INST_0_NXP_KINETIS_I2C``: - - - ```` is 0 because it was the first node with compatible - "nxp,kinetis-i2c" that the devicetree scripts happened to discover as they - walked the tree - - ```` is ``NXP_KINETIS_I2C`` - - As another example, if there are two enabled nodes that have ``compatible = - "foo,uart"``, then these node identifiers get generated: - - .. code-block:: none - - INST_0_FOO_UART - INST_1_FOO_UART - - .. warning:: - - Instance numbers are simple indexes among enabled nodes with the same - compatible. They **in no way reflect** any numbering scheme that might - exist in SoC documentation, node labels or unit addresses, or properties - of the /aliases node. - - There is no guarantee that the same node will have the same instance - number between application builds. The only guarantee is that instance - numbers will start at 0, be contiguous, and be assigned for each enabled - node with a matching compatible. - -``DT_ALIAS_`` - Generated from the names of any properties in the ``/aliases`` node. - See :ref:`dt-alias-chosen` for an overview. - - Here is a simple example. - - .. code-block:: DTS - - / { - aliases { - uart-1 = &my_uart; - }; - - my_uart: uart@12345 { /* ... */ }; - }; - - The ``uart@12345`` node identifier is ``ALIAS_UART_1``: ```` is - ``UART_1`` by uppercasing ``uart-1`` and replacing non-alphanumeric - characters with underscores. The alias refers to ``uart@12345`` using its - :ref:`label ` ``my_uart``. - - For such a simple concept, dealing with aliases can be surprisingly tricky - due to multiple names which have only minor differences. - - For a real-world example, the ``i2c@40066000`` node's alias identifier in - the :ref:`main example ` is ``ALIAS_I2C_0``: - ```` is ``I2C_0`` because the property ``i2c-0 = &i2c0;`` in the - ``/aliases`` node "points at" ``i2c@40066000`` using its label ``i2c0``. - The alias name ``i2c-0`` is converted to C identifier ``I2C_0``. - - The differences between ``i2c-0``, ``&i2c0``, ``i2c0``, and - ``i2c@40006000`` in this example are very subtle and can be quite confusing - at first. Here is some more clarification: - - - ``i2c-0`` is the *name* of a property in the ``/aliases`` node; this is - the alias name - - ``&i2c0`` is that property's *value*, which is the *phandle* of the - the node with label ``i2c0`` - - ``i2c@40006000`` is the name of the node which happens to have label - ``i2c0`` in this example - - See the devicetree specification for full details. - - .. note:: - - Another ``DT__`` form is also - generated for aliases. For the example above, assuming the compatible - string for the ``&uart1`` node is ``"foo,uart"``, this gives - ``DT_FOO_UART_UART_1``. - -.. _legacy-property-macros: - -Macros generated for properties -******************************* - -Macros for node property values have the form ``DT__``, where -```` is a :ref:`node identifier ` and ```` -identifies the property. The macros generated for a property usually depend on -its ``type:`` key in the matching devicetree binding. - -The following general purpose rules apply in most cases: - -- :ref:`generic-legacy-macros` -- :ref:`phandle-array-legacy-macros` -- :ref:`enum-legacy-macros` - -However, some "special" properties get individual treatment: - -- :ref:`reg_legacy_macros` -- :ref:`irq_legacy_macros` -- :ref:`clk_legacy_macros` -- :ref:`spi_cs_legacy_macros` - -No macros are currently generated for properties with type ``phandle``, -``phandles``, ``path``, or ``compound``. - -.. _generic-legacy-macros: - -Generic property macros -======================= - -This section documents the macros generated for non-"special" properties by -example. These properties are handled based on their devicetree binding -``type:`` keys. - -In the generic case, the ```` portion of a ``DT__`` -macro begins with the property's name converted to a C identifier by -uppercasing it and replacing non-alphanumeric characters with underscores. For -example, a ``baud-rate`` property has a ```` portion that starts with -``BAUD_RATE``. - -The table below gives the values generated for simple types. Note that an index -is added at the end of identifiers generated from properties with ``array`` or -``string-array`` type, and that ``array`` properties generate an additional -compound initializer (``{ ... }``). - - - -+------------------+------------------------+----------------------------------------+ -| Type | Property and value | Generated macros | -+==================+========================+========================================+ -| ``int`` | ``foo = <1>`` | ``#define DT__FOO 1`` | -+------------------+------------------------+----------------------------------------+ -| ``array`` | ``foo = <1 2>`` | | ``#define DT__FOO_0 1`` | -| | | | ``#define DT__FOO_1 2`` | -| | | | ``#define DT__FOO {1, 2}`` | -+------------------+------------------------+----------------------------------------+ -| ``string`` | ``foo = "bar"`` | ``#define DT__FOO "bar"`` | -+------------------+------------------------+----------------------------------------+ -| ``string-array`` | ``foo = "bar", "baz"`` | | ``#define DT__FOO_0 "bar"`` | -| | | | ``#define DT__FOO_1 "baz"`` | -+------------------+------------------------+----------------------------------------+ -| ``uint8-array`` | ``foo = [01 02]`` | ``#define DT__FOO {0x01, 0x02}`` | -+------------------+------------------------+----------------------------------------+ - -For ``type: boolean``, the generated macro is set to 1 if the property exists -on the node, and to 0 otherwise: - -.. code-block:: none - - #define DT__FOO 0/1 - -For non-boolean types the property macros are not generated if the binding's -``category`` is ``optional`` and the property is not present in the devicetree -source. - -.. _phandle-array-legacy-macros: - -Properties with type ``phandle-array`` -====================================== - -The generation for properties with type ``phandle-array`` is the most complex. -To understand it, it is a good idea to first go through the documentation for -``phandle-array`` in :ref:`dt-bindings`. - -Take the following devicetree nodes and binding contents as an example: - -.. code-block:: DTS - :caption: Devicetree nodes for PWM controllers - - pwm_ctrl_0: pwm-controller-0 { - label = "pwm-0"; - #pwm-cells = <2>; - /* ... */ - }; - - pwm_ctrl_1: pwm-controller-1 { - label = "pwm-1"; - #pwm-cells = <2>; - /* ... */ - }; - -.. code-block:: yaml - :caption: ``pwm-cells`` declaration in binding for ``vendor,pwm-controller`` - - pwm-cells: - - channel - - period - -Assume the property assignment looks like this: - -.. code-block:: DTS - - pwm-user@0 { - status = "okay"; - pwms = <&pwm_ctrl_0 1 10>, <&pwm_ctrl_1 2 20>; - pwm-names = "first", "second"; - /* ... */ - }; - -These macros then get generated. - -.. code-block:: none - - #define DT__PWMS_CONTROLLER_0 "pwm-0" - #define DT__PWMS_CHANNEL_0 1 - #define DT__PWMS_PERIOD_0 10 - - #define DT__PWMS_CONTROLLER_1 "pwm-1" - #define DT__PWMS_CHANNEL_1 2 - #define DT__PWMS_PERIOD_1 20 - - #define DT__PWMS_NAMES_0 "first" - #define DT__PWMS_NAMES_1 "second" - - #define DT__FIRST_PWMS_CONTROLLER DT__PWMS_CONTROLLER_0 - #define DT__FIRST_PWMS_CHANNEL DT__PWMS_CHANNEL_0 - #define DT__FIRST_PWMS_PERIOD DT__PWMS_PERIOD_0 - - #define DT__SECOND_PWMS_CONTROLLER DT__PWMS_CONTROLLER_1 - #define DT__SECOND_PWMS_CHANNEL DT__PWMS_CHANNEL_1 - #define DT__SECOND_PWMS_PERIOD DT__PWMS_PERIOD_1 - - /* Initializers */ - - #define DT__PWMS_0 {"pwm-0", 1, 10} - #define DT__PWMS_1 {"pwm-1", 2, 20} - #define DT__PWMS {DT__PWMS_0, DT__PWMS_1} - #define DT__PWMS_COUNT 2 - -Macros with a ``*_0`` suffix deal with the first entry in ``pwms`` -(``<&pwm_ctrl_0 1 10>``). Macros with a ``*_1`` suffix deal with the second -entry (``<&pwm_ctrl_1 2 20>``). The index suffix is only added if there's more -than one entry in the property. - -The ``DT__PWMS_CONTROLLER(_)`` macros are set to the string from -the ``label`` property of the referenced controller. The -``DT__PWMS_CHANNEL(_)`` and ``DT__PWMS_PERIOD(_)`` -macros are set to the values of the corresponding cells in the ``pwms`` -property, with macro names generated from the strings in ``pwm-cells:`` in -the binding for the controller. - -The macros in the ``/* Initializers */`` section provide the same information -as ``DT__PWMS_{CONTROLLER,CHANNEL,PERIOD}(_)``, except as compound -initializers that can be used to initialize C ``struct`` variables. - -If a ``pwm-names`` property exists on the same node as ``pwms`` (more -generally, if a ``foo-names`` property is defined next to a ``foo`` property -with type ``phandle-array``), it gives a list of strings that name each entry -in ``pwms``. The names are used to generate extra macro names with the name -instead of an index, like ``DT__FIRST_PWMS_CONTROLLER`` above. - -.. _enum-legacy-macros: - -Properties with ``enum:`` in the binding -======================================== - -Properties declared with an ``enum:`` key in their binding generate a macro -that gives the the zero-based index of the property's value in the ``enum:`` -list. - -Take this binding declaration as an example: - -.. code-block:: yaml - - properties: - foo: - type: string - enum: - - one - - two - - three - -The property ``foo = "three"`` then generates this macro: - -.. code-block:: none - - #define DT__FOO_ENUM 2 - -.. _reg_legacy_macros: - -``reg`` property macros -======================= - -``reg`` properties generate the macros ``DT__BASE_ADDRESS(_)`` and -``DT__SIZE(_)``. ```` is a numeric index starting from 0, -which is only added if there's more than one register defined in ``reg``. - -For example, the ``reg = <0x4004700 0x1060>`` assignment in the example -devicetree above gives these macros: - -.. code-block:: none - - #define DT__BASE_ADDRESS 0x40047000 - #define DT__SIZE 4192 - -.. note:: - - The length of the address and size portions of ``reg`` is determined from - the ``#address-cells`` and ``#size-cells`` properties. See the devicetree - specification for more information. - - In this case, both ``#address-cells`` and ``#size-cells`` are 1, and there's - just a single register in ``reg``. Four numbers would give two registers. - -If a ``reg-names`` property exists on the same node as ``reg``, it gives a list -of strings that names each register in ``reg``. The names are used to generate -extra macros. For example, ``reg-names = "foo"`` together with the example node -generates these macros: - -.. code-block:: c - - #define DT__FOO_BASE_ADDRESS 0x40047000 - #define DT__FOO_SIZE 4192 - -.. _irq_legacy_macros: - -``interrupts`` property macros -============================== - -Take these devicetree nodes as an example: - -.. code-block:: DTS - - timer@123 { - interrupts = <1 5 2 6>; - interrupt-parent = <&intc>; - /* ... */ - }; - - intc: interrupt-controller { /* ... */ }; - -Assume that the binding for ``interrupt-controller`` has these lines: - -.. code-block:: yaml - - interrupt-cells: - - irq - - priority - -Then these macros get generated for ``timer@123``: - -.. code-block:: c - - #define DT__IRQ_0 1 - #define DT__IRQ_0_PRIORITY 5 - #define DT__IRQ_1 2 - #define DT__IRQ_1_PRIORITY 6 - -These macros have the the format ``DT__IRQ_(_)``, where -```` is the node identifier for ``timer@123``, ```` is an index -that identifies the particular interrupt, and ```` is the identifier for -the cell value (a number within ``interrupts = <...>``), taken from the -binding. - -Bindings for interrupt controllers are expected to declare a cell named ``irq`` -in ``interrupt-cells``, giving the interrupt number. The ``_`` suffix is -skipped for macros generated from ``irq`` cells, which is why there's e.g. a -``DT__IRQ_0`` macro and no ``DT__IRQ_0_IRQ`` macro. - -If the interrupt controller in turn generates other interrupts, Zephyr uses a -multi-level interrupt encoding for the interrupt numbers at each level. See -:ref:`multi_level_interrupts` for more information. - -There is also hard-coded logic for mapping Arm GIC interrupts to linear IRQ -numbers. See the source code for details. - -Additional macros that use names instead of indices for interrupts can be -generated by including an ``interrupt-names`` property on the -interrupt-generating node. For example, this node: - -.. code-block:: DTS - - timer@456 { - interrupts = <10 50 20 60>; - interrupt-parent = <&intc>; - interrupt-names = "timer-a", "timer-b"; - /* ... */ - }; - -generates these macros: - -.. code-block:: c - - #define DT__IRQ_TIMER_A 1 - #define DT__IRQ_TIMER_A_PRIORITY 5 - #define DT__IRQ_TIMER_B 2 - #define DT__IRQ_TIMER_B_PRIORITY 6 - -.. _clk_legacy_macros: - -``clocks`` property macros -========================== - -``clocks`` work the same as other :ref:`phandle-array-legacy-macros`, except the -generated macros have ``CLOCK`` in them instead of ``CLOCKS``, giving for -example ``DT__CLOCK_CONTROLLER_0`` instead of -``DT__CLOCKS_CONTROLLER_0``. - -If a ``clocks`` controller node has a ``"fixed-clock"`` compatible, it -must also have a ``clock-frequency`` property giving its frequency in Hertz. -In this case, an additional macro is generated: - -.. code-block:: none - - #define DT__CLOCKS_CLOCK_FREQUENCY - -.. _spi_cs_legacy_macros: - -``cs-gpios`` property macros -============================ - -.. boards/arm/sensortile_box/sensortile_box.dts has a real-world example - -Take these devicetree nodes as an example. where the binding for -``vendor,spi-controller`` is assumed to have ``bus: spi``, and the bindings for -the SPI slaves are assumed to have ``on-bus: spi``: - -.. code-block:: DTS - - gpioa: gpio@400ff000 { - compatible = "vendor,gpio-ctlr"; - reg = <0x400ff000 0x40>; - label = "GPIOA"; - gpio-controller; - #gpio-cells = <0x1>; - }; - - spi { - compatible = "vendor,spi-controller"; - cs-gpios = <&gpioa 1>, <&gpioa 2>; - spi-slave@0 { - compatible = "vendor,foo-spi-device"; - reg = <0>; - }; - spi-slave@1 { - compatible = "vendor,bar-spi-device"; - reg = <1>; - }; - }; - -Here, the unit address of the SPI slaves (0 and 1) is taken as a chip select -number, which is used as an index into ``cs-gpios`` (a ``phandle-array``). -``spi-slave@0`` is matched to ``<&gpioa 1>``, and ``spi-slave@1`` to -``<&gpiob 2>``. - -The output for ``spi-slave@0`` and ``spi-slave@1`` is the same as if the -devicetree had looked like this: - -.. code-block:: DTS - - gpioa: gpio@400ff000 { - compatible = "vendor,gpio-ctlr"; - reg = <0x400ff000 0x40>; - label = "GPIOA"; - gpio-controller; - #gpio-cells = <1>; - }; - - spi { - compatible = "vendor,spi-controller"; - spi-slave@0 { - compatible = "vendor,foo-spi-device"; - reg = <0>; - cs-gpios = <&gpioa 1>; - }; - spi-slave@1 { - compatible = "vendor,bar-spi-device"; - reg = <1>; - cs-gpios = <&gpioa 2>; - }; - }; - -See the ``phandle-array`` section in :ref:`generic-legacy-macros` for more -information. - -For example, since the node labeled ``gpioa`` has property -``label = "GPIOA"`` and 1 and 2 are pin numbers, macros like the following -will be generated for ``spi-slave@0``: - -.. code-block:: none - - #define DT__CS_GPIOS_CONTROLLER "GPIOA" - #define DT__CS_GPIOS_PIN 1 - -.. _other-macros: - -Other macros -************ - -These are generated in addition to macros generated for :ref:`properties -`. - -- :ref:`dt-existence-legacy-macros` -- :ref:`bus-legacy-macros` -- :ref:`flash-legacy-macros` - -.. _dt-existence-legacy-macros: - -Node existence flags -==================== - -An "existence flag" is a macro which is defined when the devicetree contains -nodes matching some criterion. - -Existence flags are generated for each compatible property that appears on an -enabled node: - -.. code-block:: none - - #define DT_COMPAT_ 1 - -An existence flag is also written for all enabled nodes with a matching -compatible: - -.. code-block:: none - - #define DT_INST__ 1 - -For the ``i2c@40066000`` node in the :ref:`example ` above, -assuming the node is the first node with ``compatible = "nxp,kinetis-i2c"``, -the following existence flags would be generated: - -.. code-block:: c - - /* At least one node had compatible nxp,kinetis-i2c: */ - #define DT_COMPAT_NXP_KINETIS_I2C 1 - - /* Instance 0 of compatible nxp,kinetis-i2c exists: */ - #define DT_INST_0_NXP_KINETIS_I2C 1 - -If additional nodes had compatible ``nxp,kinetis-i2c``, additional existence -flags would be generated: - -.. code-block:: c - - #define DT_INST_1_NXP_KINETIS_I2C 1 - #define DT_INST_2_NXP_KINETIS_I2C 1 - /* ... and so on, one for each node with this compatible. */ - -.. _bus-legacy-macros: - -Bus-related macros -================== - -These macros get generated for nodes that appear on buses (have ``on-bus:`` in -their binding): - -.. code-block:: none - - #define DT__BUS_NAME "" - #define DT__BUS_ 1 - -```` is taken from the ``label`` property on the bus node, which -must exist. ```` is the identifier for the bus as given in -``on-bus:`` in the binding. - -.. _flash-legacy-macros: - -Macros generated from flash partitions -====================================== - -.. note:: - - This section only covers flash partitions. See :ref:`dt-alias-chosen` for - some other flash-related macros that get generated from devicetree, via - ``/chosen``. - -If a node has a name that looks like ``partition@``, it is -assumed to represent a flash partition. - -Assume the devicetree has this: - -.. code-block:: DTS - - flash@0 { - /* ... */ - label = "foo-flash"; - - partitions { - /* ... */ - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 0x00010000>; - read-only; - }; - slot0_partition: partition@10000 { - label = "image-0"; - reg = <0x00010000 0x00020000 - 0x00040000 0x00010000>; - }; - /* ... */ - }; - -These macros then get generated: - -.. code-block:: c - - #define DT_FLASH_AREA_MCUBOOT_ID 0 - #define DT_FLASH_AREA_MCUBOOT_READ_ONLY 1 - #define DT_FLASH_AREA_MCUBOOT_OFFSET_0 0x0 - #define DT_FLASH_AREA_MCUBOOT_SIZE_0 0x10000 - #define DT_FLASH_AREA_MCUBOOT_OFFSET DT_FLASH_AREA_MCUBOOT_OFFSET_0 - #define DT_FLASH_AREA_MCUBOOT_SIZE DT_FLASH_AREA_MCUBOOT_SIZE_0 - #define DT_FLASH_AREA_MCUBOOT_DEV "foo-flash" - - #define DT_FLASH_AREA_IMAGE_0_ID 0 - #define DT_FLASH_AREA_IMAGE_0_READ_ONLY 1 - #define DT_FLASH_AREA_IMAGE_0_OFFSET_0 0x10000 - #define DT_FLASH_AREA_IMAGE_0_SIZE_0 0x20000 - #define DT_FLASH_AREA_IMAGE_0_OFFSET_1 0x40000 - #define DT_FLASH_AREA_IMAGE_0_SIZE_1 0x10000 - #define DT_FLASH_AREA_IMAGE_0_OFFSET DT_FLASH_AREA_IMAGE_0_OFFSET_0 - #define DT_FLASH_AREA_IMAGE_0_SIZE DT_FLASH_AREA_IMAGE_0_SIZE_0 - #define DT_FLASH_AREA_IMAGE_0_DEV "foo-flash" - - /* Same macros, just with index instead of label */ - #define DT_FLASH_AREA_0_ID 0 - #define DT_FLASH_AREA_0_READ_ONLY 1 - ... - -The ``*_ID`` macro gives the zero-based index for the partition. - -The ``*_OFFSET_`` and ``*_SIZE_`` macros give the offset and size -for each partition, derived from ``reg``. The ``*_OFFSET`` and ``*_SIZE`` -macros, with no index, are aliases that point to the first sector (with index -0). - -.. _dt-alias-chosen: - -``aliases`` and ``chosen`` nodes -================================ - -Using an alias with a common name for a particular node makes it easier for you -to write board-independent source code. Devicetree ``aliases`` nodes are used -for this purpose, by mapping certain generic, commonly used names to specific -hardware resources: - -.. code-block:: yaml - - aliases { - led0 = &led0; - sw0 = &button0; - sw1 = &button1; - uart-0 = &uart0; - uart-1 = &uart1; - }; - -Certain software subsystems require a specific hardware resource to bind to in -order to function properly. Some of those subsystems are used with many -different boards, which makes using the devicetree ``chosen`` nodes very -convenient. By doing so, the software subsystem can rely on having the specific -hardware peripheral assigned to it. In the following example we bind the shell -to ``uart1`` in this board: - -.. code-block:: yaml - - chosen { - zephyr,shell-uart = &uart1; - }; - -The table below lists Zephyr-specific ``chosen`` properties. The macro -identifiers that start with ``CONFIG_*`` are generated from Kconfig symbols -that reference devicetree data via the :ref:`Kconfig preprocessor -`. - -.. note:: - - Since the particular devicetree isn't known while generating Kconfig - documentation, the Kconfig symbol reference pages linked below do not - include information derived from devicetree. Instead, you might see e.g. an - empty default: - - .. code-block:: none - - default "" if HAS_DTS - - To see how the preprocessor is used for a symbol, look it up directly in the - :file:`Kconfig` file where it is defined instead. The reference page for the - symbol gives the definition location. - -.. list-table:: - :header-rows: 1 - - * - ``chosen`` node name - - Generated macros - - * - ``zephyr,flash`` - - ``DT_FLASH_BASE_ADDRESS``/``DT_FLASH_SIZE``/``DT_FLASH_ERASE_BLOCK_SIZE``/``DT_FLASH_WRITE_BLOCK_SIZE`` - * - ``zephyr,code-partition`` - - ``DT_CODE_PARTITION_OFFSET``/``DT_CODE_PARTITION_SIZE`` - * - ``zephyr,sram`` - - :option:`CONFIG_SRAM_BASE_ADDRESS`/:option:`CONFIG_SRAM_SIZE` - * - ``zephyr,ccm`` - - ``DT_CCM_BASE_ADDRESS``/``DT_CCM_SIZE`` - * - ``zephyr,dtcm`` - - ``DT_DTCM_BASE_ADDRESS``/``DT_DTCM_SIZE`` - * - ``zephyr,ipc_shm`` - - ``DT_IPC_SHM_BASE_ADDRESS``/``DT_IPC_SHM_SIZE`` - * - ``zephyr,console`` - - :option:`CONFIG_UART_CONSOLE_ON_DEV_NAME` - * - ``zephyr,shell-uart`` - - :option:`CONFIG_UART_SHELL_ON_DEV_NAME` - * - ``zephyr,bt-uart`` - - :option:`CONFIG_BT_UART_ON_DEV_NAME` - * - ``zephyr,uart-pipe`` - - :option:`CONFIG_UART_PIPE_ON_DEV_NAME` - * - ``zephyr,bt-mon-uart`` - - :option:`CONFIG_BT_MONITOR_ON_DEV_NAME` - * - ``zephyr,bt-c2h-uart`` - - :option:`CONFIG_BT_CTLR_TO_HOST_UART_DEV_NAME` - * - ``zephyr,uart-mcumgr`` - - :option:`CONFIG_UART_MCUMGR_ON_DEV_NAME` - -.. _legacy_flash_partitions: - -Legacy flash partitions -*********************** - -Devicetree can be used to describe a partition layout for any flash -device in the system. - -Two important uses for this mechanism are: - -#. To force the Zephyr image to be linked into a specific area on - Flash. - - This is useful, for example, if the Zephyr image must be linked at - some offset from the flash device's start, to be loaded by a - bootloader at runtime. - -#. To generate compile-time definitions for the partition layout, - which can be shared by Zephyr subsystems and applications to - operate on specific areas in flash. - - This is useful, for example, to create areas for storing file - systems or other persistent state. These defines only describe the - boundaries of each partition. They don't, for example, initialize a - partition's flash contents with a file system. - -Partitions are generally managed using device tree overlays. See -:ref:`set-devicetree-overlays` for examples. - -Defining Partitions -=================== - -The partition layout for a flash device is described inside the -``partitions`` child node of the flash device's node in the device -tree. - -You can define partitions for any flash device on the system. - -Most Zephyr-supported SoCs with flash support in device tree -will define a label ``flash0``. This label refers to the primary -on-die flash programmed to run Zephyr. To generate partitions -for this device, add the following snippet to a device tree overlay -file: - -.. code-block:: DTS - - &flash0 { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* Define your partitions here; see below */ - }; - }; - -To define partitions for another flash device, modify the above to -either use its label or provide a complete path to the flash device -node in the device tree. - -The content of the ``partitions`` node looks like this: - -.. code-block:: DTS - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition1_label: partition@START_OFFSET_1 { - label = "partition1_name"; - reg = <0xSTART_OFFSET_1 0xSIZE_1>; - }; - - /* ... */ - - partitionN_label: partition@START_OFFSET_N { - label = "partitionN_name"; - reg = <0xSTART_OFFSET_N 0xSIZE_N>; - }; - }; - -Where: - -- ``partitionX_label`` are device tree labels that can be used - elsewhere in the device tree to refer to the partition - -- ``partitionX_name`` controls how defines generated by the Zephyr - build system for this partition will be named - -- ``START_OFFSET_x`` is the start offset in hexadecimal notation of - the partition from the beginning of the flash device - -- ``SIZE_x`` is the hexadecimal size, in bytes, of the flash partition - -The partitions do not have to cover the entire flash device. The -device tree compiler currently does not check if partitions overlap; -you must ensure they do not when defining them. - -Example Primary Flash Partition Layout -====================================== - -Here is a complete (but hypothetical) example device tree overlay -snippet illustrating these ideas. Notice how the partitions do not -overlap, but also do not cover the entire device. - -.. code-block:: DTS - - &flash0 { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - code_dts_label: partition@8000 { - label = "zephyr-code"; - reg = <0x00008000 0x34000>; - }; - - data_dts_label: partition@70000 { - label = "application-data"; - reg = <0x00070000 0xD000>; - }; - }; - }; - -Linking Zephyr Within a Partition -================================= - -To force the linker to output a Zephyr image within a given flash -partition, add this to a device tree overlay: - -.. code-block:: DTS - - / { - chosen { - zephyr,code-partition = &slot0_partition; - }; - }; - -Then, enable the :option:`CONFIG_USE_DT_CODE_PARTITION` Kconfig option. - -Flash Partition Macros -====================== - -The Zephyr build system generates definitions for each flash device -partition. These definitions are available to any files which -include ````. - -Consider this flash partition: - -.. code-block:: DTS - - dts_label: partition@START_OFFSET { - label = "def-name"; - reg = <0xSTART_OFFSET 0xSIZE>; - }; - -The build system will generate the following corresponding defines: - -.. code-block:: c - - #define DT_FLASH_AREA_DEF_NAME_DEV "def-name" - #define DT_FLASH_AREA_DEF_NAME_OFFSET_0 0xSTART_OFFSET - #define DT_FLASH_AREA_DEF_NAME_SIZE_0 0xSIZE - #define DT_FLASH_AREA_DEF_NAME_OFFSET DT_FLASH_AREA_DEF_NAME_OFFSET_0 - #define DT_FLASH_AREA_DEF_NAME_SIZE DT_FLASH_AREA_DEF_NAME_SIZE_0 - -As you can see, the ``label`` property is capitalized when forming the -macro names. Other simple conversions to ensure it is a valid C -identifier, such as converting "-" to "_", are also performed. The -offsets and sizes are available as well. - -.. _mcuboot_partitions: - -MCUboot Partitions -================== - -`MCUboot`_ is a secure bootloader for 32-bit microcontrollers. - -Some Zephyr boards provide definitions for the flash partitions which -are required to build MCUboot itself, as well as any applications -which must be chain-loaded by MCUboot. - -The device tree labels for these partitions are: - -**boot_partition** - This is the partition where the bootloader is expected to be - placed. MCUboot's build system will attempt to link the MCUboot - image into this partition. - -**slot0_partition** - MCUboot loads the executable application image from this - partition. Any application bootable by MCUboot must be linked to run - from this partition. - -**slot1_partition** - This is the partition which stores firmware upgrade images. Zephyr - applications which receive firmware updates must ensure the upgrade - images are placed in this partition (the Zephyr DFU subsystem can be - used for this purpose). MCUboot checks for upgrade images in this - partition, and can move them to ``slot0_partition`` for execution. - The ``slot0_partition`` and ``slot1_partition`` must be the same - size. - -**scratch_partition** - This partition is used as temporary storage while swapping the - contents of ``slot0_partition`` and ``slot1_partition``. - -.. important:: - - Upgrade images are only temporarily stored in ``slot1_partition``. - They must be linked to execute of out of ``slot0_partition``. - -See the `MCUboot documentation`_ for more details on these partitions. - -.. _MCUboot: https://mcuboot.com/ - -.. _MCUboot documentation: - https://github.com/runtimeco/mcuboot/blob/master/docs/design.md#image-slots - -File System Partitions -====================== - -**storage_partition** - This is the area where e.g. LittleFS or NVS or FCB expects its partition. - -ABNF grammar -************ - -This section contains an Augmented Backus-Naur Form grammar for the macros -generated from a devicetree. See `RFC 7405`_ (which extends `RFC 5234`_) for a -syntax specification. - -.. literalinclude:: legacy-macros.bnf - :language: abnf - -.. _RFC 7405: https://tools.ietf.org/html/rfc7405 -.. _RFC 5234: https://tools.ietf.org/html/rfc5234 diff --git a/doc/guides/dts/macros.bnf b/doc/guides/dts/macros.bnf index 5cf333840be666..35a5b0fbd752d4 100644 --- a/doc/guides/dts/macros.bnf +++ b/doc/guides/dts/macros.bnf @@ -19,7 +19,7 @@ dt-macro = node-macro / other-macro ; A macro about a property value node-macro = property-macro -; EXISTS macro: node has matching binding and "okay" status. +; EXISTS macro: node exists in the devicetree node-macro =/ %s"DT_N" path-id %s"_EXISTS" ; Bus macros: the plain BUS is a way to access a node's bus controller. ; The additional dt-name suffix is added to match that node's bus type; @@ -39,22 +39,42 @@ node-macro =/ %s"DT_N" path-id %s"_IRQ_IDX_" DIGIT %s"_VAL_" dt-name [ %s"_EXISTS" ] node-macro =/ %s"DT_N" path-id %s"_IRQ_NAME_" dt-name %s"_VAL_" dt-name [ %s"_EXISTS" ] -; For fixed-partitions give a unique ordinal value for each partition */ +; Subnodes of the fixed-partitions compatible get macros which contain +; a unique ordinal value for each partition node-macro =/ %s"DT_N" path-id %s"_PARTITION_ID" DIGIT -; Macros are generated for each of the node's compatibles. +; Macros are generated for each of a node's compatibles; +; dt-name in this case is something like "vnd_device". node-macro =/ %s"DT_N" path-id %s"_COMPAT_MATCHES_" dt-name -; The node identifier for the node's parent in the devicetree. +; Every non-root node gets one of these macros, which expands to the node +; identifier for that node's parent in the devicetree. node-macro =/ %s"DT_N" path-id %s"_PARENT" ; These are used internally by DT_FOREACH_CHILD, which iterates over ; each child node. node-macro =/ %s"DT_N" path-id %s"_FOREACH_CHILD" -; The node's status macro +; The node's status macro; dt-name in this case is something like "okay" +; or "disabled". node-macro =/ %s"DT_N" path-id %s"_STATUS_" dt-name +; The node's dependency ordinal. This is a non-negative integer +; value that is used to represent dependency information. +node-macro =/ %s"DT_N" path-id %s"_ORD" +; The dependency ordinals of a node's requirements (direct dependencies). +node-macro =/ %s"DT_N" path-id %s"_REQUIRES_ORDS" +; The dependency ordinals of a node supports (reverse direct dependencies). +node-macro =/ %s"DT_N" path-id %s"_SUPPORTS_ORDS" ; -------------------------------------------------------------------- ; property-macro: a macro related to a node property ; -; The "plain vanilla" macro for a property's value thus looks like: +; These combine a node identifier with a "lowercase-and-underscores form" +; property name. The value expands to something related to the property's +; value. +; +; The optional prop-suf suffix is when there's some specialized +; subvalue that deserves its own macro, like the macros for an array +; property's individual elements +; +; The "plain vanilla" macro for a property's value, with no prop-suf, +; looks like this: ; ; DT_N__P_ ; @@ -68,7 +88,8 @@ property-macro = %s"DT_N" path-id %s"_P_" prop-id [prop-suf] ; -------------------------------------------------------------------- ; path-id: a node's path-based macro identifier ; -; The path of the node converted to a C token by changing: +; This in "lowercase-and-underscores" form. I.e. it is +; the node's devicetree path converted to a C token by changing: ; ; - each slash (/) to _S_ ; - all letters to lowercase @@ -112,8 +133,8 @@ prop-id = dt-name ; - that are special to the specification ("reg", "interrupts", etc.) ; - with array types (uint8-array, phandle-array, etc.) ; - with "enum:" in their bindings -; - zephyr device API specific macros for phandle-arrays -; - phandle specifier names ("foo-names") +; - that have zephyr device API specific macros for phandle-arrays +; - related to phandle specifier names ("foo-names") ; ; Here are some examples: ; @@ -143,15 +164,20 @@ other-macro =/ %s"DT_FOREACH_OKAY_INST_" dt-name ; E.g.: #define DT_CHOSEN_zephyr_flash other-macro =/ %s"DT_CHOSEN_" dt-name ; Declares that a compatible has at least one node on a bus. -; ; Example: ; ; #define DT_COMPAT_vnd_dev_BUS_spi 1 other-macro =/ %s"DT_COMPAT_" dt-name %s"_BUS_" dt-name +; Declares that a compatible has at least one status "okay" node. +; Example: +; ; #define DT_COMPAT_HAS_OKAY_vnd_dev 1 other-macro =/ %s"DT_COMPAT_HAS_OKAY_" dt-name -; Allows mapping a "label" property to a compatible node -other-macro =/ %s"DT_COMPAT_" dt-name %s"_LABEL" dt-name +; Currently used to allow mapping a lowercase-and-underscores "label" +; property to a fixed-partitions node. See the flash map API docs +; for an example. +other-macro =/ %s"DT_COMPAT_" dt-name %s"_LABEL_" dt-name + ; -------------------------------------------------------------------- ; alternate-id: another way to specify a node besides a path-id ; @@ -202,6 +228,9 @@ alternate-id =/ %s"INST_" 1*DIGIT "_" dt-name ; from devicetree to a valid component of a C identifier by ; lowercasing letters (in practice, this is a no-op) and converting ; non-alphanumeric characters to underscores. +; +; You'll see these referred to as "lowercase-and-underscores" forms of +; various devicetree identifiers throughout the documentation. dt-name = 1*( lower / DIGIT / "_" ) ; gen-name is used as a stand-in for a component of a generated macro diff --git a/doc/guides/emulator/img/app.png b/doc/guides/emulator/img/app.png new file mode 100644 index 00000000000000..25173530ca205e Binary files /dev/null and b/doc/guides/emulator/img/app.png differ diff --git a/doc/guides/emulator/img/arch.png b/doc/guides/emulator/img/arch.png new file mode 100644 index 00000000000000..eac62bf9da6555 Binary files /dev/null and b/doc/guides/emulator/img/arch.png differ diff --git a/doc/guides/emulator/index.rst b/doc/guides/emulator/index.rst new file mode 100644 index 00000000000000..6e4597e2f177fc --- /dev/null +++ b/doc/guides/emulator/index.rst @@ -0,0 +1,115 @@ +.. _emulators: + +Emulators +######### + +Overview +======== + +Zephyr supports a simple emulator framework to support testing of drivers +without requiring real hardware. + +Emulators are used to emulate hardware devices, to support testing of +various subsystems. For example, it is possible to write an emulator +for an I2C compass such that it appears on the I2C bus and can be used +just like a real hardware device. + +Emulators often implement special features for testing. For example a +compass may support returning bogus data if the I2C bus speed is too +high, or may return invalid measurements if calibration has not yet +been completed. This allows for testing that high-level code can +handle these situations correctly. Test coverage can therefore +approach 100% if all failure conditions are emulated. + +Concept +======= + +The diagram below shows application code / high-level tests at the top. +This is the ultimate application we want to run. + +.. figure:: img/arch.png + :align: center + :alt: Emulator architecture showing tests, emulators and drivers + +Below that are peripheral drivers, such as the AT24 EEPROM driver. We can test +peripheral drivers using an emulation driver connected via a native_posix I2C +controller/emulator which passes I2C traffic from the AT24 driver to the AT24 +simulator. + +Separately we can test the STM32 and NXP I2C drivers on real hardware using API +tests. These require some sort of device attached to the bus, but with this, we +can validate much of the driver functionality. + +Putting the two together, we can test the application and peripheral code +entirely on native_posix. Since we know that the I2C driver on the real hardware +works, we should expect the application and peripheral drivers to work on the +real hardware also. + +Using the above framework we can test an entire application (e.g. Embedded +Controller) on native_posix using emulators for all non-chip drivers: + +.. figure:: img/app.png + :align: center + :alt: Example system, using emulators to implement a PC EC + +The 'real' code is shown in green. The Zephyr emulation-framework code is shown +in yellow. The blue boxes are the extra code we have to write to emulate the +peripherals. + +With this approach we can: + +* Write individual tests for each driver (green), covering all failure modes, + error conditions, etc. + +* Ensure 100% test coverage for drivers (green) + +* Write tests for combinations of drivers, such as GPIOs provided by an I2C GPIO + expander driver talking over an I2C bus, with the GPIOs controlling a charger. + All of this can work in the emulated environment or on real hardware. + +* Write a complex application that ties together all of these pieces and runs on + native_posix. We can develop on a host, use source-level debugging, etc. + +* Transfer the application to any board which provides the required features + (e.g. I2C, enough GPIOs), by adding Kconfig and devicetree fragments. + +Available emulators +=================== + +Zephyr includes the following emulators: + +* EEPROM, which uses a file as the EEPROM contents + +* I2C emulator driver, allowing drivers to be connected to an emulator so that + tests can be performed without access to the real hardware + +* SPI emulator driver, which does the same for SPI + +A GPIO emulator is planned but is not yet complete. + +Samples +======= + +Here are some examples present in Zephyr: + +#. Bosche BMI160 sensor driver connected via both I2C and SPI to an emulator: + + .. zephyr-app-commands:: + :app: tests/drivers/sensor/accel/ + :board: native_posix + :goals: build + +#. Simple test of the EEPROM emulator: + + .. zephyr-app-commands:: + :app: tests/drivers/eeprom + :board: native_posix + :goals: build + +#. The same test has a second EEPROM which is an Atmel AT24 EEPROM driver + connected via I2C an emulator: + + .. zephyr-app-commands:: + :app: tests/drivers/eeprom + :board: native_posix + :goals: build diff --git a/doc/guides/flash_debug/coredump.rst b/doc/guides/flash_debug/coredump.rst new file mode 100644 index 00000000000000..a1c1c97550dfb4 --- /dev/null +++ b/doc/guides/flash_debug/coredump.rst @@ -0,0 +1,347 @@ +.. _coredump: + +Core Dump +######### + +The core dump module enables dumping the CPU registers and memory content +for offline debugging. This module is called when fatal error is +encountered, and the data is printed or stored according to which backends +are enabled. + +Configuration +************* + +Configure this module using the following options. + +* ``DEBUG_COREDUMP``: enable the module. + +Here are the options to enable output backends for core dump: + +* ``DEBUG_COREDUMP_BACKEND_LOGGING``: use log module for core dump output. +* ``DEBUG_COREDUMP_BACKEND_NULL``: fallback core dump backend if other + backends cannot be enabled. All output is sent to null. + +Here are the choices regarding memory dump: + +* ``DEBUG_COREDUMP_MEMORY_DUMP_MIN```: only dumps the stack of the exception + thread, its thread struct, and some other bare minimal data to support + walking the stack in debugger. Use this only if absolute minimum of data + dump is desired. + +Usage +***** + +When the core dump module is enabled, during fatal error, CPU registers +and memory content are being printed or stored according to which backends +are enabled. This core dump data can fed into a custom made GDB server as +a remote target for GDB (and other GDB compatible debuggers). CPU registers, +memory content and stack can be examined in the debugger. + +This usually involves the following steps: + +1. Get the core dump log from the device depending on enabled backends. + For example, if the log module backend is used, get the log output + from the log module backend. + +2. Convert the core dump log into a binary format that can be parsed by + the GDB server. For example, + :zephyr_file:`scripts/coredump/coredump_serial_log_parser.py` can be used + to convert the serial console log into a binary file. + +3. Start the custom GDB server using the script + :zephyr_file:`scripts/coredump/coredump_gdbserver.py` with the core dump + binary log file, and the Zephyr ELF file as parameters. + +4. Start the debugger corresponding to the target architecture. + +Example +------- + +This example uses the log module backend tied to serial console. +This was done on `qemu_x86` where a null pointer was dereferenced. + +This is the core dump log from the serial console, and is stored +in :file:`coredump.log`: + +:: + + Booting from ROM..*** Booting Zephyr OS build zephyr-v2.3.0-1840-g7bba91944a63 *** + Hello World! qemu_x86 + E: Page fault at address 0x0 (error code 0x2) + E: Linear address not present in page tables + E: PDE: 0x0000000000115827 Writable, User, Execute Enabled + E: PTE: Non-present + E: EAX: 0x00000000, EBX: 0x00000000, ECX: 0x00119d74, EDX: 0x000003f8 + E: ESI: 0x00000000, EDI: 0x00101aa7, EBP: 0x00119d10, ESP: 0x00119d00 + E: EFLAGS: 0x00000206 CS: 0x0008 CR3: 0x00119000 + E: call trace: + E: EIP: 0x00100459 + E: 0x00100477 (0x0) + E: 0x00100492 (0x0) + E: 0x001004c8 (0x0) + E: 0x00105465 (0x105465) + E: 0x00101abe (0x0) + E: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0 + E: Current thread: 0x00119080 (unknown) + E: #CD:BEGIN# + E: #CD:5a4501000100050000000000 + E: #CD:4101003800 + E: #CD:0e0000000200000000000000749d1100f803000000000000009d1100109d1100 + E: #CD:00000000a71a100059041000060200000800000000901100 + E: #CD:4d010080901100e0901100 + E: #CD:0100000000000000000000000180000000000000000000000000000000000000 + E: #CD:00000000000000000000000000000000e364100000000000000000004c9c1100 + E: #CD:000000000000000000000000b49911000004000000000000fc03000000000000 + E: #CD:4d0100b4991100b49d1100 + E: #CD:f8030000020000000200000002000000f8030000fd03000a02000000dc9e1100 + E: #CD:149a1160fd03000002000000dc9e1100249a110087201000049f11000a000000 + E: #CD:349a11000a4f1000049f11000a9e1100449a11000a8b10000200000002000000 + E: #CD:449a1100388b1000049f11000a000000549a1100ad201000049f11000a000000 + E: #CD:749a11000a201000049f11000a000000649a11000a201000049f11000a000000 + E: #CD:749a1100e8201000049f11000a000000949a1100890b10000a0000000a000000 + E: #CD:a49a1100890b10000a0000000a000000f8030000189b11000200000002000000 + E: #CD:f49a1100289b11000a000000189b1100049b11009b0710000a000000289b1100 + E: #CD:f49a110087201000049f110045000000f49a1100509011000a00000020901100 + E: #CD:f49a110060901100049f1100ffffffff0000000000000000049f1100ffffffff + E: #CD:0000000000000000630b1000189b1100349b1100af0b1000630b1000289b1100 + E: #CD:55891000789b11000000000020901100549b1100480000004a891000609b1100 + E: #CD:649b1100d00b10004a891000709b110000000000609b11000a00000000000000 + E: #CD:849b1100709b11004a89100000000000949b1100794a10000000000058901100 + E: #CD:20901100c34a10000a00001734020000d001000000000000d49b110038000000 + E: #CD:c49b110078481000b49911000004000000000000000000000c9c11000c9c1100 + E: #CD:149c110000000000d49b110038000000f49b1100da481000b499110000040000 + E: #CD:0e0000000200000000000000744d0100b4991100b49d1100009d1100109d1100 + E: #CD:149c110099471000b4991100000400000800000000901100ad861000409c1100 + E: #CD:349c1100e94710008090110000000000349c1100b64710008086100045000000 + E: #CD:849c11002d53100000000000d09c11008090110020861000f5ffffff8c9c1100 + E: #CD:000000000000000000000000a71a1000a49c1100020200008090110000000000 + E: #CD:a49c1100020200000800000000000000a49c11001937100000000000d09c1100 + E: #CD:0c9d0000bc9c0000b49d1100b4991100c49c1100ae37100000000000d09c1100 + E: #CD:0800000000000000c888100000000000109d11005d031000d09c1100009d1100 + E: #CD:109d11000000000000000000a71a1000f803000000000000749d110002000000 + E: #CD:5904100008000000060200000e0000000202000002020000000000002c9d1100 + E: #CD:7704100000000000d00b1000c9881000549d110000000000489d110092041000 + E: #CD:00000000689d1100549d11000000000000000000689d1100c804100000000000 + E: #CD:c0881000000000007c9d110000000000749d11007c9d11006554100065541000 + E: #CD:00000000000000009c9d1100be1a100000000000000000000000000038041000 + E: #CD:08000000020200000000000000000000f4531000000000000000000000000000 + E: #CD:END# + E: Halting system + + +1. Run the core dump serial log converter: + + .. code-block:: console + + ./scripts/coredump/coredump_serial_log_parser.py coredump.log coredump.bin + +2. Start the custom GDB server: + + .. code-block:: console + + ./scripts/coredump/coredump_gdbserver.py build/zephyr/zephyr.elf coredump.bin + +3. Start GDB: + + .. code-block:: console + + /x86_64-zephyr-elf/bin/x86_64-zephyr-elf-gdb build/zephyr/zephyr.elf + +4. Inside GDB, connect to the GDB server via port 1234: + + .. code-block:: console + + (gdb) target remote localhost:1234 + +5. Examine the CPU registers: + + .. code-block:: console + + (gdb) info registers + + Output from GDB: + + :: + + eax 0x0 0 + ecx 0x119d74 1154420 + edx 0x3f8 1016 + ebx 0x0 0 + esp 0x119d00 0x119d00 + ebp 0x119d10 0x119d10 + esi 0x0 0 + edi 0x101aa7 1055399 + eip 0x100459 0x100459 + eflags 0x206 [ PF IF ] + cs 0x8 8 + ss + ds + es + fs + gs + +6. Examine the backtrace: + + .. code-block:: console + + (gdb) bt + + + Output from GDB: + + :: + + #0 0x00100459 in func_3 (addr=0x0) at zephyr/rtos/zephyr/samples/hello_world/src/main.c:14 + #1 0x00100477 in func_2 (addr=0x0) at zephyr/rtos/zephyr/samples/hello_world/src/main.c:21 + #2 0x00100492 in func_1 (addr=0x0) at zephyr/rtos/zephyr/samples/hello_world/src/main.c:28 + #3 0x001004c8 in main () at zephyr/rtos/zephyr/samples/hello_world/src/main.c:42 + +File Format +*********** + +The core dump binary file consists of one file header, one +architecture-specific block, and multiple memory blocks. All numbers in +the headers below are little endian. + +File Header +----------- + +The file header consists of the following fields: + +.. list-table:: Core dump binary file header + :widths: 2 1 7 + :header-rows: 1 + + * - Field + - Data Type + - Description + * - ID + - ``char[2]`` + - ``Z``, ``E`` as identifier of file. + * - Header version + - ``uint16_t`` + - Identify the version of the header. This needs to be incremented + whenever the header struct is modified. This allows parser to + reject older header versions so it will not incorrectly parse + the header. + * - Target code + - ``uint16_t`` + - Indicate which target (e.g. architecture or SoC) so the parser + can instantiate the correct register block parser. + * - Pointer size + - 'uint8_t' + - Size of ``uintptr_t`` in power of 2. (e.g. 5 for 32-bit, + 6 for 64-bit). This is needed to accommodate 32-bit and 64-bit + target in parsing the memory block addresses. + * - Flags + - ``uint8_t`` + - + * - Fatal error reason + - ``unsigned int`` + - Reason for the fatal error, as the same in + ``enum k_fatal_error_reason`` defined in + :zephyr_file:`include/fatal.h` + +Architecture-specific Block +--------------------------- + +The architecture-specific block contains the byte stream of data specific +to the target architecture (e.g. CPU registers) + +.. list-table:: Architecture-specific Block + :widths: 2 1 7 + :header-rows: 1 + + * - Field + - Data Type + - Description + * - ID + - ``char`` + - ``A`` to indiciate this is a architecture-specific block. + * - Header version + - ``uint16_t`` + - Identify the version of this block. To be interpreted by the target + architecture specific block parser. + * - Number of bytes + - ``uint16_t`` + - Number of bytes following the header which contains the byte stream + for target data. The format of the byte stream is specific to + the target and is only being parsed by the target parser. + * - Register byte stream + - ``uint8_t[]`` + - Contains target architecture specific data. + +Memory Block +------------ + +The memory block contains the start and end addresses and the data within +the memory region. + +.. list-table:: Memory Block + :widths: 2 1 7 + :header-rows: 1 + + * - Field + - Data Type + - Description + * - ID + - ``char`` + - ``M`` to indiciate this is a memory block. + * - Header version + - ``uint16_t`` + - Identify the version of the header. This needs to be incremented + whenever the header struct is modified. This allows parser to + reject older header versions so it will not incorrectly parse + the header. + * - Start address + - ``uintptr_t`` + - The start address of the memory region. + * - End address + - ``uintptr_t`` + - The end address of the memory region. + * - Memory byte stream + - ``uint8_t[]`` + - Contains the memory content between the start and end addresses. + +Adding New Target +***************** + +The architecture-specific block is target specific and requires new +dumping routine and parser for new targets. To add a new target, +the following needs to be done: + +#. Add a new target code to the ``enum z_coredump_tgt_code`` in + :zephyr_file:`include/debug/coredump.h`. +#. Implement :c:func:`arch_coredump_tgt_code_get` simply to return + the newly introducted target code. +#. Implement :c:func:`arch_coredump_info_dump` to construct + a target architecture block and call :c:func:`z_coredump_buffer_output` + to output the block to core dump backend. +#. Add a parser to the core dump GDB stub scripts under + ``scripts/coredump/gdbstubs/`` + + #. Extends the ``gdbstubs.gdbstub.GdbStub`` class. + #. During ``__init__``, store the GDB signal corresponding to + the exception reason in ``self.gdb_signal``. + #. Parse the architecture-specific block from + ``self.logfile.get_arch_data()``. This needs to match the format + as implemented in step 3 (inside :c:func:`arch_coredump_info_dump`). + #. Implement the abstract method ``handle_register_group_read_packet`` + where it returns the register group as GDB expected. Refer to + GDB's code and documentation on what it is expecting for + the new target. + #. Optionally implement ``handle_register_single_read_packet`` + for registers not covered in the ``g`` packet. + +#. Extend ``get_gdbstub()`` in + :zephyr_file:`scripts/coredump/gdbstubs/__init__.py` to return + the newly implemented GDB stub. + +API documentation +***************** + +.. doxygengroup:: coredump_apis + :project: Zephyr + +.. doxygengroup:: arch-coredump + :project: Zephyr diff --git a/doc/guides/flash_debug/gdbstub.rst b/doc/guides/flash_debug/gdbstub.rst new file mode 100644 index 00000000000000..94a0db4b4644e9 --- /dev/null +++ b/doc/guides/flash_debug/gdbstub.rst @@ -0,0 +1,34 @@ +.. _gdbgstub: + +GDB stub +######## + +Overview +******** + +The gdbstub feature provides an implementation of the GDB Remote +Serial Protocol (RSP) that allows you to remotely debug Zephyr +using GDB. + +The protocol supports different connection types: serial, UDP/IP and +TCP/IP. Zephyr currently supports only serial device communication. + +The GDB program acts as the client while Zephyr acts as the +server. When this feature is enabled, Zephyr stops its execution after +``gdb_init()`` starts gdbstub service and waits for a GDB +connection. Once a connection is established it is possible to +synchronously interact with Zephyr. Note that currently it is not +possible to asynchronously send commands to the target. + +Enable this feature with the :option:`CONFIG_GDBSTUB` option. + +Features +******** + +The following features are supported: + +* Add and remove breakpoints +* Continue and step the target +* Print backtrace +* Read or write general registers +* Read or write the memory diff --git a/doc/guides/flash_debug/host-tools.rst b/doc/guides/flash_debug/host-tools.rst new file mode 100644 index 00000000000000..8c856b51a98aef --- /dev/null +++ b/doc/guides/flash_debug/host-tools.rst @@ -0,0 +1,269 @@ +.. _flash-debug-host-tools: + +Flash & Debug Host Tools +######################## + +This guide describes the software tools you can run on your host workstation to +flash and debug Zephyr applications. + +Zephyr's west tool has built-in support for all of these in its ``flash``, +``debug``, ``debugserver``, and ``attach`` commands, provided your board +hardware supports them and your Zephyr board directory's :file:`board.cmake` +file declares that support properly. See :ref:`west-build-flash-debug` for +more information on these commands. + +.. _atmel_sam_ba_bootloader: + + +SAM Boot Assistant (SAM-BA) +*************************** + +Atmel SAM Boot Assistant (Atmel SAM-BA) allows In-System Programming (ISP) +from USB or UART host without any external programming interface. Zephyr +allows users to develop and program boards with SAM-BA support using +:ref:`west `. Zephyr supports devices with/without ROM +bootloader and both extensions from Arduino and Adafruit. Full support was +introduced in Zephyr SDK 0.12.0. + +The typical command to flash the board is: + +.. code-block:: console + + west flash [ -r bossac ] [ -p /dev/ttyX ] + + +Devices with ROM bootloader +--------------------------- + +These devices don't need any special configuration. After building your +application, just run ``west flash`` to flash the board. + + +Devices without ROM bootloader +------------------------------ + +For these devices, the user should: + +1. Define flash partitions required to accommodate the bootloader and + application image; see :ref:`flash_map_api` for details. +2. Have board :file:`.defconfig` file with the + :option:`CONFIG_USE_DT_CODE_PARTITION` Kconfig option set to ``y`` to + instruct the build system to use these partitions for code relocation. + This option can also be set in ``prj.conf`` or any other Kconfig fragment. +3. Build and flash the SAM-BA bootloader on the device. + + +Devices with compatible SAM-BA bootloader +----------------------------------------- + +For these devices, the user should: + +1. Define flash partitions required to accommodate the bootloader and + application image; see :ref:`flash_map_api` for details. +2. Have board :file:`.defconfig` file with the + :option:`CONFIG_BOOTLOADER_BOSSA` Kconfig option set to ``y``. This will + automatically select the :option:`CONFIG_USE_DT_CODE_PARTITION` Kconfig + option which instruct the build system to use these partitions for code + relocation. The board :file:`.defconfig` file should have + :option:`CONFIG_BOOTLOADER_BOSSA_ARDUINO` or the + :option:`CONFIG_BOOTLOADER_BOSSA_ADAFRUIT_UF2` Kconfig option set to ``y`` + to select the right compatible SAM-BA bootloader mode. + These options can also be set in ``prj.conf`` or any other Kconfig fragment. +3. Build and flash the SAM-BA bootloader on the device. + + +Typical flash layout and configuration +-------------------------------------- + +For bootloaders that reside on flash, the devicetree partition layout is +mandatory. For devices that have a ROM bootloader, they are mandatory when +the application uses a storage or other non-application partition. In this +special case, the boot partition should be omitted and code_partition should +start from offset 0. It is necessary to define the partitions with sizes that +avoid overlaps, always. + +A typical flash layout for devices without a ROM bootloader is: + +.. code-block:: DTS + + / { + chosen { + zephyr,code-partition = &code_partition; + }; + }; + + &flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "sam-ba"; + reg = <0x00000000 0x2000>; + read-only; + }; + + code_partition: partition@2000 { + label = "code"; + reg = <0x2000 0x3a000>; + read-only; + }; + + /* + * The final 16 KiB is reserved for the application. + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@3c000 { + label = "storage"; + reg = <0x0003c000 0x00004000>; + }; + }; + }; + +A typical flash layout for devices with a ROM bootloader and storage +partition is: + +.. code-block:: DTS + + / { + chosen { + zephyr,code-partition = &code_partition; + }; + }; + + &flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + code_partition: partition@0 { + label = "code"; + reg = <0x0 0xF0000>; + read-only; + }; + + /* + * The final 64 KiB is reserved for the application. + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@F0000 { + label = "storage"; + reg = <0x000F0000 0x00100000>; + }; + }; + }; + + +Enabling SAM-BA runner +---------------------- + +In order to instruct Zephyr west tool to use the SAM-BA bootloader the +:file:`board.cmake` file must have +``include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake)`` entry. Note that +Zephyr tool accept more entries to define multiple runners. By default, the +first one will be selected when using ``west flash`` command. The remaining +options are available passing the runner option, for instance +``west flash -r bossac``. + + +More implementation details can be found in the :ref:`boards` documentation. +As a quick reference, see these three board documentation pages: + + - :ref:`sam4e_xpro` (ROM bootloader) + - :ref:`adafruit_feather_m0_basic_proto` (Adafruit UF2 bootloader) + - :ref:`arduino_nano_33_iot` (Arduino bootloader) + +.. _jlink-debug-host-tools: + +J-Link Debug Host Tools +*********************** + +Segger provides a suite of debug host tools for Linux, macOS, and Windows +operating systems: + +- J-Link GDB Server: GDB remote debugging +- J-Link Commander: Command-line control and flash programming +- RTT Viewer: RTT terminal input and output +- SystemView: Real-time event visualization and recording + +These debug host tools are compatible with the following debug probes: + +- :ref:`lpclink2-jlink-onboard-debug-probe` +- :ref:`opensda-jlink-onboard-debug-probe` +- :ref:`jlink-external-debug-probe` +- :ref:`stlink-v21-onboard-debug-probe` + +Check if your SoC is listed in `J-Link Supported Devices`_. + +Download and install the `J-Link Software and Documentation Pack`_ to get the +J-Link GDB Server and Commander, and to install the associated USB device +drivers. RTT Viewer and SystemView can be downloaded separately, but are not +required. + +Note that the J-Link GDB server does not yet support Zephyr RTOS-awareness. + +.. _openocd-debug-host-tools: + +OpenOCD Debug Host Tools +************************ + +OpenOCD is a community open source project that provides GDB remote debugging +and flash programming support for a wide range of SoCs. A fork that adds Zephyr +RTOS-awareness is included in the Zephyr SDK; otherwise see `Getting OpenOCD`_ +for options to download OpenOCD from official repositories. + +These debug host tools are compatible with the following debug probes: + +- :ref:`opensda-daplink-onboard-debug-probe` +- :ref:`jlink-external-debug-probe` +- :ref:`stlink-v21-onboard-debug-probe` + +Check if your SoC is listed in `OpenOCD Supported Devices`_. + +.. note:: On Linux, openocd is available though the `Zephyr SDK + `_. + Windows users should use the following steps to install + openocd: + + - Download openocd for Windows from here: `OpenOCD Windows`_ + - Copy bin and share dirs to ``C:\Program Files\OpenOCD\`` + - Add ``C:\Program Files\OpenOCD\bin`` to 'PATH' environment variable + +.. _pyocd-debug-host-tools: + +pyOCD Debug Host Tools +********************** + +pyOCD is an open source project from Arm that provides GDB remote debugging and +flash programming support for Arm Cortex-M SoCs. It is distributed on PyPi and +installed when you complete the :ref:`gs_python_deps` step in the Getting +Started Guide. pyOCD includes support for Zephyr RTOS-awareness. + +These debug host tools are compatible with the following debug probes: + +- :ref:`opensda-daplink-onboard-debug-probe` +- :ref:`stlink-v21-onboard-debug-probe` + +Check if your SoC is listed in `pyOCD Supported Devices`_. + +.. _J-Link Software and Documentation Pack: + https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack + +.. _J-Link Supported Devices: + https://www.segger.com/downloads/supported-devices.php + +.. _Getting OpenOCD: + http://openocd.org/getting-openocd/ + +.. _OpenOCD Supported Devices: + https://github.com/zephyrproject-rtos/openocd/tree/master/tcl/target + +.. _pyOCD Supported Devices: + https://github.com/mbedmicro/pyOCD/tree/master/pyocd/target/builtin + +.. _OpenOCD Windows: + http://gnutoolchains.com/arm-eabi/openocd/ diff --git a/doc/guides/flash_debug/index.rst b/doc/guides/flash_debug/index.rst new file mode 100644 index 00000000000000..329a6ef537d7f7 --- /dev/null +++ b/doc/guides/flash_debug/index.rst @@ -0,0 +1,13 @@ +.. _flashing_and_debugging: + +Flashing and Debugging +###################### + +.. toctree:: + :maxdepth: 1 + + host-tools.rst + probes.rst + thread-analyzer.rst + coredump.rst + gdbstub.rst diff --git a/doc/guides/debugging/probes.rst b/doc/guides/flash_debug/probes.rst similarity index 96% rename from doc/guides/debugging/probes.rst rename to doc/guides/flash_debug/probes.rst index cad760b5c18492..ebe0a17737316e 100644 --- a/doc/guides/debugging/probes.rst +++ b/doc/guides/flash_debug/probes.rst @@ -9,7 +9,7 @@ reading and writing registers and memory, and support breakpoint debugging of the Zephyr application on your host workstation using tools like GDB. They may also support other debug software and more advanced features such as :ref:`tracing program execution `. For details on the related host -software supported by Zephyr, see :ref:`debug-host-tools`. +software supported by Zephyr, see :ref:`flash-debug-host-tools`. Debug probes are usually connected to your host workstation via USB; they are sometimes also accessible via an IP network or other means. They usually @@ -192,13 +192,13 @@ Using Segger J-Link Once STLink is flashed with SEGGER FW and J-Link GDB server is installed on your host computer, you can flash and debug as follows: -Use CMake with ``-DZEPHYR_BOARD_FLASH_RUNNER=jlink`` to change the default OpenOCD +Use CMake with ``-DBOARD_FLASH_RUNNER=jlink`` to change the default OpenOCD runner to J-Link. Alternatively, you might add the following line to your application ``CMakeList.txt`` file. .. code-block:: cmake - set(ZEPHYR_BOARD_FLASH_RUNNER jlink) + set(BOARD_FLASH_RUNNER jlink) If you use West (Zephyr's meta-tool) you can modify the default runner using the ``--runner`` (or ``-r``) option. @@ -241,7 +241,7 @@ Updating or restoring ST-Link firmware ST-Link firmware can be updated using `STM32CubeProgrammer Tool`_. It is usually useful when facing flashing issues, for instance when using -sanitycheck's device-testing option. +twister's device-testing option. Once installed, you can update attached board ST-Link firmware with the following command @@ -250,9 +250,9 @@ following command s java -jar ~/STMicroelectronics/STM32Cube/STM32CubeProgrammer/Drivers/FirmwareUpgrade/STLinkUpgrade.jar -sn -Where board_uid can be obtained using sanitycheck's generate-hardware-map -option. For more information about sanitycheck and available options, see -:ref:`sanitycheck_script`. +Where board_uid can be obtained using twister's generate-hardware-map +option. For more information about twister and available options, see +:ref:`twister_script`. .. _jlink-external-debug-probe: diff --git a/doc/guides/debugging/thread-analyzer.rst b/doc/guides/flash_debug/thread-analyzer.rst similarity index 93% rename from doc/guides/debugging/thread-analyzer.rst rename to doc/guides/flash_debug/thread-analyzer.rst index 5df3d49b31581a..cee4a378bb6d62 100644 --- a/doc/guides/debugging/thread-analyzer.rst +++ b/doc/guides/flash_debug/thread-analyzer.rst @@ -6,7 +6,7 @@ Thread analyzer The thread analyzer module enables all the Zephyr options required to track the thread information, e.g. thread stack size usage. The analysis is performed on demand when the application calls -:cpp:func:`thread_analyzer_run` or :cpp:func:`thread_analyzer_print`. +:c:func:`thread_analyzer_run` or :c:func:`thread_analyzer_print`. Configuration ************* diff --git a/doc/guides/index.rst b/doc/guides/index.rst index 5ca272b6b64d33..c32932aa189317 100644 --- a/doc/guides/index.rst +++ b/doc/guides/index.rst @@ -10,16 +10,19 @@ User and Developer Guides beyond-GSG.rst bluetooth/index.rst build/index + coding_guidelines/index + design_guidelines.rst c_library ../README.rst documentation/index coccinelle.rst code-relocation.rst crypto/index - debugging/index + flash_debug/index device_mgmt/index device_mgmt/dfu dts/index + emulator/index.rst env_vars.rst coverage.rst kconfig/index @@ -33,3 +36,4 @@ User and Developer Guides west/index optimizations/index zephyr_cmake_package.rst + thread_local_storage.rst diff --git a/doc/guides/kconfig/setting.rst b/doc/guides/kconfig/setting.rst index bbc327f46b5b7d..a536872a71d03e 100644 --- a/doc/guides/kconfig/setting.rst +++ b/doc/guides/kconfig/setting.rst @@ -141,19 +141,25 @@ The application configuration can come from the sources below. By default, merged and used as the application configuration. ``CONF_FILE`` can be set in various ways: - 1. In :file:`CMakeLists.txt`, before including :file:`boilerplate.cmake` + 1. In :file:`CMakeLists.txt`, before calling ``find_package(Zephyr)`` 2. By passing ``-DCONF_FILE=``, either directly or via ``west`` 3. From the CMake variable cache -2. Otherwise, :file:`prj_.conf` is used if it exists in the application +2. Otherwise if ``CONF_FILE`` is set, and a single configuration file of the + form :file:`prj_.conf` is used, then if file + :file:`boards/_.conf` exists in same folder as file + :file:`prj_.conf`, the result of merging :file:`prj_.conf` and + :file:`boards/_.conf` is used. + +3. Otherwise, :file:`prj_.conf` is used if it exists in the application directory. -3. Otherwise, if :file:`boards/.conf` exists in the application +4. Otherwise, if :file:`boards/.conf` exists in the application directory, the result of merging it with :file:`prj.conf` is used. -4. Otherwise, :file:`prj.conf` is used if it exists in the application +5. Otherwise, :file:`prj.conf` is used if it exists in the application directory If a symbol is assigned both in :file:`_defconfig` and in the diff --git a/doc/guides/modules.rst b/doc/guides/modules.rst index 122db1bd80b28f..3ff16566b5a269 100644 --- a/doc/guides/modules.rst +++ b/doc/guides/modules.rst @@ -10,7 +10,21 @@ system those are called *modules*. These modules must be integrated with the Zephyr build system, as described in more detail in other sections on this page. -Zephyr depends on several categories of modules, including: +To be classified as a candidate for being included in the default list of +modules, an external project is required to have its own life-cycle outside +the Zephyr Project, that is, reside in its own repository, and have its own +contribution and maintenance workfow and release process. Zephyr modules +should not contain code that is written exclusively for Zephyr. Instead, +such code should be contributed to the main zephyr tree. + +Modules to be included in the default manifest of the Zephyr project need to +provide functionality or features endorsed and approved by the project Technical +Steering Committee and should comply with the +:ref:`module licensing requirements` and +:ref:`contribute guidelines`. They should also have a +Zephyr developer that is committed to maintain the module codebase. + +Zephyr depends on several categories of modules, including but not limited to: - Debugger integration - Silicon vendor Hardware Abstraction Layers (HALs) @@ -18,6 +32,350 @@ Zephyr depends on several categories of modules, including: - File Systems - Inter-Process Communication (IPC) libraries +This page summarizes a list of policies and best practices which aim at +better organizing the workflow in Zephyr modules. + +Module Repositories +******************* + +* All modules included in the default manifest shall be hosted in repositories + under the zephyrproject-rtos GitHub organization. + +* The module repository codebase shall include a *module.yml* file in a + :file:`zephyr/` folder at the root of the repository. + +* Module repository names should follow the convention of using lowercase + letters and dashes instead of underscores. This rule will apply to all + new module repositories, except for repositories that are directly + tracking external projects (hosted in Git repositories); such modules + may be named as their external project counterparts. + + .. note:: + + Existing module repositories that do not conform to the above convention + do not need to be renamed to comply with the above convention. + +* Modules should use "zephyr" as the default name for the repository main + branch. Branches for specific purposes, for example, a module branch for + an LTS Zephyr version, shall have names starting with the 'zephyr\_' prefix. + +* If the module has an external (upstream) project repository, the module + repository should preserve the upstream repository folder structure. + + .. note:: + + It is not required in module repositories to maintain a 'master' + branch mirroring the master branch of the external repository. It + is not recommended as this may generate confusion around the module's + main branch, which should be 'zephyr'. + +.. _modules_synchronization: + +Synchronizing with upstream +=========================== + +It is preferred to synchronize a module respository with the latest stable +release of the corresponding external project. It is permitted, however, to +update a Zephyr module repository with the latest development branch tip, +if this is required to get important updates in the module codebase. When +synchronizing a module with upstream it is mandatory to document the +rationale for performing the particular update. + +Requirements for allowed practices +---------------------------------- + +Changes to the main branch of a module repository, including synchronization +with upstream code base, may only be applied via pull requests. These pull +requests shall be *verifiable* by Zephyr CI and *mergeable* (e.g. with the +*Rebase and merge*, or *Create a merge commit* option using Github UI). This +ensures that the incoming changes are always **reviewable**, and the +*downstream* module repository history is incremental (that is, existing +commits, tags, etc. are always preserved). This policy also allows to run +Zephyr CI, git lint, identity, and license checks directly on the set of +changes that are to be brought into the module repository. + +.. note:: + + Force-pushing to a module's main branch is not allowed. + +Allowed practices +--------------------- + +The following practices conform to the above requirements and should be +followed in all modules repositories. It is up to the module code owner +to select the preferred synchronization practice, however, it is required +that the selected practice is consistently followed in the respective +module repository. + +**Updating modules with a diff from upstream:** +Upstream changes brought as a single *snapshot* commit (manual diff) in a +pull request against the module's main branch, which may be merged using +the *Rebase & merge* operation. This approach is simple and +should be applicable to all modules with the downside of supressing the +upstream history in the module repository. + + .. note:: + + The above practice is the only allowed practice in modules where + the external project is not hosted in an upstream Git repository. + +The commit message is expected to identify the upstream project URL, the +version to which the module is updated (upstream version, tag, commit SHA, +if applicable, etc.), and the reason for the doing the update. + +**Updating modules by merging the upstream branch:** +Upstream changes brought in by performing a Git merge of the intended upstream +branch (e.g. main branch, latest release branch, etc.) submitting the result in +pull request against the module main branch, and merging the pull request using +the *Create a merge commit* operation. +This approach is applicable to modules with an upstream project Git repository. +The main advantages of this approach is that the upstream repository history +(that is, the original commit SHAs) is preserved in the module repository. The +downside of this approach is that two additional merge commits are generated in +the downstream main branch. + + +Contributing to Zephyr modules +****************************** + +.. _modules_contributing: + + +Individual Roles & Responsibilities +=================================== + +To facilitate management of Zephyr module repositories, the following +individual roles are defined. + +**Administrator:** Each Zephyr module shall have an administrator +who is responsible for managing access to the module repository, +for example, for adding individuals as Collaborators in the repository +at the request of the module owner. Module administrators are +members of the Administrators team, that is a group of project +members with admin rights to module GitHub repositories. + +**Module owner:** Each module shall have a module code owner. Module +owners will have the overall responsibility of the contents of a +Zephyr module repository. In particular, a module owner will: + +* coordinate code reviewing in the module repository +* be the default assignee in pull-requests against the repository's + main branch +* request additional collaborators to be added to the repository, as + they see fit +* regularly synchronize the module repository with its upstream + counterpart following the policies described in + :ref:`modules_synchronization` +* be aware of security vulnerability issues in the external project + and update the module repository to include security fixes, as + soon as the fixes are available in the upstream code base +* list any known security vulnerability issues, present in the + module codebase, in Zephyr release notes. + + + .. note:: + + Module owners are not required to be Zephyr + :ref:`Maintainers `. + +**Merger:** The Zephyr Release Engineering team has the right and the +responsibility to merge approved pull requests in the main branch of a +module repository. + + +Maintaining the module codebase +=============================== + +Updates in the zephyr main tree, for example, in public Zephyr APIs, +may require patching a module's codebase. The responsibility for keeping +the module codebase up to date is shared between the **contributor** of +such updates in Zephyr and the module **owner**. In particular: + +* the contributor of the original changes in Zephyr is required to submit + the corresponding changes that are required in module repositories, to + ensure that Zephyr CI on the pull request with the original changes, as + well as the module integration testing are successful. + +* the module owner has the overall responsibility for synchronizing + and testing the module codebase with the zephyr main tree. + This includes occasional advanced testing of the module's codebase + in addition to the testing performed by Zephyr's CI. + The module owner is required to fix issues in the module's codebase that + have not been caught by Zephyr pull request CI runs. + + + +Contributing changes to modules +=============================== + +Submitting and merging changes directly to a module's codebase, that is, +before they have been merged in the corresponding external project +repository, should be limited to: + +* changes required due to updates in the zephyr main tree +* urgent changes that should not wait to be merged in the external project + first, such as fixes to security vulnerabilities. + +Non-trivial changes to a module's codebase, including changes in the module +design or functionality should be discouraged, if the module has an upstream +project repository. In that case, such changes shall be submitted to the +upstream project, directly. + +:ref:`Submitting changes to modules ` describes in +detail the process of contributing changes to module repositories. + +Contribution guidelines +----------------------- + +Contributing to Zephyr modules shall follow the generic project +:ref:`Contribution guidelines `. + +**Pull Requests:** may be merged with minimum of 2 approvals, including +an approval by the PR assignee. In addition to this, pull requests in module +repositories may only be merged if the introduced changes are verified +with Zephyr CI tools, as described in more detail in other sections on +this page. + +The merging of pull requests in the main branch of a module +repository must be coupled with the corresponding manifest +file update in the zephyr main tree. + +**Issue Reporting:** GitHub issues are intentionally disabled in module +repositories, in +favor of a centralized policy for issue reporting. Tickets concerning, for +example, bugs or enhancements in modules shall be opened in the main +zephyr repository. Issues should be appropriately labeled using GitHub +labels corresponding to each module, where applicable. + + .. note:: + + It is allowed to file bug reports for zephyr modules to track + the corresponding upstream project bugs in Zephyr. These bug reports + shall not affect the + :ref:`Release Quality Criteria`. + + +.. _modules_licensing: + +Licensing requirements and policies +*********************************** + +All source files in a module's codebase shall include a license header, +unless the module repository has **main license file** that covers source +files that do not include license headers. + +Main license files shall be added in the module's codebase by Zephyr +developers, only if they exist as part of the external project, +and they contain a permissive OSI-compliant license. Main license files +should preferably contain the full license text instead of including an +SPDX license identifier. If multiple main license files are present it +shall be made clear which license applies to each source file in a module's +codebase. + +Individual license headers in module source files supersede the main license. + +Any new content to be added in a module repository will require to have +license coverage. + + .. note:: + + Zephyr recommends conveying module licensing via individual license + headers and main license files. This not a hard requirement; should + an external project have its own practice of conveying how licensing + applies in the module's codebase (for example, by having a single or + multiple main license files), this practice may be accepted by and + be referred to in the Zephyr module, as long as licensing requirements, + for example OSI compliance, are satisfied. + +License policies +================ + +When creating a module repository a developer shall: + +* import the main license files, if they exist in the external project, and +* document (for example in the module README or .yml file) the default license + that covers the module's codebase. + +License checks +-------------- + +License checks (via CI tools) shall be enabled on every pull request that +adds new content in module repositories. + + +Documentation requirements +************************** + +All Zephyr module repositories shall include an .rst file documenting: + +* the scope and the purpose of the module +* how the module integrates with Zephyr +* the owner of the module repository +* synchronization information with the external project (commit, SHA, version etc.) +* licensing information as described in :ref:`modules_licensing`. + +The file shall be required for the inclusion of the module and the contained +information should be kept up to date. + + +Testing requirements +******************** + +All Zephyr modules should provide some level of **integration** testing, +ensuring that the integration with Zephyr works correctly. +Integration tests: + +* may be in the form of a minimal set of samples and tests that reside + in the zephyr main tree +* should verify basic usage of the module (configuration, + functional APIs, etc.) that is integrated with Zephyr. +* shall be built and executed (for example in QEMU) as part of + twister runs in pull requests that introduce changes in module + repositories. + + .. note:: + + New modules, that are candidates for being included in the Zephyr + default manifest, shall provide some level of integration testing. + + .. note:: + + Vendor HALs are implicitly tested via Zephyr tests built or executed + on target platforms, so they do not need to provide integration tests. + +The purpose of integration testing is not to provide functional verification +of the module; this should be part of the testing framework of the external +project. + +Certain external projects provide test suites that reside in the upstream +testing infrastructure but are written explicitly for Zephyr. These tests +may (but are not required to) be part of the Zephyr test framework. + +Deprecating and removing modules +********************************* + +Modules may be deprecated for reasons including, but not limited to: + +* Lack of maintainership in the module +* Licensing changes in the external project +* Codebase becoming obsolete + +The module information shall indicate whether a module is +deprecated and the build system shall issue a warning +when trying to build Zephyr using a deprecated module. + +Deprecated modules may be removed from the Zephyr default manifest +after 2 Zephyr releases. + + .. note:: + + Repositories of removed modules shall remain accessible via their + original URL, as they are required by older Zephyr versions. + + +Integrate modules in Zephyr build system +**************************************** + The build system variable :makevar:`ZEPHYR_MODULES` is a `CMake list`_ of absolute paths to the directories containing Zephyr modules. These modules contain :file:`CMakeLists.txt` and :file:`Kconfig` files describing how to @@ -40,67 +398,186 @@ Finally, you can also specify the list of modules yourself in various ways, or not use modules at all if your application doesn't need them. +Module yaml file description +**************************** -Module Inclusion -**************** +A module can be described using a file named :file:`zephyr/module.yml`. +The format of :file:`zephyr/module.yml` is described in the following: -.. _modules_using_west: -Using West -========== +Build files +=========== -If west is installed and :makevar:`ZEPHYR_MODULES` is not already set, the -build system finds all the modules in your :term:`west installation` and uses -those. It does this by running :ref:`west list ` to get -the paths of all the projects in the installation, then filters the results to -just those projects which have the necessary module metadata files. +Inclusion of build files, :file:`CMakeLists.txt` and :file:`Kconfig`, can be +described as: -Each project in the ``west list`` output is tested like this: +.. code-block:: yaml + + build: + cmake: + kconfig: /Kconfig + +The ``cmake: `` part specifies that +:file:`` contains the :file:`CMakeLists.txt` to use. The +``kconfig: /Kconfig`` part specifies the Kconfig file to use. +Neither is required: ``cmake`` defaults to ``zephyr``, and ``kconfig`` +defaults to ``zephyr/Kconfig``. + +Here is an example :file:`module.yml` file referring to +:file:`CMakeLists.txt` and :file:`Kconfig` files in the root directory of the +module: + +.. code-block:: yaml + + build: + cmake: . + kconfig: Kconfig + + +Build system integration +======================== + +When a module has a :file:`module.yml` file, it will automatically be included into +the Zephyr build system. The path to the module is then accessible through Kconfig +and CMake variables. + +In both Kconfig and CMake, the variable ``ZEPHYR__MODULE_DIR`` +contains the absolute path to the module. + +In CMake, ``ZEPHYR__CMAKE_DIR`` contains the +absolute path to the directory containing the :file:`CMakeLists.txt` file that +is included into CMake build system. This variable's value is empty if the +module.yml file does not specify a CMakeLists.txt. + +To read these variables for a Zephyr module named ``foo``: + +- In CMake: use ``${ZEPHYR_FOO_MODULE_DIR}`` for the module's top level directory, and ``${ZEPHYR_FOO_CMAKE_DIR}`` for the directory containing its :file:`CMakeLists.txt` +- In Kconfig: use ``$(ZEPHYR_FOO_MODULE_DIR)`` for the module's top level directory + +Notice how a lowercase module name ``foo`` is capitalized to ``FOO`` +in both CMake and Kconfig. + +These variables can also be used to test whether a given module exists. +For example, to verify that ``foo`` is the name of a Zephyr module: + +.. code-block:: cmake + + if(ZEPHYR_FOO_MODULE_DIR) + # Do something if FOO exists. + endif() -- If the project contains a file named :file:`zephyr/module.yml`, then - its contents should look like this: +In Kconfig, the variable may be used to find additional files to include. +For example, to include the file :file:`some/Kconfig` in module ``foo``: - .. code-block:: yaml +.. code-block:: kconfig - build: - cmake: - kconfig: /Kconfig + source "$(ZEPHYR_FOO_MODULE_DIR)/some/Kconfig" - The ``cmake: `` part specifies that - :file:`` contains the :file:`CMakeLists.txt` to use. The - ``kconfig: /Kconfig`` part specifies the Kconfig file to use. - Neither is required: ``cmake`` defaults to ``zephyr``, and ``kconfig`` - defaults to ``zephyr/Kconfig``. +During CMake processing of each Zephyr module, the following two variables are +also available: - Here is an example :file:`module.yml` file referring to - :file:`CMakeLists.txt` and :file:`Kconfig` files in the root directory of the - module: +- the current module's top level directory: ``${ZEPHYR_CURRENT_MODULE_DIR}`` +- the current module's :file:`CMakeLists.txt` directory: ``${ZEPHYR_CURRENT_CMAKE_DIR}`` - .. code-block:: yaml +This removes the need for a Zephyr module to know its own name during CMake +processing. The module can source additional CMake files using these ``CURRENT`` +variables. For example: - build: - cmake: . - kconfig: Kconfig +.. code-block:: cmake -- To execute both tests and samples available in modules, the Zephyr test runner - (sanitycheck) should be pointed to the directories containing those samples and - tests. This can be done by specifying the path to both samples and tests in the - :file:`zephyr/module.yml` file. Additionally, if a module defines out of tree - boards, the module file can point sanitycheck to the path where those files - are maintained in the module. For example: + include(${ZEPHYR_CURRENT_MODULE_DIR}/cmake/code.cmake) +.. _modules_build_settings: - .. code-block:: yaml +Build settings +============== - build: - cmake: . - samples: - - samples - tests: - - tests - boards: - - boards +It is possible to specify additional build settings that must be used when +including the module into the build system. +All ``root`` settings are relative to the root of the module. + +Build settings supported in the :file:`module.yml` file are: + +- ``board_root``: Contains additional boards that are available to the build + system. Additional boards must be located in a :file:`/boards` + folder. +- ``dts_root``: Contains additional dts files related to the architecture/soc + families. Additional dts files must be located in a :file:`/dts` + folder. +- ``soc_root``: Contains additional SoCs that are available to the build + system. Additional SoCs must be located in a :file:`/soc` folder. +- ``arch_root``: Contains additional architectures that are available to the + build system. Additional architectures must be located in a + :file:`/arch` folder. + +Example of a :file:`module.yaml` file containing additional roots, and the +corresponding file system layout. + +.. code-block:: yaml + + build: + settings: + board_root: . + dts_root: . + soc_root: . + arch_root: . + + +requires the following folder structure: + +.. code-block:: none + + + ├── arch + ├── boards + ├── dts + └── soc + + + +Sanitycheck +=========== + +To execute both tests and samples available in modules, the Zephyr test runner +(twister) should be pointed to the directories containing those samples and +tests. This can be done by specifying the path to both samples and tests in the +:file:`zephyr/module.yml` file. Additionally, if a module defines out of tree +boards, the module file can point twister to the path where those files +are maintained in the module. For example: + + +.. code-block:: yaml + + build: + cmake: . + samples: + - samples + tests: + - tests + boards: + - boards + + +Module Inclusion +================ + +.. _modules_using_west: + +Using West +---------- + +If west is installed and :makevar:`ZEPHYR_MODULES` is not already set, the +build system finds all the modules in your :term:`west installation` and uses +those. It does this by running :ref:`west list ` to get +the paths of all the projects in the installation, then filters the results to +just those projects which have the necessary module metadata files. + +Each project in the ``west list`` output is tested like this: + +- If the project contains a file named :file:`zephyr/module.yml`, then the + content of that file will be used to determine which files should be added + to the build, as described in the previous section. - Otherwise (i.e. if the project has no :file:`zephyr/module.yml`), the build system looks for :file:`zephyr/CMakeLists.txt` and @@ -111,7 +588,7 @@ Each project in the ``west list`` output is tested like this: and is not added to :makevar:`ZEPHYR_MODULES`. Without West -============ +------------ If you don't have west installed or don't want the build system to use it to find Zephyr modules, you can set :makevar:`ZEPHYR_MODULES` yourself using one @@ -131,10 +608,10 @@ section. .. code-block:: cmake set(ZEPHYR_MODULES [...]) - include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) + find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) - If you choose this option, make sure to set the variable **before** including - the boilerplate file, as shown above. + If you choose this option, make sure to set the variable **before** calling + ``find_package(Zephyr ...)``, as shown above. #. In a separate CMake script which is pre-loaded to populate the CMake cache, like this: @@ -149,7 +626,7 @@ section. zephyr-modules.cmake`` to your CMake command line. Not using modules -================= +----------------- If you don't have west installed and don't specify :makevar:`ZEPHYR_MODULES` yourself, then no additional modules are added to the build. You will still be @@ -167,7 +644,7 @@ Zephyr needs a reference to the changes to be able to verify the changes. In the main tree this is done using revisions. For code that is already merged and part of the tree we use the commit hash, a tag, or a branch name. For pull requests however, we require specifying the pull request number in the revision field to -allow building the Zephyr main tree with the changes submitted to the +allow building the zephyr main tree with the changes submitted to the module. To avoid merging changes to master with pull request information, the pull @@ -182,16 +659,8 @@ using exactly the same process. In this case you will change multiple entries of all modules that have a pull request against them. -Submitting a new module -======================== - -Requirements -------------- - -Modules to be included in the default manifest of the Zephyr project need to -provide functionality or features endorsed and approved by the project technical -steering committee and should follow the project licensing and -:ref:`contribute_guidelines`. +Process for submitting a new module +=================================== A request for a new module should be initialized using an RFC issue in the Zephyr project issue tracking system with details about the module and how it @@ -200,15 +669,10 @@ created by the project team and initialized with basic information that would allow submitting code to the module project following the project contribution guidelines. -All modules should be hosted in repositories under the Zephyr organization. The -manifest should only point to repositories maintained under the Zephyr project. If a module is maintained as a fork of another project on Github, the Zephyr module related files and changes in relation to upstream need to be maintained in a special branch named ``zephyr``. -Process -------- - Follow the following steps to request a new module: #. Use `GitHub issues`_ to open an issue with details about the module to be @@ -244,8 +708,8 @@ revision needs to be changed to the commit hash from the module repository. .. _changes_to_existing_module: -Changes to existing modules -=========================== +Process for submitting changes to existing modules +================================================== #. Submit the changes using a pull request to an existing repository following the :ref:`contribution guidelines `. diff --git a/doc/guides/networking/net-stack-architecture.rst b/doc/guides/networking/net-stack-architecture.rst index c73519b54081f0..aea3c2cc82aac9 100644 --- a/doc/guides/networking/net-stack-architecture.rst +++ b/doc/guides/networking/net-stack-architecture.rst @@ -3,6 +3,12 @@ Network Stack Architecture ########################## +.. toctree:: + :maxdepth: 1 + :hidden: + + net_pkt_processing_stats.rst + The Zephyr network stack is a native network stack specifically designed for Zephyr OS. It consists of layers, each meant to provide certain services to other layers. Network stack functionality is highly configurable via Kconfig @@ -156,3 +162,10 @@ one :ref:`thread ` to another. These :ref:`threads ` might run in different contexts (:ref:`kernel ` vs. :ref:`userspace `) and with different :ref:`priorities `. + + +Network packet processing statistics +************************************ + +See information about network processing statistics +:ref:`here `. diff --git a/doc/guides/networking/net_pkt_processing_stats.rst b/doc/guides/networking/net_pkt_processing_stats.rst new file mode 100644 index 00000000000000..b57d6f48679620 --- /dev/null +++ b/doc/guides/networking/net_pkt_processing_stats.rst @@ -0,0 +1,84 @@ +.. _net_pkt_processing_stats: + +Network Packet Processing Statistics +#################################### + +.. contents:: + :local: + :depth: 2 + +This page describes how to get information about network packet processing +statistics inside network stack. + +Network stack contains infrastructure to figure out how long the network packet +processing takes either in sending or receiving path. There are two Kconfig +options that control this. For transmit (TX) path the option is called +:option:`CONFIG_NET_PKT_TXTIME_STATS` and for receive (RX) path the options is +called :option:`CONFIG_NET_PKT_RXTIME_STATS`. Note that for TX, all kind of +network packet statistics is collected. For RX, only UDP, TCP or raw packet +type network packet statistics is collected. + +After enabling these options, the :ref:`net stats ` network shell +command will show this information: + +.. code-block:: console + + Avg TX net_pkt (11484) time 67 us + Avg RX net_pkt (11474) time 43 us + +.. note:: + + The values above and below are from emulated qemu_x86 board and UDP traffic + +The TX time tells how long it took for network packet from its creation to +when it was sent to the network. The RX time tells the time from its creation +to when it was passed to the application. The values are in microseconds. The +statistics will be collected per traffic class if there are more than one +transmit or receive queues defined in the system. These are controlled by +:option:`CONFIG_NET_TC_TX_COUNT` and :option:`CONFIG_NET_TC_RX_COUNT` options. + +If you enable :option:`CONFIG_NET_PKT_TXTIME_STATS_DETAIL` or +:option:`CONFIG_NET_PKT_RXTIME_STATS_DETAIL` options, then additional +information for TX or RX network packets are collected when the network packet +traverses the IP stack. + +After enabling these options, the :ref:`net stats ` will show +this information: + +.. code-block:: console + + Avg TX net_pkt (18902) time 63 us [0->22->15->23=60 us] + Avg RX net_pkt (18892) time 42 us [0->9->6->11->13=39 us] + +The numbers inside the brackets contain information how many microseconds it +took for a network packet to go from previous state to next. + +In the TX example above, the values are averages over **18902** packets and +contain this information: + +* Packet was created by application so the time is **0**. +* Packet is about to be placed to transmit queue. The time it took from network + packet creation to this state, is **22** microseconds in this example. +* The correct TX thread is invoked, and the packet is read from the transmit + queue. It took **15** microseconds from previous state. +* The network packet was just sent and the network stack is about to free the + network packet. It took **23** microseconds from previous state. +* In total it took on average **60** microseconds to get the network packet + sent. The value **63** tells also the same information, but is calculated + differently so there is slight difference because of rounding errors. + +In the RX example above, the values are averages over **18892** packets and +contain this information: + +* Packet was created network device driver so the time is **0**. +* Packet is about to be placed to receive queue. The time it took from network + packet creation to this state, is **9** microseconds in this example. +* The correct RX thread is invoked, and the packet is read from the receive + queue. It took **6** microseconds from previous state. +* The network packet is then processed and placed to correct socket queue. + It took **11** microseconds from previous state. +* The last value tells how long it took from there to the application. Here + the value is **13** microseconds. +* In total it took on average **39** microseconds to get the network packet + sent. The value **42** tells also the same information, but is calculated + differently so there is slight difference because of rounding errors. diff --git a/doc/guides/networking/networking_with_host.rst b/doc/guides/networking/networking_with_host.rst index 746168d2feeeeb..32bd7e291c4c90 100644 --- a/doc/guides/networking/networking_with_host.rst +++ b/doc/guides/networking/networking_with_host.rst @@ -13,6 +13,7 @@ Networking with the host system usbnet_setup.rst qemu_user_setup.rst networking_with_multiple_instances.rst + qemu_802154_setup.rst While developing networking software, it is usually necessary to connect and exchange data with the host system like a Linux desktop computer. @@ -61,3 +62,9 @@ possible: * If you have multiple Zephyr instances, either QEMU or native_posix ones, and want to create a connection between them, see :ref:`networking_with_multiple_instances` for details. + +* Simulating IEEE 802.15.4 network between two QEMUs. + + * Here, two Zephyr instances are running and there is IEEE 802.15.4 link layer + run over an UART between them. + See :ref:`networking_with_ieee802154_qemu` for details. diff --git a/doc/guides/networking/qemu_802154_setup.rst b/doc/guides/networking/qemu_802154_setup.rst new file mode 100644 index 00000000000000..0e6f0af6aa8ab2 --- /dev/null +++ b/doc/guides/networking/qemu_802154_setup.rst @@ -0,0 +1,77 @@ +.. _networking_with_ieee802154_qemu: + +Networking with QEMU and IEEE 802.15.4 +###################################### + +.. contents:: + :local: + :depth: 2 + +This page describes how to set up a virtual network between two QEMUs that +are connected together via UART and are running IEEE 802.15.4 link layer +between them. Note that this only works in Linux host. + +Basic Setup +*********** + +For the steps below, you will need two terminal windows: + +* Terminal #1 is terminal window with ``echo-server`` Zephyr sample application. +* Terminal #2 is terminal window with ``echo-client`` Zephyr sample application. + +If you want to capture the transferred network data, you must compile the +``monitor_15_4`` program in ``net-tools`` directory. + +Open a terminal window and type: + +.. code-block:: console + + cd $ZEPHYR_BASE/../net-tools + make monitor_15_4 + + +Step 1 - Compile and start echo-server +====================================== + +In terminal #1, type: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_server + :host-os: unix + :board: qemu_x86 + :build-dir: server + :gen-args: -DOVERLAY_CONFIG=overlay-qemu_802154.conf + :goals: server + :compact: + +If you want to capture the network traffic between the two QEMUs, type: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_server + :host-os: unix + :board: qemu_x86 + :build-dir: server + :gen-args: -G'Unix Makefiles' -DOVERLAY_CONFIG=overlay-qemu_802154.conf -DPCAP=capture.pcap + :goals: server + :compact: + +Note that the ``make`` must be used for ``server`` target if packet capture +option is set in command line. The ``build/server/capture.pcap`` file will contain the +transferred data. + +Step 2 - Compile and start echo-client +====================================== + +In terminal #2, type: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_client + :host-os: unix + :board: qemu_x86 + :build-dir: client + :gen-args: -DOVERLAY_CONFIG=overlay-qemu_802154.conf + :goals: client + :compact: + +You should see data passed between the two QEMUs. +Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`. diff --git a/doc/guides/optimizations/index.rst b/doc/guides/optimizations/index.rst index cddc5f6b029906..0a94b501ef050b 100644 --- a/doc/guides/optimizations/index.rst +++ b/doc/guides/optimizations/index.rst @@ -9,3 +9,4 @@ Guides on how to optimize Zephyr for performance, power and footprint. :maxdepth: 1 footprint.rst + tools.rst diff --git a/doc/guides/optimizations/tools.rst b/doc/guides/optimizations/tools.rst new file mode 100644 index 00000000000000..39e8b8f3fece60 --- /dev/null +++ b/doc/guides/optimizations/tools.rst @@ -0,0 +1,219 @@ +.. _optimization_tools: + +Optimization Tools +################## + +.. _footprint_tools: + +Footprint and Memory Usage +************************** + +The build system offers 3 targets to view and analyse RAM, ROM and stack usage +in generated images. The tools run on the final image and give information +about size of symbols and code being used in both RAM and ROM. Additionally, +with features available through the compiler, we can also generate worst-case +stack usage analysis: + +Tools that are available as build system targets: + +Build Target: puncover +====================== + +This target uses a 3rd party tools called puncover which can be found `here +`_. When this target is built, it will +launch a local web server which will allow you to open a web client and browse +the files and view their ROM, RAM and stack usage. Before you can use this +target, you will have to install the puncover python module:: + + pip3 install git+https://github.com/HBehrens/puncover --user + + +Then: + +.. zephyr-app-commands:: + :tool: all + :app: samples/hello_world + :board: reel_board + :goals: puncover + + +To view worst-case stack usage analysis, build this with the +:option:`CONFIG_STACK_USAGE` enabled. + +.. zephyr-app-commands:: + :tool: all + :app: samples/hello_world + :board: reel_board + :goals: puncover + :gen-args: -DCONFIG_STACK_USAGE=y + + +Build Target: ram_report +======================== + +List all compiled objects and their RAM usage in a tabular form with bytes +per symbol and the percentage it uses. The data is grouped based on the file +system location of the object in the tree and the file containing the symbol. + +Use the ``ram_report`` target with your board: + +.. zephyr-app-commands:: + :tool: all + :app: samples/hello_world + :board: reel_board + :goals: ram_report + +which will generate something similar to the output below:: + + Path Size % + ============================================================================================================== + ... + ... + SystemCoreClock 4 0.08% + _kernel 48 0.99% + _sw_isr_table 384 7.94% + cli.10544 16 0.33% + gpio_initialized.9765 1 0.02% + on.10543 4 0.08% + poll_out_lock.9764 4 0.08% + z_idle_threads 128 2.65% + z_interrupt_stacks 2048 42.36% + z_main_thread 128 2.65% + arch 1 0.02% + arm 1 0.02% + core 1 0.02% + aarch32 1 0.02% + cortex_m 1 0.02% + mpu 1 0.02% + arm_mpu.c 1 0.02% + static_regions_num 1 0.02% + drivers 536 11.09% + clock_control 100 2.07% + nrf_power_clock.c 100 2.07% + __device_clock_nrf 16 0.33% + data 80 1.65% + hfclk_users 4 0.08% + ... + ... + + +Build Target: rom_report +======================== + +List all compiled objects and their ROM usage in a tabular form with bytes +per symbol and the percentage it uses. The data is grouped based on the file +system location of the object in the tree and the file containing the symbol. + +Use the ``rom_report`` to get the ROM report: + +.. zephyr-app-commands:: + :tool: all + :app: samples/hello_world + :board: reel_board + :goals: rom_report + +which will generate something similar to the output below:: + + Path Size % + ============================================================================================================== + ... + ... + CSWTCH.5 4 0.02% + SystemCoreClock 4 0.02% + __aeabi_idiv0 2 0.01% + __udivmoddi4 702 3.37% + _sw_isr_table 384 1.85% + delay_machine_code.9114 6 0.03% + levels.8826 20 0.10% + mpu_config 8 0.04% + transitions.10558 12 0.06% + arch 1194 5.74% + arm 1194 5.74% + core 1194 5.74% + aarch32 1194 5.74% + cortex_m 852 4.09% + fault.c 400 1.92% + bus_fault.isra.0 60 0.29% + mem_manage_fault.isra.0 56 0.27% + usage_fault.isra.0 36 0.17% + z_arm_fault 232 1.11% + z_arm_fault_init 16 0.08% + irq_init.c 24 0.12% + z_arm_interrupt_init 24 0.12% + mpu 352 1.69% + arm_core_mpu.c 56 0.27% + z_arm_configure_static_mpu_regions 56 0.27% + arm_mpu.c 296 1.42% + __init_sys_init_arm_mpu_init0 8 0.04% + arm_core_mpu_configure_static_mpu_regions 20 0.10% + arm_core_mpu_disable 16 0.08% + arm_core_mpu_enable 20 0.10% + arm_mpu_init 92 0.44% + mpu_configure_regions 140 0.67% + thread_abort.c 76 0.37% + z_impl_k_thread_abort + 76 0.37% + ... + ... + + +Data Structures +**************** + + +Build Target: pahole +===================== + +Poke-a-hole (pahole) is an object-file analysis tool to find the size of +the data structures, and the holes caused due to aligning the data +elements to the word-size of the CPU by the compiler. + +Poke-a-hole (pahole) must be installed prior to using this target. It can be +obtained from https://git.kernel.org/pub/scm/devel/pahole/pahole.git and is +available in the dwarves package in both fedora and ubuntu:: + + sudo apt-get install dwarves + +or in fedora:: + + sudo dnf install dwarves + + +.. zephyr-app-commands:: + :tool: all + :app: samples/hello_world + :board: reel_board + :goals: pahole + + +After running this target, pahole will output the results to the console:: + + /* Used at: zephyr/isr_tables.c */ + /* <80> ../include/sw_isr_table.h:30 */ + struct _isr_table_entry { + void * arg; /* 0 4 */ + void (*isr)(void *); /* 4 4 */ + + /* size: 8, cachelines: 1, members: 2 */ + /* last cacheline: 8 bytes */ + }; + /* Used at: zephyr/isr_tables.c */ + /* ../include/arch/arm/aarch32/cortex_m/mpu/arm_mpu_v7m.h:134 */ + struct arm_mpu_region_attr { + uint32_t rasr; /* 0 4 */ + + /* size: 4, cachelines: 1, members: 1 */ + /* last cacheline: 4 bytes */ + }; + /* Used at: zephyr/isr_tables.c */ + /* <112> ../include/arch/arm/aarch32/cortex_m/mpu/arm_mpu.h:24 */ + struct arm_mpu_region { + uint32_t base; /* 0 4 */ + const char * name; /* 4 4 */ + arm_mpu_region_attr_t attr; /* 8 4 */ + + /* size: 12, cachelines: 1, members: 3 */ + /* last cacheline: 12 bytes */ + }; + ... + ... diff --git a/doc/guides/portability/posix.rst b/doc/guides/portability/posix.rst index 6562a6fabe5a21..b3edcf2d544ace 100644 --- a/doc/guides/portability/posix.rst +++ b/doc/guides/portability/posix.rst @@ -261,9 +261,9 @@ This is implemented as part of the minimal C library available in Zephyr. isspace(),+ isupper(),+ isxdigit(),+ - labs(), + labs(),+ ldiv(), - llabs(), + llabs(),+ lldiv(), localeconv(), localtime(),+ @@ -283,40 +283,40 @@ This is implemented as part of the minimal C library available in Zephyr. snprintf(),+ sprintf(),+ srand(), - canf(), + sscanf(), strcat(),+ strchr(),+ strcmp(),+ strcoll(), strcpy(),+ - trcspn(), + strcspn(), strerror(), strerror_r(), strftime(), strlen(),+ - trncat(),+ + strncat(),+ strncmp(),+ strncpy(),+ strpbrk(), strrchr(),+ - trspn(), + strspn(), strstr(),+ strtod(), strtof(), strtoimax(), - trtok(), - strtok_r(), + strtok(), + strtok_r(),+ strtol(),+ strtold(), strtoll(), - trtoul(),+ + strtoul(),+ strtoull(), strtoumax(), strxfrm(), time(),+ tolower(),+ toupper(),+ - tzname, + tzname(), tzset(), va_arg(), va_copy(), diff --git a/doc/guides/porting/arch.rst b/doc/guides/porting/arch.rst index 12a44eca60dc5b..8ca43d2e943152 100644 --- a/doc/guides/porting/arch.rst +++ b/doc/guides/porting/arch.rst @@ -144,10 +144,10 @@ parameter. Each architecture also has to implement primitives for interrupt control: -* locking interrupts: :c:func:`irq_lock`, :c:func:`irq_unlock`. -* registering interrupts: :c:func:`IRQ_CONNECT`. +* locking interrupts: :c:macro:`irq_lock()`, :c:macro:`irq_unlock()`. +* registering interrupts: :c:macro:`IRQ_CONNECT()`. * programming the priority if possible :c:func:`irq_priority_set`. -* enabling/disabling interrupts: :c:func:`irq_enable`, :c:func:`irq_disable`. +* enabling/disabling interrupts: :c:macro:`irq_enable()`, :c:macro:`irq_disable()`. .. note:: @@ -297,10 +297,34 @@ mode if the thread triggered a fatal exception, but not if the thread gracefully exits its entry point function. This means implementing an architecture-specific version of -:cpp:func:`k_thread_abort`, and setting the Kconfig option +:c:func:`k_thread_abort`, and setting the Kconfig option :option:`CONFIG_ARCH_HAS_THREAD_ABORT` as needed for the architecture (e.g. see :zephyr_file:`arch/arm/core/aarch32/cortex_m/Kconfig`). +Thread Local Storage +******************** + +To enable thread local storage on a new architecture: + +#. Implement :c:func:`arch_tls_stack_setup` to setup the TLS storage area in + stack. Refer to the toolchain documentation on how the storage area needs + to be structured. Some helper functions can be used: + + * Function :c:func:`z_tls_data_size` returns the size + needed for thread local variables (excluding any extra data required by + toolchain and architecture). + * Function :c:func:`z_tls_copy` prepares the TLS storage area for + thread local variables. This only copies the variable themselves and + does not do architecture and/or toolchain specific data. + +#. In the context switching, grab the ``tls`` field inside the new thread's + ``struct k_thread`` and put it into an appropriate register (or some + other variable) for access to the TLS storage area. Refer to toolchain + and architecture documentation on which registers to use. +#. In kconfig, add ``select CONFIG_ARCH_HAS_THREAD_LOCAL_STORAGE`` to + kconfig related to the new architecture. +#. Run the ``tests/kernel/threads/tls`` to make sure the new code works. + Device Drivers ************** @@ -460,8 +484,99 @@ be derived from the linker scripts of other architectures. Some sections might be specific to the new architecture, for example the SCB section on ARM and the IDT section on x86. -Hardware Stack Protection -========================= +Memory Management +***************** + +If the target platform enables paging and requires drivers to memory-map +their I/O regions, :option:`CONFIG_MMU` needs to be enabled and the +:c:func:`arch_mem_map` API implemented. + +Stack Objects +************* + +The presence of memory protection hardware affects how stack objects are +created. All architecture ports must specify the required alignment of the +stack pointer, which is some combination of CPU and ABI requirements. This +is defined in architecture headers with :c:macro:`ARCH_STACK_PTR_ALIGN` and +is typically something small like 4, 8, or 16 bytes. + +Two types of thread stacks exist: + +- "kernel" stacks defined with :c:macro:`K_KERNEL_STACK_DEFINE()` and related + APIs, which can host kernel threads running in supervisor mode or + used as the stack for interrupt/exception handling. These have significantly + relaxed alignment requirements and use less reserved data. No memory is + reserved for prvilege elevation stacks. + +- "thread" stacks which typically use more memory, but are capable of hosting + thread running in user mode, as well as any use-cases for kernel stacks. + +If :c:option:`CONFIG_USERSPACE` is not enabled, "thread" and "kernel" stacks +are equivalent. + +Additional macros may be defined in the architecture layer to specify +the alignment of the base of stack objects, any reserved data inside the +stack object not used for the thread's stack buffer, and how to round up +stack sizes to support user mode threads. In the absence of definitions +some defaults are assumed: + +- :c:macro:`ARCH_KERNEL_STACK_RESERVED`: default no reserved space +- :c:macro:`ARCH_THREAD_STACK_RESERVED`: default no reserved space +- :c:macro:`ARCH_KERNEL_STACK_OBJ_ALIGN`: default align to + :c:macro:`ARCH_STACK_PTR_ALIGN` +- :c:macro:`ARCH_THREAD_STACK_OBJ_ALIGN`: default align to + :c:macro:`ARCH_STACK_PTR_ALIGN` +- :c:macro:`ARCH_THREAD_STACK_SIZE_ALIGN`: default round up to + :c:macro:`ARCH_STACK_PTR_ALIGN` + +All stack creation macros are defined in terms of these. + +Stack objects all have the following layout, with some regions potentially +zero-sized depending on configuration. There are always two main parts: +reserved memory at the beginning, and then the stack buffer itself. The +bounds of some areas can only be determined at runtime in the context of +its associated thread object. Other areas are entirely computable at build +time. + +Some architectures may need to carve-out reserved memory at runtime from the +stack buffer, instead of unconditionally reserving it at build time, or to +supplement an existing reserved area (as is the case with the ARM FPU). +Such carve-outs will always be tracked in ``thread.stack_info.start``. +The region specified by ``thread.stack_info.start`` and +``thread.stack_info.size`` is always fully accessible by a user mode thread. +``thread.stack_info.delta`` denotes an offset which can be used to compute +the initial stack pointer from the very end of the stack object, taking into +account storage for TLS and ASLR random offsets. + +:: + + +---------------------+ <- thread.stack_obj + | Reserved Memory | } K_(THREAD|KERNEL)_STACK_RESERVED + +---------------------+ + | Carved-out memory | + |.....................| <- thread.stack_info.start + | Unused stack buffer | + | | + |.....................| <- thread's current stack pointer + | Used stack buffer | + | | + |.....................| <- Initial stack pointer. Computable + | ASLR Random offset | with thread.stack_info.delta + +---------------------| <- thread.userspace_local_data + | Thread-local data | + +---------------------+ <- thread.stack_info.start + + thread.stack_info.size + + +At present, Zephyr does not support stacks that grow upward. + +No Memory Protection +==================== + +If no memory protection is in use, then the defaults are sufficient. + +HW-based stack overflow detection +================================= This option uses hardware features to generate a fatal error if a thread in supervisor mode overflows its stack. This is useful for debugging, although @@ -470,6 +585,7 @@ of the system after this happens: * The kernel could have been inside a critical section when the overflow occurs, leaving important global data structures in a corrupted state. + * For systems that implement stack protection using a guard memory region, it's possible to overshoot the guard and corrupt adjacent data structures before the hardware detects this situation. @@ -478,68 +594,243 @@ To enable the :option:`CONFIG_HW_STACK_PROTECTION` feature, the system must provide some kind of hardware-based stack overflow protection, and enable the :option:`CONFIG_ARCH_HAS_STACK_PROTECTION` option. -There are no C APIs that need to be implemented to support stack protection, -and it's entirely implemented within the ``arch/`` code. However in most cases -(such as if a guard region needs to be defined) the architecture will need to -declare its own versions of the K_THREAD_STACK macros in ``arch/cpu.h``: +Two forms of HW-based stack overflow detection are supported: dedicated +CPU features for this purpose, or special read-only guard regions immediately +preceding stack buffers. -* :c:macro:`_ARCH_THREAD_STACK_DEFINE()` -* :c:macro:`_ARCH_THREAD_STACK_ARRAY_DEFINE()` -* :c:macro:`_ARCH_THREAD_STACK_MEMBER()` -* :c:macro:`_ARCH_THREAD_STACK_SIZEOF()` +:option:`CONFIG_HW_STACK_PROTECTION` only catches stack overflows for +supervisor threads. This is not required to catch stack overflow from user +threads; :option:`CONFIG_USERSPACE` is orthogonal. -For systems that implement stack protection using a Memory Protection Unit -(MPU) or Memory Management Unit (MMU), this is typically done by declaring a -guard memory region immediately before the stack area. +This feature only detects supervisor mode stack overflows, including stack +overflows when handling system calls. It doesn't guarantee that the kernel has +not been corrupted. Any stack overflow in supervisor mode should be treated as +a fatal error, with no assertions about the integrity of the overall system +possible. -* On MMU systems, this guard area is an entire page whose permissions in the - page table will generate a fault on writes. This page needs to be - configured in the arch's _new_thread() function. +Stack overflows in user mode are recoverable (from the kernel's perspective) +and require no special configuration; :option:`CONFIG_HW_STACK_PROTECTION` +only applies to catching overflows when the CPU is in sueprvisor mode. -* On MPU systems, one of the MPU regions needs to be reserved for the thread - stack guard area, whose size should be minimized. The region in the MPU - should be reconfigured on context switch such that the guard region - for the incoming thread is not writable. +CPU-based stack overflow detection +---------------------------------- -User Mode Threads +If we are detecting stack overflows in supervisor mode via special CPU +registers (like ARM's SPLIM), then the defaults are sufficient. + + + +Guard-based stack overflow detection +------------------------------------ + +We are detecting supervisor mode stack overflows via special memory protection +region located immediately before the stack buffer that generates an exception +on write. Reserved memory will be used for the guard region. + +:c:macro:`ARCH_KERNEL_STACK_RESERVED` should be defined to the minimum size +of a memory protection region. On most ARM CPUs this is 32 bytes. +:c:macro:`ARCH_KERNEL_STACK_OBJ_ALIGN` should also be set to the required +alignment for this region. + +MMU-based systems should not reserve RAM for the guard region and instead +simply leave an non-present virtual page below every stack when it is mapped +into the address space. The stack object will still need to be properly aligned +and sized to page granularity. + +:: + + +-----------------------------+ <- thread.stack_obj + | Guard reserved memory | } K_KERNEL_STACK_RESERVED + +-----------------------------+ + | Guard carve-out | + |.............................| <- thread.stack_info.start + | Stack buffer | + . . + +Guard carve-outs for kernel stacks are uncommon and should be avoided if +possible. They tend to be needed for two situations: + +* The same stack may be re-purposed to host a user thread, in which case + the guard is unnecessary and shouldn't be unconditionally reserved. + This is the case when privilege elevation stacks are not inside the stack + object. + +* The required guard size is variable and depends on context. For example, some + ARM CPUs have lazy floating point stacking during exceptions and may + decrement the stack pointer by a large value without writing anything, + completely overshooting a minimally-sized guard and corrupting adjacent + memory. Rather than unconditionally reserving a larger guard, the extra + memory is carved out if the thread uses floating point. + +User mode enabled ================= +Enabling user mode activates two new requirements: + +* A separate fixed-sized privilege mode stack, specified by + :option:`CONFIG_PRIVILEGED_STACK_SIZE`, must be allocated that the user + thread cannot access. It is used as the stack by the kernel when handling + system calls. If stack guards are implemented, a stack guard region must + be able to be placed before it, with support for carve-outs if necessary. + +* The memory protection hardware must be able to program a region that exactly + covers the thread's stack buffer, tracked in ``thread.stack_info``. This + implies that :c:macro:`ARCH_THREAD_STACK_SIZE_ADJUST()` will need to round + up the requested stack size so that a region may cover it, and that + :c:macro:`ARCH_THREAD_STACK_OBJ_ALIGN()` is also specified per the + granularity of the memory protection hardware. + +This becomes more complicated if the memory protection hardware requires that +all memory regions be sized to a power of two, and aligned to their own size. +This is common on older MPUs and is known with +:option:`CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT`. + +``thread.stack_info`` always tracks the user-accessible part of the stack +object, it must always be correct to program a memory protection region with +user access using the range stored within. + +Non power-of-two memory region requirements +------------------------------------------- + +On systems without power-of-two region requirements, the reserved memory area +for threads stacks defined by :c:macro:`K_THREAD_STACK_RESERVED` may be used to +contain the privilege mode stack. The layout could be something like: + +:: + + +------------------------------+ <- thread.stack_obj + | Other platform data | + +------------------------------+ + | Guard region (if enabled) | + +------------------------------+ + | Guard carve-out (if needed) | + |..............................| + | Privilege elevation stack | + +------------------------------| <- thread.stack_obj + + | Stack buffer | K_THREAD_STACK_RESERVED = + . . thread.stack_info.start + +The guard region, and any carve-out (if needed) would be configured as a +read-only region when the thread is created. + +* If the thread is a supervisor thread, the privilege elevation region is just + extra stack memory. An overflow will eventually crash into the guard region. + +* If the thread is running in user mode, a memory protection region will be + configured to allow user threads access to the stack buffer, but nothing + before or after it. An overflow in user mode will crash into the privilege + elevation stack, which the user thread has no access to. An overflow when + handling a system call will crash into the guard region. + +On an MMU system there should be no physical guards; the privilege mode stack +will be mapped into kernel memory, and the stack buffer in the user part of +memory, each with non-present virtual guard pages below them to catch runtime +stack overflows. + +Other platform data may be stored before the guard region, but this is highly +discouraged if such data could be stored in ``thread.arch`` somewhere. + +:c:macro:`ARCH_THREAD_STACK_RESERVED` will need to be defined to capture +the size of the reserved region containing platform data, privilege elevation +stacks, and guards. It must be appropriately sized such that an MPU region +to grant user mode access to the stack buffer can be placed immediately +after it. + +Power-of-two memory region requirements +--------------------------------------- + +Thread stack objects must be sized and aligned to the same power of two, +without any reserved memory to allow efficient packing in memory. Thus, +any guards in the thread stack must be completely carved out, and the +privilege elevation stack must be allocated elsewhere. + +:c:macro:`ARCH_THREAD_STACK_SIZE_ADJUST()` and +:c:macro:`ARCH_THREAD_STACK_OBJ_ALIGN()` should both be defined to +:c:macro:`Z_POW2_CEIL()`. :c:macro:`K_THREAD_STACK_RESERVED` must be 0. + +For the privilege stacks, the :option:`CONFIG_GEN_PRIV_STACKS` must be, +enabled. For every thread stack found in the system, a corresponding fixed- +size kernel stack used for handling system calls is generated. The address +of the privilege stacks can be looked up quickly at runtime based on the +thread stack address using :c:func:`z_priv_stack_find()`. These stacks are +laid out the same way as other kernel-only stacks. + +:: + + +-----------------------------+ <- z_priv_stack_find(thread.stack_obj) + | Reserved memory | } K_KERNEL_STACK_RESERVED + +-----------------------------+ + | Guard carve-out (if needed) | + |.............................| + | Privilege elevation stack | + | | + +-----------------------------+ <- z_priv_stack_find(thread.stack_obj) + + K_KERNEL_STACK_RESERVED + + CONFIG_PRIVILEGED_STACK_SIZE + + +-----------------------------+ <- thread.stack_obj + | MPU guard carve-out | + | (supervisor mode only) | + |.............................| <- thread.stack_info.start + | Stack buffer | + . . + +The guard carve-out in the thread stack object is only used if the thread is +running in supervisor mode. If the thread drops to user mode, there is no guard +and the entire object is used as the stack buffer, with full access to the +associated user mode thread and ``thread.stack_info`` updated appropriately. + +User Mode Threads +***************** + To support user mode threads, several kernel-to-arch APIs need to be implemented, and the system must enable the :option:`CONFIG_ARCH_HAS_USERSPACE` option. Please see the documentation for each of these functions for more details: -* :cpp:func:`arch_buffer_validate()` to test whether the current thread has +* :c:func:`arch_buffer_validate` to test whether the current thread has access permissions to a particular memory region -* :cpp:func:`arch_user_mode_enter()` which will irreversibly drop a supervisor +* :c:func:`arch_user_mode_enter` which will irreversibly drop a supervisor thread to user mode privileges. The stack must be wiped. -* :cpp:func:`arch_syscall_oops()` which generates a kernel oops when system +* :c:func:`arch_syscall_oops` which generates a kernel oops when system call parameters can't be validated, in such a way that the oops appears to be generated from where the system call was invoked in the user thread -* :cpp:func:`arch_syscall_invoke0()` through - :cpp:func:`arch_syscall_invoke6()` invoke a system call with the +* :c:func:`arch_syscall_invoke0` through + :c:func:`arch_syscall_invoke6` invoke a system call with the appropriate number of arguments which must all be passed in during the privilege elevation via registers. -* :cpp:func:`arch_is_user_context()` return nonzero if the CPU is currently +* :c:func:`arch_is_user_context` return nonzero if the CPU is currently running in user mode -* :cpp:func:`arch_mem_domain_max_partitions_get()` which indicates the max +* :c:func:`arch_mem_domain_max_partitions_get` which indicates the max number of regions for a memory domain. MMU systems have an unlimited amount, MPU systems have constraints on this. -* :cpp:func:`arch_mem_domain_partition_remove()` Remove a partition from - a memory domain if the currently executing thread was part of that domain. +Some architectures may need to update software memory management structures +or modify hardware registers on another CPU when memory domain APIs are invoked. +If so, CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API must be selected by the +architecture and some additional APIs must be implemented. This is common +on MMU systems and uncommon on MPU systems: -* :cpp:func:`arch_mem_domain_destroy()` Reset the thread's memory domain - configuration +* :c:func:`arch_mem_domain_thread_add` + +* :c:func:`arch_mem_domain_thread_remove` + +* :c:func:`arch_mem_domain_partition_add` + +* :c:func:`arch_mem_domain_partition_remove` + +* :c:func:`arch_mem_domain_destroy` + +Please see the doxygen documentation of these APIs for details. In addition to implementing these APIs, there are some other tasks as well: -* :cpp:func:`_new_thread()` needs to spawn threads with :c:macro:`K_USER` in +* :c:func:`_new_thread` needs to spawn threads with :c:macro:`K_USER` in user mode * On context switch, the outgoing thread's stack memory should be marked @@ -560,7 +851,7 @@ In addition to implementing these APIs, there are some other tasks as well: be established. This is closely tied to how the _arch_syscall_invoke macros are implemented. On system call, the appropriate handler function needs to be looked up in _k_syscall_table. Bad system call IDs should jump to the - :cpp:enum:`K_SYSCALL_BAD` handler. Upon completion of the system call, care + :c:enum:`K_SYSCALL_BAD` handler. Upon completion of the system call, care must be taken not to leak any register state back to user mode. API Reference @@ -578,6 +869,9 @@ Threads .. doxygengroup:: arch-threads :project: Zephyr +.. doxygengroup:: arch-tls + :project: Zephyr + Power Management ================ @@ -602,10 +896,10 @@ Userspace .. doxygengroup:: arch-userspace :project: Zephyr -Benchmarking -============ +Memory Management +================= -.. doxygengroup:: arch-benchmarking +.. doxygengroup:: arch-mmu :project: Zephyr Miscellaneous Architecture APIs diff --git a/doc/guides/porting/board_porting.rst b/doc/guides/porting/board_porting.rst index 5932024f2ea807..42884caa912d2c 100644 --- a/doc/guides/porting/board_porting.rst +++ b/doc/guides/porting/board_porting.rst @@ -180,7 +180,7 @@ The optional files are: of your board. You only need this if you're :ref:`contributing-your-board` to Zephyr. - :file:`plank.yaml`: a YAML file with miscellaneous metadata used by the - :ref:`sanitycheck_script`. + :ref:`twister_script`. .. _default_board_configuration: @@ -432,7 +432,10 @@ while porting. - It is recommended to enable the MPU by default, if there is support for it in hardware. For boards with limited memory resources it is acceptable to - disable it. + disable it. When the MPU is enabled, it is recommended to also enable + hardware stack protection (CONFIG_HW_STACK_PROTECTION=y) and, thus, allow the + kernel to detect stack overflows when the system is running in privileged + mode. .. _flash-and-debug-support: @@ -447,7 +450,7 @@ to configure a "runner" for your board. (There's nothing special you need to do to get ``west build`` support for your board.) "Runners" are Zephyr-specific Python classes that wrap :ref:`flash and debug -host tools ` and integrate with west and the zephyr build +host tools ` and integrate with west and the zephyr build system to support ``west flash`` and related commands. Each runner supports flashing, debugging, or both. You need to configure the arguments to these Python scripts in your :file:`board.cmake` to support those commands like this diff --git a/doc/guides/porting/shields.rst b/doc/guides/porting/shields.rst index 834392c04769e7..e7463d57d64bc6 100644 --- a/doc/guides/porting/shields.rst +++ b/doc/guides/porting/shields.rst @@ -78,9 +78,9 @@ files to a shield, as follows: .. code-block:: none boards/shields/ - └── - ├── board.overlay - └── board.defconfig + └── boards + ├── .overlay + └── .defconfig Shield activation @@ -132,10 +132,10 @@ revision: ├── .defconfig ├── .overlay ├── .defconfig - └── + └── boards └── - ├── board.overlay - └── board.defconfig + ├── .overlay + └── .defconfig GPIO nexus nodes **************** diff --git a/doc/guides/test/index.rst b/doc/guides/test/index.rst index f401b71a216339..f45fa93932fab9 100644 --- a/doc/guides/test/index.rst +++ b/doc/guides/test/index.rst @@ -7,4 +7,4 @@ Testing :maxdepth: 1 ztest - sanitycheck + twister diff --git a/doc/guides/test/sanitycheck.rst b/doc/guides/test/sanitycheck.rst deleted file mode 100644 index 573e44ac94d8d2..00000000000000 --- a/doc/guides/test/sanitycheck.rst +++ /dev/null @@ -1,575 +0,0 @@ -.. _sanitycheck_script: - -Sanity Tests -############# - -This script scans for the set of unit test applications in the git repository -and attempts to execute them. By default, it tries to build each test -case on boards marked as default in the board definition file. - -The default options will build the majority of the tests on a defined set of -boards and will run in an emulated environment if available for the -architecture or configuration being tested. - -In normal use, sanitycheck runs a limited set of kernel tests (inside -an emulator). Because of its limited test execution coverage, sanitycheck -cannot guarantee local changes will succeed in the full build -environment, but it does sufficient testing by building samples and -tests for different boards and different configurations to help keep the -complete code tree buildable. - -When using (at least) one ``-v`` option, sanitycheck's console output -shows for every test how the test is run (qemu, native_posix, etc.) or -whether the binary was just built. There are a few reasons why sanitycheck -only builds a test and doesn't run it: - -- The test is marked as ``build_only: true`` in its ``.yaml`` - configuration file. -- The test configuration has defined a ``harness`` but you don't have - it or haven't set it up. -- The target device is not connected and not available for flashing -- You or some higher level automation invoked sanitycheck with - ``--build-only``. - -These also affect the outputs of ``--testcase-report`` and -``--detailed-report``, see their respective ``--help`` sections. - -To run the script in the local tree, follow the steps below: - -:: - - $ source zephyr-env.sh - $ ./scripts/sanitycheck - -If you have a system with a large number of cores, you can build and run -all possible tests using the following options: - -:: - - $ ./scripts/sanitycheck --all --enable-slow - -This will build for all available boards and run all applicable tests in -a simulated (for example QEMU) environment. - -The list of command line options supported by sanitycheck can be viewed using:: - - $ ./scripts/sanitycheck --help - - - -Board Configuration -******************* - -To build tests for a specific board and to execute some of the tests on real -hardware or in an emulation environment such as QEMU a board configuration file -is required which is generic enough to be used for other tasks that require a -board inventory with details about the board and its configuration that is only -available during build time otherwise. - -The board metadata file is located in the board directory and is structured -using the YAML markup language. The example below shows a board with a data -required for best test coverage for this specific board: - -.. code-block:: yaml - - identifier: frdm_k64f - name: NXP FRDM-K64F - type: mcu - arch: arm - toolchain: - - zephyr - - gnuarmemb - - xtools - supported: - - arduino_gpio - - arduino_i2c - - netif:eth - - adc - - i2c - - nvs - - spi - - gpio - - usb_device - - watchdog - - can - - pwm - testing: - default: true - - -identifier: - A string that matches how the board is defined in the build system. This same - string is used when building, for example when calling ``west build`` or - ``cmake``:: - - # with west - west build -b reel_board - # with cmake - cmake -DBOARD=reel_board .. - -name: - The actual name of the board as it appears in marketing material. -type: - Type of the board or configuration, currently we support 2 types: mcu, qemu -arch: - Architecture of the board -toolchain: - The list of supported toolchains that can build this board. This should match - one of the values used for 'ZEPHYR_TOOLCHAIN_VARIANT' when building on the command line -ram: - Available RAM on the board (specified in KB). This is used to match testcase - requirements. If not specified we default to 128KB. -flash: - Available FLASH on the board (specified in KB). This is used to match testcase - requirements. If not specified we default to 512KB. -supported: - A list of features this board supports. This can be specified as a single word - feature or as a variant of a feature class. For example: - - :: - - supported: - - pci - - This indicates the board does support PCI. You can make a testcase build or - run only on such boards, or: - - :: - - supported: - - netif:eth - - sensor:bmi16 - - A testcase can both depend on 'eth' to only test ethernet or on 'netif' to run - on any board with a networking interface. - -testing: - testing relating keywords to provide best coverage for the features of this - board. - - default: [True|False]: - This is a default board, it will tested with the highest priority and is - covered when invoking the simplified sanitycheck without any additional - arguments. - ignore_tags: - Do not attempt to build (and therefore run) tests marked with this list of - tags. - -Test Cases -********** - -Test cases are detected by the presence of a 'testcase.yaml' or a 'sample.yaml' -files in the application's project directory. This file may contain one or more -entries in the test section each identifying a test scenario. - -The name of each testcase needs to be unique in the context of the overall -testsuite and has to follow basic rules: - -#. The format of the test identifier shall be a string without any spaces or - special characters (allowed characters: alphanumric and [\_=]) consisting of - multiple sections delimited with a dot (.). - -#. Each test identifier shall start with a section followed by a subsection - separated by a dot. For example, a test that covers semaphores in the kernel - shall start with ``kernel.sempahore``. - -#. All test identifiers within a testcase.yaml file need to be unique. For - example a testcase.yaml file covering semaphores in the kernel can have: - - * ``kernel.semaphore``: For general semaphore tests - * ``kernel.semaphore.stress``: Stress testng semaphores in the kernel. - -#. Depending on the nature of the test, an identifier can consist of at least - two sections: - - * Ztest tests: The individual testcases in the ztest testsuite will be - concatenated to identifier in the testcase.yaml file generating unique - identifiers for every testcase in the suite. - - * Standalone tests and samples: This type of test should at least have 3 - sections in the test identifier in the testcase.yaml (or sample.yaml) file. - The last section of the name shall signify the test itself. - - -Test cases are written using the YAML syntax and share the same structure as -samples. The following is an example test with a few options that are -explained in this document. - - -:: - - tests: - bluetooth.gatt: - build_only: true - platform_whitelist: qemu_cortex_m3 qemu_x86 - tags: bluetooth - bluetooth.gatt.br: - build_only: true - extra_args: CONF_FILE="prj_br.conf" - filter: not CONFIG_DEBUG - platform_exclude: up_squared - platform_whitelist: qemu_cortex_m3 qemu_x86 - tags: bluetooth - - -A sample with tests will have the same structure with additional information -related to the sample and what is being demonstrated: - -:: - - sample: - name: hello world - description: Hello World sample, the simplest Zephyr application - tests: - sample.basic.hello_world: - build_only: true - tags: tests - min_ram: 16 - sample.basic.hello_world.singlethread: - build_only: true - extra_args: CONF_FILE=prj_single.conf - filter: not CONFIG_BT - tags: tests - min_ram: 16 - -The full canonical name for each test case is: - -:: - - / - -Each test block in the testcase meta data can define the following key/value -pairs: - -tags: (required) - A set of string tags for the testcase. Usually pertains to - functional domains but can be anything. Command line invocations - of this script can filter the set of tests to run based on tag. - -skip: (default False) - skip testcase unconditionally. This can be used for broken tests. - -slow: (default False) - Don't run this test case unless --enable-slow was passed in on the - command line. Intended for time-consuming test cases that are only - run under certain circumstances, like daily builds. These test cases - are still compiled. - -extra_args: - Extra arguments to pass to Make when building or running the - test case. - -extra_configs: - Extra configuration options to be merged with a master prj.conf - when building or running the test case. For example:: - - common: - tags: drivers adc - tests: - test: - depends_on: adc - test_async: - extra_configs: - - CONFIG_ADC_ASYNC=y - - -build_only: (default False) - If true, don't try to run the test even if the - selected platform supports it. - -build_on_all: (default False) - If true, attempt to build test on all available platforms. - -depends_on: - A board or platform can announce what features it supports, this option - will enable the test only those platforms that provide this feature. - -min_ram: - minimum amount of RAM needed for this test to build and run. This is - compared with information provided by the board metadata. - -min_flash: - minimum amount of ROM needed for this test to build and run. This is - compared with information provided by the board metadata. - -timeout: - Length of time to run test in QEMU before automatically killing it. - Default to 60 seconds. - -arch_whitelist: - Set of architectures that this test case should only be run for. - -arch_exclude: - Set of architectures that this test case should not run on. - -platform_whitelist: - Set of platforms that this test case should only be run for. - -platform_exclude: - Set of platforms that this test case should not run on. - -extra_sections: - When computing sizes, sanitycheck will report errors if it finds - extra, unexpected sections in the Zephyr binary unless they are named - here. They will not be included in the size calculation. - -harness: - A harness string needed to run the tests successfully. This can be as - simple as a loopback wiring or a complete hardware test setup for - sensor and IO testing. - Usually pertains to external dependency domains but can be anything such as - console, sensor, net, keyboard, or Bluetooth. - -harness_config: - Extra harness configuration options to be used to select a board and/or - for handling generic Console with regex matching. Config can announce - what features it supports. This option will enable the test to run on - only those platforms that fulfill this external dependency. - - The following options are currently supported: - - type: (required) - Depends on the regex string to be matched - - - record: - - regex: (required) - Any string that the particular test case prints to record test - results. - - regex: (required) - Any string that the particular test case prints to confirm test - runs as expected. - - ordered: (default False) - Check the regular expression strings in orderly or randomly fashion - - repeat: - Number of times to validate the repeated regex expression - - fixture: - Specify a test case dependency on an external device(e.g., sensor), - and identify setups that fulfill this dependency. It depends on - specific test setup and board selection logic to pick the particular - board(s) out of multiple boards that fulfill the dependency in an - automation setup based on "fixture" keyword. Some sample fixture names - are i2c_hts221, i2c_bme280, i2c_FRAM, ble_fw and gpio_loop. - - Only one fixture can be defined per testcase. - - The following is an example yaml file with a few harness_config options. - - :: - - sample: - name: HTS221 Temperature and Humidity Monitor - common: - tags: sensor - harness: console - harness_config: - type: multi_line - ordered: false - regex: - - "Temperature:(.*)C" - - "Relative Humidity:(.*)%" - fixture: i2c_hts221 - tests: - test: - tags: sensors - depends_on: i2c - -filter: - Filter whether the testcase should be run by evaluating an expression - against an environment containing the following values: - - :: - - { ARCH : , - PLATFORM : , - , - *: any environment variable available - } - - The grammar for the expression language is as follows: - - expression ::= expression "and" expression - | expression "or" expression - | "not" expression - | "(" expression ")" - | symbol "==" constant - | symbol "!=" constant - | symbol "<" number - | symbol ">" number - | symbol ">=" number - | symbol "<=" number - | symbol "in" list - | symbol ":" string - | symbol - - list ::= "[" list_contents "]" - - list_contents ::= constant - | list_contents "," constant - - constant ::= number - | string - - - For the case where expression ::= symbol, it evaluates to true - if the symbol is defined to a non-empty string. - - Operator precedence, starting from lowest to highest: - - or (left associative) - and (left associative) - not (right associative) - all comparison operators (non-associative) - - arch_whitelist, arch_exclude, platform_whitelist, platform_exclude - are all syntactic sugar for these expressions. For instance - - arch_exclude = x86 arc - - Is the same as: - - filter = not ARCH in ["x86", "arc"] - - The ':' operator compiles the string argument as a regular expression, - and then returns a true value only if the symbol's value in the environment - matches. For example, if CONFIG_SOC="stm32f107xc" then - - filter = CONFIG_SOC : "stm.*" - - Would match it. - -The set of test cases that actually run depends on directives in the testcase -filed and options passed in on the command line. If there is any confusion, -running with -v or examining the discard report -(:file:`sanitycheck_discard.csv`) can help show why particular test cases were -skipped. - -Metrics (such as pass/fail state and binary size) for the last code -release are stored in scripts/sanity_chk/sanity_last_release.csv. -To update this, pass the --all --release options. - -To load arguments from a file, write '+' before the file name, e.g., -+file_name. File content must be one or more valid arguments separated by -line break instead of white spaces. - -Most everyday users will run with no arguments. - - -Running Tests on Hardware -************************* - -Beside being able to run tests in QEMU and other simulated environments, -sanitycheck supports running most of the tests on real devices and produces -reports for each run with detailed FAIL/PASS results. - - -Executing tests on a single device -=================================== - -To use this feature on a single connected device, run sanitycheck with -the following new options:: - - scripts/sanitycheck --device-testing --device-serial /dev/ttyACM0 -p \ - frdm_k64f -T tests/kernel - -The ``--device-serial`` option denotes the serial device the board is connected to. -This needs to be accessible by the user running sanitycheck. You can run this on -only one board at a time, specified using the ``--platform`` option. - - -Executing tests on multiple devices -=================================== - -To build and execute tests on multiple devices connected to the host PC, a -hardware map needs to be created with all connected devices and their -details such as the serial device and their IDs if available. Run the following -command to produce the hardware map:: - - ./scripts/sanitycheck --generate-hardware-map map.yml - -The generated hardware map file (map.yml) will have the list of connected -devices, for example:: - - - available: true - id: OSHW000032254e4500128002ab98002784d1000097969900 - platform: unknown - product: DAPLink CMSIS-DAP - runner: pyocd - serial: /dev/cu.usbmodem146114202 - - available: true - id: 000683759358 - platform: unknown - product: J-Link - runner: unknown - serial: /dev/cu.usbmodem0006837593581 - - -Any options marked as 'unknown' need to be changed and set with the correct -values, in the above example both the platform names and the runners need to be -replaced with the correct values corresponding to the connected hardware. In -this example we are using a reel_board and an nrf52840dk_nrf52840:: - - - available: true - id: OSHW000032254e4500128002ab98002784d1000097969900 - platform: reel_board - product: DAPLink CMSIS-DAP - runner: pyocd - serial: /dev/cu.usbmodem146114202 - - available: true - id: 000683759358 - platform: nrf52840dk_nrf52840 - product: J-Link - runner: nrfjprog - serial: /dev/cu.usbmodem0006837593581 - -If the map file already exists, then new entries are added and existing entries -will be updated. This way you can use one single master hardware map and update -it for every run to get the correct serial devices and status of the devices. - -With the hardware map ready, you can run any tests by pointing to the map -file:: - - ./scripts/sanitycheck --device-testing --hardware-map map.yml -T samples/hello_world/ - -The above command will result in sanitycheck building tests for the platforms -defined in the hardware map and subsequently flashing and running the tests -on those platforms. - -.. note:: - - Currently only boards with support for both pyocd and nrfjprog are supported - with the hardware map features. Boards that require other runners to flash the - Zephyr binary are still work in progress. - -Fixtures -+++++++++ - -Some tests require additional setup or special wiring specific to the test. -Running the tests without this setup or test fixture may fail. A testcase can -specify the fixture it needs which can then be matched with hardware capability -of a board and the fixtures it supports via the command line or using the hardware -map file. - -Fixtures are defined in the hardware map file as a list:: - - - available: true - connected: true - fixtures: - - gpio_loopback - id: 0240000026334e450015400f5e0e000b4eb1000097969900 - platform: frdm_k64f - product: DAPLink CMSIS-DAP - runner: pyocd - serial: /dev/ttyACM9 - -When running `sanitycheck` with ``--device-testing``, the configured fixture -in the hardware map file will be matched to testcases requesting the same fixtures -and these tests will be executed on the boards that provide this fixture. - -.. figure:: fixtures.svg - :figclass: align-center diff --git a/doc/guides/test/twister.rst b/doc/guides/test/twister.rst new file mode 100644 index 00000000000000..777bac486a2074 --- /dev/null +++ b/doc/guides/test/twister.rst @@ -0,0 +1,636 @@ +.. _twister_script: + +Test Runner (Twister) +##################### + +This script scans for the set of unit test applications in the git repository +and attempts to execute them. By default, it tries to build each test +case on boards marked as default in the board definition file. + +The default options will build the majority of the tests on a defined set of +boards and will run in an emulated environment if available for the +architecture or configuration being tested. + +In normal use, twister runs a limited set of kernel tests (inside +an emulator). Because of its limited test execution coverage, twister +cannot guarantee local changes will succeed in the full build +environment, but it does sufficient testing by building samples and +tests for different boards and different configurations to help keep the +complete code tree buildable. + +When using (at least) one ``-v`` option, twister's console output +shows for every test how the test is run (qemu, native_posix, etc.) or +whether the binary was just built. There are a few reasons why twister +only builds a test and doesn't run it: + +- The test is marked as ``build_only: true`` in its ``.yaml`` + configuration file. +- The test configuration has defined a ``harness`` but you don't have + it or haven't set it up. +- The target device is not connected and not available for flashing +- You or some higher level automation invoked twister with + ``--build-only``. + +These also affect the outputs of ``--testcase-report`` and +``--detailed-report``, see their respective ``--help`` sections. + +To run the script in the local tree, follow the steps below: + +:: + + $ source zephyr-env.sh + $ ./scripts/twister + +If you have a system with a large number of cores, you can build and run +all possible tests using the following options: + +:: + + $ ./scripts/twister --all --enable-slow + +This will build for all available boards and run all applicable tests in +a simulated (for example QEMU) environment. + +The list of command line options supported by twister can be viewed using:: + + $ ./scripts/twister --help + + + +Board Configuration +******************* + +To build tests for a specific board and to execute some of the tests on real +hardware or in an emulation environment such as QEMU a board configuration file +is required which is generic enough to be used for other tasks that require a +board inventory with details about the board and its configuration that is only +available during build time otherwise. + +The board metadata file is located in the board directory and is structured +using the YAML markup language. The example below shows a board with a data +required for best test coverage for this specific board: + +.. code-block:: yaml + + identifier: frdm_k64f + name: NXP FRDM-K64F + type: mcu + arch: arm + toolchain: + - zephyr + - gnuarmemb + - xtools + supported: + - arduino_gpio + - arduino_i2c + - netif:eth + - adc + - i2c + - nvs + - spi + - gpio + - usb_device + - watchdog + - can + - pwm + testing: + default: true + + +identifier: + A string that matches how the board is defined in the build system. This same + string is used when building, for example when calling ``west build`` or + ``cmake``:: + + # with west + west build -b reel_board + # with cmake + cmake -DBOARD=reel_board .. + +name: + The actual name of the board as it appears in marketing material. +type: + Type of the board or configuration, currently we support 2 types: mcu, qemu +arch: + Architecture of the board +toolchain: + The list of supported toolchains that can build this board. This should match + one of the values used for 'ZEPHYR_TOOLCHAIN_VARIANT' when building on the command line +ram: + Available RAM on the board (specified in KB). This is used to match testcase + requirements. If not specified we default to 128KB. +flash: + Available FLASH on the board (specified in KB). This is used to match testcase + requirements. If not specified we default to 512KB. +supported: + A list of features this board supports. This can be specified as a single word + feature or as a variant of a feature class. For example: + + :: + + supported: + - pci + + This indicates the board does support PCI. You can make a testcase build or + run only on such boards, or: + + :: + + supported: + - netif:eth + - sensor:bmi16 + + A testcase can both depend on 'eth' to only test ethernet or on 'netif' to run + on any board with a networking interface. + +testing: + testing relating keywords to provide best coverage for the features of this + board. + + default: [True|False]: + This is a default board, it will tested with the highest priority and is + covered when invoking the simplified twister without any additional + arguments. + ignore_tags: + Do not attempt to build (and therefore run) tests marked with this list of + tags. + only_tags: + Only execute tests with this list of tags on a specific platform. + +Test Cases +********** + +Test cases are detected by the presence of a 'testcase.yaml' or a 'sample.yaml' +files in the application's project directory. This file may contain one or more +entries in the test section each identifying a test scenario. + +The name of each testcase needs to be unique in the context of the overall +testsuite and has to follow basic rules: + +#. The format of the test identifier shall be a string without any spaces or + special characters (allowed characters: alphanumric and [\_=]) consisting of + multiple sections delimited with a dot (.). + +#. Each test identifier shall start with a section followed by a subsection + separated by a dot. For example, a test that covers semaphores in the kernel + shall start with ``kernel.sempahore``. + +#. All test identifiers within a testcase.yaml file need to be unique. For + example a testcase.yaml file covering semaphores in the kernel can have: + + * ``kernel.semaphore``: For general semaphore tests + * ``kernel.semaphore.stress``: Stress testng semaphores in the kernel. + +#. Depending on the nature of the test, an identifier can consist of at least + two sections: + + * Ztest tests: The individual testcases in the ztest testsuite will be + concatenated to identifier in the testcase.yaml file generating unique + identifiers for every testcase in the suite. + + * Standalone tests and samples: This type of test should at least have 3 + sections in the test identifier in the testcase.yaml (or sample.yaml) file. + The last section of the name shall signify the test itself. + + +Test cases are written using the YAML syntax and share the same structure as +samples. The following is an example test with a few options that are +explained in this document. + + +:: + + tests: + bluetooth.gatt: + build_only: true + platform_allow: qemu_cortex_m3 qemu_x86 + tags: bluetooth + bluetooth.gatt.br: + build_only: true + extra_args: CONF_FILE="prj_br.conf" + filter: not CONFIG_DEBUG + platform_exclude: up_squared + platform_allow: qemu_cortex_m3 qemu_x86 + tags: bluetooth + + +A sample with tests will have the same structure with additional information +related to the sample and what is being demonstrated: + +:: + + sample: + name: hello world + description: Hello World sample, the simplest Zephyr application + tests: + sample.basic.hello_world: + build_only: true + tags: tests + min_ram: 16 + sample.basic.hello_world.singlethread: + build_only: true + extra_args: CONF_FILE=prj_single.conf + filter: not CONFIG_BT + tags: tests + min_ram: 16 + +The full canonical name for each test case is: + +:: + + / + +Each test block in the testcase meta data can define the following key/value +pairs: + +tags: (required) + A set of string tags for the testcase. Usually pertains to + functional domains but can be anything. Command line invocations + of this script can filter the set of tests to run based on tag. + +skip: (default False) + skip testcase unconditionally. This can be used for broken tests. + +slow: (default False) + Don't run this test case unless --enable-slow was passed in on the + command line. Intended for time-consuming test cases that are only + run under certain circumstances, like daily builds. These test cases + are still compiled. + +extra_args: + Extra arguments to pass to Make when building or running the + test case. + +extra_configs: + Extra configuration options to be merged with a master prj.conf + when building or running the test case. For example:: + + common: + tags: drivers adc + tests: + test: + depends_on: adc + test_async: + extra_configs: + - CONFIG_ADC_ASYNC=y + + +build_only: (default False) + If true, don't try to run the test even if the + selected platform supports it. + +build_on_all: (default False) + If true, attempt to build test on all available platforms. + +depends_on: + A board or platform can announce what features it supports, this option + will enable the test only those platforms that provide this feature. + +min_ram: + minimum amount of RAM needed for this test to build and run. This is + compared with information provided by the board metadata. + +min_flash: + minimum amount of ROM needed for this test to build and run. This is + compared with information provided by the board metadata. + +timeout: + Length of time to run test in QEMU before automatically killing it. + Default to 60 seconds. + +arch_allow: + Set of architectures that this test case should only be run for. + +arch_exclude: + Set of architectures that this test case should not run on. + +platform_allow: + Set of platforms that this test case should only be run for. Do not use + this option to limit testing or building in CI due to time or resource + constraints, this option should only be used if the test or sample can + only be run on the allowed platform and nothing else. + +integration_platforms: + This option limits the scope to the listed platforms when twister is + invoked with the --integration option. Use this instead of + platform_allow if the goal is to limit scope due to timing or + resource constraints. + +platform_exclude: + Set of platforms that this test case should not run on. + +extra_sections: + When computing sizes, twister will report errors if it finds + extra, unexpected sections in the Zephyr binary unless they are named + here. They will not be included in the size calculation. + +harness: + A harness string needed to run the tests successfully. This can be as + simple as a loopback wiring or a complete hardware test setup for + sensor and IO testing. + Usually pertains to external dependency domains but can be anything such as + console, sensor, net, keyboard, or Bluetooth. + +harness_config: + Extra harness configuration options to be used to select a board and/or + for handling generic Console with regex matching. Config can announce + what features it supports. This option will enable the test to run on + only those platforms that fulfill this external dependency. + + The following options are currently supported: + + type: (required) + Depends on the regex string to be matched + + + record: + + regex: (required) + Any string that the particular test case prints to record test + results. + + regex: (required) + Any string that the particular test case prints to confirm test + runs as expected. + + ordered: (default False) + Check the regular expression strings in orderly or randomly fashion + + repeat: + Number of times to validate the repeated regex expression + + fixture: + Specify a test case dependency on an external device(e.g., sensor), + and identify setups that fulfill this dependency. It depends on + specific test setup and board selection logic to pick the particular + board(s) out of multiple boards that fulfill the dependency in an + automation setup based on "fixture" keyword. Some sample fixture names + are i2c_hts221, i2c_bme280, i2c_FRAM, ble_fw and gpio_loop. + + Only one fixture can be defined per testcase. + + The following is an example yaml file with a few harness_config options. + + :: + + sample: + name: HTS221 Temperature and Humidity Monitor + common: + tags: sensor + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "Temperature:(.*)C" + - "Relative Humidity:(.*)%" + fixture: i2c_hts221 + tests: + test: + tags: sensors + depends_on: i2c + +filter: + Filter whether the testcase should be run by evaluating an expression + against an environment containing the following values: + + :: + + { ARCH : , + PLATFORM : , + , + *: any environment variable available + } + + The grammar for the expression language is as follows: + + expression ::= expression "and" expression + | expression "or" expression + | "not" expression + | "(" expression ")" + | symbol "==" constant + | symbol "!=" constant + | symbol "<" number + | symbol ">" number + | symbol ">=" number + | symbol "<=" number + | symbol "in" list + | symbol ":" string + | symbol + + list ::= "[" list_contents "]" + + list_contents ::= constant + | list_contents "," constant + + constant ::= number + | string + + + For the case where expression ::= symbol, it evaluates to true + if the symbol is defined to a non-empty string. + + Operator precedence, starting from lowest to highest: + + or (left associative) + and (left associative) + not (right associative) + all comparison operators (non-associative) + + arch_allow, arch_exclude, platform_allow, platform_exclude + are all syntactic sugar for these expressions. For instance + + arch_exclude = x86 arc + + Is the same as: + + filter = not ARCH in ["x86", "arc"] + + The ':' operator compiles the string argument as a regular expression, + and then returns a true value only if the symbol's value in the environment + matches. For example, if CONFIG_SOC="stm32f107xc" then + + filter = CONFIG_SOC : "stm.*" + + Would match it. + +The set of test cases that actually run depends on directives in the testcase +filed and options passed in on the command line. If there is any confusion, +running with -v or examining the discard report +(:file:`twister_discard.csv`) can help show why particular test cases were +skipped. + +Metrics (such as pass/fail state and binary size) for the last code +release are stored in scripts/release/twister_last_release.csv. +To update this, pass the --all --release options. + +To load arguments from a file, write '+' before the file name, e.g., ++file_name. File content must be one or more valid arguments separated by +line break instead of white spaces. + +Most everyday users will run with no arguments. + +Running in Integration Mode +*************************** + +This mode is used in continuous integration (CI) and other automated +environments used to give developers fast feedback on changes. The mode can +be activated using the --integration option of twister and narrows down +the scope of builds and tests if applicable to platforms defined under the +integration keyword in the testcase definition file (testcase.yaml and +sample.yaml). + + +Running Tests on Hardware +************************* + +Beside being able to run tests in QEMU and other simulated environments, +twister supports running most of the tests on real devices and produces +reports for each run with detailed FAIL/PASS results. + + +Executing tests on a single device +=================================== + +To use this feature on a single connected device, run twister with +the following new options:: + + scripts/twister --device-testing --device-serial /dev/ttyACM0 -p \ + frdm_k64f -T tests/kernel + +The ``--device-serial`` option denotes the serial device the board is connected to. +This needs to be accessible by the user running twister. You can run this on +only one board at a time, specified using the ``--platform`` option. + + +Executing tests on multiple devices +=================================== + +To build and execute tests on multiple devices connected to the host PC, a +hardware map needs to be created with all connected devices and their +details such as the serial device and their IDs if available. Run the following +command to produce the hardware map:: + + ./scripts/twister --generate-hardware-map map.yml + +The generated hardware map file (map.yml) will have the list of connected +devices, for example:: + + - available: true + id: OSHW000032254e4500128002ab98002784d1000097969900 + platform: unknown + product: DAPLink CMSIS-DAP + runner: pyocd + serial: /dev/cu.usbmodem146114202 + - available: true + id: 000683759358 + platform: unknown + product: J-Link + runner: unknown + serial: /dev/cu.usbmodem0006837593581 + + +Any options marked as 'unknown' need to be changed and set with the correct +values, in the above example both the platform names and the runners need to be +replaced with the correct values corresponding to the connected hardware. In +this example we are using a reel_board and an nrf52840dk_nrf52840:: + + - available: true + id: OSHW000032254e4500128002ab98002784d1000097969900 + platform: reel_board + product: DAPLink CMSIS-DAP + runner: pyocd + serial: /dev/cu.usbmodem146114202 + - available: true + id: 000683759358 + platform: nrf52840dk_nrf52840 + product: J-Link + runner: nrfjprog + serial: /dev/cu.usbmodem0006837593581 + +If the map file already exists, then new entries are added and existing entries +will be updated. This way you can use one single master hardware map and update +it for every run to get the correct serial devices and status of the devices. + +With the hardware map ready, you can run any tests by pointing to the map +file:: + + ./scripts/twister --device-testing --hardware-map map.yml -T samples/hello_world/ + +The above command will result in twister building tests for the platforms +defined in the hardware map and subsequently flashing and running the tests +on those platforms. + +.. note:: + + Currently only boards with support for both pyocd and nrfjprog are supported + with the hardware map features. Boards that require other runners to flash the + Zephyr binary are still work in progress. + +Fixtures ++++++++++ + +Some tests require additional setup or special wiring specific to the test. +Running the tests without this setup or test fixture may fail. A testcase can +specify the fixture it needs which can then be matched with hardware capability +of a board and the fixtures it supports via the command line or using the hardware +map file. + +Fixtures are defined in the hardware map file as a list:: + + - available: true + connected: true + fixtures: + - gpio_loopback + id: 0240000026334e450015400f5e0e000b4eb1000097969900 + platform: frdm_k64f + product: DAPLink CMSIS-DAP + runner: pyocd + serial: /dev/ttyACM9 + +When running `twister` with ``--device-testing``, the configured fixture +in the hardware map file will be matched to testcases requesting the same fixtures +and these tests will be executed on the boards that provide this fixture. + +.. figure:: fixtures.svg + :figclass: align-center + +Notes ++++++ + +It may be useful to annotate board descriptions in the hardware map file +with additional information. Use the "notes" keyword to do this. For +example:: + + - available: true + connected: false + fixtures: + - gpio_loopback + id: 000683290670 + notes: An nrf5340pdk_nrf5340 is detected as an nrf52840dk_nrf52840 with no serial + port, and three serial ports with an unknown platform. The board id of the serial + ports is not the same as the board id of the the development kit. If you regenerate + this file you will need to update serial to reference the third port, and platform + to nrf5340pdk_nrf5340_cpuapp or another supported board target. + platform: nrf52840dk_nrf52840 + product: J-Link + runner: jlink + serial: null + +Overriding Board Identifier ++++++++++++++++++++++++++++ + +When (re-)generated the hardware map file will contain an "id" keyword +that serves as the argument to ``--board-id`` when flashing. In some +cases the detected ID is not the correct one to use, for example when +using an external J-Link probe. The "probe_id" keyword overrides the +"id" keyword for this purpose. For example:: + + - available: true + connected: false + id: 0229000005d9ebc600000000000000000000000097969905 + platform: mimxrt1060_evk + probe_id: 000609301751 + product: DAPLink CMSIS-DAP + runner: jlink + serial: null diff --git a/doc/guides/test/ztest.rst b/doc/guides/test/ztest.rst index dc28196b1223de..3544c33dd3cfcb 100644 --- a/doc/guides/test/ztest.rst +++ b/doc/guides/test/ztest.rst @@ -15,11 +15,11 @@ Quick start - Integration testing A simple working base is located at :zephyr_file:`samples/testing/integration`. Just copy the files to ``tests/`` and edit them for your needs. The test will then -be automatically built and run by the sanitycheck script. If you are testing +be automatically built and run by the twister script. If you are testing the **bar** component of **foo**, you should copy the sample folder to ``tests/foo/bar``. It can then be tested with:: - ./scripts/sanitycheck -s tests/foo/bar/test-identifier + ./scripts/twister -s tests/foo/bar/test-identifier In the example above ``tests/foo/bar`` signifies the path to the test and the @@ -27,7 +27,7 @@ In the example above ``tests/foo/bar`` signifies the path to the test and the To run all tests defined in a test project, run:: - ./scripts/sanitycheck -T tests/foo/bar/ + ./scripts/twister -T tests/foo/bar/ The sample contains the following files: @@ -95,14 +95,14 @@ Listing Tests Tests (test projects) in the Zephyr tree consist of many testcases that run as part of a project and test similar functionality, for example an API or a -feature. The ``sanitycheck`` script can parse the testcases in all +feature. The ``twister`` script can parse the testcases in all test projects or a subset of them, and can generate reports on a granular level, i.e. if cases have passed or failed or if they were blocked or skipped. Sanitycheck parses the source files looking for test case names, so you can list all kernel test cases, for example, by entering:: - sanitycheck --list-tests -T tests/kernel + twister --list-tests -T tests/kernel Skipping Tests ============== @@ -161,7 +161,7 @@ that interaction. Best practices for declaring the test suite =========================================== -*sanitycheck* and other validation tools need to obtain the list of +*twister* and other validation tools need to obtain the list of subcases that a Zephyr *ztest* test image will expose. .. admonition:: Rationale @@ -207,7 +207,7 @@ Here is a generic template for a test showing the expected use of ztest_run_test_suite(common); } -For *sanitycheck* to parse source files and create a list of subcases, +For *twister* to parse source files and create a list of subcases, the declarations of :func:`ztest_test_suite` must follow a few rules: - one declaration per line diff --git a/doc/guides/thread_local_storage.rst b/doc/guides/thread_local_storage.rst new file mode 100644 index 00000000000000..23d5de3d1ba0d4 --- /dev/null +++ b/doc/guides/thread_local_storage.rst @@ -0,0 +1,58 @@ +.. _thread_local_storage: + +Thread Local Storage (TLS) +########################## + +Thread Local Storage (TLS) allows variables to be allocated on a per-thread +basis. These variables are stored in the thread stack which means every +thread has its own copy of these variables. + +Zephyr currently requires toolchain support for TLS. + + +Configuration +************* + +To enable thread local storage in Zephyr, :option:`CONFIG_THREAD_LOCAL_STORAGE` +needs to be enabled. Note that this option may not be available if +the architecture or the SoC does not have the hidden option +:option:`CONFIG_ARCH_HAS_THREAD_LOCAL_STORAGE` enabled, which means +the architecture or the SoC does not have the necessary code to support +thread local storage and/or the toolchain does not support TLS. + +:option:`CONFIG_ERRNO_IN_TLS` can be enabled together with +:option:`CONFIG_ERRNO` to let the variable ``errno`` be a thread local +variable. This allows user threads to access the value of ``errno`` without +making a system call. + + +Declaring and Using Thread Local Variables +****************************************** + +The keyword ``__thread`` can be used to declare thread local variables. + +For example, to declare a thread local variable in header files: + +.. code-block:: c + + extern __thread int i; + +And to declare the actual variable in source files: + +.. code-block:: c + + __thread int i; + +Keyword ``static`` can also be used to limit the variable within a source file: + +.. code-block:: c + + static __thread int j; + +Using the thread local variable is the same as using other variable, for example: + +.. code-block:: c + + void testing(void) { + i = 10; + } diff --git a/doc/guides/tracing/index.rst b/doc/guides/tracing/index.rst index b4d0798033cbb1..a50cc378bdf966 100644 --- a/doc/guides/tracing/index.rst +++ b/doc/guides/tracing/index.rst @@ -77,10 +77,10 @@ CTF Top-Layer Example The CTF_EVENT macro will serialize each argument to a field:: /* Example for illustration */ - static inline void ctf_top_foo(u32_t thread_id, ctf_bounded_string_t name) + static inline void ctf_top_foo(uint32_t thread_id, ctf_bounded_string_t name) { CTF_EVENT( - CTF_LITERAL(u8_t, 42), + CTF_LITERAL(uint8_t, 42), thread_id, name, "hello, I was emitted from function: ", @@ -111,7 +111,11 @@ supported in Zephyr). To enable tracing support with `SEGGER SystemView`_ add the configuration option :option:`CONFIG_SEGGER_SYSTEMVIEW` to your project configuration file and set it to *y*. For example, this can be added to the -:ref:`synchronization_sample` to visualize fast switching between threads:: +:ref:`synchronization_sample` to visualize fast switching between threads. +SystemView can also be used for post-mortem tracing, which can be enabled with +`CONFIG_SEGGER_SYSVIEW_POST_MORTEM_MODE`. In this mode, a debugger can +be attached after the system has crashed using ``west attach`` after which the +latest data from the internal RAM buffer can be loaded into SystemView:: CONFIG_STDOUT_CONSOLE=y # enable to use thread names @@ -119,6 +123,8 @@ it to *y*. For example, this can be added to the CONFIG_SEGGER_SYSTEMVIEW=y CONFIG_USE_SEGGER_RTT=y CONFIG_TRACING=y + # enable for post-mortem tracing + CONFIG_SEGGER_SYSVIEW_POST_MORTEM_MODE=n .. figure:: segger_systemview.png diff --git a/doc/guides/west/build-flash-debug.rst b/doc/guides/west/build-flash-debug.rst index ed3b0c47a10091..59ad249c5fa7f6 100644 --- a/doc/guides/west/build-flash-debug.rst +++ b/doc/guides/west/build-flash-debug.rst @@ -141,22 +141,24 @@ Pristine Builds A *pristine* build directory is essentially a new build directory. All byproducts from previous builds have been removed. -To have ``west build`` make the build directory pristine before re-running -CMake to generate a build system, use the ``--pristine`` (or ``-p``) -option. For example, to switch board and application (which requires a pristine -build directory) in one command:: +To force ``west build`` make the build directory pristine before re-running +CMake to generate a build system, use the ``--pristine=always`` (or +``-p=always``) option. - west build -b qemu_x86 samples/philosophers - west build -p -b reel_board samples/hello_world +Giving ``--pristine`` or ``-p`` without a value has the same effect as giving +it the value ``always``. For example, these commands are equivalent:: -To let west decide for you if a pristine build is needed, use ``-p auto``:: + west build -p -b reel_board samples/hello_world + west build -p=always -b reel_board samples/hello_world - west build -p auto -b reel_board samples/hello_world +By default, ``west build`` applies a heuristic to detect if the build directory +needs to be made pristine. This is the same as using ``--pristine=auto``. .. tip:: - You can run ``west config build.pristine auto`` to make this setting - permanent. + You can run ``west config build.pristine always`` to always do a pristine + build, or ``west config build.pristine never`` to disable the heuristic. + See the ``west build`` :ref:`west-building-config` for details. .. _west-building-verbose: @@ -531,35 +533,20 @@ For example, to print usage information about the ``jlink`` runner:: .. _west-runner: -runners package API -******************* - -The flash and debug commands are implemented as west *extension -commands*: that is, they are west commands whose source code lives -outside the west repository. Some reasons this choice was made are: - -- Their implementations are tightly coupled to the Zephyr build - system, e.g. due to their reliance on CMake cache variables. - -- Pull requests adding features to them are almost always motivated by - a corresponding change to an upstream board, so it makes sense to - put them in Zephyr to avoid needing pull requests in multiple - repositories. - -- Many users find it natural to search for their implementations in - the Zephyr source tree. +Flash and debug runners +*********************** -The extension commands are a thin wrapper around a package called -``runners`` (this package is also in the Zephyr tree, in -:zephyr_file:`scripts/west_commands/runners`). +The flash and debug commands use Python wrappers around various +:ref:`flash-debug-host-tools`. These wrappers are all defined in a Python +library at :zephyr_file:`scripts/west_commands/runners`. Each wrapper is +called a *runner*. Runners can flash and/or debug Zephyr programs. -The central abstraction within this library is ``ZephyrBinaryRunner``, -an abstract class which represents *runner* objects, which can flash -and/or debug Zephyr programs. The set of available runners is +The central abstraction within this library is ``ZephyrBinaryRunner``, an +abstract class which represents runners. The set of available runners is determined by the imported subclasses of ``ZephyrBinaryRunner``. -``ZephyrBinaryRunner`` is available in the ``runners.core`` module; -individual runner implementations are in other submodules, such as -``runners.nrfjprog``, ``runners.openocd``, etc. +``ZephyrBinaryRunner`` is available in the ``runners.core`` module; individual +runner implementations are in other submodules, such as ``runners.nrfjprog``, +``runners.openocd``, etc. Hacking ******* diff --git a/doc/guides/west/index.rst b/doc/guides/west/index.rst index cc6c058dc0e2f8..fd0f1b38617454 100644 --- a/doc/guides/west/index.rst +++ b/doc/guides/west/index.rst @@ -4,30 +4,29 @@ West (Zephyr's meta-tool) ######################### The Zephyr project includes a swiss-army knife command line tool named -``west``\ [#west-name]_. West is developed in its own `repository`_. Like -``git`` and ``docker``, the top-level ``west`` command takes some common +``west``\ [#west-name]_. West is developed in its own `repository`_. + +West's built-in commands provide a multiple repository management system with +features inspired by Google's Repo tool and Git submodules. West is also +"pluggable": you can write your own west extension commands which add +additional features to west. Zephyr uses this to provide conveniences for +building applications, flashing and debugging them, and more. + +Like ``git`` and ``docker``, the top-level ``west`` command takes some common options, a sub-command to run, and then options and arguments for that sub-command:: west [common-opts] [opts] -West's built-in commands provide a multiple repository management -system with features inspired by Google's Repo tool and Git -submodules. West simplifies configuration and is also pluggable: you -can write your own west "extension commands" which add additional -features to west. Zephyr uses this feature to provide conveniences -for building applications, flashing and debugging them, and more. +Since west v0.8, you can also run west like this:: -It is possible not to use west for Zephyr development if you do not -require these features, prefer to use your own tools, or want to -eliminate the extra layer of indirection. However, this implies extra -effort and expert knowledge. + python3 -m west [common-opts] [opts] You can run ``west --help`` (or ``west -h`` for short) to get top-level help for available west commands, and ``west -h`` for detailed help on each command. -The following pages document west's ``v0.7.x`` releases, and provide additional +The following pages document west's ``v0.8.x`` releases, and provide additional context about the tool. .. toctree:: diff --git a/doc/guides/west/manifest.rst b/doc/guides/west/manifest.rst index 08dcb970bcf07a..35968c2379e28a 100644 --- a/doc/guides/west/manifest.rst +++ b/doc/guides/west/manifest.rst @@ -354,6 +354,7 @@ these in order, using examples: - :ref:`west-manifest-ex3.1` - :ref:`west-manifest-ex3.2` - :ref:`west-manifest-ex3.3` + - :ref:`west-manifest-ex3.4` - :ref:`Sequence of paths and mappings ` - :ref:`west-manifest-ex4.1` - :ref:`west-manifest-ex4.2` @@ -415,15 +416,16 @@ In other words, the west workspace you want looks like this: .. code-block:: none - my-downstream - ├── .west # west directory - ├── zephyr # mainline zephyr repository - ├── modules # modules from mainline zephyr - │   ├── hal + my-downstream/ + ├── .west/ # west directory + ├── zephyr/ # mainline zephyr repository + │ └── west.yml # the v1.14.1 version of this file is imported + ├── modules/ # modules from mainline zephyr + │   ├── hal/ │   └── [...other directories..] ├── [ ... other projects ...] # other mainline repositories - └── my-repo # your downstream repository - ├── west.yml + └── my-repo/ # your downstream repository + ├── west.yml # main manifest importing zephyr/west.yml v1.14.1 └── [...other files..] You can do this with the following :file:`my-repo/west.yml`: @@ -528,14 +530,14 @@ This manifest is similar to the one in :ref:`west-manifest-ex1.1`, except it: - name: my-remote url-base: https://git.example.com projects: - - name: hal_nordic + - name: hal_nordic # higher precedence remote: my-remote revision: my-sha path: modules/hal/nordic - name: zephyr remote: zephyrproject-rtos revision: v2.0.0 - import: true + import: true # imported projects have lower precedence # subset of zephyr/west.yml contents at v2.0.0: manifest: @@ -546,7 +548,7 @@ This manifest is similar to the one in :ref:`west-manifest-ex1.1`, except it: url-base: https://github.com/zephyrproject-rtos projects: # ... - - name: hal_nordic + - name: hal_nordic # lower precedence, values ignored path: modules/hal/nordic revision: another-sha @@ -757,6 +759,10 @@ The ``import`` key can also contain a mapping with the following keys: names to exclude rather than include. - ``path-blacklist``: Optional. Like ``path-whitelist``, but contains project paths to exclude rather than include. +- ``path-prefix``: Optional (new in v0.8.0). If given, this will be prepended + to the project's path in the workspace, as well as the paths of any imported + projects. This can be used to place these projects in a subdirectory of the + workspace. .. _re: https://docs.python.org/3/library/re.html .. _pathlib: @@ -780,13 +786,13 @@ hosted at ``https://git.example.com/mainline/manifest``. # mainline west.yml: manifest: projects: - - name: mainline-app + - name: mainline-app # included path: examples/app url: https://git.example.com/mainline/app - name: lib path: libraries/lib url: https://git.example.com/mainline/lib - - name: lib2 + - name: lib2 # included path: libraries/lib2 url: https://git.example.com/mainline/lib2 @@ -818,10 +824,10 @@ An equivalent manifest in a single file would be: - name: lib3 path: libraries/lib3 url: https://git.example.com/downstream/lib3 - - name: mainline-app + - name: mainline-app # imported path: examples/app url: https://git.example.com/mainline/app - - name: lib2 + - name: lib2 # imported path: libraries/lib2 url: https://git.example.com/mainline/lib2 @@ -845,10 +851,10 @@ using ``path-whitelist``. path: examples/app url: https://git.example.com/mainline/app - name: lib - path: libraries/lib + path: libraries/lib # included url: https://git.example.com/mainline/lib - name: lib2 - path: libraries/lib2 + path: libraries/lib2 # included url: https://git.example.com/mainline/lib2 # downstream west.yml: @@ -870,10 +876,10 @@ An equivalent manifest in a single file would be: manifest: projects: - - name: lib + - name: lib # imported path: libraries/lib url: https://git.example.com/mainline/lib - - name: lib2 + - name: lib2 # imported path: libraries/lib2 url: https://git.example.com/mainline/lib2 - name: mainline @@ -909,11 +915,11 @@ you're targeting, and keep everything else. - name: lib2 path: libraries/lib2 - name: hal_foo - path: modules/hals/foo + path: modules/hals/foo # excluded - name: hal_bar - path: modules/hals/bar + path: modules/hals/bar # excluded - name: hal_baz - path: modules/hals/baz + path: modules/hals/baz # excluded # downstream west.yml: manifest: @@ -937,10 +943,10 @@ An equivalent manifest in a single file would be: - name: mainline url-base: https://git.example.com/mainline projects: - - name: app - - name: lib + - name: app # imported + - name: lib # imported path: libraries/lib - - name: lib2 + - name: lib2 # imported path: libraries/lib2 - name: mainline repo-path: https://git.example.com/mainline/manifest @@ -948,6 +954,71 @@ An equivalent manifest in a single file would be: path: modules/hals/foo url: https://git.example.com/downstream/hal_foo +.. _west-manifest-ex3.4: + +Example 3.4: Import into a subdirectory +--------------------------------------- + +You want to import a manifest and its projects, placing everything into a +subdirectory of your :term:`west workspace`. + +For example, suppose you want to import this manifest from project ``foo``, +adding this project and its projects ``bar`` and ``baz`` to your workspace: + +.. code-block:: yaml + + # foo/west.yml: + manifest: + defaults: + remote: example + remotes: + - name: example + url-base: https://git.example.com + projects: + - name: bar + - name: baz + +Instead of importing these into the top level workspace, you want to place all +three project repositories in an :file:`external-code` subdirectory, like this: + +.. code-block:: none + + workspace/ + └── external-code/ + ├── foo/ + ├── bar/ + └── baz/ + +You can do this using this manifest: + +.. code-block:: yaml + + manifest: + projects: + - name: foo + url: https://git.example.com/foo + import: + path-prefix: external-code + +An equivalent manifest in a single file would be: + +.. code-block:: yaml + + # foo/west.yml: + manifest: + defaults: + remote: example + remotes: + - name: example + url-base: https://git.example.com + projects: + - name: foo + path: external-code/foo + - name: bar + path: external-code/bar + - name: baz + path: external-code/baz + .. _west-manifest-import-seq: Option 4: Sequence @@ -1167,3 +1238,17 @@ or fails with an error: west manifest --validate The error message can help diagnose errors. + +.. _west-manifest-path: + +Get the manifest path +===================== + +The ``--path`` action prints the path to the top level manifest file: + +.. code-block:: none + + west manifest --path + +The output is something like ``/path/to/workspace/west.yml``. The path format +depends on your operating system. diff --git a/doc/guides/west/release-notes.rst b/doc/guides/west/release-notes.rst index bd705813a1b8f7..b2eb735585412f 100644 --- a/doc/guides/west/release-notes.rst +++ b/doc/guides/west/release-notes.rst @@ -1,6 +1,59 @@ West Release Notes ################## +v0.8.0 +****** + +This is a feature release which changes the manifest schema by adding support +for a ``path-prefix:`` key in an ``import:`` mapping, along with some other +features and fixes. + +- Manifest import mappings now support a ``path-prefix:`` key, which places + the project and its imported repositories in a subdirectory of the workspace. + See :ref:`west-manifest-ex3.4` for an example. +- The west command line application can now also be run using ``python3 -m + west``. This makes it easier to run west under a particular Python + interpreter without modifying the :envvar:`PATH` environment variable. +- :ref:`west manifest --path ` prints the absolute path to + west.yml +- ``west init`` now supports an ``--mf foo.yml`` option, which initializes the + workspace using :file:`foo.yml` instead of :file:`west.yml`. +- ``west list`` now prints the manifest repository's path using the + ``manifest.path`` :ref:`configuration option `, which may differ + from the ``self: path:`` value in the manifest data. The old behavior is + still available, but requires passing a new ``--manifest-path-from-yaml`` + option. +- Various Python API changes; see :ref:`west-apis` for details. + +v0.7.3 +****** + +This is a bugfix release. + +- Fix an error where a failed import could leave the workspace in an unusable + state (see [PR #415](https://github.com/zephyrproject-rtos/west/pull/415) for + details) + +v0.7.2 +****** + +This is a bugfix and minor feature release. + +- Filter out duplicate extension commands brought in by manifest imports +- Fix ``west.Manifest.get_projects()`` when finding the manifest repository by + path + +v0.7.1 +****** + +This is a bugfix and minor feature release. + +- ``west update --stats`` now prints timing for operations which invoke a + subprocess, time spent in west's Python process for each project, and total + time updating each project. +- ``west topdir`` always prints a POSIX style path +- minor console output changes + v0.7.0 ****** diff --git a/doc/guides/west/repo-tool.rst b/doc/guides/west/repo-tool.rst index cc596cea69adb9..0f5fd26cf1a872 100644 --- a/doc/guides/west/repo-tool.rst +++ b/doc/guides/west/repo-tool.rst @@ -32,16 +32,16 @@ like this: .. code-block:: none - zephyrproject - ├── .west + zephyrproject/ # west topdir + ├── .west/ │ └── config - ├── zephyr - │ ├── west.yml - │ └── [... other files ...] - ├── modules - │ └── lib - │ └── tinycbor - ├── net-tools + ├── zephyr/ # .git/ │ + │ ├── west.yml # manifest │ never modified by west + │ └── [... other files ...] │ + ├── modules/ + │ └── lib/ + │ └── tinycbor/ # .git/ project + ├── net-tools/ # .git/ project └── [ ... other projects ...] Above, :file:`zephyrproject` is the name of the west workspace's root @@ -111,17 +111,23 @@ A workspace using this topology looks like this: .. code-block:: none - west-workspace - ├── application - │   ├── CMakeLists.txt - │   ├── prj.conf - │   ├── src - │   │   └── main.c - │   └── west.yml - ├── modules - │   └── lib - │   └── tinycbor - └── zephyr + west-workspace/ + │ + ├── application/ # .git/ │ + │   ├── CMakeLists.txt │ + │   ├── prj.conf │ never modified by west + │   ├── src/ │ + │   │   └── main.c │ + │   └── west.yml # main manifest with optional import(s) and override(s) + │ │ + ├── modules/ + │   └── lib/ + │   └── tinycbor/ # .git/ project from either the main manifest or some import. + │ + └── zephyr/ # .git/ project + └── west.yml # This can be partially imported with lower precedence or ignored. + # Only the 'manifest-rev' version can be imported. + Here is an example :file:`application/west.yml` which uses :ref:`west-manifest-import`, available since west 0.7, to import Zephyr v2.2.0 @@ -192,23 +198,28 @@ A workspace using this topology looks like this: .. code-block:: none - west-workspace - ├── app1 + west-workspace/ + ├── app1/ # .git/ project │   ├── CMakeLists.txt │   ├── prj.conf - │   └── src + │   └── src/ │   └── main.c - ├── app2 + ├── app2/ # .git/ project │   ├── CMakeLists.txt │   ├── prj.conf - │   └── src + │   └── src/ │   └── main.c - ├── manifest-repo - │   └── west.yml - ├── modules - │   └── lib - │   └── tinycbor - └── zephyr + ├── manifest-repo/ # .git/ never modified by west + │   └── west.yml # main manifest with optional import(s) and override(s) + ├── modules/ + │   └── lib/ + │   └── tinycbor/ # .git/ project from either the main manifest or + │ # frome some import + │ + └── zephyr/ # .git/ project + └── west.yml # This can be partially imported with lower precedence or ignored. + # Only the 'manifest-rev' version can be imported. + Here is an example T3 :file:`manifest-repo/west.yml` which uses :ref:`west-manifest-import`, available since west 0.7, to import Zephyr @@ -389,6 +400,114 @@ discussed here. Run ``west -h`` for detailed help. - ``west topdir``: Prints the top directory of the west workspace. +Private repositories +******************** + +You can use west to fetch from private repositories. There is nothing +west-specific about this. + +The ``west update`` command essentially runs ``git fetch YOUR_PROJECT_URL`` +when a project's ``manifest-rev`` branch must be updated to a newly fetched +commit. It's up to your environment to make sure the fetch succeeds. + +You can either enter the password manually or use any of the `credential +helpers built in to Git`_. Since Git has credential storage built in, there is +no need for a west-specific feature. + +The following sections cover common cases for running ``west update`` without +having to enter your password, as well as how to troubleshoot issues. + +.. _credential helpers built in to Git: + https://git-scm.com/docs/gitcredentials + +Fetching via HTTPS +================== + +On Windows when fetching from GitHub, recent versions of Git prompt you for +your GitHub password in a graphical window once, then store it for future use +(in a default installation). Passwordless fetching from GitHub should therefore +work "out of the box" on Windows after you have done it once. + +In general, you can store your credentials on disk using the "store" git +credential helper. See the `git-credential-store`_ manual page for details. + +To use this helper for all the repositories in your workspace, run: + +.. code-block:: shell + + west forall -c "git config credential.helper store" + +To use this helper on just the projects ``foo`` and ``bar``, run: + +.. code-block:: shell + + west forall -c "git config credential.helper store" foo bar + +To use this helper by default on your computer, run: + +.. code-block:: shell + + git config --global credential.helper store + +On GitHub, you can set up a `personal access token`_ to use in place of your +account password. (This may be required if your account has two-factor +authentication enabled, and may be preferable to storing your account password +in plain text even if two-factor authentication is disabed.) + +If you don't want to store any credentials on the file system, you can store +them in memory temporarily using `git-credential-cache`_ instead. + +.. _git-credential-store: + https://git-scm.com/docs/git-credential-store#_examples +.. _git-credential-cache: + https://git-scm.com/docs/git-credential-cache +.. _personal access token: + https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token + +Fetching via SSH +================ + +If your SSH key has no password, fetching should just work. If it does have a +password, you can avoid entering it manually every time using `ssh-agent`_. + +On GitHub, see `Connecting to GitHub with SSH`_ for details on configuration +and key creation. + +.. _ssh-agent: + https://www.ssh.com/ssh/agent +.. _Connecting to GitHub with SSH: + https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh + +Troubleshooting +=============== + +One good way to troubleshoot fetching issues is to run ``west update`` in +verbose mode, like this: + +.. code-block:: shell + + west -v update + +The output includes Git commands run by west and their outputs. Look for +something like this: + +.. code-block:: none + + === updating your_project (path/to/your/project): + west.manifest: your_project: checking if cloned + [...other west.manifest logs...] + --- your_project: fetching, need revision SOME_SHA + west.manifest: running 'git fetch ... https://github.com/your-username/your_project ...' in /some/directory + +The ``git fetch`` command example in the last line above is what needs to +succeed. Go to ``/some/directory``, copy/paste and run the entire ``git fetch`` +command, then debug from there using the documentation for your credential +storage helper. + +If you can get the ``git fetch`` command to run successfully without prompting +for a password when you run it directly, you will be able to run ``west +update`` without entering your password in that same shell. + .. _PyPI: https://pypi.org/project/west/ diff --git a/doc/guides/west/sign.rst b/doc/guides/west/sign.rst index 5fe5828efe8997..a386d0f4d03275 100644 --- a/doc/guides/west/sign.rst +++ b/doc/guides/west/sign.rst @@ -3,65 +3,91 @@ Signing Binaries ################ -This page documents the ``west sign`` :ref:`extension ` -command included in the zephyr repository. It is used to sign a Zephyr -application binary for consumption by a bootloader using an external tool. - -Currently, it supports signing binaries for use with the `MCUboot`_ bootloader, -using the `imgtool`_ program provided by its developers. Using ``west sign`` as -a wrapper around ``imgtool`` for Zephyr binaries is more convenient than using -``imgtool`` directly, because ``west sign`` knows how to read numeric values -needed by ``imgtool`` out of an application build directory. These values -differ depending on your :ref:`board `, so using ``west sign`` means -both shorter command lines and not having to learn or memorize -hardware-specific details. - -To produce signed ``.bin`` and ``.hex`` files for a Zephyr application, make -sure ``imgtool`` is installed (e.g. with ``pip3 install imgtool`` on macOS and -Windows, and ``pip3 install --user imgtool`` on Linux), then run: +The ``west sign`` :ref:`extension ` command can be used to +sign a Zephyr application binary for consumption by a bootloader using an +external tool. Run ``west sign -h`` for command line help. -.. code-block:: console - - west sign -t imgtool -d YOUR_BUILD_DIR -- --key YOUR_SIGNING_KEY.pem - -Above, :file:`YOUR_BUILD_DIR` is a Zephyr build directory containing an -application compiled for MCUboot (in practice, this means -:option:`CONFIG_BOOTLOADER_MCUBOOT` is ``y`` in the application's Kconfig). - -Some additional notes follow. See ``west sign -h`` for detailed help. +MCUboot / imgtool +***************** -- The default ``-d`` value is ``build``, which is the default output directory - created by :ref:`west build `. -- If you don't have your own signing key and have a default MCUboot build, use - ``--key path/to/mcuboot/root-rsa-2048.pem``. -- By default, the output files produced by ``west sign`` are named - :file:`zephyr.signed.bin` and :file:`zephyr.signed.hex` and are created in the - build directory next to the unsigned :file:`zephyr.bin` and :file:`zephyr.hex` - versions. +The Zephyr build system has special support for signing binaries for use with +the `MCUboot`_ bootloader using the `imgtool`_ program provided by its +developers. You can both build and sign this type of application binary in one +step by setting some Kconfig options. If you do, ``west flash`` will use the +signed binaries. - You can control this using the ``-B`` and ``-H`` options, e.g. this would - create :file:`my-signed.bin` and :file:`my-signed.hex` in the current working - directory instead: +If you use this feature, you don't need to run ``west sign`` yourself; the +build system will do it for you. - .. code-block:: console - - west sign -t imgtool -B my-signed.bin -H my-signed.hex [...] - -Example build flow -****************** - -For reference, here is an example showing how to build :ref:`hello_world` for -MCUboot using ``west``: +Here is an example workflow, which builds and flashes MCUboot, as well as the +:ref:`hello_world` application for chain-loading by MCUboot. Run these commands +from the :file:`zephyrproject` workspace you created in the +:ref:`getting_started`. .. code-block:: console - west build -b YOUR_BOARD samples/hello_world -- -DCONFIG_BOOTLOADER_MCUBOOT=y - west sign -t imgtool -- --key YOUR_SIGNING_KEY.pem - west flash --hex-file build/zephyr/zephyr.signed.hex - -The availability of a hex file, and whether ``west flash`` uses it to flash, -depends on your board and build configuration. At least the west flash runners -using ``nrfjprog`` and ``pyocd`` work with the above flow. + west build -b YOUR_BOARD -s bootloader/mcuboot/boot/zephyr -d build-mcuboot + west build -b YOUR_BOARD -s zephyr/samples/hello_world -d build-hello-signed -- \ + -DCONFIG_BOOTLOADER_MCUBOOT=y \ + -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"bootloader/mcuboot/root-rsa-2048.pem\" + + west flash -d build-mcuboot + west flash -d build-hello-signed + +Notes on the above commands: + +- ``YOUR_BOARD`` should be changed to match your board +- The ``CONFIG_MCUBOOT_SIGNATURE_KEY_FILE`` value is the insecure default + provided and used by by MCUboot for development and testing +- You can change the ``hello_world`` application directory to any other + application that can be loaded by MCUboot, such as the :ref:`smp_svr_sample` + +For more information on these and other related configuration options, see: + +- :option:`CONFIG_BOOTLOADER_MCUBOOT`: build the application for loading by + MCUboot +- :option:`CONFIG_MCUBOOT_SIGNATURE_KEY_FILE`: the key file to use with ``west + sign``. If you have your own key, change this appropriately +- :option:`CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS`: optional additional command line + arguments for ``imgtool`` +- :option:`CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE`: also generate a confirmed + image, which may be more useful for flashing in production environments than + the OTA-able default image +- On Windows, if you get "Access denied" issues, the recommended fix is + to run ``pip3 install imgtool``, then retry with a pristine build directory. + +If your ``west flash`` :ref:`runner ` uses an image format +supported by imgtool, you should see something like this on your device's +serial console when you run ``west flash -d build-mcuboot``: + +.. code-block:: none + + *** Booting Zephyr OS build zephyr-v2.3.0-2310-gcebac69c8ae1 *** + [00:00:00.004,669] mcuboot: Starting bootloader + [00:00:00.011,169] mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 + [00:00:00.021,636] mcuboot: Boot source: none + [00:00:00.027,313] mcuboot: Failed reading image headers; Image=0 + [00:00:00.035,064] mcuboot: Unable to find bootable image + +Then, you should see something like this when you run ``west flash -d +build-hello-signed``: + +.. code-block:: none + + *** Booting Zephyr OS build zephyr-v2.3.0-2310-gcebac69c8ae1 *** + [00:00:00.004,669] mcuboot: Starting bootloader + [00:00:00.011,169] mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 + [00:00:00.021,636] mcuboot: Boot source: none + [00:00:00.027,374] mcuboot: Swap type: none + [00:00:00.115,142] mcuboot: Bootloader chainload address offset: 0xc000 + [00:00:00.123,168] mcuboot: Jumping to the first image slot + *** Booting Zephyr OS build zephyr-v2.3.0-2310-gcebac69c8ae1 *** + Hello World! nrf52840dk_nrf52840 + +Whether ``west flash`` supports this feature depends on your runner. The +``nrfjprog`` and ``pyocd`` runners work with the above flow. If your runner +does not support this flow and you would like it to, please send a patch or +file an issue for adding support. .. _MCUboot: https://mcuboot.com/ diff --git a/doc/guides/west/troubleshooting.rst b/doc/guides/west/troubleshooting.rst index d4c075b86d6012..0d354df3b8a5e3 100644 --- a/doc/guides/west/troubleshooting.rst +++ b/doc/guides/west/troubleshooting.rst @@ -5,6 +5,48 @@ Troubleshooting West This page covers common issues with west and how to solve them. +"'west' is not recognized as an internal or external command, operable program or batch file.' +********************************************************************************************** + +On Windows, this means that either west is not installed, or your :envvar:`PATH` +environment variable does not contain the directory where pip installed +:file:`west.exe`. + +First, make sure you've installed west; see :ref:`west-install`. Then try +running ``west`` from a new ``cmd.exe`` window. If that still doesn't work, +keep reading. + +You need to find the directory containing :file:`west.exe`, then add it to your +:envvar:`PATH`. (This :envvar:`PATH` change should have been done for you when +you installed Python and pip, so ordinarily you should not need to follow these +steps.) + +Run this command in ``cmd.exe``:: + + pip3 show west + +Then: + +#. Look for a line in the output that looks like ``Location: + C:\foo\python\python38\lib\site-packages``. The exact location + will be different on your computer. +#. Look for a file named ``west.exe`` in the ``scripts`` directory + ``C:\foo\python\python38\scripts``. + + .. important:: + + Notice how ``lib\site-packages`` in the ``pip3 show`` output was changed + to ``scripts``! +#. If you see ``west.exe`` in the ``scripts`` directory, add the full path to + ``scripts`` to your :envvar:`PATH` using a command like this:: + + setx PATH "%PATH%;C:\foo\python\python38\scripts" + + **Do not just copy/paste this command**. The ``scripts`` directory location + will be different on your system. +#. Close your ``cmd.exe`` window and open a new one. You should be able to run + ``west``. + "Error: unexpected keyword argument 'requires_workspace'" ********************************************************* diff --git a/doc/guides/west/west-apis.rst b/doc/guides/west/west-apis.rst index 41328d1c0fdd65..2bd3efc396e94b 100644 --- a/doc/guides/west/west-apis.rst +++ b/doc/guides/west/west-apis.rst @@ -93,6 +93,8 @@ WestCommand .. automethod:: __init__ + .. versionchanged:: 0.8.0 + The *topdir* parameter can now be any ``os.PathLike``. .. versionadded:: 0.6.0 The *requires_installation* parameter. .. versionadded:: 0.7.0 @@ -141,6 +143,9 @@ Reading and writing options .. autofunction:: west.configuration.read_config +.. versionchanged:: 0.8.0 + The deprecated *read_config* parameter was removed. + .. versionchanged:: 0.6.0 Errors due to an inability to find a local configuration file are ignored. @@ -231,19 +236,24 @@ Manifest and sub-objects .. automethod:: __init__ .. versionchanged:: 0.7.0 - The ``importer`` and ``import_flags`` keyword arguments. + The *importer* and *import_flags* keyword arguments. .. automethod:: from_file + .. versionchanged:: 0.8.0 + The *source_file*, *manifest_path*, and *topdir* arguments + can now be any ``os.PathLike``. .. versionchanged:: 0.7.0 ``**kwargs`` added. .. automethod:: from_data .. versionchanged:: 0.7.0 - ``**kwargs`` added, and ``source_data`` may be a ``str``. + ``**kwargs`` added, and *source_data* may be a ``str``. Conveniences for accessing sub-objects by name or other identifier: .. automethod:: get_projects + .. versionchanged:: 0.8.0 + The *project_ids* sequence can now contain any ``os.PathLike``. .. versionadded:: 0.6.1 Additional methods: @@ -257,22 +267,31 @@ Manifest and sub-objects .. versionadded:: 0.7.0 .. autoclass:: west.manifest.ImportFlag + :members: + :member-order: bysource .. autoclass:: west.manifest.Project .. (note: attributes are part of the class docstring) + .. versionchanged:: 0.8.0 + The *west_commands* attribute is now always a list. In previous + releases, it could be a string or ``None``. + .. versionchanged:: 0.7.0 - The ``remote`` attribute was removed. Its semantics could no longer + The *remote* attribute was removed. Its semantics could no longer be preserved when support for manifest ``import`` keys was added. .. versionadded:: 0.7.0 - The ``remote_name`` and ``name_and_path`` attributes. + The *remote_name* and *name_and_path* attributes. Constructor: .. automethod:: __init__ + .. versionchanged:: 0.8.0 + The *path* and *topdir* parameters can now be any ``os.PathLike``. + .. versionchanged:: 0.7.0 The parameters were incompatibly changed from previous versions. @@ -283,7 +302,7 @@ Manifest and sub-objects .. automethod:: git .. versionchanged:: 0.6.1 - The ``capture_stderr`` kwarg. + The *capture_stderr* kwarg. .. versionchanged:: 0.7.0 The (now removed) ``Project.format`` method is no longer called on arguments. @@ -293,18 +312,30 @@ Manifest and sub-objects Standard error is now captured. .. automethod:: is_ancestor_of + .. versionchanged:: 0.8.0 + The *cwd* parameter can now be any ``os.PathLike``. .. automethod:: is_cloned + .. versionchanged:: 0.8.0 + The *cwd* parameter can now be any ``os.PathLike``. .. versionadded:: 0.6.1 .. automethod:: is_up_to_date_with + .. versionchanged:: 0.8.0 + The *cwd* parameter can now be any ``os.PathLike``. .. automethod:: is_up_to_date + .. versionchanged:: 0.8.0 + The *cwd* parameter can now be any ``os.PathLike``. .. automethod:: read_at + .. versionchanged:: 0.8.0 + The *cwd* parameter can now be any ``os.PathLike``. .. versionadded:: 0.7.0 .. automethod:: listdir_at + .. versionchanged:: 0.8.0 + The *cwd* parameter can now be any ``os.PathLike``. .. versionadded:: 0.7.0 .. autoclass:: west.manifest.ManifestProject @@ -312,6 +343,11 @@ Manifest and sub-objects A limited subset of Project methods is supported. Results for calling others are not specified. + .. versionchanged:: 0.8.0 + The *url* attribute is now the empty string instead of ``None``. + The *abspath* attribute is created using ``os.path.abspath()`` + instead of ``os.path.realpath()``, improving support for symbolic links. + .. automethod:: as_dict .. versionadded:: 0.6.0 @@ -328,9 +364,15 @@ Exceptions .. autoclass:: west.manifest.ManifestVersionError :show-inheritance: + .. versionchanged:: 0.8.0 + The *file* argument can now be any ``os.PathLike``. + .. autoclass:: west.manifest.ManifestImportFailed :show-inheritance: + .. versionchanged:: 0.8.0 + The *filename* argument can now be any ``os.PathLike``. + .. _west-apis-util: west.util @@ -345,8 +387,14 @@ Functions .. autofunction:: west.util.west_dir + .. versionchanged:: 0.8.0 + The *start* parameter can be any ``os.PathLike``. + .. autofunction:: west.util.west_topdir + .. versionchanged:: 0.8.0 + The *start* parameter can be any ``os.PathLike``. + Exceptions ========== diff --git a/doc/guides/west/without-west.rst b/doc/guides/west/without-west.rst index 7078578f0dfcaa..0f371c04df2f91 100644 --- a/doc/guides/west/without-west.rst +++ b/doc/guides/west/without-west.rst @@ -66,7 +66,7 @@ etc. is just a call to the corresponding :ref:`west command `. For example, ``ninja flash`` calls ``west flash``\ [#wbninja]_. If you don't have west installed on your system, running those targets will fail. You can of course still flash and debug using -any :ref:`debug-host-tools` which work for your board (and which those +any :ref:`flash-debug-host-tools` which work for your board (and which those west commands wrap). If you want to use these build system targets but do not want to diff --git a/doc/guides/zephyr_cmake_package.rst b/doc/guides/zephyr_cmake_package.rst index ff8e749f846b45..c650e7fc471395 100644 --- a/doc/guides/zephyr_cmake_package.rst +++ b/doc/guides/zephyr_cmake_package.rst @@ -58,11 +58,16 @@ Zephyr CMake package is exported to the CMake user package registry using the fo .. code-block:: bash - cmake -S /share/zephyr-package/cmake -B /share/zephyr-package/cmake - cmake --build /share/zephyr-package/cmake --target pristine + cmake -P /share/zephyr-package/cmake/zephyr_export.cmake + +This will export the current Zephyr to the CMake user package registry. + +To also export the Zephyr Unittest CMake package, run the following command in addition: + +.. code-block:: bash + + cmake -P /share/zephyrunittest-package/cmake/zephyr_export.cmake -This will export the current Zephyr to the CMake user package registry and remove the temporary -files generated by CMake during export. .. _zephyr_cmake_package_zephyr_base: diff --git a/doc/introduction/index.rst b/doc/introduction/index.rst index 04dcf2e3412504..bdf2f51ea53628 100644 --- a/doc/introduction/index.rst +++ b/doc/introduction/index.rst @@ -8,9 +8,18 @@ resource-constrained and embedded systems: from simple embedded environmental sensors and LED wearables to sophisticated embedded controllers, smart watches, and IoT wireless applications. -The Zephyr kernel supports multiple architectures, including ARM Cortex-M, Intel -x86, ARC, NIOS II, Tensilica Xtensa and RISC-V 32. The full list of supported -boards can be found :ref:`here `. +The Zephyr kernel supports multiple architectures, including: + - ARC EM and HS + - ARMv6-M, ARMv7-M, and ARMv8-M (Cortex-M) + - ARMv7-A and ARMv8-A (Cortex-A, 32- and 64-bit) + - ARMv7-R (Cortex-R) + - Intel x86 (32- and 64-bit) + - NIOS II Gen 2 + - RISC-V (32- and 64-bit) + - SPARC V8 + - Tensilica Xtensa + +The full list of supported boards based on these architectures can be found :ref:`here `. Licensing ********* diff --git a/doc/reference/audio/dmic.rst b/doc/reference/audio/dmic.rst index a4a46d8319957f..5ec64c7c55fec8 100644 --- a/doc/reference/audio/dmic.rst +++ b/doc/reference/audio/dmic.rst @@ -1,7 +1,7 @@ .. _audio_dmic_api: -DMIC -#### +Audio DMIC +########## Overview ******** diff --git a/doc/reference/peripherals/i2s.rst b/doc/reference/audio/i2s.rst similarity index 100% rename from doc/reference/peripherals/i2s.rst rename to doc/reference/audio/i2s.rst diff --git a/doc/reference/audio/index.rst b/doc/reference/audio/index.rst index 0728dd6103a270..61aa366b3b158f 100644 --- a/doc/reference/audio/index.rst +++ b/doc/reference/audio/index.rst @@ -8,3 +8,4 @@ Audio codec.rst dmic.rst + i2s.rst diff --git a/doc/reference/bluetooth/connection_mgmt.rst b/doc/reference/bluetooth/connection_mgmt.rst index bf406f614e2f2e..10eb91d08bd716 100644 --- a/doc/reference/bluetooth/connection_mgmt.rst +++ b/doc/reference/bluetooth/connection_mgmt.rst @@ -3,26 +3,26 @@ Connection Management ##################### -The Zephyr Bluetooth stack uses an abstraction called :c:type:`bt_conn` +The Zephyr Bluetooth stack uses an abstraction called :c:struct:`bt_conn` to represent connections to other devices. The internals of this struct are not exposed to the application, but a limited amount of information (such as the remote address) can be acquired using the -:cpp:func:`bt_conn_get_info` API. Connection objects are reference +:c:func:`bt_conn_get_info` API. Connection objects are reference counted, and the application is expected to use the -:cpp:func:`bt_conn_ref` API whenever storing a connection pointer for a +:c:func:`bt_conn_ref` API whenever storing a connection pointer for a longer period of time, since this ensures that the object remains valid (even if the connection would get disconnected). Similarly the -:cpp:func:`bt_conn_unref` API is to be used when releasing a reference +:c:func:`bt_conn_unref` API is to be used when releasing a reference to a connection. An application may track connections by registering a -:c:type:`bt_conn_cb` struct using the :cpp:func:`bt_conn_cb_register` +:c:struct:`bt_conn_cb` struct using the :c:func:`bt_conn_cb_register` API. This struct lets the application define callbacks for connection & disconnection events, as well as other events related to a connection such as a change in the security level or the connection parameters. When acting as a central the application will also get hold of the connection object through the return value of the -:cpp:func:`bt_conn_create_le` API. +:c:func:`bt_conn_create_le` API. API Reference ************* diff --git a/doc/reference/bluetooth/gatt.rst b/doc/reference/bluetooth/gatt.rst index 4711ec4d5e9397..3229923383ed1d 100644 --- a/doc/reference/bluetooth/gatt.rst +++ b/doc/reference/bluetooth/gatt.rst @@ -7,39 +7,39 @@ Generic Attribute Profile (GATT) GATT layer manages the service database providing APIs for service registration and attribute declaration. -Services can be registered using :cpp:func:`bt_gatt_service_register` API -which takes the :cpp:class:`bt_gatt_service` struct that provides the list of -attributes the service contains. The helper macro :cpp:func:`BT_GATT_SERVICE` +Services can be registered using :c:func:`bt_gatt_service_register` API +which takes the :c:struct:`bt_gatt_service` struct that provides the list of +attributes the service contains. The helper macro :c:macro:`BT_GATT_SERVICE()` can be used to declare a service. -Attributes can be declared using the :cpp:class:`bt_gatt_attr` struct or using +Attributes can be declared using the :c:struct:`bt_gatt_attr` struct or using one of the helper macros: - :cpp:func:`BT_GATT_PRIMARY_SERVICE` + :c:macro:`BT_GATT_PRIMARY_SERVICE` Declares a Primary Service. - :cpp:func:`BT_GATT_SECONDARY_SERVICE` + :c:macro:`BT_GATT_SECONDARY_SERVICE` Declares a Secondary Service. - :cpp:func:`BT_GATT_INCLUDE_SERVICE` + :c:macro:`BT_GATT_INCLUDE_SERVICE` Declares a Include Service. - :cpp:func:`BT_GATT_CHARACTERISTIC` + :c:macro:`BT_GATT_CHARACTERISTIC` Declares a Characteristic. - :cpp:func:`BT_GATT_DESCRIPTOR` + :c:macro:`BT_GATT_DESCRIPTOR` Declares a Descriptor. - :cpp:func:`BT_GATT_ATTRIBUTE` + :c:macro:`BT_GATT_ATTRIBUTE` Declares an Attribute. - :cpp:func:`BT_GATT_CCC` + :c:macro:`BT_GATT_CCC` Declares a Client Characteristic Configuration. - :cpp:func:`BT_GATT_CEP` + :c:macro:`BT_GATT_CEP` Declares a Characteristic Extended Properties. - :cpp:func:`BT_GATT_CUD` + :c:macro:`BT_GATT_CUD` Declares a Characteristic User Format. Each attribute contain a ``uuid``, which describes their type, a ``read`` @@ -51,18 +51,18 @@ respective operations. Attribute ``read`` and ``write`` callbacks are called directly from RX Thread thus it is not recommended to block for long periods of time in them. -Attribute value changes can be notified using :cpp:func:`bt_gatt_notify` API, -alternatively there is :cpp:func:`bt_gatt_notify_cb` where is is possible to +Attribute value changes can be notified using :c:func:`bt_gatt_notify` API, +alternatively there is :c:func:`bt_gatt_notify_cb` where is is possible to pass a callback to be called when it is necessary to know the exact instant when the data has been transmitted over the air. Indications are supported by -:cpp:func:`bt_gatt_indicate` API. +:c:func:`bt_gatt_indicate` API. Client procedures can be enabled with the configuration option: :option:`CONFIG_BT_GATT_CLIENT` Discover procedures can be initiated with the use of -:cpp:func:`bt_gatt_discover` API which takes the -:cpp:class:`bt_gatt_discover_params` struct which describes the type of +:c:func:`bt_gatt_discover` API which takes the +:c:struct:`bt_gatt_discover_params` struct which describes the type of discovery. The parameters also serves as a filter when setting the ``uuid`` field only attributes which matches will be discovered, in contrast setting it to NULL allows all attributes to be discovered. @@ -70,23 +70,23 @@ to NULL allows all attributes to be discovered. .. note:: Caching discovered attributes is not supported. -Read procedures are supported by :cpp:func:`bt_gatt_read` API which takes the -:cpp:class:`bt_gatt_read_params` struct as parameters. In the parameters one or +Read procedures are supported by :c:func:`bt_gatt_read` API which takes the +:c:struct:`bt_gatt_read_params` struct as parameters. In the parameters one or more attributes can be set, though setting multiple handles requires the option: :option:`CONFIG_BT_GATT_READ_MULTIPLE` -Write procedures are supported by :cpp:func:`bt_gatt_write` API and takes -:cpp:class:`bt_gatt_write_params` struct as parameters. In case the write -operation don't require a response :cpp:func:`bt_gatt_write_without_response` -or :cpp:func:`bt_gatt_write_without_response_cb` APIs can be used, with the -later working similarly to ``bt_gatt_notify_cb``. +Write procedures are supported by :c:func:`bt_gatt_write` API and takes +:c:struct:`bt_gatt_write_params` struct as parameters. In case the write +operation don't require a response :c:func:`bt_gatt_write_without_response` +or :c:func:`bt_gatt_write_without_response_cb` APIs can be used, with the +later working similarly to :c:func:`bt_gatt_notify_cb`. Subscriptions to notification and indication can be initiated with use of -:cpp:func`bt_gatt_subscribe` API which takes -:cpp:class:`bt_gatt_subscribe_params` as parameters. Multiple subscriptions to +:c:func:`bt_gatt_subscribe` API which takes +:c:struct:`bt_gatt_subscribe_params` as parameters. Multiple subscriptions to the same attribute are supported so there could be multiple ``notify`` callback being triggered for the same attribute. Subscriptions can be removed with use of -:cpp:func:`bt_gatt_unsubscribe()` API. +:c:func:`bt_gatt_unsubscribe` API. .. note:: When subscriptions are removed ``notify`` callback is called with the data diff --git a/doc/reference/bluetooth/l2cap.rst b/doc/reference/bluetooth/l2cap.rst index 3c0da1cfc3411a..277c5220833475 100644 --- a/doc/reference/bluetooth/l2cap.rst +++ b/doc/reference/bluetooth/l2cap.rst @@ -8,31 +8,31 @@ configuration option: :option:`CONFIG_BT_L2CAP_DYNAMIC_CHANNEL`. This channels support segmentation and reassembly transparently, they also support credit based flow control making it suitable for data streams. -Channels instances are represented by the :cpp:class:`bt_l2cap_chan` struct which -contains the callbacks in the :cpp:class:`bt_l2cap_chan_ops` struct to inform +Channels instances are represented by the :c:struct:`bt_l2cap_chan` struct which +contains the callbacks in the :c:struct:`bt_l2cap_chan_ops` struct to inform when the channel has been connected, disconnected or when the encryption has changed. In addition to that it also contains the ``recv`` callback which is called whenever an incoming data has been received. Data received this way can be marked as processed by returning 0 or using -:cpp:func:`bt_l2cap_chan_recv_complete` API if processing is asynchronous. +:c:func:`bt_l2cap_chan_recv_complete` API if processing is asynchronous. .. note:: The ``recv`` callback is called directly from RX Thread thus it is not recommended to block for long periods of time. -For sending data the :cpp:func:`bt_l2cap_chan_send` API can be used noting that +For sending data the :c:func:`bt_l2cap_chan_send` API can be used noting that it may block if no credits are available, and resuming as soon as more credits are available. -Servers can be registered using :cpp:func:`bt_l2cap_server_register` API passing -the :cpp:class:`bt_l2cap_server` struct which informs what ``psm`` it should +Servers can be registered using :c:func:`bt_l2cap_server_register` API passing +the :c:struct:`bt_l2cap_server` struct which informs what ``psm`` it should listen to, the required security level ``sec_level``, and the callback ``accept`` which is called to authorize incoming connection requests and allocate channel instances. -Client channels can be initiated with use of :cpp:func:`bt_l2cap_chan_connect` -API and can be disconnected with the :cpp:func:`bt_l2cap_chan_disconnect` API. +Client channels can be initiated with use of :c:func:`bt_l2cap_chan_connect` +API and can be disconnected with the :c:func:`bt_l2cap_chan_disconnect` API. Note that the later can also disconnect channel instances created by servers. API Reference diff --git a/doc/reference/bluetooth/mesh.rst b/doc/reference/bluetooth/mesh.rst index a2f314b9444dae..c131fadd4cbd52 100644 --- a/doc/reference/bluetooth/mesh.rst +++ b/doc/reference/bluetooth/mesh.rst @@ -18,4 +18,6 @@ Read more about Bluetooth Mesh on the mesh/models.rst mesh/provisioning.rst mesh/proxy.rst - + mesh/heartbeat.rst + mesh/cfg.rst + mesh/shell.rst diff --git a/doc/reference/bluetooth/mesh/access.rst b/doc/reference/bluetooth/mesh/access.rst index 80e65b942c1e3f..e7ea80b9200b24 100644 --- a/doc/reference/bluetooth/mesh/access.rst +++ b/doc/reference/bluetooth/mesh/access.rst @@ -21,7 +21,7 @@ element instantiating all the models required for a single aspect of the supported behavior. The node's element and model structure is specified in the node composition -data, which is passed to :cpp:func:`bt_mesh_init()` during initialization. The +data, which is passed to :c:func:`bt_mesh_init` during initialization. The Bluetooth SIG have defined a set of foundation models (see :ref:`bluetooth_mesh_models`) and a set of models for implementing common behavior in the `Bluetooth Mesh Model Specification @@ -79,12 +79,12 @@ Model publication The models may send messages in two ways: -* By specifying a set of message parameters in a :cpp:type:`bt_mesh_msg_ctx`, - and calling :cpp:func:`bt_mesh_model_send()`. -* By setting up a :cpp:type:`bt_mesh_model_pub` structure and calling - :cpp:func:`bt_mesh_model_publish()`. +* By specifying a set of message parameters in a :c:struct:`bt_mesh_msg_ctx`, + and calling :c:func:`bt_mesh_model_send`. +* By setting up a :c:struct:`bt_mesh_model_pub` structure and calling + :c:func:`bt_mesh_model_publish`. -When publishing messages with :cpp:func:`bt_mesh_model_publish()`, the model +When publishing messages with :c:func:`bt_mesh_model_publish`, the model will use the publication parameters configured by the :ref:`bluetooth_mesh_models_cfg_srv`. This is the recommended way to send unprompted model messages, as it passes the responsibility of selecting @@ -93,10 +93,10 @@ the mesh network than the individual nodes will. To support publishing with the publication parameters, the model must allocate a packet buffer for publishing, and pass it to -:cpp:var:`bt_mesh_model_pub::msg`. The Config Server may also set up period +:c:member:`bt_mesh_model_pub.msg`. The Config Server may also set up period publication for the publication message. To support this, the model must -populate the :cpp:var:`bt_mesh_model_pub::update` callback. The -:cpp:var:`bt_mesh_model_pub::update` callback will be called right before the +populate the :c:member:`bt_mesh_model_pub.update` callback. The +:c:member:`bt_mesh_model_pub.update` callback will be called right before the message is published, allowing the model to change the payload to reflect its current state. @@ -115,7 +115,7 @@ in total. Models may extend models that extend others, creating an "extension tree". All models in an extension tree share a single subscription list per element it spans. -Model extensions are done by calling :cpp:func:`bt_mesh_model_extend()` during +Model extensions are done by calling :c:func:`bt_mesh_model_extend` during initialization. A model can only be extended by one other model, and extensions cannot be circular. Note that binding of node states and other relationships between the models must be defined by the model implementations. @@ -131,9 +131,9 @@ Mesh models may have data associated with each model instance that needs to be stored persistently. The access API provides a mechanism for storing this data, leveraging the internal model instance encoding scheme. Models can store one user defined data entry per instance by calling -:cpp:func:`bt_mesh_model_data_store()`. To be able to read out the data the +:c:func:`bt_mesh_model_data_store`. To be able to read out the data the next time the device reboots, the model's -:cpp:var:`bt_mesh_model_cb::settings_set()` callback must be populated. This +:c:member:`bt_mesh_model_cb.settings_set` callback must be populated. This callback gets called when model specific data is found in the persistent storage. The model can retrieve the data by calling the ``read_cb`` passed as a parameter to the callback. See the :ref:`settings_api` module documentation for diff --git a/doc/reference/bluetooth/mesh/cfg.rst b/doc/reference/bluetooth/mesh/cfg.rst new file mode 100644 index 00000000000000..af38e17abb67c9 --- /dev/null +++ b/doc/reference/bluetooth/mesh/cfg.rst @@ -0,0 +1,23 @@ +.. _bluetooth_mesh_cfg: + +Runtime configuration +##################### + +The Bluetooth Mesh runtime configuration API allows applications to change +their runtime configuration directly, without going through the Configuration +models. + +Bluetooth Mesh nodes should generally be configured by a central network +configurator device with a :ref:`bluetooth_mesh_models_cfg_cli` model. Each +mesh node instantiates a :ref:`bluetooth_mesh_models_cfg_srv` model that the +Config Client can communicate with to change the node configuration. In some +cases, the mesh node can't rely on the Config Client to detect or determine +local constraints, such as low battery power or changes in topology. For these +scenarios, this API can be used to change the configuration locally. + +API reference +************* + +.. doxygengroup:: bt_mesh_cfg + :project: Zephyr + :members: diff --git a/doc/reference/bluetooth/mesh/cfg_srv.rst b/doc/reference/bluetooth/mesh/cfg_srv.rst index fc1af389f02ef7..0e85127fb34d0e 100644 --- a/doc/reference/bluetooth/mesh/cfg_srv.rst +++ b/doc/reference/bluetooth/mesh/cfg_srv.rst @@ -8,11 +8,11 @@ specification. The Configuration Server model controls most parameters of the mesh node. It does not have an API of its own, but relies on a :ref:`bluetooth_mesh_models_cfg_cli` to control it. -The application can configure the initial parameters of the Configuration -Server model through the :cpp:type:`bt_mesh_cfg_srv` instance passed to -:c:macro:`BT_MESH_MODEL_CFG_SRV`. Note that if the mesh node stored changes to -this configuration in the settings subsystem, the initial values may be -overwritten upon loading. +..note:: + The :c:struct:`bt_mesh_cfg_srv` structure has been deprecated. The initial + values of the Relay, Beacon, Friend, Network transmit and Relay retransmit + should be set through Kconfig, and the Heartbeat feature should be + controlled through the :ref:`bluetooth_mesh_heartbeat` API. The Configuration Server model is mandatory on all Bluetooth Mesh nodes, and should be instantiated in the first element. diff --git a/doc/reference/bluetooth/mesh/core.rst b/doc/reference/bluetooth/mesh/core.rst index 7d25e94219066c..8320be239926b7 100644 --- a/doc/reference/bluetooth/mesh/core.rst +++ b/doc/reference/bluetooth/mesh/core.rst @@ -17,7 +17,7 @@ either send messages or poll the Friend node for any incoming messages. The radio control and polling is managed automatically by the mesh stack, but the LPN API allows the application to trigger the polling at any time through -:cpp:func:`bt_mesh_lpn_poll()`. The LPN operation parameters, including poll +:c:func:`bt_mesh_lpn_poll`. The LPN operation parameters, including poll interval, poll event timing and Friend requirements is controlled through the :option:`CONFIG_BT_MESH_LOW_POWER` option and related configuration options. diff --git a/doc/reference/bluetooth/mesh/health_srv.rst b/doc/reference/bluetooth/mesh/health_srv.rst index 0000509358c305..a3435d41f103c8 100644 --- a/doc/reference/bluetooth/mesh/health_srv.rst +++ b/doc/reference/bluetooth/mesh/health_srv.rst @@ -38,12 +38,12 @@ device they're provisioning, as well as through the Health models at runtime. The attention state is always assigned a timeout in the range of one to 255 seconds when enabled. The Health Server API provides two callbacks for the application to run their attention calling behavior: -:cpp:var:`bt_mesh_health_srv_cb::attn_on` is called at the beginning of the -attention period, :cpp:var:`bt_mesh_health_srv_cb::attn_off` is called at +:c:member:`bt_mesh_health_srv_cb.attn_on` is called at the beginning of the +attention period, :c:member:`bt_mesh_health_srv_cb.attn_off` is called at the end. The remaining time for the attention period may be queried through -:cpp:var:`bt_mesh_health_srv::attn_timer`. +:c:member:`bt_mesh_health_srv.attn_timer`. API reference ************* diff --git a/doc/reference/bluetooth/mesh/heartbeat.rst b/doc/reference/bluetooth/mesh/heartbeat.rst new file mode 100644 index 00000000000000..c867b051965c5f --- /dev/null +++ b/doc/reference/bluetooth/mesh/heartbeat.rst @@ -0,0 +1,67 @@ +.. _bluetooth_mesh_heartbeat: + +Heartbeat +######### + +The Bluetooth Mesh Heartbeat feature provides functionality for monitoring mesh +nodes and determining the distance between nodes. + +The Heartbeat feature is configured through the :ref:`bluetooth_mesh_models_cfg_srv` model. + +Heartbeat messages +****************** + +Heartbeat messages are sent as transport control packets through the network, +and are only encrypted with a network key. Heartbeat messages contain the +original Time To Live (TTL) value used to send the message and a bitfield of +the active features on the node. Through this, a receiving node can determine +how many relays the message had to go through to arrive at the receiver, and +what features the node supports. + +Available Heartbeat feature flags: + +- :c:macro:`BT_MESH_FEAT_RELAY` +- :c:macro:`BT_MESH_FEAT_PROXY` +- :c:macro:`BT_MESH_FEAT_FRIEND` +- :c:macro:`BT_MESH_FEAT_LOW_POWER` + +Heartbeat publication +********************* + +Heartbeat publication is controlled through the Configuration models, and can +be triggered in two ways: + +Periodic publication + The node publishes a new Heartbeat message at regular intervals. The + publication can be configured to stop after a certain number of messages, or + continue indefinitely. + +Triggered publication + The node publishes a new Heartbeat message every time a feature changes. The + set of features that can trigger the publication is configurable. + +The two publication types can be combined. + +Heartbeat subscription +********************** + +A node can be configured to subscribe to Heartbeat messages from one node at +the time. To receive a Heartbeat message, both the source and destination must +match the configured subscription parameters. + +Heartbeat subscription is always time limited, and throughout the subscription +period, the node keeps track of the number of received Heartbeats as well as +the minimum and maximum received hop count. + +All Heartbeats received with the configured subscription parameters are passed +to the :cpp:member:`bt_mesh_hb_cb::recv` event handler. + +When the Heartbeat subscription period ends, the +:cpp:member:`bt_mesh_hb_cb::sub_end` callback gets called. + +API reference +************** + +.. doxygengroup:: bt_mesh_heartbeat + :project: Zephyr + :members: diff --git a/doc/reference/bluetooth/mesh/provisioning.rst b/doc/reference/bluetooth/mesh/provisioning.rst index 89ad0f80107a48..64a25dcacc77fa 100644 --- a/doc/reference/bluetooth/mesh/provisioning.rst +++ b/doc/reference/bluetooth/mesh/provisioning.rst @@ -29,10 +29,10 @@ Beaconing To start the provisioning process, the unprovisioned device must first start broadcasting the Unprovisioned Beacon. This makes it visible to nearby provisioners, which can initiate the provisioning. To indicate that the device -needs to be provisioned, call :cpp:func:`bt_mesh_prov_enable()`. The device +needs to be provisioned, call :c:func:`bt_mesh_prov_enable`. The device starts broadcasting the Unprovisioned Beacon with the device UUID and the ``OOB information`` field, as specified in the ``prov`` parameter passed to -:cpp:func:`bt_mesh_init`. Additionally, a Uniform Resource Identifier (URI) +:c:func:`bt_mesh_init`. Additionally, a Uniform Resource Identifier (URI) may be specified, which can point the provisioner to the location of some Out Of Band information, such as the device's public key or an authentication value database. The URI is advertised in a separate beacon, with a URI hash @@ -88,25 +88,25 @@ provisionee: production, which the provisioner can query in some application specific way. * **Input OOB:** The user inputs the authentication value. The available input - actions are listed in :cpp:enum:`bt_mesh_input_action_t`. + actions are listed in :c:enum:`bt_mesh_input_action_t`. * **Output OOB:** Show the user the authentication value. The available output - actions are listed in :cpp:enum:`bt_mesh_output_action_t`. + actions are listed in :c:enum:`bt_mesh_output_action_t`. The application must provide callbacks for the supported authentication -methods in :cpp:type:`bt_mesh_prov`, as well as enabling the supported actions -in :cpp:var:`bt_mesh_prov::output_actions` and -:cpp:var:`bt_mesh_prov::input_actions`. +methods in :c:struct:`bt_mesh_prov`, as well as enabling the supported actions +in :c:member:`bt_mesh_prov.output_actions` and +:c:member:`bt_mesh_prov.input_actions`. When an Output OOB action is selected, the authentication value should be presented to the user when the output callback is called, and remain until the -:cpp:var:`bt_mesh_prov::input_complete` or :cpp:var:`bt_mesh_prov::complete` +:c:member:`bt_mesh_prov.input_complete` or :c:member:`bt_mesh_prov.complete` callback is called. If the action is ``blink``, ``beep`` or ``vibrate``, the sequence should be repeated after a delay of three seconds or more. When an Input OOB action is selected, the user should be prompted when the -application receives the :cpp:var:`bt_mesh_prov::input` callback. The user +application receives the :c:member:`bt_mesh_prov.input` callback. The user response should be fed back to the Provisioning API through -:cpp:func:`bt_mesh_input_string()` or :cpp:func:`bt_mesh_input_number()`. If +:c:func:`bt_mesh_input_string` or :c:func:`bt_mesh_input_number`. If no user response is recorded within 60 seconds, the Provisioning process is aborted. @@ -125,7 +125,7 @@ transfers the Provisioning data: * IV update Additionally, a device key is generated for the node. All this data is stored -by the mesh stack, and the provisioning :cpp:var:`bt_mesh_prov::complete` +by the mesh stack, and the provisioning :c:member:`bt_mesh_prov.complete` callback gets called. API reference diff --git a/doc/reference/bluetooth/mesh/proxy.rst b/doc/reference/bluetooth/mesh/proxy.rst index 8999157bd666d4..6f31a15b478931 100644 --- a/doc/reference/bluetooth/mesh/proxy.rst +++ b/doc/reference/bluetooth/mesh/proxy.rst @@ -7,7 +7,7 @@ The Bluetooth Mesh Proxy feature allows legacy devices like phones to access the Mesh network through GATT. The Proxy feature is only compiled in if the :option:`CONFIG_BT_MESH_GATT_PROXY` option is set. The Proxy feature state is controlled by the :ref:`bluetooth_mesh_models_cfg_srv`, and the initial value -can be set with :cpp:var:`bt_mesh_cfg_srv::gatt_proxy`. +can be set with :c:member:`bt_mesh_cfg_srv.gatt_proxy`. API reference ************* diff --git a/doc/reference/bluetooth/mesh/shell.rst b/doc/reference/bluetooth/mesh/shell.rst new file mode 100644 index 00000000000000..69eae58fd64924 --- /dev/null +++ b/doc/reference/bluetooth/mesh/shell.rst @@ -0,0 +1,772 @@ +.. _bluetooth_mesh_shell: + +Shell +##### + +The Bluetooth Mesh Shell subsystem provides a set of Bluetooth Mesh commands for the :ref:`shell_api` module. +It allows for testing and exploring the Bluetooth Mesh API through an interactive interface, without having to write an application. + +The Bluetooth Mesh Shell interface provides access to most Bluetooth Mesh features, including provisioning, configuration, and message sending. + +Prerequisites +************* + +The Mesh Shell subsystem depends on the :ref:`bluetooth_mesh_models_cfg_cli` and :ref:`bluetooth_mesh_models_health_cli` models. + +Mesh Shell application +********************** + +The Mesh Shell subsystem is most easily used through the Mesh Shell application under ``tests/bluetooth/mesh_shell``. +See :ref:`shell_api` for information on how to connect and interact with the shell application. + +Basic usage +*********** + +The Mesh Shell subsystem adds a single ``mesh`` command, which holds a set of sub-commands. Every time the device boots up, make sure to call ``mesh init`` before any of the other Mesh Shell commands can be called:: + + uart:~$ mesh init + +Provisioning +============ + +The mesh node must be provisioned to become part of the network. This is only necessary the first time the device boots up, as the device will remember its provisioning data between reboots. + +The simplest way to provision the device is through self-provisioning. To provision the device with the default network key and address ``0x0001``, execute:: + + uart:~$ mesh provision 0 0x0001 + +Since all mesh shell nodes use the same values for the default network key, this can be done on multiple devices, as long as they're assigned non-overlapping unicast addresses. Alternatively, to provision the device into an existing network, the unprovisioned beacon can be enabled with ``mesh pb-adv on`` or ``mesh pb-gatt on``. The beacons can be picked up by an external provisioner, which can provision the node into its network. + +Once the mesh node is part of a network, its transmission parameters can be controlled by the general configuration commands: + +* To set the destination address, call ``mesh dst ``. +* To set the network key index, call ``mesh netidx ``. +* To set the application key index, call ``mesh appidx ``. + +By default, the transmission parameters are set to send messages to the provisioned address and network key. + +Configuration +============= + +By setting the destination address to the local unicast address (``0x0001`` in the ``mesh provision`` command above), we can perform self-configuration through any of the :ref:`bluetooth_mesh_shell_cfg_cli` commands. + +A good first step is to read out the node's own composition data:: + + uart:~$ mesh get-comp + +This prints a list of the composition data of the node, including a list of its model IDs. + +Next, since the device has no application keys by default, it's a good idea to add one:: + + uart:~$ mesh app-key-add 0 0 + +Message sending +=============== + +With an application key added (see above), the mesh node's transition parameters are all valid, and the Mesh Shell can send raw mesh messages through the network. + +For example, to send a Generic OnOff Set message, call:: + + uart:~$ mesh net-send 82020100 + +.. note:: + All multibyte fields model messages are in little endian, except the opcode. + +The message will be sent to the current destination address, using the current network and application key indexes. As the destination address points to the local unicast address by default, the device will only send packets to itself. To change the destination address to the All Nodes broadcast address, call:: + + uart:~$ mesh dst 0xffff + +With the destination address set to ``0xffff``, any other mesh nodes in the network with the configured network and application keys will receive and process the messages we send. + +.. note:: + To change the configuration of the device, the destination address must be set back to the local unicast address before issuing any configuration commands. + +Sending raw mesh packets is a good way to test model message handler implementations during development, as it can be done without having to implement the sending model. By default, only the reception of the model messages can be tested this way, as the Mesh Shell only includes the foundation models. To receive a packet in the Mesh Shell node, you have to add a model with a valid opcode handler list to the composition data in ``subsys/bluetooth/mesh/shell.c``, and print the incoming message to the shell in the handler callback. + +Parameter formats +***************** + +The Mesh Shell commands are parsed with a variety of formats: + +.. list-table:: Parameter formats + :widths: 1 4 2 + :header-rows: 1 + + * - Type + - Description + - Example + * - Integers + - The default format unless something else is specified. Can be either decimal or hexadecimal. + - ``1234``, ``0xabcd01234`` + * - Hexstrings + - For raw byte arrays, like UUIDs, key values and message payloads, the parameters should be formatted as an unbroken string of hexadecimal values without any prefix. + - ``deadbeef01234`` + * - Booleans + - Boolean values are denoted in the API documentation as ````. + - ``on``, ``off``, ``enabled``, ``disabled``, ``1``, ``0`` + +Mesh Shell commands +******************* + +The Mesh shell implements a large set of commands. Some of the commands accept parameters, which are mentioned in brackets after the command name. For example, ``mesh lpn ``. Mandatory parameters are marked with angle brackets (e.g. ````), and optional parameters are marked with square brackets (e.g. ``[destination address]``). + +The Mesh Shell commands are divided into the following groups: + +.. contents:: + :depth: 1 + :local: + +.. note:: + Some commands depend on specific features being enabled in the compile time configuration of the application. Not all features are enabled by default. The list of available Mesh Shell commands can be shown in the shell by calling ``mesh`` without any arguments. + +General configuration +===================== + +``mesh init`` +------------- + + Initialize the mesh. This command must be run before any other mesh command. + + +``mesh reset `` +--------------------- + + reset the local mesh node to its initial unprovisioned state or reset a remote node and remove it from the network. + * ``addr``: address of the node to reset. + + +``mesh lpn `` +----------------------------- + + Enable or disable Low Power operation. Once enabled, the device will turn off its radio and start polling for friend nodes. The device will not be able to receive messages from the mesh network until the friendship has been established. + + * ``value``: Sets whether Low Power operation is enabled. + + +``mesh poll`` +------------- + + Perform a poll to the friend node, to receive any pending messages. Only available when LPN is enabled. + + +``mesh ident`` +-------------- + + Enable the Proxy Node Identity beacon, allowing Proxy devices to connect explicitly to this device. The beacon will run for 60 seconds before the node returns to normal Proxy beacons. + + +``mesh dst [destination address]`` +---------------------------------- + + Get or set the message destination address. The destination address determines where mesh packets are sent with the shell, but has no effect on modules outside the shell's control. + + * ``destination address``: If present, sets the new 16-bit mesh destination address. If omitted, the current destination address is printed. + + +``mesh netidx [NetIdx]`` +------------------------ + + Get or set the message network index. The network index determines which network key is used to encrypt mesh packets that are sent with the shell, but has no effect on modules outside the shell's control. The network key must already be added to the device, either through provisioning or by a Config Client. + + * ``NetIdx``: If present, sets the new network index. If omitted, the current network index is printed. + + +``mesh appidx [AppIdx]`` +------------------------ + + Get or set the message application index. The application index determines which application key is used to encrypt mesh packets that are sent with the shell, but has no effect on modules outside the shell's control. The application key must already be added to the device by a Config Client, and must be bound to the current network index. + + * ``AppIdx``: If present, sets the new application index. If omitted, the current application index is printed. + + +``mesh net-send `` +------------------------------ + + Send a raw mesh message with the current destination address, network and application index. The message opcode must be encoded manually. + + * ``hex string`` Raw hexadecimal representation of the message to send. + + +Testing +======= + +``mesh iv-update`` +------------------ + + Force an IV update. + + +``mesh iv-update-test `` +---------------------------------------- + + Set the IV update test mode. In test mode, the IV update timing requirements are bypassed. + + * ``value``: Enable or disable the IV update test mode. + + +``mesh rpl-clear`` +------------------ + + Clear the replay protection list, forcing the node to forget all received messages. + +.. warning:: + + Clearing the replay protection list breaks the security mechanisms of the mesh node, making it susceptible to message replay attacks. This should never be performed in a real deployment. + + +Provisioning +============ + +``mesh pb-gatt `` +------------------------------- + + Start or stop advertising a connectable unprovisioned beacon. The connectable unprovisioned beacon allows the mesh node to be discovered by nearby GATT based provisioners, and provisioned through the GATT bearer. + + * ``val``: Enable or disable provisioning with GATT + + +``mesh pb-adv `` +------------------------------ + + Start or stop advertising the unprovisioned beacon. The unprovisioned beacon allows the mesh node to be discovered by nearby advertising-based provisioners, and provisioned through the advertising bearer. + + * ``val``: Enable or disable provisioning with advertiser + + +``mesh provision-adv `` +---------------------------------------------------------------------- + + Provision a nearby device into the mesh. The mesh node starts scanning for unprovisioned beacons with the given UUID. Once found, the unprovisioned device will be added to the mesh network with the given unicast address, and given the network key indicated by ``NetKeyIndex``. + + * ``UUID``: UUID of the unprovisioned device. + * ``NetKeyIndex``: Index of the network key to pass to the device. + * ``addr``: First unicast address to assign to the unprovisioned device. The device will occupy as many addresses as it has elements, and all must be available. + * ``AttentionDuration``: The duration in seconds the unprovisioned device will identify itself for, if supported. See :ref:`bluetooth_mesh_models_health_srv_attention` for details. + + +``mesh uuid `` +------------------------------------- + + Set the mesh node's UUID, used in the unprovisioned beacons. + + * ``UUID``: New 128-bit UUID value. Any missing bytes will be zero. + + +``mesh input-num `` +--------------------------- + + Input a numeric OOB authentication value. Only valid when prompted by the shell during provisioning. The input number must match the number presented by the other participant in the provisioning. + + * ``number``: Decimal authentication number. + + +``mesh input-str `` +--------------------------- + + Input an alphanumeric OOB authentication value. Only valid when prompted by the shell during provisioning. The input string must match the string presented by the other participant in the provisioning. + + * ``string``: Unquoted alphanumeric authentication string. + + +``mesh static-oob [val: 1-16 hex values]`` +------------------------------------------ + + Set or clear the static OOB authentication value. The static OOB authentication value must be set before provisioning starts to have any effect. The static OOB value must be same on both participants in the provisioning. + + * ``val``: If present, indicates the new hexadecimal value of the static OOB. If omitted, the static OOB value is cleared. + + +``mesh provision [IVIndex]`` +------------------------------------------------- + + Provision the mesh node itself. If the Configuration database is enabled, the network key must be created. Otherwise, the default key value is used. + + * ``NetKeyIndex``: Index of the network key to provision. + * ``addr``: First unicast address to assign to the device. The device will occupy as many addresses as it has elements, and all must be available. + * ``IVindex``: Indicates the current network IV index. Defaults to 0 if omitted. + + +``mesh beacon-listen `` +------------------------------------- + + Enable or disable printing of incoming unprovisioned beacons. Allows a provisioner device to detect nearby unprovisioned devices and provision them. + + * ``val``: Whether to enable the unprovisioned beacon printing. + +.. _bluetooth_mesh_shell_cfg_cli: + +Configuration Client model +========================== + +The Mesh Shell module instantiates a Configuration Client model for configuring itself and other nodes in the mesh network. + +The Configuration Client uses the general messages parameters set by ``mesh dst`` and ``mesh netidx`` to target specific nodes. When the Mesh Shell node is provisioned, the Configuration Client model targets itself by default. When another node has been provisioned by the Mesh Shell, the Configuration Client model targets the new node. The Configuration Client always sends messages using the Device key bound to the destination address, so it will only be able to configure itself and mesh nodes it provisioned. + +``mesh timeout [timeout in seconds]`` +------------------------------------- + + Get and set the Config Client model timeout used during message sending. + + * ``timeout in seconds``: If present, set the Config Client model timeout in seconds. If omitted, the current timeout is printed. + + +``mesh get-comp [page]`` +------------------------ + + Read a composition data page. The full composition data page will be printed. If the target does not have the given page, it will return the last page before it. + + * ``page``: The composition data page to request. Defaults to 0 if omitted. + + +``mesh beacon [val: off, on]`` +------------------------------ + + Get or set the network beacon transmission. + + * ``val``: If present, enables or disables sending of the network beacon. If omitted, the current network beacon state is printed. + + +``mesh ttl [ttl: 0x00, 0x02-0x7f]`` +----------------------------------- + + Get or set the default TTL value. + + * ``ttl``: If present, sets the new default TTL value. If omitted, the current default TTL value is printed. + + +``mesh friend [val: off, on]`` +------------------------------ + + Get or set the Friend feature. + + * ``val``: If present, enables or disables the Friend feature. If omitted, the current Friend feature state is printed: + + * ``0x00``: The feature is supported, but disabled. + * ``0x01``: The feature is enabled. + * ``0x02``: The feature is not supported. + + +``mesh gatt-proxy [val: off, on]`` +---------------------------------- + + Get or set the GATT Proxy feature. + + * ``val``: If present, enables or disables the GATT Proxy feature. If omitted, the current GATT Proxy feature state is printed: + + * ``0x00``: The feature is supported, but disabled. + * ``0x01``: The feature is enabled. + * ``0x02``: The feature is not supported. + + +``mesh relay [ [ [interval: 10-320]]]`` +----------------------------------------------------------------- + + Get or set the Relay feature and its parameters. + + * ``val``: If present, enables or disables the Relay feature. If omitted, the current Relay feature state is printed: + + * ``0x00``: The feature is supported, but disabled. + * ``0x01``: The feature is enabled. + * ``0x02``: The feature is not supported. + + * ``count``: Sets the new relay retransmit count if ``val`` is ``on``. Ignored if ``val`` is ``off``. Defaults to ``2`` if omitted. + * ``interval``: Sets the new relay retransmit interval in milliseconds if ``val`` is ``on``. Ignored if ``val`` is ``off``. Defaults to ``20`` if omitted. + + +``mesh net-transmit-param [ ]`` +------------------------------------------------------------- + + Get or set the network transmit parameters. + + * ``count``: Sets the number of additional network transmits for every sent message. + * ``interval``: Sets the new network retransmit interval in milliseconds. + + +``mesh net-key-add [val]`` +---------------------------------------- + + Add a network key to the target node. Adds the key to the Configuration Database if enabled. + + * ``NetKeyIndex``: The network key index to add. + * ``val``: If present, sets the key value as a 128-bit hexadecimal value. Any missing bytes will be zero. Only valid if the key does not already exist in the Configuration Database. If omitted, the default key value is used. + + +``mesh net-key-get`` +-------------------- + + Get a list of known network key indexes. + + +``mesh net-key-del `` +---------------------------------------- + + Delete a network key from the target node. + + * ``NetKeyIndex``: The network key index to delete. + + +``mesh app-key-add [val]`` +------------------------------------------------------ + + Add an application key to the target node. Adds the key to the Configuration Database if enabled. + + * ``NetKeyIndex``: The network key index the application key is bound to. + * ``AppKeyIndex``: The application key index to add. + * ``val``: If present, sets the key value as a 128-bit hexadecimal value. Any missing bytes will be zero. Only valid if the key does not already exist in the Configuration Database. If omitted, the default key value is used. + + +``mesh app-key-get `` +---------------------------------- + + Get a list of known application key indexes bound to the given network key index. + + * ``NetKeyIndex``: Network key indexes to get a list of application key indexes from. + + +``mesh app-key-del `` +------------------------------------------------ + + Delete an application key from the target node. + + * ``NetKeyIndex``: The network key index the application key is bound to. + * ``AppKeyIndex``: The application key index to delete. + + +``mesh mod-app-bind [Company ID]`` +--------------------------------------------------------------- + + Bind an application key to a model. Models can only encrypt and decrypt messages sent with application keys they are bound to. + + * ``addr``: Address of the element the model is on. + * ``AppIndex``: The application key to bind to the model. + * ``Model ID``: The model ID of the model to bind the key to. + * ``Company ID``: If present, determines the Company ID of the model. If omitted, the model is a Bluetooth SIG defined model. + + + +``mesh mod-app-unbind [Company ID]`` +----------------------------------------------------------------- + + Unbind an application key from a model. + + * ``addr``: Address of the element the model is on. + * ``AppIndex``: The application key to unbind from the model. + * ``Model ID``: The model ID of the model to unbind the key from. + * ``Company ID``: If present, determines the Company ID of the model. If omitted, the model is a Bluetooth SIG defined model. + + +``mesh mod-app-get [Company ID]`` +-------------------------------------------------------- + + Get a list of application keys bound to a model. + + * ``elem addr``: Address of the element the model is on. + * ``Model ID``: The model ID of the model to get the bound keys of. + * ``Company ID``: If present, determines the Company ID of the model. If omitted, the model is a Bluetooth SIG defined model. + + +``mesh mod-pub [cid] [ ]`` +------------------------------------------------------------------------------------------------------------------ + + Get or set the publication parameters of a model. If all publication parameters are included, they become the new publication parameters of the model. If all publication parameters are omitted, print the current publication parameters of the model. + + * ``addr``: Address of the element the model is on. + * ``Model ID``: The model ID of the model to get the bound keys of. + * ``cid``: If present, determines the Company ID of the model. If omitted, the model is a Bluetooth SIG defined model. + + Publication parameters: + + * ``PubAddr``: The destination address to publish to. + * ``AppKeyIndex``: The application key index to publish with. + * ``cred``: Whether to publish with Friendship credentials when acting as a Low Power Node. + * ``ttl``: TTL value to publish with (``0x00`` to ``0x07f``). + * ``period``: Encoded publication period, or 0 to disable periodic publication. + * ``count``: Number of retransmission for each published message (``0`` to ``7``). + * ``interval`` The interval between each retransmission, in milliseconds. Must be a multiple of 50. + + +``mesh mod-sub-add [Company ID]`` +------------------------------------------------------------------- + + Subscription the model to a group address. Models only receive messages sent to their unicast address or a group or virtual address they subscribe to. Models may subscribe to multiple group and virtual addresses. + + * ``elem addr``: Address of the element the model is on. + * ``sub addr``: 16-bit group address the model should subscribe to (``0xc000`` to ``0xFEFF``). + * ``Model ID``: The model ID of the model to add the subscription to. + * ``Company ID``: If present, determines the Company ID of the model. If omitted, the model is a Bluetooth SIG defined model. + + +``mesh mod-sub-del [Company ID]`` +------------------------------------------------------------------- + + Unsubscribe a model from a group address. + + * ``elem addr``: Address of the element the model is on. + * ``sub addr``: 16-bit group address the model should remove from its subscription list (``0xc000`` to ``0xFEFF``). + * ``Model ID``: The model ID of the model to add the subscription to. + * ``Company ID``: If present, determines the Company ID of the model. If omitted, the model is a Bluetooth SIG defined model. + + +``mesh mod-sub-add-va