2 Copyright © 1995-2011, 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 #include "hostinterface.h"
21 #include "kernel_base.h"
22 #include "kernel_debug.h"
23 #include "kernel_globals.h"
24 #include "kernel_intr.h"
25 #include "kernel_intern.h"
26 #include "kernel_interrupts.h"
27 #include "kernel_scheduler.h"
28 #include "kernel_unix.h"
41 #ifdef SIGCORE_NEED_SA_SIGINFO
42 #define SETHANDLER(sa, h) \
43 sa.sa_sigaction = h ## _gate; \
44 sa.sa_flags |= SA_SIGINFO
46 #define SETHANDLER(sa, h) \
47 sa.sa_handler = h ## _gate;
50 static void core_TrapHandler(int sig
, regs_t
*regs
)
52 struct KernelBase
*KernelBase
= getKernelBase();
53 const struct SignalTranslation
*s
;
55 struct AROSCPUContext ctx
;
59 /* Just for completeness */
60 krnRunIRQHandlers(KernelBase
, sig
);
62 bug("[KRN] Trap signal %d, SysBase %p, KernelBase %p\n", sig
, SysBase
, KernelBase
);
65 /* Translate UNIX trap number to CPU and exec trap numbers */
66 for (s
= sigs
; s
->sig
!= -1; s
++)
73 * Trap handler expects struct ExceptionContext, so we have to convert regs_t to it.
74 * But first initialize all context area to zero, this is important since it may include
75 * pointers to FPU state buffers.
76 * TODO: FPU state also can be interesting for debuggers, we need to prepare space for it
77 * too. Needs to be enclosed in some macros.
79 memset(&ctx
, 0, sizeof(ctx
));
82 amigaTrap
= s
->AmigaTrap
;
85 if (krnRunExceptionHandlers(KernelBase
, s
->CPUTrap
, &ctx
))
86 /* Do not call exec trap handler */
91 * Call exec trap handler if needed.
92 * Note that it may return, this means that the it has
93 * fixed the problem somehow and we may safely continue.
96 core_Trap(amigaTrap
, &ctx
);
98 /* Trap handler(s) have possibly modified the context, so
99 we convert it back before returning */
100 RESTOREREGS(&ctx
, regs
);
105 static void core_IRQ(int sig
, regs_t
*sc
)
107 struct KernelBase
*KernelBase
= getKernelBase();
111 /* Just additional protection - what if there's more than 32 signals? */
113 krnRunIRQHandlers(KernelBase
, sig
);
115 if (UKB(KernelBase
)->SupervisorCount
== 1)
116 core_ExitInterrupt(sc
);
122 * This is from sigcore.h - it brings in the definition of the
123 * systems initial signal handler, which simply calls
124 * sighandler(int signum, regs_t sigcontext)
126 GLOBAL_SIGNAL_INIT(core_TrapHandler
)
127 GLOBAL_SIGNAL_INIT(core_SysCall
)
128 GLOBAL_SIGNAL_INIT(core_IRQ
)
130 /* libc functions that we use */
131 static const char *kernel_functions
[] =
145 #ifdef HOST_OS_android
151 #ifdef HOST_OS_android
163 * Our post-SINGLETASK initialization code.
164 * At this point we are starting up interrupt subsystem.
165 * We have hostlib.resource and can use it in order to pick up all needed host OS functions.
167 int core_Start(void *libc
)
169 struct KernelBase
*KernelBase
= getKernelBase();
170 struct PlatformData
*pd
= KernelBase
->kb_PlatformData
;
172 struct sigaction sa
= {};
173 const struct SignalTranslation
*s
;
177 /* We have hostlib.resource. Obtain the complete set of needed functions. */
178 HostLibBase
= OpenResource("hostlib.resource");
181 krnPanic(KernelBase
, "Failed to open hostlib.resource");
185 pd
->iface
= (struct KernelInterface
*)HostLib_GetInterface(libc
, kernel_functions
, &r
);
188 krnPanic(KernelBase
, "Failed to allocate host-side libc interface");
194 krnPanic(KernelBase
, "Failed to resove %u functions from host libc", r
);
198 /* Cache errno pointer, for context switching */
199 pd
->errnoPtr
= pd
->iface
->__error();
203 /* Pass unhandled exceptions to the debugger, if present */
204 SIGEMPTYSET(&pd
->sig_int_mask
);
206 /* We only want signal that we can handle at the moment */
207 SIGFILLSET(&pd
->sig_int_mask
);
209 SIGEMPTYSET(&sa
.sa_mask
);
210 sa
.sa_flags
= SA_RESTART
;
213 * These ones we consider as processor traps.
214 * They are not be blocked by KrnCli()
216 SETHANDLER(sa
, core_TrapHandler
);
217 for (s
= sigs
; s
->sig
!= -1; s
++)
219 pd
->iface
->sigaction(s
->sig
, &sa
, NULL
);
221 SIGDELSET(&pd
->sig_int_mask
, s
->sig
);
224 /* SIGUSRs are software interrupts, we also never block them */
225 SIGDELSET(&pd
->sig_int_mask
, SIGUSR1
);
226 SIGDELSET(&pd
->sig_int_mask
, SIGUSR2
);
227 /* We want to be able to interrupt AROS using Ctrl-C in its console,
228 so exclude SIGINT too. */
229 SIGDELSET(&pd
->sig_int_mask
, SIGINT
);
232 * Any interrupt including software one must disable
233 * all interrupts. Otherwise one interrupt may happen
234 * between interrupt handler entry and supervisor count
235 * increment. This can cause bad things in cpu_Dispatch()
237 sa
.sa_mask
= pd
->sig_int_mask
;
239 /* Install interrupt handlers */
240 SETHANDLER(sa
, core_IRQ
);
242 /* Use VTALRM instead of ALRM during debugging, so
243 * that stepping though code won't have to deal
244 * with constant SIGALRM processing.
246 * NOTE: This will cause the AROS clock to march slower
247 * than the host clock in debug builds!
249 pd
->iface
->sigaction(SIGVTALRM
, &sa
, NULL
);
252 pd
->iface
->sigaction(SIGALRM
, &sa
, NULL
);
255 pd
->iface
->sigaction(SIGIO
, &sa
, NULL
);
258 /* Software IRQs do not need to block themselves. Anyway we know when we send them. */
259 sa
.sa_flags
|= SA_NODEFER
;
261 pd
->iface
->sigaction(SIGUSR2
, &sa
, NULL
);
264 SETHANDLER(sa
, core_SysCall
);
265 pd
->iface
->sigaction(SIGUSR1
, &sa
, NULL
);
268 /* We need to start up with disabled interrupts */
269 pd
->iface
->sigprocmask(SIG_BLOCK
, &pd
->sig_int_mask
, NULL
);
273 * Explicitly make sure that SIGUSR1 and SIGUSR2 are enabled.
274 * This effectively kicks DalvikVM's ass on Android and takes SIGUSR1 away
275 * from its "signal catcher". On other platforms this at least should not harm.
276 * I also added SIGUSR2, just in case.
278 SIGEMPTYSET(&tmp_mask
);
279 SIGADDSET(&tmp_mask
, SIGUSR1
);
280 SIGADDSET(&tmp_mask
, SIGUSR2
);
281 pd
->iface
->sigprocmask(SIG_UNBLOCK
, &tmp_mask
, NULL
);
288 * All syscalls are mapped to single SIGUSR1. We look at task's tc_State
289 * to determine the needed action.
290 * This is not inlined because actual SIGUSR1 number is host-specific, it can
291 * differ between different UNIX variants, and even between different ports of the same
292 * OS (e. g. Linux). We need host OS includes in order to get the proper definition, and
293 * we include them only in arch-specific code.
295 void unix_SysCall(unsigned char n
, struct KernelBase
*KernelBase
)
297 DSC(bug("[KRN] SysCall %d\n", n
));
299 KernelBase
->kb_PlatformData
->iface
->raise(SIGUSR1
);