Example #1
0
static void __init setup_intr(unsigned int intr, unsigned int cpu,
    unsigned int pin, unsigned int polarity, unsigned int trigtype)
{
    /* Setup Intr to Pin mapping */
    if (pin & GIC_MAP_TO_NMI_MSK) {
        GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
        /* FIXME: hack to route NMI to all cpu's */
        for (cpu = 0; cpu < NR_CPUS; cpu += 32) {
            GICWRITE(GIC_REG_ADDR(SHARED,
                      GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)),
                 0xffffffff);
        }
    } else {
        GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)),
             GIC_MAP_TO_PIN_MSK | pin);
        /* Setup Intr to CPU mapping */
        GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
    }

    /* Setup Intr Polarity */
    GIC_SET_POLARITY(intr, polarity);

    /* Setup Intr Trigger Type */
    GIC_SET_TRIGGER(intr, trigtype);

    /* Init Intr Masks */
    GIC_SET_INTR_MASK(intr, 0);
}
Example #2
0
static void __init gic_basic_init(void)
{
    unsigned int i, cpu;

    /* Setup defaults */
    for (i = 0; i < GIC_NUM_INTRS; i++) {
        GIC_SET_POLARITY(i, GIC_POL_POS);
        GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
        GIC_SET_INTR_MASK(i, 0);
    }

    /* Setup specifics */
    for (i = 0; i < _mapsize; i++) {
        cpu = _intrmap[i].cpunum;
        if (cpu == X)
            continue;

        setup_intr(_intrmap[i].intrnum,
                _intrmap[i].cpunum,
                _intrmap[i].pin,
                _intrmap[i].polarity,
                _intrmap[i].trigtype);
        /* Initialise per-cpu Interrupt software masks */
        if (_intrmap[i].ipiflag)
            set_bit(_intrmap[i].intrnum, pcpu_masks[cpu].pcpu_mask);
    }

    vpe_local_setup(numvpes);

    for (i = _irqbase; i < (_irqbase + numintrs); i++)
        set_irq_chip(i, &gic_irq_controller);
}
static void __init gic_basic_init(int numintrs, int numvpes,
			struct gic_intr_map *intrmap, int mapsize)
{
	unsigned int i, cpu;

	/* Setup defaults */
	for (i = 0; i < numintrs; i++) {
		GIC_SET_POLARITY(i, GIC_POL_POS);
		GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
		GIC_CLR_INTR_MASK(i);
		if (i < GIC_NUM_INTRS)
			gic_irq_flags[i] = 0;
	}

	/* Setup specifics */
	for (i = 0; i < mapsize; i++) {
		cpu = intrmap[i].cpunum;
		if (cpu == GIC_UNUSED)
			continue;
		if (cpu == 0 && i != 0 && intrmap[i].flags == 0)
			continue;
		gic_setup_intr(i,
			intrmap[i].cpunum,
			intrmap[i].pin,
			intrmap[i].polarity,
			intrmap[i].trigtype,
			intrmap[i].flags);
	}

	vpe_local_setup(numvpes);

	for (i = _irqbase; i < (_irqbase + numintrs); i++)
		irq_set_chip(i, &gic_irq_controller);
}
Example #4
0
static void gic_reset(gic_state *s)
{
    int i;
    memset(s->irq_state, 0, GIC_NIRQ * sizeof(gic_irq_state));
    s->priority_mask = 0xf0;
    s->current_pending = 1023;
    s->running_irq = 1023;
    s->running_priority = 0x100;
    for (i = 0; i < 15; i++) {
        GIC_SET_ENABLED(i);
        GIC_SET_TRIGGER(i);
    }
    s->enabled = 0;
    s->cpu_enabled = 0;
}
Example #5
0
static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
	unsigned int pin, unsigned int polarity, unsigned int trigtype,
	unsigned int flags)
{
	/* Setup Intr to Pin mapping */
	if (pin & GIC_MAP_TO_NMI_MSK) {
		GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
		/* FIXME: hack to route NMI to all cpu's */
		for (cpu = 0; cpu < NR_CPUS; cpu += 32) {
			GICWRITE(GIC_REG_ADDR(SHARED,
					  GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)),
				 0xffffffff);
		}
	} else {
		GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)),
			 GIC_MAP_TO_PIN_MSK | pin);
		/* Setup Intr to CPU mapping */
		GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
	}

	/* Setup Intr Polarity */
	GIC_SET_POLARITY(intr, polarity);

	/* Setup Intr Trigger Type */
	GIC_SET_TRIGGER(intr, trigtype);

	/* Init Intr Masks */
	GIC_CLR_INTR_MASK(intr);
	/* Initialise per-cpu Interrupt software masks */
	if (flags & GIC_FLAG_IPI)
		set_bit(intr, pcpu_masks[cpu].pcpu_mask);
#ifdef CONFIG_RALINK_SOC
	if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0))
#else
	if (flags & GIC_FLAG_TRANSPARENT)
#endif
		GIC_SET_INTR_MASK(intr);
	if (trigtype == GIC_TRIG_EDGE)
		gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE;
}
static void arm_gic_common_reset(DeviceState *dev)
{
    gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(dev));
    int i;
    memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
    for (i = 0 ; i < s->num_cpu; i++) {
        s->priority_mask[i] = 0xf0;
        s->current_pending[i] = 1023;
        s->running_irq[i] = 1023;
        s->running_priority[i] = 0x100;
        s->cpu_enabled[i] = 0;
    }
    for (i = 0; i < 16; i++) {
        GIC_SET_ENABLED(i, ALL_CPU_MASK);
        GIC_SET_TRIGGER(i);
    }
    if (s->num_cpu == 1) {
        /* For uniprocessor GICs all interrupts always target the sole CPU */
        for (i = 0; i < GIC_MAXIRQ; i++) {
            s->irq_target[i] = 1;
        }
    }
    s->enabled = 0;
}
Example #7
0
static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
                            uint32_t value)
{
    gic_state *s = (gic_state *)opaque;
    int irq;
    int i;

    offset -= s->base + 0x1000;
    if (offset < 0x100) {
        if (offset == 0) {
            s->enabled = (value & 1);
            DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
        } else if (offset < 4) {
            /* ignored.  */
        } else {
            goto bad_reg;
        }
    } else if (offset < 0x180) {
        /* Interrupt Set Enable.  */
        irq = (offset - 0x100) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 8; i++) {
            if (value & (1 << i)) {
                if (!GIC_TEST_ENABLED(irq + i))
                    DPRINTF("Enabled IRQ %d\n", irq + i);
                GIC_SET_ENABLED(irq + i);
                /* If a raised level triggered IRQ enabled then mark
                   is as pending.  */
                if (GIC_TEST_LEVEL(irq + i) && !GIC_TEST_TRIGGER(irq + i))
                    GIC_SET_PENDING(irq + i);
            }
        }
    } else if (offset < 0x200) {
        /* Interrupt Clear Enable.  */
        irq = (offset - 0x180) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 8; i++) {
            if (value & (1 << i)) {
                if (GIC_TEST_ENABLED(irq + i))
                    DPRINTF("Disabled IRQ %d\n", irq + i);
                GIC_CLEAR_ENABLED(irq + i);
            }
        }
    } else if (offset < 0x280) {
        /* Interrupt Set Pending.  */
        irq = (offset - 0x200) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 8; i++) {
            if (value & (1 << i)) {
                GIC_SET_PENDING(irq + i);
            }
        }
    } else if (offset < 0x300) {
        /* Interrupt Clear Pending.  */
        irq = (offset - 0x280) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 8; i++) {
            if (value & (1 << i)) {
                GIC_CLEAR_PENDING(irq + i);
            }
        }
    } else if (offset < 0x400) {
        /* Interrupt Active.  */
        goto bad_reg;
    } else if (offset < 0x800) {
        /* Interrupt Priority.  */
        irq = offset - 0x400;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        s->priority[irq] = value;
    } else if (offset < 0xc00) {
        /* Interrupt CPU Target.  */
        irq = offset - 0x800;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        s->irq_target[irq] = value;
    } else if (offset < 0xf00) {
        /* Interrupt Configuration.  */
        irq = (offset - 0xc00) * 4;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 4; i++) {
            if (value & (1 << (i * 2))) {
                GIC_SET_MODEL(irq + i);
            } else {
                GIC_CLEAR_MODEL(irq + i);
            }
            if (value & (2 << (i * 2))) {
                GIC_SET_TRIGGER(irq + i);
            } else {
                GIC_CLEAR_TRIGGER(irq + i);
            }
        }
    } else {
        /* 0xf00 is only handled for word writes.  */
        goto bad_reg;
    }
    gic_update(s);
    return;
bad_reg:
    cpu_abort (cpu_single_env, "gic_dist_writeb: Bad offset %x\n", offset);
}