Compare commits

..

43 Commits

Author SHA1 Message Date
Jiang Jiang Jian
310beae373 Merge branch 'bugfix/revert_optimize_wifi_rx_v4.0' into 'release/v4.0'
esp_wifi: revert WiFi RX optimization

See merge request espressif/esp-idf!5941
2019-08-30 10:59:20 +08:00
liu zhifu
cf0caaec11 esp_wifi: revert WiFi RX optimization
Revert following commit since it has compatibility issue:
commit 45dd6175cd
esp32: optimize wifi rx
2019-08-29 21:26:42 +08:00
Angus Gratton
ea1037742d Merge branch 'bugfix/confgen_msys_path_v4.0' into 'release/v4.0'
Fix sdkconfig.rename paths for confgen.py in MSYS (v4.0)

See merge request espressif/esp-idf!5904
2019-08-29 10:15:21 +08:00
Mahavir Jain
465d46e9dd Merge branch 'bugfix/cmake_src_exclude_issue_v4.0' into 'release/v4.0'
cmake: fix issue with handling of EXCLUDE_SRCS (v4.0)

See merge request espressif/esp-idf!5900
2019-08-28 14:42:20 +08:00
Jiang Jiang Jian
ebcb3a22b8 Merge branch 'bugfix/btdm_fix_ble_data_loss_and_send_same_pkt_twice_v4.0' into 'release/v4.0'
Component/bt: fix some BLE bugs (backport v4.0)

See merge request espressif/esp-idf!5909
2019-08-27 18:49:55 +08:00
baohongde
61ba1c3026 components/bt: backport 2 BT bugfix about controller
1.Bugfix btdm sleep twice after wakeup request
2.Set the minimum encryption key size to be 7 octects for BR/EDR link for preventing KNOB attack
    This patch is to address the CVE-2019-9506 vulnerability.
2019-08-27 10:42:40 +08:00
zhiweijian
90bbea65c1 Component/bt: fix some BLE bugs
- fix data loss and send same pkt twice sometimes
- fix adv data error in air sometimes
- fix adv start/stop crash sometimes
2019-08-26 20:29:01 +08:00
Roland Dobai
cb3d458050 Fix sdkconfig.rename paths for confgen.py in MSYS
Closes https://github.com/espressif/esp-idf/issues/3950
2019-08-26 11:12:44 +02:00
Mahavir Jain
b72ff61899 cmake: fix issue with handling of EXCLUDE_SRCS 2019-08-26 11:49:30 +05:30
Jiang Jiang Jian
7bb8b5ba9e Merge branch 'Bugfix/nonblocking_udp_is_zero_for_4.0' into 'release/v4.0'
fix bug for nonblocking udp is zero for v4.0

See merge request espressif/esp-idf!5855
2019-08-23 10:50:45 +08:00
xueyunfei
1f5f6adcb6 fix bug for nonblocking udp is zero for v4.0 2019-08-21 17:07:45 +08:00
Angus Gratton
16ee476a77 Merge branch 'bugfix/config_panic_gdbstub_build_issue_v4.0' into 'release/v4.0'
esp32_gdbstub: fix build error with esp32-2019r1 toolchain (v4.0)

See merge request espressif/esp-idf!5764
2019-08-20 13:11:24 +08:00
Angus Gratton
674ecc3b56 Merge branch 'bugfix/vfs_concurrent_select_v4.0' into 'release/v4.0'
VFS: Support concurrent VFS select calls & improve the documentation (backport v4.0)

See merge request espressif/esp-idf!5797
2019-08-20 12:49:03 +08:00
Angus Gratton
43efee5232 Merge branch 'bugfix/fix_mbedtls_net_sockets_error_handling_v4.0' into 'release/v4.0'
mbedtls: use `errno` instead of `SO_ERROR` for getting socket errors (v4.0)

See merge request espressif/esp-idf!5768
2019-08-20 12:28:56 +08:00
Angus Gratton
5dab23ea98 Merge branch 'bugfix/confserver_temporaryfile_windows_v4.0' into 'release/v4.0'
confserver: Fix NamedTemporaryFile use on Windows (v4.0)

See merge request espressif/esp-idf!5818
2019-08-20 12:28:16 +08:00
Angus Gratton
79afd2d580 confserver: Fix NamedTemporaryFile use on Windows
Can't have the file open twice, so need to close and delete after reopening.
2019-08-19 17:44:18 +10:00
Roland Dobai
a8e8919bbf tools: Support sdkconfig.rename files from outside IDF in confgen.py 2019-08-19 17:44:18 +10:00
Angus Gratton
ba0f4f17ed Merge branch 'bugfix/doc_pip_requirements_v4.0' into 'release/v4.0'
Add -r flag to pip install command from file (backport v4.0)

See merge request espressif/esp-idf!5798
2019-08-16 13:16:04 +08:00
Angus Gratton
a63b3c4fe6 Merge branch 'feature/dport_eco_revision2_v4.0' into 'release/v4.0'
make dport workaround depend on chip revision (v4.0)

See merge request espressif/esp-idf!5765
2019-08-16 13:15:18 +08:00
Angus Gratton
6b8c75d87c Merge branch 'bugfix/hwcrypt_fault_inj_v4.0' into 'release/v4.0'
AES & SHA fault injection checks (backport v4.0)

See merge request espressif/esp-idf!5748
2019-08-16 05:29:54 +08:00
Luke Bayes
68d82abe52 Added -r flag to pip install command from file
Closes https://github.com/espressif/esp-idf/pull/3874
Closes https://github.com/espressif/esp-idf/issues/3915
2019-08-15 14:23:49 +02:00
Roland Dobai
ec31f235e9 docs: Correct and extend the documentation about VFS select() 2019-08-15 14:11:51 +02:00
Roland Dobai
7e9d90b180 VFS: Support concurrent VFS select calls
Closes https://github.com/espressif/esp-idf/issues/3392
2019-08-15 14:11:37 +02:00
Angus Gratton
d4fcbe37f3 Merge branch 'bugfix/idf_tool_default_encoding_v4.0' into 'release/v4.0'
idf_tool: fix UnicodeDecodeError (v4.0)

See merge request espressif/esp-idf!5720
2019-08-15 16:35:58 +08:00
Angus Gratton
b9a5f764ba Merge branch 'bugfix/fix_flash_read_error_in_dio_mode_v4.0' into 'release/v4.0'
bugfix(flash): add spi dio address bitlen configure in psram init (backprot v4.0)

See merge request espressif/esp-idf!5790
2019-08-15 12:08:56 +08:00
chenjianqiang
764b70d7e6 bugfix(flash): add spi dio address bitlen configure in psram init 2019-08-15 10:52:56 +08:00
Angus Gratton
a1496b90e5 Merge branch 'bugfix/fix_ledc_clock_select_bug_v4.0' into 'release/v4.0'
driver(ledc): fixed ledc clock selection bug for v4.0

See merge request espressif/esp-idf!5757
2019-08-14 10:44:39 +08:00
Mahavir Jain
622d6d5504 mbedtls: use errno instead of SO_ERROR for getting socket errors
As per upgrade notes of lwIP v2.1.0:
socket API: according to the standard, SO_ERROR now only returns asynchronous errors.
All other/normal/synchronous errors are (and always were) available via 'errno'.
LWIP_SOCKET_SET_ERRNO has been removed - 'errno' is always set - and required!

Refer: https://www.nongnu.org/lwip/2_1_x/upgrading.html

Fixes https://github.com/espressif/esp-azure/issues/51
2019-08-13 13:11:24 +05:30
suda-morris
1b903111b6 efuse: update the scheme of getting chip revision 2019-08-13 14:37:17 +08:00
Mahavir Jain
69ef694178 esp32_gdbstub: fix build error with esp32-2019r1 toolchain
Fixes https://github.com/espressif/esp-idf/issues/3866
Closes https://github.com/espressif/esp-idf/issues/3834
2019-08-13 11:38:28 +05:30
Angus Gratton
81651b47a4 Merge branch 'ci/disable_nimble_tests_v4.0' into 'release/v4.0'
ci: Temporarily disable NimBLE tests in CI (v4.0)

See merge request espressif/esp-idf!5754
2019-08-13 10:42:38 +08:00
Jiang Jiang Jian
30dc86179c Merge branch 'bugfix/fix_wifi_bugs_for_authmode_and_multi_ssid_v4.0' into 'release/v4.0'
fix wifi bugs for authmode and multi ssid (backport v4.0)

See merge request espressif/esp-idf!5725
2019-08-12 23:34:43 +08:00
kooho
eff3ac05b3 driver(ledc): fixed ledc clock selection bug for release/v4.0 2019-08-12 17:16:52 +08:00
Angus Gratton
e5349d47a8 ci: Temporarily disable NimBLE tests in CI 2019-08-12 17:14:54 +10:00
zhangyanjiao
4253adf42b modify WIFI_CONN_0101 case for wrong authmode of AP 2019-08-12 02:38:44 +00:00
zhangyanjiao
088ed65194 wifi: fix wifi bugs for authmode and multi ssid 2019-08-12 02:38:44 +00:00
Angus Gratton
0ce94950b7 sha: Add fault injection checks reading hash digest state
Vulnerability reported by LimitedResults under Espressif Bug Bounty Program.
2019-08-11 15:58:48 +10:00
Angus Gratton
ae8b2684d7 aes: Add fault injection checks when writing key to hardware
Vulnerability reported by LimitedResults under Espressif Bug Bounty Program.
2019-08-11 15:58:48 +10:00
Angus Gratton
9c51f679a7 Merge branch 'bugfix/update_example_docs_build_instructions_to_cmake_v4.0' into 'release/v4.0'
examples: change default build instructions in docs to CMake (v4.0)

See merge request espressif/esp-idf!5704
2019-08-09 13:20:25 +08:00
suda-morris
5c07acad46 idf_tool: fix unicode decode error
Closes https://github.com/espressif/esp-idf/issues/3841
2019-08-07 21:27:29 +08:00
Mahavir Jain
70af759dd2 examples: change default build instructions in docs to CMake 2019-08-06 17:25:25 +05:30
Mahavir Jain
76191a0f55 Merge branch 'move/ble_example_v4.0' into 'release/v4.0'
examples/bluetooth: Move the demos to the appropriate locations (v4.0)

See merge request espressif/esp-idf!5687
2019-08-06 00:32:26 +08:00
Hrishikesh Dhayagude
f0c3114f2f examples/bluetooth: Move the demos to the appropriate locations (v4.0) 2019-08-06 00:32:25 +08:00
3129 changed files with 72964 additions and 276694 deletions

View File

@@ -152,7 +152,6 @@ exclude =
examples/build_system/cmake/import_lib/main/lib/tinyxml2,
# other third-party libraries
tools/kconfig_new/kconfiglib.py,
tools/kconfig_new/menuconfig.py,
# autogenerated scripts
components/protocomm/python/constants_pb2.py,
components/protocomm/python/sec0_pb2.py,

View File

@@ -1,16 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: ESP-IDF Programming Guide
url: https://docs.espressif.com/projects/esp-idf/en/latest/
about: Documentation for configuring and using ESP-IDF
- name: Espressif documentation page
url: https://www.espressif.com/en/support/download/documents
about: Hardware documentation (datasheets, Technical Reference Manual, etc)
- name: Forum
url: https://esp32.com
about: For questions about using ESP-IDF and/or ESP32 series chips. Please submit all questions starting "How do I..." here.
- name: Hardware-related services
url: https://www.espressif.com/en/products/hardware-services
about: Espressif service providing hardware design and certification support

View File

@@ -1,26 +0,0 @@
---
name: Feature request
about: Suggest an idea for ESP-IDF
title: ''
labels: 'Type: Feature Request'
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
Please give as many details as you can. Include suggestions for useful APIs or interfaces if relevant.
**Additional context**
Add any other context or screenshots about the feature request here.

22
.github/main.workflow vendored Normal file
View File

@@ -0,0 +1,22 @@
workflow "Sync issues to JIRA" {
on = "issues"
resolves = ["Sync to JIRA"]
}
workflow "Sync issue and PR comments to JIRA" {
on = "issue_comment"
resolves = ["Sync to JIRA"]
}
workflow "Sync PRs to JIRA" {
on = "pull_request"
resolves = ["Sync to JIRA"]
}
action "Sync to JIRA" {
uses = "espressif/github-actions/sync_issues_to_jira@master"
secrets = ["GITHUB_TOKEN", "JIRA_URL", "JIRA_USER", "JIRA_PASS"]
env = {
JIRA_PROJECT = "IDFGH"
}
}

View File

@@ -1,19 +0,0 @@
name: Sync issue comments to JIRA
# This workflow will be triggered when new issue comment is created (including PR comments)
on: issue_comment
jobs:
sync_issue_comments_to_jira:
name: Sync Issue Comments to Jira
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Sync issue comments to JIRA
uses: espressif/github-actions/sync_issues_to_jira@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JIRA_PASS: ${{ secrets.JIRA_PASS }}
JIRA_PROJECT: IDFGH
JIRA_URL: ${{ secrets.JIRA_URL }}
JIRA_USER: ${{ secrets.JIRA_USER }}

View File

@@ -1,19 +0,0 @@
name: Sync issues to Jira
# This workflow will be triggered when a new issue is opened
on: issues
jobs:
sync_issues_to_jira:
name: Sync issues to Jira
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Sync GitHub issues to Jira project
uses: espressif/github-actions/sync_issues_to_jira@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JIRA_PASS: ${{ secrets.JIRA_PASS }}
JIRA_PROJECT: IDFGH
JIRA_URL: ${{ secrets.JIRA_URL }}
JIRA_USER: ${{ secrets.JIRA_USER }}

View File

@@ -1,24 +0,0 @@
name: Sync remain PRs to Jira
# This workflow will be triggered every hour, to sync remaining PRs (i.e. PRs with zero comment) to Jira project
# Note that, PRs can also get synced when new PR comment is created
on:
schedule:
- cron: "0 * * * *"
jobs:
sync_prs_to_jira:
name: Sync PRs to Jira
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Sync PRs to Jira project
uses: espressif/github-actions/sync_issues_to_jira@master
with:
cron_job: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JIRA_PASS: ${{ secrets.JIRA_PASS }}
JIRA_PROJECT: IDFGH
JIRA_URL: ${{ secrets.JIRA_URL }}
JIRA_USER: ${{ secrets.JIRA_USER }}

View File

@@ -1,32 +0,0 @@
name: Python CI
# This workflow will be triggered when a PR modifies some python relevant files
on:
pull_request:
paths:
- "**.py"
- "requirements.txt"
jobs:
python_lint:
name: python lint
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [2.7, 3.5, 3.6, 3.7]
steps:
- name: Checkout
uses: actions/checkout@master
- name: Set up Python environment
uses: actions/setup-python@master
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
- name: Lint with flake8
run: |
pip install flake8
flake8 . --config=.flake8

16
.gitignore vendored
View File

@@ -63,20 +63,8 @@ test_multi_heap_host
# VS Code Settings
.vscode/
# VIM files
*.swp
*.swo
# Clion IDE CMake build & config
.idea/
cmake-build-*/
# Results for the checking of the Python coding style and static analysis
.mypy_cache
# Results for the checking of the Python coding style
flake8_output.txt
# ESP-IDF default build directory name
# ESP-IDF library
build
# lock files for examples and components
dependencies.lock

View File

@@ -1,10 +1,9 @@
stages:
- pre_check
- build
- assign_test
- host_test
- target_test
- post_check
- check
- deploy
- post_check
@@ -23,19 +22,11 @@ variables:
# GIT_STRATEGY is not defined here.
# Use an option from "CI / CD Settings" - "General pipelines".
# we will download archive for each submodule instead of clone.
# we don't do "recursive" when fetch submodule as they're not used in CI now.
GIT_SUBMODULE_STRATEGY: none
SUBMODULE_FETCH_TOOL: "tools/ci/ci_fetch_submodule.py"
# by default we will fetch all submodules
# jobs can overwrite this variable to only fetch submodules they required
# set to "none" if don't need to fetch submodules
SUBMODULES_TO_FETCH: "all"
# tell build system do not check submodule update as we download archive instead of clone
IDF_SKIP_CHECK_SUBMODULES: 1
# "normal" strategy for fetching only top-level submodules since nothing requires the sub-submodules code for building IDF.
# If the "recursive" strategy is used we have a problem with using relative URLs for sub-submodules.
GIT_SUBMODULE_STRATEGY: normal
UNIT_TEST_BUILD_SYSTEM: cmake
EXAMPLE_TEST_BUILD_SYSTEM: cmake
UNIT_TEST_BUILD_SYSTEM: make
# IDF environment
IDF_PATH: "$CI_PROJECT_DIR"
@@ -51,7 +42,6 @@ variables:
CI_TARGET_TEST_CONFIG_FILE: "$CI_PROJECT_DIR/tools/ci/config/target-test.yml"
# before each job, we need to check if this job is filtered by bot stage/job filter
.apply_bot_filter: &apply_bot_filter
python $APPLY_BOT_FILTER_SCRIPT || exit 0
@@ -76,14 +66,16 @@ variables:
rm -rf "$CUSTOM_TOOLCHAIN_PATH"
.setup_tools_unless_target_test: &setup_tools_unless_target_test |
if [[ "$SETUP_TOOLS" == "1" || "$CI_JOB_STAGE" != "target_test" ]]; then
if [ "$CI_JOB_STAGE" != "target_test" ]; then
tools/idf_tools.py --non-interactive install && eval "$(tools/idf_tools.py --non-interactive export)" || exit 1
fi
.fetch_submodules: &fetch_submodules |
python $SUBMODULE_FETCH_TOOL -s $SUBMODULES_TO_FETCH
.show_submodule_urls: &show_submodule_urls |
git config --get-regexp '^submodule\..*\.url$' || true
before_script:
- echo "Running common script"
- *show_submodule_urls
- source tools/ci/setup_python.sh
# apply bot filter in before script
- *apply_bot_filter
@@ -99,8 +91,6 @@ before_script:
- *setup_tools_unless_target_test
- *fetch_submodules
- *setup_custom_toolchain
# used for check scripts which we want to run unconditionally
@@ -129,7 +119,7 @@ after_script:
- *cleanup_custom_toolchain
.check_job_template:
stage: pre_check
stage: check
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- host_test
@@ -137,29 +127,17 @@ after_script:
extends: .before_script_lesser_nofilter
.check_job_template_with_filter:
stage: pre_check
stage: check
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- host_test
dependencies: []
extends: .before_script_lesser_nofilter
.macos_build_template:
stage: build
tags:
- macos_shell
dependencies: []
before_script:
- *apply_bot_filter
- *setup_tools_unless_target_test
- *setup_custom_toolchain
- source tools/ci/configure_ci_environment.sh
include:
- '/tools/ci/config/pre_check.yml'
- '/tools/ci/config/build.yml'
- '/tools/ci/config/assign-test.yml'
- '/tools/ci/config/host-test.yml'
- '/tools/ci/config/target-test.yml'
- '/tools/ci/config/post_check.yml'
- '/tools/ci/config/check.yml'
- '/tools/ci/config/deploy.yml'

13
.gitmodules vendored
View File

@@ -67,15 +67,10 @@
path = examples/build_system/cmake/import_lib/main/lib/tinyxml2
url = ../../leethomason/tinyxml2.git
[submodule "components/esp_wifi/lib_esp32"]
path = components/esp_wifi/lib_esp32
url = ../../espressif/esp32-wifi-lib.git
[submodule "components/bt/host/nimble/nimble"]
path = components/bt/host/nimble/nimble
url = ../../espressif/esp-nimble.git
[submodule "components/cbor/tinycbor"]
path = components/cbor/tinycbor
url = ../../intel/tinycbor.git
[submodule "components/esp_wifi/lib"]
path = components/esp_wifi/lib
url = ../../espressif/esp32-wifi-lib.git

7
.travis.yml Normal file
View File

@@ -0,0 +1,7 @@
language: python
sudo: false
python:
- "3.4"
script:
- pip install flake8
- travis_wait 20 python -m flake8 --config=.flake8 .

View File

@@ -5,21 +5,15 @@ unset(compile_options)
unset(c_compile_options)
unset(cxx_compile_options)
unset(compile_definitions)
unset(link_options)
# Add the following build specifications here, since these seem to be dependent
# on config values on the root Kconfig.
if(CONFIG_COMPILER_OPTIMIZATION_SIZE)
if(CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE)
list(APPEND compile_options "-Os")
list(APPEND compile_options "-freorder-blocks")
elseif(CONFIG_COMPILER_OPTIMIZATION_DEFAULT)
else()
list(APPEND compile_options "-Og")
elseif(CONFIG_COMPILER_OPTIMIZATION_NONE)
list(APPEND compile_options "-O0")
elseif(CONFIG_COMPILER_OPTIMIZATION_PERF)
list(APPEND compile_options "-O2")
endif()
if(CONFIG_COMPILER_CXX_EXCEPTIONS)
@@ -28,28 +22,24 @@ else()
list(APPEND cxx_compile_options "-fno-exceptions")
endif()
if(CONFIG_COMPILER_CXX_RTTI)
list(APPEND cxx_compile_options "-frtti")
else()
list(APPEND cxx_compile_options "-fno-rtti")
list(APPEND link_options "-fno-rtti") # used to invoke correct multilib variant (no-rtti) during linking
endif()
if(CONFIG_COMPILER_DISABLE_GCC8_WARNINGS)
list(APPEND compile_options "-Wno-parentheses"
"-Wno-sizeof-pointer-memaccess"
"-Wno-clobbered")
list(APPEND compile_options "-Wno-format-overflow"
"-Wno-stringop-truncation"
"-Wno-misleading-indentation"
"-Wno-cast-function-type"
"-Wno-implicit-fallthrough"
"-Wno-unused-const-variable"
"-Wno-switch-unreachable"
"-Wno-format-truncation"
"-Wno-memset-elt-size"
"-Wno-int-in-bool-context")
# doesn't use GCC_NOT_5_2_0 because idf_set_global_variables was not called before
if(GCC_NOT_5_2_0)
list(APPEND compile_options "-Wno-format-overflow"
"-Wno-stringop-truncation"
"-Wno-misleading-indentation"
"-Wno-cast-function-type"
"-Wno-implicit-fallthrough"
"-Wno-unused-const-variable"
"-Wno-switch-unreachable"
"-Wno-format-truncation"
"-Wno-memset-elt-size"
"-Wno-int-in-bool-context")
endif()
endif()
if(CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE)
@@ -64,13 +54,11 @@ elseif(CONFIG_COMPILER_STACK_CHECK_MODE_ALL)
list(APPEND compile_options "-fstack-protector-all")
endif()
list(APPEND link_options "-fno-lto")
idf_build_set_property(COMPILE_OPTIONS "${compile_options}" APPEND)
idf_build_set_property(C_COMPILE_OPTIONS "${c_compile_options}" APPEND)
idf_build_set_property(CXX_COMPILE_OPTIONS "${cxx_compile_options}" APPEND)
idf_build_set_property(COMPILE_DEFINITIONS "${compile_definitions}" APPEND)
idf_build_set_property(LINK_OPTIONS "${link_options}" APPEND)
idf_build_get_property(build_component_targets __BUILD_COMPONENT_TARGETS)

175
Kconfig
View File

@@ -4,13 +4,21 @@
#
mainmenu "Espressif IoT Development Framework Configuration"
# Hidden option to support checking for this specific target in C code and Kconfig files
config IDF_TARGET_ESP32
bool
default "y" if IDF_TARGET="esp32"
default "n"
config IDF_CMAKE
bool
option env="IDF_CMAKE"
config IDF_ENV_FPGA
# This option is for internal use only
bool
config IDF_TARGET_ENV
# A proxy to get environment variable $IDF_TARGET
string
option env="IDF_TARGET"
config IDF_TARGET
# This option records the IDF target when sdkconfig is generated the first time.
@@ -18,29 +26,14 @@ mainmenu "Espressif IoT Development Framework Configuration"
# the build system is responsible for detecting the mismatch between
# CONFIG_IDF_TARGET and $IDF_TARGET.
string
default "$IDF_TARGET"
default "IDF_TARGET_NOT_SET" if IDF_TARGET_ENV=""
default IDF_TARGET_ENV
config IDF_TARGET_ESP32
bool
default "y" if IDF_TARGET="esp32"
config IDF_TARGET_ESP32S2BETA
bool
default "y" if IDF_TARGET="esp32s2beta"
select FREERTOS_UNICORE
config IDF_FIRMWARE_CHIP_ID
hex
default 0x0000 if IDF_TARGET_ESP32
# note: S2 beta uses Chip ID 0 still, S2 will use 0x0002
default 0x0000 if IDF_TARGET_ESP32S2BETA
default 0xFFFF
menu "SDK tool configuration"
config SDK_TOOLPREFIX
string "Compiler toolchain path/prefix"
default "xtensa-esp32-elf-" if IDF_TARGET_ESP32
default "xtensa-esp32s2-elf-" if IDF_TARGET_ESP32S2BETA
default "xtensa-esp32-elf-"
help
The prefix/path that is used to call the toolchain. The default setting assumes
a crosstool-ng gcc setup that is in your PATH.
@@ -69,136 +62,32 @@ mainmenu "Espressif IoT Development Framework Configuration"
(Note: this option is used with the legacy GNU Make build system only.)
config SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS
bool "Toolchain supports time_t wide 64-bits"
default n
help
Enable this option in case you have a custom toolchain which supports time_t wide 64-bits.
This option checks time_t is 64-bits and disables ROM time functions
to use the time functions from the toolchain instead.
This option allows resolving the Y2K38 problem.
See "Setup Linux Toolchain from Scratch" to build
a custom toolchain which supports 64-bits time_t.
Note: ESP-IDF does not currently come with any pre-compiled toolchain
that supports 64-bit wide time_t.
This will change in a future major release,
but currently 64-bit time_t requires a custom built toolchain.
endmenu # SDK tool configuration
menu "Build type"
choice APP_BUILD_TYPE
prompt "Application build type"
default APP_BUILD_TYPE_APP_2NDBOOT
help
Select the way the application is built.
By default, the application is built as a binary file in a format compatible with
the ESP32 bootloader. In addition to this application, 2nd stage bootloader is
also built. Application and bootloader binaries can be written into flash and
loaded/executed from there.
Another option, useful for only very small and limited applications, is to only link
the .elf file of the application, such that it can be loaded directly into RAM over
JTAG. Note that since IRAM and DRAM sizes are very limited, it is not possible to
build any complex application this way. However for kinds of testing and debugging,
this option may provide faster iterations, since the application does not need to be
written into flash.
Note that at the moment, ESP-IDF does not contain all the startup code required to
initialize the CPUs and ROM memory (data/bss). Therefore it is necessary to execute
a bit of ROM code prior to executing the application. A gdbinit file may look as follows:
# Connect to a running instance of OpenOCD
target remote :3333
# Reset and halt the target
mon reset halt
# Run to a specific point in ROM code,
# where most of initialization is complete.
thb *0x40007901
c
# Load the application into RAM
load
# Run till app_main
tb app_main
c
Execute this gdbinit file as follows:
xtensa-esp32-elf-gdb build/app-name.elf -x gdbinit
Recommended sdkconfig.defaults for building loadable ELF files is as follows.
CONFIG_APP_BUILD_TYPE_ELF_RAM is required, other options help reduce application
memory footprint.
CONFIG_APP_BUILD_TYPE_ELF_RAM=y
CONFIG_VFS_SUPPORT_TERMIOS=
CONFIG_NEWLIB_NANO_FORMAT=y
CONFIG_ESP32_PANIC_PRINT_HALT=y
CONFIG_ESP32_DEBUG_STUBS_ENABLE=
CONFIG_ESP_ERR_TO_NAME_LOOKUP=
config APP_BUILD_TYPE_APP_2NDBOOT
bool
prompt "Default (binary application + 2nd stage bootloader)"
select APP_BUILD_GENERATE_BINARIES
select APP_BUILD_BOOTLOADER
select APP_BUILD_USE_FLASH_SECTIONS
config APP_BUILD_TYPE_ELF_RAM
bool
prompt "ELF file, loadable into RAM (EXPERIMENTAL))"
endchoice # APP_BUILD_TYPE
# Hidden options, set according to the choice above
config APP_BUILD_GENERATE_BINARIES
bool # Whether to generate .bin files or not
config APP_BUILD_BOOTLOADER
bool # Whether to build the bootloader
config APP_BUILD_USE_FLASH_SECTIONS
bool # Whether to place code/data into memory-mapped flash sections
endmenu # Build type
source "$COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE"
source "$COMPONENT_KCONFIGS_PROJBUILD"
menu "Compiler options"
choice COMPILER_OPTIMIZATION
prompt "Optimization Level"
default COMPILER_OPTIMIZATION_DEFAULT
default COMPILER_OPTIMIZATION_LEVEL_DEBUG
help
This option sets compiler optimization level (gcc -O argument).
- The "Default" setting will add the -0g flag to CFLAGS.
- The "Size" setting will add the -0s flag to CFLAGS.
- The "Performance" setting will add the -O2 flag to CFLAGS.
- The "None" setting will add the -O0 flag to CFLAGS.
- for "Release" setting, -Os flag is added to CFLAGS.
- for "Debug" setting, -Og flag is added to CFLAGS.
The "Size" setting cause the compiled code to be smaller and faster, but
may lead to difficulties of correlating code addresses to source file
lines when debugging.
"Release" with -Os produces smaller & faster compiled code but it
may be harder to correlated code addresses to source files when debugging.
The "Performance" setting causes the compiled code to be larger and faster,
but will be easier to correlated code addresses to source file lines.
To add custom optimization settings, set CFLAGS and/or CPPFLAGS
in project makefile, before including $(IDF_PATH)/make/project.mk. Note that
custom optimization levels may be unsupported.
"None" with -O0 produces compiled code without optimization.
Note that custom optimization levels may be unsupported.
config COMPILER_OPTIMIZATION_DEFAULT
config COMPILER_OPTIMIZATION_LEVEL_DEBUG
bool "Debug (-Og)"
config COMPILER_OPTIMIZATION_SIZE
bool "Optimize for size (-Os)"
config COMPILER_OPTIMIZATION_PERF
bool "Optimize for performance (-O2)"
config COMPILER_OPTIMIZATION_NONE
bool "Debug without optimization (-O0)"
config COMPILER_OPTIMIZATION_LEVEL_RELEASE
bool "Release (-Os)"
endchoice
choice COMPILER_OPTIMIZATION_ASSERTION_LEVEL
@@ -256,14 +145,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate
memory for thrown exceptions when there is not enough memory on the heap.
config COMPILER_CXX_RTTI
bool "Enable C++ run-time type info (RTTI)"
default n
help
Enabling this option compiles all C++ files with RTTI support enabled.
This increases binary size (typically by tens of kB) but allows using
dynamic_cast conversion and typeid operator.
choice COMPILER_STACK_CHECK_MODE
prompt "Stack smashing protection mode"
default COMPILER_STACK_CHECK_MODE_NONE
@@ -330,12 +211,12 @@ mainmenu "Espressif IoT Development Framework Configuration"
endmenu # Compiler Options
menu "Component config"
source "$COMPONENT_KCONFIGS_SOURCE_FILE"
source "$COMPONENT_KCONFIGS"
endmenu
menu "Compatibility options"
config LEGACY_INCLUDE_COMMON_HEADERS
bool "Include headers across components as before IDF v4.0"
bool "Include headers accross components as before IDF v4.0"
default n
help
Soc, esp32, and driver components, the most common

View File

@@ -1,7 +1,5 @@
# Espressif IoT Development Framework
* [中文版](./README_CN.md)
[![Documentation Status](https://readthedocs.com/projects/espressif-esp-idf/badge/?version=latest)](https://docs.espressif.com/projects/esp-idf/en/latest/?badge=latest)
ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview) chip.

View File

@@ -1,112 +0,0 @@
# Espressif 物联网开发框架
* [English Version](./README.md)
[![Documentation Status](https://readthedocs.com/projects/espressif-esp-idf/badge/?version=latest)](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/?badge=latest)
ESP-IDF 是由乐鑫官方推出的针对 [ESP32](https://espressif.com/en/products/hardware/esp32/overview) 系列芯片的开发框架。
# 使用 ESP-IDF 进行开发
## 搭建 ESP-IDF 开发环境
请参阅如下指南搭建 ESP-IDF 的开发环境:
* [ESP-IDF 稳定版本的入门指南](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/)
* [ESP-IDF 开发版本master 分支)的入门指南](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)
### 非 GitHub 分叉的 ESP-IDF 项目
ESP-IDF 中的子模块采用相对路径([详见 .gitmodules 文件](.gitmodules)),所以它们会指向 GitHub。
如果 ESP-IDF 被分叉到的仓库不在 GitHub 上,那么你需要在克隆结束后运行该[脚本](tools/set-submodules-to-github.sh)。它会为所有的子模块设置绝对路径,接着可以通过 `git submodule update --init --recursive` 完成子模块的更新。
如果 ESP-IDF 是从 GitHub 上克隆得到,则不需要此步骤。
## 寻找项目
除了入门指南中提到的 [esp-idf 模板项目](https://github.com/espressif/esp-idf-template)ESP-IDF 的 [examples](examples) 目录下还带有很多其它示例项目。
一旦找到了需要的项目,便可以进入该目录,执行配置和构建操作。
如果要基于示例工程开始你自己的项目,请将示例工程复制到 ESP-IDF 目录之外。
# 快速参考
详细的使用方法请参考上面入门指南的链接,这里仅仅列举一些 ESP-IDF 项目开发中常用的命令:
## 设置构建环境
(请参考入门指南中列出的详细步骤。)
* 在主机中安装入门指南中提到的构建所依赖的工具。
* 将 ESP-IDF 中的 `tools/` 目录加入 PATH 环境变量中。
* 运行 `python -m pip install -r requirements.txt` 安装 Python 依赖库。
## 配置项目
`idf.py menuconfig`
* 打开项目的文本配置菜单。
* 使用上下键浏览菜单。
* 使用回车键进入子菜单,退出键返回上一级菜单或者退出配置。
* 输入 `?` 查看帮助界面,按下回车键可以退出帮助界面。
* 使用空格键或者 `Y``N` 按键来启用和禁用带复选框“`[*]`”的配置项。
* 高亮某个配置项的同时按下 `?` 键可以显示该选项的帮助文档。
* 输入 `/` 可以搜索指定的配置项。
一旦配置完成,请按下退出键多次以退出配置界面,当提示是否保存新的的配置时,选择 “Yes”。
## 编译项目
`idf.py build`
编译应用程序,引导程序,并根据配置生成分区表。
## 烧写项目
当构建结束,终端会打印出一条命令行,告知如何使用 esptool.py 工具烧写项目到芯片中。但是你还可以运行下面这条命令来自动烧写:
`idf.py -p PORT flash`
将其中的 PORT 替换为系统中实际串口的名字(比如 Windows 下的 `COM3`Linux 下的 `/dev/ttyUSB0`,或者 MacOS 下的 `/dev/cu.usbserial-X`。如果省略 `-p` 选项,`idf.py flash` 会尝试使用第一个可用的串口进行烧写。
这会烧写整个项目(包括应用程序,引导程序和分区表)到芯片中,此外还可以使用 `idf.py menuconfig` 来调整串口烧写相关的配置。
你也不必先运行 `idf.py build`,再运行 `idf.py flash``idf.py flash` 会根据需要自动重新构建项目。
## 观察串口输入
`idf.py monitor` 会调用 [idf_monitor 工具](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html)来显示 ESP32 的串口输出。`idf_monitor` 还包含一系列的功能来解析程序崩溃后的输出结果并与设备进行交互。更多详细内容,请参阅[文档](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
输入 `Ctrl-]` 可退出监视器。
想要一次性执行构建,烧写和监视,可以运行如下命令:
`idf.py flash monitor`
## 仅编译并烧写应用程序
在第一次烧写过后,你可能只想构建并烧写你的应用程序,不包括引导程序和分区表:
* `idf.py app` - 仅构建应用程序。
* `idf.py app-flash` - 仅烧写应用程序。
`idf.py app-flash` 会自动判断是否有源文件发生了改变而后重新构建应用程序。
(在正常的开发中,即使引导程序和分区表没有发生变化,每次都重新烧写它们并不会带来什么危害。)
## 擦除 Flash
`idf.py flash` 并不会擦除 Flash 上所有的内容,但是有时候我们需要设备恢复到完全擦除的状态,尤其是分区表发生了变化或者 OTA 应用升级。要擦除整块 Flash 请运行 `idf.py erase_flash`
这条命令还可以和其余命令整合在一起,`idf.py -p PORT erase_flash flash` 会擦除一切然后重新烧写新的应用程序,引导程序和分区表。
# 其它参考资源
* 最新版的文档https://docs.espressif.com/projects/esp-idf/ ,该文档是由本仓库 [docs 目录](docs) 构建得到。
* 可以前往 [esp32.com 论坛](https://esp32.com/) 提问,挖掘社区资源。
* 如果你在使用中发现了错误或者需要新的功能,请先[查看 GitHub Issues](https://github.com/espressif/esp-idf/issues),确保该问题不会被重复提交。
* 如果你有兴趣为 ESP-IDF 作贡献,请先阅读[贡献指南](https://docs.espressif.com/projects/esp-idf/en/latest/contribute/index.html)。

View File

@@ -1,68 +0,0 @@
The latest support policy for ESP-IDF can be found at [https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY.md](https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY.md)
Support Period Policy
=====================
* [中文版](./SUPPORT_POLICY_CN.md)
Each ESP-IDF major and minor release (V4.0, V4.1, etc) is supported for
18 months after the initial stable release date.
Supported means that the ESP-IDF team will continue to apply bug fixes,
security fixes, etc to the release branch on GitHub, and periodically
make new bugfix releases as needed.
Users are encouraged to upgrade to a newer ESP-IDF release before the
support period finishes and the release becomes End of Life (EOL). It is
our policy to not continue fixing bugs in End of Life releases.
Pre-release versions (betas, previews, `-rc` and `-dev` versions, etc)
are not covered by any support period. Sometimes a particular feature is
marked as \"Preview\" in a release, which means it is also not covered
by the support period.
The ESP-IDF Programming Guide has information about the
[different versions of ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/versions.html)
(major, minor, bugfix, etc).
Long Term Support releases
--------------------------
Some releases (starting with ESP-IDF V3.3) are designated Long Term
Support (LTS). LTS releases are supported for 30 months (2.5 years)
after the initial stable release date.
A new LTS release will be made at least every 18 months. This means
there will always be a period of at least 12 months to upgrade from the
previous LTS release to the following LTS release.
Example
-------
ESP-IDF V3.3 was released in September 2019 and is a Long Term Support
(LTS) release, meaning it will be supported for 30 months until February
2022.
- The first V3.3 release was `v3.3` in September 2019.
- The ESP-IDF team continues to backport bug fixes, security fixes,
etc to the release branch `release/v3.3`.
- Periodically stable bugfix releases are created from the release
branch. For example `v3.3.1`, `v3.3.2`, etc. Users are encouraged to
always update to the latest bugfix release.
- V3.3 bugfix releases continue until February 2022, when all V3.3.x
releases become End of Life.
Existing Releases
-----------------
ESP-IDF release V3.3 and all newer releases will follow this support
period policy. The support period for each release will be announced
when the release is made.
For releases made before the support period policy was announced,
the following support periods apply:
- ESP-IDF V3.1.x and V3.2.x will both be supported until October 2020.
- ESP-IDF V3.0.9 (planned for October 2019) will be the last V3.0
bugfix release. ESP-IDF V3.0.x is End of Life from October 2019.
- ESP-IDF versions before V3.0 are already End of Life.

View File

@@ -1,43 +0,0 @@
有关 ESP-IDF 的最新支持政策,详见 [支持期限政策](./SUPPORT_POLICY_CN.md)。
支持期限政策
=================
* [English Version](./SUPPORT_POLICY.md)
ESP-IDF 的每个主要版本和次要版本(如 V4.0、V4.1 等)自其首次稳定版本发布之日起将维护 18 个月。
维护意味着 ESP-IDF 团队将会对 GitHub 上的发布分支继续进行 bug 修复、安全修补等,并根据需求定期发布新的 bugfix 版本。
在某一版本支持期限结束,停止更新维护 (EOL) 前,建议用户升级到较新的 ESP-IDF 版本。根据《支持期限政策》,我们将停止对 EOL 版本进行 bug 修复。
《支持期限政策》不适用于预发布版本(包括 beta、preview、`-rc``-dev` 版本等)。有时,在发布的版本中存在被标记为 "Preview" 的特定功能,则该功能也不在支持期限内。
有关 [ ESP-IDF 不同版本](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/versions.html)主要版本、次要版本、bugfix 版本等信息可参阅《ESP-IDF 编程指南》。
长期支持版本
------------
有些发布版本(从 ESP-IDF V3.3 开始)属于长期支持 (LTS) 版本。LTS 版本将自其首次稳定版本发布之日起维护 30 个月2.5 年)。
我们将至少每 18 个月发布一个新的 LTS 版本。这意味着将至少有 12 个月的期限可更新至下一个 LTS 版本。
示例
-----
ESP-IDF V3.3 于 2019 年 9 月发布,属于 LTS 版本,将维护 30 个月至 2022 年 2 月停止。
- V3.3 的首个发布版本为 2019 年 9 月发布的 `v3.3`
- ESP-IDF 团队将持续进行 bug 修复、安全修补等更新,并 backport 至分支 `release/v3.3`
- 定期从 release 分支创建稳定的 bugfix 版本,比如,`v3.3.1``v3.3.2` 等,并建议用户保持使用最新的 bugfix 版本。
- V3.3 的 bugfix 版本发布将持续至 2022 年 2 月,届时所有 V3.3.x 将停止更新维护。
现有版本
--------
ESP-IDF V3.3 及所有后续更新版本都将遵守该《支持期限政策》。每一版本发布时将同时公布其支持期限。
对于该政策公布之日前发布的版本,应适用下述支持期限:
- ESP-IDF V3.1.x 和 V3.2.x 将维护至 2020 年 10 月。
- ESP-IDF V3.0.9(计划 2019 年 10 月发布)将是 V3.0 的最后一个 bugfix 版本。ESP-IDF V3.0.x 自 2019 年 10 月起停止更新维护 (EOL)。
- ESP-IDF 中 V3.0 之前的版本均已停止更新维护 (EOL)。

View File

@@ -23,9 +23,6 @@ endif()
if(CONFIG_HEAP_TRACING_TOHOST)
list(APPEND srcs "heap_trace_tohost.c")
set_source_files_properties(heap_trace_tohost.c
PROPERTIES COMPILE_FLAGS
-Wno-frame-address)
endif()
idf_component_register(SRCS "${srcs}"
@@ -36,7 +33,4 @@ idf_component_register(SRCS "${srcs}"
# disable --coverage for this component, as it is used as transport
# for gcov
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
# Force app_trace to also appear later than gcov in link line
idf_component_get_property(app_trace app_trace COMPONENT_LIB)
target_link_libraries(${COMPONENT_LIB} INTERFACE $<TARGET_FILE:${app_trace}> gcov $<TARGET_FILE:${app_trace}> ${LIBC})
target_link_libraries(${COMPONENT_LIB} PUBLIC gcov ${LIBC} ${LIBM} gcc)

View File

@@ -1,56 +1,54 @@
menu "Application Level Tracing"
choice APPTRACE_DESTINATION
choice ESP32_APPTRACE_DESTINATION
prompt "Data Destination"
default APPTRACE_DEST_NONE
default ESP32_APPTRACE_DEST_NONE
help
Select destination for application trace: trace memory or none (to disable).
config APPTRACE_DEST_TRAX
config ESP32_APPTRACE_DEST_TRAX
bool "Trace memory"
select APPTRACE_ENABLE
config APPTRACE_DEST_NONE
select ESP32_APPTRACE_ENABLE
config ESP32_APPTRACE_DEST_NONE
bool "None"
endchoice
config APPTRACE_ENABLE
config ESP32_APPTRACE_ENABLE
bool
depends on !ESP32_TRAX && !ESP32S2_TRAX
depends on !ESP32_TRAX
select ESP32_MEMMAP_TRACEMEM
select ESP32S2_MEMMAP_TRACEMEM
select ESP32_MEMMAP_TRACEMEM_TWOBANKS
select ESP32S2_MEMMAP_TRACEMEM_TWOBANKS
default n
help
Enables/disable application tracing module.
config APPTRACE_LOCK_ENABLE
config ESP32_APPTRACE_LOCK_ENABLE
bool
default !SYSVIEW_ENABLE
help
Enables/disable application tracing module internal sync lock.
config APPTRACE_ONPANIC_HOST_FLUSH_TMO
config ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO
int "Timeout for flushing last trace data to host on panic"
depends on APPTRACE_ENABLE
depends on ESP32_APPTRACE_ENABLE
range -1 5000
default -1
help
Timeout for flushing last trace data to host in case of panic. In ms.
Use -1 to disable timeout and wait forever.
config APPTRACE_POSTMORTEM_FLUSH_THRESH
config ESP32_APPTRACE_POSTMORTEM_FLUSH_THRESH
int "Threshold for flushing last trace data to host on panic"
depends on APPTRACE_DEST_TRAX
depends on ESP32_APPTRACE_DEST_TRAX
range 0 16384
default 0
help
Threshold for flushing last trace data to host on panic in post-mortem mode.
This is minimal amount of data needed to perform flush. In bytes.
config APPTRACE_PENDING_DATA_SIZE_MAX
config ESP32_APPTRACE_PENDING_DATA_SIZE_MAX
int "Size of the pending data buffer"
depends on APPTRACE_DEST_TRAX
depends on ESP32_APPTRACE_DEST_TRAX
default 0
help
Size of the buffer for events in bytes. It is useful for buffering events from
@@ -58,10 +56,10 @@ menu "Application Level Tracing"
events will be discarded when main HW buffer is full.
menu "FreeRTOS SystemView Tracing"
depends on APPTRACE_ENABLE
depends on ESP32_APPTRACE_ENABLE
config SYSVIEW_ENABLE
bool "SystemView Tracing Enable"
depends on APPTRACE_ENABLE
depends on ESP32_APPTRACE_ENABLE
default n
help
Enables supporrt for SEGGER SystemView tracing functionality.
@@ -210,11 +208,10 @@ menu "Application Level Tracing"
endmenu
config APPTRACE_GCOV_ENABLE
config ESP32_GCOV_ENABLE
bool "GCOV to Host Enable"
depends on APPTRACE_ENABLE && !SYSVIEW_ENABLE
select ESP_DEBUG_STUBS_ENABLE
default n
depends on ESP32_DEBUG_STUBS_ENABLE && ESP32_APPTRACE_ENABLE && !SYSVIEW_ENABLE
default y
help
Enables support for GCOV data transfer to host.

View File

@@ -76,11 +76,11 @@
// It can happen that system panic occurs when there are very small amount of data which are not exposed to host yet (e.g. crash just after the
// TRAX block switch). In this case the previous 16KB of collected data will be dropped and host will see the latest, but very small piece of trace.
// It can be insufficient to diagnose the problem. To avoid such situations there is menuconfig option
// CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH
// CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_THRESH
// which controls the threshold for flushing data in case of panic.
// - Streaming mode. Tracing module enters this mode when host connects to target and sets respective bits in control registers (per core).
// In this mode before switching the block tracing module waits for the host to read all the data from the previously exposed block.
// On panic tracing module also waits (timeout is configured via menuconfig via CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO) for the host to read all data.
// On panic tracing module also waits (timeout is configured via menuconfig via CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO) for the host to read all data.
// 4. Communication Protocol
// =========================
@@ -114,7 +114,7 @@
// has not completed reading of the previous one yet. So in this case time critical tracing calls (which can not be delayed for too long time due to
// the lack of free memory in TRAX block) can be dropped. To avoid such scenarios tracing module implements data buffering. Buffered data will be sent
// to the host later when TRAX block switch occurs. The maximum size of the buffered data is controlled by menuconfig option
// CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX.
// CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX.
// 4.4 Target Connection/Disconnection
// -----------------------------------
@@ -158,16 +158,13 @@
#include <sys/param.h>
#include "soc/soc.h"
#include "soc/dport_reg.h"
#if CONFIG_IDF_TARGET_ESP32S2BETA
#include "soc/sensitive_reg.h"
#endif
#include "eri.h"
#include "trax.h"
#include "soc/timer_periph.h"
#include "freertos/FreeRTOS.h"
#include "esp_app_trace.h"
#if CONFIG_APPTRACE_ENABLE
#if CONFIG_ESP32_APPTRACE_ENABLE
#define ESP_APPTRACE_MAX_VPRINTF_ARGS 256
#define ESP_APPTRACE_HOST_BUF_SIZE 256
@@ -205,16 +202,10 @@ const static char *TAG = "esp_apptrace";
#define ESP_APPTRACE_LOGO( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_NONE, format, ##__VA_ARGS__)
// TODO: move these (and same definitions in trax.c to dport_reg.h)
#if CONFIG_IDF_TARGET_ESP32
#define TRACEMEM_MUX_PROBLK0_APPBLK1 0
#define TRACEMEM_MUX_BLK0_ONLY 1
#define TRACEMEM_MUX_BLK1_ONLY 2
#define TRACEMEM_MUX_PROBLK1_APPBLK0 3
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#define TRACEMEM_MUX_BLK0_NUM 19
#define TRACEMEM_MUX_BLK1_NUM 20
#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4))
#endif
// TRAX is disabled, so we use its registers for our own purposes
// | 31..XXXXXX..24 | 23 .(host_connect). 23 | 22 .(host_data). 22| 21..(block_id)..15 | 14..(block_len)..0 |
@@ -239,17 +230,10 @@ const static char *TAG = "esp_apptrace";
#endif
#define ESP_APPTRACE_USR_BLOCK_RAW_SZ(_s_) ((_s_) + sizeof(esp_tracedata_hdr_t))
#if CONFIG_IDF_TARGET_ESP32
static volatile uint8_t *s_trax_blocks[] = {
(volatile uint8_t *) 0x3FFFC000,
(volatile uint8_t *) 0x3FFF8000
};
#elif CONFIG_IDF_TARGET_ESP32S2BETA
static volatile uint8_t *s_trax_blocks[] = {
(volatile uint8_t *)TRACEMEM_BLK_NUM2ADDR(TRACEMEM_MUX_BLK0_NUM),
(volatile uint8_t *)TRACEMEM_BLK_NUM2ADDR(TRACEMEM_MUX_BLK1_NUM)
};
#endif
#define ESP_APPTRACE_TRAX_BLOCKS_NUM (sizeof(s_trax_blocks)/sizeof(s_trax_blocks[0]))
@@ -309,17 +293,17 @@ typedef struct {
typedef struct {
volatile esp_apptrace_trax_state_t state; // state
esp_apptrace_mem_block_t blocks[ESP_APPTRACE_TRAX_BLOCKS_NUM]; // memory blocks
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > 0
// ring buffer control struct for pending user blocks
esp_apptrace_rb_t rb_pend;
// storage for pending user blocks
uint8_t pending_data[CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX + 1];
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
uint8_t pending_data[CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX + 1];
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
// ring buffer control struct for pending user data chunks sizes,
// every chunk contains whole number of user blocks and fit into TRAX memory block
esp_apptrace_rb_t rb_pend_chunk_sz;
// storage for above ring buffer data
uint16_t pending_chunk_sz[CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX/ESP_APPTRACE_TRAX_BLOCK_SIZE + 2];
uint16_t pending_chunk_sz[CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX/ESP_APPTRACE_TRAX_BLOCK_SIZE + 2];
// current (accumulated) pending user data chunk size
uint16_t cur_pending_chunk_sz;
#endif
@@ -376,7 +360,7 @@ static esp_apptrace_hw_t s_trace_hw[ESP_APPTRACE_HW_MAX] = {
}
};
static inline int esp_apptrace_log_lock(void)
static inline int esp_apptrace_log_lock()
{
#if ESP_APPTRACE_PRINT_LOCK
esp_apptrace_tmo_t tmo;
@@ -388,29 +372,29 @@ static inline int esp_apptrace_log_lock(void)
#endif
}
static inline void esp_apptrace_log_unlock(void)
static inline void esp_apptrace_log_unlock()
{
#if ESP_APPTRACE_PRINT_LOCK
esp_apptrace_lock_give(&s_log_lock);
#endif
}
static inline esp_err_t esp_apptrace_lock_initialize(esp_apptrace_lock_t *lock)
static inline esp_err_t esp_apptrace_lock_initialize()
{
#if CONFIG_APPTRACE_LOCK_ENABLE
esp_apptrace_lock_init(lock);
#if CONFIG_ESP32_APPTRACE_LOCK_ENABLE
esp_apptrace_lock_init(&s_trace_buf.lock);
#endif
return ESP_OK;
}
static inline esp_err_t esp_apptrace_lock_cleanup(void)
static inline esp_err_t esp_apptrace_lock_cleanup()
{
return ESP_OK;
}
esp_err_t esp_apptrace_lock(esp_apptrace_tmo_t *tmo)
{
#if CONFIG_APPTRACE_LOCK_ENABLE
#if CONFIG_ESP32_APPTRACE_LOCK_ENABLE
esp_err_t ret = esp_apptrace_lock_take(&s_trace_buf.lock, tmo);
if (ret != ESP_OK) {
return ESP_FAIL;
@@ -419,28 +403,17 @@ esp_err_t esp_apptrace_lock(esp_apptrace_tmo_t *tmo)
return ESP_OK;
}
esp_err_t esp_apptrace_unlock(void)
esp_err_t esp_apptrace_unlock()
{
esp_err_t ret = ESP_OK;
#if CONFIG_APPTRACE_LOCK_ENABLE
#if CONFIG_ESP32_APPTRACE_LOCK_ENABLE
ret = esp_apptrace_lock_give(&s_trace_buf.lock);
#endif
return ret;
}
#if CONFIG_APPTRACE_DEST_TRAX
static inline void esp_apptrace_trax_select_memory_block(int block_num)
{
// select memory block to be exposed to the TRAX module (accessed by host)
#if CONFIG_IDF_TARGET_ESP32
DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, block_num ? TRACEMEM_MUX_BLK0_ONLY : TRACEMEM_MUX_BLK1_ONLY);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
DPORT_WRITE_PERI_REG(DPORT_PMS_OCCUPY_3_REG, block_num ? BIT(TRACEMEM_MUX_BLK0_NUM-4) : BIT(TRACEMEM_MUX_BLK1_NUM-4));
#endif
}
static void esp_apptrace_trax_init(void)
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
static void esp_apptrace_trax_init()
{
// Stop trace, if any (on the current CPU)
eri_write(ERI_TRAX_TRAXCTRL, TRAXCTRL_TRSTP);
@@ -453,7 +426,7 @@ static void esp_apptrace_trax_init(void)
ESP_APPTRACE_LOGI("Initialized TRAX on CPU%d", xPortGetCoreID());
}
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
// keep the size of buffered data for copying to TRAX mem block.
// Only whole user blocks should be copied from buffer to TRAX block upon the switch
static void esp_apptrace_trax_pend_chunk_sz_update(uint16_t size)
@@ -476,7 +449,7 @@ static void esp_apptrace_trax_pend_chunk_sz_update(uint16_t size)
}
}
static uint16_t esp_apptrace_trax_pend_chunk_sz_get(void)
static uint16_t esp_apptrace_trax_pend_chunk_sz_get()
{
uint16_t ch_sz;
ESP_APPTRACE_LOGD("Get chunk enter %d w-r-s %d-%d-%d", s_trace_buf.trax.cur_pending_chunk_sz,
@@ -494,7 +467,7 @@ static uint16_t esp_apptrace_trax_pend_chunk_sz_get(void)
#endif
// assumed to be protected by caller from multi-core/thread access
static esp_err_t esp_apptrace_trax_block_switch(void)
static esp_err_t esp_apptrace_trax_block_switch()
{
int prev_block_num = s_trace_buf.trax.state.in_block % 2;
int new_block_num = prev_block_num ? (0) : (1);
@@ -526,7 +499,7 @@ static esp_err_t esp_apptrace_trax_block_switch(void)
// switch to new block
s_trace_buf.trax.state.in_block++;
esp_apptrace_trax_select_memory_block(new_block_num);
DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, new_block_num ? TRACEMEM_MUX_BLK0_ONLY : TRACEMEM_MUX_BLK1_ONLY);
// handle data from host
esp_hostdata_hdr_t *hdr = (esp_hostdata_hdr_t *)s_trace_buf.trax.blocks[new_block_num].start;
if (ctrl_reg & ESP_APPTRACE_TRAX_HOST_DATA && hdr->block_sz > 0) {
@@ -544,9 +517,9 @@ static esp_err_t esp_apptrace_trax_block_switch(void)
}
hdr->block_sz = 0;
}
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > 0
// copy pending data to TRAX block if any
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
uint16_t max_chunk_sz = esp_apptrace_trax_pend_chunk_sz_get();
#else
uint16_t max_chunk_sz = s_trace_buf.trax.blocks[new_block_num].sz;
@@ -554,7 +527,7 @@ static esp_err_t esp_apptrace_trax_block_switch(void)
while (s_trace_buf.trax.state.markers[new_block_num] < max_chunk_sz) {
uint32_t read_sz = esp_apptrace_rb_read_size_get(&s_trace_buf.trax.rb_pend);
if (read_sz == 0) {
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
/* theres is a bug: esp_apptrace_trax_pend_chunk_sz_get returned wrong value,
it must be greater or equal to one returned by esp_apptrace_rb_read_size_get */
ESP_APPTRACE_LOGE("No pended bytes, must be > 0 and <= %d!", max_chunk_sz);
@@ -697,7 +670,7 @@ static inline uint8_t *esp_apptrace_trax_wait4buf(uint16_t size, esp_apptrace_tm
return NULL;
}
// check if we still have pending data
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > 0
if (esp_apptrace_rb_read_size_get(&s_trace_buf.trax.rb_pend) > 0) {
// if after TRAX block switch still have pending data (not all pending data have been pumped to TRAX block)
// alloc new pending buffer
@@ -711,7 +684,7 @@ static inline uint8_t *esp_apptrace_trax_wait4buf(uint16_t size, esp_apptrace_tm
{
// update block pointers
if (ESP_APPTRACE_TRAX_INBLOCK_MARKER() + size > ESP_APPTRACE_TRAX_INBLOCK_GET()->sz) {
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > 0
*pended = 1;
ptr = esp_apptrace_rb_produce(&s_trace_buf.trax.rb_pend, size);
if (ptr == NULL) {
@@ -741,7 +714,7 @@ static uint8_t *esp_apptrace_trax_get_buffer(uint32_t size, esp_apptrace_tmo_t *
return NULL;
}
// check for data in the pending buffer
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > 0
if (esp_apptrace_rb_read_size_get(&s_trace_buf.trax.rb_pend) > 0) {
// if we have buffered data try to switch TRAX block
esp_apptrace_trax_block_switch();
@@ -756,7 +729,7 @@ static uint8_t *esp_apptrace_trax_get_buffer(uint32_t size, esp_apptrace_tmo_t *
buf_ptr = esp_apptrace_trax_wait4buf(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size), tmo, &pended_buf);
if (buf_ptr) {
if (pended_buf) {
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
esp_apptrace_trax_pend_chunk_sz_update(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
#endif
} else {
@@ -766,18 +739,18 @@ static uint8_t *esp_apptrace_trax_get_buffer(uint32_t size, esp_apptrace_tmo_t *
}
}
} else {
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
esp_apptrace_trax_pend_chunk_sz_update(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
#endif
}
} else
#endif
if (ESP_APPTRACE_TRAX_INBLOCK_MARKER() + ESP_APPTRACE_USR_BLOCK_RAW_SZ(size) > ESP_APPTRACE_TRAX_INBLOCK_GET()->sz) {
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > 0
ESP_APPTRACE_LOGD("TRAX full. Get %d bytes from PEND buffer", size);
buf_ptr = esp_apptrace_rb_produce(&s_trace_buf.trax.rb_pend, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
if (buf_ptr) {
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
esp_apptrace_trax_pend_chunk_sz_update(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
#endif
}
@@ -788,7 +761,7 @@ static uint8_t *esp_apptrace_trax_get_buffer(uint32_t size, esp_apptrace_tmo_t *
buf_ptr = esp_apptrace_trax_wait4buf(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size), tmo, &pended_buf);
if (buf_ptr) {
if (pended_buf) {
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
esp_apptrace_trax_pend_chunk_sz_update(ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
#endif
} else {
@@ -872,7 +845,7 @@ static esp_err_t esp_apptrace_trax_status_reg_get(uint32_t *val)
return ESP_OK;
}
static esp_err_t esp_apptrace_trax_dest_init(void)
static esp_err_t esp_apptrace_trax_dest_init()
{
for (int i = 0; i < ESP_APPTRACE_TRAX_BLOCKS_NUM; i++) {
s_trace_buf.trax.blocks[i].start = (uint8_t *)s_trax_blocks[i];
@@ -880,29 +853,28 @@ static esp_err_t esp_apptrace_trax_dest_init(void)
s_trace_buf.trax.state.markers[i] = 0;
}
s_trace_buf.trax.state.in_block = ESP_APPTRACE_TRAX_INBLOCK_START;
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > 0
esp_apptrace_rb_init(&s_trace_buf.trax.rb_pend, s_trace_buf.trax.pending_data,
sizeof(s_trace_buf.trax.pending_data));
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
#if CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX > ESP_APPTRACE_TRAX_BLOCK_SIZE
s_trace_buf.trax.cur_pending_chunk_sz = 0;
esp_apptrace_rb_init(&s_trace_buf.trax.rb_pend_chunk_sz, (uint8_t *)s_trace_buf.trax.pending_chunk_sz,
sizeof(s_trace_buf.trax.pending_chunk_sz));
#endif
#endif
#if CONFIG_IDF_TARGET_ESP32
DPORT_WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, DPORT_PRO_TRACEMEM_ENA_M);
#if CONFIG_FREERTOS_UNICORE == 0
DPORT_WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, DPORT_APP_TRACEMEM_ENA_M);
#endif
#endif
esp_apptrace_trax_select_memory_block(0);
// Expose block 1 to host, block 0 is current trace input buffer
DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, TRACEMEM_MUX_BLK1_ONLY);
return ESP_OK;
}
#endif
esp_err_t esp_apptrace_init(void)
esp_err_t esp_apptrace_init()
{
int res;
@@ -915,7 +887,7 @@ esp_err_t esp_apptrace_init(void)
ESP_APPTRACE_LOGE("Failed to init log lock (%d)!", res);
return res;
}
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
res = esp_apptrace_trax_dest_init();
if (res != ESP_OK) {
ESP_APPTRACE_LOGE("Failed to init TRAX dest data (%d)!", res);
@@ -925,7 +897,7 @@ esp_err_t esp_apptrace_init(void)
#endif
}
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
// init TRAX on this CPU
esp_apptrace_trax_init();
#endif
@@ -947,7 +919,7 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size,
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -984,7 +956,7 @@ uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size,
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -1008,7 +980,7 @@ esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, u
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -1033,7 +1005,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -1069,7 +1041,7 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -1133,7 +1105,7 @@ uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -1157,7 +1129,7 @@ esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -1181,7 +1153,7 @@ esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, u
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -1225,7 +1197,7 @@ bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest)
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -1243,7 +1215,7 @@ esp_err_t esp_apptrace_status_reg_set(esp_apptrace_dest_t dest, uint32_t val)
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
@@ -1261,7 +1233,7 @@ esp_err_t esp_apptrace_status_reg_get(esp_apptrace_dest_t dest, uint32_t *val)
esp_apptrace_hw_t *hw = NULL;
if (dest == ESP_APPTRACE_DEST_TRAX) {
#if CONFIG_APPTRACE_DEST_TRAX
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
#else
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");

View File

@@ -15,12 +15,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_app_trace_util.h"
#include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/clk.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/clk.h"
#endif
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////// TIMEOUT /////////////////////////////////////

View File

@@ -14,23 +14,15 @@
// This module implements runtime file I/O API for GCOV.
#include <string.h>
#include "esp_task_wdt.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "soc/cpu.h"
#include "soc/timer_periph.h"
#include "esp_app_trace.h"
#include "esp_private/dbg_stubs.h"
#include "hal/timer_ll.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/libc_stubs.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/libc_stubs.h"
#endif
#if CONFIG_APPTRACE_GCOV_ENABLE
#if CONFIG_ESP32_GCOV_ENABLE
#define ESP_GCOV_DOWN_BUF_SIZE 4200
@@ -38,37 +30,37 @@
#include "esp_log.h"
const static char *TAG = "esp_gcov_rtio";
extern void __gcov_dump(void);
extern void __gcov_reset(void);
#if GCC_NOT_5_2_0
void __gcov_dump(void);
void __gcov_reset(void);
#else
/* The next code for old GCC */
static struct syscall_stub_table s_gcov_stub_table;
static int gcov_stub_lock_try_acquire_recursive(_lock_t *lock)
static void (*s_gcov_exit)(void);
/* Root of a program/shared-object state */
struct gcov_root
{
if (*lock && uxSemaphoreGetCount((xSemaphoreHandle)(*lock)) == 0) {
// we can do nothing here, gcov dump is initiated with some resource locked
// which is also used by gcov functions
ESP_EARLY_LOGE(TAG, "Lock 0x%x is busy during GCOV dump! System state can be inconsistent after dump!", lock);
}
return pdTRUE;
}
void *list;
unsigned dumped : 1; /* counts have been dumped. */
unsigned run_counted : 1; /* run has been accounted for. */
struct gcov_root *next;
struct gcov_root *prev;
};
static void gcov_stub_lock_acquire_recursive(_lock_t *lock)
{
gcov_stub_lock_try_acquire_recursive(lock);
}
/* Per-dynamic-object gcov state. */
extern struct gcov_root __gcov_root;
static void gcov_stub_lock_release_recursive(_lock_t *lock)
static void esp_gcov_reset_status(void)
{
__gcov_root.dumped = 0;
__gcov_root.run_counted = 0;
}
#endif
static int esp_dbg_stub_gcov_dump_do(void)
{
int ret = ESP_OK;
FILE* old_stderr = stderr;
FILE* old_stdout = stdout;
struct syscall_stub_table* old_table = syscall_table_ptr_pro;
ESP_EARLY_LOGV(TAG, "Alloc apptrace down buf %d bytes", ESP_GCOV_DOWN_BUF_SIZE);
void *down_buf = malloc(ESP_GCOV_DOWN_BUF_SIZE);
@@ -79,22 +71,18 @@ static int esp_dbg_stub_gcov_dump_do(void)
ESP_EARLY_LOGV(TAG, "Config apptrace down buf");
esp_apptrace_down_buffer_config(down_buf, ESP_GCOV_DOWN_BUF_SIZE);
ESP_EARLY_LOGV(TAG, "Dump data...");
// incase of dual-core chip APP and PRO CPUs share the same table, so it is safe to save only PRO's table
memcpy(&s_gcov_stub_table, old_table, sizeof(s_gcov_stub_table));
s_gcov_stub_table._lock_acquire_recursive = &gcov_stub_lock_acquire_recursive;
s_gcov_stub_table._lock_release_recursive = &gcov_stub_lock_release_recursive;
s_gcov_stub_table._lock_try_acquire_recursive = &gcov_stub_lock_try_acquire_recursive,
syscall_table_ptr_pro = &s_gcov_stub_table;
stderr = (FILE*) &__sf_fake_stderr;
stdout = (FILE*) &__sf_fake_stdout;
#if GCC_NOT_5_2_0
__gcov_dump();
// reset dump status to allow incremental data accumulation
__gcov_reset();
stdout = old_stdout;
stderr = old_stderr;
syscall_table_ptr_pro = old_table;
#else
ESP_EARLY_LOGV(TAG, "Check for dump handler %p", s_gcov_exit);
if (s_gcov_exit) {
s_gcov_exit();
// reset dump status to allow incremental data accumulation
esp_gcov_reset_status();
}
#endif
ESP_EARLY_LOGV(TAG, "Free apptrace down buf");
free(down_buf);
ESP_EARLY_LOGV(TAG, "Finish file transfer session");
@@ -114,17 +102,19 @@ static int esp_dbg_stub_gcov_dump_do(void)
*/
static int esp_dbg_stub_gcov_entry(void)
{
#if GCC_NOT_5_2_0
return esp_dbg_stub_gcov_dump_do();
#else
int ret = ESP_OK;
// disable IRQs on this CPU, other CPU is halted by OpenOCD
unsigned irq_state = portENTER_CRITICAL_NESTED();
ret = esp_dbg_stub_gcov_dump_do();
portEXIT_CRITICAL_NESTED(irq_state);
return ret;
#endif
}
int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused)))
{
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry);
return 0;
}
void esp_gcov_dump(void)
void esp_gcov_dump()
{
// disable IRQs on this CPU, other CPU is halted by OpenOCD
unsigned irq_state = portENTER_CRITICAL_NESTED();
@@ -134,13 +124,13 @@ void esp_gcov_dump(void)
#endif
while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) {
// to avoid complains that task watchdog got triggered for other tasks
timer_ll_wdt_set_protect(&TIMERG0, false);
timer_ll_wdt_feed(&TIMERG0);
timer_ll_wdt_set_protect(&TIMERG0, true);
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_feed=1;
TIMERG0.wdt_wprotect=0;
// to avoid reboot on INT_WDT
timer_ll_wdt_set_protect(&TIMERG1, false);
timer_ll_wdt_feed(&TIMERG1);
timer_ll_wdt_set_protect(&TIMERG1, true);
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_feed=1;
TIMERG1.wdt_wprotect=0;
}
esp_dbg_stub_gcov_dump_do();
@@ -150,6 +140,18 @@ void esp_gcov_dump(void)
portEXIT_CRITICAL_NESTED(irq_state);
}
int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused)))
{
#if GCC_NOT_5_2_0
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
#else
ESP_EARLY_LOGV(TAG, "%s %p", __FUNCTION__, function);
s_gcov_exit = function;
#endif
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry);
return 0;
}
void *gcov_rtio_fopen(const char *path, const char *mode)
{
ESP_EARLY_LOGV(TAG, "%s '%s' '%s'", __FUNCTION__, path, mode);

View File

@@ -32,7 +32,7 @@
static bool s_tracing;
esp_err_t heap_trace_init_tohost(void)
esp_err_t heap_trace_init_tohost()
{
if (s_tracing) {
return ESP_ERR_INVALID_STATE;

View File

@@ -25,7 +25,7 @@
#include <string.h>
#include "esp_app_trace.h"
#if CONFIG_APPTRACE_ENABLE
#if CONFIG_ESP32_APPTRACE_ENABLE
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include "esp_log.h"

View File

@@ -18,10 +18,6 @@
#include "esp_err.h"
#include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE
#ifdef __cplusplus
extern "C" {
#endif
/**
* Application trace data destinations bits.
*/
@@ -37,7 +33,7 @@ typedef enum {
*
* @return ESP_OK on success, otherwise see esp_err_t
*/
esp_err_t esp_apptrace_init(void);
esp_err_t esp_apptrace_init();
/**
* @brief Configures down buffer.
@@ -266,8 +262,4 @@ int esp_apptrace_fstop(esp_apptrace_dest_t dest);
*/
void esp_gcov_dump(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -14,10 +14,6 @@
#ifndef ESP_APP_TRACE_UTIL_H_
#define ESP_APP_TRACE_UTIL_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "freertos/FreeRTOS.h"
#include "esp_err.h"
@@ -168,8 +164,4 @@ uint32_t esp_apptrace_rb_read_size_get(esp_apptrace_rb_t *rb);
*/
uint32_t esp_apptrace_rb_write_size_get(esp_apptrace_rb_t *rb);
#ifdef __cplusplus
}
#endif
#endif //ESP_APP_TRACE_UTIL_H_

View File

@@ -14,10 +14,6 @@
#ifndef ESP_SYSVIEW_TRACE_H_
#define ESP_SYSVIEW_TRACE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include "esp_err.h"
#include "SEGGER_RTT.h" // SEGGER_RTT_ESP32_Flush
@@ -81,8 +77,4 @@ void esp_sysview_heap_trace_alloc(void *addr, uint32_t size, const void *callers
*/
void esp_sysview_heap_trace_free(void *addr, const void *callers);
#ifdef __cplusplus
}
#endif
#endif //ESP_SYSVIEW_TRACE_H_

View File

@@ -1,12 +1,4 @@
# sdkconfig replacement configurations for deprecated options formatted as
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
CONFIG_ESP32_APPTRACE_DESTINATION CONFIG_APPTRACE_DESTINATION
CONFIG_ESP32_APPTRACE_DEST_NONE CONFIG_APPTRACE_DEST_NONE
CONFIG_ESP32_APPTRACE_DEST_TRAX CONFIG_APPTRACE_DEST_TRAX
CONFIG_ESP32_APPTRACE_ENABLE CONFIG_APPTRACE_ENABLE
CONFIG_ESP32_APPTRACE_LOCK_ENABLE CONFIG_APPTRACE_LOCK_ENABLE
CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO
CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH
CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX
CONFIG_ESP32_GCOV_ENABLE CONFIG_APPTRACE_GCOV_ENABLE
CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_THRESH

View File

@@ -285,12 +285,12 @@ Revision: $Rev: 5626 $
* RTT lock configuration fallback
*/
#ifndef SEGGER_RTT_LOCK
void SEGGER_SYSVIEW_X_RTT_Lock(void);
void SEGGER_SYSVIEW_X_RTT_Lock();
#define SEGGER_RTT_LOCK() SEGGER_SYSVIEW_X_RTT_Lock() // Lock RTT (nestable) (i.e. disable interrupts)
#endif
#ifndef SEGGER_RTT_UNLOCK
void SEGGER_SYSVIEW_X_RTT_Unlock(void);
void SEGGER_SYSVIEW_X_RTT_Unlock();
#define SEGGER_RTT_UNLOCK() SEGGER_SYSVIEW_X_RTT_Unlock() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
#endif

View File

@@ -65,8 +65,6 @@ Revision: $Rev: 5927 $
#ifndef SEGGER_SYSVIEW_CONF_H
#define SEGGER_SYSVIEW_CONF_H
#include "soc/soc.h"
/*********************************************************************
*
* Defines, fixed
@@ -149,7 +147,7 @@ Revision: $Rev: 5927 $
* SystemView Id configuration
*/
//TODO: optimise it
#define SEGGER_SYSVIEW_ID_BASE SOC_DROM_LOW // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM)
#define SEGGER_SYSVIEW_ID_BASE 0x3F400000 // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM)
#define SEGGER_SYSVIEW_ID_SHIFT 0 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
/*********************************************************************
@@ -168,7 +166,7 @@ Revision: $Rev: 5927 $
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
#endif
unsigned SEGGER_SYSVIEW_X_SysView_Lock(void);
unsigned SEGGER_SYSVIEW_X_SysView_Lock();
void SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state);
// to be recursive save IRQ status on the stack of the caller
#define SEGGER_SYSVIEW_LOCK() unsigned _SYSVIEW_int_state = SEGGER_SYSVIEW_X_SysView_Lock()

View File

@@ -63,26 +63,11 @@ Revision: $Rev: 3734 $
*/
#include "freertos/FreeRTOS.h"
#include "SEGGER_SYSVIEW.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h"
#include "esp32/clk.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/ets_sys.h"
#include "esp32s2beta/clk.h"
#endif
#include "esp_app_trace.h"
#include "esp_app_trace_util.h"
#include "esp_intr_alloc.h"
#include "soc/soc.h"
#include "soc/interrupts.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h"
#include "esp32/clk.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/ets_sys.h"
#include "esp32s2beta/clk.h"
#endif
extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
@@ -96,7 +81,7 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
#define SYSVIEW_APP_NAME "FreeRTOS Application"
// The target device name
#define SYSVIEW_DEVICE_NAME CONFIG_IDF_TARGET
#define SYSVIEW_DEVICE_NAME "ESP32"
// Determine which timer to use as timestamp source
#if CONFIG_SYSVIEW_TS_SOURCE_CCOUNT
@@ -138,18 +123,14 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
#if TS_USE_CCOUNT
// CCOUNT is incremented at CPU frequency
#if CONFIG_IDF_TARGET_ESP32
#define SYSVIEW_TIMESTAMP_FREQ (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000)
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#define SYSVIEW_TIMESTAMP_FREQ (CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000)
#endif
#endif // TS_USE_CCOUNT
// System Frequency.
#define SYSVIEW_CPU_FREQ (esp_clk_cpu_freq())
// The lowest RAM address used for IDs (pointers)
#define SYSVIEW_RAM_BASE (SOC_DROM_LOW)
#define SYSVIEW_RAM_BASE (0x3F400000)
#if CONFIG_FREERTOS_CORETIMER_0
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
@@ -166,6 +147,78 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
static esp_apptrace_lock_t s_sys_view_lock = {.mux = portMUX_INITIALIZER_UNLOCKED, .int_state = 0};
static const char * const s_isr_names[] = {
[0] = "WIFI_MAC",
[1] = "WIFI_NMI",
[2] = "WIFI_BB",
[3] = "BT_MAC",
[4] = "BT_BB",
[5] = "BT_BB_NMI",
[6] = "RWBT",
[7] = "RWBLE",
[8] = "RWBT_NMI",
[9] = "RWBLE_NMI",
[10] = "SLC0",
[11] = "SLC1",
[12] = "UHCI0",
[13] = "UHCI1",
[14] = "TG0_T0_LEVEL",
[15] = "TG0_T1_LEVEL",
[16] = "TG0_WDT_LEVEL",
[17] = "TG0_LACT_LEVEL",
[18] = "TG1_T0_LEVEL",
[19] = "TG1_T1_LEVEL",
[20] = "TG1_WDT_LEVEL",
[21] = "TG1_LACT_LEVEL",
[22] = "GPIO",
[23] = "GPIO_NMI",
[24] = "FROM_CPU0",
[25] = "FROM_CPU1",
[26] = "FROM_CPU2",
[27] = "FROM_CPU3",
[28] = "SPI0",
[29] = "SPI1",
[30] = "SPI2",
[31] = "SPI3",
[32] = "I2S0",
[33] = "I2S1",
[34] = "UART0",
[35] = "UART1",
[36] = "UART2",
[37] = "SDIO_HOST",
[38] = "ETH_MAC",
[39] = "PWM0",
[40] = "PWM1",
[41] = "PWM2",
[42] = "PWM3",
[43] = "LEDC",
[44] = "EFUSE",
[45] = "CAN",
[46] = "RTC_CORE",
[47] = "RMT",
[48] = "PCNT",
[49] = "I2C_EXT0",
[50] = "I2C_EXT1",
[51] = "RSA",
[52] = "SPI1_DMA",
[53] = "SPI2_DMA",
[54] = "SPI3_DMA",
[55] = "WDT",
[56] = "TIMER1",
[57] = "TIMER2",
[58] = "TG0_T0_EDGE",
[59] = "TG0_T1_EDGE",
[60] = "TG0_WDT_EDGE",
[61] = "TG0_LACT_EDGE",
[62] = "TG1_T0_EDGE",
[63] = "TG1_T1_EDGE",
[64] = "TG1_WDT_EDGE",
[65] = "TG1_LACT_EDGE",
[66] = "MMU_IA",
[67] = "MPU_IA",
[68] = "CACHE_IA",
};
/*********************************************************************
*
* _cbSendSystemDesc()
@@ -178,9 +231,9 @@ static void _cbSendSystemDesc(void) {
SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME",C=Xtensa,O=FreeRTOS");
snprintf(irq_str, sizeof(irq_str), "I#%d=SysTick", SYSTICK_INTR_ID);
SEGGER_SYSVIEW_SendSysDesc(irq_str);
size_t isr_count = sizeof(esp_isr_names)/sizeof(esp_isr_names[0]);
size_t isr_count = sizeof(s_isr_names)/sizeof(s_isr_names[0]);
for (size_t i = 0; i < isr_count; ++i) {
snprintf(irq_str, sizeof(irq_str), "I#%d=%s", ETS_INTERNAL_INTR_SOURCE_OFF + i, esp_isr_names[i]);
snprintf(irq_str, sizeof(irq_str), "I#%d=%s", ETS_INTERNAL_INTR_SOURCE_OFF + i, s_isr_names[i]);
SEGGER_SYSVIEW_SendSysDesc(irq_str);
}
}
@@ -191,7 +244,7 @@ static void _cbSendSystemDesc(void) {
*
**********************************************************************
*/
static void SEGGER_SYSVIEW_TS_Init(void)
static void SEGGER_SYSVIEW_TS_Init()
{
/* We only need to initialize something if we use Timer Group.
* esp_timer and ccount can be used as is.
@@ -263,7 +316,7 @@ void SEGGER_SYSVIEW_Conf(void) {
SEGGER_SYSVIEW_DisableEvents(disable_evts);
}
U32 SEGGER_SYSVIEW_X_GetTimestamp(void)
U32 SEGGER_SYSVIEW_X_GetTimestamp()
{
#if TS_USE_TIMERGROUP
uint64_t ts = 0;
@@ -276,15 +329,15 @@ U32 SEGGER_SYSVIEW_X_GetTimestamp(void)
#endif
}
void SEGGER_SYSVIEW_X_RTT_Lock(void)
void SEGGER_SYSVIEW_X_RTT_Lock()
{
}
void SEGGER_SYSVIEW_X_RTT_Unlock(void)
void SEGGER_SYSVIEW_X_RTT_Unlock()
{
}
unsigned SEGGER_SYSVIEW_X_SysView_Lock(void)
unsigned SEGGER_SYSVIEW_X_SysView_Lock()
{
esp_apptrace_tmo_t tmo;
esp_apptrace_tmo_init(&tmo, SEGGER_LOCK_WAIT_TMO);

View File

@@ -18,11 +18,7 @@
#include "SEGGER_SYSVIEW.h"
#include "SEGGER_SYSVIEW_Conf.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/ets_sys.h"
#endif
#include "esp_app_trace.h"
#include "esp_log.h"

View File

@@ -9,7 +9,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#if CONFIG_APPTRACE_ENABLE == 1
#if CONFIG_ESP32_APPTRACE_ENABLE == 1
#include "esp_app_trace.h"
#include "esp_app_trace_util.h"
@@ -125,7 +125,7 @@ typedef struct {
static SemaphoreHandle_t s_print_lock;
#endif
static uint64_t esp_apptrace_test_ts_get(void);
static uint64_t esp_apptrace_test_ts_get();
static void esp_apptrace_test_timer_isr(void *arg)
{
@@ -145,16 +145,56 @@ static void esp_apptrace_test_timer_isr(void *arg)
}
tim_arg->data.wr_cnt++;
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->id);
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id);
if (tim_arg->group == 0) {
if (tim_arg->id == 0) {
TIMERG0.int_clr_timers.t0 = 1;
TIMERG0.hw_timer[0].update = 1;
TIMERG0.hw_timer[0].config.alarm_en = 1;
} else {
TIMERG0.int_clr_timers.t1 = 1;
TIMERG0.hw_timer[1].update = 1;
TIMERG0.hw_timer[1].config.alarm_en = 1;
}
}
if (tim_arg->group == 1) {
if (tim_arg->id == 0) {
TIMERG1.int_clr_timers.t0 = 1;
TIMERG1.hw_timer[0].update = 1;
TIMERG1.hw_timer[0].config.alarm_en = 1;
} else {
TIMERG1.int_clr_timers.t1 = 1;
TIMERG1.hw_timer[1].update = 1;
TIMERG1.hw_timer[1].config.alarm_en = 1;
}
}
}
static void esp_apptrace_test_timer_isr_crash(void *arg)
{
esp_apptrace_test_timer_arg_t *tim_arg = (esp_apptrace_test_timer_arg_t *)arg;
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->id);
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id);
if (tim_arg->group == 0) {
if (tim_arg->id == 0) {
TIMERG0.int_clr_timers.t0 = 1;
TIMERG0.hw_timer[0].update = 1;
TIMERG0.hw_timer[0].config.alarm_en = 1;
} else {
TIMERG0.int_clr_timers.t1 = 1;
TIMERG0.hw_timer[1].update = 1;
TIMERG0.hw_timer[1].config.alarm_en = 1;
}
}
if (tim_arg->group == 1) {
if (tim_arg->id == 0) {
TIMERG1.int_clr_timers.t0 = 1;
TIMERG1.hw_timer[0].update = 1;
TIMERG1.hw_timer[0].config.alarm_en = 1;
} else {
TIMERG1.int_clr_timers.t1 = 1;
TIMERG1.hw_timer[1].update = 1;
TIMERG1.hw_timer[1].config.alarm_en = 1;
}
}
if (tim_arg->data.wr_cnt < ESP_APPTRACE_TEST_BLOCKS_BEFORE_CRASH) {
uint32_t *ts = (uint32_t *)(tim_arg->data.buf + sizeof(uint32_t));
*ts = (uint32_t)esp_apptrace_test_ts_get();//xthal_get_ccount();//xTaskGetTickCount();
@@ -343,7 +383,7 @@ static void esp_apptrace_test_task_crash(void *p)
static int s_ts_timer_group, s_ts_timer_idx;
static uint64_t esp_apptrace_test_ts_get(void)
static uint64_t esp_apptrace_test_ts_get()
{
uint64_t ts = 0;
timer_get_counter_value(s_ts_timer_group, s_ts_timer_idx, &ts);
@@ -373,7 +413,7 @@ static void esp_apptrace_test_ts_init(int timer_group, int timer_idx)
timer_start(timer_group, timer_idx);
}
static void esp_apptrace_test_ts_cleanup(void)
static void esp_apptrace_test_ts_cleanup()
{
timer_config_t config;
@@ -810,8 +850,28 @@ static void esp_sysview_test_timer_isr(void *arg)
//ESP_APPTRACE_TEST_LOGI("tim-%d: IRQ %d/%d\n", tim_arg->id, tim_arg->group, tim_arg->timer);
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->id);
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id);
if (tim_arg->group == 0) {
if (tim_arg->timer == 0) {
TIMERG0.int_clr_timers.t0 = 1;
TIMERG0.hw_timer[0].update = 1;
TIMERG0.hw_timer[0].config.alarm_en = 1;
} else {
TIMERG0.int_clr_timers.t1 = 1;
TIMERG0.hw_timer[1].update = 1;
TIMERG0.hw_timer[1].config.alarm_en = 1;
}
}
if (tim_arg->group == 1) {
if (tim_arg->timer == 0) {
TIMERG1.int_clr_timers.t0 = 1;
TIMERG1.hw_timer[0].update = 1;
TIMERG1.hw_timer[0].config.alarm_en = 1;
} else {
TIMERG1.int_clr_timers.t1 = 1;
TIMERG1.hw_timer[1].update = 1;
TIMERG1.hw_timer[1].config.alarm_en = 1;
}
}
}
static void esp_sysviewtrace_test_task(void *p)

View File

@@ -29,11 +29,8 @@ if(NOT BOOTLOADER_BUILD)
idf_build_get_property(idf_path IDF_PATH)
idf_build_get_property(python PYTHON)
idf_component_get_property(partition_table_dir partition_table COMPONENT_DIR)
add_custom_command(OUTPUT ${blank_otadata_file}
COMMAND ${python} ${partition_table_dir}/gen_empty_partition.py
COMMAND ${python} ${idf_path}/components/partition_table/gen_empty_partition.py
${otadata_size} ${blank_otadata_file})
add_custom_target(blank_ota_data ALL DEPENDS ${blank_otadata_file})

View File

@@ -40,6 +40,9 @@ read_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_pytho
--partition-table-offset $(partition_table_offset) \
read_otadata
erase_ota: erase_otadata
@echo "WARNING: erase_ota is deprecated. Use erase_otadata instead."
all: blank_ota_data
flash: blank_ota_data
ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT

View File

@@ -42,7 +42,7 @@
#include "esp_efuse.h"
#define SUB_TYPE_ID(i) (i & 0x0F)
#define SUB_TYPE_ID(i) (i & 0x0F)
typedef struct ota_ops_entry_ {
uint32_t handle;
@@ -200,7 +200,7 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
// must erase the partition before writing to it
assert(it->erased_size > 0 && "must erase the partition before writing to it");
if (it->wrote_size == 0 && it->partial_bytes == 0 && size > 0 && data_bytes[0] != ESP_IMAGE_HEADER_MAGIC) {
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x)", data_bytes[0]);
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x", data_bytes[0]);
return ESP_ERR_OTA_VALIDATE_FAILED;
}
@@ -687,12 +687,12 @@ static esp_err_t esp_ota_current_ota_is_workable(bool valid)
return ESP_OK;
}
esp_err_t esp_ota_mark_app_valid_cancel_rollback(void)
esp_err_t esp_ota_mark_app_valid_cancel_rollback()
{
return esp_ota_current_ota_is_workable(true);
}
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot(void)
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot()
{
return esp_ota_current_ota_is_workable(false);
}
@@ -715,7 +715,7 @@ static int get_last_invalid_otadata(const esp_ota_select_entry_t *two_otadata)
return num_invalid_otadata;
}
const esp_partition_t* esp_ota_get_last_invalid_partition(void)
const esp_partition_t* esp_ota_get_last_invalid_partition()
{
esp_ota_select_entry_t otadata[2];
if (read_otadata(otadata) == NULL) {

View File

@@ -221,7 +221,7 @@ esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, es
* @return
* - ESP_OK: if successful.
*/
esp_err_t esp_ota_mark_app_valid_cancel_rollback(void);
esp_err_t esp_ota_mark_app_valid_cancel_rollback();
/**
* @brief This function is called to roll back to the previously workable app with reboot.
@@ -233,14 +233,14 @@ esp_err_t esp_ota_mark_app_valid_cancel_rollback(void);
* - ESP_FAIL: if not successful.
* - ESP_ERR_OTA_ROLLBACK_FAILED: The rollback is not possible due to flash does not have any apps.
*/
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot(void);
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot();
/**
* @brief Returns last partition with invalid state (ESP_OTA_IMG_INVALID or ESP_OTA_IMG_ABORTED).
*
* @return partition.
*/
const esp_partition_t* esp_ota_get_last_invalid_partition(void);
const esp_partition_t* esp_ota_get_last_invalid_partition();
/**
* @brief Returns state for given partition.

View File

@@ -1,4 +1,3 @@
idf_component_register(SRC_DIRS "."
INCLUDE_DIRS "."
REQUIRES unity test_utils app_update bootloader_support nvs_flash
)
INCLUDE_DIRS "."
REQUIRES unity test_utils app_update bootloader_support nvs_flash)

View File

@@ -58,7 +58,7 @@ TEST_CASE("esp_ota_get_next_update_partition logic", "[ota]")
TEST_ASSERT_NOT_NULL(ota_1);
TEST_ASSERT_NULL(ota_2); /* this partition shouldn't exist in test partition table */
TEST_ASSERT_EQUAL_PTR(factory, running); /* this may not be true if/when we get OTA tests that do OTA updates */
TEST_ASSERT_EQUAL_PTR(factory, running); /* this may not be true if/when we get OTA tests that do OTA updates */
/* (The test steps verify subtypes before verifying pointer equality, because the failure messages are more readable
this way.)

View File

@@ -7,13 +7,9 @@
#include "string.h"
#include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/spi_flash.h"
#include "esp32/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/spi_flash.h"
#include "esp32s2beta/rom/rtc.h"
#endif
#include "esp32/rom/ets_sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -122,7 +118,7 @@ static void reboot_as_deep_sleep(void)
/* @brief Copies a current app to next partition (OTA0-15), after that ESP is rebooting and run this (the next) OTAx.
*/
static void copy_current_app_to_next_part_and_reboot(void)
static void copy_current_app_to_next_part_and_reboot()
{
const esp_partition_t *cur_app = esp_ota_get_running_partition();
copy_current_app_to_next_part(cur_app, get_next_update_partition());
@@ -268,19 +264,19 @@ static void test_flow1(void)
case 2:
ESP_LOGI(TAG, "Factory");
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
copy_current_app_to_next_part_and_reboot();
copy_current_app_to_next_part_and_reboot(cur_app);
break;
case 3:
ESP_LOGI(TAG, "OTA0");
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
mark_app_valid();
copy_current_app_to_next_part_and_reboot();
copy_current_app_to_next_part_and_reboot(cur_app);
break;
case 4:
ESP_LOGI(TAG, "OTA1");
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
mark_app_valid();
copy_current_app_to_next_part_and_reboot();
copy_current_app_to_next_part_and_reboot(cur_app);
break;
case 5:
ESP_LOGI(TAG, "OTA0");
@@ -311,7 +307,7 @@ static void test_flow2(void)
case 2:
ESP_LOGI(TAG, "Factory");
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
copy_current_app_to_next_part_and_reboot();
copy_current_app_to_next_part_and_reboot(cur_app);
break;
case 3:
ESP_LOGI(TAG, "OTA0");
@@ -348,13 +344,13 @@ static void test_flow3(void)
case 2:
ESP_LOGI(TAG, "Factory");
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
copy_current_app_to_next_part_and_reboot();
copy_current_app_to_next_part_and_reboot(cur_app);
break;
case 3:
ESP_LOGI(TAG, "OTA0");
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
mark_app_valid();
copy_current_app_to_next_part_and_reboot();
copy_current_app_to_next_part_and_reboot(cur_app);
break;
case 4:
ESP_LOGI(TAG, "OTA1");
@@ -406,7 +402,7 @@ static void test_flow4(void)
nvs_close(handle);
nvs_flash_deinit();
copy_current_app_to_next_part_and_reboot();
copy_current_app_to_next_part_and_reboot(cur_app);
break;
case 3:
ESP_LOGI(TAG, "OTA0");
@@ -448,7 +444,7 @@ static void test_flow4(void)
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
// 3 Stage: run OTA0 -> check it -> set_pin_factory_reset -> reboot --//--
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
#endif
#ifdef CONFIG_BOOTLOADER_APP_TEST
@@ -491,7 +487,7 @@ static void test_flow5(void)
// 2 Stage: run factory -> check it -> copy factory to Test and set pin_test_app -> reboot --//--
// 3 Stage: run test -> check it -> reset pin_test_app -> reboot --//--
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
#endif
static const esp_partition_t* app_update(void)

View File

@@ -22,12 +22,8 @@
# define ASIO_NO_EXCEPTIONS
# endif // CONFIG_COMPILER_CXX_EXCEPTIONS
# ifndef CONFIG_COMPILER_RTTI
# define ASIO_NO_TYPEID
# endif // CONFIG_COMPILER_RTTI
//
// LWIP compatibility inet and address macros/functions
// LWIP compatifility inet and address macros/functions
//
# define LWIP_COMPAT_SOCKET_INET 1
# define LWIP_COMPAT_SOCKET_ADDR 1
@@ -38,6 +34,12 @@
# define ASIO_DISABLE_SERIAL_PORT
# define ASIO_SEPARATE_COMPILATION
# define ASIO_STANDALONE
# define ASIO_NO_TYPEID
# define ASIO_DISABLE_SIGNAL
# define ASIO_HAS_PTHREADS
# define ASIO_DISABLE_EPOLL
# define ASIO_DISABLE_EVENTFD
# define ASIO_DISABLE_SIGNAL
# define ASIO_DISABLE_SIGACTION
#endif // _ESP_ASIO_CONFIG_H_

View File

@@ -1,7 +1,7 @@
idf_component_register(PRIV_REQUIRES partition_table)
# Do not generate flash file when building bootloader or is in early expansion of the build
if(BOOTLOADER_BUILD OR NOT CONFIG_APP_BUILD_BOOTLOADER)
if(BOOTLOADER_BUILD)
return()
endif()

View File

@@ -204,13 +204,10 @@ menu "Bootloader config"
config BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD
int "Size of the efuse secure version field"
depends on BOOTLOADER_APP_ANTI_ROLLBACK
range 1 32 if IDF_TARGET_ESP32
default 32 if IDF_TARGET_ESP32
range 1 16 if IDF_TARGET_ESP32S2BETA
default 16 if IDF_TARGET_ESP32S2BETA
range 1 32
default 32
help
The size of the efuse secure version field.
Its length is limited to 32 bits for ESP32 and 16 bits for ESP32S2BETA.
The size of the efuse secure version field. Its length is limited to 32 bits.
This determines how many times the security version can be increased.
config BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
@@ -222,53 +219,6 @@ menu "Bootloader config"
It allow to test anti-rollback implemention without permanent write eFuse bits.
In partition table should be exist this partition `emul_efuse, data, 5, , 0x2000`.
config BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
bool "Skip image validation when exiting deep sleep"
depends on (SECURE_BOOT_ENABLED && SECURE_BOOT_INSECURE) || !SECURE_BOOT_ENABLED
default n
help
This option disables the normal validation of an image coming out of
deep sleep (checksums, SHA256, and signature). This is a trade-off
between wakeup performance from deep sleep, and image integrity checks.
Only enable this if you know what you are doing. It should not be used
in conjunction with using deep_sleep() entry and changing the active OTA
partition as this would skip the validation upon first load of the new
OTA partition.
config BOOTLOADER_RESERVE_RTC_SIZE
hex
default 0x10 if BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP || BOOTLOADER_CUSTOM_RESERVE_RTC
default 0
help
Reserve RTC FAST memory for Skip image validation. This option in bytes.
This option reserves an area in the RTC FAST memory (access only PRO_CPU).
Used to save the addresses of the selected application.
When a wakeup occurs (from Deep sleep), the bootloader retrieves it and
loads the application without validation.
config BOOTLOADER_CUSTOM_RESERVE_RTC
bool "Reserve RTC FAST memory for custom purposes"
default n
help
This option allows the customer to place data in the RTC FAST memory,
this area remains valid when rebooted, except for power loss.
This memory is located at a fixed address and is available
for both the bootloader and the application.
(The application and bootoloader must be compiled with the same option).
The RTC FAST memory has access only through PRO_CPU.
config BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE
hex "Size in bytes for custom purposes"
range 0 0x10
default 0
depends on BOOTLOADER_CUSTOM_RESERVE_RTC
help
This option reserves in RTC FAST memory the area for custom purposes.
If you want to create your own bootloader and save more information
in this area of memory, you can increase it. It must be a multiple of 4 bytes.
This area (rtc_retain_mem_t) is reserved and has access from the bootloader and an application.
endmenu # Bootloader
@@ -284,15 +234,12 @@ menu "Security features"
config SECURE_SIGNED_ON_UPDATE
bool
default y
select MBEDTLS_ECP_DP_SECP256R1_ENABLED
depends on SECURE_BOOT_ENABLED || SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
config SECURE_SIGNED_APPS
bool
default y
select MBEDTLS_ECP_DP_SECP256R1_ENABLED
select MBEDTLS_ECP_C
select MBEDTLS_ECDH_C
select MBEDTLS_ECDSA_C
depends on SECURE_SIGNED_ON_BOOT || SECURE_SIGNED_ON_UPDATE
@@ -391,7 +338,7 @@ menu "Security features"
config SECURE_BOOT_SIGNING_KEY
string "Secure boot private signing key"
depends on SECURE_BOOT_BUILD_SIGNED_BINARIES
default "secure_boot_signing_key.pem"
default secure_boot_signing_key.pem
help
Path to the key file used to sign app images.
@@ -407,7 +354,7 @@ menu "Security features"
config SECURE_BOOT_VERIFICATION_KEY
string "Secure boot public signature verification key"
depends on SECURE_SIGNED_APPS && !SECURE_BOOT_BUILD_SIGNED_BINARIES
default "signature_verification_key.bin"
default signature_verification_key.bin
help
Path to a public key file used to verify signed images. This key is compiled into the bootloader and/or
app, to verify app images.
@@ -421,7 +368,7 @@ menu "Security features"
choice SECURE_BOOTLOADER_KEY_ENCODING
bool "Hardware Key Encoding"
depends on SECURE_BOOTLOADER_REFLASHABLE
default SECURE_BOOTLOADER_KEY_ENCODING_256BIT
default SECURE_BOOTLOADER_NO_ENCODING
help
In reflashable secure bootloader mode, a hardware key is derived from the signing key (with SHA-256) and
@@ -465,26 +412,6 @@ menu "Security features"
Read https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html
before enabling.
choice SECURE_FLASH_ENCRYPTION_KEYSIZE
bool "Size of generated AES-XTS key"
default SECURE_FLASH_ENCRYPTION_AES128
depends on IDF_TARGET_ESP32S2BETA && SECURE_FLASH_ENC_ENABLED
help
Size of generated AES-XTS key.
AES-128 uses a 256-bit key (32 bytes) which occupies one Efuse key block.
AES-256 uses a 512-bit key (64 bytes) which occupies two Efuse key blocks.
This setting is ignored if either type of key is already burned to Efuse before the first boot.
In this case, the pre-burned key is used and no new key is generated.
config SECURE_FLASH_ENCRYPTION_AES128
bool "AES-128 (256-bit key)"
config SECURE_FLASH_ENCRYPTION_AES256
bool "AES-256 (512-bit key)"
endchoice
choice SECURE_FLASH_ENCRYPTION_MODE
bool "Enable usage mode"
depends on SECURE_FLASH_ENC_ENABLED
@@ -588,20 +515,6 @@ menu "Security features"
Only set this option in testing environments.
config SECURE_FLASH_REQUIRE_ALREADY_ENABLED
bool "Require flash encryption to be already enabled"
depends on SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
default N
help
If not set (default), and flash encryption is not yet enabled in eFuses, the 2nd stage bootloader
will enable flash encryption: generate the flash encryption key and program eFuses.
If this option is set, and flash encryption is not yet enabled, the bootloader will error out and
reboot.
If flash encryption is enabled in eFuses, this option does not change the bootloader behavior.
Only use this option in testing environments, to avoid accidentally enabling flash encryption on
the wrong device. The device needs to have flash encryption already enabled using espefuse.py.
endmenu # Potentially Insecure
endmenu # Security features

View File

@@ -1,7 +1,7 @@
set(BOOTLOADER_OFFSET 0x1000)
# Do not generate flash file when building bootloader
if(BOOTLOADER_BUILD OR NOT CONFIG_APP_BUILD_BOOTLOADER)
if(BOOTLOADER_BUILD)
return()
endif()
@@ -67,7 +67,6 @@ if(CONFIG_SECURE_SIGNED_APPS)
set(SECURE_BOOT_SIGNING_KEY ${secure_boot_signing_key}) # needed by some other components
set(sign_key_arg "-DSECURE_BOOT_SIGNING_KEY=${secure_boot_signing_key}")
set(ver_key_arg)
add_dependencies(gen_secure_boot_keys gen_secure_boot_signing_key)
else()
@@ -88,34 +87,27 @@ if(CONFIG_SECURE_SIGNED_APPS)
add_custom_target(gen_secure_boot_verification_key)
endif()
set(sign_key_arg)
set(ver_key_arg "-DSECURE_BOOT_VERIFICATION_KEY=${secure_boot_verification_key}")
add_dependencies(gen_secure_boot_keys gen_secure_boot_verification_key)
endif()
else()
set(sign_key_arg)
set(ver_key_arg)
endif()
idf_build_get_property(idf_path IDF_PATH)
idf_build_get_property(idf_target IDF_TARGET)
idf_build_get_property(sdkconfig SDKCONFIG)
idf_build_get_property(python PYTHON)
idf_build_get_property(extra_cmake_args EXTRA_CMAKE_ARGS)
externalproject_add(bootloader
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/subproject"
BINARY_DIR "${BOOTLOADER_BUILD_DIR}"
CMAKE_ARGS -DSDKCONFIG=${sdkconfig} -DIDF_PATH=${idf_path} -DIDF_TARGET=${idf_target}
-DPYTHON_DEPS_CHECKED=1 -DPYTHON=${python}
-DPYTHON_DEPS_CHECKED=1
-DEXTRA_COMPONENT_DIRS=${CMAKE_CURRENT_LIST_DIR}
${sign_key_arg} ${ver_key_arg}
# LEGACY_INCLUDE_COMMON_HEADERS has to be passed in via cache variable since
# the bootloader common component requirements depends on this and
# config variables are not available before project() call.
-DLEGACY_INCLUDE_COMMON_HEADERS=${CONFIG_LEGACY_INCLUDE_COMMON_HEADERS}
${extra_cmake_args}
INSTALL_COMMAND ""
BUILD_ALWAYS 1 # no easy way around this...
BUILD_BYPRODUCTS ${bootloader_binary_files}
@@ -132,4 +124,4 @@ endif()
# So for now we just have the top-level build remove the final build products...
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
${bootloader_binary_files})
${bootloader_binary_files})

View File

@@ -75,8 +75,7 @@ if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
add_custom_command(OUTPUT "${bootloader_digest_bin}"
COMMAND ${CMAKE_COMMAND} -E echo "DIGEST ${bootloader_digest_bin}"
COMMAND ${ESPSECUREPY} digest_secure_bootloader --keyfile "${secure_bootloader_key}"
-o "${bootloader_digest_bin}" "${CMAKE_BINARY_DIR}/bootloader.bin"
MAIN_DEPENDENCY "${CMAKE_BINARY_DIR}/.bin_timestamp"
-o "${bootloader_digest_bin}" "${CMAKE_BINARY_DIR}/bootloader.bin"
DEPENDS gen_secure_bootloader_key gen_project_binary
VERBATIM)

View File

@@ -2,8 +2,7 @@ idf_component_register(SRCS "bootloader_start.c"
REQUIRES bootloader bootloader_support)
idf_build_get_property(target IDF_TARGET)
set(scripts "ld/${target}/bootloader.ld"
"ld/${target}/bootloader.rom.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "${scripts}")
set(scripts "${target}.bootloader.ld"
"${target}.bootloader.rom.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "${scripts}")

View File

@@ -0,0 +1,4 @@
# Submodules normally added in component.mk, but fully qualified
# paths can be added at this level (we need binary librtc to be
# available to link bootloader).
COMPONENT_SUBMODULES += $(IDF_PATH)/components/esp_wifi/lib_esp32

View File

@@ -1,4 +1,4 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -11,39 +11,38 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_log.h"
#include "esp32/rom/gpio.h"
#include "esp32/rom/spi_flash.h"
#include "bootloader_config.h"
#include "bootloader_init.h"
#include "bootloader_utility.h"
#include "bootloader_common.h"
#include "sdkconfig.h"
#include "esp_image_format.h"
static const char *TAG = "boot";
static const char* TAG = "boot";
static int select_partition_number(bootloader_state_t *bs);
static int select_partition_number (bootloader_state_t *bs);
static int selected_boot_partition(const bootloader_state_t *bs);
/*
* We arrive here after the ROM bootloader finished loading this second stage bootloader from flash.
* The hardware is mostly uninitialized, flash cache is down and the app CPU is in reset.
* We do have a stack, so we can do the initialization in C.
*/
void __attribute__((noreturn)) call_start_cpu0(void)
void __attribute__((noreturn)) call_start_cpu0()
{
// 1. Hardware initialization
if (bootloader_init() != ESP_OK) {
bootloader_reset();
}
#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
// If this boot is a wake up from the deep sleep then go to the short way,
// try to load the application which worked before deep sleep.
// It skips a lot of checks due to it was done before (while first boot).
bootloader_utility_load_boot_image_from_deep_sleep();
// If it is not successful try to load an application as usual.
#endif
// 2. Select the number of boot partition
bootloader_state_t bs = {0};
bootloader_state_t bs = { 0 };
int boot_index = select_partition_number(&bs);
if (boot_index == INVALID_INDEX) {
bootloader_reset();
@@ -54,7 +53,7 @@ void __attribute__((noreturn)) call_start_cpu0(void)
}
// Select the number of boot partition
static int select_partition_number(bootloader_state_t *bs)
static int select_partition_number (bootloader_state_t *bs)
{
// 1. Load partition table
if (!bootloader_utility_load_partition_table(bs)) {
@@ -75,8 +74,7 @@ static int selected_boot_partition(const bootloader_state_t *bs)
int boot_index = bootloader_utility_get_selected_boot_partition(bs);
if (boot_index == INVALID_INDEX) {
return boot_index; // Unrecoverable failure (not due to corrupt ota data or bad partition contents)
}
if (bootloader_common_get_reset_reason(0) != DEEPSLEEP_RESET) {
} else {
// Factory firmware.
#ifdef CONFIG_BOOTLOADER_FACTORY_RESET
if (bootloader_common_check_long_hold_gpio(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET, CONFIG_BOOTLOADER_HOLD_TIME_GPIO) == 1) {
@@ -93,7 +91,7 @@ static int selected_boot_partition(const bootloader_state_t *bs)
return bootloader_utility_get_selected_boot_partition(bs);
}
#endif
// TEST firmware.
// TEST firmware.
#ifdef CONFIG_BOOTLOADER_APP_TEST
if (bootloader_common_check_long_hold_gpio(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST, CONFIG_BOOTLOADER_HOLD_TIME_GPIO) == 1) {
ESP_LOGI(TAG, "Detect a boot condition of the test firmware");
@@ -115,7 +113,7 @@ static int selected_boot_partition(const bootloader_state_t *bs)
}
// Return global reent struct if any newlib functions are linked to bootloader
struct _reent *__getreent(void)
{
struct _reent* __getreent() {
return _GLOBAL_REENT;
}

View File

@@ -6,17 +6,14 @@
#
LINKER_SCRIPTS := \
$(COMPONENT_PATH)/ld/$(IDF_TARGET)/bootloader.ld \
$(COMPONENT_PATH)/ld/$(IDF_TARGET)/bootloader.rom.ld \
$(IDF_TARGET).bootloader.ld \
$(IDF_TARGET).bootloader.rom.ld \
$(IDF_PATH)/components/esp_rom/$(IDF_TARGET)/ld/$(IDF_TARGET).rom.ld \
$(IDF_PATH)/components/esp_rom/$(IDF_TARGET)/ld/$(IDF_TARGET).rom.newlib-funcs.ld \
$(IDF_PATH)/components/$(IDF_TARGET)/ld/$(IDF_TARGET).peripherals.ld
# SPI driver patch for ROM is only needed in ESP32
ifdef CONFIG_IDF_TARGET_ESP32
ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
LINKER_SCRIPTS += $(IDF_PATH)/components/esp_rom/$(IDF_TARGET)/ld/$(IDF_TARGET).rom.spiflash.ld
endif
ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
LINKER_SCRIPTS += $(IDF_PATH)/components/esp_rom/$(IDF_TARGET)/ld/$(IDF_TARGET).rom.spiflash.ld
endif
COMPONENT_ADD_LDFLAGS += -L $(COMPONENT_PATH) $(addprefix -T ,$(LINKER_SCRIPTS))

View File

@@ -40,7 +40,6 @@ SECTIONS
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*liblog.a:(.literal .text .literal.* .text.*)
*libgcc.a:(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_clock.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_common.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*)
@@ -54,7 +53,6 @@ SECTIONS
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
*libsoc.a:rtc_wdt.*(.literal .text .literal.* .text.*)
*libsoc.a:rtc_clk.*(.literal .text .literal.* .text.*)
*libefuse.a:*.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)

View File

@@ -1,162 +0,0 @@
/*
Linker file used to link the bootloader.
*/
/* Simplified memory map for the bootloader
The main purpose is to make sure the bootloader can load into main memory
without overwriting itself.
*/
MEMORY
{
/* I/O */
dport0_seg (RW) : org = 0x3FF00000, len = 0x10
iram_loader_seg (RWX) : org = 0x40062000, len = 0x4000 /* 16KB, IRAM */
iram_seg (RWX) : org = 0x40066000, len = 0x4000 /* 16KB, IRAM */
/* 8k at the end of DRAM, before ROM data & stack */
dram_seg (RW) : org = 0x3FFFA000, len = 0x2000
}
/* Default entry point: */
ENTRY(call_start_cpu0);
SECTIONS
{
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*liblog.a:(.literal .text .literal.* .text.*)
*libgcc.a:(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_common.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
*libbootloader_support.a:secure_boot_signatures.*(.literal .text .literal.* .text.*)
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
*libsoc.a:rtc_wdt.*(.literal .text .literal.* .text.*)
*libefuse.a:*.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
.iram.text :
{
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
} > iram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} >dram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
_data_end = ABSOLUTE(.);
} >dram_seg
.dram0.rodata :
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
_heap_start = ABSOLUTE(.);
} >dram_seg
.iram.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg
}

View File

@@ -1,14 +0,0 @@
/*
* ESP32S2 ROM address table
* Generated for ROM with MD5sum: f054d40c5f6b9207d3827460a6f5748c
*/
PROVIDE ( ets_update_cpu_frequency = 0x4000d954 );
/* ToDo: Following address may need modification */
PROVIDE ( MD5Final = 0x400056e8 );
PROVIDE ( MD5Init = 0x40005648 );
PROVIDE ( MD5Update = 0x40005668 );
/* bootloader will use following functions from xtensa hal library */
xthal_get_ccount = 0x40015cbc;
xthal_get_ccompare = 0x40015ce8;
xthal_set_ccompare = 0x40015cc4;

View File

@@ -1,103 +1,65 @@
set(srcs
set(srcs
"src/bootloader_clock.c"
"src/bootloader_common.c"
"src/bootloader_flash.c"
"src/bootloader_flash_config.c"
"src/bootloader_random.c"
"src/bootloader_utility.c"
"src/esp_image_format.c"
"src/flash_encrypt.c"
"src/flash_partitions.c"
"src/flash_qio_mode.c"
"src/bootloader_flash_config_${IDF_TARGET}.c"
"src/bootloader_efuse_${IDF_TARGET}.c"
)
if(IDF_TARGET STREQUAL "esp32")
# Not supported on ESP32S2Beta yet
list(APPEND srcs "src/flash_encrypt.c")
endif()
"src/flash_qio_mode.c")
if(BOOTLOADER_BUILD)
set(include_dirs "include" "include_bootloader")
set(requires soc) #unfortunately the header directly uses SOC registers
set(priv_requires micro-ecc spi_flash efuse)
list(APPEND srcs
list(APPEND srcs
"src/bootloader_init.c"
"src/${IDF_TARGET}/bootloader_sha.c"
"src/${IDF_TARGET}/flash_encrypt.c"
"src/${IDF_TARGET}/secure_boot_signatures.c"
"src/${IDF_TARGET}/secure_boot.c"
"src/${IDF_TARGET}/bootloader_${IDF_TARGET}.c"
)
"src/${IDF_TARGET}/secure_boot.c")
else()
list(APPEND srcs
list(APPEND srcs
"src/idf/bootloader_sha.c"
"src/idf/secure_boot_signatures.c")
set(include_dirs "include")
set(priv_include_dirs "include_bootloader")
set(requires soc) #unfortunately the header directly uses SOC registers
set(priv_requires spi_flash mbedtls efuse)
endif()
set(requires soc) #unfortunately the header directly uses SOC registers
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${include_dirs}"
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
REQUIRES "${requires}"
PRIV_REQUIRES "${priv_requires}")
if(CONFIG_SECURE_SIGNED_APPS)
if(BOOTLOADER_BUILD)
# Whether CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES or not, we need verification key to embed
# in the library.
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
# We generate the key from the signing key. The signing key is passed from the main project.
get_filename_component(secure_boot_signing_key
"${SECURE_BOOT_SIGNING_KEY}"
ABSOLUTE BASE_DIR "${project_dir}")
get_filename_component(secure_boot_verification_key
"signature_verification_key.bin"
ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
add_custom_command(OUTPUT "${secure_boot_verification_key}"
COMMAND ${ESPSECUREPY}
if(BOOTLOADER_BUILD AND CONFIG_SECURE_SIGNED_APPS)
# Whether CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES or not, we need verification key to embed
# in the library.
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
# We generate the key from the signing key. The signing key is passed from the main project.
get_filename_component(secure_boot_signing_key
"${SECURE_BOOT_SIGNING_KEY}"
ABSOLUTE BASE_DIR "${project_dir}")
get_filename_component(secure_boot_verification_key
"signature_verification_key.bin"
ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
add_custom_command(OUTPUT "${secure_boot_verification_key}"
COMMAND ${ESPSECUREPY}
extract_public_key --keyfile "${secure_boot_signing_key}"
"${secure_boot_verification_key}"
DEPENDS ${secure_boot_signing_key}
VERBATIM)
else()
# We expect to 'inherit' the verification key passed from main project.
get_filename_component(secure_boot_verification_key
${SECURE_BOOT_VERIFICATION_KEY}
ABSOLUTE BASE_DIR "${project_dir}")
endif()
else() # normal app build
idf_build_get_property(project_dir PROJECT_DIR)
if(CONFIG_SECURE_BOOT_VERIFICATION_KEY)
# verification-only build supplies verification key
set(secure_boot_verification_key ${CONFIG_SECURE_BOOT_VERIFICATION_KEY})
get_filename_component(secure_boot_verification_key
${secure_boot_verification_key}
ABSOLUTE BASE_DIR "${project_dir}")
else()
# sign at build time, extracts key from signing key
set(secure_boot_verification_key "${CMAKE_BINARY_DIR}/signature_verification_key.bin")
get_filename_component(secure_boot_signing_key
${CONFIG_SECURE_BOOT_SIGNING_KEY}
ABSOLUTE BASE_DIR "${project_dir}")
add_custom_command(OUTPUT "${secure_boot_verification_key}"
COMMAND ${ESPSECUREPY}
extract_public_key --keyfile "${secure_boot_signing_key}"
"${secure_boot_verification_key}"
WORKING_DIRECTORY ${project_dir}
DEPENDS ${secure_boot_signing_key}
VERBATIM)
endif()
VERBATIM)
else()
# We expect to 'inherit' the verification key passed from main project.
get_filename_component(secure_boot_verification_key
${SECURE_BOOT_VERIFICATION_KEY}
ABSOLUTE BASE_DIR "${project_dir}")
endif()
# Embed the verification key in the binary (app & bootloader)
#
target_add_binary_data(${COMPONENT_LIB} "${secure_boot_verification_key}" "BINARY"
RENAME_TO signature_verification_key_bin)
target_add_binary_data(${COMPONENT_LIB} "${secure_boot_verification_key}" "BINARY")
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
"${secure_boot_verification_key}")

View File

@@ -19,9 +19,6 @@ ifndef IS_BOOTLOADER_BUILD
COMPONENT_OBJEXCLUDE := src/bootloader_init.o
endif
COMPONENT_OBJEXCLUDE += src/bootloader_flash_config_esp32s2beta.o \
src/bootloader_efuse_esp32s2beta.o
#
# Secure boot signing key support
#
@@ -49,10 +46,10 @@ $(ORIG_SECURE_BOOT_VERIFICATION_KEY):
$(SECURE_BOOT_VERIFICATION_KEY): $(ORIG_SECURE_BOOT_VERIFICATION_KEY) $(SDKCONFIG_MAKEFILE)
$(summary) CP $< $@
cp $< $@
endif #CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES
endif
COMPONENT_EXTRA_CLEAN += $(SECURE_BOOT_VERIFICATION_KEY)
COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY)
endif #CONFIG_SECURE_SIGNED_APPS
endif

View File

@@ -24,11 +24,6 @@ extern "C" {
*/
void bootloader_clock_configure(void);
/** @brief Return the rated maximum frequency of this chip
*/
int bootloader_clock_get_rated_freq_mhz(void);
#ifdef __cplusplus
}
#endif

View File

@@ -15,13 +15,6 @@
#pragma once
#include "esp_flash_partitions.h"
#include "esp_image_format.h"
#include "esp_app_format.h"
// RESET_REASON is declared in rom/rtc.h
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/rtc.h"
#endif
#ifdef __cplusplus
extern "C" {
@@ -34,11 +27,6 @@ typedef enum {
GPIO_NOT_HOLD = 0 /*!< If the GPIO input is not low */
} esp_comm_gpio_hold_t;
typedef enum {
ESP_IMAGE_BOOTLOADER,
ESP_IMAGE_APPLICATION
} esp_image_type;
/**
* @brief Calculate crc for the OTA data select.
*
@@ -94,13 +82,6 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
*/
bool bootloader_common_label_search(const char *list, char *label);
/**
* @brief Configure default SPI pin modes and drive strengths
*
* @param drv GPIO drive level (determined by clock frequency)
*/
void bootloader_configure_spi_pins(int drv);
/**
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
*
@@ -148,7 +129,7 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
/**
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
*
*
* Returns a description for the requested app partition.
* @param[in] partition App partition description.
* @param[out] app_desc Structure of info about app.
@@ -160,98 +141,10 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
*/
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
/**
* @brief Get chip revision
*
* @return Chip revision number
*/
uint8_t bootloader_common_get_chip_revision(void);
/**
* @brief Query reset reason
*
* @param cpu_no CPU number
* @return reset reason enumeration
*/
RESET_REASON bootloader_common_get_reset_reason(int cpu_no);
/**
* @brief Check if the image (bootloader and application) has valid chip ID and revision
*
* @param[in] img_hdr: image header
* @param[in] type: image type, bootloader or application
* @return
* - ESP_OK: image and chip are matched well
* - ESP_FAIL: image doesn't match to the chip
*/
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type);
/**
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
*/
void bootloader_common_vddsdio_configure(void);
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
/**
* @brief Returns partition from rtc_retain_mem
*
* Uses to get the partition of application which was worked before to go to the deep sleep.
* This partition was stored in rtc_retain_mem.
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @return partition: If rtc_retain_mem is valid.
* - NULL: If it is not valid.
*/
esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void);
/**
* @brief Update the partition and reboot_counter in rtc_retain_mem.
*
* This function saves the partition of application for fast booting from the deep sleep.
* An algorithm uses this partition to avoid reading the otadata and does not validate an image.
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @param[in] partition App partition description. Can be NULL, in this case rtc_retain_mem.partition is not updated.
* @param[in] reboot_counter If true then update reboot_counter.
*
*/
void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter);
/**
* @brief Reset entire rtc_retain_mem.
*
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*/
void bootloader_common_reset_rtc_retain_mem(void);
/**
* @brief Returns reboot_counter from rtc_retain_mem
*
* The reboot_counter counts the number of reboots. Reset only when power is off.
* The very first launch of the application will be from 1.
* Overflow is not possible, it will stop at the value UINT16_MAX.
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @return reboot_counter: 1..65535
* - 0: If rtc_retain_mem is not valid.
*/
uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void);
/**
* @brief Returns rtc_retain_mem
*
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @return rtc_retain_mem
*/
rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void);
#endif
void bootloader_common_vddsdio_configure();
#ifdef __cplusplus
}

View File

@@ -25,7 +25,7 @@ extern "C" {
*
* @return None
*/
void bootloader_flash_update_id(void);
void bootloader_flash_update_id();
/**
* @brief Set the flash CS setup and hold time.
@@ -35,7 +35,7 @@ void bootloader_flash_update_id(void);
*
* @return None
*/
void bootloader_flash_cs_timing_config(void);
void bootloader_flash_cs_timing_config();
/**
* @brief Configure SPI flash clock.

View File

@@ -13,19 +13,6 @@
// limitations under the License.
#pragma once
/**
* @brief ESP chip ID
*
*/
typedef enum {
ESP_CHIP_ID_ESP32 = 0x0000, /*!< chip ID: ESP32 */
ESP_CHIP_ID_INVALID = 0xFFFF /*!< Invalid chip ID (we defined it to make sure the esp_chip_id_t is 2 bytes size) */
} __attribute__((packed)) esp_chip_id_t;
/** @cond */
_Static_assert(sizeof(esp_chip_id_t) == 2, "esp_chip_id_t should be 16 bit");
/** @endcond */
/**
* @brief SPI flash mode, used in esp_image_header_t
*/
@@ -76,9 +63,7 @@ typedef struct {
* the IDF bootloader uses software to configure the WP
* pin and sets this field to 0xEE=disabled) */
uint8_t spi_pin_drv[3]; /*!< Drive settings for the SPI flash pins (read by ROM bootloader) */
esp_chip_id_t chip_id; /*!< Chip identification number */
uint8_t min_chip_rev; /*!< Minimum chip revision supported by image */
uint8_t reserved[8]; /*!< Reserved bytes in additional header space, currently unused */
uint8_t reserved[11]; /*!< Reserved bytes in ESP32 additional header space, currently unused */
uint8_t hash_appended; /*!< If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum.
* Included in image length. This digest
* is separate to secure boot and only used for detecting corruption.

View File

@@ -20,7 +20,6 @@
#include "esp_spi_flash.h"
#endif
#include "soc/efuse_periph.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
@@ -47,17 +46,11 @@ typedef enum {
*
* @return true if flash encryption is enabled.
*/
static inline /** @cond */ IRAM_ATTR /** @endcond */ bool esp_flash_encryption_enabled(void)
{
uint32_t flash_crypt_cnt;
#if CONFIG_IDF_TARGET_ESP32
flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_RD_FLASH_CRYPT_CNT);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
flash_crypt_cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_SPI_BOOT_CRYPT_CNT);
#endif
static inline /** @cond */ IRAM_ATTR /** @endcond */ bool esp_flash_encryption_enabled(void) {
uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_RD_FLASH_CRYPT_CNT);
/* __builtin_parity is in flash, so we calculate parity inline */
bool enabled = false;
while (flash_crypt_cnt) {
while(flash_crypt_cnt) {
if (flash_crypt_cnt & 1) {
enabled = !enabled;
}
@@ -129,7 +122,7 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
* serial re-flashing of an unauthorised code in absence of secure boot.
*
*/
void esp_flash_write_protect_crypt_cnt(void);
void esp_flash_write_protect_crypt_cnt();
/** @brief Return the flash encryption mode
*
@@ -138,22 +131,7 @@ void esp_flash_write_protect_crypt_cnt(void);
*
* @return
*/
esp_flash_enc_mode_t esp_get_flash_encryption_mode(void);
/** @brief Check the flash encryption mode during startup
*
* @note This function is called automatically during app startup,
* it doesn't need to be called from the app.
*
* Verifies the flash encryption config during startup:
*
* - Correct any insecure flash encryption settings if hardware
* Secure Boot is enabled.
* - Log warnings if the efuse config doesn't match the project
* config in any way
*/
void esp_flash_encryption_init_checks(void);
esp_flash_enc_mode_t esp_get_flash_encryption_mode();
#ifdef __cplusplus
}

View File

@@ -98,6 +98,12 @@ typedef struct {
esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
/* This function is included for compatibility with the ESP-IDF v3.x API */
inline static __attribute__((deprecated)) esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
{
return esp_partition_table_verify(partition_table, log_errors, num_partitions);
}
/**
* Check whether the region on the main flash is safe to write.
*

View File

@@ -42,42 +42,44 @@ typedef struct {
uint8_t image_digest[32]; /* appended SHA-256 digest */
} esp_image_metadata_t;
/* Mode selection for esp_image_load() */
typedef enum {
ESP_IMAGE_VERIFY, /* Verify image contents, not load to memory, load metadata. Print errors. */
ESP_IMAGE_VERIFY_SILENT, /* Verify image contents, not load to memory, load metadata. Don't print errors. */
ESP_IMAGE_VERIFY, /* Verify image contents, load metadata. Print errors. */
ESP_IMAGE_VERIFY_SILENT, /* Verify image contents, load metadata. Don't print errors. */
#ifdef BOOTLOADER_BUILD
ESP_IMAGE_LOAD, /* Verify image contents, load to memory, load metadata. Print errors. */
ESP_IMAGE_LOAD_NO_VALIDATE, /* Not verify image contents, load to memory, load metadata. Print errors. */
ESP_IMAGE_LOAD, /* Verify image contents, load to memory. Print errors. */
#endif
} esp_image_load_mode_t;
typedef struct {
esp_partition_pos_t partition; /*!< Partition of application which worked before goes to the deep sleep. */
uint16_t reboot_counter; /*!< Reboot counter. Reset only when power is off. */
uint16_t reserve; /*!< Reserve */
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
uint8_t custom[CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE]; /*!< Reserve for custom propose */
#endif
uint32_t crc; /*!< Check sum crc32 */
} rtc_retain_mem_t;
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
_Static_assert(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
#endif
#if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
_Static_assert(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
#endif
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif
#if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
_Static_assert(sizeof(rtc_retain_mem_t) <= ESP_BOOTLOADER_RESERVE_RTC, "Reserved RTC area must exceed size of rtc_retain_mem_t");
#endif
/**
* @brief Verify and (optionally, in bootloader mode) load an app image.
*
* This name is deprecated and is included for compatibility with the ESP-IDF v3.x API.
* It will be removed in V4.0 version.
* Function has been renamed to esp_image_verify().
* Use function esp_image_verify() to verify a image. And use function bootloader_load_image() to load image from a bootloader space.
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param mode Mode of operation (verify, silent verify, or load).
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function. 'start_addr' member should be set (to the start address of the image.) Other fields will all be initialised by this function.
*
* Image validation checks:
* - Magic byte.
* - Partition smaller than 16MB.
* - All segments & image fit in partition.
* - 8 bit image checksum is valid.
* - SHA-256 of image is valid (if image has this appended).
* - (Signature) if signature verification is enabled.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) __attribute__((deprecated));
/**
* @brief Verify an app image.
@@ -132,24 +134,6 @@ esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t
*/
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Load an app image without verification (available only in space of bootloader).
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t bootloader_load_image_no_verify(const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Verify the bootloader image.
*

View File

@@ -18,9 +18,6 @@
#include "soc/efuse_periph.h"
#include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/efuse.h"
#endif
#ifdef CONFIG_SECURE_BOOT_ENABLED
#if !defined(CONFIG_SECURE_SIGNED_ON_BOOT) || !defined(CONFIG_SECURE_SIGNED_ON_UPDATE) || !defined(CONFIG_SECURE_SIGNED_APPS)
@@ -39,18 +36,14 @@ extern "C" {
/** @brief Is secure boot currently enabled in hardware?
*
* This means that the ROM bootloader code will only boot
* a verified secure bootloader from now on.
* Secure boot is enabled if the ABS_DONE_0 efuse is blown. This means
* that the ROM bootloader code will only boot a verified secure
* bootloader digest from now on.
*
* @return true if secure boot is enabled.
*/
static inline bool esp_secure_boot_enabled(void)
{
#if CONFIG_IDF_TARGET_ESP32
static inline bool esp_secure_boot_enabled(void) {
return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
return ets_efuse_secure_boot_enabled();
#endif
}
/** @brief Generate secure digest from bootloader image

View File

@@ -18,6 +18,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <esp_err.h>
#include "esp_spi_flash.h"
#define FLASH_SECTOR_SIZE 0x1000
#define FLASH_BLOCK_SIZE 0x10000
@@ -34,7 +35,7 @@
*
* @return Number of free pages
*/
uint32_t bootloader_mmap_get_free_pages(void);
uint32_t bootloader_mmap_get_free_pages();
/**
* @brief Map a region of flash to data memory

View File

@@ -14,37 +14,6 @@
#pragma once
#include "esp_err.h"
#include "esp_image_format.h"
/**@{*/
/**
* @brief labels from bootloader linker script: bootloader.ld
*
*/
extern int _bss_start;
extern int _bss_end;
extern int _data_start;
extern int _data_end;
/**@}*/
/**
* @brief bootloader image header
*
*/
extern esp_image_header_t bootloader_image_hdr;
/**@{*/
/**
* @brief Common initialization steps that are applied to all targets.
*
*/
esp_err_t bootloader_read_bootloader_header(void);
esp_err_t bootloader_check_bootloader_validity(void);
void bootloader_clear_bss_section(void);
void bootloader_config_wdt(void);
void bootloader_enable_random(void);
void bootloader_print_banner(void);
/**@}*/
/* @brief Prepares hardware for work.
*
@@ -56,4 +25,4 @@ void bootloader_print_banner(void);
* @return ESP_OK - If the setting is successful.
* ESP_FAIL - If the setting is not successful.
*/
esp_err_t bootloader_init(void);
esp_err_t bootloader_init();

View File

@@ -26,7 +26,7 @@
typedef void *bootloader_sha256_handle_t;
bootloader_sha256_handle_t bootloader_sha256_start(void);
bootloader_sha256_handle_t bootloader_sha256_start();
void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len);

View File

@@ -15,7 +15,6 @@
#include "bootloader_config.h"
#include "esp_image_format.h"
#include "bootloader_config.h"
/**
* @brief Load partition table.
@@ -55,16 +54,6 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
*/
__attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index);
#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
/**
* @brief Load that application which was worked before we go to the deep sleep.
*
* Checks the reboot reason if it is the deep sleep and has a valid partition in the RTC memory
* then try to load the application which was worked before we go to the deep sleep.
*
*/
void bootloader_utility_load_boot_image_from_deep_sleep(void);
#endif
/**
* @brief Software reset the ESP32
@@ -97,14 +86,3 @@ __attribute__((noreturn)) void bootloader_reset(void);
* ESP_ERR_INVALID_ARG: Error in the passed arguments
*/
esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len);
/**
* @brief Debug log contents of a buffer as hexadecimal
*
* @note Only works if component log level is DEBUG or higher.
*
* @param buffer Buffer to log
* @param length Length of buffer in bytes. Maximum length 128 bytes.
* @param label Label to print at beginning of log line.
*/
void bootloader_debug_buffer(const void *buffer, size_t length, const char *label);

View File

@@ -30,7 +30,7 @@ void bootloader_enable_qio_mode(void);
* mfg_id = (ID >> 16) & 0xFF;
flash_id = ID & 0xffff;
*/
uint32_t bootloader_read_flash_id(void);
uint32_t bootloader_read_flash_id();
#ifdef __cplusplus
}

View File

@@ -11,21 +11,14 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "esp32/rom/uart.h"
#include "esp32/rom/rtc.h"
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/dport_reg.h"
#include "soc/efuse_periph.h"
#ifdef CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/uart.h"
#include "esp32/rom/rtc.h"
#else
#include "esp32s2beta/rom/uart.h"
#include "esp32s2beta/rom/rtc.h"
#endif
void bootloader_clock_configure(void)
void bootloader_clock_configure()
{
// ROM bootloader may have put a lot of text into UART0 FIFO.
// Wait for it to be printed.
@@ -34,30 +27,23 @@ void bootloader_clock_configure(void)
// and will be done with the bootloader much earlier than UART FIFO is empty.
uart_tx_wait_idle(0);
/* Set CPU to 80MHz. Keep other clocks unmodified. */
int cpu_freq_mhz = 80;
/* On ESP32 rev 0, switching to 80/160 MHz if clock was previously set to
* 240 MHz may cause the chip to lock up (see section 3.5 of the errata
* document). For rev. 0, switch to 240 instead if it has been enabled
* previously.
*/
#if CONFIG_IDF_TARGET_ESP32
/* Set CPU to 80MHz. Keep other clocks unmodified. */
int cpu_freq_mhz = 80;
uint32_t chip_ver_reg = REG_READ(EFUSE_BLK0_RDATA3_REG);
if ((chip_ver_reg & EFUSE_RD_CHIP_VER_REV1_M) == 0 &&
DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL) == DPORT_CPUPERIOD_SEL_240) {
cpu_freq_mhz = 240;
}
#endif
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
#if CONFIG_IDF_TARGET_ESP32
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
clk_cfg.xtal_freq = RTC_XTAL_FREQ_40M;
clk_cfg.cpu_freq = RTC_CPU_FREQ_80M;
#endif
clk_cfg.slow_freq = rtc_clk_slow_freq_get();
clk_cfg.fast_freq = rtc_clk_fast_freq_get();
rtc_clk_init(clk_cfg);
@@ -72,12 +58,3 @@ void bootloader_clock_configure(void)
}
#endif
}
#ifdef BOOTLOADER_BUILD
int esp_clk_apb_freq(void)
{
return rtc_clk_apb_freq_get();
}
#endif // BOOTLOADER_BUILD

View File

@@ -17,22 +17,14 @@
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_log.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/spi_flash.h"
#include "esp32/rom/crc.h"
#include "esp32/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/spi_flash.h"
#include "esp32s2beta/rom/crc.h"
#include "esp32s2beta/rom/ets_sys.h"
#include "esp32s2beta/rom/gpio.h"
#endif
#include "esp_secure_boot.h"
#include "esp_flash_partitions.h"
#include "bootloader_flash.h"
#include "bootloader_common.h"
#include "soc/gpio_periph.h"
#include "soc/rtc.h"
#include "soc/efuse_reg.h"
#include "esp_image_format.h"
#include "bootloader_sha.h"
#include "sys/param.h"
@@ -264,7 +256,7 @@ esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t
return ESP_OK;
}
void bootloader_common_vddsdio_configure(void)
void bootloader_common_vddsdio_configure()
{
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
@@ -278,91 +270,3 @@ void bootloader_common_vddsdio_configure(void)
}
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
}
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type)
{
esp_err_t err = ESP_OK;
esp_chip_id_t chip_id = CONFIG_IDF_FIRMWARE_CHIP_ID;
if (chip_id != img_hdr->chip_id) {
ESP_LOGE(TAG, "mismatch chip ID, expected %d, found %d", chip_id, img_hdr->chip_id);
err = ESP_FAIL;
}
uint8_t revision = bootloader_common_get_chip_revision();
if (revision < img_hdr->min_chip_rev) {
ESP_LOGE(TAG, "can't run on lower chip revision, expected %d, found %d", revision, img_hdr->min_chip_rev);
err = ESP_FAIL;
} else if (revision != img_hdr->min_chip_rev) {
#ifdef BOOTLOADER_BUILD
ESP_LOGI(TAG, "chip revision: %d, min. %s chip revision: %d", revision, type == ESP_IMAGE_BOOTLOADER ? "bootloader" : "application", img_hdr->min_chip_rev);
#endif
}
return err;
}
RESET_REASON bootloader_common_get_reset_reason(int cpu_no)
{
return rtc_get_reset_reason(cpu_no);
}
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)(SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t));
static bool check_rtc_retain_mem(void)
{
return crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc)) == rtc_retain_mem->crc && rtc_retain_mem->crc != UINT32_MAX;
}
static void update_rtc_retain_mem_crc(void)
{
rtc_retain_mem->crc = crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc));
}
void bootloader_common_reset_rtc_retain_mem(void)
{
memset(rtc_retain_mem, 0, sizeof(rtc_retain_mem_t));
}
uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void)
{
if (check_rtc_retain_mem()) {
return rtc_retain_mem->reboot_counter;
}
return 0;
}
esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void)
{
if (check_rtc_retain_mem()) {
return &rtc_retain_mem->partition;
}
return NULL;
}
void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter)
{
if (reboot_counter) {
if (!check_rtc_retain_mem()) {
bootloader_common_reset_rtc_retain_mem();
}
if (++rtc_retain_mem->reboot_counter == 0) {
// do not allow to overflow. Stop it.
--rtc_retain_mem->reboot_counter;
}
}
if (partition != NULL) {
rtc_retain_mem->partition.offset = partition->offset;
rtc_retain_mem->partition.size = partition->size;
}
update_rtc_retain_mem_crc();
}
rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void)
{
return rtc_retain_mem;
}
#endif

View File

@@ -1,56 +0,0 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "bootloader_common.h"
#include "bootloader_clock.h"
#include "soc/efuse_reg.h"
#include "soc/apb_ctrl_reg.h"
uint8_t bootloader_common_get_chip_revision(void)
{
uint8_t eco_bit0, eco_bit1, eco_bit2;
eco_bit0 = (REG_READ(EFUSE_BLK0_RDATA3_REG) & 0xF000) >> 15;
eco_bit1 = (REG_READ(EFUSE_BLK0_RDATA5_REG) & 0x100000) >> 20;
eco_bit2 = (REG_READ(APB_CTRL_DATE_REG) & 0x80000000) >> 31;
uint32_t combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0;
uint8_t chip_ver = 0;
switch (combine_value) {
case 0:
chip_ver = 0;
break;
case 1:
chip_ver = 1;
break;
case 3:
chip_ver = 2;
break;
case 7:
chip_ver = 3;
break;
default:
chip_ver = 0;
break;
}
return chip_ver;
}
int bootloader_clock_get_rated_freq_mhz()
{
//Check if ESP32 is rated for a CPU frequency of 160MHz only
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) &&
REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_LOW)) {
return 160;
}
return 240;
}

View File

@@ -1,29 +0,0 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "bootloader_clock.h"
#include "bootloader_common.h"
int bootloader_clock_get_rated_freq_mhz()
{
/* No known limitation: all chips are 240MHz rated */
return 240;
}
uint8_t bootloader_common_get_chip_revision(void)
{
/* No other revisions for ESP32-S2beta */
return 0;
}

View File

@@ -17,9 +17,6 @@
#include <esp_log.h>
#include <esp_spi_flash.h> /* including in bootloader for error values */
#include <esp_flash_encrypt.h>
#if CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/spi_flash.h"
#endif
#ifndef BOOTLOADER_BUILD
/* Normal app version maps to esp_spi_flash.h operations...
@@ -28,7 +25,7 @@ static const char *TAG = "bootloader_mmap";
static spi_flash_mmap_handle_t map;
uint32_t bootloader_mmap_get_free_pages(void)
uint32_t bootloader_mmap_get_free_pages()
{
return spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
}
@@ -40,7 +37,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
return NULL; /* existing mapping in use... */
}
const void *result = NULL;
uint32_t src_page = src_addr & ~(SPI_FLASH_MMU_PAGE_SIZE - 1);
uint32_t src_page = src_addr & ~(SPI_FLASH_MMU_PAGE_SIZE-1);
size += (src_addr - src_page);
esp_err_t err = spi_flash_mmap(src_page, size, SPI_FLASH_MMAP_DATA, &result, &map);
if (err != ESP_OK) {
@@ -52,7 +49,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
void bootloader_munmap(const void *mapping)
{
if (mapping && map) {
if(mapping && map) {
spi_flash_munmap(map);
}
map = 0;
@@ -70,11 +67,7 @@ esp_err_t bootloader_flash_read(size_t src, void *dest, size_t size, bool allow_
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted)
{
if (write_encrypted) {
#if CONFIG_IDF_TARGET_ESP32
return spi_flash_write_encrypted(dest_addr, src, size);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
return SPI_Encrypt_Write(dest_addr, src, size);
#endif
} else {
return spi_flash_write(dest_addr, src, size);
}
@@ -93,41 +86,24 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
#else
/* Bootloader version, uses ROM functions only */
#include <soc/dport_reg.h>
#if CONFIG_IDF_TARGET_ESP32
#include <esp32/rom/spi_flash.h>
#include <esp32/rom/cache.h>
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include <esp32s2beta/rom/spi_flash.h>
#include <esp32s2beta/rom/cache.h>
#endif
static const char *TAG = "bootloader_flash";
#if CONFIG_IDF_TARGET_ESP32
/* Use first 50 blocks in MMU for bootloader_mmap,
50th block for bootloader_flash_read
*/
#define MMU_BLOCK0_VADDR SOC_DROM_LOW
#define MMU_SIZE (0x320000)
#define MMU_BLOCK50_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE)
#define FLASH_READ_VADDR MMU_BLOCK50_VADDR
#elif CONFIG_IDF_TARGET_ESP32S2BETA
/* Use first 63 blocks in MMU for bootloader_mmap,
63th block for bootloader_flash_read
*/
#define MMU_BLOCK0_VADDR SOC_DROM_LOW
#define MMU_SIZE (0x3f0000)
#define MMU_BLOCK63_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE)
#define FLASH_READ_VADDR MMU_BLOCK63_VADDR
#endif
#define MMU_BLOCK0_VADDR 0x3f400000
#define MMU_BLOCK50_VADDR 0x3f720000
#define MMU_FREE_PAGES ((MMU_BLOCK50_VADDR - MMU_BLOCK0_VADDR) / FLASH_BLOCK_SIZE)
#define MMU_FREE_PAGES (MMU_SIZE / FLASH_BLOCK_SIZE)
static bool mapped;
// Current bootloader mapping (ab)used for bootloader_read()
static uint32_t current_read_mapping = UINT32_MAX;
uint32_t bootloader_mmap_get_free_pages(void)
uint32_t bootloader_mmap_get_free_pages()
{
/**
* Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads)
@@ -142,41 +118,25 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
ESP_LOGE(TAG, "tried to bootloader_mmap twice");
return NULL; /* can't map twice */
}
if (size > MMU_SIZE) {
if (size > 0x320000) {
/* Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads) */
ESP_LOGE(TAG, "bootloader_mmap excess size %x", size);
return NULL;
}
uint32_t src_addr_aligned = src_addr & MMU_FLASH_MASK;
uint32_t count = bootloader_cache_pages_to_map(size, src_addr);
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Disable(0);
Cache_Flush(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
uint32_t autoload = Cache_Suspend_ICache();
Cache_Invalidate_ICache_All();
#endif
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d size=%x src_addr=%x src_addr_aligned=%x",
src_addr & MMU_FLASH_MASK, count, size, src_addr, src_addr_aligned );
#if CONFIG_IDF_TARGET_ESP32
src_addr & MMU_FLASH_MASK, count, size, src_addr, src_addr_aligned );
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
int e = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count, 0);
#endif
if (e != 0) {
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Enable(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
Cache_Resume_ICache(autoload);
#endif
return NULL;
}
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Enable(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
Cache_Resume_ICache(autoload);
#endif
mapped = true;
@@ -186,17 +146,10 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
void bootloader_munmap(const void *mapping)
{
if (mapped) {
#if CONFIG_IDF_TARGET_ESP32
/* Full MMU reset */
Cache_Read_Disable(0);
Cache_Flush(0);
mmu_init(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
//TODO, save the autoload value.
Cache_Suspend_ICache();
Cache_Invalidate_ICache_All();
Cache_MMU_Init();
#endif
mapped = false;
current_read_mapping = UINT32_MAX;
}
@@ -204,7 +157,7 @@ void bootloader_munmap(const void *mapping)
static esp_err_t spi_to_esp_err(esp_rom_spiflash_result_t r)
{
switch (r) {
switch(r) {
case ESP_ROM_SPIFLASH_RESULT_OK:
return ESP_OK;
case ESP_ROM_SPIFLASH_RESULT_ERR:
@@ -218,18 +171,10 @@ static esp_err_t spi_to_esp_err(esp_rom_spiflash_result_t r)
static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, size_t size)
{
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Disable(0);
Cache_Flush(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
uint32_t autoload = Cache_Suspend_ICache();
#endif
esp_rom_spiflash_result_t r = esp_rom_spiflash_read(src_addr, dest, size);
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Enable(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
Cache_Resume_ICache(autoload);
#endif
return spi_to_esp_err(r);
}
@@ -238,42 +183,28 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest
{
uint32_t *dest_words = (uint32_t *)dest;
/* Use the 51st MMU mapping to read from flash in 64KB blocks.
(MMU will transparently decrypt if encryption is enabled.)
*/
for (int word = 0; word < size / 4; word++) {
uint32_t word_src = src_addr + word * 4; /* Read this offset from flash */
uint32_t map_at = word_src & MMU_FLASH_MASK; /* Map this 64KB block from flash */
uint32_t *map_ptr;
if (map_at != current_read_mapping) {
/* Move the 64KB mmu mapping window to fit map_at */
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Disable(0);
Cache_Flush(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
uint32_t autoload = Cache_Suspend_ICache();
Cache_Invalidate_ICache_All();
#endif
ESP_LOGD(TAG, "mmu set block paddr=0x%08x (was 0x%08x)", map_at, current_read_mapping);
#if CONFIG_IDF_TARGET_ESP32
int e = cache_flash_mmu_set(0, 0, FLASH_READ_VADDR, map_at, 64, 1);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
int e = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, FLASH_READ_VADDR, map_at, 64, 1, 0);
#endif
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK50_VADDR, map_at, 64, 1);
if (e != 0) {
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Enable(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
Cache_Resume_ICache(autoload);
#endif
return ESP_FAIL;
}
current_read_mapping = map_at;
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Enable(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
Cache_Resume_ICache(autoload);
#endif
}
map_ptr = (uint32_t *)(FLASH_READ_VADDR + (word_src - map_at));
map_ptr = (uint32_t *)(MMU_BLOCK50_VADDR + (word_src - map_at));
dest_words[word] = *map_ptr;
}
return ESP_OK;
@@ -324,12 +255,7 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool
}
if (write_encrypted) {
#if CONFIG_IDF_TARGET_ESP32
return spi_to_esp_err(esp_rom_spiflash_write_encrypted(dest_addr, src, size));
#elif CONFIG_IDF_TARGET_ESP32S2BETA
// TODO: use the same ROM AP here
return spi_to_esp_err(SPI_Encrypt_Write(dest_addr, src, size));
#endif
} else {
return spi_to_esp_err(esp_rom_spiflash_write(dest_addr, src, size));
}

View File

@@ -27,12 +27,12 @@
#include "flash_qio_mode.h"
#include "bootloader_flash_config.h"
void bootloader_flash_update_id(void)
void bootloader_flash_update_id()
{
g_rom_flashchip.device_id = bootloader_read_flash_id();
}
void IRAM_ATTR bootloader_flash_cs_timing_config(void)
void IRAM_ATTR bootloader_flash_cs_timing_config()
{
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_HOLD_TIME_V, 1, SPI_HOLD_TIME_S);

View File

@@ -1,118 +0,0 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdbool.h>
#include <assert.h>
#include "string.h"
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp32s2beta/rom/gpio.h"
#include "esp32s2beta/rom/spi_flash.h"
#include "esp32s2beta/rom/efuse.h"
#include "soc/gpio_periph.h"
#include "soc/efuse_reg.h"
#include "soc/spi_reg.h"
#include "soc/spi_mem_reg.h"
#include "soc/spi_caps.h"
#include "flash_qio_mode.h"
#include "bootloader_flash_config.h"
#include "bootloader_common.h"
#define FLASH_IO_MATRIX_DUMMY_40M 0
#define FLASH_IO_MATRIX_DUMMY_80M 0
#define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3
void bootloader_flash_update_id()
{
g_rom_flashchip.device_id = bootloader_read_flash_id();
}
void IRAM_ATTR bootloader_flash_cs_timing_config()
{
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_CS_HOLD_TIME_V, 1, SPI_CS_HOLD_TIME_S);
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_CS_SETUP_TIME_V, 0, SPI_CS_SETUP_TIME_S);
SET_PERI_REG_MASK(SPI_USER_REG(1), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_CS_HOLD_TIME_V, 1, SPI_CS_HOLD_TIME_S);
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_CS_SETUP_TIME_V, 0, SPI_CS_SETUP_TIME_S);
}
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t* pfhdr)
{
uint32_t spi_clk_div = 0;
switch (pfhdr->spi_speed) {
case ESP_IMAGE_SPI_SPEED_80M:
spi_clk_div = 1;
break;
case ESP_IMAGE_SPI_SPEED_40M:
spi_clk_div = 2;
break;
case ESP_IMAGE_SPI_SPEED_26M:
spi_clk_div = 3;
break;
case ESP_IMAGE_SPI_SPEED_20M:
spi_clk_div = 4;
break;
default:
break;
}
esp_rom_spiflash_config_clk(spi_clk_div, 0);
}
void IRAM_ATTR bootloader_flash_gpio_config(const esp_image_header_t* pfhdr)
{
}
void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t* pfhdr)
{
int spi_cache_dummy = 0;
int drv = 2;
switch (pfhdr->spi_mode) {
case ESP_IMAGE_SPI_MODE_QIO:
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
break;
case ESP_IMAGE_SPI_MODE_DIO:
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //qio 3
break;
case ESP_IMAGE_SPI_MODE_QOUT:
case ESP_IMAGE_SPI_MODE_DOUT:
default:
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
break;
}
/* dummy_len_plus values defined in ROM for SPI flash configuration */
extern uint8_t g_rom_spiflash_dummy_len_plus[];
switch (pfhdr->spi_speed) {
case ESP_IMAGE_SPI_SPEED_80M:
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M;
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M;
SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY
drv = 3;
break;
case ESP_IMAGE_SPI_SPEED_40M:
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M;
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M;
SET_PERI_REG_BITS(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M,
SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY
break;
default:
break;
}
bootloader_configure_spi_pins(drv);
}

View File

@@ -1,4 +1,4 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -13,54 +13,137 @@
// limitations under the License.
#include <string.h>
#include <stdint.h>
#include "sdkconfig.h"
#include <limits.h>
#include <sys/param.h>
#include "esp_attr.h"
#include "esp_log.h"
#include "bootloader_init.h"
#include "bootloader_flash.h"
#include "bootloader_flash_config.h"
#include "bootloader_random.h"
#include "bootloader_clock.h"
#include "bootloader_common.h"
#include "esp_flash_encrypt.h"
#include "hal/timer_ll.h"
#include "esp32/rom/cache.h"
#include "esp32/rom/efuse.h"
#include "esp32/rom/ets_sys.h"
#include "esp32/rom/spi_flash.h"
#include "esp32/rom/crc.h"
#include "esp32/rom/rtc.h"
#include "esp32/rom/uart.h"
#include "esp32/rom/gpio.h"
#include "esp32/rom/secure_boot.h"
#include "soc/soc.h"
#include "soc/cpu.h"
#include "soc/rtc.h"
#include "soc/dport_reg.h"
#include "soc/gpio_periph.h"
#include "soc/efuse_periph.h"
#include "soc/rtc_periph.h"
#include "soc/timer_periph.h"
#include "soc/rtc_wdt.h"
#include "soc/spi_periph.h"
#include "sdkconfig.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "esp_flash_encrypt.h"
#include "esp_flash_partitions.h"
#include "bootloader_flash.h"
#include "bootloader_random.h"
#include "bootloader_config.h"
#include "bootloader_clock.h"
#include "bootloader_common.h"
#include "bootloader_flash_config.h"
#include "flash_qio_mode.h"
extern int _bss_start;
extern int _bss_end;
extern int _data_start;
extern int _data_end;
static const char* TAG = "boot";
static esp_err_t bootloader_main();
static void print_flash_info(const esp_image_header_t* pfhdr);
static void update_flash_config(const esp_image_header_t* pfhdr);
static void bootloader_init_flash_configure(const esp_image_header_t* pfhdr);
static void uart_console_configure(void);
static void wdt_reset_check(void);
static const char *TAG = "boot";
esp_image_header_t bootloader_image_hdr;
void bootloader_clear_bss_section(void)
esp_err_t bootloader_init()
{
cpu_configure_region_protection();
cpu_init_memctl();
/* Sanity check that static RAM is after the stack */
#ifndef NDEBUG
{
int *sp = get_sp();
assert(&_bss_start <= &_bss_end);
assert(&_data_start <= &_data_end);
assert(sp < &_bss_start);
assert(sp < &_data_start);
}
#endif
//Clear bss
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
}
esp_err_t bootloader_read_bootloader_header(void)
{
/* load bootloader image header */
if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) {
ESP_LOGE(TAG, "failed to load bootloader image header!");
/* completely reset MMU for both CPUs
(in case serial bootloader was running) */
Cache_Read_Disable(0);
Cache_Read_Disable(1);
Cache_Flush(0);
Cache_Flush(1);
mmu_init(0);
DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
mmu_init(1);
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
/* (above steps probably unnecessary for most serial bootloader
usage, all that's absolutely needed is that we unmask DROM0
cache on the following two lines - normal ROM boot exits with
DROM0 cache unmasked, but serial bootloader exits with it
masked. However can't hurt to be thorough and reset
everything.)
The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
necessary to work around a hardware bug.
*/
DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);
if(bootloader_main() != ESP_OK){
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t bootloader_check_bootloader_validity(void)
static esp_err_t bootloader_main()
{
/* read chip revision from efuse */
uint8_t revision = bootloader_common_get_chip_revision();
ESP_LOGI(TAG, "chip revision: %d", revision);
/* compare with the one set in bootloader image header */
if (bootloader_common_check_chip_validity(&bootloader_image_hdr, ESP_IMAGE_BOOTLOADER) != ESP_OK) {
bootloader_common_vddsdio_configure();
/* Read and keep flash ID, for further use. */
g_rom_flashchip.device_id = bootloader_read_flash_id();
esp_image_header_t fhdr;
if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &fhdr, sizeof(esp_image_header_t), true) != ESP_OK) {
ESP_LOGE(TAG, "failed to load bootloader header!");
return ESP_FAIL;
}
return ESP_OK;
}
bootloader_init_flash_configure(&fhdr);
#if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240)
//Check if ESP32 is rated for a CPU frequency of 160MHz only
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) &&
REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_LOW)) {
ESP_LOGE(TAG, "Chip CPU frequency rated for 160MHz. Modify CPU frequency in menuconfig");
return ESP_FAIL;
}
#endif
bootloader_clock_configure();
uart_console_configure();
wdt_reset_check();
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
ESP_LOGI(TAG, "compile time " __TIME__ );
ets_set_appcpu_boot_addr(0);
void bootloader_config_wdt(void)
{
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
ESP_LOGD(TAG, "Enabling RTCWDT(%d ms)", CONFIG_BOOTLOADER_WDT_TIME_MS);
rtc_wdt_protect_off();
@@ -71,28 +154,293 @@ void bootloader_config_wdt(void)
rtc_wdt_set_time(RTC_WDT_STAGE0, CONFIG_BOOTLOADER_WDT_TIME_MS);
rtc_wdt_enable();
rtc_wdt_protect_on();
#else /* disable watch dog */
#else
/* disable watch dog here */
rtc_wdt_disable();
#endif
timer_ll_wdt_set_protect(&TIMERG0, false);
timer_ll_wdt_flashboot_en(&TIMERG0, false);
}
REG_SET_FIELD(TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY, TIMG_WDT_WKEY_VALUE);
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
const uint32_t spiconfig = ets_efuse_get_spiconfig();
if(spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
ESP_LOGE(TAG, "SPI flash pins are overridden. \"Enable SPI flash ROM driver patched functions\" must be enabled in menuconfig");
return ESP_FAIL;
}
#endif
esp_rom_spiflash_unlock();
void bootloader_enable_random(void)
{
ESP_LOGI(TAG, "Enabling RNG early entropy source...");
bootloader_random_enable();
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT
bootloader_enable_qio_mode();
#endif
print_flash_info(&fhdr);
update_flash_config(&fhdr);
return ESP_OK;
}
void bootloader_print_banner(void)
static void update_flash_config(const esp_image_header_t* pfhdr)
{
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
ESP_LOGI(TAG, "compile time " __TIME__);
uint32_t size;
switch(pfhdr->spi_size) {
case ESP_IMAGE_FLASH_SIZE_1MB:
size = 1;
break;
case ESP_IMAGE_FLASH_SIZE_2MB:
size = 2;
break;
case ESP_IMAGE_FLASH_SIZE_4MB:
size = 4;
break;
case ESP_IMAGE_FLASH_SIZE_8MB:
size = 8;
break;
case ESP_IMAGE_FLASH_SIZE_16MB:
size = 16;
break;
default:
size = 2;
}
Cache_Read_Disable( 0 );
// Set flash chip size
esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
// TODO: set mode
// TODO: set frequency
Cache_Flush(0);
Cache_Read_Enable( 0 );
}
static void print_flash_info(const esp_image_header_t* phdr)
{
#if (BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_NOTICE)
ESP_LOGD(TAG, "magic %02x", phdr->magic );
ESP_LOGD(TAG, "segments %02x", phdr->segment_count );
ESP_LOGD(TAG, "spi_mode %02x", phdr->spi_mode );
ESP_LOGD(TAG, "spi_speed %02x", phdr->spi_speed );
ESP_LOGD(TAG, "spi_size %02x", phdr->spi_size );
const char* str;
switch ( phdr->spi_speed ) {
case ESP_IMAGE_SPI_SPEED_40M:
str = "40MHz";
break;
case ESP_IMAGE_SPI_SPEED_26M:
str = "26.7MHz";
break;
case ESP_IMAGE_SPI_SPEED_20M:
str = "20MHz";
break;
case ESP_IMAGE_SPI_SPEED_80M:
str = "80MHz";
break;
default:
str = "20MHz";
break;
}
ESP_LOGI(TAG, "SPI Speed : %s", str );
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
if (spi_ctrl & SPI_FREAD_QIO) {
str = "QIO";
} else if (spi_ctrl & SPI_FREAD_QUAD) {
str = "QOUT";
} else if (spi_ctrl & SPI_FREAD_DIO) {
str = "DIO";
} else if (spi_ctrl & SPI_FREAD_DUAL) {
str = "DOUT";
} else if (spi_ctrl & SPI_FASTRD_MODE) {
str = "FAST READ";
} else {
str = "SLOW READ";
}
ESP_LOGI(TAG, "SPI Mode : %s", str );
switch ( phdr->spi_size ) {
case ESP_IMAGE_FLASH_SIZE_1MB:
str = "1MB";
break;
case ESP_IMAGE_FLASH_SIZE_2MB:
str = "2MB";
break;
case ESP_IMAGE_FLASH_SIZE_4MB:
str = "4MB";
break;
case ESP_IMAGE_FLASH_SIZE_8MB:
str = "8MB";
break;
case ESP_IMAGE_FLASH_SIZE_16MB:
str = "16MB";
break;
default:
str = "2MB";
break;
}
ESP_LOGI(TAG, "SPI Flash Size : %s", str );
#endif
}
/*
* Bootloader reads SPI configuration from bin header, so that
* the burning configuration can be different with compiling configuration.
*/
static void IRAM_ATTR bootloader_init_flash_configure(const esp_image_header_t* pfhdr)
{
bootloader_flash_gpio_config(pfhdr);
bootloader_flash_dummy_config(pfhdr);
bootloader_flash_cs_timing_config();
}
static void uart_console_configure(void)
{
#if CONFIG_ESP_CONSOLE_UART_NONE
ets_install_putc1(NULL);
ets_install_putc2(NULL);
#else // CONFIG_ESP_CONSOLE_UART_NONE
const int uart_num = CONFIG_ESP_CONSOLE_UART_NUM;
uartAttach();
ets_install_uart_printf();
// Wait for UART FIFO to be empty.
uart_tx_wait_idle(0);
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
// Some constants to make the following code less upper-case
const int uart_tx_gpio = CONFIG_ESP_CONSOLE_UART_TX_GPIO;
const int uart_rx_gpio = CONFIG_ESP_CONSOLE_UART_RX_GPIO;
// Switch to the new UART (this just changes UART number used for
// ets_printf in ROM code).
uart_tx_switch(uart_num);
// If console is attached to UART1 or if non-default pins are used,
// need to reconfigure pins using GPIO matrix
if (uart_num != 0 || uart_tx_gpio != 1 || uart_rx_gpio != 3) {
// Change pin mode for GPIO1/3 from UART to GPIO
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_GPIO1);
// Route GPIO signals to/from pins
// (arrays should be optimized away by the compiler)
const uint32_t tx_idx_list[3] = { U0TXD_OUT_IDX, U1TXD_OUT_IDX, U2TXD_OUT_IDX };
const uint32_t rx_idx_list[3] = { U0RXD_IN_IDX, U1RXD_IN_IDX, U2RXD_IN_IDX };
const uint32_t uart_reset[3] = { DPORT_UART_RST, DPORT_UART1_RST, DPORT_UART2_RST };
const uint32_t tx_idx = tx_idx_list[uart_num];
const uint32_t rx_idx = rx_idx_list[uart_num];
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
gpio_pad_pullup(uart_rx_gpio);
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
}
#endif // CONFIG_ESP_CONSOLE_UART_CUSTOM
// Set configured UART console baud rate
const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
#endif // CONFIG_ESP_CONSOLE_UART_NONE
}
static void wdt_reset_cpu0_info_enable(void)
{
//We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1.
DPORT_REG_SET_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_PDEBUG_ENABLE | DPORT_PRO_CPU_RECORD_ENABLE);
DPORT_REG_CLR_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_RECORD_ENABLE);
}
static void wdt_reset_info_dump(int cpu)
{
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
const char *cpu_name = cpu ? "APP" : "PRO";
if (cpu == 0) {
stat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_STATUS_REG);
pid = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PID_REG);
inst = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGINST_REG);
dstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGSTATUS_REG);
data = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGDATA_REG);
pc = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGPC_REG);
lsstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0STAT_REG);
lsaddr = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0ADDR_REG);
lsdata = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0DATA_REG);
} else {
stat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_STATUS_REG);
pid = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PID_REG);
inst = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGINST_REG);
dstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGSTATUS_REG);
data = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGDATA_REG);
pc = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGPC_REG);
lsstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0STAT_REG);
lsaddr = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0ADDR_REG);
lsdata = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0DATA_REG);
}
if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 &&
DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) {
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x (waiti mode)", cpu_name, pc);
} else {
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x", cpu_name, pc);
}
ESP_LOGD(TAG, "WDT reset info: %s CPU STATUS 0x%08x", cpu_name, stat);
ESP_LOGD(TAG, "WDT reset info: %s CPU PID 0x%08x", cpu_name, pid);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST 0x%08x", cpu_name, inst);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS 0x%08x", cpu_name, dstat);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA 0x%08x", cpu_name, data);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC 0x%08x", cpu_name, pc);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08x", cpu_name, lsstat);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08x", cpu_name, lsaddr);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08x", cpu_name, lsdata);
}
static void wdt_reset_check(void)
{
int wdt_rst = 0;
RESET_REASON rst_reas[2];
rst_reas[0] = rtc_get_reset_reason(0);
rst_reas[1] = rtc_get_reset_reason(1);
if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET ||
rst_reas[0] == TGWDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
}
if (rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET || rst_reas[1] == TG1WDT_SYS_RESET ||
rst_reas[1] == TGWDT_CPU_RESET || rst_reas[1] == RTCWDT_CPU_RESET) {
ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
wdt_rst = 1;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
wdt_reset_info_dump(1);
}
wdt_reset_cpu0_info_enable();
}
void __assert_func(const char *file, int line, const char *func, const char *expr)
{
ESP_LOGE(TAG, "Assert failed in %s, %s:%d (%s)", func, file, line, expr);
while (1) {
}
while(1) {}
}
void abort()
{
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT
ets_printf("abort() was called at PC 0x%08x\r\n", (intptr_t)__builtin_return_address(0) - 3);
#endif
if (esp_cpu_in_ocd_debug_mode()) {
__asm__ ("break 0,0");
}
while(1) {}
}

View File

@@ -23,7 +23,6 @@
#ifndef BOOTLOADER_BUILD
#include "esp_system.h"
#include "driver/periph_ctrl.h"
void bootloader_fill_random(void *buffer, size_t length)
{
@@ -35,9 +34,7 @@ void bootloader_fill_random(void *buffer, size_t length)
{
uint8_t *buffer_bytes = (uint8_t *)buffer;
uint32_t random;
#if CONFIG_IDF_TARGET_ESP32
uint32_t start, now;
#endif
assert(buffer != NULL);
@@ -50,18 +47,14 @@ void bootloader_fill_random(void *buffer, size_t length)
as-is, we repeatedly read the RNG register and XOR all
values.
*/
#if CONFIG_IDF_TARGET_ESP32
random = REG_READ(WDEV_RND_REG);
RSR(CCOUNT, start);
do {
random ^= REG_READ(WDEV_RND_REG);
RSR(CCOUNT, now);
} while (now - start < 80 * 32 * 2); /* extra factor of 2 is precautionary */
#elif CONFIG_IDF_TARGET_ESP32S2BETA
// ToDo: Get random from register
random = 12345678;
#endif
} while(now - start < 80*32*2); /* extra factor of 2 is precautionary */
}
buffer_bytes[i] = random >> ((i % 4) * 8);
}
}
@@ -72,11 +65,7 @@ void bootloader_random_enable(void)
/* Ensure the hardware RNG is enabled following a soft reset. This should always be the case already (this clock is
never disabled while the CPU is running), this is a "belts and braces" type check.
*/
#ifdef BOOTLOADER_BUILD
DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_RNG_EN);
#else
periph_module_enable(PERIPH_RNG_MODULE);
#endif // BOOTLOADER_BUILD
/* Enable SAR ADC in test mode to feed ADC readings of the 1.1V
reference via I2S into the RNG entropy input.
@@ -86,23 +75,11 @@ void bootloader_random_enable(void)
*/
SET_PERI_REG_BITS(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_DTEST_RTC, 2, RTC_CNTL_DTEST_RTC_S);
SET_PERI_REG_MASK(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC);
#if CONFIG_IDF_TARGET_ESP32
SET_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST);
#ifdef BOOTLOADER_BUILD
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
#else
periph_module_enable(PERIPH_I2S0_MODULE);
#endif // BOOTLOADER_BUILD
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP);
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_START_TOP);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL1_REG, SENS_SAR2_EN_TEST);
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_CTRL_REG, RTC_CNTL_ULP_CP_FORCE_START_TOP);
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_CTRL_REG, RTC_CNTL_ULP_CP_START_TOP);
#endif
// Test pattern configuration byte 0xAD:
//--[7:4] channel_sel: 10-->en_test
//--[3:2] bit_width : 3-->12bit
@@ -111,31 +88,22 @@ void bootloader_random_enable(void)
WRITE_PERI_REG(SYSCON_SARADC_SAR2_PATT_TAB2_REG, 0xADADADAD);
WRITE_PERI_REG(SYSCON_SARADC_SAR2_PATT_TAB3_REG, 0xADADADAD);
WRITE_PERI_REG(SYSCON_SARADC_SAR2_PATT_TAB4_REG, 0xADADADAD);
#if CONFIG_IDF_TARGET_ESP32
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S);
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE);
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
SET_PERI_REG_BITS(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S);
SET_PERI_REG_MASK(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE);
#endif
#if CONFIG_IDF_TARGET_ESP32
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX);
#endif
SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_CLK_DIV, 4, SYSCON_SARADC_SAR_CLK_DIV_S);
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_RSTB_WAIT, 8, SYSCON_SARADC_RSTB_WAIT_S); /* was 1 */
#if CONFIG_IDF_TARGET_ESP32
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 10, SYSCON_SARADC_START_WAIT_S);
#endif
SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_WORK_MODE, 0, SYSCON_SARADC_WORK_MODE_S);
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL);
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_SAR_SEL);
SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 20, I2S_RX_BCK_DIV_NUM_S);
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_TO_I2S);
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG,SYSCON_SARADC_DATA_TO_I2S);
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_CAMERA_EN);
SET_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_LCD_EN);
@@ -146,54 +114,32 @@ void bootloader_random_enable(void)
void bootloader_random_disable(void)
{
/* Disable i2s clock */
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
/* Reset some i2s configuration (possibly redundant as we reset entire
I2S peripheral further down). */
CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_START);
SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET);
CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET);
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_CAMERA_EN);
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_LCD_EN);
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_DATA_ENABLE_TEST_EN);
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_DATA_ENABLE);
/* Disable i2s clock */
#ifdef BOOTLOADER_BUILD
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
#else
periph_module_disable(PERIPH_I2S0_MODULE);
#endif // BOOTLOADER_BUILD
CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_START);
/* Restore SYSCON mode registers */
#if CONFIG_IDF_TARGET_ESP32
CLEAR_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE);
CLEAR_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE);
#endif
#if CONFIG_IDF_TARGET_ESP32
/* Restore SAR ADC mode */
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST);
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX
| SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL1_REG, SENS_SAR2_EN_TEST);
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S);
SET_PERI_REG_BITS(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S);
#endif
#if CONFIG_IDF_TARGET_ESP32
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 8, SYSCON_SARADC_START_WAIT_S);
#endif
/* Reset i2s peripheral */
#ifdef BOOTLOADER_BUILD
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
#else
periph_module_reset(PERIPH_I2S0_MODULE);
#endif
/* Disable pull supply voltage to SAR ADC */
CLEAR_PERI_REG_MASK(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC);

View File

@@ -19,7 +19,6 @@
#include "esp_attr.h"
#include "esp_log.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/cache.h"
#include "esp32/rom/efuse.h"
#include "esp32/rom/ets_sys.h"
@@ -29,19 +28,6 @@
#include "esp32/rom/uart.h"
#include "esp32/rom/gpio.h"
#include "esp32/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/cache.h"
#include "esp32s2beta/rom/efuse.h"
#include "esp32s2beta/rom/ets_sys.h"
#include "esp32s2beta/rom/spi_flash.h"
#include "esp32s2beta/rom/crc.h"
#include "esp32s2beta/rom/rtc.h"
#include "esp32s2beta/rom/uart.h"
#include "esp32s2beta/rom/gpio.h"
#include "esp32s2beta/rom/secure_boot.h"
#else
#error "Unsupported IDF_TARGET"
#endif
#include "soc/soc.h"
#include "soc/cpu.h"
@@ -65,22 +51,22 @@
#include "bootloader_sha.h"
#include "esp_efuse.h"
static const char *TAG = "boot";
static const char* TAG = "boot";
/* Reduce literal size for some generic string literals */
#define MAP_ERR_MSG "Image contains multiple %s segments. Only the last one will be mapped."
static bool ota_has_initial_contents;
static void load_image(const esp_image_metadata_t *image_data);
static void load_image(const esp_image_metadata_t* image_data);
static void unpack_load_app(const esp_image_metadata_t *data);
static void set_cache_and_start_app(uint32_t drom_addr,
uint32_t drom_load_addr,
uint32_t drom_size,
uint32_t irom_addr,
uint32_t irom_load_addr,
uint32_t irom_size,
uint32_t entry_addr);
uint32_t drom_load_addr,
uint32_t drom_size,
uint32_t irom_addr,
uint32_t irom_load_addr,
uint32_t irom_size,
uint32_t entry_addr);
// Read ota_info partition and fill array from two otadata structures.
static esp_err_t read_otadata(const esp_partition_pos_t *ota_info, esp_ota_select_entry_t *two_otadata)
@@ -110,7 +96,7 @@ static esp_err_t read_otadata(const esp_partition_pos_t *ota_info, esp_ota_selec
return ESP_OK;
}
bool bootloader_utility_load_partition_table(bootloader_state_t *bs)
bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
{
const esp_partition_info_t *partitions;
const char *partition_usage;
@@ -133,16 +119,16 @@ bool bootloader_utility_load_partition_table(bootloader_state_t *bs)
ESP_LOGI(TAG, "Partition Table:");
ESP_LOGI(TAG, "## Label Usage Type ST Offset Length");
for (int i = 0; i < num_partitions; i++) {
for(int i = 0; i < num_partitions; i++) {
const esp_partition_info_t *partition = &partitions[i];
ESP_LOGD(TAG, "load partition table entry 0x%x", (intptr_t)partition);
ESP_LOGD(TAG, "type=%x subtype=%x", partition->type, partition->subtype);
partition_usage = "unknown";
/* valid partition table */
switch (partition->type) {
switch(partition->type) {
case PART_TYPE_APP: /* app partition */
switch (partition->subtype) {
switch(partition->subtype) {
case PART_SUBTYPE_FACTORY: /* factory binary */
bs->factory = partition->pos;
partition_usage = "factory app";
@@ -157,14 +143,15 @@ bool bootloader_utility_load_partition_table(bootloader_state_t *bs)
bs->ota[partition->subtype & PART_SUBTYPE_OTA_MASK] = partition->pos;
++bs->app_count;
partition_usage = "OTA app";
} else {
}
else {
partition_usage = "Unknown app";
}
break;
}
break; /* PART_TYPE_APP */
case PART_TYPE_DATA: /* data partition */
switch (partition->subtype) {
switch(partition->subtype) {
case PART_SUBTYPE_DATA_OTA: /* ota data */
bs->ota_info = partition->pos;
partition_usage = "OTA data";
@@ -201,7 +188,7 @@ bool bootloader_utility_load_partition_table(bootloader_state_t *bs)
bootloader_munmap(partitions);
ESP_LOGI(TAG, "End of partition table");
ESP_LOGI(TAG,"End of partition table");
return true;
}
@@ -227,7 +214,7 @@ static esp_partition_pos_t index_to_partition(const bootloader_state_t *bs, int
static void log_invalid_app_partition(int index)
{
const char *not_bootable = " is not bootable"; /* save a few string literal bytes */
switch (index) {
switch(index) {
case FACTORY_INDEX:
ESP_LOGE(TAG, "Factory app partition%s", not_bootable);
break;
@@ -330,8 +317,8 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
#ifndef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
if ((bootloader_common_ota_select_invalid(&otadata[0]) &&
bootloader_common_ota_select_invalid(&otadata[1])) ||
bs->app_count == 0) {
bootloader_common_ota_select_invalid(&otadata[1])) ||
bs->app_count == 0) {
ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF) or partition table does not have bootable ota_apps (app_count=%d)", bs->app_count);
if (bs->factory.offset != 0) {
ESP_LOGI(TAG, "Defaulting to factory image");
@@ -341,7 +328,7 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
boot_index = 0;
// Try to boot from ota_0.
if ((otadata[0].ota_seq == UINT32_MAX || otadata[0].crc != bootloader_common_ota_select_crc(&otadata[0])) &&
(otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) {
(otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) {
// Factory is not found and both otadata are initial(0xFFFFFFFF) or incorrect crc.
// will set correct ota_seq.
ota_has_initial_contents = true;
@@ -354,7 +341,7 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
ESP_LOGI(TAG, "Secure version (from eFuse) = %d", esp_efuse_read_secure_version());
// When CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK is enabled factory partition should not be in partition table, only two ota_app are there.
if ((otadata[0].ota_seq == UINT32_MAX || otadata[0].crc != bootloader_common_ota_select_crc(&otadata[0])) &&
(otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) {
(otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) {
ESP_LOGI(TAG, "otadata[0..1] in initial state");
// both otadata are initial(0xFFFFFFFF) or incorrect crc.
// will set correct ota_seq.
@@ -429,31 +416,8 @@ static void set_actual_ota_seq(const bootloader_state_t *bs, int index)
update_anti_rollback(&bs->ota[index]);
#endif
}
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
esp_partition_pos_t partition = index_to_partition(bs, index);
bootloader_common_update_rtc_retain_mem(&partition, true);
#endif
}
#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
void bootloader_utility_load_boot_image_from_deep_sleep(void)
{
if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
esp_partition_pos_t* partition = bootloader_common_get_rtc_retain_mem_partition();
if (partition != NULL) {
esp_image_metadata_t image_data;
if (bootloader_load_image_no_verify(partition, &image_data) == ESP_OK) {
ESP_LOGI(TAG, "Fast booting app from partition at offset 0x%x", partition->offset);
bootloader_common_update_rtc_retain_mem(NULL, true);
load_image(&image_data);
}
}
ESP_LOGE(TAG, "Fast booting is not successful");
ESP_LOGI(TAG, "Try to load an app as usual with all validations");
}
}
#endif
#define TRY_LOG_FORMAT "Trying partition index %d offs 0x%x size 0x%x"
void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index)
@@ -462,7 +426,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
esp_partition_pos_t part;
esp_image_metadata_t image_data;
if (start_index == TEST_APP_INDEX) {
if(start_index == TEST_APP_INDEX) {
if (try_load_partition(&bs->test, &image_data)) {
load_image(&image_data);
} else {
@@ -472,7 +436,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
}
/* work backwards from start_index, down to the factory app */
for (index = start_index; index >= FACTORY_INDEX; index--) {
for(index = start_index; index >= FACTORY_INDEX; index--) {
part = index_to_partition(bs, index);
if (part.size == 0) {
continue;
@@ -486,7 +450,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
}
/* failing that work forwards from start_index, try valid OTA slots */
for (index = start_index + 1; index < bs->app_count; index++) {
for(index = start_index + 1; index < bs->app_count; index++) {
part = index_to_partition(bs, index);
if (part.size == 0) {
continue;
@@ -510,7 +474,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
}
// Copy loaded segments to RAM, set up caches for mapped segments, and start application.
static void load_image(const esp_image_metadata_t *image_data)
static void load_image(const esp_image_metadata_t* image_data)
{
/**
* Rough steps for a first boot, when encryption and secure boot are both disabled:
@@ -607,21 +571,18 @@ static void load_image(const esp_image_metadata_t *image_data)
so issue a system reset to ensure flash encryption
cache resets properly */
ESP_LOGI(TAG, "Resetting with flash encryption enabled...");
uart_tx_wait_idle(0);
bootloader_reset();
}
#endif
ESP_LOGI(TAG, "Disabling RNG early entropy source...");
#if !CONFIG_IDF_ENV_FPGA
bootloader_random_disable();
#endif
// copy loaded segments to RAM, set up caches for mapped segments, and start application
unpack_load_app(image_data);
}
static void unpack_load_app(const esp_image_metadata_t *data)
static void unpack_load_app(const esp_image_metadata_t* data)
{
uint32_t drom_addr = 0;
uint32_t drom_load_addr = 0;
@@ -657,12 +618,12 @@ static void unpack_load_app(const esp_image_metadata_t *data)
ESP_LOGD(TAG, "calling set_cache_and_start_app");
set_cache_and_start_app(drom_addr,
drom_load_addr,
drom_size,
irom_addr,
irom_load_addr,
irom_size,
data->image.entry_addr);
drom_load_addr,
drom_size,
irom_addr,
irom_load_addr,
irom_size,
data->image.entry_addr);
}
static void set_cache_and_start_app(
@@ -676,13 +637,8 @@ static void set_cache_and_start_app(
{
int rc;
ESP_LOGD(TAG, "configure drom and irom and start");
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Disable(0);
Cache_Flush(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
uint32_t autoload = Cache_Suspend_ICache();
Cache_Invalidate_ICache_All();
#endif
Cache_Read_Disable( 0 );
Cache_Flush( 0 );
/* Clear the MMU entries that are already set up,
so the new app only has the mappings it creates.
@@ -694,66 +650,33 @@ static void set_cache_and_start_app(
uint32_t drom_load_addr_aligned = drom_load_addr & MMU_FLASH_MASK;
uint32_t drom_page_count = bootloader_cache_pages_to_map(drom_size, drom_load_addr);
ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d",
drom_addr & MMU_FLASH_MASK, drom_load_addr_aligned, drom_size, drom_page_count);
#if CONFIG_IDF_TARGET_ESP32
drom_addr & MMU_FLASH_MASK, drom_load_addr_aligned, drom_size, drom_page_count);
rc = cache_flash_mmu_set(0, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000,
64, drom_page_count, 0);
#endif
ESP_LOGV(TAG, "rc=%d", rc);
#if CONFIG_IDF_TARGET_ESP32
rc = cache_flash_mmu_set(1, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
ESP_LOGV(TAG, "rc=%d", rc);
#endif
uint32_t irom_load_addr_aligned = irom_load_addr & MMU_FLASH_MASK;
uint32_t irom_page_count = bootloader_cache_pages_to_map(irom_size, irom_load_addr);
ESP_LOGV(TAG, "i mmu set paddr=%08x vaddr=%08x size=%d n=%d",
irom_addr & MMU_FLASH_MASK, irom_load_addr_aligned, irom_size, irom_page_count);
#if CONFIG_IDF_TARGET_ESP32
irom_addr & MMU_FLASH_MASK, irom_load_addr_aligned, irom_size, irom_page_count);
rc = cache_flash_mmu_set(0, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
ESP_LOGV(TAG, "rc=%d", rc);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
uint32_t iram1_used = 0, irom0_used = 0;
if (irom_load_addr + irom_size > IRAM1_ADDRESS_LOW) {
iram1_used = 1;
}
if (irom_load_addr + irom_size > IROM0_ADDRESS_LOW) {
irom0_used = 1;
}
if (iram1_used || irom0_used) {
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, IRAM0_ADDRESS_LOW, 0, 64, 64, 1);
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, IRAM1_ADDRESS_LOW, 0, 64, 64, 1);
REG_SET_BIT(DPORT_CACHE_SOURCE_1_REG, DPORT_PRO_CACHE_I_SOURCE_PRO_IRAM1);
REG_CLR_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_IRAM1);
if (irom0_used) {
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, IROM0_ADDRESS_LOW, 0, 64, 64, 1);
REG_SET_BIT(DPORT_CACHE_SOURCE_1_REG, DPORT_PRO_CACHE_I_SOURCE_PRO_IROM0);
REG_CLR_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_IROM0);
}
}
rc = Cache_Ibus_MMU_Set(DPORT_MMU_ACCESS_FLASH, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count, 0);
#endif
ESP_LOGV(TAG, "rc=%d", rc);
#if CONFIG_IDF_TARGET_ESP32
rc = cache_flash_mmu_set(1, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
ESP_LOGV(TAG, "rc=%d", rc);
DPORT_REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG,
(DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) |
(DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 |
DPORT_PRO_CACHE_MASK_DRAM1 );
(DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) |
(DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 |
DPORT_PRO_CACHE_MASK_DRAM1 );
DPORT_REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG,
(DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) |
(DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 |
DPORT_APP_CACHE_MASK_DRAM1 );
#elif CONFIG_IDF_TARGET_ESP32S2BETA
DPORT_REG_CLR_BIT( DPORT_PRO_ICACHE_CTRL1_REG, (DPORT_PRO_ICACHE_MASK_IRAM0) | (DPORT_PRO_ICACHE_MASK_IRAM1 & 0) | (DPORT_PRO_ICACHE_MASK_IROM0 & 0) | DPORT_PRO_ICACHE_MASK_DROM0 );
#endif
#if CONFIG_IDF_TARGET_ESP32
Cache_Read_Enable(0);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
Cache_Resume_ICache(autoload);
#endif
(DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) |
(DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 |
DPORT_APP_CACHE_MASK_DRAM1 );
Cache_Read_Enable( 0 );
// Application will need to do Cache_Flush(1) and Cache_Read_Enable(1)
ESP_LOGD(TAG, "start: 0x%08x", entry_addr);
@@ -765,6 +688,7 @@ static void set_cache_and_start_app(
(*entry)();
}
void bootloader_reset(void)
{
#ifdef BOOTLOADER_BUILD
@@ -795,24 +719,3 @@ esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_he
}
return ESP_OK;
}
void bootloader_debug_buffer(const void *buffer, size_t length, const char *label)
{
#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
assert(length <= 128); // Avoid unbounded VLA size
const uint8_t *bytes = (const uint8_t *)buffer;
char hexbuf[length * 2 + 1];
hexbuf[length * 2] = 0;
for (int i = 0; i < length; i++) {
for (int shift = 0; shift < 2; shift++) {
uint8_t nibble = (bytes[i] >> (shift ? 0 : 4)) & 0x0F;
if (nibble < 10) {
hexbuf[i * 2 + shift] = '0' + nibble;
} else {
hexbuf[i * 2 + shift] = 'a' + nibble - 10;
}
}
}
ESP_LOGD(TAG, "%s: %s", label, hexbuf);
#endif
}

View File

@@ -1,480 +0,0 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "flash_qio_mode.h"
#include "bootloader_init.h"
#include "bootloader_clock.h"
#include "bootloader_common.h"
#include "bootloader_flash_config.h"
#include "soc/cpu.h"
#include "soc/dport_reg.h"
#include "soc/efuse_reg.h"
#include "soc/gpio_sig_map.h"
#include "soc/io_mux_reg.h"
#include "soc/rtc.h"
#include "soc/spi_periph.h"
#include "esp32/rom/cache.h"
#include "esp32/rom/efuse.h"
#include "esp32/rom/ets_sys.h"
#include "esp32/rom/gpio.h"
#include "esp32/rom/spi_flash.h"
#include "esp32/rom/rtc.h"
#include "esp32/rom/uart.h"
static const char *TAG = "boot.esp32";
#define FLASH_CLK_IO SPI_CLK_GPIO_NUM
#define FLASH_CS_IO SPI_CS0_GPIO_NUM
#define FLASH_SPIQ_IO SPI_Q_GPIO_NUM
#define FLASH_SPID_IO SPI_D_GPIO_NUM
#define FLASH_SPIWP_IO SPI_WP_GPIO_NUM
#define FLASH_SPIHD_IO SPI_HD_GPIO_NUM
void bootloader_configure_spi_pins(int drv)
{
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
uint32_t pkg_ver = chip_ver & 0x7;
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
// For ESP32D2WD the SPI pins are already configured
// flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
// For ESP32PICOD2 the SPI pins are already configured
// flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
// For ESP32PICOD4 the SPI pins are already configured
// flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
} else {
const uint32_t spiconfig = ets_efuse_get_spiconfig();
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0);
gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
//select pin function gpio
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
// flash clock signal should come from IO MUX.
// set drive ability for clock
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32 || CONFIG_SPIRAM_TYPE_ESPPSRAM64
uint32_t flash_id = g_rom_flashchip.device_id;
if (flash_id == FLASH_ID_GD25LQ32C) {
// Set drive ability for 1.8v flash in 80Mhz.
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
}
#endif
}
}
}
static void bootloader_reset_mmu(void)
{
/* completely reset MMU in case serial bootloader was running */
Cache_Read_Disable(0);
#if !CONFIG_FREERTOS_UNICORE
Cache_Read_Disable(1);
#endif
Cache_Flush(0);
#if !CONFIG_FREERTOS_UNICORE
Cache_Flush(1);
#endif
mmu_init(0);
#if !CONFIG_FREERTOS_UNICORE
/* The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
necessary to work around a hardware bug. */
DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
mmu_init(1);
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
#endif
/* normal ROM boot exits with DROM0 cache unmasked,
but serial bootloader exits with it masked. */
DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
#if !CONFIG_FREERTOS_UNICORE
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);
#endif
}
static esp_err_t bootloader_check_rated_cpu_clock(void)
{
int rated_freq = bootloader_clock_get_rated_freq_mhz();
if (rated_freq < CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) {
ESP_LOGE(TAG, "Chip CPU frequency rated for %dMHz, configured for %dMHz. Modify CPU frequency in menuconfig",
rated_freq, CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ);
return ESP_FAIL;
}
return ESP_OK;
}
static void update_flash_config(const esp_image_header_t *bootloader_hdr)
{
uint32_t size;
switch (bootloader_hdr->spi_size) {
case ESP_IMAGE_FLASH_SIZE_1MB:
size = 1;
break;
case ESP_IMAGE_FLASH_SIZE_2MB:
size = 2;
break;
case ESP_IMAGE_FLASH_SIZE_4MB:
size = 4;
break;
case ESP_IMAGE_FLASH_SIZE_8MB:
size = 8;
break;
case ESP_IMAGE_FLASH_SIZE_16MB:
size = 16;
break;
default:
size = 2;
}
Cache_Read_Disable(0);
// Set flash chip size
esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
// TODO: set mode
// TODO: set frequency
Cache_Flush(0);
Cache_Read_Enable(0);
}
static void print_flash_info(const esp_image_header_t *bootloader_hdr)
{
ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic);
ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count);
ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode);
ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed);
ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size);
const char *str;
switch (bootloader_hdr->spi_speed) {
case ESP_IMAGE_SPI_SPEED_40M:
str = "40MHz";
break;
case ESP_IMAGE_SPI_SPEED_26M:
str = "26.7MHz";
break;
case ESP_IMAGE_SPI_SPEED_20M:
str = "20MHz";
break;
case ESP_IMAGE_SPI_SPEED_80M:
str = "80MHz";
break;
default:
str = "20MHz";
break;
}
ESP_LOGI(TAG, "SPI Speed : %s", str);
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
if (spi_ctrl & SPI_FREAD_QIO) {
str = "QIO";
} else if (spi_ctrl & SPI_FREAD_QUAD) {
str = "QOUT";
} else if (spi_ctrl & SPI_FREAD_DIO) {
str = "DIO";
} else if (spi_ctrl & SPI_FREAD_DUAL) {
str = "DOUT";
} else if (spi_ctrl & SPI_FASTRD_MODE) {
str = "FAST READ";
} else {
str = "SLOW READ";
}
ESP_LOGI(TAG, "SPI Mode : %s", str);
switch (bootloader_hdr->spi_size) {
case ESP_IMAGE_FLASH_SIZE_1MB:
str = "1MB";
break;
case ESP_IMAGE_FLASH_SIZE_2MB:
str = "2MB";
break;
case ESP_IMAGE_FLASH_SIZE_4MB:
str = "4MB";
break;
case ESP_IMAGE_FLASH_SIZE_8MB:
str = "8MB";
break;
case ESP_IMAGE_FLASH_SIZE_16MB:
str = "16MB";
break;
default:
str = "2MB";
break;
}
ESP_LOGI(TAG, "SPI Flash Size : %s", str);
}
static void IRAM_ATTR bootloader_init_flash_configure(void)
{
bootloader_flash_gpio_config(&bootloader_image_hdr);
bootloader_flash_dummy_config(&bootloader_image_hdr);
bootloader_flash_cs_timing_config();
}
static esp_err_t bootloader_init_spi_flash(void)
{
bootloader_init_flash_configure();
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
const uint32_t spiconfig = ets_efuse_get_spiconfig();
if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
return ESP_FAIL;
}
#endif
esp_rom_spiflash_unlock();
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT
bootloader_enable_qio_mode();
#endif
print_flash_info(&bootloader_image_hdr);
update_flash_config(&bootloader_image_hdr);
return ESP_OK;
}
static void bootloader_init_uart_console(void)
{
#if CONFIG_ESP_CONSOLE_UART_NONE
ets_install_putc1(NULL);
ets_install_putc2(NULL);
#else // CONFIG_ESP_CONSOLE_UART_NONE
const int uart_num = CONFIG_ESP_CONSOLE_UART_NUM;
uartAttach();
ets_install_uart_printf();
// Wait for UART FIFO to be empty.
uart_tx_wait_idle(0);
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
// Some constants to make the following code less upper-case
const int uart_tx_gpio = CONFIG_ESP_CONSOLE_UART_TX_GPIO;
const int uart_rx_gpio = CONFIG_ESP_CONSOLE_UART_RX_GPIO;
// Switch to the new UART (this just changes UART number used for
// ets_printf in ROM code).
uart_tx_switch(uart_num);
// If console is attached to UART1 or if non-default pins are used,
// need to reconfigure pins using GPIO matrix
if (uart_num != 0 || uart_tx_gpio != 1 || uart_rx_gpio != 3) {
// Change pin mode for GPIO1/3 from UART to GPIO
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_GPIO1);
// Route GPIO signals to/from pins
// (arrays should be optimized away by the compiler)
const uint32_t tx_idx_list[3] = {U0TXD_OUT_IDX, U1TXD_OUT_IDX, U2TXD_OUT_IDX};
const uint32_t rx_idx_list[3] = {U0RXD_IN_IDX, U1RXD_IN_IDX, U2RXD_IN_IDX};
const uint32_t uart_reset[3] = {DPORT_UART_RST, DPORT_UART1_RST, DPORT_UART2_RST};
const uint32_t tx_idx = tx_idx_list[uart_num];
const uint32_t rx_idx = rx_idx_list[uart_num];
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
gpio_pad_pullup(uart_rx_gpio);
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
}
#endif // CONFIG_ESP_CONSOLE_UART_CUSTOM
// Set configured UART console baud rate
const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
#endif // CONFIG_ESP_CONSOLE_UART_NONE
}
static void wdt_reset_cpu0_info_enable(void)
{
//We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1.
DPORT_REG_SET_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_PDEBUG_ENABLE | DPORT_PRO_CPU_RECORD_ENABLE);
DPORT_REG_CLR_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_RECORD_ENABLE);
}
static void wdt_reset_info_dump(int cpu)
{
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
const char *cpu_name = cpu ? "APP" : "PRO";
if (cpu == 0) {
stat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_STATUS_REG);
pid = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PID_REG);
inst = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGINST_REG);
dstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGSTATUS_REG);
data = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGDATA_REG);
pc = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGPC_REG);
lsstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0STAT_REG);
lsaddr = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0ADDR_REG);
lsdata = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0DATA_REG);
} else {
#if !CONFIG_FREERTOS_UNICORE
stat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_STATUS_REG);
pid = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PID_REG);
inst = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGINST_REG);
dstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGSTATUS_REG);
data = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGDATA_REG);
pc = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGPC_REG);
lsstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0STAT_REG);
lsaddr = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0ADDR_REG);
lsdata = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0DATA_REG);
#else
ESP_LOGE(TAG, "WDT reset info: &s CPU not support!\n", cpu_name);
return;
#endif
}
if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 &&
DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) {
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x (waiti mode)", cpu_name, pc);
} else {
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x", cpu_name, pc);
}
ESP_LOGD(TAG, "WDT reset info: %s CPU STATUS 0x%08x", cpu_name, stat);
ESP_LOGD(TAG, "WDT reset info: %s CPU PID 0x%08x", cpu_name, pid);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST 0x%08x", cpu_name, inst);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS 0x%08x", cpu_name, dstat);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA 0x%08x", cpu_name, data);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC 0x%08x", cpu_name, pc);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08x", cpu_name, lsstat);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08x", cpu_name, lsaddr);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08x", cpu_name, lsdata);
}
static void bootloader_check_wdt_reset(void)
{
int wdt_rst = 0;
RESET_REASON rst_reas[2];
rst_reas[0] = rtc_get_reset_reason(0);
rst_reas[1] = rtc_get_reset_reason(1);
if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET ||
rst_reas[0] == TGWDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
}
if (rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET || rst_reas[1] == TG1WDT_SYS_RESET ||
rst_reas[1] == TGWDT_CPU_RESET || rst_reas[1] == RTCWDT_CPU_RESET) {
ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
wdt_rst = 1;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
wdt_reset_info_dump(1);
}
wdt_reset_cpu0_info_enable();
}
void abort(void)
{
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT
ets_printf("abort() was called at PC 0x%08x\r\n", (intptr_t)__builtin_return_address(0) - 3);
#endif
if (esp_cpu_in_ocd_debug_mode()) {
__asm__("break 0,0");
}
while (1) {
}
}
esp_err_t bootloader_init(void)
{
esp_err_t ret = ESP_OK;
// workaround for tensilica erratum572
cpu_init_memctl();
// protect memory region
cpu_configure_region_protection();
// check that static RAM is after the stack
#ifndef NDEBUG
{
assert(&_bss_start <= &_bss_end);
assert(&_data_start <= &_data_end);
int *sp = get_sp();
assert(sp < &_bss_start);
assert(sp < &_data_start);
}
#endif
// clear bss section
bootloader_clear_bss_section();
// bootst up vddsdio
bootloader_common_vddsdio_configure();
// reset MMU
bootloader_reset_mmu();
// check rated CPU clock
if ((ret = bootloader_check_rated_cpu_clock()) != ESP_OK) {
goto err;
}
// config clock
bootloader_clock_configure();
// initialize uart console, from now on, we can use esp_log
bootloader_init_uart_console();
/* print 2nd bootloader banner */
bootloader_print_banner();
// update flash ID
bootloader_flash_update_id();
// read bootloader header
if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
goto err;
}
// read chip revision and check if it's compatible to bootloader
if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) {
goto err;
}
// initialize spi flash
if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
goto err;
}
// check whether a WDT reset happend
bootloader_check_wdt_reset();
// config WDT
bootloader_config_wdt();
// enable RNG early entropy source
bootloader_enable_random();
err:
return ret;
}

View File

@@ -16,10 +16,9 @@
#include <string.h>
#include <assert.h>
#include <sys/param.h>
#include "esp32/rom/sha.h"
#include "soc/dport_reg.h"
#include "soc/hwcrypto_periph.h"
#include "esp32/rom/ets_sys.h" // TO REMOVE
static uint32_t words_hashed;
@@ -28,7 +27,7 @@ static const size_t BLOCK_WORDS = (64 / sizeof(uint32_t));
// Words in final SHA256 digest
static const size_t DIGEST_WORDS = (32 / sizeof(uint32_t));
bootloader_sha256_handle_t bootloader_sha256_start(void)
bootloader_sha256_handle_t bootloader_sha256_start()
{
// Enable SHA hardware
ets_sha_enable();

View File

@@ -37,8 +37,8 @@ static const char *TAG = "flash_encrypt";
/* Static functions for stages of flash encryption */
static esp_err_t initialise_flash_encryption(void);
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis) __attribute__((unused));
static esp_err_t encrypt_bootloader(void);
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis);
static esp_err_t encrypt_bootloader();
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions);
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition);
@@ -60,14 +60,8 @@ esp_err_t esp_flash_encrypt_check_and_update(void)
return ESP_OK;
}
else {
#ifndef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
/* Flash is not encrypted, so encrypt it! */
return encrypt_flash_contents(flash_crypt_cnt, flash_crypt_wr_dis);
#else
ESP_LOGE(TAG, "flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED "
"is set, refusing to boot.");
return ESP_ERR_INVALID_STATE;
#endif // CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
}
}
@@ -174,7 +168,7 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
/* If the last flash_crypt_cnt bit is burned or write-disabled, the
device can't re-encrypt itself. */
if (flash_crypt_wr_dis || flash_crypt_cnt == 0xFF) {
if (flash_crypt_wr_dis) {
ESP_LOGE(TAG, "Cannot re-encrypt data (FLASH_CRYPT_CNT 0x%02x write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
return ESP_FAIL;
}
@@ -229,7 +223,7 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
return ESP_OK;
}
static esp_err_t encrypt_bootloader(void)
static esp_err_t encrypt_bootloader()
{
esp_err_t err;
uint32_t image_length;

View File

@@ -95,7 +95,7 @@ static bool secure_boot_generate(uint32_t image_len){
}
/* Burn values written to the efuse write registers */
static inline void burn_efuses(void)
static inline void burn_efuses()
{
esp_efuse_burn_new_values();
}

View File

@@ -18,7 +18,6 @@
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "esp_spi_flash.h"
#include "esp32/rom/sha.h"
#include "uECC.h"

View File

@@ -1,399 +0,0 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include "sdkconfig.h"
#include "bootloader_common.h"
#include "soc/efuse_reg.h"
#include "soc/gpio_sig_map.h"
#include "soc/io_mux_reg.h"
#include "esp32s2beta/rom/efuse.h"
#include "esp32s2beta/rom/gpio.h"
#include "esp32s2beta/rom/spi_flash.h"
#include "bootloader_init.h"
#include "bootloader_clock.h"
#include "bootloader_flash_config.h"
#include "esp32s2beta/rom/cache.h"
#include "esp32s2beta/rom/ets_sys.h"
#include "esp32s2beta/rom/spi_flash.h"
#include "esp32s2beta/rom/rtc.h"
#include "esp32s2beta/rom/uart.h"
#include "esp_attr.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "flash_qio_mode.h"
#include "soc/assist_debug_reg.h"
#include "soc/cpu.h"
#include "soc/dport_reg.h"
#include "soc/rtc.h"
#include "soc/spi_periph.h"
static const char *TAG = "boot.esp32s2";
#define FLASH_CLK_IO SPI_CLK_GPIO_NUM
#define FLASH_CS_IO SPI_CS0_GPIO_NUM
#define FLASH_SPIQ_IO SPI_Q_GPIO_NUM
#define FLASH_SPID_IO SPI_D_GPIO_NUM
#define FLASH_SPIWP_IO SPI_WP_GPIO_NUM
#define FLASH_SPIHD_IO SPI_HD_GPIO_NUM
void bootloader_configure_spi_pins(int drv)
{
const uint32_t spiconfig = ets_efuse_get_spiconfig();
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0);
gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
//select pin function gpio
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIHD_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIWP_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICS0_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIQ_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPID_U, PIN_FUNC_GPIO);
// flash clock signal should come from IO MUX.
// set drive ability for clock
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICLK_U, FUNC_SPICLK_SPICLK);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPICLK_U, FUN_DRV, drv, FUN_DRV_S);
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32 || CONFIG_SPIRAM_TYPE_ESPPSRAM64
uint32_t flash_id = g_rom_flashchip.device_id;
if (flash_id == FLASH_ID_GD25LQ32C) {
// Set drive ability for 1.8v flash in 80Mhz.
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPIHD_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPIWP_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPICS0_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPICLK_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPIQ_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SPID_U, FUN_DRV, 3, FUN_DRV_S);
}
#endif
}
}
static void bootloader_reset_mmu(void)
{
//ToDo: save the autoload value
Cache_Suspend_ICache();
Cache_Invalidate_ICache_All();
Cache_MMU_Init();
/* normal ROM boot exits with DROM0 cache unmasked,
but serial bootloader exits with it masked. */
DPORT_REG_CLR_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_DROM0);
}
static void update_flash_config(const esp_image_header_t *bootloader_hdr)
{
uint32_t size;
switch (bootloader_hdr->spi_size) {
case ESP_IMAGE_FLASH_SIZE_1MB:
size = 1;
break;
case ESP_IMAGE_FLASH_SIZE_2MB:
size = 2;
break;
case ESP_IMAGE_FLASH_SIZE_4MB:
size = 4;
break;
case ESP_IMAGE_FLASH_SIZE_8MB:
size = 8;
break;
case ESP_IMAGE_FLASH_SIZE_16MB:
size = 16;
break;
default:
size = 2;
}
uint32_t autoload = Cache_Suspend_ICache();
// Set flash chip size
esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
// TODO: set mode
// TODO: set frequency
Cache_Resume_ICache(autoload);
}
static void print_flash_info(const esp_image_header_t *bootloader_hdr)
{
ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic);
ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count);
ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode);
ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed);
ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size);
const char *str;
switch (bootloader_hdr->spi_speed) {
case ESP_IMAGE_SPI_SPEED_40M:
str = "40MHz";
break;
case ESP_IMAGE_SPI_SPEED_26M:
str = "26.7MHz";
break;
case ESP_IMAGE_SPI_SPEED_20M:
str = "20MHz";
break;
case ESP_IMAGE_SPI_SPEED_80M:
str = "80MHz";
break;
default:
str = "20MHz";
break;
}
ESP_LOGI(TAG, "SPI Speed : %s", str);
/* SPI mode could have been set to QIO during boot already,
so test the SPI registers not the flash header */
uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
if (spi_ctrl & SPI_MEM_FREAD_QIO) {
str = "QIO";
} else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
str = "QOUT";
} else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
str = "DIO";
} else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
str = "DOUT";
} else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
str = "FAST READ";
} else {
str = "SLOW READ";
}
ESP_LOGI(TAG, "SPI Mode : %s", str);
switch (bootloader_hdr->spi_size) {
case ESP_IMAGE_FLASH_SIZE_1MB:
str = "1MB";
break;
case ESP_IMAGE_FLASH_SIZE_2MB:
str = "2MB";
break;
case ESP_IMAGE_FLASH_SIZE_4MB:
str = "4MB";
break;
case ESP_IMAGE_FLASH_SIZE_8MB:
str = "8MB";
break;
case ESP_IMAGE_FLASH_SIZE_16MB:
str = "16MB";
break;
default:
str = "2MB";
break;
}
ESP_LOGI(TAG, "SPI Flash Size : %s", str);
}
static void IRAM_ATTR bootloader_init_flash_configure(void)
{
bootloader_flash_gpio_config(&bootloader_image_hdr);
bootloader_flash_dummy_config(&bootloader_image_hdr);
bootloader_flash_cs_timing_config();
}
static esp_err_t bootloader_init_spi_flash(void)
{
bootloader_init_flash_configure();
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
const uint32_t spiconfig = ets_efuse_get_spiconfig();
if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
return ESP_FAIL;
}
#endif
esp_rom_spiflash_unlock();
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT
bootloader_enable_qio_mode();
#endif
print_flash_info(&bootloader_image_hdr);
update_flash_config(&bootloader_image_hdr);
return ESP_OK;
}
static void bootloader_init_uart_console(void)
{
#if CONFIG_ESP_CONSOLE_UART_NONE
ets_install_putc1(NULL);
ets_install_putc2(NULL);
#else // CONFIG_ESP_CONSOLE_UART_NONE
const int uart_num = CONFIG_ESP_CONSOLE_UART_NUM;
uartAttach();
ets_install_uart_printf();
// Wait for UART FIFO to be empty.
uart_tx_wait_idle(0);
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
// Some constants to make the following code less upper-case
const int uart_tx_gpio = CONFIG_ESP_CONSOLE_UART_TX_GPIO;
const int uart_rx_gpio = CONFIG_ESP_CONSOLE_UART_RX_GPIO;
// Switch to the new UART (this just changes UART number used for
// ets_printf in ROM code).
uart_tx_switch(uart_num);
// If console is attached to UART1 or if non-default pins are used,
// need to reconfigure pins using GPIO matrix
if (uart_num != 0 || uart_tx_gpio != 1 || uart_rx_gpio != 3) {
// Change pin mode for GPIO1/3 from UART to GPIO
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_GPIO1);
// Route GPIO signals to/from pins
// (arrays should be optimized away by the compiler)
const uint32_t tx_idx_list[3] = {U0TXD_OUT_IDX, U1TXD_OUT_IDX, U2TXD_OUT_IDX};
const uint32_t rx_idx_list[3] = {U0RXD_IN_IDX, U1RXD_IN_IDX, U2RXD_IN_IDX};
const uint32_t uart_reset[3] = {DPORT_UART_RST, DPORT_UART1_RST, DPORT_UART2_RST};
const uint32_t tx_idx = tx_idx_list[uart_num];
const uint32_t rx_idx = rx_idx_list[uart_num];
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
gpio_pad_pullup(uart_rx_gpio);
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
}
#endif // CONFIG_ESP_CONSOLE_UART_CUSTOM
// Set configured UART console baud rate
const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
#endif // CONFIG_ESP_CONSOLE_UART_NONE
}
static void wdt_reset_cpu0_info_enable(void)
{
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG);
DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG);
REG_WRITE(ASSIST_DEBUG_PRO_PDEBUGENABLE, 1);
REG_WRITE(ASSIST_DEBUG_PRO_RCD_RECORDING, 1);
}
static void wdt_reset_info_dump(int cpu)
{
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
const char *cpu_name = cpu ? "APP" : "PRO";
stat = 0xdeadbeef;
pid = 0;
inst = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGINST);
dstat = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGSTATUS);
data = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGDATA);
pc = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGPC);
lsstat = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0STAT);
lsaddr = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0ADDR);
lsdata = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0DATA);
if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 &&
DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) {
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x (waiti mode)", cpu_name, pc);
} else {
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x", cpu_name, pc);
}
ESP_LOGD(TAG, "WDT reset info: %s CPU STATUS 0x%08x", cpu_name, stat);
ESP_LOGD(TAG, "WDT reset info: %s CPU PID 0x%08x", cpu_name, pid);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST 0x%08x", cpu_name, inst);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS 0x%08x", cpu_name, dstat);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA 0x%08x", cpu_name, data);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC 0x%08x", cpu_name, pc);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08x", cpu_name, lsstat);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08x", cpu_name, lsaddr);
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08x", cpu_name, lsdata);
}
static void bootloader_check_wdt_reset(void)
{
int wdt_rst = 0;
RESET_REASON rst_reas[2];
rst_reas[0] = rtc_get_reset_reason(0);
if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET ||
rst_reas[0] == TG0WDT_CPU_RESET || rst_reas[0] == TG1WDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
}
wdt_reset_cpu0_info_enable();
}
void abort(void)
{
#if !CONFIG_ESP32S2_PANIC_SILENT_REBOOT
ets_printf("abort() was called at PC 0x%08x\r\n", (intptr_t)__builtin_return_address(0) - 3);
#endif
if (esp_cpu_in_ocd_debug_mode()) {
__asm__("break 0,0");
}
while (1) {
}
}
esp_err_t bootloader_init(void)
{
esp_err_t ret = ESP_OK;
// protect memory region
cpu_configure_region_protection();
/* check that static RAM is after the stack */
#ifndef NDEBUG
{
assert(&_bss_start <= &_bss_end);
assert(&_data_start <= &_data_end);
}
#endif
// clear bss section
bootloader_clear_bss_section();
// reset MMU
bootloader_reset_mmu();
// config clock
bootloader_clock_configure();
// initialize uart console, from now on, we can use esp_log
bootloader_init_uart_console();
/* print 2nd bootloader banner */
bootloader_print_banner();
// update flash ID
bootloader_flash_update_id();
// read bootloader header
if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
goto err;
}
// read chip revision and check if it's compatible to bootloader
if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) {
goto err;
}
// initialize spi flash
if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
goto err;
}
// check whether a WDT reset happend
bootloader_check_wdt_reset();
// config WDT
bootloader_config_wdt();
// enable RNG early entropy source
bootloader_enable_random();
err:
return ret;
}

View File

@@ -1,53 +0,0 @@
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "bootloader_sha.h"
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <sys/param.h>
#include "esp32s2beta/rom/sha.h"
static SHA_CTX ctx;
// Words per SHA256 block
// static const size_t BLOCK_WORDS = (64/sizeof(uint32_t));
// Words in final SHA256 digest
// static const size_t DIGEST_WORDS = (32/sizeof(uint32_t));
bootloader_sha256_handle_t bootloader_sha256_start()
{
// Enable SHA hardware
ets_sha_enable();
ets_sha_init(&ctx, SHA2_256);
return &ctx; // Meaningless non-NULL value
}
void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len)
{
assert(handle != NULL);
assert(data_len % 4 == 0);
ets_sha_update(&ctx, data, data_len, false);
}
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest)
{
assert(handle != NULL);
if (digest == NULL) {
bzero(&ctx, sizeof(ctx));
return;
}
ets_sha_finish(&ctx, digest);
}

View File

@@ -1,303 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <strings.h>
#include "bootloader_flash.h"
#include "bootloader_random.h"
#include "bootloader_utility.h"
#include "esp_image_format.h"
#include "esp_flash_encrypt.h"
#include "esp_flash_partitions.h"
#include "esp_secure_boot.h"
#include "esp_log.h"
#include "esp32s2beta/rom/secure_boot.h"
#include "esp32s2beta/rom/cache.h"
#include "esp32s2beta/rom/efuse.h"
static const char *TAG = "flash_encrypt";
/* Static functions for stages of flash encryption */
static esp_err_t initialise_flash_encryption(void);
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis);
static esp_err_t encrypt_bootloader(void);
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions);
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition);
esp_err_t esp_flash_encrypt_check_and_update(void)
{
// TODO: not clear why this is read from DATA1 and written to PGM_DATA2
uint32_t cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_SPI_BOOT_CRYPT_CNT);
ESP_LOGV(TAG, "SPI_BOOT_CRYPT_CNT 0x%x", cnt);
bool flash_crypt_wr_dis = false; // TODO: check if CRYPT_CNT is write disabled
_Static_assert(EFUSE_SPI_BOOT_CRYPT_CNT == 0x7, "assuming CRYPT_CNT is only 3 bits wide");
if (cnt == 1 || cnt == 3 || cnt == 7) {
/* Flash is already encrypted */
int left;
if (cnt == 7 /* || disabled */) {
left = 0;
} else if (cnt == 3) {
left = 1;
} else {
left = 2;
}
ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left);
return ESP_OK;
}
else {
/* Flash is not encrypted, so encrypt it! */
return encrypt_flash_contents(cnt, flash_crypt_wr_dis);
}
}
static esp_err_t initialise_flash_encryption(void)
{
/* Before first flash encryption pass, need to initialise key & crypto config */
/* Find out if a key is already set */
bool has_aes128 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL);
bool has_aes256_1 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1, NULL);
bool has_aes256_2 = ets_efuse_find_purpose(ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2, NULL);
bool has_key = has_aes128 || (has_aes256_1 && has_aes256_2);
if (!has_key && (has_aes256_1 || has_aes256_2)) {
ESP_LOGE(TAG, "Invalid efuse key blocks: Both AES-256 key blocks must be set.");
return ESP_ERR_INVALID_STATE;
}
if (has_key) {
ESP_LOGI(TAG, "Using pre-existing key in efuse");
ESP_LOGE(TAG, "TODO: Check key is read & write protected"); // TODO
} else {
ESP_LOGI(TAG, "Generating new flash encryption key...");
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_AES256
const unsigned BLOCKS_NEEDED = 2;
const ets_efuse_purpose_t PURPOSE_START = ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1;
const ets_efuse_purpose_t PURPOSE_END = ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2;
#else
const unsigned BLOCKS_NEEDED = 1;
const ets_efuse_purpose_t PURPOSE_START = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY;
const ets_efuse_purpose_t PURPOSE_END = ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY;
#endif
if (ets_efuse_count_unused_key_blocks() < BLOCKS_NEEDED) {
ESP_LOGE(TAG, "Not enough free efuse key blocks (need %d) to continue", BLOCKS_NEEDED);
return ESP_ERR_INVALID_STATE;
}
for(ets_efuse_purpose_t purpose = PURPOSE_START; purpose <= PURPOSE_END; purpose++) {
uint32_t buf[8];
bootloader_fill_random(buf, sizeof(buf));
ets_efuse_block_t block = ets_efuse_find_unused_key_block();
ESP_LOGD(TAG, "Writing ETS_EFUSE_BLOCK_KEY%d with purpose %d",
block - ETS_EFUSE_BLOCK_KEY0, purpose);
bootloader_debug_buffer(buf, sizeof(buf), "Key content");
int r = ets_efuse_write_key(block, purpose, buf, sizeof(buf));
bzero(buf, sizeof(buf));
if (r != 0) {
ESP_LOGE(TAG, "Failed to write efuse block %d with purpose %d. Can't continue.");
return ESP_FAIL;
}
}
ESP_LOGD(TAG, "Key generation complete");
}
ESP_LOGE(TAG, "TODO: burn remaining security protection bits"); // TODO
return ESP_OK;
}
/* Encrypt all flash data that should be encrypted */
static esp_err_t encrypt_flash_contents(uint32_t spi_boot_crypt_cnt, bool flash_crypt_wr_dis)
{
esp_err_t err;
esp_partition_info_t partition_table[ESP_PARTITION_TABLE_MAX_ENTRIES];
int num_partitions;
/* If the last spi_boot_crypt_cnt bit is burned or write-disabled, the
device can't re-encrypt itself. */
if (flash_crypt_wr_dis || spi_boot_crypt_cnt == EFUSE_SPI_BOOT_CRYPT_CNT) {
ESP_LOGE(TAG, "Cannot re-encrypt data (SPI_BOOT_CRYPT_CNT 0x%02x write disabled %d", spi_boot_crypt_cnt, flash_crypt_wr_dis);
return ESP_FAIL;
}
if (spi_boot_crypt_cnt == 0) {
/* Very first flash of encrypted data: generate keys, etc. */
err = initialise_flash_encryption();
if (err != ESP_OK) {
return err;
}
}
err = encrypt_bootloader();
if (err != ESP_OK) {
return err;
}
err = encrypt_and_load_partition_table(partition_table, &num_partitions);
if (err != ESP_OK) {
return err;
}
/* Now iterate the just-loaded partition table, looking for entries to encrypt
*/
/* Go through each partition and encrypt if necessary */
for (int i = 0; i < num_partitions; i++) {
err = encrypt_partition(i, &partition_table[i]);
if (err != ESP_OK) {
return err;
}
}
ESP_LOGD(TAG, "All flash regions checked for encryption pass");
/* Set least significant 0-bit in spi_boot_crypt_cnt */
int ffs_inv = __builtin_ffs((~spi_boot_crypt_cnt) & 0x7);
/* ffs_inv shouldn't be zero, as zero implies spi_boot_crypt_cnt == 0xFF */
uint32_t new_spi_boot_crypt_cnt = spi_boot_crypt_cnt + (1 << (ffs_inv - 1));
ESP_LOGD(TAG, "SPI_BOOT_CRYPT_CNT 0x%x -> 0x%x", spi_boot_crypt_cnt, new_spi_boot_crypt_cnt);
ets_efuse_clear_program_registers();
REG_SET_FIELD(EFUSE_PGM_DATA2_REG, EFUSE_SPI_BOOT_CRYPT_CNT, new_spi_boot_crypt_cnt);
ets_efuse_program(ETS_EFUSE_BLOCK0);
ESP_LOGI(TAG, "Flash encryption completed");
return ESP_OK;
}
static esp_err_t encrypt_bootloader(void)
{
esp_err_t err;
uint32_t image_length;
/* Check for plaintext bootloader (verification will fail if it's already encrypted) */
if (esp_image_verify_bootloader(&image_length) == ESP_OK) {
ESP_LOGD(TAG, "bootloader is plaintext. Encrypting...");
err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, image_length);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
return err;
}
if (esp_secure_boot_enabled()) {
// TODO: anything different for secure boot?
}
}
else {
ESP_LOGW(TAG, "no valid bootloader was found");
}
return ESP_OK;
}
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions)
{
esp_err_t err;
/* Check for plaintext partition table */
err = bootloader_flash_read(ESP_PARTITION_TABLE_OFFSET, partition_table, ESP_PARTITION_TABLE_MAX_LEN, false);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to read partition table data");
return err;
}
if (esp_partition_table_verify(partition_table, false, num_partitions) == ESP_OK) {
ESP_LOGD(TAG, "partition table is plaintext. Encrypting...");
esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET,
FLASH_SECTOR_SIZE);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to encrypt partition table in place. %x", err);
return err;
}
}
else {
ESP_LOGE(TAG, "Failed to read partition table data - not plaintext?");
return ESP_ERR_INVALID_STATE;
}
/* Valid partition table loded */
return ESP_OK;
}
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition)
{
esp_err_t err;
bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED);
if (partition->type == PART_TYPE_APP) {
/* check if the partition holds a valid unencrypted app */
esp_image_metadata_t data_ignored;
err = esp_image_verify(ESP_IMAGE_VERIFY,
&partition->pos,
&data_ignored);
should_encrypt = (err == ESP_OK);
} else if (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) {
/* check if we have ota data partition and the partition should be encrypted unconditionally */
should_encrypt = true;
}
if (!should_encrypt) {
return ESP_OK;
}
else {
/* should_encrypt */
ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, partition->pos.size);
err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size);
ESP_LOGI(TAG, "Done encrypting");
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to encrypt partition %d", index);
}
return err;
}
}
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
{
esp_err_t err;
uint32_t buf[FLASH_SECTOR_SIZE / sizeof(uint32_t)];
if (src_addr % FLASH_SECTOR_SIZE != 0) {
ESP_LOGE(TAG, "esp_flash_encrypt_region bad src_addr 0x%x",src_addr);
return ESP_FAIL;
}
for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) {
uint32_t sec_start = i + src_addr;
err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, false);
if (err != ESP_OK) {
goto flash_failed;
}
err = bootloader_flash_erase_sector(sec_start / FLASH_SECTOR_SIZE);
if (err != ESP_OK) {
goto flash_failed;
}
err = bootloader_flash_write(sec_start, buf, FLASH_SECTOR_SIZE, true);
if (err != ESP_OK) {
goto flash_failed;
}
}
return ESP_OK;
flash_failed:
ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
return err;
}

View File

@@ -1,45 +0,0 @@
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_secure_boot.h"
#include "esp_log.h"
#include "esp32s2beta/rom/secure_boot.h"
#define TAG "secure_boot"
esp_err_t esp_secure_boot_permanently_enable(void)
{
uint8_t hash[32];
if (ets_efuse_secure_boot_enabled())
{
ESP_LOGI(TAG, "secure boot is already enabled, continuing..");
return ESP_OK;
}
ESP_LOGI(TAG, "Verifying bootloader signature...\n");
int r = ets_secure_boot_verify_bootloader(hash, false);
if (r != ESP_OK) {
ESP_LOGE(TAG, "Failed to verify bootloader signature");
return r;
}
ets_efuse_clear_program_registers();
REG_SET_BIT(EFUSE_PGM_DATA3_REG, EFUSE_SECURE_BOOT_EN);
ets_efuse_program(ETS_EFUSE_BLOCK0);
assert(ets_efuse_secure_boot_enabled());
ESP_LOGI(TAG, "Secure boot permanently enabled");
return ESP_OK;
}

View File

@@ -1,92 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "bootloader_flash.h"
#include "bootloader_sha.h"
#include "esp_log.h"
#include "esp_image_format.h"
#include "esp32s2beta/rom/secure_boot.h"
static const char* TAG = "secure_boot";
#define DIGEST_LEN 32
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
{
ets_secure_boot_key_digests_t trusted_keys = { 0 };
uint8_t digest[DIGEST_LEN];
const uint8_t *data;
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
if ((src_addr + length) % 4096 != 0) {
ESP_LOGE(TAG, "addr 0x%x length 0x%x doesn't end on a sector boundary", src_addr, length);
return ESP_ERR_INVALID_ARG;
}
data = bootloader_mmap(src_addr, length + sizeof(struct ets_secure_boot_sig_block));
if(data == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(ets_secure_boot_signature_t));
return ESP_FAIL;
}
// Calculate digest of main image
#ifdef BOOTLOADER_BUILD
bootloader_sha256_handle_t handle = bootloader_sha256_start();
bootloader_sha256_data(handle, data, length);
bootloader_sha256_finish(handle, digest);
#else
/* Use thread-safe esp-idf SHA function */
esp_sha(SHA2_256, data, length, digest);
#endif
int r = ets_secure_boot_read_key_digests(&trusted_keys);
if (r == ETS_OK) {
const ets_secure_boot_signature_t *sig = (const ets_secure_boot_signature_t *)(data + length);
// TODO: calling this function in IDF app context is unsafe
r = ets_secure_boot_verify_signature(sig, digest, &trusted_keys);
}
bootloader_munmap(data);
return (r == ETS_OK) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_secure_boot_verify_signature_block(uint32_t sig_block_flash_offs, const uint8_t *image_digest)
{
ets_secure_boot_key_digests_t trusted_keys;
assert(sig_block_flash_offs % 4096 == 0); // TODO: enforce this in a better way
const ets_secure_boot_signature_t *sig = bootloader_mmap(sig_block_flash_offs, sizeof(ets_secure_boot_signature_t));
if (sig == NULL) {
ESP_LOGE(TAG, "Failed to mmap data at offset 0x%x", sig_block_flash_offs);
return ESP_FAIL;
}
int r = ets_secure_boot_read_key_digests(&trusted_keys);
if (r != 0) {
ESP_LOGE(TAG, "No trusted key digests were found in efuse!");
} else {
ESP_LOGD(TAG, "Verifying with RSA-PSS...");
// TODO: calling this function in IDF app context is unsafe
r = ets_secure_boot_verify_signature(sig, image_digest, &trusted_keys);
}
bootloader_munmap(sig);
return (r == 0) ? ESP_OK : ESP_ERR_IMAGE_INVALID;
}

View File

@@ -13,6 +13,8 @@
// limitations under the License.
#include <string.h>
#include <sys/param.h>
#include <esp32/rom/rtc.h>
#include <soc/cpu.h>
#include <bootloader_utility.h>
#include <esp_secure_boot.h>
@@ -22,14 +24,6 @@
#include <bootloader_random.h>
#include <bootloader_sha.h>
#include "bootloader_util.h"
#include "bootloader_common.h"
#if CONFIG_IDF_TARGET_ESP32
#include <esp32/rom/rtc.h>
#include <esp32/rom/secure_boot.h>
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include <esp32s2beta/rom/rtc.h>
#include <esp32s2beta/rom/secure_boot.h>
#endif
/* Checking signatures as part of verifying images is necessary:
- Always if secure boot is enabled
@@ -103,17 +97,14 @@ static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_ha
static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#ifdef BOOTLOADER_BUILD
bool do_load = (mode == ESP_IMAGE_LOAD) || (mode == ESP_IMAGE_LOAD_NO_VALIDATE);
bool do_verify = (mode == ESP_IMAGE_LOAD) || (mode == ESP_IMAGE_VERIFY) || (mode == ESP_IMAGE_VERIFY_SILENT);
bool do_load = (mode == ESP_IMAGE_LOAD);
#else
bool do_load = false; // Can't load the image in app mode
bool do_verify = true; // In app mode is avalible only verify mode
bool do_load = false; // Can't load the image in app mode
#endif
bool silent = (mode == ESP_IMAGE_VERIFY_SILENT);
bool silent = (mode == ESP_IMAGE_VERIFY_SILENT);
esp_err_t err = ESP_OK;
// checksum the image a word at a time. This shaves 30-40ms per MB of image size
uint32_t checksum_word = ESP_ROM_CHECKSUM_INITIAL;
uint32_t *checksum = NULL;
bootloader_sha256_handle_t sha_handle = NULL;
if (data == NULL || part == NULL) {
@@ -134,45 +125,41 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
goto err;
}
if (do_verify) {
checksum = &checksum_word;
// Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
// Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
#ifdef SECURE_BOOT_CHECK_SIGNATURE
if (1) {
if (1) {
#else
if (data->image.hash_appended) {
if (data->image.hash_appended) {
#endif
sha_handle = bootloader_sha256_start();
if (sha_handle == NULL) {
return ESP_ERR_NO_MEM;
}
bootloader_sha256_data(sha_handle, &data->image, sizeof(esp_image_header_t));
sha_handle = bootloader_sha256_start();
if (sha_handle == NULL) {
return ESP_ERR_NO_MEM;
}
bootloader_sha256_data(sha_handle, &data->image, sizeof(esp_image_header_t));
}
ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08x",
data->image.magic,
data->image.segment_count,
data->image.spi_mode,
data->image.spi_size,
data->image.entry_addr);
ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08x",
data->image.magic,
data->image.segment_count,
data->image.spi_mode,
data->image.spi_size,
data->image.entry_addr);
err = verify_image_header(data->start_addr, &data->image, silent);
if (err != ESP_OK) {
goto err;
}
err = verify_image_header(data->start_addr, &data->image, silent);
if (err != ESP_OK) {
goto err;
}
if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
FAIL_LOAD("image at 0x%x segment count %d exceeds max %d",
data->start_addr, data->image.segment_count, ESP_IMAGE_MAX_SEGMENTS);
}
} // if (do_verify)
if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
FAIL_LOAD("image at 0x%x segment count %d exceeds max %d",
data->start_addr, data->image.segment_count, ESP_IMAGE_MAX_SEGMENTS);
}
uint32_t next_addr = data->start_addr + sizeof(esp_image_header_t);
for (int i = 0; i < data->image.segment_count; i++) {
for(int i = 0; i < data->image.segment_count; i++) {
esp_image_segment_header_t *header = &data->segments[i];
ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr);
err = process_segment(i, next_addr, header, silent, do_load, sha_handle, checksum);
err = process_segment(i, next_addr, header, silent, do_load, sha_handle, &checksum_word);
if (err != ESP_OK) {
goto err;
}
@@ -181,81 +168,69 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
next_addr += header->data_len;
}
if (do_verify) {
// Segments all loaded, verify length
uint32_t end_addr = next_addr;
if (end_addr < data->start_addr) {
FAIL_LOAD("image offset has wrapped");
// Segments all loaded, verify length
uint32_t end_addr = next_addr;
if (end_addr < data->start_addr) {
FAIL_LOAD("image offset has wrapped");
}
data->image_len = end_addr - data->start_addr;
ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr);
if (!esp_cpu_in_ocd_debug_mode()) {
err = verify_checksum(sha_handle, checksum_word, data);
if (err != ESP_OK) {
goto err;
}
}
if (data->image_len > part->size) {
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
}
data->image_len = end_addr - data->start_addr;
ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr);
if (NULL != checksum && !esp_cpu_in_ocd_debug_mode()) {
err = verify_checksum(sha_handle, checksum_word, data);
if (err != ESP_OK) {
goto err;
}
}
/* For secure boot on ESP32, we don't calculate SHA or verify signautre on bootloaders.
For ESP32S2, we do verify signature on botoloaders which includes the SHA calculation.
(For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because
esptool.py may have rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.)
*/
bool verify_sha;
#if defined(CONFIG_SECURE_BOOT_ENABLED) && defined(CONFIG_IDF_TARGET_ESP32S2BETA)
verify_sha = true;
#else // ESP32, or ESP32S2 without secure boot enabled
verify_sha = (data->start_addr != ESP_BOOTLOADER_OFFSET);
#endif
if (verify_sha) {
if (data->image_len > part->size) {
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
}
bool is_bootloader = (data->start_addr == ESP_BOOTLOADER_OFFSET);
/* For secure boot, we don't verify signature on bootloaders.
For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because esptool.py may have
rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.
*/
if (!is_bootloader) {
#ifdef SECURE_BOOT_CHECK_SIGNATURE
// secure boot images have a signature appended
err = verify_secure_boot_signature(sha_handle, data);
// secure boot images have a signature appended
err = verify_secure_boot_signature(sha_handle, data);
#else
// No secure boot, but SHA-256 can be appended for basic corruption detection
if (sha_handle != NULL && !esp_cpu_in_ocd_debug_mode()) {
err = verify_simple_hash(sha_handle, data);
sha_handle = NULL; // calling verify_simple_hash finishes sha_handle
}
#endif // SECURE_BOOT_CHECK_SIGNATURE
} else { // verify_sha
// bootloader may still have a sha256 digest handle open
if (sha_handle != NULL) {
bootloader_sha256_finish(sha_handle, NULL);
}
sha_handle = NULL;
} //verify_sha
// Separately, if there's a hash appended to the image then copy it out to the data->image_digest field
if (data->image.hash_appended) {
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
if (hash == NULL) {
err = ESP_FAIL;
goto err;
}
memcpy(data->image_digest, hash, HASH_LEN);
bootloader_munmap(hash);
// No secure boot, but SHA-256 can be appended for basic corruption detection
if (sha_handle != NULL && !esp_cpu_in_ocd_debug_mode()) {
err = verify_simple_hash(sha_handle, data);
}
} // do_verify
#endif // SECURE_BOOT_CHECK_SIGNATURE
} else { // is_bootloader
// bootloader may still have a sha256 digest handle open
if (sha_handle != NULL) {
bootloader_sha256_finish(sha_handle, NULL);
}
}
if (data->image.hash_appended) {
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
if (hash == NULL) {
err = ESP_FAIL;
goto err;
}
memcpy(data->image_digest, hash, HASH_LEN);
bootloader_munmap(hash);
}
sha_handle = NULL;
if (err != ESP_OK) {
goto err;
}
#ifdef BOOTLOADER_BUILD
if (do_load && ram_obfs_value[0] != 0 && ram_obfs_value[1] != 0) { // Need to deobfuscate RAM
if (do_load) { // Need to deobfuscate RAM
for (int i = 0; i < data->image.segment_count; i++) {
uint32_t load_addr = data->segments[i].load_addr;
if (should_load(load_addr)) {
uint32_t *loaded = (uint32_t *)load_addr;
for (int j = 0; j < data->segments[i].data_len / sizeof(uint32_t); j++) {
for (int j = 0; j < data->segments[i].data_len/sizeof(uint32_t); j++) {
loaded[j] ^= (j & 1) ? ram_obfs_value[0] : ram_obfs_value[1];
}
}
@@ -266,9 +241,9 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
// Success!
return ESP_OK;
err:
err:
if (err == ESP_OK) {
err = ESP_ERR_IMAGE_INVALID;
err = ESP_ERR_IMAGE_INVALID;
}
if (sha_handle != NULL) {
// Need to finish the hash process to free the handle
@@ -277,7 +252,7 @@ err:
// Prevent invalid/incomplete data leaking out
bzero(data, sizeof(esp_image_metadata_t));
return err;
}
}
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
@@ -288,20 +263,13 @@ esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metad
#endif
}
esp_err_t bootloader_load_image_no_verify(const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#ifdef BOOTLOADER_BUILD
return image_load(ESP_IMAGE_LOAD_NO_VALIDATE, part, data);
#else
return ESP_FAIL;
#endif
}
esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
return image_load(mode, part, data);
}
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) __attribute__((alias("esp_image_verify")));
static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent)
{
esp_err_t err = ESP_OK;
@@ -323,16 +291,6 @@ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t
ESP_LOGW(TAG, "image at 0x%x has invalid SPI size %d", src_addr, image->spi_size);
}
}
if (err == ESP_OK) {
// Checking the chip revision header *will* print a bunch of other info
// regardless of silent setting as this may be important, but don't bother checking it
// if it looks like the app partition is erased or otherwise garbage
if (bootloader_common_check_chip_validity(image, ESP_IMAGE_APPLICATION) != ESP_OK) {
err = ESP_ERR_IMAGE_INVALID;
}
}
return err;
}
@@ -372,7 +330,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
ESP_LOGI(TAG, "segment %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s",
index, data_addr, load_addr,
data_len, data_len,
(do_load) ? "load" : (is_mapping) ? "map" : "");
(do_load)?"load":(is_mapping)?"map":"");
}
@@ -380,7 +338,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
/* Before loading segment, check it doesn't clobber bootloader RAM. */
if (do_load) {
const intptr_t load_end = load_addr + data_len;
if (load_end < (intptr_t) SOC_DRAM_HIGH) {
if (load_end <= (intptr_t) SOC_DIRAM_DRAM_HIGH) {
/* Writing to DRAM */
intptr_t sp = (intptr_t)get_sp();
if (load_end > sp - STACK_LOAD_HEADROOM) {
@@ -401,7 +359,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
const intptr_t loader_iram_end = (intptr_t) &_loader_text_end;
if (bootloader_util_regions_overlap(loader_iram_start, loader_iram_end,
load_addr, load_end)) {
load_addr, load_end)) {
ESP_LOGE(TAG, "Segment %d (0x%08x-0x%08x) overlaps bootloader IRAM (0x%08x-0x%08x)",
index, load_addr, load_end, loader_iram_start, loader_iram_end);
return ESP_ERR_IMAGE_INVALID;
@@ -438,26 +396,13 @@ err:
static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
{
// If we are not loading, and the checksum is empty, skip processing this
// segment for data
if(!do_load && checksum == NULL) {
ESP_LOGD(TAG, "skipping checksum for segment");
return ESP_OK;
}
const uint32_t *data = (const uint32_t *)bootloader_mmap(data_addr, data_len);
if (!data) {
if(!data) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed",
data_addr, data_len);
return ESP_FAIL;
}
if (checksum == NULL && sha_handle == NULL) {
memcpy((void *)load_addr, data, data_len);
bootloader_munmap(data);
return ESP_OK;
}
#ifdef BOOTLOADER_BUILD
// Set up the obfuscation value to use for loading
while (ram_obfs_value[0] == 0 || ram_obfs_value[1] == 0) {
@@ -469,11 +414,9 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui
const uint32_t *src = data;
for (int i = 0; i < data_len; i += 4) {
int w_i = i / 4; // Word index
int w_i = i/4; // Word index
uint32_t w = src[w_i];
if (checksum != NULL) {
*checksum ^= w;
}
*checksum ^= w;
#ifdef BOOTLOADER_BUILD
if (do_load) {
dest[w_i] = w ^ ((w_i & 1) ? ram_obfs_value[0] : ram_obfs_value[1]);
@@ -498,7 +441,7 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui
static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent)
{
if ((segment->data_len & 3) != 0
|| segment->data_len >= SIXTEEN_MB) {
|| segment->data_len >= SIXTEEN_MB) {
if (!silent) {
ESP_LOGE(TAG, "invalid segment length 0x%x", segment->data_len);
}
@@ -514,7 +457,7 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header
ESP_LOGV(TAG, "segment %d map_segment %d segment_data_offs 0x%x load_addr 0x%x",
index, map_segment, segment_data_offs, load_addr);
if (map_segment
&& ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) {
&& ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) {
if (!silent) {
ESP_LOGE(TAG, "Segment %d load address 0x%08x, doesn't match data 0x%08x",
index, load_addr, segment_data_offs);
@@ -528,7 +471,7 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header
static bool should_map(uint32_t load_addr)
{
return (load_addr >= SOC_IROM_LOW && load_addr < SOC_IROM_HIGH)
|| (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH);
|| (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH);
}
static bool should_load(uint32_t load_addr)
@@ -551,15 +494,15 @@ static bool should_load(uint32_t load_addr)
if (!load_rtc_memory) {
if (load_addr >= SOC_RTC_IRAM_LOW && load_addr < SOC_RTC_IRAM_HIGH) {
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x", load_addr);
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
return false;
}
if (load_addr >= SOC_RTC_DRAM_LOW && load_addr < SOC_RTC_DRAM_HIGH) {
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x", load_addr);
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
return false;
}
if (load_addr >= SOC_RTC_DATA_LOW && load_addr < SOC_RTC_DATA_HIGH) {
ESP_LOGD(TAG, "Skipping RTC slow memory segment at 0x%08x", load_addr);
ESP_LOGD(TAG, "Skipping RTC slow memory segment at 0x%08x\n", load_addr);
return false;
}
}
@@ -587,8 +530,8 @@ esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data)
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
};
return esp_image_verify(ESP_IMAGE_VERIFY,
&bootloader_part,
data);
&bootloader_part,
data);
}
@@ -603,9 +546,9 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t
esp_err_t err = bootloader_flash_read(data->start_addr + unpadded_length, buf, length - unpadded_length, true);
uint8_t calc = buf[length - unpadded_length - 1];
uint8_t checksum = (checksum_word >> 24)
^ (checksum_word >> 16)
^ (checksum_word >> 8)
^ (checksum_word >> 0);
^ (checksum_word >> 16)
^ (checksum_word >> 8)
^ (checksum_word >> 0);
if (err != ESP_OK || checksum != calc) {
ESP_LOGE(TAG, "Checksum failed. Calculated 0x%x read 0x%x", checksum, calc);
return ESP_ERR_IMAGE_INVALID;
@@ -623,36 +566,26 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t
return ESP_OK;
}
static void debug_log_hash(const uint8_t *image_hash, const char *caption);
static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data)
{
uint8_t image_hash[HASH_LEN] = { 0 };
uint32_t end = data->start_addr + data->image_len;
ESP_LOGI(TAG, "Verifying image signature...");
// For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash
// appended to the image for corruption detection
if (data->image.hash_appended) {
const void *simple_hash = bootloader_mmap(end - HASH_LEN, HASH_LEN);
const void *simple_hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
bootloader_sha256_data(sha_handle, simple_hash, HASH_LEN);
bootloader_munmap(simple_hash);
}
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
// Pad to 4096 byte sector boundary
if (end % FLASH_SECTOR_SIZE != 0) {
uint32_t pad_len = FLASH_SECTOR_SIZE - (end % FLASH_SECTOR_SIZE);
const void *padding = bootloader_mmap(end, pad_len);
bootloader_sha256_data(sha_handle, padding, pad_len);
bootloader_munmap(padding);
end += pad_len;
}
#endif
bootloader_sha256_finish(sha_handle, image_hash);
// Log the hash for debugging
bootloader_debug_buffer(image_hash, HASH_LEN, "Calculated secure boot hash");
debug_log_hash(image_hash, "Calculated secure boot hash");
// Use hash to verify signature block
const esp_secure_boot_sig_block_t *sig_block = bootloader_mmap(data->start_addr + data->image_len, sizeof(esp_secure_boot_sig_block_t));
@@ -677,11 +610,6 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han
return ESP_ERR_IMAGE_INVALID;
}
#if CONFIG_IDF_TARGET_ESP32S2BETA
// Adjust image length result to include the appended signature
data->image_len = end - data->start_addr + sizeof(ets_secure_boot_signature_t);
#endif
return ESP_OK;
}
@@ -691,13 +619,13 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i
bootloader_sha256_finish(sha_handle, image_hash);
// Log the hash for debugging
bootloader_debug_buffer(image_hash, HASH_LEN, "Calculated hash");
debug_log_hash(image_hash, "Calculated hash");
// Simple hash for verification only
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
if (memcmp(hash, image_hash, HASH_LEN) != 0) {
ESP_LOGE(TAG, "Image hash failed - image is corrupt");
bootloader_debug_buffer(hash, HASH_LEN, "Expected hash");
debug_log_hash(hash, "Expected hash");
bootloader_munmap(hash);
return ESP_ERR_IMAGE_INVALID;
}
@@ -705,3 +633,14 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i
bootloader_munmap(hash);
return ESP_OK;
}
// Log a hash as a hex string
static void debug_log_hash(const uint8_t *image_hash, const char *label)
{
#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
char hash_print[HASH_LEN * 2 + 1];
hash_print[HASH_LEN * 2] = 0;
bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN);
ESP_LOGD(TAG, "%s: %s", label, hash_print);
#endif
}

View File

@@ -13,53 +13,11 @@
// limitations under the License.
#include <strings.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_flash_encrypt.h"
#include "esp_secure_boot.h"
#ifndef BOOTLOADER_BUILD
static const char *TAG = "flash_encrypt";
void esp_flash_encryption_init_checks()
{
esp_flash_enc_mode_t mode;
// First check is: if Release mode flash encryption & secure boot are enabled then
// FLASH_CRYPT_CNT *must* be write protected. This will have happened automatically
// if bootloader is IDF V4.0 or newer but may not have happened for previous ESP-IDF bootloaders.
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
#ifdef CONFIG_SECURE_BOOT_ENABLED
if (esp_secure_boot_enabled() && esp_flash_encryption_enabled()) {
uint8_t flash_crypt_cnt_wr_dis = 0;
esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
if (!flash_crypt_cnt_wr_dis) {
ESP_EARLY_LOGE(TAG, "Flash encryption & Secure Boot together requires FLASH_CRYPT_CNT efuse to be write protected. Fixing now...");
esp_flash_write_protect_crypt_cnt();
}
}
#endif // CONFIG_SECURE_BOOT_ENABLED
#endif // CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
// Second check is to print a warning or error if the current running flash encryption mode
// doesn't match the expectation from project config (due to mismatched bootloader and app, probably)
mode = esp_get_flash_encryption_mode();
if (mode == ESP_FLASH_ENC_MODE_DEVELOPMENT) {
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
ESP_EARLY_LOGE(TAG, "Flash encryption settings error: app is configured for RELEASE but efuses are set for DEVELOPMENT");
ESP_EARLY_LOGE(TAG, "Mismatch found in security options in bootloader menuconfig and efuse settings. Device is not secure.");
#else
ESP_EARLY_LOGW(TAG, "Flash encryption mode is DEVELOPMENT (not secure)");
#endif
} else if (mode == ESP_FLASH_ENC_MODE_RELEASE) {
ESP_EARLY_LOGI(TAG, "Flash encryption mode is RELEASE");
}
}
#endif
void esp_flash_write_protect_crypt_cnt(void)
void esp_flash_write_protect_crypt_cnt()
{
uint8_t flash_crypt_cnt_wr_dis = 0;
esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
@@ -68,7 +26,7 @@ void esp_flash_write_protect_crypt_cnt(void)
}
}
esp_flash_enc_mode_t esp_get_flash_encryption_mode(void)
esp_flash_enc_mode_t esp_get_flash_encryption_mode()
{
uint8_t efuse_flash_crypt_cnt_wr_protected = 0;
uint8_t dis_dl_enc = 0, dis_dl_dec = 0, dis_dl_cache = 0;

View File

@@ -16,26 +16,14 @@
#include "flash_qio_mode.h"
#include "esp_log.h"
#include "esp_err.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/spi_flash.h"
#include "esp32/rom/efuse.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/spi_flash.h"
#include "esp32s2beta/rom/efuse.h"
#include "soc/spi_mem_struct.h"
#endif
#include "soc/spi_struct.h"
#include "soc/spi_reg.h"
#include "soc/spi_periph.h"
#include "soc/efuse_periph.h"
#include "soc/io_mux_reg.h"
#include "sdkconfig.h"
/* SPI flash controller */
#if CONFIG_IDF_TARGET_ESP32
#define SPIFLASH SPI1
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#define SPIFLASH SPIMEM1
#endif
/* SPI commands (actual on-wire commands not SPI controller bitmasks)
Suitable for use with the execute_flash_command static function.
@@ -51,11 +39,10 @@
static const char *TAG = "qio_mode";
typedef unsigned (*read_status_fn_t)(void);
typedef unsigned (*read_status_fn_t)();
typedef void (*write_status_fn_t)(unsigned);
typedef struct __attribute__((packed))
{
typedef struct __attribute__((packed)) {
const char *manufacturer;
uint8_t mfg_id; /* 8-bit JEDEC manufacturer ID */
uint16_t flash_id; /* 16-bit JEDEC flash chip ID */
@@ -66,11 +53,11 @@ typedef struct __attribute__((packed))
} qio_info_t;
/* Read 8 bit status using RDSR command */
static unsigned read_status_8b_rdsr(void);
static unsigned read_status_8b_rdsr();
/* Read 8 bit status (second byte) using RDSR2 command */
static unsigned read_status_8b_rdsr2(void);
static unsigned read_status_8b_rdsr2();
/* read 16 bit status using RDSR & RDSR2 (low and high bytes) */
static unsigned read_status_16b_rdsr_rdsr2(void);
static unsigned read_status_16b_rdsr_rdsr2();
/* Write 8 bit status using WRSR */
static void write_status_8b_wrsr(unsigned new_status);
@@ -80,7 +67,7 @@ static void write_status_8b_wrsr2(unsigned new_status);
static void write_status_16b_wrsr(unsigned new_status);
/* Read 8 bit status of XM25QU64A */
static unsigned read_status_8b_xmc25qu64a(void);
static unsigned read_status_8b_xmc25qu64a();
/* Write 8 bit status of XM25QU64A */
static void write_status_8b_xmc25qu64a(unsigned new_status);
@@ -103,7 +90,7 @@ static void write_status_8b_xmc25qu64a(unsigned new_status);
Searching of this table stops when the first match is found.
*/
const static qio_info_t chip_data[] = {
/* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */
/* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */
{ "MXIC", 0xC2, 0x2000, 0xFF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 },
{ "ISSI", 0x9D, 0x4000, 0xCF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, /* IDs 0x40xx, 0x70xx */
{ "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
@@ -122,8 +109,8 @@ const static qio_info_t chip_data[] = {
#define NUM_CHIPS (sizeof(chip_data) / sizeof(qio_info_t))
static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
write_status_fn_t write_status_fn,
uint8_t status_qio_bit);
write_status_fn_t write_status_fn,
uint8_t status_qio_bit);
/* Generic function to use the "user command" SPI controller functionality
to send commands to the SPI flash and read the respopnse.
@@ -134,53 +121,13 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8
/* dummy_len_plus values defined in ROM for SPI flash configuration */
extern uint8_t g_rom_spiflash_dummy_len_plus[];
uint32_t bootloader_read_flash_id(void)
uint32_t bootloader_read_flash_id()
{
uint32_t id = execute_flash_command(CMD_RDID, 0, 0, 24);
id = ((id & 0xff) << 16) | ((id >> 16) & 0xff) | (id & 0xff00);
return id;
}
#if CONFIG_IDF_TARGET_ESP32S2BETA
#define FLASH_WRAP_CMD 0x77
typedef enum {
FLASH_WRAP_MODE_8B = 0,
FLASH_WRAP_MODE_16B = 2,
FLASH_WRAP_MODE_32B = 4,
FLASH_WRAP_MODE_64B = 6,
FLASH_WRAP_MODE_DISABLE = 1
} spi_flash_wrap_mode_t;
static esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
uint32_t reg_bkp_usr = SPIFLASH.user.val;
SPIFLASH.user.fwrite_dio = 0;
SPIFLASH.user.fwrite_dual = 0;
SPIFLASH.user.fwrite_qio = 1;
SPIFLASH.user.fwrite_quad = 0;
SPIFLASH.ctrl.fcmd_dual = 0;
SPIFLASH.ctrl.fcmd_quad = 0;
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 1;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD;
SPIFLASH.user1.usr_addr_bitlen = 23;
SPIFLASH.addr = 0;
SPIFLASH.user.usr_miso = 0;
SPIFLASH.user.usr_mosi = 1;
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
SPIFLASH.cmd.usr = 1;
while (SPIFLASH.cmd.usr != 0) {
}
SPIFLASH.ctrl.val = reg_bkp_ctrl;
SPIFLASH.user.val = reg_bkp_usr;
return ESP_OK;
}
#endif
void bootloader_enable_qio_mode(void)
{
uint32_t raw_flash_id;
@@ -198,7 +145,7 @@ void bootloader_enable_qio_mode(void)
flash_id = raw_flash_id & 0xFFFF;
ESP_LOGD(TAG, "Manufacturer ID 0x%02x chip ID 0x%04x", mfg_id, flash_id);
for (i = 0; i < NUM_CHIPS - 1; i++) {
for (i = 0; i < NUM_CHIPS-1; i++) {
const qio_info_t *chip = &chip_data[i];
if (mfg_id == chip->mfg_id && (flash_id & chip->id_mask) == (chip->flash_id & chip->id_mask)) {
ESP_LOGI(TAG, "Enabling QIO for flash chip %s", chip_data[i].manufacturer);
@@ -209,22 +156,19 @@ void bootloader_enable_qio_mode(void)
if (i == NUM_CHIPS - 1) {
ESP_LOGI(TAG, "Enabling default flash chip QIO");
}
enable_qio_mode(chip_data[i].read_status_fn,
chip_data[i].write_status_fn,
chip_data[i].status_qio_bit);
#if CONFIG_IDF_TARGET_ESP32S2BETA
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
#endif
}
static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
write_status_fn_t write_status_fn,
uint8_t status_qio_bit)
write_status_fn_t write_status_fn,
uint8_t status_qio_bit)
{
uint32_t status;
const uint32_t spiconfig = ets_efuse_get_spiconfig();
#if CONFIG_IDF_TARGET_ESP32
if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
// spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP,
// which is compiled into the bootloader instead.
@@ -234,28 +178,27 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
//assignment from that chip's WP pin.
uint32_t pkg_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
if (CONFIG_BOOTLOADER_SPI_WP_PIN != ESP32_D2WD_WP_GPIO &&
(pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 ||
pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 ||
pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) {
(pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 ||
pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 ||
pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) {
ESP_LOGW(TAG, "Chip is ESP32-D2WD/ESP32-PICOD4 but flash WP pin is different value to internal flash");
}
}
#endif
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
status = read_status_fn();
ESP_LOGD(TAG, "Initial flash chip status 0x%x", status);
if ((status & (1 << status_qio_bit)) == 0) {
if ((status & (1<<status_qio_bit)) == 0) {
execute_flash_command(CMD_WREN, 0, 0, 0);
write_status_fn(status | (1 << status_qio_bit));
write_status_fn(status | (1<<status_qio_bit));
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
status = read_status_fn();
ESP_LOGD(TAG, "Updated flash chip status 0x%x", status);
if ((status & (1 << status_qio_bit)) == 0) {
if ((status & (1<<status_qio_bit)) == 0) {
ESP_LOGE(TAG, "Failed to set QIE bit, not enabling QIO mode");
return ESP_FAIL;
}
@@ -275,29 +218,22 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
esp_rom_spiflash_config_readmode(mode);
#if CONFIG_IDF_TARGET_ESP32
esp_rom_spiflash_select_qio_pins(CONFIG_BOOTLOADER_SPI_WP_PIN, spiconfig);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
if (ets_efuse_get_wp_pad() <= MAX_PAD_GPIO_NUM) {
esp_rom_spiflash_select_qio_pins(ets_efuse_get_wp_pad(), spiconfig);
} else {
esp_rom_spiflash_select_qio_pins(CONFIG_BOOTLOADER_SPI_WP_PIN, spiconfig);
}
#endif
return ESP_OK;
}
static unsigned read_status_8b_rdsr(void)
static unsigned read_status_8b_rdsr()
{
return execute_flash_command(CMD_RDSR, 0, 0, 8);
}
static unsigned read_status_8b_rdsr2(void)
static unsigned read_status_8b_rdsr2()
{
return execute_flash_command(CMD_RDSR2, 0, 0, 8);
}
static unsigned read_status_16b_rdsr_rdsr2(void)
static unsigned read_status_16b_rdsr_rdsr2()
{
return execute_flash_command(CMD_RDSR, 0, 0, 8) | (execute_flash_command(CMD_RDSR2, 0, 0, 8) << 8);
}
@@ -317,7 +253,7 @@ static void write_status_16b_wrsr(unsigned new_status)
execute_flash_command(CMD_WRSR, new_status, 16, 0);
}
static unsigned read_status_8b_xmc25qu64a(void)
static unsigned read_status_8b_xmc25qu64a()
{
execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
@@ -338,11 +274,7 @@ static void write_status_8b_xmc25qu64a(unsigned new_status)
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
{
uint32_t old_ctrl_reg = SPIFLASH.ctrl.val;
#if CONFIG_IDF_TARGET_ESP32
SPIFLASH.ctrl.val = SPI_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
#elif CONFIG_IDF_TARGET_ESP32S2BETA
SPIFLASH.ctrl.val = SPI_MEM_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
#endif
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 0;
SPIFLASH.user.usr_command = 1;
@@ -350,17 +282,9 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8
SPIFLASH.user2.usr_command_value = command;
SPIFLASH.user.usr_miso = miso_len > 0;
#if CONFIG_IDF_TARGET_ESP32
SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
SPIFLASH.miso_dlen.usr_miso_bit_len = miso_len ? (miso_len - 1) : 0;
#endif
SPIFLASH.user.usr_mosi = mosi_len > 0;
#if CONFIG_IDF_TARGET_ESP32
SPIFLASH.mosi_dlen.usr_mosi_dbitlen = mosi_len ? (mosi_len - 1) : 0;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
SPIFLASH.mosi_dlen.usr_mosi_bit_len = mosi_len ? (mosi_len - 1) : 0;
#endif
SPIFLASH.data_buf[0] = mosi_data;
if (g_rom_spiflash_dummy_len_plus[1]) {
@@ -375,8 +299,8 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8
}
SPIFLASH.cmd.usr = 1;
while (SPIFLASH.cmd.usr != 0) {
}
while(SPIFLASH.cmd.usr != 0)
{ }
SPIFLASH.ctrl.val = old_ctrl_reg;
return SPIFLASH.data_buf[0];

View File

@@ -18,7 +18,7 @@
#include <sys/param.h>
#include <mbedtls/sha256.h>
bootloader_sha256_handle_t bootloader_sha256_start(void)
bootloader_sha256_handle_t bootloader_sha256_start()
{
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)malloc(sizeof(mbedtls_sha256_context));
if (!ctx) {

View File

@@ -56,10 +56,6 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest)
{
#if !(defined(CONFIG_MBEDTLS_ECDSA_C) && defined(CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED))
ESP_LOGE(TAG, "Signature verification requires ECDSA & SECP256R1 curve enabled");
return ESP_ERR_NOT_SUPPORTED;
#else
ptrdiff_t keylen;
keylen = signature_verification_key_end - signature_verification_key_start;
@@ -121,5 +117,4 @@ cleanup:
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa_context);
return ret == 0 ? ESP_OK : ESP_ERR_IMAGE_INVALID;
#endif // CONFIG_MBEDTLS_ECDSA_C && CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED
}

View File

@@ -5,6 +5,7 @@
#include <esp_types.h>
#include <stdio.h>
#include "string.h"
#include "esp32/rom/ets_sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -33,7 +34,6 @@ TEST_CASE("Verify bootloader image in flash", "[bootloader_support]")
TEST_ASSERT_EQUAL(data.image_len, bootloader_length);
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2BETA)
TEST_CASE("Verify unit test app image", "[bootloader_support]")
{
esp_image_metadata_t data = { 0 };
@@ -48,7 +48,6 @@ TEST_CASE("Verify unit test app image", "[bootloader_support]")
TEST_ASSERT_NOT_EQUAL(0, data.image_len);
TEST_ASSERT_TRUE(data.image_len <= running->size);
}
#endif
void check_label_search (int num_test, const char *list, const char *t_label, bool result)
{

View File

@@ -33,7 +33,6 @@ if(CONFIG_BT_ENABLED)
host/bluedroid/bta/av/include
host/bluedroid/bta/dm/include
host/bluedroid/bta/gatt/include
host/bluedroid/bta/hf_ag/include
host/bluedroid/bta/hf_client/include
host/bluedroid/bta/hh/include
host/bluedroid/bta/jv/include
@@ -75,7 +74,6 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/api/esp_gatt_common_api.c"
"host/bluedroid/api/esp_gattc_api.c"
"host/bluedroid/api/esp_gatts_api.c"
"host/bluedroid/api/esp_hf_ag_api.c"
"host/bluedroid/api/esp_hf_client_api.c"
"host/bluedroid/api/esp_spp_api.c"
"host/bluedroid/bta/ar/bta_ar.c"
@@ -118,15 +116,6 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/bta/jv/bta_jv_api.c"
"host/bluedroid/bta/jv/bta_jv_cfg.c"
"host/bluedroid/bta/jv/bta_jv_main.c"
"host/bluedroid/bta/hf_ag/bta_ag_act.c"
"host/bluedroid/bta/hf_ag/bta_ag_api.c"
"host/bluedroid/bta/hf_ag/bta_ag_at.c"
"host/bluedroid/bta/hf_ag/bta_ag_cfg.c"
"host/bluedroid/bta/hf_ag/bta_ag_cmd.c"
"host/bluedroid/bta/hf_ag/bta_ag_main.c"
"host/bluedroid/bta/hf_ag/bta_ag_rfc.c"
"host/bluedroid/bta/hf_ag/bta_ag_sco.c"
"host/bluedroid/bta/hf_ag/bta_ag_sdp.c"
"host/bluedroid/bta/hf_client/bta_hf_client_act.c"
"host/bluedroid/bta/hf_client/bta_hf_client_api.c"
"host/bluedroid/bta/hf_client/bta_hf_client_at.c"
@@ -162,8 +151,6 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/btc/profile/std/a2dp/btc_av.c"
"host/bluedroid/btc/profile/std/avrc/btc_avrc.c"
"host/bluedroid/btc/profile/std/avrc/bta_avrc_co.c"
"host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c"
"host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c"
"host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
"host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
"host/bluedroid/btc/profile/std/gap/btc_gap_ble.c"
@@ -302,23 +289,15 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/stack/smp/smp_l2c.c"
"host/bluedroid/stack/smp/smp_main.c"
"host/bluedroid/stack/smp/smp_utils.c")
if(CONFIG_BLE_MESH)
list(APPEND srcs "esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c")
endif()
endif()
if(CONFIG_BLE_MESH)
list(APPEND include_dirs
"esp_ble_mesh/mesh_common/include"
"esp_ble_mesh/mesh_core"
"esp_ble_mesh/mesh_core/include"
"esp_ble_mesh/mesh_core/storage"
"esp_ble_mesh/mesh_core/settings"
"esp_ble_mesh/btc/include"
"esp_ble_mesh/mesh_models/common/include"
"esp_ble_mesh/mesh_models/client/include"
"esp_ble_mesh/mesh_models/server/include"
"esp_ble_mesh/mesh_models/include"
"esp_ble_mesh/api/core/include"
"esp_ble_mesh/api/models/include"
"esp_ble_mesh/api")
@@ -342,13 +321,7 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/btc/btc_ble_mesh_prov.c"
"esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c"
"esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c"
"esp_ble_mesh/mesh_common/mesh_aes_encrypt.c"
"esp_ble_mesh/mesh_common/mesh_atomic.c"
"esp_ble_mesh/mesh_common/mesh_buf.c"
"esp_ble_mesh/mesh_common/mesh_common.c"
"esp_ble_mesh/mesh_common/mesh_kernel.c"
"esp_ble_mesh/mesh_common/mesh_util.c"
"esp_ble_mesh/mesh_core/storage/settings_nvs.c"
"esp_ble_mesh/mesh_core/settings/settings_nvs.c"
"esp_ble_mesh/mesh_core/access.c"
"esp_ble_mesh/mesh_core/adv.c"
"esp_ble_mesh/mesh_core/beacon.c"
@@ -359,30 +332,30 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/mesh_core/health_cli.c"
"esp_ble_mesh/mesh_core/health_srv.c"
"esp_ble_mesh/mesh_core/lpn.c"
"esp_ble_mesh/mesh_core/main.c"
"esp_ble_mesh/mesh_core/mesh_aes_encrypt.c"
"esp_ble_mesh/mesh_core/mesh_atomic.c"
"esp_ble_mesh/mesh_core/mesh_bearer_adapt.c"
"esp_ble_mesh/mesh_core/mesh_buf.c"
"esp_ble_mesh/mesh_core/mesh_hci.c"
"esp_ble_mesh/mesh_core/mesh_kernel.c"
"esp_ble_mesh/mesh_core/mesh_main.c"
"esp_ble_mesh/mesh_core/mesh_util.c"
"esp_ble_mesh/mesh_core/net.c"
"esp_ble_mesh/mesh_core/prov.c"
"esp_ble_mesh/mesh_core/provisioner_beacon.c"
"esp_ble_mesh/mesh_core/provisioner_main.c"
"esp_ble_mesh/mesh_core/provisioner_prov.c"
"esp_ble_mesh/mesh_core/proxy_client.c"
"esp_ble_mesh/mesh_core/proxy_server.c"
"esp_ble_mesh/mesh_core/provisioner_proxy.c"
"esp_ble_mesh/mesh_core/proxy.c"
"esp_ble_mesh/mesh_core/settings.c"
"esp_ble_mesh/mesh_core/test.c"
"esp_ble_mesh/mesh_core/transport.c"
"esp_ble_mesh/mesh_models/client/client_common.c"
"esp_ble_mesh/mesh_models/client/generic_client.c"
"esp_ble_mesh/mesh_models/client/lighting_client.c"
"esp_ble_mesh/mesh_models/client/sensor_client.c"
"esp_ble_mesh/mesh_models/client/time_scene_client.c"
"esp_ble_mesh/mesh_models/server/device_property.c"
"esp_ble_mesh/mesh_models/server/generic_server.c"
"esp_ble_mesh/mesh_models/server/lighting_server.c"
"esp_ble_mesh/mesh_models/server/sensor_server.c"
"esp_ble_mesh/mesh_models/server/server_common.c"
"esp_ble_mesh/mesh_models/server/state_binding.c"
"esp_ble_mesh/mesh_models/server/state_transition.c"
"esp_ble_mesh/mesh_models/server/time_scene_server.c")
"esp_ble_mesh/mesh_models/generic_client.c"
"esp_ble_mesh/mesh_models/lighting_client.c"
"esp_ble_mesh/mesh_models/mesh_common.c"
"esp_ble_mesh/mesh_models/model_common.c"
"esp_ble_mesh/mesh_models/sensor_client.c"
"esp_ble_mesh/mesh_models/time_scene_client.c")
endif()
if(CONFIG_BT_NIMBLE_ENABLED)
@@ -397,20 +370,15 @@ if(CONFIG_BT_ENABLED)
host/nimble/nimble/nimble/host/services/gap/include
host/nimble/nimble/nimble/host/services/gatt/include
host/nimble/nimble/nimble/host/services/ias/include
host/nimble/nimble/nimble/host/services/ipss/include
host/nimble/nimble/nimble/host/services/lls/include
host/nimble/nimble/nimble/host/services/tps/include
host/nimble/nimble/nimble/host/util/include
host/nimble/nimble/nimble/host/store/ram/include
host/nimble/nimble/nimble/host/store/config/include
host/nimble/nimble/porting/npl/freertos/include
host/nimble/nimble/ext/tinycrypt/include
host/nimble/esp-hci/include)
if(NOT CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS)
list(APPEND include_dirs
host/nimble/nimble/ext/tinycrypt/include)
list(APPEND srcs "host/nimble/nimble/ext/tinycrypt/src/utils.c"
"host/nimble/nimble/ext/tinycrypt/src/sha256.c"
"host/nimble/nimble/ext/tinycrypt/src/ecc.c"
@@ -425,14 +393,11 @@ if(CONFIG_BT_ENABLED)
"host/nimble/nimble/ext/tinycrypt/src/hmac_prng.c"
"host/nimble/nimble/ext/tinycrypt/src/ecc_platform_specific.c"
"host/nimble/nimble/ext/tinycrypt/src/hmac.c"
"host/nimble/nimble/ext/tinycrypt/src/cbc_mode.c")
endif()
list(APPEND srcs "host/nimble/nimble/nimble/host/util/src/addr.c"
"host/nimble/nimble/ext/tinycrypt/src/cbc_mode.c"
"host/nimble/nimble/nimble/host/util/src/addr.c"
"host/nimble/nimble/nimble/host/services/gatt/src/ble_svc_gatt.c"
"host/nimble/nimble/nimble/host/services/tps/src/ble_svc_tps.c"
"host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c"
"host/nimble/nimble/nimble/host/services/ipss/src/ble_svc_ipss.c"
"host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c"
"host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c"
"host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c"
@@ -454,7 +419,6 @@ if(CONFIG_BT_ENABLED)
"host/nimble/nimble/nimble/host/src/ble_hs_hci_evt.c"
"host/nimble/nimble/nimble/host/src/ble_hs_dbg.c"
"host/nimble/nimble/nimble/host/src/ble_hs_mqueue.c"
"host/nimble/nimble/nimble/host/src/ble_hs_periodic_sync.c"
"host/nimble/nimble/nimble/host/src/ble_att.c"
"host/nimble/nimble/nimble/host/src/ble_gattc.c"
"host/nimble/nimble/nimble/host/src/ble_store.c"
@@ -498,10 +462,6 @@ if(CONFIG_BT_ENABLED)
"host/nimble/nimble/porting/nimble/src/os_cputime.c"
"host/nimble/esp-hci/src/esp_nimble_hci.c")
if (CONFIG_BLE_MESH)
list(APPEND srcs "esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c")
endif()
if(CONFIG_BT_NIMBLE_MESH)
list(APPEND include_dirs
@@ -541,7 +501,9 @@ idf_component_register(SRCS "${srcs}"
REQUIRES nvs_flash soc)
if(CONFIG_BT_ENABLED)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
if(GCC_NOT_5_2_0)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
endif()
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/controller/lib")
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)

View File

@@ -1,8 +1,7 @@
menu "Bluetooth"
menu Bluetooth
config BT_ENABLED
bool "Bluetooth"
depends on IDF_TARGET_ESP32
help
Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices.
@@ -78,20 +77,6 @@ menu "Bluetooth"
default 1 if BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM
default 0
config BTDM_CTRL_AUTO_LATENCY
bool "Auto latency"
depends on BTDM_CTRL_MODE_BTDM
default n
help
BLE auto latency, used to enhance classic BT performance
while classic BT and BLE are enabled at the same time.
config BTDM_CTRL_AUTO_LATENCY_EFF
bool
default BTDM_CTRL_AUTO_LATENCY if BTDM_CTRL_MODE_BTDM
default n
config BTDM_CTRL_BLE_MAX_CONN_EFF
int
default BTDM_CTRL_BLE_MAX_CONN if BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM
@@ -333,8 +318,8 @@ menu "Bluetooth"
config BTDM_CTRL_FULL_SCAN_SUPPORTED
bool "BLE full scan feature supported"
depends on BTDM_CONTROLLER_MODE_BLE_ONLY || BTDM_CONTROLLER_MODE_BTDM
default y
depends on BTDM_CTRL_MODE_BLE_ONLY
default n
help
The full scan function is mainly used to provide BLE scan performance.
This is required for scenes with high scan performance requirements, such as BLE Mesh scenes.
@@ -373,21 +358,6 @@ menu "Bluetooth"
If you set `BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
may cause adv packets lost more.
menuconfig BTDM_COEX_BT_OPTIONS
bool "Coexistence Bluetooth Side Options"
depends on ESP32_WIFI_SW_COEXIST_ENABLE
default n
help
Options of Bluetooth Side of WiFi and bluetooth coexistence.
config BTDM_COEX_BLE_ADV_HIGH_PRIORITY
bool "Improve BLE ADV priority for WiFi & BLE coexistence"
depends on BTDM_COEX_BT_OPTIONS
default n
help
Improve BLE ADV coexistence priority to make it better performance.
For example, BLE mesh need to enable this option to improve BLE adv performance.
endmenu
choice BT_HOST
@@ -408,13 +378,6 @@ menu "Bluetooth"
help
This option is recommended for BLE only usecases to save on memory
config BT_CONTROLLER_ONLY
bool "Controller Only"
help
This option is recommended when you want to communicate directly with the
controller (without any host) or when you are using any other host stack
not supported by Espressif (not mentioned here).
endchoice
menu "Bluedroid Options"
@@ -432,6 +395,7 @@ endmenu
menuconfig BLE_MESH
bool "ESP BLE Mesh Support"
depends on BT_BLUEDROID_ENABLED
help
This option enables ESP BLE Mesh support. The specific features that are
available may depend on other features that have been enabled in the

View File

@@ -19,7 +19,6 @@
#include "esp_log.h"
#include "bt_common.h"
#include "osi/allocator.h"
#include "btc/btc_alarm.h"
#ifdef CONFIG_BT_BLUEDROID_ENABLED
#include "common/bt_target.h"
@@ -33,6 +32,7 @@
#include "btc_blufi_prf.h"
#include "blufi_int.h"
#include "btc/btc_dm.h"
#include "btc/btc_alarm.h"
#include "bta/bta_gatt_api.h"
#if CLASSIC_BT_INCLUDED
#include "btc/btc_profile_queue.h"
@@ -47,9 +47,6 @@
#if (BTC_SPP_INCLUDED == TRUE)
#include "btc_spp.h"
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
#if BTC_HF_INCLUDED
#include "btc_hf_ag.h"
#endif/* #if BTC_HF_INCLUDED */
#if BTC_HF_CLIENT_INCLUDED
#include "btc_hf_client.h"
#endif /* #if BTC_HF_CLIENT_INCLUDED */
@@ -97,9 +94,7 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
[BTC_PID_BLUFI] = {btc_blufi_call_handler, btc_blufi_cb_handler },
#endif ///GATTS_INCLUDED == TRUE
[BTC_PID_DM_SEC] = {NULL, btc_dm_sec_cb_handler },
#endif
[BTC_PID_ALARM] = {btc_alarm_handler, NULL },
#ifdef CONFIG_BT_BLUEDROID_ENABLED
#if CLASSIC_BT_INCLUDED
#if (BTC_GAP_BT_INCLUDED == TRUE)
[BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, btc_gap_bt_cb_handler },
@@ -113,29 +108,22 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
#if (BTC_SPP_INCLUDED == TRUE)
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
#if BTC_HF_INCLUDED
[BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler},
#endif /* #if BTC_HF_INCLUDED */
#if BTC_HF_CLIENT_INCLUDED
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
#endif /* #if BTC_HF_CLIENT_INCLUDED */
#endif /* #if CLASSIC_BT_INCLUDED */
#endif
#if CONFIG_BLE_MESH
[BTC_PID_PROV] = {btc_ble_mesh_prov_call_handler, btc_ble_mesh_prov_cb_handler },
[BTC_PID_MODEL] = {btc_ble_mesh_model_call_handler, btc_ble_mesh_model_cb_handler },
[BTC_PID_HEALTH_CLIENT] = {btc_ble_mesh_health_client_call_handler, btc_ble_mesh_health_client_cb_handler },
[BTC_PID_HEALTH_SERVER] = {btc_ble_mesh_health_server_call_handler, btc_ble_mesh_health_server_cb_handler },
[BTC_PID_CONFIG_CLIENT] = {btc_ble_mesh_config_client_call_handler, btc_ble_mesh_config_client_cb_handler },
[BTC_PID_CONFIG_SERVER] = {NULL, btc_ble_mesh_config_server_cb_handler },
[BTC_PID_GENERIC_CLIENT] = {btc_ble_mesh_generic_client_call_handler, btc_ble_mesh_generic_client_cb_handler },
[BTC_PID_LIGHTING_CLIENT] = {btc_ble_mesh_lighting_client_call_handler, btc_ble_mesh_lighting_client_cb_handler },
[BTC_PID_SENSOR_CLIENT] = {btc_ble_mesh_sensor_client_call_handler, btc_ble_mesh_sensor_client_cb_handler },
[BTC_PID_TIME_SCENE_CLIENT] = {btc_ble_mesh_time_scene_client_call_handler, btc_ble_mesh_time_scene_client_cb_handler},
[BTC_PID_GENERIC_SERVER] = {NULL, btc_ble_mesh_generic_server_cb_handler },
[BTC_PID_LIGHTING_SERVER] = {NULL, btc_ble_mesh_lighting_server_cb_handler },
[BTC_PID_SENSOR_SERVER] = {NULL, btc_ble_mesh_sensor_server_cb_handler },
[BTC_PID_TIME_SCENE_SERVER] = {NULL, btc_ble_mesh_time_scene_server_cb_handler},
[BTC_PID_PROV] = {btc_mesh_prov_call_handler, btc_mesh_prov_cb_handler},
[BTC_PID_MODEL] = {btc_mesh_model_call_handler, btc_mesh_model_cb_handler},
[BTC_PID_HEALTH_CLIENT] = {btc_mesh_health_client_call_handler, btc_mesh_health_client_cb_handler},
[BTC_PID_HEALTH_SERVER] = {btc_mesh_health_server_call_handler, btc_mesh_health_server_cb_handler},
[BTC_PID_CFG_CLIENT] = {btc_mesh_cfg_client_call_handler, btc_mesh_cfg_client_cb_handler},
[BTC_PID_CFG_SERVER] = {NULL , btc_mesh_cfg_server_cb_handler},
[BTC_PID_GENERIC_CLIENT] = {btc_mesh_generic_client_call_handler, btc_mesh_generic_client_cb_handler},
[BTC_PID_LIGHT_CLIENT] = {btc_mesh_light_client_call_handler, btc_mesh_light_client_cb_handler},
[BTC_PID_SENSOR_CLIENT] = {btc_mesh_sensor_client_call_handler, btc_mesh_sensor_client_cb_handler},
[BTC_PID_TIME_SCENE_CLIENT] = {btc_mesh_time_scene_client_call_handler, btc_mesh_time_scene_client_cb_handler},
#endif /* #if CONFIG_BLE_MESH */
};
@@ -333,7 +321,7 @@ error_exit:;
int btc_init(void)
{
btc_thread = osi_thread_create("BTC_TASK", BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, 2);
btc_thread = osi_thread_create("BTC_TASK", BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, 3);
if (btc_thread == NULL) {
return BT_STATUS_NOMEM;
}

View File

@@ -15,7 +15,9 @@
#ifndef __BTC_MANAGE_H__
#define __BTC_MANAGE_H__
#include "bta/bta_api.h"
#include "btc/btc_task.h"
#include "esp_bt_defs.h"
#if BTC_DYNAMIC_MEMORY == FALSE
extern void *btc_profile_cb_tab[BTC_PID_NUM];

Some files were not shown because too many files have changed in this diff Show More