diff options
77 files changed, 2182 insertions, 320 deletions
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index d9d7f84fdd..802dafcd87 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -64,6 +64,14 @@ Amlogic Meson S905X2 (G12A) platform port :F: drivers/amlogic/g12a :F: plat/amlogic/g12a/ +Amlogic Meson A113D (AXG) platform port +----------------------------------------- +:M: Carlo Caione <ccaione@baylibre.com> +:G: `carlocaione`_ +:F: docs/plat/meson-axg.rst +:F: drivers/amlogic/axg +:F: plat/amlogic/axg/ + Armv7-A architecture port ------------------------- :M: Etienne Carriere <etienne.carriere@linaro.org> diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst index 2025243164..f5c8bc98c8 100644 --- a/docs/design/trusted-board-boot-build.rst +++ b/docs/design/trusted-board-boot-build.rst @@ -33,7 +33,7 @@ images with support for these features: - ``GENERATE_COT=1`` In the case of Arm platforms, the location of the ROTPK hash must also be - specified at build time. Two locations are currently supported (see + specified at build time. The following locations are currently supported (see ``ARM_ROTPK_LOCATION`` build option): - ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted @@ -41,17 +41,16 @@ images with support for these features: registers are read-only. On FVP Base and Cortex models, the registers are read-only, but the value can be specified using the command line option ``bp.trusted_key_storage.public_key`` when launching the model. - On both Juno and FVP models, the default value corresponds to an - ECDSA-SECP256R1 public key hash, whose private part is not currently - available. + On Juno board, the default value corresponds to an ECDSA-SECP256R1 public + key hash, whose private part is not currently available. - - ``ARM_ROTPK_LOCATION=devel_rsa``: use the ROTPK hash that is hardcoded - in the Arm platform port. The private/public RSA key pair may be - found in ``plat/arm/board/common/rotpk``. + - ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in + plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin. Enforce generation + of the new hash if ROT_KEY is specified. - - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded - in the Arm platform port. The private/public ECDSA key pair may be - found in ``plat/arm/board/common/rotpk``. + - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in + plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin. Enforce generation + of the new hash if ROT_KEY is specified. Example of command line using RSA development keys: @@ -108,7 +107,7 @@ images with support for these features: -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* .. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git .. _mbed TLS Security Center: https://tls.mbed.org/security diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index e9747afbe1..ca305355be 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -468,7 +468,8 @@ Common build options entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0. - ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the - file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this + file that contains the ROT private key in PEM format and enforces public key + hash generation. If ``SAVE_KEYS=1``, this file name will be used to save the key. - ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index d24ad231d8..9622de65df 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -57,8 +57,7 @@ Arm Platform Build Options ``ARM_ROTPK_LOCATION`` are: - ``regs`` : return the ROTPK hash stored in the Trusted root-key storage - registers. The private key corresponding to this ROTPK hash is not - currently available. + registers. - ``devel_rsa`` : return a development public key hash embedded in the BL1 and BL2 binaries. This hash has been obtained from the RSA public key ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use @@ -70,6 +69,12 @@ Arm Platform Build Options use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as ``ROT_KEY`` when creating the certificates. +- ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``. Specifies the + location of the ROTPK hash. Not expected to be a build option. This defaults to + ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified algorithm. + Providing ``ROT_KEY`` enforces generation of the hash from the ``ROT_KEY`` and + overwrites the default hash file. + - ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options: - ``tsram`` : Trusted SRAM (default option when TBB is not enabled) @@ -109,6 +114,11 @@ Arm CSS Platform-Specific Build Options management operations and for SCP RAM Firmware transfer. If this option is set to 1, then SCMI/SDS drivers will be used. Default is 0. + - ``CSS_SGI_CHIP_COUNT``: Configures the number of chips on a SGI/RD platform + which supports multi-chip operation. If ``CSS_SGI_CHIP_COUNT`` is set to any + valid value greater than 1, the platform code performs required configuration + to support multi-chip operation. + -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/plat/meson-axg.rst b/docs/plat/meson-axg.rst new file mode 100644 index 0000000000..1e4b2c207b --- /dev/null +++ b/docs/plat/meson-axg.rst @@ -0,0 +1,27 @@ +Amlogic Meson A113D (AXG) +=========================== + +The Amlogic Meson A113D is a SoC with a quad core Arm Cortex-A53 running at +~1.2GHz. It also contains a Cortex-M3 used as SCP. + +This port is a minimal implementation of BL31 capable of booting mainline U-Boot +and Linux: + +- SCPI support. +- Basic PSCI support (CPU_ON, CPU_OFF, SYSTEM_RESET, SYSTEM_OFF). Note that CPU0 + can't be turned off, so there is a workaround to hide this from the caller. +- GICv2 driver set up. +- Basic SIP services (read efuse data, enable/disable JTAG). + +In order to build it: + +.. code:: shell + + CROSS_COMPILE=aarch64-none-elf- make DEBUG=1 PLAT=axg [SPD=opteed] + [AML_USE_ATOS=1 when using ATOS as BL32] + +This port has been tested on a A113D board. After building it, follow the +instructions in the `U-Boot repository`_, replacing the mentioned **bl31.img** +by the one built from this port. + +.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/s400/README diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c index 885874272f..c51f3b1d78 100644 --- a/drivers/arm/css/mhu/css_mhu_doorbell.c +++ b/drivers/arm/css/mhu/css_mhu_doorbell.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,11 +20,13 @@ void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info) void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) { + uintptr_t mhuv2_base = plat_info->db_reg_addr & MHU_V2_FRAME_BASE_MASK; + /* wake receiver */ - MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR); + MHU_V2_ACCESS_REQUEST(mhuv2_base); /* wait for receiver to acknowledge its ready */ - while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0) + while (MHU_V2_IS_ACCESS_READY(mhuv2_base) == 0) ; MHU_RING_DOORBELL(plat_info->db_reg_addr, @@ -32,7 +34,7 @@ void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) plat_info->db_preserve_mask); /* clear the access request for the receiver */ - MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR); + MHU_V2_CLEAR_REQUEST(mhuv2_base); return; } diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c index b945cda788..097d2eb2b6 100644 --- a/drivers/arm/css/scp/css_pm_scmi.c +++ b/drivers/arm/css/scp/css_pm_scmi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -63,17 +63,45 @@ typedef enum { } scmi_power_state_t; /* - * The global handle for invoking the SCMI driver APIs after the driver + * The global handles for invoking the SCMI driver APIs after the driver * has been initialized. */ -static void *scmi_handle; +static void *scmi_handles[PLAT_ARM_SCMI_CHANNEL_COUNT]; -/* The SCMI channel global object */ -static scmi_channel_t channel; +/* The global SCMI channels array */ +static scmi_channel_t scmi_channels[PLAT_ARM_SCMI_CHANNEL_COUNT]; +/* + * Channel ID for the default SCMI channel. + * The default channel is used to issue SYSTEM level SCMI requests and is + * initialized to the channel which has the boot cpu as its resource. + */ +static uint32_t default_scmi_channel_id; + +/* + * TODO: Allow use of channel specific lock instead of using a single lock for + * all the channels. + */ ARM_SCMI_INSTANTIATE_LOCK; /* + * Function to obtain the SCMI Domain ID and SCMI Channel number from the linear + * core position. The SCMI Channel number is encoded in the upper 16 bits and + * the Domain ID is encoded in the lower 16 bits in each entry of the mapping + * array exported by the platform. + */ +static void css_scp_core_pos_to_scmi_channel(unsigned int core_pos, + unsigned int *scmi_domain_id, unsigned int *scmi_channel_id) +{ + unsigned int composite_id; + + composite_id = plat_css_core_pos_to_scmi_dmn_id_map[core_pos]; + + *scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id); + *scmi_domain_id = GET_SCMI_DOMAIN_ID(composite_id); +} + +/* * Helper function to suspend a CPU power domain and its parent power domains * if applicable. */ @@ -87,10 +115,10 @@ void css_scp_suspend(const struct psci_power_state *target_state) /* Check if power down at system power domain level is requested */ if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) { - /* Issue SCMI command for SYSTEM_SUSPEND */ - ret = scmi_sys_pwr_state_set(scmi_handle, - SCMI_SYS_PWR_FORCEFUL_REQ, - SCMI_SYS_PWR_SUSPEND); + /* Issue SCMI command for SYSTEM_SUSPEND on all SCMI channels */ + ret = scmi_sys_pwr_state_set( + scmi_handles[default_scmi_channel_id], + SCMI_SYS_PWR_FORCEFUL_REQ, SCMI_SYS_PWR_SUSPEND); if (ret != SCMI_E_SUCCESS) { ERROR("SCMI system power domain suspend return 0x%x unexpected\n", ret); @@ -99,7 +127,7 @@ void css_scp_suspend(const struct psci_power_state *target_state) return; } #if !HW_ASSISTED_COHERENCY - unsigned int lvl; + unsigned int lvl, channel_id, domain_id; uint32_t scmi_pwr_state = 0; /* * If we reach here, then assert that power down at system power domain @@ -127,9 +155,10 @@ void css_scp_suspend(const struct psci_power_state *target_state) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); + css_scp_core_pos_to_scmi_channel(plat_my_core_pos(), + &domain_id, &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", @@ -145,7 +174,7 @@ void css_scp_suspend(const struct psci_power_state *target_state) */ void css_scp_off(const struct psci_power_state *target_state) { - unsigned int lvl = 0; + unsigned int lvl = 0, channel_id, domain_id; int ret; uint32_t scmi_pwr_state = 0; @@ -168,10 +197,10 @@ void css_scp_off(const struct psci_power_state *target_state) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); - + css_scp_core_pos_to_scmi_channel(plat_my_core_pos(), + &domain_id, &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", ret); @@ -185,8 +214,8 @@ void css_scp_off(const struct psci_power_state *target_state) */ void css_scp_on(u_register_t mpidr) { - unsigned int lvl = 0; - int core_pos, ret; + unsigned int lvl = 0, channel_id, core_pos, domain_id; + int ret; uint32_t scmi_pwr_state = 0; for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) @@ -196,13 +225,12 @@ void css_scp_on(u_register_t mpidr) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); core_pos = plat_core_pos_by_mpidr(mpidr); - assert((core_pos >= 0) && - (((unsigned int)core_pos) < PLATFORM_CORE_COUNT)); - - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[core_pos], - scmi_pwr_state); + assert(core_pos >= 0 && (core_pos < PLATFORM_CORE_COUNT)); + css_scp_core_pos_to_scmi_channel(core_pos, &domain_id, + &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", ret); @@ -216,8 +244,9 @@ void css_scp_on(u_register_t mpidr) */ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) { - int ret, cpu_idx; + int ret; uint32_t scmi_pwr_state = 0, lvl_state; + unsigned int channel_id, cpu_idx, domain_id; /* We don't support get power state at the system power domain level */ if ((power_level > PLAT_MAX_PWR_LVL) || @@ -230,9 +259,9 @@ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) cpu_idx = plat_core_pos_by_mpidr(mpidr); assert(cpu_idx > -1); - ret = scmi_pwr_state_get(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx], - &scmi_pwr_state); + css_scp_core_pos_to_scmi_channel(cpu_idx, &domain_id, &channel_id); + ret = scmi_pwr_state_get(scmi_handles[channel_id], + domain_id, &scmi_pwr_state); if (ret != SCMI_E_SUCCESS) { WARN("SCMI get power state command return 0x%x unexpected\n", @@ -271,7 +300,7 @@ void __dead2 css_scp_system_off(int state) * Issue SCMI command. First issue a graceful * request and if that fails force the request. */ - ret = scmi_sys_pwr_state_set(scmi_handle, + ret = scmi_sys_pwr_state_set(scmi_handles[default_scmi_channel_id], SCMI_SYS_PWR_FORCEFUL_REQ, state); @@ -325,17 +354,28 @@ static int scmi_ap_core_init(scmi_channel_t *ch) void __init plat_arm_pwrc_setup(void) { - channel.info = plat_css_get_scmi_info(); - channel.lock = ARM_SCMI_LOCK_GET_INSTANCE; - scmi_handle = scmi_init(&channel); - if (scmi_handle == NULL) { - ERROR("SCMI Initialization failed\n"); - panic(); - } - if (scmi_ap_core_init(&channel) < 0) { - ERROR("SCMI AP core protocol initialization failed\n"); - panic(); + unsigned int composite_id, idx; + + for (idx = 0; idx < PLAT_ARM_SCMI_CHANNEL_COUNT; idx++) { + INFO("Initializing driver on Channel %d\n", idx); + + scmi_channels[idx].info = plat_css_get_scmi_info(idx); + scmi_channels[idx].lock = ARM_SCMI_LOCK_GET_INSTANCE; + scmi_handles[idx] = scmi_init(&scmi_channels[idx]); + + if (scmi_handles[idx] == NULL) { + ERROR("SCMI Initialization failed on channel %d\n", idx); + panic(); + } + + if (scmi_ap_core_init(&scmi_channels[idx]) < 0) { + ERROR("SCMI AP core protocol initialization failed\n"); + panic(); + } } + + composite_id = plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()]; + default_scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id); } /****************************************************************************** @@ -347,6 +387,7 @@ const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops) { uint32_t msg_attr; int ret; + void *scmi_handle = scmi_handles[default_scmi_channel_id]; assert(scmi_handle); @@ -411,14 +452,17 @@ int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie) #if PROGRAMMABLE_RESET_ADDRESS void plat_arm_program_trusted_mailbox(uintptr_t address) { - int ret; + int ret, i; - assert(scmi_handle); - ret = scmi_ap_core_set_reset_addr(scmi_handle, address, - SCMI_AP_CORE_LOCK_ATTR); - if (ret != SCMI_E_SUCCESS) { - ERROR("CSS: Failed to program reset address: %d\n", ret); - panic(); + for (i = 0; i < PLAT_ARM_SCMI_CHANNEL_COUNT; i++) { + assert(scmi_handles[i]); + + ret = scmi_ap_core_set_reset_addr(scmi_handles[i], address, + SCMI_AP_CORE_LOCK_ATTR); + if (ret != SCMI_E_SUCCESS) { + ERROR("CSS: Failed to program reset address: %d\n", ret); + panic(); + } } } #endif diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h index e6f7a1bd1b..88302fd7bb 100644 --- a/include/drivers/arm/css/css_mhu_doorbell.h +++ b/include/drivers/arm/css/css_mhu_doorbell.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,13 +11,13 @@ #include <lib/mmio.h> -/* MHUv2 Base Address */ -#define MHUV2_BASE_ADDR PLAT_MHUV2_BASE +/* MHUv2 Frame Base Mask */ +#define MHU_V2_FRAME_BASE_MASK UL(~0xFFF) /* MHUv2 Control Registers Offsets */ -#define MHU_V2_MSG_NO_CAP_OFFSET 0xF80 -#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 -#define MHU_V2_ACCESS_READY_OFFSET 0xF8C +#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) diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h index 1f8dc6ccea..e8a2863a9f 100644 --- a/include/drivers/arm/css/scmi.h +++ b/include/drivers/arm/css/scmi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -162,7 +162,7 @@ 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(void); +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); diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 5bd53f3b53..c825bf4dca 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -18,6 +18,12 @@ * Definitions common to all ARM standard platforms *****************************************************************************/ +/* + * Root of trust key hash lengths + */ +#define ARM_ROTPK_HEADER_LEN 19 +#define ARM_ROTPK_HASH_LEN 32 + /* Special value used to verify platform parameters from BL2 to BL31 */ #define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 02feec7086..32dc9f93df 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -142,6 +142,11 @@ void arm_setup_romlib(void); #define STATE_SW_E_PARAM (-2) #define STATE_SW_E_DENIED (-3) +/* plat_get_rotpk_info() flags */ +#define ARM_ROTPK_REGS_ID 1 +#define ARM_ROTPK_DEVEL_RSA_ID 2 +#define ARM_ROTPK_DEVEL_ECDSA_ID 3 + /* IO storage utility functions */ void arm_io_setup(void); @@ -255,9 +260,17 @@ int plat_arm_bl1_fwu_needed(void); __dead2 void plat_arm_error_handler(int err); /* - * Optional function in ARM standard platforms + * Optional functions in ARM standard platforms */ void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames); +int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, + unsigned int *flags); #if ARM_PLAT_MT unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr); diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index 2adf11d66e..7b61484455 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -29,6 +29,10 @@ #define SID_REG_BASE 0x2a4a0000 #define SID_SYSTEM_ID_OFFSET 0x40 #define SID_SYSTEM_CFG_OFFSET 0x70 +#define SID_NODE_ID_OFFSET 0x60 +#define SID_CHIP_ID_MASK 0xFF +#define SID_MULTI_CHIP_MODE_MASK 0x100 +#define SID_MULTI_CHIP_MODE_SHIFT 8 /* The slave_bootsecure controls access to GPU, DMC and CS. */ #define CSS_NIC400_SLAVE_BOOTSECURE 8 diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h index 93f86162e9..e5357f50be 100644 --- a/include/plat/arm/css/common/css_pm.h +++ b/include/plat/arm/css/common/css_pm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -44,4 +44,15 @@ int css_node_hw_state(u_register_t mpidr, unsigned int power_level); */ extern const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[]; +#define SCMI_DOMAIN_ID_MASK U(0xFFFF) +#define SCMI_CHANNEL_ID_MASK U(0xFFFF) +#define SCMI_CHANNEL_ID_SHIFT U(16) + +#define SET_SCMI_CHANNEL_ID(n) (((n) & SCMI_CHANNEL_ID_MASK) << \ + SCMI_CHANNEL_ID_SHIFT) +#define SET_SCMI_DOMAIN_ID(n) ((n) & SCMI_DOMAIN_ID_MASK) +#define GET_SCMI_CHANNEL_ID(n) (((n) >> SCMI_CHANNEL_ID_SHIFT) & \ + SCMI_CHANNEL_ID_MASK) +#define GET_SCMI_DOMAIN_ID(n) ((n) & SCMI_DOMAIN_ID_MASK) + #endif /* CSS_PM_H */ diff --git a/plat/amlogic/axg/axg_bl31_setup.c b/plat/amlogic/axg/axg_bl31_setup.c new file mode 100644 index 0000000000..8cc9d69f41 --- /dev/null +++ b/plat/amlogic/axg/axg_bl31_setup.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/bl_common.h> +#include <common/interrupt_props.h> +#include <drivers/arm/gicv2.h> +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_mmu_helpers.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +#include "aml_private.h" + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL31 from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; +static image_info_t bl30_image_info; +static image_info_t bl301_image_info; + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + next_image_info = (type == NON_SECURE) ? + &bl33_image_ep_info : &bl32_image_ep_info; + + /* None of the images can have 0x0 as the entrypoint. */ + if (next_image_info->pc != 0U) + return next_image_info; + + return NULL; +} + +/******************************************************************************* + * Perform any BL31 early platform setup. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before + * they are lost (potentially). This needs to be done before the MMU is + * initialized so that the memory layout can be used while creating page + * tables. BL2 has flushed this information to memory, so we are guaranteed + * to pick up good data. + ******************************************************************************/ +struct axg_bl31_param { + param_header_t h; + image_info_t *bl31_image_info; + entry_point_info_t *bl32_ep_info; + image_info_t *bl32_image_info; + entry_point_info_t *bl33_ep_info; + image_info_t *bl33_image_info; + image_info_t *scp_image_info[]; +}; + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + struct axg_bl31_param *from_bl2; + + /* Initialize the console to provide early debug support */ + aml_console_init(); + + from_bl2 = (struct axg_bl31_param *)arg0; + + /* Check params passed from BL2 are not NULL. */ + assert(from_bl2 != NULL); + assert(from_bl2->h.type == PARAM_BL31); + assert(from_bl2->h.version >= VERSION_1); + + /* + * Copy BL32 and BL33 entry point information. It is stored in Secure + * RAM, in BL2's address space. + */ + bl32_image_ep_info = *from_bl2->bl32_ep_info; + bl33_image_ep_info = *from_bl2->bl33_ep_info; + +#if AML_USE_ATOS + /* + * BL2 is unconditionally setting 0 (OPTEE_AARCH64) in arg0 even when + * the BL32 image is 32bit (OPTEE_AARCH32). This is causing the boot to + * hang when ATOS (32bit Amlogic BL32 binary-only TEE OS) is used. + * + * Hardcode to OPTEE_AARCH32 / MODE_RW_32. + */ + bl32_image_ep_info.args.arg0 = MODE_RW_32; +#endif + + if (bl33_image_ep_info.pc == 0U) { + ERROR("BL31: BL33 entrypoint not obtained from BL2\n"); + panic(); + } + + bl30_image_info = *from_bl2->scp_image_info[0]; + bl301_image_info = *from_bl2->scp_image_info[1]; +} + +void bl31_plat_arch_setup(void) +{ + aml_setup_page_tables(); + + enable_mmu_el3(0); +} + +static inline bool axg_scp_ready(void) +{ + return AML_AO_RTI_SCP_IS_READY(mmio_read_32(AML_AO_RTI_SCP_STAT)); +} + +static inline void axg_scp_boot(void) +{ + aml_scpi_upload_scp_fw(bl30_image_info.image_base, + bl30_image_info.image_size, 0); + aml_scpi_upload_scp_fw(bl301_image_info.image_base, + bl301_image_info.image_size, 1); + while (!axg_scp_ready()) + ; +} + +/******************************************************************************* + * GICv2 driver setup information + ******************************************************************************/ +static const interrupt_prop_t axg_interrupt_props[] = { + INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL) +}; + +static const gicv2_driver_data_t axg_gic_data = { + .gicd_base = AML_GICD_BASE, + .gicc_base = AML_GICC_BASE, + .interrupt_props = axg_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(axg_interrupt_props) +}; + +void bl31_platform_setup(void) +{ + aml_mhu_secure_init(); + + gicv2_driver_init(&axg_gic_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + + axg_scp_boot(); +} diff --git a/plat/amlogic/axg/axg_common.c b/plat/amlogic/axg/axg_common.c new file mode 100644 index 0000000000..870daf4591 --- /dev/null +++ b/plat/amlogic/axg/axg_common.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <bl31/interrupt_mgmt.h> +#include <common/bl_common.h> +#include <common/ep_info.h> +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_tables_v2.h> +#include <platform_def.h> +#include <stdint.h> + +/******************************************************************************* + * Platform memory map regions + ******************************************************************************/ +#define MAP_NSDRAM0 MAP_REGION_FLAT(AML_NSDRAM0_BASE, \ + AML_NSDRAM0_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_NS_SHARE_MEM MAP_REGION_FLAT(AML_NS_SHARE_MEM_BASE, \ + AML_NS_SHARE_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_SEC_SHARE_MEM MAP_REGION_FLAT(AML_SEC_SHARE_MEM_BASE, \ + AML_SEC_SHARE_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(AML_SEC_DEVICE0_BASE, \ + AML_SEC_DEVICE0_SIZE, \ + MT_DEVICE | MT_RW) + +#define MAP_GIC_DEVICE MAP_REGION_FLAT(AML_GIC_DEVICE_BASE, \ + AML_GIC_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(AML_SEC_DEVICE1_BASE, \ + AML_SEC_DEVICE1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(AML_SEC_DEVICE2_BASE, \ + AML_SEC_DEVICE2_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_TZRAM MAP_REGION_FLAT(AML_TZRAM_BASE, \ + AML_TZRAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +static const mmap_region_t axg_mmap[] = { + MAP_NSDRAM0, + MAP_NS_SHARE_MEM, + MAP_SEC_SHARE_MEM, + MAP_SEC_DEVICE0, + MAP_GIC_DEVICE, + MAP_SEC_DEVICE1, + MAP_SEC_DEVICE2, + MAP_TZRAM, + {0} +}; + +/******************************************************************************* + * Per-image regions + ******************************************************************************/ +#define MAP_BL31 MAP_REGION_FLAT(BL31_BASE, \ + BL31_END - BL31_BASE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_BL_CODE MAP_REGION_FLAT(BL_CODE_BASE, \ + BL_CODE_END - BL_CODE_BASE, \ + MT_CODE | MT_SECURE) + +#define MAP_BL_RO_DATA MAP_REGION_FLAT(BL_RO_DATA_BASE, \ + BL_RO_DATA_END - BL_RO_DATA_BASE, \ + MT_RO_DATA | MT_SECURE) + +#define MAP_BL_COHERENT MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, \ + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/******************************************************************************* + * Function that sets up the translation tables. + ******************************************************************************/ +void aml_setup_page_tables(void) +{ +#if IMAGE_BL31 + const mmap_region_t axg_bl_mmap[] = { + MAP_BL31, + MAP_BL_CODE, + MAP_BL_RO_DATA, +#if USE_COHERENT_MEM + MAP_BL_COHERENT, +#endif + {0} + }; +#endif + + mmap_add(axg_bl_mmap); + + mmap_add(axg_mmap); + + init_xlat_tables(); +} + +/******************************************************************************* + * Function that returns the system counter frequency + ******************************************************************************/ +unsigned int plat_get_syscnt_freq2(void) +{ + mmio_clrbits_32(AML_SYS_CPU_CFG7, PLAT_SYS_CPU_CFG7); + mmio_clrbits_32(AML_AO_TIMESTAMP_CNTL, PLAT_AO_TIMESTAMP_CNTL); + + return AML_OSC24M_CLK_IN_HZ; +} diff --git a/plat/amlogic/axg/axg_def.h b/plat/amlogic/axg/axg_def.h new file mode 100644 index 0000000000..d90681afdb --- /dev/null +++ b/plat/amlogic/axg/axg_def.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AXG_DEF_H +#define AXG_DEF_H + +#include <lib/utils_def.h> + +/******************************************************************************* + * System oscillator + ******************************************************************************/ +#define AML_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */ + +/******************************************************************************* + * Memory regions + ******************************************************************************/ +#define AML_NS_SHARE_MEM_BASE UL(0x05000000) +#define AML_NS_SHARE_MEM_SIZE UL(0x00100000) + +#define AML_SEC_SHARE_MEM_BASE UL(0x05200000) +#define AML_SEC_SHARE_MEM_SIZE UL(0x00100000) + +#define AML_GIC_DEVICE_BASE UL(0xFFC00000) +#define AML_GIC_DEVICE_SIZE UL(0x00008000) + +#define AML_NSDRAM0_BASE UL(0x01000000) +#define AML_NSDRAM0_SIZE UL(0x0F000000) + +#define BL31_BASE UL(0x05100000) +#define BL31_SIZE UL(0x00100000) +#define BL31_LIMIT (BL31_BASE + BL31_SIZE) + +/* Shared memory used for SMC services */ +#define AML_SHARE_MEM_INPUT_BASE UL(0x050FE000) +#define AML_SHARE_MEM_OUTPUT_BASE UL(0x050FF000) + +#define AML_SEC_DEVICE0_BASE UL(0xFFD00000) +#define AML_SEC_DEVICE0_SIZE UL(0x00026000) + +#define AML_SEC_DEVICE1_BASE UL(0xFF800000) +#define AML_SEC_DEVICE1_SIZE UL(0x0000A000) + +#define AML_SEC_DEVICE2_BASE UL(0xFF620000) +#define AML_SEC_DEVICE2_SIZE UL(0x00028000) + +#define AML_TZRAM_BASE UL(0xFFFC0000) +#define AML_TZRAM_SIZE UL(0x00020000) + +/* Mailboxes */ +#define AML_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xFFFD3800) +#define AML_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xFFFD3A00) +#define AML_PSCI_MAILBOX_BASE UL(0xFFFD3F00) + +/******************************************************************************* + * GIC-400 and interrupt handling related constants + ******************************************************************************/ +#define AML_GICD_BASE UL(0xFFC01000) +#define AML_GICC_BASE UL(0xFFC02000) + +#define IRQ_SEC_PHY_TIMER 29 + +#define IRQ_SEC_SGI_0 8 +#define IRQ_SEC_SGI_1 9 +#define IRQ_SEC_SGI_2 10 +#define IRQ_SEC_SGI_3 11 +#define IRQ_SEC_SGI_4 12 +#define IRQ_SEC_SGI_5 13 +#define IRQ_SEC_SGI_6 14 +#define IRQ_SEC_SGI_7 15 +#define IRQ_SEC_SGI_8 16 + +/******************************************************************************* + * UART definitions + ******************************************************************************/ +#define AML_UART0_AO_BASE UL(0xFF803000) +#define AML_UART0_AO_CLK_IN_HZ AML_OSC24M_CLK_IN_HZ +#define AML_UART_BAUDRATE U(115200) + +/******************************************************************************* + * Memory-mapped I/O Registers + ******************************************************************************/ +#define AML_AO_TIMESTAMP_CNTL UL(0xFF8000B4) + +#define AML_SYS_CPU_CFG7 UL(0xFF634664) + +#define AML_AO_RTI_STATUS_REG3 UL(0xFF80001C) +#define AML_AO_RTI_SCP_STAT UL(0xFF80023C) +#define AML_AO_RTI_SCP_READY_OFF U(0x14) +#define AML_A0_RTI_SCP_READY_MASK U(3) +#define AML_AO_RTI_SCP_IS_READY(v) \ + ((((v) >> AML_AO_RTI_SCP_READY_OFF) & \ + AML_A0_RTI_SCP_READY_MASK) == AML_A0_RTI_SCP_READY_MASK) + +#define AML_HIU_MAILBOX_SET_0 UL(0xFF63C404) +#define AML_HIU_MAILBOX_STAT_0 UL(0xFF63C408) +#define AML_HIU_MAILBOX_CLR_0 UL(0xFF63C40C) +#define AML_HIU_MAILBOX_SET_3 UL(0xFF63C428) +#define AML_HIU_MAILBOX_STAT_3 UL(0xFF63C42C) +#define AML_HIU_MAILBOX_CLR_3 UL(0xFF63C430) + +#define AML_SHA_DMA_BASE UL(0xFF63E000) +#define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08) +#define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x28) + +/******************************************************************************* + * System Monitor Call IDs and arguments + ******************************************************************************/ +#define AML_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020) +#define AML_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021) + +#define AML_SM_EFUSE_READ U(0x82000030) +#define AML_SM_EFUSE_USER_MAX U(0x82000033) + +#define AML_SM_JTAG_ON U(0x82000040) +#define AML_SM_JTAG_OFF U(0x82000041) +#define AML_SM_GET_CHIP_ID U(0x82000044) + +#define AML_JTAG_STATE_ON U(0) +#define AML_JTAG_STATE_OFF U(1) + +#define AML_JTAG_M3_AO U(0) +#define AML_JTAG_M3_EE U(1) +#define AML_JTAG_A53_AO U(2) +#define AML_JTAG_A53_EE U(3) + +#endif /* AXG_DEF_H */ diff --git a/plat/amlogic/axg/axg_pm.c b/plat/amlogic/axg/axg_pm.c new file mode 100644 index 0000000000..e67f263a4b --- /dev/null +++ b/plat/amlogic/axg/axg_pm.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <assert.h> +#include <common/debug.h> +#include <drivers/arm/gicv2.h> +#include <drivers/console.h> +#include <errno.h> +#include <lib/mmio.h> +#include <lib/psci/psci.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +#include "aml_private.h" + +#define SCPI_POWER_ON 0 +#define SCPI_POWER_RETENTION 1 +#define SCPI_POWER_OFF 3 + +#define SCPI_SYSTEM_SHUTDOWN 0 +#define SCPI_SYSTEM_REBOOT 1 + +static uintptr_t axg_sec_entrypoint; + +static void axg_pm_set_reset_addr(u_register_t mpidr, uint64_t value) +{ + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4); + + mmio_write_64(cpu_mailbox_addr, value); +} + +static void axg_pm_reset(u_register_t mpidr, uint32_t value) +{ + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4) + 8; + + mmio_write_32(cpu_mailbox_addr, value); +} + +static void __dead2 axg_system_reset(void) +{ + u_register_t mpidr = read_mpidr_el1(); + int ret; + + INFO("BL31: PSCI_SYSTEM_RESET\n"); + + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_REBOOT); + if (ret != 0) { + ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %i\n", ret); + panic(); + } + + axg_pm_reset(mpidr, 0); + + wfi(); + + ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n"); + panic(); +} + +static void __dead2 axg_system_off(void) +{ + u_register_t mpidr = read_mpidr_el1(); + int ret; + + INFO("BL31: PSCI_SYSTEM_OFF\n"); + + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN); + if (ret != 0) { + ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %i\n", ret); + panic(); + } + + axg_pm_set_reset_addr(mpidr, 0); + axg_pm_reset(mpidr, 0); + + dmbsy(); + wfi(); + + ERROR("BL31: PSCI_SYSTEM_OFF: Operation not handled\n"); + panic(); +} + +static int32_t axg_pwr_domain_on(u_register_t mpidr) +{ + axg_pm_set_reset_addr(mpidr, axg_sec_entrypoint); + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON); + dmbsy(); + sev(); + + return PSCI_E_SUCCESS; +} + +static void axg_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); + + axg_pm_set_reset_addr(read_mpidr_el1(), 0); +} + +static void axg_pwr_domain_off(const psci_power_state_t *target_state) +{ + u_register_t mpidr = read_mpidr_el1(); + uint32_t system_state = SCPI_POWER_ON; + uint32_t cluster_state = SCPI_POWER_ON; + + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + axg_pm_reset(mpidr, -1); + + gicv2_cpuif_disable(); + + if (target_state->pwr_domain_state[MPIDR_AFFLVL2] == + PLAT_LOCAL_STATE_OFF) + system_state = SCPI_POWER_OFF; + + if (target_state->pwr_domain_state[MPIDR_AFFLVL1] == + PLAT_LOCAL_STATE_OFF) + cluster_state = SCPI_POWER_OFF; + + + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_OFF, cluster_state, + system_state); +} + +static void __dead2 axg_pwr_domain_pwr_down_wfi(const psci_power_state_t + *target_state) +{ + dsbsy(); + axg_pm_reset(read_mpidr_el1(), 0); + + for (;;) + wfi(); +} + +/******************************************************************************* + * Platform handlers and setup function. + ******************************************************************************/ +static const plat_psci_ops_t axg_ops = { + .pwr_domain_on = axg_pwr_domain_on, + .pwr_domain_on_finish = axg_pwr_domain_on_finish, + .pwr_domain_off = axg_pwr_domain_off, + .pwr_domain_pwr_down_wfi = axg_pwr_domain_pwr_down_wfi, + .system_off = axg_system_off, + .system_reset = axg_system_reset +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + axg_sec_entrypoint = sec_entrypoint; + *psci_ops = &axg_ops; + return 0; +} diff --git a/plat/amlogic/axg/include/platform_def.h b/plat/amlogic/axg/include/platform_def.h new file mode 100644 index 0000000000..a47cf7348e --- /dev/null +++ b/plat/amlogic/axg/include/platform_def.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <arch.h> +#include <lib/utils_def.h> + +#include "../axg_def.h" + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE UL(0x1000) + +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT + +#define AML_PRIMARY_CPU U(0) + +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(2) + +#define PLAT_SYS_CPU_CFG7 (U(1) << 25) +#define PLAT_AO_TIMESTAMP_CNTL U(0x1ff) + +/* Local power state for power domains in Run state. */ +#define PLAT_LOCAL_STATE_RUN U(0) +/* Local power state for retention. Valid only for CPU power domains */ +#define PLAT_LOCAL_STATE_RET U(1) +/* Local power state for power-down. Valid for CPU and cluster power domains. */ +#define PLAT_LOCAL_STATE_OFF U(2) + +/* + * Macros used to parse state information from State-ID if it is using the + * recommended encoding for State-ID. + */ +#define PLAT_LOCAL_PSTATE_WIDTH U(4) +#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1) + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_SHIFT U(6) +#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) + +/* Memory-related defines */ +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) + +#define MAX_MMAP_REGIONS 16 +#define MAX_XLAT_TABLES 8 + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk new file mode 100644 index 0000000000..3560b0cd18 --- /dev/null +++ b/plat/amlogic/axg/platform.mk @@ -0,0 +1,95 @@ +# +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include lib/xlat_tables_v2/xlat_tables.mk + +AML_PLAT := plat/amlogic +AML_PLAT_SOC := ${AML_PLAT}/${PLAT} +AML_PLAT_COMMON := ${AML_PLAT}/common + +DOIMAGEPATH ?= tools/amlogic +DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage + +PLAT_INCLUDES := -Iinclude/drivers/amlogic/ \ + -I${AML_PLAT_SOC}/include \ + -I${AML_PLAT_COMMON}/include + +GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + plat/common/plat_psci_common.c \ + drivers/amlogic/console/aarch64/meson_console.S \ + ${AML_PLAT_SOC}/${PLAT}_bl31_setup.c \ + ${AML_PLAT_SOC}/${PLAT}_pm.c \ + ${AML_PLAT_SOC}/${PLAT}_common.c \ + ${AML_PLAT_COMMON}/aarch64/aml_helpers.S \ + ${AML_PLAT_COMMON}/aml_efuse.c \ + ${AML_PLAT_COMMON}/aml_mhu.c \ + ${AML_PLAT_COMMON}/aml_scpi.c \ + ${AML_PLAT_COMMON}/aml_sip_svc.c \ + ${AML_PLAT_COMMON}/aml_thermal.c \ + ${AML_PLAT_COMMON}/aml_topology.c \ + ${AML_PLAT_COMMON}/aml_console.c \ + drivers/amlogic/crypto/sha_dma.c \ + ${XLAT_TABLES_LIB_SRCS} \ + ${GIC_SOURCES} + +# Tune compiler for Cortex-A53 +ifeq ($(notdir $(CC)),armclang) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else ifneq ($(findstring clang,$(notdir $(CC))),) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else + TF_CFLAGS_aarch64 += -mtune=cortex-a53 +endif + +# Build config flags +# ------------------ + +# Enable all errata workarounds for Cortex-A53 +ERRATA_A53_855873 := 1 +ERRATA_A53_819472 := 1 +ERRATA_A53_824069 := 1 +ERRATA_A53_827319 := 1 + +WORKAROUND_CVE_2017_5715 := 0 + +# Have different sections for code and rodata +SEPARATE_CODE_AND_RODATA := 1 + +# Use Coherent memory +USE_COHERENT_MEM := 1 + +AML_USE_ATOS := 0 +$(eval $(call assert_boolean,AML_USE_ATOS)) +$(eval $(call add_define,AML_USE_ATOS)) + +# Verify build config +# ------------------- + +ifneq (${RESET_TO_BL31}, 0) + $(error Error: ${PLAT} needs RESET_TO_BL31=0) +endif + +ifeq (${ARCH},aarch32) + $(error Error: AArch32 not supported on ${PLAT}) +endif + +all: ${BUILD_PLAT}/bl31.img +distclean realclean clean: cleanimage + +cleanimage: + ${Q}${MAKE} -C ${DOIMAGEPATH} clean + +${DOIMAGETOOL}: + ${Q}${MAKE} -C ${DOIMAGEPATH} + +${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL} + ${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img + diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index c71e932a0f..3c19230bd6 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,130 +8,61 @@ #include <stdint.h> #include <string.h> +#include <common/debug.h> +#include <drivers/arm/cryptocell/cc_rotpk.h> +#include <drivers/delay_timer.h> #include <lib/cassert.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/common/common_def.h> #include <plat/common/platform.h> -#include <tools_share/tbbr_oid.h> #include <platform_def.h> +#include <tools_share/tbbr_oid.h> -/* SHA256 algorithm */ -#define SHA256_BYTES 32 - -/* ROTPK locations */ -#define ARM_ROTPK_REGS_ID 1 -#define ARM_ROTPK_DEVEL_RSA_ID 2 -#define ARM_ROTPK_DEVEL_ECDSA_ID 3 - -static const unsigned char rotpk_hash_hdr[] = \ - "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \ - "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; -static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1; -static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES]; -/* Use the cryptocell variants if Cryptocell is present */ #if !ARM_CRYPTOCELL_INTEG #if !ARM_ROTPK_LOCATION_ID #error "ARM_ROTPK_LOCATION_ID not defined" #endif +#endif /* Weak definition may be overridden in specific platform */ #pragma weak plat_get_nv_ctr #pragma weak plat_set_nv_ctr -#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) -static const unsigned char arm_devel_rotpk_hash[] = \ - "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \ - "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \ - "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \ - "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA"; -#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) -static const unsigned char arm_devel_rotpk_hash[] = \ - "\x2E\x40\xBF\x6E\xF9\x12\xBB\x98" \ - "\x31\x71\x09\x0E\x1E\x15\x3D\x0B" \ - "\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B" \ - "\xA0\xB0\x20\x86\x4E\x6C\x07\x17"; -#endif +extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[]; + +static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; /* - * Return the ROTPK hash in the following ASN.1 structure in DER format: - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm AlgorithmIdentifier, - * digest OCTET STRING - * } + * Return the ROTPK hash stored in dedicated registers. */ -int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, +int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, unsigned int *flags) { uint8_t *dst; + uint32_t *src, tmp; + unsigned int words, i; assert(key_ptr != NULL); assert(key_len != NULL); assert(flags != NULL); /* Copy the DER header */ - memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); - dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len]; -#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \ - || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) - memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES); -#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) - uint32_t *src, tmp; - unsigned int words, i; + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + + words = ARM_ROTPK_HASH_LEN >> 2; - /* - * Append the hash from Trusted Root-Key Storage registers. The hash has - * not been written linearly into the registers, so we have to do a bit - * of byte swapping: - * - * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C - * +---------------------------------------------------------------+ - * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | - * +---------------------------------------------------------------+ - * | ... ... | | ... ... | - * | +--------------------+ | +-------+ - * | | | | - * +----------------------------+ +----------------------------+ - * | | | | - * +-------+ | +--------------------+ | - * | | | | - * v v v v - * +---------------------------------------------------------------+ - * | | | - * +---------------------------------------------------------------+ - * 0 15 16 31 - * - * Additionally, we have to access the registers in 32-bit words - */ - words = SHA256_BYTES >> 3; - - /* Swap bytes 0-15 (first four registers) */ src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; for (i = 0 ; i < words ; i++) { tmp = src[words - 1 - i]; /* Words are read in little endian */ - *dst++ = (uint8_t)((tmp >> 24) & 0xFF); - *dst++ = (uint8_t)((tmp >> 16) & 0xFF); - *dst++ = (uint8_t)((tmp >> 8) & 0xFF); *dst++ = (uint8_t)(tmp & 0xFF); - } - - /* Swap bytes 16-31 (last four registers) */ - src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2); - for (i = 0 ; i < words ; i++) { - tmp = src[words - 1 - i]; - *dst++ = (uint8_t)((tmp >> 24) & 0xFF); - *dst++ = (uint8_t)((tmp >> 16) & 0xFF); *dst++ = (uint8_t)((tmp >> 8) & 0xFF); - *dst++ = (uint8_t)(tmp & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); } -#endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \ - || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */ *key_ptr = (void *)rotpk_hash_der; *key_len = (unsigned int)sizeof(rotpk_hash_der); @@ -139,6 +70,65 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, return 0; } +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) +/* + * Return development ROTPK hash generated from ROT_KEY. + */ +int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + *key_ptr = arm_rotpk_header; + *key_len = arm_rotpk_hash_end - arm_rotpk_header; + *flags = ROTPK_IS_HASH; + return 0; +} +#endif + +#if ARM_CRYPTOCELL_INTEG +/* + * Return ROTPK hash from CryptoCell. + */ +int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + unsigned char *dst; + + assert(key_ptr != NULL); + assert(key_len != NULL); + assert(flags != NULL); + + /* Copy the DER header */ + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + *key_ptr = rotpk_hash_der; + *key_len = sizeof(rotpk_hash_der); + return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags); +} +#endif + +/* + * Wraper function for most Arm platforms to get ROTPK hash. + */ +int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ +#if ARM_CRYPTOCELL_INTEG + return arm_get_rotpk_info_cc(key_ptr, key_len, flags); +#else + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) + return arm_get_rotpk_info_dev(key_ptr, key_len, flags); +#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + return arm_get_rotpk_info_regs(key_ptr, key_len, flags); +#else + return 1; +#endif + +#endif /* ARM_CRYPTOCELL_INTEG */ +} + /* * Return the non-volatile counter value stored in the platform. The cookie * will contain the OID of the counter in the certificate. @@ -179,37 +169,3 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) { return 1; } -#else /* ARM_CRYPTOCELL_INTEG */ - -#include <drivers/arm/cryptocell/cc_rotpk.h> - -/* - * Return the ROTPK hash in the following ASN.1 structure in DER format: - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm AlgorithmIdentifier, - * digest OCTET STRING - * } - */ -int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, - unsigned int *flags) -{ - unsigned char *dst; - - assert(key_ptr != NULL); - assert(key_len != NULL); - assert(flags != NULL); - - /* Copy the DER header */ - memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); - dst = &rotpk_hash_der[rotpk_hash_hdr_len]; - *key_ptr = rotpk_hash_der; - *key_len = sizeof(rotpk_hash_der); - return cc_get_rotpk_hash(dst, SHA256_BYTES, flags); -} -#endif /* ARM_CRYPTOCELL_INTEG */ diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index b98dfd48b2..da63430454 100644 --- a/plat/arm/board/common/board_common.mk +++ b/plat/arm/board/common/board_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -12,31 +12,60 @@ BL1_SOURCES += drivers/cfi/v2m/v2m_flash.c BL2_SOURCES += drivers/cfi/v2m/v2m_flash.c ifneq (${TRUSTED_BOARD_BOOT},0) - ifneq (${ARM_CRYPTOCELL_INTEG}, 1) - # ROTPK hash location - ifeq (${ARM_ROTPK_LOCATION}, regs) - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID - else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa) - KEY_ALG := rsa - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID - else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa) - KEY_ALG := ecdsa - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID - else - $(error "Unsupported ARM_ROTPK_LOCATION value") - endif - $(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) - - # Certificate NV-Counters. Use values corresponding to tied off values in - # ARM development platforms - TFW_NVCTR_VAL ?= 31 - NTFW_NVCTR_VAL ?= 223 - else - # Certificate NV-Counters when CryptoCell is integrated. For development - # platforms we set the counter to first valid value. - TFW_NVCTR_VAL ?= 0 - NTFW_NVCTR_VAL ?= 0 - endif - BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c - BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c +ifneq (${ARM_CRYPTOCELL_INTEG}, 1) +# ROTPK hash location +ifeq (${ARM_ROTPK_LOCATION}, regs) + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID +else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa) + KEY_ALG := rsa + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID + ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin +$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) +$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH) +$(warning Development keys support for FVP is deprecated. Use `regs` \ +option instead) +else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa) + KEY_ALG := ecdsa + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID + ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin +$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) +$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH) +$(warning Development keys support for FVP is deprecated. Use `regs` \ +option instead) +else + $(error "Unsupported ARM_ROTPK_LOCATION value") +endif + +$(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) + +# Force generation of the new hash if ROT_KEY is specified +ifdef ROT_KEY + HASH_PREREQUISITES = $(ROT_KEY) FORCE +FORCE: +else + HASH_PREREQUISITES = $(ROT_KEY) +endif + +$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES) +ifndef ROT_KEY + $(error Cannot generate hash: no ROT_KEY defined) +endif + openssl rsa -in $< -pubout -outform DER | openssl dgst \ + -sha256 -binary > $@ + +# Certificate NV-Counters. Use values corresponding to tied off values in +# ARM development platforms +TFW_NVCTR_VAL ?= 31 +NTFW_NVCTR_VAL ?= 223 +else +# Certificate NV-Counters when CryptoCell is integrated. For development +# platforms we set the counter to first valid value. +TFW_NVCTR_VAL ?= 0 +NTFW_NVCTR_VAL ?= 0 +endif +BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ + plat/arm/board/common/rotpk/arm_dev_rotpk.S +BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ + plat/arm/board/common/rotpk/arm_dev_rotpk.S + endif diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S new file mode 100644 index 0000000000..80f2192e4d --- /dev/null +++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "plat/arm/common/arm_def.h" + + .global arm_rotpk_header + .global arm_rotpk_header_end + .section .rodata.arm_rotpk_hash, "a" + +arm_rotpk_header: + .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48 + .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +arm_rotpk_header_len: + +#ifdef ARM_ROTPK_HASH + .global arm_rotpk_hash_end + .incbin ARM_ROTPK_HASH +arm_rotpk_hash_end: +#endif + +.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header +.error "Invalid ROTPK header length." +.endif diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c index dc50764356..a09b80e10b 100644 --- a/plat/arm/board/fvp/fvp_trusted_boot.c +++ b/plat/arm/board/fvp/fvp_trusted_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,12 +9,31 @@ #include <string.h> #include <lib/mmio.h> - +#include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> #include <platform_def.h> #include <tools_share/tbbr_oid.h> /* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} + +/* * Store a new non-volatile counter value. * * On some FVP versions, the non-volatile counters are read-only so this diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 97a326c092..6fb34c48ab 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -139,7 +139,6 @@ BL1_SOURCES += drivers/arm/smmu/smmu_v3.c \ plat/arm/board/fvp/fvp_bl1_setup.c \ plat/arm/board/fvp/fvp_err.c \ plat/arm/board/fvp/fvp_io_storage.c \ - plat/arm/board/fvp/fvp_trusted_boot.c \ ${FVP_CPU_LIBS} \ ${FVP_INTERCONNECT_SOURCES} @@ -158,7 +157,6 @@ BL2_SOURCES += drivers/arm/sp805/sp805.c \ plat/arm/board/fvp/fvp_bl2_setup.c \ plat/arm/board/fvp/fvp_err.c \ plat/arm/board/fvp/fvp_io_storage.c \ - plat/arm/board/fvp/fvp_trusted_boot.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ ${FVP_SECURITY_SOURCES} @@ -302,8 +300,10 @@ endif include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c +BL2_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c # FVP being a development platform, enable capability to disable Authentication # dynamically if TRUSTED_BOARD_BOOT is set. -ifeq (${TRUSTED_BOARD_BOOT}, 1) - DYN_DISABLE_AUTH := 1 +DYN_DISABLE_AUTH := 1 endif diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 16bb33d7ef..eddd7e5704 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -224,7 +224,6 @@ /* MHU related constants */ #define PLAT_CSS_MHU_BASE UL(0x2b1f0000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* * Base address of the first memory region used for communication between AP @@ -301,4 +300,7 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c index 052ab9f8a7..075f512c36 100644 --- a/plat/arm/board/juno/juno_topology.c +++ b/plat/arm/board/juno/juno_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,7 +20,7 @@ static scmi_channel_plat_info_t juno_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell, }; -scmi_channel_plat_info_t *plat_css_get_scmi_info(void) +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &juno_scmi_plat_info; } diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c new file mode 100644 index 0000000000..25a74705d9 --- /dev/null +++ b/plat/arm/board/juno/juno_trusted_boot.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <string.h> + +#include <drivers/arm/cryptocell/cc_rotpk.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/common/common_def.h> +#include <plat/common/platform.h> + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + +static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; + +extern unsigned char arm_rotpk_header[]; + +/* + * Return the ROTPK hash stored in the registers of Juno board. + */ +static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + uint8_t *dst; + uint32_t *src, tmp; + unsigned int words, i; + + assert(key_ptr != NULL); + assert(key_len != NULL); + assert(flags != NULL); + + /* Copy the DER header */ + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + + + /* + * Append the hash from Trusted Root-Key Storage registers. The hash has + * not been written linearly into the registers, so we have to do a bit + * of byte swapping: + * + * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C + * +---------------------------------------------------------------+ + * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | + * +---------------------------------------------------------------+ + * | ... ... | | ... ... | + * | +--------------------+ | +-------+ + * | | | | + * +----------------------------+ +----------------------------+ + * | | | | + * +-------+ | +--------------------+ | + * | | | | + * v v v v + * +---------------------------------------------------------------+ + * | | | + * +---------------------------------------------------------------+ + * 0 15 16 31 + * + * Additionally, we have to access the registers in 32-bit words + */ + words = ARM_ROTPK_HASH_LEN >> 3; + + /* Swap bytes 0-15 (first four registers) */ + src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + /* Words are read in little endian */ + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } + + /* Swap bytes 16-31 (last four registers) */ + src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2); + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } + + *key_ptr = (void *)rotpk_hash_der; + *key_len = (unsigned int)sizeof(rotpk_hash_der); + *flags = ROTPK_IS_HASH; + return 0; +} + +#endif + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ +#if ARM_CRYPTOCELL_INTEG + return arm_get_rotpk_info_cc(key_ptr, key_len, flags); +#else + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) + return arm_get_rotpk_info_dev(key_ptr, key_len, flags); +#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + return juno_get_rotpk_info_regs(key_ptr, key_len, flags); +#else + return 1; +#endif + +#endif /* ARM_CRYPTOCELL_INTEG */ +} diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index bd6bae536d..a85ad53761 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -91,6 +91,11 @@ ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) BL1_SOURCES += drivers/arm/css/sds/sds.c endif +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += plat/arm/board/juno/juno_trusted_boot.c +BL2_SOURCES += plat/arm/board/juno/juno_trusted_boot.c +endif + endif ifneq (${RESET_TO_BL31},0) diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index 6a309e8e16..cc07852c27 100644 --- a/plat/arm/board/n1sdp/include/platform_def.h +++ b/plat/arm/board/n1sdp/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -90,7 +90,6 @@ #define PLAT_ARM_NSTIMER_FRAME_ID 0 #define PLAT_CSS_MHU_BASE 0x45000000 -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE #define PLAT_MAX_PWR_LVL 2 #define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \ @@ -144,4 +143,7 @@ #define SBSA_SECURE_WDOG_BASE UL(0x2A480000) #define SBSA_SECURE_WDOG_TIMEOUT UL(100) +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index b150b89599..136287a8da 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -74,7 +74,7 @@ static uintptr_t n1sdp_multichip_gicr_frames[3] = { 0 }; -scmi_channel_plat_info_t *plat_css_get_scmi_info() +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &n1sdp_scmi_plat_info; } diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts new file mode 100644 index 0000000000..4d4580d68b --- /dev/null +++ b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +/ { + /* compatible string */ + compatible = "arm,rd-daniel"; + + /* + * Place holder for system-id node with default values. The + * value of platform-id and config-id will be set to the + * correct values during the BL2 stage of boot. + */ + system-id { + platform-id = <0x0>; + config-id = <0x0>; + multi-chip-mode = <0x0>; + }; +}; diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts new file mode 100644 index 0000000000..9acec137e7 --- /dev/null +++ b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + /* Platform Config */ + compatible = "arm,tb_fw"; + nt_fw_config_addr = <0x0 0xFEF00000>; + nt_fw_config_max_size = <0x0100000>; + + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; +}; diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h new file mode 100644 index 0000000000..516360278e --- /dev/null +++ b/plat/arm/board/rddaniel/include/platform_def.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <lib/utils_def.h> + +#include <sgi_base_platform_def.h> + +#define PLAT_ARM_CLUSTER_COUNT U(16) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1) +#define CSS_SGI_MAX_PE_PER_CPU U(1) + +#define PLAT_CSS_MHU_BASE UL(0x45400000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE + +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + +/* + * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes + */ +#ifdef __aarch64__ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x30140000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk new file mode 100644 index 0000000000..67f57779a2 --- /dev/null +++ b/plat/arm/board/rddaniel/platform.mk @@ -0,0 +1,43 @@ +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include plat/arm/css/sgi/sgi-common.mk + +RDDANIEL_BASE = plat/arm/board/rddaniel + +PLAT_INCLUDES += -I${RDDANIEL_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_zeus.S + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDDANIEL_BASE}/rddaniel_err.c + +BL2_SOURCES += ${RDDANIEL_BASE}/rddaniel_plat.c \ + ${RDDANIEL_BASE}/rddaniel_security.c \ + ${RDDANIEL_BASE}/rddaniel_err.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDDANIEL_BASE}/rddaniel_plat.c \ + ${RDDANIEL_BASE}/rddaniel_topology.c \ + drivers/cfi/v2m/v2m_flash.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) + +FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_nt_fw_config.dts +NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb + +# Add the NT_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) + +override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rddaniel/rddaniel_err.c b/plat/arm/board/rddaniel/rddaniel_err.c new file mode 100644 index 0000000000..5e10942199 --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_err.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * rddaniel error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (1) { + wfi(); + } +} diff --git a/plat/arm/board/rddaniel/rddaniel_plat.c b/plat/arm/board/rddaniel/rddaniel_plat.c new file mode 100644 index 0000000000..ab5251e511 --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_plat.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/common/platform.h> +#include <sgi_plat.h> + +unsigned int plat_arm_sgi_get_platform_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) + & SID_SYSTEM_ID_PART_NUM_MASK; +} + +unsigned int plat_arm_sgi_get_config_id(void) +{ + return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); +} + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; +} + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/rddaniel/rddaniel_security.c b/plat/arm/board/rddaniel/rddaniel_security.c new file mode 100644 index 0000000000..6aa38c822c --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_security.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <platform_def.h> + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/board/rddaniel/rddaniel_topology.c b/plat/arm/board/rddaniel/rddaniel_topology.c new file mode 100644 index 0000000000..55f5e04da5 --- /dev/null +++ b/plat/arm/board/rddaniel/rddaniel_topology.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> +#include <plat/arm/css/common/css_pm.h> + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +const unsigned char rd_daniel_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return rd_daniel_pd_tree_desc; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)) +}; diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts index 41769217a9..0af821e15d 100644 --- a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,6 +17,7 @@ system-id { platform-id = <0x0>; config-id = <0x0>; + multi-chip-mode = <0x0>; }; }; diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h index 2be3f8852f..3fb640972a 100644 --- a/plat/arm/board/rde1edge/include/platform_def.h +++ b/plat/arm/board/rde1edge/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,6 @@ #define CSS_SGI_MAX_PE_PER_CPU U(2) #define PLAT_CSS_MHU_BASE UL(0x45400000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* Base address of DMC-620 instances */ #define RDE1EDGE_DMC620_BASE0 UL(0x4e000000) @@ -37,4 +36,9 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index 43c37ffc11..88aa634b86 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -29,6 +29,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c +BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb @@ -42,4 +47,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +ifneq ($(CSS_SGI_CHIP_COUNT),1) + $(error "Chip count for RDE1Edge should be 1, currently set to \ + ${CSS_SGI_CHIP_COUNT}.") +endif + override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c index a1b8d621d6..44d818aecb 100644 --- a/plat/arm/board/rde1edge/rde1edge_plat.c +++ b/plat/arm/board/rde1edge/rde1edge_plat.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <plat/common/platform.h> +#include <sgi_plat.h> unsigned int plat_arm_sgi_get_platform_id(void) { @@ -16,3 +17,13 @@ unsigned int plat_arm_sgi_get_config_id(void) { return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); } + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return 0; +} + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c index 0b56f208ae..a16283e450 100644 --- a/plat/arm/board/rde1edge/rde1edge_topology.c +++ b/plat/arm/board/rde1edge/rde1edge_topology.c @@ -7,12 +7,15 @@ #include <plat/arm/common/plat_arm.h> /****************************************************************************** - * The power domain tree descriptor. + * The power domain tree descriptor. RD-E1-Edge platform consists of two + * clusters with eight CPUs in each cluster. The CPUs are multi-threaded with + * two threads per CPU. ******************************************************************************/ static const unsigned char rde1edge_pd_tree_desc[] = { + CSS_SGI_CHIP_COUNT, PLAT_ARM_CLUSTER_COUNT, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER + CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU, + CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU }; /****************************************************************************** diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c new file mode 100644 index 0000000000..c271f7f2dc --- /dev/null +++ b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts index fff5874769..68366c5ca1 100644 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,5 +17,6 @@ system-id { platform-id = <0x0>; config-id = <0x0>; + multi-chip-mode = <0x0>; }; }; diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h index c635faa441..ab63e23ece 100644 --- a/plat/arm/board/rdn1edge/include/platform_def.h +++ b/plat/arm/board/rdn1edge/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,6 @@ #define CSS_SGI_MAX_PE_PER_CPU U(1) #define PLAT_CSS_MHU_BASE UL(0x45400000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* Base address of DMC-620 instances */ #define RDN1EDGE_DMC620_BASE0 UL(0x4e000000) @@ -27,15 +26,23 @@ #define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 +/* Virtual address used by dynamic mem_protect for chunk_base */ +#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) + /* * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes */ #ifdef __aarch64__ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43) #else #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index ca1e95eaf0..04f70f3f25 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -26,9 +26,18 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ ${RDN1EDGE_BASE}/rdn1edge_plat.c \ ${RDN1EDGE_BASE}/rdn1edge_topology.c \ drivers/cfi/v2m/v2m_flash.c \ + drivers/arm/gic/v3/gic600_multichip.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +endif + +# Enable dynamic addition of MMAP regions in BL31 +BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb @@ -42,4 +51,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) +ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),1 2)) + $(error "Chip count for RDN1Edge platform should either 1 or 2, currently \ + set to ${CSS_SGI_CHIP_COUNT}.") +endif + override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c index 3b7e5ee4e4..f62c6f402b 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_plat.c +++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c @@ -1,10 +1,44 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <common/debug.h> +#include <drivers/arm/gic600_multichip.h> +#include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> +#include <sgi_base_platform_def.h> +#include <sgi_plat.h> + +#if defined(IMAGE_BL31) +static const mmap_region_t rdn1edge_dynamic_mmap[] = { + ARM_MAP_SHARED_RAM_REMOTE_CHIP(1), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1) +}; + +static struct gic600_multichip_data rdn1e1_multichip_data __init = { + .rt_owner_base = PLAT_ARM_GICD_BASE, + .rt_owner = 0, + .chip_count = CSS_SGI_CHIP_COUNT, + .chip_addrs = { + PLAT_ARM_GICD_BASE >> 16, + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16 + }, + .spi_ids = { + {32, 255}, + {0, 0} + } +}; + +static uintptr_t rdn1e1_multichip_gicr_frames[] = { + PLAT_ARM_GICR_BASE, /* Chip 0's GICR Base */ + PLAT_ARM_GICR_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), /* Chip 1's GICR BASE */ + UL(0) /* Zero Termination */ +}; +#endif /* IMAGE_BL31 */ unsigned int plat_arm_sgi_get_platform_id(void) { @@ -16,3 +50,48 @@ unsigned int plat_arm_sgi_get_config_id(void) { return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET); } + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) & + SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT; +} + +/* + * IMAGE_BL31 macro is added to build bl31_platform_setup function only for BL31 + * because PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not + * for other stages. + */ +#if defined(IMAGE_BL31) +void bl31_platform_setup(void) +{ + int i, ret; + + if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) { + ERROR("Chip Count is set to %d but multi-chip mode not enabled\n", + CSS_SGI_CHIP_COUNT); + panic(); + } else if (plat_arm_sgi_get_multi_chip_mode() == 1 && + CSS_SGI_CHIP_COUNT > 1) { + INFO("Enabling support for multi-chip in RD-N1-Edge\n"); + + for (i = 0; i < ARRAY_SIZE(rdn1edge_dynamic_mmap); i++) { + ret = mmap_add_dynamic_region( + rdn1edge_dynamic_mmap[i].base_pa, + rdn1edge_dynamic_mmap[i].base_va, + rdn1edge_dynamic_mmap[i].size, + rdn1edge_dynamic_mmap[i].attr + ); + if (ret != 0) { + ERROR("Failed to add dynamic mmap entry\n"); + panic(); + } + } + + plat_arm_override_gicr_frames(rdn1e1_multichip_gicr_frames); + gic600_multichip_init(&rdn1e1_multichip_data); + } + + sgi_bl31_common_platform_setup(); +} +#endif /* IMAGE_BL31 */ diff --git a/plat/arm/board/rdn1edge/rdn1edge_topology.c b/plat/arm/board/rdn1edge/rdn1edge_topology.c index 687ae35953..5bbea6998c 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_topology.c +++ b/plat/arm/board/rdn1edge/rdn1edge_topology.c @@ -5,14 +5,19 @@ */ #include <plat/arm/common/plat_arm.h> +#include <plat/arm/css/common/css_pm.h> /****************************************************************************** * The power domain tree descriptor. ******************************************************************************/ static const unsigned char rdn1edge_pd_tree_desc[] = { - PLAT_ARM_CLUSTER_COUNT, + (PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT), + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#if (CSS_SGI_CHIP_COUNT > 1) CSS_SGI_MAX_CPUS_PER_CLUSTER, CSS_SGI_MAX_CPUS_PER_CLUSTER +#endif }; /******************************************************************************* @@ -28,5 +33,22 @@ const unsigned char *plat_get_power_domain_tree_desc(void) * to the SCMI power domain ID implemented by SCP. ******************************************************************************/ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { - 0, 1, 2, 3, 4, 5, 6, 7 + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)), +#if (CSS_SGI_CHIP_COUNT > 1) + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x4)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x5)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x6)), + (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x7)), +#endif }; diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c new file mode 100644 index 0000000000..c271f7f2dc --- /dev/null +++ b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts index 1e1ea14b0e..260247a0d8 100644 --- a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts +++ b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,5 +17,6 @@ system-id { platform-id = <0x0>; config-id = <0x0>; + multi-chip-mode = <0x0>; }; }; diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h index fd59e5277e..95986cf4a3 100644 --- a/plat/arm/board/sgi575/include/platform_def.h +++ b/plat/arm/board/sgi575/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,6 @@ #define CSS_SGI_MAX_PE_PER_CPU U(1) #define PLAT_CSS_MHU_BASE UL(0x45000000) -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE /* Base address of DMC-620 instances */ #define SGI575_DMC620_BASE0 UL(0x4e000000) @@ -38,4 +37,9 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index ce2717fe02..76cc4e2c2e 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -29,6 +29,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c +BL2_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb @@ -41,3 +46,8 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config)) + +ifneq ($(CSS_SGI_CHIP_COUNT),1) + $(error "Chip count for SGI575 should be 1, currently set to \ + ${CSS_SGI_CHIP_COUNT}.") +endif diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/sgi575/sgi575_plat.c index 0d3fd16ab6..dc294e6a8d 100644 --- a/plat/arm/board/sgi575/sgi575_plat.c +++ b/plat/arm/board/sgi575/sgi575_plat.c @@ -1,11 +1,11 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <plat/common/platform.h> - +#include <sgi_plat.h> #include <sgi_variant.h> unsigned int plat_arm_sgi_get_platform_id(void) @@ -18,3 +18,13 @@ unsigned int plat_arm_sgi_get_config_id(void) return (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT) & SSC_VERSION_CONFIG_MASK; } + +unsigned int plat_arm_sgi_get_multi_chip_mode(void) +{ + return 0; +} + +void bl31_platform_setup(void) +{ + sgi_bl31_common_platform_setup(); +} diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/sgi575/sgi575_trusted_boot.c new file mode 100644 index 0000000000..c271f7f2dc --- /dev/null +++ b/plat/arm/board/sgi575/sgi575_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index 7a843c369c..f096ca53d3 100644 --- a/plat/arm/board/sgm775/platform.mk +++ b/plat/arm/board/sgm775/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,3 +21,8 @@ BL2_SOURCES += lib/utils/mem_region.c \ BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c + +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c +BL2_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c +endif diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c new file mode 100644 index 0000000000..c271f7f2dc --- /dev/null +++ b/plat/arm/board/sgm775/sgm775_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S index b80903d061..04bfb77718 100644 --- a/plat/arm/css/sgi/aarch64/sgi_helper.S +++ b/plat/arm/css/sgi/aarch64/sgi_helper.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,19 +18,22 @@ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) * * Helper function to calculate the core position. + * (ChipId * PLAT_ARM_CLUSTER_COUNT * + * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) + * (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) + * (CPUId * CSS_SGI_MAX_PE_PER_CPU) + * ThreadId * * which can be simplified as: * - * ((ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER + CPUId) * - * CSS_SGI_MAX_PE_PER_CPU) + ThreadId + * ((((ChipId * PLAT_ARM_CLUSTER_COUNT) + ClusterId) * + * CSS_SGI_MAX_CPUS_PER_CLUSTER) + CPUId) * CSS_SGI_MAX_PE_PER_CPU + + * ThreadId * ------------------------------------------------------ */ func plat_arm_calc_core_pos - mov x3, x0 + mov x4, x0 /* * The MT bit in MPIDR is always set for SGI platforms @@ -38,15 +41,18 @@ func plat_arm_calc_core_pos */ /* Extract individual affinity fields from MPIDR */ - ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS /* Compute linear position */ + mov x4, #PLAT_ARM_CLUSTER_COUNT + madd x2, x3, x4, x2 mov x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER madd x1, x2, x4, x1 - mov x5, #CSS_SGI_MAX_PE_PER_CPU - madd x0, x1, x5, x0 + mov x4, #CSS_SGI_MAX_PE_PER_CPU + madd x0, x1, x4, x0 ret endfunc plat_arm_calc_core_pos diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h index e21457304b..4986378e99 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,12 +17,16 @@ #include <plat/arm/soc/common/soc_css_def.h> #include <plat/common/common_def.h> -#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ - CSS_SGI_MAX_CPUS_PER_CLUSTER * \ +#define PLATFORM_CORE_COUNT (CSS_SGI_CHIP_COUNT * \ + PLAT_ARM_CLUSTER_COUNT * \ + CSS_SGI_MAX_CPUS_PER_CLUSTER * \ CSS_SGI_MAX_PE_PER_CPU) #define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */ +/* Remote chip address offset (4TB per chip) */ +#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) ((ULL(1) << 42) * (n)) + /* * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the * plat_arm_mmap array defined for each BL stage. @@ -35,14 +39,14 @@ # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else # define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 8 # endif #elif defined(IMAGE_BL32) # define PLAT_ARM_MMAP_ENTRIES 8 # define MAX_XLAT_TABLES 5 #elif !USE_ROMLIB # define PLAT_ARM_MMAP_ENTRIES 11 -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 7 #else # define PLAT_ARM_MMAP_ENTRIES 12 # define MAX_XLAT_TABLES 6 @@ -129,10 +133,29 @@ CSS_SGI_DEVICE_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -/* GIC related constants */ -#define PLAT_ARM_GICD_BASE 0x30000000 -#define PLAT_ARM_GICC_BASE 0x2C000000 -#define PLAT_ARM_GICR_BASE 0x300C0000 +#define ARM_MAP_SHARED_RAM_REMOTE_CHIP(n) \ + MAP_REGION_FLAT( \ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ + ARM_SHARED_RAM_BASE, \ + ARM_SHARED_RAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE \ + ) + +#define CSS_SGI_MAP_DEVICE_REMOTE_CHIP(n) \ + MAP_REGION_FLAT( \ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ + CSS_SGI_DEVICE_BASE, \ + CSS_SGI_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE \ + ) + +#define SOC_CSS_MAP_DEVICE_REMOTE_CHIP(n) \ + MAP_REGION_FLAT( \ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \ + SOC_CSS_DEVICE_BASE, \ + SOC_CSS_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE \ + ) /* Map the secure region for access from S-EL0 */ #define PLAT_ARM_SECURE_MAP_DEVICE MAP_REGION_FLAT( \ @@ -212,4 +235,7 @@ #define SBSA_SECURE_WDOG_BASE UL(0x2A480000) #define SBSA_SECURE_WDOG_TIMEOUT UL(100) +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT CSS_SGI_CHIP_COUNT + #endif /* SGI_BASE_PLATFORM_DEF_H */ diff --git a/plat/arm/css/sgi/include/sgi_plat.h b/plat/arm/css/sgi/include/sgi_plat.h new file mode 100644 index 0000000000..a5fbded3ca --- /dev/null +++ b/plat/arm/css/sgi/include/sgi_plat.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI_PLAT_H +#define SGI_PLAT_H + +/* BL31 platform setup common to all SGI based platforms */ +void sgi_bl31_common_platform_setup(void); + +#endif /* SGI_PLAT_H */ diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h index c75f2132b9..f4c5300d09 100644 --- a/plat/arm/css/sgi/include/sgi_variant.h +++ b/plat/arm/css/sgi/include/sgi_variant.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,16 +8,21 @@ #define SGI_VARIANT_H /* SSC_VERSION values for SGI575 */ -#define SGI575_SSC_VER_PART_NUM 0x0783 +#define SGI575_SSC_VER_PART_NUM 0x0783 /* SID Version values for RD-N1E1-Edge */ #define RD_N1E1_EDGE_SID_VER_PART_NUM 0x0786 #define RD_E1_EDGE_CONFIG_ID 0x2 +/* SID Version values for RD-Daniel */ +#define RD_DANIEL_SID_VER_PART_NUM 0x078a + /* Structure containing SGI platform variant information */ typedef struct sgi_platform_info { unsigned int platform_id; /* Part Number of the platform */ unsigned int config_id; /* Config Id of the platform */ + unsigned int chip_id; /* Chip Id or Node number */ + unsigned int multi_chip_mode; /* Multi-chip mode availability */ } sgi_platform_info_t; extern sgi_platform_info_t sgi_plat_info; @@ -28,4 +33,7 @@ unsigned int plat_arm_sgi_get_platform_id(void); /* returns the configuration id of the platform */ unsigned int plat_arm_sgi_get_config_id(void); +/* returns true if operating in multi-chip configuration */ +unsigned int plat_arm_sgi_get_multi_chip_mode(void); + #endif /* SGI_VARIANT_H */ diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index 71601118f6..40a7fd8a3e 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -16,6 +16,8 @@ EL3_EXCEPTION_HANDLING := 0 HANDLE_EA_EL3_FIRST := 0 +CSS_SGI_CHIP_COUNT := 1 + INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c PLAT_INCLUDES += -I${CSS_ENT_BASE}/include @@ -52,6 +54,8 @@ endif $(eval $(call add_define,SGI_PLAT)) +$(eval $(call add_define,CSS_SGI_CHIP_COUNT)) + override CSS_LOAD_SCP_IMAGES := 0 override NEED_BL2U := no override ARM_BL31_IN_DRAM := 1 diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index ba050d5f1c..fcb7e1f9fa 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -28,18 +28,57 @@ static scmi_channel_plat_info_t sgi575_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell, }; -static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info = { +static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = { + { .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE, .db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0), .db_preserve_mask = 0xfffffffe, .db_modify_mask = 0x1, .ring_doorbell = &mhuv2_ring_doorbell, + }, + #if (CSS_SGI_CHIP_COUNT > 1) + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), + .db_reg_addr = PLAT_CSS_MHU_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + }, + #endif + #if (CSS_SGI_CHIP_COUNT > 2) + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2), + .db_reg_addr = PLAT_CSS_MHU_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + }, + #endif + #if (CSS_SGI_CHIP_COUNT > 3) + { + .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3), + .db_reg_addr = PLAT_CSS_MHU_BASE + + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0), + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhuv2_ring_doorbell, + }, + #endif }; -scmi_channel_plat_info_t *plat_css_get_scmi_info(void) +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { - if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) - return &rd_n1e1_edge_scmi_plat_info; + if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM || + sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM) { + if (channel_id >= sizeof(rd_n1e1_edge_scmi_plat_info)) + panic(); + return &rd_n1e1_edge_scmi_plat_info[channel_id]; + } else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM) return &sgi575_scmi_plat_info; else @@ -51,11 +90,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { sgi_plat_info.platform_id = plat_arm_sgi_get_platform_id(); sgi_plat_info.config_id = plat_arm_sgi_get_config_id(); + sgi_plat_info.multi_chip_mode = plat_arm_sgi_get_multi_chip_mode(); arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); } -void bl31_platform_setup(void) +void sgi_bl31_common_platform_setup(void) { arm_bl31_platform_setup(); @@ -66,9 +106,13 @@ void bl31_platform_setup(void) const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { - /* For RD-E1-Edge platform only CPU ON/OFF is supported */ - if ((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) && - (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) { + /* + * For RD-E1-Edge and RD-Daniel platforms, only CPU power ON/OFF + * PSCI platform callbacks are supported. + */ + if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) && + (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) || + (sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM)) { ops->cpu_standby = NULL; ops->system_off = NULL; ops->system_reset = NULL; diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c index a2f10dcc7f..09f3b728db 100644 --- a/plat/arm/css/sgi/sgi_image_load.c +++ b/plat/arm/css/sgi/sgi_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -62,6 +62,13 @@ static int plat_sgi_append_config_node(void) return -1; } + platcfg = plat_arm_sgi_get_multi_chip_mode(); + err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg); + if (err < 0) { + ERROR("Failed to set multi-chip-mode\n"); + return -1; + } + flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size); return 0; diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index 24bbed513f..90511ac6a7 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -86,7 +86,6 @@ /* MHU related constants */ #define PLAT_CSS_MHU_BASE 0x2b1f0000 -#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE #define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000 #define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 @@ -239,4 +238,7 @@ /* System power domain level */ #define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +/* Number of SCMI channels on the platform */ +#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) + #endif /* SGM_BASE_PLATFORM_DEF_H */ diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c index 7e92ac8350..907e9fdacf 100644 --- a/plat/arm/css/sgm/sgm_bl31_setup.c +++ b/plat/arm/css/sgm/sgm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,7 +20,7 @@ static scmi_channel_plat_info_t sgm775_scmi_plat_info = { .ring_doorbell = &mhu_ring_doorbell, }; -scmi_channel_plat_info_t *plat_css_get_scmi_info() +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) { return &sgm775_scmi_plat_info; } diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index 13099b40fe..4b11440955 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -14,6 +14,7 @@ #include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables.h> +#include "socfpga_mailbox.h" #include "socfpga_private.h" static entry_point_info_t bl32_image_ep_info; @@ -107,6 +108,8 @@ void bl31_platform_setup(void) /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ mmio_write_64(PLAT_CPU_RELEASE_ADDR, (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_agilex_mmap[] = { diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index c4b9e59671..38f46963a4 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -73,6 +73,29 @@ /* Mailbox REBOOT commands */ #define MBOX_CMD_REBOOT_HPS 71 +/* Mailbox RSU commands */ +#define MBOX_GET_SUBPARTITION_TABLE 90 +#define MBOX_RSU_STATUS 91 +#define MBOX_RSU_UPDATE 92 + +/* Mailbox RSU macros */ +#define RSU_VERSION_ACMF BIT(8) +#define RSU_VERSION_ACMF_MASK 0xff00 + +/* HPS stage notify command */ +#define MBOX_HPS_STAGE_NOTIFY 93 + +/* Execution states for HPS_STAGE_NOTIFY */ +#define HPS_EXECUTION_STATE_FSBL 0 +#define HPS_EXECUTION_STATE_SSBL 1 +#define HPS_EXECUTION_STATE_OS 2 + +/* Mailbox reconfiguration commands */ +#define MBOX_CONFIG_STATUS 4 +#define MBOX_RECONFIG 6 +#define MBOX_RECONFIG_DATA 8 +#define MBOX_RECONFIG_STATUS 9 + /* Generic error handling */ #define MBOX_TIMEOUT -2047 #define MBOX_NO_RESPONSE -2 @@ -98,13 +121,6 @@ #define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007 #define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008 -/* Mailbox reconfiguration commands */ -#define MBOX_CONFIG_STATUS 4 -#define MBOX_RECONFIG 6 -#define MBOX_RECONFIG_DATA 8 -#define MBOX_RECONFIG_STATUS 9 - - void mailbox_set_int(int interrupt_input); int mailbox_init(void); void mailbox_set_qspi_close(void); @@ -122,4 +138,9 @@ void mailbox_clear_response(void); uint32_t intel_mailbox_get_config_status(uint32_t cmd); int intel_mailbox_is_fpga_not_ready(void); +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_update(uint32_t *flash_offset); +int mailbox_hps_stage_notify(uint32_t execution_stage); + #endif /* SOCFPGA_MBOX_H */ diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 6bb41f31b6..2b1d9837ce 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -28,6 +28,7 @@ #define INTEL_SIP_LEGACY_SMC_ECC_DBE 0xC200000D #define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E #define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F +#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E /* FPGA config helpers */ #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000 diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 8d7c1d6638..673c2d56e1 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -267,6 +267,55 @@ void mailbox_reset_cold(void) mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0); } +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE, + NULL, 0, 0, (uint32_t *)resp_buf, + resp_buf_len); +} + +struct rsu_status_info { + uint64_t current_image; + uint64_t fail_image; + uint32_t state; + uint32_t version; + uint32_t error_location; + uint32_t error_details; + uint32_t retry_counter; +}; + +int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) +{ + int ret; + struct rsu_status_info *info = (struct rsu_status_info *)resp_buf; + + info->retry_counter = ~0; + + ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, 0, + (uint32_t *)resp_buf, resp_buf_len); + + if (ret < 0) + return ret; + + if (info->retry_counter != ~0) + if (!(info->version & RSU_VERSION_ACMF_MASK)) + info->version |= RSU_VERSION_ACMF; + + return ret; +} + +int mailbox_rsu_update(uint32_t *flash_offset) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE, + (uint32_t *)flash_offset, 2, 0, NULL, 0); +} + +int mailbox_hps_stage_notify(uint32_t execution_stage) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY, + &execution_stage, 1, 0, NULL, 0); +} + int mailbox_init(void) { int status = 0; diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c index d8a6c19804..d27ab9f966 100644 --- a/plat/intel/soc/common/socfpga_psci.c +++ b/plat/intel/soc/common/socfpga_psci.c @@ -130,9 +130,14 @@ static void __dead2 socfpga_system_off(void) panic(); } +extern uint64_t intel_rsu_update_address; + static void __dead2 socfpga_system_reset(void) { - mailbox_reset_cold(); + if (intel_rsu_update_address) + mailbox_rsu_update((uint32_t *)&intel_rsu_update_address); + else + mailbox_reset_cold(); while (1) wfi(); diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 41dae9e763..5b600e5ea8 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -252,12 +252,16 @@ static bool is_fpga_config_buffer_full(void) return true; } -static bool is_address_in_ddr_range(uint64_t addr) +static bool is_address_in_ddr_range(uint64_t addr, uint64_t size) { - if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE) - return true; + if (size > (UINT64_MAX - addr)) + return false; + if (addr < DRAM_BASE) + return false; + if (addr + size > DRAM_BASE + DRAM_SIZE) + return false; - return false; + return true; } static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) @@ -266,8 +270,7 @@ static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) intel_fpga_sdm_write_all(); - if (!is_address_in_ddr_range(mem) || - !is_address_in_ddr_range(mem + size) || + if (!is_address_in_ddr_range(mem, size) || is_fpga_config_buffer_full()) return INTEL_SIP_SMC_STATUS_REJECTED; @@ -365,6 +368,66 @@ uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask, return INTEL_SIP_SMC_STATUS_ERROR; } +/* Intel Remote System Update (RSU) services */ +uint64_t intel_rsu_update_address; + +static uint32_t intel_rsu_status(uint64_t *respbuf, uint32_t respbuf_sz) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_update(uint64_t update_address) +{ + intel_rsu_update_address = update_address; + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_notify(uint64_t execution_stage) +{ + if (mailbox_hps_stage_notify((uint32_t)execution_stage) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, + uint32_t *ret_stat) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + *ret_stat = respbuf[8]; + return INTEL_SIP_SMC_STATUS_OK; +} + +/* Mailbox services */ +static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, int len, + int urgent, uint32_t *response, + int resp_len, int *mbox_status, + int *len_in_resp) +{ + *len_in_resp = 0; + *mbox_status = 0; + + if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) + return INTEL_SIP_SMC_STATUS_REJECTED; + + int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent, + response, resp_len); + + if (status < 0) { + *mbox_status = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *mbox_status = 0; + *len_in_resp = status; + return INTEL_SIP_SMC_STATUS_OK; +} + /* * This function is responsible for handling all SiP calls from the NS world */ @@ -381,7 +444,10 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, uint32_t val = 0; uint32_t status = INTEL_SIP_SMC_STATUS_OK; uint32_t completed_addr[3]; + uint64_t rsu_respbuf[9]; uint32_t count = 0; + u_register_t x5, x6; + int mbox_status, len_in_resp; switch (smc_fid) { case SIP_SVC_UID: @@ -446,6 +512,41 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, (uint32_t)x3, &val); SMC_RET3(handle, status, val, x1); + case INTEL_SIP_SMC_RSU_STATUS: + status = intel_rsu_status(rsu_respbuf, + ARRAY_SIZE(rsu_respbuf)); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET4(handle, rsu_respbuf[0], rsu_respbuf[1], + rsu_respbuf[2], rsu_respbuf[3]); + } + + case INTEL_SIP_SMC_RSU_UPDATE: + status = intel_rsu_update(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_NOTIFY: + status = intel_rsu_notify(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_RETRY_COUNTER: + status = intel_rsu_retry_counter((uint32_t *)rsu_respbuf, + ARRAY_SIZE(rsu_respbuf), &val); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET2(handle, status, val); + } + + case INTEL_SIP_SMC_MBOX_SEND_CMD: + x5 = SMC_GET_GP(handle, CTX_GPREG_X5); + x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, + (uint32_t *)x5, x6, &mbox_status, + &len_in_resp); + SMC_RET4(handle, status, mbox_status, x5, len_in_resp); + default: return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c index 29f57c467b..4c3123815a 100644 --- a/plat/intel/soc/stratix10/bl31_plat_setup.c +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -16,6 +16,7 @@ #include <plat/common/platform.h> #include <platform_def.h> +#include "socfpga_mailbox.h" #include "socfpga_private.h" #include "socfpga_reset_manager.h" #include "socfpga_system_manager.h" @@ -115,6 +116,8 @@ void bl31_platform_setup(void) /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ mmio_write_64(PLAT_CPU_RELEASE_ADDR, (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_stratix10_mmap[] = { diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index b95bf5a519..bc10569ba7 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -15,6 +15,7 @@ ifeq (${ARM_ARCH_MAJOR},7) MARCH32_DIRECTIVE := -mcpu=cortex-a15 $(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)) $(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER)) +$(eval $(call add_define,ARMV7_SUPPORTS_VFP)) # Qemu expects a BL32 boot stage. NEED_BL32 := yes endif # ARMv7 diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h index 7158bfaf3d..b87ac3fd6b 100644 --- a/plat/socionext/synquacer/include/platform_def.h +++ b/plat/socionext/synquacer/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -80,7 +80,6 @@ #define DRAMINFO_BASE 0x2E00FFC0 #define PLAT_SQ_MHU_BASE 0x45000000 -#define PLAT_MHUV2_BASE 0xFFFFFFFF /* MHUV2 is not supported */ #define PLAT_SQ_SCP_COM_SHARED_MEM_BASE 0x45400000 #define SCPI_CMD_GET_DRAMINFO 0x1 diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index a3a9f43165..45b2803704 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -165,7 +165,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, { uint32_t result[4] = {0}; - pm_get_callbackdata(result, sizeof(result)); + pm_get_callbackdata(result, ARRAY_SIZE(result)); SMC_RET2(handle, (uint64_t)result[0] | ((uint64_t)result[1] << 32), (uint64_t)result[2] | ((uint64_t)result[3] << 32)); diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index 98dbe7d6e8..3f4f0691e5 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -423,7 +423,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, { uint32_t result[4] = {0}; - pm_get_callbackdata(result, (sizeof(result)/sizeof(uint32_t))); + pm_get_callbackdata(result, ARRAY_SIZE(result)); SMC_RET2(handle, (uint64_t)result[0] | ((uint64_t)result[1] << 32), (uint64_t)result[2] | ((uint64_t)result[3] << 32)); |