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

Block-device dispatcher – forwards each public call into the bound backend vtable, and bridges any backend to an ra8_fs_backend_t. More...

#include "ra8_io_blockdev.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_fs.h"
#include "ra8_io_blockdev_backend.h"
#include "ra8_log.h"
Include dependency graph for ra8_io_blockdev.c:

Go to the source code of this file.

Functions

static ra8_err_t internal_validate (const ra8_io_blockdev_t *bd)
 Reject a handle that is NULL or has no backend bound.
ra8_err_t ra8_io_blockdev_read (const ra8_io_blockdev_t *bd, uint32_t lba, uint32_t count, uint8_t *buf)
 Read count logical blocks starting at lba into buf.
ra8_err_t ra8_io_blockdev_write (const ra8_io_blockdev_t *bd, uint32_t lba, uint32_t count, const uint8_t *buf)
 Write count logical blocks from buf starting at lba.
ra8_err_t ra8_io_blockdev_erase (const ra8_io_blockdev_t *bd, uint32_t lba, uint32_t count)
 Erase count blocks starting at lba to the medium's erase value.
ra8_err_t ra8_io_blockdev_get_caps (const ra8_io_blockdev_t *bd, ra8_io_blockdev_caps_t *out)
 Report the bound backend's medium capabilities.
ra8_err_t ra8_io_blockdev_sync (const ra8_io_blockdev_t *bd)
 Flush any backend write buffering to the medium.
static ra8_err_t internal_fs_read (void *ctx, uint64_t lba, uint32_t count, uint8_t *buf)
 ra8_fs read trampoline – forward into the bound block device.
static ra8_err_t internal_fs_write (void *ctx, uint64_t lba, uint32_t count, const uint8_t *buf)
 ra8_fs write trampoline – forward into the bound block device.
static ra8_err_t internal_fs_get_capacity (void *ctx, uint64_t *block_count, uint32_t *block_size)
 ra8_fs capacity trampoline – map block-device caps to (count, size).
static ra8_err_t internal_fs_erase (void *ctx, uint64_t lba, uint64_t count)
 ra8_fs erase trampoline – only advertise erase on zero-erase media.
ra8_err_t ra8_io_blockdev_as_fs_backend (const ra8_io_blockdev_t *bd, ra8_fs_backend_t *out)
 Expose a bound block device as an ra8_fs_backend_t for ra8_fs.

Variables

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

Detailed Description

Block-device dispatcher – forwards each public call into the bound backend vtable, and bridges any backend to an ra8_fs_backend_t.

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

Stateless dispatcher: it validates the handle, then forwards through the bound ra8_io_blockdev_iface. A NULL optional callback maps to a defined result (no erase => not-supported, no sync => success). The bridge installs static trampolines whose ctx is the ra8_io_blockdev_t itself.

Definition in file ra8_io_blockdev.c.

Function Documentation

◆ internal_fs_erase()

ra8_err_t internal_fs_erase ( void * ctx,
uint64_t lba,
uint64_t count )
static

ra8_fs erase trampoline – only advertise erase on zero-erase media.

ra8_fs's formatter requires an erased range to read back as 0x00. Flash media erase to 0xFF, so for those this returns k_ra8_err_not_supported and the formatter falls back to writing zeros explicitly.

Parameters
[in]ctxThe ra8_io_blockdev_t handle (as a void cookie).
[in]lbaFirst logical block address.
[in]countNumber of blocks to erase.
Returns
ra8_err_t Error code.
Return values
k_ra8_okRange erased to zero.
k_ra8_err_null_ptrctx was NULL.
k_ra8_err_not_supportedMedium does not erase to zero.
k_ra8_err_*Propagated from ra8_io_blockdev_erase.
Precondition
ctx is a bound ra8_io_blockdev_t.
count is non-zero for any observable effect.
Postcondition
On success the range reads back as 0x00.
On failure the device is untouched.
Note
Not thread-safe with respect to the same device.
Since
0.1.0

Definition at line 289 of file ra8_io_blockdev.c.

References ra8_io_blockdev_caps_t::erase_value, k_ra8_err_not_supported, k_ra8_err_out_of_range, k_ra8_io_erase_value_zero, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_io_blockdev_erase(), ra8_io_blockdev_get_caps(), and s_tag.

Referenced by ra8_io_blockdev_as_fs_backend().

◆ internal_fs_get_capacity()

ra8_err_t internal_fs_get_capacity ( void * ctx,
uint64_t * block_count,
uint32_t * block_size )
static

ra8_fs capacity trampoline – map block-device caps to (count, size).

Queries the block-device capabilities and reports block_count plus the 512-byte logical block size ra8_fs expects.

Parameters
[in]ctxThe ra8_io_blockdev_t handle (as a void cookie).
[out]block_countTotal blocks reported to ra8_fs.
[out]block_sizeBytes per block reported to ra8_fs (always 512).
Returns
ra8_err_t Error code.
Return values
k_ra8_okCapacity reported.
k_ra8_err_null_ptrAny pointer argument was NULL.
k_ra8_err_*Propagated from ra8_io_blockdev_get_caps.
Precondition
ctx is a bound ra8_io_blockdev_t.
block_count and block_size are writable.
Postcondition
On success both outputs describe the medium.
On failure the outputs are untouched.
Note
Thread-safe (pure read of immutable backend state).
Since
0.1.0

Definition at line 246 of file ra8_io_blockdev.c.

References ra8_io_blockdev_caps_t::block_count, k_ra8_ok, ra8_io_blockdev_caps_t::logical_block_bytes, RA8_CHECK_NULL_PTR, ra8_io_blockdev_get_caps(), and s_tag.

Referenced by ra8_io_blockdev_as_fs_backend(), and ra8_sdmmc_spi_bind_fs_backend().

◆ internal_fs_read()

ra8_err_t internal_fs_read ( void * ctx,
uint64_t lba,
uint32_t count,
uint8_t * buf )
static

ra8_fs read trampoline – forward into the bound block device.

Casts the ra8_fs cookie back to the block-device handle and dispatches the read.

Parameters
[in]ctxThe ra8_io_blockdev_t handle (as a void cookie).
[in]lbaFirst logical block address.
[in]countNumber of blocks to read.
[out]bufDestination buffer.
Returns
ra8_err_t Error code.
Return values
k_ra8_okBlocks read.
k_ra8_err_null_ptrctx or buf was NULL.
k_ra8_err_*Propagated from ra8_io_blockdev_read.
Precondition
ctx is a bound ra8_io_blockdev_t.
buf is writable for count * 512 bytes.
Postcondition
On success buf mirrors the device contents.
On failure buf is untouched by the fabric.
Note
Not thread-safe with respect to the same device.
Since
0.1.0

Definition at line 169 of file ra8_io_blockdev.c.

References k_ra8_err_out_of_range, RA8_CHECK_NULL_PTR, ra8_io_blockdev_read(), and s_tag.

Referenced by ra8_io_blockdev_as_fs_backend().

◆ internal_fs_write()

ra8_err_t internal_fs_write ( void * ctx,
uint64_t lba,
uint32_t count,
const uint8_t * buf )
static

ra8_fs write trampoline – forward into the bound block device.

Casts the ra8_fs cookie back to the block-device handle and dispatches the write.

Parameters
[in]ctxThe ra8_io_blockdev_t handle (as a void cookie).
[in]lbaFirst logical block address.
[in]countNumber of blocks to write.
[in]bufSource buffer.
Returns
ra8_err_t Error code.
Return values
k_ra8_okBlocks written.
k_ra8_err_null_ptrctx or buf was NULL.
k_ra8_err_*Propagated from ra8_io_blockdev_write.
Precondition
ctx is a bound ra8_io_blockdev_t.
buf is readable for count * 512 bytes.
Postcondition
On success the device blocks equal buf.
On failure the device is untouched by the fabric.
Note
Not thread-safe with respect to the same device.
Since
0.1.0

Definition at line 210 of file ra8_io_blockdev.c.

References k_ra8_err_out_of_range, RA8_CHECK_NULL_PTR, ra8_io_blockdev_write(), and s_tag.

Referenced by ra8_io_blockdev_as_fs_backend().

◆ internal_validate()

ra8_err_t internal_validate ( const ra8_io_blockdev_t * bd)
static

Reject a handle that is NULL or has no backend bound.

Run on every dispatch path. Kept tiny so each public entry point stays well under the NASA Power-of-10 Rule 4 sixty-line cap.

Parameters
[in]bdCandidate handle.
Returns
ra8_err_t Error code.
Return values
k_ra8_okbd is non-NULL with a bound backend.
k_ra8_err_null_ptrbd was NULL.
k_ra8_err_not_initializedbd->iface was NULL (never bound).
Precondition
None.
None.
Postcondition
No state is mutated.
The return reflects only the binding state of bd.
Note
Thread-safe.
Since
0.1.0

Definition at line 62 of file ra8_io_blockdev.c.

References ra8_io_blockdev_t::iface, k_ra8_err_not_initialized, k_ra8_err_null_ptr, and k_ra8_ok.

Referenced by mdl_storage_vfs_init(), ra8_io_blockdev_as_fs_backend(), ra8_io_blockdev_erase(), ra8_io_blockdev_get_caps(), ra8_io_blockdev_read(), ra8_io_blockdev_sync(), and ra8_io_blockdev_write().

◆ ra8_io_blockdev_as_fs_backend()

ra8_err_t ra8_io_blockdev_as_fs_backend ( const ra8_io_blockdev_t * bd,
ra8_fs_backend_t * out )
nodiscard

Expose a bound block device as an ra8_fs_backend_t for ra8_fs.

Fills out with trampolines that forward ra8_fs's read_block / write_block / get_capacity / erase_blocks calls into this fabric, with out->ctx pointing at bd. The erase trampoline advertises itself to the formatter only when the medium erases to zero (ra8_fs requires erased ranges to read back as 0x00); on all-ones flash it returns k_ra8_err_not_supported so the formatter falls back to writing zeros. After this call any existing ra8_fs API (ra8_fs_mount, ra8_fs_format, ...) works on the bound medium.

Parameters
[in]bdBound block-device handle (must out-live the filesystem use).
[out]outra8_fs_backend_t to populate.
Returns
ra8_err_t Error code.
Return values
k_ra8_ok*out wired to bd.
k_ra8_err_null_ptrbd or out was NULL.
k_ra8_err_not_initializedNo backend is bound to bd.
Precondition
A backend has been bound into bd.
out is writable and out-lives every filesystem call.
Postcondition
On success out's callbacks and ctx reference bd.
No device or handle state is mutated.
Note
bd must remain valid for the entire lifetime of the resulting mount.
Since
0.1.0

Definition at line 307 of file ra8_io_blockdev.c.

References ra8_fs_backend_t::ctx, ra8_fs_backend_t::erase_blocks, ra8_fs_backend_t::get_capacity, internal_fs_erase(), internal_fs_get_capacity(), internal_fs_read(), internal_fs_write(), internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_fs_backend_t::read_block, s_tag, and ra8_fs_backend_t::write_block.

Referenced by fileops_mount_volume(), internal_demo_mount(), internal_demo_mount(), internal_demo_probe_fat(), internal_demo_probe_foreign(), internal_swap_run_one(), ra8_io_roundtrip_mount(), sdhi_demo_mount_via_io(), selftest_mount_volume(), selftest_mount_volume(), selftest_mount_volume(), selftest_mount_volume(), and selftest_mount_volume().

◆ ra8_io_blockdev_erase()

ra8_err_t ra8_io_blockdev_erase ( const ra8_io_blockdev_t * bd,
uint32_t lba,
uint32_t count )
nodiscard

Erase count blocks starting at lba to the medium's erase value.

After a successful erase the range reads back as caps.erase_value (zero for RAM media, all-ones for NOR/MRAM). Backends whose medium has no erase concept may omit the operation, in which case this returns k_ra8_err_not_supported.

Parameters
[in]bdBound block-device handle.
[in]lbaFirst logical block address to erase.
[in]countNumber of consecutive blocks to erase.
Returns
ra8_err_t Error code.
Return values
k_ra8_okRange erased.
k_ra8_err_null_ptrbd was NULL.
k_ra8_err_not_initializedNo backend is bound to bd.
k_ra8_err_not_supportedThe backend has no erase primitive.
k_ra8_err_out_of_rangelba + count exceeds the device capacity.
Precondition
A backend has been bound into bd.
count is non-zero for any observable effect.
Postcondition
On success the range reads back as caps.erase_value.
On any non-ok return the device is left unchanged by the fabric.
Note
Not thread-safe with respect to the same device.
Since
0.1.0

Definition at line 102 of file ra8_io_blockdev.c.

References ra8_io_blockdev_t::ctx, ra8_io_blockdev_iface::erase, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_err_not_supported, and k_ra8_ok.

Referenced by demo_checkpoint(), internal_alloc_blank(), internal_cache_erase(), internal_demo_roundtrip(), internal_fs_erase(), and internal_reclaim_stale().

◆ ra8_io_blockdev_get_caps()

ra8_err_t ra8_io_blockdev_get_caps ( const ra8_io_blockdev_t * bd,
ra8_io_blockdev_caps_t * out )
nodiscard

Report the bound backend's medium capabilities.

Parameters
[in]bdBound block-device handle.
[out]outCapabilities snapshot.
Returns
ra8_err_t Error code.
Return values
k_ra8_ok*out populated.
k_ra8_err_null_ptrbd or out was NULL.
k_ra8_err_not_initializedNo backend is bound to bd.
Precondition
A backend has been bound into bd.
out is writable.
Postcondition
On success *out describes the bound medium.
No device or handle state is mutated.
Note
Thread-safe (pure read of immutable backend state).
Since
0.1.0

Definition at line 114 of file ra8_io_blockdev.c.

References ra8_io_blockdev_t::ctx, ra8_io_blockdev_iface::get_caps, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by internal_cache_get_caps(), internal_fs_erase(), internal_fs_get_capacity(), and ra8_ftl_init().

◆ ra8_io_blockdev_read()

ra8_err_t ra8_io_blockdev_read ( const ra8_io_blockdev_t * bd,
uint32_t lba,
uint32_t count,
uint8_t * buf )
nodiscard

Read count logical blocks starting at lba into buf.

Forwards to the bound backend's read primitive. buf must hold at least count * k_ra8_io_block_size_bytes bytes. Reading past the device capacity is rejected by the backend, not silently truncated.

Parameters
[in]bdBound block-device handle.
[in]lbaFirst logical block address to read.
[in]countNumber of consecutive blocks to read.
[out]bufDestination buffer (>= count * 512 bytes).
Returns
ra8_err_t Error code.
Return values
k_ra8_okBlocks read into buf.
k_ra8_err_null_ptrbd or buf was NULL.
k_ra8_err_not_initializedNo backend is bound to bd.
k_ra8_err_out_of_rangelba + count exceeds the device capacity.
k_ra8_err_invalid_argBackend rejected the request.
Precondition
A backend has been bound into bd.
buf is writable for count * 512 bytes.
Postcondition
On success buf[0 .. count*512) mirrors the device contents.
On any non-ok return buf is left unchanged by the fabric.
Note
Not thread-safe with respect to the same device.
Since
0.1.0

Definition at line 79 of file ra8_io_blockdev.c.

References ra8_io_blockdev_t::ctx, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_io_blockdev_iface::read, and s_tag.

Referenced by demo_reopen_naive(), demo_restore(), demo_write_verify(), fileops_probe_layout(), internal_bd_read_middle(), internal_bd_read_sector(), internal_cache_read_block(), internal_demo_roundtrip(), internal_fs_read(), and internal_read_one().

◆ ra8_io_blockdev_sync()

ra8_err_t ra8_io_blockdev_sync ( const ra8_io_blockdev_t * bd)
nodiscard

Flush any backend write buffering to the medium.

For buffered backends (e.g. a NOR write-coalescing shim) this commits pending data. Backends with no buffering treat it as a successful no-op.

Parameters
[in]bdBound block-device handle.
Returns
ra8_err_t Error code.
Return values
k_ra8_okPending writes committed (or none pending).
k_ra8_err_null_ptrbd was NULL.
k_ra8_err_not_initializedNo backend is bound to bd.
Precondition
A backend has been bound into bd.
The device is idle (no concurrent access).
Postcondition
On success the medium reflects every prior successful write.
No handle state is mutated.
Note
Not thread-safe with respect to the same device.
Since
0.1.0

Definition at line 125 of file ra8_io_blockdev.c.

References ra8_io_blockdev_t::ctx, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_ok, and ra8_io_blockdev_iface::sync.

Referenced by internal_cache_sync(), and internal_dev_sync().

◆ ra8_io_blockdev_write()

ra8_err_t ra8_io_blockdev_write ( const ra8_io_blockdev_t * bd,
uint32_t lba,
uint32_t count,
const uint8_t * buf )
nodiscard

Write count logical blocks from buf starting at lba.

Forwards to the bound backend's write primitive. On media that require an erase before programming the backend performs the necessary read-modify-write or erase internally; callers that want erase-aligned efficiency should use ra8_io_blockdev_erase plus aligned writes.

Parameters
[in]bdBound block-device handle.
[in]lbaFirst logical block address to write.
[in]countNumber of consecutive blocks to write.
[in]bufSource buffer (>= count * 512 bytes).
Returns
ra8_err_t Error code.
Return values
k_ra8_okBlocks written.
k_ra8_err_null_ptrbd or buf was NULL.
k_ra8_err_not_initializedNo backend is bound to bd.
k_ra8_err_out_of_rangelba + count exceeds the device capacity.
k_ra8_err_not_supportedThe device is read-only.
Precondition
A backend has been bound into bd.
buf is readable for count * 512 bytes.
Postcondition
On success the device blocks [lba, lba+count) equal buf.
On any non-ok return the device is left unchanged by the fabric.
Note
Not thread-safe with respect to the same device.
Since
0.1.0

Definition at line 91 of file ra8_io_blockdev.c.

References ra8_io_blockdev_t::ctx, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_io_blockdev_iface::write.

Referenced by demo_checkpoint(), demo_write_verify(), internal_bdsink_commit_sector(), internal_cache_write_block(), internal_demo_probe_foreign(), internal_demo_roundtrip(), internal_fs_write(), and internal_write_one().

Variable Documentation

◆ s_tag

const char* const s_tag = "ra8_io_blockdev"
static

Module log tag.

Definition at line 31 of file ra8_io_blockdev.c.