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 */