diff options
-rw-r--r-- | docs/components/secure-partition-manager.rst | 30 | ||||
-rw-r--r-- | lib/gpt_rme/gpt_rme_private.h | 38 |
2 files changed, 60 insertions, 8 deletions
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index 057226181..68bb6f2fd 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -1063,6 +1063,36 @@ streams. Fault handling, Performance Monitor Extensions, Event Handling, MPAM. - No support for independent peripheral devices. +S-EL0 Partition support +========================= +The SPMC (Hafnium) has limited capability to run S-EL0 FF-A partitions using +FEAT_VHE (mandatory with ARMv8.1 in non-secure state, and in secure world +with ARMv8.4 and FEAT_SEL2). + +S-EL0 partitions are useful for simple partitions that don't require full +Trusted OS functionality. It is also useful to reduce jitter and cycle +stealing from normal world since they are more lightweight than VMs. + +S-EL0 partitions are presented, loaded and initialized the same as S-EL1 VMs by +the SPMC. They are differentiated primarily by the 'exception-level' property +and the 'execution-ctx-count' property in the SP manifest. They are host apps +under the single EL2&0 Stage-1 translation regime controlled by the SPMC and +call into the SPMC through SVCs as opposed to HVCs and SMCs. These partitions +can use FF-A defined services (FFA_MEM_PERM_*) to update or change permissions +for memory regions. + +S-EL0 partitions are required by the FF-A specification to be UP endpoints, +capable of migrating, and the SPMC enforces this requirement. The SPMC allows +a S-EL0 partition to accept a direct message from secure world and normal world, +and generate direct responses to them. + +Memory sharing between and with S-EL0 partitions is supported. +Indirect messaging, Interrupt handling and Notifications are not supported with +S-EL0 partitions and is work in progress, planned for future releases. +All S-EL0 partitions must use AArch64. AArch32 S-EL0 partitions are not +supported. + + References ========== diff --git a/lib/gpt_rme/gpt_rme_private.h b/lib/gpt_rme/gpt_rme_private.h index 5770bf7d6..4203bba28 100644 --- a/lib/gpt_rme/gpt_rme_private.h +++ b/lib/gpt_rme/gpt_rme_private.h @@ -117,11 +117,13 @@ typedef enum { /******************************************************************************/ /* + * Width of the L0 index field. + * * If S is greater than or equal to T then there is a single L0 region covering * the entire protected space so there is no L0 index, so the width (and the * derivative mask value) are both zero. If we don't specifically handle this * special case we'll get a negative width value which does not make sense and - * could cause a lot of problems. + * would cause problems. */ #define GPT_L0_IDX_WIDTH(_t) (((_t) > GPT_S_VAL) ? \ ((_t) - GPT_S_VAL) : (0U)) @@ -129,9 +131,16 @@ typedef enum { /* Bit shift for the L0 index field in a PA. */ #define GPT_L0_IDX_SHIFT (GPT_S_VAL) -/* Mask for the L0 index field, must be shifted. */ -#define GPT_L0_IDX_MASK(_t) (0xFFFFFFFFFFFFFFFFUL >> \ - (64U - (GPT_L0_IDX_WIDTH(_t)))) +/* + * Mask for the L0 index field, must be shifted. + * + * The value 0x3FFFFF is 22 bits wide which is the maximum possible width of the + * L0 index within a physical address. This is calculated by + * ((t_max - 1) - s_min + 1) where t_max is 52 for 4PB, the largest PPS, and + * s_min is 30 for 1GB, the smallest L0GPTSZ. + */ +#define GPT_L0_IDX_MASK(_t) (0x3FFFFFUL >> (22U - \ + (GPT_L0_IDX_WIDTH(_t)))) /* Total number of L0 regions. */ #define GPT_L0_REGION_COUNT(_t) ((GPT_L0_IDX_MASK(_t)) + 1U) @@ -146,15 +155,28 @@ typedef enum { /* L1 address attribute macros */ /******************************************************************************/ -/* Width of the L1 index field. */ +/* + * Width of the L1 index field. + * + * This field does not have a special case to handle widths less than zero like + * the L0 index field above since all valid combinations of PGS (p) and L0GPTSZ + * (s) will result in a positive width value. + */ #define GPT_L1_IDX_WIDTH(_p) ((GPT_S_VAL - 1U) - ((_p) + 3U)) /* Bit shift for the L1 index field. */ #define GPT_L1_IDX_SHIFT(_p) ((_p) + 4U) -/* Mask for the L1 index field, must be shifted. */ -#define GPT_L1_IDX_MASK(_p) (0xFFFFFFFFFFFFFFFFUL >> \ - (64U - (GPT_L1_IDX_WIDTH(_p)))) +/* + * Mask for the L1 index field, must be shifted. + * + * The value 0x7FFFFF is 23 bits wide and is the maximum possible width of the + * L1 index within a physical address. It is calculated by + * ((s_max - 1) - (p_min + 4) + 1) where s_max is 39 for 512gb, the largest + * L0GPTSZ, and p_min is 12 for 4KB granules, the smallest PGS. + */ +#define GPT_L1_IDX_MASK(_p) (0x7FFFFFUL >> (23U - \ + (GPT_L1_IDX_WIDTH(_p)))) /* Bit shift for the index of the L1 GPI in a PA. */ #define GPT_L1_GPI_IDX_SHIFT(_p) (_p) |