diff --git a/arch/risc-v/src/mpfs/mpfs_mpu.c b/arch/risc-v/src/mpfs/mpfs_mpu.c index 58bc30f4e8deb..2643c79c0ac7a 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 6bef8fe5f4c25..d934cd64044ef 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 */ diff --git a/arch/risc-v/src/mpfs/mpfs_usb.c b/arch/risc-v/src/mpfs/mpfs_usb.c index 85fd1dbdf086e..e048ab6a6b941 100644 --- a/arch/risc-v/src/mpfs/mpfs_usb.c +++ b/arch/risc-v/src/mpfs/mpfs_usb.c @@ -3675,7 +3675,7 @@ static void mpfs_usb_iomux(void) #ifdef CONFIG_USBDEV_DMA /* DMA operations need to open the USB PMP registers for proper - * operation. If not configured, apply default settings. + * operation. */ uint64_t pmpcfg_usb_x; @@ -3684,28 +3684,24 @@ static void mpfs_usb_iomux(void) if ((pmpcfg_usb_x & 0x1ffffff000000000llu) != 0x1f00000000000000llu) { uerr("Please check the MPFS_PMPCFG_USB_0 register.\n"); - putreg64(0x1f00000fffffffffllu, MPFS_PMPCFG_USB_0); } pmpcfg_usb_x = getreg64(MPFS_PMPCFG_USB_1); if ((pmpcfg_usb_x & 0x1ffffff000000000llu) != 0x1f00000000000000llu) { uerr("Please check the MPFS_PMPCFG_USB_1 register.\n"); - putreg64(0x1f00000fffffffffllu, MPFS_PMPCFG_USB_1); } pmpcfg_usb_x = getreg64(MPFS_PMPCFG_USB_2); if ((pmpcfg_usb_x & 0x1ffffff000000000llu) != 0x1f00000000000000llu) { uerr("Please check the MPFS_PMPCFG_USB_2 register.\n"); - putreg64(0x1f00000fffffffffllu, MPFS_PMPCFG_USB_2); } pmpcfg_usb_x = getreg64(MPFS_PMPCFG_USB_3); if ((pmpcfg_usb_x & 0x1ffffff000000000llu) != 0x1f00000000000000llu) { uerr("Please check the MPFS_PMPCFG_USB_3 register.\n"); - putreg64(0x1f00000fffffffffllu, MPFS_PMPCFG_USB_3); } #endif }