Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / arch / all-mingw32 / kernel / kernel_intr.c
blobeb68ca0e444607f756ed21426d8295f736f1e304
1 /*
2 * Architecture-specific interrupt processing. We reimplement
3 * core_ExitInterrupt() because of non-typical idle loop implementation,
4 * hence the file name.
5 */
7 #include <exec/execbase.h>
8 #include <hardware/intbits.h>
9 #include <proto/exec.h>
11 #include <inttypes.h>
13 #include "kernel_base.h"
14 #include "kernel_debug.h"
15 #include "kernel_interrupts.h"
16 #include "kernel_intr.h"
17 #include "kernel_mingw32.h"
18 #include "kernel_scheduler.h"
19 #include "kernel_syscall.h"
20 #include "kernel_timer.h"
21 #include "kernel_traps.h"
23 #define D(x) /* This may lock up. See notes in host_intr.c */
24 #define DSC(x)
25 #define DTRAP(x)
27 #define IRET return (SysBase->IDNestCnt < 0) ? INT_ENABLE : INT_DISABLE
30 * Leave the interrupt. This function receives the register frame used to leave the supervisor
31 * mode. It reschedules the task if it was asked for.
32 * This implementation differs from generic one because Windows-hosted AROS has very specific
33 * idle loop implementation.
35 void core_ExitInterrupt(CONTEXT *regs)
37 D(bug("[Scheduler] core_ExitInterrupt\n"));
39 /* Soft interrupt requested? It's high time to do it */
40 if (SysBase->SysFlags & SFF_SoftInt)
42 D(bug("[Scheduler] Causing SoftInt\n"));
43 core_Cause(INTB_SOFTINT, 1L << INTB_SOFTINT);
46 /* No tasks active (AROS is in idle state)? If yes, just pick up
47 a new ready task (if there is any) */
48 if (Sleep_Mode != SLEEP_MODE_OFF)
50 cpu_Dispatch(regs);
51 return;
54 /* If task switching is disabled, leave immediatelly */
55 D(bug("[Scheduler] TDNestCnt is %d\n", SysBase->TDNestCnt));
56 if (SysBase->TDNestCnt < 0)
58 /*
59 * Do not disturb task if it's not necessary.
60 * Reschedule only if switch pending flag is set. Exit otherwise.
62 if (SysBase->AttnResched & ARF_AttnSwitch)
64 D(bug("[Scheduler] Rescheduling\n"));
65 if (core_Schedule())
67 cpu_Switch(regs);
68 cpu_Dispatch(regs);
74 /* This entry point is called by host-side DLL when an IRQ arrives */
75 int core_IRQHandler(unsigned char *irqs, CONTEXT *regs)
77 struct IntrNode *in, *in2;
79 /* Run handlers for all active IRQs */
80 ForeachNodeSafe(KernelBase->kb_Interrupts, in, in2)
82 irqhandler_t h = in->in_Handler;
84 if (h && (irqs[in->in_nr]))
85 h(in->in_HandlerData, in->in_HandlerData2);
88 /* Timer IRQ is also used to emulate exec VBlank */
89 if (irqs[IRQ_TIMER])
90 core_TimerTick();
92 /* Reschedule tasks and exit */
93 core_ExitInterrupt(regs);
94 IRET;
97 /* Trap handler entry point */
98 int core_TrapHandler(unsigned int num, IPTR *args, CONTEXT *regs)
100 void (*trapHandler)(unsigned long, struct ExceptionContext *) = NULL;
101 struct ExceptionTranslation *ex;
102 struct AROSCPUContext *ctx;
104 switch (num)
106 case AROS_EXCEPTION_SYSCALL:
107 /* It's a SysCall exception issued by core_raise() */
108 DSC(bug("[KRN] SysCall 0x%04X\n", args[0]));
109 switch(args[0])
111 case SC_SCHEDULE:
112 if (!core_Schedule())
113 break;
115 case SC_SWITCH:
116 cpu_Switch(regs);
118 case SC_DISPATCH:
119 cpu_Dispatch(regs);
120 break;
122 case SC_CAUSE:
123 core_ExitInterrupt(regs);
124 break;
126 break;
128 case AROS_EXCEPTION_RESUME:
129 /* Restore saved context and continue */
130 ctx = (struct AROSCPUContext *)args[0];
131 RESTOREREGS(regs, ctx);
132 *LastErrorPtr = ctx->LastError;
133 break;
135 default:
136 /* It's something else, likely a CPU trap */
137 bug("[KRN] Exception 0x%08lX, SysBase 0x%p, KernelBase 0x%p\n", num, SysBase, KernelBase);
139 /* Find out trap handler for caught task */
140 if (SysBase)
142 struct Task *t = SysBase->ThisTask;
144 if (t)
146 bug("[KRN] %s 0x%p (%s)\n", t->tc_Node.ln_Type == NT_TASK ? "Task":"Process", t, t->tc_Node.ln_Name ? t->tc_Node.ln_Name : "--unknown--");
147 trapHandler = t->tc_TrapCode;
148 D(bug("[KRN] Task trap handler 0x%p\n", trapHandler));
150 else
151 bug("[KRN] No task\n");
153 DTRAP(bug("[KRN] Exec trap handler 0x%p\n", SysBase->TaskTrapCode));
154 if (!trapHandler)
155 trapHandler = SysBase->TaskTrapCode;
158 PRINT_CPUCONTEXT(regs);
160 /* Translate Windows exception code to CPU and exec trap numbers */
161 for (ex = Traps; ex->ExceptionCode; ex++)
163 if (num == ex->ExceptionCode)
164 break;
166 DTRAP(bug("[KRN] CPU exception %d, AROS exception %d\n", ex->CPUTrap, ex->AROSTrap));
168 /* Convert CPU context to AROS structure */
169 struct ExceptionContext tmpContext;
170 TRAP_SAVEREGS(regs, tmpContext);
174 if (ex->CPUTrap != -1)
176 if (krnRunExceptionHandlers(ex->CPUTrap, &tmpContext))
177 break;
180 if (trapHandler && (ex->AmigaTrap != -1))
182 /* Call our trap handler. Note that we may return, this means that the handler has
183 fixed the problem somehow and we may safely continue */
184 DTRAP(bug("[KRN] Amiga trap %d\n", ex->AmigaTrap));
185 trapHandler(ex->AmigaTrap, &tmpContext);
187 break;
190 /* If we reach here, the trap is unhandled and we request the virtual machine to stop */
191 return INT_HALT;
192 } while(0);
194 TRAP_RESTOREREGS(regs, tmpContext);
197 IRET;