예제 #1
0
/*
 * 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);
		}
	}
}
예제 #2
0
/*
 * 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);
            }
        }
    }
}
예제 #3
0
/*
 * 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
}
예제 #4
0
/*
 * 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);
			}
		}
	}
}
예제 #5
0
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 */
	}
}