ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_dtc.c
Go to the documentation of this file.
1
36
37#include "ra8_dtc.h"
38
39#include <stdint.h>
40
41#include "ra8_attributes.h"
42#include "ra8_cache.h"
43#include "ra8_check.h"
44#include "ra8_dtc_regs.h"
45#include "ra8_err.h"
46#include "ra8_log.h"
47#include "ra8_mstp.h"
48
49static const char* s_tag = "DTC";
50
52static void* s_dtc_ctx;
53
54/* Retained DTC vector-table base. ra8_dtc_enable() has no vector_base
55 * argument, yet the DTC fetches the table from RAM at DTCST=1; keep the
56 * base from ra8_dtc_init()/ra8_dtc_reconfigure() so the pre-enable D-cache
57 * clean can flush the caller-populated entries out to memory. */
58static void* s_dtc_vector_base;
59
60ra8_err_t ra8_dtc_init(void* vector_base)
61{
62 RA8_CHECK_NULL_PTR(vector_base, s_tag, "vector_base must not be nullptr");
63
64 /* DTC0 + DMAC0 share MSTPA22; ra8_mstp keeps the ref count so
65 * a follow-up ra8_dmac_start does not flip the bit again.
66 * HUM Ch 11.2.6 "MSTPCRA : Module Stop Control Register A" p 443 */
68 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
69 RA8_RETURN_ON_ERROR(mst_err, s_tag, "dtc_init: mstp enable");
70 /* GCOVR_EXCL_BR_STOP */
71
72 volatile r_dtc_regs_t* reg = ra8_dtc();
73 /* HUM 18.2.1 DTCCR p 786 / 18.2.2 DTCVBR p 787 / 18.2.3 DTCST p 787. On a
74 * TrustZone part the secure (and flat-secure) DTC engine fetches its vector
75 * table from DTCVBR_SEC (+0x14, HUM 18.2.6 p 789); the plain DTCVBR (+0x04)
76 * is the Non-secure alias and a secure write to it is dropped. Program both
77 * so the table is found in either world (and so the ra8_emulator DTC model,
78 * which shadows DTCVBR, still sees the base). */
79 reg->DTCCR = 0U;
80 reg->DTCVBR = (uint32_t)(uintptr_t)vector_base;
81 reg->DTCVBR_SEC = (uint32_t)(uintptr_t)vector_base;
82 reg->DTCST = 0U;
83 s_dtc_vector_base = vector_base; /* flushed to RAM by ra8_dtc_enable() */
84
85 ra8_log_info(s_tag, "dtc_init");
86 return k_ra8_ok;
87}
88
90{
91 volatile r_dtc_regs_t* reg = ra8_dtc();
92 /* HUM 18.2.3 DTCST p 787 / 18.2.1 DTCCR p 786 / 18.2.2 DTCVBR p 787 /
93 * 18.2.6 DTCVBR_SEC p 789. Clear both vector bases (see ra8_dtc_init). */
94 reg->DTCST = 0U;
95 reg->DTCCR = 0U;
96 reg->DTCVBR = 0U;
97 reg->DTCVBR_SEC = 0U;
98 s_dtc_fn = nullptr;
99 s_dtc_ctx = nullptr;
100 s_dtc_vector_base = nullptr;
102}
103
105{
106 /* Cache coherency (M85 L1 D-cache): the DTC fetches its vector table --
107 * and, one indirection on, each per-source TI block -- straight from RAM.
108 * Vector-table entries the CPU wrote between ra8_dtc_init() and here may
109 * still sit in dirty cache lines the engine cannot see, so clean (write
110 * back) the table region before DTCST=1. Clean is non-destructive and an
111 * architectural no-op when the D-cache is off (every current app), so it
112 * is added unconditionally. The TI blocks and the source/destination data
113 * buffers are NOT reachable from this driver: the DTC is direction-blind
114 * (like the DMAC), so the owning driver cleans the TI/source and
115 * invalidates the destination. */
116 if (s_dtc_vector_base != nullptr) {
118 }
119 /* HUM 18.2.3 DTCST p 787. */
121 return k_ra8_ok;
122}
123
125{
126 /* HUM 18.2.3 DTCST p 787. */
127 ra8_dtc()->DTCST = 0U;
128 return k_ra8_ok;
129}
130
132{
133 RA8_CHECK_NULL_PTR(vector_base, s_tag, "vector_base must not be nullptr");
134 volatile r_dtc_regs_t* reg = ra8_dtc();
135 /* HUM 18.2.3 DTCST p 787 / 18.2.2 DTCVBR p 787 / 18.2.1 DTCCR p 786.
136 * Mirrors FSP r_dtc_set_info(): drop RRS before touching the table,
137 * rewrite the base, then re-enable RRS so the read-skip cache picks
138 * up the fresh entries. Bit 3 of DTCCR is reserved-write-1. */
139 reg->DTCST = 0U;
140 reg->DTCVBR = (uint32_t)(uintptr_t)vector_base;
141 reg->DTCVBR_SEC = (uint32_t)(uintptr_t)vector_base;
142 s_dtc_vector_base = vector_base;
143 /* Cache coherency (M85 L1 D-cache): the RRS toggle below drops the DTC's
144 * internal read-skip cache and forces it to re-read its descriptors from
145 * RAM. Clean the CPU's vector-table edits out to memory first so the
146 * re-read sees them, not stale dirty lines. Non-destructive and a no-op
147 * when the D-cache is off. The indirectly-referenced TI blocks live one
148 * pointer-hop away and are flushed by the owning driver (DTC is
149 * direction-blind, like the DMAC). */
153 return k_ra8_ok;
154}
155
156ra8_err_t ra8_dtc_get_status(uint16_t* out_mask)
157{
158 RA8_CHECK_NULL_PTR(out_mask, s_tag, "out_mask must not be nullptr");
159 /* HUM 18.2.4 DTCSTS p 788. */
160 *out_mask = ra8_dtc()->DTCSTS;
161 return k_ra8_ok;
162}
163
165{
166 volatile r_dtc_regs_t* reg = ra8_dtc();
167 /* HUM 18.2.4 DTCSTS p 788. */
168 reg->DTCSTS = (uint16_t)(reg->DTCSTS & ~mask);
169 return k_ra8_ok;
170}
171
173{
174 s_dtc_fn = fn;
175 s_dtc_ctx = ctx;
176 return k_ra8_ok;
177}
178
181{
182 volatile r_dtc_regs_t* reg = ra8_dtc();
183 /* HUM 18.2.4 DTCSTS p 788. */
184 const uint16_t mask = reg->DTCSTS;
185 const ra8_dtc_event_fn_t fn = s_dtc_fn;
186 void* const ctx = s_dtc_ctx;
187 reg->DTCSTS = 0U;
188 if (fn != nullptr) {
189 fn(ctx, mask);
190 }
191}
192
194{
195 /* HUM 18.2.3 DTCST p 787. */
196 ra8_dtc()->DTCST = 0U;
198}
199
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_ISR_SAFE
The function is callable from interrupt context.
Cortex-M85 L1 cache maintenance, enable/disable, and I-cache invalidate.
ra8_err_t ra8_cache_dcache_clean_by_addr(const void *addr, uint32_t size)
Clean (write back) the D-cache lines covering a byte range.
Definition ra8_cache.c:180
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
ra8_err_t ra8_dtc_disable(void)
Stop the DTC module.
Definition ra8_dtc.c:124
static ra8_dtc_event_fn_t s_dtc_fn
Definition ra8_dtc.c:51
ra8_err_t ra8_dtc_enter_stop(void)
Put the DTC into MSTP-gated stop.
Definition ra8_dtc.c:193
ra8_err_t ra8_dtc_get_status(uint16_t *out_mask)
Read the DTCSTS activation status register.
Definition ra8_dtc.c:156
ra8_err_t ra8_dtc_deinit(void)
Tear down the DTC (clears run bit + drops MSTP ref).
Definition ra8_dtc.c:89
ra8_err_t ra8_dtc_reconfigure(void *vector_base)
Reconfigure the DTC vector base at runtime.
Definition ra8_dtc.c:131
ra8_err_t ra8_dtc_exit_stop(void)
Exit MSTP-gated stop and re-arm the engine.
Definition ra8_dtc.c:200
static void * s_dtc_ctx
Definition ra8_dtc.c:52
void ra8_dtc_dispatch(void)
Fire the attached activation callback with current DTCSTS.
Definition ra8_dtc.c:180
ra8_err_t ra8_dtc_attach_handler(ra8_dtc_event_fn_t fn, void *ctx)
Attach a shared activation-complete callback.
Definition ra8_dtc.c:172
static void * s_dtc_vector_base
Definition ra8_dtc.c:58
ra8_err_t ra8_dtc_enable(void)
Start the DTC module.
Definition ra8_dtc.c:104
ra8_err_t ra8_dtc_clear_status(uint16_t mask)
Clear sticky bits in DTCSTS.
Definition ra8_dtc.c:164
ra8_err_t ra8_dtc_init(void *vector_base)
Initialise the DTC and install its vector table base.
Definition ra8_dtc.c:60
Data Transfer Controller (DTC) driver.
void(* ra8_dtc_event_fn_t)(void *ctx, uint16_t status)
DTC activation-complete callback.
Definition ra8_dtc.h:47
DTC (Data Transfer Controller) register layout for the RA8D2.
@ k_ra8_dtcst_dtcst_msk
DTCST.DTCST mask.
static volatile r_dtc_regs_t * ra8_dtc(void)
Get pointer to the DTC controller register block.
@ k_ra8_dtc_vector_table_align
DTCVBR write granularity (HUM 18.2.2).
@ k_ra8_dtccr_rrs_enable
DTCCR with RRS=1 (FSP value).
@ k_ra8_dtccr_rrs_disable
DTCCR with RRS=0 (FSP value).
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
Definition ra8_mstp.c:343
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Definition ra8_mstp.c:382
@ k_ra8_mstp_dmac0_dtc0
MSTPA22 DMAC0+DTC0 (shared).
DTC controller register block at 0x4000AC00.
volatile uint8_t DTCST
+0x0C Module Start Register (HUM 18.2.3).
volatile uint32_t DTCVBR_SEC
+0x14 Secure Vector Base (HUM 18.2.6).
volatile uint8_t DTCCR
+0x00 Control Register (HUM 18.2.1).
volatile uint32_t DTCVBR
+0x04 Vector Base Register (HUM 18.2.2).
volatile uint16_t DTCSTS
+0x0E Status Register (HUM 18.2.4).