5c2a635bb98b7af70f55189f97f812f6a18115a5
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
7 #include <arch_helpers.h>
9 #include <bakery_lock.h>
11 #include <platform_def.h>
12 #include <sq_common.h>
15 /* SCP MHU secure channel registers */
16 #define SCP_INTR_S_STAT 0x200
17 #define SCP_INTR_S_SET 0x208
18 #define SCP_INTR_S_CLEAR 0x210
20 /* CPU MHU secure channel registers */
21 #define CPU_INTR_S_STAT 0x300
22 #define CPU_INTR_S_SET 0x308
23 #define CPU_INTR_S_CLEAR 0x310
25 DEFINE_BAKERY_LOCK(sq_lock
);
28 * Slot 31 is reserved because the MHU hardware uses this register bit to
29 * indicate a non-secure access attempt. The total number of available slots is
30 * therefore 31 [30:0].
32 #define MHU_MAX_SLOT_ID 30
34 void mhu_secure_message_start(unsigned int slot_id
)
36 assert(slot_id
<= MHU_MAX_SLOT_ID
);
38 bakery_lock_get(&sq_lock
);
40 /* Make sure any previous command has finished */
41 while (mmio_read_32(PLAT_SQ_MHU_BASE
+ CPU_INTR_S_STAT
) &
46 void mhu_secure_message_send(unsigned int slot_id
)
48 assert(slot_id
<= MHU_MAX_SLOT_ID
);
49 assert(!(mmio_read_32(PLAT_SQ_MHU_BASE
+ CPU_INTR_S_STAT
) &
52 /* Send command to SCP */
53 mmio_write_32(PLAT_SQ_MHU_BASE
+ CPU_INTR_S_SET
, 1 << slot_id
);
56 uint32_t mhu_secure_message_wait(void)
60 /* Wait for response from SCP */
61 while (!(response
= mmio_read_32(PLAT_SQ_MHU_BASE
+ SCP_INTR_S_STAT
)))
67 void mhu_secure_message_end(unsigned int slot_id
)
69 assert(slot_id
<= MHU_MAX_SLOT_ID
);
72 * Clear any response we got by writing one in the relevant slot bit to
75 mmio_write_32(PLAT_SQ_MHU_BASE
+ SCP_INTR_S_CLEAR
, 1 << slot_id
);
77 bakery_lock_release(&sq_lock
);
80 void mhu_secure_init(void)
82 bakery_lock_init(&sq_lock
);
85 * The STAT register resets to zero. Ensure it is in the expected state,
86 * as a stale or garbage value would make us think it's a message we've
89 assert(mmio_read_32(PLAT_SQ_MHU_BASE
+ CPU_INTR_S_STAT
) == 0);
92 void plat_sq_pwrc_setup(void)