summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-02-18 16:48:14 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-02-18 16:48:14 +0000
commit0c04c377bc8ac177d28bd0e0096d7c6940d33cd4 (patch)
treeba3062eb819e89de2eee14397ffe61b202ad10de /c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c
parent./clock/Makefile.in,v (diff)
downloadrtems-0c04c377bc8ac177d28bd0e0096d7c6940d33cd4.tar.bz2
./clock/Makefile.in,v
./clock/clock.c,v ./console/Makefile.in,v ./console/config.c,v ./console/console.c,v ./console/console.h,v ./console/debugio.c,v ./console/i8042.c,v ./console/i8042_p.h,v ./console/i8042vga.c,v ./console/i8042vga.h,v ./console/ns16550.c,v ./console/ns16550.h,v ./console/ns16550_p.h,v ./console/ns16550cfg.c,v ./console/ns16550cfg.h,v ./console/vga.c,v ./console/vga_p.h,v ./console/z85c30.c,v ./console/z85c30.h,v ./console/z85c30_p.h,v ./console/z85c30cfg.c,v ./console/z85c30cfg.h,v ./include/Makefile.in,v ./include/bsp.h,v ./include/chain.h,v ./include/coverhd.h,v ./include/extisrdrv.h,v ./include/nvram.h,v ./include/pci.h,v ./include/tod.h,v ./network/Makefile.in,v ./network/amd79c970.c,v ./network/amd79c970.h,v ./nvram/Makefile.in,v ./nvram/ds1385.h,v ./nvram/mk48t18.h,v ./nvram/nvram.c,v ./nvram/prepnvr.h,v ./nvram/stk11c68.h,v ./pci/Makefile.in,v ./pci/pci.c,v ./start/Makefile.in,v ./start/start.s,v ./startup/Makefile.in,v ./startup/bspclean.c,v ./startup/bspstart.c,v ./startup/bsptrap.s,v ./startup/device-tree,v ./startup/genpvec.c,v ./startup/linkcmds,v ./startup/rtems-ctor.cc,v ./startup/sbrk.c,v ./startup/setvec.c,v ./startup/spurious.c,v ./startup/swap.c,v ./timer/Makefile.in,v ./timer/timer.c,v ./tod/Makefile.in,v ./tod/cmos.h,v ./tod/tod.c,v ./universe/Makefile.in,v ./universe/universe.c,v ./vectors/Makefile.in,v ./vectors/README,v ./vectors/align_h.s,v ./vectors/vectors.s,v ./wrapup/Makefile.in,v ./Makefile.in,v ./README,v ./STATUS,v ./bsp_specs,v
Diffstat (limited to 'c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c')
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c355
1 files changed, 355 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c
new file mode 100644
index 0000000000..d4b8f46274
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c
@@ -0,0 +1,355 @@
+/*
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ */
+/* genpvec.c
+ *
+ * These routines handle the external exception. Multiple ISRs occur off
+ * of this one interrupt.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id:
+ */
+
+#include <bsp.h>
+#include "chain.h"
+#include <assert.h>
+
+/*
+ * Proto types for this file
+ */
+
+rtems_isr external_exception_ISR (
+ rtems_vector_number vector /* IN */
+);
+
+#define NUM_LIRQ_HANDLERS 20
+#define NUM_LIRQ ( MAX_BOARD_IRQS - PPC_IRQ_LAST )
+
+/*
+ * Current 8259 masks
+ */
+unsigned8 ucMaster8259Mask;
+unsigned8 ucSlave8259Mask;
+
+/*
+ * Structure to for one of possible multiple interrupt handlers for
+ * a given interrupt.
+ */
+typedef struct
+{
+ Chain_Node Node;
+ rtems_isr_entry handler; /* isr routine */
+ rtems_vector_number vector; /* vector number */
+} EE_ISR_Type;
+
+
+/* Note: The following will not work if we add a method to remove
+ * handlers at a later time.
+ */
+ EE_ISR_Type ISR_Nodes [NUM_LIRQ_HANDLERS];
+ rtems_unsigned16 Nodes_Used;
+ Chain_Control ISR_Array [NUM_LIRQ];
+
+void initialize_external_exception_vector()
+{
+ rtems_isr_entry previous_isr;
+ rtems_status_code status;
+ int i;
+
+ Nodes_Used = 0;
+
+ for (i=0; i <NUM_LIRQ; i++)
+ {
+ Chain_Initialize_empty( &ISR_Array[i] );
+ }
+
+ /*
+ * Initialise the 8259s
+ */
+ outport_byte(ISA8259_M_CTRL, 0x11); /* ICW1 */
+ outport_byte(ISA8259_S_CTRL, 0x11); /* ICW1 */
+ outport_byte(ISA8259_M_MASK, 0x00); /* ICW2 vectors 0-7 */
+ outport_byte(ISA8259_S_MASK, 0x08); /* ICW2 vectors 8-15 */
+ outport_byte(ISA8259_M_MASK, 0x04); /* ICW3 cascade on IRQ2 */
+ outport_byte(ISA8259_S_MASK, 0x02); /* ICW3 cascade on IRQ2 */
+ outport_byte(ISA8259_M_MASK, 0x01); /* ICW4 x86 normal EOI */
+ outport_byte(ISA8259_S_MASK, 0x01); /* ICW4 x86 normal EOI */
+
+ /*
+ * Enable IRQ2 cascade and disable all other interrupts
+ */
+ ucMaster8259Mask=0xfb;
+ ucSlave8259Mask=0xff;
+
+ outport_byte(ISA8259_M_MASK, ucMaster8259Mask);
+ outport_byte(ISA8259_S_MASK, ucSlave8259Mask);
+
+ /*
+ * Set up edge/level
+ */
+ switch(ucSystemType)
+ {
+ case SYS_TYPE_PPC1:
+ {
+ if(ucBoardRevMaj<5)
+ {
+ outport_byte(ISA8259_S_ELCR,
+ ELCRS_INT15_LVL);
+ }
+ else
+ {
+ outport_byte(ISA8259_S_ELCR,
+ ELCRS_INT9_LVL |
+ ELCRS_INT11_LVL |
+ ELCRS_INT14_LVL |
+ ELCRS_INT15_LVL);
+ }
+ outport_byte(ISA8259_M_ELCR,
+ ELCRM_INT5_LVL |
+ ELCRM_INT7_LVL);
+ break;
+ }
+
+ case SYS_TYPE_PPC1a:
+ {
+ outport_byte(ISA8259_S_ELCR,
+ ELCRS_INT9_LVL |
+ ELCRS_INT11_LVL |
+ ELCRS_INT14_LVL |
+ ELCRS_INT15_LVL);
+ outport_byte(ISA8259_M_ELCR,
+ ELCRM_INT5_LVL);
+ break;
+ }
+
+ case SYS_TYPE_PPC2:
+ case SYS_TYPE_PPC2a:
+ case SYS_TYPE_PPC4:
+ default:
+ {
+ outport_byte(ISA8259_S_ELCR,
+ ELCRS_INT9_LVL |
+ ELCRS_INT10_LVL |
+ ELCRS_INT11_LVL |
+ ELCRS_INT14_LVL |
+ ELCRS_INT15_LVL);
+ outport_byte(ISA8259_M_ELCR,
+ ELCRM_INT5_LVL |
+ ELCRM_INT7_LVL);
+ break;
+ }
+ }
+
+ /*
+ * Install external_exception_ISR () as the handler for
+ * the General Purpose Interrupt.
+ */
+
+ status = rtems_interrupt_catch( external_exception_ISR,
+ PPC_IRQ_EXTERNAL,
+ (rtems_isr_entry *) &previous_isr );
+}
+
+/*
+ * This routine installs one of multiple ISRs for the general purpose
+ * inerrupt.
+ */
+void set_EE_vector(
+ rtems_isr_entry handler, /* isr routine */
+ rtems_vector_number vector /* vector number */
+)
+{
+ rtems_unsigned16 vec_idx = vector - PPCN_60X_8259_IRQ_BASE;
+ rtems_unsigned32 index;
+
+ assert (Nodes_Used < NUM_LIRQ_HANDLERS);
+
+ /*
+ * If we have already installed this handler for this vector, then
+ * just reset it.
+ */
+
+ for ( index=0 ; index < Nodes_Used ; index++ )
+ {
+ if(ISR_Nodes[index].vector == vector &&
+ ISR_Nodes[index].handler == handler)
+ {
+ return;
+ }
+ }
+
+ /*
+ * Doing things in this order makes them more atomic
+ */
+
+ Nodes_Used++;
+
+ index = Nodes_Used - 1;
+
+ ISR_Nodes[index].handler = handler;
+ ISR_Nodes[index].vector = vector;
+
+ Chain_Append( &ISR_Array[vec_idx], &ISR_Nodes[index].Node );
+
+ /*
+ * Enable the interrupt
+ */
+ En_Ext_Interrupt(vector);
+}
+
+/*
+ * This interrupt service routine is called for an External Exception.
+ */
+rtems_isr external_exception_ISR (
+ rtems_vector_number vector /* IN */
+)
+{
+ unsigned16 index;
+ unsigned8 ucISr;
+ EE_ISR_Type *node;
+
+ index = *((volatile unsigned8 *)IRQ_VECTOR_BASE);
+
+ /*
+ * check for spurious interrupt
+ */
+ if(index==7)
+ {
+ /*
+ * OCW3 select IS register
+ */
+ outport_byte(ISA8259_M_CTRL, 0x0b);
+ /*
+ * Read IS register
+ */
+ inport_byte(ISA8259_M_CTRL, ucISr);
+ if(!(ucISr & 0x80))
+ {
+ /*
+ * Spurious interrupt
+ */
+ return;
+ }
+ }
+
+ node=(EE_ISR_Type *)ISR_Array[index].first;
+ while(!_Chain_Is_tail(&ISR_Array[index], (Chain_Node *)node))
+ {
+ (*node->handler)( node->vector );
+ node = (EE_ISR_Type *)node->Node.next;
+ }
+
+ /*
+ * Dismiss the interrupt
+ */
+ if(index&8)
+ {
+ /*
+ * Dismiss the interrupt in Slave first as it
+ * is cascaded
+ */
+ outport_byte(ISA8259_S_CTRL, NONSPECIFIC_EOI);
+ }
+
+ /*
+ * Dismiss the interrupt in Master
+ */
+ outport_byte(ISA8259_M_CTRL, NONSPECIFIC_EOI);
+}
+
+void Dis_Ext_Interrupt(int level)
+{
+ ISR_Level Irql;
+
+ level-=PPCN_60X_8259_IRQ_BASE;
+
+ if(level==2)
+ {
+ /*
+ * Level 2 is for cascade and must not be fiddled with
+ */
+ return;
+ }
+
+ /*
+ * Ensure that accesses to the mask are indivisible
+ */
+ _ISR_Disable(Irql);
+
+ if(level<8)
+ {
+ /*
+ * Interrupt is handled by Master
+ */
+ ucMaster8259Mask|=1<<level;
+ outport_byte(ISA8259_M_MASK, ucMaster8259Mask);
+ }
+ else
+ {
+ /*
+ * Interrupt is handled by Slave
+ */
+ ucSlave8259Mask|=1<<(level-8);
+ outport_byte(ISA8259_S_MASK, ucSlave8259Mask);
+ }
+ _ISR_Enable(Irql);
+}
+
+void En_Ext_Interrupt(int level)
+{
+ ISR_Level Irql;
+
+ level-=PPCN_60X_8259_IRQ_BASE;
+
+ if(level==2)
+ {
+ /*
+ * Level 2 is for cascade and must not be fiddled with
+ */
+ return;
+ }
+
+ /*
+ * Ensure that accesses to the mask are indivisible
+ */
+ _ISR_Disable(Irql);
+
+ if(level<8)
+ {
+ /*
+ * Interrupt is handled by Master
+ */
+ ucMaster8259Mask&=~(1<<level);
+ outport_byte(ISA8259_M_MASK, ucMaster8259Mask);
+ }
+ else
+ {
+ /*
+ * Interrupt is handled by Slave
+ */
+ ucSlave8259Mask&=~(1<<(level-8));
+ outport_byte(ISA8259_S_MASK, ucSlave8259Mask);
+ }
+
+ _ISR_Enable(Irql);
+}
+