diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h index 16db5c5..7bcf596 100644 --- a/plat/xilinx/common/include/pm_ipi.h +++ b/plat/xilinx/common/include/pm_ipi.h @@ -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 */ @@ -26,5 +26,8 @@ void pm_ipi_irq_enable(const struct pm_proc *proc); void pm_ipi_irq_clear(const struct pm_proc *proc); uint32_t pm_ipi_irq_status(const struct pm_proc *proc); +#if ZYNQMP_IPI_CRC_CHECK +uint32_t calculate_crc(uint32_t payload[PAYLOAD_ARG_CNT], uint32_t buffersize); +#endif #endif /* PM_IPI_H */ diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c index 034cd5b..c83d25b 100644 --- a/plat/xilinx/common/pm_service/pm_ipi.c +++ b/plat/xilinx/common/pm_service/pm_ipi.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 */ @@ -57,6 +57,9 @@ uintptr_t buffer_base = proc->ipi->buffer_base + IPI_BUFFER_TARGET_REMOTE_OFFSET + IPI_BUFFER_REQ_OFFSET; +#if ZYNQMP_IPI_CRC_CHECK + payload[PAYLOAD_CRC_POS] = calculate_crc(payload, IPI_W0_TO_W6_SIZE); +#endif /* Write payload into IPI buffer */ for (size_t i = 0; i < PAYLOAD_ARG_CNT; i++) { @@ -132,6 +135,10 @@ unsigned int *value, size_t count) { size_t i; +#if ZYNQMP_IPI_CRC_CHECK + size_t j; + unsigned int response_payload[PAYLOAD_ARG_CNT]; +#endif uintptr_t buffer_base = proc->ipi->buffer_base + IPI_BUFFER_TARGET_REMOTE_OFFSET + IPI_BUFFER_RESP_OFFSET; @@ -147,6 +154,16 @@ *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE)); value++; } +#if ZYNQMP_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)) + NOTICE("ERROR in CRC response payload value:0x%x\n", + response_payload[PAYLOAD_CRC_POS]); +#endif return mmio_read_32(buffer_base); } @@ -162,6 +179,10 @@ void pm_ipi_buff_read_callb(unsigned int *value, size_t count) { size_t i; +#if ZYNQMP_IPI_CRC_CHECK + size_t j; + unsigned int response_payload[PAYLOAD_ARG_CNT]; +#endif uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE + IPI_BUFFER_TARGET_LOCAL_OFFSET + IPI_BUFFER_REQ_OFFSET; @@ -173,6 +194,16 @@ *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE)); value++; } +#if ZYNQMP_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)) + NOTICE("ERROR in CRC response payload value:0x%x\n", + response_payload[PAYLOAD_CRC_POS]); +#endif } /** @@ -228,3 +259,34 @@ else return 0; } + +#if ZYNQMP_IPI_CRC_CHECK +uint32_t calculate_crc(uint32_t *payload, uint32_t bufsize) +{ + uint32_t crcinit = CRC_INIT_VALUE; + uint32_t order = CRC_ORDER; + uint32_t polynom = CRC_POLYNOM; + uint32_t i, j, c, bit, datain, crcmask, crchighbit; + uint32_t crc = crcinit; + + crcmask = ((uint32_t)((1U << (order - 1U)) - 1U) << 1U) | 1U; + crchighbit = (uint32_t)(1U << (order - 1U)); + + for (i = 0U; i < bufsize; i++) { + datain = mmio_read_8((unsigned long)payload + i); + c = datain; + j = 0x80U; + while (j != 0U) { + bit = crc & crchighbit; + crc <<= 1U; + if (0U != (c & j)) + bit ^= crchighbit; + if (bit != 0U) + crc ^= polynom; + j >>= 1U; + } + crc &= crcmask; + } + return crc; +} +#endif diff --git a/plat/xilinx/zynqmp/include/plat_pm_common.h b/plat/xilinx/zynqmp/include/plat_pm_common.h index 1b371cc..56a747a 100644 --- a/plat/xilinx/zynqmp/include/plat_pm_common.h +++ b/plat/xilinx/zynqmp/include/plat_pm_common.h @@ -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 */ @@ -16,7 +16,16 @@ #include #include "pm_defs.h" -#define PAYLOAD_ARG_CNT 6U +#if ZYNQMP_IPI_CRC_CHECK +#define PAYLOAD_ARG_CNT 8U +#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 +#endif #define PAYLOAD_ARG_SIZE 4U /* size in bytes */ #define ZYNQMP_TZ_VERSION_MAJOR 1 diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk index c34a516..1039e27 100644 --- a/plat/xilinx/zynqmp/platform.mk +++ b/plat/xilinx/zynqmp/platform.mk @@ -1,5 +1,5 @@ # -# 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 @@ -9,6 +9,7 @@ A53_DISABLE_NON_TEMPORAL_HINT := 0 SEPARATE_CODE_AND_RODATA := 1 ZYNQMP_WDT_RESTART := 0 +ZYNQMP_IPI_CRC_CHECK := 0 override RESET_TO_BL31 := 1 # Do not enable SVE @@ -45,7 +46,12 @@ $(eval $(call add_define,ZYNQMP_WDT_RESTART)) endif -PLAT_INCLUDES := -Iinclude/plat/arm/common/aarch64/ \ +ifdef ZYNQMP_IPI_CRC_CHECK + $(eval $(call add_define,ZYNQMP_IPI_CRC_CHECK)) +endif + +PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ + -Iinclude/plat/arm/common/aarch64/ \ -Iplat/xilinx/common/include/ \ -Iplat/xilinx/zynqmp/include/ \ -Iplat/xilinx/zynqmp/pm_service/ \