revert between 56095 -> 55830 in arch
[AROS.git] / arch / all-unix / kernel / kernel.c
blob165c8c25faae59a375637e83e8802c16bcbd4c4a
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Initialize the interface to the "hardware".
6 Lang: english
7 */
9 #include <exec/interrupts.h>
10 #include <exec/execbase.h>
11 #include <aros/asmcall.h>
12 #include <aros/atomic.h>
13 #include <aros/symbolsets.h>
14 #include <hardware/intbits.h>
15 #include <proto/exec.h>
16 #include <proto/hostlib.h>
18 #define timeval sys_timeval
20 #define __AROS_KERNEL__
22 #include "hostinterface.h"
23 #include "kernel_base.h"
24 #include "kernel_debug.h"
25 #include "kernel_globals.h"
26 #include "kernel_intr.h"
27 #include "kernel_intern.h"
28 #include "kernel_interrupts.h"
29 #include "kernel_scheduler.h"
30 #include "kernel_unix.h"
32 #include <stdarg.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <signal.h>
36 #include <unistd.h>
38 #undef timeval
40 #define D(x)
41 #define DSC(x)
43 #ifdef SIGCORE_NEED_SA_SIGINFO
44 #define SETHANDLER(sa, h) \
45 sa.sa_sigaction = h ## _gate; \
46 sa.sa_flags |= SA_SIGINFO
47 #else
48 #define SETHANDLER(sa, h) \
49 sa.sa_handler = h ## _gate;
50 #endif
52 static void core_TrapHandler(int sig, regs_t *regs)
54 struct KernelBase *KernelBase = getKernelBase();
55 const struct SignalTranslation *s;
56 short amigaTrap;
57 struct AROSCPUContext ctx;
59 SUPERVISOR_ENTER;
61 /* Just for completeness */
62 krnRunIRQHandlers(KernelBase, sig);
64 bug("[KRN] Trap signal %d, SysBase %p, KernelBase %p\n", sig, SysBase, KernelBase);
65 PRINT_SC(regs);
67 /* Translate UNIX trap number to CPU and exec trap numbers */
68 for (s = sigs; s->sig != -1; s++)
70 if (sig == s->sig)
71 break;
75 * Trap handler expects struct ExceptionContext, so we have to convert regs_t to it.
76 * But first initialize all context area to zero, this is important since it may include
77 * pointers to FPU state buffers.
78 * TODO: FPU state also can be interesting for debuggers, we need to prepare space for it
79 * too. Needs to be enclosed in some macros.
81 memset(&ctx, 0, sizeof(ctx));
82 SAVEREGS(&ctx, regs);
84 amigaTrap = s->AmigaTrap;
85 if (s->CPUTrap != -1)
87 if (krnRunExceptionHandlers(KernelBase, s->CPUTrap, &ctx))
88 /* Do not call exec trap handler */
89 amigaTrap = -1;
93 * Call exec trap handler if needed.
94 * Note that it may return, this means that the it has
95 * fixed the problem somehow and we may safely continue.
97 if (amigaTrap != -1)
98 core_Trap(amigaTrap, &ctx);
100 /* Trap handler(s) have possibly modified the context, so
101 we convert it back before returning */
102 RESTOREREGS(&ctx, regs);
104 SUPERVISOR_LEAVE;
107 static void core_IRQ(int sig, regs_t *sc)
109 struct KernelBase *KernelBase = getKernelBase();
111 SUPERVISOR_ENTER;
113 /* Just additional protection - what if there's more than 32 signals? */
114 if (sig < IRQ_COUNT)
115 krnRunIRQHandlers(KernelBase, sig);
117 if (UKB(KernelBase)->SupervisorCount == 1)
118 core_ExitInterrupt(sc);
120 SUPERVISOR_LEAVE;
124 * This is from sigcore.h - it brings in the definition of the
125 * systems initial signal handler, which simply calls
126 * sighandler(int signum, regs_t sigcontext)
128 GLOBAL_SIGNAL_INIT(core_TrapHandler)
129 GLOBAL_SIGNAL_INIT(core_SysCall)
130 GLOBAL_SIGNAL_INIT(core_IRQ)
132 /* libc functions that we use */
133 static const char *kernel_functions[] =
135 "raise",
136 "sigprocmask",
137 "sigsuspend",
138 "sigaction",
139 "mprotect",
140 "read",
141 "fcntl",
142 "mmap",
143 "munmap",
144 #ifdef HOST_OS_linux
145 "__errno_location",
146 #else
147 #ifdef HOST_OS_android
148 "__errno",
149 #else
150 "__error",
151 #endif
152 #endif
153 #ifdef HOST_OS_android
154 "sigwait",
155 #else
156 "sigemptyset",
157 "sigfillset",
158 "sigaddset",
159 "sigdelset",
160 #endif
161 NULL
165 * Our post-SINGLETASK initialization code.
166 * At this point we are starting up interrupt subsystem.
167 * We have hostlib.resource and can use it in order to pick up all needed host OS functions.
169 int core_Start(void *libc)
171 struct KernelBase *KernelBase = getKernelBase();
172 struct PlatformData *pd = KernelBase->kb_PlatformData;
173 APTR HostLibBase;
174 struct sigaction sa = {};
175 const struct SignalTranslation *s;
176 sigset_t tmp_mask;
177 ULONG r;
179 /* We have hostlib.resource. Obtain the complete set of needed functions. */
180 HostLibBase = OpenResource("hostlib.resource");
181 if (!HostLibBase)
183 krnPanic(KernelBase, "Failed to open hostlib.resource");
184 return FALSE;
187 pd->iface = (struct KernelInterface *)HostLib_GetInterface(libc, kernel_functions, &r);
188 if (!pd->iface)
190 krnPanic(KernelBase, "Failed to allocate host-side libc interface");
191 return FALSE;
194 if (r)
196 krnPanic(KernelBase, "Failed to resove %u functions from host libc", r);
197 return FALSE;
200 /* Cache errno pointer, for context switching */
201 pd->errnoPtr = pd->iface->__error();
202 AROS_HOST_BARRIER
204 #if DEBUG
205 /* Pass unhandled exceptions to the debugger, if present */
206 SIGEMPTYSET(&pd->sig_int_mask);
207 #else
208 /* We only want signal that we can handle at the moment */
209 SIGFILLSET(&pd->sig_int_mask);
210 #endif
211 SIGEMPTYSET(&sa.sa_mask);
212 sa.sa_flags = SA_RESTART;
215 * These ones we consider as processor traps.
216 * They are not be blocked by KrnCli()
218 SETHANDLER(sa, core_TrapHandler);
219 for (s = sigs; s->sig != -1; s++)
221 pd->iface->sigaction(s->sig, &sa, NULL);
222 AROS_HOST_BARRIER
223 SIGDELSET(&pd->sig_int_mask, s->sig);
226 /* SIGUSRs are software interrupts, we also never block them */
227 SIGDELSET(&pd->sig_int_mask, SIGUSR1);
228 SIGDELSET(&pd->sig_int_mask, SIGUSR2);
229 /* We want to be able to interrupt AROS using Ctrl-C in its console,
230 so exclude SIGINT too. */
231 SIGDELSET(&pd->sig_int_mask, SIGINT);
234 * Any interrupt including software one must disable
235 * all interrupts. Otherwise one interrupt may happen
236 * between interrupt handler entry and supervisor count
237 * increment. This can cause bad things in cpu_Dispatch()
239 sa.sa_mask = pd->sig_int_mask;
241 /* Install interrupt handlers */
242 SETHANDLER(sa, core_IRQ);
243 #if DEBUG
244 /* Use VTALRM instead of ALRM during debugging, so
245 * that stepping though code won't have to deal
246 * with constant SIGALRM processing.
248 * NOTE: This will cause the AROS clock to march slower
249 * than the host clock in debug builds!
251 pd->iface->sigaction(SIGVTALRM, &sa, NULL);
252 AROS_HOST_BARRIER
253 #else
254 pd->iface->sigaction(SIGALRM, &sa, NULL);
255 AROS_HOST_BARRIER
256 #endif
257 pd->iface->sigaction(SIGIO , &sa, NULL);
258 AROS_HOST_BARRIER
260 /* Software IRQs do not need to block themselves. Anyway we know when we send them. */
261 sa.sa_flags |= SA_NODEFER;
263 pd->iface->sigaction(SIGUSR2, &sa, NULL);
264 AROS_HOST_BARRIER
266 SETHANDLER(sa, core_SysCall);
267 pd->iface->sigaction(SIGUSR1, &sa, NULL);
268 AROS_HOST_BARRIER
270 /* We need to start up with disabled interrupts */
271 pd->iface->sigprocmask(SIG_BLOCK, &pd->sig_int_mask, NULL);
272 AROS_HOST_BARRIER
275 * Explicitly make sure that SIGUSR1 and SIGUSR2 are enabled.
276 * This effectively kicks DalvikVM's ass on Android and takes SIGUSR1 away
277 * from its "signal catcher". On other platforms this at least should not harm.
278 * I also added SIGUSR2, just in case.
280 SIGEMPTYSET(&tmp_mask);
281 SIGADDSET(&tmp_mask, SIGUSR1);
282 SIGADDSET(&tmp_mask, SIGUSR2);
283 pd->iface->sigprocmask(SIG_UNBLOCK, &tmp_mask, NULL);
284 AROS_HOST_BARRIER
286 return TRUE;
290 * All syscalls are mapped to single SIGUSR1. We look at task's tc_State
291 * to determine the needed action.
292 * This is not inlined because actual SIGUSR1 number is host-specific, it can
293 * differ between different UNIX variants, and even between different ports of the same
294 * OS (e. g. Linux). We need host OS includes in order to get the proper definition, and
295 * we include them only in arch-specific code.
297 void unix_SysCall(unsigned char n, struct KernelBase *KernelBase)
299 DSC(bug("[KRN] SysCall %d\n", n));
301 KernelBase->kb_PlatformData->iface->raise(SIGUSR1);
302 AROS_HOST_BARRIER