53static const char*
s_tag =
"SRAM";
59typedef enum : uint8_t {
78typedef enum : uint8_t {
163 const uint8_t max_rgn =
165 if ((uint8_t)cfg->
eccrgn > max_rgn) {
199 uint8_t value = eccmod_field;
327 const uint16_t one_bit_pos = (uint16_t)((uint16_t)2U * (uint16_t)bank);
328 const uint16_t two_bit_pos = (uint16_t)(one_bit_pos + 1U);
329 if ((raw & (uint16_t)((uint16_t)1U << one_bit_pos)) != 0U) {
330 one |= (uint8_t)((uint8_t)1U << bank);
332 if ((raw & (uint16_t)((uint16_t)1U << two_bit_pos)) != 0U) {
333 two |= (uint8_t)((uint8_t)1U << bank);
358 return (uintptr_t)0U;
436 for (uint32_t i = 0U; i < words; ++i) {
652 const uint8_t max_rgn =
654 if ((uint8_t)region > max_rgn) {
663 if ((iclk_hz == 0U) || (iclk_max_hz == 0U)) {
668 const uint32_t threshold = iclk_max_hz >> 1U;
670 if (iclk_hz > threshold) {
690 const uint16_t raw = regs->
SRAMESR;
728 const uint16_t bit_pos = (uint16_t)(((uint16_t)2U * (uint16_t)bank) + (uint16_t)slot);
729 const uint16_t mask = (uint16_t)((uint16_t)1U << bit_pos);
780 if (inject_two_bit) {
783 const uint64_t syndrome = *data;
784 const uint64_t corrupted = syndrome ^ (uint64_t)inject_mask;
809 const uintptr_t data_addr = (uintptr_t)bank_base + (uintptr_t)probe_offset;
810 volatile uint64_t*
const data = (
volatile uint64_t*)data_addr;
824 volatile uint64_t scratch = *data;
829 const uint16_t esr = check_regs->
SRAMESR;
830 uint16_t slot_bit = 0U;
831 if (inject_two_bit) {
834 const uint16_t want_bit =
835 (uint16_t)((uint16_t)1U << (uint16_t)(((uint16_t)2U * (uint16_t)bank) + slot_bit));
836 *out_caught = ((esr & want_bit) != 0U);
static const char * s_tag
Logging / check tag.
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_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
static bool s_initialized
True once display_init has succeeded.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info(tag, message)
RA8 log info.
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
ra8_mstp_t
Packed (reg << 8) | bit module-stop identifier.
@ k_ra8_mstp_sram2
MSTPA2 SRAM2.
@ k_ra8_mstp_sram0
MSTPA0 SRAM0.
@ k_ra8_mstp_sram3
MSTPA3 SRAM3.
@ k_ra8_mstp_sram1
MSTPA1 SRAM1.
ra8_err_t ra8_sram_clear_address(uint8_t bank, uint8_t slot)
Clear the captured EAR address for a single (bank, slot) pair.
ra8_err_t ra8_sram_exit_stop(uint8_t bank)
Re-ungate a single bank's clock (Module-Stop exit).
static void internal_self_test_inject(uint8_t bank, volatile uint64_t *data, bool inject_two_bit)
Inject a 1- or 2-bit fault on a probed ECC line.
static void internal_write_wtsc_locked(uint8_t value)
Write SRAMWTSC under SRAMPRCR_S unlock.
ra8_err_t ra8_sram_set_wait_state_for_clock(uint32_t iclk_hz, uint32_t iclk_max_hz)
Derive SRAMWTSC.WTEN from an ICLK frequency and program it.
ra8_sram_local_t
Internal helpers / shifts / sizes.
@ k_ra8_sram_eccmod_shift
ECCMOD field is at bits [3:2] of SRAMCRn.
@ k_ra8_sram_ear_slot_max
0 (1-bit) or 1 (2-bit).
@ k_ra8_sram_eccmod_max
ra8_sram_ecc_mode_t enumerates 0..2.
@ k_ra8_sram_eccrgn_max012
Largest legal ECCRGN for SRAM0..2.
@ k_ra8_sram_on_error_max
OAD is single-bit (0 or 1).
@ k_ra8_sram_eccrgn_max3
Largest legal ECCRGN for SRAM3.
@ k_ra8_sram_bank_max_idx
Last legal bank index.
static void internal_decode_esr(uint16_t raw, uint8_t *one_bit_mask, uint8_t *two_bit_mask)
Compose the per-bank 1-bit / 2-bit error-status masks.
static const uint32_t s_sram_ecc_off_table[k_ra8_sram_bank_count]
Bank-index -> ECC syndrome window offset (HUM Ch 58.1, p 3527).
ra8_err_t ra8_sram_deinit(void)
Tear down the driver and re-gate each bank.
static const ra8_mstp_t s_sram_mstp_table[k_ra8_sram_bank_count]
Bank-index -> ra8_mstp_t lookup.
ra8_err_t ra8_sram_set_mode(uint8_t bank, const ra8_sram_bank_cfg_t *cfg)
Change the ECC mode of a single bank at runtime.
ra8_err_t ra8_sram_zero_init_bank(uint8_t bank)
Deterministically zero one bank under ECC-no-check.
static ra8_err_t internal_validate_and_ungate(const ra8_sram_config_t *cfg)
Validate every bank cfg and ungate the corresponding MSTP bits.
static uintptr_t internal_ear_to_abs_addr(uint32_t ear)
Translate a SRAMEAR offset into its absolute Secure-alias address (per HUM Ch 58.2....
static void internal_zero_fill_bank(uint8_t bank)
8-byte zero fill across the bank's data window.
static void internal_apply_per_bank(const ra8_sram_config_t *cfg)
Apply the per-bank zero-init + ECC mode programming pass.
ra8_err_t ra8_sram_set_eccrgn(uint8_t bank, ra8_sram_eccrgn_size_t region)
Update only the ECC region size (SRAMECCRGNn) for one bank.
ra8_err_t ra8_sram_enter_stop(uint8_t bank)
Re-gate a single bank's clock (Module-Stop entry).
static const uint32_t s_sram_data_off_table[k_ra8_sram_bank_count]
Bank-index -> data-window offset (HUM Ch 58.1 Table 58.1, p 3527).
static void internal_zero_init_with_no_check(uint8_t bank)
Run a single bank's deterministic zero-init pass.
static void internal_write_eccrgn_locked(uint8_t bank, uint8_t value)
Write SRAMECCRGNn for bank under SRAMPRCR_S unlock.
ra8_sram_self_test_inject_t
Bit masks for the ECC self-test fault injection.
@ k_ra8_sram_self_test_flip_2bit
Flip bits 0+1 of the syndrome.
@ k_ra8_sram_self_test_flip_1bit
Flip bit 0 of the syndrome.
ra8_err_t ra8_sram_get_status(ra8_sram_status_t *out)
Snapshot the current ECC error state across all four banks.
static ra8_err_t internal_validate_bank_cfg(const ra8_sram_bank_cfg_t *cfg, uint8_t bank)
Validate per-bank config.
static void internal_write_cr_locked(uint8_t bank, uint8_t value)
Write SRAMCRn for bank under SRAMPRCR_S unlock.
ra8_err_t ra8_sram_get_bank_info(uint8_t bank, ra8_sram_bank_info_t *out)
Report the static layout of one bank.
static void internal_apply_security(const ra8_sram_security_cfg_t *sec)
Apply the optional security cfg from ra8_sram_init.
ra8_err_t ra8_sram_init(const ra8_sram_config_t *cfg)
Initialise the SRAM driver and configure each bank.
static uint8_t internal_encode_cr(const ra8_sram_bank_cfg_t *cfg)
Encode a ra8_sram_bank_cfg_t into an SRAMCRn byte value.
ra8_err_t ra8_sram_self_test(uint8_t bank, uint32_t probe_offset, bool inject_two_bit, bool *out_caught)
Run the HUM Ch 58.3.4 ECC decoder self-test on one bank.
ra8_err_t ra8_sram_clear_status(uint16_t esr_mask)
Clear the listed ECC error bits in SRAMESR (also clears EAR).
SRAM (with ECC) HAL driver public API.
ra8_sram_eccrgn_size_t
Public form of SRAMECCRGNn.ECCRGN (per-bank ECC region size).
@ k_ra8_sram_ecc_no_check
ECC encode/correct, no error reporting (10b).
@ k_ra8_sram_ecc_with_chk
Full ECC (11b) – raises NMI / reset.
@ k_ra8_sram_on_error_reset
Reset the MCU on ECC error.
src/-local shared surface for the SRAM HAL driver split.
ra8_sram_error_fn_t g_sram_on_error
Registered global ECC error callback (NULL until attach).
ra8_sram_error_fn_t g_sram_on_error_bank[k_ra8_sram_bank_count]
Per-bank ECC error callback table (NULL until attach).
void * g_sram_on_error_ctx
Caller context forwarded to g_sram_on_error.
void * g_sram_on_error_bank_ctx[k_ra8_sram_bank_count]
Per-bank context forwarded to g_sram_on_error_bank.
SRAM (with ECC) control / status / security register layout.
static volatile uint8_t * ra8_sram_eccrgn_ptr(volatile r_sram_regs_t *regs, uint8_t bank)
Indexed write helper: SRAMECCRGNn slot.
@ k_ra8_sram_eccrgn_off
000b – no ECC target region.
@ k_ra8_sram_eccrgn_field_msk
ECCRGN[2:0] bit mask.
@ k_ra8_sram_err_all_mask
Union of all 8 error bits.
@ k_ra8_sram_wtsc_wten
Insert one wait state on SRAM access.
@ k_ra8_sram_wtsc_msk
All R/W bits in SRAMWTSC.
@ k_ra8_sram_data_base_addr
Secure SRAM data alias (bank 0).
@ k_ra8_sram_ecc_word_bytes
64-bit ECC word width (bytes).
@ k_ra8_sram_ecc_word_shift
log2(word bytes), for size>>shift loops.
static volatile uint8_t * ra8_sram_cr_ptr(volatile r_sram_regs_t *regs, uint8_t bank)
Indexed write helper: SRAMCRn slot.
@ k_ra8_sram_sabar_align_mask
b12..b0 must be 0.
@ k_ra8_sram_ecc_bank1_off
SRAM1 ECC region @ 0x221B_0000.
@ k_ra8_sram_ecc_bank2_off
SRAM2 ECC region @ 0x221C_0000.
@ k_ra8_sram_ecc_bank3_off
SRAM3 ECC region @ 0x221D_0000.
@ k_ra8_sram_ecc_bank0_off
SRAM0 ECC region @ 0x221A_0000.
@ k_ra8_sram_bank2_data_off
SRAM2 starts at 0x2210_0000.
@ k_ra8_sram_bank1_data_off
SRAM1 starts at 0x2208_0000.
@ k_ra8_sram_bank3_data_off
SRAM3 starts at 0x2218_0000.
@ k_ra8_sram_bank0_data_off
SRAM0 starts at 0x2200_0000.
@ k_ra8_sram_cr_mask_e1stsen
E1STSEN bit 4.
@ k_ra8_sram_cr_mask_oad
OAD bit 0.
static volatile r_sram_cpscu_regs_t * ra8_sram_cpscu_regs(void)
Get pointer to the (Secure) CPSCU SRAM security register block.
@ k_ra8_sram_prcr_lock
KW=0xA5, PR=0 – writes blocked.
@ k_ra8_sram_prcr_unlock
KW=0xA5, PR=1 – writes enabled.
@ k_ra8_sram_esar_bit_esa
SRAMESA – ECC region Non-Secure.
@ k_ra8_sram_cr_self_test_phase_write
ECCMOD=10, all others 0.
@ k_ra8_sram_cr_self_test_phase_bypass
TSTBYP=1, ECCMOD=00.
@ k_ra8_sram_cr_self_test_phase_verify
ECCMOD=11, E1STSEN=1.
@ k_ra8_sram_sar_bit_wtsa
SRAMWTSC Non-Secure.
@ k_ra8_sram_sar_bit_sa0
SRAM0 register set Non-Secure.
static uint32_t ra8_sram_bank_size_bytes(uint8_t bank)
Per-bank data-region size in bytes.
static volatile uint64_t * ra8_sram_bank_data_ptr(uint8_t bank)
Per-bank data window helper: pointer to the start of the data alias.
@ k_ra8_sram_bank_count
SRAM0, SRAM1, SRAM2, SRAM3.
static uint32_t ra8_sram_bank_ecc_size_bytes(uint8_t bank)
Per-bank ECC syndrome region size in bytes.
@ k_ra8_sram_eccmod_disabled
00b<<2 = 0x00 (ECC off).
@ k_ra8_sram_eccmod_no_check
10b<<2 = 0x08 (ECC, no check).
@ k_ra8_sram_eccmod_with_chk
11b<<2 = 0x0C (ECC + checking).
static volatile r_sram_regs_t * ra8_sram_regs(void)
Get pointer to the (Secure) SRAM control register block.
@ k_ra8_sram_zero_init_word
Default fill pattern.
Memory layout of the CPSCU SRAM security window.
volatile uint32_t SRAMSAR
+0x010 SRAM register security.
volatile uint32_t SRAMSABAR[k_ra8_sram_bank_count]
+0x400..+0x40F Bank boundary.
volatile uint32_t SRAMESAR
+0x510 ECC region security.
Memory layout of the SRAM control window.
volatile uint16_t SRAMESR
+0x40 ECC error status.
volatile uint16_t SRAMPRCR_S
+0x00 Secure write-protect.
volatile uint8_t SRAMWTSC
+0x08 Wait-state control.
volatile uint32_t SRAMEAR[k_ra8_sram_bank_count][k_ra8_sram_ear_pair_count]
+0x50..+0x7F Error addresses.
volatile uint16_t SRAMESCLR
+0x48 ECC error status clear.
Per-bank ECC configuration descriptor.
ra8_sram_eccrgn_size_t eccrgn
ECC target region size (SRAMECCRGNn).
ra8_sram_on_error_t on_error
NMI vs Reset on ECC error.
ra8_sram_ecc_mode_t ecc_mode
ECC mode (off / no-check / with-check).
bool zero_init
If true, init() runs the zero-init pass.
bool enable_1bit_latch
Set E1STSEN: latch 1-bit errors.
Static description of one bank.
uintptr_t ecc_base
Absolute Secure base of ECC syndrome.
uint8_t bank
Bank index 0..3.
uintptr_t data_base
Absolute Secure base of data region.
uint32_t ecc_size
Bytes in the ECC syndrome region.
uint32_t data_size
Bytes in the data region.
Top-level driver configuration.
bool apply_security
Touch CPSCU registers if true.
ra8_sram_security_cfg_t security
CPSCU security attribution.
ra8_sram_bank_cfg_t banks[k_ra8_sram_bank_count]
Per-bank settings.
TrustZone security attribution configured at init time.
uint32_t boundary_offset[k_ra8_sram_bank_count]
SRAMSABARn boundary value.
bool ecc_region_ns
SRAMESAR.SRAMESA bit.
bool wtsc_ns
SRAMSAR.SRAMWTSA bit.
bool bank_ns[k_ra8_sram_bank_count]
Bit n -> SRAMSAn = 1 (NS).
Snapshot of ECC error state (filled by ra8_sram_get_status).
uint8_t two_bit_mask
Bit i = SRAMi 2-bit error.
uintptr_t addr_2bit[k_ra8_sram_bank_count]
Captured 2-bit error address per bank.
uintptr_t addr_1bit[k_ra8_sram_bank_count]
Captured 1-bit error address per bank.
uint8_t one_bit_mask
Bit i = SRAMi 1-bit error.
uint16_t raw_esr
Raw SRAMESR value.