1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Description:
8  *     Framework API for the architecture layer.
9  */
10 
11 #ifndef FWK_ARCH_H
12 #define FWK_ARCH_H
13 
14 #include <stdbool.h>
15 #include <stddef.h>
16 #include <stdint.h>
17 
18 /*!
19  * \addtogroup GroupLibFramework Framework
20  * \{
21  */
22 
23 /*!
24  * \defgroup GroupArch Architecture Interface
25  * \{
26  */
27 
28 /*!
29  * \brief Interrupt driver interface.
30  *
31  * \details The interrupt driver interface allows the framework to provide
32  *      architecture-specific handling of the system interrupts.
33  */
34 struct fwk_arch_interrupt_driver {
35     /*!
36      * \brief Enable interrupts.
37      *
38      * \retval ::FWK_SUCCESS Operation succeeded.
39      */
40     int (*global_enable)(void);
41 
42     /*!
43      * \brief Disable interrupts.
44      *
45      * \retval ::FWK_SUCCESS Operation succeeded.
46      */
47     int (*global_disable)(void);
48 
49     /*!
50      * \brief Test whether an interrupt is enabled.
51      *
52      * \param interrupt Interrupt number.
53      * \param [out] enabled \c true if the interrupt is enabled, else \c false.
54      *
55      * \retval ::FWK_SUCCESS Operation succeeded.
56      * \retval ::FWK_E_PARAM One or more parameters were invalid.
57      */
58     int (*is_enabled)(unsigned int interrupt, bool *enabled);
59 
60     /*!
61      * \brief Enable an interrupt.
62      *
63      * \param interrupt Interrupt number.
64      *
65      * \retval ::FWK_SUCCESS Operation succeeded.
66      * \retval ::FWK_E_PARAM One or more parameters were invalid.
67      */
68     int (*enable)(unsigned int interrupt);
69 
70     /*!
71      * \brief Disable an interrupt.
72      *
73      * \param interrupt Interrupt number.
74      *
75      * \retval ::FWK_SUCCESS Operation succeeded.
76      * \retval ::FWK_E_PARAM One or more parameters were invalid.
77      */
78     int (*disable)(unsigned int interrupt);
79 
80     /*!
81      * \brief Check if an interrupt is pending.
82      *
83      * \param interrupt Interrupt number.
84      * \param [out] pending \c true if the interrupt is pending, else \c false.
85      *
86      * \retval ::FWK_SUCCESS Operation succeeded.
87      * \retval ::FWK_E_PARAM One or more parameters were invalid.
88      */
89     int (*is_pending)(unsigned int interrupt, bool *pending);
90 
91     /*!
92      * \brief Set an interrupt as pending.
93      *
94      * \param interrupt Interrupt number.
95      *
96      * \retval ::FWK_SUCCESS Operation succeeded.
97      * \retval ::FWK_E_PARAM One or more parameters were invalid.
98      */
99     int (*set_pending)(unsigned int interrupt);
100 
101     /*!
102      * \brief Clear a pending interrupt.
103      *
104      * \param interrupt Interrupt number.
105      *
106      * \retval ::FWK_SUCCESS Operation succeeded.
107      * \retval ::FWK_E_PARAM One or more parameters were invalid.
108      */
109     int (*clear_pending)(unsigned int interrupt);
110 
111     /*!
112      * \brief Set an IRQ interrupt service routine.
113      *
114      * \param interrupt Interrupt number.
115      * \param isr Pointer to the interrupt service routine function.
116      *
117      * \retval ::FWK_SUCCESS Operation succeeded.
118      * \retval ::FWK_E_PARAM One or more parameters were invalid.
119      */
120     int (*set_isr_irq)(unsigned int interrupt, void (*isr)(void));
121 
122     /*!
123      * \brief Set an IRQ interrupt service routine that should receive a
124      *     parameter.
125      *
126      * \param interrupt Interrupt number.
127      * \param isr Pointer to the interrupt service routine function.
128      * \param parameter Parameter that should be passed to the isr function.
129      *
130      * \retval ::FWK_SUCCESS Operation succeeded.
131      * \retval ::FWK_E_PARAM One or more parameters were invalid.
132      */
133     int (*set_isr_irq_param)(unsigned int interrupt,
134                              void (*isr)(uintptr_t param),
135                              uintptr_t parameter);
136 
137     /*!
138      * \brief Set the interrupt service routine for the non-maskable interrupt
139      *      (NMI).
140      *
141      * \param isr Pointer to the NMI interrupt service routine function.
142      *
143      * \retval ::FWK_SUCCESS Operation succeeded.
144      * \retval ::FWK_E_PARAM One or more parameters were invalid.
145      */
146     int (*set_isr_nmi)(void (*isr)(void));
147 
148     /*!
149      * \brief Set the interrupt service routine for the non-maskable interrupt
150      *      (NMI) that should receive a parameter.
151      *
152      * \param isr Pointer to the NMI interrupt service routine function.
153      * \param parameter Parameter that should be passed to the isr function.
154      *
155      * \retval ::FWK_SUCCESS Operation succeeded.
156      * \retval ::FWK_E_PARAM One or more parameters were invalid.
157      */
158     int (*set_isr_nmi_param)(void (*isr)(uintptr_t param), uintptr_t parameter);
159 
160     /*!
161      * \brief Set the fault interrupt service routine.
162      *
163      * \param isr Pointer to the fault interrupt service routine function.
164      *
165      * \retval ::FWK_SUCCESS Operation succeeded.
166      * \retval ::FWK_E_PARAM One or more parameters were invalid.
167      */
168     int (*set_isr_fault)(void (*isr)(void));
169 
170     /*!
171      * \brief Get the interrupt number for the current interrupt service routine
172      *      being processed.
173      *
174      * \param [out] interrupt Interrupt number.
175      *
176      * \retval ::FWK_SUCCESS Operation succeeded.
177      * \retval ::FWK_E_PARAM One or more parameters were invalid.
178      * \retval ::FWK_E_STATE An interrupt is not currently being serviced.
179      */
180     int (*get_current)(unsigned int *interrupt);
181 
182     /*!
183      * \brief Check if in interrupt context.
184      *
185      * \retval :: \c true if in an interrupt context.
186      * \retval :: \c false not in an interrupt context.
187      */
188     bool (*is_interrupt_context)(void);
189 };
190 
191 /*!
192  * \brief Initialization driver interface.
193  *
194  * \details The initialization driver interface allows the framework to request
195  *      low-level (architecture-specific) initialization.
196  */
197 struct fwk_arch_init_driver {
198     /*!
199      * \brief Interrupt driver initialization.
200      *
201      * \details This handler is used by the framework library to request the
202      *      interrupt driver.
203      *
204      * \param [out] driver Pointer to an interrupt driver.
205      *
206      * \retval ::FWK_SUCCESS Operation succeeded.
207      * \retval ::FWK_E_PARAM The parameter received by the handler is invalid.
208      * \retval ::FWK_E_PANIC Unrecoverable initialization error.
209      */
210     int (*interrupt)(const struct fwk_arch_interrupt_driver **driver);
211 };
212 
213 /*!
214  * \brief Initialize the framework library.
215  *
216  * \param driver Pointer to an initialization driver used to perform the
217  *      initialization.
218  *
219  * \retval ::FWK_SUCCESS Operation succeeded.
220  * \retval ::FWK_E_PARAM One or more parameters were invalid.
221  * \retval ::FWK_E_PANIC Unrecoverable initialization error.
222  */
223 int fwk_arch_init(const struct fwk_arch_init_driver *driver);
224 
225 /*!
226  * \brief Stop the framework library.
227  *
228  * \details Before terminating the SCP-firmware, the modules and their elements
229  * get the opportunity to release or reset some resources.
230  *
231  * \retval ::FWK_SUCCESS Operation succeeded.
232  * \retval ::FWK_E_PANIC Unrecoverable error.
233  */
234 int fwk_arch_deinit(void);
235 
236 /*!
237  * \brief Architecture defined suspend, will wakup on receiving interrupt
238  *
239  */
240 void fwk_arch_suspend(void);
241 
242 /*!
243  * \}
244  */
245 
246 /*!
247  * \}
248  */
249 
250 #endif /* FWK_ARCH_H */
251