mirror of
https://xff.cz/git/u-boot/
synced 2025-09-02 01:02:19 +02:00
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:
@@ -16,9 +16,15 @@ config TARGET_QEMU_VIRT
|
|||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
# board-specific options below
|
||||||
source "board/AndesTech/ax25-ae350/Kconfig"
|
source "board/AndesTech/ax25-ae350/Kconfig"
|
||||||
source "board/emulation/qemu-riscv/Kconfig"
|
source "board/emulation/qemu-riscv/Kconfig"
|
||||||
|
|
||||||
|
# platform-specific options below
|
||||||
|
source "arch/riscv/cpu/ax25/Kconfig"
|
||||||
|
|
||||||
|
# architecture-specific options below
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Base ISA"
|
prompt "Base ISA"
|
||||||
default ARCH_RV32I
|
default ARCH_RV32I
|
||||||
|
7
arch/riscv/cpu/ax25/Kconfig
Normal file
7
arch/riscv/cpu/ax25/Kconfig
Normal 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.
|
@@ -4,3 +4,4 @@
|
|||||||
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
|
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
|
||||||
|
|
||||||
obj-y := cpu.o
|
obj-y := cpu.o
|
||||||
|
obj-y += cache.o
|
||||||
|
95
arch/riscv/cpu/ax25/cache.c
Normal file
95
arch/riscv/cpu/ax25/cache.c
Normal 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;
|
||||||
|
}
|
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
/* CPU specific code */
|
/* CPU specific code */
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <asm/cache.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cleanup_before_linux() is called just before we call linux
|
* cleanup_before_linux() is called just before we call linux
|
||||||
@@ -18,6 +19,9 @@ int cleanup_before_linux(void)
|
|||||||
disable_interrupts();
|
disable_interrupts();
|
||||||
|
|
||||||
/* turn off I/D-cache */
|
/* turn off I/D-cache */
|
||||||
|
cache_flush();
|
||||||
|
icache_disable();
|
||||||
|
dcache_disable();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@ int cleanup_before_linux(void)
|
|||||||
{
|
{
|
||||||
disable_interrupts();
|
disable_interrupts();
|
||||||
|
|
||||||
/* turn off I/D-cache */
|
cache_flush();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -46,6 +46,10 @@ _start:
|
|||||||
/* mask all interrupts */
|
/* mask all interrupts */
|
||||||
csrw mie, zero
|
csrw mie, zero
|
||||||
|
|
||||||
|
/* Enable cache */
|
||||||
|
jal icache_enable
|
||||||
|
jal dcache_enable
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set stackpointer in internal/ex RAM to call board_init_f
|
* Set stackpointer in internal/ex RAM to call board_init_f
|
||||||
*/
|
*/
|
||||||
@@ -181,6 +185,8 @@ clbss_l:
|
|||||||
* initialization, now running from RAM.
|
* initialization, now running from RAM.
|
||||||
*/
|
*/
|
||||||
call_board_init_r:
|
call_board_init_r:
|
||||||
|
jal invalidate_icache_all
|
||||||
|
jal flush_dcache_all
|
||||||
la t0, board_init_r
|
la t0, board_init_r
|
||||||
mv t4, t0 /* offset of board_init_r() */
|
mv t4, t0 /* offset of board_init_r() */
|
||||||
add t4, t4, t6 /* real address of board_init_r() */
|
add t4, t4, t6 /* real address of board_init_r() */
|
||||||
|
@@ -7,6 +7,9 @@
|
|||||||
#ifndef _ASM_RISCV_CACHE_H
|
#ifndef _ASM_RISCV_CACHE_H
|
||||||
#define _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.
|
* 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
|
* We use that value for aligning DMA buffers unless the board config has
|
||||||
|
@@ -6,8 +6,18 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#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)
|
void flush_dcache_range(unsigned long start, unsigned long end)
|
||||||
{
|
{
|
||||||
|
flush_dcache_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidate_icache_range(unsigned long start, unsigned long end)
|
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();
|
invalidate_icache_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidate_icache_all(void)
|
|
||||||
{
|
|
||||||
asm volatile ("fence.i" ::: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalidate_dcache_range(unsigned long start, unsigned long end)
|
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)
|
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user