grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / exec / alert.c
blob77a9dab0fa9c21b6910a3e232d45b180a176dd42
1 /*
2 Copyright © 1995-2016, 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 <proto/kernel.h>
15 #include <string.h>
17 #include "exec_intern.h"
18 #include "exec_util.h"
19 #include "etask.h"
21 /*****************************************************************************
23 NAME */
25 AROS_LH1(void, Alert,
27 /* SYNOPSIS */
28 AROS_LHA(ULONG, alertNum, D7),
30 /* LOCATION */
31 struct ExecBase *, SysBase, 18, Exec)
33 /* FUNCTION
34 Alerts the user of a serious system problem.
36 INPUTS
37 alertNum - This is a number which contains information about
38 the reason for the call.
40 RESULT
41 This routine may return, if the alert is not a dead-end one.
43 NOTES
44 You should not call this routine because it halts the machine,
45 displays the message and then may reboot it.
47 EXAMPLE
48 // Dead-End alert: 680x0 Access To Odd Address
49 Alert (0x80000003);
51 BUGS
53 SEE ALSO
55 INTERNALS
57 ******************************************************************************/
59 AROS_LIBFUNC_INIT
61 Exec_ExtAlert(alertNum, __builtin_return_address(0), CALLER_FRAME, AT_NONE, NULL, SysBase);
63 AROS_LIBFUNC_EXIT
66 static const ULONG contextSizes[] =
69 sizeof(struct ExceptionContext),
70 sizeof(struct MungwallContext),
71 sizeof(struct MMContext)
74 void Exec_ExtAlert(ULONG alertNum, APTR location, APTR stack, UBYTE type, APTR data, struct ExecBase *SysBase)
76 struct Task *task = GET_THIS_TASK;
77 int supervisor = KrnIsSuper();
78 BOOL usesystemalert = !!supervisor;
79 struct IntETask *iet = NULL;
81 D(bug("[exec] Alert 0x%08X, supervisor %d\n", alertNum, supervisor));
83 if (task && (task->tc_Flags & TF_ETASK) && (task->tc_State != TS_REMOVED))
85 iet = GetIntETask(task);
87 D(bug("[Alert] Task 0x%p, ETask 0x%p\n", task, iet));
89 /* Do we already have location set? */
90 if (iet->iet_AlertFlags & AF_Location)
92 /* If yes, pick it up */
93 location = iet->iet_AlertLocation;
94 stack = iet->iet_AlertStack;
96 else
98 if (supervisor && ((alertNum & ~AT_DeadEnd) == AN_StackProbe))
101 * Special case: AN_StackProbe issued by kernel's task dispatcher.
102 * Pick up data from task's context.
104 struct ExceptionContext *ctx = iet->iet_ETask.et_RegFrame;
106 location = (APTR)ctx->PC;
107 stack = (APTR)ctx->FP;
108 type = AT_CPU;
109 data = ctx;
112 /* Set location */
113 iet->iet_AlertFlags |= AF_Location;
114 iet->iet_AlertLocation = location;
115 iet->iet_AlertStack = stack;
117 D(bug("[Alert] Previous frame 0x%p, caller 0x%p\n", iet->iet_AlertStack, iet->iet_AlertLocation));
120 /* If this is not a nested call, set the supplementary data if specified */
121 if (data && !(iet->iet_AlertFlags & AF_Alert))
123 D(bug("[Alert] Setting alert context, type %u, data 0x%p\n", type, data));
125 iet->iet_AlertType = type;
126 CopyMem(data, &iet->iet_AlertData, contextSizes[type]);
128 else
130 /* Either no data or already present */
131 type = iet->iet_AlertType;
132 data = &iet->iet_AlertData;
134 D(bug("[Alert] Got stored alert context, type %u, data 0x%p\n", type, data));
137 else
140 * If we have no task, or the task is being removed,
141 * we can't use the user-mode routine.
143 usesystemalert = TRUE;
147 * If we are running in user mode we should first try to report a problem
148 * using Intuition display.
150 if (!usesystemalert)
152 alertNum = Exec_UserAlert(alertNum, SysBase);
153 if (!alertNum)
156 * UserAlert() succeeded and the user decided to continue the task.
157 * Clear crash status and return happily
159 if (iet)
160 ResetETask(iet);
161 return;
165 /* Hint for SystemAlert() - if AlertType is AT_NONE, we don't have AlertData */
166 if (type == AT_NONE)
167 data = NULL;
170 * We're here if Intuition failed. Use safe (but not so
171 * system and user-friendly) way to post alerts.
173 Disable();
174 Exec_SystemAlert(alertNum, location, stack, type, data, SysBase);
176 if (alertNum & AT_DeadEnd)
178 /* Um, we have to do something here in order to prevent the
179 computer from continuing... */
180 ColdReboot();
181 ShutdownA(SD_ACTION_COLDREBOOT);
184 Enable();
187 * We successfully displayed an alert in supervisor mode.
188 * Clear alert status by clearing respective fields in ETask.
190 if (iet)
191 ResetETask(iet);