diff options
author | davidcunado-arm <david.cunado@arm.com> | 2017-10-09 23:09:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-09 23:09:29 +0100 |
commit | 0f49d4968b8a8d1037ce20b7d8372c0055e816d2 (patch) | |
tree | 38a6254d8b466ebc60c8eebb51f17fb606bfb8a3 /include/lib | |
parent | 4d415c11c436e7a74a151a4fdf5cbdd27664e976 (diff) | |
parent | 609c91917f95e5c2c0dcccbfbea6ff32539bf738 (diff) | |
download | platform_external_arm-trusted-firmware-0f49d4968b8a8d1037ce20b7d8372c0055e816d2.tar.gz platform_external_arm-trusted-firmware-0f49d4968b8a8d1037ce20b7d8372c0055e816d2.tar.bz2 platform_external_arm-trusted-firmware-0f49d4968b8a8d1037ce20b7d8372c0055e816d2.zip |
Merge pull request #1117 from antonio-nino-diaz-arm/an/xlat-improvements
Improvements to the translation tables library v2
Diffstat (limited to 'include/lib')
-rw-r--r-- | include/lib/xlat_tables/xlat_tables_defs.h | 17 | ||||
-rw-r--r-- | include/lib/xlat_tables/xlat_tables_v2.h | 84 | ||||
-rw-r--r-- | include/lib/xlat_tables/xlat_tables_v2_helpers.h | 40 |
3 files changed, 119 insertions, 22 deletions
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h index b0f5a04c9..7cb9d37f1 100644 --- a/include/lib/xlat_tables/xlat_tables_defs.h +++ b/include/lib/xlat_tables/xlat_tables_defs.h @@ -89,9 +89,22 @@ * AP[1] bit is ignored by hardware and is * treated as if it is One in EL2/EL3 */ -#define AP_RO (U(0x1) << 5) -#define AP_RW (U(0x0) << 5) +#define AP2_SHIFT U(0x7) +#define AP2_RO U(0x1) +#define AP2_RW U(0x0) +#define AP1_SHIFT U(0x6) +#define AP1_ACCESS_UNPRIVILEGED U(0x1) +#define AP1_NO_ACCESS_UNPRIVILEGED U(0x0) + +/* + * The following definitions must all be passed to the LOWER_ATTRS() macro to + * get the right bitmask. + */ +#define AP_RO (AP2_RO << 5) +#define AP_RW (AP2_RW << 5) +#define AP_ACCESS_UNPRIVILEGED (AP1_ACCESS_UNPRIVILEGED << 4) +#define AP_NO_ACCESS_UNPRIVILEGED (AP1_NO_ACCESS_UNPRIVILEGED << 4) #define NS (U(0x1) << 3) #define ATTR_NON_CACHEABLE_INDEX U(0x2) #define ATTR_DEVICE_INDEX U(0x1) diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 59f0955fe..1a55fba77 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -15,20 +15,36 @@ #include <xlat_mmu_helpers.h> #include <xlat_tables_v2_helpers.h> -/* Helper macro to define entries for mmap_region_t. It creates - * identity mappings for each region. +/* + * Default granularity size for an mmap_region_t. + * Useful when no specific granularity is required. + * + * By default, choose the biggest possible block size allowed by the + * architectural state and granule size in order to minimize the number of page + * tables required for the mapping. */ -#define MAP_REGION_FLAT(adr, sz, attr) MAP_REGION(adr, adr, sz, attr) +#define REGION_DEFAULT_GRANULARITY XLAT_BLOCK_SIZE(MIN_LVL_BLOCK_DESC) + +/* Helper macro to define an mmap_region_t. */ +#define MAP_REGION(_pa, _va, _sz, _attr) \ + _MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, REGION_DEFAULT_GRANULARITY) -/* Helper macro to define entries for mmap_region_t. It allows to - * re-map address mappings from 'pa' to 'va' for each region. +/* Helper macro to define an mmap_region_t with an identity mapping. */ +#define MAP_REGION_FLAT(_adr, _sz, _attr) \ + MAP_REGION(_adr, _adr, _sz, _attr) + +/* + * Helper macro to define an mmap_region_t to map with the desired granularity + * of translation tables. + * + * The granularity value passed to this macro must be a valid block or page + * size. When using a 4KB translation granule, this might be 4KB, 2MB or 1GB. + * Passing REGION_DEFAULT_GRANULARITY is also allowed and means that the library + * is free to choose the granularity for this region. In this case, it is + * equivalent to the MAP_REGION() macro. */ -#define MAP_REGION(_pa, _va, _sz, _attr) { \ - .base_pa = (_pa), \ - .base_va = (_va), \ - .size = (_sz), \ - .attr = (_attr), \ - } +#define MAP_REGION2(_pa, _va, _sz, _attr, _gr) \ + _MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr) /* * Shifts and masks to access fields of an mmap_attr_t @@ -41,6 +57,11 @@ #define MT_SEC_SHIFT U(4) /* Access permissions for instruction execution (EXECUTE/EXECUTE_NEVER) */ #define MT_EXECUTE_SHIFT U(5) +/* + * In the EL1&0 translation regime, mark the region as User (EL0) or + * Privileged (EL1). In the EL3 translation regime this has no effect. + */ +#define MT_USER_SHIFT U(6) /* All other bits are reserved */ /* @@ -73,10 +94,20 @@ typedef enum { */ MT_EXECUTE = U(0) << MT_EXECUTE_SHIFT, MT_EXECUTE_NEVER = U(1) << MT_EXECUTE_SHIFT, + + /* + * When mapping a region at EL0 or EL1, this attribute will be used to + * determine if a User mapping (EL0) will be created or a Privileged + * mapping (EL1). + */ + MT_USER = U(1) << MT_USER_SHIFT, + MT_PRIVILEGED = U(0) << MT_USER_SHIFT, } mmap_attr_t; +/* Compound attributes for most common usages */ #define MT_CODE (MT_MEMORY | MT_RO | MT_EXECUTE) #define MT_RO_DATA (MT_MEMORY | MT_RO | MT_EXECUTE_NEVER) +#define MT_RW_DATA (MT_MEMORY | MT_RW | MT_EXECUTE_NEVER) /* * Structure for specifying a single region of memory. @@ -86,9 +117,19 @@ typedef struct mmap_region { uintptr_t base_va; size_t size; mmap_attr_t attr; + /* Desired granularity. See the MAP_REGION2() macro for more details. */ + size_t granularity; } mmap_region_t; /* + * Translation regimes supported by this library. + */ +typedef enum xlat_regime { + EL1_EL0_REGIME, + EL3_REGIME, +} xlat_regime_t; + +/* * Declare the translation context type. * Its definition is private. */ @@ -123,8 +164,25 @@ typedef struct xlat_ctx xlat_ctx_t; */ #define REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \ _virt_addr_space_size, _phy_addr_space_size) \ - _REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \ - _virt_addr_space_size, _phy_addr_space_size) + _REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \ + _xlat_tables_count, \ + _virt_addr_space_size, \ + _phy_addr_space_size, \ + IMAGE_XLAT_DEFAULT_REGIME) + +/* + * Same as REGISTER_XLAT_CONTEXT plus the additional parameter _xlat_regime to + * specify the translation regime managed by this xlat_ctx_t instance. The + * values are the one from xlat_regime_t enumeration. + */ +#define REGISTER_XLAT_CONTEXT2(_ctx_name, _mmap_count, _xlat_tables_count, \ + _virt_addr_space_size, _phy_addr_space_size, \ + _xlat_regime) \ + _REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \ + _xlat_tables_count, \ + _virt_addr_space_size, \ + _phy_addr_space_size, \ + _xlat_regime) /****************************************************************************** * Generic translation table APIs. diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h index f5e310066..0ebdc9307 100644 --- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h +++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h @@ -27,6 +27,20 @@ /* Forward declaration */ struct mmap_region; +/* + * Helper macro to define an mmap_region_t. This macro allows to specify all + * the fields of the structure but its parameter list is not guaranteed to + * remain stable as we add members to mmap_region_t. + */ +#define _MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr) \ + { \ + .base_pa = (_pa), \ + .base_va = (_va), \ + .size = (_sz), \ + .attr = (_attr), \ + .granularity = (_gr), \ + } + /* Struct that holds all information about the translation tables. */ struct xlat_ctx { /* @@ -85,11 +99,12 @@ struct xlat_ctx { unsigned int initialized; /* - * Bit mask that has to be ORed to the rest of a translation table - * descriptor in order to prohibit execution of code at the exception - * level of this translation context. + * Translation regime managed by this xlat_ctx_t. It takes the values of + * the enumeration xlat_regime_t. The type is "int" to avoid a circular + * dependency on xlat_tables_v2.h, but this member must be treated as + * xlat_regime_t. */ - uint64_t execute_never_mask; + int xlat_regime; }; #if PLAT_XLAT_TABLES_DYNAMIC @@ -106,9 +121,9 @@ struct xlat_ctx { /* do nothing */ #endif /* PLAT_XLAT_TABLES_DYNAMIC */ - -#define _REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \ - _virt_addr_space_size, _phy_addr_space_size) \ +#define _REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, _xlat_tables_count, \ + _virt_addr_space_size, _phy_addr_space_size, \ + _xlat_regime) \ CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size), \ assert_invalid_virtual_addr_space_size_for_##_ctx_name); \ \ @@ -140,12 +155,23 @@ struct xlat_ctx { .tables = _ctx_name##_xlat_tables, \ .tables_num = _xlat_tables_count, \ _REGISTER_DYNMAP_STRUCT(_ctx_name) \ + .xlat_regime = (_xlat_regime), \ .max_pa = 0, \ .max_va = 0, \ .next_table = 0, \ .initialized = 0, \ } + +/* This IMAGE_EL macro must not to be used outside the library */ +#if IMAGE_BL1 || IMAGE_BL31 +# define IMAGE_EL 3 +# define IMAGE_XLAT_DEFAULT_REGIME EL3_REGIME +#else +# define IMAGE_EL 1 +# define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME +#endif + #endif /*__ASSEMBLY__*/ #endif /* __XLAT_TABLES_V2_HELPERS_H__ */ |