ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_cache.c
Go to the documentation of this file.
1
30
31#include "ra8_cache.h"
32
33#include <stdint.h>
34
35#include "ra8_attributes.h"
36#include "ra8_check.h"
37#include "ra8_err.h"
38#include "ra8_hw_intrinsics.h"
39
41static const char* const s_tag = "ra8_cache";
42
49typedef enum : uintptr_t {
50 k_ra8_cache_ccr = 0xE000ED14UL,
51 k_ra8_cache_ctr = 0xE000ED7CUL,
52 k_ra8_cache_ccsidr = 0xE000ED80UL,
53 k_ra8_cache_csselr = 0xE000ED84UL,
54 k_ra8_cache_iciallu = 0xE000EF50UL,
55 k_ra8_cache_dcimvac = 0xE000EF5CUL,
56 k_ra8_cache_dcisw = 0xE000EF60UL,
57 k_ra8_cache_dccmvac = 0xE000EF68UL,
58 k_ra8_cache_dccimvac = 0xE000EF70UL,
59 k_ra8_cache_dccisw = 0xE000EF74UL,
61
80
92RA8_INTERNAL static inline volatile uint32_t* internal_ra8_cache_reg(ra8_cache_reg_addr_t addr)
93{
94 return (volatile uint32_t*)addr;
95}
96
98{
99 /* Arm v8-M ARM: CTR.DminLine = log2 of the smallest D-cache line in words. */
100 const uint32_t ctr = *internal_ra8_cache_reg(k_ra8_cache_ctr);
101 const uint32_t dmin =
102 (ctr >> (uint32_t)k_ra8_cache_ctr_dmin_shift) & (uint32_t)k_ra8_cache_ctr_dmin_mask;
103 return (uint32_t)k_ra8_cache_word_bytes << dmin;
104}
105
129RA8_INTERNAL static uint32_t
130internal_ra8_cache_span_lines(uintptr_t addr, uint32_t size, uint32_t line, uintptr_t* out_start)
131{
132 const uintptr_t mask = (uintptr_t)line - 1U;
133 const uintptr_t start = addr & ~mask;
134 const uintptr_t last = (addr + (uintptr_t)size - 1U) & ~mask;
135 *out_start = start;
136 return (uint32_t)((last - start) / (uintptr_t)line) + 1U;
137}
138
162internal_ra8_cache_maintain_range(const void* addr, uint32_t size, ra8_cache_reg_addr_t reg)
163{
164 RA8_CHECK_NULL_PTR(addr, s_tag, "maintain: addr");
165 if (size == 0U) {
166 return k_ra8_ok;
167 }
168 const uint32_t line = ra8_cache_dcache_line_bytes();
169 uintptr_t start = 0U;
170 const uint32_t lines = internal_ra8_cache_span_lines((uintptr_t)addr, size, line, &start);
171 ra8_hw_dsb();
172 for (uint32_t i = 0U; i < lines; ++i) {
173 *internal_ra8_cache_reg(reg) = (uint32_t)(start + ((uintptr_t)i * (uintptr_t)line));
174 }
175 ra8_hw_dsb();
176 ra8_hw_isb();
177 return k_ra8_ok;
178}
179
180ra8_err_t ra8_cache_dcache_clean_by_addr(const void* addr, uint32_t size)
181{
183}
184
185ra8_err_t ra8_cache_dcache_invalidate_by_addr(const void* addr, uint32_t size)
186{
188}
189
191{
193}
194
220{
221 /* Arm v8-M ARM: select L1 data cache, read its geometry, then apply the
222 * set/way op to every set/way. CSSELR=0 selects level 0, data. */
224 ra8_hw_dsb();
225 const uint32_t ccsidr = *internal_ra8_cache_reg(k_ra8_cache_ccsidr);
226 if ((ccsidr == 0U) || (ccsidr == UINT32_MAX)) {
227 return; /* geometry unavailable -- nothing safe to touch */
228 }
229 uint32_t sets =
230 (ccsidr >> (uint32_t)k_ra8_cache_ccsidr_sets_sh) & (uint32_t)k_ra8_cache_ccsidr_sets_msk;
231 do {
232 uint32_t ways =
233 (ccsidr >> (uint32_t)k_ra8_cache_ccsidr_assoc_sh) & (uint32_t)k_ra8_cache_ccsidr_assoc_mk;
234 do {
235 *internal_ra8_cache_reg(op_reg) = (sets << (uint32_t)k_ra8_cache_dcisw_set_shift) |
236 (ways << (uint32_t)k_ra8_cache_dcisw_way_shift);
237 } while (ways-- != 0U);
238 } while (sets-- != 0U);
239 ra8_hw_dsb();
240 ra8_hw_isb();
241}
242
247
249{
250 /* Arm v8-M ARM: ICIALLU invalidates the whole L1 instruction cache to the
251 * point of unification. Barriers bracket it so prior accesses retire and the
252 * pipeline refetches before execution continues. */
253 ra8_hw_dsb();
254 ra8_hw_isb();
256 ra8_hw_dsb();
257 ra8_hw_isb();
258}
259
261{
263 /* Arm v8-M ARM: set SCB.CCR.IC (bit 17) to enable the L1 instruction cache.
264 * Read-modify-write preserves the other CCR controls (DIV_0_TRP, BP, ...). */
266 ccr |= (uint32_t)k_ra8_cache_ccr_ic_bit;
268 ra8_hw_dsb();
269 ra8_hw_isb();
270}
271
273{
274 /* Arm v8-M ARM: clear SCB.CCR.IC (bit 17), then invalidate so no stale line
275 * survives a later re-enable. The I-cache holds no dirty state. */
276 ra8_hw_dsb();
277 ra8_hw_isb();
279 ccr &= ~(uint32_t)k_ra8_cache_ccr_ic_bit;
282 ra8_hw_dsb();
283 ra8_hw_isb();
284}
285
287{
288 /* Invalidate every set/way first (existing primitive) so no random power-on
289 * line is treated as valid once the cache is on, THEN set CCR.DC. */
291 /* Arm v8-M ARM: set SCB.CCR.DC (bit 16) to enable the L1 data cache. */
293 ccr |= (uint32_t)k_ra8_cache_ccr_dc_bit;
295 ra8_hw_dsb();
296 ra8_hw_isb();
297}
298
300{
301 /* Arm v8-M ARM: clear SCB.CCR.DC (bit 16) to stop new allocations, then clean
302 * AND invalidate every set/way via DCCISW so any dirty line is written back to
303 * memory as the cache goes cold -- disable must not discard dirty data. */
305 ccr &= ~(uint32_t)k_ra8_cache_ccr_dc_bit;
308}
309
311{
312 /* Unified L1 bring-up: I-cache then D-cache, matching the order every
313 * system_init.c boot copy uses. Each half runs its own architectural
314 * invalidate before setting its CCR enable bit, so this is safe to call once
315 * from a cold cache at boot. */
318}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
static void internal_ra8_cache_setway_all(ra8_cache_reg_addr_t op_reg)
Apply a set/way maintenance op to every line of the L1 D-cache.
Definition ra8_cache.c:219
static volatile uint32_t * internal_ra8_cache_reg(ra8_cache_reg_addr_t addr)
Typed pointer to a 32-bit SCB cache register.
Definition ra8_cache.c:92
void ra8_cache_dcache_disable(void)
Disable the Cortex-M85 L1 data cache, cleaning dirty lines (CCR.DC).
Definition ra8_cache.c:299
void ra8_cache_icache_disable(void)
Disable the Cortex-M85 L1 instruction cache and invalidate it (CCR.IC).
Definition ra8_cache.c:272
ra8_cache_reg_addr_t
Arm v8-M SCB cache-maintenance register addresses (PPB 0xE000Exxx).
Definition ra8_cache.c:49
@ k_ra8_cache_iciallu
I-cache invalidate all to PoU.
Definition ra8_cache.c:54
@ k_ra8_cache_ctr
Cache Type Register (CTR).
Definition ra8_cache.c:51
@ k_ra8_cache_ccsidr
Cache Size ID Register (CCSIDR).
Definition ra8_cache.c:52
@ k_ra8_cache_dcisw
D-cache invalidate by set/way.
Definition ra8_cache.c:56
@ k_ra8_cache_dccisw
D-cache clean+invalidate by set/way.
Definition ra8_cache.c:59
@ k_ra8_cache_dccmvac
D-cache clean by MVA (PoC).
Definition ra8_cache.c:57
@ k_ra8_cache_dcimvac
D-cache invalidate by MVA (PoC).
Definition ra8_cache.c:55
@ k_ra8_cache_ccr
Configuration and Control (CCR).
Definition ra8_cache.c:50
@ k_ra8_cache_csselr
Cache Size Selection (CSSELR).
Definition ra8_cache.c:53
@ k_ra8_cache_dccimvac
D-cache clean+invalidate by MVA.
Definition ra8_cache.c:58
ra8_err_t ra8_cache_dcache_invalidate_by_addr(const void *addr, uint32_t size)
Invalidate (drop) the D-cache lines covering a byte range.
Definition ra8_cache.c:185
void ra8_cache_icache_invalidate_all(void)
Invalidate the entire Cortex-M85 L1 instruction cache (ICIALLU).
Definition ra8_cache.c:248
uint32_t ra8_cache_dcache_line_bytes(void)
Smallest Cortex-M85 D-cache line size, in bytes.
Definition ra8_cache.c:97
void ra8_cache_icache_enable(void)
Invalidate then enable the Cortex-M85 L1 instruction cache (CCR.IC).
Definition ra8_cache.c:260
void ra8_cache_enable(void)
Enable both Cortex-M85 L1 caches (I-cache then D-cache).
Definition ra8_cache.c:310
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
ra8_cache_field_t
Bit positions, masks, and sizes for the CTR / CCSIDR / DCISW fields.
Definition ra8_cache.c:67
@ k_ra8_cache_ccsidr_sets_msk
CCSIDR.NumSets field mask (15 bit).
Definition ra8_cache.c:72
@ k_ra8_cache_dcisw_set_shift
DCISW.SET position (32-byte line).
Definition ra8_cache.c:75
@ k_ra8_cache_word_bytes
Bytes per 32-bit cache word.
Definition ra8_cache.c:68
@ k_ra8_cache_ctr_dmin_mask
CTR.DminLine field mask (4 bits).
Definition ra8_cache.c:70
@ k_ra8_cache_ccsidr_assoc_sh
CCSIDR.Associativity bit position.
Definition ra8_cache.c:73
@ k_ra8_cache_ccsidr_sets_sh
CCSIDR.NumSets bit position.
Definition ra8_cache.c:71
@ k_ra8_cache_ccr_dc_bit
CCR.DC – L1 data-cache enable.
Definition ra8_cache.c:78
@ k_ra8_cache_dcisw_way_shift
DCISW.WAY position (assoc <= 4).
Definition ra8_cache.c:76
@ k_ra8_cache_ctr_dmin_shift
CTR.DminLine bit position.
Definition ra8_cache.c:69
@ k_ra8_cache_ccsidr_assoc_mk
CCSIDR.Associativity mask (10 bit).
Definition ra8_cache.c:74
@ k_ra8_cache_ccr_ic_bit
CCR.IC – L1 instruction-cache en.
Definition ra8_cache.c:77
static uint32_t internal_ra8_cache_span_lines(uintptr_t addr, uint32_t size, uint32_t line, uintptr_t *out_start)
Number of cache lines spanning size bytes from addr.
Definition ra8_cache.c:130
void ra8_cache_dcache_invalidate_all(void)
Invalidate the entire D-cache by set/way.
Definition ra8_cache.c:243
ra8_err_t ra8_cache_dcache_clean_invalidate_by_addr(const void *addr, uint32_t size)
Clean and invalidate the D-cache lines covering a byte range.
Definition ra8_cache.c:190
void ra8_cache_dcache_enable(void)
Invalidate then enable the Cortex-M85 L1 data cache (CCR.DC).
Definition ra8_cache.c:286
static ra8_err_t internal_ra8_cache_maintain_range(const void *addr, uint32_t size, ra8_cache_reg_addr_t reg)
Apply a by-MVA maintenance op to every line of a range.
Definition ra8_cache.c:162
Cortex-M85 L1 cache maintenance, enable/disable, and I-cache invalidate.
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
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
Shared CPU-intrinsic seam for the HAL drivers (host/target split).
static void ra8_hw_dsb(void)
Data Synchronisation Barrier (full system).
static void ra8_hw_isb(void)
Instruction Synchronisation Barrier (full system).