summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/gen83xx/irq
diff options
context:
space:
mode:
authorThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2007-07-10 16:00:28 +0000
committerThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2007-07-10 16:00:28 +0000
commitf610e83f5350e09d29a23352b420551d06f15499 (patch)
tree6f1914643c458af3c680a057405dea6bd0c7400a /c/src/lib/libbsp/powerpc/gen83xx/irq
parent2007-07-06 Joel Sherrill <joel.sherrill@OARcorp.com> (diff)
downloadrtems-f610e83f5350e09d29a23352b420551d06f15499.tar.bz2
compilable release of virtex/gen83xx/gen5200 powerpc adaptations. Merged many different versions of new exception handling code to shared sources.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/gen83xx/irq')
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/irq/ipic.c394
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/irq/irq.h149
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/irq/irq_init.c413
3 files changed, 956 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/irq/ipic.c b/c/src/lib/libbsp/powerpc/gen83xx/irq/ipic.c
new file mode 100644
index 0000000000..8433c32a67
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/gen83xx/irq/ipic.c
@@ -0,0 +1,394 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC83xx BSP |
++-----------------------------------------------------------------+
+| Copyright (c) 2007 |
+| 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 integrates the IPIC irq controller |
+\*===============================================================*/
+
+#include <mpc83xx/mpc83xx.h>
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <rtems/powerpc/powerpc.h>
+
+typedef struct {
+ volatile uint32_t *pend_reg;
+ volatile uint32_t *mask_reg;
+ const uint32_t bit_num;
+} BSP_isrc_rsc_t;
+
+const BSP_isrc_rsc_t BSP_ipic_isrc_rsc[] = {
+ /* vector 0 */
+ {&mpc83xx.ipic.sersr,&mpc83xx.ipic.sermr,31},
+ {NULL,NULL,0},
+ {NULL,NULL,0},
+ {NULL,NULL,0},
+ {NULL,NULL,0},
+ {NULL,NULL,0},
+ {NULL,NULL,0},
+ {NULL,NULL,0},
+ /* vector 8 */
+ {NULL,NULL,0}, /* reserved vector 8 */
+ /* vector 9: UART1 SIxxR_H, Bit 24 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],24},
+ /* vector 10: UART2 SIxxR_H, Bit 25 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],25},
+ /* vector 11: SEC SIxxR_H, Bit 26 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],26},
+ {NULL,NULL,0}, /* reserved vector 12 */
+ {NULL,NULL,0}, /* reserved vector 13 */
+ /* vector 14: I2C1 SIxxR_H, Bit 29 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],29},
+ /* vector 15: I2C2 SIxxR_H, Bit 30 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],30},
+ /* vector 16: SPI SIxxR_H, Bit 31 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],31},
+ /* vector 17: IRQ1 SExxR , Bit 1 */
+ {&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 1},
+ /* vector 18: IRQ2 SExxR , Bit 2 */
+ {&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 2},
+ /* vector 19: IRQ3 SExxR , Bit 3 */
+ {&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 3},
+ /* vector 20: IRQ4 SExxR , Bit 4 */
+ {&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 4},
+ /* vector 21: IRQ5 SExxR , Bit 5 */
+ {&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 5},
+ /* vector 22: IRQ6 SExxR , Bit 6 */
+ {&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 6},
+ /* vector 23: IRQ7 SExxR , Bit 7 */
+ {&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 7},
+ {NULL,NULL,0}, /* reserved vector 24 */
+ {NULL,NULL,0}, /* reserved vector 25 */
+ {NULL,NULL,0}, /* reserved vector 26 */
+ {NULL,NULL,0}, /* reserved vector 27 */
+ {NULL,NULL,0}, /* reserved vector 28 */
+ {NULL,NULL,0}, /* reserved vector 29 */
+ {NULL,NULL,0}, /* reserved vector 30 */
+ {NULL,NULL,0}, /* reserved vector 31 */
+ /* vector 32: TSEC1 Tx SIxxR_H , Bit 0 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 0},
+ /* vector 33: TSEC1 Rx SIxxR_H , Bit 1 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 1},
+ /* vector 34: TSEC1 Err SIxxR_H , Bit 2 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 2},
+ /* vector 35: TSEC2 Tx SIxxR_H , Bit 3 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 3},
+ /* vector 36: TSEC2 Rx SIxxR_H , Bit 4 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 4},
+ /* vector 37: TSEC2 Err SIxxR_H , Bit 5 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 5},
+ /* vector 38: USB DR SIxxR_H , Bit 6 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 6},
+ /* vector 39: USB MPH SIxxR_H , Bit 7 */
+ {&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 7},
+ {NULL,NULL,0}, /* reserved vector 40 */
+ {NULL,NULL,0}, /* reserved vector 41 */
+ {NULL,NULL,0}, /* reserved vector 42 */
+ {NULL,NULL,0}, /* reserved vector 43 */
+ {NULL,NULL,0}, /* reserved vector 44 */
+ {NULL,NULL,0}, /* reserved vector 45 */
+ {NULL,NULL,0}, /* reserved vector 46 */
+ {NULL,NULL,0}, /* reserved vector 47 */
+ /* vector 48: IRQ0 SExxR , Bit 0 */
+ {&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 0},
+ {NULL,NULL,0}, /* reserved vector 49 */
+ {NULL,NULL,0}, /* reserved vector 50 */
+ {NULL,NULL,0}, /* reserved vector 51 */
+ {NULL,NULL,0}, /* reserved vector 52 */
+ {NULL,NULL,0}, /* reserved vector 53 */
+ {NULL,NULL,0}, /* reserved vector 54 */
+ {NULL,NULL,0}, /* reserved vector 55 */
+ {NULL,NULL,0}, /* reserved vector 56 */
+ {NULL,NULL,0}, /* reserved vector 57 */
+ {NULL,NULL,0}, /* reserved vector 58 */
+ {NULL,NULL,0}, /* reserved vector 59 */
+ {NULL,NULL,0}, /* reserved vector 60 */
+ {NULL,NULL,0}, /* reserved vector 61 */
+ {NULL,NULL,0}, /* reserved vector 62 */
+ {NULL,NULL,0}, /* reserved vector 63 */
+ /* vector 64: RTC SEC SIxxR_L , Bit 0 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 0},
+ /* vector 65: PIT SIxxR_L , Bit 1 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 1},
+ /* vector 66: PCI1 SIxxR_L , Bit 2 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 2},
+ /* vector 67: PCI2 SIxxR_L , Bit 3 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 3},
+ /* vector 68: RTC ALR SIxxR_L , Bit 4 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 4},
+ /* vector 69: MU SIxxR_L , Bit 5 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 5},
+ /* vector 70: SBA SIxxR_L , Bit 6 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 6},
+ /* vector 71: DMA SIxxR_L , Bit 7 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 7},
+ /* vector 72: GTM4 SIxxR_L , Bit 8 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 8},
+ /* vector 73: GTM8 SIxxR_L , Bit 9 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 9},
+ /* vector 74: GPIO1 SIxxR_L , Bit 10 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],10},
+ /* vector 75: GPIO2 SIxxR_L , Bit 11 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],11},
+ /* vector 76: DDR SIxxR_L , Bit 12 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],12},
+ /* vector 77: LBC SIxxR_L , Bit 13 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],13},
+ /* vector 78: GTM2 SIxxR_L , Bit 14 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],14},
+ /* vector 79: GTM6 SIxxR_L , Bit 15 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],15},
+ /* vector 80: PMC SIxxR_L , Bit 16 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],16},
+ {NULL,NULL,0}, /* reserved vector 81 */
+ {NULL,NULL,0}, /* reserved vector 82 */
+ {NULL,NULL,0}, /* reserved vector 63 */
+ /* vector 84: GTM3 SIxxR_L , Bit 20 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],20},
+ /* vector 85: GTM7 SIxxR_L , Bit 21 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],21},
+ {NULL,NULL,0}, /* reserved vector 81 */
+ {NULL,NULL,0}, /* reserved vector 82 */
+ {NULL,NULL,0}, /* reserved vector 63 */
+ {NULL,NULL,0}, /* reserved vector 63 */
+ /* vector 90: GTM1 SIxxR_L , Bit 26 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],26},
+ /* vector 91: GTM5 SIxxR_L , Bit 27 */
+ {&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],27}
+};
+
+/*
+ * data structure to handle all mask registers in the IPIC
+ */
+typedef struct {
+ uint32_t simsr_mask[2];
+ uint32_t semsr_mask;
+ uint32_t sermr_mask;
+} BSP_ipic_mask_t;
+
+/*
+ * this array will be filled with mask values needed
+ * to temporarily disable all IRQ soures with lower or same
+ * priority of the current source (whose vector is the array index)
+ */
+BSP_ipic_mask_t BSP_ipic_prio2mask[BSP_ARRAY_CNT(BSP_ipic_isrc_rsc)];
+
+
+/*
+ * functions to enable/disable a source at the ipic
+ */
+void BSP_irq_enable_at_ipic (rtems_irq_number irqnum)
+{
+ uint32_t vecnum = irqnum - BSP_IPIC_IRQ_LOWEST_OFFSET;
+ const BSP_isrc_rsc_t *rsc_ptr;
+
+ if ((vecnum >= 0)
+ && (vecnum < BSP_ARRAY_CNT(BSP_ipic_isrc_rsc))) {
+ rsc_ptr = &BSP_ipic_isrc_rsc[vecnum];
+ if (rsc_ptr->mask_reg != NULL) {
+ *(rsc_ptr->mask_reg) |= 1 << (31-rsc_ptr->bit_num);
+ }
+ }
+}
+
+void BSP_irq_disable_at_ipic (rtems_irq_number irqnum)
+{
+ uint32_t vecnum = irqnum - BSP_IPIC_IRQ_LOWEST_OFFSET;
+ const BSP_isrc_rsc_t *rsc_ptr;
+
+ if ((vecnum >= 0)
+ && (vecnum < BSP_ARRAY_CNT(BSP_ipic_isrc_rsc))) {
+ rsc_ptr = &BSP_ipic_isrc_rsc[vecnum];
+ if (rsc_ptr->mask_reg != NULL) {
+ *(rsc_ptr->mask_reg) &= ~(1 << (31-rsc_ptr->bit_num));
+ }
+ }
+}
+
+
+/*
+ * IRQ Handler: this is called from the primary exception dispatcher
+ */
+rtems_status_code BSP_irq_handle_at_ipic(uint32_t excNum)
+{
+ rtems_status_code rc = RTEMS_SUCCESSFUL;
+ rtems_irq_connect_data *tbl_entry;
+ int32_t vecnum;
+ uint32_t msr_value;
+ uint32_t msr_save;
+ uint32_t msr_enable = 0;
+ BSP_ipic_mask_t mask_save;
+ const BSP_ipic_mask_t *mask_ptr;
+ /*
+ * get vector
+ */
+ switch(excNum) {
+ case ASM_EXT_VECTOR:
+ vecnum = MPC83xx_VCR_TO_VEC(mpc83xx.ipic.sivcr);
+ msr_enable = PPC_MSR_EE;
+ break;
+ case ASM_SYSMGMT_VECTOR:
+ vecnum = MPC83xx_VCR_TO_VEC(mpc83xx.ipic.smvcr);
+ msr_enable = PPC_MSR_EE;
+ break;
+#if defined(ASM_CRIT_VECTOR)
+ case ASM_CRIT_VECTOR:
+ vecnum = MPC83xx_VCR_TO_VEC(mpc83xx.ipic.scvcr);
+ break;
+#endif
+ default:
+ vecnum = -1;
+ }
+ /*
+ * check vector number
+ */
+ if ((vecnum >= 0)
+ && (vecnum < BSP_ARRAY_CNT(BSP_ipic_isrc_rsc))) {
+ /*
+ * save current mask registers
+ */
+ mask_save.simsr_mask[0] = mpc83xx.ipic.simsr[0];
+ mask_save.simsr_mask[1] = mpc83xx.ipic.simsr[1];
+ mask_save.semsr_mask = mpc83xx.ipic.semsr ;
+ mask_save.sermr_mask = mpc83xx.ipic.sermr ;
+ /*
+ * mask all lower prio interrupts
+ */
+ mask_ptr = &BSP_ipic_prio2mask[vecnum];
+ mpc83xx.ipic.simsr[0] &= mask_ptr->simsr_mask[0];
+ mpc83xx.ipic.simsr[1] &= mask_ptr->simsr_mask[1];
+ mpc83xx.ipic.semsr &= mask_ptr->semsr_mask ;
+ mpc83xx.ipic.sermr &= mask_ptr->sermr_mask ;
+ /*
+ * reenable msr_ee
+ */
+ _CPU_MSR_GET(msr_value);
+ msr_save = msr_value;
+ msr_value |= msr_enable;
+ _CPU_MSR_SET(msr_value);
+ /*
+ * call handler
+ */
+ tbl_entry = &BSP_rtems_irq_tbl[vecnum+BSP_IPIC_IRQ_LOWEST_OFFSET];
+ if (tbl_entry->hdl != NULL) {
+ (tbl_entry->hdl) (tbl_entry->handle);
+ } else {
+ printk("IPIC: Spurious interrupt; excNum=0x%x, vector=0x%02x\n\r",
+ excNum,vecnum);
+ }
+ /*
+ * disable msr_enable
+ */
+ _CPU_MSR_SET(msr_save);
+ /*
+ * restore initial masks
+ */
+ mpc83xx.ipic.simsr[0] = mask_save.simsr_mask[0];
+ mpc83xx.ipic.simsr[1] = mask_save.simsr_mask[1];
+ mpc83xx.ipic.semsr = mask_save.semsr_mask ;
+ mpc83xx.ipic.sermr = mask_save.sermr_mask ;
+ }
+ return rc;
+}
+
+
+/*
+ * fill the array BSP_ipic_prio2mask to allow masking of lower prio sources
+ * to implement nested interrupts
+ */
+rtems_status_code BSP_ipic_calc_prio2mask(void)
+{
+ rtems_status_code rc = RTEMS_SUCCESSFUL;
+ /*
+ * FIXME: fill the array
+ */
+ return rc;
+}
+
+/*
+ * activate the interrupt controller
+ */
+rtems_status_code BSP_ipic_intc_init(void)
+{
+ uint32_t msr_value;
+ rtems_status_code rc = RTEMS_SUCCESSFUL;
+
+ /*
+ * mask off all interrupts
+ */
+ mpc83xx.ipic.simsr[0] = 0;
+ mpc83xx.ipic.simsr[1] = 0;
+ mpc83xx.ipic.semsr = 0;
+ mpc83xx.ipic.sermr = 0;
+ /*
+ * set desired configuration as defined in bspopts.h
+ * normally, the default values should be fine
+ */
+#if defined(BSP_SICFR_VAL) /* defined in bspopts.h ? */
+ mpc83xx.ipic.sicfr = BSP_SICFR_VAL;
+#endif
+
+ /*
+ * set desired priorities as defined in bspopts.h
+ * normally, the default values should be fine
+ */
+#if defined(BSP_SIPRR0_VAL) /* defined in bspopts.h ? */
+ mpc83xx.ipic.siprr[0] = BSP_SIPRR0_VAL;
+#endif
+
+#if defined(BSP_SIPRR1_VAL) /* defined in bspopts.h ? */
+ mpc83xx.ipic.siprr[1] = BSP_SIPRR1_VAL;
+#endif
+
+#if defined(BSP_SIPRR2_VAL) /* defined in bspopts.h ? */
+ mpc83xx.ipic.siprr[2] = BSP_SIPRR2_VAL;
+#endif
+
+#if defined(BSP_SIPRR3_VAL) /* defined in bspopts.h ? */
+ mpc83xx.ipic.siprr[3] = BSP_SIPRR3_VAL;
+#endif
+
+#if defined(BSP_SMPRR0_VAL) /* defined in bspopts.h ? */
+ mpc83xx.ipic.smprr[0] = BSP_SMPRR0_VAL;
+#endif
+
+#if defined(BSP_SMPRR1_VAL) /* defined in bspopts.h ? */
+ mpc83xx.ipic.smprr[1] = BSP_SMPRR1_VAL;
+#endif
+
+#if defined(BSP_SECNR_VAL) /* defined in bspopts.h ? */
+ mpc83xx.ipic.secnr = BSP_SECNR_VAL;
+#endif
+
+ /*
+ * calculate priority masks
+ */
+ rc = BSP_ipic_calc_prio2mask();
+ if (rc == RTEMS_SUCCESSFUL) {
+ /*
+ * enable (non-critical) exceptions
+ */
+
+ _CPU_MSR_GET(msr_value);
+ msr_value |= PPC_MSR_EE;
+ _CPU_MSR_SET(msr_value);
+
+ /* install exit handler to close ipic when program atexit called */
+ /* atexit(ipic_intc_exit); */
+ }
+ return rc;
+}
+
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/irq/irq.h b/c/src/lib/libbsp/powerpc/gen83xx/irq/irq.h
new file mode 100644
index 0000000000..b9d3cfe49e
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/gen83xx/irq/irq.h
@@ -0,0 +1,149 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC83xx BSP |
++-----------------------------------------------------------------+
+| Copyright (c) 2007 |
+| 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 declares constants of the interrupt controller |
+\*===============================================================*/
+#ifndef GEN83xx_IRQ_IRQ_H
+#define GEN83xx_IRQ_IRQ_H
+
+#include <rtems.h>
+#include <rtems/irq.h>
+
+/*
+ * the following definitions specify the indices used
+ * to interface the interrupt handler API
+ */
+
+/*
+ * Base index for the module specific irq handlers
+ */
+#define BSP_ASM_IRQ_VECTOR_BASE 0x0
+#define BSP_IPIC_VECTOR_BASE BSP_ASM_IRQ_VECTOR_BASE
+
+/*
+ * Peripheral IRQ handlers related definitions
+ */
+#define BSP_IPIC_PER_IRQ_NUMBER 128
+#define BSP_IPIC_IRQ_LOWEST_OFFSET BSP_IPIC_VECTOR_BASE /* 0 */
+#define BSP_IPIC_IRQ_MAX_OFFSET (BSP_IPIC_IRQ_LOWEST_OFFSET\
+ +BSP_IPIC_PER_IRQ_NUMBER-1)
+
+#define BSP_IS_IPIC_IRQ(irqnum) \
+ (((irqnum) >= BSP_IPIC_IRQ_LOWEST_OFFSET) && \
+ ((irqnum) <= BSP_IPIC_IRQ_MAX_OFFSET))
+/*
+ * Processor IRQ handlers related definitions
+ */
+#define BSP_PROCESSOR_IRQ_NUMBER 1
+#define BSP_PROCESSOR_IRQ_LOWEST_OFFSET (BSP_IPIC_IRQ_MAX_OFFSET+1)
+#define BSP_PROCESSOR_IRQ_MAX_OFFSET (BSP_PROCESSOR_IRQ_LOWEST_OFFSET\
+ +BSP_PROCESSOR_IRQ_NUMBER-1)
+
+#define BSP_IS_PROCESSOR_IRQ(irqnum) \
+ (((irqnum) >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET) && \
+ ((irqnum) <= BSP_PROCESSOR_IRQ_MAX_OFFSET))
+/*
+ * Summary
+ */
+#define BSP_IRQ_NUMBER (BSP_PROCESSOR_IRQ_MAX_OFFSET+1)
+#define BSP_LOWEST_OFFSET BSP_IPIC_IRQ_LOWEST_OFFSET
+#define BSP_MAX_OFFSET BSP_PROCESSOR_IRQ_MAX_OFFSET
+
+#define BSP_IS_VALID_IRQ(irqnum) \
+ (BSP_IS_PROCESSOR_IRQ(irqnum) \
+ || BSP_IS_IPIC_IRQ(irqnum))
+
+#ifndef ASM
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * index table for the module specific handlers, a few entries are only placeholders
+ */
+ typedef enum {
+ BSP_IPIC_IRQ_FIRST = BSP_IPIC_IRQ_LOWEST_OFFSET,
+ BSP_IPIC_IRQ_ERROR = BSP_IPIC_IRQ_LOWEST_OFFSET + 0,
+ /* reserved irqs 1- 8 */
+ BSP_IPIC_IRQ_UART1 = BSP_IPIC_IRQ_LOWEST_OFFSET + 9,
+ BSP_IPIC_IRQ_UART2 = BSP_IPIC_IRQ_LOWEST_OFFSET + 10,
+ BSP_IPIC_IRQ_SEC = BSP_IPIC_IRQ_LOWEST_OFFSET + 11,
+ /* reserved irqs 12-13 */
+ BSP_IPIC_IRQ_I2C1 = BSP_IPIC_IRQ_LOWEST_OFFSET + 14,
+ BSP_IPIC_IRQ_I2C2 = BSP_IPIC_IRQ_LOWEST_OFFSET + 15,
+ BSP_IPIC_IRQ_SPI = BSP_IPIC_IRQ_LOWEST_OFFSET + 16,
+ BSP_IPIC_IRQ_IRQ1 = BSP_IPIC_IRQ_LOWEST_OFFSET + 17,
+ BSP_IPIC_IRQ_IRQ2 = BSP_IPIC_IRQ_LOWEST_OFFSET + 18,
+ BSP_IPIC_IRQ_IRQ3 = BSP_IPIC_IRQ_LOWEST_OFFSET + 19,
+ BSP_IPIC_IRQ_IRQ4 = BSP_IPIC_IRQ_LOWEST_OFFSET + 20,
+ BSP_IPIC_IRQ_IRQ5 = BSP_IPIC_IRQ_LOWEST_OFFSET + 21,
+ BSP_IPIC_IRQ_IRQ6 = BSP_IPIC_IRQ_LOWEST_OFFSET + 22,
+ BSP_IPIC_IRQ_IRQ7 = BSP_IPIC_IRQ_LOWEST_OFFSET + 23,
+ /* reserved irqs 24-31 */
+ BSP_IPIC_IRQ_TSEC1_TX = BSP_IPIC_IRQ_LOWEST_OFFSET + 32,
+ BSP_IPIC_IRQ_TSEC1_RX = BSP_IPIC_IRQ_LOWEST_OFFSET + 33,
+ BSP_IPIC_IRQ_TSEC1_ERR = BSP_IPIC_IRQ_LOWEST_OFFSET + 34,
+ BSP_IPIC_IRQ_TSEC2_TX = BSP_IPIC_IRQ_LOWEST_OFFSET + 35,
+ BSP_IPIC_IRQ_TSEC2_RX = BSP_IPIC_IRQ_LOWEST_OFFSET + 36,
+ BSP_IPIC_IRQ_TSEC2_ERR = BSP_IPIC_IRQ_LOWEST_OFFSET + 37,
+ BSP_IPIC_IRQ_USB_DR = BSP_IPIC_IRQ_LOWEST_OFFSET + 38,
+ BSP_IPIC_IRQ_USB_MPH = BSP_IPIC_IRQ_LOWEST_OFFSET + 39,
+ /* reserved irqs 40-47 */
+ BSP_IPIC_IRQ_IRQ0 = BSP_IPIC_IRQ_LOWEST_OFFSET + 48,
+ /* reserved irqs 49-63 */
+ BSP_IPIC_IRQ_RTC_SEC = BSP_IPIC_IRQ_LOWEST_OFFSET + 64,
+ BSP_IPIC_IRQ_PIT = BSP_IPIC_IRQ_LOWEST_OFFSET + 65,
+ BSP_IPIC_IRQ_PCI1 = BSP_IPIC_IRQ_LOWEST_OFFSET + 66,
+ BSP_IPIC_IRQ_PCI2 = BSP_IPIC_IRQ_LOWEST_OFFSET + 67,
+ BSP_IPIC_IRQ_RTC_ALR = BSP_IPIC_IRQ_LOWEST_OFFSET + 68,
+ BSP_IPIC_IRQ_MU = BSP_IPIC_IRQ_LOWEST_OFFSET + 69,
+ BSP_IPIC_IRQ_SBA = BSP_IPIC_IRQ_LOWEST_OFFSET + 70,
+ BSP_IPIC_IRQ_DMA = BSP_IPIC_IRQ_LOWEST_OFFSET + 71,
+ BSP_IPIC_IRQ_GTM4 = BSP_IPIC_IRQ_LOWEST_OFFSET + 72,
+ BSP_IPIC_IRQ_GTM8 = BSP_IPIC_IRQ_LOWEST_OFFSET + 73,
+ BSP_IPIC_IRQ_GPIO1 = BSP_IPIC_IRQ_LOWEST_OFFSET + 74,
+ BSP_IPIC_IRQ_GPIO2 = BSP_IPIC_IRQ_LOWEST_OFFSET + 75,
+ BSP_IPIC_IRQ_DDR = BSP_IPIC_IRQ_LOWEST_OFFSET + 76,
+ BSP_IPIC_IRQ_LBC = BSP_IPIC_IRQ_LOWEST_OFFSET + 77,
+ BSP_IPIC_IRQ_GTM2 = BSP_IPIC_IRQ_LOWEST_OFFSET + 78,
+ BSP_IPIC_IRQ_GTM6 = BSP_IPIC_IRQ_LOWEST_OFFSET + 79,
+ BSP_IPIC_IRQ_PMC = BSP_IPIC_IRQ_LOWEST_OFFSET + 80,
+ /* reserved irqs 81-83 */
+ BSP_IPIC_IRQ_GTM3 = BSP_IPIC_IRQ_LOWEST_OFFSET + 84,
+ BSP_IPIC_IRQ_GTM7 = BSP_IPIC_IRQ_LOWEST_OFFSET + 85,
+ /* reserved irqs 86-89 */
+ BSP_IPIC_IRQ_GTM1 = BSP_IPIC_IRQ_LOWEST_OFFSET + 90,
+ BSP_IPIC_IRQ_GTM5 = BSP_IPIC_IRQ_LOWEST_OFFSET + 91,
+ /* reserved irqs 92-127 */
+
+ BSP_IPIC_IRQ_LAST = BSP_IPIC_IRQ_MAX_OFFSET,
+ BSP_DECREMENTER = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 0
+ } rtems_irq_symbolic_name;
+
+ extern rtems_irq_connect_data *BSP_rtems_irq_tbl;
+ void BSP_rtems_irq_mng_init(unsigned cpuId);
+
+ /* ipic.c */
+ rtems_status_code BSP_irq_handle_at_ipic(uint32_t excNum);
+ void BSP_irq_enable_at_ipic (rtems_irq_number irqnum);
+ void BSP_irq_disable_at_ipic (rtems_irq_number irqnum);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ASM */
+
+#endif /* GEN83XX_IRQ_IRQ_H */
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/irq/irq_init.c b/c/src/lib/libbsp/powerpc/gen83xx/irq/irq_init.c
new file mode 100644
index 0000000000..c930f7bcbf
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/gen83xx/irq/irq_init.c
@@ -0,0 +1,413 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC83xx BSP |
++-----------------------------------------------------------------+
+| Copyright (c) 2007 |
+| 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 init code |
++-----------------------------------------------------------------+
+| derived from the virtex BSP |
+\*===============================================================*/
+#include <libcpu/spr.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <libcpu/raw_exception.h>
+#include <rtems/bspIo.h>
+#include <rtems/powerpc/powerpc.h>
+#include <bsp/vectors.h>
+
+static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
+rtems_irq_connect_data *BSP_rtems_irq_tbl;
+rtems_irq_global_settings* BSP_rtems_irq_config;
+
+/***********************************************************
+ * dummy functions for on/off/isOn calls
+ * these functions just do nothing fulfill the semantic
+ * requirements to enable/disable a certain interrupt or exception
+ */
+void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
+{
+ /*
+ * nothing to do
+ */
+}
+
+void BSP_irq_nop_hdl(void *hdl)
+{
+ /*
+ * nothing to do
+ */
+}
+
+int BSP_irq_true_func(const rtems_irq_connect_data *unused)
+{
+ /*
+ * nothing to do
+ */
+ return TRUE;
+}
+
+/***********************************************************
+ * interrupt handler and its enable/disable functions
+ ***********************************************************/
+
+/***********************************************************
+ * functions to enable/disable/query external/critical interrupts
+ */
+void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data)
+{
+ uint32_t msr_value;
+ /*
+ * get current MSR value
+ */
+ _CPU_MSR_GET(msr_value);
+
+
+ msr_value |= PPC_MSR_EE;
+ _CPU_MSR_SET(msr_value);
+}
+
+void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
+{
+ /*
+ * nothing to do
+ */
+}
+
+/***********************************************************
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
+{
+ uint32_t msr_value,new_msr;
+
+ /*
+ * Handle interrupt
+ */
+ switch(excNum) {
+ case ASM_DEC_VECTOR:
+ _CPU_MSR_GET(msr_value);
+ new_msr = msr_value | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ BSP_rtems_irq_tbl[BSP_DECREMENTER].hdl
+ (BSP_rtems_irq_tbl[BSP_DECREMENTER].handle);
+
+ _CPU_MSR_SET(msr_value);
+
+ break;
+#if 0 /* Critical interrupts not yet supported */
+ case ASM_CRIT_VECTOR:
+#endif
+ case ASM_SYSMGMT_VECTOR:
+ case ASM_EXT_VECTOR:
+ BSP_irq_handle_at_ipic(excNum);
+ break;
+ }
+}
+
+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();
+ }
+}
+
+/***********************************************************
+ * functions to set/get/remove interrupt handlers
+ ***********************************************************/
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+ /*
+ * check for valid irq name
+ * if invalid, print error and return 0
+ */
+ if (!BSP_IS_VALID_IRQ(irq->name)) {
+ printk("Invalid interrupt vector %d\n",irq->name);
+ return 0;
+ }
+
+ /*
+ * disable interrupts
+ */
+ _CPU_ISR_Disable(level);
+ /*
+ * check, that default handler is installed now
+ */
+ if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
+ _CPU_ISR_Enable(level);
+ printk("IRQ vector %d already connected\n",irq->name);
+ return 0;
+ }
+ /*
+ * store new handler data
+ */
+ rtemsIrqTbl[irq->name] = *irq;
+
+ /*
+ * enable irq at interrupt controller
+ */
+ if (BSP_IS_IPIC_IRQ(irq->name)) {
+ BSP_irq_enable_at_ipic(irq->name);
+ }
+ /*
+ * call "on" function to enable interrupt at device
+ */
+ irq->on(irq);
+ /*
+ * reenable interrupts
+ */
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ /*
+ * check for valid IRQ name
+ */
+ if (!BSP_IS_VALID_IRQ(irq->name)) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+ /*
+ * return current IRQ entry
+ */
+ *irq = rtemsIrqTbl[irq->name];
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ /*
+ * check for valid IRQ name
+ */
+ if (!BSP_IS_VALID_IRQ(irq->name)) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+ /*
+ * check, that specified handler is really connected now
+ */
+ if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
+ _CPU_ISR_Enable(level);
+ return 0;
+ }
+ /*
+ * disable interrupt at interrupt controller
+ */
+ if (BSP_IS_IPIC_IRQ(irq->name)) {
+ BSP_irq_disable_at_ipic(irq->name);
+ }
+ /*
+ * disable interrupt at source
+ */
+ irq->off(irq);
+ /*
+ * restore default interrupt handler
+ */
+ rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
+
+ /*
+ * reenable interrupts
+ */
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+/***********************************************************
+ * functions to set/get the basic interrupt management setup
+ ***********************************************************/
+/*
+ * (Re) get info on current RTEMS interrupt management.
+ */
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
+{
+ *ret_ptr = BSP_rtems_irq_config;
+ return 0;
+}
+
+
+/*
+ * set management stuff
+ */
+int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
+{
+ int i;
+ unsigned int level;
+
+ _CPU_ISR_Disable(level);
+ /*
+ * store given configuration
+ */
+ BSP_rtems_irq_config = config;
+ BSP_rtems_irq_tbl = BSP_rtems_irq_config->irqHdlTbl;
+ /*
+ * enable any non-empty IRQ entries at OPBINTC
+ */
+ for (i = BSP_IPIC_IRQ_LOWEST_OFFSET;
+ i <= BSP_IPIC_IRQ_MAX_OFFSET;
+ i++) {
+ if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
+ BSP_irq_enable_at_ipic(i);
+ BSP_rtems_irq_tbl[i].on((&BSP_rtems_irq_tbl[i]));
+ }
+ else {
+ BSP_rtems_irq_tbl[i].off(&(BSP_rtems_irq_tbl[i]));
+ BSP_irq_disable_at_ipic(i);
+ }
+ }
+ /*
+ * store any irq-like processor exceptions
+ */
+ for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
+ i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
+ i++) {
+ if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
+ if (BSP_rtems_irq_tbl[i].on != NULL) {
+ BSP_rtems_irq_tbl[i].on
+ (&(BSP_rtems_irq_tbl[i]));
+ }
+ }
+ else {
+ if (BSP_rtems_irq_tbl[i].off != NULL) {
+ BSP_rtems_irq_tbl[i].off
+ (&(BSP_rtems_irq_tbl[i]));
+ }
+ }
+ }
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+/**********************************************
+ * list of exception vectors to tap for interrupt handlers
+ */
+static rtems_raw_except_connect_data BSP_vec_desc[] = {
+#if defined(ASM_DEC_VECTOR)
+ {ASM_DEC_VECTOR,
+ {ASM_DEC_VECTOR,
+ decrementer_exception_vector_prolog_code,
+ (size_t)decrementer_exception_vector_prolog_code_size
+ },
+ exception_nop_enable,
+ exception_nop_enable,
+ exception_always_enabled
+ },
+#endif
+#if defined(ASM_SYSMGMT_VECTOR)
+ {ASM_SYSMGMT_VECTOR,
+ {ASM_SYSMGMT_VECTOR,
+ sysmgmt_exception_vector_prolog_code,
+ (size_t)sysmgmt_exception_vector_prolog_code_size
+ },
+ exception_nop_enable,
+ exception_nop_enable,
+ exception_always_enabled
+ },
+#endif
+ {ASM_EXT_VECTOR,
+ {ASM_EXT_VECTOR,
+ external_exception_vector_prolog_code,
+ (size_t)&external_exception_vector_prolog_code_size
+ },
+ exception_nop_enable,
+ exception_nop_enable,
+ exception_always_enabled
+ }
+#if 0 /* Critical interrupts not yet supported */
+ ,{ASM_CRIT_VECTOR,
+ {ASM_CRIT_VECTOR,
+ critical_exception_vector_prolog_code,
+ critical_exception_vector_prolog_code_size
+ }
+ BSP_irq_nop_func,
+ BSP_irq_nop_func,
+ BSP_irq_true_func
+ }
+#endif
+};
+
+/*
+ * dummy for an empty IRQ handler entry
+ */
+static rtems_irq_connect_data emptyIrq = {
+ 0, /* Irq Name */
+ BSP_irq_nop_hdl, /* handler function */
+ NULL, /* handle passed to handler */
+ BSP_irq_nop_func, /* on function */
+ BSP_irq_nop_func, /* off function */
+ BSP_irq_true_func /* isOn function */
+};
+
+static rtems_irq_global_settings initialConfig = {
+ BSP_IRQ_NUMBER, /* irqNb */
+ { 0, /* Irq Name */
+ BSP_irq_nop_hdl, /* handler function */
+ NULL, /* handle passed to handler */
+ BSP_irq_nop_func, /* on function */
+ BSP_irq_nop_func, /* off function */
+ BSP_irq_true_func /* isOn function */
+ }, /* emptyIrq */
+ rtemsIrqTbl, /* irqHdlTbl */
+ 0, /* irqBase */
+ NULL /* irqPrioTbl */
+};
+
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+ int i;
+ /*
+ * connect all exception vectors needed
+ */
+ for (i = 0;
+ i < (sizeof(BSP_vec_desc) /
+ sizeof(BSP_vec_desc[0]));
+ i++) {
+ if (!ppc_set_exception (&BSP_vec_desc[i])) {
+ BSP_panic("Unable to initialize RTEMS raw exception\n");
+ }
+ }
+ /*
+ * setup interrupt handlers table
+ */
+ for (i = 0;
+ i < BSP_IRQ_NUMBER;
+ i++) {
+ rtemsIrqTbl[i] = emptyIrq;
+ rtemsIrqTbl[i].name = i;
+ }
+
+ /*
+ * initialize interrupt management
+ */
+ if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
+ BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+ }
+}
+