1 /*
2  * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
3  * Copyright (c) 2019, 2021 Cypress Semiconductor Corporation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "cmsis_compiler.h"
9 
10 #include "platform_multicore.h"
11 #include "tfm_multi_core_api.h"
12 
13 #include "cy_ipc_drv.h"
14 #include "cy_sysint.h"
15 #if CY_SYSTEM_CPU_CM0P
16 #include "spe_ipc_config.h"
17 #else
18 #include "ns_ipc_config.h"
19 #endif
20 
platform_mailbox_fetch_msg_ptr(void ** msg_ptr)21 int platform_mailbox_fetch_msg_ptr(void **msg_ptr)
22 {
23     cy_en_ipcdrv_status_t status;
24 
25     if (!msg_ptr) {
26         return PLATFORM_MAILBOX_INVAL_PARAMS;
27     }
28 
29     status = Cy_IPC_Drv_ReadMsgPtr(Cy_IPC_Drv_GetIpcBaseAddress(IPC_RX_CHAN),
30                                    msg_ptr);
31     if (status != CY_IPC_DRV_SUCCESS) {
32         return PLATFORM_MAILBOX_RX_ERROR;
33     }
34 
35     Cy_IPC_Drv_ReleaseNotify(Cy_IPC_Drv_GetIpcBaseAddress(IPC_RX_CHAN),
36                              IPC_RX_RELEASE_MASK);
37     return PLATFORM_MAILBOX_SUCCESS;
38 }
39 
platform_mailbox_fetch_msg_data(uint32_t * data_ptr)40 int platform_mailbox_fetch_msg_data(uint32_t *data_ptr)
41 {
42     cy_en_ipcdrv_status_t status;
43 
44     if (!data_ptr) {
45         return PLATFORM_MAILBOX_INVAL_PARAMS;
46     }
47 
48     status = Cy_IPC_Drv_ReadMsgWord(Cy_IPC_Drv_GetIpcBaseAddress(IPC_RX_CHAN),
49                                     data_ptr);
50     if (status != CY_IPC_DRV_SUCCESS) {
51         return PLATFORM_MAILBOX_RX_ERROR;
52     }
53 
54     Cy_IPC_Drv_ReleaseNotify(Cy_IPC_Drv_GetIpcBaseAddress(IPC_RX_CHAN),
55                              IPC_RX_RELEASE_MASK);
56     return PLATFORM_MAILBOX_SUCCESS;
57 }
58 
platform_mailbox_send_msg_ptr(const void * msg_ptr)59 int platform_mailbox_send_msg_ptr(const void *msg_ptr)
60 {
61     cy_en_ipcdrv_status_t status;
62 
63     if (!msg_ptr)
64         return PLATFORM_MAILBOX_INVAL_PARAMS;
65 
66     status = Cy_IPC_Drv_SendMsgPtr(Cy_IPC_Drv_GetIpcBaseAddress(IPC_TX_CHAN),
67                                    IPC_TX_NOTIFY_MASK, msg_ptr);
68     if (status != CY_IPC_DRV_SUCCESS) {
69         return PLATFORM_MAILBOX_TX_ERROR;
70     }
71 
72     return PLATFORM_MAILBOX_SUCCESS;
73 }
74 
platform_mailbox_send_msg_data(uint32_t data)75 int platform_mailbox_send_msg_data(uint32_t data)
76 {
77     cy_en_ipcdrv_status_t status;
78 
79     status = Cy_IPC_Drv_SendMsgWord(Cy_IPC_Drv_GetIpcBaseAddress(IPC_TX_CHAN),
80                                     IPC_TX_NOTIFY_MASK, data);
81     if (status != CY_IPC_DRV_SUCCESS) {
82         return PLATFORM_MAILBOX_TX_ERROR;
83     }
84 
85     return PLATFORM_MAILBOX_SUCCESS;
86 }
87 
platform_mailbox_wait_for_notify(void)88 void platform_mailbox_wait_for_notify(void)
89 {
90     uint32_t status;
91 
92     while (1) {
93         status = Cy_IPC_Drv_GetInterruptStatusMasked(
94                             Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT));
95         status >>= CY_IPC_NOTIFY_SHIFT;
96         if (status & IPC_RX_INT_MASK) {
97             break;
98         }
99     }
100 
101     Cy_IPC_Drv_ClearInterrupt(Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT),
102                               0, IPC_RX_INT_MASK);
103 }
104 
platform_ns_ipc_init(void)105 static int platform_ns_ipc_init(void)
106 {
107     Cy_IPC_Drv_SetInterruptMask(Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT),
108                                 0, IPC_RX_INT_MASK);
109     return PLATFORM_MAILBOX_SUCCESS;
110 }
111 
tfm_platform_ns_wait_for_s_cpu_ready(void)112 int32_t tfm_platform_ns_wait_for_s_cpu_ready(void)
113 {
114     uint32_t data = 0;
115 
116     if (platform_ns_ipc_init() != PLATFORM_MAILBOX_SUCCESS) {
117         return PLATFORM_MAILBOX_INVAL_PARAMS;
118     }
119     while(data != IPC_SYNC_MAGIC)
120     {
121         platform_mailbox_wait_for_notify();
122         platform_mailbox_fetch_msg_data(&data);
123     }
124 
125     if (platform_mailbox_send_msg_data(~IPC_SYNC_MAGIC) !=
126         PLATFORM_MAILBOX_SUCCESS) {
127         return PLATFORM_MAILBOX_RX_ERROR;
128     }
129     return PLATFORM_MAILBOX_SUCCESS;
130 }
131