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

Reset-cause status register (RSTSRn) model for ra8_emulator. More...

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

Go to the source code of this file.

Enumerations

enum  reset1_geom_t : uint64_t {
  k_rstsr1_base = 0x4001E0C0UL ,
  k_rstsr1_span = 0x04UL
}
 RSTSR1 window geometry (ra8_reset_regs.h). More...
enum  reset0_geom_t : uint64_t {
  k_rstsr0_base = 0x4001EA40UL ,
  k_rstsr0_span = 0x0CUL ,
  k_rstsr0_off_r0 = 0x00UL ,
  k_rstsr0_off_r2 = 0x04UL ,
  k_rstsr0_off_r3 = 0x08UL
}
 RSTSR0 / RSTSR2 / RSTSR3 window geometry (ra8_reset_regs.h). More...
enum  reset_flag_t : uint32_t {
  k_rstsr0_porf = 0x01U ,
  k_rstsr1_iwdtrf = 0x00000001U ,
  k_rstsr1_wdtrf = 0x00000002U ,
  k_rstsr1_swrf = 0x00000004U
}
 RSTSR flag bit masks (ra8_reset_regs.h). More...
enum  reset_order_t : uint32_t { k_reset_block_order = 178U }
 Per-tick order slot for the reset block (relative order only). More...
enum  reboot_cause_t : uint32_t {
  k_reboot_cause_none = 0U ,
  k_reboot_cause_wdt = 1U ,
  k_reboot_cause_iwdt = 2U
}
 Reboot-cause codes a peripheral can request via _request_reboot. More...

Functions

void board_periph_reset_request_reboot (bool watchdog, bool iwdt)
 Request a warm reboot from a peripheral model (e.g.
bool board_periph_reset_take_request (bool *out_watchdog, bool *out_iwdt)
 Consume a pending peripheral reboot request, if any (run-loop side).
void board_periph_reset_set_cause (bool power_on, bool software, bool watchdog, bool iwdt)
 Record the cause of a warm reboot in the sticky RSTSRn flags.
static RA8_INTERNAL void internal_reset_reset (void)
 Reset hook: the cause flags are sticky, so this preserves them.
static RA8_INTERNAL uint64_t internal_reset1_read (uc_engine *uc, uint64_t addr, unsigned size)
 MMIO read inside the RSTSR1 window.
static RA8_INTERNAL void internal_reset1_write (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
 MMIO write inside the RSTSR1 window (write-0-to-clear flags).
static RA8_INTERNAL uint64_t internal_reset0_read (uc_engine *uc, uint64_t addr, unsigned size)
 MMIO read inside the RSTSR0 / RSTSR2 / RSTSR3 window.
static RA8_INTERNAL void internal_reset0_write (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
 MMIO write inside the RSTSR0 / RSTSR2 / RSTSR3 window.
static RA8_INTERNAL void internal_reset_report (void)
 End-of-run reset section: the latched cause flags.
static RA8_INTERNAL void internal_reset_block_register (void)
 Register the reset-status windows + seed PORF (cold boot).

Variables

static uint32_t s_rstsr1
 Sticky reset-cause flags (survive a warm reboot).
static uint8_t s_rstsr0
 RSTSR0 sticky flags.
static uint8_t s_rstsr2
 RSTSR2 (CWSF).
static uint8_t s_rstsr3
 RSTSR3.
static uint32_t s_reboot_req_cause
static const board_periph_block_t s_k_reset1_block
 RSTSR1 block descriptor (owns the report).
static const board_periph_block_t s_k_reset0_block
 RSTSR0 / RSTSR2 / RSTSR3 block descriptor.

Detailed Description

Reset-cause status register (RSTSRn) model for ra8_emulator.

Models the RA8D2 reset-status registers (ra8_reset_regs.h, ra8_reset.c) so a firmware can read back WHY it booted – power-on, software reset, or watchdog reset – which the sparse fallback could not provide (the cause always read back as cleared). The flags are sticky across a ra8_emulator warm reboot (the --reboot path and the AIRCR.SYSRESETREQ / watchdog-timeout triggers in main.c), so an example such as reset_cause_demo sees k_ra8_reset_cause_software on the second boot after it asks for a software reset, exactly as on silicon.

The RSTSRn live inside the R_SYSTEM block; this model claims only the two small windows that hold them, leaving the rest of R_SYSTEM to the sparse fallback and the other R_SYSTEM models (LVD status, VBATT backup):

  • RSTSR1 (32-bit) at 0x4001E0C0 – IWDTRF / WDTRF / SWRF / ... .
  • RSTSR0 (8-bit) at 0x4001EA40 – PORF / LVDxRF / DPSRSTF – plus the adjacent RSTSR2 (CWSF) and RSTSR3.

Clear semantics match the hardware: the RSTSRn flag bits are write-0-to-clear ("only 0 can be written; to clear, read 1 then write 0"), so a write keeps only the bits that are both currently set and written as 1, and a written 0 clears that bit.

At cold boot (process start / a power-on reboot) PORF is set and the other flags clear. The reboot path in main.c calls board_periph_reset_set_cause to record the new cause (clearing PORF, setting SWRF for a software reset or WDTRF / IWDTRF for a watchdog reset) just before it re-enters the firmware.

Since
0.1.0

Definition in file board_periph_reset.c.

Enumeration Type Documentation

◆ reboot_cause_t

enum reboot_cause_t : uint32_t

Reboot-cause codes a peripheral can request via _request_reboot.

Enumerator
k_reboot_cause_none 

No pending request.

k_reboot_cause_wdt 

Watchdog-0 reset (RSTSR1.WDTRF).

k_reboot_cause_iwdt 

Independent-watchdog reset.

Definition at line 90 of file board_periph_reset.c.

◆ reset0_geom_t

enum reset0_geom_t : uint64_t

RSTSR0 / RSTSR2 / RSTSR3 window geometry (ra8_reset_regs.h).

Enumerator
k_rstsr0_base 

RSTSR0 (8-bit) window base.

k_rstsr0_span 

Covers RSTSR0 / RSTSR2 / RSTSR3.

k_rstsr0_off_r0 

RSTSR0 at the window base.

k_rstsr0_off_r2 

RSTSR2 (CWSF).

k_rstsr0_off_r3 

RSTSR3.

Definition at line 50 of file board_periph_reset.c.

◆ reset1_geom_t

enum reset1_geom_t : uint64_t

RSTSR1 window geometry (ra8_reset_regs.h).

Enumerator
k_rstsr1_base 

RSTSR1 (32-bit).

k_rstsr1_span 

Single 32-bit register.

Definition at line 44 of file board_periph_reset.c.

◆ reset_flag_t

enum reset_flag_t : uint32_t

RSTSR flag bit masks (ra8_reset_regs.h).

Enumerator
k_rstsr0_porf 

RSTSR0.PORF power-on reset (bit 0).

k_rstsr1_iwdtrf 

RSTSR1.IWDTRF independent WDT (bit 0).

k_rstsr1_wdtrf 

RSTSR1.WDTRF watchdog reset (bit 1).

k_rstsr1_swrf 

RSTSR1.SWRF software reset (bit 2).

Definition at line 59 of file board_periph_reset.c.

◆ reset_order_t

enum reset_order_t : uint32_t

Per-tick order slot for the reset block (relative order only).

Enumerator
k_reset_block_order 

After the VBATT-backup block; report order.

Definition at line 67 of file board_periph_reset.c.

Function Documentation

◆ board_periph_reset_request_reboot()

void board_periph_reset_request_reboot ( bool watchdog,
bool iwdt )

Request a warm reboot from a peripheral model (e.g.

the watchdog).

A peripheral block cannot perform the reboot itself (the run loop in main.c owns that), so it records a request here and the run loop polls board_periph_reset_take_request once per chunk. Used by the WDT model when its down-counter underflows in reset mode. Exactly one of the flags should be true.

Parameters
[in]watchdogtrue for a watchdog-0 reset (RSTSR1.WDTRF).
[in]iwdttrue for an independent-watchdog reset (RSTSR1.IWDTRF).
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph reset request reboot.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 96 of file board_periph_reset.c.

References k_reboot_cause_iwdt, k_reboot_cause_wdt, and s_reboot_req_cause.

Referenced by internal_wdt_tick().

◆ board_periph_reset_set_cause()

void board_periph_reset_set_cause ( bool power_on,
bool software,
bool watchdog,
bool iwdt )

Record the cause of a warm reboot in the sticky RSTSRn flags.

Called by the ra8_emulator reboot path (main.c) just before it re-enters the firmware from the reset vector, so the next boot reads the reset cause it expects. For a power-on reboot, leaves RSTSR0.PORF set and asserts nothing else. For any other reset, clears PORF and latches the specific cause in RSTSR1: SWRF (software reset / AIRCR.SYSRESETREQ), WDTRF (watchdog-0 reset), or IWDTRF (independent-watchdog reset). The reset block's reset hook preserves these flags across the warm reboot. Exactly one of the four booleans should be true for a well-formed reset cause.

Parameters
[in]power_ontrue for a power-on / cold reboot (RSTSR0.PORF).
[in]softwaretrue to latch RSTSR1.SWRF (software reset).
[in]watchdogtrue to latch RSTSR1.WDTRF (watchdog-0 reset).
[in]iwdttrue to latch RSTSR1.IWDTRF (independent-watchdog reset).
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph reset set cause.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 119 of file board_periph_reset.c.

References k_rstsr0_porf, k_rstsr1_iwdtrf, k_rstsr1_swrf, k_rstsr1_wdtrf, s_rstsr0, and s_rstsr1.

Referenced by internal_run_loop_prologue(), and internal_run_loop_run_chunk().

◆ board_periph_reset_take_request()

bool board_periph_reset_take_request ( bool * out_watchdog,
bool * out_iwdt )

Consume a pending peripheral reboot request, if any (run-loop side).

Polled by the run loop each chunk. If a peripheral requested a warm reboot (board_periph_reset_request_reboot), reports which cause and clears the request so it fires once.

Parameters
[out]out_watchdogSet true if the request was a watchdog-0 reset.
[out]out_iwdtSet true if the request was an independent-WDT reset.
Returns
true if a request was pending (and consumed); false otherwise.
Since
0.1.0
Return values
trueThe board periph reset take request condition holds or completed successfully; false otherwise.
Precondition
Arguments satisfy the ranges documented for board periph reset take request.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 105 of file board_periph_reset.c.

References k_reboot_cause_iwdt, k_reboot_cause_none, k_reboot_cause_wdt, and s_reboot_req_cause.

Referenced by internal_run_loop_prologue().

◆ internal_reset0_read()

RA8_INTERNAL uint64_t internal_reset0_read ( uc_engine * uc,
uint64_t addr,
unsigned size )
static

MMIO read inside the RSTSR0 / RSTSR2 / RSTSR3 window.

MMIO read inside the rstsr0 / rstsr2 / rstsr3 window; this step is contained within the board periph reset 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 reset0 read result produced by the board periph reset model.
Return values
valueThe operation-specific reset0 read value.
Precondition
Arguments satisfy the ranges documented for reset0 read.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph reset 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 211 of file board_periph_reset.c.

References k_rstsr0_base, k_rstsr0_off_r0, k_rstsr0_off_r2, k_rstsr0_off_r3, RA8_INTERNAL, s_rstsr0, s_rstsr2, and s_rstsr3.

◆ internal_reset0_write()

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

MMIO write inside the RSTSR0 / RSTSR2 / RSTSR3 window.

MMIO write inside the rstsr0 / rstsr2 / rstsr3 window; this step is contained within the board periph reset 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 reset0 write.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph reset 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 241 of file board_periph_reset.c.

References k_rstsr0_base, k_rstsr0_off_r0, k_rstsr0_off_r2, k_rstsr0_off_r3, s_rstsr0, s_rstsr2, and s_rstsr3.

◆ internal_reset1_read()

RA8_INTERNAL uint64_t internal_reset1_read ( uc_engine * uc,
uint64_t addr,
unsigned size )
static

MMIO read inside the RSTSR1 window.

MMIO read inside the rstsr1 window; this step is contained within the board periph reset 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 reset1 read result produced by the board periph reset model.
Return values
valueThe operation-specific reset1 read value.
Precondition
Arguments satisfy the ranges documented for reset1 read.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph reset 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 168 of file board_periph_reset.c.

References RA8_INTERNAL, and s_rstsr1.

◆ internal_reset1_write()

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

MMIO write inside the RSTSR1 window (write-0-to-clear flags).

MMIO write inside the rstsr1 window (write-0-to-clear flags); this step is contained within the board periph reset 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 reset1 write.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph reset 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 189 of file board_periph_reset.c.

References s_rstsr1.

◆ internal_reset_block_register()

RA8_INTERNAL void internal_reset_block_register ( void )
static

Register the reset-status windows + seed PORF (cold boot).

Definition at line 304 of file board_periph_reset.c.

References board_periph_register_block(), k_rstsr0_porf, RA8_INTERNAL, s_k_reset0_block, s_k_reset1_block, and s_rstsr0.

◆ internal_reset_report()

RA8_INTERNAL void internal_reset_report ( void )
static

End-of-run reset section: the latched cause flags.

End-of-run reset section: the latched cause flags; this step is contained within the board periph reset model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for reset report.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph reset 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 263 of file board_periph_reset.c.

References k_rstsr0_porf, k_rstsr1_iwdtrf, k_rstsr1_swrf, k_rstsr1_wdtrf, priv_emu_io_errf(), RA8_INTERNAL, s_rstsr0, and s_rstsr1.

◆ internal_reset_reset()

RA8_INTERNAL void internal_reset_reset ( void )
static

Reset hook: the cause flags are sticky, so this preserves them.

Reset hook: the cause flags are sticky, so this preserves them; this step is contained within the board periph reset model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for reset reset.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph reset 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 148 of file board_periph_reset.c.

References RA8_INTERNAL.

Variable Documentation

◆ s_k_reset0_block

const board_periph_block_t s_k_reset0_block
static
Initial value:
= {
.base = (uint64_t)k_rstsr0_base,
.span = (uint64_t)k_rstsr0_span,
.order = (uint32_t)k_reset_block_order,
.tick = nullptr,
.reset = nullptr,
.report = nullptr,
.name = "RESET-RSTSR0",
}
static RA8_INTERNAL uint64_t internal_reset0_read(uc_engine *uc, uint64_t addr, unsigned size)
MMIO read inside the RSTSR0 / RSTSR2 / RSTSR3 window.
@ k_reset_block_order
After the VBATT-backup block; report order.
@ k_rstsr0_span
Covers RSTSR0 / RSTSR2 / RSTSR3.
@ k_rstsr0_base
RSTSR0 (8-bit) window base.
static RA8_INTERNAL void internal_reset0_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
MMIO write inside the RSTSR0 / RSTSR2 / RSTSR3 window.
-proof

RSTSR0 / RSTSR2 / RSTSR3 block descriptor.

Definition at line 291 of file board_periph_reset.c.

Referenced by internal_reset_block_register().

◆ s_k_reset1_block

const board_periph_block_t s_k_reset1_block
static
Initial value:
= {
.base = (uint64_t)k_rstsr1_base,
.span = (uint64_t)k_rstsr1_span,
.order = (uint32_t)k_reset_block_order,
.tick = nullptr,
.name = "RESET-RSTSR1",
}
static RA8_INTERNAL void internal_reset_report(void)
End-of-run reset section: the latched cause flags.
static RA8_INTERNAL void internal_reset_reset(void)
Reset hook: the cause flags are sticky, so this preserves them.
@ k_rstsr1_span
Single 32-bit register.
@ k_rstsr1_base
RSTSR1 (32-bit).
static RA8_INTERNAL uint64_t internal_reset1_read(uc_engine *uc, uint64_t addr, unsigned size)
MMIO read inside the RSTSR1 window.
static RA8_INTERNAL void internal_reset1_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
MMIO write inside the RSTSR1 window (write-0-to-clear flags).

RSTSR1 block descriptor (owns the report).

Definition at line 278 of file board_periph_reset.c.

Referenced by internal_reset_block_register().

◆ s_reboot_req_cause

uint32_t s_reboot_req_cause
static

◆ s_rstsr0

uint8_t s_rstsr0
static

◆ s_rstsr1

uint32_t s_rstsr1
static

Sticky reset-cause flags (survive a warm reboot).

Held across the block reset hook (it leaves them untouched) so the cause the reboot recorded is still readable on the next boot. Cleared only at process start (static zero-init), where the constructor then seeds PORF: the first-ever boot is a power-on. RSTSR1 sticky flags.

Definition at line 79 of file board_periph_reset.c.

Referenced by board_periph_reset_set_cause(), internal_reset1_read(), internal_reset1_write(), and internal_reset_report().

◆ s_rstsr2

uint8_t s_rstsr2
static

RSTSR2 (CWSF).

Definition at line 81 of file board_periph_reset.c.

Referenced by internal_reset0_read(), and internal_reset0_write().

◆ s_rstsr3

uint8_t s_rstsr3
static

RSTSR3.

Definition at line 82 of file board_periph_reset.c.

Referenced by internal_reset0_read(), and internal_reset0_write().