Example #1
0
/*
 * do_cio_interrupt() handles all normal I/O device IRQ's
 */
static irqreturn_t do_cio_interrupt(int irq, void *dummy)
{
	struct tpi_info *tpi_info;
	struct subchannel *sch;
	struct irb *irb;

	set_cpu_flag(CIF_NOHZ_DELAY);
	tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
	trace_s390_cio_interrupt(tpi_info);
	irb = this_cpu_ptr(&cio_irb);
	sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
	if (!sch) {
		/* Clear pending interrupt condition. */
		inc_irq_stat(IRQIO_CIO);
		tsch(tpi_info->schid, irb);
		return IRQ_HANDLED;
	}
	spin_lock(sch->lock);
	/* Store interrupt response block to lowcore. */
	if (tsch(tpi_info->schid, irb) == 0) {
		/* Keep subchannel information word up to date. */
		memcpy (&sch->schib.scsw, &irb->scsw, sizeof (irb->scsw));
		/* Call interrupt handler if there is one. */
		if (sch->driver && sch->driver->irq)
			sch->driver->irq(sch);
		else
			inc_irq_stat(IRQIO_CIO);
	} else
		inc_irq_stat(IRQIO_CIO);
	spin_unlock(sch->lock);

	return IRQ_HANDLED;
}
Example #2
0
static uint8_t execute_NMI(cpu_registers* registers) {
    clear_nmi_flag();
    // NMI clears bit 4 and sets bit 5 for flags push
    uint8_t NMI_flags = registers->flags | 0x20;
    NMI_flags &= ~0x10;
    push_PC_onto_stack(registers, registers->PC - 1); // Sub 1 to get correct PC since it was incremented
    push_stack(registers, NMI_flags);
    registers->PC = (read_RAM(0xFFFB) << 8) | read_RAM(0xFFFA);
    set_cpu_flag(registers, INTERRUPT_FLAG);
    return 7;
}