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