drivers/interrupt_controller/mvic.c: remove MVIC interrupt controller
The Quark D2000 is the only x86 with an MVIC, and since support for it has been dropped, the interrupt controller is orphaned. Removed. Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
parent
c6c9dcf28c
commit
3dc7c7a6ea
16 changed files with 5 additions and 435 deletions
|
@ -4,7 +4,6 @@ zephyr_sources_ifdef(CONFIG_ARCV2_INTERRUPT_UNIT arcv2_irq_unit.c)
|
|||
zephyr_sources_ifdef(CONFIG_IOAPIC ioapic_intr.c)
|
||||
zephyr_sources_ifdef(CONFIG_LOAPIC loapic_intr.c system_apic.c)
|
||||
zephyr_sources_ifdef(CONFIG_LOAPIC_SPURIOUS_VECTOR loapic_spurious.S)
|
||||
zephyr_sources_ifdef(CONFIG_MVIC mvic.c)
|
||||
zephyr_sources_ifdef(CONFIG_PLIC plic.c)
|
||||
zephyr_sources_ifdef(CONFIG_SHARED_IRQ shared_irq.c)
|
||||
zephyr_sources_ifdef(CONFIG_EXTI_STM32 exti_stm32.c)
|
||||
|
|
|
@ -84,27 +84,6 @@ config IOAPIC_MASK_RTE
|
|||
|
||||
endif #LOAPIC
|
||||
|
||||
config MVIC
|
||||
bool "Intel Quark D2000 Interrupt Controller (MVIC)"
|
||||
depends on X86
|
||||
select X86_FIXED_IRQ_MAPPING
|
||||
help
|
||||
The MVIC (Intel Quark microcontroller D2000 Interrupt Controller) is
|
||||
configured by default to support 32 external interrupt lines. Unlike the
|
||||
traditional IA LAPIC/IOAPIC, the interrupt vectors in MVIC are fixed and
|
||||
not programmable. In addition, the priorities of these interrupt
|
||||
lines are also fixed.
|
||||
|
||||
config MVIC_TIMER_IRQ
|
||||
int "IRQ line to use for timer interrupt"
|
||||
range 0 15
|
||||
default 10
|
||||
depends on MVIC
|
||||
help
|
||||
Specify the IRQ line to use for the timer interrupt. This should be
|
||||
an IRQ line unused by any hardware. If nested interrupts are enabled,
|
||||
higher interrupt lines have priority.
|
||||
|
||||
config ARCV2_INTERRUPT_UNIT
|
||||
bool "ARCv2 Interrupt Unit"
|
||||
default y
|
||||
|
|
|
@ -1,225 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Quark D2000 Interrupt Controller (MVIC)
|
||||
*
|
||||
* This module is based on the standard Local APIC and IO APIC source modules.
|
||||
* This modules combines these modules into one source module that exports the
|
||||
* same APIs defined by the Local APIC and IO APIC header modules. These
|
||||
* routine have been adapted for the Quark D2000 Interrupt Controller which has
|
||||
* a cutdown implementation of the Local APIC & IO APIC register sets.
|
||||
*
|
||||
* The MVIC (Quark D2000 Interrupt Controller) is configured by default
|
||||
* to support 32 external interrupt lines.
|
||||
* Unlike the traditional IA LAPIC/IOAPIC, the interrupt vectors in MVIC are fixed
|
||||
* and not programmable.
|
||||
* The larger the vector number, the higher the priority of the interrupt.
|
||||
* Higher priority interrupts preempt lower priority interrupts.
|
||||
* Lower priority interrupts do not preempt higher priority interrupts.
|
||||
* The MVIC holds the lower priority interrupts pending until the interrupt
|
||||
* service routine for the higher priority interrupt writes to the End of
|
||||
* Interrupt (EOI) register.
|
||||
* After an EOI write, the MVIC asserts the next highest pending interrupt.
|
||||
*
|
||||
* INCLUDE FILES: ioapic.h loapic.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include <kernel.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <misc/__assert.h>
|
||||
#include <misc/util.h>
|
||||
#include <init.h>
|
||||
#include <arch/x86/irq_controller.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
static inline u32_t compute_ioregsel(unsigned int irq)
|
||||
{
|
||||
unsigned int low_nibble;
|
||||
unsigned int high_nibble;
|
||||
|
||||
__ASSERT(irq < MVIC_NUM_RTES, "invalid irq line %d", irq);
|
||||
|
||||
low_nibble = ((irq & MVIC_LOW_NIBBLE_MASK) << 0x1);
|
||||
high_nibble = ((irq & MVIC_HIGH_NIBBLE_MASK) << 0x2);
|
||||
return low_nibble | high_nibble;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief write to 32 bit MVIC IO APIC register
|
||||
*
|
||||
* @param irq INTIN number
|
||||
* @param value value to be written
|
||||
*
|
||||
* @returns N/A
|
||||
*/
|
||||
static void mvic_rte_set(unsigned int irq, u32_t value)
|
||||
{
|
||||
unsigned int key; /* interrupt lock level */
|
||||
u32_t regsel;
|
||||
|
||||
__ASSERT(!(value & ~MVIC_IOWIN_SUPPORTED_BITS_MASK),
|
||||
"invalid IRQ flags %" PRIx32 " for irq %d", value, irq);
|
||||
|
||||
regsel = compute_ioregsel(irq);
|
||||
|
||||
/* lock interrupts to ensure indirect addressing works "atomically" */
|
||||
key = irq_lock();
|
||||
|
||||
sys_write32(regsel, MVIC_IOREGSEL);
|
||||
sys_write32(value, MVIC_IOWIN);
|
||||
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @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, u32_t value, u32_t mask)
|
||||
{
|
||||
unsigned int key;
|
||||
u32_t regsel, old_value, updated_value;
|
||||
|
||||
__ASSERT(!(value & ~MVIC_IOWIN_SUPPORTED_BITS_MASK),
|
||||
"invalid IRQ flags %" PRIx32 " for irq %d", value, irq);
|
||||
|
||||
regsel = compute_ioregsel(irq);
|
||||
|
||||
key = irq_lock();
|
||||
|
||||
sys_write32(regsel, MVIC_IOREGSEL);
|
||||
|
||||
old_value = sys_read32(MVIC_IOWIN);
|
||||
updated_value = (old_value & ~mask) | (value & mask);
|
||||
sys_write32(updated_value, MVIC_IOWIN);
|
||||
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @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;
|
||||
|
||||
}
|
||||
SYS_INIT(mvic_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
||||
|
||||
|
||||
void z_arch_irq_enable(unsigned int irq)
|
||||
{
|
||||
if (irq == CONFIG_MVIC_TIMER_IRQ) {
|
||||
sys_write32(sys_read32(MVIC_LVTTIMER) & ~MVIC_LVTTIMER_MASK,
|
||||
MVIC_LVTTIMER);
|
||||
} else {
|
||||
mvic_rte_update(irq, 0, MVIC_IOWIN_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void z_arch_irq_disable(unsigned int irq)
|
||||
{
|
||||
if (irq == CONFIG_MVIC_TIMER_IRQ) {
|
||||
sys_write32(sys_read32(MVIC_LVTTIMER) | MVIC_LVTTIMER_MASK,
|
||||
MVIC_LVTTIMER);
|
||||
} else {
|
||||
mvic_rte_update(irq, MVIC_IOWIN_MASK, MVIC_IOWIN_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 == 0U,
|
||||
"Timer interrupt cannot have triggering flags set");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Find the currently executing interrupt vector, if any
|
||||
*
|
||||
* This routine finds the vector of the interrupt that is being processed.
|
||||
* The ISR (In-Service Register) register contain the vectors of the interrupts
|
||||
* in service. And the higher vector is the identification of the interrupt
|
||||
* being currently processed.
|
||||
*
|
||||
* MVIC ISR registers' offsets:
|
||||
* --------------------
|
||||
* | Offset | bits |
|
||||
* --------------------
|
||||
* | 0110H | 32:63 |
|
||||
* --------------------
|
||||
*
|
||||
* @return The vector of the interrupt that is currently being processed, or
|
||||
* -1 if this can't be determined
|
||||
*/
|
||||
int __irq_controller_isr_vector_get(void)
|
||||
{
|
||||
/* In-service register value */
|
||||
int isr;
|
||||
|
||||
isr = sys_read32(MVIC_ISR);
|
||||
if (unlikely(!isr)) {
|
||||
return -1;
|
||||
}
|
||||
return 32 + (find_msb_set(isr) - 1);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue