mpfs: cache: provide L1/L2 cache enablers

E51 may configure the L1 and L2 caches. Once configured,
no reconfiguration is possible after hardware reset is
issued.

L2 is 16-way set associative with write-back policy. The
size 2 MB, from which 1 MB is utilized with the values
provided here. That's a total of 8 ways. The rest of the
L2 is left out for the bootloader usage.

mpfs_enable_cache() first checks the bootloader usage
doesn't overlap with the cache itself, thus providing a
set of functional values.

Signed-off-by: Eero Nurkkala <eero.nurkkala@offcode.fi>
This commit is contained in:
Eero Nurkkala 2021-11-04 13:11:13 +02:00 committed by Alan Carvalho de Assis
parent 60de445ab3
commit 8e43f39141
6 changed files with 343 additions and 0 deletions

View File

@ -85,3 +85,7 @@ endif
ifeq (${CONFIG_MPFS_DDR_INIT},y)
CHIP_CSRCS += mpfs_ddr.c
endif
ifeq (${CONFIG_MPFS_BOOTLOADER},y)
CHIP_CSRCS += mpfs_cache.c
endif

View File

@ -0,0 +1,95 @@
/****************************************************************************
* arch/risc-v/src/mpfs/hardware/mpfs_cache.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_CACHE_H
#define __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_CACHE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "hardware/mpfs_memorymap.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Register Base Address ****************************************************/
#define MPFS_CACHE_CTRL_BASE 0x02010000
/* Register offsets *********************************************************/
#define MPFS_CACHE_CONFIG_OFFSET 0x000
#define MPFS_CACHE_WAY_ENABLE_OFFSET 0x008
#define MPFS_CACHE_ECC_INJECT_ERROR_OFFSET 0x040
#define MPFS_CACHE_ECC_DIR_FIX_ADDR_OFFSET 0x100
#define MPFS_CACHE_ECC_DIR_FIX_COUNT_OFFSET 0x108
#define MPFS_CACHE_ECC_DATA_FIX_ADDR_OFFSET 0x140
#define MPFS_CACHE_ECC_DATA_FIX_COUNT_OFFSET 0x148
#define MPFS_CACHE_ECC_DATA_FAIL_ADDR_OFFSET 0x160
#define MPFS_CACHE_ECC_DATA_FAIL_COUNT_OFFSET 0x168
#define MPFS_CACHE_FLUSH64_OFFSET 0x200
#define MPFS_CACHE_FLUSH32_OFFSET 0x240
#define MPFS_CACHE_WAY_MASK_DMA_OFFSET 0x800
#define MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_0_OFFSET 0x808
#define MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_1_OFFSET 0x810
#define MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_2_OFFSET 0x818
#define MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_3_OFFSET 0x820
#define MPFS_CACHE_WAY_MASK_E51_DCACHE_OFFSET 0x828
#define MPFS_CACHE_WAY_MASK_E51_ICACHE_OFFSET 0x830
#define MPFS_CACHE_WAY_MASK_U54_1_DCACHE_OFFSET 0x838
#define MPFS_CACHE_WAY_MASK_U54_1_ICACHE_OFFSET 0x840
#define MPFS_CACHE_WAY_MASK_U54_2_DCACHE_OFFSET 0x848
#define MPFS_CACHE_WAY_MASK_U54_2_ICACHE_OFFSET 0x850
#define MPFS_CACHE_WAY_MASK_U54_3_DCACHE_OFFSET 0x858
#define MPFS_CACHE_WAY_MASK_U54_3_ICACHE_OFFSET 0x860
#define MPFS_CACHE_WAY_MASK_U54_4_DCACHE_OFFSET 0x868
#define MPFS_CACHE_WAY_MASK_U54_4_ICACHE_OFFSET 0x870
/* Registers ****************************************************************/
#define MPFS_CACHE_CONFIG (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_CONFIG_OFFSET)
#define MPFS_CACHE_WAY_ENABLE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_ENABLE_OFFSET)
#define MPFS_CACHE_ECC_INJECT_ERROR (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_ECC_INJECT_ERROR_OFFSET)
#define MPFS_CACHE_ECC_DIR_FIX_ADDR (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_ECC_DIR_FIX_ADDR_OFFSET)
#define MPFS_CACHE_ECC_DIR_FIX_COUNT (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_ECC_DIR_FIX_COUNT_OFFSET)
#define MPFS_CACHE_ECC_DATA_FAIL_ADDR (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_ECC_DATA_FAIL_ADDR_OFFSET)
#define MPFS_CACHE_ECC_DATA_FAIL_COUNT (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_ECC_DATA_FAIL_COUNT_OFFSET)
#define MPFS_CACHE_FLUSH64 (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_FLUSH64_OFFSET)
#define MPFS_CACHE_FLUSH32 (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_FLUSH32_OFFSET)
#define MPFS_CACHE_WAY_MASK_DMA (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_DMA_OFFSET)
#define MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_0 (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_0_OFFSET)
#define MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_1 (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_1_OFFSET)
#define MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_2 (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_2_OFFSET)
#define MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_3 (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_3_OFFSET)
#define MPFS_CACHE_WAY_MASK_E51_DCACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_E51_DCACHE_OFFSET)
#define MPFS_CACHE_WAY_MASK_E51_ICACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_E51_ICACHE_OFFSET)
#define MPFS_CACHE_WAY_MASK_U54_1_DCACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_U54_1_DCACHE_OFFSET)
#define MPFS_CACHE_WAY_MASK_U54_1_ICACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_U54_1_ICACHE_OFFSET)
#define MPFS_CACHE_WAY_MASK_U54_2_DCACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_U54_2_DCACHE_OFFSET)
#define MPFS_CACHE_WAY_MASK_U54_2_ICACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_U54_2_ICACHE_OFFSET)
#define MPFS_CACHE_WAY_MASK_U54_3_DCACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_U54_3_DCACHE_OFFSET)
#define MPFS_CACHE_WAY_MASK_U54_3_ICACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_U54_3_ICACHE_OFFSET)
#define MPFS_CACHE_WAY_MASK_U54_4_DCACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_U54_4_DCACHE_OFFSET)
#define MPFS_CACHE_WAY_MASK_U54_4_ICACHE (MPFS_CACHE_CTRL_BASE + MPFS_CACHE_WAY_MASK_U54_4_ICACHE_OFFSET)
#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_CACHE_H */

134
arch/risc-v/src/mpfs/mpfs_cache.c Executable file
View File

@ -0,0 +1,134 @@
/****************************************************************************
* arch/risc-v/src/mpfs/mpfs_cache.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include <arch/board/board_liberodefs.h>
#include "riscv_arch.h"
#include "hardware/mpfs_cache.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define MPFS_SYSREG_L2_SHUTDOWN_CR (MPFS_SYSREG_BASE + \
MPFS_SYSREG_L2_SHUTDOWN_CR_OFFSET)
#define mb() asm volatile ("fence" ::: "memory")
#define MPFS_L2LIM_ADDR 0x08200000
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: mpfs_enable_cache
*
* Description:
* Enables L2 and L1 caches and the cache ways. The values are defined in
* the board_liberodefs.h -file. Those values are generated via the Libero
* SoC Design Suite or utilized from the reference implementation.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void mpfs_enable_cache(void)
{
/* Increasing the ways decreases the 2 MB l2lim area:
* - Way0: 0x081e0000 - 0x08200000
* - Way1: 0x081c0000 - 0x081e0000
* ...
* - Way15: 0x08000000 - 0x08020000
*
* For example, 7 + 1 ways eats up 1 MB of the l2lim whereas all 16 would
* fill up the entire region.
*
* First, check that the l2lim is not overlapping with the cache.
* MPFS_IDLESTACK_TOP may be also elsewhere, when configured into DDR
* etc. which makes the check pointless.
*/
if ((MPFS_IDLESTACK_TOP & 0xff000000) == 0x08000000)
{
DEBUGASSERT((MPFS_L2LIM_ADDR - (LIBERO_SETTING_WAY_ENABLE + 1) *
0x20000) > MPFS_IDLESTACK_TOP);
}
putreg32(LIBERO_SETTING_WAY_ENABLE, MPFS_CACHE_WAY_ENABLE);
putreg32(LIBERO_SETTING_L2_SHUTDOWN_CR, MPFS_SYSREG_L2_SHUTDOWN_CR);
putreg32(LIBERO_SETTING_WAY_MASK_DMA, MPFS_CACHE_WAY_MASK_DMA);
putreg32(LIBERO_SETTING_WAY_MASK_AXI4_PORT_0,
MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_0);
putreg32(LIBERO_SETTING_WAY_MASK_AXI4_PORT_1,
MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_1);
putreg32(LIBERO_SETTING_WAY_MASK_AXI4_PORT_2,
MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_2);
putreg32(LIBERO_SETTING_WAY_MASK_AXI4_PORT_3,
MPFS_CACHE_WAY_MASK_AXI4_SLAVE_PORT_3);
putreg32(LIBERO_SETTING_WAY_MASK_E51_ICACHE,
MPFS_CACHE_WAY_MASK_E51_DCACHE);
putreg32(LIBERO_SETTING_WAY_MASK_U54_1_DCACHE,
MPFS_CACHE_WAY_MASK_U54_1_DCACHE);
putreg32(LIBERO_SETTING_WAY_MASK_U54_1_ICACHE,
MPFS_CACHE_WAY_MASK_U54_1_ICACHE);
putreg32(LIBERO_SETTING_WAY_MASK_U54_2_DCACHE,
MPFS_CACHE_WAY_MASK_U54_2_DCACHE);
putreg32(LIBERO_SETTING_WAY_MASK_U54_2_ICACHE,
MPFS_CACHE_WAY_MASK_U54_2_ICACHE);
putreg32(LIBERO_SETTING_WAY_MASK_U54_3_DCACHE,
MPFS_CACHE_WAY_MASK_U54_3_DCACHE);
putreg32(LIBERO_SETTING_WAY_MASK_U54_3_ICACHE,
MPFS_CACHE_WAY_MASK_U54_3_ICACHE);
putreg32(LIBERO_SETTING_WAY_MASK_U54_4_DCACHE,
MPFS_CACHE_WAY_MASK_U54_4_DCACHE);
putreg32(LIBERO_SETTING_WAY_MASK_U54_4_ICACHE,
MPFS_CACHE_WAY_MASK_U54_4_ICACHE);
/* L2 scratchpad region needs to be configured right here. Currently
* we have no OpenSBI or other modules using the region so it isn't
* configured. This corresponds to LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS
* = 0.
*/
putreg32(LIBERO_SETTING_WAY_MASK_E51_DCACHE,
MPFS_CACHE_WAY_MASK_E51_DCACHE);
mb();
}

View File

@ -0,0 +1,76 @@
/****************************************************************************
* arch/risc-v/src/mpfs/mpfs_cache.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_MPFS_MPFS_CACHE_H
#define __ARCH_RISCV_SRC_MPFS_MPFS_CACHE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: mpfs_enable_cache
*
* Description:
* Enables L2 and L1 caches and the cache ways. The values are defined in
* the board_liberodefs.h -file. Those values are generated via the Libero
* SoC Design Suite or utilized from the reference implementation.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void mpfs_enable_cache(void);
#if defined(__cplusplus)
}
#endif
#undef EXTERN
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_MPFS_MPFS_CACHE_H */

View File

@ -32,6 +32,7 @@
#include "mpfs.h"
#include "mpfs_clockconfig.h"
#include "mpfs_ddr.h"
#include "mpfs_cache.h"
#include "mpfs_userspace.h"
#include "riscv_arch.h"
@ -125,6 +126,18 @@ void __mpfs_start(uint32_t mhartid)
mpfs_boardinitialize();
/* Initialize the caches. Should only be executed from E51 (hart 0) to be
* functional. Consider the caches already configured if running without
* the CONFIG_MPFS_BOOTLOADER -option.
*/
#ifdef CONFIG_MPFS_BOOTLOADER
if (mhartid == 0)
{
mpfs_enable_cache();
}
#endif
showprogress('C');
/* For the case of the separate user-/kernel-space build, perform whatever

View File

@ -593,4 +593,25 @@
#define LIBERO_SETTING_DPC_BITS 0x00050422
#define LIBERO_SETTING_DATA_LANES_USED 0x00000004
/* Cache settings */
#define LIBERO_SETTING_WAY_MASK_DMA 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_0 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_1 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_2 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_3 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_E51_DCACHE 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_E51_ICACHE 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_U54_1_DCACHE 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_U54_1_ICACHE 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_U54_2_DCACHE 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_U54_2_ICACHE 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_U54_3_DCACHE 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_U54_3_ICACHE 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_U54_4_DCACHE 0x0000ffff
#define LIBERO_SETTING_WAY_MASK_U54_4_ICACHE 0x0000ffff
#define LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS 0x00000000
#define LIBERO_SETTING_L2_SHUTDOWN_CR 0x00000000
#define LIBERO_SETTING_WAY_ENABLE 0x00000007
#endif /* __BOARDS_RISCV_MPFS_ICICLE_INCLUDE_BOARD_LIBERODEFS_H */