[PATCH 1/6] Add Jetson-TK1 board support

andreas.koelbl at st.oth-regensburg.de andreas.koelbl at st.oth-regensburg.de
Mon Jul 31 22:27:18 UTC 2017


From: Andreas Kölbl <andreas.koelbl at st.oth-regensburg.de>

Peripheral device drivers:
  - RTEMS Timercounter API using the ARM Generic Timer.
  - Benchmark RTEMS with the Nvidia TMRUS
  Console:
    - 8250 UART based driver
    - Devices UART-A and UART-D (Default: UART-D, UART-A is turned off)
    - Interrupt driven or polled (Default: Polled)
---
Instructions to run RTEMS using this BSP in the Jailhouse hypervisor
will be provided later.

 c/src/lib/libbsp/arm/acinclude.m4                  |   2 +
 c/src/lib/libbsp/arm/jetson-tk1/Makefile.am        | 134 ++++++++++
 c/src/lib/libbsp/arm/jetson-tk1/README             |  21 ++
 c/src/lib/libbsp/arm/jetson-tk1/TODO               |   3 +
 c/src/lib/libbsp/arm/jetson-tk1/bsp_specs          |  13 +
 c/src/lib/libbsp/arm/jetson-tk1/clock/car.c        | 117 +++++++++
 c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c   | 138 ++++++++++
 c/src/lib/libbsp/arm/jetson-tk1/configure.ac       |  39 +++
 c/src/lib/libbsp/arm/jetson-tk1/console/console.c  | 291 +++++++++++++++++++++
 .../libbsp/arm/jetson-tk1/console/debug-console.c  |  50 ++++
 c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h      |  25 ++
 c/src/lib/libbsp/arm/jetson-tk1/include/car.h      |  30 +++
 c/src/lib/libbsp/arm/jetson-tk1/include/console.h  |  32 +++
 c/src/lib/libbsp/arm/jetson-tk1/include/irq.h      |  25 ++
 c/src/lib/libbsp/arm/jetson-tk1/include/memory.h   |  31 +++
 c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h      |  42 +++
 .../arm/jetson-tk1/make/custom/jetson-tk1.cfg      |  16 ++
 c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c       |  64 +++++
 c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c |  19 ++
 c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c |  16 ++
 .../libbsp/arm/jetson-tk1/startup/bspstarthooks.c  |  59 +++++
 .../lib/libbsp/arm/jetson-tk1/startup/linkcmds.in  |  39 +++
 .../arm/jetson-tk1/startup/mm_config_table.c       |  56 ++++
 23 files changed, 1262 insertions(+)
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/Makefile.am
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/README
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/TODO
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/bsp_specs
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/clock/car.c
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/configure.ac
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/console/console.c
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/console/debug-console.c
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/car.h
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/console.h
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/irq.h
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/memory.h
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/make/custom/jetson-tk1.cfg
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/bspstarthooks.c
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/linkcmds.in
 create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c

diff --git a/c/src/lib/libbsp/arm/acinclude.m4 b/c/src/lib/libbsp/arm/acinclude.m4
index f5ca105eca..26f743a95e 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]);;
+  jetson-tk1 )
+    AC_CONFIG_SUBDIRS([jetson-tk1]);;
   lm3s69xx )
     AC_CONFIG_SUBDIRS([lm3s69xx]);;
   lpc176x )
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am b/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am
new file mode 100644
index 0000000000..4316e67957
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am
@@ -0,0 +1,134 @@
+ACLOCAL_AMFLAGS = -I ../../../../aclocal
+
+include $(top_srcdir)/../../../../automake/compile.am
+
+include_bspdir = $(includedir)/bsp
+include_libcpudir = $(includedir)/libcpu
+
+dist_project_lib_DATA = bsp_specs
+
+###############################################################################
+# Header                                                     #
+###############################################################################
+
+include_HEADERS = include/bsp.h
+include_HEADERS += ../realview-pbx-a9/include/tm27.h
+
+nodist_include_HEADERS = ../../shared/include/coverhd.h include/bspopts.h
+nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h
+
+include_libcpu_HEADERS =  ../../../libcpu/arm/shared/include/arm-cp15.h
+
+include_bsp_HEADERS =
+include_bsp_HEADERS += ../../../libbsp/shared/include/mm.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/uart-output-char.h
+include_bsp_HEADERS += ../../shared/include/utility.h
+include_bsp_HEADERS += ../shared/include/linker-symbols.h
+include_bsp_HEADERS += ../shared/include/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 += ../shared/include/arm-cache-l1.h
+include_bsp_HEADERS += ../shared/armv467ar-basic-cache/cache_.h
+
+include_bsp_HEADERS += include/car.h
+include_bsp_HEADERS += include/console.h
+include_bsp_HEADERS += include/irq.h
+include_bsp_HEADERS += include/memory.h
+include_bsp_HEADERS += include/mmu.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 += ../shared/startup/linkcmds.base
+
+###############################################################################
+# 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/cpucounterread.c
+libbsp_a_SOURCES += ../../shared/cpucounterdiff.c
+libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c
+libbsp_a_SOURCES += ../../shared/sbrk.c
+libbsp_a_SOURCES += ../../shared/src/stackalloc.c
+libbsp_a_SOURCES += ../shared/startup/bsp-start-memcpy.S
+libbsp_a_SOURCES += ../shared/arm-cp15-set-ttb-entries.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
+
+# Clock and reset
+libbsp_a_SOURCES += clock/clockdrv.c ../../../shared/clockdrv_shell.h
+libbsp_a_SOURCES += clock/car.c
+
+# Console
+libbsp_a_SOURCES += ../../shared/console-termios.c
+libbsp_a_SOURCES += console/console.c
+libbsp_a_SOURCES += console/debug-console.c
+
+# IRQ
+libbsp_a_SOURCES += ../shared/arm-cp15-set-exception-handler.c
+libbsp_a_SOURCES += ../shared/arm-gic-irq.c
+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
+
+# Restart
+libbsp_a_SOURCES += startup/bspreset.c
+
+# Startup
+libbsp_a_SOURCES += startup/bspstart.c
+if HAS_SMP
+libbsp_a_SOURCES += ../shared/arm-a9mpcore-smp.c
+endif
+
+# Start hooks
+libbsp_a_SOURCES += startup/bspstarthooks.c
+
+# LIBMM
+libbsp_a_SOURCES += startup/mm_config_table.c
+libbsp_a_SOURCES += ../shared/mminit.c
+
+# misc
+libbsp_a_SOURCES += misc/timer.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/jetson-tk1/README b/c/src/lib/libbsp/arm/jetson-tk1/README
new file mode 100644
index 0000000000..13821c7082
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/README
@@ -0,0 +1,21 @@
+BSP for the Jetson TK1 ARM board
+
+This BSP currently supports the following devices:
+  - Console using UART-D on DB9 connector and UART-A on the J3A2 Pin header
+  - Clock using the ARM internal CP15 timer
+  - Benchmark timer using the Nvidia Generic Timer TimerUS
+
+Checkout the options described in include/bspopts.h.in in order to configure
+the second console or let the consoles operate interrupt driven.
+
+Currently, following IRQs are used:
+  If configured NS8250_CONSOLE_USE_INTERRUPTS=1)
+    - 122
+    - 68
+
+Also allow the following memory regions:
+  - UARTA 0x40 at 0x70006000
+  - UARTD 0x40 at 0x70006300
+  - Nvidia Timers 0x1000 at 0x60005000
+  - RAM 64MB at 0x90000000
+  - PINMUX AUX 0x1000 at 0x70003000
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/TODO b/c/src/lib/libbsp/arm/jetson-tk1/TODO
new file mode 100644
index 0000000000..5813393d82
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/TODO
@@ -0,0 +1,3 @@
+- SMP
+- Peripheral device drivers
+- Doxygen comments
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/bsp_specs b/c/src/lib/libbsp/arm/jetson-tk1/bsp_specs
new file mode 100644
index 0000000000..32c105fd0f
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/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/jetson-tk1/clock/car.c b/c/src/lib/libbsp/arm/jetson-tk1/clock/car.c
new file mode 100644
index 0000000000..d9553588eb
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/clock/car.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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 <bsp/car.h>
+#include <bsp/memory.h>
+#include <rtems/score/basedefs.h>
+
+#define CLK_ENB_L_SET (CAR + 0x320)
+#define CLK_ENB_L_CLR (CAR + 0x324)
+#define CLK_ENB_U_SET (CAR + 0x330)
+#define CLK_ENB_U_CLR (CAR + 0x334)
+#define CLK_SOURCE_UARTA (CAR + 0x178)
+#define CLK_SOURCE_UARTD (CAR + 0x1c0)
+
+#define RST_DEV_L_SET (CAR + 0x300)
+#define RST_DEV_L_CLR (CAR + 0x304)
+#define RST_DEV_U_SET (CAR + 0x310)
+#define RST_DEV_U_CLR (CAR + 0x314)
+
+#define GATE_UARTA (1 << 6)
+#define GATE_UARTD (1 << 0)
+
+typedef struct {
+  void *enb_set;
+  void *enb_clear;
+} clock_dev;
+
+typedef struct {
+  void *enb_set;
+  void *enb_clear;
+} reset_dev;
+
+typedef const struct {
+  clock_dev clock;
+  reset_dev reset;
+  void *src_reg;
+  uint32_t gate;
+} car_dev;
+
+static car_dev tegra124_car_dev[] = {
+  {
+    .clock = {
+      .enb_set = CLK_ENB_U_SET,
+      .enb_clear = CLK_ENB_U_CLR,
+    },
+    .reset = {
+      .enb_set = RST_DEV_U_SET,
+      .enb_clear = RST_DEV_U_CLR,
+    },
+    .src_reg = CLK_SOURCE_UARTD,
+    .gate = GATE_UARTD,
+  },
+  {
+    .clock = {
+      .enb_set = CLK_ENB_L_SET,
+      .enb_clear = CLK_ENB_L_CLR,
+    },
+    .reset = {
+      .enb_set = RST_DEV_L_SET,
+      .enb_clear = RST_DEV_L_CLR,
+    },
+    .src_reg = (void *) CLK_SOURCE_UARTA,
+    .gate = GATE_UARTA,
+  },
+};
+
+int tegra_car_set(uint32_t device_num)
+{
+  if (device_num > RTEMS_ARRAY_SIZE(tegra124_car_dev)) {
+    return -1;
+  }
+
+  mmio_write(tegra124_car_dev[device_num].clock.enb_set,
+    tegra124_car_dev[device_num].gate);
+
+  return 0;
+}
+
+int tegra_car_gate(uint32_t device_num, uint32_t car_source)
+{
+  uint32_t source;
+
+  if ((device_num > RTEMS_ARRAY_SIZE(tegra124_car_dev)) ||
+    (car_source > CAR_GATE_MAX)) {
+    return -1;
+  }
+
+  source = mmio_read(tegra124_car_dev[device_num].src_reg);
+  source &= ~(7 << CAR_GATE_OFFSET);
+  source |= car_source << CAR_GATE_OFFSET;
+
+  mmio_write(tegra124_car_dev[device_num].src_reg, source);
+
+  return 0;
+}
+
+int tegra_car_clear(uint32_t device_num)
+{
+  if (device_num > RTEMS_ARRAY_SIZE(tegra124_car_dev)) {
+    return -1;
+  }
+
+  mmio_write(
+    tegra124_car_dev[device_num].reset.enb_clear,
+    mmio_read(tegra124_car_dev[device_num].reset.enb_clear) |
+    tegra124_car_dev[device_num].gate
+  );
+
+  return 0;
+}
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c b/c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c
new file mode 100644
index 0000000000..52c2e7c9ef
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/clock/clockdrv.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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.h>
+#include <rtems/timecounter.h>
+#include <rtems/bspIo.h>
+#include <bsp.h>
+#include <bsp/memory.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
+#define USEC_PER_SEC 1000000L
+#define GICD_ICPENDR 0x1280
+#define TIMER_IRQ 27
+
+/* This is defined in ../../../shared/clockdrv_shell.h */
+void Clock_isr(rtems_irq_hdl_param arg);
+static uint32_t           timecounter_ticks_per_clock_tick;
+static struct timecounter clock_tc;
+
+static void gic_timer_start(uint32_t timeout)
+{
+  /* Write timeout into Virtual Timer TimerValue register */
+  arm_write_cp15_32(0, c14, c3, 0, timeout);
+  /* Run the timer with Virtual Timer Control register */
+  arm_write_cp15_32(0, c14, c3, 1, 1);
+}
+
+static uint32_t jetson_clock_get_timecount(struct timecounter *tc)
+{
+  uint64_t ret = 0;
+
+  /* Read the Physical Count Register */
+  arm_read_cp15_64(0, c14, ret);
+
+  /* This should be safe for rtems */
+  return (uint32_t) ret;
+}
+
+static void jetson_clock_at_tick(void)
+{
+  uint32_t CNTV_TVAL = 0;
+
+  arm_read_cp15_32(0, c14, c3, 0, CNTV_TVAL);
+
+  if ( CNTV_TVAL >= timecounter_ticks_per_clock_tick ) {
+    /* Clear pending interrupt */
+    mmio_write(BSP_ARM_GIC_DIST_BASE + GICD_ICPENDR, 1);
+    /* Reset the Virtual Timer */
+    arm_write_cp15_32(0, c14, c3, 1, 0);
+    gic_timer_start(timecounter_ticks_per_clock_tick);
+  }
+}
+
+static void jetson_clock_handler_install_isr(rtems_isr_entry clock_isr)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  if ( clock_isr != NULL ) {
+    sc = rtems_interrupt_handler_install(
+      TIMER_IRQ,
+      "Clock",
+      RTEMS_INTERRUPT_UNIQUE,
+      (rtems_interrupt_handler) clock_isr,
+      NULL
+    );
+  } else {
+    sc = rtems_interrupt_handler_remove(
+      TIMER_IRQ,
+      (rtems_interrupt_handler) Clock_isr,
+      NULL
+    );
+  }
+
+  if ( sc != RTEMS_SUCCESSFUL ) {
+    printk("fatal: %p\n", (uint32_t *) clock_isr);
+    rtems_fatal_error_occurred(0xc10cd1f3);
+  }
+}
+
+static void jetson_clock_initialize_hardware(void)
+{
+  uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  uint32_t frequency;
+
+  /* Get frequency of Generic Timer (CNTFRQ) */
+  arm_read_cp15_32(0, c14, c0, 0, frequency);
+  timecounter_ticks_per_clock_tick =
+    ((uint64_t) frequency * us_per_tick) / (uint64_t) USEC_PER_SEC;
+
+  gic_timer_start(timecounter_ticks_per_clock_tick);
+  clock_tc.tc_get_timecount = jetson_clock_get_timecount;
+  clock_tc.tc_counter_mask = 0xffffffff;
+  clock_tc.tc_frequency = frequency;
+  clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&clock_tc);
+}
+
+static void jetson_clock_cleanup(void)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  /* Stop the timer */
+  arm_write_cp15_32(0, c14, c3, 1, 0);
+
+  sc = rtems_interrupt_handler_remove(
+    TIMER_IRQ,
+    (rtems_interrupt_handler) Clock_isr,
+    NULL
+  );
+
+  if ( sc != RTEMS_SUCCESSFUL ) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+}
+
+#define Clock_driver_support_at_tick() jetson_clock_at_tick()
+
+#define Clock_driver_support_initialize_hardware() \
+  jetson_clock_initialize_hardware()
+
+#define Clock_driver_support_shutdown_hardware() jetson_clock_cleanup()
+
+#define Clock_driver_support_install_isr(clock_isr, old_isr) \
+  do {                                                 \
+    jetson_clock_handler_install_isr(clock_isr);  \
+    old_isr = NULL;                                    \
+  } while ( 0 )
+
+#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR 1
+
+#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/configure.ac b/c/src/lib/libbsp/arm/jetson-tk1/configure.ac
new file mode 100644
index 0000000000..7d4dce3008
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/configure.ac
@@ -0,0 +1,39 @@
+AC_PREREQ([2.68])
+AC_INIT([rtems-c-src-lib-libbsp-arm-jetson-tk1],[_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_BSPOPTS_SET([NS8250_CONSOLE_USE_INTERRUPTS],[*],[0])
+RTEMS_BSPOPTS_HELP([NS8250_CONSOLE_USE_INTERRUPTS],[Use interrupt driven mode for console devices])
+
+RTEMS_BSPOPTS_SET([MEMORY_SIZE],[*],[0x4000000])
+RTEMS_BSPOPTS_HELP([MEMORY_SIZE],[Set the amount of memory the application can
+use])
+
+RTEMS_BSPOPTS_SET([TEGRA_BASE],[*],[0x80000000])
+RTEMS_BSPOPTS_HELP([TEGRA_BASE],[Base load address])
+
+AC_DEFUN([TEGRA_LINKCMD],[
+AC_ARG_VAR([$1],[$2; default $3])dnl
+[$1]=[$]{[$1]:-[$3]}
+])
+
+TEGRA_LINKCMD([MEMORY_SIZE],[Begin of RAM region],[${MEMORY_SIZE}])
+TEGRA_LINKCMD([TEGRA_BASE],[Base load address],[${TEGRA_BASE}])
+
+AM_CONDITIONAL(HAS_SMP,[test "$rtems_cv_HAS_SMP" = "yes"])
+
+RTEMS_BSP_CLEANUP_OPTIONS(0, 0)
+
+AC_CONFIG_FILES([
+Makefile
+startup/linkcmds])
+AC_OUTPUT
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/console/console.c b/c/src/lib/libbsp/arm/jetson-tk1/console/console.c
new file mode 100644
index 0000000000..408972e3fe
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/console/console.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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 <unistd.h>
+
+#include <rtems/console.h>
+#include <rtems/termiostypes.h>
+#include <rtems/bspIo.h>
+
+#include <bsp.h>
+#include <bspopts.h>
+#include <bsp/car.h>
+#include <bsp/console.h>
+#include <bsp/fatal.h>
+#include <bsp/irq.h>
+#include <bsp/memory.h>
+
+#define UART_TX 0x0
+#define UART_DLL 0x0
+#define UART_RBR 0x0
+#define UART_DLM 0x4
+#define UART_IER 0x4
+#define UART_IIR 0x8
+#define UART_LCR 0xc
+#define  UART_LCR_8N1 ((1 << 0) | (1 << 1))
+#define  UART_LCR_DLAB (1 << 7)
+#define UART_LSR 0x14
+#define  UART_LSR_RDR (1 << 0)
+#define  UART_LSR_THRE (1 << 5)
+#define UART_MSR 0x18
+
+#define UART_IER_IE_RHR (1 << 0)
+#define UART_IER_IE_THR (1 << 1)
+
+#define BSP_UART_DEFAULT_BAUD_RATE 115200L
+#define BSP_UART_SPEED 408000000L
+
+typedef struct {
+  rtems_termios_device_context base;
+  void *regs;
+  uint32_t car;
+  bool console;
+  const char *device_name;
+#if NS8250_CONSOLE_USE_INTERRUPTS == 1
+  rtems_vector_number irq;
+  volatile bool transmitting;
+#endif
+} ns8250_uart_context;
+
+static ns8250_uart_context ns8250_uart_instances[] = {
+  {
+    .regs = UARTD,
+    .car = CAR_DEV_UARTD,
+    .device_name = "/dev/ttyS0",
+#if NS8250_CONSOLE_USE_INTERRUPTS == 1
+    .irq = UARTD_IRQ,
+    .transmitting = false,
+#endif
+  },
+  {
+    .regs = UARTA,
+    .car = CAR_DEV_UARTA,
+    .device_name = "/dev/ttyS1",
+#if NS8250_CONSOLE_USE_INTERRUPTS == 1
+    .irq = UARTA_IRQ,
+    .transmitting = false,
+#endif
+  },
+};
+
+static void ns8250_uart_write(
+  rtems_termios_device_context *context,
+  const char                   *buf,
+  size_t                        len
+)
+{
+  ns8250_uart_context *ctx = (ns8250_uart_context *) context;
+
+#if NS8250_CONSOLE_USE_INTERRUPTS == 1
+
+  if ( len ) {
+    ctx->transmitting = true;
+    mmio_write(ctx->regs + UART_TX, buf[0]);
+    mmio_write(ctx->regs + UART_IER,
+      mmio_read(ctx->regs + UART_IER) | UART_IER_IE_THR);
+  } else {
+    mmio_write(ctx->regs + UART_IER,
+      mmio_read(ctx->regs + UART_IER) & ~UART_IER_IE_THR);
+    ctx->transmitting = false;
+  }
+
+#else
+  unsigned int i = 0;
+
+  for ( i = 0; i < len; i++ ) {
+    while ( !(mmio_read(ctx->regs + UART_LSR) & UART_LSR_THRE) ) {
+      asm volatile("nop");
+    }
+
+    if ( buf[i] == '\n' ) {
+      mmio_write(ctx->regs + UART_TX, '\r');
+    }
+
+    mmio_write(ctx->regs + UART_TX, buf[i]);
+  }
+
+#endif
+}
+
+#if NS8250_CONSOLE_USE_INTERRUPTS == 1
+static void ns8250_uart_interrupt_handler(void *arg)
+{
+  char                 input;
+  rtems_termios_tty   *tty = arg;
+  ns8250_uart_context *ctx = rtems_termios_get_device_context(tty);
+  uint32_t             lsr = mmio_read(ctx->regs + UART_LSR);
+
+  if ( ctx->transmitting && lsr & UART_LSR_THRE ) {
+    rtems_termios_dequeue_characters(tty, 1);
+  }
+
+  if ( lsr & UART_LSR_RDR ) {
+    input = mmio_read(ctx->regs + UART_RBR);
+    rtems_termios_enqueue_raw_characters(tty, &input, 1);
+  }
+}
+#endif
+
+static int ns8250_uart_poll_read(rtems_termios_device_context *context)
+{
+  int                  result;
+  ns8250_uart_context *ctx = (ns8250_uart_context *) context;
+
+  /* Block until character appears */
+  while ( !(mmio_read(ctx->regs + UART_LSR) & UART_LSR_RDR) ) {
+    asm volatile("nop");
+  }
+
+  /* Save read input to result */
+  result = mmio_read(ctx->regs + UART_RBR);
+
+  return result;
+}
+
+static bool ns8250_uart_set_attributes(
+  rtems_termios_device_context *context,
+  const struct termios         *term
+)
+{
+  ns8250_uart_context *ctx = (ns8250_uart_context *) context;
+  rtems_termios_baud_t baud;
+  unsigned int         lcr;
+  uint16_t             divider;
+
+  /* We only have baud rate support yet */
+  baud = rtems_termios_baud_to_number(term->c_ospeed);
+  divider = BSP_UART_SPEED / (baud * 16);
+  lcr = mmio_read(ctx->regs + UART_LCR) | UART_LCR_DLAB;
+  mmio_write(ctx->regs + UART_LCR, lcr);
+
+  mmio_write(ctx->regs + UART_DLL, divider & 0xff);
+  mmio_write(ctx->regs + UART_DLM, (divider >> 8) & 0xff);
+  lcr = UART_LCR_8N1;
+  mmio_write(ctx->regs + UART_LCR, lcr);
+
+  return true;
+}
+
+static bool ns8250_uart_first_open(
+  rtems_termios_tty             *tty,
+  rtems_termios_device_context  *context,
+  struct termios                *term,
+  rtems_libio_open_close_args_t *args
+)
+{
+#if NS8250_CONSOLE_USE_INTERRUPTS == 1
+  rtems_status_code status;
+#endif
+  ns8250_uart_context *ctx = (ns8250_uart_context *) context;
+
+  tegra_car_clear(ctx->car);
+  tegra_car_gate(ctx->car, CAR_SOURCE_UART);
+  tegra_car_set(ctx->car);
+
+  rtems_termios_set_initial_baud(tty, BSP_UART_DEFAULT_BAUD_RATE);
+
+  if ( !ns8250_uart_set_attributes(context, term) ) {
+    return false;
+  }
+
+#if NS8250_CONSOLE_USE_INTERRUPTS == 1
+  /* Read everything pending */
+  mmio_read(ctx->regs + UART_RBR);
+  mmio_read(ctx->regs + UART_IIR);
+  mmio_read(ctx->regs + UART_LSR);
+  mmio_read(ctx->regs + UART_MSR);
+  status = rtems_interrupt_handler_install(
+    ctx->irq,
+    ctx->device_name,
+    RTEMS_INTERRUPT_UNIQUE,
+    ns8250_uart_interrupt_handler,
+    tty
+  );
+  if ( status != RTEMS_SUCCESSFUL ) {
+    return false;
+  }
+
+  mmio_write(ctx->regs + UART_LCR, UART_LCR_8N1);
+  mmio_write(ctx->regs + UART_IER, UART_IER_IE_RHR);
+#endif
+
+  return true;
+}
+
+static void ns8250_uart_last_close(
+  rtems_termios_tty             *tty,
+  rtems_termios_device_context  *context,
+  rtems_libio_open_close_args_t *args
+)
+{
+#if NS8250_CONSOLE_USE_INTERRUPTS == 1
+  rtems_status_code    status;
+  ns8250_uart_context *ctx = (ns8250_uart_context *) context;
+
+  tegra_car_clear(ctx->car);
+
+  status = rtems_interrupt_handler_remove(
+    ctx->irq,
+    ns8250_uart_interrupt_handler,
+    tty
+  );
+
+  if ( status != RTEMS_SUCCESSFUL ) {
+    rtems_fatal_error_occurred(status);
+  }
+
+#endif
+}
+
+static const rtems_termios_device_handler ns8250_uart_handler = {
+  .first_open = ns8250_uart_first_open,
+  .last_close = ns8250_uart_last_close,
+  .write = ns8250_uart_write,
+  .set_attributes = ns8250_uart_set_attributes,
+#if NS8250_CONSOLE_USE_INTERRUPTS == 1
+  .mode = TERMIOS_IRQ_DRIVEN,
+#else
+  .poll_read = ns8250_uart_poll_read,
+  .mode = TERMIOS_POLLED
+#endif
+};
+
+rtems_status_code console_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                     *arg
+)
+{
+  rtems_status_code status;
+
+  rtems_termios_initialize();
+  unsigned int i = 0;
+  int          err = 0;
+
+  for ( i = 0; i < RTEMS_ARRAY_SIZE(ns8250_uart_instances); i++ ) {
+    status = rtems_termios_device_install(
+      ns8250_uart_instances[i].device_name,
+      &ns8250_uart_handler,
+      NULL,
+      &ns8250_uart_instances[i].base
+    );
+
+    if ( status != RTEMS_SUCCESSFUL ) {
+      rtems_fatal_error_occurred(status);
+    }
+  }
+
+  err = link(ns8250_uart_instances[0].device_name, CONSOLE_DEVICE_NAME);
+
+  if ( err ) {
+    printk("link: %d", err);
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/console/debug-console.c b/c/src/lib/libbsp/arm/jetson-tk1/console/debug-console.c
new file mode 100644
index 0000000000..44b9b6a0fe
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/console/debug-console.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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/console.h>
+#include <bsp/memory.h>
+#include <rtems/bspIo.h>
+
+#define UART_LSR 0x14
+#define  UART_LSR_RDR (1 << 0)
+
+#define UART_RBR (0 << 0)
+
+static void ns8250_debug_console_out(char c)
+{
+  while ( !(mmio_read(UARTD + UART_LSR) & UART_LSR_THRE) ) {
+    asm volatile ("nop");
+  }
+
+  if ( c == '\n' ) {
+    mmio_write(UARTD + UART_TX, '\r');
+  }
+
+  mmio_write( UARTD + UART_TX, c );
+}
+
+static int ns8250_debug_console_in(void)
+{
+  int result;
+
+  while ( !(mmio_read( UARTD + UART_LSR ) & UART_LSR_RDR) ) {
+    asm volatile ( "nop" );
+  }
+
+  /* Read from UARTD */
+  result = mmio_read(UARTD + UART_RBR);
+  /* Clear interrupts */
+  mmio_write(UARTD + UART_LSR, 0);
+
+  return result;
+}
+
+BSP_output_char_function_type     BSP_output_char = ns8250_debug_console_out;
+BSP_polling_getchar_function_type BSP_poll_char = ns8250_debug_console_in;
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h b/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h
new file mode 100644
index 0000000000..ea4dcb74e4
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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_JETSONTK1_BSP_H
+#define LIBBSP_ARM_JETSONTK1_BSP_H
+
+#include <bspopts.h>
+#include <rtems.h>
+#include <bsp/default-initial-extension.h>
+
+#define BSP_ARM_GIC_DIST_BASE ((void *) 0x50041000)
+#define BSP_ARM_GIC_CPUIF_BASE ((void *) 0x50042000)
+
+#define APB_MISC_BASE ((void*) 0x70000000)
+#define PMC_BASE (APB_MISC_BASE + 0xE400)
+
+#define TIMER_BASE ((void *) 0x60005000)
+
+#endif /* LIBBSP_ARM_JETSONTK1_BSP_H */
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/car.h b/c/src/lib/libbsp/arm/jetson-tk1/include/car.h
new file mode 100644
index 0000000000..8b9687386f
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/include/car.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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_JETSONTK1_CAR_H
+#define LIBBSP_ARM_JETSONTK1_CAR_H
+
+#include <bspopts.h>
+
+#define CAR ((void *) 0x60006000)
+
+/* UART clock source: PLLC_OUT0 */
+#define CAR_SOURCE_UART 0
+
+#define CAR_DEV_UARTD 0 /* U */
+#define CAR_DEV_UARTA 1 /* L */
+
+#define CAR_GATE_MAX 31
+#define CAR_GATE_OFFSET 29
+
+int tegra_car_set(uint32_t device_num);
+int tegra_car_gate(uint32_t device_num, uint32_t car_source);
+int tegra_car_clear(uint32_t device_num);
+
+#endif /* LIBBSP_ARM_JETSONTK1_CAR_H */
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/console.h b/c/src/lib/libbsp/arm/jetson-tk1/include/console.h
new file mode 100644
index 0000000000..e5191b48e0
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/include/console.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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_JETSONTK1_CONSOLE_H
+#define LIBBSP_ARM_JETSONTK1_CONSOLE_H
+
+#include <rtems/termiostypes.h>
+#include <bsp/memory.h>
+
+#define UARTA ((void *) 0x70006000)
+#define UARTD ((void *) 0x70006300)
+
+#define UART_TX 0x0
+#define UART_LSR 0x14
+#define  UART_LSR_THRE (1 << 5)
+
+#define UARTA_IRQ (36 + 32)
+#define UARTD_IRQ (90 + 32)
+
+rtems_status_code console_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                     *arg
+);
+
+#endif /* LIBBSP_ARM_JETSONTK1_CONSOLE_H */
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/irq.h b/c/src/lib/libbsp/arm/jetson-tk1/include/irq.h
new file mode 100644
index 0000000000..200c8c78fa
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/include/irq.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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_JETSONTK1_IRQ_H
+#define LIBBSP_ARM_JETSONTK1_IRQ_H
+
+#ifndef ASM
+
+#include <rtems.h>
+#include <rtems/irq.h>
+#include <rtems/irq-extension.h>
+#include <bsp/arm-gic-irq.h>
+#include <bsp.h>
+
+#define BSP_INTERRUPT_VECTOR_MIN 0
+#define BSP_INTERRUPT_VECTOR_MAX 160
+
+#endif /* ASM */
+#endif /* LIBBSP_ARM_JETSONTK1_IRQ_H */
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/memory.h b/c/src/lib/libbsp/arm/jetson-tk1/include/memory.h
new file mode 100644
index 0000000000..a65e53e0a4
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/include/memory.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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_JETSONTK1_MEMORY_H
+#define LIBBSP_ARM_JETSONTK1_MEMORY_H
+
+#define arm_write_cp15_32(op1, crn, crm, op2, val) \
+  asm volatile("mcr	p15, "#op1 ", %0, "#crn ", "#crm ", "#op2 "\n" \
+                 : : "r" ((uint32_t) (val)))
+#define arm_write_cp15_64(op1, crm, val) \
+  asm volatile("mcrr	p15, "#op1 ", %Q0, %R0, "#crm "\n" \
+                 : : "r" ((uint64_t) (val)))
+
+#define arm_read_cp15_32(op1, crn, crm, op2, val) \
+  asm volatile("mrc	p15, "#op1 ", %0, "#crn ", "#crm ", "#op2 "\n" \
+                 : "=r" ((uint32_t) (val)))
+#define arm_read_cp15_64(op1, crm, val) \
+  asm volatile("mrrc	p15, "#op1 ", %Q0, %R0, "#crm "\n" \
+                 : "=r" ((uint64_t) (val)))
+
+#define mmio_read(address) (*(volatile uint32_t *) (address))
+#define mmio_write(address, value) \
+  (*(volatile uint32_t *) (address) = (value))
+
+#endif /* LIBBSP_ARM_JETSONTK1_MEMORY_H */
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h b/c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h
new file mode 100644
index 0000000000..fb8685aa12
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/include/mmu.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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_JETSONTK1_MMU_H
+#define LIBBSP_ARM_JETSONTK1_MMU_H
+
+#include <bsp/start.h>
+#include <bsp/arm-cp15-start.h>
+#include <libcpu/arm-cp15.h>
+
+static __attribute__((always_inline)) void jetson_setup_mmu_and_cache(void)
+{
+  unsigned int sctlr;
+
+  arm_cp15_start_setup_translation_table(
+    (uint32_t *) bsp_translation_table_base,
+    ARM_MMU_DEFAULT_CLIENT_DOMAIN,
+    arm_cp15_start_mmu_config_table,
+    arm_cp15_start_mmu_config_table_size
+  );
+  sctlr = arm_cp15_get_control();
+
+  arm_cp15_instruction_cache_invalidate();
+  arm_cp15_branch_predictor_invalidate_all();
+  arm_cp15_tlb_invalidate();
+  arm_cp15_flush_prefetch_buffer();
+
+  arm_cp15_set_translation_table_base_control_register(0);
+
+  sctlr |= ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M |
+           ARM_CP15_CTRL_Z | ARM_CP15_CTRL_A | ARM_CP15_CTRL_AFE;
+  arm_cp15_set_control( sctlr );
+  arm_cp15_tlb_invalidate();
+}
+
+#endif /* LIBBSP_ARM_JETSONTK1_MMU_H */
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/make/custom/jetson-tk1.cfg b/c/src/lib/libbsp/arm/jetson-tk1/make/custom/jetson-tk1.cfg
new file mode 100644
index 0000000000..bc7fb9b70a
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/make/custom/jetson-tk1.cfg
@@ -0,0 +1,16 @@
+include $(RTEMS_ROOT)/make/custom/default.cfg
+
+RTEMS_CPU = arm
+RTEMS_CPU_MODEL = cortex-a15
+
+CFLAGS_OPTIMIZE_V ?= -O2 -g
+CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections
+
+CPU_CFLAGS = -march=armv7ve -mtune=cortex-a15 -mfpu=neon-vfpv4
+LDFLAGS = -Wl,--gc-sections
+
+define bsp-post-link
+    $(OBJCOPY) -O binary --strip-all \
+        $(basename $@)$(EXEEXT) $(basename $@)$(DOWNEXT)
+    $(SIZE) $(basename $@)$(EXEEXT)
+endef
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c b/c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c
new file mode 100644
index 0000000000..d7ed8967a5
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/misc/timer.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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 <rtems.h>
+#include <rtems/btimer.h>
+#include <bsp/memory.h>
+
+#define TMR1 (0x0)
+#define TMR2 (0x8)
+#define TIMERUS (0x10)
+#define TMR3 (0x50)
+#define TMR4 (0x58)
+#define TMR5 (0x60)
+#define TMR6 (0x68)
+#define TMR7 (0x70)
+#define TMR8 (0x78)
+#define TMR9 (0x80)
+#define TMR0 (0x88)
+
+#define TIMERUS_BASE (TIMER_BASE + TIMERUS)
+
+#define TIMERUS_CFG 0x4
+#define TIMERUS_CNTR 0x0
+#define TIMERUS_USEC_CFG_12MHZ 0x000b
+
+static bool benchmark_timer_find_average_overhead = true;
+
+static uint32_t benchmark_timer_base;
+
+void benchmark_timer_initialize(void)
+{
+  /* Set clock speed */
+  mmio_write(TIMERUS_BASE + TIMERUS_CFG, TIMERUS_USEC_CFG_12MHZ);
+  /* Write timeout into Virtual Timer TimerValue register */
+  arm_write_cp15_32(0, c14, c3, 0, UINT32_MAX );
+  /* Run the timer with Virtual Timer Control register */
+  arm_write_cp15_32(0, c14, c3, 1, 1);
+  benchmark_timer_base = mmio_read(TIMERUS_BASE + TIMERUS_CNTR);
+}
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  benchmark_timer_t delta;
+
+  delta = mmio_read(TIMERUS_BASE + TIMERUS_CNTR) - benchmark_timer_base;
+
+  if ( benchmark_timer_find_average_overhead == true) {
+    return delta;
+  } else {
+    return mmio_read(TIMERUS_BASE + TIMERUS_CNTR);
+  }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c
new file mode 100644
index 0000000000..d3120cb564
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspreset.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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/memory.h>
+#include <bsp/bootcard.h>
+
+#define MAIN_RST 4
+
+void bsp_reset(void)
+{
+  mmio_write(PMC_BASE, mmio_read(PMC_BASE) | (1 << MAIN_RST));
+}
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c
new file mode 100644
index 0000000000..5deadf7b63
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstart.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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/irq-generic.h>
+#include <bsp/bootcard.h>
+
+void bsp_start(void)
+{
+  bsp_interrupt_initialize();
+}
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstarthooks.c b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstarthooks.c
new file mode 100644
index 0000000000..01ebcdffa8
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/bspstarthooks.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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/mmu.h>
+#include <bsp/arm-cache-l1.h>
+#include <rtems.h>
+
+void BSP_START_TEXT_SECTION bsp_start_hook_0(void)
+{
+}
+
+void BSP_START_TEXT_SECTION bsp_start_hook_1(void)
+{
+  uint32_t sctlr;
+
+  /*
+   * Do not use bsp_vector_table_begin == 0, since this will get optimized away.
+   */
+  if (bsp_vector_table_end != bsp_vector_table_size) {
+    arm_cp15_set_vector_base_address(bsp_vector_table_begin);
+
+    sctlr = arm_cp15_get_control();
+    sctlr &= ~ARM_CP15_CTRL_V;
+    arm_cp15_set_control(sctlr);
+  }
+
+  /*
+   * Current U-boot loader seems to start kernel image
+   * with I and D caches on and MMU enabled.
+   * If RTEMS application image finds that cache is on
+   * during startup then disable caches.
+   */
+  if ( sctlr & (ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M |
+    ARM_CP15_CTRL_A | ARM_CP15_CTRL_Z) ) {
+    if ( sctlr & (ARM_CP15_CTRL_C | ARM_CP15_CTRL_M) ) {
+      /*
+       * If the data cache is on then ensure that it is clean
+       * before switching off to be extra carefull.
+       */
+      arm_cp15_data_cache_clean_all_levels();
+    }
+    rtems_cache_invalidate_entire_data();
+    arm_cp15_flush_prefetch_buffer();
+    sctlr &= ~(ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M |
+               ARM_CP15_CTRL_Z | ARM_CP15_CTRL_A);
+    arm_cp15_set_control(sctlr);
+
+  }
+  bsp_start_copy_sections();
+  jetson_setup_mmu_and_cache();
+  bsp_start_clear_bss();
+}
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/linkcmds.in b/c/src/lib/libbsp/arm/jetson-tk1/startup/linkcmds.in
new file mode 100644
index 0000000000..f37a62faed
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/linkcmds.in
@@ -0,0 +1,39 @@
+bsp_mmu_size = 16k;
+
+MEMORY {
+  RAM         (AIW) : ORIGIN = @TEGRA_BASE@, LENGTH = @MEMORY_SIZE@ - bsp_mmu_size
+  RAM_MMU     (AIW) : ORIGIN = @TEGRA_BASE@ + @MEMORY_SIZE@ - bsp_mmu_size, LENGTH = bsp_mmu_size
+}
+
+bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 1;
+
+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_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_vector_table_in_start_section = 1;
+bsp_section_robarrier_align = DEFINED (bsp_section_robarrier_align) ? bsp_section_robarrier_align : 1M;
+
+bsp_translation_table_base = ORIGIN (RAM_MMU);
+bsp_translation_table_end = ORIGIN (RAM_MMU) + LENGTH (RAM_MMU);
+
+INCLUDE linkcmds.armv4
+
+HeapSize = DEFINED(HeapSize) ? HeapSize : 1024*1024;
diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c b/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c
new file mode 100644
index 0000000000..a8c3f41ccf
--- /dev/null
+++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) OTH Regensburg, 2017
+ *   Author: Andreas Kölbl
+ *
+ * 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 <bspopts.h>
+#include <bsp/car.h>
+#include <bsp/console.h>
+#include <bsp/arm-cp15-start.h>
+
+/*
+ * Pagetable initialization data
+ *
+ * Keep all read-only sections before read-write ones.
+ * This ensures that write is allowed if one page/region
+ * is partially filled by read-only section content
+ * and rest is used for writeable section
+ */
+
+BSP_START_DATA_SECTION const arm_cp15_start_section_config
+arm_cp15_start_mmu_config_table[] = {
+  ARMV7_CP15_START_DEFAULT_SECTIONS,
+  {
+    .begin = (uint32_t) CAR,
+    .end = (uint32_t) (CAR + 0x1000),
+    .flags = ARMV7_MMU_DEVICE
+  }, {
+    .begin = (uint32_t) TIMER_BASE,
+    .end = (uint32_t) (TIMER_BASE + 0x1000),
+    .flags = ARMV7_MMU_DEVICE
+  }, {
+    .begin = (uint32_t) APB_MISC_BASE,
+    .end = (uint32_t) (APB_MISC_BASE + 0x1000),
+    .flags = ARMV7_MMU_DEVICE
+  }, {
+    .begin = (uint32_t) UARTA,
+    .end = (uint32_t) UARTA + 0x1000,
+    .flags = ARMV7_MMU_DEVICE
+  }, {
+    .begin = (uint32_t) BSP_ARM_GIC_DIST_BASE,
+    .end = (uint32_t) (BSP_ARM_GIC_DIST_BASE + 0x1000),
+    .flags = ARMV7_MMU_DEVICE
+  }, {
+    .begin = (uint32_t) BSP_ARM_GIC_CPUIF_BASE,
+    .end = (uint32_t) (BSP_ARM_GIC_CPUIF_BASE + 0x1000),
+    .flags = ARMV7_MMU_DEVICE
+  }
+};
+
+const size_t arm_cp15_start_mmu_config_table_size =
+  RTEMS_ARRAY_SIZE(arm_cp15_start_mmu_config_table);
-- 
2.13.3



More information about the devel mailing list