Minor fixes to comments.
[AROS.git] / rom / exec / traphandler.c
blobe7e1f5363d67cc8769cd1ad4e9ef8f7cfbf31668
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 * NOTE: This is only called on ETasks!
21 static void Exec_CrashHandler(void)
23 struct Task *task = FindTask(NULL);
24 struct IntETask *iet = GetIntETask(task);
26 /* Makes Alert() attempting to bring up Intuition requester */
27 iet->iet_AlertFlags &= ~AF_Alert;
29 Alert(iet->iet_AlertCode);
32 /* In original AmigaOS the trap handler is entered in supervisor mode with the
33 * following on the supervisor stack:
34 * 0(sp).l = trap#
35 * 4(sp) Processor dependent exception frame
36 * In our current implementation we use two pointers on stack. The idea is taken
37 * from AmigaOS v4.
39 * For m68k, we need a thunk, since we will call this routine via
40 * the AOS 1.x-3.x method described above.
42 * See arch/m68k-all/kernel/m68k_exception.c for implementation details.
44 #ifdef __mc68000
45 asm (
46 " .text\n"
47 " .balign 2\n"
48 " .global Exec_TrapHandler\n"
49 "Exec_TrapHandler:\n"
50 " movem.l %d0-%d7/%a0-%a6,%sp@-\n" /* Save regs */
51 " move.l %sp@(15*4),%d0\n" /* Get trap code */
52 " move.l %usp,%a0\n" /* Get USP */
53 " move.l %a0,%sp@(15*4)\n" /* Fix up A7 to be USP */
54 " move.l %sp,%sp@-\n" /* Push on pointer to exception ctx */
55 " move.l %d0,%sp@-\n" /* Push on trap number */
56 " jsr Exec__TrapHandler\n" /* Call C routine */
57 " addq.l #8,%sp\n" /* Pop off C routine args */
58 " movem.l %sp@+,%d0-%d7/%a0-%a5\n" /* Restore registers */
59 " move.l %sp@(4), %a6\n"
60 " move.l %a6,%usp\n" /* Restore USP */
61 " move.l %sp@+,%a6\n" /* Restore A6 */
62 " addq.l #4,%sp\n" /* Skip past A7 */
63 " rte\n" /* Return from trap */
65 void Exec__TrapHandler(ULONG trapNum, struct ExceptionContext *ctx)
66 #else
67 void Exec_TrapHandler(ULONG trapNum, struct ExceptionContext *ctx)
68 #endif
70 struct Task *task = SysBase->ThisTask;
72 /* Our situation is deadend */
73 trapNum |= AT_DeadEnd;
76 * We must have a valid ETask in order to be able
77 * to display a requester in user mode.
79 if (task && (task->tc_Flags & TF_ETASK) && (task->tc_State != TS_REMOVED))
81 /* Get internal task structure */
82 struct IntETask *iet = GetIntETask(task);
84 if (iet->iet_AlertFlags & AF_Alert)
87 * Protection against double-crash. If the task is already in alert state, we have
88 * a second crash during processing the first one. Then we just pick up initial alert code
89 * and call Alert() with it in supervisor mode.
91 trapNum = iet->iet_AlertCode;
93 else
96 * Otherwise we can try to send the crash to user level.
98 * First mark crash condition, and also specify alert code for user-level handler.
99 * If we double-crash while jumping to user mode, we will know this (ETF_Alert will
100 * already be set)
102 iet->iet_AlertType = AT_CPU;
103 iet->iet_AlertFlags = AF_Alert|AF_Location;
104 iet->iet_AlertCode = trapNum;
105 iet->iet_AlertLocation = (APTR)ctx->PC; /* Location is our PC, where we crashed */
106 iet->iet_AlertStack = (APTR)ctx->FP; /* Remember also stack frame for backtrace */
109 * This is a CPU alert. We've got a full CPU context, so we remember it
110 * in our ETask structure for displaying to the user later.
111 * Note that we store only GPR part of the context. We don't copy
112 * attached FPU data (if any). This can be considered TODO.
114 CopyMem(ctx, &iet->iet_AlertData, sizeof(struct ExceptionContext));
117 * Make the task to jump to crash handler. We don't care about return address etc because
118 * the alert is deadend anyway.
120 ctx->PC = (IPTR)Exec_CrashHandler;
121 /* Let the task go */
122 return;
126 Exec_ExtAlert(trapNum, (APTR)ctx->PC, (APTR)ctx->FP, AT_CPU, ctx, SysBase);
127 } /* TrapHandler */