Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / rom / exec / traphandler.c
blobc98b27aa54a3acd2162db89086aebea094b45991
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Default trap handler
6 Lang: english
7 */
9 #include <exec/alerts.h>
10 #include <exec/interrupts.h>
11 #include <exec/tasks.h>
12 #include <proto/exec.h>
14 #include "etask.h"
15 #include "exec_intern.h"
16 #include "exec_util.h"
18 /* User-mode code where the task jumps to */
19 static void Exec_CrashHandler(void)
21 struct Task *task = FindTask(NULL);
22 struct IntETask *iet = GetIntETask(task);
24 iet->iet_AlertFlags &= ~AF_Alert; /* Makes Alert() attempting to bring up Intuition requester */
26 Alert(iet->iet_AlertCode);
29 /* In original AmigaOS the trap handler is entered in supervisor mode with the
30 * following on the supervisor stack:
31 * 0(sp).l = trap#
32 * 4(sp) Processor dependent exception frame
33 * In our current implementation we use two pointers on stack. The idea is taken
34 * from AmigaOS v4.
36 * For m68k, we need a thunk, since we will call this routine via
37 * the AOS 1.x-3.x method described above.
39 * See arch/m68k-all/kernel/m68k_exception.c for implementation details.
41 #ifdef __mc68000
42 asm (
43 " .text\n"
44 " .balign 2\n"
45 " .global Exec_TrapHandler\n"
46 "Exec_TrapHandler:\n"
47 " move.l #0,%sp@-\n" /* Push on a NULL trapcode */
48 " movem.l %d0-%d7/%a0-%a7,%sp@-\n" /* Save regs */
49 " move.l %usp,%a0\n" /* Get USP */
50 " move.l %a0,%sp@(15*4)\n" /* Fix up A7 to be USP */
51 " move.l %sp@(17*4),%d0\n" /* Get the trap number */
52 " move.l %sp,%sp@-\n" /* Push on pointer to exception ctx */
53 " move.l %d0,%sp@-\n" /* Push on trap number */
54 " jsr Exec__TrapHandler\n" /* Call C routine */
55 " addq.l #8,%sp\n" /* Pop off C routine args */
56 " movem.l %sp@+,%d0-%d7/%a0-%a5\n" /* Restore registers */
57 " move.l %sp@(4), %a6\n"
58 " move.l %a6,%usp\n" /* Restore USP */
59 " move.l %sp@+,%a6\n" /* Restore A6 */
60 " addq.l #4,%sp\n" /* Skip past A7 */
61 " addq.l #8,%sp\n" /* Skip past trapcode and traparg */
62 " rte\n" /* Return from trap */
64 void Exec__TrapHandler(ULONG trapNum, struct ExceptionContext *ctx)
65 #else
66 void Exec_TrapHandler(ULONG trapNum, struct ExceptionContext *ctx)
67 #endif
69 struct Task *task = SysBase->ThisTask;
71 /* Our situation is deadend */
72 trapNum |= AT_DeadEnd;
75 * We must have a valid ETask in order to be able
76 * to display a requester in user mode.
78 if (task && (task->tc_Flags & TF_ETASK) && (task->tc_State != TS_REMOVED))
80 /* Get internal task structure */
81 struct IntETask *iet = GetIntETask(task);
84 * Protection against double-crash. If the task is already in alert state, we have
85 * a second crash during processing the first one. Then we just pick up initial alert code
86 * and call Alert() with it in supervisor mode.
88 if (iet->iet_AlertFlags & AF_Alert)
89 trapNum = iet->iet_AlertCode;
92 * Workaround for i386-native. There trap handler already runs in user mode (BAD!),
93 * and it gets NULL as context pointer (this port saves CPU context in own format,
94 * which is TWICE BAD!!!)
95 * All this needs to be fixed.
97 else if (ctx)
100 * Otherwise we can try to send the crash to user level.
102 * First mark crash condition, and also specify alert code for user-level handler.
103 * If we double-crash while jumping to user mode, we will know this (ETF_Alert will
104 * already be set)
106 iet->iet_AlertType = AT_CPU;
107 iet->iet_AlertFlags = AF_Alert|AF_Location;
108 iet->iet_AlertCode = trapNum;
109 iet->iet_AlertLocation = (APTR)ctx->PC; /* Location is our PC, where we crashed */
110 iet->iet_AlertStack = (APTR)ctx->FP; /* Remember also stack frame for backtrace */
113 * This is a CPU alert. We've got a full CPU context, so we remember it
114 * in our ETask structure for displaying to the user later.
115 * Note that we store only GPR part of the context. We don't copy
116 * attached FPU data (if any). This can be considered TODO.
118 CopyMem(ctx, &iet->iet_AlertData, sizeof(struct ExceptionContext));
121 * Make the task to jump to crash handler. We don't care about return address etc because
122 * the alert is deadend anyway.
124 ctx->PC = (IPTR)Exec_CrashHandler;
125 /* Let the task go */
126 return;
130 Exec_ExtAlert(trapNum, ctx ? (APTR)ctx->PC : NULL, ctx ? (APTR)ctx->FP : NULL, AT_CPU, ctx, SysBase);
131 } /* TrapHandler */