Esempio n. 1
0
/*
 * XXX We can make arm_enable_irq to operate on ICE and then mask/unmask only
 * by ISM/ICM and remove access to ICE in masking operation
 */
void
arm_mask_irq(uintptr_t nb)
{

    MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 1);

    if (nb < ERR_IRQ) {
        bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
                          MPIC_ICE, nb);
        MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ISM, nb);
    } else if (nb < MSI_IRQ)
        arm_mask_irq_err(nb);
}
Esempio n. 2
0
static void
mpic_unmask_irq(uintptr_t nb)
{

	if (nb < ERR_IRQ) {
		bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
		    MPIC_ISE, nb);
		MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ICM, nb);
	} else if (nb < MSI_IRQ)
		mpic_unmask_irq_err(nb);

	if (nb == 0)
		MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DRBL_MASK, 0xffffffff);
}
Esempio n. 3
0
static void
mpic_unmask_irq_err(uintptr_t nb)
{
	uint32_t mask;
	uint8_t bit_off;

	bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
	    MPIC_ISE, MPIC_INT_ERR);
	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ICM, MPIC_INT_ERR);

	bit_off = nb - ERR_IRQ;
	mask = MPIC_CPU_READ(mv_mpic_sc, MPIC_ERR_MASK);
	mask |= (1 << bit_off);
	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ERR_MASK, mask);
}
Esempio n. 4
0
void
pic_ipi_clear(int ipi)
{
    uint32_t val;

    val = ~(1 << ipi);
    MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DRBL, val);
}
Esempio n. 5
0
static void
mpic_mask_irq_err(uintptr_t nb)
{
	uint32_t mask;
	uint8_t bit_off;

	bit_off = nb - ERR_IRQ;
	mask = MPIC_CPU_READ(mv_mpic_sc, MPIC_ERR_MASK);
	mask &= ~(1 << bit_off);
	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ERR_MASK, mask);
}
Esempio n. 6
0
int
pic_ipi_read(int i __unused)
{
	uint32_t val;
	int ipi;

	val = MPIC_CPU_READ(mv_mpic_sc, MPIC_IN_DRBL);
	if (val) {
		ipi = ffs(val) - 1;
		MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DRBL, ~(1 << ipi));
		return (ipi);
	}

	return (0x3ff);
}
Esempio n. 7
0
static int
mv_mpic_attach(device_t dev)
{
    struct mv_mpic_softc *sc;
    int error;

    sc = (struct mv_mpic_softc *)device_get_softc(dev);

    if (mv_mpic_sc != NULL)
        return (ENXIO);
    mv_mpic_sc = sc;

    sc->sc_dev = dev;

    error = bus_alloc_resources(dev, mv_mpic_spec, sc->mpic_res);
    if (error) {
        device_printf(dev, "could not allocate resources\n");
        return (ENXIO);
    }

    sc->mpic_bst = rman_get_bustag(sc->mpic_res[0]);
    sc->mpic_bsh = rman_get_bushandle(sc->mpic_res[0]);

    sc->cpu_bst = rman_get_bustag(sc->mpic_res[1]);
    sc->cpu_bsh = rman_get_bushandle(sc->mpic_res[1]);

    sc->drbl_bst = rman_get_bustag(sc->mpic_res[2]);
    sc->drbl_bsh = rman_get_bushandle(sc->mpic_res[2]);

    bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
                      MPIC_CTRL, 1);
    MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0);

    arm_unmask_msi();

    return (0);
}
Esempio n. 8
0
static int
mv_mpic_attach(device_t dev)
{
	struct mv_mpic_softc *sc;
	int error;
	uint32_t val;

	sc = (struct mv_mpic_softc *)device_get_softc(dev);

	if (mv_mpic_sc != NULL)
		return (ENXIO);
	mv_mpic_sc = sc;

	sc->sc_dev = dev;

	mtx_init(&sc->mtx, "MPIC lock", NULL, MTX_SPIN);

	error = bus_alloc_resources(dev, mv_mpic_spec, sc->mpic_res);
	if (error) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}
#ifdef ARM_INTRNG
	if (sc->mpic_res[3] == NULL)
		device_printf(dev, "No interrupt to use.\n");
	else
		bus_setup_intr(dev, sc->mpic_res[3], INTR_TYPE_CLK,
		    mpic_intr, NULL, sc, &sc->intr_hand);
#endif

	sc->mpic_bst = rman_get_bustag(sc->mpic_res[0]);
	sc->mpic_bsh = rman_get_bushandle(sc->mpic_res[0]);

	sc->cpu_bst = rman_get_bustag(sc->mpic_res[1]);
	sc->cpu_bsh = rman_get_bushandle(sc->mpic_res[1]);

	if (sc->mpic_res[2] != NULL) {
		/* This is required only if MSIs are used. */
		sc->drbl_bst = rman_get_bustag(sc->mpic_res[2]);
		sc->drbl_bsh = rman_get_bushandle(sc->mpic_res[2]);
	}

	bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
	    MPIC_CTRL, 1);
	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0);

	val = MPIC_READ(mv_mpic_sc, MPIC_CTRL);
	sc->nirqs = MPIC_CTRL_NIRQS(val);

#ifdef ARM_INTRNG
	sc->mpic_isrcs = malloc(sc->nirqs * sizeof (*sc->mpic_isrcs), M_DEVBUF,
	    M_WAITOK | M_ZERO);

	if (intr_pic_register(dev, OF_xref_from_device(dev)) != 0) {
		device_printf(dev, "could not register PIC\n");
		bus_release_resources(dev, mv_mpic_spec, sc->mpic_res);
		return (ENXIO);
	}
#endif

	mpic_unmask_msi();

	return (0);
}