/* * softintr_dispatch: * * Process pending software interrupts. */ void softintr_dispatch() { struct alpha_soft_intr *asi; struct alpha_soft_intrhand *sih; u_int64_t n, i; while ((n = atomic_loadlatch_ulong(&ssir, 0)) != 0) { for (i = 0; i < IPL_NSOFT; i++) { if ((n & (1 << i)) == 0) continue; asi = &alpha_soft_intrs[i]; /* Already at splsoft() */ simple_lock(&asi->softintr_slock); for (sih = LIST_FIRST(&asi->softintr_q); sih != NULL; sih = LIST_NEXT(sih, sih_q)) { if (sih->sih_pending) { uvmexp.softs++; sih->sih_pending = 0; (*sih->sih_fn)(sih->sih_arg); } } simple_unlock(&asi->softintr_slock); } } }
/* * Process IPIs for a CPU. */ void alpha_ipi_process(struct cpu_info *ci, struct trapframe *framep) { u_long pending_ipis, bit; while ((pending_ipis = atomic_loadlatch_ulong(&ci->ci_ipis, 0)) != 0) { for (bit = 0; bit < ALPHA_NIPIS; bit++) { if (pending_ipis & (1UL << bit)) { (*ipifuncs[bit])(ci, framep); } } } }
/* * softintr_dispatch: * * Process pending software interrupts. */ void softintr_dispatch() { struct alpha_soft_intr *asi; struct alpha_soft_intrhand *sih; u_int64_t n, i; #if defined(MULTIPROCESSOR) __mp_lock(&kernel_lock); #endif while ((n = atomic_loadlatch_ulong(&ssir, 0)) != 0) { for (i = 0; i < SI_NSOFT; i++) { if ((n & (1 << i)) == 0) continue; asi = &alpha_soft_intrs[i]; for (;;) { mtx_enter(&asi->softintr_mtx); sih = TAILQ_FIRST(&asi->softintr_q); if (sih == NULL) { mtx_leave(&asi->softintr_mtx); break; } TAILQ_REMOVE(&asi->softintr_q, sih, sih_q); sih->sih_pending = 0; atomic_add_int(&uvmexp.softs, 1); mtx_leave(&asi->softintr_mtx); (*sih->sih_fn)(sih->sih_arg); } } } #if defined(MULTIPROCESSOR) __mp_unlock(&kernel_lock); #endif }
/* * softintr_dispatch: * * Process pending software interrupts. */ void softintr_dispatch() { struct alpha_soft_intr *asi; struct alpha_soft_intrhand *sih; u_int64_t n, i; while ((n = atomic_loadlatch_ulong(&ssir, 0)) != 0) { for (i = 0; i < SI_NSOFT; i++) { if ((n & (1 << i)) == 0) continue; asi = &alpha_soft_intrs[i]; for (;;) { (void) alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH); simple_lock(&asi->softintr_slock); sih = TAILQ_FIRST(&asi->softintr_q); if (sih != NULL) { TAILQ_REMOVE(&asi->softintr_q, sih, sih_q); sih->sih_pending = 0; } simple_unlock(&asi->softintr_slock); (void) alpha_pal_swpipl(ALPHA_PSL_IPL_SOFT); if (sih == NULL) break; uvmexp.softs++; (*sih->sih_fn)(sih->sih_arg); } } } }
void interrupt(unsigned long a0, unsigned long a1, unsigned long a2, struct trapframe *framep) { struct proc *p; struct cpu_info *ci = curcpu(); extern int schedhz; switch (a0) { case ALPHA_INTR_XPROC: /* interprocessor interrupt */ #if defined(MULTIPROCESSOR) { u_long pending_ipis, bit; #if 0 printf("CPU %lu got IPI\n", cpu_id); #endif #ifdef DIAGNOSTIC if (ci->ci_dev == NULL) { /* XXX panic? */ printf("WARNING: no device for ID %lu\n", ci->ci_cpuid); return; } #endif pending_ipis = atomic_loadlatch_ulong(&ci->ci_ipis, 0); for (bit = 0; bit < ALPHA_NIPIS; bit++) if (pending_ipis & (1UL << bit)) (*ipifuncs[bit])(); /* * Handle inter-console messages if we're the primary * CPU. */ if (ci->ci_cpuid == hwrpb->rpb_primary_cpu_id && hwrpb->rpb_txrdy != 0) cpu_iccb_receive(); } #else printf("WARNING: received interprocessor interrupt!\n"); #endif /* MULTIPROCESSOR */ break; case ALPHA_INTR_CLOCK: /* clock interrupt */ #if defined(MULTIPROCESSOR) /* XXX XXX XXX */ if (CPU_IS_PRIMARY(ci) == 0) return; #endif uvmexp.intrs++; clk_count.ec_count++; if (platform.clockintr) { /* * Call hardclock(). This will also call * statclock(). On the primary CPU, it * will also deal with time-of-day stuff. */ (*platform.clockintr)((struct clockframe *)framep); /* * If it's time to call the scheduler clock, * do so. */ if ((++schedclk2 & 0x3f) == 0 && (p = ci->ci_curproc) != NULL && schedhz != 0) schedclock(p); } break; case ALPHA_INTR_ERROR: /* Machine Check or Correctable Error */ a0 = alpha_pal_rdmces(); if (platform.mcheck_handler) (*platform.mcheck_handler)(a0, framep, a1, a2); else machine_check(a0, framep, a1, a2); break; case ALPHA_INTR_DEVICE: /* I/O device interrupt */ { struct scbvec *scb; KDASSERT(a1 >= SCB_IOVECBASE && a1 < SCB_SIZE); #if defined(MULTIPROCESSOR) /* XXX XXX XXX */ if (CPU_IS_PRIMARY(ci) == 0) return; #endif uvmexp.intrs++; scb = &scb_iovectab[SCB_VECTOIDX(a1 - SCB_IOVECBASE)]; (*scb->scb_func)(scb->scb_arg, a1); break; } case ALPHA_INTR_PERF: /* performance counter interrupt */ printf("WARNING: received performance counter interrupt!\n"); break; case ALPHA_INTR_PASSIVE: #if 0 printf("WARNING: received passive release interrupt vec " "0x%lx\n", a1); #endif break; default: printf("unexpected interrupt: type 0x%lx vec 0x%lx " "a2 0x%lx" #if defined(MULTIPROCESSOR) " cpu %lu" #endif "\n", a0, a1, a2 #if defined(MULTIPROCESSOR) , ci->ci_cpuid #endif ); panic("interrupt"); /* NOTREACHED */ } }