ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
board_periph_poeg.c
Go to the documentation of this file.
1
42
43#include <stdint.h>
44#include <stdio.h>
45
46#include "board_periph_block.h"
48
50typedef enum : uint64_t {
51 k_poeg_base = 0x40212000UL,
52 k_poeg_stride = 0x100UL,
54 k_poeg_span = 0x100UL * 4UL,
57
59typedef enum : uint32_t {
60 k_poegg_pidf = 0x00000001UL,
61 k_poegg_iocf = 0x00000002UL,
62 k_poegg_ostp = 0x00000004UL,
63 k_poegg_ssf = 0x00000008UL,
64 k_poegg_st = 0x00010000UL,
68
70typedef enum : uint32_t {
73
75typedef struct {
76 uint32_t poegg[k_poeg_count];
77 uint32_t asserts;
78 uint32_t clears;
80
82
97RA8_INTERNAL static uint32_t internal_poeg_with_st(uint32_t writable)
98{
99 if ((writable & (uint32_t)k_poegg_trig) != 0U) {
100 return writable | (uint32_t)k_poegg_st;
101 }
102 return writable & ~(uint32_t)k_poegg_st;
103}
104
114{
115 s_poeg = (poeg_state_t){};
116}
117
131RA8_INTERNAL static uint64_t internal_poeg_read(uc_engine* uc, uint64_t addr, unsigned size)
132{
133 (void)uc;
134 (void)size;
135 const uint64_t off = addr - (uint64_t)k_poeg_base;
136 const uint64_t group = off / (uint64_t)k_poeg_stride;
137 const uint64_t reg = off % (uint64_t)k_poeg_stride;
138 if (group >= (uint64_t)k_poeg_count) {
139 return 0U;
140 }
141 if (reg == (uint64_t)k_poeg_off_poegg) {
142 return s_poeg.poegg[group];
143 }
144 return 0U;
145}
146
159RA8_INTERNAL static void
160internal_poeg_write(uc_engine* uc, uint64_t addr, unsigned size, uint64_t value)
161{
162 (void)uc;
163 (void)size;
164 const uint64_t off = addr - (uint64_t)k_poeg_base;
165 const uint64_t group = off / (uint64_t)k_poeg_stride;
166 const uint64_t reg = off % (uint64_t)k_poeg_stride;
167 if (group >= (uint64_t)k_poeg_count) {
168 return;
169 }
170 if (reg != (uint64_t)k_poeg_off_poegg) {
171 return;
172 }
173 /* ST is read-only: strip any incoming ST, then re-derive it from the
174 * request flags so a software-stop assert / clear moves ST as hardware would. */
175 const uint32_t writable = (uint32_t)value & ~(uint32_t)k_poegg_st;
176 const uint32_t prev = s_poeg.poegg[group];
177 const uint32_t next = internal_poeg_with_st(writable);
178 s_poeg.poegg[group] = next;
179 if (((prev & (uint32_t)k_poegg_st) == 0U) && ((next & (uint32_t)k_poegg_st) != 0U)) {
180 s_poeg.asserts++;
181 }
182 if (((prev & (uint32_t)k_poegg_st) != 0U) && ((next & (uint32_t)k_poegg_st) == 0U)) {
183 s_poeg.clears++;
184 }
185}
186
196{
197 if ((s_poeg.asserts == 0U) && (s_poeg.clears == 0U)) {
198 return; /* Untouched: stay quiet. */
199 }
200 (void)priv_emu_io_errf(" POEG : shutoffs=%u re-enables=%u\n",
201 s_poeg.asserts,
202 s_poeg.clears);
203}
204
207 .base = (uint64_t)k_poeg_base,
208 .span = (uint64_t)k_poeg_span,
209 .order = (uint32_t)k_poeg_block_order,
210 .read = internal_poeg_read,
212 .tick = nullptr,
213 .reset = internal_poeg_reset,
214 .report = internal_poeg_report,
215 .name = "POEG",
216};
217
219[[gnu::constructor]] RA8_INTERNAL static void internal_poeg_block_register(void)
220{
222}
Decentralized peripheral-block registry for the board emulator core.
void board_periph_register_block(const board_periph_block_t *block)
Register a peripheral block's descriptor with the core registry.
static RA8_INTERNAL void internal_poeg_reset(void)
Reset the POEG model to power-on state.
static poeg_state_t s_poeg
poeg_geom_t
POEG block geometry (ra8_poeg_regs.h, r_poeg_regs_t).
@ k_poeg_off_poegg
POEGG setting + status.
@ k_poeg_base
POEG0 base (HUM Ch 21.2.1).
@ k_poeg_span
Covers all four groups.
@ k_poeg_count
POEG0..POEG3.
@ k_poeg_stride
Bytes per POEG group.
static RA8_INTERNAL void internal_poeg_block_register(void)
Register the POEG block before main (host constructor).
static RA8_INTERNAL uint64_t internal_poeg_read(uc_engine *uc, uint64_t addr, unsigned size)
MMIO read inside the POEG window.
static RA8_INTERNAL void internal_poeg_report(void)
End-of-run POEG section: shutoff assert / re-enable counts.
static RA8_INTERNAL uint32_t internal_poeg_with_st(uint32_t writable)
Recompute the read-only ST bit from the active request flags.
static const board_periph_block_t s_k_poeg_block
POEG block descriptor (self-registered with the core).
poeg_order_t
Per-tick order slot for the POEG block (report order only).
@ k_poeg_block_order
Just after the GPT/AGT timers (20).
poegg_field_t
POEGG field masks (ra8_poeg.h enum mirror).
@ k_poegg_st
Output-disable STATE flag (bit 16).
@ k_poegg_ssf
Software-stop request flag (bit 3).
@ k_poegg_iocf
Output-short request flag (bit 1).
@ k_poegg_trig
Any request flag: ST is the OR of these.
@ k_poegg_ostp
Osc-stop request flag (bit 2).
@ k_poegg_pidf
Port-input request flag (bit 0).
static RA8_INTERNAL void internal_poeg_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
MMIO write inside the POEG window.
Bounded raw-descriptor I/O seam for the RA8 emulator.
emu_io_result_t priv_emu_io_errf(const char *format,...)
Format bounded text and write it to the injected error descriptor.
-proof
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
A modelled peripheral block's self-description for the core registry.
POEG register state.
uint32_t asserts
0->1 ST transitions (shutoffs).
uint32_t poegg[k_poeg_count]
Per-group POEGG shadow (ST derived).
uint32_t clears
1->0 ST transitions (re-enables).