Skip to content

Commit 88d9313

Browse files
authored
Merge pull request #13358 from RaymondNgun/topic/cytfm_064b0s2_4343w
Add CYTFM_064B0S2 4343W Target
2 parents ead1cec + 1be0b1f commit 88d9313

File tree

154 files changed

+36242
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+36242
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
/*
2+
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
3+
* Copyright (c) 2019, Cypress Semiconductor Corporation. All rights reserved
4+
*
5+
* SPDX-License-Identifier: BSD-3-Clause
6+
*/
7+
8+
/* -------------------------------------- Includes ----------------------------------- */
9+
#include <limits.h>
10+
#include <string.h>
11+
12+
#include "cmsis_compiler.h"
13+
14+
#include "cy_ipc_drv.h"
15+
#include "cy_sysint.h"
16+
#include "cy_ipc_sema.h"
17+
18+
#include "ns_ipc_config.h"
19+
#include "tfm_ns_mailbox.h"
20+
#include "platform_multicore.h"
21+
#include "cmsis_os2.h"
22+
23+
static uint8_t saved_irq_state = 1;
24+
25+
/* -------------------------------------- HAL API ------------------------------------ */
26+
27+
static void mailbox_ipc_init(void)
28+
{
29+
Cy_IPC_Drv_SetInterruptMask(Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT),
30+
0, IPC_RX_INT_MASK);
31+
}
32+
33+
static void mailbox_ipc_config(void)
34+
{
35+
NVIC_SetPriority(PSA_CLIENT_REPLY_NVIC_IRQn, PSA_CLIENT_REPLY_IRQ_PRIORITY);
36+
37+
NVIC_EnableIRQ(PSA_CLIENT_REPLY_NVIC_IRQn);
38+
}
39+
40+
int32_t tfm_ns_mailbox_hal_notify_peer(void)
41+
{
42+
cy_en_ipcdrv_status_t status;
43+
44+
status = Cy_IPC_Drv_SendMsgWord(Cy_IPC_Drv_GetIpcBaseAddress(IPC_TX_CHAN),
45+
IPC_TX_NOTIFY_MASK,
46+
PSA_CLIENT_CALL_REQ_MAGIC);
47+
48+
if (status == CY_IPC_DRV_SUCCESS) {
49+
return MAILBOX_SUCCESS;
50+
} else {
51+
return MAILBOX_CHAN_BUSY;
52+
}
53+
}
54+
55+
static int32_t mailbox_sema_init(void)
56+
{
57+
#if defined(CY_IPC_DEFAULT_CFG_DISABLE)
58+
/* semaphore data */
59+
static uint32_t tfm_sema __attribute__((section("TFM_SHARED_DATA")));
60+
61+
if (Cy_IPC_Sema_Init(PLATFORM_MAILBOX_IPC_CHAN_SEMA,
62+
sizeof(tfm_sema) * CHAR_BIT,
63+
&tfm_sema) != CY_IPC_SEMA_SUCCESS) {
64+
return PLATFORM_MAILBOX_INIT_ERROR;
65+
}
66+
#endif
67+
return PLATFORM_MAILBOX_SUCCESS;
68+
}
69+
70+
int32_t tfm_ns_mailbox_hal_init(struct ns_mailbox_queue_t *queue)
71+
{
72+
uint32_t stage;
73+
74+
if (!queue) {
75+
return MAILBOX_INVAL_PARAMS;
76+
}
77+
78+
/* Init semaphores used for critical sections */
79+
if (mailbox_sema_init() != PLATFORM_MAILBOX_SUCCESS)
80+
return MAILBOX_INIT_ERROR;
81+
82+
/*
83+
* FIXME
84+
* Further verification of mailbox queue address may be required according
85+
* to diverse NSPE implementations.
86+
*/
87+
88+
mailbox_ipc_init();
89+
90+
/*
91+
* Wait until SPE mailbox library is ready to receive NSPE mailbox queue
92+
* address.
93+
*/
94+
while (1) {
95+
platform_mailbox_wait_for_notify();
96+
97+
platform_mailbox_fetch_msg_data(&stage);
98+
if (stage == NS_MAILBOX_INIT_ENABLE) {
99+
break;
100+
}
101+
}
102+
103+
/* Send out the address */
104+
platform_mailbox_send_msg_ptr(queue);
105+
106+
/* Wait until SPE mailbox service is ready */
107+
while (1) {
108+
platform_mailbox_wait_for_notify();
109+
110+
platform_mailbox_fetch_msg_data(&stage);
111+
if (stage == S_MAILBOX_READY) {
112+
break;
113+
}
114+
}
115+
116+
mailbox_ipc_config();
117+
118+
return MAILBOX_SUCCESS;
119+
}
120+
121+
const void *tfm_ns_mailbox_get_task_handle(void)
122+
{
123+
return osThreadGetId();;
124+
}
125+
126+
void tfm_ns_mailbox_hal_wait_reply(mailbox_msg_handle_t handle)
127+
{
128+
osThreadFlagsWait(handle, osFlagsWaitAll, osWaitForever);
129+
}
130+
131+
static cy_en_ipcsema_status_t mailbox_raw_spin_lock(uint32_t ipc_channel,
132+
uint32_t sema_num)
133+
{
134+
uint32_t semaIndex;
135+
uint32_t semaMask;
136+
cy_stc_ipc_sema_t *semaStruct;
137+
cy_en_ipcdrv_status_t acqStatus;
138+
cy_en_ipcsema_status_t ret = CY_IPC_SEMA_BAD_PARAM;
139+
bool is_lock = false;
140+
IPC_STRUCT_Type *semaIpcStruct;
141+
142+
/* Get IPC register structure */
143+
semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipc_channel);
144+
/* Get pointer to structure */
145+
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(semaIpcStruct);
146+
147+
if (sema_num < semaStruct->maxSema) {
148+
semaIndex = sema_num / CY_IPC_SEMA_PER_WORD;
149+
semaMask = (uint32_t)(1ul << (sema_num - \
150+
(semaIndex * CY_IPC_SEMA_PER_WORD)));
151+
152+
while (!is_lock) {
153+
/* Check to make sure the IPC channel is released
154+
If so, check if specific channel can be locked. */
155+
do {
156+
acqStatus = Cy_IPC_Drv_LockAcquire(semaIpcStruct);
157+
} while (acqStatus != CY_IPC_DRV_SUCCESS);
158+
159+
if ((semaStruct->arrayPtr[semaIndex] & semaMask) == 0ul) {
160+
semaStruct->arrayPtr[semaIndex] |= semaMask;
161+
is_lock = true;
162+
}
163+
164+
/* Release, but do not trigger a release event */
165+
(void)Cy_IPC_Drv_LockRelease(semaIpcStruct,
166+
CY_IPC_NO_NOTIFICATION);
167+
168+
if (!is_lock) {
169+
/*
170+
* The secure core is occupying this lock. Insert a small delay
171+
* to give the secure core a chance to acquire the IPC channel
172+
* and release the lock.
173+
* Otherwise, the secure core may not be able to release the
174+
* lock if non-secure core has higher CPU frequency. It will
175+
* generate a deadlock.
176+
* This delay won't harm performance too much since non-secure
177+
* core has to busy wait here anyway.
178+
* Alternatively, non-secure core can wait for release
179+
* notification event from secure core. However, it is more
180+
* complex and requires more code and more modifications.
181+
*/
182+
volatile uint32_t count = 1000;
183+
while(count > 0) {
184+
count--;
185+
}
186+
Cy_IPC_Sema_Status(sema_num);
187+
}
188+
}
189+
190+
ret = CY_IPC_SEMA_SUCCESS;
191+
}
192+
193+
return ret;
194+
}
195+
196+
static cy_en_ipcsema_status_t mailbox_raw_spin_unlock(uint32_t ipc_channel,
197+
uint32_t sema_num)
198+
{
199+
uint32_t semaIndex;
200+
uint32_t semaMask;
201+
cy_stc_ipc_sema_t *semaStruct;
202+
cy_en_ipcdrv_status_t acqStatus;
203+
cy_en_ipcsema_status_t ret = CY_IPC_SEMA_BAD_PARAM;
204+
bool is_unlock = false;
205+
IPC_STRUCT_Type *semaIpcStruct;
206+
207+
/* Get IPC register structure */
208+
semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipc_channel);
209+
/* Get pointer to structure */
210+
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(semaIpcStruct);
211+
212+
if (sema_num < semaStruct->maxSema) {
213+
semaIndex = sema_num / CY_IPC_SEMA_PER_WORD;
214+
semaMask = (uint32_t)(1ul << (sema_num - \
215+
(semaIndex * CY_IPC_SEMA_PER_WORD)));
216+
217+
while (!is_unlock) {
218+
/* Check to make sure the IPC channel is released
219+
If so, check if specific channel can be locked. */
220+
do {
221+
acqStatus = Cy_IPC_Drv_LockAcquire(semaIpcStruct);
222+
} while (acqStatus != CY_IPC_DRV_SUCCESS);
223+
224+
if ((semaStruct->arrayPtr[semaIndex] & semaMask) != 0ul) {
225+
semaStruct->arrayPtr[semaIndex] &= ~semaMask;
226+
is_unlock = true;
227+
}
228+
229+
/* Release, but do not trigger a release event */
230+
(void)Cy_IPC_Drv_LockRelease(semaIpcStruct,
231+
CY_IPC_NO_NOTIFICATION);
232+
}
233+
234+
ret = CY_IPC_SEMA_SUCCESS;
235+
}
236+
237+
return ret;
238+
}
239+
240+
void tfm_ns_mailbox_hal_enter_critical(void)
241+
{
242+
saved_irq_state = Cy_SysLib_EnterCriticalSection();
243+
244+
mailbox_raw_spin_lock(CY_IPC_CHAN_SEMA, MAILBOX_SEMAPHORE_NUM);
245+
}
246+
247+
void tfm_ns_mailbox_hal_exit_critical(void)
248+
{
249+
mailbox_raw_spin_unlock(CY_IPC_CHAN_SEMA, MAILBOX_SEMAPHORE_NUM);
250+
251+
Cy_SysLib_ExitCriticalSection(saved_irq_state);
252+
}
253+
254+
void tfm_ns_mailbox_hal_enter_critical_isr(void)
255+
{
256+
mailbox_raw_spin_lock(CY_IPC_CHAN_SEMA, MAILBOX_SEMAPHORE_NUM);
257+
}
258+
259+
void tfm_ns_mailbox_hal_exit_critical_isr(void)
260+
{
261+
mailbox_raw_spin_unlock(CY_IPC_CHAN_SEMA, MAILBOX_SEMAPHORE_NUM);
262+
}
263+
264+
static bool mailbox_clear_intr(void)
265+
{
266+
uint32_t status;
267+
268+
status = Cy_IPC_Drv_GetInterruptStatusMasked(
269+
Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT));
270+
status >>= CY_IPC_NOTIFY_SHIFT;
271+
if ((status & IPC_RX_INT_MASK) == 0) {
272+
return false;
273+
}
274+
275+
Cy_IPC_Drv_ClearInterrupt(Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT),
276+
0, IPC_RX_INT_MASK);
277+
return true;
278+
}
279+
280+
void cpuss_interrupts_ipc_8_IRQHandler(void)
281+
{
282+
uint32_t magic;
283+
mailbox_msg_handle_t handle;
284+
osThreadId_t task_handle;
285+
286+
if (!mailbox_clear_intr())
287+
return;
288+
289+
platform_mailbox_fetch_msg_data(&magic);
290+
if (magic == PSA_CLIENT_CALL_REPLY_MAGIC) {
291+
/* Handle all the pending replies */
292+
while (1) {
293+
handle = tfm_ns_mailbox_fetch_reply_msg_isr();
294+
if (handle == MAILBOX_MSG_NULL_HANDLE) {
295+
break;
296+
}
297+
298+
task_handle = (osThreadId_t)tfm_ns_mailbox_get_msg_owner(handle);
299+
if (task_handle) {
300+
osThreadFlagsSet(task_handle, handle);
301+
}
302+
}
303+
}
304+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2019, Arm Limited. All rights reserved.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*
6+
*/
7+
8+
#include "tfm_api.h"
9+
#include "tfm_mailbox.h"
10+
#include "tfm_multi_core_api.h"
11+
#include "cmsis_os2.h"
12+
#include "mbed_rtos_storage.h"
13+
14+
#define MAX_SEMAPHORE_COUNT NUM_MAILBOX_QUEUE_SLOT
15+
16+
static void *ns_lock_handle = NULL;
17+
static mbed_rtos_storage_semaphore_t tfm_ns_sema_obj;
18+
19+
__attribute__((weak))
20+
enum tfm_status_e tfm_ns_interface_init(void)
21+
{
22+
osSemaphoreAttr_t sema_attrib = {
23+
.name = "tfm_ns_lock",
24+
.attr_bits = 0,
25+
.cb_size = sizeof(tfm_ns_sema_obj),
26+
.cb_mem = &tfm_ns_sema_obj
27+
};
28+
29+
ns_lock_handle = osSemaphoreNew(MAX_SEMAPHORE_COUNT,
30+
MAX_SEMAPHORE_COUNT,
31+
&sema_attrib);
32+
if (!ns_lock_handle) {
33+
return TFM_ERROR_GENERIC;
34+
}
35+
36+
return TFM_SUCCESS;
37+
}
38+
39+
int32_t tfm_ns_wait_for_s_cpu_ready(void)
40+
{
41+
return tfm_platform_ns_wait_for_s_cpu_ready();
42+
}
43+
44+
uint32_t tfm_ns_multi_core_lock_acquire(void)
45+
{
46+
return osSemaphoreAcquire(ns_lock_handle, osWaitForever);
47+
}
48+
49+
uint32_t tfm_ns_multi_core_lock_release(void)
50+
{
51+
return osSemaphoreRelease(ns_lock_handle);
52+
}

0 commit comments

Comments
 (0)