diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2008-09-03 20:35:43 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2008-09-03 20:35:43 +0000 |
commit | e36390a662764faf3b38e8f6196e8f77d1b5d00f (patch) | |
tree | 810a3778767fa392b44ccfe2577fc645e7620ee8 /c/src/lib/libbsp/powerpc/ep1a/irq | |
parent | 2008-09-03 Joel Sherrill <joel.sherrill@OARcorp.com> (diff) | |
download | rtems-e36390a662764faf3b38e8f6196e8f77d1b5d00f.tar.bz2 |
2008-09-03 Joel Sherrill <joel.sherrill@OARcorp.com>
* Makefile.am, configure.ac, console/alloc360.c, console/console.c,
console/console.h, console/m68360.h, console/mc68360_scc.c,
console/ns16550cfg.c, console/rsPMCQ1.c, console/rsPMCQ1.h,
include/bsp.h, irq/irq_init.c, vme/VMEConfig.h: Initiate update and
testing. Add missing files. Does not run hello yet.
* console/debugio.c, console/polled_io.c, irq/openpic_xxx_irq.c: New files.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/ep1a/irq')
-rw-r--r-- | c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/ep1a/irq/openpic_xxx_irq.c | 293 |
2 files changed, 295 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c b/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c index a9f702c076..b9ed2ccc47 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c +++ b/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c @@ -35,6 +35,7 @@ /* #define SHOW_ISA_PCI_BRIDGE_SETTINGS */ +#define TRACE_IRQ_INIT /* * default on/off function @@ -184,6 +185,7 @@ void BSP_rtems_irq_mng_init(unsigned cpuId) initial_config.irqBase = BSP_LOWEST_OFFSET; initial_config.irqPrioTbl = irqPrioTable; +printk("Call BSP_rtems_irq_mngt_set\n"); if (!BSP_rtems_irq_mngt_set(&initial_config)) { /* * put something here that will show the failure... diff --git a/c/src/lib/libbsp/powerpc/ep1a/irq/openpic_xxx_irq.c b/c/src/lib/libbsp/powerpc/ep1a/irq/openpic_xxx_irq.c new file mode 100644 index 0000000000..791500083b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ep1a/irq/openpic_xxx_irq.c @@ -0,0 +1,293 @@ +/* + * + * This file contains the i8259/openpic-specific implementation of the function described in irq.h + * + * Copyright (C) 1998, 1999 valette@crf.canon.fr + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include <stdlib.h> + +#include <bsp.h> +#include <bsp/irq.h> +#include <bsp/irq_supp.h> +#include <bsp/VMEConfig.h> +#include <bsp/openpic.h> +#include <libcpu/raw_exception.h> +#include <libcpu/io.h> +#include <bsp/vectors.h> +#include <stdlib.h> + +#include <rtems/bspIo.h> /* for printk */ +#define RAVEN_INTR_ACK_REG 0xfeff0030 + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ +/* + * pointer to the mask representing the additionnal irq vectors + * that must be disabled when a particular entry is activated. + * They will be dynamically computed from the priority table given + * in BSP_rtems_irq_mngt_set(); + * CAUTION : this table is accessed directly by interrupt routine + * prologue. + */ +rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_NUMBER]; +#endif + +/* + * default handler connected on each irq after bsp initialization + */ +static rtems_irq_connect_data default_rtems_entry; + +static rtems_irq_connect_data* rtems_hdl_tbl; + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ +/* + * Check if IRQ is an ISA IRQ + */ +static inline int is_isa_irq(const rtems_irq_number irqLine) +{ + return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) & + ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET) + ); +} +#endif + +/* + * Check if IRQ is an OPENPIC IRQ + */ +static inline int is_pci_irq(const rtems_irq_number irqLine) +{ + return (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) & + ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET) + ); +} + +/* + * ------------------------ RTEMS Irq helper functions ---------------- + */ + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ +/* + * Caution : this function assumes the variable "*config" + * is already set and that the tables it contains are still valid + * and accessible. + */ +static void compute_i8259_masks_from_prio (rtems_irq_global_settings* config) +{ + int i; + int j; + /* + * Always mask at least current interrupt to prevent re-entrance + */ + for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) { + * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i); + for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) { + /* + * Mask interrupts at i8259 level that have a lower priority + */ + if (config->irqPrioTbl [i] > config->irqPrioTbl [j]) { + * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j); + } + } + } +} +#endif + +void +BSP_enable_irq_at_pic(const rtems_irq_number name) +{ +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + if (is_isa_irq(name)) { + /* + * Enable interrupt at PIC level + */ +printk("ERROR BSP_irq_enable_at_i8259s Being Called for %d\n", (int)name); + BSP_irq_enable_at_i8259s ((int) name); + } +#endif + + if (is_pci_irq(name)) { + /* + * Enable interrupt at OPENPIC level + */ +printk(" openpic_enable_irq %d\n", (int)name ); + openpic_enable_irq ((int) name); + } +} + +int +BSP_disable_irq_at_pic(const rtems_irq_number name) +{ +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + if (is_isa_irq(name)) { + /* + * disable interrupt at PIC level + */ + return BSP_irq_disable_at_i8259s ((int) name); + } +#endif + if (is_pci_irq(name)) { + /* + * disable interrupt at OPENPIC level + */ + return openpic_disable_irq ((int) name ); + } + return -1; +} + +/* + * RTEMS Global Interrupt Handler Management Routines + */ +int BSP_setup_the_pic(rtems_irq_global_settings* config) +{ + int i; + /* + * Store various code accelerators + */ + default_rtems_entry = config->defaultEntry; + rtems_hdl_tbl = config->irqHdlTbl; + + /* + * set up internal tables used by rtems interrupt prologue + */ +#if 0 +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + /* + * start with ISA IRQ + */ + compute_i8259_masks_from_prio (config); + + for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) { + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { + BSP_irq_enable_at_i8259s (i); + } + else { + BSP_irq_disable_at_i8259s (i); + } + } + + if ( BSP_ISA_IRQ_NUMBER > 0 ) { + /* + * must enable slave pic anyway + */ + BSP_irq_enable_at_i8259s (2); + } +#endif +#endif + + /* + * continue with PCI IRQ + */ + for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) { + /* + * Note that openpic_set_priority() sets the TASK priority of the PIC + */ + openpic_set_source_priority(i - BSP_PCI_IRQ_LOWEST_OFFSET, + config->irqPrioTbl[i]); + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { + openpic_enable_irq ((int) i ); + } + else { + openpic_disable_irq ((int) i ); + } + } + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + if ( BSP_ISA_IRQ_NUMBER > 0 ) { + /* + * Must enable PCI/ISA bridge IRQ + */ + openpic_enable_irq (0); + } +#endif + + return 1; +} + +int _BSP_vme_bridge_irq = -1; + +unsigned BSP_spuriousIntr = 0; + +/* + * High level IRQ handler called from shared_raw_irq_code_entry + */ +int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum) +{ + register unsigned int irq; +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + register unsigned isaIntr; /* boolean */ + register unsigned oldMask = 0; /* old isa pic masks */ + register unsigned newMask; /* new isa pic masks */ +#endif + + if (excNum == ASM_DEC_VECTOR) { +/* printk("ASM_DEC_VECTOR\n"); */ + bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl); + + return 0; + + } + irq = openpic_irq(0); + if (irq == OPENPIC_VEC_SPURIOUS) { +/* printk("OPENPIC_VEC_SPURIOUS interrupt %d\n", OPENPIC_VEC_SPURIOUS ); */ + ++BSP_spuriousIntr; + return 0; + } + + /* some BSPs might want to use a different numbering... */ + irq = irq - OPENPIC_VEC_SOURCE + BSP_PCI_IRQ_LOWEST_OFFSET; +/* printk("OpenPic Irq: %d\n", irq); */ + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ); + if (isaIntr) { +/* printk("BSP_PCI_ISA_BRIDGE_IRQ\n"); */ + /* + * Acknowledge and read 8259 vector + */ + irq = (unsigned int) (*(unsigned char *) RAVEN_INTR_ACK_REG); + /* + * store current PIC mask + */ + oldMask = i8259s_cache; + newMask = oldMask | irq_mask_or_tbl [irq]; + i8259s_cache = newMask; + outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff); + outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8)); + BSP_irq_ack_at_i8259s (irq); + openpic_eoi(0); + } +#endif + + + /* dispatch handlers */ +/* printk("dispatch\n"); */ +irq -=16; + bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl); +/* printk("Back from dispatch\n"); */ + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + if (isaIntr) {\ + i8259s_cache = oldMask; + outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff); + outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8)); + } + else +#endif + { +#ifdef BSP_PCI_VME_DRIVER_DOES_EOI + /* leave it to the VME bridge driver to do EOI, so + * it can re-enable the openpic while handling + * VME interrupts (-> VME priorities in software) + */ + if (_BSP_vme_bridge_irq != irq) +#endif + openpic_eoi(0); + } + return 0; +} |