2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: Initialize the interface to the "hardware".
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"
43 #ifdef SIGCORE_NEED_SA_SIGINFO
44 #define SETHANDLER(sa, h) \
45 sa.sa_sigaction = h ## _gate; \
46 sa.sa_flags |= SA_SIGINFO
48 #define SETHANDLER(sa, h) \
49 sa.sa_handler = h ## _gate;
52 static void core_TrapHandler(int sig
, regs_t
*regs
)
54 struct KernelBase
*KernelBase
= getKernelBase();
55 const struct SignalTranslation
*s
;
57 struct AROSCPUContext ctx
;
61 /* Just for completeness */
62 krnRunIRQHandlers(KernelBase
, sig
);
64 bug("[KRN] Trap signal %d, SysBase %p, KernelBase %p\n", sig
, SysBase
, KernelBase
);
67 /* Translate UNIX trap number to CPU and exec trap numbers */
68 for (s
= sigs
; s
->sig
!= -1; s
++)
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
));
84 amigaTrap
= s
->AmigaTrap
;
87 if (krnRunExceptionHandlers(KernelBase
, s
->CPUTrap
, &ctx
))
88 /* Do not call exec trap handler */
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.
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
);
107 static void core_IRQ(int sig
, regs_t
*sc
)
109 struct KernelBase
*KernelBase
= getKernelBase();
113 /* Just additional protection - what if there's more than 32 signals? */
115 krnRunIRQHandlers(KernelBase
, sig
);
117 if (UKB(KernelBase
)->SupervisorCount
== 1)
118 core_ExitInterrupt(sc
);
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
[] =
147 #ifdef HOST_OS_android
153 #ifdef HOST_OS_android
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
;
174 struct sigaction sa
= {};
175 const struct SignalTranslation
*s
;
179 /* We have hostlib.resource. Obtain the complete set of needed functions. */
180 HostLibBase
= OpenResource("hostlib.resource");
183 krnPanic(KernelBase
, "Failed to open hostlib.resource");
187 pd
->iface
= (struct KernelInterface
*)HostLib_GetInterface(libc
, kernel_functions
, &r
);
190 krnPanic(KernelBase
, "Failed to allocate host-side libc interface");
196 krnPanic(KernelBase
, "Failed to resove %u functions from host libc", r
);
200 /* Cache errno pointer, for context switching */
201 pd
->errnoPtr
= pd
->iface
->__error();
205 /* Pass unhandled exceptions to the debugger, if present */
206 SIGEMPTYSET(&pd
->sig_int_mask
);
208 /* We only want signal that we can handle at the moment */
209 SIGFILLSET(&pd
->sig_int_mask
);
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
);
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
);
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
);
254 pd
->iface
->sigaction(SIGALRM
, &sa
, NULL
);
257 pd
->iface
->sigaction(SIGIO
, &sa
, NULL
);
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
);
266 SETHANDLER(sa
, core_SysCall
);
267 pd
->iface
->sigaction(SIGUSR1
, &sa
, NULL
);
270 /* We need to start up with disabled interrupts */
271 pd
->iface
->sigprocmask(SIG_BLOCK
, &pd
->sig_int_mask
, NULL
);
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
);
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
);