- Added missing exec parts
[AROS.git] / arch / all-mingw32 / kernel / host_intr.c
blobc66f8b96511a9a81151161988a28cc2cdbb2cd49
1 #include <aros/system.h>
2 #include <windows.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;
10 #include <stddef.h>
11 #include <stdio.h>
12 #include <exec/lists.h>
13 #include <exec/execbase.h>
14 #include "kernel_intern.h"
15 #include "syscall.h"
17 #define DS(x) x
18 #define SLOW
20 #define AROS_EXCEPTION_SYSCALL 0x80000001
22 struct SwitcherData {
23 HANDLE MainThread;
24 HANDLE IntTimer;
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;
36 if (KernelBase) {
37 if (!IsListEmpty(&KernelBase->kb_Exceptions[exception]))
39 struct IntrNode *in, *in2;
41 ForeachNodeSafe(&KernelBase->kb_Exceptions[exception], in, in2)
43 if (in->in_Handler)
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)
61 case SC_CAUSE:
62 if (SysBase)
63 core_Cause(SysBase);
64 break;
65 case SC_DISPATCH:
66 core_Dispatch(Except->ContextRecord);
67 break;
68 case SC_SWITCH:
69 core_Switch(Except->ContextRecord);
70 break;
71 case SC_SCHEDULE:
72 core_Schedule(Except->ContextRecord);
73 break;
75 return EXCEPTION_CONTINUE_EXECUTION;
76 default:
77 printf("[KRN] Exception 0x%08lX handler. Context @ %p, SysBase @ %p, KernelBase @ %p\n", Except->ExceptionRecord->ExceptionCode, Except->ContextRecord, SysBase, KernelBase);
78 if (SysBase)
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)
90 HANDLE IntEvent;
91 DWORD obj;
92 CONTEXT MainCtx;
93 D(BOOL res);
95 for (;;) {
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));
100 if (Ints_Enabled) {
101 DS(res =) GetThreadContext(args->MainThread, &MainCtx);
102 DS(printf("[Task switcher] Get context result: %ld\n", res));
103 user_handler(0);
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));
112 return 0;
115 /* ****** Interface functions ****** */
117 long __declspec(dllexport) core_intr_disable(void)
119 D(printf("[KRN] disabling interrupts\n"));
120 Ints_Enabled = 0;
123 long __declspec(dllexport) core_intr_enable(void)
125 D(printf("[KRN] enabling interrupts\n"));
126 Ints_Enabled = 1;
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)
136 HANDLE ThisProcess;
137 HANDLE SwitcherThread;
138 DWORD SwitcherId;
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);
153 #ifdef SLOW
154 TimerPeriod = 5000;
155 #else
156 TimerPeriod = 1000/TimerPeriod;
157 #endif
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");)
166 return 0;