|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Caching block device – LRU sector cache + write-through over a backend. More...
#include "ra8_io_blockdev_cache.h"#include <stddef.h>#include <stdint.h>#include <string.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_io_blockdev.h"#include "ra8_io_blockdev_backend.h"Go to the source code of this file.
Functions | |
| static uint32_t | internal_cache_find (const ra8_io_blockdev_cache_state_t *st, uint32_t lba) |
| Find the cache slot holding lba. | |
| static uint32_t | internal_cache_pick_victim (const ra8_io_blockdev_cache_state_t *st) |
| Pick a slot to (re)use: the first free slot, else least-recently-used. | |
| static ra8_err_t | internal_cache_read_block (ra8_io_blockdev_cache_state_t *st, uint32_t lba, uint8_t *dst) |
| Read one block through the cache (hit) or fill it (miss). | |
| static ra8_err_t | internal_cache_write_block (ra8_io_blockdev_cache_state_t *st, uint32_t lba, const uint8_t *src) |
| Write one block through to the backend and update the cache. | |
| static ra8_err_t | internal_cache_read (void *ctx, uint32_t lba, uint32_t count, uint8_t *buf) |
| Cache vtable: read count blocks at lba into buf. | |
| static ra8_err_t | internal_cache_write (void *ctx, uint32_t lba, uint32_t count, const uint8_t *buf) |
| Cache vtable: write count blocks from buf at lba. | |
| static ra8_err_t | internal_cache_erase (void *ctx, uint32_t lba, uint32_t count) |
| Cache vtable: erase through to the backend and drop stale slots. | |
| static ra8_err_t | internal_cache_get_caps (const void *ctx, ra8_io_blockdev_caps_t *out) |
| Cache vtable: report the wrapped backend's capabilities. | |
| static ra8_err_t | internal_cache_sync (void *ctx) |
| Cache vtable: flush the wrapped backend. | |
| static void | internal_cache_state_init (ra8_io_blockdev_cache_state_t *state, const ra8_io_blockdev_t *under, uint8_t *data, ra8_io_blockdev_cache_slot_t *slots, uint32_t n_slots) |
| Populate the scalar fields of a fresh cache state. | |
| static void | internal_cache_reset_slots (ra8_io_blockdev_cache_slot_t *slots, uint32_t n_slots) |
| Reset a slot array to the empty (no sectors cached) state. | |
| ra8_err_t | ra8_io_blockdev_cache_init (ra8_io_blockdev_t *bd, ra8_io_blockdev_cache_state_t *state, const ra8_io_blockdev_t *under, uint8_t *data, ra8_io_blockdev_cache_slot_t *slots, uint32_t n_slots) |
| Bind a caching block device over an existing backend. | |
| ra8_err_t | ra8_io_blockdev_cache_stats (const ra8_io_blockdev_cache_state_t *state, uint32_t *out_hits, uint32_t *out_misses) |
| Report the cache hit/miss counters. | |
Variables | |
| static const char *const | s_tag = "ra8_io_blockdev_cache" |
| Module log tag. | |
| static const ra8_io_blockdev_iface_t | s_cache_iface |
| Caching block-device vtable. | |
Caching block device – LRU sector cache + write-through over a backend.
Reads check a caller-owned sector cache and fill it on a miss (evicting the least-recently-used slot); writes go straight through to the wrapped backend and update the cache. Capabilities and sync delegate to the backend. Every predicate is a single condition, so no MC/DC vectors are due.
Definition in file ra8_io_blockdev_cache.c.
|
static |
Cache vtable: erase through to the backend and drop stale slots.
Delegates the erase, then invalidates any cached slot whose block lies in the erased range (three single-condition guards).
| [in] | ctx | Cache state (as a void cookie). |
| [in] | lba | First logical block address. |
| [in] | count | Number of blocks to erase. |
| k_ra8_ok | Range erased and stale slots dropped. |
| k_ra8_err_null_ptr | ctx was NULL. |
| k_ra8_err_* | Propagated from the backend erase. |
Definition at line 299 of file ra8_io_blockdev_cache.c.
References k_ra8_ok, ra8_io_blockdev_cache_slot_t::lba, ra8_io_blockdev_cache_state_t::n_slots, RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_io_blockdev_erase(), RA8_RETURN_ON_ERROR, s_tag, ra8_io_blockdev_cache_state_t::slots, ra8_io_blockdev_cache_state_t::under, and ra8_io_blockdev_cache_slot_t::valid.
|
static |
Find the cache slot holding lba.
Linear scan over valid slots; two single-condition checks avoid a compound decision.
| [in] | st | Cache state. |
| [in] | lba | Logical block address to look up. |
| st->n_slots | The block is not in the cache. |
Definition at line 55 of file ra8_io_blockdev_cache.c.
References ra8_io_blockdev_cache_slot_t::lba, ra8_io_blockdev_cache_state_t::n_slots, RA8_INTERNAL, ra8_io_blockdev_cache_state_t::slots, and ra8_io_blockdev_cache_slot_t::valid.
Referenced by internal_cache_read_block(), and internal_cache_write_block().
|
static |
Cache vtable: report the wrapped backend's capabilities.
The cache does not change the medium's geometry, so it forwards.
| [in] | ctx | Cache state (as a const void cookie). |
| [out] | out | Capabilities snapshot. |
| k_ra8_ok | *out populated from the backend. |
| k_ra8_err_null_ptr | ctx or out was NULL. |
| k_ra8_err_* | Propagated from the backend. |
Definition at line 343 of file ra8_io_blockdev_cache.c.
References RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_io_blockdev_get_caps(), s_tag, and ra8_io_blockdev_cache_state_t::under.
|
static |
Pick a slot to (re)use: the first free slot, else least-recently-used.
A free slot wins immediately; otherwise the slot with the smallest last_use stamp is evicted.
| [in] | st | Cache state. |
| <st->n_slots | Always a valid slot index. |
Definition at line 90 of file ra8_io_blockdev_cache.c.
References ra8_io_blockdev_cache_slot_t::last_use, ra8_io_blockdev_cache_state_t::n_slots, RA8_INTERNAL, ra8_io_blockdev_cache_state_t::slots, and ra8_io_blockdev_cache_slot_t::valid.
Referenced by internal_cache_read_block(), and internal_cache_write_block().
|
static |
Cache vtable: read count blocks at lba into buf.
Iterates the range one block at a time through internal_cache_read_block.
| [in] | ctx | Cache state (as a void cookie). |
| [in] | lba | First logical block address. |
| [in] | count | Number of blocks to read. |
| [out] | buf | Destination buffer. |
| k_ra8_ok | Blocks read. |
| k_ra8_err_null_ptr | ctx or buf was NULL. |
| k_ra8_err_* | Propagated from the backend read. |
Definition at line 220 of file ra8_io_blockdev_cache.c.
References internal_cache_read_block(), k_ra8_io_block_size_bytes, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
|
static |
Read one block through the cache (hit) or fill it (miss).
On a hit, copies from the cache and bumps the LRU stamp; on a miss, reads one block from the backend into the victim slot, records it, and copies it out. Updates the hit/miss counters.
| [in] | st | Cache state. |
| [in] | lba | Logical block address. |
| [out] | dst | Destination of one 512-byte block. |
| k_ra8_ok | Block delivered into dst. |
| k_ra8_err_* | Propagated from the backend read. |
Definition at line 130 of file ra8_io_blockdev_cache.c.
References ra8_io_blockdev_cache_state_t::clock, ra8_io_blockdev_cache_state_t::data, ra8_io_blockdev_cache_state_t::hits, internal_cache_find(), internal_cache_pick_victim(), k_ra8_io_block_size_bytes, k_ra8_ok, ra8_io_blockdev_cache_slot_t::last_use, ra8_io_blockdev_cache_slot_t::lba, memcpy(), ra8_io_blockdev_cache_state_t::misses, ra8_io_blockdev_cache_state_t::n_slots, ra8_io_blockdev_read(), RA8_RETURN_ON_ERROR, s_tag, ra8_io_blockdev_cache_state_t::slots, ra8_io_blockdev_cache_state_t::under, and ra8_io_blockdev_cache_slot_t::valid.
Referenced by internal_cache_read().
|
static |
Reset a slot array to the empty (no sectors cached) state.
Marks every slot invalid and clears its LBA and LRU stamp so the first access fills a free slot rather than evicting stale data.
| [out] | slots | Cache metadata array of n_slots entries. |
| [in] | n_slots | Number of slots to reset (>= 1). |
Definition at line 451 of file ra8_io_blockdev_cache.c.
References ra8_io_blockdev_cache_slot_t::last_use, ra8_io_blockdev_cache_slot_t::lba, RA8_INTERNAL, and ra8_io_blockdev_cache_slot_t::valid.
Referenced by ra8_io_blockdev_cache_init().
|
static |
Populate the scalar fields of a fresh cache state.
Records the caller-owned backend, data buffer, and slot array on state and zeroes the monotonic clock and the hit/miss counters. The slot array itself is reset separately by internal_cache_reset_slots.
| [out] | state | Cache state to populate (already null-checked). |
| [in] | under | Wrapped backend (must out-live the cache). |
| [in] | data | Cache data buffer of n_slots * 512 bytes. |
| [in] | slots | Cache metadata array of n_slots entries. |
| [in] | n_slots | Number of cached sectors (>= 1). |
Definition at line 415 of file ra8_io_blockdev_cache.c.
References ra8_io_blockdev_cache_state_t::clock, ra8_io_blockdev_cache_state_t::data, ra8_io_blockdev_cache_state_t::hits, ra8_io_blockdev_cache_state_t::misses, ra8_io_blockdev_cache_state_t::n_slots, RA8_INTERNAL, ra8_io_blockdev_cache_state_t::slots, and ra8_io_blockdev_cache_state_t::under.
Referenced by ra8_io_blockdev_cache_init().
|
static |
Cache vtable: flush the wrapped backend.
Writes are write-through so nothing is buffered here; the call forwards so a backend with its own buffering can commit.
| [in] | ctx | Cache state (as a void cookie). |
| k_ra8_ok | Backend flushed. |
| k_ra8_err_null_ptr | ctx was NULL. |
| k_ra8_err_* | Propagated from the backend sync. |
Definition at line 374 of file ra8_io_blockdev_cache.c.
References RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_io_blockdev_sync(), s_tag, and ra8_io_blockdev_cache_state_t::under.
|
static |
Cache vtable: write count blocks from buf at lba.
Iterates the range one block at a time through internal_cache_write_block.
| [in] | ctx | Cache state (as a void cookie). |
| [in] | lba | First logical block address. |
| [in] | count | Number of blocks to write. |
| [in] | buf | Source buffer. |
| k_ra8_ok | Blocks written through. |
| k_ra8_err_null_ptr | ctx or buf was NULL. |
| k_ra8_err_* | Propagated from the backend write. |
Definition at line 260 of file ra8_io_blockdev_cache.c.
References internal_cache_write_block(), k_ra8_io_block_size_bytes, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
|
static |
Write one block through to the backend and update the cache.
Write-through: the backend is written first, then the cache slot for the block is inserted or refreshed so a following read hits.
| [in] | st | Cache state. |
| [in] | lba | Logical block address. |
| [in] | src | Source of one 512-byte block. |
| k_ra8_ok | Block committed and cached. |
| k_ra8_err_* | Propagated from the backend write. |
Definition at line 178 of file ra8_io_blockdev_cache.c.
References ra8_io_blockdev_cache_state_t::clock, ra8_io_blockdev_cache_state_t::data, internal_cache_find(), internal_cache_pick_victim(), k_ra8_io_block_size_bytes, k_ra8_ok, ra8_io_blockdev_cache_slot_t::last_use, ra8_io_blockdev_cache_slot_t::lba, memcpy(), ra8_io_blockdev_cache_state_t::n_slots, ra8_io_blockdev_write(), RA8_RETURN_ON_ERROR, s_tag, ra8_io_blockdev_cache_state_t::slots, ra8_io_blockdev_cache_state_t::under, and ra8_io_blockdev_cache_slot_t::valid.
Referenced by internal_cache_write().
|
nodiscard |
Bind a caching block device over an existing backend.
| [out] | bd | Handle to bind (zero-initialised by the caller). |
| [out] | state | Caller-owned cache state to populate. |
| [in] | under | Backend to wrap (must out-live the cache). |
| [in] | data | Cache data buffer of n_slots * 512 bytes. |
| [in] | slots | Cache metadata array of n_slots entries. |
| [in] | n_slots | Number of cached sectors (>= 1). |
| k_ra8_ok | Cache bound; bd is usable. |
| k_ra8_err_null_ptr | bd, state, under, data, or slots NULL. |
| k_ra8_err_invalid_size | n_slots was zero. |
Definition at line 461 of file ra8_io_blockdev_cache.c.
References ra8_io_blockdev_t::ctx, ra8_io_blockdev_t::iface, internal_cache_reset_slots(), internal_cache_state_init(), k_ra8_err_invalid_size, k_ra8_ok, RA8_CHECK_NULL_PTR, s_cache_iface, and s_tag.
Referenced by internal_demo_mount().
|
nodiscard |
Report the cache hit/miss counters.
| [in] | state | Bound cache state. |
| [out] | out_hits | Read hits so far (may be NULL). |
| [out] | out_misses | Read misses so far (may be NULL). |
| k_ra8_ok | Counters reported. |
| k_ra8_err_null_ptr | state was NULL. |
Definition at line 483 of file ra8_io_blockdev_cache.c.
References ra8_io_blockdev_cache_state_t::hits, k_ra8_ok, ra8_io_blockdev_cache_state_t::misses, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by internal_demo_run().
|
static |
Caching block-device vtable.
Definition at line 382 of file ra8_io_blockdev_cache.c.
Referenced by ra8_io_blockdev_cache_init().
|
static |
Module log tag.
Definition at line 31 of file ra8_io_blockdev_cache.c.