1 /*
2  * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
3  * Copyright (c) 2021-2022 Cypress Semiconductor Corporation (an Infineon
4  * company) or an affiliate of Cypress Semiconductor Corporation. All rights
5  * reserved.
6  *
7  * SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 #include <stdint.h>
12 
13 #include "tfm_hal_device_header.h"
14 #include "cy_ipc_drv.h"
15 #include "spe_ipc_config.h"
16 #include "spm.h"
17 #include "tfm_hal_interrupt.h"
18 #include "tfm_multi_core.h"
19 #include "tfm_peripherals_def.h"
20 #include "interrupt.h"
21 #include "load/interrupt_defs.h"
22 #include "mailbox/platform_multicore.h"
23 
24 static struct irq_t timer0_irq = {0};
25 
TFM_TIMER0_IRQ_Handler(void)26 void TFM_TIMER0_IRQ_Handler(void)
27 {
28     spm_handle_interrupt(timer0_irq.p_pt, timer0_irq.p_ildi);
29 }
30 
tfm_timer0_irq_init(void * p_pt,const struct irq_load_info_t * p_ildi)31 enum tfm_hal_status_t tfm_timer0_irq_init(void *p_pt,
32                                           const struct irq_load_info_t *p_ildi)
33 {
34     timer0_irq.p_ildi = p_ildi;
35     timer0_irq.p_pt = p_pt;
36 
37     NVIC_SetPriority(TFM_TIMER0_IRQ, DEFAULT_IRQ_PRIORITY);
38     NVIC_DisableIRQ(TFM_TIMER0_IRQ);
39 
40     return TFM_HAL_SUCCESS;
41 }
42 
43 static struct irq_t mbox_irq_info = {0};
44 
mailbox_clear_intr(void)45 static void mailbox_clear_intr(void)
46 {
47     uint32_t status;
48 
49     status = Cy_IPC_Drv_GetInterruptStatusMasked(
50                             Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT));
51     status >>= CY_IPC_NOTIFY_SHIFT;
52     if ((status & IPC_RX_INT_MASK) == 0) {
53         return;
54     }
55 
56     Cy_IPC_Drv_ClearInterrupt(Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT),
57                               0, IPC_RX_INT_MASK);
58 }
59 
tfm_mailbox_irq_handler(void)60 void tfm_mailbox_irq_handler(void)
61 {
62     uint32_t magic;
63 
64     mailbox_clear_intr();
65 
66     /* Read from mailbox */
67     platform_mailbox_fetch_msg_data(&magic);
68     if (magic == PSA_CLIENT_CALL_REQ_MAGIC) {
69         spm_handle_interrupt(mbox_irq_info.p_pt, mbox_irq_info.p_ildi);
70     }
71 }
72 
mailbox_irq_init(void * p_pt,const struct irq_load_info_t * p_ildi)73 enum tfm_hal_status_t mailbox_irq_init(void *p_pt,
74                                        const struct irq_load_info_t *p_ildi)
75 {
76     mbox_irq_info.p_pt = p_pt;
77     mbox_irq_info.p_ildi = p_ildi;
78 
79     NVIC_SetPriority(NvicMux7_IRQn, DEFAULT_IRQ_PRIORITY);
80     NVIC_DisableIRQ(NvicMux7_IRQn);
81 
82     if (tfm_multi_core_register_client_id_range(CLIENT_ID_OWNER_MAGIC,
83                                                 p_ildi->client_id_base,
84                                                 p_ildi->client_id_limit) != 0) {
85         return TFM_HAL_ERROR_INVALID_INPUT;
86     }
87     return TFM_HAL_SUCCESS;
88 }
89 #ifdef PSA_API_TEST_IPC
90 
91 static struct irq_t ff_test_uart_irq;
92 
FF_TEST_UART_IRQ_Handler(void)93 void FF_TEST_UART_IRQ_Handler(void)
94 {
95     spm_handle_interrupt(ff_test_uart_irq.p_pt, ff_test_uart_irq.p_ildi);
96 }
97 
ff_test_uart_irq_init(void * p_pt,const struct irq_load_info_t * p_ildi)98 enum tfm_hal_status_t ff_test_uart_irq_init(void *p_pt,
99                                             const struct irq_load_info_t *p_ildi)
100 {
101     ff_test_uart_irq.p_ildi = p_ildi;
102     ff_test_uart_irq.p_pt = p_pt;
103 
104     NVIC_SetPriority(FF_TEST_UART_IRQ, DEFAULT_IRQ_PRIORITY);
105     NVIC_ClearTargetState(FF_TEST_UART_IRQ);
106     NVIC_DisableIRQ(FF_TEST_UART_IRQ);
107 
108     return TFM_HAL_SUCCESS;
109 }
110 
111 #endif
112