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
|
@ -230,7 +230,6 @@
|
||||||
/include/drivers/modem/ @mike-scott
|
/include/drivers/modem/ @mike-scott
|
||||||
/include/drivers/ioapic.h @andrewboie
|
/include/drivers/ioapic.h @andrewboie
|
||||||
/include/drivers/loapic.h @andrewboie
|
/include/drivers/loapic.h @andrewboie
|
||||||
/include/drivers/mvic.h @andrewboie
|
|
||||||
/include/drivers/pcie/ @gnuless
|
/include/drivers/pcie/ @gnuless
|
||||||
/include/drivers/serial/uart_ns16550.h @gnuless
|
/include/drivers/serial/uart_ns16550.h @gnuless
|
||||||
/include/dt-bindings/clock/kinetis_scg.h @henrikbrixandersen
|
/include/dt-bindings/clock/kinetis_scg.h @henrikbrixandersen
|
||||||
|
|
|
@ -345,27 +345,19 @@ config X86_KERNEL_OOPS
|
||||||
|
|
||||||
config X86_KERNEL_OOPS_VECTOR
|
config X86_KERNEL_OOPS_VECTOR
|
||||||
int "IDT vector to use for kernel oops"
|
int "IDT vector to use for kernel oops"
|
||||||
default 62 if MVIC
|
default 33
|
||||||
default 33 if !MVIC
|
|
||||||
range 32 255
|
range 32 255
|
||||||
depends on X86_KERNEL_OOPS
|
depends on X86_KERNEL_OOPS
|
||||||
help
|
help
|
||||||
Specify the IDT vector to use for the kernel oops exception handler.
|
Specify the IDT vector to use for the kernel oops exception handler.
|
||||||
The default should be fine for most arches, but on systems like MVIC
|
|
||||||
where there is a fixed IRQ-to-vector mapping another value may be
|
|
||||||
needed to avoid collision.
|
|
||||||
|
|
||||||
config IRQ_OFFLOAD_VECTOR
|
config IRQ_OFFLOAD_VECTOR
|
||||||
int "IDT vector to use for IRQ offload"
|
int "IDT vector to use for IRQ offload"
|
||||||
default 63 if MVIC
|
default 32
|
||||||
default 32 if !MVIC
|
|
||||||
range 32 255
|
range 32 255
|
||||||
depends on IRQ_OFFLOAD
|
depends on IRQ_OFFLOAD
|
||||||
help
|
help
|
||||||
Specify the IDT vector to use for the IRQ offload interrupt handler.
|
Specify the IDT vector to use for the IRQ offload interrupt handler.
|
||||||
The default should be fine for most arches, but on systems like MVIC
|
|
||||||
where there is a fixed IRQ-to-vector mapping another value may be
|
|
||||||
needed to avoid collision.
|
|
||||||
|
|
||||||
config X86_DYNAMIC_IRQ_STUBS
|
config X86_DYNAMIC_IRQ_STUBS
|
||||||
int "Number of dynamic interrupt stubs"
|
int "Number of dynamic interrupt stubs"
|
||||||
|
|
|
@ -249,10 +249,6 @@ static void idt_vector_install(int vector, void *irq_handler)
|
||||||
key = irq_lock();
|
key = irq_lock();
|
||||||
z_init_irq_gate(&z_x86_idt.entries[vector], CODE_SEG,
|
z_init_irq_gate(&z_x86_idt.entries[vector], CODE_SEG,
|
||||||
(u32_t)irq_handler, 0);
|
(u32_t)irq_handler, 0);
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
/* MVIC requires IDT be reloaded if the entries table is ever changed */
|
|
||||||
z_set_idt(&z_x86_idt);
|
|
||||||
#endif
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,10 +320,7 @@ There can be significant differences between the interrupt controllers and the
|
||||||
interrupt concepts across architectures.
|
interrupt concepts across architectures.
|
||||||
|
|
||||||
For example, x86 has the concept of an :abbr:`IDT (Interrupt Descriptor Table)`
|
For example, x86 has the concept of an :abbr:`IDT (Interrupt Descriptor Table)`
|
||||||
and different interrupt controllers. Although modern systems mostly
|
and different interrupt controllers. The position of an interrupt in the IDT
|
||||||
standardized on the :abbr:`APIC (Advanced Programmable Interrupt Controller)`,
|
|
||||||
some small Quark-based systems use the :abbr:`MVIC (Micro-controller Vectored
|
|
||||||
Interrupt Controller)`. Also, the position of an interrupt in the IDT
|
|
||||||
determines its priority.
|
determines its priority.
|
||||||
|
|
||||||
On the other hand, the ARM Cortex-M has the :abbr:`NVIC (Nested Vectored
|
On the other hand, the ARM Cortex-M has the :abbr:`NVIC (Nested Vectored
|
||||||
|
|
|
@ -389,10 +389,6 @@ scheme, interrupts of priority level 0 will be placed in vectors 32-47, level 1
|
||||||
configures an interrupt it will look for a free vector in the appropriate range
|
configures an interrupt it will look for a free vector in the appropriate range
|
||||||
for the requested priority level and set the handler there.
|
for the requested priority level and set the handler there.
|
||||||
|
|
||||||
There are some APIC variants (such as MVIC) where priorities cannot be set
|
|
||||||
by the user and the position in the vector table does correspond to the
|
|
||||||
IRQ line. Systems like this will enable CONFIG_X86_FIXED_IRQ_MAPPING.
|
|
||||||
|
|
||||||
On x86 when an interrupt or exception vector is executed by the CPU, there is
|
On x86 when an interrupt or exception vector is executed by the CPU, there is
|
||||||
no foolproof way to determine which vector was fired, so a software ISR table
|
no foolproof way to determine which vector was fired, so a software ISR table
|
||||||
indexed by IRQ line is not used. Instead, the :c:macro:`IRQ_CONNECT` call
|
indexed by IRQ line is not used. Instead, the :c:macro:`IRQ_CONNECT` call
|
||||||
|
|
|
@ -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_IOAPIC ioapic_intr.c)
|
||||||
zephyr_sources_ifdef(CONFIG_LOAPIC loapic_intr.c system_apic.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_LOAPIC_SPURIOUS_VECTOR loapic_spurious.S)
|
||||||
zephyr_sources_ifdef(CONFIG_MVIC mvic.c)
|
|
||||||
zephyr_sources_ifdef(CONFIG_PLIC plic.c)
|
zephyr_sources_ifdef(CONFIG_PLIC plic.c)
|
||||||
zephyr_sources_ifdef(CONFIG_SHARED_IRQ shared_irq.c)
|
zephyr_sources_ifdef(CONFIG_SHARED_IRQ shared_irq.c)
|
||||||
zephyr_sources_ifdef(CONFIG_EXTI_STM32 exti_stm32.c)
|
zephyr_sources_ifdef(CONFIG_EXTI_STM32 exti_stm32.c)
|
||||||
|
|
|
@ -84,27 +84,6 @@ config IOAPIC_MASK_RTE
|
||||||
|
|
||||||
endif #LOAPIC
|
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
|
config ARCV2_INTERRUPT_UNIT
|
||||||
bool "ARCv2 Interrupt Unit"
|
bool "ARCv2 Interrupt Unit"
|
||||||
default y
|
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);
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
#if defined(CONFIG_IOAPIC) || defined(CONFIG_MVIC)
|
#if defined(CONFIG_IOAPIC)
|
||||||
#include <ioapic.h>
|
#include <ioapic.h>
|
||||||
#endif
|
#endif
|
||||||
#include <uart.h>
|
#include <uart.h>
|
||||||
|
|
|
@ -44,7 +44,7 @@ endif #HPET_TIMER
|
||||||
|
|
||||||
menuconfig LOAPIC_TIMER
|
menuconfig LOAPIC_TIMER
|
||||||
bool "LOAPIC timer"
|
bool "LOAPIC timer"
|
||||||
depends on (LOAPIC || MVIC) && X86
|
depends on LOAPIC && X86
|
||||||
help
|
help
|
||||||
This option selects LOAPIC timer as a system timer.
|
This option selects LOAPIC timer as a system timer.
|
||||||
|
|
||||||
|
|
|
@ -110,10 +110,8 @@ static unsigned char timer_mode = TIMER_MODE_PERIODIC;
|
||||||
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
||||||
static u32_t loapic_timer_device_power_state;
|
static u32_t loapic_timer_device_power_state;
|
||||||
static u32_t reg_timer_save;
|
static u32_t reg_timer_save;
|
||||||
#ifndef CONFIG_MVIC
|
|
||||||
static u32_t reg_timer_cfg_save;
|
static u32_t reg_timer_cfg_save;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -125,13 +123,8 @@ static u32_t reg_timer_cfg_save;
|
||||||
*/
|
*/
|
||||||
static inline void periodic_mode_set(void)
|
static inline void periodic_mode_set(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
sys_write32(sys_read32(MVIC_LVTTIMER) | LOAPIC_TIMER_PERIODIC,
|
|
||||||
MVIC_LVTTIMER);
|
|
||||||
#else
|
|
||||||
x86_write_loapic(LOAPIC_TIMER,
|
x86_write_loapic(LOAPIC_TIMER,
|
||||||
x86_read_loapic(LOAPIC_TIMER) | LOAPIC_TIMER_PERIODIC);
|
x86_read_loapic(LOAPIC_TIMER) | LOAPIC_TIMER_PERIODIC);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,11 +140,7 @@ static inline void periodic_mode_set(void)
|
||||||
*/
|
*/
|
||||||
static inline void initial_count_register_set(u32_t count)
|
static inline void initial_count_register_set(u32_t count)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
sys_write32(count, MVIC_ICR);
|
|
||||||
#else
|
|
||||||
x86_write_loapic(LOAPIC_TIMER_ICR, count);
|
x86_write_loapic(LOAPIC_TIMER_ICR, count);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_TICKLESS_IDLE)
|
#if defined(CONFIG_TICKLESS_IDLE)
|
||||||
|
@ -165,13 +154,8 @@ static inline void initial_count_register_set(u32_t count)
|
||||||
*/
|
*/
|
||||||
static inline void one_shot_mode_set(void)
|
static inline void one_shot_mode_set(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
sys_write32(sys_read32(MVIC_LVTTIMER) & ~LOAPIC_TIMER_PERIODIC,
|
|
||||||
MVIC_LVTTIMER);
|
|
||||||
#else
|
|
||||||
x86_write_loapic(LOAPIC_TIMER,
|
x86_write_loapic(LOAPIC_TIMER,
|
||||||
x86_read_loapic(LOAPIC_TIMER) & ~LOAPIC_TIMER_PERIODIC);
|
x86_read_loapic(LOAPIC_TIMER) & ~LOAPIC_TIMER_PERIODIC);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_TICKLESS_IDLE */
|
#endif /* CONFIG_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
@ -188,11 +172,7 @@ static inline void one_shot_mode_set(void)
|
||||||
*/
|
*/
|
||||||
static inline u32_t current_count_register_get(void)
|
static inline u32_t current_count_register_get(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
return sys_read32(MVIC_CCR);
|
|
||||||
#else
|
|
||||||
return x86_read_loapic(LOAPIC_TIMER_CCR);
|
return x86_read_loapic(LOAPIC_TIMER_CCR);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -207,11 +187,7 @@ static inline u32_t current_count_register_get(void)
|
||||||
*/
|
*/
|
||||||
static inline u32_t initial_count_register_get(void)
|
static inline u32_t initial_count_register_get(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
return sys_read32(MVIC_ICR);
|
|
||||||
#else
|
|
||||||
return x86_read_loapic(LOAPIC_TIMER_ICR);
|
return x86_read_loapic(LOAPIC_TIMER_ICR);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_TICKLESS_IDLE */
|
#endif /* CONFIG_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
@ -603,11 +579,9 @@ int z_clock_driver_init(struct device *device)
|
||||||
|
|
||||||
tickless_idle_init();
|
tickless_idle_init();
|
||||||
|
|
||||||
#ifndef CONFIG_MVIC
|
|
||||||
x86_write_loapic(LOAPIC_TIMER_CONFIG,
|
x86_write_loapic(LOAPIC_TIMER_CONFIG,
|
||||||
(x86_read_loapic(LOAPIC_TIMER_CONFIG) & ~0xf)
|
(x86_read_loapic(LOAPIC_TIMER_CONFIG) & ~0xf)
|
||||||
| LOAPIC_TIMER_DIVBY_1);
|
| LOAPIC_TIMER_DIVBY_1);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_TICKLESS_KERNEL
|
#ifdef CONFIG_TICKLESS_KERNEL
|
||||||
one_shot_mode_set();
|
one_shot_mode_set();
|
||||||
|
@ -619,14 +593,9 @@ int z_clock_driver_init(struct device *device)
|
||||||
loapic_timer_device_power_state = DEVICE_PM_ACTIVE_STATE;
|
loapic_timer_device_power_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
IRQ_CONNECT(CONFIG_MVIC_TIMER_IRQ, -1, timer_int_handler, 0, 0);
|
|
||||||
irq_enable(CONFIG_MVIC_TIMER_IRQ);
|
|
||||||
#else
|
|
||||||
IRQ_CONNECT(CONFIG_LOAPIC_TIMER_IRQ, CONFIG_LOAPIC_TIMER_IRQ_PRIORITY,
|
IRQ_CONNECT(CONFIG_LOAPIC_TIMER_IRQ, CONFIG_LOAPIC_TIMER_IRQ_PRIORITY,
|
||||||
timer_int_handler, 0, 0);
|
timer_int_handler, 0, 0);
|
||||||
irq_enable(CONFIG_LOAPIC_TIMER_IRQ);
|
irq_enable(CONFIG_LOAPIC_TIMER_IRQ);
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -636,13 +605,8 @@ static int sys_clock_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
ARG_UNUSED(dev);
|
||||||
|
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
reg_timer_save = sys_read32(MVIC_LVTTIMER);
|
|
||||||
#else
|
|
||||||
reg_timer_save = x86_read_loapic(LOAPIC_TIMER);
|
reg_timer_save = x86_read_loapic(LOAPIC_TIMER);
|
||||||
reg_timer_cfg_save = x86_read_loapic(LOAPIC_TIMER_CONFIG);
|
reg_timer_cfg_save = x86_read_loapic(LOAPIC_TIMER_CONFIG);
|
||||||
#endif
|
|
||||||
|
|
||||||
loapic_timer_device_power_state = DEVICE_PM_SUSPEND_STATE;
|
loapic_timer_device_power_state = DEVICE_PM_SUSPEND_STATE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -652,12 +616,8 @@ static int sys_clock_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
ARG_UNUSED(dev);
|
||||||
|
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
sys_write32(reg_timer_save, MVIC_LVTTIMER);
|
|
||||||
#else
|
|
||||||
x86_write_loapic(LOAPIC_TIMER, reg_timer_save);
|
x86_write_loapic(LOAPIC_TIMER, reg_timer_save);
|
||||||
x86_write_loapic(LOAPIC_TIMER_CONFIG, reg_timer_cfg_save);
|
x86_write_loapic(LOAPIC_TIMER_CONFIG, reg_timer_cfg_save);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is difficult to accurately know the time spent in DS.
|
* It is difficult to accurately know the time spent in DS.
|
||||||
|
@ -758,11 +718,7 @@ void sys_clock_disable(void)
|
||||||
|
|
||||||
key = irq_lock();
|
key = irq_lock();
|
||||||
|
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
irq_disable(MVIC_TIMER_IRQ);
|
|
||||||
#else
|
|
||||||
irq_disable(CONFIG_LOAPIC_TIMER_IRQ);
|
irq_disable(CONFIG_LOAPIC_TIMER_IRQ);
|
||||||
#endif
|
|
||||||
|
|
||||||
initial_count_register_set(0);
|
initial_count_register_set(0);
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
|
|
||||||
title: Intel Quark D2000 Interrupt Controller
|
|
||||||
version: 0.1
|
|
||||||
|
|
||||||
description: >
|
|
||||||
This binding describes the Intel Quark D2000 Interrupt
|
|
||||||
Controller
|
|
||||||
|
|
||||||
inherits:
|
|
||||||
!include base.yaml
|
|
||||||
|
|
||||||
properties:
|
|
||||||
compatible:
|
|
||||||
constraint: "intel,mvic"
|
|
||||||
|
|
||||||
reg:
|
|
||||||
category: required
|
|
||||||
|
|
||||||
intel,num-irq-priority-bits:
|
|
||||||
category: required
|
|
||||||
type: int
|
|
||||||
description: number of bits of IRQ priorities
|
|
||||||
generation: define
|
|
||||||
|
|
||||||
"#cells":
|
|
||||||
- irq
|
|
||||||
- sense
|
|
|
@ -163,9 +163,6 @@ typedef struct s_isrList {
|
||||||
* out the right vector to use based on our priority scheme. Groups of 16
|
* out the right vector to use based on our priority scheme. Groups of 16
|
||||||
* vectors starting at 32 correspond to each priority level.
|
* vectors starting at 32 correspond to each priority level.
|
||||||
*
|
*
|
||||||
* On MVIC, the mapping is fixed; the vector to use is just the irq line
|
|
||||||
* number plus 0x20. The priority argument supplied by the user is discarded.
|
|
||||||
*
|
|
||||||
* These macros are only intended to be used by IRQ_CONNECT() macro.
|
* These macros are only intended to be used by IRQ_CONNECT() macro.
|
||||||
*/
|
*/
|
||||||
#if CONFIG_X86_FIXED_IRQ_MAPPING
|
#if CONFIG_X86_FIXED_IRQ_MAPPING
|
||||||
|
|
|
@ -7,21 +7,12 @@
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @brief Abstraction layer for x86 interrupt controllers
|
* @brief Abstraction layer for x86 interrupt controllers
|
||||||
*
|
|
||||||
* Most x86 just support APIC. However we are starting to see design
|
|
||||||
* variants such as MVIC or APICs with reduced feature sets. This
|
|
||||||
* interface provides a layer of abstraction between the core arch code
|
|
||||||
* and the interrupt controller implementation for x86
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZEPHYR_INCLUDE_ARCH_X86_IRQ_CONTROLLER_H_
|
#ifndef ZEPHYR_INCLUDE_ARCH_X86_IRQ_CONTROLLER_H_
|
||||||
#define ZEPHYR_INCLUDE_ARCH_X86_IRQ_CONTROLLER_H_
|
#define ZEPHYR_INCLUDE_ARCH_X86_IRQ_CONTROLLER_H_
|
||||||
|
|
||||||
#ifdef CONFIG_MVIC
|
|
||||||
#include <drivers/mvic.h>
|
|
||||||
#else
|
|
||||||
#include <drivers/sysapic.h>
|
#include <drivers/sysapic.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Triggering flags abstraction layer.
|
/* Triggering flags abstraction layer.
|
||||||
* If a particular set of triggers is not supported, leave undefined
|
* If a particular set of triggers is not supported, leave undefined
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2015 Intel Corporation
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_MVIC_H_
|
|
||||||
#define ZEPHYR_INCLUDE_DRIVERS_MVIC_H_
|
|
||||||
|
|
||||||
#include <arch/cpu.h>
|
|
||||||
|
|
||||||
/* Register defines. A lot of similarities to APIC, but not quite the same */
|
|
||||||
#define MVIC_TPR 0xFEE00080 /* Task priority register */
|
|
||||||
#define MVIC_PPR 0xFEE000A0 /* Process priority register */
|
|
||||||
#define MVIC_EOI 0xFEE000B0 /* End-of-interrupt register */
|
|
||||||
#define MVIC_SIVR 0xFEE000F0 /* Spurious interrupt vector register */
|
|
||||||
#define MVIC_ISR 0xFEE00110 /* In-service register */
|
|
||||||
#define MVIC_IRR 0xFEE00210 /* Interrupt request register */
|
|
||||||
#define MVIC_LVTTIMER 0xFEE00320 /* Local vector table timer register */
|
|
||||||
#define MVIC_ICR 0xFEE00380 /* Timer initial count register */
|
|
||||||
#define MVIC_CCR 0xFEE00390 /* Timer current count register */
|
|
||||||
#define MVIC_IOREGSEL 0xFEC00000 /* Register select (index) */
|
|
||||||
#define MVIC_IOWIN 0xFEC00010 /* Register windows (data) */
|
|
||||||
|
|
||||||
/* MVIC_LVTTIMER bits */
|
|
||||||
#define MVIC_LVTTIMER_MASK BIT(16)
|
|
||||||
#define MVIC_LVTTIMER_PERIODIC BIT(17)
|
|
||||||
|
|
||||||
/* MVIC_IOWIN bits */
|
|
||||||
#define MVIC_IOWIN_TRIGGER_LEVEL BIT(15)
|
|
||||||
#define MVIC_IOWIN_TRIGGER_EDGE 0
|
|
||||||
#define MVIC_IOWIN_MASK BIT(16)
|
|
||||||
#define MVIC_IOWIN_SUPPORTED_BITS_MASK (MVIC_IOWIN_MASK | \
|
|
||||||
MVIC_IOWIN_TRIGGER_LEVEL)
|
|
||||||
|
|
||||||
/* MVIC IOREGSEL register usage defines */
|
|
||||||
#define MVIC_LOW_NIBBLE_MASK 0x07
|
|
||||||
#define MVIC_HIGH_NIBBLE_MASK 0x18
|
|
||||||
|
|
||||||
#define MVIC_NUM_RTES 32
|
|
||||||
|
|
||||||
#define _IRQ_TRIGGER_EDGE MVIC_IOWIN_TRIGGER_EDGE
|
|
||||||
#define _IRQ_TRIGGER_LEVEL MVIC_IOWIN_TRIGGER_LEVEL
|
|
||||||
|
|
||||||
/* MVIC does not support IRQ_POLARITY_HIGH or IRQ_POLARITY_LOW,
|
|
||||||
* leave undefined
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
|
||||||
#include <zephyr/types.h>
|
|
||||||
|
|
||||||
/* Implementation of irq_controller.h interface */
|
|
||||||
|
|
||||||
#define __IRQ_CONTROLLER_VECTOR_MAPPING(irq) ((irq) + 32)
|
|
||||||
|
|
||||||
void __irq_controller_irq_config(unsigned int vector, unsigned int irq,
|
|
||||||
u32_t flags);
|
|
||||||
|
|
||||||
int __irq_controller_isr_vector_get(void);
|
|
||||||
|
|
||||||
static inline void __irq_controller_eoi(void)
|
|
||||||
{
|
|
||||||
*(volatile int *)(MVIC_EOI) = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* _ASMLANGUAGE */
|
|
||||||
|
|
||||||
.macro __irq_controller_eoi_macro
|
|
||||||
xorl %eax, %eax /* zeroes eax */
|
|
||||||
movl %eax, MVIC_EOI /* tell MVIC the IRQ is handled */
|
|
||||||
.endm
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_MVIC_H_ */
|
|
|
@ -50,12 +50,7 @@
|
||||||
#if defined(CONFIG_HPET_TIMER)
|
#if defined(CONFIG_HPET_TIMER)
|
||||||
#define TICK_IRQ CONFIG_HPET_TIMER_IRQ
|
#define TICK_IRQ CONFIG_HPET_TIMER_IRQ
|
||||||
#elif defined(CONFIG_LOAPIC_TIMER)
|
#elif defined(CONFIG_LOAPIC_TIMER)
|
||||||
#if defined(CONFIG_LOAPIC)
|
|
||||||
#define TICK_IRQ CONFIG_LOAPIC_TIMER_IRQ
|
#define TICK_IRQ CONFIG_LOAPIC_TIMER_IRQ
|
||||||
#else
|
|
||||||
/* MVIC case */
|
|
||||||
#define TICK_IRQ CONFIG_MVIC_TIMER_IRQ
|
|
||||||
#endif
|
|
||||||
#elif defined(CONFIG_XTENSA)
|
#elif defined(CONFIG_XTENSA)
|
||||||
#define TICK_IRQ UTIL_CAT(XCHAL_TIMER, \
|
#define TICK_IRQ UTIL_CAT(XCHAL_TIMER, \
|
||||||
UTIL_CAT(CONFIG_XTENSA_TIMER_ID, _INTERRUPT))
|
UTIL_CAT(CONFIG_XTENSA_TIMER_ID, _INTERRUPT))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue