Revision 39d51eb8

b/hw/mips_int.c
20 20

  
21 21
void cpu_mips_irq_request(void *opaque, int irq, int level)
22 22
{
23
    CPUState *env = first_cpu;
24
   
25
    uint32_t mask;
23
    CPUState *env = (CPUState *)opaque;
26 24

  
27
    if (irq >= 16)
25
    if (irq < 0 || irq > 7)
28 26
        return;
29 27

  
30
    mask = 1 << (irq + CP0Ca_IP);
31

  
32 28
    if (level) {
33
        env->CP0_Cause |= mask;
29
        env->CP0_Cause |= 1 << (irq + CP0Ca_IP);
34 30
    } else {
35
        env->CP0_Cause &= ~mask;
31
        env->CP0_Cause &= ~(1 << (irq +CP0Ca_IP));
36 32
    }
37 33
    cpu_mips_update_irq(env);
38 34
}
39

  
b/hw/mips_timer.c
28 28
    uint64_t now, next;
29 29
    uint32_t tmp;
30 30

  
31
    if (env->CP0_Cause & (1 << CP0Ca_DC))
32
        return;
33

  
31 34
    tmp = count;
32 35
    if (count == compare)
33 36
        tmp++;
......
57 60
void cpu_mips_store_compare (CPUState *env, uint32_t value)
58 61
{
59 62
    cpu_mips_update_count(env, cpu_mips_get_count(env), value);
63
    if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
64
        env->CP0_Cause &= ~(1 << CP0Ca_TI);
60 65
    cpu_mips_irq_request(env, 7, 0);
61 66
}
62 67

  
......
71 76
    }
72 77
#endif
73 78
    cpu_mips_update_count(env, cpu_mips_get_count(env), env->CP0_Compare);
79
    if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
80
        env->CP0_Cause |= 1 << CP0Ca_TI;
74 81
    cpu_mips_irq_request(env, 7, 1);
75 82
}
76 83

  
b/target-mips/helper.c
295 295
            /* If the exception was raised from a delay slot,
296 296
               come back to the jump.  */
297 297
            env->CP0_DEPC = env->PC - 4;
298
            if (!(env->hflags & MIPS_HFLAG_EXL))
299
                env->CP0_Cause |= (1 << CP0Ca_BD);
298 300
            env->hflags &= ~MIPS_HFLAG_BMASK;
299 301
        } else {
300 302
            env->CP0_DEPC = env->PC;
303
            env->CP0_Cause &= ~(1 << CP0Ca_BD);
301 304
        }
302 305
    enter_debug_mode:
303 306
        env->hflags |= MIPS_HFLAG_DM;
......
318 321
            /* If the exception was raised from a delay slot,
319 322
               come back to the jump.  */
320 323
            env->CP0_ErrorEPC = env->PC - 4;
324
            if (!(env->hflags & MIPS_HFLAG_EXL))
325
                env->CP0_Cause |= (1 << CP0Ca_BD);
321 326
            env->hflags &= ~MIPS_HFLAG_BMASK;
322 327
        } else {
323 328
            env->CP0_ErrorEPC = env->PC;
329
            env->CP0_Cause &= ~(1 << CP0Ca_BD);
324 330
        }
325 331
        env->hflags |= MIPS_HFLAG_ERL;
326 332
	env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
......
364 370
        goto set_EPC;
365 371
    case EXCP_CpU:
366 372
        cause = 11;
367
        env->CP0_Cause = (env->CP0_Cause & ~0x03000000) | (env->error_code << 28);
373
        env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) |
374
                         (env->error_code << CP0Ca_CE);
368 375
        goto set_EPC;
369 376
    case EXCP_OVERFLOW:
370 377
        cause = 12;
......
385 392
            /* If the exception was raised from a delay slot,
386 393
               come back to the jump.  */
387 394
            env->CP0_EPC = env->PC - 4;
388
            env->CP0_Cause |= 0x80000000;
395
            if (!(env->hflags & MIPS_HFLAG_EXL))
396
                env->CP0_Cause |= (1 << CP0Ca_BD);
389 397
            env->hflags &= ~MIPS_HFLAG_BMASK;
390 398
        } else {
391 399
            env->CP0_EPC = env->PC;
392
            env->CP0_Cause &= ~0x80000000;
400
            env->CP0_Cause &= ~(1 << CP0Ca_BD);
393 401
        }
394 402
        if (env->CP0_Status & (1 << CP0St_BEV)) {
395 403
            env->PC = (int32_t)0xBFC00200;
b/target-mips/op.c
1397 1397

  
1398 1398
void op_mtc0_cause (void)
1399 1399
{
1400
    env->CP0_Cause = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x00C00300);
1400
    uint32_t mask = 0x00C00300;
1401

  
1402
    if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
1403
        mask |= 1 << CP0Ca_DC;
1404

  
1405
    env->CP0_Cause = (env->CP0_Cause & 0xFCC0FF7C) | (T0 & mask);
1401 1406

  
1402 1407
    /* Handle the software interrupt as an hardware one, as they
1403 1408
       are very similar */

Also available in: Unified diff