Пример #1
0
/**
 *
 * @brief initialize the MVIC IO APIC and local APIC register sets.
 *
 * This routine initializes the Quark D2000 Interrupt Controller (MVIC).
 * This routine replaces the standard Local APIC / IO APIC init routines.
 *
 * @returns: N/A
 */
static int _mvic_init(struct device *unused)
{
	ARG_UNUSED(unused);
	int i;

	/* By default mask all interrupt lines */
	for (i = 0; i < MVIC_NUM_RTES; i++) {
		_mvic_rte_set(i, MVIC_IOWIN_MASK);
	}

	/* reset the task priority and timer initial count registers */
	sys_write32(0, MVIC_TPR);
	sys_write32(0, MVIC_ICR);

	/* Initialize and mask the timer interrupt.
	 * Bits 0-3 program the interrupt line number we will use
	 * for the timer interrupt.
	 */
	__ASSERT(CONFIG_MVIC_TIMER_IRQ < 16,
		 "Bad irq line %d chosen for timer irq", CONFIG_MVIC_TIMER_IRQ);
	sys_write32(MVIC_LVTTIMER_MASK | CONFIG_MVIC_TIMER_IRQ, MVIC_LVTTIMER);

	/* discard a pending interrupt if any */
	sys_write32(0, MVIC_EOI);

	return 0;

}
Пример #2
0
/**
 *
 * @brief Programs Rte interrupt line register.
 *
 * Always mask interrupt as part of programming like standard IOAPIC
 * version of this routine.
 * Vector is fixed by this HW and is unused.
 * Or in flags for trigger bit.
 *
 * @param irq Virtualized IRQ
 * @param vector Vector Number
 * @param flags Interrupt flags
 *
 * @returns: N/A
 */
void _ioapic_irq_set(unsigned int irq, unsigned int vector, uint32_t flags)
{
	uint32_t rteValue;   /* value to copy into Rte register */

	ARG_UNUSED(vector);

	rteValue = IOAPIC_INT_MASK | flags;
	_mvic_rte_set(irq, rteValue);
}
Пример #3
0
void __irq_controller_irq_config(unsigned int vector, unsigned int irq,
				 u32_t flags)
{
	ARG_UNUSED(vector);

	/* Vector argument always ignored. There are no triggering options
	 * for the timer, so nothing to do at all for that case. Other I/O
	 * interrupts need their triggering set
	 */
	if (irq != CONFIG_MVIC_TIMER_IRQ) {
		_mvic_rte_set(irq, MVIC_IOWIN_MASK | flags);
	} else {
		__ASSERT(flags == 0,
			 "Timer interrupt cannot have triggering flags set");
	}
}
Пример #4
0
/**
 *
 * @brief initialize the MVIC IO APIC and local APIC register sets.
 *
 * This routine initializes the Quark D2000 Interrupt Controller (MVIC).
 * This routine replaces the standard Local APIC / IO APIC init routines.
 *
 * @returns: N/A
 */
int _mvic_init(struct device *unused)
{
	ARG_UNUSED(unused);
	int32_t ix;	/* Interrupt line register index */
	uint32_t rteValue; /* value to copy into interrupt line register */

	/*
	 * The platform must define the CONFIG_IOAPIC_NUM_RTES macro to indicate the number
	 * of redirection table entries supported by the IOAPIC on the board.
	 *

	 * By default mask all interrupt lines and set default sensitivity to edge.
	 *
	 */

	rteValue = IOAPIC_EDGE | IOAPIC_INT_MASK;

	for (ix = 0; ix < CONFIG_IOAPIC_NUM_RTES; ix++) {
		_mvic_rte_set(ix, rteValue);
	}

	/* enable the MVIC Local APIC */

	_loapic_enable();

	/* reset the TPR, and TIMER_ICR */

	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_TPR) = (int)0x0;
	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_TIMER_ICR) = (int)0x0;

	/* program Local Vector Table for the Virtual Wire Mode */

	/* lock the MVIC timer interrupt, set which IRQ line should be
	 * used for timer interrupts (this is unlike LOAPIC where the
	 * vector is programmed instead).
	 */
	__ASSERT_NO_MSG(CONFIG_LOAPIC_TIMER_IRQ <= 15);
	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_TIMER) =
		LOAPIC_LVT_MASKED | CONFIG_LOAPIC_TIMER_IRQ;

	/* discard a pending interrupt if any */

	*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI) = 0;

	return 0;

}
Пример #5
0
/**
 *
 * @brief modify interrupt line register.
 *
 * @param irq INTIN number
 * @param value value to be written
 * @param mask of bits to be modified
 *
 * @returns N/A
 */
static void _mvic_rte_update(unsigned int irq, uint32_t value, uint32_t mask)
{
	_mvic_rte_set(irq, (_mvic_rte_get(irq) & ~mask) | (value & mask));
}