diff options
author | Joanna Farley <joanna.farley@arm.com> | 2023-10-17 16:27:13 +0200 |
---|---|---|
committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2023-10-17 16:27:13 +0200 |
commit | f8363a8e2c1ac8aa7340030f199daa72dcc9126b (patch) | |
tree | ca76013a9c521a61d759f0d744eb8ae264be5f99 | |
parent | 47dddbe7b0f53b87592f68be3dc9bc14ce33a5bf (diff) | |
parent | a467e813a362fae69484e70ecb26fd8b14489d38 (diff) |
Merge changes from topic "xlnx_dtb_console" into integration
* changes:
feat(versal-net): retrieval of console information from dtb
feat(versal): retrieval of console information from dtb
refactor(xilinx): create generic function for clock retrieval
feat(zynqmp): retrieval of console information from dtb
-rw-r--r-- | plat/xilinx/common/include/plat_console.h | 27 | ||||
-rw-r--r-- | plat/xilinx/common/plat_console.c | 346 | ||||
-rw-r--r-- | plat/xilinx/versal/aarch64/versal_common.c | 5 | ||||
-rw-r--r-- | plat/xilinx/versal/bl31_versal_setup.c | 27 | ||||
-rw-r--r-- | plat/xilinx/versal/include/plat_private.h | 1 | ||||
-rw-r--r-- | plat/xilinx/versal/platform.mk | 2 | ||||
-rw-r--r-- | plat/xilinx/versal_net/aarch64/versal_net_common.c | 24 | ||||
-rw-r--r-- | plat/xilinx/versal_net/bl31_versal_net_setup.c | 35 | ||||
-rw-r--r-- | plat/xilinx/versal_net/include/plat_private.h | 1 | ||||
-rw-r--r-- | plat/xilinx/versal_net/platform.mk | 2 | ||||
-rw-r--r-- | plat/xilinx/zynqmp/bl31_zynqmp_setup.c | 24 | ||||
-rw-r--r-- | plat/xilinx/zynqmp/platform.mk | 2 |
12 files changed, 417 insertions, 79 deletions
diff --git a/plat/xilinx/common/include/plat_console.h b/plat/xilinx/common/include/plat_console.h new file mode 100644 index 000000000..0f8320e05 --- /dev/null +++ b/plat/xilinx/common/include/plat_console.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_DT_UART_H +#define PLAT_DT_UART_H + +#define DT_UART_DCC_COMPAT "arm,dcc" + +#if defined(PLAT_zynqmp) +#define DT_UART_COMPAT "xlnx,zynqmp-uart" +#else +#define DT_UART_COMPAT "arm,pl011" +#endif + +typedef struct dt_uart_info_s { + char compatible[30]; + uintptr_t base; + uint32_t baud_rate; + int32_t status; +} dt_uart_info_t; + +void setup_console(void); + +#endif /* PLAT_DT_UART_H */ diff --git a/plat/xilinx/common/plat_console.c b/plat/xilinx/common/plat_console.c new file mode 100644 index 000000000..0c0e74b96 --- /dev/null +++ b/plat/xilinx/common/plat_console.c @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <common/debug.h> +#include <common/fdt_fixup.h> +#include <common/fdt_wrappers.h> +#include <drivers/arm/dcc.h> +#include <drivers/arm/pl011.h> +#include <drivers/cadence/cdns_uart.h> +#include <drivers/console.h> +#include <libfdt.h> +#include <plat_console.h> + +#include <platform_def.h> +#include <plat_private.h> + +static console_t console; + +#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE)) +/** + * get_baudrate() - Get the baudrate form DTB. + * @dtb: Address of the Device Tree Blob (DTB). + * + * Return: On success returns the baudrate; on failure returns an error. + */ +static int32_t get_baudrate(void *dtb) +{ + int node; + int32_t ret = 0; + const char *prop, *path; + char *end; + int32_t baud_rate = 0; + + node = fdt_path_offset(dtb, "/secure-chosen"); + if (node < 0) { + node = fdt_path_offset(dtb, "/chosen"); + if (node < 0) { + ret = -FDT_ERR_NOTFOUND; + goto error; + } + } + + prop = fdt_getprop(dtb, node, "stdout-path", NULL); + if (prop == NULL) { + ret = -FDT_ERR_NOTFOUND; + goto error; + } + + /* Parse string serial0:115200n8 */ + path = strchr(prop, ':'); + if (!path) { + ret = -FDT_ERR_NOTFOUND; + goto error; + } else { + + baud_rate = strtoul(path + 1, &end, 10); + if (baud_rate == 0 && end == path) { + ERROR("Conversion error occurred: %d\n", baud_rate); + ret = -FDT_ERR_NOTFOUND; + goto error; + } + ret = baud_rate; + } + +error: + return ret; +} + +/** + * get_node_status() - Get the DTB node status. + * @dtb: Address of the Device Tree Blob (DTB). + * @node: Node address in the device tree. + * + * Return: On success, it returns 1; on failure, it returns an 0. + */ +static uint32_t get_node_status(void *dtb, int node) +{ + const char *status_cell; + uint32_t status = 0; + + status_cell = fdt_getprop(dtb, node, "status", NULL); + if (!status_cell || strcmp(status_cell, "okay") == 0) { + status = 1; + } else { + status = 0; + } + + return status; +} + +/** + * fdt_add_uart_info() - Add DTB information to a UART structure. + * @info: Pointer to the UART information structure. + * @node: Node address in the device tree. + * @dtb: Address of the Device Tree Blob(DTB). + * + * Return: On success, it returns 1; on failure, it returns an 0. + */ +static uint32_t fdt_add_uart_info(dt_uart_info_t *info, int node, void *dtb) +{ + uintptr_t base_addr; + const char *com; + uint32_t ret = 0; + + com = fdt_getprop(dtb, node, "compatible", NULL); + if (com != NULL) { + strlcpy(info->compatible, com, sizeof(info->compatible)); + } else { + ERROR("Compatible property not found in DTB node\n"); + ret = -FDT_ERR_NOTFOUND; + goto error; + } + + ret = fdt_get_reg_props_by_index(dtb, node, 0, &base_addr, NULL); + if (ret >= 0) { + info->base = base_addr; + } else { + ERROR("Failed to retrieve base address. Error code: %d\n", ret); + ret = -FDT_ERR_NOTFOUND; + goto error; + } + + info->status = get_node_status(dtb, node); + info->baud_rate = get_baudrate(dtb); + +error: + return ret; +} + +/** + * fdt_get_uart_info() - Get the uart information form DTB. + * @info: Pointer to the UART information structure. + * + * Return: On success, it returns 0; on failure, it returns an error+reason. + */ +static int fdt_get_uart_info(dt_uart_info_t *info) +{ + int node, ret = 0; + void *dtb = (void *)XILINX_OF_BOARD_DTB_ADDR; + + if (fdt_check_header(dtb) != 0) { + ERROR("Can't read DT at %p\n", dtb); + ret = -FDT_ERR_NOTFOUND; + goto error; + } + + ret = fdt_open_into(dtb, dtb, XILINX_OF_BOARD_DTB_MAX_SIZE); + if (ret < 0) { + ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret); + ret = -FDT_ERR_NOTFOUND; + goto error; + } + + node = fdt_get_stdout_node_offset(dtb); + if (node < 0) { + ERROR("DT get stdout node failed : %d\n", node); + ret = -FDT_ERR_NOTFOUND; + goto error; + } + + ret = fdt_add_uart_info(info, node, dtb); + if (ret < 0) { + ERROR("Failed to add DT UART info: %d\n", ret); + ret = -FDT_ERR_NOTFOUND; + goto error; + } + +error: + return ret; +} + +/** + * check_fdt_uart_info() - Check early uart info with DTB uart info. + * @info: Pointer to the UART information structure. + * + * Return: On success, it returns 0; on failure, it returns an error+reason. + */ +static int check_fdt_uart_info(dt_uart_info_t *info) +{ + uint32_t ret = 0; + + if (info->status == 0) { + ret = -ENODEV; + goto error; + } + + if ((info->base == console.base) && + (info->baud_rate == UART_BAUDRATE) && !CONSOLE_IS(dcc)) { + ret = -ENODEV; + goto error; + } + +error: + return ret; +} + +/** + * console_boot_end() - Unregister the console_t instance form the console list. + * @boot_console: Pointer to the console information structure. + */ +static void console_boot_end(console_t *boot_console) +{ + if (CONSOLE_IS(dcc)) { + console_dcc_unregister(); + } else { + console_flush(); + (void)console_unregister(boot_console); + } +} + +/** + * setup_runtime_console() - Registers the runtime uart with console list. + * @clock: UART clock. + * @info: Pointer to the UART information structure. + */ +static void setup_runtime_console(uint32_t clock, dt_uart_info_t *info) +{ + static console_t bl31_runtime_console; + uint32_t rc; + +#if defined(PLAT_zynqmp) + rc = console_cdns_register(info->base, + clock, + info->baud_rate, + &bl31_runtime_console); +#else + rc = console_pl011_register(info->base, + clock, + info->baud_rate, + &bl31_runtime_console); +#endif + if (rc == 0) { + panic(); + } + + console_set_scope(&bl31_runtime_console, + CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | + CONSOLE_FLAG_CRASH); +} + + +/** + * runtime_console_init() - Initializes the run time console information. + * @uart_info: Pointer to the UART information structure. + * @bl31_boot_console: Pointer to the console information structure. + * @clock: UART clock. + * + * Return: On success, it returns 0; on failure, it returns an error+reason; + */ +static int32_t runtime_console_init(dt_uart_info_t *uart_info, + console_t *bl31_boot_console, + uint32_t clock) +{ + int32_t rc = 0; + + /* Parse UART information from Device Tree Blob (DTB) */ + rc = fdt_get_uart_info(uart_info); + if (rc < 0) { + rc = -FDT_ERR_NOTFOUND; + } + + if (strncmp(uart_info->compatible, DT_UART_COMPAT, + strlen(DT_UART_COMPAT)) == 0) { + + if (check_fdt_uart_info(uart_info) == 0) { + setup_runtime_console(clock, uart_info); + console_boot_end(bl31_boot_console); + INFO("Runtime console setup\n"); + } else { + INFO("Early console and DTB console are same\n"); + } + } else if (strncmp(uart_info->compatible, DT_UART_DCC_COMPAT, + strlen(DT_UART_DCC_COMPAT)) == 0) { + rc = console_dcc_register(); + if (rc == 0) { + panic(); + } + console_boot_end(bl31_boot_console); + } else { + WARN("BL31: No console device found in DT.\n"); + } + + return rc; +} +#endif + +void setup_console(void) +{ + uint32_t rc; + uint32_t uart_clk = get_uart_clk(); + +#if defined(PLAT_zynqmp) + if (CONSOLE_IS(cadence) || (CONSOLE_IS(cadence1))) { + rc = console_cdns_register(UART_BASE, + uart_clk, + UART_BAUDRATE, + &console); + if (rc == 0) { + panic(); + } + + console_set_scope(&console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); + } +#else + if (CONSOLE_IS(pl011) || (CONSOLE_IS(pl011_1))) { + /* Initialize the console to provide early debug support */ + rc = console_pl011_register((uint32_t)UART_BASE, + uart_clk, + (uint32_t)UART_BAUDRATE, + &console); + if (rc == 0) { + panic(); + } + + console_set_scope(&console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); + } +#endif + if (CONSOLE_IS(dcc)) { + /* Initialize the dcc console for debug */ + rc = console_dcc_register(); + if (rc == 0) { + panic(); + } + } + INFO("BL31: Early console setup\n"); + +#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE)) + static dt_uart_info_t uart_info = {0}; + + /* Initialize the runtime console using UART information from the DTB */ + rc = runtime_console_init(&uart_info, &console, uart_clk); + if (rc < 0) { + ERROR("Failed to initialize runtime console: %d\n", rc); + } +#endif +} diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c index 93deedc63..6541f2734 100644 --- a/plat/xilinx/versal/aarch64/versal_common.c +++ b/plat/xilinx/versal/aarch64/versal_common.c @@ -73,3 +73,8 @@ void board_detection(void) platform_id = FIELD_GET(PLATFORM_MASK, plat_info[1]); platform_version = FIELD_GET(PLATFORM_VERSION_MASK, plat_info[1]); } + +uint32_t get_uart_clk(void) +{ + return UART_CLOCK; +} diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c index 566415f16..48f774dfe 100644 --- a/plat/xilinx/versal/bl31_versal_setup.c +++ b/plat/xilinx/versal/bl31_versal_setup.c @@ -12,13 +12,11 @@ #include <bl31/bl31.h> #include <common/bl_common.h> #include <common/debug.h> -#include <drivers/arm/dcc.h> -#include <drivers/arm/pl011.h> -#include <drivers/console.h> #include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables_v2.h> #include <plat/common/platform.h> #include <plat_arm.h> +#include <plat_console.h> #include <plat_fdt.h> #include <plat_private.h> @@ -74,28 +72,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, enum pm_ret_status ret_status; uint64_t addr[HANDOFF_PARAMS_MAX_SIZE]; - if (CONSOLE_IS(pl011) || (CONSOLE_IS(pl011_1))) { - static console_t versal_runtime_console; - /* Initialize the console to provide early debug support */ - int32_t rc = console_pl011_register((uintptr_t)UART_BASE, - (uint32_t)UART_CLOCK, - (uint32_t)UART_BAUDRATE, - &versal_runtime_console); - if (rc == 0) { - panic(); - } - - console_set_scope(&versal_runtime_console, (uint32_t)(CONSOLE_FLAG_BOOT | - CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH)); - } else if (CONSOLE_IS(dcc)) { - /* Initialize the dcc console for debug */ - int32_t rc = console_dcc_register(); - if (rc == 0) { - panic(); - } - } else { - /* No console device found. */ - } + setup_console(); /* Initialize the platform config for future decision making */ versal_config_setup(); diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h index 48f64eaf9..26545ba0f 100644 --- a/plat/xilinx/versal/include/plat_private.h +++ b/plat/xilinx/versal/include/plat_private.h @@ -17,6 +17,7 @@ typedef struct versal_intr_info_type_el3 { interrupt_type_handler_t handler; } versal_intr_info_type_el3_t; +uint32_t get_uart_clk(void); void versal_config_setup(void); const mmap_region_t *plat_versal_get_mmap(void); diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk index a0527134f..494c30df3 100644 --- a/plat/xilinx/versal/platform.mk +++ b/plat/xilinx/versal/platform.mk @@ -88,9 +88,11 @@ $(eval $(call add_define_val,VERSAL_CONSOLE,VERSAL_CONSOLE_ID_${VERSAL_CONSOLE}) BL31_SOURCES += drivers/arm/cci/cci.c \ lib/cpus/aarch64/cortex_a72.S \ + common/fdt_wrappers.c \ plat/common/plat_psci_common.c \ plat/xilinx/common/ipi.c \ plat/xilinx/common/plat_fdt.c \ + plat/xilinx/common/plat_console.c \ plat/xilinx/common/plat_startup.c \ plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \ plat/xilinx/common/pm_service/pm_ipi.c \ diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c index b2de411fe..df18814fb 100644 --- a/plat/xilinx/versal_net/aarch64/versal_net_common.c +++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c @@ -88,6 +88,30 @@ void board_detection(void) platform_version / 10U, platform_version % 10U); } +uint32_t get_uart_clk(void) +{ + uint32_t uart_clock; + + switch (platform_id) { + case VERSAL_NET_SPP: + uart_clock = 1000000; + break; + case VERSAL_NET_EMU: + uart_clock = 25000000; + break; + case VERSAL_NET_QEMU: + uart_clock = 25000000; + break; + case VERSAL_NET_SILICON: + uart_clock = 100000000; + break; + default: + panic(); + } + + return uart_clock; +} + void versal_net_config_setup(void) { uint32_t val; diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c index a70095d40..08f79deae 100644 --- a/plat/xilinx/versal_net/bl31_versal_net_setup.c +++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c @@ -12,13 +12,11 @@ #include <bl31/bl31.h> #include <common/bl_common.h> #include <common/debug.h> -#include <drivers/arm/dcc.h> -#include <drivers/arm/pl011.h> -#include <drivers/console.h> #include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables_v2.h> #include <plat/common/platform.h> #include <plat_arm.h> +#include <plat_console.h> #include <plat_fdt.h> #include <plat_private.h> @@ -69,8 +67,6 @@ static inline void bl31_set_default_config(void) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - uint32_t uart_clock; - int32_t rc; #if !(TFA_NO_PM) uint64_t tfa_handoff_addr, buff[HANDOFF_PARAMS_MAX_SIZE] = {0}; uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE; @@ -82,49 +78,22 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, switch (platform_id) { case VERSAL_NET_SPP: cpu_clock = 1000000; - uart_clock = 1000000; break; case VERSAL_NET_EMU: cpu_clock = 3660000; - uart_clock = 25000000; break; case VERSAL_NET_QEMU: /* Random values now */ cpu_clock = 100000000; - uart_clock = 25000000; break; case VERSAL_NET_SILICON: cpu_clock = 100000000; - uart_clock = 100000000; break; default: panic(); } - if (CONSOLE_IS(pl011_0) || CONSOLE_IS(pl011_1)) { - static console_t versal_net_runtime_console; - - /* Initialize the console to provide early debug support */ - rc = console_pl011_register(UART_BASE, uart_clock, - UART_BAUDRATE, - &versal_net_runtime_console); - if (rc == 0) { - panic(); - } - - console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT | - CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); - } else if (CONSOLE_IS(dcc)) { - /* Initialize the dcc console for debug. - * dcc is over jtag and does not configures uart0 or uart1. - */ - rc = console_dcc_register(); - if (rc == 0) { - panic(); - } - } else { - /* No console device found. */ - } + setup_console(); NOTICE("TF-A running on %s %d.%d\n", board_name_decode(), platform_version / 10U, platform_version % 10U); diff --git a/plat/xilinx/versal_net/include/plat_private.h b/plat/xilinx/versal_net/include/plat_private.h index be75bfdfa..3eb80525e 100644 --- a/plat/xilinx/versal_net/include/plat_private.h +++ b/plat/xilinx/versal_net/include/plat_private.h @@ -18,6 +18,7 @@ typedef struct versal_intr_info_type_el3 { } versal_intr_info_type_el3_t; void versal_net_config_setup(void); +uint32_t get_uart_clk(void); const mmap_region_t *plat_versal_net_get_mmap(void); diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk index 9fa16fdee..fb229bb45 100644 --- a/plat/xilinx/versal_net/platform.mk +++ b/plat/xilinx/versal_net/platform.mk @@ -108,12 +108,14 @@ BL31_SOURCES += ${PLAT_PATH}/plat_psci.c endif BL31_SOURCES += plat/xilinx/common/plat_fdt.c \ plat/xilinx/common/plat_startup.c \ + plat/xilinx/common/plat_console.c \ plat/xilinx/common/ipi.c \ plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \ plat/xilinx/common/versal.c \ ${PLAT_PATH}/bl31_versal_net_setup.c \ ${PLAT_PATH}/plat_topology.c \ common/fdt_fixup.c \ + common/fdt_wrappers.c \ ${LIBFDT_SRCS} \ ${PLAT_PATH}/sip_svc_setup.c \ ${PLAT_PATH}/versal_net_gicv3.c \ diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index 32bb9820d..801853591 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -13,12 +13,11 @@ #include <common/debug.h> #include <common/fdt_fixup.h> #include <common/fdt_wrappers.h> -#include <drivers/arm/dcc.h> -#include <drivers/console.h> #include <lib/mmio.h> #include <libfdt.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> +#include <plat_console.h> #include <custom_svc.h> #include <plat_fdt.h> @@ -74,25 +73,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { uint64_t tfa_handoff_addr; - if (CONSOLE_IS(cadence) || (CONSOLE_IS(cadence1))) { - /* Register the console to provide early debug support */ - static console_t bl31_boot_console; - (void)console_cdns_register(UART_BASE, - get_uart_clk(), - UART_BAUDRATE, - &bl31_boot_console); - console_set_scope(&bl31_boot_console, - CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT | - CONSOLE_FLAG_CRASH); - } else if (CONSOLE_IS(dcc)) { - /* Initialize the dcc console for debug */ - int32_t rc = console_dcc_register(); - if (rc == 0) { - panic(); - } - } else { - /* No console device found. */ - } + setup_console(); + /* Initialize the platform config for future decision making */ zynqmp_config_setup(); diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk index e20cb2246..b77893200 100644 --- a/plat/xilinx/zynqmp/platform.mk +++ b/plat/xilinx/zynqmp/platform.mk @@ -124,9 +124,11 @@ BL31_SOURCES += drivers/arm/cci/cci.c \ lib/cpus/aarch64/cortex_a53.S \ plat/common/plat_psci_common.c \ common/fdt_fixup.c \ + common/fdt_wrappers.c \ ${LIBFDT_SRCS} \ plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \ plat/xilinx/common/plat_startup.c \ + plat/xilinx/common/plat_console.c \ plat/xilinx/common/plat_fdt.c \ plat/xilinx/zynqmp/bl31_zynqmp_setup.c \ plat/xilinx/zynqmp/plat_psci.c \ |