static int openpic_acknowledge_io_interrupt(void *cookie) { openpic_info *info = (openpic_info*)cookie; int cpu = 0; // Note: We direct all I/O interrupts to CPU 0. We could nevertheless // check against the value of the "Who Am I Register". int irq = openpic_read_irq(info, cpu); if (irq == 255) return -1; // spurious interrupt // signal end of interrupt openpic_eoi(info, cpu); return irq; }
int opic_get_irq(struct pic_ops *pic, int mode) { return openpic_read_irq(curcpu()->ci_index); }
static status_t openpic_init(openpic_info *info) { uint32 x = openpic_read(info, OPENPIC_FEATURE); const char *featureVersion; char versionBuffer[64]; switch (x & OPENPIC_FEATURE_VERSION_MASK) { case 1: featureVersion = "1.0"; break; case 2: featureVersion = "1.2"; break; case 3: featureVersion = "1.3"; break; default: snprintf(versionBuffer, sizeof(versionBuffer), "unknown (feature reg: 0x%lx)", x); featureVersion = versionBuffer; break; } info->cpu_count = ((x & OPENPIC_FEATURE_LAST_CPU_MASK) >> OPENPIC_FEATURE_LAST_CPU_SHIFT) + 1; info->irq_count = ((x & OPENPIC_FEATURE_LAST_IRQ_MASK) >> OPENPIC_FEATURE_LAST_IRQ_SHIFT) + 1; /* * PSIM seems to report 1 too many IRQs */ // if (sc->sc_psim) // sc->sc_nirq--; dprintf("openpic: Version %s, supports %d CPUs and %d irqs\n", featureVersion, info->cpu_count, info->irq_count); /* disable all interrupts */ for (int irq = 0; irq < info->irq_count; irq++) openpic_write(info, OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK); openpic_set_priority(info, 0, 15); /* we don't need 8259 passthrough mode */ x = openpic_read(info, OPENPIC_CONFIG); x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE; openpic_write(info, OPENPIC_CONFIG, x); /* send all interrupts to cpu 0 */ for (int irq = 0; irq < info->irq_count; irq++) openpic_write(info, OPENPIC_IDEST(irq), 1 << 0); for (int irq = 0; irq < info->irq_count; irq++) { x = irq; x |= OPENPIC_IMASK; x |= OPENPIC_POLARITY_POSITIVE; x |= OPENPIC_SENSE_LEVEL; x |= 8 << OPENPIC_PRIORITY_SHIFT; openpic_write(info, OPENPIC_SRC_VECTOR(irq), x); } /* XXX IPI */ /* XXX set spurious intr vector */ openpic_set_priority(info, 0, 0); /* clear all pending interrupts */ for (int irq = 0; irq < info->irq_count; irq++) { openpic_read_irq(info, 0); openpic_eoi(info, 0); } return B_OK; }