|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Ethernet Generic PTP Timer (GPTP) model for ra8_emulator – HUM Ch 35. More...
#include <stdint.h>#include <stdio.h>#include "board_periph_block.h"#include "emu_host_io_internal.h"#include "ra8_ether_regs.h"Go to the source code of this file.
Data Structures | |
| struct | gptp_timer_t |
| Runtime state of one GPTP timer unit. More... | |
| struct | gptp_state_t |
| Whole-block model state. More... | |
Enumerations | |
| enum | gptp_win_geom_t : uint64_t { k_gptp_win_base = (uint64_t)k_ra8_gptp_base_addr , k_gptp_win_span = 0x1000UL } |
| Absolute window the block owns. More... | |
| enum | gptp_order_t : uint32_t { k_gptp_block_order = 59U } |
| Per-tick order slot: right after the R-Switch cluster (58). More... | |
| enum | gptp_time_const_t : uint64_t { k_gptp_eswclk_hz = 250000000ULL , k_gptp_tick_hz = 1000ULL , k_gptp_clk_per_tick = 250000ULL , k_gptp_subns_shift = 27ULL , k_gptp_ns_per_sec = 1000000000ULL , k_gptp_mask_nsec = 0x3FFFFFFFULL , k_gptp_mask_sec_u = 0x0000FFFFULL , k_gptp_mask_sec_48 = 0xFFFFFFFFFFFFULL , k_gptp_shift_sec_u = 32ULL , k_gptp_ipv_reset = 0x00000003ULL , k_gptp_hz_per_mhz = 1000000ULL } |
| Clock rate, fixed-point scale and field widths of the GPTP time. More... | |
| enum | gptp_access_const_t : uint32_t { k_gptp_reg32_bytes = 4U , k_gptp_byte_mask = 0xFFU , k_gptp_shift_byte = 8U } |
| Byte / word access constants for the flat config shadow. More... | |
Functions | |
| static uint64_t | internal_gptp_shadow_read (uint64_t off, unsigned size) |
Read size bytes little-endian from the config shadow at off. | |
| static void | internal_gptp_shadow_write (uint64_t off, unsigned size, uint64_t value) |
Write size bytes little-endian into the config shadow at off. | |
| static uint32_t | internal_gptp_shadow_u32 (uint64_t off) |
Read a 32-bit shadow register at window offset off. | |
| static bool | internal_gptp_decode_timer (uint64_t off, uint32_t *out_timer, uint64_t *out_inoff) |
| Resolve a window offset to a timer unit and its in-block offset. | |
| static void | internal_gptp_time_now (uint32_t t, uint64_t *out_sec, uint32_t *out_nsec) |
| Compute one unit's current GPTP time (offset + free-running counter). | |
| static void | internal_gptp_tick_timer (uint32_t t) |
| Advance one running unit's free-running accumulator by one tick. | |
| static void | internal_gptp_apply_tmec (uint32_t value) |
| Apply a PTPTMEC write: start each unit whose bit is set. | |
| static void | internal_gptp_apply_tmdc (uint32_t value) |
| Apply a PTPTMDC write: stop and clear each unit whose bit is set. | |
| static uint32_t | internal_gptp_read_tmec (void) |
| Read PTPTMEC back as the live enable bitmask across the units. | |
| static void | internal_gptp_commit_offset (uint32_t t) |
| Commit one unit's 78-bit offset from the staged PTPTOVCt registers. | |
| static bool | internal_gptp_read_monitor (uint32_t t, uint64_t inoff, uint32_t *out) |
| Serve a read of a per-timer monitoring register, or report "not one". | |
| static uint64_t | internal_gptp_read (uc_engine *uc, uint64_t addr, unsigned size) |
| MMIO read handler for the GPTP window. | |
| static void | internal_gptp_write (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value) |
| MMIO write handler for the GPTP window. | |
| static void | internal_gptp_tick (uc_engine *uc) |
| Per-tick advance for every running timer unit. | |
| static void | internal_gptp_reset (void) |
| Reset the GPTP model to its power-on state. | |
| static void | internal_gptp_report (void) |
| End-of-run GPTP section: report any unit that advanced. | |
| static void | internal_gptp_block_register (void) |
| Self-register the GPTP window before main runs (decentralized). | |
Variables | |
| static gptp_state_t | s_gptp |
| Singleton GPTP model state. | |
| static const board_periph_block_t | s_k_gptp_block |
| GPTP block descriptor. | |
Ethernet Generic PTP Timer (GPTP) model for ra8_emulator – HUM Ch 35.
Models the timer surface of the RA8D2 GPTP block (HUM Ch 35 "Ethernet
Generic PTP Timer (GPTP)" p 1925-1964) so the GENUINE ra8_eth_gptp driver – and the apps that assert against it – run headless. The block is a timer: two independent free-running counters that advance one nanosecond per nanosecond off the ESWM clock, plus an additive 78-bit offset. Before this block existed the 0x403E_0000 window fell through to the sparse config-reflect fallback – a write-back RAM shadow, where a counter can never advance – so eth_gptp_timestamp_demo / eth_tsn_tas_demo could not have their strongest assertion (the counter advances one second per second against an independent SysTick time base) checked anywhere. This block makes that assertion run.
What is modelled faithfully (per timer unit t = 0, 1 at +0x0020 + 0x40*t):
PTPTIVCt * clk_cycles_this_tick, the same gptpTimer = TimerOffset + FreeRunningTimerValue equation the manual gives. The clk is ESWCLK (HUM 9.10.23 "EtherSW Clock (ESWCLK)" p 398), which the CGC brings up to PLL1P/4 = 250 MHz; one emulator tick is one SysTick period (k_gptp_tick_hz = 1 kHz), so the counter tracks SysTick to the nanosecond and the demos' 10 % window closes. The rate is derived from the firmware's own PTPTIVCt (5.27 fixed-point ns/clk, HUM 35.3.2.3 p 1928): a wrong increment drifts the counter here just as it would on silicon – the model does not paper over a mis-programmed timer.Honest-model note: the media-clock capture / recovery (PTPMCCCm / PTPMCRCm), media-clock pin mapping, cyclic compare (PTPCCCc), the pulse-output timer and the security-config registers all need the MEDIA_IN / MEDIA_OUT / CYCLIC_COMP pins the EK-RA8D2 board does not route, so – exactly as ra8_eth_gptp itself leaves them alone – they are served by a flat config-reflect shadow inside this window (read back what was written), never a faked action.
Window: the whole [0x403E_0000, 0x403E_1000) GPTP aperture (HUM Ch 35.2 "gPTP Register List" Table 35.3 p 1926). The ESWM media-mux at 0x403E_1400 sits above it and stays in the sparse fallback.
Definition in file board_periph_gptp.c.
| enum gptp_access_const_t : uint32_t |
Byte / word access constants for the flat config shadow.
| Enumerator | |
|---|---|
| k_gptp_reg32_bytes | One 32-bit register. |
| k_gptp_byte_mask | Low 8 bits of a value. |
| k_gptp_shift_byte | One-byte shift. |
Definition at line 119 of file board_periph_gptp.c.
| enum gptp_order_t : uint32_t |
Per-tick order slot: right after the R-Switch cluster (58).
| Enumerator | |
|---|---|
| k_gptp_block_order | Tick / reset / report order (just after ETH). |
Definition at line 82 of file board_periph_gptp.c.
| enum gptp_time_const_t : uint64_t |
Clock rate, fixed-point scale and field widths of the GPTP time.
k_gptp_eswclk_hz is ESWCLK = PLL1P / 4 = 250 MHz (HUM 9.10.23 p 398), the clk that drives the free-running counter. One emulator tick is one SysTick period, so k_gptp_clk_per_tick = k_gptp_eswclk_hz / k_gptp_tick_hz is the number of clk cycles that elapse per tick. PTPTIVCt is 5.27 fixed-point nanoseconds (HUM 35.3.2.3 p 1928), so the sub-nanosecond scale is 2^k_gptp_subns_shift and the free-running accumulator carries a whole second every 1e9 << k_gptp_subns_shift fixed-point units. The GPTP time is 78 bits: nanoseconds in [29:0] and seconds split 32 + 16 across the M and U registers (HUM 35.3.3.3 to 35.3.3.5 p 1931-1932).
Definition at line 104 of file board_periph_gptp.c.
| enum gptp_win_geom_t : uint64_t |
Absolute window the block owns.
The full GPTP aperture of HUM Ch 35.2 Table 35.3 p 1926, base k_ra8_gptp_base_addr for k_gptp_win_span bytes.
| Enumerator | |
|---|---|
| k_gptp_win_base | GPTP window base (0x403E_0000). |
| k_gptp_win_span | Whole GPTP aperture length. |
Definition at line 76 of file board_periph_gptp.c.
|
static |
Apply a PTPTMDC write: stop and clear each unit whose bit is set.
Apply a ptptmdc write: stop and clear each unit whose bit is set; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
| [in] | value | Register or payload value involved in the operation. |
Definition at line 376 of file board_periph_gptp.c.
References k_ra8_gptp_timer_count, RA8_INTERNAL, and s_gptp.
Referenced by internal_gptp_write().
|
static |
Apply a PTPTMEC write: start each unit whose bit is set.
Apply a ptptmec write: start each unit whose bit is set; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
| [in] | value | Register or payload value involved in the operation. |
Definition at line 356 of file board_periph_gptp.c.
References k_ra8_gptp_timer_count, RA8_INTERNAL, and s_gptp.
Referenced by internal_gptp_write().
|
static |
Self-register the GPTP window before main runs (decentralized).
Definition at line 672 of file board_periph_gptp.c.
References board_periph_register_block(), RA8_INTERNAL, and s_k_gptp_block.
|
static |
Commit one unit's 78-bit offset from the staged PTPTOVCt registers.
The PTPTOVCtL write is what commits the whole offset (HUM 35.4.1.3.1 Figure 35.4 p 1944-1945); PTPTOVCtU / PTPTOVCtM were written first and already sit in the config shadow, so this reads them back and forms {U[15:0], M[31:0]} seconds with L[29:0] nanoseconds.
| [in] | t | Timer unit index (< k_ra8_gptp_timer_count). |
t is a valid unit index. off_sec is 48-bit and off_nsec below one second. Definition at line 428 of file board_periph_gptp.c.
References internal_gptp_shadow_u32(), k_gptp_mask_nsec, k_gptp_mask_sec_u, k_gptp_shift_sec_u, k_ra8_gptp_off_t_ptptovcl, k_ra8_gptp_off_t_ptptovcm, k_ra8_gptp_off_t_ptptovcu, k_ra8_gptp_off_timer0, k_ra8_gptp_timer_stride, RA8_INTERNAL, and s_gptp.
Referenced by internal_gptp_write().
|
static |
Resolve a window offset to a timer unit and its in-block offset.
| [in] | off | Window byte offset. |
| [out] | out_timer | Receives the unit index when off is inside a unit. |
| [out] | out_inoff | Receives the in-block offset when off is inside a unit. |
off lands inside one of the two per-timer blocks. | true | *out_timer / *out_inoff describe the addressed unit. |
| false | off is a global register or the reserved tail. |
Resolve a window offset to a timer unit and its in-block offset; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
Definition at line 247 of file board_periph_gptp.c.
References k_ra8_gptp_off_timer0, k_ra8_gptp_timer_count, and k_ra8_gptp_timer_stride.
Referenced by internal_gptp_read(), and internal_gptp_write().
|
static |
MMIO read handler for the GPTP window.
| [in,out] | uc | Active engine (unused: GPTP reads touch no SRAM). |
| [in] | addr | Absolute register address inside the window. |
| [in] | size | Access width (1 / 2 / 4). |
| value | A modelled register or the config shadow. |
addr is inside [k_gptp_win_base, k_gptp_win_base + k_gptp_win_span). size is 1, 2, or 4. MMIO read handler for the gptp window; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
Definition at line 531 of file board_periph_gptp.c.
References internal_gptp_decode_timer(), internal_gptp_read_monitor(), internal_gptp_read_tmec(), internal_gptp_shadow_read(), k_gptp_ipv_reset, k_gptp_win_base, k_ra8_gptp_off_ptpipv, k_ra8_gptp_off_ptptmdc, k_ra8_gptp_off_ptptmec, and RA8_INTERNAL.
|
static |
Serve a read of a per-timer monitoring register, or report "not one".
Reading PTPGPTPTMtL / PTPAVTPTMtL samples the counter and latches the matching M/U halves (HUM 35.4.1.3.4 Figure 35.7 p 1946 / 35.4.1.3.3 Figure 35.6 p 1945-1946); reading M/U returns the latched half. The AVTP view is the same instant flattened to nanoseconds modulo 2^64 (HUM 35.5.1.2 p 1952).
| [in] | t | Timer unit index (< k_ra8_gptp_timer_count). |
| [in] | inoff | In-block offset inside the unit. |
| [out] | out | Receives the register value when it is a monitoring register. |
inoff addressed a monitoring register (*out is set). | true | A monitoring register was served. |
| false | inoff is a config register (caller uses the shadow). |
t is a valid unit index and out is non-null. Definition at line 474 of file board_periph_gptp.c.
References internal_gptp_time_now(), k_gptp_mask_sec_u, k_gptp_ns_per_sec, k_gptp_shift_sec_u, k_ra8_gptp_off_t_ptpavtptml, k_ra8_gptp_off_t_ptpavtptmu, k_ra8_gptp_off_t_ptpgptptml, k_ra8_gptp_off_t_ptpgptptmm, k_ra8_gptp_off_t_ptpgptptmu, gptp_timer_t::latch_avtp_u, gptp_timer_t::latch_gptp_m, gptp_timer_t::latch_gptp_u, RA8_INTERNAL, and s_gptp.
Referenced by internal_gptp_read().
|
static |
Read PTPTMEC back as the live enable bitmask across the units.
Read ptptmec back as the live enable bitmask across the units; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
| value | The operation-specific gptp read tmec value. |
Definition at line 400 of file board_periph_gptp.c.
References k_ra8_gptp_timer_count, RA8_INTERNAL, and s_gptp.
Referenced by internal_gptp_read().
|
static |
End-of-run GPTP section: report any unit that advanced.
End-of-run gptp section: report any unit that advanced; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
Definition at line 639 of file board_periph_gptp.c.
References gptp_timer_t::acc_fixed, gptp_timer_t::acc_sec, gptp_timer_t::enabled, internal_gptp_time_now(), k_gptp_eswclk_hz, k_gptp_hz_per_mhz, k_ra8_gptp_timer_count, priv_emu_io_errf(), RA8_INTERNAL, and s_gptp.
|
static |
Reset the GPTP model to its power-on state.
Reset the gptp model to its power-on state; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
Definition at line 626 of file board_periph_gptp.c.
References RA8_INTERNAL, and s_gptp.
|
static |
Read size bytes little-endian from the config shadow at off.
Read size bytes little-endian from the config shadow at off; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
| [in] | off | Register or byte offset addressed by the operation. |
| [in] | size | Size of the requested region or access in bytes. |
| value | The operation-specific gptp shadow read value. |
Definition at line 182 of file board_periph_gptp.c.
References k_gptp_shift_byte, k_gptp_win_span, RA8_INTERNAL, and s_gptp.
Referenced by internal_gptp_read(), and internal_gptp_shadow_u32().
|
static |
Read a 32-bit shadow register at window offset off.
Read a 32-bit shadow register at window offset off; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
| [in] | off | Register or byte offset addressed by the operation. |
| value | The operation-specific gptp shadow u32 value. |
Definition at line 220 of file board_periph_gptp.c.
References internal_gptp_shadow_read(), k_gptp_reg32_bytes, and RA8_INTERNAL.
Referenced by internal_gptp_commit_offset(), and internal_gptp_tick_timer().
|
static |
Write size bytes little-endian into the config shadow at off.
Write size bytes little-endian into the config shadow at off; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
| [in] | off | Register or byte offset addressed by the operation. |
| [in] | size | Size of the requested region or access in bytes. |
| [in] | value | Register or payload value involved in the operation. |
Definition at line 202 of file board_periph_gptp.c.
References k_gptp_shift_byte, k_gptp_win_span, RA8_INTERNAL, and s_gptp.
Referenced by internal_gptp_write().
|
static |
Per-tick advance for every running timer unit.
Per-tick advance for every running timer unit; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
| [in,out] | uc | Unicorn engine whose emulated state is read or updated. |
Definition at line 610 of file board_periph_gptp.c.
References internal_gptp_tick_timer(), k_ra8_gptp_timer_count, and RA8_INTERNAL.
|
static |
Advance one running unit's free-running accumulator by one tick.
Adds PTPTIVCt * k_gptp_clk_per_tick fixed-point nanoseconds (HUM 35.5.1.1 p 1951, increment HUM 35.3.2.3 p 1928), then carries any whole seconds out of the sub-second accumulator so it never overflows.
| [in] | t | Timer unit index (< k_ra8_gptp_timer_count). |
t is a valid unit index. acc_fixed stays below one second in fixed point. Definition at line 321 of file board_periph_gptp.c.
References gptp_timer_t::acc_fixed, gptp_timer_t::acc_sec, gptp_timer_t::enabled, internal_gptp_shadow_u32(), k_gptp_clk_per_tick, k_gptp_ns_per_sec, k_gptp_subns_shift, k_ra8_gptp_off_t_ptptivc, k_ra8_gptp_off_timer0, k_ra8_gptp_timer_stride, RA8_INTERNAL, and s_gptp.
Referenced by internal_gptp_tick().
|
static |
Compute one unit's current GPTP time (offset + free-running counter).
Implements gptpTimer = TimerOffset + FreeRunningTimerValue (HUM 35.5.1.1 p 1951). A stopped unit reads time zero (HUM 35.3.2.1 p 1927).
| [in] | t | Timer unit index (< k_ra8_gptp_timer_count). |
| [out] | out_sec | Receives the 48-bit seconds field. |
| [out] | out_nsec | Receives the 30-bit nanoseconds field. |
t is a valid unit index and both out-pointers are non-null. *out_sec is below 2^48 and *out_nsec below one second. Definition at line 283 of file board_periph_gptp.c.
References gptp_timer_t::acc_fixed, gptp_timer_t::acc_sec, gptp_timer_t::enabled, k_gptp_mask_nsec, k_gptp_mask_sec_48, k_gptp_ns_per_sec, k_gptp_subns_shift, gptp_timer_t::off_nsec, gptp_timer_t::off_sec, RA8_INTERNAL, and s_gptp.
Referenced by internal_gptp_read_monitor(), and internal_gptp_report().
|
static |
MMIO write handler for the GPTP window.
| [in,out] | uc | Active engine (unused: GPTP writes touch no SRAM). |
| [in] | addr | Absolute register address inside the window. |
| [in] | size | Access width (1 / 2 / 4). |
| [in] | value | Value written. |
addr is inside the block window. size is 1, 2, or 4. value in the shadow. MMIO write handler for the gptp window; this step is contained within the board periph gptp model and uses bounded caller or module-owned storage.
Definition at line 577 of file board_periph_gptp.c.
References internal_gptp_apply_tmdc(), internal_gptp_apply_tmec(), internal_gptp_commit_offset(), internal_gptp_decode_timer(), internal_gptp_shadow_write(), k_gptp_win_base, k_ra8_gptp_off_ptpipv, k_ra8_gptp_off_ptptmdc, k_ra8_gptp_off_ptptmec, and k_ra8_gptp_off_t_ptptovcl.
|
static |
Singleton GPTP model state.
Definition at line 164 of file board_periph_gptp.c.
Referenced by internal_gptp_apply_tmdc(), internal_gptp_apply_tmec(), internal_gptp_commit_offset(), internal_gptp_read_monitor(), internal_gptp_read_tmec(), internal_gptp_report(), internal_gptp_reset(), internal_gptp_shadow_read(), internal_gptp_shadow_write(), internal_gptp_tick_timer(), and internal_gptp_time_now().
|
static |
GPTP block descriptor.
Definition at line 659 of file board_periph_gptp.c.
Referenced by internal_gptp_block_register().