[rtems commit] bsp/genmcf548x: Add interrupt extension support

Sebastian Huber sebh at rtems.org
Mon Dec 16 14:13:16 UTC 2013


Module:    rtems
Branch:    master
Commit:    5df9bf6e8a8f1efa88625467d9ccf4ac51d89cdb
Changeset: http://git.rtems.org/rtems/commit/?id=5df9bf6e8a8f1efa88625467d9ccf4ac51d89cdb

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Dec  5 16:42:06 2013 +0100

bsp/genmcf548x: Add interrupt extension support

---

 c/src/lib/libbsp/m68k/genmcf548x/Makefile.am   |   14 ++
 c/src/lib/libbsp/m68k/genmcf548x/include/irq.h |   79 ++++++++
 c/src/lib/libbsp/m68k/genmcf548x/irq/irq.c     |  235 ++++++++++++++++++++++++
 c/src/lib/libbsp/m68k/genmcf548x/preinstall.am |   12 ++
 4 files changed, 340 insertions(+), 0 deletions(-)

diff --git a/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am
index 6a7cfd9..64e7682 100644
--- a/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am
+++ b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am
@@ -9,6 +9,12 @@ include_HEADERS += include/tm27.h
 
 nodist_include_HEADERS = include/bspopts.h
 nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h
+
+include_bsp_HEADERS =
+include_bsp_HEADERS += ../../shared/include/irq-generic.h
+include_bsp_HEADERS += ../../shared/include/irq-info.h
+include_bsp_HEADERS += include/irq.h
+
 DISTCLEANFILES = include/bspopts.h
 noinst_PROGRAMS =
 
@@ -42,6 +48,14 @@ libbsp_a_SOURCES += console/console.c
 # timer
 libbsp_a_SOURCES += timer/timer.c
 
+# IRQ
+libbsp_a_SOURCES += ../../shared/src/irq-default-handler.c
+libbsp_a_SOURCES += ../../shared/src/irq-info.c
+libbsp_a_SOURCES += ../../shared/src/irq-legacy.c
+libbsp_a_SOURCES += ../../shared/src/irq-server.c
+libbsp_a_SOURCES += ../../shared/src/irq-shell.c
+libbsp_a_SOURCES += irq/irq.c
+
 if HAS_NETWORKING
 network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
 noinst_PROGRAMS += network.rel
diff --git a/c/src/lib/libbsp/m68k/genmcf548x/include/irq.h b/c/src/lib/libbsp/m68k/genmcf548x/include/irq.h
new file mode 100644
index 0000000..23ff73d
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/genmcf548x/include/irq.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at 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.
+ */
+
+#ifndef LIBBSP_M68K_MCF548X_IRQ_H
+#define LIBBSP_M68K_MCF548X_IRQ_H
+
+#include <rtems.h>
+#include <rtems/irq.h>
+#include <rtems/irq-extension.h>
+
+#define MCF548X_IRQ_EPORT_EPF1 1
+#define MCF548X_IRQ_EPORT_EPF2 2
+#define MCF548X_IRQ_EPORT_EPF3 3
+#define MCF548X_IRQ_EPORT_EPF4 4
+#define MCF548X_IRQ_EPORT_EPF5 5
+#define MCF548X_IRQ_EPORT_EPF6 6
+#define MCF548X_IRQ_EPORT_EPF7 7
+#define MCF548X_IRQ_USB_EP0ISR 15
+#define MCF548X_IRQ_USB_EP1ISR 16
+#define MCF548X_IRQ_USB_EP2ISR 17
+#define MCF548X_IRQ_USB_EP3ISR 18
+#define MCF548X_IRQ_USB_EP4ISR 19
+#define MCF548X_IRQ_USB_EP5ISR 20
+#define MCF548X_IRQ_USB_EP6ISR 21
+#define MCF548X_IRQ_USB_ISR 22
+#define MCF548X_IRQ_USB_AISR 23
+#define MCF548X_IRQ_DSPI_RFOF_TFUF 25
+#define MCF548X_IRQ_DSPI_RFOF 26
+#define MCF548X_IRQ_DSPI_RFDF 27
+#define MCF548X_IRQ_DSPI_TFUF 28
+#define MCF548X_IRQ_DSPI_TCF 29
+#define MCF548X_IRQ_DSPI_TFFF 30
+#define MCF548X_IRQ_DSPI_EOQF 31
+#define MCF548X_IRQ_DSPI 25
+#define MCF548X_IRQ_PSC3 32
+#define MCF548X_IRQ_PSC2 33
+#define MCF548X_IRQ_PSC1 34
+#define MCF548X_IRQ_PSC0 35
+#define MCF548X_IRQ_PSC(i) (35 - (i))
+#define MCF548X_IRQ_COMMTIM 36
+#define MCF548X_IRQ_SEC 37
+#define MCF548X_IRQ_FEC1 38
+#define MCF548X_IRQ_FEC0 39
+#define MCF548X_IRQ_FEC(i) (39 - (i))
+#define MCF548X_IRQ_I2C 40
+#define MCF548X_IRQ_PCIARB 41
+#define MCF548X_IRQ_CBPCI 42
+#define MCF548X_IRQ_XLBPCI 43
+#define MCF548X_IRQ_XLBARB 47
+#define MCF548X_IRQ_DMA 48
+#define MCF548X_IRQ_CAN0_ERROR 49
+#define MCF548X_IRQ_CAN0_BUSOFF 50
+#define MCF548X_IRQ_CAN0_MBOR 51
+#define MCF548X_IRQ_SLT1 53
+#define MCF548X_IRQ_SLT0 54
+#define MCF548X_IRQ_CAN1_ERROR 55
+#define MCF548X_IRQ_CAN1_BUSOFF 56
+#define MCF548X_IRQ_CAN1_MBOR 57
+#define MCF548X_IRQ_GPT3 59
+#define MCF548X_IRQ_GPT2 60
+#define MCF548X_IRQ_GPT1 61
+#define MCF548X_IRQ_GPT0 62
+
+#define BSP_INTERRUPT_VECTOR_MIN 1
+
+#define BSP_INTERRUPT_VECTOR_MAX 63
+
+#endif /* LIBBSP_M68K_MCF548X_IRQ_H */
diff --git a/c/src/lib/libbsp/m68k/genmcf548x/irq/irq.c b/c/src/lib/libbsp/m68k/genmcf548x/irq/irq.c
new file mode 100644
index 0000000..2f2f43a
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/genmcf548x/irq/irq.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at 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.
+ */
+
+#include <bsp/irq-generic.h>
+
+#include <mcf548x/mcf548x.h>
+
+void asm_default_interrupt(void);
+
+typedef void (*void_func)(void);
+
+typedef struct {
+  rtems_interrupt_handler handler;
+  void *arg;
+  const char *info;
+} interrupt_control;
+
+static interrupt_control interrupt_controls[BSP_INTERRUPT_VECTOR_MAX + 1];
+
+static uint32_t vector_to_reg(rtems_vector_number vector)
+{
+  return ((vector + 32U) >> 5) & 0x1;
+}
+
+static uint32_t vector_to_bit(rtems_vector_number vector)
+{
+  return 1U << (vector & 0x1fU);
+}
+
+static volatile uint32_t *vector_to_imr(rtems_vector_number vector)
+{
+  volatile uint32_t *imr = &MCF548X_INTC_IMRH;
+
+  return &imr[vector_to_reg(vector)];
+}
+
+static rtems_vector_number exception_vector_to_vector(
+  rtems_vector_number exception_vector
+)
+{
+  return exception_vector - 64U;
+}
+
+static rtems_vector_number vector_to_exception_vector(
+  rtems_vector_number vector
+)
+{
+  return vector + 64U;
+}
+
+rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  if (bsp_interrupt_is_valid_vector(vector)) {
+    volatile uint32_t *imr = vector_to_imr(vector);
+    uint32_t bit = vector_to_bit(vector);
+    rtems_interrupt_level level;
+
+    rtems_interrupt_disable(level);
+    *imr &= ~bit;
+    rtems_interrupt_enable(level);
+  } else {
+    sc = RTEMS_INVALID_ID;
+  }
+
+  return sc;
+}
+
+rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  if (bsp_interrupt_is_valid_vector(vector)) {
+    volatile uint32_t *imr = vector_to_imr(vector);
+    uint32_t bit = vector_to_bit(vector);
+    rtems_interrupt_level level;
+
+    rtems_interrupt_disable(level);
+    *imr |= bit;
+    rtems_interrupt_enable(level);
+  } else {
+    sc = RTEMS_INVALID_ID;
+  }
+
+  return sc;
+}
+
+static void_func get_exception_handler(rtems_vector_number vector)
+{
+  void_func *exception_table;
+
+  m68k_get_vbr(exception_table);
+
+  return exception_table[vector_to_exception_vector(vector)];
+}
+
+static void set_exception_handler(rtems_vector_number vector, void_func handler)
+{
+  void_func *exception_table;
+
+  m68k_get_vbr(exception_table);
+
+  exception_table[vector_to_exception_vector(vector)] = handler;
+}
+
+static void dispatch_handler(rtems_vector_number exception_vector)
+{
+  const interrupt_control *ic =
+    &interrupt_controls[exception_vector_to_vector(exception_vector)];
+
+  (*ic->handler)(ic->arg);
+}
+
+static uint8_t get_intc_icr(rtems_vector_number vector)
+{
+  volatile uint8_t *icr = &MCF548X_INTC_ICR0;
+
+  return icr[vector];
+}
+
+rtems_status_code rtems_interrupt_handler_install(
+  rtems_vector_number vector,
+  const char *info,
+  rtems_option options,
+  rtems_interrupt_handler handler,
+  void *arg
+)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  if (bsp_interrupt_is_valid_vector(vector)) {
+    rtems_interrupt_level level;
+
+    rtems_interrupt_disable(level);
+
+    if (
+      get_exception_handler(vector) == asm_default_interrupt
+        && get_intc_icr(vector) != 0
+    ) {
+      interrupt_control *ic = &interrupt_controls[vector];
+
+      ic->handler = handler;
+      ic->arg = arg;
+      ic->info = info;
+
+      _ISR_Vector_table[vector_to_exception_vector(vector)]
+        = dispatch_handler;
+      set_exception_handler(vector, _ISR_Handler);
+      bsp_interrupt_vector_enable(vector);
+    } else {
+      sc = RTEMS_RESOURCE_IN_USE;
+    }
+
+    rtems_interrupt_enable(level);
+  } else {
+    sc = RTEMS_INVALID_ID;
+  }
+
+  return sc;
+}
+
+static bool is_occupied_by_us(rtems_vector_number vector)
+{
+  return get_exception_handler(vector) == _ISR_Handler
+    && _ISR_Vector_table[vector_to_exception_vector(vector)]
+      == dispatch_handler;
+}
+
+rtems_status_code rtems_interrupt_handler_remove(
+  rtems_vector_number vector,
+  rtems_interrupt_handler handler,
+  void *arg
+)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  if (bsp_interrupt_is_valid_vector(vector)) {
+    rtems_interrupt_level level;
+    interrupt_control *ic = &interrupt_controls[vector];
+
+    rtems_interrupt_disable(level);
+
+    if (
+      is_occupied_by_us(vector)
+        && ic->handler == handler
+        && ic->arg == arg
+    ) {
+      bsp_interrupt_vector_disable(vector);
+      set_exception_handler(vector, asm_default_interrupt);
+
+      memset(ic, 0, sizeof(*ic));
+    } else {
+      sc = RTEMS_UNSATISFIED;
+    }
+
+    rtems_interrupt_enable(level);
+  } else {
+    sc = RTEMS_INVALID_ID;
+  }
+
+  return sc;
+}
+
+rtems_status_code rtems_interrupt_handler_iterate(
+  rtems_vector_number vector,
+  rtems_interrupt_per_handler_routine routine,
+  void *arg
+)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  if (bsp_interrupt_is_valid_vector(vector)) {
+    if (is_occupied_by_us(vector)) {
+      const interrupt_control *ic = &interrupt_controls[vector];
+
+      (*routine)(arg, ic->info, RTEMS_INTERRUPT_UNIQUE, ic->handler, ic->arg);
+    }
+  } else {
+    sc = RTEMS_INVALID_ID;
+  }
+
+  return sc;
+}
diff --git a/c/src/lib/libbsp/m68k/genmcf548x/preinstall.am b/c/src/lib/libbsp/m68k/genmcf548x/preinstall.am
index 8c86e37..31ce6bc 100644
--- a/c/src/lib/libbsp/m68k/genmcf548x/preinstall.am
+++ b/c/src/lib/libbsp/m68k/genmcf548x/preinstall.am
@@ -49,6 +49,18 @@ $(PROJECT_INCLUDE)/bsp/bootcard.h: ../../shared/include/bootcard.h $(PROJECT_INC
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bootcard.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h
 
+$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
+
+$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
+
+$(PROJECT_INCLUDE)/bsp/irq.h: include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
+
 $(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h




More information about the vc mailing list