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:
parent
cba993df85
commit
62c358946d
3 changed files with 54 additions and 7 deletions
|
@ -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"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue