diff options
author | Venkatesh Yadav Abbarapu <venkatesh.abbarapu@xilinx.com> | 2020-11-23 04:26:54 -0800 |
---|---|---|
committer | Manish Pandey <manish.pandey2@arm.com> | 2021-01-04 11:50:14 +0000 |
commit | 504925f99da0d9c63646b1eb3c1ad9a861c20968 (patch) | |
tree | c14e2bcebbf65c22e3ca406232b6d70b903e6c53 /plat/xilinx | |
parent | 1f91019457b7c2e0f7e9445935985f3d376ad844 (diff) | |
download | trusted-firmware-a-504925f99da0d9c63646b1eb3c1ad9a861c20968.tar.gz |
xilinx: zynqmp: Add support for Error Management
Adding the EM specific smc handler for the EM-related requests.
Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@xilinx.com>
Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
Change-Id: I98122d49604a01a2f6bd1e509a5896ee68069dd0
Diffstat (limited to 'plat/xilinx')
-rw-r--r-- | plat/xilinx/zynqmp/pm_service/pm_api_sys.c | 31 | ||||
-rw-r--r-- | plat/xilinx/zynqmp/pm_service/pm_api_sys.h | 3 | ||||
-rw-r--r-- | plat/xilinx/zynqmp/pm_service/pm_defs.h | 10 | ||||
-rw-r--r-- | plat/xilinx/zynqmp/pm_service/pm_svc_main.c | 53 | ||||
-rw-r--r-- | plat/xilinx/zynqmp/pm_service/pm_svc_main.h | 5 | ||||
-rw-r--r-- | plat/xilinx/zynqmp/sip_svc_setup.c | 11 |
6 files changed, 110 insertions, 3 deletions
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index 3427149353..9a53408fd2 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -65,6 +65,10 @@ unsigned int pm_get_shutdown_scope(void) PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4); \ } +#define EM_PACK_PAYLOAD1(pl, arg0) { \ + pl[0] = (uint16_t)(0xE) << 16 | (uint16_t)arg0; \ +} + /** * pm_self_suspend() - PM call for processor to suspend itself * @nid Node id of the processor or subsystem @@ -1617,3 +1621,30 @@ enum pm_ret_status pm_efuse_access(uint32_t address_high, return pm_ipi_send_sync(primary_proc, payload, value, 1); } + +enum pm_ret_status em_set_action(unsigned int *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + EM_PACK_PAYLOAD1(payload, EM_SET_ACTION); + return pm_ipi_send_sync(primary_proc, payload, value, 1); +} + +enum pm_ret_status em_remove_action(unsigned int *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + EM_PACK_PAYLOAD1(payload, EM_REMOVE_ACTION); + return pm_ipi_send_sync(primary_proc, payload, value, 1); +} + +enum pm_ret_status em_send_errors(unsigned int *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS); + return pm_ipi_send_sync(primary_proc, payload, value, 1); +} diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h index b3ebb27525..b0c26529d3 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h @@ -198,5 +198,8 @@ enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode); enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode); enum pm_ret_status pm_efuse_access(uint32_t address_high, uint32_t address_low, uint32_t *value); +enum pm_ret_status em_set_action(unsigned int *value); +enum pm_ret_status em_remove_action(unsigned int *value); +enum pm_ret_status em_send_errors(unsigned int *value); #endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h index da8789301a..ee31c9267b 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_defs.h +++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h @@ -33,6 +33,7 @@ #define PM_STATE_CPU_IDLE 0x0U #define PM_STATE_SUSPEND_TO_RAM 0xFU +#define EM_FUNID_NUM_MASK 0xF0000U /********************************************************************* * Enum definitions ********************************************************************/ @@ -323,4 +324,13 @@ enum pm_clock_div_id { PM_CLOCK_DIV1_ID, }; +/** + * EM API IDs + */ +enum em_api_id { + EM_SET_ACTION = 1, + EM_REMOVE_ACTION, + EM_SEND_ERRORS, +}; + #endif /* PM_DEFS_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index 5b3e73724d..a4bc1ac080 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -628,3 +628,56 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, SMC_RET1(handle, SMC_UNK); } } + +/** + * em_smc_handler() - SMC handler for EM-API calls coming from EL1/EL2. + * @smc_fid - Function Identifier + * @x1 - x4 - Arguments + * @cookie - Unused + * @handler - Pointer to caller's context structure + * + * @return - Unused + * + * Determines that smc_fid is valid and supported EM SMC Function ID from the + * list of em_api_ids, otherwise completes the request with + * the unknown SMC Function ID + * + * The SMC calls for EM service are forwarded from SIP Service SMC handler + * function with rt_svc_handle signature + */ +uint64_t em_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, + uint64_t x4, void *cookie, void *handle, uint64_t flags) +{ + enum pm_ret_status ret; + + switch (smc_fid & FUNCID_NUM_MASK) { + /* EM API Functions */ + case EM_SET_ACTION: + { + uint32_t value; + + ret = em_set_action(&value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case EM_REMOVE_ACTION: + { + uint32_t value; + + ret = em_remove_action(&value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case EM_SEND_ERRORS: + { + uint32_t value; + + ret = em_send_errors(&value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + default: + WARN("Unimplemented EM Service Call: 0x%x\n", smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h index 0968f64cba..abadd40653 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,4 +14,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, void *cookie, void *handle, uint64_t flags); +uint64_t em_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, + uint64_t x4, void *cookie, void *handle, + uint64_t flags); #endif /* PM_SVC_MAIN_H */ diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c index 9b182749cb..4c29da2317 100644 --- a/plat/xilinx/zynqmp/sip_svc_setup.c +++ b/plat/xilinx/zynqmp/sip_svc_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,6 +25,9 @@ #define PM_FID_MASK 0xf000u #define PM_FID_VALUE 0u #define IPI_FID_VALUE 0x1000u +#define EM_FID_MASK 0xf0000u +#define EM_FID_VALUE 0xE0000u +#define is_em_fid(_fid) (((_fid) & EM_FID_MASK) == EM_FID_VALUE) #define is_pm_fid(_fid) (((_fid) & PM_FID_MASK) == PM_FID_VALUE) #define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE) @@ -61,8 +64,12 @@ uintptr_t sip_svc_smc_handler(uint32_t smc_fid, void *handle, u_register_t flags) { + /* Let EM SMC handler deal with EM-related requests */ + if (is_em_fid(smc_fid)) { + return em_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, + flags); + } else if (is_pm_fid(smc_fid)) { /* Let PM SMC handler deal with PM-related requests */ - if (is_pm_fid(smc_fid)) { return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); } |