Revision 24c7b0e3 target-mips/helper.c

b/target-mips/helper.c
90 90
    if (user_mode && address > 0x7FFFFFFFUL)
91 91
        return TLBRET_BADADDR;
92 92
    if (address < (int32_t)0x80000000UL) {
93
        if (!(env->hflags & MIPS_HFLAG_ERL)) {
93
        if (!(env->CP0_Status & (1 << CP0St_ERL))) {
94 94
#ifdef MIPS_USES_R4K_TLB
95 95
            ret = map_address(env, physical, prot, address, rw, access_type);
96 96
#else
......
289 289
        goto set_DEPC;
290 290
    case EXCP_DDBL:
291 291
        env->CP0_Debug |= 1 << CP0DB_DDBL;
292
        goto set_DEPC;
293 292
    set_DEPC:
294 293
        if (env->hflags & MIPS_HFLAG_BMASK) {
295 294
            /* If the exception was raised from a delay slot,
296 295
               come back to the jump.  */
297 296
            env->CP0_DEPC = env->PC - 4;
298
            if (!(env->hflags & MIPS_HFLAG_EXL))
299
                env->CP0_Cause |= (1 << CP0Ca_BD);
300 297
            env->hflags &= ~MIPS_HFLAG_BMASK;
301 298
        } else {
302 299
            env->CP0_DEPC = env->PC;
303
            env->CP0_Cause &= ~(1 << CP0Ca_BD);
304 300
        }
305 301
    enter_debug_mode:
306 302
        env->hflags |= MIPS_HFLAG_DM;
303
        env->hflags &= ~MIPS_HFLAG_UM;
307 304
        /* EJTAG probe trap enable is not implemented... */
308 305
        env->PC = (int32_t)0xBFC00480;
309 306
        break;
......
311 308
        cpu_reset(env);
312 309
        break;
313 310
    case EXCP_SRESET:
314
        env->CP0_Status = (1 << CP0St_SR);
311
        env->CP0_Status |= (1 << CP0St_SR);
315 312
        env->CP0_WatchLo = 0;
316 313
        goto set_error_EPC;
317 314
    case EXCP_NMI:
318
        env->CP0_Status = (1 << CP0St_NMI);
315
        env->CP0_Status |= (1 << CP0St_NMI);
319 316
    set_error_EPC:
320 317
        if (env->hflags & MIPS_HFLAG_BMASK) {
321 318
            /* If the exception was raised from a delay slot,
322 319
               come back to the jump.  */
323 320
            env->CP0_ErrorEPC = env->PC - 4;
324
            if (!(env->hflags & MIPS_HFLAG_EXL))
325
                env->CP0_Cause |= (1 << CP0Ca_BD);
326 321
            env->hflags &= ~MIPS_HFLAG_BMASK;
327 322
        } else {
328 323
            env->CP0_ErrorEPC = env->PC;
329
            env->CP0_Cause &= ~(1 << CP0Ca_BD);
330 324
        }
331
        env->hflags |= MIPS_HFLAG_ERL;
332
	env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
325
        env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
326
        env->hflags &= ~MIPS_HFLAG_UM;
333 327
        env->PC = (int32_t)0xBFC00000;
334 328
        break;
335 329
    case EXCP_MCHECK:
......
350 344
        goto set_EPC;
351 345
    case EXCP_TLBL:
352 346
        cause = 2;
353
        if (env->error_code == 1 && !(env->hflags & MIPS_HFLAG_EXL))
347
        if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL)))
354 348
            offset = 0x000;
355 349
        goto set_EPC;
356 350
    case EXCP_IBE:
......
384 378
        goto set_EPC;
385 379
    case EXCP_TLBS:
386 380
        cause = 3;
387
        if (env->error_code == 1 && !(env->hflags & MIPS_HFLAG_EXL))
381
        if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL)))
388 382
            offset = 0x000;
389
        goto set_EPC;
390 383
    set_EPC:
391
        if (env->hflags & MIPS_HFLAG_BMASK) {
392
            /* If the exception was raised from a delay slot,
393
               come back to the jump.  */
394
            env->CP0_EPC = env->PC - 4;
395
            if (!(env->hflags & MIPS_HFLAG_EXL))
384
        if (!(env->CP0_Status & (1 << CP0St_EXL))) {
385
            if (env->hflags & MIPS_HFLAG_BMASK) {
386
                /* If the exception was raised from a delay slot,
387
                   come back to the jump.  */
388
                env->CP0_EPC = env->PC - 4;
396 389
                env->CP0_Cause |= (1 << CP0Ca_BD);
397
            env->hflags &= ~MIPS_HFLAG_BMASK;
390
                env->hflags &= ~MIPS_HFLAG_BMASK;
391
            } else {
392
                env->CP0_EPC = env->PC;
393
                env->CP0_Cause &= ~(1 << CP0Ca_BD);
394
            }
398 395
        } else {
399
            env->CP0_EPC = env->PC;
400
            env->CP0_Cause &= ~(1 << CP0Ca_BD);
396
            env->CP0_Status |= (1 << CP0St_EXL);
397
            env->hflags &= ~MIPS_HFLAG_UM;
401 398
        }
402 399
        if (env->CP0_Status & (1 << CP0St_BEV)) {
403 400
            env->PC = (int32_t)0xBFC00200;
404 401
        } else {
405 402
            env->PC = (int32_t)0x80000000;
406 403
        }
407
        env->hflags |= MIPS_HFLAG_EXL;
408
        env->CP0_Status |= (1 << CP0St_EXL);
409 404
        env->PC += offset;
410 405
        env->CP0_Cause = (env->CP0_Cause & ~0x7C) | (cause << 2);
411 406
        break;

Also available in: Unified diff