summaryrefslogtreecommitdiffstats
path: root/bsps/powerpc/tqm8xx
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 09:50:39 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:44 +0200
commit8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708 (patch)
tree5dc76f7a4527b0a500fbf5ee91486b2780e47a1a /bsps/powerpc/tqm8xx
parentbsps: Move SPI drivers to bsps (diff)
downloadrtems-8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708.tar.bz2
bsps: Move interrupt controller support to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'bsps/powerpc/tqm8xx')
-rw-r--r--bsps/powerpc/tqm8xx/irq/irq.c231
1 files changed, 231 insertions, 0 deletions
diff --git a/bsps/powerpc/tqm8xx/irq/irq.c b/bsps/powerpc/tqm8xx/irq/irq.c
new file mode 100644
index 0000000000..2a94c27d1b
--- /dev/null
+++ b/bsps/powerpc/tqm8xx/irq/irq.c
@@ -0,0 +1,231 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by |
+| Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> |
+| Copyright (c) 2008 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
+| |
+| See the other copyright notice below for the original parts. |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be |
+| found in the file LICENSE in this distribution or at |
+| |
+| http://www.rtems.org/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| this file contains the console driver |
+\*===============================================================*/
+/* derived from: generic MPC83xx BSP */
+
+#include <rtems.h>
+#include <mpc8xx.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <bsp/vectors.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+/*
+ * functions to enable/disable a source at the SIU/CPM irq controller
+ */
+
+static rtems_status_code bsp_irq_disable_at_SIU(rtems_vector_number irqnum)
+{
+ rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
+ m8xx.simask &= ~(1 << (31 - vecnum));
+ return RTEMS_SUCCESSFUL;
+}
+
+static rtems_status_code bsp_irq_enable_at_SIU(rtems_vector_number irqnum)
+{
+ rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
+ m8xx.simask |= (1 << (31 - vecnum));
+ return RTEMS_SUCCESSFUL;
+}
+
+static rtems_status_code bsp_irq_disable_at_CPM(rtems_vector_number irqnum)
+{
+ rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
+ m8xx.cimr &= ~(1 << (vecnum));
+ return RTEMS_SUCCESSFUL;
+}
+
+static rtems_status_code bsp_irq_enable_at_CPM(rtems_vector_number irqnum)
+{
+ rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
+ m8xx.cimr |= (1 << (vecnum));
+ return RTEMS_SUCCESSFUL;
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ if (BSP_IS_CPM_IRQ(vector)) {
+ bsp_irq_enable_at_CPM(vector);
+ } else if (BSP_IS_SIU_IRQ(vector)) {
+ bsp_irq_enable_at_SIU(vector);
+ }
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+ if (BSP_IS_CPM_IRQ(vector)) {
+ bsp_irq_disable_at_CPM(vector);
+ } else if (BSP_IS_SIU_IRQ(vector)) {
+ bsp_irq_disable_at_SIU(vector);
+ }
+}
+
+/*
+ * IRQ Handler: this is called from the primary exception dispatcher
+ */
+static int BSP_irq_handle_at_cpm(void)
+{
+ int32_t cpvecnum;
+ uint32_t msr;
+
+ /* Get vector number: write IACK=1, then read vectir */
+ m8xx.civr = 1;
+ cpvecnum = (m8xx.civr >> 11) + BSP_CPM_IRQ_LOWEST_OFFSET;
+
+ /*
+ * Check the vector number,
+ * enable exceptions and dispatch the handler.
+ * NOTE: lower-prio interrupts are automatically masked in CPIC
+ */
+ if (BSP_IS_CPM_IRQ(cpvecnum)) {
+ /* Enable all interrupts */
+ msr = ppc_external_exceptions_enable();
+ /* Dispatch interrupt handlers */
+ bsp_interrupt_handler_dispatch(cpvecnum);
+ /* Restore machine state */
+ ppc_external_exceptions_disable(msr);
+ }
+ else {
+ /* not valid vector */
+ bsp_interrupt_handler_default(cpvecnum);
+ }
+ /*
+ * clear "in-service" bit
+ */
+ m8xx.cisr = 1 << (cpvecnum - BSP_CPM_IRQ_LOWEST_OFFSET);
+
+ return 0;
+}
+
+static int BSP_irq_handle_at_siu( unsigned excNum)
+{
+ int32_t sivecnum;
+ uint32_t msr;
+ bool is_cpm_irq;
+ uint32_t simask_save;
+ /*
+ * check, if interrupt is pending
+ * and repeat as long as valid interrupts are pending
+ */
+ while (0 != (m8xx.simask & m8xx.sipend)) {
+ /* Get vector number */
+ sivecnum = (m8xx.sivec >> 26);
+ is_cpm_irq = (sivecnum == BSP_CPM_INTERRUPT);
+ /*
+ * Check the vector number, mask lower priority interrupts, enable
+ * exceptions and dispatch the handler.
+ */
+ if (BSP_IS_SIU_IRQ(sivecnum)) {
+ simask_save = m8xx.simask;
+ /*
+ * if this is the CPM interrupt, mask lower prio interrupts at SIU
+ * else mask lower and same priority interrupts
+ */
+ m8xx.simask &= ~0 << (32
+ - sivecnum
+ - ((is_cpm_irq) ? 1 : 0));
+
+ if (is_cpm_irq) {
+ BSP_irq_handle_at_cpm();
+ }
+ else {
+ /* Enable all interrupts */
+ msr = ppc_external_exceptions_enable();
+ /* Dispatch interrupt handlers */
+ bsp_interrupt_handler_dispatch(sivecnum + BSP_SIU_IRQ_LOWEST_OFFSET);
+ /* Restore machine state */
+ ppc_external_exceptions_disable(msr);
+ /*
+ * clear pending bit, if edge triggered interrupt input
+ */
+ m8xx.sipend = 1 << (31 - sivecnum);
+ }
+
+
+ /* Restore initial masks */
+ m8xx.simask = simask_save;
+ } else {
+ /* not valid vector */
+ bsp_interrupt_handler_default(sivecnum);
+ }
+ }
+ return 0;
+}
+
+/*
+ * Activate the CPIC
+ */
+static rtems_status_code mpc8xx_cpic_initialize( void)
+{
+ /*
+ * mask off all interrupts
+ */
+ m8xx.cimr = 0;
+ /*
+ * make sure CPIC request proper level at SIU interrupt controller
+ */
+ m8xx.cicr = (0x00e41f80 |
+ ((BSP_CPM_INTERRUPT/2) << 13));
+ /*
+ * enable CPIC interrupt in SIU interrupt controller
+ */
+ return bsp_irq_enable_at_SIU(BSP_CPM_INTERRUPT);
+}
+
+/*
+ * Activate the SIU interrupt controller
+ */
+static rtems_status_code mpc8xx_siu_int_initialize( void)
+{
+ /*
+ * mask off all interrupts
+ */
+ m8xx.simask = 0;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+static int mpc8xx_exception_handler(BSP_Exception_frame *frame,
+ unsigned exception_number)
+{
+ return BSP_irq_handle_at_siu(exception_number);
+}
+
+rtems_status_code bsp_interrupt_facility_initialize()
+{
+ /* Install exception handler */
+ if (ppc_exc_set_handler(ASM_EXT_VECTOR, mpc8xx_exception_handler)) {
+ return RTEMS_IO_ERROR;
+ }
+ /* Initialize the SIU interrupt controller */
+ if (mpc8xx_siu_int_initialize()) {
+ return RTEMS_IO_ERROR;
+ }
+ /* Initialize the CPIC interrupt controller */
+ return mpc8xx_cpic_initialize();
+}