diff -Nru esptool-4.6.2+dfsg/.cz.toml esptool-4.7.0+dfsg/.cz.toml --- esptool-4.6.2+dfsg/.cz.toml 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/.cz.toml 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,24 @@ +[tool.commitizen] +version = "4.7.0" +update_changelog_on_bump = true +tag_format = "v$version" +changelog_start_rev = "v4.2.1" +changelog_merge_prerelease = true +annotated_tag = true +bump_message = "change: Update version to $new_version" +version_files = [ + "esptool/__init__.py:__version__" +] +change_type_order = [ + "BREAKING CHANGE", + "New Features", + "Bug Fixes", + "Code Refactoring", + "Performance Improvements" +] + +[tool.commitizen.change_type_map] +feat = "New Features" +fix = "Bug Fixes" +refactor = "Code Refactoring" +perf = "Performance Improvements" \ No newline at end of file diff -Nru esptool-4.6.2+dfsg/.github/pull_request_template.md esptool-4.7.0+dfsg/.github/pull_request_template.md --- esptool-4.6.2+dfsg/.github/pull_request_template.md 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/.github/pull_request_template.md 2023-12-13 11:05:18.000000000 +0000 @@ -1,15 +1,20 @@ -(Please delete any lines which don't apply) - -# Description of change + # This change fixes the following bug(s): + # I have tested this change with the following hardware & software combinations: + -(Operating system(s), development board name(s), ESP8266 and/or ESP32.) +# I have run the esptool.py automated integration tests with this change and the above hardware: + diff -Nru esptool-4.6.2+dfsg/.github/workflows/build_esptool.yml esptool-4.7.0+dfsg/.github/workflows/build_esptool.yml --- esptool-4.6.2+dfsg/.github/workflows/build_esptool.yml 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/.github/workflows/build_esptool.yml 2023-12-13 11:05:18.000000000 +0000 @@ -31,8 +31,8 @@ container: ${{ matrix.CONTAINER }} # use python container on ARM env: DISTPATH: esptool-${{ matrix.TARGET }} - STUBS_DIR: /esptool/targets/stub_flasher/ - EFUSE_DIR: /espefuse/efuse_defs/ + STUBS_DIR: ./esptool/targets/stub_flasher/ + EFUSE_DIR: ./espefuse/efuse_defs/ PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi" steps: - name: Checkout repository @@ -50,8 +50,8 @@ pip install --user -e . - name: Build with PyInstaller run: | - pyinstaller --distpath ./${{ env.DISTPATH }} -F --icon=ci/espressif.ico --add-data=".${{ env.STUBS_DIR }}*.json${{ matrix.SEPARATOR }}${{ env.STUBS_DIR }}" esptool.py - pyinstaller --distpath ./${{ env.DISTPATH }} -F --icon=ci/espressif.ico --add-data=".${{ env.EFUSE_DIR }}*.yaml${{ matrix.SEPARATOR }}${{ env.EFUSE_DIR }}" espefuse.py + pyinstaller --distpath ./${{ env.DISTPATH }} -F --icon=ci/espressif.ico --add-data="${{ env.STUBS_DIR }}*.json${{ matrix.SEPARATOR }}${{ env.STUBS_DIR }}" esptool.py + pyinstaller --distpath ./${{ env.DISTPATH }} -F --icon=ci/espressif.ico --add-data="${{ env.EFUSE_DIR }}*.yaml${{ matrix.SEPARATOR }}${{ env.EFUSE_DIR }}" espefuse.py pyinstaller --distpath ./${{ env.DISTPATH }} -F --icon=ci/espressif.ico espsecure.py pyinstaller --distpath ./${{ env.DISTPATH }} -F --icon=ci/espressif.ico esp_rfc2217_server.py - name: Sign binaries @@ -83,52 +83,43 @@ create_release: name: Create GitHub release - if: startsWith(github.ref, 'refs/tags/') + if: startsWith(github.ref, 'refs/tags/') && !(contains(github.ref_name, 'dev')) needs: build-esptool-binaries runs-on: ubuntu-latest - outputs: - upload_url: ${{ steps.create_release.outputs.upload_url }} - VERSION: ${{ steps.get_version.outputs.VERSION }} + permissions: + contents: write steps: - - name: Create release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Version ${{ github.ref }} - draft: true - prerelease: false - name: Get version id: get_version - run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT shell: bash - - upload_assets: - name: Upload release assets - if: startsWith(github.ref, 'refs/tags/') - needs: create_release - runs-on: ubuntu-latest - strategy: - matrix: - TARGET: [macos, linux-amd64, win64, arm, arm64] - env: - DISTPATH: esptool-${{ needs.create_release.outputs.VERSION }}-${{ matrix.TARGET }} - steps: + - name: Checkout + uses: actions/checkout@master + with: + fetch-depth: 0 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install --user -e ".[dev]" + - name: Generate changelog + run: | + cz changelog ${{ steps.get_version.outputs.VERSION }} --template ci/gh_changelog_template.md.j2 --file-name changelog_body.md + cat changelog_body.md - name: Download built binaries uses: actions/download-artifact@master - - name: Rename and package binaries + - name: Compress and rename binaries run: | - mv esptool-${{ matrix.TARGET }} ${{ env.DISTPATH }} - zip -r ${{ env.DISTPATH }}.zip ./${{ env.DISTPATH }}/* - - name: Upload release assets - id: upload-release-asset - uses: actions/upload-release-asset@v1 + for dir in esptool-*; do + zip -r "esptool-v${{ steps.get_version.outputs.VERSION }}-${dir#esptool-}.zip" "$dir" + done + - name: Create release + id: create_release + uses: softprops/action-gh-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - upload_url: ${{ needs.create_release.outputs.upload_url }} - asset_path: "${{ env.DISTPATH }}.zip" - asset_name: "${{ env.DISTPATH }}.zip" - asset_content_type: application/zip + body_path: changelog_body.md + name: Version ${{ steps.get_version.outputs.VERSION }} + draft: true + prerelease: false + files: esptool-v${{ steps.get_version.outputs.VERSION }}-*.zip diff -Nru esptool-4.6.2+dfsg/.github/workflows/dangerjs.yml esptool-4.7.0+dfsg/.github/workflows/dangerjs.yml --- esptool-4.6.2+dfsg/.github/workflows/dangerjs.yml 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/.github/workflows/dangerjs.yml 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,25 @@ +name: DangerJS Pull Request linter +on: + pull_request_target: + types: [opened, edited, reopened, synchronize] + +permissions: + pull-requests: write + contents: write + +jobs: + pull-request-style-linter: + runs-on: ubuntu-latest + steps: + - name: Check out PR head + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: DangerJS pull request linter + uses: espressif/shared-github-dangerjs@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + instructions-contributions-file: 'CONTRIBUTING.rst' + instructions-gitlab-mirror: 'true' diff -Nru esptool-4.6.2+dfsg/.github/workflows/dev_release_esptool_pypi.yml esptool-4.7.0+dfsg/.github/workflows/dev_release_esptool_pypi.yml --- esptool-4.6.2+dfsg/.github/workflows/dev_release_esptool_pypi.yml 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/.github/workflows/dev_release_esptool_pypi.yml 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,42 @@ +# This workflow will upload an esptool Python package when a dev release tag (e.g. "v4.7.dev2") is pushed + +name: PyPI dev release + +on: + push: + tags: + - v*.*.dev* + +jobs: + build_and_upload: + + runs-on: ubuntu-latest + + if: startsWith(github.ref, 'refs/tags/') && contains(github.ref_name, 'dev') + + steps: + - uses: actions/checkout@master + - name: Set up Python 3.8 + uses: actions/setup-python@master + with: + python-version: '3.8' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install twine setuptools + + - name: Create development release ${{ github.ref_name }} + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + TWINE_NON_INTERACTIVE: true + run: | + DEV_VERSION=$(echo "${{ github.ref_name }}" | grep -oE 'dev[0-9]+' | sed 's/dev//') + python ci/patch_dev_release.py --dev-no ${DEV_VERSION} esptool/__init__.py + git diff + python -m pip download esptool==$(python setup.py -V) && echo "Version ${{ github.ref_name }} already published, skipping..." && exit 1 + + echo "Packaging and publishing new esptool development release: ${{ github.ref_name }}" + python setup.py sdist + tar -ztvf dist/* + twine upload dist/* diff -Nru esptool-4.6.2+dfsg/.github/workflows/test_esptool.yml esptool-4.7.0+dfsg/.github/workflows/test_esptool.yml --- esptool-4.6.2+dfsg/.github/workflows/test_esptool.yml 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/.github/workflows/test_esptool.yml 2023-12-13 11:05:18.000000000 +0000 @@ -8,7 +8,7 @@ strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10'] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] steps: - name: Checkout ref commit @@ -19,6 +19,11 @@ with: python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools + - name: SoftHSM2 setup run: | sudo apt-get update @@ -28,23 +33,19 @@ sudo chown -R $(whoami) /var/lib/softhsm ./ci/setup_softhsm2.sh || exit 1 - - name: Test python components (fast) + - name: Install esptool and check if the installed versions can run run: | python setup.py build pip install --extra-index-url https://dl.espressif.com/pypi -e .[dev,hsm] - pytest test/test_imagegen.py - pytest test/test_espsecure.py - pytest test/test_espsecure_hsm.py - pytest test/test_merge_bin.py - pytest test/test_image_info.py - pytest test/test_modules.py - - - name: Check the installed versions can run - run: | esptool.py --help espefuse.py --help espsecure.py --help + - name: Test esptool and components + run: | + pytest -m host_test + pytest test/test_espsecure_hsm.py + - name: Build stub (Python 3.7 only) if: matrix.python-version == 3.7 run: | diff -Nru esptool-4.6.2+dfsg/.gitlab-ci.yml esptool-4.7.0+dfsg/.gitlab-ci.yml --- esptool-4.6.2+dfsg/.gitlab-ci.yml 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/.gitlab-ci.yml 2023-12-13 11:05:18.000000000 +0000 @@ -2,12 +2,27 @@ # # Note: When updating, please also update test_esptool.yml GH Actions workflow file stages: + - pre-check - test - report - build_docs - deploy_docs - deploy_development_package +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"' + when: never + - if: '$CI_COMMIT_BRANCH' + +include: + - project: espressif/shared-ci-dangerjs + ref: master + file: danger.yaml +run-danger-mr-linter: + stage: pre-check + # cache the pip download directory in all jobs variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" @@ -28,8 +43,8 @@ version_check: <<: *test_template - only: - - tags + rules: + - if: '$CI_COMMIT_TAG != null' script: - VERSION=$(esptool.py version | head -n 1) - | @@ -50,6 +65,15 @@ reports: junit: test/report.xml +check_uf2_ids: + <<: *host_tests_template + allow_failure: true + variables: + COVERAGE_PROCESS_START: "${CI_PROJECT_DIR}/test/.covconf" + PYTEST_ADDOPTS: "-sv --junitxml=test/report.xml --color=yes" + script: + - coverage run -m pytest ${CI_PROJECT_DIR}/test/test_uf2_ids.py + host_tests: <<: *host_tests_template variables: @@ -71,6 +95,7 @@ - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_espefuse.py --chip esp32h2beta1 - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_espefuse.py --chip esp32c6 - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_espefuse.py --chip esp32h2 + - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_espefuse.py --chip esp32p4 # some .coverage files in sub-directories are not collected on some runners, move them first - find . -mindepth 2 -type f -name ".coverage*" -print -exec mv --backup=numbered {} . \; @@ -257,6 +282,8 @@ extends: .target_esptool_test tags: - esptool_esp32c3_target + variables: + ESPTOOL_TEST_SPI_CONN: "6,2,7,4,10" script: - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_esptool.py --port /dev/serial_ports/ESP32C3 --chip esp32c3 --baud 115200 @@ -275,10 +302,19 @@ script: - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_esptool.py --port /dev/serial_ports/ESP32S3 --chip esp32s3 --baud 115200 -target_esp32s3_32MB: +target_esp32s3_32MB_octal: + extends: .target_esptool_test + tags: + - esptool_esp32s3_32MB_octal_target + variables: + ESPTOOL_TEST_FLASH_SIZE: "32" + script: + - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_esptool.py --port /dev/serial_ports/ESP32S3_32MB --chip esp32s3 --baud 115200 + +target_esp32s3_32MB_quad: extends: .target_esptool_test tags: - - esptool_esp32s3_32MB_target + - esptool_esp32s3_32MB_quad_target variables: ESPTOOL_TEST_FLASH_SIZE: "32" script: @@ -295,6 +331,8 @@ extends: .target_esptool_test tags: - esptool_esp32s3_jtag_serial_target + variables: + ESPTOOL_TEST_SPI_CONN: "12,13,11,9,10" script: - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_esptool.py --port /dev/serial_ports/ESP32S3_JTAG_SERIAL --preload-port /dev/serial_ports/ESP32S3_PRELOAD --chip esp32s3 --baud 115200 @@ -413,8 +451,8 @@ image: python:3.7-bullseye tags: - build_docs - only: - changes: + rules: + - changes: - "docs/**/*" - "CONTRIBUTING.rst" needs: [] @@ -436,10 +474,6 @@ - deploy needs: - build_docs - only: - changes: - - "docs/**/*" - - "CONTRIBUTING.rst" script: - source ${CI_PROJECT_DIR}/docs/utils.sh - add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER @@ -450,9 +484,12 @@ deploy_docs_preview: extends: - .deploy_docs_template - except: - refs: - - master + rules: + - if: '$CI_COMMIT_REF_NAME == "master"' + when: never + - changes: + - "docs/**/*" + - "CONTRIBUTING.rst" variables: TYPE: "preview" DOCS_BUILD_DIR: "${CI_PROJECT_DIR}/docs/_build/" @@ -465,9 +502,11 @@ deploy_docs_production: extends: - .deploy_docs_template - only: - refs: - - master + rules: + - if: '$CI_COMMIT_REF_NAME == "master"' + changes: + - "docs/**/*" + - "CONTRIBUTING.rst" variables: TYPE: "production" DOCS_BUILD_DIR: "${CI_PROJECT_DIR}/docs/_build/" @@ -476,25 +515,3 @@ DOCS_DEPLOY_SERVER_USER: "$DOCS_PROD_SERVER_USER" DOCS_DEPLOY_PATH: "$DOCS_PROD_PATH" DOCS_DEPLOY_URL_BASE: "https://docs.espressif.com/projects/esptool" - -deploy_dev_package: - <<: *test_template - rules: - - if: $CI_DEV_PUBLISH != null && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - variables: - TWINE_NON_INTERACTIVE: "true" - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${PYPI_ESPTOOL_TOKEN} - stage: deploy_development_package - dependencies: [] - script: - - python -m pip install --upgrade pip - - python -m pip install twine setuptools - - python ci/patch_dev_release.py --dev-no ${CI_DEV_PUBLISH} esptool/__init__.py - # check what has been changed with git - - git diff - - python setup.py sdist - # skip release if it has already been released (with failure) - - python -m pip download esptool==$(python setup.py -V) && exit 1 - - tar -ztvf dist/* - - python -m twine upload dist/* diff -Nru esptool-4.6.2+dfsg/.pre-commit-config.yaml esptool-4.7.0+dfsg/.pre-commit-config.yaml --- esptool-4.6.2+dfsg/.pre-commit-config.yaml 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/.pre-commit-config.yaml 2023-12-13 11:05:18.000000000 +0000 @@ -1,9 +1,17 @@ repos: - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 6.1.0 hooks: - id: flake8 + additional_dependencies: [flake8-import-order] - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 23.11.0 hooks: - id: black + - repo: https://github.com/espressif/conventional-precommit-linter + rev: v1.4.0 + hooks: + - id: conventional-precommit-linter + stages: [commit-msg] +default_stages: [commit] +default_install_hook_types: [pre-commit, commit-msg] diff -Nru esptool-4.6.2+dfsg/CHANGELOG.md esptool-4.7.0+dfsg/CHANGELOG.md --- esptool-4.6.2+dfsg/CHANGELOG.md 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/CHANGELOG.md 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,156 @@ +## v4.7.0 (2023-12-13) + +### New Features + +- **test_esptool**: Added test for embedded and detected flash size match +- **spi_connection**: Support --spi-connection on all chips +- **espefuse**: Support XTS_AES_256_KEY key_purpose for ESP32P4 +- **xip_psram**: support xip psram feature on esp32p4 +- add support for intel hex format +- **esp32p4**: Stub flasher support +- **elf2image**: add ram-only-header argument +- **rfc2217_server**: Add hard reset sequence +- **espefuse**: Adds efuse ADC calibration data for ESP32H2 +- **espefuse**: Update the way to complete the operation +- add support for get_security_info on esp32c3 ECO7 +- **loader**: Added hints for some serial port issues when rising port error +- Add support for Python 3.12 +- **esp32c3**: Support ECO6 and ECO7 magic numbers +- **merge_bin**: add support for uf2 format +- **esp32-s3**: Support >16MB quad flash chips +- **efuse**: Update key purpose table and tests +- **efuse**: ESP32P4 adds ecdsa_key support +- **espefuse**: Add support for esp32p4 chip +- **esptool**: added target to esp32p4 +- **espsecure**: Allow prompting for HSM PIN in read_hsm_config +- **esptool**: Add new packages for ESP32C3 and flash efuses +- **esptool**: Add tests for get_chip_features +- **esptool**: Add PICO package for ESP32S3 and flash/psram efuses +- **get_security_info**: Improved the output format and added more details + +### Bug Fixes + +- **esp32c2**: Added get_flash_cap and get_flash_vendor +- **testloadram**: Windows assertion error +- fixed exit() to be used from right module +- **esp32c2**: Recommend using higher baud rate if connection fails +- **test_esptool**: Fixed connection issue on Windows +- **esptool**: Rephrase the --ram-only-header command message +- **load_ram**: check for overlaps in bss section +- **tests/intelhex**: make sure file is closed on Windows +- **spi_connection**: Unattach previously attached SPI flash +- **espefuse**: Fix ECDSA_FORCE_USE_HARDWARE_K for ECDSA key (esp32h2) +- **loader**: Could not open serial port message adjusted +- **flasher_stub**: fix usb-serial-jtag enabled non-related intr source +- **bin_image**: Check only ELF sections when searching for .flash.appdesc +- **danger-github**: Fir Danger GitHub token permission +- Fix redirection of STDOUT +- **autodetection**: Remove the ESP32-S2 ROM class from get_security_info autodetection +- assert in esp32 exclusive workaround +- **elf2image**: fix text/rodata mapping overlap issue on uni-idrom bus chips +- **dangerGH**: Update token permissions - allow Danger to add comments to PR +- **expand file args**: Correctly print the expanded command +- **esp32-c2**: Enable flashing in secure download mode + +### Code Refactoring + +- **stub_flasher**: Cleanup, make adding new targets easier + +## v4.6.2 (2023-06-12) + +### Bug Fixes + +- **CH9102F**: Suggest to install new serial drivers if writing to RAM fails +- **compressed upload**: Accept short data blocks with only Adler-32 bytes + +## v4.6.1 (2023-06-01) + +### Bug Fixes + +- **ESP32-S3**: Correct RTC WDT registers to fix resets during flashing + +## v4.6 (2023-05-29) + +### New Features + +- **esptool**: add option to dump whole flash based on detected size + +### Bug Fixes + +- inconsistent usage of dirs separator +- USB-JTAG-Serial PID detection error +- Set flash parameters even with --flash_size keep +- **ESP32-C6**: Fix get_pkg_version and get_{major,minor}_chip_version + +## v4.5.1 (2023-02-28) + +### Bug Fixes + +- **ESP32-S3**: Temporarily disable increasing CPU freq +- Unknown chip (ID or magic number) error +- **ESP32-S3**: Lower CPU freq to improve flasher stub stability +- **rfc2217_server**: Use new reset sequences + +## v4.5 (2023-02-10) + +### New Features + +- **stub**: Add ESP32-S3 octal flash support +- **esp32h2**: Enable USB-JTAG/Serial mode in the stub flasher +- **bootloader reset**: Allow custom reset strategy setting with a config file +- Allow configuration with a config file +- **bootloader reset**: Tighter transitions on Unix systems +- **ci**: Publish development releases with custom pipeline +- **esp32c6 stub**: Increase CPU frequency and write/read speeds over USB-JTAG/Serial +- **esp32c6 stub**: Enable USB-JTAG/Serial +- **flash_id**: Print the flash type if available for the chip + +### Bug Fixes + +- **cmds**: Make clear that flash type is from eFuse and not detection +- **load config file**: Sort unknown config options +- **esp32c6**: Workaround for bad MSPI frequency in HS mode +- **flasher_stub**: Correct boundaries for SPIWrite4B and SPIRead4B +- **secure download mode**: Reconnect if ROM refuses to respond +- **secure download mode**: Fix SDM detection on S2/S3 +- **ci**: Merge two "ci" directories and build_tools into one +- **ci**: The development release job should not run by default +- **setup**: Use latest reedsolo package which can be installed with Python3.10 and Cython +- **write_flash**: Fix `--erase-all` option +- **espefuse**: Close serial port even when espefuse fails +- **espefuse**: Fix compatibility with Bitstring>=4 + +### Code Refactoring + +- Comply with black 23.1 style +- Optimize unnecessary chip interrogations +- **connection attempt**: Decouple reset sequence settings + +## v4.4 (2022-11-21) + +### New Features + +- **flasher_stub**: Increase CPU frequency and write/read speeds over native USB (USB-OTG) +- **flasher_stub**: Increase CPU frequency and write/read speeds over USB-JTAG/Serial +- Readable error message for serial-related issues +- Detect Guru Meditation errors + +### Bug Fixes + +- Add workaround for breaking changes of bitstring==4 +- close unused ports while get_default_connected_device + +## v4.3 (2022-09-14) + +### New Features + +- **image_info**: Print application information if possible +- Add Macronix flash memory density definitions +- **write_flash**: Prevent flashing incompatible images +- Recover from serial errors when flashing +- Add stub flasher error messages definitions +- **image_info**: Image type autodetection + +### Code Refactoring + +- **elf2image**: Simplify bootloader image selection diff -Nru esptool-4.6.2+dfsg/CONTRIBUTING.rst esptool-4.7.0+dfsg/CONTRIBUTING.rst --- esptool-4.6.2+dfsg/CONTRIBUTING.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/CONTRIBUTING.rst 2023-12-13 11:05:18.000000000 +0000 @@ -78,15 +78,20 @@ `pre-commit `_ is a framework for managing pre-commit hooks. These hooks help to identify simple issues before committing code for review. -To use the tool, first install ``pre-commit`` and then the git hooks: +To use the tool, first install ``pre-commit``. Then enable the ``pre-commit`` and ``commit-msg`` git hooks: :: $ python -m pip install pre-commit - $ pre-commit install + $ pre-commit install -t pre-commit -t commit-msg On the first commit ``pre-commit`` will install the hooks, subsequent checks will be significantly faster. If an error is found an appropriate error message will be displayed. If the error was with ``black`` then the tool will fix them for you automatically. Review the changes and re-stage for commit if you are happy with them. +Conventional Commits +"""""""""""""""""""" + +``esptool.py`` complies with the `Conventional Commits standard `_. Every commit message is checked with `Conventional Precommit Linter `_, ensuring it adheres to the standard. + Flake8 """""" @@ -97,7 +102,7 @@ All files should be formatted using the `Black `_ auto-formatter. -``Black`` and ``flake8`` tools will be automatically run by ``pre-commit`` if that is configured. To check your code manually before submitting, run ``python -m flake8`` and ``black .`` (the tools are installed as part of the development requirements shown at the beginning of this document). +``Black``, ``flake8``, and ``Conventional Precommit Linter`` tools will be automatically run by ``pre-commit`` if that is configured. To check your code manually before submitting, run ``python -m flake8`` and ``black .`` (the tools are installed as part of the development requirements shown at the beginning of this document). When you submit a Pull Request, the GitHub Actions automated build system will run automated checks using these tools. diff -Nru esptool-4.6.2+dfsg/ci/gh_changelog_template.md.j2 esptool-4.7.0+dfsg/ci/gh_changelog_template.md.j2 --- esptool-4.6.2+dfsg/ci/gh_changelog_template.md.j2 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/ci/gh_changelog_template.md.j2 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,22 @@ +{# This changelog template is used for automatically generated GH release notes. #} +{# It is passed to commitizen's --template option in a GH Actions workflow run. #} + +{% for entry in tree %} + +{% for change_key, changes in entry.changes.items() %} + +{% if change_key %} +### {{ change_key }} +{% endif %} + +{% for change in changes %} +{% if change.scope %} +- **{{ change.scope }}**: {{ change.message }} +{% elif change.message %} +- {{ change.message }} +{% endif %} +{% endfor %} +{% endfor %} +{% endfor %} + +Thanks to , and others for contributing to this release! diff -Nru esptool-4.6.2+dfsg/debian/changelog esptool-4.7.0+dfsg/debian/changelog --- esptool-4.6.2+dfsg/debian/changelog 2023-07-13 22:05:45.000000000 +0000 +++ esptool-4.7.0+dfsg/debian/changelog 2024-01-26 12:31:42.000000000 +0000 @@ -1,3 +1,11 @@ +esptool (4.7.0+dfsg-0.1) unstable; urgency=medium + + * Non-maintainer upload. + * New upstream release. + - Add new build dependency python3-intelhex. + + -- Faidon Liambotis Fri, 26 Jan 2024 14:31:42 +0200 + esptool (4.6.2+dfsg-0.1) unstable; urgency=medium * Non-maintainer upload. diff -Nru esptool-4.6.2+dfsg/debian/control esptool-4.7.0+dfsg/debian/control --- esptool-4.6.2+dfsg/debian/control 2023-07-13 22:05:45.000000000 +0000 +++ esptool-4.7.0+dfsg/debian/control 2024-01-26 12:31:34.000000000 +0000 @@ -10,6 +10,7 @@ python3-bitstring, python3-cryptography, python3-ecdsa, + python3-intelhex, python3-pkcs11, python3-reedsolo, python3-serial, diff -Nru esptool-4.6.2+dfsg/docs/en/advanced-topics/boot-mode-selection.rst esptool-4.7.0+dfsg/docs/en/advanced-topics/boot-mode-selection.rst --- esptool-4.6.2+dfsg/docs/en/advanced-topics/boot-mode-selection.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/advanced-topics/boot-mode-selection.rst 2023-12-13 11:05:18.000000000 +0000 @@ -80,7 +80,7 @@ {IDF_TARGET_STRAP_BOOT_2_GPIO} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - .. only:: not esp32c3 + .. only:: esp32 or esp32s2 or esp32s3 {IDF_TARGET_STRAP_BOOT_2_GPIO} must also be either left unconnected/floating, or driven Low, in order to enter the serial bootloader. @@ -125,7 +125,7 @@ As an example of auto-reset curcuitry implementation, check the `schematic `_ of the ESP32 DevKitC development board: -- The **Micro USB 5V & USB-UART** section shows the ``DTR`` and ``RTS`` control lines of the USB to serial converter chip connected to ``GPIO0`` and ``EN`` pins of the ESP module. +- The **Micro USB 5V & USB-UART** section shows the ``DTR`` and ``RTS`` control lines of the USB to serial converter chip connected to ``{IDF_TARGET_STRAP_BOOT_GPIO}`` and ``EN`` pins of the ESP module. - Some OS and/or drivers may activate ``RTS`` and or ``DTR`` automatically when opening the serial port (true only for some serial terminal programs, not ``esptool.py``), pulling them low together and holding the ESP in reset. If ``RTS`` is wired directly to ``EN`` then RTS/CTS "hardware flow control" needs to be disabled in the serial program to avoid this. An additional circuitry is implemented in order to avoid this problem - if both ``RTS`` and ``DTR`` are asserted together, this doesn't reset the chip. The schematic shows this specific circuit with two transistors and its truth table. - If this circuitry is implemented (all Espressif boards have it), adding a capacitor between the ``EN`` pin and ``GND`` (in the 1uF-10uF range) is necessary for the reset circuitry to work reliably. This is shown in the **ESP32 Module** section of the schematic. @@ -241,7 +241,7 @@ ``boot:0xNN (DESCRIPTION)`` is the hex value of the strapping pins, as represented in the `GPIO_STRAP register `__. The individual bit values are as follows: - + .. only:: esp32 - ``0x01`` - GPIO5 @@ -308,7 +308,7 @@ clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 - + .. only:: not esp32 :: diff -Nru esptool-4.6.2+dfsg/docs/en/advanced-topics/diag/command_packet_format.diag esptool-4.7.0+dfsg/docs/en/advanced-topics/diag/command_packet_format.diag --- esptool-4.6.2+dfsg/docs/en/advanced-topics/diag/command_packet_format.diag 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/advanced-topics/diag/command_packet_format.diag 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,13 @@ +packetdiag command_packet_format{ + colwidth = 16 + node_width = 50 + node_height = 50 + default_fontsize = 16 + + 0: "0x00"; + 1: "Cmd"; + 2-3: "Size"; + 4-7: "Checksum"; + 8-15: "Data" [color = lightgrey]; + 16-31: "..." [color = lightgrey]; +} diff -Nru esptool-4.6.2+dfsg/docs/en/advanced-topics/diag/download_procedure_chart.diag esptool-4.7.0+dfsg/docs/en/advanced-topics/diag/download_procedure_chart.diag --- esptool-4.6.2+dfsg/docs/en/advanced-topics/diag/download_procedure_chart.diag 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/advanced-topics/diag/download_procedure_chart.diag 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,39 @@ +blockdiag download_procedure_diagram { + node_height = 40; + node_width = 150; + span_width = 40; + span_height = 45; + default_fontsize = 12 + orientation = portrait; + edge_layout = flowchart; + default_group_color = none; + + // nodes + start [label = "Start", shape = flowchart.terminator]; + sync [label = "Synchronization", shape = box]; + success_cond [label = "Success?", shape = flowchart.condition]; + erase_data [label = "Erase data", shape = box]; + transmit_data [label = "Transmit data", shape = box]; + finish_cond [label = "Finish?", shape = flowchart.condition]; + transmit_finish [label = "Transmit finish frame", shape = box]; + finish [label = "Finish", shape = flowchart.terminator]; + // fake nodes to adjust shape and edge label position + succ_fin [shape = none]; + fincon_fin [shape = none]; + + // edges + start -> sync -> success_cond; + success_cond -> erase_data [label = "Yes"]; + erase_data -> transmit_data; + transmit_data -> finish_cond; + success_cond -- succ_fin [label = "Timeout"]; + finish_cond -> transmit_finish [label = "Yes"]; + finish_cond -- fincon_fin [label = "Failure"]; + succ_fin -- fincon_fin; + fincon_fin -> finish; + transmit_finish -> finish; + + // group + group{transmit_finish, fincon_fin}; + group{erase_data, succ_fin}; +} diff -Nru esptool-4.6.2+dfsg/docs/en/advanced-topics/diag/response_packet_format.diag esptool-4.7.0+dfsg/docs/en/advanced-topics/diag/response_packet_format.diag --- esptool-4.6.2+dfsg/docs/en/advanced-topics/diag/response_packet_format.diag 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/advanced-topics/diag/response_packet_format.diag 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,13 @@ +packetdiag command_packet_format{ + colwidth = 16 + node_width = 50 + node_height = 50 + default_fontsize = 16 + + 0: "0x01"; + 1: "Cmd"; + 2-3: "Size"; + 4-7: "Value"; + 8-15: "Data" [color = lightgrey]; + 16-31: "..." [color = lightgrey]; +} diff -Nru esptool-4.6.2+dfsg/docs/en/advanced-topics/serial-protocol.rst esptool-4.7.0+dfsg/docs/en/advanced-topics/serial-protocol.rst --- esptool-4.6.2+dfsg/docs/en/advanced-topics/serial-protocol.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/advanced-topics/serial-protocol.rst 2023-12-13 11:05:18.000000000 +0000 @@ -27,7 +27,7 @@ Low Level Protocol ^^^^^^^^^^^^^^^^^^ -The bootloader protocol uses `SLIP `_ packet framing for data transmissions in both directions. +The bootloader protocol uses `SLIP `_ packet framing for data transmissions in both directions. Each SLIP packet begins and ends with ``0xC0``. Within the packet, all occurrences of ``0xC0`` and ``0xDB`` are replaced with ``0xDB 0xDC`` and ``0xDB 0xDD``, respectively. The replacing is to be done **after** the checksum and lengths are calculated, so the packet length may be longer than the ``size`` field below. @@ -36,6 +36,11 @@ Each command is a SLIP packet initiated by the host and results in a response packet. Inside the packet, the packet consists of a header and a variable-length body. All multi-byte fields are little-endian. +.. packetdiag:: diag/command_packet_format.diag + :caption: Command packet format + :align: center + + +--------+-------------+--------------------------------------------------------------------------------------------------------------------+ | Byte | Name | Comment | +========+=============+====================================================================================================================+ @@ -55,6 +60,10 @@ Each received command will result in a response SLIP packet sent from the ESP chip to the host. Contents of the response packet is: +.. packetdiag:: diag/response_packet_format.diag + :caption: Command packet format + :align: center + +--------+-------------+--------------------------------------------------------------------------------------------------------------+ | Byte | Name | Comment | +========+=============+==============================================================================================================+ @@ -270,7 +279,7 @@ Checksum ^^^^^^^^ -The checksum field is ignored (can be zero) for all comands except for MEM_DATA, FLASH_DATA, and FLASH_DEFL_DATA. +The checksum field is ignored (can be zero) for all commands except for MEM_DATA, FLASH_DATA, and FLASH_DEFL_DATA. Each of the ``_DATA`` command packets (like ``FLASH_DEFL_DATA``, ``MEM_DATA``) has the same "data payload" format: @@ -297,6 +306,14 @@ Functional Description ---------------------- +.. blockdiag:: diag/download_procedure_chart.diag + :caption: Download procedure flow chart + :align: center + + +.. note:: + This flow chart is used to illustrate the download procedure (writing to flash), other commands have different flows. + Initial Synchronisation ^^^^^^^^^^^^^^^^^^^^^^^ .. list:: @@ -384,7 +401,7 @@ .. only:: not esp8266 - On the {IDF_TARGET_NAME} stub loader, it is required to send this command before interacting with SPI flash. + On the {IDF_TARGET_NAME} stub loader sending this command before interacting with SPI flash is optional. On {IDF_TARGET_NAME} ROM loader, it is required to send this command before interacting with SPI flash. +------------------+----------------------------------------------------------------------------------------------------------------------------------+ | Value | Meaning | @@ -400,9 +417,11 @@ When writing the values of each pin as 6-bit numbers packed into the data word, each 6-bit value uses the following representation: - * Pin numbers 0 through 30 are represented as themselves. - * Pin numbers 32 & 33 are represented as values 30 & 31. - * It is not possible to represent pins 30 & 31 or pins higher than 33. This is the same 6-bit representation used by the ``SPI_PAD_CONFIG_xxx`` efuses. + .. only:: esp32 + + * Pin numbers 0 through 30 are represented as themselves. + * Pin numbers 32 & 33 are represented as values 30 & 31. + * It is not possible to represent pins 30 & 31 or pins higher than 33. This is the same 6-bit representation used by the ``SPI_PAD_CONFIG_xxx`` efuses. On {IDF_TARGET_NAME} ROM loader only, there is an additional 4 bytes in the data payload of this command. These bytes should all be set to zero. diff -Nru esptool-4.6.2+dfsg/docs/en/contributing.rst esptool-4.7.0+dfsg/docs/en/contributing.rst --- esptool-4.6.2+dfsg/docs/en/contributing.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/contributing.rst 2023-12-13 11:05:18.000000000 +0000 @@ -1 +1,3 @@ +.. _contribute: + .. include:: ../../CONTRIBUTING.rst diff -Nru esptool-4.6.2+dfsg/docs/en/espefuse/inc/summary_ESP32-P4.rst esptool-4.7.0+dfsg/docs/en/espefuse/inc/summary_ESP32-P4.rst --- esptool-4.6.2+dfsg/docs/en/espefuse/inc/summary_ESP32-P4.rst 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/espefuse/inc/summary_ESP32-P4.rst 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,176 @@ +.. code-block:: none + + > espefuse.py -p PORT summary + + Connecting.... + Detecting chip type... ESP32-P4 + + === Run "summary" command === + EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) + ---------------------------------------------------------------------------------------- + Config fuses: + WR_DIS (BLOCK0) Disable programming of individual eFuses = 0 R/W (0x00000000) + RD_DIS (BLOCK0) Disable reading from BlOCK4-10 = 0 R/W (0b0000000) + POWERGLITCH_EN (BLOCK0) Represents whether power glitch function is enable = False R/W (0b0) + d. 1: enabled. 0: disabled + DIS_TWAI (BLOCK0) Represents whether TWAI function is disabled or en = False R/W (0b0) + abled. 1: disabled. 0: enabled + KM_HUK_GEN_STATE_LOW (BLOCK0) Set this bit to control validation of HUK generate = 0 R/W (0b000000) + mode. Odd of 1 is invalid; even of 1 is valid + KM_HUK_GEN_STATE_HIGH (BLOCK0) Set this bit to control validation of HUK generate = 0 R/W (0b000) + mode. Odd of 1 is invalid; even of 1 is valid + KM_RND_SWITCH_CYCLE (BLOCK0) Set bits to control key manager random number swit = 0 R/W (0b00) + ch cycle. 0: control by register. 1: 8 km clk cycl + es. 2: 16 km cycles. 3: 32 km cycles + KM_DEPLOY_ONLY_ONCE (BLOCK0) Set each bit to control whether corresponding key = 0 R/W (0x0) + can only be deployed once. 1 is true; 0 is false. + Bit0: ecdsa. Bit1: xts. Bit2: hmac. Bit3: ds + DIS_DIRECT_BOOT (BLOCK0) Represents whether direct boot mode is disabled or = False R/W (0b0) + enabled. 1: disabled. 0: enabled + UART_PRINT_CONTROL (BLOCK0) Represents the type of UART printing. 00: force en = 0 R/W (0b00) + able printing. 01: enable printing when GPIO8 is r + eset at low level. 10: enable printing when GPIO8 + is reset at high level. 11: force disable printing + HYS_EN_PAD (BLOCK0) Represents whether the hysteresis function of corr = False R/W (0b0) + esponding PAD is enabled. 1: enabled. 0:disabled + DCDC_VSET (BLOCK0) Set the dcdc voltage default = 0 R/W (0b00000) + PXA0_TIEH_SEL_0 (BLOCK0) TBD = 0 R/W (0b00) + PXA0_TIEH_SEL_1 (BLOCK0) TBD = 0 R/W (0b00) + PXA0_TIEH_SEL_2 (BLOCK0) TBD = 0 R/W (0b00) + PXA0_TIEH_SEL_3 (BLOCK0) TBD = 0 R/W (0b00) + KM_DISABLE_DEPLOY_MODE (BLOCK0) TBD = 0 R/W (0x0) + HP_PWR_SRC_SEL (BLOCK0) HP system power source select. 0:LDO. 1: DCDC = False R/W (0b0) + DCDC_VSET_EN (BLOCK0) Select dcdc vset use efuse_dcdc_vset = False R/W (0b0) + DIS_SWD (BLOCK0) Set this bit to disable super-watchdog = False R/W (0b0) + BLOCK_SYS_DATA1 (BLOCK2) System data part 1 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + BLOCK_USR_DATA (BLOCK3) User data + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + BLOCK_SYS_DATA2 (BLOCK10) System data part 2 (reserved) + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + + Flash fuses: + FLASH_TYPE (BLOCK0) The type of interfaced flash. 0: four data lines; = False R/W (0b0) + 1: eight data lines + FLASH_PAGE_SIZE (BLOCK0) Set flash page size = 0 R/W (0b00) + FLASH_ECC_EN (BLOCK0) Set this bit to enable ecc for flash boot = False R/W (0b0) + FLASH_TPUW (BLOCK0) Represents the flash waiting time after power-up; = 0 R/W (0x0) + in unit of ms. When the value less than 15; the wa + iting time is the programmed value. Otherwise; the + waiting time is 2 times the programmed value + FORCE_SEND_RESUME (BLOCK0) Represents whether ROM code is forced to send a re = False R/W (0b0) + sume command during SPI boot. 1: forced. 0:not for + ced + + Jtag fuses: + JTAG_SEL_ENABLE (BLOCK0) Represents whether the selection between usb_to_jt = False R/W (0b0) + ag and pad_to_jtag through strapping gpio15 when b + oth EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are + equal to 0 is enabled or disabled. 1: enabled. 0: + disabled + SOFT_DIS_JTAG (BLOCK0) Represents whether JTAG is disabled in soft way. O = 0 R/W (0b000) + dd number: disabled. Even number: enabled + DIS_PAD_JTAG (BLOCK0) Represents whether JTAG is disabled in the hard wa = False R/W (0b0) + y(permanently). 1: disabled. 0: enabled + + Mac fuses: + MAC (BLOCK1) MAC address + = 00:00:00:00:00:00 (OK) R/W + MAC_EXT (BLOCK1) Stores the extended bits of MAC address = 00:00 (OK) R/W + MAC_EUI64 (BLOCK1) calc MAC_EUI64 = MAC[0]:MAC[1]:MAC[2]:MAC_EXT[0]:M + = 00:00:00:00:00:00:00:00 (OK) R/W + AC_EXT[1]:MAC[3]:MAC[4]:MAC[5] + + Security fuses: + DIS_FORCE_DOWNLOAD (BLOCK0) Represents whether the function that forces chip i = False R/W (0b0) + nto download mode is disabled or enabled. 1: disab + led. 0: enabled + SPI_DOWNLOAD_MSPI_DIS (BLOCK0) Set this bit to disable accessing MSPI flash/MSPI = False R/W (0b0) + ram by SYS AXI matrix during boot_mode_download + DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Represents whether flash encrypt function is disab = False R/W (0b0) + led or enabled(except in SPI boot mode). 1: disabl + ed. 0: enabled + FORCE_USE_KEY_MANAGER_KEY (BLOCK0) Set each bit to control whether corresponding key = 0 R/W (0x0) + must come from key manager.. 1 is true; 0 is false + . Bit0: ecdsa. Bit1: xts. Bit2: hmac. Bit3: ds + FORCE_DISABLE_SW_INIT_KEY (BLOCK0) Set this bit to disable software written init key; = False R/W (0b0) + and force use efuse_init_key + XTS_KEY_LENGTH_256 (BLOCK0) Set this bit to configure flash encryption use xts = False R/W (0b0) + -128 key; else use xts-256 key + SPI_BOOT_CRYPT_CNT (BLOCK0) Enables flash encryption when 1 or 3 bits are set = Disable R/W (0b000) + and disables otherwise + SECURE_BOOT_KEY_REVOKE0 (BLOCK0) Revoke 1st secure boot key = False R/W (0b0) + SECURE_BOOT_KEY_REVOKE1 (BLOCK0) Revoke 2nd secure boot key = False R/W (0b0) + SECURE_BOOT_KEY_REVOKE2 (BLOCK0) Revoke 3rd secure boot key = False R/W (0b0) + KEY_PURPOSE_0 (BLOCK0) Represents the purpose of Key0 = USER R/W (0x0) + KEY_PURPOSE_1 (BLOCK0) Represents the purpose of Key1 = USER R/W (0x0) + KEY_PURPOSE_2 (BLOCK0) Represents the purpose of Key2 = USER R/W (0x0) + KEY_PURPOSE_3 (BLOCK0) Represents the purpose of Key3 = USER R/W (0x0) + KEY_PURPOSE_4 (BLOCK0) Represents the purpose of Key4 = USER R/W (0x0) + KEY_PURPOSE_5 (BLOCK0) Represents the purpose of Key5 = USER R/W (0x0) + SEC_DPA_LEVEL (BLOCK0) Represents the spa secure level by configuring the = 0 R/W (0b00) + clock random divide mode + ECDSA_ENABLE_SOFT_K (BLOCK0) Represents whether hardware random number k is for = False R/W (0b0) + ced used in ESDCA. 1: force used. 0: not force use + d + CRYPT_DPA_ENABLE (BLOCK0) Represents whether anti-dpa attack is enabled. 1:e = False R/W (0b0) + nabled. 0: disabled + SECURE_BOOT_EN (BLOCK0) Represents whether secure boot is enabled or disab = False R/W (0b0) + led. 1: enabled. 0: disabled + SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0) Represents whether revoking aggressive secure boot = False R/W (0b0) + is enabled or disabled. 1: enabled. 0: disabled + DIS_DOWNLOAD_MODE (BLOCK0) Represents whether Download mode is disabled or en = False R/W (0b0) + abled. 1: disabled. 0: enabled + LOCK_KM_KEY (BLOCK0) TBD = False R/W (0b0) + ENABLE_SECURITY_DOWNLOAD (BLOCK0) Represents whether security download is enabled or = False R/W (0b0) + disabled. 1: enabled. 0: disabled + SECURE_VERSION (BLOCK0) Represents the version used by ESP-IDF anti-rollba = 0 R/W (0x0000) + ck feature + SECURE_BOOT_DISABLE_FAST_WAKE (BLOCK0) Represents whether FAST VERIFY ON WAKE is disabled = False R/W (0b0) + or enabled when Secure Boot is enabled. 1: disabl + ed. 0: enabled + BLOCK_KEY0 (BLOCK4) + Purpose: USER + Key0 or user data + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + BLOCK_KEY1 (BLOCK5) + Purpose: USER + Key1 or user data + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + BLOCK_KEY2 (BLOCK6) + Purpose: USER + Key2 or user data + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + BLOCK_KEY3 (BLOCK7) + Purpose: USER + Key3 or user data + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + BLOCK_KEY4 (BLOCK8) + Purpose: USER + Key4 or user data + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + BLOCK_KEY5 (BLOCK9) + Purpose: USER + Key5 or user data + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + + Usb fuses: + USB_DEVICE_EXCHG_PINS (BLOCK0) Enable usb device exchange pins of D+ and D- = False R/W (0b0) + USB_OTG11_EXCHG_PINS (BLOCK0) Enable usb otg11 exchange pins of D+ and D- = False R/W (0b0) + DIS_USB_JTAG (BLOCK0) Represents whether the function of usb switch to j = False R/W (0b0) + tag is disabled or enabled. 1: disabled. 0: enable + d + USB_PHY_SEL (BLOCK0) TBD = False R/W (0b0) + DIS_USB_OTG_DOWNLOAD_MODE (BLOCK0) Set this bit to disable download via USB-OTG = False R/W (0b0) + DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0) Represents whether print from USB-Serial-JTAG is d = False R/W (0b0) + isabled or enabled. 1: disabled. 0: enabled + DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0) Represents whether the USB-Serial-JTAG download fu = False R/W (0b0) + nction is disabled or enabled. 1: disabled. 0: ena + bled + + Wdt fuses: + WDT_DELAY_SEL (BLOCK0) Represents whether RTC watchdog timeout threshold = 0 R/W (0b00) + is selected at startup. 1: selected. 0: not select + ed + DIS_WDT (BLOCK0) Set this bit to disable watch dog = False R/W (0b0) + \ No newline at end of file diff -Nru esptool-4.6.2+dfsg/docs/en/espsecure/index.rst esptool-4.7.0+dfsg/docs/en/espsecure/index.rst --- esptool-4.6.2+dfsg/docs/en/espsecure/index.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/espsecure/index.rst 2023-12-13 11:05:18.000000000 +0000 @@ -50,6 +50,9 @@ An HSM config file is required with the fields (``pkcs11_lib``, ``credentials``, ``slot``, ``label``, ``label_pubkey``) populated corresponding to the HSM used. +To access an HSM token of a selected slot, you will also need to pass in the token User PIN and thus you will be prompted to type in the User PIN. +Alternatively, you could also add a ``credentials`` field in the HSM config file to store the (plaintext) User PIN to automate the signing workflow. + Below is a sample HSM config file (``hsm_config.ini``) for using `SoftHSMv2 `_ as an external HSM: :: # hsm_config.ini diff -Nru esptool-4.6.2+dfsg/docs/en/esptool/advanced-commands.rst esptool-4.7.0+dfsg/docs/en/esptool/advanced-commands.rst --- esptool-4.6.2+dfsg/docs/en/esptool/advanced-commands.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/esptool/advanced-commands.rst 2023-12-13 11:05:18.000000000 +0000 @@ -48,7 +48,7 @@ Load a Binary to RAM: load_ram ------------------------------ -The ``load_ram`` command allows the loading of an executable binary image (created with the ``elf2image`` or ``make_image`` commands) directly into RAM, and then immediately executes the program contained within it. +The ``load_ram`` command allows the loading of an executable binary image (created with the ``elf2image`` or ``make_image`` commands) directly into RAM, and then immediately executes the program contained within it. Command also supports ``.hex`` file created by ``merge_bin`` command from supported ``.bin`` files. :: diff -Nru esptool-4.6.2+dfsg/docs/en/esptool/advanced-options.rst esptool-4.7.0+dfsg/docs/en/esptool/advanced-options.rst --- esptool-4.6.2+dfsg/docs/en/esptool/advanced-options.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/esptool/advanced-options.rst 2023-12-13 11:05:18.000000000 +0000 @@ -45,7 +45,7 @@ Passing ``--no-stub`` will disable certain options, as not all options are implemented in every chip's ROM loader. -.. only:: esp32 +.. only:: not esp8266 Overriding SPI Flash Connections -------------------------------- @@ -61,46 +61,59 @@ The only exception to this is if the ``--no-stub`` option is also provided. In this case, efuse values are ignored and ``--spi-connection`` will default to ``--spi-connection SPI`` unless set to a different value. - SPI Mode - ^^^^^^^^ + .. only:: esp32 - ``--spi-connection SPI`` uses the default SPI pins: + SPI Mode + ^^^^^^^^ - * CLK = GPIO 6 - * Q = GPIO 7 - * D = GPIO 8 - * HD = GPIO 9 - * CS = GPIO 11 + ``--spi-connection SPI`` uses the default SPI pins: - During normal booting, this configuration is selected if all SPI pin efuses are unset and GPIO1 (U0TXD) is not pulled low (default). + * CLK = GPIO 6 + * Q = GPIO 7 + * D = GPIO 8 + * HD = GPIO 9 + * CS = GPIO 11 - This is the normal pin configuration for ESP32 chips that do not contain embedded flash. + During normal booting, this configuration is selected if all SPI pin efuses are unset and GPIO1 (U0TXD) is not pulled low (default). - HSPI Mode - ^^^^^^^^^ + This is the normal pin configuration for ESP32 chips that do not contain embedded flash. - ``--spi-connection HSPI`` uses the HSPI peripheral instead of the SPI peripheral for SPI flash communications, via the following HSPI pins: + HSPI Mode + ^^^^^^^^^ - * CLK = GPIO 14 - * Q = GPIO 12 - * D = GPIO 13 - * HD = GPIO 4 - * CS = GPIO 15 + ``--spi-connection HSPI`` uses the HSPI peripheral instead of the SPI peripheral for SPI flash communications, via the following HSPI pins: - During normal booting, this configuration is selected if all SPI pin efuses are unset and GPIO1 (U0TXD) is pulled low on reset. + * CLK = GPIO 14 + * Q = GPIO 12 + * D = GPIO 13 + * HD = GPIO 4 + * CS = GPIO 15 + + During normal booting, this configuration is selected if all SPI pin efuses are unset and GPIO1 (U0TXD) is pulled low on reset. Custom SPI Pin Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``--spi-connection ,,,,`` allows a custom list of pins to be configured for the SPI flash connection. This can be used to emulate the flash configuration equivalent to a particular set of SPI pin efuses being burned. The values supplied are GPIO numbers. - For example, ``--spi-connection 6,17,8,11,16`` sets an identical configuration to the factory efuse configuration for ESP32s with embedded flash. + .. only:: esp32 + + For example, ``--spi-connection 6,17,8,11,16`` sets an identical configuration to the factory efuse configuration for ESP32s with embedded flash. + + When setting a custom pin configuration, the SPI peripheral (not HSPI) will be used unless the ``CLK`` pin value is set to 14 (HSPI CLK), in which case the HSPI peripheral will be used. - When setting a custom pin configuration, the SPI peripheral (not HSPI) will be used unless the ``CLK`` pin value is set to 14 (HSPI CLK), in which case the HSPI peripheral will be used. + .. note:: + + Some GPIO pins might be shared with other peripherals. Therefore, some SPI pad pin configurations might not work reliably or at all. Use a different combination of pins if you encounter issues. Specifying Arguments via File ----------------------------- +.. _specify_arguments_via_file: Anywhere on the esptool command line, you can specify a file name as ``@filename.txt`` to read one or more arguments from text file ``filename.txt``. Arguments can be separated by newlines or spaces, quotes can be used to enclose arguments that span multiple words. Arguments read from the text file are expanded exactly as if they had appeared in that order on the esptool command line. An example of this is available in the :ref:`merge_bin ` command description. + +.. note:: PowerShell users + + Because of `splatting `__ in PowerShell (method of passing a collection of parameter values to a command as a unit) there is a need to add quotes around @filename.txt ("@filename.txt") to be correctly resolved. diff -Nru esptool-4.6.2+dfsg/docs/en/esptool/basic-commands.rst esptool-4.7.0+dfsg/docs/en/esptool/basic-commands.rst --- esptool-4.6.2+dfsg/docs/en/esptool/basic-commands.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/esptool/basic-commands.rst 2023-12-13 11:05:18.000000000 +0000 @@ -211,12 +211,16 @@ In the above example, the output image file would be called ``my_esp_app.bin``. + The ``--ram-only-header`` configuration is mainly applicable for use within the Espressif's SIMPLE_BOOT option from 3rd party OSes such as ZephyrOS and NuttX OS. + This option makes only the RAM segments visible to the ROM bootloader placing them at the beginning of the file and altering the segment count from the image header with the quantity of these segments, and also writing only their checksum. This segment placement may result in a more fragmented binary because of flash alignment constraints. + It is strongly recommended to use this configuration with care, because the image built must then handle the basic hardware initialization and the flash mapping for code execution after ROM bootloader boot it. + .. _image-info: Output .bin Image Details: image_info ------------------------------------- -The ``image_info`` command outputs some information (load addresses, sizes, etc) about a ``.bin`` file created by ``elf2image``. +The ``image_info`` command outputs some information (load addresses, sizes, etc) about a ``.bin`` file created by ``elf2image``. Command also supports ``.hex`` file created by ``merge_bin`` command from supported ``.bin`` files. To view more information about the image, such as set flash size, frequency and mode, or extended header information, use the ``--version 2`` option. This extended output will become the default in a future major release. @@ -236,8 +240,7 @@ Merge Binaries for Flashing: merge_bin -------------------------------------- - -The ``merge_bin`` command will merge multiple binary files (of any kind) into a single file that can be flashed to a device later. Any gaps between the input files are padded with 0xFF bytes (same as unwritten flash contents). +The ``merge_bin`` command will merge multiple binary files (of any kind) into a single file that can be flashed to a device later. Any gaps between the input files are padded based on the selected output format. For example: @@ -245,25 +248,73 @@ esptool.py --chip {IDF_TARGET_NAME} merge_bin -o merged-flash.bin --flash_mode dio --flash_size 4MB 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 app.bin -Will create a file ``merged-flash.bin`` with the contents of the other 3 files. This file can be later be written to flash with ``esptool.py write_flash 0x0 merged-flash.bin``. +Will create a file ``merged-flash.bin`` with the contents of the other 3 files. This file can be later written to flash with ``esptool.py write_flash 0x0 merged-flash.bin``. -.. note: - Because gaps between the input files are padded with 0xFF bytes, when the merged binary is written then any flash sectors between the individual files will be erased. To avoid this, write the files individually. - -**Options:** +**Common options:** * The ``merge_bin`` command supports the same ``--flash_mode``, ``--flash_size`` and ``--flash_freq`` options as the ``write_flash`` command to override the bootloader flash header (see above for details). These options are applied to the output file contents in the same way as when writing to flash. Make sure to pass the ``--chip`` parameter if using these options, as the supported values and the bootloader offset both depend on the chip. -* The ``--target-offset 0xNNN`` option will create a merged binary that should be flashed at the specified offset, instead of at offset 0x0. -* The ``--fill-flash-size SIZE`` option will pad the merged binary with 0xFF bytes to the full flash specified size, for example ``--fill-flash-size 4MB`` will create a 4MB binary file. -* It is possible to append options from a text file with ``@filename``. As an example, this can be conveniently used with the ESP-IDF build system, which produces a ``flash_args`` file in the build directory of a project: +* The ``--format`` option will change the format of the output file. For more information about formats see formats description below. +* The input files can be in either ``bin`` or ``hex`` format and they will be automatically converted to type selected by ``--format`` argument. +* It is possible to append options from a text file with ``@filename`` (see the advanced options page :ref:`Specifying Arguments via File ` section for details). As an example, this can be conveniently used with the ESP-IDF build system, which produces a ``flash_args`` file in the build directory of a project: .. code:: sh cd build # The build directory of an ESP-IDF project esptool.py --chip {IDF_TARGET_NAME} merge_bin -o merged-flash.bin @flash_args + +HEX Output Format +^^^^^^^^^^^^^^^^^ + +The output of the command will be in `Intel Hex format `__. The gaps between the files won't be padded. + +Intel Hex format offers distinct advantages when compared to the binary format, primarily in the following areas: + +* **Transport**: Intel Hex files are represented in ASCII text format, significantly increasing the likelihood of flawless transfers across various mediums. +* **Size**: Data is carefully allocated to specific memory addresses eliminating the need for unnecessary padding. Binary images often lack detailed addressing information, leading to the inclusion of data for all memory locations from the file's initial address to its end. +* **Validity Checks**: Each line in an Intel Hex file has a checksum to help find errors and make sure data stays unchanged. + +.. code:: sh + + esptool.py --chip {IDF_TARGET_NAME} merge_bin --format hex -o merged-flash.hex --flash_mode dio --flash_size 4MB 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 app.bin + + +RAW Output Format +^^^^^^^^^^^^^^^^^ + +The output of the command will be in ``raw`` format and gaps between individual files will be filled with `0xFF` bytes (same as unwritten flash contents). + +.. note:: + + Because gaps between the input files are padded with `0xFF` bytes, when the merged binary is written then any flash sectors between the individual files will be erased. To avoid this, write the files individually. + + +**RAW options:** + +* The ``--fill-flash-size SIZE`` option will pad the merged binary with `0xFF` bytes to the full flash specified size, for example ``--fill-flash-size 4MB`` will create a 4MB binary file. +* The ``--target-offset 0xNNN`` option will create a merged binary that should be flashed at the specified offset, instead of at offset 0x0. + + +UF2 Output Format +^^^^^^^^^^^^^^^^^ + +This command will generate a UF2 (`USB Flashing Format `_) binary. +This UF2 file can be copied to a USB mass storage device exposed by another ESP running the `ESP USB Bridge `_ project. The bridge MCU will use it to flash the target MCU. This is as simple copying (or "drag-and-dropping") the file to the exposed disk accessed by a file explorer in your machine. + +Gaps between the files will be filled with `0x00` bytes. + +**UF2 options:** + +* The ``--chunk-size`` option will set what portion of 512 byte block will be used for data. A common value is 256 bytes. By default, the largest possible value will be used. +* The ``--md5-disable`` option will disable MD5 checksums at the end of each block. This can be useful for integration with e.g. `tinyuf2 `__. + +.. code:: sh + + esptool.py --chip {IDF_TARGET_NAME} merge_bin --format uf2 -o merged-flash.uf2 --flash_mode dio --flash_size 4MB 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 app.bin + + Advanced Commands ----------------- diff -Nru esptool-4.6.2+dfsg/docs/en/esptool/serial-connection.rst esptool-4.7.0+dfsg/docs/en/esptool/serial-connection.rst --- esptool-4.6.2+dfsg/docs/en/esptool/serial-connection.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/esptool/serial-connection.rst 2023-12-13 11:05:18.000000000 +0000 @@ -40,6 +40,12 @@ | Flow control | None | +---------------------+-------------------+ +.. only:: esp32c2 + + .. note:: + + You might experience issues when using low baud rates on {IDF_TARGET_NAME}. If you encounter any problems when connecting, please use at least 115200 or higher. + .. only:: esp8266 .. note:: diff -Nru esptool-4.6.2+dfsg/docs/en/index.rst esptool-4.7.0+dfsg/docs/en/index.rst --- esptool-4.6.2+dfsg/docs/en/index.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/index.rst 2023-12-13 11:05:18.000000000 +0000 @@ -51,4 +51,5 @@ Troubleshooting Contribute Versions + Resources About diff -Nru esptool-4.6.2+dfsg/docs/en/resources.rst esptool-4.7.0+dfsg/docs/en/resources.rst --- esptool-4.6.2+dfsg/docs/en/resources.rst 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/resources.rst 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,40 @@ +.. _resources: + +Resources +========= + + +Useful Links +------------- + +* The `esp32.com forum `_ is a place to ask questions and find community resources. + +* Check the `Issues `_ section on GitHub if you find a bug or have a feature request. Please check existing `issues `_ before opening a new one. + +* Several `books `_ have been written about the ESP8266 or ESP32 series of SoCs and they are listed on `Espressif `__ web site. + +* If you're interested in contributing to esptool.py, please check the :ref:`contribute` page. + +* For additional {IDF_TARGET_NAME} product related information, please refer to the `documentation `_ section of `Espressif `__ web site. + +Webinars and Trainings +---------------------- + +Mastering the Basics of Espressif Chips: An In-Depth Look at Chip Flashing +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The content of this webinar is designed for developers, engineers and hobbyists interested in getting a better understanding of how to use esptool.py or other tools for the development with the ESP8266 or ESP32 series of SoCs. + +It offers an in-depth look at the inner mechanisms of esptool.py, including the :ref:`boot-mode` process. + +.. image:: https://img.youtube.com/vi/zh-Y_s4X6zs/maxresdefault.jpg + :alt: Mastering the Basics of Espressif Chips: An In-Depth Look at Chip Flashing + :target: https://www.youtube.com/watch?v=zh-Y_s4X6zs + +DevCon22: esptool.py: Espressif's Swiss Army Knife +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +This talk aims to show how simple, yet powerful, esptool.py is, and how to use it to tame your ESP. + +.. image:: https://img.youtube.com/vi/GjWGKzu3XTk/maxresdefault.jpg + :alt: DevCon22: esptool.py: Espressif's Swiss Army Knife + :target: https://www.youtube.com/watch?v=GjWGKzu3XTk diff -Nru esptool-4.6.2+dfsg/docs/en/troubleshooting.rst esptool-4.7.0+dfsg/docs/en/troubleshooting.rst --- esptool-4.6.2+dfsg/docs/en/troubleshooting.rst 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/docs/en/troubleshooting.rst 2023-12-13 11:05:18.000000000 +0000 @@ -102,6 +102,17 @@ Use any of `serial terminal programs`_ to view the boot log. ({IDF_TARGET_NAME} baud rate is 115200bps). See if the program is crashing during early startup or outputting an error message. +.. only:: not esp8266 and not esp32 and not esp32c2 + + Issues When Using USB-Serial/JTAG or USB-OTG + -------------------------------------------- + + When working with ESP chips that implement a `USB-Serial/JTAG Controller `_ or a `USB-OTG console `_, it's essential to be aware of potential issues related to the loaded application interfering with or reprogramming the GPIO pins used for USB communication. + + If the application accidentally reconfigures the USB peripheral pins or disables the USB peripheral, the device disappears from the system. You can also encounter unstable flashing or errors like ``OSError: [Errno 71] Protocol error``. + + If that happens, try :ref:`manually entering the download mode ` and then using the :ref:`erase_flash ` command to wipe the flash memory. Then, make sure to fix the issue in the application before flashing again. + Serial Terminal Programs ------------------------ diff -Nru esptool-4.6.2+dfsg/esp_rfc2217_server.py esptool-4.7.0+dfsg/esp_rfc2217_server.py --- esptool-4.6.2+dfsg/esp_rfc2217_server.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esp_rfc2217_server.py 2023-12-13 11:05:18.000000000 +0000 @@ -37,7 +37,13 @@ import time from esptool.config import load_config_file -from esptool.reset import ClassicReset, CustomReset, DEFAULT_RESET_DELAY, UnixTightReset +from esptool.reset import ( + ClassicReset, + CustomReset, + DEFAULT_RESET_DELAY, + HardReset, + UnixTightReset, +) import serial import serial.rfc2217 @@ -63,14 +69,23 @@ def __init__(self, serial_port, connection, esp32r0_delay, logger=None): self.esp32r0_delay = esp32r0_delay + self.is_download_mode = False super(EspPortManager, self).__init__(serial_port, connection, logger) def _telnet_process_subnegotiation(self, suboption): if suboption[0:1] == COM_PORT_OPTION and suboption[1:2] == SET_CONTROL: if suboption[2:3] == SET_CONTROL_DTR_OFF: + self.is_download_mode = False self.serial.dtr = False return - elif suboption[2:3] == SET_CONTROL_RTS_ON and not self.serial.dtr: + elif suboption[2:3] == SET_CONTROL_RTS_OFF and not self.is_download_mode: + reset_thread = threading.Thread(target=self._hard_reset_thread) + reset_thread.daemon = True + reset_thread.name = "hard_reset_thread" + reset_thread.start() + return + elif suboption[2:3] == SET_CONTROL_DTR_ON and not self.is_download_mode: + self.is_download_mode = True reset_thread = threading.Thread(target=self._reset_thread) reset_thread.daemon = True reset_thread.name = "reset_thread" @@ -85,6 +100,14 @@ # only in cases not handled above do the original implementation in PortManager super(EspPortManager, self)._telnet_process_subnegotiation(suboption) + def _hard_reset_thread(self): + """ + The reset logic used for hard resetting the chip. + """ + if self.logger: + self.logger.info("Activating hard reset in thread") + HardReset(self.serial)() + def _reset_thread(self): """ The reset logic is used from esptool.py because the RTS and DTR signals diff -Nru esptool-4.6.2+dfsg/espefuse/__init__.py esptool-4.7.0+dfsg/espefuse/__init__.py --- esptool-4.6.2+dfsg/espefuse/__init__.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/__init__.py 2023-12-13 11:05:18.000000000 +0000 @@ -14,6 +14,7 @@ import espefuse.efuse.esp32c6 as esp32c6_efuse import espefuse.efuse.esp32h2 as esp32h2_efuse import espefuse.efuse.esp32h2beta1 as esp32h2beta1_efuse +import espefuse.efuse.esp32p4 as esp32p4_efuse import espefuse.efuse.esp32s2 as esp32s2_efuse import espefuse.efuse.esp32s3 as esp32s3_efuse import espefuse.efuse.esp32s3beta2 as esp32s3beta2_efuse @@ -49,6 +50,7 @@ "esp32c3": DefChip("ESP32-C3", esp32c3_efuse, esptool.targets.ESP32C3ROM), "esp32c6": DefChip("ESP32-C6", esp32c6_efuse, esptool.targets.ESP32C6ROM), "esp32h2": DefChip("ESP32-H2", esp32h2_efuse, esptool.targets.ESP32H2ROM), + "esp32p4": DefChip("ESP32-P4", esp32p4_efuse, esptool.targets.ESP32P4ROM), "esp32h2beta1": DefChip( "ESP32-H2(beta1)", esp32h2beta1_efuse, esptool.targets.ESP32H2BETA1ROM ), diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32c2/emulate_efuse_controller.py esptool-4.7.0+dfsg/espefuse/efuse/esp32c2/emulate_efuse_controller.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32c2/emulate_efuse_controller.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32c2/emulate_efuse_controller.py 2023-12-13 11:05:18.000000000 +0000 @@ -24,7 +24,7 @@ self.Fields = EfuseDefineFields() self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -55,10 +55,10 @@ self.clean_blocks_wr_regs() self.check_rd_protection_area() self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) elif value == self.REGS.EFUSE_READ_CMD: self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) self.save_to_file() def get_bitlen_of_block(self, blk, wr=False): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32c2/fields.py esptool-4.7.0+dfsg/espefuse/efuse/esp32c2/fields.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32c2/fields.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32c2/fields.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ import binascii import struct +import sys import time from bitstring import BitArray @@ -152,9 +153,13 @@ def wait_efuse_idle(self): deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT while time.time() < deadline: - # if self.read_reg(self.REGS.EFUSE_CMD_REG) == 0: - if self.read_reg(self.REGS.EFUSE_STATUS_REG) & 0x7 == 1: - return + cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + # Due to a hardware error, we have to read READ_CMD again + # to make sure the efuse clock is normal. + # For PGM_CMD it is not necessary. + return raise esptool.FatalError( "Timed out waiting for Efuse controller command to complete" ) @@ -194,7 +199,7 @@ ) print("DIS_DOWNLOAD_MODE is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise print("Established a connection with the chip") @@ -208,7 +213,7 @@ ) print("ENABLE_SECURITY_DOWNLOAD is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise def set_efuse_timing(self): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32c3/emulate_efuse_controller.py esptool-4.7.0+dfsg/espefuse/efuse/esp32c3/emulate_efuse_controller.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32c3/emulate_efuse_controller.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32c3/emulate_efuse_controller.py 2023-12-13 11:05:18.000000000 +0000 @@ -22,7 +22,7 @@ self.Fields = EfuseDefineFields() self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ self.clean_blocks_wr_regs() self.check_rd_protection_area() self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) elif value == self.REGS.EFUSE_READ_CMD: self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) self.save_to_file() def get_bitlen_of_block(self, blk, wr=False): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32c3/fields.py esptool-4.7.0+dfsg/espefuse/efuse/esp32c3/fields.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32c3/fields.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32c3/fields.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ import binascii import struct +import sys import time from bitstring import BitArray @@ -160,9 +161,13 @@ def wait_efuse_idle(self): deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT while time.time() < deadline: - # if self.read_reg(self.REGS.EFUSE_CMD_REG) == 0: - if self.read_reg(self.REGS.EFUSE_STATUS_REG) & 0x7 == 1: - return + cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + # Due to a hardware error, we have to read READ_CMD again + # to make sure the efuse clock is normal. + # For PGM_CMD it is not necessary. + return raise esptool.FatalError( "Timed out waiting for Efuse controller command to complete" ) @@ -202,7 +207,7 @@ ) print("DIS_DOWNLOAD_MODE is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise print("Established a connection with the chip") @@ -216,7 +221,7 @@ ) print("ENABLE_SECURITY_DOWNLOAD is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise def set_efuse_timing(self): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32c6/emulate_efuse_controller.py esptool-4.7.0+dfsg/espefuse/efuse/esp32c6/emulate_efuse_controller.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32c6/emulate_efuse_controller.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32c6/emulate_efuse_controller.py 2023-12-13 11:05:18.000000000 +0000 @@ -22,7 +22,7 @@ self.Fields = EfuseDefineFields() self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ self.clean_blocks_wr_regs() self.check_rd_protection_area() self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) elif value == self.REGS.EFUSE_READ_CMD: self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) self.save_to_file() def get_bitlen_of_block(self, blk, wr=False): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32c6/fields.py esptool-4.7.0+dfsg/espefuse/efuse/esp32c6/fields.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32c6/fields.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32c6/fields.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ import binascii import struct +import sys import time from bitstring import BitArray @@ -160,9 +161,13 @@ def wait_efuse_idle(self): deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT while time.time() < deadline: - # if self.read_reg(self.REGS.EFUSE_CMD_REG) == 0: - if self.read_reg(self.REGS.EFUSE_STATUS_REG) & 0x7 == 1: - return + cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + # Due to a hardware error, we have to read READ_CMD again + # to make sure the efuse clock is normal. + # For PGM_CMD it is not necessary. + return raise esptool.FatalError( "Timed out waiting for Efuse controller command to complete" ) @@ -202,7 +207,7 @@ ) print("DIS_DOWNLOAD_MODE is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise print("Established a connection with the chip") @@ -216,7 +221,7 @@ ) print("ENABLE_SECURITY_DOWNLOAD is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise def set_efuse_timing(self): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32h2/emulate_efuse_controller.py esptool-4.7.0+dfsg/espefuse/efuse/esp32h2/emulate_efuse_controller.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32h2/emulate_efuse_controller.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32h2/emulate_efuse_controller.py 2023-12-13 11:05:18.000000000 +0000 @@ -22,7 +22,7 @@ self.Fields = EfuseDefineFields() self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ self.clean_blocks_wr_regs() self.check_rd_protection_area() self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) elif value == self.REGS.EFUSE_READ_CMD: self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) self.save_to_file() def get_bitlen_of_block(self, blk, wr=False): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32h2/fields.py esptool-4.7.0+dfsg/espefuse/efuse/esp32h2/fields.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32h2/fields.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32h2/fields.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ import binascii import struct +import sys import time from bitstring import BitArray @@ -94,7 +95,7 @@ for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] else: - if self["BLK_VERSION_MAJOR"].get() == 1: + if self["BLK_VERSION_MINOR"].get() == 2: self.efuses += [ EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES @@ -160,9 +161,13 @@ def wait_efuse_idle(self): deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT while time.time() < deadline: - # if self.read_reg(self.REGS.EFUSE_CMD_REG) == 0: - if self.read_reg(self.REGS.EFUSE_STATUS_REG) & 0x7 == 1: - return + cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + # Due to a hardware error, we have to read READ_CMD again + # to make sure the efuse clock is normal. + # For PGM_CMD it is not necessary. + return raise esptool.FatalError( "Timed out waiting for Efuse controller command to complete" ) @@ -202,7 +207,7 @@ ) print("DIS_DOWNLOAD_MODE is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise print("Established a connection with the chip") @@ -216,7 +221,7 @@ ) print("ENABLE_SECURITY_DOWNLOAD is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise def set_efuse_timing(self): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32h2/mem_definition.py esptool-4.7.0+dfsg/espefuse/efuse/esp32h2/mem_definition.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32h2/mem_definition.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32h2/mem_definition.py 2023-12-13 11:05:18.000000000 +0000 @@ -117,7 +117,7 @@ self.KEYBLOCKS = [] - # if BLK_VERSION_MAJOR is 1, these efuse fields are in BLOCK2 + # if BLK_VERSION_MINOR is 2, these efuse fields are in BLOCK2 self.BLOCK2_CALIBRATION_EFUSES = [] self.CALC = [] diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32h2/operations.py esptool-4.7.0+dfsg/espefuse/efuse/esp32h2/operations.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32h2/operations.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32h2/operations.py 2023-12-13 11:05:18.000000000 +0000 @@ -193,38 +193,28 @@ def adc_info(esp, efuses, args): print("") # fmt: off - if efuses["BLK_VERSION_MAJOR"].get() == 1: - print("Temperature Sensor Calibration = {}C".format(efuses["TEMP_SENSOR_CAL"].get())) + if efuses["BLK_VERSION_MINOR"].get() == 2: + print("Temperature Sensor Calibration = {}C".format(efuses["TEMP_CALIB"].get())) print("") print("ADC1 readings stored in efuse BLOCK2:") - print(" MODE0 D1 reading (250mV): {}".format(efuses["ADC1_MODE0_D1"].get())) - print(" MODE0 D2 reading (600mV): {}".format(efuses["ADC1_MODE0_D2"].get())) - - print(" MODE1 D1 reading (250mV): {}".format(efuses["ADC1_MODE1_D1"].get())) - print(" MODE1 D2 reading (800mV): {}".format(efuses["ADC1_MODE1_D2"].get())) - - print(" MODE2 D1 reading (250mV): {}".format(efuses["ADC1_MODE2_D1"].get())) - print(" MODE2 D2 reading (1000mV): {}".format(efuses["ADC1_MODE2_D2"].get())) - - print(" MODE3 D1 reading (250mV): {}".format(efuses["ADC1_MODE3_D1"].get())) - print(" MODE3 D2 reading (2000mV): {}".format(efuses["ADC1_MODE3_D2"].get())) - - print("") - print("ADC2 readings stored in efuse BLOCK2:") - print(" MODE0 D1 reading (250mV): {}".format(efuses["ADC2_MODE0_D1"].get())) - print(" MODE0 D2 reading (600mV): {}".format(efuses["ADC2_MODE0_D2"].get())) - - print(" MODE1 D1 reading (250mV): {}".format(efuses["ADC2_MODE1_D1"].get())) - print(" MODE1 D2 reading (800mV): {}".format(efuses["ADC2_MODE1_D2"].get())) - - print(" MODE2 D1 reading (250mV): {}".format(efuses["ADC2_MODE2_D1"].get())) - print(" MODE2 D2 reading (1000mV): {}".format(efuses["ADC2_MODE2_D2"].get())) - - print(" MODE3 D1 reading (250mV): {}".format(efuses["ADC2_MODE3_D1"].get())) - print(" MODE3 D2 reading (2000mV): {}".format(efuses["ADC2_MODE3_D2"].get())) + print(" AVE_INITCODE_ATTEN0: {}".format(efuses["ADC1_AVE_INITCODE_ATTEN0"].get())) + print(" AVE_INITCODE_ATTEN1: {}".format(efuses["ADC1_AVE_INITCODE_ATTEN1"].get())) + print(" AVE_INITCODE_ATTEN2: {}".format(efuses["ADC1_AVE_INITCODE_ATTEN2"].get())) + print(" AVE_INITCODE_ATTEN3: {}".format(efuses["ADC1_AVE_INITCODE_ATTEN3"].get())) + + print(" HI_DOUT_ATTEN0: {}".format(efuses["ADC1_HI_DOUT_ATTEN0"].get())) + print(" HI_DOUT_ATTEN1: {}".format(efuses["ADC1_HI_DOUT_ATTEN1"].get())) + print(" HI_DOUT_ATTEN2: {}".format(efuses["ADC1_HI_DOUT_ATTEN2"].get())) + print(" HI_DOUT_ATTEN3: {}".format(efuses["ADC1_HI_DOUT_ATTEN3"].get())) + + print(" CH0_ATTEN0_INITCODE_DIFF: {}".format(efuses["ADC1_CH0_ATTEN0_INITCODE_DIFF"].get())) + print(" CH1_ATTEN0_INITCODE_DIFF: {}".format(efuses["ADC1_CH1_ATTEN0_INITCODE_DIFF"].get())) + print(" CH2_ATTEN0_INITCODE_DIFF: {}".format(efuses["ADC1_CH2_ATTEN0_INITCODE_DIFF"].get())) + print(" CH3_ATTEN0_INITCODE_DIFF: {}".format(efuses["ADC1_CH3_ATTEN0_INITCODE_DIFF"].get())) + print(" CH4_ATTEN0_INITCODE_DIFF: {}".format(efuses["ADC1_CH4_ATTEN0_INITCODE_DIFF"].get())) else: - print("BLK_VERSION_MAJOR = {}".format(efuses["BLK_VERSION_MAJOR"].get_meaning())) + print("BLK_VERSION_MINOR = {}".format(efuses["BLK_VERSION_MINOR"].get())) # fmt: on @@ -333,6 +323,15 @@ if efuses[block.key_purpose_name].is_writeable(): disable_wr_protect_key_purpose = True + if keypurpose == "ECDSA_KEY": + if efuses["ECDSA_FORCE_USE_HARDWARE_K"].get() == 0: + # For ECDSA key purpose block permanently enable + # the hardware TRNG supplied k mode (most secure mode) + print("\tECDSA_FORCE_USE_HARDWARE_K: 0 -> 1") + efuses["ECDSA_FORCE_USE_HARDWARE_K"].save(1) + else: + print("\tECDSA_FORCE_USE_HARDWARE_K is already '1'") + if disable_wr_protect_key_purpose: print("\tDisabling write to '%s'." % block.key_purpose_name) efuses[block.key_purpose_name].disable_write() diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py esptool-4.7.0+dfsg/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py 2023-12-13 11:05:18.000000000 +0000 @@ -22,7 +22,7 @@ self.Fields = EfuseDefineFields() self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ self.clean_blocks_wr_regs() self.check_rd_protection_area() self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) elif value == self.REGS.EFUSE_READ_CMD: self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) self.save_to_file() def get_bitlen_of_block(self, blk, wr=False): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32h2beta1/fields.py esptool-4.7.0+dfsg/espefuse/efuse/esp32h2beta1/fields.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32h2beta1/fields.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32h2beta1/fields.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ import binascii import struct +import sys import time from bitstring import BitArray @@ -160,9 +161,13 @@ def wait_efuse_idle(self): deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT while time.time() < deadline: - # if self.read_reg(self.REGS.EFUSE_CMD_REG) == 0: - if self.read_reg(self.REGS.EFUSE_STATUS_REG) & 0x7 == 1: - return + cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + # Due to a hardware error, we have to read READ_CMD again + # to make sure the efuse clock is normal. + # For PGM_CMD it is not necessary. + return raise esptool.FatalError( "Timed out waiting for Efuse controller command to complete" ) @@ -202,7 +207,7 @@ ) print("DIS_DOWNLOAD_MODE is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise print("Established a connection with the chip") @@ -216,7 +221,7 @@ ) print("ENABLE_SECURITY_DOWNLOAD is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise def set_efuse_timing(self): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/__init__.py esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/__init__.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/__init__.py 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,3 @@ +from . import operations +from .emulate_efuse_controller import EmulateEfuseController +from .fields import EspEfuses diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/emulate_efuse_controller.py esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/emulate_efuse_controller.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/emulate_efuse_controller.py 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/emulate_efuse_controller.py 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,92 @@ +# This file describes eFuses controller for ESP32-P4 chip +# +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import reedsolo + +from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters +from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError + + +class EmulateEfuseController(EmulateEfuseControllerBase): + """The class for virtual efuse operation. Using for HOST_TEST.""" + + CHIP_NAME = "ESP32-P4" + mem = None + debug = False + + def __init__(self, efuse_file=None, debug=False): + self.Blocks = EfuseDefineBlocks + self.Fields = EfuseDefineFields() + self.REGS = EfuseDefineRegisters + super(EmulateEfuseController, self).__init__(efuse_file, debug) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) + + """ esptool method start >>""" + + def get_major_chip_version(self): + return 0 + + def get_minor_chip_version(self): + return 0 + + def get_crystal_freq(self): + return 40 # MHz (common for all chips) + + def get_security_info(self): + return { + "flags": 0, + "flash_crypt_cnt": 0, + "key_purposes": 0, + "chip_id": 0, + "api_version": 0, + } + + """ << esptool method end """ + + def handle_writing_event(self, addr, value): + if addr == self.REGS.EFUSE_CMD_REG: + if value & self.REGS.EFUSE_PGM_CMD: + self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) + self.clean_blocks_wr_regs() + self.check_rd_protection_area() + self.write_reg(addr, 0) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) + elif value == self.REGS.EFUSE_READ_CMD: + self.write_reg(addr, 0) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) + self.save_to_file() + + def get_bitlen_of_block(self, blk, wr=False): + if blk.id == 0: + if wr: + return 32 * 8 + else: + return 32 * blk.len + else: + if wr: + rs_coding = 32 * 3 + return 32 * 8 + rs_coding + else: + return 32 * blk.len + + def handle_coding_scheme(self, blk, data): + if blk.id != 0: + # CODING_SCHEME RS applied only for all blocks except BLK0. + coded_bytes = 12 + data.pos = coded_bytes * 8 + plain_data = data.readlist("32*uint:8")[::-1] + # takes 32 bytes + # apply RS encoding + rs = reedsolo.RSCodec(coded_bytes) + # 32 byte of data + 12 bytes RS + calc_encoded_data = list(rs.encode([x for x in plain_data])) + data.pos = 0 + if calc_encoded_data != data.readlist("44*uint:8")[::-1]: + raise FatalError("Error in coding scheme data") + data = data[coded_bytes * 8 :] + if blk.len < 8: + data = data[(8 - blk.len) * 32 :] + return data diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/fields.py esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/fields.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/fields.py 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/fields.py 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,435 @@ +# This file describes eFuses for ESP32-P4 chip +# +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import binascii +import struct +import sys +import time + +from bitstring import BitArray + +import esptool + +import reedsolo + +from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters +from .. import base_fields +from .. import util + + +class EfuseBlock(base_fields.EfuseBlockBase): + def len_of_burn_unit(self): + # The writing register window is 8 registers for any blocks. + # len in bytes + return 8 * 4 + + def __init__(self, parent, param, skip_read=False): + parent.read_coding_scheme() + super(EfuseBlock, self).__init__(parent, param, skip_read=skip_read) + + def apply_coding_scheme(self): + data = self.get_raw(from_read=False)[::-1] + if len(data) < self.len_of_burn_unit(): + add_empty_bytes = self.len_of_burn_unit() - len(data) + data = data + (b"\x00" * add_empty_bytes) + if self.get_coding_scheme() == self.parent.REGS.CODING_SCHEME_RS: + # takes 32 bytes + # apply RS encoding + rs = reedsolo.RSCodec(12) + # 32 byte of data + 12 bytes RS + encoded_data = rs.encode([x for x in data]) + words = struct.unpack("<" + "I" * 11, encoded_data) + # returns 11 words (8 words of data + 3 words of RS coding) + else: + # takes 32 bytes + words = struct.unpack("<" + ("I" * (len(data) // 4)), data) + # returns 8 words + return words + + +class EspEfuses(base_fields.EspEfusesBase): + """ + Wrapper object to manage the efuse fields in a connected ESP bootloader + """ + + debug = False + do_not_confirm = False + + def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + self.Blocks = EfuseDefineBlocks() + self.Fields = EfuseDefineFields() + self.REGS = EfuseDefineRegisters + self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() + self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() + self._esp = esp + self.debug = debug + self.do_not_confirm = do_not_confirm + if esp.CHIP_NAME != "ESP32-P4": + raise esptool.FatalError( + "Expected the 'esp' param for ESP32-P4 chip but got for '%s'." + % (esp.CHIP_NAME) + ) + if not skip_connect: + flags = self._esp.get_security_info()["flags"] + GET_SECURITY_INFO_FLAG_SECURE_DOWNLOAD_ENABLE = 1 << 2 + if flags & GET_SECURITY_INFO_FLAG_SECURE_DOWNLOAD_ENABLE: + raise esptool.FatalError( + "Secure Download Mode is enabled. The tool can not read eFuses." + ) + self.blocks = [ + EfuseBlock(self, self.Blocks.get(block), skip_read=skip_connect) + for block in self.Blocks.BLOCKS + ] + if not skip_connect: + self.get_coding_scheme_warnings() + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] + self.efuses += [ + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS + ] + if skip_connect: + self.efuses += [ + EfuseField.convert(self, efuse) + for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES + ] + else: + # TODO add processing of self.Fields.BLOCK2_CALIBRATION_EFUSES + # if self["BLK_VERSION_MINOR"].get() == 1: + # self.efuses += [ + # EfuseField.convert(self, efuse) + # for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES + # ] + self.efuses += [ + EfuseField.convert(self, efuse) for efuse in self.Fields.CALC + ] + + def __getitem__(self, efuse_name): + """Return the efuse field with the given name""" + for e in self.efuses: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): + return e + new_fields = False + for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): + self.efuses += [ + EfuseField.convert(self, efuse) + for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES + ] + new_fields = True + if new_fields: + for e in self.efuses: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): + return e + raise KeyError + + def read_coding_scheme(self): + self.coding_scheme = self.REGS.CODING_SCHEME_RS + + def print_status_regs(self): + print("") + self.blocks[0].print_block(self.blocks[0].err_bitarray, "err__regs", debug=True) + print( + "{:27} 0x{:08x}".format( + "EFUSE_RD_RS_ERR0_REG", self.read_reg(self.REGS.EFUSE_RD_RS_ERR0_REG) + ) + ) + print( + "{:27} 0x{:08x}".format( + "EFUSE_RD_RS_ERR1_REG", self.read_reg(self.REGS.EFUSE_RD_RS_ERR1_REG) + ) + ) + + def efuse_controller_setup(self): + self.set_efuse_timing() + self.clear_pgm_registers() + self.wait_efuse_idle() + + def write_efuses(self, block): + self.efuse_program(block) + return self.get_coding_scheme_warnings(silent=True) + + def clear_pgm_registers(self): + self.wait_efuse_idle() + for r in range( + self.REGS.EFUSE_PGM_DATA0_REG, self.REGS.EFUSE_PGM_DATA0_REG + 32, 4 + ): + self.write_reg(r, 0) + + def wait_efuse_idle(self): + deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT + while time.time() < deadline: + cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + # Due to a hardware error, we have to read READ_CMD again + # to make sure the efuse clock is normal. + # For PGM_CMD it is not necessary. + return + raise esptool.FatalError( + "Timed out waiting for Efuse controller command to complete" + ) + + def efuse_program(self, block): + self.wait_efuse_idle() + self.write_reg(self.REGS.EFUSE_CONF_REG, self.REGS.EFUSE_WRITE_OP_CODE) + self.write_reg(self.REGS.EFUSE_CMD_REG, self.REGS.EFUSE_PGM_CMD | (block << 2)) + self.wait_efuse_idle() + self.clear_pgm_registers() + self.efuse_read() + + def efuse_read(self): + self.wait_efuse_idle() + self.write_reg(self.REGS.EFUSE_CONF_REG, self.REGS.EFUSE_READ_OP_CODE) + # need to add a delay after triggering EFUSE_READ_CMD, as ROM loader checks some + # efuse registers after each command is completed + # if ENABLE_SECURITY_DOWNLOAD or DIS_DOWNLOAD_MODE is enabled by the current cmd, then we need to try to reconnect to the chip. + try: + self.write_reg( + self.REGS.EFUSE_CMD_REG, self.REGS.EFUSE_READ_CMD, delay_after_us=1000 + ) + self.wait_efuse_idle() + except esptool.FatalError: + secure_download_mode_before = self._esp.secure_download_mode + + try: + self._esp = self.reconnect_chip(self._esp) + except esptool.FatalError: + print("Can not re-connect to the chip") + if not self["DIS_DOWNLOAD_MODE"].get() and self[ + "DIS_DOWNLOAD_MODE" + ].get(from_read=False): + print( + "This is the correct behavior as we are actually burning " + "DIS_DOWNLOAD_MODE which disables the connection to the chip" + ) + print("DIS_DOWNLOAD_MODE is enabled") + print("Successful") + sys.exit(0) # finish without errors + raise + + print("Established a connection with the chip") + if self._esp.secure_download_mode and not secure_download_mode_before: + print("Secure download mode is enabled") + if not self["ENABLE_SECURITY_DOWNLOAD"].get() and self[ + "ENABLE_SECURITY_DOWNLOAD" + ].get(from_read=False): + print( + "espefuse tool can not continue to work in Secure download mode" + ) + print("ENABLE_SECURITY_DOWNLOAD is enabled") + print("Successful") + sys.exit(0) # finish without errors + raise + + def set_efuse_timing(self): + """Set timing registers for burning efuses""" + # Configure clock + apb_freq = self.get_crystal_freq() + if apb_freq != 40: + raise esptool.FatalError( + "The eFuse supports only xtal=40M (xtal was %d)" % apb_freq + ) + # keep default timing settings + + def get_coding_scheme_warnings(self, silent=False): + """Check if the coding scheme has detected any errors.""" + old_addr_reg = 0 + reg_value = 0 + ret_fail = False + for block in self.blocks: + if block.id == 0: + words = [ + self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR0_REG + offs * 4) + for offs in range(5) + ] + block.err_bitarray.pos = 0 + for word in reversed(words): + block.err_bitarray.overwrite(BitArray("uint:32=%d" % word)) + block.num_errors = block.err_bitarray.count(True) + block.fail = block.num_errors != 0 + else: + addr_reg, err_num_mask, err_num_offs, fail_bit = self.REGS.BLOCK_ERRORS[ + block.id + ] + if err_num_mask is None or err_num_offs is None or fail_bit is None: + continue + if addr_reg != old_addr_reg: + old_addr_reg = addr_reg + reg_value = self.read_reg(addr_reg) + block.fail = reg_value & (1 << fail_bit) != 0 + block.num_errors = (reg_value >> err_num_offs) & err_num_mask + ret_fail |= block.fail + if not silent and (block.fail or block.num_errors): + print( + "Error(s) in BLOCK%d [ERRORS:%d FAIL:%d]" + % (block.id, block.num_errors, block.fail) + ) + if (self.debug or ret_fail) and not silent: + self.print_status_regs() + return ret_fail + + def summary(self): + # TODO add support set_flash_voltage - "Flash voltage (VDD_SPI)" + return "" + + +class EfuseField(base_fields.EfuseFieldBase): + @staticmethod + def convert(parent, efuse): + return { + "mac": EfuseMacField, + "keypurpose": EfuseKeyPurposeField, + "t_sensor": EfuseTempSensor, + "adc_tp": EfuseAdcPointCalibration, + }.get(efuse.class_type, EfuseField)(parent, efuse) + + +class EfuseTempSensor(EfuseField): + def get(self, from_read=True): + value = self.get_bitstring(from_read) + sig = -1 if value[0] else 1 + return sig * value[1:].uint * 0.1 + + +class EfuseAdcPointCalibration(EfuseField): + def get(self, from_read=True): + STEP_SIZE = 4 + value = self.get_bitstring(from_read) + sig = -1 if value[0] else 1 + return sig * value[1:].uint * STEP_SIZE + + +class EfuseMacField(EfuseField): + def check_format(self, new_value_str): + if new_value_str is None: + raise esptool.FatalError( + "Required MAC Address in AA:CD:EF:01:02:03 format!" + ) + num_bytes = 8 if self.name == "MAC_EUI64" else 6 + if new_value_str.count(":") != num_bytes - 1: + raise esptool.FatalError( + f"MAC Address needs to be a {num_bytes}-byte hexadecimal format " + "separated by colons (:)!" + ) + hexad = new_value_str.replace(":", "").split(" ", 1)[0] + hexad = hexad.split(" ", 1)[0] if self.is_field_calculated() else hexad + if len(hexad) != num_bytes * 2: + raise esptool.FatalError( + f"MAC Address needs to be a {num_bytes}-byte hexadecimal number " + f"({num_bytes * 2} hexadecimal characters)!" + ) + # order of bytearray = b'\xaa\xcd\xef\x01\x02\x03', + bindata = binascii.unhexlify(hexad) + + if not self.is_field_calculated(): + # unicast address check according to + # https://tools.ietf.org/html/rfc7042#section-2.1 + if esptool.util.byte(bindata, 0) & 0x01: + raise esptool.FatalError("Custom MAC must be a unicast MAC!") + return bindata + + def check(self): + errs, fail = self.parent.get_block_errors(self.block) + if errs != 0 or fail: + output = "Block%d has ERRORS:%d FAIL:%d" % (self.block, errs, fail) + else: + output = "OK" + return "(" + output + ")" + + def get(self, from_read=True): + if self.name == "CUSTOM_MAC": + mac = self.get_raw(from_read)[::-1] + elif self.name == "MAC": + mac = self.get_raw(from_read) + elif self.name == "MAC_EUI64": + mac = self.parent["MAC"].get_bitstring(from_read).copy() + mac_ext = self.parent["MAC_EXT"].get_bitstring(from_read) + mac.insert(mac_ext, 24) + mac = mac.bytes + else: + mac = self.get_raw(from_read) + return "%s %s" % (util.hexify(mac, ":"), self.check()) + + def save(self, new_value): + def print_field(e, new_value): + print( + " - '{}' ({}) {} -> {}".format( + e.name, e.description, e.get_bitstring(), new_value + ) + ) + + if self.name == "CUSTOM_MAC": + bitarray_mac = self.convert_to_bitstring(new_value) + print_field(self, bitarray_mac) + super(EfuseMacField, self).save(new_value) + else: + # Writing the BLOCK1 (MAC_SPI_8M_0) default MAC is not possible, + # as it's written in the factory. + raise esptool.FatalError(f"Burning {self.name} is not supported") + + +# fmt: off +class EfuseKeyPurposeField(EfuseField): + KEY_PURPOSES = [ + ("USER", 0, None, None, "no_need_rd_protect"), # User purposes (software-only use) + ("ECDSA_KEY", 1, None, "Reverse", "need_rd_protect"), # ECDSA key + ("XTS_AES_256_KEY_1", 2, None, "Reverse", "need_rd_protect"), # XTS_AES_256_KEY_1 (flash/PSRAM encryption) + ("XTS_AES_256_KEY_2", 3, None, "Reverse", "need_rd_protect"), # XTS_AES_256_KEY_2 (flash/PSRAM encryption) + ("XTS_AES_128_KEY", 4, None, "Reverse", "need_rd_protect"), # XTS_AES_128_KEY (flash/PSRAM encryption) + ("HMAC_DOWN_ALL", 5, None, None, "need_rd_protect"), # HMAC Downstream mode + ("HMAC_DOWN_JTAG", 6, None, None, "need_rd_protect"), # JTAG soft enable key (uses HMAC Downstream mode) + ("HMAC_DOWN_DIGITAL_SIGNATURE", 7, None, None, "need_rd_protect"), # Digital Signature peripheral key (uses HMAC Downstream mode) + ("HMAC_UP", 8, None, None, "need_rd_protect"), # HMAC Upstream mode + ("SECURE_BOOT_DIGEST0", 9, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST0 (Secure Boot key digest) + ("SECURE_BOOT_DIGEST1", 10, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST1 (Secure Boot key digest) + ("SECURE_BOOT_DIGEST2", 11, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST2 (Secure Boot key digest) + ("KM_INIT_KEY", 12, None, None, "need_rd_protect"), # init key that is used for the generation of AES/ECDSA key + ("XTS_AES_256_KEY", -1, "VIRTUAL", None, "no_need_rd_protect"), # Virtual purpose splits to XTS_AES_256_KEY_1 and XTS_AES_256_KEY_2 + ] +# fmt: on + KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES] + DIGEST_KEY_PURPOSES = [name[0] for name in KEY_PURPOSES if name[2] == "DIGEST"] + + def check_format(self, new_value_str): + # str convert to int: "XTS_AES_128_KEY" - > str(4) + # if int: 4 -> str(4) + raw_val = new_value_str + for purpose_name in self.KEY_PURPOSES: + if purpose_name[0] == new_value_str: + raw_val = str(purpose_name[1]) + break + if raw_val.isdigit(): + if int(raw_val) not in [p[1] for p in self.KEY_PURPOSES if p[1] > 0]: + raise esptool.FatalError("'%s' can not be set (value out of range)" % raw_val) + else: + raise esptool.FatalError("'%s' unknown name" % raw_val) + return raw_val + + def need_reverse(self, new_key_purpose): + for key in self.KEY_PURPOSES: + if key[0] == new_key_purpose: + return key[3] == "Reverse" + + def need_rd_protect(self, new_key_purpose): + for key in self.KEY_PURPOSES: + if key[0] == new_key_purpose: + return key[4] == "need_rd_protect" + + def get(self, from_read=True): + for p in self.KEY_PURPOSES: + if p[1] == self.get_raw(from_read): + return p[0] + return "FORBIDDEN_STATE" + + def get_name(self, raw_val): + for key in self.KEY_PURPOSES: + if key[1] == raw_val: + return key[0] + + def save(self, new_value): + raw_val = int(self.check_format(str(new_value))) + return super(EfuseKeyPurposeField, self).save(raw_val) diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/mem_definition.py esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/mem_definition.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/mem_definition.py 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/mem_definition.py 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,169 @@ +# This file describes eFuses fields and registers for ESP32-P4 chip +# +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os + +import yaml + +from ..mem_definition_base import ( + EfuseBlocksBase, + EfuseFieldsBase, + EfuseRegistersBase, + Field, +) + + +class EfuseDefineRegisters(EfuseRegistersBase): + EFUSE_MEM_SIZE = 0x01FC + 4 + + # EFUSE registers & command/conf values + DR_REG_EFUSE_BASE = 0x5012D000 + EFUSE_PGM_DATA0_REG = DR_REG_EFUSE_BASE + EFUSE_CHECK_VALUE0_REG = DR_REG_EFUSE_BASE + 0x020 + EFUSE_CLK_REG = DR_REG_EFUSE_BASE + 0x1C8 + EFUSE_CONF_REG = DR_REG_EFUSE_BASE + 0x1CC + EFUSE_STATUS_REG = DR_REG_EFUSE_BASE + 0x1D0 + EFUSE_CMD_REG = DR_REG_EFUSE_BASE + 0x1D4 + EFUSE_RD_RS_ERR0_REG = DR_REG_EFUSE_BASE + 0x1C0 + EFUSE_RD_RS_ERR1_REG = DR_REG_EFUSE_BASE + 0x1C4 + EFUSE_RD_REPEAT_ERR0_REG = DR_REG_EFUSE_BASE + 0x17C + EFUSE_RD_REPEAT_ERR1_REG = DR_REG_EFUSE_BASE + 0x180 + EFUSE_RD_REPEAT_ERR2_REG = DR_REG_EFUSE_BASE + 0x184 + EFUSE_RD_REPEAT_ERR3_REG = DR_REG_EFUSE_BASE + 0x188 + EFUSE_RD_REPEAT_ERR4_REG = DR_REG_EFUSE_BASE + 0x18C + EFUSE_DAC_CONF_REG = DR_REG_EFUSE_BASE + 0x1E8 + EFUSE_RD_TIM_CONF_REG = DR_REG_EFUSE_BASE + 0x1EC + EFUSE_WR_TIM_CONF1_REG = DR_REG_EFUSE_BASE + 0x1F0 + EFUSE_WR_TIM_CONF2_REG = DR_REG_EFUSE_BASE + 0x1F4 + EFUSE_DATE_REG = DR_REG_EFUSE_BASE + 0x1FC + EFUSE_WRITE_OP_CODE = 0x5A5A + EFUSE_READ_OP_CODE = 0x5AA5 + EFUSE_PGM_CMD_MASK = 0x3 + EFUSE_PGM_CMD = 0x2 + EFUSE_READ_CMD = 0x1 + + BLOCK_ERRORS = [ + # error_reg, err_num_mask, err_num_offs, fail_bit + (EFUSE_RD_REPEAT_ERR0_REG, None, None, None), # BLOCK0 + (EFUSE_RD_RS_ERR0_REG, 0x7, 0, 3), # MAC_SPI_8M_0 + (EFUSE_RD_RS_ERR0_REG, 0x7, 4, 7), # BLOCK_SYS_DATA + (EFUSE_RD_RS_ERR0_REG, 0x7, 8, 11), # BLOCK_USR_DATA + (EFUSE_RD_RS_ERR0_REG, 0x7, 12, 15), # BLOCK_KEY0 + (EFUSE_RD_RS_ERR0_REG, 0x7, 16, 19), # BLOCK_KEY1 + (EFUSE_RD_RS_ERR0_REG, 0x7, 20, 23), # BLOCK_KEY2 + (EFUSE_RD_RS_ERR0_REG, 0x7, 24, 27), # BLOCK_KEY3 + (EFUSE_RD_RS_ERR0_REG, 0x7, 28, 31), # BLOCK_KEY4 + (EFUSE_RD_RS_ERR1_REG, 0x7, 0, 3), # BLOCK_KEY5 + (EFUSE_RD_RS_ERR1_REG, 0x7, 4, 7), # BLOCK_SYS_DATA2 + ] + + # EFUSE_WR_TIM_CONF2_REG + EFUSE_PWR_OFF_NUM_S = 0 + EFUSE_PWR_OFF_NUM_M = 0xFFFF << EFUSE_PWR_OFF_NUM_S + + # EFUSE_WR_TIM_CONF1_REG + EFUSE_PWR_ON_NUM_S = 8 + EFUSE_PWR_ON_NUM_M = 0x0000FFFF << EFUSE_PWR_ON_NUM_S + + # EFUSE_DAC_CONF_REG + EFUSE_DAC_CLK_DIV_S = 0 + EFUSE_DAC_CLK_DIV_M = 0xFF << EFUSE_DAC_CLK_DIV_S + + # EFUSE_DAC_CONF_REG + EFUSE_DAC_NUM_S = 9 + EFUSE_DAC_NUM_M = 0xFF << EFUSE_DAC_NUM_S + + +class EfuseDefineBlocks(EfuseBlocksBase): + __base_rd_regs = EfuseDefineRegisters.DR_REG_EFUSE_BASE + __base_wr_regs = EfuseDefineRegisters.EFUSE_PGM_DATA0_REG + # List of efuse blocks + # fmt: off + BLOCKS = [ + # Name, Alias, Index, Read address, Write address, Write protect bit, Read protect bit, Len, key_purpose + ("BLOCK0", [], 0, __base_rd_regs + 0x02C, __base_wr_regs, None, None, 6, None), + ("MAC_SPI_8M_0", ["BLOCK1"], 1, __base_rd_regs + 0x044, __base_wr_regs, 20, None, 6, None), + ("BLOCK_SYS_DATA", ["BLOCK2"], 2, __base_rd_regs + 0x05C, __base_wr_regs, 21, None, 8, None), + ("BLOCK_USR_DATA", ["BLOCK3"], 3, __base_rd_regs + 0x07C, __base_wr_regs, 22, None, 8, None), + ("BLOCK_KEY0", ["BLOCK4"], 4, __base_rd_regs + 0x09C, __base_wr_regs, 23, 0, 8, "KEY_PURPOSE_0"), + ("BLOCK_KEY1", ["BLOCK5"], 5, __base_rd_regs + 0x0BC, __base_wr_regs, 24, 1, 8, "KEY_PURPOSE_1"), + ("BLOCK_KEY2", ["BLOCK6"], 6, __base_rd_regs + 0x0DC, __base_wr_regs, 25, 2, 8, "KEY_PURPOSE_2"), + ("BLOCK_KEY3", ["BLOCK7"], 7, __base_rd_regs + 0x0FC, __base_wr_regs, 26, 3, 8, "KEY_PURPOSE_3"), + ("BLOCK_KEY4", ["BLOCK8"], 8, __base_rd_regs + 0x11C, __base_wr_regs, 27, 4, 8, "KEY_PURPOSE_4"), + ("BLOCK_KEY5", ["BLOCK9"], 9, __base_rd_regs + 0x13C, __base_wr_regs, 28, 5, 8, "KEY_PURPOSE_5"), + ("BLOCK_SYS_DATA2", ["BLOCK10"], 10, __base_rd_regs + 0x15C, __base_wr_regs, 29, 6, 8, None), + ] + # fmt: on + + def get_burn_block_data_names(self): + list_of_names = [] + for block in self.BLOCKS: + blk = self.get(block) + if blk.name: + list_of_names.append(blk.name) + if blk.alias: + for alias in blk.alias: + list_of_names.append(alias) + return list_of_names + + +class EfuseDefineFields(EfuseFieldsBase): + def __init__(self) -> None: + # List of efuse fields from TRM the chapter eFuse Controller. + self.EFUSES = [] + + self.KEYBLOCKS = [] + + # if BLK_VERSION_MINOR is 1, these efuse fields are in BLOCK2 + self.BLOCK2_CALIBRATION_EFUSES = [] + + self.CALC = [] + + dir_name = os.path.dirname(os.path.abspath(__file__)) + dir_name, file_name = os.path.split(dir_name) + file_name = file_name + ".yaml" + dir_name, _ = os.path.split(dir_name) + efuse_file = os.path.join(dir_name, "efuse_defs", file_name) + with open(f"{efuse_file}", "r") as r_file: + e_desc = yaml.safe_load(r_file) + super().__init__(e_desc) + + for i, efuse in enumerate(self.ALL_EFUSES): + if efuse.name in [ + "BLOCK_USR_DATA", + "BLOCK_KEY0", + "BLOCK_KEY1", + "BLOCK_KEY2", + "BLOCK_KEY3", + "BLOCK_KEY4", + "BLOCK_KEY5", + "BLOCK_SYS_DATA2", + ]: + if efuse.name == "BLOCK_USR_DATA": + efuse.bit_len = 256 + efuse.type = "bytes:32" + self.KEYBLOCKS.append(efuse) + self.ALL_EFUSES[i] = None + + elif efuse.category == "calibration": + self.BLOCK2_CALIBRATION_EFUSES.append(efuse) + self.ALL_EFUSES[i] = None + + f = Field() + f.name = "MAC_EUI64" + f.block = 1 + f.bit_len = 64 + f.type = f"bytes:{f.bit_len // 8}" + f.category = "MAC" + f.class_type = "mac" + f.description = "calc MAC_EUI64 = MAC[0]:MAC[1]:MAC[2]:MAC_EXT[0]:MAC_EXT[1]:MAC[3]:MAC[4]:MAC[5]" + self.CALC.append(f) + + for efuse in self.ALL_EFUSES: + if efuse is not None: + self.EFUSES.append(efuse) + + self.ALL_EFUSES = [] diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/operations.py esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/operations.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32p4/operations.py 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32p4/operations.py 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,458 @@ +# This file includes the operations with eFuses for ESP32-P4 chip +# +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import argparse +import io +import os # noqa: F401. It is used in IDF scripts +import traceback + +import espsecure + +import esptool + +from . import fields +from .. import util +from ..base_operations import ( + add_common_commands, + add_force_write_always, + add_show_sensitive_info_option, + burn_bit, + burn_block_data, + burn_efuse, + check_error, + dump, + read_protect_efuse, + summary, + write_protect_efuse, +) + + +def protect_options(p): + p.add_argument( + "--no-write-protect", + help="Disable write-protecting of the key. The key remains writable. " + "(The keys use the RS coding scheme that does not support " + "post-write data changes. Forced write can damage RS encoding bits.) " + "The write-protecting of keypurposes does not depend on the option, " + "it will be set anyway.", + action="store_true", + ) + p.add_argument( + "--no-read-protect", + help="Disable read-protecting of the key. The key remains readable software." + "The key with keypurpose[USER, RESERVED and *_DIGEST] " + "will remain readable anyway. For the rest keypurposes the read-protection " + "will be defined the option (Read-protect by default).", + action="store_true", + ) + + +def add_commands(subparsers, efuses): + add_common_commands(subparsers, efuses) + burn_key = subparsers.add_parser( + "burn_key", help="Burn the key block with the specified name" + ) + protect_options(burn_key) + add_force_write_always(burn_key) + add_show_sensitive_info_option(burn_key) + burn_key.add_argument( + "block", + help="Key block to burn", + action="append", + choices=efuses.BLOCKS_FOR_KEYS, + ) + burn_key.add_argument( + "keyfile", + help="File containing 256 bits of binary key data. For the ECDSA_KEY purpose use PEM file.", + action="append", + type=argparse.FileType("rb"), + ) + burn_key.add_argument( + "keypurpose", + help="Purpose to set.", + action="append", + choices=fields.EfuseKeyPurposeField.KEY_PURPOSES_NAME, + ) + for _ in efuses.BLOCKS_FOR_KEYS: + burn_key.add_argument( + "block", + help="Key block to burn", + nargs="?", + action="append", + metavar="BLOCK", + choices=efuses.BLOCKS_FOR_KEYS, + ) + burn_key.add_argument( + "keyfile", + help="File containing 256 bits of binary key data. For the ECDSA_KEY purpose use PEM file.", + nargs="?", + action="append", + metavar="KEYFILE", + type=argparse.FileType("rb"), + ) + burn_key.add_argument( + "keypurpose", + help="Purpose to set.", + nargs="?", + action="append", + metavar="KEYPURPOSE", + choices=fields.EfuseKeyPurposeField.KEY_PURPOSES_NAME, + ) + + burn_key_digest = subparsers.add_parser( + "burn_key_digest", + help="Parse a RSA public key and burn the digest to key efuse block", + ) + protect_options(burn_key_digest) + add_force_write_always(burn_key_digest) + add_show_sensitive_info_option(burn_key_digest) + burn_key_digest.add_argument( + "block", + help="Key block to burn", + action="append", + choices=efuses.BLOCKS_FOR_KEYS, + ) + burn_key_digest.add_argument( + "keyfile", + help="Key file to digest (PEM format)", + action="append", + type=argparse.FileType("rb"), + ) + burn_key_digest.add_argument( + "keypurpose", + help="Purpose to set.", + action="append", + choices=fields.EfuseKeyPurposeField.DIGEST_KEY_PURPOSES, + ) + for _ in efuses.BLOCKS_FOR_KEYS: + burn_key_digest.add_argument( + "block", + help="Key block to burn", + nargs="?", + action="append", + metavar="BLOCK", + choices=efuses.BLOCKS_FOR_KEYS, + ) + burn_key_digest.add_argument( + "keyfile", + help="Key file to digest (PEM format)", + nargs="?", + action="append", + metavar="KEYFILE", + type=argparse.FileType("rb"), + ) + burn_key_digest.add_argument( + "keypurpose", + help="Purpose to set.", + nargs="?", + action="append", + metavar="KEYPURPOSE", + choices=fields.EfuseKeyPurposeField.DIGEST_KEY_PURPOSES, + ) + + p = subparsers.add_parser( + "set_flash_voltage", + help="Permanently set the internal flash voltage regulator " + "to either 1.8V, 3.3V or OFF. " + "This means GPIO45 can be high or low at reset without " + "changing the flash voltage.", + ) + p.add_argument("voltage", help="Voltage selection", choices=["1.8V", "3.3V", "OFF"]) + + p = subparsers.add_parser( + "burn_custom_mac", help="Burn a 48-bit Custom MAC Address to EFUSE BLOCK3." + ) + p.add_argument( + "mac", + help="Custom MAC Address to burn given in hexadecimal format with bytes " + "separated by colons (e.g. AA:CD:EF:01:02:03).", + type=fields.base_fields.CheckArgValue(efuses, "CUSTOM_MAC"), + ) + add_force_write_always(p) + + p = subparsers.add_parser("get_custom_mac", help="Prints the Custom MAC Address.") + + +def burn_custom_mac(esp, efuses, args): + print("Not supported yet") + + +def get_custom_mac(esp, efuses, args): + print("Not supported yet") + + +def set_flash_voltage(esp, efuses, args): + raise esptool.FatalError("set_flash_voltage is not supported!") + + +def adc_info(esp, efuses, args): + print("not supported yet") + + +def key_block_is_unused(block, key_purpose_block): + if not block.is_readable() or not block.is_writeable(): + return False + + if key_purpose_block.get() != "USER" or not key_purpose_block.is_writeable(): + return False + + if not block.get_bitstring().all(False): + return False + + return True + + +def get_next_key_block(efuses, current_key_block, block_name_list): + key_blocks = [b for b in efuses.blocks if b.key_purpose_name] + start = key_blocks.index(current_key_block) + + # Sort key blocks so that we pick the next free block (and loop around if necessary) + key_blocks = key_blocks[start:] + key_blocks[0:start] + + # Exclude any other blocks that will be be burned + key_blocks = [b for b in key_blocks if b.name not in block_name_list] + + for block in key_blocks: + key_purpose_block = efuses[block.key_purpose_name] + if key_block_is_unused(block, key_purpose_block): + return block + + return None + + +def split_512_bit_key(efuses, block_name_list, datafile_list, keypurpose_list): + i = keypurpose_list.index("XTS_AES_256_KEY") + block_name = block_name_list[i] + + block_num = efuses.get_index_block_by_name(block_name) + block = efuses.blocks[block_num] + + data = datafile_list[i].read() + if len(data) != 64: + raise esptool.FatalError( + "Incorrect key file size %d, XTS_AES_256_KEY should be 64 bytes" % len(data) + ) + + key_block_2 = get_next_key_block(efuses, block, block_name_list) + if not key_block_2: + raise esptool.FatalError("XTS_AES_256_KEY requires two free keyblocks") + + keypurpose_list.append("XTS_AES_256_KEY_1") + datafile_list.append(io.BytesIO(data[:32])) + block_name_list.append(block_name) + + keypurpose_list.append("XTS_AES_256_KEY_2") + datafile_list.append(io.BytesIO(data[32:])) + block_name_list.append(key_block_2.name) + + keypurpose_list.pop(i) + datafile_list.pop(i) + block_name_list.pop(i) + + +def burn_key(esp, efuses, args, digest=None): + if digest is None: + datafile_list = args.keyfile[ + 0 : len([name for name in args.keyfile if name is not None]) : + ] + else: + datafile_list = digest[0 : len([name for name in digest if name is not None]) :] + efuses.force_write_always = args.force_write_always + block_name_list = args.block[ + 0 : len([name for name in args.block if name is not None]) : + ] + keypurpose_list = args.keypurpose[ + 0 : len([name for name in args.keypurpose if name is not None]) : + ] + + if "XTS_AES_256_KEY" in keypurpose_list: + # XTS_AES_256_KEY is not an actual HW key purpose, needs to be split into + # XTS_AES_256_KEY_1 and XTS_AES_256_KEY_2 + split_512_bit_key(efuses, block_name_list, datafile_list, keypurpose_list) + + util.check_duplicate_name_in_list(block_name_list) + if len(block_name_list) != len(datafile_list) or len(block_name_list) != len( + keypurpose_list + ): + raise esptool.FatalError( + "The number of blocks (%d), datafile (%d) and keypurpose (%d) " + "should be the same." + % (len(block_name_list), len(datafile_list), len(keypurpose_list)) + ) + + print("Burn keys to blocks:") + for block_name, datafile, keypurpose in zip( + block_name_list, datafile_list, keypurpose_list + ): + efuse = None + for block in efuses.blocks: + if block_name == block.name or block_name in block.alias: + efuse = efuses[block.name] + if efuse is None: + raise esptool.FatalError("Unknown block name - %s" % (block_name)) + num_bytes = efuse.bit_len // 8 + + block_num = efuses.get_index_block_by_name(block_name) + block = efuses.blocks[block_num] + + if digest is None: + if keypurpose == "ECDSA_KEY": + sk = espsecure.load_ecdsa_signing_key(datafile) + data = sk.to_string() + if len(data) == 24: + # the private key is 24 bytes long for NIST192p, add 8 bytes of padding + data = b"\x00" * 8 + data + else: + data = datafile.read() + else: + data = datafile + + print(" - %s" % (efuse.name), end=" ") + revers_msg = None + if efuses[block.key_purpose_name].need_reverse(keypurpose): + revers_msg = f"\tReversing byte order for {keypurpose} hardware peripheral" + data = data[::-1] + print( + "-> [{}]".format( + util.hexify(data, " ") + if args.show_sensitive_info + else " ".join(["??"] * len(data)) + ) + ) + if revers_msg: + print(revers_msg) + if len(data) != num_bytes: + raise esptool.FatalError( + "Incorrect key file size %d. Key file must be %d bytes (%d bits) " + "of raw binary key data." % (len(data), num_bytes, num_bytes * 8) + ) + + if efuses[block.key_purpose_name].need_rd_protect(keypurpose): + read_protect = False if args.no_read_protect else True + else: + read_protect = False + write_protect = not args.no_write_protect + + # using efuse instead of a block gives the advantage of checking it as the whole field. + efuse.save(data) + + disable_wr_protect_key_purpose = False + if efuses[block.key_purpose_name].get() != keypurpose: + if efuses[block.key_purpose_name].is_writeable(): + print( + "\t'%s': '%s' -> '%s'." + % ( + block.key_purpose_name, + efuses[block.key_purpose_name].get(), + keypurpose, + ) + ) + efuses[block.key_purpose_name].save(keypurpose) + disable_wr_protect_key_purpose = True + else: + raise esptool.FatalError( + "It is not possible to change '%s' to '%s' " + "because write protection bit is set." + % (block.key_purpose_name, keypurpose) + ) + else: + print("\t'%s' is already '%s'." % (block.key_purpose_name, keypurpose)) + if efuses[block.key_purpose_name].is_writeable(): + disable_wr_protect_key_purpose = True + + if disable_wr_protect_key_purpose: + print("\tDisabling write to '%s'." % block.key_purpose_name) + efuses[block.key_purpose_name].disable_write() + + if read_protect: + print("\tDisabling read to key block") + efuse.disable_read() + + if write_protect: + print("\tDisabling write to key block") + efuse.disable_write() + print("") + + if not write_protect: + print("Keys will remain writeable (due to --no-write-protect)") + if args.no_read_protect: + print("Keys will remain readable (due to --no-read-protect)") + + if not efuses.burn_all(check_batch_mode=True): + return + print("Successful") + + +def burn_key_digest(esp, efuses, args): + digest_list = [] + datafile_list = args.keyfile[ + 0 : len([name for name in args.keyfile if name is not None]) : + ] + block_list = args.block[ + 0 : len([block for block in args.block if block is not None]) : + ] + for block_name, datafile in zip(block_list, datafile_list): + efuse = None + for block in efuses.blocks: + if block_name == block.name or block_name in block.alias: + efuse = efuses[block.name] + if efuse is None: + raise esptool.FatalError("Unknown block name - %s" % (block_name)) + num_bytes = efuse.bit_len // 8 + digest = espsecure._digest_sbv2_public_key(datafile) + if len(digest) != num_bytes: + raise esptool.FatalError( + "Incorrect digest size %d. Digest must be %d bytes (%d bits) " + "of raw binary key data." % (len(digest), num_bytes, num_bytes * 8) + ) + digest_list.append(digest) + burn_key(esp, efuses, args, digest=digest_list) + + +def espefuse(esp, efuses, args, command): + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers(dest="operation") + add_commands(subparsers, efuses) + try: + cmd_line_args = parser.parse_args(command.split()) + except SystemExit: + traceback.print_stack() + raise esptool.FatalError('"{}" - incorrect command'.format(command)) + if cmd_line_args.operation == "execute_scripts": + configfiles = cmd_line_args.configfiles + index = cmd_line_args.index + # copy arguments from args to cmd_line_args + vars(cmd_line_args).update(vars(args)) + if cmd_line_args.operation == "execute_scripts": + cmd_line_args.configfiles = configfiles + cmd_line_args.index = index + if cmd_line_args.operation is None: + parser.print_help() + parser.exit(1) + operation_func = globals()[cmd_line_args.operation] + # each 'operation' is a module-level function of the same name + operation_func(esp, efuses, cmd_line_args) + + +def execute_scripts(esp, efuses, args): + efuses.batch_mode_cnt += 1 + del args.operation + scripts = args.scripts + del args.scripts + + for file in scripts: + with open(file.name, "r") as file: + exec(compile(file.read(), file.name, "exec")) + + if args.debug: + for block in efuses.blocks: + data = block.get_bitstring(from_read=False) + block.print_block(data, "regs_for_burn", args.debug) + + efuses.batch_mode_cnt -= 1 + if not efuses.burn_all(check_batch_mode=True): + return + print("Successful") diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32s2/emulate_efuse_controller.py esptool-4.7.0+dfsg/espefuse/efuse/esp32s2/emulate_efuse_controller.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32s2/emulate_efuse_controller.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32s2/emulate_efuse_controller.py 2023-12-13 11:05:18.000000000 +0000 @@ -22,7 +22,7 @@ self.Fields = EfuseDefineFields() self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ self.clean_blocks_wr_regs() self.check_rd_protection_area() self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) elif value == self.REGS.EFUSE_READ_CMD: self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) self.save_to_file() def get_bitlen_of_block(self, blk, wr=False): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32s2/fields.py esptool-4.7.0+dfsg/espefuse/efuse/esp32s2/fields.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32s2/fields.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32s2/fields.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ import binascii import struct +import sys import time from bitstring import BitArray @@ -160,9 +161,13 @@ def wait_efuse_idle(self): deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT while time.time() < deadline: - # if self.read_reg(self.EFUSE_CMD_REG) == 0: - if self.read_reg(self.REGS.EFUSE_STATUS_REG) & 0x7 == 1: - return + cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + # Due to a hardware error, we have to read READ_CMD again + # to make sure the efuse clock is normal. + # For PGM_CMD it is not necessary. + return raise esptool.FatalError( "Timed out waiting for Efuse controller command to complete" ) @@ -202,7 +207,7 @@ ) print("DIS_DOWNLOAD_MODE is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise print("Established a connection with the chip") @@ -216,7 +221,7 @@ ) print("ENABLE_SECURITY_DOWNLOAD is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise def set_efuse_timing(self): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32s3/emulate_efuse_controller.py esptool-4.7.0+dfsg/espefuse/efuse/esp32s3/emulate_efuse_controller.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32s3/emulate_efuse_controller.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32s3/emulate_efuse_controller.py 2023-12-13 11:05:18.000000000 +0000 @@ -22,7 +22,7 @@ self.Fields = EfuseDefineFields() self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ self.clean_blocks_wr_regs() self.check_rd_protection_area() self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) elif value == self.REGS.EFUSE_READ_CMD: self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) self.save_to_file() def get_bitlen_of_block(self, blk, wr=False): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32s3/fields.py esptool-4.7.0+dfsg/espefuse/efuse/esp32s3/fields.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32s3/fields.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32s3/fields.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ import binascii import struct +import sys import time from bitstring import BitArray @@ -160,9 +161,13 @@ def wait_efuse_idle(self): deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT while time.time() < deadline: - # if self.read_reg(self.EFUSE_CMD_REG) == 0: - if self.read_reg(self.REGS.EFUSE_STATUS_REG) & 0x7 == 1: - return + cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + # Due to a hardware error, we have to read READ_CMD again + # to make sure the efuse clock is normal. + # For PGM_CMD it is not necessary. + return raise esptool.FatalError( "Timed out waiting for Efuse controller command to complete" ) @@ -202,7 +207,7 @@ ) print("DIS_DOWNLOAD_MODE is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise print("Established a connection with the chip") @@ -216,7 +221,7 @@ ) print("ENABLE_SECURITY_DOWNLOAD is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise def set_efuse_timing(self): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py esptool-4.7.0+dfsg/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py 2023-12-13 11:05:18.000000000 +0000 @@ -22,7 +22,7 @@ self.Fields = EfuseDefineFields() self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ self.clean_blocks_wr_regs() self.check_rd_protection_area() self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) elif value == self.REGS.EFUSE_READ_CMD: self.write_reg(addr, 0) - self.write_reg(self.REGS.EFUSE_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) self.save_to_file() def get_bitlen_of_block(self, blk, wr=False): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse/esp32s3beta2/fields.py esptool-4.7.0+dfsg/espefuse/efuse/esp32s3beta2/fields.py --- esptool-4.6.2+dfsg/espefuse/efuse/esp32s3beta2/fields.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse/esp32s3beta2/fields.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ import binascii import struct +import sys import time from bitstring import BitArray @@ -160,9 +161,13 @@ def wait_efuse_idle(self): deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT while time.time() < deadline: - # if self.read_reg(self.EFUSE_CMD_REG) == 0: - if self.read_reg(self.REGS.EFUSE_STATUS_REG) & 0x7 == 1: - return + cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0: + # Due to a hardware error, we have to read READ_CMD again + # to make sure the efuse clock is normal. + # For PGM_CMD it is not necessary. + return raise esptool.FatalError( "Timed out waiting for Efuse controller command to complete" ) @@ -202,7 +207,7 @@ ) print("DIS_DOWNLOAD_MODE is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise print("Established a connection with the chip") @@ -216,7 +221,7 @@ ) print("ENABLE_SECURITY_DOWNLOAD is enabled") print("Successful") - exit(0) # finish without errors + sys.exit(0) # finish without errors raise def set_efuse_timing(self): diff -Nru esptool-4.6.2+dfsg/espefuse/efuse_defs/esp32c3.yaml esptool-4.7.0+dfsg/espefuse/efuse_defs/esp32c3.yaml --- esptool-4.6.2+dfsg/espefuse/efuse_defs/esp32c3.yaml 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse_defs/esp32c3.yaml 2023-12-13 11:05:18.000000000 +0000 @@ -1,4 +1,4 @@ -VER_NO: a85f874ae2b6538ca48b7c3db4a79531 +VER_NO: 4622cf9245401eca0eb1df8122449a6d EFUSES: WR_DIS : {show: y, blk : 0, word: 0, pos : 0, len : 32, start : 0, type : 'uint:32', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Disable programming of individual eFuses, rloc: EFUSE_RD_WR_DIS_REG, bloc: 'B0,B1,B2,B3'} RD_DIS : {show: y, blk : 0, word: 1, pos : 0, len : 7, start : 32, type : 'uint:7', wr_dis : 0, rd_dis: null, alt : '', dict : '', desc: Disable reading from BlOCK4-10, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[6:0]', bloc: 'B4[6:0]'} @@ -71,8 +71,10 @@ WAFER_VERSION_MINOR_LO : {show: y, blk : 1, word: 3, pos: 18, len : 3, start: 114, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MINOR least significant bits, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[20:18]', bloc: 'B14[4:2]'} PKG_VERSION : {show: y, blk : 1, word: 3, pos: 21, len : 3, start: 117, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Package version, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[23:21]', bloc: 'B14[7:5]'} BLK_VERSION_MINOR : {show: y, blk : 1, word: 3, pos: 24, len : 3, start: 120, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLK_VERSION_MINOR, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[26:24]', bloc: 'B15[2:0]'} - RESERVED_1_123 : {show: n, blk : 1, word: 3, pos: 27, len : 5, start: 123, type : 'uint:5', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[31:27]', bloc: 'B15[7:3]'} - RESERVED_1_128 : {show: n, blk : 1, word: 4, pos : 0, len : 7, start: 128, type : 'uint:7', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[6:0]', bloc: 'B16[6:0]'} + FLASH_CAP : {show: y, blk : 1, word: 3, pos: 27, len : 3, start: 123, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict: '{0: "None", 1: "4M", 2: "2M", 3: "1M", 4: "8M"}', desc: Flash capacity, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[29:27]', bloc: 'B15[5:3]'} + FLASH_TEMP : {show: y, blk : 1, word: 3, pos: 30, len : 2, start: 126, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict: '{0: "None", 1: "105C", 2: "85C"}', desc: Flash temperature, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[31:30]', bloc: 'B15[7:6]'} + FLASH_VENDOR : {show: y, blk : 1, word: 4, pos : 0, len : 3, start: 128, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict: '{0: "None", 1: "XMC", 2: "GD", 3: "FM", 4: "TT", 5: "ZBIT"}', desc: Flash vendor, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[2:0]', bloc: 'B16[2:0]'} + RESERVED_1_131 : {show: n, blk : 1, word: 4, pos : 3, len : 4, start: 131, type : 'uint:4', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[6:3]', bloc: 'B16[6:3]'} K_RTC_LDO : {show: y, blk : 1, word: 4, pos : 7, len : 7, start: 135, type : 'uint:7', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 K_RTC_LDO, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[13:7]', bloc: 'B16[7],B17[5:0]'} K_DIG_LDO : {show: y, blk : 1, word: 4, pos: 14, len : 7, start: 142, type : 'uint:7', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 K_DIG_LDO, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[20:14]', bloc: 'B17[7:6],B18[4:0]'} V_RTC_DBIAS20 : {show: y, blk : 1, word: 4, pos: 21, len : 8, start: 149, type : 'uint:8', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 voltage of rtc dbias20, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[28:21]', bloc: 'B18[7:5],B19[4:0]'} diff -Nru esptool-4.6.2+dfsg/espefuse/efuse_defs/esp32h2.yaml esptool-4.7.0+dfsg/espefuse/efuse_defs/esp32h2.yaml --- esptool-4.6.2+dfsg/espefuse/efuse_defs/esp32h2.yaml 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse_defs/esp32h2.yaml 2023-12-13 11:05:18.000000000 +0000 @@ -1,4 +1,4 @@ -VER_NO: 4df10f83de85f2d830b7c466aabb28e7 +VER_NO: b69ddcfb39a412df490e3facbbfb46b2 EFUSES: WR_DIS : {show: y, blk : 0, word: 0, pos : 0, len : 32, start : 0, type : 'uint:32', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Disable programming of individual eFuses, rloc: EFUSE_RD_WR_DIS_REG, bloc: 'B0,B1,B2,B3'} RD_DIS : {show: y, blk : 0, word: 1, pos : 0, len : 7, start : 32, type : 'uint:7', wr_dis : 0, rd_dis: null, alt : '', dict : '', desc: Disable reading from BlOCK4-10, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[6:0]', bloc: 'B4[6:0]'} @@ -75,10 +75,21 @@ BLK_VERSION_MINOR : {show: y, blk : 2, word: 4, pos : 2, len : 3, start: 130, type : 'uint:3', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: 'BLK_VERSION_MINOR of BLOCK2. 1: RF Calibration data in BLOCK1', rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[4:2]', bloc: 'B16[4:2]'} BLK_VERSION_MAJOR : {show: y, blk : 2, word: 4, pos : 5, len : 2, start: 133, type : 'uint:2', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: BLK_VERSION_MAJOR of BLOCK2, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[6:5]', bloc: 'B16[6:5]'} DISABLE_BLK_VERSION_MAJOR : {show: y, blk : 2, word: 4, pos : 7, len : 1, start: 135, type : bool, wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Disables check of blk version major, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[7]', bloc: 'B16[7]'} - RESERVED_2_136 : {show: n, blk : 2, word: 4, pos : 8, len : 24, start: 136, type : 'uint:24', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[31:8]', bloc: 'B17,B18,B19'} - SYS_DATA_PART1_5 : {show: n, blk : 2, word: 5, pos : 0, len : 32, start: 160, type : 'uint:32', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Stores the fifth 32 bits of the first part of system data, rloc: EFUSE_RD_SYS_PART1_DATA5_REG, bloc: 'B20,B21,B22,B23'} - SYS_DATA_PART1_6 : {show: n, blk : 2, word: 6, pos : 0, len : 32, start: 192, type : 'uint:32', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Stores the sixth 32 bits of the first part of system data, rloc: EFUSE_RD_SYS_PART1_DATA6_REG, bloc: 'B24,B25,B26,B27'} - SYS_DATA_PART1_7 : {show: n, blk : 2, word: 7, pos : 0, len : 32, start: 224, type : 'uint:32', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Stores the seventh 32 bits of the first part of system data, rloc: EFUSE_RD_SYS_PART1_DATA7_REG, bloc: 'B28,B29,B30,B31'} + TEMP_CALIB : {show: y, blk : 2, word: 4, pos : 8, len : 9, start: 136, type : 'uint:9', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Temperature calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[16:8]', bloc: 'B17,B18[0]'} + ADC1_AVE_INITCODE_ATTEN0 : {show: y, blk : 2, word: 4, pos: 17, len : 10, start: 145, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[26:17]', bloc: 'B18[7:1],B19[2:0]'} + ADC1_AVE_INITCODE_ATTEN1 : {show: y, blk : 2, word: 4, pos: 27, len : 10, start: 155, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[31:27]', bloc: 'B19[7:3],B20[4:0]'} + ADC1_AVE_INITCODE_ATTEN2 : {show: y, blk : 2, word: 5, pos : 5, len : 10, start: 165, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[14:5]', bloc: 'B20[7:5],B21[6:0]'} + ADC1_AVE_INITCODE_ATTEN3 : {show: y, blk : 2, word: 5, pos: 15, len : 10, start: 175, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[24:15]', bloc: 'B21[7],B22,B23[0]'} + ADC1_HI_DOUT_ATTEN0 : {show: y, blk : 2, word: 5, pos: 25, len : 10, start: 185, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[31:25]', bloc: 'B23[7:1],B24[2:0]'} + ADC1_HI_DOUT_ATTEN1 : {show: y, blk : 2, word: 6, pos : 3, len : 10, start: 195, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[12:3]', bloc: 'B24[7:3],B25[4:0]'} + ADC1_HI_DOUT_ATTEN2 : {show: y, blk : 2, word: 6, pos: 13, len : 10, start: 205, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[22:13]', bloc: 'B25[7:5],B26[6:0]'} + ADC1_HI_DOUT_ATTEN3 : {show: y, blk : 2, word: 6, pos: 23, len : 10, start: 215, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[31:23]', bloc: 'B26[7],B27,B28[0]'} + ADC1_CH0_ATTEN0_INITCODE_DIFF : {show: y, blk : 2, word: 7, pos : 1, len : 4, start: 225, type : 'uint:4', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[4:1]', bloc: 'B28[4:1]'} + ADC1_CH1_ATTEN0_INITCODE_DIFF : {show: y, blk : 2, word: 7, pos : 5, len : 4, start: 229, type : 'uint:4', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[8:5]', bloc: 'B28[7:5],B29[0]'} + ADC1_CH2_ATTEN0_INITCODE_DIFF : {show: y, blk : 2, word: 7, pos : 9, len : 4, start: 233, type : 'uint:4', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[12:9]', bloc: 'B29[4:1]'} + ADC1_CH3_ATTEN0_INITCODE_DIFF : {show: y, blk : 2, word: 7, pos: 13, len : 4, start: 237, type : 'uint:4', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[16:13]', bloc: 'B29[7:5],B30[0]'} + ADC1_CH4_ATTEN0_INITCODE_DIFF : {show: y, blk : 2, word: 7, pos: 17, len : 4, start: 241, type : 'uint:4', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[20:17]', bloc: 'B30[4:1]'} + RESERVED_2_245 : {show: n, blk : 2, word: 7, pos: 21, len : 11, start: 245, type : 'uint:11', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[31:21]', bloc: 'B30[7:5],B31'} BLOCK_USR_DATA : {show: y, blk : 3, word: 0, pos : 0, len: 192, start : 0, type: 'bytes:24', wr_dis : 22, rd_dis: null, alt : USER_DATA, dict : '', desc: User data, rloc: EFUSE_RD_USR_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23'} RESERVED_3_192 : {show: n, blk : 3, word: 6, pos : 0, len : 8, start: 192, type : 'uint:8', wr_dis : 22, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_USR_DATA6_REG[7:0]', bloc: B24} CUSTOM_MAC : {show: y, blk : 3, word: 6, pos : 8, len : 48, start: 200, type : 'bytes:6', wr_dis : 22, rd_dis: null, alt: MAC_CUSTOM USER_DATA_MAC_CUSTOM, dict : '', desc: Custom MAC, rloc: 'EFUSE_RD_USR_DATA6_REG[31:8]', bloc: 'B25,B26,B27,B28,B29,B30'} diff -Nru esptool-4.6.2+dfsg/espefuse/efuse_defs/esp32p4.yaml esptool-4.7.0+dfsg/espefuse/efuse_defs/esp32p4.yaml --- esptool-4.6.2+dfsg/espefuse/efuse_defs/esp32p4.yaml 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse_defs/esp32p4.yaml 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,91 @@ +VER_NO: 95ae7b662df04208c40c69564ea06a28 +EFUSES: + WR_DIS : {show: y, blk : 0, word: 0, pos : 0, len : 32, start : 0, type : 'uint:32', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Disable programming of individual eFuses, rloc: EFUSE_RD_WR_DIS_REG, bloc: 'B0,B1,B2,B3'} + RD_DIS : {show: y, blk : 0, word: 1, pos : 0, len : 7, start : 32, type : 'uint:7', wr_dis : 0, rd_dis: null, alt : '', dict : '', desc: Disable reading from BlOCK4-10, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[6:0]', bloc: 'B4[6:0]'} + USB_DEVICE_EXCHG_PINS : {show: y, blk : 0, word: 1, pos : 7, len : 1, start : 39, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Enable usb device exchange pins of D+ and D-, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[7]', bloc: 'B4[7]'} + USB_OTG11_EXCHG_PINS : {show: y, blk : 0, word: 1, pos : 8, len : 1, start : 40, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Enable usb otg11 exchange pins of D+ and D-, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[8]', bloc: 'B5[0]'} + DIS_USB_JTAG : {show: y, blk : 0, word: 1, pos : 9, len : 1, start : 41, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether the function of usb switch to jtag is disabled or enabled. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[9]', bloc: 'B5[1]'} + POWERGLITCH_EN : {show: y, blk : 0, word: 1, pos: 10, len : 1, start : 42, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether power glitch function is enabled. 1: enabled. 0: disabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[10]', bloc: 'B5[2]'} + DIS_USB_SERIAL_JTAG : {show: n, blk : 0, word: 1, pos: 11, len : 1, start : 43, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether USB-Serial-JTAG is disabled or enabled. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[11]', bloc: 'B5[3]'} + DIS_FORCE_DOWNLOAD : {show: y, blk : 0, word: 1, pos: 12, len : 1, start : 44, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether the function that forces chip into download mode is disabled or enabled. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[12]', bloc: 'B5[4]'} + SPI_DOWNLOAD_MSPI_DIS : {show: y, blk : 0, word: 1, pos: 13, len : 1, start : 45, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable accessing MSPI flash/MSPI ram by SYS AXI matrix during boot_mode_download, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[13]', bloc: 'B5[5]'} + DIS_TWAI : {show: y, blk : 0, word: 1, pos: 14, len : 1, start : 46, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether TWAI function is disabled or enabled. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[14]', bloc: 'B5[6]'} + JTAG_SEL_ENABLE : {show: y, blk : 0, word: 1, pos: 15, len : 1, start : 47, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether the selection between usb_to_jtag and pad_to_jtag through strapping gpio15 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 is enabled or disabled. 1: enabled. 0: disabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[15]', bloc: 'B5[7]'} + SOFT_DIS_JTAG : {show: y, blk : 0, word: 1, pos: 16, len : 3, start : 48, type : 'uint:3', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether JTAG is disabled in soft way. Odd number: disabled. Even number: enabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[18:16]', bloc: 'B6[2:0]'} + DIS_PAD_JTAG : {show: y, blk : 0, word: 1, pos: 19, len : 1, start : 51, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether JTAG is disabled in the hard way(permanently). 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[19]', bloc: 'B6[3]'} + DIS_DOWNLOAD_MANUAL_ENCRYPT : {show: y, blk : 0, word: 1, pos: 20, len : 1, start : 52, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether flash encrypt function is disabled or enabled(except in SPI boot mode). 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[20]', bloc: 'B6[4]'} + USB_DEVICE_DREFH : {show: n, blk : 0, word: 1, pos: 21, len : 2, start : 53, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: USB intphy of usb device signle-end input high threshold; 1.76V to 2V. Step by 80mV, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[22:21]', bloc: 'B6[6:5]'} + USB_OTG11_DREFH : {show: n, blk : 0, word: 1, pos: 23, len : 2, start : 55, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: USB intphy of usb otg11 signle-end input high threshold; 1.76V to 2V. Step by 80mV, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[24:23]', bloc: 'B6[7],B7[0]'} + USB_PHY_SEL : {show: y, blk : 0, word: 1, pos: 25, len : 1, start : 57, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: TBD, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[25]', bloc: 'B7[1]'} + KM_HUK_GEN_STATE_LOW : {show: y, blk : 0, word: 1, pos: 26, len : 6, start : 58, type : 'uint:6', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set this bit to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is valid, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[31:26]', bloc: 'B7[7:2]'} + KM_HUK_GEN_STATE_HIGH : {show: y, blk : 0, word: 2, pos : 0, len : 3, start : 64, type : 'uint:3', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set this bit to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is valid, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[2:0]', bloc: 'B8[2:0]'} + KM_RND_SWITCH_CYCLE : {show: y, blk : 0, word: 2, pos : 3, len : 2, start : 67, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Set bits to control key manager random number switch cycle. 0: control by register. 1: 8 km clk cycles. 2: 16 km cycles. 3: 32 km cycles', rloc: 'EFUSE_RD_REPEAT_DATA1_REG[4:3]', bloc: 'B8[4:3]'} + KM_DEPLOY_ONLY_ONCE : {show: y, blk : 0, word: 2, pos : 5, len : 4, start : 69, type : 'uint:4', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Set each bit to control whether corresponding key can only be deployed once. 1 is true; 0 is false. Bit0: ecdsa. Bit1: xts. Bit2: hmac. Bit3: ds', rloc: 'EFUSE_RD_REPEAT_DATA1_REG[8:5]', bloc: 'B8[7:5],B9[0]'} + FORCE_USE_KEY_MANAGER_KEY : {show: y, blk : 0, word: 2, pos : 9, len : 4, start : 73, type : 'uint:4', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Set each bit to control whether corresponding key must come from key manager.. 1 is true; 0 is false. Bit0: ecdsa. Bit1: xts. Bit2: hmac. Bit3: ds', rloc: 'EFUSE_RD_REPEAT_DATA1_REG[12:9]', bloc: 'B9[4:1]'} + FORCE_DISABLE_SW_INIT_KEY : {show: y, blk : 0, word: 2, pos: 13, len : 1, start : 77, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable software written init key; and force use efuse_init_key, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[13]', bloc: 'B9[5]'} + XTS_KEY_LENGTH_256 : {show: y, blk : 0, word: 2, pos: 14, len : 1, start : 78, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set this bit to configure flash encryption use xts-128 key; else use xts-256 key, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[14]', bloc: 'B9[6]'} + RESERVE_0_79 : {show: n, blk : 0, word: 2, pos: 15, len : 1, start : 79, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[15]', bloc: 'B9[7]'} + WDT_DELAY_SEL : {show: y, blk : 0, word: 2, pos: 16, len : 2, start : 80, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether RTC watchdog timeout threshold is selected at startup. 1: selected. 0: not selected', rloc: 'EFUSE_RD_REPEAT_DATA1_REG[17:16]', bloc: 'B10[1:0]'} + SPI_BOOT_CRYPT_CNT : {show: y, blk : 0, word: 2, pos: 18, len : 3, start : 82, type : 'uint:3', wr_dis : 4, rd_dis: null, alt : '', dict: '{0: "Disable", 1: "Enable", 3: "Disable", 7: "Enable"}', desc: Enables flash encryption when 1 or 3 bits are set and disables otherwise, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[20:18]', bloc: 'B10[4:2]'} + SECURE_BOOT_KEY_REVOKE0 : {show: y, blk : 0, word: 2, pos: 21, len : 1, start : 85, type : bool, wr_dis : 5, rd_dis: null, alt : '', dict : '', desc: Revoke 1st secure boot key, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[21]', bloc: 'B10[5]'} + SECURE_BOOT_KEY_REVOKE1 : {show: y, blk : 0, word: 2, pos: 22, len : 1, start : 86, type : bool, wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: Revoke 2nd secure boot key, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[22]', bloc: 'B10[6]'} + SECURE_BOOT_KEY_REVOKE2 : {show: y, blk : 0, word: 2, pos: 23, len : 1, start : 87, type : bool, wr_dis : 7, rd_dis: null, alt : '', dict : '', desc: Revoke 3rd secure boot key, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[23]', bloc: 'B10[7]'} + KEY_PURPOSE_0 : {show: y, blk : 0, word: 2, pos: 24, len : 4, start : 88, type : 'uint:4', wr_dis : 8, rd_dis: null, alt : KEY0_PURPOSE, dict : '', desc: Represents the purpose of Key0, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[27:24]', bloc: 'B11[3:0]'} + KEY_PURPOSE_1 : {show: y, blk : 0, word: 2, pos: 28, len : 4, start : 92, type : 'uint:4', wr_dis : 9, rd_dis: null, alt : KEY1_PURPOSE, dict : '', desc: Represents the purpose of Key1, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[31:28]', bloc: 'B11[7:4]'} + KEY_PURPOSE_2 : {show: y, blk : 0, word: 3, pos : 0, len : 4, start : 96, type : 'uint:4', wr_dis : 10, rd_dis: null, alt : KEY2_PURPOSE, dict : '', desc: Represents the purpose of Key2, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[3:0]', bloc: 'B12[3:0]'} + KEY_PURPOSE_3 : {show: y, blk : 0, word: 3, pos : 4, len : 4, start: 100, type : 'uint:4', wr_dis : 11, rd_dis: null, alt : KEY3_PURPOSE, dict : '', desc: Represents the purpose of Key3, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[7:4]', bloc: 'B12[7:4]'} + KEY_PURPOSE_4 : {show: y, blk : 0, word: 3, pos : 8, len : 4, start: 104, type : 'uint:4', wr_dis : 12, rd_dis: null, alt : KEY4_PURPOSE, dict : '', desc: Represents the purpose of Key4, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[11:8]', bloc: 'B13[3:0]'} + KEY_PURPOSE_5 : {show: y, blk : 0, word: 3, pos: 12, len : 4, start: 108, type : 'uint:4', wr_dis : 13, rd_dis: null, alt : KEY5_PURPOSE, dict : '', desc: Represents the purpose of Key5, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[15:12]', bloc: 'B13[7:4]'} + SEC_DPA_LEVEL : {show: y, blk : 0, word: 3, pos: 16, len : 2, start: 112, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Represents the spa secure level by configuring the clock random divide mode, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[17:16]', bloc: 'B14[1:0]'} + ECDSA_ENABLE_SOFT_K : {show: y, blk : 0, word: 3, pos: 18, len : 1, start: 114, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether hardware random number k is forced used in ESDCA. 1: force used. 0: not force used', rloc: 'EFUSE_RD_REPEAT_DATA2_REG[18]', bloc: 'B14[2]'} + CRYPT_DPA_ENABLE : {show: y, blk : 0, word: 3, pos: 19, len : 1, start: 115, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether anti-dpa attack is enabled. 1:enabled. 0: disabled', rloc: 'EFUSE_RD_REPEAT_DATA2_REG[19]', bloc: 'B14[3]'} + SECURE_BOOT_EN : {show: y, blk : 0, word: 3, pos: 20, len : 1, start: 116, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether secure boot is enabled or disabled. 1: enabled. 0: disabled', rloc: 'EFUSE_RD_REPEAT_DATA2_REG[20]', bloc: 'B14[4]'} + SECURE_BOOT_AGGRESSIVE_REVOKE : {show: y, blk : 0, word: 3, pos: 21, len : 1, start: 117, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether revoking aggressive secure boot is enabled or disabled. 1: enabled. 0: disabled', rloc: 'EFUSE_RD_REPEAT_DATA2_REG[21]', bloc: 'B14[5]'} + RESERVE_0_118 : {show: n, blk : 0, word: 3, pos: 22, len : 1, start: 118, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[22]', bloc: 'B14[6]'} + FLASH_TYPE : {show: y, blk : 0, word: 3, pos: 23, len : 1, start: 119, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'The type of interfaced flash. 0: four data lines; 1: eight data lines', rloc: 'EFUSE_RD_REPEAT_DATA2_REG[23]', bloc: 'B14[7]'} + FLASH_PAGE_SIZE : {show: y, blk : 0, word: 3, pos: 24, len : 2, start: 120, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set flash page size, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[25:24]', bloc: 'B15[1:0]'} + FLASH_ECC_EN : {show: y, blk : 0, word: 3, pos: 26, len : 1, start: 122, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable ecc for flash boot, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[26]', bloc: 'B15[2]'} + DIS_USB_OTG_DOWNLOAD_MODE : {show: y, blk : 0, word: 3, pos: 27, len : 1, start: 123, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable download via USB-OTG, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[27]', bloc: 'B15[3]'} + FLASH_TPUW : {show: y, blk : 0, word: 3, pos: 28, len : 4, start: 124, type : 'uint:4', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Represents the flash waiting time after power-up; in unit of ms. When the value less than 15; the waiting time is the programmed value. Otherwise; the waiting time is 2 times the programmed value, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[31:28]', bloc: 'B15[7:4]'} + DIS_DOWNLOAD_MODE : {show: y, blk : 0, word: 4, pos : 0, len : 1, start: 128, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether Download mode is disabled or enabled. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA3_REG[0]', bloc: 'B16[0]'} + DIS_DIRECT_BOOT : {show: y, blk : 0, word: 4, pos : 1, len : 1, start: 129, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether direct boot mode is disabled or enabled. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA3_REG[1]', bloc: 'B16[1]'} + DIS_USB_SERIAL_JTAG_ROM_PRINT : {show: y, blk : 0, word: 4, pos : 2, len : 1, start: 130, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether print from USB-Serial-JTAG is disabled or enabled. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA3_REG[2]', bloc: 'B16[2]'} + LOCK_KM_KEY : {show: y, blk : 0, word: 4, pos : 3, len : 1, start: 131, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: TBD, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[3]', bloc: 'B16[3]'} + DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE: {show: y, blk : 0, word: 4, pos : 4, len : 1, start: 132, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether the USB-Serial-JTAG download function is disabled or enabled. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA3_REG[4]', bloc: 'B16[4]'} + ENABLE_SECURITY_DOWNLOAD : {show: y, blk : 0, word: 4, pos : 5, len : 1, start: 133, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether security download is enabled or disabled. 1: enabled. 0: disabled', rloc: 'EFUSE_RD_REPEAT_DATA3_REG[5]', bloc: 'B16[5]'} + UART_PRINT_CONTROL : {show: y, blk : 0, word: 4, pos : 6, len : 2, start: 134, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents the type of UART printing. 00: force enable printing. 01: enable printing when GPIO8 is reset at low level. 10: enable printing when GPIO8 is reset at high level. 11: force disable printing', rloc: 'EFUSE_RD_REPEAT_DATA3_REG[7:6]', bloc: 'B16[7:6]'} + FORCE_SEND_RESUME : {show: y, blk : 0, word: 4, pos : 8, len : 1, start: 136, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether ROM code is forced to send a resume command during SPI boot. 1: forced. 0:not forced', rloc: 'EFUSE_RD_REPEAT_DATA3_REG[8]', bloc: 'B17[0]'} + SECURE_VERSION : {show: y, blk : 0, word: 4, pos : 9, len : 16, start: 137, type : 'uint:16', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Represents the version used by ESP-IDF anti-rollback feature, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[24:9]', bloc: 'B17[7:1],B18,B19[0]'} + SECURE_BOOT_DISABLE_FAST_WAKE : {show: y, blk : 0, word: 4, pos: 25, len : 1, start: 153, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether FAST VERIFY ON WAKE is disabled or enabled when Secure Boot is enabled. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA3_REG[25]', bloc: 'B19[1]'} + HYS_EN_PAD : {show: y, blk : 0, word: 4, pos: 26, len : 1, start: 154, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'Represents whether the hysteresis function of corresponding PAD is enabled. 1: enabled. 0:disabled', rloc: 'EFUSE_RD_REPEAT_DATA3_REG[26]', bloc: 'B19[2]'} + DCDC_VSET : {show: y, blk : 0, word: 4, pos: 27, len : 5, start: 155, type : 'uint:5', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set the dcdc voltage default, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[31:27]', bloc: 'B19[7:3]'} + PXA0_TIEH_SEL_0 : {show: y, blk : 0, word: 5, pos : 0, len : 2, start: 160, type : 'uint:2', wr_dis: null, rd_dis: null, alt : 0PXA_TIEH_SEL_0, dict : '', desc: TBD, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[1:0]', bloc: 'B20[1:0]'} + PXA0_TIEH_SEL_1 : {show: y, blk : 0, word: 5, pos : 2, len : 2, start: 162, type : 'uint:2', wr_dis: null, rd_dis: null, alt : 0PXA_TIEH_SEL_1, dict : '', desc: TBD, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[3:2]', bloc: 'B20[3:2]'} + PXA0_TIEH_SEL_2 : {show: y, blk : 0, word: 5, pos : 4, len : 2, start: 164, type : 'uint:2', wr_dis: null, rd_dis: null, alt : 0PXA_TIEH_SEL_2, dict : '', desc: TBD, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[5:4]', bloc: 'B20[5:4]'} + PXA0_TIEH_SEL_3 : {show: y, blk : 0, word: 5, pos : 6, len : 2, start: 166, type : 'uint:2', wr_dis: null, rd_dis: null, alt : 0PXA_TIEH_SEL_3, dict : '', desc: TBD, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[7:6]', bloc: 'B20[7:6]'} + KM_DISABLE_DEPLOY_MODE : {show: y, blk : 0, word: 5, pos : 8, len : 4, start: 168, type : 'uint:4', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: TBD, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[11:8]', bloc: 'B21[3:0]'} + USB_DEVICE_DREFL : {show: n, blk : 0, word: 5, pos: 12, len : 2, start: 172, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Represents the usb device single-end input low threhold; 0.8 V to 1.04 V with step of 80 mV, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[13:12]', bloc: 'B21[5:4]'} + USB_OTG11_DREFL : {show: n, blk : 0, word: 5, pos: 14, len : 2, start: 174, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Represents the usb otg11 single-end input low threhold; 0.8 V to 1.04 V with step of 80 mV, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[15:14]', bloc: 'B21[7:6]'} + RESERVE_0_176 : {show: n, blk : 0, word: 5, pos: 16, len : 2, start: 176, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[17:16]', bloc: 'B22[1:0]'} + HP_PWR_SRC_SEL : {show: y, blk : 0, word: 5, pos: 18, len : 1, start: 178, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: 'HP system power source select. 0:LDO. 1: DCDC', rloc: 'EFUSE_RD_REPEAT_DATA4_REG[18]', bloc: 'B22[2]'} + DCDC_VSET_EN : {show: y, blk : 0, word: 5, pos: 19, len : 1, start: 179, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Select dcdc vset use efuse_dcdc_vset, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[19]', bloc: 'B22[3]'} + DIS_WDT : {show: y, blk : 0, word: 5, pos: 20, len : 1, start: 180, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable watch dog, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[20]', bloc: 'B22[4]'} + DIS_SWD : {show: y, blk : 0, word: 5, pos: 21, len : 1, start: 181, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable super-watchdog, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[21]', bloc: 'B22[5]'} + RESERVE_0_182 : {show: n, blk : 0, word: 5, pos: 22, len : 10, start: 182, type : 'uint:10', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[31:22]', bloc: 'B22[7:6],B23'} + MAC : {show: y, blk : 1, word: 0, pos : 0, len : 48, start : 0, type : 'bytes:6', wr_dis : 20, rd_dis: null, alt : MAC_FACTORY, dict : '', desc: MAC address, rloc: EFUSE_RD_MAC_SYS_0_REG, bloc: 'B0,B1,B2,B3,B4,B5'} + MAC_EXT : {show: y, blk : 1, word: 1, pos: 16, len : 16, start : 48, type : 'bytes:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Stores the extended bits of MAC address, rloc: 'EFUSE_RD_MAC_SYS_1_REG[31:16]', bloc: 'B6,B7'} + MAC_RESERVED_1 : {show: n, blk : 1, word: 2, pos : 0, len : 14, start : 64, type : 'uint:14', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_MAC_SYS_2_REG[13:0]', bloc: 'B8,B9[5:0]'} + MAC_RESERVED_0 : {show: n, blk : 1, word: 2, pos: 14, len : 18, start : 78, type : 'uint:18', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_MAC_SYS_2_REG[31:14]', bloc: 'B9[7:6],B10,B11'} + MAC_RESERVED_2 : {show: n, blk : 1, word: 3, pos : 0, len : 18, start : 96, type : 'uint:18', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_MAC_SYS_3_REG[17:0]', bloc: 'B12,B13,B14[1:0]'} + SYS_DATA_PART0_0 : {show: n, blk : 1, word: 3, pos: 18, len : 14, start: 114, type : 'uint:14', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Stores the first 14 bits of the zeroth part of system data, rloc: 'EFUSE_RD_MAC_SYS_3_REG[31:18]', bloc: 'B14[7:2],B15'} + SYS_DATA_PART0_1 : {show: n, blk : 1, word: 4, pos : 0, len : 32, start: 128, type : 'uint:32', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Stores the first 32 bits of the zeroth part of system data, rloc: EFUSE_RD_MAC_SYS_4_REG, bloc: 'B16,B17,B18,B19'} + SYS_DATA_PART0_2 : {show: n, blk : 1, word: 5, pos : 0, len : 32, start: 160, type : 'uint:32', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Stores the second 32 bits of the zeroth part of system data, rloc: EFUSE_RD_MAC_SYS_5_REG, bloc: 'B20,B21,B22,B23'} + BLOCK_SYS_DATA1 : {show: y, blk : 2, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 21, rd_dis: null, alt : SYS_DATA_PART1, dict : '', desc: System data part 1, rloc: EFUSE_RD_SYS_PART1_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26,B27,B28,B29,B30,B31'} + BLOCK_USR_DATA : {show: y, blk : 3, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 22, rd_dis: null, alt : USER_DATA, dict : '', desc: User data, rloc: EFUSE_RD_USR_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26,B27,B28,B29,B30,B31'} + BLOCK_KEY0 : {show: y, blk : 4, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 23, rd_dis : 0, alt : KEY0, dict : '', desc: Key0 or user data, rloc: EFUSE_RD_KEY0_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26,B27,B28,B29,B30,B31'} + BLOCK_KEY1 : {show: y, blk : 5, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 24, rd_dis : 1, alt : KEY1, dict : '', desc: Key1 or user data, rloc: EFUSE_RD_KEY1_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26,B27,B28,B29,B30,B31'} + BLOCK_KEY2 : {show: y, blk : 6, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 25, rd_dis : 2, alt : KEY2, dict : '', desc: Key2 or user data, rloc: EFUSE_RD_KEY2_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26,B27,B28,B29,B30,B31'} + BLOCK_KEY3 : {show: y, blk : 7, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 26, rd_dis : 3, alt : KEY3, dict : '', desc: Key3 or user data, rloc: EFUSE_RD_KEY3_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26,B27,B28,B29,B30,B31'} + BLOCK_KEY4 : {show: y, blk : 8, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 27, rd_dis : 4, alt : KEY4, dict : '', desc: Key4 or user data, rloc: EFUSE_RD_KEY4_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26,B27,B28,B29,B30,B31'} + BLOCK_KEY5 : {show: y, blk : 9, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 28, rd_dis : 5, alt : KEY5, dict : '', desc: Key5 or user data, rloc: EFUSE_RD_KEY5_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26,B27,B28,B29,B30,B31'} + BLOCK_SYS_DATA2 : {show: y, blk: 10, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 29, rd_dis : 6, alt : SYS_DATA_PART2, dict : '', desc: System data part 2 (reserved), rloc: EFUSE_RD_SYS_PART2_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26,B27,B28,B29,B30,B31'} diff -Nru esptool-4.6.2+dfsg/espefuse/efuse_defs/esp32s3.yaml esptool-4.7.0+dfsg/espefuse/efuse_defs/esp32s3.yaml --- esptool-4.6.2+dfsg/espefuse/efuse_defs/esp32s3.yaml 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espefuse/efuse_defs/esp32s3.yaml 2023-12-13 11:05:18.000000000 +0000 @@ -1,4 +1,4 @@ -VER_NO: 6925129eca795b8b087d31be539740ec +VER_NO: f75f74727101326a187188a23f4a6c70 EFUSES: WR_DIS : {show: y, blk : 0, word: 0, pos : 0, len : 32, start : 0, type : 'uint:32', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Disable programming of individual eFuses, rloc: EFUSE_RD_WR_DIS_REG, bloc: 'B0,B1,B2,B3'} RD_DIS : {show: y, blk : 0, word: 1, pos : 0, len : 7, start : 32, type : 'uint:7', wr_dis : 0, rd_dis: null, alt : '', dict : '', desc: Disable reading from BlOCK4-10, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[6:0]', bloc: 'B4[6:0]'} @@ -84,8 +84,13 @@ WAFER_VERSION_MINOR_LO : {show: y, blk : 1, word: 3, pos: 18, len : 3, start: 114, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MINOR least significant bits, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[20:18]', bloc: 'B14[4:2]'} PKG_VERSION : {show: y, blk : 1, word: 3, pos: 21, len : 3, start: 117, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Package version, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[23:21]', bloc: 'B14[7:5]'} BLK_VERSION_MINOR : {show: y, blk : 1, word: 3, pos: 24, len : 3, start: 120, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLK_VERSION_MINOR, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[26:24]', bloc: 'B15[2:0]'} - RESERVED_1_123 : {show: n, blk : 1, word: 3, pos: 27, len : 5, start: 123, type : 'uint:5', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[31:27]', bloc: 'B15[7:3]'} - RESERVED_1_128 : {show: n, blk : 1, word: 4, pos : 0, len : 13, start: 128, type : 'uint:13', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[12:0]', bloc: 'B16,B17[4:0]'} + FLASH_CAP : {show: y, blk : 1, word: 3, pos: 27, len : 3, start: 123, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict: '{0: "None", 1: "8M", 2: "4M"}', desc: Flash capacity, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[29:27]', bloc: 'B15[5:3]'} + FLASH_TEMP : {show: y, blk : 1, word: 3, pos: 30, len : 2, start: 126, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict: '{0: "None", 1: "105C", 2: "85C"}', desc: Flash temperature, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[31:30]', bloc: 'B15[7:6]'} + FLASH_VENDOR : {show: y, blk : 1, word: 4, pos : 0, len : 3, start: 128, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict: '{0: "None", 1: "XMC", 2: "GD", 3: "FM", 4: "TT", 5: "BY"}', desc: Flash vendor, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[2:0]', bloc: 'B16[2:0]'} + PSRAM_CAP : {show: y, blk : 1, word: 4, pos : 3, len : 2, start: 131, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict: '{0: "None", 1: "8M", 2: "2M"}', desc: PSRAM capacity, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[4:3]', bloc: 'B16[4:3]'} + PSRAM_TEMP : {show: y, blk : 1, word: 4, pos : 5, len : 2, start: 133, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict: '{0: "None", 1: "105C", 2: "85C"}', desc: PSRAM temperature, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[6:5]', bloc: 'B16[6:5]'} + PSRAM_VENDOR : {show: y, blk : 1, word: 4, pos : 7, len : 2, start: 135, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict: '{0: "None", 1: "AP_3v3", 2: "AP_1v8"}', desc: PSRAM vendor, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[8:7]', bloc: 'B16[7],B17[0]'} + RESERVED_1_137 : {show: n, blk : 1, word: 4, pos : 9, len : 4, start: 137, type : 'uint:4', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[12:9]', bloc: 'B17[4:1]'} K_RTC_LDO : {show: y, blk : 1, word: 4, pos: 13, len : 7, start: 141, type : 'uint:7', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 K_RTC_LDO, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[19:13]', bloc: 'B17[7:5],B18[3:0]'} K_DIG_LDO : {show: y, blk : 1, word: 4, pos: 20, len : 7, start: 148, type : 'uint:7', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 K_DIG_LDO, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[26:20]', bloc: 'B18[7:4],B19[2:0]'} V_RTC_DBIAS20 : {show: y, blk : 1, word: 4, pos: 27, len : 8, start: 155, type : 'uint:8', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 voltage of rtc dbias20, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[31:27]', bloc: 'B19[7:3],B20[2:0]'} diff -Nru esptool-4.6.2+dfsg/espsecure/__init__.py esptool-4.7.0+dfsg/espsecure/__init__.py --- esptool-4.6.2+dfsg/espsecure/__init__.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espsecure/__init__.py 2023-12-13 11:05:18.000000000 +0000 @@ -1712,7 +1712,7 @@ "--aes_xts", "-x", help="Decrypt data using AES-XTS as used on " - "ESP32-S2, ESP32-C2, ESP32-C3 and ESP32-C6", + "ESP32-S2, ESP32-C2, ESP32-C3, ESP32-C6 and ESP32-P4", action="store_true", ) p.add_argument( @@ -1752,7 +1752,7 @@ "--aes_xts", "-x", help="Encrypt data using AES-XTS as used on " - "ESP32-S2, ESP32-C2, ESP32-C3 and ESP32-C6", + "ESP32-S2, ESP32-C2, ESP32-C3, ESP32-C6 and ESP32-P4", action="store_true", ) p.add_argument( diff -Nru esptool-4.6.2+dfsg/espsecure/esp_hsm_sign/__init__.py esptool-4.7.0+dfsg/espsecure/esp_hsm_sign/__init__.py --- esptool-4.6.2+dfsg/espsecure/esp_hsm_sign/__init__.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/espsecure/esp_hsm_sign/__init__.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ import configparser import os import sys +from getpass import getpass try: import pkcs11 @@ -31,11 +32,17 @@ if not config.has_section(section): raise configparser.NoSectionError(section) - section_options = ["pkcs11_lib", "credentials", "slot", "label"] + section_options = ["pkcs11_lib", "slot", "label"] for option in section_options: if not config.has_option(section, option): raise configparser.NoOptionError(option, section) + # If the config file does not contain the "credentials" option, + # prompt the user for the HSM PIN + if not config.has_option(section, "credentials"): + hsm_pin = getpass("Please enter the PIN of your HSM:\n") + config.set(section, "credentials", hsm_pin) + return config[section] diff -Nru esptool-4.6.2+dfsg/esptool/__init__.py esptool-4.7.0+dfsg/esptool/__init__.py --- esptool-4.6.2+dfsg/esptool/__init__.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/__init__.py 2023-12-13 11:05:18.000000000 +0000 @@ -28,7 +28,7 @@ "write_mem", ] -__version__ = "4.6.2" +__version__ = "4.7.0" import argparse import inspect @@ -38,6 +38,7 @@ import time import traceback +from esptool.bin_image import intel_hex_to_bin from esptool.cmds import ( DETECTED_FLASH_SIZES, chip_id, @@ -176,16 +177,18 @@ parent.add_argument( "--spi-connection", "-sc", - help="ESP32-only argument. Override default SPI Flash connection. " + help="Override default SPI Flash connection. " "Value can be SPI, HSPI or a comma-separated list of 5 I/O numbers " - "to use for SPI flash (CLK,Q,D,HD,CS).", + "to use for SPI flash (CLK,Q,D,HD,CS). Not supported with ESP8266.", action=SpiConnectionAction, ) parser_load_ram = subparsers.add_parser( "load_ram", help="Download an image to RAM and execute" ) - parser_load_ram.add_argument("filename", help="Firmware image") + parser_load_ram.add_argument( + "filename", help="Firmware image", action=AutoHex2BinAction + ) parser_dump_mem = subparsers.add_parser( "dump_mem", help="Dump arbitrary memory to disk" @@ -357,7 +360,9 @@ parser_image_info = subparsers.add_parser( "image_info", help="Dump headers from a binary file (bootloader or application)" ) - parser_image_info.add_argument("filename", help="Image file to parse") + parser_image_info.add_argument( + "filename", help="Image file to parse", action=AutoHex2BinAction + ) parser_image_info.add_argument( "--version", "-v", @@ -477,6 +482,17 @@ "must be aligned to. Value 0xFF is used for padding, similar to erase_flash", default=None, ) + parser_elf2image.add_argument( + "--ram-only-header", + help="Order segments of the output so IRAM and DRAM are placed at the " + "beginning and force the main header segment number to RAM segments " + "quantity. This will make the other segments invisible to the ROM " + "loader. Use this argument with care because the ROM loader will load " + "only the RAM segments although the other segments being present in " + "the output.", + action="store_true", + default=None, + ) add_spi_flash_subparsers(parser_elf2image, allow_keep=False, auto_detect=False) @@ -587,18 +603,36 @@ "--output", "-o", help="Output filename", type=str, required=True ) parser_merge_bin.add_argument( - "--format", "-f", help="Format of the output file", choices="raw", default="raw" - ) # for future expansion + "--format", + "-f", + help="Format of the output file", + choices=["raw", "uf2", "hex"], + default="raw", + ) + uf2_group = parser_merge_bin.add_argument_group("UF2 format") + uf2_group.add_argument( + "--chunk-size", + help="Specify the used data part of the 512 byte UF2 block. " + "A common value is 256. By default the largest possible value will be used.", + default=None, + type=arg_auto_chunk_size, + ) + uf2_group.add_argument( + "--md5-disable", + help="Disable MD5 checksum in UF2 output", + action="store_true", + ) add_spi_flash_subparsers(parser_merge_bin, allow_keep=True, auto_detect=False) - parser_merge_bin.add_argument( + raw_group = parser_merge_bin.add_argument_group("RAW format") + raw_group.add_argument( "--target-offset", "-t", help="Target offset where the output file will be flashed", type=arg_auto_int, default=0, ) - parser_merge_bin.add_argument( + raw_group.add_argument( "--fill-flash-size", help="If set, the final binary file will be padded with FF " "bytes up to this flash size.", @@ -736,14 +770,22 @@ "Keeping initial baud rate %d" % initial_baud ) - # override common SPI flash parameter stuff if configured to do so + # Override the common SPI flash parameter stuff if configured to do so if hasattr(args, "spi_connection") and args.spi_connection is not None: - if esp.CHIP_NAME != "ESP32": - raise FatalError( - "Chip %s does not support --spi-connection option." % esp.CHIP_NAME - ) - print("Configuring SPI flash mode...") - esp.flash_spi_attach(args.spi_connection) + spi_config = args.spi_connection + if args.spi_connection == "SPI": + value = 0 + elif args.spi_connection == "HSPI": + value = 1 + else: + esp.check_spi_connection(args.spi_connection) + # Encode the pin numbers as a 32-bit integer with packed 6-bit values, + # the same way the ESP ROM takes them + clk, q, d, hd, cs = args.spi_connection + spi_config = f"CLK:{clk}, Q:{q}, D:{d}, HD:{hd}, CS:{cs}" + value = (hd << 24) | (cs << 18) | (d << 12) | (q << 6) | clk + print(f"Configuring SPI flash mode ({spi_config})...") + esp.flash_spi_attach(value) elif args.no_stub: print("Enabling default SPI flash mode...") # ROM loader doesn't enable flash unless we explicitly do it @@ -812,6 +854,15 @@ "Try checking the chip connections or removing " "any other hardware connected to IOs." ) + if ( + hasattr(args, "spi_connection") + and args.spi_connection is not None + ): + print( + "Some GPIO pins might be used by other peripherals, " + "try using another --spi-connection combination." + ) + except FatalError as e: raise FatalError(f"Unable to verify flash chip connection ({e}).") @@ -834,7 +885,11 @@ if flash_size is not None: # Secure download mode esp.flash_set_parameters(flash_size_bytes(flash_size)) # Check if stub supports chosen flash size - if esp.IS_STUB and flash_size in ("32MB", "64MB", "128MB"): + if ( + esp.IS_STUB + and esp.CHIP_NAME != "ESP32-S3" + and flash_size_bytes(flash_size) > 16 * 1024 * 1024 + ): print( "WARNING: Flasher stub doesn't fully support flash size larger " "than 16MB, in case of failure use --no-stub." @@ -858,7 +913,7 @@ args.size = flash_size_bytes(size_str) if esp.IS_STUB and hasattr(args, "address") and hasattr(args, "size"): - if args.address + args.size > 0x1000000: + if esp.CHIP_NAME != "ESP32-S3" and args.address + args.size > 0x1000000: print( "WARNING: Flasher stub doesn't fully support flash size larger " "than 16MB, in case of failure use --no-stub." @@ -906,6 +961,13 @@ return x if x == "all" else arg_auto_int(x) +def arg_auto_chunk_size(string: str) -> int: + num = int(string, 0) + if num & 3 != 0: + raise argparse.ArgumentTypeError("Chunk size should be a 4-byte aligned number") + return num + + def get_port_list(): if list_ports is None: raise FatalError( @@ -934,7 +996,7 @@ else: new_args.append(arg) if expanded: - print("esptool %s" % (" ".join(new_args[1:]))) + print(f"esptool.py {' '.join(new_args)}") return new_args return argv @@ -978,42 +1040,44 @@ """ def __call__(self, parser, namespace, value, option_string=None): - if value.upper() == "SPI": - value = 0 - elif value.upper() == "HSPI": - value = 1 + if value.upper() in ["SPI", "HSPI"]: + values = value.upper() elif "," in value: values = value.split(",") if len(values) != 5: raise argparse.ArgumentError( self, - "%s is not a valid list of comma-separate pin numbers. " - "Must be 5 numbers - CLK,Q,D,HD,CS." % value, + f"{value} is not a valid list of comma-separate pin numbers. " + "Must be 5 numbers - CLK,Q,D,HD,CS.", ) try: values = tuple(int(v, 0) for v in values) except ValueError: raise argparse.ArgumentError( self, - "%s is not a valid argument. All pins must be numeric values" - % values, + f"{values} is not a valid argument. " + "All pins must be numeric values", ) - if any([v for v in values if v > 33 or v < 0]): - raise argparse.ArgumentError( - self, "Pin numbers must be in the range 0-33." - ) - # encode the pin numbers as a 32-bit integer with packed 6-bit values, - # the same way ESP32 ROM takes them - # TODO: make this less ESP32 ROM specific somehow... - clk, q, d, hd, cs = values - value = (hd << 24) | (cs << 18) | (d << 12) | (q << 6) | clk else: raise argparse.ArgumentError( self, - "%s is not a valid spi-connection value. " - "Values are SPI, HSPI, or a sequence of 5 pin numbers CLK,Q,D,HD,CS)." - % value, + f"{value} is not a valid spi-connection value. " + "Values are SPI, HSPI, or a sequence of 5 pin numbers - CLK,Q,D,HD,CS.", ) + setattr(namespace, self.dest, values) + + +class AutoHex2BinAction(argparse.Action): + """Custom parser class for auto conversion of input files from hex to bin""" + + def __call__(self, parser, namespace, value, option_string=None): + try: + with open(value, "rb") as f: + # if hex file was detected replace hex file with converted temp bin + # otherwise keep the original file + value = intel_hex_to_bin(f).name + except IOError as e: + raise argparse.ArgumentError(self, e) setattr(namespace, self.dest, value) @@ -1045,6 +1109,8 @@ "Must be pairs of an address " "and the binary filename to write there", ) + # check for intel hex files and convert them to bin + argfile = intel_hex_to_bin(argfile, address) pairs.append((address, argfile)) # Sort the addresses and check for overlapping diff -Nru esptool-4.6.2+dfsg/esptool/bin_image.py esptool-4.7.0+dfsg/esptool/bin_image.py --- esptool-4.6.2+dfsg/esptool/bin_image.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/bin_image.py 2023-12-13 11:05:18.000000000 +0000 @@ -10,6 +10,10 @@ import os import re import struct +import tempfile +from typing import BinaryIO, Optional + +from intelhex import IntelHex from .loader import ESPLoader from .targets import ( @@ -20,6 +24,7 @@ ESP32H2BETA1ROM, ESP32H2BETA2ROM, ESP32H2ROM, + ESP32P4ROM, ESP32ROM, ESP32S2ROM, ESP32S3BETA2ROM, @@ -35,6 +40,23 @@ f.seek(align, 1) +def intel_hex_to_bin(file: BinaryIO, start_addr: Optional[int] = None) -> BinaryIO: + """Convert IntelHex file to temp binary file with padding from start_addr + If hex file was detected return temp bin file object; input file otherwise""" + INTEL_HEX_MAGIC = b":" + magic = file.read(1) + file.seek(0) + if magic == INTEL_HEX_MAGIC: + ih = IntelHex() + ih.loadhex(file.name) + file.close() + bin = tempfile.NamedTemporaryFile(suffix=".bin", delete=False) + ih.tobinfile(bin, start=start_addr) + return bin + else: + return file + + def LoadFirmwareImage(chip, image_file): """ Load a firmware image. Can be for any supported SoC. @@ -61,6 +83,7 @@ "esp32c2": ESP32C2FirmwareImage, "esp32c6": ESP32C6FirmwareImage, "esp32h2": ESP32H2FirmwareImage, + "esp32p4": ESP32P4FirmwareImage, }[chip](f) else: # Otherwise, ESP8266 so look at magic to determine the image type magic = ord(f.read(1)) @@ -248,6 +271,20 @@ if checksum is not None: return ESPLoader.checksum(segment_data, checksum) + def save_flash_segment(self, f, segment, checksum=None): + """ + Save the next segment to the image file, return next checksum value if provided + """ + if self.ROM_LOADER.CHIP_NAME == "ESP32": + # Work around a bug in ESP-IDF 2nd stage bootloader, that it didn't map the + # last MMU page, if an IROM/DROM segment was < 0x24 bytes + # over the page boundary. + segment_end_pos = f.tell() + len(segment.data) + self.SEG_HEADER_LEN + segment_len_remainder = segment_end_pos % self.IROM_ALIGN + if segment_len_remainder < 0x24: + segment.data += b"\x00" * (0x24 - segment_len_remainder) + return self.save_segment(f, segment, checksum) + def read_checksum(self, f): """Return ESPLoader checksum from end of just-read image""" # Skip the padding. The checksum is stored in the last byte so that the @@ -555,7 +592,7 @@ IROM_ALIGN = 65536 - def __init__(self, load_file=None, append_digest=True): + def __init__(self, load_file=None, append_digest=True, ram_only_header=False): super(ESP32FirmwareImage, self).__init__() self.secure_pad = None self.flash_mode = 0 @@ -573,6 +610,7 @@ self.min_rev = 0 self.min_rev_full = 0 self.max_rev_full = 0 + self.ram_only_header = ram_only_header self.append_digest = append_digest @@ -632,10 +670,10 @@ if not self.is_flash_addr(s.addr) ] - # Patch to support 761 union bus memmap // TODO: ESPTOOL-512 + # Patch to support ESP32-C6 union bus memmap # move ".flash.appdesc" segment to the top of the flash segment for segment in flash_segments: - if segment.name == ".flash.appdesc": + if isinstance(segment, ELFSection) and segment.name == ".flash.appdesc": flash_segments.remove(segment) flash_segments.insert(0, segment) break @@ -685,33 +723,61 @@ pad_len += self.IROM_ALIGN return pad_len - # try to fit each flash segment on a 64kB aligned boundary - # by padding with parts of the non-flash segments... - while len(flash_segments) > 0: - segment = flash_segments[0] - pad_len = get_alignment_data_needed(segment) - if pad_len > 0: # need to pad - if len(ram_segments) > 0 and pad_len > self.SEG_HEADER_LEN: - pad_segment = ram_segments[0].split_image(pad_len) - if len(ram_segments[0].data) == 0: - ram_segments.pop(0) - else: - pad_segment = ImageSegment(0, b"\x00" * pad_len, f.tell()) - checksum = self.save_segment(f, pad_segment, checksum) + if self.ram_only_header: + # write RAM segments first in order to get only RAM segments quantity + # and checksum (ROM bootloader will only care for RAM segments and its + # correct checksums) + for segment in ram_segments: + checksum = self.save_segment(f, segment, checksum) total_segments += 1 - else: + self.append_checksum(f, checksum) + + # reversing to match the same section order from linker script + flash_segments.reverse() + for segment in flash_segments: + pad_len = get_alignment_data_needed(segment) + while pad_len > 0: + pad_segment = ImageSegment(0, b"\x00" * pad_len, f.tell()) + self.save_segment(f, pad_segment) + total_segments += 1 + pad_len = get_alignment_data_needed(segment) # write the flash segment assert ( f.tell() + 8 ) % self.IROM_ALIGN == segment.addr % self.IROM_ALIGN - checksum = self.save_flash_segment(f, segment, checksum) - flash_segments.pop(0) + # save the flash segment but not saving its checksum neither + # saving the number of flash segments, since ROM bootloader + # should "not see" them + self.save_flash_segment(f, segment) + total_segments += 1 + else: # not self.ram_only_header + # try to fit each flash segment on a 64kB aligned boundary + # by padding with parts of the non-flash segments... + while len(flash_segments) > 0: + segment = flash_segments[0] + pad_len = get_alignment_data_needed(segment) + if pad_len > 0: # need to pad + if len(ram_segments) > 0 and pad_len > self.SEG_HEADER_LEN: + pad_segment = ram_segments[0].split_image(pad_len) + if len(ram_segments[0].data) == 0: + ram_segments.pop(0) + else: + pad_segment = ImageSegment(0, b"\x00" * pad_len, f.tell()) + checksum = self.save_segment(f, pad_segment, checksum) + total_segments += 1 + else: + # write the flash segment + assert ( + f.tell() + 8 + ) % self.IROM_ALIGN == segment.addr % self.IROM_ALIGN + checksum = self.save_flash_segment(f, segment, checksum) + flash_segments.pop(0) + total_segments += 1 + + # flash segments all written, so write any remaining RAM segments + for segment in ram_segments: + checksum = self.save_segment(f, segment, checksum) total_segments += 1 - - # flash segments all written, so write any remaining RAM segments - for segment in ram_segments: - checksum = self.save_segment(f, segment, checksum) - total_segments += 1 if self.secure_pad: # pad the image so that after signing it will end on a a 64KB boundary. @@ -743,8 +809,9 @@ checksum = self.save_segment(f, pad_segment, checksum) total_segments += 1 - # done writing segments - self.append_checksum(f, checksum) + if not self.ram_only_header: + # done writing segments + self.append_checksum(f, checksum) image_length = f.tell() if self.secure_pad: @@ -753,7 +820,12 @@ # kinda hacky: go back to the initial header and write the new segment count # that includes padding segments. This header is not checksummed f.seek(1) - f.write(bytes([total_segments])) + if self.ram_only_header: + # Update the header with the RAM segments quantity as it should be + # visible by the ROM bootloader + f.write(bytes([len(ram_segments)])) + else: + f.write(bytes([total_segments])) if self.append_digest: # calculate the SHA256 of the whole file and append it @@ -771,19 +843,6 @@ with open(filename, "wb") as real_file: real_file.write(f.getvalue()) - def save_flash_segment(self, f, segment, checksum=None): - """ - Save the next segment to the image file, return next checksum value if provided - """ - segment_end_pos = f.tell() + len(segment.data) + self.SEG_HEADER_LEN - segment_len_remainder = segment_end_pos % self.IROM_ALIGN - if segment_len_remainder < 0x24: - # Work around a bug in ESP-IDF 2nd stage bootloader, that it didn't map the - # last MMU page, if an IROM/DROM segment was < 0x24 bytes - # over the page boundary. - segment.data += b"\x00" * (0x24 - segment_len_remainder) - return self.save_segment(f, segment, checksum) - def load_extended_header(self, load_file): def split_byte(n): return (n & 0x0F, (n >> 4) & 0x0F) @@ -1055,6 +1114,15 @@ ESP32C6ROM.BOOTLOADER_IMAGE = ESP32C6FirmwareImage +class ESP32P4FirmwareImage(ESP32FirmwareImage): + """ESP32P4 Firmware Image almost exactly the same as ESP32FirmwareImage""" + + ROM_LOADER = ESP32P4ROM + + +ESP32P4ROM.BOOTLOADER_IMAGE = ESP32P4FirmwareImage + + class ESP32H2FirmwareImage(ESP32C6FirmwareImage): """ESP32H2 Firmware Image almost exactly the same as ESP32FirmwareImage""" @@ -1067,6 +1135,7 @@ class ELFFile(object): SEC_TYPE_PROGBITS = 0x01 SEC_TYPE_STRTAB = 0x03 + SEC_TYPE_NOBITS = 0x08 # e.g. .bss section SEC_TYPE_INITARRAY = 0x0E SEC_TYPE_FINIARRAY = 0x0F @@ -1157,6 +1226,7 @@ all_sections = [read_section_header(offs) for offs in section_header_offsets] prog_sections = [s for s in all_sections if s[1] in ELFFile.PROG_SEC_TYPES] + nobits_secitons = [s for s in all_sections if s[1] == ELFFile.SEC_TYPE_NOBITS] # search for the string table section if not (shstrndx * self.LEN_SEC_HEADER) in section_header_offsets: @@ -1188,6 +1258,11 @@ if lma != 0 and size > 0 ] self.sections = prog_sections + self.nobits_sections = [ + ELFSection(lookup_string(n_offs), lma, b"") + for (n_offs, _type, lma, size, offs) in nobits_secitons + if lma != 0 and size > 0 + ] def _read_segments(self, f, segment_header_offs, segment_header_count, shstrndx): f.seek(segment_header_offs) diff -Nru esptool-4.6.2+dfsg/esptool/cmds.py esptool-4.7.0+dfsg/esptool/cmds.py --- esptool-4.6.2+dfsg/esptool/cmds.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/cmds.py 2023-12-13 11:05:18.000000000 +0000 @@ -11,6 +11,8 @@ import time import zlib +from intelhex import IntelHex + from .bin_image import ELFFile, ImageSegment, LoadFirmwareImage from .bin_image import ( ESP8266ROMFirmwareImage, @@ -25,6 +27,7 @@ timeout_per_mb, ) from .targets import CHIP_DEFS, CHIP_LIST, ROM_LIST +from .uf2_writer import UF2Writer from .util import ( FatalError, NotImplementedInROMError, @@ -96,7 +99,7 @@ print("Detecting chip type...", end="") chip_id = detect_port.get_chip_id() for cls in [ - n for n in ROM_LIST if n.CHIP_NAME not in ("ESP8266", "ESP32", "ESP32S2") + n for n in ROM_LIST if n.CHIP_NAME not in ("ESP8266", "ESP32", "ESP32-S2") ]: # cmd not supported on ESP8266 and ESP32 + ESP32-S2 doesn't return chip_id if chip_id == cls.IMAGE_CHIP_ID: @@ -466,7 +469,7 @@ flash_end = flash_size_bytes( detect_flash_size(esp) if args.flash_size == "keep" else args.flash_size ) - if flash_end is not None: # Secure download mode + if flash_end is not None: # Not in secure download mode for address, argfile in args.addr_filename: argfile.seek(0, os.SEEK_END) if address + argfile.tell() > flash_end: @@ -979,6 +982,8 @@ args.chip = "esp8266" print("Creating {} image...".format(args.chip)) + if args.ram_only_header: + print("ROM segments hidden - only RAM segments are visible to the ROM loader!") if args.chip != "esp8266": image = CHIP_DEFS[args.chip].BOOTLOADER_IMAGE() @@ -989,6 +994,7 @@ image.min_rev = args.min_rev image.min_rev_full = args.min_rev_full image.max_rev_full = args.max_rev_full + image.ram_only_header = args.ram_only_header image.append_digest = args.append_digest elif args.version == "1": # ESP8266 image = ESP8266ROMFirmwareImage() @@ -1180,15 +1186,95 @@ print(("After flash status: " + fmt) % esp.read_status(args.bytes)) +# The following mapping was taken from the ROM code +# This mapping is same across all targets in the ROM +SECURITY_INFO_FLAG_MAP = { + "SECURE_BOOT_EN": (1 << 0), + "SECURE_BOOT_AGGRESSIVE_REVOKE": (1 << 1), + "SECURE_DOWNLOAD_ENABLE": (1 << 2), + "SECURE_BOOT_KEY_REVOKE0": (1 << 3), + "SECURE_BOOT_KEY_REVOKE1": (1 << 4), + "SECURE_BOOT_KEY_REVOKE2": (1 << 5), + "SOFT_DIS_JTAG": (1 << 6), + "HARD_DIS_JTAG": (1 << 7), + "DIS_USB": (1 << 8), + "DIS_DOWNLOAD_DCACHE": (1 << 9), + "DIS_DOWNLOAD_ICACHE": (1 << 10), +} + + +# Get the status of respective security flag +def get_security_flag_status(flag_name, flags_value): + try: + return (flags_value & SECURITY_INFO_FLAG_MAP[flag_name]) != 0 + except KeyError: + raise ValueError(f"Invalid flag name: {flag_name}") + + def get_security_info(esp, args): si = esp.get_security_info() - # TODO: better display + print() + title = "Security Information:" + print(title) + print("=" * len(title)) print("Flags: {:#010x} ({})".format(si["flags"], bin(si["flags"]))) - print("Flash_Crypt_Cnt: {:#x}".format(si["flash_crypt_cnt"])) - print("Key_Purposes: {}".format(si["key_purposes"])) + print("Key Purposes: {}".format(si["key_purposes"])) if si["chip_id"] is not None and si["api_version"] is not None: - print("Chip_ID: {}".format(si["chip_id"])) - print("Api_Version: {}".format(si["api_version"])) + print("Chip ID: {}".format(si["chip_id"])) + print("API Version: {}".format(si["api_version"])) + + flags = si["flags"] + + if get_security_flag_status("SECURE_BOOT_EN", flags): + print("Secure Boot: Enabled") + if get_security_flag_status("SECURE_BOOT_AGGRESSIVE_REVOKE", flags): + print("Secure Boot Aggressive key revocation: Enabled") + + revoked_keys = [] + for i, key in enumerate( + [ + "SECURE_BOOT_KEY_REVOKE0", + "SECURE_BOOT_KEY_REVOKE1", + "SECURE_BOOT_KEY_REVOKE2", + ] + ): + if get_security_flag_status(key, flags): + revoked_keys.append(i) + + if len(revoked_keys) > 0: + print("Secure Boot Key Revocation Status:\n") + for i in revoked_keys: + print(f"\tSecure Boot Key{i} is Revoked\n") + + else: + print("Secure Boot: Disabled") + + flash_crypt_cnt = bin(si["flash_crypt_cnt"]) + if (flash_crypt_cnt.count("1") % 2) != 0: + print("Flash Encryption: Enabled") + else: + print("Flash Encryption: Disabled") + + CRYPT_CNT_STRING = "SPI Boot Crypt Count (SPI_BOOT_CRYPT_CNT)" + if esp.CHIP_NAME == "esp32": + CRYPT_CNT_STRING = "Flash Crypt Count (FLASH_CRYPT_CNT)" + + print(f"{CRYPT_CNT_STRING}: {si['flash_crypt_cnt']:#x}") + + if get_security_flag_status("DIS_DOWNLOAD_DCACHE", flags): + print("Dcache in UART download mode: Disabled") + + if get_security_flag_status("DIS_DOWNLOAD_ICACHE", flags): + print("Icache in UART download mode: Disabled") + + hard_dis_jtag = get_security_flag_status("HARD_DIS_JTAG", flags) + soft_dis_jtag = get_security_flag_status("SOFT_DIS_JTAG", flags) + if hard_dis_jtag: + print("JTAG: Permenantly Disabled") + elif soft_dis_jtag: + print("JTAG: Software Access Disabled") + if get_security_flag_status("DIS_USB", flags): + print("USB Access: Disabled") def merge_bin(args): @@ -1198,9 +1284,9 @@ msg = ( "Please specify the chip argument" if args.chip == "auto" - else "Invalid chip choice: '{}'".format(args.chip) + else f"Invalid chip choice: '{args.chip}'" ) - msg = msg + " (choose from {})".format(", ".join(CHIP_LIST)) + msg = f"{msg} (choose from {', '.join(CHIP_LIST)})" raise FatalError(msg) # sort the files by offset. @@ -1211,31 +1297,57 @@ first_addr = input_files[0][0] if first_addr < args.target_offset: raise FatalError( - "Output file target offset is 0x%x. Input file offset 0x%x is before this." - % (args.target_offset, first_addr) + f"Output file target offset is {args.target_offset:#x}. " + f"Input file offset {first_addr:#x} is before this." ) - if args.format != "raw": - raise FatalError( - "This version of esptool only supports the 'raw' output format" + if args.format == "uf2": + with UF2Writer( + chip_class.UF2_FAMILY_ID, + args.output, + args.chunk_size, + md5_enabled=not args.md5_disable, + ) as writer: + for addr, argfile in input_files: + print(f"Adding {argfile.name} at {addr:#x}") + image = argfile.read() + image = _update_image_flash_params(chip_class, addr, args, image) + writer.add_file(addr, image) + print( + f"Wrote {os.path.getsize(args.output):#x} bytes to file {args.output}, " + f"ready to be flashed with any ESP USB Bridge" ) - with open(args.output, "wb") as of: - - def pad_to(flash_offs): - # account for output file offset if there is any - of.write(b"\xFF" * (flash_offs - args.target_offset - of.tell())) + elif args.format == "raw": + with open(args.output, "wb") as of: + def pad_to(flash_offs): + # account for output file offset if there is any + of.write(b"\xFF" * (flash_offs - args.target_offset - of.tell())) + + for addr, argfile in input_files: + pad_to(addr) + image = argfile.read() + image = _update_image_flash_params(chip_class, addr, args, image) + of.write(image) + if args.fill_flash_size: + pad_to(flash_size_bytes(args.fill_flash_size)) + print( + f"Wrote {of.tell():#x} bytes to file {args.output}, " + f"ready to flash to offset {args.target_offset:#x}" + ) + elif args.format == "hex": + out = IntelHex() for addr, argfile in input_files: - pad_to(addr) + ihex = IntelHex() image = argfile.read() image = _update_image_flash_params(chip_class, addr, args, image) - of.write(image) - if args.fill_flash_size: - pad_to(flash_size_bytes(args.fill_flash_size)) + ihex.frombytes(image, addr) + out.merge(ihex) + out.write_hex_file(args.output) print( - "Wrote 0x%x bytes to file %s, ready to flash to offset 0x%x" - % (of.tell(), args.output, args.target_offset) + f"Wrote {os.path.getsize(args.output):#x} bytes to file {args.output}, " + f"ready to flash to offset {args.target_offset:#x}" ) diff -Nru esptool-4.6.2+dfsg/esptool/loader.py esptool-4.7.0+dfsg/esptool/loader.py --- esptool-4.6.2+dfsg/esptool/loader.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/loader.py 2023-12-13 11:05:18.000000000 +0000 @@ -170,6 +170,8 @@ self.data = None self.data_start = None + self.bss_start = stub.get("bss_start") + class ESPLoader(object): """Base class providing access to ESP ROM & software stub bootloaders. @@ -184,8 +186,6 @@ CHIP_NAME = "Espressif device" IS_STUB = False - FPGA_SLOW_BOOT = False - DEFAULT_PORT = "/dev/ttyUSB0" USES_RFC2217 = False @@ -301,8 +301,39 @@ if isinstance(port, str): try: self._port = serial.serial_for_url(port) - except serial.serialutil.SerialException: - raise FatalError(f"Could not open {port}, the port doesn't exist") + except serial.serialutil.SerialException as e: + port_issues = [ + [ # does not exist error + re.compile(r"Errno 2|FileNotFoundError", re.IGNORECASE), + "Check if the port is correct and ESP connected", + ], + [ # busy port error + re.compile(r"Access is denied", re.IGNORECASE), + "Check if the port is not used by another task", + ], + ] + if sys.platform.startswith("linux"): + port_issues.append( + [ # permission denied error + re.compile(r"Permission denied", re.IGNORECASE), + ( + "Try to add user into dialout group: " + "sudo usermod -a -G dialout $USER" + ), + ], + ) + + hint_msg = "" + for port_issue in port_issues: + if port_issue[0].search(str(e)): + hint_msg = f"\nHint: {port_issue[1]}\n" + break + + raise FatalError( + f"Could not open {port}, the port is busy or doesn't exist." + f"\n({e})\n" + f"{hint_msg}" + ) else: self._port = port self._slip_reader = slip_reader(self._port, self.trace) @@ -597,7 +628,7 @@ # This FPGA delay is for Espressif internal use if ( - self.FPGA_SLOW_BOOT + self.CHIP_NAME == "ESP32" and os.environ.get("ESPTOOL_ENV_FPGA", "").strip() == "1" ): delay = extra_delay = 7 @@ -651,8 +682,17 @@ print("") # end 'Connecting...' line if last_error is not None: + additional_msg = "" + if self.CHIP_NAME == "ESP32-C2" and self._port.baudrate < 115200: + additional_msg = ( + "\nNote: Please set a higher baud rate (--baud)" + " if ESP32-C2 doesn't connect" + " (at least 115200 Bd is recommended)." + ) + raise FatalError( "Failed to connect to {}: {}" + f"{additional_msg}" "\nFor troubleshooting steps visit: " "https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html".format( # noqa E501 self.CHIP_NAME, last_error @@ -751,17 +791,17 @@ stub = StubFlasher(get_stub_json_path(self.CHIP_NAME)) load_start = offset load_end = offset + size - for start, end in [ - (stub.data_start, stub.data_start + len(stub.data)), - (stub.text_start, stub.text_start + len(stub.text)), + for stub_start, stub_end in [ + (stub.bss_start, stub.data_start + len(stub.data)), # DRAM = bss+data + (stub.text_start, stub.text_start + len(stub.text)), # IRAM ]: - if load_start < end and load_end > start: + if load_start < stub_end and load_end > stub_start: raise FatalError( "Software loader is resident at 0x%08x-0x%08x. " "Can't load binary at overlapping address range 0x%08x-0x%08x. " "Either change binary loading address, or use the --no-stub " "option to disable the software loader." - % (start, end, load_start, load_end) + % (stub_start, stub_end, load_start, load_end) ) return self.check_command( diff -Nru esptool-4.6.2+dfsg/esptool/targets/__init__.py esptool-4.7.0+dfsg/esptool/targets/__init__.py --- esptool-4.6.2+dfsg/esptool/targets/__init__.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/__init__.py 2023-12-13 11:05:18.000000000 +0000 @@ -6,6 +6,7 @@ from .esp32h2 import ESP32H2ROM from .esp32h2beta1 import ESP32H2BETA1ROM from .esp32h2beta2 import ESP32H2BETA2ROM +from .esp32p4 import ESP32P4ROM from .esp32s2 import ESP32S2ROM from .esp32s3 import ESP32S3ROM from .esp32s3beta2 import ESP32S3BETA2ROM @@ -25,6 +26,7 @@ "esp32c2": ESP32C2ROM, "esp32c6": ESP32C6ROM, "esp32h2": ESP32H2ROM, + "esp32p4": ESP32P4ROM, } CHIP_LIST = list(CHIP_DEFS.keys()) diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp32.py esptool-4.7.0+dfsg/esptool/targets/esp32.py --- esptool-4.6.2+dfsg/esptool/targets/esp32.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp32.py 2023-12-13 11:05:18.000000000 +0000 @@ -17,8 +17,6 @@ IMAGE_CHIP_ID = 0 IS_STUB = False - FPGA_SLOW_BOOT = True - CHIP_DETECT_MAGIC_VALUE = [0x00F01D83] IROM_MAP_START = 0x400D0000 @@ -105,6 +103,8 @@ FLASH_ENCRYPTED_WRITE_ALIGN = 32 + UF2_FAMILY_ID = 0x1C5F21B0 + """ Try to read the BLOCK1 (encryption key) and check if it is valid """ def is_flash_encryption_key_valid(self): @@ -281,7 +281,7 @@ return self.read_reg(self.EFUSE_RD_REG_BASE + (4 * n)) def chip_id(self): - raise NotSupportedError(self, "chip_id") + raise NotSupportedError(self, "Function chip_id") def read_mac(self, mac_type="BASE_MAC"): """Read MAC from EFUSE region""" @@ -361,6 +361,7 @@ return rom_calculated_freq def change_baud(self, baud): + assert self.CHIP_NAME == "ESP32", "This workaround should only apply to ESP32" # It's a workaround to avoid esp32 CK_8M frequency drift. rom_calculated_freq = self.get_rom_cal_crystal_freq() valid_freq = 40000000 if rom_calculated_freq > 33000000 else 26000000 @@ -373,6 +374,11 @@ time.sleep(0.05) # get rid of garbage sent during baud rate change self.flush_input() + def check_spi_connection(self, spi_connection): + # Pins 30, 31 do not exist + if not set(spi_connection).issubset(set(range(0, 30)) | set((32, 33))): + raise FatalError("SPI Pin numbers must be in the range 0-29, 32, or 33.") + class ESP32StubLoader(ESP32ROM): """Access class for ESP32 stub loader, runs on top of ROM.""" diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp32c2.py esptool-4.7.0+dfsg/esptool/targets/esp32c2.py --- esptool-4.6.2+dfsg/esptool/targets/esp32c2.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp32c2.py 2023-12-13 11:05:18.000000000 +0000 @@ -8,6 +8,7 @@ from .esp32c3 import ESP32C3ROM from ..loader import ESPLoader +from ..util import FatalError class ESP32C2ROM(ESP32C3ROM): @@ -61,6 +62,8 @@ [0x4037C000, 0x403C0000, "IRAM"], ] + UF2_FAMILY_ID = 0x2B88D29C + def get_pkg_version(self): num_word = 1 return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 22) & 0x07 @@ -82,6 +85,16 @@ num_word = 1 return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 20) & 0x3 + def get_flash_cap(self): + # ESP32-C2 doesn't have eFuse field FLASH_CAP. + # Can't get info about the flash chip. + return 0 + + def get_flash_vendor(self): + # ESP32-C2 doesn't have eFuse field FLASH_VENDOR. + # Can't get info about the flash chip. + return "" + def get_crystal_freq(self): # The crystal detection algorithm of ESP32/ESP8266 works for ESP32-C2 as well. return ESPLoader.get_crystal_freq(self) @@ -110,7 +123,7 @@ def _post_connect(self): # ESP32C2 ECO0 is no longer supported by the flasher stub - if self.get_chip_revision() == 0: + if not self.secure_download_mode and self.get_chip_revision() == 0: self.stub_is_disabled = True self.IS_STUB = False @@ -142,6 +155,10 @@ return True return False + def check_spi_connection(self, spi_connection): + if not set(spi_connection).issubset(set(range(0, 21))): + raise FatalError("SPI Pin numbers must be in the range 0-20.") + class ESP32C2StubLoader(ESP32C2ROM): """Access class for ESP32C2 stub loader, runs on top of ROM. diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp32c3.py esptool-4.7.0+dfsg/esptool/targets/esp32c3.py --- esptool-4.6.2+dfsg/esptool/targets/esp32c3.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp32c3.py 2023-12-13 11:05:18.000000000 +0000 @@ -14,8 +14,6 @@ CHIP_NAME = "ESP32-C3" IMAGE_CHIP_ID = 5 - FPGA_SLOW_BOOT = False - IROM_MAP_START = 0x42000000 IROM_MAP_END = 0x42800000 DROM_MAP_START = 0x3C000000 @@ -31,8 +29,8 @@ BOOTLOADER_FLASH_OFFSET = 0x0 - # Magic value for ESP32C3 eco 1+2 and ESP32C3 eco3 respectivly - CHIP_DETECT_MAGIC_VALUE = [0x6921506F, 0x1B31506F] + # Magic values for ESP32-C3 eco 1+2, eco 3, eco 6, and eco 7 respectively + CHIP_DETECT_MAGIC_VALUE = [0x6921506F, 0x1B31506F, 0x4881606F, 0x4361606F] UART_DATE_REG_ADDR = 0x60000000 + 0x7C @@ -99,6 +97,8 @@ [0x600FE000, 0x60100000, "MEM_INTERNAL2"], ] + UF2_FAMILY_ID = 0xD42BA06C + def get_pkg_version(self): num_word = 3 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x07 @@ -114,16 +114,39 @@ num_word = 5 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x03 + def get_flash_cap(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 27) & 0x07 + + def get_flash_vendor(self): + num_word = 4 + vendor_id = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x07 + return {1: "XMC", 2: "GD", 3: "FM", 4: "TT", 5: "ZBIT"}.get(vendor_id, "") + def get_chip_description(self): chip_name = { - 0: "ESP32-C3", + 0: "ESP32-C3 (QFN32)", + 1: "ESP8685 (QFN28)", + 2: "ESP32-C3 AZ (QFN32)", + 3: "ESP8686 (QFN24)", }.get(self.get_pkg_version(), "unknown ESP32-C3") major_rev = self.get_major_chip_version() minor_rev = self.get_minor_chip_version() return f"{chip_name} (revision v{major_rev}.{minor_rev})" def get_chip_features(self): - return ["WiFi", "BLE"] + features = ["WiFi", "BLE"] + + flash = { + 0: None, + 1: "Embedded Flash 4MB", + 2: "Embedded Flash 2MB", + 3: "Embedded Flash 1MB", + 4: "Embedded Flash 8MB", + }.get(self.get_flash_cap(), "Unknown Embedded Flash") + if flash is not None: + features += [flash + f" ({self.get_flash_vendor()})"] + return features def get_crystal_freq(self): # ESP32C3 XTAL is fixed to 40MHz @@ -205,6 +228,15 @@ if not self.sync_stub_detected: # Don't run if stub is reused self.disable_watchdogs() + def check_spi_connection(self, spi_connection): + if not set(spi_connection).issubset(set(range(0, 22))): + raise FatalError("SPI Pin numbers must be in the range 0-21.") + if any([v for v in spi_connection if v in [18, 19]]): + print( + "WARNING: GPIO pins 18 and 19 are used by USB-Serial/JTAG, " + "consider using other pins for SPI flash connection." + ) + class ESP32C3StubLoader(ESP32C3ROM): """Access class for ESP32C3 stub loader, runs on top of ROM. diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp32c6.py esptool-4.7.0+dfsg/esptool/targets/esp32c6.py --- esptool-4.6.2+dfsg/esptool/targets/esp32c6.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp32c6.py 2023-12-13 11:05:18.000000000 +0000 @@ -13,8 +13,6 @@ CHIP_NAME = "ESP32-C6" IMAGE_CHIP_ID = 13 - FPGA_SLOW_BOOT = False - IROM_MAP_START = 0x42000000 IROM_MAP_END = 0x42800000 DROM_MAP_START = 0x42800000 @@ -101,6 +99,8 @@ [0x600FE000, 0x60100000, "MEM_INTERNAL2"], ] + UF2_FAMILY_ID = 0x540DDF62 + def get_pkg_version(self): num_word = 3 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x07 @@ -180,6 +180,15 @@ return any(p == self.PURPOSE_VAL_XTS_AES128_KEY for p in purposes) + def check_spi_connection(self, spi_connection): + if not set(spi_connection).issubset(set(range(0, 31))): + raise FatalError("SPI Pin numbers must be in the range 0-30.") + if any([v for v in spi_connection if v in [12, 13]]): + print( + "WARNING: GPIO pins 12 and 13 are used by USB-Serial/JTAG, " + "consider using other pins for SPI flash connection." + ) + class ESP32C6StubLoader(ESP32C6ROM): """Access class for ESP32C6 stub loader, runs on top of ROM. diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp32h2.py esptool-4.7.0+dfsg/esptool/targets/esp32h2.py --- esptool-4.6.2+dfsg/esptool/targets/esp32h2.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp32h2.py 2023-12-13 11:05:18.000000000 +0000 @@ -4,6 +4,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later from .esp32c6 import ESP32C6ROM +from ..util import FatalError class ESP32H2ROM(ESP32C6ROM): @@ -29,6 +30,8 @@ "12m": 0x2, } + UF2_FAMILY_ID = 0x332726F6 + def get_pkg_version(self): num_word = 4 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x07 @@ -56,6 +59,15 @@ # ESP32H2 XTAL is fixed to 32MHz return 32 + def check_spi_connection(self, spi_connection): + if not set(spi_connection).issubset(set(range(0, 28))): + raise FatalError("SPI Pin numbers must be in the range 0-27.") + if any([v for v in spi_connection if v in [26, 27]]): + print( + "WARNING: GPIO pins 26 and 27 are used by USB-Serial/JTAG, " + "consider using other pins for SPI flash connection." + ) + class ESP32H2StubLoader(ESP32H2ROM): """Access class for ESP32H2 stub loader, runs on top of ROM. diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp32p4.py esptool-4.7.0+dfsg/esptool/targets/esp32p4.py --- esptool-4.6.2+dfsg/esptool/targets/esp32p4.py 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp32p4.py 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,195 @@ +# SPDX-FileCopyrightText: 2023 Fredrik Ahlberg, Angus Gratton, +# Espressif Systems (Shanghai) CO LTD, other contributors as noted. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import struct + +from .esp32 import ESP32ROM +from ..loader import ESPLoader +from ..util import FatalError, NotImplementedInROMError + + +class ESP32P4ROM(ESP32ROM): + CHIP_NAME = "ESP32-P4" + IMAGE_CHIP_ID = 18 + + IROM_MAP_START = 0x40000000 + IROM_MAP_END = 0x4C000000 + DROM_MAP_START = 0x40000000 + DROM_MAP_END = 0x4C000000 + + BOOTLOADER_FLASH_OFFSET = 0x2000 # First 2 sectors are reserved for FE purposes + + CHIP_DETECT_MAGIC_VALUE = [0x0] + + UART_DATE_REG_ADDR = 0x500CA000 + 0x8C + + EFUSE_BASE = 0x5012D000 + EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x044 + MAC_EFUSE_REG = EFUSE_BASE + 0x044 + + SPI_REG_BASE = 0x5008D000 # SPIMEM1 + SPI_USR_OFFS = 0x18 + SPI_USR1_OFFS = 0x1C + SPI_USR2_OFFS = 0x20 + SPI_MOSI_DLEN_OFFS = 0x24 + SPI_MISO_DLEN_OFFS = 0x28 + SPI_W0_OFFS = 0x58 + + EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address + + EFUSE_PURPOSE_KEY0_REG = EFUSE_BASE + 0x34 + EFUSE_PURPOSE_KEY0_SHIFT = 24 + EFUSE_PURPOSE_KEY1_REG = EFUSE_BASE + 0x34 + EFUSE_PURPOSE_KEY1_SHIFT = 28 + EFUSE_PURPOSE_KEY2_REG = EFUSE_BASE + 0x38 + EFUSE_PURPOSE_KEY2_SHIFT = 0 + EFUSE_PURPOSE_KEY3_REG = EFUSE_BASE + 0x38 + EFUSE_PURPOSE_KEY3_SHIFT = 4 + EFUSE_PURPOSE_KEY4_REG = EFUSE_BASE + 0x38 + EFUSE_PURPOSE_KEY4_SHIFT = 8 + EFUSE_PURPOSE_KEY5_REG = EFUSE_BASE + 0x38 + EFUSE_PURPOSE_KEY5_SHIFT = 12 + + EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG = EFUSE_RD_REG_BASE + EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT = 1 << 20 + + EFUSE_SPI_BOOT_CRYPT_CNT_REG = EFUSE_BASE + 0x034 + EFUSE_SPI_BOOT_CRYPT_CNT_MASK = 0x7 << 18 + + EFUSE_SECURE_BOOT_EN_REG = EFUSE_BASE + 0x038 + EFUSE_SECURE_BOOT_EN_MASK = 1 << 20 + + PURPOSE_VAL_XTS_AES256_KEY_1 = 2 + PURPOSE_VAL_XTS_AES256_KEY_2 = 3 + PURPOSE_VAL_XTS_AES128_KEY = 4 + + SUPPORTS_ENCRYPTED_FLASH = True + + FLASH_ENCRYPTED_WRITE_ALIGN = 16 + + MEMORY_MAP = [ + [0x00000000, 0x00010000, "PADDING"], + [0x40000000, 0x4C000000, "DROM"], + [0x4FF00000, 0x4FFA0000, "DRAM"], + [0x4FF00000, 0x4FFA0000, "BYTE_ACCESSIBLE"], + [0x4FC00000, 0x4FC20000, "DROM_MASK"], + [0x4FC00000, 0x4FC20000, "IROM_MASK"], + [0x40000000, 0x4C000000, "IROM"], + [0x4FF00000, 0x4FFA0000, "IRAM"], + [0x50108000, 0x50110000, "RTC_IRAM"], + [0x50108000, 0x50110000, "RTC_DRAM"], + [0x600FE000, 0x60100000, "MEM_INTERNAL2"], + ] + + UF2_FAMILY_ID = 0x3D308E94 + + def get_pkg_version(self): + # ESP32P4 TODO + return 0 + + def get_minor_chip_version(self): + # ESP32P4 TODO + return 0 + + def get_major_chip_version(self): + # ESP32P4 TODO + return 0 + + def get_chip_description(self): + chip_name = { + 0: "ESP32-P4", + }.get(self.get_pkg_version(), "unknown ESP32-P4") + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return f"{chip_name} (revision v{major_rev}.{minor_rev})" + + def get_chip_features(self): + return ["High-Performance MCU"] + + def get_crystal_freq(self): + # ESP32P4 XTAL is fixed to 40MHz + return 40 + + def override_vddsdio(self, new_voltage): + raise NotImplementedInROMError( + "VDD_SDIO overrides are not supported for ESP32-P4" + ) + + def read_mac(self, mac_type="BASE_MAC"): + """Read MAC from EFUSE region""" + if mac_type != "BASE_MAC": + return None + mac0 = self.read_reg(self.MAC_EFUSE_REG) + mac1 = self.read_reg(self.MAC_EFUSE_REG + 4) # only bottom 16 bits are MAC + bitstring = struct.pack(">II", mac1, mac0)[2:] + return tuple(bitstring) + + def get_flash_crypt_config(self): + return None # doesn't exist on ESP32-P4 + + def get_secure_boot_enabled(self): + return ( + self.read_reg(self.EFUSE_SECURE_BOOT_EN_REG) + & self.EFUSE_SECURE_BOOT_EN_MASK + ) + + def get_key_block_purpose(self, key_block): + if key_block < 0 or key_block > 5: + raise FatalError("Valid key block numbers must be in range 0-5") + + reg, shift = [ + (self.EFUSE_PURPOSE_KEY0_REG, self.EFUSE_PURPOSE_KEY0_SHIFT), + (self.EFUSE_PURPOSE_KEY1_REG, self.EFUSE_PURPOSE_KEY1_SHIFT), + (self.EFUSE_PURPOSE_KEY2_REG, self.EFUSE_PURPOSE_KEY2_SHIFT), + (self.EFUSE_PURPOSE_KEY3_REG, self.EFUSE_PURPOSE_KEY3_SHIFT), + (self.EFUSE_PURPOSE_KEY4_REG, self.EFUSE_PURPOSE_KEY4_SHIFT), + (self.EFUSE_PURPOSE_KEY5_REG, self.EFUSE_PURPOSE_KEY5_SHIFT), + ][key_block] + return (self.read_reg(reg) >> shift) & 0xF + + def is_flash_encryption_key_valid(self): + # Need to see either an AES-128 key or two AES-256 keys + purposes = [self.get_key_block_purpose(b) for b in range(6)] + + if any(p == self.PURPOSE_VAL_XTS_AES128_KEY for p in purposes): + return True + + return any(p == self.PURPOSE_VAL_XTS_AES256_KEY_1 for p in purposes) and any( + p == self.PURPOSE_VAL_XTS_AES256_KEY_2 for p in purposes + ) + + def change_baud(self, baud): + ESPLoader.change_baud(self, baud) + + def _post_connect(self): + pass + # TODO: Disable watchdogs when USB modes are supported in the stub + # if not self.sync_stub_detected: # Don't run if stub is reused + # self.disable_watchdogs() + + def check_spi_connection(self, spi_connection): + pass # TODO: Define GPIOs for --spi-connection + + +class ESP32P4StubLoader(ESP32P4ROM): + """Access class for ESP32P4 stub loader, runs on top of ROM. + + (Basically the same as ESP32StubLoader, but different base class. + Can possibly be made into a mixin.) + """ + + FLASH_WRITE_SIZE = 0x4000 # matches MAX_WRITE_BLOCK in stub_loader.c + STATUS_BYTES_LENGTH = 2 # same as ESP8266, different to ESP32 ROM + IS_STUB = True + + def __init__(self, rom_loader): + self.secure_download_mode = rom_loader.secure_download_mode + self._port = rom_loader._port + self._trace_enabled = rom_loader._trace_enabled + self.cache = rom_loader.cache + self.flush_input() # resets _slip_reader + + +ESP32P4ROM.STUB_CLASS = ESP32P4StubLoader diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp32s2.py esptool-4.7.0+dfsg/esptool/targets/esp32s2.py --- esptool-4.6.2+dfsg/esptool/targets/esp32s2.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp32s2.py 2023-12-13 11:05:18.000000000 +0000 @@ -16,8 +16,6 @@ CHIP_NAME = "ESP32-S2" IMAGE_CHIP_ID = 2 - FPGA_SLOW_BOOT = False - IROM_MAP_START = 0x40080000 IROM_MAP_END = 0x40B80000 DROM_MAP_START = 0x3F000000 @@ -101,6 +99,8 @@ [0x50000000, 0x50002000, "RTC_DATA"], ] + UF2_FAMILY_ID = 0xBFDD4EEE + def get_pkg_version(self): num_word = 4 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x0F @@ -120,10 +120,16 @@ num_word = 3 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x0F + def get_flash_cap(self): + return self.get_flash_version() + def get_psram_version(self): num_word = 3 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 28) & 0x0F + def get_psram_cap(self): + return self.get_psram_version() + def get_block2_version(self): # BLK_VERSION_MINOR num_word = 4 @@ -137,7 +143,7 @@ 102: "ESP32-S2FNR2", 100: "ESP32-S2R2", }.get( - self.get_flash_version() + self.get_psram_version() * 100, + self.get_flash_cap() + self.get_psram_cap() * 100, "unknown ESP32-S2", ) major_rev = self.get_major_chip_version() @@ -154,14 +160,14 @@ 0: "No Embedded Flash", 1: "Embedded Flash 2MB", 2: "Embedded Flash 4MB", - }.get(self.get_flash_version(), "Unknown Embedded Flash") + }.get(self.get_flash_cap(), "Unknown Embedded Flash") features += [flash_version] psram_version = { 0: "No Embedded PSRAM", 1: "Embedded PSRAM 2MB", 2: "Embedded PSRAM 4MB", - }.get(self.get_psram_version(), "Unknown Embedded PSRAM") + }.get(self.get_psram_cap(), "Unknown Embedded PSRAM") features += [psram_version] block2_version = { @@ -281,6 +287,15 @@ def change_baud(self, baud): ESPLoader.change_baud(self, baud) + def check_spi_connection(self, spi_connection): + if not set(spi_connection).issubset(set(range(0, 22)) | set(range(26, 47))): + raise FatalError("SPI Pin numbers must be in the range 0-21, or 26-46.") + if any([v for v in spi_connection if v in [19, 20]]): + print( + "WARNING: GPIO pins 19 and 20 are used by USB-OTG, " + "consider using other pins for SPI flash connection." + ) + class ESP32S2StubLoader(ESP32S2ROM): """Access class for ESP32-S2 stub loader, runs on top of ROM. diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp32s3.py esptool-4.7.0+dfsg/esptool/targets/esp32s3.py --- esptool-4.6.2+dfsg/esptool/targets/esp32s3.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp32s3.py 2023-12-13 11:05:18.000000000 +0000 @@ -19,8 +19,6 @@ CHIP_DETECT_MAGIC_VALUE = [0x9] - FPGA_SLOW_BOOT = False - IROM_MAP_START = 0x42000000 IROM_MAP_END = 0x44000000 DROM_MAP_START = 0x3C000000 @@ -117,6 +115,8 @@ [0x50000000, 0x50002000, "RTC_DATA"], ] + UF2_FAMILY_ID = 0xC47E5767 + def get_pkg_version(self): num_word = 3 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x07 @@ -165,10 +165,53 @@ def get_chip_description(self): major_rev = self.get_major_chip_version() minor_rev = self.get_minor_chip_version() - return f"{self.CHIP_NAME} (revision v{major_rev}.{minor_rev})" + pkg_version = self.get_pkg_version() + + chip_name = { + 0: "ESP32-S3 (QFN56)", + 1: "ESP32-S3-PICO-1 (LGA56)", + }.get(pkg_version, "unknown ESP32-S3") + + return f"{chip_name} (revision v{major_rev}.{minor_rev})" + + def get_flash_cap(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 27) & 0x07 + + def get_flash_vendor(self): + num_word = 4 + vendor_id = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x07 + return {1: "XMC", 2: "GD", 3: "FM", 4: "TT", 5: "BY"}.get(vendor_id, "") + + def get_psram_cap(self): + num_word = 4 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 3) & 0x03 + + def get_psram_vendor(self): + num_word = 4 + vendor_id = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 7) & 0x03 + return {1: "AP_3v3", 2: "AP_1v8"}.get(vendor_id, "") def get_chip_features(self): - return ["WiFi", "BLE"] + features = ["WiFi", "BLE"] + + flash = { + 0: None, + 1: "Embedded Flash 8MB", + 2: "Embedded Flash 4MB", + }.get(self.get_flash_cap(), "Unknown Embedded Flash") + if flash is not None: + features += [flash + f" ({self.get_flash_vendor()})"] + + psram = { + 0: None, + 1: "Embedded PSRAM 8MB", + 2: "Embedded PSRAM 2MB", + }.get(self.get_psram_cap(), "Unknown Embedded PSRAM") + if psram is not None: + features += [psram + f" ({self.get_psram_vendor()})"] + + return features def get_crystal_freq(self): # ESP32S3 XTAL is fixed to 40MHz @@ -306,6 +349,17 @@ def change_baud(self, baud): ESPLoader.change_baud(self, baud) + def check_spi_connection(self, spi_connection): + if not set(spi_connection).issubset(set(range(0, 22)) | set(range(26, 49))): + raise FatalError("SPI Pin numbers must be in the range 0-21, or 26-48.") + if spi_connection[3] > 46: # hd_gpio_num must be <= SPI_GPIO_NUM_LIMIT (46) + raise FatalError("SPI HD Pin number must be <= 46.") + if any([v for v in spi_connection if v in [19, 20]]): + print( + "WARNING: GPIO pins 19 and 20 are used by USB-Serial/JTAG and USB-OTG, " + "consider using other pins for SPI flash connection." + ) + class ESP32S3StubLoader(ESP32S3ROM): """Access class for ESP32S3 stub loader, runs on top of ROM. diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp32s3beta2.py esptool-4.7.0+dfsg/esptool/targets/esp32s3beta2.py --- esptool-4.6.2+dfsg/esptool/targets/esp32s3beta2.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp32s3beta2.py 2023-12-13 11:05:18.000000000 +0000 @@ -14,11 +14,6 @@ EFUSE_BASE = 0x6001A000 # BLOCK0 read base address - def get_chip_description(self): - major_rev = self.get_major_chip_version() - minor_rev = self.get_minor_chip_version() - return f"{self.CHIP_NAME} (revision v{major_rev}.{minor_rev})" - class ESP32S3BETA2StubLoader(ESP32S3BETA2ROM): """Access class for ESP32S3 stub loader, runs on top of ROM. diff -Nru esptool-4.6.2+dfsg/esptool/targets/esp8266.py esptool-4.7.0+dfsg/esptool/targets/esp8266.py --- esptool-4.6.2+dfsg/esptool/targets/esp8266.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/targets/esp8266.py 2023-12-13 11:05:18.000000000 +0000 @@ -4,7 +4,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later from ..loader import ESPLoader -from ..util import FatalError, NotImplementedInROMError +from ..util import FatalError, NotSupportedError class ESP8266ROM(ESPLoader): @@ -60,6 +60,8 @@ [0x40201010, 0x402E1010, "IROM"], ] + UF2_FAMILY_ID = 0x7EAB61ED + def get_efuses(self): # Return the 128 bits of ESP8266 efuse as a single Python integer result = self.read_reg(0x3FF0005C) << 96 @@ -168,9 +170,10 @@ return (num_sectors - head_sectors) * sector_size def override_vddsdio(self, new_voltage): - raise NotImplementedInROMError( - "Overriding VDDSDIO setting only applies to ESP32" - ) + raise NotSupportedError(self, "Overriding VDDSDIO") + + def check_spi_connection(self, spi_connection): + raise NotSupportedError(self, "Setting --spi-connection") class ESP8266StubLoader(ESP8266ROM): diff -Nru esptool-4.6.2+dfsg/esptool/uf2_writer.py esptool-4.7.0+dfsg/esptool/uf2_writer.py --- esptool-4.6.2+dfsg/esptool/uf2_writer.py 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/uf2_writer.py 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# +# SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: GPL-2.0-or-later +# Code was originally licensed under Apache 2.0 before the release of ESP-IDF v5.2 + +import hashlib +import os +import struct +from typing import List + +from esptool.util import div_roundup + + +class UF2Writer(object): + # The UF2 format is described here: https://github.com/microsoft/uf2 + UF2_BLOCK_SIZE = 512 + # max value of CHUNK_SIZE reduced by optional parts. Currently, MD5_PART only. + UF2_DATA_SIZE = 476 + UF2_MD5_PART_SIZE = 24 + UF2_FIRST_MAGIC = 0x0A324655 + UF2_SECOND_MAGIC = 0x9E5D5157 + UF2_FINAL_MAGIC = 0x0AB16F30 + UF2_FLAG_FAMILYID_PRESENT = 0x00002000 + UF2_FLAG_MD5_PRESENT = 0x00004000 + + def __init__( + self, + chip_id: int, + output_file: os.PathLike, + chunk_size: int, + md5_enabled: bool = True, + ) -> None: + if not md5_enabled: + self.UF2_MD5_PART_SIZE = 0 + self.UF2_FLAG_MD5_PRESENT = 0x00000000 + self.md5_enabled = md5_enabled + self.chip_id = chip_id + self.CHUNK_SIZE = ( + self.UF2_DATA_SIZE - self.UF2_MD5_PART_SIZE + if chunk_size is None + else chunk_size + ) + self.f = open(output_file, "wb") + + def __enter__(self) -> "UF2Writer": + return self + + def __exit__(self, exc_type: str, exc_val: int, exc_tb: List) -> None: + if self.f: + self.f.close() + + @staticmethod + def _to_uint32(num: int) -> bytes: + return struct.pack(" None: + assert len_chunk > 0 + assert len_chunk <= self.CHUNK_SIZE + assert block_no < blocks + block = struct.pack( + " None: + blocks = div_roundup(len(image), self.CHUNK_SIZE) + chunks = [ + image[i : i + self.CHUNK_SIZE] + for i in range(0, len(image), self.CHUNK_SIZE) + ] + for i, chunk in enumerate(chunks): + len_chunk = len(chunk) + self._write_block(addr, chunk, len_chunk, i, blocks) + addr += len_chunk diff -Nru esptool-4.6.2+dfsg/esptool/util.py esptool-4.7.0+dfsg/esptool/util.py --- esptool-4.6.2+dfsg/esptool/util.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/esptool/util.py 2023-12-13 11:05:18.000000000 +0000 @@ -34,6 +34,8 @@ """Given a flash size of the type passed in args.flash_size (ie 512KB or 1MB) then return the size in bytes. """ + if size is None: + return None if "MB" in size: return int(size[: size.index("MB")]) * 1024 * 1024 elif "KB" in size: @@ -66,7 +68,7 @@ If output is not a TTY (for example redirected a pipe), no overwriting happens and this function is the same as print(). """ - if sys.stdout.isatty(): + if hasattr(sys.stdout, "isatty") and sys.stdout.isatty(): print("\r%s" % message, end="\n" if last_line else "") else: print(message) @@ -165,7 +167,7 @@ def __init__(self, esp, function_name): FatalError.__init__( self, - "Function %s is not supported for %s." % (function_name, esp.CHIP_NAME), + f"{function_name} is not supported by {esp.CHIP_NAME}.", ) diff -Nru esptool-4.6.2+dfsg/flasher_stub/Makefile esptool-4.7.0+dfsg/flasher_stub/Makefile --- esptool-4.6.2+dfsg/flasher_stub/Makefile 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/Makefile 2023-12-13 11:05:18.000000000 +0000 @@ -69,6 +69,7 @@ STUB_ELF_32C2 = $(BUILD_DIR)/$(STUB)_32c2.elf STUB_ELF_32C6 = $(BUILD_DIR)/$(STUB)_32c6.elf STUB_ELF_32H2 = $(BUILD_DIR)/$(STUB)_32h2.elf +STUB_ELF_32P4 = $(BUILD_DIR)/$(STUB)_32p4.elf STUBS_ELF = ifneq ($(WITHOUT_ESP8266),1) @@ -92,7 +93,8 @@ $(STUB_ELF_32H2_BETA_2) \ $(STUB_ELF_32C2) \ $(STUB_ELF_32C6) \ - $(STUB_ELF_32H2) + $(STUB_ELF_32H2) \ + $(STUB_ELF_32P4) endif .PHONY: all clean install @@ -137,7 +139,7 @@ $(STUB_ELF_32S3_BETA_2): $(SRCS) $(BUILD_DIR) ld/stub_32s3_beta_2.ld @echo " CC(32S3) $^ -> $@" - $(Q) $(CROSS_32S3)gcc $(CFLAGS) -DESP32S3=1 -DESP32S3BETA2=1 -Tstub_32s3_beta_2.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) + $(Q) $(CROSS_32S3)gcc $(CFLAGS) -DESP32S3BETA2=1 -Tstub_32s3_beta_2.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) $(STUB_ELF_32S3): $(SRCS) $(BUILD_DIR) ld/stub_32s3.ld @echo " CC(32S3) $^ -> $@" @@ -153,11 +155,11 @@ $(STUB_ELF_32H2_BETA_1): $(SRCS) $(BUILD_DIR) ld/stub_32h2_beta_1.ld @echo " CC(32H2BETA1) $^ -> $@" - $(Q) $(CROSS_ESPRISCV32)gcc $(CFLAGS_ESPRISCV32) -DESP32H2BETA1=1 -DESP32H2BETA1=1 -Tstub_32h2_beta_1.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) + $(Q) $(CROSS_ESPRISCV32)gcc $(CFLAGS_ESPRISCV32) -DESP32H2BETA1=1 -Tstub_32h2_beta_1.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) $(STUB_ELF_32H2_BETA_2): $(SRCS) $(BUILD_DIR) ld/stub_32h2_beta_2.ld @echo " CC(32H2BETA2) $^ -> $@" - $(Q) $(CROSS_ESPRISCV32)gcc $(CFLAGS_ESPRISCV32) -DESP32H2BETA2=1 -DESP32H2BETA2=1 -Tstub_32h2_beta_2.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) + $(Q) $(CROSS_ESPRISCV32)gcc $(CFLAGS_ESPRISCV32) -DESP32H2BETA2=1 -Tstub_32h2_beta_2.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) $(STUB_ELF_32C2): $(SRCS) $(BUILD_DIR) ld/stub_32c2.ld @echo " CC(32C2) $^ -> $@" @@ -171,5 +173,9 @@ @echo " CC(32H2) $^ -> $@" $(Q) $(CROSS_ESPRISCV32)gcc $(CFLAGS_ESPRISCV32) -DESP32H2=1 -Tstub_32h2.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) +$(STUB_ELF_32P4): $(SRCS) $(BUILD_DIR) ld/stub_32p4.ld + @echo " CC(32P4) $^ -> $@" + $(Q) $(CROSS_ESPRISCV32)gcc $(CFLAGS_ESPRISCV32) -DESP32P4=1 -Tstub_32p4.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) + clean: $(Q) rm -rf $(BUILD_DIR) diff -Nru esptool-4.6.2+dfsg/flasher_stub/include/rom_functions.h esptool-4.7.0+dfsg/flasher_stub/include/rom_functions.h --- esptool-4.6.2+dfsg/flasher_stub/include/rom_functions.h 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/include/rom_functions.h 2023-12-13 11:05:18.000000000 +0000 @@ -107,6 +107,10 @@ #if ESP32S2_OR_LATER uint32_t GetSecurityInfoProc(int* pMsg, int* pnErr, uint8_t *buf); // pMsg and pnErr unused in ROM +#if ESP32C3 +extern uint32_t _rom_eco_version; // rom constant to define ECO version +uint32_t GetSecurityInfoProcNewEco(int* pMsg, int* pnErr, uint8_t *buf); // GetSecurityInfo for C3 ECO7+ +#endif // ESP32C3 SpiFlashOpResult SPI_read_status_high(esp_rom_spiflash_chip_t *spi, uint32_t *status); #else /* Note: On ESP32 this was a static function whose first argument was elided by the diff -Nru esptool-4.6.2+dfsg/flasher_stub/include/soc_support.h esptool-4.7.0+dfsg/flasher_stub/include/soc_support.h --- esptool-4.6.2+dfsg/flasher_stub/include/soc_support.h 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/include/soc_support.h 2023-12-13 11:05:18.000000000 +0000 @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -/* SoC-level support for ESP8266/ESP32. +/* SoC-level support. * * Provide a unified register-level interface. * @@ -23,6 +23,7 @@ #define WRITE_REG(REG, VAL) *((volatile uint32_t *)(REG)) = (VAL) #define REG_SET_MASK(reg, mask) WRITE_REG((reg), (READ_REG(reg)|(mask))) #define REG_CLR_MASK(reg, mask) WRITE_REG((reg), (READ_REG(reg)&(~(mask)))) +#define REG_SET_FIELD(_r, _f, _v) (WRITE_REG((_r),((READ_REG(_r) & ~((_f) << (_f##_S)))|(((_v) & (_f))<<(_f##_S))))) #define ESP32_OR_LATER !(ESP8266) #define ESP32S2_OR_LATER !(ESP8266 || ESP32) @@ -55,12 +56,24 @@ #define IS_RISCV 1 #endif // ESP32H2 +#ifdef ESP32P4 +// TODO: Add support for USB modes when MP is available +// #define WITH_USB_JTAG_SERIAL 1 +// #define WITH_USB_OTG 1 +#define IS_RISCV 1 +#endif // ESP32P4 + // Increase CPU freq to speed up read/write operations over USB -// Temporarily disabled on the S3 due to stability issues, will be fixed in the next minor release +// Disabled on the S3 due to stability issues, would require dbias adjustment. +// https://github.com/espressif/esptool/issues/832, https://github.com/espressif/esptool/issues/808 #define USE_MAX_CPU_FREQ ((WITH_USB_JTAG_SERIAL || WITH_USB_OTG) && !ESP32S3) +// Later chips don't support ets_efuse_get_spiconfig. +#define SUPPORT_CONFIG_SPI (ESP32 || ESP32S2 || ESP32S3 || ESP32S3BETA2 || ESP32C3 || ESP32H2BETA1 || ESP32H2BETA2 || ESP32C6BETA) + /********************************************************** * Per-SOC based peripheral register base addresses + * Sync with reg_base.h in ESP-IDF */ #ifdef ESP8266 #define UART_BASE_REG 0x60000000 /* UART0 */ @@ -72,6 +85,7 @@ #define SPI_BASE_REG 0x3ff42000 /* SPI peripheral 1, used for SPI flash */ #define SPI0_BASE_REG 0x3ff43000 /* SPI peripheral 0, inner state machine */ #define GPIO_BASE_REG 0x3ff44000 /* GPIO */ +#define DR_REG_IO_MUX_BASE 0x3ff49000 #endif #ifdef ESP32S2 @@ -82,6 +96,7 @@ #define USB_BASE_REG 0x60080000 #define RTCCNTL_BASE_REG 0x3f408000 #define SYSTEM_BASE_REG 0x3F4C0000 +#define DR_REG_IO_MUX_BASE 0x3f409000 #endif #ifdef ESP32S3 @@ -93,6 +108,19 @@ #define RTCCNTL_BASE_REG 0x60008000 /* RTC Control */ #define USB_DEVICE_BASE_REG 0x60038000 #define SYSTEM_BASE_REG 0x600C0000 +#define DR_REG_IO_MUX_BASE 0x60009000 +#endif + +#ifdef ESP32S3BETA2 +#define UART_BASE_REG 0x60000000 /* UART0 */ +#define SPI_BASE_REG 0x60002000 /* SPI peripheral 1, used for SPI flash */ +#define SPI0_BASE_REG 0x60003000 /* SPI peripheral 0, inner state machine */ +#define GPIO_BASE_REG 0x60004000 /* GPIO */ +#define USB_BASE_REG 0x60080000 +#define RTCCNTL_BASE_REG 0x60008000 /* RTC Control */ +#define USB_DEVICE_BASE_REG 0x60038000 +#define SYSTEM_BASE_REG 0x600C0000 +#define DR_REG_IO_MUX_BASE 0x60009000 #endif #ifdef ESP32C3 @@ -103,6 +131,7 @@ #define RTCCNTL_BASE_REG 0x60008000 /* RTC Control */ #define USB_DEVICE_BASE_REG 0x60043000 #define SYSTEM_BASE_REG 0x600C0000 +#define DR_REG_IO_MUX_BASE 0x60009000 #endif #ifdef ESP32C6BETA @@ -110,6 +139,7 @@ #define SPI_BASE_REG 0x60002000 /* SPI peripheral 1, used for SPI flash */ #define SPI0_BASE_REG 0x60003000 /* SPI peripheral 0, inner state machine */ #define GPIO_BASE_REG 0x60004000 +#define DR_REG_IO_MUX_BASE 0x60009000 #endif #ifdef ESP32H2BETA1 @@ -118,6 +148,7 @@ #define SPI0_BASE_REG 0x60003000 /* SPI peripheral 0, inner state machine */ #define GPIO_BASE_REG 0x60004000 #define RTCCNTL_BASE_REG 0x60008000 +#define DR_REG_IO_MUX_BASE 0x60009000 #endif #ifdef ESP32H2BETA2 @@ -125,6 +156,7 @@ #define SPI_BASE_REG 0x60002000 /* SPI peripheral 1, used for SPI flash */ #define SPI0_BASE_REG 0x60003000 /* SPI peripheral 0, inner state machine */ #define GPIO_BASE_REG 0x60004000 +#define DR_REG_IO_MUX_BASE 0x60009000 #endif #ifdef ESP32C2 @@ -132,6 +164,7 @@ #define SPI_BASE_REG 0x60002000 /* SPI peripheral 1, used for SPI flash */ #define SPI0_BASE_REG 0x60003000 /* SPI peripheral 0, inner state machine */ #define GPIO_BASE_REG 0x60004000 +#define DR_REG_IO_MUX_BASE 0x60009000 #endif #ifdef ESP32C6 @@ -142,6 +175,7 @@ #define USB_DEVICE_BASE_REG 0x6000F000 #define DR_REG_PCR_BASE 0x60096000 #define DR_REG_LP_WDT_BASE 0x600B1C00 +#define DR_REG_IO_MUX_BASE 0x60009000 #endif #ifdef ESP32H2 @@ -152,6 +186,15 @@ #define USB_DEVICE_BASE_REG 0x6000F000 #define DR_REG_PCR_BASE 0x60096000 #define DR_REG_LP_WDT_BASE 0x600B1C00 +#define DR_REG_IO_MUX_BASE 0x60009000 +#endif + +#ifdef ESP32P4 +#define UART_BASE_REG 0x500CA000 /* UART0 */ +#define SPI_BASE_REG 0x5008D000 /* SPI peripheral 1, used for SPI flash */ +#define SPI0_BASE_REG 0x5008C000 /* SPI peripheral 0, inner state machine */ +#define GPIO_BASE_REG 0x500E0000 +#define DR_REG_IO_MUX_BASE 0x500E1000 #endif /********************************************************** @@ -366,21 +409,6 @@ * SYSTEM registers */ -#ifdef ESP32S3 -#define SYSTEM_CPU_PER_CONF_REG (SYSTEM_BASE_REG + 0x010) -#define SYSTEM_CPUPERIOD_SEL_M ((SYSTEM_CPUPERIOD_SEL_V)<<(SYSTEM_CPUPERIOD_SEL_S)) -#define SYSTEM_CPUPERIOD_SEL_V 0x3 -#define SYSTEM_CPUPERIOD_SEL_S 0 -#define SYSTEM_CPUPERIOD_MAX 1 // CPU_CLK frequency is 160 MHz - not actually max possible frequency, -// see https://github.com/espressif/esptool/issues/832 and https://github.com/espressif/esptool/issues/808 - -#define SYSTEM_SYSCLK_CONF_REG (SYSTEM_BASE_REG + 0x060) -#define SYSTEM_SOC_CLK_SEL_M ((SYSTEM_SOC_CLK_SEL_V)<<(SYSTEM_SOC_CLK_SEL_S)) -#define SYSTEM_SOC_CLK_SEL_V 0x3 -#define SYSTEM_SOC_CLK_SEL_S 10 -#define SYSTEM_SOC_CLK_MAX 1 -#endif // ESP32S3 - #ifdef ESP32C3 #define SYSTEM_CPU_PER_CONF_REG (SYSTEM_BASE_REG + 0x008) #define SYSTEM_CPUPERIOD_SEL_M ((SYSTEM_CPUPERIOD_SEL_V)<<(SYSTEM_CPUPERIOD_SEL_S)) @@ -423,7 +451,7 @@ #define PCR_SOC_CLK_SEL_V 0x3 #define PCR_SOC_CLK_SEL_S 16 #define PCR_SOC_CLK_MAX 1 // CPU_CLK frequency is 160 MHz (source is PLL_CLK) -#endif // ESP32C6 +#endif // ESP32H2 /********************************************************** * Per-SOC security info buffer size @@ -436,3 +464,102 @@ #if ESP32S3_OR_LATER #define SECURITY_INFO_BYTES 20 #endif // ESP32S3_OR_LATER + +/********************************************************** + * Per-SOC address of the rom_spiflash_legacy_funcs symbol in ROM + * Can be retrieved with gdb: "info address rom_spiflash_legacy_funcs" + */ + +#if ESP32 || ESP32S2 || ESP32S3 || ESP32S3BETA2 +#define ROM_SPIFLASH_LEGACY 0x3ffae270 +#endif // ESP32 || ESP32S2 || ESP32S3 || ESP32S3BETA2 + +#if ESP32C3 || ESP32C6BETA || ESP32C2 || ESP32C6 +#define ROM_SPIFLASH_LEGACY 0x3fcdfff4 +#endif // ESP32C3 || ESP32C6BETA || ESP32C2 || ESP32C6 + +#if ESP32H2BETA1 || ESP32H2BETA2 +#define ROM_SPIFLASH_LEGACY 0x3fcdfff0 +#endif // ESP32H2BETA1 || ESP32H2BETA2 + +#if ESP32H2 +#define ROM_SPIFLASH_LEGACY 0x4084fff0 +#endif // ESP32H2 + +#if ESP32P4 +#define ROM_SPIFLASH_LEGACY 0x4ff3ffec +#endif // ESP32P4 + +/********************************************************** + * IO-MUX peripheral + */ + +#define MCU_SEL 0x7 +#define MCU_SEL_S 12 + +#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC) + +#if ESP32 +// PERIPHS_IO_MUX_SD_... +#define PERIPHS_IO_MUX_SPICLK_U (DR_REG_IO_MUX_BASE + 0x60) +#define PERIPHS_IO_MUX_SPID_U (DR_REG_IO_MUX_BASE + 0x68) +#define PERIPHS_IO_MUX_SPIQ_U (DR_REG_IO_MUX_BASE + 0x64) +#define PERIPHS_IO_MUX_SPICS0_U (DR_REG_IO_MUX_BASE + 0x5c) +#define FUNC_GPIO 2 +#endif // ESP32 + +#if ESP32S2 +#define PERIPHS_IO_MUX_SPICLK_U (DR_REG_IO_MUX_BASE + 0x7c) +#define PERIPHS_IO_MUX_SPIQ_U (DR_REG_IO_MUX_BASE + 0x80) +#define PERIPHS_IO_MUX_SPID_U (DR_REG_IO_MUX_BASE + 0x84) +#define PERIPHS_IO_MUX_SPICS0_U (DR_REG_IO_MUX_BASE + 0x78) +#define FUNC_GPIO 1 +#endif // ESP32S2 + +#if ESP32C3 +#define PERIPHS_IO_MUX_SPICLK_U (DR_REG_IO_MUX_BASE + 0x40) +#define PERIPHS_IO_MUX_SPIQ_U (DR_REG_IO_MUX_BASE + 0x48) +#define PERIPHS_IO_MUX_SPID_U (DR_REG_IO_MUX_BASE + 0x44) +#define PERIPHS_IO_MUX_SPICS0_U (DR_REG_IO_MUX_BASE + 0x3c) +#define FUNC_GPIO 1 +#endif // ESP32C3 + +#if ESP32S3 || ESP32S3BETA2 +#define PERIPHS_IO_MUX_SPICLK_U (DR_REG_IO_MUX_BASE + 0x7c) +#define PERIPHS_IO_MUX_SPIQ_U (DR_REG_IO_MUX_BASE + 0x80) +#define PERIPHS_IO_MUX_SPID_U (DR_REG_IO_MUX_BASE + 0x84) +#define PERIPHS_IO_MUX_SPICS0_U (DR_REG_IO_MUX_BASE + 0x78) +#define FUNC_GPIO 1 +#endif // ESP32S3 || ESP32S3BETA2 + +#if ESP32C2 +#define PERIPHS_IO_MUX_SPICLK_U (DR_REG_IO_MUX_BASE + 0x40) +#define PERIPHS_IO_MUX_SPIQ_U (DR_REG_IO_MUX_BASE + 0x48) +#define PERIPHS_IO_MUX_SPID_U (DR_REG_IO_MUX_BASE + 0x44) +#define PERIPHS_IO_MUX_SPICS0_U (DR_REG_IO_MUX_BASE + 0x3c) +#define FUNC_GPIO 1 +#endif // ESP32C2 + +#if ESP32C6 || ESP32C6BETA +#define PERIPHS_IO_MUX_SPICLK_U (DR_REG_IO_MUX_BASE + 0x78) +#define PERIPHS_IO_MUX_SPIQ_U (DR_REG_IO_MUX_BASE + 0x68) +#define PERIPHS_IO_MUX_SPID_U (DR_REG_IO_MUX_BASE + 0x7c) +#define PERIPHS_IO_MUX_SPICS0_U (DR_REG_IO_MUX_BASE + 0x64) +#define FUNC_GPIO 1 +#endif // ESP32C6 || ESP32C6BETA + +#if ESP32H2 || ESP32H2BETA1 || ESP32H2BETA2 +#define PERIPHS_IO_MUX_SPICLK_U (DR_REG_IO_MUX_BASE + 0x50) +#define PERIPHS_IO_MUX_SPIQ_U (DR_REG_IO_MUX_BASE + 0x44) +#define PERIPHS_IO_MUX_SPID_U (DR_REG_IO_MUX_BASE + 0x54) +#define PERIPHS_IO_MUX_SPICS0_U (DR_REG_IO_MUX_BASE + 0x40) +#define FUNC_GPIO 1 +#endif // ESP32H2 || ESP32H2BETA1 || ESP32H2BETA2 + +#if ESP32P4 +#define PERIPHS_IO_MUX_SPICLK_U (DR_REG_IO_MUX_BASE + 0x7c) +#define PERIPHS_IO_MUX_SPIQ_U (DR_REG_IO_MUX_BASE + 0x80) +#define PERIPHS_IO_MUX_SPID_U (DR_REG_IO_MUX_BASE + 0x84) +#define PERIPHS_IO_MUX_SPICS0_U (DR_REG_IO_MUX_BASE + 0x78) +#define FUNC_GPIO 1 +#endif // ESP32P4 diff -Nru esptool-4.6.2+dfsg/flasher_stub/include/stub_flasher.h esptool-4.7.0+dfsg/flasher_stub/include/stub_flasher.h --- esptool-4.6.2+dfsg/flasher_stub/include/stub_flasher.h 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/include/stub_flasher.h 2023-12-13 11:05:18.000000000 +0000 @@ -6,9 +6,8 @@ * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD */ -#ifndef STUB_FLASHER_H_ -#define STUB_FLASHER_H_ - +#pragma once +#include #include /* Maximum write block size, used for various buffers. */ @@ -22,8 +21,9 @@ #define SECTORS_PER_BLOCK (FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE) /* 32-bit addressing is supported only by ESP32S3 */ -#if defined(ESP32S3) +#if defined(ESP32S3) && !defined(ESP32S3BETA2) #define FLASH_MAX_SIZE 64*1024*1024 +extern bool large_flash_mode; #else #define FLASH_MAX_SIZE 16*1024*1024 #endif @@ -108,5 +108,3 @@ ESP_CMD_NOT_IMPLEMENTED = 0xFF, } esp_command_error; - -#endif /* STUB_FLASHER_H_ */ diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/rom_32c3.ld esptool-4.7.0+dfsg/flasher_stub/ld/rom_32c3.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/rom_32c3.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/rom_32c3.ld 2023-12-13 11:05:18.000000000 +0000 @@ -67,6 +67,7 @@ recv_packet = 0x400000ac; GetUartDevice = 0x400000b0; GetSecurityInfoProc = 0x4004b9da; +GetSecurityInfoProcNewEco = 0x4004d51e; /* manually added from esp32c3eco7-20230720; new address of function for eco7+ */ UartDwnLdProc = 0x400000b4; Uart_Init = 0x400000b8; ets_set_user_start = 0x400000bc; @@ -2197,4 +2198,3 @@ */ _rom_chip_id = 0x40000010; _rom_eco_version = 0x40000014; - diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/rom_32h2.ld esptool-4.7.0+dfsg/flasher_stub/ld/rom_32h2.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/rom_32h2.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/rom_32h2.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,8 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ /* ROM function interface esp32h2.rom.ld for esp32h2 * * @@ -22,7 +17,7 @@ PROVIDE ( SPI_write_status = esp_rom_spiflash_write_status); PROVIDE ( SPIRead = esp_rom_spiflash_read); PROVIDE ( SPIParamCfg = esp_rom_spiflash_config_param); -PROVIDE ( SPIEraseChip = esp_rom_spiflash_erase_chip); +PROVIDE ( SPIEraseChip = esp_rom_spiflash_erase_chip); PROVIDE ( SPIEraseSector = esp_rom_spiflash_erase_sector); PROVIDE ( SPIEraseBlock = esp_rom_spiflash_erase_block); PROVIDE ( SPI_Write_Encrypt_Enable = esp_rom_spiflash_write_encrypted_enable); diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/rom_32p4.ld esptool-4.7.0+dfsg/flasher_stub/ld/rom_32p4.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/rom_32p4.ld 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/rom_32p4.ld 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,619 @@ +/* ROM function interface esp32p4.rom.ld for esp32p4 + * + * + * Generated from ./target/esp32p4/interface-esp32p4.yml md5sum f6516bd9708d890f63db87f8aed53ca7 + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group common + ***************************************/ + +PROVIDE ( SPIWrite = esp_rom_spiflash_write); +PROVIDE ( SPI_read_status_high = esp_rom_spiflash_read_statushigh); +PROVIDE ( SPI_write_status = esp_rom_spiflash_write_status); +PROVIDE ( SPIRead = esp_rom_spiflash_read); +PROVIDE ( SPIParamCfg = esp_rom_spiflash_config_param); +PROVIDE ( SPIEraseChip = esp_rom_spiflash_erase_chip); +PROVIDE ( SPIEraseSector = esp_rom_spiflash_erase_sector); +PROVIDE ( SPIEraseBlock = esp_rom_spiflash_erase_block); +PROVIDE ( SPI_Write_Encrypt_Enable = esp_rom_spiflash_write_encrypted_enable); +PROVIDE ( SPI_Write_Encrypt_Disable = esp_rom_spiflash_write_encrypted_disable); +PROVIDE ( SPI_Encrypt_Write = esp_rom_spiflash_write_encrypted); + +/*************************************** + Group common + ***************************************/ + +/* Functions */ +rtc_get_reset_reason = 0x4fc00018; +rtc_get_wakeup_cause = 0x4fc0001c; +pmu_enable_unhold_pads = 0x4fc00020; +ets_printf = 0x4fc00024; +ets_install_putc1 = 0x4fc00028; +ets_install_putc2 = 0x4fc0002c; +ets_install_uart_printf = 0x4fc00030; +ets_install_usb_printf = 0x4fc00034; +ets_get_printf_channel = 0x4fc00038; +ets_delay_us = 0x4fc0003c; +ets_get_cpu_frequency = 0x4fc00040; +ets_update_cpu_frequency = 0x4fc00044; +ets_install_lock = 0x4fc00048; +UartRxString = 0x4fc0004c; +UartGetCmdLn = 0x4fc00050; +uart_tx_one_char = 0x4fc00054; +uart_tx_one_char2 = 0x4fc00058; +uart_tx_one_char3 = 0x4fc0005c; +uart_rx_one_char = 0x4fc00060; +uart_rx_one_char_block = 0x4fc00064; +uart_rx_intr_handler = 0x4fc00068; +uart_rx_readbuff = 0x4fc0006c; +uartAttach = 0x4fc00070; +uart_tx_flush = 0x4fc00074; +uart_tx_wait_idle = 0x4fc00078; +uart_div_modify = 0x4fc0007c; +ets_write_char_uart = 0x4fc00080; +uart_tx_switch = 0x4fc00084; +uart_buff_switch = 0x4fc00088; +roundup2 = 0x4fc0008c; +multofup = 0x4fc00090; +software_reset = 0x4fc00094; +software_reset_cpu = 0x4fc00098; +ets_clk_assist_debug_clock_enable = 0x4fc0009c; +clear_super_wdt_reset_flag = 0x4fc000a0; +disable_default_watchdog = 0x4fc000a4; +ets_set_appcpu_boot_addr = 0x4fc000a8; +send_packet = 0x4fc000ac; +recv_packet = 0x4fc000b0; +GetUartDevice = 0x4fc000b4; +UartDwnLdProc = 0x4fc000b8; +GetSecurityInfoProc = 0x4fc000bc; +Uart_Init = 0x4fc000c0; +ets_set_user_start = 0x4fc000c4; +/* Data (.data, .bss, .rodata) */ +ets_rom_layout_p = 0x4fc1fffc; +ets_ops_table_ptr = 0x4ff3fff4; +g_saved_pc = 0x4ff3fff8; + + +/*************************************** + Group miniz + ***************************************/ + +/* Functions */ +mz_adler32 = 0x4fc000c8; +mz_free = 0x4fc000cc; +tdefl_compress = 0x4fc000d0; +tdefl_compress_buffer = 0x4fc000d4; +tdefl_compress_mem_to_heap = 0x4fc000d8; +tdefl_compress_mem_to_mem = 0x4fc000dc; +tdefl_compress_mem_to_output = 0x4fc000e0; +tdefl_get_adler32 = 0x4fc000e4; +tdefl_get_prev_return_status = 0x4fc000e8; +tdefl_init = 0x4fc000ec; +tdefl_write_image_to_png_file_in_memory = 0x4fc000f0; +tdefl_write_image_to_png_file_in_memory_ex = 0x4fc000f4; +tinfl_decompress = 0x4fc000f8; +tinfl_decompress_mem_to_callback = 0x4fc000fc; +tinfl_decompress_mem_to_heap = 0x4fc00100; +tinfl_decompress_mem_to_mem = 0x4fc00104; + + +/*************************************** + Group spi_extmem_common + ***************************************/ + +/* Functions */ +esp_rom_spi_cmd_config = 0x4fc00108; +esp_rom_spi_cmd_start = 0x4fc0010c; +esp_rom_spi_set_op_mode = 0x4fc00110; +esp_rom_spi_set_dtr_swap_mode = 0x4fc00114; + + +/*************************************** + Group spiflash_legacy + ***************************************/ + +/* Functions */ +esp_rom_spiflash_wait_idle = 0x4fc00118; +esp_rom_spiflash_write_encrypted = 0x4fc0011c; +esp_rom_spiflash_write_encrypted_dest = 0x4fc00120; +esp_rom_spiflash_write_encrypted_enable = 0x4fc00124; +esp_rom_spiflash_write_encrypted_disable = 0x4fc00128; +esp_rom_spiflash_erase_chip = 0x4fc0012c; +_esp_rom_spiflash_erase_sector = 0x4fc00130; +_esp_rom_spiflash_erase_block = 0x4fc00134; +_esp_rom_spiflash_write = 0x4fc00138; +_esp_rom_spiflash_read = 0x4fc0013c; +_esp_rom_spiflash_unlock = 0x4fc00140; +_SPIEraseArea = 0x4fc00144; +_SPI_write_enable = 0x4fc00148; +esp_rom_spiflash_erase_sector = 0x4fc0014c; +esp_rom_spiflash_erase_block = 0x4fc00150; +esp_rom_spiflash_write = 0x4fc00154; +esp_rom_spiflash_read = 0x4fc00158; +esp_rom_spiflash_unlock = 0x4fc0015c; +SPIEraseArea = 0x4fc00160; +SPI_write_enable = 0x4fc00164; +esp_rom_spiflash_config_param = 0x4fc00168; +esp_rom_spiflash_read_user_cmd = 0x4fc0016c; +esp_rom_spiflash_select_qio_pins = 0x4fc00170; +esp_rom_spi_flash_auto_sus_res = 0x4fc00174; +esp_rom_spi_flash_send_resume = 0x4fc00178; +esp_rom_spi_flash_update_id = 0x4fc0017c; +esp_rom_spiflash_config_clk = 0x4fc00180; +esp_rom_spiflash_config_readmode = 0x4fc00184; +esp_rom_spiflash_read_status = 0x4fc00188; +esp_rom_spiflash_read_statushigh = 0x4fc0018c; +esp_rom_spiflash_write_status = 0x4fc00190; +esp_rom_spiflash_write_disable = 0x4fc00194; +spi_cache_mode_switch = 0x4fc00198; +spi_common_set_dummy_output = 0x4fc0019c; +spi_common_set_flash_cs_timing = 0x4fc001a0; +esp_rom_spi_set_address_bit_len = 0x4fc001a4; +SPILock = 0x4fc001a8; +SPIMasterReadModeCnfig = 0x4fc001ac; +SPI_Common_Command = 0x4fc001b0; +SPI_WakeUp = 0x4fc001b4; +SPI_block_erase = 0x4fc001b8; +SPI_chip_erase = 0x4fc001bc; +SPI_init = 0x4fc001c0; +SPI_page_program = 0x4fc001c4; +SPI_read_data = 0x4fc001c8; +SPI_sector_erase = 0x4fc001cc; +SelectSpiFunction = 0x4fc001d0; +SetSpiDrvs = 0x4fc001d4; +Wait_SPI_Idle = 0x4fc001d8; +spi_dummy_len_fix = 0x4fc001dc; +Disable_QMode = 0x4fc001e0; +Enable_QMode = 0x4fc001e4; +spi_flash_attach = 0x4fc001e8; +spi_flash_get_chip_size = 0x4fc001ec; +spi_flash_guard_set = 0x4fc001f0; +spi_flash_guard_get = 0x4fc001f4; +spi_flash_read_encrypted = 0x4fc001f8; +/* Data (.data, .bss, .rodata) */ +rom_spiflash_legacy_funcs = 0x4ff3ffec; +rom_spiflash_legacy_data = 0x4ff3ffe8; +g_flash_guard_ops = 0x4ff3fff0; + + +/*************************************** + Group hal_systimer + ***************************************/ + +/* Functions */ +systimer_hal_init = 0x4fc00228; +systimer_hal_deinit = 0x4fc0022c; +systimer_hal_set_tick_rate_ops = 0x4fc00230; +systimer_hal_get_counter_value = 0x4fc00234; +systimer_hal_get_time = 0x4fc00238; +systimer_hal_set_alarm_target = 0x4fc0023c; +systimer_hal_set_alarm_period = 0x4fc00240; +systimer_hal_get_alarm_value = 0x4fc00244; +systimer_hal_enable_alarm_int = 0x4fc00248; +systimer_hal_on_apb_freq_update = 0x4fc0024c; +systimer_hal_counter_value_advance = 0x4fc00250; +systimer_hal_enable_counter = 0x4fc00254; +systimer_hal_select_alarm_mode = 0x4fc00258; +systimer_hal_connect_alarm_counter = 0x4fc0025c; +systimer_hal_counter_can_stall_by_cpu = 0x4fc00260; + + +/*************************************** + Group cache + ***************************************/ + +/* Functions */ +Cache_Get_L1_ICache_Line_Size = 0x4fc003c4; +Cache_Get_L1_DCache_Line_Size = 0x4fc003c8; +Cache_Get_L2_Cache_Line_Size = 0x4fc003cc; +Cache_Get_Mode = 0x4fc003d0; +Cache_Set_L2_Cache_Mode = 0x4fc003d4; +Cache_Address_Through_Cache = 0x4fc003d8; +ROM_Boot_Cache_Init = 0x4fc003dc; +Cache_Sync_Addr = 0x4fc003e0; +Cache_Invalidate_Addr = 0x4fc003e4; +Cache_Invalidate_Addr_Gid = 0x4fc003e8; +Cache_Clean_Addr = 0x4fc003ec; +Cache_Clean_Addr_Gid = 0x4fc003f0; +Cache_WriteBack_Addr = 0x4fc003f4; +Cache_WriteBack_Addr_Gid = 0x4fc003f8; +Cache_WriteBack_Invalidate_Addr = 0x4fc003fc; +Cache_WriteBack_Invalidate_Addr_Gid = 0x4fc00400; +Cache_Invalidate_All = 0x4fc00404; +Cache_Invalidate_All_Gid = 0x4fc00408; +Cache_Clean_All = 0x4fc0040c; +Cache_Clean_All_Gid = 0x4fc00410; +Cache_WriteBack_All = 0x4fc00414; +Cache_WriteBack_All_Gid = 0x4fc00418; +Cache_WriteBack_Invalidate_All = 0x4fc0041c; +Cache_WriteBack_Invalidate_All_Gid = 0x4fc00420; +Cache_Mask_All = 0x4fc00424; +Cache_Suspend_L1_CORE0_ICache_Autoload = 0x4fc00428; +Cache_Resume_L1_CORE0_ICache_Autoload = 0x4fc0042c; +Cache_Suspend_L1_CORE1_ICache_Autoload = 0x4fc00430; +Cache_Resume_L1_CORE1_ICache_Autoload = 0x4fc00434; +Cache_Suspend_L1_DCache_Autoload = 0x4fc00438; +Cache_Resume_L1_DCache_Autoload = 0x4fc0043c; +Cache_Suspend_L2_Cache_Autoload = 0x4fc00440; +Cache_Resume_L2_Cache_Autoload = 0x4fc00444; +Cache_Start_L1_CORE0_ICache_Preload = 0x4fc00448; +Cache_L1_CORE0_ICache_Preload_Done = 0x4fc0044c; +Cache_End_L1_CORE0_ICache_Preload = 0x4fc00450; +Cache_Start_L1_CORE1_ICache_Preload = 0x4fc00454; +Cache_L1_CORE1_ICache_Preload_Done = 0x4fc00458; +Cache_End_L1_CORE1_ICache_Preload = 0x4fc0045c; +Cache_Start_L1_DCache_Preload = 0x4fc00460; +Cache_L1_DCache_Preload_Done = 0x4fc00464; +Cache_End_L1_DCache_Preload = 0x4fc00468; +Cache_Start_L2_Cache_Preload = 0x4fc0046c; +Cache_L2_Cache_Preload_Done = 0x4fc00470; +Cache_End_L2_Cache_Preload = 0x4fc00474; +Cache_Config_L1_CORE0_ICache_Autoload = 0x4fc00478; +Cache_Enable_L1_CORE0_ICache_Autoload = 0x4fc0047c; +Cache_Disable_L1_CORE0_ICache_Autoload = 0x4fc00480; +Cache_Config_L1_CORE1_ICache_Autoload = 0x4fc00484; +Cache_Enable_L1_CORE1_ICache_Autoload = 0x4fc00488; +Cache_Disable_L1_CORE1_ICache_Autoload = 0x4fc0048c; +Cache_Config_L1_DCache_Autoload = 0x4fc00490; +Cache_Enable_L1_DCache_Autoload = 0x4fc00494; +Cache_Disable_L1_DCache_Autoload = 0x4fc00498; +Cache_Config_L2_Cache_Autoload = 0x4fc0049c; +Cache_Enable_L2_Cache_Autoload = 0x4fc004a0; +Cache_Disable_L2_Cache_Autoload = 0x4fc004a4; +Cache_Enable_L1_CORE0_ICache_PreLock = 0x4fc004a8; +Cache_Disable_L1_CORE0_ICache_PreLock = 0x4fc004ac; +Cache_Enable_L1_CORE1_ICache_PreLock = 0x4fc004b0; +Cache_Disable_L1_CORE1_ICache_PreLock = 0x4fc004b4; +Cache_Enable_L1_DCache_PreLock = 0x4fc004b8; +Cache_Disable_L1_DCache_PreLock = 0x4fc004bc; +Cache_Enable_L2_Cache_PreLock = 0x4fc004c0; +Cache_Disable_L2_Cache_PreLock = 0x4fc004c4; +Cache_Lock_Addr = 0x4fc004c8; +Cache_Unlock_Addr = 0x4fc004cc; +Cache_Disable_L1_CORE0_ICache = 0x4fc004d0; +Cache_Enable_L1_CORE0_ICache = 0x4fc004d4; +Cache_Suspend_L1_CORE0_ICache = 0x4fc004d8; +Cache_Resume_L1_CORE0_ICache = 0x4fc004dc; +Cache_Disable_L1_CORE1_ICache = 0x4fc004e0; +Cache_Enable_L1_CORE1_ICache = 0x4fc004e4; +Cache_Suspend_L1_CORE1_ICache = 0x4fc004e8; +Cache_Resume_L1_CORE1_ICache = 0x4fc004ec; +Cache_Disable_L1_DCache = 0x4fc004f0; +Cache_Enable_L1_DCache = 0x4fc004f4; +Cache_Suspend_L1_DCache = 0x4fc004f8; +Cache_Resume_L1_DCache = 0x4fc004fc; +Cache_Disable_L2_Cache = 0x4fc00500; +Cache_Enable_L2_Cache = 0x4fc00504; +Cache_Suspend_L2_Cache = 0x4fc00508; +Cache_Resume_L2_Cache = 0x4fc0050c; +Cache_FLASH_MMU_Init = 0x4fc00510; +Cache_PSRAM_MMU_Init = 0x4fc00514; +Cache_FLASH_MMU_Set = 0x4fc00518; +Cache_FLASH_MMU_Set_Secure = 0x4fc0051c; +Cache_PSRAM_MMU_Set = 0x4fc00520; +Cache_PSRAM_MMU_Set_Secure = 0x4fc00524; +Cache_Count_Flash_Pages = 0x4fc00528; +Cache_Flash_To_SPIRAM_Copy = 0x4fc0052c; +Cache_Travel_Tag_Memory = 0x4fc00530; +Cache_Travel_Tag_Memory2 = 0x4fc00534; +Cache_Get_Virtual_Addr = 0x4fc00538; +Cache_Set_IDROM_MMU_Size = 0x4fc0053c; +flash2spiram_instruction_offset = 0x4fc00540; +flash2spiram_rodata_offset = 0x4fc00544; +flash_instr_rodata_start_page = 0x4fc00548; +flash_instr_rodata_end_page = 0x4fc0054c; +Cache_Set_IDROM_MMU_Info = 0x4fc00550; +Cache_Get_IROM_MMU_End = 0x4fc00554; +Cache_Get_DROM_MMU_End = 0x4fc00558; +/* Data (.data, .bss, .rodata) */ +rom_cache_op_cb = 0x4ff3ffdc; +rom_cache_internal_table_ptr = 0x4ff3ffd8; + + +/*************************************** + Group clock + ***************************************/ + +/* Functions */ +ets_clk_get_xtal_freq = 0x4fc0055c; +ets_clk_get_cpu_freq = 0x4fc00560; + + +/*************************************** + Group gpio + ***************************************/ + +/* Functions */ +gpio_set_output_level = 0x4fc00564; +gpio_get_input_level = 0x4fc00568; +gpio_matrix_in = 0x4fc0056c; +gpio_matrix_out = 0x4fc00570; +gpio_bypass_matrix_in = 0x4fc00574; +gpio_output_disable = 0x4fc00578; +gpio_output_enable = 0x4fc0057c; +gpio_pad_input_disable = 0x4fc00580; +gpio_pad_input_enable = 0x4fc00584; +gpio_pad_pulldown = 0x4fc00588; +gpio_pad_pullup = 0x4fc0058c; +gpio_pad_select_gpio = 0x4fc00590; +gpio_pad_set_drv = 0x4fc00594; +gpio_pad_unhold = 0x4fc00598; +gpio_pad_hold = 0x4fc0059c; +gpio_lppad_select_mux = 0x4fc005a0; +gpio_ded_pad_set_drv = 0x4fc005a4; +gpio_ded_pad_pullup = 0x4fc005a8; +gpio_ded_pad_pulldown = 0x4fc005ac; +gpio_ded_pad_hold = 0x4fc005b0; +gpio_ded_pad_unhold = 0x4fc005b4; + + +/*************************************** + Group interrupts + ***************************************/ + +/* Functions */ +esprv_intc_int_set_priority = 0x4fc005b8; +esprv_intc_int_set_threshold = 0x4fc005bc; +esprv_intc_int_enable = 0x4fc005c0; +esprv_intc_int_disable = 0x4fc005c4; +esprv_intc_int_set_type = 0x4fc005c8; +PROVIDE( intr_handler_set = 0x4fc005cc ); +intr_matrix_set = 0x4fc005d0; +ets_intr_lock = 0x4fc005d4; +ets_intr_unlock = 0x4fc005d8; +ets_isr_attach = 0x4fc005dc; +ets_isr_mask = 0x4fc005e0; +ets_isr_unmask = 0x4fc005e4; + + +/*************************************** + Group crypto + ***************************************/ + +/* Functions */ +md5_vector = 0x4fc005e8; +MD5Init = 0x4fc005ec; +MD5Update = 0x4fc005f0; +MD5Final = 0x4fc005f4; +crc32_le = 0x4fc005f8; +crc16_le = 0x4fc005fc; +crc8_le = 0x4fc00600; +crc32_be = 0x4fc00604; +crc16_be = 0x4fc00608; +crc8_be = 0x4fc0060c; +esp_crc8 = 0x4fc00610; +ets_sha_enable = 0x4fc00614; +ets_sha_disable = 0x4fc00618; +ets_sha_get_state = 0x4fc0061c; +ets_sha_init = 0x4fc00620; +ets_sha_process = 0x4fc00624; +ets_sha_starts = 0x4fc00628; +ets_sha_update = 0x4fc0062c; +ets_sha_finish = 0x4fc00630; +ets_sha_clone = 0x4fc00634; +ets_hmac_enable = 0x4fc00638; +ets_hmac_disable = 0x4fc0063c; +ets_hmac_calculate_message = 0x4fc00640; +ets_hmac_calculate_downstream = 0x4fc00644; +ets_hmac_invalidate_downstream = 0x4fc00648; +ets_jtag_enable_temporarily = 0x4fc0064c; +ets_aes_enable = 0x4fc00650; +ets_aes_disable = 0x4fc00654; +ets_aes_setkey = 0x4fc00658; +ets_aes_block = 0x4fc0065c; +ets_aes_setkey_dec = 0x4fc00660; +ets_aes_setkey_enc = 0x4fc00664; +ets_bigint_enable = 0x4fc00668; +ets_bigint_disable = 0x4fc0066c; +ets_bigint_multiply = 0x4fc00670; +ets_bigint_modmult = 0x4fc00674; +ets_bigint_modexp = 0x4fc00678; +ets_bigint_wait_finish = 0x4fc0067c; +ets_bigint_getz = 0x4fc00680; +ets_ds_enable = 0x4fc00684; +ets_ds_disable = 0x4fc00688; +ets_ds_start_sign = 0x4fc0068c; +ets_ds_is_busy = 0x4fc00690; +ets_ds_finish_sign = 0x4fc00694; +ets_ds_encrypt_params = 0x4fc00698; +ets_mgf1_sha256 = 0x4fc0069c; +/* Data (.data, .bss, .rodata) */ +crc32_le_table_ptr = 0x4fc1fff8; +crc16_le_table_ptr = 0x4fc1fff4; +crc8_le_table_ptr = 0x4fc1fff0; +crc32_be_table_ptr = 0x4fc1ffec; +crc16_be_table_ptr = 0x4fc1ffe8; +crc8_be_table_ptr = 0x4fc1ffe4; + + +/*************************************** + Group efuse + ***************************************/ + +/* Functions */ +ets_efuse_read = 0x4fc006a0; +ets_efuse_program = 0x4fc006a4; +ets_efuse_clear_program_registers = 0x4fc006a8; +ets_efuse_write_key = 0x4fc006ac; +ets_efuse_get_read_register_address = 0x4fc006b0; +ets_efuse_get_key_purpose = 0x4fc006b4; +ets_efuse_key_block_unused = 0x4fc006b8; +ets_efuse_find_unused_key_block = 0x4fc006bc; +ets_efuse_rs_calculate = 0x4fc006c0; +ets_efuse_count_unused_key_blocks = 0x4fc006c4; +ets_efuse_secure_boot_enabled = 0x4fc006c8; +ets_efuse_secure_boot_aggressive_revoke_enabled = 0x4fc006cc; +ets_efuse_cache_encryption_enabled = 0x4fc006d0; +ets_efuse_download_modes_disabled = 0x4fc006d4; +ets_efuse_find_purpose = 0x4fc006d8; +ets_efuse_force_send_resume = 0x4fc006dc; +ets_efuse_get_flash_delay_us = 0x4fc006e0; +ets_efuse_get_uart_print_control = 0x4fc006e4; +ets_efuse_direct_boot_mode_disabled = 0x4fc006e8; +ets_efuse_security_download_modes_enabled = 0x4fc006ec; +ets_efuse_jtag_disabled = 0x4fc006f0; +ets_efuse_usb_print_is_disabled = 0x4fc006f4; +ets_efuse_usb_download_mode_disabled = 0x4fc006f8; +ets_efuse_usb_device_disabled = 0x4fc006fc; +ets_efuse_get_km_huk_gen_state = 0x4fc00700; +ets_efuse_get_km_deploy_only_once = 0x4fc00704; +ets_efuse_get_force_use_km_key = 0x4fc00708; +ets_efuse_xts_key_length_256 = 0x4fc0070c; +ets_efuse_get_km_key_lock = 0x4fc00710; + + +/*************************************** + Group key_mgr + ***************************************/ + +/* Functions */ +esp_rom_check_recover_key = 0x4fc00714; +esp_rom_km_huk_conf = 0x4fc00718; +esp_rom_km_huk_risk = 0x4fc0071c; + + +/*************************************** + Group secureboot + ***************************************/ + +/* Functions */ +ets_emsa_pss_verify = 0x4fc00720; +ets_rsa_pss_verify = 0x4fc00724; +ets_ecdsa_verify = 0x4fc00728; +ets_secure_boot_verify_bootloader_with_keys = 0x4fc0072c; +ets_secure_boot_verify_signature = 0x4fc00730; +ets_secure_boot_read_key_digests = 0x4fc00734; +ets_secure_boot_revoke_public_key_digest = 0x4fc00738; + + +/*************************************** + Group usb_device_uart + ***************************************/ + +/* Functions */ +usb_serial_device_rx_one_char = 0x4fc008b0; +usb_serial_device_rx_one_char_block = 0x4fc008b4; +usb_serial_device_tx_flush = 0x4fc008b8; +usb_serial_device_tx_one_char = 0x4fc008bc; + + +/*************************************** + Group usb_dwcotg_uart + ***************************************/ + +/* Functions */ +Uart_Init_USB = 0x4fc008c0; +usb_serial_otg_rx_one_char = 0x4fc008c4; +usb_serial_otg_rx_one_char_block = 0x4fc008c8; +usb_serial_otg_tx_flush = 0x4fc008cc; +usb_serial_otg_tx_one_char = 0x4fc008d0; +/* Data (.data, .bss, .rodata) */ +uart_acm_dev = 0x4ff3ffd4; + + +/*************************************** + Group usb_dwcotg_module + ***************************************/ + +/* Functions */ +cdc_acm_class_handle_req = 0x4fc008d4; +cdc_acm_init = 0x4fc008d8; +cdc_acm_fifo_fill = 0x4fc008dc; +cdc_acm_rx_fifo_cnt = 0x4fc008e0; +cdc_acm_fifo_read = 0x4fc008e4; +cdc_acm_irq_tx_enable = 0x4fc008e8; +cdc_acm_irq_tx_disable = 0x4fc008ec; +cdc_acm_irq_state_enable = 0x4fc008f0; +cdc_acm_irq_state_disable = 0x4fc008f4; +cdc_acm_irq_tx_ready = 0x4fc008f8; +cdc_acm_irq_rx_enable = 0x4fc008fc; +cdc_acm_irq_rx_disable = 0x4fc00900; +cdc_acm_irq_rx_ready = 0x4fc00904; +cdc_acm_irq_is_pending = 0x4fc00908; +cdc_acm_irq_callback_set = 0x4fc0090c; +cdc_acm_line_ctrl_set = 0x4fc00910; +cdc_acm_line_ctrl_get = 0x4fc00914; +cdc_acm_poll_out = 0x4fc00918; +chip_usb_dw_did_persist = 0x4fc0091c; +chip_usb_dw_init = 0x4fc00920; +chip_usb_detach = 0x4fc00924; +chip_usb_dw_prepare_persist = 0x4fc00928; +chip_usb_get_persist_flags = 0x4fc0092c; +chip_usb_set_persist_flags = 0x4fc00930; +cpio_start = 0x4fc00934; +cpio_feed = 0x4fc00938; +cpio_done = 0x4fc0093c; +cpio_destroy = 0x4fc00940; +dfu_flash_init = 0x4fc00944; +dfu_flash_erase = 0x4fc00948; +dfu_flash_program = 0x4fc0094c; +dfu_flash_read = 0x4fc00950; +dfu_flash_attach = 0x4fc00954; +dfu_cpio_callback = 0x4fc00958; +dfu_updater_get_err = 0x4fc0095c; +dfu_updater_clear_err = 0x4fc00960; +dfu_updater_enable = 0x4fc00964; +dfu_updater_begin = 0x4fc00968; +dfu_updater_feed = 0x4fc0096c; +dfu_updater_end = 0x4fc00970; +dfu_updater_set_raw_addr = 0x4fc00974; +dfu_updater_flash_read = 0x4fc00978; +usb_dc_prepare_persist = 0x4fc0097c; +usb_dw_isr_handler = 0x4fc00980; +usb_dc_attach = 0x4fc00984; +usb_dc_detach = 0x4fc00988; +usb_dc_reset = 0x4fc0098c; +usb_dc_set_address = 0x4fc00990; +usb_dc_ep_check_cap = 0x4fc00994; +usb_dc_ep_configure = 0x4fc00998; +usb_dc_ep_set_stall = 0x4fc0099c; +usb_dc_ep_clear_stall = 0x4fc009a0; +usb_dc_ep_halt = 0x4fc009a4; +usb_dc_ep_is_stalled = 0x4fc009a8; +usb_dc_ep_enable = 0x4fc009ac; +usb_dc_ep_disable = 0x4fc009b0; +usb_dc_ep_flush = 0x4fc009b4; +usb_dc_ep_write_would_block = 0x4fc009b8; +usb_dc_ep_write = 0x4fc009bc; +usb_dc_ep_read_wait = 0x4fc009c0; +usb_dc_ep_read_continue = 0x4fc009c4; +usb_dc_ep_read = 0x4fc009c8; +usb_dc_ep_set_callback = 0x4fc009cc; +usb_dc_set_status_callback = 0x4fc009d0; +usb_dc_ep_mps = 0x4fc009d4; +usb_dc_check_poll_for_interrupts = 0x4fc009d8; +mac_addr_to_serial_str_desc = 0x4fc009dc; +usb_set_current_descriptor = 0x4fc009e0; +usb_get_descriptor = 0x4fc009e4; +usb_dev_resume = 0x4fc009e8; +usb_dev_get_configuration = 0x4fc009ec; +usb_set_config = 0x4fc009f0; +usb_deconfig = 0x4fc009f4; +usb_enable = 0x4fc009f8; +usb_disable = 0x4fc009fc; +usb_write_would_block = 0x4fc00a00; +usb_write = 0x4fc00a04; +usb_read = 0x4fc00a08; +usb_ep_set_stall = 0x4fc00a0c; +usb_ep_clear_stall = 0x4fc00a10; +usb_ep_read_wait = 0x4fc00a14; +usb_ep_read_continue = 0x4fc00a18; +usb_transfer_ep_callback = 0x4fc00a1c; +usb_transfer = 0x4fc00a20; +usb_cancel_transfer = 0x4fc00a24; +usb_transfer_sync = 0x4fc00a28; +usb_dfu_set_detach_cb = 0x4fc00a2c; +dfu_class_handle_req = 0x4fc00a30; +dfu_status_cb = 0x4fc00a34; +dfu_custom_handle_req = 0x4fc00a38; +usb_dfu_init = 0x4fc00a3c; +usb_dfu_force_detach = 0x4fc00a40; +usb_dev_deinit = 0x4fc00a44; +usb_dw_ctrl_deinit = 0x4fc00a48; +/* Data (.data, .bss, .rodata) */ +s_usb_osglue = 0x4ff3ffc8; diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,20 +1,3 @@ -/* - * Copyright (c) 2016 Cesanta Software Limited - * All rights reserved - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - /* Note: stub is deliberately loaded close to the very top of available RAM, to reduce change of colliding with anything else... */ diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32c3.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32c3.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32c3.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32c3.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40380000, len = 0x4000 dram : org = 0x3FC84000, len = 0x18000 diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32c6.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32c6.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32c6.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32c6.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,20 +1,3 @@ -/* - * Copyright (c) 2022 Espressif Systems (Shanghai) PTE LTD - * All rights reserved - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - MEMORY { iram : org = 0x40800000, len = 0x4000 dram : org = 0x40840000, len = 0x18000 diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32c6_beta.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32c6_beta.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32c6_beta.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32c6_beta.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40380000, len = 0x4000 dram : org = 0x3FC84000, len = 0x18000 diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32h2.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32h2.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32h2.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32h2.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40800000, len = 0x4000 dram : org = 0x40830000, len = 0x18000 diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32h2_beta_1.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32h2_beta_1.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32h2_beta_1.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32h2_beta_1.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40380000, len = 0x4000 dram : org = 0x3FC84000, len = 0x18000 diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32h2_beta_2.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32h2_beta_2.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32h2_beta_2.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32h2_beta_2.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40380000, len = 0x4000 dram : org = 0x3FC84000, len = 0x18000 diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32p4.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32p4.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32p4.ld 1970-01-01 00:00:00.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32p4.ld 2023-12-13 11:05:18.000000000 +0000 @@ -0,0 +1,26 @@ +MEMORY { + iram : org = 0x4FF10000, len = 0x4000 + dram : org = 0x4FF50000, len = 0x18000 +} + +ENTRY(stub_main) + +SECTIONS { + .text : ALIGN(4) { + *(.literal) + *(.text .text.*) + } > iram + + .bss : ALIGN(4) { + _bss_start = ABSOLUTE(.); + *(.bss) + _bss_end = ABSOLUTE(.); + } > dram + + .data : ALIGN(4) { + *(.data) + *(.rodata .rodata.*) + } > dram +} + +INCLUDE "rom_32p4.ld" diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32s2.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32s2.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32s2.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32s2.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40028000, len = 0x18000 dram : org = 0x3FFD0000, len = 0x28000 diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32s3.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32s3.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32s3.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32s3.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40378000, len = 0x18000 dram : org = 0x3FCA0000, len = 0x28000 diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_32s3_beta_2.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_32s3_beta_2.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_32s3_beta_2.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_32s3_beta_2.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40378000, len = 0x18000 dram : org = 0x3FCA0000, len = 0x28000 diff -Nru esptool-4.6.2+dfsg/flasher_stub/ld/stub_8266.ld esptool-4.7.0+dfsg/flasher_stub/ld/stub_8266.ld --- esptool-4.6.2+dfsg/flasher_stub/ld/stub_8266.ld 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/ld/stub_8266.ld 2023-12-13 11:05:18.000000000 +0000 @@ -1,20 +1,3 @@ -/* - * Copyright (c) 2016 Cesanta Software Limited - * All rights reserved - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - /* Note: stub is deliberately loaded close to the very top of available RAM, to reduce change of colliding with anything else... */ diff -Nru esptool-4.6.2+dfsg/flasher_stub/stub_commands.c esptool-4.7.0+dfsg/flasher_stub/stub_commands.c --- esptool-4.6.2+dfsg/flasher_stub/stub_commands.c 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/stub_commands.c 2023-12-13 11:05:18.000000000 +0000 @@ -49,7 +49,7 @@ while (len > 0 && (addr % FLASH_BLOCK_SIZE != 0)) { #if defined(ESP32S3) && !defined(ESP32S3BETA2) - if (ets_efuse_flash_octal_mode()) { + if (large_flash_mode) { if (esp_rom_opiflash_erase_sector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35; } else { if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35; @@ -63,7 +63,7 @@ while (len > FLASH_BLOCK_SIZE) { #if defined(ESP32S3) && !defined(ESP32S3BETA2) - if (ets_efuse_flash_octal_mode()) { + if (large_flash_mode) { if (esp_rom_opiflash_erase_block_64k(addr / FLASH_BLOCK_SIZE) != 0) return 0x36; } else { if (SPIEraseBlock(addr / FLASH_BLOCK_SIZE) != 0) return 0x36; @@ -77,7 +77,7 @@ while (len > 0) { #if defined(ESP32S3) && !defined(ESP32S3BETA2) - if (ets_efuse_flash_octal_mode()) { + if (large_flash_mode) { if (esp_rom_opiflash_erase_sector(addr / FLASH_SECTOR_SIZE) != 0) return 0x37; } else { if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x37; @@ -112,7 +112,7 @@ uint32_t n = len - num_sent; if (n > block_size) n = block_size; #if defined(ESP32S3) && !defined(ESP32S3BETA2) - if (ets_efuse_flash_octal_mode()) { + if (large_flash_mode) { res = SPIRead4B(1, addr, buf, n); } else { res = SPIRead(addr, (uint32_t *)buf, n); @@ -152,7 +152,7 @@ n = FLASH_SECTOR_SIZE; } #if defined(ESP32S3) && !defined(ESP32S3BETA2) - if (ets_efuse_flash_octal_mode()) { + if (large_flash_mode) { res = SPIRead4B(1, addr, buf, n); } else { res = SPIRead(addr, (uint32_t *)buf, n); @@ -186,6 +186,16 @@ see https://github.com/themadinventor/esptool/issues/98 */ SelectSpiFunction(); #else + /* Stub calls spi_flash_attach automatically when it boots, + therefore, we need to "unattach" the flash before attaching again + with different configuration to avoid issues. */ + + // Configure the SPI flash pins back as classic GPIOs + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICLK_U, FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIQ_U, FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPID_U, FUNC_GPIO); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICS0_U, FUNC_GPIO); + /* spi_flash_attach calls SelectSpiFunction() and another function to initialise SPI flash interface. @@ -254,7 +264,14 @@ uint8_t buf[SECURITY_INFO_BYTES]; esp_command_error ret; + #ifdef ESP32C3 + if (_rom_eco_version >= 7) + ret = GetSecurityInfoProcNewEco(NULL, NULL, buf); + else + ret = GetSecurityInfoProc(NULL, NULL, buf); + #else ret = GetSecurityInfoProc(NULL, NULL, buf); + #endif // ESP32C3 if (ret == ESP_OK) SLIP_send_frame_data_buf(buf, sizeof(buf)); return ret; diff -Nru esptool-4.6.2+dfsg/flasher_stub/stub_flasher.c esptool-4.7.0+dfsg/flasher_stub/stub_flasher.c --- esptool-4.6.2+dfsg/flasher_stub/stub_flasher.c 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/stub_flasher.c 2023-12-13 11:05:18.000000000 +0000 @@ -123,6 +123,26 @@ } #endif // WITH_USB_JTAG_SERIAL +#if ESP32S3 && !ESP32S3BETA2 +bool large_flash_mode = false; + +bool flash_larger_than_16mb() +{ + uint32_t flash_id; + esp_rom_opiflash_exec_cmd(1, SPI_FLASH_FASTRD_MODE, + CMD_RDID, 8, + 0, 0, + 0, + NULL, 0, + (uint8_t *)&flash_id, 24, + ESP_ROM_OPIFLASH_SEL_CS0, + false); + + uint8_t flid_lowbyte = (flash_id >> 16) & 0xFF; + return ((flid_lowbyte >= 0x19 && flid_lowbyte < 0x30) || (flid_lowbyte >= 0x39)); // See DETECTED_FLASH_SIZES in esptool +} +#endif // ESP32S3 + static void stub_handle_rx_byte(char byte) { int16_t r = SLIP_recv_byte(byte, (slip_state_t *)&ub.state); @@ -446,65 +466,72 @@ { const uint32_t greeting = 0x4941484f; /* OHAI */ - /* this points to stub_main now, clear for next boot */ + /* This points to stub_main now, clear for next boot. */ ets_set_user_start(0); + /* Increase CPU frequency and flashing speed if supported. */ #if USE_MAX_CPU_FREQ set_max_cpu_freq(); #endif // USE_MAX_CPU_FREQ + /* Disable all watchdogs to prevent the chip from resetting during longer operations. */ #if WITH_USB_JTAG_SERIAL disable_watchdogs(); #endif // WITH_USB_JTAG_SERIAL - /* zero bss */ + /* Zero the bss region. */ for(uint32_t *p = &_bss_start; p < &_bss_end; p++) { *p = 0; } + /* Send the OHAI greeting, stub will be reported as running. */ SLIP_send(&greeting, 4); + /* Configure the interrupts for receiving data from esptool on the host. */ ub.reading_buf = ub.buf_a; stub_io_init(&stub_handle_rx_byte); /* Configure default SPI flash functionality. Can be overriden later by esptool.py. */ -#ifdef ESP8266 - SelectSpiFunction(); + #ifdef ESP8266 + SelectSpiFunction(); + spi_flash_attach(); + #else + #if SUPPORT_CONFIG_SPI + uint32_t spiconfig = ets_efuse_get_spiconfig(); + #else + uint32_t spiconfig = 0; + #endif // SUPPORT_CONFIG_SPI + uint32_t strapping = READ_REG(GPIO_STRAP_REG); + /* If GPIO1 (U0TXD) is pulled low and no other boot mode is + set in efuse, assume HSPI flash mode (same as normal boot) + */ + if (spiconfig == 0 && (strapping & 0x1c) == 0x08) { + spiconfig = 1; /* HSPI flash mode */ + } + spi_flash_attach(spiconfig, 0); + #endif // ESP8266 - spi_flash_attach(); -#else -#if !ESP32C2 && !ESP32C6 && !ESP32H2 - uint32_t spiconfig = ets_efuse_get_spiconfig(); -#else - // ESP32C2/ESP32C6 doesn't support get spiconfig. - uint32_t spiconfig = 0; -#endif - uint32_t strapping = READ_REG(GPIO_STRAP_REG); - /* If GPIO1 (U0TXD) is pulled low and no other boot mode is - set in efuse, assume HSPI flash mode (same as normal boot) - */ - if (spiconfig == 0 && (strapping & 0x1c) == 0x08) { - spiconfig = 1; /* HSPI flash mode */ - } - spi_flash_attach(spiconfig, 0); -#endif -#if ESP32S3 && !ESP32S3BETA2 - // Initialize OPI flash driver only when flash is detected octal. Otherwise, we don't need to - // initialize such a driver - if (ets_efuse_flash_octal_mode()) { - static const esp_rom_opiflash_def_t flash_driver = OPIFLASH_DRIVER(); - esp_rom_opiflash_legacy_driver_init(&flash_driver); - esp_rom_opiflash_wait_idle(); - } -#endif //ESP32S3 && !ESP32S3BETA2 - SPIParamCfg(0, FLASH_MAX_SIZE, FLASH_BLOCK_SIZE, FLASH_SECTOR_SIZE, - FLASH_PAGE_SIZE, FLASH_STATUS_MASK); + /* Initialize the OPI flash driver if supported. */ + #if ESP32S3 && !ESP32S3BETA2 + large_flash_mode = ets_efuse_flash_octal_mode() || flash_larger_than_16mb(); + + // Initialize OPI flash driver only when flash is detected octal or quad larger than 16MB. + // Otherwise, we don't need to initialize such a driver + if (large_flash_mode) { + static const esp_rom_opiflash_def_t flash_driver = OPIFLASH_DRIVER(); + esp_rom_opiflash_legacy_driver_init(&flash_driver); + esp_rom_opiflash_wait_idle(); + } + #endif //ESP32S3 && !ESP32S3BETA2 + SPIParamCfg(0, FLASH_MAX_SIZE, FLASH_BLOCK_SIZE, FLASH_SECTOR_SIZE, + FLASH_PAGE_SIZE, FLASH_STATUS_MASK); + /* Configurations are done, now run the loop to receive and handle commands. */ cmd_loop(); - /* if cmd_loop returns, it's due to ESP_RUN_USER_CODE command. */ - + /* If cmd_loop returns, it's due to ESP_RUN_USER_CODE command. */ + /* Decrease CPU frequency back to the saved value before the stub flasher returns. */ #if USE_MAX_CPU_FREQ reset_cpu_freq(); #endif // USE_MAX_CPU_FREQ diff -Nru esptool-4.6.2+dfsg/flasher_stub/stub_io.c esptool-4.7.0+dfsg/flasher_stub/stub_io.c --- esptool-4.6.2+dfsg/flasher_stub/stub_io.c 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/stub_io.c 2023-12-13 11:05:18.000000000 +0000 @@ -71,7 +71,7 @@ WRITE_REG(INTERRUPT_CORE0_USB_DEVICE_INT_MAP_REG, ETS_USB_INUM); #endif // IS_RISCV ets_isr_attach(ETS_USB_INUM, jtag_serial_isr, NULL); - REG_SET_MASK(USB_DEVICE_INT_ENA_REG, USB_DEVICE_SERIAL_OUT_RECV_PKT_INT_ENA); + WRITE_REG(USB_DEVICE_INT_ENA_REG, USB_DEVICE_SERIAL_OUT_RECV_PKT_INT_ENA); ets_isr_unmask(1 << ETS_USB_INUM); return; } diff -Nru esptool-4.6.2+dfsg/flasher_stub/stub_write_flash.c esptool-4.7.0+dfsg/flasher_stub/stub_write_flash.c --- esptool-4.6.2+dfsg/flasher_stub/stub_write_flash.c 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/stub_write_flash.c 2023-12-13 11:05:18.000000000 +0000 @@ -96,15 +96,7 @@ } #if ESP32_OR_LATER -#if ESP32C3 || ESP32C6BETA || ESP32C2 || ESP32C6 -static esp_rom_spiflash_chip_t *flashchip = (esp_rom_spiflash_chip_t *)0x3fcdfff4; -#elif ESP32H2BETA1 || ESP32H2BETA2 -static esp_rom_spiflash_chip_t *flashchip = (esp_rom_spiflash_chip_t *)0x3fcdfff0; -#elif ESP32H2 -static esp_rom_spiflash_chip_t *flashchip = (esp_rom_spiflash_chip_t *)0x4084fff0; -#else -static esp_rom_spiflash_chip_t *flashchip = (esp_rom_spiflash_chip_t *)0x3ffae270; -#endif +static esp_rom_spiflash_chip_t *flashchip = (esp_rom_spiflash_chip_t *)ROM_SPIFLASH_LEGACY; /* Stub version of SPIUnlock() that replaces version in ROM. @@ -126,7 +118,7 @@ if (SPI_read_status_high(&status) != SPI_FLASH_RESULT_OK) { return SPI_FLASH_RESULT_ERR; } -#endif +#endif // ESP32S2_OR_LATER /* Clear all bits except QIE, if it is set. (This is different from ROM SPIUnlock, which keeps all bits as-is.) @@ -142,7 +134,7 @@ return SPI_FLASH_RESULT_OK; } -#endif +#endif // ESP32_OR_LATER #if defined(ESP32S3) && !defined(ESP32S3BETA2) static esp_rom_spiflash_result_t page_program_internal(int spi_num, uint32_t spi_addr, uint8_t* addr_source, uint32_t byte_length) @@ -203,7 +195,7 @@ esp_rom_opiflash_wait_idle(); return ESP_ROM_SPIFLASH_RESULT_OK; } -#endif // ESP32S3 +#endif // defined(ESP32S3) && !defined(ESP32S3BETA2) esp_command_error handle_flash_begin(uint32_t total_size, uint32_t offset) { fs.in_flash_mode = true; @@ -214,7 +206,7 @@ fs.last_error = ESP_OK; #if defined(ESP32S3) && !defined(ESP32S3BETA2) - if (ets_efuse_flash_octal_mode()) { + if (large_flash_mode) { esp_rom_opiflash_wait_idle(); } else { if (SPIUnlock() != 0) { @@ -266,7 +258,7 @@ spi_write_enable(); spi_wait_ready(); #if defined(ESP32S3) && !defined(ESP32S3BETA2) - if (ets_efuse_flash_octal_mode()) { + if (large_flash_mode) { if (block_erase) { if (fs.next_erase_sector * FLASH_SECTOR_SIZE < (1 << 24)) { esp_rom_opiflash_wait_idle(); @@ -354,14 +346,14 @@ /* do the actual write */ #if defined(ESP32S3) && !defined(ESP32S3BETA2) - if (ets_efuse_flash_octal_mode()) { + if (large_flash_mode){ res = SPIWrite4B(1, fs.next_write, data_buf, length); } else { res = SPIWrite(fs.next_write, data_buf, length); } #else res = SPIWrite(fs.next_write, data_buf, length); - #endif // ESP32S3 + #endif // defined(ESP32S3) && !defined(ESP32S3BETA2) if (res != 0) fs.last_error = ESP_FAILED_SPI_OP; fs.next_write += length; diff -Nru esptool-4.6.2+dfsg/flasher_stub/wrap_stub.py esptool-4.7.0+dfsg/flasher_stub/wrap_stub.py --- esptool-4.6.2+dfsg/flasher_stub/wrap_stub.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/flasher_stub/wrap_stub.py 2023-12-13 11:05:18.000000000 +0000 @@ -39,6 +39,10 @@ except ValueError: pass + for s in e.nobits_sections: + if s.name == ".bss": + stub["bss_start"] = s.addr + # Pad text with NOPs to mod 4. if len(stub["text"]) % 4 != 0: stub["text"] += (4 - (len(stub["text"]) % 4)) * "\0" diff -Nru esptool-4.6.2+dfsg/setup.py esptool-4.7.0+dfsg/setup.py --- esptool-4.6.2+dfsg/setup.py 2023-06-12 12:16:14.000000000 +0000 +++ esptool-4.7.0+dfsg/setup.py 2023-12-13 11:05:18.000000000 +0000 @@ -16,7 +16,7 @@ "Please see the installation section in the esptool documentation" " for instructions on how to install it." ) - exit(1) + sys.exit(1) # Example code to pull version from esptool module with regex, taken from @@ -101,6 +101,8 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ], python_requires=">=3.7", setup_requires=(["wheel"] if "bdist_wheel" in sys.argv else []), @@ -115,6 +117,8 @@ "pre-commit", "pytest", "pytest-rerunfailures", + "requests", + "commitizen", ], "hsm": [ "python-pkcs11", @@ -127,6 +131,7 @@ "pyserial>=3.0", "reedsolo>=1.5.3,<1.8", "PyYAML>=5.1", + "intelhex", ], packages=find_packages(), include_package_data=True,