1 #include <aros/system.h>
3 #define __typedef_LONG /* LONG, ULONG, WORD, BYTE and BOOL are declared in Windows headers. Looks like everything */
4 #define __typedef_WORD /* is the same except BOOL. It's defined to short on AROS and to int on Windows. This means */
5 #define __typedef_BYTE /* that you can't use it in OS-native part of the code and can't use any AROS structure */
6 #define __typedef_BOOL /* definition that contains BOOL. */
7 typedef unsigned AROS_16BIT_TYPE UWORD
;
8 typedef unsigned char UBYTE
;
12 #include <exec/lists.h>
13 #include <exec/execbase.h>
14 #include "kernel_intern.h"
20 #define AROS_EXCEPTION_SYSCALL 0x80000001
27 struct SwitcherData SwData
;
28 unsigned char Ints_Enabled
= 0;
29 struct ExecBase
**SysBasePtr
;
30 struct KernelBase
**KernelBasePtr
;
32 void user_handler(uint8_t exception
)
34 struct KernelBase
*KernelBase
= *KernelBasePtr
;
37 if (!IsListEmpty(&KernelBase
->kb_Exceptions
[exception
]))
39 struct IntrNode
*in
, *in2
;
41 ForeachNodeSafe(&KernelBase
->kb_Exceptions
[exception
], in
, in2
)
44 in
->in_Handler(in
->in_HandlerData
, in
->in_HandlerData2
);
51 LONG CALLBACK
ExceptionHandler(PEXCEPTION_POINTERS Except
)
53 struct ExecBase
*SysBase
= *SysBasePtr
;
54 struct KernelBase
*KernelBase
= *KernelBasePtr
;
56 switch (Except
->ExceptionRecord
->ExceptionCode
) {
57 case AROS_EXCEPTION_SYSCALL
:
58 D(printf("[KRN] Syscall exception %lu\n", *Except
->ExceptionRecord
->ExceptionInformation
));
59 switch (*Except
->ExceptionRecord
->ExceptionInformation
)
66 core_Dispatch(Except
->ContextRecord
);
69 core_Switch(Except
->ContextRecord
);
72 core_Schedule(Except
->ContextRecord
);
75 return EXCEPTION_CONTINUE_EXECUTION
;
77 printf("[KRN] Exception 0x%08lX handler. Context @ %p, SysBase @ %p, KernelBase @ %p\n", Except
->ExceptionRecord
->ExceptionCode
, Except
->ContextRecord
, SysBase
, KernelBase
);
80 struct Task
*t
= SysBase
->ThisTask
;
81 printf("[KRN] %s %p (%s)\n", t
->tc_Node
.ln_Type
== NT_TASK
? "Task":"Process", t
, t
->tc_Node
.ln_Name
? t
->tc_Node
.ln_Name
: "--unknown--");
83 printf("[KRN] **UNHANDLED EXCEPTION** stopping here...\n");
84 return EXCEPTION_EXECUTE_HANDLER
;
88 DWORD
TaskSwitcher(struct SwitcherData
*args
)
96 WaitForSingleObject(args
->IntTimer
, INFINITE
);
97 DS(printf("[Task switcher] Timer interrupt\n"));
98 DS(res
=) SuspendThread(args
->MainThread
);
99 DS(printf("[Task switcher] Suspend thread result: %ld\n", res
));
101 DS(res
=) GetThreadContext(args
->MainThread
, &MainCtx
);
102 DS(printf("[Task switcher] Get context result: %ld\n", res
));
104 core_ExitInterrupt(&MainCtx
);
105 D(res
=)SetThreadContext(args
->MainThread
, &MainCtx
);
106 DS(printf("[Task switcher] Set context result: %ld\n", res
));
108 DS(else printf("[KRN] Interrupts are disabled\n"));
109 DS(res
=) ResumeThread(args
->MainThread
);
110 DS(printf("[Task switcher] Resume thread result: %ld\n", res
));
115 /* ****** Interface functions ****** */
117 long __declspec(dllexport
) core_intr_disable(void)
119 D(printf("[KRN] disabling interrupts\n"));
123 long __declspec(dllexport
) core_intr_enable(void)
125 D(printf("[KRN] enabling interrupts\n"));
129 void __declspec(dllexport
) core_syscall(unsigned long n
)
131 RaiseException(AROS_EXCEPTION_SYSCALL
, 0, 1, &n
);
134 int __declspec(dllexport
) core_init(unsigned long TimerPeriod
, struct ExecBase
**SysBasePointer
, struct KernelBase
**KernelBasePointer
)
137 HANDLE SwitcherThread
;
139 LARGE_INTEGER VBLPeriod
;
141 D(printf("[KRN] Setting up interrupts, SysBasePtr = 0x%08lX, KernelBasePtr = 0x%08lX\n", SysBasePointer
, KernelBasePointer
));
142 SysBasePtr
= SysBasePointer
;
143 KernelBasePtr
= KernelBasePointer
;
144 SetUnhandledExceptionFilter(ExceptionHandler
);
145 SwData
.IntTimer
= CreateWaitableTimer(NULL
, 0, NULL
);
146 if (SwData
.IntTimer
) {
147 ThisProcess
= GetCurrentProcess();
148 if (DuplicateHandle(ThisProcess
, GetCurrentThread(), ThisProcess
, &SwData
.MainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
)) {
149 SwitcherThread
= CreateThread(NULL
, 0, (LPTHREAD_START_ROUTINE
)TaskSwitcher
, &SwData
, 0, &SwitcherId
);
150 if (SwitcherThread
) {
151 D(printf("[KRN] Task switcher started\n"));
152 CloseHandle(SwitcherThread
);
156 TimerPeriod
= 1000/TimerPeriod
;
158 VBLPeriod
.QuadPart
= -10000*(LONGLONG
)TimerPeriod
;
159 return SetWaitableTimer(SwData
.IntTimer
, &VBLPeriod
, TimerPeriod
, NULL
, NULL
, 0);
161 D(else printf("[KRN] Failed to run task switcher thread\n");)
163 D(else printf("[KRN] failed to get thread handle\n");)
165 D(else printf("[KRN] failed to create VBlank timer\n");)