define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / rom / exec / cause.c
blob677e75a5225f544716927e2201734d6c3e5f3801
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Cause() - Cause a software interrupt.
6 Lang: english
7 */
9 #include <exec/execbase.h>
10 #include <aros/asmcall.h>
11 #include <hardware/custom.h>
13 /* Change this to <exec_intern.h> if you move this file... */
14 #include "exec_intern.h"
16 /*****************************************************************************
18 NAME */
19 #include <exec/interrupts.h>
20 #include <proto/exec.h>
22 AROS_LH1(void, Cause,
24 /* SYNOPSIS */
25 AROS_LHA(struct Interrupt *, softint, A1),
27 /* LOCATION */
28 struct ExecBase *, SysBase, 30, Exec)
30 /* FUNCTION
31 Schedule a software interrupt to occur. If the processor is
32 currently running a user task, then the software interrupt will
33 prempt the current task and run itself. From a real interrupt, it
34 will queue the software interrupt for a later time.
36 Software interrupts are useful from hardware interrupts if you
37 wish to defer your processing down to a lower level. They can
38 also be used in some special cases of device I/O. The timer.device
39 and audio.device allow software interrupt driven timing and
40 audio output respectively.
42 Software interrupts are restricted to 5 different priority levels,
43 +32, +16, 0, -16, -32.
45 Software interrupts can only be scheduled once.
47 The software interrupt is called with the following prototype:
49 AROS_UFH3(void, YourIntCode,
50 AROS_UFHA(APTR, interruptData, A1),
51 AROS_UFHA(APTR, interruptCode, A5),
52 AROS_UFHA(struct ExecBase *, SysBase, A6))
54 The interruptData is the value of the is_Data field, interruptCode
55 is the value of the is_Code field - it is included for historical
56 and compatibility reasons. You can ignore the value of interruptCode,
57 but you must declare it.
59 INPUTS
60 softint - The interrupt you wish to schedule. When setting up
61 you should set the type of the interrupt to either
62 NT_INTERRUPT or NT_UNKNOWN.
64 RESULT
65 The software interrupt will be delivered, or queued for later
66 delivery.
68 NOTES
69 No bounds checking on the software interrupt priority is done.
70 Passing a bad priority to the system can have a strange effect.
72 EXAMPLE
74 BUGS
75 Older versions of the Amiga operating system require that the
76 software interrupts preserve the A6 register.
78 Software interrupts which are added from a software interrupt of
79 lower priority may not be called immediately.
81 SEE ALSO
83 INTERNALS
85 ******************************************************************************/
87 AROS_LIBFUNC_INIT
89 UBYTE pri;
91 /* Check to ensure that this node is not already in a list. */
92 if( softint->is_Node.ln_Type != NT_SOFTINT )
94 /* Scale the priority down to a number between 0 and 4 inclusive
95 We can use that to index into exec's software interrupt lists. */
96 pri = ((softint->is_Node.ln_Pri & 0xF0) + 0x20) >> 4;
98 /* We are accessing an Exec list, protect ourselves. */
99 Disable();
100 AddTail((struct List *)&SysBase->SoftInts[pri],
101 (struct Node *)softint);
102 softint->is_Node.ln_Type = NT_SOFTINT;
103 SysBase->SysFlags |= SFF_SoftInt;
104 Enable();
106 /* We now cause a software interrupt. Pretty hard here... */
107 #ifndef __CXREF__
108 #error The '$(KERNEL)' interrupt implementation has not been completed.
109 #endif
112 AROS_LIBFUNC_EXIT
113 } /* Cause() */
116 This is the dispatcher for software interrupts. We go through the
117 lists and remove the interrupts before calling them. Because we
118 can be interrupted we should not cache the next pointer, but
119 retreive it from ExecBase each time.
121 Note: All these arguments are passed to the function, so you must
122 at least declare all of them. You do not however have to use any
123 of them (although that is recommended).
125 This procedure could be more efficient, and it has to be implemented
126 in the kernel.
129 AROS_UFH5(ULONG, SoftIntDispatch,
130 AROS_UFHA(ULONG, intReady, D1),
131 AROS_UFHA(struct Custom *, custom, A0),
132 AROS_UFHA(IPTR, intData, A1),
133 AROS_UFHA(ULONG_FUNC, intCode, A5),
134 AROS_UFHA(struct ExecBase *, SysBase, A6))
136 AROS_USERFUNC_INIT
138 struct Interrupt *intr;
139 UBYTE i;
140 ULONG res;
143 Hmm, we have to disable software interrupts ONLY. Do NOT disable
144 any other kind of interrupt. This is very hard to do here however.
146 The #error line above will trap however.
149 /* Don't bother if there are no software ints queued. */
150 if( SysBase->SysFlags & SFF_SoftInt )
152 /* Clear Software interrupt pending flag. */
153 SysBase->SysFlags &= ~(SFF_SoftInt);
155 for(i=0; i < 4; i++)
157 /* There is a possible problem here with list access */
158 while( (intr = RemHead((struct List *)&SysBase->SoftInts[i])) )
160 intr->is_Node.ln_Type = NT_INTERRUPT;
162 /* Call the software interrupt. */
163 AROS_UFC3(void, intr->is_Code,
164 AROS_UFCA(APTR, intr->is_Data, A1),
165 AROS_UFCA(ULONG_FUNC, intr->is_Code, A5),
166 AROS_UFCA(struct ExecBase *, SysBase, A6));
171 /* We now re-enable software interrupts. But we can't do it here. */
172 AROS_USERFUNC_EXIT