From 102b0d2daa97dae68d3eed54d8fe37a9cc38a892 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:13:47 +0200 Subject: Adding upstream version 2.8.0+dfsg. Signed-off-by: Daniel Baumann --- include/drivers/arm/arm_gicv3_common.h | 28 + include/drivers/arm/cci.h | 125 +++++ include/drivers/arm/ccn.h | 113 ++++ .../arm/cryptocell/712/cc_crypto_boot_defs.h | 34 ++ .../drivers/arm/cryptocell/712/cc_pal_sb_plat.h | 33 ++ include/drivers/arm/cryptocell/712/cc_pal_types.h | 40 ++ .../drivers/arm/cryptocell/712/cc_pal_types_plat.h | 25 + include/drivers/arm/cryptocell/712/cc_sec_defs.h | 34 ++ include/drivers/arm/cryptocell/712/crypto_driver.h | 35 ++ include/drivers/arm/cryptocell/712/nvm.h | 55 ++ include/drivers/arm/cryptocell/712/nvm_otp.h | 59 ++ include/drivers/arm/cryptocell/712/rsa.h | 57 ++ include/drivers/arm/cryptocell/712/sbrom_bsv_api.h | 72 +++ .../arm/cryptocell/712/secureboot_base_func.h | 49 ++ .../arm/cryptocell/712/secureboot_gen_defs.h | 66 +++ include/drivers/arm/cryptocell/712/util.h | 72 +++ include/drivers/arm/cryptocell/713/bsv_api.h | 221 ++++++++ .../drivers/arm/cryptocell/713/bsv_crypto_api.h | 76 +++ .../arm/cryptocell/713/bsv_crypto_asym_api.h | 100 ++++ .../drivers/arm/cryptocell/713/bsv_crypto_defs.h | 94 ++++ include/drivers/arm/cryptocell/713/bsv_error.h | 161 ++++++ .../drivers/arm/cryptocell/713/cc_address_defs.h | 50 ++ include/drivers/arm/cryptocell/713/cc_boot_defs.h | 52 ++ include/drivers/arm/cryptocell/713/cc_pal_types.h | 100 ++++ .../drivers/arm/cryptocell/713/cc_pal_types_plat.h | 25 + .../arm/cryptocell/713/cc_pka_hw_plat_defs.h | 62 +++ include/drivers/arm/cryptocell/713/cc_sec_defs.h | 70 +++ include/drivers/arm/cryptocell/cc_rotpk.h | 13 + include/drivers/arm/css/css_mhu.h | 19 + include/drivers/arm/css/css_mhu_doorbell.h | 44 ++ include/drivers/arm/css/css_scp.h | 52 ++ include/drivers/arm/css/css_scpi.h | 109 ++++ include/drivers/arm/css/scmi.h | 176 ++++++ include/drivers/arm/css/sds.h | 90 +++ include/drivers/arm/dcc.h | 19 + include/drivers/arm/ethosn.h | 62 +++ include/drivers/arm/fvp/fvp_pwrc.h | 55 ++ include/drivers/arm/gic600_multichip.h | 55 ++ include/drivers/arm/gic600ae_fmu.h | 157 ++++++ include/drivers/arm/gic_common.h | 99 ++++ include/drivers/arm/gicv2.h | 200 +++++++ include/drivers/arm/gicv3.h | 605 +++++++++++++++++++++ include/drivers/arm/mhu.h | 86 +++ include/drivers/arm/nic_400.h | 16 + include/drivers/arm/pl011.h | 99 ++++ include/drivers/arm/pl061_gpio.h | 15 + include/drivers/arm/rss_comms.h | 15 + include/drivers/arm/sbsa.h | 24 + include/drivers/arm/scu.h | 20 + include/drivers/arm/smmu_v3.h | 71 +++ include/drivers/arm/sp804_delay_timer.h | 28 + include/drivers/arm/sp805.h | 36 ++ include/drivers/arm/tzc380.h | 164 ++++++ include/drivers/arm/tzc400.h | 160 ++++++ include/drivers/arm/tzc_common.h | 89 +++ include/drivers/arm/tzc_dmc500.h | 151 +++++ include/drivers/arm/tzc_dmc620.h | 104 ++++ 57 files changed, 4741 insertions(+) create mode 100644 include/drivers/arm/arm_gicv3_common.h create mode 100644 include/drivers/arm/cci.h create mode 100644 include/drivers/arm/ccn.h create mode 100644 include/drivers/arm/cryptocell/712/cc_crypto_boot_defs.h create mode 100644 include/drivers/arm/cryptocell/712/cc_pal_sb_plat.h create mode 100644 include/drivers/arm/cryptocell/712/cc_pal_types.h create mode 100644 include/drivers/arm/cryptocell/712/cc_pal_types_plat.h create mode 100644 include/drivers/arm/cryptocell/712/cc_sec_defs.h create mode 100644 include/drivers/arm/cryptocell/712/crypto_driver.h create mode 100644 include/drivers/arm/cryptocell/712/nvm.h create mode 100644 include/drivers/arm/cryptocell/712/nvm_otp.h create mode 100644 include/drivers/arm/cryptocell/712/rsa.h create mode 100644 include/drivers/arm/cryptocell/712/sbrom_bsv_api.h create mode 100644 include/drivers/arm/cryptocell/712/secureboot_base_func.h create mode 100644 include/drivers/arm/cryptocell/712/secureboot_gen_defs.h create mode 100644 include/drivers/arm/cryptocell/712/util.h create mode 100644 include/drivers/arm/cryptocell/713/bsv_api.h create mode 100644 include/drivers/arm/cryptocell/713/bsv_crypto_api.h create mode 100644 include/drivers/arm/cryptocell/713/bsv_crypto_asym_api.h create mode 100644 include/drivers/arm/cryptocell/713/bsv_crypto_defs.h create mode 100644 include/drivers/arm/cryptocell/713/bsv_error.h create mode 100644 include/drivers/arm/cryptocell/713/cc_address_defs.h create mode 100644 include/drivers/arm/cryptocell/713/cc_boot_defs.h create mode 100644 include/drivers/arm/cryptocell/713/cc_pal_types.h create mode 100644 include/drivers/arm/cryptocell/713/cc_pal_types_plat.h create mode 100644 include/drivers/arm/cryptocell/713/cc_pka_hw_plat_defs.h create mode 100644 include/drivers/arm/cryptocell/713/cc_sec_defs.h create mode 100644 include/drivers/arm/cryptocell/cc_rotpk.h create mode 100644 include/drivers/arm/css/css_mhu.h create mode 100644 include/drivers/arm/css/css_mhu_doorbell.h create mode 100644 include/drivers/arm/css/css_scp.h create mode 100644 include/drivers/arm/css/css_scpi.h create mode 100644 include/drivers/arm/css/scmi.h create mode 100644 include/drivers/arm/css/sds.h create mode 100644 include/drivers/arm/dcc.h create mode 100644 include/drivers/arm/ethosn.h create mode 100644 include/drivers/arm/fvp/fvp_pwrc.h create mode 100644 include/drivers/arm/gic600_multichip.h create mode 100644 include/drivers/arm/gic600ae_fmu.h create mode 100644 include/drivers/arm/gic_common.h create mode 100644 include/drivers/arm/gicv2.h create mode 100644 include/drivers/arm/gicv3.h create mode 100644 include/drivers/arm/mhu.h create mode 100644 include/drivers/arm/nic_400.h create mode 100644 include/drivers/arm/pl011.h create mode 100644 include/drivers/arm/pl061_gpio.h create mode 100644 include/drivers/arm/rss_comms.h create mode 100644 include/drivers/arm/sbsa.h create mode 100644 include/drivers/arm/scu.h create mode 100644 include/drivers/arm/smmu_v3.h create mode 100644 include/drivers/arm/sp804_delay_timer.h create mode 100644 include/drivers/arm/sp805.h create mode 100644 include/drivers/arm/tzc380.h create mode 100644 include/drivers/arm/tzc400.h create mode 100644 include/drivers/arm/tzc_common.h create mode 100644 include/drivers/arm/tzc_dmc500.h create mode 100644 include/drivers/arm/tzc_dmc620.h (limited to 'include/drivers/arm') diff --git a/include/drivers/arm/arm_gicv3_common.h b/include/drivers/arm/arm_gicv3_common.h new file mode 100644 index 0000000..d1e93be --- /dev/null +++ b/include/drivers/arm/arm_gicv3_common.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef ARM_GICV3_COMMON_H +#define ARM_GICV3_COMMON_H + +/******************************************************************************* + * GIC500/GIC600 Re-distributor interface registers & constants + ******************************************************************************/ + +/* GICR_WAKER implementation-defined bit definitions */ +#define WAKER_SL_SHIFT 0 +#define WAKER_QSC_SHIFT 31 + +#define WAKER_SL_BIT (1U << WAKER_SL_SHIFT) +#define WAKER_QSC_BIT (1U << WAKER_QSC_SHIFT) + +#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b) +#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b) +#define IIDR_MODEL_ARM_GIC_700 U(0x0400043b) + +#define PIDR_COMPONENT_ARM_DIST U(0x492) +#define PIDR_COMPONENT_ARM_REDIST U(0x493) +#define PIDR_COMPONENT_ARM_ITS U(0x494) + +#endif /* ARM_GICV3_COMMON_H */ diff --git a/include/drivers/arm/cci.h b/include/drivers/arm/cci.h new file mode 100644 index 0000000..5aea95a --- /dev/null +++ b/include/drivers/arm/cci.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CCI_H +#define CCI_H + +#include + +/* Slave interface offsets from PERIPHBASE */ +#define SLAVE_IFACE6_OFFSET UL(0x7000) +#define SLAVE_IFACE5_OFFSET UL(0x6000) +#define SLAVE_IFACE4_OFFSET UL(0x5000) +#define SLAVE_IFACE3_OFFSET UL(0x4000) +#define SLAVE_IFACE2_OFFSET UL(0x3000) +#define SLAVE_IFACE1_OFFSET UL(0x2000) +#define SLAVE_IFACE0_OFFSET UL(0x1000) +#define SLAVE_IFACE_OFFSET(index) (SLAVE_IFACE0_OFFSET + \ + (UL(0x1000) * (index))) + +/* Slave interface event and count register offsets from PERIPHBASE */ +#define EVENT_SELECT7_OFFSET UL(0x80000) +#define EVENT_SELECT6_OFFSET UL(0x70000) +#define EVENT_SELECT5_OFFSET UL(0x60000) +#define EVENT_SELECT4_OFFSET UL(0x50000) +#define EVENT_SELECT3_OFFSET UL(0x40000) +#define EVENT_SELECT2_OFFSET UL(0x30000) +#define EVENT_SELECT1_OFFSET UL(0x20000) +#define EVENT_SELECT0_OFFSET UL(0x10000) +#define EVENT_OFFSET(index) (EVENT_SELECT0_OFFSET + \ + (UL(0x10000) * (index))) + +/* Control and ID register offsets */ +#define CTRL_OVERRIDE_REG U(0x0) +#define SECURE_ACCESS_REG U(0x8) +#define STATUS_REG U(0xc) +#define IMPRECISE_ERR_REG U(0x10) +#define PERFMON_CTRL_REG U(0x100) +#define IFACE_MON_CTRL_REG U(0x104) + +/* Component and peripheral ID registers */ +#define PERIPHERAL_ID0 U(0xFE0) +#define PERIPHERAL_ID1 U(0xFE4) +#define PERIPHERAL_ID2 U(0xFE8) +#define PERIPHERAL_ID3 U(0xFEC) +#define PERIPHERAL_ID4 U(0xFD0) +#define PERIPHERAL_ID5 U(0xFD4) +#define PERIPHERAL_ID6 U(0xFD8) +#define PERIPHERAL_ID7 U(0xFDC) + +#define COMPONENT_ID0 U(0xFF0) +#define COMPONENT_ID1 U(0xFF4) +#define COMPONENT_ID2 U(0xFF8) +#define COMPONENT_ID3 U(0xFFC) +#define COMPONENT_ID4 U(0x1000) +#define COMPONENT_ID5 U(0x1004) +#define COMPONENT_ID6 U(0x1008) +#define COMPONENT_ID7 U(0x100C) + +/* Slave interface register offsets */ +#define SNOOP_CTRL_REG U(0x0) +#define SH_OVERRIDE_REG U(0x4) +#define READ_CHNL_QOS_VAL_OVERRIDE_REG U(0x100) +#define WRITE_CHNL_QOS_VAL_OVERRIDE_REG U(0x104) +#define MAX_OT_REG U(0x110) + +/* Snoop Control register bit definitions */ +#define DVM_EN_BIT BIT_32(1) +#define SNOOP_EN_BIT BIT_32(0) +#define SUPPORT_SNOOPS BIT_32(30) +#define SUPPORT_DVM BIT_32(31) + +/* Status register bit definitions */ +#define CHANGE_PENDING_BIT BIT_32(0) + +/* Event and count register offsets */ +#define EVENT_SELECT_REG U(0x0) +#define EVENT_COUNT_REG U(0x4) +#define COUNT_CNTRL_REG U(0x8) +#define COUNT_OVERFLOW_REG U(0xC) + +/* Slave interface monitor registers */ +#define INT_MON_REG_SI0 U(0x90000) +#define INT_MON_REG_SI1 U(0x90004) +#define INT_MON_REG_SI2 U(0x90008) +#define INT_MON_REG_SI3 U(0x9000C) +#define INT_MON_REG_SI4 U(0x90010) +#define INT_MON_REG_SI5 U(0x90014) +#define INT_MON_REG_SI6 U(0x90018) + +/* Master interface monitor registers */ +#define INT_MON_REG_MI0 U(0x90100) +#define INT_MON_REG_MI1 U(0x90104) +#define INT_MON_REG_MI2 U(0x90108) +#define INT_MON_REG_MI3 U(0x9010c) +#define INT_MON_REG_MI4 U(0x90110) +#define INT_MON_REG_MI5 U(0x90114) + +#define SLAVE_IF_UNUSED -1 + +#ifndef __ASSEMBLER__ + +#include + +/* Function declarations */ + +/* + * The ARM CCI driver needs the following: + * 1. Base address of the CCI product + * 2. An array of map between AMBA 4 master ids and ACE/ACE lite slave + * interfaces. + * 3. Size of the array. + * + * SLAVE_IF_UNUSED should be used in the map to represent no AMBA 4 master exists + * for that interface. + */ +void cci_init(uintptr_t base, const int *map, unsigned int num_cci_masters); + +void cci_enable_snoop_dvm_reqs(unsigned int master_id); +void cci_disable_snoop_dvm_reqs(unsigned int master_id); + +#endif /* __ASSEMBLER__ */ +#endif /* CCI_H */ diff --git a/include/drivers/arm/ccn.h b/include/drivers/arm/ccn.h new file mode 100644 index 0000000..7f73768 --- /dev/null +++ b/include/drivers/arm/ccn.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CCN_H +#define CCN_H + +/* + * This macro defines the maximum number of master interfaces that reside on + * Request nodes which the CCN driver can accommodate. The driver APIs to add + * and remove Request nodes from snoop/dvm domains take a bit map of master + * interfaces as inputs. The largest C data type that can be used is a 64-bit + * unsigned integer. Hence the value of 64. The platform will have to ensure + * that the master interfaces are numbered from 0-63. + */ +#define CCN_MAX_RN_MASTERS 64 + +/* + * The following constants define the various run modes that the platform can + * request the CCN driver to place the L3 cache in. These map to the + * programmable P-State values in a HN-F P-state register. + */ +#define CCN_L3_RUN_MODE_NOL3 0x0 /* HNF_PM_NOL3 */ +#define CCN_L3_RUN_MODE_SFONLY 0x1 /* HNF_PM_SFONLY */ +#define CCN_L3_RUN_MODE_HAM 0x2 /* HNF_PM_HALF */ +#define CCN_L3_RUN_MODE_FAM 0x3 /* HNF_PM_FULL */ + +/* part 0 IDs for various CCN variants */ +#define CCN_502_PART0_ID 0x30 +#define CCN_504_PART0_ID 0x26 +#define CCN_505_PART0_ID 0x27 +#define CCN_508_PART0_ID 0x28 +#define CCN_512_PART0_ID 0x29 + +/* + * The following macro takes the value returned from a read of a HN-F P-state + * status register and returns the retention state value. + */ +#define CCN_GET_RETENTION_STATE(pstate) ((pstate >> 4) & 0x3) + +/* + * The following macro takes the value returned from a read of a HN-F P-state + * status register and returns the run state value. + */ +#define CCN_GET_RUN_STATE(pstate) (pstate & 0xf) + +#ifndef __ASSEMBLER__ +#include + +/* + * This structure describes some of the implementation defined attributes of the + * CCN IP. It is used by the platform port to specify these attributes in order + * to initialise the CCN driver. The attributes are described below. + * + * 1. The 'num_masters' field specifies the total number of master interfaces + * resident on Request nodes. + * + * 2. The 'master_to_rn_id_map' field is a ponter to an array in which each + * index corresponds to a master interface and its value corresponds to the + * Request node on which the master interface resides. + * This field is not simply defined as an array of size CCN_MAX_RN_MASTERS. + * In reality, a platform will have much fewer master * interfaces than + * CCN_MAX_RN_MASTERS. With an array of this size, it would also have to + * set the unused entries to a suitable value. Zeroing the array would not + * be enough since 0 is also a valid node id. Hence, such an array is not + * used. + * + * 3. The 'periphbase' field is the base address of the programmer's view of the + * CCN IP. + */ +typedef struct ccn_desc { + unsigned int num_masters; + const unsigned char *master_to_rn_id_map; + uintptr_t periphbase; +} ccn_desc_t; + +/* Enum used to loop through all types of nodes in CCN*/ +typedef enum node_types { + NODE_TYPE_RNF = 0, + NODE_TYPE_RNI, + NODE_TYPE_RND, + NODE_TYPE_HNF, + NODE_TYPE_HNI, + NODE_TYPE_SN, + NUM_NODE_TYPES +} node_types_t; + +void ccn_init(const ccn_desc_t *plat_ccn_desc); +void ccn_enter_snoop_dvm_domain(unsigned long long master_iface_map); +void ccn_exit_snoop_dvm_domain(unsigned long long master_iface_map); +void ccn_enter_dvm_domain(unsigned long long master_iface_map); +void ccn_exit_dvm_domain(unsigned long long master_iface_map); +void ccn_set_l3_run_mode(unsigned int mode); +void ccn_program_sys_addrmap(unsigned int sn0_id, + unsigned int sn1_id, + unsigned int sn2_id, + unsigned int top_addr_bit0, + unsigned int top_addr_bit1, + unsigned char three_sn_en); +unsigned int ccn_get_l3_run_mode(void); +int ccn_get_part0_id(uintptr_t periphbase); + +void ccn_write_node_reg(node_types_t node_type, unsigned int node_id, + unsigned int reg_offset, + unsigned long long val); +unsigned long long ccn_read_node_reg(node_types_t node_type, + unsigned int node_id, + unsigned int reg_offset); + +#endif /* __ASSEMBLER__ */ +#endif /* CCN_H */ diff --git a/include/drivers/arm/cryptocell/712/cc_crypto_boot_defs.h b/include/drivers/arm/cryptocell/712/cc_crypto_boot_defs.h new file mode 100644 index 0000000..2cb8938 --- /dev/null +++ b/include/drivers/arm/cryptocell/712/cc_crypto_boot_defs.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_CRYPTO_BOOT_DEFS_H +#define _CC_CRYPTO_BOOT_DEFS_H + +/*! @file +@brief This file contains SBROM definitions +*/ + +/*! Version counters value. */ +typedef enum { + + CC_SW_VERSION_COUNTER1 = 1, /*!< Counter 1 - trusted version. */ + CC_SW_VERSION_COUNTER2, /*!< Counter 2 - non trusted version. */ + + CC_SW_VERSION_MAX = 0x7FFFFFFF + +} CCSbSwVersionId_t; + +/* HASH boot key definition */ +typedef enum { + CC_SB_HASH_BOOT_KEY_0_128B = 0, /*!< 128-bit truncated SHA256 digest of public key 0. */ + CC_SB_HASH_BOOT_KEY_1_128B = 1, /*!< 128-bit truncated SHA256 digest of public key 1. */ + CC_SB_HASH_BOOT_KEY_256B = 2, /*!< 256-bit SHA256 digest of public key. */ + CC_SB_HASH_BOOT_NOT_USED = 0xFF, + CC_SB_HASH_MAX_NUM = 0x7FFFFFFF, /*!\internal use external 128-bit truncated SHA256 digest */ +} CCSbPubKeyIndexType_t; + + +#endif diff --git a/include/drivers/arm/cryptocell/712/cc_pal_sb_plat.h b/include/drivers/arm/cryptocell/712/cc_pal_sb_plat.h new file mode 100644 index 0000000..212a710 --- /dev/null +++ b/include/drivers/arm/cryptocell/712/cc_pal_sb_plat.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*! +@file +@brief This file contains the platform-dependent definitions that are used in the SBROM code. +*/ + +#ifndef _CC_PAL_SB_PLAT_H +#define _CC_PAL_SB_PLAT_H + +#include "cc_pal_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! Definition of DMA address type, can be 32 bits or 64 bits according to CryptoCell's HW. */ +typedef uint64_t CCDmaAddr_t; +/*! Definition of CryptoCell address type, can be 32 bits or 64 bits according to platform. */ +typedef uintptr_t CCAddr_t; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/712/cc_pal_types.h b/include/drivers/arm/cryptocell/712/cc_pal_types.h new file mode 100644 index 0000000..8c09b23 --- /dev/null +++ b/include/drivers/arm/cryptocell/712/cc_pal_types.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CC_PAL_TYPES_H +#define CC_PAL_TYPES_H + +/*! +@file +@brief This file contains platform-dependent definitions and types. +*/ + +#include "cc_pal_types_plat.h" + +typedef enum { + CC_FALSE = 0, + CC_TRUE = 1 +} CCBool; + +#define CC_SUCCESS 0UL +#define CC_FAIL 1UL + +#define CC_1K_SIZE_IN_BYTES 1024 +#define CC_BITS_IN_BYTE 8 +#define CC_BITS_IN_32BIT_WORD 32 +#define CC_32BIT_WORD_SIZE (sizeof(uint32_t)) + +#define CC_OK CC_SUCCESS + +#define CC_UNUSED_PARAM(prm) ((void)prm) + +#define CC_MAX_UINT32_VAL (0xFFFFFFFF) + +#define CALC_FULL_BYTES(numBits) (((numBits) + (CC_BITS_IN_BYTE - 1))/CC_BITS_IN_BYTE) +#define CALC_FULL_32BIT_WORDS(numBits) (((numBits) + (CC_BITS_IN_32BIT_WORD - 1))/CC_BITS_IN_32BIT_WRD) +#define CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) (((sizeBytes) + CC_32BIT_WORD_SIZE - 1)/CC_32BIT_WORD_SIZE) + +#endif diff --git a/include/drivers/arm/cryptocell/712/cc_pal_types_plat.h b/include/drivers/arm/cryptocell/712/cc_pal_types_plat.h new file mode 100644 index 0000000..8410024 --- /dev/null +++ b/include/drivers/arm/cryptocell/712/cc_pal_types_plat.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*! @file +@brief This file contains basic type definitions that are platform-dependent. +*/ +#ifndef _CC_PAL_TYPES_PLAT_H +#define _CC_PAL_TYPES_PLAT_H +/* Host specific types for standard (ISO-C99) compilant platforms */ + +#include +#include + +typedef uint32_t CCStatus; + +#define CCError_t CCStatus +#define CC_INFINITE 0xFFFFFFFF + +#define CEXPORT_C +#define CIMPORT_C + +#endif /*_CC_PAL_TYPES_PLAT_H*/ diff --git a/include/drivers/arm/cryptocell/712/cc_sec_defs.h b/include/drivers/arm/cryptocell/712/cc_sec_defs.h new file mode 100644 index 0000000..d419218 --- /dev/null +++ b/include/drivers/arm/cryptocell/712/cc_sec_defs.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_SEC_DEFS_H +#define _CC_SEC_DEFS_H + +/*! +@file +@brief This file contains general hash definitions and types. +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! The hashblock size in words. */ +#define HASH_BLOCK_SIZE_IN_WORDS 16 +/*! The hash - SHA2 results in words. */ +#define HASH_RESULT_SIZE_IN_WORDS 8 +#define HASH_RESULT_SIZE_IN_BYTES 32 + +/*! Definition for hash result array. */ +typedef uint32_t CCHashResult_t[HASH_RESULT_SIZE_IN_WORDS]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/712/crypto_driver.h b/include/drivers/arm/cryptocell/712/crypto_driver.h new file mode 100644 index 0000000..18104dd --- /dev/null +++ b/include/drivers/arm/cryptocell/712/crypto_driver.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CRYPTO_DRIVER_H +#define _CRYPTO_DRIVER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cc_pal_sb_plat.h" +#include "cc_sec_defs.h" + +/*---------------------------- + PUBLIC FUNCTIONS +-----------------------------------*/ +/*! + * @brief This function gives the functionality of integrated hash + * + * @param[in] hwBaseAddress - CryptoCell base address + * @param[out] hashResult - the HASH result. + * + */ +CCError_t SBROM_CryptoHash(unsigned long hwBaseAddress, CCDmaAddr_t inputDataAddr, uint32_t BlockSize, + CCHashResult_t hashResult); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/712/nvm.h b/include/drivers/arm/cryptocell/712/nvm.h new file mode 100644 index 0000000..a70289f --- /dev/null +++ b/include/drivers/arm/cryptocell/712/nvm.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _NVM__H +#define _NVM__H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cc_crypto_boot_defs.h" +#include "cc_pal_types.h" +#include "cc_sec_defs.h" + +/*------------------------------------ + DEFINES +-------------------------------------*/ + +/** + * @brief This function reads the LCS from the SRAM/NVM + * + * @param[in] hwBaseAddress - CryptoCell base address + * + * @param[in/out] lcs_ptr - pointer to memory to store the LCS + * + * @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h + */ +CCError_t NVM_GetLCS(unsigned long hwBaseAddress, uint32_t *lcs_ptr); + +/** + * @brief The NVM_ReadHASHPubKey function is a NVM interface function - + * The function retrieves the HASH of the device Public key from the SRAM/NVM + * + * @param[in] hwBaseAddress - CryptoCell base address + * + * @param[in] pubKeyIndex - Index of HASH in the OTP + * + * @param[out] PubKeyHASH - the public key HASH. + * + * @param[in] hashSizeInWords - hash size (valid values: 4W, 8W) + * + * @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h + */ + +CCError_t NVM_ReadHASHPubKey(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t pubKeyIndex, CCHashResult_t PubKeyHASH, uint32_t hashSizeInWords); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/712/nvm_otp.h b/include/drivers/arm/cryptocell/712/nvm_otp.h new file mode 100644 index 0000000..390d62b --- /dev/null +++ b/include/drivers/arm/cryptocell/712/nvm_otp.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _NVM_OTP_H +#define _NVM_OTP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cc_crypto_boot_defs.h" +#include "cc_pal_types.h" + +/*------------------------------------ + DEFINES +-------------------------------------*/ + + + +/** + * @brief The NVM_GetSwVersion function is a NVM interface function - + * The function retrieves the SW version from the SRAM/NVM. + * In case of OTP, we support up to 16 anti-rollback counters (taken from the certificate) + * + * @param[in] hwBaseAddress - CryptoCell base address + * + * @param[in] counterId - relevant only for OTP (valid values: 1,2) + * + * @param[out] swVersion - the minimum SW version + * + * @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h + */ +CCError_t NVM_GetSwVersion(unsigned long hwBaseAddress, CCSbSwVersionId_t counterId, uint32_t *swVersion); + + +/** + * @brief The NVM_SetSwVersion function is a NVM interface function - + * The function writes the SW version into the SRAM/NVM. + * In case of OTP, we support up to 16 anti-rollback counters (taken from the certificate) + * + * @param[in] hwBaseAddress - CryptoCell base address + * + * @param[in] counterId - relevant only for OTP (valid values: 1,2) + * + * @param[in] swVersion - the minimum SW version + * + * @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h + */ +CCError_t NVM_SetSwVersion(unsigned long hwBaseAddress, CCSbSwVersionId_t counterId, uint32_t swVersion); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/712/rsa.h b/include/drivers/arm/cryptocell/712/rsa.h new file mode 100644 index 0000000..825214d --- /dev/null +++ b/include/drivers/arm/cryptocell/712/rsa.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RSA_H +#define RSA_H + +/* + * All the includes that are needed for code using this module to + * compile correctly should be #included here. + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cc_pal_types.h" + +/************************ Defines ******************************/ + +/* the modulus size in bits */ +#if (KEY_SIZE == 2048) +#define RSA_MOD_SIZE_IN_BITS 2048UL +#elif (KEY_SIZE == 3072) +#define RSA_MOD_SIZE_IN_BITS 3072UL +#else +#error Unsupported CryptoCell key size requested +#endif + +#define RSA_MOD_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_MOD_SIZE_IN_BITS)) +#define RSA_MOD_SIZE_IN_WORDS (CALC_FULL_32BIT_WORDS(RSA_MOD_SIZE_IN_BITS)) +#define RSA_MOD_SIZE_IN_256BITS (RSA_MOD_SIZE_IN_WORDS/8) +#define RSA_EXP_SIZE_IN_BITS 17UL +#define RSA_EXP_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_EXP_SIZE_IN_BITS)) + +/* + * @brief The RSA_CalcNp calculates Np value and saves it into Np_ptr: + * + * + + * @param[in] hwBaseAddress - HW base address. Relevant for HW + * implementation, for SW it is ignored. + * @N_ptr[in] - The pointer to the modulus buffer. + * @Np_ptr[out] - pointer to Np vector buffer. Its size must be >= 160. + */ +void RSA_CalcNp(unsigned long hwBaseAddress, + uint32_t *N_ptr, + uint32_t *Np_ptr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/712/sbrom_bsv_api.h b/include/drivers/arm/cryptocell/712/sbrom_bsv_api.h new file mode 100644 index 0000000..de83546 --- /dev/null +++ b/include/drivers/arm/cryptocell/712/sbrom_bsv_api.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _SBROM_BSV_API_H +#define _SBROM_BSV_API_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! @file +@brief This file contains all SBROM library APIs and definitions. +*/ +#include "cc_pal_types.h" + +/* Life cycle state definitions */ +#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0 /*!< CM lifecycle value. */ +#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1 /*!< DM lifecycle value. */ +#define CC_BSV_SECURITY_DISABLED_LCS 0x3 /*!< SD lifecycle value. */ +#define CC_BSV_SECURE_LCS 0x5 /*!< Secure lifecycle value. */ +#define CC_BSV_RMA_LCS 0x7 /*!< RMA lifecycle value. */ + +/*---------------------------- + PUBLIC FUNCTIONS +-----------------------------------*/ + +/*! +@brief This function should be the first ARM TrustZone CryptoCell TEE SBROM library API called. +It verifies the HW product and version numbers. + +@return CC_OK On success. +@return A non-zero value from sbrom_bsv_error.h on failure. +*/ +CCError_t CC_BsvSbromInit( + unsigned long hwBaseAddress /*!< [in] HW registers base address. */ + ); + + +/*! +@brief This function can be used for checking the LCS value, after CC_BsvLcsGetAndInit was called by the Boot ROM. + +@return CC_OK On success. +@return A non-zero value from sbrom_bsv_error.h on failure. +*/ +CCError_t CC_BsvLcsGet( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + uint32_t *pLcs /*!< [out] Returned lifecycle state. */ + ); + +/*! +@brief This function retrieves the HW security lifecycle state, performs validity checks, +and additional initializations in case the LCS is RMA (sets the Kce to fixed value). +\note Invalid LCS results in an error returned. +In this case, the customer's code must completely disable the device. + +@return CC_OK On success. +@return A non-zero value from sbrom_bsv_error.h on failure. +*/ +CCError_t CC_BsvLcsGetAndInit( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + uint32_t *pLcs /*!< [out] Returned lifecycle state. */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/712/secureboot_base_func.h b/include/drivers/arm/cryptocell/712/secureboot_base_func.h new file mode 100644 index 0000000..6db596e --- /dev/null +++ b/include/drivers/arm/cryptocell/712/secureboot_base_func.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _SECURE_BOOT_BASE_FUNC_H +#define _SECURE_BOOT_BASE_FUNC_H + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cc_pal_types.h" +#include "secureboot_gen_defs.h" + + +/*---------------------------- + PUBLIC FUNCTIONS +-----------------------------------*/ + +/** + * @brief This function calculates the HASH over the given data and than verify + * RSA signature on that hashed data + * + * @param[in] hwBaseAddr - CryptoCell base address + * @param[in] pData - pointer to the data to be verified + * @param[in] pNParams - a pointer to the public key parameters + * @param[in] pSignature - a pointer to the signature structure + * @param[in] sizeOfData - size of the data to calculate the HASH on (in bytes) + * @param[in] RSAAlg - RSA algorithm to use + * + * @return CCError_t - On success the value CC_OK is returned, + * on failure - a value from BootImagesVerifier_error.h + */ +CCError_t CCSbVerifySignature(unsigned long hwBaseAddress, + uint32_t *pData, + CCSbNParams_t *pNParams, + CCSbSignature_t *pSignature, + uint32_t sizeOfData, + CCSbRsaAlg_t RSAAlg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h b/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h new file mode 100644 index 0000000..ed1f283 --- /dev/null +++ b/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _SECURE_BOOT_GEN_DEFS_H +#define _SECURE_BOOT_GEN_DEFS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! @file +@brief This file contains all of the definitions and structures that are used for the secure boot. +*/ + +#include "cc_pal_sb_plat.h" +#include "cc_sec_defs.h" + + +/* General definitions */ +/***********************/ + +/*RSA definitions*/ +#if (KEY_SIZE == 2048) +#define SB_RSA_MOD_SIZE_IN_WORDS 64 +#elif (KEY_SIZE == 3072) +#define SB_RSA_MOD_SIZE_IN_WORDS 96 +#else +#error Unsupported CryptoCell key size requested +#endif + +#define SB_RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS 5 + + +/*! Public key data structure. */ +typedef struct { + uint32_t N[SB_RSA_MOD_SIZE_IN_WORDS]; /*!< N public key, big endian representation. */ + uint32_t Np[SB_RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS]; /*!< Np (Barrett n' value). */ +} CCSbNParams_t; + +/*! Signature structure. */ +typedef struct { + uint32_t sig[SB_RSA_MOD_SIZE_IN_WORDS]; /*!< RSA PSS signature. */ +} CCSbSignature_t; + + +/********* Supported algorithms definitions ***********/ + +/*! RSA supported algorithms */ +/* Note: this applies to either 2k or 3k based on CryptoCell SBROM library + * version - it means 2k in version 1 and 3k in version 2 (yes, really). + */ +typedef enum { + RSA_PSS = 0x01, /*!< RSA PSS after hash SHA 256 */ + RSA_PKCS15 = 0x02, /*!< RSA PKX15 */ + RSA_Last = 0x7FFFFFFF +} CCSbRsaAlg_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/712/util.h b/include/drivers/arm/cryptocell/712/util.h new file mode 100644 index 0000000..18fb599 --- /dev/null +++ b/include/drivers/arm/cryptocell/712/util.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef UTIL_H +#define UTIL_H + +/* + * All the includes that are needed for code using this module to + * compile correctly should be #included here. + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************ Defines ******************************/ + +/* invers the bytes on a word- used for output from HASH */ +#ifdef BIG__ENDIAN +#define UTIL_INVERSE_UINT32_BYTES(val) (val) +#else +#define UTIL_INVERSE_UINT32_BYTES(val) \ + (((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24)) +#endif + +/* invers the bytes on a word - used for input data for HASH */ +#ifdef BIG__ENDIAN +#define UTIL_REVERT_UINT32_BYTES(val) \ + (((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24)) +#else +#define UTIL_REVERT_UINT32_BYTES(val) (val) +#endif + + /* ------------------------------------------------------------ + ** + * @brief This function executes a reverse bytes copying from one buffer to another buffer. + * + * @param[in] dst_ptr - The pointer to destination buffer. + * @param[in] src_ptr - The pointer to source buffer. + * @param[in] size - The size in bytes. + * + */ + +void UTIL_ReverseMemCopy(uint8_t *dst_ptr, uint8_t *src_ptr, uint32_t size); + + + /* ------------------------------------------------------------ + ** + * @brief This function executes a reversed byte copy on a specified buffer. + * + * on a 6 byte byffer: + * + * buff[5] <---> buff[0] + * buff[4] <---> buff[1] + * buff[3] <---> buff[2] + * + * @param[in] dst_ptr - The counter buffer. + * @param[in] src_ptr - The counter size in bytes. + * + */ +void UTIL_ReverseBuff(uint8_t *buff_ptr, uint32_t size); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/drivers/arm/cryptocell/713/bsv_api.h b/include/drivers/arm/cryptocell/713/bsv_api.h new file mode 100644 index 0000000..dc49473 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_api.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_API_H +#define _BSV_API_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file contains the Boot Services APIs and definitions. + +@defgroup cc_bsv_api CryptoCell Boot Services APIs and definitions +@{ +@ingroup cc_bsv +*/ + +#include "cc_pal_types.h" +#include "cc_sec_defs.h" +#include "cc_boot_defs.h" + +/* Life cycle state definitions. */ +#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0 /*!< The CM life-cycle state (LCS) value. */ +#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1 /*!< The DM life-cycle state (LCS) value. */ +#define CC_BSV_SECURE_LCS 0x5 /*!< The Secure life-cycle state (LCS) value. */ +#define CC_BSV_RMA_LCS 0x7 /*!< The RMA life-cycle state (LCS) value. */ +#define CC_BSV_INVALID_LCS 0xff /*!< The invalid life-cycle state (LCS) value. */ + +/*---------------------------- + TYPES +-----------------------------------*/ + +/*---------------------------- + PUBLIC FUNCTIONS +-----------------------------------*/ + + +/*! +@brief This function verifies the product and version numbers of the HW, and initializes it. + +\warning This function must be the first CryptoCell-7xx SBROM library API called. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvInit( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); + +/*! +@brief This function retrieves the HW LCS and performs validity checks. + +If the LCS is RMA, it also sets the OTP secret keys to a fixed value. + +@note An error is returned if there is an invalid LCS. If this happens, your code must +completely disable the device. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvGetAndInitLcs( + unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + uint32_t *pLcs /*!< [out] The value of the current LCS. */ + ); + +/*! +@brief This function retrieves the LCS from the NVM manager. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvLcsGet( + unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + uint32_t *pLcs /*!< [out] The value of the current LCS. */ + ); + +/*! +@brief This function reads software revocation counter from OTP memory, according to the provided sw version index. +SW version is stored in NVM counter and represented by ones. Meaning seVersion=5 would be stored as binary 0b11111; +hence: + the maximal of trusted is 32 + the maximal of non-trusted is 224 + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSwVersionGet( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCSbSwVersionId_t id, /*!< [in] Enumeration defining the trusted/non-trusted counter to read. */ + uint32_t *swVersion /*!< [out] The value of the requested counter as read from OTP memory. */ + ); + +/*! +@brief This function sets the NVM counter according to swVersionID (trusted/non-trusted). + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSwVersionSet( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCSbSwVersionId_t id, /*!< [in] Enumeration defining the trusted/non-trusted counter to read. */ + uint32_t swVersion /*!< [in] New value of the counter to be programmed in OTP memory. */ + ); + +/*! +@brief This function sets the "fatal error" flag in the NVM manager, to disable the use of +any HW keys or security services. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvFatalErrorSet( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); + +/*! +@brief This function retrieves the public key hash from OTP memory, according to the provided index. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvPubKeyHashGet( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCSbPubKeyIndexType_t keyIndex, /*!< [in] Enumeration defining the key hash to retrieve: 128-bit HBK0, 128-bit HBK1, or 256-bit HBK. */ + uint32_t *hashedPubKey, /*!< [out] A buffer to contain the public key HASH. */ + uint32_t hashResultSizeWords /*!< [in] The size of the hash in 32-bit words: + - Must be 4 for 128-bit hash. + - Must be 8 for 256bit hash. */ + ); + +/*! +@brief This function permanently sets the RMA LCS for the ICV and the OEM. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvRMAModeEnable( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); + +/*! +@brief This function is called by the ICV code, to disable the OEM code from changing the ICV RMA bit flag. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvICVRMAFlagBitLock( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); + +/*! +@brief This function locks the defined ICV class keys from further usage. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvICVKeyLock( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCBool_t isICVProvisioningKeyLock, /*!< [in] Should the provisioning key be locked. */ + CCBool_t isICVCodeEncKeyLock /*!< [in] Should the encryption key be locked. */ + ); + + +/*! +@brief This function retrieves the value of "secure disable" bit. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSecureDisableGet( + unsigned long hwBaseAddress, /*!< [in] HW registers base address. */ + CCBool_t *isSDEnabled /*!< [out] The value of the SD Enable bit. */ + ); + + +/*! +@brief This function derives the platform key (Kplt) from the Kpicv, and then decrypts the customer key (Kcst) +from the EKcst (burned in the OTP). The decryption is done only in Secure and RMA LCS mode using AES-ECB. +The customer ROM should invoke this function during early boot, prior to running any non-ROM code, only if Kcst exists. +The resulting Kcst is saved in a HW register. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvCustomerKeyDecrypt( + unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */ + ); +#ifdef __cplusplus +} +#endif + +/*! +@brief This function derives the unique SoC_ID for the device, as hashed (Hbk || AES_CMAC (HUK)). + +@note SoC_ID is required to create debug certificates. + +The OEM or ICV must provide a method for a developer to discover the SoC_ID of a target +device without having to first enable debugging. +One suggested implementation is to have the device ROM code compute the SoC_ID and place +it in a specific location in the flash memory, from where it can be accessed by the developer. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSocIDCompute( + unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + CCHashResult_t hashResult /*!< [out] The derived SoC_ID. */ + ); + +#endif /* _BSV_API_H */ + +/** +@} + */ + diff --git a/include/drivers/arm/cryptocell/713/bsv_crypto_api.h b/include/drivers/arm/cryptocell/713/bsv_crypto_api.h new file mode 100644 index 0000000..1e60579 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_crypto_api.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_CRYPTO_API_H +#define _BSV_CRYPTO_API_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file contains the cryptographic ROM APIs of the Boot Services. + +@defgroup cc_bsv_crypto_api CryptoCell Boot Services cryptographic ROM APIs +@{ +@ingroup cc_bsv +*/ + +#include "cc_pal_types.h" +#include "cc_sec_defs.h" +#include "cc_address_defs.h" +#include "bsv_crypto_defs.h" + +/*---------------------------- + PUBLIC FUNCTIONS +-----------------------------------*/ + +/*! +@brief This function calculates the SHA-256 digest over contiguous memory +in an integrated operation. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvSha256( + unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + uint8_t *pDataIn, /*!< [in] A pointer to the input buffer to be hashed. The buffer must be contiguous. */ + size_t dataSize, /*!< [in] The size of the data to be hashed, in bytes. */ + CCHashResult_t hashBuff /*!< [out] A pointer to a word-aligned 32-byte buffer. */ + ); + + +/*! +@brief This function allows you to calculate SHA256 digest of an image with decryption base on AES-CTR, +with HW or user key. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. (in this case, hashBuff will be returned clean, while the output data should be cleaned by the user). +*/ +CCError_t CC_BsvCryptoImageDecrypt( unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + CCBsvflowMode_t flow, /*!< [in] The supported operations are: HASH, AES to HASH, AES and HASH. */ + CCBsvKeyType_t keyType, /*!< [in] The key type to use: Kce, Kceicv, or user key. */ + uint8_t *pUserKey, /*!< [in] A pointer to the user key buffer in case keyType is CC_BSV_USER_KEY. */ + size_t userKeySize, /*!< [in] The user key size in bytes (128bits) in case keyType is CC_BSV_USER_KEY. */ + uint8_t *pIvBuf, /*!< [in] A pointer to the IV / counter buffer. */ + uint8_t *pInputData, /*!< [in] A pointer to the input data. */ + uint8_t *pOutputData, /*!< [out] A pointer to the output buffer. (optional – should be null in case of hash only). */ + size_t dataSize, /*!< [in] The size of the input data in bytes. MUST be multiple of AES block size. */ + CCHashResult_t hashBuff /*!< [out] A pointer to a word-aligned 32-byte digest output buffer. */ + ); + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + diff --git a/include/drivers/arm/cryptocell/713/bsv_crypto_asym_api.h b/include/drivers/arm/cryptocell/713/bsv_crypto_asym_api.h new file mode 100644 index 0000000..406e1ef --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_crypto_asym_api.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_CRYPTO_ASYM_API_H +#define _BSV_CRYPTO_ASYM_API_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file contains the cryptographic Asymmetric ROM APIs of the Boot Services. + +@defgroup cc_bsv_crypto_asym_api CryptoCell Boot Services cryptographic Asymmetric ROM APIs +@{ +@ingroup cc_bsv +*/ + +#include "cc_pal_types.h" +#include "cc_pka_hw_plat_defs.h" +#include "cc_sec_defs.h" +#include "bsv_crypto_api.h" + +/*! Defines the workspace size in bytes needed for internal Asymmetric operations. */ +#define BSV_RSA_WORKSPACE_MIN_SIZE (4*BSV_CERT_RSA_KEY_SIZE_IN_BYTES +\ + 2*RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES) + +/*! Definition for the RSA public modulus array. */ +typedef uint32_t CCBsvNBuff_t[BSV_CERT_RSA_KEY_SIZE_IN_WORDS]; + +/*! Definition for the RSA Barrett mod tag array. */ +typedef uint32_t CCBsvNpBuff_t[RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES]; + +/*! Definition for the RSA signature array. */ +typedef uint32_t CCBsvSignature_t[BSV_CERT_RSA_KEY_SIZE_IN_WORDS]; + + +/*---------------------------- + PUBLIC FUNCTIONS +-----------------------------------*/ + +/*! +@brief This function performs the primitive operation of RSA, meaning exponent and modulus. + outBuff = (pInBuff ^ Exp) mod NBuff. ( Exp = 0x10001 ) + + The function supports 2k and 3K bit size of modulus, based on compile time define. + There are no restriction on pInBuff location, however its size must be equal to BSV_RSA_KEY_SIZE_IN_BYTES and its + value must be smaller than the modulus. + + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvRsaPrimVerify (unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + CCBsvNBuff_t NBuff, /*!< [in] The modulus buffer big endian format. */ + CCBsvNpBuff_t NpBuff, /*!< [in] The barret tag buffer big endian format - optional. */ + uint32_t *pInBuff, /*!< [in] The DataIn buffer to be encrypted. */ + size_t inBuffSize, /*!< [in] The DataIn buffer size in bytes, must be BSV_RSA_KEY_SIZE_IN_BYTES. */ + CCBsvSignature_t pOutBuff, /*!< [out] The encrypted buffer in big endian format. */ + uint32_t *pWorkSpace, /*!< [in] The pointer to user allocated buffer for internal use. */ + size_t workBufferSize /*!< [in] The size in bytes of pWorkSpace, must be at-least BSV_RSA_WORKSPACE_MIN_SIZE. */ +); + + +/*! +@brief This function performs RSA PSS verify. + + The function should support 2k and 3K bit size of modulus, based on compile time define. + +@return \c CC_OK on success. +@return A non-zero value from bsv_error.h on failure. +*/ +CCError_t CC_BsvRsaPssVerify (unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */ + CCBsvNBuff_t NBuff, /*!< [in] The modulus buffer big endian format. */ + CCBsvNpBuff_t NpBuff, /*!< [in] The barret tag buffer big endian format - optional. */ + CCBsvSignature_t signature, /*!< [in] The signature buffer to verify - big endian format. */ + CCHashResult_t hashedData, /*!< [in] The data-in buffer to be verified as sha256 digest. */ + uint32_t *pWorkSpace, /*!< [in] The pointer to user allocated buffer for internal use. */ + size_t workBufferSize, /*!< [in] The size in bytes of pWorkSpace, must be at-least BSV_RSA_WORKSPACE_MIN_SIZE. */ + CCBool_t *pIsVerified /*!< [out] The flag indicates whether the signature is verified or not. + If verified value will be CC_TRUE, otherwise CC_FALSE */ +); + + + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + diff --git a/include/drivers/arm/cryptocell/713/bsv_crypto_defs.h b/include/drivers/arm/cryptocell/713/bsv_crypto_defs.h new file mode 100644 index 0000000..9ea354d --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_crypto_defs.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_CRYPTO_DEFS_H +#define _BSV_CRYPTO_DEFS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file contains the definitions of the cryptographic ROM APIs. + +@defgroup cc_bsv_crypto_defs CryptoCell Boot Services cryptographic ROM API definitions +@{ +@ingroup cc_bsv +*/ + +/*! AES supported HW key code table. */ +typedef enum { + + CC_BSV_USER_KEY = 0, /*!< Definition for a user key. */ + CC_BSV_HUK_KEY = 1, /*!< Definition for the HW unique key. */ + CC_BSV_RTL_KEY = 2, /*!< Definition for the RTL key. */ + CC_BSV_SESSION_KEY = 3, /*!< Definition for the Session key. */ + CC_BSV_CE_KEY = 4, /*!< Definition for the Kce. */ + CC_BSV_PLT_KEY = 5, /*!< Definition for the Platform key. */ + CC_BSV_KCST_KEY = 6, /*!< Definition for Kcst. */ + CC_BSV_ICV_PROV_KEY = 0xd, /*!< Definition for the Kpicv. */ + CC_BSV_ICV_CE_KEY = 0xe, /*!< Definition for the Kceicv. */ + CC_BSV_PROV_KEY = 0xf, /*!< Definition for the Kcp. */ + CC_BSV_END_OF_KEY_TYPE = INT32_MAX, /*!< Reserved. */ +}CCBsvKeyType_t; + +/*! AES directions. */ +typedef enum bsvAesDirection { + BSV_AES_DIRECTION_ENCRYPT = 0, /*!< Encrypt.*/ + BSV_AES_DIRECTION_DECRYPT = 1, /*!< Decrypt.*/ + BSV_AES_NUM_OF_ENCRYPT_MODES, /*!< The maximal number of operations. */ + BSV_AES_DIRECTION_RESERVE32B = INT32_MAX /*!< Reserved.*/ +}bsvAesDirection_t; + +/*! Definitions of the cryptographic flow supported as part of the Secure Boot. */ +typedef enum { + CC_BSV_CRYPTO_HASH_MODE = 0, /*!< Hash mode only. */ + CC_BSV_CRYPTO_AES_CTR_AND_HASH_MODE = 1, /*!< Data goes into the AES and Hash engines. */ + CC_BSV_CRYPTO_AES_CTR_TO_HASH_MODE = 2 /*!< Data goes into the AES and from the AES to the Hash engine. */ +}CCBsvflowMode_t; + +/*! CryptoImage HW completion sequence mode */ +typedef enum +{ + BSV_CRYPTO_COMPLETION_NO_WAIT = 0, /*!< The driver waits only before reading the output. */ + BSV_CRYPTO_COMPLETION_WAIT_UPON_END = 1 /*!< The driver waits after each chunk of data. */ +}bsvCryptoCompletionMode_t; + + +/*! AES-CMAC result size, in words. */ +#define CC_BSV_CMAC_RESULT_SIZE_IN_WORDS 4 /* 128b */ +/*! AES-CMAC result size, in bytes. */ +#define CC_BSV_CMAC_RESULT_SIZE_IN_BYTES 16 /* 128b */ +/*! AES-CCM 128bit key size, in bytes. */ +#define CC_BSV_CCM_KEY_SIZE_BYTES 16 +/*! AES-CCM 128bit key size, in words. */ +#define CC_BSV_CCM_KEY_SIZE_WORDS 4 +/*! AES-CCM NONCE size, in bytes. */ +#define CC_BSV_CCM_NONCE_SIZE_BYTES 12 + + +/*! AES-CMAC result buffer. */ +typedef uint32_t CCBsvCmacResult_t[CC_BSV_CMAC_RESULT_SIZE_IN_WORDS]; +/*! AES-CCM key buffer.*/ +typedef uint32_t CCBsvCcmKey_t[CC_BSV_CCM_KEY_SIZE_WORDS]; +/*! AES-CCM nonce buffer.*/ +typedef uint8_t CCBsvCcmNonce_t[CC_BSV_CCM_NONCE_SIZE_BYTES]; +/*! AES-CCM MAC buffer.*/ +typedef uint8_t CCBsvCcmMacRes_t[CC_BSV_CMAC_RESULT_SIZE_IN_BYTES]; + + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + diff --git a/include/drivers/arm/cryptocell/713/bsv_error.h b/include/drivers/arm/cryptocell/713/bsv_error.h new file mode 100644 index 0000000..4d72e60 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/bsv_error.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BSV_ERROR_H +#define _BSV_ERROR_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! +@file +@brief This file defines the error code types that are returned from the Boot Services APIs. + +@defgroup cc_bsv_error CryptoCell Boot Services error codes +@{ +@ingroup cc_bsv +*/ + +/*! Defines the base address for Boot Services errors. */ +#define CC_BSV_BASE_ERROR 0x0B000000 +/*! Defines the base address for Boot Services cryptographic errors. */ +#define CC_BSV_CRYPTO_ERROR 0x0C000000 + +/*! Illegal input parameter. */ +#define CC_BSV_ILLEGAL_INPUT_PARAM_ERR (CC_BSV_BASE_ERROR + 0x00000001) +/*! Illegal HUK value. */ +#define CC_BSV_ILLEGAL_HUK_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000002) +/*! Illegal Kcp value. */ +#define CC_BSV_ILLEGAL_KCP_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000003) +/*! Illegal Kce value. */ +#define CC_BSV_ILLEGAL_KCE_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000004) +/*! Illegal Kpicv value. */ +#define CC_BSV_ILLEGAL_KPICV_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000005) +/*! Illegal Kceicv value. */ +#define CC_BSV_ILLEGAL_KCEICV_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000006) +/*! Illegal EKcst value. */ +#define CC_BSV_ILLEGAL_EKCST_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000007) +/*! Hash boot key not programmed in the OTP. */ +#define CC_BSV_HASH_NOT_PROGRAMMED_ERR (CC_BSV_BASE_ERROR + 0x00000008) +/*! Illegal Hash boot key zero count in the OTP. */ +#define CC_BSV_HBK_ZERO_COUNT_ERR (CC_BSV_BASE_ERROR + 0x00000009) +/*! Illegal LCS. */ +#define CC_BSV_ILLEGAL_LCS_ERR (CC_BSV_BASE_ERROR + 0x0000000A) +/*! OTP write compare failure. */ +#define CC_BSV_OTP_WRITE_CMP_FAIL_ERR (CC_BSV_BASE_ERROR + 0x0000000B) +/*! OTP access error */ +#define CC_BSV_OTP_ACCESS_ERR (CC_BSV_BASE_ERROR + 0x0000000C) +/*! Erase key in OTP failed. */ +#define CC_BSV_ERASE_KEY_FAILED_ERR (CC_BSV_BASE_ERROR + 0x0000000D) +/*! Illegal PIDR. */ +#define CC_BSV_ILLEGAL_PIDR_ERR (CC_BSV_BASE_ERROR + 0x0000000E) +/*! Illegal CIDR. */ +#define CC_BSV_ILLEGAL_CIDR_ERR (CC_BSV_BASE_ERROR + 0x0000000F) +/*! Device failed to move to fatal error state. */ +#define CC_BSV_FAILED_TO_SET_FATAL_ERR (CC_BSV_BASE_ERROR + 0x00000010) +/*! Failed to set RMA LCS. */ +#define CC_BSV_FAILED_TO_SET_RMA_ERR (CC_BSV_BASE_ERROR + 0x00000011) +/*! Illegal RMA indication. */ +#define CC_BSV_ILLEGAL_RMA_INDICATION_ERR (CC_BSV_BASE_ERROR + 0x00000012) +/*! Boot Services version is not initialized. */ +#define CC_BSV_VER_IS_NOT_INITIALIZED_ERR (CC_BSV_BASE_ERROR + 0x00000013) +/*! APB secure mode is locked. */ +#define CC_BSV_APB_SECURE_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000014) +/*! APB privilege mode is locked. */ +#define CC_BSV_APB_PRIVILEG_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000015) +/*! Illegal operation. */ +#define CC_BSV_ILLEGAL_OPERATION_ERR (CC_BSV_BASE_ERROR + 0x00000016) +/*! Illegal asset size. */ +#define CC_BSV_ILLEGAL_ASSET_SIZE_ERR (CC_BSV_BASE_ERROR + 0x00000017) +/*! Illegal asset value. */ +#define CC_BSV_ILLEGAL_ASSET_VAL_ERR (CC_BSV_BASE_ERROR + 0x00000018) +/*! Kpicv is locked. */ +#define CC_BSV_KPICV_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000019) +/*! Illegal SW version. */ +#define CC_BSV_ILLEGAL_SW_VERSION_ERR (CC_BSV_BASE_ERROR + 0x0000001A) +/*! AO write operation. */ +#define CC_BSV_AO_WRITE_FAILED_ERR (CC_BSV_BASE_ERROR + 0x0000001B) +/*! Chip state is already initialized. */ +#define CC_BSV_CHIP_INITIALIZED_ERR (CC_BSV_BASE_ERROR + 0x0000001C) +/*! SP is not enabled. */ +#define CC_BSV_SP_NOT_ENABLED_ERR (CC_BSV_BASE_ERROR + 0x0000001D) +/*! Production secure provisioning - header fields. */ +#define CC_BSV_PROD_PKG_HEADER_ERR (CC_BSV_BASE_ERROR + 0x0000001E) +/*! Production secure provisioning - header MAC. */ +#define CC_BSV_PROD_PKG_HEADER_MAC_ERR (CC_BSV_BASE_ERROR + 0x0000001F) +/*! Overrun buffer or size. */ +#define CC_BSV_OVERRUN_ERR (CC_BSV_BASE_ERROR + 0x00000020) +/*! Kceicv is locked. */ +#define CC_BSV_KCEICV_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000021) +/*! Chip indication is CHIP_STATE_ERROR. */ +#define CC_BSV_CHIP_INDICATION_ERR (CC_BSV_BASE_ERROR + 0x00000022) +/*! Device is locked in fatal error state. */ +#define CC_BSV_FATAL_ERR_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000023) +/*! Device has security disable feature enabled. */ +#define CC_BSV_SECURE_DISABLE_ERROR (CC_BSV_BASE_ERROR + 0x00000024) +/*! Device has Kcst in disabled state */ +#define CC_BSV_KCST_DISABLE_ERROR (CC_BSV_BASE_ERROR + 0x00000025) + + +/*! Illegal data-in pointer. */ +#define CC_BSV_CRYPTO_INVALID_DATA_IN_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000001) +/*! Illegal data-out pointer. */ +#define CC_BSV_CRYPTO_INVALID_DATA_OUT_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000002) +/*! Illegal data size. */ +#define CC_BSV_CRYPTO_INVALID_DATA_SIZE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000003) +/*! Illegal key type. */ +#define CC_BSV_CRYPTO_INVALID_KEY_TYPE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000004) +/*! Illegal key size. */ +#define CC_BSV_CRYPTO_INVALID_KEY_SIZE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000005) +/*! Invalid key pointer. */ +#define CC_BSV_CRYPTO_INVALID_KEY_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000006) +/*! Illegal key DMA type. */ +#define CC_BSV_CRYPTO_INVALID_KEY_DMA_TYPE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000007) +/*! Illegal IV pointer. */ +#define CC_BSV_CRYPTO_INVALID_IV_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000008) +/*! Illegal cipher mode. */ +#define CC_BSV_CRYPTO_INVALID_CIPHER_MODE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000009) +/*! Illegal result buffer pointer. */ +#define CC_BSV_CRYPTO_INVALID_RESULT_BUFFER_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000A) +/*! Invalid DMA type. */ +#define CC_BSV_CRYPTO_INVALID_DMA_TYPE_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000B) +/*! Invalid in/out buffers overlapping. */ +#define CC_BSV_CRYPTO_DATA_OUT_DATA_IN_OVERLAP_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000C) +/*! Invalid KDF label size. */ +#define CC_BSV_CRYPTO_ILLEGAL_KDF_LABEL_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000D) +/*! Invalid KDF Context size. */ +#define CC_BSV_CRYPTO_ILLEGAL_KDF_CONTEXT_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000E) +/*! Invalid CCM key. */ +#define CC_BSV_CCM_INVALID_KEY_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000f) +/*! Invalid CCM Nonce. */ +#define CC_BSV_CCM_INVALID_NONCE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000010) +/*! Invalid CCM associated data. */ +#define CC_BSV_CCM_INVALID_ASSOC_DATA_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000011) +/*! Invalid CCM text data. */ +#define CC_BSV_CCM_INVALID_TEXT_DATA_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000012) +/*! Invalid CCM-MAC buffer. */ +#define CC_BSV_CCM_INVALID_MAC_BUF_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000013) +/*! CCM-MAC comparison failed. */ +#define CC_BSV_CCM_TAG_LENGTH_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000014) +/*! CCM-MAC comparison failed. */ +#define CC_BSV_CCM_MAC_INVALID_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000015) +/*! Illegal flow mode. */ +#define CC_BSV_CRYPTO_INVALID_FLOW_MODE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000016) + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + + + diff --git a/include/drivers/arm/cryptocell/713/cc_address_defs.h b/include/drivers/arm/cryptocell/713/cc_address_defs.h new file mode 100644 index 0000000..0abc15c --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_address_defs.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_ADDRESS_DEFS_H +#define _CC_ADDRESS_DEFS_H + +/*! +@file +@brief This file contains general definitions. +*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cc_pal_types.h" + +/************************ Defines ******************************/ + +/** + * Address types within CC + */ +/*! Definition of DMA address type, can be 32 bits or 64 bits according to CryptoCell's HW. */ +typedef uint64_t CCDmaAddr_t; +/*! Definition of CryptoCell address type, can be 32 bits or 64 bits according to platform. */ +typedef uint64_t CCAddr_t; +/*! Definition of CC SRAM address type, can be 32 bits according to CryptoCell's HW. */ +typedef uint32_t CCSramAddr_t; + +/* + * CCSramAddr_t is being cast into pointer type which can be 64 bit. + */ +/*! Definition of MACRO that casts SRAM addresses to pointer types. */ +#define CCSramAddr2Ptr(sramAddr) ((uintptr_t)sramAddr) + +#ifdef __cplusplus +} +#endif + +#endif + +/** + @} + */ + + diff --git a/include/drivers/arm/cryptocell/713/cc_boot_defs.h b/include/drivers/arm/cryptocell/713/cc_boot_defs.h new file mode 100644 index 0000000..4d29a6d --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_boot_defs.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_BOOT_DEFS_H +#define _CC_BOOT_DEFS_H + +/*! + @file + @brief This file contains general definitions of types and enums of Boot APIs. + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*! Version counters value. */ +typedef enum { + + CC_SW_VERSION_TRUSTED = 0, /*!< Trusted counter. */ + CC_SW_VERSION_NON_TRUSTED, /*!< Non trusted counter. */ + CC_SW_VERSION_MAX = 0x7FFFFFFF /*!< Reserved */ +} CCSbSwVersionId_t; + +/*! The hash boot key definition. */ +typedef enum { + CC_SB_HASH_BOOT_KEY_0_128B = 0, /*!< Hbk0: 128-bit truncated SHA-256 digest of PubKB0. Used by ICV */ + CC_SB_HASH_BOOT_KEY_1_128B = 1, /*!< Hbk1: 128-bit truncated SHA-256 digest of PubKB1. Used by OEM */ + CC_SB_HASH_BOOT_KEY_256B = 2, /*!< Hbk: 256-bit SHA-256 digest of public key. */ + CC_SB_HASH_BOOT_NOT_USED = 0xF, /*!< Hbk is not used. */ + CC_SB_HASH_MAX_NUM = 0x7FFFFFFF, /*!< Reserved. */ +} CCSbPubKeyIndexType_t; + +/*! Chip state. */ +typedef enum { + CHIP_STATE_NOT_INITIALIZED = 0, /*! Chip is not initialized. */ + CHIP_STATE_TEST = 1, /*! Chip is in Production state. */ + CHIP_STATE_PRODUCTION = 2, /*! Chip is in Production state. */ + CHIP_STATE_ERROR = 3, /*! Chip is in Error state. */ +} CCBsvChipState_t; +#ifdef __cplusplus +} +#endif + +#endif /*_CC_BOOT_DEFS_H */ + +/** +@} + */ diff --git a/include/drivers/arm/cryptocell/713/cc_pal_types.h b/include/drivers/arm/cryptocell/713/cc_pal_types.h new file mode 100644 index 0000000..4ab3960 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_pal_types.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CC_PAL_TYPES_H +#define CC_PAL_TYPES_H + +/*! +@file +@brief This file contains platform-dependent definitions and types of the PAL layer. + +@defgroup cc_pal_types CryptoCell platform-dependent PAL layer definitions and types +@{ +@ingroup cc_pal + + @{ + @ingroup cc_pal + @} +*/ + +#include "cc_pal_types_plat.h" + +/*! Definition of Boolean type.*/ +typedef enum { + /*! Boolean false.*/ + CC_FALSE = 0, + /*! Boolean true.*/ + CC_TRUE = 1 +} CCBool_t; + +/*! Success. */ +#define CC_SUCCESS 0UL +/*! Failure. */ +#define CC_FAIL 1UL + +/*! Success (OK). */ +#define CC_OK 0 + +/*! This macro handles unused parameters in the code, to avoid compilation warnings. */ +#define CC_UNUSED_PARAM(prm) ((void)prm) + +/*! The maximal uint32 value.*/ +#define CC_MAX_UINT32_VAL (0xFFFFFFFF) + + +/* Minimal and Maximal macros */ +#ifdef min +/*! Definition for minimal calculation. */ +#define CC_MIN(a,b) min( a , b ) +#else +/*! Definition for minimal calculation. */ +#define CC_MIN( a , b ) ( ( (a) < (b) ) ? (a) : (b) ) +#endif + +#ifdef max +/*! Definition for maximal calculation. */ +#define CC_MAX(a,b) max( a , b ) +#else +/*! Definition for maximal calculation.. */ +#define CC_MAX( a , b ) ( ( (a) > (b) ) ? (a) : (b) ) +#endif + +/*! This macro calculates the number of full Bytes from bits, where seven bits are one Byte. */ +#define CALC_FULL_BYTES(numBits) ((numBits)/CC_BITS_IN_BYTE + (((numBits) & (CC_BITS_IN_BYTE-1)) > 0)) +/*! This macro calculates the number of full 32-bit words from bits where 31 bits are one word. */ +#define CALC_FULL_32BIT_WORDS(numBits) ((numBits)/CC_BITS_IN_32BIT_WORD + (((numBits) & (CC_BITS_IN_32BIT_WORD-1)) > 0)) +/*! This macro calculates the number of full 32-bit words from Bytes where three Bytes are one word. */ +#define CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) ((sizeBytes)/CC_32BIT_WORD_SIZE + (((sizeBytes) & (CC_32BIT_WORD_SIZE-1)) > 0)) +/*! This macro calculates the number of full 32-bit words from 64-bits dwords. */ +#define CALC_32BIT_WORDS_FROM_64BIT_DWORD(sizeWords) (sizeWords * CC_32BIT_WORD_IN_64BIT_DWORD) +/*! This macro rounds up bits to 32-bit words. */ +#define ROUNDUP_BITS_TO_32BIT_WORD(numBits) (CALC_FULL_32BIT_WORDS(numBits) * CC_BITS_IN_32BIT_WORD) +/*! This macro rounds up bits to Bytes. */ +#define ROUNDUP_BITS_TO_BYTES(numBits) (CALC_FULL_BYTES(numBits) * CC_BITS_IN_BYTE) +/*! This macro rounds up bytes to 32-bit words. */ +#define ROUNDUP_BYTES_TO_32BIT_WORD(sizeBytes) (CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) * CC_32BIT_WORD_SIZE) +/*! This macro calculates the number Bytes from words. */ +#define CALC_WORDS_TO_BYTES(numwords) ((numwords)*CC_32BIT_WORD_SIZE) +/*! Definition of 1 KB in Bytes. */ +#define CC_1K_SIZE_IN_BYTES 1024 +/*! Definition of number of bits in a Byte. */ +#define CC_BITS_IN_BYTE 8 +/*! Definition of number of bits in a 32-bits word. */ +#define CC_BITS_IN_32BIT_WORD 32 +/*! Definition of number of Bytes in a 32-bits word. */ +#define CC_32BIT_WORD_SIZE 4 +/*! Definition of number of 32-bits words in a 64-bits dword. */ +#define CC_32BIT_WORD_IN_64BIT_DWORD 2 + + +#endif + +/** +@} + */ + + + diff --git a/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h b/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h new file mode 100644 index 0000000..9848472 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_pal_types_plat.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*! @file +@brief This file contains basic type definitions that are platform-dependent. +*/ +#ifndef _CC_PAL_TYPES_PLAT_H +#define _CC_PAL_TYPES_PLAT_H +/* Host specific types for standard (ISO-C99) compilant platforms */ + +#include +#include + +typedef uint32_t CCStatus; + +#define CCError_t CCStatus +#define CC_INFINITE 0xFFFFFFFF + +#define CEXPORT_C +#define CIMPORT_C + +#endif /*_CC_PAL_TYPES_PLAT_H*/ diff --git a/include/drivers/arm/cryptocell/713/cc_pka_hw_plat_defs.h b/include/drivers/arm/cryptocell/713/cc_pka_hw_plat_defs.h new file mode 100644 index 0000000..1a1bce0 --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_pka_hw_plat_defs.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_PKA_HW_PLAT_DEFS_H +#define _CC_PKA_HW_PLAT_DEFS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#include "cc_pal_types.h" +/*! +@file +@brief Contains the enums and definitions that are used in the PKA code (definitions that are platform dependent). +*/ + +/*! The size of the PKA engine word. */ +#define CC_PKA_WORD_SIZE_IN_BITS 128 + +/*! The maximal supported size of modulus in RSA in bits. */ +#define CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS 4096 +/*! The maximal supported size of key-generation in RSA in bits. */ +#define CC_RSA_MAX_KEY_GENERATION_HW_SIZE_BITS 4096 + +/*! Secure boot/debug certificate RSA public modulus key size in bits. */ +#if (KEY_SIZE == 3072) + #define BSV_CERT_RSA_KEY_SIZE_IN_BITS 3072 +#else + #define BSV_CERT_RSA_KEY_SIZE_IN_BITS 2048 +#endif +/*! Secure boot/debug certificate RSA public modulus key size in bytes. */ +#define BSV_CERT_RSA_KEY_SIZE_IN_BYTES (BSV_CERT_RSA_KEY_SIZE_IN_BITS/CC_BITS_IN_BYTE) +/*! Secure boot/debug certificate RSA public modulus key size in words. */ +#define BSV_CERT_RSA_KEY_SIZE_IN_WORDS (BSV_CERT_RSA_KEY_SIZE_IN_BITS/CC_BITS_IN_32BIT_WORD) + +/*! The maximal count of extra bits in PKA operations. */ +#define PKA_EXTRA_BITS 8 +/*! The number of memory registers in PKA operations. */ +#define PKA_MAX_COUNT_OF_PHYS_MEM_REGS 32 + +/*! Size of buffer for Barrett modulus tag in words. */ +#define RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS 5 +/*! Size of buffer for Barrett modulus tag in bytes. */ +#define RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES (RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE) + + + +#ifdef __cplusplus +} +#endif + +#endif //_CC_PKA_HW_PLAT_DEFS_H + +/** + @} + */ + diff --git a/include/drivers/arm/cryptocell/713/cc_sec_defs.h b/include/drivers/arm/cryptocell/713/cc_sec_defs.h new file mode 100644 index 0000000..8fb698f --- /dev/null +++ b/include/drivers/arm/cryptocell/713/cc_sec_defs.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_SEC_DEFS_H +#define _CC_SEC_DEFS_H + +/*! +@file +@brief This file contains general definitions and types. +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cc_pal_types.h" + +/*! Hashblock size in words. */ +#define HASH_BLOCK_SIZE_IN_WORDS 16 +/*! Hash - SHA2 results in words. */ +#define HASH_RESULT_SIZE_IN_WORDS 8 +/*! Hash - SHA2 results in bytes. */ +#define HASH_RESULT_SIZE_IN_BYTES 32 + +/*! Definition for hash result array. */ +typedef uint32_t CCHashResult_t[HASH_RESULT_SIZE_IN_WORDS]; + +/*! Definition for converting pointer to Host address. */ +#define CONVERT_TO_ADDR(ptr) (unsigned long)ptr + +/*! Definition for converting pointer to SRAM address. */ +#define CONVERT_TO_SRAM_ADDR(ptr) (0xFFFFFFFF & ptr) + +/*! The data size of the signed SW image, in bytes. */ +/*!\internal ContentCertImageRecord_t includes: HS(8W) + 64-b dstAddr(2W) + imgSize(1W) + isCodeEncUsed(1W) */ +#define SW_REC_SIGNED_DATA_SIZE_IN_BYTES 48 + +/*! The data size of the unsigned SW image, in bytes. */ +/*!\internal CCSbSwImgAddData_t includes: 64-b srcAddr(2W)*/ +#define SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES 8 + +/*! The additional data size - storage address and length of the unsigned SW image, in words. */ +#define SW_REC_NONE_SIGNED_DATA_SIZE_IN_WORDS SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES/CC_32BIT_WORD_SIZE + +/*! The additional data section size, in bytes. */ +#define CC_SB_MAX_SIZE_ADDITIONAL_DATA_BYTES 128 + +/*! Indication of whether or not to load the SW image to memory. */ +#define CC_SW_COMP_NO_MEM_LOAD_INDICATION 0xFFFFFFFFFFFFFFFFUL + +/*! Indication of product version, stored in certificate version field. */ +#define CC_SB_CERT_VERSION_PROJ_PRD 0x713 + +#ifdef __cplusplus +} +#endif + +#endif + +/** +@} + */ + + + diff --git a/include/drivers/arm/cryptocell/cc_rotpk.h b/include/drivers/arm/cryptocell/cc_rotpk.h new file mode 100644 index 0000000..9398496 --- /dev/null +++ b/include/drivers/arm/cryptocell/cc_rotpk.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _CC_ROTPK_H +#define _CC_ROTPK_H + +int cc_get_rotpk_hash(unsigned char *dst, unsigned int len, + unsigned int *flags); + +#endif diff --git a/include/drivers/arm/css/css_mhu.h b/include/drivers/arm/css/css_mhu.h new file mode 100644 index 0000000..ff04ae4 --- /dev/null +++ b/include/drivers/arm/css/css_mhu.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_MHU_H +#define CSS_MHU_H + +#include + +void mhu_secure_message_start(unsigned int slot_id); +void mhu_secure_message_send(unsigned int slot_id); +uint32_t mhu_secure_message_wait(void); +void mhu_secure_message_end(unsigned int slot_id); + +void mhu_secure_init(void); + +#endif /* CSS_MHU_H */ diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h new file mode 100644 index 0000000..88302fd --- /dev/null +++ b/include/drivers/arm/css/css_mhu_doorbell.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_MHU_DOORBELL_H +#define CSS_MHU_DOORBELL_H + +#include + +#include + +/* MHUv2 Frame Base Mask */ +#define MHU_V2_FRAME_BASE_MASK UL(~0xFFF) + +/* MHUv2 Control Registers Offsets */ +#define MHU_V2_MSG_NO_CAP_OFFSET UL(0xF80) +#define MHU_V2_ACCESS_REQ_OFFSET UL(0xF88) +#define MHU_V2_ACCESS_READY_OFFSET UL(0xF8C) + +#define SENDER_REG_STAT(_channel) (0x20 * (_channel)) +#define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC) + +/* Helper macro to ring doorbell */ +#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask) do { \ + uint32_t db = mmio_read_32(addr) & (preserve_mask); \ + mmio_write_32(addr, db | (modify_mask)); \ + } while (0) + +#define MHU_V2_ACCESS_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) + +#define MHU_V2_CLEAR_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) + +#define MHU_V2_IS_ACCESS_READY(addr) \ + (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) + +struct scmi_channel_plat_info; +void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info); +void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info); + +#endif /* CSS_MHU_DOORBELL_H */ diff --git a/include/drivers/arm/css/css_scp.h b/include/drivers/arm/css/css_scp.h new file mode 100644 index 0000000..2b506ea --- /dev/null +++ b/include/drivers/arm/css/css_scp.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_SCP_H +#define CSS_SCP_H + +#include + +#include + +#include + +/* Forward declarations */ +struct psci_power_state; + +/* API for power management by SCP */ +int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie); +void css_scp_suspend(const struct psci_power_state *target_state); +void css_scp_off(const struct psci_power_state *target_state); +void css_scp_on(u_register_t mpidr); +int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level); +void __dead2 css_scp_sys_shutdown(void); +void __dead2 css_scp_sys_reboot(void); +void __dead2 css_scp_system_off(int state); + +/* API for SCP Boot Image transfer. Return 0 on success, -1 on error */ +int css_scp_boot_image_xfer(void *image, unsigned int image_size); + +/* + * API to wait for SCP to signal till it's ready after booting the transferred + * image. + */ +int css_scp_boot_ready(void); + +#if CSS_LOAD_SCP_IMAGES + +/* + * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 + * usually resides except when ARM_BL31_IN_DRAM is + * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into fw_config. + */ +CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); +CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); + +CASSERT(SCP_BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); +CASSERT(SCP_BL2U_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); +#endif + +#endif /* CSS_SCP_H */ diff --git a/include/drivers/arm/css/css_scpi.h b/include/drivers/arm/css/css_scpi.h new file mode 100644 index 0000000..68fc60a --- /dev/null +++ b/include/drivers/arm/css/css_scpi.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_SCPI_H +#define CSS_SCPI_H + +#include +#include + +/* + * An SCPI command consists of a header and a payload. + * The following structure describes the header. It is 64-bit long. + */ +typedef struct { + /* Command ID */ + uint32_t id : 7; + /* Set ID. Identifies whether this is a standard or extended command. */ + uint32_t set : 1; + /* Sender ID to match a reply. The value is sender specific. */ + uint32_t sender : 8; + /* Size of the payload in bytes (0 - 511) */ + uint32_t size : 9; + uint32_t reserved : 7; + /* + * Status indicating the success of a command. + * See the enum below. + */ + uint32_t status; +} scpi_cmd_t; + +typedef enum { + SCPI_SET_NORMAL = 0, /* Normal SCPI commands */ + SCPI_SET_EXTENDED /* Extended SCPI commands */ +} scpi_set_t; + +enum { + SCP_OK = 0, /* Success */ + SCP_E_PARAM, /* Invalid parameter(s) */ + SCP_E_ALIGN, /* Invalid alignment */ + SCP_E_SIZE, /* Invalid size */ + SCP_E_HANDLER, /* Invalid handler or callback */ + SCP_E_ACCESS, /* Invalid access or permission denied */ + SCP_E_RANGE, /* Value out of range */ + SCP_E_TIMEOUT, /* Time out has ocurred */ + SCP_E_NOMEM, /* Invalid memory area or pointer */ + SCP_E_PWRSTATE, /* Invalid power state */ + SCP_E_SUPPORT, /* Feature not supported or disabled */ + SCPI_E_DEVICE, /* Device error */ + SCPI_E_BUSY, /* Device is busy */ +}; + +typedef uint32_t scpi_status_t; + +typedef enum { + SCPI_CMD_SCP_READY = 0x01, + SCPI_CMD_SET_CSS_POWER_STATE = 0x03, + SCPI_CMD_GET_CSS_POWER_STATE = 0x04, + SCPI_CMD_SYS_POWER_STATE = 0x05 +} scpi_command_t; + +/* + * Macros to parse SCP response to GET_CSS_POWER_STATE command + * + * [3:0] : cluster ID + * [7:4] : cluster state: 0 = on; 3 = off; rest are reserved + * [15:8]: on/off state for individual CPUs in the cluster + * + * Payload is in little-endian + */ +#define CLUSTER_ID(_resp) ((_resp) & 0xf) +#define CLUSTER_POWER_STATE(_resp) (((_resp) >> 4) & 0xf) + +/* Result is a bit mask of CPU on/off states in the cluster */ +#define CPU_POWER_STATE(_resp) (((_resp) >> 8) & 0xff) + +/* + * For GET_CSS_POWER_STATE, SCP returns the power states of every cluster. The + * size of response depends on the number of clusters in the system. The + * SCP-to-AP payload contains 2 bytes per cluster. Make sure the response is + * large enough to contain power states of a given cluster + */ +#define CHECK_RESPONSE(_resp, _clus) \ + (_resp.size >= (((_clus) + 1) * 2)) + +typedef enum { + scpi_power_on = 0, + scpi_power_retention = 1, + scpi_power_off = 3, +} scpi_power_state_t; + +typedef enum { + scpi_system_shutdown = 0, + scpi_system_reboot = 1, + scpi_system_reset = 2 +} scpi_system_state_t; + +int scpi_wait_ready(void); +void scpi_set_css_power_state(unsigned int mpidr, + scpi_power_state_t cpu_state, + scpi_power_state_t cluster_state, + scpi_power_state_t css_state); +int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p, + unsigned int *cluster_state_p); +uint32_t scpi_sys_power_state(scpi_system_state_t system_state); + +#endif /* CSS_SCPI_H */ diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h new file mode 100644 index 0000000..9dd08e5 --- /dev/null +++ b/include/drivers/arm/css/scmi.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCMI_H +#define SCMI_H + +#include +#include + +#include +#include +#include + +/* Supported SCMI Protocol Versions */ +#define SCMI_AP_CORE_PROTO_VER MAKE_SCMI_VERSION(1, 0) +#define SCMI_PWR_DMN_PROTO_VER MAKE_SCMI_VERSION(2, 0) +#define SCMI_SYS_PWR_PROTO_VER MAKE_SCMI_VERSION(1, 0) + +#define GET_SCMI_MAJOR_VER(ver) (((ver) >> 16) & 0xffff) +#define GET_SCMI_MINOR_VER(ver) ((ver) & 0xffff) + +#define MAKE_SCMI_VERSION(maj, min) \ + ((((maj) & 0xffff) << 16) | ((min) & 0xffff)) + +/* + * Check that the driver's version is same or higher than the reported SCMI + * version. We accept lower major version numbers, as all affected protocols + * so far stay backwards compatible. This might need to be revisited in the + * future. + */ +#define is_scmi_version_compatible(drv, scmi) \ + ((GET_SCMI_MAJOR_VER(drv) > GET_SCMI_MAJOR_VER(scmi)) || \ + ((GET_SCMI_MAJOR_VER(drv) == GET_SCMI_MAJOR_VER(scmi)) && \ + (GET_SCMI_MINOR_VER(drv) <= GET_SCMI_MINOR_VER(scmi)))) + +/* SCMI Protocol identifiers */ +#define SCMI_PWR_DMN_PROTO_ID 0x11 +#define SCMI_SYS_PWR_PROTO_ID 0x12 +/* The AP core protocol is a CSS platform-specific extension */ +#define SCMI_AP_CORE_PROTO_ID 0x90 + +/* Mandatory messages IDs for all SCMI protocols */ +#define SCMI_PROTO_VERSION_MSG 0x0 +#define SCMI_PROTO_ATTR_MSG 0x1 +#define SCMI_PROTO_MSG_ATTR_MSG 0x2 + +/* SCMI power domain management protocol message IDs */ +#define SCMI_PWR_STATE_SET_MSG 0x4 +#define SCMI_PWR_STATE_GET_MSG 0x5 + +/* SCMI system power management protocol message IDs */ +#define SCMI_SYS_PWR_STATE_SET_MSG 0x3 +#define SCMI_SYS_PWR_STATE_GET_MSG 0x4 + +/* SCMI AP core protocol message IDs */ +#define SCMI_AP_CORE_RESET_ADDR_SET_MSG 0x3 +#define SCMI_AP_CORE_RESET_ADDR_GET_MSG 0x4 + +/* Helper macros for system power management protocol commands */ + +/* + * Macros to describe the bit-fields of the `attribute` of system power domain + * protocol PROTOCOL_MSG_ATTRIBUTE message. + */ +#define SYS_PWR_ATTR_WARM_RESET_SHIFT 31 +#define SCMI_SYS_PWR_WARM_RESET_SUPPORTED (1U << SYS_PWR_ATTR_WARM_RESET_SHIFT) + +#define SYS_PWR_ATTR_SUSPEND_SHIFT 30 +#define SCMI_SYS_PWR_SUSPEND_SUPPORTED (1 << SYS_PWR_ATTR_SUSPEND_SHIFT) + +/* + * Macros to describe the bit-fields of the `flags` parameter of system power + * domain protocol SYSTEM_POWER_STATE_SET message. + */ +#define SYS_PWR_SET_GRACEFUL_REQ_SHIFT 0 +#define SCMI_SYS_PWR_GRACEFUL_REQ (1 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT) +#define SCMI_SYS_PWR_FORCEFUL_REQ (0 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT) + +/* + * Macros to describe the `system_state` parameter of system power + * domain protocol SYSTEM_POWER_STATE_SET message. + */ +#define SCMI_SYS_PWR_SHUTDOWN 0x0 +#define SCMI_SYS_PWR_COLD_RESET 0x1 +#define SCMI_SYS_PWR_WARM_RESET 0x2 +#define SCMI_SYS_PWR_POWER_UP 0x3 +#define SCMI_SYS_PWR_SUSPEND 0x4 + +/* + * Macros to describe the bit-fields of the `attribute` of AP core protocol + * AP_CORE_RESET_ADDR set/get messages. + */ +#define SCMI_AP_CORE_LOCK_ATTR_SHIFT 0x0 +#define SCMI_AP_CORE_LOCK_ATTR (1U << SCMI_AP_CORE_LOCK_ATTR_SHIFT) + +/* SCMI Error code definitions */ +#define SCMI_E_QUEUED 1 +#define SCMI_E_SUCCESS 0 +#define SCMI_E_NOT_SUPPORTED -1 +#define SCMI_E_INVALID_PARAM -2 +#define SCMI_E_DENIED -3 +#define SCMI_E_NOT_FOUND -4 +#define SCMI_E_OUT_OF_RANGE -5 +#define SCMI_E_BUSY -6 + +/* + * SCMI driver platform information. The details of the doorbell mechanism + * can be found in the SCMI specification. + */ +typedef struct scmi_channel_plat_info { + /* SCMI mailbox memory */ + uintptr_t scmi_mbx_mem; + /* The door bell register address */ + uintptr_t db_reg_addr; + /* The bit mask that need to be preserved when ringing doorbell */ + uint32_t db_preserve_mask; + /* The bit mask that need to be set to ring doorbell */ + uint32_t db_modify_mask; + /* The handler for ringing doorbell */ + void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info); + /* cookie is unused now. But added for future enhancements. */ + void *cookie; +} scmi_channel_plat_info_t; + + +#if HW_ASSISTED_COHERENCY +typedef spinlock_t scmi_lock_t; +#else +typedef bakery_lock_t scmi_lock_t; +#endif + +/* + * Structure to represent an SCMI channel. + */ +typedef struct scmi_channel { + scmi_channel_plat_info_t *info; + /* The lock for channel access */ + scmi_lock_t *lock; + /* Indicate whether the channel is initialized */ + int is_initialized; +} scmi_channel_t; + +/* External Common API */ +void *scmi_init(scmi_channel_t *ch); +int scmi_proto_msg_attr(void *p, uint32_t proto_id, uint32_t command_id, + uint32_t *attr); +int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version); + +/* + * Power domain protocol commands. Refer to the SCMI specification for more + * details on these commands. + */ +int scmi_pwr_state_set(void *p, uint32_t domain_id, uint32_t scmi_pwr_state); +int scmi_pwr_state_get(void *p, uint32_t domain_id, uint32_t *scmi_pwr_state); + +/* + * System power management protocol commands. Refer SCMI specification for more + * details on these commands. + */ +int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state); +int scmi_sys_pwr_state_get(void *p, uint32_t *system_state); + +/* SCMI AP core configuration protocol commands. */ +int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr); +int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr); + +/* API to get the platform specific SCMI channel information. */ +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id); + +/* API to override default PSCI callbacks for platforms that support SCMI. */ +const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops); + +#endif /* SCMI_H */ diff --git a/include/drivers/arm/css/sds.h b/include/drivers/arm/css/sds.h new file mode 100644 index 0000000..db4cbaa --- /dev/null +++ b/include/drivers/arm/css/sds.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SDS_H +#define SDS_H + +/* SDS Structure Identifier defines */ +/* AP CPU INFO defines */ +#define SDS_AP_CPU_INFO_STRUCT_ID 1 +#define SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET 0x0 +#define SDS_AP_CPU_INFO_PRIMARY_CPUID_SIZE 0x4 + +/* ROM Firmware Version defines */ +#define SDS_ROM_VERSION_STRUCT_ID 2 +#define SDS_ROM_VERSION_OFFSET 0x0 +#define SDS_ROM_VERSION_SIZE 0x4 + +/* RAM Firmware version defines */ +#define SDS_RAM_VERSION_STRUCT_ID 3 +#define SDS_RAM_VERSION_OFFSET 0x0 +#define SDS_RAM_VERSION_SIZE 0x4 + +/* Platform Identity defines */ +#define SDS_PLATFORM_IDENTITY_STRUCT_ID 4 +#define SDS_PLATFORM_IDENTITY_ID_OFFSET 0x0 +#define SDS_PLATFORM_IDENTITY_ID_SIZE 0x4 +#define SDS_PLATFORM_IDENTITY_ID_CONFIG_SHIFT 28 +#define SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH 4 +#define SDS_PLATFORM_IDENTITY_ID_CONFIG_MASK \ + ((1 << SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH) - 1) + +#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_OFFSET 0x4 +#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_SIZE 0x4 + +/* Reset Syndrome defines */ +#define SDS_RESET_SYNDROME_STRUCT_ID 5 +#define SDS_RESET_SYNDROME_OFFSET 0 +#define SDS_RESET_SYNDROME_SIZE 4 +#define SDS_RESET_SYNDROME_POW_ON_RESET_BIT (1 << 0) +#define SDS_RESET_SYNDROME_SCP_WD_RESET_BIT (1 << 1) +#define SDS_RESET_SYNDROME_AP_WD_RESET_BIT (1 << 2) +#define SDS_RESET_SYNDROME_SYS_RESET_REQ_BIT (1 << 3) +#define SDS_RESET_SYNDROME_M3_LOCKUP_BIT (1 << 4) + +/* SCP Firmware Feature Availability defines */ +#define SDS_FEATURE_AVAIL_STRUCT_ID 6 +#define SDS_FEATURE_AVAIL_OFFSET 0 +#define SDS_FEATURE_AVAIL_SIZE 4 +#define SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT (1 << 0) +#define SDS_FEATURE_AVAIL_DMC_READY_BIT (1 << 1) +#define SDS_FEATURE_AVAIL_MSG_IF_READY_BIT (1 << 2) + +/* SCP BL2 Image Metadata defines */ +#define SDS_SCP_IMG_STRUCT_ID 9 +#define SDS_SCP_IMG_FLAG_OFFSET 0 +#define SDS_SCP_IMG_FLAG_SIZE 4 +#define SDS_SCP_IMG_VALID_FLAG_BIT (1 << 0) +#define SDS_SCP_IMG_ADDR_OFFSET 4 +#define SDS_SCP_IMG_ADDR_SIZE 4 +#define SDS_SCP_IMG_SIZE_OFFSET 8 +#define SDS_SCP_IMG_SIZE_SIZE 4 + +/* SDS Driver Error Codes */ +#define SDS_OK 0 +#define SDS_ERR_FAIL -1 +#define SDS_ERR_INVALID_PARAMS -2 +#define SDS_ERR_STRUCT_NOT_FOUND -3 +#define SDS_ERR_STRUCT_NOT_FINALIZED -4 + +#ifndef __ASSEMBLER__ +#include +#include + +typedef enum { + SDS_ACCESS_MODE_NON_CACHED, + SDS_ACCESS_MODE_CACHED, +} sds_access_mode_t; + +int sds_init(void); +int sds_struct_exists(unsigned int structure_id); +int sds_struct_read(uint32_t structure_id, unsigned int fld_off, void *data, + size_t size, sds_access_mode_t mode); +int sds_struct_write(uint32_t structure_id, unsigned int fld_off, void *data, + size_t size, sds_access_mode_t mode); +#endif /*__ASSEMBLER__ */ + +#endif /* SDS_H */ diff --git a/include/drivers/arm/dcc.h b/include/drivers/arm/dcc.h new file mode 100644 index 0000000..1f1fd03 --- /dev/null +++ b/include/drivers/arm/dcc.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021, Xilinx Inc. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DCC_H +#define DCC_H + +#include +#include + +/* + * Initialize a new dcc console instance and register it with the console + * framework. + */ +int console_dcc_register(void); + +#endif /* DCC */ diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h new file mode 100644 index 0000000..dbaf16c --- /dev/null +++ b/include/drivers/arm/ethosn.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ETHOSN_H +#define ETHOSN_H + +#include + +/* Function numbers */ +#define ETHOSN_FNUM_VERSION U(0x50) +#define ETHOSN_FNUM_IS_SEC U(0x51) +#define ETHOSN_FNUM_HARD_RESET U(0x52) +#define ETHOSN_FNUM_SOFT_RESET U(0x53) +/* 0x54-0x5F reserved for future use */ + +/* SMC64 function IDs */ +#define ETHOSN_FID_64(func_num) U(0xC2000000 | func_num) +#define ETHOSN_FID_VERSION_64 ETHOSN_FID_64(ETHOSN_FNUM_VERSION) +#define ETHOSN_FID_IS_SEC_64 ETHOSN_FID_64(ETHOSN_FNUM_IS_SEC) +#define ETHOSN_FID_HARD_RESET_64 ETHOSN_FID_64(ETHOSN_FNUM_HARD_RESET) +#define ETHOSN_FID_SOFT_RESET_64 ETHOSN_FID_64(ETHOSN_FNUM_SOFT_RESET) + +/* SMC32 function IDs */ +#define ETHOSN_FID_32(func_num) U(0x82000000 | func_num) +#define ETHOSN_FID_VERSION_32 ETHOSN_FID_32(ETHOSN_FNUM_VERSION) +#define ETHOSN_FID_IS_SEC_32 ETHOSN_FID_32(ETHOSN_FNUM_IS_SEC) +#define ETHOSN_FID_HARD_RESET_32 ETHOSN_FID_32(ETHOSN_FNUM_HARD_RESET) +#define ETHOSN_FID_SOFT_RESET_32 ETHOSN_FID_32(ETHOSN_FNUM_SOFT_RESET) + +#define ETHOSN_NUM_SMC_CALLS 8 + +/* Macro to identify function calls */ +#define ETHOSN_FID_MASK U(0xFFF0) +#define ETHOSN_FID_VALUE U(0x50) +#define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE) + +/* Service version */ +#define ETHOSN_VERSION_MAJOR U(2) +#define ETHOSN_VERSION_MINOR U(0) + +/* Return codes for function calls */ +#define ETHOSN_SUCCESS 0 +#define ETHOSN_NOT_SUPPORTED -1 +/* -2 Reserved for NOT_REQUIRED */ +/* -3 Reserved for INVALID_PARAMETER */ +#define ETHOSN_FAILURE -4 +#define ETHOSN_UNKNOWN_CORE_ADDRESS -5 +#define ETHOSN_UNKNOWN_ALLOCATOR_IDX -6 + +uintptr_t ethosn_smc_handler(uint32_t smc_fid, + u_register_t core_addr, + u_register_t asset_alloc_idx, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags); + +#endif /* ETHOSN_H */ diff --git a/include/drivers/arm/fvp/fvp_pwrc.h b/include/drivers/arm/fvp/fvp_pwrc.h new file mode 100644 index 0000000..39e2516 --- /dev/null +++ b/include/drivers/arm/fvp/fvp_pwrc.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FVP_PWRC_H +#define FVP_PWRC_H + +/* FVP Power controller register offset etc */ +#define PPOFFR_OFF U(0x0) +#define PPONR_OFF U(0x4) +#define PCOFFR_OFF U(0x8) +#define PWKUPR_OFF U(0xc) +#define PSYSR_OFF U(0x10) + +#define PWKUPR_WEN BIT_32(31) + +#define PSYSR_AFF_L2 BIT_32(31) +#define PSYSR_AFF_L1 BIT_32(30) +#define PSYSR_AFF_L0 BIT_32(29) +#define PSYSR_WEN BIT_32(28) +#define PSYSR_PC BIT_32(27) +#define PSYSR_PP BIT_32(26) + +#define PSYSR_WK_SHIFT 24 +#define PSYSR_WK_WIDTH 0x2 +#define PSYSR_WK_MASK ((1U << PSYSR_WK_WIDTH) - 1U) +#define PSYSR_WK(x) ((x) >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK + +#define WKUP_COLD U(0x0) +#define WKUP_RESET U(0x1) +#define WKUP_PPONR U(0x2) +#define WKUP_GICREQ U(0x3) + +#define PSYSR_INVALID U(0xffffffff) + +#ifndef __ASSEMBLER__ + +#include + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ +void fvp_pwrc_write_pcoffr(u_register_t mpidr); +void fvp_pwrc_write_ppoffr(u_register_t mpidr); +void fvp_pwrc_write_pponr(u_register_t mpidr); +void fvp_pwrc_set_wen(u_register_t mpidr); +void fvp_pwrc_clr_wen(u_register_t mpidr); +unsigned int fvp_pwrc_read_psysr(u_register_t mpidr); +unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr); + +#endif /*__ASSEMBLER__*/ + +#endif /* FVP_PWRC_H */ diff --git a/include/drivers/arm/gic600_multichip.h b/include/drivers/arm/gic600_multichip.h new file mode 100644 index 0000000..bda406b --- /dev/null +++ b/include/drivers/arm/gic600_multichip.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GIC600_MULTICHIP_H +#define GIC600_MULTICHIP_H + +#include + +/* + * GIC-600 microarchitecture supports coherent multichip environments containing + * up to 16 chips. + */ +#define GIC600_MAX_MULTICHIP 16 + +/* SPI IDs array consist of min and max ids */ +#define GIC600_SPI_IDS_SIZE 2 + +/******************************************************************************* + * GIC-600 multichip data structure describes platform specific attributes + * related to GIC-600 multichip. Platform port is expected to define these + * attributes to initialize the multichip related registers and create + * successful connections between the GIC-600s in a multichip system. + * + * The 'rt_owner_base' field contains the base address of the GIC Distributor + * which owns the routing table. + * + * The 'rt_owner' field contains the chip number which owns the routing table. + * Chip number or chip_id starts from 0. + * + * The 'chip_count' field contains the total number of chips in a multichip + * system. This should match the number of entries in 'chip_addrs' and 'spi_ids' + * fields. + * + * The 'chip_addrs' field contains array of chip addresses. These addresses are + * implementation specific values. + * + * The 'spi_ids' field contains array of minimum and maximum SPI interrupt ids + * that each chip owns. Note that SPI interrupt ids can range from 32 to 960 and + * it should be group of 32 (i.e., SPI minimum and (SPI maximum + 1) should be + * a multiple of 32). If a chip doesn't own any SPI interrupts a value of {0, 0} + * should be passed. + ******************************************************************************/ +struct gic600_multichip_data { + uintptr_t rt_owner_base; + unsigned int rt_owner; + unsigned int chip_count; + uint64_t chip_addrs[GIC600_MAX_MULTICHIP]; + unsigned int spi_ids[GIC600_MAX_MULTICHIP][GIC600_SPI_IDS_SIZE]; +}; + +void gic600_multichip_init(struct gic600_multichip_data *multichip_data); +#endif /* GIC600_MULTICHIP_H */ diff --git a/include/drivers/arm/gic600ae_fmu.h b/include/drivers/arm/gic600ae_fmu.h new file mode 100644 index 0000000..88b87b9 --- /dev/null +++ b/include/drivers/arm/gic600ae_fmu.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GIC600AE_FMU_H +#define GIC600AE_FMU_H + +/******************************************************************************* + * GIC600-AE FMU register offsets and constants + ******************************************************************************/ +#define GICFMU_ERRFR_LO U(0x000) +#define GICFMU_ERRFR_HI U(0x004) +#define GICFMU_ERRCTLR_LO U(0x008) +#define GICFMU_ERRCTLR_HI U(0x00C) +#define GICFMU_ERRSTATUS_LO U(0x010) +#define GICFMU_ERRSTATUS_HI U(0x014) +#define GICFMU_ERRGSR_LO U(0xE00) +#define GICFMU_ERRGSR_HI U(0xE04) +#define GICFMU_KEY U(0xEA0) +#define GICFMU_PINGCTLR U(0xEA4) +#define GICFMU_PINGNOW U(0xEA8) +#define GICFMU_SMEN U(0xEB0) +#define GICFMU_SMINJERR U(0xEB4) +#define GICFMU_PINGMASK_LO U(0xEC0) +#define GICFMU_PINGMASK_HI U(0xEC4) +#define GICFMU_STATUS U(0xF00) +#define GICFMU_ERRIDR U(0xFC8) + +/* ERRCTLR bits */ +#define FMU_ERRCTLR_ED_BIT BIT(0) +#define FMU_ERRCTLR_CE_EN_BIT BIT(1) +#define FMU_ERRCTLR_UI_BIT BIT(2) +#define FMU_ERRCTLR_CI_BIT BIT(3) + +/* SMEN constants */ +#define FMU_SMEN_BLK_SHIFT U(8) +#define FMU_SMEN_SMID_SHIFT U(24) +#define FMU_SMEN_EN_BIT BIT(0) + +/* Error record IDs */ +#define FMU_BLK_GICD U(0) +#define FMU_BLK_SPICOL U(1) +#define FMU_BLK_WAKERQ U(2) +#define FMU_BLK_ITS0 U(4) +#define FMU_BLK_ITS1 U(5) +#define FMU_BLK_ITS2 U(6) +#define FMU_BLK_ITS3 U(7) +#define FMU_BLK_ITS4 U(8) +#define FMU_BLK_ITS5 U(9) +#define FMU_BLK_ITS6 U(10) +#define FMU_BLK_ITS7 U(11) +#define FMU_BLK_PPI0 U(12) +#define FMU_BLK_PPI1 U(13) +#define FMU_BLK_PPI2 U(14) +#define FMU_BLK_PPI3 U(15) +#define FMU_BLK_PPI4 U(16) +#define FMU_BLK_PPI5 U(17) +#define FMU_BLK_PPI6 U(18) +#define FMU_BLK_PPI7 U(19) +#define FMU_BLK_PPI8 U(20) +#define FMU_BLK_PPI9 U(21) +#define FMU_BLK_PPI10 U(22) +#define FMU_BLK_PPI11 U(23) +#define FMU_BLK_PPI12 U(24) +#define FMU_BLK_PPI13 U(25) +#define FMU_BLK_PPI14 U(26) +#define FMU_BLK_PPI15 U(27) +#define FMU_BLK_PPI16 U(28) +#define FMU_BLK_PPI17 U(29) +#define FMU_BLK_PPI18 U(30) +#define FMU_BLK_PPI19 U(31) +#define FMU_BLK_PPI20 U(32) +#define FMU_BLK_PPI21 U(33) +#define FMU_BLK_PPI22 U(34) +#define FMU_BLK_PPI23 U(35) +#define FMU_BLK_PPI24 U(36) +#define FMU_BLK_PPI25 U(37) +#define FMU_BLK_PPI26 U(38) +#define FMU_BLK_PPI27 U(39) +#define FMU_BLK_PPI28 U(40) +#define FMU_BLK_PPI29 U(41) +#define FMU_BLK_PPI30 U(42) +#define FMU_BLK_PPI31 U(43) +#define FMU_BLK_PRESENT_MASK U(0xFFFFFFFFFFF) + +/* Safety Mechamism limit */ +#define FMU_SMID_GICD_MAX U(33) +#define FMU_SMID_PPI_MAX U(12) +#define FMU_SMID_ITS_MAX U(14) +#define FMU_SMID_SPICOL_MAX U(5) +#define FMU_SMID_WAKERQ_MAX U(2) + +/* MBIST Safety Mechanism ID */ +#define GICD_MBIST_REQ_ERROR U(23) +#define GICD_FMU_CLKGATE_ERROR U(33) +#define PPI_MBIST_REQ_ERROR U(10) +#define PPI_FMU_CLKGATE_ERROR U(12) +#define ITS_MBIST_REQ_ERROR U(13) +#define ITS_FMU_CLKGATE_ERROR U(14) + +/* ERRSTATUS bits */ +#define FMU_ERRSTATUS_BLKID_SHIFT U(32) +#define FMU_ERRSTATUS_BLKID_MASK U(0xFF) +#define FMU_ERRSTATUS_V_BIT BIT(30) +#define FMU_ERRSTATUS_UE_BIT BIT(29) +#define FMU_ERRSTATUS_OV_BIT BIT(27) +#define FMU_ERRSTATUS_CE_BITS (BIT(25) | BIT(24)) +#define FMU_ERRSTATUS_CLEAR (FMU_ERRSTATUS_V_BIT | FMU_ERRSTATUS_UE_BIT | \ + FMU_ERRSTATUS_OV_BIT | FMU_ERRSTATUS_CE_BITS) +#define FMU_ERRSTATUS_IERR_MASK U(0xFF) +#define FMU_ERRSTATUS_IERR_SHIFT U(8) +#define FMU_ERRSTATUS_SERR_MASK U(0xFF) + +/* PINGCTLR constants */ +#define FMU_PINGCTLR_INTDIFF_SHIFT U(16) +#define FMU_PINGCTLR_TIMEOUTVAL_SHIFT U(4) +#define FMU_PINGCTLR_EN_BIT BIT(0) + +#ifndef __ASSEMBLER__ + +#include + +#include + +/******************************************************************************* + * GIC600 FMU EL3 driver API + ******************************************************************************/ +uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n); +uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n); +uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n); +uint64_t gic_fmu_read_errgsr(uintptr_t base); +uint32_t gic_fmu_read_pingctlr(uintptr_t base); +uint32_t gic_fmu_read_pingnow(uintptr_t base); +uint64_t gic_fmu_read_pingmask(uintptr_t base); +uint32_t gic_fmu_read_status(uintptr_t base); +uint32_t gic_fmu_read_erridr(uintptr_t base); +void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val); +void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val); +void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val); +void gic_fmu_write_pingnow(uintptr_t base, uint32_t val); +void gic_fmu_write_smen(uintptr_t base, uint32_t val); +void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val); +void gic_fmu_write_pingmask(uintptr_t base, uint64_t val); +void gic_fmu_disable_all_sm_blkid(uintptr_t base, unsigned int blkid); + +void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask, bool errctlr_ce_en, bool errctlr_ue_en); +void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask, + unsigned int timeout_val, unsigned int interval_diff); +void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid); +int gic600_fmu_probe(uint64_t base, int *probe_data); +int gic600_fmu_ras_handler(uint64_t base, int probe_data); + +#endif /* __ASSEMBLER__ */ + +#endif /* GIC600AE_FMU_H */ diff --git a/include/drivers/arm/gic_common.h b/include/drivers/arm/gic_common.h new file mode 100644 index 0000000..dc23721 --- /dev/null +++ b/include/drivers/arm/gic_common.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GIC_COMMON_H +#define GIC_COMMON_H + +#include + +/******************************************************************************* + * GIC Distributor interface general definitions + ******************************************************************************/ +/* Constants to categorise interrupts */ +#define MIN_SGI_ID U(0) +#define MIN_SEC_SGI_ID U(8) +#define MIN_PPI_ID U(16) +#define MIN_SPI_ID U(32) +#define MAX_SPI_ID U(1019) + +#define TOTAL_SPI_INTR_NUM (MAX_SPI_ID - MIN_SPI_ID + U(1)) +#define TOTAL_PCPU_INTR_NUM (MIN_SPI_ID - MIN_SGI_ID) + +/* Mask for the priority field common to all GIC interfaces */ +#define GIC_PRI_MASK U(0xff) + +/* Mask for the configuration field common to all GIC interfaces */ +#define GIC_CFG_MASK U(0x3) + +/* Constant to indicate a spurious interrupt in all GIC versions */ +#define GIC_SPURIOUS_INTERRUPT U(1023) + +/* Interrupt configurations: 2-bit fields with LSB reserved */ +#define GIC_INTR_CFG_LEVEL (0 << 1) +#define GIC_INTR_CFG_EDGE (1 << 1) + +/* Highest possible interrupt priorities */ +#define GIC_HIGHEST_SEC_PRIORITY U(0x00) +#define GIC_HIGHEST_NS_PRIORITY U(0x80) + +/******************************************************************************* + * Common GIC Distributor interface register offsets + ******************************************************************************/ +#define GICD_CTLR U(0x0) +#define GICD_TYPER U(0x4) +#define GICD_IIDR U(0x8) +#define GICD_IGROUPR U(0x80) +#define GICD_ISENABLER U(0x100) +#define GICD_ICENABLER U(0x180) +#define GICD_ISPENDR U(0x200) +#define GICD_ICPENDR U(0x280) +#define GICD_ISACTIVER U(0x300) +#define GICD_ICACTIVER U(0x380) +#define GICD_IPRIORITYR U(0x400) +#define GICD_ICFGR U(0xc00) +#define GICD_NSACR U(0xe00) + +/* GICD_CTLR bit definitions */ +#define CTLR_ENABLE_G0_SHIFT 0 +#define CTLR_ENABLE_G0_MASK U(0x1) +#define CTLR_ENABLE_G0_BIT BIT_32(CTLR_ENABLE_G0_SHIFT) + +/******************************************************************************* + * Common GIC Distributor interface register constants + ******************************************************************************/ +#define PIDR2_ARCH_REV_SHIFT 4 +#define PIDR2_ARCH_REV_MASK U(0xf) + +/* GIC revision as reported by PIDR2.ArchRev register field */ +#define ARCH_REV_GICV1 U(0x1) +#define ARCH_REV_GICV2 U(0x2) +#define ARCH_REV_GICV3 U(0x3) +#define ARCH_REV_GICV4 U(0x4) + +#define IGROUPR_SHIFT 5 +#define ISENABLER_SHIFT 5 +#define ICENABLER_SHIFT ISENABLER_SHIFT +#define ISPENDR_SHIFT 5 +#define ICPENDR_SHIFT ISPENDR_SHIFT +#define ISACTIVER_SHIFT 5 +#define ICACTIVER_SHIFT ISACTIVER_SHIFT +#define IPRIORITYR_SHIFT 2 +#define ITARGETSR_SHIFT 2 +#define ICFGR_SHIFT 4 +#define NSACR_SHIFT 4 + +/* GICD_TYPER shifts and masks */ +#define TYPER_IT_LINES_NO_SHIFT U(0) +#define TYPER_IT_LINES_NO_MASK U(0x1f) + +/* Value used to initialize Normal world interrupt priorities four at a time */ +#define GICD_IPRIORITYR_DEF_VAL \ + (GIC_HIGHEST_NS_PRIORITY | \ + (GIC_HIGHEST_NS_PRIORITY << 8) | \ + (GIC_HIGHEST_NS_PRIORITY << 16) | \ + (GIC_HIGHEST_NS_PRIORITY << 24)) + +#endif /* GIC_COMMON_H */ diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h new file mode 100644 index 0000000..cfc168d --- /dev/null +++ b/include/drivers/arm/gicv2.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GICV2_H +#define GICV2_H + +#include +#include + +/******************************************************************************* + * GICv2 miscellaneous definitions + ******************************************************************************/ + +/* Interrupt group definitions */ +#define GICV2_INTR_GROUP0 U(0) +#define GICV2_INTR_GROUP1 U(1) + +/* Interrupt IDs reported by the HPPIR and IAR registers */ +#define PENDING_G1_INTID U(1022) + +/* GICv2 can only target up to 8 PEs */ +#define GICV2_MAX_TARGET_PE U(8) + +/******************************************************************************* + * GICv2 specific Distributor interface register offsets and constants. + ******************************************************************************/ +#define GICD_ITARGETSR U(0x800) +#define GICD_SGIR U(0xF00) +#define GICD_CPENDSGIR U(0xF10) +#define GICD_SPENDSGIR U(0xF20) + +/* + * Some GICv2 implementations violate the specification and have this register + * at a different address. Allow overriding it in platform_def.h as workaround. + */ +#ifndef GICD_PIDR2_GICV2 +#define GICD_PIDR2_GICV2 U(0xFE8) +#endif + +#define ITARGETSR_SHIFT 2 +#define GIC_TARGET_CPU_MASK U(0xff) + +#define CPENDSGIR_SHIFT 2 +#define SPENDSGIR_SHIFT CPENDSGIR_SHIFT + +#define SGIR_TGTLSTFLT_SHIFT 24 +#define SGIR_TGTLSTFLT_MASK U(0x3) +#define SGIR_TGTLST_SHIFT 16 +#define SGIR_TGTLST_MASK U(0xff) +#define SGIR_NSATT (U(0x1) << 16) +#define SGIR_INTID_MASK ULL(0xf) + +#define SGIR_TGT_SPECIFIC U(0) + +#define GICV2_SGIR_VALUE(tgt_lst_flt, tgt, nsatt, intid) \ + ((((tgt_lst_flt) & SGIR_TGTLSTFLT_MASK) << SGIR_TGTLSTFLT_SHIFT) | \ + (((tgt) & SGIR_TGTLST_MASK) << SGIR_TGTLST_SHIFT) | \ + ((nsatt) ? SGIR_NSATT : U(0)) | \ + ((intid) & SGIR_INTID_MASK)) + +/******************************************************************************* + * GICv2 specific CPU interface register offsets and constants. + ******************************************************************************/ +/* Physical CPU Interface registers */ +#define GICC_CTLR U(0x0) +#define GICC_PMR U(0x4) +#define GICC_BPR U(0x8) +#define GICC_IAR U(0xC) +#define GICC_EOIR U(0x10) +#define GICC_RPR U(0x14) +#define GICC_HPPIR U(0x18) +#define GICC_AHPPIR U(0x28) +#define GICC_IIDR U(0xFC) +#define GICC_DIR U(0x1000) +#define GICC_PRIODROP GICC_EOIR + +/* GICC_CTLR bit definitions */ +#define EOI_MODE_NS BIT_32(10) +#define EOI_MODE_S BIT_32(9) +#define IRQ_BYP_DIS_GRP1 BIT_32(8) +#define FIQ_BYP_DIS_GRP1 BIT_32(7) +#define IRQ_BYP_DIS_GRP0 BIT_32(6) +#define FIQ_BYP_DIS_GRP0 BIT_32(5) +#define CBPR BIT_32(4) +#define FIQ_EN_SHIFT 3 +#define FIQ_EN_BIT BIT_32(FIQ_EN_SHIFT) +#define ACK_CTL BIT_32(2) + +/* GICC_IIDR bit masks and shifts */ +#define GICC_IIDR_PID_SHIFT 20 +#define GICC_IIDR_ARCH_SHIFT 16 +#define GICC_IIDR_REV_SHIFT 12 +#define GICC_IIDR_IMP_SHIFT 0 + +#define GICC_IIDR_PID_MASK U(0xfff) +#define GICC_IIDR_ARCH_MASK U(0xf) +#define GICC_IIDR_REV_MASK U(0xf) +#define GICC_IIDR_IMP_MASK U(0xfff) + +/* HYP view virtual CPU Interface registers */ +#define GICH_CTL U(0x0) +#define GICH_VTR U(0x4) +#define GICH_ELRSR0 U(0x30) +#define GICH_ELRSR1 U(0x34) +#define GICH_APR0 U(0xF0) +#define GICH_LR_BASE U(0x100) + +/* Virtual CPU Interface registers */ +#define GICV_CTL U(0x0) +#define GICV_PRIMASK U(0x4) +#define GICV_BP U(0x8) +#define GICV_INTACK U(0xC) +#define GICV_EOI U(0x10) +#define GICV_RUNNINGPRI U(0x14) +#define GICV_HIGHESTPEND U(0x18) +#define GICV_DEACTIVATE U(0x1000) + +/* GICD_CTLR bit definitions */ +#define CTLR_ENABLE_G1_SHIFT 1 +#define CTLR_ENABLE_G1_MASK U(0x1) +#define CTLR_ENABLE_G1_BIT BIT_32(CTLR_ENABLE_G1_SHIFT) + +/* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */ +#define INT_ID_MASK U(0x3ff) + +#ifndef __ASSEMBLER__ + +#include +#include +#include + +#include + +/******************************************************************************* + * This structure describes some of the implementation defined attributes of + * the GICv2 IP. It is used by the platform port to specify these attributes + * in order to initialize the GICv2 driver. The attributes are described + * below. + * + * The 'gicd_base' field contains the base address of the Distributor interface + * programmer's view. + * + * The 'gicc_base' field contains the base address of the CPU Interface + * programmer's view. + * + * The 'target_masks' is a pointer to an array containing 'target_masks_num' + * elements. The GIC driver will populate the array with per-PE target mask to + * use to when targeting interrupts. + * + * The 'interrupt_props' field is a pointer to an array that enumerates secure + * interrupts and their properties. If this field is not NULL, both + * 'g0_interrupt_array' and 'g1s_interrupt_array' fields are ignored. + * + * The 'interrupt_props_num' field contains the number of entries in the + * 'interrupt_props' array. If this field is non-zero, 'g0_interrupt_num' is + * ignored. + ******************************************************************************/ +typedef struct gicv2_driver_data { + uintptr_t gicd_base; + uintptr_t gicc_base; + unsigned int *target_masks; + unsigned int target_masks_num; + const interrupt_prop_t *interrupt_props; + unsigned int interrupt_props_num; +} gicv2_driver_data_t; + +/******************************************************************************* + * Function prototypes + ******************************************************************************/ +void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data); +void gicv2_distif_init(void); +void gicv2_pcpu_distif_init(void); +void gicv2_cpuif_enable(void); +void gicv2_cpuif_disable(void); +unsigned int gicv2_is_fiq_enabled(void); +unsigned int gicv2_get_pending_interrupt_type(void); +unsigned int gicv2_get_pending_interrupt_id(void); +unsigned int gicv2_acknowledge_interrupt(void); +void gicv2_end_of_interrupt(unsigned int id); +unsigned int gicv2_get_interrupt_group(unsigned int id); +unsigned int gicv2_get_running_priority(void); +void gicv2_set_pe_target_mask(unsigned int proc_num); +unsigned int gicv2_get_interrupt_active(unsigned int id); +void gicv2_enable_interrupt(unsigned int id); +void gicv2_disable_interrupt(unsigned int id); +void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority); +void gicv2_set_interrupt_type(unsigned int id, unsigned int type); +void gicv2_raise_sgi(int sgi_num, bool ns, int proc_num); +void gicv2_set_spi_routing(unsigned int id, int proc_num); +void gicv2_set_interrupt_pending(unsigned int id); +void gicv2_clear_interrupt_pending(unsigned int id); +unsigned int gicv2_set_pmr(unsigned int mask); +void gicv2_interrupt_set_cfg(unsigned int id, unsigned int cfg); + +#endif /* __ASSEMBLER__ */ +#endif /* GICV2_H */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h new file mode 100644 index 0000000..5bb22fd --- /dev/null +++ b/include/drivers/arm/gicv3.h @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GICV3_H +#define GICV3_H + +/******************************************************************************* + * GICv3 and 3.1 miscellaneous definitions + ******************************************************************************/ +/* Interrupt group definitions */ +#define INTR_GROUP1S U(0) +#define INTR_GROUP0 U(1) +#define INTR_GROUP1NS U(2) + +/* Interrupt IDs reported by the HPPIR and IAR registers */ +#define PENDING_G1S_INTID U(1020) +#define PENDING_G1NS_INTID U(1021) + +/* Constant to categorize LPI interrupt */ +#define MIN_LPI_ID U(8192) + +/* GICv3 can only target up to 16 PEs with SGI */ +#define GICV3_MAX_SGI_TARGETS U(16) + +/* PPIs INTIDs 16-31 */ +#define MAX_PPI_ID U(31) + +#if GIC_EXT_INTID + +/* GICv3.1 extended PPIs INTIDs 1056-1119 */ +#define MIN_EPPI_ID U(1056) +#define MAX_EPPI_ID U(1119) + +/* Total number of GICv3.1 EPPIs */ +#define TOTAL_EPPI_INTR_NUM (MAX_EPPI_ID - MIN_EPPI_ID + U(1)) + +/* Total number of GICv3.1 PPIs and EPPIs */ +#define TOTAL_PRIVATE_INTR_NUM (TOTAL_PCPU_INTR_NUM + TOTAL_EPPI_INTR_NUM) + +/* GICv3.1 extended SPIs INTIDs 4096 - 5119 */ +#define MIN_ESPI_ID U(4096) +#define MAX_ESPI_ID U(5119) + +/* Total number of GICv3.1 ESPIs */ +#define TOTAL_ESPI_INTR_NUM (MAX_ESPI_ID - MIN_ESPI_ID + U(1)) + +/* Total number of GICv3.1 SPIs and ESPIs */ +#define TOTAL_SHARED_INTR_NUM (TOTAL_SPI_INTR_NUM + TOTAL_ESPI_INTR_NUM) + +/* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */ +#define IS_SGI_PPI(id) (((id) <= MAX_PPI_ID) || \ + (((id) >= MIN_EPPI_ID) && \ + ((id) <= MAX_EPPI_ID))) + +/* SPIs: 32-1019, ESPIs: 4096-5119 */ +#define IS_SPI(id) ((((id) >= MIN_SPI_ID) && \ + ((id) <= MAX_SPI_ID)) || \ + (((id) >= MIN_ESPI_ID) && \ + ((id) <= MAX_ESPI_ID))) +#else /* GICv3 */ + +/* Total number of GICv3 PPIs */ +#define TOTAL_PRIVATE_INTR_NUM TOTAL_PCPU_INTR_NUM + +/* Total number of GICv3 SPIs */ +#define TOTAL_SHARED_INTR_NUM TOTAL_SPI_INTR_NUM + +/* SGIs: 0-15, PPIs: 16-31 */ +#define IS_SGI_PPI(id) ((id) <= MAX_PPI_ID) + +/* SPIs: 32-1019 */ +#define IS_SPI(id) (((id) >= MIN_SPI_ID) && ((id) <= MAX_SPI_ID)) + +#endif /* GIC_EXT_INTID */ + +#define GIC_REV(r, p) ((r << 4) | p) + +/******************************************************************************* + * GICv3 and 3.1 specific Distributor interface register offsets and constants + ******************************************************************************/ +#define GICD_TYPER2 U(0x0c) +#define GICD_STATUSR U(0x10) +#define GICD_SETSPI_NSR U(0x40) +#define GICD_CLRSPI_NSR U(0x48) +#define GICD_SETSPI_SR U(0x50) +#define GICD_CLRSPI_SR U(0x58) +#define GICD_IGRPMODR U(0xd00) +#define GICD_IGROUPRE U(0x1000) +#define GICD_ISENABLERE U(0x1200) +#define GICD_ICENABLERE U(0x1400) +#define GICD_ISPENDRE U(0x1600) +#define GICD_ICPENDRE U(0x1800) +#define GICD_ISACTIVERE U(0x1a00) +#define GICD_ICACTIVERE U(0x1c00) +#define GICD_IPRIORITYRE U(0x2000) +#define GICD_ICFGRE U(0x3000) +#define GICD_IGRPMODRE U(0x3400) +#define GICD_NSACRE U(0x3600) +/* + * GICD_IROUTER register is at 0x6000 + 8n, where n is the interrupt ID + * and n >= 32, making the effective offset as 0x6100 + */ +#define GICD_IROUTER U(0x6000) +#define GICD_IROUTERE U(0x8000) + +#define GICD_PIDR0_GICV3 U(0xffe0) +#define GICD_PIDR1_GICV3 U(0xffe4) +#define GICD_PIDR2_GICV3 U(0xffe8) + +#define IGRPMODR_SHIFT 5 + +/* GICD_CTLR bit definitions */ +#define CTLR_ENABLE_G1NS_SHIFT 1 +#define CTLR_ENABLE_G1S_SHIFT 2 +#define CTLR_ARE_S_SHIFT 4 +#define CTLR_ARE_NS_SHIFT 5 +#define CTLR_DS_SHIFT 6 +#define CTLR_E1NWF_SHIFT 7 +#define GICD_CTLR_RWP_SHIFT 31 + +#define CTLR_ENABLE_G1NS_MASK U(0x1) +#define CTLR_ENABLE_G1S_MASK U(0x1) +#define CTLR_ARE_S_MASK U(0x1) +#define CTLR_ARE_NS_MASK U(0x1) +#define CTLR_DS_MASK U(0x1) +#define CTLR_E1NWF_MASK U(0x1) +#define GICD_CTLR_RWP_MASK U(0x1) + +#define CTLR_ENABLE_G1NS_BIT BIT_32(CTLR_ENABLE_G1NS_SHIFT) +#define CTLR_ENABLE_G1S_BIT BIT_32(CTLR_ENABLE_G1S_SHIFT) +#define CTLR_ARE_S_BIT BIT_32(CTLR_ARE_S_SHIFT) +#define CTLR_ARE_NS_BIT BIT_32(CTLR_ARE_NS_SHIFT) +#define CTLR_DS_BIT BIT_32(CTLR_DS_SHIFT) +#define CTLR_E1NWF_BIT BIT_32(CTLR_E1NWF_SHIFT) +#define GICD_CTLR_RWP_BIT BIT_32(GICD_CTLR_RWP_SHIFT) + +/* GICD_IROUTER shifts and masks */ +#define IROUTER_SHIFT 0 +#define IROUTER_IRM_SHIFT 31 +#define IROUTER_IRM_MASK U(0x1) + +#define GICV3_IRM_PE U(0) +#define GICV3_IRM_ANY U(1) + +#define NUM_OF_DIST_REGS 30 + +/* GICD_TYPER shifts and masks */ +#define TYPER_ESPI U(1 << 8) +#define TYPER_DVIS U(1 << 18) +#define TYPER_ESPI_RANGE_MASK U(0x1f) +#define TYPER_ESPI_RANGE_SHIFT U(27) +#define TYPER_ESPI_RANGE U(TYPER_ESPI_MASK << TYPER_ESPI_SHIFT) + +/******************************************************************************* + * Common GIC Redistributor interface registers & constants + ******************************************************************************/ +#define GICR_V4_PCPUBASE_SHIFT 0x12 +#define GICR_V3_PCPUBASE_SHIFT 0x11 +#define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */ +#define GICR_CTLR U(0x0) +#define GICR_IIDR U(0x04) +#define GICR_TYPER U(0x08) +#define GICR_STATUSR U(0x10) +#define GICR_WAKER U(0x14) +#define GICR_PROPBASER U(0x70) +#define GICR_PENDBASER U(0x78) +#define GICR_IGROUPR0 (GICR_SGIBASE_OFFSET + U(0x80)) +#define GICR_ISENABLER0 (GICR_SGIBASE_OFFSET + U(0x100)) +#define GICR_ICENABLER0 (GICR_SGIBASE_OFFSET + U(0x180)) +#define GICR_ISPENDR0 (GICR_SGIBASE_OFFSET + U(0x200)) +#define GICR_ICPENDR0 (GICR_SGIBASE_OFFSET + U(0x280)) +#define GICR_ISACTIVER0 (GICR_SGIBASE_OFFSET + U(0x300)) +#define GICR_ICACTIVER0 (GICR_SGIBASE_OFFSET + U(0x380)) +#define GICR_IPRIORITYR (GICR_SGIBASE_OFFSET + U(0x400)) +#define GICR_ICFGR0 (GICR_SGIBASE_OFFSET + U(0xc00)) +#define GICR_ICFGR1 (GICR_SGIBASE_OFFSET + U(0xc04)) +#define GICR_IGRPMODR0 (GICR_SGIBASE_OFFSET + U(0xd00)) +#define GICR_NSACR (GICR_SGIBASE_OFFSET + U(0xe00)) + +#define GICR_IGROUPR GICR_IGROUPR0 +#define GICR_ISENABLER GICR_ISENABLER0 +#define GICR_ICENABLER GICR_ICENABLER0 +#define GICR_ISPENDR GICR_ISPENDR0 +#define GICR_ICPENDR GICR_ICPENDR0 +#define GICR_ISACTIVER GICR_ISACTIVER0 +#define GICR_ICACTIVER GICR_ICACTIVER0 +#define GICR_ICFGR GICR_ICFGR0 +#define GICR_IGRPMODR GICR_IGRPMODR0 + +/* GICR_CTLR bit definitions */ +#define GICR_CTLR_UWP_SHIFT 31 +#define GICR_CTLR_UWP_MASK U(0x1) +#define GICR_CTLR_UWP_BIT BIT_32(GICR_CTLR_UWP_SHIFT) +#define GICR_CTLR_DPG1S_SHIFT 26 +#define GICR_CTLR_DPG1S_MASK U(0x1) +#define GICR_CTLR_DPG1S_BIT BIT_32(GICR_CTLR_DPG1S_SHIFT) +#define GICR_CTLR_DPG1NS_SHIFT 25 +#define GICR_CTLR_DPG1NS_MASK U(0x1) +#define GICR_CTLR_DPG1NS_BIT BIT_32(GICR_CTLR_DPG1NS_SHIFT) +#define GICR_CTLR_DPG0_SHIFT 24 +#define GICR_CTLR_DPG0_MASK U(0x1) +#define GICR_CTLR_DPG0_BIT BIT_32(GICR_CTLR_DPG0_SHIFT) +#define GICR_CTLR_RWP_SHIFT 3 +#define GICR_CTLR_RWP_MASK U(0x1) +#define GICR_CTLR_RWP_BIT BIT_32(GICR_CTLR_RWP_SHIFT) +#define GICR_CTLR_EN_LPIS_BIT BIT_32(0) + +/* GICR_WAKER bit definitions */ +#define WAKER_CA_SHIFT 2 +#define WAKER_PS_SHIFT 1 + +#define WAKER_CA_MASK U(0x1) +#define WAKER_PS_MASK U(0x1) + +#define WAKER_CA_BIT BIT_32(WAKER_CA_SHIFT) +#define WAKER_PS_BIT BIT_32(WAKER_PS_SHIFT) + +/* GICR_TYPER bit definitions */ +#define TYPER_AFF_VAL_SHIFT 32 +#define TYPER_PROC_NUM_SHIFT 8 +#define TYPER_LAST_SHIFT 4 +#define TYPER_VLPI_SHIFT 1 + +#define TYPER_AFF_VAL_MASK U(0xffffffff) +#define TYPER_PROC_NUM_MASK U(0xffff) +#define TYPER_LAST_MASK U(0x1) + +#define TYPER_LAST_BIT BIT_32(TYPER_LAST_SHIFT) +#define TYPER_VLPI_BIT BIT_32(TYPER_VLPI_SHIFT) + +#define TYPER_PPI_NUM_SHIFT U(27) +#define TYPER_PPI_NUM_MASK U(0x1f) + +/* GICR_IIDR bit definitions */ +#define IIDR_PRODUCT_ID_MASK U(0xff) +#define IIDR_VARIANT_MASK U(0xf) +#define IIDR_REV_MASK U(0xf) +#define IIDR_IMPLEMENTER_MASK U(0xfff) +#define IIDR_PRODUCT_ID_SHIFT 24 +#define IIDR_VARIANT_SHIFT 16 +#define IIDR_REV_SHIFT 12 +#define IIDR_IMPLEMENTER_SHIFT 0 +#define IIDR_PRODUCT_ID_BIT BIT_32(IIDR_PRODUCT_ID_SHIFT) +#define IIDR_VARIANT_BIT BIT_32(IIDR_VARIANT_SHIFT) +#define IIDR_REV_BIT BIT_32(IIDR_REVISION_SHIFT) +#define IIDR_IMPLEMENTER_BIT BIT_32(IIDR_IMPLEMENTER_SHIFT) + +#define IIDR_MODEL_MASK (IIDR_PRODUCT_ID_MASK << IIDR_PRODUCT_ID_SHIFT | \ + IIDR_IMPLEMENTER_MASK << IIDR_IMPLEMENTER_SHIFT) + +#define GIC_PRODUCT_ID_GIC600 U(0x2) +#define GIC_PRODUCT_ID_GIC600AE U(0x3) +#define GIC_PRODUCT_ID_GIC700 U(0x4) + +/* + * Note that below revisions and variants definations are as per GIC600/GIC600AE + * specification. + */ +#define GIC_REV_P0 U(0x1) +#define GIC_REV_P1 U(0x3) +#define GIC_REV_P2 U(0x4) +#define GIC_REV_P3 U(0x5) +#define GIC_REV_P4 U(0x6) +#define GIC_REV_P6 U(0x7) + +#define GIC_VARIANT_R0 U(0x0) +#define GIC_VARIANT_R1 U(0x1) +#define GIC_VARIANT_R2 U(0x2) + +/******************************************************************************* + * GICv3 and 3.1 CPU interface registers & constants + ******************************************************************************/ +/* ICC_SRE bit definitions */ +#define ICC_SRE_EN_BIT BIT_32(3) +#define ICC_SRE_DIB_BIT BIT_32(2) +#define ICC_SRE_DFB_BIT BIT_32(1) +#define ICC_SRE_SRE_BIT BIT_32(0) + +/* ICC_IGRPEN1_EL3 bit definitions */ +#define IGRPEN1_EL3_ENABLE_G1NS_SHIFT 0 +#define IGRPEN1_EL3_ENABLE_G1S_SHIFT 1 + +#define IGRPEN1_EL3_ENABLE_G1NS_BIT BIT_32(IGRPEN1_EL3_ENABLE_G1NS_SHIFT) +#define IGRPEN1_EL3_ENABLE_G1S_BIT BIT_32(IGRPEN1_EL3_ENABLE_G1S_SHIFT) + +/* ICC_IGRPEN0_EL1 bit definitions */ +#define IGRPEN1_EL1_ENABLE_G0_SHIFT 0 +#define IGRPEN1_EL1_ENABLE_G0_BIT BIT_32(IGRPEN1_EL1_ENABLE_G0_SHIFT) + +/* ICC_HPPIR0_EL1 bit definitions */ +#define HPPIR0_EL1_INTID_SHIFT 0 +#define HPPIR0_EL1_INTID_MASK U(0xffffff) + +/* ICC_HPPIR1_EL1 bit definitions */ +#define HPPIR1_EL1_INTID_SHIFT 0 +#define HPPIR1_EL1_INTID_MASK U(0xffffff) + +/* ICC_IAR0_EL1 bit definitions */ +#define IAR0_EL1_INTID_SHIFT 0 +#define IAR0_EL1_INTID_MASK U(0xffffff) + +/* ICC_IAR1_EL1 bit definitions */ +#define IAR1_EL1_INTID_SHIFT 0 +#define IAR1_EL1_INTID_MASK U(0xffffff) + +/* ICC SGI macros */ +#define SGIR_TGT_MASK ULL(0xffff) +#define SGIR_AFF1_SHIFT 16 +#define SGIR_INTID_SHIFT 24 +#define SGIR_INTID_MASK ULL(0xf) +#define SGIR_AFF2_SHIFT 32 +#define SGIR_IRM_SHIFT 40 +#define SGIR_IRM_MASK ULL(0x1) +#define SGIR_AFF3_SHIFT 48 +#define SGIR_AFF_MASK ULL(0xff) + +#define SGIR_IRM_TO_AFF U(0) + +#define GICV3_SGIR_VALUE(_aff3, _aff2, _aff1, _intid, _irm, _tgt) \ + ((((uint64_t) (_aff3) & SGIR_AFF_MASK) << SGIR_AFF3_SHIFT) | \ + (((uint64_t) (_irm) & SGIR_IRM_MASK) << SGIR_IRM_SHIFT) | \ + (((uint64_t) (_aff2) & SGIR_AFF_MASK) << SGIR_AFF2_SHIFT) | \ + (((_intid) & SGIR_INTID_MASK) << SGIR_INTID_SHIFT) | \ + (((_aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \ + ((_tgt) & SGIR_TGT_MASK)) + +/***************************************************************************** + * GICv3 and 3.1 ITS registers and constants + *****************************************************************************/ +#define GITS_CTLR U(0x0) +#define GITS_IIDR U(0x4) +#define GITS_TYPER U(0x8) +#define GITS_CBASER U(0x80) +#define GITS_CWRITER U(0x88) +#define GITS_CREADR U(0x90) +#define GITS_BASER U(0x100) + +/* GITS_CTLR bit definitions */ +#define GITS_CTLR_ENABLED_BIT BIT_32(0) +#define GITS_CTLR_QUIESCENT_BIT BIT_32(1) + +#define GITS_TYPER_VSGI BIT_64(39) + +#ifndef __ASSEMBLER__ + +#include +#include + +#include +#include +#include +#include + +typedef enum { + GICV3_G1S, + GICV3_G1NS, + GICV3_G0 +} gicv3_irq_group_t; + +static inline uintptr_t gicv3_redist_size(uint64_t typer_val) +{ +#if GIC_ENABLE_V4_EXTN + if ((typer_val & TYPER_VLPI_BIT) != 0U) { + return 1U << GICR_V4_PCPUBASE_SHIFT; + } else { + return 1U << GICR_V3_PCPUBASE_SHIFT; + } +#else + return 1U << GICR_V3_PCPUBASE_SHIFT; +#endif +} + +unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame); + +static inline bool gicv3_is_intr_id_special_identifier(unsigned int id) +{ + return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT); +} + +/******************************************************************************* + * Helper GICv3 and 3.1 macros for SEL1 + ******************************************************************************/ +static inline uint32_t gicv3_acknowledge_interrupt_sel1(void) +{ + return (uint32_t)read_icc_iar1_el1() & IAR1_EL1_INTID_MASK; +} + +static inline uint32_t gicv3_get_pending_interrupt_id_sel1(void) +{ + return (uint32_t)read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK; +} + +static inline void gicv3_end_of_interrupt_sel1(unsigned int id) +{ + /* + * Interrupt request deassertion from peripheral to GIC happens + * by clearing interrupt condition by a write to the peripheral + * register. It is desired that the write transfer is complete + * before the core tries to change GIC state from 'AP/Active' to + * a new state on seeing 'EOI write'. + * Since ICC interface writes are not ordered against Device + * memory writes, a barrier is required to ensure the ordering. + * The dsb will also ensure *completion* of previous writes with + * DEVICE nGnRnE attribute. + */ + dsbishst(); + write_icc_eoir1_el1(id); +} + +/******************************************************************************* + * Helper GICv3 macros for EL3 + ******************************************************************************/ +static inline uint32_t gicv3_acknowledge_interrupt(void) +{ + return (uint32_t)read_icc_iar0_el1() & IAR0_EL1_INTID_MASK; +} + +static inline void gicv3_end_of_interrupt(unsigned int id) +{ + /* + * Interrupt request deassertion from peripheral to GIC happens + * by clearing interrupt condition by a write to the peripheral + * register. It is desired that the write transfer is complete + * before the core tries to change GIC state from 'AP/Active' to + * a new state on seeing 'EOI write'. + * Since ICC interface writes are not ordered against Device + * memory writes, a barrier is required to ensure the ordering. + * The dsb will also ensure *completion* of previous writes with + * DEVICE nGnRnE attribute. + */ + dsbishst(); + return write_icc_eoir0_el1(id); +} + +/* + * This macro returns the total number of GICD/GICR registers corresponding to + * the register name + */ +#define GICD_NUM_REGS(reg_name) \ + DIV_ROUND_UP_2EVAL(TOTAL_SHARED_INTR_NUM, (1 << reg_name##_SHIFT)) + +#define GICR_NUM_REGS(reg_name) \ + DIV_ROUND_UP_2EVAL(TOTAL_PRIVATE_INTR_NUM, (1 << reg_name##_SHIFT)) + +/* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */ +#define INT_ID_MASK U(0xffffff) + +/******************************************************************************* + * This structure describes some of the implementation defined attributes of the + * GICv3 IP. It is used by the platform port to specify these attributes in order + * to initialise the GICV3 driver. The attributes are described below. + * + * The 'gicd_base' field contains the base address of the Distributor interface + * programmer's view. + * + * The 'gicr_base' field contains the base address of the Re-distributor + * interface programmer's view. + * + * The 'interrupt_props' field is a pointer to an array that enumerates secure + * interrupts and their properties. If this field is not NULL, both + * 'g0_interrupt_array' and 'g1s_interrupt_array' fields are ignored. + * + * The 'interrupt_props_num' field contains the number of entries in the + * 'interrupt_props' array. If this field is non-zero, both 'g0_interrupt_num' + * and 'g1s_interrupt_num' are ignored. + * + * The 'rdistif_num' field contains the number of Redistributor interfaces the + * GIC implements. This is equal to the number of CPUs or CPU interfaces + * instantiated in the GIC. + * + * The 'rdistif_base_addrs' field is a pointer to an array that has an entry for + * storing the base address of the Redistributor interface frame of each CPU in + * the system. The size of the array = 'rdistif_num'. The base addresses are + * detected during driver initialisation. + * + * The 'mpidr_to_core_pos' field is a pointer to a hash function which the + * driver will use to convert an MPIDR value to a linear core index. This index + * will be used for accessing the 'rdistif_base_addrs' array. This is an + * optional field. A GICv3 implementation maps each MPIDR to a linear core index + * as well. This mapping can be found by reading the "Affinity Value" and + * "Processor Number" fields in the GICR_TYPER. It is IMP. DEF. if the + * "Processor Numbers" are suitable to index into an array to access core + * specific information. If this not the case, the platform port must provide a + * hash function. Otherwise, the "Processor Number" field will be used to access + * the array elements. + ******************************************************************************/ +typedef unsigned int (*mpidr_hash_fn)(u_register_t mpidr); + +typedef struct gicv3_driver_data { + uintptr_t gicd_base; + uintptr_t gicr_base; + const interrupt_prop_t *interrupt_props; + unsigned int interrupt_props_num; + unsigned int rdistif_num; + uintptr_t *rdistif_base_addrs; + mpidr_hash_fn mpidr_to_core_pos; +} gicv3_driver_data_t; + +typedef struct gicv3_redist_ctx { + /* 64 bits registers */ + uint64_t gicr_propbaser; + uint64_t gicr_pendbaser; + + /* 32 bits registers */ + uint32_t gicr_ctlr; + uint32_t gicr_igroupr[GICR_NUM_REGS(IGROUPR)]; + uint32_t gicr_isenabler[GICR_NUM_REGS(ISENABLER)]; + uint32_t gicr_ispendr[GICR_NUM_REGS(ISPENDR)]; + uint32_t gicr_isactiver[GICR_NUM_REGS(ISACTIVER)]; + uint32_t gicr_ipriorityr[GICR_NUM_REGS(IPRIORITYR)]; + uint32_t gicr_icfgr[GICR_NUM_REGS(ICFGR)]; + uint32_t gicr_igrpmodr[GICR_NUM_REGS(IGRPMODR)]; + uint32_t gicr_nsacr; +} gicv3_redist_ctx_t; + +typedef struct gicv3_dist_ctx { + /* 64 bits registers */ + uint64_t gicd_irouter[TOTAL_SHARED_INTR_NUM]; + + /* 32 bits registers */ + uint32_t gicd_ctlr; + uint32_t gicd_igroupr[GICD_NUM_REGS(IGROUPR)]; + uint32_t gicd_isenabler[GICD_NUM_REGS(ISENABLER)]; + uint32_t gicd_ispendr[GICD_NUM_REGS(ISPENDR)]; + uint32_t gicd_isactiver[GICD_NUM_REGS(ISACTIVER)]; + uint32_t gicd_ipriorityr[GICD_NUM_REGS(IPRIORITYR)]; + uint32_t gicd_icfgr[GICD_NUM_REGS(ICFGR)]; + uint32_t gicd_igrpmodr[GICD_NUM_REGS(IGRPMODR)]; + uint32_t gicd_nsacr[GICD_NUM_REGS(NSACR)]; +} gicv3_dist_ctx_t; + +typedef struct gicv3_its_ctx { + /* 64 bits registers */ + uint64_t gits_cbaser; + uint64_t gits_cwriter; + uint64_t gits_baser[8]; + + /* 32 bits registers */ + uint32_t gits_ctlr; +} gicv3_its_ctx_t; + +/******************************************************************************* + * GICv3 EL3 driver API + ******************************************************************************/ +void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data); +int gicv3_rdistif_probe(const uintptr_t gicr_frame); +void gicv3_distif_init(void); +void gicv3_rdistif_init(unsigned int proc_num); +void gicv3_rdistif_on(unsigned int proc_num); +void gicv3_rdistif_off(unsigned int proc_num); +unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame); +void gicv3_cpuif_enable(unsigned int proc_num); +void gicv3_cpuif_disable(unsigned int proc_num); +unsigned int gicv3_get_pending_interrupt_type(void); +unsigned int gicv3_get_pending_interrupt_id(void); +unsigned int gicv3_get_interrupt_type(unsigned int id, + unsigned int proc_num); +void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx); +void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx); +/* + * gicv3_distif_post_restore and gicv3_distif_pre_save must be implemented if + * gicv3_distif_save and gicv3_rdistif_init_restore are used. If no + * implementation-defined sequence is needed at these steps, an empty function + * can be provided. + */ +void gicv3_distif_post_restore(unsigned int proc_num); +void gicv3_distif_pre_save(unsigned int proc_num); +void gicv3_rdistif_init_restore(unsigned int proc_num, const gicv3_redist_ctx_t * const rdist_ctx); +void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ctx); +void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx); +void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx); + +unsigned int gicv3_get_running_priority(void); +unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num); +void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num); +void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num); +void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num, + unsigned int priority); +void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num, + unsigned int type); +void gicv3_raise_sgi(unsigned int sgi_num, gicv3_irq_group_t group, + u_register_t target); +void gicv3_set_spi_routing(unsigned int id, unsigned int irm, + u_register_t mpidr); +void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num); +void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num); +unsigned int gicv3_set_pmr(unsigned int mask); + +void gicv3_get_component_prodid_rev(const uintptr_t gicd_base, + unsigned int *gic_prod_id, + uint8_t *gic_rev); +void gicv3_check_erratas_applies(const uintptr_t gicd_base); +#if GIC600_ERRATA_WA_2384374 +void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base); +#else +static inline void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base) +{ +} +#endif /* GIC600_ERRATA_WA_2384374 */ + +#endif /* __ASSEMBLER__ */ +#endif /* GICV3_H */ diff --git a/include/drivers/arm/mhu.h b/include/drivers/arm/mhu.h new file mode 100644 index 0000000..31c6a81 --- /dev/null +++ b/include/drivers/arm/mhu.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MHU_H +#define MHU_H + +#include +#include + +/** + * Generic MHU error enumeration types. + */ +enum mhu_error_t { + MHU_ERR_NONE = 0, + MHU_ERR_NOT_INIT = -1, + MHU_ERR_ALREADY_INIT = -2, + MHU_ERR_UNSUPPORTED_VERSION = -3, + MHU_ERR_UNSUPPORTED = -4, + MHU_ERR_INVALID_ARG = -5, + MHU_ERR_BUFFER_TOO_SMALL = -6, + MHU_ERR_GENERAL = -7, +}; + +/** + * Initializes sender MHU. + * + * mhu_sender_base Base address of sender MHU. + * + * Returns mhu_error_t error code. + * + * This function must be called before mhu_send_data(). + */ +enum mhu_error_t mhu_init_sender(uintptr_t mhu_sender_base); + + +/** + * Initializes receiver MHU. + * + * mhu_receiver_base Base address of receiver MHU. + * + * Returns mhu_error_t error code. + * + * This function must be called before mhu_receive_data(). + */ +enum mhu_error_t mhu_init_receiver(uintptr_t mhu_receiver_base); + +/** + * Sends data over MHU. + * + * send_buffer Pointer to buffer containing the data to be transmitted. + * size Size of the data to be transmitted in bytes. + * + * Returns mhu_error_t error code. + * + * The send_buffer must be 4-byte aligned and its length must be at least + * (4 - (size % 4)) bytes bigger than the data size to prevent buffer + * over-reading. + */ +enum mhu_error_t mhu_send_data(const uint8_t *send_buffer, size_t size); + +/** + * Receives data from MHU. + * + * receive_buffer Pointer the buffer where to store the received data. + * size As input the size of the receive_buffer, as output the + * number of bytes received. As a limitation, + * the size of the buffer must be a multiple of 4. + * + * Returns mhu_error_t error code. + * + * The receive_buffer must be 4-byte aligned and its length must be a + * multiple of 4. + */ +enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size); + +/** + * Gets the maximum amount of bytes that can be transmitted in a single send by MHU. + * + * Returns The amount of bytes that can be sent or received in a single message. + */ +size_t mhu_get_max_message_size(void); + +#endif /* MHU_H */ diff --git a/include/drivers/arm/nic_400.h b/include/drivers/arm/nic_400.h new file mode 100644 index 0000000..bb74982 --- /dev/null +++ b/include/drivers/arm/nic_400.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef NIC_400_H +#define NIC_400_H + +/* + * Address of slave 'n' security setting in the NIC-400 address region + * control + */ +#define NIC400_ADDR_CTRL_SECURITY_REG(n) (0x8 + (n) * 4) + +#endif /* NIC_400_H */ diff --git a/include/drivers/arm/pl011.h b/include/drivers/arm/pl011.h new file mode 100644 index 0000000..ebc6643 --- /dev/null +++ b/include/drivers/arm/pl011.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PL011_H +#define PL011_H + +#include + +/* PL011 Registers */ +#define UARTDR 0x000 +#define UARTRSR 0x004 +#define UARTECR 0x004 +#define UARTFR 0x018 +#define UARTIMSC 0x038 +#define UARTRIS 0x03C +#define UARTICR 0x044 + +/* PL011 registers (out of the SBSA specification) */ +#if !PL011_GENERIC_UART +#define UARTILPR 0x020 +#define UARTIBRD 0x024 +#define UARTFBRD 0x028 +#define UARTLCR_H 0x02C +#define UARTCR 0x030 +#define UARTIFLS 0x034 +#define UARTMIS 0x040 +#define UARTDMACR 0x048 +#endif /* !PL011_GENERIC_UART */ + +/* Data status bits */ +#define UART_DATA_ERROR_MASK 0x0F00 + +/* Status reg bits */ +#define UART_STATUS_ERROR_MASK 0x0F + +/* Flag reg bits */ +#define PL011_UARTFR_RI (1 << 8) /* Ring indicator */ +#define PL011_UARTFR_TXFE (1 << 7) /* Transmit FIFO empty */ +#define PL011_UARTFR_RXFF (1 << 6) /* Receive FIFO full */ +#define PL011_UARTFR_TXFF (1 << 5) /* Transmit FIFO full */ +#define PL011_UARTFR_RXFE (1 << 4) /* Receive FIFO empty */ +#define PL011_UARTFR_BUSY (1 << 3) /* UART busy */ +#define PL011_UARTFR_DCD (1 << 2) /* Data carrier detect */ +#define PL011_UARTFR_DSR (1 << 1) /* Data set ready */ +#define PL011_UARTFR_CTS (1 << 0) /* Clear to send */ + +#define PL011_UARTFR_TXFF_BIT 5 /* Transmit FIFO full bit in UARTFR register */ +#define PL011_UARTFR_RXFE_BIT 4 /* Receive FIFO empty bit in UARTFR register */ +#define PL011_UARTFR_BUSY_BIT 3 /* UART busy bit in UARTFR register */ + +/* Control reg bits */ +#if !PL011_GENERIC_UART +#define PL011_UARTCR_CTSEN (1 << 15) /* CTS hardware flow control enable */ +#define PL011_UARTCR_RTSEN (1 << 14) /* RTS hardware flow control enable */ +#define PL011_UARTCR_RTS (1 << 11) /* Request to send */ +#define PL011_UARTCR_DTR (1 << 10) /* Data transmit ready. */ +#define PL011_UARTCR_RXE (1 << 9) /* Receive enable */ +#define PL011_UARTCR_TXE (1 << 8) /* Transmit enable */ +#define PL011_UARTCR_LBE (1 << 7) /* Loopback enable */ +#define PL011_UARTCR_UARTEN (1 << 0) /* UART Enable */ + +#if !defined(PL011_LINE_CONTROL) +/* FIFO Enabled / No Parity / 8 Data bit / One Stop Bit */ +#define PL011_LINE_CONTROL (PL011_UARTLCR_H_FEN | PL011_UARTLCR_H_WLEN_8) +#endif + +/* Line Control Register Bits */ +#define PL011_UARTLCR_H_SPS (1 << 7) /* Stick parity select */ +#define PL011_UARTLCR_H_WLEN_8 (3 << 5) +#define PL011_UARTLCR_H_WLEN_7 (2 << 5) +#define PL011_UARTLCR_H_WLEN_6 (1 << 5) +#define PL011_UARTLCR_H_WLEN_5 (0 << 5) +#define PL011_UARTLCR_H_FEN (1 << 4) /* FIFOs Enable */ +#define PL011_UARTLCR_H_STP2 (1 << 3) /* Two stop bits select */ +#define PL011_UARTLCR_H_EPS (1 << 2) /* Even parity select */ +#define PL011_UARTLCR_H_PEN (1 << 1) /* Parity Enable */ +#define PL011_UARTLCR_H_BRK (1 << 0) /* Send break */ + +#endif /* !PL011_GENERIC_UART */ + +#ifndef __ASSEMBLER__ + +#include + +/* + * Initialize a new PL011 console instance and register it with the console + * framework. The |console| pointer must point to storage that will be valid + * for the lifetime of the console, such as a global or static local variable. + * Its contents will be reinitialized from scratch. + */ +int console_pl011_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, + console_t *console); + +#endif /*__ASSEMBLER__*/ + +#endif /* PL011_H */ diff --git a/include/drivers/arm/pl061_gpio.h b/include/drivers/arm/pl061_gpio.h new file mode 100644 index 0000000..68238c9 --- /dev/null +++ b/include/drivers/arm/pl061_gpio.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PL061_GPIO_H +#define PL061_GPIO_H + +#include + +void pl061_gpio_register(uintptr_t base_addr, int gpio_dev); +void pl061_gpio_init(void); + +#endif /* PL061_GPIO_H */ diff --git a/include/drivers/arm/rss_comms.h b/include/drivers/arm/rss_comms.h new file mode 100644 index 0000000..b96c79f --- /dev/null +++ b/include/drivers/arm/rss_comms.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef RSS_COMMS_H +#define RSS_COMMS_H + +#include + +int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base); + +#endif /* RSS_COMMS_H */ diff --git a/include/drivers/arm/sbsa.h b/include/drivers/arm/sbsa.h new file mode 100644 index 0000000..9403634 --- /dev/null +++ b/include/drivers/arm/sbsa.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SBSA_H +#define SBSA_H + +#include + +/* Register Offsets */ +#define SBSA_WDOG_WCS_OFFSET UL(0x000) +#define SBSA_WDOG_WOR_LOW_OFFSET UL(0x008) +#define SBSA_WDOG_WOR_HIGH_OFFSET UL(0x00C) + +#define SBSA_WDOG_WCS_EN U(0x1) + +#define SBSA_WDOG_WOR_WIDTH UL(48) + +void sbsa_wdog_start(uintptr_t base, uint64_t ms); +void sbsa_wdog_stop(uintptr_t base); + +#endif /* SBSA_H */ diff --git a/include/drivers/arm/scu.h b/include/drivers/arm/scu.h new file mode 100644 index 0000000..992539f --- /dev/null +++ b/include/drivers/arm/scu.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCU_H +#define SCU_H + +#include + +#define SCU_CTRL_REG 0x00 +#define SCU_CFG_REG 0x04 + +#define SCU_ENABLE_BIT (1 << 0) + +void enable_snoop_ctrl_unit(uintptr_t base); +uint32_t read_snoop_ctrl_unit_cfg(uintptr_t base); + +#endif /* SCU_H */ diff --git a/include/drivers/arm/smmu_v3.h b/include/drivers/arm/smmu_v3.h new file mode 100644 index 0000000..37da56f --- /dev/null +++ b/include/drivers/arm/smmu_v3.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SMMU_V3_H +#define SMMU_V3_H + +#include +#include +#include + +/* SMMUv3 register offsets from device base */ +#define SMMU_CR0 U(0x0020) +#define SMMU_CR0ACK U(0x0024) +#define SMMU_GBPA U(0x0044) +#define SMMU_S_IDR1 U(0x8004) +#define SMMU_S_INIT U(0x803c) +#define SMMU_S_GBPA U(0x8044) + +/* + * TODO: SMMU_ROOT_PAGE_OFFSET is platform specific. + * Currently defined as a command line model parameter. + */ +#if ENABLE_RME + +#define SMMU_ROOT_PAGE_OFFSET (PLAT_ARM_SMMUV3_ROOT_REG_OFFSET) +#define SMMU_ROOT_IDR0 U(SMMU_ROOT_PAGE_OFFSET + 0x0000) +#define SMMU_ROOT_IIDR U(SMMU_ROOT_PAGE_OFFSET + 0x0008) +#define SMMU_ROOT_CR0 U(SMMU_ROOT_PAGE_OFFSET + 0x0020) +#define SMMU_ROOT_CR0ACK U(SMMU_ROOT_PAGE_OFFSET + 0x0024) +#define SMMU_ROOT_GPT_BASE U(SMMU_ROOT_PAGE_OFFSET + 0x0028) +#define SMMU_ROOT_GPT_BASE_CFG U(SMMU_ROOT_PAGE_OFFSET + 0x0030) +#define SMMU_ROOT_GPF_FAR U(SMMU_ROOT_PAGE_OFFSET + 0x0038) +#define SMMU_ROOT_GPT_CFG_FAR U(SMMU_ROOT_PAGE_OFFSET + 0x0040) +#define SMMU_ROOT_TLBI U(SMMU_ROOT_PAGE_OFFSET + 0x0050) +#define SMMU_ROOT_TLBI_CTRL U(SMMU_ROOT_PAGE_OFFSET + 0x0058) + +#endif /* ENABLE_RME */ + +/* SMMU_CR0 and SMMU_CR0ACK register fields */ +#define SMMU_CR0_SMMUEN (1UL << 0) + +/* SMMU_GBPA register fields */ +#define SMMU_GBPA_UPDATE (1UL << 31) +#define SMMU_GBPA_ABORT (1UL << 20) + +/* SMMU_S_IDR1 register fields */ +#define SMMU_S_IDR1_SECURE_IMPL (1UL << 31) + +/* SMMU_S_INIT register fields */ +#define SMMU_S_INIT_INV_ALL (1UL << 0) + +/* SMMU_S_GBPA register fields */ +#define SMMU_S_GBPA_UPDATE (1UL << 31) +#define SMMU_S_GBPA_ABORT (1UL << 20) + +/* SMMU_ROOT_IDR0 register fields */ +#define SMMU_ROOT_IDR0_ROOT_IMPL (1UL << 0) + +/* SMMU_ROOT_CR0 register fields */ +#define SMMU_ROOT_CR0_GPCEN (1UL << 1) +#define SMMU_ROOT_CR0_ACCESSEN (1UL << 0) + +int smmuv3_init(uintptr_t smmu_base); +int smmuv3_security_init(uintptr_t smmu_base); + +int smmuv3_ns_set_abort_all(uintptr_t smmu_base); + +#endif /* SMMU_V3_H */ diff --git a/include/drivers/arm/sp804_delay_timer.h b/include/drivers/arm/sp804_delay_timer.h new file mode 100644 index 0000000..f8769e8 --- /dev/null +++ b/include/drivers/arm/sp804_delay_timer.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SP804_DELAY_TIMER_H +#define SP804_DELAY_TIMER_H + +#include + +#include + +uint32_t sp804_get_timer_value(void); + +void sp804_timer_ops_init(uintptr_t base_addr, const timer_ops_t *ops); + +#define sp804_timer_init(base_addr, clk_mult, clk_div) \ + do { \ + static const timer_ops_t sp804_timer_ops = { \ + sp804_get_timer_value, \ + (clk_mult), \ + (clk_div) \ + }; \ + sp804_timer_ops_init((base_addr), &sp804_timer_ops); \ + } while (0) + +#endif /* SP804_DELAY_TIMER_H */ diff --git a/include/drivers/arm/sp805.h b/include/drivers/arm/sp805.h new file mode 100644 index 0000000..b00ede1 --- /dev/null +++ b/include/drivers/arm/sp805.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SP805_H +#define SP805_H + +#include + +/* SP805 register offset */ +#define SP805_WDOG_LOAD_OFF UL(0x000) +#define SP805_WDOG_CTR_OFF UL(0x008) +#define SP805_WDOG_LOCK_OFF UL(0xc00) + +/* Magic word to unlock the wd registers */ +#define WDOG_UNLOCK_KEY U(0x1ACCE551) + +/* Register field definitions */ +#define SP805_CTR_RESEN (U(1) << 1) +#define SP805_CTR_INTEN (U(1) << 0) + +#ifndef __ASSEMBLER__ + +#include + +/* Public high level API */ + +void sp805_start(uintptr_t base, unsigned int ticks); +void sp805_stop(uintptr_t base); +void sp805_refresh(uintptr_t base, unsigned int ticks); + +#endif /* __ASSEMBLER__ */ + +#endif /* SP805_H */ diff --git a/include/drivers/arm/tzc380.h b/include/drivers/arm/tzc380.h new file mode 100644 index 0000000..9bd5f21 --- /dev/null +++ b/include/drivers/arm/tzc380.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TZC380_H +#define TZC380_H + +#include +#include + +#define TZC380_CONFIGURATION_OFF U(0x000) +#define ACTION_OFF U(0x004) +#define LOCKDOWN_RANGE_OFF U(0x008) +#define LOCKDOWN_SELECT_OFF U(0x00C) +#define INT_STATUS U(0x010) +#define INT_CLEAR U(0x014) + +#define FAIL_ADDRESS_LOW_OFF U(0x020) +#define FAIL_ADDRESS_HIGH_OFF U(0x024) +#define FAIL_CONTROL_OFF U(0x028) +#define FAIL_ID U(0x02c) + +#define SPECULATION_CTRL_OFF U(0x030) +#define SECURITY_INV_EN_OFF U(0x034) + +#define REGION_SETUP_LOW_OFF(n) U(0x100 + (n) * 0x10) +#define REGION_SETUP_HIGH_OFF(n) U(0x104 + (n) * 0x10) +#define REGION_ATTRIBUTES_OFF(n) U(0x108 + (n) * 0x10) + +#define BUILD_CONFIG_AW_SHIFT 8 +#define BUILD_CONFIG_AW_MASK U(0x3f) +#define BUILD_CONFIG_NR_SHIFT 0 +#define BUILD_CONFIG_NR_MASK U(0xf) + +#define ACTION_RV_SHIFT 0 +#define ACTION_RV_MASK U(0x3) +#define ACTION_RV_LOWOK U(0x0) +#define ACTION_RV_LOWERR U(0x1) +#define ACTION_RV_HIGHOK U(0x2) +#define ACTION_RV_HIGHERR U(0x3) + +/* Speculation is enabled by default. */ +#define SPECULATION_CTRL_WRITE_DISABLE BIT_32(1) +#define SPECULATION_CTRL_READ_DISABLE BIT_32(0) + +#define INT_STATUS_OVERRUN_SHIFT 1 +#define INT_STATUS_OVERRUN_MASK U(0x1) +#define INT_STATUS_STATUS_SHIFT 0 +#define INT_STATUS_STATUS_MASK U(0x1) + +#define INT_CLEAR_CLEAR_SHIFT 0 +#define INT_CLEAR_CLEAR_MASK U(0x1) + +#define TZC380_COMPONENT_ID U(0xb105f00d) +#define TZC380_PERIPH_ID_LOW U(0x001bb380) +#define TZC380_PERIPH_ID_HIGH U(0x00000004) + +#define TZC_SP_NS_W BIT_32(0) +#define TZC_SP_NS_R BIT_32(1) +#define TZC_SP_S_W BIT_32(2) +#define TZC_SP_S_R BIT_32(3) + +#define TZC_ATTR_SP_SHIFT 28 +#define TZC_ATTR_SP_ALL ((TZC_SP_S_W | TZC_SP_S_R | TZC_SP_NS_W | \ + TZC_SP_NS_R) << TZC_ATTR_SP_SHIFT) +#define TZC_ATTR_SP_S_RW ((TZC_SP_S_W | TZC_SP_S_R) << \ + TZC_ATTR_SP_SHIFT) +#define TZC_ATTR_SP_NS_RW ((TZC_SP_NS_W | TZC_SP_NS_R) << \ + TZC_ATTR_SP_SHIFT) + +#define TZC_REGION_SIZE_32K U(0xe) +#define TZC_REGION_SIZE_64K U(0xf) +#define TZC_REGION_SIZE_128K U(0x10) +#define TZC_REGION_SIZE_256K U(0x11) +#define TZC_REGION_SIZE_512K U(0x12) +#define TZC_REGION_SIZE_1M U(0x13) +#define TZC_REGION_SIZE_2M U(0x14) +#define TZC_REGION_SIZE_4M U(0x15) +#define TZC_REGION_SIZE_8M U(0x16) +#define TZC_REGION_SIZE_16M U(0x17) +#define TZC_REGION_SIZE_32M U(0x18) +#define TZC_REGION_SIZE_64M U(0x19) +#define TZC_REGION_SIZE_128M U(0x1a) +#define TZC_REGION_SIZE_256M U(0x1b) +#define TZC_REGION_SIZE_512M U(0x1c) +#define TZC_REGION_SIZE_1G U(0x1d) +#define TZC_REGION_SIZE_2G U(0x1e) +#define TZC_REGION_SIZE_4G U(0x1f) +#define TZC_REGION_SIZE_8G U(0x20) +#define TZC_REGION_SIZE_16G U(0x21) +#define TZC_REGION_SIZE_32G U(0x22) +#define TZC_REGION_SIZE_64G U(0x23) +#define TZC_REGION_SIZE_128G U(0x24) +#define TZC_REGION_SIZE_256G U(0x25) +#define TZC_REGION_SIZE_512G U(0x26) +#define TZC_REGION_SIZE_1T U(0x27) +#define TZC_REGION_SIZE_2T U(0x28) +#define TZC_REGION_SIZE_4T U(0x29) +#define TZC_REGION_SIZE_8T U(0x2a) +#define TZC_REGION_SIZE_16T U(0x2b) +#define TZC_REGION_SIZE_32T U(0x2c) +#define TZC_REGION_SIZE_64T U(0x2d) +#define TZC_REGION_SIZE_128T U(0x2e) +#define TZC_REGION_SIZE_256T U(0x2f) +#define TZC_REGION_SIZE_512T U(0x30) +#define TZC_REGION_SIZE_1P U(0x31) +#define TZC_REGION_SIZE_2P U(0x32) +#define TZC_REGION_SIZE_4P U(0x33) +#define TZC_REGION_SIZE_8P U(0x34) +#define TZC_REGION_SIZE_16P U(0x35) +#define TZC_REGION_SIZE_32P U(0x36) +#define TZC_REGION_SIZE_64P U(0x37) +#define TZC_REGION_SIZE_128P U(0x38) +#define TZC_REGION_SIZE_256P U(0x39) +#define TZC_REGION_SIZE_512P U(0x3a) +#define TZC_REGION_SIZE_1E U(0x3b) +#define TZC_REGION_SIZE_2E U(0x3c) +#define TZC_REGION_SIZE_4E U(0x3d) +#define TZC_REGION_SIZE_8E U(0x3e) +#define TZC_REGION_SIZE_16E U(0x3f) + +#define TZC_SUBREGION_DIS_SHIFT 0x8 +#define TZC_SUBREGION_DIS_MASK U(0xff) +#define TZC_ATTR_SUBREG_DIS(s) (((s) & TZC_SUBREGION_DIS_MASK) \ + << TZC_SUBREGION_DIS_SHIFT) + +#define TZC_REGION_SIZE_SHIFT 0x1 +#define TZC_REGION_SIZE_MASK U(0x7e) +#define TZC_ATTR_REGION_SIZE(s) ((s) << TZC_REGION_SIZE_SHIFT) + +#define TZC_ATTR_REGION_EN_SHIFT 0x0 +#define TZC_ATTR_REGION_EN_MASK U(0x1) + +#define TZC_ATTR_REGION_EN +#define TZC_ATTR_REGION_ENABLE U(0x1) +#define TZC_ATTR_REGION_DISABLE U(0x0) + +#define REGION_MAX 16 + +void tzc380_init(uintptr_t base); +void tzc380_configure_region(uint8_t region, + uintptr_t region_base, + unsigned int attr); +void tzc380_set_action(unsigned int action); +static inline void tzc_init(uintptr_t base) +{ + tzc380_init(base); +} + +static inline void tzc_configure_region(uint8_t region, + uintptr_t region_base, + unsigned int attr) +{ + tzc380_configure_region(region, region_base, attr); +} + +static inline void tzc_set_action(unsigned int action) +{ + tzc380_set_action(action); +} + +#endif /* TZC380_H */ diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h new file mode 100644 index 0000000..765c130 --- /dev/null +++ b/include/drivers/arm/tzc400.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TZC400_H +#define TZC400_H + +#include +#include + +#define BUILD_CONFIG_OFF U(0x000) +#define GATE_KEEPER_OFF U(0x008) +#define SPECULATION_CTRL_OFF U(0x00c) +#define INT_STATUS U(0x010) +#define INT_CLEAR U(0x014) + +#define FAIL_ADDRESS_LOW_OFF U(0x020) +#define FAIL_ADDRESS_HIGH_OFF U(0x024) +#define FAIL_CONTROL_OFF U(0x028) +#define FAIL_ID U(0x02c) + +/* ID registers not common across different varieties of TZC */ +#define PID5 U(0xFD4) +#define PID6 U(0xFD8) +#define PID7 U(0xFDC) + +#define BUILD_CONFIG_NF_SHIFT 24 +#define BUILD_CONFIG_NF_MASK U(0x3) +#define BUILD_CONFIG_AW_SHIFT 8 +#define BUILD_CONFIG_AW_MASK U(0x3f) +#define BUILD_CONFIG_NR_SHIFT 0 +#define BUILD_CONFIG_NR_MASK U(0x1f) + +/* + * Number of gate keepers is implementation defined. But we know the max for + * this device is 4. Get implementation details from BUILD_CONFIG. + */ +#define GATE_KEEPER_OS_SHIFT 16 +#define GATE_KEEPER_OS_MASK U(0xf) +#define GATE_KEEPER_OR_SHIFT 0 +#define GATE_KEEPER_OR_MASK U(0xf) +#define GATE_KEEPER_FILTER_MASK U(0x1) + +/* Speculation is enabled by default. */ +#define SPECULATION_CTRL_WRITE_DISABLE BIT_32(1) +#define SPECULATION_CTRL_READ_DISABLE BIT_32(0) + +/* Max number of filters allowed is 4. */ +#define INT_STATUS_OVERLAP_SHIFT 16 +#define INT_STATUS_OVERLAP_MASK U(0xf) +#define INT_STATUS_OVERRUN_SHIFT 8 +#define INT_STATUS_OVERRUN_MASK U(0xf) +#define INT_STATUS_STATUS_SHIFT 0 +#define INT_STATUS_STATUS_MASK U(0xf) + +#define INT_CLEAR_CLEAR_SHIFT 0 +#define INT_CLEAR_CLEAR_MASK U(0xf) + +#define FAIL_CONTROL_DIR_SHIFT 24 +#define FAIL_CONTROL_DIR_READ U(0) +#define FAIL_CONTROL_DIR_WRITE U(1) +#define FAIL_CONTROL_NS_SHIFT 21 +#define FAIL_CONTROL_NS_SECURE U(0) +#define FAIL_CONTROL_NS_NONSECURE U(1) +#define FAIL_CONTROL_PRIV_SHIFT 20 +#define FAIL_CONTROL_PRIV_UNPRIV U(0) +#define FAIL_CONTROL_PRIV_PRIV U(1) + +/* + * FAIL_ID_ID_MASK depends on AID_WIDTH which is platform specific. + * Platform should provide the value on initialisation. + */ +#define FAIL_ID_VNET_SHIFT 24 +#define FAIL_ID_VNET_MASK U(0xf) +#define FAIL_ID_ID_SHIFT 0 + +#define TZC_400_PERIPHERAL_ID U(0x460) + +/* Filter enable bits in a TZC */ +#define TZC_400_REGION_ATTR_F_EN_MASK U(0xf) +#define TZC_400_REGION_ATTR_FILTER_BIT(x) (U(1) << (x)) +#define TZC_400_REGION_ATTR_FILTER_BIT_ALL TZC_400_REGION_ATTR_F_EN_MASK + +/* + * All TZC region configuration registers are placed one after another. It + * depicts size of block of registers for programming each region. + */ +#define TZC_400_REGION_SIZE U(0x20) +#define TZC_400_ACTION_OFF U(0x4) + +#define FILTER_OFFSET U(0x10) + +#ifndef __ASSEMBLER__ + +#include +#include + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ +void tzc400_init(uintptr_t base); +void tzc400_configure_region0(unsigned int sec_attr, + unsigned int ns_device_access); +void tzc400_configure_region(unsigned int filters, + unsigned int region, + unsigned long long region_base, + unsigned long long region_top, + unsigned int sec_attr, + unsigned int nsaid_permissions); +void tzc400_update_filters(unsigned int region, unsigned int filters); +void tzc400_set_action(unsigned int action); +void tzc400_enable_filters(void); +void tzc400_disable_filters(void); +int tzc400_it_handler(void); + +static inline void tzc_init(uintptr_t base) +{ + tzc400_init(base); +} + +static inline void tzc_configure_region0( + unsigned int sec_attr, + unsigned int ns_device_access) +{ + tzc400_configure_region0(sec_attr, ns_device_access); +} + +static inline void tzc_configure_region( + unsigned int filters, + unsigned int region, + unsigned long long region_base, + unsigned long long region_top, + unsigned int sec_attr, + unsigned int ns_device_access) +{ + tzc400_configure_region(filters, region, region_base, + region_top, sec_attr, ns_device_access); +} + +static inline void tzc_set_action(unsigned int action) +{ + tzc400_set_action(action); +} + + +static inline void tzc_enable_filters(void) +{ + tzc400_enable_filters(); +} + +static inline void tzc_disable_filters(void) +{ + tzc400_disable_filters(); +} + +#endif /* __ASSEMBLER__ */ + +#endif /* TZC400_H */ diff --git a/include/drivers/arm/tzc_common.h b/include/drivers/arm/tzc_common.h new file mode 100644 index 0000000..e58201c --- /dev/null +++ b/include/drivers/arm/tzc_common.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TZC_COMMON_H +#define TZC_COMMON_H + +#include + +/* + * Offset of core registers from the start of the base of configuration + * registers for each region. + */ + +/* ID Registers */ +#define PID0_OFF U(0xfe0) +#define PID1_OFF U(0xfe4) +#define PID2_OFF U(0xfe8) +#define PID3_OFF U(0xfec) +#define PID4_OFF U(0xfd0) +#define CID0_OFF U(0xff0) +#define CID1_OFF U(0xff4) +#define CID2_OFF U(0xff8) +#define CID3_OFF U(0xffc) + +/* + * What type of action is expected when an access violation occurs. + * The memory requested is returned as zero. But we can also raise an event to + * let the system know it happened. + * We can raise an interrupt(INT) and/or cause an exception(ERR). + * TZC_ACTION_NONE - No interrupt, no Exception + * TZC_ACTION_ERR - No interrupt, raise exception -> sync external + * data abort + * TZC_ACTION_INT - Raise interrupt, no exception + * TZC_ACTION_ERR_INT - Raise interrupt, raise exception -> sync + * external data abort + */ +#define TZC_ACTION_NONE U(0) +#define TZC_ACTION_ERR U(1) +#define TZC_ACTION_INT U(2) +#define TZC_ACTION_ERR_INT (TZC_ACTION_ERR | TZC_ACTION_INT) + +/* Bit positions of TZC_ACTION registers */ +#define TZC_ACTION_RV_SHIFT 0 +#define TZC_ACTION_RV_MASK U(0x3) +#define TZC_ACTION_RV_LOWOK U(0x0) +#define TZC_ACTION_RV_LOWERR U(0x1) +#define TZC_ACTION_RV_HIGHOK U(0x2) +#define TZC_ACTION_RV_HIGHERR U(0x3) + +/* + * Controls secure access to a region. If not enabled secure access is not + * allowed to region. + */ +#define TZC_REGION_S_NONE U(0) +#define TZC_REGION_S_RD U(1) +#define TZC_REGION_S_WR U(2) +#define TZC_REGION_S_RDWR (TZC_REGION_S_RD | TZC_REGION_S_WR) + +#define TZC_REGION_ATTR_S_RD_SHIFT 30 +#define TZC_REGION_ATTR_S_WR_SHIFT 31 +#define TZC_REGION_ATTR_F_EN_SHIFT 0 +#define TZC_REGION_ATTR_SEC_SHIFT 30 +#define TZC_REGION_ATTR_S_RD_MASK U(0x1) +#define TZC_REGION_ATTR_S_WR_MASK U(0x1) +#define TZC_REGION_ATTR_SEC_MASK U(0x3) + +#define TZC_REGION_ACCESS_WR_EN_SHIFT 16 +#define TZC_REGION_ACCESS_RD_EN_SHIFT 0 +#define TZC_REGION_ACCESS_ID_MASK U(0xf) + +/* Macros for allowing Non-Secure access to a region based on NSAID */ +#define TZC_REGION_ACCESS_RD(nsaid) \ + ((U(1) << ((nsaid) & TZC_REGION_ACCESS_ID_MASK)) << \ + TZC_REGION_ACCESS_RD_EN_SHIFT) +#define TZC_REGION_ACCESS_WR(nsaid) \ + ((U(1) << ((nsaid) & TZC_REGION_ACCESS_ID_MASK)) << \ + TZC_REGION_ACCESS_WR_EN_SHIFT) +#define TZC_REGION_ACCESS_RDWR(nsaid) \ + (TZC_REGION_ACCESS_RD(nsaid) | \ + TZC_REGION_ACCESS_WR(nsaid)) + +/* Returns offset of registers to program for a given region no */ +#define TZC_REGION_OFFSET(region_size, region_no) \ + ((region_size) * (region_no)) + +#endif /* TZC_COMMON_H */ diff --git a/include/drivers/arm/tzc_dmc500.h b/include/drivers/arm/tzc_dmc500.h new file mode 100644 index 0000000..cce074c --- /dev/null +++ b/include/drivers/arm/tzc_dmc500.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TZC_DMC500_H +#define TZC_DMC500_H + +#include +#include + +#define SI_STATUS_OFFSET U(0x000) +#define SI_STATE_CTRL_OFFSET U(0x030) +#define SI_FLUSH_CTRL_OFFSET U(0x034) +#define SI_INT_CONTROL_OFFSET U(0x048) + +#define SI_INT_STATUS_OFFSET U(0x004) +#define SI_TZ_FAIL_ADDRESS_LOW_OFFSET U(0x008) +#define SI_TZ_FAIL_ADDRESS_HIGH_OFFSET U(0x00c) +#define SI_FAIL_CONTROL_OFFSET U(0x010) +#define SI_FAIL_ID_OFFSET U(0x014) +#define SI_INT_CLR_OFFSET U(0x04c) + +/* + * DMC-500 has 2 system interfaces each having a similar set of regs + * to configure each interface. + */ +#define SI0_BASE U(0x0000) +#define SI1_BASE U(0x0200) + +/* Bit positions of SIx_SI_STATUS */ +#define SI_EMPTY_SHIFT 1 +#define SI_STALL_ACK_SHIFT 0 +#define SI_EMPTY_MASK U(0x01) +#define SI_STALL_ACK_MASK U(0x01) + +/* Bit positions of SIx_SI_INT_STATUS */ +#define PMU_REQ_INT_OVERFLOW_STATUS_SHIFT 18 +#define FAILED_ACCESS_INT_OVERFLOW_STATUS_SHIFT 16 +#define PMU_REQ_INT_STATUS_SHIFT 2 +#define FAILED_ACCESS_INT_INFO_TZ_OVERLAP_STATUS_SHIFT 1 +#define FAILED_ACCESS_INT_STATUS_SHIFT 0 +#define PMU_REQ_INT_OVERFLOW_STATUS_MASK U(0x1) +#define FAILED_ACCESS_INT_OVERFLOW_STATUS_MASK U(0x1) +#define PMU_REQ_INT_STATUS_MASK U(0x1) +#define FAILED_ACCESS_INT_INFO_TZ_OVERLAP_STATUS_MASK U(0x1) +#define FAILED_ACCESS_INT_STATUS_MASK U(0x1) + +/* Bit positions of SIx_TZ_FAIL_CONTROL */ +#define DIRECTION_SHIFT 24 +#define NON_SECURE_SHIFT 21 +#define PRIVILEGED_SHIFT 20 +#define FAILED_ACCESS_INT_INFO_RANK_MASKED_SHIFT 3 +#define FAILED_ACCESS_INT_INFO_UNMAPPED_SHIFT 2 +#define FAILED_ACCESS_INT_TZ_FAIL_SHIFT 1 +#define FAILED_ACCESS_INT_INFO_OUTSIDE_DEFAULT_SHIFT 0 +#define DIRECTION_MASK U(0x1) +#define NON_SECURE_MASK U(0x1) +#define PRIVILEGED_MASK U(0x1) +#define FAILED_ACCESS_INT_INFO_RANK_MASKED_MASK U(0x1) +#define FAILED_ACCESS_INT_INFO_UNMAPPED_MASK U(0x1) +#define FAILED_ACCESS_INT_TZ_FAIL_MASK U(0x1) +#define FAILED_ACCESS_INT_INFO_OUTSIDE_DEFAULT_MASK U(0x1) + +/* Bit positions of SIx_FAIL_STATUS */ +#define FAIL_ID_VNET_SHIFT 24 +#define FAIL_ID_ID_SHIFT 0 +#define FAIL_ID_VNET_MASK U(0xf) +#define FAIL_ID_ID_MASK U(0xffffff) + +/* Bit positions of SIx_SI_STATE_CONTRL */ +#define SI_STALL_REQ_GO 0x0 +#define SI_STALL_REQ_STALL 0x1 + +/* Bit positions of SIx_SI_FLUSH_CONTROL */ +#define SI_FLUSH_REQ_INACTIVE 0x0 +#define SI_FLUSH_REQ_ACTIVE 0x1 +#define SI_FLUSH_REQ_MASK 0x1 + +/* Bit positions of SIx_SI_INT_CONTROL */ +#define PMU_REQ_INT_EN_SHIFT 2 +#define OVERLAP_DETECT_INT_EN_SHIFT 1 +#define FAILED_ACCESS_INT_EN_SHIFT 0 +#define PMU_REQ_INT_EN_MASK U(0x1) +#define OVERLAP_DETECT_INT_EN_MASK U(0x1) +#define FAILED_ACCESS_INT_EN_MASK U(0x1) +#define PMU_REQ_INT_EN U(0x1) +#define OVERLAP_DETECT_INT_EN U(0x1) +#define FAILED_ACCESS_INT_EN U(0x1) + +/* Bit positions of SIx_SI_INT_CLR */ +#define PMU_REQ_OFLOW_CLR_SHIFT 18 +#define FAILED_ACCESS_OFLOW_CLR_SHIFT 16 +#define PMU_REQ_INT_CLR_SHIFT 2 +#define FAILED_ACCESS_INT_CLR_SHIFT 0 +#define PMU_REQ_OFLOW_CLR_MASK U(0x1) +#define FAILED_ACCESS_OFLOW_CLR_MASK U(0x1) +#define PMU_REQ_INT_CLR_MASK U(0x1) +#define FAILED_ACCESS_INT_CLR_MASK U(0x1) +#define PMU_REQ_OFLOW_CLR U(0x1) +#define FAILED_ACCESS_OFLOW_CLR U(0x1) +#define PMU_REQ_INT_CLR U(0x1) +#define FAILED_ACCESS_INT_CLR U(0x1) + +/* Macro to get the correct base register for a system interface */ +#define IFACE_OFFSET(sys_if) ((sys_if) ? SI1_BASE : SI0_BASE) + +#define MAX_SYS_IF_COUNT U(2) +#define MAX_REGION_VAL 8 + +/* DMC-500 supports striping across a max of 4 DMC instances */ +#define MAX_DMC_COUNT 4 + +/* Consist of part_number_1 and part_number_0 */ +#define DMC500_PERIPHERAL_ID U(0x0450) + +/* Filter enable bits in a TZC */ +#define TZC_DMC500_REGION_ATTR_F_EN_MASK U(0x1) + +/* Length of registers for configuring each region */ +#define TZC_DMC500_REGION_SIZE U(0x018) + +#ifndef __ASSEMBLER__ + +#include + +/* + * Contains the base addresses of all the DMC instances. + */ +typedef struct tzc_dmc500_driver_data { + uintptr_t dmc_base[MAX_DMC_COUNT]; + int dmc_count; + unsigned int sys_if_count; +} tzc_dmc500_driver_data_t; + +void tzc_dmc500_driver_init(const tzc_dmc500_driver_data_t *plat_driver_data); +void tzc_dmc500_configure_region0(unsigned int sec_attr, + unsigned int nsaid_permissions); +void tzc_dmc500_configure_region(unsigned int region_no, + unsigned long long region_base, + unsigned long long region_top, + unsigned int sec_attr, + unsigned int nsaid_permissions); +void tzc_dmc500_set_action(unsigned int action); +void tzc_dmc500_config_complete(void); +int tzc_dmc500_verify_complete(void); + + +#endif /* __ASSEMBLER__ */ +#endif /* TZC_DMC500_H */ diff --git a/include/drivers/arm/tzc_dmc620.h b/include/drivers/arm/tzc_dmc620.h new file mode 100644 index 0000000..26c444d --- /dev/null +++ b/include/drivers/arm/tzc_dmc620.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TZC_DMC620_H +#define TZC_DMC620_H + +#include + +/* 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 */ + -- cgit v1.2.3