Example #1
0
/** Handler of IRQ exceptions.
 *
 */
static void irq_interrupt(unsigned int n, istate_t *istate)
{
	ASSERT(n >= IVT_IRQBASE);
	
	unsigned int inum = n - IVT_IRQBASE;
	bool ack = false;
	ASSERT(inum < IRQ_COUNT);
	ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
	
	irq_t *irq = irq_dispatch_and_lock(inum);
	if (irq) {
		/*
		 * The IRQ handler was found.
		 */
		
		if (irq->preack) {
			/* Send EOI before processing the interrupt */
			trap_virtual_eoi();
			ack = true;
		}
		irq->handler(irq);
		irq_spinlock_unlock(&irq->lock, false);
	} else {
		/*
		 * Spurious interrupt.
		 */
#ifdef CONFIG_DEBUG
		printf("cpu%u: spurious interrupt (inum=%u)\n", CPU->id, inum);
#endif
	}
	
	if (!ack)
		trap_virtual_eoi();
}
Example #2
0
/** Process hardware interrupt.
 *
 * @param n Ignored.
 * @param istate Ignored.
 */
void interrupt(unsigned int n, istate_t *istate)
{
	uint64_t status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
	if (status & (!INTR_DISPATCH_STATUS_BUSY))
		panic("Interrupt Dispatch Status busy bit not set\n");
	
	uint64_t intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
#if defined (US)
	uint64_t data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0);
#elif defined (US3)
	uint64_t data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0);
#endif
	
	irq_t *irq = irq_dispatch_and_lock(data0);
	if (irq) {
		/*
		 * The IRQ handler was found.
		 */
		irq->handler(irq);
		
		/*
		 * See if there is a clear-interrupt-routine and call it.
		 */
		if (irq->cir)
			irq->cir(irq->cir_arg, irq->inr);
		
		irq_spinlock_unlock(&irq->lock, false);
	} else if (data0 > config.base) {
		/*
		 * This is a cross-call.
		 * data0 contains address of the kernel function.
		 * We call the function only after we verify
		 * it is one of the supported ones.
		 */
#ifdef CONFIG_SMP
		if (data0 == (uintptr_t) tlb_shootdown_ipi_recv)
			tlb_shootdown_ipi_recv();
#endif
	} else {
		/*
		 * Spurious interrupt.
		 */
#ifdef CONFIG_DEBUG
		log(LF_ARCH, LVL_DEBUG,
		    "cpu%u: spurious interrupt (intrcv=%#" PRIx64 ", data0=%#"
		    PRIx64 ")", CPU->id, intrcv, data0);
#else
		(void) intrcv;
#endif
	}
	
	membar();
	asi_u64_write(ASI_INTR_RECEIVE, 0, 0);
}
Example #3
0
static void raspberrypi_irq_exception(unsigned int exc_no, istate_t *istate)
{
	const unsigned inum = bcm2835_irc_inum_get(raspi.irc);

	irq_t *irq = irq_dispatch_and_lock(inum);
	if (irq) {
		/* The IRQ handler was found. */
		irq->handler(irq);
		spinlock_unlock(&irq->lock);
	} else {
		/* Spurious interrupt.*/
		printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
		bcm2835_irc_disable(raspi.irc, inum);
	}
}
Example #4
0
static void gta02_irq_exception(unsigned int exc_no, istate_t *istate)
{
	uint32_t inum;

	/* Determine IRQ number. */
	inum = s3c24xx_irqc_inum_get(&gta02_irqc);

	/* Clear interrupt condition in the interrupt controller. */
	s3c24xx_irqc_clear(&gta02_irqc, inum);

	irq_t *irq = irq_dispatch_and_lock(inum);
	if (irq) {
		/* The IRQ handler was found. */
		irq->handler(irq);
		spinlock_unlock(&irq->lock);
	} else {
		/* Spurious interrupt.*/
		printf("cpu%d: spurious interrupt (inum=%d)\n",
		    CPU->id, inum);
	}
}
Example #5
0
static void interrupt_exception(unsigned int n, istate_t *istate)
{
	uint32_t ip;
	uint32_t im;

	/* Decode interrupt number and process the interrupt */
	ip = (cp0_cause_read() & cp0_cause_ip_mask) >> cp0_cause_ip_shift;
	im = (cp0_status_read() & cp0_status_im_mask) >> cp0_status_im_shift;
	
	unsigned int i;
	for (i = 0; i < 8; i++) {

		/*
		 * The interrupt could only occur if it is unmasked in the
		 * status register. On the other hand, an interrupt can be
		 * apparently pending even if it is masked, so we need to
		 * check both the masked and pending interrupts.
		 */
		if (im & ip & (1 << i)) {
			irq_t *irq = irq_dispatch_and_lock(i);
			if (irq) {
				/*
				 * The IRQ handler was found.
				 */
				irq->handler(irq);
				irq_spinlock_unlock(&irq->lock, false);
			} else {
				/*
				 * Spurious interrupt.
				 */
#ifdef CONFIG_DEBUG
				log(LF_ARCH, LVL_DEBUG,
				    "cpu%u: spurious interrupt (inum=%u)",
				    CPU->id, i);
#endif
			}
		}
	}
}