riscv: cache: Implement i/dcache [status, enable, disable]

AndeStar RISC-V(V5) provide mcache_ctl register which
can configure I/D cache as enabled or disabled.

This CSR will be encapsulated by CONFIG_RISCV_NDS.
If you want to configure cache on AndeStar V5
AE350 platform. YOu can enable [*] AndeStar V5 ISA support
by make menuconfig.

This approach also provide the expansion when the
vender specific features are going to join in.

Signed-off-by: Rick Chen <rick@andestech.com>
Cc: Greentime Hu <greentime@andestech.com>
This commit is contained in:
Rick Chen 2018-11-07 09:34:06 +08:00 committed by Andes
parent bae2d72507
commit 52923c6db7
9 changed files with 148 additions and 12 deletions

View file

@ -16,9 +16,15 @@ config TARGET_QEMU_VIRT
endchoice
# board-specific options below
source "board/AndesTech/ax25-ae350/Kconfig"
source "board/emulation/qemu-riscv/Kconfig"
# platform-specific options below
source "arch/riscv/cpu/ax25/Kconfig"
# architecture-specific options below
choice
prompt "Base ISA"
default ARCH_RV32I

View file

@ -0,0 +1,7 @@
config RISCV_NDS
bool "AndeStar V5 ISA support"
default n
help
Say Y here if you plan to run U-Boot on AndeStar v5
platforms and use some specific features which are
provided by Andes Technology AndeStar V5 Families.

View file

@ -4,3 +4,4 @@
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
obj-y := cpu.o
obj-y += cache.o

View file

@ -0,0 +1,95 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2017 Andes Technology Corporation
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*/
#include <common.h>
void icache_enable(void)
{
#ifndef CONFIG_SYS_ICACHE_OFF
#ifdef CONFIG_RISCV_NDS
asm volatile (
"csrr t1, mcache_ctl\n\t"
"ori t0, t1, 0x1\n\t"
"csrw mcache_ctl, t0\n\t"
);
#endif
#endif
}
void icache_disable(void)
{
#ifndef CONFIG_SYS_ICACHE_OFF
#ifdef CONFIG_RISCV_NDS
asm volatile (
"fence.i\n\t"
"csrr t1, mcache_ctl\n\t"
"andi t0, t1, ~0x1\n\t"
"csrw mcache_ctl, t0\n\t"
);
#endif
#endif
}
void dcache_enable(void)
{
#ifndef CONFIG_SYS_DCACHE_OFF
#ifdef CONFIG_RISCV_NDS
asm volatile (
"csrr t1, mcache_ctl\n\t"
"ori t0, t1, 0x2\n\t"
"csrw mcache_ctl, t0\n\t"
);
#endif
#endif
}
void dcache_disable(void)
{
#ifndef CONFIG_SYS_DCACHE_OFF
#ifdef CONFIG_RISCV_NDS
asm volatile (
"fence\n\t"
"csrr t1, mcache_ctl\n\t"
"andi t0, t1, ~0x2\n\t"
"csrw mcache_ctl, t0\n\t"
);
#endif
#endif
}
int icache_status(void)
{
int ret = 0;
#ifdef CONFIG_RISCV_NDS
asm volatile (
"csrr t1, mcache_ctl\n\t"
"andi %0, t1, 0x01\n\t"
: "=r" (ret)
:
: "memory"
);
#endif
return ret;
}
int dcache_status(void)
{
int ret = 0;
#ifdef CONFIG_RISCV_NDS
asm volatile (
"csrr t1, mcache_ctl\n\t"
"andi %0, t1, 0x02\n\t"
: "=r" (ret)
:
: "memory"
);
#endif
return ret;
}

View file

@ -6,6 +6,7 @@
/* CPU specific code */
#include <common.h>
#include <asm/cache.h>
/*
* cleanup_before_linux() is called just before we call linux
@ -18,6 +19,9 @@ int cleanup_before_linux(void)
disable_interrupts();
/* turn off I/D-cache */
cache_flush();
icache_disable();
dcache_disable();
return 0;
}

View file

@ -15,7 +15,7 @@ int cleanup_before_linux(void)
{
disable_interrupts();
/* turn off I/D-cache */
cache_flush();
return 0;
}

View file

@ -46,6 +46,10 @@ _start:
/* mask all interrupts */
csrw mie, zero
/* Enable cache */
jal icache_enable
jal dcache_enable
/*
* Set stackpointer in internal/ex RAM to call board_init_f
*/
@ -181,6 +185,8 @@ clbss_l:
* initialization, now running from RAM.
*/
call_board_init_r:
jal invalidate_icache_all
jal flush_dcache_all
la t0, board_init_r
mv t4, t0 /* offset of board_init_r() */
add t4, t4, t6 /* real address of board_init_r() */

View file

@ -7,6 +7,9 @@
#ifndef _ASM_RISCV_CACHE_H
#define _ASM_RISCV_CACHE_H
/* cache */
void cache_flush(void);
/*
* The current upper bound for RISCV L1 data cache line sizes is 32 bytes.
* We use that value for aligning DMA buffers unless the board config has

View file

@ -6,8 +6,18 @@
#include <common.h>
void invalidate_icache_all(void)
{
asm volatile ("fence.i" ::: "memory");
}
void flush_dcache_all(void)
{
asm volatile ("fence" :::"memory");
}
void flush_dcache_range(unsigned long start, unsigned long end)
{
flush_dcache_all();
}
void invalidate_icache_range(unsigned long start, unsigned long end)
@ -19,41 +29,45 @@ void invalidate_icache_range(unsigned long start, unsigned long end)
invalidate_icache_all();
}
void invalidate_icache_all(void)
{
asm volatile ("fence.i" ::: "memory");
}
void invalidate_dcache_range(unsigned long start, unsigned long end)
{
flush_dcache_all();
}
void cache_flush(void)
{
invalidate_icache_all();
flush_dcache_all();
}
void flush_cache(unsigned long addr, unsigned long size)
{
invalidate_icache_all();
flush_dcache_all();
}
void icache_enable(void)
__weak void icache_enable(void)
{
}
void icache_disable(void)
__weak void icache_disable(void)
{
}
int icache_status(void)
__weak int icache_status(void)
{
return 0;
}
void dcache_enable(void)
__weak void dcache_enable(void)
{
}
void dcache_disable(void)
__weak void dcache_disable(void)
{
}
int dcache_status(void)
__weak int dcache_status(void)
{
return 0;
}