diff --git a/plat/arm/board/corstone700/corstone700_plat.c b/plat/arm/board/corstone700/corstone700_plat.c index cee6fd6..e2ade70 100644 --- a/plat/arm/board/corstone700/corstone700_plat.c +++ b/plat/arm/board/corstone700/corstone700_plat.c @@ -1,10 +1,12 @@ /* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include + +#include #include #include #include @@ -26,6 +28,7 @@ */ void __init plat_arm_pwrc_setup(void) { + mhu_secure_init(); } unsigned int plat_get_syscnt_freq2(void) diff --git a/plat/arm/board/corstone700/drivers/mhu/mhu.c b/plat/arm/board/corstone700/drivers/mhu/mhu.c new file mode 100644 index 0000000..2231d11 --- /dev/null +++ b/plat/arm/board/corstone700/drivers/mhu/mhu.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +#include "mhu.h" +#include +#include + +ARM_INSTANTIATE_LOCK; + +#pragma weak plat_arm_pwrc_setup + +/* + * Slot 31 is reserved because the MHU hardware uses this register bit to + * indicate a non-secure access attempt. The total number of available slots is + * therefore 31 [30:0]. + */ +#define MHU_MAX_SLOT_ID 30 + +void mhu_secure_message_start(uintptr_t address, unsigned int slot_id) +{ + unsigned int intr_stat_check; + uint64_t timeout_cnt; + volatile uint8_t expiration; + + assert(slot_id <= MHU_MAX_SLOT_ID); + arm_lock_get(); + + /* + * Make sure any previous command has finished + * and polling timeout not expired + */ + + timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); + + do { + intr_stat_check = (mmio_read_32(address + CPU_INTR_S_STAT) & + (1 << slot_id)); + + expiration = timeout_elapsed(timeout_cnt); + + } while ((intr_stat_check != 0U) && (expiration == 0U)); + + /* + * Note: No risk of timer overflows while waiting + * for the timeout expiration. + * According to Armv8 TRM: System counter roll-over + * time of not less than 40 years + */ +} + +void mhu_secure_message_send(uintptr_t address, + unsigned int slot_id, + unsigned int message) +{ + unsigned char access_ready; + uint64_t timeout_cnt; + volatile uint8_t expiration; + + assert(slot_id <= MHU_MAX_SLOT_ID); + assert((mmio_read_32(address + CPU_INTR_S_STAT) & + (1 << slot_id)) == 0U); + + MHU_V2_ACCESS_REQUEST(address); + + timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT); + + do { + access_ready = MHU_V2_IS_ACCESS_READY(address); + expiration = timeout_elapsed(timeout_cnt); + + } while ((access_ready == 0U) && (expiration == 0U)); + + /* + * Note: No risk of timer overflows while waiting + * for the timeout expiration. + * According to Armv8 TRM: System counter roll-over + * time of not less than 40 years + */ + + mmio_write_32(address + CPU_INTR_S_SET, message); +} + +void mhu_secure_message_end(uintptr_t address, unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + /* + * Clear any response we got by writing one in the relevant slot bit to + * the CLEAR register + */ + MHU_V2_CLEAR_REQUEST(address); + + arm_lock_release(); +} + +void __init mhu_secure_init(void) +{ + arm_lock_init(); + + /* + * The STAT register resets to zero. Ensure it is in the expected state, + * as a stale or garbage value would make us think it's a message we've + * already sent. + */ + + assert(mmio_read_32(PLAT_SDK700_MHU0_SEND + CPU_INTR_S_STAT) == 0); +} diff --git a/plat/arm/board/corstone700/drivers/mhu/mhu.h b/plat/arm/board/corstone700/drivers/mhu/mhu.h new file mode 100644 index 0000000..3808746 --- /dev/null +++ b/plat/arm/board/corstone700/drivers/mhu/mhu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MHU_H +#define MHU_H + +#define MHU_POLL_INTR_STAT_TIMEOUT 50000 /*timeout value in us*/ + +/* CPU MHU secure channel registers */ +#define CPU_INTR_S_STAT 0x00 +#define CPU_INTR_S_SET 0x0C + +/* MHUv2 Control Registers Offsets */ +#define MHU_V2_MSG_CFG_OFFSET 0xF80 +#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 +#define MHU_V2_ACCESS_READY_OFFSET 0xF8C + +#define MHU_V2_ACCESS_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) + +#define MHU_V2_CLEAR_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) + +#define MHU_V2_IS_ACCESS_READY(addr) \ + (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) + +void mhu_secure_message_start(uintptr_t address, unsigned int slot_id); +void mhu_secure_message_send(uintptr_t address, + unsigned int slot_id, + unsigned int message); +void mhu_secure_message_end(uintptr_t address, unsigned int slot_id); +void mhu_secure_init(void); + +#endif /* MHU_H */ diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h index 8dff3ec..85a3731 100644 --- a/plat/arm/board/corstone700/include/platform_def.h +++ b/plat/arm/board/corstone700/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -88,6 +88,10 @@ #define PLAT_ARM_GICD_BASE 0x1C010000 #define PLAT_ARM_GICC_BASE 0x1C02F000 +/* MHUv2 Secure Channel receiver and sender */ +#define PLAT_SDK700_MHU0_SEND 0x1B800000 +#define PLAT_SDK700_MHU0_RECV 0x1B810000 + /* Timer/watchdog related constants */ #define ARM_SYS_CNTCTL_BASE UL(0x1a200000) #define ARM_SYS_CNTREAD_BASE UL(0x1a210000) diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk index bff3589..a4d4f22 100644 --- a/plat/arm/board/corstone700/platform.mk +++ b/plat/arm/board/corstone700/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -11,16 +11,19 @@ plat/arm/common/arm_common.c \ lib/xlat_tables/aarch32/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ - ${CORSTONE700_CPU_LIBS} + ${CORSTONE700_CPU_LIBS} \ + plat/arm/board/corstone700/drivers/mhu/mhu.c -PLAT_INCLUDES := -Iplat/arm/board/corstone700/include +PLAT_INCLUDES := -Iplat/arm/board/corstone700/include \ + -Iinclude/plat/arm/common \ + -Iplat/arm/board/corstone700/drivers/mhu NEED_BL32 := yes -CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - plat/common/plat_gicv2.c \ +CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c # BL1/BL2 Image not a part of the capsule Image for Corstone700