From 03fa6f42502a3b6b318a9a73a228a6c751329a8f Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Mon, 24 Jun 2024 01:47:39 -0700 Subject: [PATCH 1/5] fix(xilinx): fix logic to read ipi response Currently, PLM IPI command supports total 8 32-bit payloads. But existing logic to read IPI response in TF-A is trying to read 9 32-bit payloads (ret status + 8 ret payloads) in case of IPI_CRC_CHECK enabled which is incorrect. So, fix logic to read only 8 32-bit payloads (ret status + 6 ret payloads + CRC) in case when IPI_CRC_CHECK is enabled and read 7 32-bit payloads (ret status + 5 ret payloads + CRC) in case when IPI_CRC_CHECK is disabled. Signed-off-by: Jay Buddhabhatti Change-Id: I0abca2f787cc7a66fdd5522e6bd15a9771029071 --- plat/xilinx/common/include/pm_common.h | 6 ++- plat/xilinx/common/pm_service/pm_api_sys.c | 4 +- plat/xilinx/common/pm_service/pm_ipi.c | 39 ++++++++----------- plat/xilinx/common/pm_service/pm_svc_main.c | 4 +- plat/xilinx/versal/plat_psci.c | 2 +- plat/xilinx/versal_net/plat_psci_pm.c | 2 +- .../zynqmp/pm_service/zynqmp_pm_api_sys.c | 2 +- .../zynqmp/pm_service/zynqmp_pm_svc_main.c | 4 +- 8 files changed, 30 insertions(+), 33 deletions(-) diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h index c0308ab6a..c38cdef35 100644 --- a/plat/xilinx/common/include/pm_common.h +++ b/plat/xilinx/common/include/pm_common.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,13 +18,15 @@ #if IPI_CRC_CHECK #define PAYLOAD_ARG_CNT 8U +#define RET_PAYLOAD_ARG_CNT 7U #define IPI_W0_TO_W6_SIZE 28U #define PAYLOAD_CRC_POS 7U #define CRC_INIT_VALUE 0x4F4EU #define CRC_ORDER 16U #define CRC_POLYNOM 0x8005U #else -#define PAYLOAD_ARG_CNT 6U +#define PAYLOAD_ARG_CNT 7U +#define RET_PAYLOAD_ARG_CNT 6U #endif #define PAYLOAD_ARG_SIZE 4U /* size in bytes */ diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c index 0a6e81024..14992858c 100644 --- a/plat/xilinx/common/pm_service/pm_api_sys.c +++ b/plat/xilinx/common/pm_service/pm_api_sys.c @@ -122,7 +122,7 @@ enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1, } PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5); - return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT); + return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, RET_PAYLOAD_ARG_CNT); } /** @@ -406,7 +406,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload, PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_FEATURE_CHECK, api_id); - return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT); + return pm_ipi_send_sync(primary_proc, payload, ret_payload, RET_PAYLOAD_ARG_CNT); } /** diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c index 56567dd67..205877c14 100644 --- a/plat/xilinx/common/pm_service/pm_ipi.c +++ b/plat/xilinx/common/pm_service/pm_ipi.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved. * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved. - * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -164,15 +164,10 @@ enum pm_ret_status pm_ipi_send(const struct pm_proc *proc, * */ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc, - uint32_t *value, size_t count) + uint32_t value[PAYLOAD_ARG_CNT]) { size_t i; enum pm_ret_status ret; -#if IPI_CRC_CHECK - uint32_t *payload_ptr = value; - size_t j; - uint32_t response_payload[PAYLOAD_ARG_CNT]; -#endif uintptr_t buffer_base = proc->ipi->buffer_base + IPI_BUFFER_TARGET_REMOTE_OFFSET + IPI_BUFFER_RESP_OFFSET; @@ -184,27 +179,21 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc, * buf-2: unused * buf-3: unused */ - for (i = 1; i <= count; i++) { - *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE)); - value++; + for (i = 0; i < PAYLOAD_ARG_CNT; i++) { + value[i] = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE)); } - ret = mmio_read_32(buffer_base); + ret = value[0]; #if IPI_CRC_CHECK - for (j = 0; j < PAYLOAD_ARG_CNT; j++) { - response_payload[j] = mmio_read_32(buffer_base + - (j * PAYLOAD_ARG_SIZE)); - } - - if (response_payload[PAYLOAD_CRC_POS] != - calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) { + if (value[PAYLOAD_CRC_POS] != + calculate_crc(value, IPI_W0_TO_W6_SIZE)) { NOTICE("ERROR in CRC response payload value:0x%x\n", - response_payload[PAYLOAD_CRC_POS]); + value[PAYLOAD_CRC_POS]); ret = PM_RET_ERROR_INVALID_CRC; /* Payload data is invalid as CRC validation failed * Clear the payload to avoid leakage of data to upper layers */ - memset(payload_ptr, 0, count); + memset(value, 0, PAYLOAD_ARG_CNT); } #endif @@ -240,7 +229,7 @@ enum pm_ret_status pm_ipi_buff_read_callb(uint32_t *value, size_t count) count = IPI_BUFFER_MAX_WORDS; } - for (i = 0; i <= count; i++) { + for (i = 0; i < count; i++) { *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE)); value++; } @@ -282,6 +271,7 @@ enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc, uint32_t *value, size_t count) { enum pm_ret_status ret; + uint32_t i, ret_payload[PAYLOAD_ARG_CNT] = {0U}; pm_ipi_lock_get(); @@ -290,7 +280,12 @@ enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc, goto unlock; } - ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count)); + ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, ret_payload)); + + for (i = 1U; i <= count; i++) { + *value = ret_payload[i]; + value++; + } unlock: pm_ipi_lock_release(); diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c index 7ac0ac1a8..1eb0c801b 100644 --- a/plat/xilinx/common/pm_service/pm_svc_main.c +++ b/plat/xilinx/common/pm_service/pm_svc_main.c @@ -278,7 +278,7 @@ static uintptr_t eemi_for_compatibility(uint32_t api_id, uint32_t *pm_arg, case (uint32_t)PM_FEATURE_CHECK: { - uint32_t result[PAYLOAD_ARG_CNT] = {0U}; + uint32_t result[RET_PAYLOAD_ARG_CNT] = {0U}; ret = pm_feature_check(pm_arg[0], result, security_flag); SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U), @@ -424,7 +424,7 @@ static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg, void *handle, uint32_t security_flag) { enum pm_ret_status ret; - uint32_t buf[PAYLOAD_ARG_CNT] = {0}; + uint32_t buf[RET_PAYLOAD_ARG_CNT] = {0}; ret = pm_handle_eemi_call(security_flag, api_id, pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3], pm_arg[4], diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c index 4cf1ed160..74c5bf3c3 100644 --- a/plat/xilinx/versal/plat_psci.c +++ b/plat/xilinx/versal/plat_psci.c @@ -197,7 +197,7 @@ static void __dead2 versal_system_reset(void) */ static void versal_pwr_domain_off(const psci_power_state_t *target_state) { - uint32_t ret, fw_api_version, version[PAYLOAD_ARG_CNT] = {0U}; + uint32_t ret, fw_api_version, version[RET_PAYLOAD_ARG_CNT] = {0U}; uint32_t cpu_id = plat_my_core_pos(); const struct pm_proc *proc = pm_get_proc(cpu_id); diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c index e5a523526..fb2005d67 100644 --- a/plat/xilinx/versal_net/plat_psci_pm.c +++ b/plat/xilinx/versal_net/plat_psci_pm.c @@ -59,7 +59,7 @@ static int32_t versal_net_pwr_domain_on(u_register_t mpidr) */ static void versal_net_pwr_domain_off(const psci_power_state_t *target_state) { - uint32_t ret, fw_api_version, version[PAYLOAD_ARG_CNT] = {0U}; + uint32_t ret, fw_api_version, version[RET_PAYLOAD_ARG_CNT] = {0U}; uint32_t cpu_id = plat_my_core_pos(); const struct pm_proc *proc = pm_get_proc(cpu_id); diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c index 3d546b313..66f011abd 100644 --- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c @@ -919,7 +919,7 @@ static enum pm_ret_status feature_check_partial(uint32_t api_id, enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version, uint32_t *bit_mask, uint8_t len) { - uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U}; + uint32_t ret_payload[RET_PAYLOAD_ARG_CNT] = {0U}; uint32_t status; /* Get API version implemented in TF-A */ diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c index 5a6a9f8c5..bf17ea413 100644 --- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c @@ -285,7 +285,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, uint32_t payload[PAYLOAD_ARG_CNT]; uint32_t pm_arg[5]; - uint32_t result[PAYLOAD_ARG_CNT] = {0}; + uint32_t result[RET_PAYLOAD_ARG_CNT] = {0}; uint32_t api_id; /* Handle case where PM wasn't initialized properly */ @@ -566,7 +566,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, PM_PACK_PAYLOAD6(payload, api_id, pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3], pm_arg[4]); ret = pm_ipi_send_sync(primary_proc, payload, result, - PAYLOAD_ARG_CNT); + RET_PAYLOAD_ARG_CNT); SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U), (uint64_t)result[1] | ((uint64_t)result[2] << 32U)); } From 4661c8f508d3ecdb7a258c71a26f489ea1bffc21 Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Mon, 24 Jun 2024 02:10:29 -0700 Subject: [PATCH 2/5] feat(xilinx): update TF-A to passthrough all PLM commands Currently, the IDs used in PLM CMD header are mixed with SMC IDs in TF-A which is restricting the range of IDs that can be used by PLM. Also, the SMC call from firmware driver is passing all 7 32-bit words in request but TF-A is not passing all of them to firmware and TF-A passes only 4 32-bit words from firmware to Linux in response. So, update TF-A to passthrough all PLM commands by having a single fixed SMC ID for all PLM commands and keep the PLM header in subsequent SMC arguments. Also, enhance size of payload argument count to support maximum payloads in request and response buffers to transmit all the IPI command properly. Signed-off-by: Jay Buddhabhatti Change-Id: I2601caba849bce3f294177b63baa1ad688e3c5bb --- plat/xilinx/common/include/pm_api_sys.h | 5 ++ plat/xilinx/common/include/pm_svc_main.h | 4 +- plat/xilinx/common/pm_service/pm_svc_main.c | 74 +++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h index ffee80522..f0d3e88fc 100644 --- a/plat/xilinx/common/include/pm_api_sys.h +++ b/plat/xilinx/common/include/pm_api_sys.h @@ -97,4 +97,9 @@ enum pm_ret_status pm_get_chipid(uint32_t *value); PM_PACK_PAYLOAD5(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4)); \ } +#define PM_PACK_PAYLOAD7(pl, mid, flag, arg0, arg1, arg2, arg3, arg4, arg5, arg6) { \ + pl[6] = (uint32_t)(arg6); \ + PM_PACK_PAYLOAD6(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4), (arg5)); \ +} + #endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/common/include/pm_svc_main.h b/plat/xilinx/common/include/pm_svc_main.h index 67fbeae63..000f198eb 100644 --- a/plat/xilinx/common/include/pm_svc_main.h +++ b/plat/xilinx/common/include/pm_svc_main.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved. - * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,6 +12,8 @@ extern bool pwrdwn_req_received; +#define PASS_THROUGH_FW_CMD_ID U(0xfff) + /******************************************************************************/ /** * SECURE_REDUNDANT_CALL() - Adds redundancy to the function call. This is to diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c index 1eb0c801b..86710b154 100644 --- a/plat/xilinx/common/pm_service/pm_svc_main.c +++ b/plat/xilinx/common/pm_service/pm_svc_main.c @@ -36,6 +36,32 @@ #define EVENT_CPU_PWRDWN (4U) #define MBOX_SGI_SHARED_IPI (7U) +/** + * upper_32_bits - return bits 32-63 of a number + * @n: the number we're accessing + */ +#define upper_32_bits(n) ((uint32_t)((n) >> 32U)) + +/** + * lower_32_bits - return bits 0-31 of a number + * @n: the number we're accessing + */ +#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffffU)) + +/** + * EXTRACT_SMC_ARGS - extracts 32-bit payloads from 64-bit SMC arguments + * @pm_arg: array of 32-bit payloads + * @x: array of 64-bit SMC arguments + */ +#define EXTRACT_ARGS(pm_arg, x) \ + for (uint32_t i = 0U; i < (PAYLOAD_ARG_CNT - 1U); i++) { \ + if ((i % 2U) != 0U) { \ + pm_arg[i] = lower_32_bits(x[(i / 2U) + 1U]); \ + } else { \ + pm_arg[i] = upper_32_bits(x[i / 2U]); \ + } \ + } + /* 1 sec of wait timeout for secondary core down */ #define PWRDWN_WAIT_TIMEOUT (1000U) DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r_el1, S3_0_C12_C11_6) @@ -448,6 +474,45 @@ static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg, (uint64_t)buf[1] | ((uint64_t)buf[2] << 32U)); } +/** + * eemi_api_handler() - Prepare EEMI payload and perform IPI transaction. + * @api_id: identifier for the API being called. + * @pm_arg: pointer to the argument data for the API call. + * @handle: Pointer to caller's context structure. + * @security_flag: SECURE_FLAG or NON_SECURE_FLAG. + * + * EEMI - Embedded Energy Management Interface is AMD-Xilinx proprietary + * protocol to allow communication between power management controller and + * different processing clusters. + * + * This handler prepares EEMI protocol payload received from kernel and performs + * IPI transaction. + * + * Return: If EEMI API found then, uintptr_t type address, else 0 + */ +static uintptr_t eemi_api_handler(uint32_t api_id, const uint32_t *pm_arg, + void *handle, uint32_t security_flag) +{ + enum pm_ret_status ret; + uint32_t buf[PAYLOAD_ARG_CNT] = {0}; + uint32_t payload[PAYLOAD_ARG_CNT] = {0}; + uint32_t module_id; + + module_id = (api_id & MODULE_ID_MASK) >> 8U; + + PM_PACK_PAYLOAD7(payload, module_id, security_flag, api_id, + pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3], + pm_arg[4], pm_arg[5]); + + ret = pm_ipi_send_sync(primary_proc, payload, (uint32_t *)buf, + PAYLOAD_ARG_CNT); + + SMC_RET4(handle, (uint64_t)ret | ((uint64_t)buf[0] << 32U), + (uint64_t)buf[1] | ((uint64_t)buf[2] << 32U), + (uint64_t)buf[3] | ((uint64_t)buf[4] << 32U), + (uint64_t)buf[5]); +} + /** * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2. * @smc_fid: Function Identifier. @@ -477,6 +542,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, uint32_t security_flag = NON_SECURE_FLAG; uint32_t api_id; bool status = false, status_tmp = false; + uint64_t x[4] = {x1, x2, x3, x4}; /* Handle case where PM wasn't initialized properly */ if (pm_up == false) { @@ -494,6 +560,14 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, security_flag = SECURE_FLAG; } + if ((smc_fid & FUNCID_NUM_MASK) == PASS_THROUGH_FW_CMD_ID) { + api_id = lower_32_bits(x[0]); + + EXTRACT_ARGS(pm_arg, x); + + return eemi_api_handler(api_id, pm_arg, handle, security_flag); + } + pm_arg[0] = (uint32_t)x1; pm_arg[1] = (uint32_t)(x1 >> 32U); pm_arg[2] = (uint32_t)x2; From c26aa08bee58e81710ee9d884247fdf9b23c0022 Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Mon, 24 Jun 2024 02:25:20 -0700 Subject: [PATCH 3/5] feat(xilinx): update SiP SVC version number SMC ID is fixed in new SiP SVC call format while it varies according to PLM header in old Linux. So, enhance SIP_SVC_VERSION number to support backward compatibility and to use full request and response buffer from bare-metal or Linux. Signed-off-by: Jay Buddhabhatti Change-Id: I6764cc92b33b7366640f553827e80c5e97985fcf --- plat/xilinx/versal/sip_svc_setup.c | 4 ++-- plat/xilinx/versal_net/sip_svc_setup.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c index 4441d3eaa..3c0bd6311 100644 --- a/plat/xilinx/versal/sip_svc_setup.c +++ b/plat/xilinx/versal/sip_svc_setup.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved. - * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,7 +22,7 @@ /* SiP Service Calls version numbers */ #define SIP_SVC_VERSION_MAJOR U(0) -#define SIP_SVC_VERSION_MINOR U(1) +#define SIP_SVC_VERSION_MINOR U(2) /* These macros are used to identify PM calls from the SMC function ID */ #define SIP_FID_MASK GENMASK(23, 16) diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c index 80d5a5323..c9748102f 100644 --- a/plat/xilinx/versal_net/sip_svc_setup.c +++ b/plat/xilinx/versal_net/sip_svc_setup.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved. * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved. - * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,7 +25,7 @@ /* SiP Service Calls version numbers */ #define SIP_SVC_VERSION_MAJOR (0U) -#define SIP_SVC_VERSION_MINOR (1U) +#define SIP_SVC_VERSION_MINOR (2U) /* These macros are used to identify PM calls from the SMC function ID */ #define SIP_FID_MASK GENMASK(23, 16) From 9a0f5d128ac70da64bc33731c4e4b29007692cc3 Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Mon, 1 Jul 2024 04:28:56 -0700 Subject: [PATCH 4/5] feat(xilinx): add feature check function for TF-A specific APIs Currently, there is common feature check function for firmware APIs and TF-A specific APIs. This should be separate from firmware APIs. So add new TF-A API for feature check of TF-A specific APIs. Signed-off-by: Jay Buddhabhatti Change-Id: I5585d17fb6aa1e98989d935117cca10bdb85133e --- plat/xilinx/common/include/pm_api_sys.h | 1 + plat/xilinx/common/include/pm_defs.h | 1 + plat/xilinx/common/pm_service/pm_api_sys.c | 31 +++++++++++++++++++++ plat/xilinx/common/pm_service/pm_svc_main.c | 9 ++++++ 4 files changed, 42 insertions(+) diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h index f0d3e88fc..029bb4382 100644 --- a/plat/xilinx/common/include/pm_api_sys.h +++ b/plat/xilinx/common/include/pm_api_sys.h @@ -64,6 +64,7 @@ enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event, uint32_t wake, uint32_t enable, uint32_t flag); enum pm_ret_status pm_get_chipid(uint32_t *value); +enum pm_ret_status eemi_feature_check(uint32_t api_id, uint32_t *ret_payload); /* * Assigning of argument values into array elements. diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h index 055fa3d1e..30b75bcb0 100644 --- a/plat/xilinx/common/include/pm_defs.h +++ b/plat/xilinx/common/include/pm_defs.h @@ -35,6 +35,7 @@ (uint32_t)XPM_NODESUBCL_DEV_PERIPH, \ (uint32_t)XPM_NODETYPE_DEV_PERIPH, (IDX)) +#define TF_A_FEATURE_CHECK 0xa00U #define PM_GET_CALLBACK_DATA 0xa01U #define PM_GET_TRUSTZONE_VERSION 0xa03U #define TF_A_PM_REGISTER_SGI 0xa04U diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c index 14992858c..e9c5f138a 100644 --- a/plat/xilinx/common/pm_service/pm_api_sys.c +++ b/plat/xilinx/common/pm_service/pm_api_sys.c @@ -363,6 +363,37 @@ enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device, return pm_ipi_send_sync(primary_proc, payload, NULL, 0); } +/** + * eemi_feature_check() - Returns the supported API version if supported. + * @api_id: API ID to check. + * @ret_payload: pointer to array of PAYLOAD_ARG_CNT number of + * words Returned supported API version + * + * Return: Returns status, either success or error+reason. + */ +enum pm_ret_status eemi_feature_check(uint32_t api_id, uint32_t *ret_payload) +{ + enum pm_ret_status ret; + + /* Return version of API which are implemented in TF-A only */ + switch (api_id) { + case PM_GET_CALLBACK_DATA: + case PM_GET_TRUSTZONE_VERSION: + ret_payload[0] = PM_API_VERSION_2; + ret = PM_RET_SUCCESS; + break; + case TF_A_PM_REGISTER_SGI: + case TF_A_FEATURE_CHECK: + ret_payload[0] = PM_API_BASE_VERSION; + ret = PM_RET_SUCCESS; + break; + default: + ret = PM_RET_ERROR_NO_FEATURE; + } + + return ret; +} + /** * pm_feature_check() - Returns the supported API version if supported. * @api_id: API ID to check. diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c index 86710b154..b431a6c41 100644 --- a/plat/xilinx/common/pm_service/pm_svc_main.c +++ b/plat/xilinx/common/pm_service/pm_svc_main.c @@ -393,6 +393,15 @@ static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg, { switch (api_id) { + case TF_A_FEATURE_CHECK: + { + enum pm_ret_status ret; + uint32_t result[PAYLOAD_ARG_CNT] = {0U}; + + ret = eemi_feature_check(pm_arg[0], result); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U)); + } + case TF_A_PM_REGISTER_SGI: { int32_t ret; From e1890297df829fe7a3af705c5c484aaf5d215a99 Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Sun, 14 Jul 2024 23:29:04 -0700 Subject: [PATCH 5/5] docs(xilinx): update SMC documentation in TF-A Updated documentation for new SMC SiP calling conventions for Platform Management specific SiP Service calls. Signed-off-by: Jay Buddhabhatti Change-Id: Iee09d3d843c6bb3f82aad6df703542ba1eb63c6c --- docs/plat/xilinx-versal-net.rst | 15 ++++++++++++++- docs/plat/xilinx-versal.rst | 17 +++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst index e9dd77210..d22a46d12 100644 --- a/docs/plat/xilinx-versal-net.rst +++ b/docs/plat/xilinx-versal-net.rst @@ -75,7 +75,7 @@ IPI SMC call ranges | 0xc2001000-0xc2001FFF | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI | +---------------------------+-----------------------------------------------------------+ -PM SMC call ranges +PM SMC call ranges for SiP SVC version 0.1 -------------------------------------------------------- +---------------------------+---------------------------------------------------------------------------+ @@ -84,6 +84,19 @@ PM SMC call ranges | 0xc2000000-0xc2000FFF | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management | +---------------------------+---------------------------------------------------------------------------+ +PM SMC call ranges for SiP SVC version 0.2 +-------------------------------------------------------- + ++---------------------------+---------------------------------------------------------------------------+ +| SMC Function Identifier | Service type | ++---------------------------+---------------------------------------------------------------------------+ +| 0xc2000FFF | Fast SMC64 SiP Service call used for pass-through of AMD-Xilinx Platform | +| | Management APIs to firmware | ++---------------------------+---------------------------------------------------------------------------+ +| 0xc2000A00-0xc2000AFF | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management | +| | specific TF-A APIs | ++---------------------------+---------------------------------------------------------------------------+ + SMC function IDs for SiP Service queries ---------------------------------------------- diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst index 072329a5b..9463dfa23 100644 --- a/docs/plat/xilinx-versal.rst +++ b/docs/plat/xilinx-versal.rst @@ -98,8 +98,8 @@ IPI SMC call ranges | 0xc2001000-0xc2001FFF | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI | +---------------------------+-----------------------------------------------------------+ -PM SMC call ranges ------------------- +PM SMC call ranges for SiP SVC version 0.1 +-------------------------------------------------------- +---------------------------+---------------------------------------------------------------------------+ | SMC Function Identifier | Service type | @@ -107,6 +107,19 @@ PM SMC call ranges | 0xc2000000-0xc2000FFF | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management | +---------------------------+---------------------------------------------------------------------------+ +PM SMC call ranges for SiP SVC version 0.2 +-------------------------------------------------------- + ++---------------------------+---------------------------------------------------------------------------+ +| SMC Function Identifier | Service type | ++---------------------------+---------------------------------------------------------------------------+ +| 0xc2000FFF | Fast SMC64 SiP Service call used for pass-through of AMD-Xilinx Platform | +| | Management APIs to firmware | ++---------------------------+---------------------------------------------------------------------------+ +| 0xc2000A00-0xc2000AFF | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management | +| | specific TF-A APIs | ++---------------------------+---------------------------------------------------------------------------+ + SMC function IDs for SiP Service queries ----------------------------------------