1 /*
2 * Copyright (c) 2014, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * ======== Hwi.xdc ========
34 *
35 */
36 package ti.sysbios.hal;
37
38 import xdc.runtime.Error;
39
40 /*!
41 * ======== Hwi ========
42 * Hardware Interrupt Manager Proxy.
43 *
44 * This module provides APIs for managing hardware interrupts.
45 * These APIs are generic across all supported targets and devices
46 * and should provide sufficient functionality for most applications.
47 *
48 * The actual implementations of the Hwi module APIs are
49 * provided by the Hwi module delegates.
50 * Additional, family-specific Hwi module APIs may also be provided by
51 * the Hwi module delegates.
52 * See the list of
53 * {@link ./../family/doc-files/delegates.html Delegate Mappings}
54 * to determine which Hwi delegate is used
55 * for your target/device.
56 *
57 * You can statically or dynamically assign functions that run when
58 * specific hardware interrupts occur. Dynamic assignment of Hwi
59 * functions to interrupts at run-time is done
60 * using the {@link #create Hwi_create} function.
61 *
62 * Interrupt routines can be written completely in C, completely in
63 * assembly, or in a mix of C and assembly. In order to support interrupt
64 * routines
65 * written completely in C, an interrupt dispatcher is provided that performs
66 * the requisite prolog and epilog for an interrupt routine.
67 *
68 * Some routines are assigned to interrupts by the other SYS/BIOS
69 * modules. For example, the
70 * {@link ti.sysbios.knl.Clock} module configures its own timer interrupt
71 * handler.
72 *
73 * @a(constraints) 74 * Since the hal Hwi module has no knowledge of the delegate Hwi
75 * module's instance definition, Hwi_construct() can NOT be properly
76 * supported.
77 *
78 * If {@link ti.sysbios.BIOS#runtimeCreatesEnabled BIOS.runtimeCreatesEnabled}
79 * is set to true, both Hwi_create() and Hwi_construct()
80 * will attempt to dynamically create (ie NOT construct) a delegate Hwi
81 * object.
82 *
83 * If {@link ti.sysbios.BIOS#runtimeCreatesEnabled BIOS.runtimeCreatesEnabled}
84 * is set to false, both Hwi_create() and Hwi_construct() will fail.
85 *
86 * @p(html) 87 * <h3> Calling Context </h3>
88 * <table border="1" cellpadding="3">
89 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
90 * </colgroup>
91 *
92 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
93 * <th> Task </th><th> Main </th><th> Startup </th></tr>
94 * <!-- -->
95 * <tr><td> {@link #clearInterrupt} </td><td> Y </td><td> Y </td>
96 * <td> Y </td><td> Y </td><td> Y </td></tr>
97 * <tr><td> {@link #create} </td><td> N </td><td> N </td>
98 * <td> Y </td><td> Y </td><td> N </td></tr>
99 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td>
100 * <td> Y </td><td> Y </td><td> Y </td></tr>
101 * <tr><td> {@link #disableInterrupt} </td><td> Y </td><td> Y </td>
102 * <td> Y </td><td> Y </td><td> N </td></tr>
103 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td>
104 * <td> Y </td><td> N </td><td> N </td></tr>
105 * <tr><td> {@link #enableInterrupt} </td><td> Y </td><td> Y </td>
106 * <td> Y </td><td> Y </td><td> N </td></tr>
107 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td>
108 * <td> Y </td><td> Y </td><td> Y </td></tr>
109 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td>
110 * <td> Y </td><td> Y </td><td> Y </td></tr>
111 * <tr><td> {@link #restoreInterrupt} </td><td> Y </td><td> Y </td>
112 * <td> Y </td><td> Y </td><td> Y </td></tr>
113 * <tr><td> {@link #construct} </td><td> N </td><td> N </td>
114 * <td> Y </td><td> Y </td><td> N </td></tr>
115 * <tr><td> {@link #delete} </td><td> N </td><td> N </td>
116 * <td> Y </td><td> Y </td><td> N </td></tr>
117 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td>
118 * <td> Y </td><td> Y </td><td> N </td></tr>
119 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td>
120 * <td> Y </td><td> Y </td><td> N </td></tr>
121 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td>
122 * <td> Y </td><td> Y </td><td> N </td></tr>
123 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td>
124 * <td> Y </td><td> Y </td><td> N </td></tr>
125 * <tr><td colspan="6"> Definitions: <br />
126 * <ul>
127 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
128 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
129 * <li> <b>Task</b>: API is callable from a Task thread. </li>
130 * <li> <b>Main</b>: API is callable during any of these phases: </li>
131 * <ul>
132 * <li> In your module startup after this module is started
133 * (e.g. Hwi_Module_startupDone() returns TRUE). </li>
134 * <li> During xdc.runtime.Startup.lastFxns. </li>
135 * <li> During main().</li>
136 * <li> During BIOS.startupFxns.</li>
137 * </ul>
138 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
139 * <ul>
140 * <li> During xdc.runtime.Startup.firstFxns.</li>
141 * <li> In your module startup before this module is started
142 * (e.g. Hwi_Module_startupDone() returns FALSE).</li>
143 * </ul>
144 * </ul>
145 * </td></tr>
146 *
147 * </table>
148 * @p 149 *
150 * @a(Runtime Hwi Creation) 151 *
152 * Below is an example that configures an interrupt at runtime.
153 * Typically such code would be placed in main().
154 *
155 * @p(code) 156 * #include <xdc/runtime/Error.h>
157 * #include <ti/sysbios/hal/Hwi.h>
158 *
159 * Hwi_Handle myHwi;
160 *
161 * Int main(Int argc, char* argv[])
162 * {
163 * Hwi_Params hwiParams;
164 * Error_Block eb;
165 *
166 * Hwi_Params_init(&hwiParams);
167 * Error_init(&eb);
168 *
169 * // set the argument you want passed to your ISR function
170 * hwiParams.arg = 1;
171 *
172 * // set the event id of the peripheral assigned to this interrupt
173 * hwiParams.eventId = 10;
174 *
175 * // don't allow this interrupt to nest itself
176 * hwiParams.maskSetting = Hwi_MaskingOption_SELF;
177 *
178 * //
179 * // Configure interrupt 5 to invoke "myIsr".
180 * // Automatically enables interrupt 5 by default
181 * // set params.enableInt = FALSE if you want to control
182 * // when the interrupt is enabled using Hwi_enableInterrupt()
183 * //
184 *
185 * myHwi = Hwi_create(5, myIsr, &hwiParams, &eb);
186 *
187 * if (Error_check(&eb)) {
188 * // handle the error
189 * }
190 * }
191 *
192 * Void myIsr(UArg arg)
193 * {
194 * // this runs when interrupt #5 goes off
195 * }
196 * @p 197 *
198 * @a(Hook Functions) 199 *
200 * Sets of hook functions can be specified for the Hwi module
201 * using the configuration tool. Each set contains these hook
202 * functions:
203 * @p(blist) 204 * -Register: A function called before any statically-created Hwis
205 * are initialized at runtime. The register hook is called at boot time
206 * before main() and before interrupts are enabled.
207 * -Create: A function that is called when a Hwi is created.
208 * This includes hwis that are created statically and those
209 * created dynamically using {@link #create Hwi_create}.
210 * -Begin: A function that is called just prior to running a Hwi.
211 * -End: A function that is called just after a Hwi finishes.
212 * -Delete: A function that is called when a Hwi is deleted at
213 * run-time with {@link #delete Hwi_delete}.
214 * @p 215 *
216 * Register Function
217 *
218 * The Register function is provided to allow a hook set to store its
219 * hookset ID. This id can be passed to
220 * {@link #setHookContext Hwi_setHookContext} and
221 * {@link #getHookContext Hwi_getHookContext} to set or get
222 * hookset-specific context. The
223 * Register function must be specified if the hook implementation
224 * needs to use {@link #setHookContext Hwi_setHookContext} or
225 * {@link #getHookContext Hwi_getHookContext}.
226 * The registerFxn hook function is called during system initialization
227 * before interrupts have been enabled.
228 *
229 * @p(code) 230 * Void myRegisterFxn(Int id);
231 * @p 232 *
233 * Create and Delete Functions
234 *
235 * The create and delete functions are called whenever a Hwi is created
236 * or deleted. They are called with interrupts enabled (unless called
237 * at boot time or from main()).
238 *
239 * @p(code) 240 * Void myCreateFxn(Hwi_Handle hwi, Error_Block *eb);
241 * @p 242 *
243 * @p(code) 244 * Void myDeleteFxn(Hwi_Handle hwi);
245 * @p 246 *
247 * Begin and End Functions
248 *
249 * The beginFxn and endFxn function hooks are called with interrupts
250 * globally disabled, therefore any hook processing function will contribute
251 * to the overall system interrupt response latency. In order to minimize
252 * this impact, carefully consider the processing time spent in an Hwi
253 * beginFxn or endFxn function hook.
254 *
255 * @p(code) 256 * Void myBeginFxn(Hwi_Handle hwi);
257 * @p 258 *
259 * @p(code) 260 * Void myEndFxn(Hwi_Handle hwi);
261 * @p 262 *
263 * Hook functions can only be configured statically.
264 *
265 */
266
267 @ModuleStartup /* generate a call to startup function */
268
269 module Hwi inherits ti.sysbios.interfaces.IHwi
270 {
271 /*!
272 * Error raised when a stack overflow (or corruption) is detected.
273 *
274 * This error is raised by kernel's stack checking function. This
275 * function checks the stacks before every task switch to make sure
276 * that reserved word at top of stack has not been modified.
277 *
278 * The stack checking logic is enabled by the {@link #initStackFlag} and
279 * {@link #checkStackFlag} configuration parameters. If both of these
280 * flags are set to true, the kernel will validate the stacks.
281 */
282 config Error.Id E_stackOverflow = {
283 msg: "E_stackOverflow: ISR stack overflow."
284 };
285
286 /*!
287 * Initialize ISR stack with known value for stack checking at runtime
288 *
289 * This is also useful for inspection of stack in debugger or core
290 * dump utilities.
291 *
292 * Default is true.
293 * (see {@link #checkStackFlag}).
294 */
295 metaonlyconfig Bool initStackFlag = true;
296
297 /*!
298 * Check for Hwi stack overrun during Idle loop.
299 *
300 * If true, then an idle function is added to the idle loop
301 * that checks for a Hwi stack overrun condition and raises
302 * an Error if one is detected.
303 *
304 * The check consists of testing the top of stack value against
305 * its initial value (see {@link #initStackFlag}). If it is no
306 * longer at this value, the assumption is that the ISR stack
307 * has been overrun. If the test fails, then the
308 * {@link #E_stackOverflow} error is raised.
309 *
310 * Runtime stack checking is only performed if {@link #initStackFlag} is
311 * also true.
312 *
313 * Default is true.
314 * (see {@link #initStackFlag}).
315 *
316 * To enable or disable full stack checking, you should set both this
317 * flag and the {@link ti.sysbios.knl.Task#checkStackFlag}.
318 */
319 metaonlyconfig Bool checkStackFlag = true;
320
321 /*!
322 * ======== disable ========
323 */
324 @Macro
325 override UInt disable();
326
327 /*!
328 * ======== enable ========
329 */
330 @Macro
331 override UInt enable();
332
333 /*!
334 * ======== restore ========
335 */
336 @Macro
337 override Void restore(UInt key);
338
339 /*!
340 * ======== viewGetHandle ========
341 * @_nodoc 342 * Returns the corresponding hal Hwi handle for a delegate Hwi handle
343 *
344 * @b(returns) hal Hwi handle
345 */
346 metaonly Handle viewGetHandle(Ptr pi);
347
348 instance:
349
350 /*!
351 * ======== create ========
352 * Create a dispatched interrupt.
353 *
354 * To cause a C function to run in response to a particular system
355 * interrupt, you create a Hwi object that encapsulates information
356 * regarding the interrupt required by the Hwi module.
357 *
358 * The standard static and dynamic forms of the "create" function are
359 * supported by the ti.sysbios.hal.Hwi module.
360 * The following C code configures interrupt 5 with the "myIsr"
361 * C function.
362 *
363 * @p(code) 364 * #include <ti/sysbios/hal/Hwi>
365 *
366 * Hwi_create(5, myIsr, NULL, NULL);
367 * @p 368 *
369 * The NULL, NULL arguments are used when the default instance
370 * parameters and generic error handling is satisfactory for creating
371 * a Hwi object.
372 *
373 * A Hwi dispatcher table entry is created and filled with the
374 * function specified by the fxn parameter and the attributes
375 * specified by the params parameter.
376 *
377 * If params is NULL, the Hwi's dispatcher properties are assigned a
378 * default set of values. Otherwise, the following properties
379 * are specified by a structure of type Hwi_Params.
380 *
381 * @p(blist) 382 * - The arg element is a generic argument that is passed to the plugged
383 * function as its only parameter. The default value is 0.
384 * - The enableInt element determines whether the interrupt should be
385 * enabled in the IER by create.
386 * - The maskSetting element defines the dispatcherAutoNestingSupport
387 * behavior of the interrupt.
388 * @p 389 *
390 * Hwi_create returns a pointer to the created Hwi object.
391 *
392 * @param(intNum) interrupt number
393 * @param(hwiFxn) pointer to ISR function
394 */
395 override create(Int intNum, FuncPtr hwiFxn);
396
397 /*!
398 * ======== getHookContext ========
399 * Get hook instance's context for a Hwi.
400 *
401 * The Handle passed to this API must be the handle passed
402 * to any of the Hook functions, not the one returned by
403 * {@link #create Hwi_create}.
404 *
405 * @b(returns) hook instance's context for hwi
406 */
407 override Ptr getHookContext(Int id);
408
409 /*!
410 * ======== setHookContext ========
411 * Set hook instance's context for a Hwi.
412 *
413 * The Handle passed to this API must be the handle passed
414 * to any of the Hook functions, not the one returned by
415 * {@link #create Hwi_create}.
416 *
417 * @param(id) hook instance's ID
418 * @param(hookContext) value to write to context
419 */
420 override Void setHookContext(Int id, Ptr hookContext);
421
422 internal: /* not for client use */
423
424 /* keep track of the number of hooks defined */
425 metaonlyconfig UInt numHooks = 0;
426
427 /*! target/device-specific Hwi implementation. */
428 proxy HwiProxy inherits ti.sysbios.interfaces.IHwi;
429
430 struct Instance_State {
431 HwiProxy.Handle pi;
432 };
433 }