2 Copyright © 1995-2016, 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>
14 #include <proto/kernel.h>
17 #include "exec_intern.h"
18 #include "exec_util.h"
21 /*****************************************************************************
28 AROS_LHA(ULONG
, alertNum
, D7
),
31 struct ExecBase
*, SysBase
, 18, Exec
)
34 Alerts the user of a serious system problem.
37 alertNum - This is a number which contains information about
38 the reason for the call.
41 This routine may return, if the alert is not a dead-end one.
44 You should not call this routine because it halts the machine,
45 displays the message and then may reboot it.
48 // Dead-End alert: 680x0 Access To Odd Address
57 ******************************************************************************/
61 Exec_ExtAlert(alertNum
, __builtin_return_address(0), CALLER_FRAME
, AT_NONE
, NULL
, SysBase
);
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
;
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
;
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
]);
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
));
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.
152 alertNum
= Exec_UserAlert(alertNum
, SysBase
);
156 * UserAlert() succeeded and the user decided to continue the task.
157 * Clear crash status and return happily
165 /* Hint for SystemAlert() - if AlertType is AT_NONE, we don't have AlertData */
170 * We're here if Intuition failed. Use safe (but not so
171 * system and user-friendly) way to post alerts.
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... */
181 ShutdownA(SD_ACTION_COLDREBOOT
);
187 * We successfully displayed an alert in supervisor mode.
188 * Clear alert status by clearing respective fields in ETask.