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

VBATT backup-register (VBTBKRn) reset-retained domain model. More...

#include <stdint.h>
#include <stdio.h>
#include "board_periph_block.h"
#include "board_periph_prcr_internal.h"
#include "emu_host_io_internal.h"
Include dependency graph for board_periph_bkup.c:

Go to the source code of this file.

Data Structures

struct  bkup_ctrl_t
 VBATT control state (cleared by a reset; data is not). More...

Enumerations

enum  bkup_geom_t : uint64_t {
  k_bkup_base = 0x4001EC40UL ,
  k_bkup_span = 0x180UL ,
  k_bkup_off_vbtber = 0x000UL ,
  k_bkup_off_vbtbkr0 = 0x0C0UL ,
  k_bkup_reg_count = 128UL
}
 VBATT backup window geometry (ra8_bkup_regs.h). More...
enum  bkup_vbtber_mask_t : uint8_t {
  k_bkup_vbtber_mask_vbae = 0x08U ,
  k_bkup_vbtber_reset = 0x08U
}
 VBTBER field masks (HUM Ch 12.2.6 p 504). More...
enum  bkup_order_t : uint32_t { k_bkup_block_order = 175U }
 Per-tick order slot for the VBATT-backup block (relative order). More...

Functions

static void internal_bkup_reset (void)
 Reset only the VBATT control state; the backup bytes are retained.
static uint64_t internal_bkup_read (uc_engine *uc, uint64_t addr, unsigned size)
 MMIO read inside the VBATT backup window (width-aware).
static void internal_bkup_write (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
 MMIO write inside the VBATT backup window (width-aware).
static void internal_bkup_report (void)
 End-of-run VBATT-backup section: writes accepted / dropped this run.
static void internal_bkup_block_register (void)
 Register the VBATT-backup block before main (host constructor).

Variables

static uint8_t s_bkup_vbtbkr [k_bkup_reg_count]
 Retained VBTBKRn bytes – the battery-backed domain.
static bkup_ctrl_t s_bkup
static const board_periph_block_t s_k_bkup_block
 VBATT-backup block descriptor (self-registered with the core).

Detailed Description

VBATT backup-register (VBTBKRn) reset-retained domain model.

Models the RA8D2 VBATT backup registers (ra8_bkup_regs.h, ra8_bkup.c) as a reset-retained power domain, so bkup_survival_demo can prove that backup state survives a CPU reset. The 128 VBTBKRn bytes (32 x 32-bit words) live in the R_SYSTEM block at 0x4001ED00; on silicon they keep their contents across a reset (and, with a battery on VBATT, across a power cycle). The sparse fallback treated them as ordinary peripheral memory that cleared on every run, so the demo's sentinel was never found and it reported survived=N.

This block claims the VBTBKRn window plus the access-enable byte (VBTBER, 0xC40) and holds the 128 backup bytes in a host-static buffer that the block's reset hook deliberately does NOT clear. The ra8_emulator run loop's --reboot path re-runs the firmware from its reset vector after resetting the peripheral blocks; because this block preserves the backup bytes across that reset, the second boot finds the sentinel intact – exactly the reset-survival contract. The bytes clear only at process start (static zero-initialisation), modelling the first-ever boot with a dead battery.

Two silicon preconditions gate a VBTBKRn write, and both are modelled here:

  1. PRCR.PRC1 must be unlocked. Every register in this block – VBTBER, VBTICTLR, VBTBKRn, VBTBPCR1, VBTBPCR2, VBTBPSR, VBTADSR, VBTADCR1, VBTADCR2, VBTICTLR2, VBTADCR3, VBTNCWCR – is named under PRC1 in HUM Ch 13.1 Table 13.1 "Association between PRCR bits and use of registers to be protected" p 520-521. A write with PRC1 locked is discarded silently: no fault, no flag. This is the #131 root cause. Bench-confirmed by J-Link on an EK-RA8D2: writing VBTBKR0 with PRCR locked reads back 0x00000000; after PRCR = 0xA502 the identical write sticks.
  2. VBTBER.VBAE must be 1 – HUM Ch 12.2.6 p 504, "You must write 1 to VBAE before accessing VBTBKR".

VBTBER resets to 0x08 (VBAE = 1) per its "Value after reset" row in HUM Ch 12.2.6 p 504, matching a J-Link read of a live board, so VBAE alone never blocks a first write – which is precisely why modelling only VBAE left the emulator green while the bench was red. Writes to VBTBER itself are PRC1-gated too, so firmware that clears VBAE without unlocking does not change it, exactly as on silicon.

A write dropped for either reason is counted in dropped and named in the end-of-run report, so the cause is visible rather than inferred from a failing banner. Reads always return the retained byte (PRCR gates writes only, HUM Ch 13.1 p 520).

The earlier revision of this file blamed the OFS1.PVDAS option byte for the #131 divergence and declared it unmodelable. That was wrong: PVDAS governs the battery power-supply switch (HUM Ch 12.3.2 p 514), not register access, and on the EK-RA8D2 – where VBATT is tied to VCC and the switch is stopped – the backup registers read and write correctly with the default OFS1 once PRC1 is unlocked. Bench-proven: rw=ok survived=Y.

Since
0.1.0

Definition in file board_periph_bkup.c.

Enumeration Type Documentation

◆ bkup_geom_t

enum bkup_geom_t : uint64_t

VBATT backup window geometry (ra8_bkup_regs.h).

Enumerator
k_bkup_base 

VBTBER .

. past VBTBKRn window base.

k_bkup_span 

Covers VBTBER (0x00) .

. VBTBKR127.

k_bkup_off_vbtber 

VBTBER access-enable (at base).

k_bkup_off_vbtbkr0 

VBTBKR0 (0x4001ED00 - 0x4001EC40).

k_bkup_reg_count 

128 byte-wide VBTBKRn slots.

Definition at line 69 of file board_periph_bkup.c.

◆ bkup_order_t

enum bkup_order_t : uint32_t

Per-tick order slot for the VBATT-backup block (relative order).

Enumerator
k_bkup_block_order 

After the LVD block; report order.

Definition at line 84 of file board_periph_bkup.c.

◆ bkup_vbtber_mask_t

enum bkup_vbtber_mask_t : uint8_t

VBTBER field masks (HUM Ch 12.2.6 p 504).

Enumerator
k_bkup_vbtber_mask_vbae 

VBAE @ bit 3: 1 = enable VBTBKRn access.

k_bkup_vbtber_reset 

"Value after reset" row: VBAE = 1.

Definition at line 78 of file board_periph_bkup.c.

Function Documentation

◆ internal_bkup_block_register()

void internal_bkup_block_register ( void )
static

Register the VBATT-backup block before main (host constructor).

Definition at line 251 of file board_periph_bkup.c.

References board_periph_register_block(), RA8_INTERNAL, and s_k_bkup_block.

◆ internal_bkup_read()

uint64_t internal_bkup_read ( uc_engine * uc,
uint64_t addr,
unsigned size )
static

MMIO read inside the VBATT backup window (width-aware).

MMIO read inside the vbatt backup window (width-aware); this step is contained within the board periph bkup model and uses bounded caller or module-owned storage.

Parameters
[in,out]ucUnicorn engine whose emulated state is read or updated.
[in]addrGuest address involved in the operation.
[in]sizeSize of the requested region or access in bytes.
Returns
The bkup read result produced by the board periph bkup model.
Return values
valueThe operation-specific bkup read value.
Precondition
Arguments satisfy the ranges documented for bkup read.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph bkup model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 140 of file board_periph_bkup.c.

References k_bkup_base, k_bkup_off_vbtber, k_bkup_off_vbtbkr0, k_bkup_reg_count, RA8_INTERNAL, s_bkup, and s_bkup_vbtbkr.

◆ internal_bkup_report()

void internal_bkup_report ( void )
static

End-of-run VBATT-backup section: writes accepted / dropped this run.

End-of-run vbatt-backup section: writes accepted / dropped this run; this step is contained within the board periph bkup model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for bkup report.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph bkup model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 213 of file board_periph_bkup.c.

References priv_emu_io_errf(), RA8_INTERNAL, and s_bkup.

◆ internal_bkup_reset()

void internal_bkup_reset ( void )
static

Reset only the VBATT control state; the backup bytes are retained.

Reset only the vbatt control state; the backup bytes are retained; this step is contained within the board periph bkup model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for bkup reset.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph bkup model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 115 of file board_periph_bkup.c.

References k_bkup_vbtber_reset, RA8_INTERNAL, and s_bkup.

◆ internal_bkup_write()

void internal_bkup_write ( uc_engine * uc,
uint64_t addr,
unsigned size,
uint64_t value )
static

MMIO write inside the VBATT backup window (width-aware).

MMIO write inside the vbatt backup window (width-aware); this step is contained within the board periph bkup model and uses bounded caller or module-owned storage.

Parameters
[in,out]ucUnicorn engine whose emulated state is read or updated.
[in]addrGuest address involved in the operation.
[in]sizeSize of the requested region or access in bytes.
[in]valueRegister or payload value involved in the operation.
Precondition
Arguments satisfy the ranges documented for bkup write.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph bkup model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 171 of file board_periph_bkup.c.

References k_bkup_base, k_bkup_off_vbtber, k_bkup_off_vbtbkr0, k_bkup_reg_count, k_bkup_vbtber_mask_vbae, k_board_prcr_grp1_lpm, priv_board_prcr_group_unlocked(), s_bkup, and s_bkup_vbtbkr.

Variable Documentation

◆ s_bkup

◆ s_bkup_vbtbkr

uint8_t s_bkup_vbtbkr[k_bkup_reg_count]
static

Retained VBTBKRn bytes – the battery-backed domain.

Survives a peripheral reset (the block's reset hook leaves it untouched), so a --reboot re-run finds the prior boot's contents intact. Clears only at process start (static zero-init): the first-ever boot.

Definition at line 95 of file board_periph_bkup.c.

Referenced by internal_bkup_read(), and internal_bkup_write().

◆ s_k_bkup_block

const board_periph_block_t s_k_bkup_block
static
Initial value:
= {
.base = (uint64_t)k_bkup_base,
.span = (uint64_t)k_bkup_span,
.order = (uint32_t)k_bkup_block_order,
.tick = nullptr,
.name = "VBATT-BKUP",
}
static void internal_bkup_reset(void)
Reset only the VBATT control state; the backup bytes are retained.
static uint64_t internal_bkup_read(uc_engine *uc, uint64_t addr, unsigned size)
MMIO read inside the VBATT backup window (width-aware).
@ k_bkup_block_order
After the LVD block; report order.
static void internal_bkup_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
MMIO write inside the VBATT backup window (width-aware).
@ k_bkup_base
VBTBER .
@ k_bkup_span
Covers VBTBER (0x00) .
static void internal_bkup_report(void)
End-of-run VBATT-backup section: writes accepted / dropped this run.
-proof

VBATT-backup block descriptor (self-registered with the core).

Definition at line 238 of file board_periph_bkup.c.

Referenced by internal_bkup_block_register().