1 /*
2  * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
3  * Copyright (c) 2022-2023 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 "critical_section.h"
12 #include "ffm/psa_api.h"
13 #include "interrupt.h"
14 #include "spm.h"
15 #include "tfm_hal_interrupt.h"
16 
tfm_spm_partition_psa_irq_enable(psa_signal_t irq_signal)17 void tfm_spm_partition_psa_irq_enable(psa_signal_t irq_signal)
18 {
19     struct partition_t *partition;
20     const struct irq_load_info_t *irq_info;
21 
22     partition = GET_CURRENT_COMPONENT();
23 
24     irq_info = get_irq_info_for_signal(partition->p_ldinf, irq_signal);
25     if (!irq_info) {
26         tfm_core_panic();
27     }
28 
29     tfm_hal_irq_enable(irq_info->source);
30 }
31 
tfm_spm_partition_psa_irq_disable(psa_signal_t irq_signal)32 psa_irq_status_t tfm_spm_partition_psa_irq_disable(psa_signal_t irq_signal)
33 {
34     struct partition_t *partition;
35     const struct irq_load_info_t *irq_info;
36 
37     partition = GET_CURRENT_COMPONENT();
38 
39     irq_info = get_irq_info_for_signal(partition->p_ldinf, irq_signal);
40     if (!irq_info) {
41         tfm_core_panic();
42     }
43 
44     tfm_hal_irq_disable(irq_info->source);
45 
46     return 1;
47 }
48 
49 /* This API is only used for FLIH. */
50 #if CONFIG_TFM_FLIH_API == 1
tfm_spm_partition_psa_reset_signal(psa_signal_t irq_signal)51 void tfm_spm_partition_psa_reset_signal(psa_signal_t irq_signal)
52 {
53     struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
54     const struct irq_load_info_t *irq_info;
55     struct partition_t *partition;
56 
57     partition = GET_CURRENT_COMPONENT();
58 
59     irq_info = get_irq_info_for_signal(partition->p_ldinf, irq_signal);
60     if (!irq_info) {
61         tfm_core_panic();
62     }
63 
64     if (!irq_info->flih_func) {
65         /* This API is for FLIH IRQs only */
66         tfm_core_panic();
67     }
68 
69     if ((partition->signals_asserted & irq_signal) == 0) {
70         /* The signal is not asserted */
71         tfm_core_panic();
72     }
73 
74     CRITICAL_SECTION_ENTER(cs_assert);
75     partition->signals_asserted &= ~irq_signal;
76     CRITICAL_SECTION_LEAVE(cs_assert);
77 }
78 #endif /* CONFIG_TFM_FLIH_API == 1 */
79 
80 /* This API is only used for SLIH. */
81 #if CONFIG_TFM_SLIH_API == 1
tfm_spm_partition_psa_eoi(psa_signal_t irq_signal)82 void tfm_spm_partition_psa_eoi(psa_signal_t irq_signal)
83 {
84     struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
85     const struct irq_load_info_t *irq_info = NULL;
86     struct partition_t *partition = NULL;
87 
88     partition = GET_CURRENT_COMPONENT();
89 
90     irq_info = get_irq_info_for_signal(partition->p_ldinf, irq_signal);
91     /* It is a fatal error if passed signal is not an interrupt signal. */
92     if (!irq_info) {
93         tfm_core_panic();
94     }
95 
96     if (irq_info->flih_func) {
97         /* This API is for SLIH IRQs only */
98         tfm_core_panic();
99     }
100 
101     /* It is a fatal error if passed signal is not currently asserted */
102     if ((partition->signals_asserted & irq_signal) == 0) {
103         tfm_core_panic();
104     }
105 
106     CRITICAL_SECTION_ENTER(cs_assert);
107     partition->signals_asserted &= ~irq_signal;
108     CRITICAL_SECTION_LEAVE(cs_assert);
109 
110     tfm_hal_irq_clear_pending(irq_info->source);
111     tfm_hal_irq_enable(irq_info->source);
112 }
113 #endif /* CONFIG_TFM_SLIH_API == 1 */
114