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

Canonical persistent metadata for the flash translation layer. More...

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_ftl.h"
Include dependency graph for ra8_ftl_checkpoint.c:

Go to the source code of this file.

Enumerations

enum  ra8_ftl_checkpoint_const_t : uint32_t {
  k_ck_magic = 0x4C544652U ,
  k_ck_legacy_magic_le = 0x46544C31U ,
  k_ck_legacy_magic_swapped = 0x314C5446U ,
  k_ck_version = 1U ,
  k_ck_header_bytes = 20U ,
  k_ck_crc_bytes = 4U ,
  k_ck_fixed_bytes = 24U ,
  k_ck_map_entry_bytes = 2U ,
  k_ck_pblock_entry_bytes = 5U ,
  k_ck_pblock_state_offset = 4U ,
  k_ck_off_version = 4U ,
  k_ck_off_header_bytes = 6U ,
  k_ck_off_total_bytes = 8U ,
  k_ck_off_logical_blocks = 12U ,
  k_ck_off_physical_blocks = 16U ,
  k_ck_scratch_bytes = 512U ,
  k_ck_bits_per_byte = 8U ,
  k_ck_byte_3_shift = 24U ,
  k_ck_bitmap_blocks = 4096U ,
  k_ck_crc_seed = 0xFFFFFFFFU ,
  k_ck_crc_poly = 0xEDB88320U
}
 Canonical wire-layout and validation constants. More...

Functions

static uint16_t internal_get_le16 (const uint8_t *in)
 Decode one canonical little-endian 16-bit field.
static uint32_t internal_get_le32 (const uint8_t *in)
 Decode one canonical little-endian 32-bit field.
static void internal_put_le16 (uint8_t *out, uint16_t value)
 Encode one canonical little-endian 16-bit field.
static void internal_put_le32 (uint8_t *out, uint32_t value)
 Encode one canonical little-endian 32-bit field.
static uint32_t internal_crc32 (const uint8_t *data, uint32_t length)
 Compute CRC-32/ISO-HDLC over a bounded byte span.
static bool internal_ranges_overlap (const void *first, uint32_t first_bytes, const void *second, uint32_t second_bytes)
 Fail closed when two byte ranges overlap or their endpoints wrap.
static ra8_err_t internal_ready (const ra8_ftl_t *ftl)
 Validate that a checkpoint-capable FTL handle is fully bound.
static ra8_err_t internal_size_values (uint32_t logical_blocks, uint32_t physical_blocks, uint32_t *out)
 Calculate the exact wire length with checked 32-bit arithmetic.
static ra8_err_t internal_disjoint (const ra8_ftl_t *ftl, const void *buffer, uint32_t buffer_bytes)
 Validate workspace and checkpoint-buffer non-aliasing.
static bool internal_bit_was_set (uint8_t *bitmap, uint32_t bit)
 Set one scratch-bitmap bit and report whether it was already set.
static bool internal_bit_is_set (const uint8_t *bitmap, uint32_t bit)
 Read one bit from the bounded scratch bitmap.
static ra8_err_t internal_window_mark (const ra8_ftl_t *ftl, uint32_t base, uint32_t count, uint16_t phys)
 Mark one mapped physical index against a bounded scratch window.
static ra8_err_t internal_native_window (const ra8_ftl_t *ftl, uint32_t base, uint32_t count)
 Validate one window of the live native mapping into scratch.
static ra8_err_t internal_validate_native (const ra8_ftl_t *ftl)
 Validate every live map/state invariant using bounded scratch windows.
static ra8_err_t internal_wire_window (const ra8_ftl_t *ftl, const uint8_t *buf, uint32_t map_offset, uint32_t pb_offset, uint32_t base, uint32_t count)
 Validate one canonical wire-map window into caller scratch.
static ra8_err_t internal_validate_wire (const ra8_ftl_t *ftl, const uint8_t *buf)
 Validate every canonical payload invariant without live mutation.
static ra8_err_t internal_validate_header (const ra8_ftl_t *ftl, const uint8_t *buf, uint32_t buf_len, uint32_t need)
 Validate the canonical header, exact length, geometry, and CRC.
static void internal_encode (const ra8_ftl_t *ftl, uint8_t *buf, uint32_t need)
 Encode a validated live state into the canonical byte layout.
static void internal_decode_commit (ra8_ftl_t *ftl, const uint8_t *buf)
 Commit an already validated canonical payload to both live tables.
ra8_err_t ra8_ftl_checkpoint_size (const ra8_ftl_t *ftl, uint32_t *size_out)
 Report the buffer size a checkpoint of this FTL requires, in bytes.
ra8_err_t ra8_ftl_checkpoint_save (const ra8_ftl_t *ftl, uint8_t *buf, uint32_t buf_len)
 Serialise the FTL's mapping state into a caller buffer.
ra8_err_t ra8_ftl_checkpoint_load (ra8_ftl_t *ftl, const uint8_t *buf, uint32_t buf_len)
 Restore FTL mapping state from a checkpoint produced by save.

Variables

static const char *const s_tag = "ra8_ftl_checkpoint"
 Module log tag.

Detailed Description

Canonical persistent metadata for the flash translation layer.

Tag
[Ring 4 / PAL] {World: NS}

Encodes FTL mapping state field-by-field in a versioned little-endian wire format. Restore is transactional: header, checksum, geometry, ranges, duplicate mappings, and map/state invariants are checked with the FTL's caller-owned 512-byte scratch block before either live table is modified.

Since
0.1.0

Definition in file ra8_ftl_checkpoint.c.

Enumeration Type Documentation

◆ ra8_ftl_checkpoint_const_t

enum ra8_ftl_checkpoint_const_t : uint32_t

Canonical wire-layout and validation constants.

All offsets are byte offsets from the checkpoint beginning. The trailer is CRC-32/ISO-HDLC over every preceding byte.

Since
0.1.0
Enumerator
k_ck_magic 

LE bytes RFTL.

k_ck_legacy_magic_le 

Legacy native LE FTL1 value.

k_ck_legacy_magic_swapped 

Legacy native BE FTL1 bytes.

k_ck_version 

Canonical format version.

k_ck_header_bytes 

Fixed version-1 header bytes.

k_ck_crc_bytes 

CRC-32 trailer bytes.

k_ck_fixed_bytes 

Header plus trailer.

k_ck_map_entry_bytes 

One LE16 physical-map entry.

k_ck_pblock_entry_bytes 

LE32 erase count plus state byte.

k_ck_pblock_state_offset 

State byte within one pblock record.

k_ck_off_version 

LE16 format version.

k_ck_off_header_bytes 

LE16 fixed-header size.

k_ck_off_total_bytes 

LE32 exact blob length.

k_ck_off_logical_blocks 

LE32 logical geometry.

k_ck_off_physical_blocks 

LE32 physical geometry.

k_ck_scratch_bytes 

Caller workspace guaranteed by FTL.

k_ck_bits_per_byte 

Bitmap packing factor.

k_ck_byte_3_shift 

Shift of byte three in a LE32.

k_ck_bitmap_blocks 

Physical indices per scratch window.

k_ck_crc_seed 

CRC initial/final XOR.

k_ck_crc_poly 

Reflected ISO-HDLC polynomial.

Definition at line 39 of file ra8_ftl_checkpoint.c.

Function Documentation

◆ internal_bit_is_set()

bool internal_bit_is_set ( const uint8_t * bitmap,
uint32_t bit )
static

Read one bit from the bounded scratch bitmap.

Derives a byte and mask from the physical-relative bit index.

Parameters
[in]bitmapCaller-owned packed ownership bitmap.
[in]bitZero-based bit index within the bitmap.
Returns
State of the selected bit.
Return values
trueThe selected bit is set.
falseThe selected bit is clear.
Precondition
bitmap contains at least bit / 8 + 1 readable bytes.
bit is relative to the current bounded scratch window.
Postcondition
No bitmap or external state is modified.
The result depends only on the selected input bit.
Note
Pure and thread-safe for immutable bitmap storage.
Since
Version 0.1.0

Definition at line 364 of file ra8_ftl_checkpoint.c.

References k_ck_bits_per_byte, and RA8_INTERNAL.

Referenced by internal_native_window(), and internal_wire_window().

◆ internal_bit_was_set()

bool internal_bit_was_set ( uint8_t * bitmap,
uint32_t bit )
static

Set one scratch-bitmap bit and report whether it was already set.

Derives the byte and mask from the physical-relative bit index, samples prior ownership, and then records ownership unconditionally.

Parameters
[in,out]bitmapCaller-owned packed ownership bitmap.
[in]bitZero-based bit index within the bitmap.
Returns
Prior state of the selected bit.
Return values
trueThe bit was already set, indicating duplicate ownership.
falseThe bit was clear before this call.
Precondition
bitmap contains at least bit / 8 + 1 writable bytes.
bit is relative to the current bounded scratch window.
Postcondition
The selected bit is set.
Every other bitmap bit is unchanged.
Note
Not thread-safe for concurrent access to the same bitmap byte.
Since
Version 0.1.0

Definition at line 340 of file ra8_ftl_checkpoint.c.

References k_ck_bits_per_byte, and RA8_INTERNAL.

Referenced by internal_window_mark().

◆ internal_crc32()

uint32_t internal_crc32 ( const uint8_t * data,
uint32_t length )
static

Compute CRC-32/ISO-HDLC over a bounded byte span.

Applies the reflected polynomial bit-by-bit from the standard seed and final complement, avoiding any mutable lookup table.

Parameters
[in]dataReadable bytes to hash.
[in]lengthNumber of bytes in data.
Returns
Finalized CRC-32 value.
Return values
UINT32_C(0)The span's finalized checksum is zero.
UINT32_MAXThe span's finalized checksum has every bit set.
Precondition
data addresses length readable bytes when non-zero.
The source remains stable throughout the bounded scan.
Postcondition
No source bytes or external state are modified.
Each source byte contributes exactly once in increasing address order.
Note
Pure and thread-safe for immutable input.
Since
Version 0.1.0

Definition at line 156 of file ra8_ftl_checkpoint.c.

References k_ck_bits_per_byte, k_ck_crc_poly, k_ck_crc_seed, and RA8_INTERNAL.

Referenced by internal_encode(), and internal_validate_header().

◆ internal_decode_commit()

void internal_decode_commit ( ra8_ftl_t * ftl,
const uint8_t * buf )
static

Commit an already validated canonical payload to both live tables.

Decodes all logical-map and physical-state records only after every structural and semantic validation pass has succeeded.

Parameters
[in,out]ftlDestination FTL whose live tables receive the checkpoint.
[in]bufFully validated, disjoint canonical checkpoint bytes.
Precondition
Wire header, CRC, mapping, state, and non-alias checks all succeeded.
Live table capacities match the geometry stored in ftl.
Postcondition
Every live map and physical-state entry matches buf.
Checkpoint bytes and unrelated FTL descriptor fields are unchanged.
Note
Not thread-safe; callers must exclude concurrent FTL operations.
Since
Version 0.1.0

Definition at line 678 of file ra8_ftl_checkpoint.c.

References ra8_ftl_pblock_t::erase_count, internal_get_le16(), internal_get_le32(), k_ck_header_bytes, k_ck_map_entry_bytes, k_ck_pblock_entry_bytes, k_ck_pblock_state_offset, ra8_ftl_t::logical_blocks, ra8_ftl_t::map, ra8_ftl_t::pblocks, ra8_ftl_t::physical_blocks, RA8_INTERNAL, and ra8_ftl_pblock_t::state.

Referenced by ra8_ftl_checkpoint_load().

◆ internal_disjoint()

ra8_err_t internal_disjoint ( const ra8_ftl_t * ftl,
const void * buffer,
uint32_t buffer_bytes )
static

Validate workspace and checkpoint-buffer non-aliasing.

Proves scratch, live map, live physical table, and the candidate checkpoint span are disjoint before transactional encode or decode.

Parameters
[in]ftlInitialized FTL descriptor and caller-owned spans.
[in]bufferCandidate checkpoint source or destination.
[in]buffer_bytesBytes the operation will access in buffer.
Returns
Alias validation status.
Return values
k_ra8_okEvery accessed span is disjoint.
k_ra8_err_invalid_stateInternal FTL workspaces overlap.
k_ra8_err_invalid_argThe checkpoint buffer aliases FTL state.
Precondition
FTL geometry has been validated and sizes both live tables.
buffer addresses buffer_bytes accessible bytes.
Postcondition
No buffer or FTL state is modified.
Success permits scratch use without corrupting input or live tables.
Note
Pure and thread-safe for immutable descriptors.
Since
Version 0.1.0

Definition at line 303 of file ra8_ftl_checkpoint.c.

References internal_ranges_overlap(), k_ck_scratch_bytes, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, ra8_ftl_t::logical_blocks, ra8_ftl_t::map, ra8_ftl_t::pblocks, ra8_ftl_t::physical_blocks, and ra8_ftl_t::scratch.

Referenced by ra8_ftl_checkpoint_load(), and ra8_ftl_checkpoint_save().

◆ internal_encode()

void internal_encode ( const ra8_ftl_t * ftl,
uint8_t * buf,
uint32_t need )
static

Encode a validated live state into the canonical byte layout.

Writes the fixed header, logical map, physical records, and final CRC explicitly in little-endian order into disjoint caller storage.

Parameters
[in]ftlFully validated live FTL state.
[out]bufDisjoint checkpoint destination.
[in]needExact destination and wire length in bytes.
Precondition
buf addresses at least need writable bytes.
Live map/state validation succeeded and all spans are disjoint.
Postcondition
Exactly need bytes contain one canonical checkpoint.
Live FTL map and physical-state tables are unchanged.
Note
Not thread-safe with concurrent mutation of the live FTL state.
Since
Version 0.1.0

Definition at line 644 of file ra8_ftl_checkpoint.c.

References ra8_ftl_pblock_t::erase_count, internal_crc32(), internal_put_le16(), internal_put_le32(), k_ck_header_bytes, k_ck_magic, k_ck_map_entry_bytes, k_ck_off_header_bytes, k_ck_off_logical_blocks, k_ck_off_physical_blocks, k_ck_off_total_bytes, k_ck_off_version, k_ck_pblock_entry_bytes, k_ck_pblock_state_offset, k_ck_version, ra8_ftl_t::logical_blocks, ra8_ftl_t::map, ra8_ftl_t::pblocks, ra8_ftl_t::physical_blocks, RA8_INTERNAL, and ra8_ftl_pblock_t::state.

Referenced by ra8_ftl_checkpoint_save().

◆ internal_get_le16()

uint16_t internal_get_le16 ( const uint8_t * in)
static

Decode one canonical little-endian 16-bit field.

Combines two octets explicitly without alignment or host-endian assumptions.

Parameters
[in]inReadable two-byte wire field.
Returns
Host-order unsigned value.
Return values
UINT16_C(0)Both source bytes are zero.
UINT16_MAXBoth source bytes are 0xff.
Precondition
in addresses at least two readable bytes.
The source remains stable during both byte reads.
Postcondition
No memory is modified.
The result is the exact canonical little-endian decoding.
Note
Pure and thread-safe for immutable input.
Since
Version 0.1.0

Definition at line 77 of file ra8_ftl_checkpoint.c.

References RA8_INTERNAL.

Referenced by internal_decode_commit(), internal_validate_header(), and internal_wire_window().

◆ internal_get_le32()

uint32_t internal_get_le32 ( const uint8_t * in)
static

Decode one canonical little-endian 32-bit field.

Combines four octets explicitly without alignment or host-endian assumptions.

Parameters
[in]inReadable four-byte wire field.
Returns
Host-order unsigned value.
Return values
UINT32_C(0)All source bytes are zero.
UINT32_MAXAll source bytes are 0xff.
Precondition
in addresses at least four readable bytes.
The source remains stable during all byte reads.
Postcondition
No memory is modified.
The result is the exact canonical little-endian decoding.
Note
Pure and thread-safe for immutable input.
Since
Version 0.1.0

Definition at line 96 of file ra8_ftl_checkpoint.c.

References k_ck_byte_3_shift, and RA8_INTERNAL.

Referenced by internal_decode_commit(), and internal_validate_header().

◆ internal_native_window()

ra8_err_t internal_native_window ( const ra8_ftl_t * ftl,
uint32_t base,
uint32_t count )
static

Validate one window of the live native mapping into scratch.

Marks mapped physical blocks within the window, rejects duplicates and out-of-range indices, then cross-checks every physical state.

Parameters
[in]ftlInitialized live FTL state.
[in]baseFirst physical-block index in the window.
[in]countNumber of physical blocks represented by scratch.
Returns
Live-window validation status.
Return values
k_ra8_okMap ownership and physical states agree in the window.
k_ra8_err_invalid_stateA map index, duplicate, or state is invalid.
Precondition
count is non-zero and at most k_ck_bitmap_blocks.
base + count does not exceed ftl->physical_blocks.
Postcondition
Scratch contains the final ownership bitmap for this window.
Live map and physical-state tables are unchanged.
Note
Not thread-safe; overwrites the shared FTL scratch workspace.
Since
Version 0.1.0

Definition at line 427 of file ra8_ftl_checkpoint.c.

References internal_bit_is_set(), internal_window_mark(), k_ck_scratch_bytes, k_ra8_err_invalid_state, k_ra8_ftl_pstate_live, k_ra8_ftl_pstate_stale, k_ra8_ftl_unmapped, k_ra8_ok, ra8_ftl_t::logical_blocks, ra8_ftl_t::map, memset(), ra8_ftl_t::pblocks, ra8_ftl_t::scratch, and ra8_ftl_pblock_t::state.

Referenced by internal_validate_native().

◆ internal_put_le16()

void internal_put_le16 ( uint8_t * out,
uint16_t value )
static

Encode one canonical little-endian 16-bit field.

Stores the low octet first to make the checkpoint host independent.

Parameters
[out]outWritable two-byte wire field.
[in]valueHost-order value to encode.
Precondition
out addresses at least two writable bytes.
The destination is not concurrently accessed.
Postcondition
Exactly two destination bytes contain value in little-endian order.
Bytes outside the two-byte field are unchanged.
Note
Thread-safe for disjoint caller-owned destinations.
Since
Version 0.1.0

Definition at line 114 of file ra8_ftl_checkpoint.c.

References RA8_INTERNAL.

Referenced by internal_encode().

◆ internal_put_le32()

void internal_put_le32 ( uint8_t * out,
uint32_t value )
static

Encode one canonical little-endian 32-bit field.

Stores four low-to-high octets to make the checkpoint host independent.

Parameters
[out]outWritable four-byte wire field.
[in]valueHost-order value to encode.
Precondition
out addresses at least four writable bytes.
The destination is not concurrently accessed.
Postcondition
Exactly four destination bytes contain value in little-endian order.
Bytes outside the four-byte field are unchanged.
Note
Thread-safe for disjoint caller-owned destinations.
Since
Version 0.1.0

Definition at line 132 of file ra8_ftl_checkpoint.c.

References k_ck_byte_3_shift, and RA8_INTERNAL.

Referenced by internal_encode().

◆ internal_ranges_overlap()

bool internal_ranges_overlap ( const void * first,
uint32_t first_bytes,
const void * second,
uint32_t second_bytes )
static

Fail closed when two byte ranges overlap or their endpoints wrap.

Uses inclusive integer-address endpoints after checking subtraction and addition bounds; an unrepresentable non-empty span is unsafe.

Parameters
[in]firstBase of the first candidate span.
[in]first_bytesLength of the first span in bytes.
[in]secondBase of the second candidate span.
[in]second_bytesLength of the second span in bytes.
Returns
Whether the spans overlap or cannot be represented safely.
Return values
trueThe spans overlap or at least one endpoint would wrap.
falseOne span is empty or both non-empty spans are disjoint.
Precondition
Non-zero lengths truthfully describe accessible object spans.
Pointer-to-integer conversion preserves address ordering on the target.
Postcondition
No memory or external state is modified.
A false result proves both non-empty endpoints were representable.
Note
Pure and thread-safe.
Since
Version 0.1.0

Definition at line 187 of file ra8_ftl_checkpoint.c.

References RA8_INTERNAL.

Referenced by internal_disjoint().

◆ internal_ready()

ra8_err_t internal_ready ( const ra8_ftl_t * ftl)
static

Validate that a checkpoint-capable FTL handle is fully bound.

Requires the raw block device, logical map, physical-state table, and fixed scratch workspace installed by FTL initialization.

Parameters
[in]ftlFTL handle to inspect.
Returns
Readiness status.
Return values
k_ra8_okEvery checkpoint dependency is bound.
k_ra8_err_not_initializedAt least one required pointer is NULL.
Precondition
ftl addresses a readable FTL descriptor.
The descriptor is not concurrently initialized or deinitialized.
Postcondition
No FTL or backing storage state is modified.
Success establishes non-NULL storage for later validation passes.
Note
Thread-safe only with external FTL lifecycle synchronization.
Since
Version 0.1.0

Definition at line 229 of file ra8_ftl_checkpoint.c.

References k_ra8_err_not_initialized, k_ra8_ok, ra8_ftl_t::map, ra8_ftl_t::pblocks, RA8_INTERNAL, ra8_ftl_t::raw, and ra8_ftl_t::scratch.

Referenced by ra8_ftl_checkpoint_size().

◆ internal_size_values()

ra8_err_t internal_size_values ( uint32_t logical_blocks,
uint32_t physical_blocks,
uint32_t * out )
static

Calculate the exact wire length with checked 32-bit arithmetic.

Adds fixed bytes, logical-map entries, and physical-state records only after proving both multiplications and sums fit in uint32_t.

Parameters
[in]logical_blocksLogical block count to encode.
[in]physical_blocksPhysical block count to encode.
[out]outReceives the exact checkpoint length.
Returns
Geometry sizing status.
Return values
k_ra8_okThe geometry is valid and out was written.
k_ra8_err_invalid_sizeGeometry is invalid or the length overflows.
Precondition
out addresses a writable uint32_t object.
Counts are candidate FTL geometry expressed in blocks.
Postcondition
Success stores the exact canonical wire length in out.
Failure leaves out unchanged.
Note
Pure apart from caller output and thread-safe for disjoint output.
Since
Version 0.1.0

Definition at line 261 of file ra8_ftl_checkpoint.c.

References k_ck_fixed_bytes, k_ck_map_entry_bytes, k_ck_pblock_entry_bytes, k_ra8_err_invalid_size, k_ra8_ftl_max_pblocks, and k_ra8_ok.

Referenced by ra8_ftl_checkpoint_size().

◆ internal_validate_header()

ra8_err_t internal_validate_header ( const ra8_ftl_t * ftl,
const uint8_t * buf,
uint32_t buf_len,
uint32_t need )
static

Validate the canonical header, exact length, geometry, and CRC.

Rejects legacy byte orders, unknown version/header geometry, length mismatch, different FTL geometry, and any trailer checksum mismatch.

Parameters
[in]ftlInitialized destination FTL geometry.
[in]bufCandidate checkpoint bytes.
[in]buf_lenAccessible candidate length in bytes.
[in]needExact length computed for ftl.
Returns
Header and integrity validation status.
Return values
k_ra8_okHeader, geometry, length, and CRC are valid.
k_ra8_err_not_supportedThe checkpoint uses a legacy or unknown version.
k_ra8_err_invalid_stateMagic is not the canonical format magic.
k_ra8_err_invalid_sizeHeader or total length is inconsistent.
k_ra8_err_invalid_argStored geometry differs from ftl.
k_ra8_err_crc_mismatchPayload integrity verification failed.
Precondition
buf addresses buf_len readable bytes.
need was computed by internal_size_values for ftl.
Postcondition
Neither checkpoint bytes nor live FTL state are modified.
Success permits semantic payload validation at the derived offsets.
Note
Pure and thread-safe for immutable inputs.
Since
Version 0.1.0

Definition at line 588 of file ra8_ftl_checkpoint.c.

References internal_crc32(), internal_get_le16(), internal_get_le32(), k_ck_crc_bytes, k_ck_fixed_bytes, k_ck_header_bytes, k_ck_legacy_magic_le, k_ck_legacy_magic_swapped, k_ck_magic, k_ck_off_header_bytes, k_ck_off_logical_blocks, k_ck_off_physical_blocks, k_ck_off_total_bytes, k_ck_off_version, k_ck_version, k_ra8_err_crc_mismatch, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_not_supported, k_ra8_ok, ra8_ftl_t::logical_blocks, and ra8_ftl_t::physical_blocks.

Referenced by ra8_ftl_checkpoint_load().

◆ internal_validate_native()

ra8_err_t internal_validate_native ( const ra8_ftl_t * ftl)
static

Validate every live map/state invariant using bounded scratch windows.

Partitions physical geometry into fixed 4096-block bitmap windows, allowing duplicate and live-state checks with exactly 512 bytes.

Parameters
[in]ftlInitialized live FTL state.
Returns
Complete live-state validation status.
Return values
k_ra8_okEvery physical window satisfies the mapping invariants.
k_ra8_err_invalid_stateA window contains invalid ownership or state.
Precondition
FTL geometry and all live-table capacities are valid.
ftl->scratch addresses at least k_ck_scratch_bytes writable bytes.
Postcondition
Live map and physical-state tables are unchanged.
Scratch contains data from the final validated or failing window.
Note
Not thread-safe; serial access to FTL scratch is required.
Since
Version 0.1.0

Definition at line 467 of file ra8_ftl_checkpoint.c.

References internal_native_window(), k_ck_bitmap_blocks, k_ra8_ok, ra8_ftl_t::physical_blocks, and RA8_INTERNAL.

Referenced by ra8_ftl_checkpoint_save().

◆ internal_validate_wire()

ra8_err_t internal_validate_wire ( const ra8_ftl_t * ftl,
const uint8_t * buf )
static

Validate every canonical payload invariant without live mutation.

Walks the full physical geometry through bounded scratch windows, proving map uniqueness and exact live-state correspondence.

Parameters
[in]ftlInitialized FTL geometry and scratch workspace.
[in]bufHeader-validated canonical checkpoint bytes.
Returns
Complete wire-payload validation status.
Return values
k_ra8_okEvery map entry and physical state is canonical.
k_ra8_err_invalid_stateA payload invariant fails.
Precondition
Header and exact wire length were validated for this FTL geometry.
buf remains readable throughout all bounded passes.
Postcondition
Live map and physical-state tables are unchanged.
Scratch contains data from the final validated or failing window.
Note
Not thread-safe; serial access to FTL scratch is required.
Since
Version 0.1.0

Definition at line 549 of file ra8_ftl_checkpoint.c.

References internal_wire_window(), k_ck_bitmap_blocks, k_ck_header_bytes, k_ck_map_entry_bytes, k_ra8_ok, ra8_ftl_t::logical_blocks, ra8_ftl_t::physical_blocks, and RA8_INTERNAL.

Referenced by ra8_ftl_checkpoint_load().

◆ internal_window_mark()

ra8_err_t internal_window_mark ( const ra8_ftl_t * ftl,
uint32_t base,
uint32_t count,
uint16_t phys )
static

Mark one mapped physical index against a bounded scratch window.

Rejects an index outside the physical geometry outright; an index outside the current window is left for a later window's pass and reported as legal here. An index inside the window is rejected only if some earlier map entry already claimed it.

Parameters
[in]ftlInitialized FTL geometry and scratch workspace.
[in]baseFirst physical-block index in the window.
[in]countNumber of physical blocks represented by scratch.
[in]physPhysical block index read from one map entry.
Returns
Map-entry validation status.
Return values
k_ra8_okThe index is legal; scratch gained a mark when in-window.
k_ra8_err_invalid_stateThe index is out of range or a duplicate.
Precondition
phys was read from a live or canonical wire map entry.
ftl->scratch addresses the same window as every other call this pass.
Postcondition
Scratch gains one marked bit when phys falls in the window.
No FTL geometry, map, or media state outside the scratch bitmap is modified.
Note
Not thread-safe; shares the caller's scratch workspace.
Since
Version 0.1.0

Definition at line 392 of file ra8_ftl_checkpoint.c.

References internal_bit_was_set(), k_ra8_err_invalid_state, k_ra8_ok, ra8_ftl_t::physical_blocks, and ra8_ftl_t::scratch.

Referenced by internal_native_window(), and internal_wire_window().

◆ internal_wire_window()

ra8_err_t internal_wire_window ( const ra8_ftl_t * ftl,
const uint8_t * buf,
uint32_t map_offset,
uint32_t pb_offset,
uint32_t base,
uint32_t count )
static

Validate one canonical wire-map window into caller scratch.

Decodes map entries and physical-state bytes directly from canonical wire storage, marking only the requested physical window in scratch.

Parameters
[in]ftlInitialized FTL geometry and scratch workspace.
[in]bufValidated canonical checkpoint bytes.
[in]map_offsetByte offset of the logical map.
[in]pb_offsetByte offset of the physical-state table.
[in]baseFirst physical-block index in the window.
[in]countPhysical blocks represented by the window.
Returns
Wire-window validation status.
Return values
k_ra8_okWire ownership and state agree in the window.
k_ra8_err_invalid_stateAn index, duplicate, or state is invalid.
Precondition
Header validation proved all derived wire offsets are in range.
count is non-zero, bounded by scratch, and within geometry.
Postcondition
Scratch contains the wire ownership bitmap for this window.
Checkpoint bytes and live FTL tables are unchanged.
Note
Not thread-safe; overwrites shared FTL scratch.
Since
Version 0.1.0

Definition at line 501 of file ra8_ftl_checkpoint.c.

References internal_bit_is_set(), internal_get_le16(), internal_window_mark(), k_ck_map_entry_bytes, k_ck_pblock_entry_bytes, k_ck_pblock_state_offset, k_ck_scratch_bytes, k_ra8_err_invalid_state, k_ra8_ftl_pstate_live, k_ra8_ftl_pstate_stale, k_ra8_ftl_unmapped, k_ra8_ok, ra8_ftl_t::logical_blocks, memset(), RA8_INTERNAL, and ra8_ftl_t::scratch.

Referenced by internal_validate_wire().

◆ ra8_ftl_checkpoint_load()

ra8_err_t ra8_ftl_checkpoint_load ( ra8_ftl_t * ftl,
const uint8_t * buf,
uint32_t buf_len )
nodiscard

Restore FTL mapping state from a checkpoint produced by save.

Validates buf as an exact-length checkpoint whose version and geometry match ftl, verifies its CRC, and rejects out-of-range or duplicate map entries, invalid states, unreferenced LIVE blocks, and references to non-LIVE blocks. Validation uses fixed windows in the FTL's caller-owned scratch block before the saved map and pblocks values are committed, so a freshly ra8_ftl_init handle resumes the exact mapping it had when the checkpoint was taken. Call ra8_ftl_init first (to re-bind the underlying device and re-establish geometry), then this to overwrite the cold-start tables with the persisted state; the underlying data blocks are untouched, so a subsequent read of any logical block returns its pre-reset contents.

Legacy native-layout checkpoints are recognized in either byte order but rejected as unsupported: their producer ABI and padding cannot be recovered safely from the blob.

Parameters
[in,out]ftlHandle freshly initialised by ra8_ftl_init.
[in]bufCheckpoint buffer from ra8_ftl_checkpoint_save.
[in]buf_lenNumber of valid bytes in buf.
Returns
ra8_err_t Error code.
Return values
k_ra8_okMapping state restored.
k_ra8_err_null_ptrftl or buf was NULL.
k_ra8_err_not_initializedftl was not initialised.
k_ra8_err_invalid_sizebuf_len is not the exact encoded length.
k_ra8_err_invalid_stateThe buffer is not an FTL checkpoint (bad magic or mapping invariant).
k_ra8_err_invalid_argThe checkpoint geometry does not match ftl, or input aliases live/scratch state.
k_ra8_err_not_supportedUnknown version or recognized legacy ABI.
k_ra8_err_crc_mismatchCheckpoint bytes fail their CRC-32 trailer.
Precondition
ftl was re-initialised by ra8_ftl_init over the retained device.
buf holds exactly one checkpoint and does not overlap the FTL map, physical-block table, or scratch block.
Postcondition
On success map/pblocks mirror the checkpointed state.
On any non-ok return the cold-start tables are left as ra8_ftl_init set them.
Note
Not thread-safe with respect to the data path.
See also
ra8_ftl_checkpoint_save
Since
0.1.0

Definition at line 733 of file ra8_ftl_checkpoint.c.

References internal_decode_commit(), internal_disjoint(), internal_validate_header(), internal_validate_wire(), k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_ftl_checkpoint_size(), and s_tag.

Referenced by demo_restore().

◆ ra8_ftl_checkpoint_save()

ra8_err_t ra8_ftl_checkpoint_save ( const ra8_ftl_t * ftl,
uint8_t * buf,
uint32_t buf_len )
nodiscard

Serialise the FTL's mapping state into a caller buffer.

Writes a self-describing checkpoint of the volatile mapping tables (map and pblocks) into buf: a versioned little-endian header (magic, exact length, and geometry), individually encoded map and physical-block records, and a CRC-32/ISO-HDLC trailer. Persisting this blob to a non-volatile region of the underlying device and reloading it after a reset (see ra8_ftl_checkpoint_load) is what lets logical data survive a power cycle – the FTL keeps no on-media metadata of its own, so without a checkpoint a cold re-init cannot resolve which physical block holds which logical block.

Version 1 is canonical across architectures: no native object representation or struct padding is copied. The pre-versioned native-layout format is deliberately not migrated because its producer ABI cannot be proven from the bytes; load identifies either legacy byte order and fails closed with k_ra8_err_not_supported.

Parameters
[in]ftlInitialised FTL handle.
[out]bufDestination buffer (>= ra8_ftl_checkpoint_size bytes).
[in]buf_lenCapacity of buf in bytes.
Returns
ra8_err_t Error code.
Return values
k_ra8_okCheckpoint written into buf.
k_ra8_err_null_ptrftl or buf was NULL.
k_ra8_err_not_initializedftl was not initialised.
k_ra8_err_invalid_sizebuf_len is smaller than the checkpoint.
k_ra8_err_invalid_argOutput aliases FTL tables or scratch.
k_ra8_err_invalid_stateLive mapping invariants are corrupt.
Precondition
ftl was initialised by ra8_ftl_init.
buf is writable for at least buf_len bytes and does not overlap the FTL map, physical-block table, or scratch block.
Postcondition
On success buf[0 .. checkpoint_size) holds a loadable checkpoint.
On any non-ok return buf is left unchanged.
Note
Not thread-safe with respect to the data path.
See also
ra8_ftl_checkpoint_load
ra8_ftl_checkpoint_size
Since
0.1.0

Definition at line 709 of file ra8_ftl_checkpoint.c.

References internal_disjoint(), internal_encode(), internal_validate_native(), k_ra8_err_invalid_size, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_ftl_checkpoint_size(), and s_tag.

Referenced by demo_checkpoint().

◆ ra8_ftl_checkpoint_size()

ra8_err_t ra8_ftl_checkpoint_size ( const ra8_ftl_t * ftl,
uint32_t * size_out )
nodiscard

Report the buffer size a checkpoint of this FTL requires, in bytes.

A checkpoint captures the FTL's volatile mapping state (the map and pblocks tables) so it can be persisted to non-volatile media and reloaded after a reset. This returns the exact byte count ra8_ftl_checkpoint_save needs for the current geometry: a fixed canonical header, two bytes per map entry, five bytes per physical-block entry, and a CRC-32 trailer. The value is independent of compiler padding, native integer layout, and host byte order, and is stable for a given initialised handle.

Parameters
[in]ftlInitialised FTL handle.
[out]size_outReceives the required checkpoint size in bytes.
Returns
ra8_err_t Error code.
Return values
k_ra8_ok*size_out populated.
k_ra8_err_null_ptrftl or size_out was NULL.
k_ra8_err_not_initializedftl was not initialised.
Precondition
ftl was initialised by ra8_ftl_init.
size_out is writable.
Postcondition
On success *size_out > 0.
No FTL or device state is mutated.
Note
Thread-safe (pure computation over immutable geometry).
See also
ra8_ftl_checkpoint_save
ra8_ftl_checkpoint_load
Since
0.1.0

Definition at line 692 of file ra8_ftl_checkpoint.c.

References internal_ready(), internal_size_values(), k_ra8_ok, ra8_ftl_t::logical_blocks, ra8_ftl_t::physical_blocks, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by demo_checkpoint(), ra8_ftl_checkpoint_load(), and ra8_ftl_checkpoint_save().

Variable Documentation

◆ s_tag

const char* const s_tag = "ra8_ftl_checkpoint"
static

Module log tag.

Definition at line 30 of file ra8_ftl_checkpoint.c.