This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 62c358946d risc-v/bl808: Flush MMU Cache after updating SATP
62c358946d is described below

commit 62c358946dd7eebcdf38fe38edd30e079791dd02
Author: Lee Lup Yuen <[email protected]>
AuthorDate: Sun Jan 21 21:43:15 2024 +0800

    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`.
---
 arch/risc-v/src/bl808/bl808_mm_init.c          | 37 +++++++++++++++++++++-----
 arch/risc-v/src/common/riscv_mmu.h             | 21 +++++++++++++++
 boards/risc-v/bl808/ox64/configs/nsh/defconfig |  3 ++-
 3 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/arch/risc-v/src/bl808/bl808_mm_init.c 
b/arch/risc-v/src/bl808/bl808_mm_init.c
index 2a0ee3d29b..0d17982a8e 100644
--- a/arch/risc-v/src/bl808/bl808_mm_init.c
+++ b/arch/risc-v/src/bl808/bl808_mm_init.c
@@ -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"
+    );
+}
diff --git a/arch/risc-v/src/common/riscv_mmu.h 
b/arch/risc-v/src/common/riscv_mmu.h
index 0e6e1b2b38..23ce40b525 100644
--- a/arch/risc-v/src/common/riscv_mmu.h
+++ b/arch/risc-v/src/common/riscv_mmu.h
@@ -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();
+    }
 }
 
 /****************************************************************************
diff --git a/boards/risc-v/bl808/ox64/configs/nsh/defconfig 
b/boards/risc-v/bl808/ox64/configs/nsh/defconfig
index 32aaa1ea5d..7cdd365ef2 100644
--- a/boards/risc-v/bl808/ox64/configs/nsh/defconfig
+++ b/boards/risc-v/bl808/ox64/configs/nsh/defconfig
@@ -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

Reply via email to