1 /*
2 * Copyright (c) 2021-2024, 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 "internal_status_code.h"
12 #include "tfm_hal_device_header.h"
13 #include "device_definition.h"
14 #include "spm.h"
15 #include "tfm_hal_interrupt.h"
16 #include "tfm_peripherals_def.h"
17 #include "tfm_multi_core.h"
18 #include "interrupt.h"
19 #include "load/interrupt_defs.h"
20 #include "platform_irq.h"
21 #ifdef TFM_MULTI_CORE_TOPOLOGY
22 #include "rse_comms_hal.h"
23 #endif
24
25 static struct irq_t timer0_irq = {0};
26
TFM_TIMER0_IRQ_Handler(void)27 void TFM_TIMER0_IRQ_Handler(void)
28 {
29 spm_handle_interrupt(timer0_irq.p_pt, timer0_irq.p_ildi);
30 }
31
tfm_timer0_irq_init(void * p_pt,const struct irq_load_info_t * p_ildi)32 enum tfm_hal_status_t tfm_timer0_irq_init(void *p_pt,
33 const struct irq_load_info_t *p_ildi)
34 {
35 timer0_irq.p_ildi = p_ildi;
36 timer0_irq.p_pt = p_pt;
37
38 NVIC_SetPriority(TFM_TIMER0_IRQ, DEFAULT_IRQ_PRIORITY);
39 NVIC_ClearTargetState(TFM_TIMER0_IRQ);
40 NVIC_DisableIRQ(TFM_TIMER0_IRQ);
41
42 return TFM_HAL_SUCCESS;
43 }
44
45 #ifdef TFM_MULTI_CORE_TOPOLOGY
46 static struct irq_t mbox_irq_info[2] = {0};
47
48 /* Platform specific inter-processor communication interrupt handler. */
CMU_MHU0_Receiver_Handler(void)49 void CMU_MHU0_Receiver_Handler(void)
50 {
51 (void)tfm_multi_core_hal_receive(&MHU_AP_MONITOR_TO_RSE_DEV,
52 &MHU_RSE_TO_AP_MONITOR_DEV,
53 mbox_irq_info[0].p_ildi->source);
54
55 /*
56 * SPM will send a MAILBOX_INTERRUPT_SIGNAL to the corresponding partition
57 * indicating that a message has arrived and can be processed.
58 */
59 spm_handle_interrupt(mbox_irq_info[0].p_pt, mbox_irq_info[0].p_ildi);
60 }
61
62 #ifdef MHU_AP_NS_TO_RSE
63 /* Platform specific inter-processor communication interrupt handler. */
CMU_MHU1_Receiver_Handler(void)64 void CMU_MHU1_Receiver_Handler(void)
65 {
66 (void)tfm_multi_core_hal_receive(&MHU_AP_NS_TO_RSE_DEV,
67 &MHU_RSE_TO_AP_NS_DEV,
68 mbox_irq_info[1].p_ildi->source);
69
70 /*
71 * SPM will send a MAILBOX_INTERRUPT_SIGNAL to the corresponding partition
72 * indicating that a message has arrived and can be processed.
73 */
74 spm_handle_interrupt(mbox_irq_info[1].p_pt, mbox_irq_info[1].p_ildi);
75 }
76 #endif /* MHU_AP_NS_TO_RSE */
77
mailbox_irq_init(void * p_pt,const struct irq_load_info_t * p_ildi)78 enum tfm_hal_status_t mailbox_irq_init(void *p_pt,
79 const struct irq_load_info_t *p_ildi)
80 {
81 mbox_irq_info[0].p_pt = p_pt;
82 mbox_irq_info[0].p_ildi = p_ildi;
83
84 /* Set MHU interrupt priority to the same as PendSV (the lowest)
85 * TODO: Consider advantages/disadvantages of setting it one higher
86 */
87 NVIC_SetPriority(CMU_MHU0_Receiver_IRQn, NVIC_GetPriority(PendSV_IRQn));
88
89 /* CMU_MHU0 is a secure peripheral, so its IRQs have to target S state */
90 NVIC_ClearTargetState(CMU_MHU0_Receiver_IRQn);
91 NVIC_DisableIRQ(CMU_MHU0_Receiver_IRQn);
92
93 if (tfm_multi_core_register_client_id_range(&MHU_RSE_TO_AP_MONITOR_DEV,
94 p_ildi->client_id_base,
95 p_ildi->client_id_limit)
96 != SPM_SUCCESS) {
97 return TFM_HAL_ERROR_INVALID_INPUT;
98 }
99 return TFM_HAL_SUCCESS;
100 }
101
102 #ifdef MHU_AP_NS_TO_RSE
mailbox_irq_1_init(void * p_pt,const struct irq_load_info_t * p_ildi)103 enum tfm_hal_status_t mailbox_irq_1_init(void *p_pt,
104 const struct irq_load_info_t *p_ildi)
105 {
106 mbox_irq_info[1].p_pt = p_pt;
107 mbox_irq_info[1].p_ildi = p_ildi;
108
109 /* Set MHU interrupt priority to the same as PendSV (the lowest)
110 * TODO: Consider advantages/disadvantages of setting it one higher
111 */
112 NVIC_SetPriority(CMU_MHU1_Receiver_IRQn, NVIC_GetPriority(PendSV_IRQn));
113
114 /* CMU_MHU1 is a secure peripheral, so its IRQs have to target S state */
115 NVIC_ClearTargetState(CMU_MHU1_Receiver_IRQn);
116 NVIC_DisableIRQ(CMU_MHU1_Receiver_IRQn);
117
118 if (tfm_multi_core_register_client_id_range(&MHU_RSE_TO_AP_NS_DEV,
119 p_ildi->client_id_base,
120 p_ildi->client_id_limit)
121 != SPM_SUCCESS) {
122 return TFM_HAL_ERROR_INVALID_INPUT;
123 }
124 return TFM_HAL_SUCCESS;
125 }
126 #else /* MHU_AP_NS_TO_RSE */
mailbox_irq_1_init(void * p_pt,const struct irq_load_info_t * p_ildi)127 enum tfm_hal_status_t mailbox_irq_1_init(void *p_pt,
128 const struct irq_load_info_t *p_ildi)
129 {
130 (void)p_pt;
131 (void)p_ildi;
132
133 return TFM_HAL_ERROR_NOT_SUPPORTED;
134 }
135 #endif /* MHU_AP_NS_TO_RSE */
136 #endif /* TFM_MULTI_CORE_TOPOLOGY */
137
138 static struct irq_t dma0_ch0_irq = {0};
139
DMA_Combined_S_Handler(void)140 void DMA_Combined_S_Handler(void)
141 {
142 spm_handle_interrupt(dma0_ch0_irq.p_pt, dma0_ch0_irq.p_ildi);
143 }
144
tfm_dma0_combined_s_irq_init(void * p_pt,struct irq_load_info_t * p_ildi)145 enum tfm_hal_status_t tfm_dma0_combined_s_irq_init(void *p_pt,
146 struct irq_load_info_t *p_ildi)
147 {
148 dma0_ch0_irq.p_ildi = p_ildi;
149 dma0_ch0_irq.p_pt = p_pt;
150
151 NVIC_SetPriority(TFM_DMA0_COMBINED_S_IRQ, DEFAULT_IRQ_PRIORITY);
152 NVIC_ClearTargetState(TFM_DMA0_COMBINED_S_IRQ);
153 NVIC_DisableIRQ(TFM_DMA0_COMBINED_S_IRQ);
154
155 return TFM_HAL_SUCCESS;
156 }
157