Skip to content

feat(core): H563 UDS OTA bootloader sim smoke + 3 missing Cortex-M decode paths#334

Merged
w1ne merged 1 commit into
mainfrom
feat/h563-ota-sim-smoke
Jun 22, 2026
Merged

feat(core): H563 UDS OTA bootloader sim smoke + 3 missing Cortex-M decode paths#334
w1ne merged 1 commit into
mainfrom
feat/h563-ota-sim-smoke

Conversation

@w1ne

@w1ne w1ne commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Adds an end-to-end simulation smoke for a dual-bank STM32H563 UDS OTA bootloader, plus three Cortex-M decode/execute paths the firmware needs that main did not yet handle. The decoder changes are additive; no existing instruction behavior changes.

The example runs the full reprogramming cycle on-chip over FDCAN internal loopback: DiagSession, SecurityAccess (real AES-CMAC), Erase, Download, TransferData, ActivateSoftware (hardware SWAP_BANK then reset), and boot into the freshly written bank. The smoke asserts the whole UART narrative and ends on BL-JUMP then APP-B v2.

Decode/execute gaps closed (each covered by decoder and executor unit tests):

  1. REV/REV16/REVSH (T1, 16-bit, 0xBA00-0xBAFF). main decoded only the 32-bit FA90 forms, so the 16-bit forms fell through to Unknown16 and byte-swaps were left stale.
  2. LDRD/STRD (T1) U-bit. The executor always added the imm8*4 offset. mbedTLS AES-128 reads round keys via ldrd Rt,Rt2,[Rn,#-32] (U=0), so it read the wrong address, the cipher output was corrupt, and the SecurityAccess key check never matched. Now decodes add_imm from h1[7] and subtracts when U=0.
  3. LDR/STR (immediate) T4 indexed with writeback (0xF85x/0xF84x). The pre- and post-indexed forms decoded as Unknown32. ldr.w pc, [sp], #4 is clang's function-return idiom; skipping it returned to the wrong address, which left SWAP_BANK cleared instead of set so the swap+reset never fired. Added LdrImm32Idx/StrImm32Idx covering pre/post-index, add/sub, and writeback; a load into PC routes through branch_to.

The FLASH bank-swap and reset model was already correct on main. Fix 3 is what lets the firmware actually set SWAP_BANK, after which the existing swap+reset path fires and the rebooted bootloader jumps into the new bank.

Companion to the udslib examples/h563_uds_bootloader/ bootloader (w1ne/udslib#64).

Gates: cargo test -p labwired-core --lib 1407 passed; cargo fmt --check and cargo clippy -D warnings clean; smoke 14/14.

Add the three Cortex-M decode/execute paths the H563 dual-bank UDS OTA
bootloader exercises that origin/main was missing, plus the end-to-end
sim smoke example. The full OTA cycle now passes 14/14:

  REV/REV16/REVSH (T1, 16-bit, 0xBA00-0xBAFF)
    The mbedTLS/UDS path emits the 16-bit REV forms; main only had the
    32-bit FA90 variants. Without these, byte-swaps were skipped.

  LDRD/STRD (T1) U-bit
    h1[7] selects add (U=1) vs subtract (U=0) of the imm8*4 offset; the
    executor always added. mbedTLS AES-128 reads round keys via
    'ldrd Rt,Rt2,[Rn,#-32]' (U=0), so the cipher output was corrupt and
    SecurityAccess key verification looped forever. Added add_imm to the
    Ldrd/Strd instruction types and apply wrapping_sub when U=0.

  LDR/STR (immediate) T4 indexed (0xF85x / 0xF84x, h2[11]=1)
    The pre/post-indexed forms with base writeback were decoded as
    Unknown32. 'ldr.w pc, [sp], #4' is clang's function-return idiom;
    skipping it made boot_state_mark_pending return to the wrong address,
    passing target_bank=0 to flash_swap_to_bank_and_reset so SWAP_BANK was
    cleared instead of set and the bank-swap+reset never fired. Added
    LdrImm32Idx/StrImm32Idx with pre/post-index, add/sub and writeback;
    load-to-PC routes through branch_to.

The example drives the whole sequence on-chip over FDCAN internal
loopback (DiagSession -> SecurityAccess -> Erase -> Download ->
TransferData -> ActivateSoftware swap+reset -> boot APP-B v2).

cargo test -p labwired-core --lib: 1407 passed
cargo fmt --check + cargo clippy -D warnings: clean
@w1ne w1ne merged commit 5f7a288 into main Jun 22, 2026
13 checks passed
@w1ne w1ne deleted the feat/h563-ota-sim-smoke branch June 22, 2026 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant