2 Copyright © 1995-2011, 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
= SysBase
->ThisTask
;
77 struct IntETask
*iet
= NULL
;
78 int supervisor
= KrnIsSuper();
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
));
138 * If we have no task, or the task is being removed,
139 * we can't use the user-mode routine.
144 * If we are running in user mode we should first try to report a problem
145 * using Intuition display.
149 alertNum
= Exec_UserAlert(alertNum
, SysBase
);
153 * UserAlert() succeeded and the user decided to continue the task.
154 * Clear crash status and return happily
161 /* Hint for SystemAlert() - if AlertType is AT_NONE, we don't have AlertData */
166 * We're here if Intuition failed. Use safe (but not so
167 * system and user-friendly) way to post alerts.
170 Exec_SystemAlert(alertNum
, location
, stack
, type
, data
, SysBase
);
173 if (alertNum
& AT_DeadEnd
)
175 /* Um, we have to do something here in order to prevent the
176 computer from continuing... */
178 ShutdownA(SD_ACTION_COLDREBOOT
);
182 * We succesfully displayed an alert in supervisor mode.
183 * Clear alert status by clearing respective fields in ETask.