Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / arch / all-unix / kernel / kernel_intr.c
blob4da19b9caecfdbf52d68d986a175e88e369eff1e
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/atomic.h>
7 #include <exec/execbase.h>
8 #include <hardware/intbits.h>
9 #include <proto/exec.h>
11 #include <kernel_base.h>
12 #include <kernel_interrupts.h>
13 #include <kernel_intr.h>
14 #include <kernel_globals.h>
15 #include <kernel_scheduler.h>
16 #include <kernel_syscall.h>
17 #include "kernel_intern.h"
18 #include "kernel_unix.h"
21 * Leave the interrupt. This function receives the interrupt register frame
22 * and runs task scheduler if needed.
24 * You should call it only if you're returning to user mode (i.e. not from
25 * within nested interrupt).
27 * It relies on CPU-specific cpu_Switch() and cpu_Dispatch() implementations
28 * which save and restore CPU context. cpu_Dispatch() is allowed just to
29 * jump to the saved context and not return here.
31 void core_ExitInterrupt(regs_t *regs)
33 /* Soft interrupt requested? It's high time to do it */
34 if (SysBase->SysFlags & SFF_SoftInt)
35 core_Cause(INTB_SOFTINT, 1L << INTB_SOFTINT);
37 /* If task switching is disabled, do nothing */
38 if (SysBase->TDNestCnt < 0)
41 * Do not disturb task if it's not necessary.
42 * Reschedule only if switch pending flag is set. Exit otherwise.
44 if (SysBase->AttnResched & ARF_AttnSwitch)
46 /* Run task scheduling sequence */
47 if (core_Schedule())
49 cpu_Switch(regs);
50 cpu_Dispatch(regs);
57 * We do not have enough user-defined signals to map
58 * them to four required syscalls (CAUSE, SCHEDULE,
59 * SWITCH, DISPATCH). We get around this by assigning
60 * CAUSE to SIGUSR2 and others to SIGUSR1.
62 * What action is to be taken upon SIGUSR1 can be
63 * figured out by looking at caller task's state.
64 * exec.library calls KrnDispatch() only after task
65 * has been actually disposed, with state set to TS_REMOVED.
66 * Similarly, KrnSwitch() is called only in Wait(), after
67 * setting state to TS_WAIT. In other cases it's KrnSchedule().
69 void core_SysCall(int sig, regs_t *regs)
71 struct KernelBase *KernelBase = getKernelBase();
72 struct Task *task = SysBase->ThisTask;
74 SUPERVISOR_ENTER;
76 krnRunIRQHandlers(KernelBase, sig);
78 switch(task->tc_State)
80 /* A running task needs to be put into TaskReady list first. It's SC_SCHEDULE. */
81 case TS_RUN:
82 if (!core_Schedule())
83 break;
85 /* If the task is already in some list with appropriate state, it's SC_SWITCH */
86 case TS_READY:
87 case TS_WAIT:
88 cpu_Switch(regs);
90 /* If the task is removed, it's simply SC_DISPATCH */
91 case TS_REMOVED:
92 cpu_Dispatch(regs);
93 break;
95 /* Special state is used for returning from exception */
96 case TS_EXCEPT:
97 cpu_DispatchContext(task, regs, KernelBase->kb_PlatformData);
98 break;
101 SUPERVISOR_LEAVE;