diff options
Diffstat (limited to 'include/lib')
-rw-r--r-- | include/lib/aarch32/arch.h | 2 | ||||
-rw-r--r-- | include/lib/aarch32/smcc_helpers.h | 6 | ||||
-rw-r--r-- | include/lib/aarch32/smcc_macros.S | 12 | ||||
-rw-r--r-- | include/lib/aarch64/arch.h | 5 | ||||
-rw-r--r-- | include/lib/aarch64/arch_helpers.h | 20 | ||||
-rw-r--r-- | include/lib/el3_runtime/aarch64/context.h | 19 | ||||
-rw-r--r-- | include/lib/psci/psci.h | 14 | ||||
-rw-r--r-- | include/lib/xlat_tables/xlat_tables_defs.h | 48 | ||||
-rw-r--r-- | include/lib/xlat_tables/xlat_tables_v2.h | 61 | ||||
-rw-r--r-- | include/lib/xlat_tables/xlat_tables_v2_helpers.h | 17 |
10 files changed, 175 insertions, 29 deletions
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h index e2c5f24f4..3846bec4d 100644 --- a/include/lib/aarch32/arch.h +++ b/include/lib/aarch32/arch.h @@ -351,6 +351,8 @@ #define PMCR_N_SHIFT 11 #define PMCR_N_MASK 0x1f #define PMCR_N_BITS (PMCR_N_MASK << PMCR_N_SHIFT) +#define PMCR_LC_BIT (1 << 6) +#define PMCR_DP_BIT (1 << 5) /******************************************************************************* * Definitions of register offsets, fields and macros for CPU system diff --git a/include/lib/aarch32/smcc_helpers.h b/include/lib/aarch32/smcc_helpers.h index 1bc843810..53f1aa4ab 100644 --- a/include/lib/aarch32/smcc_helpers.h +++ b/include/lib/aarch32/smcc_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,7 +21,8 @@ #define SMC_CTX_SP_MON 0x7C #define SMC_CTX_LR_MON 0x80 #define SMC_CTX_SCR 0x84 -#define SMC_CTX_SIZE 0x88 +#define SMC_CTX_PMCR 0x88 +#define SMC_CTX_SIZE 0x8C #ifndef __ASSEMBLY__ #include <cassert.h> @@ -73,6 +74,7 @@ typedef struct smc_ctx { u_register_t sp_mon; u_register_t lr_mon; u_register_t scr; + u_register_t pmcr; } smc_ctx_t; /* diff --git a/include/lib/aarch32/smcc_macros.S b/include/lib/aarch32/smcc_macros.S index 7edf41061..cf26175d6 100644 --- a/include/lib/aarch32/smcc_macros.S +++ b/include/lib/aarch32/smcc_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,6 +13,8 @@ * spsr, lr, sp registers and the `scr` register to the SMC context on entry * due a SMC call. The `lr` of the current mode (monitor) is expected to be * already saved. The `sp` must point to the `smc_ctx_t` to save to. + * Additionally, also save the 'pmcr' register as this is updated whilst + * executing in the secure world. */ .macro smcc_save_gp_mode_regs /* Save r0 - r12 in the SMC context */ @@ -46,6 +48,8 @@ /* lr_mon is already saved by caller */ ldcopr r4, SCR str r4, [sp, #SMC_CTX_SCR] + ldcopr r4, PMCR + str r4, [sp, #SMC_CTX_PMCR] .endm /* @@ -70,6 +74,12 @@ stcopr r1, SCR isb + /* + * Restore the PMCR register. + */ + ldr r1, [r0, #SMC_CTX_PMCR] + stcopr r1, PMCR + /* Restore the banked registers including the current SPSR */ add r1, r0, #SMC_CTX_SP_USR ldm r1!, {r4-r12} diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index bbe1e4f93..997e3a229 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -504,9 +504,14 @@ #define CNTACR_RWPT_SHIFT U(0x5) /* PMCR_EL0 definitions */ +#define PMCR_EL0_RESET_VAL U(0x0) #define PMCR_EL0_N_SHIFT U(11) #define PMCR_EL0_N_MASK U(0x1f) #define PMCR_EL0_N_BITS (PMCR_EL0_N_MASK << PMCR_EL0_N_SHIFT) +#define PMCR_EL0_LC_BIT (U(1) << 6) +#define PMCR_EL0_DP_BIT (U(1) << 5) +#define PMCR_EL0_X_BIT (U(1) << 4) +#define PMCR_EL0_D_BIT (U(1) << 3) /******************************************************************************* * Definitions of MAIR encodings for device and normal memory diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 03110fd5a..9c022ab5e 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -31,11 +31,8 @@ static inline void write_ ## _name(uint64_t v) \ __asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v)); \ } -#define _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _reg_name) \ -static inline void write_ ## _name(const uint64_t v) \ -{ \ - __asm__ volatile ("msr " #_reg_name ", %0" : : "i" (v)); \ -} +#define SYSREG_WRITE_CONST(reg_name, v) \ + __asm__ volatile ("msr " #reg_name ", %0" : : "i" (v)) /* Define read function for system register */ #define DEFINE_SYSREG_READ_FUNC(_name) \ @@ -59,11 +56,6 @@ static inline void write_ ## _name(const uint64_t v) \ #define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name) \ _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) -/* Define write function for special system registers */ -#define DEFINE_SYSREG_WRITE_CONST_FUNC(_name) \ - _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _name) - - /********************************************************************** * Macros to create inline functions for system instructions *********************************************************************/ @@ -171,15 +163,17 @@ void inv_dcache_range(uintptr_t addr, size_t size); void dcsw_op_louis(u_register_t op_type); void dcsw_op_all(u_register_t op_type); +void disable_mmu_el1(void); void disable_mmu_el3(void); +void disable_mmu_icache_el1(void); void disable_mmu_icache_el3(void); /******************************************************************************* * Misc. accessor prototypes ******************************************************************************/ -DEFINE_SYSREG_WRITE_CONST_FUNC(daifset) -DEFINE_SYSREG_WRITE_CONST_FUNC(daifclr) +#define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val) +#define write_daifset(val) SYSREG_WRITE_CONST(daifset, val) DEFINE_SYSREG_READ_FUNC(par_el1) DEFINE_SYSREG_READ_FUNC(id_pfr1_el1) @@ -308,7 +302,7 @@ DEFINE_SYSREG_READ_FUNC(ctr_el0) DEFINE_SYSREG_RW_FUNCS(mdcr_el2) DEFINE_SYSREG_RW_FUNCS(hstr_el2) DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2) -DEFINE_SYSREG_READ_FUNC(pmcr_el0) +DEFINE_SYSREG_RW_FUNCS(pmcr_el0) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index dcbf1c9d4..a89468d49 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -87,22 +87,23 @@ #define CTX_AFSR1_EL1 U(0x98) #define CTX_CONTEXTIDR_EL1 U(0xa0) #define CTX_VBAR_EL1 U(0xa8) +#define CTX_PMCR_EL0 U(0xb0) /* * If the platform is AArch64-only, there is no need to save and restore these * AArch32 registers. */ #if CTX_INCLUDE_AARCH32_REGS -#define CTX_SPSR_ABT U(0xb0) -#define CTX_SPSR_UND U(0xb8) -#define CTX_SPSR_IRQ U(0xc0) -#define CTX_SPSR_FIQ U(0xc8) -#define CTX_DACR32_EL2 U(0xd0) -#define CTX_IFSR32_EL2 U(0xd8) -#define CTX_FP_FPEXC32_EL2 U(0xe0) -#define CTX_TIMER_SYSREGS_OFF U(0xf0) /* Align to the next 16 byte boundary */ +#define CTX_SPSR_ABT U(0xc0) /* Align to the next 16 byte boundary */ +#define CTX_SPSR_UND U(0xc8) +#define CTX_SPSR_IRQ U(0xd0) +#define CTX_SPSR_FIQ U(0xd8) +#define CTX_DACR32_EL2 U(0xe0) +#define CTX_IFSR32_EL2 U(0xe8) +#define CTX_FP_FPEXC32_EL2 U(0xf0) +#define CTX_TIMER_SYSREGS_OFF U(0x100) /* Align to the next 16 byte boundary */ #else -#define CTX_TIMER_SYSREGS_OFF U(0xb0) +#define CTX_TIMER_SYSREGS_OFF U(0xc0) /* Align to the next 16 byte boundary */ #endif /* __CTX_INCLUDE_AARCH32_REGS__ */ /* diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h index 0b44ab2e0..06434f9e5 100644 --- a/include/lib/psci/psci.h +++ b/include/lib/psci/psci.h @@ -65,6 +65,8 @@ #define PSCI_STAT_RESIDENCY_AARCH64 U(0xc4000010) #define PSCI_STAT_COUNT_AARCH32 U(0x84000011) #define PSCI_STAT_COUNT_AARCH64 U(0xc4000011) +#define PSCI_SYSTEM_RESET2_AARCH32 U(0x84000012) +#define PSCI_SYSTEM_RESET2_AARCH64 U(0xc4000012) #define PSCI_MEM_PROTECT U(0x84000013) #define PSCI_MEM_CHK_RANGE_AARCH32 U(0x84000014) #define PSCI_MEM_CHK_RANGE_AARCH64 U(0xc4000014) @@ -149,7 +151,7 @@ * PSCI version ******************************************************************************/ #define PSCI_MAJOR_VER (U(1) << 16) -#define PSCI_MINOR_VER U(0x0) +#define PSCI_MINOR_VER U(0x1) /******************************************************************************* * PSCI error codes @@ -167,6 +169,14 @@ #define PSCI_INVALID_MPIDR ~((u_register_t)0) +/* + * SYSTEM_RESET2 macros + */ +#define PSCI_RESET2_TYPE_VENDOR_SHIFT 31 +#define PSCI_RESET2_TYPE_VENDOR (1U << PSCI_RESET2_TYPE_VENDOR_SHIFT) +#define PSCI_RESET2_TYPE_ARCH (0U << PSCI_RESET2_TYPE_VENDOR_SHIFT) +#define PSCI_RESET2_SYSTEM_WARM_RESET (PSCI_RESET2_TYPE_ARCH | 0) + #ifndef __ASSEMBLY__ #include <stdint.h> @@ -294,6 +304,8 @@ typedef struct plat_psci_ops { int (*mem_protect_chk)(uintptr_t base, u_register_t length); int (*read_mem_protect)(int *val); int (*write_mem_protect)(int val); + int (*system_reset2)(int is_vendor, + int reset_type, u_register_t cookie); } plat_psci_ops_t; /******************************************************************************* diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h index 7cb9d37f1..3a7f2456b 100644 --- a/include/lib/xlat_tables/xlat_tables_defs.h +++ b/include/lib/xlat_tables/xlat_tables_defs.h @@ -24,9 +24,19 @@ #define FOUR_KB_INDEX(x) ((x) >> FOUR_KB_SHIFT) #define INVALID_DESC U(0x0) +/* + * A block descriptor points to a region of memory bigger than the granule size + * (e.g. a 2MB region when the granule size is 4KB). + */ #define BLOCK_DESC U(0x1) /* Table levels 0-2 */ +/* A table descriptor points to the next level of translation table. */ #define TABLE_DESC U(0x3) /* Table levels 0-2 */ +/* + * A page descriptor points to a page, i.e. a memory region whose size is the + * translation granule size (e.g. 4KB). + */ #define PAGE_DESC U(0x3) /* Table level 3 */ + #define DESC_MASK U(0x3) #define FIRST_LEVEL_DESC_N ONE_GB_SHIFT @@ -84,10 +94,22 @@ #define XLAT_BLOCK_MASK(level) (XLAT_BLOCK_SIZE(level) - 1) /* Mask to get the address bits common to a block of a certain table level*/ #define XLAT_ADDR_MASK(level) (~XLAT_BLOCK_MASK(level)) +/* + * Extract from the given virtual address the index into the given lookup level. + * This macro assumes the system is using the 4KB translation granule. + */ +#define XLAT_TABLE_IDX(virtual_addr, level) \ + (((virtual_addr) >> XLAT_ADDR_SHIFT(level)) & ULL(0x1FF)) /* - * AP[1] bit is ignored by hardware and is - * treated as if it is One in EL2/EL3 + * The ARMv8 translation table descriptor format defines AP[2:1] as the Access + * Permissions bits, and does not define an AP[0] bit. + * + * AP[1] is valid only for a stage 1 translation that supports two VA ranges + * (i.e. in the ARMv8A.0 architecture, that is the S-EL1&0 regime). + * + * AP[1] is RES0 for stage 1 translations that support only one VA range + * (e.g. EL3). */ #define AP2_SHIFT U(0x7) #define AP2_RO U(0x1) @@ -122,6 +144,28 @@ #define ATTR_INDEX_GET(attr) (((attr) >> 2) & ATTR_INDEX_MASK) /* + * Shift values for the attributes fields in a block or page descriptor. + * See section D4.3.3 in the ARMv8-A ARM (issue B.a). + */ + +/* Memory attributes index field, AttrIndx[2:0]. */ +#define ATTR_INDEX_SHIFT 2 +/* Non-secure bit, NS. */ +#define NS_SHIFT 5 +/* Shareability field, SH[1:0] */ +#define SHAREABILITY_SHIFT 8 +/* The Access Flag, AF. */ +#define ACCESS_FLAG_SHIFT 10 +/* The not global bit, nG. */ +#define NOT_GLOBAL_SHIFT 11 +/* Contiguous hint bit. */ +#define CONT_HINT_SHIFT 52 +/* Execute-never bits, XN. */ +#define PXN_SHIFT 53 +#define XN_SHIFT 54 +#define UXN_SHIFT XN_SHIFT + +/* * Flags to override default values used to program system registers while * enabling the MMU. */ diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 1a55fba77..73a9c5334 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -251,5 +251,66 @@ int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx, #endif /* PLAT_XLAT_TABLES_DYNAMIC */ +/* + * Change the memory attributes of the memory region starting from a given + * virtual address in a set of translation tables. + * + * This function can only be used after the translation tables have been + * initialized. + * + * The base address of the memory region must be aligned on a page boundary. + * The size of this memory region must be a multiple of a page size. + * The memory region must be already mapped by the given translation tables + * and it must be mapped at the granularity of a page. + * + * Return 0 on success, a negative value on error. + * + * In case of error, the memory attributes remain unchanged and this function + * has no effect. + * + * ctx + * Translation context to work on. + * base_va: + * Virtual address of the 1st page to change the attributes of. + * size: + * Size in bytes of the memory region. + * attr: + * New attributes of the page tables. The attributes that can be changed are + * data access (MT_RO/MT_RW), instruction access (MT_EXECUTE_NEVER/MT_EXECUTE) + * and user/privileged access (MT_USER/MT_PRIVILEGED) in the case of contexts + * that are used in the EL1&0 translation regime. Also, note that this + * function doesn't allow to remap a region as RW and executable, or to remap + * device memory as executable. + * + * NOTE: The caller of this function must be able to write to the translation + * tables, i.e. the memory where they are stored must be mapped with read-write + * access permissions. This function assumes it is the case. If this is not + * the case then this function might trigger a data abort exception. + * + * NOTE2: The caller is responsible for making sure that the targeted + * translation tables are not modified by any other code while this function is + * executing. + */ +int change_mem_attributes(xlat_ctx_t *ctx, uintptr_t base_va, size_t size, + mmap_attr_t attr); + +/* + * Query the memory attributes of a memory page in a set of translation tables. + * + * Return 0 on success, a negative error code on error. + * On success, the attributes are stored into *attributes. + * + * ctx + * Translation context to work on. + * base_va + * Virtual address of the page to get the attributes of. + * There are no alignment restrictions on this address. The attributes of the + * memory page it lies within are returned. + * attributes + * Output parameter where to store the attributes of the targeted memory page. + */ +int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va, + mmap_attr_t *attributes); + #endif /*__ASSEMBLY__*/ #endif /* __XLAT_TABLES_V2_H__ */ diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h index 0ebdc9307..28228c4c6 100644 --- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h +++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h @@ -162,8 +162,12 @@ struct xlat_ctx { .initialized = 0, \ } +#if AARCH64 -/* This IMAGE_EL macro must not to be used outside the library */ +/* + * This IMAGE_EL macro must not to be used outside the library, and it is only + * used in AArch64. + */ #if IMAGE_BL1 || IMAGE_BL31 # define IMAGE_EL 3 # define IMAGE_XLAT_DEFAULT_REGIME EL3_REGIME @@ -172,6 +176,17 @@ struct xlat_ctx { # define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME #endif +#else /* if AARCH32 */ + +/* + * The PL1&0 translation regime in AArch32 behaves like the EL1&0 regime in + * AArch64 except for the XN bits, but we set and unset them at the same time, + * so there's no difference in practice. + */ +#define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME + +#endif /* AARCH64 */ + #endif /*__ASSEMBLY__*/ #endif /* __XLAT_TABLES_V2_HELPERS_H__ */ |