2 Copyright © 2017-2018, The AROS Development Team. All rights reserved.
8 #include <aros/libcall.h>
9 #include <aros/asmcall.h>
10 #include <exec/execbase.h>
11 #include <hardware/intbits.h>
12 #include <proto/exec.h>
16 #include "kernel_base.h"
17 #include "kernel_debug.h"
18 #include "kernel_globals.h"
19 #include "kernel_interrupts.h"
20 #include "kernel_intern.h"
21 #include "kernel_intr.h"
22 #include "kernel_scheduler.h"
23 #include "kernel_syscall.h"
24 #include "cpu_traps.h"
29 #if (__WORDSIZE != 64)
30 extern void core_Kick(struct TagItem
*msg
, void *target
);
31 extern void kernel_cstart(const struct TagItem
*msg
);
34 int core_SysCallHandler(struct ExceptionContext
*regs
, struct KernelBase
*KernelBase
, void *HandlerData2
)
36 struct PlatformData
*pdata
= KernelBase
->kb_PlatformData
;
37 struct syscallx86_Handler
*scHandler
;
39 #if (__WORDSIZE == 64)
44 BOOL systemSysCall
= TRUE
;
46 /* Syscall number is actually ULONG (we use only eax) */
47 DSYSCALL(bug("[Kernel] %s: Syscall %08x\n", __func__
, sc
));
49 ForeachNode(&pdata
->kb_SysCallHandlers
, scHandler
)
51 if ((ULONG
)((IPTR
)scHandler
->sc_Node
.ln_Name
) == sc
)
53 DSYSCALL(bug("[Kernel] %s: calling handler @ 0x%p\n", __func__
, scHandler
));
54 scHandler
->sc_SysCall(regs
);
55 if (scHandler
->sc_Node
.ln_Type
== 1)
56 systemSysCall
= FALSE
;
60 if (systemSysCall
&& INTR_FROMUSERMODE
)
62 DSYSCALL(bug("[Kernel] %s: User-mode syscall\n", __func__
));
64 /* Disable interrupts for a while */
65 __asm__
__volatile__("cli; cld;");
67 core_SysCall(sc
, regs
);
70 DSYSCALL(bug("[Kernel] %s: Returning from syscall...\n", __func__
));
75 BOOL
krnAddSysCallHandler(struct PlatformData
*pdata
, struct syscallx86_Handler
*newscHandler
, BOOL custom
, BOOL force
)
77 struct syscallx86_Handler
*scHandler
;
79 D(bug("[Kernel] %s(%08x)\n", __func__
, newscHandler
->sc_Node
.ln_Name
));
81 /* Unless the 'force' flag is set, bale out if there is already a handler
82 * of the same type (note that we're not comparing strings here - ln_Name
86 ForeachNode(&pdata
->kb_SysCallHandlers
, scHandler
)
88 if (scHandler
->sc_Node
.ln_Name
== newscHandler
->sc_Node
.ln_Name
)
94 newscHandler
->sc_Node
.ln_Type
= 1;
96 newscHandler
->sc_Node
.ln_Type
= 0;
98 D(bug("[Kernel] %s: Registering handler...\n", __func__
));
99 AddTail(&pdata
->kb_SysCallHandlers
, &newscHandler
->sc_Node
);
104 /* Default x86 syscall handlers */
106 void X86_HandleChangePMStateSC(struct ExceptionContext
*regs
)
115 D(bug("[Kernel] %s(0x%02x)\n", __func__
, pmState
));
119 D(bug("[Kernel] %s: STATE 0xFF - Attempting Cold Reboot...\n", __func__
));
122 * On some machines (new PCs without a PS/2 controller), this might
128 else if (pmState
== 0)
130 D(bug("[Kernel] %s: STATE 0x00 - Halting...\n", __func__
));
133 there is no way to power off by default,
134 so just halt the cpu.. */
136 while (1) asm volatile("hlt");
138 else if (pmState
== 0x90)
140 /* Sleep almost forever ;) */
141 __asm__
__volatile__("sti; hlt; cli");
143 D(bug("[Kernel] %s: Woke from sleep; checking for softints...\n",
145 if (SysBase
->SysFlags
& SFF_SoftInt
)
146 core_Cause(INTB_SOFTINT
, 1L << INTB_SOFTINT
);
150 /* We can't handle any other states atm =/ */
151 D(bug("[Kernel] %s: UNHANDLED STATE 0x%02x\n", __func__
, pmState
));
155 struct syscallx86_Handler x86_SCChangePMStateHandler
=
158 .ln_Name
= (APTR
)SC_X86CHANGEPMSTATE
160 (APTR
)X86_HandleChangePMStateSC
163 /* Generic warm-reset handler */
165 void X86_HandleRebootSC()
167 D(bug("[Kernel] %s: Warm restart, stack 0x%p\n", __func__
, AROS_GET_SP
));
170 * Restart the kernel with a double stack swap. This doesn't return.
171 * Double swap guarantees that core_Kick() is called when SP is set to a
172 * dynamically allocated emergency stack and not to boot stack.
173 * Such situation is rare but can occur in the following situation:
174 * 1. Boot task calls SuperState(). Privilege changed, but stack is manually reset
175 * back into our .bss space.
176 * 2. Boot task crashes. Privilege doesn't change this time, ESP/RSP is not changed.
177 * 3. If we call core_Kick() right now, we are dead (core_Kick() clears .bss).
179 #if (__WORDSIZE == 64)
180 __asm__
__volatile__(
185 ::"r"(__KernBootPrivate
->SystemStack
+ STACK_SIZE
), "r"(core_Kick
), "D"(BootMsg
), "S"(kernel_cstart
));
187 __asm__
__volatile__(
194 ::"r"(0x1000), "r"(core_Kick
), "r"(BootMsg
), "r"(kernel_cstart
));
198 struct syscallx86_Handler x86_SCRebootHandler
=
201 .ln_Name
= (APTR
)SC_REBOOT
203 (APTR
)X86_HandleRebootSC
206 struct syscallx86_Handler x86_SCSupervisorHandler
=
209 .ln_Name
= (APTR
)SC_SUPERVISOR
211 (APTR
)core_Supervisor