From ba6c31da59e86ba81fe0b846a9be1cb470c5e9f7 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Wed, 5 Jul 2017 15:07:05 +0100 Subject: [PATCH 1/4] Fix JUNO AArch32 build This patch fixes the inconsistency with regards as to how BL2_BASE/BL2U_BASE and BL2_LIMIT/BL2U_LIMIT macros are defined when building Juno to run in AArch32 mode at EL3. In this case, BL32 is compiled for AArch32 whereas BL1 and BL2 are compiled for AArch64. This resulted in BL32 conditionally compiling a different definition of the above mentioned macros from BL1/BL2. This is fixed by taking into consideration the JUNO_AARCH32_EL3_RUNTIME build flag as well in the conditional compilation check. Change-Id: I27ac68aa4df0502089c1739c05366a9c509eb5be Signed-off-by: Soby Mathew --- include/plat/arm/common/arm_def.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 2b0d894e1..efc276c6f 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -266,7 +266,7 @@ /******************************************************************************* * BL2 specific defines. ******************************************************************************/ -#if ARM_BL31_IN_DRAM || defined(AARCH32) +#if ARM_BL31_IN_DRAM || (defined(AARCH32) && !defined(JUNO_AARCH32_EL3_RUNTIME)) /* * For AArch32 BL31 is not applicable. * For AArch64 BL31 is loaded in the DRAM. @@ -353,7 +353,7 @@ * FWU Images: NS_BL1U, BL2U & NS_BL2U defines. ******************************************************************************/ #define BL2U_BASE BL2_BASE -#if ARM_BL31_IN_DRAM || defined(AARCH32) +#if ARM_BL31_IN_DRAM || (defined(AARCH32) && !defined(JUNO_AARCH32_EL3_RUNTIME)) /* * For AArch32 BL31 is not applicable. * For AArch64 BL31 is loaded in the DRAM. From 0a04c69a19c7b17222b84678a373e54fb3fefbe9 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Mon, 12 Jun 2017 12:15:01 +0100 Subject: [PATCH 2/4] Split CSS makefile for sp_min on Juno This patch factors out common files required for sp_min for all CSS platforms from the JUNO specific makefile to a the new `css_sp_min.mk` makefile. This also allows the common build options that affect CSS platforms to be configured in a central makefile for sp_min. Change-Id: Ida952d8833b1aa5eda77ae0a6664a4632aeab24c Signed-off-by: Soby Mathew --- plat/arm/board/juno/sp_min/sp_min-juno.mk | 6 +----- plat/arm/css/common/sp_min/css_sp_min.mk | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 plat/arm/css/common/sp_min/css_sp_min.mk diff --git a/plat/arm/board/juno/sp_min/sp_min-juno.mk b/plat/arm/board/juno/sp_min/sp_min-juno.mk index 9e2ab5f27..336c4e7ce 100644 --- a/plat/arm/board/juno/sp_min/sp_min-juno.mk +++ b/plat/arm/board/juno/sp_min/sp_min-juno.mk @@ -9,14 +9,10 @@ BL32_SOURCES += lib/cpus/aarch32/cortex_a53.S \ lib/cpus/aarch32/cortex_a57.S \ lib/cpus/aarch32/cortex_a72.S \ plat/arm/board/juno/juno_topology.c \ - plat/arm/css/common/css_pm.c \ - plat/arm/css/common/css_topology.c \ plat/arm/soc/common/soc_css_security.c \ - plat/arm/css/drivers/scp/css_pm_scpi.c \ - plat/arm/css/drivers/scpi/css_mhu.c \ - plat/arm/css/drivers/scpi/css_scpi.c \ ${JUNO_GIC_SOURCES} \ ${JUNO_INTERCONNECT_SOURCES} \ ${JUNO_SECURITY_SOURCES} include plat/arm/common/sp_min/arm_sp_min.mk +include plat/arm/css/common/sp_min/css_sp_min.mk diff --git a/plat/arm/css/common/sp_min/css_sp_min.mk b/plat/arm/css/common/sp_min/css_sp_min.mk new file mode 100644 index 000000000..7423d781b --- /dev/null +++ b/plat/arm/css/common/sp_min/css_sp_min.mk @@ -0,0 +1,20 @@ +# +# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# SP MIN source files common to CSS platforms +BL32_SOURCES += plat/arm/css/common/css_pm.c \ + plat/arm/css/common/css_topology.c + +ifeq (${CSS_USE_SCMI_DRIVER},0) +BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \ + plat/arm/css/drivers/scpi/css_mhu.c \ + plat/arm/css/drivers/scpi/css_scpi.c +else +BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scmi.c \ + plat/arm/css/drivers/scmi/scmi_common.c \ + plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c \ + plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c +endif From 9bedda4ab8fc9a67d43d35921d1dcf1280c85ba4 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Mon, 12 Jun 2017 12:13:04 +0100 Subject: [PATCH 3/4] SDS: Introduce the sds drivers This patch introduces the driver for Shared-Data-Structure (SDS) framework which will be used for communication between SCP and AP CPU. The SDS framework is intended to replace the Boot-Over-MHU (BOM) protocol used currently for the communication Change-Id: Ic174291121f4e581b174cce3389d22d6435f7269 Signed-off-by: Soby Mathew --- .../arm/css/drivers/sds/aarch32/sds_helpers.S | 63 +++++ .../arm/css/drivers/sds/aarch64/sds_helpers.S | 61 +++++ plat/arm/css/drivers/sds/sds.c | 258 ++++++++++++++++++ plat/arm/css/drivers/sds/sds.h | 89 ++++++ plat/arm/css/drivers/sds/sds_private.h | 99 +++++++ 5 files changed, 570 insertions(+) create mode 100644 plat/arm/css/drivers/sds/aarch32/sds_helpers.S create mode 100644 plat/arm/css/drivers/sds/aarch64/sds_helpers.S create mode 100644 plat/arm/css/drivers/sds/sds.c create mode 100644 plat/arm/css/drivers/sds/sds.h create mode 100644 plat/arm/css/drivers/sds/sds_private.h diff --git a/plat/arm/css/drivers/sds/aarch32/sds_helpers.S b/plat/arm/css/drivers/sds/aarch32/sds_helpers.S new file mode 100644 index 000000000..f68cb35f1 --- /dev/null +++ b/plat/arm/css/drivers/sds/aarch32/sds_helpers.S @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include "../sds.h" +#include "../sds_private.h" + + .globl sds_get_primary_cpu_id + + /* + * int sds_get_primary_cpu_id(void); + * Return the primary CPU ID from SDS Structure + * Returns CPUID on success or -1 on failure + */ +func sds_get_primary_cpu_id + ldr r0, =PLAT_ARM_SDS_MEM_BASE + ldr r2, =SDS_REGION_SIGNATURE + ldr r1, [r0] + ubfx r3, r1, #0, #16 + + /* Check if the SDS region signature found */ + cmp r2, r3 + bne 2f + + /* Get the structure count from region descriptor in r1 */ + ubfx r1, r1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH + cmp r1, #0 + beq 2f + add r0, r0, #SDS_REGION_DESC_SIZE + + /* Initialize the loop iterator count in r3 */ + mov r3, #0 +loop_begin: + ldrh r2, [r0] + cmp r2, #SDS_AP_CPU_INFO_STRUCT_ID + bne continue_loop + + /* We have found the required structure */ + ldr r0, [r0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)] + bx lr +continue_loop: + /* Increment the loop counter and exit loop if counter == structure count */ + add r3, r3, #0x1 + cmp r1, r3 + beq 2f + + /* Read the 2nd word in header */ + ldr r2, [r0,#4] + /* Get the structure size from header */ + ubfx r2, r2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH + /* Add the structure size and SDS HEADER SIZE to point to next header */ + add r2, r2, #SDS_HEADER_SIZE + add r0, r0, r2 + b loop_begin +2: + mov r0, #0xffffffff + bx lr +endfunc sds_get_primary_cpu_id diff --git a/plat/arm/css/drivers/sds/aarch64/sds_helpers.S b/plat/arm/css/drivers/sds/aarch64/sds_helpers.S new file mode 100644 index 000000000..3b9c562d0 --- /dev/null +++ b/plat/arm/css/drivers/sds/aarch64/sds_helpers.S @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include "../sds.h" +#include "../sds_private.h" + + .globl sds_get_primary_cpu_id + + /* + * int sds_get_primary_cpu_id(void); + * Return the primary CPI ID from SDS Structure + * Returns CPUID on success or -1 on failure + */ +func sds_get_primary_cpu_id + mov_imm x0, PLAT_ARM_SDS_MEM_BASE + mov w2, #SDS_REGION_SIGNATURE + ldr w1, [x0] + + /* Check if the SDS region signature found */ + cmp w2, w1, uxth + b.ne 2f + + /* Get the structure count from region descriptor in `w1 */ + ubfx w1, w1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH + cbz w1, 2f + add x0, x0, #SDS_REGION_DESC_SIZE + + /* Initialize the loop iterator count in w3 */ + mov w3, #0 +loop_begin: + ldrh w2, [x0] + cmp w2, #SDS_AP_CPU_INFO_STRUCT_ID + b.ne continue_loop + + /* We have found the required structure */ + ldr w0, [x0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)] + ret +continue_loop: + /* Increment the loop counter and exit loop if counter == structure count */ + add w3, w3, #0x1 + cmp w1, w3 + b.eq 2f + + /* Read the 2nd word in header */ + ldr w2, [x0,#4] + /* Get the structure size from header */ + ubfx x2, x2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH + /* Add the structure size and SDS HEADER SIZE to point to next header */ + add x2, x2, #SDS_HEADER_SIZE + add x0, x0, x2 + b loop_begin +2: + mov w0, #0xffffffff + ret +endfunc sds_get_primary_cpu_id diff --git a/plat/arm/css/drivers/sds/sds.c b/plat/arm/css/drivers/sds/sds.c new file mode 100644 index 000000000..e2fac54f3 --- /dev/null +++ b/plat/arm/css/drivers/sds/sds.c @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#include "sds.h" +#include "sds_private.h" + +/* + * Variables used to track and maintain the state of the memory region reserved + * for usage by the SDS framework. + */ + +/* Pointer to the base of the SDS memory region */ +static uintptr_t sds_mem_base; + +/* Size of the SDS memory region in bytes */ +static size_t sds_mem_size; + +/* + * Perform some non-exhaustive tests to determine whether any of the fields + * within a Structure Header contain obviously invalid data. + * Returns SDS_OK on success, SDS_ERR_FAIL on error. + */ +static int sds_struct_is_valid(uintptr_t header) +{ + size_t struct_size = GET_SDS_HEADER_STRUCT_SIZE(header); + + /* Zero is not a valid identifier */ + if (GET_SDS_HEADER_ID(header) == 0) + return SDS_ERR_FAIL; + + /* Check SDS Schema version */ + if (GET_SDS_HEADER_VERSION(header) == SDS_REGION_SCH_VERSION) + return SDS_ERR_FAIL; + + /* The SDS Structure sizes have to be multiple of 8 */ + if ((struct_size == 0) || ((struct_size % 8) != 0)) + return SDS_ERR_FAIL; + + if (struct_size > sds_mem_size) + return SDS_ERR_FAIL; + + return SDS_OK; +} + +/* + * Validate the SDS structure headers. + * Returns SDS_OK on success, SDS_ERR_FAIL on error. + */ +static int validate_sds_struct_headers(void) +{ + unsigned int i, structure_count; + uintptr_t header; + + structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base); + + if (structure_count == 0) + return SDS_ERR_FAIL; + + header = sds_mem_base + SDS_REGION_DESC_SIZE; + + /* Iterate over structure headers and validate each one */ + for (i = 0; i < structure_count; i++) { + if (sds_struct_is_valid(header) != SDS_OK) { + WARN("SDS: Invalid structure header detected\n"); + return SDS_ERR_FAIL; + } + header += GET_SDS_HEADER_STRUCT_SIZE(header) + SDS_HEADER_SIZE; + } + return SDS_OK; +} + +/* + * Get the structure header pointer corresponding to the structure ID. + * Returns SDS_OK on success, SDS_ERR_STRUCT_NOT_FOUND on error. + */ +static int get_struct_header(uint32_t structure_id, struct_header_t **header) +{ + unsigned int i, structure_count; + uintptr_t current_header; + + assert(header); + + structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base); + if (structure_count == 0) + return SDS_ERR_STRUCT_NOT_FOUND; + + current_header = ((uintptr_t)sds_mem_base) + SDS_REGION_DESC_SIZE; + + /* Iterate over structure headers to find one with a matching ID */ + for (i = 0; i < structure_count; i++) { + if (GET_SDS_HEADER_ID(current_header) == structure_id) { + *header = (struct_header_t *)current_header; + return SDS_OK; + } + current_header += GET_SDS_HEADER_STRUCT_SIZE(current_header) + + SDS_HEADER_SIZE; + } + + *header = NULL; + return SDS_ERR_STRUCT_NOT_FOUND; +} + +/* + * Check if a structure header corresponding to the structure ID exists. + * Returns SDS_OK if structure header exists else SDS_ERR_STRUCT_NOT_FOUND + * if not found. + */ +int sds_struct_exists(unsigned int structure_id) +{ + struct_header_t *header = NULL; + int ret; + + ret = get_struct_header(structure_id, &header); + if (ret == SDS_OK) { + assert(header); + } + + return ret; +} + +/* + * Read from field in the structure corresponding to `structure_id`. + * `fld_off` is the offset to the field in the structure and `mode` + * indicates whether cache maintenance need to performed prior to the read. + * The `data` is the pointer to store the read data of size specified by `size`. + * Returns SDS_OK on success or corresponding error codes on failure. + */ +int sds_struct_read(uint32_t structure_id, unsigned int fld_off, + void *data, size_t size, sds_access_mode_t mode) +{ + int status; + uintptr_t field_base; + struct_header_t *header = NULL; + + if (!data) + return SDS_ERR_INVALID_PARAMS; + + /* Check if a structure with this ID exists */ + status = get_struct_header(structure_id, &header); + if (status != SDS_OK) + return status; + + assert(header); + + if (mode == SDS_ACCESS_MODE_CACHED) + inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size); + + if (!IS_SDS_HEADER_VALID(header)) { + WARN("SDS: Reading from un-finalized structure 0x%x\n", + structure_id); + return SDS_ERR_STRUCT_NOT_FINALIZED; + } + + if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header)) + return SDS_ERR_FAIL; + + field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off; + if (check_uptr_overflow(field_base, size - 1)) + return SDS_ERR_FAIL; + + /* Copy the required field in the struct */ + memcpy(data, (void *)field_base, size); + + return SDS_OK; +} + +/* + * Write to the field in the structure corresponding to `structure_id`. + * `fld_off` is the offset to the field in the structure and `mode` + * indicates whether cache maintenance need to performed for the write. + * The `data` is the pointer to data of size specified by `size`. + * Returns SDS_OK on success or corresponding error codes on failure. + */ +int sds_struct_write(uint32_t structure_id, unsigned int fld_off, + void *data, size_t size, sds_access_mode_t mode) +{ + int status; + uintptr_t field_base; + struct_header_t *header = NULL; + + if (!data) + return SDS_ERR_INVALID_PARAMS; + + /* Check if a structure with this ID exists */ + status = get_struct_header(structure_id, &header); + if (status != SDS_OK) + return status; + + assert(header); + + if (mode == SDS_ACCESS_MODE_CACHED) + inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size); + + if (!IS_SDS_HEADER_VALID(header)) { + WARN("SDS: Writing to un-finalized structure 0x%x\n", + structure_id); + return SDS_ERR_STRUCT_NOT_FINALIZED; + } + + if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header)) + return SDS_ERR_FAIL; + + field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off; + if (check_uptr_overflow(field_base, size - 1)) + return SDS_ERR_FAIL; + + /* Copy the required field in the struct */ + memcpy((void *)field_base, data, size); + + if (mode == SDS_ACCESS_MODE_CACHED) + flush_dcache_range((uintptr_t)field_base, size); + + return SDS_OK; +} + +/* + * Initialize the SDS driver. Also verifies the SDS version and sanity of + * the SDS structure headers. + * Returns SDS_OK on success, SDS_ERR_FAIL on error. + */ +int sds_init(void) +{ + sds_mem_base = (uintptr_t)PLAT_ARM_SDS_MEM_BASE; + + if (!IS_SDS_REGION_VALID(sds_mem_base)) { + WARN("SDS: No valid SDS Memory Region found\n"); + return SDS_ERR_FAIL; + } + + if (GET_SDS_REGION_SCHEMA_VERSION(sds_mem_base) + != SDS_REGION_SCH_VERSION) { + WARN("SDS: Unsupported SDS schema version\n"); + return SDS_ERR_FAIL; + } + + sds_mem_size = GET_SDS_REGION_SIZE(sds_mem_base); + if (sds_mem_size > PLAT_ARM_SDS_MEM_SIZE_MAX) { + WARN("SDS: SDS Memory Region exceeds size limit\n"); + return SDS_ERR_FAIL; + } + + INFO("SDS: Detected SDS Memory Region (%zu bytes)\n", sds_mem_size); + + if (validate_sds_struct_headers() != SDS_OK) + return SDS_ERR_FAIL; + + return SDS_OK; +} diff --git a/plat/arm/css/drivers/sds/sds.h b/plat/arm/css/drivers/sds/sds.h new file mode 100644 index 000000000..ff3787da0 --- /dev/null +++ b/plat/arm/css/drivers/sds/sds.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __SDS_H__ +#define __SDS_H__ + +/* SDS Structure Identifier defines */ +/* AP CPU INFO defines */ +#define SDS_AP_CPU_INFO_STRUCT_ID 1 +#define SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET 0x0 +#define SDS_AP_CPU_INFO_PRIMARY_CPUID_SIZE 0x4 + +/* ROM Firmware Version defines */ +#define SDS_ROM_VERSION_STRUCT_ID 2 +#define SDS_ROM_VERSION_OFFSET 0x0 +#define SDS_ROM_VERSION_SIZE 0x4 + +/* RAM Firmware version defines */ +#define SDS_RAM_VERSION_STRUCT_ID 3 +#define SDS_RAM_VERSION_OFFSET 0x0 +#define SDS_RAM_VERSION_SIZE 0x4 + +/* Platform Identity defines */ +#define SDS_PLATFORM_IDENTITY_STRUCT_ID 4 +#define SDS_PLATFORM_IDENTITY_ID_OFFSET 0x0 +#define SDS_PLATFORM_IDENTITY_ID_SIZE 0x4 +#define SDS_PLATFORM_IDENTITY_ID_CONFIG_SHIFT 28 +#define SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH 4 +#define SDS_PLATFORM_IDENTITY_ID_CONFIG_MASK \ + ((1 << SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH) - 1) + +#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_OFFSET 0x4 +#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_SIZE 0x4 + +/* Reset Syndrome defines */ +#define SDS_RESET_SYNDROME_STRUCT_ID 5 +#define SDS_RESET_SYNDROME_OFFSET 0 +#define SDS_RESET_SYNDROME_SIZE 4 +#define SDS_RESET_SYNDROME_POW_ON_RESET_BIT (1 << 0) +#define SDS_RESET_SYNDROME_SCP_WD_RESET_BIT (1 << 1) +#define SDS_RESET_SYNDROME_AP_WD_RESET_BIT (1 << 2) +#define SDS_RESET_SYNDROME_SYS_RESET_REQ_BIT (1 << 3) +#define SDS_RESET_SYNDROME_M3_LOCKUP_BIT (1 << 4) + +/* SCP Firmware Feature Availability defines */ +#define SDS_FEATURE_AVAIL_STRUCT_ID 6 +#define SDS_FEATURE_AVAIL_OFFSET 0 +#define SDS_FEATURE_AVAIL_SIZE 4 +#define SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT (1 << 0) +#define SDS_FEATURE_AVAIL_DMC_READY_BIT (1 << 1) +#define SDS_FEATURE_AVAIL_MSG_IF_READY_BIT (1 << 2) + +/* SCP BL2 Image Metadata defines */ +#define SDS_SCP_IMG_STRUCT_ID 9 +#define SDS_SCP_IMG_FLAG_OFFSET 0 +#define SDS_SCP_IMG_FLAG_SIZE 4 +#define SDS_SCP_IMG_VALID_FLAG_BIT (1 << 0) +#define SDS_SCP_IMG_ADDR_OFFSET 4 +#define SDS_SCP_IMG_ADDR_SIZE 4 +#define SDS_SCP_IMG_SIZE_OFFSET 8 +#define SDS_SCP_IMG_SIZE_SIZE 4 + +/* SDS Driver Error Codes */ +#define SDS_OK 0 +#define SDS_ERR_FAIL -1 +#define SDS_ERR_INVALID_PARAMS -2 +#define SDS_ERR_STRUCT_NOT_FOUND -3 +#define SDS_ERR_STRUCT_NOT_FINALIZED -4 + +#ifndef __ASSEMBLY__ +#include +#include + +typedef enum { + SDS_ACCESS_MODE_NON_CACHED, + SDS_ACCESS_MODE_CACHED, +} sds_access_mode_t; + +int sds_init(void); +int sds_struct_exists(uint32_t structure_id); +int sds_struct_read(uint32_t structure_id, unsigned int fld_off, void *data, + size_t size, sds_access_mode_t mode); +int sds_struct_write(uint32_t structure_id, unsigned int fld_off, void *data, + size_t size, sds_access_mode_t mode); +#endif /*__ASSEMBLY__ */ +#endif /* __SDS_H__ */ diff --git a/plat/arm/css/drivers/sds/sds_private.h b/plat/arm/css/drivers/sds/sds_private.h new file mode 100644 index 000000000..649576b6d --- /dev/null +++ b/plat/arm/css/drivers/sds/sds_private.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __SDS_PRIVATE_H__ +#define __SDS_PRIVATE_H__ + +/* SDS Header defines */ +#define SDS_HEADER_ID_SHIFT 0 +#define SDS_HEADER_ID_WIDTH 16 +#define SDS_HEADER_ID_MASK ((1 << SDS_HEADER_ID_WIDTH) - 1) + +#define SDS_HEADER_MINOR_VERSION_WIDTH 8 +#define SDS_HEADER_MINOR_VERSION_SHIFT 16 +#define SDS_HEADER_MAJOR_VERSION_WIDTH 8 + +#define MAKE_SDS_HEADER_VERSION(major, minor) \ + (((((major) & 0xff) << SDS_HEADER_MINOR_VERSION_WIDTH) | ((minor) & 0xff))) +#define SDS_HEADER_VERSION_MASK \ + ((1 << (SDS_HEADER_MINOR_VERSION_WIDTH + SDS_HEADER_MAJOR_VERSION_WIDTH)) - 1) + +#define SDS_HEADER_VERSION MAKE_SDS_HEADER_VERSION(1, 0) +#define SDS_HEADER_STRUCT_SIZE_WIDTH 23 +#define SDS_HEADER_STRUCT_SIZE_SHIFT 1 +#define SDS_HEADER_STRUCT_SIZE_MASK ((1 << SDS_HEADER_STRUCT_SIZE_WIDTH) - 1) +#define SDS_HEADER_VALID_MASK 0x1 +#define SDS_HEADER_VALID_SHIFT 0 +#define SDS_HEADER_SIZE 0x8 + +/* Arbitrary, 16 bit value that indicates a valid SDS Memory Region */ +#define SDS_REGION_SIGNATURE 0xAA7A +#define SDS_REGION_SIGNATURE_WIDTH 16 +#define SDS_REGION_SIGNATURE_SHIFT 0 +#define SDS_REGION_SIGNATURE_MASK ((1 << SDS_REGION_SIGNATURE_WIDTH) - 1) + +#define SDS_REGION_STRUCT_COUNT_SHIFT 16 +#define SDS_REGION_STRUCT_COUNT_WIDTH 8 +#define SDS_REGION_STRUCT_COUNT_MASK ((1 << SDS_REGION_STRUCT_COUNT_WIDTH) - 1) + +#define SDS_REGION_SCH_MINOR_SHIFT 24 +#define SDS_REGION_SCH_MINOR_WIDTH 4 +#define SDS_REGION_SCH_MINOR_MASK ((1 << SDS_REGION_SCH_MINOR_WIDTH) - 1) + +#define SDS_REGION_SCH_MAJOR_SHIFT 28 +#define SDS_REGION_SCH_MAJOR_WIDTH 4 +#define SDS_REGION_SCH_MAJOR_MASK ((1 << SDS_REGION_SCH_MAJOR_WIDTH) - 1) + +#define SDS_REGION_SCH_VERSION_MASK \ + ((1 << (SDS_REGION_SCH_MINOR_WIDTH + SDS_REGION_SCH_MAJOR_WIDTH)) - 1) + +#define MAKE_SDS_REGION_SCH_VERSION(maj, min) \ + ((((maj) & SDS_REGION_SCH_MAJOR_MASK) << SDS_REGION_SCH_MINOR_WIDTH) | \ + ((min) & SDS_REGION_SCH_MINOR_MASK)) + +#define SDS_REGION_SCH_VERSION MAKE_SDS_REGION_SCH_VERSION(1, 0) +#define SDS_REGION_REGIONSIZE_OFFSET 0x4 +#define SDS_REGION_DESC_SIZE 0x8 + +#ifndef __ASSEMBLY__ +#include +#include + +/* Header containing Shared Data Structure metadata */ +typedef struct structure_header { + uint32_t reg[2]; +} struct_header_t; + +#define GET_SDS_HEADER_ID(header) \ + ((((struct_header_t *)(header))->reg[0]) & SDS_HEADER_ID_MASK) +#define GET_SDS_HEADER_VERSION(header) \ + (((((struct_header_t *)(header))->reg[0]) >> SDS_HEADER_MINOR_VERSION_SHIFT)\ + & SDS_HEADER_VERSION_MASK) +#define GET_SDS_HEADER_STRUCT_SIZE(header) \ + (((((struct_header_t *)(header))->reg[1]) >> SDS_HEADER_STRUCT_SIZE_SHIFT)\ + & SDS_HEADER_STRUCT_SIZE_MASK) +#define IS_SDS_HEADER_VALID(header) \ + ((((struct_header_t *)(header))->reg[1]) & SDS_HEADER_VALID_MASK) +#define GET_SDS_STRUCT_FIELD(header, field_offset) \ + ((((uint8_t *)(header)) + sizeof(struct_header_t)) + (field_offset)) + +/* Region Descriptor describing the SDS Memory Region */ +typedef struct region_descriptor { + uint32_t reg[2]; +} region_desc_t; + +#define IS_SDS_REGION_VALID(region) \ + (((((region_desc_t *)(region))->reg[0]) & SDS_REGION_SIGNATURE_MASK) == SDS_REGION_SIGNATURE) +#define GET_SDS_REGION_STRUCTURE_COUNT(region) \ + (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_STRUCT_COUNT_SHIFT)\ + & SDS_REGION_STRUCT_COUNT_MASK) +#define GET_SDS_REGION_SCHEMA_VERSION(region) \ + (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_SCH_MINOR_SHIFT)\ + & SDS_REGION_SCH_VERSION_MASK) +#define GET_SDS_REGION_SIZE(region) ((((region_desc_t *)(region))->reg[1])) + +#endif /* __ASSEMBLY__ */ +#endif /* __SDS_PRIVATE_H__ */ From 18e279ebe616dc4f2691f50c5cd37b6196c224f7 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Mon, 12 Jun 2017 12:37:10 +0100 Subject: [PATCH 4/4] CSS: Changes for SDS framework This patch does the required changes to enable CSS platforms to build and use the SDS framework. Since SDS is always coupled with SCMI protocol, the preexisting SCMI build flag is now renamed to `CSS_USE_SCMI_SDS_DRIVER` which will enable both SCMI and SDS on CSS platforms. Also some of the workarounds applied for SCMI are now removed with SDS in place. Change-Id: I94e8b93f05e3fe95e475c5501c25bec052588a9c Signed-off-by: Soby Mathew --- docs/user-guide.rst | 7 +- include/plat/arm/css/common/css_def.h | 35 ++++--- plat/arm/board/common/board_css_common.c | 9 -- plat/arm/board/fvp/platform.mk | 3 - plat/arm/board/juno/include/platform_def.h | 10 +- plat/arm/board/juno/juno_bl2_setup.c | 7 +- plat/arm/common/arm_bl2_setup.c | 2 + plat/arm/common/arm_common.mk | 8 +- plat/arm/css/common/aarch32/css_helpers.S | 21 ++++- plat/arm/css/common/aarch64/css_helpers.S | 20 +++- plat/arm/css/common/css_bl2_setup.c | 13 ++- plat/arm/css/common/css_common.mk | 53 ++++++----- plat/arm/css/common/sp_min/css_sp_min.mk | 2 +- plat/arm/css/drivers/scp/css_bom_bootloader.c | 10 +- plat/arm/css/drivers/scp/css_pm_scmi.c | 4 +- plat/arm/css/drivers/scp/css_scp.h | 23 +++-- plat/arm/css/drivers/scp/css_sds.c | 93 +++++++++++++++++++ 17 files changed, 249 insertions(+), 71 deletions(-) create mode 100644 plat/arm/css/drivers/scp/css_sds.c diff --git a/docs/user-guide.rst b/docs/user-guide.rst index 043af63ed..6031dd98d 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -669,9 +669,10 @@ ARM CSS platform specific build options SCP\_BL2U to the FIP and FWU\_FIP respectively, and enables them to be loaded during boot. Default is 1. -- ``CSS_USE_SCMI_DRIVER``: Boolean flag which selects SCMI driver instead of - SCPI driver for communicating with the SCP during power management operations. - If this option is set to 1, then SCMI driver will be used. Default is 0. +- ``CSS_USE_SCMI_SDS_DRIVER``: Boolean flag which selects SCMI/SDS drivers + instead of SCPI/BOM driver for communicating with the SCP during power + 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. ARM FVP platform specific build options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index 9d025f66b..ac0769c37 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -37,6 +37,9 @@ #define CSS_IRQ_TZ_WDOG 86 #define CSS_IRQ_SEC_SYS_TIMER 91 +/* MHU register offsets */ +#define MHU_CPU_INTR_S_SET_OFFSET 0x308 + /* * Define a list of Group 1 Secure interrupts as per GICv3 terminology. On a * GICv2 system or mode, the interrupts will be treated as Group 0 interrupts. @@ -47,17 +50,24 @@ CSS_IRQ_TZ_WDOG, \ CSS_IRQ_SEC_SYS_TIMER +#if CSS_USE_SCMI_SDS_DRIVER +/* Memory region for shared data storage */ +#define PLAT_ARM_SDS_MEM_BASE ARM_SHARED_RAM_BASE +#define PLAT_ARM_SDS_MEM_SIZE_MAX 0xDC0 /* 3520 bytes */ /* - * The lower Non-secure MHU channel is being used for SCMI for ARM Trusted - * Firmware. - * TODO: Move SCMI to Secure channel once the migration to SCMI in SCP is - * complete. + * The SCMI Channel is placed right after the SDS region */ -#define MHU_CPU_INTR_L_SET_OFFSET 0x108 -#define MHU_CPU_INTR_H_SET_OFFSET 0x128 -#define CSS_SCMI_PAYLOAD_BASE (NSRAM_BASE + 0x500) -#define CSS_SCMI_MHU_DB_REG_OFF MHU_CPU_INTR_L_SET_OFFSET +#define CSS_SCMI_PAYLOAD_BASE (PLAT_ARM_SDS_MEM_BASE + PLAT_ARM_SDS_MEM_SIZE_MAX) +#define CSS_SCMI_MHU_DB_REG_OFF MHU_CPU_INTR_S_SET_OFFSET +/* Trusted mailbox base address common to all CSS */ +/* If SDS is present, then mailbox is at top of SRAM */ +#define PLAT_ARM_TRUSTED_MAILBOX_BASE (ARM_SHARED_RAM_BASE + ARM_SHARED_RAM_SIZE - 0x8) + +/* Number of retries for SCP_RAM_READY flag */ +#define CSS_SCP_READY_10US_RETRIES 1000000 /* Effective timeout of 10000 ms */ + +#else /* * SCP <=> AP boot configuration * @@ -69,6 +79,12 @@ */ #define SCP_BOOT_CFG_ADDR PLAT_CSS_SCP_COM_SHARED_MEM_BASE +/* Trusted mailbox base address common to all CSS */ +/* If SDS is not present, then the mailbox is at the bottom of SRAM */ +#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE + +#endif /* CSS_USE_SCMI_SDS_DRIVER */ + #define CSS_MAP_DEVICE MAP_REGION_FLAT( \ CSS_DEVICE_BASE, \ CSS_DEVICE_SIZE, \ @@ -152,9 +168,6 @@ /* TZC related constants */ #define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL -/* Trusted mailbox base address common to all CSS */ -#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE - /* * Parsing of CPU and Cluster states, as returned by 'Get CSS Power State' SCP * command diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c index 68f70a781..159bf86f4 100644 --- a/plat/arm/board/common/board_css_common.c +++ b/plat/arm/board/common/board_css_common.c @@ -56,15 +56,6 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, V2M_MAP_IOFPGA, CSS_MAP_DEVICE, -#if CSS_USE_SCMI_DRIVER - /* - * The SCMI payload area is currently in the Non Secure SRAM. This is - * a potential security risk but this will be resolved once SCP - * completely replaces SCPI with SCMI as the only communication - * protocol. - */ - CSS_MAP_NSRAM, -#endif SOC_CSS_MAP_DEVICE, {0} }; diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 0b6e1da54..6d8aa5fb7 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -117,7 +117,6 @@ BL1_SOURCES += drivers/io/io_semihosting.c \ BL2_SOURCES += drivers/io/io_semihosting.c \ - drivers/delay_timer/delay_timer.c \ lib/semihosting/semihosting.c \ lib/semihosting/${ARCH}/semihosting_call.S \ plat/arm/board/fvp/fvp_bl2_setup.c \ @@ -128,8 +127,6 @@ BL2_SOURCES += drivers/io/io_semihosting.c \ ifeq (${FVP_USE_SP804_TIMER},1) BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c -else -BL2_SOURCES += drivers/delay_timer/generic_delay_timer.c endif BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \ diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 873c56987..f1714e137 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -82,13 +82,8 @@ #endif #ifdef IMAGE_BL31 -# if CSS_USE_SCMI_DRIVER -# define PLAT_ARM_MMAP_ENTRIES 6 -# define MAX_XLAT_TABLES 3 -# else # define PLAT_ARM_MMAP_ENTRIES 5 # define MAX_XLAT_TABLES 2 -# endif #endif #ifdef IMAGE_BL32 @@ -168,7 +163,9 @@ /* * Base address of the first memory region used for communication between AP * and SCP. Used by the BOM and SCPI protocols. - * + */ +#if !CSS_USE_SCMI_SDS_DRIVER +/* * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which * means the SCP/AP configuration data gets overwritten when the AP initiates * communication with the SCP. The configuration data is expected to be a @@ -178,6 +175,7 @@ #define PLAT_CSS_SCP_COM_SHARED_MEM_BASE (ARM_TRUSTED_SRAM_BASE + 0x80) #define PLAT_CSS_PRIMARY_CPU_SHIFT 8 #define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 4 +#endif /* * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c index abceb0f5e..2771e0f37 100644 --- a/plat/arm/board/juno/juno_bl2_setup.c +++ b/plat/arm/board/juno/juno_bl2_setup.c @@ -30,9 +30,12 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) return err; } +#if !CSS_USE_SCMI_SDS_DRIVER /* * We need to override some of the platform functions when booting SP_MIN - * on Juno AArch32. + * on Juno AArch32. These needs to be done only for SCPI/BOM SCP systems as + * in case of SDS, the structures remain in memory and doesn't need to be + * overwritten. */ static unsigned int scp_boot_config; @@ -53,4 +56,6 @@ void bl2_platform_setup(void) mmio_write_32(SCP_BOOT_CFG_ADDR, scp_boot_config); VERBOSE("BL2: Restored SCP Boot config = 0x%x\n", scp_boot_config); } +#endif + #endif /* JUNO_AARCH32_EL3_RUNTIME */ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 9182bd128..cab6113e9 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef SPD_opteed #include #endif @@ -182,6 +183,7 @@ void arm_bl2_early_platform_setup(meminfo_t *mem_layout) void bl2_early_platform_setup(meminfo_t *mem_layout) { arm_bl2_early_platform_setup(mem_layout); + generic_delay_timer_init(); } /* diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 20372c203..0e14806ab 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -139,7 +139,9 @@ ifdef EL3_PAYLOAD_BASE BL1_SOURCES += plat/arm/common/arm_pm.c endif -BL2_SOURCES += drivers/io/io_fip.c \ +BL2_SOURCES += drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl2_setup.c \ @@ -159,7 +161,9 @@ BL2_SOURCES += lib/optee/optee_utils.c endif endif -BL2U_SOURCES += plat/arm/common/arm_bl2u_setup.c +BL2U_SOURCES += drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + plat/arm/common/arm_bl2u_setup.c BL31_SOURCES += plat/arm/common/arm_bl31_setup.c \ plat/arm/common/arm_pm.c \ diff --git a/plat/arm/css/common/aarch32/css_helpers.S b/plat/arm/css/common/aarch32/css_helpers.S index f131e67a3..80aa24c62 100644 --- a/plat/arm/css/common/aarch32/css_helpers.S +++ b/plat/arm/css/common/aarch32/css_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -68,6 +68,24 @@ endfunc css_calc_core_pos_swap_cluster * cpu (applicable ony after a cold boot) * ----------------------------------------------------- */ +#if CSS_USE_SCMI_SDS_DRIVER +func plat_is_my_cpu_primary + mov r10, lr + bl plat_my_core_pos + mov r4, r0 + bl sds_get_primary_cpu_id + /* Check for error */ + mov r1, #0xffffffff + cmp r0, r1 + beq 1f + cmp r0, r4 + moveq r0, #1 + movne r0, #0 + bx r10 +1: + no_ret plat_panic_handler +endfunc plat_is_my_cpu_primary +#else func plat_is_my_cpu_primary mov r10, lr bl plat_my_core_pos @@ -80,3 +98,4 @@ func plat_is_my_cpu_primary movne r0, #0 bx r10 endfunc plat_is_my_cpu_primary +#endif diff --git a/plat/arm/css/common/aarch64/css_helpers.S b/plat/arm/css/common/aarch64/css_helpers.S index 0cf8f86bb..59d920650 100644 --- a/plat/arm/css/common/aarch64/css_helpers.S +++ b/plat/arm/css/common/aarch64/css_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -88,6 +88,23 @@ endfunc css_calc_core_pos_swap_cluster * cpu (applicable ony after a cold boot) * ----------------------------------------------------- */ +#if CSS_USE_SCMI_SDS_DRIVER +func plat_is_my_cpu_primary + mov x9, x30 + bl plat_my_core_pos + mov x4, x0 + bl sds_get_primary_cpu_id + /* Check for error */ + mov x1, #0xffffffff + cmp x0, x1 + b.eq 1f + cmp x0, x4 + cset w0, eq + ret x9 +1: + no_ret plat_panic_handler +endfunc plat_is_my_cpu_primary +#else func plat_is_my_cpu_primary mov x9, x30 bl plat_my_core_pos @@ -99,3 +116,4 @@ func plat_is_my_cpu_primary cset w0, eq ret x9 endfunc plat_is_my_cpu_primary +#endif diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c index c98b2fff3..9b4800e34 100644 --- a/plat/arm/css/common/css_bl2_setup.c +++ b/plat/arm/css/common/css_bl2_setup.c @@ -48,10 +48,14 @@ int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) return ret; } -#ifdef EL3_PAYLOAD_BASE +#if !CSS_USE_SCMI_SDS_DRIVER +# ifdef EL3_PAYLOAD_BASE + /* * We need to override some of the platform functions when booting an EL3 - * payload. + * payload. These needs to be done only for SCPI/BOM SCP systems as + * in case of SDS, the structures remain in memory and doesn't need to be + * overwritten. */ static unsigned int scp_boot_config; @@ -82,4 +86,7 @@ void bl2_platform_setup(void) zeromem((void *) ARM_SHARED_RAM_BASE, 128); mmio_write_32(SCP_BOOT_CFG_ADDR, scp_boot_config); } -#endif /* EL3_PAYLOAD_BASE */ + +# endif /* EL3_PAYLOAD_BASE */ + +#endif /* CSS_USE_SCMI_SDS_DRIVER */ diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk index 9381e4cd2..63e305916 100644 --- a/plat/arm/css/common/css_common.mk +++ b/plat/arm/css/common/css_common.mk @@ -9,7 +9,7 @@ CSS_LOAD_SCP_IMAGES ?= 1 # By default, SCMI driver is disabled for CSS platforms -CSS_USE_SCMI_DRIVER ?= 0 +CSS_USE_SCMI_SDS_DRIVER ?= 0 PLAT_INCLUDES += -Iinclude/plat/arm/css/common \ -Iinclude/plat/arm/css/common/aarch64 @@ -19,18 +19,14 @@ PLAT_BL_COMMON_SOURCES += plat/arm/css/common/${ARCH}/css_helpers.S BL1_SOURCES += plat/arm/css/common/css_bl1_setup.c -BL2_SOURCES += plat/arm/css/common/css_bl2_setup.c \ - plat/arm/css/drivers/scpi/css_mhu.c \ - plat/arm/css/drivers/scpi/css_scpi.c +BL2_SOURCES += plat/arm/css/common/css_bl2_setup.c -BL2U_SOURCES += plat/arm/css/common/css_bl2u_setup.c \ - plat/arm/css/drivers/scpi/css_mhu.c \ - plat/arm/css/drivers/scpi/css_scpi.c +BL2U_SOURCES += plat/arm/css/common/css_bl2u_setup.c BL31_SOURCES += plat/arm/css/common/css_pm.c \ plat/arm/css/common/css_topology.c -ifeq (${CSS_USE_SCMI_DRIVER},0) +ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \ plat/arm/css/drivers/scpi/css_mhu.c \ plat/arm/css/drivers/scpi/css_scpi.c @@ -56,19 +52,34 @@ ifeq (${CSS_LOAD_SCP_IMAGES},1) $(eval $(call FWU_FIP_ADD_IMG,SCP_BL2U,--scp-fwu-cfg)) endif - BL2U_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c - BL2_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c + ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) + BL2U_SOURCES += plat/arm/css/drivers/scp/css_sds.c \ + plat/arm/css/drivers/sds/sds.c + + BL2_SOURCES += plat/arm/css/drivers/scp/css_sds.c \ + plat/arm/css/drivers/sds/sds.c + else + BL2U_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \ + plat/arm/css/drivers/scpi/css_mhu.c \ + plat/arm/css/drivers/scpi/css_scpi.c + + BL2_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \ + plat/arm/css/drivers/scpi/css_mhu.c \ + plat/arm/css/drivers/scpi/css_scpi.c + # Enable option to detect whether the SCP ROM firmware in use predates version + # 1.7.0 and therefore, is incompatible. + CSS_DETECT_PRE_1_7_0_SCP := 1 + + # Process CSS_DETECT_PRE_1_7_0_SCP flag + $(eval $(call assert_boolean,CSS_DETECT_PRE_1_7_0_SCP)) + $(eval $(call add_define,CSS_DETECT_PRE_1_7_0_SCP)) + endif endif -# Enable option to detect whether the SCP ROM firmware in use predates version -# 1.7.0 and therefore, is incompatible. -CSS_DETECT_PRE_1_7_0_SCP := 1 - -# Process CSS_DETECT_PRE_1_7_0_SCP flag -$(eval $(call assert_boolean,CSS_DETECT_PRE_1_7_0_SCP)) -$(eval $(call add_define,CSS_DETECT_PRE_1_7_0_SCP)) - -# Process CSS_USE_SCMI_DRIVER flag -$(eval $(call assert_boolean,CSS_USE_SCMI_DRIVER)) -$(eval $(call add_define,CSS_USE_SCMI_DRIVER)) +ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) + PLAT_BL_COMMON_SOURCES += plat/arm/css/drivers/sds/${ARCH}/sds_helpers.S +endif +# Process CSS_USE_SCMI_SDS_DRIVER flag +$(eval $(call assert_boolean,CSS_USE_SCMI_SDS_DRIVER)) +$(eval $(call add_define,CSS_USE_SCMI_SDS_DRIVER)) diff --git a/plat/arm/css/common/sp_min/css_sp_min.mk b/plat/arm/css/common/sp_min/css_sp_min.mk index 7423d781b..28eb2dbda 100644 --- a/plat/arm/css/common/sp_min/css_sp_min.mk +++ b/plat/arm/css/common/sp_min/css_sp_min.mk @@ -8,7 +8,7 @@ BL32_SOURCES += plat/arm/css/common/css_pm.c \ plat/arm/css/common/css_topology.c -ifeq (${CSS_USE_SCMI_DRIVER},0) +ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \ plat/arm/css/drivers/scpi/css_mhu.c \ plat/arm/css/drivers/scpi/css_scpi.c diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c index 047e0696a..a92ce6b4f 100644 --- a/plat/arm/css/drivers/scp/css_bom_bootloader.c +++ b/plat/arm/css/drivers/scp/css_bom_bootloader.c @@ -6,12 +6,12 @@ #include #include -#include #include #include #include #include #include "../scpi/css_mhu.h" +#include "../scpi/css_scpi.h" /* ID of the MHU slot used for the BOM protocol */ #define BOM_MHU_SLOT_ID 0 @@ -183,3 +183,11 @@ int css_scp_boot_image_xfer(void *image, unsigned int image_size) return 0; } + +int css_scp_boot_ready(void) +{ + VERBOSE("Waiting for SCP to signal it is ready to go on\n"); + + /* Wait for SCP to signal it's ready */ + return scpi_wait_ready(); +} diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c index 9098d3fa9..c39bc4ba7 100644 --- a/plat/arm/css/drivers/scp/css_pm_scmi.c +++ b/plat/arm/css/drivers/scp/css_pm_scmi.c @@ -324,8 +324,8 @@ void __dead2 css_scp_sys_reboot(void) scmi_channel_plat_info_t plat_css_scmi_plat_info = { .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE, .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, - .db_preserve_mask = 0xfffffffd, - .db_modify_mask = 0x2, + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, }; void plat_arm_pwrc_setup(void) diff --git a/plat/arm/css/drivers/scp/css_scp.h b/plat/arm/css/drivers/scp/css_scp.h index 097a9f587..223e372a2 100644 --- a/plat/arm/css/drivers/scp/css_scp.h +++ b/plat/arm/css/drivers/scp/css_scp.h @@ -7,8 +7,9 @@ #ifndef __CSS_SCP_H__ #define __CSS_SCP_H__ +#include +#include #include -#include "../scpi/css_scpi.h" /* Forward declarations */ struct psci_power_state; @@ -28,10 +29,20 @@ int css_scp_boot_image_xfer(void *image, unsigned int image_size); * API to wait for SCP to signal till it's ready after booting the transferred * image. */ -static inline int css_scp_boot_ready(void) -{ - VERBOSE("Waiting for SCP to signal it is ready to go on\n"); - return scpi_wait_ready(); -} +int css_scp_boot_ready(void); + +#if CSS_LOAD_SCP_IMAGES +/* + * All CSS platforms load SCP_BL2/SCP_BL2U just below BL rw-data and above + * BL2/BL2U (this is where BL31 usually resides except when ARM_BL31_IN_DRAM is + * set. Ensure that SCP_BL2/SCP_BL2U do not overflow into BL1 rw-data nor + * BL2/BL2U. + */ +CASSERT(SCP_BL2_LIMIT <= BL1_RW_BASE, assert_scp_bl2_limit_overwrite_bl1); +CASSERT(SCP_BL2U_LIMIT <= BL1_RW_BASE, assert_scp_bl2u_limit_overwrite_bl1); + +CASSERT(SCP_BL2_BASE >= BL2_LIMIT, assert_scp_bl2_overwrite_bl2); +CASSERT(SCP_BL2U_BASE >= BL2U_LIMIT, assert_scp_bl2u_overwrite_bl2u); +#endif #endif /* __CSS_SCP_H__ */ diff --git a/plat/arm/css/drivers/scp/css_sds.c b/plat/arm/css/drivers/scp/css_sds.c new file mode 100644 index 000000000..a7a51ba2d --- /dev/null +++ b/plat/arm/css/drivers/scp/css_sds.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include "../sds/sds.h" + +int css_scp_boot_image_xfer(void *image, unsigned int image_size) +{ + int ret; + unsigned int image_offset, image_flags; + + ret = sds_init(); + if (ret != SDS_OK) { + ERROR("SCP SDS initialization failed\n"); + panic(); + } + + VERBOSE("Writing SCP image metadata\n"); + image_offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE; + ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_ADDR_OFFSET, + &image_offset, SDS_SCP_IMG_ADDR_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) + goto sds_fail; + + ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_SIZE_OFFSET, + &image_size, SDS_SCP_IMG_SIZE_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) + goto sds_fail; + + VERBOSE("Marking SCP image metadata as valid\n"); + image_flags = SDS_SCP_IMG_VALID_FLAG_BIT; + ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_FLAG_OFFSET, + &image_flags, SDS_SCP_IMG_FLAG_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) + goto sds_fail; + + return 0; +sds_fail: + ERROR("SCP SDS write to SCP IMG struct failed\n"); + panic(); +} + +/* + * API to wait for SCP to signal till it's ready after booting the transferred + * image. + */ +int css_scp_boot_ready(void) +{ + uint32_t scp_feature_availability_flags; + int ret, retry = CSS_SCP_READY_10US_RETRIES; + + + VERBOSE("Waiting for SCP RAM to complete its initialization process\n"); + + /* Wait for the SCP RAM Firmware to complete its initialization process */ + while (retry > 0) { + ret = sds_struct_read(SDS_FEATURE_AVAIL_STRUCT_ID, 0, + &scp_feature_availability_flags, + SDS_FEATURE_AVAIL_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret == SDS_ERR_STRUCT_NOT_FINALIZED) + continue; + + if (ret != SDS_OK) { + ERROR(" sds_struct_read failed\n"); + panic(); + } + + if (scp_feature_availability_flags & + SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT) + return 0; + + udelay(10); + retry--; + } + + ERROR("Timeout of %d ms expired waiting for SCP RAM Ready flag\n", + CSS_SCP_READY_10US_RETRIES/100); + + plat_panic_handler(); +}