ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_dfu_boot.c File Reference

Pure boot logic for the USB-DFU MRAM bootloader core. More...

#include "ra8_dfu.h"
Include dependency graph for ra8_dfu_boot.c:

Go to the source code of this file.

Enumerations

enum  ra8_dfu_crc_const_t : uint32_t {
  k_ra8_dfu_crc_init = 0xFFFFFFFFU ,
  k_ra8_dfu_crc_poly = 0xEDB88320U ,
  k_ra8_dfu_crc_xout = 0xFFFFFFFFU ,
  k_ra8_dfu_crc_lsb = 0x00000001U
}
 IEEE-802.3 reflected-CRC32 parameters (poly / init / final XOR). More...
enum  ra8_dfu_crc_bits_t : uint8_t { k_ra8_dfu_crc_bits = 8U }
 Bits folded per input byte in the CRC32 inner loop. More...

Functions

uint32_t ra8_dfu_crc32 (const uint8_t *data, uint32_t len)
 Implementation of ra8_dfu_crc32() – bitwise reflected CRC32.
bool ra8_dfu_hdr_valid (const ra8_dfu_img_hdr_t *hdr, uint32_t computed_crc)
 Decide whether a slot header describes a valid bootable image.
bool ra8_dfu_run_target_valid (uint32_t entry, uint32_t img_len)
 Decide whether a validated slot's image may be copied-to-run.
ra8_dfu_slot_t ra8_dfu_select_slot (bool a_valid, uint32_t a_seq, bool b_valid, uint32_t b_seq)
 Pick the active slot from the two slots' validity + sequence.
ra8_dfu_action_t ra8_dfu_boot_decide (bool dfu_trigger, bool a_valid, uint32_t a_seq, bool b_valid, uint32_t b_seq)
 Reset-time boot decision: jump to a slot, or enter DFU.

Detailed Description

Pure boot logic for the USB-DFU MRAM bootloader core.

Tag
[Ring 4 / Service] {World: S}

Implements the host-testable half of ra8_dfu: software CRC32, image header validation, A/B slot selection, and the reset-time boot decision. No MMIO and no USB – every function is a pure transform of its arguments, exercised directly by tests/misc/src/test_ra8_dfu_boot.c with MC/DC vectors for each compound decision.

Definition in file ra8_dfu_boot.c.

Enumeration Type Documentation

◆ ra8_dfu_crc_bits_t

enum ra8_dfu_crc_bits_t : uint8_t

Bits folded per input byte in the CRC32 inner loop.

Enumerator
k_ra8_dfu_crc_bits 

One byte == eight shift iterations.

Definition at line 33 of file ra8_dfu_boot.c.

◆ ra8_dfu_crc_const_t

enum ra8_dfu_crc_const_t : uint32_t

IEEE-802.3 reflected-CRC32 parameters (poly / init / final XOR).

Enumerator
k_ra8_dfu_crc_init 

Shift-register preset.

k_ra8_dfu_crc_poly 

Reflected poly of 0x04C11DB7.

k_ra8_dfu_crc_xout 

Final output XOR.

k_ra8_dfu_crc_lsb 

Low-bit test mask.

Definition at line 25 of file ra8_dfu_boot.c.

Function Documentation

◆ ra8_dfu_boot_decide()

ra8_dfu_action_t ra8_dfu_boot_decide ( bool dfu_trigger,
bool a_valid,
uint32_t a_seq,
bool b_valid,
uint32_t b_seq )

Reset-time boot decision: jump to a slot, or enter DFU.

Returns k_ra8_dfu_action_dfu when the no-init DFU trigger is set or when neither slot is valid; otherwise maps ra8_dfu_select_slot onto a jump action. This is the single decision the bootloader's main branches on.

Parameters
[in]dfu_triggertrue iff the no-init SRAM DFU-request magic was set.
[in]a_validSlot A validity (ra8_dfu_hdr_valid result).
[in]a_seqSlot A header sequence number.
[in]b_validSlot B validity (ra8_dfu_hdr_valid result).
[in]b_seqSlot B header sequence number.
Returns
The action the bootloader should take.
Return values
k_ra8_dfu_action_dfuTrigger set, or no valid slot.
k_ra8_dfu_action_jump_aBoot Slot A.
k_ra8_dfu_action_jump_bBoot Slot B.
Precondition
Validity flags came from ra8_dfu_hdr_valid on the live headers.
dfu_trigger reflects the one-shot no-init magic read at reset.
Postcondition
No state is mutated.
The returned action is always a defined ra8_dfu_action_t value.
Note
Thread-safe (pure). Compound decision – MC/DC vectors in the test.
See also
ra8_dfu_select_slot
Since
0.1.0

Definition at line 87 of file ra8_dfu_boot.c.

References k_ra8_dfu_action_dfu, k_ra8_dfu_action_jump_a, k_ra8_dfu_action_jump_b, k_ra8_dfu_slot_a, k_ra8_dfu_slot_b, and ra8_dfu_select_slot().

Referenced by blc_decide().

◆ ra8_dfu_crc32()

uint32_t ra8_dfu_crc32 ( const uint8_t * data,
uint32_t len )

Implementation of ra8_dfu_crc32() – bitwise reflected CRC32.

Compute the IEEE-802.3 CRC32 of a byte range (software).

Definition at line 38 of file ra8_dfu_boot.c.

References k_ra8_dfu_crc_bits, k_ra8_dfu_crc_init, k_ra8_dfu_crc_lsb, k_ra8_dfu_crc_poly, and k_ra8_dfu_crc_xout.

Referenced by ra8_dfu_program_commit(), and ra8_dfu_slot_valid().

◆ ra8_dfu_hdr_valid()

bool ra8_dfu_hdr_valid ( const ra8_dfu_img_hdr_t * hdr,
uint32_t computed_crc )

Decide whether a slot header describes a valid bootable image.

A header is valid iff the magic matches, the length is a non-zero multiple of the 32-byte page within [k_ra8_dfu_page_size, k_ra8_dfu_img_max], and the supplied freshly-computed CRC equals the stored img_crc32. The caller computes computed_crc over the live slot image (ra8_dfu_crc32) before calling, so this function stays pure and host-testable.

Parameters
[in]hdrHeader to test (may be NULL -> invalid).
[in]computed_crcCRC32 the caller computed over the image body.
Returns
true iff the header + CRC describe a valid image.
Return values
trueMagic, length bounds/alignment, and CRC all pass.
falsehdr is NULL, or any check fails.
Precondition
computed_crc was produced by ra8_dfu_crc32 over exactly hdr->img_len bytes of the slot's image body.
The slot's image body is readable when the caller computes the CRC.
Postcondition
No state is mutated.
The caller's hdr pointer and computed_crc value are not modified.
Note
Thread-safe (pure). Carries compound boolean decisions – see the @par MC/DC: block in tests/misc/src/test_ra8_dfu_boot.c.
See also
ra8_dfu_select_slot
Since
0.1.0

Definition at line 55 of file ra8_dfu_boot.c.

References ra8_dfu_img_hdr_t::img_crc32, ra8_dfu_img_hdr_t::img_len, k_ra8_dfu_hdr_magic, k_ra8_dfu_img_max, k_ra8_dfu_page_size, and ra8_dfu_img_hdr_t::magic.

Referenced by ra8_dfu_slot_valid().

◆ ra8_dfu_run_target_valid()

bool ra8_dfu_run_target_valid ( uint32_t entry,
uint32_t img_len )

Decide whether a validated slot's image may be copied-to-run.

The boot-time cross-check before the bootloader copies a slot body to SRAM and launches it: the header's entry must be the fixed k_ra8_dfu_run_base (so the image was linked for the run base, and a corrupted entry is caught), and img_len must be a non-zero 32-byte multiple within [k_ra8_dfu_page_size, k_ra8_dfu_img_max] (so the copy length is sane and the image fits the SRAM run window). Pure – the bootloader still copies to the trusted k_ra8_dfu_run_base constant, never to entry itself.

Parameters
[in]entryThe candidate image's header entry field.
[in]img_lenThe candidate image's body length, bytes.
Returns
true iff the image may be copied to k_ra8_dfu_run_base and run.
Return values
trueentry == k_ra8_dfu_run_base and img_len is in range/aligned.
falseentry is not the run base, or img_len is zero / too large / not a 32-byte multiple.
Precondition
entry and img_len are the live header fields of a slot that already passed ra8_dfu_hdr_valid (magic + length + body CRC).
Neither entry nor img_len is taken from an untrusted external source without a prior ra8_dfu_hdr_valid check.
Postcondition
No state is mutated.
The bootloader never uses entry as the copy destination; this function only validates it against the trusted k_ra8_dfu_run_base.
Note
Thread-safe (pure). Compound decision – MC/DC vectors in the test.
See also
ra8_dfu_hdr_valid
Since
0.1.0

Definition at line 67 of file ra8_dfu_boot.c.

References k_ra8_dfu_img_max, k_ra8_dfu_page_size, and k_ra8_dfu_run_base.

Referenced by ra8_dfu_launch().

◆ ra8_dfu_select_slot()

ra8_dfu_slot_t ra8_dfu_select_slot ( bool a_valid,
uint32_t a_seq,
bool b_valid,
uint32_t b_seq )

Pick the active slot from the two slots' validity + sequence.

The valid slot with the higher sequence number wins; Slot A wins a tie (deterministic). If only one slot is valid, it wins; if neither is valid, k_ra8_dfu_slot_none is returned so the caller enters DFU.

Parameters
[in]a_validtrue iff Slot A passed ra8_dfu_hdr_valid.
[in]a_seqSlot A header sequence number.
[in]b_validtrue iff Slot B passed ra8_dfu_hdr_valid.
[in]b_seqSlot B header sequence number.
Returns
The selected slot, or k_ra8_dfu_slot_none.
Return values
k_ra8_dfu_slot_aA valid and (B invalid or a_seq >= b_seq).
k_ra8_dfu_slot_bB valid and (A invalid or b_seq > a_seq).
k_ra8_dfu_slot_noneNeither slot valid.
Precondition
a_valid / b_valid reflect a prior ra8_dfu_hdr_valid result.
a_seq / b_seq are the live header sequence values.
Postcondition
No state is mutated.
The returned slot identifier is always a defined ra8_dfu_slot_t value.
Note
Thread-safe (pure). Compound decision – MC/DC vectors in the test.
See also
ra8_dfu_boot_decide
Since
0.1.0

Definition at line 75 of file ra8_dfu_boot.c.

References k_ra8_dfu_slot_a, k_ra8_dfu_slot_b, and k_ra8_dfu_slot_none.

Referenced by blc_decide(), and ra8_dfu_boot_decide().