1 /* 2 * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch_helpers.h> 8 #include <assert.h> 9 #include <bakery_lock.h> 10 #include <css_def.h> 11 #include <mmio.h> 12 #include <plat_arm.h> 13 #include <platform_def.h> 14 #include "css_mhu.h" 15 16 /* SCP MHU secure channel registers */ 17 #define SCP_INTR_S_STAT 0x200 18 #define SCP_INTR_S_SET 0x208 19 #define SCP_INTR_S_CLEAR 0x210 20 21 /* CPU MHU secure channel registers */ 22 #define CPU_INTR_S_STAT 0x300 23 #define CPU_INTR_S_SET 0x308 24 #define CPU_INTR_S_CLEAR 0x310 25 26 ARM_INSTANTIATE_LOCK; 27 28 /* Weak definition may be overridden in specific CSS based platform */ 29 #pragma weak plat_arm_pwrc_setup 30 31 32 /* 33 * Slot 31 is reserved because the MHU hardware uses this register bit to 34 * indicate a non-secure access attempt. The total number of available slots is 35 * therefore 31 [30:0]. 36 */ 37 #define MHU_MAX_SLOT_ID 30 38 mhu_secure_message_start(unsigned int slot_id)39void mhu_secure_message_start(unsigned int slot_id) 40 { 41 assert(slot_id <= MHU_MAX_SLOT_ID); 42 43 arm_lock_get(); 44 45 /* Make sure any previous command has finished */ 46 while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & 47 (1 << slot_id)) 48 ; 49 } 50 mhu_secure_message_send(unsigned int slot_id)51void mhu_secure_message_send(unsigned int slot_id) 52 { 53 assert(slot_id <= MHU_MAX_SLOT_ID); 54 assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & 55 (1 << slot_id))); 56 57 /* Send command to SCP */ 58 mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id); 59 } 60 mhu_secure_message_wait(void)61uint32_t mhu_secure_message_wait(void) 62 { 63 /* Wait for response from SCP */ 64 uint32_t response; 65 while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT))) 66 ; 67 68 return response; 69 } 70 mhu_secure_message_end(unsigned int slot_id)71void mhu_secure_message_end(unsigned int slot_id) 72 { 73 assert(slot_id <= MHU_MAX_SLOT_ID); 74 75 /* 76 * Clear any response we got by writing one in the relevant slot bit to 77 * the CLEAR register 78 */ 79 mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id); 80 81 arm_lock_release(); 82 } 83 mhu_secure_init(void)84void mhu_secure_init(void) 85 { 86 arm_lock_init(); 87 88 /* 89 * The STAT register resets to zero. Ensure it is in the expected state, 90 * as a stale or garbage value would make us think it's a message we've 91 * already sent. 92 */ 93 assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0); 94 } 95 plat_arm_pwrc_setup(void)96void plat_arm_pwrc_setup(void) 97 { 98 mhu_secure_init(); 99 } 100