Re-enabled use of AROS.Boot file due to lack of general enthusiasm for
[tangerine.git] / arch / i386-pc / exec / cause.c
blob032104a64092d87bea2a21d32b5ec39850c702d4
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: i386native version of Cause().
6 Lang: english
7 */
10 #include <exec/execbase.h>
11 #include <aros/asmcall.h>
12 #include <exec/interrupts.h>
13 #include <hardware/custom.h>
14 #include <hardware/intbits.h>
15 #include <proto/exec.h>
17 #include <exec_intern.h>
19 #include <asm/linkage.h>
20 #include <asm/ptrace.h>
21 #include <asm/irq.h>
23 #include "etask.h"
25 extern char softblock;
27 #define get_cs() \
28 ({ short __value; \
29 __asm__ __volatile__ ("mov %%ds,%%ax":"=a"(__value)); \
30 (__value & 0x03); })
32 AROS_LH1(void, Cause,
33 AROS_LHA(struct Interrupt *, softint, A1),
34 struct ExecBase *, SysBase, 30, Exec)
36 AROS_LIBFUNC_INIT
38 UBYTE pri;
41 Disable();
42 /* Check to ensure that this node is not already in a list. */
43 if( softint->is_Node.ln_Type != NT_SOFTINT )
45 /* Scale the priority down to a number between 0 and 4 inclusive
46 We can use that to index into exec's software interrupt lists. */
47 pri = (softint->is_Node.ln_Pri + 0x20)>>4;
49 /* We are accessing an Exec list, protect ourselves. */
50 ADDTAIL(&SysBase->SoftInts[pri].sh_List, &softint->is_Node);
51 softint->is_Node.ln_Type = NT_SOFTINT;
52 SysBase->SysFlags |= SFF_SoftInt;
54 /* If we are in usermode the software interrupt will end up
55 being triggered in Enable(). See Enable() code */
56 #if 0
57 if (!softblock)
58 if (get_cs())
59 __asm__ __volatile__ ("movl $0,%%eax\n\tint $0x80":::"eax","memory");
60 else
62 /* Cause() inside supervisor mode. We will call IntServer directly
63 no matter it is normal irq or Supervisor() call */
64 struct IntVector *iv = &SysBase->IntVects[INTB_SOFTINT];
66 if (iv->iv_Code)
68 AROS_UFC5(void, iv->iv_Code,
69 AROS_UFCA(ULONG, 0, D1),
70 AROS_UFCA(ULONG, 0, A0),
71 AROS_UFCA(APTR, NULL, A1),
72 AROS_UFCA(APTR, iv->iv_Code, A5),
73 AROS_UFCA(struct ExecBase *, SysBase, A6)
77 #endif
80 Enable();
83 AROS_LIBFUNC_EXIT
84 } /* Cause() */
86 #ifdef SysBase
87 #undef SysBase
88 #endif
89 #define SysBase (*(struct ExecBase **)4UL)
92 #define SC_ENABLE(regs) (regs.eflags |= 0x200)
93 #define SC_DISABLE(regs) (regs.eflags &= ~0x200)
96 // asmlinkage void sys_Cause(struct pt_regs regs)
97 asmlinkage void sys_Cause(void)
99 struct IntVector *iv;
101 iv = &SysBase->IntVects[INTB_SOFTINT];
103 if (iv->iv_Code)
105 /* Call it. I call with all these parameters for a reason.
107 In my `Amiga ROM Kernel Reference Manual: Libraries and
108 Devices' (the 1.3 version), interrupt servers are called
109 with the following 5 parameters.
111 D1 - Mask of INTENAR and INTREQR
112 A0 - 0xDFF000 (base of custom chips)
113 A1 - Interrupt Data
114 A5 - Interrupt Code vector
115 A6 - SysBase
117 It is quite possible that some code uses all of these, so
118 I must supply them here. Obviously I will dummy some of these
119 though.
121 AROS_UFC5(void, iv->iv_Code,
122 AROS_UFCA(ULONG, 0, D1),
123 AROS_UFCA(ULONG, 0, A0),
124 AROS_UFCA(APTR, 0, A1),
125 AROS_UFCA(APTR, iv->iv_Code, A5),
126 AROS_UFCA(struct ExecBase *, SysBase, A6)
131 #undef SysBase
134 This is the dispatcher for software interrupts. We go through the
135 lists and remove the interrupts before calling them. Because we
136 can be interrupted we should not cache the next pointer, but
137 retreive it from ExecBase each time.
139 Note: All these arguments are passed to the structure, so you must
140 at least declare all of them. You do not however have to use any
141 of them (although that is recommended).
143 This procedure could be more efficient, and it has to be implemented
144 in the kernel.
147 AROS_UFH5(void, SoftIntDispatch,
148 AROS_UFHA(ULONG, intReady, D1),
149 AROS_UFHA(struct Custom *, custom, A0),
150 AROS_UFHA(IPTR, intData, A1),
151 AROS_UFHA(IPTR, intCode, A5),
152 AROS_UFHA(struct ExecBase *, SysBase, A6))
154 AROS_USERFUNC_INIT
156 struct Interrupt *intr = 0;
157 BYTE i;
159 if( SysBase->SysFlags & SFF_SoftInt )
161 #if 1
162 /* Clear the Software interrupt pending flag. */
163 SysBase->SysFlags &= ~(SFF_SoftInt);
165 for(;;)
167 for(i=4; i>=0; i--)
169 __cli();
170 intr = (struct Interrupt *)RemHead(&SysBase->SoftInts[i].sh_List);
172 if (intr)
174 intr->is_Node.ln_Type = NT_INTERRUPT;
176 __sti();
178 /* Call the software interrupt. */
179 AROS_UFC3(void, intr->is_Code,
180 AROS_UFCA(APTR, intr->is_Data, A1),
181 AROS_UFCA(APTR, intr->is_Code, A5),
182 AROS_UFCA(struct ExecBase *, SysBase, A6));
184 /* Get out and start loop *all* over again *from scratch*! */
185 break;
189 if (!intr) break;
193 #else
194 /* Disable software interrupts */
195 softblock = 1;
197 /* Clear the Software interrupt pending flag. */
198 SysBase->SysFlags &= ~(SFF_SoftInt);
200 for(i=4; i>=0; i--)
202 while( (intr = (struct Interrupt *)RemHead(&SysBase->SoftInts[i].sh_List)) )
204 intr->is_Node.ln_Type = NT_INTERRUPT;
206 /* Call the software interrupt. */
207 AROS_UFC3(void, intr->is_Code,
208 AROS_UFCA(APTR, intr->is_Data, A1),
209 AROS_UFCA(APTR, intr->is_Code, A5),
210 AROS_UFCA(struct ExecBase *, SysBase, A6));
214 /* We now re-enable software interrupts. */
215 softblock = 0;
216 #endif
219 return;
220 AROS_USERFUNC_EXIT