arch/risc-v: Simplify pmp_check_region_attrs sanity-checks

For TOR: Any size and 4-byte aligned address is required
For NA4: Only size 4 and 4-byte aligned address is good
For NAPOT: Minimum size is 8 bytes, minimum base alignment is 8 bytes,
           and size must be power-of-two aligned with base

This commit simplifies these checks and removes all the nonsense added
by a misunderstanding of how the MPFS / Polarfire SoC's PMP works.
This commit is contained in:
Ville Juven 2023-10-23 15:50:00 +03:00 committed by Alan Carvalho de Assis
parent 8e6b448f47
commit 9c725c4903
1 changed files with 44 additions and 39 deletions

View File

@ -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;
}