ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_io_blockdev_vsource.c
Go to the documentation of this file.
1
20
22
23#include <stddef.h>
24#include <stdint.h>
25#include <string.h>
26
27#include "ra8_attributes.h"
28#include "ra8_check.h"
29#include "ra8_err.h"
30#include "ra8_io_blockdev.h"
31#include "ra8_vsource.h"
32
34static const char* const s_tag = "ra8_io_blockdev_vsource";
35
45
76
106 uint32_t lba,
107 uint32_t in_block,
108 uint32_t n,
109 uint8_t* dst)
110{
111 const ra8_err_t err = internal_bd_read_sector(ctx, lba);
112 if (err != k_ra8_ok) {
113 return err;
114 }
115 (void)memcpy(dst, &ctx->scratch[in_block], (size_t)n);
116 return k_ra8_ok;
117}
118
135typedef struct {
136 uint64_t cur;
137 uint8_t* out;
138 uint32_t remain;
140
171 uint64_t block_bytes)
172{
173 const uint32_t head_in_block = (uint32_t)(cur->cur % block_bytes);
174 if (head_in_block == 0U) {
175 return k_ra8_ok;
176 }
177 uint32_t head_n = (uint32_t)(block_bytes - (uint64_t)head_in_block);
178 if (head_n > cur->remain) {
179 head_n = cur->remain;
180 }
181 const ra8_err_t err = internal_bd_copy_slice(ctx,
182 (uint32_t)(cur->cur / block_bytes),
183 head_in_block,
184 head_n,
185 cur->out);
186 if (err != k_ra8_ok) {
187 return err;
188 }
189 cur->cur += (uint64_t)head_n;
190 cur->out += head_n;
191 cur->remain -= head_n;
192 return k_ra8_ok;
193}
194
223 uint64_t block_bytes)
224{
225 const uint32_t mid_blocks = (uint32_t)((uint64_t)cur->remain / block_bytes);
226 if (mid_blocks == 0U) {
227 return k_ra8_ok;
228 }
229 const ra8_err_t err =
230 ra8_io_blockdev_read(ctx->bd, (uint32_t)(cur->cur / block_bytes), mid_blocks, cur->out);
231 if (err != k_ra8_ok) {
232 return err;
233 }
234 const uint32_t mid_bytes = (uint32_t)((uint64_t)mid_blocks * block_bytes);
235 cur->cur += (uint64_t)mid_bytes;
236 cur->out += mid_bytes;
237 cur->remain -= mid_bytes;
238 return k_ra8_ok;
239}
240
269 uint64_t block_bytes)
270{
271 if (cur->remain == 0U) {
272 return k_ra8_ok;
273 }
274 return internal_bd_copy_slice(ctx, (uint32_t)(cur->cur / block_bytes), 0U, cur->remain, cur->out);
275}
276
278 const ra8_io_blockdev_t* bd)
279{
280 RA8_CHECK_NULL_PTR(ctx, s_tag, "ctx must not be nullptr");
281 RA8_CHECK_NULL_PTR(bd, s_tag, "bd must not be nullptr");
282 ctx->bd = bd;
283 (void)memset(ctx->scratch, 0, sizeof(ctx->scratch));
284 return k_ra8_ok;
285}
286
287ra8_err_t ra8_io_blockdev_vsource_read(void* ctx, uint64_t offset, uint8_t* buf, uint32_t len)
288{
289 RA8_CHECK_NULL_PTR(ctx, s_tag, "ctx must not be nullptr");
290 RA8_CHECK_NULL_PTR(buf, s_tag, "buf must not be nullptr");
292
293 const uint64_t block_bytes = (uint64_t)k_ra8_io_block_size_bytes;
294 if (offset > (UINT64_MAX - (uint64_t)len)) {
296 }
297
298 ra8_io_bd_vsource_cursor_t cur = {.cur = offset, .out = buf, .remain = len};
299
300 /* Unaligned head: the byte offset does not start on a sector boundary. */
301 ra8_err_t err = internal_bd_read_head(c, &cur, block_bytes);
302 if (err != k_ra8_ok) {
303 return err;
304 }
305
306 /* Aligned middle: whole sectors copied straight into the caller buffer. */
307 err = internal_bd_read_middle(c, &cur, block_bytes);
308 if (err != k_ra8_ok) {
309 return err;
310 }
311
312 /* Unaligned tail: a partial final sector. */
313 return internal_bd_read_tail(c, &cur, block_bytes);
314}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
Definition ra8_err.h:337
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
ra8_io block-device fabric – one LBA vtable across every storage medium.
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.
@ k_ra8_io_block_size_bytes
Bytes per logical block (the only size).
static ra8_err_t internal_bd_read_tail(ra8_io_blockdev_vsource_ctx_t *ctx, ra8_io_bd_vsource_cursor_t *cur, uint64_t block_bytes)
Service the unaligned tail sector of a byte-offset read.
static ra8_err_t internal_bd_read_sector(ra8_io_blockdev_vsource_ctx_t *ctx, uint32_t lba)
Read one sector at lba into the context bounce buffer.
ra8_err_t ra8_io_blockdev_vsource_read(void *ctx, uint64_t offset, uint8_t *buf, uint32_t len)
Read len bytes at byte offset from the bound block device.
static ra8_err_t internal_bd_read_head(ra8_io_blockdev_vsource_ctx_t *ctx, ra8_io_bd_vsource_cursor_t *cur, uint64_t block_bytes)
Service the unaligned head sector of a byte-offset read.
static ra8_err_t internal_bd_read_middle(ra8_io_blockdev_vsource_ctx_t *ctx, ra8_io_bd_vsource_cursor_t *cur, uint64_t block_bytes)
Service the aligned middle of a byte-offset read.
ra8_io_bd_vsource_const_t
Adapter layout constants.
@ k_ra8_io_bd_vsource_one_block
Blocks transferred per bounce read.
ra8_err_t ra8_io_blockdev_vsource_init(ra8_io_blockdev_vsource_ctx_t *ctx, const ra8_io_blockdev_t *bd)
Bind a block device into a vsource adapter context.
static ra8_err_t internal_bd_copy_slice(ra8_io_blockdev_vsource_ctx_t *ctx, uint32_t lba, uint32_t in_block, uint32_t n, uint8_t *dst)
Copy a slice out of the bounce buffer after a one-sector read.
Thin adapter exposing an ra8_io block device as an ra8_vsource reader.
Virtual-memory object sources – the page-cache storage seam (Layer 1, #147).
Mutable walk state shared by the head/middle/tail read segments.
uint64_t cur
Absolute device byte offset of the next unread byte.
uint8_t * out
Next unwritten byte of the caller's destination buffer.
uint32_t remain
Bytes still owed to the caller.
Caller-allocated block-device handle binding a backend to its context.
Caller-owned adapter context binding a block device to a vsource read.
uint8_t scratch[(uint32_t) k_ra8_io_block_size_bytes]
One-sector bounce buffer (private).
const ra8_io_blockdev_t * bd
Bound block device (private; read-only use).