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 983387e6dd mpfs_mpucfg.c: Add mpfs_mpu_lock()
983387e6dd is described below

commit 983387e6ddde090a3b20f3f0f4bbf17706840c8a
Author: Ville Juven <[email protected]>
AuthorDate: Thu Jan 11 12:22:21 2024 +0200

    mpfs_mpucfg.c: Add mpfs_mpu_lock()
    
    Add method to lock an MPUCFG entry. Locking means the value of the register
    cannot be changed until the SoC is reset.
---
 arch/risc-v/src/mpfs/mpfs_mpu.c | 54 +++++++++++++++++++++++++++++++++++------
 arch/risc-v/src/mpfs/mpfs_mpu.h | 20 +++++++++++++--
 2 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/arch/risc-v/src/mpfs/mpfs_mpu.c b/arch/risc-v/src/mpfs/mpfs_mpu.c
index 58bc30f4e8..2643c79c0a 100644
--- a/arch/risc-v/src/mpfs/mpfs_mpu.c
+++ b/arch/risc-v/src/mpfs/mpfs_mpu.c
@@ -61,9 +61,9 @@
 
 /* Encode the MPUCFG register value */
 
-#define MPFS_MPUCFG_ENCODE(mode, napot)                        \
- (((mode << MPFS_MPUCFG_MODE_SHIFT) & MPFS_MPUCFG_MODE_MASK) | \
-  ((napot << MPFS_MPUCFG_PMP_SHIFT) & MPFS_MPUCFG_PMP_MASK))
+#define MPFS_MPUCFG_ENCODE(mode, napot)                          \
+ ((((mode) << MPFS_MPUCFG_MODE_SHIFT) & MPFS_MPUCFG_MODE_MASK) | \
+  (((napot) << MPFS_MPUCFG_PMP_SHIFT) & MPFS_MPUCFG_PMP_MASK))
 
 /* Decode the MPUCFG register value */
 
@@ -91,7 +91,7 @@
  *   size - Size out.
  *
  * Returned Value:
- *   Base address
+ *   Base address.
  *
  ****************************************************************************/
 
@@ -136,7 +136,7 @@ static void napot_decode(uintptr_t val, uintptr_t *base, 
uintptr_t *size)
  *   size must align with each other.
  *
  * Returned Value:
- *   0 on success; negated error on failure
+ *   0 on success; negated error on failure.
  *
  ****************************************************************************/
 
@@ -184,7 +184,7 @@ int mpfs_mpu_set(uintptr_t reg, uintptr_t perm, uintptr_t 
base,
 
   /* Calculate mode (RWX), only NAPOT encoding is supported */
 
-  mode = (perm & PMPCFG_RWX_MASK) | PMPCFG_A_NAPOT;
+  mode = (perm & (PMPCFG_RWX_MASK | PMPCFG_L)) | PMPCFG_A_NAPOT;
 
   /* Do the NAPOT encoding */
 
@@ -210,7 +210,7 @@ int mpfs_mpu_set(uintptr_t reg, uintptr_t perm, uintptr_t 
base,
  *   size - The length of the region.
  *
  * Returned Value:
- *   true if access OK; false if not
+ *   true if access OK; false if not.
  *
  ****************************************************************************/
 
@@ -241,3 +241,43 @@ bool mpfs_mpu_access_ok(uintptr_t reg, uintptr_t perm, 
uintptr_t base,
 
   return (base >= reg_base && (base + size) <= (reg_base + reg_size));
 }
+
+/****************************************************************************
+ * Name: mpfs_mpu_lock
+ *
+ * Description:
+ *   Lock an MPUCFG register from further modifications.
+ *
+ * Input Parameters:
+ *   reg  - The MPUCFG register to lock.
+ *
+ * Returned Value:
+ *   0 on success; negated error on failure.
+ *
+ ****************************************************************************/
+
+int mpfs_mpu_lock(uintptr_t reg)
+{
+  uintptr_t mode;
+  uintptr_t napot;
+
+  /* Sanity check the register */
+
+  if (reg < MPFS_MPUCFG_BASE || reg >= MPFS_MPUCFG_END)
+    {
+      return -EINVAL;
+    }
+
+  MPFS_MPUCFG_DECODE(reg, &mode, &napot);
+
+  /* If the entry is already locked, everything is fine */
+
+  if ((mode & PMPCFG_L) == 0)
+    {
+      /* Set the lock bit and write the value back */
+
+      putreg64(MPFS_MPUCFG_ENCODE(mode | PMPCFG_L, napot), reg);
+    }
+
+  return OK;
+}
diff --git a/arch/risc-v/src/mpfs/mpfs_mpu.h b/arch/risc-v/src/mpfs/mpfs_mpu.h
index 6bef8fe5f4..d934cd6404 100644
--- a/arch/risc-v/src/mpfs/mpfs_mpu.h
+++ b/arch/risc-v/src/mpfs/mpfs_mpu.h
@@ -49,7 +49,7 @@
  *   size must align with each other.
  *
  * Returned Value:
- *   0 on success; negated error on failure
+ *   0 on success; negated error on failure.
  *
  ****************************************************************************/
 
@@ -69,11 +69,27 @@ int mpfs_mpu_set(uintptr_t reg, uintptr_t perm, uintptr_t 
base,
  *   size - The length of the region.
  *
  * Returned Value:
- *   true if access OK; false if not
+ *   true if access OK; false if not.
  *
  ****************************************************************************/
 
 bool mpfs_mpu_access_ok(uintptr_t reg, uintptr_t perm, uintptr_t base,
                         uintptr_t size);
 
+/****************************************************************************
+ * Name: mpfs_mpu_lock
+ *
+ * Description:
+ *   Lock an MPUCFG register from further modifications.
+ *
+ * Input Parameters:
+ *   reg  - The MPUCFG register to lock.
+ *
+ * Returned Value:
+ *   0 on success; negated error on failure.
+ *
+ ****************************************************************************/
+
+int mpfs_mpu_lock(uintptr_t reg);
+
 #endif /* __ARCH_RISC_V_SRC_MPFS_MPFS_MPU_H */

Reply via email to