1193 |
1193 |
}
|
1194 |
1194 |
|
1195 |
1195 |
/*
|
|
1196 |
* Check nested exceptions and change to double or triple fault if
|
|
1197 |
* needed. It should only be called, if this is not an interrupt.
|
|
1198 |
* Returns the new exception number.
|
|
1199 |
*/
|
|
1200 |
int check_exception(int intno, int *error_code)
|
|
1201 |
{
|
|
1202 |
char first_contributory = env->old_exception == 0 ||
|
|
1203 |
(env->old_exception >= 10 &&
|
|
1204 |
env->old_exception <= 13);
|
|
1205 |
char second_contributory = intno == 0 ||
|
|
1206 |
(intno >= 10 && intno <= 13);
|
|
1207 |
|
|
1208 |
if (loglevel & CPU_LOG_INT)
|
|
1209 |
fprintf(logfile, "check_exception old: %x new %x\n",
|
|
1210 |
env->old_exception, intno);
|
|
1211 |
|
|
1212 |
if (env->old_exception == EXCP08_DBLE)
|
|
1213 |
cpu_abort(env, "triple fault");
|
|
1214 |
|
|
1215 |
if ((first_contributory && second_contributory)
|
|
1216 |
|| (env->old_exception == EXCP0E_PAGE &&
|
|
1217 |
(second_contributory || (intno == EXCP0E_PAGE)))) {
|
|
1218 |
intno = EXCP08_DBLE;
|
|
1219 |
*error_code = 0;
|
|
1220 |
}
|
|
1221 |
|
|
1222 |
if (second_contributory || (intno == EXCP0E_PAGE) ||
|
|
1223 |
(intno == EXCP08_DBLE))
|
|
1224 |
env->old_exception = intno;
|
|
1225 |
|
|
1226 |
return intno;
|
|
1227 |
}
|
|
1228 |
|
|
1229 |
/*
|
1196 |
1230 |
* Signal an interruption. It is executed in the main CPU loop.
|
1197 |
1231 |
* is_int is TRUE if coming from the int instruction. next_eip is the
|
1198 |
1232 |
* EIP value AFTER the interrupt instruction. It is only relevant if
|
... | ... | |
1201 |
1235 |
void raise_interrupt(int intno, int is_int, int error_code,
|
1202 |
1236 |
int next_eip_addend)
|
1203 |
1237 |
{
|
|
1238 |
if (!is_int)
|
|
1239 |
intno = check_exception(intno, &error_code);
|
|
1240 |
|
1204 |
1241 |
env->exception_index = intno;
|
1205 |
1242 |
env->error_code = error_code;
|
1206 |
1243 |
env->exception_is_int = is_int;
|
... | ... | |
1211 |
1248 |
/* same as raise_exception_err, but do not restore global registers */
|
1212 |
1249 |
static void raise_exception_err_norestore(int exception_index, int error_code)
|
1213 |
1250 |
{
|
|
1251 |
exception_index = check_exception(exception_index, &error_code);
|
|
1252 |
|
1214 |
1253 |
env->exception_index = exception_index;
|
1215 |
1254 |
env->error_code = error_code;
|
1216 |
1255 |
env->exception_is_int = 0;
|