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