Physical Memory Protection¶
Physical Memory Protection (PMP) is a part of the RISC-V Privileged Architecture Specification which discribes the interface for a standard RISC-V memory protection unit.
The PMP defines a finite number of PMP regions which can be individually configured to enforce access permissions to a range of addresses in memory. Each PMP region is configurable with the following options:
-
struct
metal_pmp_config
Configuration for a PMP region.
Public Types
-
enum
metal_pmp_locked
Sets whether the PMP region is locked.
Values:
-
enumerator
METAL_PMP_UNLOCKED
-
enumerator
METAL_PMP_LOCKED
-
enumerator
Public Members
-
unsigned int
R
Sets whether reads to the PMP region succeed.
-
unsigned int
W
Sets whether writes to the PMP region succeed.
-
unsigned int
X
Sets whether the PMP region is executable.
-
enum metal_pmp_address_mode
A
Sets the addressing mode of the PMP region.
-
enum
Initializing the PMP¶
All PMP-related functions first depend on having a handle to the PMP device:
struct metal_pmp *pmp = metal_pmp_get_device();
if(!pmp) {
/* Failed to get PMP device handle */
}
PMP initialization is optional and has the effect of disabling all PMP regions, if possible:
metal_pmp_init(pmp);
The number of PMP regions available can be retrieved from the PMP device handle:
-
struct
metal_pmp
A handle for the PMP device.
Configuring a PMP Region¶
Freedom Metal has a set of APIs for configuring a PMP region. The most generic of these is
-
int
metal_pmp_set_region
(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config config, size_t address) Configure a PMP region.
- Return
0 upon success
- Parameters
pmp
: The PMP device handleregion
: The PMP region to configureconfig
: The desired configuration of the PMP regionaddress
: The desired address of the PMP region
This function allows for the configuration of all PMP region settings.
Additional APIs are provided for granularly changing individual PMP region settings. For example:
-
int
metal_pmp_set_address
(struct metal_pmp *pmp, unsigned int region, size_t address) Set the address for a PMP region.
- Return
0 if the address is successfully set
- Parameters
pmp
: The PMP device handleregion
: The PMP region to setaddress
: The desired address of the PMP region
-
int
metal_pmp_lock
(struct metal_pmp *pmp, unsigned int region) Lock a PMP region.
- Return
0 if the region is successfully locked
- Parameters
pmp
: The PMP device handleregion
: The PMP region to lock
-
int
metal_pmp_set_writeable
(struct metal_pmp *pmp, unsigned int region, int W) Set the writable bit for a PMP region.
- Return
0 if the writable bit is successfully set
- Parameters
pmp
: The PMP device handleregion
: The PMP region to setW
: The desired value of the writable bit
Additional documentation for this API is provided in the PMP API reference.
The RISC-V specification allows implementation of PMP to hard-wire the configuration values of PMP regions. In these cases, attempts to configure these PMP regions will fail.
Handling PMP Access Faults¶
Attempted memory accesses which the PMP is configured to prevent trigger a CPU exception. These exceptions can be handled by installing a CPU exception handler for exception codes related to memory access faults.
Additional documentation about creating and registering exception handlers can be found in the Exception Handlers Developer Guide.
Additional Documentation¶
Additional documentation about the Physical Memory Protection system and fault handling on RISC-V systems can be found in The RISC-V Privileged ISA Specification v1.10.