aboutsummaryrefslogtreecommitdiff
path: root/include/lib
diff options
context:
space:
mode:
authorjohpow01 <john.powell@arm.com>2021-06-16 17:57:28 -0500
committerjohpow01 <john.powell@arm.com>2021-10-05 16:24:57 -0500
commitf19dc624a17c9df6aa444e33568b1f70ff4e9341 (patch)
tree971ffe9a2948af46edf4ee3ff3fceaf0a50f9d87 /include/lib
parent07e96d1d2958b6f121476fd391ac67bf8c2c4735 (diff)
downloadarm-trusted-firmware-f19dc624a17c9df6aa444e33568b1f70ff4e9341.tar.gz
refactor(gpt): productize and refactor GPT library
This patch updates and refactors the GPT library and fixes bugs. - Support all combinations of PGS, PPS, and L0GPTSZ parameters. - PPS and PGS are set at runtime, L0GPTSZ is read from GPCCR_EL3. - Use compiler definitions to simplify code. - Renaming functions to better suit intended uses. - MMU enabled before GPT APIs called. - Add comments to make function usage more clear in GPT library. - Added _rme suffix to file names to differentiate better from the GPT file system code. - Renamed gpt_defs.h to gpt_rme_private.h to better separate private and public code. - Renamed gpt_core.c to gpt_rme.c to better conform to TF-A precedent. Signed-off-by: John Powell <john.powell@arm.com> Change-Id: I4cbb23b0f81e697baa9fb23ba458aa3f7d1ed919
Diffstat (limited to 'include/lib')
-rw-r--r--include/lib/gpt/gpt.h86
-rw-r--r--include/lib/gpt/gpt_defs.h76
-rw-r--r--include/lib/gpt_rme/gpt_rme.h276
3 files changed, 276 insertions, 162 deletions
diff --git a/include/lib/gpt/gpt.h b/include/lib/gpt/gpt.h
deleted file mode 100644
index 89d30177d..000000000
--- a/include/lib/gpt/gpt.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef GPT_H
-#define GPT_H
-
-#include <stdint.h>
-
-#include <arch.h>
-
-#include "gpt_defs.h"
-
-#define GPT_DESC_ATTRS(_type, _gpi) \
- ((((_type) & PAS_REG_DESC_TYPE_MASK) \
- << PAS_REG_DESC_TYPE_SHIFT) | \
- (((_gpi) & PAS_REG_GPI_MASK) \
- << PAS_REG_GPI_SHIFT))
-
-/*
- * Macro to create a GPT entry for this PAS range either as a L0 block
- * descriptor or L1 table descriptor depending upon the size of the range.
- */
-#define MAP_GPT_REGION(_pa, _sz, _gpi) \
- { \
- .base_pa = (_pa), \
- .size = (_sz), \
- .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_ANY, (_gpi)), \
- }
-
-/*
- * Special macro to create a L1 table descriptor at L0 for a 1GB region as
- * opposed to creating a block mapping by default.
- */
-#define MAP_GPT_REGION_TBL(_pa, _sz, _gpi) \
- { \
- .base_pa = (_pa), \
- .size = (_sz), \
- .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_TBL, (_gpi)), \
- }
-
-/*
- * Structure for specifying a Granule range and its properties
- */
-typedef struct pas_region {
- unsigned long long base_pa; /**< Base address for PAS. */
- size_t size; /**< Size of the PAS. */
- unsigned int attrs; /**< PAS GPI and entry type. */
-} pas_region_t;
-
-/*
- * Structure to initialise the Granule Protection Tables.
- */
-typedef struct gpt_init_params {
- unsigned int pgs; /**< Address Width of Phisical Granule Size. */
- unsigned int pps; /**< Protected Physical Address Size. */
- unsigned int l0gptsz; /**< Granule size on L0 table entry. */
- pas_region_t *pas_regions; /**< PAS regions to protect. */
- unsigned int pas_count; /**< Number of PAS regions to initialise. */
- uintptr_t l0_mem_base; /**< L0 Table base address. */
- size_t l0_mem_size; /**< Size of memory reserved for L0 tables. */
- uintptr_t l1_mem_base; /**< L1 Table base address. */
- size_t l1_mem_size; /**< Size of memory reserved for L1 tables. */
-} gpt_init_params_t;
-
-/** @brief Initialise the Granule Protection tables.
- */
-int gpt_init(gpt_init_params_t *params);
-
-/** @brief Enable the Granule Protection Checks.
- */
-void gpt_enable(void);
-
-/** @brief Disable the Granule Protection Checks.
- */
-void gpt_disable(void);
-
-/** @brief Transition a granule between security states.
- */
-int gpt_transition_pas(uint64_t pa,
- unsigned int src_sec_state,
- unsigned int target_pas);
-
-#endif /* GPT_H */
diff --git a/include/lib/gpt/gpt_defs.h b/include/lib/gpt/gpt_defs.h
deleted file mode 100644
index 6122a126f..000000000
--- a/include/lib/gpt/gpt_defs.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef GPT_DEFS_H
-#define GPT_DEFS_H
-
-#include <arch.h>
-#include <lib/utils_def.h>
-
-#include "gpt.h"
-
-/* GPI values */
-#define GPI_NO_ACCESS U(0x0)
-#define GPI_SECURE U(0x8)
-#define GPI_NS U(0x9)
-#define GPI_ROOT U(0xa)
-#define GPI_REALM U(0xb)
-#define GPI_ANY U(0xf)
-#define GPI_VAL_MASK ULL(0xf)
-
-/* GPT descriptor bit definitions */
-#define GPT_L1_INDEX_MASK ULL(0xf)
-#define GPT_L1_INDEX_SHIFT ULL(0x0)
-
-#define GPT_TBL_DESC ULL(0x3)
-#define GPT_BLK_DESC ULL(0x1)
-
-#define GPT_TBL_DESC_ADDR_SHIFT ULL(12)
-#define GPT_TBL_DESC_ADDR_MASK (((ULL(1) << \
- (51 - GPT_TBL_DESC_ADDR_SHIFT)) - 1) \
- << GPT_TBL_DESC_ADDR_SHIFT)
-
-#define GPT_BLOCK_DESC_GPI_VAL_SHIFT ULL(4)
-
-/* Each descriptor is 8 bytes long. */
-#define GPT_DESC_SIZE ULL(8)
-
-#define PPS_MAX_VAL PSTCR_EL3_PPS_4PB
-#define PPS_NUM_1GB_ENTRIES ULL(1024)
-#define PGS_4K_1GB_L1_TABLE_SZ (U(2) << 17)
-
-/* 2 << LOG2_8K = Bytes in 8K */
-#define LOG2_8K U(13)
-
-#define GPT_L1_SIZE ULL(0x40000) /* 256K */
-#define SZ_1G (ULL(0x1) << 30) /* 1GB */
-
-#define GPT_MIN_PGS_SHIFT U(12) /* 4K */
-
-#define L1_GPT_INDEX_MASK U(0x3fffffff)
-#define GPT_GRAN_DESC_NUM_GPIS U(4)
-
-#define PAS_REG_GPI_SHIFT U(0)
-#define PAS_REG_GPI_MASK U(0xf)
-
-/* .attrs field definitions */
-#define PAS_REG_DESC_TYPE_ANY U(0)
-#define PAS_REG_DESC_TYPE_BLK U(1)
-#define PAS_REG_DESC_TYPE_TBL U(2)
-#define PAS_REG_DESC_TYPE_SHIFT U(4)
-#define PAS_REG_DESC_TYPE_MASK U(0x3)
-#define PAS_REG_DESC_TYPE(_attrs) (((_attrs) \
- >> PAS_REG_DESC_TYPE_SHIFT) \
- & PAS_REG_DESC_TYPE_MASK)
-
-#define PAS_REG_GPI(_attrs) (((_attrs) \
- >> PAS_REG_GPI_SHIFT) \
- & PAS_REG_GPI_MASK)
-
-#define SZ_1G_MASK (SZ_1G - U(1))
-#define IS_1GB_ALIGNED(addr) (((addr) & SZ_1G_MASK) == U(0))
-
-#endif /* GPT_DEFS */
diff --git a/include/lib/gpt_rme/gpt_rme.h b/include/lib/gpt_rme/gpt_rme.h
new file mode 100644
index 000000000..379b91562
--- /dev/null
+++ b/include/lib/gpt_rme/gpt_rme.h
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GPT_RME_H
+#define GPT_RME_H
+
+#include <stdint.h>
+
+#include <arch.h>
+
+/******************************************************************************/
+/* GPT helper macros and definitions */
+/******************************************************************************/
+
+/*
+ * Structure for specifying a mapping range and it's properties. This should not
+ * be manually initialized, using the MAP_GPT_REGION_x macros is recommended as
+ * to avoid potential incompatibilities in the future.
+ */
+typedef struct pas_region {
+ uintptr_t base_pa; /* Base address for PAS. */
+ size_t size; /* Size of the PAS. */
+ unsigned int attrs; /* PAS GPI and entry type. */
+} pas_region_t;
+
+/* GPT GPI definitions */
+#define GPT_GPI_NO_ACCESS U(0x0)
+#define GPT_GPI_SECURE U(0x8)
+#define GPT_GPI_NS U(0x9)
+#define GPT_GPI_ROOT U(0xA)
+#define GPT_GPI_REALM U(0xB)
+#define GPT_GPI_ANY U(0xF)
+#define GPT_GPI_VAL_MASK UL(0xF)
+
+/* PAS attribute GPI definitions. */
+#define GPT_PAS_ATTR_GPI_SHIFT U(0)
+#define GPT_PAS_ATTR_GPI_MASK U(0xF)
+#define GPT_PAS_ATTR_GPI(_attrs) (((_attrs) \
+ >> GPT_PAS_ATTR_GPI_SHIFT) \
+ & GPT_PAS_ATTR_GPI_MASK)
+
+/* PAS attribute mapping type definitions */
+#define GPT_PAS_ATTR_MAP_TYPE_BLOCK U(0x0)
+#define GPT_PAS_ATTR_MAP_TYPE_GRANULE U(0x1)
+#define GPT_PAS_ATTR_MAP_TYPE_SHIFT U(4)
+#define GPT_PAS_ATTR_MAP_TYPE_MASK U(0x1)
+#define GPT_PAS_ATTR_MAP_TYPE(_attrs) (((_attrs) \
+ >> GPT_PAS_ATTR_MAP_TYPE_SHIFT) \
+ & GPT_PAS_ATTR_MAP_TYPE_MASK)
+
+/*
+ * Macro to initialize the attributes field in the pas_region_t structure.
+ * [31:5] Reserved
+ * [4] Mapping type (GPT_PAS_ATTR_MAP_TYPE_x definitions)
+ * [3:0] PAS GPI type (GPT_GPI_x definitions)
+ */
+#define GPT_PAS_ATTR(_type, _gpi) \
+ ((((_type) & GPT_PAS_ATTR_MAP_TYPE_MASK) \
+ << GPT_PAS_ATTR_MAP_TYPE_SHIFT) | \
+ (((_gpi) & GPT_PAS_ATTR_GPI_MASK) \
+ << GPT_PAS_ATTR_GPI_SHIFT))
+
+/*
+ * Macro to create a GPT entry for this PAS range as a block descriptor. If this
+ * region does not fit the requirements for a block descriptor then GPT
+ * initialization will fail.
+ */
+#define GPT_MAP_REGION_BLOCK(_pa, _sz, _gpi) \
+ { \
+ .base_pa = (_pa), \
+ .size = (_sz), \
+ .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_BLOCK, (_gpi)), \
+ }
+
+/*
+ * Macro to create a GPT entry for this PAS range as a table descriptor. If this
+ * region does not fit the requirements for a table descriptor then GPT
+ * initialization will fail.
+ */
+#define GPT_MAP_REGION_GRANULE(_pa, _sz, _gpi) \
+ { \
+ .base_pa = (_pa), \
+ .size = (_sz), \
+ .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_GRANULE, (_gpi)), \
+ }
+
+/******************************************************************************/
+/* GPT register field definitions */
+/******************************************************************************/
+
+/*
+ * Least significant address bits protected by each entry in level 0 GPT. This
+ * field is read-only.
+ */
+#define GPCCR_L0GPTSZ_SHIFT U(20)
+#define GPCCR_L0GPTSZ_MASK U(0xF)
+
+typedef enum {
+ GPCCR_L0GPTSZ_30BITS = U(0x0),
+ GPCCR_L0GPTSZ_34BITS = U(0x4),
+ GPCCR_L0GPTSZ_36BITS = U(0x6),
+ GPCCR_L0GPTSZ_39BITS = U(0x9)
+} gpccr_l0gptsz_e;
+
+/* Granule protection check priority bit definitions */
+#define GPCCR_GPCP_SHIFT U(17)
+#define GPCCR_GPCP_BIT (ULL(1) << GPCCR_EL3_GPCP_SHIFT)
+
+/* Granule protection check bit definitions */
+#define GPCCR_GPC_SHIFT U(16)
+#define GPCCR_GPC_BIT (ULL(1) << GPCCR_GPC_SHIFT)
+
+/* Physical granule size bit definitions */
+#define GPCCR_PGS_SHIFT U(14)
+#define GPCCR_PGS_MASK U(0x3)
+#define SET_GPCCR_PGS(x) (((x) & GPCCR_PGS_MASK) << GPCCR_PGS_SHIFT)
+
+typedef enum {
+ GPCCR_PGS_4K = U(0x0),
+ GPCCR_PGS_64K = U(0x1),
+ GPCCR_PGS_16K = U(0x2)
+} gpccr_pgs_e;
+
+/* GPT fetch shareability attribute bit definitions */
+#define GPCCR_SH_SHIFT U(12)
+#define GPCCR_SH_MASK U(0x3)
+#define SET_GPCCR_SH(x) (((x) & GPCCR_SH_MASK) << GPCCR_SH_SHIFT)
+
+typedef enum {
+ GPCCR_SH_NS = U(0x0),
+ GPCCR_SH_OS = U(0x2),
+ GPCCR_SH_IS = U(0x3)
+} gpccr_sh_e;
+
+/* GPT fetch outer cacheability attribute bit definitions */
+#define GPCCR_ORGN_SHIFT U(10)
+#define GPCCR_ORGN_MASK U(0x3)
+#define SET_GPCCR_ORGN(x) (((x) & GPCCR_ORGN_MASK) << GPCCR_ORGN_SHIFT)
+
+typedef enum {
+ GPCCR_ORGN_NC = U(0x0),
+ GPCCR_ORGN_WB_RA_WA = U(0x1),
+ GPCCR_ORGN_WT_RA_NWA = U(0x2),
+ GPCCR_ORGN_WB_RA_NWA = U(0x3)
+} gpccr_orgn_e;
+
+/* GPT fetch inner cacheability attribute bit definitions */
+#define GPCCR_IRGN_SHIFT U(8)
+#define GPCCR_IRGN_MASK U(0x3)
+#define SET_GPCCR_IRGN(x) (((x) & GPCCR_IRGN_MASK) << GPCCR_IRGN_SHIFT)
+
+typedef enum {
+ GPCCR_IRGN_NC = U(0x0),
+ GPCCR_IRGN_WB_RA_WA = U(0x1),
+ GPCCR_IRGN_WT_RA_NWA = U(0x2),
+ GPCCR_IRGN_WB_RA_NWA = U(0x3)
+} gpccr_irgn_e;
+
+/* Protected physical address size bit definitions */
+#define GPCCR_PPS_SHIFT U(0)
+#define GPCCR_PPS_MASK U(0x7)
+#define SET_GPCCR_PPS(x) (((x) & GPCCR_PPS_MASK) << GPCCR_PPS_SHIFT)
+
+typedef enum {
+ GPCCR_PPS_4GB = U(0x0),
+ GPCCR_PPS_64GB = U(0x1),
+ GPCCR_PPS_1TB = U(0x2),
+ GPCCR_PPS_4TB = U(0x3),
+ GPCCR_PPS_16TB = U(0x4),
+ GPCCR_PPS_256TB = U(0x5),
+ GPCCR_PPS_4PB = U(0x6)
+} gpccr_pps_e;
+
+/* Base Address for the GPT bit definitions */
+#define GPTBR_BADDR_SHIFT U(0)
+#define GPTBR_BADDR_VAL_SHIFT U(12)
+#define GPTBR_BADDR_MASK ULL(0xffffffffff)
+
+/******************************************************************************/
+/* GPT public APIs */
+/******************************************************************************/
+
+/*
+ * Public API that initializes the entire protected space to GPT_GPI_ANY using
+ * the L0 tables (block descriptors). Ideally, this function is invoked prior
+ * to DDR discovery and initialization. The MMU must be initialized before
+ * calling this function.
+ *
+ * Parameters
+ * pps PPS value to use for table generation
+ * l0_mem_base Base address of L0 tables in memory.
+ * l0_mem_size Total size of memory available for L0 tables.
+ *
+ * Return
+ * Negative Linux error code in the event of a failure, 0 for success.
+ */
+int gpt_init_l0_tables(gpccr_pps_e pps,
+ uintptr_t l0_mem_base,
+ size_t l0_mem_size);
+
+/*
+ * Public API that carves out PAS regions from the L0 tables and builds any L1
+ * tables that are needed. This function ideally is run after DDR discovery and
+ * initialization. The L0 tables must have already been initialized to GPI_ANY
+ * when this function is called.
+ *
+ * Parameters
+ * pgs PGS value to use for table generation.
+ * l1_mem_base Base address of memory used for L1 tables.
+ * l1_mem_size Total size of memory available for L1 tables.
+ * *pas_regions Pointer to PAS regions structure array.
+ * pas_count Total number of PAS regions.
+ *
+ * Return
+ * Negative Linux error code in the event of a failure, 0 for success.
+ */
+int gpt_init_pas_l1_tables(gpccr_pgs_e pgs,
+ uintptr_t l1_mem_base,
+ size_t l1_mem_size,
+ pas_region_t *pas_regions,
+ unsigned int pas_count);
+
+/*
+ * Public API to initialize the runtime gpt_config structure based on the values
+ * present in the GPTBR_EL3 and GPCCR_EL3 registers. GPT initialization
+ * typically happens in a bootloader stage prior to setting up the EL3 runtime
+ * environment for the granule transition service so this function detects the
+ * initialization from a previous stage. Granule protection checks must be
+ * enabled already or this function will return an error.
+ *
+ * Return
+ * Negative Linux error code in the event of a failure, 0 for success.
+ */
+int gpt_runtime_init(void);
+
+/*
+ * Public API to enable granule protection checks once the tables have all been
+ * initialized. This function is called at first initialization and then again
+ * later during warm boots of CPU cores.
+ *
+ * Return
+ * Negative Linux error code in the event of a failure, 0 for success.
+ */
+int gpt_enable(void);
+
+/*
+ * Public API to disable granule protection checks.
+ */
+void gpt_disable(void);
+
+/*
+ * This function is the core of the granule transition service. When a granule
+ * transition request occurs it is routed to this function where the request is
+ * validated then fulfilled if possible.
+ *
+ * TODO: implement support for transitioning multiple granules at once.
+ *
+ * Parameters
+ * base: Base address of the region to transition, must be aligned to granule
+ * size.
+ * size: Size of region to transition, must be aligned to granule size.
+ * src_sec_state: Security state of the caller.
+ * target_pas: Target PAS of the specified memory region.
+ *
+ * Return
+ * Negative Linux error code in the event of a failure, 0 for success.
+ */
+int gpt_transition_pas(uint64_t base,
+ size_t size,
+ unsigned int src_sec_state,
+ unsigned int target_pas);
+
+#endif /* GPT_RME_H */