From 1c3c37b7bf4b413aea4cf23f219e229e380fc390 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 4 Nov 2023 23:12:48 +0100 Subject: [PATCH] Master (#8) * docs: espsecure remote signing using a HSM broken link fix * fix(rfc2217_server): Use new reset sequences * fix(ESP32-S3): Lower CPU freq to improve flasher stub stability Closes https://github.com/espressif/esptool/issues/832 * fix: Unknown chip (ID or magic number) error * pyinstaller: fix glibc dependency on gnu/linux pyinstaller package for linux is built within the ubuntu-latest image in github workflow. This may cause prbolem with glibc symbol versions on older distributions, where the new symbol versions are not available. Fix this by building on the older ubuntu version. Closes https://github.com/espressif/esptool/issues/843 Signed-off-by: Frantisek Hrbata * tests: Create custom `host_test` marker for tests without real chip connected Closes https://github.com/espressif/esptool/issues/838 * fix(ESP32-S3): Temporarily disable increasing CPU freq Related to https://github.com/espressif/esptool/issues/848 Related to https://github.com/espressif/esptool/issues/842 * build: add esp_rfc2217_server to published scripts Closes https://github.com/espressif/esptool/issues/846 * Update version to v4.5.1 * Update version to v4.6-dev * espefuse: Hide sensitive info by default during burning burn_key and burn_key_digest Adds --show-sensitive-info flag for two commands: burn_key and burn_key_digest. * flasher_stub: pass -mabi=ilp32 to the RISC-V compiler This is a no-op change for the upstream toolchain (compiled stubs are binary identical), but is required when building with Debian's riscv64-unknown-elf-gcc compiler. * flasher_stub: allow passing extra CFLAGS The flasher_stub Makefile allows for some system-local configuration, either through local.mk, or through environment variables. For example, the compiler prefix can be overridden, by defining e.g. CROSS_ESPRISCV32. However, passing additional flags to the compiler isn't possible right now. Add EXTRA_CFLAGS and EXTRA_CFLAGS_ESPRISCV32 to allow for that option. * flasher_stub: collect all targets at the top, DRY * flasher_stub: make target selection more modular Rather than a special "make esp32", create WITHOUT_* variables to selectively disable chip families. Currently, WITHOUT_ESP8266, WITHOUT_ESP32_XTENSA and WITHOUT_ESP32_RISCV32 are defined, but the code can be easily adjusted to allow for all kinds of other sets/combinations. * flasher_stub: create %.json targets, make all a proper PHONY * flasher_stub: drop --embed from wrap_stub.py Since commit 94f29a5 the flasher stub is not embedded in the Python source, but rather included as simple json files. As such, wrap_stub.py --embed was converted to basically just vary the build dir. Rather than keep this indirection and for better clarity, remove that piece of code and replace it by a simple "cp" in the Makefile. While at it, replace the target name from "embed" to "install", as this more akin to a "make install" step. * espefuse: Support burning ECDSA_KEY from pem file - fix some assert check in test_espefuse.py - add tests to cover the new functionality * espefuse(c2): Fix BLOCK_KEY0 view for summary cmd when SB + FE keys are burnt For C2 secure boot + flash enc block, we saw that in summary cmd "0's" from secure boot digest part (upper 128 bit) were translated into "?'s" when the block was read protected. For C2, we should apply this translation for lower 128 bits only. * fix(ESP32-C6): Fix get_pkg_version and get_{major,minor}_chip_version * image_info: removed check that reserved bytes in image header are zero IDF may start using parts of the reserved bytes in the extended header at any time, which will break chip auto-detect in image_info. * build: limit max cryptography version to 40 * fix: Set flash parameters even with --flash_size keep Related to https://github.com/espressif/esp-idf/issues/10788 Related to https://github.com/espressif/esp-idf/issues/10959 * build: add arm and arm64 as build target Closes https://github.com/espressif/esptool/issues/845 * Fix typo in serial protocol docs Fixes misspelling of `triggered` in serial protocol docs. Signed-off-by: hasheddan * Support more recent reedsolo packages - https://github.com/tomerfiliba-org/reedsolomon/releases/tag/v1.6.1 - this seems to be related to licenses only. - https://github.com/tomerfiliba-org/reedsolomon/releases/tag/v1.7.0 - this is related to installation. Closes https://github.com/espressif/esptool/issues/872 * build(arm): add pip extra url for github action build * ci: Fix libffi symlinks for cryptography>=40 * espefuse: Prevent burning XTS_AES and ECDSA keys into BLOCK9 (BLOCK_KEY5) eFuse module has a hardware bug. It is related to ESP32-C3, C6, S3, H2 chips: - BLOCK9 (BLOCK_KEY5) can not be used by XTS_AES keys. For H2 chips, the BLOCK9 (BLOCK_KEY5) can not be used by ECDSA keys. S2 does not have such a hardware bug. * image_info: Display disabled WP pin as disabled The image formats know about the special value 0xee used to disable WP. Display this with image_info. E.g.: ESP32-C3 extended image header ============================== WP pin: 0xee (disabled) * image_info: Print chip ID's name if known Example: Flash pins drive settings: clk_drv: 0x0, q_drv: 0x0, d_drv: 0x0, cs0_drv: 0x0, hd_drv: 0x0, wp_drv: 0x0 Chip ID: 5 (ESP32-C3) Minimal chip revision: v0.0, (legacy min_rev = 0) Maximal chip revision: v655.35 An unknown ID will be printed as: Chip ID: 42 (Unknown ID) * tests: Make the testsuite Windows compatible * espefuse: Adds external esp instance Closes https://github.com/espressif/esptool/issues/873 * espefuse: Improve efuse error viewing * espefuse: Explicit setting of efuse time settings EFUSE_PWR_ON_NUM in C3 has default value = 0x2880, now = 0x3000 * docs(Boot log): Add all esp targets to cover boot troubleshooting Closes https://github.com/espressif/esptool/issues/732 * fix: USB-JTAG-Serial PID detection error * esptool: Move bootdesc on the top of the ram segment * espefuse: Move some vars under init method to speedup tool after adding yaml support * espefuse: Adds yaml efuse description files for all chip - esptool: Updates eFuses wafer major&minor versions - esptool(esp32c6): Adds package versions - espefuse(esp32c6): Replace PKG_VERSION BLK_VERSION_MINOR BLK_VERSION_MAJOR - espefuse(esp32c6): Adds adc calib efuses - espefuse: Adds yaml files for Build with PyInstaller * efuse(H2): Adds RF Calibration Information * espsecure: Improve error message for incorrect PEM format Closes https://github.com/espressif/esptool/issues/881 * bugfix(usb_jtag_serial): Autofeed super watchdog (SWD) to avoid resets during flashing * esptool: Read 64-bit MAC address on C6 and H2 * bugfix: Adjust wrapper scripts to not import themselves * bugfix(espsecure): Print a clear error message if incompatible OpenSSL backend is used Closes https://github.com/espressif/esptool/issues/878 * fix: inconsistent usage of dirs separator * feat(esptool): add option to dump whole flash based on detected size Closes https://github.com/espressif/esptool/issues/461 * Update version to v4.6 * Update version to v4.7-dev * fix(ESP32-S3): Correct RTC WDT registers to fix resets during flashing * Update version to v4.6.1 * Update version to v4.7-dev * docs: add explanation for flash_id example to avoid confusion * docs(boot-log): fix list formatting * docs: add c2, c6 and h2 as build targets * fix(compressed upload): Accept short data blocks with only Adler-32 bytes * fix(CH9102F): Suggest to install new serial drivers if writing to RAM fails * esptool & espefuse: Fix byte order in MAC (for C6 and H2) MAC: 60:55:f9:ff:fe:f7:2c:a2 (EUI64, used for IEEE802154) BASE MAC: 60:55:f9:f7:2c:a2 (used for BT) MAC_EXT: ff:fe * Update version to v4.6.2 * Update version to v4.7 * change: Add conventional precommit linter * ci(pre-commit): Update version of `conventional-precommit-linter` * feat(get_security_info): Improved the output format and added more details * fix(esp32-c2): Enable flashing in secure download mode Closes https://github.com/espressif/esptool/issues/895 * ci: Add DangerJS checks to GL and GH * feat(esptool): Add PICO package for ESP32S3 and flash/psram efuses * feat(esptool): Add tests for get_chip_features * feat(esptool): Add new packages for ESP32C3 and flash efuses * fix(expand file args): Correctly print the expanded command * feat(espsecure): Allow prompting for HSM PIN in read_hsm_config If hsm_config does not contain "credentials" the user will be prompted for the HSM PIN. This avoids the need to have HSM PINs typed in config files which is not a good security practice. ADJUNCT: Updated documentation to reflect new usage Closes https://github.com/espressif/esptool/pull/900 * fix(dangerGH): Update token permissions - allow Danger to add comments to PR * fix(elf2image): fix text/rodata mapping overlap issue on uni-idrom bus chips * fix: assert in esp32 exclusive workaround * docs: Add other resources page * fix(autodetection): Remove the ESP32-S2 ROM class from get_security_info autodetection * change(pre-commit): Bump version conventional-precommit-linter to 1.2.1 * feat(esptool): added target to esp32p4 * feat(espefuse): Add support for esp32p4 chip * fix: Fix redirection of STDOUT Closes https://github.com/espressif/esptool/issues/904 * fix(danger-github): Fir Danger GitHub token permission * ci(danger-github): Fix github-action-bot permissions for posting Danger output * ci: Shared danger to local stage (remove possible double CI pipelines) * ci: add 'flake8-import-order' as a dependecy to flake8 * fix(bin_image): Check only ELF sections when searching for .flash.appdesc Closes https://github.com/espressif/esptool/issues/917 * feat(efuse): ESP32P4 adds ecdsa_key support * feat(efuse): Update key purpose table and tests * feat(esp32-s3): Support >16MB quad flash chips Adds support for the W25Q256 and GD25Q256 flash chips. Closes https://github.com/espressif/esptool/issues/883 * ci(dev_release): Upload dev releases to PyPI with GH Actions * ci: fix pipeline for building docs * feat(merge_bin): add support for uf2 format * feat(esp32c3): Support ECO6 and ECO7 magic numbers * ci(gitlab_ci): Change only/except syntax to rules * fix(flasher_stub): fix usb-serial-jtag enabled non-related intr source * fix(loader): Could not open serial port message adjusted * ci(gitlab): Fix deploying docs to production * ci(github): Fix pyinstaller builds on ubuntu * docs(basic-commands): added note for PowerShell users for merge_bin command Closes https://github.com/espressif/esptool/issues/923 * feat: Add support for Python 3.12 * feat(loader): Added hints for some serial port issues when rising port error Closes https://github.com/espressif/esp-idf/issues/12366 * feat: add support for get_security_info on esp32c3 ECO7 * docs(troubleshooting): Explain issues when flashing with USB-Serial/JTAG or USB-OTG Closes https://github.com/espressif/esptool/issues/924 * feat(espefuse): Update the way to complete the operation * docs(boot_mode_selection): Correct secondary strapping pin boot mode levels Closes https://github.com/espressif/esptool/issues/928 * feat(espefuse): Adds efuse ADC calibration data for ESP32H2 * feat(rfc2217_server): Add hard reset sequence * feat(elf2image): add ram-only-header argument The ram-only-header configuration 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 also may not result as optimal as the standard way regarding the padding gap use among the flash segments that could result in a less fragmented binary. The image built must then handle the basic hardware initialization and the flash mapping for code execution after ROM bootloader boot it. Signed-off-by: Marek Matej Signed-off-by: Almir Okato * feat(esp32p4): Stub flasher support * refactor(stub_flasher): Cleanup, make adding new targets easier * feat: add support for intel hex format --------- Signed-off-by: Frantisek Hrbata Signed-off-by: hasheddan Signed-off-by: Marek Matej Signed-off-by: Almir Okato Co-authored-by: harshal.patil Co-authored-by: radim.karnis Co-authored-by: Frantisek Hrbata Co-authored-by: Peter Dragun Co-authored-by: KonstantinKondrashov Co-authored-by: Faidon Liambotis Co-authored-by: XiNGRZ Co-authored-by: Marius Vikhammer Co-authored-by: hasheddan Co-authored-by: Roland Dobai Co-authored-by: Trent Piepho Co-authored-by: Dean Gardiner Co-authored-by: Massimiliano Montagni Co-authored-by: Tomas Sebestik Co-authored-by: Aditya Patwardhan Co-authored-by: Richard Retanubun Co-authored-by: wuzhenghui Co-authored-by: Armando Co-authored-by: Jakub Kocka Co-authored-by: 20162026 <36726858+20162026@users.noreply.github.com> Co-authored-by: Almir Okato --- .github/pull_request_template.md | 19 +- .github/workflows/build_esptool.yml | 25 +- .github/workflows/dangerjs.yml | 22 + .../workflows/dev_release_esptool_pypi.yml | 42 ++ .github/workflows/test_esptool.yml | 23 +- .gitlab-ci.yml | 131 ++-- .pre-commit-config.yaml | 8 + CONTRIBUTING.rst | 14 +- MANIFEST.in | 1 + docs/_static/esptool_versions.js | 3 + docs/conf_common.py | 20 +- .../advanced-topics/boot-mode-selection.rst | 127 ++-- .../advanced-topics/firmware-image-format.rst | 89 ++- docs/en/advanced-topics/serial-protocol.rst | 2 +- docs/en/contributing.rst | 2 + docs/en/espefuse/burn-key-cmd.rst | 40 +- docs/en/espefuse/burn-key-digest-cmd.rst | 14 +- docs/en/espefuse/inc/summary_ESP32-C2.rst | 92 ++- docs/en/espefuse/inc/summary_ESP32-C3.rst | 228 ++++--- docs/en/espefuse/inc/summary_ESP32-C6.rst | 155 +++++ docs/en/espefuse/inc/summary_ESP32-H2.rst | 155 +++++ docs/en/espefuse/inc/summary_ESP32-P4.rst | 176 +++++ docs/en/espefuse/inc/summary_ESP32-S2.rst | 252 +++---- docs/en/espefuse/inc/summary_ESP32-S3.rst | 246 +++---- docs/en/espefuse/inc/summary_ESP32.rst | 122 ++-- docs/en/espsecure/index.rst | 12 +- docs/en/esptool/advanced-commands.rst | 4 +- docs/en/esptool/advanced-options.rst | 7 +- docs/en/esptool/basic-commands.rst | 87 ++- docs/en/esptool/flash-modes.rst | 17 +- docs/en/esptool/remote-serial-ports.rst | 2 +- docs/en/index.rst | 3 +- docs/en/resources.rst | 40 ++ docs/en/troubleshooting.rst | 13 +- docs/requirements.txt | 2 +- esp_rfc2217_server.py | 67 +- espefuse.py | 9 +- espefuse/__init__.py | 53 +- espefuse/efuse/base_fields.py | 63 +- espefuse/efuse/base_operations.py | 108 ++- .../efuse/emulate_efuse_controller_base.py | 9 +- .../efuse/esp32/emulate_efuse_controller.py | 6 +- espefuse/efuse/esp32/fields.py | 90 +-- espefuse/efuse/esp32/mem_definition.py | 188 +++--- espefuse/efuse/esp32/operations.py | 21 +- .../efuse/esp32c2/emulate_efuse_controller.py | 15 +- espefuse/efuse/esp32c2/fields.py | 114 ++-- espefuse/efuse/esp32c2/mem_definition.py | 197 +++--- espefuse/efuse/esp32c2/operations.py | 11 +- .../efuse/esp32c3/emulate_efuse_controller.py | 12 +- espefuse/efuse/esp32c3/fields.py | 106 ++- espefuse/efuse/esp32c3/mem_definition.py | 300 ++++----- espefuse/efuse/esp32c3/operations.py | 11 +- .../efuse/esp32c6/emulate_efuse_controller.py | 12 +- espefuse/efuse/esp32c6/fields.py | 167 +++-- espefuse/efuse/esp32c6/mem_definition.py | 310 +++------ espefuse/efuse/esp32c6/operations.py | 60 +- .../efuse/esp32h2/emulate_efuse_controller.py | 12 +- espefuse/efuse/esp32h2/fields.py | 168 +++-- espefuse/efuse/esp32h2/mem_definition.py | 307 +++------ espefuse/efuse/esp32h2/operations.py | 77 ++- .../esp32h2beta1/emulate_efuse_controller.py | 12 +- espefuse/efuse/esp32h2beta1/fields.py | 153 ++--- espefuse/efuse/esp32h2beta1/mem_definition.py | 254 +++---- espefuse/efuse/esp32h2beta1/operations.py | 18 +- espefuse/efuse/esp32p4/__init__.py | 3 + .../efuse/esp32p4/emulate_efuse_controller.py | 92 +++ espefuse/efuse/esp32p4/fields.py | 433 ++++++++++++ espefuse/efuse/esp32p4/mem_definition.py | 169 +++++ espefuse/efuse/esp32p4/operations.py | 391 +++++++++++ .../efuse/esp32s2/emulate_efuse_controller.py | 12 +- espefuse/efuse/esp32s2/fields.py | 96 +-- espefuse/efuse/esp32s2/mem_definition.py | 292 +++------ espefuse/efuse/esp32s2/operations.py | 11 +- .../efuse/esp32s3/emulate_efuse_controller.py | 12 +- espefuse/efuse/esp32s3/fields.py | 111 ++-- espefuse/efuse/esp32s3/mem_definition.py | 296 +++------ espefuse/efuse/esp32s3/operations.py | 11 +- .../esp32s3beta2/emulate_efuse_controller.py | 12 +- espefuse/efuse/esp32s3beta2/fields.py | 111 ++-- espefuse/efuse/esp32s3beta2/mem_definition.py | 291 +++----- espefuse/efuse/esp32s3beta2/operations.py | 11 +- espefuse/efuse/mem_definition_base.py | 132 +++- espefuse/efuse_defs/esp32.yaml | 64 ++ espefuse/efuse_defs/esp32c2.yaml | 53 ++ espefuse/efuse_defs/esp32c3.yaml | 112 ++++ espefuse/efuse_defs/esp32c6.yaml | 106 +++ espefuse/efuse_defs/esp32h2.yaml | 103 +++ espefuse/efuse_defs/esp32p4.yaml | 91 +++ espefuse/efuse_defs/esp32s2.yaml | 119 ++++ espefuse/efuse_defs/esp32s3.yaml | 134 ++++ espsecure.py | 9 +- espsecure/__init__.py | 41 +- espsecure/esp_hsm_sign/__init__.py | 9 +- esptool.py | 9 +- esptool/__init__.py | 138 +++- esptool/bin_image.py | 165 +++-- esptool/cmds.py | 260 ++++++-- esptool/loader.py | 58 +- esptool/targets/__init__.py | 2 + esptool/targets/esp32.py | 9 +- esptool/targets/esp32c2.py | 4 +- esptool/targets/esp32c3.py | 65 +- esptool/targets/esp32c6.py | 42 +- esptool/targets/esp32c6beta.py | 3 +- esptool/targets/esp32h2.py | 26 +- esptool/targets/esp32h2beta1.py | 20 +- esptool/targets/esp32p4.py | 192 ++++++ esptool/targets/esp32s2.py | 21 +- esptool/targets/esp32s3.py | 83 ++- esptool/targets/esp32s3beta2.py | 5 - esptool/targets/esp8266.py | 6 +- .../targets/stub_flasher/stub_flasher_32.json | 4 +- .../stub_flasher/stub_flasher_32c2.json | 4 +- .../stub_flasher/stub_flasher_32c3.json | 4 +- .../stub_flasher/stub_flasher_32c6.json | 4 +- .../stub_flasher/stub_flasher_32c6beta.json | 4 +- .../stub_flasher/stub_flasher_32h2.json | 4 +- .../stub_flasher/stub_flasher_32h2beta1.json | 4 +- .../stub_flasher/stub_flasher_32h2beta2.json | 4 +- .../stub_flasher/stub_flasher_32p4.json | 7 + .../stub_flasher/stub_flasher_32s2.json | 7 - .../stub_flasher/stub_flasher_32s3.json | 7 - .../stub_flasher/stub_flasher_32s3beta2.json | 7 - .../stub_flasher/stub_flasher_8266.json | 4 +- esptool/uf2_writer.py | 96 +++ esptool/util.py | 14 +- flasher_stub/Makefile | 69 +- flasher_stub/README.md | 4 +- flasher_stub/include/rom_functions.h | 4 + flasher_stub/include/soc_support.h | 67 +- flasher_stub/include/stub_flasher.h | 10 +- flasher_stub/ld/rom_32c3.ld | 2 +- flasher_stub/ld/rom_32h2.ld | 7 +- flasher_stub/ld/rom_32p4.ld | 619 ++++++++++++++++++ flasher_stub/ld/stub_32.ld | 17 - flasher_stub/ld/stub_32c3.ld | 6 - flasher_stub/ld/stub_32c6.ld | 17 - flasher_stub/ld/stub_32c6_beta.ld | 6 - flasher_stub/ld/stub_32h2.ld | 6 - flasher_stub/ld/stub_32h2_beta_1.ld | 6 - flasher_stub/ld/stub_32h2_beta_2.ld | 6 - flasher_stub/ld/stub_32p4.ld | 26 + flasher_stub/ld/stub_32s2.ld | 6 - flasher_stub/ld/stub_32s3.ld | 6 - flasher_stub/ld/stub_32s3_beta_2.ld | 6 - flasher_stub/ld/stub_8266.ld | 17 - flasher_stub/stub_commands.c | 17 +- flasher_stub/stub_flasher.c | 105 +-- flasher_stub/stub_io.c | 2 +- flasher_stub/stub_write_flash.c | 38 +- flasher_stub/wrap_stub.py | 9 +- setup.py | 10 +- test/.covconf | 6 + test/conftest.py | 12 + test/images/bootloader_esp32_v5_2.bin | Bin 0 -> 26768 bytes test/images/esp32c3_header_min_rev.bin | Bin 48 -> 48 bytes .../ram_helloworld/helloworld-esp32p4.bin | Bin 0 -> 128 bytes test/images/ram_helloworld/source/Makefile | 9 +- .../images/ram_helloworld/source/ld/app_32.ld | 17 - .../ram_helloworld/source/ld/app_32c2.ld | 7 - .../ram_helloworld/source/ld/app_32c3.ld | 6 - .../ram_helloworld/source/ld/app_32c6.ld | 6 - .../ram_helloworld/source/ld/app_32h2.ld | 6 - .../ram_helloworld/source/ld/app_32p4.ld | 26 + .../ram_helloworld/source/ld/app_32s2.ld | 6 - .../ram_helloworld/source/ld/app_32s3.ld | 6 - .../ram_helloworld/source/ld/app_8266.ld | 17 - test/test_espefuse.py | 451 +++++++++---- test/test_espsecure.py | 47 +- test/test_esptool.py | 245 +++++-- test/test_image_info.py | 62 +- test/test_imagegen.py | 25 +- test/test_merge_bin.py | 310 +++++++++ test/test_modules.py | 3 + test/test_uf2_ids.py | 66 ++ 176 files changed, 8454 insertions(+), 3701 deletions(-) create mode 100644 .github/workflows/dangerjs.yml create mode 100644 .github/workflows/dev_release_esptool_pypi.yml create mode 100644 docs/en/espefuse/inc/summary_ESP32-C6.rst create mode 100644 docs/en/espefuse/inc/summary_ESP32-H2.rst create mode 100644 docs/en/espefuse/inc/summary_ESP32-P4.rst create mode 100644 docs/en/resources.rst create mode 100644 espefuse/efuse/esp32p4/__init__.py create mode 100644 espefuse/efuse/esp32p4/emulate_efuse_controller.py create mode 100644 espefuse/efuse/esp32p4/fields.py create mode 100644 espefuse/efuse/esp32p4/mem_definition.py create mode 100644 espefuse/efuse/esp32p4/operations.py create mode 100644 espefuse/efuse_defs/esp32.yaml create mode 100644 espefuse/efuse_defs/esp32c2.yaml create mode 100644 espefuse/efuse_defs/esp32c3.yaml create mode 100644 espefuse/efuse_defs/esp32c6.yaml create mode 100644 espefuse/efuse_defs/esp32h2.yaml create mode 100644 espefuse/efuse_defs/esp32p4.yaml create mode 100644 espefuse/efuse_defs/esp32s2.yaml create mode 100644 espefuse/efuse_defs/esp32s3.yaml create mode 100644 esptool/targets/esp32p4.py create mode 100644 esptool/targets/stub_flasher/stub_flasher_32p4.json create mode 100644 esptool/uf2_writer.py create mode 100644 flasher_stub/ld/rom_32p4.ld create mode 100644 flasher_stub/ld/stub_32p4.ld create mode 100644 test/images/bootloader_esp32_v5_2.bin create mode 100644 test/images/ram_helloworld/helloworld-esp32p4.bin create mode 100644 test/images/ram_helloworld/source/ld/app_32p4.ld create mode 100644 test/test_uf2_ids.py diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7685f2935..34be8e5f4 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -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 --git a/.github/workflows/build_esptool.yml b/.github/workflows/build_esptool.yml index 3798c35de..86da69752 100644 --- a/.github/workflows/build_esptool.yml +++ b/.github/workflows/build_esptool.yml @@ -12,25 +12,38 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-10.15, ubuntu-latest, windows-latest] + os: [macos-latest, ubuntu-latest, windows-latest] include: - os: macos-10.15 TARGET: macos SEPARATOR: ':' - - os: ubuntu-latest + - os: ubuntu-20.04 TARGET: linux-amd64 SEPARATOR: ':' - os: windows-latest TARGET: win64 EXTEN: .exe SEPARATOR: ';' + - os: ARM + CONTAINER: python:3.8-bullseye + TARGET: arm + SEPARATOR: ':' + - os: ARM64 + CONTAINER: python:3.8-bullseye + TARGET: arm64 + SEPARATOR: ':' + container: ${{ matrix.CONTAINER }} # use python container on ARM env: DISTPATH: esptool-${{ matrix.TARGET }} - STUBS_DIR: /esptool/targets/stub_flasher/ + STUBS_DIR: ./esptool/targets/stub_flasher/ + EFUSE_DIR: ./espefuse/efuse_defs/ + PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi" steps: - name: Checkout repository uses: actions/checkout@master - name: Set up Python 3.8 + # Skip setting python on ARM because of missing compatibility: https://github.com/actions/setup-python/issues/108 + if: matrix.os != 'ARM' && matrix.os != 'ARM64' uses: actions/setup-python@master with: python-version: 3.8 @@ -59,8 +72,8 @@ jobs: path: /home/runner/work/esptool/esptool/flasher_stub/build - 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 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: Test binaries @@ -137,7 +150,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - TARGET: [macos, linux-amd64, win64] + TARGET: [macos, linux-amd64, win64, arm, arm64] env: DISTPATH: esptool-${{ needs.create_release.outputs.VERSION }}-${{ matrix.TARGET }} steps: diff --git a/.github/workflows/dangerjs.yml b/.github/workflows/dangerjs.yml new file mode 100644 index 000000000..ab9f002a6 --- /dev/null +++ b/.github/workflows/dangerjs.yml @@ -0,0 +1,22 @@ +name: DangerJS Check +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@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: DangerJS pull request linter + uses: espressif/github-actions/danger_pr_review@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/dev_release_esptool_pypi.yml b/.github/workflows/dev_release_esptool_pypi.yml new file mode 100644 index 000000000..a443a1323 --- /dev/null +++ b/.github/workflows/dev_release_esptool_pypi.yml @@ -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 --git a/.github/workflows/test_esptool.yml b/.github/workflows/test_esptool.yml index 46cda59e2..5ea437bb4 100644 --- a/.github/workflows/test_esptool.yml +++ b/.github/workflows/test_esptool.yml @@ -8,7 +8,7 @@ jobs: 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 @@ jobs: 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 @@ jobs: 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.8 only) if: matrix.python-version == 3.8 run: | diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b631db632..22f1339be 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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 @@ cache: version_check: <<: *test_template - only: - - tags + rules: + - if: '$CI_COMMIT_TAG != null' script: - VERSION=$(esptool.py version | head -n 1) - | @@ -50,6 +65,15 @@ version_check: 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 @@ host_tests: - 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 {} . \; @@ -209,6 +234,8 @@ check_stub_build: PYTEST_ADDOPTS: "-sv --junitxml=test/report.xml --color=yes" before_script: - pip install -e .[dev] --prefer-binary + # libffi (needed for espsecure) version keeps changing in python docker images. Add a symlink to the installed version on Raspberry Pi + - if [ $(uname -m) = "armv7l" ]; then ln -sfn /usr/lib/arm-linux-gnueabihf/libffi.so.7.1.0 /usr/lib/arm-linux-gnueabihf/libffi.so.6; fi artifacts: reports: junit: test/report.xml @@ -233,8 +260,6 @@ target_esp32: tags: - esptool_esp32_target script: - # libffi (needed for espsecure) version keeps changing in python docker images, add a symlink to the installed version - - ln -sfn /usr/lib/arm-linux-gnueabihf/libffi.so.7.1.0 /usr/lib/arm-linux-gnueabihf/libffi.so.6 - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_esptool.py --port /dev/serial_ports/ESP32 --chip esp32 --baud 115200 # ESP32S2 @@ -275,10 +300,19 @@ target_esp32s3: 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: @@ -343,6 +377,41 @@ target_esp32h2_jtag_serial: script: - coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_esptool.py --port /dev/serial_ports/ESP32H2_JTAG_SERIAL --preload-port /dev/serial_ports/ESP32H2_PRELOAD --chip esp32h2 --baud 115200 +.windows_test: + stage: test + variables: + PYTEST_ADDOPTS: "-sv --junitxml=test/report.xml --color=yes" + PYTHONPATH: "$PYTHONPATH:${CI_PROJECT_DIR}/test" + COVERAGE_PROCESS_START: "${CI_PROJECT_DIR}/test/.covconf" + before_script: + - pip install -e .[dev] --prefer-binary + artifacts: + reports: + junit: test/report.xml + when: always + paths: + - test/*.out + - "**/.coverage*" + - ".coverage*" + expire_in: 1 week + tags: + - windows-target + +host_tests_windows: + extends: .windows_test + script: + - python -m coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_espefuse.py + - python -m coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_espsecure.py + - python -m coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_imagegen.py + - python -m coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_image_info.py + - python -m coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_modules.py + - python -m coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_merge_bin.py + +target_tests_windows: + extends: .windows_test + script: + - python -m coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_esptool.py --port COM4 --chip esp32 --baud 115200 -m quick_test + combine_reports: stage: report image: python:3.7-bullseye @@ -362,6 +431,7 @@ combine_reports: coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/' variables: LC_ALL: C.UTF-8 + COVERAGE_RCFILE: "${CI_PROJECT_DIR}/test/.covconf" before_script: - pip install -e .[dev] --prefer-binary script: @@ -377,8 +447,8 @@ build_docs: image: python:3.7-bullseye tags: - build_docs - only: - changes: + rules: + - changes: - "docs/**/*" - "CONTRIBUTING.rst" needs: [] @@ -391,7 +461,7 @@ build_docs: script: - cd docs - pip install -r requirements.txt --prefer-binary - - build-docs -l en -t {esp8266,esp32,esp32s2,esp32c3,esp32s3} + - build-docs -l en -t {esp8266,esp32,esp32s2,esp32c3,esp32s3,esp32c2,esp32c6,esp32h2} .deploy_docs_template: stage: deploy_docs @@ -400,10 +470,6 @@ build_docs: - 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 @@ -414,9 +480,12 @@ build_docs: 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/" @@ -429,9 +498,11 @@ deploy_docs_preview: 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/" @@ -440,25 +511,3 @@ deploy_docs_production: 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 --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index edf3b57c9..f2fdbc737 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,15 @@ repos: rev: 4.0.1 hooks: - id: flake8 + additional_dependencies: [flake8-import-order] - repo: https://github.com/psf/black rev: 22.3.0 hooks: - id: black + - repo: https://github.com/espressif/conventional-precommit-linter + rev: v1.2.1 + hooks: + - id: conventional-precommit-linter + stages: [commit-msg] +default_stages: [commit] +default_install_hook_types: [pre-commit, commit-msg] diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 415627def..6b9d5536e 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -78,15 +78,20 @@ Pre-commit checks `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 @@ Black 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. @@ -115,6 +120,7 @@ The following tests run automatically by GitHub Actions for each Pull Request. Y * ``test_mergebin.py`` tests the ``merge_bin`` command * ``test_modules.py`` tests the modules used by ``esptool.py`` for regressions * ``test_espsecure.py`` tests ``espsecure.py`` functionality +* ``test_espsecure_hsm.py`` tests support of extarnal HSM signing in ``espsecure.py``. These tests require additional prerequisites, see ``SoftHSM2 setup`` in the `tests workflow definition `_ for more information. The following tests are not run automatically by GitHub Actions, because they need real connected hardware. Therefore, they need to be run locally in a command line: @@ -146,7 +152,7 @@ The following tests are not run automatically by GitHub Actions, but can be run Do not attempt to run these tests on real hardware! You risk damaging or destroying the ESP chip! -The whole test suite (without the tests needing an actual hardware) can be easily run with the following command in the esptool root folder: ``pytest --ignore=test/test_esptool.py`` +The whole test suite (without the tests needing an actual hardware or installation of additional prerequisites) can be easily run with the following command in the esptool root folder: ``pytest -m host_test`` Pull Request Process diff --git a/MANIFEST.in b/MANIFEST.in index 0f6d078f6..42ef8ccff 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ include README.md include LICENSE include esptool/targets/stub_flasher/*.json +include espefuse/efuse_defs/*.yaml # sdist includes test/test*.py by default, but esptool.py tests # are so far only intended to run from the git repo itself prune test diff --git a/docs/_static/esptool_versions.js b/docs/_static/esptool_versions.js index 6bc1a1887..b5e0fab54 100644 --- a/docs/_static/esptool_versions.js +++ b/docs/_static/esptool_versions.js @@ -9,5 +9,8 @@ var DOCUMENTATION_VERSIONS = { { text: "ESP32-S2", value: "esp32s2" }, { text: "ESP32-S3", value: "esp32s3" }, { text: "ESP32-C3", value: "esp32c3" }, + { text: "ESP32-C2", value: "esp32c2" }, + { text: "ESP32-C6", value: "esp32c6" }, + { text: "ESP32-H2", value: "esp32h2" }, ] }; diff --git a/docs/conf_common.py b/docs/conf_common.py index afd4cdd55..3d82118d5 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -1,7 +1,16 @@ from esp_docs.conf_docs import * # noqa: F403,F401 languages = ["en"] -idf_targets = ["esp8266", "esp32", "esp32s2", "esp32s3", "esp32c3"] +idf_targets = [ + "esp8266", + "esp32", + "esp32s2", + "esp32s3", + "esp32c3", + "esp32c2", + "esp32c6", + "esp32h2", +] # link roles config github_repo = "espressif/esptool" @@ -28,12 +37,21 @@ ESP32S3_DOCS = ESP32S2_DOCS +ESP32C2_DOCS = ESP32S3_DOCS + +ESP32C6_DOCS = ESP32C2_DOCS + +ESP32H2_DOCS = ESP32C6_DOCS + conditional_include_dict = { "esp8266": ESP8266_DOCS, "esp32": ESP32_DOCS, "esp32s2": ESP32S2_DOCS, "esp32c3": ESP32C3_DOCS, "esp32s3": ESP32S3_DOCS, + "esp32c2": ESP32C2_DOCS, + "esp32c6": ESP32C6_DOCS, + "esp32h2": ESP32H2_DOCS, } # Extra options required by sphinx_idf_theme diff --git a/docs/en/advanced-topics/boot-mode-selection.rst b/docs/en/advanced-topics/boot-mode-selection.rst index d8d99a7b6..62e187b5a 100644 --- a/docs/en/advanced-topics/boot-mode-selection.rst +++ b/docs/en/advanced-topics/boot-mode-selection.rst @@ -1,6 +1,8 @@ -{IDF_TARGET_STRAP_BOOT_GPIO:default="GPIO0", esp32="GPIO0", esp32s2="GPIO0", esp32s3="GPIO0", esp32c3="GPIO9"} +{IDF_TARGET_STRAP_BOOT_GPIO:default="GPIO9", esp32="GPIO0", esp32s2="GPIO0", esp32s3="GPIO0"} -{IDF_TARGET_STRAP_BOOT_2_GPIO:default="GPIO2", esp32="GPIO2", esp32s2="GPIO46", esp32s3="GPIO46", esp32c3="GPIO8"} +{IDF_TARGET_STRAP_BOOT_2_GPIO:default="GPIO8", esp32="GPIO2", esp32s2="GPIO46", esp32s3="GPIO46"} + +{IDF_TARGET_BOOTLOADER_OFFSET:default="0",esp32="1000", esp32s2="1000"} .. _boot-mode: @@ -78,11 +80,11 @@ This guide explains how to select the boot mode correctly and describes the boot {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. - .. only:: esp32c3 + .. only:: esp32c3 or esp32c2 or esp32h2 or esp32c6 {IDF_TARGET_STRAP_BOOT_2_GPIO} must also be driven High, in order to enter the serial bootloader reliably. The strapping combination of {IDF_TARGET_STRAP_BOOT_2_GPIO} = 0 and {IDF_TARGET_STRAP_BOOT_GPIO} = 0 is invalid and will trigger unexpected behavior. @@ -217,7 +219,7 @@ Depending on the kind of hardware you have, it may also be possible to manually The rest of boot messages are used internally by Espressif. -.. only:: esp32 +.. only:: not esp8266 Boot Log -------- @@ -225,38 +227,50 @@ Depending on the kind of hardware you have, it may also be possible to manually Boot Mode Message ^^^^^^^^^^^^^^^^^ - After reset, the second line printed by the ESP32 ROM (at 115200bps) is a reset & boot mode message: + After reset, the second line printed by the {IDF_TARGET_NAME} ROM (at 115200bps) is a reset & boot mode message: :: ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2)) - ``rst:0xNN (REASON)`` is an enumerated value (and description) of the reason for the reset. `A mapping between the hex value and each reason can be found in the ESP-IDF source `__. - The value can be read in ESP32 code via the `get_reset_reason() ROM function `__. - ``boot:0xNN (DESCRIPTION)`` is the hex value of the strapping pins, as represented in the `GPIO_STRAP register `__. + ``rst:0xNN (REASON)`` is an enumerated value (and description) of the reason for the reset. A mapping between the hex value and each reason can be found in the `ESP-IDF source under RESET_REASON enum `__. + The value can be read in {IDF_TARGET_NAME} code via the `get_reset_reason() ROM function `__. + + ``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: - - ``0x01`` - GPIO5 - - ``0x02`` - MTDO (GPIO15) - - ``0x04`` - GPIO4 - - ``0x08`` - GPIO2 - - ``0x10`` - GPIO0 - - ``0x20`` - MTDI (GPIO12) + .. only:: esp32 + + - ``0x01`` - GPIO5 + - ``0x02`` - MTDO (GPIO15) + - ``0x04`` - GPIO4 + - ``0x08`` - GPIO2 + - ``0x10`` - GPIO0 + - ``0x20`` - MTDI (GPIO12) + + .. only:: not esp32 + + - ``0x04`` - {IDF_TARGET_STRAP_BOOT_2_GPIO} + - ``0x08`` - {IDF_TARGET_STRAP_BOOT_GPIO} If the pin was high on reset, the bit value will be set. If it was low on reset, the bit will be cleared. A number of boot mode strings can be shown depending on which bits are set: - - ``DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2)`` - ESP32 is in download flashing mode (suitable for esptool) + - ``DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2)`` or ``DOWNLOAD(USB/UART0)`` - {IDF_TARGET_NAME} is in download flashing mode (suitable for esptool) - ``SPI_FAST_FLASH_BOOT`` - This is the normal SPI flash boot mode. - - Other modes (including ``HSPI_FLASH_BOOT``, ``SPI_FLASH_BOOT``, ``SDIO_REI_FEO_V1_BOOT``, ``ATE_BOOT``) may be shown here. This indicates an unsupported boot mode has been selected. - Consult the strapping pins shown above (in most cases, one of these modes is selected if GPIO2 has been pulled high when GPIO0 is low). + - Other modes (including ``SPI_FLASH_BOOT``, ``SDIO_REI_FEO_V1_BOOT``, ``ATE_BOOT``) may be shown here. This indicates an unsupported boot mode has been selected. + Consult the strapping pins shown above (in most cases, one of these modes is selected if {IDF_TARGET_STRAP_BOOT_2_GPIO} has been pulled high when {IDF_TARGET_STRAP_BOOT_GPIO} is low). + + .. only:: esp32 + + .. note:: - .. note:: + ``GPIO_STRAP`` register includes GPIO 4 but this pin is not used by any supported boot mode and be set either high or low for all supported boot modes. - ``GPIO_STRAP`` register includes GPIO 4 but this pin is not used by any supported boot mode and be set either high or low for all supported boot modes. Later Boot Messages ^^^^^^^^^^^^^^^^^^^ @@ -269,39 +283,58 @@ Depending on the kind of hardware you have, it may also be possible to manually :: - flash read err, 1000 + flash read err, {IDF_TARGET_BOOTLOADER_OFFSET} + + This fatal error indicates that the bootloader tried to read the software bootloader header at address 0x{IDF_TARGET_BOOTLOADER_OFFSET} but failed to read valid data. Possible reasons for this include: + + .. list:: + + - There isn't actually a bootloader at offset 0x{IDF_TARGET_BOOTLOADER_OFFSET} (maybe the bootloader was flashed to the wrong offset by mistake, or the flash has been erased and no bootloader has been flashed yet.) + - Physical problem with the connection to the flash chip, or flash chip power. + - Flash encryption is enabled but the bootloader is plaintext. Alternatively, flash encryption is disabled but the bootloader is encrypted ciphertext. - This fatal error indicates that the bootloader tried to read the software bootloader header at address 0x1000 but failed to read valid data. Possible reasons for this include: + :esp32: - Boot mode accidentally set to ``HSPI_FLASH_BOOT``, which uses different SPI flash pins. Check {IDF_TARGET_STRAP_BOOT_2_GPIO} (see above). + :esp32: - VDDSDIO has been enabled at 1.8V (due to MTDI/GPIO12, see above), but this flash chip requires 3.3V so it's browning out. - - There isn't actually a bootloader at offset 0x1000 (maybe the bootloader was flashed to the wrong offset by mistake, or the flash has been erased and no bootloader has been flashed yet.) - - Physical problem with the connection to the flash chip, or flash chip power. - - Boot mode accidentally set to ``HSPI_FLASH_BOOT``, which uses different SPI flash pins. Check GPIO2 (see above). - - VDDSDIO has been enabled at 1.8V (due to MTDI/GPIO12, see above), but this flash chip requires 3.3V so it's browning out. - - Flash encryption is enabled but the bootloader is plaintext. Alternatively, flash encryption is disabled but the bootloader is encrypted ciphertext. Software Bootloader Header Info """"""""""""""""""""""""""""""" - :: + .. only:: esp32 + + :: + + configsip: 0, SPIWP:0x00 + 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 + + :: + + SPIWP:0xee + mode:DIO, clock div:1 + + + This is normal boot output based on a combination of eFuse values and information read from the bootloader header at flash offset 0x{IDF_TARGET_BOOTLOADER_OFFSET}: + + .. list:: + + :esp32: - ``configsip: N`` indicates SPI flash config: + + :esp32: - 0 for default SPI flash + :esp32: - 1 if booting from the HSPI bus (due to eFuse configuration) + :esp32: - Any other value indicates that SPI flash pins have been remapped via eFuse (the value is the value read from eFuse, consult :ref:`espefuse docs ` to get an easier to read representation of these pin mappings). - configsip: 0, SPIWP:0x00 - clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 - mode:DIO, clock div:1 - - This is normal boot output based on a combination of efuse values and information read from the bootloader header at flash offset 0x1000: - - - ``configsip: N`` indicates SPI flash config: - - 0 for default SPI flash - - 1 if booting from the HSPI bus (due to EFUSE configuration) - - Any other value indicates that SPI flash pins have been remapped via efuse (the value is the value read from efuse, consult :ref:`espefuse docs ` to get an easier to read representation of these pin mappings). - - ``SPIWP:0xNN`` indicates a custom ``WP`` pin value, which is stored in the bootloader header. This pin value is only used if SPI flash pins have been remapped via efuse (as shown in the ``configsip`` value). - All custom pin values but WP are encoded in the configsip byte loaded from efuse, and WP is supplied in the bootloader header. - - ``clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00`` Custom GPIO drive strength values for SPI flash pins. These are read from the bootloader header in flash. Not currently supported. - - ``mode: AAA, clock div: N``. SPI flash access mode. Read from the bootloader header, correspond to the ``--flash_mode`` and ``--flash_freq`` arguments supplied to ``esptool.py write_flash`` or ``esptool.py elf2image``. - - ``mode`` can be DIO, DOUT, QIO, or QOUT. *QIO and QOUT are not supported here*, to boot in a Quad I/O mode the ROM bootloader should load the software bootloader in a Dual I/O mode and then the ESP-IDF software bootloader enables Quad I/O based on the detected flash chip mode. - - ``clock div: N`` is the SPI flash clock frequency divider. This is an integer clock divider value from an 80MHz APB clock, based on the supplied ``--flash_freq`` argument (ie 80MHz=1, 40MHz=2, etc). - The ROM bootloader actually loads the software bootloader at a lower frequency than the flash_freq value. The initial APB clock frequency is equal to the crystal frequency, so with a 40MHz crystal the SPI clock used to load the software bootloader will be half the configured value (40MHz/2=20MHz). - When the software bootloader starts it sets the APB clock to 80MHz causing the SPI clock frequency to match the value set when flashing. + - ``SPIWP:0xNN`` indicates a custom ``WP`` pin value, which is stored in the bootloader header. This pin value is only used if SPI flash pins have been remapped via eFuse (as shown in the ``configsip`` value). + All custom pin values but WP are encoded in the configsip byte loaded from eFuse, and WP is supplied in the bootloader header. + :esp32: - ``clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00`` Custom GPIO drive strength values for SPI flash pins. These are read from the bootloader header in flash. Not currently supported. + - ``mode: AAA, clock div: N``. SPI flash access mode. Read from the bootloader header, correspond to the ``--flash_mode`` and ``--flash_freq`` arguments supplied to ``esptool.py write_flash`` or ``esptool.py elf2image``. + - ``mode`` can be DIO, DOUT, QIO, or QOUT. *QIO and QOUT are not supported here*, to boot in a Quad I/O mode the ROM bootloader should load the software bootloader in a Dual I/O mode and then the ESP-IDF software bootloader enables Quad I/O based on the detected flash chip mode. + - ``clock div: N`` is the SPI flash clock frequency divider. This is an integer clock divider value from an 80MHz APB clock, based on the supplied ``--flash_freq`` argument (ie 80MHz=1, 40MHz=2, etc). + The ROM bootloader actually loads the software bootloader at a lower frequency than the flash_freq value. The initial APB clock frequency is equal to the crystal frequency, so with a 40MHz crystal the SPI clock used to load the software bootloader will be half the configured value (40MHz/2=20MHz). + When the software bootloader starts it sets the APB clock to 80MHz causing the SPI clock frequency to match the value set when flashing. Software Bootloader Load Segments """"""""""""""""""""""""""""""""" @@ -316,7 +349,7 @@ Depending on the kind of hardware you have, it may also be possible to manually These entries are printed as the ROM bootloader loads each segment in the software bootloader image. The load address and length of each segment is printed. - You can compare these values to the software bootloader image by running ``esptool.py --chip esp32 image_info /path/to/bootloader.bin`` to dump image info including a summary of each segment. Corresponding details will also be found in the bootloader ELF file headers. + You can compare these values to the software bootloader image by running ``esptool.py --chip {IDF_TARGET_PATH_NAME} image_info /path/to/bootloader.bin`` to dump image info including a summary of each segment. Corresponding details will also be found in the bootloader ELF file headers. If there is a problem with the SPI flash chip addressing mode, the values printed by the bootloader here may be corrupted. diff --git a/docs/en/advanced-topics/firmware-image-format.rst b/docs/en/advanced-topics/firmware-image-format.rst index 529df3d5f..48cb90669 100644 --- a/docs/en/advanced-topics/firmware-image-format.rst +++ b/docs/en/advanced-topics/firmware-image-format.rst @@ -1,3 +1,12 @@ +{IDF_TARGET_FLASH_FREQ_F:default="80", esp32c2="60", esp32h2="48"} + +{IDF_TARGET_FLASH_FREQ_0:default="40", esp32c2="30", esp32h2="24"} + +{IDF_TARGET_FLASH_FREQ_1:default="26", esp32c2="20", esp32h2="16"} + +{IDF_TARGET_FLASH_FREQ_2:default="20", esp32c2="15", esp32h2="12"} + + .. _image-format: Firmware Image Format @@ -37,29 +46,67 @@ The image header is 8 bytes long: | 4-7 | Entry point address | +--------+--------------------------------------------------------------------------------------------------+ -.. only:: not esp8266 - - +--------+--------------------------------------------------------------------------------------------------+ - | Byte | Description | - +========+==================================================================================================+ - | 0 | Magic number (always ``0xE9``) | - +--------+--------------------------------------------------------------------------------------------------+ - | 1 | Number of segments | - +--------+--------------------------------------------------------------------------------------------------+ - | 2 | SPI Flash Mode (``0`` = QIO, ``1`` = QOUT, ``2`` = DIO, ``3`` = DOUT) | - +--------+--------------------------------------------------------------------------------------------------+ - | 3 | High four bits - Flash size (``0`` = 1MB, ``1`` = 2MB, ``2`` = 4MB, ``3`` = 8MB, ``4`` = 16MB) | - | | | - | | Low four bits - Flash frequency (``0`` = 40MHz, ``1`` = 26MHz, ``2`` = 20MHz, ``0xf`` = 80MHz) | - +--------+--------------------------------------------------------------------------------------------------+ - | 4-7 | Entry point address | - +--------+--------------------------------------------------------------------------------------------------+ - -.. only:: esp32c2 or esp32h2 - .. fail_when_new_target_added:: +.. only:: esp32s2 or esp32s3 + + +--------+------------------------------------------------------------------------------------------------+ + | Byte | Description | + +========+================================================================================================+ + | 0 | Magic number (always ``0xE9``) | + +--------+------------------------------------------------------------------------------------------------+ + | 1 | Number of segments | + +--------+------------------------------------------------------------------------------------------------+ + | 2 | SPI Flash Mode (``0`` = QIO, ``1`` = QOUT, ``2`` = DIO, ``3`` = DOUT) | + +--------+------------------------------------------------------------------------------------------------+ + | 3 | High four bits - Flash size (``0`` = 1MB, ``1`` = 2MB, ``2`` = 4MB, ``3`` = 8MB, ``4`` = 16MB, | + | | ``5`` = 32MB, ``6`` = 64MB, ``7`` = 128MB") | + | | | + | | Low four bits - Flash frequency (``0`` = {IDF_TARGET_FLASH_FREQ_0}MHz, ``1`` = {IDF_TARGET_FLASH_FREQ_1}MHz, ``2`` = {IDF_TARGET_FLASH_FREQ_2}MHz, ``0xf`` = {IDF_TARGET_FLASH_FREQ_F}MHz) | + +--------+------------------------------------------------------------------------------------------------+ + | 4-7 | Entry point address | + +--------+------------------------------------------------------------------------------------------------+ + + +.. only:: esp32c6 + + +--------+------------------------------------------------------------------------------------------------+ + | Byte | Description | + +========+================================================================================================+ + | 0 | Magic number (always ``0xE9``) | + +--------+------------------------------------------------------------------------------------------------+ + | 1 | Number of segments | + +--------+------------------------------------------------------------------------------------------------+ + | 2 | SPI Flash Mode (``0`` = QIO, ``1`` = QOUT, ``2`` = DIO, ``3`` = DOUT) | + +--------+------------------------------------------------------------------------------------------------+ + | 3 | High four bits - Flash size (``0`` = 1MB, ``1`` = 2MB, ``2`` = 4MB, ``3`` = 8MB, ``4`` = 16MB) | + | | | + | | Low four bits - Flash frequency (``0`` = 80MHz, ``0`` = 40MHz, ``2`` = 20MHz) | + +--------+------------------------------------------------------------------------------------------------+ + | 4-7 | Entry point address | + +--------+------------------------------------------------------------------------------------------------+ + + .. note:: + Flash frequency with value ``0`` can mean either 80MHz or 40MHz based on MSPI clock source mode. + + +.. only:: not (esp8266 or esp32c6 or esp32s3 or esp32s2) + + +--------+------------------------------------------------------------------------------------------------+ + | Byte | Description | + +========+================================================================================================+ + | 0 | Magic number (always ``0xE9``) | + +--------+------------------------------------------------------------------------------------------------+ + | 1 | Number of segments | + +--------+------------------------------------------------------------------------------------------------+ + | 2 | SPI Flash Mode (``0`` = QIO, ``1`` = QOUT, ``2`` = DIO, ``3`` = DOUT) | + +--------+------------------------------------------------------------------------------------------------+ + | 3 | High four bits - Flash size (``0`` = 1MB, ``1`` = 2MB, ``2`` = 4MB, ``3`` = 8MB, ``4`` = 16MB) | + | | | + | | Low four bits - Flash frequency (``0`` = {IDF_TARGET_FLASH_FREQ_0}MHz, ``1`` = {IDF_TARGET_FLASH_FREQ_1}MHz, ``2`` = {IDF_TARGET_FLASH_FREQ_2}MHz, ``0xf`` = {IDF_TARGET_FLASH_FREQ_F}MHz) | + +--------+------------------------------------------------------------------------------------------------+ + | 4-7 | Entry point address | + +--------+------------------------------------------------------------------------------------------------+ - TODO: Update flash frequency lists to be esp32c2 or esp32h2 specific ``esptool.py`` overrides the 2nd and 3rd (start from 0) bytes according to the SPI flash info provided through command line option, but only if there is no SHA256 digest appended after the image. Therefore, if you would like to change SPI flash info during flashing, i.e. with the ``esptool.py write_flash`` command, then generate images without SHA256 digests. This can be achieved by running ``esptool.py elf2image`` with the ``--dont-append-digest`` argument. diff --git a/docs/en/advanced-topics/serial-protocol.rst b/docs/en/advanced-topics/serial-protocol.rst index 03d930baa..83a7e3a6b 100644 --- a/docs/en/advanced-topics/serial-protocol.rst +++ b/docs/en/advanced-topics/serial-protocol.rst @@ -60,7 +60,7 @@ Each received command will result in a response SLIP packet sent from the ESP ch +========+=============+==============================================================================================================+ | 0 | Direction | Always ``0x01`` for responses | +--------+-------------+--------------------------------------------------------------------------------------------------------------+ -| 1 | Command | Same value as Command identifier in the request packet that trigged the response | +| 1 | Command | Same value as Command identifier in the request packet that triggered the response | +--------+-------------+--------------------------------------------------------------------------------------------------------------+ | 2-3 | Size | Size of data field. At least the length of the `Status Bytes`_ (2 or 4 bytes, see below). | +--------+-------------+--------------------------------------------------------------------------------------------------------------+ diff --git a/docs/en/contributing.rst b/docs/en/contributing.rst index ac7b6bcf3..c7fcb94cf 100644 --- a/docs/en/contributing.rst +++ b/docs/en/contributing.rst @@ -1 +1,3 @@ +.. _contribute: + .. include:: ../../CONTRIBUTING.rst diff --git a/docs/en/espefuse/burn-key-cmd.rst b/docs/en/espefuse/burn-key-cmd.rst index b3a394f5c..ebaa8ebd6 100644 --- a/docs/en/espefuse/burn-key-cmd.rst +++ b/docs/en/espefuse/burn-key-cmd.rst @@ -18,7 +18,8 @@ Positional arguments: - ``block`` - Name of key block. :esp32: - ``Keyfile``. It is a raw binary file. It must contain 256 bits of binary key if the coding scheme is ``None`` and 128 bits if ``3/4``. - :not esp32: - ``Keyfile``. It is a raw binary file. The length of binary key depends on the key purpose option. + :not esp32 and not esp32h2: - ``Keyfile``. It is a raw binary file. The length of binary key depends on the key purpose option. + :esp32h2: - ``Keyfile``. It is a raw binary file. The length of binary key depends on the key purpose option. For the ``ECDSA_KEY`` purpose use ``PEM`` file. :not esp32: - ``Key purpose``. The purpose of this key. .. only:: esp32 @@ -37,6 +38,7 @@ Optional arguments: :not esp32: - ``--no-write-protect``. 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. :not esp32: - ``--no-read-protect``. Disable read-protecting of the key. The key remains readable software. The key with keypurpose [USER, RESERVED and .._DIGEST] will remain readable anyway, but for the rest keypurposes the read-protection will be defined by this option (Read-protect by default). - ``--force-write-always``. Write the eFuse key even if it looks like it is already been written, or is write protected. Note that this option can't disable write protection, or clear any bit which has already been set. + - ``--show-sensitive-info``. Show data to be burned (may expose sensitive data). Enabled if --debug is used. Use this option to see the byte order of the data being written. .. only:: esp32 @@ -53,7 +55,7 @@ Optional arguments: Do not use the names ``BLOCK1`` and ``BLOCK2`` to burn flash encryption and secure boot v2 keys because byte order will be incorrect and read protection will not meet security requirements. -.. only:: esp32c3 or esp32s2 or esp32s3 +.. only:: not esp32 and not esp32c2 {IDF_TARGET_NAME} supportes eFuse key purposes. This means that each eFuse block has a special eFuse field that indicates which key is in the eFuse block. During the burn operation this eFuse key purpose is burned as well with write protection (the ``--no-write-protect`` flag has no effect on this field). The {IDF_TARGET_NAME} chip supports the following key purposes: @@ -63,6 +65,7 @@ Optional arguments: - RESERVED. :esp32s2 or esp32s3: - XTS_AES_256_KEY_1. The first 256 bits of 512bit flash encryption key. :esp32s2 or esp32s3: - XTS_AES_256_KEY_2. The second 256 bits of 512bit flash encryption key. + :esp32h2: - ECDSA_KEY. It can be ECDSA private keys based on NIST192p or NIST256p curve. The private key is extracted from the given file and written into a eFuse block with write and read protection enabled. This private key shall be used by ECDSA accelerator for the signing purpose. - XTS_AES_128_KEY. 256 bit flash encryption key. - HMAC_DOWN_ALL. - HMAC_DOWN_JTAG. @@ -73,6 +76,22 @@ Optional arguments: - SECURE_BOOT_DIGEST2. 3 secure boot key. :esp32s2 or esp32s3: - XTS_AES_256_KEY. This is a virtual key purpose for flash encryption key. This allows you to write a whole 512-bit key into two blocks with ``XTS_AES_256_KEY_1`` and ``XTS_AES_256_KEY_2`` purposes without splitting the key file. +.. only:: esp32h2 + + {IDF_TARGET_NAME} has the ECDSA accelerator for signature purposes and supports private keys based on the NIST192p or NIST256p curve. These two commands below can be used to generate such keys (``PEM`` file). The ``burn_key`` command with the ``ECDSA_KEY`` purpose takes the ``PEM`` file and writes the private key into a eFuse block. The key is written to the block in reverse byte order. + + For NIST192p, the private key is 192 bits long, so 8 padding bytes ("0x00") are added. + + .. code-block:: none + + > espsecure.py generate_signing_key -v 2 -s ecdsa192 ecdsa192.pem + ECDSA NIST192p private key in PEM format written to ecdsa192.pem + + .. code-block:: none + + > espsecure.py generate_signing_key -v 2 -s ecdsa256 ecdsa256.pem + ECDSA NIST256p private key in PEM format written to ecdsa256.pem + .. only:: esp32c2 {IDF_TARGET_NAME} has only one eFuse key block (256 bits long). It is block #3 - ``BLOCK_KEY0``. This block can have user, flash encryption, secure boot keys. This chip does not have any eFuse key purpose fields, but we use the key purpose option to distinguish between such keys. The key purpose option determines protection and byte order for key. @@ -150,8 +169,9 @@ Usage > espefuse.py burn_key flash_encryption 256bit_fe_key.bin === Run "burn_key" command === + Sensitive data will be hidden (see --show-sensitive-info) Burn keys to blocks: - - BLOCK1 -> [1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00] + - BLOCK1 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] Reversing the byte order Disabling read to key block Disabling write to key block @@ -192,8 +212,9 @@ Usage > espefuse.py burn_key flash_encryption 256bit_fe_key.bin --no-protect-key === Run "burn_key" command === + Sensitive data will be hidden (see --show-sensitive-info) Burn keys to blocks: - - BLOCK1 -> [1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00] + - BLOCK1 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] Reversing the byte order Key is left unprotected as per --no-protect-key argument. @@ -238,14 +259,15 @@ Usage > espefuse.py burn_key BLOCK_KEY0 ~/esp/tests/efuse/512bits_0.bin XTS_AES_256_KEY --no-read-protect === Run "burn_key" command === + Sensitive data will be hidden (see --show-sensitive-info) Burn keys to blocks: - - BLOCK_KEY0 -> [1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00] + - BLOCK_KEY0 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] Reversing byte order for AES-XTS hardware peripheral 'KEY_PURPOSE_0': 'USER' -> 'XTS_AES_256_KEY_1'. Disabling write to 'KEY_PURPOSE_0'. Disabling write to key block - - BLOCK_KEY1 -> [3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20] + - BLOCK_KEY1 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] Reversing byte order for AES-XTS hardware peripheral 'KEY_PURPOSE_1': 'USER' -> 'XTS_AES_256_KEY_2'. Disabling write to 'KEY_PURPOSE_1'. @@ -291,16 +313,18 @@ Usage burn_key BLOCK_KEY0 images/efuse/128bit_key.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS === Run "burn_key_digest" command === + Sensitive data will be hidden (see --show-sensitive-info) Burn keys to blocks: - - BLOCK_KEY0_HI_128 -> [bf 0f 6a f6 8b d3 6d 8b 53 b3 da a9 33 f6 0a 04] + - BLOCK_KEY0_HI_128 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] Disabling write to key block Batch mode is enabled, the burn will be done at the end of the command. === Run "burn_key" command === + Sensitive data will be hidden (see --show-sensitive-info) Burn keys to blocks: - - BLOCK_KEY0_LOW_128 -> [0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00] + - BLOCK_KEY0_LOW_128 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] Reversing byte order for AES-XTS hardware peripheral Disabling read to key block Disabling write to key block diff --git a/docs/en/espefuse/burn-key-digest-cmd.rst b/docs/en/espefuse/burn-key-digest-cmd.rst index 3ea1e2476..1a6e50971 100644 --- a/docs/en/espefuse/burn-key-digest-cmd.rst +++ b/docs/en/espefuse/burn-key-digest-cmd.rst @@ -25,6 +25,7 @@ Optional arguments: :not esp32: - ``--no-write-protect``. 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. :not esp32: - ``--no-read-protect``. Disable read-protecting of the key. This option does not change anything, because Secure Boot keys are readable anyway. - ``--force-write-always``. Write the eFuse key even if it looks like it is already been written, or is write protected. Note that this option can't disable write protection, or clear any bit which has already been set. + - ``--show-sensitive-info``. Show data to be burned (may expose sensitive data). Enabled if --debug is used. Use this option to see the byte order of the data being written. .. only:: esp32 @@ -46,7 +47,8 @@ Usage > espefuse.py burn_key_digest secure_boot_key_v2_0.pem === Run "burn_key_digest" command === - - BLOCK2 -> [a2 cd 39 85 df 00 d7 95 07 0f f6 7c 8b ab e1 7d 39 11 95 c4 5b 37 6e 7b f0 ec 04 5e 36 30 02 5d] + Sensitive data will be hidden (see --show-sensitive-info) + - BLOCK2 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] Disabling write to efuse BLOCK2... Check all blocks for burn... @@ -76,8 +78,9 @@ Usage > espefuse.py burn_key_digest secure_boot_v2_ecdsa192.pem === Run "burn_key_digest" command === + Sensitive data will be hidden (see --show-sensitive-info) Burn keys to blocks: - - BLOCK_KEY0_HI_128 -> [02 c2 bd 9c 1a b4 b7 44 22 59 c6 d3 12 0b 79 1f] + - BLOCK_KEY0_HI_128 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] Disabling write to key block Check all blocks for burn... @@ -117,18 +120,19 @@ Usage BLOCK_KEY2 ~/esp/tests/efuse/secure_boot_key_v2_2.pem SECURE_BOOT_DIGEST2 === Run "burn_key_digest" command === + Sensitive data will be hidden (see --show-sensitive-info) Burn keys to blocks: - - BLOCK_KEY0 -> [a2 cd 39 85 df 00 d7 95 07 0f f6 7c 8b ab e1 7d 39 11 95 c4 5b 37 6e 7b f0 ec 04 5e 36 30 02 5d] + - BLOCK_KEY0 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] 'KEY_PURPOSE_0': 'USER' -> 'SECURE_BOOT_DIGEST0'. Disabling write to 'KEY_PURPOSE_0'. Disabling write to key block - - BLOCK_KEY1 -> [a3 cd 39 85 df 00 d7 95 07 0f f6 7c 8b ab e1 7d 39 11 95 c4 5b 37 6e 7b f0 ec 04 5e 36 30 02 5d] + - BLOCK_KEY1 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] 'KEY_PURPOSE_1': 'USER' -> 'SECURE_BOOT_DIGEST1'. Disabling write to 'KEY_PURPOSE_1'. Disabling write to key block - - BLOCK_KEY2 -> [a4 cd 39 85 df 00 d7 95 07 0f f6 7c 8b ab e1 7d 39 11 95 c4 5b 37 6e 7b f0 ec 04 5e 36 30 02 5d] + - BLOCK_KEY2 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??] 'KEY_PURPOSE_2': 'USER' -> 'SECURE_BOOT_DIGEST2'. Disabling write to 'KEY_PURPOSE_2'. Disabling write to key block diff --git a/docs/en/espefuse/inc/summary_ESP32-C2.rst b/docs/en/espefuse/inc/summary_ESP32-C2.rst index 47c4efc6e..0c29a2556 100644 --- a/docs/en/espefuse/inc/summary_ESP32-C2.rst +++ b/docs/en/espefuse/inc/summary_ESP32-C2.rst @@ -8,72 +8,60 @@ === Run "summary" command === EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- - Adc_Calib fuses: - ADC_CALIBRATION_0 (BLOCK2) = 0 R/W (0b0000000000000000000000) - ADC_CALIBRATION_1 (BLOCK2) = 0 R/W (0x00000000) - ADC_CALIBRATION_2 (BLOCK2) = 0 R/W (0x00000000) - Config fuses: - UART_PRINT_CONTROL (BLOCK0) Set UART boot message output mode = Force print R/W (0b00) - FORCE_SEND_RESUME (BLOCK0) Force ROM code to send a resume cmd during SPI boo = False R/W (0b0) - t - DIS_DIRECT_BOOT (BLOCK0) Disable direct_boot mode = False R/W (0b0) - - Efuse fuses: - WR_DIS (BLOCK0) Disables programming of individual eFuses = 0 R/W (0x00) - RD_DIS (BLOCK0) Disables software reading from BLOCK3 = 0 R/W (0b00) + WR_DIS (BLOCK0) Disable programming of individual eFuses = 0 R/W (0x00) + RD_DIS (BLOCK0) Disable reading from BlOCK3 = 0 R/W (0b00) + UART_PRINT_CONTROL (BLOCK0) Set the default UARTboot message output mode = Enable R/W (0b00) + DIS_DIRECT_BOOT (BLOCK0) This bit set means disable direct_boot mode = False R/W (0b0) - Flash Config fuses: - FLASH_TPUW (BLOCK0) Configures flash startup delay after SoC power-up, = 0 R/W (0x0) - unit is (ms/2). When the value is 15, delay is 7. - 5 ms + Flash fuses: + FORCE_SEND_RESUME (BLOCK0) Set this bit to force ROM code to send a resume co = False R/W (0b0) + mmand during SPI boot + FLASH_TPUW (BLOCK0) Configures flash waiting time after power-up; in u = 0 R/W (0x0) + nit of ms. If the value is less than 15; the waiti + ng time is the configurable value. Otherwise; the + waiting time is twice the configurable value Identity fuses: - SECURE_VERSION (BLOCK0) Secure version (anti-rollback feature) = 0 R/W (0x0) - CUSTOM_MAC_USED (BLOCK0) Enable CUSTOM_MAC programming = False R/W (0b0) - CUSTOM_MAC (BLOCK1) Custom MAC addr - = 00:00:00:00:00:00 (OK) R/W - MAC (BLOCK2) Factory MAC Address - = 94:b5:55:80:00:d0 (OK) R/W - WAFER_VERSION (BLOCK2) WAFER version = (revision 0) R/W (0b000) - PKG_VERSION (BLOCK2) Package version = ESP32-C2 R/W (0b000) - BLK_VERSION_MINOR (BLOCK2) Version of BLOCK2 = No calibration R/W (0b000) + DISABLE_WAFER_VERSION_MAJOR (BLOCK0) Disables check of wafer version major = False R/W (0b0) + DISABLE_BLK_VERSION_MAJOR (BLOCK0) Disables check of blk version major = False R/W (0b0) + WAFER_VERSION_MINOR (BLOCK2) WAFER_VERSION_MINOR = 0 R/W (0x0) + WAFER_VERSION_MAJOR (BLOCK2) WAFER_VERSION_MAJOR = 1 R/W (0b01) + PKG_VERSION (BLOCK2) EFUSE_PKG_VERSION = 1 R/W (0b001) + BLK_VERSION_MINOR (BLOCK2) Minor version of BLOCK2 = No calib R/W (0b000) + BLK_VERSION_MAJOR (BLOCK2) Major version of BLOCK2 = 0 R/W (0b00) - Jtag Config fuses: - DIS_PAD_JTAG (BLOCK0) Permanently disable JTAG access via padsUSB JTAG i = False R/W (0b0) - s controlled separately + Jtag fuses: + DIS_PAD_JTAG (BLOCK0) Set this bit to disable pad jtag = False R/W (0b0) - Ldo fuses: - LDO_VOL_BIAS_CONFIG_LOW (BLOCK2) = 0 R/W (0b000) - LDO_VOL_BIAS_CONFIG_HIGH (BLOCK2) = 0 R/W (0b000000000000000000000000000) - - Pvt fuses: - PVT_LOW (BLOCK2) = 0 R/W (0b00000) - PVT_HIGH (BLOCK2) = 0 R/W (0b0000000000) - - Rf fuses: - RF_REF_I_BIAS_CONFIG (BLOCK2) = 0 R/W (0b000) + Mac fuses: + CUSTOM_MAC_USED (BLOCK0) True if MAC_CUSTOM is burned = False R/W (0b0) + CUSTOM_MAC (BLOCK1) Custom MAC address + = 00:00:00:00:00:00 (OK) R/W + MAC (BLOCK2) MAC address + = 10:97:bd:f0:e5:28 (OK) R/W Security fuses: - DIS_DOWNLOAD_ICACHE (BLOCK0) Disables iCache in download mode = False R/W (0b0) - DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Disables flash encryption in Download boot modes = False R/W (0b0) - SPI_BOOT_CRYPT_CNT (BLOCK0) Enables encryption and decryption, when an SPI boo = Disable R/W (0b000) - t mode is set. Enabled when 1 or 3 bits are set,dis - abled otherwise + DIS_DOWNLOAD_ICACHE (BLOCK0) The bit be set to disable icache in download mode = False R/W (0b0) + DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) The bit be set to disable manual encryption = False R/W (0b0) + SPI_BOOT_CRYPT_CNT (BLOCK0) Enables flash encryption when 1 or 3 bits are set = Disable R/W (0b000) + and disables otherwise XTS_KEY_LENGTH_256 (BLOCK0) Flash encryption key length = 128 bits key R/W (0b0) - DIS_DOWNLOAD_MODE (BLOCK0) Disables all Download boot modes = False R/W (0b0) - ENABLE_SECURITY_DOWNLOAD (BLOCK0) Enables secure UART download mode (read/write flas = False R/W (0b0) - h only) - SECURE_BOOT_EN (BLOCK0) Configures secure boot = Flase R/W (0b0) + DIS_DOWNLOAD_MODE (BLOCK0) Set this bit to disable download mode (boot_mode[3 = False R/W (0b0) + :0] = 0; 1; 2; 4; 5; 6; 7) + ENABLE_SECURITY_DOWNLOAD (BLOCK0) Set this bit to enable secure UART download mode = False R/W (0b0) + SECURE_BOOT_EN (BLOCK0) The bit be set to enable secure boot = False R/W (0b0) + SECURE_VERSION (BLOCK0) Secure version for anti-rollback = 0 R/W (0x0) BLOCK_KEY0 (BLOCK3) BLOCK_KEY0 - 256-bits. 256-bit key of Flash Encryp - = 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 + = 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 tion BLOCK_KEY0_LOW_128 (BLOCK3) BLOCK_KEY0 - lower 128-bits. 128-bit key of Flash = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W Encryption BLOCK_KEY0_HI_128 (BLOCK3) BLOCK_KEY0 - higher 128-bits. 128-bits key of Secu = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W - re Boot. + re Boot - Wdt Config fuses: - WDT_DELAY_SEL (BLOCK0) RTC WDT timeout threshold = 0 R/W (0b00) + Wdt fuses: + WDT_DELAY_SEL (BLOCK0) RTC watchdog timeout threshold; in unit of slow cl = 40000 R/W (0b00) + ock cycle diff --git a/docs/en/espefuse/inc/summary_ESP32-C3.rst b/docs/en/espefuse/inc/summary_ESP32-C3.rst index c5ef0b91a..b1a19ea79 100644 --- a/docs/en/espefuse/inc/summary_ESP32-C3.rst +++ b/docs/en/espefuse/inc/summary_ESP32-C3.rst @@ -4,133 +4,151 @@ Connecting.... Detecting chip type... ESP32-C3 - EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) + + === Run "summary" command === + EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- + Calibration fuses: + K_RTC_LDO (BLOCK1) BLOCK1 K_RTC_LDO = -36 R/W (0b1001001) + K_DIG_LDO (BLOCK1) BLOCK1 K_DIG_LDO = -64 R/W (0b1010000) + V_RTC_DBIAS20 (BLOCK1) BLOCK1 voltage of rtc dbias20 = -40 R/W (0x8a) + V_DIG_DBIAS20 (BLOCK1) BLOCK1 voltage of digital dbias20 = -76 R/W (0x93) + DIG_DBIAS_HVT (BLOCK1) BLOCK1 digital dbias when hvt = -28 R/W (0b10111) + THRES_HVT (BLOCK1) BLOCK1 pvt threshold when hvt = 2000 R/W (0b0111110100) + TEMP_CALIB (BLOCK2) Temperature calibration data = -7.2 R/W (0b101001000) + OCODE (BLOCK2) ADC OCode = 78 R/W (0x4e) + ADC1_INIT_CODE_ATTEN0 (BLOCK2) ADC1 init code at atten0 = 1560 R/W (0b0110000110) + ADC1_INIT_CODE_ATTEN1 (BLOCK2) ADC1 init code at atten1 = -108 R/W (0b1000011011) + ADC1_INIT_CODE_ATTEN2 (BLOCK2) ADC1 init code at atten2 = -232 R/W (0b1000111010) + ADC1_INIT_CODE_ATTEN3 (BLOCK2) ADC1 init code at atten3 = -696 R/W (0b1010101110) + ADC1_CAL_VOL_ATTEN0 (BLOCK2) ADC1 calibration voltage at atten0 = -212 R/W (0b1000110101) + ADC1_CAL_VOL_ATTEN1 (BLOCK2) ADC1 calibration voltage at atten1 = 52 R/W (0b0000001101) + ADC1_CAL_VOL_ATTEN2 (BLOCK2) ADC1 calibration voltage at atten2 = -152 R/W (0b1000100110) + ADC1_CAL_VOL_ATTEN3 (BLOCK2) ADC1 calibration voltage at atten3 = -284 R/W (0b1001000111) + Config fuses: - DIS_ICACHE (BLOCK0) Disables ICache = False R/W (0b0) - DIS_DOWNLOAD_ICACHE (BLOCK0) Disables Icache when SoC is in Download mode = False R/W (0b0) - DIS_FORCE_DOWNLOAD (BLOCK0) Disables forcing chip into Download mode = False R/W (0b0) - DIS_CAN (BLOCK0) Disables the TWAI Controller hardware = False R/W (0b0) - VDD_SPI_AS_GPIO (BLOCK0) Set this bit to vdd spi pin function as gpio = False R/W (0b0) - BTLC_GPIO_ENABLE (BLOCK0) Enable btlc gpio = 0 R/W (0b00) - POWERGLITCH_EN (BLOCK0) Set this bit to enable power glitch function = False R/W (0b0) - POWER_GLITCH_DSENSE (BLOCK0) Sample delay configuration of power glitch = 0 R/W (0b00) - DIS_DIRECT_BOOT (BLOCK0) Disables direct boot mode = False R/W (0b0) - DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0) Selects the default UART for printing boot msg = UART0 R/W (0b0) - UART_PRINT_CONTROL (BLOCK0) Sets the default UART boot message output mode = Enabled R/W (0b00) - FORCE_SEND_RESUME (BLOCK0) Force ROM code to send a resume command during SPI = False R/W (0b0) - bootduring SPI boot - BLOCK_USR_DATA (BLOCK3) User data + WR_DIS (BLOCK0) Disable programming of individual eFuses = 0 R/W (0x00000000) + RD_DIS (BLOCK0) Disable reading from BlOCK4-10 = 0 R/W (0b0000000) + DIS_ICACHE (BLOCK0) Set this bit to disable Icache = False R/W (0b0) + DIS_TWAI (BLOCK0) Set this bit to disable CAN function = False R/W (0b0) + DIS_DIRECT_BOOT (BLOCK0) Disable direct boot mode = False R/W (0b0) + UART_PRINT_CONTROL (BLOCK0) Set the default UARTboot message output mode = Enable R/W (0b00) + ERR_RST_ENABLE (BLOCK0) Use BLOCK0 to check error record registers = with check R/W (0b1) + 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 - Efuse fuses: - WR_DIS (BLOCK0) Disables programming of individual eFuses = 0 R/W (0x00000000) - RD_DIS (BLOCK0) Disables software reading from BLOCK4-10 = 0 R/W (0b0000000) - - Flash Config fuses: - FLASH_TPUW (BLOCK0) Configures flash startup delay after SoC power-up, = 0 R/W (0x0) - unit is (ms/2). When the value is 15, delay is 7. - 5 ms - FLASH_ECC_MODE (BLOCK0) Set this bit to set flsah ecc mode. - = flash ecc 16to18 byte mode R/W (0b0) - FLASH_TYPE (BLOCK0) Selects SPI flash type = 4 data lines R/W (0b0) - FLASH_PAGE_SIZE (BLOCK0) Flash page size = 0 R/W (0b00) - FLASH_ECC_EN (BLOCK0) Enable ECC for flash boot = False R/W (0b0) + Flash fuses: + FLASH_TPUW (BLOCK0) Configures flash waiting time after power-up; in u = 0 R/W (0x0) + nit of ms. If the value is less than 15; the waiti + ng time is the configurable value; Otherwise; the + waiting time is twice the configurable value + FORCE_SEND_RESUME (BLOCK0) Set this bit to force ROM code to send a resume co = False R/W (0b0) + mmand during SPI boot Identity fuses: - SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000) - ure) - MAC (BLOCK1) Factory MAC Address - = 7c:df:a1:40:40:08: (OK) R/W - WAFER_VERSION (BLOCK1) WAFER version = (revision 0) R/W (0b000) - PKG_VERSION (BLOCK1) Package version = ESP32-C3 R/W (0x0) - BLOCK1_VERSION (BLOCK1) BLOCK1 efuse version = 0 R/W (0b000) - OPTIONAL_UNIQUE_ID (BLOCK2)(0 errors): Optional unique 128-bit ID - = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W - BLK_VERSION_MAJOR (BLOCK2) Version of BLOCK2 = No calibration R/W (0b000) - CUSTOM_MAC (BLOCK3) Custom MAC Address - = 00:00:00:00:00:00 (OK) R/W + DISABLE_WAFER_VERSION_MAJOR (BLOCK0) Disables check of wafer version major = False R/W (0b0) + DISABLE_BLK_VERSION_MAJOR (BLOCK0) Disables check of blk version major = False R/W (0b0) + WAFER_VERSION_MINOR_LO (BLOCK1) WAFER_VERSION_MINOR least significant bits = 3 R/W (0b011) + PKG_VERSION (BLOCK1) Package version = 0 R/W (0b000) + BLK_VERSION_MINOR (BLOCK1) BLK_VERSION_MINOR = 2 R/W (0b010) + WAFER_VERSION_MINOR_HI (BLOCK1) WAFER_VERSION_MINOR most significant bit = False R/W (0b0) + WAFER_VERSION_MAJOR (BLOCK1) WAFER_VERSION_MAJOR = 0 R/W (0b00) + OPTIONAL_UNIQUE_ID (BLOCK2) Optional unique 128-bit ID + = 25 60 04 96 c3 fd 41 6f be ed 2c 51 1d e3 7e 21 R/W + BLK_VERSION_MAJOR (BLOCK2) BLK_VERSION_MAJOR of BLOCK2 = With calibration R/W (0b01) + WAFER_VERSION_MINOR (BLOCK0) calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI = 3 R/W (0x3) + << 3 + WAFER_VERSION_MINOR_LO (read only) + + Jtag fuses: + SOFT_DIS_JTAG (BLOCK0) Set these bits to disable JTAG in the soft way (od = 0 R/W (0b000) + d number 1 means disable ). JTAG can be enabled in + HMAC module + DIS_PAD_JTAG (BLOCK0) Set this bit to disable JTAG in the hard way. JTAG = False R/W (0b0) + is disabled permanently - Jtag Config fuses: - JTAG_SEL_ENABLE (BLOCK0) Set this bit to enable selection between usb_to_jt = False R/W (0b0) - ag and pad_to_jtag through strapping gpio10 when b - oth reg_dis_usb_jtag and reg_dis_pad_jtag are equa - l to 0. - SOFT_DIS_JTAG (BLOCK0) Software disables JTAG. When software disabled, JT = 0 R/W (0b000) - AG can be activated temporarily by HMAC peripheral - DIS_PAD_JTAG (BLOCK0) Permanently disable JTAG access via pads. USB JTAG = False R/W (0b0) - is controlled separately. + Mac fuses: + MAC (BLOCK1) MAC address + = 58:cf:79:0f:96:8c (OK) R/W + CUSTOM_MAC (BLOCK3) Custom MAC address + = 00:00:00:00:00:00 (OK) R/W Security fuses: - DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Disables flash encryption when in download boot mo = False R/W (0b0) - des - SPI_BOOT_CRYPT_CNT (BLOCK0) Enables encryption and decryption, when an SPI boo = Disable R/W (0b000) - t mode is set. Enabled when 1 or 3 bits are set,di - sabled otherwise - SECURE_BOOT_KEY_REVOKE0 (BLOCK0) If set, revokes use of secure boot key digest 0 = False R/W (0b0) - SECURE_BOOT_KEY_REVOKE1 (BLOCK0) If set, revokes use of secure boot key digest 1 = False R/W (0b0) - SECURE_BOOT_KEY_REVOKE2 (BLOCK0) If set, revokes use of secure boot key digest 2 = False R/W (0b0) - KEY_PURPOSE_0 (BLOCK0) KEY0 purpose = USER R/W (0x0) - KEY_PURPOSE_1 (BLOCK0) KEY1 purpose = USER R/W (0x0) - KEY_PURPOSE_2 (BLOCK0) KEY2 purpose = USER R/W (0x0) - KEY_PURPOSE_3 (BLOCK0) KEY3 purpose = USER R/W (0x0) - KEY_PURPOSE_4 (BLOCK0) KEY4 purpose = USER R/W (0x0) - KEY_PURPOSE_5 (BLOCK0) KEY5 purpose = USER R/W (0x0) - SECURE_BOOT_EN (BLOCK0) Enables secure boot = False R/W (0b0) - SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0) Enables aggressive secure boot key revocation mode = False R/W (0b0) - DIS_DOWNLOAD_MODE (BLOCK0) Disables all Download boot modes = False R/W (0b0) - ENABLE_SECURITY_DOWNLOAD (BLOCK0) Enables secure UART download mode (read/write flas = False R/W (0b0) - h only) - BLOCK_KEY0 (BLOCK4)(0 errors): + DIS_DOWNLOAD_ICACHE (BLOCK0) Set this bit to disable Icache in download mode (b = False R/W (0b0) + oot_mode[3:0] is 0; 1; 2; 3; 6; 7) + DIS_FORCE_DOWNLOAD (BLOCK0) Set this bit to disable the function that forces c = False R/W (0b0) + hip into download mode + DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Set this bit to disable flash encryption when in d = False R/W (0b0) + ownload boot modes + 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) Purpose of Key0 = USER R/W (0x0) + KEY_PURPOSE_1 (BLOCK0) Purpose of Key1 = USER R/W (0x0) + KEY_PURPOSE_2 (BLOCK0) Purpose of Key2 = USER R/W (0x0) + KEY_PURPOSE_3 (BLOCK0) Purpose of Key3 = USER R/W (0x0) + KEY_PURPOSE_4 (BLOCK0) Purpose of Key4 = USER R/W (0x0) + KEY_PURPOSE_5 (BLOCK0) Purpose of Key5 = USER R/W (0x0) + SECURE_BOOT_EN (BLOCK0) Set this bit to enable secure boot = False R/W (0b0) + SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0) Set this bit to enable revoking aggressive secure = False R/W (0b0) + boot + DIS_DOWNLOAD_MODE (BLOCK0) Set this bit to disable download mode (boot_mode[3 = False R/W (0b0) + :0] = 0; 1; 2; 3; 6; 7) + ENABLE_SECURITY_DOWNLOAD (BLOCK0) Set this bit to enable secure UART download mode = False R/W (0b0) + SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000) + ure) + BLOCK_KEY0 (BLOCK4) Purpose: USER - Encryption key0 or user data + 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)(0 errors): + BLOCK_KEY1 (BLOCK5) Purpose: USER - Encryption key1 or user data + 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)(0 errors): + BLOCK_KEY2 (BLOCK6) Purpose: USER - Encryption key2 or user data + 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)(0 errors): + BLOCK_KEY3 (BLOCK7) Purpose: USER - Encryption key3 or user data + 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)(0 errors): + BLOCK_KEY4 (BLOCK8) Purpose: USER - Encryption key4 or user data + 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)(0 errors): + BLOCK_KEY5 (BLOCK9) Purpose: USER - Encryption 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 - BLOCK_SYS_DATA2 (BLOCK10)(0 errors): System data (part 2) + 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 - Spi_Pad_Config fuses: - SPI_PAD_CONFIG_CLK (BLOCK1) SPI CLK pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_Q (BLOCK1) SPI Q (D1) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D (BLOCK1) SPI D (D0) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_CS (BLOCK1) SPI CS pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_HD (BLOCK1) SPI HD (D3) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_WP (BLOCK1) SPI WP (D2) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_DQS (BLOCK1) SPI DQS pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D4 (BLOCK1) SPI D4 pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D5 (BLOCK1) SPI D5 pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D6 (BLOCK1) SPI D6 pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D7 (BLOCK1) SPI D7 pad = 0 R/W (0b000000) + Spi Pad fuses: + SPI_PAD_CONFIG_CLK (BLOCK1) SPI PAD CLK = 0 R/W (0b000000) + SPI_PAD_CONFIG_Q (BLOCK1) SPI PAD Q(D1) = 0 R/W (0b000000) + SPI_PAD_CONFIG_D (BLOCK1) SPI PAD D(D0) = 0 R/W (0b000000) + SPI_PAD_CONFIG_CS (BLOCK1) SPI PAD CS = 0 R/W (0b000000) + SPI_PAD_CONFIG_HD (BLOCK1) SPI PAD HD(D3) = 0 R/W (0b000000) + SPI_PAD_CONFIG_WP (BLOCK1) SPI PAD WP(D2) = 0 R/W (0b000000) + SPI_PAD_CONFIG_DQS (BLOCK1) SPI PAD DQS = 0 R/W (0b000000) + SPI_PAD_CONFIG_D4 (BLOCK1) SPI PAD D4 = 0 R/W (0b000000) + SPI_PAD_CONFIG_D5 (BLOCK1) SPI PAD D5 = 0 R/W (0b000000) + SPI_PAD_CONFIG_D6 (BLOCK1) SPI PAD D6 = 0 R/W (0b000000) + SPI_PAD_CONFIG_D7 (BLOCK1) SPI PAD D7 = 0 R/W (0b000000) - Usb Config fuses: - DIS_USB_JTAG (BLOCK0) Disables USB JTAG. JTAG access via pads is control = False R/W (0b0) - led separately - DIS_USB_DEVICE (BLOCK0) Disables USB DEVICE = False R/W (0b0) - DIS_USB (BLOCK0) Disables the USB OTG hardware = False R/W (0b0) - USB_EXCHG_PINS (BLOCK0) Exchanges USB D+ and D- pins = False R/W (0b0) - DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0) Disables download through USB-Serial-JTAG = False R/W (0b0) + Usb fuses: + DIS_USB_JTAG (BLOCK0) Set this bit to disable function of usb switch to = False R/W (0b0) + jtag in module of usb device + DIS_USB_SERIAL_JTAG (BLOCK0) USB-Serial-JTAG = Enable R/W (0b0) + USB_EXCHG_PINS (BLOCK0) Set this bit to exchange USB D+ and D- pins = False R/W (0b0) + DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0) USB printing = Enable R/W (0b0) + DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0) Disable UART download mode through USB-Serial-JTAG = False R/W (0b0) - Vdd_Spi Config fuses: - PIN_POWER_SELECTION (BLOCK0) GPIO33-GPIO37 power supply selection in ROM code = VDD3P3_CPU R/W (0b0) + Vdd fuses: + VDD_SPI_AS_GPIO (BLOCK0) Set this bit to vdd spi pin function as gpio = False R/W (0b0) - Wdt Config fuses: - WDT_DELAY_SEL (BLOCK0) Selects RTC WDT timeout threshold at startup = False R/W (0b0) + Wdt fuses: + WDT_DELAY_SEL (BLOCK0) RTC watchdog timeout threshold; in unit of slow cl = 40000 R/W (0b00) + ock cycle diff --git a/docs/en/espefuse/inc/summary_ESP32-C6.rst b/docs/en/espefuse/inc/summary_ESP32-C6.rst new file mode 100644 index 000000000..39411b778 --- /dev/null +++ b/docs/en/espefuse/inc/summary_ESP32-C6.rst @@ -0,0 +1,155 @@ +.. code-block:: none + + > espefuse.py -p PORT summary + + Connecting.... + Detecting chip type... ESP32-C6 + + === 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) + SWAP_UART_SDIO_EN (BLOCK0) Represents whether pad of uart and sdio is swapped = False R/W (0b0) + or not. 1: swapped. 0: not swapped + DIS_ICACHE (BLOCK0) Represents whether icache is disabled or enabled. = False R/W (0b0) + 1: disabled. 0: enabled + DIS_TWAI (BLOCK0) Represents whether TWAI function is disabled or en = False R/W (0b0) + abled. 1: disabled. 0: enabled + 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) Set the default UARTboot message output mode = Enable R/W (0b00) + 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_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 + FLASH_CAP (BLOCK1) = 0 R/W (0b000) + FLASH_TEMP (BLOCK1) = 0 R/W (0b00) + FLASH_VENDOR (BLOCK1) = 0 R/W (0b000) + + Identity fuses: + DISABLE_WAFER_VERSION_MAJOR (BLOCK0) Disables check of wafer version major = False R/W (0b0) + DISABLE_BLK_VERSION_MAJOR (BLOCK0) Disables check of blk version major = False R/W (0b0) + WAFER_VERSION_MINOR (BLOCK1) = 0 R/W (0x0) + WAFER_VERSION_MAJOR (BLOCK1) = 0 R/W (0b00) + BLK_VERSION_MINOR (BLOCK1) BLK_VERSION_MINOR of BLOCK2 = 0 R/W (0b000) + BLK_VERSION_MAJOR (BLOCK1) BLK_VERSION_MAJOR of BLOCK2 = 0 R/W (0b00) + PKG_VERSION (BLOCK1) Package version = 0 R/W (0b000) + OPTIONAL_UNIQUE_ID (BLOCK2) Optional unique 128-bit ID + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + + 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 + = 60:55:f9:f6:03:24 (OK) R/W + MAC_EXT (BLOCK1) Stores the extended bits of MAC address = 00:00 (OK) R/W + CUSTOM_MAC (BLOCK3) Custom MAC + = 00:00:00:00:00:00 (OK) R/W + + Security fuses: + DIS_DOWNLOAD_ICACHE (BLOCK0) Represents whether icache is disabled or enabled i = False R/W (0b0) + n Download mode. 1: disabled. 0: enabled + 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) Represents whether SPI0 controller during boot_mod = False R/W (0b0) + e_download is disabled or enabled. 1: disabled. 0: + enabled + 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 + 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 + 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 + 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: + 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 + DIS_USB_SERIAL_JTAG (BLOCK0) Represents whether USB-Serial-JTAG is disabled or = False R/W (0b0) + enabled. 1: disabled. 0: enabled + USB_EXCHG_PINS (BLOCK0) Represents whether the D+ and D- pins is exchanged = False R/W (0b0) + . 1: exchanged. 0: not exchanged + 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 + + Vdd fuses: + VDD_SPI_AS_GPIO (BLOCK0) Represents whether vdd spi pin is functioned as gp = False R/W (0b0) + io. 1: functioned. 0: not functioned + + 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 diff --git a/docs/en/espefuse/inc/summary_ESP32-H2.rst b/docs/en/espefuse/inc/summary_ESP32-H2.rst new file mode 100644 index 000000000..0032586bd --- /dev/null +++ b/docs/en/espefuse/inc/summary_ESP32-H2.rst @@ -0,0 +1,155 @@ +.. code-block:: none + + > espefuse.py -p PORT summary + + Connecting.... + Detecting chip type... ESP32-H2 + + === 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) + DIS_ICACHE (BLOCK0) Represents whether icache is disabled or enabled. = False R/W (0b0) + 1: disabled. 0: enabled + 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 + 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) Set the default UARTboot message output mode = Enable R/W (0b00) + HYS_EN_PAD0 (BLOCK0) Set bits to enable hysteresis function of PAD0~5 = 0 R/W (0b000000) + HYS_EN_PAD1 (BLOCK0) Set bits to enable hysteresis function of PAD6~27 = 0 R/W (0b0000000000000000000000) + 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_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 + FLASH_CAP (BLOCK1) = 0 R/W (0b000) + FLASH_TEMP (BLOCK1) = 0 R/W (0b00) + FLASH_VENDOR (BLOCK1) = 0 R/W (0b000) + + Identity fuses: + WAFER_VERSION_MINOR (BLOCK1) = 0 R/W (0b000) + WAFER_VERSION_MAJOR (BLOCK1) = 0 R/W (0b00) + DISABLE_WAFER_VERSION_MAJOR (BLOCK1) Disables check of wafer version major = False R/W (0b0) + PKG_VERSION (BLOCK1) Package version = 0 R/W (0b000) + OPTIONAL_UNIQUE_ID (BLOCK2) Optional unique 128-bit ID + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + BLK_VERSION_MINOR (BLOCK2) BLK_VERSION_MINOR of BLOCK2 = 0 R/W (0b000) + BLK_VERSION_MAJOR (BLOCK2) BLK_VERSION_MAJOR of BLOCK2 = 0 R/W (0b00) + DISABLE_BLK_VERSION_MAJOR (BLOCK2) Disables check of blk version major = False R/W (0b0) + + Jtag fuses: + JTAG_SEL_ENABLE (BLOCK0) Set this bit to enable selection between usb_to_jt = False R/W (0b0) + ag and pad_to_jtag through strapping gpio25 when b + oth EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are + equal to 0 + 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 + = 60:55:f9:f7:2c:05 (OK) R/W + MAC_EXT (BLOCK1) Stores the extended bits of MAC address = ff:fe (OK) R/W + CUSTOM_MAC (BLOCK3) Custom MAC + = 00:00:00:00:00:00 (OK) R/W + + 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) Represents whether SPI0 controller during boot_mod = False R/W (0b0) + e_download is disabled or enabled. 1: disabled. 0: + enabled + 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 + 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_FORCE_USE_HARDWARE_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 + 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: + 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_EXCHG_PINS (BLOCK0) Represents whether the D+ and D- pins is exchanged = False R/W (0b0) + . 1: exchanged. 0: not exchanged + DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0) Set this bit to disable USB-Serial-JTAG print duri = False R/W (0b0) + ng rom boot + 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 + + Vdd fuses: + VDD_SPI_AS_GPIO (BLOCK0) Represents whether vdd spi pin is functioned as gp = False R/W (0b0) + io. 1: functioned. 0: not functioned + + 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 diff --git a/docs/en/espefuse/inc/summary_ESP32-P4.rst b/docs/en/espefuse/inc/summary_ESP32-P4.rst new file mode 100644 index 000000000..74421869c --- /dev/null +++ b/docs/en/espefuse/inc/summary_ESP32-P4.rst @@ -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 --git a/docs/en/espefuse/inc/summary_ESP32-S2.rst b/docs/en/espefuse/inc/summary_ESP32-S2.rst index cfc61535f..85617bfa4 100644 --- a/docs/en/espefuse/inc/summary_ESP32-S2.rst +++ b/docs/en/espefuse/inc/summary_ESP32-S2.rst @@ -4,149 +4,169 @@ Connecting.... Detecting chip type... ESP32-S2 - EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) + + === Run "summary" command === + EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Calibration fuses: - TEMP_SENSOR_CAL (BLOCK2) Temperature calibration = -9.200000000000001 R/W (0b101011100) - ADC1_MODE0_D2 (BLOCK2) ADC1 calibration 1 = -28 R/W (0x87) - ADC1_MODE1_D2 (BLOCK2) ADC1 calibration 2 = -28 R/W (0x87) - ADC1_MODE2_D2 (BLOCK2) ADC1 calibration 3 = -28 R/W (0x87) - ADC1_MODE3_D2 (BLOCK2) ADC1 calibration 4 = -24 R/W (0x86) - ADC2_MODE0_D2 (BLOCK2) ADC2 calibration 5 = 12 R/W (0x03) - ADC2_MODE1_D2 (BLOCK2) ADC2 calibration 6 = 8 R/W (0x02) - ADC2_MODE2_D2 (BLOCK2) ADC2 calibration 7 = 12 R/W (0x03) - ADC2_MODE3_D2 (BLOCK2) ADC2 calibration 8 = 16 R/W (0x04) - ADC1_MODE0_D1 (BLOCK2) ADC1 calibration 9 = -20 R/W (0b100101) - ADC1_MODE1_D1 (BLOCK2) ADC1 calibration 10 = -12 R/W (0b100011) - ADC1_MODE2_D1 (BLOCK2) ADC1 calibration 11 = -12 R/W (0b100011) - ADC1_MODE3_D1 (BLOCK2) ADC1 calibration 12 = -4 R/W (0b100001) - ADC2_MODE0_D1 (BLOCK2) ADC2 calibration 13 = -12 R/W (0b100011) - ADC2_MODE1_D1 (BLOCK2) ADC2 calibration 14 = -8 R/W (0b100010) - ADC2_MODE2_D1 (BLOCK2) ADC2 calibration 15 = -8 R/W (0b100010) - ADC2_MODE3_D1 (BLOCK2) ADC2 calibration 16 = -4 R/W (0b100001) + ADC_CALIB (BLOCK2) 4 bit of ADC calibration = 0 R/W (0x0) + TEMP_CALIB (BLOCK2) Temperature calibration data = 3.2 R/W (0b000100000) + RTCCALIB_V1IDX_A10H (BLOCK2) = 55 R/W (0x37) + RTCCALIB_V1IDX_A11H (BLOCK2) = 51 R/W (0x33) + RTCCALIB_V1IDX_A12H (BLOCK2) = 52 R/W (0x34) + RTCCALIB_V1IDX_A13H (BLOCK2) = 53 R/W (0x35) + RTCCALIB_V1IDX_A20H (BLOCK2) = 56 R/W (0x38) + RTCCALIB_V1IDX_A21H (BLOCK2) = 55 R/W (0x37) + RTCCALIB_V1IDX_A22H (BLOCK2) = 55 R/W (0x37) + RTCCALIB_V1IDX_A23H (BLOCK2) = 59 R/W (0x3b) + RTCCALIB_V1IDX_A10L (BLOCK2) = 25 R/W (0b011001) + RTCCALIB_V1IDX_A11L (BLOCK2) = 17 R/W (0b010001) + RTCCALIB_V1IDX_A12L (BLOCK2) = 14 R/W (0b001110) + RTCCALIB_V1IDX_A13L (BLOCK2) = 7 R/W (0b000111) + RTCCALIB_V1IDX_A20L (BLOCK2) = 19 R/W (0b010011) + RTCCALIB_V1IDX_A21L (BLOCK2) = 14 R/W (0b001110) + RTCCALIB_V1IDX_A22L (BLOCK2) = 10 R/W (0b001010) + RTCCALIB_V1IDX_A23L (BLOCK2) = 6 R/W (0b000110) Config fuses: - DIS_RTC_RAM_BOOT (BLOCK0) Disables boot from RTC RAM = False R/W (0b0) - DIS_ICACHE (BLOCK0) Disables ICache = False R/W (0b0) - DIS_DCACHE (BLOCK0) Disables DCache = False R/W (0b0) - DIS_DOWNLOAD_ICACHE (BLOCK0) Disables Icache when SoC is in Download mode = False R/W (0b0) - DIS_DOWNLOAD_DCACHE (BLOCK0) Disables Dcache when SoC is in Download mode = False R/W (0b0) - DIS_FORCE_DOWNLOAD (BLOCK0) Disables forcing chip into Download mode = False R/W (0b0) - DIS_CAN (BLOCK0) Disables the TWAI Controller hardware = False R/W (0b0) - DIS_BOOT_REMAP (BLOCK0) Disables capability to Remap RAM to ROM address sp = False R/W (0b0) - ace - FLASH_TPUW (BLOCK0) Configures flash startup delay after SoC power-up, = 0 R/W (0x0) - unit is (ms/2). When the value is 15, delay is 7. - 5 ms - DIS_LEGACY_SPI_BOOT (BLOCK0) Disables Legacy SPI boot mode = False R/W (0b0) - UART_PRINT_CHANNEL (BLOCK0) Selects the default UART for printing boot msg = UART0 R/W (0b0) - DIS_USB_DOWNLOAD_MODE (BLOCK0) Disables use of USB in UART download boot mode = False R/W (0b0) - UART_PRINT_CONTROL (BLOCK0) Sets the default UART boot message output mode = Enabled R/W (0b00) - FLASH_TYPE (BLOCK0) Selects SPI flash type = 4 data lines R/W (0b0) - FORCE_SEND_RESUME (BLOCK0) Forces ROM code to send an SPI flash resume comman = False R/W (0b0) - d during SPI boot - BLOCK_USR_DATA (BLOCK3) User data + WR_DIS (BLOCK0) Disable programming of individual eFuses = 0 R/W (0x00000000) + RD_DIS (BLOCK0) Disable reading from BlOCK4-10 = 0 R/W (0b0000000) + DIS_ICACHE (BLOCK0) Set this bit to disable Icache = False R/W (0b0) + DIS_DCACHE (BLOCK0) Set this bit to disable Dcache = False R/W (0b0) + DIS_TWAI (BLOCK0) Set this bit to disable the TWAI Controller functi = False R/W (0b0) + on + DIS_BOOT_REMAP (BLOCK0) Disables capability to Remap RAM to ROM address sp = False R/W (0b0) + ace + DIS_LEGACY_SPI_BOOT (BLOCK0) Set this bit to disable Legacy SPI boot mode = False R/W (0b0) + UART_PRINT_CHANNEL (BLOCK0) Selects the default UART for printing boot message = UART0 R/W (0b0) + s + UART_PRINT_CONTROL (BLOCK0) Set the default UART boot message output mode = Enable R/W (0b00) + PIN_POWER_SELECTION (BLOCK0) Set default power supply for GPIO33-GPIO37; set wh = VDD3P3_CPU R/W (0b0) + en SPI flash is initialized + 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 - Efuse fuses: - WR_DIS (BLOCK0) Disables programming of individual eFuses = 0 R/W (0x00000000) - RD_DIS (BLOCK0) Disables software reading from BLOCK4-10 = 0 R/W (0b0000000) + Flash fuses: + FLASH_TPUW (BLOCK0) Configures flash startup delay after SoC power-up; = 0 R/W (0x0) + in unit of (ms/2). When the value is 15; delay is + 7.5 ms + FLASH_TYPE (BLOCK0) SPI flash type = 4 data lines R/W (0b0) + FORCE_SEND_RESUME (BLOCK0) If set; forces ROM code to send an SPI flash resum = False R/W (0b0) + e command during SPI boot + FLASH_VERSION (BLOCK1) Flash version = 1 R/W (0x1) Identity fuses: - BLOCK0_VERSION (BLOCK0) BLOCK0 efuse version = 0 R/W (0b00) - SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000) - ure) - MAC (BLOCK1) Factory MAC Address - = 7c:df:a1:00:3a:6e: (OK) R/W - WAFER_VERSION (BLOCK1) WAFER version = A R/W (0b000) - PKG_VERSION (BLOCK1) Package version - = ESP32-S2, QFN 7x7 56 pins R/W (0x0) - BLOCK1_VERSION (BLOCK1) BLOCK1 efuse version = 0 R/W (0b000) - OPTIONAL_UNIQUE_ID (BLOCK2)(0 errors): Optional unique 128-bit ID - = 7d 33 b8 bb 0b 13 b3 c8 71 37 0e e8 7c ab d5 92 R/W - BLK_VERSION_MINOR (BLOCK2) Version of BLOCK2 = With calibration R/W (0b001) - CUSTOM_MAC (BLOCK3) Custom MAC Address + BLOCK0_VERSION (BLOCK0) BLOCK0 efuse version = 0 R/W (0b00) + DISABLE_WAFER_VERSION_MAJOR (BLOCK0) Disables check of wafer version major = False R/W (0b0) + DISABLE_BLK_VERSION_MAJOR (BLOCK0) Disables check of blk version major = False R/W (0b0) + WAFER_VERSION_MAJOR (BLOCK1) WAFER_VERSION_MAJOR = 0 R/W (0b00) + WAFER_VERSION_MINOR_HI (BLOCK1) WAFER_VERSION_MINOR most significant bit = False R/W (0b0) + BLK_VERSION_MAJOR (BLOCK1) BLK_VERSION_MAJOR = 0 R/W (0b00) + PSRAM_VERSION (BLOCK1) PSRAM version = 0 R/W (0x0) + PKG_VERSION (BLOCK1) Package version = 0 R/W (0x0) + WAFER_VERSION_MINOR_LO (BLOCK1) WAFER_VERSION_MINOR least significant bits = 0 R/W (0b000) + OPTIONAL_UNIQUE_ID (BLOCK2) Optional unique 128-bit ID + = d9 8f 05 d0 86 77 53 db 80 6c ee 40 df 5d ef b0 R/W + BLK_VERSION_MINOR (BLOCK2) BLK_VERSION_MINOR of BLOCK2 = ADC calib V1 R/W (0b001) + WAFER_VERSION_MINOR (BLOCK0) calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI = 0 R/W (0x0) + << 3 + WAFER_VERSION_MINOR_LO (read only) + + Jtag fuses: + SOFT_DIS_JTAG (BLOCK0) Software disables JTAG. When software disabled; JT = False R/W (0b0) + AG can be activated temporarily by HMAC peripheral + HARD_DIS_JTAG (BLOCK0) Hardware disables JTAG permanently = False R/W (0b0) + + Mac fuses: + MAC (BLOCK1) MAC address + = 7c:df:a1:00:48:34 (OK) R/W + CUSTOM_MAC (BLOCK3) Custom MAC = 00:00:00:00:00:00 (OK) R/W Security fuses: - SOFT_DIS_JTAG (BLOCK0) Software disables JTAG. When software disabled, JT = False R/W (0b0) - AG can be activated temporarily by HMAC peripheral - HARD_DIS_JTAG (BLOCK0) Hardware disables JTAG permanently = False R/W (0b0) - DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Disables flash encryption when in download boot mo = False R/W (0b0) - des - SPI_BOOT_CRYPT_CNT (BLOCK0) Enables encryption and decryption, when an SPI boo = Disable R/W (0b000) - t mode is set. Enabled when 1 or 3 bits are set,di - sabled otherwise - SECURE_BOOT_KEY_REVOKE0 (BLOCK0) If set, revokes use of secure boot key digest 0 = False R/W (0b0) - SECURE_BOOT_KEY_REVOKE1 (BLOCK0) If set, revokes use of secure boot key digest 1 = False R/W (0b0) - SECURE_BOOT_KEY_REVOKE2 (BLOCK0) If set, revokes use of secure boot key digest 2 = False R/W (0b0) - KEY_PURPOSE_0 (BLOCK0) KEY0 purpose = USER R/W (0x0) - KEY_PURPOSE_1 (BLOCK0) KEY1 purpose = USER R/W (0x0) - KEY_PURPOSE_2 (BLOCK0) KEY2 purpose = USER R/W (0x0) - KEY_PURPOSE_3 (BLOCK0) KEY3 purpose = USER R/W (0x0) - KEY_PURPOSE_4 (BLOCK0) KEY4 purpose = USER R/W (0x0) - KEY_PURPOSE_5 (BLOCK0) KEY5 purpose = USER R/W (0x0) - SECURE_BOOT_EN (BLOCK0) Enables secure boot = False R/W (0b0) - SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0) Enables aggressive secure boot key revocation mode = False R/W (0b0) - DIS_DOWNLOAD_MODE (BLOCK0) Disables all Download boot modes = False R/W (0b0) - ENABLE_SECURITY_DOWNLOAD (BLOCK0) Enables secure UART download mode (read/write flas = False R/W (0b0) - h only) - BLOCK_KEY0 (BLOCK4)(0 errors): + DIS_DOWNLOAD_ICACHE (BLOCK0) Disables Icache when SoC is in Download mode = False R/W (0b0) + DIS_DOWNLOAD_DCACHE (BLOCK0) Disables Dcache when SoC is in Download mode = False R/W (0b0) + DIS_FORCE_DOWNLOAD (BLOCK0) Set this bit to disable the function that forces c = False R/W (0b0) + hip into download mode + DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Disables flash encryption when in download boot mo = False R/W (0b0) + des + SPI_BOOT_CRYPT_CNT (BLOCK0) Enables flash encryption when 1 or 3 bits are set = Disable R/W (0b000) + and disabled 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) Purpose of KEY0 = USER R/W (0x0) + KEY_PURPOSE_1 (BLOCK0) Purpose of KEY1 = USER R/W (0x0) + KEY_PURPOSE_2 (BLOCK0) Purpose of KEY2 = USER R/W (0x0) + KEY_PURPOSE_3 (BLOCK0) Purpose of KEY3 = USER R/W (0x0) + KEY_PURPOSE_4 (BLOCK0) Purpose of KEY4 = USER R/W (0x0) + KEY_PURPOSE_5 (BLOCK0) Purpose of KEY5 = USER R/W (0x0) + SECURE_BOOT_EN (BLOCK0) Set this bit to enable secure boot = False R/W (0b0) + SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0) Set this bit to enable aggressive secure boot key = False R/W (0b0) + revocation mode + DIS_DOWNLOAD_MODE (BLOCK0) Set this bit to disable all download boot modes = False R/W (0b0) + ENABLE_SECURITY_DOWNLOAD (BLOCK0) Set this bit to enable secure UART download mode ( = False R/W (0b0) + read/write flash only) + SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000) + ure) + BLOCK_KEY0 (BLOCK4) Purpose: USER - Encryption key0 or user data + 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)(0 errors): + BLOCK_KEY1 (BLOCK5) Purpose: USER - Encryption key1 or user data + 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)(0 errors): + BLOCK_KEY2 (BLOCK6) Purpose: USER - Encryption key2 or user data + 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)(0 errors): + BLOCK_KEY3 (BLOCK7) Purpose: USER - Encryption key3 or user data + 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)(0 errors): + BLOCK_KEY4 (BLOCK8) Purpose: USER - Encryption key4 or user data + 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)(0 errors): + BLOCK_KEY5 (BLOCK9) Purpose: USER - Encryption 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 - BLOCK_SYS_DATA2 (BLOCK10) System data (part 2) + 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 - Spi_Pad_Config fuses: - SPI_PAD_CONFIG_CLK (BLOCK1) SPI CLK pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_Q (BLOCK1) SPI Q (D1) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D (BLOCK1) SPI D (D0) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_CS (BLOCK1) SPI CS pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_HD (BLOCK1) SPI HD (D3) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_WP (BLOCK1) SPI WP (D2) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_DQS (BLOCK1) SPI DQS pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D4 (BLOCK1) SPI D4 pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D5 (BLOCK1) SPI D5 pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D6 (BLOCK1) SPI D6 pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D7 (BLOCK1) SPI D7 pad = 0 R/W (0b000000) + Spi Pad fuses: + SPI_PAD_CONFIG_CLK (BLOCK1) SPI_PAD_configure CLK = 0 R/W (0b000000) + SPI_PAD_CONFIG_Q (BLOCK1) SPI_PAD_configure Q(D1) = 0 R/W (0b000000) + SPI_PAD_CONFIG_D (BLOCK1) SPI_PAD_configure D(D0) = 0 R/W (0b000000) + SPI_PAD_CONFIG_CS (BLOCK1) SPI_PAD_configure CS = 0 R/W (0b000000) + SPI_PAD_CONFIG_HD (BLOCK1) SPI_PAD_configure HD(D3) = 0 R/W (0b000000) + SPI_PAD_CONFIG_WP (BLOCK1) SPI_PAD_configure WP(D2) = 0 R/W (0b000000) + SPI_PAD_CONFIG_DQS (BLOCK1) SPI_PAD_configure DQS = 0 R/W (0b000000) + SPI_PAD_CONFIG_D4 (BLOCK1) SPI_PAD_configure D4 = 0 R/W (0b000000) + SPI_PAD_CONFIG_D5 (BLOCK1) SPI_PAD_configure D5 = 0 R/W (0b000000) + SPI_PAD_CONFIG_D6 (BLOCK1) SPI_PAD_configure D6 = 0 R/W (0b000000) + SPI_PAD_CONFIG_D7 (BLOCK1) SPI_PAD_configure D7 = 0 R/W (0b000000) - Usb Config fuses: - DIS_USB (BLOCK0) Disables the USB OTG hardware = False R/W (0b0) - USB_EXCHG_PINS (BLOCK0) Exchanges USB D+ and D- pins = False R/W (0b0) - EXT_PHY_ENABLE (BLOCK0) Enables external USB PHY = False R/W (0b0) - USB_FORCE_NOPERSIST (BLOCK0) Forces to set USB BVALID to 1 = False R/W (0b0) + Usb fuses: + DIS_USB (BLOCK0) Set this bit to disable USB OTG function = False R/W (0b0) + USB_EXCHG_PINS (BLOCK0) Set this bit to exchange USB D+ and D- pins = False R/W (0b0) + USB_EXT_PHY_ENABLE (BLOCK0) Set this bit to enable external USB PHY = False R/W (0b0) + USB_FORCE_NOPERSIST (BLOCK0) If set; forces USB BVALID to 1 = False R/W (0b0) + DIS_USB_DOWNLOAD_MODE (BLOCK0) Set this bit to disable use of USB OTG in UART dow = False R/W (0b0) + nload boot mode - Vdd_Spi Config fuses: - VDD_SPI_FORCE (BLOCK0) Force using VDD_SPI_XPD and VDD_SPI_TIEH to config = False R/W (0b0) - ure VDD_SPI LDO - VDD_SPI_XPD (BLOCK0) The VDD_SPI regulator is powered on = False R/W (0b0) - VDD_SPI_TIEH (BLOCK0) The VDD_SPI power supply voltage at reset = Connect to 1.8V LDO R/W (0b0) - PIN_POWER_SELECTION (BLOCK0) Sets default power supply for GPIO33..37, set when = VDD3P3_CPU R/W (0b0) - SPI flash is initialized + Vdd fuses: + VDD_SPI_XPD (BLOCK0) If VDD_SPI_FORCE is 1; this value determines if th = False R/W (0b0) + e VDD_SPI regulator is powered on + VDD_SPI_TIEH (BLOCK0) If VDD_SPI_FORCE is 1; determines VDD_SPI voltage + = VDD_SPI connects to 1.8 V LDO R/W (0b0) + VDD_SPI_FORCE (BLOCK0) Set this bit to use XPD_VDD_PSI_REG and VDD_SPI_TI = False R/W (0b0) + EH to configure VDD_SPI LDO - Wdt Config fuses: - WDT_DELAY_SEL (BLOCK0) Selects RTC WDT timeout threshold at startup = 0 R/W (0b00) + Wdt fuses: + WDT_DELAY_SEL (BLOCK0) RTC watchdog timeout threshold; in unit of slow cl = 40000 R/W (0b00) + ock cycle Flash voltage (VDD_SPI) determined by GPIO45 on reset (GPIO45=High: VDD_SPI pin is powered from internal 1.8V LDO GPIO45=Low or NC: VDD_SPI pin is powered directly from VDD3P3_RTC_IO via resistor Rspi. Typically this voltage is 3.3 V). diff --git a/docs/en/espefuse/inc/summary_ESP32-S3.rst b/docs/en/espefuse/inc/summary_ESP32-S3.rst index 603f64239..25c64ac27 100644 --- a/docs/en/espefuse/inc/summary_ESP32-S3.rst +++ b/docs/en/espefuse/inc/summary_ESP32-S3.rst @@ -4,148 +4,160 @@ Connecting.... Detecting chip type... ESP32-S3 - EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) - ---------------------------------------------------------------------------------------- - Calibration fuses: - TEMP_SENSOR_CAL (BLOCK2) Temperature calibration = -9.200000000000001 R/W (0b101011100) - ADC1_MODE0_D2 (BLOCK2) ADC1 calibration 1 = -28 R/W (0x87) - ADC1_MODE1_D2 (BLOCK2) ADC1 calibration 2 = -28 R/W (0x87) - ADC1_MODE2_D2 (BLOCK2) ADC1 calibration 3 = -28 R/W (0x87) - ADC1_MODE3_D2 (BLOCK2) ADC1 calibration 4 = -24 R/W (0x86) - ADC2_MODE0_D2 (BLOCK2) ADC2 calibration 5 = 12 R/W (0x03) - ADC2_MODE1_D2 (BLOCK2) ADC2 calibration 6 = 8 R/W (0x02) - ADC2_MODE2_D2 (BLOCK2) ADC2 calibration 7 = 12 R/W (0x03) - ADC2_MODE3_D2 (BLOCK2) ADC2 calibration 8 = 16 R/W (0x04) - ADC1_MODE0_D1 (BLOCK2) ADC1 calibration 9 = -20 R/W (0b100101) - ADC1_MODE1_D1 (BLOCK2) ADC1 calibration 10 = -12 R/W (0b100011) - ADC1_MODE2_D1 (BLOCK2) ADC1 calibration 11 = -12 R/W (0b100011) - ADC1_MODE3_D1 (BLOCK2) ADC1 calibration 12 = -4 R/W (0b100001) - ADC2_MODE0_D1 (BLOCK2) ADC2 calibration 13 = -12 R/W (0b100011) - ADC2_MODE1_D1 (BLOCK2) ADC2 calibration 14 = -8 R/W (0b100010) - ADC2_MODE2_D1 (BLOCK2) ADC2 calibration 15 = -8 R/W (0b100010) - ADC2_MODE3_D1 (BLOCK2) ADC2 calibration 16 = -4 R/W (0b100001) + === Run "summary" command === + EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) + ---------------------------------------------------------------------------------------- Config fuses: - DIS_ICACHE (BLOCK0) Disables ICache = False R/W (0b0) - DIS_DCACHE (BLOCK0) Disables DCache = False R/W (0b0) - DIS_DOWNLOAD_ICACHE (BLOCK0) Disables Icache when SoC is in Download mode = False R/W (0b0) - DIS_DOWNLOAD_DCACHE (BLOCK0) Disables Dcache when SoC is in Download mode = False R/W (0b0) - DIS_FORCE_DOWNLOAD (BLOCK0) Disables forcing chip into Download mode = False R/W (0b0) - DIS_CAN (BLOCK0) Disables the TWAI Controller hardware = False R/W (0b0) - DIS_BOOT_REMAP (BLOCK0) Disables capability to Remap RAM to ROM address sp = False R/W (0b0) - ace - FLASH_TPUW (BLOCK0) Configures flash startup delay after SoC power-up, = 0 R/W (0x0) - unit is (ms/2). When the value is 15, delay is 7. - 5 ms - DIS_DIRECT_BOOT (BLOCK0) Disables direct boot mode = False R/W (0b0) - DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0) Selects the default UART for printing boot msg = UART0 R/W (0b0) - DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0) Disables download through USB-Serial-JTAG = False R/W (0b0) - UART_PRINT_CONTROL (BLOCK0) Sets the default UART boot message output mode = Enabled R/W (0b00) - FLASH_TYPE (BLOCK0) Selects SPI flash type = 4 data lines R/W (0b0) - FORCE_SEND_RESUME (BLOCK0) Forces ROM code to send an SPI flash resume comman = False R/W (0b0) - d during SPI boot - BLOCK_USR_DATA (BLOCK3) User data + WR_DIS (BLOCK0) Disable programming of individual eFuses = 0 R/W (0x00000000) + RD_DIS (BLOCK0) Disable reading from BlOCK4-10 = 0 R/W (0b0000000) + DIS_ICACHE (BLOCK0) Set this bit to disable Icache = False R/W (0b0) + DIS_DCACHE (BLOCK0) Set this bit to disable Dcache = False R/W (0b0) + DIS_TWAI (BLOCK0) Set this bit to disable CAN function = False R/W (0b0) + DIS_APP_CPU (BLOCK0) Disable app cpu = False R/W (0b0) + DIS_DIRECT_BOOT (BLOCK0) Disable direct boot mode = False R/W (0b0) + UART_PRINT_CONTROL (BLOCK0) Set the default UART boot message output mode = Enable R/W (0b00) + PIN_POWER_SELECTION (BLOCK0) Set default power supply for GPIO33-GPIO37; set wh = VDD3P3_CPU R/W (0b0) + en SPI flash is initialized + 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 - Efuse fuses: - WR_DIS (BLOCK0) Disables programming of individual eFuses = 0 R/W (0x00000000) - RD_DIS (BLOCK0) Disables software reading from BLOCK4-10 = 0 R/W (0b0000000) + Flash fuses: + FLASH_TPUW (BLOCK0) Configures flash waiting time after power-up; in u = 0 R/W (0x0) + nit of ms. If the value is less than 15; the waiti + ng time is the configurable value. Otherwise; the + waiting time is twice the configurable value + FLASH_ECC_MODE (BLOCK0) Flash ECC mode in ROM = 16to18 byte R/W (0b0) + FLASH_TYPE (BLOCK0) SPI flash type = 4 data lines R/W (0b0) + FLASH_PAGE_SIZE (BLOCK0) Set Flash page size = 0 R/W (0b00) + FLASH_ECC_EN (BLOCK0) Set 1 to enable ECC for flash boot = False R/W (0b0) + FORCE_SEND_RESUME (BLOCK0) Set this bit to force ROM code to send a resume co = False R/W (0b0) + mmand during SPI boot Identity fuses: - BLOCK0_VERSION (BLOCK0) BLOCK0 efuse version = 0 R/W (0b00) - SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000) - ure) - MAC (BLOCK1) Factory MAC Address - = 7c:df:a1:00:3a:6e: (OK) R/W - WAFER_VERSION (BLOCK1) WAFER version = A R/W (0b000) - PKG_VERSION (BLOCK1) Package version - = ESP32-S3, QFN 7x7 56 pins R/W (0x0) - BLOCK1_VERSION (BLOCK1) BLOCK1 efuse version = 0 R/W (0b000) - OPTIONAL_UNIQUE_ID (BLOCK2)(0 errors): Optional unique 128-bit ID - = 7d 33 b8 bb 0b 13 b3 c8 71 37 0e e8 7c ab d5 92 R/W - BLK_VERSION_MAJOR (BLOCK2) Version of BLOCK2 = With calibration R/W (0b001) - CUSTOM_MAC (BLOCK3) Custom MAC Address + DISABLE_WAFER_VERSION_MAJOR (BLOCK0) Disables check of wafer version major = False R/W (0b0) + DISABLE_BLK_VERSION_MAJOR (BLOCK0) Disables check of blk version major = False R/W (0b0) + WAFER_VERSION_MINOR_LO (BLOCK1) WAFER_VERSION_MINOR least significant bits = 0 R/W (0b000) + PKG_VERSION (BLOCK1) Package version = 0 R/W (0b000) + BLK_VERSION_MINOR (BLOCK1) BLK_VERSION_MINOR = 0 R/W (0b000) + WAFER_VERSION_MINOR_HI (BLOCK1) WAFER_VERSION_MINOR most significant bit = False R/W (0b0) + WAFER_VERSION_MAJOR (BLOCK1) WAFER_VERSION_MAJOR = 0 R/W (0b00) + OPTIONAL_UNIQUE_ID (BLOCK2) Optional unique 128-bit ID + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W + BLK_VERSION_MAJOR (BLOCK2) BLK_VERSION_MAJOR of BLOCK2 = No calib R/W (0b00) + WAFER_VERSION_MINOR (BLOCK0) calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI = 0 R/W (0x0) + << 3 + WAFER_VERSION_MINOR_LO (read only) + + Jtag fuses: + SOFT_DIS_JTAG (BLOCK0) Set these bits to disable JTAG in the soft way (od = 0 R/W (0b000) + d number 1 means disable ). JTAG can be enabled in + HMAC module + DIS_PAD_JTAG (BLOCK0) Set this bit to disable JTAG in the hard way. JTAG = False R/W (0b0) + is disabled permanently + STRAP_JTAG_SEL (BLOCK0) Set this bit to enable selection between usb_to_jt = False R/W (0b0) + ag and pad_to_jtag through strapping gpio10 when b + oth reg_dis_usb_jtag and reg_dis_pad_jtag are equa + l to 0 + + Mac fuses: + MAC (BLOCK1) MAC address + = 7c:df:a1:e0:00:58 (OK) R/W + CUSTOM_MAC (BLOCK3) Custom MAC = 00:00:00:00:00:00 (OK) R/W Security fuses: - SOFT_DIS_JTAG (BLOCK0) Software disables JTAG. When software disabled, JT = False R/W (0b000) - AG can be activated temporarily by HMAC peripheral - HARD_DIS_JTAG (BLOCK0) Hardware disables JTAG permanently = False R/W (0b0) - DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Disables flash encryption when in download boot mo = False R/W (0b0) - des - SPI_BOOT_CRYPT_CNT (BLOCK0) Enables encryption and decryption, when an SPI boo = Disable R/W (0b000) - t mode is set. Enabled when 1 or 3 bits are set,di - sabled otherwise - SECURE_BOOT_KEY_REVOKE0 (BLOCK0) If set, revokes use of secure boot key digest 0 = False R/W (0b0) - SECURE_BOOT_KEY_REVOKE1 (BLOCK0) If set, revokes use of secure boot key digest 1 = False R/W (0b0) - SECURE_BOOT_KEY_REVOKE2 (BLOCK0) If set, revokes use of secure boot key digest 2 = False R/W (0b0) - KEY_PURPOSE_0 (BLOCK0) KEY0 purpose = USER R/W (0x0) - KEY_PURPOSE_1 (BLOCK0) KEY1 purpose = USER R/W (0x0) - KEY_PURPOSE_2 (BLOCK0) KEY2 purpose = USER R/W (0x0) - KEY_PURPOSE_3 (BLOCK0) KEY3 purpose = USER R/W (0x0) - KEY_PURPOSE_4 (BLOCK0) KEY4 purpose = USER R/W (0x0) - KEY_PURPOSE_5 (BLOCK0) KEY5 purpose = USER R/W (0x0) - SECURE_BOOT_EN (BLOCK0) Enables secure boot = False R/W (0b0) - SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0) Enables aggressive secure boot key revocation mode = False R/W (0b0) - DIS_DOWNLOAD_MODE (BLOCK0) Disables all Download boot modes = False R/W (0b0) - ENABLE_SECURITY_DOWNLOAD (BLOCK0) Enables secure UART download mode (read/write flas = False R/W (0b0) - h only) - BLOCK_KEY0 (BLOCK4)(0 errors): + DIS_DOWNLOAD_ICACHE (BLOCK0) Set this bit to disable Icache in download mode (b = False R/W (0b0) + oot_mode[3:0] is 0; 1; 2; 3; 6; 7) + DIS_DOWNLOAD_DCACHE (BLOCK0) Set this bit to disable Dcache in download mode ( = False R/W (0b0) + boot_mode[3:0] is 0; 1; 2; 3; 6; 7) + DIS_FORCE_DOWNLOAD (BLOCK0) Set this bit to disable the function that forces c = False R/W (0b0) + hip into download mode + DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Set this bit to disable flash encryption when in d = False R/W (0b0) + ownload boot modes + SPI_BOOT_CRYPT_CNT (BLOCK0) Enables flash encryption when 1 or 3 bits are set = Disable R/W (0b000) + and disabled 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) Purpose of Key0 = USER R/W (0x0) + KEY_PURPOSE_1 (BLOCK0) Purpose of Key1 = USER R/W (0x0) + KEY_PURPOSE_2 (BLOCK0) Purpose of Key2 = USER R/W (0x0) + KEY_PURPOSE_3 (BLOCK0) Purpose of Key3 = USER R/W (0x0) + KEY_PURPOSE_4 (BLOCK0) Purpose of Key4 = USER R/W (0x0) + KEY_PURPOSE_5 (BLOCK0) Purpose of Key5 = USER R/W (0x0) + SECURE_BOOT_EN (BLOCK0) Set this bit to enable secure boot = False R/W (0b0) + SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0) Set this bit to enable revoking aggressive secure = False R/W (0b0) + boot + DIS_DOWNLOAD_MODE (BLOCK0) Set this bit to disable download mode (boot_mode[3 = False R/W (0b0) + :0] = 0; 1; 2; 3; 6; 7) + ENABLE_SECURITY_DOWNLOAD (BLOCK0) Set this bit to enable secure UART download mode = False R/W (0b0) + SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000) + ure) + BLOCK_KEY0 (BLOCK4) Purpose: USER - Encryption key0 or user data + 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)(0 errors): + BLOCK_KEY1 (BLOCK5) Purpose: USER - Encryption key1 or user data + 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)(0 errors): + BLOCK_KEY2 (BLOCK6) Purpose: USER - Encryption key2 or user data + 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)(0 errors): + BLOCK_KEY3 (BLOCK7) Purpose: USER - Encryption key3 or user data + 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)(0 errors): + BLOCK_KEY4 (BLOCK8) Purpose: USER - Encryption key4 or user data + 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)(0 errors): + BLOCK_KEY5 (BLOCK9) Purpose: USER - Encryption 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 - BLOCK_SYS_DATA2 (BLOCK10) System data (part 2) + 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 - Spi_Pad_Config fuses: - SPI_PAD_CONFIG_CLK (BLOCK1) SPI CLK pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_Q (BLOCK1) SPI Q (D1) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D (BLOCK1) SPI D (D0) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_CS (BLOCK1) SPI CS pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_HD (BLOCK1) SPI HD (D3) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_WP (BLOCK1) SPI WP (D2) pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_DQS (BLOCK1) SPI DQS pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D4 (BLOCK1) SPI D4 pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D5 (BLOCK1) SPI D5 pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D6 (BLOCK1) SPI D6 pad = 0 R/W (0b000000) - SPI_PAD_CONFIG_D7 (BLOCK1) SPI D7 pad = 0 R/W (0b000000) + Spi Pad fuses: + SPI_PAD_CONFIG_CLK (BLOCK1) SPI_PAD_configure CLK = 0 R/W (0b000000) + SPI_PAD_CONFIG_Q (BLOCK1) SPI_PAD_configure Q(D1) = 0 R/W (0b000000) + SPI_PAD_CONFIG_D (BLOCK1) SPI_PAD_configure D(D0) = 0 R/W (0b000000) + SPI_PAD_CONFIG_CS (BLOCK1) SPI_PAD_configure CS = 0 R/W (0b000000) + SPI_PAD_CONFIG_HD (BLOCK1) SPI_PAD_configure HD(D3) = 0 R/W (0b000000) + SPI_PAD_CONFIG_WP (BLOCK1) SPI_PAD_configure WP(D2) = 0 R/W (0b000000) + SPI_PAD_CONFIG_DQS (BLOCK1) SPI_PAD_configure DQS = 0 R/W (0b000000) + SPI_PAD_CONFIG_D4 (BLOCK1) SPI_PAD_configure D4 = 0 R/W (0b000000) + SPI_PAD_CONFIG_D5 (BLOCK1) SPI_PAD_configure D5 = 0 R/W (0b000000) + SPI_PAD_CONFIG_D6 (BLOCK1) SPI_PAD_configure D6 = 0 R/W (0b000000) + SPI_PAD_CONFIG_D7 (BLOCK1) SPI_PAD_configure D7 = 0 R/W (0b000000) - Usb Config fuses: - DIS_USB (BLOCK0) Disables the USB OTG hardware = False R/W (0b0) - USB_EXCHG_PINS (BLOCK0) Exchanges USB D+ and D- pins = False R/W (0b0) - EXT_PHY_ENABLE (BLOCK0) Enables external USB PHY = False R/W (0b0) - USB_FORCE_NOPERSIST (BLOCK0) Forces to set USB BVALID to 1 = False R/W (0b0) + Usb fuses: + DIS_USB_OTG (BLOCK0) Set this bit to disable USB function = False R/W (0b0) + USB_EXCHG_PINS (BLOCK0) Set this bit to exchange USB D+ and D- pins = False R/W (0b0) + USB_EXT_PHY_ENABLE (BLOCK0) Set this bit to enable external PHY = False R/W (0b0) + DIS_USB_JTAG (BLOCK0) Set this bit to disable function of usb switch to = False R/W (0b0) + jtag in module of usb device + DIS_USB_SERIAL_JTAG (BLOCK0) Set this bit to disable usb device = False R/W (0b0) + USB_PHY_SEL (BLOCK0) This bit is used to switch internal PHY and extern + = internal PHY is assigned to USB Device while external PHY is assigned to USB OTG R/W (0b0) + al PHY for USB OTG and USB Device + DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0) USB printing = Enable R/W (0b0) + DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0) Set this bit to disable UART download mode through = False R/W (0b0) + USB + DIS_USB_OTG_DOWNLOAD_MODE (BLOCK0) Set this bit to disable download through USB-OTG = False R/W (0b0) - Vdd_Spi Config fuses: - VDD_SPI_FORCE (BLOCK0) Force using VDD_SPI_XPD and VDD_SPI_TIEH to config = False R/W (0b0) - ure VDD_SPI LDO - VDD_SPI_XPD (BLOCK0) The VDD_SPI regulator is powered on = False R/W (0b0) - VDD_SPI_TIEH (BLOCK0) The VDD_SPI power supply voltage at reset = Connect to 1.8V LDO R/W (0b0) - PIN_POWER_SELECTION (BLOCK0) Sets default power supply for GPIO33..37, set when = VDD3P3_CPU R/W (0b0) - SPI flash is initialized + Vdd fuses: + VDD_SPI_XPD (BLOCK0) SPI regulator power up signal = False R/W (0b0) + VDD_SPI_TIEH (BLOCK0) If VDD_SPI_FORCE is 1; determines VDD_SPI voltage + = VDD_SPI connects to 1.8 V LDO R/W (0b0) + VDD_SPI_FORCE (BLOCK0) Set this bit and force to use the configuration of = False R/W (0b0) + eFuse to configure VDD_SPI - Wdt Config fuses: - WDT_DELAY_SEL (BLOCK0) Selects RTC WDT timeout threshold at startup = 0 R/W (0b00) + Wdt fuses: + WDT_DELAY_SEL (BLOCK0) RTC watchdog timeout threshold; in unit of slow cl = 40000 R/W (0b00) + ock cycle Flash voltage (VDD_SPI) determined by GPIO45 on reset (GPIO45=High: VDD_SPI pin is powered from internal 1.8V LDO GPIO45=Low or NC: VDD_SPI pin is powered directly from VDD3P3_RTC_IO via resistor Rspi. Typically this voltage is 3.3 V). diff --git a/docs/en/espefuse/inc/summary_ESP32.rst b/docs/en/espefuse/inc/summary_ESP32.rst index 575cdb91a..59f303815 100644 --- a/docs/en/espefuse/inc/summary_ESP32.rst +++ b/docs/en/espefuse/inc/summary_ESP32.rst @@ -4,61 +4,87 @@ Connecting........__ Detecting chip type... ESP32 - EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) + + === Run "summary" command === + EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Calibration fuses: - BLK3_PART_RESERVE (BLOCK0): BLOCK3 partially served for ADC calibration data = True R/W (0b1) - ADC_VREF (BLOCK0): Voltage reference calibration = 1114 R/W (0b00010) - ADC1_TP_LOW (BLOCK3): ADC1 150mV reading = 346 R/W (0b0010001) - ADC1_TP_HIGH (BLOCK3): ADC1 850mV reading = 3285 R/W (0b000000101) - ADC2_TP_LOW (BLOCK3): ADC2 150mV reading = 449 R/W (0b0000111) - ADC2_TP_HIGH (BLOCK3): ADC2 850mV reading = 3362 R/W (0b111110101) + ADC_VREF (BLOCK0): True ADC reference voltage = 1121 R/W (0b00011) Config fuses: - XPD_SDIO_FORCE (BLOCK0): Ignore MTDI pin (GPIO12) for VDD_SDIO on reset = False R/W (0b0) - XPD_SDIO_REG (BLOCK0): If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset = False R/W (0b0) - XPD_SDIO_TIEH (BLOCK0): If XPD_SDIO_FORCE & XPD_SDIO_REG = 1.8V R/W (0b0) - CLK8M_FREQ (BLOCK0): 8MHz clock freq override = 53 R/W (0x35) - SPI_PAD_CONFIG_CLK (BLOCK0): Override SD_CLK pad (GPIO6/SPICLK) = 0 R/W (0b00000) - SPI_PAD_CONFIG_Q (BLOCK0): Override SD_DATA_0 pad (GPIO7/SPIQ) = 0 R/W (0b00000) - SPI_PAD_CONFIG_D (BLOCK0): Override SD_DATA_1 pad (GPIO8/SPID) = 0 R/W (0b00000) - SPI_PAD_CONFIG_HD (BLOCK0): Override SD_DATA_2 pad (GPIO9/SPIHD) = 0 R/W (0b00000) - SPI_PAD_CONFIG_CS0 (BLOCK0): Override SD_CMD pad (GPIO11/SPICS0) = 0 R/W (0b00000) - DISABLE_SDIO_HOST (BLOCK0): Disable SDIO host = False R/W (0b0) + WR_DIS (BLOCK0): Efuse write disable mask = 0 R/W (0x0000) + RD_DIS (BLOCK0): Disable reading from BlOCK1-3 = 0 R/W (0x0) + DISABLE_APP_CPU (BLOCK0): Disables APP CPU = False R/W (0b0) + DISABLE_BT (BLOCK0): Disables Bluetooth = False R/W (0b0) + DIS_CACHE (BLOCK0): Disables cache = False R/W (0b0) + CHIP_CPU_FREQ_LOW (BLOCK0): If set alongside EFUSE_RD_CHIP_CPU_FREQ_RATED; the = False R/W (0b0) + ESP32's max CPU frequency is rated for 160MHz. 24 + 0MHz otherwise + CHIP_CPU_FREQ_RATED (BLOCK0): If set; the ESP32's maximum CPU frequency has been = True R/W (0b1) + rated + BLK3_PART_RESERVE (BLOCK0): BLOCK3 partially served for ADC calibration data = False R/W (0b0) + CLK8M_FREQ (BLOCK0): 8MHz clock freq override = 51 R/W (0x33) + VOL_LEVEL_HP_INV (BLOCK0): This field stores the voltage level for CPU to run = 0 R/W (0b00) + at 240 MHz; or for flash/PSRAM to run at 80 MHz.0 + x0: level 7; 0x1: level 6; 0x2: level 5; 0x3: leve + l 4. (RO) + CODING_SCHEME (BLOCK0): Efuse variable block length scheme + = NONE (BLK1-3 len=256 bits) R/W (0b00) + CONSOLE_DEBUG_DISABLE (BLOCK0): Disable ROM BASIC interpreter fallback = True R/W (0b1) + DISABLE_SDIO_HOST (BLOCK0): = False R/W (0b0) + DISABLE_DL_CACHE (BLOCK0): Disable flash cache in UART bootloader = False R/W (0b0) - Efuse fuses: - WR_DIS (BLOCK0): Efuse write disable mask = 0 R/W (0x0000) - RD_DIS (BLOCK0): Efuse read disable mask = 0 R/W (0x0) - CODING_SCHEME (BLOCK0): Efuse variable block length scheme - = 3/4 (BLK1-3 len=192 bits) R/W (0b01) - KEY_STATUS (BLOCK0): Usage of efuse block 3 (reserved) = False R/W (0b0) + Flash fuses: + FLASH_CRYPT_CNT (BLOCK0): Flash encryption is enabled if this field has an o = 0 R/W (0b0000000) + dd number of bits set + FLASH_CRYPT_CONFIG (BLOCK0): Flash encryption config (key tweak bits) = 0 R/W (0x0) Identity fuses: - MAC (BLOCK0): Factory MAC Address - = 84:0d:8e:18:8e:44 (CRC 0xad OK) R/W - MAC_CRC (BLOCK0): CRC8 for factory MAC address = 173 R/W (0xad) - CHIP_VER_REV1 (BLOCK0): Silicon Revision 1 = True R/W (0b1) - CHIP_VER_REV2 (BLOCK0): Silicon Revision 2 = False R/W (0b0) - CHIP_VERSION (BLOCK0): Reserved for future chip versions = 2 R/W (0b10) - CHIP_PACKAGE (BLOCK0): Chip package identifier = 0 R/W (0b000) - MAC_VERSION (BLOCK3): Version of the MAC field = 0 R/W (0x00) + CHIP_PACKAGE_4BIT (BLOCK0): Chip package identifier #4bit = False R/W (0b0) + CHIP_PACKAGE (BLOCK0): Chip package identifier = 1 R/W (0b001) + CHIP_VER_REV1 (BLOCK0): bit is set to 1 for rev1 silicon = True R/W (0b1) + CHIP_VER_REV2 (BLOCK0): = True R/W (0b1) + WAFER_VERSION_MINOR (BLOCK0): = 0 R/W (0b00) + WAFER_VERSION_MAJOR (BLOCK0): calc WAFER VERSION MAJOR from CHIP_VER_REV1 and CH = 3 R/W (0b011) + IP_VER_REV2 and apb_ctl_date (read only) + PKG_VERSION (BLOCK0): calc Chip package = CHIP_PACKAGE_4BIT << 3 + CHIP_ = 1 R/W (0x1) + PACKAGE (read only) + + Jtag fuses: + JTAG_DISABLE (BLOCK0): Disable JTAG = False R/W (0b0) + + Mac fuses: + MAC (BLOCK0): MAC address + = 94:b9:7e:5a:6e:58 (CRC 0xe2 OK) R/W + MAC_CRC (BLOCK0): CRC8 for MAC address = 226 R/W (0xe2) + MAC_VERSION (BLOCK3): Version of the MAC field = 0 R/W (0x00) Security fuses: - FLASH_CRYPT_CNT (BLOCK0): Flash encryption mode counter = 0 R/W (0b0000000) - UART_DOWNLOAD_DIS (BLOCK0): Disable UART download mode (ESP32 rev3 only) = False R/W (0b0) - FLASH_CRYPT_CONFIG (BLOCK0): Flash encryption config (key tweak bits) = 0 R/W (0x0) - CONSOLE_DEBUG_DISABLE (BLOCK0): Disable ROM BASIC interpreter fallback = True R/W (0b1) - ABS_DONE_0 (BLOCK0): Secure boot V1 is enabled for bootloader image = False R/W (0b0) - ABS_DONE_1 (BLOCK0): Secure boot V2 is enabled for bootloader image = False R/W (0b0) - JTAG_DISABLE (BLOCK0): Disable JTAG = False R/W (0b0) - DISABLE_DL_ENCRYPT (BLOCK0): Disable flash encryption in UART bootloader = False R/W (0b0) - DISABLE_DL_DECRYPT (BLOCK0): Disable flash decryption in UART bootloader = False R/W (0b0) - DISABLE_DL_CACHE (BLOCK0): Disable flash cache in UART bootloader = False R/W (0b0) - BLOCK1 (BLOCK1): Flash encryption key - = 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 - BLOCK2 (BLOCK2): Secure boot key - = 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 - BLOCK3 (BLOCK3): Variable Block 3 - = 00 00 00 00 00 00 00 00 00 00 00 00 91 02 87 fa 00 00 00 00 00 00 00 00 R/W + UART_DOWNLOAD_DIS (BLOCK0): Disable UART download mode. Valid for ESP32 V3 and = False R/W (0b0) + newer; only + ABS_DONE_0 (BLOCK0): Secure boot V1 is enabled for bootloader image = False R/W (0b0) + ABS_DONE_1 (BLOCK0): Secure boot V2 is enabled for bootloader image = False R/W (0b0) + DISABLE_DL_ENCRYPT (BLOCK0): Disable flash encryption in UART bootloader = False R/W (0b0) + DISABLE_DL_DECRYPT (BLOCK0): Disable flash decryption in UART bootloader = False R/W (0b0) + KEY_STATUS (BLOCK0): Usage of efuse block 3 (reserved) = False R/W (0b0) + SECURE_VERSION (BLOCK3): Secure version for anti-rollback = 0 R/W (0x00000000) + BLOCK1 (BLOCK1): Flash encryption key + = 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 + BLOCK2 (BLOCK2): Security boot key + = 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 + BLOCK3 (BLOCK3): Variable Block 3 + = 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 + + Spi Pad fuses: + SPI_PAD_CONFIG_HD (BLOCK0): read for SPI_pad_config_hd = 0 R/W (0b00000) + SPI_PAD_CONFIG_CLK (BLOCK0): Override SD_CLK pad (GPIO6/SPICLK) = 0 R/W (0b00000) + SPI_PAD_CONFIG_Q (BLOCK0): Override SD_DATA_0 pad (GPIO7/SPIQ) = 0 R/W (0b00000) + SPI_PAD_CONFIG_D (BLOCK0): Override SD_DATA_1 pad (GPIO8/SPID) = 0 R/W (0b00000) + SPI_PAD_CONFIG_CS0 (BLOCK0): Override SD_CMD pad (GPIO11/SPICS0) = 0 R/W (0b00000) + + Vdd fuses: + XPD_SDIO_REG (BLOCK0): read for XPD_SDIO_REG = False R/W (0b0) + XPD_SDIO_TIEH (BLOCK0): If XPD_SDIO_FORCE & XPD_SDIO_REG = 1.8V R/W (0b0) + XPD_SDIO_FORCE (BLOCK0): Ignore MTDI pin (GPIO12) for VDD_SDIO on reset = False R/W (0b0) - Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V). + Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V) diff --git a/docs/en/espsecure/index.rst b/docs/en/espsecure/index.rst index 9b5b63f88..c03b3478e 100644 --- a/docs/en/espsecure/index.rst +++ b/docs/en/espsecure/index.rst @@ -17,11 +17,7 @@ Remote Signing using an external HSM An external Hardware Security Module (HSM) can be used for remote signing of images in secure boot v2 scheme. -You must install ``esptool.py`` package with the ``hsm`` extra using the command, ``pip install 'esptool[hsm]'`` to use this feature. - -``esp_hsm_sign`` provides a PKCS #11 interface to communicate with the external HSM and is integrated in ``espsecure.py``. - -Refer to `Signing using an External HSM `_ to generate a Secure Boot V2 format unsigned firmware image. +You must install ``esptool.py`` package with the ``hsm`` extra using the command ``pip install 'esptool[hsm]'`` to use this feature. ``esp_hsm_sign`` provides a PKCS #11 interface to communicate with the external HSM and is integrated in ``espsecure.py``. The following command should be used to get an image signed using an external HSM. :: @@ -33,6 +29,9 @@ If the public key is not stored in the external HSM, you can specify the ``--pub python espsecure.py sign_data --version 2 --hsm --hsm-config --pub-key --output +.. note:: + In case you are using ESP-IDF, then an unsigned application can be generated by disabling ``CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES`` configuration option in the project settings. + Verifying the Signed Image ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -51,6 +50,9 @@ HSM config file 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 --git a/docs/en/esptool/advanced-commands.rst b/docs/en/esptool/advanced-commands.rst index a5dd1562e..bfc9d2c0c 100644 --- a/docs/en/esptool/advanced-commands.rst +++ b/docs/en/esptool/advanced-commands.rst @@ -1,4 +1,4 @@ -{IDF_TARGET_BOOTLOADER_OFFSET:default="0x0", esp8266="0x0", esp32="0x1000", esp32s2="0x1000", esp32s3="0x0", esp32c3="0x0"} +{IDF_TARGET_BOOTLOADER_OFFSET:default="0x0", esp32="0x1000", esp32s2="0x1000"} .. _advanced-commands: @@ -48,7 +48,7 @@ The ``dump_mem`` command will dump a region from the chip's memory space to a fi 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 --git a/docs/en/esptool/advanced-options.rst b/docs/en/esptool/advanced-options.rst index 8d8b8e483..d47ab515a 100644 --- a/docs/en/esptool/advanced-options.rst +++ b/docs/en/esptool/advanced-options.rst @@ -22,7 +22,7 @@ The ``--before`` argument allows you to specify whether the chip needs resetting * ``--before default_reset`` is the default, which uses DTR & RTS serial control lines (see :ref:`entering-the-bootloader`) to try to reset the chip into bootloader mode. * ``--before no_reset`` will skip DTR/RTS control signal assignments and just start sending a serial synchronisation command to the chip. This is useful if your chip doesn't have DTR/RTS, or for some serial interfaces (like Arduino board onboard serial) which behave differently when DTR/RTS are toggled. * ``--before no_reset_no_sync`` will skip DTR/RTS control signal assignments and skip also the serial synchronization command. This is useful if your chip is already running the :ref:`stub bootloader ` and you want to avoid resetting the chip and uploading the stub again. - :esp32c3 or esp32s3: * ``--before usb_reset`` will use custom reset sequence for USB-JTAG-Serial (used for example for ESP chips connected through the USB-JTAG-Serial peripheral). Usually, this option doesn't have to be used directly. Esptool should be able to detect connection through USB-JTAG-Serial. + :esp32c3 or esp32s3 or esp32c6 or esp32h2: * ``--before usb_reset`` will use custom reset sequence for USB-JTAG-Serial (used for example for ESP chips connected through the USB-JTAG-Serial peripheral). Usually, this option doesn't have to be used directly. Esptool should be able to detect connection through USB-JTAG-Serial. Reset After Operation ^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,12 @@ Passing ``--no-stub`` will disable certain options, as not all options are imple 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 --git a/docs/en/esptool/basic-commands.rst b/docs/en/esptool/basic-commands.rst index 8246d73ff..ead5ac208 100644 --- a/docs/en/esptool/basic-commands.rst +++ b/docs/en/esptool/basic-commands.rst @@ -105,6 +105,14 @@ The read_flash command allows reading back the contents of flash. The arguments esptool.py -p PORT -b 460800 read_flash 0 0x200000 flash_contents.bin + +It is also possible to autodetect flash size by using ``ALL`` as size. The above example with autodetection would look like this: + +:: + + esptool.py -p PORT -b 460800 read_flash 0 ALL flash_contents.bin + + .. note:: If ``write_flash`` updated the boot image's :ref:`flash mode and flash size ` during flashing then these bytes may be different when read back. @@ -163,7 +171,7 @@ Example output: Device: 4016 Detected flash size: 4MB -Refer to `flashrom source code `__ for flash chip manufacturer name and part number. +Refer to `flashrom source code `__ for flash chip manufacturer name and part number. .. _elf-2-image: @@ -203,12 +211,16 @@ By default, ``elf2image`` uses the sections in the ELF file to generate each seg 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. @@ -220,14 +232,15 @@ This information corresponds to the headers described in :ref:`image-format`. .. only:: not esp8266 - If a valid `ESP-IDF application header `__ is detected in the image, specific fields describing the application are also displayed. + If the given binary file is an application and a valid `ESP-IDF application header `__ is detected in the image, specific fields describing the application are also displayed. + + If the given binary file is a bootloader and a valid `ESP-IDF bootloader header `__ is detected in the image, specific fields describing the bootloader are also displayed. .. _merge-bin: 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: @@ -235,25 +248,73 @@ For example: 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``. - -.. note: +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``. - 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 --git a/docs/en/esptool/flash-modes.rst b/docs/en/esptool/flash-modes.rst index 675673d8f..37d3033b7 100644 --- a/docs/en/esptool/flash-modes.rst +++ b/docs/en/esptool/flash-modes.rst @@ -1,4 +1,11 @@ -{IDF_TARGET_BOOTLOADER_OFFSET:default="0x0", esp8266="0x0", esp32="0x1000", esp32s2="0x1000", esp32s3="0x0", esp32c3="0x0"} +{IDF_TARGET_BOOTLOADER_OFFSET:default="0x0", esp32="0x1000", esp32s2="0x1000"} + +{IDF_TARGET_FLASH_FREQ_F:default="80", esp32c2="60", esp32h2="48"} + +{IDF_TARGET_FLASH_FREQ_0:default="40", esp32c2="30", esp32h2="24"} + +{IDF_TARGET_FLASH_FREQ:default="``40m``, ``26m``, ``20m``, ``80m``", esp32c2="``30m``, ``20m``, ``15m``, ``60m``", esp32h2="``24m``, ``16m``, ``12m``, ``48m``", esp32c6="``40m``, ``20m``, ``80m``"} + .. _flash-modes: @@ -36,9 +43,9 @@ For a full explanation of these modes, see the :ref:`SPI Flash Modes page `__ (Telnet) protocol. To do this, specify the serial port to esptool as ``rfc2217://:``. For example: +It is possible to connect to any networked remote serial port that supports `RFC2217 `__ (Telnet) protocol. To do this, specify the serial port to esptool as ``rfc2217://:``. For example, to read information about your chip's SPI flash, run: :: diff --git a/docs/en/index.rst b/docs/en/index.rst index b1c49be3c..201b71bf1 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -29,7 +29,7 @@ Getting started is easy: 2) Connect an Espressif chip to your computer. -3) Run ``esptool.py`` commands: +3) Run ``esptool.py`` commands. For example, to read information about your chip's SPI flash, run: :: @@ -51,4 +51,5 @@ More Information Troubleshooting Contribute Versions + Resources About diff --git a/docs/en/resources.rst b/docs/en/resources.rst new file mode 100644 index 000000000..13add7041 --- /dev/null +++ b/docs/en/resources.rst @@ -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 --git a/docs/en/troubleshooting.rst b/docs/en/troubleshooting.rst index 35037e9e5..5d3e3dbf3 100644 --- a/docs/en/troubleshooting.rst +++ b/docs/en/troubleshooting.rst @@ -1,4 +1,4 @@ -{IDF_TARGET_BOOTLOADER_OFFSET:default="0x0", esp8266="0x0", esp32="0x1000", esp32s2="0x1000", esp32s3="0x0", esp32c3="0x0"} +{IDF_TARGET_BOOTLOADER_OFFSET:default="0x0", esp32="0x1000", esp32s2="0x1000"} .. _troubleshooting: @@ -102,6 +102,17 @@ Early Stage Crash 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 --git a/docs/requirements.txt b/docs/requirements.txt index 3be65005f..34d2904ed 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -esp-docs==1.0.* +esp-docs==1.4.* diff --git a/esp_rfc2217_server.py b/esp_rfc2217_server.py index 61a6fc166..8b9a1678e 100755 --- a/esp_rfc2217_server.py +++ b/esp_rfc2217_server.py @@ -30,11 +30,21 @@ # SPDX-License-Identifier: BSD-3-Clause import logging +import os import socket import sys import threading import time +from esptool.config import load_config_file +from esptool.reset import ( + ClassicReset, + CustomReset, + DEFAULT_RESET_DELAY, + HardReset, + UnixTightReset, +) + import serial import serial.rfc2217 from serial.rfc2217 import ( @@ -46,6 +56,9 @@ SET_CONTROL_RTS_ON, ) +cfg, _ = load_config_file(verbose=True) +cfg = cfg["esptool"] + class EspPortManager(serial.rfc2217.PortManager): """ @@ -56,14 +69,23 @@ class EspPortManager(serial.rfc2217.PortManager): 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" @@ -78,15 +100,13 @@ def _telnet_process_subnegotiation(self, suboption): # only in cases not handled above do the original implementation in PortManager super(EspPortManager, self)._telnet_process_subnegotiation(suboption) - def _setDTR(self, state): - self.serial.setDTR(state) - - def _setRTS(self, state): - self.serial.setRTS(state) - # Work-around for adapters on Windows using the usbser.sys driver: - # generate a dummy change to DTR so that the set-control-line-state - # request is sent with the updated RTS state and the same DTR state - self.serial.setDTR(self.serial.dtr) + 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): """ @@ -95,17 +115,18 @@ def _reset_thread(self): """ if self.logger: self.logger.info("Activating reset in thread") - self._setDTR(False) # IO0=HIGH - self._setRTS(True) # EN=LOW, chip in reset - time.sleep(0.1) - if self.esp32r0_delay: - time.sleep(1.2) - self._setDTR(True) # IO0=LOW - self._setRTS(False) # EN=HIGH, chip out of reset + + delay = DEFAULT_RESET_DELAY if self.esp32r0_delay: - time.sleep(0.4) - time.sleep(0.05) - self._setDTR(False) # IO0=HIGH, done + delay += 0.5 + + cfg_custom_reset_sequence = cfg.get("custom_reset_sequence") + if cfg_custom_reset_sequence is not None: + CustomReset(self.serial, cfg_custom_reset_sequence)() + elif os.name != "nt": + UnixTightReset(self.serial, delay)() + else: + ClassicReset(self.serial, delay)() class Redirector(object): @@ -186,7 +207,7 @@ def stop(self): self.thread_poll.join() -if __name__ == "__main__": +def main(): import argparse parser = argparse.ArgumentParser( @@ -284,3 +305,7 @@ def stop(self): logging.error(str(msg)) logging.info("--- exit ---") + + +if __name__ == "__main__": + main() diff --git a/espefuse.py b/espefuse.py index 9b8633a22..2222d4e55 100755 --- a/espefuse.py +++ b/espefuse.py @@ -18,9 +18,12 @@ # Linux/macOS: remove current script directory to avoid importing this file # as a module; we want to import the installed espefuse module instead with contextlib.suppress(ValueError): - if sys.path[0].endswith("/bin"): - sys.path.pop(0) - sys.path.remove(os.path.dirname(sys.executable)) + executable_dir = os.path.dirname(sys.executable) + sys.path = [ + path + for path in sys.path + if not path.endswith(("/bin", "/sbin")) and path != executable_dir + ] # Linux/macOS: delete imported module entry to force Python to load # the module from scratch; this enables importing espefuse module in diff --git a/espefuse/__init__.py b/espefuse/__init__.py index 20357ee81..777d53f41 100755 --- a/espefuse/__init__.py +++ b/espefuse/__init__.py @@ -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 ), @@ -132,7 +134,7 @@ def split_on_groups(all_args): return groups, used_cmds -def main(custom_commandline=None): +def main(custom_commandline=None, esp=None): """ Main function for espefuse @@ -140,7 +142,13 @@ def main(custom_commandline=None): (that uses sys.argv), can be a list of custom arguments as strings. Arguments and their values need to be added as individual items to the list e.g. "--port /dev/ttyUSB1" thus becomes ['--port', '/dev/ttyUSB1']. + + esp - Optional override of the connected device previously + returned by esptool.get_default_connected_device() """ + + external_esp = esp is not None + init_parser = argparse.ArgumentParser( description="espefuse.py v%s - [ESP32xx] efuse get/set tool" % esptool.__version__, @@ -211,22 +219,24 @@ def main(custom_commandline=None): print("espefuse.py v{}".format(esptool.__version__)) - try: - esp = get_esp( - common_args.port, - common_args.baud, - common_args.before, - common_args.chip, - just_print_help, - common_args.virt, - common_args.debug, - common_args.path_efuse_file, - ) - except esptool.FatalError as e: - raise esptool.FatalError( - f"{e}\nPlease make sure that you have specified " - "the right port with the --port argument" - ) # TODO: Require the --port argument in the next major release, ESPTOOL-490 + if not external_esp: + try: + esp = get_esp( + common_args.port, + common_args.baud, + common_args.before, + common_args.chip, + just_print_help, + common_args.virt, + common_args.debug, + common_args.path_efuse_file, + ) + except esptool.FatalError as e: + raise esptool.FatalError( + f"{e}\nPlease make sure that you have specified " + "the right port with the --port argument" + ) + # TODO: Require the --port argument in the next major release, ESPTOOL-490 efuses, efuse_operations = get_efuses( esp, just_print_help, debug_mode, common_args.do_not_confirm @@ -262,6 +272,13 @@ def main(custom_commandline=None): operation_func = vars(efuse_operations)[args.operation] # each 'operation' is a module-level function of the same name print('\n=== Run "{}" command ==='.format(args.operation)) + + if hasattr(args, "show_sensitive_info"): + if args.show_sensitive_info or args.debug: + args.show_sensitive_info = True + else: + print("Sensitive data will be hidden (see --show-sensitive-info)") + operation_func(esp, efuses, args) if there_are_multiple_burn_commands_in_args: @@ -269,7 +286,7 @@ def main(custom_commandline=None): if not efuses.burn_all(check_batch_mode=True): raise esptool.FatalError("BURN was not done") finally: - if not common_args.virt and esp._port: + if not external_esp and not common_args.virt and esp._port: esp._port.close() diff --git a/espefuse/efuse/base_fields.py b/espefuse/efuse/base_fields.py index 9569fe775..ab12f0312 100644 --- a/espefuse/efuse/base_fields.py +++ b/espefuse/efuse/base_fields.py @@ -5,7 +5,6 @@ # SPDX-License-Identifier: GPL-2.0-or-later import binascii -import re import sys from bitstring import BitArray, BitStream, CreationError @@ -85,21 +84,34 @@ def check_arg_value(efuse, new_value): class EfuseProtectBase(object): # This class is used by EfuseBlockBase and EfuseFieldBase - def get_read_disable_mask(self): + def get_read_disable_mask(self, blk_part=None): + """Returns mask of read protection bits + blk_part: + - None: Calculate mask for all read protection bits. + - a number: Calculate mask only for specific item in read protection list. + """ mask = 0 if isinstance(self.read_disable_bit, list): - for i in self.read_disable_bit: - mask |= 1 << i + if blk_part is None: + for i in self.read_disable_bit: + mask |= 1 << i + else: + mask |= 1 << self.read_disable_bit[blk_part] else: mask = 1 << self.read_disable_bit return mask - def is_readable(self): + def get_count_read_disable_bits(self): + """Returns the number of read protection bits used by the field""" + # On the C2 chip, BLOCK_KEY0 has two read protection bits [0, 1]. + return bin(self.get_read_disable_mask()).count("1") + + def is_readable(self, blk_part=None): """Return true if the efuse is readable by software""" num_bit = self.read_disable_bit if num_bit is None: return True # read cannot be disabled - return (self.parent["RD_DIS"].get() & (self.get_read_disable_mask())) == 0 + return (self.parent["RD_DIS"].get() & self.get_read_disable_mask(blk_part)) == 0 def disable_read(self): num_bit = self.read_disable_bit @@ -538,6 +550,10 @@ def print_error_msg(self, error_msg): else: raise esptool.FatalError(error_msg) + def get_block_errors(self, block_num): + """Returns (error count, failure boolean flag)""" + return self.blocks[block_num].num_errors, self.blocks[block_num].fail + class EfuseFieldBase(EfuseProtectBase): def __init__(self, parent, param): @@ -553,19 +569,17 @@ def __init__(self, parent, param): self.efuse_type = param.type self.description = param.description self.dict_value = param.dictionary + self.bit_len = param.bit_len + self.alt_names = param.alt_names self.fail = False self.num_errors = 0 - if self.efuse_type.startswith("bool"): - field_len = 1 - else: - field_len = int(re.search(r"\d+", self.efuse_type).group()) - if self.efuse_type.startswith("bytes"): - field_len *= 8 - self.bitarray = BitStream(field_len) - self.bit_len = field_len + self.bitarray = BitStream(self.bit_len) self.bitarray.set(0) self.update(self.parent.blocks[self.block].bitarray) + def is_field_calculated(self): + return self.word is None or self.pos is None + def check_format(self, new_value_str): if new_value_str is None: return new_value_str @@ -658,8 +672,10 @@ def save(self, new_value): self.save_to_block(bitarray_field) def update(self, bit_array_block): - if self.word is None or self.pos is None: - self.bitarray.overwrite(self.convert_to_bitstring(self.get()), pos=0) + if self.is_field_calculated(): + self.bitarray.overwrite( + self.convert_to_bitstring(self.check_format(self.get())), pos=0 + ) return field_len = self.bitarray.len bit_array_block.pos = bit_array_block.length - ( @@ -721,3 +737,18 @@ def burn(self, new_value): # Burn a efuse. Added for compatibility reason. self.save(new_value) self.parent.burn_all() + + def get_info(self): + output = f"{self.name} (BLOCK{self.block})" + if self.block == 0: + if self.fail: + output += "[error]" + else: + errs, fail = self.parent.get_block_errors(self.block) + if errs != 0 or fail: + output += "[error]" + if self.efuse_class == "keyblock": + name = self.parent.blocks[self.block].key_purpose_name + if name is not None: + output += f"\n Purpose: {self.parent[name].get()}\n " + return output diff --git a/espefuse/efuse/base_operations.py b/espefuse/efuse/base_operations.py index b1c30dbb4..5e3475e49 100644 --- a/espefuse/efuse/base_operations.py +++ b/espefuse/efuse/base_operations.py @@ -71,7 +71,8 @@ def check_efuse_name(efuse_name, efuse_list): metavar="[EFUSE_NAME VALUE] [{} VALUE".format( " VALUE] [".join([e.name for e in efuses.efuses]) ), - efuse_choices=[e.name for e in efuses.efuses], + efuse_choices=[e.name for e in efuses.efuses] + + [name for e in efuses.efuses for name in e.alt_names if name != ""], efuses=efuses, ) @@ -83,7 +84,14 @@ def check_efuse_name(efuse_name, efuse_list): "efuse_name", help="Name of efuse register to burn", nargs="+", - choices=[e.name for e in efuses.efuses if e.read_disable_bit is not None], + choices=[e.name for e in efuses.efuses if e.read_disable_bit is not None] + + [ + name + for e in efuses.efuses + if e.read_disable_bit is not None + for name in e.alt_names + if name != "" + ], ) write_protect_efuse = subparsers.add_parser( @@ -94,7 +102,14 @@ def check_efuse_name(efuse_name, efuse_list): "efuse_name", help="Name of efuse register to burn", nargs="+", - choices=[e.name for e in efuses.efuses if e.write_disable_bit is not None], + choices=[e.name for e in efuses.efuses if e.write_disable_bit is not None] + + [ + name + for e in efuses.efuses + if e.write_disable_bit is not None + for name in e.alt_names + if name != "" + ], ) burn_block_data = subparsers.add_parser( @@ -220,6 +235,16 @@ def add_force_write_always(p): ) +def add_show_sensitive_info_option(p): + p.add_argument( + "--show-sensitive-info", + help="Show data to be burned (may expose sensitive data). " + "Enabled if --debug is used.", + action="store_true", + default=False, + ) + + def summary(esp, efuses, args): """Print a human-readable summary of efuse contents""" ROW_FORMAT = "%-50s %-50s%s = %s %s %s" @@ -261,7 +286,17 @@ def summary(esp, efuses, args): base_value = e.get_meaning() value = str(base_value) if not readable: - value = value.replace("0", "?") + count_read_disable_bits = e.get_count_read_disable_bits() + if count_read_disable_bits == 2: + # On the C2 chip, BLOCK_KEY0 has two read protection bits [0, 1] + # related to the lower and higher part of the block. + v = [value[: (len(value) // 2)], value[(len(value) // 2) :]] + for i in range(count_read_disable_bits): + if not e.is_readable(blk_part=i): + v[i] = v[i].replace("0", "?") + value = "".join(v) + else: + value = value.replace("0", "?") if human_output: print( ROW_FORMAT @@ -648,26 +683,49 @@ def burn_bit(esp, efuses, args): print("Successful") -def check_error(esp, efuses, args): +def get_error_summary(efuses): error_in_blocks = efuses.get_coding_scheme_warnings() - if args.recovery: - if error_in_blocks: - confirmed = False - for block in reversed(efuses.blocks): - if block.fail or block.num_errors > 0: - if not block.get_bitstring().all(False): - block.save(block.get_bitstring().bytes[::-1]) - if not confirmed: - confirmed = True - efuses.confirm( - "Recovery of block coding errors", args.do_not_confirm - ) - block.burn() - # Reset the recovery flag to run check_error() without it, - # just to check the new state of eFuse blocks. - args.recovery = False - check_error(esp, efuses, args) - else: - if error_in_blocks: - raise esptool.FatalError("Error(s) were detected in eFuses") + if not error_in_blocks: + return False + writable = True + for blk in efuses.blocks: + if blk.fail or blk.num_errors: + if blk.id == 0: + for field in efuses: + if field.block == blk.id and (field.fail or field.num_errors): + wr = "writable" if field.is_writeable() else "not writable" + writable &= wr == "writable" + name = field.name + val = field.get() + print(f"BLOCK{field.block:<2}: {name:<40} = {val:<8} ({wr})") + else: + wr = "writable" if blk.is_writeable() else "not writable" + writable &= wr == "writable" + name = f"{blk.name} [ERRORS:{blk.num_errors} FAIL:{int(blk.fail)}]" + val = str(blk.get_bitstring()) + print(f"BLOCK{blk.id:<2}: {name:<40} = {val:<8} ({wr})") + if not writable and error_in_blocks: + print("Not all errors can be fixed because some fields are write-protected!") + return True + + +def check_error(esp, efuses, args): + error_in_blocks = get_error_summary(efuses) + if args.recovery and error_in_blocks: + confirmed = False + for block in reversed(efuses.blocks): + if block.fail or block.num_errors > 0: + if not block.get_bitstring().all(False): + block.save(block.get_bitstring().bytes[::-1]) + if not confirmed: + confirmed = True + efuses.confirm( + "Recovery of block coding errors", args.do_not_confirm + ) + block.burn() + if confirmed: + efuses.update_efuses() + error_in_blocks = get_error_summary(efuses) + if error_in_blocks: + raise esptool.FatalError("Error(s) were detected in eFuses") print("No errors detected") diff --git a/espefuse/efuse/emulate_efuse_controller_base.py b/espefuse/efuse/emulate_efuse_controller_base.py index d1c200f0f..232bfaad8 100644 --- a/espefuse/efuse/emulate_efuse_controller_base.py +++ b/espefuse/efuse/emulate_efuse_controller_base.py @@ -109,8 +109,7 @@ def clean_blocks_wr_regs(self): self.write_reg(wr_addr, 0) def read_field(self, name, bitstring=True): - for e in self.Fields.EFUSES: - field = self.Fields.get(e) + for field in self.Fields.EFUSES: if field.name == name: self.read_block(field.block) block = self.read_block(field.block) @@ -166,8 +165,7 @@ def check_wr_protection_area(self, num_blk, wr_data): ): mask_wr_data.set(1) else: - for e in self.Fields.EFUSES: - field = self.Fields.get(e) + for field in self.Fields.EFUSES: if blk.id == field.block and field.block == num_blk: if field.write_disable_bit is not None and write_disable_bit & ( 1 << field.write_disable_bit @@ -193,8 +191,7 @@ def check_rd_protection_area(self): ): block.set(0) else: - for e in self.Fields.EFUSES: - field = self.Fields.get(e) + for field in self.Fields.EFUSES: if ( blk.id == field.block and field.read_disable_bit is not None diff --git a/espefuse/efuse/esp32/emulate_efuse_controller.py b/espefuse/efuse/esp32/emulate_efuse_controller.py index 35923cfb1..da7cd44d6 100644 --- a/espefuse/efuse/esp32/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32/emulate_efuse_controller.py @@ -16,11 +16,11 @@ class EmulateEfuseController(EmulateEfuseControllerBase): CHIP_NAME = "ESP32" mem = None debug = False - Blocks = EfuseDefineBlocks - Fields = EfuseDefineFields - REGS = EfuseDefineRegisters def __init__(self, efuse_file=None, debug=False): + self.Blocks = EfuseDefineBlocks + self.Fields = EfuseDefineFields() + self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) """ esptool method start >> """ diff --git a/espefuse/efuse/esp32/fields.py b/espefuse/efuse/esp32/fields.py index ceb160c19..7ca5fc356 100644 --- a/espefuse/efuse/esp32/fields.py +++ b/espefuse/efuse/esp32/fields.py @@ -65,16 +65,15 @@ class EspEfuses(base_fields.EspEfusesBase): Wrapper object to manage the efuse fields in a connected ESP bootloader """ - Blocks = EfuseDefineBlocks() - Fields = EfuseDefineFields() - REGS = EfuseDefineRegisters - BURN_BLOCK_DATA_NAMES = Blocks.get_burn_block_data_names() - BLOCKS_FOR_KEYS = Blocks.get_blocks_for_keys() - 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 @@ -89,44 +88,26 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ] if not skip_connect: self.get_coding_scheme_warnings() - self.efuses = [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.EFUSES - ] + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] if skip_connect: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.KEYBLOCKS_256 + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS_256 ] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CUSTOM_MAC + EfuseField.convert(self, efuse) for efuse in self.Fields.CUSTOM_MAC ] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.ADC_CALIBRATION + EfuseField.convert(self, efuse) for efuse in self.Fields.ADC_CALIBRATION ] else: if self.coding_scheme == self.REGS.CODING_SCHEME_NONE: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS_256 ] elif self.coding_scheme == self.REGS.CODING_SCHEME_34: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS_192 ] else: @@ -135,54 +116,43 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ) if self["MAC_VERSION"].get() == 1: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CUSTOM_MAC + EfuseField.convert(self, efuse) for efuse in self.Fields.CUSTOM_MAC ] if self["BLK3_PART_RESERVE"].get(): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.ADC_CALIBRATION ] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CALC + 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: + 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.CUSTOM_MAC: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CUSTOM_MAC + EfuseField.convert(self, efuse) for efuse in self.Fields.CUSTOM_MAC ] new_fields = True for efuse in self.Fields.ADC_CALIBRATION: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.ADC_CALIBRATION ] new_fields = True if new_fields: for e in self.efuses: - if efuse_name == e.name: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): return e raise KeyError @@ -263,8 +233,7 @@ def get_coding_scheme_warnings(self, silent=False): def summary(self): if self["XPD_SDIO_FORCE"].get() == 0: - output = "Flash voltage (VDD_SDIO) determined by GPIO12 on reset " - "(High for 1.8V, Low/NC for 3.3V)." + output = "Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V)" elif self["XPD_SDIO_REG"].get() == 0: output = "Flash voltage (VDD_SDIO) internal regulator disabled by efuse." elif self["XPD_SDIO_TIEH"].get() == 0: @@ -276,7 +245,7 @@ def summary(self): class EfuseField(base_fields.EfuseFieldBase): @staticmethod - def from_tuple(parent, efuse_tuple, type_class): + def convert(parent, efuse): return { "mac": EfuseMacField, "spipin": EfuseSpiPinField, @@ -284,10 +253,7 @@ def from_tuple(parent, efuse_tuple, type_class): "adc_tp": EfuseAdcPointCalibration, "wafer": EfuseWafer, "pkg": EfusePkg, - }.get(type_class, EfuseField)(parent, efuse_tuple) - - def get_info(self): - return "%s (BLOCK%d):" % (self.name, self.block) + }.get(efuse.class_type, EfuseField)(parent, efuse) class EfuseMacField(EfuseField): @@ -402,7 +368,9 @@ def print_field(e, new_value): class EfuseWafer(EfuseField): def get(self, from_read=True): rev_bit0 = self.parent["CHIP_VER_REV1"].get(from_read) + assert self.parent["CHIP_VER_REV1"].bit_len == 1 rev_bit1 = self.parent["CHIP_VER_REV2"].get(from_read) + assert self.parent["CHIP_VER_REV2"].bit_len == 1 apb_ctl_date = self.parent.read_reg(self.parent.REGS.APB_CTL_DATE_ADDR) rev_bit2 = ( apb_ctl_date >> self.parent.REGS.APB_CTL_DATE_S diff --git a/espefuse/efuse/esp32/mem_definition.py b/espefuse/efuse/esp32/mem_definition.py index 0e09030c5..7d29a010a 100644 --- a/espefuse/efuse/esp32/mem_definition.py +++ b/espefuse/efuse/esp32/mem_definition.py @@ -4,7 +4,17 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase +import copy +import os + +import yaml + +from ..mem_definition_base import ( + EfuseBlocksBase, + EfuseFieldsBase, + EfuseRegistersBase, + Field, +) class EfuseDefineRegisters(EfuseRegistersBase): @@ -56,11 +66,10 @@ class EfuseDefineRegisters(EfuseRegistersBase): EFUSE_RD_CHIP_VER_REV2 = 1 << 20 -# fmt: off class EfuseDefineBlocks(EfuseBlocksBase): - __base_regs = EfuseDefineRegisters.DR_REG_EFUSE_BASE # 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_regs + 0x000, __base_regs + 0x01C, None, None, 7, None), @@ -68,6 +77,7 @@ class EfuseDefineBlocks(EfuseBlocksBase): ("BLOCK2", ["secure_boot_v1", "secure_boot_v2"], 2, __base_regs + 0x058, __base_regs + 0x0B8, 8, 1, 8, None), ("BLOCK3", [], 3, __base_regs + 0x078, __base_regs + 0x0D8, 9, 2, 8, None), ] + # fmt: on def get_burn_block_data_names(self): list_of_names = [] @@ -79,87 +89,91 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - - # Lists of efuse fields - EFUSES = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('WR_DIS', "efuse", 0, 0, 0, "uint:16", 1, None, None, "Efuse write disable mask", None), - ('RD_DIS', "efuse", 0, 0, 16, "uint:4", 0, None, None, "Efuse read disable mask", None), - ('CODING_SCHEME', "efuse", 0, 6, 0, "uint:2", 10, 3, None, "Efuse variable block length scheme", - {0: "NONE (BLK1-3 len=256 bits)", - 1: "3/4 (BLK1-3 len=192 bits)", - 2: "REPEAT (BLK1-3 len=128 bits) not supported", - 3: "NONE (BLK1-3 len=256 bits)"}), - ('KEY_STATUS', "efuse", 0, 6, 10, "bool", 10, 3, None, "Usage of efuse block 3 (reserved)", None), - ('MAC', "identity", 0, 1, 0, "bytes:6", 3, None, "mac", "Factory MAC Address", None), - ('MAC_CRC', "identity", 0, 2, 16, "uint:8", 3, None, None, "CRC8 for factory MAC address", None), - ('CHIP_VER_REV1', "identity", 0, 3, 15, "bool", 3, None, None, "Silicon Revision 1", None), - ('CHIP_VER_REV2', "identity", 0, 5, 20, "bool", 6, None, None, "Silicon Revision 2", None), - ("WAFER_VERSION_MINOR", "identity", 0, 5, 24, "uint:2", 6, None, None, "WAFER VERSION MINOR", None), - ('CHIP_PACKAGE', "identity", 0, 3, 9, "uint:3", 3, None, None, "Chip package identifier", None), - ('CHIP_PACKAGE_4BIT', "identity", 0, 3, 2, "uint:1", 3, None, None, "Chip package identifier #4bit", None), - ('XPD_SDIO_FORCE', "config", 0, 4, 16, "bool", 5, None, None, "Ignore MTDI pin (GPIO12) for VDD_SDIO on reset", None), - ('XPD_SDIO_REG', "config", 0, 4, 14, "bool", 5, None, None, "If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset", None), - ('XPD_SDIO_TIEH', "config", 0, 4, 15, "bool", 5, None, None, "If XPD_SDIO_FORCE & XPD_SDIO_REG", - {1: "3.3V", - 0: "1.8V"}), - ('CLK8M_FREQ', "config", 0, 4, 0, "uint:8", None, None, None, "8MHz clock freq override", None), - ('SPI_PAD_CONFIG_CLK', "config", 0, 5, 0, "uint:5", 6, None, "spipin", "Override SD_CLK pad (GPIO6/SPICLK)", None), - ('SPI_PAD_CONFIG_Q', "config", 0, 5, 5, "uint:5", 6, None, "spipin", "Override SD_DATA_0 pad (GPIO7/SPIQ)", None), - ('SPI_PAD_CONFIG_D', "config", 0, 5, 10, "uint:5", 6, None, "spipin", "Override SD_DATA_1 pad (GPIO8/SPID)", None), - ('SPI_PAD_CONFIG_HD', "config", 0, 3, 4, "uint:5", 6, None, "spipin", "Override SD_DATA_2 pad (GPIO9/SPIHD)", None), - ('SPI_PAD_CONFIG_CS0', "config", 0, 5, 15, "uint:5", 6, None, "spipin", "Override SD_CMD pad (GPIO11/SPICS0)", None), - ('DISABLE_SDIO_HOST', "config", 0, 6, 3, "bool", None, None, None, "Disable SDIO host", None), - ('FLASH_CRYPT_CNT', "security", 0, 0, 20, "uint:7", 2, None, "bitcount", "Flash encryption mode counter", None), - ('UART_DOWNLOAD_DIS', "security", 0, 0, 27, "bool", 2, None, None, "Disable UART download mode (ESP32 rev3 only)", None), - ('FLASH_CRYPT_CONFIG', "security", 0, 5, 28, "uint:4", 10, 3, None, "Flash encryption config (key tweak bits)", None), - ('CONSOLE_DEBUG_DISABLE', "security", 0, 6, 2, "bool", 15, None, None, "Disable ROM BASIC interpreter fallback", None), - ('ABS_DONE_0', "security", 0, 6, 4, "bool", 12, None, None, "Secure boot V1 is enabled for bootloader image", None), - ('ABS_DONE_1', "security", 0, 6, 5, "bool", 13, None, None, "Secure boot V2 is enabled for bootloader image", None), - ('JTAG_DISABLE', "security", 0, 6, 6, "bool", 14, None, None, "Disable JTAG", None), - ('DISABLE_DL_ENCRYPT', "security", 0, 6, 7, "bool", 15, None, None, "Disable flash encryption in UART bootloader", None), - ('DISABLE_DL_DECRYPT', "security", 0, 6, 8, "bool", 15, None, None, "Disable flash decryption in UART bootloader", None), - ('DISABLE_DL_CACHE', "security", 0, 6, 9, "bool", 15, None, None, "Disable flash cache in UART bootloader", None), - ('BLK3_PART_RESERVE', "calibration", 0, 3, 14, "bool", 10, 3, None, "BLOCK3 partially served for ADC calibration data", None), - ('ADC_VREF', "calibration", 0, 4, 8, "uint:5", 0, None, "vref", "Voltage reference calibration", None), - ('MAC_VERSION', "identity", 3, 5, 24, "uint:8", 9, 2, None, "Version of the MAC field", - {1: "Custom MAC in BLOCK3"}), - ] - - # if MAC_VERSION is set "1", these efuse fields are in BLOCK3: - CUSTOM_MAC = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('CUSTOM_MAC', "identity", 3, 0, 8, "bytes:6", 9, 2, "mac", "Custom MAC", None), - ('CUSTOM_MAC_CRC', "identity", 3, 0, 0, "uint:8", 9, 2, None, "CRC of custom MAC", None), - ] - - # The len of fields depends on coding scheme: for CODING_SCHEME_NONE - KEYBLOCKS_256 = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK1', "security", 1, 0, 0, "bytes:32", 7, 0, "keyblock", "Flash encryption key", None), - ('BLOCK2', "security", 2, 0, 0, "bytes:32", 8, 1, "keyblock", "Secure boot key", None), - ('BLOCK3', "security", 3, 0, 0, "bytes:32", 9, 2, "keyblock", "Variable Block 3", None), - ] - - # The len of fields depends on coding scheme: for CODING_SCHEME_34 - KEYBLOCKS_192 = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK1', "security", 1, 0, 0, "bytes:24", 7, 0, "keyblock", "Flash encryption key", None), - ('BLOCK2', "security", 2, 0, 0, "bytes:24", 8, 1, "keyblock", "Secure boot key", None), - ('BLOCK3', "security", 3, 0, 0, "bytes:24", 9, 2, "keyblock", "Variable Block 3", None), - ] - - # if BLK3_PART_RESERVE is set, these efuse fields are in BLOCK3: - ADC_CALIBRATION = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('ADC1_TP_LOW', "calibration", 3, 3, 0, "uint:7", 9, 2, "adc_tp", "ADC1 150mV reading", None), - ('ADC1_TP_HIGH', "calibration", 3, 3, 7, "uint:9", 9, 2, "adc_tp", "ADC1 850mV reading", None), - ('ADC2_TP_LOW', "calibration", 3, 3, 16, "uint:7", 9, 2, "adc_tp", "ADC2 150mV reading", None), - ('ADC2_TP_HIGH', "calibration", 3, 3, 23, "uint:9", 9, 2, "adc_tp", "ADC2 850mV reading", None), - ] - - CALC = [ - ("WAFER_VERSION_MAJOR", "identity", 0, None, None, "uint:3", None, None, "wafer", "calc WAFER VERSION MAJOR from CHIP_VER_REV1 and CHIP_VER_REV2 and apb_ctl_date (read only)", None), - ('PKG_VERSION', "identity", 0, None, None, "uint:4", None, None, "pkg", "calc Chip package = CHIP_PACKAGE_4BIT << 3 + CHIP_PACKAGE (read only)", None), - ] -# fmt: on + def __init__(self) -> None: + self.EFUSES = [] + # if MAC_VERSION is set "1", these efuse fields are in BLOCK3: + self.CUSTOM_MAC = [] + # The len of fields depends on coding scheme: for CODING_SCHEME_NONE + self.KEYBLOCKS_256 = [] + # The len of fields depends on coding scheme: for CODING_SCHEME_34 + self.KEYBLOCKS_192 = [] + # if BLK3_PART_RESERVE is set, these efuse fields are in BLOCK3: + self.ADC_CALIBRATION = [] + + 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 == "BLOCK1" or efuse.name == "BLOCK2": + self.KEYBLOCKS_256.append(efuse) + BLOCK = copy.deepcopy(efuse) + BLOCK.type = "bytes:24" + BLOCK.bit_len = 24 * 8 + self.KEYBLOCKS_192.append(BLOCK) + self.ALL_EFUSES[i] = None + + elif efuse.name == "MAC_VERSION": + # A field from BLOCK3, It is used as a template + BLOCK3 = copy.deepcopy(efuse) + BLOCK3.name = "BLOCK3" + BLOCK3.block = 3 + BLOCK3.word = 0 + BLOCK3.pos = 0 + BLOCK3.bit_len = 32 * 8 + BLOCK3.type = "bytes:32" + BLOCK3.category = "security" + BLOCK3.class_type = "keyblock" + BLOCK3.description = "Variable Block 3" + self.KEYBLOCKS_256.append(BLOCK3) + + BLOCK3 = copy.deepcopy(BLOCK3) + BLOCK3.type = "bytes:24" + BLOCK3.bit_len = 24 * 8 + self.KEYBLOCKS_192.append(BLOCK3) + + elif efuse.category == "calibration" and efuse.block == 3: + self.ADC_CALIBRATION.append(efuse) + self.ALL_EFUSES[i] = None + + elif efuse.name in ["CUSTOM_MAC_CRC", "CUSTOM_MAC"]: + self.CUSTOM_MAC.append(efuse) + self.ALL_EFUSES[i] = None + + elif efuse.category == "spi pad": + efuse.class_type = "spipin" + + f = Field() + f.name = "WAFER_VERSION_MAJOR" + f.block = 0 + f.bit_len = 3 + f.type = f"uint:{f.bit_len}" + f.category = "identity" + f.class_type = "wafer" + f.description = "calc WAFER VERSION MAJOR from CHIP_VER_REV1 and CHIP_VER_REV2 and apb_ctl_date (read only)" + self.CALC.append(f) + + f = Field() + f.name = "PKG_VERSION" + f.block = 0 + f.bit_len = 4 + f.type = f"uint:{f.bit_len}" + f.category = "identity" + f.class_type = "pkg" + f.description = ( + "calc Chip package = CHIP_PACKAGE_4BIT << 3 + CHIP_PACKAGE (read only)" + ) + self.CALC.append(f) + + for efuse in self.ALL_EFUSES: + if efuse is not None: + self.EFUSES.append(efuse) + + self.ALL_EFUSES = [] diff --git a/espefuse/efuse/esp32/operations.py b/espefuse/efuse/esp32/operations.py index 69b288f4f..e0f419a1c 100644 --- a/espefuse/efuse/esp32/operations.py +++ b/espefuse/efuse/esp32/operations.py @@ -17,6 +17,7 @@ from ..base_operations import ( add_common_commands, add_force_write_always, + add_show_sensitive_info_option, burn_bit, burn_block_data, burn_efuse, @@ -42,6 +43,7 @@ def add_commands(subparsers, efuses): action="store_true", ) add_force_write_always(p) + add_show_sensitive_info_option(p) p.add_argument( "block", help='Key block to burn. "flash_encryption" (block1), ' @@ -89,6 +91,7 @@ def add_commands(subparsers, efuses): action="store_true", ) add_force_write_always(burn_key_digest) + add_show_sensitive_info_option(burn_key_digest) p = subparsers.add_parser( "set_flash_voltage", @@ -230,7 +233,14 @@ def burn_key(esp, efuses, args): if block_name in ("flash_encryption", "secure_boot_v1"): revers_msg = "\tReversing the byte order" data = data[::-1] - print(" - %s -> [%s]" % (efuse.name, util.hexify(data, " "))) + print(" - %s" % (efuse.name), end=" ") + 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: @@ -290,7 +300,14 @@ def burn_key_digest(esp, efuses, args): "Digest must be %d bytes (%d bits) of raw binary key data." % (len(digest), num_bytes, num_bytes * 8) ) - print(" - %s -> [%s]" % (efuse.name, util.hexify(digest, " "))) + print(" - %s" % (efuse.name), end=" ") + print( + "-> [{}]".format( + util.hexify(digest, " ") + if args.show_sensitive_info + else " ".join(["??"] * len(digest)) + ) + ) efuse.save(digest) if not args.no_protect_key: diff --git a/espefuse/efuse/esp32c2/emulate_efuse_controller.py b/espefuse/efuse/esp32c2/emulate_efuse_controller.py index 1a15f8496..26796dff8 100644 --- a/espefuse/efuse/esp32c2/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32c2/emulate_efuse_controller.py @@ -18,13 +18,13 @@ class EmulateEfuseController(EmulateEfuseControllerBase): CHIP_NAME = "ESP32-C2" mem = None debug = False - Blocks = EfuseDefineBlocks - Fields = EfuseDefineFields - REGS = EfuseDefineRegisters 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_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -55,10 +55,10 @@ def handle_writing_event(self, addr, value): 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): @@ -124,8 +124,7 @@ def get_read_disable_mask(blk): else: block.set(0) else: - for e in self.Fields.EFUSES: - field = self.Fields.get(e) + for field in self.Fields.EFUSES: if ( blk.id == field.block and field.read_disable_bit is not None diff --git a/espefuse/efuse/esp32c2/fields.py b/espefuse/efuse/esp32c2/fields.py index f05ee082d..dda997e58 100644 --- a/espefuse/efuse/esp32c2/fields.py +++ b/espefuse/efuse/esp32c2/fields.py @@ -54,16 +54,15 @@ class EspEfuses(base_fields.EspEfusesBase): Wrapper object to manage the efuse fields in a connected ESP bootloader """ - Blocks = EfuseDefineBlocks() - Fields = EfuseDefineFields() - REGS = EfuseDefineRegisters - BURN_BLOCK_DATA_NAMES = Blocks.get_burn_block_data_names() - BLOCKS_FOR_KEYS = Blocks.get_blocks_for_keys() - 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 @@ -85,53 +84,40 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ] if not skip_connect: self.get_coding_scheme_warnings() - self.efuses = [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.EFUSES - ] + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.KEYBLOCKS + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS ] if skip_connect: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] else: if self["BLK_VERSION_MINOR"].get() == 1: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] def __getitem__(self, efuse_name): """Return the efuse field with the given name""" for e in self.efuses: - if efuse_name == e.name: + 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: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + 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: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): return e raise KeyError @@ -147,10 +133,6 @@ def print_status_regs(self): ) ) - def get_block_errors(self, block_num): - """Returns (error count, failure boolean flag)""" - return self.blocks[block_num].num_errors, self.blocks[block_num].fail - def efuse_controller_setup(self): self.set_efuse_timing() self.clear_pgm_registers() @@ -170,9 +152,13 @@ def clear_pgm_registers(self): 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" ) @@ -238,6 +224,13 @@ def set_efuse_timing(self): "The eFuse supports only xtal=26M and 40M (xtal was %d)" % xtal_freq ) + self.update_reg(self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_NUM_M, 0xFF) + self.update_reg( + self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_CLK_DIV_M, 0x28 + ) + self.update_reg( + self.REGS.EFUSE_WR_TIM_CONF1_REG, self.REGS.EFUSE_PWR_ON_NUM_M, 0x3000 + ) self.update_reg( self.REGS.EFUSE_WR_TIM_CONF2_REG, self.REGS.EFUSE_PWR_OFF_NUM_M, 0x190 ) @@ -260,12 +253,9 @@ def get_coding_scheme_warnings(self, silent=False): self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR_REG + offs * 4) for offs in range(1) ] - data = BitArray() + block.err_bitarray.pos = 0 for word in reversed(words): - data.append("uint:32=%d" % word) - # pos=32 because EFUSE_WR_DIS goes first it is 32bit long - # and not under error control - block.err_bitarray.overwrite(data, pos=32) + block.err_bitarray.overwrite(BitArray("uint:32=%d" % word)) block.num_errors = block.err_bitarray.count(True) block.fail = block.num_errors != 0 else: @@ -296,28 +286,13 @@ def summary(self): class EfuseField(base_fields.EfuseFieldBase): @staticmethod - def from_tuple(parent, efuse_tuple, type_class): + def convert(parent, efuse): return { "mac": EfuseMacField, "keypurpose": EfuseKeyPurposeField, "t_sensor": EfuseTempSensor, "adc_tp": EfuseAdcPointCalibration, - }.get(type_class, EfuseField)(parent, efuse_tuple) - - def get_info(self): - output = "%s (BLOCK%d)" % (self.name, self.block) - errs, fail = self.parent.get_block_errors(self.block) - if errs != 0 or fail: - output += ( - "[FAIL:%d]" % (fail) - if self.block == 0 - else "[ERRS:%d FAIL:%d]" % (errs, fail) - ) - if self.efuse_class == "keyblock": - name = self.parent.blocks[self.block].key_purpose_name - if name is not None: - output += "\n Purpose: %s\n " % (self.parent[name].get()) - return output + }.get(efuse.class_type, EfuseField)(parent, efuse) class EfuseTempSensor(EfuseField): @@ -393,22 +368,13 @@ def print_field(e, new_value): class EfuseKeyPurposeField(EfuseField): KEY_PURPOSES = [ - ("USER", 0, None), # User purposes (software-only use) - ( - "XTS_AES_128_KEY", - 1, - None, - ), # (whole 256bits) XTS_AES_128_KEY (flash/PSRAM encryption) - ( - "XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS", - 2, - None, - ), # (lo 128bits) XTS_AES_128_KEY (flash/PSRAM encryption) - ( - "SECURE_BOOT_DIGEST", - 3, - "DIGEST", - ), # (hi 128bits)SECURE_BOOT_DIGEST (Secure Boot key digest) + # fmt: off + ("USER", 0, None), # User purposes (software-only use) + ("XTS_AES_128_KEY", 1, None), # (whole 256bits) flash/PSRAM encryption + ("XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS", 2, None), # (lo 128bits) flash/PSRAM encryption + ("SECURE_BOOT_DIGEST", 3, "DIGEST"), + # (hi 128bits) Secure Boot key digest + # fmt: on ] KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES] diff --git a/espefuse/efuse/esp32c2/mem_definition.py b/espefuse/efuse/esp32c2/mem_definition.py index 0127ddc7a..7adb0111f 100644 --- a/espefuse/efuse/esp32c2/mem_definition.py +++ b/espefuse/efuse/esp32c2/mem_definition.py @@ -4,36 +4,43 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase +import copy +import os +import yaml + +from ..mem_definition_base import ( + EfuseBlocksBase, + EfuseFieldsBase, + EfuseRegistersBase, +) -# fmt: off -class EfuseDefineRegisters(EfuseRegistersBase): - EFUSE_MEM_SIZE = (0x01FC + 4) +class EfuseDefineRegisters(EfuseRegistersBase): + EFUSE_MEM_SIZE = 0x01FC + 4 # EFUSE registers & command/conf values - DR_REG_EFUSE_BASE = 0x60008800 - EFUSE_PGM_DATA0_REG = DR_REG_EFUSE_BASE - EFUSE_PGM_CHECK_VALUE0_REG = DR_REG_EFUSE_BASE + 0x020 - EFUSE_CLK_REG = DR_REG_EFUSE_BASE + 0x88 - EFUSE_CONF_REG = DR_REG_EFUSE_BASE + 0x8C - EFUSE_STATUS_REG = DR_REG_EFUSE_BASE + 0x90 - EFUSE_CMD_REG = DR_REG_EFUSE_BASE + 0x94 + DR_REG_EFUSE_BASE = 0x60008800 + EFUSE_PGM_DATA0_REG = DR_REG_EFUSE_BASE + EFUSE_PGM_CHECK_VALUE0_REG = DR_REG_EFUSE_BASE + 0x020 + EFUSE_CLK_REG = DR_REG_EFUSE_BASE + 0x88 + EFUSE_CONF_REG = DR_REG_EFUSE_BASE + 0x8C + EFUSE_STATUS_REG = DR_REG_EFUSE_BASE + 0x90 + EFUSE_CMD_REG = DR_REG_EFUSE_BASE + 0x94 EFUSE_RD_REPEAT_ERR_REG = DR_REG_EFUSE_BASE + 0x80 - EFUSE_RD_RS_ERR_REG = DR_REG_EFUSE_BASE + 0x84 - EFUSE_WRITE_OP_CODE = 0x5A5A - EFUSE_READ_OP_CODE = 0x5AA5 - EFUSE_PGM_CMD_MASK = 0x3 - EFUSE_PGM_CMD = 0x2 - EFUSE_READ_CMD = 0x1 + EFUSE_RD_RS_ERR_REG = DR_REG_EFUSE_BASE + 0x84 + 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_ERR_REG, None, None, None), # BLOCK0 - (EFUSE_RD_RS_ERR_REG, 0x7, 0, 3), # BLOCK1 - (EFUSE_RD_RS_ERR_REG, 0x7, 4, 7), # BLOCK2 - (EFUSE_RD_RS_ERR_REG, 0x7, 8, 11), # BLOCK3 + (EFUSE_RD_REPEAT_ERR_REG, None, None, None), # BLOCK0 + (EFUSE_RD_RS_ERR_REG, 0x7, 0, 3), # BLOCK1 + (EFUSE_RD_RS_ERR_REG, 0x7, 4, 7), # BLOCK2 + (EFUSE_RD_RS_ERR_REG, 0x7, 8, 11), # BLOCK3 ] EFUSE_WR_TIM_CONF2_REG = DR_REG_EFUSE_BASE + 0x118 @@ -44,12 +51,24 @@ class EfuseDefineRegisters(EfuseRegistersBase): EFUSE_TPGM_INACTIVE_S = 8 EFUSE_TPGM_INACTIVE_M = 0xFF << EFUSE_TPGM_INACTIVE_S + EFUSE_WR_TIM_CONF1_REG = DR_REG_EFUSE_BASE + 0x114 + EFUSE_PWR_ON_NUM_S = 8 + EFUSE_PWR_ON_NUM_M = 0x0000FFFF << EFUSE_PWR_ON_NUM_S -class EfuseDefineBlocks(EfuseBlocksBase): + EFUSE_DAC_CONF_REG = DR_REG_EFUSE_BASE + 0x108 + 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", ["BLOCK0"], 0, __base_rd_regs + 0x02C, __base_wr_regs, None, None, 2, None), @@ -57,6 +76,7 @@ class EfuseDefineBlocks(EfuseBlocksBase): ("BLOCK2", ["BLOCK2"], 2, __base_rd_regs + 0x040, __base_wr_regs, 6, None, 8, None), ("BLOCK_KEY0", ["BLOCK3"], 3, __base_rd_regs + 0x060, __base_wr_regs, 7, [0, 1], 8, None), ] + # fmt: on def get_burn_block_data_names(self): list_of_names = [] @@ -70,87 +90,58 @@ def get_burn_block_data_names(self): return list_of_names def get_blocks_for_keys(self): - return ['BLOCK_KEY0'] + return ["BLOCK_KEY0"] class EfuseDefineFields(EfuseFieldsBase): - - # List of efuse fields from TRM the chapter eFuse Controller. - EFUSES = [ - # - # Parameters in BLOCK0 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("WR_DIS", "efuse", 0, 0, 0, "uint:8", None, None, None, "Disables programming of individual eFuses", None), - ("RD_DIS", "efuse", 0, 1, 0, "uint:2", 0, None, None, "Disables software reading from BLOCK3", None), - ("WDT_DELAY_SEL", "WDT config", 0, 1, 2, "uint:2", 1, None, None, "RTC WDT timeout threshold", None), - ("DIS_PAD_JTAG", "jtag config", 0, 1, 4, "bool", 1, None, None, "Permanently disable JTAG access via pads" - "USB JTAG is controlled separately", None), - ("DIS_DOWNLOAD_ICACHE", "security", 0, 1, 5, "bool", 1, None, None, "Disables iCache in download mode", None), - ("DIS_DOWNLOAD_MANUAL_ENCRYPT", "security", 0, 1, 6, "bool", 2, None, None, "Disables flash encryption in Download boot modes", - None), - ("SPI_BOOT_CRYPT_CNT", "security", 0, 1, 7, "uint:3", 2, None, None, "Enables encryption and decryption, when an SPI boot" - "mode is set. Enabled when 1 or 3 bits are set," - "disabled otherwise", - {0: "Disable", - 1: "Enable", - 3: "Disable", - 7: "Enable"}), - ("XTS_KEY_LENGTH_256", "security", 0, 1, 10, "bool", 2, None, None, "Flash encryption key length", - {0: "128 bits key", - 1: "256 bits key"}), - ("UART_PRINT_CONTROL", "config", 0, 1, 11, "uint:2", 3, None, None, "Set UART boot message output mode", - {0: "Force print", - 1: "Low-level print controlled by GPIO 8", - 3: "High-level print controlled by GPIO 8", - 7: "Print force disabled"}), - ("FORCE_SEND_RESUME", "config", 0, 1, 13, "bool", 3, None, None, "Force ROM code to send a resume cmd during SPI boot", - None), - ("DIS_DOWNLOAD_MODE", "security", 0, 1, 14, "bool", 3, None, None, "Disables all Download boot modes", None), - ("DIS_DIRECT_BOOT", "config", 0, 1, 15, "bool", 3, None, None, "Disable direct_boot mode", None), - ("ENABLE_SECURITY_DOWNLOAD", "security", 0, 1, 16, "bool", 3, None, None, "Enables secure UART download mode " - "(read/write flash only)", None), - ("FLASH_TPUW", "flash config", 0, 1, 17, "uint:4", 3, None, None, "Configures flash startup delay after SoC power-up, " - "unit is (ms/2). When the value is 15, delay is 7.5 ms", - None), - ("SECURE_BOOT_EN", "security", 0, 1, 21, "bool", 2, None, None, "Configures secure boot", None), - ("SECURE_VERSION", "identity", 0, 1, 22, "uint:4", 4, None, "bitcount", "Secure version (anti-rollback feature)", None), - ("CUSTOM_MAC_USED", "identity", 0, 1, 26, "bool", 4, None, None, "Enable CUSTOM_MAC programming", None), - ("DISABLE_WAFER_VERSION_MAJOR", "config", 0, 1, 27, "bool", 4, None, None, "Disables check of wafer version major", None), - ("DISABLE_BLK_VERSION_MAJOR", "config", 0, 1, 28, "bool", 4, None, None, "Disables check of blk version major", None), - - # - # Parameters in BLOCK1 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("CUSTOM_MAC", "identity", 1, 0, 0, "bytes:6", 5, None, 'mac', "Custom MAC addr", None), - - # - # Parameters in BLOCK2 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("MAC", "identity", 2, 0, 0, "bytes:6", 6, None, 'mac', "Factory MAC Address", None), - ("WAFER_VERSION_MINOR", "identity", 2, 1, 16, "uint:4", 6, None, None, "Minor WAFER version", None), - ("WAFER_VERSION_MAJOR", "identity", 2, 1, 20, "uint:2", 6, None, None, "Major WAFER version", None), - ("PKG_VERSION", "identity", 2, 1, 22, "uint:3", 6, None, None, "Package version", None), - ("BLK_VERSION_MINOR", "identity", 2, 1, 25, "uint:3", 6, None, None, "Minor version of BLOCK2", - {0: "No calibration", 1: "With calibration"}), - - ("BLK_VERSION_MAJOR", "identity", 2, 1, 28, "uint:2", 6, None, None, "Major version of BLOCK2", None), - ("LDO_VOL_BIAS_CONFIG_HIGH", "ldo", 2, 2, 0, "uint:27", 6, None, None, "", None), - ("PVT_LOW", "pvt", 2, 2, 27, "uint:5", 6, None, None, "", None), - ("PVT_HIGH", "pvt", 2, 3, 0, "uint:10", 6, None, None, "", None), - ("ADC_CALIBRATION_0", "adc_calib", 2, 3, 10, "uint:22", 6, None, None, "", None), - ("ADC_CALIBRATION_1", "adc_calib", 2, 4, 0, "uint:32", 6, None, None, "", None), - ("ADC_CALIBRATION_2", "adc_calib", 2, 5, 0, "uint:32", 6, None, None, "", None), - ] - - KEYBLOCKS = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK_KEY0', "security", 3, 0, 0, "bytes:32", 7, [0, 1], "keyblock", "BLOCK_KEY0 - 256-bits. 256-bit key of Flash Encryption", None), - ('BLOCK_KEY0_LOW_128', "security", 3, 0, 0, "bytes:16", 7, 0, "keyblock", "BLOCK_KEY0 - lower 128-bits. 128-bit key of Flash Encryption", None), - ('BLOCK_KEY0_HI_128', "security", 3, 4, 0, "bytes:16", 7, 1, "keyblock", "BLOCK_KEY0 - higher 128-bits. 128-bits key of Secure Boot.", None), - ] - - # if BLK_VERSION_MINOR is 1, these efuse fields are in BLOCK2 - BLOCK2_CALIBRATION_EFUSES = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ] -# fmt: on + 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 = [] + + 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_KEY0"]: + self.KEYBLOCKS.append(efuse) + BLOCK_KEY0_LOW_128 = copy.deepcopy(efuse) + BLOCK_KEY0_LOW_128.name = "BLOCK_KEY0_LOW_128" + BLOCK_KEY0_LOW_128.type = "bytes:16" + BLOCK_KEY0_LOW_128.bit_len = 16 * 8 + BLOCK_KEY0_LOW_128.description = ( + "BLOCK_KEY0 - lower 128-bits. 128-bit key of Flash Encryption" + ) + BLOCK_KEY0_LOW_128.read_disable_bit = efuse.read_disable_bit[0] + self.KEYBLOCKS.append(BLOCK_KEY0_LOW_128) + BLOCK_KEY0_HI_128 = copy.deepcopy(efuse) + BLOCK_KEY0_HI_128.name = "BLOCK_KEY0_HI_128" + BLOCK_KEY0_HI_128.word = 4 + BLOCK_KEY0_HI_128.type = "bytes:16" + BLOCK_KEY0_HI_128.bit_len = 16 * 8 + BLOCK_KEY0_HI_128.description = ( + "BLOCK_KEY0 - higher 128-bits. 128-bits key of Secure Boot" + ) + BLOCK_KEY0_HI_128.read_disable_bit = efuse.read_disable_bit[1] + self.KEYBLOCKS.append(BLOCK_KEY0_HI_128) + self.ALL_EFUSES[i] = None + + elif efuse.category == "calibration": + self.BLOCK2_CALIBRATION_EFUSES.append(efuse) + self.ALL_EFUSES[i] = None + + for efuse in self.ALL_EFUSES: + if efuse is not None: + self.EFUSES.append(efuse) + + self.ALL_EFUSES = [] diff --git a/espefuse/efuse/esp32c2/operations.py b/espefuse/efuse/esp32c2/operations.py index 3fc19dcc8..fb7324e97 100644 --- a/espefuse/efuse/esp32c2/operations.py +++ b/espefuse/efuse/esp32c2/operations.py @@ -17,6 +17,7 @@ from ..base_operations import ( add_common_commands, add_force_write_always, + add_show_sensitive_info_option, burn_bit, burn_block_data, burn_efuse, @@ -52,6 +53,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -103,6 +105,7 @@ def add_commands(subparsers, efuses): ) 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( "keyfile", help="Key file to digest (PEM format)", type=argparse.FileType("rb") ) @@ -239,7 +242,13 @@ def burn_key(esp, efuses, args, digest=None): if keypurpose.startswith("XTS_AES_"): revers_msg = "\tReversing byte order for AES-XTS hardware peripheral" data = data[::-1] - print("-> [%s]" % (util.hexify(data, " "))) + 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: diff --git a/espefuse/efuse/esp32c3/emulate_efuse_controller.py b/espefuse/efuse/esp32c3/emulate_efuse_controller.py index 71381a23d..2d812a10d 100644 --- a/espefuse/efuse/esp32c3/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32c3/emulate_efuse_controller.py @@ -16,13 +16,13 @@ class EmulateEfuseController(EmulateEfuseControllerBase): CHIP_NAME = "ESP32-C3" mem = None debug = False - Blocks = EfuseDefineBlocks - Fields = EfuseDefineFields - REGS = EfuseDefineRegisters 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_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ def handle_writing_event(self, addr, value): 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 --git a/espefuse/efuse/esp32c3/fields.py b/espefuse/efuse/esp32c3/fields.py index 48ab06249..7a09c65c5 100644 --- a/espefuse/efuse/esp32c3/fields.py +++ b/espefuse/efuse/esp32c3/fields.py @@ -54,16 +54,15 @@ class EspEfuses(base_fields.EspEfusesBase): Wrapper object to manage the efuse fields in a connected ESP bootloader """ - Blocks = EfuseDefineBlocks() - Fields = EfuseDefineFields() - REGS = EfuseDefineRegisters - BURN_BLOCK_DATA_NAMES = Blocks.get_burn_block_data_names() - BLOCKS_FOR_KEYS = Blocks.get_blocks_for_keys() - 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 @@ -85,59 +84,43 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ] if not skip_connect: self.get_coding_scheme_warnings() - self.efuses = [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.EFUSES - ] + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.KEYBLOCKS + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS ] if skip_connect: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] else: if self["BLK_VERSION_MAJOR"].get() == 1: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CALC + 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: + 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: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + 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: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): return e raise KeyError @@ -158,10 +141,6 @@ def print_status_regs(self): ) ) - def get_block_errors(self, block_num): - """Returns (error count, failure boolean flag)""" - return self.blocks[block_num].num_errors, self.blocks[block_num].fail - def efuse_controller_setup(self): self.set_efuse_timing() self.clear_pgm_registers() @@ -181,9 +160,13 @@ def clear_pgm_registers(self): 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" ) @@ -249,6 +232,13 @@ def set_efuse_timing(self): "The eFuse supports only xtal=40M (xtal was %d)" % apb_freq ) + self.update_reg(self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_NUM_M, 0xFF) + self.update_reg( + self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_CLK_DIV_M, 0x28 + ) + self.update_reg( + self.REGS.EFUSE_WR_TIM_CONF1_REG, self.REGS.EFUSE_PWR_ON_NUM_M, 0x3000 + ) self.update_reg( self.REGS.EFUSE_WR_TIM_CONF2_REG, self.REGS.EFUSE_PWR_OFF_NUM_M, 0x190 ) @@ -262,12 +252,9 @@ def get_coding_scheme_warnings(self, silent=False): self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR0_REG + offs * 4) for offs in range(5) ] - data = BitArray() + block.err_bitarray.pos = 0 for word in reversed(words): - data.append("uint:32=%d" % word) - # pos=32 because EFUSE_WR_DIS goes first it is 32bit long - # and not under error control - block.err_bitarray.overwrite(data, pos=32) + block.err_bitarray.overwrite(BitArray("uint:32=%d" % word)) block.num_errors = block.err_bitarray.count(True) block.fail = block.num_errors != 0 else: @@ -302,35 +289,22 @@ def summary(self): class EfuseField(base_fields.EfuseFieldBase): @staticmethod - def from_tuple(parent, efuse_tuple, type_class): + def convert(parent, efuse): return { "mac": EfuseMacField, "keypurpose": EfuseKeyPurposeField, "t_sensor": EfuseTempSensor, "adc_tp": EfuseAdcPointCalibration, "wafer": EfuseWafer, - }.get(type_class, EfuseField)(parent, efuse_tuple) - - def get_info(self): - output = "%s (BLOCK%d)" % (self.name, self.block) - errs, fail = self.parent.get_block_errors(self.block) - if errs != 0 or fail: - output += ( - "[FAIL:%d]" % (fail) - if self.block == 0 - else "[ERRS:%d FAIL:%d]" % (errs, fail) - ) - if self.efuse_class == "keyblock": - name = self.parent.blocks[self.block].key_purpose_name - if name is not None: - output += "\n Purpose: %s\n " % (self.parent[name].get()) - return output + }.get(efuse.class_type, EfuseField)(parent, efuse) class EfuseWafer(EfuseField): def get(self, from_read=True): hi_bits = self.parent["WAFER_VERSION_MINOR_HI"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_HI"].bit_len == 1 lo_bits = self.parent["WAFER_VERSION_MINOR_LO"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_LO"].bit_len == 3 return (hi_bits << 3) + lo_bits def save(self, new_value): @@ -459,6 +433,14 @@ def get(self, from_read=True): 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))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"): + raise esptool.FatalError(f"{self.name} can not have {str_new_value} key due to a hardware bug (please see TRM for more details)") return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/espefuse/efuse/esp32c3/mem_definition.py b/espefuse/efuse/esp32c3/mem_definition.py index a0405a13b..610d64e17 100644 --- a/espefuse/efuse/esp32c3/mem_definition.py +++ b/espefuse/efuse/esp32c3/mem_definition.py @@ -4,24 +4,31 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase +import os +import yaml + +from ..mem_definition_base import ( + EfuseBlocksBase, + EfuseFieldsBase, + EfuseRegistersBase, + Field, +) -# fmt: off -class EfuseDefineRegisters(EfuseRegistersBase): - EFUSE_MEM_SIZE = (0x01FC + 4) +class EfuseDefineRegisters(EfuseRegistersBase): + EFUSE_MEM_SIZE = 0x01FC + 4 # EFUSE registers & command/conf values - DR_REG_EFUSE_BASE = 0x60008800 - 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 + DR_REG_EFUSE_BASE = 0x60008800 + 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 @@ -32,53 +39,65 @@ class EfuseDefineRegisters(EfuseRegistersBase): 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 + EFUSE_WRITE_OP_CODE = 0x5A5A + EFUSE_READ_OP_CODE = 0x5AA5 + EFUSE_PGM_CMD_MASK = 0x3 + EFUSE_PGM_CMD = 0x2 + EFUSE_READ_CMD = 0x1 # this chip has a design error so fail_bit is shifted by one block but err_num is in the correct place BLOCK_FAIL_BIT = [ # error_reg, fail_bit - (EFUSE_RD_REPEAT_ERR0_REG, None), # BLOCK0 - (EFUSE_RD_RS_ERR0_REG, 7), # MAC_SPI_8M_0 - (EFUSE_RD_RS_ERR0_REG, 11), # BLOCK_SYS_DATA - (EFUSE_RD_RS_ERR0_REG, 15), # BLOCK_USR_DATA - (EFUSE_RD_RS_ERR0_REG, 19), # BLOCK_KEY0 - (EFUSE_RD_RS_ERR0_REG, 23), # BLOCK_KEY1 - (EFUSE_RD_RS_ERR0_REG, 27), # BLOCK_KEY2 - (EFUSE_RD_RS_ERR0_REG, 31), # BLOCK_KEY3 - (EFUSE_RD_RS_ERR1_REG, 3), # BLOCK_KEY4 - (EFUSE_RD_RS_ERR1_REG, 7), # BLOCK_KEY5 - (EFUSE_RD_RS_ERR1_REG, None), # BLOCK_SYS_DATA2 + (EFUSE_RD_REPEAT_ERR0_REG, None), # BLOCK0 + (EFUSE_RD_RS_ERR0_REG, 7), # MAC_SPI_8M_0 + (EFUSE_RD_RS_ERR0_REG, 11), # BLOCK_SYS_DATA + (EFUSE_RD_RS_ERR0_REG, 15), # BLOCK_USR_DATA + (EFUSE_RD_RS_ERR0_REG, 19), # BLOCK_KEY0 + (EFUSE_RD_RS_ERR0_REG, 23), # BLOCK_KEY1 + (EFUSE_RD_RS_ERR0_REG, 27), # BLOCK_KEY2 + (EFUSE_RD_RS_ERR0_REG, 31), # BLOCK_KEY3 + (EFUSE_RD_RS_ERR1_REG, 3), # BLOCK_KEY4 + (EFUSE_RD_RS_ERR1_REG, 7), # BLOCK_KEY5 + (EFUSE_RD_RS_ERR1_REG, None), # BLOCK_SYS_DATA2 ] BLOCK_NUM_ERRORS = [ # error_reg, err_num_mask, err_num_offs - (EFUSE_RD_REPEAT_ERR0_REG, None, None), # BLOCK0 - (EFUSE_RD_RS_ERR0_REG, 0x7, 0), # MAC_SPI_8M_0 - (EFUSE_RD_RS_ERR0_REG, 0x7, 4), # BLOCK_SYS_DATA - (EFUSE_RD_RS_ERR0_REG, 0x7, 8), # BLOCK_USR_DATA - (EFUSE_RD_RS_ERR0_REG, 0x7, 12), # BLOCK_KEY0 - (EFUSE_RD_RS_ERR0_REG, 0x7, 16), # BLOCK_KEY1 - (EFUSE_RD_RS_ERR0_REG, 0x7, 20), # BLOCK_KEY2 - (EFUSE_RD_RS_ERR0_REG, 0x7, 24), # BLOCK_KEY3 - (EFUSE_RD_RS_ERR0_REG, 0x7, 28), # BLOCK_KEY4 - (EFUSE_RD_RS_ERR1_REG, 0x7, 0), # BLOCK_KEY5 - (EFUSE_RD_RS_ERR1_REG, 0x7, 4), # BLOCK_SYS_DATA2 + (EFUSE_RD_REPEAT_ERR0_REG, None, None), # BLOCK0 + (EFUSE_RD_RS_ERR0_REG, 0x7, 0), # MAC_SPI_8M_0 + (EFUSE_RD_RS_ERR0_REG, 0x7, 4), # BLOCK_SYS_DATA + (EFUSE_RD_RS_ERR0_REG, 0x7, 8), # BLOCK_USR_DATA + (EFUSE_RD_RS_ERR0_REG, 0x7, 12), # BLOCK_KEY0 + (EFUSE_RD_RS_ERR0_REG, 0x7, 16), # BLOCK_KEY1 + (EFUSE_RD_RS_ERR0_REG, 0x7, 20), # BLOCK_KEY2 + (EFUSE_RD_RS_ERR0_REG, 0x7, 24), # BLOCK_KEY3 + (EFUSE_RD_RS_ERR0_REG, 0x7, 28), # BLOCK_KEY4 + (EFUSE_RD_RS_ERR1_REG, 0x7, 0), # BLOCK_KEY5 + (EFUSE_RD_RS_ERR1_REG, 0x7, 4), # 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 -class EfuseDefineBlocks(EfuseBlocksBase): + # 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), @@ -93,6 +112,7 @@ class EfuseDefineBlocks(EfuseBlocksBase): ("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 = [] @@ -107,141 +127,63 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - - # List of efuse fields from TRM the chapter eFuse Controller. - EFUSES = [ - # - # Table 51: Parameters in BLOCK0 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("WR_DIS", "efuse", 0, 0, 0, "uint:32", None, None, None, "Disables programming of individual eFuses", None), - ("RD_DIS", "efuse", 0, 1, 0, "uint:7", 0, None, None, "Disables software reading from BLOCK4-10", None), - ("DIS_ICACHE", "config", 0, 1, 8, "bool", 2, None, None, "Disables ICache", None), - ("DIS_USB_JTAG", "usb config", 0, 1, 9, "bool", 2, None, None, "Disables USB JTAG. " - "JTAG access via pads is controlled separately", None), - ("DIS_DOWNLOAD_ICACHE", "config", 0, 1, 10, "bool", 2, None, None, "Disables Icache when SoC is in Download mode", None), - ("DIS_USB_DEVICE", "usb config", 0, 1, 11, "bool", 2, None, None, "Disables USB DEVICE", None), - ("DIS_FORCE_DOWNLOAD", "config", 0, 1, 12, "bool", 2, None, None, "Disables forcing chip into Download mode", None), - ("DIS_CAN", "config", 0, 1, 14, "bool", 2, None, None, "Disables the TWAI Controller hardware", None), - ("SOFT_DIS_JTAG", "jtag config", 0, 1, 16, "uint:3", 2, None, None, "Software disables JTAG. When software disabled, " - "JTAG can be activated temporarily by HMAC peripheral", - None), - ("DIS_PAD_JTAG", "jtag config", 0, 1, 19, "bool", 2, None, None, "Permanently disable JTAG access via pads. " - "USB JTAG is controlled separately.", None), - ("DIS_DOWNLOAD_MANUAL_ENCRYPT", "security", 0, 1, 20, "bool", 2, None, None, "Disables flash encryption when in download boot modes", - None), - ("USB_EXCHG_PINS", "usb config", 0, 1, 25, "bool", 30, None, None, "Exchanges USB D+ and D- pins", None), - ("VDD_SPI_AS_GPIO", "config", 0, 1, 26, "bool", 30, None, None, "Set this bit to vdd spi pin function as gpio", None), - ("BTLC_GPIO_ENABLE", "config", 0, 1, 27, "uint:2", 30, None, None, "Enable btlc gpio", None), - ("POWERGLITCH_EN", "config", 0, 1, 29, "bool", 30, None, None, "Set this bit to enable power glitch function", None), - ("POWER_GLITCH_DSENSE", "config", 0, 1, 30, "uint:2", 30, None, None, "Sample delay configuration of power glitch", None), - ("WDT_DELAY_SEL", "WDT config", 0, 2, 16, "bool", 3, None, None, "Selects RTC WDT timeout threshold at startup", None), - ("SPI_BOOT_CRYPT_CNT", "security", 0, 2, 18, "uint:3", 4, None, "bitcount", "Enables encryption and decryption, when an SPI boot " - "mode is set. Enabled when 1 or 3 bits are set," - "disabled otherwise", - {0: "Disable", - 1: "Enable", - 3: "Disable", - 7: "Enable"}), - ("SECURE_BOOT_KEY_REVOKE0", "security", 0, 2, 21, "bool", 5, None, None, "If set, revokes use of secure boot key digest 0", None), - ("SECURE_BOOT_KEY_REVOKE1", "security", 0, 2, 22, "bool", 6, None, None, "If set, revokes use of secure boot key digest 1", None), - ("SECURE_BOOT_KEY_REVOKE2", "security", 0, 2, 23, "bool", 7, None, None, "If set, revokes use of secure boot key digest 2", None), - ("KEY_PURPOSE_0", "security", 0, 2, 24, "uint:4", 8, None, "keypurpose", "KEY0 purpose", None), - ("KEY_PURPOSE_1", "security", 0, 2, 28, "uint:4", 9, None, "keypurpose", "KEY1 purpose", None), - ("KEY_PURPOSE_2", "security", 0, 3, 0, "uint:4", 10, None, "keypurpose", "KEY2 purpose", None), - ("KEY_PURPOSE_3", "security", 0, 3, 4, "uint:4", 11, None, "keypurpose", "KEY3 purpose", None), - ("KEY_PURPOSE_4", "security", 0, 3, 8, "uint:4", 12, None, "keypurpose", "KEY4 purpose", None), - ("KEY_PURPOSE_5", "security", 0, 3, 12, "uint:4", 13, None, "keypurpose", "KEY5 purpose", None), - ("SECURE_BOOT_EN", "security", 0, 3, 20, "bool", 15, None, None, "Enables secure boot", None), - ("SECURE_BOOT_AGGRESSIVE_REVOKE", "security", 0, 3, 21, "bool", 16, None, None, "Enables aggressive secure boot key revocation mode", - None), - ("FLASH_TPUW", "flash config", 0, 3, 28, "uint:4", 18, None, None, "Configures flash startup delay after SoC power-up, " - "unit is (ms/2). When the value is 15, delay is 7.5 ms", - None), - ("DIS_DOWNLOAD_MODE", "security", 0, 4, 0, "bool", 18, None, None, "Disables all Download boot modes", None), - ("DIS_DIRECT_BOOT", "config", 0, 4, 1, "bool", 18, None, None, "Disables direct boot mode", None), - ("DIS_USB_SERIAL_JTAG_ROM_PRINT", "config", 0, 4, 2, "bool", 18, None, None, "Disables USB-Serial-JTAG ROM printing", None), - ("DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE", "usb config", 0, 4, 4, "bool", 18, None, None, "Disables USB-Serial-JTAG download feature in " - "UART download boot mode", None), - ("ENABLE_SECURITY_DOWNLOAD", "security", 0, 4, 5, "bool", 18, None, None, "Enables secure UART download mode " - "(read/write flash only)", None), - ("UART_PRINT_CONTROL", "config", 0, 4, 6, "uint:2", 18, None, None, "Sets the default UART boot message output mode", - {0: "Enabled", - 1: "Enable when GPIO8 is low at reset", - 2: "Enable when GPIO8 is high at reset", - 3: "Disabled"}), - ("FORCE_SEND_RESUME", "config", 0, 4, 13, "bool", 18, None, None, "Force ROM code to send a resume command during SPI boot" - "during SPI boot", None), - ("SECURE_VERSION", "identity", 0, 4, 14, "uint:16", 18, None, "bitcount", "Secure version (used by ESP-IDF anti-rollback feature)", - None), - ("ERR_RST_ENABLE", "config", 0, 4, 31, "bool", 19, None, None, "Use BLOCK0 to check error record registers", - {0: "without check", - 1: "with check"}), - ("DISABLE_WAFER_VERSION_MAJOR", "config", 0, 5, 0, "bool", 19, None, None, "Disables check of wafer version major", None), - ("DISABLE_BLK_VERSION_MAJOR", "config", 0, 5, 1, "bool", 19, None, None, "Disables check of blk version major", None), - # - # Table 53: Parameters in BLOCK1-10 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("MAC", "identity", 1, 0, 0, "bytes:6", 20, None, "mac", "Factory MAC Address", None), - ("SPI_PAD_CONFIG_CLK", "spi_pad_config", 1, 1, 16, "uint:6", 20, None, None, "SPI CLK pad", None), - ("SPI_PAD_CONFIG_Q", "spi_pad_config", 1, 1, 22, "uint:6", 20, None, None, "SPI Q (D1) pad", None), - ("SPI_PAD_CONFIG_D", "spi_pad_config", 1, 1, 28, "uint:6", 20, None, None, "SPI D (D0) pad", None), - ("SPI_PAD_CONFIG_CS", "spi_pad_config", 1, 2, 2, "uint:6", 20, None, None, "SPI CS pad", None), - ("SPI_PAD_CONFIG_HD", "spi_pad_config", 1, 2, 8, "uint:6", 20, None, None, "SPI HD (D3) pad", None), - ("SPI_PAD_CONFIG_WP", "spi_pad_config", 1, 2, 14, "uint:6", 20, None, None, "SPI WP (D2) pad", None), - ("SPI_PAD_CONFIG_DQS", "spi_pad_config", 1, 2, 20, "uint:6", 20, None, None, "SPI DQS pad", None), - ("SPI_PAD_CONFIG_D4", "spi_pad_config", 1, 2, 26, "uint:6", 20, None, None, "SPI D4 pad", None), - ("SPI_PAD_CONFIG_D5", "spi_pad_config", 1, 3, 0, "uint:6", 20, None, None, "SPI D5 pad", None), - ("SPI_PAD_CONFIG_D6", "spi_pad_config", 1, 3, 6, "uint:6", 20, None, None, "SPI D6 pad", None), - ("SPI_PAD_CONFIG_D7", "spi_pad_config", 1, 3, 12, "uint:6", 20, None, None, "SPI D7 pad", None), - - ("WAFER_VERSION_MINOR_LO", "identity", 1, 3, 18, "uint:3", 20, None, None, "WAFER_VERSION_MINOR least significant bits", None), - ("PKG_VERSION", "identity", 1, 3, 21, "uint:3", 20, None, None, "Package version", None), - ("BLK_VERSION_MINOR", "identity", 1, 3, 24, "uint:3", 20, None, None, "BLOCK version minor", None), - ("WAFER_VERSION_MINOR_HI", "identity", 1, 5, 23, "uint:1", 20, None, None, "WAFER_VERSION_MINOR most significant bits", None), - ("WAFER_VERSION_MAJOR", "identity", 1, 5, 24, "uint:2", 20, None, None, "WAFER_VERSION_MAJOR", None), - - ("OPTIONAL_UNIQUE_ID", "identity", 2, 0, 0, "bytes:16", 21, None, "keyblock", "Optional unique 128-bit ID", None), - ("BLK_VERSION_MAJOR", "identity", 2, 4, 0, "uint:2", 21, None, None, "BLOCK version major", - {0: "No calibration", - 1: "With calibration"}), - ("CUSTOM_MAC", "identity", 3, 6, 8, "bytes:6", 22, None, "mac", "Custom MAC Address", None), - ] - - KEYBLOCKS = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK_USR_DATA', "config", 3, 0, 0, "bytes:32", 22, None, None, "User data", None), - ('BLOCK_KEY0', "security", 4, 0, 0, "bytes:32", 23, 0, "keyblock", "Encryption key0 or user data", None), - ('BLOCK_KEY1', "security", 5, 0, 0, "bytes:32", 24, 1, "keyblock", "Encryption key1 or user data", None), - ('BLOCK_KEY2', "security", 6, 0, 0, "bytes:32", 25, 2, "keyblock", "Encryption key2 or user data", None), - ('BLOCK_KEY3', "security", 7, 0, 0, "bytes:32", 26, 3, "keyblock", "Encryption key3 or user data", None), - ('BLOCK_KEY4', "security", 8, 0, 0, "bytes:32", 27, 4, "keyblock", "Encryption key4 or user data", None), - ('BLOCK_KEY5', "security", 9, 0, 0, "bytes:32", 28, 5, "keyblock", "Encryption key5 or user data", None), - ('BLOCK_SYS_DATA2', "security", 10, 0, 0, "bytes:32", 29, 6, "keyblock", "System data (part 2)", None), - ] - - # if BLK_VERSION_MAJOR is 1, these efuse fields are in BLOCK2 - BLOCK2_CALIBRATION_EFUSES = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('TEMP_SENSOR_CAL', "calibration", 2, 4, 7, "uint:9", 21, None, "t_sensor", "Temperature calibration", None), - ('ADC1_MODE0_D2', "calibration", 2, 4, 16, "uint:8", 21, None, "adc_tp", "ADC1 calibration 1", None), - ('ADC1_MODE1_D2', "calibration", 2, 4, 24, "uint:8", 21, None, "adc_tp", "ADC1 calibration 2", None), - ('ADC1_MODE2_D2', "calibration", 2, 5, 0, "uint:8", 21, None, "adc_tp", "ADC1 calibration 3", None), - ('ADC1_MODE3_D2', "calibration", 2, 5, 8, "uint:8", 21, None, "adc_tp", "ADC1 calibration 4", None), - ('ADC2_MODE0_D2', "calibration", 2, 5, 16, "uint:8", 21, None, "adc_tp", "ADC2 calibration 5", None), - ('ADC2_MODE1_D2', "calibration", 2, 5, 24, "uint:8", 21, None, "adc_tp", "ADC2 calibration 6", None), - ('ADC2_MODE2_D2', "calibration", 2, 6, 0, "uint:8", 21, None, "adc_tp", "ADC2 calibration 7", None), - ('ADC2_MODE3_D2', "calibration", 2, 6, 8, "uint:8", 21, None, "adc_tp", "ADC2 calibration 8", None), - ('ADC1_MODE0_D1', "calibration", 2, 6, 16, "uint:6", 21, None, "adc_tp", "ADC1 calibration 9", None), - ('ADC1_MODE1_D1', "calibration", 2, 6, 22, "uint:6", 21, None, "adc_tp", "ADC1 calibration 10", None), - ('ADC1_MODE2_D1', "calibration", 2, 6, 28, "uint:6", 21, None, "adc_tp", "ADC1 calibration 11", None), - ('ADC1_MODE3_D1', "calibration", 2, 7, 2, "uint:6", 21, None, "adc_tp", "ADC1 calibration 12", None), - ('ADC2_MODE0_D1', "calibration", 2, 7, 8, "uint:6", 21, None, "adc_tp", "ADC2 calibration 13", None), - ('ADC2_MODE1_D1', "calibration", 2, 7, 14, "uint:6", 21, None, "adc_tp", "ADC2 calibration 14", None), - ('ADC2_MODE2_D1', "calibration", 2, 7, 20, "uint:6", 21, None, "adc_tp", "ADC2 calibration 15", None), - ('ADC2_MODE3_D1', "calibration", 2, 7, 26, "uint:6", 21, None, "adc_tp", "ADC2 calibration 16", None), - ] - - CALC = [ - ("WAFER_VERSION_MINOR", "identity", 0, None, None, "uint:4", None, None, "wafer", "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)", None), - ] -# fmt: on + def __init__(self) -> None: + # List of efuse fields from TRM the chapter eFuse Controller. + self.EFUSES = [] + + self.KEYBLOCKS = [] + + # if BLK_VERSION_MAJOR 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 + + # It is not functional, a bug in the hardware + elif efuse.name == "JTAG_SEL_ENABLE": + self.ALL_EFUSES[i] = None + + f = Field() + f.name = "WAFER_VERSION_MINOR" + f.block = 0 + f.bit_len = 4 + f.type = f"uint:{f.bit_len}" + f.category = "identity" + f.class_type = "wafer" + f.description = "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)" + self.CALC.append(f) + + for efuse in self.ALL_EFUSES: + if efuse is not None: + self.EFUSES.append(efuse) + + self.ALL_EFUSES = [] diff --git a/espefuse/efuse/esp32c3/operations.py b/espefuse/efuse/esp32c3/operations.py index 29353d095..59f446904 100644 --- a/espefuse/efuse/esp32c3/operations.py +++ b/espefuse/efuse/esp32c3/operations.py @@ -17,6 +17,7 @@ from ..base_operations import ( add_common_commands, add_force_write_always, + add_show_sensitive_info_option, burn_bit, burn_block_data, burn_efuse, @@ -55,6 +56,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -105,6 +107,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -276,7 +279,13 @@ def burn_key(esp, efuses, args, digest=None): if efuses[block.key_purpose_name].need_reverse(keypurpose): revers_msg = "\tReversing byte order for AES-XTS hardware peripheral" data = data[::-1] - print("-> [%s]" % (util.hexify(data, " "))) + 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: diff --git a/espefuse/efuse/esp32c6/emulate_efuse_controller.py b/espefuse/efuse/esp32c6/emulate_efuse_controller.py index e22bb7578..a9e7d4d4a 100644 --- a/espefuse/efuse/esp32c6/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32c6/emulate_efuse_controller.py @@ -16,13 +16,13 @@ class EmulateEfuseController(EmulateEfuseControllerBase): CHIP_NAME = "ESP32-C6" mem = None debug = False - Blocks = EfuseDefineBlocks - Fields = EfuseDefineFields - REGS = EfuseDefineRegisters 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_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ def handle_writing_event(self, addr, value): 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 --git a/espefuse/efuse/esp32c6/fields.py b/espefuse/efuse/esp32c6/fields.py index 14a878199..a62004f1a 100644 --- a/espefuse/efuse/esp32c6/fields.py +++ b/espefuse/efuse/esp32c6/fields.py @@ -54,16 +54,15 @@ class EspEfuses(base_fields.EspEfusesBase): Wrapper object to manage the efuse fields in a connected ESP bootloader """ - Blocks = EfuseDefineBlocks() - Fields = EfuseDefineFields() - REGS = EfuseDefineRegisters - BURN_BLOCK_DATA_NAMES = Blocks.get_burn_block_data_names() - BLOCKS_FOR_KEYS = Blocks.get_blocks_for_keys() - 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 @@ -85,59 +84,43 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ] if not skip_connect: self.get_coding_scheme_warnings() - self.efuses = [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.EFUSES - ] + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.KEYBLOCKS + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS ] if skip_connect: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] else: - if self["BLK_VERSION_MAJOR"].get() == 1: + if self["BLK_VERSION_MINOR"].get() == 1: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CALC + 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: + 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: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + 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: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): return e raise KeyError @@ -158,10 +141,6 @@ def print_status_regs(self): ) ) - def get_block_errors(self, block_num): - """Returns (error count, failure boolean flag)""" - return self.blocks[block_num].num_errors, self.blocks[block_num].fail - def efuse_controller_setup(self): self.set_efuse_timing() self.clear_pgm_registers() @@ -181,9 +160,13 @@ def clear_pgm_registers(self): 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" ) @@ -249,12 +232,21 @@ def set_efuse_timing(self): "The eFuse supports only xtal=40M (xtal was %d)" % apb_freq ) + self.update_reg(self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_NUM_M, 0xFF) + self.update_reg( + self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_CLK_DIV_M, 0x28 + ) + self.update_reg( + self.REGS.EFUSE_WR_TIM_CONF1_REG, self.REGS.EFUSE_PWR_ON_NUM_M, 0x3000 + ) self.update_reg( self.REGS.EFUSE_WR_TIM_CONF2_REG, self.REGS.EFUSE_PWR_OFF_NUM_M, 0x190 ) 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: @@ -262,29 +254,22 @@ def get_coding_scheme_warnings(self, silent=False): self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR0_REG + offs * 4) for offs in range(5) ] - data = BitArray() + block.err_bitarray.pos = 0 for word in reversed(words): - data.append("uint:32=%d" % word) - # pos=32 because EFUSE_WR_DIS goes first it is 32bit long - # and not under error control - block.err_bitarray.overwrite(data, pos=32) + 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_f, fail_bit = self.REGS.BLOCK_FAIL_BIT[block.id] - if fail_bit is None: - block.fail = False - else: - block.fail = self.read_reg(addr_reg_f) & (1 << fail_bit) != 0 - - addr_reg_n, num_mask, num_offs = self.REGS.BLOCK_NUM_ERRORS[block.id] - if num_mask is None or num_offs is None: - block.num_errors = 0 - else: - block.num_errors = ( - self.read_reg(addr_reg_n) >> num_offs - ) & num_mask - + 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( @@ -302,35 +287,22 @@ def summary(self): class EfuseField(base_fields.EfuseFieldBase): @staticmethod - def from_tuple(parent, efuse_tuple, type_class): + def convert(parent, efuse): return { "mac": EfuseMacField, "keypurpose": EfuseKeyPurposeField, "t_sensor": EfuseTempSensor, "adc_tp": EfuseAdcPointCalibration, "wafer": EfuseWafer, - }.get(type_class, EfuseField)(parent, efuse_tuple) - - def get_info(self): - output = "%s (BLOCK%d)" % (self.name, self.block) - errs, fail = self.parent.get_block_errors(self.block) - if errs != 0 or fail: - output += ( - "[FAIL:%d]" % (fail) - if self.block == 0 - else "[ERRS:%d FAIL:%d]" % (errs, fail) - ) - if self.efuse_class == "keyblock": - name = self.parent.blocks[self.block].key_purpose_name - if name is not None: - output += "\n Purpose: %s\n " % (self.parent[name].get()) - return output + }.get(efuse.class_type, EfuseField)(parent, efuse) class EfuseWafer(EfuseField): def get(self, from_read=True): hi_bits = self.parent["WAFER_VERSION_MINOR_HI"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_HI"].bit_len == 1 lo_bits = self.parent["WAFER_VERSION_MINOR_LO"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_LO"].bit_len == 3 return (hi_bits << 3) + lo_bits def save(self, new_value): @@ -358,23 +330,27 @@ def check_format(self, new_value_str): raise esptool.FatalError( "Required MAC Address in AA:CD:EF:01:02:03 format!" ) - if new_value_str.count(":") != 5: + num_bytes = 8 if self.name == "MAC_EUI64" else 6 + if new_value_str.count(":") != num_bytes - 1: raise esptool.FatalError( - "MAC Address needs to be a 6-byte hexadecimal format " + f"MAC Address needs to be a {num_bytes}-byte hexadecimal format " "separated by colons (:)!" ) - hexad = new_value_str.replace(":", "") - if len(hexad) != 12: + 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( - "MAC Address needs to be a 6-byte hexadecimal number " - "(12 hexadecimal characters)!" + 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) - # 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!") + + 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): @@ -388,6 +364,13 @@ def check(self): 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()) @@ -407,7 +390,7 @@ def print_field(e, 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("Writing Factory MAC address is not supported") + raise esptool.FatalError(f"Burning {self.name} is not supported") # fmt: off @@ -459,6 +442,14 @@ def get(self, from_read=True): 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))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"): + raise esptool.FatalError(f"{self.name} can not have {str_new_value} key due to a hardware bug (please see TRM for more details)") return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/espefuse/efuse/esp32c6/mem_definition.py b/espefuse/efuse/esp32c6/mem_definition.py index 890653888..25e4caf01 100644 --- a/espefuse/efuse/esp32c6/mem_definition.py +++ b/espefuse/efuse/esp32c6/mem_definition.py @@ -4,24 +4,31 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase +import os +import yaml + +from ..mem_definition_base import ( + EfuseBlocksBase, + EfuseFieldsBase, + EfuseRegistersBase, + Field, +) -# fmt: off -class EfuseDefineRegisters(EfuseRegistersBase): - EFUSE_MEM_SIZE = (0x01FC + 4) +class EfuseDefineRegisters(EfuseRegistersBase): + EFUSE_MEM_SIZE = 0x01FC + 4 # EFUSE registers & command/conf values - DR_REG_EFUSE_BASE = 0x600B0800 - 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 + DR_REG_EFUSE_BASE = 0x600B0800 + 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 @@ -32,53 +39,49 @@ class EfuseDefineRegisters(EfuseRegistersBase): 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 - - # this chip has a design error so fail_bit is shifted by one block but err_num is in the correct place - BLOCK_FAIL_BIT = [ - # error_reg, fail_bit - (EFUSE_RD_REPEAT_ERR0_REG, None), # BLOCK0 - (EFUSE_RD_RS_ERR0_REG, 7), # MAC_SPI_8M_0 - (EFUSE_RD_RS_ERR0_REG, 11), # BLOCK_SYS_DATA - (EFUSE_RD_RS_ERR0_REG, 15), # BLOCK_USR_DATA - (EFUSE_RD_RS_ERR0_REG, 19), # BLOCK_KEY0 - (EFUSE_RD_RS_ERR0_REG, 23), # BLOCK_KEY1 - (EFUSE_RD_RS_ERR0_REG, 27), # BLOCK_KEY2 - (EFUSE_RD_RS_ERR0_REG, 31), # BLOCK_KEY3 - (EFUSE_RD_RS_ERR1_REG, 3), # BLOCK_KEY4 - (EFUSE_RD_RS_ERR1_REG, 7), # BLOCK_KEY5 - (EFUSE_RD_RS_ERR1_REG, None), # BLOCK_SYS_DATA2 - ] - - BLOCK_NUM_ERRORS = [ - # error_reg, err_num_mask, err_num_offs - (EFUSE_RD_REPEAT_ERR0_REG, None, None), # BLOCK0 - (EFUSE_RD_RS_ERR0_REG, 0x7, 0), # MAC_SPI_8M_0 - (EFUSE_RD_RS_ERR0_REG, 0x7, 4), # BLOCK_SYS_DATA - (EFUSE_RD_RS_ERR0_REG, 0x7, 8), # BLOCK_USR_DATA - (EFUSE_RD_RS_ERR0_REG, 0x7, 12), # BLOCK_KEY0 - (EFUSE_RD_RS_ERR0_REG, 0x7, 16), # BLOCK_KEY1 - (EFUSE_RD_RS_ERR0_REG, 0x7, 20), # BLOCK_KEY2 - (EFUSE_RD_RS_ERR0_REG, 0x7, 24), # BLOCK_KEY3 - (EFUSE_RD_RS_ERR0_REG, 0x7, 28), # BLOCK_KEY4 - (EFUSE_RD_RS_ERR1_REG, 0x7, 0), # BLOCK_KEY5 - (EFUSE_RD_RS_ERR1_REG, 0x7, 4), # BLOCK_SYS_DATA2 + 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 -class EfuseDefineBlocks(EfuseBlocksBase): + # 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), @@ -93,6 +96,7 @@ class EfuseDefineBlocks(EfuseBlocksBase): ("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 = [] @@ -107,155 +111,59 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - - # List of efuse fields from TRM the chapter eFuse Controller. - EFUSES = [ - # - # Table 51: Parameters in BLOCK0 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("WR_DIS", "efuse", 0, 0, 0, "uint:32", None, None, None, "Disables programming of individual eFuses", None), - ("RD_DIS", "efuse", 0, 1, 0, "uint:7", 0, None, None, "Disables software reading from BLOCK4-10", None), - ("DIS_ICACHE", "config", 0, 1, 8, "bool", 2, None, None, "Disables ICache", None), - ("DIS_USB_JTAG", "usb config", 0, 1, 9, "bool", 2, None, None, "Disables USB JTAG. " - "JTAG access via pads is controlled separately", None), - ("DIS_DOWNLOAD_ICACHE", "config", 0, 1, 10, "bool", 2, None, None, "Disables Icache when SoC is in Download mode", None), - ("DIS_USB_DEVICE", "usb config", 0, 1, 11, "bool", 2, None, None, "Disables USB DEVICE", None), - ("DIS_FORCE_DOWNLOAD", "config", 0, 1, 12, "bool", 2, None, None, "Disables forcing chip into Download mode", None), - ("DIS_USB", "usb config", 0, 1, 13, "bool", 2, None, None, "Disables the USB OTG hardware", None), - ("DIS_CAN", "config", 0, 1, 14, "bool", 2, None, None, "Disables the TWAI Controller hardware", None), - ("JTAG_SEL_ENABLE", "jtag config", 0, 1, 15, "bool", 2, None, None, "Set this bit to enable selection between " - "usb_to_jtag and pad_to_jtag through strapping " - "gpio10 when both reg_dis_usb_jtag and " - "reg_dis_pad_jtag are equal to 0.", None), - ("SOFT_DIS_JTAG", "jtag config", 0, 1, 16, "uint:3", 2, None, None, "Software disables JTAG. When software disabled, " - "JTAG can be activated temporarily by HMAC peripheral", - None), - ("DIS_PAD_JTAG", "jtag config", 0, 1, 19, "bool", 2, None, None, "Permanently disable JTAG access via pads. " - "USB JTAG is controlled separately.", None), - ("DIS_DOWNLOAD_MANUAL_ENCRYPT", "security", 0, 1, 20, "bool", 2, None, None, "Disables flash encryption when in download boot modes", - None), - ("USB_EXCHG_PINS", "usb config", 0, 1, 25, "bool", 30, None, None, "Exchanges USB D+ and D- pins", None), - ("VDD_SPI_AS_GPIO", "config", 0, 1, 26, "bool", 30, None, None, "Set this bit to vdd spi pin function as gpio", None), - ("BTLC_GPIO_ENABLE", "config", 0, 1, 27, "uint:2", 30, None, None, "Enable btlc gpio", None), - ("POWERGLITCH_EN", "config", 0, 1, 29, "bool", 30, None, None, "Set this bit to enable power glitch function", None), - ("POWER_GLITCH_DSENSE", "config", 0, 1, 30, "uint:2", 30, None, None, "Sample delay configuration of power glitch", None), - ("WDT_DELAY_SEL", "WDT config", 0, 2, 16, "bool", 3, None, None, "Selects RTC WDT timeout threshold at startup", None), - ("SPI_BOOT_CRYPT_CNT", "security", 0, 2, 18, "uint:3", 4, None, "bitcount", "Enables encryption and decryption, when an SPI boot " - "mode is set. Enabled when 1 or 3 bits are set," - "disabled otherwise", - {0: "Disable", - 1: "Enable", - 3: "Disable", - 7: "Enable"}), - ("SECURE_BOOT_KEY_REVOKE0", "security", 0, 2, 21, "bool", 5, None, None, "If set, revokes use of secure boot key digest 0", None), - ("SECURE_BOOT_KEY_REVOKE1", "security", 0, 2, 22, "bool", 6, None, None, "If set, revokes use of secure boot key digest 1", None), - ("SECURE_BOOT_KEY_REVOKE2", "security", 0, 2, 23, "bool", 7, None, None, "If set, revokes use of secure boot key digest 2", None), - ("KEY_PURPOSE_0", "security", 0, 2, 24, "uint:4", 8, None, "keypurpose", "KEY0 purpose", None), - ("KEY_PURPOSE_1", "security", 0, 2, 28, "uint:4", 9, None, "keypurpose", "KEY1 purpose", None), - ("KEY_PURPOSE_2", "security", 0, 3, 0, "uint:4", 10, None, "keypurpose", "KEY2 purpose", None), - ("KEY_PURPOSE_3", "security", 0, 3, 4, "uint:4", 11, None, "keypurpose", "KEY3 purpose", None), - ("KEY_PURPOSE_4", "security", 0, 3, 8, "uint:4", 12, None, "keypurpose", "KEY4 purpose", None), - ("KEY_PURPOSE_5", "security", 0, 3, 12, "uint:4", 13, None, "keypurpose", "KEY5 purpose", None), - ("SECURE_BOOT_EN", "security", 0, 3, 20, "bool", 15, None, None, "Enables secure boot", None), - ("SECURE_BOOT_AGGRESSIVE_REVOKE", "security", 0, 3, 21, "bool", 16, None, None, "Enables aggressive secure boot key revocation mode", - None), - ("FLASH_TPUW", "flash config", 0, 3, 28, "uint:4", 18, None, None, "Configures flash startup delay after SoC power-up, " - "unit is (ms/2). When the value is 15, delay is 7.5 ms", - None), - ("DIS_DOWNLOAD_MODE", "security", 0, 4, 0, "bool", 18, None, None, "Disables all Download boot modes", None), - ("DIS_DIRECT_BOOT", "config", 0, 4, 1, "bool", 18, None, None, "Disables direct boot mode", None), - ("UART_PRINT_CHANNEL", "config", 0, 4, 2, "bool", 18, None, None, "Selects the default UART for printing boot msg", - {0: "UART0", - 1: "UART1"}), - ("FLASH_ECC_MODE", "flash config", 0, 4, 3, "bool", 18, None, None, "Set this bit to set flsah ecc mode.", - {0: "flash ecc 16to18 byte mode", - 1: "flash ecc 16to17 byte mode"}), - ("DIS_USB_DOWNLOAD_MODE", "usb config", 0, 4, 4, "bool", 18, None, None, "Disables use of USB in UART download boot mode", None), - ("ENABLE_SECURITY_DOWNLOAD", "security", 0, 4, 5, "bool", 18, None, None, "Enables secure UART download mode " - "(read/write flash only)", None), - ("UART_PRINT_CONTROL", "config", 0, 4, 6, "uint:2", 18, None, None, "Sets the default UART boot message output mode", - {0: "Enabled", - 1: "Enable when GPIO8 is low at reset", - 2: "Enable when GPIO8 is high at reset", - 3: "Disabled"}), - ("PIN_POWER_SELECTION", "VDD_SPI config", 0, 4, 8, "bool", 18, None, None, "GPIO33-GPIO37 power supply selection in ROM code", - {0: "VDD3P3_CPU", - 1: "VDD_SPI"}), - ("FLASH_TYPE", "flash config", 0, 4, 9, "bool", 18, None, None, "Selects SPI flash type", - {0: "4 data lines", - 1: "8 data lines"}), - ("FLASH_PAGE_SIZE", "flash config", 0, 4, 10, "uint:2", 18, None, None, "Flash page size", None), - ("FLASH_ECC_EN", "flash config", 0, 4, 12, "bool", 18, None, None, "Enable ECC for flash boot", None), - ("FORCE_SEND_RESUME", "config", 0, 4, 13, "bool", 18, None, None, "Force ROM code to send a resume command during SPI boot" - "during SPI boot", None), - ("SECURE_VERSION", "identity", 0, 4, 14, "uint:16", 18, None, "bitcount", "Secure version (used by ESP-IDF anti-rollback feature)", - None), - ("DISABLE_WAFER_VERSION_MAJOR", "config", 0, 5, 0, "bool", 19, None, None, "Disables check of wafer version major", None), - ("DISABLE_BLK_VERSION_MAJOR", "config", 0, 5, 1, "bool", 19, None, None, "Disables check of blk version major", None), - # - # Table 53: Parameters in BLOCK1-10 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("MAC", "identity", 1, 0, 0, "bytes:6", 20, None, "mac", "Factory MAC Address", None), - ("SPI_PAD_CONFIG_CLK", "spi_pad_config", 1, 1, 16, "uint:6", 20, None, None, "SPI CLK pad", None), - ("SPI_PAD_CONFIG_Q", "spi_pad_config", 1, 1, 22, "uint:6", 20, None, None, "SPI Q (D1) pad", None), - ("SPI_PAD_CONFIG_D", "spi_pad_config", 1, 1, 28, "uint:6", 20, None, None, "SPI D (D0) pad", None), - ("SPI_PAD_CONFIG_CS", "spi_pad_config", 1, 2, 2, "uint:6", 20, None, None, "SPI CS pad", None), - ("SPI_PAD_CONFIG_HD", "spi_pad_config", 1, 2, 8, "uint:6", 20, None, None, "SPI HD (D3) pad", None), - ("SPI_PAD_CONFIG_WP", "spi_pad_config", 1, 2, 14, "uint:6", 20, None, None, "SPI WP (D2) pad", None), - ("SPI_PAD_CONFIG_DQS", "spi_pad_config", 1, 2, 20, "uint:6", 20, None, None, "SPI DQS pad", None), - ("SPI_PAD_CONFIG_D4", "spi_pad_config", 1, 2, 26, "uint:6", 20, None, None, "SPI D4 pad", None), - ("SPI_PAD_CONFIG_D5", "spi_pad_config", 1, 3, 0, "uint:6", 20, None, None, "SPI D5 pad", None), - ("SPI_PAD_CONFIG_D6", "spi_pad_config", 1, 3, 6, "uint:6", 20, None, None, "SPI D6 pad", None), - ("SPI_PAD_CONFIG_D7", "spi_pad_config", 1, 3, 12, "uint:6", 20, None, None, "SPI D7 pad", None), - - ("WAFER_VERSION_MINOR_LO", "identity", 1, 3, 18, "uint:3", 20, None, None, "WAFER_VERSION_MINOR least significant bits", None), - ("PKG_VERSION", "identity", 1, 3, 21, "uint:3", 20, None, None, "Package version", None), - ("BLK_VERSION_MINOR", "identity", 1, 3, 24, "uint:3", 20, None, None, "BLOCK version minor", None), - ("WAFER_VERSION_MINOR_HI", "identity", 1, 5, 23, "uint:1", 20, None, None, "WAFER_VERSION_MINOR most significant bits", None), - ("WAFER_VERSION_MAJOR", "identity", 1, 5, 24, "uint:2", 20, None, None, "WAFER_VERSION_MAJOR", None), - - ("OPTIONAL_UNIQUE_ID", "identity", 2, 0, 0, "bytes:16", 21, None, "keyblock", "Optional unique 128-bit ID", None), - ("BLK_VERSION_MAJOR", "identity", 2, 4, 0, "uint:2", 21, None, None, "BLOCK version major", - {0: "No calibration", - 1: "With calibration"}), - ("CUSTOM_MAC", "identity", 3, 6, 8, "bytes:6", 22, None, "mac", "Custom MAC Address", None), - ] - - KEYBLOCKS = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK_USR_DATA', "config", 3, 0, 0, "bytes:32", 22, None, None, "User data", None), - ('BLOCK_KEY0', "security", 4, 0, 0, "bytes:32", 23, 0, "keyblock", "Encryption key0 or user data", None), - ('BLOCK_KEY1', "security", 5, 0, 0, "bytes:32", 24, 1, "keyblock", "Encryption key1 or user data", None), - ('BLOCK_KEY2', "security", 6, 0, 0, "bytes:32", 25, 2, "keyblock", "Encryption key2 or user data", None), - ('BLOCK_KEY3', "security", 7, 0, 0, "bytes:32", 26, 3, "keyblock", "Encryption key3 or user data", None), - ('BLOCK_KEY4', "security", 8, 0, 0, "bytes:32", 27, 4, "keyblock", "Encryption key4 or user data", None), - ('BLOCK_KEY5', "security", 9, 0, 0, "bytes:32", 28, 5, "keyblock", "Encryption key5 or user data", None), - ('BLOCK_SYS_DATA2', "security", 10, 0, 0, "bytes:32", 29, 6, "keyblock", "System data (part 2)", None), - ] - - # if BLK_VERSION_MAJOR is 1, these efuse fields are in BLOCK2 - BLOCK2_CALIBRATION_EFUSES = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('TEMP_SENSOR_CAL', "calibration", 2, 4, 7, "uint:9", 21, None, "t_sensor", "Temperature calibration", None), - ('ADC1_MODE0_D2', "calibration", 2, 4, 16, "uint:8", 21, None, "adc_tp", "ADC1 calibration 1", None), - ('ADC1_MODE1_D2', "calibration", 2, 4, 24, "uint:8", 21, None, "adc_tp", "ADC1 calibration 2", None), - ('ADC1_MODE2_D2', "calibration", 2, 5, 0, "uint:8", 21, None, "adc_tp", "ADC1 calibration 3", None), - ('ADC1_MODE3_D2', "calibration", 2, 5, 8, "uint:8", 21, None, "adc_tp", "ADC1 calibration 4", None), - ('ADC2_MODE0_D2', "calibration", 2, 5, 16, "uint:8", 21, None, "adc_tp", "ADC2 calibration 5", None), - ('ADC2_MODE1_D2', "calibration", 2, 5, 24, "uint:8", 21, None, "adc_tp", "ADC2 calibration 6", None), - ('ADC2_MODE2_D2', "calibration", 2, 6, 0, "uint:8", 21, None, "adc_tp", "ADC2 calibration 7", None), - ('ADC2_MODE3_D2', "calibration", 2, 6, 8, "uint:8", 21, None, "adc_tp", "ADC2 calibration 8", None), - ('ADC1_MODE0_D1', "calibration", 2, 6, 16, "uint:6", 21, None, "adc_tp", "ADC1 calibration 9", None), - ('ADC1_MODE1_D1', "calibration", 2, 6, 22, "uint:6", 21, None, "adc_tp", "ADC1 calibration 10", None), - ('ADC1_MODE2_D1', "calibration", 2, 6, 28, "uint:6", 21, None, "adc_tp", "ADC1 calibration 11", None), - ('ADC1_MODE3_D1', "calibration", 2, 7, 2, "uint:6", 21, None, "adc_tp", "ADC1 calibration 12", None), - ('ADC2_MODE0_D1', "calibration", 2, 7, 8, "uint:6", 21, None, "adc_tp", "ADC2 calibration 13", None), - ('ADC2_MODE1_D1', "calibration", 2, 7, 14, "uint:6", 21, None, "adc_tp", "ADC2 calibration 14", None), - ('ADC2_MODE2_D1', "calibration", 2, 7, 20, "uint:6", 21, None, "adc_tp", "ADC2 calibration 15", None), - ('ADC2_MODE3_D1', "calibration", 2, 7, 26, "uint:6", 21, None, "adc_tp", "ADC2 calibration 16", None), - ] - - CALC = [ - ("WAFER_VERSION_MINOR", "identity", 0, None, None, "uint:4", None, None, "wafer", "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)", None), - ] -# fmt: on + 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 --git a/espefuse/efuse/esp32c6/operations.py b/espefuse/efuse/esp32c6/operations.py index 5905e5186..f8e450fa0 100644 --- a/espefuse/efuse/esp32c6/operations.py +++ b/espefuse/efuse/esp32c6/operations.py @@ -17,6 +17,7 @@ from ..base_operations import ( add_common_commands, add_force_write_always, + add_show_sensitive_info_option, burn_bit, burn_block_data, burn_efuse, @@ -55,6 +56,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -105,6 +107,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -191,38 +194,29 @@ def set_flash_voltage(esp, efuses, args): 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() == 1: + 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("ADC1 Calibration data stored in efuse BLOCK2:") + print(f"OCODE: {efuses['OCODE'].get()}") + print(f"INIT_CODE_ATTEN0: {efuses['ADC1_INIT_CODE_ATTEN0'].get()}") + print(f"INIT_CODE_ATTEN1: {efuses['ADC1_INIT_CODE_ATTEN1'].get()}") + print(f"INIT_CODE_ATTEN2: {efuses['ADC1_INIT_CODE_ATTEN2'].get()}") + print(f"INIT_CODE_ATTEN3: {efuses['ADC1_INIT_CODE_ATTEN3'].get()}") + print(f"CAL_VOL_ATTEN0: {efuses['ADC1_CAL_VOL_ATTEN0'].get()}") + print(f"CAL_VOL_ATTEN1: {efuses['ADC1_CAL_VOL_ATTEN1'].get()}") + print(f"CAL_VOL_ATTEN2: {efuses['ADC1_CAL_VOL_ATTEN2'].get()}") + print(f"CAL_VOL_ATTEN3: {efuses['ADC1_CAL_VOL_ATTEN3'].get()}") + print(f"INIT_CODE_ATTEN0_CH0: {efuses['ADC1_INIT_CODE_ATTEN0_CH0'].get()}") + print(f"INIT_CODE_ATTEN0_CH1: {efuses['ADC1_INIT_CODE_ATTEN0_CH1'].get()}") + print(f"INIT_CODE_ATTEN0_CH2: {efuses['ADC1_INIT_CODE_ATTEN0_CH2'].get()}") + print(f"INIT_CODE_ATTEN0_CH3: {efuses['ADC1_INIT_CODE_ATTEN0_CH3'].get()}") + print(f"INIT_CODE_ATTEN0_CH4: {efuses['ADC1_INIT_CODE_ATTEN0_CH4'].get()}") + print(f"INIT_CODE_ATTEN0_CH5: {efuses['ADC1_INIT_CODE_ATTEN0_CH5'].get()}") + print(f"INIT_CODE_ATTEN0_CH6: {efuses['ADC1_INIT_CODE_ATTEN0_CH6'].get()}") else: - print("BLK_VERSION_MAJOR = {}".format(efuses["BLK_VERSION_MAJOR"].get_meaning())) + print("BLK_VERSION_MINOR = {}".format(efuses["BLK_VERSION_MINOR"].get_meaning())) # fmt: on @@ -276,7 +270,13 @@ def burn_key(esp, efuses, args, digest=None): if efuses[block.key_purpose_name].need_reverse(keypurpose): revers_msg = "\tReversing byte order for AES-XTS hardware peripheral" data = data[::-1] - print("-> [%s]" % (util.hexify(data, " "))) + 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: diff --git a/espefuse/efuse/esp32h2/emulate_efuse_controller.py b/espefuse/efuse/esp32h2/emulate_efuse_controller.py index c4c839da6..c8d3cd91a 100644 --- a/espefuse/efuse/esp32h2/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32h2/emulate_efuse_controller.py @@ -16,13 +16,13 @@ class EmulateEfuseController(EmulateEfuseControllerBase): CHIP_NAME = "ESP32-H2" mem = None debug = False - Blocks = EfuseDefineBlocks - Fields = EfuseDefineFields - REGS = EfuseDefineRegisters 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_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ def handle_writing_event(self, addr, value): 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 --git a/espefuse/efuse/esp32h2/fields.py b/espefuse/efuse/esp32h2/fields.py index 45bd29f01..add5db76f 100644 --- a/espefuse/efuse/esp32h2/fields.py +++ b/espefuse/efuse/esp32h2/fields.py @@ -54,16 +54,15 @@ class EspEfuses(base_fields.EspEfusesBase): Wrapper object to manage the efuse fields in a connected ESP bootloader """ - Blocks = EfuseDefineBlocks() - Fields = EfuseDefineFields() - REGS = EfuseDefineRegisters - BURN_BLOCK_DATA_NAMES = Blocks.get_burn_block_data_names() - BLOCKS_FOR_KEYS = Blocks.get_blocks_for_keys() - 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 @@ -85,59 +84,43 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ] if not skip_connect: self.get_coding_scheme_warnings() - self.efuses = [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.EFUSES - ] + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.KEYBLOCKS + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS ] if skip_connect: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) 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.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CALC + 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: + 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: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + 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: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): return e raise KeyError @@ -158,10 +141,6 @@ def print_status_regs(self): ) ) - def get_block_errors(self, block_num): - """Returns (error count, failure boolean flag)""" - return self.blocks[block_num].num_errors, self.blocks[block_num].fail - def efuse_controller_setup(self): self.set_efuse_timing() self.clear_pgm_registers() @@ -181,9 +160,13 @@ def clear_pgm_registers(self): 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" ) @@ -250,12 +233,21 @@ def set_efuse_timing(self): "The eFuse supports only xtal=32M (xtal was %d)" % apb_freq ) + self.update_reg(self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_NUM_M, 0xFF) + self.update_reg( + self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_CLK_DIV_M, 0x28 + ) + self.update_reg( + self.REGS.EFUSE_WR_TIM_CONF1_REG, self.REGS.EFUSE_PWR_ON_NUM_M, 0x3000 + ) self.update_reg( self.REGS.EFUSE_WR_TIM_CONF2_REG, self.REGS.EFUSE_PWR_OFF_NUM_M, 0x190 ) 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: @@ -263,29 +255,22 @@ def get_coding_scheme_warnings(self, silent=False): self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR0_REG + offs * 4) for offs in range(5) ] - data = BitArray() + block.err_bitarray.pos = 0 for word in reversed(words): - data.append("uint:32=%d" % word) - # pos=32 because EFUSE_WR_DIS goes first it is 32bit long - # and not under error control - block.err_bitarray.overwrite(data, pos=32) + 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_f, fail_bit = self.REGS.BLOCK_FAIL_BIT[block.id] - if fail_bit is None: - block.fail = False - else: - block.fail = self.read_reg(addr_reg_f) & (1 << fail_bit) != 0 - - addr_reg_n, num_mask, num_offs = self.REGS.BLOCK_NUM_ERRORS[block.id] - if num_mask is None or num_offs is None: - block.num_errors = 0 - else: - block.num_errors = ( - self.read_reg(addr_reg_n) >> num_offs - ) & num_mask - + 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( @@ -303,35 +288,22 @@ def summary(self): class EfuseField(base_fields.EfuseFieldBase): @staticmethod - def from_tuple(parent, efuse_tuple, type_class): + def convert(parent, efuse): return { "mac": EfuseMacField, "keypurpose": EfuseKeyPurposeField, "t_sensor": EfuseTempSensor, "adc_tp": EfuseAdcPointCalibration, "wafer": EfuseWafer, - }.get(type_class, EfuseField)(parent, efuse_tuple) - - def get_info(self): - output = "%s (BLOCK%d)" % (self.name, self.block) - errs, fail = self.parent.get_block_errors(self.block) - if errs != 0 or fail: - output += ( - "[FAIL:%d]" % (fail) - if self.block == 0 - else "[ERRS:%d FAIL:%d]" % (errs, fail) - ) - if self.efuse_class == "keyblock": - name = self.parent.blocks[self.block].key_purpose_name - if name is not None: - output += "\n Purpose: %s\n " % (self.parent[name].get()) - return output + }.get(efuse.class_type, EfuseField)(parent, efuse) class EfuseWafer(EfuseField): def get(self, from_read=True): hi_bits = self.parent["WAFER_VERSION_MINOR_HI"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_HI"].bit_len == 1 lo_bits = self.parent["WAFER_VERSION_MINOR_LO"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_LO"].bit_len == 3 return (hi_bits << 3) + lo_bits def save(self, new_value): @@ -359,23 +331,27 @@ def check_format(self, new_value_str): raise esptool.FatalError( "Required MAC Address in AA:CD:EF:01:02:03 format!" ) - if new_value_str.count(":") != 5: + num_bytes = 8 if self.name == "MAC_EUI64" else 6 + if new_value_str.count(":") != num_bytes - 1: raise esptool.FatalError( - "MAC Address needs to be a 6-byte hexadecimal format " + f"MAC Address needs to be a {num_bytes}-byte hexadecimal format " "separated by colons (:)!" ) hexad = new_value_str.replace(":", "") - if len(hexad) != 12: + hexad = hexad.split(" ", 1)[0] if self.is_field_calculated() else hexad + if len(hexad) != num_bytes * 2: raise esptool.FatalError( - "MAC Address needs to be a 6-byte hexadecimal number " - "(12 hexadecimal characters)!" + 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) - # 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!") + + 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): @@ -389,6 +365,13 @@ def check(self): 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()) @@ -408,14 +391,15 @@ def print_field(e, 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("Writing Factory MAC address is not supported") + 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) - ("RESERVED", 1, None, None, "no_need_rd_protect"), # Reserved + ("ECDSA_KEY", 1, None, "Reverse", "need_rd_protect"), # ECDSA key + ("RESERVED", 2, None, None, "no_need_rd_protect"), # Reserved ("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) @@ -460,6 +444,14 @@ def get(self, from_read=True): 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))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value in ["XTS_AES_128_KEY", "ECDSA_KEY"]: + raise esptool.FatalError(f"{self.name} can not have {str_new_value} key due to a hardware bug (please see TRM for more details)") return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/espefuse/efuse/esp32h2/mem_definition.py b/espefuse/efuse/esp32h2/mem_definition.py index a49ce9a0d..d08a71f0c 100644 --- a/espefuse/efuse/esp32h2/mem_definition.py +++ b/espefuse/efuse/esp32h2/mem_definition.py @@ -4,24 +4,31 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase +import os +import yaml + +from ..mem_definition_base import ( + EfuseBlocksBase, + EfuseFieldsBase, + EfuseRegistersBase, + Field, +) -# fmt: off -class EfuseDefineRegisters(EfuseRegistersBase): - EFUSE_MEM_SIZE = (0x01FC + 4) +class EfuseDefineRegisters(EfuseRegistersBase): + EFUSE_MEM_SIZE = 0x01FC + 4 # EFUSE registers & command/conf values - DR_REG_EFUSE_BASE = 0x600B0800 - 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 + DR_REG_EFUSE_BASE = 0x600B0800 + 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 @@ -32,53 +39,49 @@ class EfuseDefineRegisters(EfuseRegistersBase): 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 - - # this chip has a design error so fail_bit is shifted by one block but err_num is in the correct place - BLOCK_FAIL_BIT = [ - # error_reg, fail_bit - (EFUSE_RD_REPEAT_ERR0_REG, None), # BLOCK0 - (EFUSE_RD_RS_ERR0_REG, 7), # MAC_SPI_8M_0 - (EFUSE_RD_RS_ERR0_REG, 11), # BLOCK_SYS_DATA - (EFUSE_RD_RS_ERR0_REG, 15), # BLOCK_USR_DATA - (EFUSE_RD_RS_ERR0_REG, 19), # BLOCK_KEY0 - (EFUSE_RD_RS_ERR0_REG, 23), # BLOCK_KEY1 - (EFUSE_RD_RS_ERR0_REG, 27), # BLOCK_KEY2 - (EFUSE_RD_RS_ERR0_REG, 31), # BLOCK_KEY3 - (EFUSE_RD_RS_ERR1_REG, 3), # BLOCK_KEY4 - (EFUSE_RD_RS_ERR1_REG, 7), # BLOCK_KEY5 - (EFUSE_RD_RS_ERR1_REG, None), # BLOCK_SYS_DATA2 - ] - - BLOCK_NUM_ERRORS = [ - # error_reg, err_num_mask, err_num_offs - (EFUSE_RD_REPEAT_ERR0_REG, None, None), # BLOCK0 - (EFUSE_RD_RS_ERR0_REG, 0x7, 0), # MAC_SPI_8M_0 - (EFUSE_RD_RS_ERR0_REG, 0x7, 4), # BLOCK_SYS_DATA - (EFUSE_RD_RS_ERR0_REG, 0x7, 8), # BLOCK_USR_DATA - (EFUSE_RD_RS_ERR0_REG, 0x7, 12), # BLOCK_KEY0 - (EFUSE_RD_RS_ERR0_REG, 0x7, 16), # BLOCK_KEY1 - (EFUSE_RD_RS_ERR0_REG, 0x7, 20), # BLOCK_KEY2 - (EFUSE_RD_RS_ERR0_REG, 0x7, 24), # BLOCK_KEY3 - (EFUSE_RD_RS_ERR0_REG, 0x7, 28), # BLOCK_KEY4 - (EFUSE_RD_RS_ERR1_REG, 0x7, 0), # BLOCK_KEY5 - (EFUSE_RD_RS_ERR1_REG, 0x7, 4), # BLOCK_SYS_DATA2 + 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 -class EfuseDefineBlocks(EfuseBlocksBase): + # 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), @@ -93,6 +96,7 @@ class EfuseDefineBlocks(EfuseBlocksBase): ("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 = [] @@ -107,152 +111,59 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - - # List of efuse fields from TRM the chapter eFuse Controller. - EFUSES = [ - # - # Table 51: Parameters in BLOCK0 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("WR_DIS", "efuse", 0, 0, 0, "uint:32", None, None, None, "Disables programming of individual eFuses", None), - ("RD_DIS", "efuse", 0, 1, 0, "uint:7", 0, None, None, "Disables software reading from BLOCK4-10", None), - ("DIS_ICACHE", "config", 0, 1, 8, "bool", 2, None, None, "Disables ICache", None), - ("DIS_USB_JTAG", "usb config", 0, 1, 9, "bool", 2, None, None, "Disables USB JTAG. " - "JTAG access via pads is controlled separately", None), - ("DIS_DOWNLOAD_ICACHE", "config", 0, 1, 10, "bool", 2, None, None, "Disables Icache when SoC is in Download mode", None), - ("DIS_USB_DEVICE", "usb config", 0, 1, 11, "bool", 2, None, None, "Disables USB DEVICE", None), - ("DIS_FORCE_DOWNLOAD", "config", 0, 1, 12, "bool", 2, None, None, "Disables forcing chip into Download mode", None), - ("DIS_USB", "usb config", 0, 1, 13, "bool", 2, None, None, "Disables the USB OTG hardware", None), - ("DIS_CAN", "config", 0, 1, 14, "bool", 2, None, None, "Disables the TWAI Controller hardware", None), - ("JTAG_SEL_ENABLE", "jtag config", 0, 1, 15, "bool", 2, None, None, "Set this bit to enable selection between " - "usb_to_jtag and pad_to_jtag through strapping " - "gpio10 when both reg_dis_usb_jtag and " - "reg_dis_pad_jtag are equal to 0.", None), - ("SOFT_DIS_JTAG", "jtag config", 0, 1, 16, "uint:3", 2, None, None, "Software disables JTAG. When software disabled, " - "JTAG can be activated temporarily by HMAC peripheral", - None), - ("DIS_PAD_JTAG", "jtag config", 0, 1, 19, "bool", 2, None, None, "Permanently disable JTAG access via pads. " - "USB JTAG is controlled separately.", None), - ("DIS_DOWNLOAD_MANUAL_ENCRYPT", "security", 0, 1, 20, "bool", 2, None, None, "Disables flash encryption when in download boot modes", - None), - ("USB_EXCHG_PINS", "usb config", 0, 1, 25, "bool", 30, None, None, "Exchanges USB D+ and D- pins", None), - ("VDD_SPI_AS_GPIO", "config", 0, 1, 26, "bool", 30, None, None, "Set this bit to vdd spi pin function as gpio", None), - ("BTLC_GPIO_ENABLE", "config", 0, 1, 27, "uint:2", 30, None, None, "Enable btlc gpio", None), - ("POWERGLITCH_EN", "config", 0, 1, 29, "bool", 30, None, None, "Set this bit to enable power glitch function", None), - ("POWER_GLITCH_DSENSE", "config", 0, 1, 30, "uint:2", 30, None, None, "Sample delay configuration of power glitch", None), - ("WDT_DELAY_SEL", "WDT config", 0, 2, 16, "bool", 3, None, None, "Selects RTC WDT timeout threshold at startup", None), - ("SPI_BOOT_CRYPT_CNT", "security", 0, 2, 18, "uint:3", 4, None, "bitcount", "Enables encryption and decryption, when an SPI boot " - "mode is set. Enabled when 1 or 3 bits are set," - "disabled otherwise", - {0: "Disable", - 1: "Enable", - 3: "Disable", - 7: "Enable"}), - ("SECURE_BOOT_KEY_REVOKE0", "security", 0, 2, 21, "bool", 5, None, None, "If set, revokes use of secure boot key digest 0", None), - ("SECURE_BOOT_KEY_REVOKE1", "security", 0, 2, 22, "bool", 6, None, None, "If set, revokes use of secure boot key digest 1", None), - ("SECURE_BOOT_KEY_REVOKE2", "security", 0, 2, 23, "bool", 7, None, None, "If set, revokes use of secure boot key digest 2", None), - ("KEY_PURPOSE_0", "security", 0, 2, 24, "uint:4", 8, None, "keypurpose", "KEY0 purpose", None), - ("KEY_PURPOSE_1", "security", 0, 2, 28, "uint:4", 9, None, "keypurpose", "KEY1 purpose", None), - ("KEY_PURPOSE_2", "security", 0, 3, 0, "uint:4", 10, None, "keypurpose", "KEY2 purpose", None), - ("KEY_PURPOSE_3", "security", 0, 3, 4, "uint:4", 11, None, "keypurpose", "KEY3 purpose", None), - ("KEY_PURPOSE_4", "security", 0, 3, 8, "uint:4", 12, None, "keypurpose", "KEY4 purpose", None), - ("KEY_PURPOSE_5", "security", 0, 3, 12, "uint:4", 13, None, "keypurpose", "KEY5 purpose", None), - ("SECURE_BOOT_EN", "security", 0, 3, 20, "bool", 15, None, None, "Enables secure boot", None), - ("SECURE_BOOT_AGGRESSIVE_REVOKE", "security", 0, 3, 21, "bool", 16, None, None, "Enables aggressive secure boot key revocation mode", - None), - ("FLASH_TPUW", "flash config", 0, 3, 28, "uint:4", 18, None, None, "Configures flash startup delay after SoC power-up, " - "unit is (ms/2). When the value is 15, delay is 7.5 ms", - None), - ("DIS_DOWNLOAD_MODE", "security", 0, 4, 0, "bool", 18, None, None, "Disables all Download boot modes", None), - ("DIS_DIRECT_BOOT", "config", 0, 4, 1, "bool", 18, None, None, "Disables direct boot mode", None), - ("UART_PRINT_CHANNEL", "config", 0, 4, 2, "bool", 18, None, None, "Selects the default UART for printing boot msg", - {0: "UART0", - 1: "UART1"}), - ("FLASH_ECC_MODE", "flash config", 0, 4, 3, "bool", 18, None, None, "Set this bit to set flsah ecc mode.", - {0: "flash ecc 16to18 byte mode", - 1: "flash ecc 16to17 byte mode"}), - ("DIS_USB_DOWNLOAD_MODE", "usb config", 0, 4, 4, "bool", 18, None, None, "Disables use of USB in UART download boot mode", None), - ("ENABLE_SECURITY_DOWNLOAD", "security", 0, 4, 5, "bool", 18, None, None, "Enables secure UART download mode " - "(read/write flash only)", None), - ("UART_PRINT_CONTROL", "config", 0, 4, 6, "uint:2", 18, None, None, "Sets the default UART boot message output mode", - {0: "Enabled", - 1: "Enable when GPIO8 is low at reset", - 2: "Enable when GPIO8 is high at reset", - 3: "Disabled"}), - ("PIN_POWER_SELECTION", "VDD_SPI config", 0, 4, 8, "bool", 18, None, None, "GPIO33-GPIO37 power supply selection in ROM code", - {0: "VDD3P3_CPU", - 1: "VDD_SPI"}), - ("FLASH_PAGE_SIZE", "flash config", 0, 4, 10, "uint:2", 18, None, None, "Flash page size", None), - ("FLASH_ECC_EN", "flash config", 0, 4, 12, "bool", 18, None, None, "Enable ECC for flash boot", None), - ("FORCE_SEND_RESUME", "config", 0, 4, 13, "bool", 18, None, None, "Force ROM code to send a resume command during SPI boot" - "during SPI boot", None), - ("SECURE_VERSION", "identity", 0, 4, 14, "uint:16", 18, None, "bitcount", "Secure version (used by ESP-IDF anti-rollback feature)", - None), - ("DISABLE_WAFER_VERSION_MAJOR", "config", 0, 5, 0, "bool", 19, None, None, "Disables check of wafer version major", None), - ("DISABLE_BLK_VERSION_MAJOR", "config", 0, 5, 1, "bool", 19, None, None, "Disables check of blk version major", None), - # - # Table 53: Parameters in BLOCK1-10 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("MAC", "identity", 1, 0, 0, "bytes:6", 20, None, "mac", "Factory MAC Address", None), - ("SPI_PAD_CONFIG_CLK", "spi_pad_config", 1, 1, 16, "uint:6", 20, None, None, "SPI CLK pad", None), - ("SPI_PAD_CONFIG_Q", "spi_pad_config", 1, 1, 22, "uint:6", 20, None, None, "SPI Q (D1) pad", None), - ("SPI_PAD_CONFIG_D", "spi_pad_config", 1, 1, 28, "uint:6", 20, None, None, "SPI D (D0) pad", None), - ("SPI_PAD_CONFIG_CS", "spi_pad_config", 1, 2, 2, "uint:6", 20, None, None, "SPI CS pad", None), - ("SPI_PAD_CONFIG_HD", "spi_pad_config", 1, 2, 8, "uint:6", 20, None, None, "SPI HD (D3) pad", None), - ("SPI_PAD_CONFIG_WP", "spi_pad_config", 1, 2, 14, "uint:6", 20, None, None, "SPI WP (D2) pad", None), - ("SPI_PAD_CONFIG_DQS", "spi_pad_config", 1, 2, 20, "uint:6", 20, None, None, "SPI DQS pad", None), - ("SPI_PAD_CONFIG_D4", "spi_pad_config", 1, 2, 26, "uint:6", 20, None, None, "SPI D4 pad", None), - ("SPI_PAD_CONFIG_D5", "spi_pad_config", 1, 3, 0, "uint:6", 20, None, None, "SPI D5 pad", None), - ("SPI_PAD_CONFIG_D6", "spi_pad_config", 1, 3, 6, "uint:6", 20, None, None, "SPI D6 pad", None), - ("SPI_PAD_CONFIG_D7", "spi_pad_config", 1, 3, 12, "uint:6", 20, None, None, "SPI D7 pad", None), - - ("WAFER_VERSION_MINOR_LO", "identity", 1, 3, 18, "uint:3", 20, None, None, "WAFER_VERSION_MINOR least significant bits", None), - ("PKG_VERSION", "identity", 1, 3, 21, "uint:3", 20, None, None, "Package version", None), - ("BLK_VERSION_MINOR", "identity", 1, 3, 24, "uint:3", 20, None, None, "BLOCK version minor", None), - ("WAFER_VERSION_MINOR_HI", "identity", 1, 5, 23, "uint:1", 20, None, None, "WAFER_VERSION_MINOR most significant bits", None), - ("WAFER_VERSION_MAJOR", "identity", 1, 5, 24, "uint:2", 20, None, None, "WAFER_VERSION_MAJOR", None), - - ("OPTIONAL_UNIQUE_ID", "identity", 2, 0, 0, "bytes:16", 21, None, "keyblock", "Optional unique 128-bit ID", None), - ("BLK_VERSION_MAJOR", "identity", 2, 4, 0, "uint:2", 21, None, None, "BLOCK version major", - {0: "No calibration", - 1: "With calibration"}), - ("CUSTOM_MAC", "identity", 3, 6, 8, "bytes:6", 22, None, "mac", "Custom MAC Address", None), - ] - - KEYBLOCKS = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK_USR_DATA', "config", 3, 0, 0, "bytes:32", 22, None, None, "User data", None), - ('BLOCK_KEY0', "security", 4, 0, 0, "bytes:32", 23, 0, "keyblock", "Encryption key0 or user data", None), - ('BLOCK_KEY1', "security", 5, 0, 0, "bytes:32", 24, 1, "keyblock", "Encryption key1 or user data", None), - ('BLOCK_KEY2', "security", 6, 0, 0, "bytes:32", 25, 2, "keyblock", "Encryption key2 or user data", None), - ('BLOCK_KEY3', "security", 7, 0, 0, "bytes:32", 26, 3, "keyblock", "Encryption key3 or user data", None), - ('BLOCK_KEY4', "security", 8, 0, 0, "bytes:32", 27, 4, "keyblock", "Encryption key4 or user data", None), - ('BLOCK_KEY5', "security", 9, 0, 0, "bytes:32", 28, 5, "keyblock", "Encryption key5 or user data", None), - ('BLOCK_SYS_DATA2', "security", 10, 0, 0, "bytes:32", 29, 6, "keyblock", "System data (part 2)", None), - ] - - # if BLK_VERSION_MAJOR is 1, these efuse fields are in BLOCK2 - BLOCK2_CALIBRATION_EFUSES = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('TEMP_SENSOR_CAL', "calibration", 2, 4, 7, "uint:9", 21, None, "t_sensor", "Temperature calibration", None), - ('ADC1_MODE0_D2', "calibration", 2, 4, 16, "uint:8", 21, None, "adc_tp", "ADC1 calibration 1", None), - ('ADC1_MODE1_D2', "calibration", 2, 4, 24, "uint:8", 21, None, "adc_tp", "ADC1 calibration 2", None), - ('ADC1_MODE2_D2', "calibration", 2, 5, 0, "uint:8", 21, None, "adc_tp", "ADC1 calibration 3", None), - ('ADC1_MODE3_D2', "calibration", 2, 5, 8, "uint:8", 21, None, "adc_tp", "ADC1 calibration 4", None), - ('ADC2_MODE0_D2', "calibration", 2, 5, 16, "uint:8", 21, None, "adc_tp", "ADC2 calibration 5", None), - ('ADC2_MODE1_D2', "calibration", 2, 5, 24, "uint:8", 21, None, "adc_tp", "ADC2 calibration 6", None), - ('ADC2_MODE2_D2', "calibration", 2, 6, 0, "uint:8", 21, None, "adc_tp", "ADC2 calibration 7", None), - ('ADC2_MODE3_D2', "calibration", 2, 6, 8, "uint:8", 21, None, "adc_tp", "ADC2 calibration 8", None), - ('ADC1_MODE0_D1', "calibration", 2, 6, 16, "uint:6", 21, None, "adc_tp", "ADC1 calibration 9", None), - ('ADC1_MODE1_D1', "calibration", 2, 6, 22, "uint:6", 21, None, "adc_tp", "ADC1 calibration 10", None), - ('ADC1_MODE2_D1', "calibration", 2, 6, 28, "uint:6", 21, None, "adc_tp", "ADC1 calibration 11", None), - ('ADC1_MODE3_D1', "calibration", 2, 7, 2, "uint:6", 21, None, "adc_tp", "ADC1 calibration 12", None), - ('ADC2_MODE0_D1', "calibration", 2, 7, 8, "uint:6", 21, None, "adc_tp", "ADC2 calibration 13", None), - ('ADC2_MODE1_D1', "calibration", 2, 7, 14, "uint:6", 21, None, "adc_tp", "ADC2 calibration 14", None), - ('ADC2_MODE2_D1', "calibration", 2, 7, 20, "uint:6", 21, None, "adc_tp", "ADC2 calibration 15", None), - ('ADC2_MODE3_D1', "calibration", 2, 7, 26, "uint:6", 21, None, "adc_tp", "ADC2 calibration 16", None), - ] - - CALC = [ - ("WAFER_VERSION_MINOR", "identity", 0, None, None, "uint:4", None, None, "wafer", "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)", None), - ] -# fmt: on + def __init__(self) -> None: + # List of efuse fields from TRM the chapter eFuse Controller. + self.EFUSES = [] + + self.KEYBLOCKS = [] + + # if BLK_VERSION_MINOR is 2, 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 --git a/espefuse/efuse/esp32h2/operations.py b/espefuse/efuse/esp32h2/operations.py index cc8ba64be..d9445d152 100644 --- a/espefuse/efuse/esp32h2/operations.py +++ b/espefuse/efuse/esp32h2/operations.py @@ -17,6 +17,7 @@ from ..base_operations import ( add_common_commands, add_force_write_always, + add_show_sensitive_info_option, burn_bit, burn_block_data, burn_efuse, @@ -55,6 +56,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -63,7 +65,7 @@ def add_commands(subparsers, efuses): ) burn_key.add_argument( "keyfile", - help="File containing 256 bits of binary key data", + help="File containing 256 bits of binary key data. For the ECDSA_KEY purpose use PEM file.", action="append", type=argparse.FileType("rb"), ) @@ -84,7 +86,7 @@ def add_commands(subparsers, efuses): ) burn_key.add_argument( "keyfile", - help="File containing 256 bits of binary key data", + help="File containing 256 bits of binary key data. For the ECDSA_KEY purpose use PEM file.", nargs="?", action="append", metavar="KEYFILE", @@ -105,6 +107,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -152,9 +155,8 @@ def add_commands(subparsers, efuses): 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.", + "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"]) @@ -191,38 +193,28 @@ def set_flash_voltage(esp, efuses, args): 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 @@ -267,16 +259,29 @@ def burn_key(esp, efuses, args, digest=None): block = efuses.blocks[block_num] if digest is None: - data = datafile.read() + 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 = "\tReversing byte order for AES-XTS hardware peripheral" + revers_msg = f"\tReversing byte order for {keypurpose} hardware peripheral" data = data[::-1] - print("-> [%s]" % (util.hexify(data, " "))) + 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: diff --git a/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py b/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py index 1f98087d3..b81e8e08f 100644 --- a/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py @@ -16,13 +16,13 @@ class EmulateEfuseController(EmulateEfuseControllerBase): CHIP_NAME = "ESP32-H2(beta1)" mem = None debug = False - Blocks = EfuseDefineBlocks - Fields = EfuseDefineFields - REGS = EfuseDefineRegisters 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_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ def handle_writing_event(self, addr, value): 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 --git a/espefuse/efuse/esp32h2beta1/fields.py b/espefuse/efuse/esp32h2beta1/fields.py index 587bf3263..3e8f28928 100644 --- a/espefuse/efuse/esp32h2beta1/fields.py +++ b/espefuse/efuse/esp32h2beta1/fields.py @@ -54,16 +54,15 @@ class EspEfuses(base_fields.EspEfusesBase): Wrapper object to manage the efuse fields in a connected ESP bootloader """ - Blocks = EfuseDefineBlocks() - Fields = EfuseDefineFields() - REGS = EfuseDefineRegisters - BURN_BLOCK_DATA_NAMES = Blocks.get_burn_block_data_names() - BLOCKS_FOR_KEYS = Blocks.get_blocks_for_keys() - 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 @@ -85,53 +84,43 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ] if not skip_connect: self.get_coding_scheme_warnings() - self.efuses = [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.EFUSES - ] + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.KEYBLOCKS + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS ] if skip_connect: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] else: - if self["BLOCK2_VERSION"].get() == 1: + if self["BLK_VERSION_MAJOR"].get() == 1: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + 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: + 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: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + 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: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): return e raise KeyError @@ -152,10 +141,6 @@ def print_status_regs(self): ) ) - def get_block_errors(self, block_num): - """Returns (error count, failure boolean flag)""" - return self.blocks[block_num].num_errors, self.blocks[block_num].fail - def efuse_controller_setup(self): self.set_efuse_timing() self.clear_pgm_registers() @@ -175,9 +160,13 @@ def clear_pgm_registers(self): 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" ) @@ -243,6 +232,13 @@ def set_efuse_timing(self): "The eFuse supports only xtal=32M (xtal was %d)" % apb_freq ) + self.update_reg(self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_NUM_M, 0xFF) + self.update_reg( + self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_CLK_DIV_M, 0x28 + ) + self.update_reg( + self.REGS.EFUSE_WR_TIM_CONF1_REG, self.REGS.EFUSE_PWR_ON_NUM_M, 0x3000 + ) self.update_reg( self.REGS.EFUSE_WR_TIM_CONF2_REG, self.REGS.EFUSE_PWR_OFF_NUM_M, 0x190 ) @@ -258,12 +254,9 @@ def get_coding_scheme_warnings(self, silent=False): self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR0_REG + offs * 4) for offs in range(5) ] - data = BitArray() + block.err_bitarray.pos = 0 for word in reversed(words): - data.append("uint:32=%d" % word) - # pos=32 because EFUSE_WR_DIS goes first it is 32bit long - # and not under error control - block.err_bitarray.overwrite(data, pos=32) + block.err_bitarray.overwrite(BitArray("uint:32=%d" % word)) block.num_errors = block.err_bitarray.count(True) block.fail = block.num_errors != 0 else: @@ -294,28 +287,26 @@ def summary(self): class EfuseField(base_fields.EfuseFieldBase): @staticmethod - def from_tuple(parent, efuse_tuple, type_class): + def convert(parent, efuse): return { "mac": EfuseMacField, "keypurpose": EfuseKeyPurposeField, "t_sensor": EfuseTempSensor, "adc_tp": EfuseAdcPointCalibration, - }.get(type_class, EfuseField)(parent, efuse_tuple) + "wafer": EfuseWafer, + }.get(efuse.class_type, EfuseField)(parent, efuse) - def get_info(self): - output = "%s (BLOCK%d)" % (self.name, self.block) - errs, fail = self.parent.get_block_errors(self.block) - if errs != 0 or fail: - output += ( - "[FAIL:%d]" % (fail) - if self.block == 0 - else "[ERRS:%d FAIL:%d]" % (errs, fail) - ) - if self.efuse_class == "keyblock": - name = self.parent.blocks[self.block].key_purpose_name - if name is not None: - output += "\n Purpose: %s\n " % (self.parent[name].get()) - return output + +class EfuseWafer(EfuseField): + def get(self, from_read=True): + hi_bits = self.parent["WAFER_VERSION_MINOR_HI"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_HI"].bit_len == 1 + lo_bits = self.parent["WAFER_VERSION_MINOR_LO"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_LO"].bit_len == 3 + return (hi_bits << 3) + lo_bits + + def save(self, new_value): + raise esptool.FatalError("Burning %s is not supported" % self.name) class EfuseTempSensor(EfuseField): @@ -339,23 +330,27 @@ def check_format(self, new_value_str): raise esptool.FatalError( "Required MAC Address in AA:CD:EF:01:02:03 format!" ) - if new_value_str.count(":") != 5: + num_bytes = 8 if self.name == "MAC_EUI64" else 6 + if new_value_str.count(":") != num_bytes - 1: raise esptool.FatalError( - "MAC Address needs to be a 6-byte hexadecimal format " + f"MAC Address needs to be a {num_bytes}-byte hexadecimal format " "separated by colons (:)!" ) - hexad = new_value_str.replace(":", "") - if len(hexad) != 12: + 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( - "MAC Address needs to be a 6-byte hexadecimal number " - "(12 hexadecimal characters)!" + 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) - # 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!") + + 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): @@ -368,11 +363,14 @@ def check(self): def get(self, from_read=True): if self.name == "CUSTOM_MAC": - mac = self.get_raw(from_read)[::-1] + self.parent["MAC_EXT"].get_raw( - from_read - ) + mac = self.get_raw(from_read)[::-1] elif self.name == "MAC": - mac = self.get_raw(from_read) + self.parent["MAC_EXT"].get_raw(from_read) + 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()) @@ -392,6 +390,7 @@ def print_field(e, 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") raise esptool.FatalError("Writing Factory MAC address is not supported") @@ -400,8 +399,6 @@ class EfuseKeyPurposeField(EfuseField): KEY_PURPOSES = [ ("USER", 0, None, None, "no_need_rd_protect"), # User purposes (software-only use) ("RESERVED", 1, None, None, "no_need_rd_protect"), # Reserved - ("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) @@ -447,6 +444,14 @@ def get(self, from_read=True): 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))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"): + raise esptool.FatalError(f"{self.name} can not have {str_new_value} key due to a hardware bug (please see TRM for more details)") return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/espefuse/efuse/esp32h2beta1/mem_definition.py b/espefuse/efuse/esp32h2beta1/mem_definition.py index 58aff675f..ee2f00697 100644 --- a/espefuse/efuse/esp32h2beta1/mem_definition.py +++ b/espefuse/efuse/esp32h2beta1/mem_definition.py @@ -4,24 +4,26 @@ # # SPDX-License-Identifier: GPL-2.0-or-later +import os + +import yaml + from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase -# fmt: off class EfuseDefineRegisters(EfuseRegistersBase): - - EFUSE_MEM_SIZE = (0x01FC + 4) + EFUSE_MEM_SIZE = 0x01FC + 4 # EFUSE registers & command/conf values - DR_REG_EFUSE_BASE = 0x6001A000 - 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 + DR_REG_EFUSE_BASE = 0x6001A000 + 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 @@ -32,37 +34,49 @@ class EfuseDefineRegisters(EfuseRegistersBase): 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 + 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_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 -class EfuseDefineBlocks(EfuseBlocksBase): + # 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), @@ -77,6 +91,7 @@ class EfuseDefineBlocks(EfuseBlocksBase): ("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 = [] @@ -91,137 +106,50 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - - # List of efuse fields from TRM the chapter eFuse Controller. - EFUSES = [ - # - # Table 51: Parameters in BLOCK0 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("WR_DIS", "efuse", 0, 0, 0, "uint:32", None, None, None, "Disables programming of individual eFuses", None), - ("RD_DIS", "efuse", 0, 1, 0, "uint:7", 0, None, None, "Disables software reading from BLOCK4-10", None), - ("DIS_ICACHE", "config", 0, 1, 8, "bool", 2, None, None, "Disables ICache", None), - ("DIS_USB_JTAG", "usb config", 0, 1, 9, "bool", 2, None, None, "Disables USB JTAG. " - "JTAG access via pads is controlled separately", None), - ("DIS_DOWNLOAD_ICACHE", "config", 0, 1, 10, "bool", 2, None, None, "Disables Icache when SoC is in Download mode", None), - ("DIS_USB_DEVICE", "usb config", 0, 1, 11, "bool", 2, None, None, "Disables USB DEVICE", None), - ("DIS_FORCE_DOWNLOAD", "config", 0, 1, 12, "bool", 2, None, None, "Disables forcing chip into Download mode", None), - ("DIS_CAN", "config", 0, 1, 14, "bool", 2, None, None, "Disables the TWAI Controller hardware", None), - ("JTAG_SEL_ENABLE", "jtag config", 0, 1, 15, "bool", 2, None, None, "Set this bit to enable selection between " - "usb_to_jtag and pad_to_jtag through strapping " - "gpio10 when both reg_dis_usb_jtag and " - "reg_dis_pad_jtag are equal to 0.", None), - ("SOFT_DIS_JTAG", "jtag config", 0, 1, 16, "uint:3", 2, None, None, "Software disables JTAG. When software disabled, " - "JTAG can be activated temporarily by HMAC peripheral", - None), - ("DIS_PAD_JTAG", "jtag config", 0, 1, 19, "bool", 2, None, None, "Permanently disable JTAG access via pads. " - "USB JTAG is controlled separately.", None), - ("DIS_DOWNLOAD_MANUAL_ENCRYPT", "security", 0, 1, 20, "bool", 2, None, None, "Disables flash encryption when in download boot modes", - None), - ("USB_EXCHG_PINS", "usb config", 0, 1, 25, "bool", 30, None, None, "Exchanges USB D+ and D- pins", None), - ("VDD_SPI_AS_GPIO", "config", 0, 1, 26, "bool", 30, None, None, "Set this bit to vdd spi pin function as gpio", None), - ("BTLC_GPIO_ENABLE", "config", 0, 1, 27, "uint:2", 30, None, None, "Enable btlc gpio", None), - ("POWERGLITCH_EN", "config", 0, 1, 29, "bool", 30, None, None, "Set this bit to enable power glitch function", None), - ("POWER_GLITCH_DSENSE", "config", 0, 1, 30, "uint:2", 30, None, None, "Sample delay configuration of power glitch", None), - ("WDT_DELAY_SEL", "WDT config", 0, 2, 16, "bool", 3, None, None, "Selects RTC WDT timeout threshold at startup", None), - ("SPI_BOOT_CRYPT_CNT", "security", 0, 2, 18, "uint:3", 4, None, "bitcount", "Enables encryption and decryption, when an SPI boot " - "mode is set. Enabled when 1 or 3 bits are set," - "disabled otherwise", - {0: "Disable", - 1: "Enable", - 3: "Disable", - 7: "Enable"}), - ("SECURE_BOOT_KEY_REVOKE0", "security", 0, 2, 21, "bool", 5, None, None, "If set, revokes use of secure boot key digest 0", None), - ("SECURE_BOOT_KEY_REVOKE1", "security", 0, 2, 22, "bool", 6, None, None, "If set, revokes use of secure boot key digest 1", None), - ("SECURE_BOOT_KEY_REVOKE2", "security", 0, 2, 23, "bool", 7, None, None, "If set, revokes use of secure boot key digest 2", None), - ("KEY_PURPOSE_0", "security", 0, 2, 24, "uint:4", 8, None, "keypurpose", "KEY0 purpose", None), - ("KEY_PURPOSE_1", "security", 0, 2, 28, "uint:4", 9, None, "keypurpose", "KEY1 purpose", None), - ("KEY_PURPOSE_2", "security", 0, 3, 0, "uint:4", 10, None, "keypurpose", "KEY2 purpose", None), - ("KEY_PURPOSE_3", "security", 0, 3, 4, "uint:4", 11, None, "keypurpose", "KEY3 purpose", None), - ("KEY_PURPOSE_4", "security", 0, 3, 8, "uint:4", 12, None, "keypurpose", "KEY4 purpose", None), - ("KEY_PURPOSE_5", "security", 0, 3, 12, "uint:4", 13, None, "keypurpose", "KEY5 purpose", None), - ("SECURE_BOOT_EN", "security", 0, 3, 20, "bool", 15, None, None, "Enables secure boot", None), - ("SECURE_BOOT_AGGRESSIVE_REVOKE", "security", 0, 3, 21, "bool", 16, None, None, "Enables aggressive secure boot key revocation mode", - None), - ("FLASH_TPUW", "flash config", 0, 3, 28, "uint:4", 18, None, None, "Configures flash startup delay after SoC power-up, " - "unit is (ms/2). When the value is 15, delay is 7.5 ms", - None), - ("DIS_DOWNLOAD_MODE", "security", 0, 4, 0, "bool", 18, None, None, "Disables all Download boot modes", None), - ("DIS_DIRECT_BOOT", "config", 0, 4, 1, "bool", 18, None, None, "Disables direct boot mode", None), - ("DIS_USB_SERIAL_JTAG_ROM_PRINT", "config", 0, 4, 2, "bool", 18, None, None, "Disables USB-Serial-JTAG ROM printing", None), - ("DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE", "usb config", 0, 4, 4, "bool", 18, None, None, "Disables USB-Serial-JTAG download feature in " - "UART download boot mode", None), - ("ENABLE_SECURITY_DOWNLOAD", "security", 0, 4, 5, "bool", 18, None, None, "Enables secure UART download mode " - "(read/write flash only)", None), - ("UART_PRINT_CONTROL", "config", 0, 4, 6, "uint:2", 18, None, None, "Sets the default UART boot message output mode", - {0: "Enabled", - 1: "Enable when GPIO8 is low at reset", - 2: "Enable when GPIO8 is high at reset", - 3: "Disabled"}), - ("FORCE_SEND_RESUME", "config", 0, 4, 13, "bool", 18, None, None, "Force ROM code to send a resume command during SPI boot" - "during SPI boot", None), - ("SECURE_VERSION", "identity", 0, 4, 14, "uint:16", 18, None, "bitcount", "Secure version (used by ESP-IDF anti-rollback feature)", - None), - ("DISABLE_WAFER_VERSION_MAJOR", "config", 0, 5, 0, "bool", 19, None, None, "Disables check of wafer version major", None), - ("DISABLE_BLK_VERSION_MAJOR", "config", 0, 5, 1, "bool", 19, None, None, "Disables check of blk version major", None), - # - # Table 53: Parameters in BLOCK1-10 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("MAC", "identity", 1, 0, 0, "bytes:6", 20, None, "mac", "Factory MAC Address", None), - ("SPI_PAD_CONFIG_CLK", "spi_pad_config", 1, 1, 16, "uint:6", 20, None, None, "SPI CLK pad", None), - ("SPI_PAD_CONFIG_Q", "spi_pad_config", 1, 1, 22, "uint:6", 20, None, None, "SPI Q (D1) pad", None), - ("SPI_PAD_CONFIG_D", "spi_pad_config", 1, 1, 28, "uint:6", 20, None, None, "SPI D (D0) pad", None), - ("SPI_PAD_CONFIG_CS", "spi_pad_config", 1, 2, 2, "uint:6", 20, None, None, "SPI CS pad", None), - ("SPI_PAD_CONFIG_HD", "spi_pad_config", 1, 2, 8, "uint:6", 20, None, None, "SPI HD (D3) pad", None), - ("SPI_PAD_CONFIG_WP", "spi_pad_config", 1, 2, 14, "uint:6", 20, None, None, "SPI WP (D2) pad", None), - ("SPI_PAD_CONFIG_DQS", "spi_pad_config", 1, 2, 20, "uint:6", 20, None, None, "SPI DQS pad", None), - ("SPI_PAD_CONFIG_D4", "spi_pad_config", 1, 2, 26, "uint:6", 20, None, None, "SPI D4 pad", None), - ("SPI_PAD_CONFIG_D5", "spi_pad_config", 1, 3, 0, "uint:6", 20, None, None, "SPI D5 pad", None), - ("SPI_PAD_CONFIG_D6", "spi_pad_config", 1, 3, 6, "uint:6", 20, None, None, "SPI D6 pad", None), - ("SPI_PAD_CONFIG_D7", "spi_pad_config", 1, 3, 12, "uint:6", 20, None, None, "SPI D7 pad", None), - ("WAFER_VERSION", "identity", 1, 3, 18, "uint:3", 20, None, None, "WAFER version", - {0: "(revision 0)", 1: "(revision 1)"}), - ("PKG_VERSION", "identity", 1, 3, 21, "uint:4", 20, None, None, "Package version", - {0: "ESP32-H2(beta1)"}), - ("BLOCK1_VERSION", "identity", 1, 3, 24, "uint:3", 20, None, None, "BLOCK1 efuse version", None), - ("MAC_EXT", "identity", 1, 3, 27, "bytes:2", 20, None, "mac", "MAC extension", None), - ("OPTIONAL_UNIQUE_ID", "identity", 2, 0, 0, "bytes:16", 21, None, "keyblock", "Optional unique 128-bit ID", None), - ("BLOCK2_VERSION", "identity", 2, 4, 4, "uint:3", 21, None, None, "Version of BLOCK2", - {0: "No calibration", - 1: "With calibration"}), - ("CUSTOM_MAC", "identity", 3, 6, 8, "bytes:6", 22, None, "mac", "Custom MAC Address", None), - ] - - KEYBLOCKS = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK_USR_DATA', "config", 3, 0, 0, "bytes:32", 22, None, None, "User data", None), - ('BLOCK_KEY0', "security", 4, 0, 0, "bytes:32", 23, 0, "keyblock", "Encryption key0 or user data", None), - ('BLOCK_KEY1', "security", 5, 0, 0, "bytes:32", 24, 1, "keyblock", "Encryption key1 or user data", None), - ('BLOCK_KEY2', "security", 6, 0, 0, "bytes:32", 25, 2, "keyblock", "Encryption key2 or user data", None), - ('BLOCK_KEY3', "security", 7, 0, 0, "bytes:32", 26, 3, "keyblock", "Encryption key3 or user data", None), - ('BLOCK_KEY4', "security", 8, 0, 0, "bytes:32", 27, 4, "keyblock", "Encryption key4 or user data", None), - ('BLOCK_KEY5', "security", 9, 0, 0, "bytes:32", 28, 5, "keyblock", "Encryption key5 or user data", None), - ('BLOCK_SYS_DATA2', "security", 10, 0, 0, "bytes:32", 29, 6, "keyblock", "System data (part 2)", None), - ] - - # if BLOCK2_VERSION is 1, these efuse fields are in BLOCK2 - BLOCK2_CALIBRATION_EFUSES = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('TEMP_SENSOR_CAL', "calibration", 2, 4, 7, "uint:9", 21, None, "t_sensor", "Temperature calibration", None), - ('ADC1_MODE0_D2', "calibration", 2, 4, 16, "uint:8", 21, None, "adc_tp", "ADC1 calibration 1", None), - ('ADC1_MODE1_D2', "calibration", 2, 4, 24, "uint:8", 21, None, "adc_tp", "ADC1 calibration 2", None), - ('ADC1_MODE2_D2', "calibration", 2, 5, 0, "uint:8", 21, None, "adc_tp", "ADC1 calibration 3", None), - ('ADC1_MODE3_D2', "calibration", 2, 5, 8, "uint:8", 21, None, "adc_tp", "ADC1 calibration 4", None), - ('ADC2_MODE0_D2', "calibration", 2, 5, 16, "uint:8", 21, None, "adc_tp", "ADC2 calibration 5", None), - ('ADC2_MODE1_D2', "calibration", 2, 5, 24, "uint:8", 21, None, "adc_tp", "ADC2 calibration 6", None), - ('ADC2_MODE2_D2', "calibration", 2, 6, 0, "uint:8", 21, None, "adc_tp", "ADC2 calibration 7", None), - ('ADC2_MODE3_D2', "calibration", 2, 6, 8, "uint:8", 21, None, "adc_tp", "ADC2 calibration 8", None), - ('ADC1_MODE0_D1', "calibration", 2, 6, 16, "uint:6", 21, None, "adc_tp", "ADC1 calibration 9", None), - ('ADC1_MODE1_D1', "calibration", 2, 6, 22, "uint:6", 21, None, "adc_tp", "ADC1 calibration 10", None), - ('ADC1_MODE2_D1', "calibration", 2, 6, 28, "uint:6", 21, None, "adc_tp", "ADC1 calibration 11", None), - ('ADC1_MODE3_D1', "calibration", 2, 7, 2, "uint:6", 21, None, "adc_tp", "ADC1 calibration 12", None), - ('ADC2_MODE0_D1', "calibration", 2, 7, 8, "uint:6", 21, None, "adc_tp", "ADC2 calibration 13", None), - ('ADC2_MODE1_D1', "calibration", 2, 7, 14, "uint:6", 21, None, "adc_tp", "ADC2 calibration 14", None), - ('ADC2_MODE2_D1', "calibration", 2, 7, 20, "uint:6", 21, None, "adc_tp", "ADC2 calibration 15", None), - ('ADC2_MODE3_D1', "calibration", 2, 7, 26, "uint:6", 21, None, "adc_tp", "ADC2 calibration 16", None), - ] -# fmt: on + def __init__(self) -> None: + # List of efuse fields from TRM the chapter eFuse Controller. + self.EFUSES = [] + + self.KEYBLOCKS = [] + + # if BLK_VERSION_MAJOR 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) + efuse_file = efuse_file.replace("esp32h2beta1", "esp32h2") + 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 + + for efuse in self.ALL_EFUSES: + if efuse is not None: + self.EFUSES.append(efuse) + + self.ALL_EFUSES = [] diff --git a/espefuse/efuse/esp32h2beta1/operations.py b/espefuse/efuse/esp32h2beta1/operations.py index 9d10f2dd4..9f602544a 100644 --- a/espefuse/efuse/esp32h2beta1/operations.py +++ b/espefuse/efuse/esp32h2beta1/operations.py @@ -17,6 +17,7 @@ from ..base_operations import ( add_common_commands, add_force_write_always, + add_show_sensitive_info_option, burn_bit, burn_block_data, burn_efuse, @@ -55,6 +56,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -105,6 +107,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -163,8 +166,7 @@ def add_commands(subparsers, efuses): 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). " - "Final CUSTOM_MAC = CUSTOM_MAC[48] + MAC_EXT[16]", + "separated by colons (e.g. AA:CD:EF:01:02:03).", type=fields.base_fields.CheckArgValue(efuses, "CUSTOM_MAC"), ) add_force_write_always(p) @@ -191,7 +193,7 @@ def set_flash_voltage(esp, efuses, args): def adc_info(esp, efuses, args): print("") # fmt: off - if efuses["BLOCK2_VERSION"].get() == 1: + if efuses["BLK_VERSION_MAJOR"].get() == 1: print("Temperature Sensor Calibration = {}C".format(efuses["TEMP_SENSOR_CAL"].get())) print("") @@ -222,7 +224,7 @@ def adc_info(esp, efuses, args): print(" MODE3 D1 reading (250mV): {}".format(efuses["ADC2_MODE3_D1"].get())) print(" MODE3 D2 reading (2000mV): {}".format(efuses["ADC2_MODE3_D2"].get())) else: - print("BLOCK2_VERSION = {}".format(efuses["BLOCK2_VERSION"].get_meaning())) + print("BLK_VERSION_MAJOR = {}".format(efuses["BLK_VERSION_MAJOR"].get_meaning())) # fmt: on @@ -276,7 +278,13 @@ def burn_key(esp, efuses, args, digest=None): if efuses[block.key_purpose_name].need_reverse(keypurpose): revers_msg = "\tReversing byte order for AES-XTS hardware peripheral" data = data[::-1] - print("-> [%s]" % (util.hexify(data, " "))) + 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: diff --git a/espefuse/efuse/esp32p4/__init__.py b/espefuse/efuse/esp32p4/__init__.py new file mode 100644 index 000000000..a3b55a802 --- /dev/null +++ b/espefuse/efuse/esp32p4/__init__.py @@ -0,0 +1,3 @@ +from . import operations +from .emulate_efuse_controller import EmulateEfuseController +from .fields import EspEfuses diff --git a/espefuse/efuse/esp32p4/emulate_efuse_controller.py b/espefuse/efuse/esp32p4/emulate_efuse_controller.py new file mode 100644 index 000000000..aa670aff7 --- /dev/null +++ b/espefuse/efuse/esp32p4/emulate_efuse_controller.py @@ -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 --git a/espefuse/efuse/esp32p4/fields.py b/espefuse/efuse/esp32p4/fields.py new file mode 100644 index 000000000..b79816208 --- /dev/null +++ b/espefuse/efuse/esp32p4/fields.py @@ -0,0 +1,433 @@ +# 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 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") + 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") + 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 + ] +# 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 --git a/espefuse/efuse/esp32p4/mem_definition.py b/espefuse/efuse/esp32p4/mem_definition.py new file mode 100644 index 000000000..1d56f8d86 --- /dev/null +++ b/espefuse/efuse/esp32p4/mem_definition.py @@ -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 --git a/espefuse/efuse/esp32p4/operations.py b/espefuse/efuse/esp32p4/operations.py new file mode 100644 index 000000000..093a04802 --- /dev/null +++ b/espefuse/efuse/esp32p4/operations.py @@ -0,0 +1,391 @@ +# 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 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 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]) : + ] + + 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 --git a/espefuse/efuse/esp32s2/emulate_efuse_controller.py b/espefuse/efuse/esp32s2/emulate_efuse_controller.py index 749fd424f..497c91a5f 100644 --- a/espefuse/efuse/esp32s2/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32s2/emulate_efuse_controller.py @@ -16,13 +16,13 @@ class EmulateEfuseController(EmulateEfuseControllerBase): CHIP_NAME = "ESP32-S2" mem = None debug = False - Blocks = EfuseDefineBlocks - Fields = EfuseDefineFields - REGS = EfuseDefineRegisters 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_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ def handle_writing_event(self, addr, value): 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 --git a/espefuse/efuse/esp32s2/fields.py b/espefuse/efuse/esp32s2/fields.py index 4bc7af9a7..a4113848b 100644 --- a/espefuse/efuse/esp32s2/fields.py +++ b/espefuse/efuse/esp32s2/fields.py @@ -54,16 +54,15 @@ class EspEfuses(base_fields.EspEfusesBase): Wrapper object to manage the efuse fields in a connected ESP bootloader """ - Blocks = EfuseDefineBlocks() - Fields = EfuseDefineFields() - REGS = EfuseDefineRegisters - BURN_BLOCK_DATA_NAMES = Blocks.get_burn_block_data_names() - BLOCKS_FOR_KEYS = Blocks.get_blocks_for_keys() - 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 @@ -85,59 +84,43 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ] if not skip_connect: self.get_coding_scheme_warnings() - self.efuses = [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.EFUSES - ] + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.KEYBLOCKS + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS ] if skip_connect: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] else: if self["BLK_VERSION_MINOR"].get() == 1: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CALC + 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: + 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: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + 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: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): return e raise KeyError @@ -158,10 +141,6 @@ def print_status_regs(self): ) ) - def get_block_errors(self, block_num): - """Returns (error count, failure boolean flag)""" - return self.blocks[block_num].num_errors, self.blocks[block_num].fail - def efuse_controller_setup(self): self.set_efuse_timing() self.clear_pgm_registers() @@ -181,9 +160,13 @@ def clear_pgm_registers(self): 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" ) @@ -310,12 +293,9 @@ def get_coding_scheme_warnings(self, silent=False): self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR0_REG + offs * 4) for offs in range(5) ] - data = BitArray() + block.err_bitarray.pos = 0 for word in reversed(words): - data.append("uint:32=%d" % word) - # pos=32 because EFUSE_WR_DIS goes first it is 32bit long - # and not under error control - block.err_bitarray.overwrite(data, pos=32) + block.err_bitarray.overwrite(BitArray("uint:32=%d" % word)) block.num_errors = block.err_bitarray.count(True) block.fail = block.num_errors != 0 else: @@ -342,9 +322,10 @@ def get_coding_scheme_warnings(self, silent=False): def summary(self): if self["VDD_SPI_FORCE"].get() == 0: output = "Flash voltage (VDD_SPI) determined by GPIO45 on reset " - "(GPIO45=High: VDD_SPI pin is powered from internal 1.8V LDO\n" + output += "(GPIO45=High: VDD_SPI pin is powered from internal 1.8V LDO\n" output += "GPIO45=Low or NC: VDD_SPI pin is powered directly from " - "VDD3P3_RTC_IO via resistor Rspi. Typically this voltage is 3.3 V)." + output += "VDD3P3_RTC_IO via resistor Rspi. " + output += "Typically this voltage is 3.3 V)." elif self["VDD_SPI_XPD"].get() == 0: output = "Flash voltage (VDD_SPI) internal regulator disabled by efuse." elif self["VDD_SPI_TIEH"].get() == 0: @@ -356,35 +337,22 @@ def summary(self): class EfuseField(base_fields.EfuseFieldBase): @staticmethod - def from_tuple(parent, efuse_tuple, type_class): + def convert(parent, efuse): return { "mac": EfuseMacField, "keypurpose": EfuseKeyPurposeField, "t_sensor": EfuseTempSensor, "adc_tp": EfuseAdcPointCalibration, "wafer": EfuseWafer, - }.get(type_class, EfuseField)(parent, efuse_tuple) - - def get_info(self): - output = "%s (BLOCK%d)" % (self.name, self.block) - errs, fail = self.parent.get_block_errors(self.block) - if errs != 0 or fail: - output += ( - "[FAIL:%d]" % (fail) - if self.block == 0 - else "[ERRS:%d FAIL:%d]" % (errs, fail) - ) - if self.efuse_class == "keyblock": - name = self.parent.blocks[self.block].key_purpose_name - if name is not None: - output += "\n Purpose: %s\n " % (self.parent[name].get()) - return output + }.get(efuse.class_type, EfuseField)(parent, efuse) class EfuseWafer(EfuseField): def get(self, from_read=True): hi_bits = self.parent["WAFER_VERSION_MINOR_HI"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_HI"].bit_len == 1 lo_bits = self.parent["WAFER_VERSION_MINOR_LO"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_LO"].bit_len == 3 return (hi_bits << 3) + lo_bits def save(self, new_value): diff --git a/espefuse/efuse/esp32s2/mem_definition.py b/espefuse/efuse/esp32s2/mem_definition.py index 94642ad3c..b83ea9139 100644 --- a/espefuse/efuse/esp32s2/mem_definition.py +++ b/espefuse/efuse/esp32s2/mem_definition.py @@ -4,24 +4,31 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase +import os +import yaml + +from ..mem_definition_base import ( + EfuseBlocksBase, + EfuseFieldsBase, + EfuseRegistersBase, + Field, +) -# fmt: off -class EfuseDefineRegisters(EfuseRegistersBase): - EFUSE_MEM_SIZE = (0x01FC + 4) +class EfuseDefineRegisters(EfuseRegistersBase): + EFUSE_MEM_SIZE = 0x01FC + 4 # EFUSE registers & command/conf values - DR_REG_EFUSE_BASE = 0x3f41A000 - 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 + 0x194 - EFUSE_RD_RS_ERR1_REG = DR_REG_EFUSE_BASE + 0x198 + DR_REG_EFUSE_BASE = 0x3F41A000 + 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 + 0x194 + EFUSE_RD_RS_ERR1_REG = DR_REG_EFUSE_BASE + 0x198 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 @@ -32,28 +39,28 @@ class EfuseDefineRegisters(EfuseRegistersBase): EFUSE_WR_TIM_CONF1_REG = DR_REG_EFUSE_BASE + 0x1F4 EFUSE_WR_TIM_CONF2_REG = DR_REG_EFUSE_BASE + 0x1F8 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 + 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_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_DAC_CONF_REG = DR_REG_EFUSE_BASE + 0x1e8 + EFUSE_DAC_CONF_REG = DR_REG_EFUSE_BASE + 0x1E8 EFUSE_DAC_CLK_DIV_S = 0 EFUSE_DAC_CLK_DIV_M = 0xFF << EFUSE_DAC_CLK_DIV_S @@ -89,7 +96,7 @@ class EfuseDefineRegisters(EfuseRegistersBase): # Taken from TRM chapter "eFuse Controller": eFuse-Programming Timing 80: (0x2, 0x320, 0x2, 0x4), 40: (0x1, 0x190, 0x1, 0x2), - 20: (0x1, 0xC8, 0x1, 0x1), + 20: (0x1, 0xC8, 0x1, 0x1), } VDDQ_TIMING_PARAMETERS = { @@ -110,10 +117,10 @@ class EfuseDefineRegisters(EfuseRegistersBase): 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), @@ -128,6 +135,7 @@ class EfuseDefineBlocks(EfuseBlocksBase): ("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 = [] @@ -142,167 +150,59 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - - # List of efuse fields from TRM the chapter eFuse Controller. - EFUSES = [ - # - # Table 51: Parameters in BLOCK0 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("WR_DIS", "efuse", 0, 0, 0, "uint:32", None, None, None, "Disables programming of individual eFuses", None), - ("RD_DIS", "efuse", 0, 1, 0, "uint:7", 0, None, None, "Disables software reading from BLOCK4-10", None), - ("DIS_RTC_RAM_BOOT", "config", 0, 1, 7, "bool", 1, None, None, "Disables boot from RTC RAM", None), - ("DIS_ICACHE", "config", 0, 1, 8, "bool", 2, None, None, "Disables ICache", None), - ("DIS_DCACHE", "config", 0, 1, 9, "bool", 2, None, None, "Disables DCache", None), - ("DIS_DOWNLOAD_ICACHE", "config", 0, 1, 10, "bool", 2, None, None, "Disables Icache when SoC is in Download mode", None), - ("DIS_DOWNLOAD_DCACHE", "config", 0, 1, 11, "bool", 2, None, None, "Disables Dcache when SoC is in Download mode", None), - ("DIS_FORCE_DOWNLOAD", "config", 0, 1, 12, "bool", 2, None, None, "Disables forcing chip into Download mode", None), - ("DIS_USB", "usb config", 0, 1, 13, "bool", 2, None, None, "Disables the USB OTG hardware", None), - ("DIS_CAN", "config", 0, 1, 14, "bool", 2, None, None, "Disables the TWAI Controller hardware", None), - ("DIS_BOOT_REMAP", "config", 0, 1, 15, "bool", 2, None, None, "Disables capability to Remap RAM to ROM address space", - None), - ("SOFT_DIS_JTAG", "security", 0, 1, 17, "bool", 2, None, None, "Software disables JTAG. When software disabled, " - "JTAG can be activated temporarily by HMAC peripheral", - None), - ("HARD_DIS_JTAG", "security", 0, 1, 18, "bool", 2, None, None, "Hardware disables JTAG permanently", None), - ("DIS_DOWNLOAD_MANUAL_ENCRYPT", "security", 0, 1, 19, "bool", 2, None, None, "Disables flash encryption when in download boot modes", - None), - ("USB_EXCHG_PINS", "usb config", 0, 1, 24, "bool", 30, None, None, "Exchanges USB D+ and D- pins", None), - ("EXT_PHY_ENABLE", "usb config", 0, 1, 25, "bool", 30, None, None, "Enables external USB PHY", None), - ("USB_FORCE_NOPERSIST", "usb config", 0, 1, 26, "bool", 30, None, None, "Forces to set USB BVALID to 1", None), - ("BLOCK0_VERSION", "identity", 0, 1, 27, "uint:2", 30, None, None, "BLOCK0 efuse version", None), - ("VDD_SPI_FORCE", "VDD_SPI config", 0, 2, 6, "bool", 3, None, None, "Force using VDD_SPI_XPD and VDD_SPI_TIEH " - "to configure VDD_SPI LDO", None), - ("VDD_SPI_XPD", "VDD_SPI config", 0, 2, 4, "bool", 3, None, None, "The VDD_SPI regulator is powered on", None), - ("VDD_SPI_TIEH", "VDD_SPI config", 0, 2, 5, "bool", 3, None, None, "The VDD_SPI power supply voltage at reset", - {0: "Connect to 1.8V LDO", - 1: "Connect to VDD3P3_RTC_IO"}), - ("WDT_DELAY_SEL", "WDT config", 0, 2, 16, "uint:2", 3, None, None, "Selects RTC WDT timeout threshold at startup", None), - ("SPI_BOOT_CRYPT_CNT", "security", 0, 2, 18, "uint:3", 4, None, "bitcount", "Enables encryption and decryption, when an SPI boot " - "mode is set. Enabled when 1 or 3 bits are set," - "disabled otherwise", - - {0: "Disable", - 1: "Enable", - 3: "Disable", - 7: "Enable"}), - ("SECURE_BOOT_KEY_REVOKE0", "security", 0, 2, 21, "bool", 5, None, None, "If set, revokes use of secure boot key digest 0", None), - ("SECURE_BOOT_KEY_REVOKE1", "security", 0, 2, 22, "bool", 6, None, None, "If set, revokes use of secure boot key digest 1", None), - ("SECURE_BOOT_KEY_REVOKE2", "security", 0, 2, 23, "bool", 7, None, None, "If set, revokes use of secure boot key digest 2", None), - ("KEY_PURPOSE_0", "security", 0, 2, 24, "uint:4", 8, None, "keypurpose", "KEY0 purpose", None), - ("KEY_PURPOSE_1", "security", 0, 2, 28, "uint:4", 9, None, "keypurpose", "KEY1 purpose", None), - ("KEY_PURPOSE_2", "security", 0, 3, 0, "uint:4", 10, None, "keypurpose", "KEY2 purpose", None), - ("KEY_PURPOSE_3", "security", 0, 3, 4, "uint:4", 11, None, "keypurpose", "KEY3 purpose", None), - ("KEY_PURPOSE_4", "security", 0, 3, 8, "uint:4", 12, None, "keypurpose", "KEY4 purpose", None), - ("KEY_PURPOSE_5", "security", 0, 3, 12, "uint:4", 13, None, "keypurpose", "KEY5 purpose", None), - ("SECURE_BOOT_EN", "security", 0, 3, 20, "bool", 15, None, None, "Enables secure boot", None), - ("SECURE_BOOT_AGGRESSIVE_REVOKE", "security", 0, 3, 21, "bool", 16, None, None, "Enables aggressive secure boot key revocation mode", - None), - ("FLASH_TPUW", "config", 0, 3, 28, "uint:4", 18, None, None, "Configures flash startup delay after SoC power-up, " - "unit is (ms/2). When the value is 15, delay is 7.5 ms", - None), - ("DIS_DOWNLOAD_MODE", "security", 0, 4, 0, "bool", 18, None, None, "Disables all Download boot modes", None), - ("DIS_LEGACY_SPI_BOOT", "config", 0, 4, 1, "bool", 18, None, None, "Disables Legacy SPI boot mode", None), - ("UART_PRINT_CHANNEL", "config", 0, 4, 2, "bool", 18, None, None, "Selects the default UART for printing boot msg", - - {0: "UART0", - 1: "UART1"}), - ("DIS_USB_DOWNLOAD_MODE", "config", 0, 4, 4, "bool", 18, None, None, "Disables use of USB in UART download boot mode", None), - ("ENABLE_SECURITY_DOWNLOAD", "security", 0, 4, 5, "bool", 18, None, None, "Enables secure UART download mode " - "(read/write flash only)", None), - ("UART_PRINT_CONTROL", "config", 0, 4, 6, "uint:2", 18, None, None, "Sets the default UART boot message output mode", - - {0: "Enabled", - 1: "Enable when GPIO 46 is low at reset", - 2: "Enable when GPIO 46 is high at rest", - 3: "Disabled"}), - ("PIN_POWER_SELECTION", "VDD_SPI config", 0, 4, 8, "bool", 18, None, None, "Sets default power supply for GPIO33..37, " - "set when SPI flash is initialized", - - {0: "VDD3P3_CPU", - 1: "VDD_SPI"}), - ("FLASH_TYPE", "config", 0, 4, 9, "bool", 18, None, None, "Selects SPI flash type", - - {0: "4 data lines", - 1: "8 data lines"}), - ("FORCE_SEND_RESUME", "config", 0, 4, 10, "bool", 18, None, None, "Forces ROM code to send an SPI flash resume command " - "during SPI boot", None), - ("SECURE_VERSION", "identity", 0, 4, 11, "uint:16", 18, None, "bitcount", "Secure version (used by ESP-IDF anti-rollback feature)", - None), - ("DISABLE_WAFER_VERSION_MAJOR", "config", 0, 5, 0, "bool", 19, None, None, "Disables check of wafer version major", None), - ("DISABLE_BLK_VERSION_MAJOR", "config", 0, 5, 1, "bool", 19, None, None, "Disables check of blk version major", None), - # - # Table 53: Parameters in BLOCK1-10 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("MAC", "identity", 1, 0, 0, "bytes:6", 20, None, "mac", "Factory MAC Address", None), - ("SPI_PAD_CONFIG_CLK", "spi_pad_config", 1, 1, 16, "uint:6", 20, None, None, "SPI CLK pad", None), - ("SPI_PAD_CONFIG_Q", "spi_pad_config", 1, 1, 22, "uint:6", 20, None, None, "SPI Q (D1) pad", None), - ("SPI_PAD_CONFIG_D", "spi_pad_config", 1, 1, 28, "uint:6", 20, None, None, "SPI D (D0) pad", None), - ("SPI_PAD_CONFIG_CS", "spi_pad_config", 1, 2, 2, "uint:6", 20, None, None, "SPI CS pad", None), - ("SPI_PAD_CONFIG_HD", "spi_pad_config", 1, 2, 8, "uint:6", 20, None, None, "SPI HD (D3) pad", None), - ("SPI_PAD_CONFIG_WP", "spi_pad_config", 1, 2, 14, "uint:6", 20, None, None, "SPI WP (D2) pad", None), - ("SPI_PAD_CONFIG_DQS", "spi_pad_config", 1, 2, 20, "uint:6", 20, None, None, "SPI DQS pad", None), - ("SPI_PAD_CONFIG_D4", "spi_pad_config", 1, 2, 26, "uint:6", 20, None, None, "SPI D4 pad", None), - ("SPI_PAD_CONFIG_D5", "spi_pad_config", 1, 3, 0, "uint:6", 20, None, None, "SPI D5 pad", None), - ("SPI_PAD_CONFIG_D6", "spi_pad_config", 1, 3, 6, "uint:6", 20, None, None, "SPI D6 pad", None), - ("SPI_PAD_CONFIG_D7", "spi_pad_config", 1, 3, 12, "uint:6", 20, None, None, "SPI D7 pad", None), - - ("WAFER_VERSION_MAJOR", "identity", 1, 3, 18, "uint:2", 20, None, None, "WAFER_VERSION_MAJOR", None), - ("WAFER_VERSION_MINOR_HI", "identity", 1, 3, 20, "uint:1", 20, None, None, "WAFER_VERSION_MINOR most significant bits", None), - ("FLASH_VERSION", "identity", 1, 3, 21, "uint:4", 20, None, None, "Flash version", - {0: "No Embedded Flash", - 1: "Embedded Flash 2MB", - 2: "Embedded Flash 4MB"}), - ("BLK_VERSION_MAJOR", "identity", 1, 3, 25, "uint:2", 20, None, None, "BLOCK version major", None), - ("PSRAM_VERSION", "identity", 1, 3, 28, "uint:4", 20, None, None, "PSRAM version", - {0: "No Embedded PSRAM", - 1: "Embedded PSRAM 2MB", - 2: "Embedded PSRAM 4MB"}), - ("PKG_VERSION", "identity", 1, 4, 0, "uint:4", 20, None, None, "Package version", None), - ("WAFER_VERSION_MINOR_LO", "identity", 1, 4, 4, "uint:3", 20, None, None, "WAFER_VERSION_MINOR least significant bits", None), - - ('OPTIONAL_UNIQUE_ID', "identity", 2, 0, 0, "bytes:16", 21, None, "keyblock", "Optional unique 128-bit ID", None), - ("BLK_VERSION_MINOR", "identity", 2, 4, 4, "uint:3", 21, None, None, "BLOCK version minor", - {0: "No calibration", - 1: "With ADC calibration V1", - 2: "With ADC calibration V2"}), - ("CUSTOM_MAC", "identity", 3, 6, 8, "bytes:6", 22, None, "mac", "Custom MAC Address", None), - ] - - KEYBLOCKS = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK_USR_DATA', "config", 3, 0, 0, "bytes:32", 22, None, None, "User data", None), - ('BLOCK_KEY0', "security", 4, 0, 0, "bytes:32", 23, 0, "keyblock", "Encryption key0 or user data", None), - ('BLOCK_KEY1', "security", 5, 0, 0, "bytes:32", 24, 1, "keyblock", "Encryption key1 or user data", None), - ('BLOCK_KEY2', "security", 6, 0, 0, "bytes:32", 25, 2, "keyblock", "Encryption key2 or user data", None), - ('BLOCK_KEY3', "security", 7, 0, 0, "bytes:32", 26, 3, "keyblock", "Encryption key3 or user data", None), - ('BLOCK_KEY4', "security", 8, 0, 0, "bytes:32", 27, 4, "keyblock", "Encryption key4 or user data", None), - ('BLOCK_KEY5', "security", 9, 0, 0, "bytes:32", 28, 5, "keyblock", "Encryption key5 or user data", None), - ('BLOCK_SYS_DATA2', "security", 10, 0, 0, "bytes:32", 29, 6, None, "System data (part 2)", None), - ] - - # if BLK_VERSION_MINOR is 1, these efuse fields are in BLOCK2 - BLOCK2_CALIBRATION_EFUSES = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('TEMP_SENSOR_CAL', "calibration", 2, 4, 7, "uint:9", 21, None, "t_sensor", "Temperature calibration", None), - ('ADC1_MODE0_D2', "calibration", 2, 4, 16, "uint:8", 21, None, "adc_tp", "ADC1 calibration 1", None), - ('ADC1_MODE1_D2', "calibration", 2, 4, 24, "uint:8", 21, None, "adc_tp", "ADC1 calibration 2", None), - ('ADC1_MODE2_D2', "calibration", 2, 5, 0, "uint:8", 21, None, "adc_tp", "ADC1 calibration 3", None), - ('ADC1_MODE3_D2', "calibration", 2, 5, 8, "uint:8", 21, None, "adc_tp", "ADC1 calibration 4", None), - ('ADC2_MODE0_D2', "calibration", 2, 5, 16, "uint:8", 21, None, "adc_tp", "ADC2 calibration 5", None), - ('ADC2_MODE1_D2', "calibration", 2, 5, 24, "uint:8", 21, None, "adc_tp", "ADC2 calibration 6", None), - ('ADC2_MODE2_D2', "calibration", 2, 6, 0, "uint:8", 21, None, "adc_tp", "ADC2 calibration 7", None), - ('ADC2_MODE3_D2', "calibration", 2, 6, 8, "uint:8", 21, None, "adc_tp", "ADC2 calibration 8", None), - ('ADC1_MODE0_D1', "calibration", 2, 6, 16, "uint:6", 21, None, "adc_tp", "ADC1 calibration 9", None), - ('ADC1_MODE1_D1', "calibration", 2, 6, 22, "uint:6", 21, None, "adc_tp", "ADC1 calibration 10", None), - ('ADC1_MODE2_D1', "calibration", 2, 6, 28, "uint:6", 21, None, "adc_tp", "ADC1 calibration 11", None), - ('ADC1_MODE3_D1', "calibration", 2, 7, 2, "uint:6", 21, None, "adc_tp", "ADC1 calibration 12", None), - ('ADC2_MODE0_D1', "calibration", 2, 7, 8, "uint:6", 21, None, "adc_tp", "ADC2 calibration 13", None), - ('ADC2_MODE1_D1', "calibration", 2, 7, 14, "uint:6", 21, None, "adc_tp", "ADC2 calibration 14", None), - ('ADC2_MODE2_D1', "calibration", 2, 7, 20, "uint:6", 21, None, "adc_tp", "ADC2 calibration 15", None), - ('ADC2_MODE3_D1', "calibration", 2, 7, 26, "uint:6", 21, None, "adc_tp", "ADC2 calibration 16", None), - ] - - CALC = [ - ("WAFER_VERSION_MINOR", "identity", 0, None, None, "uint:4", None, None, "wafer", "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)", None), - ] -# fmt: on + 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 = "WAFER_VERSION_MINOR" + f.block = 0 + f.bit_len = 4 + f.type = f"uint:{f.bit_len}" + f.category = "identity" + f.class_type = "wafer" + f.description = "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)" + self.CALC.append(f) + + for efuse in self.ALL_EFUSES: + if efuse is not None: + self.EFUSES.append(efuse) + + self.ALL_EFUSES = [] diff --git a/espefuse/efuse/esp32s2/operations.py b/espefuse/efuse/esp32s2/operations.py index 26cb23007..5ccfac3c9 100644 --- a/espefuse/efuse/esp32s2/operations.py +++ b/espefuse/efuse/esp32s2/operations.py @@ -18,6 +18,7 @@ from ..base_operations import ( add_common_commands, add_force_write_always, + add_show_sensitive_info_option, burn_bit, burn_block_data, burn_efuse, @@ -56,6 +57,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -106,6 +108,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -385,7 +388,13 @@ def burn_key(esp, efuses, args, digest=None): if efuses[block.key_purpose_name].need_reverse(keypurpose): revers_msg = "\tReversing byte order for AES-XTS hardware peripheral" data = data[::-1] - print("-> [%s]" % (util.hexify(data, " "))) + 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: diff --git a/espefuse/efuse/esp32s3/emulate_efuse_controller.py b/espefuse/efuse/esp32s3/emulate_efuse_controller.py index 69e8bafac..7e767b954 100644 --- a/espefuse/efuse/esp32s3/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32s3/emulate_efuse_controller.py @@ -16,13 +16,13 @@ class EmulateEfuseController(EmulateEfuseControllerBase): CHIP_NAME = "ESP32-S3" mem = None debug = False - Blocks = EfuseDefineBlocks - Fields = EfuseDefineFields - REGS = EfuseDefineRegisters 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_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ def handle_writing_event(self, addr, value): 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 --git a/espefuse/efuse/esp32s3/fields.py b/espefuse/efuse/esp32s3/fields.py index a96f0cc07..604c4a45c 100644 --- a/espefuse/efuse/esp32s3/fields.py +++ b/espefuse/efuse/esp32s3/fields.py @@ -54,16 +54,15 @@ class EspEfuses(base_fields.EspEfusesBase): Wrapper object to manage the efuse fields in a connected ESP bootloader """ - Blocks = EfuseDefineBlocks() - Fields = EfuseDefineFields() - REGS = EfuseDefineRegisters - BURN_BLOCK_DATA_NAMES = Blocks.get_burn_block_data_names() - BLOCKS_FOR_KEYS = Blocks.get_blocks_for_keys() - 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 @@ -85,59 +84,43 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ] if not skip_connect: self.get_coding_scheme_warnings() - self.efuses = [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.EFUSES - ] + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.KEYBLOCKS + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS ] if skip_connect: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] else: if self["BLK_VERSION_MAJOR"].get() == 1: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CALC + 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: + 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: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + 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: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): return e raise KeyError @@ -158,10 +141,6 @@ def print_status_regs(self): ) ) - def get_block_errors(self, block_num): - """Returns (error count, failure boolean flag)""" - return self.blocks[block_num].num_errors, self.blocks[block_num].fail - def efuse_controller_setup(self): self.set_efuse_timing() self.clear_pgm_registers() @@ -181,9 +160,13 @@ def clear_pgm_registers(self): 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" ) @@ -249,6 +232,13 @@ def set_efuse_timing(self): "The eFuse supports only xtal=40M (xtal was %d)" % apb_freq ) + self.update_reg(self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_NUM_M, 0xFF) + self.update_reg( + self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_CLK_DIV_M, 0x28 + ) + self.update_reg( + self.REGS.EFUSE_WR_TIM_CONF1_REG, self.REGS.EFUSE_PWR_ON_NUM_M, 0x3000 + ) self.update_reg( self.REGS.EFUSE_WR_TIM_CONF2_REG, self.REGS.EFUSE_PWR_OFF_NUM_M, 0x190 ) @@ -264,12 +254,9 @@ def get_coding_scheme_warnings(self, silent=False): self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR0_REG + offs * 4) for offs in range(5) ] - data = BitArray() + block.err_bitarray.pos = 0 for word in reversed(words): - data.append("uint:32=%d" % word) - # pos=32 because EFUSE_WR_DIS goes first it is 32bit long - # and not under error control - block.err_bitarray.overwrite(data, pos=32) + block.err_bitarray.overwrite(BitArray("uint:32=%d" % word)) block.num_errors = block.err_bitarray.count(True) block.fail = block.num_errors != 0 else: @@ -296,9 +283,10 @@ def get_coding_scheme_warnings(self, silent=False): def summary(self): if self["VDD_SPI_FORCE"].get() == 0: output = "Flash voltage (VDD_SPI) determined by GPIO45 on reset " - "(GPIO45=High: VDD_SPI pin is powered from internal 1.8V LDO\n" + output += "(GPIO45=High: VDD_SPI pin is powered from internal 1.8V LDO\n" output += "GPIO45=Low or NC: VDD_SPI pin is powered directly from " - "VDD3P3_RTC_IO via resistor Rspi. Typically this voltage is 3.3 V)." + output += "VDD3P3_RTC_IO via resistor Rspi. " + output += "Typically this voltage is 3.3 V)." elif self["VDD_SPI_XPD"].get() == 0: output = "Flash voltage (VDD_SPI) internal regulator disabled by efuse." elif self["VDD_SPI_TIEH"].get() == 0: @@ -310,35 +298,22 @@ def summary(self): class EfuseField(base_fields.EfuseFieldBase): @staticmethod - def from_tuple(parent, efuse_tuple, type_class): + def convert(parent, efuse): return { "mac": EfuseMacField, "keypurpose": EfuseKeyPurposeField, "t_sensor": EfuseTempSensor, "adc_tp": EfuseAdcPointCalibration, "wafer": EfuseWafer, - }.get(type_class, EfuseField)(parent, efuse_tuple) - - def get_info(self): - output = "%s (BLOCK%d)" % (self.name, self.block) - errs, fail = self.parent.get_block_errors(self.block) - if errs != 0 or fail: - output += ( - "[FAIL:%d]" % (fail) - if self.block == 0 - else "[ERRS:%d FAIL:%d]" % (errs, fail) - ) - if self.efuse_class == "keyblock": - name = self.parent.blocks[self.block].key_purpose_name - if name is not None: - output += "\n Purpose: %s\n " % (self.parent[name].get()) - return output + }.get(efuse.class_type, EfuseField)(parent, efuse) class EfuseWafer(EfuseField): def get(self, from_read=True): hi_bits = self.parent["WAFER_VERSION_MINOR_HI"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_HI"].bit_len == 1 lo_bits = self.parent["WAFER_VERSION_MINOR_LO"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_LO"].bit_len == 3 return (hi_bits << 3) + lo_bits def save(self, new_value): @@ -471,6 +446,14 @@ def get(self, from_read=True): 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))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"): + raise esptool.FatalError(f"{self.name} can not have {str_new_value} key due to a hardware bug (please see TRM for more details)") return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/espefuse/efuse/esp32s3/mem_definition.py b/espefuse/efuse/esp32s3/mem_definition.py index b4e19a76c..54c88712c 100644 --- a/espefuse/efuse/esp32s3/mem_definition.py +++ b/espefuse/efuse/esp32s3/mem_definition.py @@ -4,25 +4,32 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase +import os +import yaml + +from ..mem_definition_base import ( + EfuseBlocksBase, + EfuseFieldsBase, + EfuseRegistersBase, + Field, +) -# fmt: off -class EfuseDefineRegisters(EfuseRegistersBase): +class EfuseDefineRegisters(EfuseRegistersBase): EFUSE_ADDR_MASK = 0x00000FFF - EFUSE_MEM_SIZE = (0x01FC + 4) + EFUSE_MEM_SIZE = 0x01FC + 4 # EFUSE registers & command/conf values - DR_REG_EFUSE_BASE = 0x60007000 - 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 + DR_REG_EFUSE_BASE = 0x60007000 + 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 @@ -33,37 +40,49 @@ class EfuseDefineRegisters(EfuseRegistersBase): EFUSE_WR_TIM_CONF1_REG = DR_REG_EFUSE_BASE + 0x1F4 EFUSE_WR_TIM_CONF2_REG = DR_REG_EFUSE_BASE + 0x1F8 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 + 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_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 -class EfuseDefineBlocks(EfuseBlocksBase): + # 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), @@ -78,6 +97,7 @@ class EfuseDefineBlocks(EfuseBlocksBase): ("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 = [] @@ -92,163 +112,59 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - - # List of efuse fields from TRM the chapter eFuse Controller. - EFUSES = [ - # - # Table 51: Parameters in BLOCK0 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("WR_DIS", "efuse", 0, 0, 0, "uint:32", None, None, None, "Disables programming of individual eFuses", None), - ("RD_DIS", "efuse", 0, 1, 0, "uint:7", 0, None, None, "Disables software reading from BLOCK4-10", None), - ("DIS_ICACHE", "config", 0, 1, 8, "bool", 2, None, None, "Disables ICache", None), - ("DIS_DCACHE", "config", 0, 1, 9, "bool", 2, None, None, "Disables DCache", None), - ("DIS_DOWNLOAD_ICACHE", "config", 0, 1, 10, "bool", 2, None, None, "Disables Icache when SoC is in Download mode", None), - ("DIS_DOWNLOAD_DCACHE", "config", 0, 1, 11, "bool", 2, None, None, "Disables Dcache when SoC is in Download mode", None), - ("DIS_FORCE_DOWNLOAD", "config", 0, 1, 12, "bool", 2, None, None, "Disables forcing chip into Download mode", None), - ("DIS_USB", "usb config", 0, 1, 13, "bool", 2, None, None, "Disables the USB OTG hardware", None), - ("DIS_CAN", "config", 0, 1, 14, "bool", 2, None, None, "Disables the TWAI Controller hardware", None), - ("DIS_APP_CPU", "config", 0, 1, 15, "bool", 2, None, None, "Disables APP CPU", None), - ("SOFT_DIS_JTAG", "security", 0, 1, 16, "uint:3", 31, None, None, "Software disables JTAG by programming " - "odd number of 1 bit(s). " - "JTAG can be re-enabled via HMAC peripheral", - None), - ("HARD_DIS_JTAG", "security", 0, 1, 19, "bool", 2, None, None, "Hardware disables JTAG permanently", None), - - ("DIS_DOWNLOAD_MANUAL_ENCRYPT", "security", 0, 1, 20, "bool", 2, None, None, "Disables flash encryption when in download boot modes", - None), - ("USB_EXCHG_PINS", "usb config", 0, 1, 25, "bool", 30, None, None, "Exchanges USB D+ and D- pins", None), - ("EXT_PHY_ENABLE", "usb config", 0, 1, 26, "bool", 30, None, None, "Enables external USB PHY", None), - ("BTLC_GPIO_ENABLE", "usb config", 0, 1, 27, "uint:2", 30, None, None, "Enables BTLC GPIO", None), - ("VDD_SPI_XPD", "VDD_SPI config", 0, 2, 4, "bool", 3, None, None, "The VDD_SPI regulator is powered on", None), - ("VDD_SPI_TIEH", "VDD_SPI config", 0, 2, 5, "bool", 3, None, None, "The VDD_SPI power supply voltage at reset", - {0: "Connect to 1.8V LDO", - 1: "Connect to VDD_RTC_IO"}), - ("VDD_SPI_FORCE", "VDD_SPI config", 0, 2, 6, "bool", 3, None, None, "Force using VDD_SPI_XPD and VDD_SPI_TIEH " - "to configure VDD_SPI LDO", None), - ("WDT_DELAY_SEL", "WDT config", 0, 2, 16, "uint:2", 3, None, None, "Selects RTC WDT timeout threshold at startup", None), - ("SPI_BOOT_CRYPT_CNT", "security", 0, 2, 18, "uint:3", 4, None, "bitcount", "Enables encryption and decryption, when an SPI boot " - "mode is set. Enabled when 1 or 3 bits are set," - "disabled otherwise", - {0: "Disable", - 1: "Enable", - 3: "Disable", - 7: "Enable"}), - ("SECURE_BOOT_KEY_REVOKE0", "security", 0, 2, 21, "bool", 5, None, None, "Revokes use of secure boot key digest 0", None), - ("SECURE_BOOT_KEY_REVOKE1", "security", 0, 2, 22, "bool", 6, None, None, "Revokes use of secure boot key digest 1", None), - ("SECURE_BOOT_KEY_REVOKE2", "security", 0, 2, 23, "bool", 7, None, None, "Revokes use of secure boot key digest 2", None), - ("KEY_PURPOSE_0", "security", 0, 2, 24, "uint:4", 8, None, "keypurpose", "KEY0 purpose", None), - ("KEY_PURPOSE_1", "security", 0, 2, 28, "uint:4", 9, None, "keypurpose", "KEY1 purpose", None), - ("KEY_PURPOSE_2", "security", 0, 3, 0, "uint:4", 10, None, "keypurpose", "KEY2 purpose", None), - ("KEY_PURPOSE_3", "security", 0, 3, 4, "uint:4", 11, None, "keypurpose", "KEY3 purpose", None), - ("KEY_PURPOSE_4", "security", 0, 3, 8, "uint:4", 12, None, "keypurpose", "KEY4 purpose", None), - ("KEY_PURPOSE_5", "security", 0, 3, 12, "uint:4", 13, None, "keypurpose", "KEY5 purpose", None), - ("SECURE_BOOT_EN", "security", 0, 3, 20, "bool", 15, None, None, "Enables secure boot", None), - ("SECURE_BOOT_AGGRESSIVE_REVOKE", "security", 0, 3, 21, "bool", 16, None, None, "Enables aggressive secure boot key revocation mode", - None), - ("DIS_USB_JTAG", "usb config", 0, 3, 22, "bool", 2, None, None, "Disable usb_serial_jtag-to-jtag function", None), - ("DIS_USB_SERIAL_JTAG", "usb config", 0, 3, 23, "bool", 2, None, None, "Disable usb_serial_jtag module", None), - ("STRAP_JTAG_SEL", "security", 0, 3, 24, "bool", 2, None, None, "Enable selection between usb_to_jtag" - "or pad_to_jtag through GPIO3", None), - ("USB_PHY_SEL", "usb config", 0, 3, 25, "bool", 2, None, None, "Select internal/external PHY for USB OTG" - "and usb_serial_jtag", None), - ("FLASH_TPUW", "config", 0, 3, 28, "uint:4", 18, None, None, "Configures flash startup delay after SoC power-up, " - "unit is (ms/2). When the value is 15, delay is 7.5 ms", - None), - ("DIS_DOWNLOAD_MODE", "security", 0, 4, 0, "bool", 18, None, None, "Disables all Download boot modes", None), - ("DIS_DIRECT_BOOT", "config", 0, 4, 1, "bool", 18, None, None, "Disables direct boot mode", None), - ("DIS_USB_SERIAL_JTAG_ROM_PRINT", "config", 0, 4, 2, "bool", 18, None, None, "Disables USB-Serial-JTAG ROM printing", None), - ("FLASH_ECC_MODE", "config", 0, 4, 3, "bool", 18, None, None, "Configures the ECC mode for SPI flash", - {0: "16-byte to 18-byte mode", - 1: "16-byte to 17-byte mode"}), - ("DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE", "config", 0, 4, 4, "bool", 18, None, None, "Disables USB-Serial-JTAG download feature in " - "UART download boot mode", None), - ("ENABLE_SECURITY_DOWNLOAD", "security", 0, 4, 5, "bool", 18, None, None, "Enables secure UART download mode " - "(read/write flash only)", None), - ("UART_PRINT_CONTROL", "config", 0, 4, 6, "uint:2", 18, None, None, "Sets the default UART boot message output mode", - {0: "Enabled", - 1: "Enable when GPIO 46 is low at reset", - 2: "Enable when GPIO 46 is high at rest", - 3: "Disabled"}), - ("PIN_POWER_SELECTION", "VDD_SPI config", 0, 4, 8, "bool", 18, None, None, "Sets default power supply for GPIO33..37", - {0: "VDD3P3_CPU", - 1: "VDD_SPI"}), - ("FLASH_TYPE", "config", 0, 4, 9, "bool", 18, None, None, "Selects SPI flash type", - {0: "4 data lines", - 1: "8 data lines"}), - ("FLASH_PAGE_SIZE", "config", 0, 4, 10, "uint:2", 18, None, None, "Sets the size of flash page", None), - ("FLASH_ECC_EN", "config", 0, 4, 12, "bool", 18, None, None, "Enables ECC in Flash boot mode", None), - ("FORCE_SEND_RESUME", "config", 0, 4, 13, "bool", 18, None, None, "Forces ROM code to send an SPI flash resume command " - "during SPI boot", None), - ("SECURE_VERSION", "identity", 0, 4, 14, "uint:16", 18, None, "bitcount", "Secure version (used by ESP-IDF anti-rollback feature)", - None), - ("DIS_USB_OTG_DOWNLOAD_MODE", "config", 0, 4, 31, "bool", 19, None, None, "Disables USB-OTG download feature in " - "UART download boot mode", None), - ("DISABLE_WAFER_VERSION_MAJOR", "config", 0, 5, 0, "bool", 19, None, None, "Disables check of wafer version major", None), - ("DISABLE_BLK_VERSION_MAJOR", "config", 0, 5, 1, "bool", 19, None, None, "Disables check of blk version major", None), - # - # Table 53: Parameters in BLOCK1-10 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("MAC", "identity", 1, 0, 0, "bytes:6", 20, None, "mac", "Factory MAC Address", None), - ("SPI_PAD_CONFIG_CLK", "spi_pad_config", 1, 1, 16, "uint:6", 20, None, None, "SPI CLK pad", None), - ("SPI_PAD_CONFIG_Q", "spi_pad_config", 1, 1, 22, "uint:6", 20, None, None, "SPI Q (D1) pad", None), - ("SPI_PAD_CONFIG_D", "spi_pad_config", 1, 1, 28, "uint:6", 20, None, None, "SPI D (D0) pad", None), - ("SPI_PAD_CONFIG_CS", "spi_pad_config", 1, 2, 2, "uint:6", 20, None, None, "SPI CS pad", None), - ("SPI_PAD_CONFIG_HD", "spi_pad_config", 1, 2, 8, "uint:6", 20, None, None, "SPI HD (D3) pad", None), - ("SPI_PAD_CONFIG_WP", "spi_pad_config", 1, 2, 14, "uint:6", 20, None, None, "SPI WP (D2) pad", None), - ("SPI_PAD_CONFIG_DQS", "spi_pad_config", 1, 2, 20, "uint:6", 20, None, None, "SPI DQS pad", None), - ("SPI_PAD_CONFIG_D4", "spi_pad_config", 1, 2, 26, "uint:6", 20, None, None, "SPI D4 pad", None), - ("SPI_PAD_CONFIG_D5", "spi_pad_config", 1, 3, 0, "uint:6", 20, None, None, "SPI D5 pad", None), - ("SPI_PAD_CONFIG_D6", "spi_pad_config", 1, 3, 6, "uint:6", 20, None, None, "SPI D6 pad", None), - ("SPI_PAD_CONFIG_D7", "spi_pad_config", 1, 3, 12, "uint:6", 20, None, None, "SPI D7 pad", None), - - ("WAFER_VERSION_MINOR_LO", "identity", 1, 3, 18, "uint:3", 20, None, None, "WAFER_VERSION_MINOR least significant bits", None), - ("PKG_VERSION", "identity", 1, 3, 21, "uint:3", 20, None, None, "Package version", None), - ("BLK_VERSION_MINOR", "identity", 1, 3, 24, "uint:3", 20, None, None, "BLOCK version minor", None), - ("WAFER_VERSION_MINOR_HI", "identity", 1, 5, 23, "uint:1", 20, None, None, "WAFER_VERSION_MINOR most significant bits", None), - ("WAFER_VERSION_MAJOR", "identity", 1, 5, 24, "uint:2", 20, None, None, "WAFER_VERSION_MAJOR", None), - - ("OPTIONAL_UNIQUE_ID", "identity", 2, 0, 0, "bytes:16", 21, None, "keyblock", "Optional unique 128-bit ID", None), - ("BLK_VERSION_MAJOR", "identity", 2, 4, 0, "uint:2", 21, None, None, "BLOCK version major", - {0: "No calibration", - 1: "With calibration"}), - ("CUSTOM_MAC", "identity", 3, 6, 8, "bytes:6", 22, None, "mac", "Custom MAC Address", None), - ] - - KEYBLOCKS = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK_USR_DATA', "config", 3, 0, 0, "bytes:32", 22, None, None, "User data", None), - ('BLOCK_KEY0', "security", 4, 0, 0, "bytes:32", 23, 0, "keyblock", "Encryption key0 or user data", None), - ('BLOCK_KEY1', "security", 5, 0, 0, "bytes:32", 24, 1, "keyblock", "Encryption key1 or user data", None), - ('BLOCK_KEY2', "security", 6, 0, 0, "bytes:32", 25, 2, "keyblock", "Encryption key2 or user data", None), - ('BLOCK_KEY3', "security", 7, 0, 0, "bytes:32", 26, 3, "keyblock", "Encryption key3 or user data", None), - ('BLOCK_KEY4', "security", 8, 0, 0, "bytes:32", 27, 4, "keyblock", "Encryption key4 or user data", None), - ('BLOCK_KEY5', "security", 9, 0, 0, "bytes:32", 28, 5, "keyblock", "Encryption key5 or user data", None), - ('BLOCK_SYS_DATA2', "security", 10, 0, 0, "bytes:32", 29, 6, None, "System data (part 2)", None), - ] - - # if BLK_VERSION_MAJOR is 1, these efuse fields are in BLOCK2 - BLOCK2_CALIBRATION_EFUSES = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('TEMP_SENSOR_CAL', "calibration", 2, 4, 7, "uint:9", 21, None, "t_sensor", "??? Temperature calibration", None), - ('ADC1_MODE0_D2', "calibration", 2, 4, 16, "uint:8", 21, None, "adc_tp", "??? ADC1 calibration 1", None), - ('ADC1_MODE1_D2', "calibration", 2, 4, 24, "uint:8", 21, None, "adc_tp", "??? ADC1 calibration 2", None), - ('ADC1_MODE2_D2', "calibration", 2, 5, 0, "uint:8", 21, None, "adc_tp", "??? ADC1 calibration 3", None), - ('ADC1_MODE3_D2', "calibration", 2, 5, 8, "uint:8", 21, None, "adc_tp", "??? ADC1 calibration 4", None), - ('ADC2_MODE0_D2', "calibration", 2, 5, 16, "uint:8", 21, None, "adc_tp", "??? ADC2 calibration 5", None), - ('ADC2_MODE1_D2', "calibration", 2, 5, 24, "uint:8", 21, None, "adc_tp", "??? ADC2 calibration 6", None), - ('ADC2_MODE2_D2', "calibration", 2, 6, 0, "uint:8", 21, None, "adc_tp", "??? ADC2 calibration 7", None), - ('ADC2_MODE3_D2', "calibration", 2, 6, 8, "uint:8", 21, None, "adc_tp", "??? ADC2 calibration 8", None), - ('ADC1_MODE0_D1', "calibration", 2, 6, 16, "uint:6", 21, None, "adc_tp", "??? ADC1 calibration 9", None), - ('ADC1_MODE1_D1', "calibration", 2, 6, 22, "uint:6", 21, None, "adc_tp", "??? ADC1 calibration 10", None), - ('ADC1_MODE2_D1', "calibration", 2, 6, 28, "uint:6", 21, None, "adc_tp", "??? ADC1 calibration 11", None), - ('ADC1_MODE3_D1', "calibration", 2, 7, 2, "uint:6", 21, None, "adc_tp", "??? ADC1 calibration 12", None), - ('ADC2_MODE0_D1', "calibration", 2, 7, 8, "uint:6", 21, None, "adc_tp", "??? ADC2 calibration 13", None), - ('ADC2_MODE1_D1', "calibration", 2, 7, 14, "uint:6", 21, None, "adc_tp", "??? ADC2 calibration 14", None), - ('ADC2_MODE2_D1', "calibration", 2, 7, 20, "uint:6", 21, None, "adc_tp", "??? ADC2 calibration 15", None), - ('ADC2_MODE3_D1', "calibration", 2, 7, 26, "uint:6", 21, None, "adc_tp", "??? ADC2 calibration 16", None), - ] - - CALC = [ - ("WAFER_VERSION_MINOR", "identity", 0, None, None, "uint:4", None, None, "wafer", "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)", None), - ] -# fmt: on + def __init__(self) -> None: + # List of efuse fields from TRM the chapter eFuse Controller. + self.EFUSES = [] + + self.KEYBLOCKS = [] + + # if BLK_VERSION_MAJOR 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 = "WAFER_VERSION_MINOR" + f.block = 0 + f.bit_len = 4 + f.type = f"uint:{f.bit_len}" + f.category = "identity" + f.class_type = "wafer" + f.description = "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)" + self.CALC.append(f) + + for efuse in self.ALL_EFUSES: + if efuse is not None: + self.EFUSES.append(efuse) + + self.ALL_EFUSES = [] diff --git a/espefuse/efuse/esp32s3/operations.py b/espefuse/efuse/esp32s3/operations.py index 56be216c1..9331374da 100644 --- a/espefuse/efuse/esp32s3/operations.py +++ b/espefuse/efuse/esp32s3/operations.py @@ -18,6 +18,7 @@ from ..base_operations import ( add_common_commands, add_force_write_always, + add_show_sensitive_info_option, burn_bit, burn_block_data, burn_efuse, @@ -57,6 +58,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -107,6 +109,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -384,7 +387,13 @@ def burn_key(esp, efuses, args, digest=None): if efuses[block.key_purpose_name].need_reverse(keypurpose): revers_msg = "\tReversing byte order for AES-XTS hardware peripheral" data = data[::-1] - print("-> [%s]" % (util.hexify(data, " "))) + 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: diff --git a/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py b/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py index 48f9305a4..0d81c0832 100644 --- a/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py @@ -16,13 +16,13 @@ class EmulateEfuseController(EmulateEfuseControllerBase): CHIP_NAME = "ESP32-S3(beta2)" mem = None debug = False - Blocks = EfuseDefineBlocks - Fields = EfuseDefineFields - REGS = EfuseDefineRegisters 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_STATUS_REG, 1) + self.write_reg(self.REGS.EFUSE_CMD_REG, 0) """ esptool method start >>""" @@ -53,10 +53,10 @@ def handle_writing_event(self, addr, value): 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 --git a/espefuse/efuse/esp32s3beta2/fields.py b/espefuse/efuse/esp32s3beta2/fields.py index 952e72927..26abb9f1f 100644 --- a/espefuse/efuse/esp32s3beta2/fields.py +++ b/espefuse/efuse/esp32s3beta2/fields.py @@ -54,16 +54,15 @@ class EspEfuses(base_fields.EspEfusesBase): Wrapper object to manage the efuse fields in a connected ESP bootloader """ - Blocks = EfuseDefineBlocks() - Fields = EfuseDefineFields() - REGS = EfuseDefineRegisters - BURN_BLOCK_DATA_NAMES = Blocks.get_burn_block_data_names() - BLOCKS_FOR_KEYS = Blocks.get_blocks_for_keys() - 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 @@ -85,59 +84,43 @@ def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): ] if not skip_connect: self.get_coding_scheme_warnings() - self.efuses = [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.EFUSES - ] + self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.KEYBLOCKS + EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS ] if skip_connect: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] else: if self["BLK_VERSION_MAJOR"].get() == 1: self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + EfuseField.convert(self, efuse) for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES ] self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) - for efuse in self.Fields.CALC + 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: + 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: - e = self.Fields.get(efuse) - if e.name == efuse_name: + if efuse.name == efuse_name or any( + x == efuse_name for x in efuse.alt_names + ): self.efuses += [ - EfuseField.from_tuple( - self, self.Fields.get(efuse), self.Fields.get(efuse).class_type - ) + 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: + if efuse_name == e.name or any(x == efuse_name for x in e.alt_names): return e raise KeyError @@ -158,10 +141,6 @@ def print_status_regs(self): ) ) - def get_block_errors(self, block_num): - """Returns (error count, failure boolean flag)""" - return self.blocks[block_num].num_errors, self.blocks[block_num].fail - def efuse_controller_setup(self): self.set_efuse_timing() self.clear_pgm_registers() @@ -181,9 +160,13 @@ def clear_pgm_registers(self): 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" ) @@ -249,6 +232,13 @@ def set_efuse_timing(self): "The eFuse supports only xtal=40M (xtal was %d)" % apb_freq ) + self.update_reg(self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_NUM_M, 0xFF) + self.update_reg( + self.REGS.EFUSE_DAC_CONF_REG, self.REGS.EFUSE_DAC_CLK_DIV_M, 0x28 + ) + self.update_reg( + self.REGS.EFUSE_WR_TIM_CONF1_REG, self.REGS.EFUSE_PWR_ON_NUM_M, 0x3000 + ) self.update_reg( self.REGS.EFUSE_WR_TIM_CONF2_REG, self.REGS.EFUSE_PWR_OFF_NUM_M, 0x190 ) @@ -264,12 +254,9 @@ def get_coding_scheme_warnings(self, silent=False): self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR0_REG + offs * 4) for offs in range(5) ] - data = BitArray() + block.err_bitarray.pos = 0 for word in reversed(words): - data.append("uint:32=%d" % word) - # pos=32 because EFUSE_WR_DIS goes first it is 32bit long - # and not under error control - block.err_bitarray.overwrite(data, pos=32) + block.err_bitarray.overwrite(BitArray("uint:32=%d" % word)) block.num_errors = block.err_bitarray.count(True) block.fail = block.num_errors != 0 else: @@ -296,9 +283,10 @@ def get_coding_scheme_warnings(self, silent=False): def summary(self): if self["VDD_SPI_FORCE"].get() == 0: output = "Flash voltage (VDD_SPI) determined by GPIO45 on reset " - "(GPIO45=High: VDD_SPI pin is powered from internal 1.8V LDO\n" + output += "(GPIO45=High: VDD_SPI pin is powered from internal 1.8V LDO\n" output += "GPIO45=Low or NC: VDD_SPI pin is powered directly from " - "VDD3P3_RTC_IO via resistor Rspi. Typically this voltage is 3.3 V)." + output += "VDD3P3_RTC_IO via resistor Rspi. " + output += "Typically this voltage is 3.3 V)." elif self["VDD_SPI_XPD"].get() == 0: output = "Flash voltage (VDD_SPI) internal regulator disabled by efuse." elif self["VDD_SPI_TIEH"].get() == 0: @@ -310,35 +298,22 @@ def summary(self): class EfuseField(base_fields.EfuseFieldBase): @staticmethod - def from_tuple(parent, efuse_tuple, type_class): + def convert(parent, efuse): return { "mac": EfuseMacField, "keypurpose": EfuseKeyPurposeField, "t_sensor": EfuseTempSensor, "adc_tp": EfuseAdcPointCalibration, "wafer": EfuseWafer, - }.get(type_class, EfuseField)(parent, efuse_tuple) - - def get_info(self): - output = "%s (BLOCK%d)" % (self.name, self.block) - errs, fail = self.parent.get_block_errors(self.block) - if errs != 0 or fail: - output += ( - "[FAIL:%d]" % (fail) - if self.block == 0 - else "[ERRS:%d FAIL:%d]" % (errs, fail) - ) - if self.efuse_class == "keyblock": - name = self.parent.blocks[self.block].key_purpose_name - if name is not None: - output += "\n Purpose: %s\n " % (self.parent[name].get()) - return output + }.get(efuse.class_type, EfuseField)(parent, efuse) class EfuseWafer(EfuseField): def get(self, from_read=True): hi_bits = self.parent["WAFER_VERSION_MINOR_HI"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_HI"].bit_len == 1 lo_bits = self.parent["WAFER_VERSION_MINOR_LO"].get(from_read) + assert self.parent["WAFER_VERSION_MINOR_LO"].bit_len == 3 return (hi_bits << 3) + lo_bits def save(self, new_value): @@ -471,6 +446,14 @@ def get(self, from_read=True): 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))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"): + raise esptool.FatalError(f"{self.name} can not have {str_new_value} key due to a hardware bug (please see TRM for more details)") return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/espefuse/efuse/esp32s3beta2/mem_definition.py b/espefuse/efuse/esp32s3beta2/mem_definition.py index a551fce89..eabf76781 100644 --- a/espefuse/efuse/esp32s3beta2/mem_definition.py +++ b/espefuse/efuse/esp32s3beta2/mem_definition.py @@ -4,25 +4,32 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase +import os +import yaml + +from ..mem_definition_base import ( + EfuseBlocksBase, + EfuseFieldsBase, + EfuseRegistersBase, + Field, +) -# fmt: off -class EfuseDefineRegisters(EfuseRegistersBase): +class EfuseDefineRegisters(EfuseRegistersBase): EFUSE_ADDR_MASK = 0x00000FFF - EFUSE_MEM_SIZE = (0x01FC + 4) + EFUSE_MEM_SIZE = 0x01FC + 4 # EFUSE registers & command/conf values - DR_REG_EFUSE_BASE = 0x6001A000 - 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 + DR_REG_EFUSE_BASE = 0x6001A000 + 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 @@ -33,37 +40,49 @@ class EfuseDefineRegisters(EfuseRegistersBase): EFUSE_WR_TIM_CONF1_REG = DR_REG_EFUSE_BASE + 0x1F4 EFUSE_WR_TIM_CONF2_REG = DR_REG_EFUSE_BASE + 0x1F8 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 + 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_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 -class EfuseDefineBlocks(EfuseBlocksBase): + # 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), @@ -78,6 +97,7 @@ class EfuseDefineBlocks(EfuseBlocksBase): ("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 = [] @@ -92,157 +112,60 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - - # List of efuse fields from TRM the chapter eFuse Controller. - EFUSES = [ - # - # Table 51: Parameters in BLOCK0 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("WR_DIS", "efuse", 0, 0, 0, "uint:32", None, None, None, "Disables programming of individual eFuses", None), - ("RD_DIS", "efuse", 0, 1, 0, "uint:7", 0, None, None, "Disables software reading from BLOCK4-10", None), - ("DIS_ICACHE", "config", 0, 1, 8, "bool", 2, None, None, "Disables ICache", None), - ("DIS_DCACHE", "config", 0, 1, 9, "bool", 2, None, None, "Disables DCache", None), - ("DIS_DOWNLOAD_ICACHE", "config", 0, 1, 10, "bool", 2, None, None, "Disables Icache when SoC is in Download mode", None), - ("DIS_DOWNLOAD_DCACHE", "config", 0, 1, 11, "bool", 2, None, None, "Disables Dcache when SoC is in Download mode", None), - ("DIS_FORCE_DOWNLOAD", "config", 0, 1, 12, "bool", 2, None, None, "Disables forcing chip into Download mode", None), - ("DIS_USB", "usb config", 0, 1, 13, "bool", 2, None, None, "Disables the USB OTG hardware", None), - ("DIS_CAN", "config", 0, 1, 14, "bool", 2, None, None, "Disables the TWAI Controller hardware", None), - ("DIS_APP_CPU", "config", 0, 1, 15, "bool", 2, None, None, "Disables APP CPU", None), - ("SOFT_DIS_JTAG", "security", 0, 1, 16, "uint:3", 31, None, None, "Software disables JTAG by programming " - "odd number of 1 bit(s). " - "JTAG can be re-enabled via HMAC peripheral", - None), - ("HARD_DIS_JTAG", "security", 0, 1, 19, "bool", 2, None, None, "Hardware disables JTAG permanently", None), - - ("DIS_DOWNLOAD_MANUAL_ENCRYPT", "security", 0, 1, 20, "bool", 2, None, None, "Disables flash encryption when in download boot modes", - None), - ("USB_EXCHG_PINS", "usb config", 0, 1, 25, "bool", 30, None, None, "Exchanges USB D+ and D- pins", None), - ("EXT_PHY_ENABLE", "usb config", 0, 1, 26, "bool", 30, None, None, "Enables external USB PHY", None), - ("BTLC_GPIO_ENABLE", "usb config", 0, 1, 27, "uint:2", 30, None, None, "Enables BTLC GPIO", None), - ("VDD_SPI_XPD", "VDD_SPI config", 0, 2, 4, "bool", 3, None, None, "The VDD_SPI regulator is powered on", None), - ("VDD_SPI_TIEH", "VDD_SPI config", 0, 2, 5, "bool", 3, None, None, "The VDD_SPI power supply voltage at reset", - {0: "Connect to 1.8V LDO", - 1: "Connect to VDD_RTC_IO"}), - ("VDD_SPI_FORCE", "VDD_SPI config", 0, 2, 6, "bool", 3, None, None, "Force using VDD_SPI_XPD and VDD_SPI_TIEH " - "to configure VDD_SPI LDO", None), - ("WDT_DELAY_SEL", "WDT config", 0, 2, 16, "uint:2", 3, None, None, "Selects RTC WDT timeout threshold at startup", None), - ("SPI_BOOT_CRYPT_CNT", "security", 0, 2, 18, "uint:3", 4, None, "bitcount", "Enables encryption and decryption, when an SPI boot " - "mode is set. Enabled when 1 or 3 bits are set," - "disabled otherwise", - {0: "Disable", - 1: "Enable", - 3: "Disable", - 7: "Enable"}), - ("SECURE_BOOT_KEY_REVOKE0", "security", 0, 2, 21, "bool", 5, None, None, "Revokes use of secure boot key digest 0", None), - ("SECURE_BOOT_KEY_REVOKE1", "security", 0, 2, 22, "bool", 6, None, None, "Revokes use of secure boot key digest 1", None), - ("SECURE_BOOT_KEY_REVOKE2", "security", 0, 2, 23, "bool", 7, None, None, "Revokes use of secure boot key digest 2", None), - ("KEY_PURPOSE_0", "security", 0, 2, 24, "uint:4", 8, None, "keypurpose", "KEY0 purpose", None), - ("KEY_PURPOSE_1", "security", 0, 2, 28, "uint:4", 9, None, "keypurpose", "KEY1 purpose", None), - ("KEY_PURPOSE_2", "security", 0, 3, 0, "uint:4", 10, None, "keypurpose", "KEY2 purpose", None), - ("KEY_PURPOSE_3", "security", 0, 3, 4, "uint:4", 11, None, "keypurpose", "KEY3 purpose", None), - ("KEY_PURPOSE_4", "security", 0, 3, 8, "uint:4", 12, None, "keypurpose", "KEY4 purpose", None), - ("KEY_PURPOSE_5", "security", 0, 3, 12, "uint:4", 13, None, "keypurpose", "KEY5 purpose", None), - ("SECURE_BOOT_EN", "security", 0, 3, 20, "bool", 15, None, None, "Enables secure boot", None), - ("SECURE_BOOT_AGGRESSIVE_REVOKE", "security", 0, 3, 21, "bool", 16, None, None, "Enables aggressive secure boot key revocation mode", - None), - ("FLASH_TPUW", "config", 0, 3, 28, "uint:4", 18, None, None, "Configures flash startup delay after SoC power-up, " - "unit is (ms/2). When the value is 15, delay is 7.5 ms", - None), - ("DIS_DOWNLOAD_MODE", "security", 0, 4, 0, "bool", 18, None, None, "Disables all Download boot modes", None), - ("DIS_DIRECT_BOOT", "config", 0, 4, 1, "bool", 18, None, None, "Disables direct boot mode", None), - ("DIS_USB_SERIAL_JTAG_ROM_PRINT", "config", 0, 4, 2, "bool", 18, None, None, "Disables USB-Serial-JTAG ROM printing", None), - ("FLASH_ECC_MODE", "config", 0, 4, 3, "bool", 18, None, None, "Configures the ECC mode for SPI flash", - {0: "16-byte to 18-byte mode", - 1: "16-byte to 17-byte mode"}), - ("DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE", "config", 0, 4, 4, "bool", 18, None, None, "Disables USB-Serial-JTAG download feature in " - "UART download boot mode", None), - ("ENABLE_SECURITY_DOWNLOAD", "security", 0, 4, 5, "bool", 18, None, None, "Enables secure UART download mode " - "(read/write flash only)", None), - ("UART_PRINT_CONTROL", "config", 0, 4, 6, "uint:2", 18, None, None, "Sets the default UART boot message output mode", - {0: "Enabled", - 1: "Enable when GPIO 46 is low at reset", - 2: "Enable when GPIO 46 is high at rest", - 3: "Disabled"}), - ("PIN_POWER_SELECTION", "VDD_SPI config", 0, 4, 8, "bool", 18, None, None, "Sets default power supply for GPIO33..37", - {0: "VDD3P3_CPU", - 1: "VDD_SPI"}), - ("FLASH_TYPE", "config", 0, 4, 9, "bool", 18, None, None, "Selects SPI flash type", - {0: "4 data lines", - 1: "8 data lines"}), - ("FLASH_PAGE_SIZE", "config", 0, 4, 10, "uint:2", 18, None, None, "Sets the size of flash page", None), - ("FLASH_ECC_EN", "config", 0, 4, 12, "bool", 18, None, None, "Enables ECC in Flash boot mode", None), - ("FORCE_SEND_RESUME", "config", 0, 4, 13, "bool", 18, None, None, "Forces ROM code to send an SPI flash resume command " - "during SPI boot", None), - ("SECURE_VERSION", "identity", 0, 4, 14, "uint:16", 18, None, "bitcount", "Secure version (used by ESP-IDF anti-rollback feature)", - None), - ("DIS_USB_OTG_DOWNLOAD_MODE", "config", 0, 4, 31, "bool", 19, None, None, "Disables USB-OTG download feature in " - "UART download boot mode", None), - ("DISABLE_WAFER_VERSION_MAJOR", "config", 0, 5, 0, "bool", 19, None, None, "Disables check of wafer version major", None), - ("DISABLE_BLK_VERSION_MAJOR", "config", 0, 5, 1, "bool", 19, None, None, "Disables check of blk version major", None), - # - # Table 53: Parameters in BLOCK1-10 - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ("MAC", "identity", 1, 0, 0, "bytes:6", 20, None, "mac", "Factory MAC Address", None), - ("SPI_PAD_CONFIG_CLK", "spi_pad_config", 1, 1, 16, "uint:6", 20, None, None, "SPI CLK pad", None), - ("SPI_PAD_CONFIG_Q", "spi_pad_config", 1, 1, 22, "uint:6", 20, None, None, "SPI Q (D1) pad", None), - ("SPI_PAD_CONFIG_D", "spi_pad_config", 1, 1, 28, "uint:6", 20, None, None, "SPI D (D0) pad", None), - ("SPI_PAD_CONFIG_CS", "spi_pad_config", 1, 2, 2, "uint:6", 20, None, None, "SPI CS pad", None), - ("SPI_PAD_CONFIG_HD", "spi_pad_config", 1, 2, 8, "uint:6", 20, None, None, "SPI HD (D3) pad", None), - ("SPI_PAD_CONFIG_WP", "spi_pad_config", 1, 2, 14, "uint:6", 20, None, None, "SPI WP (D2) pad", None), - ("SPI_PAD_CONFIG_DQS", "spi_pad_config", 1, 2, 20, "uint:6", 20, None, None, "SPI DQS pad", None), - ("SPI_PAD_CONFIG_D4", "spi_pad_config", 1, 2, 26, "uint:6", 20, None, None, "SPI D4 pad", None), - ("SPI_PAD_CONFIG_D5", "spi_pad_config", 1, 3, 0, "uint:6", 20, None, None, "SPI D5 pad", None), - ("SPI_PAD_CONFIG_D6", "spi_pad_config", 1, 3, 6, "uint:6", 20, None, None, "SPI D6 pad", None), - ("SPI_PAD_CONFIG_D7", "spi_pad_config", 1, 3, 12, "uint:6", 20, None, None, "SPI D7 pad", None), - - ("WAFER_VERSION_MINOR_LO", "identity", 1, 3, 18, "uint:3", 20, None, None, "WAFER_VERSION_MINOR least significant bits", None), - ("PKG_VERSION", "identity", 1, 3, 21, "uint:3", 20, None, None, "Package version", None), - ("BLK_VERSION_MINOR", "identity", 1, 3, 24, "uint:3", 20, None, None, "BLOCK version minor", None), - ("WAFER_VERSION_MINOR_HI", "identity", 1, 5, 23, "uint:1", 20, None, None, "WAFER_VERSION_MINOR most significant bits", None), - ("WAFER_VERSION_MAJOR", "identity", 1, 5, 24, "uint:2", 20, None, None, "WAFER_VERSION_MAJOR", None), - - ("OPTIONAL_UNIQUE_ID", "identity", 2, 0, 0, "bytes:16", 21, None, "keyblock", "Optional unique 128-bit ID", None), - ("BLK_VERSION_MAJOR", "identity", 2, 4, 0, "uint:2", 21, None, None, "BLOCK version major", - {0: "No calibration", - 1: "With calibration"}), - ("CUSTOM_MAC", "identity", 3, 6, 8, "bytes:6", 22, None, "mac", "Custom MAC Address", None), - ] - - KEYBLOCKS = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('BLOCK_USR_DATA', "config", 3, 0, 0, "bytes:32", 22, None, None, "User data", None), - ('BLOCK_KEY0', "security", 4, 0, 0, "bytes:32", 23, 0, "keyblock", "Encryption key0 or user data", None), - ('BLOCK_KEY1', "security", 5, 0, 0, "bytes:32", 24, 1, "keyblock", "Encryption key1 or user data", None), - ('BLOCK_KEY2', "security", 6, 0, 0, "bytes:32", 25, 2, "keyblock", "Encryption key2 or user data", None), - ('BLOCK_KEY3', "security", 7, 0, 0, "bytes:32", 26, 3, "keyblock", "Encryption key3 or user data", None), - ('BLOCK_KEY4', "security", 8, 0, 0, "bytes:32", 27, 4, "keyblock", "Encryption key4 or user data", None), - ('BLOCK_KEY5', "security", 9, 0, 0, "bytes:32", 28, 5, "keyblock", "Encryption key5 or user data", None), - ('BLOCK_SYS_DATA2', "security", 10, 0, 0, "bytes:32", 29, 6, None, "System data (part 2)", None), - ] - - # if BLK_VERSION_MAJOR is 1, these efuse fields are in BLOCK2 - BLOCK2_CALIBRATION_EFUSES = [ - # Name Category Block Word Pos Type:len WR_DIS RD_DIS Class Description Dictionary - ('TEMP_SENSOR_CAL', "calibration", 2, 4, 7, "uint:9", 21, None, "t_sensor", "??? Temperature calibration", None), - ('ADC1_MODE0_D2', "calibration", 2, 4, 16, "uint:8", 21, None, "adc_tp", "??? ADC1 calibration 1", None), - ('ADC1_MODE1_D2', "calibration", 2, 4, 24, "uint:8", 21, None, "adc_tp", "??? ADC1 calibration 2", None), - ('ADC1_MODE2_D2', "calibration", 2, 5, 0, "uint:8", 21, None, "adc_tp", "??? ADC1 calibration 3", None), - ('ADC1_MODE3_D2', "calibration", 2, 5, 8, "uint:8", 21, None, "adc_tp", "??? ADC1 calibration 4", None), - ('ADC2_MODE0_D2', "calibration", 2, 5, 16, "uint:8", 21, None, "adc_tp", "??? ADC2 calibration 5", None), - ('ADC2_MODE1_D2', "calibration", 2, 5, 24, "uint:8", 21, None, "adc_tp", "??? ADC2 calibration 6", None), - ('ADC2_MODE2_D2', "calibration", 2, 6, 0, "uint:8", 21, None, "adc_tp", "??? ADC2 calibration 7", None), - ('ADC2_MODE3_D2', "calibration", 2, 6, 8, "uint:8", 21, None, "adc_tp", "??? ADC2 calibration 8", None), - ('ADC1_MODE0_D1', "calibration", 2, 6, 16, "uint:6", 21, None, "adc_tp", "??? ADC1 calibration 9", None), - ('ADC1_MODE1_D1', "calibration", 2, 6, 22, "uint:6", 21, None, "adc_tp", "??? ADC1 calibration 10", None), - ('ADC1_MODE2_D1', "calibration", 2, 6, 28, "uint:6", 21, None, "adc_tp", "??? ADC1 calibration 11", None), - ('ADC1_MODE3_D1', "calibration", 2, 7, 2, "uint:6", 21, None, "adc_tp", "??? ADC1 calibration 12", None), - ('ADC2_MODE0_D1', "calibration", 2, 7, 8, "uint:6", 21, None, "adc_tp", "??? ADC2 calibration 13", None), - ('ADC2_MODE1_D1', "calibration", 2, 7, 14, "uint:6", 21, None, "adc_tp", "??? ADC2 calibration 14", None), - ('ADC2_MODE2_D1', "calibration", 2, 7, 20, "uint:6", 21, None, "adc_tp", "??? ADC2 calibration 15", None), - ('ADC2_MODE3_D1', "calibration", 2, 7, 26, "uint:6", 21, None, "adc_tp", "??? ADC2 calibration 16", None), - ] - - CALC = [ - ("WAFER_VERSION_MINOR", "identity", 0, None, None, "uint:4", None, None, "wafer", "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)", None), - ] -# fmt: on + def __init__(self) -> None: + # List of efuse fields from TRM the chapter eFuse Controller. + self.EFUSES = [] + + self.KEYBLOCKS = [] + + # if BLK_VERSION_MAJOR 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) + efuse_file = efuse_file.replace("esp32s3beta2", "esp32s3") + 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 = "WAFER_VERSION_MINOR" + f.block = 0 + f.bit_len = 4 + f.type = f"uint:{f.bit_len}" + f.category = "identity" + f.class_type = "wafer" + f.description = "calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI << 3 + WAFER_VERSION_MINOR_LO (read only)" + self.CALC.append(f) + + for efuse in self.ALL_EFUSES: + if efuse is not None: + self.EFUSES.append(efuse) + + self.ALL_EFUSES = [] diff --git a/espefuse/efuse/esp32s3beta2/operations.py b/espefuse/efuse/esp32s3beta2/operations.py index e94fa9cae..e17d773e1 100644 --- a/espefuse/efuse/esp32s3beta2/operations.py +++ b/espefuse/efuse/esp32s3beta2/operations.py @@ -18,6 +18,7 @@ from ..base_operations import ( add_common_commands, add_force_write_always, + add_show_sensitive_info_option, burn_bit, burn_block_data, burn_efuse, @@ -57,6 +58,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -107,6 +109,7 @@ def add_commands(subparsers, efuses): ) 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", @@ -384,7 +387,13 @@ def burn_key(esp, efuses, args, digest=None): if efuses[block.key_purpose_name].need_reverse(keypurpose): revers_msg = "\tReversing byte order for AES-XTS hardware peripheral" data = data[::-1] - print("-> [%s]" % (util.hexify(data, " "))) + 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: diff --git a/espefuse/efuse/mem_definition_base.py b/espefuse/efuse/mem_definition_base.py index 1d1f4ebf6..21ae698b3 100644 --- a/espefuse/efuse/mem_definition_base.py +++ b/espefuse/efuse/mem_definition_base.py @@ -43,13 +43,129 @@ def get_blocks_for_keys(self): return list_of_names +class Field: + name = "" + block = 0 + word = None + pos = None + bit_len = 0 + alt_names = [] + type = "" + write_disable_bit = None + read_disable_bit = None + category = "config" + class_type = "" + description = "" + dictionary = None + + class EfuseFieldsBase(object): - NamedtupleField = namedtuple( - "Efuse", - "name category block word pos type write_disable_bit " - "read_disable_bit class_type description dictionary", - ) + def __init__(self, e_desc) -> None: + self.ALL_EFUSES = [] - @staticmethod - def get(tuple_field): - return EfuseFieldsBase.NamedtupleField._make(tuple_field) + def set_category_and_class_type(efuse, name): + def includes(name, names): + return any([word in name for word in names]) + + if name.startswith("SPI_PAD_CONFIG"): + efuse.category = "spi pad" + + elif "USB" in name: + efuse.category = "usb" + + elif "WDT" in name: + efuse.category = "wdt" + + elif "JTAG" in name: + efuse.category = "jtag" + + elif includes(name, ["FLASH", "FORCE_SEND_RESUME"]): + efuse.category = "flash" + + elif includes(name, ["VDD_SPI_", "XPD"]): + efuse.category = "vdd" + + elif "MAC" in name: + efuse.category = "MAC" + if name in ["MAC", "CUSTOM_MAC", "MAC_EXT"]: + efuse.class_type = "mac" + + elif includes( + name, + [ + "BLOCK_KEY0", + "BLOCK_KEY1", + "BLOCK_KEY2", + "BLOCK_KEY3", + "BLOCK_KEY4", + "BLOCK_KEY5", + "BLOCK1", + "BLOCK2", + ], + ): + efuse.category = "security" + efuse.class_type = "keyblock" + + elif includes( + name, + [ + "KEY", + "SECURE", + "DOWNLOAD", + "SPI_BOOT_CRYPT_CNT", + "KEY_PURPOSE", + "SECURE_VERSION", + "DPA", + "ECDSA", + "FLASH_CRYPT_CNT", + "ENCRYPT", + "DECRYPT", + "ABS_DONE", + ], + ): + efuse.category = "security" + if name.startswith("KEY_PURPOSE"): + efuse.class_type = "keypurpose" + elif includes( + name, ["FLASH_CRYPT_CNT", "SPI_BOOT_CRYPT_CNT", "SECURE_VERSION"] + ): + efuse.class_type = "bitcount" + + elif includes(name, ["VERSION", "WAFER", "_ID", "PKG", "PACKAGE", "REV"]): + efuse.category = "identity" + if name == "OPTIONAL_UNIQUE_ID": + efuse.class_type = "keyblock" + + elif includes(name, ["ADC", "LDO", "DBIAS", "_HVT", "CALIB", "OCODE"]): + efuse.category = "calibration" + if name == "ADC_VREF": + efuse.class_type = "vref" + return + if includes(name, ["ADC", "LDO", "DBIAS", "_HVT"]): + efuse.class_type = "adc_tp" + elif name == "TEMP_CALIB": + efuse.class_type = "t_sensor" + + for e_name in e_desc["EFUSES"]: + data_dict = e_desc["EFUSES"][e_name] + if data_dict["show"] == "y": + d = Field() + d.name = e_name + d.block = data_dict["blk"] + d.word = data_dict["word"] + d.pos = data_dict["pos"] + d.bit_len = data_dict["len"] + d.type = data_dict["type"] + d.write_disable_bit = data_dict["wr_dis"] + d.read_disable_bit = ( + [int(x) for x in data_dict["rd_dis"].split(" ")] + if isinstance(data_dict["rd_dis"], str) + else data_dict["rd_dis"] + ) + d.description = data_dict["desc"] + d.alt_names = data_dict["alt"].split(" ") if data_dict["alt"] else [] + d.dictionary = ( + eval(data_dict["dict"]) if data_dict["dict"] != "" else None + ) + set_category_and_class_type(d, e_name) + self.ALL_EFUSES.append(d) diff --git a/espefuse/efuse_defs/esp32.yaml b/espefuse/efuse_defs/esp32.yaml new file mode 100644 index 000000000..cfae99038 --- /dev/null +++ b/espefuse/efuse_defs/esp32.yaml @@ -0,0 +1,64 @@ +VER_NO: 369d2d860d34e777c0f7d545a7dfc3c4 +EFUSES: + WR_DIS : {show: y, blk : 0, word: 0, pos : 0, len : 16, start : 0, type : 'uint:16', wr_dis : 1, rd_dis: null, alt : '', dict : '', desc: Efuse write disable mask, rloc: 'EFUSE_BLK0_RDATA0_REG[15:0]', bloc: 'B0,B1'} + RD_DIS : {show: y, blk : 0, word: 0, pos: 16, len : 4, start : 16, type : 'uint:4', wr_dis : 0, rd_dis: null, alt : '', dict : '', desc: Disable reading from BlOCK1-3, rloc: 'EFUSE_BLK0_RDATA0_REG[19:16]', bloc: 'B2[3:0]'} + FLASH_CRYPT_CNT : {show: y, blk : 0, word: 0, pos: 20, len : 7, start : 20, type : 'uint:7', wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Flash encryption is enabled if this field has an odd number of bits set, rloc: 'EFUSE_BLK0_RDATA0_REG[26:20]', bloc: 'B2[7:4],B3[2:0]'} + UART_DOWNLOAD_DIS : {show: y, blk : 0, word: 0, pos: 27, len : 1, start : 27, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Disable UART download mode. Valid for ESP32 V3 and newer; only, rloc: 'EFUSE_BLK0_RDATA0_REG[27]', bloc: 'B3[3]'} + RESERVED_0_28 : {show: n, blk : 0, word: 0, pos: 28, len : 4, start : 28, type : 'uint:4', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_BLK0_RDATA0_REG[31:28]', bloc: 'B3[7:4]'} + MAC : {show: y, blk : 0, word: 1, pos : 0, len : 48, start : 32, type : 'bytes:6', wr_dis : 3, rd_dis: null, alt : MAC_FACTORY, dict : '', desc: MAC address, rloc: EFUSE_BLK0_RDATA1_REG, bloc: 'B4,B5,B6,B7,B8,B9'} + MAC_CRC : {show: y, blk : 0, word: 2, pos: 16, len : 8, start : 80, type : 'uint:8', wr_dis : 3, rd_dis: null, alt : MAC_FACTORY_CRC, dict : '', desc: CRC8 for MAC address, rloc: 'EFUSE_BLK0_RDATA2_REG[23:16]', bloc: B10} + RESERVE_0_88 : {show: n, blk : 0, word: 2, pos: 24, len : 8, start : 88, type : 'uint:8', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_BLK0_RDATA2_REG[31:24]', bloc: B11} + DISABLE_APP_CPU : {show: y, blk : 0, word: 3, pos : 0, len : 1, start : 96, type : bool, wr_dis : 3, rd_dis: null, alt : CHIP_VER_DIS_APP_CPU, dict : '', desc: Disables APP CPU, rloc: 'EFUSE_BLK0_RDATA3_REG[0]', bloc: 'B12[0]'} + DISABLE_BT : {show: y, blk : 0, word: 3, pos : 1, len : 1, start : 97, type : bool, wr_dis : 3, rd_dis: null, alt : CHIP_VER_DIS_BT, dict : '', desc: Disables Bluetooth, rloc: 'EFUSE_BLK0_RDATA3_REG[1]', bloc: 'B12[1]'} + CHIP_PACKAGE_4BIT : {show: y, blk : 0, word: 3, pos : 2, len : 1, start : 98, type : bool, wr_dis: null, rd_dis: null, alt : CHIP_VER_PKG_4BIT, dict : '', desc: 'Chip package identifier #4bit', rloc: 'EFUSE_BLK0_RDATA3_REG[2]', bloc: 'B12[2]'} + DIS_CACHE : {show: y, blk : 0, word: 3, pos : 3, len : 1, start : 99, type : bool, wr_dis : 3, rd_dis: null, alt : CHIP_VER_DIS_CACHE, dict : '', desc: Disables cache, rloc: 'EFUSE_BLK0_RDATA3_REG[3]', bloc: 'B12[3]'} + SPI_PAD_CONFIG_HD : {show: y, blk : 0, word: 3, pos : 4, len : 5, start: 100, type : 'uint:5', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: read for SPI_pad_config_hd, rloc: 'EFUSE_BLK0_RDATA3_REG[8:4]', bloc: 'B12[7:4],B13[0]'} + CHIP_PACKAGE : {show: y, blk : 0, word: 3, pos : 9, len : 3, start: 105, type : 'uint:3', wr_dis: null, rd_dis: null, alt : CHIP_VER_PKG, dict : '', desc: Chip package identifier, rloc: 'EFUSE_BLK0_RDATA3_REG[11:9]', bloc: 'B13[3:1]'} + CHIP_CPU_FREQ_LOW : {show: y, blk : 0, word: 3, pos: 12, len : 1, start: 108, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: If set alongside EFUSE_RD_CHIP_CPU_FREQ_RATED; the ESP32's max CPU frequency is rated for 160MHz. 240MHz otherwise, rloc: 'EFUSE_BLK0_RDATA3_REG[12]', bloc: 'B13[4]'} + CHIP_CPU_FREQ_RATED : {show: y, blk : 0, word: 3, pos: 13, len : 1, start: 109, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: If set; the ESP32's maximum CPU frequency has been rated, rloc: 'EFUSE_BLK0_RDATA3_REG[13]', bloc: 'B13[5]'} + BLK3_PART_RESERVE : {show: y, blk : 0, word: 3, pos: 14, len : 1, start: 110, type : bool, wr_dis : 10, rd_dis : 3, alt : '', dict : '', desc: BLOCK3 partially served for ADC calibration data, rloc: 'EFUSE_BLK0_RDATA3_REG[14]', bloc: 'B13[6]'} + CHIP_VER_REV1 : {show: y, blk : 0, word: 3, pos: 15, len : 1, start: 111, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: bit is set to 1 for rev1 silicon, rloc: 'EFUSE_BLK0_RDATA3_REG[15]', bloc: 'B13[7]'} + RESERVE_0_112 : {show: n, blk : 0, word: 3, pos: 16, len : 16, start: 112, type : 'uint:16', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_BLK0_RDATA3_REG[31:16]', bloc: 'B14,B15'} + CLK8M_FREQ : {show: y, blk : 0, word: 4, pos : 0, len : 8, start: 128, type : 'uint:8', wr_dis : 4, rd_dis: null, alt : CK8M_FREQ, dict : '', desc: 8MHz clock freq override, rloc: 'EFUSE_BLK0_RDATA4_REG[7:0]', bloc: B16} + ADC_VREF : {show: y, blk : 0, word: 4, pos : 8, len : 5, start: 136, type : 'uint:5', wr_dis : 4, rd_dis: null, alt : '', dict : '', desc: True ADC reference voltage, rloc: 'EFUSE_BLK0_RDATA4_REG[12:8]', bloc: 'B17[4:0]'} + RESERVE_0_141 : {show: n, blk : 0, word: 4, pos: 13, len : 1, start: 141, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_BLK0_RDATA4_REG[13]', bloc: 'B17[5]'} + XPD_SDIO_REG : {show: y, blk : 0, word: 4, pos: 14, len : 1, start: 142, type : bool, wr_dis : 5, rd_dis: null, alt : '', dict : '', desc: read for XPD_SDIO_REG, rloc: 'EFUSE_BLK0_RDATA4_REG[14]', bloc: 'B17[6]'} + XPD_SDIO_TIEH : {show: y, blk : 0, word: 4, pos: 15, len : 1, start: 143, type : bool, wr_dis : 5, rd_dis: null, alt : SDIO_TIEH, dict: '{1: "3.3V", 0: "1.8V"}', desc: If XPD_SDIO_FORCE & XPD_SDIO_REG, rloc: 'EFUSE_BLK0_RDATA4_REG[15]', bloc: 'B17[7]'} + XPD_SDIO_FORCE : {show: y, blk : 0, word: 4, pos: 16, len : 1, start: 144, type : bool, wr_dis : 5, rd_dis: null, alt : SDIO_FORCE, dict : '', desc: Ignore MTDI pin (GPIO12) for VDD_SDIO on reset, rloc: 'EFUSE_BLK0_RDATA4_REG[16]', bloc: 'B18[0]'} + RESERVE_0_145 : {show: n, blk : 0, word: 4, pos: 17, len : 15, start: 145, type : 'uint:15', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_BLK0_RDATA4_REG[31:17]', bloc: 'B18[7:1],B19'} + SPI_PAD_CONFIG_CLK : {show: y, blk : 0, word: 5, pos : 0, len : 5, start: 160, type : 'uint:5', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: Override SD_CLK pad (GPIO6/SPICLK), rloc: 'EFUSE_BLK0_RDATA5_REG[4:0]', bloc: 'B20[4:0]'} + SPI_PAD_CONFIG_Q : {show: y, blk : 0, word: 5, pos : 5, len : 5, start: 165, type : 'uint:5', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: Override SD_DATA_0 pad (GPIO7/SPIQ), rloc: 'EFUSE_BLK0_RDATA5_REG[9:5]', bloc: 'B20[7:5],B21[1:0]'} + SPI_PAD_CONFIG_D : {show: y, blk : 0, word: 5, pos: 10, len : 5, start: 170, type : 'uint:5', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: Override SD_DATA_1 pad (GPIO8/SPID), rloc: 'EFUSE_BLK0_RDATA5_REG[14:10]', bloc: 'B21[6:2]'} + SPI_PAD_CONFIG_CS0 : {show: y, blk : 0, word: 5, pos: 15, len : 5, start: 175, type : 'uint:5', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: Override SD_CMD pad (GPIO11/SPICS0), rloc: 'EFUSE_BLK0_RDATA5_REG[19:15]', bloc: 'B21[7],B22[3:0]'} + CHIP_VER_REV2 : {show: y, blk : 0, word: 5, pos: 20, len : 1, start: 180, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_BLK0_RDATA5_REG[20]', bloc: 'B22[4]'} + RESERVE_0_181 : {show: n, blk : 0, word: 5, pos: 21, len : 1, start: 181, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_BLK0_RDATA5_REG[21]', bloc: 'B22[5]'} + VOL_LEVEL_HP_INV : {show: y, blk : 0, word: 5, pos: 22, len : 2, start: 182, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: 'This field stores the voltage level for CPU to run at 240 MHz; or for flash/PSRAM to run at 80 MHz.0x0: level 7; 0x1: level 6; 0x2: level 5; 0x3: level 4. (RO)', rloc: 'EFUSE_BLK0_RDATA5_REG[23:22]', bloc: 'B22[7:6]'} + WAFER_VERSION_MINOR : {show: y, blk : 0, word: 5, pos: 24, len : 2, start: 184, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_BLK0_RDATA5_REG[25:24]', bloc: 'B23[1:0]'} + RESERVE_0_186 : {show: n, blk : 0, word: 5, pos: 26, len : 2, start: 186, 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_BLK0_RDATA5_REG[27:26]', bloc: 'B23[3:2]'} + FLASH_CRYPT_CONFIG : {show: y, blk : 0, word: 5, pos: 28, len : 4, start: 188, type : 'uint:4', wr_dis : 10, rd_dis : 3, alt : ENCRYPT_CONFIG, dict : '', desc: Flash encryption config (key tweak bits), rloc: 'EFUSE_BLK0_RDATA5_REG[31:28]', bloc: 'B23[7:4]'} + CODING_SCHEME : {show: y, blk : 0, word: 6, pos : 0, len : 2, start: 192, type : 'uint:2', wr_dis : 10, rd_dis : 3, alt : '', dict: '{0: "NONE (BLK1-3 len=256 bits)", 1: "3/4 (BLK1-3 len=192 bits)", 2: "REPEAT (BLK1-3 len=128 bits) not supported", 3: "NONE (BLK1-3 len=256 bits)"}', desc: Efuse variable block length scheme, rloc: 'EFUSE_BLK0_RDATA6_REG[1:0]', bloc: 'B24[1:0]'} + CONSOLE_DEBUG_DISABLE: {show: y, blk : 0, word: 6, pos : 2, len : 1, start: 194, type : bool, wr_dis : 15, rd_dis: null, alt : '', dict : '', desc: Disable ROM BASIC interpreter fallback, rloc: 'EFUSE_BLK0_RDATA6_REG[2]', bloc: 'B24[2]'} + DISABLE_SDIO_HOST : {show: y, blk : 0, word: 6, pos : 3, len : 1, start: 195, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_BLK0_RDATA6_REG[3]', bloc: 'B24[3]'} + ABS_DONE_0 : {show: y, blk : 0, word: 6, pos : 4, len : 1, start: 196, type : bool, wr_dis : 12, rd_dis: null, alt : '', dict : '', desc: Secure boot V1 is enabled for bootloader image, rloc: 'EFUSE_BLK0_RDATA6_REG[4]', bloc: 'B24[4]'} + ABS_DONE_1 : {show: y, blk : 0, word: 6, pos : 5, len : 1, start: 197, type : bool, wr_dis : 13, rd_dis: null, alt : '', dict : '', desc: Secure boot V2 is enabled for bootloader image, rloc: 'EFUSE_BLK0_RDATA6_REG[5]', bloc: 'B24[5]'} + JTAG_DISABLE : {show: y, blk : 0, word: 6, pos : 6, len : 1, start: 198, type : bool, wr_dis : 14, rd_dis: null, alt : DISABLE_JTAG, dict : '', desc: Disable JTAG, rloc: 'EFUSE_BLK0_RDATA6_REG[6]', bloc: 'B24[6]'} + DISABLE_DL_ENCRYPT : {show: y, blk : 0, word: 6, pos : 7, len : 1, start: 199, type : bool, wr_dis : 15, rd_dis: null, alt : '', dict : '', desc: Disable flash encryption in UART bootloader, rloc: 'EFUSE_BLK0_RDATA6_REG[7]', bloc: 'B24[7]'} + DISABLE_DL_DECRYPT : {show: y, blk : 0, word: 6, pos : 8, len : 1, start: 200, type : bool, wr_dis : 15, rd_dis: null, alt : '', dict : '', desc: Disable flash decryption in UART bootloader, rloc: 'EFUSE_BLK0_RDATA6_REG[8]', bloc: 'B25[0]'} + DISABLE_DL_CACHE : {show: y, blk : 0, word: 6, pos : 9, len : 1, start: 201, type : bool, wr_dis : 15, rd_dis: null, alt : '', dict : '', desc: Disable flash cache in UART bootloader, rloc: 'EFUSE_BLK0_RDATA6_REG[9]', bloc: 'B25[1]'} + KEY_STATUS : {show: y, blk : 0, word: 6, pos: 10, len : 1, start: 202, type : bool, wr_dis : 10, rd_dis : 3, alt : '', dict : '', desc: Usage of efuse block 3 (reserved), rloc: 'EFUSE_BLK0_RDATA6_REG[10]', bloc: 'B25[2]'} + RESERVE_0_203 : {show: n, blk : 0, word: 6, pos: 11, len : 21, start: 203, type : 'uint:21', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved; it was created by set_missed_fields_in_regs func, rloc: 'EFUSE_BLK0_RDATA6_REG[31:11]', bloc: 'B25[7:3],B26,B27'} + BLOCK1 : {show: y, blk : 1, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 7, rd_dis : 0, alt : ENCRYPT_FLASH_KEY, dict : '', desc: Flash encryption key, rloc: EFUSE_BLK1_RDATA0_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'} + BLOCK2 : {show: y, blk : 2, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 8, rd_dis : 1, alt : SECURE_BOOT_KEY, dict : '', desc: Security boot key, rloc: EFUSE_BLK2_RDATA0_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'} + CUSTOM_MAC_CRC : {show: y, blk : 3, word: 0, pos : 0, len : 8, start : 0, type : 'uint:8', wr_dis : 9, rd_dis : 2, alt : MAC_CUSTOM_CRC, dict : '', desc: CRC8 for custom MAC address, rloc: 'EFUSE_BLK3_RDATA0_REG[7:0]', bloc: B0} + CUSTOM_MAC : {show: y, blk : 3, word: 0, pos : 8, len : 48, start : 8, type : 'bytes:6', wr_dis : 9, rd_dis : 2, alt : MAC_CUSTOM, dict : '', desc: Custom MAC address, rloc: 'EFUSE_BLK3_RDATA0_REG[31:8]', bloc: 'B1,B2,B3,B4,B5,B6'} + RESERVED_3_56 : {show: n, blk : 3, word: 1, pos: 24, len : 8, start : 56, type : 'uint:8', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_BLK3_RDATA1_REG[31:24]', bloc: B7} + BLK3_RESERVED_2 : {show: n, blk : 3, word: 2, pos : 0, len : 32, start : 64, type : 'uint:32', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: read for BLOCK3, rloc: EFUSE_BLK3_RDATA2_REG, bloc: 'B8,B9,B10,B11'} + ADC1_TP_LOW : {show: y, blk : 3, word: 3, pos : 0, len : 7, start : 96, type : 'uint:7', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: ADC1 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE, rloc: 'EFUSE_BLK3_RDATA3_REG[6:0]', bloc: 'B12[6:0]'} + ADC1_TP_HIGH : {show: y, blk : 3, word: 3, pos : 7, len : 9, start: 103, type : 'uint:9', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: ADC1 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE, rloc: 'EFUSE_BLK3_RDATA3_REG[15:7]', bloc: 'B12[7],B13'} + ADC2_TP_LOW : {show: y, blk : 3, word: 3, pos: 16, len : 7, start: 112, type : 'uint:7', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: ADC2 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE, rloc: 'EFUSE_BLK3_RDATA3_REG[22:16]', bloc: 'B14[6:0]'} + ADC2_TP_HIGH : {show: y, blk : 3, word: 3, pos: 23, len : 9, start: 119, type : 'uint:9', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: ADC2 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE, rloc: 'EFUSE_BLK3_RDATA3_REG[31:23]', bloc: 'B14[7],B15'} + SECURE_VERSION : {show: y, blk : 3, word: 4, pos : 0, len : 32, start: 128, type : 'uint:32', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: Secure version for anti-rollback, rloc: EFUSE_BLK3_RDATA4_REG, bloc: 'B16,B17,B18,B19'} + RESERVED_3_160 : {show: n, blk : 3, word: 5, pos : 0, len : 24, start: 160, type : 'uint:24', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_BLK3_RDATA5_REG[23:0]', bloc: 'B20,B21,B22'} + MAC_VERSION : {show: y, blk : 3, word: 5, pos: 24, len : 8, start: 184, type : 'uint:8', wr_dis : 9, rd_dis : 2, alt : MAC_CUSTOM_VER, dict: '{1: "Custom MAC in BLOCK3"}', desc: Version of the MAC field, rloc: 'EFUSE_BLK3_RDATA5_REG[31:24]', bloc: B23} + BLK3_RESERVED_6 : {show: n, blk : 3, word: 6, pos : 0, len : 32, start: 192, type : 'uint:32', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: read for BLOCK3, rloc: EFUSE_BLK3_RDATA6_REG, bloc: 'B24,B25,B26,B27'} + BLK3_RESERVED_7 : {show: n, blk : 3, word: 7, pos : 0, len : 32, start: 224, type : 'uint:32', wr_dis : 9, rd_dis : 2, alt : '', dict : '', desc: read for BLOCK3, rloc: EFUSE_BLK3_RDATA7_REG, bloc: 'B28,B29,B30,B31'} diff --git a/espefuse/efuse_defs/esp32c2.yaml b/espefuse/efuse_defs/esp32c2.yaml new file mode 100644 index 000000000..e89e354fc --- /dev/null +++ b/espefuse/efuse_defs/esp32c2.yaml @@ -0,0 +1,53 @@ +VER_NO: 897499b0349a608b895d467abbcf006b +EFUSES: + WR_DIS : {show: y, blk : 0, word: 0, pos : 0, len : 8, start : 0, type : 'uint:8', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Disable programming of individual eFuses, rloc: 'EFUSE_RD_WR_DIS_REG[7:0]', bloc: B0} + RESERVED_0_8 : {show: n, blk : 0, word: 0, pos : 8, len : 24, start : 8, type : 'uint:24', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_WR_DIS_REG[31:8]', bloc: 'B1,B2,B3'} + RD_DIS : {show: y, blk : 0, word: 1, pos : 0, len : 2, start : 32, type : 'uint:2', wr_dis : 0, rd_dis: null, alt : '', dict : '', desc: Disable reading from BlOCK3, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[1:0]', bloc: 'B1[1:0]'} + WDT_DELAY_SEL : {show: y, blk : 0, word: 1, pos : 2, len : 2, start : 34, type : 'uint:2', wr_dis : 1, rd_dis: null, alt : '', dict: '{0: "40000", 1: "80000", 2: "160000", 3: "320000"}', desc: RTC watchdog timeout threshold; in unit of slow clock cycle, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[3:2]', bloc: 'B1[3:2]'} + DIS_PAD_JTAG : {show: y, blk : 0, word: 1, pos : 4, len : 1, start : 36, type : bool, wr_dis : 1, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable pad jtag, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[4]', bloc: 'B1[4]'} + DIS_DOWNLOAD_ICACHE : {show: y, blk : 0, word: 1, pos : 5, len : 1, start : 37, type : bool, wr_dis : 1, rd_dis: null, alt : '', dict : '', desc: The bit be set to disable icache in download mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[5]', bloc: 'B1[5]'} + DIS_DOWNLOAD_MANUAL_ENCRYPT: {show: y, blk : 0, word: 1, pos : 6, len : 1, start : 38, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: The bit be set to disable manual encryption, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[6]', bloc: 'B1[6]'} + SPI_BOOT_CRYPT_CNT : {show: y, blk : 0, word: 1, pos : 7, len : 3, start : 39, type : 'uint:3', wr_dis : 2, 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_DATA0_REG[9:7]', bloc: 'B1[7],B2[1:0]'} + XTS_KEY_LENGTH_256 : {show: y, blk : 0, word: 1, pos: 10, len : 1, start : 42, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict: '{0: "128 bits key", 1: "256 bits key"}', desc: Flash encryption key length, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[10]', bloc: 'B2[2]'} + UART_PRINT_CONTROL : {show: y, blk : 0, word: 1, pos: 11, len : 2, start : 43, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict: '{0: "Enable", 1: "Enable when GPIO8 is low at reset", 2: "Enable when GPIO8 is high at reset", 3: "Disable"}', desc: Set the default UARTboot message output mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[12:11]', bloc: 'B2[4:3]'} + FORCE_SEND_RESUME : {show: y, blk : 0, word: 1, pos: 13, len : 1, start : 45, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Set this bit to force ROM code to send a resume command during SPI boot, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[13]', bloc: 'B2[5]'} + DIS_DOWNLOAD_MODE : {show: y, blk : 0, word: 1, pos: 14, len : 1, start : 46, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: 'Set this bit to disable download mode (boot_mode[3:0] = 0; 1; 2; 4; 5; 6; 7)', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[14]', bloc: 'B2[6]'} + DIS_DIRECT_BOOT : {show: y, blk : 0, word: 1, pos: 15, len : 1, start : 47, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: This bit set means disable direct_boot mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[15]', bloc: 'B2[7]'} + ENABLE_SECURITY_DOWNLOAD : {show: y, blk : 0, word: 1, pos: 16, len : 1, start : 48, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable secure UART download mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[16]', bloc: 'B3[0]'} + FLASH_TPUW : {show: y, blk : 0, word: 1, pos: 17, len : 4, start : 49, type : 'uint:4', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Configures flash waiting time after power-up; in unit of ms. If the value is less than 15; the waiting time is the configurable value. Otherwise; the waiting time is twice the configurable value, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[20:17]', bloc: 'B3[4:1]'} + SECURE_BOOT_EN : {show: y, blk : 0, word: 1, pos: 21, len : 1, start : 53, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: The bit be set to enable secure boot, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[21]', bloc: 'B3[5]'} + SECURE_VERSION : {show: y, blk : 0, word: 1, pos: 22, len : 4, start : 54, type : 'uint:4', wr_dis : 4, rd_dis: null, alt : '', dict : '', desc: Secure version for anti-rollback, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[25:22]', bloc: 'B3[7:6],B4[1:0]'} + CUSTOM_MAC_USED : {show: y, blk : 0, word: 1, pos: 26, len : 1, start : 58, type : bool, wr_dis : 4, rd_dis: null, alt : ENABLE_CUSTOM_MAC, dict : '', desc: True if MAC_CUSTOM is burned, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[26]', bloc: 'B4[2]'} + DISABLE_WAFER_VERSION_MAJOR: {show: y, blk : 0, word: 1, pos: 27, len : 1, start : 59, type : bool, wr_dis : 4, rd_dis: null, alt : '', dict : '', desc: Disables check of wafer version major, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[27]', bloc: 'B4[3]'} + DISABLE_BLK_VERSION_MAJOR : {show: y, blk : 0, word: 1, pos: 28, len : 1, start : 60, type : bool, wr_dis : 4, rd_dis: null, alt : '', dict : '', desc: Disables check of blk version major, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[28]', bloc: 'B4[4]'} + RESERVED_0_61 : {show: n, blk : 0, word: 1, pos: 29, len : 3, start : 61, type : 'uint:3', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[31:29]', bloc: 'B4[7:5]'} + CUSTOM_MAC : {show: y, blk : 1, word: 0, pos : 0, len : 48, start : 0, type : 'bytes:6', wr_dis : 5, rd_dis: null, alt: MAC_CUSTOM USER_DATA_MAC_CUSTOM, dict : '', desc: Custom MAC address, rloc: EFUSE_RD_BLK1_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5'} + RESERVED_1_48 : {show: n, blk : 1, word: 1, pos: 16, len : 16, start : 48, type : 'uint:16', wr_dis : 5, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_BLK1_DATA1_REG[31:16]', bloc: 'B6,B7'} + SYSTEM_DATA2 : {show: n, blk : 1, word: 2, pos : 0, len : 24, start : 64, type : 'uint:24', wr_dis : 5, rd_dis: null, alt : '', dict : '', desc: 'Stores the bits [64:87] of system data', rloc: 'EFUSE_RD_BLK1_DATA2_REG[23:0]', bloc: 'B8,B9,B10'} + MAC : {show: y, blk : 2, word: 0, pos : 0, len : 48, start : 0, type : 'bytes:6', wr_dis : 6, rd_dis: null, alt : MAC_FACTORY, dict : '', desc: MAC address, rloc: EFUSE_RD_BLK2_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5'} + WAFER_VERSION_MINOR : {show: y, blk : 2, word: 1, pos: 16, len : 4, start : 48, type : 'uint:4', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MINOR, rloc: 'EFUSE_RD_BLK2_DATA1_REG[19:16]', bloc: 'B6[3:0]'} + WAFER_VERSION_MAJOR : {show: y, blk : 2, word: 1, pos: 20, len : 2, start : 52, type : 'uint:2', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MAJOR, rloc: 'EFUSE_RD_BLK2_DATA1_REG[21:20]', bloc: 'B6[5:4]'} + PKG_VERSION : {show: y, blk : 2, word: 1, pos: 22, len : 3, start : 54, type : 'uint:3', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: EFUSE_PKG_VERSION, rloc: 'EFUSE_RD_BLK2_DATA1_REG[24:22]', bloc: 'B6[7:6],B7[0]'} + BLK_VERSION_MINOR : {show: y, blk : 2, word: 1, pos: 25, len : 3, start : 57, type : 'uint:3', wr_dis : 6, rd_dis: null, alt : '', dict: '{0: "No calib", 1: "With calib"}', desc: Minor version of BLOCK2, rloc: 'EFUSE_RD_BLK2_DATA1_REG[27:25]', bloc: 'B7[3:1]'} + BLK_VERSION_MAJOR : {show: y, blk : 2, word: 1, pos: 28, len : 2, start : 60, type : 'uint:2', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: Major version of BLOCK2, rloc: 'EFUSE_RD_BLK2_DATA1_REG[29:28]', bloc: 'B7[5:4]'} + OCODE : {show: y, blk : 2, word: 1, pos: 30, len : 7, start : 62, type : 'uint:7', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: OCode, rloc: 'EFUSE_RD_BLK2_DATA1_REG[31:30]', bloc: 'B7[7:6],B8[4:0]'} + TEMP_CALIB : {show: y, blk : 2, word: 2, pos : 5, len : 9, start : 69, type : 'uint:9', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: Temperature calibration data, rloc: 'EFUSE_RD_BLK2_DATA2_REG[13:5]', bloc: 'B8[7:5],B9[5:0]'} + ADC1_INIT_CODE_ATTEN0 : {show: y, blk : 2, word: 2, pos: 14, len : 8, start : 78, type : 'uint:8', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten0, rloc: 'EFUSE_RD_BLK2_DATA2_REG[21:14]', bloc: 'B9[7:6],B10[5:0]'} + ADC1_INIT_CODE_ATTEN3 : {show: y, blk : 2, word: 2, pos: 22, len : 5, start : 86, type : 'uint:5', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten3, rloc: 'EFUSE_RD_BLK2_DATA2_REG[26:22]', bloc: 'B10[7:6],B11[2:0]'} + ADC1_CAL_VOL_ATTEN0 : {show: y, blk : 2, word: 2, pos: 27, len : 8, start : 91, type : 'uint:8', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten0, rloc: 'EFUSE_RD_BLK2_DATA2_REG[31:27]', bloc: 'B11[7:3],B12[2:0]'} + ADC1_CAL_VOL_ATTEN3 : {show: y, blk : 2, word: 3, pos : 3, len : 6, start : 99, type : 'uint:6', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten3, rloc: 'EFUSE_RD_BLK2_DATA3_REG[8:3]', bloc: 'B12[7:3],B13[0]'} + DIG_DBIAS_HVT : {show: y, blk : 2, word: 3, pos : 9, len : 5, start: 105, type : 'uint:5', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 digital dbias when hvt, rloc: 'EFUSE_RD_BLK2_DATA3_REG[13:9]', bloc: 'B13[5:1]'} + DIG_LDO_SLP_DBIAS2 : {show: y, blk : 2, word: 3, pos: 14, len : 7, start: 110, type : 'uint:7', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 DIG_LDO_DBG0_DBIAS2, rloc: 'EFUSE_RD_BLK2_DATA3_REG[20:14]', bloc: 'B13[7:6],B14[4:0]'} + DIG_LDO_SLP_DBIAS26 : {show: y, blk : 2, word: 3, pos: 21, len : 8, start: 117, type : 'uint:8', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 DIG_LDO_DBG0_DBIAS26, rloc: 'EFUSE_RD_BLK2_DATA3_REG[28:21]', bloc: 'B14[7:5],B15[4:0]'} + DIG_LDO_ACT_DBIAS26 : {show: y, blk : 2, word: 3, pos: 29, len : 6, start: 125, type : 'uint:6', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 DIG_LDO_ACT_DBIAS26, rloc: 'EFUSE_RD_BLK2_DATA3_REG[31:29]', bloc: 'B15[7:5],B16[2:0]'} + DIG_LDO_ACT_STEPD10 : {show: y, blk : 2, word: 4, pos : 3, len : 4, start: 131, type : 'uint:4', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 DIG_LDO_ACT_STEPD10, rloc: 'EFUSE_RD_BLK2_DATA4_REG[6:3]', bloc: 'B16[6:3]'} + RTC_LDO_SLP_DBIAS13 : {show: y, blk : 2, word: 4, pos : 7, len : 7, start: 135, type : 'uint:7', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 DIG_LDO_SLP_DBIAS13, rloc: 'EFUSE_RD_BLK2_DATA4_REG[13:7]', bloc: 'B16[7],B17[5:0]'} + RTC_LDO_SLP_DBIAS29 : {show: y, blk : 2, word: 4, pos: 14, len : 9, start: 142, type : 'uint:9', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 DIG_LDO_SLP_DBIAS29, rloc: 'EFUSE_RD_BLK2_DATA4_REG[22:14]', bloc: 'B17[7:6],B18[6:0]'} + RTC_LDO_SLP_DBIAS31 : {show: y, blk : 2, word: 4, pos: 23, len : 6, start: 151, type : 'uint:6', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 DIG_LDO_SLP_DBIAS31, rloc: 'EFUSE_RD_BLK2_DATA4_REG[28:23]', bloc: 'B18[7],B19[4:0]'} + RTC_LDO_ACT_DBIAS31 : {show: y, blk : 2, word: 4, pos: 29, len : 6, start: 157, type : 'uint:6', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 DIG_LDO_ACT_DBIAS31, rloc: 'EFUSE_RD_BLK2_DATA4_REG[31:29]', bloc: 'B19[7:5],B20[2:0]'} + RTC_LDO_ACT_DBIAS13 : {show: y, blk : 2, word: 5, pos : 3, len : 8, start: 163, type : 'uint:8', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: BLOCK2 DIG_LDO_ACT_DBIAS13, rloc: 'EFUSE_RD_BLK2_DATA5_REG[10:3]', bloc: 'B20[7:3],B21[2:0]'} + RESERVED_2_171 : {show: n, blk : 2, word: 5, pos: 11, len : 21, start: 171, type : 'uint:21', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_BLK2_DATA5_REG[31:11]', bloc: 'B21[7:3],B22,B23'} + ADC_CALIBRATION_3 : {show: y, blk : 2, word: 6, pos : 0, len : 11, start: 192, type : 'uint:11', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: 'Store the bit [86:96] of ADC calibration data', rloc: 'EFUSE_RD_BLK2_DATA6_REG[10:0]', bloc: 'B24,B25[2:0]'} + BLK2_RESERVED_DATA_0 : {show: n, blk : 2, word: 6, pos: 11, len : 21, start: 203, type : 'uint:21', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: 'Store the bit [0:20] of block2 reserved data', rloc: 'EFUSE_RD_BLK2_DATA6_REG[31:11]', bloc: 'B25[7:3],B26,B27'} + BLK2_RESERVED_DATA_1 : {show: n, blk : 2, word: 7, pos : 0, len : 32, start: 224, type : 'uint:32', wr_dis : 6, rd_dis: null, alt : '', dict : '', desc: 'Store the bit [21:52] of block2 reserved data', rloc: EFUSE_RD_BLK2_DATA7_REG, bloc: 'B28,B29,B30,B31'} + BLOCK_KEY0 : {show: y, blk : 3, word: 0, pos : 0, len: 256, start : 0, type: 'bytes:32', wr_dis : 7, rd_dis : 0 1, alt : KEY0, dict : '', desc: BLOCK_KEY0 - 256-bits. 256-bit key of Flash Encryption, rloc: EFUSE_RD_BLK3_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 --git a/espefuse/efuse_defs/esp32c3.yaml b/espefuse/efuse_defs/esp32c3.yaml new file mode 100644 index 000000000..035f30c5b --- /dev/null +++ b/espefuse/efuse_defs/esp32c3.yaml @@ -0,0 +1,112 @@ +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]'} + DIS_RTC_RAM_BOOT : {show: n, blk : 0, word: 1, pos : 7, len : 1, start : 39, type : bool, wr_dis : 1, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable boot from RTC RAM, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[7]', bloc: 'B4[7]'} + DIS_ICACHE : {show: y, blk : 0, word: 1, pos : 8, len : 1, start : 40, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable Icache, 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 : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable function of usb switch to jtag in module of usb device, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[9]', bloc: 'B5[1]'} + DIS_DOWNLOAD_ICACHE : {show: y, blk : 0, word: 1, pos: 10, len : 1, start : 42, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: 'Set this bit to disable Icache in download mode (boot_mode[3:0] is 0; 1; 2; 3; 6; 7)', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[10]', bloc: 'B5[2]'} + DIS_USB_SERIAL_JTAG : {show: y, blk : 0, word: 1, pos: 11, len : 1, start : 43, type : bool, wr_dis : 2, rd_dis: null, alt : DIS_USB_DEVICE, dict: '{0: "Enable", 1: "Disable"}', desc: USB-Serial-JTAG, 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 : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable the function that forces chip into download mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[12]', bloc: 'B5[4]'} + RPT4_RESERVED6 : {show: n, blk : 0, word: 1, pos: 13, len : 1, start : 45, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved (used for four backups method), 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 : 2, rd_dis: null, alt : DIS_CAN, dict : '', desc: Set this bit to disable CAN function, 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 : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping gpio10 when both reg_dis_usb_jtag and reg_dis_pad_jtag are equal to 0, 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 : 31, rd_dis: null, alt : '', dict : '', desc: Set these bits to disable JTAG in the soft way (odd number 1 means disable ). JTAG can be enabled in HMAC module, 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 : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable JTAG in the hard way. JTAG is disabled permanently, 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 : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable flash encryption when in download boot modes, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[20]', bloc: 'B6[4]'} + USB_DREFH : {show: n, blk : 0, word: 1, pos: 21, len : 2, start : 53, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Controls single-end input threshold vrefh; 1.76 V to 2 V with step of 80 mV; stored in eFuse, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[22:21]', bloc: 'B6[6:5]'} + USB_DREFL : {show: n, blk : 0, word: 1, pos: 23, len : 2, start : 55, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Controls single-end input threshold vrefl; 0.8 V to 1.04 V with step of 80 mV; stored in eFuse, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[24:23]', bloc: 'B6[7],B7[0]'} + USB_EXCHG_PINS : {show: y, blk : 0, word: 1, pos: 25, len : 1, start : 57, type : bool, wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Set this bit to exchange USB D+ and D- pins, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[25]', bloc: 'B7[1]'} + VDD_SPI_AS_GPIO : {show: y, blk : 0, word: 1, pos: 26, len : 1, start : 58, type : bool, wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Set this bit to vdd spi pin function as gpio, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[26]', bloc: 'B7[2]'} + BTLC_GPIO_ENABLE : {show: n, blk : 0, word: 1, pos: 27, len : 2, start : 59, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Enable btlc gpio, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[28:27]', bloc: 'B7[4:3]'} + POWERGLITCH_EN : {show: n, blk : 0, word: 1, pos: 29, len : 1, start : 61, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable power glitch function, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[29]', bloc: 'B7[5]'} + POWER_GLITCH_DSENSE : {show: n, blk : 0, word: 1, pos: 30, len : 2, start : 62, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Sample delay configuration of power glitch, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[31:30]', bloc: 'B7[7:6]'} + RPT4_RESERVED2 : {show: n, blk : 0, word: 2, pos : 0, len : 16, start : 64, type : 'uint:16', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved (used for four backups method), rloc: 'EFUSE_RD_REPEAT_DATA1_REG[15:0]', bloc: 'B8,B9'} + WDT_DELAY_SEL : {show: y, blk : 0, word: 2, pos: 16, len : 2, start : 80, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict: '{0: "40000", 1: "80000", 2: "160000", 3: "320000"}', desc: RTC watchdog timeout threshold; in unit of slow clock cycle, 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: 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: 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: 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: 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: 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: Purpose of Key5, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[15:12]', bloc: 'B13[7:4]'} + RPT4_RESERVED3 : {show: n, blk : 0, word: 3, pos: 16, len : 4, start: 112, type : 'uint:4', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved (used for four backups method), rloc: 'EFUSE_RD_REPEAT_DATA2_REG[19:16]', bloc: 'B14[3:0]'} + SECURE_BOOT_EN : {show: y, blk : 0, word: 3, pos: 20, len : 1, start: 116, type : bool, wr_dis : 15, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable secure boot, 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 : 16, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable revoking aggressive secure boot, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[21]', bloc: 'B14[5]'} + RPT4_RESERVED0 : {show: n, blk : 0, word: 3, pos: 22, len : 6, start: 118, type : 'uint:6', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved (used for four backups method), rloc: 'EFUSE_RD_REPEAT_DATA2_REG[27:22]', bloc: 'B14[7:6],B15[3:0]'} + FLASH_TPUW : {show: y, blk : 0, word: 3, pos: 28, len : 4, start: 124, type : 'uint:4', wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Configures flash waiting time after power-up; in unit of ms. If the value is less than 15; the waiting time is the configurable value; Otherwise; the waiting time is twice the configurable 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 : 18, rd_dis: null, alt : '', dict : '', desc: 'Set this bit to disable download mode (boot_mode[3:0] = 0; 1; 2; 3; 6; 7)', 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 : 18, rd_dis: null, alt : DIS_LEGACY_SPI_BOOT, dict : '', desc: Disable direct boot mode, 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 : 18, rd_dis: null, alt : UART_PRINT_CHANNEL, dict: '{0: "Enable", 1: "Disable"}', desc: USB printing, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[2]', bloc: 'B16[2]'} + FLASH_ECC_MODE : {show: n, blk : 0, word: 4, pos : 3, len : 1, start: 131, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict: '{0: "ROM would Enable Flash ECC 16to18 byte mode", 1: "ROM would use 16to17 byte mode"}', desc: ECC mode in ROM, 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 : 18, rd_dis: null, alt : DIS_USB_DOWNLOAD_MODE, dict : '', desc: Disable UART download mode through USB-Serial-JTAG, 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 : 18, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable secure UART download mode, 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 : 18, rd_dis: null, alt : '', dict: '{0: "Enable", 1: "Enable when GPIO8 is low at reset", 2: "Enable when GPIO8 is high at reset", 3: "Disable"}', desc: Set the default UARTboot message output mode, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[7:6]', bloc: 'B16[7:6]'} + PIN_POWER_SELECTION : {show: n, blk : 0, word: 4, pos : 8, len : 1, start: 136, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict: '{0: "VDD3P3_CPU", 1: "VDD_SPI"}', desc: GPIO33-GPIO37 power supply selection in ROM code, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[8]', bloc: 'B17[0]'} + FLASH_TYPE : {show: n, blk : 0, word: 4, pos : 9, len : 1, start: 137, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict: '{0: "4 data lines", 1: "8 data lines"}', desc: Maximum lines of SPI flash, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[9]', bloc: 'B17[1]'} + FLASH_PAGE_SIZE : {show: n, blk : 0, word: 4, pos: 10, len : 2, start: 138, type : 'uint:2', wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Set Flash page size, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[11:10]', bloc: 'B17[3:2]'} + FLASH_ECC_EN : {show: n, blk : 0, word: 4, pos: 12, len : 1, start: 140, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Set 1 to enable ECC for flash boot, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[12]', bloc: 'B17[4]'} + FORCE_SEND_RESUME : {show: y, blk : 0, word: 4, pos: 13, len : 1, start: 141, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Set this bit to force ROM code to send a resume command during SPI boot, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[13]', bloc: 'B17[5]'} + SECURE_VERSION : {show: y, blk : 0, word: 4, pos: 14, len : 16, start: 142, type : 'uint:16', wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Secure version (used by ESP-IDF anti-rollback feature), rloc: 'EFUSE_RD_REPEAT_DATA3_REG[29:14]', bloc: 'B17[7:6],B18,B19[5:0]'} + RESERVED_0_158 : {show: n, blk : 0, word: 4, pos: 30, len : 1, start: 158, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[30]', bloc: 'B19[6]'} + ERR_RST_ENABLE : {show: y, blk : 0, word: 4, pos: 31, len : 1, start: 159, type : bool, wr_dis : 19, rd_dis: null, alt : '', dict: '{0: "without check", 1: "with check"}', desc: Use BLOCK0 to check error record registers, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[31]', bloc: 'B19[7]'} + DISABLE_WAFER_VERSION_MAJOR : {show: y, blk : 0, word: 5, pos : 0, len : 1, start: 160, type : bool, wr_dis : 19, rd_dis: null, alt : '', dict : '', desc: Disables check of wafer version major, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[0]', bloc: 'B20[0]'} + DISABLE_BLK_VERSION_MAJOR : {show: y, blk : 0, word: 5, pos : 1, len : 1, start: 161, type : bool, wr_dis : 19, rd_dis: null, alt : '', dict : '', desc: Disables check of blk version major, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[1]', bloc: 'B20[1]'} + RESERVED_0_162 : {show: n, blk : 0, word: 5, pos : 2, len : 22, start: 162, type : 'uint:22', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[23:2]', bloc: 'B20[7:2],B21,B22'} + 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_SPI_SYS_0_REG, bloc: 'B0,B1,B2,B3,B4,B5'} + SPI_PAD_CONFIG_CLK : {show: y, blk : 1, word: 1, pos: 16, len : 6, start : 48, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD CLK, rloc: 'EFUSE_RD_MAC_SPI_SYS_1_REG[21:16]', bloc: 'B6[5:0]'} + SPI_PAD_CONFIG_Q : {show: y, blk : 1, word: 1, pos: 22, len : 6, start : 54, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD Q(D1), rloc: 'EFUSE_RD_MAC_SPI_SYS_1_REG[27:22]', bloc: 'B6[7:6],B7[3:0]'} + SPI_PAD_CONFIG_D : {show: y, blk : 1, word: 1, pos: 28, len : 6, start : 60, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD D(D0), rloc: 'EFUSE_RD_MAC_SPI_SYS_1_REG[31:28]', bloc: 'B7[7:4],B8[1:0]'} + SPI_PAD_CONFIG_CS : {show: y, blk : 1, word: 2, pos : 2, len : 6, start : 66, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD CS, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[7:2]', bloc: 'B8[7:2]'} + SPI_PAD_CONFIG_HD : {show: y, blk : 1, word: 2, pos : 8, len : 6, start : 72, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD HD(D3), rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[13:8]', bloc: 'B9[5:0]'} + SPI_PAD_CONFIG_WP : {show: y, blk : 1, word: 2, pos: 14, len : 6, start : 78, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD WP(D2), rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[19:14]', bloc: 'B9[7:6],B10[3:0]'} + SPI_PAD_CONFIG_DQS : {show: y, blk : 1, word: 2, pos: 20, len : 6, start : 84, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD DQS, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[25:20]', bloc: 'B10[7:4],B11[1:0]'} + SPI_PAD_CONFIG_D4 : {show: y, blk : 1, word: 2, pos: 26, len : 6, start : 90, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD D4, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[31:26]', bloc: 'B11[7:2]'} + SPI_PAD_CONFIG_D5 : {show: y, blk : 1, word: 3, pos : 0, len : 6, start : 96, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD D5, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[5:0]', bloc: 'B12[5:0]'} + SPI_PAD_CONFIG_D6 : {show: y, blk : 1, word: 3, pos : 6, len : 6, start: 102, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD D6, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[11:6]', bloc: 'B12[7:6],B13[3:0]'} + SPI_PAD_CONFIG_D7 : {show: y, blk : 1, word: 3, pos: 12, len : 6, start: 108, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI PAD D7, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[17:12]', bloc: 'B13[7:4],B14[1:0]'} + 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]'} + 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]'} + V_DIG_DBIAS20 : {show: y, blk : 1, word: 4, pos: 29, len : 8, start: 157, type : 'uint:8', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 voltage of digital dbias20, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[31:29]', bloc: 'B19[7:5],B20[4:0]'} + DIG_DBIAS_HVT : {show: y, blk : 1, word: 5, pos : 5, len : 5, start: 165, type : 'uint:5', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 digital dbias when hvt, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[9:5]', bloc: 'B20[7:5],B21[1:0]'} + THRES_HVT : {show: y, blk : 1, word: 5, pos: 10, len : 10, start: 170, type : 'uint:10', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 pvt threshold when hvt, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[19:10]', bloc: 'B21[7:2],B22[3:0]'} + RESERVED_1_180 : {show: n, blk : 1, word: 5, pos: 20, len : 3, start: 180, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[22:20]', bloc: 'B22[6:4]'} + WAFER_VERSION_MINOR_HI : {show: y, blk : 1, word: 5, pos: 23, len : 1, start: 183, type : bool, wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MINOR most significant bit, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[23]', bloc: 'B22[7]'} + WAFER_VERSION_MAJOR : {show: y, blk : 1, word: 5, pos: 24, len : 2, start: 184, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MAJOR, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[25:24]', bloc: 'B23[1:0]'} + RESERVED_1_186 : {show: n, blk : 1, word: 5, pos: 26, len : 6, start: 186, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[31:26]', bloc: 'B23[7:2]'} + OPTIONAL_UNIQUE_ID : {show: y, blk : 2, word: 0, pos : 0, len: 128, start : 0, type: 'bytes:16', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Optional unique 128-bit ID, rloc: EFUSE_RD_SYS_PART1_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15'} + BLK_VERSION_MAJOR : {show: y, blk : 2, word: 4, pos : 0, len : 2, start: 128, type : 'uint:2', wr_dis : 21, rd_dis: null, alt : '', dict: '{0: "No calibration", 1: "With calibration"}', desc: BLK_VERSION_MAJOR of BLOCK2, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[1:0]', bloc: 'B16[1:0]'} + RESERVED_2_130 : {show: n, blk : 2, word: 4, pos : 2, len : 1, start: 130, type : bool, wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[2]', bloc: 'B16[2]'} + TEMP_CALIB : {show: y, blk : 2, word: 4, pos : 3, len : 9, start: 131, type : 'uint:9', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Temperature calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[11:3]', bloc: 'B16[7:3],B17[3:0]'} + OCODE : {show: y, blk : 2, word: 4, pos: 12, len : 8, start: 140, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC OCode, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[19:12]', bloc: 'B17[7:4],B18[3:0]'} + ADC1_INIT_CODE_ATTEN0 : {show: y, blk : 2, word: 4, pos: 20, len : 10, start: 148, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten0, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[29:20]', bloc: 'B18[7:4],B19[5:0]'} + ADC1_INIT_CODE_ATTEN1 : {show: y, blk : 2, word: 4, pos: 30, len : 10, start: 158, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten1, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[31:30]', bloc: 'B19[7:6],B20'} + ADC1_INIT_CODE_ATTEN2 : {show: y, blk : 2, word: 5, pos : 8, len : 10, start: 168, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten2, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[17:8]', bloc: 'B21,B22[1:0]'} + ADC1_INIT_CODE_ATTEN3 : {show: y, blk : 2, word: 5, pos: 18, len : 10, start: 178, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten3, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[27:18]', bloc: 'B22[7:2],B23[3:0]'} + ADC1_CAL_VOL_ATTEN0 : {show: y, blk : 2, word: 5, pos: 28, len : 10, start: 188, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten0, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[31:28]', bloc: 'B23[7:4],B24[5:0]'} + ADC1_CAL_VOL_ATTEN1 : {show: y, blk : 2, word: 6, pos : 6, len : 10, start: 198, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten1, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[15:6]', bloc: 'B24[7:6],B25'} + ADC1_CAL_VOL_ATTEN2 : {show: y, blk : 2, word: 6, pos: 16, len : 10, start: 208, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten2, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[25:16]', bloc: 'B26,B27[1:0]'} + ADC1_CAL_VOL_ATTEN3 : {show: y, blk : 2, word: 6, pos: 26, len : 10, start: 218, type : 'uint:10', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten3, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[31:26]', bloc: 'B27[7:2],B28[3:0]'} + RESERVED_2_228 : {show: n, blk : 2, word: 7, pos : 4, len : 28, start: 228, type : 'uint:28', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[31:4]', bloc: 'B28[7:4],B29,B30,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 address, rloc: 'EFUSE_RD_USR_DATA6_REG[31:8]', bloc: 'B25,B26,B27,B28,B29,B30'} + RESERVED_3_248 : {show: n, blk : 3, word: 7, pos: 24, len : 8, start: 248, type : 'uint:8', wr_dis : 22, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_USR_DATA7_REG[31:24]', bloc: 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 --git a/espefuse/efuse_defs/esp32c6.yaml b/espefuse/efuse_defs/esp32c6.yaml new file mode 100644 index 000000000..aee94306f --- /dev/null +++ b/espefuse/efuse_defs/esp32c6.yaml @@ -0,0 +1,106 @@ +VER_NO: 709e8ea096e8a03a10006d40d5451a49 +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]'} + SWAP_UART_SDIO_EN : {show: y, blk : 0, word: 1, pos : 7, len : 1, start : 39, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: 'Represents whether pad of uart and sdio is swapped or not. 1: swapped. 0: not swapped', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[7]', bloc: 'B4[7]'} + DIS_ICACHE : {show: y, blk : 0, word: 1, pos : 8, len : 1, start : 40, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: 'Represents whether icache is disabled or enabled. 1: disabled. 0: enabled', 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 : 2, 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]'} + DIS_DOWNLOAD_ICACHE : {show: y, blk : 0, word: 1, pos: 10, len : 1, start : 42, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: 'Represents whether icache is disabled or enabled in Download mode. 1: disabled. 0: enabled', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[10]', bloc: 'B5[2]'} + DIS_USB_SERIAL_JTAG : {show: y, blk : 0, word: 1, pos: 11, len : 1, start : 43, type : bool, wr_dis : 2, 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 : 2, 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 : 17, rd_dis: null, alt : '', dict : '', desc: 'Represents whether SPI0 controller during boot_mode_download is disabled or enabled. 1: disabled. 0: enabled', 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 : 2, rd_dis: null, alt : DIS_CAN, 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 : 2, 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 : 31, 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 : 2, 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 : 2, 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_DREFH : {show: n, blk : 0, word: 1, pos: 21, len : 2, start : 53, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Represents the single-end input threhold vrefh; 1.76 V to 2 V with step of 80 mV, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[22:21]', bloc: 'B6[6:5]'} + USB_DREFL : {show: n, blk : 0, word: 1, pos: 23, len : 2, start : 55, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Represents the single-end input threhold vrefl; 1.76 V to 2 V with step of 80 mV, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[24:23]', bloc: 'B6[7],B7[0]'} + USB_EXCHG_PINS : {show: y, blk : 0, word: 1, pos: 25, len : 1, start : 57, type : bool, wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: 'Represents whether the D+ and D- pins is exchanged. 1: exchanged. 0: not exchanged', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[25]', bloc: 'B7[1]'} + VDD_SPI_AS_GPIO : {show: y, blk : 0, word: 1, pos: 26, len : 1, start : 58, type : bool, wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: 'Represents whether vdd spi pin is functioned as gpio. 1: functioned. 0: not functioned', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[26]', bloc: 'B7[2]'} + RPT4_RESERVED0_2 : {show: n, blk : 0, word: 1, pos: 27, len : 2, start : 59, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[28:27]', bloc: 'B7[4:3]'} + RPT4_RESERVED0_1 : {show: n, blk : 0, word: 1, pos: 29, len : 1, start : 61, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[29]', bloc: 'B7[5]'} + RPT4_RESERVED0_0 : {show: n, blk : 0, word: 1, pos: 30, len : 2, start : 62, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[31:30]', bloc: 'B7[7:6]'} + RPT4_RESERVED1_0 : {show: n, blk : 0, word: 2, pos : 0, len : 16, start : 64, type : 'uint:16', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[15:0]', bloc: 'B8,B9'} + WDT_DELAY_SEL : {show: y, blk : 0, word: 2, pos: 16, len : 2, start : 80, type : 'uint:2', wr_dis : 3, 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 : 14, rd_dis: null, alt : DPA_SEC_LEVEL, 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]'} + CRYPT_DPA_ENABLE : {show: y, blk : 0, word: 3, pos: 18, len : 1, start: 114, type : bool, wr_dis : 1, rd_dis: null, alt : '', dict : '', desc: 'Represents whether anti-dpa attack is enabled. 1:enabled. 0: disabled', rloc: 'EFUSE_RD_REPEAT_DATA2_REG[18]', bloc: 'B14[2]'} + RPT4_RESERVED2_1 : {show: n, blk : 0, word: 3, pos: 19, len : 1, start: 115, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, 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 : 15, 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 : 16, 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]'} + RPT4_RESERVED2_0 : {show: n, blk : 0, word: 3, pos: 22, len : 6, start: 118, type : 'uint:6', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[27:22]', bloc: 'B14[7:6],B15[3:0]'} + FLASH_TPUW : {show: y, blk : 0, word: 3, pos: 28, len : 4, start: 124, type : 'uint:4', wr_dis : 18, 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 : 18, 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 : 18, 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 : 18, rd_dis: null, alt : DIS_USB_PRINT, 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]'} + RPT4_RESERVED3_5 : {show: n, blk : 0, word: 4, pos : 3, len : 1, start: 131, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, 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 : 18, 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 : 18, 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 : 18, rd_dis: null, alt : '', dict: '{0: "Enable", 1: "Enable when GPIO8 is low at reset", 2: "Enable when GPIO8 is high at reset", 3: "Disable"}', desc: Set the default UARTboot message output mode, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[7:6]', bloc: 'B16[7:6]'} + RPT4_RESERVED3_4 : {show: n, blk : 0, word: 4, pos : 8, len : 1, start: 136, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[8]', bloc: 'B17[0]'} + RPT4_RESERVED3_3 : {show: n, blk : 0, word: 4, pos : 9, len : 1, start: 137, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[9]', bloc: 'B17[1]'} + RPT4_RESERVED3_2 : {show: n, blk : 0, word: 4, pos: 10, len : 2, start: 138, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[11:10]', bloc: 'B17[3:2]'} + RPT4_RESERVED3_1 : {show: n, blk : 0, word: 4, pos: 12, len : 1, start: 140, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[12]', bloc: 'B17[4]'} + FORCE_SEND_RESUME : {show: y, blk : 0, word: 4, pos: 13, len : 1, start: 141, type : bool, wr_dis : 18, 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[13]', bloc: 'B17[5]'} + SECURE_VERSION : {show: y, blk : 0, word: 4, pos: 14, len : 16, start: 142, type : 'uint:16', wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Represents the version used by ESP-IDF anti-rollback feature, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[29:14]', bloc: 'B17[7:6],B18,B19[5:0]'} + SECURE_BOOT_DISABLE_FAST_WAKE : {show: y, blk : 0, word: 4, pos: 30, len : 1, start: 158, type : bool, wr_dis : 19, 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[30]', bloc: 'B19[6]'} + RPT4_RESERVED3_0 : {show: n, blk : 0, word: 4, pos: 31, len : 1, start: 159, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[31]', bloc: 'B19[7]'} + DISABLE_WAFER_VERSION_MAJOR : {show: y, blk : 0, word: 5, pos : 0, len : 1, start: 160, type : bool, wr_dis : 19, rd_dis: null, alt : '', dict : '', desc: Disables check of wafer version major, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[0]', bloc: 'B20[0]'} + DISABLE_BLK_VERSION_MAJOR : {show: y, blk : 0, word: 5, pos : 1, len : 1, start: 161, type : bool, wr_dis : 19, rd_dis: null, alt : '', dict : '', desc: Disables check of blk version major, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[1]', bloc: 'B20[1]'} + RESERVED_0_162 : {show: n, blk : 0, word: 5, pos : 2, len : 22, start: 162, type : 'uint:22', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[23:2]', bloc: 'B20[7:2],B21,B22'} + RPT4_RESERVED4_0 : {show: n, blk : 0, word: 5, pos: 24, len : 8, start: 184, type : 'uint:8', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[31:24]', bloc: 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_SPI_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_SPI_SYS_1_REG[31:16]', bloc: 'B6,B7'} + MAC_SPI_RESERVED : {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_SPI_SYS_2_REG[13:0]', bloc: 'B8,B9[5:0]'} + SPI_PAD_CONF_1 : {show: n, blk : 1, word: 2, pos: 14, len : 18, start : 78, type : 'uint:18', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Stores the first part of SPI_PAD_CONF, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[31:14]', bloc: 'B9[7:6],B10,B11'} + SPI_PAD_CONF_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: Stores the second part of SPI_PAD_CONF, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[17:0]', bloc: 'B12,B13,B14[1:0]'} + WAFER_VERSION_MINOR : {show: y, blk : 1, word: 3, pos: 18, len : 4, start: 114, type : 'uint:4', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[21:18]', bloc: 'B14[5:2]'} + WAFER_VERSION_MAJOR : {show: y, blk : 1, word: 3, pos: 22, len : 2, start: 118, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[23:22]', bloc: 'B14[7:6]'} + PKG_VERSION : {show: y, blk : 1, word: 3, pos: 24, len : 3, start: 120, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Package version, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[26:24]', bloc: 'B15[2:0]'} + BLK_VERSION_MINOR : {show: y, blk : 1, word: 3, pos: 27, len : 3, start: 123, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLK_VERSION_MINOR of BLOCK2, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[29:27]', bloc: 'B15[5:3]'} + BLK_VERSION_MAJOR : {show: y, blk : 1, word: 3, pos: 30, len : 2, start: 126, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLK_VERSION_MAJOR of BLOCK2, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[31:30]', bloc: 'B15[7:6]'} + FLASH_CAP : {show: y, blk : 1, word: 4, pos : 0, len : 3, start: 128, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[2:0]', bloc: 'B16[2:0]'} + FLASH_TEMP : {show: y, blk : 1, word: 4, pos : 3, len : 2, start: 131, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[4:3]', bloc: 'B16[4:3]'} + FLASH_VENDOR : {show: y, blk : 1, word: 4, pos : 5, len : 3, start: 133, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[7:5]', bloc: 'B16[7:5]'} + RESERVED_1_136 : {show: n, blk : 1, word: 4, pos : 8, len : 24, start: 136, type : 'uint:24', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[31:8]', bloc: '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_SPI_SYS_5_REG, bloc: 'B20,B21,B22,B23'} + OPTIONAL_UNIQUE_ID : {show: y, blk : 2, word: 0, pos : 0, len: 128, start : 0, type: 'bytes:16', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Optional unique 128-bit ID, rloc: EFUSE_RD_SYS_PART1_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15'} + TEMP_CALIB : {show: y, blk : 2, word: 4, pos : 0, len : 9, start: 128, type : 'uint:9', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Temperature calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[8:0]', bloc: 'B16,B17[0]'} + OCODE : {show: y, blk : 2, word: 4, pos : 9, len : 8, start: 137, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC OCode, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[16:9]', bloc: 'B17[7:1],B18[0]'} + ADC1_INIT_CODE_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 init code at atten0, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[26:17]', bloc: 'B18[7:1],B19[2:0]'} + ADC1_INIT_CODE_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 init code at atten1, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[31:27]', bloc: 'B19[7:3],B20[4:0]'} + ADC1_INIT_CODE_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 init code at atten2, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[14:5]', bloc: 'B20[7:5],B21[6:0]'} + ADC1_INIT_CODE_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 init code at atten3, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[24:15]', bloc: 'B21[7],B22,B23[0]'} + ADC1_CAL_VOL_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 voltage at atten0, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[31:25]', bloc: 'B23[7:1],B24[2:0]'} + ADC1_CAL_VOL_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 voltage at atten1, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[12:3]', bloc: 'B24[7:3],B25[4:0]'} + ADC1_CAL_VOL_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 voltage at atten2, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[22:13]', bloc: 'B25[7:5],B26[6:0]'} + ADC1_CAL_VOL_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 voltage at atten3, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[31:23]', bloc: 'B26[7],B27,B28[0]'} + ADC1_INIT_CODE_ATTEN0_CH0 : {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 init code at atten0 ch0, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[4:1]', bloc: 'B28[4:1]'} + ADC1_INIT_CODE_ATTEN0_CH1 : {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 init code at atten0 ch1, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[8:5]', bloc: 'B28[7:5],B29[0]'} + ADC1_INIT_CODE_ATTEN0_CH2 : {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 init code at atten0 ch2, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[12:9]', bloc: 'B29[4:1]'} + ADC1_INIT_CODE_ATTEN0_CH3 : {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 init code at atten0 ch3, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[16:13]', bloc: 'B29[7:5],B30[0]'} + ADC1_INIT_CODE_ATTEN0_CH4 : {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 init code at atten0 ch4, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[20:17]', bloc: 'B30[4:1]'} + ADC1_INIT_CODE_ATTEN0_CH5 : {show: y, blk : 2, word: 7, pos: 21, len : 4, start: 245, type : 'uint:4', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten0 ch5, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[24:21]', bloc: 'B30[7:5],B31[0]'} + ADC1_INIT_CODE_ATTEN0_CH6 : {show: y, blk : 2, word: 7, pos: 25, len : 4, start: 249, type : 'uint:4', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten0 ch6, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[28:25]', bloc: 'B31[4:1]'} + RESERVED_2_253 : {show: n, blk : 2, word: 7, pos: 29, len : 3, start: 253, type : 'uint:3', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[31:29]', bloc: 'B31[7:5]'} + 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'} + RESERVED_3_248 : {show: n, blk : 3, word: 7, pos: 24, len : 8, start: 248, type : 'uint:8', wr_dis : 22, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_USR_DATA7_REG[31:24]', bloc: 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 --git a/espefuse/efuse_defs/esp32h2.yaml b/espefuse/efuse_defs/esp32h2.yaml new file mode 100644 index 000000000..a86a01895 --- /dev/null +++ b/espefuse/efuse_defs/esp32h2.yaml @@ -0,0 +1,103 @@ +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]'} + RPT4_RESERVED0_4 : {show: n, blk : 0, word: 1, pos : 7, len : 1, start : 39, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[7]', bloc: 'B4[7]'} + DIS_ICACHE : {show: y, blk : 0, word: 1, pos : 8, len : 1, start : 40, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: 'Represents whether icache is disabled or enabled. 1: disabled. 0: enabled', 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 : 2, 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 : 2, 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 : 2, 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 : 2, 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 : 2, rd_dis: null, alt : '', dict : '', desc: 'Represents whether SPI0 controller during boot_mode_download is disabled or enabled. 1: disabled. 0: enabled', 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 : 2, rd_dis: null, alt : DIS_CAN, 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 : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping gpio25 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0, 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 : 31, 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 : 2, 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 : 2, 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_DREFH : {show: n, blk : 0, word: 1, pos: 21, len : 2, start : 53, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Represents the single-end input threhold vrefh; 1.76 V to 2 V with step of 80 mV, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[22:21]', bloc: 'B6[6:5]'} + USB_DREFL : {show: n, blk : 0, word: 1, pos: 23, len : 2, start : 55, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Represents the single-end input threhold vrefl; 1.76 V to 2 V with step of 80 mV, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[24:23]', bloc: 'B6[7],B7[0]'} + USB_EXCHG_PINS : {show: y, blk : 0, word: 1, pos: 25, len : 1, start : 57, type : bool, wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: 'Represents whether the D+ and D- pins is exchanged. 1: exchanged. 0: not exchanged', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[25]', bloc: 'B7[1]'} + VDD_SPI_AS_GPIO : {show: y, blk : 0, word: 1, pos: 26, len : 1, start : 58, type : bool, wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: 'Represents whether vdd spi pin is functioned as gpio. 1: functioned. 0: not functioned', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[26]', bloc: 'B7[2]'} + RPT4_RESERVED0_2 : {show: n, blk : 0, word: 1, pos: 27, len : 2, start : 59, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[28:27]', bloc: 'B7[4:3]'} + RPT4_RESERVED0_1 : {show: n, blk : 0, word: 1, pos: 29, len : 1, start : 61, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[29]', bloc: 'B7[5]'} + RPT4_RESERVED0_0 : {show: n, blk : 0, word: 1, pos: 30, len : 2, start : 62, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[31:30]', bloc: 'B7[7:6]'} + RPT4_RESERVED1_1 : {show: n, blk : 0, word: 2, pos : 0, len : 16, start : 64, type : 'uint:16', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[15:0]', bloc: 'B8,B9'} + WDT_DELAY_SEL : {show: y, blk : 0, word: 2, pos: 16, len : 2, start : 80, type : 'uint:2', wr_dis : 3, 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 : 14, 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_FORCE_USE_HARDWARE_K : {show: y, blk : 0, word: 3, pos: 18, len : 1, start: 114, type : bool, wr_dis : 17, 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 : 14, 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 : 15, 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 : 16, 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]'} + RPT4_RESERVED2_0 : {show: n, blk : 0, word: 3, pos: 22, len : 6, start: 118, type : 'uint:6', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[27:22]', bloc: 'B14[7:6],B15[3:0]'} + FLASH_TPUW : {show: y, blk : 0, word: 3, pos: 28, len : 4, start: 124, type : 'uint:4', wr_dis : 18, 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 : 18, 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 : 18, 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 : 18, rd_dis: null, alt : DIS_USB_PRINT, dict : '', desc: Set this bit to disable USB-Serial-JTAG print during rom boot, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[2]', bloc: 'B16[2]'} + RPT4_RESERVED3_5 : {show: n, blk : 0, word: 4, pos : 3, len : 1, start: 131, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, 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 : 18, 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 : 18, 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 : 18, rd_dis: null, alt : '', dict: '{0: "Enable", 1: "Enable when GPIO8 is low at reset", 2: "Enable when GPIO8 is high at reset", 3: "Disable"}', desc: Set the default UARTboot message output mode, 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 : 18, 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 : 18, 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 : 18, 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_PAD0 : {show: y, blk : 0, word: 4, pos: 26, len : 6, start: 154, type : 'uint:6', wr_dis : 19, rd_dis: null, alt : '', dict : '', desc: Set bits to enable hysteresis function of PAD0~5, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[31:26]', bloc: 'B19[7:2]'} + HYS_EN_PAD1 : {show: y, blk : 0, word: 5, pos : 0, len : 22, start: 160, type : 'uint:22', wr_dis : 19, rd_dis: null, alt : '', dict : '', desc: Set bits to enable hysteresis function of PAD6~27, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[21:0]', bloc: 'B20,B21,B22[5:0]'} + RPT4_RESERVED4_1 : {show: n, blk : 0, word: 5, pos: 22, len : 2, start: 182, type : 'uint:2', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[23:22]', bloc: 'B22[7:6]'} + RPT4_RESERVED4_0 : {show: n, blk : 0, word: 5, pos: 24, len : 8, start: 184, type : 'uint:8', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[31:24]', bloc: 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'} + RXIQ_VERSION : {show: y, blk : 1, word: 2, pos : 0, len : 3, start : 64, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: RF Calibration data. RXIQ version, rloc: 'EFUSE_RD_MAC_SYS_2_REG[2:0]', bloc: 'B8[2:0]'} + RXIQ_0 : {show: y, blk : 1, word: 2, pos : 3, len : 7, start : 67, type : 'uint:7', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: RF Calibration data. RXIQ data 0, rloc: 'EFUSE_RD_MAC_SYS_2_REG[9:3]', bloc: 'B8[7:3],B9[1:0]'} + RXIQ_1 : {show: y, blk : 1, word: 2, pos: 10, len : 7, start : 74, type : 'uint:7', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: RF Calibration data. RXIQ data 1, rloc: 'EFUSE_RD_MAC_SYS_2_REG[16:10]', bloc: 'B9[7:2],B10[0]'} + RESERVED_1_81 : {show: n, blk : 1, word: 2, pos: 17, len : 15, start : 81, type : 'uint:15', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SYS_2_REG[31:17]', bloc: 'B10[7:1],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]'} + WAFER_VERSION_MINOR : {show: y, blk : 1, word: 3, pos: 18, len : 3, start: 114, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SYS_3_REG[20:18]', bloc: 'B14[4:2]'} + WAFER_VERSION_MAJOR : {show: y, blk : 1, word: 3, pos: 21, len : 2, start: 117, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SYS_3_REG[22:21]', bloc: 'B14[6:5]'} + DISABLE_WAFER_VERSION_MAJOR : {show: y, blk : 1, word: 3, pos: 23, len : 1, start: 119, type : bool, wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Disables check of wafer version major, rloc: 'EFUSE_RD_MAC_SYS_3_REG[23]', bloc: 'B14[7]'} + FLASH_CAP : {show: y, blk : 1, word: 3, pos: 24, len : 3, start: 120, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SYS_3_REG[26:24]', bloc: 'B15[2:0]'} + FLASH_TEMP : {show: y, blk : 1, word: 3, pos: 27, len : 2, start: 123, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SYS_3_REG[28:27]', bloc: 'B15[4:3]'} + FLASH_VENDOR : {show: y, blk : 1, word: 3, pos: 29, len : 3, start: 125, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_MAC_SYS_3_REG[31:29]', bloc: 'B15[7:5]'} + PKG_VERSION : {show: y, blk : 1, word: 4, pos : 0, len : 3, start: 128, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Package version, rloc: 'EFUSE_RD_MAC_SYS_4_REG[2:0]', bloc: 'B16[2:0]'} + RESERVED_1_131 : {show: n, blk : 1, word: 4, pos : 3, len : 29, start: 131, type : 'uint:29', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SYS_4_REG[31:3]', bloc: 'B16[7:3],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'} + OPTIONAL_UNIQUE_ID : {show: y, blk : 2, word: 0, pos : 0, len: 128, start : 0, type: 'bytes:16', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Optional unique 128-bit ID, rloc: EFUSE_RD_SYS_PART1_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15'} + RESERVED_2_128 : {show: n, blk : 2, word: 4, pos : 0, len : 2, start: 128, type : 'uint:2', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[1:0]', bloc: 'B16[1:0]'} + 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]'} + 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'} + RESERVED_3_248 : {show: n, blk : 3, word: 7, pos: 24, len : 8, start: 248, type : 'uint:8', wr_dis : 22, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_USR_DATA7_REG[31:24]', bloc: 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 --git a/espefuse/efuse_defs/esp32p4.yaml b/espefuse/efuse_defs/esp32p4.yaml new file mode 100644 index 000000000..fe10b2eda --- /dev/null +++ b/espefuse/efuse_defs/esp32p4.yaml @@ -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 --git a/espefuse/efuse_defs/esp32s2.yaml b/espefuse/efuse_defs/esp32s2.yaml new file mode 100644 index 000000000..45b5900e4 --- /dev/null +++ b/espefuse/efuse_defs/esp32s2.yaml @@ -0,0 +1,119 @@ +VER_NO: 888a61f6f500d9c7ee0aa32016b0bee7 +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]'} + DIS_RTC_RAM_BOOT : {show: n, blk : 0, word: 1, pos : 7, len : 1, start : 39, type : bool, wr_dis : 1, rd_dis: null, alt : '', dict : '', desc: Reserved, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[7]', bloc: 'B4[7]'} + DIS_ICACHE : {show: y, blk : 0, word: 1, pos : 8, len : 1, start : 40, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable Icache, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[8]', bloc: 'B5[0]'} + DIS_DCACHE : {show: y, blk : 0, word: 1, pos : 9, len : 1, start : 41, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable Dcache, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[9]', bloc: 'B5[1]'} + DIS_DOWNLOAD_ICACHE : {show: y, blk : 0, word: 1, pos: 10, len : 1, start : 42, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Disables Icache when SoC is in Download mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[10]', bloc: 'B5[2]'} + DIS_DOWNLOAD_DCACHE : {show: y, blk : 0, word: 1, pos: 11, len : 1, start : 43, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Disables Dcache when SoC is in Download mode, 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 : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable the function that forces chip into download mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[12]', bloc: 'B5[4]'} + DIS_USB : {show: y, blk : 0, word: 1, pos: 13, len : 1, start : 45, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable USB OTG function, 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 : 2, rd_dis: null, alt : DIS_CAN, dict : '', desc: Set this bit to disable the TWAI Controller function, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[14]', bloc: 'B5[6]'} + DIS_BOOT_REMAP : {show: y, blk : 0, word: 1, pos: 15, len : 1, start : 47, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Disables capability to Remap RAM to ROM address space, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[15]', bloc: 'B5[7]'} + RPT4_RESERVED5 : {show: n, blk : 0, word: 1, pos: 16, len : 1, start : 48, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved (used for four backups method), rloc: 'EFUSE_RD_REPEAT_DATA0_REG[16]', bloc: 'B6[0]'} + SOFT_DIS_JTAG : {show: y, blk : 0, word: 1, pos: 17, len : 1, start : 49, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Software disables JTAG. When software disabled; JTAG can be activated temporarily by HMAC peripheral, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[17]', bloc: 'B6[1]'} + HARD_DIS_JTAG : {show: y, blk : 0, word: 1, pos: 18, len : 1, start : 50, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Hardware disables JTAG permanently, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[18]', bloc: 'B6[2]'} + DIS_DOWNLOAD_MANUAL_ENCRYPT : {show: y, blk : 0, word: 1, pos: 19, len : 1, start : 51, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Disables flash encryption when in download boot modes, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[19]', bloc: 'B6[3]'} + USB_DREFH : {show: n, blk : 0, word: 1, pos: 20, len : 2, start : 52, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Controls single-end input threshold vrefh; 1.76 V to 2 V with step of 80 mV; stored in eFuse, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[21:20]', bloc: 'B6[5:4]'} + USB_DREFL : {show: n, blk : 0, word: 1, pos: 22, len : 2, start : 54, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Controls single-end input threshold vrefl; 0.8 V to 1.04 V with step of 80 mV; stored in eFuse, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[23:22]', bloc: 'B6[7:6]'} + USB_EXCHG_PINS : {show: y, blk : 0, word: 1, pos: 24, len : 1, start : 56, type : bool, wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Set this bit to exchange USB D+ and D- pins, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[24]', bloc: 'B7[0]'} + USB_EXT_PHY_ENABLE : {show: y, blk : 0, word: 1, pos: 25, len : 1, start : 57, type : bool, wr_dis : 30, rd_dis: null, alt : EXT_PHY_ENABLE, dict : '', desc: Set this bit to enable external USB PHY, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[25]', bloc: 'B7[1]'} + USB_FORCE_NOPERSIST : {show: y, blk : 0, word: 1, pos: 26, len : 1, start : 58, type : bool, wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: If set; forces USB BVALID to 1, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[26]', bloc: 'B7[2]'} + BLOCK0_VERSION : {show: y, blk : 0, word: 1, pos: 27, len : 2, start : 59, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: BLOCK0 efuse version, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[28:27]', bloc: 'B7[4:3]'} + VDD_SPI_MODECURLIM : {show: n, blk : 0, word: 1, pos: 29, len : 1, start : 61, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: SPI regulator switches current limit mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[29]', bloc: 'B7[5]'} + VDD_SPI_DREFH : {show: n, blk : 0, word: 1, pos: 30, len : 2, start : 62, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: SPI regulator high voltage reference, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[31:30]', bloc: 'B7[7:6]'} + VDD_SPI_DREFM : {show: n, blk : 0, word: 2, pos : 0, len : 2, start : 64, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: SPI regulator medium voltage reference, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[1:0]', bloc: 'B8[1:0]'} + VDD_SPI_DREFL : {show: n, blk : 0, word: 2, pos : 2, len : 2, start : 66, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: SPI regulator low voltage reference, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[3:2]', bloc: 'B8[3:2]'} + VDD_SPI_XPD : {show: y, blk : 0, word: 2, pos : 4, len : 1, start : 68, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: If VDD_SPI_FORCE is 1; this value determines if the VDD_SPI regulator is powered on, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[4]', bloc: 'B8[4]'} + VDD_SPI_TIEH : {show: y, blk : 0, word: 2, pos : 5, len : 1, start : 69, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict: '{0: "VDD_SPI connects to 1.8 V LDO", 1: "VDD_SPI connects to VDD3P3_RTC_IO"}', desc: If VDD_SPI_FORCE is 1; determines VDD_SPI voltage, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[5]', bloc: 'B8[5]'} + VDD_SPI_FORCE : {show: y, blk : 0, word: 2, pos : 6, len : 1, start : 70, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Set this bit to use XPD_VDD_PSI_REG and VDD_SPI_TIEH to configure VDD_SPI LDO, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[6]', bloc: 'B8[6]'} + VDD_SPI_EN_INIT : {show: n, blk : 0, word: 2, pos : 7, len : 1, start : 71, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: 'Set SPI regulator to 0 to configure init[1:0]=0', rloc: 'EFUSE_RD_REPEAT_DATA1_REG[7]', bloc: 'B8[7]'} + VDD_SPI_ENCURLIM : {show: n, blk : 0, word: 2, pos : 8, len : 1, start : 72, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Set SPI regulator to 1 to enable output current limit, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[8]', bloc: 'B9[0]'} + VDD_SPI_DCURLIM : {show: n, blk : 0, word: 2, pos : 9, len : 3, start : 73, type : 'uint:3', wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Tunes the current limit threshold of SPI regulator when tieh=0; about 800 mA/(8+d), rloc: 'EFUSE_RD_REPEAT_DATA1_REG[11:9]', bloc: 'B9[3:1]'} + VDD_SPI_INIT : {show: n, blk : 0, word: 2, pos: 12, len : 2, start : 76, type : 'uint:2', wr_dis : 2, rd_dis: null, alt : '', dict: '{0: "no resistance", 1: "6K", 2: "4K", 3: "2K"}', desc: Adds resistor from LDO output to ground, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[13:12]', bloc: 'B9[5:4]'} + VDD_SPI_DCAP : {show: n, blk : 0, word: 2, pos: 14, len : 2, start : 78, type : 'uint:2', wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Prevents SPI regulator from overshoot, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[15:14]', bloc: 'B9[7:6]'} + WDT_DELAY_SEL : {show: y, blk : 0, word: 2, pos: 16, len : 2, start : 80, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict: '{0: "40000", 1: "80000", 2: "160000", 3: "320000"}', desc: RTC watchdog timeout threshold; in unit of slow clock cycle, 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 disabled 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: 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: 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: 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: 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: 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: Purpose of KEY5, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[15:12]', bloc: 'B13[7:4]'} + KEY_PURPOSE_6 : {show: n, blk : 0, word: 3, pos: 16, len : 4, start: 112, type : 'uint:4', wr_dis : 14, rd_dis: null, alt : '', dict : '', desc: Purpose of KEY6, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[19:16]', bloc: 'B14[3:0]'} + SECURE_BOOT_EN : {show: y, blk : 0, word: 3, pos: 20, len : 1, start: 116, type : bool, wr_dis : 15, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable secure boot, 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 : 16, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable aggressive secure boot key revocation mode, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[21]', bloc: 'B14[5]'} + RPT4_RESERVED1 : {show: n, blk : 0, word: 3, pos: 22, len : 6, start: 118, type : 'uint:6', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved (used for four backups method), rloc: 'EFUSE_RD_REPEAT_DATA2_REG[27:22]', bloc: 'B14[7:6],B15[3:0]'} + FLASH_TPUW : {show: y, blk : 0, word: 3, pos: 28, len : 4, start: 124, type : 'uint:4', wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Configures flash startup delay after SoC power-up; in unit of (ms/2). When the value is 15; delay is 7.5 ms, 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 : 18, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable all download boot modes, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[0]', bloc: 'B16[0]'} + DIS_LEGACY_SPI_BOOT : {show: y, blk : 0, word: 4, pos : 1, len : 1, start: 129, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable Legacy SPI boot mode, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[1]', bloc: 'B16[1]'} + UART_PRINT_CHANNEL : {show: y, blk : 0, word: 4, pos : 2, len : 1, start: 130, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict: '{0: "UART0", 1: "UART1"}', desc: Selects the default UART for printing boot messages, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[2]', bloc: 'B16[2]'} + RPT4_RESERVED3 : {show: n, blk : 0, word: 4, pos : 3, len : 1, start: 131, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved (used for four backups method), rloc: 'EFUSE_RD_REPEAT_DATA3_REG[3]', bloc: 'B16[3]'} + DIS_USB_DOWNLOAD_MODE : {show: y, blk : 0, word: 4, pos : 4, len : 1, start: 132, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable use of USB OTG in UART download boot mode, 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 : 18, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable secure UART download mode (read/write flash only), 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 : 18, rd_dis: null, alt : '', dict: '{0: "Enable", 1: "Enable when GPIO46 is low at reset", 2: "Enable when GPIO46 is high at reset", 3: "Disable"}', desc: Set the default UART boot message output mode, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[7:6]', bloc: 'B16[7:6]'} + PIN_POWER_SELECTION : {show: y, blk : 0, word: 4, pos : 8, len : 1, start: 136, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict: '{0: "VDD3P3_CPU", 1: "VDD_SPI"}', desc: Set default power supply for GPIO33-GPIO37; set when SPI flash is initialized, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[8]', bloc: 'B17[0]'} + FLASH_TYPE : {show: y, blk : 0, word: 4, pos : 9, len : 1, start: 137, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict: '{0: "4 data lines", 1: "8 data lines"}', desc: SPI flash type, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[9]', bloc: 'B17[1]'} + FORCE_SEND_RESUME : {show: y, blk : 0, word: 4, pos: 10, len : 1, start: 138, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: If set; forces ROM code to send an SPI flash resume command during SPI boot, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[10]', bloc: 'B17[2]'} + SECURE_VERSION : {show: y, blk : 0, word: 4, pos: 11, len : 16, start: 139, type : 'uint:16', wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Secure version (used by ESP-IDF anti-rollback feature), rloc: 'EFUSE_RD_REPEAT_DATA3_REG[26:11]', bloc: 'B17[7:3],B18,B19[2:0]'} + RPT4_RESERVED2 : {show: n, blk : 0, word: 4, pos: 27, len : 5, start: 155, type : 'uint:5', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved (used for four backups method), rloc: 'EFUSE_RD_REPEAT_DATA3_REG[31:27]', bloc: 'B19[7:3]'} + DISABLE_WAFER_VERSION_MAJOR : {show: y, blk : 0, word: 5, pos : 0, len : 1, start: 160, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Disables check of wafer version major, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[0]', bloc: 'B20[0]'} + DISABLE_BLK_VERSION_MAJOR : {show: y, blk : 0, word: 5, pos : 1, len : 1, start: 161, type : bool, wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Disables check of blk version major, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[1]', bloc: 'B20[1]'} + RESERVED_0_162 : {show: n, blk : 0, word: 5, pos : 2, len : 22, start: 162, type : 'uint:22', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[23:2]', bloc: 'B20[7:2],B21,B22'} + 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_SPI_SYS_0_REG, bloc: 'B0,B1,B2,B3,B4,B5'} + SPI_PAD_CONFIG_CLK : {show: y, blk : 1, word: 1, pos: 16, len : 6, start : 48, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure CLK, rloc: 'EFUSE_RD_MAC_SPI_SYS_1_REG[21:16]', bloc: 'B6[5:0]'} + SPI_PAD_CONFIG_Q : {show: y, blk : 1, word: 1, pos: 22, len : 6, start : 54, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure Q(D1), rloc: 'EFUSE_RD_MAC_SPI_SYS_1_REG[27:22]', bloc: 'B6[7:6],B7[3:0]'} + SPI_PAD_CONFIG_D : {show: y, blk : 1, word: 1, pos: 28, len : 6, start : 60, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D(D0), rloc: 'EFUSE_RD_MAC_SPI_SYS_1_REG[31:28]', bloc: 'B7[7:4],B8[1:0]'} + SPI_PAD_CONFIG_CS : {show: y, blk : 1, word: 2, pos : 2, len : 6, start : 66, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure CS, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[7:2]', bloc: 'B8[7:2]'} + SPI_PAD_CONFIG_HD : {show: y, blk : 1, word: 2, pos : 8, len : 6, start : 72, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure HD(D3), rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[13:8]', bloc: 'B9[5:0]'} + SPI_PAD_CONFIG_WP : {show: y, blk : 1, word: 2, pos: 14, len : 6, start : 78, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure WP(D2), rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[19:14]', bloc: 'B9[7:6],B10[3:0]'} + SPI_PAD_CONFIG_DQS : {show: y, blk : 1, word: 2, pos: 20, len : 6, start : 84, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure DQS, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[25:20]', bloc: 'B10[7:4],B11[1:0]'} + SPI_PAD_CONFIG_D4 : {show: y, blk : 1, word: 2, pos: 26, len : 6, start : 90, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D4, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[31:26]', bloc: 'B11[7:2]'} + SPI_PAD_CONFIG_D5 : {show: y, blk : 1, word: 3, pos : 0, len : 6, start : 96, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D5, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[5:0]', bloc: 'B12[5:0]'} + SPI_PAD_CONFIG_D6 : {show: y, blk : 1, word: 3, pos : 6, len : 6, start: 102, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D6, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[11:6]', bloc: 'B12[7:6],B13[3:0]'} + SPI_PAD_CONFIG_D7 : {show: y, blk : 1, word: 3, pos: 12, len : 6, start: 108, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D7, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[17:12]', bloc: 'B13[7:4],B14[1:0]'} + WAFER_VERSION_MAJOR : {show: y, blk : 1, word: 3, pos: 18, len : 2, start: 114, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MAJOR, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[19:18]', bloc: 'B14[3:2]'} + WAFER_VERSION_MINOR_HI : {show: y, blk : 1, word: 3, pos: 20, len : 1, start: 116, type : bool, wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MINOR most significant bit, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[20]', bloc: 'B14[4]'} + FLASH_VERSION : {show: y, blk : 1, word: 3, pos: 21, len : 4, start: 117, type : 'uint:4', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Flash version, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[24:21]', bloc: 'B14[7:5],B15[0]'} + BLK_VERSION_MAJOR : {show: y, blk : 1, word: 3, pos: 25, len : 2, start: 121, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLK_VERSION_MAJOR, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[26:25]', bloc: 'B15[2:1]'} + RESERVED_1_123 : {show: n, blk : 1, word: 3, pos: 27, len : 1, start: 123, type : bool, wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[27]', bloc: 'B15[3]'} + PSRAM_VERSION : {show: y, blk : 1, word: 3, pos: 28, len : 4, start: 124, type : 'uint:4', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: PSRAM version, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[31:28]', bloc: 'B15[7:4]'} + PKG_VERSION : {show: y, blk : 1, word: 4, pos : 0, len : 4, start: 128, type : 'uint:4', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: Package version, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[3:0]', bloc: 'B16[3:0]'} + WAFER_VERSION_MINOR_LO : {show: y, blk : 1, word: 4, pos : 4, len : 3, start: 132, type : 'uint:3', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MINOR least significant bits, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[6:4]', bloc: 'B16[6:4]'} + RESERVED_1_135 : {show: n, blk : 1, word: 4, pos : 7, len : 25, start: 135, type : 'uint:25', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_4_REG[31:7]', bloc: 'B16[7],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 part of the zeroth part of system data, rloc: EFUSE_RD_MAC_SPI_SYS_5_REG, bloc: 'B20,B21,B22,B23'} + OPTIONAL_UNIQUE_ID : {show: y, blk : 2, word: 0, pos : 0, len: 128, start : 0, type: 'bytes:16', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Optional unique 128-bit ID, rloc: EFUSE_RD_SYS_PART1_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15'} + ADC_CALIB : {show: y, blk : 2, word: 4, pos : 0, len : 4, start: 128, type : 'uint:4', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: 4 bit of ADC calibration, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[3:0]', bloc: 'B16[3:0]'} + BLK_VERSION_MINOR : {show: y, blk : 2, word: 4, pos : 4, len : 3, start: 132, type : 'uint:3', wr_dis : 21, rd_dis: null, alt : '', dict: '{0: "No calib", 1: "ADC calib V1", 2: "ADC calib V2"}', desc: BLK_VERSION_MINOR of BLOCK2, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[6:4]', bloc: 'B16[6:4]'} + TEMP_CALIB : {show: y, blk : 2, word: 4, pos : 7, len : 9, start: 135, type : 'uint:9', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Temperature calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[15:7]', bloc: 'B16[7],B17'} + RTCCALIB_V1IDX_A10H : {show: y, blk : 2, word: 4, pos: 16, len : 8, start: 144, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[23:16]', bloc: B18} + RTCCALIB_V1IDX_A11H : {show: y, blk : 2, word: 4, pos: 24, len : 8, start: 152, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[31:24]', bloc: B19} + RTCCALIB_V1IDX_A12H : {show: y, blk : 2, word: 5, pos : 0, len : 8, start: 160, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[7:0]', bloc: B20} + RTCCALIB_V1IDX_A13H : {show: y, blk : 2, word: 5, pos : 8, len : 8, start: 168, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[15:8]', bloc: B21} + RTCCALIB_V1IDX_A20H : {show: y, blk : 2, word: 5, pos: 16, len : 8, start: 176, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[23:16]', bloc: B22} + RTCCALIB_V1IDX_A21H : {show: y, blk : 2, word: 5, pos: 24, len : 8, start: 184, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[31:24]', bloc: B23} + RTCCALIB_V1IDX_A22H : {show: y, blk : 2, word: 6, pos : 0, len : 8, start: 192, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[7:0]', bloc: B24} + RTCCALIB_V1IDX_A23H : {show: y, blk : 2, word: 6, pos : 8, len : 8, start: 200, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[15:8]', bloc: B25} + RTCCALIB_V1IDX_A10L : {show: y, blk : 2, word: 6, pos: 16, len : 6, start: 208, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[21:16]', bloc: 'B26[5:0]'} + RTCCALIB_V1IDX_A11L : {show: y, blk : 2, word: 6, pos: 22, len : 6, start: 214, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[27:22]', bloc: 'B26[7:6],B27[3:0]'} + RTCCALIB_V1IDX_A12L : {show: y, blk : 2, word: 6, pos: 28, len : 6, start: 220, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[31:28]', bloc: 'B27[7:4],B28[1:0]'} + RTCCALIB_V1IDX_A13L : {show: y, blk : 2, word: 7, pos : 2, len : 6, start: 226, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[7:2]', bloc: 'B28[7:2]'} + RTCCALIB_V1IDX_A20L : {show: y, blk : 2, word: 7, pos : 8, len : 6, start: 232, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[13:8]', bloc: 'B29[5:0]'} + RTCCALIB_V1IDX_A21L : {show: y, blk : 2, word: 7, pos: 14, len : 6, start: 238, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[19:14]', bloc: 'B29[7:6],B30[3:0]'} + RTCCALIB_V1IDX_A22L : {show: y, blk : 2, word: 7, pos: 20, len : 6, start: 244, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[25:20]', bloc: 'B30[7:4],B31[1:0]'} + RTCCALIB_V1IDX_A23L : {show: y, blk : 2, word: 7, pos: 26, len : 6, start: 250, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: '', rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[31:26]', bloc: 'B31[7:2]'} + 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'} + RESERVED_3_248 : {show: n, blk : 3, word: 7, pos: 24, len : 8, start: 248, type : 'uint:8', wr_dis : 22, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_USR_DATA7_REG[31:24]', bloc: 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 --git a/espefuse/efuse_defs/esp32s3.yaml b/espefuse/efuse_defs/esp32s3.yaml new file mode 100644 index 000000000..4d4c69511 --- /dev/null +++ b/espefuse/efuse_defs/esp32s3.yaml @@ -0,0 +1,134 @@ +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]'} + DIS_RTC_RAM_BOOT : {show: n, blk : 0, word: 1, pos : 7, len : 1, start : 39, type : bool, wr_dis : 1, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable boot from RTC RAM, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[7]', bloc: 'B4[7]'} + DIS_ICACHE : {show: y, blk : 0, word: 1, pos : 8, len : 1, start : 40, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable Icache, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[8]', bloc: 'B5[0]'} + DIS_DCACHE : {show: y, blk : 0, word: 1, pos : 9, len : 1, start : 41, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable Dcache, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[9]', bloc: 'B5[1]'} + DIS_DOWNLOAD_ICACHE : {show: y, blk : 0, word: 1, pos: 10, len : 1, start : 42, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: 'Set this bit to disable Icache in download mode (boot_mode[3:0] is 0; 1; 2; 3; 6; 7)', rloc: 'EFUSE_RD_REPEAT_DATA0_REG[10]', bloc: 'B5[2]'} + DIS_DOWNLOAD_DCACHE : {show: y, blk : 0, word: 1, pos: 11, len : 1, start : 43, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: 'Set this bit to disable Dcache in download mode ( boot_mode[3:0] is 0; 1; 2; 3; 6; 7)', 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 : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable the function that forces chip into download mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[12]', bloc: 'B5[4]'} + DIS_USB_OTG : {show: y, blk : 0, word: 1, pos: 13, len : 1, start : 45, type : bool, wr_dis : 2, rd_dis: null, alt : DIS_USB, dict : '', desc: Set this bit to disable USB function, 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 : 2, rd_dis: null, alt : DIS_CAN, dict : '', desc: Set this bit to disable CAN function, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[14]', bloc: 'B5[6]'} + DIS_APP_CPU : {show: y, blk : 0, word: 1, pos: 15, len : 1, start : 47, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Disable app cpu, 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 : 31, rd_dis: null, alt : '', dict : '', desc: Set these bits to disable JTAG in the soft way (odd number 1 means disable ). JTAG can be enabled in HMAC module, 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 : 2, rd_dis: null, alt : HARD_DIS_JTAG, dict : '', desc: Set this bit to disable JTAG in the hard way. JTAG is disabled permanently, 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 : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable flash encryption when in download boot modes, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[20]', bloc: 'B6[4]'} + USB_DREFH : {show: n, blk : 0, word: 1, pos: 21, len : 2, start : 53, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Controls single-end input threshold vrefh; 1.76 V to 2 V with step of 80 mV; stored in eFuse, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[22:21]', bloc: 'B6[6:5]'} + USB_DREFL : {show: n, blk : 0, word: 1, pos: 23, len : 2, start : 55, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Controls single-end input threshold vrefl; 0.8 V to 1.04 V with step of 80 mV; stored in eFuse, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[24:23]', bloc: 'B6[7],B7[0]'} + USB_EXCHG_PINS : {show: y, blk : 0, word: 1, pos: 25, len : 1, start : 57, type : bool, wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Set this bit to exchange USB D+ and D- pins, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[25]', bloc: 'B7[1]'} + USB_EXT_PHY_ENABLE : {show: y, blk : 0, word: 1, pos: 26, len : 1, start : 58, type : bool, wr_dis : 30, rd_dis: null, alt : EXT_PHY_ENABLE, dict : '', desc: Set this bit to enable external PHY, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[26]', bloc: 'B7[2]'} + BTLC_GPIO_ENABLE : {show: n, blk : 0, word: 1, pos: 27, len : 2, start : 59, type : 'uint:2', wr_dis : 30, rd_dis: null, alt : '', dict : '', desc: Bluetooth GPIO signal output security level control, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[28:27]', bloc: 'B7[4:3]'} + VDD_SPI_MODECURLIM : {show: n, blk : 0, word: 1, pos: 29, len : 1, start : 61, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: SPI regulator switches current limit mode, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[29]', bloc: 'B7[5]'} + VDD_SPI_DREFH : {show: n, blk : 0, word: 1, pos: 30, len : 2, start : 62, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: SPI regulator high voltage reference, rloc: 'EFUSE_RD_REPEAT_DATA0_REG[31:30]', bloc: 'B7[7:6]'} + VDD_SPI_DREFM : {show: n, blk : 0, word: 2, pos : 0, len : 2, start : 64, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: SPI regulator medium voltage reference, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[1:0]', bloc: 'B8[1:0]'} + VDD_SPI_DREFL : {show: n, blk : 0, word: 2, pos : 2, len : 2, start : 66, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: SPI regulator low voltage reference, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[3:2]', bloc: 'B8[3:2]'} + VDD_SPI_XPD : {show: y, blk : 0, word: 2, pos : 4, len : 1, start : 68, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: SPI regulator power up signal, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[4]', bloc: 'B8[4]'} + VDD_SPI_TIEH : {show: y, blk : 0, word: 2, pos : 5, len : 1, start : 69, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict: '{0: "VDD_SPI connects to 1.8 V LDO", 1: "VDD_SPI connects to VDD3P3_RTC_IO"}', desc: If VDD_SPI_FORCE is 1; determines VDD_SPI voltage, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[5]', bloc: 'B8[5]'} + VDD_SPI_FORCE : {show: y, blk : 0, word: 2, pos : 6, len : 1, start : 70, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Set this bit and force to use the configuration of eFuse to configure VDD_SPI, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[6]', bloc: 'B8[6]'} + VDD_SPI_EN_INIT : {show: n, blk : 0, word: 2, pos : 7, len : 1, start : 71, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: 'Set SPI regulator to 0 to configure init[1:0]=0', rloc: 'EFUSE_RD_REPEAT_DATA1_REG[7]', bloc: 'B8[7]'} + VDD_SPI_ENCURLIM : {show: n, blk : 0, word: 2, pos : 8, len : 1, start : 72, type : bool, wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Set SPI regulator to 1 to enable output current limit, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[8]', bloc: 'B9[0]'} + VDD_SPI_DCURLIM : {show: n, blk : 0, word: 2, pos : 9, len : 3, start : 73, type : 'uint:3', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Tunes the current limit threshold of SPI regulator when tieh=0; about 800 mA/(8+d), rloc: 'EFUSE_RD_REPEAT_DATA1_REG[11:9]', bloc: 'B9[3:1]'} + VDD_SPI_INIT : {show: n, blk : 0, word: 2, pos: 12, len : 2, start : 76, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict: '{0: "no resistance", 1: "6K", 2: "4K", 3: "2K"}', desc: Adds resistor from LDO output to ground, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[13:12]', bloc: 'B9[5:4]'} + VDD_SPI_DCAP : {show: n, blk : 0, word: 2, pos: 14, len : 2, start : 78, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict : '', desc: Prevents SPI regulator from overshoot, rloc: 'EFUSE_RD_REPEAT_DATA1_REG[15:14]', bloc: 'B9[7:6]'} + WDT_DELAY_SEL : {show: y, blk : 0, word: 2, pos: 16, len : 2, start : 80, type : 'uint:2', wr_dis : 3, rd_dis: null, alt : '', dict: '{0: "40000", 1: "80000", 2: "160000", 3: "320000"}', desc: RTC watchdog timeout threshold; in unit of slow clock cycle, 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 disabled 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: 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: 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: 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: 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: 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: Purpose of Key5, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[15:12]', bloc: 'B13[7:4]'} + RPT4_RESERVED0 : {show: n, blk : 0, word: 3, pos: 16, len : 4, start: 112, type : 'uint:4', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: Reserved (used for four backups method), rloc: 'EFUSE_RD_REPEAT_DATA2_REG[19:16]', bloc: 'B14[3:0]'} + SECURE_BOOT_EN : {show: y, blk : 0, word: 3, pos: 20, len : 1, start: 116, type : bool, wr_dis : 15, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable secure boot, 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 : 16, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable revoking aggressive secure boot, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[21]', bloc: 'B14[5]'} + DIS_USB_JTAG : {show: y, blk : 0, word: 3, pos: 22, len : 1, start: 118, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable function of usb switch to jtag in module of usb device, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[22]', bloc: 'B14[6]'} + DIS_USB_SERIAL_JTAG : {show: y, blk : 0, word: 3, pos: 23, len : 1, start: 119, type : bool, wr_dis : 2, rd_dis: null, alt : DIS_USB_DEVICE, dict : '', desc: Set this bit to disable usb device, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[23]', bloc: 'B14[7]'} + STRAP_JTAG_SEL : {show: y, blk : 0, word: 3, pos: 24, len : 1, start: 120, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping gpio10 when both reg_dis_usb_jtag and reg_dis_pad_jtag are equal to 0, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[24]', bloc: 'B15[0]'} + USB_PHY_SEL : {show: y, blk : 0, word: 3, pos: 25, len : 1, start: 121, type : bool, wr_dis : 2, rd_dis: null, alt : '', dict: '{0: "internal PHY is assigned to USB Device while external PHY is assigned to USB OTG", 1: "internal PHY is assigned to USB OTG while external PHY is assigned to USB Device"}', desc: This bit is used to switch internal PHY and external PHY for USB OTG and USB Device, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[25]', bloc: 'B15[1]'} + POWER_GLITCH_DSENSE : {show: n, blk : 0, word: 3, pos: 26, len : 2, start: 122, type : 'uint:2', wr_dis : 17, rd_dis: null, alt : '', dict : '', desc: Sample delay configuration of power glitch, rloc: 'EFUSE_RD_REPEAT_DATA2_REG[27:26]', bloc: 'B15[3:2]'} + FLASH_TPUW : {show: y, blk : 0, word: 3, pos: 28, len : 4, start: 124, type : 'uint:4', wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Configures flash waiting time after power-up; in unit of ms. If the value is less than 15; the waiting time is the configurable value. Otherwise; the waiting time is twice the configurable 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 : 18, rd_dis: null, alt : '', dict : '', desc: 'Set this bit to disable download mode (boot_mode[3:0] = 0; 1; 2; 3; 6; 7)', 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 : 18, rd_dis: null, alt : DIS_LEGACY_SPI_BOOT, dict : '', desc: Disable direct boot mode, 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 : 18, rd_dis: null, alt : UART_PRINT_CHANNEL, dict: '{0: "Enable", 1: "Disable"}', desc: USB printing, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[2]', bloc: 'B16[2]'} + FLASH_ECC_MODE : {show: y, blk : 0, word: 4, pos : 3, len : 1, start: 131, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict: '{0: "16to18 byte", 1: "16to17 byte"}', desc: Flash ECC mode in ROM, 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 : 18, rd_dis: null, alt : DIS_USB_DOWNLOAD_MODE, dict : '', desc: Set this bit to disable UART download mode through USB, 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 : 18, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable secure UART download mode, 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 : 18, rd_dis: null, alt : '', dict: '{0: "Enable", 1: "Enable when GPIO46 is low at reset", 2: "Enable when GPIO46 is high at reset", 3: "Disable"}', desc: Set the default UART boot message output mode, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[7:6]', bloc: 'B16[7:6]'} + PIN_POWER_SELECTION : {show: y, blk : 0, word: 4, pos : 8, len : 1, start: 136, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict: '{0: "VDD3P3_CPU", 1: "VDD_SPI"}', desc: Set default power supply for GPIO33-GPIO37; set when SPI flash is initialized, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[8]', bloc: 'B17[0]'} + FLASH_TYPE : {show: y, blk : 0, word: 4, pos : 9, len : 1, start: 137, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict: '{0: "4 data lines", 1: "8 data lines"}', desc: SPI flash type, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[9]', bloc: 'B17[1]'} + FLASH_PAGE_SIZE : {show: y, blk : 0, word: 4, pos: 10, len : 2, start: 138, type : 'uint:2', wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Set Flash page size, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[11:10]', bloc: 'B17[3:2]'} + FLASH_ECC_EN : {show: y, blk : 0, word: 4, pos: 12, len : 1, start: 140, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Set 1 to enable ECC for flash boot, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[12]', bloc: 'B17[4]'} + FORCE_SEND_RESUME : {show: y, blk : 0, word: 4, pos: 13, len : 1, start: 141, type : bool, wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Set this bit to force ROM code to send a resume command during SPI boot, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[13]', bloc: 'B17[5]'} + SECURE_VERSION : {show: y, blk : 0, word: 4, pos: 14, len : 16, start: 142, type : 'uint:16', wr_dis : 18, rd_dis: null, alt : '', dict : '', desc: Secure version (used by ESP-IDF anti-rollback feature), rloc: 'EFUSE_RD_REPEAT_DATA3_REG[29:14]', bloc: 'B17[7:6],B18,B19[5:0]'} + POWERGLITCH_EN : {show: n, blk : 0, word: 4, pos: 30, len : 1, start: 158, type : bool, wr_dis : 17, rd_dis: null, alt : '', dict : '', desc: Set this bit to enable power glitch function, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[30]', bloc: 'B19[6]'} + DIS_USB_OTG_DOWNLOAD_MODE : {show: y, blk : 0, word: 4, pos: 31, len : 1, start: 159, type : bool, wr_dis : 19, rd_dis: null, alt : '', dict : '', desc: Set this bit to disable download through USB-OTG, rloc: 'EFUSE_RD_REPEAT_DATA3_REG[31]', bloc: 'B19[7]'} + DISABLE_WAFER_VERSION_MAJOR : {show: y, blk : 0, word: 5, pos : 0, len : 1, start: 160, type : bool, wr_dis : 19, rd_dis: null, alt : '', dict : '', desc: Disables check of wafer version major, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[0]', bloc: 'B20[0]'} + DISABLE_BLK_VERSION_MAJOR : {show: y, blk : 0, word: 5, pos : 1, len : 1, start: 161, type : bool, wr_dis : 19, rd_dis: null, alt : '', dict : '', desc: Disables check of blk version major, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[1]', bloc: 'B20[1]'} + RESERVED_0_162 : {show: n, blk : 0, word: 5, pos : 2, len : 22, start: 162, type : 'uint:22', wr_dis: null, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_REPEAT_DATA4_REG[23:2]', bloc: 'B20[7:2],B21,B22'} + 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_SPI_SYS_0_REG, bloc: 'B0,B1,B2,B3,B4,B5'} + SPI_PAD_CONFIG_CLK : {show: y, blk : 1, word: 1, pos: 16, len : 6, start : 48, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure CLK, rloc: 'EFUSE_RD_MAC_SPI_SYS_1_REG[21:16]', bloc: 'B6[5:0]'} + SPI_PAD_CONFIG_Q : {show: y, blk : 1, word: 1, pos: 22, len : 6, start : 54, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure Q(D1), rloc: 'EFUSE_RD_MAC_SPI_SYS_1_REG[27:22]', bloc: 'B6[7:6],B7[3:0]'} + SPI_PAD_CONFIG_D : {show: y, blk : 1, word: 1, pos: 28, len : 6, start : 60, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D(D0), rloc: 'EFUSE_RD_MAC_SPI_SYS_1_REG[31:28]', bloc: 'B7[7:4],B8[1:0]'} + SPI_PAD_CONFIG_CS : {show: y, blk : 1, word: 2, pos : 2, len : 6, start : 66, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure CS, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[7:2]', bloc: 'B8[7:2]'} + SPI_PAD_CONFIG_HD : {show: y, blk : 1, word: 2, pos : 8, len : 6, start : 72, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure HD(D3), rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[13:8]', bloc: 'B9[5:0]'} + SPI_PAD_CONFIG_WP : {show: y, blk : 1, word: 2, pos: 14, len : 6, start : 78, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure WP(D2), rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[19:14]', bloc: 'B9[7:6],B10[3:0]'} + SPI_PAD_CONFIG_DQS : {show: y, blk : 1, word: 2, pos: 20, len : 6, start : 84, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure DQS, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[25:20]', bloc: 'B10[7:4],B11[1:0]'} + SPI_PAD_CONFIG_D4 : {show: y, blk : 1, word: 2, pos: 26, len : 6, start : 90, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D4, rloc: 'EFUSE_RD_MAC_SPI_SYS_2_REG[31:26]', bloc: 'B11[7:2]'} + SPI_PAD_CONFIG_D5 : {show: y, blk : 1, word: 3, pos : 0, len : 6, start : 96, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D5, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[5:0]', bloc: 'B12[5:0]'} + SPI_PAD_CONFIG_D6 : {show: y, blk : 1, word: 3, pos : 6, len : 6, start: 102, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D6, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[11:6]', bloc: 'B12[7:6],B13[3:0]'} + SPI_PAD_CONFIG_D7 : {show: y, blk : 1, word: 3, pos: 12, len : 6, start: 108, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: SPI_PAD_configure D7, rloc: 'EFUSE_RD_MAC_SPI_SYS_3_REG[17:12]', bloc: 'B13[7:4],B14[1:0]'} + 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]'} + 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]'} + V_DIG_DBIAS20 : {show: y, blk : 1, word: 5, pos : 3, len : 8, start: 163, type : 'uint:8', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 voltage of digital dbias20, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[10:3]', bloc: 'B20[7:3],B21[2:0]'} + DIG_DBIAS_HVT : {show: y, blk : 1, word: 5, pos: 11, len : 5, start: 171, type : 'uint:5', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: BLOCK1 digital dbias when hvt, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[15:11]', bloc: 'B21[7:3]'} + RESERVED_1_176 : {show: n, blk : 1, word: 5, pos: 16, len : 7, start: 176, type : 'uint:7', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[22:16]', bloc: 'B22[6:0]'} + WAFER_VERSION_MINOR_HI : {show: y, blk : 1, word: 5, pos: 23, len : 1, start: 183, type : bool, wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MINOR most significant bit, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[23]', bloc: 'B22[7]'} + WAFER_VERSION_MAJOR : {show: y, blk : 1, word: 5, pos: 24, len : 2, start: 184, type : 'uint:2', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: WAFER_VERSION_MAJOR, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[25:24]', bloc: 'B23[1:0]'} + ADC2_CAL_VOL_ATTEN3 : {show: y, blk : 1, word: 5, pos: 26, len : 6, start: 186, type : 'uint:6', wr_dis : 20, rd_dis: null, alt : '', dict : '', desc: ADC2 calibration voltage at atten3, rloc: 'EFUSE_RD_MAC_SPI_SYS_5_REG[31:26]', bloc: 'B23[7:2]'} + OPTIONAL_UNIQUE_ID : {show: y, blk : 2, word: 0, pos : 0, len: 128, start : 0, type: 'bytes:16', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Optional unique 128-bit ID, rloc: EFUSE_RD_SYS_PART1_DATA0_REG, bloc: 'B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15'} + BLK_VERSION_MAJOR : {show: y, blk : 2, word: 4, pos : 0, len : 2, start: 128, type : 'uint:2', wr_dis : 21, rd_dis: null, alt : '', dict: '{0: "No calib", 1: "ADC calib V1"}', desc: BLK_VERSION_MAJOR of BLOCK2, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[1:0]', bloc: 'B16[1:0]'} + RESERVED_2_130 : {show: n, blk : 2, word: 4, pos : 2, len : 2, start: 130, type : 'uint:2', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[3:2]', bloc: 'B16[3:2]'} + TEMP_CALIB : {show: y, blk : 2, word: 4, pos : 4, len : 9, start: 132, type : 'uint:9', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: Temperature calibration data, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[12:4]', bloc: 'B16[7:4],B17[4:0]'} + OCODE : {show: y, blk : 2, word: 4, pos: 13, len : 8, start: 141, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC OCode, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[20:13]', bloc: 'B17[7:5],B18[4:0]'} + ADC1_INIT_CODE_ATTEN0 : {show: y, blk : 2, word: 4, pos: 21, len : 8, start: 149, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten0, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[28:21]', bloc: 'B18[7:5],B19[4:0]'} + ADC1_INIT_CODE_ATTEN1 : {show: y, blk : 2, word: 4, pos: 29, len : 6, start: 157, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten1, rloc: 'EFUSE_RD_SYS_PART1_DATA4_REG[31:29]', bloc: 'B19[7:5],B20[2:0]'} + ADC1_INIT_CODE_ATTEN2 : {show: y, blk : 2, word: 5, pos : 3, len : 6, start: 163, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten2, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[8:3]', bloc: 'B20[7:3],B21[0]'} + ADC1_INIT_CODE_ATTEN3 : {show: y, blk : 2, word: 5, pos : 9, len : 6, start: 169, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 init code at atten3, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[14:9]', bloc: 'B21[6:1]'} + ADC2_INIT_CODE_ATTEN0 : {show: y, blk : 2, word: 5, pos: 15, len : 8, start: 175, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC2 init code at atten0, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[22:15]', bloc: 'B21[7],B22[6:0]'} + ADC2_INIT_CODE_ATTEN1 : {show: y, blk : 2, word: 5, pos: 23, len : 6, start: 183, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC2 init code at atten1, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[28:23]', bloc: 'B22[7],B23[4:0]'} + ADC2_INIT_CODE_ATTEN2 : {show: y, blk : 2, word: 5, pos: 29, len : 6, start: 189, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC2 init code at atten2, rloc: 'EFUSE_RD_SYS_PART1_DATA5_REG[31:29]', bloc: 'B23[7:5],B24[2:0]'} + ADC2_INIT_CODE_ATTEN3 : {show: y, blk : 2, word: 6, pos : 3, len : 6, start: 195, type : 'uint:6', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC2 init code at atten3, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[8:3]', bloc: 'B24[7:3],B25[0]'} + ADC1_CAL_VOL_ATTEN0 : {show: y, blk : 2, word: 6, pos : 9, len : 8, start: 201, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten0, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[16:9]', bloc: 'B25[7:1],B26[0]'} + ADC1_CAL_VOL_ATTEN1 : {show: y, blk : 2, word: 6, pos: 17, len : 8, start: 209, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten1, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[24:17]', bloc: 'B26[7:1],B27[0]'} + ADC1_CAL_VOL_ATTEN2 : {show: y, blk : 2, word: 6, pos: 25, len : 8, start: 217, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten2, rloc: 'EFUSE_RD_SYS_PART1_DATA6_REG[31:25]', bloc: 'B27[7:1],B28[0]'} + ADC1_CAL_VOL_ATTEN3 : {show: y, blk : 2, word: 7, pos : 1, len : 8, start: 225, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC1 calibration voltage at atten3, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[8:1]', bloc: 'B28[7:1],B29[0]'} + ADC2_CAL_VOL_ATTEN0 : {show: y, blk : 2, word: 7, pos : 9, len : 8, start: 233, type : 'uint:8', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC2 calibration voltage at atten0, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[16:9]', bloc: 'B29[7:1],B30[0]'} + ADC2_CAL_VOL_ATTEN1 : {show: y, blk : 2, word: 7, pos: 17, len : 7, start: 241, type : 'uint:7', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC2 calibration voltage at atten1, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[23:17]', bloc: 'B30[7:1]'} + ADC2_CAL_VOL_ATTEN2 : {show: y, blk : 2, word: 7, pos: 24, len : 7, start: 248, type : 'uint:7', wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: ADC2 calibration voltage at atten2, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[30:24]', bloc: 'B31[6:0]'} + RESERVED_2_255 : {show: n, blk : 2, word: 7, pos: 31, len : 1, start: 255, type : bool, wr_dis : 21, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_SYS_PART1_DATA7_REG[31]', bloc: 'B31[7]'} + 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'} + RESERVED_3_248 : {show: n, blk : 3, word: 7, pos: 24, len : 8, start: 248, type : 'uint:8', wr_dis : 22, rd_dis: null, alt : '', dict : '', desc: reserved, rloc: 'EFUSE_RD_USR_DATA7_REG[31:24]', bloc: 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 --git a/espsecure.py b/espsecure.py index c58eabf15..29b8e48e8 100755 --- a/espsecure.py +++ b/espsecure.py @@ -18,9 +18,12 @@ # Linux/macOS: remove current script directory to avoid importing this file # as a module; we want to import the installed espsecure module instead with contextlib.suppress(ValueError): - if sys.path[0].endswith("/bin"): - sys.path.pop(0) - sys.path.remove(os.path.dirname(sys.executable)) + executable_dir = os.path.dirname(sys.executable) + sys.path = [ + path + for path in sys.path + if not path.endswith(("/bin", "/sbin")) and path != executable_dir + ] # Linux/macOS: delete imported module entry to force Python to load # the module from scratch; this enables importing espsecure module in diff --git a/espsecure/__init__.py b/espsecure/__init__.py index 73656f5ea..3e5ef2039 100755 --- a/espsecure/__init__.py +++ b/espsecure/__init__.py @@ -200,9 +200,23 @@ def generate_signing_key(args): ) +def load_ecdsa_signing_key(keyfile): + """Load ECDSA signing key""" + try: + sk = ecdsa.SigningKey.from_pem(keyfile.read()) + except ValueError: + raise esptool.FatalError( + "Incorrect ECDSA private key specified. " + "Please check algorithm and/or format." + ) + if sk.curve not in [ecdsa.NIST192p, ecdsa.NIST256p]: + raise esptool.FatalError("Supports NIST192p and NIST256p keys only") + return sk + + def _load_ecdsa_signing_key(keyfile): """Load ECDSA signing key for Secure Boot V1 only""" - sk = ecdsa.SigningKey.from_pem(keyfile.read()) + sk = load_ecdsa_signing_key(keyfile) if sk.curve != ecdsa.NIST256p: raise esptool.FatalError( "Signing key uses incorrect curve. ESP32 Secure Boot only supports " @@ -213,7 +227,13 @@ def _load_ecdsa_signing_key(keyfile): def _load_ecdsa_verifying_key(keyfile): """Load ECDSA verifying key for Secure Boot V1 only""" - vk = ecdsa.VerifyingKey.from_pem(keyfile.read()) + try: + vk = ecdsa.VerifyingKey.from_pem(keyfile.read()) + except ValueError: + raise esptool.FatalError( + "Incorrect ECDSA public key specified. " + "Please check algorithm and/or format." + ) if vk.curve != ecdsa.NIST256p: raise esptool.FatalError( "Signing key uses incorrect curve. ESP32 Secure Boot only supports " @@ -1637,7 +1657,8 @@ def main(custom_commandline=None): p = subparsers.add_parser( "digest_private_key", help="Generate an SHA-256 digest of the private signing key. " - "This can be used as a reproducible secure bootloader or flash encryption key.", + "This can be used as a reproducible secure bootloader (only secure boot v1) " + "or flash encryption key.", ) p.add_argument( "--keyfile", @@ -1691,7 +1712,7 @@ def main(custom_commandline=None): "--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( @@ -1731,7 +1752,7 @@ def main(custom_commandline=None): "--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( @@ -1791,6 +1812,16 @@ def _main(): except esptool.FatalError as e: print("\nA fatal error occurred: %s" % e) sys.exit(2) + except ValueError as e: + try: + if [arg for arg in e.args if "Could not deserialize key data." in arg]: + print( + "Note: This error originates from the cryptography module. " + "It is likely not a problem with espsecure, " + "please make sure you are using a compatible OpenSSL backend." + ) + finally: + raise if __name__ == "__main__": diff --git a/espsecure/esp_hsm_sign/__init__.py b/espsecure/esp_hsm_sign/__init__.py index baf88241a..d255116ad 100644 --- a/espsecure/esp_hsm_sign/__init__.py +++ b/espsecure/esp_hsm_sign/__init__.py @@ -6,6 +6,7 @@ import configparser import os import sys +from getpass import getpass try: import pkcs11 @@ -31,11 +32,17 @@ def read_hsm_config(configfile): 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 --git a/esptool.py b/esptool.py index 60e5bd339..ee3fdc90f 100755 --- a/esptool.py +++ b/esptool.py @@ -18,9 +18,12 @@ # Linux/macOS: remove current script directory to avoid importing this file # as a module; we want to import the installed esptool module instead with contextlib.suppress(ValueError): - if sys.path[0].endswith("/bin"): - sys.path.pop(0) - sys.path.remove(os.path.dirname(sys.executable)) + executable_dir = os.path.dirname(sys.executable) + sys.path = [ + path + for path in sys.path + if not path.endswith(("/bin", "/sbin")) and path != executable_dir + ] # Linux/macOS: delete imported module entry to force Python to load # the module from scratch; this enables importing esptool module in diff --git a/esptool/__init__.py b/esptool/__init__.py index 88a021813..206b6fadd 100644 --- a/esptool/__init__.py +++ b/esptool/__init__.py @@ -28,7 +28,7 @@ "write_mem", ] -__version__ = "4.6-dev" +__version__ = "4.7-dev" import argparse import inspect @@ -38,7 +38,9 @@ import time import traceback +from esptool.bin_image import intel_hex_to_bin from esptool.cmds import ( + DETECTED_FLASH_SIZES, chip_id, detect_chip, detect_flash_size, @@ -184,7 +186,9 @@ def add_spi_connection_arg(parent): 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" @@ -354,9 +358,11 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect): subparsers.add_parser("run", help="Run application code in flash") parser_image_info = subparsers.add_parser( - "image_info", help="Dump headers from an application image" + "image_info", help="Dump headers from a binary file (bootloader or application)" + ) + parser_image_info.add_argument( + "filename", help="Image file to parse", action=AutoHex2BinAction ) - parser_image_info.add_argument("filename", help="Image file to parse") parser_image_info.add_argument( "--version", "-v", @@ -476,6 +482,17 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect): "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) @@ -526,7 +543,9 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect): add_spi_connection_arg(parser_read_flash) parser_read_flash.add_argument("address", help="Start address", type=arg_auto_int) parser_read_flash.add_argument( - "size", help="Size of region to dump", type=arg_auto_int + "size", + help="Size of region to dump. Use `ALL` to read to the end of flash.", + type=arg_auto_size, ) parser_read_flash.add_argument("filename", help="Name of binary dump") parser_read_flash.add_argument( @@ -570,8 +589,9 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect): ) parser_erase_region.add_argument( "size", - help="Size of region to erase (must be multiple of 4096)", - type=arg_auto_int, + help="Size of region to erase (must be multiple of 4096). " + "Use `ALL` to erase to the end of flash.", + type=arg_auto_size, ) parser_merge_bin = subparsers.add_parser( @@ -583,18 +603,36 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect): "--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.", @@ -709,7 +747,16 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect): ) args.no_stub = True else: - esp = esp.run_stub() + try: + esp = esp.run_stub() + except Exception: + # The CH9102 bridge (PID: 0x55D4) can have issues on MacOS + if sys.platform == "darwin" and esp._get_pid() == 0x55D4: + print( + "\nNote: If issues persist, " + "try installing the WCH USB-to-Serial MacOS driver." + ) + raise if args.override_vddsdio: esp.override_vddsdio(args.override_vddsdio) @@ -811,18 +858,45 @@ def flash_xmc_startup(): if hasattr(args, "flash_size"): print("Configuring flash size...") - detect_flash_size(esp, args) - if args.flash_size != "keep": # TODO: should set this even with 'keep' - esp.flash_set_parameters(flash_size_bytes(args.flash_size)) + if args.flash_size == "detect": + flash_size = detect_flash_size(esp, args) + elif args.flash_size == "keep": + flash_size = detect_flash_size(esp, args=None) + else: + flash_size = args.flash_size + + 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 args.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." ) + if getattr(args, "size", "") == "all": + if esp.secure_download_mode: + raise FatalError( + "Detecting flash size is not supported in secure download mode. " + "Set an exact size value." + ) + # detect flash size + flash_id = esp.flash_id() + size_id = flash_id >> 16 + size_str = DETECTED_FLASH_SIZES.get(size_id) + if size_str is None: + raise FatalError( + "Detecting flash size failed. Set an exact size value." + ) + print(f"Detected flash size: {size_str}") + 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." @@ -865,6 +939,18 @@ def arg_auto_int(x): return int(x, 0) +def arg_auto_size(x): + x = x.lower() + 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( @@ -893,7 +979,7 @@ def expand_file_arguments(argv): 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 @@ -976,6 +1062,20 @@ def __call__(self, parser, namespace, value, option_string=None): setattr(namespace, self.dest, value) +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) + + class AddrFilenamePairAction(argparse.Action): """Custom parser class for the address/filename pairs passed as arguments""" @@ -1004,6 +1104,8 @@ def __call__(self, parser, namespace, values, option_string=None): "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 --git a/esptool/bin_image.py b/esptool/bin_image.py index b001a1eae..b011b55b5 100644 --- a/esptool/bin_image.py +++ b/esptool/bin_image.py @@ -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 @@ def align_file_position(f, size): 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 @@ def select_image_class(f, chip): "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 @@ def save_segment(self, f, segment, checksum=None): 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 @@ class ESP32FirmwareImage(BaseFirmwareImage): 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 @@ def __init__(self, load_file=None, append_digest=True): 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,14 +670,24 @@ def save(self, filename): 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 + # For the bootloader image + # move ".dram0.bootdesc" segment to the top of the ram segment + # So bootdesc will be at the very top of the binary at 0x20 offset + # (in the first segment). + for segment in ram_segments: + if segment.name == ".dram0.bootdesc": + ram_segments.remove(segment) + ram_segments.insert(0, segment) + break + # check for multiple ELF sections that are mapped in the same # flash mapping region. This is usually a sign of a broken linker script, # but if you have a legitimate use case then let us know @@ -675,33 +723,61 @@ def get_alignment_data_needed(segment): 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. @@ -733,8 +809,9 @@ def get_alignment_data_needed(segment): 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: @@ -743,7 +820,12 @@ def get_alignment_data_needed(segment): # 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 @@ -761,19 +843,6 @@ def get_alignment_data_needed(segment): 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) @@ -803,13 +872,6 @@ def split_byte(n): self.min_rev_full = fields[6] self.max_rev_full = fields[7] - # reserved fields in the middle should all be zero - if any(f for f in fields[8:-1] if f != 0): - print( - "Warning: some reserved header fields have non-zero values. " - "This image may be from a newer esptool.py?" - ) - append_digest = fields[-1] # last byte is append_digest if append_digest in [0, 1]: self.append_digest = append_digest == 1 @@ -1052,6 +1114,15 @@ def set_mmu_page_size(self, size): 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""" diff --git a/esptool/cmds.py b/esptool/cmds.py index 26416eae1..3a6f914e0 100644 --- a/esptool/cmds.py +++ b/esptool/cmds.py @@ -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, @@ -34,6 +37,7 @@ from .util import ( div_roundup, flash_size_bytes, + get_file_size, hexify, pad_to, print_overwrite, @@ -95,7 +99,7 @@ def detect_chip( 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: @@ -107,6 +111,9 @@ def detect_chip( except UnsupportedCommandError: inst.secure_download_mode = True inst._post_connect() + break + else: + err_msg = f"Unexpected chip ID value {chip_id}." except (UnsupportedCommandError, struct.error, FatalError) as e: # UnsupportedCommmanddError: ESP8266/ESP32 ROM # struct.error: ESP32-S2 @@ -130,6 +137,9 @@ def detect_chip( inst = cls(detect_port._port, baud, trace_enabled=trace_enabled) inst._post_connect() inst.check_chip_id() + break + else: + err_msg = f"Unexpected chip magic value {chip_magic_value:#010x}." except UnsupportedCommandError: raise FatalError( "Unsupported Command Error received. " @@ -145,8 +155,8 @@ def detect_chip( print("") # end line return inst raise FatalError( - "Unexpected CHIP magic value 0x%08x. Failed to autodetect chip type." - % (chip_magic_value) + f"{err_msg} Failed to autodetect chip type." + "\nProbably it is unsupported by this version of esptool." ) @@ -202,24 +212,30 @@ def dump_mem(esp, args): print("Done!") -def detect_flash_size(esp, args): - if args.flash_size == "detect": - if esp.secure_download_mode: +def detect_flash_size(esp, args=None): + # TODO: Remove the dependency on args in the next major release (v5.0) + if esp.secure_download_mode: + if args is not None and args.flash_size == "detect": raise FatalError( "Detecting flash size is not supported in secure download mode. " "Need to manually specify flash size." ) - flash_id = esp.flash_id() - size_id = flash_id >> 16 - args.flash_size = DETECTED_FLASH_SIZES.get(size_id) - if args.flash_size is None: + else: + return None + flash_id = esp.flash_id() + size_id = flash_id >> 16 + flash_size = DETECTED_FLASH_SIZES.get(size_id) + if args is not None and args.flash_size == "detect": + if flash_size is None: + flash_size = "4MB" print( - "Warning: Could not auto-detect Flash size (FlashID=0x%x, SizeID=0x%x)," - " defaulting to 4MB" % (flash_id, size_id) + "Warning: Could not auto-detect Flash size " + f"(FlashID={flash_id:#x}, SizeID={size_id:#x}), defaulting to 4MB" ) - args.flash_size = "4MB" else: - print("Auto-detected Flash size:", args.flash_size) + print("Auto-detected Flash size:", flash_size) + args.flash_size = flash_size + return flash_size def _update_image_flash_params(esp, address, args, image): @@ -450,8 +466,10 @@ def write_flash(esp, args): ) # verify file sizes fit in flash - if args.flash_size != "keep": # TODO: check this even with 'keep' - flash_end = flash_size_bytes(args.flash_size) + flash_end = flash_size_bytes( + detect_flash_size(esp) if args.flash_size == "keep" else args.flash_size + ) + 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: @@ -723,7 +741,10 @@ def get_key_from_value(dict, val): title = "{} extended image header".format(args.chip.upper()) print(title) print("=" * len(title)) - print("WP pin: {:#02x}".format(image.wp_pin)) + print( + f"WP pin: {image.wp_pin:#02x}", + *["(disabled)"] if image.wp_pin == image.WP_PIN_DISABLED else [], + ) print( "Flash pins drive settings: " "clk_drv: {:#02x}, q_drv: {:#02x}, d_drv: {:#02x}, " @@ -736,7 +757,15 @@ def get_key_from_value(dict, val): image.wp_drv, ) ) - print("Chip ID: {}".format(image.chip_id)) + try: + chip = next( + chip + for chip in CHIP_DEFS.values() + if getattr(chip, "IMAGE_CHIP_ID", None) == image.chip_id + ) + print(f"Chip ID: {image.chip_id} ({chip.CHIP_NAME})") + except StopIteration: + print(f"Chip ID: {image.chip_id} (Unknown ID)") print( "Minimal chip revision: " f"v{image.min_rev_full // 100}.{image.min_rev_full % 100}, " @@ -763,11 +792,16 @@ def get_key_from_value(dict, val): ) format_str = "{:7} {:#07x} {:#010x} {:#010x} {}" app_desc = None + bootloader_desc = None for idx, seg in enumerate(image.segments, start=1): segs = seg.get_memory_type(image) seg_name = ", ".join(segs) if "DROM" in segs: # The DROM segment starts with the esp_app_desc_t struct app_desc = seg.data[:256] + elif "DRAM" in segs: + # The DRAM segment starts with the esp_bootloader_desc_t struct + if len(seg.data) >= 80: + bootloader_desc = seg.data[:80] print( format_str.format(idx, len(seg.data), seg.addr, seg.file_offs, seg_name) ) @@ -825,6 +859,27 @@ def get_key_from_value(dict, val): print(f'ESP-IDF: {idf_ver.decode("utf-8")}') print(f"Secure version: {secure_version}") + elif bootloader_desc: + BOOTLOADER_DESC_STRUCT_FMT = " 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): @@ -1145,9 +1287,9 @@ def merge_bin(args): 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. @@ -1158,31 +1300,57 @@ def merge_bin(args): 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: + 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())) + 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 --git a/esptool/loader.py b/esptool/loader.py index eb6402369..bd1fcbab2 100644 --- a/esptool/loader.py +++ b/esptool/loader.py @@ -97,13 +97,13 @@ # Number of times to try writing a data block WRITE_BLOCK_ATTEMPTS = cfg.getint("write_block_attempts", 3) -STUBS_DIR = os.path.join(os.path.dirname(__file__), "./targets/stub_flasher/") +STUBS_DIR = os.path.join(os.path.dirname(__file__), "targets", "stub_flasher") def get_stub_json_path(chip_name): chip_name = strip_chip_name(chip_name) chip_name = chip_name.replace("esp", "") - return STUBS_DIR + "stub_flasher_" + chip_name + ".json" + return os.path.join(STUBS_DIR, f"stub_flasher_{chip_name}.json") def timeout_per_mb(seconds_per_mb, size_bytes): @@ -184,8 +184,6 @@ class ESPLoader(object): CHIP_NAME = "Espressif device" IS_STUB = False - FPGA_SLOW_BOOT = False - DEFAULT_PORT = "/dev/ttyUSB0" USES_RFC2217 = False @@ -295,13 +293,45 @@ def __init__(self, port=DEFAULT_PORT, baud=ESP_ROM_BAUD, trace_enabled=False): "flash_id": None, "chip_id": None, "uart_no": None, + "usb_pid": None, } 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) @@ -475,6 +505,9 @@ def sync(self): self.sync_stub_detected &= val == 0 def _get_pid(self): + if self.cache["usb_pid"] is not None: + return self.cache["usb_pid"] + if list_ports is None: print( "\nListing all serial ports is currently not available. " @@ -494,16 +527,19 @@ def _get_pid(self): if active_port.startswith("/dev/") and os.path.islink(active_port): active_port = os.path.realpath(active_port) + active_ports = [active_port] + # The "cu" (call-up) device has to be used for outgoing communication on MacOS if sys.platform == "darwin" and "tty" in active_port: - active_port = [active_port, active_port.replace("tty", "cu")] + active_ports.append(active_port.replace("tty", "cu")) ports = list_ports.comports() for p in ports: - if p.device in active_port: + if p.device in active_ports: + self.cache["usb_pid"] = p.pid return p.pid print( - "\nFailed to get PID of a device on {}, " - "using standard reset sequence.".format(active_port) + f"\nFailed to get PID of a device on {active_port}, " + "using standard reset sequence." ) def _connect_attempt(self, reset_strategy, mode="default_reset"): @@ -590,7 +626,7 @@ def _construct_reset_strategy_sequence(self, mode): # 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 diff --git a/esptool/targets/__init__.py b/esptool/targets/__init__.py index 9d76ca543..dd1ba485d 100644 --- a/esptool/targets/__init__.py +++ b/esptool/targets/__init__.py @@ -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 --git a/esptool/targets/esp32.py b/esptool/targets/esp32.py index 67cbc17b3..3444944d7 100644 --- a/esptool/targets/esp32.py +++ b/esptool/targets/esp32.py @@ -17,8 +17,6 @@ class ESP32ROM(ESPLoader): IMAGE_CHIP_ID = 0 IS_STUB = False - FPGA_SLOW_BOOT = True - CHIP_DETECT_MAGIC_VALUE = [0x00F01D83] IROM_MAP_START = 0x400D0000 @@ -105,6 +103,8 @@ class ESP32ROM(ESPLoader): 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): @@ -284,8 +284,10 @@ def read_efuse(self, n): def chip_id(self): raise NotSupportedError(self, "chip_id") - def read_mac(self): + def read_mac(self, mac_type="BASE_MAC"): """Read MAC from EFUSE region""" + if mac_type != "BASE_MAC": + return None words = [self.read_efuse(2), self.read_efuse(1)] bitstring = struct.pack(">II", *words) bitstring = bitstring[2:8] # trim the 2 byte CRC @@ -360,6 +362,7 @@ def get_rom_cal_crystal_freq(self): 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 diff --git a/esptool/targets/esp32c2.py b/esptool/targets/esp32c2.py index f70d4a826..ff8341869 100644 --- a/esptool/targets/esp32c2.py +++ b/esptool/targets/esp32c2.py @@ -61,6 +61,8 @@ class ESP32C2ROM(ESP32C3ROM): [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 @@ -110,7 +112,7 @@ def change_baud(self, baud): 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 diff --git a/esptool/targets/esp32c3.py b/esptool/targets/esp32c3.py index 3db0dea74..47191b0c2 100644 --- a/esptool/targets/esp32c3.py +++ b/esptool/targets/esp32c3.py @@ -14,8 +14,6 @@ class ESP32C3ROM(ESP32ROM): 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 @@ class ESP32C3ROM(ESP32ROM): 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 @@ -75,10 +73,15 @@ class ESP32C3ROM(ESP32ROM): UARTDEV_BUF_NO = 0x3FCDF07C # Variable in ROM .bss which indicates the port in use UARTDEV_BUF_NO_USB_JTAG_SERIAL = 3 # The above var when USB-JTAG/Serial is used - RTC_CNTL_WDT_WKEY = 0x50D83AA1 RTCCNTL_BASE_REG = 0x60008000 + RTC_CNTL_SWD_CONF_REG = RTCCNTL_BASE_REG + 0x00AC + RTC_CNTL_SWD_AUTO_FEED_EN = 1 << 31 + RTC_CNTL_SWD_WPROTECT_REG = RTCCNTL_BASE_REG + 0x00B0 + RTC_CNTL_SWD_WKEY = 0x8F1D312A + RTC_CNTL_WDTCONFIG0_REG = RTCCNTL_BASE_REG + 0x0090 RTC_CNTL_WDTWPROTECT_REG = RTCCNTL_BASE_REG + 0x00A8 + RTC_CNTL_WDT_WKEY = 0x50D83AA1 MEMORY_MAP = [ [0x00000000, 0x00010000, "PADDING"], @@ -94,6 +97,8 @@ class ESP32C3ROM(ESP32ROM): [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 @@ -109,16 +114,39 @@ def get_major_chip_version(self): 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 @@ -129,7 +157,10 @@ def override_vddsdio(self, new_voltage): "VDD_SDIO overrides are not supported for ESP32-C3" ) - def read_mac(self): + 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:] @@ -175,17 +206,27 @@ def uses_usb_jtag_serial(self): return False # Can't detect USB-JTAG/Serial in secure download mode return self.get_uart_no() == self.UARTDEV_BUF_NO_USB_JTAG_SERIAL - def disable_rtc_watchdog(self): - # When USB-JTAG/Serial is used, the RTC watchdog is not reset - # and can then reset the board during flashing. Disable it. + def disable_watchdogs(self): + # When USB-JTAG/Serial is used, the RTC WDT and SWD watchdog are not reset + # and can then reset the board during flashing. Disable or autofeed them. if self.uses_usb_jtag_serial(): + # Disable RTC WDT self.write_reg(self.RTC_CNTL_WDTWPROTECT_REG, self.RTC_CNTL_WDT_WKEY) self.write_reg(self.RTC_CNTL_WDTCONFIG0_REG, 0) self.write_reg(self.RTC_CNTL_WDTWPROTECT_REG, 0) + # Automatically feed SWD + self.write_reg(self.RTC_CNTL_SWD_WPROTECT_REG, self.RTC_CNTL_SWD_WKEY) + self.write_reg( + self.RTC_CNTL_SWD_CONF_REG, + self.read_reg(self.RTC_CNTL_SWD_CONF_REG) + | self.RTC_CNTL_SWD_AUTO_FEED_EN, + ) + self.write_reg(self.RTC_CNTL_SWD_WPROTECT_REG, 0) + def _post_connect(self): if not self.sync_stub_detected: # Don't run if stub is reused - self.disable_rtc_watchdog() + self.disable_watchdogs() class ESP32C3StubLoader(ESP32C3ROM): diff --git a/esptool/targets/esp32c6.py b/esptool/targets/esp32c6.py index 0c4575ebf..c18bf9d1f 100644 --- a/esptool/targets/esp32c6.py +++ b/esptool/targets/esp32c6.py @@ -13,8 +13,6 @@ class ESP32C6ROM(ESP32C3ROM): CHIP_NAME = "ESP32-C6" IMAGE_CHIP_ID = 13 - FPGA_SLOW_BOOT = False - IROM_MAP_START = 0x42000000 IROM_MAP_END = 0x42800000 DROM_MAP_START = 0x42800000 @@ -76,6 +74,11 @@ class ESP32C6ROM(ESP32C3ROM): RTC_CNTL_WDTCONFIG0_REG = DR_REG_LP_WDT_BASE + 0x0 # LP_WDT_RWDT_CONFIG0_REG RTC_CNTL_WDTWPROTECT_REG = DR_REG_LP_WDT_BASE + 0x0018 # LP_WDT_RWDT_WPROTECT_REG + RTC_CNTL_SWD_CONF_REG = DR_REG_LP_WDT_BASE + 0x001C # LP_WDT_SWD_CONFIG_REG + RTC_CNTL_SWD_AUTO_FEED_EN = 1 << 18 + RTC_CNTL_SWD_WPROTECT_REG = DR_REG_LP_WDT_BASE + 0x0020 # LP_WDT_SWD_WPROTECT_REG + RTC_CNTL_SWD_WKEY = 0x50D83AA1 # LP_WDT_SWD_WKEY, same as WDT key in this case + FLASH_FREQUENCY = { "80m": 0x0, # workaround for wrong mspi HS div value in ROM "40m": 0x0, @@ -96,24 +99,24 @@ class ESP32C6ROM(ESP32C3ROM): [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)) >> 21) & 0x07 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x07 def get_minor_chip_version(self): - hi_num_word = 5 - hi = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * hi_num_word)) >> 23) & 0x01 - low_num_word = 3 - low = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * low_num_word)) >> 18) & 0x07 - return (hi << 3) + low + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 18) & 0x0F def get_major_chip_version(self): - num_word = 5 - return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x03 + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 22) & 0x03 def get_chip_description(self): chip_name = { - 0: "ESP32-C6", + 0: "ESP32-C6 (QFN40)", + 1: "ESP32-C6FH4 (QFN32)", }.get(self.get_pkg_version(), "unknown ESP32-C6") major_rev = self.get_major_chip_version() minor_rev = self.get_minor_chip_version() @@ -131,11 +134,22 @@ def override_vddsdio(self, new_voltage): "VDD_SDIO overrides are not supported for ESP32-C6" ) - def read_mac(self): + def read_mac(self, mac_type="BASE_MAC"): + """Read MAC from EFUSE region""" 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) + base_mac = struct.pack(">II", mac1, mac0)[2:] + ext_mac = struct.pack(">H", (mac1 >> 16) & 0xFFFF) + eui64 = base_mac[0:3] + ext_mac + base_mac[3:6] + # BASE MAC: 60:55:f9:f7:2c:a2 + # EUI64 MAC: 60:55:f9:ff:fe:f7:2c:a2 + # EXT_MAC: ff:fe + macs = { + "BASE_MAC": tuple(base_mac), + "EUI64": tuple(eui64), + "MAC_EXT": tuple(ext_mac), + } + return macs.get(mac_type, None) def get_flash_crypt_config(self): return None # doesn't exist on ESP32-C6 diff --git a/esptool/targets/esp32c6beta.py b/esptool/targets/esp32c6beta.py index 4c4b6bebd..b6e100bb4 100644 --- a/esptool/targets/esp32c6beta.py +++ b/esptool/targets/esp32c6beta.py @@ -16,7 +16,8 @@ class ESP32C6BETAROM(ESP32C3ROM): def get_chip_description(self): chip_name = { - 0: "ESP32-C6", + 0: "ESP32-C6 (QFN40)", + 1: "ESP32-C6FH4 (QFN32)", }.get(self.get_pkg_version(), "unknown ESP32-C6") major_rev = self.get_major_chip_version() minor_rev = self.get_minor_chip_version() diff --git a/esptool/targets/esp32h2.py b/esptool/targets/esp32h2.py index a37617e1d..66600c7da 100644 --- a/esptool/targets/esp32h2.py +++ b/esptool/targets/esp32h2.py @@ -13,6 +13,15 @@ class ESP32H2ROM(ESP32C6ROM): # Magic value for ESP32H2 CHIP_DETECT_MAGIC_VALUE = [0xD7B73E80] + DR_REG_LP_WDT_BASE = 0x600B1C00 + RTC_CNTL_WDTCONFIG0_REG = DR_REG_LP_WDT_BASE + 0x0 # LP_WDT_RWDT_CONFIG0_REG + RTC_CNTL_WDTWPROTECT_REG = DR_REG_LP_WDT_BASE + 0x001C # LP_WDT_RWDT_WPROTECT_REG + + RTC_CNTL_SWD_CONF_REG = DR_REG_LP_WDT_BASE + 0x0020 # LP_WDT_SWD_CONFIG_REG + RTC_CNTL_SWD_AUTO_FEED_EN = 1 << 18 + RTC_CNTL_SWD_WPROTECT_REG = DR_REG_LP_WDT_BASE + 0x0024 # LP_WDT_SWD_WPROTECT_REG + RTC_CNTL_SWD_WKEY = 0x50D83AA1 # LP_WDT_SWD_WKEY, same as WDT key in this case + FLASH_FREQUENCY = { "48m": 0xF, "24m": 0x0, @@ -20,12 +29,19 @@ class ESP32H2ROM(ESP32C6ROM): "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 + + def get_minor_chip_version(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 18) & 0x07 + + def get_major_chip_version(self): num_word = 3 - block1_addr = self.EFUSE_BASE + 0x044 - word3 = self.read_reg(block1_addr + (4 * num_word)) - pkg_version = (word3 >> 21) & 0x0F - return pkg_version + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x03 def get_chip_description(self): chip_name = { @@ -36,7 +52,7 @@ def get_chip_description(self): return f"{chip_name} (revision v{major_rev}.{minor_rev})" def get_chip_features(self): - return ["BLE"] + return ["BLE", "IEEE802.15.4"] def get_crystal_freq(self): # ESP32H2 XTAL is fixed to 32MHz diff --git a/esptool/targets/esp32h2beta1.py b/esptool/targets/esp32h2beta1.py index 66b6df902..49e38e44a 100644 --- a/esptool/targets/esp32h2beta1.py +++ b/esptool/targets/esp32h2beta1.py @@ -76,19 +76,16 @@ class ESP32H2BETA1ROM(ESP32C3ROM): } def get_pkg_version(self): - num_word = 3 - return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x0F + num_word = 4 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x07 def get_minor_chip_version(self): - hi_num_word = 5 - hi = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * hi_num_word)) >> 23) & 0x01 - low_num_word = 3 - low = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * low_num_word)) >> 18) & 0x07 - return (hi << 3) + low + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 18) & 0x07 def get_major_chip_version(self): - num_word = 5 - return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x03 + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x03 def get_chip_description(self): chip_name = { @@ -109,7 +106,10 @@ def override_vddsdio(self, new_voltage): "VDD_SDIO overrides are not supported for ESP32-H2" ) - def read_mac(self): + 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:] diff --git a/esptool/targets/esp32p4.py b/esptool/targets/esp32p4.py new file mode 100644 index 000000000..23ff407c1 --- /dev/null +++ b/esptool/targets/esp32p4.py @@ -0,0 +1,192 @@ +# 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 = 0x44000000 + DROM_MAP_START = 0x40000000 + DROM_MAP_END = 0x44000000 + + 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, 0x44000000, "DROM"], + [0x4FF00000, 0x4FFA0000, "DRAM"], + [0x4FF00000, 0x4FFA0000, "BYTE_ACCESSIBLE"], + [0x4FC00000, 0x4FC20000, "DROM_MASK"], + [0x4FC00000, 0x4FC20000, "IROM_MASK"], + [0x40000000, 0x44000000, "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() + + +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 --git a/esptool/targets/esp32s2.py b/esptool/targets/esp32s2.py index bffd55331..cd361f918 100644 --- a/esptool/targets/esp32s2.py +++ b/esptool/targets/esp32s2.py @@ -16,8 +16,6 @@ class ESP32S2ROM(ESP32ROM): 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 @@ class ESP32S2ROM(ESP32ROM): [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 @@ def get_flash_version(self): 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 @@ def get_chip_description(self): 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 @@ def get_chip_features(self): 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 = { @@ -182,7 +188,10 @@ def override_vddsdio(self, new_voltage): "VDD_SDIO overrides are not supported for ESP32-S2" ) - def read_mac(self): + 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:] diff --git a/esptool/targets/esp32s3.py b/esptool/targets/esp32s3.py index 660537b51..3dc785216 100644 --- a/esptool/targets/esp32s3.py +++ b/esptool/targets/esp32s3.py @@ -19,8 +19,6 @@ class ESP32S3ROM(ESP32ROM): CHIP_DETECT_MAGIC_VALUE = [0x9] - FPGA_SLOW_BOOT = False - IROM_MAP_START = 0x42000000 IROM_MAP_END = 0x44000000 DROM_MAP_START = 0x3C000000 @@ -83,10 +81,15 @@ class ESP32S3ROM(ESP32ROM): UARTDEV_BUF_NO_USB_OTG = 3 # The above var when USB-OTG is used UARTDEV_BUF_NO_USB_JTAG_SERIAL = 4 # The above var when USB-JTAG/Serial is used - RTC_CNTL_WDT_WKEY = 0x50D83AA1 RTCCNTL_BASE_REG = 0x60008000 - RTC_CNTL_WDTCONFIG0_REG = RTCCNTL_BASE_REG + 0x0090 + RTC_CNTL_SWD_CONF_REG = RTCCNTL_BASE_REG + 0x00B4 + RTC_CNTL_SWD_AUTO_FEED_EN = 1 << 31 + RTC_CNTL_SWD_WPROTECT_REG = RTCCNTL_BASE_REG + 0x00B8 + RTC_CNTL_SWD_WKEY = 0x8F1D312A + + RTC_CNTL_WDTCONFIG0_REG = RTCCNTL_BASE_REG + 0x0098 RTC_CNTL_WDTWPROTECT_REG = RTCCNTL_BASE_REG + 0x00B0 + RTC_CNTL_WDT_WKEY = 0x50D83AA1 USB_RAM_BLOCK = 0x800 # Max block size USB-OTG is used @@ -112,6 +115,8 @@ class ESP32S3ROM(ESP32ROM): [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 @@ -160,10 +165,53 @@ def get_raw_major_chip_version(self): 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 @@ -208,7 +256,10 @@ def override_vddsdio(self, new_voltage): "VDD_SDIO overrides are not supported for ESP32-S3" ) - def read_mac(self): + 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:] @@ -238,19 +289,29 @@ def uses_usb_jtag_serial(self): return False # can't detect USB-JTAG/Serial in secure download mode return self.get_uart_no() == self.UARTDEV_BUF_NO_USB_JTAG_SERIAL - def disable_rtc_watchdog(self): - # When USB-JTAG/Serial is used, the RTC watchdog is not reset - # and can then reset the board during flashing. Disable it. + def disable_watchdogs(self): + # When USB-JTAG/Serial is used, the RTC WDT and SWD watchdog are not reset + # and can then reset the board during flashing. Disable them. if self.uses_usb_jtag_serial(): + # Disable RTC WDT self.write_reg(self.RTC_CNTL_WDTWPROTECT_REG, self.RTC_CNTL_WDT_WKEY) self.write_reg(self.RTC_CNTL_WDTCONFIG0_REG, 0) self.write_reg(self.RTC_CNTL_WDTWPROTECT_REG, 0) + # Automatically feed SWD + self.write_reg(self.RTC_CNTL_SWD_WPROTECT_REG, self.RTC_CNTL_SWD_WKEY) + self.write_reg( + self.RTC_CNTL_SWD_CONF_REG, + self.read_reg(self.RTC_CNTL_SWD_CONF_REG) + | self.RTC_CNTL_SWD_AUTO_FEED_EN, + ) + self.write_reg(self.RTC_CNTL_SWD_WPROTECT_REG, 0) + def _post_connect(self): if self.uses_usb_otg(): self.ESP_RAM_BLOCK = self.USB_RAM_BLOCK if not self.sync_stub_detected: # Don't run if stub is reused - self.disable_rtc_watchdog() + self.disable_watchdogs() def _check_if_can_reset(self): """ diff --git a/esptool/targets/esp32s3beta2.py b/esptool/targets/esp32s3beta2.py index b7958bd53..f91bb3cb2 100644 --- a/esptool/targets/esp32s3beta2.py +++ b/esptool/targets/esp32s3beta2.py @@ -14,11 +14,6 @@ class ESP32S3BETA2ROM(ESP32S3ROM): 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 --git a/esptool/targets/esp8266.py b/esptool/targets/esp8266.py index f9966634d..e686abf6e 100644 --- a/esptool/targets/esp8266.py +++ b/esptool/targets/esp8266.py @@ -60,6 +60,8 @@ class ESP8266ROM(ESPLoader): [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 @@ -131,8 +133,10 @@ def chip_id(self): id1 = self.read_reg(self.ESP_OTP_MAC1) return (id0 >> 24) | ((id1 & 0xFFFFFF) << 8) - def read_mac(self): + def read_mac(self, mac_type="BASE_MAC"): """Read MAC from OTP ROM""" + if mac_type != "BASE_MAC": + return None mac0 = self.read_reg(self.ESP_OTP_MAC0) mac1 = self.read_reg(self.ESP_OTP_MAC1) mac3 = self.read_reg(self.ESP_OTP_MAC3) diff --git a/esptool/targets/stub_flasher/stub_flasher_32.json b/esptool/targets/stub_flasher/stub_flasher_32.json index 3e87d813c..23a283fa9 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32.json +++ b/esptool/targets/stub_flasher/stub_flasher_32.json @@ -1,7 +1,7 @@ { "entry": 1074521560, - "text": "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", + "text": "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", "text_start": 1074520064, - "data": "GOv8P9jnC0Bx6AtA8+wLQO3oC0CP6AtA7egLQEnpC0AG6gtAeOoLQCHqC0CB5wtAo+kLQPjpC0Bn6QtAmuoLQI7pC0Ca6gtAXegLQLPoC0Dt6AtASekLQHfoC0BM6wtAs+wLQKXmC0DX7AtApeYLQKXmC0Cl5gtApeYLQKXmC0Cl5gtApeYLQKXmC0Dz6gtApeYLQM3rC0Cz7AtA", + "data": "DMD8P9jnC0Br6AtAA+0LQPLoC0CL6AtA8ugLQFHpC0Ae6gtAkOoLQDnqC0CB5wtAtukLQBDqC0B06QtAtOoLQJ7pC0C06gtAWegLQLboC0Dy6AtAUekLQHHoC0Bk6wtAxewLQKTmC0Dn7AtApOYLQKTmC0Ck5gtApOYLQKTmC0Ck5gtApOYLQKTmC0AL6wtApOYLQOXrC0DF7AtA", "data_start": 1073605544 } \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32c2.json b/esptool/targets/stub_flasher/stub_flasher_32c2.json index 07887d4d1..365c705ff 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32c2.json +++ b/esptool/targets/stub_flasher/stub_flasher_32c2.json @@ -1,7 +1,7 @@ { "entry": 1077413304, - "text": "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", + "text": "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", "text_start": 1077411840, - "data": "GGvKP+AIOEAsCThAhAk4QCgKOECUCjhAQgo4QKgHOEDkCThAJAo4QJgJOEBYBzhAzAk4QFgHOEC6CDhA/gg4QCwJOECECThAzAg4QBIIOEBCCDhAyAg4QOYMOEAsCThArAs4QJoMOECkBjhAxAw4QKQGOECkBjhApAY4QKQGOECkBjhApAY4QKQGOECkBjhASAs4QKQGOEDICzhAmgw4QA==", + "data": "DEDKP+AIOEAsCThAhAk4QCgKOECUCjhAQgo4QKgHOEDkCThAJAo4QJgJOEBYBzhAzAk4QFgHOEC6CDhA/gg4QCwJOECECThAzAg4QBIIOEBCCDhAyAg4QOwMOEAsCThArAs4QKAMOECkBjhAygw4QKQGOECkBjhApAY4QKQGOECkBjhApAY4QKQGOECkBjhASAs4QKQGOEDICzhAoAw4QA==", "data_start": 1070295976 } \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32c3.json b/esptool/targets/stub_flasher/stub_flasher_32c3.json index 8426a637a..3edf1457e 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32c3.json +++ b/esptool/targets/stub_flasher/stub_flasher_32c3.json @@ -1,7 +1,7 @@ { "entry": 1077413532, - "text": "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", + "text": "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", "text_start": 1077411840, - "data": "IGvIP1YKOECmCjhA/go4QKILOEAODDhAvAs4QCIJOEBeCzhAngs4QBILOEDSCDhARgs4QNIIOEAwCjhAdgo4QKYKOED+CjhAQgo4QIYJOEC2CThAPgo4QGAOOECmCjhAJg04QBgOOEASCDhAQA44QBIIOEASCDhAEgg4QBIIOEASCDhAEgg4QBIIOEASCDhAwgw4QBIIOEBEDThAGA44QA==", + "data": "FEDIP4wKOEDcCjhANAs4QNgLOEBEDDhA8gs4QD4JOECUCzhA1As4QEgLOEDuCDhAfAs4QO4IOEBmCjhArAo4QNwKOEA0CzhAeAo4QKIJOEDsCThAdAo4QJwOOEDcCjhAXA04QFQOOEAuCDhAfA44QC4IOEAuCDhALgg4QC4IOEAuCDhALgg4QC4IOEAuCDhA+Aw4QC4IOEB6DThAVA44QA==", "data_start": 1070164912 } \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32c6.json b/esptool/targets/stub_flasher/stub_flasher_32c6.json index 2bf3accf8..fa81d618f 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32c6.json +++ b/esptool/targets/stub_flasher/stub_flasher_32c6.json @@ -1,7 +1,7 @@ { "entry": 1082132112, - "text": "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", + "text": "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", "text_start": 1082130432, - "data": "HCuEQCoKgEB6CoBA0gqAQHYLgEDiC4BAkAuAQPYIgEAyC4BAcguAQOYKgECmCIBAGguAQKYIgEAECoBASgqAQHoKgEDSCoBAFgqAQFoJgECKCYBAEgqAQDQOgEB6CoBA+gyAQOwNgEDmB4BAFA6AQOYHgEDmB4BA5geAQOYHgEDmB4BA5geAQOYHgEDmB4BAlgyAQOYHgEAYDYBA7A2AQA==", + "data": "EACEQD4KgECOCoBA5gqAQIoLgED2C4BApAuAQAoJgEBGC4BAhguAQPoKgEC6CIBALguAQLoIgEAYCoBAXgqAQI4KgEDmCoBAKgqAQG4JgECeCYBAJgqAQE4OgECOCoBADg2AQAYOgED6B4BALg6AQPoHgED6B4BA+geAQPoHgED6B4BA+geAQPoHgED6B4BAqgyAQPoHgEAsDYBABg6AQA==", "data_start": 1082469292 } \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32c6beta.json b/esptool/targets/stub_flasher/stub_flasher_32c6beta.json index 4709f9ddc..94fd3da07 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32c6beta.json +++ b/esptool/targets/stub_flasher/stub_flasher_32c6beta.json @@ -1,7 +1,7 @@ { "entry": 1077413318, - "text": "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", + "text": "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", "text_start": 1077411840, - "data": "GGvIP/gIOEBECThAnAk4QEAKOECsCjhAWgo4QMAHOED8CThAPAo4QLAJOEBwBzhA5Ak4QHAHOEDSCDhAFgk4QEQJOECcCThA5Ag4QCoIOEBaCDhA4Ag4QP4MOEBECThAxAs4QLIMOEC8BjhA3Aw4QLwGOEC8BjhAvAY4QLwGOEC8BjhAvAY4QLwGOEC8BjhAYAs4QLwGOEDgCzhAsgw4QA==", + "data": "DEDIP/gIOEBECThAnAk4QEAKOECsCjhAWgo4QMAHOED8CThAPAo4QLAJOEBwBzhA5Ak4QHAHOEDSCDhAFgk4QEQJOECcCThA5Ag4QCoIOEBaCDhA4Ag4QAQNOEBECThAxAs4QLgMOEC8BjhA4gw4QLwGOEC8BjhAvAY4QLwGOEC8BjhAvAY4QLwGOEC8BjhAYAs4QLwGOEDgCzhAuAw4QA==", "data_start": 1070164904 } \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32h2.json b/esptool/targets/stub_flasher/stub_flasher_32h2.json index f003a550b..b3b637395 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32h2.json +++ b/esptool/targets/stub_flasher/stub_flasher_32h2.json @@ -1,7 +1,7 @@ { "entry": 1082132112, - "text": "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", + "text": "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", "text_start": 1082130432, - "data": "HCuDQCoKgEB6CoBA0gqAQHYLgEDiC4BAkAuAQPYIgEAyC4BAcguAQOYKgECmCIBAGguAQKYIgEAECoBASgqAQHoKgEDSCoBAFgqAQFoJgECKCYBAEgqAQDQOgEB6CoBA+gyAQOwNgEDmB4BAFA6AQOYHgEDmB4BA5geAQOYHgEDmB4BA5geAQOYHgEDmB4BAlgyAQOYHgEAYDYBA7A2AQA==", + "data": "EACDQD4KgECOCoBA5gqAQIoLgED2C4BApAuAQAoJgEBGC4BAhguAQPoKgEC6CIBALguAQLoIgEAYCoBAXgqAQI4KgEDmCoBAKgqAQG4JgECeCYBAJgqAQE4OgECOCoBADg2AQAYOgED6B4BALg6AQPoHgED6B4BA+geAQPoHgED6B4BA+geAQPoHgED6B4BAqgyAQPoHgEAsDYBABg6AQA==", "data_start": 1082403756 } \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32h2beta1.json b/esptool/targets/stub_flasher/stub_flasher_32h2beta1.json index 37d29e8fb..6d4ec72b1 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32h2beta1.json +++ b/esptool/targets/stub_flasher/stub_flasher_32h2beta1.json @@ -1,7 +1,7 @@ { "entry": 1077413318, - "text": "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", + "text": "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", "text_start": 1077411840, - "data": "GGvIP/gIOEBECThAnAk4QEAKOECsCjhAWgo4QMAHOED8CThAPAo4QLAJOEBwBzhA5Ak4QHAHOEDSCDhAFgk4QEQJOECcCThA5Ag4QCoIOEBaCDhA4Ag4QP4MOEBECThAxAs4QLIMOEC8BjhA3Aw4QLwGOEC8BjhAvAY4QLwGOEC8BjhAvAY4QLwGOEC8BjhAYAs4QLwGOEDgCzhAsgw4QA==", + "data": "DEDIP/gIOEBECThAnAk4QEAKOECsCjhAWgo4QMAHOED8CThAPAo4QLAJOEBwBzhA5Ak4QHAHOEDSCDhAFgk4QEQJOECcCThA5Ag4QCoIOEBaCDhA4Ag4QAQNOEBECThAxAs4QLgMOEC8BjhA4gw4QLwGOEC8BjhAvAY4QLwGOEC8BjhAvAY4QLwGOEC8BjhAYAs4QLwGOEDgCzhAuAw4QA==", "data_start": 1070164904 } \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32h2beta2.json b/esptool/targets/stub_flasher/stub_flasher_32h2beta2.json index f7cc1cecd..cd438aba0 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32h2beta2.json +++ b/esptool/targets/stub_flasher/stub_flasher_32h2beta2.json @@ -1,7 +1,7 @@ { "entry": 1077413318, - "text": "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", + "text": "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", "text_start": 1077411840, - "data": "GGvIP/gIOEBECThAnAk4QEAKOECsCjhAWgo4QMAHOED8CThAPAo4QLAJOEBwBzhA5Ak4QHAHOEDSCDhAFgk4QEQJOECcCThA5Ag4QCoIOEBaCDhA4Ag4QP4MOEBECThAxAs4QLIMOEC8BjhA3Aw4QLwGOEC8BjhAvAY4QLwGOEC8BjhAvAY4QLwGOEC8BjhAYAs4QLwGOEDgCzhAsgw4QA==", + "data": "DEDIP/gIOEBECThAnAk4QEAKOECsCjhAWgo4QMAHOED8CThAPAo4QLAJOEBwBzhA5Ak4QHAHOEDSCDhAFgk4QEQJOECcCThA5Ag4QCoIOEBaCDhA4Ag4QAQNOEBECThAxAs4QLgMOEC8BjhA4gw4QLwGOEC8BjhAvAY4QLwGOEC8BjhAvAY4QLwGOEC8BjhAYAs4QLwGOEDgCzhAuAw4QA==", "data_start": 1070164904 } \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32p4.json b/esptool/targets/stub_flasher/stub_flasher_32p4.json new file mode 100644 index 000000000..6ed0687a3 --- /dev/null +++ b/esptool/targets/stub_flasher/stub_flasher_32p4.json @@ -0,0 +1,7 @@ +{ + "entry": 1341195718, + "text": "ARG3pwxQTsaDqYcASsg3CfVPJspSxAbOIsy3pAxQfVoTCQkAwEwTdPQ/DeDyQGJEI6g0AUJJ0kSySSJKBWGCgIhAgycJABN19Q+Cl30U4xlE/8m/EwcADJRBqodjGOUAhUeFxiOgBQB5VYKABUdjh+YACUZjjcYAfVWCgEIFEwewDUGFY5XnAolHnMH1t5MGwA1jFtUAmMETBQAMgoCTBtANfVVjldcAmMETBbANgoC3NfZPQRGThQW6BsZhP2NFBQa3N/ZPk4eHsQOnBwgD1kcIE3X1D5MGFgDCBsGCI5LXCDKXIwCnAAPXRwiRZ5OHBwRjHvcCN7f1TxMHh7GhZ7qXA6YHCLf29U+3N/ZPk4eHsZOGhrVjH+YAI6bHCCOg1wgjkgcIIaD5V+MG9fyyQEEBgoAjptcII6DnCN23N9cIUHxLnYv1/zfHCFB8S52L9f+CgEERBsbdN7fXCFAjpgcCNwcACJjDmEN9/8hXskATRfX/BYlBAYKAQREGxtk/fd03BwBAt9cIUJjDN9cIUBxD/f+yQEEBgoBBESLEN4T1T5MHxABKwAOpBwEGxibCYwoJBEU3OcW9RxMExACBRGPWJwEERL2Ik7QUAH03hT8cRDcGgAATl8cAmeA3BgABt/b/AHWPt9YIUNjCkMKYQn3/QUeR4AVHMwnpQLqXIygkARzEskAiRJJEAklBAYKAQREGxhMHAAxjEOUCEwWwDZcAz//ngEDjEwXADbJAQQEXA8//ZwBD4hMHsA3jGOX+lwDP/+eAQOETBdANxbdBESLEJsIGxiqEswS1AGMXlACyQCJEkkRBAYKAA0UEAAUERTfttxMFAAwXA8//ZwDD3TVxJstOx/1yhWn9dCLNSslSxVbDBs+ThIT6FpGThwkHppcYCLOE5wAqiSaFLoSXAM//54DgM5OHCQcYCAVqupezikdBMeQFZ311kwWF+pMHBwcTBYX5FAiqlzOF1wCTBwcHrpezhdcAKsaXAM//54CgMDJFwUWhPwFFhWIWkfpAakTaREpJukkqSppKDWGCgKKJY3OKAIVpTobWhUqFlwDP/+eAoOMTdfUPAe1OhtaFJoWXAM//54DgK06ZMwQ0QVG3EwUwBlW/MXH9ck7XUtVW017PBt8i3SbbStla0WLNZstqyW7HqokWkRMFAAIuirKKtosCypcAz//ngKAmhWdj4FcThWR9dBMEhPqThwQHopcYCDOE5wAihZcAz//ngCAlfXsTDDv5kwyL+ROHBAeThwQHFAhil+aXAUkzDNcAs4zXAFJNY3xNCWNxqQNBqFU1poUIAaU9cT0mhgwBIoWXAM//54AAIaaZJpljdUkDswepQWPxdwOzBCpBY/OaANaEJoYMAU6FlwDP/+eAANUTdfUPVd0CzIFEeV2NTaMJAQBihZcAz//ngMDDffkDRTEB5oUFMWNPBQDj4p3+hWeThwcHppcYCLqX2pcjiqf4hQTxt+MVpf2RR+OF9PYFZ311kwcHB5MFhfoTBYX5FAiqlzOF1wCTBwcHrpezhdcAKsaXAM//54AgF+0zMkXBRX07zTMTBQAClwDP/+eAwBSFYhaR+lBqVNpUSlm6WSpamloKW/pLakzaTEpNuk0pYYKAAREGziLMnTk3BPRPbAATBcT+lwDP/+eAgMuqhwVFleeyR5P3ByA+xkE5N9cIUBxHtwZAABMFxP7VjxzHskWXAM//54AAyTM1oADyQGJEBWGCgEERt4f1TwbGk4fHAAVHI4DnABPXxQCYxwVnfRfMw8jH+Y06laqVsYGMyyOqBwBBNxnBEwVQDLJAQQGCgAERIsw3hPVPkwfEACbKxEdOxgbOSsiqiRMExABj85UAroSpwAMpRAAmmRNZyQAcSGNV8AAcRGNe+QLpNn3dSEAmhs6FlwDP/+eAALwTdfUPAcWTB0AMXMhcQKaXXMBcRIWPXMTyQGJE0kRCSbJJBWGCgOE+bb+3V0FJGXGTh/eEAUU+zobeotym2srYztbS1NbS2tDezuLM5srqyO7GlwDP/+eAYK23B/VPNzf2T5OHBwATB4e6Y+DnFK0xkUVoCD05jTG3t/VPk4eHsSFnPpcjIPcItwXxT7cH8U8BRpOHBwuThQUANwn1TxVFIyD5AJcAz//ngMD5N6cMUFxHEwUAAreE9U+T5xcQXMeXAM//54CA+LcHDlCIX4FFtzn2T3GJYRUTNRUAlwDP/+eAALfBZ/0XEwcAEIVmQWa3BQABAUWThMQAtwr1Tw1qlwDP/+eAwKyTiYmxEwkJABOLygAmmoOnyQj134OryQiFRyOmCQgjAvECg8cbAAlHIxPhAqMC8QIC1E1HY4vnBlFHY4nnBilHY5/nAIPHOwADxysAogfZjxFHY5bnAIOniwCcQz7UjT6hRUgQmTaDxzsAA8crAKIH2Y8RZ0EHY373AhMFsA2XAM//54AgkxMFwA2XAM//54BgkhMF4A6XAM//54CgkQ0+vbcjoAcAkQdtvclHIxPxAn23A8cbANFGY+fmAoVGY+bmAAFMEwTwD52oeRcTd/cPyUbj6Ob+tzb2TwoHk4bGujaXGEMCh5MGBwOT9vYPEUbjadb8Ewf3AhN39w+NRmPu5gi3NvZPCgeThoa/NpcYQwKHEwdAAmOa5xAC1B1EAUWXAM//54AAiQFFiTRVNE00oUVIEH0UlTx98AFMAUQTdfQPLTQTdfwPFTRZNOMRBOyDxxsASUdjYPcuCUfjeffq9ReT9/cPPUfjY/fqNzf2T4oHEweHwLqXnEOChwVEnetwEIFFAUWXAM//54AgiR3h0UVoEBk8AUQxqAVEge+XAM//54CgjjM0oAApoCFHY4XnAAVEAUxhtwOsiwADpMsAs2eMANIH9feZOWX1wWwinP0cfX0zBYxAXdyzd5UBlePBbDMFjEBj5owC/XwzBYxAXdAxgZcAz//ngECLXflmlPW3MYGXAM//54BAil3xapTRt0GBlwDP/+eAgIlZ+TMElEHBtyFH44rn8AFMEwQADDm3QUfNv0FHBUTjnef2g6XLAAOliwBZOrm/QUcFROOT5/YDpwsBkWdj4+ccg6VLAQOliwAxMYG3QUcFROOU5/SDpwsBEWdjZPcaA6fLAIOlSwEDpYsAM4TnAt02I6wEACMkirAJvwPHBABjDgcQA6eLAMEXEwQADGMT9wDASAFHkwbwDmNG9wKDx1sAA8dLAAFMogfZjwPHawBCB12Pg8d7AOIH2Y/jhPbmEwQQDIW1M4brAANGhgEFB7GO4beDxwQA8cPcRGOYBxLASCOABABVvWFHY5bnAoOnywEDp4sBg6ZLAQOmCwGDpcsAA6WLAJfwzv/ngEB6KowzNKAAAb0BTAVEKbURRwVE453n5gOliwCBRZcAz//ngACAqbUT9/cA4xwH7JPcRwAThIsAAUx9XeN8nN1IRJfwzv/ngABjGERUQBBA+Y5jB6cBHEITR/f/fY/ZjhTCBQxBBNm/EUdZvUFHBUTjn+fgg6eLAAOnSwEjJPkAIyLpAPWzgyVJAMEXkeWJzwFMEwRgDEmzAyeJAGNm9wYT9zcA4xAH5gMoiQABRgFHMwXoQLOG5QBjafcA4wwG1CMkqQAjItkAsbMzhusAEE4RB5DCBUbpvyFHBUTjmefaAySJABnAEwSADCMkCQAjIgkAMzSAAGG7AUwTBCAMKbsBTBMEgAwJuwFMEwSQDCmzEwcgDWOD5wwTB0AN45bnvAPEOwCDxysAIgRdjJfwzv/ngOBiA6zEAEEUY3OEASKM4wQMusBAYpQxgJxIY1XwAJxEY1r0Cu/wT+N13chAYoaThYsBl/DO/+eA4F4BxZMHQAzcyNxA4pfcwNxEs4eHQdzEl/DO/+eAwF25vgllEwUFcQOsywADpIsAl/DO/+eAgE23pwxQ2Eu3BgABwRaTV0cBEgd1j72L2Y+zh4cDAUWz1YcCl/DO/+eA4E4TBYA+l/DO/+eAIEoBvoOmSwEDpgsBg6XLAAOliwDv8E/57byDxTsAg8crABOFiwGiBd2NwRVRMtW07/Cv3IG3A8Q7AIPHKwATjIsBIgRdjNxEQRTF45FHhUtj/ocIkweQDNzIZbwDpw0AItAFSLOH7EA+1oMnirBjc/QADUhCxjrE7/Av2CJHMkg3hfVP4oV8EJOGygAQEBMFRQKX8M7/54BgTDe39U+TCMcAglcDp4iwg6UNAB2MHY8+nLJXI6TosKqLvpUjoL0Ak4fKAJ2NAcWhZ2OW9QBahcUwI6BtAQnE3ESZw+NAcPlj3wsAkwdwDIW/hUu3PfZPt4z1T5ONjbqTjMwA6b/jmgug3ETjhwegkweADLG3g6eLAOOQB6ABRZfwzv/ngMA7CWUTBQVxl/DO/+eAYDeX8M7/54BgPPG6A6TLAOMLBJwBRZfwzv/ngCA5EwWAPpfwzv/ngOA0ApRtuvZQZlTWVEZZtlkmWpZaBlv2S2ZM1kxGTbZNCWGCgA==", + "text_start": 1341194240, + "data": "DAD1T+4I8U86CfFPkgnxTzYK8U+iCvFPUArxT7YH8U/yCfFPMgrxT6YJ8U9mB/FP2gnxT2YH8U/ICPFPDAnxTzoJ8U+SCfFP2gjxTyAI8U9QCPFP1gjxT/oM8U86CfFPugvxT64M8U+yBvFP2AzxT7IG8U+yBvFPsgbxT7IG8U+yBvFPsgbxT7IG8U+yBvFPVgvxT7IG8U/WC/FPrgzxTw==", + "data_start": 1341533096 +} \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32s2.json b/esptool/targets/stub_flasher/stub_flasher_32s2.json index b8b5151c4..e69de29bb 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32s2.json +++ b/esptool/targets/stub_flasher/stub_flasher_32s2.json @@ -1,7 +0,0 @@ -{ - "entry": 1073907696, - "text": "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", - "text_start": 1073905664, - "data": "ZCv9PzaLAkDBiwJAhpACQEqMAkDjiwJASowCQKmMAkByjQJA5Y0CQI2NAkDAigJAC40CQGSNAkDMjAJACI4CQPaMAkAIjgJAr4sCQA6MAkBKjAJAqYwCQMeLAkACiwJAx44CQD2QAkDYiQJAZZACQNiJAkDYiQJA2IkCQNiJAkDYiQJA2IkCQNiJAkDYiQJAZI4CQNiJAkBZjwJAPZACQA==", - "data_start": 1073622012 -} \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32s3.json b/esptool/targets/stub_flasher/stub_flasher_32s3.json index 1e14dc1f6..e69de29bb 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32s3.json +++ b/esptool/targets/stub_flasher/stub_flasher_32s3.json @@ -1,7 +0,0 @@ -{ - "entry": 1077381816, - "text": "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", - "text_start": 1077379072, - "data": "ZCvKP2qON0BLjzdAGpQ3QNaPN0BrjzdA1o83QDWQN0ACkTdAc5E3QB2RN0D1jTdAmJA3QPSQN0BYkDdAlpE3QIKQN0CWkTdAOY83QJaPN0DWjzdANZA3QFGPN0A2jjdAVJI3QNGTN0ASjTdA+ZM3QBKNN0ASjTdAEo03QBKNN0ASjTdAEo03QBKNN0ASjTdA75E3QBKNN0DpkjdA0ZM3QAQInwAAAAAAAAAYAQQIBQAAAAAAAAAIAQQIBgAAAAAAAAAAAQQIIQAAAAAAIAAAEQQI3AAAAAAAIAAAEQQIDAAAAAAAIAAAAQQIEgAAAAAAIAAAESAoDAAQAQAA", - "data_start": 1070279676 -} \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_32s3beta2.json b/esptool/targets/stub_flasher/stub_flasher_32s3beta2.json index 053586e66..e69de29bb 100644 --- a/esptool/targets/stub_flasher/stub_flasher_32s3beta2.json +++ b/esptool/targets/stub_flasher/stub_flasher_32s3beta2.json @@ -1,7 +0,0 @@ -{ - "entry": 1077381308, - "text": "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", - "text_start": 1077379072, - "data": "ZCvKP1qMN0DnjDdAvpE3QHGNN0AHjTdAcY03QNGNN0CejjdAEI83QLmON0DlizdANI43QJCON0D0jTdANI83QB6ON0A0jzdA1Yw3QDKNN0BxjTdA0Y03QO2MN0AmjDdA9I83QHWRN0ACizdAnZE3QAKLN0ACizdAAos3QAKLN0ACizdAAos3QAKLN0ACizdAjo83QAKLN0CKkDdAdZE3QA==", - "data_start": 1070279676 -} \ No newline at end of file diff --git a/esptool/targets/stub_flasher/stub_flasher_8266.json b/esptool/targets/stub_flasher/stub_flasher_8266.json index 8d42b24af..95e6e9e53 100644 --- a/esptool/targets/stub_flasher/stub_flasher_8266.json +++ b/esptool/targets/stub_flasher/stub_flasher_8266.json @@ -1,7 +1,7 @@ { "entry": 1074843652, - "text": "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", + "text": "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", "text_start": 1074843648, - "data": "CIH+PwUFBAACAwcAAwMLALnXEEDv1xBAHdgQQLrYEEBo5xBAHtkQQHTZEEDA2RBAaOcQQILaEED/2hBAwNsQQGjnEEBo5xBAWNwQQGjnEEA33xBAAOAQQDvgEEBo5xBAaOcQQNfgEEBo5xBAv+EQQGXiEECj4xBAY+QQQDTlEEBo5xBAaOcQQGjnEEBo5xBAYuYQQGjnEEBX5xBAkN0QQI/YEECm5RBAq9oQQPzZEEBo5xBA7OYQQDHnEEBo5xBAaOcQQGjnEEBo5xBAaOcQQGjnEEBo5xBAaOcQQCLaEEBf2hBAvuUQQAEAAAACAAAAAwAAAAQAAAAFAAAABwAAAAkAAAANAAAAEQAAABkAAAAhAAAAMQAAAEEAAABhAAAAgQAAAMEAAAABAQAAgQEAAAECAAABAwAAAQQAAAEGAAABCAAAAQwAAAEQAAABGAAAASAAAAEwAAABQAAAAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAUAAAAGAAAABgAAAAcAAAAHAAAACAAAAAgAAAAJAAAACQAAAAoAAAAKAAAACwAAAAsAAAAMAAAADAAAAA0AAAANAAAAAAAAAAAAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAANAAAADwAAABEAAAATAAAAFwAAABsAAAAfAAAAIwAAACsAAAAzAAAAOwAAAEMAAABTAAAAYwAAAHMAAACDAAAAowAAAMMAAADjAAAAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAgAAAAIAAAACAAAAAgAAAAMAAAADAAAAAwAAAAMAAAAEAAAABAAAAAQAAAAEAAAABQAAAAUAAAAFAAAABQAAAAAAAAAAAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AAQEAAAEAAAAEAAAA", + "data": "CIH+PwUFBAACAwcAAwMLANTXEEAL2BBAOdgQQNbYEECF5xBAOtkQQJDZEEDc2RBAhecQQKLaEEAf2xBA4NsQQIXnEECF5xBAeNwQQIXnEEBV3xBAHOAQQFfgEECF5xBAhecQQPPgEECF5xBA2+EQQIHiEEDA4xBAf+QQQFDlEECF5xBAhecQQIXnEECF5xBAfuYQQIXnEEB05xBAsN0QQKnYEEDC5RBAydoQQBvaEECF5xBACOcQQE/nEECF5xBAhecQQIXnEECF5xBAhecQQIXnEECF5xBAhecQQELaEEB/2hBA2uUQQAEAAAACAAAAAwAAAAQAAAAFAAAABwAAAAkAAAANAAAAEQAAABkAAAAhAAAAMQAAAEEAAABhAAAAgQAAAMEAAAABAQAAgQEAAAECAAABAwAAAQQAAAEGAAABCAAAAQwAAAEQAAABGAAAASAAAAEwAAABQAAAAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAUAAAAGAAAABgAAAAcAAAAHAAAACAAAAAgAAAAJAAAACQAAAAoAAAAKAAAACwAAAAsAAAAMAAAADAAAAA0AAAANAAAAAAAAAAAAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAANAAAADwAAABEAAAATAAAAFwAAABsAAAAfAAAAIwAAACsAAAAzAAAAOwAAAEMAAABTAAAAYwAAAHMAAACDAAAAowAAAMMAAADjAAAAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAgAAAAIAAAACAAAAAgAAAAMAAAADAAAAAwAAAAMAAAAEAAAABAAAAAQAAAAEAAAABQAAAAUAAAAFAAAABQAAAAAAAAAAAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AAQEAAAEAAAAEAAAA", "data_start": 1073720488 } \ No newline at end of file diff --git a/esptool/uf2_writer.py b/esptool/uf2_writer.py new file mode 100644 index 000000000..554c8450c --- /dev/null +++ b/esptool/uf2_writer.py @@ -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 --git a/esptool/util.py b/esptool/util.py index 66d9bd45e..ecd41c0d9 100644 --- a/esptool/util.py +++ b/esptool/util.py @@ -3,6 +3,7 @@ # # SPDX-License-Identifier: GPL-2.0-or-later +import os import re import struct import sys @@ -33,6 +34,8 @@ def flash_size_bytes(size): """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: @@ -65,7 +68,7 @@ def print_overwrite(message, last_line=False): 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) @@ -87,6 +90,15 @@ def strip_chip_name(chip_name): return re.sub(r"[-()]", "", chip_name.lower()) +def get_file_size(path_to_file): + """Returns the file size in bytes""" + file_size = 0 + with open(path_to_file, "rb") as f: + f.seek(0, os.SEEK_END) + file_size = f.tell() + return file_size + + class FatalError(RuntimeError): """ Wrapper class for runtime errors that aren't caused by internal bugs, but by diff --git a/flasher_stub/Makefile b/flasher_stub/Makefile index 934f8574a..8f4948c50 100644 --- a/flasher_stub/Makefile +++ b/flasher_stub/Makefile @@ -1,7 +1,7 @@ # Makefile to compile the flasher stub program # # Note that YOU DO NOT NEED TO COMPILE THIS IN ORDER TO JUST USE -# esptool.py - a precompiled version is embedded in esptool.py, +# esptool.py - a precompiled version is included in esptool.py, # so if you don't want to modify the stub code then you are good to go. # # See the comments in the top of the Makefile for parameters that @@ -38,6 +38,10 @@ CROSS_32S2 ?= xtensa-esp32s2-elf- CROSS_32S3 ?= xtensa-esp32s3-elf- CROSS_ESPRISCV32 ?= riscv32-esp-elf- +# extra CFLAGS to be passed on the compiler, in addition to the stock ones +EXTRA_CFLAGS ?= +EXTRA_CFLAGS_ESPRISCV32 ?= + # Python command to invoke wrap_stub.py WRAP_STUB ?= ./wrap_stub.py @@ -65,27 +69,60 @@ STUB_ELF_32H2_BETA_2 = $(BUILD_DIR)/$(STUB)_32h2beta2.elf 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 -.PHONY: all esp32 clean embed embed_esp32 +STUBS_ELF = +ifneq ($(WITHOUT_ESP8266),1) +STUBS_ELF += \ + $(STUB_ELF_8266) +endif -all: $(STUB_ELF_8266) $(STUB_ELF_32) $(STUB_ELF_32S2) $(STUB_ELF_32S3_BETA_2) $(STUB_ELF_32S3) $(STUB_ELF_32C3) $(STUB_ELF_32C6BETA) $(STUB_ELF_32H2_BETA_1) $(STUB_ELF_32H2_BETA_2) $(STUB_ELF_32C2) $(STUB_ELF_32C6) $(STUB_ELF_32H2) - @echo " WRAP $^ -> $(BUILD_DIR)" - $(Q) $(WRAP_STUB) $^ +ifneq ($(WITHOUT_ESP32_XTENSA),1) +STUBS_ELF += \ + $(STUB_ELF_32) \ + $(STUB_ELF_32S2) \ + $(STUB_ELF_32S3_BETA_2) \ + $(STUB_ELF_32S3) +endif -esp32: $(STUB_ELF_32) $(STUB_ELF_32S2) $(STUB_ELF_32S3_BETA_2) $(STUB_ELF_32S3) $(STUB_ELF_32C3) $(STUB_ELF_32C6BETA) $(STUB_ELF_32H2_BETA_1) $(STUB_ELF_32H2_BETA_2) $(STUB_ELF_32C2) $(STUB_ELF_32C6) $(STUB_ELF_32H2) - @echo " WRAP $^ -> $(BUILD_DIR)" - $(Q) $(WRAP_STUB) $^ +ifneq ($(WITHOUT_ESP32_RISCV32),1) +STUBS_ELF += \ + $(STUB_ELF_32C3) \ + $(STUB_ELF_32C6BETA) \ + $(STUB_ELF_32H2_BETA_1) \ + $(STUB_ELF_32H2_BETA_2) \ + $(STUB_ELF_32C2) \ + $(STUB_ELF_32C6) \ + $(STUB_ELF_32H2) \ + $(STUB_ELF_32P4) +endif + +.PHONY: all clean install + +all: $(STUBS_ELF:.elf=.json) + +install: $(patsubst $(BUILD_DIR)/%.elf,$(ESPTOOL_STUBS_DIR)/%.json,$(STUBS_ELF)) $(BUILD_DIR): $(Q) mkdir $@ +$(BUILD_DIR)/%.json: $(BUILD_DIR)/%.elf + @echo " WRAP $^ -> $(BUILD_DIR)" + $(Q) $(WRAP_STUB) $^ + +$(ESPTOOL_STUBS_DIR)/%.json: $(BUILD_DIR)/%.json + @echo " INSTALL $^ -> $@" + $(Q) cp $^ $@ + CFLAGS = -std=c99 -Wall -Werror -Os \ -mtext-section-literals -mlongcalls -nostdlib -fno-builtin -flto \ - -Wl,-static -g -ffunction-sections -Wl,--gc-sections -Iinclude -Lld + -Wl,-static -g -ffunction-sections -Wl,--gc-sections -Iinclude -Lld \ + $(EXTRA_CFLAGS) CFLAGS_ESPRISCV32 = -std=c99 -Wall -Werror -Os \ - -march=rv32imc -msmall-data-limit=0 \ + -march=rv32imc -mabi=ilp32 -msmall-data-limit=0 \ -nostdlib -fno-builtin -flto \ - -Wl,-static -g -ffunction-sections -Wl,--gc-sections -Iinclude -Lld + -Wl,-static -g -ffunction-sections -Wl,--gc-sections -Iinclude -Lld \ + $(EXTRA_CFLAGS_ESPRISCV32) LDLIBS = -lgcc $(STUB_ELF_8266): $(SRCS) $(SRCS_8266) $(BUILD_DIR) ld/stub_8266.ld | Makefile @@ -136,13 +173,9 @@ $(STUB_ELF_32H2): $(SRCS) $(BUILD_DIR) ld/stub_32h2.ld @echo " CC(32H2) $^ -> $@" $(Q) $(CROSS_ESPRISCV32)gcc $(CFLAGS_ESPRISCV32) -DESP32H2=1 -Tstub_32h2.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) -embed: $(STUB_ELF_8266) $(STUB_ELF_32) $(STUB_ELF_32S2) $(STUB_ELF_32S3_BETA_2) $(STUB_ELF_32S3) $(STUB_ELF_32C3) $(STUB_ELF_32C6BETA) $(STUB_ELF_32H2_BETA_1) $(STUB_ELF_32H2_BETA_2) $(STUB_ELF_32C2) $(STUB_ELF_32C6) $(STUB_ELF_32H2) - @echo " WRAP $^ -> $(ESPTOOL_STUBS_DIR)" - $(Q) $(WRAP_STUB) --embed $^ - -embed_esp32: $(STUB_ELF_32) $(STUB_ELF_32S2) $(STUB_ELF_32S3_BETA_2) $(STUB_ELF_32S3) $(STUB_ELF_32C3) $(STUB_ELF_32C6BETA) $(STUB_ELF_32H2_BETA_1) $(STUB_ELF_32H2_BETA_2) $(STUB_ELF_32C2) $(STUB_ELF_32C6) $(STUB_ELF_32H2) - @echo " WRAP $^ -> $(ESPTOOL_STUBS_DIR)" - $(Q) $(WRAP_STUB) --embed $^ +$(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 --git a/flasher_stub/README.md b/flasher_stub/README.md index 5b7f4e2cf..052909c3f 100644 --- a/flasher_stub/README.md +++ b/flasher_stub/README.md @@ -28,13 +28,13 @@ If you want to build the stub to test modifications or updates, here's how: * Set any other environment variables you'd like to override in the Makefile. -* To build type `make`. To build only for the ESP32 family, type `make esp32` (this negates the need of an ESP8266 toolchain). +* To build type `make`. To build only for the ESP32 family, type `make WITHOUT_ESP8266=1` (this negates the need of an ESP8266 toolchain). Activating an ESP-IDF environment takes care of most of these steps (only the ESP8266 gcc toolchain has to be manually added to PATH). # To Test -To test the built stub, you can run `make embed` (or `make embed_esp32`), which will update the stubs in `esptool.py` to the newly compiled ones. Or there are some convenience wrappers to make testing quicker to iterate on: +To test the built stub, you can run `make install` (or `make install WITHOUT_ESP8266=1`), which will update the stubs in `esptool.py` to the newly compiled ones. Or there are some convenience wrappers to make testing quicker to iterate on: * Running `esptool_test_stub.py` is the same as running `esptool.py`, only it uses the just-compiled stubs from the build directory. diff --git a/flasher_stub/include/rom_functions.h b/flasher_stub/include/rom_functions.h index 84a920344..6259dae88 100644 --- a/flasher_stub/include/rom_functions.h +++ b/flasher_stub/include/rom_functions.h @@ -107,6 +107,10 @@ SpiFlashOpResult SPI_Encrypt_Write(uint32_t flash_addr, const void* data, uint32 #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 --git a/flasher_stub/include/soc_support.h b/flasher_stub/include/soc_support.h index 823b4c1cc..d77b50d67 100644 --- a/flasher_stub/include/soc_support.h +++ b/flasher_stub/include/soc_support.h @@ -55,11 +55,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 -#define USE_MAX_CPU_FREQ (WITH_USB_JTAG_SERIAL || WITH_USB_OTG) +// 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 */ @@ -153,6 +166,13 @@ #define DR_REG_LP_WDT_BASE 0x600B1C00 #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 +#endif + /********************************************************** * UART peripheral * @@ -323,23 +343,39 @@ #ifdef ESP32S3 #define RTC_CNTL_OPTION1_REG (RTCCNTL_BASE_REG + 0x012C) -#define RTC_CNTL_WDTCONFIG0_REG (RTCCNTL_BASE_REG + 0x0090) // RTC_CNTL_RTC_WDTCONFIG0_REG +#define RTC_CNTL_WDTCONFIG0_REG (RTCCNTL_BASE_REG + 0x0098) // RTC_CNTL_RTC_WDTCONFIG0_REG #define RTC_CNTL_WDTWPROTECT_REG (RTCCNTL_BASE_REG + 0x00B0) // RTC_CNTL_RTC_WDTWPROTECT_REG +#define RTC_CNTL_SWD_CONF_REG (RTCCNTL_BASE_REG + 0x00B4) +#define RTC_CNTL_SWD_WPROTECT_REG (RTCCNTL_BASE_REG + 0x00B8) +#define RTC_CNTL_SWD_WKEY 0x8F1D312A +#define RTC_CNTL_SWD_AUTO_FEED_EN (1 << 31) #endif #ifdef ESP32C3 #define RTC_CNTL_WDTCONFIG0_REG (RTCCNTL_BASE_REG + 0x0090) #define RTC_CNTL_WDTWPROTECT_REG (RTCCNTL_BASE_REG + 0x00A8) +#define RTC_CNTL_SWD_CONF_REG (RTCCNTL_BASE_REG + 0x00AC) +#define RTC_CNTL_SWD_WPROTECT_REG (RTCCNTL_BASE_REG + 0x00B0) +#define RTC_CNTL_SWD_WKEY 0x8F1D312A +#define RTC_CNTL_SWD_AUTO_FEED_EN (1 << 31) #endif #ifdef ESP32C6 #define RTC_CNTL_WDTCONFIG0_REG (DR_REG_LP_WDT_BASE + 0x0) // LP_WDT_RWDT_CONFIG0_REG #define RTC_CNTL_WDTWPROTECT_REG (DR_REG_LP_WDT_BASE + 0x0018) // LP_WDT_RWDT_WPROTECT_REG +#define RTC_CNTL_SWD_CONF_REG (DR_REG_LP_WDT_BASE + 0x001C) // LP_WDT_SWD_CONFIG_REG +#define RTC_CNTL_SWD_WPROTECT_REG (DR_REG_LP_WDT_BASE + 0x0020) // LP_WDT_SWD_WPROTECT_REG +#define RTC_CNTL_SWD_WKEY 0x50D83AA1 +#define RTC_CNTL_SWD_AUTO_FEED_EN (1 << 18) #endif #ifdef ESP32H2 #define RTC_CNTL_WDTCONFIG0_REG (DR_REG_LP_WDT_BASE + 0x0) // LP_WDT_RWDT_CONFIG0_REG -#define RTC_CNTL_WDTWPROTECT_REG (DR_REG_LP_WDT_BASE + 0x0018) // LP_WDT_RWDT_WPROTECT_REG +#define RTC_CNTL_WDTWPROTECT_REG (DR_REG_LP_WDT_BASE + 0x001C) // LP_WDT_RWDT_WPROTECT_REG +#define RTC_CNTL_SWD_CONF_REG (DR_REG_LP_WDT_BASE + 0x0020) // LP_WDT_SWD_CONFIG_REG +#define RTC_CNTL_SWD_WPROTECT_REG (DR_REG_LP_WDT_BASE + 0x0024) // LP_WDT_SWD_WPROTECT_REG +#define RTC_CNTL_SWD_WKEY 0x50D83AA1 +#define RTC_CNTL_SWD_AUTO_FEED_EN (1 << 18) #endif #define RTC_CNTL_WDT_WKEY 0x50D83AA1 @@ -418,3 +454,28 @@ #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 +#define ROM_SPIFLASH_LEGACY 0x3ffae270 +#endif // ESP32 || ESP32S2 || ESP32S3 + +#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 diff --git a/flasher_stub/include/stub_flasher.h b/flasher_stub/include/stub_flasher.h index 79b8a24d8..3cf1f6310 100644 --- a/flasher_stub/include/stub_flasher.h +++ b/flasher_stub/include/stub_flasher.h @@ -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 @@ typedef enum { ESP_CMD_NOT_IMPLEMENTED = 0xFF, } esp_command_error; - -#endif /* STUB_FLASHER_H_ */ diff --git a/flasher_stub/ld/rom_32c3.ld b/flasher_stub/ld/rom_32c3.ld index 40f112d41..ecaaf4928 100755 --- a/flasher_stub/ld/rom_32c3.ld +++ b/flasher_stub/ld/rom_32c3.ld @@ -67,6 +67,7 @@ send_packet = 0x400000a8; 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 @@ _global_impure_ptr = 0x3fcdffdc; */ _rom_chip_id = 0x40000010; _rom_eco_version = 0x40000014; - diff --git a/flasher_stub/ld/rom_32h2.ld b/flasher_stub/ld/rom_32h2.ld index b736e491b..accb0adcf 100755 --- a/flasher_stub/ld/rom_32h2.ld +++ b/flasher_stub/ld/rom_32h2.ld @@ -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_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 ( 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 --git a/flasher_stub/ld/rom_32p4.ld b/flasher_stub/ld/rom_32p4.ld new file mode 100644 index 000000000..51ac8cded --- /dev/null +++ b/flasher_stub/ld/rom_32p4.ld @@ -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 --git a/flasher_stub/ld/stub_32.ld b/flasher_stub/ld/stub_32.ld index ca812c887..9ab825585 100644 --- a/flasher_stub/ld/stub_32.ld +++ b/flasher_stub/ld/stub_32.ld @@ -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 --git a/flasher_stub/ld/stub_32c3.ld b/flasher_stub/ld/stub_32c3.ld index b7c3e88aa..dc9d4201e 100644 --- a/flasher_stub/ld/stub_32c3.ld +++ b/flasher_stub/ld/stub_32c3.ld @@ -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 --git a/flasher_stub/ld/stub_32c6.ld b/flasher_stub/ld/stub_32c6.ld index 994a010fb..91b8d3137 100644 --- a/flasher_stub/ld/stub_32c6.ld +++ b/flasher_stub/ld/stub_32c6.ld @@ -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 --git a/flasher_stub/ld/stub_32c6_beta.ld b/flasher_stub/ld/stub_32c6_beta.ld index 89ab54df1..5acb1029b 100644 --- a/flasher_stub/ld/stub_32c6_beta.ld +++ b/flasher_stub/ld/stub_32c6_beta.ld @@ -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 --git a/flasher_stub/ld/stub_32h2.ld b/flasher_stub/ld/stub_32h2.ld index 16559d807..c94f5939e 100644 --- a/flasher_stub/ld/stub_32h2.ld +++ b/flasher_stub/ld/stub_32h2.ld @@ -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 --git a/flasher_stub/ld/stub_32h2_beta_1.ld b/flasher_stub/ld/stub_32h2_beta_1.ld index da6e273bf..62b16372c 100644 --- a/flasher_stub/ld/stub_32h2_beta_1.ld +++ b/flasher_stub/ld/stub_32h2_beta_1.ld @@ -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 --git a/flasher_stub/ld/stub_32h2_beta_2.ld b/flasher_stub/ld/stub_32h2_beta_2.ld index 07876ae6e..903b497ee 100644 --- a/flasher_stub/ld/stub_32h2_beta_2.ld +++ b/flasher_stub/ld/stub_32h2_beta_2.ld @@ -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 --git a/flasher_stub/ld/stub_32p4.ld b/flasher_stub/ld/stub_32p4.ld new file mode 100644 index 000000000..bf7e46a4e --- /dev/null +++ b/flasher_stub/ld/stub_32p4.ld @@ -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 --git a/flasher_stub/ld/stub_32s2.ld b/flasher_stub/ld/stub_32s2.ld index 06a32ff37..ccec2b79c 100644 --- a/flasher_stub/ld/stub_32s2.ld +++ b/flasher_stub/ld/stub_32s2.ld @@ -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 --git a/flasher_stub/ld/stub_32s3.ld b/flasher_stub/ld/stub_32s3.ld index 08eaae1ec..98cce2284 100644 --- a/flasher_stub/ld/stub_32s3.ld +++ b/flasher_stub/ld/stub_32s3.ld @@ -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 --git a/flasher_stub/ld/stub_32s3_beta_2.ld b/flasher_stub/ld/stub_32s3_beta_2.ld index 86f5405fa..5105e30d9 100644 --- a/flasher_stub/ld/stub_32s3_beta_2.ld +++ b/flasher_stub/ld/stub_32s3_beta_2.ld @@ -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 --git a/flasher_stub/ld/stub_8266.ld b/flasher_stub/ld/stub_8266.ld index 9f837a456..a42b9b25e 100644 --- a/flasher_stub/ld/stub_8266.ld +++ b/flasher_stub/ld/stub_8266.ld @@ -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 --git a/flasher_stub/stub_commands.c b/flasher_stub/stub_commands.c index 169c266b9..11340e19d 100644 --- a/flasher_stub/stub_commands.c +++ b/flasher_stub/stub_commands.c @@ -49,7 +49,7 @@ int handle_flash_erase(uint32_t addr, uint32_t len) { 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 @@ int handle_flash_erase(uint32_t addr, uint32_t len) { 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 @@ int handle_flash_erase(uint32_t addr, uint32_t len) { 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 @@ void handle_flash_read(uint32_t addr, uint32_t len, uint32_t block_size, 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 @@ int handle_flash_get_md5sum(uint32_t addr, uint32_t len) { 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); @@ -254,7 +254,14 @@ esp_command_error handle_get_security_info() 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 --git a/flasher_stub/stub_flasher.c b/flasher_stub/stub_flasher.c index 69edd7cda..6b5885039 100644 --- a/flasher_stub/stub_flasher.c +++ b/flasher_stub/stub_flasher.c @@ -108,17 +108,41 @@ static void reset_cpu_freq() #endif // USE_MAX_CPU_FREQ #if WITH_USB_JTAG_SERIAL -static void disable_rtc_watchdog() +static void disable_watchdogs() { if (stub_uses_usb_jtag_serial()) { WRITE_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY); // Disable write protection WRITE_REG(RTC_CNTL_WDTCONFIG0_REG, 0x0); // Disable RTC watchdog WRITE_REG(RTC_CNTL_WDTWPROTECT_REG, 0x0); // Re-enable write protection + + WRITE_REG(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY); // Disable write protection + REG_SET_MASK(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN); // Autofeed super watchdog + WRITE_REG(RTC_CNTL_SWD_WPROTECT_REG, 0x0); // Re-enable write protection } } #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); @@ -442,65 +466,72 @@ void stub_main() { 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_rtc_watchdog(); + 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(); - - 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); + #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 + + /* 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 --git a/flasher_stub/stub_io.c b/flasher_stub/stub_io.c index 409c24f8d..6cff6c377 100644 --- a/flasher_stub/stub_io.c +++ b/flasher_stub/stub_io.c @@ -71,7 +71,7 @@ static void stub_configure_rx_uart(void) 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 --git a/flasher_stub/stub_write_flash.c b/flasher_stub/stub_write_flash.c index b166976d8..e925d9f74 100644 --- a/flasher_stub/stub_write_flash.c +++ b/flasher_stub/stub_write_flash.c @@ -96,15 +96,7 @@ static void spi_write_enable(void) } #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 @@ SpiFlashOpResult SPIUnlock(void) 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 @@ SpiFlashOpResult SPIUnlock(void) 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 @@ static esp_rom_spiflash_result_t SPIWrite4B(int spi_num, uint32_t target, uint8_ 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 @@ esp_command_error handle_flash_begin(uint32_t total_size, uint32_t offset) { 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,14 +258,14 @@ static void start_next_erase(void) 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(); esp_rom_opiflash_wren(); esp_rom_opiflash_exec_cmd(1, SPI_FLASH_SLOWRD_MODE, - CMD_LARGE_BLOCK_ERASE, 8, + CMD_LARGE_BLOCK_ERASE, 8, fs.next_erase_sector * FLASH_SECTOR_SIZE, 24, 0, NULL, 0, @@ -291,7 +283,7 @@ static void start_next_erase(void) esp_rom_opiflash_wren(); esp_rom_opiflash_exec_cmd(1, SPI_FLASH_SLOWRD_MODE, - CMD_SECTOR_ERASE, 8, + CMD_SECTOR_ERASE, 8, fs.next_erase_sector * FLASH_SECTOR_SIZE, 24, 0, NULL, 0, @@ -354,14 +346,14 @@ void handle_flash_data(void *data_buf, uint32_t length) { /* 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; @@ -423,6 +415,13 @@ void handle_flash_encrypt_data(void *data_buf, uint32_t length) { #endif // !ESP8266 void handle_flash_deflated_data(void *data_buf, uint32_t length) { + /* if all data has been uploaded and another block comes, + accept it only if it is part of a 4-byte Adler-32 checksum */ + if (fs.remaining == 0 && length > 4) { + fs.last_error = ESP_TOO_MUCH_DATA; + return; + } + static uint8_t out_buf[32768]; static uint8_t *next_out = out_buf; int status = TINFL_STATUS_NEEDS_MORE_INPUT; @@ -464,9 +463,6 @@ void handle_flash_deflated_data(void *data_buf, uint32_t length) { if (status == TINFL_STATUS_DONE && fs.remaining > 0) { fs.last_error = ESP_NOT_ENOUGH_DATA; } - if (status != TINFL_STATUS_DONE && fs.remaining == 0) { - fs.last_error = ESP_TOO_MUCH_DATA; - } } esp_command_error handle_flash_end(void) diff --git a/flasher_stub/wrap_stub.py b/flasher_stub/wrap_stub.py index d206a9599..504d9f883 100755 --- a/flasher_stub/wrap_stub.py +++ b/flasher_stub/wrap_stub.py @@ -17,8 +17,7 @@ import esptool # noqa: E402 THIS_DIR = os.path.dirname(__file__) -BUILD_DIR = os.path.join(THIS_DIR, "./build/") -STUBS_DIR = os.path.join(THIS_DIR, "../esptool/targets/stub_flasher/") +BUILD_DIR = os.path.join(THIS_DIR, "build") def wrap_stub(elf_file): @@ -67,8 +66,7 @@ def default(self, obj): return json.JSONEncoder.default(self, obj) for filename, stub_data in stubs_dict.items(): - DIR = STUBS_DIR if args.embed else BUILD_DIR - with open(DIR + filename, "w") as outfile: + with open(os.path.join(BUILD_DIR, filename), "w") as outfile: json.dump(stub_data, outfile, cls=BytesEncoder, indent=4) @@ -79,9 +77,6 @@ def stub_name(filename): if __name__ == "__main__": parser = argparse.ArgumentParser() - parser.add_argument( - "--embed", help="Embed stub json files into esptool.py", action="store_true" - ) parser.add_argument("elf_files", nargs="+", help="Stub ELF files to convert") args = parser.parse_args() diff --git a/setup.py b/setup.py index 4b4d0490b..0f1b2826b 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ def find_version(*file_paths): if os.name != "nt": - scripts = ["esptool.py", "espefuse.py", "espsecure.py"] + scripts = ["esptool.py", "espefuse.py", "espsecure.py", "esp_rfc2217_server.py"] entry_points = {} else: scripts = [] @@ -47,6 +47,7 @@ def find_version(*file_paths): "esptool.py=esptool.__init__:_main", "espsecure.py=espsecure.__init__:_main", "espefuse.py=espefuse.__init__:_main", + "esp_rfc2217_server.py=esp_rfc2217_server:main", ], } @@ -100,6 +101,8 @@ def find_version(*file_paths): "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 []), @@ -114,6 +117,7 @@ def find_version(*file_paths): "pre-commit", "pytest", "pytest-rerunfailures", + "requests", ], "hsm": [ "python-pkcs11", @@ -124,7 +128,9 @@ def find_version(*file_paths): "cryptography>=2.1.4", "ecdsa>=0.16.0", "pyserial>=3.0", - "reedsolo>=1.5.3,<=1.6.0", + "reedsolo>=1.5.3,<1.8", + "PyYAML>=5.1", + "intelhex", ], packages=find_packages(), include_package_data=True, diff --git a/test/.covconf b/test/.covconf index 07eaf71da..a36bbba25 100644 --- a/test/.covconf +++ b/test/.covconf @@ -1,2 +1,8 @@ [run] parallel = true + +[paths] +source = + ./ + ./ + C:\GitLab-Runner\builds\*\*\espressif\esptool\ \ No newline at end of file diff --git a/test/conftest.py b/test/conftest.py index 9cc2ff08a..b87fe5624 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -40,6 +40,18 @@ def pytest_configure(config): global arg_reset_port arg_reset_port = config.getoption("--reset-port") + # register custom markers + config.addinivalue_line( + "markers", + "host_test: mark esptool tests that run on the host machine only " + "(don't require a real chip connected).", + ) + + config.addinivalue_line( + "markers", + "quick_test: mark esptool tests checking basic functionality.", + ) + def need_to_install_package_err(): pytest.exit( diff --git a/test/images/bootloader_esp32_v5_2.bin b/test/images/bootloader_esp32_v5_2.bin new file mode 100644 index 0000000000000000000000000000000000000000..d7a5cfb96d3df1f23a02c659eefb62ea88541955 GIT binary patch literal 26768 zcmbt+3tUr2*7&_QA%t+X0g)=u_9hq%7Ht3@Nb8ayMe)%BRYa>F1PDSa4Y+$ksOaU-&$nn&XbeB3F z#STNw*i@2lG-N-xirl{CZqQ`!ng?jIlWrbwV-Xm= zeVin^2cNNsdB#wZpSxv@Dhb14j9|uVQ1Z>OwE~Av>|GHUY-!>DFP&Mh7N)kJM(RPLXc4fqMacP;&BVGfLu zUufuf4M3gAFU&0(Q=l||E9g1uP$^?9Dq>0tz&0`Jg8ah#g0cb_x=hv9e06!^r=F7NZBD7T)AA!adA^K?Wsr(+=O=bVBP!EiogEpqpiIprQr2m2kUaMi;Ca zV;d81Yt-m?WMB>{LUVMpo|_c!+TgKVjhh5Yf03(Puy%PFNWSz=!}Vsps41S#U}lc7 z+n~aNiV0SRF>KB@7;;J(fhv=omtQ<4_pYo9mKP1~@`O21$dLVXDX1nWEQqIQlOgA> z1(OQ1i%Loi*~W1t?}~oM#(*N{XETLm1zCoY+l}*h^}JPF=v5{UdI|K%Xefcv1U4S@ z8|S4h5yE6G=&hR-Luqk_FktQ^;f15^b^8{xn1%Wc*<~B_Mwm2lUSvuP;2z-DUE3wl z#_81E3CP!ISGikX|5E7A-5pDgS0)7wEx? zdHTpum=nqTiYYaMK1C7_J(QG?_)vCHK{0eL%&`xRG5)1x#l_$-J(ORVy`e0}FgB~q zn7?6G9s#tXMrlP6MPTzc=!;8*A>p3ou$t_r@0cUZQa6iu(34Vi%ZV%yCdL_kPELuT zw3I2)7p^xDn3MrELWRO7=Ki<%FD=P_=w|U_nDd+>Luui3@JREGIKFS`<}DmIF>DS2?!cW`8q*(cJ0R$q z$H{f;({0n!Z7Sln&ZABgv7<~___xsm`5~zWyMA}u}3!- zgCWFWjiko(EDooP62p4%K}$0{V}fvdP#HIM9Y%tolmPZ}z%5oRU>;k!Y}x-r|D&VE zj^NTfJ&XYygc+a`jEb4fECA1!*i=-KQ<{Mc0-q`-e%a#-mu9SbJT>77%%7`a9%5$y z2P6$)g5}u%FQ~9cd z6=11xF@p{mj%8+H@=93$Ef7Wnqu!*4s$1D;b+Qi&?nGnJGO0rReBpsUa=hS?Z~(l5A3f+0ik=R*tJ zR7wobFuz*BJfq5)g*39tjP7(WDeknp%GPa;eohVa@IO(@D$C6U6Zk*1En|cQGj&c; z0qE(Nv|L!CXSg%QC8Jk+Cvh4}@Q!McBRs|gHAj_j`8F@~)%^EbF88948`-ACLwnmtqS z0AVGyzVH{^>AR4_6(kt3%|b)|Po#2iv*{N}8Qc@af5&sYo!f`d6}vqVw56b^G+&s8 zKuN)N!+=d^>-~*R_IwaqqB6=r5g31gl%SbS&s-{ zGZ6d>f$i~*W^$1c7UcObkZ_M_eOW1!zCyR`7EPRX7{NVTUj`E$x=>MbF<}gA|7VJ` zHNQwP{ulVVD;o>-xF`n035z7y^BCW%2-sJHoh5f`ez`Hw<}8rS=r+p2#~({fT9kq0 zG7?iCO+md7Hhk2A7aKl{NiZ1Q%P+U!#(Ie3d;TWLac(i}7L|G24>(fU1nQfSy(N1C zcx;crq&08uyq|mbxa*L&DPwdaMc7RdJo$&P_i^~ZMeh*;9vxIi`^Mp1;(-#*25CZf905WU(;`rY~$zGn%f$uzk6#(e~YXJf? zPZH^sgqD7V&|dfxp_OX-;uwG~(iL}I>xv_~27oW*tv?P~E6*H=TMPC4@Tr$p?8nDV z1bE>2?^7Owa4!IvNe~o(9L_V>A%6foG!G^534Heg9NR-^0|2^SBDBvzXad|<;rqc! zeB4%m4*&?FBu)wz!<+FJ|o9n>)gXea;@Qbd{jB!ZA$?~7{!XeX}65$3+Q z8h{7@Iq>==&kxh^jRKegaTMeGfY)TgG(Jv6@^L>v{c|DA1^5F1h+oU|zXgZ`pz#~i z0OI04h5Q64zZO7F@o|pA$$%4I05)q0KNrq02<`I3!h&J0YTgV zncRr0ey%U>tHC(H`ILVI^sO9q7Dz}zkBi~^4S=P~mM+8kBA^W#%oj|BgAal4IFQ8k zB#L;QC5UE-yLb>IlwC0e`e-VQRk&#&hPXEV9)gB2SQ;#SRYyQO_m8ge?Z{;Ct#N+Oz=ZyLV7;H2FSC2N@)3?pxwXa`PU&$&VcPefMMFK zkZA4jZ3p{;b_~+AVu+jE`4r<0$-bEqZOAN%HWNUKX$(P5gYbKTC_Vx3G{D0Ez5pVC z2%(&qn5!cc2VCt8VUB_yb(E<>e8%j@gimAC%zf7h%(s>kGi9Fd%uHj1Pa_H5t}!{; zxc>OWvwv{e{@`kD4CD5=x_?dXhm;1F?PW-rUO9xaV_$Y%+Km;QSHsWA&G2)~3_n*f zdS!DtFXzeY*BDH}yesuLs$JKw$!Rbpqv`cRdO27jKgeO+$n`WuKOm6M^lVd@TntY# z*W_a1wkY?-_*fA1LaNkp1Jxt5VH`eLOMh2u}oQ ziEW%ITBA|Qh5pqO=PU%YEmcowdKqn(@$`hY35>;P=;BcWKo=rsx@iByA{9?97F8Vi zl{T|%MhP!>kvgxz$zLo5|y2YZ%G?P2U!RCMU$z-Py#UQ9t?VkYJjJy`>v;2POf@+ zo;KZ>`+1~RYYbVr=*@6?=V=NGuIcXO3uNxdBWqN>yd~L4Ps_~g(>^MH=NY=P^D^II zA==+z=$-T$)eWAemjiYi{m2@_b>1|?PpbsA?u$RnFQQ(IZzO=x5J~4}eEGTQ&r^wA zyk;L`{YhZwOdEq7{|Fq@)otQOf($?KlFxWzuAX2zn75voc=q2;Tep+@yR)^i$hw3) z6YbYyAv7A}eDcS8=$#=itUYM>M3AU3zGymRCveqhd8PYXzQV#2GyDj%pGhgVn958_ z22xBAJt(&*VMJmdoN_jX64s@JWd;)%OQ2Nf;1C%|&|)#>etb>!IMF7vbvn6DC;OqZ zOG;d%P(F>87+@B$mtC&GKeXvXEji z_dY{BHOjTco5!bQr_TR(9N=qnAqzuk*~pZOV^F=Cx9l83a9f{T`}v z9l^eYEY6greLVG|?6i!2l75@5yV+1LdMo=ojDdvkyZUC1gxK zJ4g8b?PyM$h~C5g+MT0$9Xiy9-HfqIMNW1DHc35E^Cos|vywUcG$w>k#MBA4Jf}Mq zlTd_enlp?^qA^KUs~?jj!z3T=N)I_K=%Yw=>YqTe$EeH%Khq2Hl5D;HHG4pl5=GllnA6bf-(CoH7$V?3Fi69#>GEW27;`o zUN5DkU*w0=G20!}YIcyOD)}LM%XDY0H{K|f1_oZecqV^=5GkKvy0F&xtyVQMAHiaLx})26(6gNU^;m)g|nWkz9WYe%qt{vEdg!3>!@8L7MC|?%7;DWt{4C~ni`fERj7iynXqXSv!?H%OSFa$BXD(wJ877`l zO#%x#eb2-g<6*JE$y@fd(~~Tr+XVV75l_+UC?z$)q{QjrP`tsxE4?OM_M#yH>|pf> zw{xWHGDA;b3y^Yok5D1l@tv}P&>mgoNS&8l`&6T;!7tOG%S^Or6D(Z`e%dANjb8Uy zwlJHHJyfMr_3?`Gkv19gMWb!=$eGV|XMVJFU9)hTN4l>0C6P`^*SGELN+fUAmG|UM z`a_hLe~Fi$DcY|%nn`_+FFE2&PVOr%?pt+~O8ko79!+&#Yl*ufa^gQP>+$itM1 z8kJo=MNbLy@u|m20EdnyOqdN_Y1%>N!XW+Y7M zLr(#^RohIa%$d^Bx>BM?;=PE#*`)O=9{NK%!f8fW88#@wMs3Z*9DeNw7RiZ3=jY{r7NrKe5uUUYfj0zI(D3 z*!mKwBcK1o584;nMnAA@;zh6KzcB3IF|GQaXD>13f z{d{=O?&Q_&^VK-vw%AX+L z`WTgM3z(SxYGEXME*VzI#2@IU?vV_|#`kGvGAROS+SI=nCLZQ969n4sW*y z&-7Vj52Tfw?0$6Aw^wLQ1DIAhok}MO))ep`QM${~Qrqu`&(;iYuY36Hj$zx5VeW^rUfSG%^Rg#W{$;Z#k1ZW8|K5Wz2D@e2@VL_DTgOD3 zq#GPH2NC;#l*<{0&@6-YL0Bc@^zL}`X#Bs1TPEF>wC1)VtK9LHwBehjRt&eSxLK;@ z3H+==55?@uB@ct2Ne7)dNLoDJ0=s-z@JXAb%?GiO2e8FWQkecBY>={v!`x3e@zzVn zG@@S0>29`Bn9mHqA#bjW%dhBSha(>z-tIp&mzvT2GUyr?Gkj63d5>Yg83J7aaTA7@ zP>EpJaZ$sN(P;J*2G&1?0)JKP_5x{QCveq8O4Ebwz_ZNd|eveUK+pgbXi= zY7U_)dwDi!c-}GVqNql?LUNra==jQOp0Q;1ZxfwTqiMuBAb?Dp!K-%g=alI5i-x%g z!?Zu!iad6@?emO^5SnS82A(>j(9zYklHqoxoDt;Q!F^MSqVeu-x#bW!6i)^?M%Y5n9&W#dm+l3+X|sE*_>`OmDQ1hOc<* z571P$0t;Gm2(_Y%0(EUYBC?zyYo8f<`{4fh)A#|!io zk2LG*r(`_@8w7QFqGjJuqnctX5dl$%qk@9ongqqA;GajFkgZC2O}9(HZXIZngtr5p_{gMLNYm`Vy87&W(DHsr(iOA7C763OhNk+^42qu3I#ed;FNmG<$LAgJ#Cu zTt6u(CSDoVpbk!m&kED&hAO||7l)cBB}G*!b-x;te9aR=G_@*T7d-?%pg>O-Ih3oW zI=|!xVghs#Luq*f0+N3frJFS*0Uty+V<>kqRrxnwryj~prxMTdy6HompYn5UL=zRb z#P^tgP8qeEcUqVI<;@wZV!T*Q#(njhPO+$)d#@xJTU^}HpPNed#ai$FA2{LfQ1 zhl2|p0@ng0&|zT?ldK9Q9YMGLP5v>*Dlh_DNE`V`(GV?_b4LqQW&Tbw% zst(;5Yd8{k%K<|&3d=*|+9>GSmjq(xpuI${XhMuq9W|c}_fwNGe&AhS*}h8>6R%E9 z9O7vyJ@iNEyjZ$X8Mc3)go$ph&o-AfkX3#-+X?dmP7gRgu&*FZ#a;(3_4v4YBJCV; zc8|lh#}N_C?Qs|;6Ivz!+|yHy`dy9?pArjs>a+W;k1LhyIENwB*{m!9z(_*QxG>NLn2E}ndb|+S5CXe|YkS>j`S1dIj-E|qUC2N#B zp0CIyk`vla_t_A-V21hqKKe^8-!q*_SeEHw-F7~E+q94YG@ zO%%Hl>FHNHo{C?x@PJs^AzoE?1&};*G5YT-5W^GaQXM~ffeoeF#OyIUq=PC8eX`uq z)$C{b-DJj0Hn-|bCm1ft(fWy#J%UK=B8MqY>zzkk*9p3>6Ud>>u9yZEt>mP9ObwuX0wreCOAo5?!iZz`jg* z+4}9=pxx;OMbfZHVh>M*JQtreuk$(|#gU0W0b3Fn|1e(WDJPu$(Qf<@O^ReQ*ACycx)^QOT9ou0Z%Nzy(wYB_^Tb?BQ#yC_Ksu_$!n+3)PO@9f-n z_EzpGSVwQXYOlR&-&(rqIMt~p*l+C{FWGlIxBWOJSxX!yTmEgoC_XJ}{HMua=Qn;~ zPkVcE%OyK^$qs%kSeNbrKJBT1v_FeCUbNFwKwH|RRXQwi*xS(0n{{;Hq3`tP?c8~L zacO()d-kVtHodKk?69}_oEEK*^`V2A6QuS;`<@f@{TICsQ?T<~Aj9>m=4AVxQ*A!$ zW51z;Bj2*Sv0_ia^bJO1;|KQIP9SIkmL;JC`@VhS8+OxkCgk}cqQz$CYy#7;WuGRS zkoNbXjeoUse-)CThrj3Pz`#9@+PCfO+jg$iUX$Ivb?CamYFY-_J0-rX~_E>Ly zt6iJhz9;vzFEZ99Nj%RJnoaF{j&6^=SN|9L#$A}bHFr_yMa(}fNre5B0w3_T^?$Z+ z{4e`c*{s#R{%BBE6L}_=gxEfa(dBQ!LC;g!>*vv|1w>2-Zl6bWzQ=ET-kwN8vxto* zd!Ut6opZqiWGl9F_4X1y;S~QUg7xd!LC^|XB00tr8#mh%`=Jq%HwAsDpn@Bf^Q!BA z=&Ml9t2oJ2WX)45LF1>tK4 zVPW2G-EmMg;)I4W#XFgL~@e;N9;~ zFztcw-?C?ro;v*mDxH~u5%a_O+%=loY&#bOWp}?FQU|hVAo0_${J0jrlz<*fnd%wX zHNq_(T3YD@^-Y9jG%@!QvAQJ(m!!kKs_v1kq@*+-;J@-ehw>+iR7DR$O`?M{4vAX*g?Xfj=W z*h}@jYq@Oi*6z0vE5Od_>=(V*XAp0uu)S5G@CmF(d_b03U*;F<>-Bj7^pwovfO;QV zT)cP}n?2Z|qwif0>o4!(1O~VXoJOT>Bdu?`fE(E43vWJOVRH_05q35c3F{n#k}Ev% z!pe>B46fdou47LOZY`rHZ#qV<6PtAz9_>L;e^ zrD-pF)we9(n5Q?VB>AKV2Ah{QypX$QMO8{eOTJ#h@#eE>=ZUn}M+|><>3$kqCxY3k zQ6cXBlDBMSPW>}2bh!Ifm+tCd;G=_JfR~HXw%NP)xz>5>z8-{OWoGHArs6)@%Y3PL z^{(Xf_8OxGcAkohjhQR6tLN3s3gHZLYw7xay|_R=L1%E?;%*^f7M7?s}i!1O_T-K#`X?T({B@SI*=b1J*Lls~7C1Kp)&$qziy6jXTw{L6WZ zZLnZm6CIT`j}}YT!`QVEv^2@~EL9-=qjVsO_Epk>OeJi18tZJ+l$M{uYt=SdMo&J# zGS+Pt#+de0kVdsFjS4y@Y78YizP#S9+GYBjtoBcPOSZp_s(g^3y-s^I*?yE(U1~Uc zQDUg&&6n!WE|;Z!CoB2TrDo}nx2BV)WsM5jbd0IcPyEs6B4zjpkO1XvDSdzSGnY~Z zy9%{kUE&S}-Ky}p2$aC}tZ<|3kQ|%TWV}0IRKuglLdZm3XscuB~6n)YHK8YQe z9+FZvsP@_$ub#Y@GTREoQ71#pHl@^S`kyJu3}IY#*qHqbD9Pu1*u9ff+n_Vgg_5>8 zgIxX~yL$k-E1sj8*y>o?*P6#S*}(Ipec3_G==_Nf>~KV?2Q}GR?`%qPi4Qr|CObej z+QjTnh;W!{BMk=LwrViK_b_Q)&Bxea_j^VtE<(Y(VppIxfO2>L8VCH8LGH0Zb}JUN zEyog+H4U1e^BaUERYfRaYC<6yjzH^wcq%yeg=ooX-c)DV?Bks^smaT-NwdW#Sh;yp zafxnI)Hks2(li+kE@-N9h=&$*zK`cTZLrBh&oEr_oTrm1s|Vm*c=Kf1Yqhw5N`9WH zjT~$YBx-8Q;ESXuI%hy`G*)h2JW<+1+w9YVL-@;?4EE5^uPSzz>tbv+WJ z205?6&hKGQX$ovN$*BObtdq2s`xrYlcN zzy+hgys^K<IhOfyluDa9@>qc#5S|`|F88xV<2x_`6dg z2L^})zuOag25wKe_Oq1lf0pv??J3Rk$xNl(eaAwX=dLlFUO1W%F0c?*{yJ3F1)I3S zai=mb%*`2Hdh>q9Xjy-{6m~O4i@WJf0_<>f=hbk}rVoytZpD#K-Xt0ibU^}=B?OTh z>ZNZUs5}Zs@dNXzD*v=?KPp}u(7omslAE7Uu6aP~5fUC$D%GL7{Xa|D_p=ns&rM*Ur?q(^TgDV%9;4TGB z3YRd(r&vrkacHBv90TWRY#bOXBk;!=xG(O-cUYrs}VFc%bGEX!qVi z&N%WmkLez^N>#zYZlTgi|F>^e`a59`ZFB@r6c6 zuLuuS{)Nws_G8R)jj$bDkspeEAmsTgCJiv-^86*R8ICkyke|vQtzcBqD@V|FV*TX~ zc>{R?7wC;@b&arl-{mpdQ*EzLa@Wgbe@D41d^h2RgO={f!(^!I>6Z zf5t2Ulmk9X8)|QO5^p6TyT}uJsZVLa#@5Gtk&m|{D%7Gni^WtezIE2kUhd~E_an~u zGXpyII-EOrj#B6uVg8c+{>gB2&3(tA%&_6cl%30D7*drR8F|XCgjtL6aS66K~GH__UH)P*xzW?LN3b5-Jse( z_0zHgKDB=oSn}Dl#ZSnlgSu`>PB?FY3ktA~hgC@T6}|?@672K+T&+-QywJIw{i6pr zlF>UHY(Eqi2y>PFFy#iOid&DoJ9?^x8L}3(AL6Z?)^qfQ=STI@z0r+FemhF;kr}M9 z4`!zOt~Xjt(11<{zsz^cNtszzTZ|H`vl6i8f$~+d#6Ij7g&z5YTNnPON-?9>jOv!+ z$(!lh$ELF@`#Ec0n15)P^0Bnbc=tjr1+xkvTt#`TzwR|0vubILQl98dz-PUbQG%Y0 z*OEGp7}b$RE`oj3&ACvp+yT^JC_%pDJHGpp3wew|UepvbYcl9*m{L?t(NV}K0G&;&(nf7lFf#k_u6YEi>EKIE}8`m0OA{26fh3>Wdvi&|RyKp(IMpW#wEmYwdd z*v%(gsT@`1ME96i1bOP6=_SxpC_OTvOqM=VP5#@s)XS*{~*S3P5<_FsM6Wu#&Dfs@Sr^(PlQJ-%G6k?>@`+YUha!Vs-%$HgnJiYjvD3Vqyn)+%F2q+X- z5Y9SweL8P;;n@*KU_UF$}Sw?FS!1NZelW9t3Re8JEWLY4*G!ubrFj|dkf z^doM3gAf(bYu!;jMkAN>twou{h#D;x&95eFUfsqnLFH?Tid@vUm`oBG{=`f6!+Fm` zy?|!+hM)Qsv=L{8g!bB)KJb>nW{tLqjtzO0jm7ed0+&JC0-u0}1+Jq-e-tej(T@sE zI%j$BR-3fQ#5s#m@-a_~>1aBCoj5}BtT@re(>|jmj&`=e`0_++Il%oQu#o$xZlQe?292tyB;n-@mDE<)M)y23-5!|Pf z^wFgdnU9m7S{&KeE0ojTycsQyoYbdqp(N&0m3q$@Qw#~Bp%fGQv@m|ma>azc8D<6D z$Cw)xUVWyD&lz=vU<>txPTDu`jR|MH`)txaPTCjoq@miSzuHSr29k><^c3x4adLu& z_D=0^C2!uQ-GrI#zSgPm|@I z11-67uBR8wdQC1C%g1{PdD7Zzy*0T=bTs}w#)(~iqgbkauo)=t^b1pl&{8IE7hKxU z4WhQcJkj=XZEcxMIHHh zuO+%;UQ7y@c59Ur)_3Q6xpTd2YY!m1&sT*ug!%i?f$oN6CTKEOYC2Ex1k);%7&X+ z*5B}w8#p)P#U1NqI8y+_F#)cLG`H#4KcF}~`<{xLUbY^o$AI5vibhri<%*%$UA^Pu zmAA#88y_#X%i%t#dxeojuzGA;)IL0pF;jziBsg+G>{?7bwU8FUL_kEn$EWo=BU7<< zn0K~kf2-OkOfkj1Tv;!hjJTEV^D|gKPpKkVZBLz)ypY5d^|loC+KPJ3r1zEk)nvE` zyNgbRXx??`89AIv=3^V-fB?l?_Z0qiJdM9*-?YsrvGX!>>KU`ViWJTn;K=5`1R+Q@ znrUeZdG<+xDK*?{pOzNQ!`TWro^W-a_7`qX&eap#ie8!uCk-P!yR26sv>_ZdSS?K} z;c2Cr+)jD9m558~h11GjK5+>918%BShvCGXlF(bH64z8*)|yS*=l_swMf%?az-9uh z7P=j9?+Pvi_q06HTT>ygvplfqKs=l$X#`i*7K7YXJWbH%XUz1$*N^#ryay7F`z$>O zC+_j@cPZgiczSQGU=cl+oYJ=NiQn+17vZ)sqpgACMFo_o@(q3tHsDT8)tZd8p}iKZ zar^z zZh*psY|b22gZVy@vR?C~`e<-nwnuph?h2v$flrHt4JVOFS;3gzNZahf%MRc2?5P_j zrJN;@Ah>~pJqptO32{NF@L-~w7nYHDPg#HJ#>O_}BVAIwQogaj2R>H|M#o$K<_(xU zL!QaZB{NqtnC_i&rDsM?iHcl*R4i~&q7oOUUQS-$zW$8>xZMUP#o#}D1KmrDpo3vC zo7stp(COX(hTE=bJ4T9Ewl7&(ys{&+RX5|$niG~)^Rq?TcRaI_y>HO%U2v6W+)C z5YyAXgW(HXcp~c!KK^|saEJ2%$#!5)lW-#o`XJ@qo|bp9!A)N5jvLKu-dW3k`ocsql zs0Em*lt1_A_hU`MeY1S8$|%C7zwyO)RHtwldraDX0xiaIRDferdad>p*?s~=eq6d~ zh^o{PsXiq4yPgsB@$022DL3>l_9WlBh-a3iEV&WlKu!e3PI^Q@6iKb!HOQ zclnl$J!dm}YSVje6!$#h>fm5NQk|;_Q-$B6SyW{b*8dSc_^86C0}fmWnti~Ygvg%R zagRQ==PA6np69jWiF~i6=BW3y@$a`QJG5Y7*cCk~t9ljdwLyYp7uO?4!af4h#T~3tW5@|QBVp#K{(TUQog$`q=sy{)eYf2`dRLtsAS!=>0r$*HEId!ajQ#{ zukR=)w_X=?{u_%_O;9|5BtG(G#TbU8u!M1}tuSh}0f8%sij(k?z^L%*(U>h7W&8GB zUbN3laQ0*40d=uBNwhQ?wwUL#;NXj;S~2?h@GXY#h)rrZ25)Qe z-ScNGq1^}XR`&yJ5MPfg1~39_1}FzG0Xzp_2B-!|09XvL3?La`1wcB$T7XP|9Du(7 zt+xP%0q`v<)*pQjAJ->`H_8xV{5gP~@ZAJ(901=0;}cGNAN&c#wSZd*&<3Cdn#Vlv zp7E_SzSYJzok#<;A0A7-FBTqY<6BQtU)*AVQ;ax}5P%1m4)0La(0?yN9=>5_UWX2c$Ed5|ZE6m{TL97^UU=&&ynV$7tvu<%7qtmp zM5geL_FbM|065zK@Ez+{5aOFwd?U*fBfJsn#`pFy+P=8CurE*utFyT*sVLwBQwjEI z9t>^wBqDGIp<3urt{Bfpid(ct1+_)Aq@J5j#&H;4>`g<$Z;2=>`iq)Pl9m9G`u?j;orAYInuf#Bh zQmpXApYVjKo^TOgQ)5i?@iv)OL{#mr&r=m6KP!1|B`=($KY~@GZ?9P7DUs+2AH@)A zOu!IoThvmonDSQ#%TSIwr+YIxfW zNH~hV^t{;<&d%g*VGuut_j!r#b%b>)(S6b$Z+T^bZ2vT>GmKD$5Zxt&wGht4*axx2 z;A@6s2ywM19_ERwFjP$C=>Vaf8rV&DZx4V2%-)BYLb}eMPx0rqV?1K74Sk*{PG>Qc zI}(*ebn6I%w|%DUogh^@O26O5dGYMOTtKQ)LUgAIg1YYFc-LiE!@>poFE9&U7-GK| zQt|y>EN@+b;oGk61w!1#eu_xzWWdxZ{HpuFQGR}bEdFE1cAs4OAFGbf+b&)dQExK) z?LYoV^Shu;jbFS1QPWAw1trDM!w@jEf+gqSB?|cVb^*zVa zL56dD;zhwnG*rS?t;DoLo~u?>yoMijoCBtuI(U`a;Ab-R!F_qtLB_C?fX9X%ND~AB z{u1tf&aijSwntgAm6qiF(E*VsT=By0G^`I`hbihkmuA{F7*J*`lzWisoK8f(;W8=x z;zNm;Nl9dso>Z+EqUS^3HjwQ*$gTvK>hQbgJ!_x zI@0hYq1f%Bag8^hQoQ6UN7r>eEJ{FK_Y6hubnSM~uASANhc5mA^DH*cGTGBJXo```c60aJ0;+ zUBV4;;oY-gtz9wI6*faQ5c`NC&{Z9znB-E)alCR5xZvg!UIG{1JR|8q7c*^kSk%mc z_-T=H*P(d$2~$20Ink9UArw+qSnT`wyX3D5Zx^nIiAb3%H~uSwuRxA=fz5(T-3Rcw zZ-rPySD2og9Tp=WSiFSxuQpelbkXs2s3~+849rgur@fU_eDA!$JDcF1AsuoV&OR^t z5vTmv5zGaw_dKBkL+fL9TqswZ90{Qkf5bI1*W|P{IcZ2Qy!rQ6wI znW8=HXNa^1&LCAJ+N~>2?uwJGKuq_WCmdtf2jRt(iXS}twbRz+JaeuQB!kZncUnwl z3*2Aj{^c}XZfA{HiaP_fb(40u594o9Z)2EDVUIWR?@pR}ftw#0uIN7FXoF9~IS2gw z-Qj*{4xcYMx+e}TkTu$**8k^deARFU?sN-#P8X>TxHf$fsl&VM?1CM!@PC{x)b$ z9_p}MYLgY8@`D8H7lQ&0OSJsa8L|xCJy7gkL|#BHry607d4ma7cF!S}M(3vf1UEf> zRdbLi@TKZ;ESITz9SdZq)(9C_;YP0vUV5mW8d6j{ZPiZZ?MCKc1w1M>AwkUvKg+%k zEDtgfG1FrfMNF9hj0esrY4efiT^@NN|*u;~M``Wl}+ z>9loY~caNQ8`4U+PSPxVBYebh!$H~ z8{t6ZG+yxa#!j((H;Gj^V_2A}O~QXULPxbL$@wf3Er-)=m|BCT?+UhdIN+^NQ1=Ip zCf3q8S@k7`uTJj%6neY7r&&qPh}OKi%hGIg@2`OGK0$aePnk|nHl3Jk3ZJ}wv)XjT z3vSqL_d0kGOf(F0Qv-A66r2My%_sa|f~kR1rEmsy`z((Sxa*hK)Ofvv>*A*6@MFfG z`URHP;32s9+pG6N>?9@~!yonX_LBk4ZwD|D0kn?}QAxsmjeB9UQ>3|^tbzClPe;46;J8*eU=vovcm4UR{QsT& kwDgtP!{XA0haYMFx^1&|=2PV#w0!bkK^GtN^RgfM{~v_PbpQYW literal 0 HcmV?d00001 diff --git a/test/images/esp32c3_header_min_rev.bin b/test/images/esp32c3_header_min_rev.bin index 9c556e3ef07c319d45c61a09df2d29c4f7a7367c..1422b596fee093b4a950508acb12dec08b927bd1 100644 GIT binary patch delta 22 ccmXpo5O~SRB=COU+ItK@z{80BY $@" $(Q) $(CROSS_ESPRISCV32)gcc $(CFLAGS_ESPRISCV32) -DESP32H2=1 -Tapp_32h2.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) +$(APP_ELF_32P4): $(SRCS) $(BUILD_DIR) ld/app_32p4.ld + @echo " CC(32P4) $^ -> $@" + $(Q) $(CROSS_ESPRISCV32)gcc $(CFLAGS_ESPRISCV32) -DESP32P4=1 -Tapp_32p4.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS) + clean: $(Q) rm -rf $(BUILD_DIR) diff --git a/test/images/ram_helloworld/source/ld/app_32.ld b/test/images/ram_helloworld/source/ld/app_32.ld index ab5e15f7d..2301e0bea 100644 --- a/test/images/ram_helloworld/source/ld/app_32.ld +++ b/test/images/ram_helloworld/source/ld/app_32.ld @@ -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. - */ - MEMORY { iram : org = 0x4008c000, len = 0x1000 dram : org = 0x3ffc0000, len = 0xc000 diff --git a/test/images/ram_helloworld/source/ld/app_32c2.ld b/test/images/ram_helloworld/source/ld/app_32c2.ld index f9bb37b4e..cb792b06c 100644 --- a/test/images/ram_helloworld/source/ld/app_32c2.ld +++ b/test/images/ram_helloworld/source/ld/app_32c2.ld @@ -1,10 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - - MEMORY { iram : org = 0x40390000, len = 0x100 dram : org = 0x3FCD0000, len = 0x100 diff --git a/test/images/ram_helloworld/source/ld/app_32c3.ld b/test/images/ram_helloworld/source/ld/app_32c3.ld index a28a8a3aa..b9e1fe9db 100644 --- a/test/images/ram_helloworld/source/ld/app_32c3.ld +++ b/test/images/ram_helloworld/source/ld/app_32c3.ld @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x403DFD00, len = 0x100 dram : org = 0x3FCDFD00, len = 0x100 diff --git a/test/images/ram_helloworld/source/ld/app_32c6.ld b/test/images/ram_helloworld/source/ld/app_32c6.ld index 91055f1ab..a046073a6 100644 --- a/test/images/ram_helloworld/source/ld/app_32c6.ld +++ b/test/images/ram_helloworld/source/ld/app_32c6.ld @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40860000, len = 0x100 dram : org = 0x40870000, len = 0x100 diff --git a/test/images/ram_helloworld/source/ld/app_32h2.ld b/test/images/ram_helloworld/source/ld/app_32h2.ld index 766286255..1409330d1 100644 --- a/test/images/ram_helloworld/source/ld/app_32h2.ld +++ b/test/images/ram_helloworld/source/ld/app_32h2.ld @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40804000, len = 0x100 dram : org = 0x40848000, len = 0x100 diff --git a/test/images/ram_helloworld/source/ld/app_32p4.ld b/test/images/ram_helloworld/source/ld/app_32p4.ld new file mode 100644 index 000000000..1a4589dd7 --- /dev/null +++ b/test/images/ram_helloworld/source/ld/app_32p4.ld @@ -0,0 +1,26 @@ +MEMORY { + iram : org = 0x4FF60000, len = 0x100 + dram : org = 0x4FF70000, len = 0x100 +} + +ENTRY(ram_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 "../../../../flasher_stub/ld/rom_32p4.ld" diff --git a/test/images/ram_helloworld/source/ld/app_32s2.ld b/test/images/ram_helloworld/source/ld/app_32s2.ld index 76811c12a..7caf884cd 100644 --- a/test/images/ram_helloworld/source/ld/app_32s2.ld +++ b/test/images/ram_helloworld/source/ld/app_32s2.ld @@ -1,9 +1,3 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - MEMORY { iram : org = 0x40020000, len = 0x8000 dram : org = 0x3FFC8000, len = 0x8000 diff --git a/test/images/ram_helloworld/source/ld/app_32s3.ld b/test/images/ram_helloworld/source/ld/app_32s3.ld index 4d3d5da4d..ca263a1ef 100644 --- a/test/images/ram_helloworld/source/ld/app_32s3.ld +++ b/test/images/ram_helloworld/source/ld/app_32s3.ld @@ -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 = 0x100 dram : org = 0x3FCA0000, len = 0x100 diff --git a/test/images/ram_helloworld/source/ld/app_8266.ld b/test/images/ram_helloworld/source/ld/app_8266.ld index 218b9e191..3b7a1e04d 100644 --- a/test/images/ram_helloworld/source/ld/app_8266.ld +++ b/test/images/ram_helloworld/source/ld/app_8266.ld @@ -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. - */ - MEMORY { iram : org = 0x40108000, len = 0x2000 dram : org = 0x3FFE8000, len = 0x100 diff --git a/test/test_espefuse.py b/test/test_espefuse.py index 7179e711e..cb8ada0d0 100755 --- a/test/test_espefuse.py +++ b/test/test_espefuse.py @@ -1,7 +1,7 @@ # HOST_TEST for espefuse.py using the pytest framework # # Supports esp32, esp32s2, esp32s3beta2, esp32s3, -# esp32c3, esp32h2beta1, esp32c2, esp32c6 +# esp32c3, esp32h2beta1, esp32c2, esp32c6, esp32p4 # # How to use: # @@ -36,9 +36,9 @@ from conftest import arg_chip, arg_port, arg_reset_port, need_to_install_package_err TEST_DIR = os.path.abspath(os.path.dirname(__file__)) -IMAGES_DIR = os.path.join(TEST_DIR, "images/efuse/") -S_IMAGES_DIR = os.path.join(TEST_DIR, "secure_images/") -EFUSE_S_DIR = os.path.join(TEST_DIR, "efuse_scripts/") +IMAGES_DIR = os.path.join(TEST_DIR, "images", "efuse") +S_IMAGES_DIR = os.path.join(TEST_DIR, "secure_images") +EFUSE_S_DIR = os.path.join(TEST_DIR, "efuse_scripts") import pytest @@ -63,10 +63,11 @@ print("Running espefuse.py tests...") +@pytest.mark.host_test class EfuseTestCase: def setup_method(self): if reset_port is None: - self.efuse_file = tempfile.NamedTemporaryFile() + self.efuse_file = tempfile.NamedTemporaryFile(delete=False) self.base_cmd = ( f"{sys.executable} -m espefuse --chip {arg_chip} " f"--virt --path-efuse-file {self.efuse_file.name} -d" @@ -81,6 +82,7 @@ def setup_method(self): def teardown_method(self): if reset_port is None: self.efuse_file.close() + os.unlink(self.efuse_file.name) def reset_efuses(self): # reset and zero efuses @@ -178,12 +180,13 @@ def test_summary(self): def test_summary_json(self): self.espefuse_py("summary --format json") + @pytest.mark.skipif( + arg_chip == "esp32p4", reason="No Custom MAC Address defined yet" + ) def test_get_custom_mac(self): self.espefuse_py("get_custom_mac -h") if arg_chip == "esp32": right_msg = "Custom MAC Address is not set in the device." - elif arg_chip == "esp32h2beta1": - right_msg = "Custom MAC Address: 00:00:00:00:00:00:00:00 (OK)" else: right_msg = "Custom MAC Address: 00:00:00:00:00:00 (OK)" self.espefuse_py("get_custom_mac", check_msg=right_msg) @@ -277,9 +280,10 @@ def test_read_protect_efuse4(self): ret_code=2, ) else: + key1_purpose = "USER" if arg_chip in ["esp32p4"] else "RESERVED" self.espefuse_py( f"burn_key BLOCK_KEY0 {IMAGES_DIR}/256bit USER \ - BLOCK_KEY1 {IMAGES_DIR}/256bit RESERVED \ + BLOCK_KEY1 {IMAGES_DIR}/256bit {key1_purpose} \ BLOCK_KEY2 {IMAGES_DIR}/256bit SECURE_BOOT_DIGEST0 \ BLOCK_KEY3 {IMAGES_DIR}/256bit SECURE_BOOT_DIGEST1 \ BLOCK_KEY4 {IMAGES_DIR}/256bit SECURE_BOOT_DIGEST2 \ @@ -343,8 +347,12 @@ def test_write_protect_efuse(self): efuse_lists = """RD_DIS DIS_DOWNLOAD_ICACHE XTS_KEY_LENGTH_256 UART_PRINT_CONTROL""" efuse_lists2 = "RD_DIS DIS_DOWNLOAD_ICACHE" + elif arg_chip == "esp32p4": + efuse_lists = """RD_DIS KEY_PURPOSE_0 SECURE_BOOT_KEY_REVOKE0 + SPI_BOOT_CRYPT_CNT""" + efuse_lists2 = "RD_DIS KEY_PURPOSE_0 KEY_PURPOSE_2" else: - efuse_lists = """RD_DIS DIS_ICACHE DIS_DOWNLOAD_ICACHE DIS_FORCE_DOWNLOAD + efuse_lists = """RD_DIS DIS_ICACHE DIS_FORCE_DOWNLOAD DIS_CAN SOFT_DIS_JTAG DIS_DOWNLOAD_MANUAL_ENCRYPT USB_EXCHG_PINS WDT_DELAY_SEL SPI_BOOT_CRYPT_CNT SECURE_BOOT_KEY_REVOKE0 SECURE_BOOT_KEY_REVOKE1 @@ -352,14 +360,18 @@ def test_write_protect_efuse(self): KEY_PURPOSE_2 KEY_PURPOSE_3 KEY_PURPOSE_4 KEY_PURPOSE_5 SECURE_BOOT_EN SECURE_BOOT_AGGRESSIVE_REVOKE FLASH_TPUW DIS_DOWNLOAD_MODE - ENABLE_SECURITY_DOWNLOAD - UART_PRINT_CONTROL MAC SPI_PAD_CONFIG_CLK SPI_PAD_CONFIG_Q - SPI_PAD_CONFIG_D SPI_PAD_CONFIG_CS SPI_PAD_CONFIG_HD - SPI_PAD_CONFIG_WP SPI_PAD_CONFIG_DQS SPI_PAD_CONFIG_D4 - SPI_PAD_CONFIG_D5 SPI_PAD_CONFIG_D6 SPI_PAD_CONFIG_D7 - OPTIONAL_UNIQUE_ID + ENABLE_SECURITY_DOWNLOAD UART_PRINT_CONTROL + MAC OPTIONAL_UNIQUE_ID BLOCK_USR_DATA BLOCK_KEY0 BLOCK_KEY1 BLOCK_KEY2 BLOCK_KEY3 BLOCK_KEY4 BLOCK_KEY5""" + if arg_chip not in ["esp32h2", "esp32h2beta1"] and arg_chip not in [ + "esp32c6" + ]: + efuse_lists += """ DIS_DOWNLOAD_ICACHE + SPI_PAD_CONFIG_CLK SPI_PAD_CONFIG_Q + SPI_PAD_CONFIG_D SPI_PAD_CONFIG_CS SPI_PAD_CONFIG_HD + SPI_PAD_CONFIG_WP SPI_PAD_CONFIG_DQS SPI_PAD_CONFIG_D4 + SPI_PAD_CONFIG_D5 SPI_PAD_CONFIG_D6 SPI_PAD_CONFIG_D7""" efuse_lists2 = "RD_DIS DIS_ICACHE" self.espefuse_py(f"write_protect_efuse {efuse_lists}") output = self.espefuse_py(f"write_protect_efuse {efuse_lists2}") @@ -376,23 +388,18 @@ def test_write_protect_efuse2(self): ) +@pytest.mark.skipif(arg_chip == "esp32p4", reason="No Custom MAC Address defined yet") class TestBurnCustomMacCommands(EfuseTestCase): def test_burn_custom_mac(self): self.espefuse_py("burn_custom_mac -h") cmd = "burn_custom_mac AA:CD:EF:11:22:33" + mac = "aa:cd:ef:11:22:33" if arg_chip == "esp32": self.espefuse_py( - cmd, - check_msg="Custom MAC Address version 1: " - "aa:cd:ef:11:22:33 (CRC 0x63 OK)", + cmd, check_msg=f"Custom MAC Address version 1: {mac} (CRC 0x63 OK)" ) else: - mac_custom = ( - "aa:cd:ef:11:22:33:00:00" - if arg_chip == "esp32h2beta1" - else "aa:cd:ef:11:22:33" - ) - self.espefuse_py(cmd, check_msg=f"Custom MAC Address: {mac_custom} (OK)") + self.espefuse_py(cmd, check_msg=f"Custom MAC Address: {mac} (OK)") def test_burn_custom_mac2(self): self.espefuse_py( @@ -433,7 +440,7 @@ def test_burn_custom_mac_with_34_coding_scheme(self): @pytest.mark.skipif( - arg_chip in ["esp32c2", "esp32h2beta1", "esp32c3", "esp32c6", "esp32h2"], + arg_chip in ["esp32c2", "esp32h2beta1", "esp32c3", "esp32c6", "esp32h2", "esp32p4"], reason=f"TODO: add support set_flash_voltage for {arg_chip}", ) class TestSetFlashVoltageCommands(EfuseTestCase): @@ -619,6 +626,9 @@ def test_set_spi_flash_pin_efuses(self): assert "(Override SD_CMD pad (GPIO11/SPICS0)) 0b00000 -> 0b11111" in output assert "BURN BLOCK0 - OK (all write block bits are set)" in output + @pytest.mark.skipif( + arg_chip == "esp32p4", reason="No Custom MAC Address defined yet" + ) def test_burn_mac_custom_efuse(self): crc_msg = "(OK)" self.espefuse_py("burn_efuse -h") @@ -639,13 +649,11 @@ def test_burn_mac_custom_efuse(self): ret_code=2, ) self.espefuse_py("burn_efuse CUSTOM_MAC AA:CD:EF:01:02:03") - if arg_chip in ["esp32h2beta2", "esp32h2beta1"]: - self.espefuse_py( - "get_custom_mac", check_msg=f"aa:cd:ef:01:02:03:00:00 {crc_msg}" - ) - else: - self.espefuse_py("get_custom_mac", check_msg=f"aa:cd:ef:01:02:03 {crc_msg}") + self.espefuse_py("get_custom_mac", check_msg=f"aa:cd:ef:01:02:03 {crc_msg}") + @pytest.mark.skipif( + arg_chip == "esp32p4", reason="No such eFuses, will be defined later" + ) def test_burn_efuse(self): self.espefuse_py("burn_efuse -h") if arg_chip == "esp32": @@ -680,20 +688,19 @@ def test_burn_efuse(self): output = self.espefuse_py("summary -d") assert ( "read_regs: d6eae168 8f843a26 c9145f69 2328ad5a " - "00000000 00000000 00000000 00000000" in output - ) + "00000000 00000000 00000000 00000000" + ) in output assert "= 68 e1 ea d6 26 3a 84 8f 69 5f 14 c9 5a ad 28 23 R/W" in output efuse_from_blk2 = "BLK_VERSION_MAJOR" if arg_chip == "esp32s2": efuse_from_blk2 = "BLK_VERSION_MINOR" - if arg_chip == "esp32h2beta1": - efuse_from_blk2 = "BLOCK2_VERSION" - self.espefuse_py( - f"burn_efuse {efuse_from_blk2} 1", - check_msg="Burn into BLOCK_SYS_DATA is forbidden " - "(RS coding scheme does not allow this).", - ret_code=2, - ) + if arg_chip != "esp32c6": + self.espefuse_py( + f"burn_efuse {efuse_from_blk2} 1", + check_msg="Burn into BLOCK_SYS_DATA is forbidden " + "(RS coding scheme does not allow this).", + ret_code=2, + ) blk1 = "BLOCK_KEY1" blk2 = "BLOCK_KEY2" output = self.espefuse_py( @@ -707,12 +714,12 @@ def test_burn_efuse(self): output = self.espefuse_py("summary -d") assert ( "read_regs: 112233ff 11110000 11111111 11111111 " - "11111111 08091111 04050607 00010203" in output - ) + "11111111 08091111 04050607 00010203" + ) in output assert ( "= ff 33 22 11 00 00 11 11 11 11 11 11 11 11 11 11 " - "11 11 11 11 11 11 09 08 07 06 05 04 03 02 01 00 R/W" in output - ) + "11 11 11 11 11 11 09 08 07 06 05 04 03 02 01 00 R/W" + ) in output if blk2 is not None: output = self.espefuse_py( @@ -726,12 +733,12 @@ def test_burn_efuse(self): output = self.espefuse_py("summary -d") assert ( "read_regs: 03020100 07060504 11110908 11111111 " - "11111111 11111111 00001111 ff332211" in output - ) + "11111111 11111111 00001111 ff332211" + ) in output assert ( "= 00 01 02 03 04 05 06 07 08 09 11 11 11 11 11 11 " - "11 11 11 11 11 11 11 11 11 11 00 00 11 22 33 ff R/W" in output - ) + "11 11 11 11 11 11 11 11 11 11 00 00 11 22 33 ff R/W" + ) in output @pytest.mark.skipif( arg_chip != "esp32", reason="3/4 coding scheme is only in esp32" @@ -811,8 +818,15 @@ def test_burn_key_1_key_block(self): self.espefuse_py(f"burn_key BLOCK_KEY0 {IMAGES_DIR}/256bit XTS_AES_128_KEY") output = self.espefuse_py("summary -d") - assert "[3 ] read_regs: 00000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output + assert ( + "[3 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output + + assert ( + "= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? " + "?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-" + ) in output @pytest.mark.skipif(arg_chip != "esp32c2", reason="ESP32-C2-only") def test_burn_key_one_key_block_with_fe_and_sb_keys(self): @@ -830,8 +844,10 @@ def test_burn_key_one_key_block_with_fe_and_sb_keys(self): f"BLOCK_KEY0 {IMAGES_DIR}/128bit_key SECURE_BOOT_DIGEST --no-read-protect" ) output = self.espefuse_py("summary -d") - assert "[3 ] read_regs: 0c0d0e0f 08090a0b 04050607 00010203 " - "03020100 07060504 0b0a0908 0f0e0d0c" in output + assert ( + "[3 ] read_regs: 0c0d0e0f 08090a0b 04050607 00010203 " + "03020100 07060504 0b0a0908 0f0e0d0c" + ) in output self.espefuse_py( f"burn_key BLOCK_KEY0 {IMAGES_DIR}/128bit_key " @@ -839,8 +855,17 @@ def test_burn_key_one_key_block_with_fe_and_sb_keys(self): f"BLOCK_KEY0 {IMAGES_DIR}/128bit_key SECURE_BOOT_DIGEST" ) output = self.espefuse_py("summary -d") - assert "[3 ] read_regs: 00000000 00000000 00000000 00000000 " - "03020100 07060504 0b0a0908 0f0e0d0c" in output + assert ( + "[3 ] read_regs: 00000000 00000000 00000000 00000000 " + "03020100 07060504 0b0a0908 0f0e0d0c" + ) in output + + assert ( + "= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? " + "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f -/-" + ) in output + assert "= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-" in output + assert "= 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f R/-" in output @pytest.mark.skipif( arg_chip @@ -849,10 +874,10 @@ def test_burn_key_one_key_block_with_fe_and_sb_keys(self): "esp32s3", "esp32s3beta1", "esp32c3", - "esp32h2beta2", "esp32h2beta1", "esp32c6", "esp32h2", + "esp32p4", ], reason="Only chips with 6 keys", ) @@ -861,7 +886,10 @@ def test_burn_key_with_6_keys(self): BLOCK_KEY0 {IMAGES_DIR}/256bit XTS_AES_256_KEY_1 \ BLOCK_KEY1 {IMAGES_DIR}/256bit_1 XTS_AES_256_KEY_2 \ BLOCK_KEY2 {IMAGES_DIR}/256bit_2 XTS_AES_128_KEY" - if arg_chip in ["esp32c3", "esp32c6", "esp32h2"]: + if arg_chip in ["esp32c3", "esp32c6"] or arg_chip in [ + "esp32h2", + "esp32h2beta1", + ]: cmd = cmd.replace("XTS_AES_256_KEY_1", "XTS_AES_128_KEY") cmd = cmd.replace("XTS_AES_256_KEY_2", "XTS_AES_128_KEY") self.espefuse_py(cmd + " --no-read-protect --no-write-protect") @@ -876,12 +904,18 @@ def test_burn_key_with_6_keys(self): self.espefuse_py(cmd) output = self.espefuse_py("summary -d") - assert "[4 ] read_regs: 00000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output - assert "[5 ] read_regs: 00000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output - assert "[6 ] read_regs: 00000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output + assert ( + "[4 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output + assert ( + "[5 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output + assert ( + "[6 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output self.espefuse_py( f"burn_key \ @@ -956,20 +990,19 @@ def test_burn_key_512bit_non_consecutive_blocks(self): f"burn_key \ BLOCK_KEY2 {IMAGES_DIR}/256bit XTS_AES_128_KEY" ) - self.espefuse_py( - f"burn_key \ - BLOCK_KEY3 {IMAGES_DIR}/256bit USER --no-read-protect --no-write-protect" - ) self.espefuse_py( f"burn_key \ BLOCK_KEY4 {IMAGES_DIR}/256bit SECURE_BOOT_DIGEST0" ) - self.espefuse_py( f"burn_key \ BLOCK_KEY1 {IMAGES_DIR}/256bit_1_256bit_2_combined \ XTS_AES_256_KEY --no-read-protect --no-write-protect" ) + self.espefuse_py( + f"burn_key \ + BLOCK_KEY5 {IMAGES_DIR}/256bit USER --no-read-protect --no-write-protect" + ) # Second half of key should burn to first available key block (BLOCK_KEY5) output = self.espefuse_py("summary -d") @@ -980,10 +1013,14 @@ def test_burn_key_512bit_non_consecutive_blocks(self): output, f"{IMAGES_DIR}/256bit_2", reverse_order=True ) - assert "[5 ] read_regs: bcbd11bf b8b9babb b4b5b6b7 " - "b0b1b2b3 acadaeaf a8a9aaab a4a5a6a7 11a1a2a3" in output - assert "[9 ] read_regs: bcbd22bf b8b9babb b4b5b6b7 " - "b0b1b2b3 acadaeaf a8a9aaab a4a5a6a7 22a1a2a3" in output + assert ( + "[5 ] read_regs: bcbd11bf b8b9babb b4b5b6b7 " + "b0b1b2b3 acadaeaf a8a9aaab a4a5a6a7 11a1a2a3" + ) in output + assert ( + "[7 ] read_regs: bcbd22bf b8b9babb b4b5b6b7 " + "b0b1b2b3 acadaeaf a8a9aaab a4a5a6a7 22a1a2a3" + ) in output @pytest.mark.skipif( arg_chip not in ["esp32s2", "esp32s3"], @@ -1009,10 +1046,71 @@ def test_burn_key_512bit_non_consecutive_blocks_loop_around(self): output, f"{IMAGES_DIR}/256bit_2", reverse_order=True ) - assert "[5 ] read_regs: bcbd11bf b8b9babb b4b5b6b7 b0b1b2b3 " - "acadaeaf a8a9aaab a4a5a6a7 11a1a2a3" in output - assert "[4 ] read_regs: bcbd22bf b8b9babb b4b5b6b7 b0b1b2b3 " - "acadaeaf a8a9aaab a4a5a6a7 22a1a2a3" in output + assert ( + "[5 ] read_regs: bcbd11bf b8b9babb b4b5b6b7 b0b1b2b3 " + "acadaeaf a8a9aaab a4a5a6a7 11a1a2a3" + ) in output + assert ( + "[4 ] read_regs: bcbd22bf b8b9babb b4b5b6b7 b0b1b2b3 " + "acadaeaf a8a9aaab a4a5a6a7 22a1a2a3" + ) in output + + @pytest.mark.skipif( + arg_chip not in ["esp32h2", "esp32p4"], + reason="These chips support ECDSA_KEY", + ) + def test_burn_key_ecdsa_key(self): + self.espefuse_py( + f"burn_key \ + BLOCK_KEY0 {S_IMAGES_DIR}/ecdsa192_secure_boot_signing_key_v2.pem \ + ECDSA_KEY \ + BLOCK_KEY1 {S_IMAGES_DIR}/ecdsa256_secure_boot_signing_key_v2.pem \ + ECDSA_KEY" + ) + output = self.espefuse_py("summary -d") + assert 2 == output.count( + "= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? " + "?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-" + ) + assert ( + "[4 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output + assert ( + "[5 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output + + @pytest.mark.skipif( + arg_chip not in ["esp32h2", "esp32p4"], + reason="These chips support ECDSA_KEY", + ) + def test_burn_key_ecdsa_key_check_byte_order(self): + self.espefuse_py( + f"burn_key \ + BLOCK_KEY0 {S_IMAGES_DIR}/ecdsa192_secure_boot_signing_key_v2.pem \ + ECDSA_KEY \ + BLOCK_KEY1 {S_IMAGES_DIR}/ecdsa256_secure_boot_signing_key_v2.pem \ + ECDSA_KEY \ + --no-read-protect" + ) + output = self.espefuse_py("summary -d") + assert ( + "= c8 c4 5d 62 9e 05 05 bd cb 04 a4 7c 06 f5 86 14 " + "cb 23 81 23 95 b7 71 4f 00 00 00 00 00 00 00 00 R/-" + ) in output + assert ( + "= fc 6b ec 75 64 37 7d 3b 88 8d 34 05 ed 91 06 1b " + "38 c2 50 84 7a 08 9d c3 66 6a 06 90 23 8b 54 b4 R/-" + ) in output + assert ( + "[4 ] read_regs: 625dc4c8 bd05059e 7ca404cb 1486f506 " + "238123cb 4f71b795 00000000 00000000" + ) in output + assert ( + "[5 ] read_regs: 75ec6bfc 3b7d3764 05348d88 1b0691ed " + "8450c238 c39d087a 90066a66 b4548b23" + ) in output class TestBurnBlockDataCommands(EfuseTestCase): @@ -1035,8 +1133,10 @@ def test_burn_block_data_with_3_key_blocks(self): BLOCK3 {IMAGES_DIR}/256bit" ) output = self.espefuse_py("summary -d") - assert "[3 ] read_regs: a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac " - "b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc" in output + assert ( + "[3 ] read_regs: a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac " + "b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc" + ) in output self.check_data_block_in_log(output, f"{IMAGES_DIR}/256bit") self.espefuse_py( @@ -1067,10 +1167,14 @@ def test_burn_block_data_with_1_key_block(self): output = self.espefuse_py("summary -d") assert "[0 ] read_regs: 00000001 0000000c" in output assert "[1 ] read_regs: 03020100 07060504 000a0908" in output - assert "[2 ] read_regs: a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac " - "b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc" in output - assert "[3 ] read_regs: a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac " - "b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc" in output + assert ( + "[2 ] read_regs: a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac " + "b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc" + ) in output + assert ( + "[3 ] read_regs: a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac " + "b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc" + ) in output @pytest.mark.skipif( arg_chip @@ -1079,10 +1183,10 @@ def test_burn_block_data_with_1_key_block(self): "esp32s3", "esp32s3beta1", "esp32c3", - "esp32h2beta2", "esp32h2beta1", "esp32c6", "esp32h2", + "esp32p4", ], reason="Only chip with 6 keys", ) @@ -1097,8 +1201,10 @@ def test_burn_block_data_with_6_keys(self): "[0 ] read_regs: 00000000 07060500 00000908 00000000 13000000 00161514" in output ) - assert "[3 ] read_regs: a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac " - "b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc" in output + assert ( + "[3 ] read_regs: a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac " + "b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc" + ) in output self.check_data_block_in_log(output, f"{IMAGES_DIR}/256bit") self.espefuse_py( @@ -1195,8 +1301,10 @@ def test_burn_block_data_with_offset_1_key_block(self): f"burn_block_data --offset {offset} BLOCK2 {IMAGES_DIR}/192bit_1" ) output = self.espefuse_py("summary -d") - assert "[2 ] read_regs: 00000000 00110000 05000000 09080706 " - "0d0c0b0a 11100f0e 15141312 00002116" in output + assert ( + "[2 ] read_regs: 00000000 00110000 05000000 09080706 " + "0d0c0b0a 11100f0e 15141312 00002116" + ) in output offset = 8 self.espefuse_py( @@ -1213,10 +1321,10 @@ def test_burn_block_data_with_offset_1_key_block(self): "esp32s3", "esp32s3beta1", "esp32c3", - "esp32h2beta2", "esp32h2beta1", "esp32c6", "esp32h2", + "esp32p4", ], reason="Only chips with 6 keys", ) @@ -1309,8 +1417,10 @@ def test_burn_key_digest(self): f"burn_key_digest {S_IMAGES_DIR}/rsa_secure_boot_signing_key.pem" ) output = self.espefuse_py("summary -d") - assert " = cb 27 91 a3 71 b0 c0 32 2b f7 37 04 78 ba 09 62 " - "22 4c ab 1c f2 28 78 79 e4 29 67 3e 7d a8 44 63 R/-" in output + assert ( + " = cb 27 91 a3 71 b0 c0 32 2b f7 37 04 78 ba 09 62 " + "22 4c ab 1c f2 28 78 79 e4 29 67 3e 7d a8 44 63 R/-" + ) in output else: self.espefuse_py( f"burn_key_digest {S_IMAGES_DIR}/rsa_secure_boot_signing_key.pem", @@ -1352,8 +1462,10 @@ def test_burn_key_digest1(self): ) output = self.espefuse_py("summary -d") assert " = 1e 3d 15 16 96 ca 7f 22 a6 e8 8b d5 27 a0 3b 3b R/-" in output - assert " = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " - "1e 3d 15 16 96 ca 7f 22 a6 e8 8b d5 27 a0 3b 3b R/-" in output + assert ( + " = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + "1e 3d 15 16 96 ca 7f 22 a6 e8 8b d5 27 a0 3b 3b R/-" + ) in output def test_burn_key_digest2(self): # python espsecure.py generate_signing_key --version 2 @@ -1364,8 +1476,10 @@ def test_burn_key_digest2(self): ) output = self.espefuse_py("summary -d") assert " = bf 0f 6a f6 8b d3 6d 8b 53 b3 da a9 33 f6 0a 04 R/-" in output - assert " = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " - "bf 0f 6a f6 8b d3 6d 8b 53 b3 da a9 33 f6 0a 04 R/-" in output + assert ( + " = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + "bf 0f 6a f6 8b d3 6d 8b 53 b3 da a9 33 f6 0a 04 R/-" + ) in output def test_burn_key_from_digest1(self): # python espsecure.py digest_sbv2_public_key --keyfile @@ -1376,8 +1490,10 @@ def test_burn_key_from_digest1(self): f"{S_IMAGES_DIR}/ecdsa192_public_key_digest_v2.bin SECURE_BOOT_DIGEST" ) output = self.espefuse_py("summary -d") - assert " = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " - "1e 3d 15 16 96 ca 7f 22 a6 e8 8b d5 27 a0 3b 3b R/-" in output + assert ( + " = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + "1e 3d 15 16 96 ca 7f 22 a6 e8 8b d5 27 a0 3b 3b R/-" + ) in output def test_burn_key_from_digest2(self): # python espsecure.py digest_sbv2_public_key --keyfile @@ -1388,8 +1504,10 @@ def test_burn_key_from_digest2(self): f"{S_IMAGES_DIR}/ecdsa256_public_key_digest_v2.bin SECURE_BOOT_DIGEST" ) output = self.espefuse_py("summary -d") - assert " = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " - "bf 0f 6a f6 8b d3 6d 8b 53 b3 da a9 33 f6 0a 04 R/-" in output + assert ( + " = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + "bf 0f 6a f6 8b d3 6d 8b 53 b3 da a9 33 f6 0a 04 R/-" + ) in output @pytest.mark.skipif( @@ -1399,10 +1517,10 @@ def test_burn_key_from_digest2(self): "esp32s3", "esp32s3beta1", "esp32c3", - "esp32h2beta2", "esp32h2beta1", "esp32c6", "esp32h2", + "esp32p4", ], reason="Supports 6 key blocks", ) @@ -1511,10 +1629,10 @@ def test_burn_bit_for_chips_with_1_key_block(self): "esp32s3", "esp32s3beta1", "esp32c3", - "esp32h2beta2", "esp32h2beta1", "esp32c6", "esp32h2", + "esp32p4", ], reason="Only chip with 6 keys", ) @@ -1591,12 +1709,18 @@ def test_1_secure_boot_v1(self): secure_boot_v1 {IMAGES_DIR}/256bit_1" ) output = self.espefuse_py("summary -d") - assert "[1 ] read_regs: 00000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output - assert "[2 ] read_regs: 00000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output - assert "[3 ] read_regs: 00000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output + assert ( + "[1 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output + assert ( + "[2 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output + assert ( + "[3 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output def test_2_secure_boot_v1(self): if arg_chip == "esp32": @@ -1619,8 +1743,10 @@ def test_2_secure_boot_v1(self): secure_boot_v2 {IMAGES_DIR}/256bit_1" ) output = self.espefuse_py("summary -d") - assert "[1 ] read_regs: 00000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output + assert ( + "[1 ] read_regs: 00000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output self.check_data_block_in_log( output, f"{IMAGES_DIR}/256bit_1", reverse_order=False ) @@ -1637,14 +1763,20 @@ def teardown_class(self): # Restore the stored working directory os.chdir(self.stored_dir) - @pytest.mark.skipif(arg_chip == "esp32c2", reason="TODO: Add tests for esp32c2") + @pytest.mark.skipif( + arg_chip in ["esp32c2", "esp32p4"], + reason="These chips do not have eFuses used in this test", + ) def test_execute_scripts_with_check_that_only_one_burn(self): self.espefuse_py("execute_scripts -h") name = arg_chip if arg_chip in ["esp32", "esp32c2"] else "esp32xx" os.chdir(os.path.join(TEST_DIR, "efuse_scripts", name)) self.espefuse_py("execute_scripts execute_efuse_script2.py") - @pytest.mark.skipif(arg_chip == "esp32c2", reason="TODO: Add tests for esp32c2") + @pytest.mark.skipif( + arg_chip in ["esp32c2", "esp32p4"], + reason="These chips do not have eFuses used in this test", + ) def test_execute_scripts_with_check(self): self.espefuse_py("execute_scripts -h") name = arg_chip if arg_chip in ["esp32", "esp32c2"] else "esp32xx" @@ -1662,11 +1794,15 @@ def test_execute_scripts_with_index_and_config(self): self.espefuse_py(cmd) output = self.espefuse_py("summary -d") if arg_chip in ["esp32", "esp32c2"]: - assert "[3 ] read_regs: e00007ff 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output + assert ( + "[3 ] read_regs: e00007ff 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output else: - assert "[8 ] read_regs: e00007ff 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output + assert ( + "[8 ] read_regs: e00007ff 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output def test_execute_scripts_nesting(self): os.chdir(TEST_DIR) @@ -1679,15 +1815,23 @@ def test_execute_scripts_nesting(self): self.espefuse_py(cmd) output = self.espefuse_py("summary -d") if arg_chip in ["esp32", "esp32c2"]: - assert "[2 ] read_regs: 10000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output - assert "[3 ] read_regs: ffffffff 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output + assert ( + "[2 ] read_regs: 10000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output + assert ( + "[3 ] read_regs: ffffffff 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output else: - assert "[7 ] read_regs: 10000000 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output - assert "[8 ] read_regs: ffffffff 00000000 00000000 00000000 " - "00000000 00000000 00000000 00000000" in output + assert ( + "[7 ] read_regs: 10000000 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output + assert ( + "[8 ] read_regs: ffffffff 00000000 00000000 00000000 " + "00000000 00000000 00000000 00000000" + ) in output class TestMultipleCommands(EfuseTestCase): @@ -1736,8 +1880,10 @@ def test_1_esp32c2(self): summary" ) output = self.espefuse_py("summary -d") - assert "[3 ] read_regs: 0c0d0e0f 08090a0b 04050607 00010203 " - "f66a0fbf 8b6dd38b a9dab353 040af633" in output + assert ( + "[3 ] read_regs: 0c0d0e0f 08090a0b 04050607 00010203 " + "f66a0fbf 8b6dd38b a9dab353 040af633" + ) in output assert " = 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 R/-" in output assert " = bf 0f 6a f6 8b d3 6d 8b 53 b3 da a9 33 f6 0a 04 R/-" in output @@ -1752,8 +1898,10 @@ def test_2_esp32c2(self): summary" ) output = self.espefuse_py("summary -d") - assert "[3 ] read_regs: 00000000 00000000 00000000 00000000 " - "f66a0fbf 8b6dd38b a9dab353 040af633" in output + assert ( + "[3 ] read_regs: 00000000 00000000 00000000 00000000 " + "f66a0fbf 8b6dd38b a9dab353 040af633" + ) in output assert " = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-" in output assert " = bf 0f 6a f6 8b d3 6d 8b 53 b3 da a9 33 f6 0a 04 R/-" in output @@ -1778,3 +1926,54 @@ def test_not_burn_cmds(self): adc_info \ check_error" ) + + +@pytest.mark.skipif( + arg_chip not in ["esp32c3", "esp32c6", "esp32h2", "esp32s3"], + reason="These chips have a hardware bug that limits the use of the KEY5", +) +class TestKeyPurposes(EfuseTestCase): + def test_burn_xts_aes_key_purpose(self): + self.espefuse_py( + "burn_efuse KEY_PURPOSE_5 XTS_AES_128_KEY", + check_msg="A fatal error occurred: " + "KEY_PURPOSE_5 can not have XTS_AES_128_KEY " + "key due to a hardware bug (please see TRM for more details)", + ret_code=2, + ) + + @pytest.mark.skipif( + arg_chip != "esp32h2", reason="esp32h2 can not have ECDSA key in KEY5" + ) + def test_burn_ecdsa_key_purpose(self): + self.espefuse_py( + "burn_efuse KEY_PURPOSE_5 ECDSA_KEY", + check_msg="A fatal error occurred: " + "KEY_PURPOSE_5 can not have ECDSA_KEY " + "key due to a hardware bug (please see TRM for more details)", + ret_code=2, + ) + + def test_burn_xts_aes_key(self): + self.espefuse_py( + f"burn_key \ + BLOCK_KEY5 {IMAGES_DIR}/256bit XTS_AES_128_KEY", + check_msg="A fatal error occurred: " + "KEY_PURPOSE_5 can not have XTS_AES_128_KEY " + "key due to a hardware bug (please see TRM for more details)", + ret_code=2, + ) + + @pytest.mark.skipif( + arg_chip != "esp32h2", reason="esp32h2 can not have ECDSA key in KEY5" + ) + def test_burn_ecdsa_key(self): + self.espefuse_py( + f"burn_key \ + BLOCK_KEY5 {S_IMAGES_DIR}/ecdsa192_secure_boot_signing_key_v2.pem \ + ECDSA_KEY", + check_msg="A fatal error occurred: " + "KEY_PURPOSE_5 can not have ECDSA_KEY " + "key due to a hardware bug (please see TRM for more details)", + ret_code=2, + ) diff --git a/test/test_espsecure.py b/test/test_espsecure.py index f2c213a9d..90045ff40 100755 --- a/test/test_espsecure.py +++ b/test/test_espsecure.py @@ -24,6 +24,7 @@ TEST_DIR = os.path.abspath(os.path.dirname(__file__)) +@pytest.mark.host_test class EspSecureTestCase: def run_espsecure(self, args): """ @@ -181,7 +182,9 @@ def test_sign_v1_with_pre_calculated_signature(self): # Sign using pre-calculated signature + Verify signing_pubkey = "ecdsa_secure_boot_signing_pubkey.pem" pre_calculated_signature = "pre_calculated_bootloader_signature.bin" - with tempfile.NamedTemporaryFile() as output_file: + + try: + output_file = tempfile.NamedTemporaryFile(delete=False) args = self.SignArgs( "1", None, @@ -199,6 +202,9 @@ def test_sign_v1_with_pre_calculated_signature(self): "1", False, None, self._open(signing_pubkey), output_file ) espsecure.verify_signature(args) + finally: + output_file.close() + os.unlink(output_file.name) def test_sign_v2_data(self): signing_keys = [ @@ -207,7 +213,8 @@ def test_sign_v2_data(self): "ecdsa_secure_boot_signing_key.pem", ] for key in signing_keys: - with tempfile.NamedTemporaryFile() as output_file: + try: + output_file = tempfile.NamedTemporaryFile(delete=False) args = self.SignArgs( "2", [self._open(key)], @@ -223,10 +230,14 @@ def test_sign_v2_data(self): args = self.VerifyArgs("2", False, None, self._open(key), output_file) espsecure.verify_signature(args) + finally: + output_file.close() + os.unlink(output_file.name) def test_sign_v2_multiple_keys(self): # 3 keys + Verify with 3rd key - with tempfile.NamedTemporaryFile() as output_file: + try: + output_file = tempfile.NamedTemporaryFile(delete=False) args = self.SignArgs( "2", [ @@ -272,11 +283,15 @@ def test_sign_v2_multiple_keys(self): output_file, ) espsecure.verify_signature(args) + finally: + output_file.close() + os.unlink(output_file.name) def test_sign_v2_append_signatures(self): # Append signatures + Verify with an appended key # (bootloader_signed_v2.bin already signed with rsa_secure_boot_signing_key.pem) - with tempfile.NamedTemporaryFile() as output_file: + try: + output_file = tempfile.NamedTemporaryFile(delete=False) args = self.SignArgs( "2", [ @@ -321,10 +336,15 @@ def test_sign_v2_append_signatures(self): output_file, ) espsecure.verify_signature(args) + finally: + output_file.close() + os.unlink(output_file.name) def test_sign_v2_append_signatures_multiple_steps(self): # similar to previous test, but sign in two invocations - with tempfile.NamedTemporaryFile() as output_file1, tempfile.NamedTemporaryFile() as output_file2: # noqa E501 + try: + output_file1 = tempfile.NamedTemporaryFile(delete=False) + output_file2 = tempfile.NamedTemporaryFile(delete=False) args = self.SignArgs( "2", [self._open("rsa_secure_boot_signing_key2.pem")], @@ -379,6 +399,11 @@ def test_sign_v2_append_signatures_multiple_steps(self): output_file2, ) espsecure.verify_signature(args) + finally: + output_file1.close() + os.unlink(output_file1.name) + output_file2.close() + os.unlink(output_file2.name) def test_sign_v2_with_pre_calculated_signature(self): # Sign using pre-calculated signature + Verify @@ -393,7 +418,8 @@ def test_sign_v2_with_pre_calculated_signature(self): "pre_calculated_bootloader_signature_ecdsa256.bin", ] for pub_key, signature in zip(signing_keys, pre_calculated_signatures): - with tempfile.NamedTemporaryFile() as output_file: + try: + output_file = tempfile.NamedTemporaryFile(delete=False) args = self.SignArgs( "2", None, @@ -411,6 +437,9 @@ def test_sign_v2_with_pre_calculated_signature(self): "2", False, None, self._open(pub_key), output_file ) espsecure.verify_signature(args) + finally: + output_file.close() + os.unlink(output_file.name) def test_sign_v2_with_multiple_pre_calculated_signatures(self): # Sign using multiple pre-calculated signatures + Verify @@ -424,7 +453,8 @@ def test_sign_v2_with_multiple_pre_calculated_signatures(self): "pre_calculated_bootloader_signature_rsa.bin", "pre_calculated_bootloader_signature_rsa.bin", ] - with tempfile.NamedTemporaryFile() as output_file: + try: + output_file = tempfile.NamedTemporaryFile(delete=False) args = self.SignArgs( "2", None, @@ -442,6 +472,9 @@ def test_sign_v2_with_multiple_pre_calculated_signatures(self): "2", False, None, self._open(signing_pubkeys[0]), output_file ) espsecure.verify_signature(args) + finally: + output_file.close() + os.unlink(output_file.name) def test_verify_signature_signing_key(self): # correct key v1 diff --git a/test/test_esptool.py b/test/test_esptool.py index 7724c07e4..c625ea983 100755 --- a/test/test_esptool.py +++ b/test/test_esptool.py @@ -24,6 +24,8 @@ import time from socket import AF_INET, SOCK_STREAM, socket from time import sleep +from typing import List +from unittest.mock import MagicMock # Link command line options --port, --chip, --baud, --with-trace, and --preload-port from conftest import ( @@ -230,17 +232,21 @@ def teardown_class(self): def readback(self, offset, length): """Read contents of flash back, return to caller.""" - with tempfile.NamedTemporaryFile() as tf: # need a file we can read into + dump_file = tempfile.NamedTemporaryFile(delete=False) # a file we can read into + try: self.run_esptool( - f"--before default_reset read_flash {offset} {length} {tf.name}" + f"--before default_reset read_flash {offset} {length} {dump_file.name}" ) - with open(tf.name, "rb") as f: + with open(dump_file.name, "rb") as f: rb = f.read() - assert length == len( - rb - ), f"read_flash length {length} offset {offset:#x} yielded {len(rb)} bytes!" - return rb + assert length == len( + rb + ), f"read_flash length {length} offset {offset:#x} yielded {len(rb)} bytes!" + return rb + finally: + dump_file.close() + os.unlink(dump_file.name) def verify_readback(self, offset, length, compare_to, is_bootloader=False): rb = self.readback(offset, length) @@ -266,11 +272,14 @@ def verify_readback(self, offset, length, compare_to, is_bootloader=False): @pytest.mark.skipif(arg_chip != "esp32", reason="ESP32 only") class TestFlashEncryption(EsptoolTestCase): def valid_key_present(self): - esp = esptool.ESP32ROM(arg_port) - esp.connect() - efuses, _ = espefuse.get_efuses(esp=esp) - blk1_rd_en = efuses["BLOCK1"].is_readable() - return not blk1_rd_en + try: + esp = esptool.ESP32ROM(arg_port) + esp.connect() + efuses, _ = espefuse.get_efuses(esp=esp) + blk1_rd_en = efuses["BLOCK1"].is_readable() + return not blk1_rd_en + finally: + esp._port.close() def test_blank_efuse_encrypt_write_abort(self): """ @@ -366,10 +375,12 @@ def test_blank_efuse_encrypt_write_continue2(self): class TestFlashing(EsptoolTestCase): + @pytest.mark.quick_test def test_short_flash(self): self.run_esptool("write_flash 0x0 images/one_kb.bin") self.verify_readback(0, 1024, "images/one_kb.bin") + @pytest.mark.quick_test def test_highspeed_flash(self): self.run_esptool("write_flash 0x0 images/fifty_kb.bin", baud=921600) self.verify_readback(0, 50 * 1024, "images/fifty_kb.bin") @@ -379,6 +390,42 @@ def test_adjacent_flash(self): self.verify_readback(0, 4096, "images/sector.bin") self.verify_readback(4096, 50 * 1024, "images/fifty_kb.bin") + def test_short_flash_hex(self): + _, f = tempfile.mkstemp(suffix=".hex") + try: + self.run_esptool(f"merge_bin --format hex 0x0 images/one_kb.bin -o {f}") + self.run_esptool(f"write_flash 0x0 {f}") + self.verify_readback(0, 1024, "images/one_kb.bin") + finally: + os.unlink(f) + + def test_adjacent_flash_hex(self): + _, f1 = tempfile.mkstemp(suffix=".hex") + _, f2 = tempfile.mkstemp(suffix=".hex") + try: + self.run_esptool(f"merge_bin --format hex 0x0 images/sector.bin -o {f1}") + self.run_esptool( + f"merge_bin --format hex 0x1000 images/fifty_kb.bin -o {f2}" + ) + self.run_esptool(f"write_flash 0x0 {f1} 0x1000 {f2}") + self.verify_readback(0, 4096, "images/sector.bin") + self.verify_readback(4096, 50 * 1024, "images/fifty_kb.bin") + finally: + os.unlink(f1) + os.unlink(f2) + + def test_adjacent_flash_mixed(self): + _, f = tempfile.mkstemp(suffix=".hex") + try: + self.run_esptool( + f"merge_bin --format hex 0x1000 images/fifty_kb.bin -o {f}" + ) + self.run_esptool(f"write_flash 0x0 images/sector.bin 0x1000 {f}") + self.verify_readback(0, 4096, "images/sector.bin") + self.verify_readback(4096, 50 * 1024, "images/fifty_kb.bin") + finally: + os.unlink(f) + def test_adjacent_independent_flash(self): self.run_esptool("write_flash 0x0 images/sector.bin") self.verify_readback(0, 4096, "images/sector.bin") @@ -423,6 +470,7 @@ def test_correct_offset(self): ct = f.read() assert last_sector == ct + @pytest.mark.quick_test def test_no_compression_flash(self): self.run_esptool( "write_flash -u 0x0 images/sector.bin 0x1000 images/fifty_kb.bin" @@ -430,6 +478,7 @@ def test_no_compression_flash(self): self.verify_readback(0, 4096, "images/sector.bin") self.verify_readback(4096, 50 * 1024, "images/fifty_kb.bin") + @pytest.mark.quick_test @pytest.mark.skipif(arg_chip == "esp8266", reason="Added in ESP32") def test_compressed_nostub_flash(self): self.run_esptool( @@ -465,18 +514,24 @@ def test_length_not_aligned_4bytes(self): def test_length_not_aligned_4bytes_no_compression(self): self.run_esptool("write_flash -u 0x0 images/not_4_byte_aligned.bin") + @pytest.mark.quick_test + @pytest.mark.host_test def test_write_overlap(self): output = self.run_esptool_error( "write_flash 0x0 images/bootloader_esp32.bin 0x1000 images/one_kb.bin" ) assert "Detected overlap at address: 0x1000 " in output + @pytest.mark.quick_test + @pytest.mark.host_test def test_repeated_address(self): output = self.run_esptool_error( "write_flash 0x0 images/one_kb.bin 0x0 images/one_kb.bin" ) assert "Detected overlap at address: 0x0 " in output + @pytest.mark.quick_test + @pytest.mark.host_test def test_write_sector_overlap(self): # These two 1KB files don't overlap, # but they do both touch sector at 0x1000 so should fail @@ -492,19 +547,30 @@ def test_write_no_overlap(self): assert "Detected overlap at address" not in output def test_compressible_file(self): - with tempfile.NamedTemporaryFile() as f: + try: + input_file = tempfile.NamedTemporaryFile(delete=False) file_size = 1024 * 1024 - f.write(b"\x00" * file_size) - self.run_esptool(f"write_flash 0x10000 {f.name}") + input_file.write(b"\x00" * file_size) + input_file.close() + self.run_esptool(f"write_flash 0x10000 {input_file.name}") + finally: + os.unlink(input_file.name) def test_compressible_non_trivial_file(self): - with tempfile.NamedTemporaryFile() as f: + try: + input_file = tempfile.NamedTemporaryFile(delete=False) file_size = 1000 * 1000 same_bytes = 8000 for _ in range(file_size // same_bytes): - f.write(struct.pack("B", random.randrange(0, 1 << 8)) * same_bytes) - self.run_esptool(f"write_flash 0x10000 {f.name}") + input_file.write( + struct.pack("B", random.randrange(0, 1 << 8)) * same_bytes + ) + input_file.close() + self.run_esptool(f"write_flash 0x10000 {input_file.name}") + finally: + os.unlink(input_file.name) + @pytest.mark.quick_test def test_zero_length(self): # Zero length files are skipped with a warning output = self.run_esptool( @@ -513,6 +579,7 @@ def test_zero_length(self): self.verify_readback(0x10000, 1024, "images/one_kb.bin") assert "zerolength.bin is empty" in output + @pytest.mark.quick_test def test_single_byte(self): self.run_esptool("write_flash 0x0 images/onebyte.bin") self.verify_readback(0x0, 1, "images/onebyte.bin") @@ -568,10 +635,11 @@ def test_flash_with_min_max_rev(self): ) assert ( "images/esp32c3_header_min_rev.bin " - "requires chip revision in range [v0.10 - max rev not set]" in output + "requires chip revision in range [v2.55 - max rev not set]" in output ) assert "Use --force to flash anyway." in output + @pytest.mark.quick_test def test_erase_before_write(self): output = self.run_esptool("write_flash --erase-all 0x0 images/one_kb.bin") assert "Chip erase completed successfully" in output @@ -586,14 +654,16 @@ class TestSecurityInfo(EsptoolTestCase): def test_show_security_info(self): res = self.run_esptool("get_security_info") assert "Flags" in res - assert "Flash_Crypt_Cnt" in res - assert "Key_Purposes" in res + assert "Crypt Count" in res + assert "Key Purposes" in res if arg_chip != "esp32s2": esp = esptool.get_default_connected_device( [arg_port], arg_port, 10, 115200, arg_chip ) - assert f"Chip_ID: {esp.IMAGE_CHIP_ID}" in res - assert "Api_Version" in res + assert f"Chip ID: {esp.IMAGE_CHIP_ID}" in res + assert "API Version" in res + assert "Secure Boot" in res + assert "Flash Encryption" in res class TestFlashSizes(EsptoolTestCase): @@ -613,6 +683,8 @@ def test_large_no_compression(self): self.run_esptool("write_flash -u -fs 4MB 0x280000 images/one_mb.bin") self.verify_readback(0x280000, 0x100000, "images/one_mb.bin") + @pytest.mark.quick_test + @pytest.mark.host_test def test_invalid_size_arg(self): self.run_esptool_error("write_flash -fs 10MB 0x6000 images/one_kb.bin") @@ -650,23 +722,29 @@ def test_flash_size_keep(self): class TestFlashDetection(EsptoolTestCase): + @pytest.mark.quick_test def test_flash_id(self): """Test manufacturer and device response of flash detection.""" res = self.run_esptool("flash_id") assert "Manufacturer:" in res assert "Device:" in res + @pytest.mark.quick_test def test_flash_id_expand_args(self): """ Test manufacturer and device response of flash detection with expandable arg """ - with tempfile.NamedTemporaryFile() as tf: - tf.write(b"flash_id\n") - tf.seek(0) - res = self.run_esptool(f"@{tf.name}") + try: + arg_file = tempfile.NamedTemporaryFile(delete=False) + arg_file.write(b"flash_id\n") + arg_file.close() + res = self.run_esptool(f"@{arg_file.name}") assert "Manufacturer:" in res assert "Device:" in res + finally: + os.unlink(arg_file.name) + @pytest.mark.quick_test def test_flash_id_trace(self): """Test trace functionality on flash detection, running without stub""" res = self.run_esptool("--trace flash_id") @@ -686,6 +764,9 @@ def test_flash_id_trace(self): assert "Device:" in res +@pytest.mark.skipif( + os.name == "nt", reason="Temporarily disabled on windows" +) # TODO: ESPTOOL-673 class TestStubReuse(EsptoolTestCase): def test_stub_reuse_with_synchronization(self): """Keep the flasher stub running and reuse it the next time.""" @@ -716,6 +797,7 @@ def test_stub_reuse_without_synchronization(self): class TestErase(EsptoolTestCase): + @pytest.mark.quick_test def test_chip_erase(self): self.run_esptool("write_flash 0x10000 images/one_kb.bin") self.verify_readback(0x10000, 0x400, "images/one_kb.bin") @@ -734,6 +816,10 @@ def test_region_erase(self): empty = self.readback(0x10000, 0x1000) assert empty == b"\xFF" * 0x1000 + def test_region_erase_all(self): + res = self.run_esptool("erase_region 0x0 ALL") + assert re.search(r"Detected flash size: \d+[KM]B", res) is not None + def test_large_region_erase(self): # verifies that erasing a large region doesn't time out self.run_esptool("erase_region 0x0 0x100000") @@ -758,6 +844,7 @@ def test_overlap(self): class TestVerifyCommand(EsptoolTestCase): + @pytest.mark.quick_test def test_verify_success(self): self.run_esptool("write_flash 0x5000 images/one_kb.bin") self.run_esptool("verify_flash 0x5000 images/one_kb.bin") @@ -776,6 +863,7 @@ def test_verify_unaligned_length(self): class TestReadIdentityValues(EsptoolTestCase): + @pytest.mark.quick_test def test_read_mac(self): output = self.run_esptool("read_mac") mac = re.search(r"[0-9a-f:]{17}", output) @@ -795,6 +883,7 @@ def test_read_chip_id(self): class TestMemoryOperations(EsptoolTestCase): + @pytest.mark.quick_test def test_memory_dump(self): output = self.run_esptool("dump_mem 0x50000000 128 memout.bin") assert "Read 128 bytes" in output @@ -847,6 +936,7 @@ def test_keep_does_not_change_settings(self): arg_chip not in ["esp8266", "esp32", "esp32c3"], reason="Don't run for every chip, so other bootloader images are not needed", ) + @pytest.mark.quick_test def test_detect_size_changes_size(self): self.run_esptool( f"write_flash -fs detect {self.flash_offset:#x} {self.BL_IMAGE}" @@ -896,6 +986,16 @@ def test_explicit_set_size_freq_mode(self): class TestLoadRAM(EsptoolTestCase): # flashing an application not supporting USB-CDC will make # /dev/ttyACM0 disappear and USB-CDC tests will not work anymore + + def verify_output(self, expected_out: List[bytes]): + """Verify that at least one element of expected_out is in serial output""" + with serial.serial_for_url(arg_port, arg_baud) as p: + p.timeout = 5 + output = p.read(100) + print(f"Output: {output}") + assert any(item in output for item in expected_out) + + @pytest.mark.quick_test def test_load_ram(self): """Verify load_ram command @@ -903,15 +1003,28 @@ def test_load_ram(self): "Hello world!\n" to the serial port. """ self.run_esptool(f"load_ram images/ram_helloworld/helloworld-{arg_chip}.bin") - p = serial.serial_for_url(arg_port, arg_baud) - p.timeout = 5 - output = p.read(100) - print(f"Output: {output}") - assert ( - b"Hello world!" in output # xtensa - or b'\xce?\x13\x05\x04\xd0\x97A\x11"\xc4\x06\xc67\x04' in output # RISC-V + self.verify_output( + [b"Hello world!", b'\xce?\x13\x05\x04\xd0\x97A\x11"\xc4\x06\xc67\x04'] ) - p.close() + + def test_load_ram_hex(self): + """Verify load_ram command with hex file as input + + The "hello world" binary programs for each chip print + "Hello world!\n" to the serial port. + """ + _, f = tempfile.mkstemp(suffix=".hex") + try: + self.run_esptool( + f"merge_bin --format hex -o {f} 0x0 " + f"images/ram_helloworld/helloworld-{arg_chip}.bin" + ) + self.run_esptool(f"load_ram {f}") + self.verify_output( + [b"Hello world!", b'\xce?\x13\x05\x04\xd0\x97A\x11"\xc4\x06\xc67\x04'] + ) + finally: + os.unlink(f) class TestDeepSleepFlash(EsptoolTestCase): @@ -941,6 +1054,7 @@ class TestBootloaderHeaderRewriteCases(EsptoolTestCase): arg_chip not in ["esp8266", "esp32", "esp32c3"], reason="Don't run on every chip, so other bootloader images are not needed", ) + @pytest.mark.quick_test def test_flash_header_rewrite(self): bl_offset = 0x1000 if arg_chip in ("esp32", "esp32s2") else 0 bl_image = f"images/bootloader_{arg_chip}.bin" @@ -977,6 +1091,7 @@ def _check_output(self, output): assert f"Detecting chip type... {expected_chip_name}" in output assert f"Chip is {expected_chip_name}" in output + @pytest.mark.quick_test def test_auto_detect(self): output = self.run_esptool("chip_id", chip="auto") self._check_output(output) @@ -984,6 +1099,7 @@ def test_auto_detect(self): @pytest.mark.flaky(reruns=5) @pytest.mark.skipif(arg_preload_port is not False, reason="USB-to-UART bridge only") +@pytest.mark.skipif(os.name == "nt", reason="Linux/MacOS only") class TestVirtualPort(TestAutoDetect): def test_auto_detect_virtual_port(self): with ESPRFC2217Server() as server: @@ -1005,6 +1121,7 @@ def test_highspeed_flash_virtual_port(self): self.verify_readback(0, 50 * 1024, "images/fifty_kb.bin") +@pytest.mark.quick_test class TestReadWriteMemory(EsptoolTestCase): def _test_read_write(self, esp): # find the start of one of these named memory regions @@ -1035,19 +1152,26 @@ def _test_read_write(self, esp): assert esp.read_reg(test_addr) == 0x555 finally: esp.write_reg(test_addr, val) # write the original value, non-destructive + esp._port.close() def test_read_write_memory_rom(self): - esp = esptool.get_default_connected_device( - [arg_port], arg_port, 10, 115200, arg_chip - ) - self._test_read_write(esp) + try: + esp = esptool.get_default_connected_device( + [arg_port], arg_port, 10, 115200, arg_chip + ) + self._test_read_write(esp) + finally: + esp._port.close() def test_read_write_memory_stub(self): - esp = esptool.get_default_connected_device( - [arg_port], arg_port, 10, 115200, arg_chip - ) - esp = esp.run_stub() - self._test_read_write(esp) + try: + esp = esptool.get_default_connected_device( + [arg_port], arg_port, 10, 115200, arg_chip + ) + esp = esp.run_stub() + self._test_read_write(esp) + finally: + esp._port.close() @pytest.mark.skipif( arg_chip != "esp32", reason="Could be unsupported by different flash" @@ -1063,11 +1187,31 @@ def test_read_write_flash_status(self): assert f"After flash status: {match.group(1)}" in res def test_read_chip_description(self): - esp = esptool.get_default_connected_device( - [arg_port], arg_port, 10, 115200, arg_chip - ) - chip = esp.get_chip_description() - assert "unknown" not in chip.lower() + try: + esp = esptool.get_default_connected_device( + [arg_port], arg_port, 10, 115200, arg_chip + ) + chip = esp.get_chip_description() + assert "unknown" not in chip.lower() + finally: + esp._port.close() + + def test_read_get_chip_features(self): + try: + esp = esptool.get_default_connected_device( + [arg_port], arg_port, 10, 115200, arg_chip + ) + + if hasattr(esp, "get_flash_cap") and esp.get_flash_cap() == 0: + esp.get_flash_cap = MagicMock(return_value=1) + if hasattr(esp, "get_psram_cap") and esp.get_psram_cap() == 0: + esp.get_psram_cap = MagicMock(return_value=1) + + features = ", ".join(esp.get_chip_features()) + assert "Unknown Embedded Flash" not in features + assert "Unknown Embedded PSRAM" not in features + finally: + esp._port.close() @pytest.mark.skipif( @@ -1107,6 +1251,7 @@ def test_make_image(self): @pytest.mark.skipif(arg_chip != "esp32", reason="Don't need to test multiple times") +@pytest.mark.quick_test class TestConfigFile(EsptoolTestCase): class ConfigFile: """ @@ -1134,6 +1279,7 @@ def __exit__(self, exc_type, exc_value, exc_tb): "serial_write_timeout = 12" ) + @pytest.mark.host_test def test_load_config_file(self): # Test a valid file is loaded config_file_path = os.path.join(os.getcwd(), "esptool.cfg") @@ -1171,6 +1317,7 @@ def test_load_config_file(self): output = self.run_esptool("version") assert f"Loaded custom configuration from {config_file_path}" in output + @pytest.mark.host_test def test_load_config_file_with_env_var(self): config_file_path = os.path.join(TEST_DIR, "custom_file.ini") with self.ConfigFile(config_file_path, self.dummy_config): diff --git a/test/test_image_info.py b/test/test_image_info.py index 1436cb4f5..3dac7310a 100755 --- a/test/test_image_info.py +++ b/test/test_image_info.py @@ -2,6 +2,7 @@ import os.path import subprocess import sys +import tempfile from conftest import need_to_install_package_err @@ -12,7 +13,7 @@ except ImportError: need_to_install_package_err() -IMAGES_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "images/") +IMAGES_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "images") ESP8266_BIN = "not_4_byte_aligned.bin" @@ -22,6 +23,7 @@ def read_image(filename): return f.read() +@pytest.mark.host_test class TestImageInfo: def run_image_info(self, chip, file, version=None): """Runs image_info on a binary file. @@ -39,7 +41,9 @@ def run_image_info(self, chip, file, version=None): ] if version is not None: cmd += ["--version", str(version)] - cmd += ["".join([IMAGES_DIR, file])] + # if path was passed use the whole path + # if file does not exists try to use file from IMAGES_DIR directory + cmd += [file] if os.path.isfile(file) else ["".join([IMAGES_DIR, os.sep, file])] print("\nExecuting {}".format(" ".join(cmd))) try: @@ -85,8 +89,8 @@ def test_v2_esp32c3(self): assert "Flash mode: DIO" in out, "Wrong flash mode" # Extended header - assert "WP pin: 0xee" in out, "Wrong WP pin" - assert "Chip ID: 5" in out, "Wrong chip ID" + assert "WP pin: 0xee (disabled)" in out, "Wrong WP pin" + assert "Chip ID: 5 (ESP32-C3)" in out, "Wrong chip ID" assert ( "clk_drv: 0x0, q_drv: 0x0, d_drv: 0x0, " "cs0_drv: 0x0, hd_drv: 0x0, wp_drv: 0x0" in out @@ -178,3 +182,53 @@ def test_application_info(self): assert "Application information" not in out out = self.run_image_info("auto", ESP8266_BIN, "2") assert "Application information" not in out + + def test_bootloader_info(self): + # This bootloader binary is built from "hello_world" project + # with default settings, IDF version is v5.2. + out = self.run_image_info("esp32", "bootloader_esp32_v5_2.bin", "2") + assert "File size: 26768 (bytes)" in out + assert "Bootloader information" in out + assert "Bootloader version: 1" in out + assert "ESP-IDF: v5.2-dev-254-g1950b15" in out + assert "Compile time: Apr 25 2023 00:13:32" in out + + def test_intel_hex(self): + # This bootloader binary is built from "hello_world" project + # with default settings, IDF version is v5.2. + # File is converted to Intel Hex using merge_bin + + def convert_bin2hex(file): + subprocess.check_output( + [ + sys.executable, + "-m", + "esptool", + "--chip", + "esp32", + "merge_bin", + "--format", + "hex", + "0x0", + "".join([IMAGES_DIR, os.sep, "bootloader_esp32_v5_2.bin"]), + "-o", + file, + ] + ) + + fd, file = tempfile.mkstemp(suffix=".hex") + try: + convert_bin2hex(file) + out = self.run_image_info("esp32", file, "2") + assert "File size: 26768 (bytes)" in out + assert "Bootloader information" in out + assert "Bootloader version: 1" in out + assert "ESP-IDF: v5.2-dev-254-g1950b15" in out + assert "Compile time: Apr 25 2023 00:13:32" in out + finally: + try: + # make sure that file was closed before removing it + os.close(fd) + except OSError: + pass + os.unlink(file) diff --git a/test/test_imagegen.py b/test/test_imagegen.py index d1d5c0c20..9756e3fc9 100755 --- a/test/test_imagegen.py +++ b/test/test_imagegen.py @@ -1,6 +1,7 @@ import hashlib import os import os.path +import re import struct import subprocess import sys @@ -36,6 +37,7 @@ def segment_matches_section(segment, section): return section.header.sh_addr == segment.addr and sh_size == len(segment.data) +@pytest.mark.host_test class BaseTestCase: @classmethod def setup_class(self): @@ -112,7 +114,7 @@ def assertImageContainsSection(self, image, elf, section_name): f" segment(s) in bin image (image segments: {image.segments})" ) - def assertImageInfo(self, binpath, chip="esp8266"): + def assertImageInfo(self, binpath, chip="esp8266", assert_sha=False): """ Run esptool.py image_info on a binary file, assert no red flags about contents. @@ -125,7 +127,13 @@ def assertImageInfo(self, binpath, chip="esp8266"): except subprocess.CalledProcessError as e: print(e.output) raise - assert "invalid" not in output, "Checksum calculation should be valid" + assert re.search( + r"Checksum: [a-fA-F0-9]{2} \(valid\)", output + ), "Checksum calculation should be valid" + if assert_sha: + assert re.search( + r"Validation Hash: [a-fA-F0-9]{64} \(valid\)", output + ), "SHA256 should be valid" assert ( "warning" not in output.lower() ), "Should be no warnings in image_info output" @@ -266,7 +274,11 @@ def _test_elf2image(self, elfpath, binpath, extra_args=[]): try: self.run_elf2image("esp32", elfpath, extra_args=extra_args) image = esptool.bin_image.LoadFirmwareImage("esp32", binpath) - self.assertImageInfo(binpath, "esp32") + self.assertImageInfo( + binpath, + "esp32", + True if "--ram-only-header" not in extra_args else False, + ) return image finally: try_delete(binpath) @@ -321,6 +333,13 @@ def test_use_segments(self): image = self._test_elf2image(ELF, BIN, ["--use_segments"]) assert len(image.segments) == 2 + def test_ram_only_header(self): + ELF = "esp32-app-template.elf" + BIN = "esp32-app-template.bin" + # --ram-only-header produces just 2 visible segments in the bin + image = self._test_elf2image(ELF, BIN, ["--ram-only-header"]) + assert len(image.segments) == 2 + class TestESP8266FlashHeader(BaseTestCase): def test_2mb(self): diff --git a/test/test_merge_bin.py b/test/test_merge_bin.py index 1c2d96ebb..83abbff92 100755 --- a/test/test_merge_bin.py +++ b/test/test_merge_bin.py @@ -1,9 +1,14 @@ +import filecmp +import hashlib import itertools import os import os.path +import random +import struct import subprocess import sys import tempfile +from functools import partial IMAGES_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "images") @@ -13,6 +18,8 @@ try: from esptool.util import byte + from esptool.uf2_writer import UF2Writer + from esptool.targets import CHIP_DEFS except ImportError: need_to_install_package_err() @@ -22,6 +29,7 @@ def read_image(filename): return f.read() +@pytest.mark.host_test class TestMergeBin: def run_merge_bin(self, chip, offsets_names, options=[]): """Run merge_bin on a list of (offset, filename) tuples @@ -188,3 +196,305 @@ def test_fill_flash_size_w_target_offset(self): assert bootloader == merged[: len(bootloader)] assert helloworld == merged[0xF000 : 0xF000 + len(helloworld)] self.assertAllFF(merged[0xF000 + len(helloworld) :]) + + def test_merge_mixed(self): + # convert bootloader to hex + hex = self.run_merge_bin( + "esp32", + [(0x1000, "bootloader_esp32.bin")], + options=["--format", "hex"], + ) + # create a temp file with hex content + with tempfile.NamedTemporaryFile(suffix=".hex", delete=False) as f: + f.write(hex) + # merge hex file with bin file + # output to bin file should be the same as in merge bin + bin + try: + merged = self.run_merge_bin( + "esp32", + [(0x1000, f.name), (0x10000, "ram_helloworld/helloworld-esp32.bin")], + ["--target-offset", "0x1000", "--fill-flash-size", "2MB"], + ) + finally: + os.unlink(f.name) + # full length is without target-offset arg + assert len(merged) == 0x200000 - 0x1000 + + bootloader = read_image("bootloader_esp32.bin") + helloworld = read_image("ram_helloworld/helloworld-esp32.bin") + assert bootloader == merged[: len(bootloader)] + assert helloworld == merged[0xF000 : 0xF000 + len(helloworld)] + self.assertAllFF(merged[0xF000 + len(helloworld) :]) + + def test_merge_bin2hex(self): + merged = self.run_merge_bin( + "esp32", + [ + (0x1000, "bootloader_esp32.bin"), + ], + options=["--format", "hex"], + ) + lines = merged.splitlines() + # hex format - :0300300002337A1E + # :03 0030 00 02337A 1E + # ^data_cnt/2 ^addr ^type ^data ^checksum + + # check for starting address - 0x1000 passed from arg + assert lines[0][3:7] == b"1000" + # pick a random line for testing the format + line = lines[random.randrange(0, len(lines))] + assert line[0] == ord(":") + data_len = int(b"0x" + line[1:3], 16) + # : + len + addr + type + data + checksum + assert len(line) == 1 + 2 + 4 + 2 + data_len * 2 + 2 + # last line is allways :00000001FF + assert lines[-1] == b":00000001FF" + # convert back and verify the result against the source bin file + with tempfile.NamedTemporaryFile(suffix=".hex", delete=False) as hex: + hex.write(merged) + merged_bin = self.run_merge_bin( + "esp32", + [(0x1000, hex.name)], + options=["--format", "raw"], + ) + source = read_image("bootloader_esp32.bin") + # verify that padding was done correctly + assert b"\xFF" * 0x1000 == merged_bin[:0x1000] + # verify the file itself + assert source == merged_bin[0x1000:] + + +class UF2Block(object): + def __init__(self, bs): + self.length = len(bs) + + # See https://github.com/microsoft/uf2 for the format + first_part = "<" + "I" * 8 + # payload is between + last_part = "