revert between 56095 -> 55830 in arch
[AROS.git] / arch / all-unix / kernel / kernel_intr.c
blobadcd8f18db8e77da57e1066cdf4c1e795891b148
1 /*
2 Copyright © 1995-2017, 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_debug.h>
13 #include <kernel_interrupts.h>
14 #include <kernel_intr.h>
15 #include <kernel_globals.h>
16 #include <kernel_scheduler.h>
17 #include <kernel_syscall.h>
18 #include "kernel_intern.h"
19 #include "kernel_unix.h"
21 #define D(x)
24 * Leave the interrupt. This function receives the interrupt register frame
25 * and runs task scheduler if needed.
27 * You should call it only if you're returning to user mode (i.e. not from
28 * within nested interrupt).
30 * It relies on CPU-specific cpu_Switch() and cpu_Dispatch() implementations
31 * which save and restore CPU context. cpu_Dispatch() is allowed just to
32 * jump to the saved context and not return here.
34 void core_ExitInterrupt(regs_t *regs)
36 /* Soft interrupt requested? It's high time to do it */
37 if (SysBase->SysFlags & SFF_SoftInt)
38 core_Cause(INTB_SOFTINT, 1L << INTB_SOFTINT);
40 /* If task switching is disabled, do nothing */
41 if (SysBase->TDNestCnt < 0)
44 * Do not disturb task if it's not necessary.
45 * Reschedule only if switch pending flag is set. Exit otherwise.
47 if (SysBase->AttnResched & ARF_AttnSwitch)
49 /* Run task scheduling sequence */
50 if (core_Schedule())
52 cpu_Switch(regs);
53 cpu_Dispatch(regs);
60 * We do not have enough user-defined signals to map
61 * them to four required syscalls (CAUSE, SCHEDULE,
62 * SWITCH, DISPATCH). We get around this by assigning
63 * CAUSE to SIGUSR2 and others to SIGUSR1.
65 * What action is to be taken upon SIGUSR1 can be
66 * figured out by looking at caller task's state.
67 * exec.library calls KrnDispatch() only after task
68 * has been actually disposed, with state set to TS_REMOVED.
69 * Similarly, KrnSwitch() is called only in Wait(), after
70 * setting state to TS_WAIT. In other cases it's KrnSchedule().
72 void core_SysCall(int sig, regs_t *regs)
74 struct KernelBase *KernelBase = getKernelBase();
75 struct Task *task = SysBase->ThisTask;
77 D(bug("[KRN] %s()\n", __func__));
79 SUPERVISOR_ENTER;
81 krnRunIRQHandlers(KernelBase, sig);
83 switch(task->tc_State)
85 /* A running task needs to be put into TaskReady list first. It's SC_SCHEDULE. */
86 case TS_RUN:
87 if (!core_Schedule())
88 break;
90 /* If the task is already in some list with appropriate state, it's SC_SWITCH */
91 case TS_REMOVED:
92 case TS_READY:
93 case TS_WAIT:
94 cpu_Switch(regs);
96 /* If the task is removed, it's simply SC_DISPATCH */
97 case TS_INVALID:
98 cpu_Dispatch(regs);
99 break;
101 /* Special state is used for returning from exception */
102 case TS_EXCEPT:
103 cpu_DispatchContext(task, regs, KernelBase->kb_PlatformData);
104 break;
107 SUPERVISOR_LEAVE;