From 48ab390444e1dabb669430ace9b8e5a80348eed0 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Thu, 3 Mar 2022 15:24:31 -0600 Subject: [PATCH] feat(synquacer): add BL2 support Add BL2 support by default. Move the legacy mode behind the RESET_TO_BL31 define. Cc: Sumit Garg Cc: Masahisa Kojima Cc: Manish V Badarkhe Cc: Leonardo Sandoval Change-Id: Ic490745a7e8f6114172733428ebd6bd6adfcc1ec Signed-off-by: Jassi Brar --- .../synquacer/include/platform_def.h | 31 +++- plat/socionext/synquacer/include/sq_common.h | 4 +- plat/socionext/synquacer/platform.mk | 24 ++- plat/socionext/synquacer/sq_bl2_setup.c | 84 +++++++++++ plat/socionext/synquacer/sq_bl31_setup.c | 37 ++++- plat/socionext/synquacer/sq_helpers.S | 7 +- plat/socionext/synquacer/sq_image_desc.c | 76 ++++++++++ plat/socionext/synquacer/sq_io_storage.c | 142 ++++++++++++++++++ plat/socionext/synquacer/sq_psci.c | 10 +- 9 files changed, 407 insertions(+), 8 deletions(-) create mode 100644 plat/socionext/synquacer/sq_bl2_setup.c create mode 100644 plat/socionext/synquacer/sq_image_desc.c create mode 100644 plat/socionext/synquacer/sq_io_storage.c diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h index 49ffbf9a5..c03c7a4bb 100644 --- a/plat/socionext/synquacer/include/platform_def.h +++ b/plat/socionext/synquacer/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -44,14 +44,43 @@ #define PLATFORM_STACK_SIZE 0x400 +#if !RESET_TO_BL31 + +/* A mailbox page will be mapped from BL2 and BL31 */ +#define BL2_MAILBOX_BASE 0x0403f000 +#define BL2_MAILBOX_SIZE 0x1000 + +#define MAX_IO_HANDLES 2 +#define MAX_IO_DEVICES 2 +#define MAX_IO_BLOCK_DEVICES U(1) + +#define BL2_BASE 0x04000000 +#define BL2_SIZE (256 * 1024) +#define BL2_LIMIT (BL2_BASE + BL2_SIZE) + +/* If BL2 is enabled, the BL31 is loaded on secure DRAM */ +#define BL31_BASE 0xfbe00000 +#define BL31_SIZE 0x00100000 +#else + #define BL31_BASE 0x04000000 #define BL31_SIZE 0x00080000 +#endif + #define BL31_LIMIT (BL31_BASE + BL31_SIZE) #define BL32_BASE 0xfc000000 #define BL32_SIZE 0x03c00000 #define BL32_LIMIT (BL32_BASE + BL32_SIZE) +/* Alternative BL33 */ +#define PLAT_SQ_BL33_BASE 0xe0000000 +#define PLAT_SQ_BL33_SIZE 0x00100000 + +/* FIP IO base */ +#define PLAT_SQ_FIP_IOBASE 0x08600000 +#define PLAT_SQ_FIP_MAXSIZE 0x00400000 + #define PLAT_SQ_CCN_BASE 0x32000000 #define PLAT_SQ_CLUSTER_TO_CCN_ID_MAP \ 0, /* Cluster 0 */ \ diff --git a/plat/socionext/synquacer/include/sq_common.h b/plat/socionext/synquacer/include/sq_common.h index b09d22a03..eef0e1fb1 100644 --- a/plat/socionext/synquacer/include/sq_common.h +++ b/plat/socionext/synquacer/include/sq_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,6 +39,8 @@ void sq_gic_cpuif_enable(void); void sq_gic_cpuif_disable(void); void sq_gic_pcpu_init(void); +int sq_io_setup(void); +struct image_info *sq_get_image_info(unsigned int image_id); void sq_mmap_setup(uintptr_t total_base, size_t total_size, const struct mmap_region *mmap); diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk index 98a4c3eca..e46732492 100644 --- a/plat/socionext/synquacer/platform.mk +++ b/plat/socionext/synquacer/platform.mk @@ -4,15 +4,23 @@ # SPDX-License-Identifier: BSD-3-Clause # -override RESET_TO_BL31 := 1 override PROGRAMMABLE_RESET_ADDRESS := 1 override USE_COHERENT_MEM := 1 override SEPARATE_CODE_AND_RODATA := 1 override ENABLE_SVE_FOR_NS := 0 # Enable workarounds for selected Cortex-A53 erratas. ERRATA_A53_855873 := 1 -# Enable SCMI support -SQ_USE_SCMI_DRIVER ?= 0 + +ifeq (${RESET_TO_BL31}, 1) +override RESET_TO_BL31 := 1 +override TRUSTED_BOARD_BOOT := 0 +SQ_USE_SCMI_DRIVER ?= 0 +else +override RESET_TO_BL31 := 0 +override BL2_AT_EL3 := 1 +SQ_USE_SCMI_DRIVER := 1 +BL2_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC +endif # Libraries include lib/xlat_tables_v2/xlat_tables.mk @@ -35,6 +43,16 @@ PLAT_BL_COMMON_SOURCES += $(PLAT_PATH)/sq_helpers.S \ # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk +ifneq (${RESET_TO_BL31}, 1) +BL2_SOURCES += common/desc_image_load.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + $(PLAT_PATH)/sq_bl2_setup.c \ + $(PLAT_PATH)/sq_image_desc.c \ + $(PLAT_PATH)/sq_io_storage.c +endif + BL31_SOURCES += drivers/arm/ccn/ccn.c \ ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ diff --git a/plat/socionext/synquacer/sq_bl2_setup.c b/plat/socionext/synquacer/sq_bl2_setup.c new file mode 100644 index 000000000..a98d91220 --- /dev/null +++ b/plat/socionext/synquacer/sq_bl2_setup.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, Socionext Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static console_t console; + +void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, + u_register_t x2, u_register_t x3) +{ + /* Initialize the console to provide early debug support */ + (void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE, + PLAT_SQ_BOOT_UART_CLK_IN_HZ, + SQ_CONSOLE_BAUDRATE, &console); + console_set_scope(&console, CONSOLE_FLAG_BOOT); +} + +void bl2_el3_plat_arch_setup(void) +{ + int ret; + + sq_mmap_setup(BL2_BASE, BL2_SIZE, NULL); + + ret = sq_io_setup(); + if (ret) { + ERROR("failed to setup io devices\n"); + plat_error_handler(ret); + } +} + +void bl2_platform_setup(void) +{ +} + +void plat_flush_next_bl_params(void) +{ + flush_bl_params_desc(); +} + +bl_load_info_t *plat_get_bl_image_load_info(void) +{ + return get_bl_load_info_from_mem_params_desc(); +} + +bl_params_t *plat_get_next_bl_params(void) +{ + return get_next_bl_params_from_mem_params_desc(); +} + +void bl2_plat_preload_setup(void) +{ +} + +int bl2_plat_handle_pre_image_load(unsigned int image_id) +{ + struct image_info *image_info; + + image_info = sq_get_image_info(image_id); + + return mmap_add_dynamic_region(image_info->image_base, + image_info->image_base, + image_info->image_max_size, + MT_MEMORY | MT_RW | MT_NS); +} + +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + return 0; +} diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c index a7a0ce0be..967437b29 100644 --- a/plat/socionext/synquacer/sq_bl31_setup.c +++ b/plat/socionext/synquacer/sq_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -44,6 +44,35 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) return type == NON_SECURE ? &bl33_image_ep_info : &bl32_image_ep_info; } +#if !RESET_TO_BL31 +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + void *from_bl2 = (void *) arg0; + bl_params_node_t *bl_params = ((bl_params_t *) from_bl2)->head; + + /* Initialize the console to provide early debug support */ + (void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE, + PLAT_SQ_BOOT_UART_CLK_IN_HZ, + SQ_CONSOLE_BAUDRATE, &console); + + console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); + + /* Initialize power controller before setting up topology */ + plat_sq_pwrc_setup(); + + while (bl_params) { + if (bl_params->image_id == BL32_IMAGE_ID) + bl32_image_ep_info = *bl_params->ep_info; + + if (bl_params->image_id == BL33_IMAGE_ID) + bl33_image_ep_info = *bl_params->ep_info; + + bl_params = bl_params->next_params_info; + } +} + +#else /******************************************************************************* * Gets SPSR for BL32 entry ******************************************************************************/ @@ -129,6 +158,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, bl33_image_ep_info.spsr = sq_get_spsr_for_bl33_entry(); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); } +#endif static void sq_configure_sys_timer(void) { @@ -191,6 +221,11 @@ void bl31_plat_arch_setup(void) MAP_REGION_FLAT(PLAT_SQ_SP_PRIV_BASE, PLAT_SQ_SP_PRIV_SIZE, MT_RW_DATA | MT_SECURE), +#endif +#if !RESET_TO_BL31 + MAP_REGION_FLAT(BL2_MAILBOX_BASE, + BL2_MAILBOX_SIZE, + MT_RW | MT_SECURE), #endif {0}, }; diff --git a/plat/socionext/synquacer/sq_helpers.S b/plat/socionext/synquacer/sq_helpers.S index 7a2d97b33..5f9eab41e 100644 --- a/plat/socionext/synquacer/sq_helpers.S +++ b/plat/socionext/synquacer/sq_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -46,7 +46,12 @@ endfunc platform_mem_init * code that secondary CPUs jump to. */ func plat_secondary_cold_boot_setup +#if !RESET_TO_BL31 + mov_imm x0, BL2_MAILBOX_BASE + ldr x0, [x0] +#else ldr x0, sq_sec_entrypoint +#endif /* Wait until the mailbox gets populated */ poll_mailbox: diff --git a/plat/socionext/synquacer/sq_image_desc.c b/plat/socionext/synquacer/sq_image_desc.c new file mode 100644 index 000000000..5fe125b56 --- /dev/null +++ b/plat/socionext/synquacer/sq_image_desc.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Socionext Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include + +static struct bl_mem_params_node sq_image_descs[] = { + { + .image_id = BL31_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = BL31_BASE, + .image_info.image_max_size = BL31_SIZE, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + .ep_info.pc = BL31_BASE, + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), + + .next_handoff_image_id = BL32_IMAGE_ID, + }, + { + .image_id = BL32_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = BL32_BASE, + .image_info.image_max_size = BL32_SIZE, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE), + .ep_info.pc = BL32_BASE, + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), + + .next_handoff_image_id = BL33_IMAGE_ID, + }, + { + .image_id = BL33_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = PLAT_SQ_BL33_BASE, + .image_info.image_max_size = PLAT_SQ_BL33_SIZE, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + NON_SECURE | EXECUTABLE), + .ep_info.pc = PLAT_SQ_BL33_BASE, + .ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +}; +REGISTER_BL_IMAGE_DESCS(sq_image_descs) + +struct image_info *sq_get_image_info(unsigned int image_id) +{ + struct bl_mem_params_node *desc; + + desc = get_bl_mem_params_node(image_id); + assert(desc); + return &desc->image_info; +} diff --git a/plat/socionext/synquacer/sq_io_storage.c b/plat/socionext/synquacer/sq_io_storage.c new file mode 100644 index 000000000..d0fe2d323 --- /dev/null +++ b/plat/socionext/synquacer/sq_io_storage.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2022, Socionext Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static const io_dev_connector_t *sq_fip_dev_con; +static uintptr_t sq_fip_dev_handle; + +static const io_dev_connector_t *sq_backend_dev_con; +static uintptr_t sq_backend_dev_handle; + +static io_block_spec_t sq_fip_spec = { + .offset = PLAT_SQ_FIP_IOBASE, /* FIP Image is at 5MB offset on memory-mapped NOR flash */ + .length = PLAT_SQ_FIP_MAXSIZE, /* Expected maximum FIP image size */ +}; + +static const io_uuid_spec_t sq_bl2_spec = { + .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, +}; + +static const io_uuid_spec_t sq_bl31_spec = { + .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, +}; + +static const io_uuid_spec_t sq_bl32_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32, +}; + +static const io_uuid_spec_t sq_bl33_spec = { + .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, +}; + +struct sq_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + uintptr_t init_params; +}; + +static const struct sq_io_policy sq_io_policies[] = { + [FIP_IMAGE_ID] = { + .dev_handle = &sq_backend_dev_handle, + .image_spec = (uintptr_t)&sq_fip_spec, + }, + [BL2_IMAGE_ID] = { + .dev_handle = &sq_fip_dev_handle, + .image_spec = (uintptr_t)&sq_bl2_spec, + .init_params = FIP_IMAGE_ID, + }, + [BL31_IMAGE_ID] = { + .dev_handle = &sq_fip_dev_handle, + .image_spec = (uintptr_t)&sq_bl31_spec, + .init_params = FIP_IMAGE_ID, + }, + [BL32_IMAGE_ID] = { + .dev_handle = &sq_fip_dev_handle, + .image_spec = (uintptr_t)&sq_bl32_spec, + .init_params = FIP_IMAGE_ID, + }, + [BL33_IMAGE_ID] = { + .dev_handle = &sq_fip_dev_handle, + .image_spec = (uintptr_t)&sq_bl33_spec, + .init_params = FIP_IMAGE_ID, + }, +}; + +static int sq_io_memmap_setup(void) +{ + int ret; + + ret = mmap_add_dynamic_region(sq_fip_spec.offset, sq_fip_spec.offset, + sq_fip_spec.length, MT_RO_DATA | MT_SECURE); + if (ret) { + return ret; + } + + ret = register_io_dev_memmap(&sq_backend_dev_con); + if (ret) { + return ret; + } + + return io_dev_open(sq_backend_dev_con, 0, &sq_backend_dev_handle); +} + +static int sq_io_fip_setup(void) +{ + int ret; + + ret = register_io_dev_fip(&sq_fip_dev_con); + if (ret) { + return ret; + } + + return io_dev_open(sq_fip_dev_con, 0, &sq_fip_dev_handle); +} + +int sq_io_setup(void) +{ + int ret; + + ret = sq_io_memmap_setup(); + if (ret) { + return ret; + } + + ret = sq_io_fip_setup(); + if (ret) { + return ret; + } + + return 0; +} + +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + uintptr_t init_params; + + assert(image_id < ARRAY_SIZE(sq_io_policies)); + + *dev_handle = *sq_io_policies[image_id].dev_handle; + *image_spec = sq_io_policies[image_id].image_spec; + init_params = sq_io_policies[image_id].init_params; + + return io_dev_init(*dev_handle, init_params); +} diff --git a/plat/socionext/synquacer/sq_psci.c b/plat/socionext/synquacer/sq_psci.c index 3062f6318..017516ff8 100644 --- a/plat/socionext/synquacer/sq_psci.c +++ b/plat/socionext/synquacer/sq_psci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -197,9 +197,17 @@ const plat_psci_ops_t sq_psci_ops = { int plat_setup_psci_ops(uintptr_t sec_entrypoint, const struct plat_psci_ops **psci_ops) { +#if !RESET_TO_BL31 + uintptr_t *sq_sec_ep = (uintptr_t *)BL2_MAILBOX_BASE; + + *sq_sec_ep = sec_entrypoint; + flush_dcache_range((uint64_t)sq_sec_ep, + sizeof(*sq_sec_ep)); +#else sq_sec_entrypoint = sec_entrypoint; flush_dcache_range((uint64_t)&sq_sec_entrypoint, sizeof(sq_sec_entrypoint)); +#endif *psci_ops = &sq_psci_ops;