[rtems commit] bsp/imx: New BSP

Sebastian Huber sebh at rtems.org
Fri Aug 4 12:25:56 UTC 2017


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Aug  3 08:53:13 2017 +0200

bsp/imx: New BSP

Update #3090.

---

 c/src/lib/libbsp/arm/acinclude.m4                  |   2 +
 c/src/lib/libbsp/arm/imx/Makefile.am               | 125 ++++++++
 c/src/lib/libbsp/arm/imx/bsp_specs                 |  13 +
 c/src/lib/libbsp/arm/imx/configure.ac              |  64 ++++
 c/src/lib/libbsp/arm/imx/console/console-config.c  | 356 +++++++++++++++++++++
 .../arm/imx/include/arm/freescale/imx/imx_ccmvar.h |  64 ++++
 .../imx/include/arm/freescale/imx/imx_uartreg.h    | 174 ++++++++++
 c/src/lib/libbsp/arm/imx/include/bsp.h             |  50 +++
 c/src/lib/libbsp/arm/imx/include/irq.h             |  38 +++
 c/src/lib/libbsp/arm/imx/include/tm27.h            |  24 ++
 c/src/lib/libbsp/arm/imx/make/custom/imx7.cfg      |  16 +
 c/src/lib/libbsp/arm/imx/preinstall.am             | 153 +++++++++
 c/src/lib/libbsp/arm/imx/startup/bspreset.c        |  20 ++
 c/src/lib/libbsp/arm/imx/startup/bspsmp.c          |  41 +++
 c/src/lib/libbsp/arm/imx/startup/bspstart.c        |  60 ++++
 c/src/lib/libbsp/arm/imx/startup/bspstarthooks.c   |  58 ++++
 c/src/lib/libbsp/arm/imx/startup/ccm.c             |  33 ++
 c/src/lib/libbsp/arm/imx/startup/linkcmds.imx7     |  36 +++
 c/src/lib/libbsp/shared/include/fatal.h            |   6 +-
 19 files changed, 1332 insertions(+), 1 deletion(-)

diff --git a/c/src/lib/libbsp/arm/acinclude.m4 b/c/src/lib/libbsp/arm/acinclude.m4
index f5ca105..079d2b0 100644
--- a/c/src/lib/libbsp/arm/acinclude.m4
+++ b/c/src/lib/libbsp/arm/acinclude.m4
@@ -18,6 +18,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR],
     AC_CONFIG_SUBDIRS([gdbarmsim]);;
   gumstix )
     AC_CONFIG_SUBDIRS([gumstix]);;
+  imx )
+    AC_CONFIG_SUBDIRS([imx]);;
   lm3s69xx )
     AC_CONFIG_SUBDIRS([lm3s69xx]);;
   lpc176x )
diff --git a/c/src/lib/libbsp/arm/imx/Makefile.am b/c/src/lib/libbsp/arm/imx/Makefile.am
new file mode 100644
index 0000000..da0b12b
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/Makefile.am
@@ -0,0 +1,125 @@
+ACLOCAL_AMFLAGS = -I ../../../../aclocal
+
+include $(top_srcdir)/../../../../automake/compile.am
+
+include_bspdir = $(includedir)/bsp
+include_libcpudir = $(includedir)/libcpu
+include_arm_freescale_imxdir = $(includedir)/arm/freescale/imx
+
+dist_project_lib_DATA = bsp_specs
+
+###############################################################################
+#                  Header                                                     #
+###############################################################################
+
+include_HEADERS = include/bsp.h
+include_HEADERS += include/tm27.h
+
+nodist_include_HEADERS = ../../shared/include/coverhd.h \
+	include/bspopts.h
+
+nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h
+
+include_bsp_HEADERS =
+include_bsp_HEADERS += ../../shared/include/utility.h
+include_bsp_HEADERS += ../../shared/include/irq-generic.h
+include_bsp_HEADERS += ../../shared/include/irq-info.h
+include_bsp_HEADERS += ../../shared/include/stackalloc.h
+include_bsp_HEADERS += ../shared/include/start.h
+include_bsp_HEADERS += ../shared/include/arm-a9mpcore-regs.h
+include_bsp_HEADERS += ../shared/include/arm-a9mpcore-start.h
+include_bsp_HEADERS += ../shared/include/arm-cp15-start.h
+include_bsp_HEADERS += ../shared/include/arm-errata.h
+include_bsp_HEADERS += ../shared/include/arm-gic.h
+include_bsp_HEADERS += ../shared/include/arm-gic-irq.h
+include_bsp_HEADERS += ../shared/include/arm-gic-regs.h
+include_bsp_HEADERS += ../shared/include/arm-gic-tm27.h
+include_bsp_HEADERS += ../shared/include/arm-release-id.h
+include_bsp_HEADERS += include/irq.h
+
+include_libcpu_HEADERS = ../../../libcpu/arm/shared/include/arm-cp15.h
+
+include_arm_freescale_imx_HEADERS =
+include_arm_freescale_imx_HEADERS += include/arm/freescale/imx/imx_ccmvar.h
+include_arm_freescale_imx_HEADERS += include/arm/freescale/imx/imx_uartreg.h
+
+###############################################################################
+#                  Data                                                       #
+###############################################################################
+
+noinst_LIBRARIES = libbspstart.a
+
+libbspstart_a_SOURCES = ../shared/start/start.S
+
+project_lib_DATA = start.$(OBJEXT)
+
+project_lib_DATA += startup/linkcmds
+project_lib_DATA += startup/linkcmds.imx7
+
+###############################################################################
+#                  LibBSP                                                     #
+###############################################################################
+
+noinst_LIBRARIES += libbsp.a
+
+libbsp_a_SOURCES =
+libbsp_a_CPPFLAGS =
+libbsp_a_LIBADD =
+
+# Shared
+libbsp_a_SOURCES += ../../shared/bootcard.c
+libbsp_a_SOURCES += ../../shared/bspclean.c
+libbsp_a_SOURCES += ../../shared/bspgetworkarea.c
+libbsp_a_SOURCES += ../../shared/bsppredriverhook.c
+libbsp_a_SOURCES += ../../shared/cpucounterdiff.c
+libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c
+libbsp_a_SOURCES += ../../shared/sbrk.c
+libbsp_a_SOURCES += ../../shared/timerstub.c
+libbsp_a_SOURCES += ../../shared/src/bsp-fdt.c
+libbsp_a_SOURCES += ../../shared/src/stackalloc.c
+libbsp_a_SOURCES += ../shared/startup/bsp-start-memcpy.S
+libbsp_a_SOURCES += ../shared/arm-cp15-set-exception-handler.c
+libbsp_a_SOURCES += ../shared/arm-cp15-set-ttb-entries.c
+
+# Startup
+libbsp_a_SOURCES += startup/bspreset.c
+libbsp_a_SOURCES += startup/bspstart.c
+libbsp_a_SOURCES += startup/ccm.c
+if HAS_SMP
+libbsp_a_SOURCES += startup/bspsmp.c
+endif
+
+# IRQ
+libbsp_a_SOURCES += ../../shared/src/irq-default-handler.c
+libbsp_a_SOURCES += ../../shared/src/irq-generic.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 += ../shared/arm-gic-irq.c
+
+# Console
+libbsp_a_SOURCES += ../../shared/console-termios.c
+libbsp_a_SOURCES += console/console-config.c
+
+# Clock
+libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
+libbsp_a_SOURCES += ../shared/arm-generic-timer-clock-config.c
+
+# Cache
+libbsp_a_SOURCES += ../../../libcpu/shared/src/cache_manager.c
+libbsp_a_SOURCES += ../shared/include/arm-cache-l1.h
+libbsp_a_SOURCES += ../shared/armv467ar-basic-cache/cache_.h
+libbsp_a_CPPFLAGS += -I$(srcdir)/../shared/armv467ar-basic-cache
+
+# Start hooks
+libbsp_a_SOURCES += startup/bspstarthooks.c
+
+###############################################################################
+#                  Special Rules                                              #
+###############################################################################
+
+DISTCLEANFILES = include/bspopts.h
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/../../../../automake/local.am
diff --git a/c/src/lib/libbsp/arm/imx/bsp_specs b/c/src/lib/libbsp/arm/imx/bsp_specs
new file mode 100644
index 0000000..32c105f
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/bsp_specs
@@ -0,0 +1,13 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: start.o%s crti.o%s crtbegin.o%s -e _start}}
+
+*link:
+%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s }
diff --git a/c/src/lib/libbsp/arm/imx/configure.ac b/c/src/lib/libbsp/arm/imx/configure.ac
new file mode 100644
index 0000000..b494334
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/configure.ac
@@ -0,0 +1,64 @@
+AC_PREREQ([2.69])
+AC_INIT([rtems-c-src-lib-libbsp-arm-imx],[_RTEMS_VERSION],[https://devel.rtems.org/newticket])
+AC_CONFIG_SRCDIR([bsp_specs])
+RTEMS_TOP(../../../../../..)
+
+RTEMS_CANONICAL_TARGET_CPU
+AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.12.2])
+RTEMS_BSP_CONFIGURE
+
+RTEMS_PROG_CC_FOR_TARGET
+RTEMS_CANONICALIZE_TOOLS
+RTEMS_PROG_CCAS
+
+RTEMS_CHECK_NETWORKING
+AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
+
+RTEMS_BSPOPTS_SET([BSP_START_RESET_VECTOR],[*],[])
+RTEMS_BSPOPTS_HELP([BSP_START_RESET_VECTOR],[reset vector address for BSP start])
+
+RTEMS_BSPOPTS_SET([BSP_DATA_CACHE_ENABLED],[*qemu],[])
+RTEMS_BSPOPTS_SET([BSP_DATA_CACHE_ENABLED],[*],[1])
+RTEMS_BSPOPTS_HELP([BSP_DATA_CACHE_ENABLED],[enable data cache])
+
+RTEMS_BSPOPTS_SET([BSP_INSTRUCTION_CACHE_ENABLED],[*qemu],[])
+RTEMS_BSPOPTS_SET([BSP_INSTRUCTION_CACHE_ENABLED],[*],[1])
+RTEMS_BSPOPTS_HELP([BSP_INSTRUCTION_CACHE_ENABLED],[enable instruction cache])
+
+RTEMS_BSPOPTS_SET([BSP_START_COPY_FDT_FROM_U_BOOT],[*],[1])
+RTEMS_BSPOPTS_HELP([BSP_START_COPY_FDT_FROM_U_BOOT],[copy the U-Boot provided FDT to an internal storage])
+
+RTEMS_BSPOPTS_SET([BSP_FDT_BLOB_SIZE_MAX],[*],[262144])
+RTEMS_BSPOPTS_HELP([BSP_FDT_BLOB_SIZE_MAX],[maximum size of the FDT blob in bytes])
+
+RTEMS_BSPOPTS_SET([BSP_FDT_BLOB_READ_ONLY],[*],[1])
+RTEMS_BSPOPTS_HELP([BSP_FDT_BLOB_READ_ONLY],[place the FDT blob into the read-only data area])
+
+RTEMS_BSPOPTS_SET([BSP_FDT_BLOB_COPY_TO_READ_ONLY_LOAD_AREA],[*],[1])
+RTEMS_BSPOPTS_HELP([BSP_FDT_BLOB_COPY_TO_READ_ONLY_LOAD_AREA],[copy the FDT blob into the read-only load area via bsp_fdt_copy()])
+
+RTEMS_BSPOPTS_SET([CONSOLE_USE_INTERRUPTS],[*],[1])
+RTEMS_BSPOPTS_HELP([CONSOLE_USE_INTERRUPTS],[use interrupt driven mode for console devices (used by default)])
+
+RTEMS_BSPOPTS_SET([CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR],[*qemu*],[1])
+RTEMS_BSPOPTS_HELP([CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR],
+[If defined, then do the clock tick processing on the boot processor on behalf
+of all other processors.])
+
+RTEMS_BSPOPTS_SET([IMX_CCM_IPG_HZ],[*],[67500000])
+RTEMS_BSPOPTS_HELP([IMX_CCM_IPG_HZ],[IPG clock frequency in Hz])
+
+RTEMS_BSPOPTS_SET([IMX_CCM_UART_HZ],[*],[24000000])
+RTEMS_BSPOPTS_HELP([IMX_CCM_UART_HZ],[UART clock frequency in Hz])
+
+RTEMS_BSPOPTS_SET([IMX_CCM_AHB_HZ],[*],[135000000])
+RTEMS_BSPOPTS_HELP([IMX_CCM_AHB_HZ],[AHB clock frequency in Hz])
+
+RTEMS_CHECK_SMP
+AM_CONDITIONAL(HAS_SMP,[test "$rtems_cv_HAS_SMP" = "yes"])
+
+RTEMS_BSP_CLEANUP_OPTIONS(0, 1)
+RTEMS_BSP_LINKCMDS
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/c/src/lib/libbsp/arm/imx/console/console-config.c b/c/src/lib/libbsp/arm/imx/console/console-config.c
new file mode 100644
index 0000000..87dac03
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/console/console-config.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#include <rtems/bspIo.h>
+#include <rtems/console.h>
+#include <rtems/sysinit.h>
+#include <rtems/termiostypes.h>
+
+#include <bsp.h>
+#include <bsp/fdt.h>
+#include <bsp/irq.h>
+
+#include <arm/freescale/imx/imx_uartreg.h>
+
+#include <libfdt.h>
+
+typedef struct {
+  rtems_termios_device_context base;
+  volatile imx_uart *regs;
+#ifdef CONSOLE_USE_INTERRUPTS
+  rtems_vector_number irq;
+  bool transmitting;
+#endif
+} imx_uart_context;
+
+static imx_uart_context imx_uart_instances[7];
+
+static imx_uart_context *imx_uart_console;
+
+static volatile imx_uart *imx_uart_get_regs(rtems_termios_device_context *base)
+{
+  imx_uart_context *ctx;
+
+  ctx = (imx_uart_context *) base;
+  return ctx->regs;
+}
+
+static void imx_uart_write_polled(rtems_termios_device_context *base, char c)
+{
+  volatile imx_uart *regs;
+
+  regs = imx_uart_get_regs(base);
+
+  while ((regs->usr1 & IMX_UART_USR1_TRDY) == 0) {
+    /* Wait */
+  }
+
+  regs->utxd = IMX_UART_UTXD_TX_DATA(c);
+}
+
+static void imx_output_char(char c)
+{
+  imx_uart_context *ctx;
+
+  ctx = imx_uart_console;
+
+  if (c == '\n') {
+    imx_uart_write_polled(&ctx->base, '\r');
+  }
+
+  imx_uart_write_polled(&ctx->base, c);
+}
+
+static void imx_uart_init_context(
+  imx_uart_context *ctx,
+  const char *fdt,
+  const char *serial
+)
+{
+  int node;
+  int len;
+  const uint32_t *val;
+
+  rtems_termios_device_context_initialize(&ctx->base, "UART");
+
+  node = fdt_path_offset(fdt, serial);
+
+  val = fdt_getprop(fdt, node, "reg", &len);
+  if (val != NULL && len >= 4) {
+    ctx->regs = (imx_uart *) fdt32_to_cpu(val[0]);
+  }
+
+#ifdef CONSOLE_USE_INTERRUPTS
+  val = fdt_getprop(fdt, node, "interrupts", &len);
+  if (val != NULL && len >= 8) {
+    ctx->irq = bsp_fdt_map_intr(fdt32_to_cpu(val[1]));
+  }
+#endif
+}
+
+static void imx_uart_probe(void)
+{
+  const void *fdt;
+  int node;
+  int offset;
+  const char *console;
+  size_t i;
+
+  fdt = bsp_fdt_get();
+  node = fdt_path_offset(fdt, "/chosen");
+
+  console = fdt_getprop(fdt, node, "stdout-path", NULL);
+  if (console == NULL) {
+    console = "";
+  }
+
+  node = fdt_path_offset(fdt, "/aliases");
+  offset = fdt_first_property_offset(fdt, node);
+  i = 0;
+
+  while (offset >= 0 && i < RTEMS_ARRAY_SIZE(imx_uart_instances)) {
+    const struct fdt_property *prop;
+
+    prop = fdt_get_property_by_offset(fdt, offset, NULL);
+
+    if (prop != NULL) {
+      const char *name;
+
+      name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+      if (strstr(name, "serial") != NULL) {
+        imx_uart_context *ctx;
+        const char *serial;
+
+        ctx = &imx_uart_instances[i];
+        serial = prop->data;
+
+        if (strcmp(serial, console) == 0) {
+          imx_uart_console = ctx;
+        }
+
+        imx_uart_init_context(ctx, fdt, serial);
+        ++i;
+      }
+    }
+
+    offset = fdt_next_property_offset(fdt, offset);
+  }
+
+  BSP_output_char = imx_output_char;
+}
+
+static void imx_output_char_init(char c)
+{
+  imx_uart_probe();
+  imx_output_char(c);
+}
+
+BSP_output_char_function_type BSP_output_char = imx_output_char_init;
+
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
+
+#ifdef CONSOLE_USE_INTERRUPTS
+static void imx_uart_interrupt(void *arg)
+{
+  rtems_termios_tty *tty;
+  imx_uart_context *ctx;
+  volatile imx_uart *regs;
+  uint32_t usr2;
+
+  tty = arg;
+  ctx = rtems_termios_get_device_context(tty);
+  regs = ctx->regs;
+  usr2 = regs->usr2;
+
+  while ((usr2 & IMX_UART_USR2_RDR) != 0) {
+    char c;
+
+    c = IMX_UART_URXD_RX_DATA_GET(regs->urxd);
+    rtems_termios_enqueue_raw_characters(tty, &c, 1);
+    usr2 = regs->usr2;
+  }
+
+  if (ctx->transmitting && (regs->usr1 & IMX_UART_USR1_TRDY) != 0) {
+    rtems_termios_dequeue_characters(tty, 1);
+  }
+}
+#endif
+
+static bool imx_uart_set_attributes(
+  rtems_termios_device_context *base,
+  const struct termios *term
+)
+{
+  return true;
+}
+
+static bool imx_uart_first_open(
+  rtems_termios_tty *tty,
+  rtems_termios_device_context *base,
+  struct termios *term,
+  rtems_libio_open_close_args_t *args
+)
+{
+  imx_uart_context *ctx;
+  volatile imx_uart *regs;
+#ifdef CONSOLE_USE_INTERRUPTS
+  rtems_status_code sc;
+  uint32_t ufcr;
+#endif
+
+  ctx = (imx_uart_context *) base;
+  regs = imx_uart_get_regs(&ctx->base);
+
+  regs->ucr1 = IMX_UART_UCR1_UARTEN;
+  regs->ucr2 = IMX_UART_UCR2_IRTS | IMX_UART_UCR2_WS | IMX_UART_UCR2_RXEN
+    | IMX_UART_UCR2_TXEN | IMX_UART_UCR2_SRST;
+
+  rtems_termios_set_initial_baud(tty, 115200);
+  imx_uart_set_attributes(base, term);
+
+#ifdef CONSOLE_USE_INTERRUPTS
+  ufcr = regs->ufcr;
+  ufcr = IMX_UART_UFCR_RXTL_SET(ufcr, 16);
+  ufcr = IMX_UART_UFCR_TXTL_SET(ufcr, 16);
+  regs->ufcr = ufcr;
+  regs->ucr1 |= IMX_UART_UCR1_RRDYEN;
+  regs->ucr2 |= IMX_UART_UCR2_ATEN;
+  sc = rtems_interrupt_handler_install(
+    ctx->irq,
+    "UART",
+    RTEMS_INTERRUPT_SHARED,
+    imx_uart_interrupt,
+    tty
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    return false;
+  }
+#endif
+
+  return true;
+}
+
+static void imx_uart_last_close(
+  rtems_termios_tty *tty,
+  rtems_termios_device_context *base,
+  rtems_libio_open_close_args_t *args
+)
+{
+#ifdef CONSOLE_USE_INTERRUPTS
+  imx_uart_context *ctx;
+
+  ctx = (imx_uart_context *) base;
+  rtems_interrupt_handler_remove(ctx->irq, imx_uart_interrupt, tty);
+#endif
+}
+
+static void imx_uart_write(
+  rtems_termios_device_context *base,
+  const char *buf,
+  size_t len
+)
+{
+#ifdef CONSOLE_USE_INTERRUPTS
+  imx_uart_context *ctx;
+  volatile imx_uart *regs;
+  uint32_t ucr1;
+
+  ctx = (imx_uart_context *) base;
+  regs = imx_uart_get_regs(&ctx->base);
+  ucr1 = regs->ucr1;
+
+  if (len > 0) {
+    ctx->transmitting = true;
+    regs->utxd = IMX_UART_UTXD_TX_DATA(buf[0]);
+    ucr1 |= IMX_UART_UCR1_TRDYEN;
+  } else {
+    ctx->transmitting = false;
+    ucr1 &= ~IMX_UART_UCR1_TRDYEN;
+  }
+
+  regs->ucr1 = ucr1;
+#else
+  size_t i;
+
+  for (i = 0; i < len; ++i) {
+    imx_uart_write_polled(base, buf[i]);
+  }
+#endif
+}
+
+#ifndef CONSOLE_USE_INTERRUPTS
+static int imx_uart_read(rtems_termios_device_context *base)
+{
+  volatile imx_uart *regs;
+
+  regs = imx_uart_get_regs(base);
+
+  if ((regs->usr2 & IMX_UART_USR2_RDR) != 0) {
+    return IMX_UART_URXD_RX_DATA_GET(regs->urxd);
+  } else {
+    return -1;
+  }
+}
+#endif
+
+static const rtems_termios_device_handler imx_uart_handler = {
+  .first_open = imx_uart_first_open,
+  .last_close = imx_uart_last_close,
+  .write = imx_uart_write,
+  .set_attributes = imx_uart_set_attributes,
+#ifdef CONSOLE_USE_INTERRUPTS
+  .mode = TERMIOS_IRQ_DRIVEN
+#else
+  .poll_read = imx_uart_read,
+  .mode = TERMIOS_POLLED
+#endif
+};
+
+rtems_status_code console_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *arg
+)
+{
+  char path[] = "/dev/ttyS?";
+  size_t i;
+
+  rtems_termios_initialize();
+
+  for (i = 0; i < RTEMS_ARRAY_SIZE(imx_uart_instances); ++i) {
+    imx_uart_context *ctx;
+
+    ctx = &imx_uart_instances[i];
+    path[sizeof(path) - 2] = (char) ('0' + i);
+
+    rtems_termios_device_install(
+      path,
+      &imx_uart_handler,
+      NULL,
+      &ctx->base
+    );
+
+    if (ctx == imx_uart_console) {
+      link(path, CONSOLE_DEVICE_NAME);
+    }
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
+
+RTEMS_SYSINIT_ITEM(
+  imx_uart_probe,
+  RTEMS_SYSINIT_BSP_START,
+  RTEMS_SYSINIT_ORDER_LAST
+);
diff --git a/c/src/lib/libbsp/arm/imx/include/arm/freescale/imx/imx_ccmvar.h b/c/src/lib/libbsp/arm/imx/include/arm/freescale/imx/imx_ccmvar.h
new file mode 100644
index 0000000..5633de6
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/include/arm/freescale/imx/imx_ccmvar.h
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2014 Ian Lepore <ian at freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/sys/arm/freescale/imx/imx_ccmvar.h 292565 2015-12-21 20:17:24Z gonzo $
+ */
+
+#ifndef	IMX_CCMVAR_H
+#define	IMX_CCMVAR_H
+
+/*
+ * We need a clock management system that works across unrelated SoCs and
+ * devices.  For now, to keep imx development moving, define some barebones
+ * functionality that can be shared within the imx family by having each SoC
+ * implement functions with a common name.
+ *
+ * The usb enable functions are best-effort.  They turn on the usb otg, host,
+ * and phy clocks in a SoC-specific manner, but it may take a lot more than that
+ * to make usb work on a given board.  In particular, it can require specific
+ * pinmux setup of gpio pins connected to external phy parts, voltage regulators
+ * and overcurrent detectors, and so on.  On such boards, u-boot or other early
+ * board setup code has to handle those things.
+ */
+
+uint32_t imx_ccm_ipg_hz(void);
+uint32_t imx_ccm_perclk_hz(void);
+uint32_t imx_ccm_sdhci_hz(void);
+uint32_t imx_ccm_uart_hz(void);
+uint32_t imx_ccm_ahb_hz(void);
+
+#ifndef __rtems__
+void imx_ccm_usb_enable(device_t _usbdev);
+void imx_ccm_usbphy_enable(device_t _phydev);
+void imx_ccm_ssi_configure(device_t _ssidev);
+void imx_ccm_hdmi_enable(void);
+void imx_ccm_ipu_enable(int ipu);
+
+/* Routines to get and set the arm clock root divisor register. */
+uint32_t imx_ccm_get_cacrr(void);
+void     imx_ccm_set_cacrr(uint32_t _divisor);
+#endif /* __rtems__ */
+
+#endif
diff --git a/c/src/lib/libbsp/arm/imx/include/arm/freescale/imx/imx_uartreg.h b/c/src/lib/libbsp/arm/imx/include/arm/freescale/imx/imx_uartreg.h
new file mode 100644
index 0000000..3586260
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/include/arm/freescale/imx/imx_uartreg.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#ifndef IMX_UARTREG_H
+#define IMX_UARTREG_H
+
+#include <bsp/utility.h>
+
+typedef struct {
+	uint32_t urxd;
+#define IMX_UART_URXD_CHARRDY BSP_BIT32(15)
+#define IMX_UART_URXD_ERR BSP_BIT32(14)
+#define IMX_UART_URXD_OVRRUN BSP_BIT32(13)
+#define IMX_UART_URXD_FRMERR BSP_BIT32(12)
+#define IMX_UART_URXD_BRK BSP_BIT32(11)
+#define IMX_UART_URXD_PRERR BSP_BIT32(10)
+#define IMX_UART_URXD_RX_DATA(val) BSP_FLD32(val, 0, 7)
+#define IMX_UART_URXD_RX_DATA_GET(reg) BSP_FLD32GET(reg, 0, 7)
+#define IMX_UART_URXD_RX_DATA_SET(reg, val) BSP_FLD32SET(reg, val, 0, 7)
+	uint32_t reserved_04[15];
+	uint32_t utxd;
+#define IMX_UART_UTXD_TX_DATA(val) BSP_FLD32(val, 0, 7)
+#define IMX_UART_UTXD_TX_DATA_GET(reg) BSP_FLD32GET(reg, 0, 7)
+#define IMX_UART_UTXD_TX_DATA_SET(reg, val) BSP_FLD32SET(reg, val, 0, 7)
+	uint32_t reserved_44[15];
+	uint32_t ucr1;
+#define IMX_UART_UCR1_ADEN BSP_BIT32(15)
+#define IMX_UART_UCR1_ADBR BSP_BIT32(14)
+#define IMX_UART_UCR1_TRDYEN BSP_BIT32(13)
+#define IMX_UART_UCR1_IDEN BSP_BIT32(12)
+#define IMX_UART_UCR1_ICD(val) BSP_FLD32(val, 10, 11)
+#define IMX_UART_UCR1_ICD_GET(reg) BSP_FLD32GET(reg, 10, 11)
+#define IMX_UART_UCR1_ICD_SET(reg, val) BSP_FLD32SET(reg, val, 10, 11)
+#define IMX_UART_UCR1_RRDYEN BSP_BIT32(9)
+#define IMX_UART_UCR1_RXDMAEN BSP_BIT32(8)
+#define IMX_UART_UCR1_IREN BSP_BIT32(7)
+#define IMX_UART_UCR1_TXMPTYEN BSP_BIT32(6)
+#define IMX_UART_UCR1_RTSDEN BSP_BIT32(5)
+#define IMX_UART_UCR1_SNDBRK BSP_BIT32(4)
+#define IMX_UART_UCR1_TXDMAEN BSP_BIT32(3)
+#define IMX_UART_UCR1_ATDMAEN BSP_BIT32(2)
+#define IMX_UART_UCR1_DOZE BSP_BIT32(1)
+#define IMX_UART_UCR1_UARTEN BSP_BIT32(0)
+	uint32_t ucr2;
+#define IMX_UART_UCR2_ESCI BSP_BIT32(15)
+#define IMX_UART_UCR2_IRTS BSP_BIT32(14)
+#define IMX_UART_UCR2_CTSC BSP_BIT32(13)
+#define IMX_UART_UCR2_CTS BSP_BIT32(12)
+#define IMX_UART_UCR2_ESCEN BSP_BIT32(11)
+#define IMX_UART_UCR2_RTEC(val) BSP_FLD32(val, 9, 10)
+#define IMX_UART_UCR2_RTEC_GET(reg) BSP_FLD32GET(reg, 9, 10)
+#define IMX_UART_UCR2_RTEC_SET(reg, val) BSP_FLD32SET(reg, val, 9, 10)
+#define IMX_UART_UCR2_PREN BSP_BIT32(8)
+#define IMX_UART_UCR2_PROE BSP_BIT32(7)
+#define IMX_UART_UCR2_STPB BSP_BIT32(6)
+#define IMX_UART_UCR2_WS BSP_BIT32(5)
+#define IMX_UART_UCR2_RTSEN BSP_BIT32(4)
+#define IMX_UART_UCR2_ATEN BSP_BIT32(3)
+#define IMX_UART_UCR2_TXEN BSP_BIT32(2)
+#define IMX_UART_UCR2_RXEN BSP_BIT32(1)
+#define IMX_UART_UCR2_SRST BSP_BIT32(0)
+	uint32_t ucr3;
+#define IMX_UART_UCR3_DPEC(val) BSP_FLD32(val, 14, 15)
+#define IMX_UART_UCR3_DPEC_GET(reg) BSP_FLD32GET(reg, 14, 15)
+#define IMX_UART_UCR3_DPEC_SET(reg, val) BSP_FLD32SET(reg, val, 14, 15)
+#define IMX_UART_UCR3_DTREN BSP_BIT32(13)
+#define IMX_UART_UCR3_PARERREN BSP_BIT32(12)
+#define IMX_UART_UCR3_FRAERREN BSP_BIT32(11)
+#define IMX_UART_UCR3_DSR BSP_BIT32(10)
+#define IMX_UART_UCR3_DCD BSP_BIT32(9)
+#define IMX_UART_UCR3_RI BSP_BIT32(8)
+#define IMX_UART_UCR3_ADNIMP BSP_BIT32(7)
+#define IMX_UART_UCR3_RXDSEN BSP_BIT32(6)
+#define IMX_UART_UCR3_AIRINTEN BSP_BIT32(5)
+#define IMX_UART_UCR3_AWAKEN BSP_BIT32(4)
+#define IMX_UART_UCR3_DTRDEN BSP_BIT32(3)
+#define IMX_UART_UCR3_RXDMUXSEL BSP_BIT32(2)
+#define IMX_UART_UCR3_INVT BSP_BIT32(1)
+#define IMX_UART_UCR3_ACIEN BSP_BIT32(0)
+	uint32_t ucr4;
+#define IMX_UART_UCR4_CTSTL(val) BSP_FLD32(val, 10, 15)
+#define IMX_UART_UCR4_CTSTL_GET(reg) BSP_FLD32GET(reg, 10, 15)
+#define IMX_UART_UCR4_CTSTL_SET(reg, val) BSP_FLD32SET(reg, val, 10, 15)
+#define IMX_UART_UCR4_INVR BSP_BIT32(9)
+#define IMX_UART_UCR4_ENIRI BSP_BIT32(8)
+#define IMX_UART_UCR4_WKEN BSP_BIT32(7)
+#define IMX_UART_UCR4_IDDMAEN BSP_BIT32(6)
+#define IMX_UART_UCR4_IRSC BSP_BIT32(5)
+#define IMX_UART_UCR4_LPBYP BSP_BIT32(4)
+#define IMX_UART_UCR4_TCEN BSP_BIT32(3)
+#define IMX_UART_UCR4_BKEN BSP_BIT32(2)
+#define IMX_UART_UCR4_OREN BSP_BIT32(1)
+#define IMX_UART_UCR4_DREN BSP_BIT32(0)
+	uint32_t ufcr;
+#define IMX_UART_UFCR_TXTL(val) BSP_FLD32(val, 10, 15)
+#define IMX_UART_UFCR_TXTL_GET(reg) BSP_FLD32GET(reg, 10, 15)
+#define IMX_UART_UFCR_TXTL_SET(reg, val) BSP_FLD32SET(reg, val, 10, 15)
+#define IMX_UART_UFCR_RFDIV(val) BSP_FLD32(val, 7, 9)
+#define IMX_UART_UFCR_RFDIV_GET(reg) BSP_FLD32GET(reg, 7, 9)
+#define IMX_UART_UFCR_RFDIV_SET(reg, val) BSP_FLD32SET(reg, val, 7, 9)
+#define IMX_UART_UFCR_DCEDTE BSP_BIT32(6)
+#define IMX_UART_UFCR_RXTL(val) BSP_FLD32(val, 0, 5)
+#define IMX_UART_UFCR_RXTL_GET(reg) BSP_FLD32GET(reg, 0, 5)
+#define IMX_UART_UFCR_RXTL_SET(reg, val) BSP_FLD32SET(reg, val, 0, 5)
+	uint32_t usr1;
+#define IMX_UART_USR1_PARITYERR BSP_BIT32(15)
+#define IMX_UART_USR1_RTSS BSP_BIT32(14)
+#define IMX_UART_USR1_TRDY BSP_BIT32(13)
+#define IMX_UART_USR1_RTSD BSP_BIT32(12)
+#define IMX_UART_USR1_ESCF BSP_BIT32(11)
+#define IMX_UART_USR1_FRAMERR BSP_BIT32(10)
+#define IMX_UART_USR1_RRDY BSP_BIT32(9)
+#define IMX_UART_USR1_AGTIM BSP_BIT32(8)
+#define IMX_UART_USR1_DTRD BSP_BIT32(7)
+#define IMX_UART_USR1_RXDS BSP_BIT32(6)
+#define IMX_UART_USR1_AIRINT BSP_BIT32(5)
+#define IMX_UART_USR1_AWAKE BSP_BIT32(4)
+#define IMX_UART_USR1_SAD BSP_BIT32(3)
+	uint32_t usr2;
+#define IMX_UART_USR2_ADET BSP_BIT32(15)
+#define IMX_UART_USR2_TXFE BSP_BIT32(14)
+#define IMX_UART_USR2_DTRF BSP_BIT32(13)
+#define IMX_UART_USR2_IDLE BSP_BIT32(12)
+#define IMX_UART_USR2_ACST BSP_BIT32(11)
+#define IMX_UART_USR2_RIDELT BSP_BIT32(10)
+#define IMX_UART_USR2_RIIN BSP_BIT32(9)
+#define IMX_UART_USR2_IRINT BSP_BIT32(8)
+#define IMX_UART_USR2_WAKE BSP_BIT32(7)
+#define IMX_UART_USR2_DCDDELT BSP_BIT32(6)
+#define IMX_UART_USR2_DCDIN BSP_BIT32(5)
+#define IMX_UART_USR2_RTSF BSP_BIT32(4)
+#define IMX_UART_USR2_TXDC BSP_BIT32(3)
+#define IMX_UART_USR2_BRCD BSP_BIT32(2)
+#define IMX_UART_USR2_ORE BSP_BIT32(1)
+#define IMX_UART_USR2_RDR BSP_BIT32(0)
+	uint32_t uesc;
+	uint32_t utim;
+	uint32_t ubir;
+	uint32_t ubmr;
+	uint32_t ubrc;
+	uint32_t onems;
+	uint32_t uts;
+#define IMX_UART_UTS_FRCPERR BSP_BIT32(13)
+#define IMX_UART_UTS_LOOP BSP_BIT32(12)
+#define IMX_UART_UTS_DBGEN BSP_BIT32(11)
+#define IMX_UART_UTS_LOOPIR BSP_BIT32(10)
+#define IMX_UART_UTS_RXDBG BSP_BIT32(9)
+#define IMX_UART_UTS_TXEMPTY BSP_BIT32(6)
+#define IMX_UART_UTS_RXEMPTY BSP_BIT32(5)
+#define IMX_UART_UTS_TXFULL BSP_BIT32(4)
+#define IMX_UART_UTS_RXFULL BSP_BIT32(3)
+#define IMX_UART_UTS_SOFTRST BSP_BIT32(0)
+	uint32_t umcr;
+#define IMX_UART_UMCR_SLADDR(val) BSP_FLD32(val, 8, 15)
+#define IMX_UART_UMCR_SLADDR_GET(reg) BSP_FLD32GET(reg, 8, 15)
+#define IMX_UART_UMCR_SLADDR_SET(reg, val) BSP_FLD32SET(reg, val, 8, 15)
+#define IMX_UART_UMCR_SADEN BSP_BIT32(3)
+#define IMX_UART_UMCR_TXB8 BSP_BIT32(2)
+#define IMX_UART_UMCR_SLAM BSP_BIT32(1)
+#define IMX_UART_UMCR_MDEN BSP_BIT32(0)
+} imx_uart;
+
+#endif /* IMX_UARTREG_H */
diff --git a/c/src/lib/libbsp/arm/imx/include/bsp.h b/c/src/lib/libbsp/arm/imx/include/bsp.h
new file mode 100644
index 0000000..d0d9dc7
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/include/bsp.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_IMX_BSP_H
+#define LIBBSP_ARM_IMX_BSP_H
+
+#include <bspopts.h>
+
+#define BSP_FEATURE_IRQ_EXTENSION
+
+#define BSP_FDT_IS_SUPPORTED
+
+#ifndef ASM
+
+#include <rtems.h>
+
+#include <bsp/default-initial-extension.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define BSP_ARM_GIC_DIST_BASE 0x31001000
+
+#define BSP_ARM_GIC_CPUIF_BASE 0x31002000
+
+#define BSP_ARM_A9MPCORE_GT_BASE 0
+
+#define BSP_ARM_A9MPCORE_SCU_BASE 0
+
+void arm_generic_timer_get_config(uint32_t *frequency, uint32_t *irq);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ASM */
+
+#endif /* LIBBSP_ARM_IMX_BSP_H */
diff --git a/c/src/lib/libbsp/arm/imx/include/irq.h b/c/src/lib/libbsp/arm/imx/include/irq.h
new file mode 100644
index 0000000..73d2e69
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/include/irq.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_IMX_IRQ_H
+#define LIBBSP_ARM_IMX_IRQ_H
+
+#ifndef ASM
+
+#include <rtems/irq.h>
+#include <rtems/irq-extension.h>
+
+#include <bsp/arm-gic-irq.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define BSP_INTERRUPT_VECTOR_MIN 0
+#define BSP_INTERRUPT_VECTOR_MAX 159
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ASM */
+
+#endif /* LIBBSP_ARM_IMX_IRQ_H */
diff --git a/c/src/lib/libbsp/arm/imx/include/tm27.h b/c/src/lib/libbsp/arm/imx/include/tm27.h
new file mode 100644
index 0000000..c17c010
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/include/tm27.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_TMTEST27
+#error "This is an RTEMS internal file you must not include directly."
+#endif
+
+#ifndef __tm27_h
+#define __tm27_h
+
+#include <bsp/arm-gic-tm27.h>
+
+#endif /* __tm27_h */
diff --git a/c/src/lib/libbsp/arm/imx/make/custom/imx7.cfg b/c/src/lib/libbsp/arm/imx/make/custom/imx7.cfg
new file mode 100644
index 0000000..a93919e
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/make/custom/imx7.cfg
@@ -0,0 +1,16 @@
+include $(RTEMS_ROOT)/make/custom/default.cfg
+
+RTEMS_CPU = arm
+
+CPU_CFLAGS = -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -mtune=cortex-a7
+
+LDFLAGS = -Wl,--gc-sections
+
+CFLAGS_OPTIMIZE_V ?= -O2 -g -ffunction-sections -fdata-sections
+
+# define bsp-post-link
+#   $(OBJCOPY) -O binary '$@' '$(basename $@).bin'
+#   gzip -f -9 '$(basename $@).bin'
+#   mkimage -A arm -O linux -T kernel -a 0x80004000 -e 0x80004000 -name '$(notdir $@)' -d '$(basename $@).bin.gz' '$(basename $@).img'
+#   $(default-bsp-post-link)
+# endef
diff --git a/c/src/lib/libbsp/arm/imx/preinstall.am b/c/src/lib/libbsp/arm/imx/preinstall.am
new file mode 100644
index 0000000..1f08be6
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/preinstall.am
@@ -0,0 +1,153 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+	$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES += $(PREINSTALL_DIRS)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES = $(PREINSTALL_FILES)
+
+all-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES += $(TMPINSTALL_FILES)
+
+$(PROJECT_LIB)/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_LIB)
+	@: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)
+	@: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+$(PROJECT_INCLUDE)/bsp/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
+	@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+
+$(PROJECT_INCLUDE)/libcpu/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)/libcpu
+	@: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+
+$(PROJECT_INCLUDE)/arm/freescale/imx/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)/arm/freescale/imx
+	@: > $(PROJECT_INCLUDE)/arm/freescale/imx/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/arm/freescale/imx/$(dirstamp)
+
+$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
+PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
+
+$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
+
+$(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
+
+$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
+
+$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
+
+$(PROJECT_INCLUDE)/bsp/bootcard.h: ../../shared/include/bootcard.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bootcard.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h
+
+$(PROJECT_INCLUDE)/bsp/utility.h: ../../shared/include/utility.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/utility.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/utility.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/stackalloc.h: ../../shared/include/stackalloc.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/stackalloc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/stackalloc.h
+
+$(PROJECT_INCLUDE)/bsp/start.h: ../shared/include/start.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/start.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/start.h
+
+$(PROJECT_INCLUDE)/bsp/arm-a9mpcore-regs.h: ../shared/include/arm-a9mpcore-regs.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-a9mpcore-regs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-a9mpcore-regs.h
+
+$(PROJECT_INCLUDE)/bsp/arm-a9mpcore-start.h: ../shared/include/arm-a9mpcore-start.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-a9mpcore-start.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-a9mpcore-start.h
+
+$(PROJECT_INCLUDE)/bsp/arm-cp15-start.h: ../shared/include/arm-cp15-start.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-cp15-start.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-cp15-start.h
+
+$(PROJECT_INCLUDE)/bsp/arm-errata.h: ../shared/include/arm-errata.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-errata.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-errata.h
+
+$(PROJECT_INCLUDE)/bsp/arm-gic.h: ../shared/include/arm-gic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-gic.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-gic.h
+
+$(PROJECT_INCLUDE)/bsp/arm-gic-irq.h: ../shared/include/arm-gic-irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-gic-irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-gic-irq.h
+
+$(PROJECT_INCLUDE)/bsp/arm-gic-regs.h: ../shared/include/arm-gic-regs.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-gic-regs.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-gic-regs.h
+
+$(PROJECT_INCLUDE)/bsp/arm-gic-tm27.h: ../shared/include/arm-gic-tm27.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-gic-tm27.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-gic-tm27.h
+
+$(PROJECT_INCLUDE)/bsp/arm-release-id.h: ../shared/include/arm-release-id.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-release-id.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-release-id.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)/libcpu/arm-cp15.h: ../../../libcpu/arm/shared/include/arm-cp15.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
+
+$(PROJECT_INCLUDE)/arm/freescale/imx/imx_ccmvar.h: include/arm/freescale/imx/imx_ccmvar.h $(PROJECT_INCLUDE)/arm/freescale/imx/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/arm/freescale/imx/imx_ccmvar.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/arm/freescale/imx/imx_ccmvar.h
+
+$(PROJECT_INCLUDE)/arm/freescale/imx/imx_uartreg.h: include/arm/freescale/imx/imx_uartreg.h $(PROJECT_INCLUDE)/arm/freescale/imx/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/arm/freescale/imx/imx_uartreg.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/arm/freescale/imx/imx_uartreg.h
+
+$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)
+TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT)
+
+$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
+TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds
+
+$(PROJECT_LIB)/linkcmds.imx7: startup/linkcmds.imx7 $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.imx7
+TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds.imx7
+
diff --git a/c/src/lib/libbsp/arm/imx/startup/bspreset.c b/c/src/lib/libbsp/arm/imx/startup/bspreset.c
new file mode 100644
index 0000000..5d0ffe7
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/startup/bspreset.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#include <bsp/bootcard.h>
+
+void bsp_reset(void)
+{
+  /* TODO */
+}
diff --git a/c/src/lib/libbsp/arm/imx/startup/bspsmp.c b/c/src/lib/libbsp/arm/imx/startup/bspsmp.c
new file mode 100644
index 0000000..ac9561d
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/startup/bspsmp.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#include <rtems/score/smpimpl.h>
+
+uint32_t _CPU_SMP_Initialize(void)
+{
+  return 1;
+}
+
+bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+{
+  (void) cpu_index;
+
+  /* Nothing to do */
+
+  return true;
+}
+
+void _CPU_SMP_Finalize_initialization(uint32_t cpu_count)
+{
+}
+
+void _CPU_SMP_Prepare_start_multitasking(void)
+{
+}
+
+void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
+{
+}
diff --git a/c/src/lib/libbsp/arm/imx/startup/bspstart.c b/c/src/lib/libbsp/arm/imx/startup/bspstart.c
new file mode 100644
index 0000000..eb2ba29
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/startup/bspstart.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/fatal.h>
+#include <bsp/fdt.h>
+#include <bsp/irq-generic.h>
+
+#include <libfdt.h>
+
+uint32_t bsp_fdt_map_intr(uint32_t intr)
+{
+  return intr + 32;
+}
+
+void arm_generic_timer_get_config(
+  uint32_t *frequency,
+  uint32_t *irq
+)
+{
+  const void *fdt;
+  int node;
+  int len;
+  const uint32_t *val;
+
+  fdt = bsp_fdt_get();
+  node = fdt_path_offset(fdt, "/timer");
+
+  val = fdt_getprop(fdt, node, "clock-frequency", &len);
+  if (val != NULL && len >= 4) {
+    *frequency = fdt32_to_cpu(val[0]);
+  } else {
+    bsp_fatal(IMX_FATAL_GENERIC_TIMER_FREQUENCY);
+  }
+
+  val = fdt_getprop(fdt, node, "interrupts", &len);
+  if (val != NULL && len >= 8) {
+    /* FIXME: Figure out how Linux gets a proper IRQ number */
+    *irq = 16 + fdt32_to_cpu(val[1]);
+  } else {
+    bsp_fatal(IMX_FATAL_GENERIC_TIMER_IRQ);
+  }
+}
+
+void bsp_start(void)
+{
+  bsp_interrupt_initialize();
+}
diff --git a/c/src/lib/libbsp/arm/imx/startup/bspstarthooks.c b/c/src/lib/libbsp/arm/imx/startup/bspstarthooks.c
new file mode 100644
index 0000000..2bbbae0
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/startup/bspstarthooks.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/arm-a9mpcore-start.h>
+
+BSP_START_DATA_SECTION static const arm_cp15_start_section_config
+imx_mmu_config_table[] = {
+  ARMV7_CP15_START_DEFAULT_SECTIONS,
+  {
+    .begin = 0x07000000U,
+    .end = 0x70000000U,
+    .flags = ARMV7_MMU_DEVICE
+  }
+};
+
+BSP_START_TEXT_SECTION static void setup_mmu_and_cache(void)
+{
+  uint32_t ctrl = arm_cp15_start_setup_mmu_and_cache(
+    ARM_CP15_CTRL_A,
+    ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z
+  );
+
+  arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
+    ctrl,
+    (uint32_t *) bsp_translation_table_base,
+    ARM_MMU_DEFAULT_CLIENT_DOMAIN,
+    &imx_mmu_config_table[0],
+    RTEMS_ARRAY_SIZE(imx_mmu_config_table)
+  );
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+{
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+{
+  arm_a9mpcore_start_set_vector_base();
+  bsp_start_copy_sections();
+  setup_mmu_and_cache();
+  bsp_start_clear_bss();
+}
diff --git a/c/src/lib/libbsp/arm/imx/startup/ccm.c b/c/src/lib/libbsp/arm/imx/startup/ccm.c
new file mode 100644
index 0000000..bbb72db
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/startup/ccm.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info 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.org/license/LICENSE.
+ */
+
+#include <stdint.h>
+#include <bspopts.h>
+
+#include <arm/freescale/imx/imx_ccmvar.h>
+
+uint32_t imx_ccm_ipg_hz(void)
+{
+  return IMX_CCM_IPG_HZ;
+}
+
+uint32_t imx_ccm_uart_hz(void)
+{
+  return IMX_CCM_UART_HZ;
+}
+
+uint32_t imx_ccm_ahb_hz(void)
+{
+  return IMX_CCM_AHB_HZ;
+}
diff --git a/c/src/lib/libbsp/arm/imx/startup/linkcmds.imx7 b/c/src/lib/libbsp/arm/imx/startup/linkcmds.imx7
new file mode 100644
index 0000000..6cb9fc3
--- /dev/null
+++ b/c/src/lib/libbsp/arm/imx/startup/linkcmds.imx7
@@ -0,0 +1,36 @@
+MEMORY {
+	RAM_MMU : ORIGIN = 0x80000000, LENGTH = 16k
+	RAM : ORIGIN = 0x80004000, LENGTH = 512M - 16k
+}
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_VECTOR", RAM);
+REGION_ALIAS ("REGION_TEXT", RAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_RODATA", RAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", RAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM);
+
+bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 2;
+
+bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
+bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
+
+bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1M;
+
+bsp_vector_table_in_start_section = 1;
+
+bsp_translation_table_base = ORIGIN (RAM_MMU);
+bsp_translation_table_end = ORIGIN (RAM_MMU) + LENGTH (RAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/c/src/lib/libbsp/shared/include/fatal.h b/c/src/lib/libbsp/shared/include/fatal.h
index 1bdfde6..cc303fa 100644
--- a/c/src/lib/libbsp/shared/include/fatal.h
+++ b/c/src/lib/libbsp/shared/include/fatal.h
@@ -134,7 +134,11 @@ typedef enum {
   ATSAM_FATAL_PIO_IRQ_C,
   ATSAM_FATAL_PIO_IRQ_D,
   ATSAM_FATAL_PIO_IRQ_E,
-  ATSAM_FATAL_PIO_CONFIGURE_IT
+  ATSAM_FATAL_PIO_CONFIGURE_IT,
+
+  /* i.MX fatal codes */
+  IMX_FATAL_GENERIC_TIMER_FREQUENCY = BSP_FATAL_CODE_BLOCK(12),
+  IMX_FATAL_GENERIC_TIMER_IRQ
 } bsp_fatal_code;
 
 RTEMS_NO_RETURN static inline void



More information about the vc mailing list