loapic: handle spurious interrupts

A special situation may occur when a processor raises its task
priority to be greater than or equal to the level of the
interrupt for which the processor INTR signal is currently
being asserted. If at the time the INTA cycle is issued, the
interrupt that was to be dispensed has become masked (programmed
by software), the local APIC will deliver a spurious-interrupt
vector. Dispensing the spurious-interrupt vector does not affect
the ISR, so the handler for this vector should return without an EOI.

Change-Id: I4cf4744bd6efd68b72e2c380269de4181dc80bd9
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2015-12-09 14:53:41 -08:00 committed by Anas Nashif
commit c25d6c5d63
4 changed files with 75 additions and 0 deletions

View file

@ -41,6 +41,30 @@ config LOAPIC_BASE_ADDRESS
help
This option specifies the base address of the Local APIC device.
config LOAPIC_SPURIOUS_VECTOR
bool "Handle LOAPIC spurious interrupts"
default n
depends on LOAPIC
help
A special situation may occur when a processor raises its task
priority to be greater than or equal to the level of the
interrupt for which the processor INTR signal is currently being
asserted. If at the time the INTA cycle is issued, the
interrupt that was to be dispensed has become masked (programmed
by software), the local APIC will deliver a spurious-interrupt
vector. Dispensing the spurious-interrupt vector does not affect
the ISR, so the handler for this vector should return without an EOI.
From x86 manual Volume 3 Section 10.9.
config LOAPIC_SPURIOUS_VECTOR_ID
int "LOAPIC spurious vector ID"
default -1
depends on LOAPIC_SPURIOUS_VECTOR
help
IDT vector to use for spurious LOAPIC interrupts. Note that some
arches (P6, Pentium) ignore the low 4 bits and fix them at 0xF.
If this value is left at -1 the last entry in the IDT will be used.
config IOAPIC
bool "IO-APIC"
default y

View file

@ -4,5 +4,6 @@ obj-$(CONFIG_LOAPIC)$(CONFIG_MVIC) += system_apic.o
obj-$(CONFIG_MVIC) += mvic.o
obj-$(CONFIG_LOAPIC) += loapic_intr.o
obj-$(CONFIG_IOAPIC) += ioapic_intr.o
obj-$(CONFIG_LOAPIC_SPURIOUS_VECTOR) += loapic_spurious.o
obj-$(CONFIG_ARCV2_INTERRUPT_UNIT) += arcv2_irq_unit.o

View file

@ -181,6 +181,11 @@
#define IMCR_IOAPIC_ON 0x01 /* IMCR IOAPIC route enable */
#define IMCR_IOAPIC_OFF 0x00 /* IMCR IOAPIC route disable */
#if CONFIG_LOAPIC_SPURIOUS_VECTOR_ID == -1
#define LOAPIC_SPURIOUS_VECTOR_ID (CONFIG_IDT_NUM_VECTORS - 1)
#else
#define LOAPIC_SPURIOUS_VECTOR_ID CONFIG_LOAPIC_SPURIOUS_VECTOR_ID
#endif
/**
*
@ -244,6 +249,12 @@ int _loapic_init(struct device *unused)
*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_THERMAL) =
LOAPIC_LVT_MASKED;
#if CONFIG_LOAPIC_SPURIOUS_VECTOR
*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_SVR) =
(*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_SVR) & 0xFFFFFF00)
| (LOAPIC_SPURIOUS_VECTOR_ID & 0xFF);
#endif
/* discard a pending interrupt if any */
_loapic_eoi();
return 0;
@ -436,3 +447,11 @@ int _loapic_isr_vector_get(void)
DECLARE_DEVICE_INIT_CONFIG(loapic_0, "", _loapic_init, NULL);
SYS_DEFINE_DEVICE(loapic_0, NULL, PRIMARY,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
#if CONFIG_LOAPIC_SPURIOUS_VECTOR
extern void _loapic_spurious_handler(void);
NANO_CPU_INT_REGISTER(_loapic_spurious_handler, NANO_SOFT_IRQ,
LOAPIC_SPURIOUS_VECTOR_ID >> 4,
LOAPIC_SPURIOUS_VECTOR_ID, 0);
#endif

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2015 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* @brief LOAPIC spurioys interrupt handler
*/
#define _ASMLANGUAGE
#include <nano_private.h>
#include <arch/x86/asm.h>
GTEXT(_loapic_spurious_handler)
SECTION_FUNC(TEXT, _loapic_spurious_handler)
iret