Exemplo n.º 1
0
void
openpic_bind(device_t dev, u_int irq, cpumask_t cpumask)
{
	struct openpic_softc *sc;

	/* If we aren't directly connected to the CPU, this won't work */
	if (dev != root_pic)
		return;

	sc = device_get_softc(dev);
	openpic_write(sc, OPENPIC_IDEST(irq), cpumask);
}
Exemplo n.º 2
0
void
opic_finish_setup(struct pic_ops *pic)
{
	uint32_t cpumask = 0;
	int i;

#ifdef OPENPIC_DISTRIBUTE
	for (i = 0; i < ncpu; i++)
		cpumask |= (1 << cpu_info[i].ci_index);
#else
	cpumask = 1;
#endif
	for (i = 0; i < pic->pic_numintrs; i++) {
		/* send all interrupts to all active CPUs */
		openpic_write(OPENPIC_IDEST(i), cpumask);
	}
}
Exemplo n.º 3
0
int
openpic_attach(device_t dev)
{
	struct openpic_softc *sc;
	u_int     cpu, ipi, irq;
	u_int32_t x;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;

	sc->sc_rid = 0;
	sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
	    RF_ACTIVE);

	if (sc->sc_memr == NULL) {
		device_printf(dev, "Could not alloc mem resource!\n");
		return (ENXIO);
	}

	sc->sc_bt = rman_get_bustag(sc->sc_memr);
	sc->sc_bh = rman_get_bushandle(sc->sc_memr);

	/* Reset the PIC */
	x = openpic_read(sc, OPENPIC_CONFIG);
	x |= OPENPIC_CONFIG_RESET;
	openpic_write(sc, OPENPIC_CONFIG, x);

	while (openpic_read(sc, OPENPIC_CONFIG) & OPENPIC_CONFIG_RESET) {
		powerpc_sync();
		DELAY(100);
	}

	/* Check if this is a cascaded PIC */
	sc->sc_irq = 0;
	sc->sc_intr = NULL;
	do {
		struct resource_list *rl;

		rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
		if (rl == NULL)
			break;
		if (resource_list_find(rl, SYS_RES_IRQ, 0) == NULL)
			break;

		sc->sc_intr = bus_alloc_resource_any(dev, SYS_RES_IRQ,
		    &sc->sc_irq, RF_ACTIVE);

		/* XXX Cascaded PICs pass NULL trapframes! */
		bus_setup_intr(dev, sc->sc_intr, INTR_TYPE_MISC | INTR_MPSAFE,
		    openpic_intr, NULL, dev, &sc->sc_icookie);
	} while (0);

	/* Reset the PIC */
	x = openpic_read(sc, OPENPIC_CONFIG);
	x |= OPENPIC_CONFIG_RESET;
	openpic_write(sc, OPENPIC_CONFIG, x);

	while (openpic_read(sc, OPENPIC_CONFIG) & OPENPIC_CONFIG_RESET) {
		powerpc_sync();
		DELAY(100);
	}

	x = openpic_read(sc, OPENPIC_FEATURE);
	switch (x & OPENPIC_FEATURE_VERSION_MASK) {
	case 1:
		sc->sc_version = "1.0";
		break;
	case 2:
		sc->sc_version = "1.2";
		break;
	case 3:
		sc->sc_version = "1.3";
		break;
	default:
		sc->sc_version = "unknown";
		break;
	}

	sc->sc_ncpu = ((x & OPENPIC_FEATURE_LAST_CPU_MASK) >>
	    OPENPIC_FEATURE_LAST_CPU_SHIFT) + 1;
	sc->sc_nirq = ((x & OPENPIC_FEATURE_LAST_IRQ_MASK) >>
	    OPENPIC_FEATURE_LAST_IRQ_SHIFT) + 1;

	/*
	 * PSIM seems to report 1 too many IRQs and CPUs
	 */
	if (sc->sc_psim) {
		sc->sc_nirq--;
		sc->sc_ncpu--;
	}

	if (bootverbose)
		device_printf(dev,
		    "Version %s, supports %d CPUs and %d irqs\n",
		    sc->sc_version, sc->sc_ncpu, sc->sc_nirq);

	for (cpu = 0; cpu < sc->sc_ncpu; cpu++)
		openpic_write(sc, OPENPIC_PCPU_TPR(cpu), 15);

	/* Reset and disable all interrupts. */
	for (irq = 0; irq < sc->sc_nirq; irq++) {
		x = irq;                /* irq == vector. */
		x |= OPENPIC_IMASK;
		x |= OPENPIC_POLARITY_NEGATIVE;
		x |= OPENPIC_SENSE_LEVEL;
		x |= 8 << OPENPIC_PRIORITY_SHIFT;
		openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
	}

	/* Reset and disable all IPIs. */
	for (ipi = 0; ipi < 4; ipi++) {
		x = sc->sc_nirq + ipi;
		x |= OPENPIC_IMASK;
		x |= 15 << OPENPIC_PRIORITY_SHIFT;
		openpic_write(sc, OPENPIC_IPI_VECTOR(ipi), x);
	}

	/* we don't need 8259 passthrough mode */
	x = openpic_read(sc, OPENPIC_CONFIG);
	x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
	openpic_write(sc, OPENPIC_CONFIG, x);

	/* send all interrupts to cpu 0 */
	for (irq = 0; irq < sc->sc_nirq; irq++)
		openpic_write(sc, OPENPIC_IDEST(irq), 1 << 0);

	/* clear all pending interrupts from cpu 0 */
	for (irq = 0; irq < sc->sc_nirq; irq++) {
		(void)openpic_read(sc, OPENPIC_PCPU_IACK(0));
		openpic_write(sc, OPENPIC_PCPU_EOI(0), 0);
	}

	for (cpu = 0; cpu < sc->sc_ncpu; cpu++)
		openpic_write(sc, OPENPIC_PCPU_TPR(cpu), 0);

	powerpc_register_pic(dev, sc->sc_nirq);

	/* If this is not a cascaded PIC, it must be the root PIC */
	if (sc->sc_intr == NULL)
		root_pic = dev;

	return (0);
}
Exemplo n.º 4
0
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;
}