diff options
Diffstat (limited to 'cpu-docs')
| -rw-r--r-- | cpu-docs/README.md | 151 | ||||
| -rw-r--r-- | cpu-docs/espressif-custom-isa/esp32p4-pie-simd_instruction-reference_esp-dl_2026-07-15.md | 907 | ||||
| -rw-r--r-- | cpu-docs/espressif-software/esptool_boot-mode-selection_esp32p4_v5.3.1.html | 358 | ||||
| -rw-r--r-- | cpu-docs/espressif-software/esptool_boot-mode-selection_v5.3.1.rst | 373 | ||||
| -rw-r--r-- | cpu-docs/espressif-software/esptool_firmware-image-format_esp32p4_v5.3.1.html | 299 | ||||
| -rw-r--r-- | cpu-docs/espressif-software/esptool_firmware-image-format_v5.3.1.rst | 209 | ||||
| -rw-r--r-- | cpu-docs/espressif-software/esptool_serial-protocol_esp32p4_v5.3.1.html | 795 | ||||
| -rw-r--r-- | cpu-docs/espressif-software/esptool_serial-protocol_v5.3.1.rst | 584 | ||||
| -rw-r--r-- | cpu-docs/manifests/EspCustomIsa.md | 86 | ||||
| -rw-r--r-- | cpu-docs/manifests/EspSilicon.md | 28 | ||||
| -rw-r--r-- | cpu-docs/manifests/EspSoftware.md | 30 | ||||
| -rw-r--r-- | cpu-docs/manifests/LocalHarvest.md | 45 | ||||
| -rw-r--r-- | cpu-docs/manifests/RiscvSpecs.md | 35 |
13 files changed, 3900 insertions, 0 deletions
diff --git a/cpu-docs/README.md b/cpu-docs/README.md new file mode 100644 index 0000000..a4a8784 --- /dev/null +++ b/cpu-docs/README.md @@ -0,0 +1,151 @@ +# cpu-docs — source documentation for the ESP32-P4's CPU + +Primary documents only. Nothing here is written by hand except this index and the per-collector +manifests in `manifests/`; every other file is a vendor- or standards-body-official artifact, +fetched from its own site and verified (`file` + `pdfinfo` + first-page title/version check). +18 PDFs, one official HTML bundle, 7 text sources; 121 MB. The PDFs and the zip are deliberately +*untracked* (`.gitignore`) — this index and `manifests/` carry every source URL with a sha256, byte +count and page count, so the archive is re-fetchable and drift is detectable, and 121 MB of +third-party documents stay out of the repository history. Caveat worth knowing: the two TRMs and +both datasheets are **pre-release** documents served from *fixed* filenames, so espressif.com will +one day return different bytes at the same URL. The recorded hashes will detect that; they cannot +recover the superseded revision. If keeping these exact revisions matters more than a clean +history, drop the `/cpu-docs/**/*.pdf` rule and raise `jj config set --repo +snapshot.max-new-file-size 52m`. + +## The part + +| | | +|---|---| +| SoC | Espressif ESP32-P4, silicon revision **v1.3** (pre-v3, ESP-IDF register set `hw_ver1`) | +| HP CPU | dual-core 32-bit RISC-V, **RV32IMAFC** (+Zc), 360 MHz default on this revision | +| LP CPU | single-core **RV32IMAC**, no FPU, no vendor extensions | +| custom ISA | `xespv2p1` (PIE, 128-bit SIMD/DSP) and `xesploop` (hardware loop) | +| ESP-IDF `-march` for rev < v3 | `rv32imafc_zicsr_zifencei_zaamo_zalrsc_xesploop_xespv2p1 -mabi=ilp32f -mtune=esp-base` | +| debug module | RISC-V External Debug Support **0.13.2** (HP DM), 0.13 (LP DM) | +| interrupt controller | RISC-V **CLIC** + CLINT per core, behind the SoC Interrupt Matrix. There is no `INTPRI` on this chip — that is C3/S3-era naming | + +## Two traps before you cite anything + +**1. Espressif maintains two concurrent ESP32-P4 manual lines, and the generic one is the wrong +silicon.** `esp32-p4_technical-reference-manual_en_pre-release-v0.7.pdf` documents **v3.x** +silicon. The register- and feature-correct book for this board is +`esp32-p4-chip-revision-v1.3_technical-reference-manual_en_pre-release-v0.4.pdf`. Both are archived. +`esp32-p4-chip-revision-v3.x_user-guide_en_v1.0.pdf` §1 is the authoritative delta list: on v1.3 +the max HP clock is 360 not 400 MHz, there is no Zb, there are fewer than 32 PMP entries, there is +no user-mode interrupt delegation and no Interrupt-Matrix remapping, CLIC CSR access is slower and +less compliant, the hardware-loop counter is narrower, and the cached region maps from the **top** +of L2MEM rather than the bottom. + +**2. The PIE chapter exists only in the wrong-revision manual.** The rev-v1.3 TRM lists its +Processor Instruction Extensions chapter as "[to be added later]" and omits it from the body +entirely. PIE must therefore be cited from the v0.7 TRM ch.4 (p.210) plus §2.7.1 Hardware Loop +(p.119) — the only encoding-complete source anywhere. Related: `xesppie` is a dead arch-string +name; `riscv32-esp-elf-gcc` 15.2.0 rejects it outright. + +## Which document answers which question + +| question | document | where | +|---|---|---| +| memory map, address spaces, cache, flash/PSRAM MMU windows | rev-v1.3 TRM | ch.7 System and Memory p.450 — §7.3.1 Address Mapping, §7.3.3.1 External Memory Address Mapping p.456, §7.3.3.2 Cache p.457. No separate MMU or Cache chapter exists | +| CSRs the core implements | rev-v1.3 TRM | ch.1 §1.5 CSRs p.63 (summary + per-register description); §1.4 Address Map p.62 | +| which standard extensions, and their behaviour | rev-v1.3 TRM ch.1 §1.6 p.94–99, then RISC-V Vol I | M ch.12, A ch.13, F ch.20, C ch.27, Zc ch.28, Zicsr ch.6, Zifencei ch.5 | +| `cycle`/`cycleh` (CSR 0xC00/0xC80), `mcycle` | RISC-V Vol I ch.7.1 Zicntr; Vol II §3.1.10 | the counters `src/soc.zig:cycles()` reads | +| traps, `mtvec`/`mepc`/`mcause`, PMP, reset, NMI | RISC-V Vol II | §3.1.7, §3.1.14, §3.1.15, §3.7, §3.4, §3.5 | +| interrupts: CLIC, CLINT, priority/level encoding | rev-v1.3 TRM ch.1 §1.9 p.111 (§1.9.2 CLIC, §1.9.3 CLINT p.118); ch.12 Interrupt Matrix p.755 | architectural model in `riscv-fast-interrupt_clic_draft-v0.10` ch.3 `smclic` | +| timers | rev-v1.3 TRM | ch.15 System Timer p.1033, ch.16 Timer Group p.1058, ch.17 Watchdog Timers p.1083 (the RTC WDT the bootloader leaves armed) | +| boot: strapping, boot modes, ROM log routing | rev-v1.3 TRM ch.11 Chip Boot Control p.750; rev-v1.3 datasheet §3 (Tables 3-5/3-6 UART0 vs USB Serial-JTAG); `esptool_boot-mode-selection_*` | | +| ROM serial loader protocol (SLIP, `ESP_SYNC`, `FLASH_BEGIN/DATA/END`) | `esptool_serial-protocol_v5.3.1.rst` | what `tools/rom.zig` implements | +| flash image format, header, checksum, SHA-256 | `esptool_firmware-image-format_v5.3.1.rst`; ESP-IDF guide §2.9.1 p.1364, §2.9.2 p.1370 | what `tools/image.zig` implements | +| startup flow, second-stage bootloader, memory types, interrupt allocation, system time, LP-core, linker scripts, JTAG | ESP-IDF Programming Guide v5.3.2 PDF | p.1803 / p.1806 / p.1933 / p.1648 / p.1748 / p.1760 / p.1914 / p.1873 | +| PIE / SIMD instruction semantics | v0.7 TRM ch.4 p.210 (encodings) + `esp32p4-pie-simd_instruction-reference_esp-dl_2026-07-15.md` (346 mnemonics, no encodings) | covers all 8 mnemonics used by `examples/pie.zig`; enable via CSR 0x7F2 `CSR_PIE_STATE_REG` | +| LP core programming model | rev-v1.3 TRM ch.3 Low-Power CPU p.189 (**not** v0.7 ch.5); ESP-IDF guide ULP LP-Core p.1760 | `-march=rv32imac_zicsr_zifencei_zaamo_zalrsc` | +| silicon bugs, and detecting rev v1.3 at runtime | `esp32-p4_soc-errata_en_v1.3.pdf` | §1.2 + Table 1.1 give the exact `EFUSE_RD_MAC_SPI_SYS_2_REG[23]`/`[5:0]` pattern; ROM-764/770/816 are boot-ROM bugs live on v1.3 | +| debug port, triggers, JTAG DTM | `riscv-external-debug-support_v0.13.2` (the version P4 implements); 1.0 for the incompatibility list §1.2.1.2–1.2.1.4 | | +| calling convention, `e_flags`, relocations, `.riscv.attributes` | `riscv-elf-psabi_riscv-abi_draft-20260813.pdf` | §1.1/§1.3, §2.7–2.8 ilp32f, §5 code models, §9.4, §9.11.1 | + +## Index + +### `espressif-silicon/` + +| file | version / date | pp | sha256:16 | source | +|---|---|---|---|---| +| `esp32-p4-chip-revision-v1.3_technical-reference-manual_en_pre-release-v0.4.pdf` | Pre-release v0.4, 2026-06-11 | 2975 | `ae1fa2a411776760` | espressif.com | +| `esp32-p4-chip-revision-v1.3_datasheet_en_v1.2.pdf` | v1.2, 2026-06-16 | 94 | `b2b0ae6fb8e92d23` | espressif.com | +| `esp32-p4_soc-errata_en_v1.3.pdf` | v1.3, PDF build 2026-08-23 | 19 | `5fd0fec5b306873a` | docs.espressif.com/projects/esp-chip-errata | +| `esp32-p4-chip-revision-v3.x_user-guide_en_v1.0.pdf` | v1.0, 2026-03-11 | 13 | `9329de55ef88f310` | espressif.com | +| `esp32-p4_technical-reference-manual_en_pre-release-v0.7.pdf` | Pre-release v0.7, 2026-08-20 | 3701 | `622fe9625d19cf00` | local copy, byte-identical to upstream | +| `esp32-p4_datasheet_en_pre-release-v0.7.pdf` | Pre-release v0.7, 2026-07-14 | 102 | `fb4f3e91cc2ac519` | local copy, byte-identical to upstream | + +### `espressif-software/` + +| file | version / date | pp | sha256:16 | source | +|---|---|---|---|---| +| `esp-idf-programming-guide_esp32p4_en_v5.3.2.pdf` | v5.3.2, 2024-12-06 | 2262 | `adf06f5531a5c845` | docs.espressif.com | +| `esp-idf-programming-guide_esp32p4_en_v6.0.2_html.zip` | v6.0.2 (the version `src/soc.zig` cites) | 393 html | `d3f0f339d4a86a04` | docs.espressif.com | +| `esptool_serial-protocol_v5.3.1.rst` + `_esp32p4_v5.3.1.html` | esptool v5.3.1, 2026-06-29 | — | `016dbe246a0c0edf` / `a00a70719b10fbd3` | github.com/espressif/esptool @ v5.3.1 + rendered page | +| `esptool_firmware-image-format_v5.3.1.rst` + `.html` | esptool v5.3.1 | — | `1f0cfe32a766b8ab` / `f9b6269b5d9f3601` | same | +| `esptool_boot-mode-selection_v5.3.1.rst` + `.html` | esptool v5.3.1 | — | `567510a46d727a51` / `100fdf423ba92cc0` | same | + +Espressif stopped building ESP-IDF PDFs after v5.3.2; v6.0.2 exists only as the official HTML zip. +esptool has no PDF or zip artifact at all, hence the rendered HTML plus the version-pinned `.rst` +sources it is generated from. The `openocd-esp32` docs project is retired — `/en/latest/` 404s for +every target — so JTAG material comes from the ESP-IDF guide ch.4.13 instead. + +### `riscv-isa/` + +| file | version / date | pp | sha256:16 | +|---|---|---|---| +| `riscv-unprivileged-isa_vol1_ratified_20250508.pdf` | 20250508, **ratified** | 727 | `cef2e63c08c6f82c` | +| `riscv-privileged-architecture_vol2_ratified_20250508.pdf` | 20250508, **ratified** | 221 | `d0228bbecc76943a` | +| `riscv-external-debug-support_v0.13.2_20190322.pdf` | 0.13.2, 2019-03-22 — *the version P4 implements* | 94 | `f203abb93ee2ad60` | +| `riscv-external-debug-support_v1.0_20250221.pdf` | 1.0, ratified 2025-02-21 | 119 | `ce2787b25233a610` | +| `riscv-elf-psabi_riscv-abi_draft-20260813.pdf` | v1.1 pre-release | 118 | `ff94b93578a5ee44` | +| `riscv-fast-interrupt_clic_draft-v0.10_20250324.pdf` | v0.10 **draft** — last release carrying `clic.pdf` | 69 | `ddb80f16aecb98ff` | +| `riscv-fast-interrupt_aclic_draft-v0.20_20260731.pdf` | v0.20 **draft** — CLIC's successor document | 38 | `1892f06fd863fe73` | +| `riscv-assembly-programmers-manual_v0.0.1_20250205.pdf` | v0.0.1 | 50 | `2edf43ff39c0ca47` | +| `riscv-code-size-reduction_zc_v1.0.4-3_20231026.pdf` | v1.0.4-3 | 60 | `62cea3875763904b` | +| `riscv-plic_v1.0.0_20230312.pdf` | 1.0.0 ratified — low relevance, contrast only | 18 | `82644c7701601baa` | +| `riscv-aclint_v1.0-rc4_20220114.pdf` | 1.0-rc4 draft — low relevance, P4 uses systimer/TIMG | 11 | `fb7f1473470fbc2a` | + +20250508 is the newest *ratified* ISA manual; every later tag is an unratified nightly build of the +merged in-development spec. The fast-interrupt task group has never ratified anything, so both +CLIC and ACLIC are drafts. The 0.13.2 debug PDF came from riscv.org and was `cmp`-verified +byte-identical to `riscv/riscv-debug-spec@4e0bb0fc:riscv-debug-release.pdf`. + +### `espressif-custom-isa/` + +| file | version / date | sha256:16 | source | +|---|---|---|---| +| `esp32p4-pie-simd_instruction-reference_esp-dl_2026-07-15.md` | `espressif/esp-dl` master @ `1def9a2d`, 2026-07-15 | `76576a92f85fb46a` | github.com/espressif/esp-dl | + +No standalone PIE PDF exists; this is the only vendor reference document for the extension outside +the TRM. It condenses for machine consumption: 346 mnemonics against the assembler's 410, no +instruction encodings, and it drops the `sat` operand the TRM's syntax carries. Encodings come from +the v0.7 TRM ch.4 figures or from Espressif's `as` with `-march=…xespv2p1`. + +## Not obtained + +Summarised; each collector's manifest carries the evidence and the best pointer. + +* No ESP32-P4 boot-ROM prose document exists anywhere. The authoritative artifacts are the ROM ELF + and the ROM linker scripts (paths in `manifests/LocalHarvest.md`); code was deliberately not + copied into this archive. +* No standalone LP-core ISA document. Its arch string was verified from + `components/ulp/cmake/toolchain-lp-core-riscv.cmake`. +* No ESP-IDF v6.x PDF, no esptool PDF, no OpenOCD docs project — see `espressif-software/` above. +* ESP32-P4 Consolidated Pin Overview is `.xlsx` only, and is pin-mux material, so out of scope. +* Hardware design guidelines, packaging, RF certification, and all board-level documents + (JC-ESP32P4-M3 dev-kit PDFs, schematics, the ESP32-C6-MINI-1 companion-module datasheet) are out + of scope; they remain at `../../01-esp32p4-m3/docs/` and are listed in `manifests/LocalHarvest.md`. + +## Provenance + +`manifests/` holds one file per collector — `EspSilicon`, `EspSoftware`, `RiscvSpecs`, +`EspCustomIsa`, `LocalHarvest` — each with full URLs, byte counts, page counts, sha256 prefixes, +verified chapter/page numbers, and what it failed to find and why. Re-verify the archive with: + +``` +find . -name '*.pdf' -exec sh -c 'pdfinfo "$1" >/dev/null || echo "BAD $1"' _ {} \; +sha256sum $(find . -type f ! -path './manifests/*' | sort) | cut -c1-16 +``` diff --git a/cpu-docs/espressif-custom-isa/esp32p4-pie-simd_instruction-reference_esp-dl_2026-07-15.md b/cpu-docs/espressif-custom-isa/esp32p4-pie-simd_instruction-reference_esp-dl_2026-07-15.md new file mode 100644 index 0000000..fa60eb1 --- /dev/null +++ b/cpu-docs/espressif-custom-isa/esp32p4-pie-simd_instruction-reference_esp-dl_2026-07-15.md @@ -0,0 +1,907 @@ +# ESP32-P4 SIMD Instruction Reference + +## Table of Contents +- [Register Architecture](#register-architecture) +- [Data Overflow, Saturation, and Rounding](#data-overflow-saturation-and-rounding) +- [Read Instructions](#read-instructions) +- [Write Instructions](#write-instructions) +- [Data Exchange Instructions](#data-exchange-instructions) +- [Arithmetic Instructions](#arithmetic-instructions) +- [Comparison Instructions](#comparison-instructions) +- [Bitwise Logical Instructions](#bitwise-logical-instructions) +- [Shift Instructions](#shift-instructions) +- [FFT Dedicated Instructions](#fft-dedicated-instructions) + +--- + +## Register Architecture + +### QR (Vector) Registers +- 8 × 128-bit vector registers: `q0`–`q7` +- Also referenced as `qw`, `qx`, `qy`, `qz`, `qu`, `qv` in instruction syntax +- Each QR can be viewed as: + - 16 × 8-bit elements (bytes) + - 8 × 16-bit elements (half-words) + - 4 × 32-bit elements (words) + +### QACC (Quad Accumulator) Registers +- **QACC_H**: 256-bit accumulator (high half) +- **QACC_L**: 256-bit accumulator (low half) +- Together form a 512-bit accumulator for multiply-accumulate operations +- QACC_H/L are segmented based on element width: + - S8/U8 MAC: 16 × 32-bit segments per QACC half + - S16/U16 MAC: 4 × 64-bit segments per QACC half + +### XACC (Cross Accumulator) Register +- 40-bit accumulator for dot-product (sum-of-products) operations +- `XACC[39:24]`: high 16 bits +- `XACC[23:0]`: low 24 bits (sign-extended to 32 when read) + +### SAR (Shift Amount Register) +- 6-bit register (`SAR[5:0]`), controls right-shift amount for multiply/accumulate→QR moves +- Used by VMUL, CMUL, MOV.*.QACC, SRCMB instructions + +### SAR_BYTE Register +- Byte-level shift amount for spliced shift instructions (SRC.Q etc.) +- Set automatically by ESP.LD.128.USAR.* instructions from address LSBs + +### CFG (Configuration Register) +Control/status register accessed via `ESP.MOVX.R.CFG` / `ESP.MOVX.W.CFG`: + +| Field | Bits | Access | Description | +|-----------|-------|--------|-------------| +| `vxsat_en`| 8 | R/W | Enable saturation status tracking | +| `vxrm` | 7:4 | R/W | Rounding mode (see [Rounding Modes](#rounding-modes)) | +| `rm_exc` | 3 | RO | Exception flag for UNNECESSARY rounding mode | +| `vxsat` | 2 | RO | Saturation occurred flag (cleared on CFG read if vxsat_en=1) | +| `mis_ld` | 1 | R/W | Enable hardware misaligned load (0=force-align, 1=HW handle) | +| `mis_st` | 0 | R/W | Enable hardware misaligned store (0=force-align, 1=HW handle) | + +### FFT_BIT_WIDTH Register +- 4-bit register controlling bit-reverse width (3–10 bits) for `ESP.BITREV` + +### PERF (Performance Counter) Register +- 32-bit performance counter, accessed via `ESP.MOVX.R.PERF` / `ESP.MOVX.W.PERF` + +--- + +## Data Overflow, Saturation, and Rounding + +### Data Overflow Handling + +When an operation result exceeds the bit-width of the destination register, two strategies are used: + +1. **Saturation** (clipping): The result is clamped to the representable range. + - Signed N-bit: clamped to `[-2^(N-1), 2^(N-1)-1]` + - Unsigned N-bit: clamped to `[0, 2^N-1]` + - Used by: VADD, VSUB, VSADDS, VSSUBS, VMULAS, VSMULAS, SRCMB, SRS, VCLAMP, VSAT + +2. **Wraparound** (truncation): Only the lower N bits of the result are retained. + - Used by: internal calculation results of most other instructions + +### Saturation Status (vxsat) + +- When `vxsat_en` is set in CFG, the `vxsat` bit records whether any saturation occurred +- `vxsat` is sticky: once set, it stays set until explicitly cleared +- Reading CFG (via `ESP.MOVX.R.CFG`) automatically clears `vxsat` + +### Rounding Modes (vxrm) + +The 4-bit `vxrm` field in CFG controls rounding behavior for right-shift operations: + +| Mode | vxrm | Description | +|-------------|------|-------------| +| FLOOR | 0 | Round towards -∞ | +| CEILING | 1 | Round towards +∞ | +| UP | 2 | Round away from zero | +| DOWN | 3 | Round towards zero (truncation) | +| HALF_UP | 4 | Round to nearest; ties round up (away from zero) | +| HALF_DOWN | 5 | Round to nearest; ties round down (towards zero) | +| HALF_EVEN | 6 | Round to nearest; ties round to even neighbor | +| UNNECESSARY | 7 | Assert no rounding needed; `rm_exc` set if rounding would occur | + +Rounding examples for common values: + +| Input | FLOOR | CEILING | UP | DOWN | HALF_UP | HALF_DOWN | HALF_EVEN | +|--------|-------|---------|----|------|---------|-----------|-----------| +| +5.5 | 5 | 6 | 6 | 5 | 6 | 5 | 6 | +| +2.5 | 2 | 3 | 3 | 2 | 3 | 2 | 2 | +| +1.6 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | +| +1.1 | 1 | 2 | 2 | 1 | 1 | 1 | 1 | +| +1.0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | +| -1.0 | -1 | -1 | -1 | -1 | -1 | -1 | -1 | +| -1.1 | -2 | -1 | -2 | -1 | -1 | -1 | -1 | +| -1.6 | -2 | -1 | -2 | -1 | -2 | -2 | -2 | +| -2.5 | -3 | -2 | -3 | -2 | -3 | -2 | -2 | +| -5.5 | -6 | -5 | -6 | -5 | -6 | -5 | -6 | + +### Data Alignment + +| Format | Bits | Aligned Address LSBs | +|---------|-------|----------------------| +| 1-byte | 8 | xxxx | +| 2-byte | 16 | xxx0 | +| 4-byte | 32 | xx00 | +| 8-byte | 64 | x000 | +| 16-byte | 128 | 0000 | + +**Force alignment mode** (mis_ld=0 / mis_st=0): Low address bits are forced to 0. +**Hardware misaligned mode** (mis_ld=1 / mis_st=1): Hardware splits misaligned access into multiple aligned accesses. + +--- + +## Read Instructions + +Load data from memory into vector registers. Address post-increment variants available. + +### 128-bit Vector Loads + +| Instruction | Description | +|-------------|-------------| +| `ESP.VLD.128.IP qu, rs1, imm` | Load 16 bytes, rs1 += imm (imm: -128 to 112, step 16) | +| `ESP.VLD.128.XP qu, rs1, rs2` | Load 16 bytes, rs1 += rs2 | + +### 64-bit Vector Loads (to high/low half of QR) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VLD.H.64.IP qu, rs1, imm` | Load 8 bytes to QR[127:64], rs1 += imm | +| `ESP.VLD.H.64.XP qu, rs1, rs2` | Load 8 bytes to QR[127:64], rs1 += rs2 | +| `ESP.VLD.L.64.IP qu, rs1, imm` | Load 8 bytes to QR[63:0], rs1 += imm | +| `ESP.VLD.L.64.XP qu, rs1, rs2` | Load 8 bytes to QR[63:0], rs1 += rs2 | + +### Broadcast Loads (scalar to vector) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VLDBC.8.IP qu, rs1, imm` | Load 1 byte, broadcast to 16 bytes, rs1 += imm | +| `ESP.VLDBC.8.XP qu, rs1, rs2` | Load 1 byte, broadcast to 16 bytes, rs1 += rs2 | +| `ESP.VLDBC.16.IP qu, rs1, imm` | Load 2 bytes, broadcast to 8 × 16-bit, rs1 += imm | +| `ESP.VLDBC.16.XP qu, rs1, rs2` | Load 2 bytes, broadcast to 8 × 16-bit, rs1 += rs2 | +| `ESP.VLDBC.32.IP qu, rs1, imm` | Load 4 bytes, broadcast to 4 × 32-bit, rs1 += imm | +| `ESP.VLDBC.32.XP qu, rs1, rs2` | Load 4 bytes, broadcast to 4 × 32-bit, rs1 += rs2 | +| `ESP.VLDHBC.16.INCP qu, qz, rs1` | Load 16 bytes, broadcast each 16-bit element to 32-bit: low halves → `qu`, high halves → `qz`. rs1 += 16 | + +### Unaligned 128-bit Loads + +| Instruction | Description | +|-------------|-------------| +| `ESP.LD.128.USAR.IP qu, rs1, imm` | Load 16 bytes (set SAR_BYTE from addr), rs1 += imm | +| `ESP.LD.128.USAR.XP qu, rs1, rs2` | Load 16 bytes (set SAR_BYTE from addr), rs1 += rs2 | + +### QACC Loads (sign/zero extended) + +| Instruction | Description | +|-------------|-------------| +| `ESP.LDQA.U8.128.IP rs1, imm` | Load 16 bytes, zero-extend each 8-bit to 20-bit to QACC_H/L, rs1 += imm | +| `ESP.LDQA.U8.128.XP rs1, rs2` | Same, rs1 += rs2 | +| `ESP.LDQA.U16.128.IP rs1, imm` | Load 16 bytes, zero-extend each 16-bit to 40-bit to QACC_H/L | +| `ESP.LDQA.U16.128.XP rs1, rs2` | Same, rs1 += rs2 | +| `ESP.LDQA.S8.128.IP rs1, imm` | Load 16 bytes, sign-extend each 8-bit to 20-bit to QACC_H/L | +| `ESP.LDQA.S8.128.XP rs1, rs2` | Same, rs1 += rs2 | +| `ESP.LDQA.S16.128.IP rs1, imm` | Load 16 bytes, sign-extend each 16-bit to 40-bit to QACC_H/L | +| `ESP.LDQA.S16.128.XP rs1, rs2` | Same, rs1 += rs2 | + +### QACC/XACC Direct Loads + +Load data directly into QACC_H, QACC_L, XACC, or UA_STATE from memory. These instructions do NOT use a QR register — the load goes directly into the special register. + +| Instruction | Description | +|-------------|-------------| +| `ESP.LD.QACC.H.H.128.IP rs1, imm` | Load 16 bytes to QACC_H[255:128], rs1 += imm (imm: -2048 to 2032, step 16) | +| `ESP.LD.QACC.H.L.128.IP rs1, imm` | Load 16 bytes to QACC_H[127:0], rs1 += imm | +| `ESP.LD.QACC.L.H.128.IP rs1, imm` | Load 16 bytes to QACC_L[255:128], rs1 += imm | +| `ESP.LD.QACC.L.L.128.IP rs1, imm` | Load 16 bytes to QACC_L[127:0], rs1 += imm | +| `ESP.LD.XACC.IP rs1, imm` | Load 8 bytes to XACC (lower 40 bits), rs1 += imm (imm: -1024 to 1016, step 8) | +| `ESP.LD.UA.STATE.IP rs1, imm` | Load 16 bytes to UA_STATE, rs1 += imm | + +### Indexed/Extended Loads + +| Instruction | Description | +|-------------|-------------| +| `ESP.LDXQ.32 qu, qw, rs1, sel4, sel8` | rs1 += qw[sel8*16+15:sel8*16] << 2 as index, then load 4 bytes into qu[32*sel4+31:32*sel4] | +| `ESP.VLDEXT.U8.IP qu, rs1, imm` | Vector unsigned-extend 8-bit load segments to 16-bit | +| `ESP.VLDEXT.U8.XP qu, rs1, rs2` | Same, rs1 += rs2 | +| `ESP.VLDEXT.U16.IP qu, rs1, imm` | Vector unsigned-extend 16-bit load segments to 32-bit | +| `ESP.VLDEXT.U16.XP qu, rs1, rs2` | Same, rs1 += rs2 | +| `ESP.VLDEXT.S8.IP qu, rs1, imm` | Vector signed-extend 8-bit load segments to 16-bit | +| `ESP.VLDEXT.S8.XP qu, rs1, rs2` | Same, rs1 += rs2 | +| `ESP.VLDEXT.S16.IP qu, rs1, imm` | Vector signed-extend 16-bit load segments to 32-bit | +| `ESP.VLDEXT.S16.XP qu, rs1, rs2` | Same, rs1 += rs2 | + +--- + +## Write Instructions + +Store data from vector registers or accumulators to memory. + +### 128-bit Vector Stores + +| Instruction | Description | +|-------------|-------------| +| `ESP.VST.128.IP qu, rs1, imm` | Store 16 bytes, rs1 += imm (imm: -128 to 112, step 16) | +| `ESP.VST.128.XP qu, rs1, rs2` | Store 16 bytes, rs1 += rs2 | + +### 64-bit Vector Stores + +| Instruction | Description | +|-------------|-------------| +| `ESP.VST.H.64.IP qu, rs1, imm` | Store QR[127:64] (8 bytes), rs1 += imm | +| `ESP.VST.H.64.XP qu, rs1, rs2` | Store QR[127:64], rs1 += rs2 | +| `ESP.VST.L.64.IP qu, rs1, imm` | Store QR[63:0] (8 bytes), rs1 += imm | +| `ESP.VST.L.64.XP qu, rs1, rs2` | Store QR[63:0], rs1 += rs2 | + +### QACC Stores + +Store QACC_H/L data directly to memory. No QR register is involved — the data flows directly from the special register to memory. + +| Instruction | Description | +|-------------|-------------| +| `ESP.ST.QACC.H.H.128.IP rs1, imm` | Store QACC_H[255:128] to memory, rs1 += imm (imm: -2048 to 2032, step 16) | +| `ESP.ST.QACC.H.L.128.IP rs1, imm` | Store QACC_H[127:0] to memory, rs1 += imm | +| `ESP.ST.QACC.L.H.128.IP rs1, imm` | Store QACC_L[255:128] to memory, rs1 += imm | +| `ESP.ST.QACC.L.L.128.IP rs1, imm` | Store QACC_L[127:0] to memory, rs1 += imm | + +### XACC Stores + +Store XACC data directly to memory (sign-extended or zero-extended to 8 bytes). No QR register is involved. + +| Instruction | Description | +|-------------|-------------| +| `ESP.ST.U.XACC.IP rs1, imm` | Zero-extend XACC[39:0] to 64-bit and store, rs1 += imm (imm: -1024 to 1016, step 8) | +| `ESP.ST.S.XACC.IP rs1, imm` | Sign-extend XACC[39:0] to 64-bit and store, rs1 += imm | + +### Other Stores + +| Instruction | Description | +|-------------|-------------| +| `ESP.ST.UA.STATE.IP rs1, imm` | Store UA_STATE to memory, rs1 += imm | +| `ESP.STXQ.32 qu, qw, rs1, sel4, sel8` | Store qu[32*sel4+31:32*sel4] to address rs1 + qw[sel8*16+15:sel8*16] << 2, then rs1 += qw[sel8*16+15:sel8*16] << 2 | + +--- + +## Data Exchange Instructions + +Move data between different register types and perform reordering. + +### AR to QR Element Moves + +| Instruction | Description | +|-------------|-------------| +| `ESP.MOVI.8.A qu, rs1, sel16` | Move QR[sel16*8+7:sel16*8] (1 byte) to AR | +| `ESP.MOVI.16.A qu, rs1, sel8` | Move QR[sel8*16+15:sel8*16] (2 bytes) to AR | +| `ESP.MOVI.32.A qu, rs1, sel4` | Move QR[sel4*32+31:sel4*32] (4 bytes) to AR | +| `ESP.MOVI.8.Q qu, rs1, sel16` | Move AR to QR[sel16*8+7:sel16*8] | +| `ESP.MOVI.16.Q qu, rs1, sel8` | Move AR to QR[sel8*16+15:sel8*16] | +| `ESP.MOVI.32.Q qu, rs1, sel4` | Move AR to QR[sel4*32+31:sel4*32] | + +### Special Register Moves + +| Instruction | Description | +|-------------|-------------| +| `ESP.MOVX.R.CFG rd` | Read CFG to AR. Also auto-clears vxsat bit. | +| `ESP.MOVX.W.CFG rs1` | Write AR to CFG | +| `ESP.MOVX.R.SAR.BYTES rd` | Read SAR_BYTE to AR | +| `ESP.MOVX.W.SAR.BYTES rs1` | Write AR to SAR_BYTE | +| `ESP.MOVX.R.SAR rd` | Read SAR to AR | +| `ESP.MOVX.W.SAR rs1` | Write AR to SAR | +| `ESP.MOVX.R.FFT.BIT.WIDTH rd` | Read FFT_BIT_WIDTH to AR | +| `ESP.MOVX.W.FFT.BIT.WIDTH rs1` | Write AR to FFT_BIT_WIDTH | +| `ESP.MOVX.R.PERF rd, rs1` | Read PERF counter to AR | +| `ESP.MOVX.W.PERF rs1` | Write AR to PERF counter | +| `ESP.MOVX.R.XACC.H rd` | Read XACC[39:24] (high 16 bits) to AR | +| `ESP.MOVX.R.XACC.L rd` | Read XACC[23:0] (low 24 bits, sign-extended to 32) to AR | +| `ESP.MOVX.W.XACC.H rs1` | Write AR to XACC[39:24] | +| `ESP.MOVX.W.XACC.L rs1` | Write AR to XACC[23:0] | + +### QR Data Movement + +| Instruction | Description | +|-------------|-------------| +| `ESP.VZIP.8 qz, qx, qy` | Zip/interleave two QR by 8-bit elements | +| `ESP.VZIP.16 qz, qx, qy` | Zip/interleave two QR by 16-bit elements | +| `ESP.VZIP.32 qz, qx, qy` | Zip/interleave two QR by 32-bit elements | +| `ESP.VUNZIP.8 qz, qx, qy` | Unzip/deinterleave two QR by 8-bit elements | +| `ESP.VUNZIP.16 qz, qx, qy` | Unzip/deinterleave two QR by 16-bit elements | +| `ESP.VUNZIP.32 qz, qx, qy` | Unzip/deinterleave two QR by 32-bit elements | +| `ESP.VZIPT.8 qz, qx, qy` | Zip three QR by 8-bit elements | +| `ESP.VZIPT.16 qz, qx, qy` | Zip three QR by 16-bit elements | +| `ESP.VUNZIPT.8 qz, qx, qy` | Unzip three QR by 8-bit elements | +| `ESP.VUNZIPT.16 qz, qx, qy` | Unzip three QR by 16-bit elements | + +### Sign/Zero Extension + +| Instruction | Description | +|-------------|-------------| +| `ESP.VEXT.U8 qu, qv` | Zero-extend each 8-bit element to 16-bit | +| `ESP.VEXT.S8 qu, qv` | Sign-extend each 8-bit element to 16-bit | +| `ESP.VEXT.U16 qu, qv` | Zero-extend each 16-bit element to 32-bit | +| `ESP.VEXT.S16 qu, qv` | Sign-extend each 16-bit element to 32-bit | + +### QR to QACC Moves + +Load a QR register's data into QACC_H/L, with sign-extension or zero-extension. + +| Instruction | Description | +|-------------|-------------| +| `ESP.MOV.S8.QACC qu` | Sign-extend each of 16 × 8-bit segments in `qu` to 32-bit, write to QACC_H/L | +| `ESP.MOV.U8.QACC qu` | Zero-extend each of 16 × 8-bit segments in `qu` to 32-bit, write to QACC_H/L | +| `ESP.MOV.S16.QACC qu` | Sign-extend each of 8 × 16-bit segments in `qu` to 64-bit, write to QACC_H/L | +| `ESP.MOV.U16.QACC qu` | Zero-extend each of 8 × 16-bit segments in `qu` to 64-bit, write to QACC_H/L | + +> **Note:** To extract data FROM QACC back TO a QR register, use the SRCMB instructions (see [QACC/XACC Shift and Move](#qaccxacc-shift-and-move)). + +### Register Clears + +| Instruction | Description | +|-------------|-------------| +| `ESP.ZERO.Q qN` | Clear QR register to zero | +| `ESP.ZERO.QACC` | Clear QACC_H and QACC_L to zero | +| `ESP.ZERO.XACC` | Clear XACC to zero | + +--- + +## Arithmetic Instructions + +**Important:** All VADD and VSUB variants (both signed and unsigned) perform **saturating** arithmetic. Results are clamped to the representable range of the destination element type. + +### Vector Addition (Signed, Saturating) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VADD.S8 qv, qx, qy` | 16 × 8-bit signed saturating add: `min(max(qx[i]+qy[i], -2^7), 2^7-1)` | +| `ESP.VADD.S16 qv, qx, qy` | 8 × 16-bit signed saturating add: `min(max(qx[i]+qy[i], -2^15), 2^15-1)` | +| `ESP.VADD.S32 qv, qx, qy` | 4 × 32-bit signed saturating add: `min(max(qx[i]+qy[i], -2^31), 2^31-1)` | +| `ESP.VADD.S8.LD.INCP qu, rs1, qv, qx, qy` | VADD.S8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VADD.S16.LD.INCP qu, rs1, qv, qx, qy` | VADD.S16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VADD.S32.LD.INCP qu, rs1, qv, qx, qy` | VADD.S32 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VADD.S8.ST.INCP qu, rs1, qv, qx, qy` | VADD.S8 + store qu to memory, rs1 += 16 | +| `ESP.VADD.S16.ST.INCP qu, rs1, qv, qx, qy` | VADD.S16 + store qu to memory, rs1 += 16 | +| `ESP.VADD.S32.ST.INCP qu, rs1, qv, qx, qy` | VADD.S32 + store qu to memory, rs1 += 16 | + +### Vector Addition (Unsigned, Saturating) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VADD.U8 qv, qx, qy` | 16 × 8-bit unsigned saturating add: `min(qx[i]+qy[i], 2^8-1)` | +| `ESP.VADD.U16 qv, qx, qy` | 8 × 16-bit unsigned saturating add: `min(qx[i]+qy[i], 2^16-1)` | +| `ESP.VADD.U32 qv, qx, qy` | 4 × 32-bit unsigned saturating add: `min(qx[i]+qy[i], 2^32-1)` | +| `ESP.VADD.U8.LD.INCP qu, rs1, qv, qx, qy` | VADD.U8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VADD.U16.LD.INCP qu, rs1, qv, qx, qy` | VADD.U16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VADD.U32.LD.INCP qu, rs1, qv, qx, qy` | VADD.U32 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VADD.U8.ST.INCP qu, rs1, qv, qx, qy` | VADD.U8 + store qu to memory, rs1 += 16 | +| `ESP.VADD.U16.ST.INCP qu, rs1, qv, qx, qy` | VADD.U16 + store qu to memory, rs1 += 16 | +| `ESP.VADD.U32.ST.INCP qu, rs1, qv, qx, qy` | VADD.U32 + store qu to memory, rs1 += 16 | + +### Scalar Saturated Vector Addition + +**Note:** VSADDS adds a **scalar** from an AR register (`rs1`) to each element of a QR vector. Different from VADD which uses two QR vectors. + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSADDS.S8 qv, qx, rs1` | 16 × 8-bit: `qv[i] = min(max(qx[i] + rs1[7:0], -2^7), 2^7-1)` | +| `ESP.VSADDS.S16 qv, qx, rs1` | 8 × 16-bit: `qv[i] = min(max(qx[i] + rs1[15:0], -2^15), 2^15-1)` | +| `ESP.VSADDS.U8 qv, qx, rs1` | 16 × 8-bit: `qv[i] = min(qx[i] + rs1[7:0], 2^8-1)` | +| `ESP.VSADDS.U16 qv, qx, rs1` | 8 × 16-bit: `qv[i] = min(qx[i] + rs1[15:0], 2^16-1)` | + +### Vector Subtraction (Signed, Saturating) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSUB.S8 qv, qx, qy` | 16 × 8-bit signed saturating sub (qx - qy) | +| `ESP.VSUB.S16 qv, qx, qy` | 8 × 16-bit signed saturating sub | +| `ESP.VSUB.S32 qv, qx, qy` | 4 × 32-bit signed saturating sub | +| `ESP.VSUB.S8.LD.INCP qu, rs1, qv, qx, qy` | VSUB.S8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VSUB.S16.LD.INCP qu, rs1, qv, qx, qy` | VSUB.S16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VSUB.S32.LD.INCP qu, rs1, qv, qx, qy` | VSUB.S32 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VSUB.S8.ST.INCP qu, rs1, qv, qx, qy` | VSUB.S8 + store qu to memory, rs1 += 16 | +| `ESP.VSUB.S16.ST.INCP qu, rs1, qv, qx, qy` | VSUB.S16 + store qu to memory, rs1 += 16 | +| `ESP.VSUB.S32.ST.INCP qu, rs1, qv, qx, qy` | VSUB.S32 + store qu to memory, rs1 += 16 | + +### Vector Subtraction (Unsigned, Saturating) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSUB.U8 qv, qx, qy` | 16 × 8-bit unsigned saturating sub (qx - qy): `min(qx[i]-qy[i], 2^8-1)` | +| `ESP.VSUB.U16 qv, qx, qy` | 8 × 16-bit unsigned saturating sub: `min(qx[i]-qy[i], 2^16-1)` | +| `ESP.VSUB.U32 qv, qx, qy` | 4 × 32-bit unsigned saturating sub: `min(qx[i]-qy[i], 2^32-1)` | +| `ESP.VSUB.U8.LD.INCP qu, rs1, qv, qx, qy` | VSUB.U8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VSUB.U16.LD.INCP qu, rs1, qv, qx, qy` | VSUB.U16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VSUB.U32.LD.INCP qu, rs1, qv, qx, qy` | VSUB.U32 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VSUB.U8.ST.INCP qu, rs1, qv, qx, qy` | VSUB.U8 + store qu to memory, rs1 += 16 | +| `ESP.VSUB.U16.ST.INCP qu, rs1, qv, qx, qy` | VSUB.U16 + store qu to memory, rs1 += 16 | +| `ESP.VSUB.U32.ST.INCP qu, rs1, qv, qx, qy` | VSUB.U32 + store qu to memory, rs1 += 16 | + +### Scalar Saturated Vector Subtraction + +**Note:** VSSUBS subtracts a **scalar** from an AR register (`rs1`) from each element of a QR vector. + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSSUBS.S8 qv, qx, rs1` | 16 × 8-bit: `qv[i] = min(max(qx[i] - rs1[7:0], -2^7), 2^7-1)` | +| `ESP.VSSUBS.S16 qv, qx, rs1` | 8 × 16-bit: `qv[i] = min(max(qx[i] - rs1[15:0], -2^15), 2^15-1)` | +| `ESP.VSSUBS.U8 qv, qx, rs1` | 16 × 8-bit: `qv[i] = min(qx[i] - rs1[7:0], 2^8-1)` | +| `ESP.VSSUBS.U16 qv, qx, rs1` | 8 × 16-bit: `qv[i] = min(qx[i] - rs1[15:0], 2^16-1)` | + +### Vector Multiplication + +Multiplies are followed by an **arithmetic** right shift of SAR bits; the lower half is kept. The rounding mode (vxrm in CFG) controls rounding during the shift. + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMUL.S8 qz, qx, qy` | 16 × 8-bit signed mul, result >> SAR, keep low 8 | +| `ESP.VMUL.S16 qz, qx, qy` | 8 × 16-bit signed mul, result >> SAR, keep low 16 | +| `ESP.VMUL.U8 qz, qx, qy` | 16 × 8-bit unsigned mul, result >> SAR, keep low 8 | +| `ESP.VMUL.U16 qz, qx, qy` | 8 × 16-bit unsigned mul, result >> SAR, keep low 16 | +| `ESP.VMUL.S8.LD.INCP qu, rs1, qz, qx, qy` | V.MUL.S8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMUL.S16.LD.INCP qu, rs1, qz, qx, qy` | V.MUL.S16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMUL.U8.LD.INCP qu, rs1, qz, qx, qy` | V.MUL.U8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMUL.U16.LD.INCP qu, rs1, qz, qx, qy` | V.MUL.U16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMUL.S8.ST.INCP qu, rs1, qz, qx, qy` | V.MUL.S8 + store qu to memory, rs1 += 16 | +| `ESP.VMUL.S16.ST.INCP qu, rs1, qz, qx, qy` | V.MUL.S16 + store qu to memory, rs1 += 16 | +| `ESP.VMUL.U8.ST.INCP qu, rs1, qz, qx, qy` | V.MUL.U8 + store qu to memory, rs1 += 16 | +| `ESP.VMUL.U16.ST.INCP qu, rs1, qz, qx, qy` | V.MUL.U16 + store qu to memory, rs1 += 16 | + +### Extended Output Vector Multiplication + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMUL.S32.S16xS16 qz, qx, qy` | 8 × 16-bit signed mul, result >> SAR, produce 8 × 32-bit results (full 32-bit result kept) | +| `ESP.VMUL.S16.S8xS8 qz, qv, qx, qy` | 16 × 8-bit signed mul → 16 × 16-bit: low 8 results to `qz`, high 8 results to `qv`. Each result >> SAR before storing. | + +### Vector Complex Multiplication + +Operates on pairs as complex numbers (real, imag). The `sel4` immediate (0–3) selects which quadrant of the 128-bit register to operate on. Result is right-shifted by SAR. + +#### Signed Complex Multiplication + +| Instruction | Description | +|-------------|-------------| +| `ESP.CMUL.S16 qz, qx, qy, sel4` | 16-bit signed complex multiply (sel4 controls operand quadrants). `real = (a.re*b.re - a.im*b.im) >> SAR`, `imag = (a.re*b.im + a.im*b.re) >> SAR` (or conjugate variants per sel4) | +| `ESP.CMUL.S16.LD.INCP qu, rs1, qz, qx, qy, sel4` | CMUL.S16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.CMUL.S16.ST.INCP qu, rs1, qz, qx, qy, sel4` | CMUL.S16 + store qu to memory, rs1 += 16 | +| `ESP.CMUL.S8 qz, qx, qy, sel4` | 8-bit signed complex multiply (sel4 controls operand halves) | +| `ESP.CMUL.S8.LD.INCP qu, rs1, qz, qx, qy, sel4` | CMUL.S8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.CMUL.S8.ST.INCP qu, rs1, qz, qx, qy, sel4` | CMUL.S8 + store qu to memory, rs1 += 16 | + +#### Unsigned Complex Multiplication + +| Instruction | Description | +|-------------|-------------| +| `ESP.CMUL.U16 qz, qx, qy, sel4` | 16-bit unsigned complex multiply | +| `ESP.CMUL.U16.LD.INCP qu, rs1, qz, qx, qy, sel4` | CMUL.U16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.CMUL.U16.ST.INCP qu, rs1, qz, qx, qy, sel4` | CMUL.U16 + store qu to memory, rs1 += 16 | +| `ESP.CMUL.U8 qz, qx, qy, sel4` | 8-bit unsigned complex multiply | +| `ESP.CMUL.U8.LD.INCP qu, rs1, qz, qx, qy, sel4` | CMUL.U8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.CMUL.U8.ST.INCP qu, rs1, qz, qx, qy, sel4` | CMUL.U8 + store qu to memory, rs1 += 16 | + +### Vector Multiply-Accumulate to QACC + +Accumulates element-wise products into QACC segments. Results are **saturated** to the accumulator segment width. + +**Segment widths:** +- S8/U8 MAC: 32-bit per QACC segment (16 segments per QACC half) +- S16/U16 MAC: 64-bit per QACC segment (4 segments per QACC half) + +#### Signed MAC to QACC + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMULAS.S8.QACC qx, qy` | 16 × S8 mul, accumulate 32-bit to QACC_H/L (saturated to 32-bit signed) | +| `ESP.VMULAS.S16.QACC qx, qy` | 8 × S16 mul, accumulate 64-bit to QACC_H/L (saturated to 64-bit signed) | + +#### Unsigned MAC to QACC + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMULAS.U8.QACC qx, qy` | 16 × U8 mul, accumulate 32-bit to QACC_H/L (saturated to 32-bit unsigned) | +| `ESP.VMULAS.U16.QACC qx, qy` | 8 × U16 mul, accumulate 64-bit to QACC_H/L (saturated to 64-bit unsigned) | + +#### Fused MAC variants (signed, with memory access) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMULAS.S8.QACC.LD.IP qu, rs, imm, qx, qy` | MAC S8 to QACC + load (rs += imm) | +| `ESP.VMULAS.S16.QACC.LD.IP qu, rs, imm, qx, qy` | MAC S16 to QACC + load | +| `ESP.VMULAS.S8.QACC.LD.XP qu, rs1, rs2, qx, qy` | MAC S8 to QACC + load (rs1 += rs2) | +| `ESP.VMULAS.S16.QACC.LD.XP qu, rs1, rs2, qx, qy` | MAC S16 to QACC + load (rs1 += rs2) | +| `ESP.VMULAS.S8.QACC.ST.IP qu, rs, imm, qx, qy` | MAC S8 to QACC + store | +| `ESP.VMULAS.S16.QACC.ST.IP qu, rs, imm, qx, qy` | MAC S16 to QACC + store | +| `ESP.VMULAS.S8.QACC.ST.XP qu, rs1, rs2, qx, qy` | MAC S8 to QACC + store (rs1 += rs2) | +| `ESP.VMULAS.S16.QACC.ST.XP qu, rs1, rs2, qx, qy` | MAC S16 to QACC + store (rs1 += rs2) | +| `ESP.VMULAS.S8.QACC.LDBC.INCP qu, rs, imm, qx, qy` | MAC S8 to QACC + broadcast load | +| `ESP.VMULAS.S16.QACC.LDBC.INCP qu, rs, imm, qx, qy` | MAC S16 to QACC + broadcast load | + +#### Fused MAC variants (unsigned, with memory access) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMULAS.U8.QACC.LD.IP qu, rs, imm, qx, qy` | MAC U8 to QACC + load | +| `ESP.VMULAS.U16.QACC.LD.IP qu, rs, imm, qx, qy` | MAC U16 to QACC + load | +| `ESP.VMULAS.U8.QACC.LD.XP qu, rs1, rs2, qx, qy` | MAC U8 to QACC + load (rs1 += rs2) | +| `ESP.VMULAS.U16.QACC.LD.XP qu, rs1, rs2, qx, qy` | MAC U16 to QACC + load (rs1 += rs2) | +| `ESP.VMULAS.U8.QACC.ST.IP qu, rs, imm, qx, qy` | MAC U8 to QACC + store | +| `ESP.VMULAS.U16.QACC.ST.IP qu, rs, imm, qx, qy` | MAC U16 to QACC + store | +| `ESP.VMULAS.U8.QACC.ST.XP qu, rs1, rs2, qx, qy` | MAC U8 to QACC + store (rs1 += rs2) | +| `ESP.VMULAS.U16.QACC.ST.XP qu, rs1, rs2, qx, qy` | MAC U16 to QACC + store (rs1 += rs2) | +| `ESP.VMULAS.U8.QACC.LDBC.INCP qu, rs, imm, qx, qy` | MAC U8 to QACC + broadcast load | +| `ESP.VMULAS.U16.QACC.LDBC.INCP qu, rs, imm, qx, qy` | MAC U16 to QACC + broadcast load | + +### Vector Multiply-Accumulate to XACC + +Computes the **sum** of all element-wise products (dot-product style). Result accumulated in XACC (40-bit, saturated). + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMULAS.S8.XACC qx, qy` | 16 × S8 mul, sum all to XACC (40-bit, saturated) | +| `ESP.VMULAS.S16.XACC qx, qy` | 8 × S16 mul, sum all to XACC (40-bit, saturated) | +| `ESP.VMULAS.U8.XACC qx, qy` | 16 × U8 mul, sum all to XACC (40-bit, saturated) | +| `ESP.VMULAS.U16.XACC qx, qy` | 8 × U16 mul, sum all to XACC (40-bit, saturated) | + +**Fused variants:** + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMULAS.S8.XACC.LD.IP qu, rs, imm, qx, qy` | MAC to XACC + load | +| `ESP.VMULAS.S16.XACC.LD.IP qu, rs, imm, qx, qy` | MAC to XACC + load | +| `ESP.VMULAS.S8.XACC.LD.XP qu, rs1, rs2, qx, qy` | MAC to XACC + load (rs1 += rs2) | +| `ESP.VMULAS.S16.XACC.LD.XP qu, rs1, rs2, qx, qy` | MAC to XACC + load (rs1 += rs2) | +| `ESP.VMULAS.S8.XACC.ST.IP qu, rs, imm, qx, qy` | MAC to XACC + store | +| `ESP.VMULAS.S16.XACC.ST.IP qu, rs, imm, qx, qy` | MAC to XACC + store | +| `ESP.VMULAS.S8.XACC.ST.XP qu, rs1, rs2, qx, qy` | MAC to XACC + store (rs1 += rs2) | +| `ESP.VMULAS.S16.XACC.ST.XP qu, rs1, rs2, qx, qy` | MAC to XACC + store (rs1 += rs2) | + +### Scalar-Vector Multiply-Accumulate to QACC + +One operand is a vector (`qx`), the other is a **scalar element** selected from `qy` using `sel`. Accumulates into QACC with saturation. + +#### Signed Scalar-Vector MAC + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSMULAS.S8.QACC qx, qy, sel16` | Select 1 of 16 bytes from qy; 16 × S8 MAC to QACC (saturated to 32-bit signed) | +| `ESP.VSMULAS.S16.QACC qx, qy, sel8` | Select 1 of 8 half-words from qy; 8 × S16 MAC to QACC (saturated to 64-bit signed) | +| `ESP.VSMULAS.S8.QACC.LD.INCP qu, rs, qx, qy, sel16` | VSMULAS.S8.QACC + load 16 bytes to qu, rs += 16 | +| `ESP.VSMULAS.S16.QACC.LD.INCP qu, rs, qx, qy, sel8` | VSMULAS.S16.QACC + load 16 bytes to qu, rs += 16 | + +#### Unsigned Scalar-Vector MAC + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSMULAS.U8.QACC qx, qy, sel16` | Select 1 of 16 bytes from qy; 16 × U8 MAC to QACC (saturated to 32-bit unsigned) | +| `ESP.VSMULAS.U16.QACC qx, qy, sel8` | Select 1 of 8 half-words from qy; 8 × U16 MAC to QACC (saturated to 64-bit unsigned) | +| `ESP.VSMULAS.U8.QACC.LD.INCP qu, rs, qx, qy, sel16` | VSMULAS.U8.QACC + load 16 bytes to qu, rs += 16 | +| `ESP.VSMULAS.U16.QACC.LD.INCP qu, rs, qx, qy, sel8` | VSMULAS.U16.QACC + load 16 bytes to qu, rs += 16 | + +### Complex Multiply-Accumulate to QACC + +| Instruction | Description | +|-------------|-------------| +| `ESP.VCMULAS.S8.QACC.H qx, qy` | Complex MAC S8 to QACC_H | +| `ESP.VCMULAS.S8.QACC.L qx, qy` | Complex MAC S8 to QACC_L | +| `ESP.VCMULAS.S16.QACC.H qx, qy` | Complex MAC S16 to QACC_H | +| `ESP.VCMULAS.S16.QACC.L qx, qy` | Complex MAC S16 to QACC_L | + +**Fused variants:** + +| Instruction | Description | +|-------------|-------------| +| `ESP.VCMULAS.S8.QACC.H.LD.IP qu, rs, imm, qx, qy` | Complex MAC to QACC_H + load | +| `ESP.VCMULAS.S8.QACC.L.LD.IP qu, rs, imm, qx, qy` | Complex MAC to QACC_L + load | +| `ESP.VCMULAS.S16.QACC.H.LD.IP qu, rs, imm, qx, qy` | Complex MAC S16 to QACC_H + load | +| `ESP.VCMULAS.S16.QACC.L.LD.IP qu, rs, imm, qx, qy` | Complex MAC S16 to QACC_L + load | +| `ESP.VCMULAS.S8.QACC.H.LD.XP qu, rs1, rs2, qx, qy` | Complex MAC to QACC_H + load (rs1 += rs2) | +| `ESP.VCMULAS.S8.QACC.L.LD.XP qu, rs1, rs2, qx, qy` | Complex MAC to QACC_L + load (rs1 += rs2) | +| `ESP.VCMULAS.S16.QACC.H.LD.XP qu, rs1, rs2, qx, qy` | Complex MAC S16 to QACC_H + load (rs1 += rs2) | +| `ESP.VCMULAS.S16.QACC.L.LD.XP qu, rs1, rs2, qx, qy` | Complex MAC S16 to QACC_L + load (rs1 += rs2) | + +### QACC/XACC Shift and Move + +| Instruction | Description | +|-------------|-------------| +| `ESP.SRCMB.S8.QACC qx, imm` | Shift QACC_H/L right by `imm` per 32-bit segment, saturate to S8, move to qx | +| `ESP.SRCMB.S16.QACC qx, imm` | Shift QACC_H/L right by `imm` per 64-bit segment, saturate to S16, move to qx | +| `ESP.SRCMB.U8.QACC qx, imm` | Shift QACC_H/L right by `imm` per 32-bit segment, saturate to U8, move to qx | +| `ESP.SRCMB.U16.QACC qx, imm` | Shift QACC_H/L right by `imm` per 64-bit segment, saturate to U16, move to qx | +| `ESP.SRCMB.S8.Q.QACC qx, qy` | Same as SRCMB.S8.QACC but shift amount from QR | +| `ESP.SRCMB.S16.Q.QACC qx, qy` | Same as SRCMB.S16.QACC but shift amount from QR | +| `ESP.SRCMB.U8.Q.QACC qx, qy` | Same as SRCMB.U8.QACC but shift amount from QR | +| `ESP.SRCMB.U16.Q.QACC qx, qy` | Same as SRCMB.U16.QACC but shift amount from QR | +| `ESP.SRS.S.XACC rd, rs1` | Arithmetic right shift XACC by `rs1[5:0]`; write 40-bit result back to XACC, and write result saturated to 32-bit signed: `min(max(XACC>>rs1, -2^31), 2^31-1)` into `rd` | +| `ESP.SRS.U.XACC rd, rs1` | Unsigned counterpart: right shift XACC by `rs1[5:0]`, write 40-bit result back to XACC, write result saturated to 32-bit unsigned into `rd` | + +### Activation / Other Arithmetic + +| Instruction | Description | +|-------------|-------------| +| `ESP.VRELU.S8 qz, qx, qy` | 16 × S8 ReLU: `qz[i] = qx[i] > 0 ? qx[i] * qy[0] : 0` | +| `ESP.VRELU.S16 qz, qx, qy` | 8 × S16 ReLU: `qz[i] = qx[i] > 0 ? qx[i] * qy[0] : 0` | +| `ESP.VPRELU.S8 qz, qx, qy` | 16 × S8 PReLU: `qz[i] = qx[i] > 0 ? qx[i] : qx[i] * qy[i]` | +| `ESP.VPRELU.S16 qz, qx, qy` | 8 × S16 PReLU: `qz[i] = qx[i] > 0 ? qx[i] : qx[i] * qy[i]` | +| `ESP.VABS.8 qz, qx` | 16 × 8-bit absolute value | +| `ESP.VABS.16 qz, qx` | 8 × 16-bit absolute value | +| `ESP.VABS.32 qz, qx` | 4 × 32-bit absolute value | +| `ESP.SAT rsd, rs0, rs1` | Saturate `rsd` between clamp bounds derived from `rs0` and `rs1`: `min_t = max(rs1, rs0)`, `max_t = min(rs1, rs0)`, `rsd = max(min(rsd, max_t), min_t)`. rsd is both source and destination (read-modify-write). | +| `ESP.ADDX2 rd, rs1, rs2` | `rd = rs1 + (rs2 << 1)` | +| `ESP.ADDX4 rd, rs1, rs2` | `rd = rs1 + (rs2 << 2)` | +| `ESP.SUBX2 rd, rs1, rs2` | `rd = rs1 - (rs2 << 1)` | +| `ESP.SUBX4 rd, rs1, rs2` | `rd = rs1 - (rs2 << 2)` | + +### Vector Clamp + +**Note:** VCLAMP uses a single QR register `qx` and an immediate `sel16`, clamped to the symmetric range `[-2^sel16, 2^sel16-1]`. + +| Instruction | Description | +|-------------|-------------| +| `ESP.VCLAMP.S16 qz, qx, sel16` | Clamp 8 × S16: `qz[i] = min(max(qx[i], -2^sel16), 2^sel16-1)` | + +### Vector Saturation (VSAT) + +**Note:** VSAT uses **two AR registers** (`rs1`, `rs2`) to define the clamp bounds. The bounds `min_t` and `max_t` are derived as `min_t = max(rs1, rs2)` and `max_t = min(rs1, rs2)` (exchanging the role of comparison to derive the actual asymmetric range). Each element in `qx` is clamped to `[min_t, max_t]`. + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSAT.S8 qz, qx, rs1, rs2` | Clamp each of 16 × S8 in qx to range derived from rs1/rs2 | +| `ESP.VSAT.S16 qz, qx, rs1, rs2` | Clamp each of 8 × S16 in qx to range derived from rs1/rs2 | +| `ESP.VSAT.S32 qz, qx, rs1, rs2` | Clamp each of 4 × S32 in qx to range derived from rs1/rs2 | +| `ESP.VSAT.U8 qz, qx, rs1, rs2` | Clamp each of 16 × U8 in qx to range derived from rs1/rs2 | +| `ESP.VSAT.U16 qz, qx, rs1, rs2` | Clamp each of 8 × U16 in qx to range derived from rs1/rs2 | +| `ESP.VSAT.U32 qz, qx, rs1, rs2` | Clamp each of 4 × U32 in qx to range derived from rs1/rs2 | + +--- + +## Comparison Instructions + +### Vector Maximum (Element-wise) + +For VMAX, each element `qz[i] = (qx[i] >= qy[i]) ? qx[i] : qy[i]`. + +#### Signed Vector Maximum + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMAX.S8 qz, qx, qy` | 16 × 8-bit signed element-wise max | +| `ESP.VMAX.S16 qz, qx, qy` | 8 × 16-bit signed element-wise max | +| `ESP.VMAX.S32 qz, qx, qy` | 4 × 32-bit signed element-wise max | +| `ESP.VMAX.S8.LD.INCP qu, rs1, qz, qx, qy` | VMAX.S8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMAX.S16.LD.INCP qu, rs1, qz, qx, qy` | VMAX.S16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMAX.S32.LD.INCP qu, rs1, qz, qx, qy` | VMAX.S32 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMAX.S8.ST.INCP qu, rs1, qz, qx, qy` | VMAX.S8 + store qu to memory, rs1 += 16 | +| `ESP.VMAX.S16.ST.INCP qu, rs1, qz, qx, qy` | VMAX.S16 + store qu to memory, rs1 += 16 | +| `ESP.VMAX.S32.ST.INCP qu, rs1, qz, qx, qy` | VMAX.S32 + store qu to memory, rs1 += 16 | + +#### Unsigned Vector Maximum + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMAX.U8 qz, qx, qy` | 16 × 8-bit unsigned element-wise max | +| `ESP.VMAX.U16 qz, qx, qy` | 8 × 16-bit unsigned element-wise max | +| `ESP.VMAX.U32 qz, qx, qy` | 4 × 32-bit unsigned element-wise max | +| `ESP.VMAX.U8.LD.INCP qu, rs1, qz, qx, qy` | VMAX.U8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMAX.U16.LD.INCP qu, rs1, qz, qx, qy` | VMAX.U16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMAX.U32.LD.INCP qu, rs1, qz, qx, qy` | VMAX.U32 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMAX.U8.ST.INCP qu, rs1, qz, qx, qy` | VMAX.U8 + store qu to memory, rs1 += 16 | +| `ESP.VMAX.U16.ST.INCP qu, rs1, qz, qx, qy` | VMAX.U16 + store qu to memory, rs1 += 16 | +| `ESP.VMAX.U32.ST.INCP qu, rs1, qz, qx, qy` | VMAX.U32 + store qu to memory, rs1 += 16 | + +### Scalar Maximum (Vector → AR) + +Finds the maximum value across all elements of a QR register and writes it to an AR register `rd`. + +| Instruction | Description | +|-------------|-------------| +| `ESP.MAX.S8.A qw, rd` | Max of 16 signed 8-bit elements → rd. `rd = {24{max_value[7]}, max_value[7:0]}` (sign-extended) | +| `ESP.MAX.S16.A qw, rd` | Max of 8 signed 16-bit elements → rd. `rd = {16{max_value[15]}, max_value[15:0]}` (sign-extended) | +| `ESP.MAX.S32.A qw, rd` | Max of 4 signed 32-bit elements → rd. `rd = max_value[31:0]` | +| `ESP.MAX.U8.A qw, rd` | Max of 16 unsigned 8-bit elements → rd. `rd = {24'b0, max_value[7:0]}` (zero-extended) | +| `ESP.MAX.U16.A qw, rd` | Max of 8 unsigned 16-bit elements → rd. `rd = {16'b0, max_value[15:0]}` (zero-extended) | +| `ESP.MAX.U32.A qw, rd` | Max of 4 unsigned 32-bit elements → rd. `rd = max_value[31:0]` | + +### Vector Minimum (Element-wise) + +For VMIN, each element `qz[i] = (qx[i] <= qy[i]) ? qx[i] : qy[i]`. + +#### Signed Vector Minimum + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMIN.S8 qz, qx, qy` | 16 × 8-bit signed element-wise min | +| `ESP.VMIN.S16 qz, qx, qy` | 8 × 16-bit signed element-wise min | +| `ESP.VMIN.S32 qz, qx, qy` | 4 × 32-bit signed element-wise min | +| `ESP.VMIN.S8.LD.INCP qu, rs1, qz, qx, qy` | VMIN.S8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMIN.S16.LD.INCP qu, rs1, qz, qx, qy` | VMIN.S16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMIN.S32.LD.INCP qu, rs1, qz, qx, qy` | VMIN.S32 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMIN.S8.ST.INCP qu, rs1, qz, qx, qy` | VMIN.S8 + store qu to memory, rs1 += 16 | +| `ESP.VMIN.S16.ST.INCP qu, rs1, qz, qx, qy` | VMIN.S16 + store qu to memory, rs1 += 16 | +| `ESP.VMIN.S32.ST.INCP qu, rs1, qz, qx, qy` | VMIN.S32 + store qu to memory, rs1 += 16 | + +#### Unsigned Vector Minimum + +| Instruction | Description | +|-------------|-------------| +| `ESP.VMIN.U8 qz, qx, qy` | 16 × 8-bit unsigned element-wise min | +| `ESP.VMIN.U16 qz, qx, qy` | 8 × 16-bit unsigned element-wise min | +| `ESP.VMIN.U32 qz, qx, qy` | 4 × 32-bit unsigned element-wise min | +| `ESP.VMIN.U8.LD.INCP qu, rs1, qz, qx, qy` | VMIN.U8 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMIN.U16.LD.INCP qu, rs1, qz, qx, qy` | VMIN.U16 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMIN.U32.LD.INCP qu, rs1, qz, qx, qy` | VMIN.U32 + load 16 bytes to qu, rs1 += 16 | +| `ESP.VMIN.U8.ST.INCP qu, rs1, qz, qx, qy` | VMIN.U8 + store qu to memory, rs1 += 16 | +| `ESP.VMIN.U16.ST.INCP qu, rs1, qz, qx, qy` | VMIN.U16 + store qu to memory, rs1 += 16 | +| `ESP.VMIN.U32.ST.INCP qu, rs1, qz, qx, qy` | VMIN.U32 + store qu to memory, rs1 += 16 | + +### Scalar Minimum (Vector → AR) + +Finds the minimum value across all elements of a QR register and writes it to an AR register `rd`. + +| Instruction | Description | +|-------------|-------------| +| `ESP.MIN.S8.A qw, rd` | Min of 16 signed 8-bit elements → rd. `rd = {24{min_value[7]}, min_value[7:0]}` (sign-extended) | +| `ESP.MIN.S16.A qw, rd` | Min of 8 signed 16-bit elements → rd. `rd = {16{min_value[15]}, min_value[15:0]}` (sign-extended) | +| `ESP.MIN.S32.A qw, rd` | Min of 4 signed 32-bit elements → rd. `rd = min_value[31:0]` | +| `ESP.MIN.U8.A qw, rd` | Min of 16 unsigned 8-bit elements → rd. `rd = {24'b0, min_value[7:0]}` (zero-extended) | +| `ESP.MIN.U16.A qw, rd` | Min of 8 unsigned 16-bit elements → rd. `rd = {16'b0, min_value[15:0]}` (zero-extended) | +| `ESP.MIN.U32.A qw, rd` | Min of 4 unsigned 32-bit elements → rd. `rd = min_value[31:0]` | + +### Vector Compare + +Result is all 1s (true) or all 0s (false) per element. The mask width matches the data width: 0xFF for 8-bit, 0xFFFF for 16-bit, 0xFFFFFFFF for 32-bit. + +#### Signed Comparison + +| Instruction | Description | +|-------------|-------------| +| `ESP.VCMP.EQ.S8 qz, qx, qy` | 16 × 8-bit compare equal: `qz[i] = (qx[i]==qy[i]) ? 0xFF : 0` | +| `ESP.VCMP.EQ.S16 qz, qx, qy` | 8 × 16-bit compare equal: `qz[i] = (qx[i]==qy[i]) ? 0xFFFF : 0` | +| `ESP.VCMP.EQ.S32 qz, qx, qy` | 4 × 32-bit compare equal: `qz[i] = (qx[i]==qy[i]) ? 0xFFFFFFFF : 0` | +| `ESP.VCMP.LT.S8 qz, qx, qy` | 16 × 8-bit compare less-than: `qz[i] = (qx[i] < qy[i]) ? 0xFF : 0` | +| `ESP.VCMP.LT.S16 qz, qx, qy` | 8 × 16-bit compare less-than: `qz[i] = (qx[i] < qy[i]) ? 0xFFFF : 0` | +| `ESP.VCMP.LT.S32 qz, qx, qy` | 4 × 32-bit compare less-than: `qz[i] = (qx[i] < qy[i]) ? 0xFFFFFFFF : 0` | +| `ESP.VCMP.GT.S8 qz, qx, qy` | 16 × 8-bit compare greater-than: `qz[i] = (qx[i] > qy[i]) ? 0xFF : 0` | +| `ESP.VCMP.GT.S16 qz, qx, qy` | 8 × 16-bit compare greater-than: `qz[i] = (qx[i] > qy[i]) ? 0xFFFF : 0` | +| `ESP.VCMP.GT.S32 qz, qx, qy` | 4 × 32-bit compare greater-than: `qz[i] = (qx[i] > qy[i]) ? 0xFFFFFFFF : 0` | + +#### Unsigned Comparison + +| Instruction | Description | +|-------------|-------------| +| `ESP.VCMP.EQ.U8 qz, qx, qy` | 16 × 8-bit unsigned compare equal: `qz[i] = (qx[i]==qy[i]) ? 0xFF : 0` | +| `ESP.VCMP.EQ.U16 qz, qx, qy` | 8 × 16-bit unsigned compare equal: `qz[i] = (qx[i]==qy[i]) ? 0xFFFF : 0` | +| `ESP.VCMP.EQ.U32 qz, qx, qy` | 4 × 32-bit unsigned compare equal: `qz[i] = (qx[i]==qy[i]) ? 0xFFFFFFFF : 0` | +| `ESP.VCMP.LT.U8 qz, qx, qy` | 16 × 8-bit unsigned less-than: `qz[i] = (qx[i] < qy[i]) ? 0xFF : 0` | +| `ESP.VCMP.LT.U16 qz, qx, qy` | 8 × 16-bit unsigned less-than: `qz[i] = (qx[i] < qy[i]) ? 0xFFFF : 0` | +| `ESP.VCMP.LT.U32 qz, qx, qy` | 4 × 32-bit unsigned less-than: `qz[i] = (qx[i] < qy[i]) ? 0xFFFFFFFF : 0` | +| `ESP.VCMP.GT.U8 qz, qx, qy` | 16 × 8-bit unsigned greater-than: `qz[i] = (qx[i] > qy[i]) ? 0xFF : 0` | +| `ESP.VCMP.GT.U16 qz, qx, qy` | 8 × 16-bit unsigned greater-than: `qz[i] = (qx[i] > qy[i]) ? 0xFFFF : 0` | +| `ESP.VCMP.GT.U32 qz, qx, qy` | 4 × 32-bit unsigned greater-than: `qz[i] = (qx[i] > qy[i]) ? 0xFFFFFFFF : 0` | + +--- + +## Bitwise Logical Instructions + +All operate on full 128-bit QR registers. + +| Instruction | Description | +|-------------|-------------| +| `ESP.ORQ qz, qx, qy` | 128-bit bitwise OR: `qz = qx \| qy` | +| `ESP.XORQ qz, qx, qy` | 128-bit bitwise XOR: `qz = qx ^ qy` | +| `ESP.ANDQ qz, qx, qy` | 128-bit bitwise AND: `qz = qx & qy` | +| `ESP.NOTQ qz, qx` | 128-bit bitwise NOT: `qz = ~qx` | + +--- + +## Shift Instructions + +### Vector Shift Right (per-element by SAR) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSR.U32 qz, qx` | 4 × 32-bit unsigned (logical) shift right by SAR | +| `ESP.VSR.S32 qz, qx` | 4 × 32-bit signed (arithmetic) shift right by SAR | + +### Vector Shift Left (by SAR) + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSL.32 qz, qx` | 4 × 32-bit shift left by SAR | + +### Vector Shift by Register (per-element signed shift amount) + +The shift amount is **not** an immediate — it comes from a Q register (`qw`), with one signed field per element aligned to that element's lane. If an element's shift field is negative, that element is shifted right by its absolute value; otherwise it is shifted left. Bits shifted out are discarded, and vacated bits are zero-filled. + +| Instruction | Description | +|-------------|-------------| +| `ESP.VSLD.8 qu, qy, qw` | 16 × 8-bit vector shift; per-lane signed amount from `qw` (negative ⇒ right shift, else left shift) | +| `ESP.VSLD.16 qu, qy, qw` | 8 × 16-bit vector shift; per-lane signed amount from `qw` (negative ⇒ right shift, else left shift) | +| `ESP.VSLD.32 qu, qy, qw` | 4 × 32-bit vector shift; per-lane signed amount from `qw` (negative ⇒ right shift, else left shift) | +| `ESP.VSRD.8 qu, qy, qw` | 16 × 8-bit vector shift; per-lane signed amount from `qw` | +| `ESP.VSRD.16 qu, qy, qw` | 8 × 16-bit vector shift; per-lane signed amount from `qw` | +| `ESP.VSRD.32 qu, qy, qw` | 4 × 32-bit vector shift; per-lane signed amount from `qw` | + +Operation for `ESP.VSLD.16 qu, qy, qw` (8 lanes of 16 bits; each lane's shift amount is the low 5 bits of the corresponding 16-bit segment of `qw`, treated as signed): + +``` +for i in 0..7: + lane_hi = 16*i + 15 + lane_lo = 16*i + shamt = qw[16*i+4 : 16*i] # signed 5-bit field + qu[lane_hi:lane_lo] = (shamt < 0) + ? (qy[lane_hi:lane_lo] >> -shamt) + : (qy[lane_hi:lane_lo] << shamt) +``` + +`ESP.VSLD.8`/`.32` and `ESP.VSRD.8/16/32` follow the same per-lane, sign-selects-direction pattern, just with the shift-amount field width and stride matched to the 8-bit/32-bit lane size instead of 16-bit. + +### Spliced Shift Instructions (for misalignment handling) + +These combine two QR registers with a byte-level shift. + +| Instruction | Description | +|-------------|-------------| +| `ESP.SRC.Q qz, qx, qy` | `qz = (qy \|\| qx) >> SAR_BYTE*8`, keep 128 bits | +| `ESP.SRC.Q.qup qz, qw, qy` | `qz = (qy \|\| qw) >> SAR_BYTE*8` AND `qw = qy` (auto-update qw for pipelined unaligned loads) | +| `ESP.SRC.Q.LD.IP qu, rs, imm, qx, qy` | SRC.Q + load 16 bytes to qu, rs += imm | +| `ESP.SRC.Q.LD.XP qu, rs1, rs2, qx, qy` | SRC.Q + load 16 bytes to qu, rs1 += rs2 | +| `ESP.SLCI.2Q qz, qx, imm` | Concatenate two QR and left shift by immediate | +| `ESP.SLCXXP.2Q qz, qx, qy` | Concatenate two QR and left shift (amount from QR) | +| `ESP.SRCI.2Q qz, qx, imm` | Concatenate two QR and right shift by immediate | +| `ESP.SRCXXP.2Q qz, qx, qy` | Concatenate two QR and right shift (amount from QR) | +| `ESP.SRCQ.128.ST.INCP qz, rs, qx, qy` | SRC.Q + store qz to memory (rs += 16) | + +--- + +## FFT Dedicated Instructions + +### Radix-2 Butterfly + +| Instruction | Description | +|-------------|-------------| +| `ESP.FFT.R2BF.S16 qz, qx, qy` | 4 × S16 radix-2 butterfly on 8 elements | +| `ESP.FFT.R2BF.S16.ST.INCP qz, qx, qy, rs` | Butterfly + store (rs += 16) | + +### Complex Multiplication for FFT + +| Instruction | Description | +|-------------|-------------| +| `ESP.FFT.CMUL.S16.LD.XP qz, qx, qy, rs` | Complex multiply + load (rs += rs2) | +| `ESP.FFT.CMUL.S16.ST.XP qz, qx, qy, rs` | Complex multiply + store (rs += rs2) | + +### Bit-Reverse + +| Instruction | Description | +|-------------|-------------| +| `ESP.BITREV rs1, rs2` | Bit-reverse rs2 (3–10 bits controlled by FFT_BIT_WIDTH), result in rs1 | + +### Real FFT Operations + +| Instruction | Description | +|-------------|-------------| +| `ESP.FFT.AMS.S16.LD.INCP.UAUP qu, rs, qx, qy` | Real FFT: multiply-subtract, load with unaligned update | +| `ESP.FFT.AMS.S16.LD.INCP qu, rs, qx, qy` | Real FFT: multiply-subtract + load | +| `ESP.FFT.AMS.S16.LD.R32.DECP qu, rs, qx, qy` | Real FFT: multiply-subtract, load 32-bit, decrement pointer | +| `ESP.FFT.AMS.S16.ST.INCP qu, rs, qx, qy` | Real FFT: multiply-subtract + store | +| `ESP.FFT.VST.R32.DECP qu, rs` | Store 32-bit real and decrement pointer | + +### FFT Multiply-Subtract Pattern + +The AMS instructions perform: `result = qx * qy - qx_shifted * qy_shifted` used in real FFT computation to extract the real spectrum from complex FFT output. + +--- + +## Instruction Summary by Operand Types + +| Operand Convention | Meaning | +|--------------------|---------| +| `qw`, `qx`, `qy`, `qz`, `qu`, `qv` | 128-bit QR vector registers (q0–q7) | +| `rd`, `rs`, `rs0`, `rs1`, `rs2` | 32-bit AR general-purpose registers | +| `imm` | Signed immediate offset | +| `sel4` | 2-bit element selector (0–3) for 32-bit elements | +| `sel8` | 3-bit element selector (0–7) for 16-bit elements | +| `sel16` | 4-bit element selector (0–15) for 8-bit elements | + +### Naming Convention in Syntax + +- **Input operands**: `qx`, `qy`, `qw` (read-only) +- **Output/destination operands**: `qz`, `qv` (write-only, or read-modify-write for MAC) +- **Load destination**: `qu` (used in fused load+compute instructions) +- **Address register**: `rs1`, `rs` (AR register holding memory address) +- **General AR**: `rd`, `rs2` or `rs0`/`rs1` for scalar operands diff --git a/cpu-docs/espressif-software/esptool_boot-mode-selection_esp32p4_v5.3.1.html b/cpu-docs/espressif-software/esptool_boot-mode-selection_esp32p4_v5.3.1.html new file mode 100644 index 0000000..d360fb7 --- /dev/null +++ b/cpu-docs/espressif-software/esptool_boot-mode-selection_esp32p4_v5.3.1.html @@ -0,0 +1,358 @@ +<!DOCTYPE html> +<html class="writer-html5" lang="en"> +<head> + <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /> + + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Boot Mode Selection - ESP32-P4 - — esptool latest documentation</title> + <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=03e43079" /> + <link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=a60756f2" /> + <link rel="stylesheet" type="text/css" href="../_static/theme_overrides.css?v=851bd809" /> + + + <!--[if lt IE 9]> + <script src="../_static/js/html5shiv.min.js"></script> + <![endif]--> + + <script src="../_static/jquery.js?v=5d32c60e"></script> + <script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> + <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js?v=becddca3"></script> + <script src="../_static/doctools.js?v=888ff710"></script> + <script src="../_static/sphinx_highlight.js?v=4825356b"></script> + <script src="../_static/js/theme.js"></script> + + + + + <script type="text/javascript"> + DOCUMENTATION_OPTIONS.PAGENAME = 'advanced-topics/boot-mode-selection'; + DOCUMENTATION_OPTIONS.PROJECT_SLUG = 'esptool'; + DOCUMENTATION_OPTIONS.LATEST_BRANCH_NAME = 'master'; + DOCUMENTATION_OPTIONS.VERSIONS_URL = '.././_static/esptool_versions.js'; + DOCUMENTATION_OPTIONS.LANGUAGES = ["en"]; + DOCUMENTATION_OPTIONS.IDF_TARGET = 'esp32p4'; + DOCUMENTATION_OPTIONS.HAS_IDF_TARGETS = ["esp8266", "esp32", "esp32s2", "esp32s3", "esp32c3", "esp32c2", "esp32c6", "esp32h2", "esp32h4", "esp32p4", "esp32c5", "esp32c61", "esp32h21", "esp32s31"] + DOCUMENTATION_OPTIONS.RELEASE = 'latest'; + DOCUMENTATION_OPTIONS.LANGUAGE_URL = 'en'; + + </script> + + <script type="text/javascript" src=".././_static/esptool_versions.js"></script> + <link rel="author" title="About these documents" href="../about.html" /> + <link rel="index" title="Index" href="../genindex.html" /> + <link rel="search" title="Search" href="../search.html" /> + <link rel="next" title="Troubleshooting" href="../troubleshooting.html" /> + <link rel="prev" title="SPI Flash Modes" href="spi-flash-modes.html" /> +</head> + +<body class="wy-body-for-nav"> + <div class="wy-grid-for-nav"> + <nav data-toggle="wy-nav-shift" class="wy-nav-side"> + <div class="wy-side-scroll"> + <div class="wy-side-nav-search" > + + + + <a href="../index.html" class="icon icon-home"> + esptool + <img src="../_static/espressif-logo.svg" class="logo" alt="Logo"/> + </a> + + + <div class="selectors"> + <select id="target-select" style="width: 150px;" hidden> + <option value="" disabled selected>Choose target...</option> + </select> + </div> + + + <div class="selectors"> + <select id="version-select" style="width: 150px;" hidden> + <option value="" disabled selected>Choose version...</option> + </select> + </div> + + +<div role="search"> + <form id="rtd-search-form" class="wy-form" action="../search.html" method="get"> + <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> +</div> + </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> + <ul class="current"> +<li class="toctree-l1"><a class="reference internal" href="../installation.html">Installation</a></li> +<li class="toctree-l1"><a class="reference internal" href="../esptool/index.html">Esptool</a></li> +<li class="toctree-l1"><a class="reference internal" href="../espefuse/index.html">Espefuse</a></li> +<li class="toctree-l1"><a class="reference internal" href="../espsecure/index.html">Espsecure</a></li> +<li class="toctree-l1"><a class="reference internal" href="../remote-serial-ports.html">Remote Serial Ports</a></li> +<li class="toctree-l1 current"><a class="reference internal" href="index.html">Advanced Topics</a><ul class="current"> +<li class="toctree-l2"><a class="reference internal" href="firmware-image-format.html">Firmware Image Format</a></li> +<li class="toctree-l2"><a class="reference internal" href="serial-protocol.html">Serial Protocol</a></li> +<li class="toctree-l2"><a class="reference internal" href="spi-flash-modes.html">SPI Flash Modes</a></li> +<li class="toctree-l2 current"><a class="current reference internal" href="#">Boot Mode Selection</a><ul> +<li class="toctree-l3"><a class="reference internal" href="#select-bootloader-mode">Select Bootloader Mode</a><ul> +<li class="toctree-l4"><a class="reference internal" href="#gpio35">GPIO35</a></li> +<li class="toctree-l4"><a class="reference internal" href="#gpio36">GPIO36</a></li> +<li class="toctree-l4"><a class="reference internal" href="#other-pins">Other Pins</a></li> +</ul> +</li> +<li class="toctree-l3"><a class="reference internal" href="#automatic-bootloader">Automatic Bootloader</a></li> +<li class="toctree-l3"><a class="reference internal" href="#manual-bootloader">Manual Bootloader</a></li> +<li class="toctree-l3"><a class="reference internal" href="#boot-log">Boot Log</a><ul> +<li class="toctree-l4"><a class="reference internal" href="#boot-mode-message">Boot Mode Message</a></li> +<li class="toctree-l4"><a class="reference internal" href="#later-boot-messages">Later Boot Messages</a></li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +<li class="toctree-l1"><a class="reference internal" href="../troubleshooting.html">Troubleshooting</a></li> +<li class="toctree-l1"><a class="reference internal" href="../contributing.html">Contribute</a></li> +<li class="toctree-l1"><a class="reference internal" href="../versions.html">Versions</a></li> +<li class="toctree-l1"><a class="reference internal" href="../migration-guide.html">Migration Guide</a></li> +<li class="toctree-l1"><a class="reference internal" href="../resources.html">Resources</a></li> +<li class="toctree-l1"><a class="reference internal" href="../about.html">About</a></li> +</ul> + + </div> + </div> + </nav> + + <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > + <i data-toggle="wy-nav-top" class="fa fa-bars"></i> + <a href="../index.html">esptool</a> + </nav> + + <div class="wy-nav-content"> + <div class="rst-content"> + <div role="navigation" aria-label="Page navigation"> + <ul class="wy-breadcrumbs"> + <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li> + <li class="breadcrumb-item"><a href="index.html">Advanced Topics</a></li> + <li class="breadcrumb-item active">Boot Mode Selection</li> + <li class="wy-breadcrumbs-aside"> + <a href="https://github.com/espressif/esptool/blob/90e9560f/docs/en/advanced-topics/boot-mode-selection.rst" class="fa fa-github"> Edit on GitHub</a> + </li> + </ul> + <hr/> +</div> + <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> + <div itemprop="articleBody"> + + <section id="boot-mode-selection"> +<span id="boot-mode"></span><h1>Boot Mode Selection<a class="headerlink" href="#boot-mode-selection" title="Permalink to this heading"></a></h1> +<p>This guide explains how to select the boot mode correctly and describes the boot log messages of ESP32-P4.</p> +<div class="admonition warning"> +<p class="admonition-title">Warning</p> +<p>The ESP32-P4 has a 45k ohm internal pull-up/pull-down resistor at GPIO35 (and other pins). If you want to connect a switch button to enter the boot mode, this has to be a strong pull-down. For example a 10k resistor to GND.</p> +</div> +<p>Information about ESP32-P4 strapping pins can also be found in the <a class="reference external" href="https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf">ESP32-P4 Datasheet</a>, section “Strapping Pins”.</p> +<p>On many development boards with built-in USB/Serial, <code class="docutils literal notranslate"><span class="pre">esptool</span></code> can automatically reset the board into bootloader mode. For other configurations or custom hardware, you will need to check the orientation of some “strapping pins” to get the correct boot mode:</p> +<section id="select-bootloader-mode"> +<h2>Select Bootloader Mode<a class="headerlink" href="#select-bootloader-mode" title="Permalink to this heading"></a></h2> +<section id="gpio35"> +<h3>GPIO35<a class="headerlink" href="#gpio35" title="Permalink to this heading"></a></h3> +<p>The ESP32-P4 will enter the serial bootloader when GPIO35 is held low on reset. Otherwise it will run the program in flash.</p> +<table class="docutils align-default"> +<colgroup> +<col style="width: 28.6%" /> +<col style="width: 71.4%" /> +</colgroup> +<thead> +<tr class="row-odd"><th class="head"><p>GPIO35 Input</p></th> +<th class="head"><p>Mode</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>Low/GND</p></td> +<td><p>ROM serial bootloader for esptool</p></td> +</tr> +<tr class="row-odd"><td><p>High/VCC</p></td> +<td><p>Normal execution mode</p></td> +</tr> +</tbody> +</table> +<p>GPIO35 has an internal pullup resistor, so if it is left unconnected then it will pull high.</p> +<p>Many boards use a button marked “Flash” (or “BOOT” on some Espressif development boards) that pulls GPIO35 low when pressed.</p> +</section> +<section id="gpio36"> +<h3>GPIO36<a class="headerlink" href="#gpio36" title="Permalink to this heading"></a></h3> +<p>GPIO36 must also be driven High, in order to enter the serial bootloader reliably. The strapping combination of GPIO36 = 0 and GPIO35 = 0 is invalid and will trigger unexpected behavior.</p> +<p>In normal boot mode (GPIO35 high), GPIO36 is ignored.</p> +</section> +<section id="other-pins"> +<h3>Other Pins<a class="headerlink" href="#other-pins" title="Permalink to this heading"></a></h3> +<p>As well as the above mentioned pins, other ones influence the serial bootloader, please consult the <a class="reference external" href="https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf">ESP32-P4 Datasheet</a>, section “Strapping Pins”.</p> +</section> +</section> +<section id="automatic-bootloader"> +<span id="id1"></span><h2>Automatic Bootloader<a class="headerlink" href="#automatic-bootloader" title="Permalink to this heading"></a></h2> +<p><code class="docutils literal notranslate"><span class="pre">esptool</span></code> resets ESP32-P4 automatically by asserting <code class="docutils literal notranslate"><span class="pre">DTR</span></code> and <code class="docutils literal notranslate"><span class="pre">RTS</span></code> control lines of the USB to serial converter chip, i.e., FTDI, CP210x, or CH340x. The <code class="docutils literal notranslate"><span class="pre">DTR</span></code> and <code class="docutils literal notranslate"><span class="pre">RTS</span></code> control lines are in turn connected to <code class="docutils literal notranslate"><span class="pre">GPIO35</span></code> and <code class="docutils literal notranslate"><span class="pre">EN</span></code> (<code class="docutils literal notranslate"><span class="pre">CHIP_PU</span></code>) pins of ESP32-P4, thus changes in the voltage levels of <code class="docutils literal notranslate"><span class="pre">DTR</span></code> and <code class="docutils literal notranslate"><span class="pre">RTS</span></code> will boot the ESP32-P4 into Firmware Download mode.</p> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>When developing <code class="docutils literal notranslate"><span class="pre">esptool</span></code>, keep in mind <code class="docutils literal notranslate"><span class="pre">DTR</span></code> and <code class="docutils literal notranslate"><span class="pre">RTS</span></code> are active low signals, i.e., <code class="docutils literal notranslate"><span class="pre">True</span></code> = pin @ 0V, <code class="docutils literal notranslate"><span class="pre">False</span></code> = pin @ VCC.</p> +</div> +<p>As an example of auto-reset curcuitry implementation, check the <a class="reference external" href="https://dl.espressif.com/dl/schematics/esp32_devkitc_v4-sch-20180607a.pdf">schematic</a> of the ESP32 DevKitC development board:</p> +<ul class="simple"> +<li><p>The <strong>Micro USB 5V & USB-UART</strong> section shows the <code class="docutils literal notranslate"><span class="pre">DTR</span></code> and <code class="docutils literal notranslate"><span class="pre">RTS</span></code> control lines of the USB to serial converter chip connected to <code class="docutils literal notranslate"><span class="pre">GPIO35</span></code> and <code class="docutils literal notranslate"><span class="pre">EN</span></code> pins of the ESP module.</p></li> +<li><p>Some OS and/or drivers may activate <code class="docutils literal notranslate"><span class="pre">RTS</span></code> and or <code class="docutils literal notranslate"><span class="pre">DTR</span></code> automatically when opening the serial port (true only for some serial terminal programs, not <code class="docutils literal notranslate"><span class="pre">esptool</span></code>), pulling them low together and holding the ESP in reset. If <code class="docutils literal notranslate"><span class="pre">RTS</span></code> is wired directly to <code class="docutils literal notranslate"><span class="pre">EN</span></code> then RTS/CTS “hardware flow control” needs to be disabled in the serial program to avoid this. +An additional circuitry is implemented in order to avoid this problem - if both <code class="docutils literal notranslate"><span class="pre">RTS</span></code> and <code class="docutils literal notranslate"><span class="pre">DTR</span></code> are asserted together, this doesn’t reset the chip. The schematic shows this specific circuit with two transistors and its truth table.</p></li> +<li><p>If this circuitry is implemented (all Espressif boards have it), adding a capacitor between the <code class="docutils literal notranslate"><span class="pre">EN</span></code> pin and <code class="docutils literal notranslate"><span class="pre">GND</span></code> (in the 1uF-10uF range) is necessary for the reset circuitry to work reliably. This is shown in the <strong>ESP32 Module</strong> section of the schematic.</p></li> +<li><p>The <strong>Switch Button</strong> section shows buttons needed for <a class="reference internal" href="#manual-bootloader"><span class="std std-ref">manually switching to bootloader</span></a>.</p></li> +</ul> +<p>Make the following connections for <code class="docutils literal notranslate"><span class="pre">esptool</span></code> to automatically enter the bootloader of an ESP32-P4 chip:</p> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>ESP Pin</p></th> +<th class="head"><p>Serial Pin</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>EN</p></td> +<td><p>RTS</p></td> +</tr> +<tr class="row-odd"><td><p>GPIO35</p></td> +<td><p>DTR</p></td> +</tr> +</tbody> +</table> +<p>In Linux serial ports by default will assert RTS when nothing is attached to them. This can hold the ESP32-P4 in a reset loop which may cause some serial adapters to subsequently reset loop. This functionality can be disabled by disabling <code class="docutils literal notranslate"><span class="pre">HUPCL</span></code> (ie <code class="docutils literal notranslate"><span class="pre">sudo</span> <span class="pre">stty</span> <span class="pre">-F</span> <span class="pre">/dev/ttyUSB0</span> <span class="pre">-hupcl</span></code>).</p> +<p>(Some third party ESP32-P4 development boards use an automatic reset circuit for <code class="docutils literal notranslate"><span class="pre">EN</span></code> & <code class="docutils literal notranslate"><span class="pre">GPIO35</span></code> pins, but don’t add a capacitor on the <code class="docutils literal notranslate"><span class="pre">EN</span></code> pin. This results in unreliable automatic reset, especially on Windows. Adding a 1uF (or higher) value capacitor between <code class="docutils literal notranslate"><span class="pre">EN</span></code> pin and <code class="docutils literal notranslate"><span class="pre">GND</span></code> may make automatic reset more reliable.)</p> +<p>In general, you should have no problems with the official Espressif development boards. However, <code class="docutils literal notranslate"><span class="pre">esptool</span></code> is not able to reset your hardware automatically in the following cases:</p> +<ul class="simple"> +<li><p>Your hardware does not have the <code class="docutils literal notranslate"><span class="pre">DTR</span></code> and <code class="docutils literal notranslate"><span class="pre">RTS</span></code> lines connected to <code class="docutils literal notranslate"><span class="pre">GPIO35</span></code> and <code class="docutils literal notranslate"><span class="pre">EN</span></code> (<code class="docutils literal notranslate"><span class="pre">CHIP_PU</span></code>)</p></li> +<li><p>The <code class="docutils literal notranslate"><span class="pre">DTR</span></code> and <code class="docutils literal notranslate"><span class="pre">RTS</span></code> lines are configured differently</p></li> +<li><p>There are no such serial control lines at all</p></li> +</ul> +</section> +<section id="manual-bootloader"> +<span id="id2"></span><h2>Manual Bootloader<a class="headerlink" href="#manual-bootloader" title="Permalink to this heading"></a></h2> +<p>Depending on the kind of hardware you have, it may also be possible to manually put your ESP32-P4 board into Firmware Download mode (reset).</p> +<ul class="simple"> +<li><p>For development boards produced by Espressif, this information can be found in the respective getting started guides or user guides. For example, to manually reset a development board, hold down the <strong>Boot</strong> button (<code class="docutils literal notranslate"><span class="pre">GPIO35</span></code>) and press the <strong>EN</strong> button (<code class="docutils literal notranslate"><span class="pre">EN</span></code> (<code class="docutils literal notranslate"><span class="pre">CHIP_PU</span></code>)).</p></li> +<li><p>For other types of hardware, try pulling <code class="docutils literal notranslate"><span class="pre">GPIO35</span></code> down.</p></li> +</ul> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>If esptool is able to reset the chip but for some reason the chip is not entering into bootloader mode then hold down the Boot button (or pull down <code class="docutils literal notranslate"><span class="pre">GPIO35</span></code>) while you start esptool and keep it down during reset.</p> +</div> +</section> +<section id="boot-log"> +<h2>Boot Log<a class="headerlink" href="#boot-log" title="Permalink to this heading"></a></h2> +<section id="boot-mode-message"> +<h3>Boot Mode Message<a class="headerlink" href="#boot-mode-message" title="Permalink to this heading"></a></h3> +<p>After reset, the second line printed by the ESP32-P4 ROM (at 115200bps) is a reset & boot mode message:</p> +<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ets</span> <span class="n">Jun</span> <span class="mi">8</span> <span class="mi">2016</span> <span class="mi">00</span><span class="p">:</span><span class="mi">22</span><span class="p">:</span><span class="mi">57</span> +<span class="n">rst</span><span class="p">:</span><span class="mh">0x1</span> <span class="p">(</span><span class="n">POWERON_RESET</span><span class="p">),</span><span class="n">boot</span><span class="p">:</span><span class="mh">0x3</span> <span class="p">(</span><span class="n">DOWNLOAD_BOOT</span><span class="p">(</span><span class="n">UART0</span><span class="o">/</span><span class="n">UART1</span><span class="o">/</span><span class="n">SDIO_REI_REO_V2</span><span class="p">))</span> +</pre></div> +</div> +<p><code class="docutils literal notranslate"><span class="pre">rst:0xNN</span> <span class="pre">(REASON)</span></code> 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 <a class="reference external" href="https://github.com/espressif/esp-idf/blob/release/v5.2/components/esp_rom/include/esp32p4/rom/rtc.h">ESP-IDF source under RESET_REASON enum</a>. +The value can be read in ESP32-P4 code via the <a class="reference external" href="https://github.com/espressif/esp-idf/blob/release/v5.2/components/esp_rom/include/esp32p4/rom/rtc.h">get_reset_reason() ROM function</a>.</p> +<p><code class="docutils literal notranslate"><span class="pre">boot:0xNN</span> <span class="pre">(DESCRIPTION)</span></code> is the hex value of the strapping pins, as represented in the <a class="reference external" href="https://github.com/espressif/esp-idf/blob/release/v5.2/components/soc/esp32p4/include/soc/gpio_reg.h">GPIO_STRAP register</a>.</p> +<p>The individual bit values are as follows:</p> +<ul class="simple"> +<li><p><code class="docutils literal notranslate"><span class="pre">0x04</span></code> - GPIO36</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">0x08</span></code> - GPIO35</p></li> +</ul> +<p>If the pin was high on reset, the bit value will be set. If it was low on reset, the bit will be cleared.</p> +<p>A number of boot mode strings can be shown depending on which bits are set:</p> +<ul class="simple"> +<li><p><code class="docutils literal notranslate"><span class="pre">DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2)</span></code> or <code class="docutils literal notranslate"><span class="pre">DOWNLOAD(USB/UART0)</span></code> - ESP32-P4 is in download flashing mode (suitable for esptool)</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">SPI_FAST_FLASH_BOOT</span></code> - This is the normal SPI flash boot mode.</p></li> +<li><p>Other modes (including <code class="docutils literal notranslate"><span class="pre">SPI_FLASH_BOOT</span></code>, <code class="docutils literal notranslate"><span class="pre">SDIO_REI_FEO_V1_BOOT</span></code>, <code class="docutils literal notranslate"><span class="pre">ATE_BOOT</span></code>) 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 GPIO36 has been pulled high when GPIO35 is low).</p></li> +</ul> +</section> +<section id="later-boot-messages"> +<h3>Later Boot Messages<a class="headerlink" href="#later-boot-messages" title="Permalink to this heading"></a></h3> +<p>Later output from the ROM bootloader depends on the strapping pins and +the boot mode. Some common output includes:</p> +<section id="early-flash-read-error"> +<h4>Early Flash Read Error<a class="headerlink" href="#early-flash-read-error" title="Permalink to this heading"></a></h4> +<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Invalid</span> <span class="n">header</span> <span class="o"><</span><span class="n">value</span> <span class="n">at</span> <span class="mh">0x2000</span><span class="o">></span> +</pre></div> +</div> +<p>This fatal error indicates that the bootloader tried to read the software bootloader header at address 0x2000 but failed to read valid data. Possible reasons for this include:</p> +<p><ul class="simple"> +<li><p>There isn’t actually a bootloader at offset 0x2000 (maybe the bootloader was flashed to the wrong offset by mistake, or the flash has been erased and no bootloader has been flashed yet.)</p></li> +<li><p>Physical problem with the connection to the flash chip, or flash chip power.</p></li> +<li><p>Flash encryption is enabled but the bootloader is plaintext. Alternatively, flash encryption is disabled but the bootloader is encrypted ciphertext.</p></li> +</ul> +</p> +</section> +<section id="software-bootloader-header-info"> +<h4>Software Bootloader Header Info<a class="headerlink" href="#software-bootloader-header-info" title="Permalink to this heading"></a></h4> +<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">SPIWP</span><span class="p">:</span><span class="mh">0xee</span> +<span class="n">mode</span><span class="p">:</span><span class="n">DIO</span><span class="p">,</span> <span class="n">clock</span> <span class="n">div</span><span class="p">:</span><span class="mi">1</span> +</pre></div> +</div> +<p>This is normal boot output based on a combination of eFuse values and information read from the bootloader header at flash offset 0x2000:</p> +<p><ul class="simple"> +<li><p><code class="docutils literal notranslate"><span class="pre">SPIWP:0xNN</span></code> indicates a custom <code class="docutils literal notranslate"><span class="pre">WP</span></code> 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 <code class="docutils literal notranslate"><span class="pre">configsip</span></code> value). +All custom pin values but WP are encoded in the configsip byte loaded from eFuse, and WP is supplied in the bootloader header.</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">mode:</span> <span class="pre">AAA,</span> <span class="pre">clock</span> <span class="pre">div:</span> <span class="pre">N</span></code>. SPI flash access mode. Read from the bootloader header, correspond to the <code class="docutils literal notranslate"><span class="pre">--flash-mode</span></code> and <code class="docutils literal notranslate"><span class="pre">--flash-freq</span></code> arguments supplied to <code class="docutils literal notranslate"><span class="pre">esptool</span> <span class="pre">write-flash</span></code> or <code class="docutils literal notranslate"><span class="pre">esptool</span> <span class="pre">elf2image</span></code>.</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">mode</span></code> can be DIO, DOUT, QIO, or QOUT. <em>QIO and QOUT are not supported here</em>, 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.</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">clock</span> <span class="pre">div:</span> <span class="pre">N</span></code> is the SPI flash clock frequency divider. This is an integer clock divider value from an 80MHz APB clock, based on the supplied <code class="docutils literal notranslate"><span class="pre">--flash-freq</span></code> argument (ie 80MHz=1, 40MHz=2, etc). +The ROM bootloader actually loads the software bootloader at a lower frequency than the <code class="docutils literal notranslate"><span class="pre">--flash-freq</span></code> 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.</p></li> +</ul> +</p> +</section> +<section id="software-bootloader-load-segments"> +<h4>Software Bootloader Load Segments<a class="headerlink" href="#software-bootloader-load-segments" title="Permalink to this heading"></a></h4> +<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">load</span><span class="p">:</span><span class="mh">0x3fff0008</span><span class="p">,</span><span class="nb">len</span><span class="p">:</span><span class="mi">8</span> +<span class="n">load</span><span class="p">:</span><span class="mh">0x3fff0010</span><span class="p">,</span><span class="nb">len</span><span class="p">:</span><span class="mi">3680</span> +<span class="n">load</span><span class="p">:</span><span class="mh">0x40078000</span><span class="p">,</span><span class="nb">len</span><span class="p">:</span><span class="mi">8364</span> +<span class="n">load</span><span class="p">:</span><span class="mh">0x40080000</span><span class="p">,</span><span class="nb">len</span><span class="p">:</span><span class="mi">252</span> +<span class="n">entry</span> <span class="mh">0x40080034</span> +</pre></div> +</div> +<p>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.</p> +<p>You can compare these values to the software bootloader image by running <code class="docutils literal notranslate"><span class="pre">esptool</span> <span class="pre">--chip</span> <span class="pre">esp32p4</span> <span class="pre">image-info</span> <span class="pre">/path/to/bootloader.bin</span></code> to dump image info including a summary of each segment. Corresponding details will also be found in the bootloader ELF file headers.</p> +<p>If there is a problem with the SPI flash chip addressing mode, the values printed by the bootloader here may be corrupted.</p> +<p>The final line shows the entry point address of the software bootloader, where the ROM bootloader will call as it hands over control.</p> +</section> +</section> +</section> +</section> + + + </div> + </div> + <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> + <a href="spi-flash-modes.html" class="btn btn-neutral float-left" title="SPI Flash Modes" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> + <a href="../troubleshooting.html" class="btn btn-neutral float-right" title="Troubleshooting" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> + </div> + + <hr/> + + <div role="contentinfo"> + <p>© Copyright 2016 - 2026, Espressif Systems (Shanghai) Co., Ltd.</p> + </div> + + <ul class="footer"> + <li> + + + Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/espressif/sphinx_idf_theme">theme</a> based on <a href="https://github.com/readthedocs/sphinx_rtd_theme">Read the Docs Sphinx Theme</a>. + </li> + + </ul> + +</footer> + </div> + </div> + </section> + </div> + + <script> + jQuery(function () { + SphinxRtdTheme.Navigation.enable(true); + }); + </script> + +</body> +</html>
\ No newline at end of file diff --git a/cpu-docs/espressif-software/esptool_boot-mode-selection_v5.3.1.rst b/cpu-docs/espressif-software/esptool_boot-mode-selection_v5.3.1.rst new file mode 100644 index 0000000..e514d53 --- /dev/null +++ b/cpu-docs/espressif-software/esptool_boot-mode-selection_v5.3.1.rst @@ -0,0 +1,373 @@ +{IDF_TARGET_STRAP_BOOT_GPIO:default="GPIO9", esp8266="GPIO0", esp32="GPIO0", esp32s2="GPIO0", esp32s3="GPIO0", esp32p4="GPIO35", esp32c5="GPIO28", esp32h21="GPIO14", esp32h4="GPIO14"} + +{IDF_TARGET_STRAP_BOOT_2_GPIO:default="GPIO8", esp32="GPIO2", esp32s2="GPIO46", esp32s3="GPIO46", esp32p4="GPIO36", esp32c5="GPIO27", esp32h21="GPIO13", esp32h4="GPIO13"} + +{IDF_TARGET_BOOTLOADER_OFFSET:default="0x0", esp32="0x1000", esp32s2="0x1000", esp32p4="0x2000", esp32c5="0x2000"} + +.. _boot-mode: + +Boot Mode Selection +=================== + +This guide explains how to select the boot mode correctly and describes the boot log messages of {IDF_TARGET_NAME}. + +.. only:: esp8266 + + On many development boards with built-in USB/Serial, this is done for you and ``esptool`` can automatically reset the board into bootloader mode. For other configurations, you will need to follow these steps: + + Required Pins + ------------- + + The following ESP8266 pins must be in a known state for either normal (flash boot) or serial bootloader operation. Most development boards or modules make necessary connections already, internally: + + +--------+--------------------------------------------------------------------------------------------------------------------+ + | GPIO | State | + +========+====================================================================================================================+ + | 15 | Pulled Low/GND (directly connected to GND, or external pull-down resistor) | + +--------+--------------------------------------------------------------------------------------------------------------------+ + | 2 | Pull-up resistor High/VCC, or No Connection (pin has internal weak pullup, external pullup resistor is optional) | + +--------+--------------------------------------------------------------------------------------------------------------------+ + + If these pins are set differently to shown, nothing on the ESP8266 will work as expected. See `ESP8266 Pin List document <https://www.espressif.com/en/support/documents/technical-documents?keys=ESP8266+Pin+List>`__ to see what boot modes are enabled for different pin combinations. + + When the ESP8266 goes into serial bootloader mode, the Boot ROM switches GPIO2 to an output and the UART TX signal is also output to this pin. For this reason GPIO2 should not be directly connected to VCC. Similarly, make sure GPIO2 is not connected to another peripheral where this may cause an issue when in download mode. + + Select Bootloader Mode + ---------------------- + + The ESP8266 will enter the serial bootloader when GPIO0 is held low on reset. Otherwise it will run the program in flash. + + +---------------+----------------------------------------+ + | GPIO0 Input | Mode | + +===============+========================================+ + | Low/GND | ROM serial bootloader for esptool | + +---------------+----------------------------------------+ + | High/VCC | Normal execution mode | + +---------------+----------------------------------------+ + + Many configurations use a "Flash" button that pulls GPIO0 low when pressed. + +.. only:: not esp8266 + + .. warning:: + + The {IDF_TARGET_NAME} has a 45k ohm internal pull-up/pull-down resistor at {IDF_TARGET_STRAP_BOOT_GPIO} (and other pins). If you want to connect a switch button to enter the boot mode, this has to be a strong pull-down. For example a 10k resistor to GND. + + Information about {IDF_TARGET_NAME} strapping pins can also be found in the `{IDF_TARGET_NAME} Datasheet <{IDF_TARGET_DATASHEET_EN_URL}>`__, section "Strapping Pins". + + On many development boards with built-in USB/Serial, ``esptool`` can automatically reset the board into bootloader mode. For other configurations or custom hardware, you will need to check the orientation of some "strapping pins" to get the correct boot mode: + + Select Bootloader Mode + ---------------------- + + {IDF_TARGET_STRAP_BOOT_GPIO} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + The {IDF_TARGET_NAME} will enter the serial bootloader when {IDF_TARGET_STRAP_BOOT_GPIO} is held low on reset. Otherwise it will run the program in flash. + + .. list-table:: + :widths: 10 25 + :header-rows: 1 + + * - {IDF_TARGET_STRAP_BOOT_GPIO} Input + - Mode + * - Low/GND + - ROM serial bootloader for esptool + * - High/VCC + - Normal execution mode + + {IDF_TARGET_STRAP_BOOT_GPIO} has an internal pullup resistor, so if it is left unconnected then it will pull high. + + Many boards use a button marked "Flash" (or "BOOT" on some Espressif development boards) that pulls {IDF_TARGET_STRAP_BOOT_GPIO} low when pressed. + + {IDF_TARGET_STRAP_BOOT_2_GPIO} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + .. 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 or esp32c2 or esp32h2 or esp32c6 or esp32p4 or esp32c5 or esp32c61 or esp32h21 or esp32h4 + + {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. + + In normal boot mode ({IDF_TARGET_STRAP_BOOT_GPIO} high), {IDF_TARGET_STRAP_BOOT_2_GPIO} is ignored. + + + Other Pins + ^^^^^^^^^^ + + .. only:: not esp32 + + As well as the above mentioned pins, other ones influence the serial bootloader, please consult the `{IDF_TARGET_NAME} Datasheet <{IDF_TARGET_DATASHEET_EN_URL}>`__, section "Strapping Pins". + + .. only:: esp32 + + As well as {IDF_TARGET_STRAP_BOOT_GPIO} and {IDF_TARGET_STRAP_BOOT_2_GPIO}, the following pins influence the serial bootloader mode: + + +-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + | GPIO | Meaning | + +=============+============================================================================================================================================================================================================================================================================================+ + | 12 (MTDI) | If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is used and this pin is pulled high, causing the flash to brownout. See the datasheet for more details. | + +-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + | 15 (MTDO) | If driven Low, silences boot messages printed by the ROM bootloader. Has an internal pull-up, so unconnected = High = normal output. | + +-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + For more information, consult the `{IDF_TARGET_NAME} Datasheet <{IDF_TARGET_DATASHEET_EN_URL}>`__, section "Strapping Pins". + +.. _automatic-bootloader: + +Automatic Bootloader +-------------------- + +``esptool`` resets {IDF_TARGET_NAME} automatically by asserting ``DTR`` and ``RTS`` control lines of the USB to serial converter chip, i.e., FTDI, CP210x, or CH340x. The ``DTR`` and ``RTS`` control lines are in turn connected to ``{IDF_TARGET_STRAP_BOOT_GPIO}`` and ``EN`` (``CHIP_PU``) pins of {IDF_TARGET_NAME}, thus changes in the voltage levels of ``DTR`` and ``RTS`` will boot the {IDF_TARGET_NAME} into Firmware Download mode. + +.. note:: + + When developing ``esptool``, keep in mind ``DTR`` and ``RTS`` are active low signals, i.e., ``True`` = pin @ 0V, ``False`` = pin @ VCC. + +As an example of auto-reset curcuitry implementation, check the `schematic <https://dl.espressif.com/dl/schematics/esp32_devkitc_v4-sch-20180607a.pdf>`_ of the ESP32 DevKitC development board: + +- The **Micro USB 5V & USB-UART** section shows the ``DTR`` and ``RTS`` control lines of the USB to serial converter chip connected to ``{IDF_TARGET_STRAP_BOOT_GPIO}`` and ``EN`` pins of the ESP module. +- Some OS and/or drivers may activate ``RTS`` and or ``DTR`` automatically when opening the serial port (true only for some serial terminal programs, not ``esptool``), pulling them low together and holding the ESP in reset. If ``RTS`` is wired directly to ``EN`` then RTS/CTS "hardware flow control" needs to be disabled in the serial program to avoid this. + An additional circuitry is implemented in order to avoid this problem - if both ``RTS`` and ``DTR`` are asserted together, this doesn't reset the chip. The schematic shows this specific circuit with two transistors and its truth table. +- If this circuitry is implemented (all Espressif boards have it), adding a capacitor between the ``EN`` pin and ``GND`` (in the 1uF-10uF range) is necessary for the reset circuitry to work reliably. This is shown in the **ESP32 Module** section of the schematic. +- The **Switch Button** section shows buttons needed for :ref:`manually switching to bootloader <manual-bootloader>`. + +Make the following connections for ``esptool`` to automatically enter the bootloader of an {IDF_TARGET_NAME} chip: + +.. list-table:: + :header-rows: 1 + + * - ESP Pin + - Serial Pin + * - EN + - RTS + * - {IDF_TARGET_STRAP_BOOT_GPIO} + - DTR + +In Linux serial ports by default will assert RTS when nothing is attached to them. This can hold the {IDF_TARGET_NAME} in a reset loop which may cause some serial adapters to subsequently reset loop. This functionality can be disabled by disabling ``HUPCL`` (ie ``sudo stty -F /dev/ttyUSB0 -hupcl``). + +(Some third party {IDF_TARGET_NAME} development boards use an automatic reset circuit for ``EN`` & ``{IDF_TARGET_STRAP_BOOT_GPIO}`` pins, but don't add a capacitor on the ``EN`` pin. This results in unreliable automatic reset, especially on Windows. Adding a 1uF (or higher) value capacitor between ``EN`` pin and ``GND`` may make automatic reset more reliable.) + +In general, you should have no problems with the official Espressif development boards. However, ``esptool`` is not able to reset your hardware automatically in the following cases: + +- Your hardware does not have the ``DTR`` and ``RTS`` lines connected to ``{IDF_TARGET_STRAP_BOOT_GPIO}`` and ``EN`` (``CHIP_PU``) +- The ``DTR`` and ``RTS`` lines are configured differently +- There are no such serial control lines at all + +.. _manual-bootloader: + +Manual Bootloader +----------------- + +Depending on the kind of hardware you have, it may also be possible to manually put your {IDF_TARGET_NAME} board into Firmware Download mode (reset). + +- For development boards produced by Espressif, this information can be found in the respective getting started guides or user guides. For example, to manually reset a development board, hold down the **Boot** button (``{IDF_TARGET_STRAP_BOOT_GPIO}``) and press the **EN** button (``EN`` (``CHIP_PU``)). +- For other types of hardware, try pulling ``{IDF_TARGET_STRAP_BOOT_GPIO}`` down. + +.. note:: + + If esptool is able to reset the chip but for some reason the chip is not entering into bootloader mode then hold down the Boot button (or pull down ``{IDF_TARGET_STRAP_BOOT_GPIO}``) while you start esptool and keep it down during reset. + +.. only:: esp8266 + + .. _boot-log-esp8266: + + Boot Log + -------- + + The ESP8266 boot rom writes a log to the UART when booting. The timing is a little bit unusual: ``74880 baud`` (see :ref:`serial-port-settings`). + + :: + + ets Jan 8 2014,rst cause 1, boot mode:(3,7) + + load 0x40100000, len 24236, room 16 + tail 12 + chksum 0xb7 + ho 0 tail 12 room 4 + load 0x3ffe8000, len 3008, room 12 + tail 4 + chksum 0x2c + load 0x3ffe8bc0, len 4816, room 4 + tail 12 + chksum 0x46 + csum 0x46 + + + Explanation + ^^^^^^^^^^^ + + **rst_cause:** + + +---------------+----------------------------------------+ + | Value | Meaning | + +===============+========================================+ + | 1 | power-on | + +---------------+----------------------------------------+ + | 2 | external-reset | + +---------------+----------------------------------------+ + | 4 | hardware watchdog-reset | + +---------------+----------------------------------------+ + + + **The first parameter of boot_mode:** + + +-------------------------+----------------------------------------------+ + | Value | Meaning | + +=========================+==============================================+ + | 1 (eg. boot mode:(1,x)) | UART download mode (download FW into Flash) | + +-------------------------+----------------------------------------------+ + | 2 (eg. boot mode:(3,x)) | Boot from flash mode | + +-------------------------+----------------------------------------------+ + + **chksum:** + + If value of "chksum" == value of "csum", it means flash has been read correctly during booting. + + The rest of boot messages are used internally by Espressif. + +.. only:: not esp8266 + + Boot Log + -------- + + 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 under RESET_REASON enum <https://github.com/espressif/esp-idf/blob/release/v5.2/components/esp_rom/include/{IDF_TARGET_PATH_NAME}/rom/rtc.h>`__. + The value can be read in {IDF_TARGET_NAME} code via the `get_reset_reason() ROM function <https://github.com/espressif/esp-idf/blob/release/v5.2/components/esp_rom/include/{IDF_TARGET_PATH_NAME}/rom/rtc.h>`__. + + ``boot:0xNN (DESCRIPTION)`` is the hex value of the strapping pins, as represented in the `GPIO_STRAP register <https://github.com/espressif/esp-idf/blob/release/v5.2/components/soc/{IDF_TARGET_PATH_NAME}/include/soc/gpio_reg.h>`__. + + The individual bit values are as follows: + + .. 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)`` 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 ``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:: + + ``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 + ^^^^^^^^^^^^^^^^^^^ + + Later output from the ROM bootloader depends on the strapping pins and + the boot mode. Some common output includes: + + Early Flash Read Error + """""""""""""""""""""" + + .. only:: esp8266 + + :: + + flash read err, 0 + + .. only:: not esp8266 + + :: + + Invalid header <value at {IDF_TARGET_BOOTLOADER_OFFSET}> + + This fatal error indicates that the bootloader tried to read the software bootloader header at address {IDF_TARGET_BOOTLOADER_OFFSET} but failed to read valid data. Possible reasons for this include: + + .. list:: + + - There isn't actually a bootloader at offset {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. + + :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. + + + 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 {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 <espefuse>` 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. + :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 write-flash`` or ``esptool 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 + """"""""""""""""""""""""""""""""" + + :: + + load:0x3fff0008,len:8 + load:0x3fff0010,len:3680 + load:0x40078000,len:8364 + load:0x40080000,len:252 + entry 0x40080034 + + 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 --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. + + The final line shows the entry point address of the software bootloader, where the ROM bootloader will call as it hands over control. diff --git a/cpu-docs/espressif-software/esptool_firmware-image-format_esp32p4_v5.3.1.html b/cpu-docs/espressif-software/esptool_firmware-image-format_esp32p4_v5.3.1.html new file mode 100644 index 0000000..1405b83 --- /dev/null +++ b/cpu-docs/espressif-software/esptool_firmware-image-format_esp32p4_v5.3.1.html @@ -0,0 +1,299 @@ +<!DOCTYPE html> +<html class="writer-html5" lang="en"> +<head> + <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /> + + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Firmware Image Format - ESP32-P4 - — esptool latest documentation</title> + <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=03e43079" /> + <link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=a60756f2" /> + <link rel="stylesheet" type="text/css" href="../_static/theme_overrides.css?v=851bd809" /> + + + <!--[if lt IE 9]> + <script src="../_static/js/html5shiv.min.js"></script> + <![endif]--> + + <script src="../_static/jquery.js?v=5d32c60e"></script> + <script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> + <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js?v=becddca3"></script> + <script src="../_static/doctools.js?v=888ff710"></script> + <script src="../_static/sphinx_highlight.js?v=4825356b"></script> + <script src="../_static/js/theme.js"></script> + + + + + <script type="text/javascript"> + DOCUMENTATION_OPTIONS.PAGENAME = 'advanced-topics/firmware-image-format'; + DOCUMENTATION_OPTIONS.PROJECT_SLUG = 'esptool'; + DOCUMENTATION_OPTIONS.LATEST_BRANCH_NAME = 'master'; + DOCUMENTATION_OPTIONS.VERSIONS_URL = '.././_static/esptool_versions.js'; + DOCUMENTATION_OPTIONS.LANGUAGES = ["en"]; + DOCUMENTATION_OPTIONS.IDF_TARGET = 'esp32p4'; + DOCUMENTATION_OPTIONS.HAS_IDF_TARGETS = ["esp8266", "esp32", "esp32s2", "esp32s3", "esp32c3", "esp32c2", "esp32c6", "esp32h2", "esp32h4", "esp32p4", "esp32c5", "esp32c61", "esp32h21", "esp32s31"] + DOCUMENTATION_OPTIONS.RELEASE = 'latest'; + DOCUMENTATION_OPTIONS.LANGUAGE_URL = 'en'; + + </script> + + <script type="text/javascript" src=".././_static/esptool_versions.js"></script> + <link rel="author" title="About these documents" href="../about.html" /> + <link rel="index" title="Index" href="../genindex.html" /> + <link rel="search" title="Search" href="../search.html" /> + <link rel="next" title="Serial Protocol" href="serial-protocol.html" /> + <link rel="prev" title="Advanced Topics" href="index.html" /> +</head> + +<body class="wy-body-for-nav"> + <div class="wy-grid-for-nav"> + <nav data-toggle="wy-nav-shift" class="wy-nav-side"> + <div class="wy-side-scroll"> + <div class="wy-side-nav-search" > + + + + <a href="../index.html" class="icon icon-home"> + esptool + <img src="../_static/espressif-logo.svg" class="logo" alt="Logo"/> + </a> + + + <div class="selectors"> + <select id="target-select" style="width: 150px;" hidden> + <option value="" disabled selected>Choose target...</option> + </select> + </div> + + + <div class="selectors"> + <select id="version-select" style="width: 150px;" hidden> + <option value="" disabled selected>Choose version...</option> + </select> + </div> + + +<div role="search"> + <form id="rtd-search-form" class="wy-form" action="../search.html" method="get"> + <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> +</div> + </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> + <ul class="current"> +<li class="toctree-l1"><a class="reference internal" href="../installation.html">Installation</a></li> +<li class="toctree-l1"><a class="reference internal" href="../esptool/index.html">Esptool</a></li> +<li class="toctree-l1"><a class="reference internal" href="../espefuse/index.html">Espefuse</a></li> +<li class="toctree-l1"><a class="reference internal" href="../espsecure/index.html">Espsecure</a></li> +<li class="toctree-l1"><a class="reference internal" href="../remote-serial-ports.html">Remote Serial Ports</a></li> +<li class="toctree-l1 current"><a class="reference internal" href="index.html">Advanced Topics</a><ul class="current"> +<li class="toctree-l2 current"><a class="current reference internal" href="#">Firmware Image Format</a><ul> +<li class="toctree-l3"><a class="reference internal" href="#file-header">File Header</a></li> +<li class="toctree-l3"><a class="reference internal" href="#extended-file-header">Extended File Header</a></li> +<li class="toctree-l3"><a class="reference internal" href="#segment">Segment</a></li> +<li class="toctree-l3"><a class="reference internal" href="#footer">Footer</a></li> +<li class="toctree-l3"><a class="reference internal" href="#analyzing-a-binary-image">Analyzing a Binary Image</a></li> +</ul> +</li> +<li class="toctree-l2"><a class="reference internal" href="serial-protocol.html">Serial Protocol</a></li> +<li class="toctree-l2"><a class="reference internal" href="spi-flash-modes.html">SPI Flash Modes</a></li> +<li class="toctree-l2"><a class="reference internal" href="boot-mode-selection.html">Boot Mode Selection</a></li> +</ul> +</li> +<li class="toctree-l1"><a class="reference internal" href="../troubleshooting.html">Troubleshooting</a></li> +<li class="toctree-l1"><a class="reference internal" href="../contributing.html">Contribute</a></li> +<li class="toctree-l1"><a class="reference internal" href="../versions.html">Versions</a></li> +<li class="toctree-l1"><a class="reference internal" href="../migration-guide.html">Migration Guide</a></li> +<li class="toctree-l1"><a class="reference internal" href="../resources.html">Resources</a></li> +<li class="toctree-l1"><a class="reference internal" href="../about.html">About</a></li> +</ul> + + </div> + </div> + </nav> + + <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > + <i data-toggle="wy-nav-top" class="fa fa-bars"></i> + <a href="../index.html">esptool</a> + </nav> + + <div class="wy-nav-content"> + <div class="rst-content"> + <div role="navigation" aria-label="Page navigation"> + <ul class="wy-breadcrumbs"> + <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li> + <li class="breadcrumb-item"><a href="index.html">Advanced Topics</a></li> + <li class="breadcrumb-item active">Firmware Image Format</li> + <li class="wy-breadcrumbs-aside"> + <a href="https://github.com/espressif/esptool/blob/90e9560f/docs/en/advanced-topics/firmware-image-format.rst" class="fa fa-github"> Edit on GitHub</a> + </li> + </ul> + <hr/> +</div> + <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> + <div itemprop="articleBody"> + + <section id="firmware-image-format"> +<span id="image-format"></span><h1>Firmware Image Format<a class="headerlink" href="#firmware-image-format" title="Permalink to this heading"></a></h1> +<p>This is technical documentation for the firmware image format used by the ROM bootloader. These are the images created by <code class="docutils literal notranslate"><span class="pre">esptool</span> <span class="pre">elf2image</span></code>.</p> +<figure class="align-center" id="id1"> +<div><img height="320" src="../_images/packetdiag-42b115aba712a6574ed718ca9d74eb4fd1142025.png" width="928" /></div><figcaption> +<p><span class="caption-text">Firmware image format</span><a class="headerlink" href="#id1" title="Permalink to this image"></a></p> +</figcaption> +</figure> +<p>The firmware file consists of a header, an extended header, a variable number of data segments and a footer. Multi-byte fields are little-endian.</p> +<section id="file-header"> +<h2>File Header<a class="headerlink" href="#file-header" title="Permalink to this heading"></a></h2> +<figure class="align-center" id="id2"> +<div><img height="170" src="../_images/packetdiag-1f7336eac0eac9530b7dd0073def52e90038c424.png" width="928" /></div><figcaption> +<p><span class="caption-text">Firmware image header</span><a class="headerlink" href="#id2" title="Permalink to this image"></a></p> +</figcaption> +</figure> +<p>The image header is 8 bytes long:</p> +<table class="docutils align-default"> +<colgroup> +<col style="width: 15.0%" /> +<col style="width: 85.0%" /> +</colgroup> +<thead> +<tr class="row-odd"><th class="head"><p>Byte</p></th> +<th class="head"><p>Description</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>0</p></td> +<td><p>Magic number (always <code class="docutils literal notranslate"><span class="pre">0xE9</span></code>)</p></td> +</tr> +<tr class="row-odd"><td><p>1</p></td> +<td><p>Number of segments</p></td> +</tr> +<tr class="row-even"><td><p>2</p></td> +<td><p>SPI Flash Mode (<code class="docutils literal notranslate"><span class="pre">0</span></code> = QIO, <code class="docutils literal notranslate"><span class="pre">1</span></code> = QOUT, <code class="docutils literal notranslate"><span class="pre">2</span></code> = DIO, <code class="docutils literal notranslate"><span class="pre">3</span></code> = DOUT)</p></td> +</tr> +<tr class="row-odd"><td><p>3</p></td> +<td><p>High four bits - Flash size (<code class="docutils literal notranslate"><span class="pre">0</span></code> = 1MB, <code class="docutils literal notranslate"><span class="pre">1</span></code> = 2MB, <code class="docutils literal notranslate"><span class="pre">2</span></code> = 4MB, <code class="docutils literal notranslate"><span class="pre">3</span></code> = 8MB, <code class="docutils literal notranslate"><span class="pre">4</span></code> = 16MB, <code class="docutils literal notranslate"><span class="pre">5</span></code> = 32MB, <code class="docutils literal notranslate"><span class="pre">6</span></code> = 64MB)</p> +<p>Low four bits - Flash frequency (<code class="docutils literal notranslate"><span class="pre">0</span></code> = 40MHz, <code class="docutils literal notranslate"><span class="pre">1</span></code> = 26MHz, <code class="docutils literal notranslate"><span class="pre">2</span></code> = 20MHz, <code class="docutils literal notranslate"><span class="pre">0xf</span></code> = 80MHz)</p> +</td> +</tr> +<tr class="row-even"><td><p>4-7</p></td> +<td><p>Entry point address</p></td> +</tr> +</tbody> +</table> +<p><code class="docutils literal notranslate"><span class="pre">esptool</span></code> overrides the 2nd and 3rd (counted from 0) bytes according to the SPI flash info provided through the command line options (see <a class="reference internal" href="../esptool/flash-modes.html#flash-modes"><span class="std std-ref">Flash Modes</span></a>). +These bytes are only overridden if this is a bootloader image (an image written to a correct bootloader offset of 0x2000). +In this case, the appended SHA256 digest, which is a cryptographic hash used to verify the integrity of the image, is also updated to reflect the header changes. +Generating images without SHA256 digest can be achieved by running <code class="docutils literal notranslate"><span class="pre">esptool</span> <span class="pre">elf2image</span></code> with the <code class="docutils literal notranslate"><span class="pre">--dont-append-digest</span></code> argument.</p> +</section> +<section id="extended-file-header"> +<h2>Extended File Header<a class="headerlink" href="#extended-file-header" title="Permalink to this heading"></a></h2> +<figure class="align-center" id="id3"> +<div><img height="170" src="../_images/packetdiag-027e6c21fd476653802b64490edef0a0e57462d2.png" width="928" /></div><figcaption> +<p><span class="caption-text">Extended File Header</span><a class="headerlink" href="#id3" title="Permalink to this image"></a></p> +</figcaption> +</figure> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Byte</p></th> +<th class="head"><p>Description</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>0</p></td> +<td><p>WP pin when SPI pins set via eFuse (read by ROM bootloader)</p></td> +</tr> +<tr class="row-odd"><td><p>1-3</p></td> +<td><p>Drive settings for the SPI flash pins (read by ROM bootloader)</p></td> +</tr> +<tr class="row-even"><td><p>4-5</p></td> +<td><p>Chip ID (which ESP device is this image for)</p></td> +</tr> +<tr class="row-odd"><td><p>6</p></td> +<td><p>Minimal chip revision supported by the image (deprecated, use the following field)</p></td> +</tr> +<tr class="row-even"><td><p>7-8</p></td> +<td><p>Minimal chip revision supported by the image (in format: major * 100 + minor)</p></td> +</tr> +<tr class="row-odd"><td><p>9-10</p></td> +<td><p>Maximal chip revision supported by the image (in format: major * 100 + minor)</p></td> +</tr> +<tr class="row-even"><td><p>11-14</p></td> +<td><p>Reserved bytes in additional header space, currently unused</p></td> +</tr> +<tr class="row-odd"><td><p>15</p></td> +<td><p>Hash appended (If 1, SHA256 digest is appended after the checksum)</p></td> +</tr> +</tbody> +</table> +</section> +<section id="segment"> +<h2>Segment<a class="headerlink" href="#segment" title="Permalink to this heading"></a></h2> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Byte</p></th> +<th class="head"><p>Description</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>0-3</p></td> +<td><p>Memory offset</p></td> +</tr> +<tr class="row-odd"><td><p>4-7</p></td> +<td><p>Segment size</p></td> +</tr> +<tr class="row-even"><td><p>8…n</p></td> +<td><p>Data</p></td> +</tr> +</tbody> +</table> +</section> +<section id="footer"> +<h2>Footer<a class="headerlink" href="#footer" title="Permalink to this heading"></a></h2> +<p>The file is padded with zeros until its size is one byte less than a multiple of 16 bytes. A last byte (thus making the file size a multiple of 16) is the checksum of the data of all segments. The checksum is defined as the xor-sum of all bytes and the byte <code class="docutils literal notranslate"><span class="pre">0xEF</span></code>.</p> +<p>If <code class="docutils literal notranslate"><span class="pre">hash</span> <span class="pre">appended</span></code> in the extended file header is <code class="docutils literal notranslate"><span class="pre">0x01</span></code>, a SHA256 digest “simple hash” (of the entire image) is appended after the checksum. This digest is separate to secure boot and only used for detecting corruption. The SPI flash info cannot be changed during flashing if hash is appended after the image.</p> +<p>If secure boot is enabled, a signature is also appended (and the simple hash is included in the signed data). This image signature is <a class="reference external" href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/secure-boot-v1.html#image-signing-algorithm">Secure Boot V1</a> and <a class="reference external" href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/secure-boot-v2.html#signature-block-format">Secure Boot V2</a> specific.</p> +</section> +<section id="analyzing-a-binary-image"> +<h2>Analyzing a Binary Image<a class="headerlink" href="#analyzing-a-binary-image" title="Permalink to this heading"></a></h2> +<p>To analyze a binary image and get a complete summary of its headers and segments, use the <a class="reference internal" href="../esptool/basic-commands.html#image-info"><span class="std std-ref">image-info</span></a> command.</p> +</section> +</section> + + + </div> + </div> + <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> + <a href="index.html" class="btn btn-neutral float-left" title="Advanced Topics" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> + <a href="serial-protocol.html" class="btn btn-neutral float-right" title="Serial Protocol" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> + </div> + + <hr/> + + <div role="contentinfo"> + <p>© Copyright 2016 - 2026, Espressif Systems (Shanghai) Co., Ltd.</p> + </div> + + <ul class="footer"> + <li> + + + Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/espressif/sphinx_idf_theme">theme</a> based on <a href="https://github.com/readthedocs/sphinx_rtd_theme">Read the Docs Sphinx Theme</a>. + </li> + + </ul> + +</footer> + </div> + </div> + </section> + </div> + + <script> + jQuery(function () { + SphinxRtdTheme.Navigation.enable(true); + }); + </script> + +</body> +</html>
\ No newline at end of file diff --git a/cpu-docs/espressif-software/esptool_firmware-image-format_v5.3.1.rst b/cpu-docs/espressif-software/esptool_firmware-image-format_v5.3.1.rst new file mode 100644 index 0000000..61d35f1 --- /dev/null +++ b/cpu-docs/espressif-software/esptool_firmware-image-format_v5.3.1.rst @@ -0,0 +1,209 @@ +{IDF_TARGET_FLASH_FREQ_F:default="80", esp32c2="60", esp32h2="48", esp32h21="48", esp32h4="48"} + +{IDF_TARGET_FLASH_FREQ_0:default="40", esp32c2="30", esp32h2="24", esp32h21="24", esp32h4="24"} + +{IDF_TARGET_FLASH_FREQ_1:default="26", esp32c2="20", esp32h2="16", esp32h21="16", esp32h4="16"} + +{IDF_TARGET_FLASH_FREQ_2:default="20", esp32c2="15", esp32h2="12", esp32h21="12", esp32h4="12"} + +{IDF_TARGET_BOOTLOADER_OFFSET:default="0x0", esp32="0x1000", esp32s2="0x1000", esp32p4="0x2000", esp32c5="0x2000"} + + +.. _image-format: + +Firmware Image Format +===================== + +This is technical documentation for the firmware image format used by the ROM bootloader. These are the images created by ``esptool elf2image``. + +.. only:: esp8266 + + .. packetdiag:: diag/firmware_image_format_esp8266.diag + :caption: Firmware image format + :align: center + + The firmware file consists of a header, a variable number of data segments and a footer. Multi-byte fields are little-endian. + +.. only:: not esp8266 + + .. packetdiag:: diag/firmware_image_format.diag + :caption: Firmware image format + :align: center + + The firmware file consists of a header, an extended header, a variable number of data segments and a footer. Multi-byte fields are little-endian. + +File Header +----------- + +.. packetdiag:: diag/firmware_image_header_format.diag + :caption: Firmware image header + :align: center + +The image header is 8 bytes long: + +.. only:: 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`` = 512KB, ``1`` = 256KB, ``2`` = 1MB, ``3`` = 2MB, ``4`` = 4MB,| + | | ``5`` = 2MB-c1, ``6`` = 4MB-c1, ``8`` = 8MB, ``9`` = 16MB) | + | | | + | | Low four bits - Flash frequency (``0`` = 40MHz, ``1`` = 26MHz, ``2`` = 20MHz, ``0xf`` = 80MHz) | + +--------+--------------------------------------------------------------------------------------------------+ + | 4-7 | Entry point address | + +--------+--------------------------------------------------------------------------------------------------+ + + +.. only:: esp32s2 or esp32s3 or esp32p4 + + +--------+------------------------------------------------------------------------------------------------+ + | 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 or 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:: esp32c5 or esp32c61 or esp32h21 or esp32h4 + + +--------+------------------------------------------------------------------------------------------------+ + | 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 (``0xf`` = {IDF_TARGET_FLASH_FREQ_F}MHz, ``0`` = {IDF_TARGET_FLASH_FREQ_0}MHz, ``2`` = {IDF_TARGET_FLASH_FREQ_2}MHz) | + +--------+------------------------------------------------------------------------------------------------+ + | 4-7 | Entry point address | + +--------+------------------------------------------------------------------------------------------------+ + +.. only:: not (esp8266 or esp32c6 or esp32s3 or esp32s2 or esp32p4 or esp32c5 or esp32c61 or esp32h21 or esp32h4) + + +--------+------------------------------------------------------------------------------------------------+ + | 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 | + +--------+------------------------------------------------------------------------------------------------+ + + +``esptool`` overrides the 2nd and 3rd (counted from 0) bytes according to the SPI flash info provided through the command line options (see :ref:`flash-modes`). +These bytes are only overridden if this is a bootloader image (an image written to a correct bootloader offset of {IDF_TARGET_BOOTLOADER_OFFSET}). +In this case, the appended SHA256 digest, which is a cryptographic hash used to verify the integrity of the image, is also updated to reflect the header changes. +Generating images without SHA256 digest can be achieved by running ``esptool elf2image`` with the ``--dont-append-digest`` argument. + +.. only:: esp8266 + + Individual segments come right after this header. + +.. only:: not esp8266 + + Extended File Header + -------------------- + + .. packetdiag:: diag/firmware_image_ext_header_format.diag + :caption: Extended File Header + :align: center + + +--------+---------------------------------------------------------------------------------------------------------+ + | Byte | Description | + +========+=========================================================================================================+ + | 0 | WP pin when SPI pins set via eFuse (read by ROM bootloader) | + +--------+---------------------------------------------------------------------------------------------------------+ + | 1-3 | Drive settings for the SPI flash pins (read by ROM bootloader) | + +--------+---------------------------------------------------------------------------------------------------------+ + | 4-5 | Chip ID (which ESP device is this image for) | + +--------+---------------------------------------------------------------------------------------------------------+ + | 6 | Minimal chip revision supported by the image (deprecated, use the following field) | + +--------+---------------------------------------------------------------------------------------------------------+ + | 7-8 | Minimal chip revision supported by the image (in format: major * 100 + minor) | + +--------+---------------------------------------------------------------------------------------------------------+ + | 9-10 | Maximal chip revision supported by the image (in format: major * 100 + minor) | + +--------+---------------------------------------------------------------------------------------------------------+ + | 11-14 | Reserved bytes in additional header space, currently unused | + +--------+---------------------------------------------------------------------------------------------------------+ + | 15 | Hash appended (If 1, SHA256 digest is appended after the checksum) | + +--------+---------------------------------------------------------------------------------------------------------+ + +Segment +------- + ++---------+-----------------+ +| Byte | Description | ++=========+=================+ +| 0-3 | Memory offset | ++---------+-----------------+ +| 4-7 | Segment size | ++---------+-----------------+ +| 8...n | Data | ++---------+-----------------+ + +Footer +------ + +The file is padded with zeros until its size is one byte less than a multiple of 16 bytes. A last byte (thus making the file size a multiple of 16) is the checksum of the data of all segments. The checksum is defined as the xor-sum of all bytes and the byte ``0xEF``. + +.. only:: not esp8266 + + If ``hash appended`` in the extended file header is ``0x01``, a SHA256 digest “simple hash” (of the entire image) is appended after the checksum. This digest is separate to secure boot and only used for detecting corruption. The SPI flash info cannot be changed during flashing if hash is appended after the image. + + If secure boot is enabled, a signature is also appended (and the simple hash is included in the signed data). This image signature is `Secure Boot V1 <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/secure-boot-v1.html#image-signing-algorithm>`_ and `Secure Boot V2 <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/secure-boot-v2.html#signature-block-format>`_ specific. + + +Analyzing a Binary Image +------------------------ + +To analyze a binary image and get a complete summary of its headers and segments, use the :ref:`image-info <image-info>` command. diff --git a/cpu-docs/espressif-software/esptool_serial-protocol_esp32p4_v5.3.1.html b/cpu-docs/espressif-software/esptool_serial-protocol_esp32p4_v5.3.1.html new file mode 100644 index 0000000..b5a0108 --- /dev/null +++ b/cpu-docs/espressif-software/esptool_serial-protocol_esp32p4_v5.3.1.html @@ -0,0 +1,795 @@ +<!DOCTYPE html> +<html class="writer-html5" lang="en"> +<head> + <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /> + + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Serial Protocol - ESP32-P4 - — esptool latest documentation</title> + <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=03e43079" /> + <link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=a60756f2" /> + <link rel="stylesheet" type="text/css" href="../_static/theme_overrides.css?v=851bd809" /> + + + <!--[if lt IE 9]> + <script src="../_static/js/html5shiv.min.js"></script> + <![endif]--> + + <script src="../_static/jquery.js?v=5d32c60e"></script> + <script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> + <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js?v=becddca3"></script> + <script src="../_static/doctools.js?v=888ff710"></script> + <script src="../_static/sphinx_highlight.js?v=4825356b"></script> + <script src="../_static/js/theme.js"></script> + + + + + <script type="text/javascript"> + DOCUMENTATION_OPTIONS.PAGENAME = 'advanced-topics/serial-protocol'; + DOCUMENTATION_OPTIONS.PROJECT_SLUG = 'esptool'; + DOCUMENTATION_OPTIONS.LATEST_BRANCH_NAME = 'master'; + DOCUMENTATION_OPTIONS.VERSIONS_URL = '.././_static/esptool_versions.js'; + DOCUMENTATION_OPTIONS.LANGUAGES = ["en"]; + DOCUMENTATION_OPTIONS.IDF_TARGET = 'esp32p4'; + DOCUMENTATION_OPTIONS.HAS_IDF_TARGETS = ["esp8266", "esp32", "esp32s2", "esp32s3", "esp32c3", "esp32c2", "esp32c6", "esp32h2", "esp32h4", "esp32p4", "esp32c5", "esp32c61", "esp32h21", "esp32s31"] + DOCUMENTATION_OPTIONS.RELEASE = 'latest'; + DOCUMENTATION_OPTIONS.LANGUAGE_URL = 'en'; + + </script> + + <script type="text/javascript" src=".././_static/esptool_versions.js"></script> + <link rel="author" title="About these documents" href="../about.html" /> + <link rel="index" title="Index" href="../genindex.html" /> + <link rel="search" title="Search" href="../search.html" /> + <link rel="next" title="SPI Flash Modes" href="spi-flash-modes.html" /> + <link rel="prev" title="Firmware Image Format" href="firmware-image-format.html" /> +</head> + +<body class="wy-body-for-nav"> + <div class="wy-grid-for-nav"> + <nav data-toggle="wy-nav-shift" class="wy-nav-side"> + <div class="wy-side-scroll"> + <div class="wy-side-nav-search" > + + + + <a href="../index.html" class="icon icon-home"> + esptool + <img src="../_static/espressif-logo.svg" class="logo" alt="Logo"/> + </a> + + + <div class="selectors"> + <select id="target-select" style="width: 150px;" hidden> + <option value="" disabled selected>Choose target...</option> + </select> + </div> + + + <div class="selectors"> + <select id="version-select" style="width: 150px;" hidden> + <option value="" disabled selected>Choose version...</option> + </select> + </div> + + +<div role="search"> + <form id="rtd-search-form" class="wy-form" action="../search.html" method="get"> + <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> +</div> + </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> + <ul class="current"> +<li class="toctree-l1"><a class="reference internal" href="../installation.html">Installation</a></li> +<li class="toctree-l1"><a class="reference internal" href="../esptool/index.html">Esptool</a></li> +<li class="toctree-l1"><a class="reference internal" href="../espefuse/index.html">Espefuse</a></li> +<li class="toctree-l1"><a class="reference internal" href="../espsecure/index.html">Espsecure</a></li> +<li class="toctree-l1"><a class="reference internal" href="../remote-serial-ports.html">Remote Serial Ports</a></li> +<li class="toctree-l1 current"><a class="reference internal" href="index.html">Advanced Topics</a><ul class="current"> +<li class="toctree-l2"><a class="reference internal" href="firmware-image-format.html">Firmware Image Format</a></li> +<li class="toctree-l2 current"><a class="current reference internal" href="#">Serial Protocol</a><ul> +<li class="toctree-l3"><a class="reference internal" href="#packet-description">Packet Description</a><ul> +<li class="toctree-l4"><a class="reference internal" href="#low-level-protocol">Low Level Protocol</a></li> +<li class="toctree-l4"><a class="reference internal" href="#command-packet">Command Packet</a></li> +<li class="toctree-l4"><a class="reference internal" href="#response-packet">Response Packet</a></li> +<li class="toctree-l4"><a class="reference internal" href="#commands">Commands</a></li> +<li class="toctree-l4"><a class="reference internal" href="#checksum">Checksum</a></li> +</ul> +</li> +<li class="toctree-l3"><a class="reference internal" href="#functional-description">Functional Description</a><ul> +<li class="toctree-l4"><a class="reference internal" href="#initialization">Initialization</a></li> +<li class="toctree-l4"><a class="reference internal" href="#initialization-chip-type-detection">Initialization - Chip Type Detection</a></li> +<li class="toctree-l4"><a class="reference internal" href="#writing-data">Writing Data</a></li> +<li class="toctree-l4"><a class="reference internal" href="#spi-configuration-commands">SPI Configuration Commands</a></li> +<li class="toctree-l4"><a class="reference internal" href="#bit-read-write">32-Bit Read/Write</a></li> +<li class="toctree-l4"><a class="reference internal" href="#reading-flash">Reading Flash</a></li> +</ul> +</li> +<li class="toctree-l3"><a class="reference internal" href="#tracing-esptool-serial-communications">Tracing Esptool Serial Communications</a></li> +</ul> +</li> +<li class="toctree-l2"><a class="reference internal" href="spi-flash-modes.html">SPI Flash Modes</a></li> +<li class="toctree-l2"><a class="reference internal" href="boot-mode-selection.html">Boot Mode Selection</a></li> +</ul> +</li> +<li class="toctree-l1"><a class="reference internal" href="../troubleshooting.html">Troubleshooting</a></li> +<li class="toctree-l1"><a class="reference internal" href="../contributing.html">Contribute</a></li> +<li class="toctree-l1"><a class="reference internal" href="../versions.html">Versions</a></li> +<li class="toctree-l1"><a class="reference internal" href="../migration-guide.html">Migration Guide</a></li> +<li class="toctree-l1"><a class="reference internal" href="../resources.html">Resources</a></li> +<li class="toctree-l1"><a class="reference internal" href="../about.html">About</a></li> +</ul> + + </div> + </div> + </nav> + + <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > + <i data-toggle="wy-nav-top" class="fa fa-bars"></i> + <a href="../index.html">esptool</a> + </nav> + + <div class="wy-nav-content"> + <div class="rst-content"> + <div role="navigation" aria-label="Page navigation"> + <ul class="wy-breadcrumbs"> + <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li> + <li class="breadcrumb-item"><a href="index.html">Advanced Topics</a></li> + <li class="breadcrumb-item active">Serial Protocol</li> + <li class="wy-breadcrumbs-aside"> + <a href="https://github.com/espressif/esptool/blob/90e9560f/docs/en/advanced-topics/serial-protocol.rst" class="fa fa-github"> Edit on GitHub</a> + </li> + </ul> + <hr/> +</div> + <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> + <div itemprop="articleBody"> + + <section id="serial-protocol"> +<span id="id1"></span><h1>Serial Protocol<a class="headerlink" href="#serial-protocol" title="Permalink to this heading"></a></h1> +<p>This is technical documentation for the serial protocol used by the UART bootloader in the ESP32-P4 ROM and the esptool <a class="reference internal" href="../esptool/flasher-stub.html#stub"><span class="std std-ref">stub loader</span></a> program.</p> +<p>The UART bootloader runs on chip reset if certain strapping pins are set. See <a class="reference internal" href="../esptool/entering-bootloader.html#entering-the-bootloader"><span class="std std-ref">Entering the Bootloader</span></a> for details of this process.</p> +<p>By default, esptool uploads a stub “software loader” to the IRAM of the chip. The stub loader then replaces the ROM loader for all future interactions. This standardizes much of the behavior. Pass <code class="docutils literal notranslate"><span class="pre">--no-stub</span></code> to esptool in order to disable the stub loader. See <a class="reference internal" href="../esptool/flasher-stub.html#stub"><span class="std std-ref">Flasher Stub</span></a> for more information.</p> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>There are differences in the serial protocol between ESP chips! To switch to documentation for a different chip, choose the desired target from the dropdown menu in the upper left corner.</p> +</div> +<section id="packet-description"> +<h2>Packet Description<a class="headerlink" href="#packet-description" title="Permalink to this heading"></a></h2> +<p>The host computer sends a SLIP encoded command request to the ESP chip. The ESP chip responds to the request with a SLIP encoded response packet, including status information and any data as a payload.</p> +<section id="low-level-protocol"> +<span id="id2"></span><h3>Low Level Protocol<a class="headerlink" href="#low-level-protocol" title="Permalink to this heading"></a></h3> +<p>The bootloader protocol uses <a class="reference external" href="https://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol">SLIP</a> packet framing for data transmissions in both directions.</p> +<p>Each SLIP packet begins and ends with <code class="docutils literal notranslate"><span class="pre">0xC0</span></code>. Within the packet, all occurrences of <code class="docutils literal notranslate"><span class="pre">0xC0</span></code> and <code class="docutils literal notranslate"><span class="pre">0xDB</span></code> are replaced with <code class="docutils literal notranslate"><span class="pre">0xDB</span> <span class="pre">0xDC</span></code> and <code class="docutils literal notranslate"><span class="pre">0xDB</span> <span class="pre">0xDD</span></code>, respectively. The replacing is to be done <strong>after</strong> the checksum and lengths are calculated, so the packet length may be longer than the <code class="docutils literal notranslate"><span class="pre">size</span></code> field below.</p> +</section> +<section id="command-packet"> +<h3>Command Packet<a class="headerlink" href="#command-packet" title="Permalink to this heading"></a></h3> +<p>Each command is a SLIP packet initiated by the host and results in a response packet. Inside the packet, the packet consists of a header and a variable-length body. All multi-byte fields are little-endian.</p> +<figure class="align-center" id="id3"> +<div><img height="220" src="../_images/packetdiag-2b26411142ad479e9f6469f32c1e2f5f2ce1f1f0.png" width="928" /></div><figcaption> +<p><span class="caption-text">Command packet format</span><a class="headerlink" href="#id3" title="Permalink to this image"></a></p> +</figcaption> +</figure> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Byte</p></th> +<th class="head"><p>Name</p></th> +<th class="head"><p>Comment</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>0</p></td> +<td><p>Direction</p></td> +<td><p>Always <code class="docutils literal notranslate"><span class="pre">0x00</span></code> for requests</p></td> +</tr> +<tr class="row-odd"><td><p>1</p></td> +<td><p>Command</p></td> +<td><p>Command identifier (see <a class="reference internal" href="#commands">Commands</a>).</p></td> +</tr> +<tr class="row-even"><td><p>2-3</p></td> +<td><p>Size</p></td> +<td><p>Length of Data field, in bytes.</p></td> +</tr> +<tr class="row-odd"><td><p>4-7</p></td> +<td><p>Checksum</p></td> +<td><p>Simple checksum of part of the data field (only used for some commands, see <a class="reference internal" href="#checksum">Checksum</a>).</p></td> +</tr> +<tr class="row-even"><td><p>8..n</p></td> +<td><p>Data</p></td> +<td><p>Variable length data payload (0-65535 bytes, as indicated by Size parameter). Usage depends on specific command.</p></td> +</tr> +</tbody> +</table> +</section> +<section id="response-packet"> +<h3>Response Packet<a class="headerlink" href="#response-packet" title="Permalink to this heading"></a></h3> +<p>Each received command will result in a response SLIP packet sent from the ESP chip to the host. Contents of the response packet is:</p> +<figure class="align-center" id="id4"> +<div><img height="220" src="../_images/packetdiag-1457843f5c1dc3f306a1c8e876eb44074a071e0a.png" width="928" /></div><figcaption> +<p><span class="caption-text">Command packet format</span><a class="headerlink" href="#id4" title="Permalink to this image"></a></p> +</figcaption> +</figure> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Byte</p></th> +<th class="head"><p>Name</p></th> +<th class="head"><p>Comment</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>0</p></td> +<td><p>Direction</p></td> +<td><p>Always <code class="docutils literal notranslate"><span class="pre">0x01</span></code> for responses</p></td> +</tr> +<tr class="row-odd"><td><p>1</p></td> +<td><p>Command</p></td> +<td><p>Same value as Command identifier in the request packet that triggered the response</p></td> +</tr> +<tr class="row-even"><td><p>2-3</p></td> +<td><p>Size</p></td> +<td><p>Size of data field. At least the length of the <a class="reference internal" href="#status-bytes">Status Bytes</a> (2 or 4 bytes, see below).</p></td> +</tr> +<tr class="row-odd"><td><p>4-7</p></td> +<td><p>Value</p></td> +<td><p>Response value used by READ_REG command (see below). Zero otherwise.</p></td> +</tr> +<tr class="row-even"><td><p>8..n</p></td> +<td><p>Data</p></td> +<td><p>Variable length data payload. Length indicated by “Size” field.</p></td> +</tr> +</tbody> +</table> +<section id="status-bytes"> +<h4>Status Bytes<a class="headerlink" href="#status-bytes" title="Permalink to this heading"></a></h4> +<p>The final bytes of the Data payload indicate command status:</p> +<p>For stub loader the final two bytes indicate status (most commands return at least a two byte Data payload):</p> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Byte</p></th> +<th class="head"><p>Name</p></th> +<th class="head"><p>Comment</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>Size-2</p></td> +<td><p>Status</p></td> +<td><p>Status flag, success (<code class="docutils literal notranslate"><span class="pre">0</span></code>) or failure (<code class="docutils literal notranslate"><span class="pre">1</span></code>)</p></td> +</tr> +<tr class="row-odd"><td><p>Size-1</p></td> +<td><p>Error</p></td> +<td><p>If Status is 1, this indicates the type of error.</p></td> +</tr> +</tbody> +</table> +<p>For ESP32-P4 ROM (only, not the stub loader) the final four bytes are used, but only the first two bytes contain status information:</p> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Byte</p></th> +<th class="head"><p>Name</p></th> +<th class="head"><p>Comment</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>Size-4</p></td> +<td><p>Status</p></td> +<td><p>Status flag, success (<code class="docutils literal notranslate"><span class="pre">0</span></code>) or failure (<code class="docutils literal notranslate"><span class="pre">1</span></code>)</p></td> +</tr> +<tr class="row-odd"><td><p>Size-3</p></td> +<td><p>Error</p></td> +<td><p>If Status 1, this indicates the type of error.</p></td> +</tr> +<tr class="row-even"><td><p>Size-2</p></td> +<td><p>Reserved</p></td> +<td></td> +</tr> +<tr class="row-odd"><td><p>Size-1</p></td> +<td><p>Reserved</p></td> +<td></td> +</tr> +</tbody> +</table> +</section> +<section id="rom-loader-errors"> +<h4>ROM Loader Errors<a class="headerlink" href="#rom-loader-errors" title="Permalink to this heading"></a></h4> +<p>The ROM loader sends the following error values</p> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Value</p></th> +<th class="head"><p>Meaning</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x00</span></code></p></td> +<td><p>“Undefined errors”</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x01</span></code></p></td> +<td><p>“The input parameter is invalid”</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x02</span></code></p></td> +<td><p>“Failed to malloc memory from system”</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x03</span></code></p></td> +<td><p>“Failed to send out message”</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x04</span></code></p></td> +<td><p>“Failed to receive message”</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x05</span></code></p></td> +<td><p>“The format of the received message is invalid”</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x06</span></code></p></td> +<td><p>“Message is ok, but the running result is wrong”</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x07</span></code></p></td> +<td><p>“Checksum error”</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x08</span></code></p></td> +<td><p>“Flash write error” - after writing a block of data to flash, +the ROM loader reads the value back and the 8-bit CRC is compared +to the data read from flash. If they don’t match, this error is returned.</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x09</span></code></p></td> +<td><p>“Flash read error” - SPI read failed</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x0a</span></code></p></td> +<td><p>“Flash read length error” - SPI read request length is wrong</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x0b</span></code></p></td> +<td><p>“Deflate failed error” (compressed uploads only)</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x0c</span></code></p></td> +<td><p>“Deflate Adler32 error”</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x0d</span></code></p></td> +<td><p>“Deflate parameter error”</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x0e</span></code></p></td> +<td><p>“Invalid RAM binary size”</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x0f</span></code></p></td> +<td><p>“Invalid RAM binary address”</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x64</span></code></p></td> +<td><p>“Invalid parameter”</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x65</span></code></p></td> +<td><p>“Invalid format”</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x66</span></code></p></td> +<td><p>“Description too long”</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x67</span></code></p></td> +<td><p>“Bad encoding description”</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x69</span></code></p></td> +<td><p>“Insufficient storage”</p></td> +</tr> +</tbody> +</table> +</section> +<section id="stub-loader-status-error"> +<h4>Stub Loader Status & Error<a class="headerlink" href="#stub-loader-status-error" title="Permalink to this heading"></a></h4> +<p>If the stub loader is used:</p> +<ul class="simple"> +<li><p>The status response is always 2 bytes regardless of chip type.</p></li> +<li><p>Stub loader error codes are entirely different to the ROM loader codes. They all take the form <code class="docutils literal notranslate"><span class="pre">0xC*</span></code>, or <code class="docutils literal notranslate"><span class="pre">0xFF</span></code> for “unimplemented command”. (<a class="reference external" href="https://github.com/espressif/esptool/blob/master/flasher_stub/include/stub_flasher.h#L95">Full list here</a>).</p></li> +</ul> +<p>After sending a command, the host should continue to read response packets until one is received where the Command field matches the request’s Command field, or a timeout is exceeded.</p> +</section> +</section> +<section id="commands"> +<h3>Commands<a class="headerlink" href="#commands" title="Permalink to this heading"></a></h3> +<section id="supported-by-stub-loader-and-rom-loader"> +<h4>Supported by Stub Loader and ROM Loader<a class="headerlink" href="#supported-by-stub-loader-and-rom-loader" title="Permalink to this heading"></a></h4> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Byte</p></th> +<th class="head"><p>Name</p></th> +<th class="head"><p>Description</p></th> +<th class="head"><p>Input Data</p></th> +<th class="head"><p>Output Data</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x02</span></code></p></td> +<td><p>FLASH_BEGIN</p></td> +<td><p><a class="reference external" href="#writing-data">Begin Flash Download</a></p></td> +<td><p>Four 32-bit words: size to erase, number of data packets, data size in one packet, flash offset. A fifth 32-bit word passed to ROM loader only: <code class="docutils literal notranslate"><span class="pre">1</span></code> to begin encrypted flash, <code class="docutils literal notranslate"><span class="pre">0</span></code> to not.</p></td> +<td></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x03</span></code></p></td> +<td><p>FLASH_DATA</p></td> +<td><p><a class="reference external" href="#writing-data">Flash Download Data</a></p></td> +<td><p>Four 32-bit words: data size, sequence number, <code class="docutils literal notranslate"><span class="pre">0</span></code>, <code class="docutils literal notranslate"><span class="pre">0</span></code>, then data. Uses <a class="reference internal" href="#checksum">Checksum</a>.</p></td> +<td></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x04</span></code></p></td> +<td><p>FLASH_END</p></td> +<td><p><a class="reference external" href="#writing-data">Finish Flash Download</a></p></td> +<td><p>One 32-bit word: <code class="docutils literal notranslate"><span class="pre">0</span></code> to reboot, <code class="docutils literal notranslate"><span class="pre">1</span></code> to run user code. Not necessary to send this command if you wish to stay in the loader</p></td> +<td></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x05</span></code></p></td> +<td><p>MEM_BEGIN</p></td> +<td><p><a class="reference external" href="#writing-data">Begin RAM Download Start</a></p></td> +<td><p>Total size, number of data packets, data size in one packet, memory offset</p></td> +<td></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x06</span></code></p></td> +<td><p>MEM_END</p></td> +<td><p><a class="reference external" href="#writing-data">Finish RAM Download</a></p></td> +<td><p>Two 32-bit words: execute flag, entry point address</p></td> +<td></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x07</span></code></p></td> +<td><p>MEM_DATA</p></td> +<td><p><a class="reference external" href="#writing-data">RAM Download Data</a></p></td> +<td><p>Four 32-bit words: data size, sequence number, <code class="docutils literal notranslate"><span class="pre">0</span></code>, <code class="docutils literal notranslate"><span class="pre">0</span></code>, then data. Uses <a class="reference internal" href="#checksum">Checksum</a>.</p></td> +<td></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x08</span></code></p></td> +<td><p>SYNC</p></td> +<td><p><a class="reference external" href="#initial-synchronisation">Sync Frame</a></p></td> +<td><p>36 bytes: <code class="docutils literal notranslate"><span class="pre">0x07</span> <span class="pre">0x07</span> <span class="pre">0x12</span> <span class="pre">0x20</span></code>, followed by 32 x <code class="docutils literal notranslate"><span class="pre">0x55</span></code></p></td> +<td></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x09</span></code></p></td> +<td><p>WRITE_REG</p></td> +<td><p><a class="reference external" href="#32-bit-readwrite">Write 32-bit memory address</a></p></td> +<td><p>Four 32-bit words: address, value, mask and delay (in microseconds)</p></td> +<td></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x0a</span></code></p></td> +<td><p>READ_REG</p></td> +<td><p><a class="reference external" href="#32-bit-readwrite">Read 32-bit memory address</a></p></td> +<td><p>Address as 32-bit word</p></td> +<td><p>Read data as 32-bit word in <code class="docutils literal notranslate"><span class="pre">value</span></code> field.</p></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x0b</span></code></p></td> +<td><p>SPI_SET_PARAMS</p></td> +<td><p><a class="reference external" href="#spi-set-parameters">Configure SPI flash</a></p></td> +<td><p>Six 32-bit words: id, total size in bytes, block size, sector size, page size, status mask.</p></td> +<td></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x0d</span></code></p></td> +<td><p>SPI_ATTACH</p></td> +<td><p><a class="reference external" href="#spi-attach-command">Attach SPI flash</a></p></td> +<td><p>32-bit word: Zero for normal SPI flash. A second 32-bit word (should be <code class="docutils literal notranslate"><span class="pre">0</span></code>) is passed to ROM loader only.</p></td> +<td></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x0f</span></code></p></td> +<td><p>CHANGE_BAUDRATE</p></td> +<td><p><a class="reference external" href="#initial-synchronisation">Change Baud rate</a></p></td> +<td><p>Two 32-bit words: new baud rate, <code class="docutils literal notranslate"><span class="pre">0</span></code> if we are talking to the ROM loader or the current/old baud rate if we are talking to the stub loader.</p></td> +<td></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x10</span></code></p></td> +<td><p>FLASH_DEFL_BEGIN</p></td> +<td><p><a class="reference external" href="#writing-data">Begin compressed flash download</a></p></td> +<td><p>Four 32-bit words: uncompressed size, number of data packets, data packet size, flash offset. With stub loader the uncompressed size is exact byte count to be written, whereas on ROM bootloader it is rounded up to flash erase block size. +A fifth 32-bit word passed to ROM loader only: <code class="docutils literal notranslate"><span class="pre">1</span></code> to begin encrypted flash, <code class="docutils literal notranslate"><span class="pre">0</span></code> to not.</p></td> +<td></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x11</span></code></p></td> +<td><p>FLASH_DEFL_DATA</p></td> +<td><p><a class="reference external" href="#writing-data">Compressed flash download data</a></p></td> +<td><p>Four 32-bit words: data size, sequence number, <code class="docutils literal notranslate"><span class="pre">0</span></code>, <code class="docutils literal notranslate"><span class="pre">0</span></code>, then data. Uses <a class="reference internal" href="#checksum">Checksum</a>.</p></td> +<td><p>Error code <code class="docutils literal notranslate"><span class="pre">0xC1</span></code> on checksum error.</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x12</span></code></p></td> +<td><p>FLASH_DEFL_END</p></td> +<td><p><a class="reference external" href="#writing-data">End compressed flash download</a></p></td> +<td><p>One 32-bit word: <code class="docutils literal notranslate"><span class="pre">0</span></code> to reboot, <code class="docutils literal notranslate"><span class="pre">1</span></code> to run user code. Not necessary to send this command if you wish to stay in the loader.</p></td> +<td></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0x13</span></code></p></td> +<td><p>SPI_FLASH_MD5</p></td> +<td><p><a class="reference external" href="#verifying-uploaded-data">Calculate MD5 of flash region</a></p></td> +<td><p>Four 32-bit words: address, size, <code class="docutils literal notranslate"><span class="pre">0</span></code>, <code class="docutils literal notranslate"><span class="pre">0</span></code></p></td> +<td><p>Body contains 16 raw bytes of MD5 followed by 2 status bytes (stub loader) or 32 hex-coded ASCII (ROM loader) of calculated MD5</p></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0x14</span></code></p></td> +<td><p>GET_SECURITY_INFO</p></td> +<td><p>Read chip security info</p></td> +<td></td> +<td><p>32 bits <code class="docutils literal notranslate"><span class="pre">flags</span></code>, 1 byte <code class="docutils literal notranslate"><span class="pre">flash_crypt_cnt</span></code>, 7x1 byte <code class="docutils literal notranslate"><span class="pre">key_purposes</span></code>, 32-bit word <code class="docutils literal notranslate"><span class="pre">chip_id</span></code>, 32-bit word <code class="docutils literal notranslate"><span class="pre">eco_version</span></code></p></td> +</tr> +</tbody> +</table> +</section> +<section id="supported-by-stub-loader-only"> +<h4>Supported by Stub Loader Only<a class="headerlink" href="#supported-by-stub-loader-only" title="Permalink to this heading"></a></h4> +<p>ROM loaders will not recognize these commands.</p> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Byte</p></th> +<th class="head"><p>Name</p></th> +<th class="head"><p>Description</p></th> +<th class="head"><p>Input</p></th> +<th class="head"><p>Output</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0xd0</span></code></p></td> +<td><p>ERASE_FLASH</p></td> +<td><p>Erase entire flash chip</p></td> +<td></td> +<td></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0xd1</span></code></p></td> +<td><p>ERASE_REGION</p></td> +<td><p>Erase flash region</p></td> +<td><p>Two 32-bit words: flash offset to erase, erase size in bytes. Both must be multiples of flash sector size.</p></td> +<td></td> +</tr> +<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">0xd2</span></code></p></td> +<td><p>READ_FLASH</p></td> +<td><p><a class="reference external" href="#reading-flash">Read flash</a></p></td> +<td><p>Four 32-bit words: flash offset, read length, flash sector size, read packet size, maximum number of un-acked packets</p></td> +<td></td> +</tr> +<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">0xd3</span></code></p></td> +<td><p>RUN_USER_CODE</p></td> +<td><p>Exits loader and runs user code</p></td> +<td></td> +<td></td> +</tr> +</tbody> +</table> +</section> +<section id="supported-in-secure-download-mode"> +<span id="supported-in-sdm"></span><h4>Supported in Secure Download Mode<a class="headerlink" href="#supported-in-secure-download-mode" title="Permalink to this heading"></a></h4> +<p>Secure Download Mode is a restricted version of the ROM Loader available on Espressif chips. It only allows a limited set of commands:</p> +<ul class="simple"> +<li><p>synchronisation (<code class="docutils literal notranslate"><span class="pre">SYNC</span></code>)</p></li> +<li><p>attaching SPI flash (<code class="docutils literal notranslate"><span class="pre">SPI_ATTACH</span></code>)</p></li> +<li><p>updating SPI config (<code class="docutils literal notranslate"><span class="pre">SPI_SET_PARAMS</span></code>)</p></li> +<li><p>changing baud rate (<code class="docutils literal notranslate"><span class="pre">CHANGE_BAUDRATE</span></code>)</p></li> +<li><p>basic flash write (<code class="docutils literal notranslate"><span class="pre">FLASH_BEGIN</span></code>, <code class="docutils literal notranslate"><span class="pre">FLASH_DATA</span></code>, <code class="docutils literal notranslate"><span class="pre">FLASH_END</span></code>)</p></li> +<li><p>reading a summary of currently enabled security features (<code class="docutils literal notranslate"><span class="pre">GET_SECURITY_INFO</span></code>)</p></li> +</ul> +<p>Any other command (e.g., reading or writing memory, arbitrary code execution through loading to RAM, …) will result in an error.</p> +<p>You can read more about Secure Download Mode in the <a class="reference external" href="https://docs.espressif.com/projects/esp-idf/en/stable/esp32p4/security/security.html#uart-download-mode">ESP-IDF Security Overview</a> or read about its <a class="reference internal" href="../troubleshooting.html#sdm-limitations"><span class="std std-ref">limitations here</span></a>.</p> +</section> +</section> +<section id="checksum"> +<h3>Checksum<a class="headerlink" href="#checksum" title="Permalink to this heading"></a></h3> +<p>The checksum field is ignored (can be zero) for all commands except for MEM_DATA, FLASH_DATA, and FLASH_DEFL_DATA.</p> +<p>Each of the <code class="docutils literal notranslate"><span class="pre">_DATA</span></code> command packets (like <code class="docutils literal notranslate"><span class="pre">FLASH_DEFL_DATA</span></code>, <code class="docutils literal notranslate"><span class="pre">MEM_DATA</span></code>) has the same “data payload” format:</p> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Bytes</p></th> +<th class="head"><p>Name</p></th> +<th class="head"><p>Format</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>0-3</p></td> +<td><p>“Data to write” length</p></td> +<td><p>Little endian 32-bit word.</p></td> +</tr> +<tr class="row-odd"><td><p>4-7</p></td> +<td><p>Sequence number</p></td> +<td><p>Little endian 32-bit word. The sequence numbers are 0 based.</p></td> +</tr> +<tr class="row-even"><td><p>8-15</p></td> +<td><p>0</p></td> +<td><p>Two words of all zeroes, unused.</p></td> +</tr> +<tr class="row-odd"><td><p>16-</p></td> +<td><p>“Data to write”</p></td> +<td><p>Length given at beginning of payload.</p></td> +</tr> +</tbody> +</table> +<p>The checksum is only applied to this final “data to write” section, not the first 16 bytes of data.</p> +<p>To calculate checksum, start with seed value 0xEF and XOR each individual byte in the “data to write”. The 8-bit result is stored in the checksum field of the packet header (as a little endian 32-bit value).</p> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>Because this checksum is not adequate to ensure valid data, the SPI_FLASH_MD5 command was added to validate flash contents after flashing. It is recommended that this command is always used. See <a class="reference internal" href="#verifying-uploaded-data">Verifying Uploaded Data</a>, below.</p> +</div> +</section> +</section> +<section id="functional-description"> +<h2>Functional Description<a class="headerlink" href="#functional-description" title="Permalink to this heading"></a></h2> +<figure class="align-center" id="id5"> +<div class="align-default"><img height="725" src="../_images/blockdiag-b0756ac4bad506cab0944d38fd3c41ad966afaed.png" width="420" /></div> +<figcaption> +<p><span class="caption-text">Download procedure flow chart</span><a class="headerlink" href="#id5" title="Permalink to this image"></a></p> +</figcaption> +</figure> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>This flow chart is used to illustrate the download procedure (writing to flash), other commands have different flows.</p> +</div> +<section id="initialization"> +<h3>Initialization<a class="headerlink" href="#initialization" title="Permalink to this heading"></a></h3> +<p><ul class="simple"> +<li><p>The ESP chip is reset into UART bootloader mode. The host starts by sending SYNC commands. These commands have a large data payload which is also used by the ESP chip to detect the configured baud rate. ESP32-P4 always initialises at 115200bps. However the sync packets can be sent at any baud rate, and the UART peripheral will detect this.</p></li> +<li><p>The host should wait until it sees a valid response to a SYNC command, indicating the ESP chip is correctly communicating.</p></li> +<li><p>Chip type detection then uses various methods to identify chip type, subtype, revision, etc. See below.</p></li> +<li><p>Esptool then (by default) uses the “RAM Download” sequence to upload <a class="reference internal" href="../esptool/flasher-stub.html#stub"><span class="std std-ref">stub loader</span></a> code to IRAM of the chip. The MEM_END command contains the entry-point address to run the stub loader. +The stub loader then sends a custom SLIP packet of the sequence OHAI (<code class="docutils literal notranslate"><span class="pre">0xC0</span> <span class="pre">0x4F</span> <span class="pre">0x48</span> <span class="pre">0x41</span> <span class="pre">0x49</span> <span class="pre">0xC0</span></code>), indicating that it is now running. This is the only unsolicited packet ever sent by the ESP. +If the <code class="docutils literal notranslate"><span class="pre">--no-stub</span></code> argument is supplied to esptool, this entire step is skipped.</p></li> +<li><p>For commands which need to use the flash, the ESP32-P4 ROM an stub loader requires the SPI_ATTACH and SPI_SET_PARAMS commands. See <a class="reference internal" href="#spi-configuration-commands">SPI Configuration Commands</a>.</p></li> +<li><p>For stub loader and/or ESP32-P4 ROM loader, the host can send a CHANGE_BAUD command to set the baud rate to an explicit value. Compared to auto-detecting during the SYNC pulse, this can be more reliable for setting very high baud rate. Esptool tries to sync at (maximum) 115200bps and then sends this command to go to a higher baud rate, if requested.</p></li> +</ul> +</p> +</section> +<section id="initialization-chip-type-detection"> +<h3>Initialization - Chip Type Detection<a class="headerlink" href="#initialization-chip-type-detection" title="Permalink to this heading"></a></h3> +<section id="esp32-p4-chip-detection"> +<h4>ESP32-P4 Chip Detection<a class="headerlink" href="#esp32-p4-chip-detection" title="Permalink to this heading"></a></h4> +<p>ESP32-P4 is detected by using <strong>GET_SECURITY_INFO (0x14)</strong> command and its <strong>chip-id</strong> value.</p> +</section> +<section id="overview-of-detection-for-all-chips"> +<h4>Overview of Detection for All Chips<a class="headerlink" href="#overview-of-detection-for-all-chips" title="Permalink to this heading"></a></h4> +<figure class="align-center" id="id6"> +<div class="align-default"><img height="640" src="../_images/blockdiag-4db88f1b40431100ebbd1950bbf9db2615cf555a.png" width="610" /></div> +<figcaption> +<p><span class="caption-text">All chips detection flow chart</span><a class="headerlink" href="#id6" title="Permalink to this image"></a></p> +</figcaption> +</figure> +<p>On older devices that do not support the <strong>GET_SECURITY_INFO (0x14)</strong> command (which provides the <strong>chip-id</strong>), esptool falls back to reading a <strong>magic register</strong> to determine the chip type.</p> +<p>The main exception is the <strong>ESP32-S2</strong>: although it supports the <strong>GET_SECURITY_INFO (0x14)</strong> command, the output lacks the <strong>chip-id</strong>. Therefore, esptool uses the <strong>magic register</strong> as a fallback for this chip as well. +If reading the register also fails, it indicates the chip is in <strong>secure download</strong> mode.</p> +<p>For details see: <a class="reference external" href="https://github.com/espressif/esptool/blob/v5.0.2/esptool/cmds.py#L101">esptool chip detection code</a></p> +</section> +</section> +<section id="writing-data"> +<h3>Writing Data<a class="headerlink" href="#writing-data" title="Permalink to this heading"></a></h3> +<p>(Includes RAM Download, Flash Download, Compressed Flash Download.)</p> +<p><ul class="simple"> +<li><p>RAM Download (MEM_BEGIN, MEM_DATA, MEM_END) loads data into the ESP chip memory space and (optionally) executes it.</p></li> +<li><p>Flash Download (FLASH_BEGIN, FLASH_DATA) flashes data into the ESP SPI flash.</p></li> +<li><p>Compressed Flash Download is the same, only the data is compressed using the gzip Deflate algorithm to reduce serial overhead.</p></li> +</ul> +</p> +<p>All three of these sequences follow a similar pattern:</p> +<ul class="simple"> +<li><p>A _BEGIN command (FLASH_BEGIN, etc) is sent which contains basic parameters for the flash erase size, start address to write to, etc. The uploader also needs to specify how many “blocks” of data (ie individual data packets) will be sent, and how big each packet is.</p></li> +<li><p>One or more _DATA commands (FLASH_DATA, etc) is sent where the data payload contains the actual data to write to flash/RAM. In the case of Compressed Flash Downloads, the data is compressed using the gzip deflate algorithm. The number of _DATA commands is specified in the _BEGIN command, as is the size of each _DATA payload. +The last data block should be padded to the block size with 0xFF bytes.</p></li> +<li><p>An _END command (FLASH_END, etc) is sent to exit the bootloader and optionally reset the chip (or jump to an address in RAM, in the case of MEM_END). Not necessary to send after flashing if you wish to continue sending other or different commands.</p></li> +</ul> +<p>It’s not necessary to send flash erase commands before sending commands to write to flash, etc. The ROM loaders erase the to-be-written region in response to the FLASH_BEGIN command. +The stub loader does just-in-time erasing as it writes data, to maximize overall flashing performance (each block of data is read into RAM via serial while the previous block is simultaneously being written to flash, and 4KB and 64KB erases are done as needed before writing to flash).</p> +<p>The block size chosen should be small enough to fit into RAM of the device. Esptool uses 16KB which gives good performance when used with the stub loader.</p> +<section id="verifying-uploaded-data"> +<h4>Verifying Uploaded Data<a class="headerlink" href="#verifying-uploaded-data" title="Permalink to this heading"></a></h4> +<p>The 8-bit checksum used in the upload protocol is not sufficient to ensure valid flash contents after upload. The uploader should send the SPI_FLASH_MD5 command or use another method to verify flash contents.</p> +<p>The SPI_FLASH_MD5 command passes the start address in flash and the size of data to calculate. The MD5 value is returned in the response payload, before the status bytes.</p> +<p>Note that the ESP32-P4 ROM loader returns the md5sum as 32 hex encoded ASCII bytes, whereas the stub loader returns the md5sum as 16 raw data bytes of MD5 followed by 2 status bytes.</p> +</section> +</section> +<section id="spi-configuration-commands"> +<h3>SPI Configuration Commands<a class="headerlink" href="#spi-configuration-commands" title="Permalink to this heading"></a></h3> +<section id="spi-attach-command"> +<h4>SPI Attach Command<a class="headerlink" href="#spi-attach-command" title="Permalink to this heading"></a></h4> +<p>The SPI_ATTACH command enables the SPI flash interface. It takes a 32-bit data payload which is used to determine which SPI peripheral and pins should be used to connect to SPI flash.</p> +<p>On the ESP32-P4 stub loader sending this command before interacting with SPI flash is optional. On ESP32-P4 ROM loader, it is required to send this command before interacting with SPI flash.</p> +<table class="docutils align-default"> +<thead> +<tr class="row-odd"><th class="head"><p>Value</p></th> +<th class="head"><p>Meaning</p></th> +</tr> +</thead> +<tbody> +<tr class="row-even"><td><p>0</p></td> +<td><p>Default SPI flash interface</p></td> +</tr> +<tr class="row-odd"><td><p>1</p></td> +<td><p>HSPI interface</p></td> +</tr> +<tr class="row-even"><td><p>(other values)</p></td> +<td><p>Pin numbers as 6-bit values, packed into a 30-bit value. Order (from MSB): HD pin, Q pin, D pin, CS pin, CLK pin.</p></td> +</tr> +</tbody> +</table> +<p>The “Default SPI flash interface” uses pins configured via the <code class="docutils literal notranslate"><span class="pre">SPI_PAD_CONFIG_xxx</span></code> eFuses (if unset, these eFuses are all zero and the default SPI flash pins given in the datasheet are used.)</p> +<p>When writing the values of each pin as 6-bit numbers packed into the data word, each 6-bit value uses the following representation:</p> +<p>On ESP32-P4 ROM loader only, there is an additional 4 bytes in the data payload of this command. These bytes should all be set to zero.</p> +</section> +<section id="spi-set-parameters"> +<h4>SPI Set Parameters<a class="headerlink" href="#spi-set-parameters" title="Permalink to this heading"></a></h4> +<p>The SPI_SET_PARAMS command sets some parameters of the attached SPI flash chip (sizes, etc).</p> +<p>All the values which are passed except total size are hardcoded, and most are not used when writing to flash. See <a class="reference external" href="https://github.com/espressif/esptool/blob/da31d9d7a1bb496995f8e30a6be259689948e43e/esptool.py#L655">flash_set_parameters function</a> in esptool for the values which it sends.</p> +</section> +</section> +<section id="bit-read-write"> +<h3>32-Bit Read/Write<a class="headerlink" href="#bit-read-write" title="Permalink to this heading"></a></h3> +<p>The 32-bit read/write commands (READ_REG, WRITE_REG) allow word-oriented reading and writing of memory and register data.</p> +<p>These commands can be used to manipulate peripherals in arbitrary ways. For example, the esptool “flash id” functionality is implemented by manipulating the SPI peripheral registers to send a JEDEC flash ID command to the flash chip and read the response.</p> +</section> +<section id="reading-flash"> +<h3>Reading Flash<a class="headerlink" href="#reading-flash" title="Permalink to this heading"></a></h3> +<p>The stub loader implements a READ_FLASH command. This command behaves differently to other commands, including the ROM loader’s READ_FLASH command:</p> +<ul class="simple"> +<li><p>The host sends the READ_FLASH command and the data payload contains the offset, read size, size of each individual packet of data, and the maximum number of “un-acknowledged” data packets which can be in flight at one time.</p></li> +<li><p>The stub loader will send a standard response packet, with no additional data payload.</p></li> +<li><p>Now the stub loader will start sending SLIP packets with raw data (of the size requested in the command). There is no metadata included with these SLIP packets.</p></li> +<li><p>After each SLIP packet is received, the host should send back a 4 byte raw SLIP acknowledgement packet with the total number of bytes which have been received. There is no header or other metadata included with these SLIP packets.</p></li> +<li><p>The stub loader may send up to a maximum number (specified by the host in the READ_FLASH commands) of data packets before waiting for the first acknowledgement packet. No more than this “max in flight” limit can be un-acknowledged at any one time.</p></li> +<li><p>After all data packets are acknowledged received, the stub loader sends a 16 byte MD5 digest of all the data which was read from flash. This is also sent as a raw SLIP packet, with no metadata.</p></li> +</ul> +<p>After the read flash process is complete, the stub loader goes back to normal command/response operation.</p> +<p>The ROM loader read flash command is more normal but also much slower to read data.</p> +</section> +</section> +<section id="tracing-esptool-serial-communications"> +<span id="tracing-communications"></span><h2>Tracing Esptool Serial Communications<a class="headerlink" href="#tracing-esptool-serial-communications" title="Permalink to this heading"></a></h2> +<p>esptool has a <code class="docutils literal notranslate"><span class="pre">--trace</span></code> option which can be supplied in the first group of arguments (before the command). This will dump all traffic sent and received via the serial port to the console.</p> +<p>Here is a sample extract, showing a READ_REG command and response:</p> +<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">TRACE</span> <span class="o">+</span><span class="mf">0.000</span> <span class="o">---</span> <span class="n">Cmd</span> <span class="n">READ_REG</span> <span class="p">(</span><span class="mh">0x0a</span><span class="p">)</span> <span class="o">|</span> <span class="n">data_len</span> <span class="mi">4</span> <span class="o">|</span> <span class="n">wait_response</span> <span class="mi">1</span> <span class="o">|</span> <span class="n">timeout</span> <span class="mf">3.000</span> <span class="o">|</span> <span class="n">data</span> <span class="mi">00100040</span> <span class="o">---</span> +<span class="n">TRACE</span> <span class="o">+</span><span class="mf">0.000</span> <span class="n">Write</span> <span class="mi">14</span> <span class="nb">bytes</span><span class="p">:</span> <span class="n">c0000a04000000000000100040c0</span> +<span class="n">TRACE</span> <span class="o">+</span><span class="mf">0.046</span> <span class="n">Read</span> <span class="mi">1</span> <span class="nb">bytes</span><span class="p">:</span> <span class="n">c0</span> +<span class="n">TRACE</span> <span class="o">+</span><span class="mf">0.000</span> <span class="n">Read</span> <span class="mi">11</span> <span class="nb">bytes</span><span class="p">:</span> <span class="mi">010</span><span class="n">a0200090000000000c0</span> +<span class="n">TRACE</span> <span class="o">+</span><span class="mf">0.000</span> <span class="n">Received</span> <span class="n">full</span> <span class="n">packet</span><span class="p">:</span> <span class="mi">010</span><span class="n">a0200090000000000</span> +</pre></div> +</div> +<p>The +X.XXX value is the time delta (in seconds) since the last trace line.</p> +<p>Values are printed in hexadecimal. If more than 16 bytes is printed at one time, a split display is used with hexadecimal bytes on the left and ASCII on the right. Non-printable characters are represented as <code class="docutils literal notranslate"><span class="pre">.</span></code> in ASCII:</p> +<p>Note that multiple protocol layers are represented in the logs. The “Write X bytes” lines show exactly which bytes are being sent “over the wire”, including SLIP framing. Similarly the “Read X bytes” lines show what bytes are being read over the wire, including any SLIP framing. +Once a full SLIP packet is read, the same bytes - as a SLIP payload with any escaping removed - appear in the “Received full packet” log lines.</p> +<p>Here is a second example showing part of the initial synchronization sequence (lots of 0x55 bytes which are <code class="docutils literal notranslate"><span class="pre">U</span></code> in ASCII):</p> +<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>TRACE +0.000 Write 46 bytes: + c000082400000000 0007071220555555 | ...$........ UUU + 5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU + 5555555555555555 5555555555c0 | UUUUUUUUUUUUU. +TRACE +0.012 Read 1 bytes: c0 +TRACE +0.000 Read 63 bytes: + 0108040007071220 00000000c0c00108 | ....... ........ + 0400070712200000 0000c0c001080400 | ..... .......... + 0707122000000000 c0c0010804000707 | ... ............ + 122000000000c0c0 01080400070712 | . ............. +TRACE +0.000 Received full packet: 010804000707122000000000 +TRACE +0.000 Received full packet: 010804000707122000000000 +</pre></div> +</div> +<div class="admonition important"> +<p class="admonition-title">Important</p> +<p>If you don’t plan to use the esptool stub loader, pass <code class="docutils literal notranslate"><span class="pre">--no-stub</span> <span class="pre">--trace</span></code> to see interactions with the chip’s built-in ROM loader only. Otherwise, the trace will show the full binary upload of the loader.</p> +</div> +<p>In addition to this trace feature, most operating systems have “system call trace” or “port trace” features which can be used to dump serial interactions.</p> +</section> +</section> + + + </div> + </div> + <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> + <a href="firmware-image-format.html" class="btn btn-neutral float-left" title="Firmware Image Format" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> + <a href="spi-flash-modes.html" class="btn btn-neutral float-right" title="SPI Flash Modes" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> + </div> + + <hr/> + + <div role="contentinfo"> + <p>© Copyright 2016 - 2026, Espressif Systems (Shanghai) Co., Ltd.</p> + </div> + + <ul class="footer"> + <li> + + + Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/espressif/sphinx_idf_theme">theme</a> based on <a href="https://github.com/readthedocs/sphinx_rtd_theme">Read the Docs Sphinx Theme</a>. + </li> + + </ul> + +</footer> + </div> + </div> + </section> + </div> + + <script> + jQuery(function () { + SphinxRtdTheme.Navigation.enable(true); + }); + </script> + +</body> +</html>
\ No newline at end of file diff --git a/cpu-docs/espressif-software/esptool_serial-protocol_v5.3.1.rst b/cpu-docs/espressif-software/esptool_serial-protocol_v5.3.1.rst new file mode 100644 index 0000000..8d726c1 --- /dev/null +++ b/cpu-docs/espressif-software/esptool_serial-protocol_v5.3.1.rst @@ -0,0 +1,584 @@ +{IDF_TARGET_SECURITY_INFO:default="32 bits ``flags``, 1 byte ``flash_crypt_cnt``, 7x1 byte ``key_purposes``, 32-bit word ``chip_id``, 32-bit word ``eco_version``", esp32s2="32 bits ``flags``, 1 byte ``flash_crypt_cnt``, 7x1 byte ``key_purposes`` "} + +.. _serial-protocol: + +Serial Protocol +=============== + +This is technical documentation for the serial protocol used by the UART bootloader in the {IDF_TARGET_NAME} ROM and the esptool :ref:`stub loader <stub>` program. + +The UART bootloader runs on chip reset if certain strapping pins are set. See :ref:`entering-the-bootloader` for details of this process. + +By default, esptool uploads a stub "software loader" to the IRAM of the chip. The stub loader then replaces the ROM loader for all future interactions. This standardizes much of the behavior. Pass ``--no-stub`` to esptool in order to disable the stub loader. See :ref:`stub` for more information. + +.. note:: + + There are differences in the serial protocol between ESP chips! To switch to documentation for a different chip, choose the desired target from the dropdown menu in the upper left corner. + +Packet Description +------------------ + +The host computer sends a SLIP encoded command request to the ESP chip. The ESP chip responds to the request with a SLIP encoded response packet, including status information and any data as a payload. + +.. _low-level-protocol: + +Low Level Protocol +^^^^^^^^^^^^^^^^^^ + +The bootloader protocol uses `SLIP <https://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol>`_ packet framing for data transmissions in both directions. + +Each SLIP packet begins and ends with ``0xC0``. Within the packet, all occurrences of ``0xC0`` and ``0xDB`` are replaced with ``0xDB 0xDC`` and ``0xDB 0xDD``, respectively. The replacing is to be done **after** the checksum and lengths are calculated, so the packet length may be longer than the ``size`` field below. + +Command Packet +^^^^^^^^^^^^^^ + +Each command is a SLIP packet initiated by the host and results in a response packet. Inside the packet, the packet consists of a header and a variable-length body. All multi-byte fields are little-endian. + +.. packetdiag:: diag/command_packet_format.diag + :caption: Command packet format + :align: center + + ++--------+-------------+--------------------------------------------------------------------------------------------------------------------+ +| Byte | Name | Comment | ++========+=============+====================================================================================================================+ +| 0 | Direction | Always ``0x00`` for requests | ++--------+-------------+--------------------------------------------------------------------------------------------------------------------+ +| 1 | Command | Command identifier (see `Commands`_). | ++--------+-------------+--------------------------------------------------------------------------------------------------------------------+ +| 2-3 | Size | Length of Data field, in bytes. | ++--------+-------------+--------------------------------------------------------------------------------------------------------------------+ +| 4-7 | Checksum | Simple checksum of part of the data field (only used for some commands, see `Checksum`_). | ++--------+-------------+--------------------------------------------------------------------------------------------------------------------+ +| 8..n | Data | Variable length data payload (0-65535 bytes, as indicated by Size parameter). Usage depends on specific command. | ++--------+-------------+--------------------------------------------------------------------------------------------------------------------+ + +Response Packet +^^^^^^^^^^^^^^^ + +Each received command will result in a response SLIP packet sent from the ESP chip to the host. Contents of the response packet is: + +.. packetdiag:: diag/response_packet_format.diag + :caption: Command packet format + :align: center + ++--------+-------------+--------------------------------------------------------------------------------------------------------------+ +| Byte | Name | Comment | ++========+=============+==============================================================================================================+ +| 0 | Direction | Always ``0x01`` for responses | ++--------+-------------+--------------------------------------------------------------------------------------------------------------+ +| 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). | ++--------+-------------+--------------------------------------------------------------------------------------------------------------+ +| 4-7 | Value | Response value used by READ_REG command (see below). Zero otherwise. | ++--------+-------------+--------------------------------------------------------------------------------------------------------------+ +| 8..n | Data | Variable length data payload. Length indicated by "Size" field. | ++--------+-------------+--------------------------------------------------------------------------------------------------------------+ + +Status Bytes +"""""""""""" + +The final bytes of the Data payload indicate command status: + +.. only:: esp8266 + + For stub loader and ESP8266 ROM loader the final two bytes indicate status (most commands return at least a two byte Data payload): + +.. only:: not esp8266 + + For stub loader the final two bytes indicate status (most commands return at least a two byte Data payload): + ++----------+----------+-----------------------------------------------------+ +| Byte | Name | Comment | ++==========+==========+=====================================================+ +| Size-2 | Status | Status flag, success (``0``) or failure (``1``) | ++----------+----------+-----------------------------------------------------+ +| Size-1 | Error | If Status is 1, this indicates the type of error. | ++----------+----------+-----------------------------------------------------+ + +.. only:: not esp8266 + + For {IDF_TARGET_NAME} ROM (only, not the stub loader) the final four bytes are used, but only the first two bytes contain status information: + + +----------+------------+---------------------------------------------------+ + | Byte | Name | Comment | + +==========+============+===================================================+ + | Size-4 | Status | Status flag, success (``0``) or failure (``1``) | + +----------+------------+---------------------------------------------------+ + | Size-3 | Error | If Status 1, this indicates the type of error. | + +----------+------------+---------------------------------------------------+ + | Size-2 | Reserved | | + +----------+------------+---------------------------------------------------+ + | Size-1 | Reserved | | + +----------+------------+---------------------------------------------------+ + +ROM Loader Errors +""""""""""""""""" + +The ROM loader sends the following error values + ++----------+---------------------------------------------------------------------------+ +| Value | Meaning | ++==========+===========================================================================+ +| ``0x00`` | "Undefined errors" | ++----------+---------------------------------------------------------------------------+ +| ``0x01`` | "The input parameter is invalid" | ++----------+---------------------------------------------------------------------------+ +| ``0x02`` | "Failed to malloc memory from system" | ++----------+---------------------------------------------------------------------------+ +| ``0x03`` | "Failed to send out message" | ++----------+---------------------------------------------------------------------------+ +| ``0x04`` | "Failed to receive message" | ++----------+---------------------------------------------------------------------------+ +| ``0x05`` | "The format of the received message is invalid" | ++----------+---------------------------------------------------------------------------+ +| ``0x06`` | "Message is ok, but the running result is wrong" | ++----------+---------------------------------------------------------------------------+ +| ``0x07`` | "Checksum error" | ++----------+---------------------------------------------------------------------------+ +| ``0x08`` | "Flash write error" - after writing a block of data to flash, | +| | the ROM loader reads the value back and the 8-bit CRC is compared | +| | to the data read from flash. If they don't match, this error is returned. | ++----------+---------------------------------------------------------------------------+ +| ``0x09`` | "Flash read error" - SPI read failed | ++----------+---------------------------------------------------------------------------+ +| ``0x0a`` | "Flash read length error" - SPI read request length is wrong | ++----------+---------------------------------------------------------------------------+ +| ``0x0b`` | "Deflate failed error" (compressed uploads only) | ++----------+---------------------------------------------------------------------------+ +| ``0x0c`` | "Deflate Adler32 error" | ++----------+---------------------------------------------------------------------------+ +| ``0x0d`` | "Deflate parameter error" | ++----------+---------------------------------------------------------------------------+ +| ``0x0e`` | "Invalid RAM binary size" | ++----------+---------------------------------------------------------------------------+ +| ``0x0f`` | "Invalid RAM binary address" | ++----------+---------------------------------------------------------------------------+ +| ``0x64`` | "Invalid parameter" | ++----------+---------------------------------------------------------------------------+ +| ``0x65`` | "Invalid format" | ++----------+---------------------------------------------------------------------------+ +| ``0x66`` | "Description too long" | ++----------+---------------------------------------------------------------------------+ +| ``0x67`` | "Bad encoding description" | ++----------+---------------------------------------------------------------------------+ +| ``0x69`` | "Insufficient storage" | ++----------+---------------------------------------------------------------------------+ + +Stub Loader Status & Error +"""""""""""""""""""""""""" + +If the stub loader is used: + +- The status response is always 2 bytes regardless of chip type. +- Stub loader error codes are entirely different to the ROM loader codes. They all take the form ``0xC*``, or ``0xFF`` for "unimplemented command". (`Full list here <https://github.com/espressif/esptool/blob/master/flasher_stub/include/stub_flasher.h#L95>`_). + +After sending a command, the host should continue to read response packets until one is received where the Command field matches the request's Command field, or a timeout is exceeded. + +Commands +^^^^^^^^ + +Supported by Stub Loader and ROM Loader +""""""""""""""""""""""""""""""""""""""" + +.. only:: esp8266 + + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + | Byte | Name | Description | Input Data | Output Data | + +============+================+=======================================================+====================================================================================================================================+================================================+ + | ``0x02`` | FLASH_BEGIN | `Begin Flash Download <#writing-data>`__ | Four 32-bit words: size to erase, number of data packets, data size in one packet, flash offset. | | + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + | ``0x03`` | FLASH_DATA | `Flash Download Data <#writing-data>`__ | Four 32-bit words: data size, sequence number, ``0``, ``0``, then data. Uses `Checksum`_. | | + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + | ``0x04`` | FLASH_END | `Finish Flash Download <#writing-data>`__ | One 32-bit word: ``0`` to reboot, ``1`` to run user code. Not necessary to send this command if you wish to stay in the loader | | + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + | ``0x05`` | MEM_BEGIN | `Begin RAM Download Start <#writing-data>`__ | Total size, number of data packets, data size in one packet, memory offset | | + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + | ``0x06`` | MEM_END | `Finish RAM Download <#writing-data>`__ | Two 32-bit words: execute flag, entry point address | | + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + | ``0x07`` | MEM_DATA | `RAM Download Data <#writing-data>`__ | Four 32-bit words: data size, sequence number, ``0``, ``0``, then data. Uses `Checksum`_. | | + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + | ``0x08`` | SYNC | `Sync Frame <#initial-synchronisation>`__ | 36 bytes: ``0x07 0x07 0x12 0x20``, followed by 32 x ``0x55`` | | + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + | ``0x09`` | WRITE_REG | `Write 32-bit memory address <#32-bit-readwrite>`__ | Four 32-bit words: address, value, mask and delay (in microseconds) | | + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + | ``0x0a`` | READ_REG | `Read 32-bit memory address <#32-bit-readwrite>`__ | Address as 32-bit word | Read data as 32-bit word in ``value`` field. | + +------------+----------------+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+ + +.. only:: esp32 + + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | Byte | Name | Description | Input Data | Output Data | + +============+======================+================================================================+================================================================================================================================================================================================================================================+===================================================================================================================================+ + | ``0x02`` | FLASH_BEGIN | `Begin Flash Download <#writing-data>`__ | Four 32-bit words: size to erase, number of data packets, data size in one packet, flash offset. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x03`` | FLASH_DATA | `Flash Download Data <#writing-data>`__ | Four 32-bit words: data size, sequence number, ``0``, ``0``, then data. Uses `Checksum`_. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x04`` | FLASH_END | `Finish Flash Download <#writing-data>`__ | One 32-bit word: ``0`` to reboot, ``1`` to run user code. Not necessary to send this command if you wish to stay in the loader | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x05`` | MEM_BEGIN | `Begin RAM Download Start <#writing-data>`__ | Total size, number of data packets, data size in one packet, memory offset | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x06`` | MEM_END | `Finish RAM Download <#writing-data>`__ | Two 32-bit words: execute flag, entry point address | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x07`` | MEM_DATA | `RAM Download Data <#writing-data>`__ | Four 32-bit words: data size, sequence number, ``0``, ``0``, then data. Uses `Checksum`_. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x08`` | SYNC | `Sync Frame <#initial-synchronisation>`__ | 36 bytes: ``0x07 0x07 0x12 0x20``, followed by 32 x ``0x55`` | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x09`` | WRITE_REG | `Write 32-bit memory address <#32-bit-readwrite>`__ | Four 32-bit words: address, value, mask and delay (in microseconds) | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x0a`` | READ_REG | `Read 32-bit memory address <#32-bit-readwrite>`__ | Address as 32-bit word | Read data as 32-bit word in ``value`` field. | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x0b`` | SPI_SET_PARAMS | `Configure SPI flash <#spi-set-parameters>`__ | Six 32-bit words: id, total size in bytes, block size, sector size, page size, status mask. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x0d`` | SPI_ATTACH | `Attach SPI flash <#spi-attach-command>`__ | 32-bit word: Zero for normal SPI flash. A second 32-bit word (should be ``0``) is passed to ROM loader only. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x0f`` | CHANGE_BAUDRATE | `Change Baud rate <#initial-synchronisation>`__ | Two 32-bit words: new baud rate, ``0`` if we are talking to the ROM loader or the current/old baud rate if we are talking to the stub loader. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x10`` | FLASH_DEFL_BEGIN | `Begin compressed flash download <#writing-data>`__ | Four 32-bit words: uncompressed size, number of data packets, data packet size, flash offset. With stub loader the uncompressed size is exact byte count to be written, whereas on ROM bootloader it is rounded up to flash erase block size. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x11`` | FLASH_DEFL_DATA | `Compressed flash download data <#writing-data>`__ | Four 32-bit words: data size, sequence number, ``0``, ``0``, then data. Uses `Checksum`_. | Error code ``0xC1`` on checksum error. | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x12`` | FLASH_DEFL_END | `End compressed flash download <#writing-data>`__ | One 32-bit word: ``0`` to reboot, ``1`` to run user code. Not necessary to send this command if you wish to stay in the loader. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x13`` | SPI_FLASH_MD5 | `Calculate MD5 of flash region <#verifying-uploaded-data>`__ | Four 32-bit words: address, size, ``0``, ``0`` | Body contains 16 raw bytes of MD5 followed by 2 status bytes (stub loader) or 32 hex-coded ASCII (ROM loader) of calculated MD5 | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + +.. only:: not esp8266 and not esp32 + + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | Byte | Name | Description | Input Data | Output Data | + +============+======================+================================================================+================================================================================================================================================================================================================================================+===================================================================================================================================+ + | ``0x02`` | FLASH_BEGIN | `Begin Flash Download <#writing-data>`__ | Four 32-bit words: size to erase, number of data packets, data size in one packet, flash offset. A fifth 32-bit word passed to ROM loader only: ``1`` to begin encrypted flash, ``0`` to not. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x03`` | FLASH_DATA | `Flash Download Data <#writing-data>`__ | Four 32-bit words: data size, sequence number, ``0``, ``0``, then data. Uses `Checksum`_. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x04`` | FLASH_END | `Finish Flash Download <#writing-data>`__ | One 32-bit word: ``0`` to reboot, ``1`` to run user code. Not necessary to send this command if you wish to stay in the loader | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x05`` | MEM_BEGIN | `Begin RAM Download Start <#writing-data>`__ | Total size, number of data packets, data size in one packet, memory offset | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x06`` | MEM_END | `Finish RAM Download <#writing-data>`__ | Two 32-bit words: execute flag, entry point address | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x07`` | MEM_DATA | `RAM Download Data <#writing-data>`__ | Four 32-bit words: data size, sequence number, ``0``, ``0``, then data. Uses `Checksum`_. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x08`` | SYNC | `Sync Frame <#initial-synchronisation>`__ | 36 bytes: ``0x07 0x07 0x12 0x20``, followed by 32 x ``0x55`` | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x09`` | WRITE_REG | `Write 32-bit memory address <#32-bit-readwrite>`__ | Four 32-bit words: address, value, mask and delay (in microseconds) | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x0a`` | READ_REG | `Read 32-bit memory address <#32-bit-readwrite>`__ | Address as 32-bit word | Read data as 32-bit word in ``value`` field. | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x0b`` | SPI_SET_PARAMS | `Configure SPI flash <#spi-set-parameters>`__ | Six 32-bit words: id, total size in bytes, block size, sector size, page size, status mask. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x0d`` | SPI_ATTACH | `Attach SPI flash <#spi-attach-command>`__ | 32-bit word: Zero for normal SPI flash. A second 32-bit word (should be ``0``) is passed to ROM loader only. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x0f`` | CHANGE_BAUDRATE | `Change Baud rate <#initial-synchronisation>`__ | Two 32-bit words: new baud rate, ``0`` if we are talking to the ROM loader or the current/old baud rate if we are talking to the stub loader. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x10`` | FLASH_DEFL_BEGIN | `Begin compressed flash download <#writing-data>`__ | Four 32-bit words: uncompressed size, number of data packets, data packet size, flash offset. With stub loader the uncompressed size is exact byte count to be written, whereas on ROM bootloader it is rounded up to flash erase block size. | | + | | | | A fifth 32-bit word passed to ROM loader only: ``1`` to begin encrypted flash, ``0`` to not. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x11`` | FLASH_DEFL_DATA | `Compressed flash download data <#writing-data>`__ | Four 32-bit words: data size, sequence number, ``0``, ``0``, then data. Uses `Checksum`_. | Error code ``0xC1`` on checksum error. | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x12`` | FLASH_DEFL_END | `End compressed flash download <#writing-data>`__ | One 32-bit word: ``0`` to reboot, ``1`` to run user code. Not necessary to send this command if you wish to stay in the loader. | | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x13`` | SPI_FLASH_MD5 | `Calculate MD5 of flash region <#verifying-uploaded-data>`__ | Four 32-bit words: address, size, ``0``, ``0`` | Body contains 16 raw bytes of MD5 followed by 2 status bytes (stub loader) or 32 hex-coded ASCII (ROM loader) of calculated MD5 | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + | ``0x14`` | GET_SECURITY_INFO | Read chip security info | | {IDF_TARGET_SECURITY_INFO} | + +------------+----------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ + +Supported by Stub Loader Only +""""""""""""""""""""""""""""" + +ROM loaders will not recognize these commands. + ++------------+-------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------+----------+ +| Byte | Name | Description | Input | Output | ++============+===================+===================================+=========================================================================================================================+==========+ +| ``0xd0`` | ERASE_FLASH | Erase entire flash chip | | | ++------------+-------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------+----------+ +| ``0xd1`` | ERASE_REGION | Erase flash region | Two 32-bit words: flash offset to erase, erase size in bytes. Both must be multiples of flash sector size. | | ++------------+-------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------+----------+ +| ``0xd2`` | READ_FLASH | `Read flash <#reading-flash>`__ | Four 32-bit words: flash offset, read length, flash sector size, read packet size, maximum number of un-acked packets | | ++------------+-------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------+----------+ +| ``0xd3`` | RUN_USER_CODE | Exits loader and runs user code | | | ++------------+-------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------+----------+ + +.. only:: not esp8266 and not esp32 + + .. _supported-in-sdm: + + Supported in Secure Download Mode + """"""""""""""""""""""""""""""""" + + Secure Download Mode is a restricted version of the ROM Loader available on Espressif chips. It only allows a limited set of commands: + + * synchronisation (``SYNC``) + * attaching SPI flash (``SPI_ATTACH``) + * updating SPI config (``SPI_SET_PARAMS``) + * changing baud rate (``CHANGE_BAUDRATE``) + * basic flash write (``FLASH_BEGIN``, ``FLASH_DATA``, ``FLASH_END``) + * reading a summary of currently enabled security features (``GET_SECURITY_INFO``) + + Any other command (e.g., reading or writing memory, arbitrary code execution through loading to RAM, ...) will result in an error. + + You can read more about Secure Download Mode in the `ESP-IDF Security Overview <https://docs.espressif.com/projects/esp-idf/en/stable/{IDF_TARGET_PATH_NAME}/security/security.html#uart-download-mode>`__ or read about its :ref:`limitations here <sdm-limitations>`. + +Checksum +^^^^^^^^ + +The checksum field is ignored (can be zero) for all commands except for MEM_DATA, FLASH_DATA, and FLASH_DEFL_DATA. + +Each of the ``_DATA`` command packets (like ``FLASH_DEFL_DATA``, ``MEM_DATA``) has the same "data payload" format: + ++---------+--------------------------+----------------------------------------------------------------+ +| Bytes | Name | Format | ++=========+==========================+================================================================+ +| 0-3 | "Data to write" length | Little endian 32-bit word. | ++---------+--------------------------+----------------------------------------------------------------+ +| 4-7 | Sequence number | Little endian 32-bit word. The sequence numbers are 0 based. | ++---------+--------------------------+----------------------------------------------------------------+ +| 8-15 | 0 | Two words of all zeroes, unused. | ++---------+--------------------------+----------------------------------------------------------------+ +| 16- | "Data to write" | Length given at beginning of payload. | ++---------+--------------------------+----------------------------------------------------------------+ + +The checksum is only applied to this final "data to write" section, not the first 16 bytes of data. + +To calculate checksum, start with seed value 0xEF and XOR each individual byte in the "data to write". The 8-bit result is stored in the checksum field of the packet header (as a little endian 32-bit value). + +.. note:: + + Because this checksum is not adequate to ensure valid data, the SPI_FLASH_MD5 command was added to validate flash contents after flashing. It is recommended that this command is always used. See `Verifying Uploaded Data`_, below. + +Functional Description +---------------------- + +.. blockdiag:: diag/download_procedure_chart.diag + :caption: Download procedure flow chart + :align: center + + +.. note:: + This flow chart is used to illustrate the download procedure (writing to flash), other commands have different flows. + +Initialization +^^^^^^^^^^^^^^ +.. list:: + + :esp8266: * The ESP chip is reset into UART bootloader mode. The host starts by sending SYNC commands. These commands have a large data payload which is also used by the ESP chip to detect the configured baud rate. The ESP8266 will initialise at 74800bps with a 26MHz crystal and 115200bps with a 40MHz crystal. However the sync packets can be sent at any baud rate, and the UART peripheral will detect this. + :not esp8266: * The ESP chip is reset into UART bootloader mode. The host starts by sending SYNC commands. These commands have a large data payload which is also used by the ESP chip to detect the configured baud rate. {IDF_TARGET_NAME} always initialises at 115200bps. However the sync packets can be sent at any baud rate, and the UART peripheral will detect this. + * The host should wait until it sees a valid response to a SYNC command, indicating the ESP chip is correctly communicating. + * Chip type detection then uses various methods to identify chip type, subtype, revision, etc. See below. + * Esptool then (by default) uses the "RAM Download" sequence to upload :ref:`stub loader <stub>` code to IRAM of the chip. The MEM_END command contains the entry-point address to run the stub loader. + The stub loader then sends a custom SLIP packet of the sequence OHAI (``0xC0 0x4F 0x48 0x41 0x49 0xC0``), indicating that it is now running. This is the only unsolicited packet ever sent by the ESP. + If the ``--no-stub`` argument is supplied to esptool, this entire step is skipped. + :not esp8266: * For commands which need to use the flash, the {IDF_TARGET_NAME} ROM an stub loader requires the SPI_ATTACH and SPI_SET_PARAMS commands. See `SPI Configuration Commands`_. + :esp8266: * For stub loader, the host can send a CHANGE_BAUD command to set the baud rate to an explicit value. Compared to auto-detecting during the SYNC pulse, this can be more reliable for setting very high baud rate. Esptool tries to sync at (maximum) 115200bps and then sends this command to go to a higher baud rate, if requested. + :not esp8266: * For stub loader and/or {IDF_TARGET_NAME} ROM loader, the host can send a CHANGE_BAUD command to set the baud rate to an explicit value. Compared to auto-detecting during the SYNC pulse, this can be more reliable for setting very high baud rate. Esptool tries to sync at (maximum) 115200bps and then sends this command to go to a higher baud rate, if requested. + +Initialization - Chip Type Detection +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +{IDF_TARGET_NAME} Chip Detection +"""""""""""""""""""""""""""""""" +.. only:: esp8266 or esp32 + + {IDF_TARGET_NAME} does not support **GET_SECURITY_INFO (0x14)** command and its **chip-id** value. So, chip is detected by using **READ_REG** and his magic value. + +.. only:: esp32s2 + + {IDF_TARGET_NAME} supports the **GET_SECURITY_INFO (0x14)** command, but the output lacks the **chip-id**. Therefore, esptool uses the **magic register** as a fallback for this chip as well. + If reading the register also fails, it indicates the chip is in **secure download** mode. + +.. only:: not esp8266 and not esp32 and not esp32s2 + + {IDF_TARGET_NAME} is detected by using **GET_SECURITY_INFO (0x14)** command and its **chip-id** value. + + +Overview of Detection for All Chips +""""""""""""""""""""""""""""""""""" +.. blockdiag:: diag/chip_type_detection_chart.diag + :caption: All chips detection flow chart + :align: center + +On older devices that do not support the **GET_SECURITY_INFO (0x14)** command (which provides the **chip-id**), esptool falls back to reading a **magic register** to determine the chip type. + +The main exception is the **ESP32-S2**: although it supports the **GET_SECURITY_INFO (0x14)** command, the output lacks the **chip-id**. Therefore, esptool uses the **magic register** as a fallback for this chip as well. +If reading the register also fails, it indicates the chip is in **secure download** mode. + +For details see: `esptool chip detection code <https://github.com/espressif/esptool/blob/v5.0.2/esptool/cmds.py#L101>`__ + +Writing Data +^^^^^^^^^^^^ + +(Includes RAM Download, Flash Download, Compressed Flash Download.) + +.. list:: + + * RAM Download (MEM_BEGIN, MEM_DATA, MEM_END) loads data into the ESP chip memory space and (optionally) executes it. + * Flash Download (FLASH_BEGIN, FLASH_DATA) flashes data into the ESP SPI flash. + :esp8266: * Compressed Flash Download is the same, only the data is compressed using the gzip Deflate algorithm to reduce serial overhead. Not supported on ESP8266 ROM loader. + :not esp8266: * Compressed Flash Download is the same, only the data is compressed using the gzip Deflate algorithm to reduce serial overhead. + +All three of these sequences follow a similar pattern: + +* A _BEGIN command (FLASH_BEGIN, etc) is sent which contains basic parameters for the flash erase size, start address to write to, etc. The uploader also needs to specify how many "blocks" of data (ie individual data packets) will be sent, and how big each packet is. +* One or more _DATA commands (FLASH_DATA, etc) is sent where the data payload contains the actual data to write to flash/RAM. In the case of Compressed Flash Downloads, the data is compressed using the gzip deflate algorithm. The number of _DATA commands is specified in the _BEGIN command, as is the size of each _DATA payload. + The last data block should be padded to the block size with 0xFF bytes. +* An _END command (FLASH_END, etc) is sent to exit the bootloader and optionally reset the chip (or jump to an address in RAM, in the case of MEM_END). Not necessary to send after flashing if you wish to continue sending other or different commands. + +It's not necessary to send flash erase commands before sending commands to write to flash, etc. The ROM loaders erase the to-be-written region in response to the FLASH_BEGIN command. +The stub loader does just-in-time erasing as it writes data, to maximize overall flashing performance (each block of data is read into RAM via serial while the previous block is simultaneously being written to flash, and 4KB and 64KB erases are done as needed before writing to flash). + +The block size chosen should be small enough to fit into RAM of the device. Esptool uses 16KB which gives good performance when used with the stub loader. + +.. only:: esp8266 + + Erase Size Bug + """""""""""""" + + On ESP8266 ROM loader only (not stub loader), there is a bug in the interpretation of the FLASH_BEGIN "erase size" parameter. Consult the ``ESP8266ROM.get_erase_size()`` function in esptool for the algorithm which works around this bug and provides the correct erase size parameter to send to the ESP8266. + + This workaround is not needed if the ESP8266 is running the stub loader. + +Verifying Uploaded Data +""""""""""""""""""""""" + +.. only:: esp8266 + + The 8-bit checksum used in the upload protocol is not sufficient to ensure valid flash contents after upload. The uploader should send the SPI_FLASH_MD5 command (not supported on ESP8266 ROM loader) or use another method to verify flash contents. + +.. only:: not esp8266 + + The 8-bit checksum used in the upload protocol is not sufficient to ensure valid flash contents after upload. The uploader should send the SPI_FLASH_MD5 command or use another method to verify flash contents. + +The SPI_FLASH_MD5 command passes the start address in flash and the size of data to calculate. The MD5 value is returned in the response payload, before the status bytes. + +.. only:: not esp8266 + + Note that the {IDF_TARGET_NAME} ROM loader returns the md5sum as 32 hex encoded ASCII bytes, whereas the stub loader returns the md5sum as 16 raw data bytes of MD5 followed by 2 status bytes. + +SPI Configuration Commands +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SPI Attach Command +"""""""""""""""""" + +The SPI_ATTACH command enables the SPI flash interface. It takes a 32-bit data payload which is used to determine which SPI peripheral and pins should be used to connect to SPI flash. + +.. only:: esp8266 + + On the ESP8266 stub loader sending this command before interacting with SPI flash is optional. On ESP8266 ROM loader this command is not supported (SPI flash is enabled when the FLASH_BEGIN command is sent). + + +------------------+----------------------------------------------------------------------------------------------------------------------------------+ + | Value | Meaning | + +==================+==================================================================================================================================+ + | 0 | Default SPI flash interface | + +------------------+----------------------------------------------------------------------------------------------------------------------------------+ + | 1 | HSPI interface | + +------------------+----------------------------------------------------------------------------------------------------------------------------------+ + +.. only:: not esp8266 + + On the {IDF_TARGET_NAME} stub loader sending this command before interacting with SPI flash is optional. On {IDF_TARGET_NAME} ROM loader, it is required to send this command before interacting with SPI flash. + + +------------------+----------------------------------------------------------------------------------------------------------------------------------+ + | Value | Meaning | + +==================+==================================================================================================================================+ + | 0 | Default SPI flash interface | + +------------------+----------------------------------------------------------------------------------------------------------------------------------+ + | 1 | HSPI interface | + +------------------+----------------------------------------------------------------------------------------------------------------------------------+ + | (other values) | Pin numbers as 6-bit values, packed into a 30-bit value. Order (from MSB): HD pin, Q pin, D pin, CS pin, CLK pin. | + +------------------+----------------------------------------------------------------------------------------------------------------------------------+ + + The "Default SPI flash interface" uses pins configured via the ``SPI_PAD_CONFIG_xxx`` eFuses (if unset, these eFuses are all zero and the default SPI flash pins given in the datasheet are used.) + + When writing the values of each pin as 6-bit numbers packed into the data word, each 6-bit value uses the following representation: + + .. only:: esp32 + + * Pin numbers 0 through 30 are represented as themselves. + * Pin numbers 32 & 33 are represented as values 30 & 31. + * It is not possible to represent pins 30 & 31 or pins higher than 33. This is the same 6-bit representation used by the ``SPI_PAD_CONFIG_xxx`` eFuses. + + On {IDF_TARGET_NAME} ROM loader only, there is an additional 4 bytes in the data payload of this command. These bytes should all be set to zero. + +SPI Set Parameters +"""""""""""""""""" + +The SPI_SET_PARAMS command sets some parameters of the attached SPI flash chip (sizes, etc). + +.. only:: esp8266 + + This command is not supported by the ESP8266 ROM loader. + +All the values which are passed except total size are hardcoded, and most are not used when writing to flash. See `flash_set_parameters function <https://github.com/espressif/esptool/blob/da31d9d7a1bb496995f8e30a6be259689948e43e/esptool.py#L655>`__ in esptool for the values which it sends. + +32-Bit Read/Write +^^^^^^^^^^^^^^^^^ + +The 32-bit read/write commands (READ_REG, WRITE_REG) allow word-oriented reading and writing of memory and register data. + +These commands can be used to manipulate peripherals in arbitrary ways. For example, the esptool "flash id" functionality is implemented by manipulating the SPI peripheral registers to send a JEDEC flash ID command to the flash chip and read the response. + +Reading Flash +^^^^^^^^^^^^^ + +The stub loader implements a READ_FLASH command. This command behaves differently to other commands, including the ROM loader's READ_FLASH command: + +* The host sends the READ_FLASH command and the data payload contains the offset, read size, size of each individual packet of data, and the maximum number of "un-acknowledged" data packets which can be in flight at one time. +* The stub loader will send a standard response packet, with no additional data payload. +* Now the stub loader will start sending SLIP packets with raw data (of the size requested in the command). There is no metadata included with these SLIP packets. +* After each SLIP packet is received, the host should send back a 4 byte raw SLIP acknowledgement packet with the total number of bytes which have been received. There is no header or other metadata included with these SLIP packets. +* The stub loader may send up to a maximum number (specified by the host in the READ_FLASH commands) of data packets before waiting for the first acknowledgement packet. No more than this "max in flight" limit can be un-acknowledged at any one time. +* After all data packets are acknowledged received, the stub loader sends a 16 byte MD5 digest of all the data which was read from flash. This is also sent as a raw SLIP packet, with no metadata. + +After the read flash process is complete, the stub loader goes back to normal command/response operation. + +The ROM loader read flash command is more normal but also much slower to read data. + +.. _tracing-communications: + +Tracing Esptool Serial Communications +------------------------------------- + +esptool has a ``--trace`` option which can be supplied in the first group of arguments (before the command). This will dump all traffic sent and received via the serial port to the console. + +Here is a sample extract, showing a READ_REG command and response: + +:: + + TRACE +0.000 --- Cmd READ_REG (0x0a) | data_len 4 | wait_response 1 | timeout 3.000 | data 00100040 --- + TRACE +0.000 Write 14 bytes: c0000a04000000000000100040c0 + TRACE +0.046 Read 1 bytes: c0 + TRACE +0.000 Read 11 bytes: 010a0200090000000000c0 + TRACE +0.000 Received full packet: 010a0200090000000000 + +The +X.XXX value is the time delta (in seconds) since the last trace line. + +Values are printed in hexadecimal. If more than 16 bytes is printed at one time, a split display is used with hexadecimal bytes on the left and ASCII on the right. Non-printable characters are represented as ``.`` in ASCII: + +Note that multiple protocol layers are represented in the logs. The "Write X bytes" lines show exactly which bytes are being sent "over the wire", including SLIP framing. Similarly the "Read X bytes" lines show what bytes are being read over the wire, including any SLIP framing. +Once a full SLIP packet is read, the same bytes - as a SLIP payload with any escaping removed - appear in the "Received full packet" log lines. + +Here is a second example showing part of the initial synchronization sequence (lots of 0x55 bytes which are ``U`` in ASCII): + +:: + + TRACE +0.000 Write 46 bytes: + c000082400000000 0007071220555555 | ...$........ UUU + 5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU + 5555555555555555 5555555555c0 | UUUUUUUUUUUUU. + TRACE +0.012 Read 1 bytes: c0 + TRACE +0.000 Read 63 bytes: + 0108040007071220 00000000c0c00108 | ....... ........ + 0400070712200000 0000c0c001080400 | ..... .......... + 0707122000000000 c0c0010804000707 | ... ............ + 122000000000c0c0 01080400070712 | . ............. + TRACE +0.000 Received full packet: 010804000707122000000000 + TRACE +0.000 Received full packet: 010804000707122000000000 + +.. important:: + + If you don't plan to use the esptool stub loader, pass ``--no-stub --trace`` to see interactions with the chip's built-in ROM loader only. Otherwise, the trace will show the full binary upload of the loader. + +In addition to this trace feature, most operating systems have "system call trace" or "port trace" features which can be used to dump serial interactions. diff --git a/cpu-docs/manifests/EspCustomIsa.md b/cpu-docs/manifests/EspCustomIsa.md new file mode 100644 index 0000000..8a5fd4c --- /dev/null +++ b/cpu-docs/manifests/EspCustomIsa.md @@ -0,0 +1,86 @@ +# EspCustomIsa — Espressif-specific ESP32-P4 CPU ISA: PIE/HWLP vendor extensions, LP core, cache/MMU, custom CSRs, toolchain + +## Key facts established for this project + +**Exact `-march` for ESP32-P4 silicon rev < v3 (this project's v1.3 part), read out of ESP-IDF v6.0.2 +`components/soc/project_include.cmake:19-83`:** + +``` +-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_xesploop_xespv2p1 -mabi=ilp32f -mtune=esp-base +``` + +Composition, line by line: base `rv32imafc_zicsr_zifencei_zaamo_zalrsc` (L20); `_zcb_zcmp_zcmt` +**suppressed** because `CONFIG_ESP32P4_SELECTS_REV_LESS_V3` (L47); `_xesploop` from +`SOC_CPU_HAS_HWLOOP` (L59-61); `_xespv` + `2p1` — the `2p1` pinned *because* rev < v3 (L63-68); +`_xespdsp` only if `SOC_CPU_HAS_DSP`, which ESP32-P4 does **not** define (L70-72). GCC normalises this +to the ELF attribute string found verbatim in IDF's prebuilt P4 libraries +(`components/openthread/lib/esp32p4/libopenthread_br.a`): +`rv32i2p1_m2p0_a2p1_f2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcf1p0_xesploop1p0_xespv2p1`. + +`xesppie` — the name in the task brief — is the **historical** spelling. `riscv32-esp-elf-gcc 15.2.0` +rejects it outright (`extension 'xesppie' starts with 'x' but is unsupported non-standard extension`); +the accepted names are `xespv2p1`, `xespv2p2`, `xesploop`/`xesploop1p0`, `xespdsp`. The old name +survives only in ESP-IDF's gdbstub (`components/esp_gdbstub/src/port/riscv/target_xml.c:88`, +`"org.gnu.gdb.riscv.xesppie"`) and in `components/esp_gdbstub/test_gdbstub_host/rv_decode/xesppie.S` +(header comment still says `-march=rv32ixesppie`). + +**PIE mnemonics used by `examples/pie.zig`** (all eight verified present in both documents cited below): +`esp.vld.128.ip`, `esp.vst.128.ip`, `esp.zero.qacc`, `esp.vmulas.s8.qacc`, +`esp.st.qacc.l.l.128.ip`, `esp.st.qacc.l.h.128.ip`, `esp.st.qacc.h.l.128.ip`, `esp.st.qacc.h.h.128.ip`. +Enable CSR is `0x7F2` (`CSR_PIE_STATE_REG`, `components/riscv/include/riscv/csr_pie.h:19`). + +**GCC exposes no PIE intrinsics.** `strings` over `cc1` and `cc1plus` in +`/home/goblin/.espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/libexec/gcc/riscv32-esp-elf/15.2.0/` +yields zero `__builtin_riscv_esp*` / `esppie` symbols — only the `-march` tokens `xespv`, `xesploop`, +`xespdsp`. The extension is assembler-only: 410 distinct `esp.*` mnemonics live in the opcode table of +the dedicated assembler `riscv32-esp-elf/riscv32-esp-elf/bin/as-xespv2p1` (sibling `as-xespv2p2`, +`objdump-xespv2p1`, `objdump-xespv2p2`). This independently confirms `examples/pie.zig`'s premise that +hand-written `.insn` words are the only route, under Espressif's own GCC as much as under stock Zig. + +## Obtained + +| file | title | version / date | source URL | bytes | pages | sha256 (first 16) | relevance | +|---|---|---|---|---|---|---|---| +| espressif-custom-isa/esp32p4-pie-simd_instruction-reference_esp-dl_2026-07-15.md | ESP32-P4 SIMD Instruction Reference | esp-dl master @ 1def9a2dff008fe1ae96c249490683147fce26bc, 2026-07-15 | https://raw.githubusercontent.com/espressif/esp-dl/master/tools/agents/skills/esp32p4-pie-simd/references/instructions.md | 47644 | 907 lines / 346 instruction rows | 76576a92f85fb46a | The only standalone vendor PIE reference: "Register Architecture" (q0–q7, QACC_H/QACC_L 256-bit each, SAR, SAR_BYTE, rounding-mode `rm_exc`), then Read / Write / Data Exchange / Arithmetic / Comparison / Bitwise Logical / Shift / FFT Dedicated instruction tables — covers all 8 mnemonics this project emits (L141 VLD.128.IP, L222 VST.128.IP, L240-243 ST.QACC.{H,L}.{H,L}.128.IP, L339 ZERO.QACC, L490 VMULAS.S8.QACC) | + +**Non-PDF fallback, declared explicitly as the rules require.** No PDF of the PIE instruction set +exists as a standalone Espressif document — the only PDF carrying it is the ESP32-P4 TRM, which is +`espressif-silicon/`'s lane (see "Belongs elsewhere"). This `.md` is the official `.md` spec source +fallback: vendor-authored, in `github.com/espressif/esp-dl`, no mirror involved. + +**Fidelity check against the TRM, so the reader can trust it.** I diffed entries against +`espressif-silicon/esp32p4_technical-reference-manual_en_pre-release-v0.7.pdf` ch.4. The `.md`'s +`ESP.VMULAS.S8.QACC` line — "16 × S8 mul, accumulate 32-bit to QACC_H/L (saturated to 32-bit signed)" — +reproduces TRM §4.7.2.23's description exactly. Caveat worth knowing: the `.md` is a *condensation* +written for agent consumption, so it drops operands and bit-level Operation pseudocode. It gives +`ESP.VMULAS.S8.QACC qx, qy` where TRM §4.7.2.23 syntax is `ESP.VMULAS.S8.QACC qx,qy,sat`, and it +carries **no instruction encodings at all**. It documents 346 mnemonics against the assembler's 410. +For encodings (which is what `.insn` needs) the TRM figures, or `as-xespv2p1` as an oracle the way +`tools/encode.sh` already uses it, remain the only sources. + +## Not obtained + +| wanted | why not | best known pointer | +|---|---|---| +| PIE instruction-set spec with **encodings** (item 1) | Exists, but only as ESP32-P4 TRM ch.4 — a PDF owned by `espressif-silicon/`. Not refetched per lane rule. | `cpu-docs/espressif-silicon/esp32p4_technical-reference-manual_en_pre-release-v0.7.pdf` ch.4 "Processor Instruction Extensions (PIE)" p.210 (§4.7.2.x per-instruction: syntax + Description + Operation + encoding figure; §4.7.2.23 = ESP.VMULAS.S8.QACC), plus §2.7.2 "Processor Instruction Extension" p.127. Upstream: https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf . Local pre-existing copy: `/home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/esp32-p4_technical_reference_manual_en.pdf`. **Warning: the rev-matched v1.3 TRM omits this chapter entirely** (confirmed by EspSilicon: its "Release Status at a Glance" lists ch.3 Processor Instruction Extensions as "[to be added later]" and in-document numbering skips it), so for PIE the generic v0.7 manual must be used even though the part is v1.3 silicon. | +| HWLP / hardware-loop (`xesploop1p0`) spec | No standalone document anywhere; TRM only. | TRM v0.7 §2.7.1 "Hardware Loop" p.119 (2.7.1.1 Overview, .2 Features, .3 Functional Description, .4 Instructions/Operations/Modes Supported in HWLP, .5 HWLP Constraints, .6-.7 Register Summary/Description) and §2.7.1.8 "HWLP Instructions" p.126. CSRs: `esp-idf/components/riscv/include/riscv/csr_hwlp.h` — `CSR_HWLP_STATE_REG 0x7F1` (states OFF/INITIAL/CLEAN/DIRTY), `CSR_LOOP0_START_ADDR 0x7C6`, `CSR_LOOP0_END_ADDR 0x7C7`, `CSR_LOOP0_COUNT 0x7C8`, `CSR_LOOP1_*` 0x7C9-0x7CB. Local: `/home/goblin/esp/esp-idf/components/riscv/include/riscv/csr_hwlp.h`. Upstream: https://github.com/espressif/esp-idf/blob/master/components/riscv/include/riscv/csr_hwlp.h . Errata to respect: `SOC_CPU_HAS_HWLOOP_STATE_BUG` — "HWLOOP state doesn't go to DIRTY after executing the last instruction of a loop" (`components/soc/esp32p4/include/soc/soc_caps.h:198`). | +| LP core (low-power RISC-V) ISA + programming model, standalone (item 2) | No standalone Espressif document exists; the material is split between the TRM's LP CPU chapter and the ESP-IDF guide, both other agents' lanes. | **ISA string (verified, and it is *not* the HP string):** `-march=rv32imac_zicsr_zifencei_zaamo_zalrsc`, no FPU, no vendor extensions — `esp-idf/components/ulp/cmake/toolchain-lp-core-riscv.cmake:8,10,12,14` (C/CXX/ASM/LINK all four). Local: `/home/goblin/esp/esp-idf/components/ulp/cmake/toolchain-lp-core-riscv.cmake`; upstream https://github.com/espressif/esp-idf/blob/master/components/ulp/cmake/toolchain-lp-core-riscv.cmake . **Interrupt/wakeup model:** `components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h` (`ulp_lp_core_intr_enable`/`_disable`, per-source ISR weak symbols) and `ulp_lp_core_utils.h`; driver side `components/ulp/lp_core/lp_core.c`. **Caps:** `components/soc/esp32p4/include/soc/soc_caps.h:57-58` (`SOC_ULP_SUPPORTED`, `SOC_LP_CORE_SUPPORTED`), `:769-771` (`SOC_LP_CORE_SUPPORT_ETM`, `_LP_ADC`, `_STORE_LOAD_EXCEPTIONS`). **Prose spec:** rev-matched `espressif-silicon/esp32-p4-chip-revision-v1.3_technical_reference_manual_en.pdf` ch.3 "Low-Power CPU" p.189 (use this one, not generic v0.7 where LP CPU is ch.5 p.633). | +| Cache + MMU document, PDF (item 3) | Espressif publishes no separate cache/MMU document; TRM chapters plus ROM headers are authoritative. | **Prose:** rev-matched v1.3 TRM ch.7 "System and Memory" p.450 — §7.3.1 Address Mapping p.451, §7.3.3.1 External Memory Address Mapping p.456, §7.3.3.2 Cache p.457, §7.3.3.3 Cache Operations p.458 (generic v0.7 equivalent: ch.9 p.901, §9.3.3.2 Cache p.909). **ROM `Cache_*` API:** `esp-idf/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h` — 1611 lines, **117** distinct `Cache_*` entry points covering the L1-per-core-ICache / L1-DCache / L2-Cache hierarchy this part actually has (`Cache_Enable_L1_CORE0_ICache`, `Cache_Enable_L1_CORE1_ICache`, `Cache_Enable_L1_DCache`, `Cache_Enable_L2_Cache`, `Cache_Clean_Addr`/`_All`/`_Gid`, `Cache_*_Autoload`, `Cache_*_PreLock`). Note the path in the brief is stale for v6.0.2: `components/esp_rom/include/esp32p4/rom/cache.h` does **not** exist; the header moved under `components/esp_rom/esp32p4/`. Local: `/home/goblin/esp/esp-idf/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h`; upstream https://github.com/espressif/esp-idf/blob/master/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h . **The 64 KiB flash-MMU page rule this project exploits:** hard-wired, not configurable — `components/hal/esp32p4/include/hal/mmu_ll.h:129` returns `MMU_PAGE_64KB` unconditionally and `:140` asserts `size == MMU_PAGE_64KB`. Image-side consumer: `components/bootloader_support/src/esp_image_format.c:690` (`__builtin_mul_overflow(max_pages, SPI_FLASH_MMU_PAGE_SIZE, &max_image_len)`) and `:865-885` (`SOC_MMU_PAGE_SIZE_CONFIGURABLE`, page-size-mismatch path). | +| Espressif CSR / interrupt-controller doc beyond the TRM (item 4) | No such document is published; ESP-IDF headers are the only machine-checkable source, and they settle the questions asked. | **`INTPRI` does not exist on the ESP32-P4** — verified negative: zero hits for `INTPRI` under `components/soc/esp32p4/`, whereas ESP32-C6 has `register/soc/intpri_reg.h` + `intpri_struct.h`. The P4 uses a CLIC instead. **Non-standard CLIC on rev < v3, i.e. this part** — `components/soc/esp32p4/include/soc/interrupt_reg.h:30-44`, guarded by `CONFIG_ESP32P4_SELECTS_REV_LESS_V3`, comment verbatim: "The ESP32-P4 implements a non-standard version of the CLIC: - The interrupt threshold is configured via a memory-mapped register instead of a CSR - The mintstatus CSR is at 0x346 instead of 0xFB1 as per the official specification" → `INTTHRESH_STANDARD 0`, `MINTSTATUS_CSR 0x346`. Standard-CLIC values for rev ≥ v3 in `components/riscv/include/riscv/csr_clic.h:39-43` (`MINTSTATUS 0xFB1`, `MINTTHRESH 0x347`, `UINTSTATUS 0xCB1`, `UINTTHRESH 0x047`); `MTVT_CSR 0x307` (:34), `RV_EXTERNAL_INT_COUNT 32` / `RV_EXTERNAL_INT_OFFSET 16` (:28-29). **mtvec is vectored, mode = 3:** `MTVEC_MODE_CSR 3` (csr_clic.h:22) is OR-ed into every write by `rv_utils_set_mtvec` (`components/riscv/include/riscv/rv_utils.h:168-177`, "Set MODE field to treat XTVEC as a vector base address"). CLIC register layout: `components/soc/esp32p4/include/soc/clic_reg.h` (`CLIC_INT_CONFIG_REG`, `NMBITS`, `MNLBITS`, `NVBITS`, `CLIC_EXT_INTR_NUM_OFFSET 16`). **`mpcer`/`mpcmr` are NOT on the P4** — verified negative: `SOC_CPU_HAS_CSR_PC` is defined only for esp32c2/c3/c6/h2/h21 `soc_caps.h`, never esp32p4, so the `CSR_PCER_MACHINE 0x7e0` / `CSR_PCMR_MACHINE 0x7e1` counters gated at `rv_utils.h:44-50` are absent and the P4 falls to standard `mcycle`/`minstret` (`rv_utils.h:122,135`). Other vendor CSRs present: `csr_pie.h` `0x7F2`; `csr_hwlp.h` `0x7F1`,`0x7C6`-`0x7CB`; `csr_dsp.h` `CSR_DSP_STATE_REG 0x7f3`, `XACC_L 0x806`, `XACC_H 0x807`, `SAR 0x809`, `STATUS 0x80a`. | +| riscv32-esp-elf toolchain doc covering the custom `-march` and its ABI implications (item 5) | Espressif publishes no toolchain reference manual, in PDF or otherwise; the `-march` string is documented only by the ESP-IDF build code above. GitHub release notes are the authoritative changelog but never state the vendor `-march` syntax. | Release index: https://github.com/espressif/crosstool-NG/releases . Installed build `esp-15.2.0_20251204` (published 2025-12-05) — its notes are PIE-relevant but shallow: "Added esp.vsl.32 instruction support for backward compatibility". Latest is `esp-16.1.0_20260609` (published 2026-06-10), which removes the `rv32imafc_zicsr_zifencei_zaamo_zalrsc_zcb_zcmp_zcmt` multilib — irrelevant here since rev < v3 already suppresses `_zcb_zcmp_zcmt`. ABI is stated only as the flags in `components/soc/project_include.cmake:75-83`: `-mabi=ilp32f` when `SOC_CPU_HAS_FPU`, `-mtune=esp-base`. Multilib layout on disk (no `xesp*` variant exists — vendor extensions add no multilib, hence no ABI split): `/home/goblin/.espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/riscv32-esp-elf/lib/`. Tooling doc page that exists but does not cover `-march`: https://docs.espressif.com/projects/esp-idf/en/stable/esp32p4/api-guides/tools/idf-tools.html | +| LLVM-side PIE definitions (`RISCVInstrInfoESP32P4.td`, intrinsics headers) | Checked and not usable as a document: `espressif/llvm-project` (branch `xtensa_release_19.1.2`) ships the stock upstream `llvm/docs/RISCVUsage.rst` with no `Xesppie`/`Xespv` section, and any `.td` file is code, which this task forbids copying. Consistent with `examples/pie.zig`'s claim that Espressif's own LLVM cannot assemble these mnemonics. | https://github.com/espressif/llvm-project — searched `llvm/docs/RISCVUsage.rst` (fetched, 26699 bytes, no vendor-extension entry). | +| An esp-dsp guide PDF documenting PIE | Provably absent: `https://docs.espressif.com/projects/esp-dsp/en/latest/` serves HTTP 200 with **zero** `.pdf` hrefs, and all four plausible docs.espressif.com PDF paths return 404 (`esp-dsp-en-master.pdf`, `esp-dsp-en-master-esp32.pdf`, `esp32/esp-dsp-en-master-esp32.pdf`, `esp32p4/esp-dsp-en-master-esp32p4.pdf`). esp-dsp has no PDF build. | https://docs.espressif.com/projects/esp-dsp/en/latest/ (HTML only) | + +### Searches run for a standalone PIE instruction-set document + +Recorded so the negative result is auditable. (1) `espressif.com/en/support/documents/technical-documents` full PDF index scraped (824888 bytes, ~40 `.pdf` hrefs enumerated): the only ESP32-P4 entries are datasheet, TRM, `esp32-p4-chip-revision-v1.3_{datasheet,technical_reference_manual}`, and `esp32-p4-chip-revision-v3.x_user_guide` — **no** PIE/ISA/instruction-set document. (2) `docs.espressif.com/projects/esp-dsp` — no PDF build (four 404s above). (3) Web search for the literal mnemonics `ESP.VMULAS` / `ESP.VLD.128.IP` — surfaced only the esp-dl reference I fetched, an Espressif developer-portal blog post, third-party blogs, and datasheet-mirror copies of the *ESP32-S3* TRM; all rejected except the esp-dl reference. (4) GitHub `espressif/esp-dl/tools/agents/skills/` enumerated via API: `esp32p4-pie-simd/{SKILL.md, references/{instructions.md, examples.md}}` — `instructions.md` taken; `SKILL.md` is agent prose and `examples.md` is example code, both out of scope for a source archive. (5) `espressif/llvm-project` docs (above). (6) Installed toolchain swept for any bundled manual: zero `.pdf`, `.info`, `.1`, or `.html` files under `riscv32-esp-elf/`, only two unrelated GCC `include-fixed` READMEs. **Conclusion: no standalone PIE instruction-set document is published; TRM ch.4 is the sole encoding-complete spec, and the esp-dl `.md` is the sole standalone reference.** + +Non-vendor and blog sources deliberately rejected: `developer.espressif.com/blog/2024/12/pie-introduction/` (Espressif-official but a blog post, excluded per the brief's "blog-free official doc"), `bitbanksoftware.blogspot.com`, `esp32.com` forum, `skillsmp.com`, and the `waveshare`/`hackaday` mirrors of the ESP32-S3 TRM (mirror + wrong chip). + +## Belongs elsewhere + +- **ESP32-P4 TRM (generic, Pre-release v0.7) ch.4 "Processor Instruction Extensions (PIE)" p.210, §2.7.1 Hardware Loop p.119, §2.7.1.8 HWLP Instructions p.126, §2.7.2 Processor Instruction Extension p.127** — the encoding-complete PIE/HWLP spec, and the single most important document for `examples/pie.zig`. Fetched by `espressif-silicon/` as `esp32p4_technical-reference-manual_en_pre-release-v0.7.pdf`; not duplicated here. +- **ESP32-P4 chip-revision-v1.3 TRM (Pre-release v0.4) ch.3 "Low-Power CPU" p.189 and ch.7 "System and Memory" p.450** — rev-correct LP-core and cache/MMU chapters for this project's silicon. `espressif-silicon/`. +- **ESP32-P4 Chip Revision v3.x User Guide** (`https://www.espressif.com/sites/default/files/documentation/esp32-p4-chip-revision-v3.x_user_guide_en.pdf`) — spotted in the espressif.com index while searching; likely documents the rev-v3 ISA/CLIC deltas that `CONFIG_ESP32P4_SELECTS_REV_LESS_V3` and the `xespv2p1`→`xespv2p2` bump straddle. Chip-level revision doc → `espressif-silicon/`. +- **ESP-IDF Programming Guide (ESP32-P4) "ULP LP-Core Coprocessor Programming"** — https://docs.espressif.com/projects/esp-idf/en/stable/esp32p4/api-reference/system/ulp-lp-core.html , part of the ESP-IDF PDF → `espressif-software/`. +- **ESP-IDF Programming Guide "Speed Optimization"** — https://docs.espressif.com/projects/esp-idf/en/stable/esp32p4/api-guides/performance/speed.html , the only guide page discussing PIE-related build flags; inside the ESP-IDF PDF → `espressif-software/`. diff --git a/cpu-docs/manifests/EspSilicon.md b/cpu-docs/manifests/EspSilicon.md new file mode 100644 index 0000000..c3a5544 --- /dev/null +++ b/cpu-docs/manifests/EspSilicon.md @@ -0,0 +1,28 @@ +# EspSilicon — ESP32-P4 chip-level primary documentation from Espressif (silicon rev v1.3 / pre-v3 focus) + +## Obtained + +| file | title | version / date | source URL | bytes | pages | sha256 (first 16) | relevance | +|---|---|---|---|---|---|---|---| +| espressif-silicon/esp32-p4-chip-revision-v1.3_technical-reference-manual_en_pre-release-v0.4.pdf | ESP32-P4 Chip Revision v1.3 Technical Reference Manual | Pre-release v0.4, 2026-06-11 | https://www.espressif.com/sites/default/files/documentation/esp32-p4-chip-revision-v1.3_technical_reference_manual_en.pdf | 20786220 | 2975 | ae1fa2a411776760 | **Rev-matched pre-v3 TRM (EOL-watermarked).** ch.1 High-Performance CPU p.60 (§1.4 Address Map p.62, §1.5 CSRs p.63 w/ register summary+description, §1.6 RISC-V standard extensions M/C/F/Zc/A p.94-99, §1.9 Interrupt Controller p.111 → §1.9.2 CLIC p.111 / §1.9.2.2 CLIC CSRs / §1.9.2.3 Interrupt Mapping / §1.9.2.5 Interrupt Level and Priority Encoding / §1.9.2.6-7 CLIC memory-mapped regs p.113-115, §1.9.3 CLINT p.118); ch.2 RISC-V Trace Encoder p.159; ch.3 Low-Power CPU p.189; ch.7 System and Memory p.450 (§7.3.1 Address Mapping p.451, §7.3.2 Internal Memory p.454, §7.3.3.1 External Memory Address Mapping p.456 = flash/PSRAM windows 0x4000_0000-0x43FF_FFFF & 0x4800_0000-0x4BFF_FFFF cacheable + 0x8000_0000/0x8800_0000 direct, mapped via MMU, §7.3.3.2 Cache p.457, §7.3.3.3 Cache Operations p.458, §7.3.4 DMA Address Space p.459, §7.3.5 Modules/Peripherals Address Mapping p.460); ch.8 eFuse Controller p.464; ch.10 Reset and Clock p.612; ch.11 Chip Boot Control p.750 (boot-mode control; no separate boot-ROM chapter); ch.12 Interrupt Matrix p.755 (per-core HP CPU0/CPU1 register sets §12.5-12.6); ch.14 Low-Power Management p.952; ch.15 System Timer p.1033; ch.16 Timer Group (TIMG) p.1058; ch.17 Watchdog Timers (WDT) p.1083; ch.18 RTC Timer p.1098; ch.19 Permission Control (PMS) p.1112; ch.20 System Registers (SYSREG) p.1209; ch.21 Debug Assistant p.1301; ch.22 LP Mailbox p.1361 | +| espressif-silicon/esp32-p4-chip-revision-v1.3_datasheet_en_v1.2.pdf | ESP32-P4 Chip Revision v1.3 Datasheet | v1.2, 2026-06-16 | https://www.espressif.com/sites/default/files/documentation/esp32-p4-chip-revision-v1.3_datasheet_en.pdf | 1603774 | 94 | b2b0ae6fb8e92d23 | Rev-v1.3 spec baseline: HP = 32-bit RISC-V dual-core **RV32IMAFC** (states "supports standard RV32IMAFCZc extensions") up to **360 MHz default** (400 MHz only on request), LP core **RV32IMAC**; on-chip memory 128 KB HP ROM + 16 KB LP ROM + 768 KB HP L2MEM + 8 KB SPM @360 MHz; in-package 16 or 32 MB PSRAM (Table 5-9 PSRAM Specifications); §3 ROM message printing control (Tables 3-5 UART0 / 3-6 USB Serial-JTAG) for boot-log routing; §1 series comparison + revision history (whole doc is the v1.3/EOL line: ESP32-P4NRW16/32 → EOL) | +| espressif-silicon/esp32-p4_soc-errata_en_v1.3.pdf | ESP32-P4 Series SoC Errata | v1.3 (index release 2026-07-10; PDF build 2026-08-23) | https://docs.espressif.com/projects/esp-chip-errata/en/latest/esp32p4/esp-chip-errata-en-master-esp32p4.pdf | 144853 | 19 | 5fd0fec5b306873a | 13 errata. §1.1 vM.X revision scheme; §1.2 runtime chip-rev detection via **EFUSE_RD_MAC_SPI_SYS_2_REG[23] + [5:0]** (Table 1.1 gives the exact bit pattern for v1.3 vs v0.0/v1.0/v3.0/v3.1/v3.2); §1.4 ESP-IDF release compatibility; §2 Errata Summary p.3; §3.3-3.5 MSPI-749 load-access-fault on power-on/deep-sleep wake, MSPI-750 PSRAM unaligned DMA stale data, MSPI-751 address-overlap timing; §3.6/3.7/3.8 ROM-764 secure-boot bad buffer addr, ROM-770 secure-download flash power-on failure, ROM-816 hang on double flash power-on — all boot-ROM issues live on v1.3 silicon; §3.10 DMA-767, §3.11 APM-560 | +| espressif-silicon/esp32-p4-chip-revision-v3.x_user-guide_en_v1.0.pdf | ESP32-P4 Chip Revision v3.x User Guide | v1.0, 2026-03-11 | https://www.espressif.com/sites/default/files/documentation/esp32-p4-chip-revision-v3.x_user_guide_en.pdf | 476336 | 13 | 9329de55ef88f310 | Chip-revision/compatibility doc; §1 "Design Changes in Chip Revision v3.x" is the definitive list of what v1.3 silicon **lacks**: HP CPU max 360 (not 400) MHz, **no Zb extension**, PMP entries fewer than 32, no user-mode interrupt delegation and no Interrupt-Matrix remapping, unfixed EXT_ILL_CSR bit-0 FPU behaviour, slower/less-compliant CLIC CSR access, different HW-loop counter width (v3.x = 24-bit), and cached region mapping starting from the **top** of L2MEM (v3.x moved it to the bottom) — plus §1 lists the v1.3 bugs fixed later (MSPI-749/750/751, ROM-764/770, Analog-765, DMA-767, APM-560); §2 upgrade impact, §4 ordering info | +| espressif-silicon/esp32-p4_technical-reference-manual_en_pre-release-v0.7.pdf | ESP32-P4 Technical Reference Manual | Pre-release v0.7, 2026-08-20 | https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf | 23537234 | 3701 | 622fe9625d19cf00 | Placed by LocalHarvest; I verified it byte-identical (full sha256 match) to current upstream, so not re-downloaded. This is the **v3.x-line** manual, kept because the rev-v1.3 TRM omits the ISA-extension chapter: ch.4 **Processor Instruction Extensions (PIE)** p.210 plus §2.7.1 Hardware Loop p.119 / §2.7.1.2 HWLP Instructions p.126 / §2.7.2 Processor Instruction Extension p.127 exist ONLY here. Other verified in-document chapters (numbering differs from both the v1.3 TRM and this manual's own "Release Status" list, which counts a non-existent eFuse chapter): ch.1 Bus Architecture p.65 (absent from v1.3 TRM), ch.2 HP CPU p.68 (§2.9 Interrupt Controller p.130, §2.9.2 CLIC p.130, §2.9.2.2 CLIC CSRs p.130), ch.5 LP CPU p.633, ch.9 System and Memory p.901 (§9.3.1 Address Mapping p.902, §9.3.2 Internal Memory p.905, §9.3.3.1 External Memory Address Mapping p.909, §9.3.3.2 Cache p.909, §9.3.3.3 Cache Operations p.910, §9.4 eFuse Controller p.916 — eFuse is a *section* here, not a chapter), ch.11 Reset and Clock p.1081, ch.12 Chip Boot Control p.1219, ch.13 Interrupt Matrix p.1224, ch.15 Low-Power Management p.1425, ch.16 System Timer p.1507, ch.17 TIMG p.1532, ch.18 WDT p.1557, ch.19 RTC Timer p.1572, ch.21 SYSREG p.1687, ch.23 AXI Performance Monitor p.1853; register details must be cross-checked against the v1.3 TRM before use on this silicon | +| espressif-silicon/esp32-p4_datasheet_en_pre-release-v0.7.pdf | ESP32-P4 Series Datasheet | Pre-release v0.7, 2026-07-14 | https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf | 1576185 | 102 | fb4f3e91cc2ac519 | Placed by LocalHarvest; verified byte-identical to current upstream, not re-downloaded. **v3.x-line only** — its §1.3 "Chip Revision" covers v3.x and explicitly defers rev-identification/older revisions to the SoC Errata and the v3.x User Guide, so it does **not** carry a v1.3 row; quotes 400 MHz RV32IMAFC (+Zc), LP RV32IMAC, 128 KB HP ROM / 768 KB L2MEM (200 MHz) / 8 KB SPM @400 MHz. Use the rev-v1.3 datasheet above for this project's silicon | + +## Not obtained + +| wanted | why not | best known pointer | +|---|---|---| +| Standalone `esp32-p4_errata_en.pdf` on espressif.com | No such file exists. The filtered ESP32-P4 document index lists "ESP32-P4 Series SoC Errata" v1.3 whose only link is the esp-chip-errata docs project HTML page; no `/sites/default/files/documentation/*errata*.pdf` is served for any chip. I fetched the vendor-official PDF build of that same document instead (see Obtained), so the content is archived — only the hypothetical filename is missing. | https://docs.espressif.com/projects/esp-chip-errata/en/latest/esp32p4/index.html | +| ESP32-P4 Chip Revision v1.x User Guide (a v1.3-side counterpart to the v3.x guide) | Not published. The ESP32-P4-filtered document index contains exactly one chip-revision user guide, for v3.x; there is no v1.x/v1.3 equivalent. The v3.x guide covers the delta in the other direction and is archived above. | https://www.espressif.com/en/support/documents/technical-documents (filter Chip = ESP32-P4) | +| ESP32-P4 Consolidated Pin Overview v1.2 (datasheet appendix) | Published only as `.xlsx`; no PDF exists anywhere official. It is a pin-mux/IO table and carries nothing about bootloader, memory map, interrupts, timers, CSRs, or instructions, so it fails the relevance bar for this archive. | https://www.espressif.com/sites/default/files/documentation/ESP32-P4%20Appendix%20Consolidated%20Pin%20Overview.xlsx | +| ESP32-P4 Hardware Design Guidelines v1.9; ESP32-P4 Test Tools and Guidelines; ESP32-P4 Series Product Packaging Information | Deliberately excluded: assignment bars hardware-design/PCB-layout/RF and board-production documents. | https://www.espressif.com/en/support/documents/technical-documents | + +## Belongs elsewhere + +- ESP-IDF Programming Guide for ESP32-P4 (SDK stable v6.0.2 / v5.5.x), esptool.py Programming Guide, ROM bootloader + flash image format, OpenOCD/GDB manuals — should be fetched by `espressif-software/` +- Vendor SIMD/PIE and HWLP instruction encodings — the source document (generic TRM v0.7, ch.4 PIE p.210 and §2.7.1 HWLP p.119) is archived here in `espressif-silicon/`, but the extension-specific extraction/spec work belongs to `espressif-custom-isa/`; note the rev-v1.3 TRM lists ch.3 "Processor Instruction Extensions" as "[to be added later]" and omits it entirely, so PIE must be cited from the v0.7 TRM +- RISC-V unprivileged/privileged ISA, Zc, debug spec, and the fast-interrupt/CLIC draft specification — should be fetched by `riscv-isa/` +- Board/module documents already present at `01-esp32p4-m3/docs/` (JC-ESP32P4-M3 dev-board PDFs, ESP32-C6-MINI-1 module datasheet) — owned by LocalHarvest; out of scope here diff --git a/cpu-docs/manifests/EspSoftware.md b/cpu-docs/manifests/EspSoftware.md new file mode 100644 index 0000000..4bbbae5 --- /dev/null +++ b/cpu-docs/manifests/EspSoftware.md @@ -0,0 +1,30 @@ +# EspSoftware — Espressif software-side primary docs: boot ROM/bootloader, image format, startup, memory, interrupts, time, flashing, debugging + +## Obtained + +| file | title | version / date | source URL | bytes | pages | sha256 (first 16) | relevance | +|---|---|---|---|---|---|---|---| +| espressif-software/esp-idf-programming-guide_esp32p4_en_v5.3.2.pdf | ESP-IDF Programming Guide — ESP32-P4 | v5.3.2, 2024-12-06 | https://docs.espressif.com/projects/esp-idf/en/v5.3.2/esp32p4/esp-idf-en-v5.3.2-esp32p4.pdf | 13656675 | 2262 | adf06f5531a5c845 | verified TOC pages: 2.9.1 App Image Format p.1364, 2.9.2 Bootloader Image Format p.1370, Heap Memory Allocation p.1593, Interrupt Allocation p.1648, System Time p.1748, ULP LP-Core Coprocessor Programming p.1760, 4.2 Application Startup Flow p.1803 (4.2.1 First/4.2.2 Second Stage Bootloader p.1804), 4.3 Bootloader p.1806, 4.13 JTAG Debugging p.1873, 4.14 Linker Script Generation p.1914, 4.16 Memory Types p.1933, 4.18 Partition Tables p.1938, 5.2.1 Flash Encryption p.2016, 5.2.2 Secure Boot V2 p.2031 | +| espressif-software/esp-idf-programming-guide_esp32p4_en_v6.0.2_html.zip | ESP-IDF Programming Guide — ESP32-P4 (official offline HTML bundle) | v6.0.2 (current stable, matches `src/soc.zig`) | https://docs.espressif.com/projects/esp-idf/en/v6.0.2/esp32p4/esp-idf-en-v6.0.2.zip | 51594786 | 393 html pages (zip verified `unzip -t` OK) | d3f0f339d4a86a04 | non-PDF fallback: Espressif stopped publishing PDFs after v5.3.2, so v6.0.2 (the version this project cross-references) exists only as the official HTML zip linked in the docs footer; same chapters as above (api-guides/startup, app_image_format, memory-types, interrupt-allocation, system-time, jtag-debugging, ulp-lp-core) | +| espressif-software/esptool_serial-protocol_esp32p4_v5.3.1.html | esptool Documentation — Serial Protocol (ESP32-P4 target render) | esptool v5.3.1, released 2026-06-29 | https://docs.espressif.com/projects/esptool/en/latest/esp32p4/advanced-topics/serial-protocol.html | 55340 | n/a | a00a70719b10fbd3 | ROM serial loader: SLIP framing, packet/command format, ESP_SYNC/ESP_MEM_*/ESP_FLASH_BEGIN-DATA-END, stub loader, `tools/rom.zig` reference | +| espressif-software/esptool_firmware-image-format_esp32p4_v5.3.1.html | esptool Documentation — Firmware Image Format (ESP32-P4 render) | esptool v5.3.1, 2026-06-29 | https://docs.espressif.com/projects/esptool/en/latest/esp32p4/advanced-topics/firmware-image-format.html | 16750 | n/a | f9b6269b5d9f3601 | ESP image v1 header, extended header, segment headers, checksum + SHA256 append; `tools/image.zig` reference | +| espressif-software/esptool_boot-mode-selection_esp32p4_v5.3.1.html | esptool Documentation — Boot Mode Selection (ESP32-P4 render) | esptool v5.3.1, 2026-06-29 | https://docs.espressif.com/projects/esptool/en/latest/esp32p4/advanced-topics/boot-mode-selection.html | 30917 | n/a | 100fdf423ba92cc0 | strapping pins, download/UART boot vs SPI boot, ROM boot log messages | +| espressif-software/esptool_serial-protocol_v5.3.1.rst | esptool docs source (canonical reStructuredText) | tag v5.3.1 | https://raw.githubusercontent.com/espressif/esptool/v5.3.1/docs/en/advanced-topics/serial-protocol.rst | 76409 | n/a | 016dbe246a0c0edf | version-pinned canonical source of the above (unresolved `IDF_TARGET_*` substitutions) | +| espressif-software/esptool_firmware-image-format_v5.3.1.rst | esptool docs source (canonical reStructuredText) | tag v5.3.1 | https://raw.githubusercontent.com/espressif/esptool/v5.3.1/docs/en/advanced-topics/firmware-image-format.rst | 15433 | n/a | 1f0cfe32a766b8ab | pinned canonical image-format spec source | +| espressif-software/esptool_boot-mode-selection_v5.3.1.rst | esptool docs source (canonical reStructuredText) | tag v5.3.1 | https://raw.githubusercontent.com/espressif/esptool/v5.3.1/docs/en/advanced-topics/boot-mode-selection.rst | 21887 | n/a | 567510a46d727a51 | pinned canonical boot-mode spec source | + +## Not obtained + +| wanted | why not | best known pointer | +|---|---|---| +| ESP-IDF Programming Guide PDF for v6.x (esp32p4) | Espressif no longer builds PDFs: every `esp-idf-en-<v>-esp32p4.pdf` guess returns 404 for v5.3.3 and all v5.4/v5.5/v6.0.x; the v6.0.2 page footer offers only "Download HTML" (zip). Newest PDF that exists is v5.3.2, obtained above; v6.0.2 taken as HTML zip. | https://docs.espressif.com/projects/esp-idf/en/v6.0.2/esp32p4/ (footer link `esp-idf-en-v6.0.2.zip`) | +| esptool documentation offline PDF | No PDF or HTML-zip artifact published for the esptool docs project (all `esptool-en-*.pdf` name patterns 404, no footer download link). Fell back to official rendered HTML + pinned `.rst` sources. | https://docs.espressif.com/projects/esptool/en/latest/esp32p4/ | +| openocd-esp32 documentation PDF | The `docs.espressif.com/projects/openocd-esp32/` project is retired — `/en/latest/` and `/en/latest/esp32p4/index.html` both return the ReadTheDocs 404 page (deleted, not saved). JTAG/OpenOCD material now lives in the ESP-IDF guide chapter 4.13 (obtained). | https://github.com/espressif/openocd-esp32 (repo `README`/`doc/`) | +| ESP32-P4 boot ROM / mask ROM description document | No prose document exists. Espressif publishes only the ROM ELF symbol tables and ROM linker scripts; per instructions no code was copied. Local authoritative copies: ROM ELF `/home/goblin/.espressif/tools/esp-rom-elfs/20241011/esp32p4_rev0_rom.elf`; ROM symbol/linker scripts `/home/goblin/esp/esp-idf/components/esp_rom/esp32p4/ld/` (`esp32p4.rom.ld`, `esp32p4.rom.api.ld`, `esp32p4.rom.systimer.ld`, `esp32p4.rom.version.ld`, `esp32p4.rom.eco5.*`, plus LP-core `esp32p4lp.rom.*.ld`). | https://github.com/espressif/esp-rom-elfs ; https://github.com/espressif/esp-idf/tree/master/components/esp_rom/esp32p4/ld | +| Standalone "ESP32-P4 Serial Protocol" / "Boot Mode Selection" / secure-boot application-note PDFs | Espressif does not publish these as standalone PDFs for ESP32-P4; the content is only in the esptool docs (obtained) and ESP-IDF guide ch. 5.2 (obtained). | https://www.espressif.com/en/support/documents/technical-documents | + +## Belongs elsewhere + +- ESP32-P4 Technical Reference Manual and Datasheet — `espressif-silicon/` (also already local at `01-esp32p4-m3/docs/`) +- RISC-V unprivileged/privileged/debug specifications — `riscv-isa/` +- Espressif custom ISA extension (`xesppie` / PIE) and LP-core ISA documents — `espressif-custom-isa/` diff --git a/cpu-docs/manifests/LocalHarvest.md b/cpu-docs/manifests/LocalHarvest.md new file mode 100644 index 0000000..469dde8 --- /dev/null +++ b/cpu-docs/manifests/LocalHarvest.md @@ -0,0 +1,45 @@ +# LocalHarvest — machine-local primary documents copied into the archive + +## Obtained + +| file | title | version / date | source URL | bytes | pages | sha256 (first 16) | relevance | +|---|---|---|---|---|---|---|---| +| espressif-silicon/esp32-p4_technical-reference-manual_en_pre-release-v0.7.pdf | ESP32-P4 Technical Reference Manual | Pre-release v0.7, PDF built 2026-08-20 | local copy: /home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/esp32-p4_technical_reference_manual_en.pdf (orig. docs.espressif.com) | 23537234 | 3701 | 622fe9625d19cf00 | ch.2 High-Performance CPU (CSRs), ch.4 Processor Instruction Extensions (PIE), ch.5 Low-Power CPU, ch.9 System and Memory (memory map/cache), ch.13 Chip Boot Control, ch.14 Interrupt Matrix, ch.17 System Timer, ch.18 Timer Group, ch.19 Watchdog Timers, ch.3 RISC-V Trace Encoder | +| espressif-silicon/esp32-p4_datasheet_en_pre-release-v0.7.pdf | ESP32-P4 Series Datasheet | Pre-release v0.7, PDF built 2026-07-14 | local copy: /home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/esp32-p4_datasheet_en.pdf (orig. docs.espressif.com) | 1576185 | 102 | fb4f3e91cc2ac519 | Product Overview (HP dual-core RISC-V + LP core), §1 pin/package, §4.1.4.6 Low-Power Management, in-package PSRAM (16/32 MB) sizing for flash/PSRAM mapping | + +Both were verified with `file` (PDF document, version 1.5), `pdfinfo` (page counts above) and `pdftotext -f 1 -l 3` (title + "Pre-release v0.7" text). Destination directory was empty at copy time, so neither is a duplicate; EspSilicon was notified of the names and sha256s over hub so any newer upstream revision lands under its own rev-suffixed name rather than overwriting these. + +## Not obtained + +| wanted | why not | best known pointer | +|---|---|---| +| RISC-V unprivileged/privileged/debug/psABI specs | no RISC-V specification PDF exists anywhere on this machine (bounded `find -maxdepth 6 -iname '*.pdf'` over 0x4200.cafe, ~/esp, ~/.espressif, ~/Downloads, ~/05-genizah; ~/Documents does not exist) | RiscvSpecs agent, upstream github.com/riscv | +| ESP-IDF / esptool / OpenOCD manuals as PDF | not present locally; the ESP-IDF checkout ships only reStructuredText sources, and the only PDFs under ~/esp/esp-idf are a Unity assertions cheat sheet and a logo asset | EspSoftware agent, docs.espressif.com PDF builds | +| ESP32-P4 errata / ECO sheet | no local copy | EspSilicon agent | + +## Belongs elsewhere + +- ESP32-P4 TRM/datasheet at a revision newer than Pre-release v0.7 — `espressif-silicon/`, owned by EspSilicon (upstream fetch). +- ESP-IDF Programming Guide, esptool, OpenOCD-ESP32 manuals — `espressif-software/`, owned by EspSoftware. +- RISC-V unprivileged/privileged/debug specs and psABI — `riscv-isa/`, owned by RiscvSpecs. +- PIE / Xesppie custom-instruction and LP-core documentation extracted upstream — `espressif-custom-isa/`, owned by EspCustomIsa. + +## Board-level, deliberately excluded + +Present on disk, not CPU documentation, not copied: + +- /home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/JC-ESP32P4-M3-DEV_getting-started.pdf +- /home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/JC-ESP32P4-M3-DEV_Specifications-EN.pdf +- /home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/JC-ESP32P4-M3_schematic.pdf +- /home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/esp32-c6-mini-1_mini-1u_datasheet_en.pdf (companion Wi-Fi module, not the P4 CPU) +- /home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/board-top-callouts.jpg and /home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/schematics/*.png + +## Local non-document sources + +Code/reference material, authoritative but not documents — must NOT be copied into the archive: + +- /home/goblin/esp/esp-idf — ESP-IDF checkout, `git describe` = `v6.0.2` (HEAD 7101770d); reference implementation of startup, image format, cache/MMU setup, interrupt allocation. +- /home/goblin/esp/esp-idf/components/esp_rom/esp32p4/ld/esp32p4.rom.ld — mask-ROM symbol addresses for the HP core; sibling files `esp32p4.rom.api.ld`, `esp32p4.rom.eco5*.ld` (ECO5 silicon variants), `esp32p4.rom.systimer.ld`, `esp32p4.rom.version.ld`, and `esp32p4lp.rom*.ld` for the LP core. +- /home/goblin/.espressif/tools/esp-rom-elfs/20241011/esp32p4_rev0_rom.elf — full boot-ROM ELF with symbols; disassemble for ROM loader protocol and entry points. +- /home/goblin/esp/esp-idf/components/soc/esp32p4/register/hw_ver1/soc/ — the `hw_ver1` (pre-v3 silicon) register headers this project's revision needs; includes `cache_reg.h`, `assist_debug_reg.h`, `efuse_reg.h`, and the matching `*_struct.h` bitfield definitions. +- /home/goblin/.espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/ — installed toolchain, `riscv32-esp-elf-gcc (crosstool-NG esp-15.2.0_20251204) 15.2.0`; ground truth for the arch string and psABI behaviour. Note: this compiler *rejects* `xesppie` ("starts with 'x' but is unsupported non-standard extension"); the real rev<v3 string is `-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_xesploop_xespv2p1 -mabi=ilp32f` — see `manifests/EspCustomIsa.md`. diff --git a/cpu-docs/manifests/RiscvSpecs.md b/cpu-docs/manifests/RiscvSpecs.md new file mode 100644 index 0000000..58ef78e --- /dev/null +++ b/cpu-docs/manifests/RiscvSpecs.md @@ -0,0 +1,35 @@ +# RiscvSpecs — official RISC-V International specifications for the ESP32-P4 HP core (RV32IMAFC_Zicsr_Zifencei, M/U modes, PMP, debug) + +## Obtained + +| file | title | version / date | source URL | bytes | pages | sha256 (first 16) | relevance | +|---|---|---|---|---|---|---|---| +| riscv-isa/riscv-unprivileged-isa_vol1_ratified_20250508.pdf | The RISC-V Instruction Set Manual Volume I: Unprivileged Architecture | 20250508, Ratified (release tag `20250508`, published 2025-05-12) | https://github.com/riscv/riscv-isa-manual/releases/download/20250508/riscv-unprivileged-20250508.pdf | 4643378 | 727 | cef2e63c08c6f82c | Ch.2 RV32I base, Ch.5 Zifencei, Ch.6 Zicsr, Ch.7.1 Zicntr (cycle/time/instret, CSR 0xC00–0xC1F with high halves at 0xC80–0xC9F, RDCYCLE/RDCYCLEH), Ch.12 M, Ch.13 A, Ch.20 F single-precision, Ch.27 C compressed, Ch.28 Zc* | +| riscv-isa/riscv-privileged-architecture_vol2_ratified_20250508.pdf | The RISC-V Instruction Set Manual: Volume II: Privileged Architecture | 20250508, Ratified (release tag `20250508`, published 2025-05-12) | https://github.com/riscv/riscv-isa-manual/releases/download/20250508/riscv-privileged-20250508.pdf | 1372206 | 221 | d0228bbecc76943a | Ch.2.2 CSR listing, Ch.3.1.7 mtvec, 3.1.9 mip/mie, 3.1.10 Hardware Performance Monitor (mcycle), 3.1.12 mcountinhibit, 3.1.14 mepc, 3.1.15 mcause, 3.1.16 mtval, 3.2.1 mtime/mtimecmp, 3.3.2 trap-return (mret), 3.4 Reset, 3.5 NMI, 3.7 Physical Memory Protection (3.7.1 PMP CSRs) | +| riscv-isa/riscv-external-debug-support_v1.0_20250221.pdf | The RISC-V Debug Specification | 1.0, Ratified, revised 2025-02-21 (release tag `1.0`) | https://github.com/riscv/riscv-debug-spec/releases/download/1.0/riscv-debug-specification.pdf | 2495279 | 119 | ce2787b25233a610 | Ch.3 Debug Module (3.1 DMI, 3.7 abstract commands, 3.8 program buffer, 3.13 version detection, 3.14 DM registers), Ch.4 Sdext (4.1 Debug Mode, 4.5 single step, 4.10 virtual debug registers), Ch.5 Sdtrig triggers (5.7 trigger registers), Ch.6.1 JTAG DTM + dtmcs/dmi, 6.1.7 JTAG connector; 1.2.1.2–1.2.1.4 lists the incompatible changes from 0.13 that Espressif's OpenOCD must work around | +| riscv-isa/riscv-external-debug-support_v0.13.2_20190322.pdf | RISC-V External Debug Support | 0.13.2, 2019-03-22 (repo commit d5029366, built PDF `riscv-debug-release.pdf`) | https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf | 818053 | 94 | f203abb93ee2ad60 | **The version ESP32-P4 actually implements** — TRM states "Debug module (DM) compliant with … RISC-V External Debug Support Version 0.13.2" for the HP DM and "Version 0.13" for the LP DM. Ch.3 Debug Module (3.12 DM registers dmstatus@0x11/dmcontrol@0x10/command@0x17/progbuf0@0x20), Ch.4 core debug registers (dcsr/dpc), Ch.5 Trigger Module, Ch.6 JTAG DTM (dmi@0x11) | +| riscv-isa/riscv-elf-psabi_riscv-abi_draft-20260813.pdf | RISC-V ABIs Specification (psABI: calling convention + ELF) | v1.1, 2026-08-13, "Pre-release" (release tag `draft-20260813-01017c3`) | https://github.com/riscv-non-isa/riscv-elf-psabi-doc/releases/download/draft-20260813-01017c343cd6d89ed4d1d568b1c75fac79d2a689/riscv-abi.pdf | 526941 | 118 | ff94b93578a5ee44 | Ch.1.1/1.3 integer + FP register convention, Ch.2.1/2.2 integer and hardware-FP calling convention, Ch.2.7/2.8 named ABIs (ilp32/ilp32f), Ch.5 code models (medlow/medany), Ch.9.1 ELF file header + e_flags, Ch.9.4 relocations (used by the hand-written linker script and LLD), Ch.9.6 sections, Ch.9.7 program header table, Ch.9.11.1 layout of `.riscv.attributes` | +| riscv-isa/riscv-fast-interrupt_clic_draft-v0.10_20250324.pdf | Core-Local Interrupt Controller (CLIC) RISC-V Privileged Architecture Extensions | v0.10, 2025-03-17, **Draft** (release tag `v0.10`, published 2025-03-24 — newest release carrying `clic.pdf`) | https://github.com/riscv/riscv-fast-interrupt/releases/download/v0.10/clic.pdf | 434674 | 69 | ddb80f16aecb98ff | Ch.2 CLIC overview + preemption, Ch.3 `smclic` M-mode extension (3.1 level/priority, 3.2 clicintip, 3.3 clicintie, 3.4 clicintattr, 3.5 clicintctl, 3.8 CLIC CSRs incl. mintthresh/mnxti, 3.9 reset, 3.10 interrupt operation), Ch.5 `smclicshv` selective hardware vectoring, Ch.6 CLIC parameters — the architectural model behind the P4's CLIC/INTPRI | +| riscv-isa/riscv-fast-interrupt_aclic_draft-v0.20_20260731.pdf | Advanced Core-Local Interrupt Controller (ACLIC) RISC-V Privileged Architecture Extensions | v0.20, 2026-07-31, "Stable" but unratified draft (release tag `v0.20`) | https://github.com/riscv/riscv-fast-interrupt/releases/download/v0.20/aclic-v0.20.pdf | 282310 | 38 | 1892f06fd863fe73 | Successor document to CLIC in the same task-group repo; current draft register/CSR model for core-local fast interrupts. Secondary to the v0.10 CLIC PDF for P4 work — the P4 predates it | +| riscv-isa/riscv-assembly-programmers-manual_v0.0.1_20250205.pdf | RISC-V Assembly Programmer's Manual | tag `v0.0.1`, 2025-02-05 (document self-labels "v0.0.0, Development state") | https://github.com/riscv-non-isa/riscv-asm-manual/releases/download/v0.0.1/riscv-asm.pdf | 238665 | 50 | 2edf43ff39c0ca47 | Ch.1 command-line arguments, Ch.2.1/2.2 general + control register naming, plus assembler directives/relocation-modifier syntax used in hand-written startup asm and linker-script-adjacent code | +| riscv-isa/riscv-code-size-reduction_zc_v1.0.4-3_20231026.pdf | Zc* code-size-reduction extension specification | v1.0.4-3, 2023-10-26 (release tag `v1.0.4-3`, riscvarchive) | https://github.com/riscvarchive/riscv-code-size-reduction/releases/download/v1.0.4-3/Zc-1.0.4-3.pdf | 916986 | 60 | 62cea3875763904b | Standalone Zc* doc; §1.1 change history records the `C implies Zca/Zcf/Zcd` and `misa.C` rules that matter when naming the P4's `c` extension in a target triple. Superseded in-tree by Vol I Ch.28 — low priority | +| riscv-isa/riscv-plic_v1.0.0_20230312.pdf | RISC-V Platform-Level Interrupt Controller Specification | 1.0.0, 3/2023, Ratified (release tag `1.0.0`) | https://github.com/riscv/riscv-plic-spec/releases/download/1.0.0/riscv-plic-1.0.0.pdf | 545211 | 18 | 82644c7701601baa | Low relevance — ESP32-P4 uses its own interrupt matrix + CLIC-style controller, not a PLIC; kept only as the contrast point referenced by CLIC §1.3 | +| riscv-isa/riscv-aclint_v1.0-rc4_20220114.pdf | RISC-V Advanced Core Local Interruptor Specification | 1.0-rc4, 2022-01-10, **Draft** (release tag `v1.0-rc4`, riscvarchive; never ratified) | https://github.com/riscvarchive/riscv-aclint/releases/download/v1.0-rc4/riscv-aclint-1.0-rc4.pdf | 133041 | 11 | fb7f1473470fbc2a | Low relevance — Ch.2 MTIMER (mtime/mtimecmp) and Ch.3 MSWI describe the CLINT-style timer the P4 does *not* use (it has systimer/TIMG instead); useful only when comparing against Vol II §3.2.1 | + +All 11 files verified: `file` reports "PDF document", `pdfinfo` parses (page counts above), and `pdftotext -f 1 -l 2` shows the expected title and version string on page 1 (e.g. "Version 20250508: This document is in Ratified state.", "Version 1.0, Revised 2025-02-21: Ratified", "RISC-V External Debug Support / Version 0.13.2"). Total directory size 12 MB. + +## Not obtained + +| wanted | why not | best known pointer | +|---|---|---| +| Debug spec 0.13.2 as a GitHub *release* asset | No release exists for 0.13.2 in `riscv/riscv-debug-spec` (oldest release with an asset is `task_group_vote`, 2018). The obtained file is the official built PDF from riscv.org; it is byte-identical (818053 bytes, sha256 f203abb93ee2ad60) to the repo-hosted `riscv-debug-release.pdf` at the 0.13.2 commit, so provenance is confirmed against github.com/riscv | https://github.com/riscv/riscv-debug-spec/raw/4e0bb0fc2d843473db2356623792c6b7603b94d4/riscv-debug-release.pdf | +| Separate "ELF psABI" PDF distinct from `riscv-abi.pdf` | Does not exist: the repo publishes a single merged artifact ("RISC-V ABIs Specification") whose Ch.9 *is* the ELF psABI. Only `draft-YYYYMMDD-<sha>` releases are published — there is no ratified/non-draft psABI release, so the newest draft was taken | https://github.com/riscv-non-isa/riscv-elf-psabi-doc/releases | +| Ratified CLIC / fast-interrupt spec | None exists. The task group has only ever published drafts; releases `v0.9`–`v0.10` carry `clic.pdf`, and `v0.16`–`v0.20` replaced it with `aclic.pdf`. Both newest artifacts of each lineage were taken and are labelled drafts above | https://github.com/riscv/riscv-fast-interrupt/releases (v0.10 = last `clic.pdf`; v0.20 = newest `aclic.pdf`) | +| Newer-than-20250508 ratified ISA manual | Not available. All 700+ newer tags in `riscv/riscv-isa-manual` are automated nightly `riscv-isa-release-<sha>-<date>` builds of the in-development merged `riscv-spec.pdf` (latest 2026-08-24), which are unratified. `20250508` is the newest ratified release and the only recent one shipping split Vol I / Vol II PDFs | https://github.com/riscv/riscv-isa-manual/releases/tag/20250508 | +| Ratified ACLINT 1.0 | Never ratified; repo moved to `riscvarchive` with `v1.0-rc4` (2022) as the final artifact. rc4 fetched and marked low relevance | https://github.com/riscvarchive/riscv-aclint/releases/tag/v1.0-rc4 | + +## Belongs elsewhere + +- ESP32-P4 Technical Reference Manual (its "RISC-V CPU", "Interrupt Matrix", "CLIC/INTPRI" and "Debug" chapters state DM compliance with debug spec 0.13.2) — should be fetched by `espressif-silicon/` +- Espressif OpenOCD / JTAG debugging manual and GDB usage docs — should be fetched by `espressif-software/` +- Espressif `Xesppie` / PIE custom-instruction documentation and the LP-core (`rv32imac`-class) ISA notes — should be fetched by `espressif-custom-isa/` |
