Beispiel #1
0
void gic_init(vaddr_t gicc_base, vaddr_t gicd_base)
{
	size_t n;

	gic.gicc_base = gicc_base;
	gic.gicd_base = gicd_base;
	gic.max_it = probe_max_it();

	for (n = 0; n <= gic.max_it / NUM_INTS_PER_REG; n++) {
		/* Disable interrupts */
		write32(0xffffffff, gic.gicd_base + GICD_ICENABLER(n));

		/* Make interrupts non-pending */
		write32(0xffffffff, gic.gicd_base + GICD_ICPENDR(n));

		/* Mark interrupts non-secure */
		if (n == 0) {
			/* per-CPU inerrupts config:
                         * ID0-ID7(SGI)   for Non-secure interrupts
                         * ID8-ID15(SGI)  for Secure interrupts.
                         * All PPI config as Non-secure interrupts.
			 */
			write32(0xffff00ff, gic.gicd_base + GICD_IGROUPR(n));
		} else {
			write32(0xffffffff, gic.gicd_base + GICD_IGROUPR(n));
		}
	}

	/* Enable GIC */
	write32(GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1 | GICC_CTLR_FIQEN,
		gic.gicc_base + GICC_CTLR);
	write32(GICD_CTLR_ENABLEGRP0 | GICD_CTLR_ENABLEGRP1,
		gic.gicd_base + GICD_CTLR);
}
Beispiel #2
0
static void gic_it_add(struct gic_data *gd, size_t it)
{
	size_t idx = it / NUM_INTS_PER_REG;
	uint32_t mask = 1 << (it % NUM_INTS_PER_REG);

	/* Disable the interrupt */
	write32(mask, gd->gicd_base + GICD_ICENABLER(idx));
	/* Make it non-pending */
	write32(mask, gd->gicd_base + GICD_ICPENDR(idx));
	/* Assign it to group0 */
	write32(read32(gd->gicd_base + GICD_IGROUPR(idx)) & ~mask,
			gd->gicd_base + GICD_IGROUPR(idx));
}
Beispiel #3
0
void gic_it_add(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 */

	/* Disable the interrupt */
	write32(mask, gic.gicd_base + GICD_ICENABLER(idx));
	/* Make it non-pending */
	write32(mask, gic.gicd_base + GICD_ICPENDR(idx));
	/* Assign it to group0 */
	write32(read32(gic.gicd_base + GICD_IGROUPR(idx)) & ~mask,
			gic.gicd_base + GICD_IGROUPR(idx));
}
Beispiel #4
0
void gic_init(vaddr_t gicc_base, vaddr_t gicd_base)
{
	size_t n;

	gic.gicc_base = gicc_base;
	gic.gicd_base = gicd_base;
	gic.max_it = probe_max_it();

	for (n = 0; n <= gic.max_it / 32; n++) {
		/* Disable interrupts */
		write32(0xffffffff, gic.gicd_base + GICD_ICENABLER(n));

		/* Make interrupts non-pending */
		write32(0xffffffff, gic.gicd_base + GICD_ICPENDR(n));

		/* Mark interrupts non-secure */
		write32(0xffffffff, gic.gicd_base + GICD_IGROUPR(n));
	}

	/* Enable GIC */
	write32(GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1 | GICC_CTLR_FIQEN,
		gic.gicc_base + GICC_CTLR);
	write32(GICD_CTLR_ENABLEGRP0 | GICD_CTLR_ENABLEGRP1,
		gic.gicd_base + GICD_CTLR);
}
Beispiel #5
0
/**
 * \fn init_gic_distributor
 *
 * Initialise GIC Dirstributor.
 *
 * Configure all IRQs to be active low, level sensitive, target cpu0,
 * priority 0xa0 and disable all interrupts.
 */
void init_gic_distributor()
{
	GICD[GICD_CTLR] = 0x0;	// disable GIC

	unsigned int typer = GICD[GICD_TYPER];
	unsigned int lines = 32 * ((typer & 0x1F) + 1);
	unsigned int i;
	/* set global interrupts to active low, level sensitive */
	for (i = 32; i < lines; i += 16) {
		GICD[GICD_ICFGR(i / 16)] = 0x0;
	}
	for (i = 32; i < lines; i += 4) {
		GICD[GICD_ITARGETSR(i / 4)] = 0x01010101;
	}
	for (i = 32; i < lines; i += 4) {
		GICD[GICD_IPRIORITYR(i / 4)] = 0xa0a0a0a0;
	}
	for (i = 32; i < lines; i += 32) {
		GICD[GICD_ICENABLER(i / 32)] = 0xFFFFFFFF;
	}
	for (i = 32; i < lines; i += 32) {
	  GICD[GICD_IGROUPR(i / 32)] = 0x0;
	}

	GICD[GICD_CTLR] = 0x0;
}
Beispiel #6
0
static void gic_it_disable(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));

	/* Disable the interrupt */
	write32(mask, gd->gicd_base + GICD_ICENABLER(idx));
}
Beispiel #7
0
void gic_it_disable(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));

	/* Disable the interrupt */
	write32(mask, gic.gicd_base + GICD_ICENABLER(idx));
}
Beispiel #8
0
static void gic_it_set_prio(struct gic_data *gd, size_t it, uint8_t prio)
{
	size_t idx __maybe_unused = it / NUM_INTS_PER_REG;
	uint32_t mask __maybe_unused = 1 << (it % NUM_INTS_PER_REG);

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

	/* Set prio it to selected CPUs */
	DMSG("prio: writing 0x%x to 0x%" PRIxVA,
		prio, gd->gicd_base + GICD_IPRIORITYR(0) + it);
	write8(prio, gd->gicd_base + GICD_IPRIORITYR(0) + it);
}
Beispiel #9
0
void gic_cpu_init(void)
{
    /* per-CPU inerrupts config:
    * ID0-ID7(SGI)   for Non-secure interrupts
    * ID8-ID15(SGI)  for Secure interrupts.
    * All PPI config as Non-secure interrupts.
    */
    write32(0xffff00ff, gic.gicd_base + GICD_IGROUPR(0));

    /* Enable GIC */
    write32(GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1 | GICC_CTLR_FIQEN,
        gic.gicc_base + GICC_CTLR);
}
Beispiel #10
0
void gic_it_enable(size_t it)
{
	size_t idx = it / 32;
	uint32_t mask = 1 << (it % 32);

	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));
}
Beispiel #11
0
void gic_it_set_prio(size_t it, uint8_t prio)
{
	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));

	/* Set prio it to selected CPUs */
	DMSG("prio: writing 0x%x to 0x%" PRIxVA,
		prio, gic.gicd_base + GICD_IPRIORITYR(0) + it);
	write8(prio, gic.gicd_base + GICD_IPRIORITYR(0) + it);
}
Beispiel #12
0
void gic_init(struct gic_data *gd, vaddr_t gicc_base, vaddr_t gicd_base)
{
	size_t n;

	gic_init_base_addr(gd, gicc_base, gicd_base);

	for (n = 0; n <= gd->max_it / NUM_INTS_PER_REG; n++) {
		/* Disable interrupts */
		write32(0xffffffff, gd->gicd_base + GICD_ICENABLER(n));

		/* Make interrupts non-pending */
		write32(0xffffffff, gd->gicd_base + GICD_ICPENDR(n));

		/* Mark interrupts non-secure */
		if (n == 0) {
			/* per-CPU inerrupts config:
                         * ID0-ID7(SGI)   for Non-secure interrupts
                         * ID8-ID15(SGI)  for Secure interrupts.
                         * All PPI config as Non-secure interrupts.
			 */
			write32(0xffff00ff, gd->gicd_base + GICD_IGROUPR(n));
		} else {
			write32(0xffffffff, gd->gicd_base + GICD_IGROUPR(n));
		}
	}

	/* Set the priority mask to permit Non-secure interrupts, and to
	 * allow the Non-secure world to adjust the priority mask itself
	 */
	write32(0x80, gd->gicc_base + GICC_PMR);

	/* Enable GIC */
	write32(GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1 | GICC_CTLR_FIQEN,
		gd->gicc_base + GICC_CTLR);
	write32(GICD_CTLR_ENABLEGRP0 | GICD_CTLR_ENABLEGRP1,
		gd->gicd_base + GICD_CTLR);
}
Beispiel #13
0
void gic_cpu_init(struct gic_data *gd)
{
	/* per-CPU interrupts config:
	 * ID0-ID7(SGI)   for Non-secure interrupts
	 * ID8-ID15(SGI)  for Secure interrupts.
	 * All PPI config as Non-secure interrupts.
	 */
	write32(0xffff00ff, gd->gicd_base + GICD_IGROUPR(0));

	/* Set the priority mask to permit Non-secure interrupts, and to
	 * allow the Non-secure world to adjust the priority mask itself
	 */
	write32(0x80, gd->gicc_base + GICC_PMR);

	/* Enable GIC */
	write32(GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1 | GICC_CTLR_FIQEN,
		gd->gicc_base + GICC_CTLR);
}
Beispiel #14
0
void gic_it_set_cpu_mask(size_t it, uint8_t cpu_mask)
{
	size_t idx = it / 32;
	uint32_t mask = 1 << (it % 32);
	uint32_t target;

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

	/* Route it to selected CPUs */
	target = read32(gic.gicd_base + GICD_ITARGETSR(it / 4));
	target &= ~(0xff << ((it % 4) * 8));
	target |= cpu_mask << ((it % 4) * 8);
	DMSG("cpu_mask: writing 0x%x to 0x%x\n",
		target, gic.gicd_base + GICD_ITARGETSR(it / 4));
	write32(target, gic.gicd_base + GICD_ITARGETSR(it / 4));
	DMSG("cpu_mask: 0x%x\n",
		read32(gic.gicd_base + GICD_ITARGETSR(it / 4)));
}
Beispiel #15
0
void gic_it_set_cpu_mask(size_t it, uint8_t cpu_mask)
{
	size_t idx = it / NUM_INTS_PER_REG;
	uint32_t mask = 1 << (it % NUM_INTS_PER_REG);
	uint32_t target, target_shift;

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

	/* Route it to selected CPUs */
	target = read32(gic.gicd_base + GICD_ITARGETSR(it / NUM_TARGETS_PER_REG));
	target_shift = (it % NUM_TARGETS_PER_REG) * ITARGETSR_FIELD_BITS;
	target &= ~(ITARGETSR_FIELD_MASK << target_shift);
	target |= cpu_mask << target_shift;
	DMSG("cpu_mask: writing 0x%x to 0x%" PRIxVA,
		target, gic.gicd_base + GICD_ITARGETSR(it / NUM_TARGETS_PER_REG));
	write32(target, gic.gicd_base + GICD_ITARGETSR(it / NUM_TARGETS_PER_REG));
	DMSG("cpu_mask: 0x%x\n",
		read32(gic.gicd_base + GICD_ITARGETSR(it / NUM_TARGETS_PER_REG)));
}
Beispiel #16
0
static void gic_it_set_cpu_mask(struct gic_data *gd, size_t it,
				uint8_t cpu_mask)
{
	size_t idx __maybe_unused = it / NUM_INTS_PER_REG;
	uint32_t mask __maybe_unused = 1 << (it % NUM_INTS_PER_REG);
	uint32_t target, target_shift;

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

	/* Route it to selected CPUs */
	target = read32(gd->gicd_base +
			GICD_ITARGETSR(it / NUM_TARGETS_PER_REG));
	target_shift = (it % NUM_TARGETS_PER_REG) * ITARGETSR_FIELD_BITS;
	target &= ~(ITARGETSR_FIELD_MASK << target_shift);
	target |= cpu_mask << target_shift;
	DMSG("cpu_mask: writing 0x%x to 0x%" PRIxVA,
	     target, gd->gicd_base + GICD_ITARGETSR(it / NUM_TARGETS_PER_REG));
	write32(target,
		gd->gicd_base + GICD_ITARGETSR(it / NUM_TARGETS_PER_REG));
	DMSG("cpu_mask: 0x%x\n",
	     read32(gd->gicd_base + GICD_ITARGETSR(it / NUM_TARGETS_PER_REG)));
}
Beispiel #17
0
static bool __maybe_unused gic_it_get_group(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_IGROUPR(idx)) & mask);
}
/*
 *  ディストリビュータの初期化
 */
void
gicd_initialize(void)
{
	int		i;

	/*
	 *  ディストリビュータをディスエーブル
	 */
	sil_wrw_mem(GICD_CTLR, GICD_CTLR_DISABLE);

#ifdef TOPPERS_SAFEG_SECURE
	/*
	 *  すべての割込みをグループ1(IRQ)に設定
	 */
	for (i = 0; i < (GIC_TNUM_INTNO + 31) / 32; i++) {
		sil_wrw_mem(GICD_IGROUPR(i), 0xffffffffU);
	}
#endif /* TOPPERS_SAFEG_SECURE */

	/*
	 *  すべての割込みを禁止
	 */
	for (i = 0; i < (GIC_TNUM_INTNO + 31) / 32; i++) {
		sil_wrw_mem(GICD_ICENABLER(i), 0xffffffffU);
	}

	/*
	 *  すべての割込みペンディングをクリア
	 */
	for (i = 0; i < (GIC_TNUM_INTNO + 31) / 32; i++) {
		sil_wrw_mem(GICD_ICPENDR(i), 0xffffffffU);
	}

	/*
	 *  すべての割込みを最低優先度に設定
	 */
	for (i = 0; i < (GIC_TNUM_INTNO + 3) / 4; i++){
		sil_wrw_mem(GICD_IPRIORITYR(i), 0xffffffffU);
	}

	/*
	 *  すべての共有ペリフェラル割込みのターゲットをプロセッサ0に設定
	 */
	for (i = GIC_INTNO_SPI0 / 4; i < (GIC_TNUM_INTNO + 3) / 4; i++) {
		sil_wrw_mem(GICD_ITARGETSR(i), 0x01010101U);
	}

	/*
	 *  すべてのペリフェラル割込みをレベルトリガに設定
	 */
	for (i = GIC_INTNO_PPI0 / 16; i < (GIC_TNUM_INTNO + 15) / 16; i++) {
#ifdef GIC_ARM11MPCORE
		sil_wrw_mem(GICD_ICFGR(i), 0x55555555U);
#else /* GIC_ARM11MPCORE */
		sil_wrw_mem(GICD_ICFGR(i), 0x00000000U);
#endif /* GIC_ARM11MPCORE */
	}

	/*
	 *  ディストリビュータをイネーブル
	 */
	sil_wrw_mem(GICD_CTLR, GICD_CTLR_ENABLE);
}
Beispiel #19
0
bool gic_it_get_group(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_IGROUPR(idx)) & mask);
}