riscv/riscv_pmp.c: Improve NAPOT area validity checks
Check that the base address and region size are properly aligned with relation to each other. With NAPOT encoding the area base and size are not arbitrary, as when the size increases the amount of bits available for encoding the base address decreases.
This commit is contained in:
parent
7d1763a57c
commit
779741d1d9
@ -100,6 +100,32 @@ typedef struct pmp_entry_s pmp_entry_t;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: log2ceil
|
||||
*
|
||||
* Description:
|
||||
* Calculate the up-rounded power-of-two for input.
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - The size of the PMP region.
|
||||
*
|
||||
* Returned Value:
|
||||
* Power-of-two for argument, rounded up.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uintptr_t log2ceil(uintptr_t size)
|
||||
{
|
||||
uintptr_t pot = 0;
|
||||
|
||||
for (size = size - 1; size > 1; size >>= 1)
|
||||
{
|
||||
pot++;
|
||||
}
|
||||
|
||||
return pot;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmp_check_addrmatch_type
|
||||
*
|
||||
@ -160,7 +186,8 @@ static bool pmp_check_addrmatch_type(uintptr_t type)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool pmp_check_region_attrs(uintptr_t base, uintptr_t size)
|
||||
static bool pmp_check_region_attrs(uintptr_t base, uintptr_t size,
|
||||
uintptr_t type)
|
||||
{
|
||||
/* Check that the size is not too small */
|
||||
|
||||
@ -183,7 +210,23 @@ static bool pmp_check_region_attrs(uintptr_t base, uintptr_t size)
|
||||
return false;
|
||||
}
|
||||
|
||||
return OK;
|
||||
/* 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 = log2ceil(size);
|
||||
|
||||
if ((base & ((UINT64_C(1) << pot) - 1)) != 0)
|
||||
{
|
||||
/* The start address is not properly aligned with size */
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -455,7 +498,7 @@ int riscv_config_pmp_region(uintptr_t region, uintptr_t attr,
|
||||
|
||||
/* Check the region attributes */
|
||||
|
||||
if (pmp_check_region_attrs(base, size))
|
||||
if (pmp_check_region_attrs(base, size, type) == false)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -463,7 +506,7 @@ int riscv_config_pmp_region(uintptr_t region, uintptr_t attr,
|
||||
/* Calculate new base address from type */
|
||||
|
||||
addr = base >> 2;
|
||||
if (PMPCFG_A_NAPOT == (attr & PMPCFG_A_MASK))
|
||||
if (type == PMPCFG_A_NAPOT)
|
||||
{
|
||||
addr |= (size - 1) >> 3;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user