diff --git a/arch/risc-v/src/common/riscv_pmp.c b/arch/risc-v/src/common/riscv_pmp.c index 302c60338c..2f63c2596d 100644 --- a/arch/risc-v/src/common/riscv_pmp.c +++ b/arch/risc-v/src/common/riscv_pmp.c @@ -48,14 +48,6 @@ #define PMP_XLEN (64) #endif -/* Minimum supported block size */ - -#define MIN_BLOCK_SIZE (PMP_XLEN / 8) - -/* Address and block size alignment mask */ - -#define BLOCK_ALIGN_MASK (MIN_BLOCK_SIZE - 1) - #define PMP_CFG_BITS_CNT (8) #define PMP_CFG_FLAG_MASK ((uintptr_t)0xFF) @@ -106,6 +98,7 @@ typedef struct pmp_entry_s pmp_entry_t; * Input Parameters: * base - The base address of the region. * size - The memory length of the region. + * type - Address matching type. * * Returned Value: * true if it is, false otherwise. @@ -115,42 +108,54 @@ typedef struct pmp_entry_s pmp_entry_t; static bool pmp_check_region_attrs(uintptr_t base, uintptr_t size, uintptr_t type) { - /* Check that the size is not too small */ + switch (type) + { + case PMPCFG_A_TOR: - if ((type != PMPCFG_A_TOR) && (size < MIN_BLOCK_SIZE)) - { - return false; - } + /* For TOR any size is good, but alignment requirement stands */ - /* Check that the base address is aligned properly */ - - if ((base & BLOCK_ALIGN_MASK) != 0) - { - return false; - } - - /* Check that the size is aligned properly */ - - if ((size & BLOCK_ALIGN_MASK) != 0) - { - return false; - } - - /* Perform additional checks on base and size for NAPOT area */ - - if (type == PMPCFG_A_NAPOT) - { - /* Get the power-of-two for size, rounded up */ - - uintptr_t pot = LOG2_CEIL(size); - - if ((base & ((UINT64_C(1) << pot) - 1)) != 0) + if ((base & 0x03) != 0) { - /* The start address is not properly aligned with size */ - return false; } - } + + break; + + case PMPCFG_A_NA4: + + /* For NA4 only size 4 is good, and base must be aligned */ + + if ((base & 0x03) != 0 || size != 4) + { + return false; + } + + break; + + case PMPCFG_A_NAPOT: + { + /* For NAPOT, both base and size must be properly aligned */ + + if ((base & 0x07) != 0 || size < 8) + { + return false; + } + + /* Get the power-of-two for size, rounded up */ + + if ((base & ((UINT64_C(1) << LOG2_CEIL(size)) - 1)) != 0) + { + /* The start address is not properly aligned with size */ + + return false; + } + } + + break; + + default: + break; + } return true; }