Example #1
0
File: gic.c Project: lorc/optee_os
static size_t probe_max_it(vaddr_t gicc_base, vaddr_t gicd_base)
{
	int i;
	uint32_t old_ctlr;
	size_t ret = 0;
	const size_t max_regs = ((GIC_MAX_INTS + NUM_INTS_PER_REG - 1) /
					NUM_INTS_PER_REG) - 1;

	/*
	 * Probe which interrupt number is the largest.
	 */
	old_ctlr = read32(gicc_base + GICC_CTLR);
	write32(0, gicc_base + GICC_CTLR);
	for (i = max_regs; i >= 0; i--) {
		uint32_t old_reg;
		uint32_t reg;
		int b;

		old_reg = read32(gicd_base + GICD_ISENABLER(i));
		write32(0xffffffff, gicd_base + GICD_ISENABLER(i));
		reg = read32(gicd_base + GICD_ISENABLER(i));
		write32(old_reg, gicd_base + GICD_ICENABLER(i));
		for (b = NUM_INTS_PER_REG - 1; b >= 0; b--) {
			if (BIT32(b) & reg) {
				ret = i * NUM_INTS_PER_REG + b;
				goto out;
			}
		}
	}
out:
	write32(old_ctlr, gicc_base + GICC_CTLR);
	return ret;
}
Example #2
0
File: gic.c Project: gxliu/optee_os
static size_t probe_max_it(void)
{
	int i;
	uint32_t old_ctlr;
	size_t ret = 0;

	/*
	 * Probe which interrupt number is the largest.
	 */
	old_ctlr = read32(gic.gicc_base + GICC_CTLR);
	write32(0, gic.gicc_base + GICC_CTLR);
	for (i = GIC_MAX_INTS / 32; i > 0; i--) {
		uint32_t old_reg;
		uint32_t reg;
		int b;

		old_reg = read32(gic.gicd_base + GICD_ISENABLER(i));
		write32(0xffffffff, gic.gicd_base + GICD_ISENABLER(i));
		reg = read32(gic.gicd_base + GICD_ISENABLER(i));
		write32(old_reg, gic.gicd_base + GICD_ICENABLER(i));
		for (b = 31; b > 0; b--) {
			if ((1 << b) & reg) {
				ret = i * 32 + b;
				goto out;
			}
		}
	}
out:
	write32(old_ctlr, gic.gicc_base + GICC_CTLR);
	return ret;
}
Example #3
0
File: gic.c Project: lorc/optee_os
static void gic_it_enable(struct gic_data *gd, size_t it)
{
	size_t idx = it / NUM_INTS_PER_REG;
	uint32_t mask = 1 << (it % NUM_INTS_PER_REG);

	/* Assigned to group0 */
	assert(!(read32(gd->gicd_base + GICD_IGROUPR(idx)) & mask));
	/* Not enabled yet */
	assert(!(read32(gd->gicd_base + GICD_ISENABLER(idx)) & mask));

	/* Enable the interrupt */
	write32(mask, gd->gicd_base + GICD_ISENABLER(idx));
}
Example #4
0
void gic_it_enable(size_t it)
{
	size_t idx = it / NUM_INTS_PER_REG;
	uint32_t mask = 1 << (it % NUM_INTS_PER_REG);

	assert(it <= gic.max_it); /* Not too large */
	/* Assigned to group0 */
	assert(!(read32(gic.gicd_base + GICD_IGROUPR(idx)) & mask));
	/* Not enabled yet */
	assert(!(read32(gic.gicd_base + GICD_ISENABLER(idx)) & mask));

	/* Enable the interrupt */
	write32(mask, gic.gicd_base + GICD_ISENABLER(idx));
}
Example #5
0
/**
 * \fn init_gic_cpu
 *
 * Initialise GIC CPU interface
 */
void init_gic_cpu()
{
	unsigned int i;
	GICD[GICD_ICENABLER(0)] = 0xFFFF0000;
	GICD[GICD_ISENABLER(0)] = 0x0000FFFF;
	for (i = 0; i < 128; i += 4)
		GICD[GICD_IPRIORITYR(i / 4)] = 0xa0a0a0a0;

	GICC[GICC_PMR] = 0xff;
	GICC[GICC_BPR] = 0;
	GICC[GICC_CTLR] = 0x201;
}
Example #6
0
void irqctrl_enable(unsigned int irq) {
	int n = irq / BITS_PER_REGISTER;
	int m = irq % BITS_PER_REGISTER;
	uint32_t tmp;

	/* Writing zeroes to this register has no
	 * effect, so we just write single "1" */
	REG_STORE(GICD_ISENABLER(n), 1 << m);

	/* N-N irq model: all CPUs receive this IRQ */
	REG_STORE(GICD_ICFGR(n), 1 << m);

	/* All CPUs do listen to this IRQ */
	n = irq / 4;
	m = irq % 4;
	tmp  = REG_LOAD(GICD_ITARGETSR(n));
	tmp |= 0xFF << (8 * m);
	REG_STORE(GICD_ITARGETSR(n), tmp);
}
Example #7
0
File: gic.c Project: lorc/optee_os
static bool gic_it_is_enabled(struct gic_data *gd, size_t it)
{
	size_t idx = it / NUM_INTS_PER_REG;
	uint32_t mask = 1 << (it % NUM_INTS_PER_REG);
	return !!(read32(gd->gicd_base + GICD_ISENABLER(idx)) & mask);
}
Example #8
0
bool gic_it_is_enabled(size_t it) {
	size_t idx = it / NUM_INTS_PER_REG;
	uint32_t mask = 1 << (it % NUM_INTS_PER_REG);
	return !!(read32(gic.gicd_base + GICD_ISENABLER(idx)) & mask);
}
Example #9
0
/**
 * \fn enable_irq(unsigned int irqn)
 *
 * Enable IRQ in GICD, setting target CPU to cpu0 and priority to 0xa0
 */
void enable_irq(unsigned int irqn)
{
	GICD[GICD_ISENABLER(irqn / 32)] = 1 << (irqn % 32);
	GICD[GICD_ITARGETSR(irqn / 4)] |= (0x01 << ((irqn % 4) * 8));
	GICD[GICD_IPRIORITYR(irqn / 4)] |= (0xa0 << ((irqn % 4) * 8));
}