summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/gen5200/irq
diff options
context:
space:
mode:
authorRalf Corsepius <ralf.corsepius@rtems.org>2005-12-31 05:09:26 +0000
committerRalf Corsepius <ralf.corsepius@rtems.org>2005-12-31 05:09:26 +0000
commitca680bc5890abe0d6bfe7eb4a40a0229f1b6bd36 (patch)
tree805a5ddce1250235d6133376ddabb5543eb2cf82 /c/src/lib/libbsp/powerpc/gen5200/irq
parentAdd BuildRoot. (diff)
downloadrtems-ca680bc5890abe0d6bfe7eb4a40a0229f1b6bd36.tar.bz2
New (CVS import Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>'s
submission).
Diffstat (limited to 'c/src/lib/libbsp/powerpc/gen5200/irq')
-rw-r--r--c/src/lib/libbsp/powerpc/gen5200/irq/irq.c1141
-rw-r--r--c/src/lib/libbsp/powerpc/gen5200/irq/irq.h411
-rw-r--r--c/src/lib/libbsp/powerpc/gen5200/irq/irq_asm.S445
-rw-r--r--c/src/lib/libbsp/powerpc/gen5200/irq/irq_init.c327
4 files changed, 2324 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c
new file mode 100644
index 0000000000..2cde1fe025
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c
@@ -0,0 +1,1141 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP |
++-----------------------------------------------------------------+
+| File: irq.c
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| |
+| http://www.rtems.com/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| this file contains the irq controller handler |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 01.12.05 creation doe |
+|*****************************************************************|
+|*CVS information: |
+|*(the following information is created automatically, |
+|*do not edit here) |
+|*****************************************************************|
+|* $Log$
+|* Revision 1.6 2005/12/09 08:57:03 thomas
+|* added/modifed file headers
+|*
+|* Revision 1.5 2005/12/06 14:30:42 thomas
+|* updated name for peripheral register block
+|*
+|* Revision 1.4 2005/12/06 14:11:12 thomas
+|* added EB file headers
+|*
+ *
+|*****************************************************************|
+\*===============================================================*/
+/***********************************************************************/
+/* */
+/* Module: irq.c */
+/* Date: 07/17/2003 */
+/* Purpose: RTEMS MPC5x00 CPU main interrupt handler & routines */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Description: This file contains the implementation of the */
+/* functions described in irq.h */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Code */
+/* References: MPC8260ads main interrupt handler & routines */
+/* Module: irc.c */
+/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */
+/* Version 1.2 */
+/* Date: 04/18/2002 */
+/* */
+/* Author(s) / Copyright(s): */
+/* */
+/* Copyright (C) 1998, 1999 valette@crf.canon.fr */
+/* */
+/* Modified for mpc8260 Andy Dachs <a.dachs@sstl.co.uk> */
+/* Surrey Satellite Technology Limited, 2000 */
+/* Nested exception handlers not working yet. */
+/* */
+/* The license and distribution terms for this file may be */
+/* found in found in the file LICENSE in this distribution or at */
+/* http://www.OARcorp.com/rtems/license.html. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Partially based on the code references which are named above. */
+/* Adaptions, modifications, enhancements and any recent parts of */
+/* the code are under the right of */
+/* */
+/* IPR Engineering, Dachauer Straße 38, D-80335 München */
+/* Copyright(C) 2003 */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* IPR Engineering makes no representation or warranties with */
+/* respect to the performance of this computer program, and */
+/* specifically disclaims any responsibility for any damages, */
+/* special or consequential, connected with the use of this program. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Version history: 1.0 */
+/* */
+/***********************************************************************/
+
+/*#include "../include/bsp.h"*/
+#include "../include/bsp.h"
+#include <rtems.h>
+/*#include "../irq/irq.h"*/
+#include "../irq/irq.h"
+/*#include <rtems/score/thread.h>*/
+#include <rtems/score/apiext.h>
+#include <rtems/bspIo.h>
+#include "../include/raw_exception.h"
+#include "../vectors/vectors.h"
+#include "../include/mpc5200.h"
+
+
+extern uint32_t irqMaskTable[];
+
+/*
+ * default handler connected on each irq after bsp initialization
+ */
+static rtems_irq_connect_data default_rtems_entry;
+
+/*
+ * location used to store initial tables used for interrupt
+ * management.
+ */
+static rtems_irq_global_settings* internal_config;
+static rtems_irq_connect_data* rtems_hdl_tbl;
+
+/*
+ * bit in the SIU mask registers (PPC bit numbering) that should
+ * be set to enable the relevant interrupt, mask of 32 is for unused entries
+ *
+ */
+const static unsigned int SIU_MaskBit[BSP_SIU_IRQ_NUMBER] =
+ {
+ 0, 1, 2, 3, /* smart_comm, psc1, psc2, psc3 */
+ 4, 5, 6, 7, /* irda/psc6, eth, usb, ata */
+ 8, 9, 10, 11, /* pci_ctrl, pci_sc_rx, pci_sc_tx, psc4 */
+ 12, 13, 14, 15, /* psc5,spi_modf, spi_spif, i2c1 */
+ 16, 17, 18, 19, /* i2c, can1, can2, ir_rx */
+ 20, 21, 15, 16, /* ir_rx, xlb_arb, slice_tim2, irq1, */
+ 17, 18, 19, 20, /* irq2, irq3, lo_int, rtc_pint */
+ 21, 22, 23, 24, /* rtc_sint, gpio_std, gpio_wkup, tmr0 */
+ 25, 26, 27, 28, /* tmr1, tmr2, tmr3, tmr4 */
+ 29, 30, 31, 32, /* tmr5, tmr6, tmr7, res */
+ 32, 32, 32 /* res, res, res */
+ };
+
+/*
+ * Check if symbolic IRQ name is a Processor IRQ
+ */
+static inline int is_processor_irq(const rtems_irq_symbolic_name irqLine)
+ {
+
+ return (((int)irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) & ((int)irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET));
+
+ }
+
+/*
+ * Check for SIU IRQ and return base index
+ */
+static inline int is_siu_irq(const rtems_irq_symbolic_name irqLine)
+ {
+
+ return (((int)irqLine <= BSP_SIU_IRQ_MAX_OFFSET) && ((int)irqLine >= BSP_SIU_IRQ_LOWEST_OFFSET));
+
+ }
+
+
+/*
+ * Check for SIU IRQ and return base index
+ */
+static inline int get_siu_irq_base_index(const rtems_irq_symbolic_name irqLine)
+ {
+
+ if(irqLine <= BSP_PER_IRQ_MAX_OFFSET)
+ return BSP_PER_IRQ_LOWEST_OFFSET;
+ else
+ if(irqLine <= BSP_MAIN_IRQ_MAX_OFFSET)
+ return BSP_MAIN_IRQ_LOWEST_OFFSET;
+ else
+ if(irqLine <= BSP_CRIT_IRQ_MAX_OFFSET)
+ return BSP_CRIT_IRQ_LOWEST_OFFSET;
+ else
+ return -1;
+
+ }
+
+
+static inline void BSP_enable_per_irq_at_siu(const rtems_irq_symbolic_name irqLine)
+ {
+ uint8_t lo_hi_ind = 0, prio_index_offset;
+ uint32_t *reg;
+ rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl;
+ volatile uint32_t per_pri_1,main_pri_1, crit_pri_main_mask, per_mask;
+
+ /* calculate the index offset of priority value bit field */
+ prio_index_offset = (irqLine - BSP_PER_IRQ_LOWEST_OFFSET) % 8;
+
+ /* set interrupt priorities */
+ if(irqPrioTable[irqLine] <= 15)
+ {
+
+ /* set peripheral int priority */
+ reg = (uint32_t *)(&(mpc5200.per_pri_1));
+
+ /* choose proper register */
+ reg += (irqLine >> 3);
+
+ /* set priority as given in priority table */
+ *reg |= (irqPrioTable[irqLine] << (28 - (prio_index_offset<< 2)));
+
+ /* test msb (hash-bit) and set LO_/HI_int indicator */
+ if((lo_hi_ind = (irqPrioTable[irqLine] >> 3)))
+ {
+
+ /* set critical HI_int priority */
+ reg = (uint32_t *)(&(mpc5200.crit_pri_main_mask));
+ *reg |= (irqPrioTable[BSP_SIU_IRQ_HI_INT] << 26);
+
+ /*
+ * critical interrupt handling for the 603le core is not
+ * yet supported, routing of critical interrupts is forced
+ * to core_int (bit 31 / CEb)
+ */
+ mpc5200.ext_en_type |= 1;
+
+ }
+ else
+ {
+
+ if(irqPrioTable[irqLine] <= 15)
+ {
+
+ /* set main LO_int priority */
+ reg = (uint32_t *)(&(mpc5200.main_pri_1));
+ *reg |= (irqPrioTable[BSP_SIU_IRQ_LO_INT] << 16);
+
+ }
+
+ }
+
+ }
+
+ /* if LO_int ind., enable (unmask) main interrupt */
+ if(!lo_hi_ind)
+ {
+
+ mpc5200.crit_pri_main_mask &= ~(0x80000000 >> SIU_MaskBit[BSP_SIU_IRQ_LO_INT]);
+
+ }
+
+
+ /* enable (unmask) peripheral interrupt */
+ mpc5200.per_mask &= ~(0x80000000 >> SIU_MaskBit[irqLine]);
+
+ main_pri_1 = mpc5200.main_pri_1;
+ crit_pri_main_mask = mpc5200.crit_pri_main_mask;
+ per_pri_1 = mpc5200.per_pri_1;
+ per_mask = mpc5200.per_mask;
+
+
+ }
+
+
+static inline void BSP_enable_main_irq_at_siu(const rtems_irq_symbolic_name irqLine)
+ {
+
+ uint8_t prio_index_offset;
+ uint32_t *reg;
+ rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl;
+
+ /* calculate the index offset of priority value bit field */
+ prio_index_offset = (irqLine - BSP_MAIN_IRQ_LOWEST_OFFSET) % 8;
+
+ /* set main interrupt priority */
+ if(irqPrioTable[irqLine] <= 15)
+ {
+
+ /* set main int priority */
+ reg = (uint32_t *)(&(mpc5200.main_pri_1));
+
+ /* choose proper register */
+ reg += (irqLine >> 3);
+
+ /* set priority as given in priority table */
+ *reg |= (irqPrioTable[irqLine] << (28 - (prio_index_offset << 2)));
+
+ if((irqLine >= BSP_SIU_IRQ_IRQ1) && (irqLine <= BSP_SIU_IRQ_IRQ3))
+ {
+
+ /* enable external irq-pin */
+ mpc5200.ext_en_type |= (0x80000000 >> (20 + prio_index_offset));
+
+ }
+
+ }
+
+ /* enable (unmask) main interrupt */
+ mpc5200.crit_pri_main_mask &= ~(0x80000000 >> SIU_MaskBit[irqLine]);
+
+ }
+
+
+static inline void BSP_enable_crit_irq_at_siu(const rtems_irq_symbolic_name irqLine)
+ {
+
+ uint8_t prio_index_offset;
+ uint32_t *reg;
+ rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl;
+
+ prio_index_offset = irqLine - BSP_CRIT_IRQ_LOWEST_OFFSET;
+
+ /*
+ * critical interrupt handling for the 603Le core is not
+ * yet supported, routing of critical interrupts is forced
+ * to core_int (bit 31 / CEb)
+ */
+ mpc5200.ext_en_type |= 1;
+
+
+ /* set critical interrupt priorities */
+ if(irqPrioTable[irqLine] <= 3)
+ {
+
+ /* choose proper register */
+ reg = (uint32_t *)(&(mpc5200.crit_pri_main_mask));
+
+ /* set priority as given in priority table */
+ *reg |= (irqPrioTable[irqLine] << (30 - (prio_index_offset << 1)));
+
+ /* external irq0-pin */
+ if(irqLine == BSP_SIU_IRQ_IRQ1)
+ {
+
+ /* enable external irq-pin */
+ mpc5200.ext_en_type |= (0x80000000 >> (20 + prio_index_offset));
+
+ }
+
+ }
+
+ }
+
+
+static inline void BSP_disable_per_irq_at_siu(const rtems_irq_symbolic_name irqLine)
+ {
+
+ uint8_t prio_index_offset;
+ uint32_t *reg;
+
+ /* calculate the index offset of priority value bit field */
+ prio_index_offset = (irqLine - BSP_PER_IRQ_LOWEST_OFFSET) % 8;
+
+ /* disable (mask) peripheral interrupt */
+ mpc5200.per_mask |= (0x80000000 >> SIU_MaskBit[irqLine]);
+
+ /* reset priority to lowest level (reset value) */
+ reg = (uint32_t *)(&(mpc5200.per_pri_1));
+ reg += (irqLine >> 3);
+ *reg &= ~(15 << (28 - (prio_index_offset << 2)));
+
+ }
+
+
+static inline void BSP_disable_main_irq_at_siu(const rtems_irq_symbolic_name irqLine)
+ {
+
+ uint8_t prio_index_offset;
+ uint32_t *reg;
+
+ /* calculate the index offset of priority value bit field */
+ prio_index_offset = (irqLine - BSP_MAIN_IRQ_LOWEST_OFFSET) % 8;
+
+ /* disable (mask) main interrupt */
+ mpc5200.crit_pri_main_mask |= (0x80000000 >> SIU_MaskBit[irqLine]);
+
+ if((irqLine >= BSP_SIU_IRQ_IRQ1) && (irqLine <= BSP_SIU_IRQ_IRQ3))
+ {
+
+ /* disable external irq-pin */
+ mpc5200.ext_en_type &= ~(0x80000000 >> (20 + prio_index_offset));
+
+ }
+
+ /* reset priority to lowest level (reset value) */
+ reg = (uint32_t *)(&(mpc5200.main_pri_1));
+ reg += (irqLine >> 3);
+ *reg &= ~(15 << (28 - (prio_index_offset << 2)));
+
+ }
+
+
+static inline void BSP_disable_crit_irq_at_siu(const rtems_irq_symbolic_name irqLine)
+ {
+
+ uint8_t prio_index_offset;
+ uint32_t *reg;
+
+ prio_index_offset = irqLine - BSP_CRIT_IRQ_LOWEST_OFFSET;
+
+ /* reset critical int priority to lowest level (reset value) */
+ reg = (uint32_t *)(&(mpc5200.crit_pri_main_mask));
+ *reg &= ~(3 << (30 - (prio_index_offset << 1)));
+
+ if(irqLine == BSP_SIU_IRQ_IRQ1)
+ {
+
+ /* disable external irq0-pin */
+ mpc5200.ext_en_type &= ~(0x80000000 >> (20 + prio_index_offset));
+
+ }
+
+ }
+
+
+/*
+ * ------------------------ RTEMS Irq helper functions ----------------
+ */
+
+
+/*
+ * This function check that the value given for the irq line
+ * is valid.
+ */
+static int isValidInterrupt(int irq)
+ {
+ if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET) )
+ return 0;
+ return 1;
+ }
+
+
+ /*
+ * This function enables a given siu interrupt
+ */
+int BSP_irq_enable_at_siu(const rtems_irq_symbolic_name irqLine)
+ {
+ int base_index;
+
+ if(is_siu_irq(irqLine))
+ {
+
+
+ if((base_index = get_siu_irq_base_index(irqLine)) != -1)
+ {
+
+ switch(base_index)
+ {
+
+ case BSP_PER_IRQ_LOWEST_OFFSET:
+ BSP_enable_per_irq_at_siu(irqLine);
+ break;
+
+ case BSP_MAIN_IRQ_LOWEST_OFFSET:
+ BSP_enable_main_irq_at_siu(irqLine);
+ break;
+
+ case BSP_CRIT_IRQ_LOWEST_OFFSET:
+ BSP_enable_crit_irq_at_siu(irqLine);
+ break;
+
+ default:
+ printk("No valid base index\n");
+ break;
+
+ }
+
+ }
+
+ }
+
+ return 0;
+
+ }
+
+/*
+ * This function disables a given siu interrupt
+ */
+int BSP_irq_disable_at_siu(const rtems_irq_symbolic_name irqLine)
+ {
+ int base_index;
+
+ if ( (base_index = get_siu_irq_base_index(irqLine)) == -1)
+ return 1;
+
+ switch(base_index)
+ {
+
+ case BSP_PER_IRQ_LOWEST_OFFSET:
+ BSP_disable_per_irq_at_siu(irqLine);
+
+ break;
+
+ case BSP_MAIN_IRQ_LOWEST_OFFSET:
+ BSP_disable_main_irq_at_siu(irqLine);
+ break;
+
+ case BSP_CRIT_IRQ_LOWEST_OFFSET:
+ BSP_disable_crit_irq_at_siu(irqLine);
+ break;
+
+ default:
+ printk("No valid base index\n");
+ break;
+
+ }
+
+ return 0;
+ }
+
+
+/*
+ * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+
+ /*
+ * This function removes the default entry and installs a device interrupt handler
+ */
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+ {
+ unsigned int level;
+
+ if(!isValidInterrupt(irq->name))
+ {
+
+ printk("not a valid interrupt\n");
+ return 0;
+
+ }
+
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl)
+ {
+
+ printk( "Default handler not there\n" );
+ return 0;
+
+ }
+
+ _CPU_ISR_Disable(level);
+
+ /*
+ * store the data provided by user
+ */
+ rtems_hdl_tbl[irq->name] = *irq;
+
+ if(is_siu_irq(irq->name))
+ {
+
+ /*
+ * Enable interrupt at siu level
+ */
+ BSP_irq_enable_at_siu(irq->name);
+
+ }
+ else
+ {
+
+ if(is_processor_irq(irq->name))
+ {
+
+ /*
+ * Should Enable exception at processor level but not needed. Will restore
+ * EE flags at the end of the routine anyway.
+ */
+
+
+ }
+ else
+ {
+
+ printk("not a valid interrupt\n");
+ return 0;
+
+ }
+
+ }
+
+
+ /*
+ * Enable interrupt on device
+ */
+ irq->on(irq);
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+
+ }
+
+
+ /*
+ * This function procures the current interrupt handler
+ */
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
+ {
+
+ if(!isValidInterrupt(irq->name))
+ {
+
+ return 0;
+
+ }
+
+ *irq = rtems_hdl_tbl[irq->name];
+ return 1;
+
+ }
+
+
+ /*
+ * This function removes a device interrupt handler and restores the default entry
+ */
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+ {
+ unsigned int level;
+
+ if(!isValidInterrupt(irq->name))
+ {
+
+ return 0;
+
+ }
+
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ if(rtems_hdl_tbl[irq->name].hdl != irq->hdl)
+ {
+
+ return 0;
+
+ }
+
+ _CPU_ISR_Disable(level);
+
+ if(is_siu_irq(irq->name))
+ {
+
+ /*
+ * disable interrupt at PIC level
+ */
+ BSP_irq_disable_at_siu(irq->name);
+
+ }
+
+ if(is_processor_irq(irq->name))
+ {
+ /*
+ * disable exception at processor level
+ */
+ }
+
+ /*
+ * Disable interrupt on device
+ */
+ irq->off(irq);
+
+ /*
+ * restore the default irq value
+ */
+ rtems_hdl_tbl[irq->name] = default_rtems_entry;
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+
+ }
+
+
+/*
+ * ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
+ */
+
+/*
+ * This function set up interrupt management dependent on the given configuration
+ */
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
+ {
+ int i;
+ unsigned int level;
+
+ /*
+ * Store various code accelerators
+ */
+ internal_config = config;
+ default_rtems_entry = config->defaultEntry;
+ rtems_hdl_tbl = config->irqHdlTbl;
+
+ _CPU_ISR_Disable(level);
+
+ /*
+ * start with SIU IRQs
+ */
+ for (i=BSP_SIU_IRQ_LOWEST_OFFSET; i < BSP_SIU_IRQ_LOWEST_OFFSET + BSP_SIU_IRQ_NUMBER ; i++)
+ {
+
+ if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl)
+ {
+
+ BSP_irq_enable_at_siu(i);
+ rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
+
+ }
+ else
+ {
+
+ rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
+ BSP_irq_disable_at_siu(i);
+
+ }
+
+ }
+
+ /*
+ * finish with Processor exceptions handled like IRQs
+ */
+ 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]);
+
+ }
+ else
+ {
+
+ rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
+
+ }
+
+ }
+
+ _CPU_ISR_Enable(level);
+ return 1;
+
+ }
+
+
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
+ {
+
+ *config = internal_config;
+ return 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 int msr;
+ register unsigned int new_msr;
+ register unsigned int pmce;
+ register unsigned int crit_pri_main_mask, per_mask;
+
+ switch(excNum)
+ {
+
+
+ /*
+ * Handle decrementer interrupt
+ */
+ case ASM_DEC_VECTOR:
+
+ /* call the module specific handler and pass the specific handler */
+ rtems_hdl_tbl[BSP_DECREMENTER].hdl(0);
+
+ return;
+
+ case ASM_SYSMGMT_VECTOR:
+
+ /* get the content of main interrupt status register */
+ pmce = mpc5200.pmce;
+
+ /* main interrupts may be routed to SMI, see bit SMI/INT select bit in main int. priorities */
+ while(CHK_MSE_STICKY(pmce))
+ {
+
+ /* check for main interrupt sources (hirarchical order) -> LO_int indicates peripheral sources */
+ if(CHK_MSE_STICKY(pmce))
+ {
+
+ /* get source of main interrupt */
+ irq = MSE_SOURCE(pmce);
+
+ switch(irq)
+ {
+
+ /* irq1-3, RTC, GPIO, TMR0-7 detected (attention: slice timer 2 is always routed to SMI) */
+ case 0: /* slice timer 2 */
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+
+ /* add proper offset for main interrupts in the siu handler array */
+ irq += BSP_MAIN_IRQ_LOWEST_OFFSET;
+
+ /* save original mask and disable all lower priorized main interrupts*/
+ crit_pri_main_mask = mpc5200.crit_pri_main_mask;
+ mpc5200.crit_pri_main_mask |= irqMaskTable[irq];
+
+ /* enable interrupt nesting */
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ /* call the module specific handler and pass the specific handler */
+ rtems_hdl_tbl[irq].hdl(0);
+
+ /* disable interrupt nesting */
+ _CPU_MSR_SET(msr);
+
+ /* restore original interrupt mask */
+ mpc5200.crit_pri_main_mask = crit_pri_main_mask;
+
+ break;
+
+ /* peripheral LO_int interrupt source detected */
+ case 4:
+
+ /* check for valid peripheral interrupt source */
+ if(CHK_PSE_STICKY(pmce))
+ {
+
+ /* get source of peripheral interrupt */
+ irq = PSE_SOURCE(pmce);
+
+ /* add proper offset for peripheral interrupts in the siu handler array */
+ irq += BSP_PER_IRQ_LOWEST_OFFSET;
+
+ /* save original mask and disable all lower priorized main interrupts */
+ per_mask = mpc5200.per_mask;
+ mpc5200.per_mask |= irqMaskTable[irq];
+
+ /* enable interrupt nesting */
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ /* call the module specific handler and pass the specific handler */
+ rtems_hdl_tbl[irq].hdl(0);
+
+
+ /* disable interrupt nesting */
+ _CPU_MSR_SET(msr);
+
+ /* restore original interrupt mask */
+ mpc5200.per_mask = per_mask;
+
+ /* force re-evaluation of peripheral interrupts */
+ CLR_PSE_STICKY(mpc5200.pmce);
+
+ }
+ /* this case may not occur: no valid peripheral interrupt source */
+ else
+ {
+
+ printk("No valid peripheral LO_int interrupt source\n");
+
+ }
+
+ break;
+
+ /* error: unknown interrupt source */
+ default:
+ printk("Unknown peripheral LO_int interrupt source\n");
+ break;
+
+ }
+
+ /* force re-evaluation of main interrupts */
+ CLR_MSE_STICKY(mpc5200.pmce);
+
+ }
+
+ /* get the content of main interrupt status register */
+ pmce = mpc5200.pmce;
+
+ }
+
+ break;
+
+ case ASM_EXT_VECTOR:
+
+ /* get the content of main interrupt status register */
+ pmce = mpc5200.pmce;
+
+ /* critical interrupts may be routed to the core_int dependent on premature initialization, see bit 31 (CEbsH) */
+ while((CHK_CE_SHADOW(pmce) && CHK_CSE_STICKY(pmce)) || CHK_MSE_STICKY(pmce) || CHK_PSE_STICKY(pmce) )
+ {
+
+ /* first: check for critical interrupt sources (hirarchical order) -> HI_int indicates peripheral sources */
+ if(CHK_CE_SHADOW(pmce) && CHK_CSE_STICKY(pmce))
+ {
+
+ /* get source of critical interrupt */
+ irq = CSE_SOURCE(pmce);
+
+ switch(irq)
+ {
+ /* irq0, slice timer 1 or ccs wakeup detected */
+ case 0:
+ case 1:
+ case 3:
+
+ /* add proper offset for critical interrupts in the siu handler array */
+ irq += BSP_CRIT_IRQ_LOWEST_OFFSET;
+
+ /* call the module specific handler and pass the specific handler */
+ rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
+
+ break;
+
+ /* peripheral HI_int interrupt source detected */
+ case 2:
+
+ /* check for valid peripheral interrupt source */
+ if(CHK_PSE_STICKY(pmce))
+ {
+
+ /* get source of peripheral interrupt */
+ irq = PSE_SOURCE(pmce);
+
+ /* add proper offset for peripheral interrupts in the siu handler array */
+ irq += BSP_PER_IRQ_LOWEST_OFFSET;
+
+ /* save original mask and disable all lower priorized main interrupts */
+ per_mask = mpc5200.per_mask;
+ mpc5200.per_mask |= irqMaskTable[irq];
+
+ /* enable interrupt nesting */
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ /* call the module specific handler and pass the specific handler */
+ rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
+
+
+ /* disable interrupt nesting */
+ _CPU_MSR_SET(msr);
+
+ /* restore original interrupt mask */
+ mpc5200.per_mask = per_mask;
+
+ /* force re-evaluation of peripheral interrupts */
+ CLR_PSE_STICKY(mpc5200.pmce);
+
+ }
+ /* this case may not occur: no valid peripheral interrupt source */
+ else
+ {
+
+ printk("No valid peripheral HI_int interrupt source\n");
+
+ }
+
+ break;
+
+ /* error: unknown interrupt source */
+ default:
+ printk("Unknown HI_int interrupt source\n");
+ break;
+
+ }
+
+ /* force re-evaluation of critical interrupts */
+ CLR_CSE_STICKY(mpc5200.pmce);
+
+ }
+
+ /* second: check for main interrupt sources (hirarchical order) -> LO_int indicates peripheral sources */
+ if(CHK_MSE_STICKY(pmce))
+ {
+
+ /* get source of main interrupt */
+ irq = MSE_SOURCE(pmce);
+
+ switch(irq)
+ {
+
+ /* irq1-3, RTC, GPIO, TMR0-7 detected (attention: slice timer 2 is always routed to SMI) */
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+
+ /* add proper offset for main interrupts in the siu handler array */
+ irq += BSP_MAIN_IRQ_LOWEST_OFFSET;
+
+ /* save original mask and disable all lower priorized main interrupts*/
+ crit_pri_main_mask = mpc5200.crit_pri_main_mask;
+ mpc5200.crit_pri_main_mask |= irqMaskTable[irq];
+
+ /* enable interrupt nesting */
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ /* call the module specific handler and pass the specific handler */
+ rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
+
+ /* disable interrupt nesting */
+ _CPU_MSR_SET(msr);
+
+ /* restore original interrupt mask */
+ mpc5200.crit_pri_main_mask = crit_pri_main_mask;
+
+ break;
+
+ /* peripheral LO_int interrupt source detected */
+ case 4:
+
+ /* check for valid peripheral interrupt source */
+ if(CHK_PSE_STICKY(pmce))
+ {
+
+ /* get source of peripheral interrupt */
+ irq = PSE_SOURCE(pmce);
+
+ /* add proper offset for peripheral interrupts in the siu handler array */
+ irq += BSP_PER_IRQ_LOWEST_OFFSET;
+
+ /* save original mask and disable all lower priorized main interrupts */
+ per_mask = mpc5200.per_mask;
+ mpc5200.per_mask |= irqMaskTable[irq];
+
+ /* enable interrupt nesting */
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ /* call the module specific handler and pass the specific handler */
+ rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
+
+
+ /* disable interrupt nesting */
+ _CPU_MSR_SET(msr);
+
+ /* restore original interrupt mask */
+ mpc5200.per_mask = per_mask;
+
+ /* force re-evaluation of peripheral interrupts */
+ CLR_PSE_STICKY(mpc5200.pmce);
+
+ }
+ /* this case may not occur: no valid peripheral interrupt source */
+ else
+ {
+
+ printk("No valid peripheral LO_int interrupt source\n");
+
+ }
+
+ break;
+
+ /* error: unknown interrupt source */
+ default:
+ printk("Unknown peripheral LO_int interrupt source\n");
+ break;
+
+ }
+
+ /* force re-evaluation of main interrupts */
+ CLR_MSE_STICKY(mpc5200.pmce);
+
+ }
+
+
+ /* get the content of main interrupt status register */
+ pmce = mpc5200.pmce;
+
+ }
+
+ break;
+
+ default:
+ printk("Unknown processor exception\n");
+ break;
+
+ } /* end of switch(excNum) */
+
+ return;
+
+ }
+
+
+void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
+ {
+ /*
+ * Process pending signals that have not already been
+ * processed by _Thread_Displatch. This happens quite
+ * unfrequently : the ISR must have posted an action
+ * to the current running thread.
+ */
+ if ( _Thread_Do_post_task_switch_extension ||
+ _Thread_Executing->do_post_task_switch_extension )
+ {
+
+ _Thread_Executing->do_post_task_switch_extension = FALSE;
+ _API_extensions_Run_postswitch();
+
+ }
+ /*
+ * I plan to process other thread related events here.
+ * This will include DEBUG session requested from keyboard...
+ */
+}
diff --git a/c/src/lib/libbsp/powerpc/gen5200/irq/irq.h b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.h
new file mode 100644
index 0000000000..e0d54fdba7
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.h
@@ -0,0 +1,411 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP |
++-----------------------------------------------------------------+
+| File: irq.h
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| |
+| http://www.rtems.com/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| this file contains declarations for the irq controller handler |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 01.12.05 creation doe |
+|*****************************************************************|
+|*CVS information: |
+|*(the following information is created automatically, |
+|*do not edit here) |
+|*****************************************************************|
+|* $Log$
+|* Revision 1.6 2005/12/09 08:57:03 thomas
+|* added/modifed file headers
+|*
+|* Revision 1.5 2005/12/06 14:11:12 thomas
+|* added EB file headers
+|*
+ *
+|*****************************************************************|
+\*===============================================================*/
+/***********************************************************************/
+/* */
+/* Module: irq.h */
+/* Date: 07/17/2003 */
+/* Purpose: RTEMS MPC5x00 CPU interrupt header file */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Description: This include file describe the data structure and */
+/* the functions implemented by rtems to write */
+/* interrupt handlers. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Code */
+/* References: MPC8260ads CPU interrupt header file */
+/* Module: irq.h */
+/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */
+/* Version 1.1 */
+/* Date: 10/10/2002 */
+/* */
+/* Author(s) / Copyright(s): */
+/* */
+/* Copyright (C) 1999 valette@crf.canon.fr */
+/* */
+/* This code is heavilly inspired by the public specification of */
+/* STREAM V2 that can be found at: */
+/* */
+/* <http://www.chorus.com/Documentation/index.html> by following */
+/* the STREAM API Specification Document link. */
+/* */
+/* Modified for mpc8260 by Andy Dachs <a.dachs@sstl.co.uk> */
+/* Surrey Satellite Technology Limited */
+/* The interrupt handling on the mpc8260 seems quite different from */
+/* the 860 (I don't know the 860 well). Although some interrupts */
+/* are routed via the CPM irq and some are direct to the SIU they */
+/* all appear logically the same.Therefore I removed the distinction */
+/* between SIU and CPM interrupts. */
+/* */
+/* The license and distribution terms for this file may be */
+/* found in found in the file LICENSE in this distribution or at */
+/* http://www.OARcorp.com/rtems/license.html. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Partially based on the code references which are named above. */
+/* Adaptions, modifications, enhancements and any recent parts of */
+/* the code are under the right of */
+/* */
+/* IPR Engineering, Dachauer Straße 38, D-80335 München */
+/* Copyright(C) 2003 */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* IPR Engineering makes no representation or warranties with */
+/* respect to the performance of this computer program, and */
+/* specifically disclaims any responsibility for any damages, */
+/* special or consequential, connected with the use of this program. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Version history: 1.0 */
+/* */
+/***********************************************************************/
+
+#ifndef LIBBSP_POWERPC_MPC5200_IRQ_IRQ_H
+#define LIBBSP_POWERPC_MPC5200_IRQ_IRQ_H
+
+#define CHK_CE_SHADOW(pmce) ((pmce) & 0x00000001)
+#define CHK_CSE_STICKY(pmce) (((pmce) >> 10) & 0x00000001)
+#define CHK_MSE_STICKY(pmce) (((pmce) >> 21) & 0x00000001)
+#define CHK_PSE_STICKY(pmce) (((pmce) >> 29) & 0x00000001)
+#define CLR_CSE_STICKY(pmce) ((pmce) |= (1 << 29 ))
+#define CLR_MSE_STICKY(pmce) ((pmce) |= (1 << 21 ))
+#define CLR_PSE_STICKY(pmce) ((pmce) |= (1 << 10 ))
+#define CSE_SOURCE(source) (((source) >> 8) & 0x00000003)
+#define MSE_SOURCE(source) (((source) >> 16) & 0x0000001F)
+#define PSE_SOURCE(source) (((source) >> 24) & 0x0000001F)
+
+/*
+ * Base index for the module specific irq handlers
+ */
+#define BSP_ASM_IRQ_VECTOR_BASE 0
+#define BSP_PER_VECTOR_BASE BSP_ASM_IRQ_VECTOR_BASE /* 0 */
+/*
+ * Peripheral IRQ handlers related definitions
+ */
+#define BSP_PER_IRQ_NUMBER 22
+#define BSP_PER_IRQ_LOWEST_OFFSET BSP_PER_VECTOR_BASE /* 0 */
+#define BSP_PER_IRQ_MAX_OFFSET BSP_PER_IRQ_LOWEST_OFFSET + BSP_PER_IRQ_NUMBER - 1 /* 21 */
+/*
+ * Main IRQ handlers related definitions
+ */
+#define BSP_MAIN_IRQ_NUMBER 17
+#define BSP_MAIN_IRQ_LOWEST_OFFSET BSP_PER_IRQ_MAX_OFFSET + 1 /* 22 */
+#define BSP_MAIN_IRQ_MAX_OFFSET BSP_MAIN_IRQ_LOWEST_OFFSET + BSP_MAIN_IRQ_NUMBER - 1 /* 38 */
+/*
+ * Critical IRQ handlers related definitions
+ */
+#define BSP_CRIT_IRQ_NUMBER 4
+#define BSP_CRIT_IRQ_LOWEST_OFFSET BSP_MAIN_IRQ_MAX_OFFSET + 1 /* 39 */
+#define BSP_CRIT_IRQ_MAX_OFFSET BSP_CRIT_IRQ_LOWEST_OFFSET + BSP_CRIT_IRQ_NUMBER - 1 /* 42 */
+/*
+ * Summary of SIU interrupts
+ */
+#define BSP_SIU_IRQ_NUMBER BSP_CRIT_IRQ_MAX_OFFSET + 1 /* 43 */
+#define BSP_SIU_IRQ_LOWEST_OFFSET BSP_PER_IRQ_LOWEST_OFFSET /* 0 */
+#define BSP_SIU_IRQ_MAX_OFFSET BSP_CRIT_IRQ_MAX_OFFSET /* 42 */
+/*
+ * Processor IRQ handlers related definitions
+ */
+#define BSP_PROCESSOR_IRQ_NUMBER 3
+#define BSP_PROCESSOR_IRQ_LOWEST_OFFSET BSP_CRIT_IRQ_MAX_OFFSET + 1 /* 44 */
+#define BSP_PROCESSOR_IRQ_MAX_OFFSET BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1 /* 46 */
+/*
+ * Summary
+ */
+#define BSP_IRQ_NUMBER BSP_PROCESSOR_IRQ_MAX_OFFSET + 1 /* 47 */
+#define BSP_LOWEST_OFFSET BSP_PER_IRQ_LOWEST_OFFSET /* 0 */
+#define BSP_MAX_OFFSET BSP_PROCESSOR_IRQ_MAX_OFFSET /* 46 */
+
+#ifndef ASM
+
+/*
+extern volatile unsigned int ppc_cached_irq_mask;
+*/
+
+/*
+ * index table for the module specific handlers, a few entries are only placeholders
+ */
+typedef enum
+ {
+ BSP_SIU_IRQ_SMARTCOMM = BSP_PER_IRQ_LOWEST_OFFSET + 0,
+ BSP_SIU_IRQ_PSC1 = BSP_PER_IRQ_LOWEST_OFFSET + 1,
+ BSP_SIU_IRQ_PSC2 = BSP_PER_IRQ_LOWEST_OFFSET + 2,
+ BSP_SIU_IRQ_PSC3 = BSP_PER_IRQ_LOWEST_OFFSET + 3,
+ BSP_SIU_IRQ_PSC6 = BSP_PER_IRQ_LOWEST_OFFSET + 4,
+ BSP_SIU_IRQ_ETH = BSP_PER_IRQ_LOWEST_OFFSET + 5,
+ BSP_SIU_IRQ_USB = BSP_PER_IRQ_LOWEST_OFFSET + 6,
+ BSP_SIU_IRQ_ATA = BSP_PER_IRQ_LOWEST_OFFSET + 7,
+ BSP_SIU_IRQ_PCI_CRT = BSP_PER_IRQ_LOWEST_OFFSET + 8,
+ BSP_SIU_IRQ_PCI_SC_RX = BSP_PER_IRQ_LOWEST_OFFSET + 9,
+ BSP_SIU_IRQ_PCI_SC_TX = BSP_PER_IRQ_LOWEST_OFFSET + 10,
+ BSP_SIU_IRQ_PSC4 = BSP_PER_IRQ_LOWEST_OFFSET + 11,
+ BSP_SIU_IRQ_PSC5 = BSP_PER_IRQ_LOWEST_OFFSET + 12,
+ BSP_SIU_IRQ_SPI_MODF = BSP_PER_IRQ_LOWEST_OFFSET + 13,
+ BSP_SIU_IRQ_SPI_SPIF = BSP_PER_IRQ_LOWEST_OFFSET + 14,
+ BSP_SIU_IRQ_I2C1 = BSP_PER_IRQ_LOWEST_OFFSET + 15,
+ BSP_SIU_IRQ_I2C2 = BSP_PER_IRQ_LOWEST_OFFSET + 16,
+ BSP_SIU_IRQ_MSCAN1 = BSP_PER_IRQ_LOWEST_OFFSET + 17,
+ BSP_SIU_IRQ_MSCAN2 = BSP_PER_IRQ_LOWEST_OFFSET + 18,
+ BSP_SIU_IRQ_IR_RX = BSP_PER_IRQ_LOWEST_OFFSET + 19,
+ BSP_SIU_IRQ_IR_TX = BSP_PER_IRQ_LOWEST_OFFSET + 20,
+ BSP_SIU_IRQ_XLB_ARB = BSP_PER_IRQ_LOWEST_OFFSET + 21,
+
+ BSP_SIU_IRQ_SL_TIMER1 = BSP_MAIN_IRQ_LOWEST_OFFSET + 0, /* handler entry only used in case of SMI */
+ BSP_SIU_IRQ_IRQ1 = BSP_MAIN_IRQ_LOWEST_OFFSET + 1,
+ BSP_SIU_IRQ_IRQ2 = BSP_MAIN_IRQ_LOWEST_OFFSET + 2,
+ BSP_SIU_IRQ_IRQ3 = BSP_MAIN_IRQ_LOWEST_OFFSET + 3,
+ BSP_SIU_IRQ_LO_INT = BSP_MAIN_IRQ_LOWEST_OFFSET + 4, /* handler entry never used (only placeholder) */
+ BSP_SIU_IRQ_RTC_PER = BSP_MAIN_IRQ_LOWEST_OFFSET + 5,
+ BSP_SIU_IRQ_RTC_STW = BSP_MAIN_IRQ_LOWEST_OFFSET + 6,
+ BSP_SIU_IRQ_GPIO_STD = BSP_MAIN_IRQ_LOWEST_OFFSET + 7,
+ BSP_SIU_IRQ_GPIO_WKUP = BSP_MAIN_IRQ_LOWEST_OFFSET + 8,
+ BSP_SIU_IRQ_TMR0 = BSP_MAIN_IRQ_LOWEST_OFFSET + 9,
+ BSP_SIU_IRQ_TMR1 = BSP_MAIN_IRQ_LOWEST_OFFSET + 10,
+ BSP_SIU_IRQ_TMR2 = BSP_MAIN_IRQ_LOWEST_OFFSET + 1,
+ BSP_SIU_IRQ_TMR3 = BSP_MAIN_IRQ_LOWEST_OFFSET + 12,
+ BSP_SIU_IRQ_TMR4 = BSP_MAIN_IRQ_LOWEST_OFFSET + 13,
+ BSP_SIU_IRQ_TMR5 = BSP_MAIN_IRQ_LOWEST_OFFSET + 14,
+ BSP_SIU_IRQ_TMR6 = BSP_MAIN_IRQ_LOWEST_OFFSET + 15,
+ BSP_SIU_IRQ_TMR7 = BSP_MAIN_IRQ_LOWEST_OFFSET + 16,
+
+ BSP_SIU_IRQ_IRQ0 = BSP_CRIT_IRQ_LOWEST_OFFSET + 0,
+ BSP_SIU_IRQ_SL_TIMER0 = BSP_CRIT_IRQ_LOWEST_OFFSET + 1,
+ BSP_SIU_IRQ_HI_INT = BSP_CRIT_IRQ_LOWEST_OFFSET + 2, /* handler entry never used (only placeholder) */
+ BSP_SIU_IRQ_CSS_WKUP = BSP_CRIT_IRQ_LOWEST_OFFSET + 3,
+
+ BSP_DECREMENTER = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 0,
+ BSP_SYSMGMT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 1,
+ BSP_EXT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 2
+
+ }rtems_irq_symbolic_name;
+
+#define BSP_CRIT_IRQ_PRIO_LEVELS 4
+/*#define BSP_PERIODIC_TIMER BSP_DECREMENTER*/
+#define BSP_PERIODIC_TIMER BSP_SIU_IRQ_TMR6
+/*#define CPM_INTERRUPT*/
+
+
+/*
+ * Type definition for RTEMS managed interrupts
+ */
+typedef unsigned char rtems_irq_prio;
+struct __rtems_irq_connect_data__; /* forward declaratiuon */
+
+typedef unsigned int rtems_irq_number;
+typedef void *rtems_irq_hdl_param;
+typedef void (*rtems_irq_hdl) (rtems_irq_hdl_param);
+typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
+typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
+typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
+
+typedef struct __rtems_irq_connect_data__ {
+ /*
+ * IRQ line
+ */
+ rtems_irq_number name;
+ /*
+ * handler. See comment on handler properties below in function prototype.
+ */
+ rtems_irq_hdl hdl;
+ /*
+ * Handler handle to store private data
+ */
+ rtems_irq_hdl_param handle;
+ /*
+ * function for enabling interrupts at device level (ONLY!).
+ * The BSP code will automatically enable it at i8259s level.
+ * RATIONALE : anyway such code has to exist in current driver code.
+ * It is usually called immediately AFTER connecting the interrupt handler.
+ * RTEMS may well need such a function when restoring normal interrupt
+ * processing after a debug session.
+ *
+ */
+ rtems_irq_enable on;
+ /*
+ * function for disabling interrupts at device level (ONLY!).
+ * The code will disable it at i8259s level. RATIONALE : anyway
+ * such code has to exist for clean shutdown. It is usually called
+ * BEFORE disconnecting the interrupt. RTEMS may well need such
+ * a function when disabling normal interrupt processing for
+ * a debug session. May well be a NOP function.
+ */
+ rtems_irq_disable off;
+ /*
+ * function enabling to know what interrupt may currently occur
+ * if someone manipulates the i8259s interrupt mask without care...
+ */
+ rtems_irq_is_enabled isOn;
+
+#ifdef BSP_SHARED_HANDLER_SUPPORT
+ /*
+ * Set to -1 for vectors forced to have only 1 handler
+ */
+ void *next_handler;
+#endif
+
+} rtems_irq_connect_data;
+
+typedef struct {
+ /*
+ * size of all the table fields (*Tbl) described below.
+ */
+ unsigned int irqNb;
+ /*
+ * Default handler used when disconnecting interrupts.
+ */
+ rtems_irq_connect_data defaultEntry;
+ /*
+ * Table containing initials/current value.
+ */
+ rtems_irq_connect_data* irqHdlTbl;
+ /*
+ * actual value of BSP_PER_IRQ_VECTOR_BASE...
+ */
+ rtems_irq_symbolic_name irqBase;
+ /*
+ * software priorities associated with interrupts.
+ * if irqPrio [i] > intrPrio [j] it means that
+ * interrupt handler hdl connected for interrupt name i
+ * will not be interrupted by the handler connected for interrupt j
+ * The interrupt source will be physically masked at i8259 level.
+ */
+ rtems_irq_prio* irqPrioTbl;
+}rtems_irq_global_settings;
+
+
+
+/*-------------------------------------------------------------------------+
+| Function Prototypes.
++--------------------------------------------------------------------------*/
+/*
+ * ------------------------ PPC CPM Mngt Routines -------
+ */
+
+/*
+ * function to disable a particular irq. After calling
+ * this function, even if the device asserts the interrupt line it will
+ * not be propagated further to the processor
+ */
+int BSP_irq_disable_at_siu (const rtems_irq_symbolic_name irqLine);
+/*
+ * function to enable a particular irq. After calling
+ * this function, if the device asserts the interrupt line it will
+ * be propagated further to the processor
+ */
+int BSP_irq_enable_at_siu (const rtems_irq_symbolic_name irqLine);
+/*
+ * function to acknoledge a particular irq. After calling
+ * this function, if a device asserts an enabled interrupt line it will
+ * be propagated further to the processor. Mainly usefull for people
+ * writting raw handlers as this is automagically done for rtems managed
+ * handlers.
+ */
+int BSP_irq_ack_at_siu (const rtems_irq_symbolic_name irqLine);
+/*
+ * function to check if a particular irq is enabled. After calling
+ */
+int BSP_irq_enabled_at_siu (const rtems_irq_symbolic_name irqLine);
+
+
+
+/*
+ * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+/*
+ * function to connect a particular irq handler. This hanlder will NOT be called
+ * directly as the result of the corresponding interrupt. Instead, a RTEMS
+ * irq prologue will be called that will :
+ *
+ * 1) save the C scratch registers,
+ * 2) switch to a interrupt stack if the interrupt is not nested,
+ * 4) modify them to disable the current interrupt at SIU level (and may
+ * be others depending on software priorities)
+ * 5) aknowledge the SIU',
+ * 6) demask the processor,
+ * 7) call the application handler
+ *
+ * As a result the hdl function provided
+ *
+ * a) can perfectly be written is C,
+ * b) may also well directly call the part of the RTEMS API that can be used
+ * from interrupt level,
+ * c) It only responsible for handling the jobs that need to be done at
+ * the device level including (aknowledging/re-enabling the interrupt at device,
+ * level, getting the data,...)
+ *
+ * When returning from the function, the following will be performed by
+ * the RTEMS irq epilogue :
+ *
+ * 1) masks the interrupts again,
+ * 2) restore the original SIU interrupt masks
+ * 3) switch back on the orinal stack if needed,
+ * 4) perform rescheduling when necessary,
+ * 5) restore the C scratch registers...
+ * 6) restore initial execution flow
+ *
+ */
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
+/*
+ * function to get the current RTEMS irq handler for ptr->name. It enables to
+ * define hanlder chain...
+ */
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
+/*
+ * function to get disconnect the RTEMS irq handler for ptr->name.
+ * This function checks that the value given is the current one for safety reason.
+ * The user can use the previous function to get it.
+ */
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*);
+
+
+void BSP_rtems_irq_mng_init(unsigned cpuId);
+
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config);
+
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/gen5200/irq/irq_asm.S b/c/src/lib/libbsp/powerpc/gen5200/irq/irq_asm.S
new file mode 100644
index 0000000000..efb2465891
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/gen5200/irq/irq_asm.S
@@ -0,0 +1,445 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP |
++-----------------------------------------------------------------+
+| File: irq_asm.S
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| |
+| http://www.rtems.com/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| this file contains the assembler portion of the irq handling |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 01.12.05 creation doe |
+|*****************************************************************|
+|*CVS information: |
+|*(the following information is created automatically, |
+|*do not edit here) |
+|*****************************************************************|
+|* $Log$
+|* Revision 1.5 2005/12/09 08:57:03 thomas
+|* added/modifed file headers
+|*
+|* Revision 1.4 2005/12/06 14:11:12 thomas
+|* added EB file headers
+|*
+ *
+|*****************************************************************|
+\*===============================================================*/
+/***********************************************************************/
+/* */
+/* Module: irq_asm.S */
+/* Date: 07/17/2003 */
+/* Purpose: RTEMS assembly code for PowerPC IRQ veneers */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Description: This file contains the assembly code for the */
+/* PowerPC IRQ veneers for RTEMS. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Code */
+/* References: RTEMS assembly code for PowerPC IRQ veneers */
+/* Module: irq_asm.S */
+/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */
+/* Version 1.2 */
+/* Date: 04/18/2002 */
+/* */
+/* Author(s) / Copyright(s): */
+/* */
+/* The license and distribution terms for this file may be */
+/* found in found in the file LICENSE in this distribution or at */
+/* http://www.OARcorp.com/rtems/license.html. */
+/* */
+/* Modified to support the MCP750. */
+/* Modifications Copyright (C) 1999 Eric Valette.valette@crf.canon.fr*/
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Partially based on the code references which are named above. */
+/* Adaptions, modifications, enhancements and any recent parts of */
+/* the code are under the right of */
+/* */
+/* IPR Engineering, Dachauer Straße 38, D-80335 München */
+/* Copyright(C) 2003 */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* IPR Engineering makes no representation or warranties with */
+/* respect to the performance of this computer program, and */
+/* specifically disclaims any responsibility for any damages, */
+/* special or consequential, connected with the use of this program. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Version history: 1.0 */
+/* */
+/***********************************************************************/
+
+/*#include <bsp/vectors.h>*/
+#include "../vectors/vectors.h"
+#include <rtems/score/cpuopts.h> /* for PPC_HAS_FPU */
+#include <rtems/score/cpu.h>
+#include <rtems/asm.h>
+#include "../include/raw_exception.h"
+
+#define SYNC \
+ sync; \
+ isync
+
+ .text
+ .p2align 5
+
+ PUBLIC_VAR(decrementer_exception_vector_prolog_code)
+
+SYM (decrementer_exception_vector_prolog_code):
+
+ /*
+ * let room for exception frame
+ */
+ stwu r1, - (EXCEPTION_FRAME_END)(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, ASM_DEC_VECTOR
+ ba shared_raw_irq_code_entry
+
+ PUBLIC_VAR (decrementer_exception_vector_prolog_code_size)
+
+ decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code
+
+ PUBLIC_VAR(external_exception_vector_prolog_code)
+
+SYM (external_exception_vector_prolog_code):
+ /*
+ * let room for exception frame
+ */
+ stwu r1, - (EXCEPTION_FRAME_END)(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, ASM_EXT_VECTOR
+ ba shared_raw_irq_code_entry
+
+ PUBLIC_VAR (external_exception_vector_prolog_code_size)
+
+ external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code
+
+ PUBLIC_VAR(system_management_exception_vector_prolog_code)
+
+SYM (system_management_exception_vector_prolog_code):
+ /*
+ * let room for exception frame
+ */
+ stwu r1, - (EXCEPTION_FRAME_END)(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, ASM_SYSMGMT_VECTOR
+ ba shared_raw_irq_code_entry
+
+ PUBLIC_VAR (system_management_exception_vector_prolog_code_size)
+
+ system_management_exception_vector_prolog_code_size = . - system_management_exception_vector_prolog_code
+
+ PUBLIC_VAR(shared_raw_irq_code_entry)
+ PUBLIC_VAR(C_dispatch_irq_handler)
+
+ .p2align 5
+SYM (shared_raw_irq_code_entry):
+ /*
+ * Entry conditions :
+ * Registers already saved : R1, R4
+ * R1 : points to a location with enough room for the
+ * interrupt frame
+ * R4 : vector number
+ */
+ /*
+ * Save SRR0/SRR1 As soon As possible as it is the minimal needed
+ * to reenable exception processing
+ */
+ stw r0, GPR0_OFFSET(r1)
+ stw r2, GPR2_OFFSET(r1)
+ stw r3, GPR3_OFFSET(r1)
+
+ mfsrr0 r0
+ mfsrr1 r2
+ mfmsr r3
+
+ stw r0, SRR0_FRAME_OFFSET(r1)
+ stw r2, SRR1_FRAME_OFFSET(r1)
+
+
+ /*
+ * Enable data and instruction address translation, exception recovery
+ *
+ * also, on CPUs with FP, enable FP so that FP context can be
+ * saved and restored (using FP instructions)
+ */
+#if (PPC_HAS_FPU == 0)
+ ori r3, r3, MSR_RI | MSR_DR/*| MSR_IR*/
+#else
+ ori r3, r3, MSR_RI | MSR_DR | /*MSR_IR |*/ MSR_FP
+#endif
+ mtmsr r3
+ SYNC
+
+ /*
+ * Push C scratch registers on the current stack. It may
+ * actually be the thread stack or the interrupt stack.
+ * Anyway we have to make it in order to be able to call C/C++
+ * functions. Depending on the nesting interrupt level, we will
+ * switch to the right stack later.
+ */
+ stw r5, GPR5_OFFSET(r1)
+ stw r6, GPR6_OFFSET(r1)
+ stw r7, GPR7_OFFSET(r1)
+ stw r8, GPR8_OFFSET(r1)
+ stw r9, GPR9_OFFSET(r1)
+ stw r10, GPR10_OFFSET(r1)
+ stw r11, GPR11_OFFSET(r1)
+ stw r12, GPR12_OFFSET(r1)
+ stw r13, GPR13_OFFSET(r1)
+
+ mfcr r5
+ mfctr r6
+ mfxer r7
+ mflr r8
+
+ stw r5, EXC_CR_OFFSET(r1)
+ stw r6, EXC_CTR_OFFSET(r1)
+ stw r7, EXC_XER_OFFSET(r1)
+ stw r8, EXC_LR_OFFSET(r1)
+
+ /*
+ * Add some non volatile registers to store information
+ * that will be used when returning from C handler
+ */
+ stw r14, GPR14_OFFSET(r1)
+ stw r15, GPR15_OFFSET(r1)
+ /*
+ * save current stack pointer location in R14
+ */
+ addi r14, r1, 0
+ /*
+ * store part of _Thread_Dispatch_disable_level address in R15
+ */
+ addis r15,0, _Thread_Dispatch_disable_level@ha
+ /*
+ * Get current nesting level in R2
+ */
+/* mfspr r2, SPRG0 */
+ addis r6, 0, _ISR_Nest_level@ha
+ lwz r2, _ISR_Nest_level@l( r6 )
+
+ /*
+ * Check if stack switch is necessary
+ */
+ cmpwi r2,0
+ bne nested
+ mfspr r1, SPRG1
+
+nested:
+ /*
+ * Start Incrementing nesting level in R2
+ */
+ addi r2,r2,1
+
+ addis r6, 0, _ISR_Nest_level@ha
+ stw r2, _ISR_Nest_level@l( r6 )
+
+ /*
+ * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
+ */
+ lwz r6,_Thread_Dispatch_disable_level@l(r15)
+ /*
+ * store new nesting level in SPRG0
+ */
+/* mtspr SPRG0, r2 */
+
+ addi r6, r6, 1
+ mfmsr r5
+ /*
+ * store new _Thread_Dispatch_disable_level value
+ */
+ stw r6, _Thread_Dispatch_disable_level@l(r15)
+ /*
+ * We are now running on the interrupt stack. External and decrementer
+ * exceptions are still disabled. I see no purpose trying to optimize
+ * further assembler code.
+ */
+ /*
+ * Call C exception handler for decrementer Interrupt frame is passed just
+ * in case...
+ */
+ addi r3, r14, 0x8
+ bl C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
+ /*
+ * start decrementing nesting level. Note : do not test result against 0
+ * value as an easy exit condition because if interrupt nesting level > 1
+ * then _Thread_Dispatch_disable_level > 1
+ */
+/* mfspr r2, SPRG0 */
+
+ addis r6, 0, _ISR_Nest_level@ha
+ lwz r2, _ISR_Nest_level@l( r6 )
+
+ /*
+ * start decrementing _Thread_Dispatch_disable_level
+ */
+ lwz r3,_Thread_Dispatch_disable_level@l(r15)
+ addi r2, r2, -1 /* Continue decrementing nesting level */
+ addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */
+
+ stw r2, _ISR_Nest_level@l( r6 )
+/* mtspr SPRG0, r2 */ /* End decrementing nesting level */
+
+ stw r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
+ cmpwi r3, 0
+ /*
+ * switch back to original stack (done here just optimize registers
+ * contention. Could have been done before...)
+ */
+ addi r1, r14, 0
+ bne easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
+ /*
+ * Here we are running again on the thread system stack.
+ * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
+ * Interrupt are still disabled. Time to check if scheduler request to
+ * do something with the current thread...
+ */
+ addis r4, 0, _Context_Switch_necessary@ha
+ lwz r5, _Context_Switch_necessary@l(r4)
+ cmpwi r5, 0
+ bne switch
+
+ addis r6, 0, _ISR_Signals_to_thread_executing@ha
+ lwz r7, _ISR_Signals_to_thread_executing@l(r6)
+ cmpwi r7, 0
+ li r8, 0
+ beq easy_exit
+ stw r8, _ISR_Signals_to_thread_executing@l(r6)
+ /*
+ * going to call _ThreadProcessSignalsFromIrq
+ * Push a complete exception like frame...
+ */
+ stmw r16, GPR16_OFFSET(r1)
+ addi r3, r1, 0x8
+ /*
+ * compute SP at exception entry
+ */
+ addi r2, r1, EXCEPTION_FRAME_END
+ /*
+ * store it at the right place
+ */
+ stw r2, GPR1_OFFSET(r1)
+ /*
+ * Call High Level signal handling code
+ */
+ bl _ThreadProcessSignalsFromIrq
+
+
+ /*
+ * start restoring exception like frame
+ */
+ lwz r31, EXC_CTR_OFFSET(r1)
+ lwz r30, EXC_XER_OFFSET(r1)
+ lwz r29, EXC_CR_OFFSET(r1)
+ lwz r28, EXC_LR_OFFSET(r1)
+
+ mtctr r31
+ mtxer r30
+ mtcr r29
+ mtlr r28
+
+
+ lmw r4, GPR4_OFFSET(r1)
+
+
+ lwz r2, GPR2_OFFSET(r1)
+ lwz r0, GPR0_OFFSET(r1)
+
+ /*
+ * Disable data and instruction translation. Make path non recoverable...
+ */
+ mfmsr r3
+ xori r3, r3, MSR_RI | MSR_DR/*| MSR_IR */
+ mtmsr r3
+ SYNC
+ /*
+ * Restore rfi related settings
+ */
+
+ lwz r3, SRR1_FRAME_OFFSET(r1)
+ mtsrr1 r3
+ lwz r3, SRR0_FRAME_OFFSET(r1)
+ mtsrr0 r3
+
+ lwz r3, GPR3_OFFSET(r1)
+ addi r1,r1, EXCEPTION_FRAME_END
+ SYNC
+ rfi
+
+switch:
+ bl SYM (_Thread_Dispatch)
+
+easy_exit:
+ /*
+ * start restoring interrupt frame
+ */
+ lwz r3, EXC_CTR_OFFSET(r1)
+ lwz r4, EXC_XER_OFFSET(r1)
+ lwz r5, EXC_CR_OFFSET(r1)
+ lwz r6, EXC_LR_OFFSET(r1)
+
+ mtctr r3
+ mtxer r4
+ mtcr r5
+ mtlr r6
+
+ lwz r15, GPR15_OFFSET(r1)
+ lwz r14, GPR14_OFFSET(r1)
+ lwz r13, GPR13_OFFSET(r1)
+ lwz r12, GPR12_OFFSET(r1)
+ lwz r11, GPR11_OFFSET(r1)
+ lwz r10, GPR10_OFFSET(r1)
+ lwz r9, GPR9_OFFSET(r1)
+ lwz r8, GPR8_OFFSET(r1)
+ lwz r7, GPR7_OFFSET(r1)
+ lwz r6, GPR6_OFFSET(r1)
+ lwz r5, GPR5_OFFSET(r1)
+
+ /*
+ * Disable nested exception processing, data and instruction
+ * translation.
+ */
+ mfmsr r3
+ xori r3, r3, MSR_RI | MSR_DR/*| MSR_IR */
+ mtmsr r3
+ SYNC
+
+ /*
+ * Restore rfi related settings
+ */
+
+ lwz r4, SRR1_FRAME_OFFSET(r1)
+ lwz r2, SRR0_FRAME_OFFSET(r1)
+ lwz r3, GPR3_OFFSET(r1)
+ lwz r0, GPR0_OFFSET(r1)
+
+ mtsrr1 r4
+ mtsrr0 r2
+ lwz r4, GPR4_OFFSET(r1)
+ lwz r2, GPR2_OFFSET(r1)
+ addi r1,r1, EXCEPTION_FRAME_END
+ SYNC
+ rfi
+
diff --git a/c/src/lib/libbsp/powerpc/gen5200/irq/irq_init.c b/c/src/lib/libbsp/powerpc/gen5200/irq/irq_init.c
new file mode 100644
index 0000000000..87f57626ac
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/gen5200/irq/irq_init.c
@@ -0,0 +1,327 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP |
++-----------------------------------------------------------------+
+| File: irq_init.c
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| |
+| http://www.rtems.com/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| this file contains the IRQ controller/system initialization |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 01.12.05 creation doe |
+|*****************************************************************|
+|*CVS information: |
+|*(the following information is created automatically, |
+|*do not edit here) |
+|*****************************************************************|
+|* $Log$
+|* Revision 1.6 2005/12/09 08:57:03 thomas
+|* added/modifed file headers
+|*
+|* Revision 1.5 2005/12/06 14:30:42 thomas
+|* updated name for peripheral register block
+|*
+|* Revision 1.4 2005/12/06 14:11:12 thomas
+|* added EB file headers
+|*
+ *
+|*****************************************************************|
+\*===============================================================*/
+/***********************************************************************/
+/* */
+/* Module: irq_init.c */
+/* Date: 07/17/2003 */
+/* Purpose: RTEMS MPC5x00 CPU interrupt initialization */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Description: This file contains the implementation of rtems */
+/* initialization related to interrupt handling. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Code */
+/* References: MBX8xx CPU interrupt initialization */
+/* Module: irq_init.c */
+/* Project: RTEMS 4.6.0pre1 / MBX8xx BSP */
+/* Version 1.1 */
+/* Date: 04/06/2001 */
+/* */
+/* Author(s) / Copyright(s): */
+/* */
+/* CopyRight (C) 2001 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.OARcorp.com/rtems/license.html. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Partially based on the code references which are named above. */
+/* Adaptions, modifications, enhancements and any recent parts of */
+/* the code are under the right of */
+/* */
+/* IPR Engineering, Dachauer Straße 38, D-80335 München */
+/* Copyright(C) 2003 */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* IPR Engineering makes no representation or warranties with */
+/* respect to the performance of this computer program, and */
+/* specifically disclaims any responsibility for any damages, */
+/* special or consequential, connected with the use of this program. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Version history: 1.0 */
+/* */
+/***********************************************************************/
+
+/*#include "../include/bsp.h"*/
+#include "../include/bsp.h"
+#include <rtems.h>
+/*#include "../irq/irq.h"*/
+#include "../irq/irq.h"
+#include <rtems/bspIo.h>
+#include "../include/raw_exception.h"
+#include "../include/mpc5200.h"
+
+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();
+extern unsigned int system_management_exception_vector_prolog_code_size;
+extern void system_management_exception_vector_prolog_code();
+
+extern void BSP_panic(char *s);
+extern void _BSP_Fatal_error(unsigned int v);
+/*
+volatile unsigned int ppc_cached_irq_mask;
+*/
+
+/*
+ * 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;}
+
+static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER];
+static rtems_irq_global_settings initial_config;
+
+static rtems_irq_connect_data defaultIrq =
+ {
+ /* vectorIdex, hdl , param, on , off , isOn */
+ 0, nop_func, NULL , nop_func, nop_func, not_connected };
+
+static rtems_irq_prio irqPrioTable[BSP_SIU_IRQ_NUMBER] =
+ {
+/* per. int. priorities (0-7) / 4bit coding / msb is HI/LO selection */
+/* msb = 0 -> non-critical per. int. is routed to main int. (LO_int) */
+/* msb = 1 -> critical per. int. is routed to critical int. (HI_int) */
+ 0xF, 0, 0, 0, /* smart_comm (do not change!), psc1, psc2, psc3 */
+ 0, 0, 0, 0, /* irda, eth, usb, ata */
+ 0, 0, 0, 0, /* pci_ctrl, pci_sc_rx, pci_sc_tx, res */
+ 0, 0, 0, 0, /* res, spi_modf, spi_spif, i2c1 */
+ 0, 0, 0, 0, /* i2c, can1, can2, ir_rx */
+ 0, 0, /* ir_rx, xlb_arb */
+/* main interrupt priorities (0-7) / 4bit coding / msb is INT/SMI selection */
+/* msb = 0 -> main int. is routed to processor INT (low vector base 0x500 ) */
+/* msb = 1 -> main int. is routed to processor SMI (low vector base 0x1400 ) */
+ 0, 0, /* slice_tim2, irq1 */
+ 0, 0, 0, 0, /* irq2, irq3, lo_int, rtc_pint */
+ 0, 0, 0, 0, /* rtc_sint, gpio_std, gpio_wkup, tmr0 */
+ 0, 0, 0, 0, /* tmr1, tmr2, tmr3, tmr4 */
+ 0, 0, 0, /* tmr5, tmr6, tmr7 */
+ /* critical interrupt priorities (0-3) / 2bit coding / no special purpose of msb */
+ 0, /* irq0 */
+ 0, 0, 0 /* slice_tim1, hi_int, ccs_wkup */
+ };
+
+uint32_t irqMaskTable[BSP_PER_IRQ_NUMBER + BSP_MAIN_IRQ_NUMBER];
+
+
+/*
+ * setup irqMaskTable to support a priorized/nested interrupt environment
+ */
+void setup_irqMaskTable(void)
+ {
+ rtems_irq_prio prio = 0;
+ uint32_t i = 0, j = 0, mask = 0;
+
+ /* set up the priority dependent masks for peripheral interrupts */
+ for(i = BSP_PER_IRQ_LOWEST_OFFSET; i <= BSP_PER_IRQ_MAX_OFFSET; i++)
+ {
+
+ prio = irqPrioTable[i];
+ mask = 0;
+
+ for(j = BSP_PER_IRQ_LOWEST_OFFSET; j <= BSP_PER_IRQ_MAX_OFFSET; j++)
+ {
+
+ if(prio > irqPrioTable[j])
+ mask |= (1 << (31 - j + BSP_PER_IRQ_LOWEST_OFFSET));
+
+ if((prio == irqPrioTable[j]) && (j >= i))
+ mask |= (1 << (31 - j + BSP_PER_IRQ_LOWEST_OFFSET));
+
+ }
+
+ irqMaskTable[i] = mask;
+
+ }
+
+
+ /* set up the priority dependent masks for main interrupts */
+ for(i = BSP_MAIN_IRQ_LOWEST_OFFSET; i <= BSP_MAIN_IRQ_MAX_OFFSET; i++)
+ {
+
+ prio = irqPrioTable[i];
+ mask = 0;
+
+ for(j = BSP_MAIN_IRQ_LOWEST_OFFSET; j <= BSP_MAIN_IRQ_MAX_OFFSET; j++)
+ {
+
+ if(prio > irqPrioTable[j])
+ mask |= (1 << (16 - j + BSP_MAIN_IRQ_LOWEST_OFFSET));
+
+ if((prio == irqPrioTable[j]) && (j >= i))
+ mask |= (1 << (16 - j + BSP_MAIN_IRQ_LOWEST_OFFSET));
+
+ }
+
+ irqMaskTable[i] = mask;
+
+ }
+
+ }
+
+
+/*
+ * Initialize MPC5x00 SIU interrupt management
+ */
+void BSP_SIU_irq_init(void)
+ {
+
+ /* disable all peripheral interrupts */
+ mpc5200.per_mask = 0xFFFFFC00;
+
+ /* peripheral interrupt priorities according to reset value */
+ mpc5200.per_pri_1 = 0xF0000000;
+ mpc5200.per_pri_2 = 0x00000000;
+ mpc5200.per_pri_3 = 0x00000000;
+
+ /* disable external interrupts IRQ0-4 / critical interrupts are routed to core_int */
+ mpc5200.ext_en_type = 0x0F000001;
+
+ /* disable main interrupts / crit. int. priorities according to reset values */
+ mpc5200.crit_pri_main_mask = 0x0001FFFF;
+
+ /* main priorities according to reset value */
+ mpc5200.main_pri_1 = 0;
+ mpc5200.main_pri_2 = 0;
+
+ /* reset all status indicators */
+ mpc5200.csa = 0x0001FFFF;
+ mpc5200.msa = 0x0001FFFF;
+ mpc5200.psa = 0x003FFFFF;
+ mpc5200.psa_be = 0x03000000;
+
+ setup_irqMaskTable();
+
+ }
+
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+ {
+ rtems_raw_except_connect_data vectorDesc;
+ int i;
+
+ BSP_SIU_irq_init();
+ /*
+ * Initialize Rtems management interrupt table
+ */
+ /*
+ * re-init the rtemsIrq table
+ */
+ for (i = 0; i < BSP_IRQ_NUMBER; i++)
+ {
+ rtemsIrq[i] = defaultIrq;
+ rtemsIrq[i].name = i;
+ }
+ /*
+ * Init initial Interrupt management config
+ */
+ initial_config.irqNb = BSP_IRQ_NUMBER;
+ initial_config.defaultEntry = defaultIrq;
+ initial_config.irqHdlTbl = rtemsIrq;
+ initial_config.irqBase = BSP_ASM_IRQ_VECTOR_BASE;
+ initial_config.irqPrioTbl = irqPrioTable;
+
+ if (!BSP_rtems_irq_mngt_set(&initial_config))
+ {
+ /*
+ * put something here that will show the failure...
+ */
+ BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+ }
+
+ /*
+ * 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");
+ }
+
+ 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");
+ }
+
+ vectorDesc.exceptIndex = ASM_SYSMGMT_VECTOR;
+ vectorDesc.hdl.vector = ASM_SYSMGMT_VECTOR;
+ vectorDesc.hdl.raw_hdl = system_management_exception_vector_prolog_code;
+ vectorDesc.hdl.raw_hdl_size = (unsigned) &system_management_exception_vector_prolog_code_size;
+
+ if (!mpc60x_set_exception (&vectorDesc))
+ {
+ BSP_panic("Unable to initialize RTEMS system management raw exception\n");
+ }
+
+}
+