Exemple #1
0
void
cpu_intr(int ppl, vaddr_t pc, uint32_t status)
{
	struct cpu_info * const ci = curcpu();
	uint32_t pending;
	int ipl;
#ifdef DIAGNOSTIC
	const int mtx_count = ci->ci_mtx_count;
	const u_int biglock_count = ci->ci_biglock_count;
	const u_int blcnt = curlwp->l_blcnt;
#endif
	KASSERT(ci->ci_cpl == IPL_HIGH);
	KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE);

	ci->ci_data.cpu_nintr++;

	while (ppl < (ipl = splintr(&pending))) {
		KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE);
		splx(ipl);	/* lower to interrupt level */
		KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE);

		KASSERTMSG(ci->ci_cpl == ipl,
		    "%s: cpl (%d) != ipl (%d)", __func__, ci->ci_cpl, ipl);
		KASSERT(pending != 0);

		cf.pc = pc;
		cf.sr = status;
		cf.intr = (ci->ci_idepth > 1);

#ifdef MIPS3_ENABLE_CLOCK_INTR
		if (pending & MIPS_INT_MASK_5) {
			KASSERTMSG(ipl == IPL_SCHED,
			    "%s: ipl (%d) != IPL_SCHED (%d)",
			     __func__, ipl, IPL_SCHED);
			/* call the common MIPS3 clock interrupt handler */ 
			mips3_clockintr(&cf);
			pending ^= MIPS_INT_MASK_5;
		}
#endif

		if (pending != 0) {
			/* Process I/O and error interrupts. */
			evbmips_iointr(ipl, pc, pending);
		}
		KASSERT(biglock_count == ci->ci_biglock_count);
		KASSERT(blcnt == curlwp->l_blcnt);
		KASSERT(mtx_count == ci->ci_mtx_count);

		/*
		 * If even our spl is higher now (due to interrupting while
		 * spin-lock is held and higher IPL spin-lock is locked, it
		 * can no longer be locked so it's safe to lower IPL back
		 * to ppl.
		 */
		(void) splhigh();	/* disable interrupts */
	}

	KASSERT(ci->ci_cpl == IPL_HIGH);
	KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE);
}
void
cpu_intr(int ppl, vaddr_t pc, uint32_t status)
{
	uint32_t pending;
	int ipl;

	curcpu()->ci_data.cpu_nintr++;

	while (ppl < (ipl = splintr(&pending))) {
		splx(ipl);
		if (pending & MIPS_INT_MASK_5) {
			struct clockframe cf;

			cf.pc = pc;
			cf.sr = status;
			cf.intr = (curcpu()->ci_idepth > 1);
			mips3_clockintr(&cf);
		}

		if (pending & (MIPS_INT_MASK_0|MIPS_INT_MASK_1|MIPS_INT_MASK_2|
				MIPS_INT_MASK_3|MIPS_INT_MASK_4)) {
			/* Process I/O and error interrupts. */
			(*algor_iointr)(ipl, pc, pending);
		}
		(void)splhigh();
	}
}
Exemple #3
0
/*
 * NB: Do not re-enable interrupts here -- reentrancy here can cause all
 * sorts of Bad Things(tm) to happen, including kernel stack overflows.
 */
void
cpu_intr(int ppl, vaddr_t pc, uint32_t status)
{
	uint32_t pending;
	int ipl;

	curcpu()->ci_data.cpu_nintr++;

	(void)(*platform.watchdog_reset)();

	while (ppl < (ipl = splintr(&pending))) {
		splx(ipl);		/* enable interrupts */

        	if (pending & MIPS_INT_MASK_5) {
               		(void)(*platform.intr5)(pc, status, pending);
			mips_int5_evcnt.ev_count++;
        	}

		if (pending & MIPS_INT_MASK_4) {
               		(void)(*platform.intr4)(pc, status, pending);
			mips_int4_evcnt.ev_count++;
		}

		if (pending & MIPS_INT_MASK_3) {
               		(void)(*platform.intr3)(pc, status, pending);
			mips_int3_evcnt.ev_count++;
		}

	        if (pending & MIPS_INT_MASK_2) {
               		(void)(*platform.intr2)(pc, status, pending);
			mips_int2_evcnt.ev_count++;
		}

		if (pending & MIPS_INT_MASK_1) {
               		(void)(*platform.intr1)(pc, status, pending);
			mips_int1_evcnt.ev_count++;
		}

		if (pending & MIPS_INT_MASK_0) {  
               		(void)(*platform.intr0)(pc, status, pending);
			mips_int0_evcnt.ev_count++;
		}
		(void)splhigh();
	}
}
Exemple #4
0
/*
 * Handle news5000 interrupts.
 */
void
news5000_intr(int ppl, vaddr_t pc, uint32_t status)
{
	uint32_t ipending;
	int ipl;

	while (ppl < (ipl = splintr(&ipending))) {

		if (ipending & MIPS_INT_MASK_2) {
#ifdef DEBUG
			static int l2cnt = 0;
#endif
			uint32_t int2stat;

			int2stat = *(volatile uint32_t *)NEWS5000_INTST2;

#ifdef DEBUG
			l2cnt++;
			if (l2cnt == 50) {
				*(volatile uint32_t *)NEWS5000_LED_SEC = 1;
			}
			if (l2cnt == 100) {
				*(volatile uint32_t *)NEWS5000_LED_SEC = 0;
				l2cnt = 0;
			}
#endif

			if (int2stat & NEWS5000_INT2_TIMER0) {
				struct clockframe cf = {
					.pc = pc,
					.sr = status,
					.intr = (curcpu()->ci_idepth > 1),
				};
				*(volatile uint32_t *)NEWS5000_TIMER0 = 1;
				hardclock(&cf);
				intrcnt[HARDCLOCK_INTR]++;
			}

			apbus_wbflush();
		}

		if (ipending & MIPS_INT_MASK_5) {
			uint32_t int5stat;

			int5stat = *(volatile u_int *)NEWS5000_INTST5;
			printf("level5 interrupt (%08x)\n", int5stat);

			apbus_wbflush();
		}

		if (ipending & MIPS_INT_MASK_4) {
			uint32_t int4stat;

			int4stat = *(volatile uint32_t *)NEWS5000_INTST4;
			printf("level4 interrupt (%08x)\n", int4stat);
			if (int4stat & NEWS5000_INT4_APBUS) {
				uint32_t stat;

				stat = *(volatile uint32_t *)NEWS5000_APBUS_INTST;
				printf("APbus error 0x%04x\n", stat & 0xffff);
				if (stat & NEWS5000_APBUS_INT_DMAADDR) {
					printf("DMA Address Error: "
					    "slot=%x, addr=0x%08x\n",
					    *(volatile uint32_t *)NEWS5000_APBUS_DER_S,
					    *(volatile uint32_t *)NEWS5000_APBUS_DER_A);
				}
				if (stat & NEWS5000_APBUS_INT_RDTIMEO)
					printf("IO Read Timeout: addr=0x%08x\n",
					    *(volatile uint32_t *)NEWS5000_APBUS_BER_A);
				if (stat & NEWS5000_APBUS_INT_WRTIMEO)
					printf("IO Write Timeout: addr=0x%08x\n",
					    *(volatile uint32_t *)NEWS5000_APBUS_BER_A);
				*(volatile uint32_t *)0xb4c00014 = stat;
			}

			apbus_wbflush();
		}

		if (ipending & MIPS_INT_MASK_3) {
			uint32_t int3stat;

			int3stat = *(volatile uint32_t *)NEWS5000_INTST3;
			printf("level3 interrupt (%08x)\n", int3stat);

			apbus_wbflush();
		}

		if (ipending & MIPS_INT_MASK_1) {
			news5000_level1_intr();
			apbus_wbflush();
		}

		if (ipending & MIPS_INT_MASK_0) {
			news5000_level0_intr();
			apbus_wbflush();
		}
	}
}


static void
news5000_level1_intr(void)
{
	uint32_t int1stat;

	int1stat = *(volatile uint32_t *)NEWS5000_INTST1;

	if (int1stat) {
		if (apbus_intr_dispatch(1, int1stat) == 0)
			printf("level1_intr: no handler (mask 0x%04x)\n",
			       int1stat);
	} else
		printf("level1 stray interrupt?\n");
}