diff options
Diffstat (limited to 'c/src/lib/libbsp/powerpc/shared/irq/irq.c')
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/irq/irq.c | 369 |
1 files changed, 70 insertions, 299 deletions
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq.c b/c/src/lib/libbsp/powerpc/shared/irq/irq.c index ecdc61dc34..40e8d848fa 100644 --- a/c/src/lib/libbsp/powerpc/shared/irq/irq.c +++ b/c/src/lib/libbsp/powerpc/shared/irq/irq.c @@ -1,6 +1,6 @@ /* * - * This file contains the implementation of the function described in irq.h + * This file contains the PIC-independent implementation of the functions described in irq.h * * Copyright (C) 1998, 1999 valette@crf.canon.fr * @@ -15,26 +15,18 @@ #include <bsp.h> #include <bsp/irq.h> -#include <bsp/VME.h> -#include <bsp/openpic.h> #include <rtems/score/apiext.h> /* for post ISR signal processing */ #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 -/* - * 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]; +extern unsigned int external_exception_vector_prolog_code_size[]; +extern void external_exception_vector_prolog_code(); +extern unsigned int decrementer_exception_vector_prolog_code_size[]; +extern void decrementer_exception_vector_prolog_code(); + /* * default handler connected on each irq after bsp initialization */ @@ -48,26 +40,6 @@ static rtems_irq_global_settings* internal_config; static rtems_irq_connect_data* rtems_hdl_tbl; /* - * 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) - ); -} - -/* - * 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) - ); -} - -/* * Check if IRQ is a Processor IRQ */ static inline int is_processor_irq(const rtems_irq_number irqLine) @@ -78,33 +50,22 @@ static inline int is_processor_irq(const rtems_irq_number irqLine) } /* - * ------------------------ RTEMS Irq helper functions ---------------- + * default on/off function + */ +static void nop_func(){} +/* + * default isOn function +static int not_connected() {return 0;} + */ +/* + * default possible isOn function */ +static int connected() {return 1;} + /* - * Caution : this function assumes the variable "internal_config" - * is already set and that the tables it contains are still valid - * and accessible. + * ------------------------ RTEMS Irq helper functions ---------------- */ -static void compute_i8259_masks_from_prio () -{ - 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 (internal_config->irqPrioTbl [i] > internal_config->irqPrioTbl [j]) { - * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j); - } - } - } -} /* * This function check that the value given for the irq line @@ -152,25 +113,13 @@ int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data* irq) /* link chain to new topmost handler */ rtems_hdl_tbl[irq->name].next_handler = (void *)vchain; - if (is_isa_irq(irq->name)) { - /* - * Enable interrupt at PIC level - */ - BSP_irq_enable_at_i8259s (irq->name); - } - - if (is_pci_irq(irq->name)) { - /* - * Enable interrupt at OPENPIC level - */ - openpic_enable_irq ((int) irq->name - BSP_PCI_IRQ_LOWEST_OFFSET); - } - if (is_processor_irq(irq->name)) { /* * Enable exception at processor level */ - } + } else { + BSP_enable_irq_at_pic(irq->name); + } /* * Enable interrupt on device */ @@ -213,25 +162,13 @@ int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq) rtems_hdl_tbl[irq->name] = *irq; rtems_hdl_tbl[irq->name].next_handler = (void *)-1; - if (is_isa_irq(irq->name)) { - /* - * Enable interrupt at PIC level - */ - BSP_irq_enable_at_i8259s (irq->name); - } - - if (is_pci_irq(irq->name)) { - /* - * Enable interrupt at OPENPIC level - */ - openpic_enable_irq ((int) irq->name - BSP_PCI_IRQ_LOWEST_OFFSET); - } - if (is_processor_irq(irq->name)) { /* * Enable exception at processor level */ - } + } else { + BSP_enable_irq_at_pic(irq->name); + } /* * Enable interrupt on device */ @@ -305,23 +242,13 @@ int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq) } } - if (is_isa_irq(irq->name)) { - /* - * disable interrupt at PIC level - */ - BSP_irq_disable_at_i8259s (irq->name); - } - if (is_pci_irq(irq->name)) { - /* - * disable interrupt at OPENPIC level - */ - openpic_disable_irq ((int) irq->name - BSP_PCI_IRQ_LOWEST_OFFSET); - } if (is_processor_irq(irq->name)) { /* * disable exception at processor level */ - } + } else { + BSP_disable_irq_at_pic(irq->name); + } /* * Disable interrupt on device @@ -366,129 +293,55 @@ int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config) { int i; unsigned int level; - /* - * Store various code accelerators - */ + rtems_irq_connect_data* vchain; + rtems_raw_except_connect_data vectorDesc; + + /* + * Store various code accelerators + */ internal_config = config; default_rtems_entry = config->defaultEntry; - rtems_hdl_tbl = config->irqHdlTbl; + rtems_hdl_tbl = config->irqHdlTbl; _CPU_ISR_Disable(level); - /* - * set up internal tables used by rtems interrupt prologue - */ - /* - * start with ISA IRQ - */ - compute_i8259_masks_from_prio (); - - 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); - - /* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */ - { - rtems_irq_connect_data* vchain; - for( vchain = &rtems_hdl_tbl[i]; - ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); - vchain = (rtems_irq_connect_data*)vchain->next_handler ) - { - vchain->on(vchain); - } - } - } - else { - /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */ - { - rtems_irq_connect_data* vchain; - for( vchain = &rtems_hdl_tbl[i]; - ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); - vchain = (rtems_irq_connect_data*)vchain->next_handler ) - { - vchain->off(vchain); - } - } - BSP_irq_disable_at_i8259s (i); - } - } - /* - * must enable slave pic anyway - */ - BSP_irq_enable_at_i8259s (2); - /* - * 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, - internal_config->irqPrioTbl[i]); - if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { - openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET); - /* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */ - { - rtems_irq_connect_data* vchain; - for( vchain = &rtems_hdl_tbl[i]; - ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); - vchain = (rtems_irq_connect_data*)vchain->next_handler ) - { - vchain->on(vchain); - } - } - - } - else { - /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */ - { - rtems_irq_connect_data* vchain; - for( vchain = &rtems_hdl_tbl[i]; - ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); - vchain = (rtems_irq_connect_data*)vchain->next_handler ) - { - vchain->off(vchain); - } - } - - openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET); - } + + if ( !BSP_setup_the_pic(config) ) { + printk("PIC setup failed; leaving IRQs OFF\n"); + return 0; + } + + for ( i = BSP_LOWEST_OFFSET; i <= BSP_MAX_OFFSET; i++ ) { + for( vchain = &rtems_hdl_tbl[i]; + ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); + vchain = (rtems_irq_connect_data*)vchain->next_handler ) + { + vchain->on(vchain); + } + } + + _CPU_ISR_Enable(level); + + /* + * We must connect the raw irq handler for the two + * expected interrupt sources : decrementer and external interrupts. + */ + vectorDesc.exceptIndex = ASM_DEC_VECTOR; + vectorDesc.hdl.vector = ASM_DEC_VECTOR; + vectorDesc.hdl.raw_hdl = decrementer_exception_vector_prolog_code; + vectorDesc.hdl.raw_hdl_size = (unsigned) decrementer_exception_vector_prolog_code_size; + vectorDesc.on = nop_func; + vectorDesc.off = nop_func; + vectorDesc.isOn = connected; + if (!mpc60x_set_exception (&vectorDesc)) { + BSP_panic("Unable to initialize RTEMS decrementer raw exception\n"); } - /* - * Must enable PCI/ISA bridge IRQ - */ - openpic_enable_irq (0); - /* - * finish with Processor exceptions handled like IRQ - */ - for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER; i++) { - if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { - /* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */ - { - rtems_irq_connect_data* vchain; - for( vchain = &rtems_hdl_tbl[i]; - ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); - vchain = (rtems_irq_connect_data*)vchain->next_handler ) - { - vchain->on(vchain); - } - } - - } - else { - /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */ - { - rtems_irq_connect_data* vchain; - for( vchain = &rtems_hdl_tbl[i]; - ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); - vchain = (rtems_irq_connect_data*)vchain->next_handler ) - { - vchain->off(vchain); - } - } - - } + vectorDesc.exceptIndex = ASM_EXT_VECTOR; + vectorDesc.hdl.vector = ASM_EXT_VECTOR; + vectorDesc.hdl.raw_hdl = external_exception_vector_prolog_code; + vectorDesc.hdl.raw_hdl_size = (unsigned) external_exception_vector_prolog_code_size; + if (!mpc60x_set_exception (&vectorDesc)) { + BSP_panic("Unable to initialize RTEMS external raw exception\n"); } - _CPU_ISR_Enable(level); return 1; } @@ -498,88 +351,6 @@ int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config) return 0; } -int _BSP_vme_bridge_irq = -1; - -unsigned BSP_spuriousIntr = 0; -/* - * High level IRQ handler called from shared_raw_irq_code_entry - */ -void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum) -{ - register unsigned int irq; - register unsigned isaIntr; /* boolean */ - register unsigned oldMask = 0; /* old isa pic masks */ - register unsigned newMask; /* new isa pic masks */ - register unsigned msr; - register unsigned new_msr; - - if (excNum == ASM_DEC_VECTOR) { - _CPU_MSR_GET(msr); - new_msr = msr | MSR_EE; - _CPU_MSR_SET(new_msr); - - rtems_hdl_tbl[BSP_DECREMENTER].hdl(rtems_hdl_tbl[BSP_DECREMENTER].handle); - - _CPU_MSR_SET(msr); - return; - - } - irq = openpic_irq(0); - if (irq == OPENPIC_VEC_SPURIOUS) { - ++BSP_spuriousIntr; - return; - } - isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ); - if (isaIntr) { - /* - * 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); - } - _CPU_MSR_GET(msr); - new_msr = msr | MSR_EE; - _CPU_MSR_SET(new_msr); - - /* rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); */ - { - rtems_irq_connect_data* vchain; - for( vchain = &rtems_hdl_tbl[irq]; - ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); - vchain = (rtems_irq_connect_data*)vchain->next_handler ) - { - vchain->hdl(vchain->handle); - } - } - - _CPU_MSR_SET(msr); - - 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 { -#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); - } -} - void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx) { /* |