revert between 56095 -> 55830 in arch
[AROS.git] / rom / exec / alert.c
blobd8c07d288b69fa855c06b083cad80b1b15149f57
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Display an alert.
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <exec/alerts.h>
11 #include <exec/execbase.h>
12 #include <exec/rawfmt.h>
13 #include <proto/exec.h>
14 #include <string.h>
16 #include "exec_intern.h"
17 #include "exec_util.h"
18 #include "etask.h"
20 /*****************************************************************************
22 NAME */
24 AROS_LH1(void, Alert,
26 /* SYNOPSIS */
27 AROS_LHA(ULONG, alertNum, D7),
29 /* LOCATION */
30 struct ExecBase *, SysBase, 18, Exec)
32 /* FUNCTION
33 Alerts the user of a serious system problem.
35 INPUTS
36 alertNum - This is a number which contains information about
37 the reason for the call.
39 RESULT
40 This routine may return, if the alert is not a dead-end one.
42 NOTES
43 You should not call this routine because it halts the machine,
44 displays the message and then may reboot it.
46 EXAMPLE
47 // Dead-End alert: 680x0 Access To Odd Address
48 Alert (0x80000003);
50 BUGS
52 SEE ALSO
54 INTERNALS
56 ******************************************************************************/
58 AROS_LIBFUNC_INIT
60 Exec_ExtAlert(alertNum, __builtin_return_address(0), CALLER_FRAME, AT_NONE, NULL, SysBase);
62 AROS_LIBFUNC_EXIT
65 static const ULONG contextSizes[] =
68 sizeof(struct ExceptionContext),
69 sizeof(struct MungwallContext),
70 sizeof(struct MMContext)
73 void Exec_ExtAlert(ULONG alertNum, APTR location, APTR stack, UBYTE type, APTR data, struct ExecBase *SysBase)
75 struct Task *task = GET_THIS_TASK;
76 int supervisor = KrnIsSuper();
77 BOOL usesystemalert = !!supervisor;
78 struct IntETask *iet = NULL;
80 D(bug("[exec] Alert 0x%08X, supervisor %d\n", alertNum, supervisor));
82 if (task && (task->tc_Flags & TF_ETASK) && (task->tc_State != TS_REMOVED))
84 iet = GetIntETask(task);
86 D(bug("[Alert] Task 0x%p, ETask 0x%p\n", task, iet));
88 /* Do we already have location set? */
89 if (iet->iet_AlertFlags & AF_Location)
91 /* If yes, pick it up */
92 location = iet->iet_AlertLocation;
93 stack = iet->iet_AlertStack;
95 else
97 if (supervisor && ((alertNum & ~AT_DeadEnd) == AN_StackProbe))
100 * Special case: AN_StackProbe issued by kernel's task dispatcher.
101 * Pick up data from task's context.
103 struct ExceptionContext *ctx = iet->iet_ETask.et_RegFrame;
105 location = (APTR)ctx->PC;
106 stack = (APTR)ctx->FP;
107 type = AT_CPU;
108 data = ctx;
111 /* Set location */
112 iet->iet_AlertFlags |= AF_Location;
113 iet->iet_AlertLocation = location;
114 iet->iet_AlertStack = stack;
116 D(bug("[Alert] Previous frame 0x%p, caller 0x%p\n", iet->iet_AlertStack, iet->iet_AlertLocation));
119 /* If this is not a nested call, set the supplementary data if specified */
120 if (data && !(iet->iet_AlertFlags & AF_Alert))
122 D(bug("[Alert] Setting alert context, type %u, data 0x%p\n", type, data));
124 iet->iet_AlertType = type;
125 CopyMem(data, &iet->iet_AlertData, contextSizes[type]);
127 else
129 /* Either no data or already present */
130 type = iet->iet_AlertType;
131 data = &iet->iet_AlertData;
133 D(bug("[Alert] Got stored alert context, type %u, data 0x%p\n", type, data));
136 else
139 * If we have no task, or the task is being removed,
140 * we can't use the user-mode routine.
142 usesystemalert = TRUE;
146 * If we are running in user mode we should first try to report a problem
147 * using Intuition display.
149 if (!usesystemalert)
151 alertNum = Exec_UserAlert(alertNum, SysBase);
152 if (!alertNum)
155 * UserAlert() succeeded and the user decided to continue the task.
156 * Clear crash status and return happily
158 if (iet)
159 ResetETask(iet);
160 return;
164 /* Hint for SystemAlert() - if AlertType is AT_NONE, we don't have AlertData */
165 if (type == AT_NONE)
166 data = NULL;
169 * We're here if Intuition failed. Use safe (but not so
170 * system and user-friendly) way to post alerts.
172 Disable();
173 Exec_SystemAlert(alertNum, location, stack, type, data, SysBase);
175 if (alertNum & AT_DeadEnd)
177 /* Um, we have to do something here in order to prevent the
178 computer from continuing... */
179 ColdReboot();
180 ShutdownA(SD_ACTION_COLDREBOOT);
183 Enable();
186 * We successfully displayed an alert in supervisor mode.
187 * Clear alert status by clearing respective fields in ETask.
189 if (iet)
190 ResetETask(iet);