summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/genmcf548x
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-12-05 16:42:06 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-12-16 15:15:41 +0100
commit5df9bf6e8a8f1efa88625467d9ccf4ac51d89cdb (patch)
treecfcc3ed4038e68959b7f893a7e9d95c42ea2d362 /c/src/lib/libbsp/m68k/genmcf548x
parentbsps/m68k: Add and use linkcmds.base (diff)
downloadrtems-5df9bf6e8a8f1efa88625467d9ccf4ac51d89cdb.tar.bz2
bsp/genmcf548x: Add interrupt extension support
Diffstat (limited to 'c/src/lib/libbsp/m68k/genmcf548x')
-rw-r--r--c/src/lib/libbsp/m68k/genmcf548x/Makefile.am14
-rw-r--r--c/src/lib/libbsp/m68k/genmcf548x/include/irq.h79
-rw-r--r--c/src/lib/libbsp/m68k/genmcf548x/irq/irq.c235
-rw-r--r--c/src/lib/libbsp/m68k/genmcf548x/preinstall.am12
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 6a7cfd9faa..64e768210c 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 0000000000..23ff73d46f
--- /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@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 0000000000..2f2f43a7cc
--- /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@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 8c86e37d70..31ce6bc0ca 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