|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
OSPI NOR block-device backend – 512-byte LBAs over ra8_xspi flash. More...
#include "ra8_io_blockdev_xspi.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"#include "ra8_ospi_regs.h"#include "ra8_xspi.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_io_xspi_const_t : uint32_t { k_xspi_sector_bytes = 4096 , k_xspi_blocks_per_sector = 8 , k_xspi_program_bytes = 256 , k_xspi_zero_blocks = 0 , k_xspi_min_instance = 0 } |
| OSPI NOR backend layout constants. More... | |
Functions | |
| static ra8_err_t | internal_xspi_bounds (const ra8_io_blockdev_xspi_state_t *st, uint32_t lba, uint32_t count) |
| Reject an out-of-range [lba, lba+count) block range. | |
| static ra8_err_t | internal_xspi_read_chunked (uint8_t instance, uint32_t flash_addr, uint8_t *buf, uint32_t len) |
| Read len flash bytes at flash_addr, chunked to the HAL limit. | |
| static ra8_err_t | internal_xspi_program_chunked (uint8_t instance, uint32_t flash_addr, const uint8_t *data, uint32_t len) |
| Program len flash bytes at flash_addr, chunked to the HAL limit. | |
| static ra8_err_t | internal_write_one_sector (const ra8_io_blockdev_xspi_state_t *st, uint32_t sector_lba, uint32_t first_blk, uint32_t n_blocks, const uint8_t *src) |
| Read-modify-write one 4 KiB sector, overlaying the touched blocks. | |
| static ra8_err_t | internal_xspi_read (void *ctx, uint32_t lba, uint32_t count, uint8_t *buf) |
| xSPI backend: read count blocks at lba into buf. | |
| static ra8_err_t | internal_xspi_write (void *ctx, uint32_t lba, uint32_t count, const uint8_t *buf) |
| xSPI backend: write count blocks from buf at lba. | |
| static ra8_err_t | internal_xspi_erase (void *ctx, uint32_t lba, uint32_t count) |
| xSPI backend: erase sector-aligned count blocks at lba. | |
| static ra8_err_t | internal_xspi_get_caps (const void *ctx, ra8_io_blockdev_caps_t *out) |
| xSPI backend: report medium capabilities. | |
| static ra8_err_t | internal_xspi_check_geom (uint8_t instance, uint32_t base_off, uint32_t block_count) |
| Validate the window geometry for ra8_io_blockdev_xspi_init. | |
| ra8_err_t | ra8_io_blockdev_xspi_init (ra8_io_blockdev_t *bd, ra8_io_blockdev_xspi_state_t *state, uint8_t instance, uint32_t base_off, uint32_t block_count, bool read_only) |
| Bind an OSPI NOR block-device backend into a caller-owned handle. | |
Variables | |
| static const char *const | s_tag = "ra8_io_blockdev_xspi" |
| Module log tag. | |
| static uint8_t | s_sector [k_xspi_sector_bytes] |
| Whole-sector read-modify-write scratch (zero-malloc, NASA Rule 3). | |
| static const ra8_io_blockdev_iface_t | s_xspi_iface |
| OSPI NOR backend vtable. | |
OSPI NOR block-device backend – 512-byte LBAs over ra8_xspi flash.
Implementation of ra8_io_blockdev_iface over the ra8_xspi HAL. Reads chunk ra8_xspi_flash_read to the controller's per-transfer limit. Arbitrary writes are correct on NOR's erase-then-program semantics via a whole-sector read-modify-write through a module-static 4 KiB scratch buffer: read the sector, overlay the touched 512-byte blocks, erase the sector, and program the 4 KiB back (chunked). Erases are sector-aligned. The file touches no MMIO; every flash access routes through the HAL, which owns the HUM citations.
Definition in file ra8_io_blockdev_xspi.c.
| enum ra8_io_xspi_const_t : uint32_t |
OSPI NOR backend layout constants.
Definition at line 44 of file ra8_io_blockdev_xspi.c.
|
static |
Read-modify-write one 4 KiB sector, overlaying the touched blocks.
Reads the whole sector at sector_lba into s_sector, overlays the n_blocks logical blocks starting at offset first_blk within the sector from src, erases the sector to all-ones, then programs the 4 KiB back. Keeps NOR's erase-before-program contract correct for arbitrary writes.
| [in] | st | xSPI backend state. |
| [in] | sector_lba | First logical block of the sector (multiple of 8). |
| [in] | first_blk | Index of the first touched block within the sector. |
| [in] | n_blocks | Number of consecutive blocks to overlay. |
| [in] | src | Source bytes for the overlaid blocks. |
| k_ra8_ok | Sector rewritten with the overlay applied. |
| k_ra8_err_null_ptr | st, src, or a HAL pointer was NULL. |
| k_ra8_err_invalid_arg | HAL rejected a transfer length. |
| k_ra8_err_timeout | Flash WIP bit never cleared. |
Definition at line 218 of file ra8_io_blockdev_xspi.c.
References ra8_io_blockdev_xspi_state_t::base_off, ra8_io_blockdev_xspi_state_t::instance, internal_xspi_program_chunked(), internal_xspi_read_chunked(), k_ra8_io_block_size_bytes, k_ra8_ok, k_xspi_sector_bytes, memcpy(), RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_xspi_flash_erase_sector(), s_sector, and s_tag.
Referenced by internal_xspi_write().
|
static |
Reject an out-of-range [lba, lba+count) block range.
Split into two single-condition checks (no compound decision) so the bounds test needs no MC/DC vectors and never underflows block_count - count.
| [in] | st | xSPI backend state. |
| [in] | lba | First logical block address. |
| [in] | count | Number of blocks in the range. |
| k_ra8_ok | Range lies within the device. |
| k_ra8_err_out_of_range | Range extends past the device capacity. |
Definition at line 81 of file ra8_io_blockdev_xspi.c.
References ra8_io_blockdev_xspi_state_t::block_count, k_ra8_err_out_of_range, and k_ra8_ok.
Referenced by internal_xspi_erase(), internal_xspi_read(), and internal_xspi_write().
|
static |
Validate the window geometry for ra8_io_blockdev_xspi_init.
Split single-condition checks (no compound decision) covering instance range, sector-aligned base offset, and a non-zero whole-sector block count.
| [in] | instance | xSPI HAL instance index. |
| [in] | base_off | Flash byte offset of logical block 0. |
| [in] | block_count | Number of 512-byte logical blocks. |
| k_ra8_ok | Geometry is valid. |
| k_ra8_err_invalid_arg | Some constraint was violated. |
Definition at line 484 of file ra8_io_blockdev_xspi.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_xspi_instance_count, k_xspi_blocks_per_sector, k_xspi_sector_bytes, and k_xspi_zero_blocks.
Referenced by ra8_io_blockdev_xspi_init().
|
static |
xSPI backend: erase sector-aligned count blocks at lba.
Requires lba and count to be multiples of k_xspi_blocks_per_sector (eight blocks per 4 KiB sector); a non-aligned request is rejected. Each spanned sector is erased to all-ones via ra8_xspi_flash_erase_sector.
| [in] | ctx | xSPI backend state (as a void cookie). |
| [in] | lba | First logical block address (multiple of 8). |
| [in] | count | Number of blocks to erase (multiple of 8). |
| k_ra8_ok | Range erased to all-ones. |
| k_ra8_err_null_ptr | ctx was NULL. |
| k_ra8_err_not_supported | The device is read-only. |
| k_ra8_err_invalid_arg | Range is not sector-aligned. |
| k_ra8_err_out_of_range | Range past capacity. |
| k_ra8_err_timeout | Flash WIP bit never cleared. |
Definition at line 381 of file ra8_io_blockdev_xspi.c.
References ra8_io_blockdev_xspi_state_t::base_off, ra8_io_blockdev_xspi_state_t::instance, internal_xspi_bounds(), k_ra8_err_invalid_arg, k_ra8_err_not_supported, k_ra8_io_block_size_bytes, k_ra8_ok, k_xspi_blocks_per_sector, k_xspi_zero_blocks, RA8_CHECK_NULL_PTR, ra8_xspi_flash_erase_sector(), ra8_io_blockdev_xspi_state_t::read_only, and s_tag.
|
static |
xSPI backend: report medium capabilities.
Reports an all-ones-erase NOR medium that must be erased before programming, with an 8-block (4 KiB) erase unit.
| [in] | ctx | xSPI backend state (as a const void cookie). |
| [out] | out | Capabilities snapshot. |
| k_ra8_ok | *out populated. |
| k_ra8_err_null_ptr | ctx or out was NULL. |
Definition at line 434 of file ra8_io_blockdev_xspi.c.
References ra8_io_blockdev_caps_t::block_count, ra8_io_blockdev_xspi_state_t::block_count, ra8_io_blockdev_caps_t::erase_unit_blocks, ra8_io_blockdev_caps_t::erase_value, k_ra8_io_block_size_bytes, k_ra8_io_erase_value_ones, k_ra8_ok, k_xspi_blocks_per_sector, k_xspi_program_bytes, ra8_io_blockdev_caps_t::logical_block_bytes, ra8_io_blockdev_caps_t::must_erase_before_write, ra8_io_blockdev_caps_t::program_size_bytes, RA8_CHECK_NULL_PTR, ra8_io_blockdev_caps_t::read_only, ra8_io_blockdev_xspi_state_t::read_only, and s_tag.
|
static |
Program len flash bytes at flash_addr, chunked to the HAL limit.
Splits the request into transfers of at most k_ra8_xspi_max_xfer bytes so every ra8_xspi_flash_program call stays within the controller window. The target sector must already have been erased to all-ones by the caller.
| [in] | instance | xSPI HAL instance index. |
| [in] | flash_addr | Absolute flash byte offset to program. |
| [in] | data | Source buffer (>= len bytes). |
| [in] | len | Number of bytes to program. |
| k_ra8_ok | All bytes programmed. |
| k_ra8_err_null_ptr | data invalid or instance out of range. |
| k_ra8_err_invalid_arg | HAL rejected a chunk length. |
| k_ra8_err_timeout | Flash WIP bit never cleared. |
Definition at line 167 of file ra8_io_blockdev_xspi.c.
References k_ra8_ok, k_ra8_xspi_max_xfer, k_xspi_zero_blocks, RA8_CHECK_NULL_PTR, ra8_xspi_flash_program(), and s_tag.
Referenced by internal_write_one_sector().
|
static |
xSPI backend: read count blocks at lba into buf.
Bounds-checks the range, then reads count * 512 flash bytes in HAL-sized chunks from base_off + lba * 512.
| [in] | ctx | xSPI backend state (as a void cookie). |
| [in] | lba | First logical block address. |
| [in] | count | Number of blocks to read. |
| [out] | buf | Destination buffer (>= count * 512 bytes). |
| k_ra8_ok | Blocks read into buf. |
| k_ra8_err_null_ptr | ctx or buf was NULL. |
| k_ra8_err_out_of_range | Range past capacity. |
| k_ra8_err_invalid_arg | HAL rejected a chunk length. |
Definition at line 274 of file ra8_io_blockdev_xspi.c.
References ra8_io_blockdev_xspi_state_t::base_off, ra8_io_blockdev_xspi_state_t::instance, internal_xspi_bounds(), internal_xspi_read_chunked(), k_ra8_io_block_size_bytes, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.
|
static |
Read len flash bytes at flash_addr, chunked to the HAL limit.
Splits the request into transfers of at most k_ra8_xspi_max_xfer bytes so every ra8_xspi_flash_read call stays within the controller's per-transfer window. Stops and returns the first non-ok HAL status.
| [in] | instance | xSPI HAL instance index. |
| [in] | flash_addr | Absolute flash byte offset to read from. |
| [out] | buf | Destination buffer (>= len bytes). |
| [in] | len | Number of bytes to read. |
| k_ra8_ok | All bytes read. |
| k_ra8_err_null_ptr | buf invalid or instance out of range. |
| k_ra8_err_invalid_arg | HAL rejected a chunk length. |
Definition at line 121 of file ra8_io_blockdev_xspi.c.
References k_ra8_ok, k_ra8_xspi_max_xfer, k_xspi_zero_blocks, RA8_CHECK_NULL_PTR, ra8_xspi_flash_read(), and s_tag.
Referenced by internal_write_one_sector(), and internal_xspi_read().
|
static |
xSPI backend: write count blocks from buf at lba.
Iterates the 4 KiB sectors the [lba, lba+count) range spans and rewrites each via internal_write_one_sector (whole-sector read-modify-write). Rejects the call up front when the device is read-only or the range exceeds capacity.
| [in] | ctx | xSPI backend state (as a void cookie). |
| [in] | lba | First logical block address. |
| [in] | count | Number of blocks to write. |
| [in] | buf | Source buffer (>= count * 512 bytes). |
| k_ra8_ok | Blocks committed to flash. |
| k_ra8_err_null_ptr | ctx or buf was NULL. |
| k_ra8_err_not_supported | The device is read-only. |
| k_ra8_err_out_of_range | Range past capacity. |
| k_ra8_err_invalid_arg | HAL rejected a transfer length. |
| k_ra8_err_timeout | Flash WIP bit never cleared. |
Definition at line 320 of file ra8_io_blockdev_xspi.c.
References internal_write_one_sector(), internal_xspi_bounds(), k_ra8_err_not_supported, k_ra8_io_block_size_bytes, k_ra8_ok, k_xspi_blocks_per_sector, k_xspi_zero_blocks, RA8_CHECK_NULL_PTR, ra8_io_blockdev_xspi_state_t::read_only, and s_tag.
|
nodiscard |
Bind an OSPI NOR block-device backend into a caller-owned handle.
Records instance/base_off/block_count in state, marks it read-only per read_only, and points bd at the xSPI vtable with state as its context. No allocation occurs; the caller owns both bd and state. The window must be whole-sector aligned: base_off a multiple of 4096 and block_count a non-zero multiple of 8 (4096 / 512). The application must have brought up the controller with ra8_xspi_init(instance, mode) before any call is dispatched through the bound device.
| [out] | bd | Handle to bind (zero-initialised by the caller). |
| [out] | state | Caller-owned backend state to populate. |
| [in] | instance | xSPI HAL instance index (0 or 1). |
| [in] | base_off | Flash byte offset of logical block 0 (% 4096 == 0). |
| [in] | block_count | Number of 512-byte logical blocks (non-zero, % 8 == 0). |
| [in] | read_only | true to reject writes and erases on this device. |
| k_ra8_ok | Backend bound; bd is usable. |
| k_ra8_err_null_ptr | bd or state was NULL. |
| k_ra8_err_invalid_arg | instance >= 2, base_off not sector-aligned, or block_count not a non-zero multiple of 8. |
Definition at line 501 of file ra8_io_blockdev_xspi.c.
References ra8_io_blockdev_xspi_state_t::base_off, ra8_io_blockdev_xspi_state_t::block_count, ra8_io_blockdev_t::ctx, ra8_io_blockdev_t::iface, ra8_io_blockdev_xspi_state_t::instance, internal_xspi_check_geom(), k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_io_blockdev_xspi_state_t::read_only, s_tag, and s_xspi_iface.
Referenced by demo_run(), and internal_swap_run_all().
|
static |
Whole-sector read-modify-write scratch (zero-malloc, NASA Rule 3).
Definition at line 53 of file ra8_io_blockdev_xspi.c.
Referenced by internal_write_one_sector().
|
static |
Module log tag.
Definition at line 36 of file ra8_io_blockdev_xspi.c.
|
static |
OSPI NOR backend vtable.
sync is NULL: programs commit on return.
Definition at line 450 of file ra8_io_blockdev_xspi.c.
Referenced by ra8_io_blockdev_xspi_init().