diff options
-rw-r--r-- | drivers/arm/tzc/tzc_dmc620.c | 175 | ||||
-rw-r--r-- | include/drivers/arm/tzc_dmc620.h | 104 | ||||
-rw-r--r-- | include/lib/aarch32/arch.h | 51 | ||||
-rw-r--r-- | include/lib/aarch32/arch_helpers.h | 75 | ||||
-rw-r--r-- | include/lib/aarch64/arch.h | 112 | ||||
-rw-r--r-- | include/lib/aarch64/arch_helpers.h | 37 | ||||
-rw-r--r-- | include/lib/utils_def.h | 1 | ||||
-rw-r--r-- | lib/romlib/Makefile | 3 | ||||
-rwxr-xr-x | lib/romlib/genwrappers.sh | 2 | ||||
-rw-r--r-- | lib/romlib/jmptbl.i | 17 | ||||
-rw-r--r-- | make_helpers/build_macros.mk | 4 | ||||
-rw-r--r-- | plat/allwinner/common/sunxi_bl31_setup.c | 20 | ||||
-rw-r--r-- | plat/allwinner/sun50i_a64/sunxi_power.c | 19 | ||||
-rw-r--r-- | plat/arm/board/sgi575/include/platform_def.h | 7 | ||||
-rw-r--r-- | plat/arm/board/sgi575/platform.mk | 4 | ||||
-rw-r--r-- | plat/arm/board/sgi575/sgi575_security.c | 39 | ||||
-rw-r--r-- | plat/arm/board/sgiclarka/include/platform_def.h | 7 | ||||
-rw-r--r-- | plat/arm/board/sgiclarka/platform.mk | 4 | ||||
-rw-r--r-- | plat/arm/board/sgiclarka/sgiclarka_security.c | 39 | ||||
-rw-r--r-- | plat/arm/common/arm_common.c | 6 | ||||
-rw-r--r-- | plat/arm/css/sgi/sgi-common.mk | 3 | ||||
-rw-r--r-- | plat/arm/css/sgi/sgi_security.c | 15 |
22 files changed, 621 insertions, 123 deletions
diff --git a/drivers/arm/tzc/tzc_dmc620.c b/drivers/arm/tzc/tzc_dmc620.c new file mode 100644 index 00000000..4abd0800 --- /dev/null +++ b/drivers/arm/tzc/tzc_dmc620.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <debug.h> +#include <mmio.h> +#include <tzc_dmc620.h> + +/* Mask to extract bit 31 to 16 */ +#define MASK_31_16 UINT64_C(0x0000ffff0000) +/* Mask to extract bit 47 to 32 */ +#define MASK_47_32 UINT64_C(0xffff00000000) + +/* Helper macro for getting dmc_base addr of a dmc_inst */ +#define DMC_BASE(plat_data, dmc_inst) \ + ((uintptr_t)(plat_data->dmc_base[dmc_inst])) + +/* Pointer to the tzc_dmc620_config_data structure populated by the platform */ +static const tzc_dmc620_config_data_t *g_plat_config_data; + +#if ENABLE_ASSERTIONS +/* + * Helper function to check if the DMC-620 instance is present at the + * base address provided by the platform and also check if at least + * one dmc instance is present. + */ +static void tzc_dmc620_validate_plat_driver_data( + const tzc_dmc620_driver_data_t *plat_driver_data) +{ + uint8_t dmc_inst, dmc_count; + unsigned int dmc_id; + uintptr_t base; + + assert(plat_driver_data != NULL); + + dmc_count = plat_driver_data->dmc_count; + assert(dmc_count > 0U); + + for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) { + base = DMC_BASE(plat_driver_data, dmc_inst); + dmc_id = mmio_read_32(base + DMC620_PERIPHERAL_ID_0); + assert(dmc_id == DMC620_PERIPHERAL_ID_0_VALUE); + } +} +#endif + +/* + * Program a region with region base and region top addresses of all + * DMC-620 instances. + */ +static void tzc_dmc620_configure_region(int region_no, + unsigned long long region_base, + unsigned long long region_top, + unsigned int sec_attr) +{ + uint32_t min_31_00, min_47_32; + uint32_t max_31_00, max_47_32; + uint8_t dmc_inst, dmc_count; + uintptr_t base; + const tzc_dmc620_driver_data_t *plat_driver_data; + + plat_driver_data = g_plat_config_data->plat_drv_data; + assert(plat_driver_data != NULL); + + /* Do range checks on regions. */ + assert((region_no >= 0U) && (region_no <= DMC620_ACC_ADDR_COUNT)); + + /* region_base and (region_top + 1) must be 4KB aligned */ + assert(((region_base | (region_top + 1U)) & (4096U - 1U)) == 0U); + + dmc_count = plat_driver_data->dmc_count; + for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) { + min_31_00 = (region_base & MASK_31_16) | sec_attr; + min_47_32 = (region_base & MASK_47_32) + >> DMC620_ACC_ADDR_WIDTH; + max_31_00 = (region_top & MASK_31_16); + max_47_32 = (region_top & MASK_47_32) + >> DMC620_ACC_ADDR_WIDTH; + + /* Extract the base address of the DMC-620 instance */ + base = DMC_BASE(plat_driver_data, dmc_inst); + /* Configure access address region registers */ + mmio_write_32(base + DMC620_ACC_ADDR_MIN_31_00_NEXT(region_no), + min_31_00); + mmio_write_32(base + DMC620_ACC_ADDR_MIN_47_32_NEXT(region_no), + min_47_32); + mmio_write_32(base + DMC620_ACC_ADDR_MAX_31_00_NEXT(region_no), + max_31_00); + mmio_write_32(base + DMC620_ACC_ADDR_MAX_47_32_NEXT(region_no), + max_47_32); + } +} + +/* + * Set the action value for all the DMC-620 instances. + */ +static void tzc_dmc620_set_action(void) +{ + uint8_t dmc_inst, dmc_count; + uintptr_t base; + const tzc_dmc620_driver_data_t *plat_driver_data; + + plat_driver_data = g_plat_config_data->plat_drv_data; + dmc_count = plat_driver_data->dmc_count; + for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) { + /* Extract the base address of the DMC-620 instance */ + base = DMC_BASE(plat_driver_data, dmc_inst); + /* Switch to READY */ + mmio_write_32(base + DMC620_MEMC_CMD, DMC620_MEMC_CMD_GO); + mmio_write_32(base + DMC620_MEMC_CMD, DMC620_MEMC_CMD_EXECUTE); + } +} + +/* + * Verify whether the DMC-620 configuration is complete by reading back + * configuration registers and comparing it with the configured value. If + * configuration is incomplete, loop till the configured value is reflected in + * the register. + */ +static void tzc_dmc620_verify_complete(void) +{ + uint8_t dmc_inst, dmc_count; + uintptr_t base; + const tzc_dmc620_driver_data_t *plat_driver_data; + + plat_driver_data = g_plat_config_data->plat_drv_data; + dmc_count = plat_driver_data->dmc_count; + for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) { + /* Extract the base address of the DMC-620 instance */ + base = DMC_BASE(plat_driver_data, dmc_inst); + while ((mmio_read_32(base + DMC620_MEMC_STATUS) & + DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO) + continue; + } +} + +/* + * Initialize the DMC-620 TrustZone Controller using the region configuration + * supplied by the platform. The DMC620 controller should be enabled elsewhere + * before invoking this function. + */ +void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data) +{ + int i; + + /* Check if valid pointer is passed */ + assert(plat_config_data != NULL); + + /* + * Check if access address count passed by the platform is less than or + * equal to DMC620's access address count + */ + assert(plat_config_data->acc_addr_count <= DMC620_ACC_ADDR_COUNT); + +#if ENABLE_ASSERTIONS + /* Validates the information passed by platform */ + tzc_dmc620_validate_plat_driver_data(plat_config_data->plat_drv_data); +#endif + + g_plat_config_data = plat_config_data; + + INFO("Configuring DMC-620 TZC settings\n"); + for (i = 0U; i < g_plat_config_data->acc_addr_count; i++) + tzc_dmc620_configure_region(i, + g_plat_config_data->plat_acc_addr_data[i].region_base, + g_plat_config_data->plat_acc_addr_data[i].region_top, + g_plat_config_data->plat_acc_addr_data[i].sec_attr); + + tzc_dmc620_set_action(); + tzc_dmc620_verify_complete(); + INFO("DMC-620 TZC setup completed\n"); +} diff --git a/include/drivers/arm/tzc_dmc620.h b/include/drivers/arm/tzc_dmc620.h new file mode 100644 index 00000000..074bbc12 --- /dev/null +++ b/include/drivers/arm/tzc_dmc620.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TZC_DMC620_H +#define TZC_DMC620_H + +#include <utils_def.h> + +/* DMC-620 memc register offsets */ +#define DMC620_MEMC_STATUS U(0x0000) +#define DMC620_MEMC_CMD U(0x0008) + +/* Mask value to check the status of memc_cmd register */ +#define DMC620_MEMC_CMD_MASK U(0x00000007) + +/* memc_cmd register's action values */ +#define DMC620_MEMC_CMD_GO U(0x00000003) +#define DMC620_MEMC_CMD_EXECUTE U(0x00000004) + +/* Address offsets of access address next region 0 registers */ +#define DMC620_ACC_ADDR_MIN_31_00_NEXT_BASE U(0x0080) +#define DMC620_ACC_ADDR_MIN_47_32_NEXT_BASE U(0x0084) +#define DMC620_ACC_ADDR_MAX_31_00_NEXT_BASE U(0x0088) +#define DMC620_ACC_ADDR_MAX_47_32_NEXT_BASE U(0x008c) + +/* Length of one block of access address next register region */ +#define DMC620_ACC_ADDR_NEXT_SIZE U(0x0010) + +/* Address offsets of access address next registers */ +#define DMC620_ACC_ADDR_MIN_31_00_NEXT(region_no) \ + (DMC620_ACC_ADDR_MIN_31_00_NEXT_BASE + \ + (region_no * DMC620_ACC_ADDR_NEXT_SIZE)) +#define DMC620_ACC_ADDR_MIN_47_32_NEXT(region_no) \ + (DMC620_ACC_ADDR_MIN_47_32_NEXT_BASE + \ + (region_no * DMC620_ACC_ADDR_NEXT_SIZE)) +#define DMC620_ACC_ADDR_MAX_31_00_NEXT(region_no) \ + (DMC620_ACC_ADDR_MAX_31_00_NEXT_BASE + \ + (region_no * DMC620_ACC_ADDR_NEXT_SIZE)) +#define DMC620_ACC_ADDR_MAX_47_32_NEXT(region_no) \ + (DMC620_ACC_ADDR_MAX_47_32_NEXT_BASE + \ + (region_no * DMC620_ACC_ADDR_NEXT_SIZE)) + +/* Number of TZC address regions in DMC-620 */ +#define DMC620_ACC_ADDR_COUNT U(8) +/* Width of access address registers */ +#define DMC620_ACC_ADDR_WIDTH U(32) + +/* Peripheral ID registers offsets */ +#define DMC620_PERIPHERAL_ID_0 U(0x1fe0) + +/* Default values in id registers */ +#define DMC620_PERIPHERAL_ID_0_VALUE U(0x00000054) + +/* Secure access region attributes. */ +#define TZC_DMC620_REGION_NS_RD U(0x00000001) +#define TZC_DMC620_REGION_NS_WR U(0x00000002) +#define TZC_DMC620_REGION_NS_RDWR \ + (TZC_DMC620_REGION_NS_RD | TZC_DMC620_REGION_NS_WR) +#define TZC_DMC620_REGION_S_RD U(0x00000004) +#define TZC_DMC620_REGION_S_WR U(0x00000008) +#define TZC_DMC620_REGION_S_RDWR \ + (TZC_DMC620_REGION_S_RD | TZC_DMC620_REGION_S_WR) +#define TZC_DMC620_REGION_S_NS_RDWR \ + (TZC_DMC620_REGION_NS_RDWR | TZC_DMC620_REGION_S_RDWR) + +/* + * Contains pointer to the base addresses of all the DMC-620 instances. + * 'dmc_count' specifies the number of DMC base addresses contained in the + * array pointed to by dmc_base. + */ +typedef struct tzc_dmc620_driver_data { + const uintptr_t *dmc_base; + const unsigned int dmc_count; +} tzc_dmc620_driver_data_t; + +/* + * Contains region base, region top addresses and corresponding attributes + * for configuring TZC access region registers. + */ +typedef struct tzc_dmc620_acc_addr_data { + const unsigned long long region_base; + const unsigned long long region_top; + const unsigned int sec_attr; +} tzc_dmc620_acc_addr_data_t; + +/* + * Contains platform specific data for configuring TZC region base and + * region top address. 'acc_addr_count' specifies the number of + * valid entries in 'plat_acc_addr_data' array. + */ +typedef struct tzc_dmc620_config_data { + const tzc_dmc620_driver_data_t *plat_drv_data; + const tzc_dmc620_acc_addr_data_t *plat_acc_addr_data; + const uint8_t acc_addr_count; +} tzc_dmc620_config_data_t; + +/* Function prototypes */ +void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data); + +#endif /* TZC_DMC620_H */ + diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h index 38e01bd3..3e5e3fbf 100644 --- a/include/lib/aarch32/arch.h +++ b/include/lib/aarch32/arch.h @@ -33,10 +33,12 @@ #define MPIDR_AFF0_SHIFT U(0) #define MPIDR_AFF1_SHIFT U(8) #define MPIDR_AFF2_SHIFT U(16) +#define MPIDR_AFF_SHIFT(_n) MPIDR_AFF##_n##_SHIFT #define MPIDR_AFFINITY_MASK U(0x00ffffff) #define MPIDR_AFFLVL0 U(0) #define MPIDR_AFFLVL1 U(1) #define MPIDR_AFFLVL2 U(2) +#define MPIDR_AFFLVL(_n) MPIDR_AFFLVL##_n #define MPIDR_AFFLVL0_VAL(mpidr) \ (((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK) @@ -46,6 +48,20 @@ (((mpidr) >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK) #define MPIDR_AFFLVL3_VAL(mpidr) U(0) +#define MPIDR_AFF_ID(mpid, n) \ + (((mpid) >> MPIDR_AFF_SHIFT(n)) & MPIDR_AFFLVL_MASK) + +#define MPID_MASK (MPIDR_MT_MASK |\ + (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)|\ + (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT)|\ + (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)) + +/* + * An invalid MPID. This value can be used by functions that return an MPID to + * indicate an error. + */ +#define INVALID_MPID U(0xFFFFFFFF) + /* * The MPIDR_MAX_AFFLVL count starts from 0. Take care to * add one while using this macro to define array sizes. @@ -127,7 +143,7 @@ #define SDCR_RESET_VAL U(0x0) /* HSCTLR definitions */ -#define HSCTLR_RES1 ((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \ +#define HSCTLR_RES1 ((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \ (U(1) << 22) | (U(1) << 18) | (U(1) << 16) | \ (U(1) << 11) | (U(1) << 4) | (U(1) << 3)) @@ -167,6 +183,7 @@ #define GET_NS_BIT(scr) ((scr) & SCR_NS_BIT) /* HCR definitions */ +#define HCR_TGE_BIT (U(1) << 27) #define HCR_AMO_BIT (U(1) << 5) #define HCR_IMO_BIT (U(1) << 4) #define HCR_FMO_BIT (U(1) << 3) @@ -212,10 +229,9 @@ /* CNTHP_CTL definitions */ #define CNTHP_CTL_RESET_VAL U(0x0) -/* NASCR definitions */ +/* NSACR definitions */ #define NSASEDIS_BIT (U(1) << 15) #define NSTRCDIS_BIT (U(1) << 20) -/* NOTE: correct typo in the definitions */ #define NSACR_CP11_BIT (U(1) << 11) #define NSACR_CP10_BIT (U(1) << 10) #define NSACR_IMP_DEF_MASK (U(0x7) << 16) @@ -262,7 +278,6 @@ /* * TTBCR definitions */ -/* The ARM Trusted Firmware uses the long descriptor format */ #define TTBCR_EAE_BIT (U(1) << 31) #define TTBCR_SH1_NON_SHAREABLE (U(0x0) << 28) @@ -407,14 +422,30 @@ #define CNTACR_RWPT_SHIFT U(0x5) /******************************************************************************* - * Definitions of register offsets in the CNTBaseN Frame of the + * Definitions of register offsets and fields in the CNTBaseN Frame of the * system level implementation of the Generic Timer. ******************************************************************************/ -#define CNTBASE_CNTFRQ U(0x10) +/* Physical Count register. */ +#define CNTPCT_LO U(0x0) +/* Counter Frequency register. */ +#define CNTBASEN_CNTFRQ U(0x10) +/* Physical Timer CompareValue register. */ +#define CNTP_CVAL_LO U(0x20) +/* Physical Timer Control register. */ +#define CNTP_CTL U(0x2c) + +/* Physical timer control register bit fields shifts and masks */ +#define CNTP_CTL_ENABLE_SHIFT 0 +#define CNTP_CTL_IMASK_SHIFT 1 +#define CNTP_CTL_ISTATUS_SHIFT 2 + +#define CNTP_CTL_ENABLE_MASK U(1) +#define CNTP_CTL_IMASK_MASK U(1) +#define CNTP_CTL_ISTATUS_MASK U(1) /* MAIR macros */ -#define MAIR0_ATTR_SET(attr, index) ((attr) << ((index) << 3)) -#define MAIR1_ATTR_SET(attr, index) ((attr) << (((index) - U(3)) << 3)) +#define MAIR0_ATTR_SET(attr, index) ((attr) << ((index) << U(3))) +#define MAIR1_ATTR_SET(attr, index) ((attr) << (((index) - U(3)) << U(3))) /* System register defines The format is: coproc, opt1, CRn, CRm, opt2 */ #define SCR p15, 0, c1, c1, 0 @@ -423,6 +454,7 @@ #define SDCR p15, 0, c1, c3, 1 #define MPIDR p15, 0, c0, c0, 5 #define MIDR p15, 0, c0, c0, 0 +#define HVBAR p15, 4, c12, c0, 0 #define VBAR p15, 0, c12, c0, 0 #define MVBAR p15, 0, c12, c0, 1 #define NSACR p15, 0, c1, c1, 2 @@ -443,6 +475,7 @@ #define TTBR0 p15, 0, c2, c0, 0 #define TTBR1 p15, 0, c2, c0, 1 #define TLBIALL p15, 0, c8, c7, 0 +#define TLBIALLH p15, 4, c8, c7, 0 #define TLBIALLIS p15, 0, c8, c3, 0 #define TLBIMVA p15, 0, c8, c7, 1 #define TLBIMVAA p15, 0, c8, c7, 3 @@ -472,6 +505,7 @@ /* Debug register defines. The format is: coproc, opt1, CRn, CRm, opt2 */ #define HDCR p15, 4, c1, c1, 1 #define PMCR p15, 0, c9, c12, 0 +#define CNTHP_TVAL p15, 4, c14, c2, 0 #define CNTHP_CTL p15, 4, c14, c2, 1 /* AArch32 coproc registers for 32bit MMU descriptor support */ @@ -507,6 +541,7 @@ #define VTTBR_64 p15, 6, c2 #define CNTPCT_64 p15, 0, c14 #define HTTBR_64 p15, 4, c2 +#define CNTHP_CVAL_64 p15, 6, c14 #define PAR_64 p15, 0, c7 /* 64 bit GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRm */ diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h index 03f0e869..7d1944ca 100644 --- a/include/lib/aarch32/arch_helpers.h +++ b/include/lib/aarch32/arch_helpers.h @@ -7,7 +7,7 @@ #ifndef ARCH_HELPERS_H #define ARCH_HELPERS_H -#include <arch.h> /* for additional register definitions */ +#include <arch.h> #include <cdefs.h> #include <stdint.h> #include <string.h> @@ -33,13 +33,8 @@ static inline u_register_t read_ ## _name(void) \ /* * The undocumented %Q and %R extended asm are used to implemented the below - * 64 bit `mrrc` and `mcrr` instructions. It works only on Little Endian - * systems for GCC versions < 4.6. Above GCC 4.6, both Little Endian and - * Big Endian systems generate the right instruction encoding. + * 64 bit `mrrc` and `mcrr` instructions. */ -#if !(__clang__ || __GNUC__ > (4) || __GNUC__ == (4) && __GNUC_MINOR__ >= (6)) -#error "clang or GCC 4.6 or above is required to build AArch32 Trusted Firmware" -#endif #define _DEFINE_COPROCR_WRITE_FUNC_64(_name, coproc, opc1, CRm) \ static inline void write64_## _name(uint64_t v) \ @@ -78,6 +73,10 @@ static inline void write_ ## _name(const u_register_t v) \ #define DEFINE_COPROCR_READ_FUNC(_name, ...) \ _DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__) +/* Define write function for coproc register */ +#define DEFINE_COPROCR_WRITE_FUNC(_name, ...) \ + _DEFINE_COPROCR_WRITE_FUNC(_name, __VA_ARGS__) + /* Define read & write function for coproc register */ #define DEFINE_COPROCR_RW_FUNCS(_name, ...) \ _DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__) \ @@ -87,6 +86,10 @@ static inline void write_ ## _name(const u_register_t v) \ #define DEFINE_COPROCR_READ_FUNC_64(_name, ...) \ _DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__) +/* Define 64 bit write function for coproc register */ +#define DEFINE_COPROCR_WRITE_FUNC_64(_name, ...) \ + _DEFINE_COPROCR_WRITE_FUNC_64(_name, __VA_ARGS__) + /* Define 64 bit read & write function for coproc register */ #define DEFINE_COPROCR_RW_FUNCS_64(_name, ...) \ _DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__) \ @@ -101,30 +104,15 @@ static inline void write_ ## _name(const u_register_t v) \ * Macros to create inline functions for tlbi operations *********************************************************************/ -#if ERRATA_A57_813419 -/* - * Define function for TLBI instruction with type specifier that - * implements the workaround for errata 813419 of Cortex-A57 - */ #define _DEFINE_TLBIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \ static inline void tlbi##_op(void) \ { \ u_register_t v = 0; \ __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\ - __asm__ volatile ("dsb ish");\ - __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\ } -#define _DEFINE_TLBIOP_PARAM_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \ -static inline void tlbi##_op(u_register_t v) \ -{ \ - __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\ - __asm__ volatile ("dsb ish");\ - __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\ -} -#else -#define _DEFINE_TLBIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \ -static inline void tlbi##_op(void) \ +#define _DEFINE_BPIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \ +static inline void bpi##_op(void) \ { \ u_register_t v = 0; \ __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\ @@ -135,14 +123,6 @@ static inline void tlbi##_op(u_register_t v) \ { \ __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\ } -#endif /* ERRATA_A57_813419 */ - -#define _DEFINE_BPIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \ -static inline void bpi##_op(void) \ -{ \ - u_register_t v = 0; \ - __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\ -} /* Define function for simple TLBI operation */ #define DEFINE_TLBIOP_FUNC(_op, ...) \ @@ -250,10 +230,13 @@ DEFINE_COPROCR_RW_FUNCS(cntfrq, CNTFRQ) DEFINE_COPROCR_RW_FUNCS(cnthctl, CNTHCTL) DEFINE_COPROCR_RW_FUNCS(mair0, MAIR0) DEFINE_COPROCR_RW_FUNCS(mair1, MAIR1) +DEFINE_COPROCR_RW_FUNCS(hmair0, HMAIR0) DEFINE_COPROCR_RW_FUNCS(ttbcr, TTBCR) +DEFINE_COPROCR_RW_FUNCS(htcr, HTCR) DEFINE_COPROCR_RW_FUNCS(ttbr0, TTBR0) DEFINE_COPROCR_RW_FUNCS_64(ttbr0, TTBR0_64) DEFINE_COPROCR_RW_FUNCS(ttbr1, TTBR1) +DEFINE_COPROCR_RW_FUNCS_64(httbr, HTTBR_64) DEFINE_COPROCR_RW_FUNCS(vpidr, VPIDR) DEFINE_COPROCR_RW_FUNCS(vmpidr, VMPIDR) DEFINE_COPROCR_RW_FUNCS_64(vttbr, VTTBR_64) @@ -261,6 +244,9 @@ DEFINE_COPROCR_RW_FUNCS_64(ttbr1, TTBR1_64) DEFINE_COPROCR_RW_FUNCS_64(cntvoff, CNTVOFF_64) DEFINE_COPROCR_RW_FUNCS(csselr, CSSELR) DEFINE_COPROCR_RW_FUNCS(hstr, HSTR) +DEFINE_COPROCR_RW_FUNCS(cnthp_ctl_el2, CNTHP_CTL) +DEFINE_COPROCR_RW_FUNCS(cnthp_tval_el2, CNTHP_TVAL) +DEFINE_COPROCR_RW_FUNCS_64(cnthp_cval_el2, CNTHP_CVAL_64) DEFINE_COPROCR_RW_FUNCS(icc_sre_el1, ICC_SRE) DEFINE_COPROCR_RW_FUNCS(icc_sre_el2, ICC_HSRE) @@ -268,6 +254,7 @@ DEFINE_COPROCR_RW_FUNCS(icc_sre_el3, ICC_MSRE) DEFINE_COPROCR_RW_FUNCS(icc_pmr_el1, ICC_PMR) DEFINE_COPROCR_RW_FUNCS(icc_rpr_el1, ICC_RPR) DEFINE_COPROCR_RW_FUNCS(icc_igrpen1_el3, ICC_MGRPEN1) +DEFINE_COPROCR_RW_FUNCS(icc_igrpen1_el1, ICC_IGRPEN1) DEFINE_COPROCR_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0) DEFINE_COPROCR_RW_FUNCS(icc_hppir0_el1, ICC_HPPIR0) DEFINE_COPROCR_RW_FUNCS(icc_hppir1_el1, ICC_HPPIR1) @@ -276,13 +263,17 @@ DEFINE_COPROCR_RW_FUNCS(icc_iar1_el1, ICC_IAR1) DEFINE_COPROCR_RW_FUNCS(icc_eoir0_el1, ICC_EOIR0) DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1) DEFINE_COPROCR_RW_FUNCS_64(icc_sgi0r_el1, ICC_SGI0R_EL1_64) +DEFINE_COPROCR_WRITE_FUNC_64(icc_sgi1r, ICC_SGI1R_EL1_64) DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR) DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL) DEFINE_COPROCR_READ_FUNC(pmcr, PMCR) -DEFINE_COPROCR_RW_FUNCS(ats1cpr, ATS1CPR) -DEFINE_COPROCR_RW_FUNCS(ats1hr, ATS1HR) +/* + * Address translation + */ +DEFINE_COPROCR_WRITE_FUNC(ats1cpr, ATS1CPR) +DEFINE_COPROCR_WRITE_FUNC(ats1hr, ATS1HR) DEFINE_COPROCR_RW_FUNCS_64(par, PAR_64) DEFINE_COPROCR_RW_FUNCS(nsacr, NSACR) @@ -340,9 +331,7 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC) #define IS_IN_SVC() (GET_M32(read_cpsr()) == MODE32_svc) #define IS_IN_MON() (GET_M32(read_cpsr()) == MODE32_mon) #define IS_IN_EL2() IS_IN_HYP() - /* - * If EL3 is AArch32, then secure PL1 and monitor mode correspond to EL3 - */ +/* If EL3 is AArch32, then secure PL1 and monitor mode correspond to EL3 */ #define IS_IN_EL3() \ ((GET_M32(read_cpsr()) == MODE32_mon) || \ (IS_IN_SECURE() && (GET_M32(read_cpsr()) != MODE32_usr))) @@ -378,7 +367,15 @@ static inline unsigned int get_current_el(void) #define read_ctr_el0() read_ctr() -#define write_icc_sgi0r_el1(_v) \ - write64_icc_sgi0r_el1(_v) +#define write_icc_sgi0r_el1(_v) write64_icc_sgi0r_el1(_v) + +#define read_daif() read_cpsr() +#define write_daif(flags) write_cpsr(flags) + +#define read_cnthp_cval_el2() read64_cnthp_cval_el2() +#define write_cnthp_cval_el2(v) write64_cnthp_cval_el2(v) + +#define read_amcntenset0_el0() read_amcntenset0() +#define read_amcntenset1_el0() read_amcntenset1() #endif /* ARCH_HELPERS_H */ diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index e6842e14..d7867bcd 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -35,12 +35,14 @@ #define MPIDR_AFF1_SHIFT U(8) #define MPIDR_AFF2_SHIFT U(16) #define MPIDR_AFF3_SHIFT U(32) +#define MPIDR_AFF_SHIFT(_n) MPIDR_AFF##_n##_SHIFT #define MPIDR_AFFINITY_MASK ULL(0xff00ffffff) #define MPIDR_AFFLVL_SHIFT U(3) -#define MPIDR_AFFLVL0 U(0x0) -#define MPIDR_AFFLVL1 U(0x1) -#define MPIDR_AFFLVL2 U(0x2) -#define MPIDR_AFFLVL3 U(0x3) +#define MPIDR_AFFLVL0 ULL(0x0) +#define MPIDR_AFFLVL1 ULL(0x1) +#define MPIDR_AFFLVL2 ULL(0x2) +#define MPIDR_AFFLVL3 ULL(0x3) +#define MPIDR_AFFLVL(_n) MPIDR_AFFLVL##_n #define MPIDR_AFFLVL0_VAL(mpidr) \ (((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK) #define MPIDR_AFFLVL1_VAL(mpidr) \ @@ -56,28 +58,42 @@ */ #define MPIDR_MAX_AFFLVL U(2) -/* Constant to highlight the assumption that MPIDR allocation starts from 0 */ -#define FIRST_MPIDR ULL(0) +#define MPID_MASK (MPIDR_MT_MASK | \ + (MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT) | \ + (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT) | \ + (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) | \ + (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)) + +#define MPIDR_AFF_ID(mpid, n) \ + (((mpid) >> MPIDR_AFF_SHIFT(n)) & MPIDR_AFFLVL_MASK) + +/* + * An invalid MPID. This value can be used by functions that return an MPID to + * indicate an error. + */ +#define INVALID_MPID U(0xFFFFFFFF) /******************************************************************************* * Definitions for CPU system register interface to GICv3 ******************************************************************************/ -#define ICC_SRE_EL1 S3_0_C12_C12_5 -#define ICC_SRE_EL2 S3_4_C12_C9_5 -#define ICC_SRE_EL3 S3_6_C12_C12_5 -#define ICC_CTLR_EL1 S3_0_C12_C12_4 -#define ICC_CTLR_EL3 S3_6_C12_C12_4 -#define ICC_PMR_EL1 S3_0_C4_C6_0 -#define ICC_RPR_EL1 S3_0_C12_C11_3 -#define ICC_IGRPEN1_EL3 S3_6_c12_c12_7 -#define ICC_IGRPEN0_EL1 S3_0_c12_c12_6 -#define ICC_HPPIR0_EL1 S3_0_c12_c8_2 -#define ICC_HPPIR1_EL1 S3_0_c12_c12_2 -#define ICC_IAR0_EL1 S3_0_c12_c8_0 -#define ICC_IAR1_EL1 S3_0_c12_c12_0 -#define ICC_EOIR0_EL1 S3_0_c12_c8_1 -#define ICC_EOIR1_EL1 S3_0_c12_c12_1 -#define ICC_SGI0R_EL1 S3_0_c12_c11_7 +#define ICC_IGRPEN1_EL1 S3_0_C12_C12_7 +#define ICC_SGI1R S3_0_C12_C11_5 +#define ICC_SRE_EL1 S3_0_C12_C12_5 +#define ICC_SRE_EL2 S3_4_C12_C9_5 +#define ICC_SRE_EL3 S3_6_C12_C12_5 +#define ICC_CTLR_EL1 S3_0_C12_C12_4 +#define ICC_CTLR_EL3 S3_6_C12_C12_4 +#define ICC_PMR_EL1 S3_0_C4_C6_0 +#define ICC_RPR_EL1 S3_0_C12_C11_3 +#define ICC_IGRPEN1_EL3 S3_6_c12_c12_7 +#define ICC_IGRPEN0_EL1 S3_0_c12_c12_6 +#define ICC_HPPIR0_EL1 S3_0_c12_c8_2 +#define ICC_HPPIR1_EL1 S3_0_c12_c12_2 +#define ICC_IAR0_EL1 S3_0_c12_c8_0 +#define ICC_IAR1_EL1 S3_0_c12_c12_0 +#define ICC_EOIR0_EL1 S3_0_c12_c8_1 +#define ICC_EOIR1_EL1 S3_0_c12_c12_1 +#define ICC_SGI0R_EL1 S3_0_c12_c11_7 /******************************************************************************* * Generic timer memory mapped registers & offsets @@ -140,6 +156,25 @@ #define ID_AA64MMFR0_EL1_PARANGE_SHIFT U(0) #define ID_AA64MMFR0_EL1_PARANGE_MASK ULL(0xf) +/* ID_AA64ISAR1_EL1 definitions */ +#define ID_AA64ISAR1_GPI_SHIFT U(28) +#define ID_AA64ISAR1_GPI_WIDTH U(4) +#define ID_AA64ISAR1_GPA_SHIFT U(24) +#define ID_AA64ISAR1_GPA_WIDTH U(4) +#define ID_AA64ISAR1_API_SHIFT U(8) +#define ID_AA64ISAR1_API_WIDTH U(4) +#define ID_AA64ISAR1_APA_SHIFT U(4) +#define ID_AA64ISAR1_APA_WIDTH U(4) + +#define ID_AA64ISAR1_GPI_MASK \ + (((ULL(1) << ID_AA64ISAR1_GPI_WIDTH) - ULL(1)) << ID_AA64ISAR1_GPI_SHIFT) +#define ID_AA64ISAR1_GPA_MASK \ + (((ULL(1) << ID_AA64ISAR1_GPA_WIDTH) - ULL(1)) << ID_AA64ISAR1_GPA_SHIFT) +#define ID_AA64ISAR1_API_MASK \ + (((ULL(1) << ID_AA64ISAR1_API_WIDTH) - ULL(1)) << ID_AA64ISAR1_API_SHIFT) +#define ID_AA64ISAR1_APA_MASK \ + (((ULL(1) << ID_AA64ISAR1_APA_WIDTH) - ULL(1)) << ID_AA64ISAR1_APA_SHIFT) + #define PARANGE_0000 U(32) #define PARANGE_0001 U(36) #define PARANGE_0010 U(40) @@ -278,6 +313,7 @@ /* HCR definitions */ #define HCR_API_BIT (ULL(1) << 41) #define HCR_APK_BIT (ULL(1) << 40) +#define HCR_TGE_BIT (ULL(1) << 27) #define HCR_RW_SHIFT U(31) #define HCR_RW_BIT (ULL(1) << HCR_RW_SHIFT) #define HCR_AMO_BIT (ULL(1) << 5) @@ -351,6 +387,8 @@ #define DISABLE_ALL_EXCEPTIONS \ (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT) +#define DISABLE_INTERRUPTS (DAIF_FIQ_BIT | DAIF_IRQ_BIT) + /* * RMR_EL3 definitions */ @@ -360,12 +398,12 @@ /* * HI-VECTOR address for AArch32 state */ -#define HI_VECTOR_BASE U(0xFFFF0000) +#define HI_VECTOR_BASE U(0xFFFF0000) /* * TCR defintions */ -#define TCR_EL3_RES1 ((U(1) << 31) | (U(1) << 23)) +#define TCR_EL3_RES1 ((ULL(1) << 31) | (ULL(1) << 23)) #define TCR_EL2_RES1 ((ULL(1) << 31) | (ULL(1) << 23)) #define TCR_EL1_IPS_SHIFT U(32) #define TCR_EL2_PS_SHIFT U(16) @@ -571,10 +609,17 @@ #define CNTACR_RWPT_SHIFT U(0x5) /******************************************************************************* - * Definitions of register offsets in the CNTBaseN Frame of the + * Definitions of register offsets and fields in the CNTBaseN Frame of the * system level implementation of the Generic Timer. ******************************************************************************/ -#define CNTBASE_CNTFRQ U(0x10) +/* Physical Count register. */ +#define CNTPCT_LO U(0x0) +/* Counter Frequency register. */ +#define CNTBASEN_CNTFRQ U(0x10) +/* Physical Timer CompareValue register. */ +#define CNTP_CVAL_LO U(0x20) +/* Physical Timer Control register. */ +#define CNTP_CTL U(0x2c) /* PMCR_EL0 definitions */ #define PMCR_EL0_RESET_VAL U(0x0) @@ -753,7 +798,22 @@ #define ERXCTLR_EL1 S3_0_C5_C4_1 #define ERXSTATUS_EL1 S3_0_C5_C4_2 #define ERXADDR_EL1 S3_0_C5_C4_3 +#define ERXPFGF_EL1 S3_0_C5_C4_4 +#define ERXPFGCTL_EL1 S3_0_C5_C4_5 +#define ERXPFGCDN_EL1 S3_0_C5_C4_6 #define ERXMISC0_EL1 S3_0_C5_C5_0 #define ERXMISC1_EL1 S3_0_C5_C5_1 +#define ERXCTLR_ED_BIT (U(1) << 0) +#define ERXCTLR_UE_BIT (U(1) << 4) + +#define ERXPFGCTL_UC_BIT (U(1) << 1) +#define ERXPFGCTL_UEU_BIT (U(1) << 2) +#define ERXPFGCTL_CDEN_BIT (U(1) << 31) + +/******************************************************************************* + * Armv8.3 Pointer Authentication Registers + *******************************************************************************/ +#define APGAKeyLo_EL1 S3_0_C2_C3_0 + #endif /* ARCH_H */ diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 61f9830d..8b3d53a4 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -7,8 +7,8 @@ #ifndef ARCH_HELPERS_H #define ARCH_HELPERS_H -#include <arch.h> /* for additional register definitions */ -#include <cdefs.h> /* For __dead2 */ +#include <arch.h> +#include <cdefs.h> #include <stdbool.h> #include <stdint.h> #include <string.h> @@ -179,11 +179,13 @@ void disable_mmu_icache_el3(void); #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_RW_FUNCS(par_el1) DEFINE_SYSREG_READ_FUNC(id_pfr1_el1) +DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1) DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1) DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1) DEFINE_SYSREG_READ_FUNC(CurrentEl) +DEFINE_SYSREG_READ_FUNC(ctr_el0) DEFINE_SYSREG_RW_FUNCS(daif) DEFINE_SYSREG_RW_FUNCS(spsr_el1) DEFINE_SYSREG_RW_FUNCS(spsr_el2) @@ -202,14 +204,20 @@ DEFINE_SYSOP_TYPE_FUNC(dmb, ld) DEFINE_SYSOP_TYPE_FUNC(dsb, ish) DEFINE_SYSOP_TYPE_FUNC(dsb, nsh) DEFINE_SYSOP_TYPE_FUNC(dsb, ishst) -DEFINE_SYSOP_TYPE_FUNC(dmb, ish) +DEFINE_SYSOP_TYPE_FUNC(dmb, oshld) +DEFINE_SYSOP_TYPE_FUNC(dmb, oshst) +DEFINE_SYSOP_TYPE_FUNC(dmb, osh) +DEFINE_SYSOP_TYPE_FUNC(dmb, nshld) +DEFINE_SYSOP_TYPE_FUNC(dmb, nshst) +DEFINE_SYSOP_TYPE_FUNC(dmb, nsh) +DEFINE_SYSOP_TYPE_FUNC(dmb, ishld) DEFINE_SYSOP_TYPE_FUNC(dmb, ishst) +DEFINE_SYSOP_TYPE_FUNC(dmb, ish) DEFINE_SYSOP_FUNC(isb) uint32_t get_afflvl_shift(uint32_t); uint32_t mpidr_mask_lower_afflvls(uint64_t, uint32_t); - void __dead2 eret(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7); void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, @@ -286,9 +294,15 @@ DEFINE_SYSREG_RW_FUNCS(cptr_el3) DEFINE_SYSREG_RW_FUNCS(cpacr_el1) DEFINE_SYSREG_RW_FUNCS(cntfrq_el0) +DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2) +DEFINE_SYSREG_RW_FUNCS(cnthp_tval_el2) +DEFINE_SYSREG_RW_FUNCS(cnthp_cval_el2) DEFINE_SYSREG_RW_FUNCS(cntps_ctl_el1) DEFINE_SYSREG_RW_FUNCS(cntps_tval_el1) DEFINE_SYSREG_RW_FUNCS(cntps_cval_el1) +DEFINE_SYSREG_RW_FUNCS(cntp_ctl_el0) +DEFINE_SYSREG_RW_FUNCS(cntp_tval_el0) +DEFINE_SYSREG_RW_FUNCS(cntp_cval_el0) DEFINE_SYSREG_READ_FUNC(cntpct_el0) DEFINE_SYSREG_RW_FUNCS(cnthctl_el2) @@ -298,24 +312,23 @@ DEFINE_SYSREG_RW_FUNCS(cntvoff_el2) DEFINE_SYSREG_RW_FUNCS(vpidr_el2) DEFINE_SYSREG_RW_FUNCS(vmpidr_el2) -DEFINE_SYSREG_RW_FUNCS(cntp_ctl_el0) DEFINE_SYSREG_READ_FUNC(isr_el1) -DEFINE_SYSREG_READ_FUNC(ctr_el0) - DEFINE_SYSREG_RW_FUNCS(mdcr_el2) DEFINE_SYSREG_RW_FUNCS(mdcr_el3) DEFINE_SYSREG_RW_FUNCS(hstr_el2) -DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2) DEFINE_SYSREG_RW_FUNCS(pmcr_el0) +/* GICv3 System Registers */ + DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(icc_rpr_el1, ICC_RPR_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el3, ICC_IGRPEN1_EL3) +DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el1, ICC_IGRPEN1_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir0_el1, ICC_HPPIR0_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir1_el1, ICC_HPPIR1_EL1) @@ -324,6 +337,7 @@ DEFINE_RENAME_SYSREG_READ_FUNC(icc_iar1_el1, ICC_IAR1_EL1) DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir0_el1, ICC_EOIR0_EL1) DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1) DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1) +DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sgi1r, ICC_SGI1R) DEFINE_RENAME_SYSREG_RW_FUNCS(amcgcr_el0, AMCGCR_EL0) DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr0_el0, AMCNTENCLR0_EL0) @@ -351,11 +365,14 @@ DEFINE_RENAME_SYSREG_READ_FUNC(erxaddr_el1, ERXADDR_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1) +/* Armv8.3 Pointer Authentication Registers */ +DEFINE_RENAME_SYSREG_RW_FUNCS(apgakeylo_el1, APGAKeyLo_EL1) + #define IS_IN_EL(x) \ (GET_EL(read_CurrentEl()) == MODE_EL##x) #define IS_IN_EL1() IS_IN_EL(1) -#define IS_IN_EL3() IS_IN_EL(3) +#define IS_IN_EL2() IS_IN_EL(2) #define IS_IN_EL3() IS_IN_EL(3) static inline unsigned int get_current_el(void) diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h index fa13caa6..02963ac5 100644 --- a/include/lib/utils_def.h +++ b/include/lib/utils_def.h @@ -160,5 +160,6 @@ */ #define ASSERT_SYM_PTR_ALIGN(sym) assert(((size_t)(sym) % __alignof__(*(sym))) == 0) +#define COMPILER_BARRIER() __asm__ volatile ("" ::: "memory") #endif /* UTILS_DEF_H */ diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile index 46b92068..00dde31c 100644 --- a/lib/romlib/Makefile +++ b/lib/romlib/Makefile @@ -15,6 +15,7 @@ LIBS = -lmbedtls -lfdt -lc INC = $(INCLUDES:-I%=-I../../%) PPFLAGS = $(INC) $(DEFINES) -P -D__ASSEMBLY__ -D__LINKER__ -MD -MP -MT $(BUILD_DIR)/romlib.ld OBJS = $(BUILD_DIR)/jmptbl.o $(BUILD_DIR)/init.o +MAPFILE = ../../$(BUILD_PLAT)/romlib/romlib.map V ?= 0 ifeq ($(V),0) @@ -25,7 +26,7 @@ endif ifeq ($(DEBUG),1) CFLAGS := -g - LDFLAGS := -g + LDFLAGS := -g --gc-sections -O1 -Map=$(MAPFILE) endif diff --git a/lib/romlib/genwrappers.sh b/lib/romlib/genwrappers.sh index bcf670b9..48ee5a43 100755 --- a/lib/romlib/genwrappers.sh +++ b/lib/romlib/genwrappers.sh @@ -31,7 +31,7 @@ do done awk '{sub(/[:blank:]*#.*/,"")} -!/^$/ {print $1*4, $2, $3}' "$@" | +!/^$/ && !/\\tpatch$/ {print $1*4, $2, $3}' "$@" | while read idx lib sym do file=$build/${lib}_$sym diff --git a/lib/romlib/jmptbl.i b/lib/romlib/jmptbl.i index 338cd8a7..5eca5aab 100644 --- a/lib/romlib/jmptbl.i +++ b/lib/romlib/jmptbl.i @@ -3,6 +3,10 @@ # # SPDX-License-Identifier: BSD-3-Clause # +# Format: +# index lib function [patch] +# Add "patch" at the end of the line to patch a function. For example: +# 14 mbedtls mbedtls_memory_buffer_alloc_init patch 0 rom rom_lib_init 1 fdt fdt_getprop_namelen @@ -27,9 +31,10 @@ 20 mbedtls mbedtls_pk_init 21 mbedtls mbedtls_pk_parse_subpubkey 22 mbedtls mbedtls_pk_verify_ext -23 mbedtls mbedtls_platform_set_snprintf -24 mbedtls mbedtls_x509_get_rsassa_pss_params -25 mbedtls mbedtls_x509_get_sig_alg -26 mbedtls mbedtls_md_info_from_type -27 c exit -28 c atexit +23 mbedtls mbedtls_platform_set_calloc_free +24 mbedtls mbedtls_platform_set_snprintf +25 mbedtls mbedtls_x509_get_rsassa_pss_params +26 mbedtls mbedtls_x509_get_sig_alg +27 mbedtls mbedtls_md_info_from_type +28 c exit +29 c atexit
\ No newline at end of file diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index e186fc10..d60a5bf0 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -338,7 +338,7 @@ LDPATHS = -L${LIB_DIR} LDLIBS += -l$(1) ifeq ($(USE_ROMLIB),1) -LDLIBS := -lwrappers -lc +LIBWRAPPER = -lwrappers endif all: ${LIB_DIR}/lib$(1).a @@ -402,7 +402,7 @@ else endif $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Map=$(MAPFILE) \ --script $(LINKERFILE) $(BUILD_DIR)/build_message.o \ - $(OBJS) $(LDPATHS) $(LDLIBS) $(BL_LIBS) + $(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) $(DUMP): $(ELF) $${ECHO} " OD $$@" diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c index 8f597c39..2c663291 100644 --- a/plat/allwinner/common/sunxi_bl31_setup.c +++ b/plat/allwinner/common/sunxi_bl31_setup.c @@ -11,6 +11,7 @@ #include <generic_delay_timer.h> #include <gicv2.h> #include <libfdt.h> +#include <mmio.h> #include <platform.h> #include <platform_def.h> #include <sunxi_def.h> @@ -148,6 +149,25 @@ void bl31_platform_setup(void) sunxi_security_setup(); + /* + * On the A64 U-Boot's SPL sets the bus clocks to some conservative + * values, to work around FEL mode instabilities with SRAM C accesses. + * FEL mode is gone when we reach ATF, so bring the AHB1 bus + * (the "main" bus) clock frequency back to the recommended 200MHz, + * for improved performance. + */ + if (soc_id == SUNXI_SOC_A64) + mmio_write_32(SUNXI_CCU_BASE + 0x54, 0x00003180); + + /* + * U-Boot or the kernel don't setup AHB2, which leaves it at the + * AHB1 frequency (200 MHz, see above). However Allwinner recommends + * 300 MHz, for improved Ethernet and USB performance. Switch the + * clock to use "PLL_PERIPH0 / 2". + */ + if (soc_id == SUNXI_SOC_A64 || soc_id == SUNXI_SOC_H5) + mmio_write_32(SUNXI_CCU_BASE + 0x5c, 0x1); + sunxi_pmic_setup(soc_id, fdt); INFO("BL31: Platform setup done\n"); diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c index af304773..59feed78 100644 --- a/plat/allwinner/sun50i_a64/sunxi_power.c +++ b/plat/allwinner/sun50i_a64/sunxi_power.c @@ -118,7 +118,7 @@ static int axp_write(uint8_t reg, uint8_t val) return rsb_write(AXP803_RT_ADDR, reg, val); } -static int axp_setbits(uint8_t reg, uint8_t set_mask) +static int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask) { uint8_t regval; int ret; @@ -127,11 +127,14 @@ static int axp_setbits(uint8_t reg, uint8_t set_mask) if (ret < 0) return ret; - regval = ret | set_mask; + regval = (ret & ~clr_mask) | set_mask; return rsb_write(AXP803_RT_ADDR, reg, regval); } +#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0) +#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask) + static bool should_enable_regulator(const void *fdt, int node) { if (fdt_getprop(fdt, node, "phandle", NULL) != NULL) @@ -178,8 +181,9 @@ struct axp_regulator { unsigned char switch_reg; unsigned char switch_bit; } regulators[] = { - {"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0xff, 9}, - {"dcdc5", 800, 1840, 10, 32, 0x24, 0xff, 9}, + {"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0x10, 0}, + {"dcdc5", 800, 1840, 10, 32, 0x24, 0x10, 4}, + {"dcdc6", 600, 1520, 10, 50, 0x25, 0x10, 5}, {"dldo1", 700, 3300, 100, NO_SPLIT, 0x15, 0x12, 3}, {"dldo2", 700, 4200, 100, 27, 0x16, 0x12, 4}, {"dldo3", 700, 3300, 100, NO_SPLIT, 0x17, 0x12, 5}, @@ -226,8 +230,11 @@ static void setup_axp803_rails(const void *fdt) return; } - if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) - axp_setbits(0x8f, BIT(4)); + if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) { + axp_clrbits(0x8f, BIT(4)); + axp_setbits(0x30, BIT(2)); + INFO("PMIC: AXP803: Enabling DRIVEVBUS\n"); + } /* descend into the "regulators" subnode */ node = fdt_first_subnode(fdt, node); diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h index 1870fc78..c06a0a1f 100644 --- a/plat/arm/board/sgi575/include/platform_def.h +++ b/plat/arm/board/sgi575/include/platform_def.h @@ -8,11 +8,16 @@ #define PLATFORM_DEF_H #include <sgi_base_platform_def.h> +#include <utils_def.h> #define PLAT_ARM_CLUSTER_COUNT 2 #define CSS_SGI_MAX_CPUS_PER_CLUSTER 4 #define CSS_SGI_MAX_PE_PER_CPU 1 -#define PLAT_CSS_MHU_BASE 0x45000000 +#define PLAT_CSS_MHU_BASE UL(0x45000000) + +/* Base address of DMC-620 instances */ +#define SGI575_DMC620_BASE0 UL(0x4e000000) +#define SGI575_DMC620_BASE1 UL(0x4e100000) #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index 8df8b129..dd82d297 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -14,7 +14,9 @@ SGI_CPU_SOURCES := lib/cpus/aarch64/cortex_a75.S BL1_SOURCES += ${SGI_CPU_SOURCES} -BL2_SOURCES += lib/utils/mem_region.c \ +BL2_SOURCES += ${SGI575_BASE}/sgi575_security.c \ + drivers/arm/tzc/tzc_dmc620.c \ + lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c BL31_SOURCES += ${SGI_CPU_SOURCES} \ diff --git a/plat/arm/board/sgi575/sgi575_security.c b/plat/arm/board/sgi575/sgi575_security.c new file mode 100644 index 00000000..7ccc59a7 --- /dev/null +++ b/plat/arm/board/sgi575/sgi575_security.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <debug.h> +#include <platform_def.h> +#include <tzc_dmc620.h> + +uintptr_t sgi575_dmc_base[] = { + SGI575_DMC620_BASE0, + SGI575_DMC620_BASE1 +}; + +static const tzc_dmc620_driver_data_t sgi575_plat_driver_data = { + .dmc_base = sgi575_dmc_base, + .dmc_count = ARRAY_SIZE(sgi575_dmc_base) +}; + +static const tzc_dmc620_acc_addr_data_t sgi575_acc_addr_data[] = { + { + .region_base = ARM_AP_TZC_DRAM1_BASE, + .region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1, + .sec_attr = TZC_DMC620_REGION_S_RDWR + } +}; + +static const tzc_dmc620_config_data_t sgi575_plat_config_data = { + .plat_drv_data = &sgi575_plat_driver_data, + .plat_acc_addr_data = sgi575_acc_addr_data, + .acc_addr_count = ARRAY_SIZE(sgi575_acc_addr_data) +}; + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ + arm_tzc_dmc620_setup(&sgi575_plat_config_data); +} diff --git a/plat/arm/board/sgiclarka/include/platform_def.h b/plat/arm/board/sgiclarka/include/platform_def.h index abc48d84..ba6d0434 100644 --- a/plat/arm/board/sgiclarka/include/platform_def.h +++ b/plat/arm/board/sgiclarka/include/platform_def.h @@ -8,11 +8,16 @@ #define PLATFORM_DEF_H #include <sgi_base_platform_def.h> +#include <utils_def.h> #define PLAT_ARM_CLUSTER_COUNT 2 #define CSS_SGI_MAX_CPUS_PER_CLUSTER 4 #define CSS_SGI_MAX_PE_PER_CPU 1 -#define PLAT_CSS_MHU_BASE 0x45400000 +#define PLAT_CSS_MHU_BASE UL(0x45400000) + +/* Base address of DMC-620 instances */ +#define SGICLARKA_DMC620_BASE0 UL(0x4e000000) +#define SGICLARKA_DMC620_BASE1 UL(0x4e100000) #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/sgiclarka/platform.mk b/plat/arm/board/sgiclarka/platform.mk index fc2f7667..cf02219f 100644 --- a/plat/arm/board/sgiclarka/platform.mk +++ b/plat/arm/board/sgiclarka/platform.mk @@ -14,7 +14,9 @@ SGI_CPU_SOURCES := lib/cpus/aarch64/cortex_ares.S BL1_SOURCES += ${SGI_CPU_SOURCES} -BL2_SOURCES += lib/utils/mem_region.c \ +BL2_SOURCES += ${SGICLARKA_BASE}/sgiclarka_security.c \ + drivers/arm/tzc/tzc_dmc620.c \ + lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c BL31_SOURCES += ${SGI_CPU_SOURCES} \ diff --git a/plat/arm/board/sgiclarka/sgiclarka_security.c b/plat/arm/board/sgiclarka/sgiclarka_security.c new file mode 100644 index 00000000..29cd7547 --- /dev/null +++ b/plat/arm/board/sgiclarka/sgiclarka_security.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <debug.h> +#include <platform_def.h> +#include <tzc_dmc620.h> + +uintptr_t sgiclarka_dmc_base[] = { + SGICLARKA_DMC620_BASE0, + SGICLARKA_DMC620_BASE1 +}; + +static const tzc_dmc620_driver_data_t sgiclarka_plat_driver_data = { + .dmc_base = sgiclarka_dmc_base, + .dmc_count = ARRAY_SIZE(sgiclarka_dmc_base) +}; + +static const tzc_dmc620_acc_addr_data_t sgiclarka_acc_addr_data[] = { + { + .region_base = ARM_AP_TZC_DRAM1_BASE, + .region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1, + .sec_attr = TZC_DMC620_REGION_S_RDWR + } +}; + +static const tzc_dmc620_config_data_t sgiclarka_plat_config_data = { + .plat_drv_data = &sgiclarka_plat_driver_data, + .plat_acc_addr_data = sgiclarka_acc_addr_data, + .acc_addr_count = ARRAY_SIZE(sgiclarka_acc_addr_data) +}; + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ + arm_tzc_dmc620_setup(&sgiclarka_plat_config_data); +} diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index b72dd201..56ad8aee 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -128,10 +128,10 @@ void arm_configure_sys_timer(void) /* * Initialize CNTFRQ register in Non-secure CNTBase frame. * This is only required for Juno, because it doesn't follow ARM ARM - * in that the value updated in CNTFRQ is not reflected in CNTBASE_CNTFRQ. - * Hence update the value manually. + * in that the value updated in CNTFRQ is not reflected in + * CNTBASEN_CNTFRQ. Hence update the value manually. */ - mmio_write_32(ARM_SYS_CNT_BASE_NS + CNTBASE_CNTFRQ, freq_val); + mmio_write_32(ARM_SYS_CNT_BASE_NS + CNTBASEN_CNTFRQ, freq_val); #endif } #endif /* ARM_SYS_TIMCTL_BASE */ diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index d6e5448d..46fa7c4d 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -35,8 +35,7 @@ PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c \ BL1_SOURCES += ${INTERCONNECT_SOURCES} -BL2_SOURCES += ${CSS_ENT_BASE}/sgi_security.c \ - ${CSS_ENT_BASE}/sgi_image_load.c +BL2_SOURCES += ${CSS_ENT_BASE}/sgi_image_load.c BL31_SOURCES += ${INTERCONNECT_SOURCES} \ ${ENT_GIC_SOURCES} \ diff --git a/plat/arm/css/sgi/sgi_security.c b/plat/arm/css/sgi/sgi_security.c deleted file mode 100644 index 23e1a64e..00000000 --- a/plat/arm/css/sgi/sgi_security.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <arm_config.h> -#include <plat_arm.h> - -/* - * We assume that all security programming is done by the primary core. - */ -void plat_arm_security_setup(void) -{ -} |