2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: i386native version of Cause().
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>
25 extern char softblock
;
29 __asm__ __volatile__ ("mov %%ds,%%ax":"=a"(__value)); \
33 AROS_LHA(struct Interrupt
*, softint
, A1
),
34 struct ExecBase
*, SysBase
, 30, Exec
)
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 */
59 __asm__
__volatile__ ("movl $0,%%eax\n\tint $0x80":::"eax","memory");
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
];
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
)
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)
101 iv
= &SysBase
->IntVects
[INTB_SOFTINT
];
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)
114 A5 - Interrupt Code vector
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
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
)
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
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
))
156 struct Interrupt
*intr
= 0;
159 if( SysBase
->SysFlags
& SFF_SoftInt
)
162 /* Clear the Software interrupt pending flag. */
163 SysBase
->SysFlags
&= ~(SFF_SoftInt
);
170 intr
= (struct Interrupt
*)RemHead(&SysBase
->SoftInts
[i
].sh_List
);
174 intr
->is_Node
.ln_Type
= NT_INTERRUPT
;
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*! */
194 /* Disable software interrupts */
197 /* Clear the Software interrupt pending flag. */
198 SysBase
->SysFlags
&= ~(SFF_SoftInt
);
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. */