make.tmpl: add missing compiler attribute to build_progs
[AROS.git] / arch / m68k-mac / exec / cause.c
blobfeb315e55a5c30dca83774af3facf01b6e562c7c
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Plam Version of Cause(); taken from i386native version of Cause().
6 Lang: english
7 */
9 #include <exec/execbase.h>
10 #include <aros/asmcall.h>
11 #include <exec/interrupts.h>
12 #include <hardware/custom.h>
13 #include <hardware/intbits.h>
14 #include <proto/exec.h>
16 #include <exec_intern.h>
19 #include <exec/ptrace.h>
21 static char softblock;
23 #if 0
24 #define get_cs() \
25 ({ short __value; \
26 __asm__ __volatile__ ("mov %%ds,%%ax":"=a"(__value)); \
27 (__value & 0x03); })
28 #endif
30 AROS_LH1(void, Cause,
31 AROS_LHA(struct Interrupt *, softint, A1),
32 struct ExecBase *, SysBase, 30, Exec)
34 AROS_LIBFUNC_INIT
36 UBYTE pri;
38 /* Check to ensure that this node is not already in a list. */
39 if( softint->is_Node.ln_Type != NT_SOFTINT )
41 /* Scale the priority down to a number between 0 and 4 inclusive
42 We can use that to index into exec's software interrupt lists. */
43 pri = (softint->is_Node.ln_Pri + 0x20) >> 4;
45 /* We are accessing an Exec list, protect ourselves. */
46 Disable();
47 AddTail((struct List *)&SysBase->SoftInts[pri], (struct Node *)softint);
48 softint->is_Node.ln_Type = NT_SOFTINT;
49 SysBase->SysFlags |= SFF_SoftInt;
50 Enable();
52 if (!softblock)
54 /* If we are in supervisor mode we simply call InterruptServer.
55 Cause software interrupt (int 0x80) otherwise */
56 #if 0
57 if (get_cs())
59 /* Called from user mode. We can do Cause in normal way */
60 __asm__ __volatile__ ("movl $0,%%eax\n\tint $0x80":::"eax","memory");
62 else
63 #endif
65 /* Cause() inside supervisor mode. We will call IntServer directly
66 no matter it is normal irq or Supervisor() call */
67 struct IntVector *iv;
68 iv = &SysBase->IntVects[INTB_SOFTINT];
70 if (iv->iv_Code)
72 AROS_INTC1(iv->iv_Code, iv->iv_Data);
78 AROS_LIBFUNC_EXIT
79 } /* Cause() */
81 extern void SaveRegs(struct Task *task, struct pt_regs *regs);
82 extern void RestoreRegs(struct Task *task, struct pt_regs *regs);
84 //#define SC_ENABLE(regs) (regs.eflags |= 0x200)
85 //#define SC_DISABLE(regs) (regs.eflags &= ~0x200)
88 /*asmlinkage*/ void sys_Cause(struct pt_regs * regs)
90 struct IntVector *iv;
92 struct ExecBase * SysBase = 0x04;
94 /* Hmm, interrupts are nesting, not a good idea... */
95 if(!user_mode(regs)) {
96 #if NOISY
97 kprintf("Illegal Supervisor\n");
98 #endif
99 return;
102 iv = &SysBase->IntVects[INTB_SOFTINT];
104 if (iv->iv_Code)
106 /* Call it. */
107 AROS_INTC1(iv->iv_Code, regs);
110 /* Has an interrupt told us to dispatch when leaving */
111 if (SysBase->AttnResched & 0x8000)
113 SysBase->AttnResched &= ~0x8000;
115 /* Save registers for this task (if there is one...) */
116 if (SysBase->ThisTask && SysBase->ThisTask->tc_State != TS_REMOVED)
117 SaveRegs(SysBase->ThisTask, regs);
119 /* Tell exec that we have actually switched tasks... */
120 Dispatch ();
122 /* Get the registers of the old task */
123 RestoreRegs(SysBase->ThisTask, regs);
125 /* Make sure that the state of the interrupts is what the task
126 expects.
128 #if 0
129 if (SysBase->IDNestCnt < 0)
130 SC_ENABLE(regs);
131 else
132 SC_DISABLE(regs);
133 #endif
134 /* Ok, the next step is to either drop back to the new task, or
135 give it its Exception() if it wants one... */
137 if (SysBase->ThisTask->tc_Flags & TF_EXCEPT)
139 Disable();
140 Exception();
141 Enable();
145 #if DEBUG_TT
146 if (lastTask != SysBase->ThisTask)
148 kprintf (stderr, "TT %s\n", SysBase->ThisTask->tc_Node.ln_Name);
149 lastTask = SysBase->ThisTask;
151 #endif
154 /* Leave the interrupt. */
157 #undef SysBase
160 This is the dispatcher for software interrupts. We go through the
161 lists and remove the interrupts before calling them. Because we
162 can be interrupted we should not cache the next pointer, but
163 retreive it from ExecBase each time.
165 Note: All these arguments are passed to the structure, so you must
166 at least declare all of them. You do not however have to use any
167 of them (although that is recommended).
169 This procedure could be more efficient, and it has to be implemented
170 in the kernel.
173 AROS_INTH0(SoftIntDispatch)
175 AROS_INTFUNC_INIT
177 struct Interrupt *intr;
178 UBYTE i;
180 if( SysBase->SysFlags & SFF_SoftInt )
182 /* Disable software interrupts */
183 softblock = 1;
185 /* Clear the Software interrupt pending flag. */
186 SysBase->SysFlags &= ~(SFF_SoftInt);
188 for(i=0; i < 4; i++)
190 while( (intr = (struct Interrupt *)RemHead((struct List *)&SysBase->SoftInts[i])) )
192 intr->is_Node.ln_Type = NT_INTERRUPT;
194 /* Call the software interrupt. */
195 AROS_INTC1(intr->is_Code, intr->is_Data);
199 /* We now re-enable software interrupts. */
200 softblock = 0;
203 return FALSE;
205 AROS_INTFUNC_EXIT