arm64: cache: Enable full inlining of the cache ops
Move all the cache functions to a standalone header to allow for the inlining of these functions. Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
parent
d3ed4a784b
commit
c2ec3d49cd
|
@ -36,7 +36,6 @@ zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c)
|
zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_HAS_ARM_SMCCC smccc-call.S)
|
zephyr_library_sources_ifdef(CONFIG_HAS_ARM_SMCCC smccc-call.S)
|
||||||
zephyr_library_sources_ifdef(CONFIG_AARCH64_IMAGE_HEADER header.S)
|
zephyr_library_sources_ifdef(CONFIG_AARCH64_IMAGE_HEADER header.S)
|
||||||
zephyr_library_sources_ifdef(CONFIG_ARCH_CACHE cache.c)
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c)
|
zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c)
|
||||||
if ((CONFIG_MP_MAX_NUM_CPUS GREATER 1) OR (CONFIG_SMP))
|
if ((CONFIG_MP_MAX_NUM_CPUS GREATER 1) OR (CONFIG_SMP))
|
||||||
zephyr_library_sources(smp.c)
|
zephyr_library_sources(smp.c)
|
||||||
|
|
|
@ -1,209 +0,0 @@
|
||||||
/* cache.c - d-cache support for AARCH64 CPUs */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2020-2021 NXP
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief d-cache manipulation
|
|
||||||
*
|
|
||||||
* This module contains functions for manipulation of the d-cache.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <zephyr/arch/arm64/cache.h>
|
|
||||||
#include <zephyr/cache.h>
|
|
||||||
|
|
||||||
#define CTR_EL0_DMINLINE_SHIFT 16
|
|
||||||
#define CTR_EL0_DMINLINE_MASK BIT_MASK(4)
|
|
||||||
#define CTR_EL0_CWG_SHIFT 24
|
|
||||||
#define CTR_EL0_CWG_MASK BIT_MASK(4)
|
|
||||||
|
|
||||||
/* clidr_el1 */
|
|
||||||
#define CLIDR_EL1_LOC_SHIFT 24
|
|
||||||
#define CLIDR_EL1_LOC_MASK BIT_MASK(3)
|
|
||||||
#define CLIDR_EL1_CTYPE_SHIFT(level) ((level) * 3)
|
|
||||||
#define CLIDR_EL1_CTYPE_MASK BIT_MASK(3)
|
|
||||||
|
|
||||||
/* ccsidr_el1 */
|
|
||||||
#define CCSIDR_EL1_LN_SZ_SHIFT 0
|
|
||||||
#define CCSIDR_EL1_LN_SZ_MASK BIT_MASK(3)
|
|
||||||
#define CCSIDR_EL1_WAYS_SHIFT 3
|
|
||||||
#define CCSIDR_EL1_WAYS_MASK BIT_MASK(10)
|
|
||||||
#define CCSIDR_EL1_SETS_SHIFT 13
|
|
||||||
#define CCSIDR_EL1_SETS_MASK BIT_MASK(15)
|
|
||||||
|
|
||||||
#define dc_ops(op, val) \
|
|
||||||
({ \
|
|
||||||
__asm__ volatile ("dc " op ", %0" :: "r" (val) : "memory"); \
|
|
||||||
})
|
|
||||||
|
|
||||||
static size_t dcache_line_size;
|
|
||||||
|
|
||||||
size_t arch_dcache_line_size_get(void)
|
|
||||||
{
|
|
||||||
uint64_t ctr_el0;
|
|
||||||
uint32_t dminline;
|
|
||||||
|
|
||||||
if (dcache_line_size) {
|
|
||||||
return dcache_line_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr_el0 = read_sysreg(CTR_EL0);
|
|
||||||
|
|
||||||
dminline = (ctr_el0 >> CTR_EL0_DMINLINE_SHIFT) & CTR_EL0_DMINLINE_MASK;
|
|
||||||
|
|
||||||
dcache_line_size = 4 << dminline;
|
|
||||||
|
|
||||||
return dcache_line_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* operation for data cache by virtual address to PoC
|
|
||||||
* ops: K_CACHE_INVD: invalidate
|
|
||||||
* K_CACHE_WB: clean
|
|
||||||
* K_CACHE_WB_INVD: clean and invalidate
|
|
||||||
*/
|
|
||||||
int arm64_dcache_range(void *addr, size_t size, int op)
|
|
||||||
{
|
|
||||||
size_t line_size;
|
|
||||||
uintptr_t start_addr = (uintptr_t)addr;
|
|
||||||
uintptr_t end_addr = start_addr + size;
|
|
||||||
|
|
||||||
if (op != K_CACHE_INVD && op != K_CACHE_WB && op != K_CACHE_WB_INVD) {
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
line_size = arch_dcache_line_size_get();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For the data cache invalidate operation, clean and invalidate
|
|
||||||
* the partial cache lines at both ends of the given range to
|
|
||||||
* prevent data corruption.
|
|
||||||
*
|
|
||||||
* For example (assume cache line size is 64 bytes):
|
|
||||||
* There are 2 consecutive 32-byte buffers, which can be cached in
|
|
||||||
* one line like below.
|
|
||||||
* +------------------+------------------+
|
|
||||||
* Cache line: | buffer 0 (dirty) | buffer 1 |
|
|
||||||
* +------------------+------------------+
|
|
||||||
* For the start address not aligned case, when invalidate the
|
|
||||||
* buffer 1, the full cache line will be invalidated, if the buffer
|
|
||||||
* 0 is dirty, its data will be lost.
|
|
||||||
* The same logic applies to the not aligned end address.
|
|
||||||
*/
|
|
||||||
if (op == K_CACHE_INVD) {
|
|
||||||
if (end_addr & (line_size - 1)) {
|
|
||||||
end_addr &= ~(line_size - 1);
|
|
||||||
dc_ops("civac", end_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start_addr & (line_size - 1)) {
|
|
||||||
start_addr &= ~(line_size - 1);
|
|
||||||
if (start_addr == end_addr) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
dc_ops("civac", start_addr);
|
|
||||||
start_addr += line_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Align address to line size */
|
|
||||||
start_addr &= ~(line_size - 1);
|
|
||||||
|
|
||||||
while (start_addr < end_addr) {
|
|
||||||
if (op == K_CACHE_INVD) {
|
|
||||||
dc_ops("ivac", start_addr);
|
|
||||||
} else if (op == K_CACHE_WB) {
|
|
||||||
dc_ops("cvac", start_addr);
|
|
||||||
} else if (op == K_CACHE_WB_INVD) {
|
|
||||||
dc_ops("civac", start_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
start_addr += line_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
dsb();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* operation for all data cache
|
|
||||||
* ops: K_CACHE_INVD: invalidate
|
|
||||||
* K_CACHE_WB: clean
|
|
||||||
* K_CACHE_WB_INVD: clean and invalidate
|
|
||||||
*/
|
|
||||||
int arm64_dcache_all(int op)
|
|
||||||
{
|
|
||||||
uint32_t clidr_el1, csselr_el1, ccsidr_el1;
|
|
||||||
uint8_t loc, ctype, cache_level, line_size, way_pos;
|
|
||||||
uint32_t max_ways, max_sets, dc_val, set, way;
|
|
||||||
|
|
||||||
if (op != K_CACHE_INVD && op != K_CACHE_WB && op != K_CACHE_WB_INVD) {
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Data barrier before start */
|
|
||||||
dsb();
|
|
||||||
|
|
||||||
clidr_el1 = read_clidr_el1();
|
|
||||||
|
|
||||||
loc = (clidr_el1 >> CLIDR_EL1_LOC_SHIFT) & CLIDR_EL1_LOC_MASK;
|
|
||||||
if (!loc) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cache_level = 0; cache_level < loc; cache_level++) {
|
|
||||||
ctype = (clidr_el1 >> CLIDR_EL1_CTYPE_SHIFT(cache_level))
|
|
||||||
& CLIDR_EL1_CTYPE_MASK;
|
|
||||||
/* No data cache, continue */
|
|
||||||
if (ctype < 2) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* select cache level */
|
|
||||||
csselr_el1 = cache_level << 1;
|
|
||||||
write_csselr_el1(csselr_el1);
|
|
||||||
isb();
|
|
||||||
|
|
||||||
ccsidr_el1 = read_ccsidr_el1();
|
|
||||||
line_size = (ccsidr_el1 >> CCSIDR_EL1_LN_SZ_SHIFT
|
|
||||||
& CCSIDR_EL1_LN_SZ_MASK) + 4;
|
|
||||||
max_ways = (ccsidr_el1 >> CCSIDR_EL1_WAYS_SHIFT)
|
|
||||||
& CCSIDR_EL1_WAYS_MASK;
|
|
||||||
max_sets = (ccsidr_el1 >> CCSIDR_EL1_SETS_SHIFT)
|
|
||||||
& CCSIDR_EL1_SETS_MASK;
|
|
||||||
/* 32-log2(ways), bit position of way in DC operand */
|
|
||||||
way_pos = __builtin_clz(max_ways);
|
|
||||||
|
|
||||||
for (set = 0; set <= max_sets; set++) {
|
|
||||||
for (way = 0; way <= max_ways; way++) {
|
|
||||||
/* way number, aligned to pos in DC operand */
|
|
||||||
dc_val = way << way_pos;
|
|
||||||
/* cache level, aligned to pos in DC operand */
|
|
||||||
dc_val |= csselr_el1;
|
|
||||||
/* set number, aligned to pos in DC operand */
|
|
||||||
dc_val |= set << line_size;
|
|
||||||
|
|
||||||
if (op == K_CACHE_INVD) {
|
|
||||||
dc_ops("isw", dc_val);
|
|
||||||
} else if (op == K_CACHE_WB_INVD) {
|
|
||||||
dc_ops("cisw", dc_val);
|
|
||||||
} else if (op == K_CACHE_WB) {
|
|
||||||
dc_ops("csw", dc_val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore csselr_el1 to level 0 */
|
|
||||||
write_csselr_el1(0);
|
|
||||||
dsb();
|
|
||||||
isb();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -23,47 +23,234 @@ extern "C" {
|
||||||
|
|
||||||
#if defined(CONFIG_DCACHE)
|
#if defined(CONFIG_DCACHE)
|
||||||
|
|
||||||
extern int arm64_dcache_range(void *addr, size_t size, int op);
|
#define CTR_EL0_DMINLINE_SHIFT 16
|
||||||
extern int arm64_dcache_all(int op);
|
#define CTR_EL0_DMINLINE_MASK BIT_MASK(4)
|
||||||
|
#define CTR_EL0_CWG_SHIFT 24
|
||||||
|
#define CTR_EL0_CWG_MASK BIT_MASK(4)
|
||||||
|
|
||||||
extern size_t arch_dcache_line_size_get(void);
|
/* clidr_el1 */
|
||||||
|
#define CLIDR_EL1_LOC_SHIFT 24
|
||||||
|
#define CLIDR_EL1_LOC_MASK BIT_MASK(3)
|
||||||
|
#define CLIDR_EL1_CTYPE_SHIFT(level) ((level) * 3)
|
||||||
|
#define CLIDR_EL1_CTYPE_MASK BIT_MASK(3)
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_dcache_flush_all(void)
|
/* ccsidr_el1 */
|
||||||
|
#define CCSIDR_EL1_LN_SZ_SHIFT 0
|
||||||
|
#define CCSIDR_EL1_LN_SZ_MASK BIT_MASK(3)
|
||||||
|
#define CCSIDR_EL1_WAYS_SHIFT 3
|
||||||
|
#define CCSIDR_EL1_WAYS_MASK BIT_MASK(10)
|
||||||
|
#define CCSIDR_EL1_SETS_SHIFT 13
|
||||||
|
#define CCSIDR_EL1_SETS_MASK BIT_MASK(15)
|
||||||
|
|
||||||
|
#define dc_ops(op, val) \
|
||||||
|
({ \
|
||||||
|
__asm__ volatile ("dc " op ", %0" :: "r" (val) : "memory"); \
|
||||||
|
})
|
||||||
|
|
||||||
|
static size_t dcache_line_size;
|
||||||
|
|
||||||
|
static ALWAYS_INLINE size_t arch_dcache_line_size_get(void)
|
||||||
|
{
|
||||||
|
uint64_t ctr_el0;
|
||||||
|
uint32_t dminline;
|
||||||
|
|
||||||
|
if (dcache_line_size) {
|
||||||
|
return dcache_line_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctr_el0 = read_sysreg(CTR_EL0);
|
||||||
|
|
||||||
|
dminline = (ctr_el0 >> CTR_EL0_DMINLINE_SHIFT) & CTR_EL0_DMINLINE_MASK;
|
||||||
|
|
||||||
|
dcache_line_size = 4 << dminline;
|
||||||
|
|
||||||
|
return dcache_line_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* operation for data cache by virtual address to PoC
|
||||||
|
* ops: K_CACHE_INVD: invalidate
|
||||||
|
* K_CACHE_WB: clean
|
||||||
|
* K_CACHE_WB_INVD: clean and invalidate
|
||||||
|
*/
|
||||||
|
static ALWAYS_INLINE int arm64_dcache_range(void *addr, size_t size, int op)
|
||||||
|
{
|
||||||
|
size_t line_size;
|
||||||
|
uintptr_t start_addr = (uintptr_t)addr;
|
||||||
|
uintptr_t end_addr = start_addr + size;
|
||||||
|
|
||||||
|
if (op != K_CACHE_INVD && op != K_CACHE_WB && op != K_CACHE_WB_INVD) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_size = arch_dcache_line_size_get();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the data cache invalidate operation, clean and invalidate
|
||||||
|
* the partial cache lines at both ends of the given range to
|
||||||
|
* prevent data corruption.
|
||||||
|
*
|
||||||
|
* For example (assume cache line size is 64 bytes):
|
||||||
|
* There are 2 consecutive 32-byte buffers, which can be cached in
|
||||||
|
* one line like below.
|
||||||
|
* +------------------+------------------+
|
||||||
|
* Cache line: | buffer 0 (dirty) | buffer 1 |
|
||||||
|
* +------------------+------------------+
|
||||||
|
* For the start address not aligned case, when invalidate the
|
||||||
|
* buffer 1, the full cache line will be invalidated, if the buffer
|
||||||
|
* 0 is dirty, its data will be lost.
|
||||||
|
* The same logic applies to the not aligned end address.
|
||||||
|
*/
|
||||||
|
if (op == K_CACHE_INVD) {
|
||||||
|
if (end_addr & (line_size - 1)) {
|
||||||
|
end_addr &= ~(line_size - 1);
|
||||||
|
dc_ops("civac", end_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start_addr & (line_size - 1)) {
|
||||||
|
start_addr &= ~(line_size - 1);
|
||||||
|
if (start_addr == end_addr) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
dc_ops("civac", start_addr);
|
||||||
|
start_addr += line_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Align address to line size */
|
||||||
|
start_addr &= ~(line_size - 1);
|
||||||
|
|
||||||
|
while (start_addr < end_addr) {
|
||||||
|
if (op == K_CACHE_INVD) {
|
||||||
|
dc_ops("ivac", start_addr);
|
||||||
|
} else if (op == K_CACHE_WB) {
|
||||||
|
dc_ops("cvac", start_addr);
|
||||||
|
} else if (op == K_CACHE_WB_INVD) {
|
||||||
|
dc_ops("civac", start_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
start_addr += line_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
dsb();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* operation for all data cache
|
||||||
|
* ops: K_CACHE_INVD: invalidate
|
||||||
|
* K_CACHE_WB: clean
|
||||||
|
* K_CACHE_WB_INVD: clean and invalidate
|
||||||
|
*/
|
||||||
|
static ALWAYS_INLINE int arm64_dcache_all(int op)
|
||||||
|
{
|
||||||
|
uint32_t clidr_el1, csselr_el1, ccsidr_el1;
|
||||||
|
uint8_t loc, ctype, cache_level, line_size, way_pos;
|
||||||
|
uint32_t max_ways, max_sets, dc_val, set, way;
|
||||||
|
|
||||||
|
if (op != K_CACHE_INVD && op != K_CACHE_WB && op != K_CACHE_WB_INVD) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Data barrier before start */
|
||||||
|
dsb();
|
||||||
|
|
||||||
|
clidr_el1 = read_clidr_el1();
|
||||||
|
|
||||||
|
loc = (clidr_el1 >> CLIDR_EL1_LOC_SHIFT) & CLIDR_EL1_LOC_MASK;
|
||||||
|
if (!loc) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cache_level = 0; cache_level < loc; cache_level++) {
|
||||||
|
ctype = (clidr_el1 >> CLIDR_EL1_CTYPE_SHIFT(cache_level))
|
||||||
|
& CLIDR_EL1_CTYPE_MASK;
|
||||||
|
/* No data cache, continue */
|
||||||
|
if (ctype < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* select cache level */
|
||||||
|
csselr_el1 = cache_level << 1;
|
||||||
|
write_csselr_el1(csselr_el1);
|
||||||
|
isb();
|
||||||
|
|
||||||
|
ccsidr_el1 = read_ccsidr_el1();
|
||||||
|
line_size = (ccsidr_el1 >> CCSIDR_EL1_LN_SZ_SHIFT
|
||||||
|
& CCSIDR_EL1_LN_SZ_MASK) + 4;
|
||||||
|
max_ways = (ccsidr_el1 >> CCSIDR_EL1_WAYS_SHIFT)
|
||||||
|
& CCSIDR_EL1_WAYS_MASK;
|
||||||
|
max_sets = (ccsidr_el1 >> CCSIDR_EL1_SETS_SHIFT)
|
||||||
|
& CCSIDR_EL1_SETS_MASK;
|
||||||
|
/* 32-log2(ways), bit position of way in DC operand */
|
||||||
|
way_pos = __builtin_clz(max_ways);
|
||||||
|
|
||||||
|
for (set = 0; set <= max_sets; set++) {
|
||||||
|
for (way = 0; way <= max_ways; way++) {
|
||||||
|
/* way number, aligned to pos in DC operand */
|
||||||
|
dc_val = way << way_pos;
|
||||||
|
/* cache level, aligned to pos in DC operand */
|
||||||
|
dc_val |= csselr_el1;
|
||||||
|
/* set number, aligned to pos in DC operand */
|
||||||
|
dc_val |= set << line_size;
|
||||||
|
|
||||||
|
if (op == K_CACHE_INVD) {
|
||||||
|
dc_ops("isw", dc_val);
|
||||||
|
} else if (op == K_CACHE_WB_INVD) {
|
||||||
|
dc_ops("cisw", dc_val);
|
||||||
|
} else if (op == K_CACHE_WB) {
|
||||||
|
dc_ops("csw", dc_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore csselr_el1 to level 0 */
|
||||||
|
write_csselr_el1(0);
|
||||||
|
dsb();
|
||||||
|
isb();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE int arch_dcache_flush_all(void)
|
||||||
{
|
{
|
||||||
return arm64_dcache_all(K_CACHE_WB);
|
return arm64_dcache_all(K_CACHE_WB);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_dcache_invd_all(void)
|
static ALWAYS_INLINE int arch_dcache_invd_all(void)
|
||||||
{
|
{
|
||||||
return arm64_dcache_all(K_CACHE_INVD);
|
return arm64_dcache_all(K_CACHE_INVD);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_dcache_flush_and_invd_all(void)
|
static ALWAYS_INLINE int arch_dcache_flush_and_invd_all(void)
|
||||||
{
|
{
|
||||||
return arm64_dcache_all(K_CACHE_WB_INVD);
|
return arm64_dcache_all(K_CACHE_WB_INVD);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_dcache_flush_range(void *addr, size_t size)
|
static ALWAYS_INLINE int arch_dcache_flush_range(void *addr, size_t size)
|
||||||
{
|
{
|
||||||
return arm64_dcache_range(addr, size, K_CACHE_WB);
|
return arm64_dcache_range(addr, size, K_CACHE_WB);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_dcache_invd_range(void *addr, size_t size)
|
static ALWAYS_INLINE int arch_dcache_invd_range(void *addr, size_t size)
|
||||||
{
|
{
|
||||||
return arm64_dcache_range(addr, size, K_CACHE_INVD);
|
return arm64_dcache_range(addr, size, K_CACHE_INVD);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_dcache_flush_and_invd_range(void *addr, size_t size)
|
static ALWAYS_INLINE int arch_dcache_flush_and_invd_range(void *addr, size_t size)
|
||||||
{
|
{
|
||||||
return arm64_dcache_range(addr, size, K_CACHE_WB_INVD);
|
return arm64_dcache_range(addr, size, K_CACHE_WB_INVD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALWAYS_INLINE arch_dcache_enable(void)
|
static ALWAYS_INLINE void arch_dcache_enable(void)
|
||||||
{
|
{
|
||||||
/* nothing */
|
/* nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALWAYS_INLINE arch_dcache_disable(void)
|
static ALWAYS_INLINE void arch_dcache_disable(void)
|
||||||
{
|
{
|
||||||
/* nothing */
|
/* nothing */
|
||||||
}
|
}
|
||||||
|
@ -72,47 +259,47 @@ void ALWAYS_INLINE arch_dcache_disable(void)
|
||||||
|
|
||||||
#if defined(CONFIG_ICACHE)
|
#if defined(CONFIG_ICACHE)
|
||||||
|
|
||||||
size_t arch_icache_line_size_get(void)
|
static ALWAYS_INLINE size_t arch_icache_line_size_get(void)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_icache_flush_all(void)
|
static ALWAYS_INLINE int arch_icache_flush_all(void)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_icache_invd_all(void)
|
static ALWAYS_INLINE int arch_icache_invd_all(void)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_icache_flush_and_invd_all(void)
|
static ALWAYS_INLINE int arch_icache_flush_and_invd_all(void)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_icache_flush_range(void *addr, size_t size)
|
static ALWAYS_INLINE int arch_icache_flush_range(void *addr, size_t size)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_icache_invd_range(void *addr, size_t size)
|
static ALWAYS_INLINE int arch_icache_invd_range(void *addr, size_t size)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALWAYS_INLINE arch_icache_flush_and_invd_range(void *addr, size_t size)
|
static ALWAYS_INLINE int arch_icache_flush_and_invd_range(void *addr, size_t size)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALWAYS_INLINE arch_icache_enable(void)
|
static ALWAYS_INLINE void arch_icache_enable(void)
|
||||||
{
|
{
|
||||||
/* nothing */
|
/* nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALWAYS_INLINE arch_icache_disable(void)
|
static ALWAYS_INLINE void arch_icache_disable(void)
|
||||||
{
|
{
|
||||||
/* nothing */
|
/* nothing */
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARM64)
|
||||||
|
#include <zephyr/arch/arm64/cache.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_DCACHE)
|
#if defined(CONFIG_DCACHE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue