void cpu_intr(struct trapframe *tf) { struct intr_event *event; register_t cause, status; int hard, i, intr; critical_enter(); cause = mips_rd_cause(); status = mips_rd_status(); intr = (cause & MIPS_INT_MASK) >> 8; /* * Do not handle masked interrupts. They were masked by * pre_ithread function (mips_mask_XXX_intr) and will be * unmasked once ithread is through with handler */ intr &= (status & MIPS_INT_MASK) >> 8; while ((i = fls(intr)) != 0) { intr &= ~(1 << (i - 1)); switch (i) { case 1: case 2: /* Software interrupt. */ i--; /* Get a 0-offset interrupt. */ hard = 0; event = softintr_events[i]; mips_intrcnt_inc(mips_intr_counters[i]); break; default: /* Hardware interrupt. */ i -= 2; /* Trim software interrupt bits. */ i--; /* Get a 0-offset interrupt. */ hard = 1; event = hardintr_events[i]; mips_intrcnt_inc(mips_intr_counters[NSOFT_IRQS + i]); break; } if (!event || TAILQ_EMPTY(&event->ie_handlers)) { printf("stray %s interrupt %d\n", hard ? "hard" : "soft", i); continue; } if (intr_event_handle(event, tf) != 0) { printf("stray %s interrupt %d\n", hard ? "hard" : "soft", i); } } KASSERT(i == 0, ("all interrupts handled")); critical_exit(); #ifdef HWPMC_HOOKS if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, tf); #endif }
/* * A very short dispatch, to try and maximise assembler code use * between all exception types. Maybe 'true' interrupts should go * here, and the trap code can come in separately */ void powerpc_interrupt(struct trapframe *framep) { struct thread *td; struct trapframe *oldframe; register_t ee; td = curthread; CTR2(KTR_INTR, "%s: EXC=%x", __func__, framep->exc); switch (framep->exc) { case EXC_EXI: critical_enter(); PIC_DISPATCH(root_pic, framep); critical_exit(); break; case EXC_DECR: critical_enter(); atomic_add_int(&td->td_intr_nesting_level, 1); oldframe = td->td_intr_frame; td->td_intr_frame = framep; decr_intr(framep); td->td_intr_frame = oldframe; atomic_subtract_int(&td->td_intr_nesting_level, 1); critical_exit(); break; #ifdef HWPMC_HOOKS case EXC_PERF: critical_enter(); KASSERT(pmc_intr != NULL, ("Performance exception, but no handler!")); (*pmc_intr)(PCPU_GET(cpuid), framep); if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, framep); critical_exit(); break; #endif default: /* Re-enable interrupts if applicable. */ ee = framep->srr1 & PSL_EE; if (ee != 0) mtmsr(mfmsr() | ee); trap(framep); } }
int mips_pic_intr(void *arg) { struct mips_pic_softc *sc = arg; register_t cause, status; struct intr_irqsrc *isrc; int i, intr; cause = mips_rd_cause(); status = mips_rd_status(); intr = (cause & MIPS_INT_MASK) >> 8; /* * Do not handle masked interrupts. They were masked by * pre_ithread function (mips_mask_XXX_intr) and will be * unmasked once ithread is through with handler */ intr &= (status & MIPS_INT_MASK) >> 8; while ((i = fls(intr)) != 0) { i--; /* Get a 0-offset interrupt. */ intr &= ~(1 << i); isrc = sc->pic_irqs[i]; if (isrc == NULL) { device_printf(sc->pic_dev, "Stray interrupt %u detected\n", i); pic_irq_mask(sc, i); continue; } intr_irq_dispatch(isrc, curthread->td_intr_frame); } KASSERT(i == 0, ("all interrupts handled")); #ifdef HWPMC_HOOKS if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) { struct trapframe *tf = PCPU_GET(curthread)->td_intr_frame; pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, tf); } #endif return (FILTER_HANDLED); }
void intr_irq_handler(struct trapframe *frame) { struct intr_event *event; int i; VM_CNT_INC(v_intr); i = -1; while ((i = arm_get_next_irq(i)) != -1) { intrcnt[i]++; event = intr_events[i]; if (intr_event_handle(event, frame) != 0) { /* XXX: Log stray IRQs */ arm_mask_irq(i); } } #ifdef HWPMC_HOOKS if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, frame); #endif }