From 526e132eb1526103a15b60a90e09eeb5a516233a Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Mon, 15 Jun 2015 06:20:24 -0700 Subject: [PATCH] x86/bsp: move PIC (i8259) driver to drivers/interrupt_controller Change-Id: I383424667f291ad4985781a7e6566c01c76ba5e0 Signed-off-by: Dirk Brandewie --- arch/x86/bsp/Kconfig | 7 - arch/x86/bsp/Makefile | 2 - drivers/Kconfig | 3 + drivers/interrupt_controller/Kconfig | 41 +++++ drivers/interrupt_controller/Makefile | 7 +- drivers/interrupt_controller/i8259_boi.s | 151 ++++++++++++++++++ .../interrupt_controller/system_pic.c | 0 include/drivers/pic.h | 11 ++ 8 files changed, 211 insertions(+), 11 deletions(-) create mode 100644 drivers/interrupt_controller/Kconfig create mode 100644 drivers/interrupt_controller/i8259_boi.s rename arch/x86/bsp/systemPic.c => drivers/interrupt_controller/system_pic.c (100%) diff --git a/arch/x86/bsp/Kconfig b/arch/x86/bsp/Kconfig index eb6844f8954..3be5b3c0fef 100644 --- a/arch/x86/bsp/Kconfig +++ b/arch/x86/bsp/Kconfig @@ -262,13 +262,6 @@ config BOOT_A20_ENABLE endmenu -config PIC - bool "PIC (i8259)" - default n - depends on BSP_GENERIC_PC && !LOAPIC && !IOAPIC - help - This option selects legacy i8259 as the interrupt controller. - config SHUTOFF_PIC bool "Shutoff PIC" depends on !PIC diff --git a/arch/x86/bsp/Makefile b/arch/x86/bsp/Makefile index 2dcad62886e..0ae1e202d5c 100644 --- a/arch/x86/bsp/Makefile +++ b/arch/x86/bsp/Makefile @@ -9,6 +9,4 @@ endif obj-$(CONFIG_LOAPIC) += systemApic.o obj-$(CONFIG_CLFLUSH_INSTRUCTION_SUPPORTED) += cache.o -obj-$(CONFIG_PIC) += systemPic.o -obj-$(CONFIG_PIC) += i8259Boi.o obj-$(CONFIG_X86_TSC_RANDOM_GENERATOR) += rand32-timestamp.o diff --git a/drivers/Kconfig b/drivers/Kconfig index f46accbc546..820b411185a 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -33,8 +33,11 @@ menu "Device Drivers" + source "drivers/simple/Kconfig" +source "drivers/interrupt_controller/Kconfig" + source "drivers/bluetooth/Kconfig" source "drivers/console/Kconfig" diff --git a/drivers/interrupt_controller/Kconfig b/drivers/interrupt_controller/Kconfig new file mode 100644 index 00000000000..6d15ce57ed2 --- /dev/null +++ b/drivers/interrupt_controller/Kconfig @@ -0,0 +1,41 @@ +# Kconfig - interrupt controller configuration options + +# +# Copyright (c) 2015 Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1) Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2) Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3) Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + + +menu "Interrupt Controllers" + +config PIC + bool "PIC (i8259)" + default n + depends on X86_32 + +endmenu diff --git a/drivers/interrupt_controller/Makefile b/drivers/interrupt_controller/Makefile index 367dc845cfb..ffb2644f620 100644 --- a/drivers/interrupt_controller/Makefile +++ b/drivers/interrupt_controller/Makefile @@ -1,5 +1,8 @@ ccflags-y +=-I$(srctree)/include/drivers -ccflags-y +=-I$(srctree)/arch/$(ARCH) -ccflags-y +=-I$(srctree)/arch/$(ARCH)/$(strip $(CONFIG_BSP_DIR)) +ccflags-y +=-I$(srctree)/arch/$(ARCH)/$(subst $(DQUOTE),,$(CONFIG_BSP_DIR)) +asflags-y +=-I$(srctree)/arch/x86/$(subst $(DQUOTE),,$(CONFIG_BSP_DIR)) + obj-${CONFIG_PIC}${CONFIG_SHUTOFF_PIC} = i8259.o +obj-$(CONFIG_PIC) += i8259_boi.o +obj-$(CONFIG_PIC) += system_pic.o diff --git a/drivers/interrupt_controller/i8259_boi.s b/drivers/interrupt_controller/i8259_boi.s new file mode 100644 index 00000000000..f46a4e0b64e --- /dev/null +++ b/drivers/interrupt_controller/i8259_boi.s @@ -0,0 +1,151 @@ +/* i8259Boi.s - Intel 8259A PIC BOI Handler */ + +/* + * Copyright (c) 2013-2015 Wind River Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3) Neither the name of Wind River Systems nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/* +DESCRIPTION + +The PIC BOI handler determines if the IRQ in question is a spurious or real +interrupt. The IRQ inputs must remain high until after the falling edge of the +first INTA. A spurious interrupt on IRQ 7 can occur if the IRQ input goes low +before this time when the CPU acknowledges the interrupt. In this case, the +interrupt handler should simply return without sending an EOI command. + +The distinction between a spurious interrupt and a real one is detected by +looking at the in service register (ISR). The bit (bit 7) will be 1 indicating +a real IRQ has been inserted. + +*/ + +/* includes */ +#define _ASMLANGUAGE + +#include +#include + +#include +#include + + /* externs */ + + GTEXT(_IntExit) + GDATA(_i8259_spurious_interrupt_count) + + +/******************************************************************************* +* +* _i8259_boi_master - detect whether it is spurious interrupt or not +* +* This routine is called before the user's interrupt handler to detect the +* spurious interrupt on the master PIC. If a spurious interrupt condition is +* detected, a global variable is incremented and the execution of the interrupt +* stub is "short circuited", i.e. a return to the interrupted context +* occurs. +* +* void _i8259_boi_master (void) +* +* RETURNS: N/A +*/ + +SECTION_FUNC(TEXT, _i8259_boi_master) + /* disable interrupts */ + pushfl + cli + + /* Master PIC, get contents of in serivce register */ + PLB_BYTE_REG_WRITE (0x0b, PIC_PORT1(PIC_MASTER_BASE_ADRS)) + PLB_BYTE_REG_READ (PIC_PORT1(PIC_MASTER_BASE_ADRS)) + + /* enable interrupts */ + popfl + + /* Contents of ISR in %AL */ + andb $0x80, %al + je spur_isr + + ret + + +/******************************************************************************* +* +* _i8259_boi_slave - detect whether it is spurious interrupt or not +* +* This routine is called before the user's interrupt handler to detect the +* spurious interrupt on the slave PIC. If a spurious interrupt condition is +* detected, a global variable is incremented and the execution of the interrupt +* stub is "short circuited", i.e. a return to the interrupted context +* occurs. +* +* void _i8259_boi_slave (void) +* +* RETURNS: N/A +*/ + +SECTION_FUNC(TEXT, _i8259_boi_slave) + /* disable interrupts */ + pushfl + cli + + /* Slave PIC, get contents of in serivce register */ + PLB_BYTE_REG_WRITE (0x0b, PIC_PORT1 (PIC_SLAVE_BASE_ADRS)) + PLB_BYTE_REG_READ (PIC_PORT1 (PIC_SLAVE_BASE_ADRS)) + + /* Contents of ISR in EAX */ + testb %al, %al + jne check_isr + + /* Check the master PIC's in service register for slave PIC IRQ */ + PLB_BYTE_REG_WRITE (0x0b, PIC_PORT1(PIC_MASTER_BASE_ADRS)) + PLB_BYTE_REG_READ (PIC_PORT1(PIC_MASTER_BASE_ADRS)) + + /* Slave connected to IRQ2 on master */ + testb $0x4, %al + je check_isr + + /* Send non-specific EOI to the master PIC IRQ2 */ + PLB_BYTE_REG_WRITE (I8259_EOI, PIC_IACK (PIC_MASTER_BASE_ADRS)); + +BRANCH_LABEL(check_isr) + /* unlock interrupts */ + popfl + + /* Contents of ISR for either PIC in %AL */ + andb $0x80, %al + je spur_isr + + ret + +BRANCH_LABEL(spur_isr) + /* An actual spurious interrupt. Increment counter and short circuit */ + incl _i8259_spurious_interrupt_count + + /* Pop the return address */ + addl $4, %esp + jmp _IntExit diff --git a/arch/x86/bsp/systemPic.c b/drivers/interrupt_controller/system_pic.c similarity index 100% rename from arch/x86/bsp/systemPic.c rename to drivers/interrupt_controller/system_pic.c diff --git a/include/drivers/pic.h b/include/drivers/pic.h index 02eddc02971..610848a8747 100644 --- a/include/drivers/pic.h +++ b/include/drivers/pic.h @@ -39,6 +39,17 @@ extern "C" { #if defined(CONFIG_PIC) || defined(CONFIG_SHUTOFF_PIC) +/* programmable interrupt controller info (pair of cascaded 8259A devices) */ + +#define PIC_MASTER_BASE_ADRS 0x20 +#define PIC_SLAVE_BASE_ADRS 0xa0 +#define PIC_MASTER_STRAY_INT_LVL 0x07 /* master PIC stray IRQ */ +#define PIC_SLAVE_STRAY_INT_LVL 0x0f /* slave PIC stray IRQ */ +#define PIC_MAX_INT_LVL 0x0f /* max interrupt level in PIC */ +#define PIC_REG_ADDR_INTERVAL 1 +#define INT_VEC_IRQ0 0x20 /* vector number for PIC IRQ0 */ +#define N_PIC_IRQS 16 /* number of PIC IRQs */ + #define I8259_EOI 0x20 /* EOI bit in OCW2 */ /* register definitions */