From 3de3eb447816f07e8526811c2923ee51c20a0234 Mon Sep 17 00:00:00 2001 From: Ville Juven Date: Thu, 11 Jan 2024 12:18:24 +0200 Subject: [PATCH 1/2] mpfs_usb.c: Remove PMPCFG configuration from the driver This is not the right place to modify DMA memory protection values. Why not? These are designed to protect other AMP mode instances. Opening the entire SoC's memory for the USB DMA kind of defeats this purpose. Also, the driver cannot know how to configure these registers correctly, only opening up the whole SoC "works". --- arch/risc-v/src/mpfs/mpfs_usb.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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 } From f92508220b8e6cc09ba7aa2e4045f01e18df9c2c Mon Sep 17 00:00:00 2001 From: Ville Juven Date: Thu, 11 Jan 2024 12:22:21 +0200 Subject: [PATCH 2/2] 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 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 */