1
0
Fork 0
forked from nuttx/nuttx-update

risc-v/bl808: Flush MMU Cache after updating SATP

Ox64 BL808 crashes with a Page Fault when we run `getprime` then `hello`. This is caused by the T-Head C906 MMU incorrectly accessing the MMU Page Tables of the Previous Process (`getprime`) while starting the New Process (`hello`).

To fix the problem, this PR flushes the MMU Cache whenever we point the MMU SATP Register to the New Page Tables. We execute 2 RISC-V Instructions that are specific to T-Head C906:

- DCACHE.IALL: Invalidate all Page Table Entries in the D-Cache
- SYNC.S: Ensure that all Cache Operations are completed

This is derived from the T-Head Errata for Linux Kernel. More details here: https://lupyuen.github.io/articles/mmu#appendix-flush-the-mmu-cache-for-t-head-c906

Modified Files:

- `arch/risc-v/src/common/riscv_mmu.h`: If needed, `mmu_write_satp()` calls `mmu_flush_cache()` (weak function) to flush the MMU Cache. (Like for T-Head C906)

- `arch/risc-v/src/bl808/bl808_mm_init.c`: Flush the MMU Cache for T-Head C906. Extend `mmuflags` from 32-bit to 64-bit to be consistent with `mmu_ln_setentry()`.

- `boards/risc-v/bl808/ox64/configs/nsh/defconfig`: Enable `ostest` in the Build Config. Update `CONFIG_BOARD_LOOPSPERMSEC` according to `calib_udelay`.
This commit is contained in:
Lee Lup Yuen 2024-01-21 21:43:15 +08:00 committed by Xiang Xiao
parent cba993df85
commit 62c358946d
3 changed files with 54 additions and 7 deletions

View file

@ -74,8 +74,8 @@
#define SLAB_COUNT (sizeof(m_l3_pgtable) / RV_MMU_PAGE_SIZE)
#define KMM_PAGE_SIZE RV_MMU_L3_PAGE_SIZE
#define KMM_PBASE PGT_L3_PBASE
#define KMM_PBASE_IDX 3
#define KMM_PBASE PGT_L3_PBASE
#define KMM_PBASE_IDX 3
#define KMM_SPBASE PGT_L2_PBASE
#define KMM_SPBASE_IDX 2
@ -171,7 +171,7 @@ static uintptr_t slab_alloc(void)
****************************************************************************/
static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
uint32_t mmuflags)
uint64_t mmuflags)
{
uintptr_t endaddr;
uintptr_t pbase;
@ -235,8 +235,7 @@ void bl808_kernel_mappings(void)
/* Begin mapping memory to MMU; note that at this point the MMU is not yet
* active, so the page table virtual addresses are actually physical
* addresses and so forth. M-mode does not perform translations anyhow, so
* this mapping is quite simple to do
* addresses and so forth.
*/
/* Map I/O region, use enough large page tables for the IO region. */
@ -291,8 +290,34 @@ void bl808_mm_init(void)
bl808_kernel_mappings();
/* Enable MMU (note: system is still in M-mode) */
/* Enable MMU */
binfo("mmu_enable: satp=%" PRIuPTR "\n", g_kernel_pgt_pbase);
mmu_enable(g_kernel_pgt_pbase, 0);
}
/****************************************************************************
* Name: mmu_flush_cache
*
* Description:
* Flush the MMU Cache for T-Head C906. Called by mmu_write_satp() after
* updating the MMU SATP Register, when swapping MMU Page Tables.
* This operation executes RISC-V Instructions that are specific to
* T-Head C906.
*
****************************************************************************/
void weak_function mmu_flush_cache(void)
{
__asm__ __volatile__
(
/* DCACHE.IALL: Invalidate all Page Table Entries in the D-Cache */
".long 0x0020000b\n"
/* SYNC.S: Ensure that all Cache Operations are completed */
".long 0x0190000b\n"
);
}

View file

@ -21,6 +21,10 @@
#ifndef ___ARCH_RISC_V_SRC_COMMON_RISCV_MMU_H_
#define ___ARCH_RISC_V_SRC_COMMON_RISCV_MMU_H_
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* RV32/64 page size */
#define RV_MMU_PAGE_SHIFT (12)
@ -150,6 +154,16 @@
extern uintptr_t g_kernel_pgt_pbase;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
void weak_function mmu_flush_cache(void);
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Name: mmu_satp_reg
*
@ -197,6 +211,13 @@ static inline void mmu_write_satp(uintptr_t reg)
: "rK" (reg)
: "memory"
);
/* Flush the MMU Cache if needed (T-Head C906) */
if (mmu_flush_cache != NULL)
{
mmu_flush_cache();
}
}
/****************************************************************************

View file

@ -34,7 +34,7 @@ CONFIG_ARCH_USE_S_MODE=y
CONFIG_BL808_UART3=y
CONFIG_BOARDCTL_ROMDISK=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=116524
CONFIG_BOARD_LOOPSPERMSEC=1120
CONFIG_BUILD_KERNEL=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_ASSERTIONS_EXPRESSION=y
@ -79,6 +79,7 @@ CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_NSH_PROGNAME="init"
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART3_BAUD=2000000
CONFIG_UART3_SERIAL_CONSOLE=y
CONFIG_USEC_PER_TICK=1000