diff options
Diffstat (limited to 'plat/arm')
224 files changed, 9385 insertions, 1331 deletions
diff --git a/plat/arm/board/a5ds/a5ds_err.c b/plat/arm/board/a5ds/a5ds_err.c index 65b41dd4c..feb9fdfaa 100644 --- a/plat/arm/board/a5ds/a5ds_err.c +++ b/plat/arm/board/a5ds/a5ds_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts new file mode 100644 index 000000000..b9ff8bff1 --- /dev/null +++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x2001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + + hw-config { + load-address = <0x0 0x83000000>; + max-size = <0x01000000>; + id = <HW_CONFIG_ID>; + }; + }; +}; diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts index 7b3aa1144..c66186f64 100644 --- a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts +++ b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * Copyright (c) 2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,11 +7,9 @@ /dts-v1/; / { - /* Platform Config */ - plat_arm_bl2 { + tb_fw-config { compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x83000000>; - hw_config_max_size = <0x01000000>; + /* Disable authentication for development */ disable_auth = <0x0>; }; diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h index 31dfb1cf1..792a754fa 100644 --- a/plat/arm/board/a5ds/include/platform_def.h +++ b/plat/arm/board/a5ds/include/platform_def.h @@ -11,6 +11,7 @@ #include <lib/utils_def.h> #include <lib/xlat_tables/xlat_tables_defs.h> #include <plat/arm/board/common/v2m_def.h> +#include <plat/arm/common/smccc_def.h> #include <plat/common/common_def.h> /* Memory location options for TSP */ @@ -151,10 +152,18 @@ #endif /* + * Map the region for device tree configuration with read and write permissions + */ +#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT(ARM_BL_RAM_BASE, \ + (ARM_FW_CONFIGS_LIMIT \ + - ARM_BL_RAM_BASE), \ + MT_MEMORY | MT_RW | MT_SECURE) + +/* * The max number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. */ -#define ARM_BL_REGIONS 5 +#define ARM_BL_REGIONS 6 #define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ ARM_BL_REGIONS) @@ -187,11 +196,17 @@ #define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space of BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) + +/* + * Define limit of firmware configuration memory: + * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory + */ +#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2)) /******************************************************************************* * BL1 specific defines. @@ -219,7 +234,9 @@ #define BL2_LIMIT BL1_RW_BASE /* Put BL32 below BL2 in NS DRAM.*/ -#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \ + + (PAGE_SIZE / 2U)) #define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\ - PLAT_ARM_MAX_BL32_SIZE) diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index d42b2bfa8..8b0dc5cf3 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -1,9 +1,12 @@ # -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk @@ -11,9 +14,10 @@ DYN_CFG_SOURCES += plat/arm/common/arm_dyn_cfg.c \ plat/arm/common/arm_dyn_cfg_helpers.c \ common/fdt_wrappers.c -A5DS_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +A5DS_GIC_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c @@ -38,6 +42,7 @@ BL1_SOURCES += drivers/io/io_fip.c \ plat/arm/common/arm_err.c \ plat/arm/board/a5ds/a5ds_err.c \ plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c \ plat/arm/board/a5ds/${ARCH}/a5ds_helpers.S \ plat/arm/board/a5ds/a5ds_bl1_setup.c \ lib/aarch32/arm32_aeabi_divmod.c \ @@ -58,6 +63,7 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \ plat/arm/common/arm_err.c \ plat/arm/board/a5ds/a5ds_err.c \ plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c \ plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c \ plat/arm/common/arm_image_load.c \ common/desc_image_load.c \ @@ -67,17 +73,21 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb +FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ fdts/$(notdir ${FVP_HW_CONFIG_DTS}))) # Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG})) -FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \ +FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \ + plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \ ${FVP_HW_CONFIG_DTS} endif diff --git a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S new file mode 100644 index 000000000..20120c9c3 --- /dev/null +++ b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> +#include <common/bl_common.h> +#include "../fpga_private.h" + +#include <platform_def.h> + + .globl plat_get_my_entrypoint + .globl plat_secondary_cold_boot_setup + .globl plat_is_my_cpu_primary + .globl platform_mem_init + .globl plat_my_core_pos + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl plat_crash_console_flush + .globl plat_fpga_calc_core_pos + +/* ----------------------------------------------------------------------- + * Indicate a cold boot for every CPU - warm boot is unsupported for the + * holding pen PSCI implementation. + * ----------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + mov x0, #0 + ret +endfunc plat_get_my_entrypoint + +/* ----------------------------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * ----------------------------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + + /* + * Wait for the primary processor to initialise the .BSS segment + * to avoid a race condition that would erase fpga_valid_mpids + * if it is populated before the C runtime is ready. + * + * We cannot use the current spin-lock implementation until the + * runtime is up and we should not rely on sevl/wfe instructions as + * it is optional whether they are implemented or not, so we use + * a global variable as lock and wait for the primary processor to + * finish the C runtime bring-up. + */ + + ldr w0, =C_RUNTIME_READY_KEY + adrp x1, secondary_core_spinlock + add x1, x1, :lo12:secondary_core_spinlock +1: + wfe + ldr w2, [x1] + cmp w2, w0 + b.ne 1b + /* Prevent reordering of the store into fpga_valid_mpids below */ + dmb ish + + mov x10, x30 + bl plat_my_core_pos + mov x30, x10 + + adrp x4, fpga_valid_mpids + add x4, x4, :lo12:fpga_valid_mpids + mov x5, #VALID_MPID + strb w5, [x4, x0] + + /* + * Poll the CPU's hold entry until it indicates to jump + * to the entrypoint address. + */ + + adrp x1, hold_base + add x1, x1, :lo12:hold_base +poll_hold_entry: + ldr x3, [x1, x0, LSL #PLAT_FPGA_HOLD_ENTRY_SHIFT] + cmp x3, #PLAT_FPGA_HOLD_STATE_GO + b.ne 1f + + adrp x2, fpga_sec_entrypoint + add x2, x2, :lo12:fpga_sec_entrypoint + ldr x3, [x2] + br x3 +1: + wfe + b poll_hold_entry + +endfunc plat_secondary_cold_boot_setup + +/* ----------------------------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary cpu + * ----------------------------------------------------------------------- + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + mov_imm x1, MPIDR_AFFINITY_MASK + and x0, x0, x1 + cmp x0, #FPGA_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary + +func platform_mem_init + ret +endfunc platform_mem_init + +func plat_my_core_pos + ldr x1, =(MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT)) + mrs x0, mpidr_el1 + and x0, x0, x1 + b plat_fpga_calc_core_pos + +endfunc plat_my_core_pos + +/* ----------------------------------------------------------------------- + * unsigned int plat_fpga_calc_core_pos (uint32_t mpid) + * Clobber registers: x0 to x5 + * ----------------------------------------------------------------------- + */ +func plat_fpga_calc_core_pos + /* + * Check for MT bit in MPIDR, which may be either value for images + * running on the FPGA. + * + * If not set, shift MPIDR to left to make it look as if in a + * multi-threaded implementation. + * + */ + tst x0, #MPIDR_MT_MASK + lsl x3, x0, #MPIDR_AFFINITY_BITS + csel x3, x3, x0, eq + + /* 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 + + mov x4, #FPGA_MAX_CPUS_PER_CLUSTER + mov x5, #FPGA_MAX_PE_PER_CPU + + /* Compute linear position */ + madd x1, x2, x4, x1 + madd x0, x1, x5, x0 + + ret +endfunc plat_fpga_calc_core_pos + +func plat_crash_console_init + mov_imm x0, PLAT_FPGA_CRASH_UART_BASE + b console_pl011_core_init +endfunc plat_crash_console_init + +func plat_crash_console_putc + mov_imm x1, PLAT_FPGA_CRASH_UART_BASE + b console_pl011_core_putc +endfunc plat_crash_console_putc + +func plat_crash_console_flush + mov_imm x0, PLAT_FPGA_CRASH_UART_BASE + b console_pl011_core_flush +endfunc plat_crash_console_flush diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S new file mode 100644 index 000000000..d7cd00882 --- /dev/null +++ b/plat/arm/board/arm_fpga/build_axf.ld.S @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Linker script for the Arm Ltd. FPGA boards to generate an ELF file that + * contains the ROM trampoline, BL31 and the DTB. + * + * This allows to pass just one file to the uploader tool, and automatically + * provides the correct load addresses. + */ + +#include <platform_def.h> + +OUTPUT_FORMAT("elf64-littleaarch64") +OUTPUT_ARCH(aarch64) + +INPUT(./bl31/bl31.elf) +INPUT(./rom_trampoline.o) + +TARGET(binary) +INPUT(./fdts/arm_fpga.dtb) + +ENTRY(_start) + +SECTIONS +{ + .rom (0x0): { + *rom_trampoline.o(.text*) + KEEP(*(.rom)) + } + + .bl31 (BL31_BASE): { + ASSERT(. == ALIGN(PAGE_SIZE), "BL31_BASE is not page aligned"); + *bl31.elf(.text* .data* .rodata* ro* .bss*) + *bl31.elf(.stack) + } + + .dtb (FPGA_PRELOADED_DTB_BASE): { + ASSERT(. == ALIGN(8), "DTB address is not 8-byte aligned"); + *arm_fpga.dtb + } + + /DISCARD/ : { *(.debug_*) } + /DISCARD/ : { *(.note*) } + /DISCARD/ : { *(.comment*) } +} diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c new file mode 100644 index 000000000..a5f5ea0f3 --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> + +#include <common/fdt_fixup.h> +#include <common/fdt_wrappers.h> +#include <drivers/arm/gicv3.h> +#include <drivers/delay_timer.h> +#include <drivers/generic_delay_timer.h> +#include <lib/extensions/spe.h> +#include <libfdt.h> + +#include "fpga_private.h" +#include <plat/common/platform.h> +#include <platform_def.h> + +static entry_point_info_t bl33_image_ep_info; +volatile uint32_t secondary_core_spinlock; + +uintptr_t plat_get_ns_image_entrypoint(void) +{ +#ifdef PRELOADED_BL33_BASE + return PRELOADED_BL33_BASE; +#else + return 0ULL; +#endif +} + +uint32_t fpga_get_spsr_for_bl33_entry(void) +{ + return SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + /* Add this core to the VALID mpids list */ + fpga_valid_mpids[plat_my_core_pos()] = VALID_MPID; + + /* + * Notify the secondary CPUs that the C runtime is ready + * so they can announce themselves. + */ + secondary_core_spinlock = C_RUNTIME_READY_KEY; + dsbish(); + sev(); + + fpga_console_init(); + + bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + bl33_image_ep_info.spsr = fpga_get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + + /* Set x0-x3 for the primary CPU as expected by the kernel */ + bl33_image_ep_info.args.arg0 = (u_register_t)FPGA_PRELOADED_DTB_BASE; + bl33_image_ep_info.args.arg1 = 0U; + bl33_image_ep_info.args.arg2 = 0U; + bl33_image_ep_info.args.arg3 = 0U; +} + +void bl31_plat_arch_setup(void) +{ +} + +void bl31_platform_setup(void) +{ + /* Write frequency to CNTCRL and initialize timer */ + generic_delay_timer_init(); + + /* + * Before doing anything else, wait for some time to ensure that + * the secondary CPUs have populated the fpga_valid_mpids array. + * As the number of secondary cores is unknown and can even be 0, + * it is not possible to rely on any signal from them, so use a + * delay instead. + */ + mdelay(5); + + /* + * On the event of a cold reset issued by, for instance, a reset pin + * assertion, we cannot guarantee memory to be initialized to zero. + * In such scenario, if the secondary cores reached + * plat_secondary_cold_boot_setup before the primary one initialized + * .BSS, we could end up having a race condition if the spinlock + * was not cleared before. + * + * Similarly, if there were a reset before the spinlock had been + * cleared, the secondary cores would find the lock opened before + * .BSS is cleared, causing another race condition. + * + * So clean the spinlock as soon as we think it is safe to reduce the + * chances of any race condition on a reset. + */ + secondary_core_spinlock = 0UL; + + /* Initialize the GIC driver, cpu and distributor interfaces */ + plat_fpga_gic_init(); +} + +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + next_image_info = &bl33_image_ep_info; + + /* Only expecting BL33: the kernel will run in EL2NS */ + assert(type == NON_SECURE); + + /* None of the images can have 0x0 as the entrypoint */ + if (next_image_info->pc) { + return next_image_info; + } else { + return NULL; + } +} + +unsigned int plat_get_syscnt_freq2(void) +{ + const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; + int node; + + node = fdt_node_offset_by_compatible(fdt, 0, "arm,armv8-timer"); + if (node < 0) { + return FPGA_DEFAULT_TIMER_FREQUENCY; + } + + return fdt_read_uint32_default(fdt, node, "clock-frequency", + FPGA_DEFAULT_TIMER_FREQUENCY); +} + +static void fpga_prepare_dtb(void) +{ + void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; + const char *cmdline = (void *)(uintptr_t)FPGA_PRELOADED_CMD_LINE; + int err; + + err = fdt_open_into(fdt, fdt, FPGA_MAX_DTB_SIZE); + if (err < 0) { + ERROR("cannot open devicetree at %p: %d\n", fdt, err); + panic(); + } + + /* Check for the command line signature. */ + if (!strncmp(cmdline, "CMD:", 4)) { + int chosen; + + INFO("using command line at 0x%x\n", FPGA_PRELOADED_CMD_LINE); + + chosen = fdt_add_subnode(fdt, 0, "chosen"); + if (chosen == -FDT_ERR_EXISTS) { + chosen = fdt_path_offset(fdt, "/chosen"); + } + if (chosen < 0) { + ERROR("cannot find /chosen node: %d\n", chosen); + } else { + const char *eol; + char nul = 0; + int slen; + + /* + * There is most likely an EOL at the end of the + * command line, make sure we terminate the line there. + * We can't replace the EOL with a NUL byte in the + * source, as this is in read-only memory. So we first + * create the property without any termination, then + * append a single NUL byte. + */ + eol = strchr(cmdline, '\n'); + if (!eol) { + eol = strchr(cmdline, 0); + } + /* Skip the signature and omit the EOL/NUL byte. */ + slen = eol - (cmdline + 4); + + /* + * Let's limit the size of the property, just in case + * we find the signature by accident. The Linux kernel + * limits to 4096 characters at most (in fact 2048 for + * arm64), so that sounds like a reasonable number. + */ + if (slen > 4095) { + slen = 4095; + } + err = fdt_setprop(fdt, chosen, "bootargs", + cmdline + 4, slen); + if (!err) { + err = fdt_appendprop(fdt, chosen, "bootargs", + &nul, 1); + } + if (err) { + ERROR("Could not set command line: %d\n", err); + } + } + } + + if (err < 0) { + ERROR("Error %d extending Device Tree\n", err); + panic(); + } + + err = fdt_add_cpus_node(fdt, FPGA_MAX_PE_PER_CPU, + FPGA_MAX_CPUS_PER_CLUSTER, + FPGA_MAX_CLUSTER_COUNT); + + if (err == -EEXIST) { + WARN("Not overwriting already existing /cpus node in DTB\n"); + } else { + if (err < 0) { + ERROR("Error %d creating the /cpus DT node\n", err); + panic(); + } else { + unsigned int nr_cores = fpga_get_nr_gic_cores(); + + INFO("Adjusting GICR DT region to cover %u cores\n", + nr_cores); + err = fdt_adjust_gic_redist(fdt, nr_cores, + 1U << GICR_PCPUBASE_SHIFT); + if (err < 0) { + ERROR("Error %d fixing up GIC DT node\n", err); + } + } + } + + /* Check whether we support the SPE PMU. Remove the DT node if not. */ + if (!spe_supported()) { + int node = fdt_node_offset_by_compatible(fdt, 0, + "arm,statistical-profiling-extension-v1"); + + if (node >= 0) { + fdt_del_node(fdt, node); + } + } + + err = fdt_pack(fdt); + if (err < 0) { + ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err); + } + + clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt)); +} + +void bl31_plat_runtime_setup(void) +{ + fpga_prepare_dtb(); +} + +void bl31_plat_enable_mmu(uint32_t flags) +{ + /* TODO: determine if MMU needs to be enabled */ +} diff --git a/plat/arm/board/arm_fpga/fpga_console.c b/plat/arm/board/arm_fpga/fpga_console.c new file mode 100644 index 000000000..8c1da62e2 --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_console.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stddef.h> +#include <stdint.h> + +#include <common/fdt_wrappers.h> +#include <drivers/arm/pl011.h> +#include <drivers/console.h> + +#include <platform_def.h> + +static console_t console; + +void fpga_console_init(void) +{ + const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; + uintptr_t base_addr = PLAT_FPGA_CRASH_UART_BASE; + int node; + + /* + * Try to read the UART base address from the DT, by chasing the + * stdout-path property of the chosen node. + * If this does not work, use the crash console address as a fallback. + */ + node = fdt_get_stdout_node_offset(fdt); + if (node >= 0) { + fdt_get_reg_props_by_index(fdt, node, 0, &base_addr, NULL); + } + + (void)console_pl011_register(base_addr, 0, 0, &console); + + console_set_scope(&console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME); +} diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h new file mode 100644 index 000000000..2884ea6d4 --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_def.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/utils_def.h> + +#ifndef FPGA_DEF_H +#define FPGA_DEF_H + +/* + * These are set to large values to account for images describing systems with + * larger cluster configurations. + * + * For cases where the number of clusters, cores or threads is smaller than a + * maximum value below, this does not affect the PSCI functionality as any PEs + * that are present will still be indexed appropriately regardless of any empty + * entries in the array used to represent the topology. + */ + +#define FPGA_MAX_CLUSTER_COUNT 4 +#define FPGA_MAX_CPUS_PER_CLUSTER 8 +#define FPGA_MAX_PE_PER_CPU 4 + +#define FPGA_PRIMARY_CPU 0x0 +/******************************************************************************* + * FPGA image memory map related constants + ******************************************************************************/ + +/* + * UART base address, just for the crash console, as a fallback. + * The actual console UART address is taken from the DT. + */ +#define PLAT_FPGA_CRASH_UART_BASE 0x7ff80000 + +#define FPGA_DEFAULT_TIMER_FREQUENCY 10000000 + +#endif diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c new file mode 100644 index 000000000..bfc116bef --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_gicv3.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <drivers/arm/gicv3.h> +#include <drivers/arm/gic_common.h> +#include <libfdt.h> + +#include <platform_def.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +static const interrupt_prop_t fpga_interrupt_props[] = { + PLATFORM_G1S_PROPS(INTR_GROUP1S), + PLATFORM_G0_PROPS(INTR_GROUP0) +}; + +static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr) +{ + return (unsigned int)plat_core_pos_by_mpidr(mpidr); +} + +static gicv3_driver_data_t fpga_gicv3_driver_data = { + .interrupt_props = fpga_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(fpga_interrupt_props), + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = fpga_rdistif_base_addrs, + .mpidr_to_core_pos = fpga_mpidr_to_core_pos +}; + +void plat_fpga_gic_init(void) +{ + const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; + int node, ret; + + node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-v3"); + if (node < 0) { + WARN("No \"arm,gic-v3\" compatible node found in DT, no GIC support.\n"); + return; + } + + /* TODO: Assuming only empty "ranges;" properties up the bus path. */ + ret = fdt_get_reg_props_by_index(fdt, node, 0, + &fpga_gicv3_driver_data.gicd_base, NULL); + if (ret < 0) { + WARN("Could not read GIC distributor address from DT.\n"); + return; + } + + ret = fdt_get_reg_props_by_index(fdt, node, 1, + &fpga_gicv3_driver_data.gicr_base, NULL); + if (ret < 0) { + WARN("Could not read GIC redistributor address from DT.\n"); + return; + } + + gicv3_driver_init(&fpga_gicv3_driver_data); + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void fpga_pwr_gic_on_finish(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void fpga_pwr_gic_off(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); + gicv3_rdistif_off(plat_my_core_pos()); +} + +unsigned int fpga_get_nr_gic_cores(void) +{ + return gicv3_rdistif_get_number_frames(fpga_gicv3_driver_data.gicr_base); +} diff --git a/plat/arm/board/arm_fpga/fpga_pm.c b/plat/arm/board/arm_fpga/fpga_pm.c new file mode 100644 index 000000000..a306a23d4 --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_pm.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <lib/psci/psci.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/common/platform.h> + +#include "fpga_private.h" +#include <platform_def.h> + +/* + * This is a basic PSCI implementation that allows secondary CPUs to be + * released from their initial state and continue to the warm boot entrypoint. + * + * The secondary CPUs are placed in a holding pen and released by calls + * to fpga_pwr_domain_on(mpidr), which updates the hold entry for the CPU + * specified by the mpidr argument - the (polling) target CPU will then branch + * to the BL31 warm boot sequence at the entrypoint address. + * + * Additionally, the secondary CPUs are kept in a low-power wfe() state + * (placed there at the end of each poll) and woken when necessary through + * calls to sev() in fpga_pwr_domain_on(mpidr), once the hold state for the + * relevant CPU has been updated. + * + * Hotplug is currently implemented using a wfi-loop, which removes the + * dependencies on any power controllers or other mechanism that is specific + * to the running system as specified by the FPGA image. + */ + +uint64_t hold_base[PLATFORM_CORE_COUNT]; +uintptr_t fpga_sec_entrypoint; + +/* + * Calls to the CPU specified by the mpidr will set its hold entry to a value + * indicating that it should stop polling and branch off to the warm entrypoint. + */ +static int fpga_pwr_domain_on(u_register_t mpidr) +{ + int pos = plat_core_pos_by_mpidr(mpidr); + unsigned long current_mpidr = read_mpidr_el1(); + + if (pos < 0) { + panic(); + } + + if (mpidr == current_mpidr) { + return PSCI_E_ALREADY_ON; + } + hold_base[pos] = PLAT_FPGA_HOLD_STATE_GO; + flush_dcache_range((uintptr_t)&hold_base[pos], sizeof(uint64_t)); + sev(); /* Wake any CPUs from wfe */ + + return PSCI_E_SUCCESS; +} + +void fpga_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + fpga_pwr_gic_on_finish(); +} + +static void fpga_pwr_domain_off(const psci_power_state_t *target_state) +{ + fpga_pwr_gic_off(); + + while (1) { + wfi(); + } +} + +static void fpga_cpu_standby(plat_local_state_t cpu_state) +{ + /* + * Enter standby state + * dsb is good practice before using wfi to enter low power states + */ + u_register_t scr = read_scr_el3(); + write_scr_el3(scr|SCR_IRQ_BIT); + dsb(); + wfi(); + write_scr_el3(scr); +} + +plat_psci_ops_t plat_fpga_psci_pm_ops = { + .pwr_domain_on = fpga_pwr_domain_on, + .pwr_domain_on_finish = fpga_pwr_domain_on_finish, + .pwr_domain_off = fpga_pwr_domain_off, + .cpu_standby = fpga_cpu_standby +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + fpga_sec_entrypoint = sec_entrypoint; + flush_dcache_range((uint64_t)&fpga_sec_entrypoint, + sizeof(fpga_sec_entrypoint)); + *psci_ops = &plat_fpga_psci_pm_ops; + return 0; +} diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h new file mode 100644 index 000000000..1ca241f26 --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FPGA_PRIVATE_H +#define FPGA_PRIVATE_H + +#include "../fpga_def.h" +#include <platform_def.h> + +#define C_RUNTIME_READY_KEY (0xaa55aa55) +#define VALID_MPID (1U) +#define FPGA_MAX_DTB_SIZE 0x10000 + +#ifndef __ASSEMBLER__ + +extern unsigned char fpga_valid_mpids[PLATFORM_CORE_COUNT]; + +void fpga_console_init(void); + +void plat_fpga_gic_init(void); +void fpga_pwr_gic_on_finish(void); +void fpga_pwr_gic_off(void); +unsigned int plat_fpga_calc_core_pos(uint32_t mpid); +unsigned int fpga_get_nr_gic_cores(void); + +#endif /* __ASSEMBLER__ */ + +#endif /* FPGA_PRIVATE_H */ diff --git a/plat/arm/board/arm_fpga/fpga_topology.c b/plat/arm/board/arm_fpga/fpga_topology.c new file mode 100644 index 000000000..7fead869b --- /dev/null +++ b/plat/arm/board/arm_fpga/fpga_topology.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/spinlock.h> + +#include "fpga_private.h" +#include <plat/common/platform.h> +#include <platform_def.h> + +unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2]; +unsigned char fpga_valid_mpids[PLATFORM_CORE_COUNT]; + +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + unsigned int i; + + /* + * The highest level is the system level. The next level is constituted + * by clusters and then cores in clusters. + * + * This description of the power domain topology is aligned with the CPU + * indices returned by the plat_core_pos_by_mpidr() and plat_my_core_pos() + * APIs. + * + * A description of the topology tree can be found at + * https://trustedfirmware-a.readthedocs.io/en/latest/design/psci-pd-tree.html#design + */ + + if (fpga_power_domain_tree_desc[0] == 0U) { + /* + * As fpga_power_domain_tree_desc[0] == 0, assume that the + * Power Domain Topology Tree has not been initialized, so + * perform the initialization here. + */ + + fpga_power_domain_tree_desc[0] = 1U; + fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT; + + for (i = 0U; i < FPGA_MAX_CLUSTER_COUNT; i++) { + fpga_power_domain_tree_desc[2 + i] = + (FPGA_MAX_CPUS_PER_CLUSTER * + FPGA_MAX_PE_PER_CPU); + } + } + + return fpga_power_domain_tree_desc; +} + +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int core_pos; + + mpidr &= (MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT)); + mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); + + if ((MPIDR_AFFLVL2_VAL(mpidr) >= FPGA_MAX_CLUSTER_COUNT) || + (MPIDR_AFFLVL1_VAL(mpidr) >= FPGA_MAX_CPUS_PER_CLUSTER) || + (MPIDR_AFFLVL0_VAL(mpidr) >= FPGA_MAX_PE_PER_CPU)) { + ERROR ("Invalid mpidr: 0x%08x\n", (uint32_t)mpidr); + panic(); + } + + /* Calculate the core position, based on the maximum topology. */ + core_pos = plat_fpga_calc_core_pos(mpidr); + + /* Check whether this core is actually present. */ + if (fpga_valid_mpids[core_pos] != VALID_MPID) { + return -1; + } + + return core_pos; +} diff --git a/plat/arm/board/arm_fpga/include/plat_macros.S b/plat/arm/board/arm_fpga/include/plat_macros.S new file mode 100644 index 000000000..44cddeb36 --- /dev/null +++ b/plat/arm/board/arm_fpga/include/plat_macros.S @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +.macro plat_crash_print_regs +.endm + +#endif diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h new file mode 100644 index 000000000..411b936da --- /dev/null +++ b/plat/arm/board/arm_fpga/include/platform_def.h @@ -0,0 +1,88 @@ +/* + * 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 <plat/common/common_def.h> +#include <platform_def.h> +#include "../fpga_def.h" + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" + +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE UL(0x800) + +#define CACHE_WRITEBACK_SHIFT U(6) +#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) + +#define PLATFORM_CORE_COUNT \ + (FPGA_MAX_CLUSTER_COUNT * \ + FPGA_MAX_CPUS_PER_CLUSTER * \ + FPGA_MAX_PE_PER_CPU) + +#define PLAT_NUM_PWR_DOMAINS (FPGA_MAX_CLUSTER_COUNT + PLATFORM_CORE_COUNT + 1) + +#if !ENABLE_PIE +#define BL31_BASE UL(0x80000000) +#define BL31_LIMIT UL(0x80100000) +#else +#define BL31_BASE UL(0x0) +#define BL31_LIMIT UL(0x01000000) +#endif + +#define PLAT_SDEI_NORMAL_PRI 0x70 + +#define ARM_IRQ_SEC_PHY_TIMER 29 + +#define ARM_IRQ_SEC_SGI_0 8 +#define ARM_IRQ_SEC_SGI_1 9 +#define ARM_IRQ_SEC_SGI_2 10 +#define ARM_IRQ_SEC_SGI_3 11 +#define ARM_IRQ_SEC_SGI_4 12 +#define ARM_IRQ_SEC_SGI_5 13 +#define ARM_IRQ_SEC_SGI_6 14 +#define ARM_IRQ_SEC_SGI_7 15 + +/* + * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLATFORM_G1S_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE) + +#define PLATFORM_G0_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE) + +#define PLAT_MAX_RET_STATE 1 +#define PLAT_MAX_OFF_STATE 2 + +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 + +#define PLAT_FPGA_HOLD_ENTRY_SHIFT 3 +#define PLAT_FPGA_HOLD_STATE_WAIT 0 +#define PLAT_FPGA_HOLD_STATE_GO 1 + +#endif diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk new file mode 100644 index 000000000..3ac1c01ab --- /dev/null +++ b/plat/arm/board/arm_fpga/platform.mk @@ -0,0 +1,120 @@ +# +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include lib/libfdt/libfdt.mk + +RESET_TO_BL31 := 1 +ifeq (${RESET_TO_BL31}, 0) +$(error "This is a BL31-only port; RESET_TO_BL31 must be enabled") +endif + +ifeq (${ENABLE_PIE}, 1) +override SEPARATE_CODE_AND_RODATA := 1 +endif + +CTX_INCLUDE_AARCH32_REGS := 0 +ifeq (${CTX_INCLUDE_AARCH32_REGS}, 1) +$(error "This is an AArch64-only port; CTX_INCLUDE_AARCH32_REGS must be disabled") +endif + +ifeq (${TRUSTED_BOARD_BOOT}, 1) +$(error "TRUSTED_BOARD_BOOT must be disabled") +endif + +PRELOADED_BL33_BASE := 0x80080000 + +FPGA_PRELOADED_DTB_BASE := 0x80070000 +$(eval $(call add_define,FPGA_PRELOADED_DTB_BASE)) + +FPGA_PRELOADED_CMD_LINE := 0x1000 +$(eval $(call add_define,FPGA_PRELOADED_CMD_LINE)) + +# Treating this as a memory-constrained port for now +USE_COHERENT_MEM := 0 + +# This can be overridden depending on CPU(s) used in the FPGA image +HW_ASSISTED_COHERENCY := 1 + +PL011_GENERIC_UART := 1 + +SUPPORT_UNKNOWN_MPID ?= 1 + +FPGA_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S + +# select a different set of CPU files, depending on whether we compile for +# hardware assisted coherency cores or not +ifeq (${HW_ASSISTED_COHERENCY}, 0) +# Cores used without DSU + FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a35.S \ + lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a57.S \ + lib/cpus/aarch64/cortex_a72.S \ + lib/cpus/aarch64/cortex_a73.S +else +# AArch64-only cores + FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \ + lib/cpus/aarch64/cortex_a76ae.S \ + lib/cpus/aarch64/cortex_a77.S \ + lib/cpus/aarch64/cortex_a78.S \ + lib/cpus/aarch64/neoverse_n_common.S \ + lib/cpus/aarch64/neoverse_n1.S \ + lib/cpus/aarch64/neoverse_n2.S \ + lib/cpus/aarch64/neoverse_e1.S \ + lib/cpus/aarch64/neoverse_v1.S \ + lib/cpus/aarch64/cortex_a78_ae.S \ + lib/cpus/aarch64/cortex_a65.S \ + lib/cpus/aarch64/cortex_a65ae.S \ + lib/cpus/aarch64/cortex_klein.S \ + lib/cpus/aarch64/cortex_matterhorn.S + +# AArch64/AArch32 cores + FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ + lib/cpus/aarch64/cortex_a75.S +endif + +ifeq (${SUPPORT_UNKNOWN_MPID}, 1) +# Add support for unknown/invalid MPIDs (aarch64 only) +$(eval $(call add_define,SUPPORT_UNKNOWN_MPID)) + FPGA_CPU_LIBS += lib/cpus/aarch64/generic.S +endif + +# Allow detection of GIC-600 +GICV3_SUPPORT_GIC600 := 1 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +FPGA_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/arm/board/arm_fpga/fpga_gicv3.c + +FDT_SOURCES := fdts/arm_fpga.dts + +PLAT_INCLUDES := -Iplat/arm/board/arm_fpga/include + +PLAT_BL_COMMON_SOURCES := plat/arm/board/arm_fpga/${ARCH}/fpga_helpers.S + +BL31_SOURCES += common/fdt_wrappers.c \ + common/fdt_fixup.c \ + drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + drivers/arm/pl011/${ARCH}/pl011_console.S \ + plat/common/plat_psci_common.c \ + plat/arm/board/arm_fpga/fpga_pm.c \ + plat/arm/board/arm_fpga/fpga_topology.c \ + plat/arm/board/arm_fpga/fpga_console.c \ + plat/arm/board/arm_fpga/fpga_bl31_setup.c \ + ${FPGA_CPU_LIBS} \ + ${FPGA_GIC_SOURCES} + +$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,31)) +$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,31)) + +bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/build_axf.ld + $(ECHO) " LD $@" + $(Q)$(LD) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -o ${BUILD_PLAT}/bl31.axf + +all: bl31.axf diff --git a/plat/arm/board/arm_fpga/rom_trampoline.S b/plat/arm/board/arm_fpga/rom_trampoline.S new file mode 100644 index 000000000..cd66c7927 --- /dev/null +++ b/plat/arm/board/arm_fpga/rom_trampoline.S @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * The Arm Ltd. FPGA images start execution at address 0x0, which is + * mapped at an (emulated) ROM image. The payload uploader can write to + * this memory, but write access by the CPU cores is prohibited. + * + * Provide a simple trampoline to start BL31 execution at the actual + * load address. We put the DTB address in x0, so any code in DRAM could + * make use of that information (not yet used in BL31 right now). + */ + +#include <asm_macros.S> +#include <common/bl_common.ld.h> + +.text +.global _start + +_start: + mov_imm x1, BL31_BASE /* beginning of DRAM */ + mov_imm x0, FPGA_PRELOADED_DTB_BASE + br x1 diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index c71e932a0..66cc3e949 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,136 +8,180 @@ #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 <lib/fconf/fconf.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/arm/common/fconf_nv_cntr_getter.h> +#include <plat/common/common_def.h> #include <plat/common/platform.h> -#include <tools_share/tbbr_oid.h> #include <platform_def.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]; +#if defined(ARM_COT_tbbr) +#include <tools_share/tbbr_oid.h> +#elif defined(ARM_COT_dualroot) +#include <tools_share/dualroot_oid.h> +#endif -/* 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 + +#if COT_DESC_IN_DTB && defined(IMAGE_BL2) +uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS]; +#else +uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = { + TFW_NVCTR_BASE, + NTFW_CTR_BASE +}; +#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"; +extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[]; + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG +static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; #endif +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) /* - * 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]; - /* - * 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; + words = ARM_ROTPK_HASH_LEN >> 2; - /* 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); *flags = ROTPK_IS_HASH; return 0; } +#endif + +#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 + +/* + * Wrapper function for most Arm platforms to get ROTPK hash. + */ +static int 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 */ +} + +#if defined(ARM_COT_tbbr) + +int arm_get_rotpk_info(void *cookie __unused, void **key_ptr, + unsigned int *key_len, unsigned int *flags) +{ + return get_rotpk_info(key_ptr, key_len, flags); +} + +#elif defined(ARM_COT_dualroot) + +int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + /* + * Return the right root of trust key hash based on the cookie value: + * - NULL means the primary ROTPK. + * - Otherwise, interpret cookie as the OID of the certificate + * extension containing the key. + */ + if (cookie == NULL) { + return get_rotpk_info(key_ptr, key_len, flags); + } else if (strcmp(cookie, PROT_PK_OID) == 0) { + extern unsigned char arm_protpk_hash[]; + extern unsigned char arm_protpk_hash_end[]; + *key_ptr = arm_protpk_hash; + *key_len = arm_protpk_hash_end - arm_protpk_hash; + *flags = ROTPK_IS_HASH; + return 0; + } else { + /* Invalid key ID. */ + return 1; + } +} +#endif /* * Return the non-volatile counter value stored in the platform. The cookie @@ -155,9 +199,11 @@ int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) oid = (const char *)cookie; if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE; + nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, + TRUSTED_NV_CTR_ID); } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE; + nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, + NON_TRUSTED_NV_CTR_ID); } else { return 1; } @@ -179,37 +225,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 b98dfd48b..6db0c0031 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,80 @@ 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) + CRYPTO_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) + CRYPTO_ALG=ec + 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 +else + HASH_PREREQUISITES = $(ROT_KEY) +endif + +$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES) +ifndef ROT_KEY + $(error Cannot generate hash: no ROT_KEY defined) +endif + openssl ${CRYPTO_ALG} -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 + +# Allows platform code to provide implementation variants depending on the +# selected chain of trust. +$(eval $(call add_define,ARM_COT_${COT})) + +ifeq (${COT},dualroot) +# Platform Root of Trust key files. +ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_rsa.pem +ARM_PROTPK_HASH := plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin + +# Provide the private key to cert_create tool. It needs it to sign the images. +PROT_KEY := ${ARM_PROT_KEY} + +$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"')) + +BL1_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S +BL2_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S + +$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH) +$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH) +endif + endif diff --git a/plat/arm/board/common/protpk/README b/plat/arm/board/common/protpk/README new file mode 100644 index 000000000..3aca180d2 --- /dev/null +++ b/plat/arm/board/common/protpk/README @@ -0,0 +1,14 @@ +This directory contains some development keys to be used as the platform +root-of-trust key. + +* arm_protprivk_rsa.pem is a 2K RSA private key in PEM format. It has been + generated using the openssl command line tool: + + openssl genrsa 2048 > arm_protprivk_rsa.pem + +* arm_protpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key + associated with the above private key. It has been generated using the openssl + command line tool: + + openssl rsa -in arm_protprivk_rsa.pem -pubout -outform DER | \ + openssl dgst -sha256 -binary > arm_protpk_rsa_sha256.bin diff --git a/plat/arm/board/common/protpk/arm_dev_protpk.S b/plat/arm/board/common/protpk/arm_dev_protpk.S new file mode 100644 index 000000000..2688cbbb1 --- /dev/null +++ b/plat/arm/board/common/protpk/arm_dev_protpk.S @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + .global arm_protpk_hash + .global arm_protpk_hash_end + + .section .rodata.arm_protpk_hash, "a" + +arm_protpk_hash: + /* DER header. */ + .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48 + .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 + /* Key hash. */ + .incbin ARM_PROTPK_HASH +arm_protpk_hash_end: diff --git a/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin new file mode 100644 index 000000000..587da6605 --- /dev/null +++ b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin @@ -0,0 +1 @@ +œó6{W*…`Ÿtíve×·§è£ €¾PžÆK{9
\ No newline at end of file diff --git a/plat/arm/board/common/protpk/arm_protprivk_rsa.pem b/plat/arm/board/common/protpk/arm_protprivk_rsa.pem new file mode 100644 index 000000000..eeaad9e28 --- /dev/null +++ b/plat/arm/board/common/protpk/arm_protprivk_rsa.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzR0h/Z4Up17wfuRlYrUWseGDmlGKpl1PflGiYbyVmI7PwTTp +y/T77EiljGp52suLWntHsc0lee50pW16DU2c5bVfmyofau3GjJ1Yqw5XFAahr6eM +/0mkN8utrevvcRT9CP07D+zdhb/WlRUAnedqr/AUHU8BXS+Bxe8P0Z0Z7+DKjYZp +thzXxsjKM02BFFzNwyVrlyBFDkW/53A4M+dpmuWDjAGCJH88W/u0LdmLcii11IzD +/Ofz8Jxc/ZhqL+9FFK4qU+AJp8yXAnACSB46DlNltJrode0y5tmPhtS37ZF7EFb8 +UZWwZVgtuQyuyz9RYUS6jtiGuq6s8GlRwjTe7wIDAQABAoIBAFoWIYeyln+sQxR4 +W88umfkmgxaUGcFX2kIwuJEUst9+WeERzF24C62LeqphWYOvQlVLMAH3iC41fSXr +H2AYZoC9WHBd386nAD1iHj+C3Nv+zaTIgjTdszKOUonAxjl0bm40SmyELAdCaoyv +3MV9jm4Xk74LpR24b9bvWJNH3MxttH9hiYS+n0IzeTXDfO8GrNvHh92zx+jo8yMm +Khhu+TDC9jA2pHpJcF/0EXxYMhwYiQT16nnHb+xMgS4JpalQhvVK01s4VYGHRoFk +K6xh4TIS336LDLyalrGsPlfNfEdx+DimShDIfBUx9Jp3Pp11TUQUz4rhIHB9WdfG +b6bV4wECgYEA+cgPS2TQ7XQ1RJq1S7OGePtBXvnoH226KwGS6Fey8838tLxbblim +MU+EOYs3O66V6U2YpzmIakXo8030k8thY+jKbZl3l0m/hMuPOG66hfE5i7dYsiP4 +atok5wFiNeNYYjHMEayzk53MhG8EOh36msAO7ohKmenONUBA7pk6yTkCgYEA0jhk +HPshwi+wKkx+JLTnuoEgx40tkRgSF2xBqKssMTasaQmX8qG+w9CEs0R8nZCI70Vc +tXSFcidjdkHUVE2WsygIFuS1tbsAnpaxtn3E6rjie30X/Z280+TV0HjR0EMETmwl +ShC5lZ0oP3LpEZfjbR5qs2kFW4MOxA7tjQVaMWcCgYEA5ZbVMBifzdMl70RA5i9C +qEtSQAl3KgRCvar5rKSHsX+iC0Kiy9+iCusq/3WONEZ6NvMDIJpKYFyYDaOW7o5f +m2TrRChu+1lnN5mfsGBfBCTBH0JMvZlAin6ussLb0eqBX+ijyY8zlLjTttsQSJcr +tThZwTj3UVfOGbZQuL+RgEkCgYBXO3U3nXI9vUIx2zoBC1yZRNoQVGITMlTXiWGZ +lyYoadKTZ5q44Sti4BUguounaoGYIEU/OtHhM70PJnPwY53kS/lHXrKUbbvtEwU9 +f+UFraC1s4wP/rOLjgq3jlsqO5T+4dt7Z4NLNUKtSYazeT6zWgrW1f6WIcUv0C38 +9bqegwKBgFCK3Oa5ibL5sPaPQ/1UfdeW4JVuu6A4JhHS7r+cVLsmcrvE1Qv7Wcvw +B5aqXeqLu2dtIN8/f++3tzccs9LXKY/fh72D4TVjfrqOSSZoGTH9l4U5NXbqWM3I +skkAYb2bMST/d1qSyYesgXVNAlaQHRh3vEz8x853nJ3v9OFj8/rW +-----END RSA PRIVATE KEY----- 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 000000000..80f2192e4 --- /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/corstone700/corstone700_helpers.S b/plat/arm/board/corstone700/common/corstone700_helpers.S index c713f4f1a..c713f4f1a 100644 --- a/plat/arm/board/corstone700/corstone700_helpers.S +++ b/plat/arm/board/corstone700/common/corstone700_helpers.S diff --git a/plat/arm/board/corstone700/corstone700_plat.c b/plat/arm/board/corstone700/common/corstone700_plat.c index cee6fd618..629f076ba 100644 --- a/plat/arm/board/corstone700/corstone700_plat.c +++ b/plat/arm/board/corstone700/common/corstone700_plat.c @@ -1,10 +1,12 @@ /* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <common/bl_common.h> + +#include <mhu.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> #include <platform_def.h> @@ -16,6 +18,7 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, + ARM_MAP_NS_SHARED_RAM, ARM_MAP_NS_DRAM1, CORSTONE700_MAP_DEVICE, {0} @@ -26,9 +29,11 @@ const mmap_region_t plat_arm_mmap[] = { */ void __init plat_arm_pwrc_setup(void) { + mhu_secure_init(); } unsigned int plat_get_syscnt_freq2(void) { - return CORSTONE700_TIMER_BASE_FREQUENCY; + /* Returning the Generic Timer Frequency */ + return SYS_COUNTER_FREQ_IN_TICKS; } diff --git a/plat/arm/board/corstone700/corstone700_pm.c b/plat/arm/board/corstone700/common/corstone700_pm.c index 4884ea519..4884ea519 100644 --- a/plat/arm/board/corstone700/corstone700_pm.c +++ b/plat/arm/board/corstone700/common/corstone700_pm.c diff --git a/plat/arm/board/corstone700/corstone700_security.c b/plat/arm/board/corstone700/common/corstone700_security.c index 39b2fc902..39b2fc902 100644 --- a/plat/arm/board/corstone700/corstone700_security.c +++ b/plat/arm/board/corstone700/common/corstone700_security.c diff --git a/plat/arm/board/corstone700/common/corstone700_stack_protector.c b/plat/arm/board/corstone700/common/corstone700_stack_protector.c new file mode 100644 index 000000000..6fd09da5b --- /dev/null +++ b/plat/arm/board/corstone700/common/corstone700_stack_protector.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include <arch_helpers.h> +#include <plat/common/platform.h> + +static uint32_t plat_generate_random_number(void) +{ + uintptr_t return_addr = (uintptr_t)__builtin_return_address(0U); + uintptr_t frame_addr = (uintptr_t)__builtin_frame_address(0U); + uint64_t cntpct = read_cntpct_el0(); + + /* Generate 32-bit pattern: saving the 2 least significant bytes + * in random_lo and random_hi + */ + uint16_t random_lo = (uint16_t)( + (((uint64_t)return_addr) << 13) ^ frame_addr ^ cntpct + ); + + uint16_t random_hi = (uint16_t)( + (((uint64_t)frame_addr) << 15) ^ return_addr ^ cntpct + ); + + return (((uint32_t)random_hi) << 16) | random_lo; +} + +u_register_t plat_get_stack_protector_canary(void) +{ + return plat_generate_random_number(); /* a 32-bit pattern is returned */ +} diff --git a/plat/arm/board/corstone700/corstone700_topology.c b/plat/arm/board/corstone700/common/corstone700_topology.c index d9445e0c5..904f5ab3a 100644 --- a/plat/arm/board/corstone700/corstone700_topology.c +++ b/plat/arm/board/corstone700/common/corstone700_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,8 +8,8 @@ #include <plat/common/platform.h> /* The Corstone700 power domain tree descriptor */ -static unsigned char corstone700_power_domain_tree_desc - [PLAT_ARM_CLUSTER_COUNT + 2]; +static unsigned char corstone700_power_domain_tree_desc[PLAT_ARM_CLUSTER_COUNT + + 2]; /******************************************************************************* * This function dynamically constructs the topology according to * CLUSTER_COUNT and returns it. diff --git a/plat/arm/board/corstone700/common/drivers/mhu/mhu.c b/plat/arm/board/corstone700/common/drivers/mhu/mhu.c new file mode 100644 index 000000000..2231d1173 --- /dev/null +++ b/plat/arm/board/corstone700/common/drivers/mhu/mhu.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <arch_helpers.h> +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/bakery_lock.h> +#include <lib/mmio.h> + +#include "mhu.h" +#include <plat_arm.h> +#include <platform_def.h> + +ARM_INSTANTIATE_LOCK; + +#pragma weak plat_arm_pwrc_setup + +/* + * Slot 31 is reserved because the MHU hardware uses this register bit to + * indicate a non-secure access attempt. The total number of available slots is + * therefore 31 [30:0]. + */ +#define MHU_MAX_SLOT_ID 30 + +void mhu_secure_message_start(uintptr_t address, unsigned int slot_id) +{ + unsigned int intr_stat_check; + uint64_t timeout_cnt; + volatile uint8_t expiration; + + assert(slot_id <= MHU_MAX_SLOT_ID); + arm_lock_get(); + + /* + * Make sure any previous command has finished + * and polling timeout not expired + */ + + timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); + + do { + intr_stat_check = (mmio_read_32(address + CPU_INTR_S_STAT) & + (1 << slot_id)); + + expiration = timeout_elapsed(timeout_cnt); + + } while ((intr_stat_check != 0U) && (expiration == 0U)); + + /* + * Note: No risk of timer overflows while waiting + * for the timeout expiration. + * According to Armv8 TRM: System counter roll-over + * time of not less than 40 years + */ +} + +void mhu_secure_message_send(uintptr_t address, + unsigned int slot_id, + unsigned int message) +{ + unsigned char access_ready; + uint64_t timeout_cnt; + volatile uint8_t expiration; + + assert(slot_id <= MHU_MAX_SLOT_ID); + assert((mmio_read_32(address + CPU_INTR_S_STAT) & + (1 << slot_id)) == 0U); + + MHU_V2_ACCESS_REQUEST(address); + + timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); + + do { + access_ready = MHU_V2_IS_ACCESS_READY(address); + expiration = timeout_elapsed(timeout_cnt); + + } while ((access_ready == 0U) && (expiration == 0U)); + + /* + * Note: No risk of timer overflows while waiting + * for the timeout expiration. + * According to Armv8 TRM: System counter roll-over + * time of not less than 40 years + */ + + mmio_write_32(address + CPU_INTR_S_SET, message); +} + +void mhu_secure_message_end(uintptr_t address, unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + /* + * Clear any response we got by writing one in the relevant slot bit to + * the CLEAR register + */ + MHU_V2_CLEAR_REQUEST(address); + + arm_lock_release(); +} + +void __init mhu_secure_init(void) +{ + arm_lock_init(); + + /* + * The STAT register resets to zero. Ensure it is in the expected state, + * as a stale or garbage value would make us think it's a message we've + * already sent. + */ + + assert(mmio_read_32(PLAT_SDK700_MHU0_SEND + CPU_INTR_S_STAT) == 0); +} diff --git a/plat/arm/board/corstone700/common/drivers/mhu/mhu.h b/plat/arm/board/corstone700/common/drivers/mhu/mhu.h new file mode 100644 index 000000000..3808746e9 --- /dev/null +++ b/plat/arm/board/corstone700/common/drivers/mhu/mhu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MHU_H +#define MHU_H + +#define MHU_POLL_INTR_STAT_TIMEOUT 50000 /*timeout value in us*/ + +/* CPU MHU secure channel registers */ +#define CPU_INTR_S_STAT 0x00 +#define CPU_INTR_S_SET 0x0C + +/* MHUv2 Control Registers Offsets */ +#define MHU_V2_MSG_CFG_OFFSET 0xF80 +#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 +#define MHU_V2_ACCESS_READY_OFFSET 0xF8C + +#define MHU_V2_ACCESS_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) + +#define MHU_V2_CLEAR_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) + +#define MHU_V2_IS_ACCESS_READY(addr) \ + (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) + +void mhu_secure_message_start(uintptr_t address, unsigned int slot_id); +void mhu_secure_message_send(uintptr_t address, + unsigned int slot_id, + unsigned int message); +void mhu_secure_message_end(uintptr_t address, unsigned int slot_id); +void mhu_secure_init(void); + +#endif /* MHU_H */ diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/common/include/platform_def.h index 8dff3ec3f..57b0551b3 100644 --- a/plat/arm/board/corstone700/include/platform_def.h +++ b/plat/arm/board/corstone700/common/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,18 +11,33 @@ #include <lib/xlat_tables/xlat_tables_defs.h> #include <plat/arm/board/common/v2m_def.h> #include <plat/arm/common/arm_spm_def.h> +#include <plat/arm/common/smccc_def.h> #include <plat/common/common_def.h> +/* PL011 UART related constants */ +#ifdef V2M_IOFPGA_UART0_CLK_IN_HZ +#undef V2M_IOFPGA_UART0_CLK_IN_HZ +#endif + +#ifdef V2M_IOFPGA_UART1_CLK_IN_HZ +#undef V2M_IOFPGA_UART1_CLK_IN_HZ +#endif + +#define V2M_IOFPGA_UART0_CLK_IN_HZ 32000000 +#define V2M_IOFPGA_UART1_CLK_IN_HZ 32000000 + /* Core/Cluster/Thread counts for Corstone700 */ #define CORSTONE700_CLUSTER_COUNT U(1) #define CORSTONE700_MAX_CPUS_PER_CLUSTER U(4) #define CORSTONE700_MAX_PE_PER_CPU U(1) -#define CORSTONE700_CORE_COUNT (CORSTONE700_CLUSTER_COUNT * \ - CORSTONE700_MAX_CPUS_PER_CLUSTER * \ - CORSTONE700_MAX_PE_PER_CPU) -#define PLATFORM_CORE_COUNT CORSTONE700_CORE_COUNT + #define PLAT_ARM_CLUSTER_COUNT CORSTONE700_CLUSTER_COUNT +#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ + CORSTONE700_MAX_CPUS_PER_CLUSTER * \ + CORSTONE700_MAX_PE_PER_CPU) + + /* UART related constants */ #define PLAT_ARM_BOOT_UART_BASE 0x1a510000 #define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ @@ -52,6 +67,9 @@ #define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \ ARM_SHARED_RAM_SIZE) +#define ARM_NS_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE + UL(0x00100000) +#define ARM_NS_SHARED_RAM_SIZE 0x00300000 + /* * SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding * the page reserved for fw_configs) to BL32 @@ -68,31 +86,54 @@ #define ARM_CACHE_WRITEBACK_SHIFT 6 /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space for BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) + +/* + * Boot parameters passed from BL2 to BL31/BL32 are stored here + */ +#define ARM_BL2_MEM_DESC_BASE (ARM_FW_CONFIG_LIMIT) +#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \ + + (PAGE_SIZE / 2U)) + +/* + * Define limit of firmware configuration memory: + * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory + */ +#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2)) /* * The max number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. */ -#define ARM_BL_REGIONS 2 +#define ARM_BL_REGIONS 3 #define PLAT_ARM_MMAP_ENTRIES 8 #define MAX_XLAT_TABLES 5 #define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ ARM_BL_REGIONS) /* GIC related constants */ -#define PLAT_ARM_GICD_BASE 0x1C010000 -#define PLAT_ARM_GICC_BASE 0x1C02F000 +#define PLAT_ARM_GICD_BASE 0x1C010000 +#define PLAT_ARM_GICC_BASE 0x1C02F000 + +/* MHUv2 Secure Channel receiver and sender */ +#define PLAT_SDK700_MHU0_SEND 0x1B800000 +#define PLAT_SDK700_MHU0_RECV 0x1B810000 /* Timer/watchdog related constants */ #define ARM_SYS_CNTCTL_BASE UL(0x1a200000) #define ARM_SYS_CNTREAD_BASE UL(0x1a210000) #define ARM_SYS_TIMCTL_BASE UL(0x1a220000) -#define CORSTONE700_TIMER_BASE_FREQUENCY UL(24000000) + +#ifdef TARGET_PLATFORM_FVP +#define SYS_COUNTER_FREQ_IN_TICKS UL(50000000) /* 50MHz */ +#else +#define SYS_COUNTER_FREQ_IN_TICKS UL(32000000) /* 32MHz */ +#endif + #define CORSTONE700_IRQ_TZ_WDOG 32 #define CORSTONE700_IRQ_SEC_SYS_TIMER 34 @@ -101,49 +142,54 @@ * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The * power levels have a 1:1 mapping with the MPIDR affinity levels. */ -#define ARM_PWR_LVL0 MPIDR_AFFLVL0 -#define ARM_PWR_LVL1 MPIDR_AFFLVL1 -#define ARM_PWR_LVL2 MPIDR_AFFLVL2 +#define ARM_PWR_LVL0 MPIDR_AFFLVL0 +#define ARM_PWR_LVL1 MPIDR_AFFLVL1 +#define ARM_PWR_LVL2 MPIDR_AFFLVL2 /* * Macros for local power states in ARM platforms encoded by State-ID field * within the power-state parameter. */ /* Local power state for power domains in Run state. */ -#define ARM_LOCAL_STATE_RUN U(0) +#define ARM_LOCAL_STATE_RUN U(0) /* Local power state for retention. Valid only for CPU power domains */ -#define ARM_LOCAL_STATE_RET U(1) +#define ARM_LOCAL_STATE_RET U(1) /* Local power state for OFF/power-down. Valid for CPU and cluster * power domains */ -#define ARM_LOCAL_STATE_OFF U(2) +#define ARM_LOCAL_STATE_OFF U(2) -#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE -#define PLAT_ARM_NSTIMER_FRAME_ID U(1) +#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE +#define PLAT_ARM_NSTIMER_FRAME_ID U(1) -#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + UL(0x8000000)) +#define PLAT_ARM_NS_IMAGE_BASE (ARM_NS_SHARED_RAM_BASE) -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) /* * This macro defines the deepest retention state possible. A higher state * ID will represent an invalid or a power down state. */ -#define PLAT_MAX_RET_STATE 1 +#define PLAT_MAX_RET_STATE 1 /* * This macro defines the deepest power down states possible. Any state ID * higher than this is invalid. */ -#define PLAT_MAX_OFF_STATE 2 +#define PLAT_MAX_OFF_STATE 2 -#define PLATFORM_STACK_SIZE UL(0x440) +#define PLATFORM_STACK_SIZE UL(0x440) -#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ +#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ ARM_SHARED_RAM_BASE, \ ARM_SHARED_RAM_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) + MT_MEMORY | MT_RW | MT_SECURE) + +#define ARM_MAP_NS_SHARED_RAM MAP_REGION_FLAT( \ + ARM_NS_SHARED_RAM_BASE, \ + ARM_NS_SHARED_RAM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) #define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \ ARM_NS_DRAM1_BASE, \ @@ -168,23 +214,31 @@ MT_DEVICE | MT_RW | MT_SECURE) #endif +/* + * Map the region for device tree configuration with read and write permissions + */ +#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT(ARM_BL_RAM_BASE, \ + (ARM_FW_CONFIGS_LIMIT \ + - ARM_BL_RAM_BASE), \ + MT_MEMORY | MT_RW | MT_SECURE) + #define CORSTONE700_DEVICE_BASE (0x1A000000) #define CORSTONE700_DEVICE_SIZE (0x26000000) -#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \ - CORSTONE700_DEVICE_BASE, \ - CORSTONE700_DEVICE_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#define ARM_IRQ_SEC_PHY_TIMER 29 - -#define ARM_IRQ_SEC_SGI_0 8 -#define ARM_IRQ_SEC_SGI_1 9 -#define ARM_IRQ_SEC_SGI_2 10 -#define ARM_IRQ_SEC_SGI_3 11 -#define ARM_IRQ_SEC_SGI_4 12 -#define ARM_IRQ_SEC_SGI_5 13 -#define ARM_IRQ_SEC_SGI_6 14 -#define ARM_IRQ_SEC_SGI_7 15 +#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \ + CORSTONE700_DEVICE_BASE,\ + CORSTONE700_DEVICE_SIZE,\ + MT_DEVICE | MT_RW | MT_SECURE) + +#define ARM_IRQ_SEC_PHY_TIMER 29 + +#define ARM_IRQ_SEC_SGI_0 8 +#define ARM_IRQ_SEC_SGI_1 9 +#define ARM_IRQ_SEC_SGI_2 10 +#define ARM_IRQ_SEC_SGI_3 11 +#define ARM_IRQ_SEC_SGI_4 12 +#define ARM_IRQ_SEC_SGI_5 13 +#define ARM_IRQ_SEC_SGI_6 14 +#define ARM_IRQ_SEC_SGI_7 15 /* * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3 @@ -192,7 +246,7 @@ * as Group 0 interrupts. */ #define ARM_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ (grp), GIC_INTR_CFG_LEVEL), \ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ (grp), GIC_INTR_CFG_EDGE), \ @@ -217,11 +271,11 @@ * as Group 0 interrupts. */ #define PLAT_ARM_G1S_IRQ_PROPS(grp) \ - ARM_G1S_IRQ_PROPS(grp), \ - INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, \ - GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \ - GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL) \ + ARM_G1S_IRQ_PROPS(grp), \ + INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL) #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk index bff3589eb..9a8d38c11 100644 --- a/plat/arm/board/corstone700/platform.mk +++ b/plat/arm/board/corstone700/platform.mk @@ -1,9 +1,14 @@ # -# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # +# Making sure the corstone700 platform type is specified +ifeq ($(filter ${TARGET_PLATFORM}, fpga fvp),) + $(error TARGET_PLATFORM must be fpga or fvp) +endif + CORSTONE700_CPU_LIBS += lib/cpus/aarch32/cortex_a32.S BL32_SOURCES += plat/arm/common/aarch32/arm_helpers.S \ @@ -11,34 +16,39 @@ BL32_SOURCES += plat/arm/common/aarch32/arm_helpers.S \ plat/arm/common/arm_common.c \ lib/xlat_tables/aarch32/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ - ${CORSTONE700_CPU_LIBS} + ${CORSTONE700_CPU_LIBS} \ + plat/arm/board/corstone700/common/drivers/mhu/mhu.c -PLAT_INCLUDES := -Iplat/arm/board/corstone700/include +PLAT_INCLUDES := -Iplat/arm/board/corstone700/common/include \ + -Iinclude/plat/arm/common \ + -Iplat/arm/board/corstone700/common/drivers/mhu NEED_BL32 := yes -CORSTONE700_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 \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +CORSTONE700_GIC_SOURCES := ${GICV2_SOURCES} \ + plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c # BL1/BL2 Image not a part of the capsule Image for Corstone700 override NEED_BL1 := no override NEED_BL2 := no override NEED_BL2U := no +override NEED_BL33 := yes #TFA for Corstone700 starts from BL32 override RESET_TO_SP_MIN := 1 #Device tree -CORSTONE700_HW_CONFIG_DTS := fdts/corstone700.dts -CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb +CORSTONE700_HW_CONFIG_DTS := fdts/corstone700_${TARGET_PLATFORM}.dts +CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/fdts/corstone700_${TARGET_PLATFORM}.dtb FDT_SOURCES += ${CORSTONE700_HW_CONFIG_DTS} $(eval CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(CORSTONE700_HW_CONFIG_DTS))) # Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${CORSTONE700_HW_CONFIG},--hw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${CORSTONE700_HW_CONFIG},--hw-config,${CORSTONE700_HW_CONFIG})) # Check for Linux kernel as a BL33 image by default $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33)) @@ -46,4 +56,8 @@ $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33)) $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.") endif $(eval $(call add_define,ARM_PRELOADED_DTB_BASE)) + +# Adding TARGET_PLATFORM as a GCC define (-D option) +$(eval $(call add_define,TARGET_PLATFORM_$(call uppercase,${TARGET_PLATFORM}))) + include plat/arm/board/common/board_common.mk diff --git a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk index 57e1ec3e4..75dc0f10c 100644 --- a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk +++ b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -7,12 +7,18 @@ # SP_MIN source files specific to FVP platform BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ - plat/arm/board/corstone700/corstone700_helpers.S \ - plat/arm/board/corstone700/corstone700_topology.c \ - plat/arm/board/corstone700/corstone700_security.c \ - plat/arm/board/corstone700/corstone700_plat.c \ - plat/arm/board/corstone700/corstone700_pm.c \ + plat/arm/board/corstone700/common/corstone700_helpers.S \ + plat/arm/board/corstone700/common/corstone700_topology.c \ + plat/arm/board/corstone700/common/corstone700_security.c \ + plat/arm/board/corstone700/common/corstone700_plat.c \ + plat/arm/board/corstone700/common/corstone700_pm.c \ plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c \ ${CORSTONE700_GIC_SOURCES} +ifneq (${ENABLE_STACK_PROTECTOR},0) + ifneq (${ENABLE_STACK_PROTECTOR},none) + BL32_SOURCES += plat/arm/board/corstone700/common/corstone700_stack_protector.c + endif +endif + include plat/arm/common/sp_min/arm_sp_min.mk diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c new file mode 100644 index 000000000..35a777b6f --- /dev/null +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <fconf_hw_config_getter.h> +#include <libfdt.h> +#include <plat/common/platform.h> + +struct gicv3_config_t gicv3_config; +struct hw_topology_t soc_topology; +struct uart_serial_config_t uart_serial_config; +struct cpu_timer_t cpu_timer; + +#define ILLEGAL_ADDR ULL(~0) + +int fconf_populate_gicv3_config(uintptr_t config) +{ + int err; + int node; + uintptr_t addr; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* + * Find the offset of the node containing "arm,gic-v3" compatible property. + * Populating fconf strucutures dynamically is not supported for legacy + * systems which use GICv2 IP. Simply skip extracting GIC properties. + */ + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,gic-v3"); + if (node < 0) { + WARN("FCONF: Unable to locate node with arm,gic-v3 compatible property\n"); + return 0; + } + /* The GICv3 DT binding holds at least two address/size pairs, + * the first describing the distributor, the second the redistributors. + * See: bindings/interrupt-controller/arm,gic-v3.yaml + */ + err = fdt_get_reg_props_by_index(hw_config_dtb, node, 0, &addr, NULL); + if (err < 0) { + ERROR("FCONF: Failed to read GICD reg property of GIC node\n"); + return err; + } + gicv3_config.gicd_base = addr; + + err = fdt_get_reg_props_by_index(hw_config_dtb, node, 1, &addr, NULL); + if (err < 0) { + ERROR("FCONF: Failed to read GICR reg property of GIC node\n"); + } else { + gicv3_config.gicr_base = addr; + } + + return err; +} + +int fconf_populate_topology(uintptr_t config) +{ + int err, node, cluster_node, core_node, thread_node; + uint32_t cluster_count = 0, max_cpu_per_cluster = 0, total_cpu_count = 0; + uint32_t max_pwr_lvl = 0; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* Find the offset of the node containing "arm,psci-1.0" compatible property */ + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,psci-1.0"); + if (node < 0) { + ERROR("FCONF: Unable to locate node with arm,psci-1.0 compatible property\n"); + return node; + } + + err = fdt_read_uint32(hw_config_dtb, node, "max-pwr-lvl", &max_pwr_lvl); + if (err < 0) { + /* + * Some legacy FVP dts may not have this property. Assign the default + * value. + */ + WARN("FCONF: Could not locate max-pwr-lvl property\n"); + max_pwr_lvl = 2; + } + + assert(max_pwr_lvl <= MPIDR_AFFLVL2); + + /* Find the offset of the "cpus" node */ + node = fdt_path_offset(hw_config_dtb, "/cpus"); + if (node < 0) { + ERROR("FCONF: Node '%s' not found in hardware configuration dtb\n", "cpus"); + return node; + } + + /* A typical cpu-map node in a device tree is shown here for reference + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU2>; + }; + core1 { + cpu = <&CPU3>; + }; + }; + }; + */ + + /* Locate the cpu-map child node */ + node = fdt_subnode_offset(hw_config_dtb, node, "cpu-map"); + if (node < 0) { + ERROR("FCONF: Node '%s' not found in hardware configuration dtb\n", "cpu-map"); + return node; + } + + uint32_t cpus_per_cluster[PLAT_ARM_CLUSTER_COUNT] = {0}; + + /* Iterate through cluster nodes */ + fdt_for_each_subnode(cluster_node, hw_config_dtb, node) { + assert(cluster_count < PLAT_ARM_CLUSTER_COUNT); + + /* Iterate through core nodes */ + fdt_for_each_subnode(core_node, hw_config_dtb, cluster_node) { + /* core nodes may have child nodes i.e., "thread" nodes */ + if (fdt_first_subnode(hw_config_dtb, core_node) < 0) { + cpus_per_cluster[cluster_count]++; + } else { + /* Multi-threaded CPU description is found in dtb */ + fdt_for_each_subnode(thread_node, hw_config_dtb, core_node) { + cpus_per_cluster[cluster_count]++; + } + + /* Since in some dtbs, core nodes may not have thread node, + * no need to error if even one child node is not found. + */ + } + } + + /* Ensure every cluster node has at least 1 child node */ + if (cpus_per_cluster[cluster_count] < 1U) { + ERROR("FCONF: Unable to locate the core node in cluster %d\n", cluster_count); + return -1; + } + + VERBOSE("CLUSTER ID: %d cpu-count: %d\n", cluster_count, + cpus_per_cluster[cluster_count]); + + /* Find the maximum number of cpus in any cluster */ + max_cpu_per_cluster = MAX(max_cpu_per_cluster, cpus_per_cluster[cluster_count]); + total_cpu_count += cpus_per_cluster[cluster_count]; + cluster_count++; + } + + + /* At least one cluster node is expected in hardware configuration dtb */ + if (cluster_count < 1U) { + ERROR("FCONF: Unable to locate the cluster node in cpu-map node\n"); + return -1; + } + + soc_topology.plat_max_pwr_level = max_pwr_lvl; + soc_topology.plat_cluster_count = cluster_count; + soc_topology.cluster_cpu_count = max_cpu_per_cluster; + soc_topology.plat_cpu_count = total_cpu_count; + + return 0; +} + +int fconf_populate_uart_config(uintptr_t config) +{ + int uart_node, node, err; + uintptr_t addr; + const char *path; + uint32_t phandle; + uint64_t translated_addr; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* + * uart child node is indirectly referenced through its path which is + * specified in the `serial1` property of the "aliases" node. + * Note that TF-A boot console is mapped to serial0 while runtime + * console is mapped to serial1. + */ + + path = fdt_get_alias(hw_config_dtb, "serial1"); + if (path == NULL) { + ERROR("FCONF: Could not read serial1 property in aliases node\n"); + return -1; + } + + /* Find the offset of the uart serial node */ + uart_node = fdt_path_offset(hw_config_dtb, path); + if (uart_node < 0) { + ERROR("FCONF: Failed to locate uart serial node using its path\n"); + return -1; + } + + /* uart serial node has its offset and size of address in reg property */ + err = fdt_get_reg_props_by_index(hw_config_dtb, uart_node, 0, &addr, + NULL); + if (err < 0) { + ERROR("FCONF: Failed to read reg property of '%s' node\n", + "uart serial"); + return err; + } + VERBOSE("FCONF: UART node address: %lx\n", addr); + + /* + * Perform address translation of local device address to CPU address + * domain. + */ + translated_addr = fdtw_translate_address(hw_config_dtb, + uart_node, (uint64_t)addr); + if (translated_addr == ILLEGAL_ADDR) { + ERROR("FCONF: failed to translate UART node base address"); + return -1; + } + + uart_serial_config.uart_base = translated_addr; + + VERBOSE("FCONF: UART serial device base address: %llx\n", + uart_serial_config.uart_base); + + /* + * The phandle of the DT node which captures the clock info of uart + * serial node is specified in the "clocks" property. + */ + err = fdt_read_uint32(hw_config_dtb, uart_node, "clocks", &phandle); + if (err < 0) { + ERROR("FCONF: Could not read clocks property in uart serial node\n"); + return err; + } + + node = fdt_node_offset_by_phandle(hw_config_dtb, phandle); + if (node < 0) { + ERROR("FCONF: Failed to locate clk node using its path\n"); + return node; + } + + /* + * Retrieve clock frequency. We assume clock provider generates a fixed + * clock. + */ + err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency", + &uart_serial_config.uart_clk); + if (err < 0) { + ERROR("FCONF: Could not read clock-frequency property in clk node\n"); + return err; + } + + VERBOSE("FCONF: UART serial device clk frequency: %x\n", + uart_serial_config.uart_clk); + + return 0; +} + +int fconf_populate_cpu_timer(uintptr_t config) +{ + int err, node; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* Find the node offset point to "arm,armv8-timer" compatible property, + * a per-core architected timer attached to a GIC to deliver its per-processor + * interrupts via PPIs */ + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,armv8-timer"); + if (node < 0) { + ERROR("FCONF: Unrecognized hardware configuration dtb (%d)\n", node); + return node; + } + + /* Locate the cell holding the clock-frequency, an optional field */ + err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency", &cpu_timer.clock_freq); + if (err < 0) { + WARN("FCONF failed to read clock-frequency property\n"); + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config); +FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); +FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config); +FCONF_REGISTER_POPULATOR(HW_CONFIG, cpu_timer, fconf_populate_cpu_timer); diff --git a/plat/arm/board/fvp/fconf/fconf_nt_config_getter.c b/plat/arm/board/fvp/fconf/fconf_nt_config_getter.c new file mode 100644 index 000000000..e25801520 --- /dev/null +++ b/plat/arm/board/fvp/fconf/fconf_nt_config_getter.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <common/fdt_wrappers.h> + +#include <libfdt.h> +#include <fconf_nt_config_getter.h> + +#include <plat/common/platform.h> + +struct event_log_config_t event_log_config; + +int fconf_populate_event_log_config(uintptr_t config) +{ + int err; + int node; + + /* Necessary to work with libfdt APIs */ + const void *dtb = (const void *)config; + + /* + * Find the offset of the node containing "arm,tpm_event_log" + * compatible property + */ + const char *compatible_str = "arm,tpm_event_log"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find '%s' compatible in dtb\n", + compatible_str); + return node; + } + + /* Retrieve Event Log details from the DTB */ +#ifdef SPD_opteed + err = fdtw_read_cells(dtb, node, "tpm_event_log_sm_addr", 2, + &event_log_config.tpm_event_log_sm_addr); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'tpm_event_log_sm_addr'\n"); + return err; + } +#endif + err = fdtw_read_cells(dtb, node, + "tpm_event_log_addr", 2, &event_log_config.tpm_event_log_addr); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'tpm_event_log_addr'\n"); + return err; + } + + err = fdtw_read_cells(dtb, node, + "tpm_event_log_size", 1, &event_log_config.tpm_event_log_size); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'tpm_event_log_size'\n"); + } + + return err; +} + +FCONF_REGISTER_POPULATOR(NT_CONFIG, event_log_config, + fconf_populate_event_log_config); diff --git a/plat/arm/board/fvp/fdts/event_log.dtsi b/plat/arm/board/fvp/fdts/event_log.dtsi new file mode 100644 index 000000000..47af672df --- /dev/null +++ b/plat/arm/board/fvp/fdts/event_log.dtsi @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* TPM Event Log Config */ +event_log: tpm_event_log { + compatible = "arm,tpm_event_log"; + tpm_event_log_addr = <0x0 0x0>; + tpm_event_log_size = <0x0>; +}; diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts new file mode 100644 index 000000000..9fb566b1e --- /dev/null +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x1800>; + id = <TB_FW_CONFIG_ID>; + }; + + hw-config { + load-address = <0x0 0x82000000>; + max-size = <0x01000000>; + id = <HW_CONFIG_ID>; + }; + + /* + * Load SoC and TOS firmware configs at the base of + * non shared SRAM. The runtime checks ensure we don't + * overlap BL2, BL31 or BL32. The NT firmware config + * is loaded at base of DRAM. + */ + soc_fw-config { + load-address = <0x0 0x04001300>; + max-size = <0x200>; + id = <SOC_FW_CONFIG_ID>; + }; + + tos_fw-config { + load-address = <0x0 0x04001500>; + max-size = <0xB00>; + id = <TOS_FW_CONFIG_ID>; + }; + + nt_fw-config { + load-address = <0x0 0x80000000>; + max-size = <0x200>; + id = <NT_FW_CONFIG_ID>; + }; + }; +}; diff --git a/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts index 7ab980b1b..8f32b9880 100644 --- a/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_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 */ @@ -7,5 +7,13 @@ /dts-v1/; / { +#if MEASURED_BOOT +#include "event_log.dtsi" +#endif +}; +#if MEASURED_BOOT && defined(SPD_opteed) +&event_log { + tpm_event_log_sm_addr = <0x0 0x0>; }; +#endif diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts new file mode 100644 index 000000000..f4805db69 --- /dev/null +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/dts-v1/; + +#define AFF 00 + +#include "fvp-defs.dtsi" +#undef POST +#define POST \ + }; + +/ { + compatible = "arm,ffa-core-manifest-1.0"; + #address-cells = <2>; + #size-cells = <1>; + + attribute { + spmc_id = <0x8000>; + maj_ver = <0x1>; + min_ver = <0x0>; + exec_state = <0x0>; + load_address = <0x0 0x6000000>; + entrypoint = <0x0 0x6000000>; + binary_size = <0x80000>; + }; + + hypervisor { + compatible = "hafnium,hafnium"; + vm1 { + is_ffa_partition; + debug_name = "cactus-primary"; + load_address = <0x7000000>; + vcpu_count = <8>; + mem_size = <1048576>; + }; + vm2 { + is_ffa_partition; + debug_name = "cactus-secondary"; + load_address = <0x7100000>; + vcpu_count = <8>; + mem_size = <1048576>; + }; + vm3 { + is_ffa_partition; + debug_name = "cactus-tertiary"; + load_address = <0x7200000>; + vcpu_count = <8>; + mem_size = <1048576>; + }; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + CPU_0 + + /* + * SPMC (Hafnium) requires secondary core nodes are declared + * in descending order. + */ + CPU_7 + CPU_6 + CPU_5 + CPU_4 + CPU_3 + CPU_2 + CPU_1 + }; + + memory@6000000 { + device_type = "memory"; + reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */ + }; +}; diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts new file mode 100644 index 000000000..57d6792e1 --- /dev/null +++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/dts-v1/; + +#define AFF 00 + +#include "fvp-defs.dtsi" +#undef POST +#define POST \ + }; + +/ { + compatible = "arm,ffa-core-manifest-1.0"; + #address-cells = <2>; + #size-cells = <1>; + + attribute { + spmc_id = <0x8000>; + maj_ver = <0x1>; + min_ver = <0x0>; + exec_state = <0x0>; + load_address = <0x0 0x6000000>; + entrypoint = <0x0 0x6000000>; + binary_size = <0x80000>; + }; + + hypervisor { + compatible = "hafnium,hafnium"; + vm1 { + is_ffa_partition; + debug_name = "op-tee"; + load_address = <0x6280000>; + smc_whitelist = <0xbe000000>; + vcpu_count = <8>; + mem_size = <1048576>; + }; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + CPU_0 + + /* + * SPMC (Hafnium) requires secondary core nodes are declared + * in descending order. + */ + CPU_7 + CPU_6 + CPU_5 + CPU_4 + CPU_3 + CPU_2 + CPU_1 + }; + + memory@6000000 { + device_type = "memory"; + reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */ + }; +}; diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts index ce589385c..fe154e970 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,25 +7,12 @@ /dts-v1/; / { - /* Platform Config */ - plat_arm_bl2 { + tb_fw-config { compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x82000000>; - hw_config_max_size = <0x01000000>; + /* Disable authentication for development */ disable_auth = <0x0>; - /* - * Load SoC and TOS firmware configs at the base of - * non shared SRAM. The runtime checks ensure we don't - * overlap BL2, BL31 or BL32. The NT firmware config - * is loaded at base of DRAM. - */ - soc_fw_config_addr = <0x0 0x04001000>; - soc_fw_config_max_size = <0x200>; - tos_fw_config_addr = <0x0 0x04001200>; - tos_fw_config_max_size = <0x200>; - nt_fw_config_addr = <0x0 0x80000000>; - nt_fw_config_max_size = <0x200>; + /* * The following two entries are placeholders for Mbed TLS * heap information. The default values don't matter since @@ -37,5 +24,96 @@ */ mbedtls_heap_addr = <0x0 0x0>; mbedtls_heap_size = <0x0>; + +#if MEASURED_BOOT + /* BL2 image hash calculated by BL1 */ + bl2_hash_data = [ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +#if BL2_HASH_SIZE > 32 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +#if BL2_HASH_SIZE > 48 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +#endif /* > 48 */ +#endif /* > 32 */ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]; +#endif /* MEASURED_BOOT */ + }; + + /* + * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in + * network order (big endian) + */ + +#if ARM_IO_IN_DTB + arm-io_policies { + fip-handles { + compatible = "arm,io-fip-handle"; + scp_bl2_uuid = <0x9766fd3d 0x89bee849 0xae5d78a1 0x40608213>; + bl31_uuid = <0x47d4086d 0x4cfe9846 0x9b952950 0xcbbd5a00>; + bl32_uuid = <0x05d0e189 0x53dc1347 0x8d2b500a 0x4b7a3e38>; + bl32_extra1_uuid = <0x0b70c28b 0x2a5a7840 0x9f650a56 0x82738288>; + bl32_extra2_uuid = <0x8ea87bb1 0xcfa23f4d 0x85fde7bb 0xa50220d9>; + bl33_uuid = <0xd6d0eea7 0xfcead54b 0x97829934 0xf234b6e4>; + hw_cfg_uuid = <0x08b8f1d9 0xc9cf9349 0xa9626fbc 0x6b7265cc>; + soc_fw_cfg_uuid = <0x9979814b 0x0376fb46 0x8c8e8d26 0x7f7859e0>; + tos_fw_cfg_uuid = <0x26257c1a 0xdbc67f47 0x8d96c4c4 0xb0248021>; + nt_fw_cfg_uuid = <0x28da9815 0x93e87e44 0xac661aaf 0x801550f9>; + t_key_cert_uuid = <0x827ee890 0xf860e411 0xa1b477a7 0x21b4f94c>; + scp_fw_key_uuid = <0x024221a1 0xf860e411 0x8d9bf33c 0x0e15a014>; + soc_fw_key_uuid = <0x8ab8becc 0xf960e411 0x9ad0eb48 0x22d8dcf8>; + tos_fw_key_cert_uuid = <0x9477d603 0xfb60e411 0x85ddb710 0x5b8cee04>; + nt_fw_key_cert_uuid = <0x8ad5832a 0xfb60e411 0x8aafdf30 0xbbc49859>; + scp_fw_content_cert_uuid = <0x44be6f04 0x5e63e411 0xb28b73d8 0xeaae9656>; + soc_fw_content_cert_uuid = <0xe2b20c20 0x5e63e411 0x9ce8abcc 0xf92bb666>; + tos_fw_content_cert_uuid = <0xa49f4411 0x5e63e411 0x87283f05 0x722af33d>; + nt_fw_content_cert_uuid = <0x8ec4c1f3 0x5d63e411 0xa7a987ee 0x40b23fa7>; + sp_content_cert_uuid = <0x776dfd44 0x86974c3b 0x91ebc13e 0x025a2a6f>; + }; + }; +#endif /* ARM_IO_IN_DTB */ + + secure-partitions { + compatible = "arm,sp"; +#ifdef OPTEE_SP_FW_CONFIG + op-tee { + uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>; + load-address = <0x6280000>; + }; +#else + cactus-primary { + uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>; + load-address = <0x7000000>; + owner = "SiP"; + }; + + cactus-secondary { + uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>; + load-address = <0x7100000>; + owner = "Plat"; + }; + + cactus-tertiary { + uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>; + load-address = <0x7200000>; + }; +#endif }; + +#if COT_DESC_IN_DTB + #include "cot_descriptors.dtsi" +#endif + +}; + +#if COT_DESC_IN_DTB + +#include "../fvp_def.h" + +&trusted_nv_counter { + reg = <TFW_NVCTR_BASE>; +}; + +&non_trusted_nv_counter { + reg = <NTFW_CTR_BASE>; }; +#endif diff --git a/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts index 7ab980b1b..7bed6cb3b 100644 --- a/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tsp_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 */ @@ -7,5 +7,7 @@ /dts-v1/; / { - +#if MEASURED_BOOT +#include "event_log.dtsi" +#endif }; diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts new file mode 100644 index 000000000..928d0d3bf --- /dev/null +++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP) + * that has additional optional properties defined. + * + */ + +/dts-v1/; + +/ { + compatible = "arm,ffa-manifest-1.0"; + + /* Properties */ + description = "op-tee"; + ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */ + uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>; + id = <1>; + execution-ctx-count = <8>; + exception-level = <2>; /* S-EL1 */ + execution-state = <0>; /* AARCH64 */ + load-address = <0x6280000>; + entrypoint-offset = <0x1000>; + xlat-granule = <0>; /* 4KiB */ + boot-order = <0>; + messaging-method = <0>; /* Direct messaging only */ + run-time-model = <1>; /* Run to completion */ + + /* Boot protocol */ + gp-register-num = <0x0>; + + device-regions { + compatible = "arm,ffa-manifest-device-regions"; + + uart1 { + base-address = <0x00000000 0x1c0a0000>; + pages-count = <1>; + attributes = <0x3>; /* read-write */ + }; + + gicd { + base-address = <0x00000000 0x2f000000>; + pages-count = <16>; + attributes = <0x3>; /* read-write */ + }; + }; +}; diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c index 8f6170daa..e713bbc44 100644 --- a/plat/arm/board/fvp/fvp_bl1_setup.c +++ b/plat/arm/board/fvp/fvp_bl1_setup.c @@ -1,9 +1,12 @@ /* - * 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 */ +#include <assert.h> + +#include <bl1/bl1.h> #include <common/tbbr/tbbr_img_def.h> #include <drivers/arm/smmu_v3.h> #include <drivers/arm/sp805.h> @@ -61,6 +64,63 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) /* Setup the watchdog to reset the system as soon as possible */ sp805_refresh(ARM_SP805_TWDG_BASE, 1U); - while (1) + while (true) wfi(); } + +#if MEASURED_BOOT +/* + * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. + */ +void bl1_plat_set_bl2_hash(const image_desc_t *image_desc) +{ + arm_bl1_set_bl2_hash(image_desc); +} + +/* + * Implementation for bl1_plat_handle_post_image_load(). This function + * populates the default arguments to BL2. The BL2 memory layout structure + * is allocated and the calculated layout is populated in arg1 to BL2. + */ +int bl1_plat_handle_post_image_load(unsigned int image_id) +{ + meminfo_t *bl2_tzram_layout; + meminfo_t *bl1_tzram_layout; + image_desc_t *image_desc; + entry_point_info_t *ep_info; + + if (image_id != BL2_IMAGE_ID) { + return 0; + } + + /* Get the image descriptor */ + image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(image_desc != NULL); + + /* Calculate BL2 hash and set it in TB_FW_CONFIG */ + bl1_plat_set_bl2_hash(image_desc); + + /* Get the entry point info */ + ep_info = &image_desc->ep_info; + + /* Find out how much free trusted ram remains after BL1 load */ + bl1_tzram_layout = bl1_plat_sec_mem_layout(); + + /* + * Create a new layout of memory for BL2 as seen by BL1 i.e. + * tell it the amount of total and free memory available. + * This layout is created at the first free address visible + * to BL2. BL2 will read the memory layout before using its + * memory for other purposes. + */ + bl2_tzram_layout = (meminfo_t *)bl1_tzram_layout->total_base; + + bl1_calc_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout); + + ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout; + + VERBOSE("BL1: BL2 memory layout address = %p\n", + (void *)bl2_tzram_layout); + return 0; +} +#endif /* MEASURED_BOOT */ diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index 89636d18a..f2f21432d 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -1,12 +1,20 @@ /* - * 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 */ +#include <assert.h> + +#include <common/debug.h> +#include <common/desc_image_load.h> #include <drivers/arm/sp804_delay_timer.h> -#include <drivers/generic_delay_timer.h> -#include <lib/mmio.h> +#if MEASURED_BOOT +#include <drivers/measured_boot/measured_boot.h> +#endif +#include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> + #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> #include <platform_def.h> @@ -28,3 +36,82 @@ void bl2_platform_setup(void) /* Initialize System level generic or SP804 timer */ fvp_timer_init(); } + +/******************************************************************************* + * This function returns the list of executable images + ******************************************************************************/ +struct bl_params *plat_get_next_bl_params(void) +{ + struct bl_params *arm_bl_params; + + arm_bl_params = arm_get_next_bl_params(); + +#if __aarch64__ && !BL2_AT_EL3 + const struct dyn_cfg_dtb_info_t *fw_config_info; + bl_mem_params_node_t *param_node; + uintptr_t fw_config_base = 0U; + entry_point_info_t *ep_info; + + /* Get BL31 image node */ + param_node = get_bl_mem_params_node(BL31_IMAGE_ID); + assert(param_node != NULL); + + /* get fw_config load address */ + fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); + assert(fw_config_info != NULL); + + fw_config_base = fw_config_info->config_addr; + assert(fw_config_base != 0U); + + /* + * Get the entry point info of BL31 image and override + * arg1 of entry point info with fw_config base address + */ + ep_info = ¶m_node->ep_info; + ep_info->args.arg1 = (uint32_t)fw_config_base; +#endif /* __aarch64__ && !BL2_AT_EL3 */ + + return arm_bl_params; +} +#if MEASURED_BOOT +static int fvp_bl2_plat_handle_post_image_load(unsigned int image_id) +{ + const bl_mem_params_node_t *bl_mem_params = + get_bl_mem_params_node(image_id); + + assert(bl_mem_params != NULL); + + image_info_t info = bl_mem_params->image_info; + int err; + + if ((info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U) { + /* Calculate image hash and record data in Event Log */ + err = tpm_record_measurement(info.image_base, + info.image_size, image_id); + if (err != 0) { + ERROR("%s%s image id %u (%i)\n", + "BL2: Failed to ", "record", image_id, err); + return err; + } + } + + err = arm_bl2_handle_post_image_load(image_id); + if (err != 0) { + ERROR("%s%s image id %u (%i)\n", + "BL2: Failed to ", "handle", image_id, err); + } + + return err; +} + +int arm_bl2_plat_handle_post_image_load(unsigned int image_id) +{ + int err = fvp_bl2_plat_handle_post_image_load(image_id); + + if (err != 0) { + ERROR("%s() returns %i\n", __func__, err); + } + + return err; +} +#endif /* MEASURED_BOOT */ diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index 8627c5ef0..f9ee4492f 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -1,10 +1,16 @@ /* - * 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 */ +#include <assert.h> +#include <common/debug.h> #include <drivers/arm/smmu_v3.h> +#include <fconf_hw_config_getter.h> +#include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> +#include <lib/mmio.h> #include <plat/arm/common/arm_config.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> @@ -14,6 +20,19 @@ void __init bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { +#if !RESET_TO_BL31 && !BL2_AT_EL3 + const struct dyn_cfg_dtb_info_t *soc_fw_config_info; + + INFO("BL31 FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1); + /* Fill the properties struct with the info from the config dtb */ + fconf_populate("FW_CONFIG", arg1); + + soc_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, SOC_FW_CONFIG_ID); + if (soc_fw_config_info != NULL) { + arg1 = soc_fw_config_info->config_addr; + } +#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */ + arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); /* Initialize the platform config for future decision making */ @@ -41,3 +60,46 @@ void __init bl31_early_platform_setup2(u_register_t arg0, if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) smmuv3_init(PLAT_FVP_SMMUV3_BASE); } + +void __init bl31_plat_arch_setup(void) +{ + arm_bl31_plat_arch_setup(); + + /* + * For RESET_TO_BL31 systems, BL31 is the first bootloader to run. + * So there is no BL2 to load the HW_CONFIG dtb into memory before + * control is passed to BL31. + */ +#if !RESET_TO_BL31 && !BL2_AT_EL3 + /* HW_CONFIG was also loaded by BL2 */ + const struct dyn_cfg_dtb_info_t *hw_config_info; + + hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID); + assert(hw_config_info != NULL); + + fconf_populate("HW_CONFIG", hw_config_info->config_addr); +#endif +} + +unsigned int plat_get_syscnt_freq2(void) +{ + unsigned int counter_base_frequency; + +#if !RESET_TO_BL31 && !BL2_AT_EL3 + /* Get the frequency through FCONF API for HW_CONFIG */ + counter_base_frequency = FCONF_GET_PROPERTY(hw_config, cpu_timer, clock_freq); + if (counter_base_frequency > 0U) { + return counter_base_frequency; + } +#endif + + /* Read the frequency from Frequency modes table */ + counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF); + + /* The first entry of the frequency modes table must not be 0 */ + if (counter_base_frequency == 0U) { + panic(); + } + + return counter_base_frequency; +} diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index ffaa93de4..52686faca 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,12 +13,17 @@ #include <drivers/arm/sp804_delay_timer.h> #include <drivers/generic_delay_timer.h> #include <lib/mmio.h> +#include <lib/smccc.h> #include <lib/xlat_tables/xlat_tables_compat.h> +#include <platform_def.h> +#include <services/arm_arch_svc.h> +#if SPM_MM +#include <services/spm_mm_partition.h> +#endif + #include <plat/arm/common/arm_config.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> -#include <platform_def.h> -#include <services/spm_mm_partition.h> #include "fvp_private.h" @@ -43,6 +48,18 @@ arm_config_t arm_config; DEVICE1_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) +#if FVP_GICR_REGION_PROTECTION +#define MAP_GICD_MEM MAP_REGION_FLAT(BASE_GICD_BASE, \ + BASE_GICD_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* Map all core's redistributor memory as read-only. After boots up, + * per-core map its redistributor memory as read-write */ +#define MAP_GICR_MEM MAP_REGION_FLAT(BASE_GICR_BASE, \ + (BASE_GICR_SIZE * PLATFORM_CORE_COUNT),\ + MT_DEVICE | MT_RO | MT_SECURE) +#endif /* FVP_GICR_REGION_PROTECTION */ + /* * Need to be mapped with write permissions in order to set a new non-volatile * counter value. @@ -65,7 +82,9 @@ const mmap_region_t plat_arm_mmap[] = { V2M_MAP_FLASH0_RW, V2M_MAP_IOFPGA, MAP_DEVICE0, +#if FVP_INTERCONNECT_DRIVER == FVP_CCN MAP_DEVICE1, +#endif #if TRUSTED_BOARD_BOOT /* To access the Root of Trust Public Key registers. */ MAP_DEVICE2, @@ -81,11 +100,16 @@ const mmap_region_t plat_arm_mmap[] = { V2M_MAP_FLASH0_RW, V2M_MAP_IOFPGA, MAP_DEVICE0, +#if FVP_INTERCONNECT_DRIVER == FVP_CCN MAP_DEVICE1, +#endif ARM_MAP_NS_DRAM1, #ifdef __aarch64__ ARM_MAP_DRAM2, #endif +#if defined(SPD_spmd) + ARM_MAP_TRUSTED_DRAM, +#endif #ifdef SPD_tspd ARM_MAP_TSP_SEC_MEM, #endif @@ -126,11 +150,18 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_EL3_TZC_DRAM, V2M_MAP_IOFPGA, MAP_DEVICE0, +#if FVP_GICR_REGION_PROTECTION + MAP_GICD_MEM, + MAP_GICR_MEM, +#else MAP_DEVICE1, +#endif /* FVP_GICR_REGION_PROTECTION */ ARM_V2M_MAP_MEM_PROTECT, #if SPM_MM ARM_SPM_BUF_EL3_MMAP, #endif + /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */ + ARM_DTB_DRAM_NS, {0} }; @@ -157,6 +188,8 @@ const mmap_region_t plat_arm_mmap[] = { V2M_MAP_IOFPGA, MAP_DEVICE0, MAP_DEVICE1, + /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */ + ARM_DTB_DRAM_NS, {0} }; #endif @@ -410,7 +443,7 @@ int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) void fvp_timer_init(void) { -#if FVP_USE_SP804_TIMER +#if USE_SP804_TIMER /* Enable the clock override for SP804 timer 0, which means that no * clock dividers are applied and the raw (35MHz) clock will be used. */ @@ -425,5 +458,42 @@ void fvp_timer_init(void) /* Enable System level generic timer */ mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0U) | CNTCR_EN); -#endif /* FVP_USE_SP804_TIMER */ +#endif /* USE_SP804_TIMER */ +} + +/***************************************************************************** + * plat_is_smccc_feature_available() - This function checks whether SMCCC + * feature is availabile for platform. + * @fid: SMCCC function id + * + * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and + * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. + *****************************************************************************/ +int32_t plat_is_smccc_feature_available(u_register_t fid) +{ + switch (fid) { + case SMCCC_ARCH_SOC_ID: + return SMC_ARCH_CALL_SUCCESS; + default: + return SMC_ARCH_CALL_NOT_SUPPORTED; + } +} + +/* Get SOC version */ +int32_t plat_get_soc_version(void) +{ + return (int32_t) + ((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT) + | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT) + | FVP_SOC_ID); +} + +/* Get SOC revision */ +int32_t plat_get_soc_revision(void) +{ + unsigned int sys_id; + + sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID); + return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) & + V2M_SYS_ID_REV_MASK); } diff --git a/plat/arm/board/fvp/fvp_console.c b/plat/arm/board/fvp/fvp_console.c new file mode 100644 index 000000000..1a6cd4202 --- /dev/null +++ b/plat/arm/board/fvp/fvp_console.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <platform_def.h> + +#include <common/debug.h> +#include <drivers/arm/pl011.h> +#include <drivers/console.h> +#include <fconf_hw_config_getter.h> +#include <plat/arm/common/plat_arm.h> + +static console_t fvp_runtime_console; + +/* Initialize the runtime console */ +void arm_console_runtime_init(void) +{ + uintptr_t uart_base; + uint32_t uart_clk; + + /* + * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and + * BL2_AT_EL3 systems. + */ +#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3 + uart_base = PLAT_ARM_RUN_UART_BASE; + uart_clk = PLAT_ARM_RUN_UART_CLK_IN_HZ; +#else + uart_base = FCONF_GET_PROPERTY(hw_config, uart_serial_config, + uart_base); + uart_clk = FCONF_GET_PROPERTY(hw_config, uart_serial_config, + uart_clk); +#endif + + int rc = console_pl011_register(uart_base, uart_clk, + ARM_CONSOLE_BAUDRATE, + &fvp_runtime_console); + + if (rc == 0) { + panic(); + } + + console_set_scope(&fvp_runtime_console, CONSOLE_FLAG_RUNTIME); +} + +void arm_console_runtime_end(void) +{ + console_flush(); + (void)console_unregister(&fvp_runtime_console); +} diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index 347ba2e1e..831eb35b7 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,6 +27,11 @@ #define FVP_CCI 1 #define FVP_CCN 2 +/****************************************************************************** + * Definition of platform soc id + *****************************************************************************/ +#define FVP_SOC_ID 0 + /******************************************************************************* * FVP memory map related constants ******************************************************************************/ @@ -52,8 +57,18 @@ #define DEVICE1_BASE UL(0x2e000000) #define DEVICE1_SIZE UL(0x1A00000) #else -#define DEVICE1_BASE UL(0x2f000000) -#define DEVICE1_SIZE UL(0x200000) +#define DEVICE1_BASE BASE_GICD_BASE + +#if GIC_ENABLE_V4_EXTN +/* GICv4 mapping: GICD + CORE_COUNT * 256KB */ +#define DEVICE1_SIZE ((BASE_GICR_BASE - BASE_GICD_BASE) + \ + (PLATFORM_CORE_COUNT * 0x40000)) +#else +/* GICv2 and GICv3 mapping: GICD + CORE_COUNT * 128KB */ +#define DEVICE1_SIZE ((BASE_GICR_BASE - BASE_GICD_BASE) + \ + (PLATFORM_CORE_COUNT * 0x20000)) +#endif /* GIC_ENABLE_V4_EXTN */ + #define NSRAM_BASE UL(0x2e000000) #define NSRAM_SIZE UL(0x10000) #endif @@ -110,7 +125,7 @@ #define FVP_SP810_CTRL_TIM3_OV BIT_32(22) /******************************************************************************* - * GIC-400 & interrupt handling related constants + * GIC & interrupt handling related constants ******************************************************************************/ /* VE compatible GIC memory map */ #define VE_GICD_BASE UL(0x2c001000) @@ -120,7 +135,16 @@ /* Base FVP compatible GIC memory map */ #define BASE_GICD_BASE UL(0x2f000000) +#define BASE_GICD_SIZE UL(0x10000) #define BASE_GICR_BASE UL(0x2f100000) + +#if GIC_ENABLE_V4_EXTN +/* GICv4 redistributor size: 256KB */ +#define BASE_GICR_SIZE UL(0x40000) +#else +#define BASE_GICR_SIZE UL(0x20000) +#endif /* GIC_ENABLE_V4_EXTN */ + #define BASE_GICC_BASE UL(0x2c000000) #define BASE_GICH_BASE UL(0x2c010000) #define BASE_GICV_BASE UL(0x2c02f000) @@ -128,7 +152,6 @@ #define FVP_IRQ_TZ_WDOG 56 #define FVP_IRQ_SEC_SYS_TIMER 57 - /******************************************************************************* * TrustZone address space controller related constants ******************************************************************************/ diff --git a/plat/arm/board/fvp/fvp_err.c b/plat/arm/board/fvp/fvp_err.c index 2437cd474..c9b20905f 100644 --- a/plat/arm/board/fvp/fvp_err.c +++ b/plat/arm/board/fvp/fvp_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,6 @@ #include <drivers/arm/sp805.h> #include <drivers/cfi/v2m_flash.h> #include <plat/arm/common/plat_arm.h> -#include <plat/common/platform.h> #include <platform_def.h> /* @@ -38,7 +37,7 @@ __dead2 void plat_arm_error_handler(int err) break; } - (void)console_flush(); + console_flush(); /* Setup the watchdog to reset the system as soon as possible */ sp805_refresh(ARM_SP805_TWDG_BASE, 1U); diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c new file mode 100644 index 000000000..8f3e7b702 --- /dev/null +++ b/plat/arm/board/fvp/fvp_gicv3.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <platform_def.h> + +#include <common/interrupt_props.h> +#include <drivers/arm/gicv3.h> +#include <fconf_hw_config_getter.h> +#include <lib/utils.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/arm/common/fconf_sec_intr_config.h> +#include <plat/common/platform.h> + +#if FVP_GICR_REGION_PROTECTION +/* To indicate GICR region of the core initialized as Read-Write */ +static bool fvp_gicr_rw_region_init[PLATFORM_CORE_COUNT] = {false}; +#endif /* FVP_GICR_REGION_PROTECTION */ + +/* The GICv3 driver only needs to be initialized in EL3 */ +static uintptr_t fvp_rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +/* Default GICR base address to be used for GICR probe. */ +static uint64_t fvp_gicr_base_addrs[2] = { 0U }; + +/* List of zero terminated GICR frame addresses which CPUs will probe */ +static uint64_t *fvp_gicr_frames = fvp_gicr_base_addrs; + +#if !(SEC_INT_DESC_IN_FCONF && ((!defined(__aarch64__) && defined(IMAGE_BL32)) || \ + (defined(__aarch64__) && defined(IMAGE_BL31)))) +static const interrupt_prop_t fvp_interrupt_props[] = { + PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S), + PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0) +}; +#endif + +/* + * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register + * to core position. + * + * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity + * values read from GICR_TYPER don't have an MT field. To reuse the same + * translation used for CPUs, we insert MT bit read from the PE's MPIDR into + * that read from GICR_TYPER. + * + * Assumptions: + * + * - All CPUs implemented in the system have MPIDR_EL1.MT bit set; + * - No CPUs implemented in the system use affinity level 3. + */ +static unsigned int fvp_gicv3_mpidr_hash(u_register_t mpidr) +{ + u_register_t temp_mpidr = mpidr; + + temp_mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); + return plat_arm_calc_core_pos(temp_mpidr); +} + + +static gicv3_driver_data_t fvp_gic_data = { + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = fvp_rdistif_base_addrs, + .mpidr_to_core_pos = fvp_gicv3_mpidr_hash +}; + +/****************************************************************************** + * This function gets called per core to make its redistributor frame rw + *****************************************************************************/ +static void fvp_gicv3_make_rdistrif_rw(void) +{ +#if FVP_GICR_REGION_PROTECTION + unsigned int core_pos = plat_my_core_pos(); + + /* Make the redistributor frame RW if it is not done previously */ + if (fvp_gicr_rw_region_init[core_pos] != true) { + int ret = xlat_change_mem_attributes(BASE_GICR_BASE + + (core_pos * BASE_GICR_SIZE), + BASE_GICR_SIZE, + MT_EXECUTE_NEVER | + MT_DEVICE | MT_RW | + MT_SECURE); + + if (ret != 0) { + ERROR("Failed to make redistributor frame \ + read write = %d\n", ret); + panic(); + } else { + fvp_gicr_rw_region_init[core_pos] = true; + } + } +#else + return; +#endif /* FVP_GICR_REGION_PROTECTION */ +} + +void plat_arm_gic_driver_init(void) +{ + fvp_gicv3_make_rdistrif_rw(); + /* + * Get GICD and GICR base addressed through FCONF APIs. + * FCONF is not supported in BL32 for FVP. + */ +#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \ + (defined(__aarch64__) && defined(IMAGE_BL31)) + fvp_gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config, + gicv3_config, + gicd_base); + fvp_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config, + gicr_base); +#if SEC_INT_DESC_IN_FCONF + fvp_gic_data.interrupt_props = FCONF_GET_PROPERTY(hw_config, + sec_intr_prop, descriptor); + fvp_gic_data.interrupt_props_num = FCONF_GET_PROPERTY(hw_config, + sec_intr_prop, count); +#else + fvp_gic_data.interrupt_props = fvp_interrupt_props; + fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props); +#endif +#else + fvp_gic_data.gicd_base = PLAT_ARM_GICD_BASE; + fvp_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE; + fvp_gic_data.interrupt_props = fvp_interrupt_props; + fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props); +#endif + + /* + * The GICv3 driver is initialized in EL3 and does not need + * to be initialized again in SEL1. This is because the S-EL1 + * can use GIC system registers to manage interrupts and does + * not need GIC interface base addresses to be configured. + */ + +#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \ + (defined(__aarch64__) && defined(IMAGE_BL31)) + gicv3_driver_init(&fvp_gic_data); + if (gicv3_rdistif_probe((uintptr_t)fvp_gicr_base_addrs[0]) == -1) { + ERROR("No GICR base frame found for Primary CPU\n"); + panic(); + } +#endif +} + +/****************************************************************************** + * Function to iterate over all GICR frames and discover the corresponding + * per-cpu redistributor frame as well as initialize the corresponding + * interface in GICv3. + *****************************************************************************/ +void plat_arm_gic_pcpu_init(void) +{ + int result; + const uint64_t *plat_gicr_frames = fvp_gicr_frames; + + fvp_gicv3_make_rdistrif_rw(); + + do { + result = gicv3_rdistif_probe(*plat_gicr_frames); + + /* If the probe is successful, no need to proceed further */ + if (result == 0) + break; + + plat_gicr_frames++; + } while (*plat_gicr_frames != 0U); + + if (result == -1) { + ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr()); + panic(); + } + gicv3_rdistif_init(plat_my_core_pos()); +} diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c index 9c4c1d574..109d32150 100644 --- a/plat/arm/board/fvp/fvp_io_storage.c +++ b/plat/arm/board/fvp/fvp_io_storage.c @@ -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 */ @@ -120,18 +120,22 @@ void plat_arm_io_setup(void) { int io_result; - arm_io_setup(); + io_result = arm_io_setup(); + if (io_result < 0) { + panic(); + } /* Register the additional IO devices on this platform */ io_result = register_io_dev_sh(&sh_dev_con); - assert(io_result == 0); + if (io_result < 0) { + panic(); + } /* Open connections to devices and cache the handles */ io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); - assert(io_result == 0); - - /* Ignore improbable errors in release builds */ - (void)io_result; + if (io_result < 0) { + panic(); + } } /* diff --git a/plat/arm/board/fvp/fvp_measured_boot.c b/plat/arm/board/fvp/fvp_measured_boot.c new file mode 100644 index 000000000..b145aae58 --- /dev/null +++ b/plat/arm/board/fvp/fvp_measured_boot.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <drivers/measured_boot/event_log.h> +#include <plat/arm/common/plat_arm.h> + +/* FVP table with platform specific image IDs, names and PCRs */ +static const image_data_t fvp_images_data[] = { + { BL2_IMAGE_ID, BL2_STRING, PCR_0 }, /* Reserved for BL2 */ + { BL31_IMAGE_ID, BL31_STRING, PCR_0 }, + { BL32_IMAGE_ID, BL32_STRING, PCR_0 }, + { BL32_EXTRA1_IMAGE_ID, BL32_EXTRA1_IMAGE_STRING, PCR_0 }, + { BL32_EXTRA2_IMAGE_ID, BL32_EXTRA2_IMAGE_STRING, PCR_0 }, + { BL33_IMAGE_ID, BL33_STRING, PCR_0 }, + { GPT_IMAGE_ID, GPT_IMAGE_STRING, PCR_0 }, + { HW_CONFIG_ID, HW_CONFIG_STRING, PCR_0 }, + { NT_FW_CONFIG_ID, NT_FW_CONFIG_STRING, PCR_0 }, + { SCP_BL2_IMAGE_ID, SCP_BL2_IMAGE_STRING, PCR_0 }, + { SOC_FW_CONFIG_ID, SOC_FW_CONFIG_STRING, PCR_0 }, + { STM32_IMAGE_ID, STM32_IMAGE_STRING, PCR_0 }, + { TOS_FW_CONFIG_ID, TOS_FW_CONFIG_STRING, PCR_0 }, + { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ +}; + +static const measured_boot_data_t fvp_measured_boot_data = { + fvp_images_data, + arm_set_nt_fw_info, + arm_set_tos_fw_info +}; + +/* + * Function retuns pointer to FVP plat_measured_boot_data_t structure + */ +const measured_boot_data_t *plat_get_measured_boot_data(void) +{ + return &fvp_measured_boot_data; +} diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index 0a62543fa..333d89288 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -1,11 +1,10 @@ /* - * 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 */ #include <assert.h> -#include <errno.h> #include <arch_helpers.h> #include <common/debug.h> @@ -16,7 +15,6 @@ #include <lib/psci/psci.h> #include <plat/arm/common/arm_config.h> #include <plat/arm/common/plat_arm.h> -#include <plat/common/platform.h> #include <platform_def.h> #include "fvp_private.h" @@ -66,6 +64,25 @@ static void fvp_cluster_pwrdwn_common(void) /* Disable coherency if this cluster is to be turned off */ fvp_interconnect_disable(); +#if HW_ASSISTED_COHERENCY + uint32_t reg; + + /* + * If we have determined this core to be the last man standing and we + * intend to power down the cluster proactively, we provide a hint to + * the power controller that cluster power is not required when all + * cores are powered down. + * Note that this is only an advisory to power controller and is supported + * by SoCs with DynamIQ Shared Units only. + */ + reg = read_clusterpwrdn(); + + /* Clear and set bit 0 : Cluster power not required */ + reg &= ~DSU_CLUSTER_PWR_MASK; + reg |= DSU_CLUSTER_PWR_OFF; + write_clusterpwrdn(reg); +#endif + /* Program the power controller to turn the cluster off */ fvp_pwrc_write_pcoffr(mpidr); } diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c index 80ec2171b..937f09f6e 100644 --- a/plat/arm/board/fvp/fvp_security.c +++ b/plat/arm/board/fvp/fvp_security.c @@ -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 */ @@ -22,5 +22,5 @@ void plat_arm_security_setup(void) */ if ((get_arm_config()->flags & ARM_CONFIG_HAS_TZC) != 0U) - arm_tzc400_setup(NULL); + arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL); } diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c index 24e79b4d4..80cfbd5ce 100644 --- a/plat/arm/board/fvp/fvp_topology.c +++ b/plat/arm/board/fvp/fvp_topology.c @@ -1,18 +1,21 @@ /* - * 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 */ -#include <platform_def.h> +#include <assert.h> #include <arch.h> #include <drivers/arm/fvp/fvp_pwrc.h> +#include <fconf_hw_config_getter.h> #include <lib/cassert.h> #include <plat/arm/common/arm_config.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> +#include <platform_def.h> + /* The FVP power domain tree descriptor */ static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2]; @@ -21,24 +24,47 @@ CASSERT(((FVP_CLUSTER_COUNT > 0) && (FVP_CLUSTER_COUNT <= 256)), assert_invalid_fvp_cluster_count); /******************************************************************************* - * This function dynamically constructs the topology according to - * FVP_CLUSTER_COUNT and returns it. + * This function dynamically constructs the topology according to cpu-map node + * in HW_CONFIG dtb and returns it. ******************************************************************************/ const unsigned char *plat_get_power_domain_tree_desc(void) { - int i; + unsigned int i; + uint32_t cluster_count, cpus_per_cluster; + + /* + * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and + * BL2_AT_EL3 systems. + */ +#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3 + cluster_count = FVP_CLUSTER_COUNT; + cpus_per_cluster = FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU; +#else + cluster_count = FCONF_GET_PROPERTY(hw_config, topology, plat_cluster_count); + cpus_per_cluster = FCONF_GET_PROPERTY(hw_config, topology, cluster_cpu_count); + /* Several FVP Models use the same blanket dts. Ex: FVP_Base_Cortex-A65x4 + * and FVP_Base_Cortex-A65AEx8 both use same dts but have different number of + * CPUs in the cluster, as reflected by build flags FVP_MAX_CPUS_PER_CLUSTER. + * Take the minimum of two to ensure PSCI functions do not exceed the size of + * the PSCI data structures allocated at build time. + */ + cpus_per_cluster = MIN(cpus_per_cluster, + (uint32_t)(FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU)); + +#endif + + assert(cluster_count > 0U); + assert(cpus_per_cluster > 0U); /* * The highest level is the system level. The next level is constituted * by clusters and then cores in clusters. */ fvp_power_domain_tree_desc[0] = 1; - fvp_power_domain_tree_desc[1] = FVP_CLUSTER_COUNT; - - for (i = 0; i < FVP_CLUSTER_COUNT; i++) - fvp_power_domain_tree_desc[i + 2] = - FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU; + fvp_power_domain_tree_desc[1] = (unsigned char)cluster_count; + for (i = 0; i < cluster_count; i++) + fvp_power_domain_tree_desc[i + 2] = (unsigned char)cpus_per_cluster; return fvp_power_domain_tree_desc; } diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c index dc5076435..1ea37f7a3 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,33 @@ #include <string.h> #include <lib/mmio.h> - +#include <lib/fconf/fconf.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/arm/common/fconf_nv_cntr_getter.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(cookie, 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 @@ -31,9 +52,11 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) oid = (const char *)cookie; if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = TFW_NVCTR_BASE; + nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, + TRUSTED_NV_CTR_ID); } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = NTFW_CTR_BASE; + nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, + NON_TRUSTED_NV_CTR_ID); } else { return 1; } diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h new file mode 100644 index 000000000..ca85f7a70 --- /dev/null +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_HW_CONFIG_GETTER_H +#define FCONF_HW_CONFIG_GETTER_H + +#include <lib/fconf/fconf.h> + +/* Hardware Config related getter */ +#define hw_config__gicv3_config_getter(prop) gicv3_config.prop +#define hw_config__topology_getter(prop) soc_topology.prop +#define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop +#define hw_config__cpu_timer_getter(prop) cpu_timer.prop + +struct gicv3_config_t { + uint64_t gicd_base; + uint64_t gicr_base; +}; + +struct hw_topology_t { + uint32_t plat_cluster_count; + uint32_t cluster_cpu_count; + uint32_t plat_cpu_count; + uint32_t plat_max_pwr_level; +}; + +struct uart_serial_config_t { + uint64_t uart_base; + uint32_t uart_clk; +}; + +struct cpu_timer_t { + uint32_t clock_freq; +}; + +int fconf_populate_gicv3_config(uintptr_t config); +int fconf_populate_topology(uintptr_t config); +int fconf_populate_uart_config(uintptr_t config); +int fconf_populate_cpu_timer(uintptr_t config); + +extern struct gicv3_config_t gicv3_config; +extern struct hw_topology_t soc_topology; +extern struct uart_serial_config_t uart_serial_config; +extern struct cpu_timer_t cpu_timer; +#endif /* FCONF_HW_CONFIG_GETTER_H */ diff --git a/plat/arm/board/fvp/include/fconf_nt_config_getter.h b/plat/arm/board/fvp/include/fconf_nt_config_getter.h new file mode 100644 index 000000000..0824c3509 --- /dev/null +++ b/plat/arm/board/fvp/include/fconf_nt_config_getter.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_NT_CONFIG_GETTER_H +#define FCONF_NT_CONFIG_GETTER_H + +#include <lib/fconf/fconf.h> + +/* NT Firmware Config related getter */ +#define nt_config__event_log_config_getter(prop) event_log.prop + +struct event_log_config_t { +#ifdef SPD_opteed + void *tpm_event_log_sm_addr; +#endif + void *tpm_event_log_addr; + size_t tpm_event_log_size; +}; + +int fconf_populate_event_log_config(uintptr_t config); + +extern struct event_log_config_t event_log_config; + +#endif /* FCONF_NT_CONFIG_GETTER_H */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index c2b7b98d4..8defcf837 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/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 */ @@ -43,6 +43,15 @@ #define PLAT_ARM_TRUSTED_DRAM_BASE UL(0x06000000) #define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */ +/* + * Max size of SPMC is 2MB for fvp. With SPMD enabled this value corresponds to + * max size of BL32 image. + */ +#if defined(SPD_spmd) +#define PLAT_ARM_SPMC_BASE PLAT_ARM_TRUSTED_DRAM_BASE +#define PLAT_ARM_SPMC_SIZE UL(0x200000) /* 2 MB */ +#endif + /* virtual address used by dynamic mem_protect for chunk_base */ #define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) @@ -52,6 +61,13 @@ #define PLAT_ARM_DRAM2_BASE ULL(0x880000000) #define PLAT_ARM_DRAM2_SIZE UL(0x80000000) +#define PLAT_HW_CONFIG_DTB_BASE ULL(0x82000000) +#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000) + +#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \ + PLAT_HW_CONFIG_DTB_BASE, \ + PLAT_HW_CONFIG_DTB_SIZE, \ + MT_MEMORY | MT_RO | MT_NS) /* * Load address of BL33 for this platform port */ @@ -63,21 +79,21 @@ */ #if defined(IMAGE_BL31) # if SPM_MM -# define PLAT_ARM_MMAP_ENTRIES 9 +# define PLAT_ARM_MMAP_ENTRIES 10 # define MAX_XLAT_TABLES 9 # define PLAT_SP_IMAGE_MMAP_REGIONS 30 # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else -# define PLAT_ARM_MMAP_ENTRIES 8 +# define PLAT_ARM_MMAP_ENTRIES 9 # if USE_DEBUGFS -# define MAX_XLAT_TABLES 6 +# define MAX_XLAT_TABLES 8 # else -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 7 # endif # endif #elif defined(IMAGE_BL32) -# define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 5 +# define PLAT_ARM_MMAP_ENTRIES 9 +# define MAX_XLAT_TABLES 6 #elif !USE_ROMLIB # define PLAT_ARM_MMAP_ENTRIES 11 # define MAX_XLAT_TABLES 5 @@ -111,17 +127,27 @@ * little space for growth. */ #if TRUSTED_BOARD_BOOT +#if COT_DESC_IN_DTB +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1E000) - FVP_BL2_ROMLIB_OPTIMIZATION) +#else # define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION) +#endif #else -# define PLAT_ARM_MAX_BL2_SIZE (UL(0x11000) - FVP_BL2_ROMLIB_OPTIMIZATION) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - FVP_BL2_ROMLIB_OPTIMIZATION) #endif +#if RESET_TO_BL31 +/* Size of Trusted SRAM - the first 4KB of shared memory */ +#define PLAT_ARM_MAX_BL31_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \ + ARM_SHARED_RAM_SIZE) +#else /* * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is * calculated using the current BL31 PROGBITS debug size plus the sizes of * BL2 and BL1-RW */ -#define PLAT_ARM_MAX_BL31_SIZE UL(0x3B000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000) +#endif /* RESET_TO_BL31 */ #ifndef __aarch64__ /* @@ -139,13 +165,13 @@ # if TRUSTED_BOARD_BOOT # define PLATFORM_STACK_SIZE UL(0x1000) # else -# define PLATFORM_STACK_SIZE UL(0x440) +# define PLATFORM_STACK_SIZE UL(0x500) # endif #elif defined(IMAGE_BL2) # if TRUSTED_BOARD_BOOT # define PLATFORM_STACK_SIZE UL(0x1000) # else -# define PLATFORM_STACK_SIZE UL(0x400) +# define PLATFORM_STACK_SIZE UL(0x440) # endif #elif defined(IMAGE_BL2U) # define PLATFORM_STACK_SIZE UL(0x400) @@ -230,8 +256,8 @@ /* * GIC related constants to cater for both GICv2 and GICv3 instances of an - * FVP. They could be overriden at runtime in case the FVP implements the legacy - * VE memory map. + * FVP. They could be overridden at runtime in case the FVP implements the + * legacy VE memory map. */ #define PLAT_ARM_GICD_BASE BASE_GICD_BASE #define PLAT_ARM_GICR_BASE BASE_GICR_BASE @@ -251,8 +277,13 @@ #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) +#if SDEI_IN_FCONF +#define PLAT_SDEI_DP_EVENT_MAX_CNT ARM_SDEI_DP_EVENT_MAX_CNT +#define PLAT_SDEI_DS_EVENT_MAX_CNT ARM_SDEI_DS_EVENT_MAX_CNT +#else #define PLAT_ARM_PRIVATE_SDEI_EVENTS ARM_SDEI_PRIVATE_EVENTS #define PLAT_ARM_SHARED_SDEI_EVENTS ARM_SDEI_SHARED_EVENTS +#endif #define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ PLAT_SP_IMAGE_NS_BUF_SIZE) diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index 6ccdd283f..b72bdab4a 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -15,11 +15,26 @@ # fdt fdt_getprop_namelen patch rom rom_lib_init +fdt fdt_getprop +fdt fdt_get_property fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial +fdt fdt_first_subnode +fdt fdt_next_subnode +fdt fdt_path_offset +fdt fdt_path_offset_namelen +fdt fdt_subnode_offset +fdt fdt_address_cells +fdt fdt_size_cells +fdt fdt_parent_offset +fdt fdt_stringlist_search +fdt fdt_get_alias_namelen +fdt fdt_get_name +fdt fdt_get_alias +fdt fdt_node_offset_by_phandle mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 97a326c09..6c09d7268 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -7,9 +7,6 @@ # Use the GICv3 driver on the FVP by default FVP_USE_GIC_DRIVER := FVP_GICV3 -# Use the SP804 timer instead of the generic one -FVP_USE_SP804_TIMER := 0 - # Default cluster count for FVP FVP_CLUSTER_COUNT := 2 @@ -19,10 +16,11 @@ FVP_MAX_CPUS_PER_CLUSTER := 4 # Default number of threads per CPU on FVP FVP_MAX_PE_PER_CPU := 1 -FVP_DT_PREFIX := fvp-base-gicv3-psci +# Disable redistributor frame of inactive/fused CPU cores by marking it as read +# only; enable redistributor frames of all CPU cores by default. +FVP_GICR_REGION_PROTECTION := 0 -$(eval $(call assert_boolean,FVP_USE_SP804_TIMER)) -$(eval $(call add_define,FVP_USE_SP804_TIMER)) +FVP_DT_PREFIX := fvp-base-gicv3-psci # The FVP platform depends on this macro to build with correct GIC driver. $(eval $(call add_define,FVP_USE_GIC_DRIVER)) @@ -36,6 +34,9 @@ $(eval $(call add_define,FVP_MAX_CPUS_PER_CLUSTER)) # Pass FVP_MAX_PE_PER_CPU to the build system. $(eval $(call add_define,FVP_MAX_PE_PER_CPU)) +# Pass FVP_GICR_REGION_PROTECTION to the build system. +$(eval $(call add_define,FVP_GICR_REGION_PROTECTION)) + # Sanity check the cluster count and if FVP_CLUSTER_COUNT <= 2, # choose the CCI driver , else the CCN driver ifeq ($(FVP_CLUSTER_COUNT), 0) @@ -48,23 +49,34 @@ endif $(eval $(call add_define,FVP_INTERCONNECT_DRIVER)) -FVP_GICV3_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ +# Choose the GIC sources depending upon the how the FVP will be invoked +ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3) + +# The GIC model (GIC-600 or GIC-500) will be detected at runtime +GICV3_SUPPORT_GIC600 := 1 +GICV3_OVERRIDE_DISTIF_PWR_OPS := 1 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +FVP_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c -# Choose the GIC sources depending upon the how the FVP will be invoked -ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3) -FVP_GIC_SOURCES := ${FVP_GICV3_SOURCES} \ - drivers/arm/gic/v3/gic500.c -else ifeq (${FVP_USE_GIC_DRIVER},FVP_GIC600) -FVP_GIC_SOURCES := ${FVP_GICV3_SOURCES} \ - drivers/arm/gic/v3/gic600.c + ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31} ${RESET_TO_SP_MIN}),) + FVP_GIC_SOURCES += plat/arm/board/fvp/fvp_gicv3.c + endif + else ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV2) -FVP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ + +# No GICv4 extension +GIC_ENABLE_V4_EXTN := 0 +$(eval $(call add_define,GIC_ENABLE_V4_EXTN)) + +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +FVP_GIC_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c @@ -112,11 +124,15 @@ else FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \ lib/cpus/aarch64/cortex_a76ae.S \ lib/cpus/aarch64/cortex_a77.S \ + lib/cpus/aarch64/cortex_a78.S \ + lib/cpus/aarch64/neoverse_n_common.S \ lib/cpus/aarch64/neoverse_n1.S \ + lib/cpus/aarch64/neoverse_n2.S \ lib/cpus/aarch64/neoverse_e1.S \ - lib/cpus/aarch64/neoverse_zeus.S \ - lib/cpus/aarch64/cortex_hercules.S \ - lib/cpus/aarch64/cortex_hercules_ae.S \ + lib/cpus/aarch64/neoverse_v1.S \ + lib/cpus/aarch64/cortex_a78_ae.S \ + lib/cpus/aarch64/cortex_klein.S \ + lib/cpus/aarch64/cortex_matterhorn.S \ lib/cpus/aarch64/cortex_a65.S \ lib/cpus/aarch64/cortex_a65ae.S endif @@ -139,11 +155,10 @@ 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} -ifeq (${FVP_USE_SP804_TIMER},1) +ifeq (${USE_SP804_TIMER},1) BL1_SOURCES += drivers/arm/sp804/sp804_delay_timer.c else BL1_SOURCES += drivers/delay_timer/generic_delay_timer.c @@ -158,11 +173,13 @@ 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} +ifeq (${COT_DESC_IN_DTB},1) +BL2_SOURCES += plat/arm/common/fconf/fconf_nv_cntr_getter.c +endif ifeq (${BL2_AT_EL3},1) BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \ @@ -171,14 +188,14 @@ BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \ ${FVP_INTERCONNECT_SOURCES} endif -ifeq (${FVP_USE_SP804_TIMER},1) +ifeq (${USE_SP804_TIMER},1) BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c endif BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \ ${FVP_SECURITY_SOURCES} -ifeq (${FVP_USE_SP804_TIMER},1) +ifeq (${USE_SP804_TIMER},1) BL2U_SOURCES += drivers/arm/sp804/sp804_delay_timer.c endif @@ -188,6 +205,7 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/board/fvp/fvp_bl31_setup.c \ + plat/arm/board/fvp/fvp_console.c \ plat/arm/board/fvp/fvp_pm.c \ plat/arm/board/fvp/fvp_topology.c \ plat/arm/board/fvp/aarch64/fvp_helpers.S \ @@ -197,7 +215,21 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ ${FVP_INTERCONNECT_SOURCES} \ ${FVP_SECURITY_SOURCES} -ifeq (${FVP_USE_SP804_TIMER},1) +# Support for fconf in BL31 +# Added separately from the above list for better readability +ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31}),) +BL31_SOURCES += common/fdt_wrappers.c \ + lib/fconf/fconf.c \ + lib/fconf/fconf_dyn_cfg_getter.c \ + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c + +ifeq (${SEC_INT_DESC_IN_FCONF},1) +BL31_SOURCES += plat/arm/common/fconf/fconf_sec_intr_config.c +endif + +endif + +ifeq (${USE_SP804_TIMER},1) BL31_SOURCES += drivers/arm/sp804/sp804_delay_timer.c else BL31_SOURCES += drivers/delay_timer/generic_delay_timer.c @@ -207,11 +239,13 @@ endif ifdef UNIX_MK FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ + ${PLAT}_fw_config.dts \ ${PLAT}_tb_fw_config.dts \ ${PLAT}_soc_fw_config.dts \ ${PLAT}_nt_fw_config.dts \ ) +FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb @@ -221,21 +255,36 @@ FDT_SOURCES += plat/arm/board/fvp/fdts/${PLAT}_tsp_fw_config.dts FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tsp_fw_config.dtb # Add the TOS_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG})) +endif + +ifeq (${SPD},spmd) + +ifeq ($(ARM_SPMC_MANIFEST_DTS),) +ARM_SPMC_MANIFEST_DTS := plat/arm/board/fvp/fdts/${PLAT}_spmc_manifest.dts +endif + +FDT_SOURCES += ${ARM_SPMC_MANIFEST_DTS} +FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb + +# Add the TOS_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG})) endif +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG})) # Add the SOC_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config,${FVP_SOC_FW_CONFIG})) # Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG})) FDT_SOURCES += ${FVP_HW_CONFIG_DTS} $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS))) # Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG})) endif # Enable Activity Monitor Unit extensions by default @@ -277,19 +326,30 @@ endif # Enable the dynamic translation tables library. ifeq (${ARCH},aarch32) ifeq (${RESET_TO_SP_MIN},1) - BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif -else # if AArch64 +else # AArch64 ifeq (${RESET_TO_BL31},1) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif ifeq (${SPD},trusty) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC + endif +endif + +ifeq (${ALLOW_RO_XLAT_TABLES}, 1) + ifeq (${ARCH},aarch32) + BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES + else # AArch64 + BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES + ifeq (${SPD},tspd) + BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES + endif endif endif ifeq (${USE_DEBUGFS},1) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif # Add support for platform supplied linker script for BL31 build @@ -302,8 +362,15 @@ 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 + +ifeq (${MEASURED_BOOT},1) +BL2_SOURCES += plat/arm/board/fvp/fvp_measured_boot.c +endif + # 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/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c index 88c91e6fe..763b42afb 100644 --- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c +++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c @@ -1,13 +1,20 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> + +#include <bl32/sp_min/platform_sp_min.h> +#include <common/debug.h> +#include <lib/fconf/fconf.h> #include <plat/arm/common/plat_arm.h> #include "../fvp_private.h" +uintptr_t hw_config_dtb; + void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { @@ -30,4 +37,24 @@ void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, * FVP PSCI code will enable coherency for other clusters. */ fvp_interconnect_enable(); + + hw_config_dtb = arg2; +} + +void sp_min_plat_arch_setup(void) +{ + arm_sp_min_plat_arch_setup(); + + /* + * For RESET_TO_SP_MIN systems, SP_MIN(BL32) is the first bootloader + * to run. So there is no BL2 to load the HW_CONFIG dtb into memory + * before control is passed to SP_MIN. + * Also, BL2 skips loading HW_CONFIG dtb for BL2_AT_EL3 builds. + */ +#if !RESET_TO_SP_MIN && !BL2_AT_EL3 + assert(hw_config_dtb != 0U); + + INFO("SP_MIN FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb); + fconf_populate("HW_CONFIG", hw_config_dtb); +#endif } diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk index 0250a5f1a..64cb7add5 100644 --- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk +++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -10,6 +10,7 @@ BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ lib/utils/mem_region.c \ plat/arm/board/fvp/aarch32/fvp_helpers.S \ plat/arm/board/fvp/fvp_pm.c \ + plat/arm/board/fvp/fvp_console.c \ plat/arm/board/fvp/fvp_topology.c \ plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ @@ -18,4 +19,17 @@ BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ ${FVP_INTERCONNECT_SOURCES} \ ${FVP_SECURITY_SOURCES} +# Support for fconf in SP_MIN(BL32) +# Added separately from the above list for better readability +ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_SP_MIN}),) +BL32_SOURCES += common/fdt_wrappers.c \ + lib/fconf/fconf.c \ + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c + +ifeq (${SEC_INT_DESC_IN_FCONF},1) +BL32_SOURCES += plat/arm/common/fconf/fconf_sec_intr_config.c +endif + +endif + include plat/arm/common/sp_min/arm_sp_min.mk diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts new file mode 100644 index 000000000..6e5691bd9 --- /dev/null +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x80001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + + hw-config { + load-address = <0x0 0x82000000>; + max-size = <0x01000000>; + id = <HW_CONFIG_ID>; + }; + }; +}; diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts index 9ab2d9656..c66186f64 100644 --- a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,11 +7,9 @@ /dts-v1/; / { - /* Platform Config */ - plat_arm_bl2 { + tb_fw-config { compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x82000000>; - hw_config_max_size = <0x01000000>; + /* Disable authentication for development */ disable_auth = <0x0>; }; diff --git a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c index 25e096417..4ccae27a2 100644 --- a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c +++ b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c @@ -25,7 +25,7 @@ void bl2_platform_setup(void) { arm_bl2_platform_setup(); -#ifdef FVP_VE_USE_SP804_TIMER +#if USE_SP804_TIMER /* * Enable the clock override for SP804 timer 0, which means that no * clock dividers are applied and the raw (35 MHz) clock will be used @@ -37,5 +37,5 @@ void bl2_platform_setup(void) SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV); #else generic_delay_timer_init(); -#endif /* FVP_VE_USE_SP804_TIMER */ +#endif /* USE_SP804_TIMER */ } diff --git a/plat/arm/board/fvp_ve/fvp_ve_err.c b/plat/arm/board/fvp_ve/fvp_ve_err.c index 7f9d2f7ed..8d3568850 100644 --- a/plat/arm/board/fvp_ve/fvp_ve_err.c +++ b/plat/arm/board/fvp_ve/fvp_ve_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h index 1b07a9b42..3f2fcee58 100644 --- a/plat/arm/board/fvp_ve/include/platform_def.h +++ b/plat/arm/board/fvp_ve/include/platform_def.h @@ -11,6 +11,7 @@ #include <lib/utils_def.h> #include <lib/xlat_tables/xlat_tables_defs.h> #include <plat/arm/board/common/v2m_def.h> +#include <plat/arm/common/smccc_def.h> #include <plat/common/common_def.h> #include "../fvp_ve_def.h" @@ -120,10 +121,19 @@ #endif /* + * Map the region for device tree configuration with read and write permissions + */ +#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT(ARM_BL_RAM_BASE, \ + (ARM_FW_CONFIGS_LIMIT \ + - ARM_BL_RAM_BASE), \ + MT_MEMORY | MT_RW | MT_SECURE) + + +/* * The max number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. */ -#define ARM_BL_REGIONS 5 +#define ARM_BL_REGIONS 6 #define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ ARM_BL_REGIONS) @@ -168,11 +178,18 @@ #define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) /* - * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space of BL2 meminfo. */ -#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_FW_CONFIG_LIMIT ((ARM_BL_RAM_BASE + PAGE_SIZE) \ + + (PAGE_SIZE / 2U)) + +/* + * Define limit of firmware configuration memory: + * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory + */ +#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2)) /******************************************************************************* * BL1 specific defines. @@ -203,7 +220,9 @@ /* Put BL32 below BL2 in NS DRAM.*/ -#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \ + + (PAGE_SIZE / 2U)) #define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\ - PLAT_ARM_MAX_BL32_SIZE) diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index 4d21f4ba0..ac45d57ee 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -1,20 +1,20 @@ # -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # ifdef ARM_CORTEX_A5 # Use the SP804 timer instead of the generic one -FVP_VE_USE_SP804_TIMER := 1 -$(eval $(call add_define,FVP_VE_USE_SP804_TIMER)) +USE_SP804_TIMER := 1 BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c endif -FVP_VE_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 \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +FVP_VE_GIC_SOURCES := ${GICV2_SOURCES} \ + plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c FVP_VE_SECURITY_SOURCES := plat/arm/board/fvp_ve/fvp_ve_security.c @@ -42,6 +42,7 @@ BL1_SOURCES += drivers/arm/sp805/sp805.c \ plat/arm/common/arm_err.c \ plat/arm/board/fvp_ve/fvp_ve_err.c \ plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c \ drivers/cfi/v2m/v2m_flash.c \ plat/arm/board/fvp_ve/${ARCH}/fvp_ve_helpers.S \ plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c \ @@ -63,6 +64,7 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \ plat/arm/common/arm_err.c \ plat/arm/board/fvp_ve/fvp_ve_err.c \ plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c \ plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c \ plat/arm/common/arm_image_load.c \ common/desc_image_load.c \ @@ -72,18 +74,22 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts +FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts \ + plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts +FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG})) FDT_SOURCES += ${FVP_HW_CONFIG_DTS} $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ fdts/$(notdir ${FVP_HW_CONFIG_DTS}))) # Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG})) endif NEED_BL32 := yes @@ -116,6 +122,9 @@ else PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} endif +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts new file mode 100644 index 000000000..c0538f863 --- /dev/null +++ b/plat/arm/board/juno/fdts/juno_fw_config.dts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + }; +}; diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts index a8ab6c5f9..80cfa3ea1 100644 --- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts +++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,19 +7,20 @@ /dts-v1/; / { - /* Platform Config */ - compatible = "arm,tb_fw"; - /* Disable authentication for development */ - disable_auth = <0x0>; - /* - * 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>; + tb_fw-config { + compatible = "arm,tb_fw"; + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * 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/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 16bb33d7e..91c3ae7e0 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 */ @@ -50,6 +50,9 @@ #define NSRAM_BASE UL(0x2e000000) #define NSRAM_SIZE UL(0x00008000) /* 32KB */ +#define PLAT_ARM_DRAM2_BASE ULL(0x880000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) + /* virtual address used by dynamic mem_protect for chunk_base */ #define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) @@ -136,7 +139,7 @@ # define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif #else -# define PLAT_ARM_MAX_BL2_SIZE (UL(0xF000) - JUNO_BL2_ROMLIB_OPTIMIZATION) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif /* @@ -145,7 +148,7 @@ * BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL31 -> BL2_BASE. * Hence the BL31 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE. */ -#define PLAT_ARM_MAX_BL31_SIZE UL(0x3E000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000) #if JUNO_AARCH32_EL3_RUNTIME /* @@ -154,7 +157,7 @@ * BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL32 -> BL2_BASE. * Hence the BL32 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE. */ -#define PLAT_ARM_MAX_BL32_SIZE UL(0x3E000) +#define PLAT_ARM_MAX_BL32_SIZE UL(0x3D000) #endif /* @@ -212,6 +215,9 @@ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU) | \ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT)) +/* TZC related constants */ +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL + /* * Required ARM CSS based platform porting definitions */ @@ -224,7 +230,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 @@ -244,16 +249,14 @@ #endif /* - * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current - * SCP_BL2 size plus a little space for growth. + * SCP_BL2 uses up whatever remaining space is available as it is loaded before + * anything else in this memory region and is handed over to the SCP before + * BL31 is loaded over the top. */ -#define PLAT_CSS_MAX_SCP_BL2_SIZE UL(0x14000) +#define PLAT_CSS_MAX_SCP_BL2_SIZE \ + ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) -/* - * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current - * SCP_BL2U size plus a little space for growth. - */ -#define PLAT_CSS_MAX_SCP_BL2U_SIZE UL(0x14000) +#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE #define PLAT_ARM_G1S_IRQ_PROPS(grp) \ CSS_G1S_IRQ_PROPS(grp), \ @@ -301,4 +304,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/jmptbl.i b/plat/arm/board/juno/jmptbl.i index 6ccdd283f..393a64816 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -15,11 +15,25 @@ # fdt fdt_getprop_namelen patch rom rom_lib_init +fdt fdt_getprop +fdt fdt_get_property fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial +fdt fdt_first_subnode +fdt fdt_next_subnode +fdt fdt_parent_offset +fdt fdt_stringlist_search +fdt fdt_get_alias_namelen +fdt fdt_path_offset +fdt fdt_path_offset_namelen +fdt fdt_address_cells +fdt fdt_size_cells +fdt fdt_get_name +fdt fdt_get_alias +fdt fdt_node_offset_by_phandle mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c index 89398d686..2234055d4 100644 --- a/plat/arm/board/juno/juno_bl1_setup.c +++ b/plat/arm/board/juno/juno_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -60,17 +60,13 @@ static int is_watchdog_reset(void) * The following function checks if Firmware update is needed, * by checking if TOC in FIP image is valid or watchdog reset happened. ******************************************************************************/ -int plat_arm_bl1_fwu_needed(void) +bool plat_arm_bl1_fwu_needed(void) { const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR; /* Check if TOC is invalid or watchdog reset happened. */ - if ((arm_io_is_toc_valid() != 1) || - (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT)) - && is_watchdog_reset())) - return 1; - - return 0; + return (!arm_io_is_toc_valid() || (((*nv_flags_ptr == -EAUTH) || + (*nv_flags_ptr == -ENOENT)) && is_watchdog_reset())); } /******************************************************************************* @@ -101,7 +97,7 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) /* Setup the watchdog to reset the system as soon as possible */ sp805_refresh(ARM_SP805_TWDG_BASE, 1U); - while (1) + while (true) wfi(); } diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c index 9570d2d4c..da4918cf2 100644 --- a/plat/arm/board/juno/juno_common.c +++ b/plat/arm/board/juno/juno_common.c @@ -1,10 +1,13 @@ /* - * 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 */ +#include <lib/smccc.h> #include <platform_def.h> +#include <services/arm_arch_svc.h> + #include <plat/arm/common/plat_arm.h> /* @@ -91,3 +94,40 @@ const mmap_region_t plat_arm_mmap[] = { #endif ARM_CASSERT_MMAP + +/***************************************************************************** + * plat_is_smccc_feature_available() - This function checks whether SMCCC + * feature is availabile for platform. + * @fid: SMCCC function id + * + * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and + * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. + *****************************************************************************/ +int32_t plat_is_smccc_feature_available(u_register_t fid) +{ + switch (fid) { + case SMCCC_ARCH_SOC_ID: + return SMC_ARCH_CALL_SUCCESS; + default: + return SMC_ARCH_CALL_NOT_SUPPORTED; + } +} + +/* Get SOC version */ +int32_t plat_get_soc_version(void) +{ + return (int32_t) + ((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT) + | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT) + | JUNO_SOC_ID); +} + +/* Get SOC revision */ +int32_t plat_get_soc_revision(void) +{ + unsigned int sys_id; + + sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID); + return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) & + V2M_SYS_ID_REV_MASK); +} diff --git a/plat/arm/board/juno/juno_decl.h b/plat/arm/board/juno/juno_decl.h index cd87c3b77..21e56c051 100644 --- a/plat/arm/board/juno/juno_decl.h +++ b/plat/arm/board/juno/juno_decl.h @@ -7,6 +7,6 @@ #ifndef JUNO_DECL_H #define JUNO_DECL_H -int juno_getentropy(void *buf, size_t len); +bool juno_getentropy(uint64_t *buf); #endif /* JUNO_DECL_H */ diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h index 3b34a9f6a..ddf99dcdb 100644 --- a/plat/arm/board/juno/juno_def.h +++ b/plat/arm/board/juno/juno_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 */ @@ -9,6 +9,11 @@ #include <lib/utils_def.h> +/****************************************************************************** + * Definition of platform soc id + *****************************************************************************/ +#define JUNO_SOC_ID 1 + /******************************************************************************* * Juno memory map related constants ******************************************************************************/ diff --git a/plat/arm/board/juno/juno_err.c b/plat/arm/board/juno/juno_err.c index 961bfda17..60699cc73 100644 --- a/plat/arm/board/juno/juno_err.c +++ b/plat/arm/board/juno/juno_err.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 */ @@ -9,7 +9,6 @@ #include <arch_helpers.h> #include <drivers/arm/sp805.h> #include <plat/arm/common/plat_arm.h> -#include <plat/common/platform.h> #include <platform_def.h> /* diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c index 32823e01c..1e64c029d 100644 --- a/plat/arm/board/juno/juno_security.c +++ b/plat/arm/board/juno/juno_security.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 */ @@ -127,13 +127,13 @@ void plat_arm_security_setup(void) init_debug_cfg(); /* Initialize the TrustZone Controller */ #ifdef JUNO_TZMP1 - arm_tzc400_setup(juno_tzmp1_tzc_regions); + arm_tzc400_setup(PLAT_ARM_TZC_BASE, juno_tzmp1_tzc_regions); INFO("TZC protected shared memory base address for TZMP usecase: %p\n", (void *)JUNO_AP_TZC_SHARE_DRAM1_BASE); INFO("TZC protected shared memory end address for TZMP usecase: %p\n", (void *)JUNO_AP_TZC_SHARE_DRAM1_END); #else - arm_tzc400_setup(NULL); + arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL); #endif /* Do ARM CSS internal NIC setup */ css_init_nic400(); diff --git a/plat/arm/board/juno/juno_stack_protector.c b/plat/arm/board/juno/juno_stack_protector.c index 236eb5ba3..8c51f574c 100644 --- a/plat/arm/board/juno/juno_stack_protector.c +++ b/plat/arm/board/juno/juno_stack_protector.c @@ -13,20 +13,16 @@ u_register_t plat_get_stack_protector_canary(void) { - u_register_t c[TRNG_NBYTES / sizeof(u_register_t)]; - u_register_t ret = 0; - size_t i; + uint64_t entropy; - if (juno_getentropy(c, sizeof(c)) != 0) { + if (!juno_getentropy(&entropy)) { ERROR("Not enough entropy to initialize canary value\n"); panic(); } - /* - * On Juno we get 128-bits of entropy in one round. - * Fuse the values together to form the canary. - */ - for (i = 0; i < ARRAY_SIZE(c); i++) - ret ^= c[i]; - return ret; + if (sizeof(entropy) == sizeof(u_register_t)) { + return entropy; + } + + return (entropy & 0xffffffffULL) ^ (entropy >> 32); } diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c index 052ab9f8a..075f512c3 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_trng.c b/plat/arm/board/juno/juno_trng.c index 7869d3e33..b38e49f45 100644 --- a/plat/arm/board/juno/juno_trng.c +++ b/plat/arm/board/juno/juno_trng.c @@ -5,6 +5,8 @@ */ #include <assert.h> +#include <stdbool.h> +#include <stdint.h> #include <string.h> #include <lib/mmio.h> @@ -16,7 +18,10 @@ #define NSAMPLE_CLOCKS 1 /* min 1 cycle, max 231 cycles */ #define NRETRIES 5 -static inline int output_valid(void) +/* initialised to false */ +static bool juno_trng_initialized; + +static bool output_valid(void) { int i; @@ -25,59 +30,58 @@ static inline int output_valid(void) val = mmio_read_32(TRNG_BASE + TRNG_STATUS); if (val & 1U) - break; + return true; } - if (i >= NRETRIES) - return 0; /* No output data available. */ - return 1; + return false; /* No output data available. */ } /* - * This function fills `buf` with `len` bytes of entropy. + * This function fills `buf` with 8 bytes of entropy. * It uses the Trusted Entropy Source peripheral on Juno. - * Returns 0 when the buffer has been filled with entropy - * successfully and -1 otherwise. + * Returns 'true' when the buffer has been filled with entropy + * successfully, or 'false' otherwise. */ -int juno_getentropy(void *buf, size_t len) +bool juno_getentropy(uint64_t *buf) { - uint8_t *bp = buf; + uint64_t ret; assert(buf); - assert(len); - assert(!check_uptr_overflow((uintptr_t)bp, len)); - - /* Disable interrupt mode. */ - mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0); - /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */ - mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS); + assert(!check_uptr_overflow((uintptr_t)buf, sizeof(*buf))); + + if (!juno_trng_initialized) { + /* Disable interrupt mode. */ + mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0); + /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */ + mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS); + /* Abort any potentially pending sampling. */ + mmio_write_32(TRNG_BASE + TRNG_CONTROL, 2); + /* Reset TRNG outputs. */ + mmio_write_32(TRNG_BASE + TRNG_STATUS, 1); - while (len > 0) { - int i; + juno_trng_initialized = true; + } + if (!output_valid()) { /* Start TRNG. */ mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1); - /* Check if output is valid. */ if (!output_valid()) - return -1; - - /* Fill entropy buffer. */ - for (i = 0; i < TRNG_NOUTPUTS; i++) { - size_t n; - uint32_t val; - - val = mmio_read_32(TRNG_BASE + i * sizeof(uint32_t)); - n = MIN(len, sizeof(uint32_t)); - memcpy(bp, &val, n); - bp += n; - len -= n; - if (len == 0) - break; - } - - /* Reset TRNG outputs. */ - mmio_write_32(TRNG_BASE + TRNG_STATUS, 1); + return false; } - return 0; + /* XOR each two 32-bit registers together, combine the pairs */ + ret = mmio_read_32(TRNG_BASE + 0); + ret ^= mmio_read_32(TRNG_BASE + 4); + ret <<= 32; + + ret |= mmio_read_32(TRNG_BASE + 8); + ret ^= mmio_read_32(TRNG_BASE + 12); + *buf = ret; + + /* Acknowledge current cycle, clear output registers. */ + mmio_write_32(TRNG_BASE + TRNG_STATUS, 1); + /* Trigger next TRNG cycle. */ + mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1); + + return true; } 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 000000000..25a74705d --- /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 bd6bae536..61cfb610c 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,12 +1,13 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # -JUNO_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ +# Include GICv2 driver files +include drivers/arm/gic/v2/gicv2.mk + +JUNO_GIC_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c @@ -91,6 +92,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) @@ -102,7 +108,7 @@ ifeq ($(USE_ROMLIB),1) all : bl1_romlib.bin endif -bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/romlib/romlib.bin +bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin romlib.bin @echo "Building combined BL1 and ROMLIB binary for Juno $@" ./lib/romlib/gen_combined_bl1_romlib.sh -o bl1_romlib.bin $(BUILD_PLAT) @@ -142,20 +148,33 @@ ENABLE_SVE_FOR_NS := 0 # Enable the dynamic translation tables library. ifeq (${ARCH},aarch32) ifeq (${RESET_TO_SP_MIN},1) - BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC endif else ifeq (${RESET_TO_BL31},1) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC + endif +endif + +ifeq (${ALLOW_RO_XLAT_TABLES}, 1) + ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1) + BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES + else + BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES endif endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts +FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts \ + plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts + +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk diff --git a/plat/arm/board/morello/aarch64/morello_helper.S b/plat/arm/board/morello/aarch64/morello_helper.S new file mode 100644 index 000000000..60470a843 --- /dev/null +++ b/plat/arm/board/morello/aarch64/morello_helper.S @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> +#include <cpu_macros.S> +#include <rainier.h> + +#include <platform_def.h> + + .globl plat_arm_calc_core_pos + .globl plat_reset_handler + + /* ----------------------------------------------------- + * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) + * + * Helper function to calculate the core position. + * ((ChipId * MORELLO_MAX_CLUSTERS_PER_CHIP + ClusterId) * + * MORELLO_MAX_CPUS_PER_CLUSTER * MORELLO_MAX_PE_PER_CPU) + + * (CPUId * MORELLO_MAX_PE_PER_CPU) + ThreadId + * + * which can be simplified as: + * + * (((ChipId * MORELLO_MAX_CLUSTERS_PER_CHIP + ClusterId) * + * MORELLO_MAX_CPUS_PER_CLUSTER + CPUId) * MORELLO_MAX_PE_PER_CPU) + + * ThreadId + * ------------------------------------------------------ + */ + +func plat_arm_calc_core_pos + mov x4, x0 + + /* + * The MT bit in MPIDR is always set for morello and the + * affinity level 0 corresponds to thread affinity level. + */ + + /* Extract individual affinity fields from MPIDR */ + 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, #MORELLO_MAX_CLUSTERS_PER_CHIP + madd x2, x3, x4, x2 + mov x4, #MORELLO_MAX_CPUS_PER_CLUSTER + madd x1, x2, x4, x1 + mov x4, #MORELLO_MAX_PE_PER_CPU + madd x0, x1, x4, x0 + ret +endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/morello/include/plat_macros.S b/plat/arm/board/morello/include/plat_macros.S new file mode 100644 index 000000000..195be8435 --- /dev/null +++ b/plat/arm/board/morello/include/plat_macros.S @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include <css_macros.S> + +/* --------------------------------------------- + * The below required platform porting macro + * prints out relevant platform registers + * whenever an unhandled exception is taken in + * BL31. + * + * There are currently no platform specific regs + * to print. + * --------------------------------------------- + */ + .macro plat_crash_print_regs + .endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h new file mode 100644 index 000000000..9ca75ffe7 --- /dev/null +++ b/plat/arm/board/morello/include/platform_def.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <plat/arm/board/common/v2m_def.h> +#include <plat/arm/common/arm_def.h> +#include <plat/arm/css/common/css_def.h> + +/* UART related constants */ +#define PLAT_ARM_BOOT_UART_BASE ULL(0x2A400000) +#define PLAT_ARM_BOOT_UART_CLK_IN_HZ U(50000000) + +#define PLAT_ARM_RUN_UART_BASE ULL(0x2A410000) +#define PLAT_ARM_RUN_UART_CLK_IN_HZ U(50000000) + +#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE +#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ + +#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0xF80000000) + +/* + * To access the complete DDR memory along with remote chip's DDR memory, + * which is at 4 TB offset, physical and virtual address space limits are + * extended to 43-bits. + */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43) + +#if CSS_USE_SCMI_SDS_DRIVER +#define MORELLO_SCMI_PAYLOAD_BASE ULL(0x45400000) +#else +#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE ULL(0x45400000) +#endif + +#define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00080000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x20000) + +/******************************************************************************* + * MORELLO topology related constants + ******************************************************************************/ +#define MORELLO_MAX_CPUS_PER_CLUSTER U(2) +#define PLAT_ARM_CLUSTER_COUNT U(2) +#define PLAT_MORELLO_CHIP_COUNT U(1) +#define MORELLO_MAX_CLUSTERS_PER_CHIP U(2) +#define MORELLO_MAX_PE_PER_CPU U(1) + +#define PLATFORM_CORE_COUNT (PLAT_MORELLO_CHIP_COUNT * \ + PLAT_ARM_CLUSTER_COUNT * \ + MORELLO_MAX_CPUS_PER_CLUSTER * \ + MORELLO_MAX_PE_PER_CPU) + +/* System power domain level */ +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL3 + +/* + * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#define PLAT_ARM_MMAP_ENTRIES U(9) +#define MAX_XLAT_TABLES U(10) + +#define PLATFORM_STACK_SIZE U(0x400) + +#define PLAT_ARM_NSTIMER_FRAME_ID U(0) +#define PLAT_CSS_MHU_BASE UL(0x45000000) +#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE +#define PLAT_MAX_PWR_LVL U(2) + +#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp) +#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) + +#define MORELLO_DEVICE_BASE ULL(0x08000000) +#define MORELLO_DEVICE_SIZE ULL(0x48000000) + +#define MORELLO_MAP_DEVICE MAP_REGION_FLAT( \ + MORELLO_DEVICE_BASE, \ + MORELLO_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define ARM_MAP_DRAM1 MAP_REGION_FLAT( \ + ARM_DRAM1_BASE, \ + ARM_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x300C0000) + +/* 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/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c new file mode 100644 index 000000000..59dd37b17 --- /dev/null +++ b/plat/arm/board/morello/morello_bl31_setup.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/arm/css/css_mhu_doorbell.h> +#include <drivers/arm/css/scmi.h> +#include <drivers/arm/css/sds.h> +#include <lib/cassert.h> +#include <plat/arm/common/plat_arm.h> + +#include "morello_def.h" +#include <platform_def.h> + +/* + * Platform information structure stored in SDS. + * This structure holds information about platform's DDR + * size which is an information about multichip setup + * - Local DDR size in bytes, DDR memory in master board + * - Remote DDR size in bytes, DDR memory in slave board + * - slave_count + * - multichip mode + */ +struct morello_plat_info { + uint64_t local_ddr_size; + uint64_t remote_ddr_size; + uint8_t slave_count; + bool multichip_mode; +} __packed; + +/* Compile time assertion to ensure the size of structure is 18 bytes */ +CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE, + assert_invalid_plat_info_size); +/* + * BL33 image information structure stored in SDS. + * This structure holds the source & destination addresses and + * the size of the BL33 image which will be loaded by BL31. + */ +struct morello_bl33_info { + uint32_t bl33_src_addr; + uint32_t bl33_dst_addr; + uint32_t bl33_size; +}; + +static scmi_channel_plat_info_t morello_scmi_plat_info = { + .scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE, + .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhu_ring_doorbell +}; + +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) +{ + return &morello_scmi_plat_info; +} + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return css_scmi_override_pm_ops(ops); +} + +static void copy_bl33(uint32_t src, uint32_t dst, uint32_t size) +{ + unsigned int i; + + INFO("Copying BL33 to DDR memory...\n"); + for (i = 0U; i < size; (i = i + 8U)) + mmio_write_64((dst + i), mmio_read_64(src + i)); + + for (i = 0U; i < size; (i = i + 8U)) { + if (mmio_read_64(src + i) != mmio_read_64(dst + i)) { + ERROR("Copy failed!\n"); + panic(); + } + } + INFO("done\n"); +} + +void bl31_platform_setup(void) +{ + int ret; + struct morello_plat_info plat_info; + struct morello_bl33_info bl33_info; + struct morello_plat_info *copy_dest; + + ret = sds_init(); + if (ret != SDS_OK) { + ERROR("SDS initialization failed. ret:%d\n", ret); + panic(); + } + + ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID, + MORELLO_SDS_PLATFORM_INFO_OFFSET, + &plat_info, + MORELLO_SDS_PLATFORM_INFO_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) { + ERROR("Error getting platform info from SDS. ret:%d\n", ret); + panic(); + } + + /* Validate plat_info SDS */ + if ((plat_info.local_ddr_size == 0U) + || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY) + || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY) + || (plat_info.slave_count > MORELLO_MAX_SLAVE_COUNT)) { + ERROR("platform info SDS is corrupted\n"); + panic(); + } + + arm_bl31_platform_setup(); + + ret = sds_struct_read(MORELLO_SDS_BL33_INFO_STRUCT_ID, + MORELLO_SDS_BL33_INFO_OFFSET, + &bl33_info, + MORELLO_SDS_BL33_INFO_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) { + ERROR("Error getting BL33 info from SDS. ret:%d\n", ret); + panic(); + } + copy_bl33(bl33_info.bl33_src_addr, + bl33_info.bl33_dst_addr, + bl33_info.bl33_size); + /* + * Pass platform information to BL33. This method is followed as + * currently there is no BL1/BL2 involved in boot flow of MORELLO. + * When TBBR is implemented for MORELLO, this method should be removed + * and platform information should be passed to BL33 using NT_FW_CONFIG + * passing mechanism. + */ + copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE; + *copy_dest = plat_info; +} diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h new file mode 100644 index 000000000..793729b99 --- /dev/null +++ b/plat/arm/board/morello/morello_def.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MORELLO_DEF_H +#define MORELLO_DEF_H + +/* Non-secure SRAM MMU mapping */ +#define MORELLO_NS_SRAM_BASE UL(0x06000000) +#define MORELLO_NS_SRAM_SIZE UL(0x00010000) +#define MORELLO_MAP_NS_SRAM MAP_REGION_FLAT( \ + MORELLO_NS_SRAM_BASE, \ + MORELLO_NS_SRAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* SDS Platform information defines */ +#define MORELLO_SDS_PLATFORM_INFO_STRUCT_ID U(8) +#define MORELLO_SDS_PLATFORM_INFO_OFFSET U(0) +#define MORELLO_SDS_PLATFORM_INFO_SIZE U(18) +#define MORELLO_MAX_DDR_CAPACITY U(0x1000000000) +#define MORELLO_MAX_SLAVE_COUNT U(16) + +/* SDS BL33 image information defines */ +#define MORELLO_SDS_BL33_INFO_STRUCT_ID U(9) +#define MORELLO_SDS_BL33_INFO_OFFSET U(0) +#define MORELLO_SDS_BL33_INFO_SIZE U(12) + +/* Base address of non-secure SRAM where Platform information will be filled */ +#define MORELLO_PLATFORM_INFO_BASE UL(0x06000000) + +#endif /* MORELLO_DEF_H */ diff --git a/plat/arm/board/morello/morello_interconnect.c b/plat/arm/board/morello/morello_interconnect.c new file mode 100644 index 000000000..d941bfe0f --- /dev/null +++ b/plat/arm/board/morello/morello_interconnect.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +/* + * For MORELLO which supports FCM (with automatic interconnect enter/exit), + * we should not do anything in these interface functions. + * They are used to override the weak functions in cci drivers. + */ + +/****************************************************************************** + * Helper function to initialize ARM interconnect driver. + *****************************************************************************/ +void plat_arm_interconnect_init(void) +{ +} + +/****************************************************************************** + * Helper function to place current master into coherency + *****************************************************************************/ +void plat_arm_interconnect_enter_coherency(void) +{ +} + +/****************************************************************************** + * Helper function to remove current master from coherency + *****************************************************************************/ +void plat_arm_interconnect_exit_coherency(void) +{ +} diff --git a/plat/arm/board/morello/morello_plat.c b/plat/arm/board/morello/morello_plat.c new file mode 100644 index 000000000..3830687a3 --- /dev/null +++ b/plat/arm/board/morello/morello_plat.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +#include "morello_def.h" + +/* + * Table of regions to map using the MMU. + * Replace or extend the below regions as required + */ + +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + MORELLO_MAP_DEVICE, + MORELLO_MAP_NS_SRAM, + ARM_MAP_DRAM1, + {0} +}; diff --git a/plat/arm/board/morello/morello_security.c b/plat/arm/board/morello/morello_security.c new file mode 100644 index 000000000..a388a8099 --- /dev/null +++ b/plat/arm/board/morello/morello_security.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * TZC programming is currently not done. + */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/board/morello/morello_topology.c b/plat/arm/board/morello/morello_topology.c new file mode 100644 index 000000000..ef2f7534f --- /dev/null +++ b/plat/arm/board/morello/morello_topology.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/cassert.h> +#include <plat/arm/common/plat_arm.h> + +/* Compile time assertion to ensure the core count is 4 */ +CASSERT(PLATFORM_CORE_COUNT == 4U, assert_invalid_platform_core_count); + +/* Topology */ +typedef struct morello_topology { + const unsigned char *power_tree; + unsigned int plat_cluster_core_count; +} morello_topology_t; + +/* + * The power domain tree descriptor. The cluster power domains are + * arranged so that when the PSCI generic code creates the power domain tree, + * the indices of the CPU power domain nodes it allocates match the linear + * indices returned by plat_core_pos_by_mpidr(). + */ +const unsigned char morello_pd_tree_desc[] = { + PLAT_MORELLO_CHIP_COUNT, + PLAT_ARM_CLUSTER_COUNT, + MORELLO_MAX_CPUS_PER_CLUSTER, + MORELLO_MAX_CPUS_PER_CLUSTER, +}; + +/* Topology configuration for morello */ +const morello_topology_t morello_topology = { + .power_tree = morello_pd_tree_desc, + .plat_cluster_core_count = MORELLO_MAX_CPUS_PER_CLUSTER +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return morello_topology.power_tree; +} + +/******************************************************************************* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + ******************************************************************************/ +unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) +{ + return morello_topology.plat_cluster_core_count; +} + +/******************************************************************************* + * 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[PLATFORM_CORE_COUNT] = { + 0, 1, 2, 3}; diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk new file mode 100644 index 000000000..fc7d4d363 --- /dev/null +++ b/plat/arm/board/morello/platform.mk @@ -0,0 +1,67 @@ +# +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +MORELLO_BASE := plat/arm/board/morello + +INTERCONNECT_SOURCES := ${MORELLO_BASE}/morello_interconnect.c + +PLAT_INCLUDES := -I${MORELLO_BASE}/include + +MORELLO_CPU_SOURCES := lib/cpus/aarch64/rainier.S + +# GIC-600 configuration +GICV3_SUPPORT_GIC600 := 1 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +MORELLO_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/arm/common/arm_gicv3.c \ + +PLAT_BL_COMMON_SOURCES := ${MORELLO_BASE}/morello_plat.c \ + ${MORELLO_BASE}/aarch64/morello_helper.S + +BL31_SOURCES := ${MORELLO_CPU_SOURCES} \ + ${INTERCONNECT_SOURCES} \ + ${MORELLO_GIC_SOURCES} \ + ${MORELLO_BASE}/morello_bl31_setup.c \ + ${MORELLO_BASE}/morello_topology.c \ + ${MORELLO_BASE}/morello_security.c \ + drivers/arm/css/sds/sds.c + +FDT_SOURCES += fdts/morello-fvp.dts + +# TF-A not required to load the SCP Images +override CSS_LOAD_SCP_IMAGES := 0 + +# BL1/BL2 Image not a part of the capsule Image for morello +override NEED_BL1 := no +override NEED_BL2 := no +override NEED_BL2U := no + +#TF-A for morello starts from BL31 +override RESET_TO_BL31 := 1 + +# 32 bit mode not supported +override CTX_INCLUDE_AARCH32_REGS := 0 + +override ARM_PLAT_MT := 1 + +# Select SCMI/SDS drivers instead of SCPI/BOM driver for communicating with the +# SCP during power management operations and for SCP RAM Firmware transfer. +CSS_USE_SCMI_SDS_DRIVER := 1 + +# System coherency is managed in hardware +HW_ASSISTED_COHERENCY := 1 + +# When building for systems with hardware-assisted coherency, there's no need to +# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too. +USE_COHERENT_MEM := 0 + +include plat/arm/common/arm_common.mk +include plat/arm/css/common/css_common.mk +include plat/arm/board/common/board_common.mk diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index 6a309e8e1..cc07852c2 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 b150b8959..d7003e951 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 */ @@ -63,8 +63,8 @@ static struct gic600_multichip_data n1sdp_multichip_data __init = { PLAT_ARM_GICD_BASE >> 16 }, .spi_ids = { - {32, 255}, - {0, 0} + {32, 479}, + {512, 959} } }; @@ -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/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 8816670dc..f20397acd 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/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 # @@ -14,14 +14,16 @@ PLAT_INCLUDES := -I${N1SDP_BASE}/include N1SDP_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S +# GIC-600 configuration +GICV3_SUPPORT_GIC600 := 1 +GICV3_IMPL_GIC600_MULTICHIP := 1 -N1SDP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gic600_multichip.c \ +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +N1SDP_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ - drivers/arm/gic/v3/gic600.c PLAT_BL_COMMON_SOURCES := ${N1SDP_BASE}/n1sdp_plat.c \ ${N1SDP_BASE}/aarch64/n1sdp_helper.S @@ -36,6 +38,8 @@ BL31_SOURCES := ${N1SDP_CPU_SOURCES} \ ${N1SDP_BASE}/n1sdp_security.c \ drivers/arm/css/sds/sds.c +FDT_SOURCES += fdts/${PLAT}-single-chip.dts \ + fdts/${PLAT}-multi-chip.dts # TF-A not required to load the SCP Images override CSS_LOAD_SCP_IMAGES := 0 @@ -63,6 +67,9 @@ HW_ASSISTED_COHERENCY := 1 # When building for systems with hardware-assisted coherency, there's no need to # use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too. USE_COHERENT_MEM := 0 + +# Enable the flag since N1SDP has a system level cache +NEOVERSE_Nx_EXTERNAL_LLC := 1 include plat/arm/common/arm_common.mk include plat/arm/css/common/css_common.mk include plat/arm/board/common/board_common.mk diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts new file mode 100644 index 000000000..69fb0d498 --- /dev/null +++ b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = <NT_FW_CONFIG_ID>; + }; + }; +}; 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 41769217a..0af821e15 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/fdts/rde1edge_tb_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts index 766dc00f5..dba91e535 100644 --- a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2020, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,19 +7,22 @@ /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>; + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * 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/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h index 2be3f8852..c39fe2b69 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 */ @@ -9,14 +9,13 @@ #include <lib/utils_def.h> -#include <sgi_base_platform_def.h> +#include <sgi_soc_platform_def.h> #define PLAT_ARM_CLUSTER_COUNT U(2) #define CSS_SGI_MAX_CPUS_PER_CLUSTER U(8) #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 43c37ffc1..53074f495 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -12,6 +12,8 @@ PLAT_INCLUDES += -I${RDE1EDGE_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_e1.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${RDE1EDGE_BASE}/rde1edge_err.c @@ -29,17 +31,31 @@ 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 +FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) FDT_SOURCES += ${RDE1EDGE_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)) +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--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_err.c b/plat/arm/board/rde1edge/rde1edge_err.c index e344d8268..c72c18ced 100644 --- a/plat/arm/board/rde1edge/rde1edge_err.c +++ b/plat/arm/board/rde1edge/rde1edge_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c index a1b8d621d..44d818aec 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 0b56f208a..a16283e45 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 000000000..4592b8fba --- /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(cookie, key_ptr, key_len, flags); +} diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts new file mode 100644 index 000000000..d3b7fba49 --- /dev/null +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = <NT_FW_CONFIG_ID>; + }; + }; +}; + 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 fff587476..68366c5ca 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/fdts/rdn1edge_tb_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts index b14d7adca..257ef4a3f 100644 --- a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts @@ -1,25 +1,27 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * 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>; + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * 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/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h index c635faa44..b167c46e0 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 */ @@ -9,14 +9,13 @@ #include <lib/utils_def.h> -#include <sgi_base_platform_def.h> +#include <sgi_soc_platform_def.h> #define PLAT_ARM_CLUSTER_COUNT U(2) #define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4) #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 ca1e95eaf..d65854f8d 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -4,6 +4,9 @@ # SPDX-License-Identifier: BSD-3-Clause # +# GIC-600 configuration +GICV3_IMPL_GIC600_MULTICHIP := 1 + include plat/arm/css/sgi/sgi-common.mk RDN1EDGE_BASE = plat/arm/board/rdn1edge @@ -12,6 +15,8 @@ PLAT_INCLUDES += -I${RDN1EDGE_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${RDN1EDGE_BASE}/rdn1edge_err.c @@ -29,17 +34,35 @@ 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 += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +endif + +# Enable dynamic addition of MMAP regions in BL31 +BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC + # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts +FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) FDT_SOURCES += ${RDN1EDGE_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)) +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG})) + +$(eval $(call CREATE_SEQ,SEQ,2)) +ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ))) + $(error "Chip count for RDN1Edge platform should be one of $(SEQ), currently \ + set to ${CSS_SGI_CHIP_COUNT}.") +endif override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rdn1edge/rdn1edge_err.c b/plat/arm/board/rdn1edge/rdn1edge_err.c index cdcbf256a..46d318c7b 100644 --- a/plat/arm/board/rdn1edge/rdn1edge_err.c +++ b/plat/arm/board/rdn1edge/rdn1edge_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c index 3b7e5ee4e..1dbbf26da 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_soc_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 687ae3595..5bbea6998 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 000000000..4592b8fba --- /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(cookie, key_ptr, key_len, flags); +} diff --git a/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts new file mode 100644 index 000000000..9c9cefe87 --- /dev/null +++ b/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = <NT_FW_CONFIG_ID>; + }; + }; +}; diff --git a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts new file mode 100644 index 000000000..bbc36fc14 --- /dev/null +++ b/plat/arm/board/rdn2/fdts/rdn2_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-n2"; + + /* + * 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/rdn2/fdts/rdn2_tb_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * 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/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h new file mode 100644 index 000000000..3f753f73f --- /dev/null +++ b/plat/arm/board/rdn2/include/platform_def.h @@ -0,0 +1,65 @@ +/* + * 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_soc_platform_def_v2.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(0x2A920000) +#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 + +/* TZC Related Constants */ +#define PLAT_ARM_TZC_BASE UL(0x10720000) +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) + +#define TZC400_OFFSET UL(0x1000000) +#define TZC400_COUNT U(8) + +#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \ + (n * TZC400_OFFSET)) + +#define TZC_NSAID_ALL_AP U(0) +#define TZC_NSAID_PCI U(1) +#define TZC_NSAID_HDLCD0 U(2) +#define TZC_NSAID_CLCD U(7) +#define TZC_NSAID_AP U(9) +#define TZC_NSAID_VIRTIO U(15) + +#define PLAT_ARM_TZC_NS_DEV_ACCESS \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO)) + +/* + * 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(0x301C0000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk new file mode 100644 index 000000000..03771dc3d --- /dev/null +++ b/plat/arm/board/rdn2/platform.mk @@ -0,0 +1,60 @@ +# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# RD-N2 platform uses GIC-Clayton which is based on GICv4.1 +GIC_ENABLE_V4_EXTN := 1 + +include plat/arm/css/sgi/sgi-common.mk + +RDN2_BASE = plat/arm/board/rdn2 + +PLAT_INCLUDES += -I${RDN2_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_n2.S + +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat_v2.c + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDN2_BASE}/rdn2_err.c + +BL2_SOURCES += ${RDN2_BASE}/rdn2_plat.c \ + ${RDN2_BASE}/rdn2_security.c \ + ${RDN2_BASE}/rdn2_err.c \ + lib/utils/mem_region.c \ + drivers/arm/tzc/tzc400.c \ + plat/arm/common/arm_tzc400.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDN2_BASE}/rdn2_plat.c \ + ${RDN2_BASE}/rdn2_topology.c \ + 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 += ${RDN2_BASE}/rdn2_trusted_boot.c +BL2_SOURCES += ${RDN2_BASE}/rdn2_trusted_boot.c +endif + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDN2_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDN2_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) + +FDT_SOURCES += ${RDN2_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 +override ENABLE_AMU := 1 diff --git a/plat/arm/board/rdn2/rdn2_err.c b/plat/arm/board/rdn2/rdn2_err.c new file mode 100644 index 000000000..802ac21f6 --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_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> + +/* + * rdn2 error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (1) { + wfi(); + } +} diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c new file mode 100644 index 000000000..5bf14e3a1 --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_plat.c @@ -0,0 +1,31 @@ +/* + * 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/rdn2/rdn2_security.c b/plat/arm/board/rdn2/rdn2_security.c new file mode 100644 index 000000000..9568b60cd --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_security.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> +#include <platform_def.h> + + +static const arm_tzc_regions_info_t tzc_regions[] = { + ARM_TZC_REGIONS_DEF, + {} +}; + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ + + int i; + + for (i = 0; i < TZC400_COUNT; i++) + arm_tzc400_setup(TZC400_BASE(i), tzc_regions); + +} diff --git a/plat/arm/board/rdn2/rdn2_topology.c b/plat/arm/board/rdn2/rdn2_topology.c new file mode 100644 index 000000000..5c2e287cb --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_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_n2_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_n2_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/rdn2/rdn2_trusted_boot.c b/plat/arm/board/rdn2/rdn2_trusted_boot.c new file mode 100644 index 000000000..4592b8fba --- /dev/null +++ b/plat/arm/board/rdn2/rdn2_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(cookie, key_ptr, key_len, flags); +} diff --git a/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts new file mode 100644 index 000000000..9c9cefe87 --- /dev/null +++ b/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = <NT_FW_CONFIG_ID>; + }; + }; +}; diff --git a/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts new file mode 100644 index 000000000..62ba2c3f2 --- /dev/null +++ b/plat/arm/board/rdv1/fdts/rdv1_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-v1"; + + /* + * 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/rdv1/fdts/rdv1_tb_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * 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/rdv1/include/platform_def.h b/plat/arm/board/rdv1/include/platform_def.h new file mode 100644 index 000000000..5b98b4e8c --- /dev/null +++ b/plat/arm/board/rdv1/include/platform_def.h @@ -0,0 +1,65 @@ +/* + * 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_soc_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 + +/* TZC Related Constants */ +#define PLAT_ARM_TZC_BASE UL(0x21830000) +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) + +#define TZC400_OFFSET UL(0x1000000) +#define TZC400_COUNT 4 + +#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \ + (n * TZC400_OFFSET)) + +#define TZC_NSAID_ALL_AP U(0) +#define TZC_NSAID_PCI U(1) +#define TZC_NSAID_HDLCD0 U(2) +#define TZC_NSAID_CLCD U(7) +#define TZC_NSAID_AP U(9) +#define TZC_NSAID_VIRTIO U(15) + +#define PLAT_ARM_TZC_NS_DEV_ACCESS \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO)) + +/* + * 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/rdv1/platform.mk b/plat/arm/board/rdv1/platform.mk new file mode 100644 index 000000000..2ffd139c9 --- /dev/null +++ b/plat/arm/board/rdv1/platform.mk @@ -0,0 +1,60 @@ +# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# RD-V1 platform uses GIC-Clayton which is based on GICv4.1 +GIC_ENABLE_V4_EXTN := 1 + +include plat/arm/css/sgi/sgi-common.mk + +RDV1_BASE = plat/arm/board/rdv1 + +PLAT_INCLUDES += -I${RDV1_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S + +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDV1_BASE}/rdv1_err.c + +BL2_SOURCES += ${RDV1_BASE}/rdv1_plat.c \ + ${RDV1_BASE}/rdv1_security.c \ + ${RDV1_BASE}/rdv1_err.c \ + lib/utils/mem_region.c \ + drivers/arm/tzc/tzc400.c \ + plat/arm/common/arm_tzc400.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDV1_BASE}/rdv1_plat.c \ + ${RDV1_BASE}/rdv1_topology.c \ + 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 += ${RDV1_BASE}/rdv1_trusted_boot.c +BL2_SOURCES += ${RDV1_BASE}/rdv1_trusted_boot.c +endif + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDV1_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDV1_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) + +FDT_SOURCES += ${RDV1_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,${NT_FW_CONFIG})) + +override CTX_INCLUDE_AARCH32_REGS := 0 +override ENABLE_AMU := 1 diff --git a/plat/arm/board/rdv1/rdv1_err.c b/plat/arm/board/rdv1/rdv1_err.c new file mode 100644 index 000000000..68f9a3ef6 --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_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> + +/* + * rdv1 error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (1) { + wfi(); + } +} diff --git a/plat/arm/board/rdv1/rdv1_plat.c b/plat/arm/board/rdv1/rdv1_plat.c new file mode 100644 index 000000000..ab5251e51 --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_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/rdv1/rdv1_security.c b/plat/arm/board/rdv1/rdv1_security.c new file mode 100644 index 000000000..1247db860 --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_security.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> +#include <platform_def.h> + +static const arm_tzc_regions_info_t tzc_regions[] = { + ARM_TZC_REGIONS_DEF, + {} +}; + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ + int i; + + for (i = 0; i < TZC400_COUNT; i++) + arm_tzc400_setup(TZC400_BASE(i), tzc_regions); +} diff --git a/plat/arm/board/rdv1/rdv1_topology.c b/plat/arm/board/rdv1/rdv1_topology.c new file mode 100644 index 000000000..ab64fd8d0 --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_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_v1_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_v1_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/rdv1/rdv1_trusted_boot.c b/plat/arm/board/rdv1/rdv1_trusted_boot.c new file mode 100644 index 000000000..4592b8fba --- /dev/null +++ b/plat/arm/board/rdv1/rdv1_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(cookie, key_ptr, key_len, flags); +} diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts new file mode 100644 index 000000000..9c9cefe87 --- /dev/null +++ b/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = <NT_FW_CONFIG_ID>; + }; + }; +}; diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts new file mode 100644 index 000000000..71c7db3cb --- /dev/null +++ b/plat/arm/board/rdv1mc/fdts/rdv1mc_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-v1-mc"; + + /* + * 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/rdv1mc/fdts/rdv1mc_tb_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts new file mode 100644 index 000000000..49eda2735 --- /dev/null +++ b/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * 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/rdv1mc/include/platform_def.h b/plat/arm/board/rdv1mc/include/platform_def.h new file mode 100644 index 000000000..112b2102b --- /dev/null +++ b/plat/arm/board/rdv1mc/include/platform_def.h @@ -0,0 +1,37 @@ +/* + * 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_soc_platform_def.h> + +#define PLAT_ARM_CLUSTER_COUNT U(4) +#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 + +/* 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 mode */ +#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \ + CSS_SGI_CHIP_COUNT) +#define PLAT_VIRT_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \ + CSS_SGI_CHIP_COUNT) + +/* 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/rdv1mc/platform.mk b/plat/arm/board/rdv1mc/platform.mk new file mode 100644 index 000000000..50728416a --- /dev/null +++ b/plat/arm/board/rdv1mc/platform.mk @@ -0,0 +1,68 @@ +# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Enable GICv4 extension with multichip driver +GIC_ENABLE_V4_EXTN := 1 +GICV3_IMPL_GIC600_MULTICHIP := 1 + +include plat/arm/css/sgi/sgi-common.mk + +RDV1MC_BASE = plat/arm/board/rdv1mc + +PLAT_INCLUDES += -I${RDV1MC_BASE}/include/ + +SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S + +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + +BL1_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDV1MC_BASE}/rdv1mc_err.c + +BL2_SOURCES += ${RDV1MC_BASE}/rdv1mc_plat.c \ + ${RDV1MC_BASE}/rdv1mc_security.c \ + ${RDV1MC_BASE}/rdv1mc_err.c \ + lib/utils/mem_region.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${SGI_CPU_SOURCES} \ + ${RDV1MC_BASE}/rdv1mc_plat.c \ + ${RDV1MC_BASE}/rdv1mc_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 += ${RDV1MC_BASE}/rdv1mc_trusted_boot.c +BL2_SOURCES += ${RDV1MC_BASE}/rdv1mc_trusted_boot.c +endif + +# Enable dynamic addition of MMAP regions in BL31 +BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC + +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${RDV1MC_BASE}/fdts/${PLAT}_fw_config.dts \ + ${RDV1MC_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) + +$(eval $(call CREATE_SEQ,SEQ,4)) +ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ))) + $(error "Chip count for RD-V1-MC should be either $(SEQ) \ + currently it is set to ${CSS_SGI_CHIP_COUNT}.") +endif + +FDT_SOURCES += ${RDV1MC_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,${NT_FW_CONFIG})) + +override CTX_INCLUDE_AARCH32_REGS := 0 diff --git a/plat/arm/board/rdv1mc/rdv1mc_err.c b/plat/arm/board/rdv1mc/rdv1mc_err.c new file mode 100644 index 000000000..755a5034e --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_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> + +/* + * rdv1mc error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (true) { + wfi(); + } +} diff --git a/plat/arm/board/rdv1mc/rdv1mc_plat.c b/plat/arm/board/rdv1mc/rdv1mc_plat.c new file mode 100644 index 000000000..d85940066 --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_plat.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 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_soc_platform_def.h> +#include <sgi_plat.h> + +#if defined(IMAGE_BL31) +static const mmap_region_t rdv1mc_dynamic_mmap[] = { + ARM_MAP_SHARED_RAM_REMOTE_CHIP(1), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1), +#if (CSS_SGI_CHIP_COUNT > 2) + ARM_MAP_SHARED_RAM_REMOTE_CHIP(2), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(2), +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + ARM_MAP_SHARED_RAM_REMOTE_CHIP(3), + CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3), + SOC_CSS_MAP_DEVICE_REMOTE_CHIP(3) +#endif +}; + +static struct gic600_multichip_data rdv1mc_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, +#if (CSS_SGI_CHIP_COUNT > 2) + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, +#endif + }, + .spi_ids = { + {32, 255}, + {0, 0}, +#if (CSS_SGI_CHIP_COUNT > 2) + {0, 0}, +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + {0, 0}, +#endif + } +}; + +static uintptr_t rdv1mc_multichip_gicr_frames[] = { + /* Chip 0's GICR Base */ + PLAT_ARM_GICR_BASE, + /* Chip 1's GICR BASE */ + PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), +#if (CSS_SGI_CHIP_COUNT > 2) + /* Chip 2's GICR BASE */ + PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2), +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + /* Chip 3's GICR BASE */ + PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3), +#endif + UL(0) /* Zero Termination */ +}; +#endif /* IMAGE_BL31 */ + +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; +} + +/* + * bl31_platform_setup_function is guarded by IMAGE_BL31 macro 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 ret; + unsigned int i; + + if ((plat_arm_sgi_get_multi_chip_mode() == 0) && + (CSS_SGI_CHIP_COUNT > 1)) { + ERROR("Chip Count is set to %u but multi-chip mode is 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-V1-MC\n"); + + for (i = 0; i < ARRAY_SIZE(rdv1mc_dynamic_mmap); i++) { + ret = mmap_add_dynamic_region( + rdv1mc_dynamic_mmap[i].base_pa, + rdv1mc_dynamic_mmap[i].base_va, + rdv1mc_dynamic_mmap[i].size, + rdv1mc_dynamic_mmap[i].attr); + if (ret != 0) { + ERROR("Failed to add dynamic mmap entry " + "(ret=%d)\n", ret); + panic(); + } + } + + plat_arm_override_gicr_frames( + rdv1mc_multichip_gicr_frames); + gic600_multichip_init(&rdv1mc_multichip_data); + } + + sgi_bl31_common_platform_setup(); +} +#endif /* IMAGE_BL31 */ diff --git a/plat/arm/board/rdv1mc/rdv1mc_security.c b/plat/arm/board/rdv1mc/rdv1mc_security.c new file mode 100644 index 000000000..541f800a8 --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_security.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ +} diff --git a/plat/arm/board/rdv1mc/rdv1mc_topology.c b/plat/arm/board/rdv1mc/rdv1mc_topology.c new file mode 100644 index 000000000..4486e5cfa --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_topology.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/arm/css/common/css_pm.h> +#include <sgi_variant.h> + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +const unsigned char rd_v1_mc_pd_tree_desc_multi_chip[] = { + ((PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_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, +#if (CSS_SGI_CHIP_COUNT > 1) + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#endif +#if (CSS_SGI_CHIP_COUNT > 2) + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +#endif +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + if (plat_arm_sgi_get_multi_chip_mode() == 1) + return rd_v1_mc_pd_tree_desc_multi_chip; + panic(); +} + +/******************************************************************************* + * 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)), +#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)), +#endif +#if (CSS_SGI_CHIP_COUNT > 2) + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)), +#endif +#if (CSS_SGI_CHIP_COUNT > 3) + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)), + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)), + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)), + (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x3)) +#endif +}; diff --git a/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c b/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c new file mode 100644 index 000000000..4592b8fba --- /dev/null +++ b/plat/arm/board/rdv1mc/rdv1mc_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(cookie, key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts new file mode 100644 index 000000000..84fc1ad5f --- /dev/null +++ b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + + nt_fw-config { + load-address = <0x0 0xFEF00000>; + max-size = <0x0100000>; + id = <NT_FW_CONFIG_ID>; + }; + }; +}; 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 1e1ea14b0..260247a0d 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/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts index b14d7adca..49eda2735 100644 --- a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts +++ b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,19 +7,22 @@ /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>; + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * 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/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h index fd59e5277..c929334cd 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 */ @@ -9,14 +9,13 @@ #include <lib/utils_def.h> -#include <sgi_base_platform_def.h> +#include <sgi_soc_platform_def.h> #define PLAT_ARM_CLUSTER_COUNT U(2) #define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4) #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 ce2717fe0..89abcfe8e 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -12,6 +12,8 @@ PLAT_INCLUDES += -I${SGI575_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/cortex_a75.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c + BL1_SOURCES += ${SGI_CPU_SOURCES} \ ${SGI575_BASE}/sgi575_err.c @@ -29,15 +31,30 @@ 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 +FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_fw_config.dts \ + ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts + +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) # Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) FDT_SOURCES += ${SGI575_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)) +$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--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_err.c b/plat/arm/board/sgi575/sgi575_err.c index c1cc1a7fd..21bfcb73a 100644 --- a/plat/arm/board/sgi575/sgi575_err.c +++ b/plat/arm/board/sgi575/sgi575_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/sgi575/sgi575_plat.c index 0d3fd16ab..dc294e6a8 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 000000000..4592b8fba --- /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(cookie, key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts new file mode 100644 index 000000000..5d478e9a5 --- /dev/null +++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x200>; + id = <TB_FW_CONFIG_ID>; + }; + }; +}; diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts index 95025493b..49eda2735 100644 --- a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts +++ b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,10 +7,22 @@ /dts-v1/; / { - /* Platform Config */ - plat_arm_bl2 { + tb_fw-config { compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x83000000>; - hw_config_max_size = <0x01000000>; + + /* Disable authentication for development */ + disable_auth = <0x0>; + + /* + * 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/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h index d165ff9ed..e83cd5764 100644 --- a/plat/arm/board/sgm775/include/platform_def.h +++ b/plat/arm/board/sgm775/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 */ @@ -12,6 +12,9 @@ #define PLAT_MAX_CPUS_PER_CLUSTER U(8) #define PLAT_MAX_PE_PER_CPU U(1) +#define PLAT_ARM_DRAM2_BASE ULL(0x880000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) + /* * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes */ diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index 7a843c369..a649939de 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 # @@ -8,7 +8,16 @@ include plat/arm/css/sgm/sgm-common.mk SGM775_BASE= plat/arm/board/sgm775 -FDT_SOURCES += ${SGM775_BASE}/fdts/sgm775_tb_fw_config.dts +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts \ + ${SGM775_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) PLAT_INCLUDES +=-I${SGM775_BASE}/include/ @@ -21,3 +30,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_err.c b/plat/arm/board/sgm775/sgm775_err.c index e1e05860d..dc114f07f 100644 --- a/plat/arm/board/sgm775/sgm775_err.c +++ b/plat/arm/board/sgm775/sgm775_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ */ void __dead2 plat_arm_error_handler(int err) { - while (1) { + while (true) { wfi(); } } 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 000000000..4592b8fba --- /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(cookie, key_ptr, key_len, flags); +} diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts new file mode 100644 index 000000000..4b6abd4d1 --- /dev/null +++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/tbbr/tbbr_img_def.h> + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + tb_fw-config { + load-address = <0x0 0x4001300>; + max-size = <0x400>; + id = <TB_FW_CONFIG_ID>; + }; + + tos_fw-config { + load-address = <0x0 0x04001700>; + max-size = <0x1000>; + id = <TOS_FW_CONFIG_ID>; + }; + + hw-config { + load-address = <0x0 0x83000000>; + max-size = <0x01000000>; + id = <HW_CONFIG_ID>; + }; + }; +}; diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts new file mode 100644 index 000000000..2f459b013 --- /dev/null +++ b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/dts-v1/; + +/ { + compatible = "arm,ffa-core-manifest-1.0"; + #address-cells = <2>; + #size-cells = <1>; + + attribute { + spmc_id = <0x8000>; + maj_ver = <0x1>; + min_ver = <0x0>; + exec_state = <0x0>; + load_address = <0x0 0xfd000000>; + entrypoint = <0x0 0xfd000000>; + binary_size = <0x80000>; + }; + + hypervisor { + compatible = "hafnium,hafnium"; + vm1 { + is_ffa_partition; + debug_name = "cactus-primary"; + load_address = <0xfe000000>; + vcpu_count = <8>; + mem_size = <1048576>; + }; + vm2 { + is_ffa_partition; + debug_name = "cactus-secondary"; + load_address = <0xfe100000>; + vcpu_count = <8>; + mem_size = <1048576>; + }; + vm3 { + is_ffa_partition; + debug_name = "cactus-tertiary"; + load_address = <0xfe200000>; + vcpu_count = <8>; + mem_size = <1048576>; + }; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + CPU0:cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + + /* + * SPMC (Hafnium) requires secondary cpu nodes are declared in + * descending order + */ + CPU7:cpu@700 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x700>; + enable-method = "psci"; + }; + + CPU6:cpu@600 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x600>; + enable-method = "psci"; + }; + + CPU5:cpu@500 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x500>; + enable-method = "psci"; + }; + + CPU4:cpu@400 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x400>; + enable-method = "psci"; + }; + + CPU3:cpu@300 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x300>; + enable-method = "psci"; + }; + + CPU2:cpu@200 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x200>; + enable-method = "psci"; + }; + + CPU1:cpu@100 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x100>; + enable-method = "psci"; + }; + }; + + /* 32MB of TC0_TZC_DRAM1_BASE */ + memory@fd000000 { + device_type = "memory"; + reg = <0x0 0xfd000000 0x2000000>; + }; +}; diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts new file mode 100644 index 000000000..221039c43 --- /dev/null +++ b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/dts-v1/; + +/ { + compatible = "arm,ffa-core-manifest-1.0"; + #address-cells = <2>; + #size-cells = <1>; + + attribute { + spmc_id = <0x8000>; + maj_ver = <0x1>; + min_ver = <0x0>; + exec_state = <0x0>; + load_address = <0x0 0xfd000000>; + entrypoint = <0x0 0xfd000000>; + binary_size = <0x80000>; + }; + + hypervisor { + compatible = "hafnium,hafnium"; + vm1 { + is_ffa_partition; + debug_name = "op-tee"; + load_address = <0xfd280000>; + vcpu_count = <8>; + mem_size = <30928896>; /* 32MB TZC DRAM - SPMC region */ + }; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + CPU0:cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + + /* + * SPMC (Hafnium) requires secondary cpu nodes are declared in + * descending order + */ + CPU7:cpu@700 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x700>; + enable-method = "psci"; + }; + + CPU6:cpu@600 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x600>; + enable-method = "psci"; + }; + + CPU5:cpu@500 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x500>; + enable-method = "psci"; + }; + + CPU4:cpu@400 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x400>; + enable-method = "psci"; + }; + + CPU3:cpu@300 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x300>; + enable-method = "psci"; + }; + + CPU2:cpu@200 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x200>; + enable-method = "psci"; + }; + + CPU1:cpu@100 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x100>; + enable-method = "psci"; + }; + }; + + /* 32MB of TC0_TZC_DRAM1_BASE */ + memory@fd000000 { + device_type = "memory"; + reg = <0x0 0xfd000000 0x2000000>; + }; +}; diff --git a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts new file mode 100644 index 000000000..de5f95d5e --- /dev/null +++ b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * 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>; + }; + + secure-partitions { + compatible = "arm,sp"; +#if OPTEE_SP_FW_CONFIG + op-tee { + uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>; + load-address = <0xfd280000>; + }; +#else + cactus-primary { + uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>; + load-address = <0xfe000000>; + owner = "SiP"; + }; + + cactus-secondary { + uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>; + load-address = <0xfe100000>; + owner = "Plat"; + }; + + cactus-tertiary { + uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>; + load-address = <0xfe200000>; + }; +#endif + }; +}; diff --git a/plat/arm/board/tc0/include/plat_macros.S b/plat/arm/board/tc0/include/plat_macros.S new file mode 100644 index 000000000..6006fa5b8 --- /dev/null +++ b/plat/arm/board/tc0/include/plat_macros.S @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include <arm_macros.S> + +/* --------------------------------------------- + * The below required platform porting macro + * prints out relevant platform registers + * whenever an unhandled exception is taken in + * BL31. + * + * There are currently no platform specific regs + * to print. + * --------------------------------------------- + */ + .macro plat_crash_print_regs + .endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h new file mode 100644 index 000000000..30b5ab716 --- /dev/null +++ b/plat/arm/board/tc0/include/platform_def.h @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <lib/utils_def.h> +#include <lib/xlat_tables/xlat_tables_defs.h> +#include <plat/arm/board/common/board_css_def.h> +#include <plat/arm/board/common/v2m_def.h> +#include <plat/arm/common/arm_def.h> +#include <plat/arm/common/arm_spm_def.h> +#include <plat/arm/css/common/css_def.h> +#include <plat/arm/soc/common/soc_css_def.h> +#include <plat/common/common_def.h> + +#define PLATFORM_CORE_COUNT 8 + +#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */ + +/* + * The top 16MB of ARM_DRAM1 is configured as secure access only using the TZC, + * its base is ARM_AP_TZC_DRAM1_BASE. + * + * Reserve 32MB below ARM_AP_TZC_DRAM1_BASE for: + * - BL32_BASE when SPD_spmd is enabled + * - Region to load Trusted OS + */ +#define TC0_TZC_DRAM1_BASE (ARM_AP_TZC_DRAM1_BASE - \ + TC0_TZC_DRAM1_SIZE) +#define TC0_TZC_DRAM1_SIZE UL(0x02000000) /* 32 MB */ +#define TC0_TZC_DRAM1_END (TC0_TZC_DRAM1_BASE + \ + TC0_TZC_DRAM1_SIZE - 1) + +#define TC0_NS_DRAM1_BASE ARM_DRAM1_BASE +#define TC0_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \ + ARM_TZC_DRAM1_SIZE - \ + TC0_TZC_DRAM1_SIZE) +#define TC0_NS_DRAM1_END (TC0_NS_DRAM1_BASE + \ + TC0_NS_DRAM1_SIZE - 1) + +/* + * Mappings for TC0 DRAM1 (non-secure) and TC0 TZC DRAM1 (secure) + */ +#define TC0_MAP_NS_DRAM1 MAP_REGION_FLAT( \ + TC0_NS_DRAM1_BASE, \ + TC0_NS_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + + +#define TC0_MAP_TZC_DRAM1 MAP_REGION_FLAT( \ + TC0_TZC_DRAM1_BASE, \ + TC0_TZC_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) +/* + * Max size of SPMC is 2MB for tc0. With SPMD enabled this value corresponds to + * max size of BL32 image. + */ +#if defined(SPD_spmd) +#define PLAT_ARM_SPMC_BASE TC0_TZC_DRAM1_BASE +#define PLAT_ARM_SPMC_SIZE UL(0x200000) /* 2 MB */ +#endif + +/* + * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#if defined(IMAGE_BL31) +# if SPM_MM +# define PLAT_ARM_MMAP_ENTRIES 9 +# define MAX_XLAT_TABLES 7 +# define PLAT_SP_IMAGE_MMAP_REGIONS 7 +# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 +# else +# define PLAT_ARM_MMAP_ENTRIES 8 +# 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 7 +#else +# define PLAT_ARM_MMAP_ENTRIES 12 +# define MAX_XLAT_TABLES 6 +#endif + +/* + * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size + * plus a little space for growth. + */ +#define PLAT_ARM_MAX_BL1_RW_SIZE 0xC000 + +/* + * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page + */ + +#if USE_ROMLIB +#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0x1000 +#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0xe000 +#else +#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0 +#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0 +#endif + +/* + * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a + * little space for growth. + */ +#if TRUSTED_BOARD_BOOT +# define PLAT_ARM_MAX_BL2_SIZE 0x20000 +#else +# define PLAT_ARM_MAX_BL2_SIZE 0x14000 +#endif + +/* + * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is + * calculated using the current BL31 PROGBITS debug size plus the sizes of + * BL2 and BL1-RW + */ +#define PLAT_ARM_MAX_BL31_SIZE 0x3B000 + +/* + * Size of cacheable stacks + */ +#if defined(IMAGE_BL1) +# if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +# else +# define PLATFORM_STACK_SIZE 0x440 +# endif +#elif defined(IMAGE_BL2) +# if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE 0x1000 +# else +# define PLATFORM_STACK_SIZE 0x400 +# endif +#elif defined(IMAGE_BL2U) +# define PLATFORM_STACK_SIZE 0x400 +#elif defined(IMAGE_BL31) +# if SPM_MM +# define PLATFORM_STACK_SIZE 0x500 +# else +# define PLATFORM_STACK_SIZE 0x400 +# endif +#elif defined(IMAGE_BL32) +# define PLATFORM_STACK_SIZE 0x440 +#endif + + +#define TC0_DEVICE_BASE 0x21000000 +#define TC0_DEVICE_SIZE 0x5f000000 + +// TC0_MAP_DEVICE covers different peripherals +// available to the platform +#define TC0_MAP_DEVICE MAP_REGION_FLAT( \ + TC0_DEVICE_BASE, \ + TC0_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + + +#define TC0_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ + V2M_FLASH0_SIZE, \ + MT_DEVICE | MT_RO | MT_SECURE) + +#define PLAT_ARM_NSTIMER_FRAME_ID 0 + +#define PLAT_ARM_TRUSTED_ROM_BASE 0x0 +#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 /* 512KB */ + +#define PLAT_ARM_NSRAM_BASE 0x06000000 +#define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */ + +#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) + +#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp) +#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) + +#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ + PLAT_SP_IMAGE_NS_BUF_SIZE) + +/******************************************************************************* + * Memprotect definitions + ******************************************************************************/ +/* PSCI memory protect definitions: + * This variable is stored in a non-secure flash because some ARM reference + * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT + * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions. + */ +#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \ + V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) + +/*Secure Watchdog Constants */ +#define SBSA_SECURE_WDOG_BASE UL(0x2A480000) +#define SBSA_SECURE_WDOG_TIMEOUT UL(100) + +#define PLAT_ARM_SCMI_CHANNEL_COUNT 1 + +#define PLAT_ARM_CLUSTER_COUNT U(1) +#define PLAT_MAX_CPUS_PER_CLUSTER U(8) +#define PLAT_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 + */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE UL(0x30000000) +#define PLAT_ARM_GICC_BASE UL(0x2C000000) +#define PLAT_ARM_GICR_BASE UL(0x30140000) + +/* + * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current + * SCP_BL2 size plus a little space for growth. + */ +#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x20000 + +/* + * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current + * SCP_BL2U size plus a little space for growth. + */ +#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x20000 + +/* TZC Related Constants */ +#define PLAT_ARM_TZC_BASE UL(0x25000000) +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) + +#define TZC400_OFFSET UL(0x1000000) +#define TZC400_COUNT 4 + +#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \ + (n * TZC400_OFFSET)) + +#define TZC_NSAID_DEFAULT U(0) + +#define PLAT_ARM_TZC_NS_DEV_ACCESS \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT)) + +/* + * The first region below, TC0_TZC_DRAM1_BASE (0xfd000000) to + * ARM_SCP_TZC_DRAM1_END (0xffffffff) will mark the last 48 MB of DRAM as + * secure. The second region gives non secure access to rest of DRAM. + */ +#define TC0_TZC_REGIONS_DEF \ + {TC0_TZC_DRAM1_BASE, ARM_SCP_TZC_DRAM1_END, \ + TZC_REGION_S_RDWR, PLAT_ARM_TZC_NS_DEV_ACCESS}, \ + {TC0_NS_DRAM1_BASE, TC0_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \ + PLAT_ARM_TZC_NS_DEV_ACCESS} + +/* virtual address used by dynamic mem_protect for chunk_base */ +#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/tc0/include/tc0_helpers.S b/plat/arm/board/tc0/include/tc0_helpers.S new file mode 100644 index 000000000..90623a273 --- /dev/null +++ b/plat/arm/board/tc0/include/tc0_helpers.S @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> +#include <platform_def.h> +#include <cpu_macros.S> + + .globl plat_arm_calc_core_pos + .globl plat_reset_handler + + /* --------------------------------------------------------------------- + * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) + * + * Function to calculate the core position on TC0. + * + * (ClusterId * PLAT_MAX_CPUS_PER_CLUSTER * PLAT_MAX_PE_PER_CPU) + + * (CPUId * PLAT_MAX_PE_PER_CPU) + + * ThreadId + * + * which can be simplified as: + * + * ((ClusterId * PLAT_MAX_CPUS_PER_CLUSTER + CPUId) * PLAT_MAX_PE_PER_CPU) + * + ThreadId + * --------------------------------------------------------------------- + */ +func plat_arm_calc_core_pos + /* + * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it + * look as if in a multi-threaded implementation. + */ + tst x0, #MPIDR_MT_MASK + lsl x3, x0, #MPIDR_AFFINITY_BITS + csel x3, x3, x0, eq + + /* 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 + + /* Compute linear position */ + mov x4, #PLAT_MAX_CPUS_PER_CLUSTER + madd x1, x2, x4, x1 + mov x5, #PLAT_MAX_PE_PER_CPU + madd x0, x1, x5, x0 + ret +endfunc plat_arm_calc_core_pos + + /* ----------------------------------------------------- + * void plat_reset_handler(void); + * + * Determine the CPU MIDR and disable power down bit for + * that CPU. + * ----------------------------------------------------- + */ +func plat_reset_handler + ret +endfunc plat_reset_handler diff --git a/plat/arm/board/tc0/include/tc0_plat.h b/plat/arm/board/tc0/include/tc0_plat.h new file mode 100644 index 000000000..f0cb43132 --- /dev/null +++ b/plat/arm/board/tc0/include/tc0_plat.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef tc0_bl31_common_platform_setup_PLAT_H +#define tc0_bl31_common_platform_setup_PLAT_H + +void tc0_bl31_common_platform_setup(void); + +#endif /* tc0_bl31_common_platform_setup_PLAT_H */ diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk new file mode 100644 index 000000000..393d09cff --- /dev/null +++ b/plat/arm/board/tc0/platform.mk @@ -0,0 +1,119 @@ +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +CSS_LOAD_SCP_IMAGES := 1 + +CSS_USE_SCMI_SDS_DRIVER := 1 + +RAS_EXTENSION := 0 + +SDEI_SUPPORT := 0 + +EL3_EXCEPTION_HANDLING := 0 + +HANDLE_EA_EL3_FIRST := 0 + +# System coherency is managed in hardware +HW_ASSISTED_COHERENCY := 1 + +# When building for systems with hardware-assisted coherency, there's no need to +# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too. +USE_COHERENT_MEM := 0 + +GIC_ENABLE_V4_EXTN := 1 + +# GIC-600 configuration +GICV3_SUPPORT_GIC600 := 1 + + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +ENT_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/arm/common/arm_gicv3.c + +override NEED_BL2U := no + +override ARM_PLAT_MT := 1 + +TC0_BASE = plat/arm/board/tc0 + +PLAT_INCLUDES += -I${TC0_BASE}/include/ + +TC0_CPU_SOURCES := lib/cpus/aarch64/cortex_klein.S \ + lib/cpus/aarch64/cortex_matterhorn.S + +INTERCONNECT_SOURCES := ${TC0_BASE}/tc0_interconnect.c + +PLAT_BL_COMMON_SOURCES += ${TC0_BASE}/tc0_plat.c \ + ${TC0_BASE}/include/tc0_helpers.S + +BL1_SOURCES += ${INTERCONNECT_SOURCES} \ + ${TC0_CPU_SOURCES} \ + ${TC0_BASE}/tc0_trusted_boot.c \ + ${TC0_BASE}/tc0_err.c \ + drivers/arm/sbsa/sbsa.c + + +BL2_SOURCES += ${TC0_BASE}/tc0_security.c \ + ${TC0_BASE}/tc0_err.c \ + ${TC0_BASE}/tc0_trusted_boot.c \ + lib/utils/mem_region.c \ + drivers/arm/tzc/tzc400.c \ + plat/arm/common/arm_tzc400.c \ + plat/arm/common/arm_nor_psci_mem_protect.c + +BL31_SOURCES += ${INTERCONNECT_SOURCES} \ + ${TC0_CPU_SOURCES} \ + ${ENT_GIC_SOURCES} \ + ${TC0_BASE}/tc0_bl31_setup.c \ + ${TC0_BASE}/tc0_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 += ${TC0_BASE}/fdts/${PLAT}_fw_config.dts \ + ${TC0_BASE}/fdts/${PLAT}_tb_fw_config.dts +FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG})) +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG})) + +ifeq (${SPD},spmd) +ifeq ($(ARM_SPMC_MANIFEST_DTS),) +ARM_SPMC_MANIFEST_DTS := ${TC0_BASE}/fdts/${PLAT}_spmc_manifest.dts +endif + +FDT_SOURCES += ${ARM_SPMC_MANIFEST_DTS} +TC0_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb + +# Add the TOS_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TC0_TOS_FW_CONFIG},--tos-fw-config,${TC0_TOS_FW_CONFIG})) +endif + +#Device tree +TC0_HW_CONFIG_DTS := fdts/tc0.dts +TC0_HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb +FDT_SOURCES += ${TC0_HW_CONFIG_DTS} +$(eval TC0_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(TC0_HW_CONFIG_DTS))) + +# Add the HW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TC0_HW_CONFIG},--hw-config,${TC0_HW_CONFIG})) + +override CTX_INCLUDE_AARCH32_REGS := 0 + +override CTX_INCLUDE_PAUTH_REGS := 1 + +override ENABLE_SPE_FOR_LOWER_ELS := 0 + +include plat/arm/common/arm_common.mk +include plat/arm/css/common/css_common.mk +include plat/arm/soc/common/soc_css.mk +include plat/arm/board/common/board_common.mk diff --git a/plat/arm/board/tc0/tc0_bl31_setup.c b/plat/arm/board/tc0/tc0_bl31_setup.c new file mode 100644 index 000000000..b91b11c9d --- /dev/null +++ b/plat/arm/board/tc0/tc0_bl31_setup.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <libfdt.h> +#include <tc0_plat.h> + +#include <common/bl_common.h> +#include <common/debug.h> +#include <drivers/arm/css/css_mhu_doorbell.h> +#include <drivers/arm/css/scmi.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/common/platform.h> + +static scmi_channel_plat_info_t tc0_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, + } +}; + +void bl31_platform_setup(void) +{ + tc0_bl31_common_platform_setup(); +} + +scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) +{ + + return &tc0_scmi_plat_info[channel_id]; + +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); +} + +void tc0_bl31_common_platform_setup(void) +{ + arm_bl31_platform_setup(); +} + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return css_scmi_override_pm_ops(ops); +} diff --git a/plat/arm/board/tc0/tc0_err.c b/plat/arm/board/tc0/tc0_err.c new file mode 100644 index 000000000..83f2e9f6a --- /dev/null +++ b/plat/arm/board/tc0/tc0_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> + +/* + * tc0 error handler + */ +void __dead2 plat_arm_error_handler(int err) +{ + while (true) { + wfi(); + } +} diff --git a/plat/arm/board/tc0/tc0_interconnect.c b/plat/arm/board/tc0/tc0_interconnect.c new file mode 100644 index 000000000..e2fc4e1e1 --- /dev/null +++ b/plat/arm/board/tc0/tc0_interconnect.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <common/debug.h> +#include <plat/arm/common/plat_arm.h> + +/* + * For Total Compute we should not do anything in these interface functions. + * They are used to override the weak functions in cci drivers. + */ + +/****************************************************************************** + * Helper function to initialize ARM interconnect driver. + *****************************************************************************/ +void __init plat_arm_interconnect_init(void) +{ +} + +/****************************************************************************** + * Helper function to place current master into coherency + *****************************************************************************/ +void plat_arm_interconnect_enter_coherency(void) +{ +} + +/****************************************************************************** + * Helper function to remove current master from coherency + *****************************************************************************/ +void plat_arm_interconnect_exit_coherency(void) +{ +} diff --git a/plat/arm/board/tc0/tc0_plat.c b/plat/arm/board/tc0/tc0_plat.c new file mode 100644 index 000000000..b5698c098 --- /dev/null +++ b/plat/arm/board/tc0/tc0_plat.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <platform_def.h> + +#include <plat/common/platform.h> +#include <common/bl_common.h> +#include <common/debug.h> +#include <drivers/arm/ccn.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/common/platform.h> +#include <drivers/arm/sbsa.h> + +#if SPM_MM +#include <services/spm_mm_partition.h> +#endif + +/* + * Table of regions for different BL stages to map using the MMU. + * This doesn't include Trusted RAM as the 'mem_layout' argument passed to + * arm_configure_mmu_elx() will give the available subset of that. + */ +#if IMAGE_BL1 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + TC0_FLASH0_RO, + TC0_MAP_DEVICE, + {0} +}; +#endif +#if IMAGE_BL2 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + TC0_FLASH0_RO, + TC0_MAP_DEVICE, + TC0_MAP_NS_DRAM1, +#if defined(SPD_spmd) + TC0_MAP_TZC_DRAM1, +#endif +#if ARM_BL31_IN_DRAM + ARM_MAP_BL31_SEC_DRAM, +#endif +#if SPM_MM + ARM_SP_IMAGE_MMAP, +#endif +#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3 + ARM_MAP_BL1_RW, +#endif +#ifdef SPD_opteed + ARM_MAP_OPTEE_CORE_MEM, + ARM_OPTEE_PAGEABLE_LOAD_MEM, +#endif + {0} +}; +#endif +#if IMAGE_BL31 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + V2M_MAP_IOFPGA, + TC0_MAP_DEVICE, +#if SPM_MM + ARM_SPM_BUF_EL3_MMAP, +#endif + {0} +}; + +#if SPM_MM && defined(IMAGE_BL31) +const mmap_region_t plat_arm_secure_partition_mmap[] = { + PLAT_ARM_SECURE_MAP_DEVICE, + ARM_SP_IMAGE_MMAP, + ARM_SP_IMAGE_NS_BUF_MMAP, + ARM_SP_CPER_BUF_MMAP, + ARM_SP_IMAGE_RW_MMAP, + ARM_SPM_BUF_EL0_MMAP, + {0} +}; +#endif /* SPM_MM && defined(IMAGE_BL31) */ +#endif + +ARM_CASSERT_MMAP + +#if SPM_MM && defined(IMAGE_BL31) +/* + * Boot information passed to a secure partition during initialisation. Linear + * indices in MP information will be filled at runtime. + */ +static spm_mm_mp_info_t sp_mp_info[] = { + [0] = {0x81000000, 0}, + [1] = {0x81000100, 0}, + [2] = {0x81000200, 0}, + [3] = {0x81000300, 0}, + [4] = {0x81010000, 0}, + [5] = {0x81010100, 0}, + [6] = {0x81010200, 0}, + [7] = {0x81010300, 0}, +}; + +const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = { + .h.type = PARAM_SP_IMAGE_BOOT_INFO, + .h.version = VERSION_1, + .h.size = sizeof(spm_mm_boot_info_t), + .h.attr = 0, + .sp_mem_base = ARM_SP_IMAGE_BASE, + .sp_mem_limit = ARM_SP_IMAGE_LIMIT, + .sp_image_base = ARM_SP_IMAGE_BASE, + .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE, + .sp_heap_base = ARM_SP_IMAGE_HEAP_BASE, + .sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE, + .sp_shared_buf_base = PLAT_SPM_BUF_BASE, + .sp_image_size = ARM_SP_IMAGE_SIZE, + .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE, + .sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE, + .sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE, + .sp_shared_buf_size = PLAT_SPM_BUF_SIZE, + .num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS, + .num_cpus = PLATFORM_CORE_COUNT, + .mp_info = &sp_mp_info[0], +}; + +const struct mmap_region *plat_get_secure_partition_mmap(void *cookie) +{ + return plat_arm_secure_partition_mmap; +} + +const struct spm_mm_boot_info *plat_get_secure_partition_boot_info( + void *cookie) +{ + return &plat_arm_secure_partition_boot_info; +} +#endif /* SPM_MM && defined(IMAGE_BL31) */ + +#if TRUSTED_BOARD_BOOT +int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) +{ + assert(heap_addr != NULL); + assert(heap_size != NULL); + + return arm_get_mbedtls_heap(heap_addr, heap_size); +} +#endif + +void plat_arm_secure_wdt_start(void) +{ + sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT); +} + +void plat_arm_secure_wdt_stop(void) +{ + sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE); +} diff --git a/plat/arm/board/tc0/tc0_security.c b/plat/arm/board/tc0/tc0_security.c new file mode 100644 index 000000000..f54376203 --- /dev/null +++ b/plat/arm/board/tc0/tc0_security.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> +#include <platform_def.h> + +static const arm_tzc_regions_info_t tzc_regions[] = { + TC0_TZC_REGIONS_DEF, + {} +}; + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ + unsigned int i; + + for (i = 0U; i < TZC400_COUNT; i++) { + arm_tzc400_setup(TZC400_BASE(i), tzc_regions); + } +} diff --git a/plat/arm/board/tc0/tc0_topology.c b/plat/arm/board/tc0/tc0_topology.c new file mode 100644 index 000000000..8cfc3b50e --- /dev/null +++ b/plat/arm/board/tc0/tc0_topology.c @@ -0,0 +1,58 @@ +/* + * 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 tc0_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + PLAT_MAX_CPUS_PER_CLUSTER, +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return tc0_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)), +}; + +/******************************************************************************* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + ******************************************************************************/ +unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) +{ + return PLAT_MAX_CPUS_PER_CLUSTER; +} + +#if ARM_PLAT_MT +/****************************************************************************** + * Return the number of PE's supported by the CPU. + *****************************************************************************/ +unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr) +{ + return PLAT_MAX_PE_PER_CPU; +} +#endif diff --git a/plat/arm/board/tc0/tc0_trusted_boot.c b/plat/arm/board/tc0/tc0_trusted_boot.c new file mode 100644 index 000000000..614f7e2ad --- /dev/null +++ b/plat/arm/board/tc0/tc0_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. 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(cookie, key_ptr, key_len, flags); +} diff --git a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c index 7aeeb2aed..78360b06c 100644 --- a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c +++ b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,6 @@ #include <common/bl_common.h> #include <common/desc_image_load.h> -#include <plat/common/platform.h> /******************************************************************************* * Following descriptor provides BL image/ep information that gets used diff --git a/plat/arm/common/aarch32/arm_helpers.S b/plat/arm/common/aarch32/arm_helpers.S index badddd3a9..1da2d4cad 100644 --- a/plat/arm/common/aarch32/arm_helpers.S +++ b/plat/arm/common/aarch32/arm_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -64,10 +64,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0 * --------------------------------------------- */ diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c index 0514b3994..6a8943d5d 100644 --- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c +++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,6 @@ #include <common/bl_common.h> #include <common/desc_image_load.h> -#include <plat/common/platform.h> /******************************************************************************* * Following descriptor provides BL image/ep information that gets used diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c deleted file mode 100644 index 69ebd798f..000000000 --- a/plat/arm/common/aarch64/arm_ehf.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <platform_def.h> - -#include <bl31/ehf.h> - -/* - * Enumeration of priority levels on ARM platforms. - */ -ehf_pri_desc_t arm_exceptions[] = { -#if RAS_EXTENSION - /* RAS Priority */ - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_RAS_PRI), -#endif - -#if SDEI_SUPPORT - /* Critical priority SDEI */ - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_CRITICAL_PRI), - - /* Normal priority SDEI */ - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI), -#endif -#if SPM_MM - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI), -#endif -}; - -/* Plug in ARM exceptions to Exception Handling Framework. */ -EHF_REGISTER_PRIORITIES(arm_exceptions, ARRAY_SIZE(arm_exceptions), ARM_PRI_BITS); diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S index 06720589a..b47078173 100644 --- a/plat/arm/common/aarch64/arm_helpers.S +++ b/plat/arm/common/aarch64/arm_helpers.S @@ -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 */ @@ -66,10 +66,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0 * --------------------------------------------- */ diff --git a/plat/arm/common/aarch64/arm_sdei.c b/plat/arm/common/aarch64/arm_sdei.c index 493134b6a..3c74a465c 100644 --- a/plat/arm/common/aarch64/arm_sdei.c +++ b/plat/arm/common/aarch64/arm_sdei.c @@ -1,16 +1,51 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /* SDEI configuration for ARM platforms */ -#include <platform_def.h> - #include <bl31/ehf.h> +#include <common/debug.h> #include <services/sdei.h> +#if SDEI_IN_FCONF +#include <plat/arm/common/fconf_sdei_getter.h> +#endif +#include <plat/common/platform.h> +#include <platform_def.h> + + +#if SDEI_IN_FCONF +/* Private event mappings */ +static sdei_ev_map_t arm_sdei_private[PLAT_SDEI_DP_EVENT_MAX_CNT + 1] = { 0 }; + +/* Shared event mappings */ +static sdei_ev_map_t arm_sdei_shared[PLAT_SDEI_DS_EVENT_MAX_CNT] = { 0 }; + +void plat_sdei_setup(void) +{ + uint32_t i; + + arm_sdei_private[0] = (sdei_ev_map_t)SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI); + + for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_cnt); i++) { + arm_sdei_private[i + 1] = (sdei_ev_map_t)SDEI_PRIVATE_EVENT( + FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_nums[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_intrs[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_flags[i])); + } + + for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_cnt); i++) { + arm_sdei_shared[i] = (sdei_ev_map_t)SDEI_SHARED_EVENT( \ + FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_nums[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_intrs[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_flags[i])); + } + INFO("FCONF: SDEI platform setup\n"); +} +#else /* Private event mappings */ static sdei_ev_map_t arm_sdei_private[] = { PLAT_ARM_PRIVATE_SDEI_EVENTS @@ -21,5 +56,11 @@ static sdei_ev_map_t arm_sdei_shared[] = { PLAT_ARM_SHARED_SDEI_EVENTS }; +void plat_sdei_setup(void) +{ + INFO("SDEI platform setup\n"); +} +#endif /* SDEI_IN_FCONF */ + /* Export ARM SDEI events */ REGISTER_SDEI_MAP(arm_sdei_private, arm_sdei_shared); diff --git a/plat/arm/common/aarch64/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c index 8835fa135..bed929a9c 100644 --- a/plat/arm/common/aarch64/execution_state_switch.c +++ b/plat/arm/common/aarch64/execution_state_switch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,7 +12,6 @@ #include <lib/el3_runtime/context_mgmt.h> #include <lib/psci/psci.h> #include <lib/utils.h> -#include <plat/arm/common/arm_sip_svc.h> #include <plat/arm/common/plat_arm.h> #include <smccc_helpers.h> diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index b19a7c39c..4b2a062f9 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.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 */ @@ -11,6 +11,8 @@ #include <arch.h> #include <bl1/bl1.h> #include <common/bl_common.h> +#include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> #include <lib/utils.h> #include <lib/xlat_tables/xlat_tables_compat.h> #include <plat/arm/common/plat_arm.h> @@ -52,6 +54,9 @@ /* Data structure which holds the extents of the trusted SRAM for BL1*/ static meminfo_t bl1_tzram_layout; +/* Boolean variable to hold condition whether firmware update needed or not */ +static bool is_fwu_needed; + struct meminfo *bl1_plat_sec_mem_layout(void) { return &bl1_tzram_layout; @@ -141,9 +146,59 @@ void bl1_plat_arch_setup(void) */ void arm_bl1_platform_setup(void) { + const struct dyn_cfg_dtb_info_t *fw_config_info; + image_desc_t *desc; + uint32_t fw_config_max_size; + int err = -1; + /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - arm_load_tb_fw_config(); + + /* Check if we need FWU before further processing */ + is_fwu_needed = plat_arm_bl1_fwu_needed(); + if (is_fwu_needed) { + ERROR("Skip platform setup as FWU detected\n"); + return; + } + + /* Set global DTB info for fixed fw_config information */ + fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE; + set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID); + + /* Fill the device tree information struct with the info from the config dtb */ + err = fconf_load_config(FW_CONFIG_ID); + if (err < 0) { + ERROR("Loading of FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + + /* + * FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing + * is successful then load TB_FW_CONFIG device tree. + */ + fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); + if (fw_config_info != NULL) { + err = fconf_populate_dtb_registry(fw_config_info->config_addr); + if (err < 0) { + ERROR("Parsing of FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + /* load TB_FW_CONFIG */ + err = fconf_load_config(TB_FW_CONFIG_ID); + if (err < 0) { + ERROR("Loading of TB_FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + } else { + ERROR("Invalid FW_CONFIG address\n"); + plat_error_handler(err); + } + + /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ + desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(desc != NULL); + desc->ep_info.args.arg0 = fw_config_info->config_addr; + #if TRUSTED_BOARD_BOOT /* Share the Mbed TLS heap info with other images */ arm_bl1_set_mbedtls_heap(); @@ -184,9 +239,9 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info) * On Arm platforms, the FWU process is triggered when the FIP image has * been tampered with. */ -int plat_arm_bl1_fwu_needed(void) +bool plat_arm_bl1_fwu_needed(void) { - return (arm_io_is_toc_valid() != 1); + return !arm_io_is_toc_valid(); } /******************************************************************************* @@ -195,8 +250,5 @@ int plat_arm_bl1_fwu_needed(void) ******************************************************************************/ unsigned int bl1_plat_get_next_image_id(void) { - if (plat_arm_bl1_fwu_needed() != 0) - return NS_BL1U_IMAGE_ID; - - return BL2_IMAGE_ID; + return is_fwu_needed ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID; } diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index cdf87ca55..c90e93cd8 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -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 */ @@ -14,6 +14,8 @@ #include <common/debug.h> #include <common/desc_image_load.h> #include <drivers/generic_delay_timer.h> +#include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> #ifdef SPD_opteed #include <lib/optee_utils.h> #endif @@ -24,17 +26,23 @@ /* Data structure which holds the extents of the trusted SRAM for BL2 */ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); +/* Base address of fw_config received from BL1 */ +static uintptr_t config_base; + /* - * Check that BL2_BASE is above ARM_TB_FW_CONFIG_LIMIT. This reserved page is + * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is * for `meminfo_t` data structure and fw_configs passed from BL1. */ -CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows); +CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak bl2_early_platform_setup2 #pragma weak bl2_platform_setup #pragma weak bl2_plat_arch_setup #pragma weak bl2_plat_sec_mem_layout +#if MEASURED_BOOT +#pragma weak bl2_plat_get_hash +#endif #define MAP_BL2_TOTAL MAP_REGION_FLAT( \ bl2_tzram_layout.total_base, \ @@ -49,7 +57,7 @@ CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows); * in x0. This memory layout is sitting at the base of the free trusted SRAM. * Copy it to a safe location before its reclaimed by later BL2 functionality. ******************************************************************************/ -void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, +void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout) { /* Initialize the console to provide early debug support */ @@ -58,11 +66,10 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; + config_base = fw_config; + /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - - if (tb_fw_config != 0U) - arm_bl2_set_tb_cfg_addr((void *)tb_fw_config); } void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) @@ -123,6 +130,7 @@ void arm_bl2_plat_arch_setup(void) #if ARM_CRYPTOCELL_INTEG ARM_MAP_BL_COHERENT_RAM, #endif + ARM_MAP_BL_CONFIG_REGION, {0} }; @@ -139,7 +147,18 @@ void arm_bl2_plat_arch_setup(void) void bl2_plat_arch_setup(void) { + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; + arm_bl2_plat_arch_setup(); + + /* Fill the properties struct with the info from the config dtb */ + fconf_populate("FW_CONFIG", config_base); + + /* TB_FW_CONFIG was also loaded by BL1 */ + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); + + fconf_populate("TB_FW", tb_fw_config_info->config_addr); } int arm_bl2_handle_post_image_load(unsigned int image_id) @@ -150,7 +169,7 @@ int arm_bl2_handle_post_image_load(unsigned int image_id) bl_mem_params_node_t *pager_mem_params = NULL; bl_mem_params_node_t *paged_mem_params = NULL; #endif - assert(bl_mem_params); + assert(bl_mem_params != NULL); switch (image_id) { #ifdef __aarch64__ @@ -202,6 +221,13 @@ int arm_bl2_handle_post_image_load(unsigned int image_id) ******************************************************************************/ int arm_bl2_plat_handle_post_image_load(unsigned int image_id) { +#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 + /* For Secure Partitions we don't need post processing */ + if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) && + (image_id < MAX_NUMBER_IDS)) { + return 0; + } +#endif return arm_bl2_handle_post_image_load(image_id); } @@ -209,3 +235,11 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) { return arm_bl2_plat_handle_post_image_load(image_id); } + +#if MEASURED_BOOT +/* Read TCG_DIGEST_SIZE bytes of BL2 hash data */ +void bl2_plat_get_hash(void *data) +{ + arm_bl2_get_hash(data); +} +#endif diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 939885f98..81ef6e7b2 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.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 */ @@ -14,7 +14,6 @@ #include <lib/debugfs.h> #include <lib/extensions/ras.h> #include <lib/mmio.h> -#include <lib/utils.h> #include <lib/xlat_tables/xlat_tables_compat.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> @@ -29,10 +28,10 @@ static entry_point_info_t bl33_image_ep_info; #if !RESET_TO_BL31 /* - * Check that BL31_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page + * Check that BL31_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. */ -CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); +CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #endif /* Weak definitions may be overridden in specific ARM standard platform */ @@ -47,7 +46,13 @@ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); MT_MEMORY | MT_RW | MT_SECURE) #if RECLAIM_INIT_CODE IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE); -IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END); +IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED); +IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED); + +#define BL_INIT_CODE_END ((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \ + ~(PAGE_SIZE - 1)) +#define BL_STACKS_END ((BL_STACKS_END_UNALIGNED + PAGE_SIZE - 1) & \ + ~(PAGE_SIZE - 1)) #define MAP_BL_INIT_CODE MAP_REGION_FLAT( \ BL_INIT_CODE_BASE, \ @@ -56,6 +61,14 @@ IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END); MT_CODE | MT_SECURE) #endif +#if SEPARATE_NOBITS_REGION +#define MAP_BL31_NOBITS MAP_REGION_FLAT( \ + BL31_NOBITS_BASE, \ + BL31_NOBITS_LIMIT \ + - BL31_NOBITS_BASE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#endif /******************************************************************************* * 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 @@ -107,6 +120,18 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); bl32_image_ep_info.pc = BL32_BASE; bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry(); + +#if defined(SPD_spmd) + /* SPM (hafnium in secure world) expects SPM Core manifest base address + * in x0, which in !RESET_TO_BL31 case loaded after base of non shared + * SRAM(after 4KB offset of SRAM). But in RESET_TO_BL31 case all non + * shared SRAM is allocated to BL31, so to avoid overwriting of manifest + * keep it in the last page. + */ + bl32_image_ep_info.args.arg0 = ARM_TRUSTED_SRAM_BASE + + PLAT_ARM_TRUSTED_SRAM_SIZE - PAGE_SIZE; +#endif + # endif /* BL32_BASE */ /* Populate entry point information for BL33 */ @@ -123,6 +148,14 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry(); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); +#if defined(SPD_spmd) && !(ARM_LINUX_KERNEL_AS_BL33) + /* + * Hafnium in normal world expects its manifest address in x0, which + * is loaded at base of DRAM. + */ + bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE; +#endif + # if ARM_LINUX_KERNEL_AS_BL33 /* * According to the file ``Documentation/arm64/booting.txt`` of the @@ -249,21 +282,51 @@ void arm_bl31_plat_runtime_setup(void) /* Initialize the runtime console */ arm_console_runtime_init(); + #if RECLAIM_INIT_CODE arm_free_init_memory(); #endif + +#if PLAT_RO_XLAT_TABLES + arm_xlat_make_tables_readonly(); +#endif } #if RECLAIM_INIT_CODE /* - * Zero out and make RW memory used to store image boot time code so it can - * be reclaimed during runtime + * Make memory for image boot time code RW to reclaim it as stack for the + * secondary cores, or RO where it cannot be reclaimed: + * + * |-------- INIT SECTION --------| + * ----------------------------------------- + * | CORE 0 | CORE 1 | CORE 2 | EXTRA | + * | STACK | STACK | STACK | SPACE | + * ----------------------------------------- + * <-------------------> <------> + * MAKE RW AND XN MAKE + * FOR STACKS RO AND XN */ void arm_free_init_memory(void) { - int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE, + int ret = 0; + + if (BL_STACKS_END < BL_INIT_CODE_END) { + /* Reclaim some of the init section as stack if possible. */ + if (BL_INIT_CODE_BASE < BL_STACKS_END) { + ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE, + BL_STACKS_END - BL_INIT_CODE_BASE, + MT_RW_DATA); + } + /* Make the rest of the init section read-only. */ + ret |= xlat_change_mem_attributes(BL_STACKS_END, + BL_INIT_CODE_END - BL_STACKS_END, + MT_RO_DATA); + } else { + /* The stacks cover the init section, so reclaim it all. */ + ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE, BL_INIT_CODE_END - BL_INIT_CODE_BASE, MT_RW_DATA); + } if (ret != 0) { ERROR("Could not reclaim initialization code"); @@ -295,6 +358,9 @@ void __init arm_bl31_plat_arch_setup(void) #if RECLAIM_INIT_CODE MAP_BL_INIT_CODE, #endif +#if SEPARATE_NOBITS_REGION + MAP_BL31_NOBITS, +#endif ARM_MAP_BL_RO, #if USE_ROMLIB ARM_MAP_ROMLIB_CODE, diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 255e6b421..7d9fd6c72 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -13,10 +13,11 @@ #include <common/debug.h> #include <common/romlib.h> #include <lib/mmio.h> +#include <lib/smccc.h> #include <lib/xlat_tables/xlat_tables_compat.h> +#include <services/arm_arch_svc.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> -#include <services/spm_mm_partition.h> /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_get_ns_image_entrypoint @@ -26,6 +27,29 @@ * conflicts with the definition in plat/common. */ #pragma weak plat_get_syscnt_freq2 +/* Get ARM SOC-ID */ +#pragma weak plat_arm_get_soc_id + +/******************************************************************************* + * Changes the memory attributes for the region of mapped memory where the BL + * image's translation tables are located such that the tables will have + * read-only permissions. + ******************************************************************************/ +#if PLAT_RO_XLAT_TABLES +void arm_xlat_make_tables_readonly(void) +{ + int rc = xlat_make_tables_readonly(); + + if (rc != 0) { + ERROR("Failed to make translation tables read-only at EL%u.\n", + get_current_el()); + panic(); + } + + INFO("Translation tables are now read-only at EL%u.\n", + get_current_el()); +} +#endif void arm_setup_romlib(void) { @@ -73,7 +97,7 @@ uint32_t arm_get_spsr_for_bl33_entry(void) * the FIP ToC and allowing the platform to have a say as * well. */ - spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); return spsr; } #else @@ -192,7 +216,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) * Translate entry point to Physical Address using the EL1&0 * translation regime, including stage 2. */ - ats12e1r(ep); + AT(ats12e1r, ep); } isb(); par = read_par_el1(); @@ -212,3 +236,4 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) return arm_validate_ns_entrypoint(pa); } #endif + diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index c8b7ab448..74afc53eb 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -121,10 +121,33 @@ endif ENABLE_PSCI_STAT := 1 ENABLE_PMF := 1 +# Override the standard libc with optimised libc_asm +OVERRIDE_LIBC := 1 +ifeq (${OVERRIDE_LIBC},1) + include lib/libc/libc_asm.mk +endif + # On ARM platforms, separate the code and read-only data sections to allow # mapping the former as executable and the latter as execute-never. SEPARATE_CODE_AND_RODATA := 1 +# On ARM platforms, disable SEPARATE_NOBITS_REGION by default. Both PROGBITS +# and NOBITS sections of BL31 image are adjacent to each other and loaded +# into Trusted SRAM. +SEPARATE_NOBITS_REGION := 0 + +# In order to support SEPARATE_NOBITS_REGION for Arm platforms, we need to load +# BL31 PROGBITS into secure DRAM space and BL31 NOBITS into SRAM. Hence mandate +# the build to require that ARM_BL31_IN_DRAM is enabled as well. +ifeq ($(SEPARATE_NOBITS_REGION),1) + ifneq ($(ARM_BL31_IN_DRAM),1) + $(error For SEPARATE_NOBITS_REGION, ARM_BL31_IN_DRAM must be enabled) + endif + ifneq ($(RECLAIM_INIT_CODE),0) + $(error For SEPARATE_NOBITS_REGION, RECLAIM_INIT_CODE cannot be supported) + endif +endif + # Disable ARM Cryptocell by default ARM_CRYPTOCELL_INTEG := 0 $(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG)) @@ -160,12 +183,21 @@ include lib/xlat_tables_v2/xlat_tables.mk PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} endif +ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c +ifeq (${SPD},spmd) + ifeq (${SPMD_SPM_AT_SEL2},1) + ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c + endif +endif + BL1_SOURCES += drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl1_setup.c \ plat/arm/common/arm_err.c \ - plat/arm/common/arm_io_storage.c + ${ARM_IO_SOURCES} + ifdef EL3_PAYLOAD_BASE # Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from # their holding pen @@ -179,7 +211,10 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl2_setup.c \ plat/arm/common/arm_err.c \ - plat/arm/common/arm_io_storage.c + ${ARM_IO_SOURCES} + +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk @@ -229,11 +264,14 @@ endif endif ifeq (${EL3_EXCEPTION_HANDLING},1) -BL31_SOURCES += plat/arm/common/aarch64/arm_ehf.c +BL31_SOURCES += plat/common/aarch64/plat_ehf.c endif ifeq (${SDEI_SUPPORT},1) BL31_SOURCES += plat/arm/common/aarch64/arm_sdei.c +ifeq (${SDEI_IN_FCONF},1) +BL31_SOURCES += plat/arm/common/fconf/fconf_sdei_getter.c +endif endif # RAS sources @@ -248,16 +286,33 @@ PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c \ lib/extensions/pauth/pauth_helpers.S endif +ifeq (${SPD},spmd) +BL31_SOURCES += plat/common/plat_spmd_manifest.c \ + common/fdt_wrappers.c \ + ${LIBFDT_SRCS} + +endif + ifneq (${TRUSTED_BOARD_BOOT},0) # Include common TBB sources AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c \ + lib/fconf/fconf_tbbr_getter.c # Include the selected chain of trust sources. ifeq (${COT},tbbr) - AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot.c + BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ + drivers/auth/tbbr/tbbr_cot_bl1.c + ifneq (${COT_DESC_IN_DTB},0) + BL2_SOURCES += lib/fconf/fconf_cot_getter.c + else + BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ + drivers/auth/tbbr/tbbr_cot_bl2.c + endif + else ifeq (${COT},dualroot) + AUTH_SOURCES += drivers/auth/dualroot/cot.c else $(error Unknown chain of trust ${COT}) endif @@ -293,3 +348,9 @@ ifeq (${RECLAIM_INIT_CODE}, 1) $(error "To reclaim init code xlat tables v2 must be used") endif endif + +ifeq (${MEASURED_BOOT},1) + MEASURED_BOOT_MK := drivers/measured_boot/measured_boot.mk + $(info Including ${MEASURED_BOOT_MK}) + include ${MEASURED_BOOT_MK} +endif diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c index 123811d71..af5f11e46 100644 --- a/plat/arm/common/arm_console.c +++ b/plat/arm/common/arm_console.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 */ @@ -13,11 +13,14 @@ #include <drivers/console.h> #include <plat/arm/common/plat_arm.h> +#pragma weak arm_console_runtime_init +#pragma weak arm_console_runtime_end + /******************************************************************************* * Functions that set up the console ******************************************************************************/ -static console_pl011_t arm_boot_console; -static console_pl011_t arm_runtime_console; +static console_t arm_boot_console; +static console_t arm_runtime_console; /* Initialize the console to provide early debug support */ void __init arm_console_boot_init(void) @@ -35,13 +38,13 @@ void __init arm_console_boot_init(void) panic(); } - console_set_scope(&arm_boot_console.console, CONSOLE_FLAG_BOOT); + console_set_scope(&arm_boot_console, CONSOLE_FLAG_BOOT); } void arm_console_boot_end(void) { - (void)console_flush(); - (void)console_unregister(&arm_boot_console.console); + console_flush(); + (void)console_unregister(&arm_boot_console); } /* Initialize the runtime console */ @@ -54,10 +57,10 @@ void arm_console_runtime_init(void) if (rc == 0) panic(); - console_set_scope(&arm_runtime_console.console, CONSOLE_FLAG_RUNTIME); + console_set_scope(&arm_runtime_console, CONSOLE_FLAG_RUNTIME); } void arm_console_runtime_end(void) { - (void)console_flush(); + console_flush(); } diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index e6c5a7361..6b3a61180 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.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 */ @@ -15,13 +15,17 @@ #include <common/tbbr/tbbr_img_def.h> #if TRUSTED_BOARD_BOOT #include <drivers/auth/mbedtls/mbedtls_config.h> +#if MEASURED_BOOT +#include <drivers/auth/crypto_mod.h> +#include <mbedtls/md.h> #endif +#endif +#include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> +#include <lib/fconf/fconf_tbbr_getter.h> + #include <plat/arm/common/arm_dyn_cfg_helpers.h> #include <plat/arm/common/plat_arm.h> -#include <plat/common/platform.h> - -/* Variable to store the address to TB_FW_CONFIG passed from BL1 */ -static void *tb_fw_cfg_dtb; #if TRUSTED_BOARD_BOOT @@ -57,20 +61,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) #elif defined(IMAGE_BL2) - int err; - /* If in BL2, retrieve the already allocated heap's info from DTB */ - if (tb_fw_cfg_dtb != NULL) { - err = arm_get_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, heap_addr, - heap_size); - if (err < 0) { - ERROR("BL2: unable to retrieve shared Mbed TLS heap information from DTB\n"); - panic(); - } - } else { - ERROR("BL2: DTB missing, cannot get Mbed TLS heap\n"); - panic(); - } + *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr); + *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size); + #endif return 0; @@ -83,6 +77,8 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) void arm_bl1_set_mbedtls_heap(void) { int err; + uintptr_t tb_fw_cfg_dtb; + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; /* * If tb_fw_cfg_dtb==NULL then DTB is not present for the current @@ -96,141 +92,150 @@ void arm_bl1_set_mbedtls_heap(void) * information, we would need to call plat_get_mbedtls_heap to retrieve * the default heap's address and size. */ - if ((tb_fw_cfg_dtb != NULL) && (mbedtls_heap_addr != NULL)) { - err = arm_set_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, + + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); + + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; + + if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) { + /* As libfdt uses void *, we can't avoid this cast */ + void *dtb = (void *)tb_fw_cfg_dtb; + + err = arm_set_dtb_mbedtls_heap_info(dtb, mbedtls_heap_addr, mbedtls_heap_size); if (err < 0) { - ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n"); + ERROR("%swrite shared Mbed TLS heap information%s", + "BL1: unable to ", " to DTB\n"); panic(); } +#if !MEASURED_BOOT /* * Ensure that the info written to the DTB is visible to other * images. It's critical because BL2 won't be able to proceed * without the heap info. + * + * In MEASURED_BOOT case flushing is done in + * arm_bl1_set_bl2_hash() function which is called after heap + * information is written in the DTB. */ - flush_dcache_range((uintptr_t)tb_fw_cfg_dtb, - fdt_totalsize(tb_fw_cfg_dtb)); + flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb)); +#endif /* !MEASURED_BOOT */ } } -#endif /* TRUSTED_BOARD_BOOT */ - +#if MEASURED_BOOT /* - * Helper function to load TB_FW_CONFIG and populate the load information to - * arg0 of BL2 entrypoint info. + * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. + * Executed only from BL1. */ -void arm_load_tb_fw_config(void) +void arm_bl1_set_bl2_hash(const image_desc_t *image_desc) { + unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; + const image_info_t image_info = image_desc->image_info; + uintptr_t tb_fw_cfg_dtb; int err; - uintptr_t config_base = 0UL; - image_desc_t *desc; - - image_desc_t arm_tb_fw_info = { - .image_id = TB_FW_CONFIG_ID, - SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, - VERSION_2, image_info_t, 0), - .image_info.image_base = ARM_TB_FW_CONFIG_BASE, - .image_info.image_max_size = - ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE - }; + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; - VERBOSE("BL1: Loading TB_FW_CONFIG\n"); - err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info.image_info); - if (err != 0) { - /* Return if TB_FW_CONFIG is not loaded */ - VERBOSE("Failed to load TB_FW_CONFIG\n"); - return; - } - - /* At this point we know that a DTB is indeed available */ - config_base = arm_tb_fw_info.image_info.image_base; - tb_fw_cfg_dtb = (void *)config_base; + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); - /* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */ - desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(desc != NULL); - desc->ep_info.args.arg0 = config_base; + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; - INFO("BL1: TB_FW_CONFIG loaded at address = 0x%lx\n", config_base); + /* + * If tb_fw_cfg_dtb==NULL then DTB is not present for the current + * platform. As such, we cannot write to the DTB at all and pass + * measured data. + */ + if (tb_fw_cfg_dtb == 0UL) { + panic(); + } -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - int tb_fw_node; - uint32_t disable_auth = 0; + /* Calculate hash */ + err = crypto_mod_calc_hash(MBEDTLS_MD_ID, + (void *)image_info.image_base, + image_info.image_size, hash_data); + if (err != 0) { + ERROR("%scalculate%s\n", "BL1: unable to ", + " BL2 hash"); + panic(); + } - err = arm_dyn_tb_fw_cfg_init((void *)config_base, &tb_fw_node); + err = arm_set_bl2_hash_info((void *)tb_fw_cfg_dtb, hash_data); if (err < 0) { - ERROR("Invalid TB_FW_CONFIG loaded\n"); + ERROR("%swrite%sdata%s\n", "BL1: unable to ", + " BL2 hash ", "to DTB\n"); panic(); } - err = arm_dyn_get_disable_auth((void *)config_base, tb_fw_node, &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif + /* + * Ensure that the info written to the DTB is visible to other + * images. It's critical because BL2 won't be able to proceed + * without the heap info and its hash data. + */ + flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize((void *)tb_fw_cfg_dtb)); } /* - * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1. + * Reads TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB. + * Executed only from BL2. */ -void arm_bl2_set_tb_cfg_addr(void *dtb) +void arm_bl2_get_hash(void *data) { - assert(dtb != NULL); - tb_fw_cfg_dtb = dtb; + const void *bl2_hash; + + assert(data != NULL); + + /* Retrieve TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB */ + bl2_hash = FCONF_GET_PROPERTY(tbbr, dyn_config, bl2_hash_data); + (void)memcpy(data, bl2_hash, TCG_DIGEST_SIZE); } +#endif /* MEASURED_BOOT */ +#endif /* TRUSTED_BOARD_BOOT */ /* * BL2 utility function to initialize dynamic configuration specified by - * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if - * specified in TB_FW_CONFIG. + * FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if + * specified in FW_CONFIG. */ void arm_bl2_dyn_cfg_init(void) { - int err = 0, tb_fw_node; unsigned int i; bl_mem_params_node_t *cfg_mem_params = NULL; - uint64_t image_base; + uintptr_t image_base; uint32_t image_size; const unsigned int config_ids[] = { HW_CONFIG_ID, SOC_FW_CONFIG_ID, NT_FW_CONFIG_ID, -#ifdef SPD_tspd - /* Currently tos_fw_config is only present for TSP */ +#if defined(SPD_tspd) || defined(SPD_spmd) + /* tos_fw_config is only present for TSPD/SPMD */ TOS_FW_CONFIG_ID #endif }; - if (tb_fw_cfg_dtb == NULL) { - VERBOSE("No TB_FW_CONFIG specified\n"); - return; - } - - err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); - panic(); - } + const struct dyn_cfg_dtb_info_t *dtb_info; /* Iterate through all the fw config IDs */ for (i = 0; i < ARRAY_SIZE(config_ids); i++) { /* Get the config load address and size from TB_FW_CONFIG */ cfg_mem_params = get_bl_mem_params_node(config_ids[i]); if (cfg_mem_params == NULL) { - VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n"); + VERBOSE("%sHW_CONFIG in bl_mem_params_node\n", + "Couldn't find "); continue; } - err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node, - config_ids[i], &image_base, &image_size); - if (err < 0) { - VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n", - config_ids[i]); + dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]); + if (dtb_info == NULL) { + VERBOSE("%sconfig_id %d load info in TB_FW_CONFIG\n", + "Couldn't find ", config_ids[i]); continue; } + image_base = dtb_info->config_addr; + image_size = dtb_info->config_max_size; + /* * Do some runtime checks on the load addresses of soc_fw_config, * tos_fw_config, nt_fw_config. This is not a comprehensive check @@ -238,32 +243,34 @@ void arm_bl2_dyn_cfg_init(void) */ if (config_ids[i] != HW_CONFIG_ID) { - if (check_uptr_overflow(image_base, image_size)) + if (check_uptr_overflow(image_base, image_size)) { continue; - + } #ifdef BL31_BASE /* Ensure the configs don't overlap with BL31 */ if ((image_base >= BL31_BASE) && - (image_base <= BL31_LIMIT)) + (image_base <= BL31_LIMIT)) { continue; + } #endif /* Ensure the configs are loaded in a valid address */ - if (image_base < ARM_BL_RAM_BASE) + if (image_base < ARM_BL_RAM_BASE) { continue; + } #ifdef BL32_BASE /* * If BL32 is present, ensure that the configs don't * overlap with it. */ if ((image_base >= BL32_BASE) && - (image_base <= BL32_LIMIT)) + (image_base <= BL32_LIMIT)) { continue; + } #endif } - - cfg_mem_params->image_info.image_base = (uintptr_t)image_base; - cfg_mem_params->image_info.image_max_size = image_size; + cfg_mem_params->image_info.image_base = image_base; + cfg_mem_params->image_info.image_max_size = (uint32_t)image_size; /* * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from @@ -271,16 +278,4 @@ void arm_bl2_dyn_cfg_init(void) */ cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; } - -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - uint32_t disable_auth = 0; - - err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node, - &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif } diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index 36d37f8f6..5f20c8d48 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -1,142 +1,38 @@ /* - * 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 <assert.h> -#include <libfdt.h> - +#if MEASURED_BOOT #include <common/desc_image_load.h> +#endif #include <common/fdt_wrappers.h> + +#include <libfdt.h> + #include <plat/arm/common/arm_dyn_cfg_helpers.h> #include <plat/arm/common/plat_arm.h> #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr" #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" -typedef struct config_load_info_prop { - unsigned int config_id; - const char *config_addr; - const char *config_max_size; -} config_load_info_prop_t; - -static const config_load_info_prop_t prop_names[] = { - {HW_CONFIG_ID, "hw_config_addr", "hw_config_max_size"}, - {SOC_FW_CONFIG_ID, "soc_fw_config_addr", "soc_fw_config_max_size"}, - {TOS_FW_CONFIG_ID, "tos_fw_config_addr", "tos_fw_config_max_size"}, - {NT_FW_CONFIG_ID, "nt_fw_config_addr", "nt_fw_config_max_size"} -}; - -/******************************************************************************* - * Helper to read the load information corresponding to the `config_id` in - * TB_FW_CONFIG. This function expects the following properties to be defined : - * <config>_addr size : 2 cells - * <config>_max_size size : 1 cell - * - * Arguments: - * void *dtb - pointer to the TB_FW_CONFIG in memory - * int node - The node offset to appropriate node in the - * DTB. - * unsigned int config_id - The configuration id - * uint64_t *config_addr - Returns the `config` load address if read - * is successful. - * uint32_t *config_size - Returns the `config` size if read is - * successful. - * - * Returns 0 on success and -1 on error. - ******************************************************************************/ -int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id, - uint64_t *config_addr, uint32_t *config_size) -{ - int err; - unsigned int i; - - assert(dtb != NULL); - assert(config_addr != NULL); - assert(config_size != NULL); - - for (i = 0; i < ARRAY_SIZE(prop_names); i++) { - if (prop_names[i].config_id == config_id) - break; - } - - if (i == ARRAY_SIZE(prop_names)) { - WARN("Invalid config id %d\n", config_id); - return -1; - } - - /* Check if the pointer to DT is correct */ - assert(fdt_check_header(dtb) == 0); - - /* Assert the node offset point to "arm,tb_fw" compatible property */ - assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); - - err = fdtw_read_cells(dtb, node, prop_names[i].config_addr, 2, - (void *) config_addr); - if (err < 0) { - WARN("Read cell failed for %s\n", prop_names[i].config_addr); - return -1; - } - - err = fdtw_read_cells(dtb, node, prop_names[i].config_max_size, 1, - (void *) config_size); - if (err < 0) { - WARN("Read cell failed for %s\n", prop_names[i].config_max_size); - return -1; - } - - VERBOSE("Dyn cfg: Read config_id %d load info from TB_FW_CONFIG 0x%llx 0x%x\n", - config_id, (unsigned long long)*config_addr, *config_size); - - return 0; -} - -/******************************************************************************* - * Helper to read the `disable_auth` property in config DTB. This function - * expects the following properties to be present in the config DTB. - * name : disable_auth size : 1 cell - * - * Arguments: - * void *dtb - pointer to the TB_FW_CONFIG in memory - * int node - The node offset to appropriate node in the - * DTB. - * uint64_t *disable_auth - The value of `disable_auth` property on - * successful read. Must be 0 or 1. - * - * Returns 0 on success and -1 on error. - ******************************************************************************/ -int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth) -{ - int err; - - assert(dtb != NULL); - assert(disable_auth != NULL); - - /* Check if the pointer to DT is correct */ - assert(fdt_check_header(dtb) == 0); - - /* Assert the node offset point to "arm,tb_fw" compatible property */ - assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); - - /* Locate the disable_auth cell and read the value */ - err = fdtw_read_cells(dtb, node, "disable_auth", 1, disable_auth); - if (err < 0) { - WARN("Read cell failed for `disable_auth`\n"); - return -1; - } +#if MEASURED_BOOT +#define DTB_PROP_BL2_HASH_DATA "bl2_hash_data" +#ifdef SPD_opteed +/* + * Currently OP-TEE does not support reading DTBs from Secure memory + * and this property should be removed when this feature is supported. + */ +#define DTB_PROP_HW_SM_LOG_ADDR "tpm_event_log_sm_addr" +#endif +#define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr" +#define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size" - /* Check if the value is boolean */ - if ((*disable_auth != 0U) && (*disable_auth != 1U)) { - WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth); - return -1; - } - - VERBOSE("Dyn cfg: `disable_auth` cell found with value = %d\n", - *disable_auth); - return 0; -} +static int dtb_root = -1; +#endif /* MEASURED_BOOT */ /******************************************************************************* * Validate the tb_fw_config is a valid DTB file and returns the node offset @@ -154,62 +50,22 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) /* Check if the pointer to DT is correct */ if (fdt_check_header(dtb) != 0) { - WARN("Invalid DTB file passed as TB_FW_CONFIG\n"); + WARN("Invalid DTB file passed as%s\n", " TB_FW_CONFIG"); return -1; } /* Assert the node offset point to "arm,tb_fw" compatible property */ *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"); if (*node < 0) { - WARN("The compatible property `arm,tb_fw` not found in the config\n"); - return -1; - } - - VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n"); - return 0; -} - -/* - * Reads and returns the Mbed TLS shared heap information from the DTB. - * This function is supposed to be called *only* when a DTB is present. - * This function is supposed to be called only by BL2. - * - * Returns: - * 0 = success - * -1 = error. In this case the values of heap_addr, heap_size should be - * considered as garbage by the caller. - */ -int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, - size_t *heap_size) -{ - int err, dtb_root; - - /* Verify the DTB is valid and get the root node */ - err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG. Cannot retrieve Mbed TLS heap information from DTB\n"); + WARN("The compatible property '%s' not%s", "arm,tb_fw", + " found in the config\n"); return -1; } - /* Retrieve the Mbed TLS heap details from the DTB */ - err = fdtw_read_cells(dtb, dtb_root, - DTB_PROP_MBEDTLS_HEAP_ADDR, 2, heap_addr); - if (err < 0) { - ERROR("Error while reading %s from DTB\n", - DTB_PROP_MBEDTLS_HEAP_ADDR); - return -1; - } - err = fdtw_read_cells(dtb, dtb_root, - DTB_PROP_MBEDTLS_HEAP_SIZE, 1, heap_size); - if (err < 0) { - ERROR("Error while reading %s from DTB\n", - DTB_PROP_MBEDTLS_HEAP_SIZE); - return -1; - } + VERBOSE("Dyn cfg: '%s'%s", "arm,tb_fw", " found in the config\n"); return 0; } - /* * This function writes the Mbed TLS heap address and size in the DTB. When it * is called, it is guaranteed that a DTB is available. However it is not @@ -221,19 +77,21 @@ int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, * * Returns: * 0 = success - * 1 = error + * -1 = error */ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) { - int err, dtb_root; - +#if !MEASURED_BOOT + int dtb_root; +#endif /* * Verify that the DTB is valid, before attempting to write to it, * and get the DTB root node. */ - err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); + int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); if (err < 0) { - ERROR("Invalid TB_FW_CONFIG loaded. Unable to get root node\n"); + ERROR("Invalid%s loaded. Unable to get root node\n", + " TB_FW_CONFIG"); return -1; } @@ -247,18 +105,199 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) err = fdtw_write_inplace_cells(dtb, dtb_root, DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr); if (err < 0) { - ERROR("Unable to write DTB property %s\n", - DTB_PROP_MBEDTLS_HEAP_ADDR); + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_MBEDTLS_HEAP_ADDR); return -1; } err = fdtw_write_inplace_cells(dtb, dtb_root, DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size); if (err < 0) { - ERROR("Unable to write DTB property %s\n", - DTB_PROP_MBEDTLS_HEAP_SIZE); + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_MBEDTLS_HEAP_SIZE); return -1; } return 0; } + +#if MEASURED_BOOT +/* + * This function writes the BL2 hash data in HW_FW_CONFIG DTB. + * When it is called, it is guaranteed that a DTB is available. + * + * This function is supposed to be called only by BL1. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_bl2_hash_info(void *dtb, void *data) +{ + assert(dtb_root >= 0); + + /* + * Write the BL2 hash data in the DTB. + */ + return fdtw_write_inplace_bytes(dtb, dtb_root, + DTB_PROP_BL2_HASH_DATA, + TCG_DIGEST_SIZE, data); +} + +/* + * Write the Event Log address and its size in the DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +static int arm_set_event_log_info(uintptr_t config_base, +#ifdef SPD_opteed + uintptr_t sm_log_addr, +#endif + uintptr_t log_addr, size_t log_size) +{ + /* As libfdt uses void *, we can't avoid this cast */ + void *dtb = (void *)config_base; + const char *compatible = "arm,tpm_event_log"; + int err, node; + + /* + * Verify that the DTB is valid, before attempting to write to it, + * and get the DTB root node. + */ + + /* Check if the pointer to DT is correct */ + err = fdt_check_header(dtb); + if (err < 0) { + WARN("Invalid DTB file passed\n"); + return err; + } + + /* Assert the node offset point to compatible property */ + node = fdt_node_offset_by_compatible(dtb, -1, compatible); + if (node < 0) { + WARN("The compatible property '%s' not%s", compatible, + " found in the config\n"); + return node; + } + + VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n"); + +#ifdef SPD_opteed + if (sm_log_addr != 0UL) { + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_SM_LOG_ADDR, 2, &sm_log_addr); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_SM_LOG_ADDR); + return err; + } + } +#endif + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_LOG_ADDR, 2, &log_addr); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_LOG_ADDR); + return err; + } + + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_LOG_SIZE, 1, &log_size); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_LOG_SIZE); + } else { + /* + * Ensure that the info written to the DTB is visible + * to other images. + */ + flush_dcache_range(config_base, fdt_totalsize(dtb)); + } + + return err; +} + +/* + * This function writes the Event Log address and its size + * in the TOS_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr, + size_t log_size) +{ + int err; + + assert(config_base != 0UL); + assert(log_addr != 0UL); + + /* Write the Event Log address and its size in the DTB */ + err = arm_set_event_log_info(config_base, +#ifdef SPD_opteed + 0UL, +#endif + log_addr, log_size); + if (err < 0) { + ERROR("%sEvent Log data to TOS_FW_CONFIG\n", + "Unable to write "); + } + + return err; +} + +/* + * This function writes the Event Log address and its size + * in the NT_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_nt_fw_info(uintptr_t config_base, +#ifdef SPD_opteed + uintptr_t log_addr, +#endif + size_t log_size, uintptr_t *ns_log_addr) +{ + uintptr_t ns_addr; + const bl_mem_params_node_t *cfg_mem_params; + int err; + + assert(config_base != 0UL); + assert(ns_log_addr != NULL); + + /* Get the config load address and size from NT_FW_CONFIG */ + cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID); + assert(cfg_mem_params != NULL); + + /* Calculate Event Log address in Non-secure memory */ + ns_addr = cfg_mem_params->image_info.image_base + + cfg_mem_params->image_info.image_max_size; + + /* Check for memory space */ + if ((uint64_t)(ns_addr + log_size) > ARM_NS_DRAM1_END) { + return -1; + } + + /* Write the Event Log address and its size in the DTB */ + err = arm_set_event_log_info(config_base, +#ifdef SPD_opteed + log_addr, +#endif + ns_addr, log_size); + + /* Return Event Log address in Non-secure memory */ + *ns_log_addr = (err < 0) ? 0UL : ns_addr; + return err; +} +#endif /* MEASURED_BOOT */ diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index 2faaa76c4..ed7f1f5a5 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,9 @@ #include <assert.h> #include <common/bl_common.h> #include <common/desc_image_load.h> +#if defined(SPD_spmd) +#include <plat/arm/common/fconf_arm_sp_getter.h> +#endif #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> @@ -29,12 +32,62 @@ void plat_flush_next_bl_params(void) next_bl_params_cpy_ptr); } +#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 +/******************************************************************************* + * This function appends Secure Partitions to list of loadable images. + ******************************************************************************/ +static void plat_add_sp_images_load_info(struct bl_load_info *load_info) +{ + bl_load_info_node_t *node_info = load_info->head; + unsigned int index = 0; + + if (sp_mem_params_descs[index].image_id == 0) { + ERROR("No Secure Partition Image available\n"); + return; + } + + /* Traverse through the bl images list */ + do { + node_info = node_info->next_load_info; + } while (node_info->next_load_info != NULL); + + for (; index < MAX_SP_IDS; index++) { + /* Populate the image information */ + node_info->image_id = sp_mem_params_descs[index].image_id; + node_info->image_info = &sp_mem_params_descs[index].image_info; + + if ((index + 1U) == MAX_SP_IDS) { + INFO("Reached Max number of SPs\n"); + return; + } + + if (sp_mem_params_descs[index + 1U].image_id == 0) { + return; + } + + node_info->next_load_info = + &sp_mem_params_descs[index + 1U].load_node_mem; + node_info = node_info->next_load_info; + + } +} +#endif + /******************************************************************************* * This function returns the list of loadable images. ******************************************************************************/ struct bl_load_info *plat_get_bl_image_load_info(void) { +#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 + bl_load_info_t *bl_load_info; + + bl_load_info = get_bl_load_info_from_mem_params_desc(); + plat_add_sp_images_load_info(bl_load_info); + + return bl_load_info; +#else return get_bl_load_info_from_mem_params_desc(); +#endif } /******************************************************************************* diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index fc1eb490e..34b4101e1 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -1,263 +1,33 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include <assert.h> -#include <string.h> - -#include <platform_def.h> - #include <common/debug.h> #include <drivers/io/io_driver.h> #include <drivers/io/io_fip.h> #include <drivers/io/io_memmap.h> #include <drivers/io/io_storage.h> #include <lib/utils.h> + +#include <plat/arm/common/arm_fconf_getter.h> +#include <plat/arm/common/arm_fconf_io_storage.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> -#include <tools_share/firmware_image_package.h> +#include <platform_def.h> /* IO devices */ static const io_dev_connector_t *fip_dev_con; -static uintptr_t fip_dev_handle; +uintptr_t fip_dev_handle; static const io_dev_connector_t *memmap_dev_con; -static uintptr_t memmap_dev_handle; - -static const io_block_spec_t fip_block_spec = { - .offset = PLAT_ARM_FIP_BASE, - .length = PLAT_ARM_FIP_MAX_SIZE -}; - -static const io_uuid_spec_t bl2_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, -}; - -static const io_uuid_spec_t scp_bl2_uuid_spec = { - .uuid = UUID_SCP_FIRMWARE_SCP_BL2, -}; - -static const io_uuid_spec_t bl31_uuid_spec = { - .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, -}; - -static const io_uuid_spec_t bl32_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32, -}; - -static const io_uuid_spec_t bl32_extra1_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, -}; - -static const io_uuid_spec_t bl32_extra2_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, -}; - -static const io_uuid_spec_t bl33_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, -}; - -static const io_uuid_spec_t tb_fw_config_uuid_spec = { - .uuid = UUID_TB_FW_CONFIG, -}; - -static const io_uuid_spec_t hw_config_uuid_spec = { - .uuid = UUID_HW_CONFIG, -}; - -static const io_uuid_spec_t soc_fw_config_uuid_spec = { - .uuid = UUID_SOC_FW_CONFIG, -}; - -static const io_uuid_spec_t tos_fw_config_uuid_spec = { - .uuid = UUID_TOS_FW_CONFIG, -}; - -static const io_uuid_spec_t nt_fw_config_uuid_spec = { - .uuid = UUID_NT_FW_CONFIG, -}; - -#if TRUSTED_BOARD_BOOT -static const io_uuid_spec_t tb_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FW_CERT, -}; - -static const io_uuid_spec_t trusted_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_KEY_CERT, -}; - -static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { - .uuid = UUID_SCP_FW_KEY_CERT, -}; - -static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { - .uuid = UUID_SOC_FW_KEY_CERT, -}; - -static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, -}; - -static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, -}; - -static const io_uuid_spec_t scp_fw_cert_uuid_spec = { - .uuid = UUID_SCP_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t soc_fw_cert_uuid_spec = { - .uuid = UUID_SOC_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t tos_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t nt_fw_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, -}; -#endif /* TRUSTED_BOARD_BOOT */ - - -static int open_fip(const uintptr_t spec); -static int open_memmap(const uintptr_t spec); - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -/* By default, ARM platforms load images from the FIP */ -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - &memmap_dev_handle, - (uintptr_t)&fip_block_spec, - open_memmap - }, - [BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl2_uuid_spec, - open_fip - }, - [SCP_BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_bl2_uuid_spec, - open_fip - }, - [BL31_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl31_uuid_spec, - open_fip - }, - [BL32_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_uuid_spec, - open_fip - }, - [BL32_EXTRA1_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra1_uuid_spec, - open_fip - }, - [BL32_EXTRA2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra2_uuid_spec, - open_fip - }, - [BL33_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl33_uuid_spec, - open_fip - }, - [TB_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&tb_fw_config_uuid_spec, - open_fip - }, - [HW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&hw_config_uuid_spec, - open_fip - }, - [SOC_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_config_uuid_spec, - open_fip - }, - [TOS_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_config_uuid_spec, - open_fip - }, - [NT_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_config_uuid_spec, - open_fip - }, -#if TRUSTED_BOARD_BOOT - [TRUSTED_BOOT_FW_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tb_fw_cert_uuid_spec, - open_fip - }, - [TRUSTED_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&trusted_key_cert_uuid_spec, - open_fip - }, - [SCP_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_fw_key_cert_uuid_spec, - open_fip - }, - [SOC_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_key_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_key_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_key_cert_uuid_spec, - open_fip - }, - [SCP_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_fw_cert_uuid_spec, - open_fip - }, - [SOC_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_cert_uuid_spec, - open_fip - }, -#endif /* TRUSTED_BOARD_BOOT */ -}; - +uintptr_t memmap_dev_handle; /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_arm_io_setup #pragma weak plat_arm_get_alt_image_source - -static int open_fip(const uintptr_t spec) +int open_fip(const uintptr_t spec) { int result; uintptr_t local_image_handle; @@ -274,8 +44,7 @@ static int open_fip(const uintptr_t spec) return result; } - -static int open_memmap(const uintptr_t spec) +int open_memmap(const uintptr_t spec) { int result; uintptr_t local_image_handle; @@ -291,33 +60,41 @@ static int open_memmap(const uintptr_t spec) return result; } - -void arm_io_setup(void) +int arm_io_setup(void) { int io_result; io_result = register_io_dev_fip(&fip_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = register_io_dev_memmap(&memmap_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } /* Open connections to devices and cache the handles */ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, &memmap_dev_handle); - assert(io_result == 0); - /* Ignore improbable errors in release builds */ - (void)io_result; + return io_result; } void plat_arm_io_setup(void) { - arm_io_setup(); + int err; + + err = arm_io_setup(); + if (err < 0) { + panic(); + } } int plat_arm_get_alt_image_source( @@ -337,9 +114,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, int result; const struct plat_io_policy *policy; - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; + policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); result = policy->check(policy->image_spec); if (result == 0) { *image_spec = policy->image_spec; @@ -357,12 +132,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, * See if a Firmware Image Package is available, * by checking if TOC is valid or not. */ -int arm_io_is_toc_valid(void) +bool arm_io_is_toc_valid(void) { - int result; - - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - - return (result == 0); + return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); } - diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c index b9181eb4c..1fa234d79 100644 --- a/plat/arm/common/arm_nor_psci_mem_protect.c +++ b/plat/arm/common/arm_nor_psci_mem_protect.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,6 @@ #include <common/debug.h> #include <drivers/cfi/v2m_flash.h> #include <lib/psci/psci.h> -#include <lib/mmio.h> #include <lib/utils.h> #include <plat/arm/common/plat_arm.h> diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c index c95f4523c..5434c9457 100644 --- a/plat/arm/common/arm_pm.c +++ b/plat/arm/common/arm_pm.c @@ -1,11 +1,10 @@ /* - * 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 */ #include <assert.h> -#include <errno.h> #include <platform_def.h> diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c index 34e650f19..370ef0a86 100644 --- a/plat/arm/common/arm_tzc400.c +++ b/plat/arm/common/arm_tzc400.c @@ -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 */ @@ -19,7 +19,8 @@ * When booting an EL3 payload, this is simplified: we configure region 0 with * secure access only and do not enable any other region. ******************************************************************************/ -void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) +void arm_tzc400_setup(uintptr_t tzc_base, + const arm_tzc_regions_info_t *tzc_regions) { #ifndef EL3_PAYLOAD_BASE unsigned int region_index = 1U; @@ -32,7 +33,7 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) INFO("Configuring TrustZone Controller\n"); - tzc400_init(PLAT_ARM_TZC_BASE); + tzc400_init(tzc_base); /* Disable filters. */ tzc400_disable_filters(); @@ -74,5 +75,5 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) void plat_arm_security_setup(void) { - arm_tzc400_setup(NULL); + arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL); } diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c new file mode 100644 index 000000000..48286c2f2 --- /dev/null +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <drivers/io/io_storage.h> +#include <lib/object_pool.h> +#include <libfdt.h> +#include <tools_share/firmware_image_package.h> + +#include <plat/arm/common/arm_fconf_getter.h> +#include <plat/arm/common/arm_fconf_io_storage.h> +#include <platform_def.h> + +const io_block_spec_t fip_block_spec = { + .offset = PLAT_ARM_FIP_BASE, + .length = PLAT_ARM_FIP_MAX_SIZE +}; + +const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { + [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2}, + [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG}, + [FW_CONFIG_ID] = {UUID_FW_CONFIG}, +#if !ARM_IO_IN_DTB + [SCP_BL2_IMAGE_ID] = {UUID_SCP_FIRMWARE_SCP_BL2}, + [BL31_IMAGE_ID] = {UUID_EL3_RUNTIME_FIRMWARE_BL31}, + [BL32_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32}, + [BL32_EXTRA1_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32_EXTRA1}, + [BL32_EXTRA2_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32_EXTRA2}, + [BL33_IMAGE_ID] = {UUID_NON_TRUSTED_FIRMWARE_BL33}, + [HW_CONFIG_ID] = {UUID_HW_CONFIG}, + [SOC_FW_CONFIG_ID] = {UUID_SOC_FW_CONFIG}, + [TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG}, + [NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG}, +#endif /* ARM_IO_IN_DTB */ +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT}, +#if !ARM_IO_IN_DTB + [TRUSTED_KEY_CERT_ID] = {UUID_TRUSTED_KEY_CERT}, + [SCP_FW_KEY_CERT_ID] = {UUID_SCP_FW_KEY_CERT}, + [SOC_FW_KEY_CERT_ID] = {UUID_SOC_FW_KEY_CERT}, + [TRUSTED_OS_FW_KEY_CERT_ID] = {UUID_TRUSTED_OS_FW_KEY_CERT}, + [NON_TRUSTED_FW_KEY_CERT_ID] = {UUID_NON_TRUSTED_FW_KEY_CERT}, + [SCP_FW_CONTENT_CERT_ID] = {UUID_SCP_FW_CONTENT_CERT}, + [SOC_FW_CONTENT_CERT_ID] = {UUID_SOC_FW_CONTENT_CERT}, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = {UUID_TRUSTED_OS_FW_CONTENT_CERT}, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT}, +#if defined(SPD_spmd) + [SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT}, + [PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT}, +#endif +#endif /* ARM_IO_IN_DTB */ +#endif /* TRUSTED_BOARD_BOOT */ +}; + +/* By default, ARM platforms load images from the FIP */ +struct plat_io_policy policies[MAX_NUMBER_IDS] = { + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, + [BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL2_IMAGE_ID], + open_fip + }, + [TB_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID], + open_fip + }, + [FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[FW_CONFIG_ID], + open_fip + }, +#if !ARM_IO_IN_DTB + [SCP_BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SCP_BL2_IMAGE_ID], + open_fip + }, + [BL31_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL31_IMAGE_ID], + open_fip + }, + [BL32_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL32_IMAGE_ID], + open_fip + }, + [BL32_EXTRA1_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL32_EXTRA1_IMAGE_ID], + open_fip + }, + [BL32_EXTRA2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL32_EXTRA2_IMAGE_ID], + open_fip + }, + [BL33_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL33_IMAGE_ID], + open_fip + }, + [HW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[HW_CONFIG_ID], + open_fip + }, + [SOC_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SOC_FW_CONFIG_ID], + open_fip + }, + [TOS_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TOS_FW_CONFIG_ID], + open_fip + }, + [NT_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[NT_FW_CONFIG_ID], + open_fip + }, +#endif /* ARM_IO_IN_DTB */ +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_BOOT_FW_CERT_ID], + open_fip + }, +#if !ARM_IO_IN_DTB + [TRUSTED_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_KEY_CERT_ID], + open_fip + }, + [SCP_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SCP_FW_KEY_CERT_ID], + open_fip + }, + [SOC_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SOC_FW_KEY_CERT_ID], + open_fip + }, + [TRUSTED_OS_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_OS_FW_KEY_CERT_ID], + open_fip + }, + [NON_TRUSTED_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_KEY_CERT_ID], + open_fip + }, + [SCP_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SCP_FW_CONTENT_CERT_ID], + open_fip + }, + [SOC_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SOC_FW_CONTENT_CERT_ID], + open_fip + }, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_OS_FW_CONTENT_CERT_ID], + open_fip + }, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_CONTENT_CERT_ID], + open_fip + }, +#if defined(SPD_spmd) + [SIP_SP_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SIP_SP_CONTENT_CERT_ID], + open_fip + }, + [PLAT_SP_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[PLAT_SP_CONTENT_CERT_ID], + open_fip + }, +#endif +#endif /* ARM_IO_IN_DTB */ +#endif /* TRUSTED_BOARD_BOOT */ +}; + +#ifdef IMAGE_BL2 + +#if TRUSTED_BOARD_BOOT +#define FCONF_ARM_IO_UUID_NUMBER U(21) +#else +#define FCONF_ARM_IO_UUID_NUMBER U(10) +#endif + +static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER]; +static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_uuids); + +struct policies_load_info { + unsigned int image_id; + const char *name; +}; + +/* image id to property name table */ +static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = { + {SCP_BL2_IMAGE_ID, "scp_bl2_uuid"}, + {BL31_IMAGE_ID, "bl31_uuid"}, + {BL32_IMAGE_ID, "bl32_uuid"}, + {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"}, + {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"}, + {BL33_IMAGE_ID, "bl33_uuid"}, + {HW_CONFIG_ID, "hw_cfg_uuid"}, + {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"}, + {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"}, + {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"}, +#if TRUSTED_BOARD_BOOT + {TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"}, + {SCP_FW_KEY_CERT_ID, "scp_fw_key_uuid"}, + {SOC_FW_KEY_CERT_ID, "soc_fw_key_uuid"}, + {TRUSTED_OS_FW_KEY_CERT_ID, "tos_fw_key_cert_uuid"}, + {NON_TRUSTED_FW_KEY_CERT_ID, "nt_fw_key_cert_uuid"}, + {SCP_FW_CONTENT_CERT_ID, "scp_fw_content_cert_uuid"}, + {SOC_FW_CONTENT_CERT_ID, "soc_fw_content_cert_uuid"}, + {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"}, + {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"}, +#if defined(SPD_spmd) + {SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"}, + {PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"}, +#endif +#endif /* TRUSTED_BOARD_BOOT */ +}; + +int fconf_populate_arm_io_policies(uintptr_t config) +{ + int err, node; + unsigned int i; + unsigned int j; + + union uuid_helper_t uuid_helper; + io_uuid_spec_t *uuid_ptr; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,io-fip-handle" compatible property */ + const char *compatible_str = "arm,io-fip-handle"; + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); + return node; + } + + /* Locate the uuid cells and read the value for all the load info uuid */ + for (i = 0; i < FCONF_ARM_IO_UUID_NUMBER; i++) { + uuid_ptr = pool_alloc(&fconf_arm_uuids_pool); + err = fdt_read_uint32_array(dtb, node, load_info[i].name, + 4, uuid_helper.word); + if (err < 0) { + WARN("FCONF: Read cell failed for %s\n", load_info[i].name); + return err; + } + + /* Convert uuid from big endian to little endian */ + for (j = 0U; j < 4U; j++) { + uuid_helper.word[j] = + ((uuid_helper.word[j] >> 24U) & 0xff) | + ((uuid_helper.word[j] << 8U) & 0xff0000) | + ((uuid_helper.word[j] >> 8U) & 0xff00) | + ((uuid_helper.word[j] << 24U) & 0xff000000); + } + + VERBOSE("FCONF: arm-io_policies.%s cell found with value = 0x%x 0x%x 0x%x 0x%x\n", + load_info[i].name, + uuid_helper.word[0], uuid_helper.word[1], + uuid_helper.word[2], uuid_helper.word[3]); + + uuid_ptr->uuid = uuid_helper.uuid_struct; + policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr; + policies[load_info[i].image_id].dev_handle = &fip_dev_handle; + policies[load_info[i].image_id].check = open_fip; + } + return 0; +} + +#if ARM_IO_IN_DTB +FCONF_REGISTER_POPULATOR(TB_FW, arm_io, fconf_populate_arm_io_policies); +#endif /* ARM_IO_IN_DTB */ + +#endif /* IMAGE_BL2 */ diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c new file mode 100644 index 000000000..7950e7f6d --- /dev/null +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <common/debug.h> +#include <common/desc_image_load.h> +#include <common/fdt_wrappers.h> +#include <drivers/io/io_storage.h> +#include <lib/object_pool.h> +#include <libfdt.h> +#include <plat/arm/common/arm_fconf_getter.h> +#include <plat/arm/common/arm_fconf_io_storage.h> +#include <plat/arm/common/fconf_arm_sp_getter.h> +#include <platform_def.h> +#include <tools_share/firmware_image_package.h> + +#ifdef IMAGE_BL2 + +bl_mem_params_node_t sp_mem_params_descs[MAX_SP_IDS]; + +struct arm_sp_t arm_sp; + +int fconf_populate_arm_sp(uintptr_t config) +{ + int sp_node, node, err; + union uuid_helper_t uuid_helper; + unsigned int index = 0; + uint32_t val32; + bool is_plat_owned = false; + const unsigned int sip_start = SP_PKG1_ID; + unsigned int sip_index = sip_start; + const unsigned int sip_end = sip_start + MAX_SP_IDS / 2; + const unsigned int plat_start = SP_PKG5_ID; + unsigned int plat_index = plat_start; + const unsigned int plat_end = plat_start + MAX_SP_IDS / 2; + unsigned int j; + + /* As libfdt use void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,sp" compatible property */ + const char *compatible_str = "arm,sp"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s in dtb\n", compatible_str); + return node; + } + + fdt_for_each_subnode(sp_node, dtb, node) { + if ((index == MAX_SP_IDS) || (sip_index == sip_end) + || (plat_index == plat_end)) { + ERROR("FCONF: Reached max number of SPs\n"); + return -1; + } + + /* Read UUID */ + err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4, + uuid_helper.word); + if (err < 0) { + ERROR("FCONF: cannot read SP uuid\n"); + return -1; + } + + /* Convert uuid from big endian to little endian */ + for (j = 0U; j < 4U; j++) { + uuid_helper.word[j] = + ((uuid_helper.word[j] >> 24U) & 0xff) | + ((uuid_helper.word[j] << 8U) & 0xff0000) | + ((uuid_helper.word[j] >> 8U) & 0xff00) | + ((uuid_helper.word[j] << 24U) & 0xff000000); + } + + arm_sp.uuids[index] = uuid_helper; + VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n", + __func__, + uuid_helper.word[0], + uuid_helper.word[1], + uuid_helper.word[2], + uuid_helper.word[3], + arm_sp.load_addr[index]); + + /* Read Load address */ + err = fdt_read_uint32(dtb, sp_node, "load-address", &val32); + if (err < 0) { + ERROR("FCONF: cannot read SP load address\n"); + return -1; + } + arm_sp.load_addr[index] = val32; + + /* Read owner field only for dualroot CoT */ +#if defined(ARM_COT_dualroot) + /* Owner is an optional field, no need to catch error */ + fdtw_read_string(dtb, sp_node, "owner", + arm_sp.owner[index], ARM_SP_OWNER_NAME_LEN); +#endif + /* If owner is empty mark it as SiP owned */ + if ((strncmp(arm_sp.owner[index], "SiP", + ARM_SP_OWNER_NAME_LEN) == 0) || + (strncmp(arm_sp.owner[index], "", + ARM_SP_OWNER_NAME_LEN) == 0)) { + is_plat_owned = false; + } else if (strcmp(arm_sp.owner[index], "Plat") == 0) { + is_plat_owned = true; + } else { + ERROR("FCONF: %s is not a valid SP owner\n", + arm_sp.owner[index]); + return -1; + } + /* + * Add SP information in mem param descriptor and IO policies + * structure. + */ + if (is_plat_owned) { + sp_mem_params_descs[index].image_id = plat_index; + policies[plat_index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[plat_index].dev_handle = &fip_dev_handle; + policies[plat_index].check = open_fip; + plat_index++; + } else { + sp_mem_params_descs[index].image_id = sip_index; + policies[sip_index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[sip_index].dev_handle = &fip_dev_handle; + policies[sip_index].check = open_fip; + sip_index++; + } + SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info, + PARAM_IMAGE_BINARY, VERSION_2, 0); + sp_mem_params_descs[index].image_info.image_max_size = + ARM_SP_MAX_SIZE; + sp_mem_params_descs[index].next_handoff_image_id = + INVALID_IMAGE_ID; + sp_mem_params_descs[index].image_info.image_base = + arm_sp.load_addr[index]; + index++; + } + + if ((sp_node < 0) && (sp_node != -FDT_ERR_NOTFOUND)) { + ERROR("%u: fdt_for_each_subnode(): %d\n", __LINE__, node); + return sp_node; + } + + arm_sp.number_of_sp = index; + return 0; +} + +FCONF_REGISTER_POPULATOR(TB_FW, arm_sp, fconf_populate_arm_sp); + +#endif /* IMAGE_BL2 */ diff --git a/plat/arm/common/fconf/fconf_nv_cntr_getter.c b/plat/arm/common/fconf/fconf_nv_cntr_getter.c new file mode 100644 index 000000000..8d645ef3d --- /dev/null +++ b/plat/arm/common/fconf/fconf_nv_cntr_getter.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <common/debug.h> +#include <common/fdt_wrappers.h> + +#include <libfdt.h> + +#include <plat/arm/common/fconf_nv_cntr_getter.h> + +/******************************************************************************* + * fconf_populate_cot_descs() - Populate available nv-counters and update global + * structure. + * @config[in]: Pointer to the device tree blob in memory + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int fconf_populate_nv_cntrs(uintptr_t config) +{ + int rc, node, child; + uint32_t id; + uintptr_t reg; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + const char *compatible_str = "arm, non-volatile-counter"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in node\n", + compatible_str); + return node; + } + + fdt_for_each_subnode(child, dtb, node) { + + rc = fdt_read_uint32(dtb, child, "id", &id); + if (rc < 0) { + ERROR("FCONF: Can't find %s property in node\n", "id"); + return rc; + } + + assert(id < MAX_NV_CTR_IDS); + + rc = fdt_get_reg_props_by_index(dtb, child, 0, ®, NULL); + if (rc < 0) { + ERROR("FCONF: Can't find %s property in node\n", "reg"); + return rc; + } + + nv_cntr_base_addr[id] = reg; + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(TB_FW, nv_cntrs, fconf_populate_nv_cntrs); diff --git a/plat/arm/common/fconf/fconf_sdei_getter.c b/plat/arm/common/fconf/fconf_sdei_getter.c new file mode 100644 index 000000000..c26e316a5 --- /dev/null +++ b/plat/arm/common/fconf/fconf_sdei_getter.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <assert.h> + +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <libfdt.h> +#include <plat/arm/common/fconf_sdei_getter.h> + +#define PRIVATE_EVENT_NUM(i) private_events[3 * (i)] +#define PRIVATE_EVENT_INTR(i) private_events[3 * (i) + 1] +#define PRIVATE_EVENT_FLAGS(i) private_events[3 * (i) + 2] + +#define SHARED_EVENT_NUM(i) shared_events[3 * (i)] +#define SHARED_EVENT_INTR(i) shared_events[3 * (i) + 1] +#define SHARED_EVENT_FLAGS(i) shared_events[3 * (i) + 2] + +struct sdei_dyn_config_t sdei_dyn_config; + +int fconf_populate_sdei_dyn_config(uintptr_t config) +{ + uint32_t i; + int node, err; + uint32_t private_events[PLAT_SDEI_DP_EVENT_MAX_CNT * 3]; + uint32_t shared_events[PLAT_SDEI_DS_EVENT_MAX_CNT * 3]; + + const void *dtb = (void *)config; + + /* Check that the node offset points to compatible property */ + node = fdt_node_offset_by_compatible(dtb, -1, "arm,sdei-1.0"); + if (node < 0) { + ERROR("FCONF: Can't find 'arm,sdei-1.0' compatible node in dtb\n"); + return node; + } + + /* Read number of private mappings */ + err = fdt_read_uint32(dtb, node, "private_event_count", + &sdei_dyn_config.private_ev_cnt); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'private_event_count': %u\n", + sdei_dyn_config.private_ev_cnt); + return err; + } + + /* Check if the value is in range */ + if (sdei_dyn_config.private_ev_cnt > PLAT_SDEI_DP_EVENT_MAX_CNT) { + ERROR("FCONF: Invalid value for 'private_event_count': %u\n", + sdei_dyn_config.private_ev_cnt); + return -1; + } + + /* Read private mappings */ + err = fdt_read_uint32_array(dtb, node, "private_events", + sdei_dyn_config.private_ev_cnt * 3, private_events); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'private_events': %d\n", err); + return err; + } + + /* Move data to fconf struct */ + for (i = 0; i < sdei_dyn_config.private_ev_cnt; i++) { + sdei_dyn_config.private_ev_nums[i] = PRIVATE_EVENT_NUM(i); + sdei_dyn_config.private_ev_intrs[i] = PRIVATE_EVENT_INTR(i); + sdei_dyn_config.private_ev_flags[i] = PRIVATE_EVENT_FLAGS(i); + } + + /* Read number of shared mappings */ + err = fdt_read_uint32(dtb, node, "shared_event_count", + &sdei_dyn_config.shared_ev_cnt); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'shared_event_count'\n"); + return err; + } + + /* Check if the value is in range */ + if (sdei_dyn_config.shared_ev_cnt > PLAT_SDEI_DS_EVENT_MAX_CNT) { + ERROR("FCONF: Invalid value for 'shared_event_count': %u\n", + sdei_dyn_config.shared_ev_cnt); + return -1; + } + + /* Read shared mappings */ + err = fdt_read_uint32_array(dtb, node, "shared_events", + sdei_dyn_config.shared_ev_cnt * 3, shared_events); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'shared_events': %d\n", err); + return err; + } + + /* Move data to fconf struct */ + for (i = 0; i < sdei_dyn_config.shared_ev_cnt; i++) { + sdei_dyn_config.shared_ev_nums[i] = SHARED_EVENT_NUM(i); + sdei_dyn_config.shared_ev_intrs[i] = SHARED_EVENT_INTR(i); + sdei_dyn_config.shared_ev_flags[i] = SHARED_EVENT_FLAGS(i); + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, sdei, fconf_populate_sdei_dyn_config); diff --git a/plat/arm/common/fconf/fconf_sec_intr_config.c b/plat/arm/common/fconf/fconf_sec_intr_config.c new file mode 100644 index 000000000..f28be240e --- /dev/null +++ b/plat/arm/common/fconf/fconf_sec_intr_config.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <assert.h> + +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <libfdt.h> +#include <plat/arm/common/fconf_sec_intr_config.h> + +#define G0_INTR_NUM(i) g0_intr_prop[3U * (i)] +#define G0_INTR_PRIORITY(i) g0_intr_prop[3U * (i) + 1] +#define G0_INTR_CONFIG(i) g0_intr_prop[3U * (i) + 2] + +#define G1S_INTR_NUM(i) g1s_intr_prop[3U * (i)] +#define G1S_INTR_PRIORITY(i) g1s_intr_prop[3U * (i) + 1] +#define G1S_INTR_CONFIG(i) g1s_intr_prop[3U * (i) + 2] + +struct sec_intr_prop_t sec_intr_prop; + +static void print_intr_prop(interrupt_prop_t prop) +{ + VERBOSE("FCONF: Secure Interrupt NUM: %d, PRI: %d, TYPE: %d\n", + prop.intr_num, prop.intr_pri, prop.intr_cfg); +} + +int fconf_populate_sec_intr_config(uintptr_t config) +{ + int node, err; + uint32_t g0_intr_count, g1s_intr_count; + uint32_t g0_intr_prop[SEC_INT_COUNT_MAX * 3]; + uint32_t g1s_intr_prop[SEC_INT_COUNT_MAX * 3]; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, + "arm,secure_interrupt_desc"); + if (node < 0) { + ERROR("FCONF: Unable to locate node with %s compatible property\n", + "arm,secure_interrupt_desc"); + return node; + } + + /* Read number of Group 0 interrupts specified by platform */ + err = fdt_read_uint32(hw_config_dtb, node, "g0_intr_cnt", &g0_intr_count); + if (err < 0) { + ERROR("FCONF: Could not locate g0s_intr_cnt property\n"); + return err; + } + + /* At least 1 Group 0 interrupt description has to be provided*/ + if (g0_intr_count < 1U) { + ERROR("FCONF: Invalid number of Group 0 interrupts count specified\n"); + return -1; + } + + /* Read number of Group 1 secure interrupts specified by platform */ + err = fdt_read_uint32(hw_config_dtb, node, "g1s_intr_cnt", + &g1s_intr_count); + if (err < 0) { + ERROR("FCONF: Could not locate g1s_intr_cnt property\n"); + return err; + } + + /* At least one Group 1 interrupt description has to be provided*/ + if (g1s_intr_count < 1U) { + ERROR("FCONF: Invalid number of Group 1 secure interrupts count specified\n"); + return -1; + } + + /* + * Check if the total number of secure interrupts described are within + * the limit defined statically by the platform. + */ + if ((g0_intr_count + g1s_intr_count) > SEC_INT_COUNT_MAX) { + ERROR("FCONF: Total number of secure interrupts exceed limit the of %d\n", + SEC_INT_COUNT_MAX); + return -1; + } + + sec_intr_prop.count = g0_intr_count + g1s_intr_count; + + /* Read the Group 0 interrupt descriptors */ + err = fdt_read_uint32_array(hw_config_dtb, node, "g0_intr_desc", + g0_intr_count * 3, g0_intr_prop); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'g0s_intr_desc': %d\n", err); + return err; + } + + /* Read the Group 1 secure interrupt descriptors */ + err = fdt_read_uint32_array(hw_config_dtb, node, "g1s_intr_desc", + g1s_intr_count * 3, g1s_intr_prop); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'g1s_intr_desc': %d\n", err); + return err; + } + + /* Populate Group 0 interrupt descriptors into fconf based C struct */ + for (uint32_t i = 0; i < g0_intr_count; i++) { + interrupt_prop_t sec_intr_property; + + /* Secure Interrupt Group: INTR_GROUP0 i.e., 0x1 */ + sec_intr_property.intr_grp = 1; + sec_intr_property.intr_num = G0_INTR_NUM(i); + sec_intr_property.intr_pri = G0_INTR_PRIORITY(i); + sec_intr_property.intr_cfg = G0_INTR_CONFIG(i); + sec_intr_prop.descriptor[i] = sec_intr_property; + print_intr_prop(sec_intr_property); + } + + /* Populate G1 secure interrupt descriptors into fconf based C struct */ + for (uint32_t i = 0; i < g1s_intr_count; i++) { + interrupt_prop_t sec_intr_property; + + /* Secure Interrupt Group: INTR_GROUP1S i.e., 0x0 */ + sec_intr_property.intr_grp = 0; + sec_intr_property.intr_num = G1S_INTR_NUM(i); + sec_intr_property.intr_pri = G1S_INTR_PRIORITY(i); + sec_intr_property.intr_cfg = G1S_INTR_CONFIG(i); + sec_intr_prop.descriptor[i + g0_intr_count] = sec_intr_property; + print_intr_prop(sec_intr_property); + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, sec_intr_prop, fconf_populate_sec_intr_config); diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index bb69914ae..270093c4e 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,6 @@ #include <bl32/sp_min/platform_sp_min.h> #include <common/bl_common.h> #include <common/debug.h> -#include <drivers/arm/pl011.h> #include <drivers/console.h> #include <lib/mmio.h> #include <plat/arm/common/plat_arm.h> @@ -30,10 +29,10 @@ static entry_point_info_t bl33_image_ep_info; MT_MEMORY | MT_RW | MT_SECURE) /* - * Check that BL32_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page + * Check that BL32_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. */ -CASSERT(BL32_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl32_base_overflows); +CASSERT(BL32_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl32_base_overflows); /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for the @@ -168,6 +167,10 @@ void arm_sp_min_plat_runtime_setup(void) { /* Initialize the runtime console */ arm_console_runtime_init(); + +#if PLAT_RO_XLAT_TABLES + arm_xlat_make_tables_readonly(); +#endif } /******************************************************************************* @@ -183,7 +186,7 @@ void sp_min_platform_setup(void) * Do initial security configuration to allow DRAM/device access * (if earlier BL has not already done so). */ -#if RESET_TO_SP_MIN +#if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME plat_arm_security_setup(); #if defined(PLAT_ARM_MEM_PROT_ADDR) @@ -214,7 +217,7 @@ void sp_min_plat_runtime_setup(void) * Perform the very early platform specific architectural setup here. At the * moment this only initializes the MMU ******************************************************************************/ -void sp_min_plat_arch_setup(void) +void arm_sp_min_plat_arch_setup(void) { const mmap_region_t bl_regions[] = { MAP_BL_SP_MIN_TOTAL, @@ -229,3 +232,8 @@ void sp_min_plat_arch_setup(void) enable_mmu_svc_mon(0); } + +void sp_min_plat_arch_setup(void) +{ + arm_sp_min_plat_arch_setup(); +} diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c index aefdf89c7..a4da8c35e 100644 --- a/plat/arm/common/tsp/arm_tsp_setup.c +++ b/plat/arm/common/tsp/arm_tsp_setup.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 */ @@ -28,7 +28,7 @@ /******************************************************************************* * Initialize the UART ******************************************************************************/ -static console_pl011_t arm_tsp_runtime_console; +static console_t arm_tsp_runtime_console; void arm_tsp_early_platform_setup(void) { @@ -43,7 +43,7 @@ void arm_tsp_early_platform_setup(void) if (rc == 0) panic(); - console_set_scope(&arm_tsp_runtime_console.console, + console_set_scope(&arm_tsp_runtime_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); } @@ -79,4 +79,8 @@ void tsp_plat_arch_setup(void) setup_page_tables(bl_regions, plat_arm_get_mmap()); enable_mmu_el1(0); + +#if PLAT_RO_XLAT_TABLES + arm_xlat_make_tables_readonly(); +#endif } diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index 01c674f82..926b8ec7c 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -1,11 +1,10 @@ /* - * 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 */ #include <assert.h> -#include <errno.h> #include <platform_def.h> @@ -15,7 +14,6 @@ #include <lib/cassert.h> #include <plat/arm/common/plat_arm.h> #include <plat/arm/css/common/css_pm.h> -#include <plat/common/platform.h> /* Allow CSS platforms to override `plat_arm_psci_pm_ops` */ #pragma weak plat_arm_psci_pm_ops @@ -125,9 +123,32 @@ static void css_power_down_common(const psci_power_state_t *target_state) /* Prevent interrupts from spuriously waking up this cpu */ plat_arm_gic_cpuif_disable(); + /* Turn redistributor off */ + plat_arm_gic_redistif_off(); + /* Cluster is to be turned off, so disable coherency */ - if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) + if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) { plat_arm_interconnect_exit_coherency(); + +#if HW_ASSISTED_COHERENCY + uint32_t reg; + + /* + * If we have determined this core to be the last man standing and we + * intend to power down the cluster proactively, we provide a hint to + * the power controller that cluster power is not required when all + * cores are powered down. + * Note that this is only an advisory to power controller and is supported + * by SoCs with DynamIQ Shared Units only. + */ + reg = read_clusterpwrdn(); + + /* Clear and set bit 0 : Cluster power not required */ + reg &= ~DSU_CLUSTER_PWR_MASK; + reg |= DSU_CLUSTER_PWR_OFF; + write_clusterpwrdn(reg); +#endif + } } /******************************************************************************* diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S index b80903d06..04bfb7771 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 e21457304..b805746de 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 */ @@ -9,20 +9,21 @@ #include <lib/utils_def.h> #include <lib/xlat_tables/xlat_tables_defs.h> -#include <plat/arm/board/common/board_css_def.h> -#include <plat/arm/board/common/v2m_def.h> #include <plat/arm/common/arm_def.h> #include <plat/arm/common/arm_spm_def.h> #include <plat/arm/css/common/css_def.h> -#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. @@ -34,15 +35,15 @@ # define PLAT_SP_IMAGE_MMAP_REGIONS 7 # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else -# define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 5 +# define PLAT_ARM_MMAP_ENTRIES (5 + ((CSS_SGI_CHIP_COUNT - 1) * 3)) +# define MAX_XLAT_TABLES (6 + ((CSS_SGI_CHIP_COUNT - 1) * 3)) # 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 @@ -52,7 +53,7 @@ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size * plus a little space for growth. */ -#define PLAT_ARM_MAX_BL1_RW_SIZE 0xB000 +#define PLAT_ARM_MAX_BL1_RW_SIZE 0xC000 /* * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page @@ -73,7 +74,7 @@ #if TRUSTED_BOARD_BOOT # define PLAT_ARM_MAX_BL2_SIZE 0x1D000 #else -# define PLAT_ARM_MAX_BL2_SIZE 0x11000 +# define PLAT_ARM_MAX_BL2_SIZE 0x14000 #endif /* @@ -119,6 +120,9 @@ #define PLAT_ARM_NSRAM_BASE 0x06000000 #define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */ +#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000) +#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) + #define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp) #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) @@ -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_NON_CACHEABLE | 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 000000000..a5fbded3c --- /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_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h new file mode 100644 index 000000000..03f107367 --- /dev/null +++ b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI_SOC_CSS_DEF_V2_H +#define SGI_SOC_CSS_DEF_V2_H + +#include <lib/utils_def.h> +#include <plat/common/common_def.h> + +/* + * Definitions common to all ARM CSS SoCs + */ + +/* Following covers ARM CSS SoC Peripherals */ + +#define SOC_SYSTEM_PERIPH_BASE UL(0x0C000000) +#define SOC_SYSTEM_PERIPH_SIZE UL(0x02000000) + +#define SOC_PLATFORM_PERIPH_BASE UL(0x0E000000) +#define SOC_PLATFORM_PERIPH_SIZE UL(0x02000000) + +#define SOC_CSS_PCIE_CONTROL_BASE UL(0x0ef20000) + +/* PL011 UART related constants */ +#define SOC_CSS_UART1_BASE UL(0x0ef80000) +#define SOC_CSS_UART0_BASE UL(0x0ef70000) + +/* Memory controller */ +#define SOC_MEMCNTRL_BASE UL(0x10000000) +#define SOC_MEMCNTRL_SIZE UL(0x10000000) + +#define SOC_CSS_UART0_CLK_IN_HZ UL(7372800) +#define SOC_CSS_UART1_CLK_IN_HZ UL(7372800) + +/* SoC NIC-400 Global Programmers View (GPV) */ +#define SOC_CSS_NIC400_BASE UL(0x0ED00000) + +#define SOC_CSS_NIC400_USB_EHCI U(0) +#define SOC_CSS_NIC400_TLX_MASTER U(1) +#define SOC_CSS_NIC400_USB_OHCI U(2) +#define SOC_CSS_NIC400_PL354_SMC U(3) +/* + * The apb4_bridge controls access to: + * - the PCIe configuration registers + * - the MMU units for USB, HDLCD and DMA + */ +#define SOC_CSS_NIC400_APB4_BRIDGE U(4) + +/* Non-volatile counters */ +#define SOC_TRUSTED_NVCTR_BASE UL(0x0EE70000) +#define TFW_NVCTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0000) +#define TFW_NVCTR_SIZE U(4) +#define NTFW_CTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0004) +#define NTFW_CTR_SIZE U(4) + +/* Keys */ +#define SOC_KEYS_BASE UL(0x0EE80000) +#define TZ_PUB_KEY_HASH_BASE (SOC_KEYS_BASE + 0x0000) +#define TZ_PUB_KEY_HASH_SIZE U(32) +#define HU_KEY_BASE (SOC_KEYS_BASE + 0x0020) +#define HU_KEY_SIZE U(16) +#define END_KEY_BASE (SOC_KEYS_BASE + 0x0044) +#define END_KEY_SIZE U(32) + +#define SOC_PLATFORM_PERIPH_MAP_DEVICE MAP_REGION_FLAT( \ + SOC_PLATFORM_PERIPH_BASE, \ + SOC_PLATFORM_PERIPH_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define SOC_SYSTEM_PERIPH_MAP_DEVICE MAP_REGION_FLAT( \ + SOC_SYSTEM_PERIPH_BASE, \ + SOC_SYSTEM_PERIPH_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define SOC_MEMCNTRL_MAP_DEVICE MAP_REGION_FLAT( \ + SOC_MEMCNTRL_BASE, \ + SOC_MEMCNTRL_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* + * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs. + */ +#define SOC_CSS_NIC400_BOOTSEC_BRIDGE U(5) +#define SOC_CSS_NIC400_BOOTSEC_BRIDGE_UART1 UL(1 << 12) + +/* + * Required platform porting definitions common to all ARM CSS SoCs + */ +/* 2MB used for SCP DDR retraining */ +#define PLAT_ARM_SCP_TZC_DRAM1_SIZE UL(0x00200000) + +/* V2M motherboard system registers & offsets */ +#define V2M_SYSREGS_BASE UL(0x0C010000) +#define V2M_SYS_LED U(0x8) + +/* + * V2M sysled bit definitions. The values written to this + * register are defined in arch.h & runtime_svc.h. Only + * used by the primary cpu to diagnose any cold boot issues. + * + * SYS_LED[0] - Security state (S=0/NS=1) + * SYS_LED[2:1] - Exception Level (EL3-EL0) + * SYS_LED[7:3] - Exception Class (Sync/Async & origin) + * + */ +#define V2M_SYS_LED_SS_SHIFT U(0) +#define V2M_SYS_LED_EL_SHIFT U(1) +#define V2M_SYS_LED_EC_SHIFT U(3) + +#define V2M_SYS_LED_SS_MASK U(0x01) +#define V2M_SYS_LED_EL_MASK U(0x03) +#define V2M_SYS_LED_EC_MASK U(0x1f) + +/* NOR Flash */ +#define V2M_FLASH0_BASE UL(0x08000000) +#define V2M_FLASH0_SIZE UL(0x04000000) +#define V2M_FLASH_BLOCK_SIZE UL(0x00040000) /* 256 KB */ + +/* + * The flash can be mapped either as read-only or read-write. + * + * If it is read-write then it should also be mapped as device memory because + * NOR flash programming involves sending a fixed, ordered sequence of commands. + * + * If it is read-only then it should also be mapped as: + * - Normal memory, because reading from NOR flash is transparent, it is like + * reading from RAM. + * - Non-executable by default. If some parts of the flash need to be executable + * then platform code is responsible for re-mapping the appropriate portion + * of it as executable. + */ +#define V2M_MAP_FLASH0_RW MAP_REGION_FLAT(V2M_FLASH0_BASE,\ + V2M_FLASH0_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define V2M_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ + V2M_FLASH0_SIZE, \ + MT_RO_DATA | MT_SECURE) + +#define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ + V2M_FLASH0_SIZE, \ + MT_DEVICE | MT_RO | MT_SECURE) + +/* Platform ID address */ +#define BOARD_CSS_PLAT_ID_REG_ADDR UL(0x0EFE00E0) + +/* Platform ID related accessors */ +#define BOARD_CSS_PLAT_ID_REG_ID_MASK U(0x0F) +#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT U(0x00) +#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK U(0xF00) +#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT U(0x08) +#define BOARD_CSS_PLAT_TYPE_RTL U(0x00) +#define BOARD_CSS_PLAT_TYPE_FPGA U(0x01) +#define BOARD_CSS_PLAT_TYPE_EMULATOR U(0x02) +#define BOARD_CSS_PLAT_TYPE_FVP U(0x03) + +#ifndef __ASSEMBLER__ + +#include <lib/mmio.h> + +#define BOARD_CSS_GET_PLAT_TYPE(addr) \ + ((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK) \ + >> BOARD_CSS_PLAT_ID_REG_ID_SHIFT) + +#endif /* __ASSEMBLER__ */ + + +#define MAX_IO_DEVICES U(3) +#define MAX_IO_HANDLES U(4) + +/* Reserve the last block of flash for PSCI MEM PROTECT flag */ +#define PLAT_ARM_FIP_BASE V2M_FLASH0_BASE +#define PLAT_ARM_FIP_MAX_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) + +#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE +#define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) + +/* UART related constants */ +#define PLAT_ARM_BOOT_UART_BASE SOC_CSS_UART0_BASE +#define PLAT_ARM_BOOT_UART_CLK_IN_HZ SOC_CSS_UART0_CLK_IN_HZ + +#define PLAT_ARM_RUN_UART_BASE SOC_CSS_UART1_BASE +#define PLAT_ARM_RUN_UART_CLK_IN_HZ SOC_CSS_UART1_CLK_IN_HZ + +#define PLAT_ARM_SP_MIN_RUN_UART_BASE SOC_CSS_UART1_BASE +#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ SOC_CSS_UART1_CLK_IN_HZ + +#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE +#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ + +#endif /* SGI_SOC_CSS_DEF_V2_H */ diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def.h b/plat/arm/css/sgi/include/sgi_soc_platform_def.h new file mode 100644 index 000000000..d7a839a52 --- /dev/null +++ b/plat/arm/css/sgi/include/sgi_soc_platform_def.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI_SOC_PLATFORM_DEF_H +#define SGI_SOC_PLATFORM_DEF_H + +#include <sgi_base_platform_def.h> +#include <plat/arm/board/common/board_css_def.h> +#include <plat/arm/board/common/v2m_def.h> +#include <plat/arm/soc/common/soc_css_def.h> + +#endif /* SGI_SOC_PLATFORM_DEF_H */ diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h new file mode 100644 index 000000000..cb747c34a --- /dev/null +++ b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI_SOC_PLATFORM_DEF_V2_H +#define SGI_SOC_PLATFORM_DEF_V2_H + +#include <sgi_base_platform_def.h> +#include <sgi_soc_css_def_v2.h> + +#endif /* SGI_SOC_PLATFORM_DEF_V2_H */ diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h index c75f2132b..ecf6d93d6 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,24 @@ #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-V1 */ +#define RD_V1_SID_VER_PART_NUM 0x078a + +/* SID Version values for RD-N2 */ +#define RD_N2_SID_VER_PART_NUM 0x07B7 + /* 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 +36,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 71601118f..615f53dc9 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.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 # @@ -16,20 +16,23 @@ 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 -ENT_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - plat/common/plat_gicv3.c \ - plat/arm/common/arm_gicv3.c \ - drivers/arm/gic/v3/gic600.c +# GIC-600 configuration +GICV3_SUPPORT_GIC600 := 1 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk +ENT_GIC_SOURCES := ${GICV3_SOURCES} \ + plat/common/plat_gicv3.c \ + plat/arm/common/arm_gicv3.c -PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c \ - ${CSS_ENT_BASE}/aarch64/sgi_helper.S +PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/aarch64/sgi_helper.S BL1_SOURCES += ${INTERCONNECT_SOURCES} \ drivers/arm/sbsa/sbsa.c @@ -52,6 +55,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 ba050d5f1..36c3fbb6c 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,58 @@ 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_V1_SID_VER_PART_NUM || + sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM) { + if (channel_id >= ARRAY_SIZE(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 +91,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 +107,12 @@ 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, 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))) { 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 a2f10dcc7..09f3b728d 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/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c index b611eaff5..39eb89eb8 100644 --- a/plat/arm/css/sgi/sgi_plat.c +++ b/plat/arm/css/sgi/sgi_plat.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 */ @@ -15,7 +15,10 @@ #include <plat/common/platform.h> #include <drivers/arm/sbsa.h> #include <sgi_base_platform_def.h> + +#if SPM_MM #include <services/spm_mm_partition.h> +#endif #define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ V2M_FLASH0_SIZE, \ @@ -40,6 +43,9 @@ const mmap_region_t plat_arm_mmap[] = { const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, SGI_MAP_FLASH0_RO, +#ifdef PLAT_ARM_MEM_PROT_ADDR + ARM_V2M_MAP_MEM_PROTECT, +#endif CSS_SGI_MAP_DEVICE, SOC_CSS_MAP_DEVICE, ARM_MAP_NS_DRAM1, @@ -60,6 +66,9 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, V2M_MAP_IOFPGA, CSS_SGI_MAP_DEVICE, +#ifdef PLAT_ARM_MEM_PROT_ADDR + ARM_V2M_MAP_MEM_PROTECT, +#endif SOC_CSS_MAP_DEVICE, #if SPM_MM ARM_SPM_BUF_EL3_MMAP, diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c new file mode 100644 index 000000000..a770255fc --- /dev/null +++ b/plat/arm/css/sgi/sgi_plat_v2.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <platform_def.h> + +#include <plat/arm/common/plat_arm.h> +#include <plat/common/platform.h> +#include <drivers/arm/sbsa.h> + +/* + * Table of regions for different BL stages to map using the MMU. + */ +#if IMAGE_BL1 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + SGI_MAP_FLASH0_RO, + CSS_SGI_MAP_DEVICE, + SOC_PLATFORM_PERIPH_MAP_DEVICE, + SOC_SYSTEM_PERIPH_MAP_DEVICE, + {0} +}; +#endif + +#if IMAGE_BL2 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + SGI_MAP_FLASH0_RO, +#ifdef PLAT_ARM_MEM_PROT_ADDR + ARM_V2M_MAP_MEM_PROTECT, +#endif + CSS_SGI_MAP_DEVICE, + SOC_MEMCNTRL_MAP_DEVICE, + SOC_PLATFORM_PERIPH_MAP_DEVICE, + SOC_SYSTEM_PERIPH_MAP_DEVICE, + ARM_MAP_NS_DRAM1, +#if ARM_BL31_IN_DRAM + ARM_MAP_BL31_SEC_DRAM, +#endif +#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3 + ARM_MAP_BL1_RW, +#endif + {0} +}; +#endif + +#if IMAGE_BL31 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, +#ifdef PLAT_ARM_MEM_PROT_ADDR + ARM_V2M_MAP_MEM_PROTECT, +#endif + CSS_SGI_MAP_DEVICE, + SOC_PLATFORM_PERIPH_MAP_DEVICE, + SOC_SYSTEM_PERIPH_MAP_DEVICE, + {0} +}; + +#endif + +ARM_CASSERT_MMAP + +#if TRUSTED_BOARD_BOOT +int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) +{ + assert(heap_addr != NULL); + assert(heap_size != NULL); + + return arm_get_mbedtls_heap(heap_addr, heap_size); +} +#endif + +void plat_arm_secure_wdt_start(void) +{ + sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT); +} + +void plat_arm_secure_wdt_stop(void) +{ + sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE); +} diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c index f56544e72..a04972d70 100644 --- a/plat/arm/css/sgi/sgi_ras.c +++ b/plat/arm/css/sgi/sgi_ras.c @@ -111,6 +111,7 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec, struct sgi_ras_ev_map *ras_map; mm_communicate_header_t *header; uint32_t intr; + int ret; cm_el1_sysregs_context_save(NON_SECURE); intr = data->interrupt; @@ -120,7 +121,7 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec, * this interrupt */ ras_map = find_ras_event_map_by_intr(intr); - assert(ras_map); + assert(ras_map != NULL); /* * Populate the MM_COMMUNICATE payload to share the @@ -152,9 +153,20 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec, plat_ic_end_of_interrupt(intr); /* Dispatch the event to the SDEI client */ - sdei_dispatch_event(ras_map->sdei_ev_num); + ret = sdei_dispatch_event(ras_map->sdei_ev_num); + if (ret != 0) { + /* + * sdei_dispatch_event() may return failing result in some cases, + * for example kernel may not have registered a handler or RAS event + * may happen early during boot. We restore the NS context when + * sdei_dispatch_event() returns failing result. + */ + ERROR("SDEI dispatch failed: %d", ret); + cm_el1_sysregs_context_restore(NON_SECURE); + cm_set_next_eret_context(NON_SECURE); + } - return 0; + return ret; } int sgi_ras_intr_handler_setup(void) diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts index d48101842..54b2423c1 100644 --- a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts +++ b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,7 @@ / { /* Platform Config */ - plat_arm_bl2 { + tb_fw-config { compatible = "arm,tb_fw"; hw_config_addr = <0x0 0x83000000>; hw_config_max_size = <0x01000000>; 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 24bbed513..2d8e6778f 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 @@ -134,16 +133,14 @@ #endif /* - * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current - * SCP_BL2 size plus a little space for growth. + * SCP_BL2 uses up whatever remaining space is available as it is loaded before + * anything else in this memory region and is handed over to the SCP before + * BL31 is loaded over the top. */ -#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x15000 +#define PLAT_CSS_MAX_SCP_BL2_SIZE \ + ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK) -/* - * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current - * SCP_BL2U size plus a little space for growth. - */ -#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x15000 +#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE /* * Most platform porting definitions provided by included headers @@ -192,7 +189,7 @@ #if TRUSTED_BOARD_BOOT # define PLAT_ARM_MAX_BL2_SIZE 0x1D000 #else -# define PLAT_ARM_MAX_BL2_SIZE 0x11000 +# define PLAT_ARM_MAX_BL2_SIZE 0x12000 #endif /* @@ -239,4 +236,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-common.mk b/plat/arm/css/sgm/sgm-common.mk index ac34450a7..5b954f842 100644 --- a/plat/arm/css/sgm/sgm-common.mk +++ b/plat/arm/css/sgm/sgm-common.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 # @@ -22,13 +22,15 @@ SGM_CPU_SOURCES := lib/cpus/aarch64/cortex_a55.S \ INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c -SGM_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ +# GIC-600 configuration +GICV3_SUPPORT_GIC600 := 1 + +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +SGM_GIC_SOURCES := ${GICV3_SOURCES} \ plat/common/plat_gicv3.c \ - plat/arm/common/arm_gicv3.c \ - drivers/arm/gic/v3/gic600.c \ - drivers/arm/gic/v3/arm_gicv3_common.c + plat/arm/common/arm_gicv3.c BL1_SOURCES += $(SGM_CPU_SOURCES) \ ${INTERCONNECT_SOURCES} \ diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c index 7e92ac835..907e9fdac 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; } |