1 /*
2  * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
3  * Copyright (c) 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 "cmsis.h"
12 #include "spm_ipc.h"
13 #include "tfm_hal_interrupt.h"
14 #include "tfm_peripherals_def.h"
15 #include "ffm/interrupt.h"
16 #include "load/interrupt_defs.h"
17 #include "platform_irq.h"
18 #ifdef TFM_MULTI_CORE_TOPOLOGY
19 #include "rss_comms_hal.h"
20 #endif
21 
22 static struct irq_t timer0_irq = {0};
23 
TFM_TIMER0_IRQ_Handler(void)24 void TFM_TIMER0_IRQ_Handler(void)
25 {
26     spm_handle_interrupt(timer0_irq.p_pt, timer0_irq.p_ildi);
27 }
28 
tfm_timer0_irq_init(void * p_pt,const struct irq_load_info_t * p_ildi)29 enum tfm_hal_status_t tfm_timer0_irq_init(void *p_pt,
30                                           const struct irq_load_info_t *p_ildi)
31 {
32     timer0_irq.p_ildi = p_ildi;
33     timer0_irq.p_pt = p_pt;
34 
35     NVIC_SetPriority(TFM_TIMER0_IRQ, DEFAULT_IRQ_PRIORITY);
36     NVIC_ClearTargetState(TFM_TIMER0_IRQ);
37     NVIC_DisableIRQ(TFM_TIMER0_IRQ);
38 
39     return TFM_HAL_SUCCESS;
40 }
41 
42 #ifdef TFM_MULTI_CORE_TOPOLOGY
43 static struct irq_t mbox_irq_info = {0};
44 
45 /* Platform specific inter-processor communication interrupt handler. */
CMU_MHU0_Receiver_Handler(void)46 void CMU_MHU0_Receiver_Handler(void)
47 {
48     (void)tfm_multi_core_hal_receive();
49 
50     /*
51      * SPM will send a MAILBOX_SIGNAL to the corresponding partition
52      * indicating that a message has arrived and can be processed.
53      */
54     spm_handle_interrupt(mbox_irq_info.p_pt, mbox_irq_info.p_ildi);
55 }
56 
mailbox_irq_init(void * p_pt,const struct irq_load_info_t * p_ildi)57 enum tfm_hal_status_t mailbox_irq_init(void *p_pt,
58                                        const struct irq_load_info_t *p_ildi)
59 {
60     mbox_irq_info.p_pt = p_pt;
61     mbox_irq_info.p_ildi = p_ildi;
62 
63     /* Set MHU interrupt priority to the same as PendSV (the lowest)
64      * TODO: Consider advantages/disadvantages of setting it one higher
65      */
66     NVIC_SetPriority(CMU_MHU0_Receiver_IRQn, NVIC_GetPriority(PendSV_IRQn));
67 
68     /* CMU_MHU0 is a secure peripheral, so its IRQs have to target S state */
69     NVIC_ClearTargetState(CMU_MHU0_Receiver_IRQn);
70     NVIC_DisableIRQ(CMU_MHU0_Receiver_IRQn);
71 
72     return TFM_HAL_SUCCESS;
73 }
74 #endif /* TFM_MULTI_CORE_TOPOLOGY */
75 
76 static struct irq_t dma0_ch0_irq = {0};
77 
DMA_Combined_S_Handler(void)78 void DMA_Combined_S_Handler(void)
79 {
80     spm_handle_interrupt(dma0_ch0_irq.p_pt, dma0_ch0_irq.p_ildi);
81 }
82 
tfm_dma0_combined_s_irq_init(void * p_pt,struct irq_load_info_t * p_ildi)83 enum tfm_hal_status_t tfm_dma0_combined_s_irq_init(void *p_pt,
84                                           struct irq_load_info_t *p_ildi)
85 {
86     dma0_ch0_irq.p_ildi = p_ildi;
87     dma0_ch0_irq.p_pt = p_pt;
88 
89     NVIC_SetPriority(TFM_DMA0_COMBINED_S_IRQ, DEFAULT_IRQ_PRIORITY);
90     NVIC_ClearTargetState(TFM_DMA0_COMBINED_S_IRQ);
91     NVIC_DisableIRQ(TFM_DMA0_COMBINED_S_IRQ);
92 
93     return TFM_HAL_SUCCESS;
94 }
95