2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: Display an alert.
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>
16 #include "exec_intern.h"
17 #include "exec_util.h"
20 /*****************************************************************************
27 AROS_LHA(ULONG
, alertNum
, D7
),
30 struct ExecBase
*, SysBase
, 18, Exec
)
33 Alerts the user of a serious system problem.
36 alertNum - This is a number which contains information about
37 the reason for the call.
40 This routine may return, if the alert is not a dead-end one.
43 You should not call this routine because it halts the machine,
44 displays the message and then may reboot it.
47 // Dead-End alert: 680x0 Access To Odd Address
56 ******************************************************************************/
60 Exec_ExtAlert(alertNum
, __builtin_return_address(0), CALLER_FRAME
, AT_NONE
, NULL
, SysBase
);
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
;
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
;
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
]);
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
));
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.
151 alertNum
= Exec_UserAlert(alertNum
, SysBase
);
155 * UserAlert() succeeded and the user decided to continue the task.
156 * Clear crash status and return happily
164 /* Hint for SystemAlert() - if AlertType is AT_NONE, we don't have AlertData */
169 * We're here if Intuition failed. Use safe (but not so
170 * system and user-friendly) way to post alerts.
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... */
180 ShutdownA(SD_ACTION_COLDREBOOT
);
186 * We successfully displayed an alert in supervisor mode.
187 * Clear alert status by clearing respective fields in ETask.