6#ifndef ZEPHYR_INCLUDE_ARCH_ARM64_CACHE_H_
7#define ZEPHYR_INCLUDE_ARCH_ARM64_CACHE_H_
21#define K_CACHE_WB BIT(0)
22#define K_CACHE_INVD BIT(1)
23#define K_CACHE_WB_INVD (K_CACHE_WB | K_CACHE_INVD)
25#define CTR_EL0_DMINLINE_SHIFT 16
26#define CTR_EL0_DMINLINE_MASK BIT_MASK(4)
27#define CTR_EL0_CWG_SHIFT 24
28#define CTR_EL0_CWG_MASK BIT_MASK(4)
31#define CLIDR_EL1_LOC_SHIFT 24
32#define CLIDR_EL1_LOC_MASK BIT_MASK(3)
33#define CLIDR_EL1_CTYPE_SHIFT(level) ((level) * 3)
34#define CLIDR_EL1_CTYPE_MASK BIT_MASK(3)
37#define CCSIDR_EL1_LN_SZ_SHIFT 0
38#define CCSIDR_EL1_LN_SZ_MASK BIT_MASK(3)
39#define CCSIDR_EL1_WAYS_SHIFT 3
40#define CCSIDR_EL1_WAYS_MASK BIT_MASK(10)
41#define CCSIDR_EL1_SETS_SHIFT 13
42#define CCSIDR_EL1_SETS_MASK BIT_MASK(15)
44#define dc_ops(op, val) \
46 __asm__ volatile ("dc " op ", %0" :: "r" (val) : "memory"); \
104 if (end_addr & (line_size - 1)) {
105 end_addr &= ~(line_size - 1);
106 dc_ops(
"civac", end_addr);
109 if (start_addr & (line_size - 1)) {
110 start_addr &= ~(line_size - 1);
111 if (start_addr == end_addr) {
114 dc_ops(
"civac", start_addr);
115 start_addr += line_size;
120 start_addr &= ~(line_size - 1);
122 while (start_addr < end_addr) {
124 dc_ops(
"ivac", start_addr);
126 dc_ops(
"cvac", start_addr);
128 dc_ops(
"civac", start_addr);
131 start_addr += line_size;
140#ifdef CONFIG_ARM64_DCACHE_ALL_OPS
150 uint32_t clidr_el1, csselr_el1, ccsidr_el1;
151 uint8_t loc, ctype, cache_level, line_size, way_pos;
152 uint32_t max_ways, max_sets, set, way;
162 clidr_el1 = read_clidr_el1();
169 for (cache_level = 0; cache_level < loc; cache_level++) {
177 csselr_el1 = cache_level << 1;
178 write_csselr_el1(csselr_el1);
181 ccsidr_el1 = read_ccsidr_el1();
186 way_pos = __builtin_clz(max_ways);
188 for (set = 0; set <= max_sets; set++) {
189 for (way = 0; way <= max_ways; way++) {
191 dc_val = way << way_pos;
193 dc_val |= csselr_el1;
195 dc_val |= set << line_size;
275#if defined(CONFIG_ICACHE)
277#define CTR_EL0_IMINLINE_MASK BIT_MASK(4)
279#define ic_va_ops(op, val) \
281 __asm__ volatile ("ic " op ", %0" :: "r" (val) : "memory"); \
284static size_t icache_line_size;
291 if (icache_line_size) {
292 return icache_line_size;
297 iminline = ctr_el0 & CTR_EL0_IMINLINE_MASK;
299 icache_line_size = 4 << iminline;
301 return icache_line_size;
315 __asm__
volatile (
"ic ialluis" :::
"memory");
342 start_addr &= ~(line_size - 1);
344 while (start_addr < end_addr) {
345 ic_va_ops(
"ivau", start_addr);
346 start_addr += line_size;
#define CTR_EL0_DMINLINE_SHIFT
Definition cache.h:25
static ALWAYS_INLINE void arch_cache_init(void)
Definition cache.h:372
static ALWAYS_INLINE void arch_dcache_enable(void)
Definition cache.h:265
static ALWAYS_INLINE size_t arch_dcache_line_size_get(void)
Definition cache.h:51
static ALWAYS_INLINE int arch_dcache_flush_range(void *addr, size_t size)
Definition cache.h:250
static ALWAYS_INLINE int arch_dcache_flush_all(void)
Definition cache.h:233
#define CLIDR_EL1_LOC_SHIFT
Definition cache.h:31
static ALWAYS_INLINE int arm64_dcache_range(void *addr, size_t size, int op)
Definition cache.h:75
#define CCSIDR_EL1_WAYS_MASK
Definition cache.h:40
#define K_CACHE_INVD
Definition cache.h:22
static ALWAYS_INLINE int arch_dcache_flush_and_invd_all(void)
Definition cache.h:243
#define CLIDR_EL1_CTYPE_MASK
Definition cache.h:34
#define K_CACHE_WB
Definition cache.h:21
#define CCSIDR_EL1_SETS_MASK
Definition cache.h:42
#define CLIDR_EL1_LOC_MASK
Definition cache.h:32
#define dc_ops(op, val)
Definition cache.h:44
static ALWAYS_INLINE int arch_dcache_invd_all(void)
Definition cache.h:238
#define CCSIDR_EL1_SETS_SHIFT
Definition cache.h:41
#define CCSIDR_EL1_LN_SZ_MASK
Definition cache.h:38
#define CTR_EL0_DMINLINE_MASK
Definition cache.h:26
#define CCSIDR_EL1_WAYS_SHIFT
Definition cache.h:39
#define K_CACHE_WB_INVD
Definition cache.h:23
static ALWAYS_INLINE int arch_dcache_invd_range(void *addr, size_t size)
Definition cache.h:255
#define CLIDR_EL1_CTYPE_SHIFT(level)
Definition cache.h:33
static size_t dcache_line_size
Definition cache.h:49
#define CCSIDR_EL1_LN_SZ_SHIFT
Definition cache.h:37
static ALWAYS_INLINE void arch_dcache_disable(void)
Definition cache.h:270
static ALWAYS_INLINE int arch_dcache_flush_and_invd_range(void *addr, size_t size)
Definition cache.h:260
#define read_sysreg(reg)
Definition lib_helpers.h:100
void arch_icache_disable(void)
Disable the i-cache.
int arch_icache_flush_and_invd_all(void)
Flush and Invalidate the i-cache.
int arch_icache_flush_all(void)
Flush the i-cache.
int arch_icache_invd_all(void)
Invalidate the i-cache.
size_t arch_icache_line_size_get(void)
Get the i-cache line size.
int arch_icache_flush_range(void *addr, size_t size)
Flush an address range in the i-cache.
int arch_icache_invd_range(void *addr, size_t size)
Invalidate an address range in the i-cache.
int arch_icache_flush_and_invd_range(void *addr, size_t size)
Flush and Invalidate an address range in the i-cache.
void arch_icache_enable(void)
Enable the i-cache.
static ALWAYS_INLINE void barrier_isync_fence_full(void)
Full/sequentially-consistent instruction synchronization barrier.
Definition barrier.h:100
static ALWAYS_INLINE void barrier_dsync_fence_full(void)
Full/sequentially-consistent data synchronization barrier.
Definition barrier.h:81
#define ENOTSUP
Unsupported value.
Definition errno.h:115
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT64_TYPE__ uint64_t
Definition stdint.h:91
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:105
Memory barrier operations.