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

Window Watchdog Timer (WDT0 / WWDT) model for ra8_emulator. More...

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

Go to the source code of this file.

Data Structures

struct  wdt_state_t
 WDT model state. More...

Enumerations

enum  wdt_geom_t : uint64_t {
  k_wdt_base = 0x40202600UL ,
  k_wdt_span = 0x10UL ,
  k_wdt_off_wdtrr = 0x00UL ,
  k_wdt_off_wdtcr = 0x02UL ,
  k_wdt_off_wdtsr = 0x04UL ,
  k_wdt_off_wdtrcr = 0x06UL
}
 WDT0 block geometry (ra8_wdt_regs.h, r_wdt_regs_t). More...
enum  wdt_field_t : uint32_t {
  k_wdt_refresh_a = 0x00U ,
  k_wdt_refresh_b = 0xFFU ,
  k_wdt_rcr_rstirqs = 0x80U ,
  k_wdt_sr_cntval = 0x3FFFU ,
  k_wdt_sr_undff = 0x4000U ,
  k_wdt_timeout_ticks = 400U
}
 WDT register field constants (ra8_wdt_regs.h). More...
enum  wdt_order_t : uint32_t { k_wdt_block_order = 180U }
 Per-tick order slot for the WDT block (relative order only). More...

Functions

static RA8_INTERNAL void internal_wdt_tick (uc_engine *uc)
 Per-chunk advance: run the armed down-counter; reset on underflow.
static RA8_INTERNAL void internal_wdt_reset (void)
 Reset the WDT model to power-on state.
static RA8_INTERNAL uint64_t internal_wdt_read (uc_engine *uc, uint64_t addr, unsigned size)
 MMIO read inside the WDT window.
static RA8_INTERNAL void internal_wdt_write (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
 MMIO write inside the WDT window.
static RA8_INTERNAL void internal_wdt_report (void)
 End-of-run WDT section: refreshes and whether it fired a reset.
static RA8_INTERNAL void internal_wdt_block_register (void)
 Register the WDT0 block before main (host constructor).

Variables

static wdt_state_t s_wdt
static const board_periph_block_t s_k_wdt_block
 WDT0 block descriptor (self-registered with the core).

Detailed Description

Window Watchdog Timer (WDT0 / WWDT) model for ra8_emulator.

Models the RA8D2 WDT0 (ra8_wdt_regs.h, ra8_wdt.c) at 0x40202600 closely enough that a watchdog reset actually fires when the firmware stops refreshing the counter, instead of the timeout never happening. Against the sparse fallback wdt_reset_recovery_demo armed the WWDT for reset and then stopped refreshing, but the chip never reset, so the post-reset boot (and its "wdt: reset_by=watchdog" banner) was unreachable. This block runs the down-counter and, on underflow in reset mode, asks the run loop to warm-reboot the firmware with the watchdog-reset cause latched, so the next boot reads k_ra8_reset_cause_wdt0.

Behaviour (HUM Ch 27.2):

  • WDTRR (0x00) is the refresh register: the 0x00 then 0xFF unlock sequence both ARMS the counter (the first refresh starts it) and RELOADS it to full. A stray write that breaks the sequence is ignored here (the model does not synthesise the refresh-error path).
  • WDTCR (0x02) selects the timeout period (TOPS); shadowed so a read back works. The board emulator has no real watchdog clock, so the timeout maps to a fixed number of emulation ticks (one tick == one run-loop chunk): large enough that a normally-refreshing app stays alive, small enough that a deliberate stop trips within the run budget.
  • WDTSR (0x04) reports the live down-counter in CNTVAL and the UNDFF underflow flag.
  • WDTRCR (0x06) RSTIRQS selects reset (1) vs NMI / IRQ (0) on underflow.

The per-chunk tick hook decrements the counter once it is armed; when it reaches zero with RSTIRQS set, it raises the reboot request and disarms (so it fires exactly once). With RSTIRQS clear (NMI / IRQ mode), the underflow latches UNDFF but does not reboot – the board emulator does not route the WDT NMI.

Since
0.1.0

Definition in file board_periph_wdt.c.

Enumeration Type Documentation

◆ wdt_field_t

enum wdt_field_t : uint32_t

WDT register field constants (ra8_wdt_regs.h).

Enumerator
k_wdt_refresh_a 

First byte of the refresh sequence.

k_wdt_refresh_b 

Second byte of the refresh sequence.

k_wdt_rcr_rstirqs 

WDTRCR.RSTIRQS: 1 = reset on underflow.

k_wdt_sr_cntval 

WDTSR.CNTVAL[13:0] live counter.

k_wdt_sr_undff 

WDTSR.UNDFF underflow flag (bit 14).

k_wdt_timeout_ticks 

Wdt timeout ticks.

Definition at line 58 of file board_periph_wdt.c.

◆ wdt_geom_t

enum wdt_geom_t : uint64_t

WDT0 block geometry (ra8_wdt_regs.h, r_wdt_regs_t).

Enumerator
k_wdt_base 

WDT0 base (HUM Ch 27).

k_wdt_span 

Covers WDTRR..WDTRCR.

k_wdt_off_wdtrr 

WDTRR refresh register (8b).

k_wdt_off_wdtcr 

WDTCR control (16b).

k_wdt_off_wdtsr 

WDTSR status (16b).

k_wdt_off_wdtrcr 

WDTRCR reset control (8b).

Definition at line 48 of file board_periph_wdt.c.

◆ wdt_order_t

enum wdt_order_t : uint32_t

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

Enumerator
k_wdt_block_order 

After the reset block; report order.

Definition at line 71 of file board_periph_wdt.c.

Function Documentation

◆ internal_wdt_block_register()

RA8_INTERNAL void internal_wdt_block_register ( void )
static

Register the WDT0 block before main (host constructor).

Definition at line 230 of file board_periph_wdt.c.

References board_periph_register_block(), RA8_INTERNAL, and s_k_wdt_block.

◆ internal_wdt_read()

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

MMIO read inside the WDT window.

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

References k_wdt_base, k_wdt_off_wdtcr, k_wdt_off_wdtrcr, k_wdt_off_wdtsr, k_wdt_sr_cntval, RA8_INTERNAL, and s_wdt.

◆ internal_wdt_report()

RA8_INTERNAL void internal_wdt_report ( void )
static

End-of-run WDT section: refreshes and whether it fired a reset.

End-of-run wdt section: refreshes and whether it fired a reset; this step is contained within the board periph watchdog model and uses bounded caller or module-owned storage.

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

References priv_emu_io_errf(), RA8_INTERNAL, and s_wdt.

◆ internal_wdt_reset()

RA8_INTERNAL void internal_wdt_reset ( void )
static

Reset the WDT model to power-on state.

Reset the wdt model to power-on state; this step is contained within the board periph watchdog model and uses bounded caller or module-owned storage.

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

References RA8_INTERNAL, and s_wdt.

◆ internal_wdt_tick()

RA8_INTERNAL void internal_wdt_tick ( uc_engine * uc)
static

Per-chunk advance: run the armed down-counter; reset on underflow.

Per-chunk advance: run the armed down-counter; reset on underflow; this step is contained within the board periph watchdog model and uses bounded caller or module-owned storage.

Parameters
[in,out]ucUnicorn engine whose emulated state is read or updated.
Precondition
Arguments satisfy the ranges documented for watchdog tick.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph watchdog 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 98 of file board_periph_wdt.c.

References board_periph_reset_request_reboot(), k_wdt_rcr_rstirqs, k_wdt_sr_undff, RA8_INTERNAL, and s_wdt.

◆ internal_wdt_write()

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

MMIO write inside the WDT window.

MMIO write inside the wdt window; this step is contained within the board periph watchdog 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 watchdog write.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph watchdog 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 175 of file board_periph_wdt.c.

References k_wdt_base, k_wdt_off_wdtcr, k_wdt_off_wdtrcr, k_wdt_off_wdtrr, k_wdt_refresh_a, k_wdt_refresh_b, k_wdt_timeout_ticks, and s_wdt.

Variable Documentation

◆ s_k_wdt_block

const board_periph_block_t s_k_wdt_block
static
Initial value:
= {
.base = (uint64_t)k_wdt_base,
.span = (uint64_t)k_wdt_span,
.order = (uint32_t)k_wdt_block_order,
.name = "WDT0",
}
static RA8_INTERNAL void internal_wdt_tick(uc_engine *uc)
Per-chunk advance: run the armed down-counter; reset on underflow.
static RA8_INTERNAL void internal_wdt_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
MMIO write inside the WDT window.
static RA8_INTERNAL uint64_t internal_wdt_read(uc_engine *uc, uint64_t addr, unsigned size)
MMIO read inside the WDT window.
@ k_wdt_block_order
After the reset block; report order.
static RA8_INTERNAL void internal_wdt_reset(void)
Reset the WDT model to power-on state.
static RA8_INTERNAL void internal_wdt_report(void)
End-of-run WDT section: refreshes and whether it fired a reset.
@ k_wdt_base
WDT0 base (HUM Ch 27).
@ k_wdt_span
Covers WDTRR..WDTRCR.
-proof

WDT0 block descriptor (self-registered with the core).

Definition at line 217 of file board_periph_wdt.c.

Referenced by internal_wdt_block_register().

◆ s_wdt