diff options
-rw-r--r-- | include/lib/coreboot.h | 1 | ||||
-rw-r--r-- | lib/compiler-rt/builtins/assembly.h | 2 | ||||
-rw-r--r-- | lib/compiler-rt/builtins/int_types.h | 2 | ||||
-rw-r--r-- | lib/coreboot/coreboot_table.c | 10 | ||||
-rw-r--r-- | lib/libc/printf.c | 7 | ||||
-rw-r--r-- | lib/libc/snprintf.c | 6 | ||||
-rw-r--r-- | lib/libfdt/fdt.c | 20 | ||||
-rw-r--r-- | plat/arm/board/morello/morello_bl31_setup.c | 3 | ||||
-rw-r--r-- | plat/arm/board/morello/morello_pm.c | 29 | ||||
-rw-r--r-- | plat/arm/board/morello/morello_private.h | 15 | ||||
-rw-r--r-- | plat/arm/board/morello/platform.mk | 1 | ||||
-rw-r--r-- | plat/arm/board/n1sdp/n1sdp_bl31_setup.c | 5 | ||||
-rw-r--r-- | plat/arm/board/n1sdp/n1sdp_pm.c | 29 | ||||
-rw-r--r-- | plat/arm/board/n1sdp/n1sdp_private.h | 15 | ||||
-rw-r--r-- | plat/arm/board/n1sdp/platform.mk | 1 | ||||
-rw-r--r-- | services/spd/opteed/opteed.mk | 1 | ||||
-rw-r--r-- | services/spd/opteed/opteed_main.c | 104 |
17 files changed, 237 insertions, 14 deletions
diff --git a/include/lib/coreboot.h b/include/lib/coreboot.h index 0aa65791d..42d4149aa 100644 --- a/include/lib/coreboot.h +++ b/include/lib/coreboot.h @@ -41,5 +41,6 @@ typedef enum { coreboot_memory_t coreboot_get_memory_type(uintptr_t start, size_t size); void coreboot_table_setup(void *base); +void coreboot_get_table_location(uint64_t *address, uint32_t *size); #endif /* COREBOOT_H */ diff --git a/lib/compiler-rt/builtins/assembly.h b/lib/compiler-rt/builtins/assembly.h index 69a3d8620..169d49683 100644 --- a/lib/compiler-rt/builtins/assembly.h +++ b/lib/compiler-rt/builtins/assembly.h @@ -267,7 +267,7 @@ #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ .globl SYMBOL_NAME(name) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - DECLARE_SYMBOL_VISIBILITY(SYMBOL_NAME(name)) SEPARATOR \ + DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR #if defined(__ARM_EABI__) diff --git a/lib/compiler-rt/builtins/int_types.h b/lib/compiler-rt/builtins/int_types.h index 7a72de480..e94d3154c 100644 --- a/lib/compiler-rt/builtins/int_types.h +++ b/lib/compiler-rt/builtins/int_types.h @@ -64,7 +64,7 @@ typedef union { } udwords; #if defined(__LP64__) || defined(__wasm__) || defined(__mips64) || \ - defined(__riscv) || defined(_WIN64) + defined(__SIZEOF_INT128__) || defined(_WIN64) #define CRT_HAS_128BIT #endif diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c index fb31ef1e0..43e983590 100644 --- a/lib/coreboot/coreboot_table.c +++ b/lib/coreboot/coreboot_table.c @@ -46,6 +46,8 @@ typedef struct { coreboot_memrange_t coreboot_memranges[COREBOOT_MAX_MEMRANGES]; coreboot_serial_t coreboot_serial; +uint64_t coreboot_table_addr; +uint32_t coreboot_table_size; /* * The coreboot table is parsed before the MMU is enabled (i.e. with strongly @@ -108,6 +110,12 @@ coreboot_memory_t coreboot_get_memory_type(uintptr_t start, size_t size) return CB_MEM_NONE; } +void coreboot_get_table_location(uint64_t *address, uint32_t *size) +{ + *address = coreboot_table_addr; + *size = coreboot_table_size; +} + void coreboot_table_setup(void *base) { cb_header_t *header = base; @@ -118,6 +126,8 @@ void coreboot_table_setup(void *base) ERROR("coreboot table signature corrupt!\n"); return; } + coreboot_table_addr = (uint64_t) base; + coreboot_table_size = header->header_bytes + header->table_bytes; ptr = base + header->header_bytes; for (i = 0; i < header->table_entries; i++) { diff --git a/lib/libc/printf.c b/lib/libc/printf.c index e52cbed73..faccfdff4 100644 --- a/lib/libc/printf.c +++ b/lib/libc/printf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -81,6 +81,7 @@ static int unsigned_num_print(unsigned long long int unum, unsigned int radix, * %x - hexadecimal format * %s - string format * %d or %i - signed decimal format + * %c - character format * %u - unsigned decimal format * %p - pointer format * @@ -130,6 +131,10 @@ loop: count += unsigned_num_print(unum, 10, padc, padn); break; + case 'c': + (void)putchar(va_arg(args, int)); + count++; + break; case 's': str = va_arg(args, char *); count += string_print(str); diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c index 0e3256cde..21d34168f 100644 --- a/lib/libc/snprintf.c +++ b/lib/libc/snprintf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -85,6 +85,7 @@ static void unsigned_num_print(char **s, size_t n, size_t *chars_printed, * * %x (or %X) - hexadecimal format * %d or %i - signed decimal format + * %c - character format * %s - string format * %u - unsigned decimal format * %p - pointer format @@ -181,6 +182,9 @@ loop: unsigned_num_print(&s, n, &chars_printed, unum, 10, padc, padn, false); break; + case 'c': + CHECK_AND_PUT_CHAR(s, n, chars_printed, va_arg(args, int)); + break; case 's': str = va_arg(args, char *); string_print(&s, n, &chars_printed, str); diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c index 9fe7cf4b7..20c6415b9 100644 --- a/lib/libfdt/fdt.c +++ b/lib/libfdt/fdt.c @@ -106,7 +106,6 @@ int fdt_check_header(const void *fdt) } hdrsize = fdt_header_size(fdt); if (!can_assume(VALID_DTB)) { - if ((fdt_totalsize(fdt) < hdrsize) || (fdt_totalsize(fdt) > INT_MAX)) return -FDT_ERR_TRUNCATED; @@ -115,9 +114,7 @@ int fdt_check_header(const void *fdt) if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt))) return -FDT_ERR_TRUNCATED; - } - if (!can_assume(VALID_DTB)) { /* Bounds check structure block */ if (!can_assume(LATEST) && fdt_version(fdt) < 17) { if (!check_off_(hdrsize, fdt_totalsize(fdt), @@ -165,7 +162,7 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) { const fdt32_t *tagp, *lenp; - uint32_t tag; + uint32_t tag, len, sum; int offset = startoffset; const char *p; @@ -191,12 +188,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); if (!can_assume(VALID_DTB) && !lenp) return FDT_END; /* premature end */ + + len = fdt32_to_cpu(*lenp); + sum = len + offset; + if (!can_assume(VALID_DTB) && + (INT_MAX <= sum || sum < (uint32_t) offset)) + return FDT_END; /* premature end */ + /* skip-name offset, length and value */ - offset += sizeof(struct fdt_property) - FDT_TAGSIZE - + fdt32_to_cpu(*lenp); + offset += sizeof(struct fdt_property) - FDT_TAGSIZE + len; + if (!can_assume(LATEST) && - fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && - ((offset - fdt32_to_cpu(*lenp)) % 8) != 0) + fdt_version(fdt) < 0x10 && len >= 8 && + ((offset - len) % 8) != 0) offset += 4; break; diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c index cef42f46c..e13a38b32 100644 --- a/plat/arm/board/morello/morello_bl31_setup.c +++ b/plat/arm/board/morello/morello_bl31_setup.c @@ -12,6 +12,7 @@ #include <services/arm_arch_svc.h> #include "morello_def.h" +#include "morello_private.h" #include <platform_def.h> #ifdef TARGET_PLATFORM_SOC @@ -33,6 +34,8 @@ scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id) const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { + ops->pwr_domain_off = morello_pwr_domain_off; + ops->pwr_domain_suspend = morello_pwr_domain_suspend; return css_scmi_override_pm_ops(ops); } diff --git a/plat/arm/board/morello/morello_pm.c b/plat/arm/board/morello/morello_pm.c new file mode 100644 index 000000000..dda006eac --- /dev/null +++ b/plat/arm/board/morello/morello_pm.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/psci/psci.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/arm/css/common/css_pm.h> + +#include "morello_private.h" + +/******************************************************************************* + * Morello specific functions called when turning off or suspending a power + * domain. Both additionally disable the GIC redistributor interface as cores + * are disabled to let cluster-PPU state transition to completion when a + * cluster is powered down. + ******************************************************************************/ +void morello_pwr_domain_off(const psci_power_state_t *target_state) +{ + css_pwr_domain_off(target_state); + plat_arm_gic_redistif_off(); +} + +void morello_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + css_pwr_domain_suspend(target_state); + plat_arm_gic_redistif_off(); +} diff --git a/plat/arm/board/morello/morello_private.h b/plat/arm/board/morello/morello_private.h new file mode 100644 index 000000000..ea2fce974 --- /dev/null +++ b/plat/arm/board/morello/morello_private.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MORELLO_PRIVATE_H +#define MORELLO_PRIVATE_H + +#include <lib/psci/psci.h> + +void morello_pwr_domain_off(const psci_power_state_t *target_state); +void morello_pwr_domain_suspend(const psci_power_state_t *target_state); + +#endif /* MORELLO_PRIVATE_H */ diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk index 0f0cabbad..0ae769338 100644 --- a/plat/arm/board/morello/platform.mk +++ b/plat/arm/board/morello/platform.mk @@ -49,6 +49,7 @@ BL31_SOURCES := ${MORELLO_CPU_SOURCES} \ ${INTERCONNECT_SOURCES} \ ${MORELLO_GIC_SOURCES} \ ${MORELLO_BASE}/morello_bl31_setup.c \ + ${MORELLO_BASE}/morello_pm.c \ ${MORELLO_BASE}/morello_topology.c \ ${MORELLO_BASE}/morello_security.c \ drivers/arm/css/sds/sds.c diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index bd0566006..db7215f43 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-2022, Arm Limited. All rights reserved. + * Copyright (c) 2018-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,7 @@ #include <plat/arm/common/plat_arm.h> #include "n1sdp_def.h" +#include "n1sdp_private.h" #include <platform_def.h> /* @@ -69,6 +70,8 @@ scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id) const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { + ops->pwr_domain_off = n1sdp_pwr_domain_off; + ops->pwr_domain_suspend = n1sdp_pwr_domain_suspend; return css_scmi_override_pm_ops(ops); } diff --git a/plat/arm/board/n1sdp/n1sdp_pm.c b/plat/arm/board/n1sdp/n1sdp_pm.c new file mode 100644 index 000000000..e43832a23 --- /dev/null +++ b/plat/arm/board/n1sdp/n1sdp_pm.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/psci/psci.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/arm/css/common/css_pm.h> + +#include "n1sdp_private.h" + +/******************************************************************************* + * N1SDP specific functions called when turning off or suspending a power + * domain. Both additionally disable the GIC redistributor interface as cores + * are disabled to let cluster-PPU state transition to completion when a + * cluster is powered down. + ******************************************************************************/ +void n1sdp_pwr_domain_off(const psci_power_state_t *target_state) +{ + css_pwr_domain_off(target_state); + plat_arm_gic_redistif_off(); +} + +void n1sdp_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + css_pwr_domain_suspend(target_state); + plat_arm_gic_redistif_off(); +} diff --git a/plat/arm/board/n1sdp/n1sdp_private.h b/plat/arm/board/n1sdp/n1sdp_private.h new file mode 100644 index 000000000..7a5c51d97 --- /dev/null +++ b/plat/arm/board/n1sdp/n1sdp_private.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef N1SDP_PRIVATE_H +#define N1SDP_PRIVATE_H + +#include <lib/psci/psci.h> + +void n1sdp_pwr_domain_off(const psci_power_state_t *target_state); +void n1sdp_pwr_domain_suspend(const psci_power_state_t *target_state); + +#endif /* N1SDP_PRIVATE_H */ diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 9c0cc022c..bd6261454 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -47,6 +47,7 @@ BL31_SOURCES := ${N1SDP_CPU_SOURCES} \ ${INTERCONNECT_SOURCES} \ ${N1SDP_GIC_SOURCES} \ ${N1SDP_BASE}/n1sdp_bl31_setup.c \ + ${N1SDP_BASE}/n1sdp_pm.c \ ${N1SDP_BASE}/n1sdp_topology.c \ ${N1SDP_BASE}/n1sdp_security.c \ drivers/arm/css/sds/sds.c diff --git a/services/spd/opteed/opteed.mk b/services/spd/opteed/opteed.mk index 477b45d98..f394744e9 100644 --- a/services/spd/opteed/opteed.mk +++ b/services/spd/opteed/opteed.mk @@ -31,4 +31,5 @@ $(warning "OPTEE_ALLOW_SMC_LOAD is enabled which may result in an insecure \ platform") $(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC)) $(eval $(call add_define,OPTEE_ALLOW_SMC_LOAD)) +include lib/libfdt/libfdt.mk endif diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c index f069775d2..4d055db17 100644 --- a/services/spd/opteed/opteed_main.c +++ b/services/spd/opteed/opteed_main.c @@ -24,9 +24,13 @@ #include <common/bl_common.h> #include <common/debug.h> #include <common/runtime_svc.h> +#include <lib/coreboot.h> #include <lib/el3_runtime/context_mgmt.h> #include <lib/optee_utils.h> #include <lib/xlat_tables/xlat_tables_v2.h> +#if OPTEE_ALLOW_SMC_LOAD +#include <libfdt.h> +#endif /* OPTEE_ALLOW_SMC_LOAD */ #include <plat/common/platform.h> #include <tools_share/uuid.h> @@ -51,6 +55,10 @@ static bool opteed_allow_load; DEFINE_SVC_UUID2(optee_image_load_uuid, 0xb1eafba3, 0x5d31, 0x4612, 0xb9, 0x06, 0xc4, 0xc7, 0xa4, 0xbe, 0x3c, 0xc0); + +#define OPTEED_FDT_SIZE 256 +static uint8_t fdt_buf[OPTEED_FDT_SIZE] __aligned(CACHE_WRITEBACK_GRANULE); + #else static int32_t opteed_init(void); #endif @@ -209,6 +217,91 @@ static int32_t opteed_init(void) #endif /* !OPTEE_ALLOW_SMC_LOAD */ #if OPTEE_ALLOW_SMC_LOAD +#if COREBOOT +/* + * Adds a firmware/coreboot node with the coreboot table information to a device + * tree. Returns zero on success or if there is no coreboot table information; + * failure code otherwise. + */ +static int add_coreboot_node(void *fdt) +{ + int ret; + uint64_t coreboot_table_addr; + uint32_t coreboot_table_size; + struct { + uint64_t addr; + uint32_t size; + } reg_node; + coreboot_get_table_location(&coreboot_table_addr, &coreboot_table_size); + if (!coreboot_table_addr || !coreboot_table_size) { + WARN("Unable to get coreboot table location for device tree"); + return 0; + } + ret = fdt_begin_node(fdt, "firmware"); + if (ret) + return ret; + + ret = fdt_property(fdt, "ranges", NULL, 0); + if (ret) + return ret; + + ret = fdt_begin_node(fdt, "coreboot"); + if (ret) + return ret; + + ret = fdt_property_string(fdt, "compatible", "coreboot"); + if (ret) + return ret; + + reg_node.addr = cpu_to_fdt64(coreboot_table_addr); + reg_node.size = cpu_to_fdt32(coreboot_table_size); + ret = fdt_property(fdt, "reg", ®_node, + sizeof(uint64_t) + sizeof(uint32_t)); + if (ret) + return ret; + + ret = fdt_end_node(fdt); + if (ret) + return ret; + + return fdt_end_node(fdt); +} +#endif /* COREBOOT */ + +/* + * Creates a device tree for passing into OP-TEE. Currently is populated with + * the coreboot table address. + * Returns 0 on success, error code otherwise. + */ +static int create_opteed_dt(void) +{ + int ret; + + ret = fdt_create(fdt_buf, OPTEED_FDT_SIZE); + if (ret) + return ret; + + ret = fdt_finish_reservemap(fdt_buf); + if (ret) + return ret; + + ret = fdt_begin_node(fdt_buf, ""); + if (ret) + return ret; + +#if COREBOOT + ret = add_coreboot_node(fdt_buf); + if (ret) + return ret; +#endif /* COREBOOT */ + + ret = fdt_end_node(fdt_buf); + if (ret) + return ret; + + return fdt_finish(fdt_buf); +} + /******************************************************************************* * This function is responsible for handling the SMC that loads the OP-TEE * binary image via a non-secure SMC call. It takes the size and physical @@ -232,6 +325,7 @@ static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa) uint64_t target_size; entry_point_info_t optee_ep_info; uint32_t linear_id = plat_my_core_pos(); + uint64_t dt_addr = 0; mapped_data_pa = page_align(data_pa, DOWN); mapped_data_va = mapped_data_pa; @@ -292,12 +386,20 @@ static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa) /* Save the non-secure state */ cm_el1_sysregs_context_save(NON_SECURE); + rc = create_opteed_dt(); + if (rc) { + ERROR("Failed device tree creation %d\n", rc); + return rc; + } + dt_addr = (uint64_t)fdt_buf; + flush_dcache_range(dt_addr, OPTEED_FDT_SIZE); + opteed_init_optee_ep_state(&optee_ep_info, opteed_rw, image_pa, 0, 0, - 0, + dt_addr, &opteed_sp_context[linear_id]); if (opteed_init_with_entry_point(&optee_ep_info) == 0) { rc = -EFAULT; |