Revision d532b26c

b/cpu-exec.c
449 449
                        next_tb = 0;
450 450
                    }
451 451
#elif defined(TARGET_SPARC)
452
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
453
			cpu_interrupts_enabled(env)) {
454
			int pil = env->interrupt_index & 15;
455
			int type = env->interrupt_index & 0xf0;
456

  
457
			if (((type == TT_EXTINT) &&
458
			     (pil == 15 || pil > env->psrpil)) ||
459
			    type != TT_EXTINT) {
460
			    env->interrupt_request &= ~CPU_INTERRUPT_HARD;
461
                            env->exception_index = env->interrupt_index;
462
                            do_interrupt(env);
463
			    env->interrupt_index = 0;
464
                        next_tb = 0;
465
			}
452
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
453
                        if (cpu_interrupts_enabled(env) &&
454
                            env->interrupt_index > 0) {
455
                            int pil = env->interrupt_index & 0xf;
456
                            int type = env->interrupt_index & 0xf0;
457

  
458
                            if (((type == TT_EXTINT) &&
459
                                  cpu_pil_allowed(env, pil)) ||
460
                                  type != TT_EXTINT) {
461
                                env->exception_index = env->interrupt_index;
462
                                do_interrupt(env);
463
                                next_tb = 0;
464
                            }
465
                        }
466 466
		    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
467 467
			//do_interrupt(0, 0, 0, 0, 0);
468 468
			env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
b/hw/sun4u.c
232 232

  
233 233
void cpu_check_irqs(CPUState *env)
234 234
{
235
    uint32_t pil = env->pil_in | (env->softint & ~SOFTINT_TIMER) |
236
        ((env->softint & SOFTINT_TIMER) << 14);
235
    uint32_t pil = env->pil_in |
236
                  (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
237

  
238
    /* check if TM or SM in SOFTINT are set
239
       setting these also causes interrupt 14 */
240
    if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
241
        pil |= 1 << 14;
242
    }
243

  
244
    if (!pil) {
245
        if (env->interrupt_request & CPU_INTERRUPT_HARD) {
246
            CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
247
                           env->interrupt_index);
248
            env->interrupt_index = 0;
249
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
250
        }
251
        return;
252
    }
253

  
254
    if (cpu_interrupts_enabled(env)) {
237 255

  
238
    if (pil && (env->interrupt_index == 0 ||
239
                (env->interrupt_index & ~15) == TT_EXTINT)) {
240 256
        unsigned int i;
241 257

  
242
        for (i = 15; i > 0; i--) {
258
        for (i = 15; i > env->psrpil; i--) {
243 259
            if (pil & (1 << i)) {
244 260
                int old_interrupt = env->interrupt_index;
245

  
246
                env->interrupt_index = TT_EXTINT | i;
247
                if (old_interrupt != env->interrupt_index) {
248
                    CPUIRQ_DPRINTF("Set CPU IRQ %d\n", i);
261
                int new_interrupt = TT_EXTINT | i;
262

  
263
                if (env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt) {
264
                    CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
265
                                   "current %x >= pending %x\n",
266
                                   env->tl, cpu_tsptr(env)->tt, new_interrupt);
267
                } else if (old_interrupt != new_interrupt) {
268
                    env->interrupt_index = new_interrupt;
269
                    CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i,
270
                                   old_interrupt, new_interrupt);
249 271
                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
250 272
                }
251 273
                break;
252 274
            }
253 275
        }
254
    } else if (!pil && (env->interrupt_index & ~15) == TT_EXTINT) {
255
        CPUIRQ_DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
256
        env->interrupt_index = 0;
257
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
276
    } else {
277
        CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
278
                       "current interrupt %x\n",
279
                       pil, env->pil_in, env->softint, env->interrupt_index);
258 280
    }
259 281
}
260 282

  
b/target-sparc/cpu.h
577 577
    return 0;
578 578
}
579 579

  
580
static inline int cpu_pil_allowed(CPUState *env1, int pil)
581
{
582
#if !defined(TARGET_SPARC64)
583
    /* level 15 is non-maskable on sparc v8 */
584
    return pil == 15 || pil > env1->psrpil;
585
#else
586
    return pil > env1->psrpil;
587
#endif
588
}
589

  
580 590
static inline int cpu_fpu_enabled(CPUState *env1)
581 591
{
582 592
#if defined(CONFIG_USER_ONLY)

Also available in: Unified diff