[rtems commit] bsp/altera-cyclone-v: New BSP

Sebastian Huber sebh at rtems.org
Thu Mar 13 15:15:49 UTC 2014


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

Author:    Ralf Kirchner <ralf.kirchner at embedded-brains.de>
Date:      Wed Jul 31 09:45:59 2013 +0200

bsp/altera-cyclone-v: New BSP

Implemented so far:
- nocache heap for uncached RAM
- basic timer
- level 1 cache handling for arm cache controller
  in arm-cache-l1.h
- level 2 L2C-310 cache controller
- MMU
- DWMAC 1000 ethernet controller
- basic errata handling
- smp startup for second core

---

 c/src/lib/libbsp/arm/acinclude.m4                  |    2 +
 c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am  |  197 ++++
 c/src/lib/libbsp/arm/altera-cyclone-v/README       |    3 +
 c/src/lib/libbsp/arm/altera-cyclone-v/bsp_specs    |   13 +
 c/src/lib/libbsp/arm/altera-cyclone-v/configure.ac |   56 +
 .../arm/altera-cyclone-v/console/console-config.c  |  195 +++
 .../lib/libbsp/arm/altera-cyclone-v/include/bsp.h  |   65 +
 .../lib/libbsp/arm/altera-cyclone-v/include/irq.h  |   41 +
 .../arm/altera-cyclone-v/include/nocache-heap.h    |   55 +
 .../lib/libbsp/arm/altera-cyclone-v/include/tm27.h |   24 +
 .../arm/altera-cyclone-v/make/custom/altcycv.inc   |    8 +
 .../make/custom/altcycv_devkit.cfg                 |    1 +
 .../make/custom/altcycv_devkit_smp.cfg             |    1 +
 .../libbsp/arm/altera-cyclone-v/network/network.c  | 1237 ++++++++++++++++++++
 .../lib/libbsp/arm/altera-cyclone-v/preinstall.am  |  200 ++++
 .../libbsp/arm/altera-cyclone-v/startup/bspreset.c |   37 +
 .../libbsp/arm/altera-cyclone-v/startup/bspstart.c |   69 ++
 .../arm/altera-cyclone-v/startup/bspstarthooks.c   |  204 ++++
 .../arm/altera-cyclone-v/startup/linkcmds.altcycv  |   26 +
 .../startup/linkcmds.altcycv_devkit                |   18 +
 .../startup/linkcmds.altcycv_devkit_smp            |    3 +
 .../arm/altera-cyclone-v/startup/nocache-heap.c    |   89 ++
 22 files changed, 2544 insertions(+), 0 deletions(-)

diff --git a/c/src/lib/libbsp/arm/acinclude.m4 b/c/src/lib/libbsp/arm/acinclude.m4
index b800a60..b4a597d 100644
--- a/c/src/lib/libbsp/arm/acinclude.m4
+++ b/c/src/lib/libbsp/arm/acinclude.m4
@@ -2,6 +2,8 @@
 AC_DEFUN([RTEMS_CHECK_BSPDIR],
 [
   case "$1" in
+  altera-cyclone-v )
+    AC_CONFIG_SUBDIRS([altera-cyclone-v]);;
   csb336 )
     AC_CONFIG_SUBDIRS([csb336]);;
   csb337 )
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am b/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am
new file mode 100644
index 0000000..64703a2
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am
@@ -0,0 +1,197 @@
+##
+#
+# @file
+#
+# @brief Makefile of LibBSP for the Altera Cyclone-V platform.
+#
+
+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 += 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/tod.h
+include_bsp_HEADERS += ../shared/include/start.h
+include_bsp_HEADERS += ../shared/include/arm-a9mpcore-clock.h
+include_bsp_HEADERS += ../shared/include/arm-a9mpcore-irq.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_bsp_HEADERS += include/nocache-heap.h
+
+# Altera hwlib
+include_bsp_HEADERS += hwlib/include/alt_address_space.h
+include_bsp_HEADERS += hwlib/include/alt_clock_group.h
+include_bsp_HEADERS += hwlib/include/alt_clock_manager.h
+include_bsp_HEADERS += hwlib/include/alt_generalpurpose_io.h
+include_bsp_HEADERS += hwlib/include/alt_hwlibs_ver.h
+include_bsp_HEADERS += hwlib/include/alt_interrupt_common.h
+include_bsp_HEADERS += hwlib/include/alt_mpu_registers.h
+include_bsp_HEADERS += hwlib/include/alt_reset_manager.h
+include_bsp_HEADERS += hwlib/include/hwlib.h
+#The following Altera hwlib header files have been left out because so far 
+#they are not required:
+#include_bsp_HEADERS += hwlib/include/alt_16550_uart.h
+#include_bsp_HEADERS += hwlib/include/alt_bridge_manager.h
+#include_bsp_HEADERS += hwlib/include/alt_dma_common.h
+#include_bsp_HEADERS += hwlib/include/alt_dma_program.h
+#include_bsp_HEADERS += hwlib/include/alt_dma.h
+#include_bsp_HEADERS += hwlib/include/alt_fpga_manager.h
+#include_bsp_HEADERS += hwlib/include/alt_globaltmr.h
+#include_bsp_HEADERS += hwlib/include/alt_system_manager.h
+#include_bsp_HEADERS += hwlib/include/alt_timers.h
+#include_bsp_HEADERS += hwlib/include/alt_watchdog.h
+#The following Altera hwlib headers would be problematic with RTEMS:
+#include_bsp_HEADERS += hwlib/include/alt_interrupt.h
+#All header files from hwlib/include/socal are regarded as BSP
+#internal and thus not installed
+
+include_libcpu_HEADERS = ../../../libcpu/arm/shared/include/arm-cp15.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.altcycv
+project_lib_DATA += startup/linkcmds.altcycv_devkit
+project_lib_DATA += startup/linkcmds.altcycv_devkit_smp
+
+###############################################################################
+#                  LibBSP                                                     #
+###############################################################################
+
+noinst_LIBRARIES += libbsp.a
+
+libbsp_a_SOURCES =
+libbsp_a_CPPFLAGS =
+libbsp_a_LIBADD =
+
+# for the Altera hwlib
+libbsp_a_CPPFLAGS += -I ${srcdir}/hwlib/include
+libbsp_a_CPPFLAGS += -std=gnu99
+
+# hwlib from Altera
+libbsp_a_SOURCES += hwlib/src/hwmgr/alt_address_space.c
+libbsp_a_SOURCES += hwlib/src/hwmgr/alt_clock_manager.c
+libbsp_a_SOURCES += hwlib/src/hwmgr/alt_generalpurpose_io.c
+libbsp_a_SOURCES += hwlib/src/hwmgr/alt_reset_manager.c
+#The following Altera hwlib source files have been left out because so far 
+#they are not required:
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_16550_uart.c
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_bridge_manager.c
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_dma_program.c
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_dma.c
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_fpga_manager.c
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_globaltmr.c
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_system_manager.c
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_timers.c
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_watchdog.c
+# The following Altera hwlib source files would be problematic with RTEMS:
+#libbsp_a_SOURCES += hwlib/src/hwmgr/alt_interrupt.c
+
+
+# Shared
+libbsp_a_SOURCES += ../../shared/bootcard.c
+libbsp_a_SOURCES += ../../shared/bspclean.c
+libbsp_a_SOURCES += ../../shared/bspgetworkarea.c
+libbsp_a_SOURCES += ../../shared/bsplibc.c
+libbsp_a_SOURCES += ../../shared/bsppost.c
+libbsp_a_SOURCES += ../../shared/bsppredriverhook.c
+libbsp_a_SOURCES += ../../shared/bsppretaskinghook.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/stackalloc.c
+libbsp_a_SOURCES += ../shared/abort/simple_abort.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/nocache-heap.c
+
+# 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
+
+# Network
+libbsp_a_SOURCES += network/network.c
+
+# Console
+libbsp_a_SOURCES += ../../shared/console.c
+libbsp_a_SOURCES += ../../shared/console_control.c
+libbsp_a_SOURCES += ../../shared/console_read.c
+libbsp_a_SOURCES += ../../shared/console_select_simple.c
+libbsp_a_SOURCES += ../../shared/console_write.c
+libbsp_a_SOURCES += console/console-config.c
+
+# Clock
+libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
+libbsp_a_SOURCES += ../shared/arm-a9mpcore-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/arm-l2c-310/cache_.h
+libbsp_a_CPPFLAGS += -I$(srcdir)/../shared/arm-l2c-310
+
+# Start hooks
+libbsp_a_SOURCES += startup/bspstarthooks.c
+
+if HAS_SMP
+libbsp_a_SOURCES += ../shared/arm-a9mpcore-smp.c
+endif
+
+###############################################################################
+#                  Special Rules                                              #
+###############################################################################
+
+DISTCLEANFILES = include/bspopts.h
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/../../../../automake/local.am
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/README b/c/src/lib/libbsp/arm/altera-cyclone-v/README
new file mode 100644
index 0000000..575b72e
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/README
@@ -0,0 +1,3 @@
+Evaluation board for this BSP: 
+- Cyclone V SoC FPGA Development Kit
+- DK-DEV-5CSXC6N/ES-0L
\ No newline at end of file
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/bsp_specs b/c/src/lib/libbsp/arm/altera-cyclone-v/bsp_specs
new file mode 100644
index 0000000..082653a
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/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/altera-cyclone-v/configure.ac b/c/src/lib/libbsp/arm/altera-cyclone-v/configure.ac
new file mode 100644
index 0000000..561a192
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/configure.ac
@@ -0,0 +1,56 @@
+##
+#
+# @file
+#
+# @brief Configure script of LibBSP for the Altera Cyclone-V platform.
+#
+
+AC_PREREQ([2.69])
+AC_INIT([rtems-c-src-lib-libbsp-arm-xilinx-zynq-a9],[_RTEMS_VERSION],[http://www.rtems.org/bugzilla])
+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_ARM_A9MPCORE_PERIPHCLK],[altcycv_devkit*],[200000000U])
+RTEMS_BSPOPTS_SET([BSP_ARM_A9MPCORE_PERIPHCLK],[*],[100000000U])
+RTEMS_BSPOPTS_HELP([BSP_ARM_A9MPCORE_PERIPHCLK],[ARM Cortex-A9 MPCore PERIPHCLK clock frequency in Hz])
+
+RTEMS_BSPOPTS_SET([CLOCK_DRIVER_USE_FAST_IDLE],[*qemu],[1])
+RTEMS_BSPOPTS_HELP([CLOCK_DRIVER_USE_FAST_IDLE],
+[This sets a mode where the time runs as fast as possible when a clock ISR
+occurs while the IDLE thread is executing.  This can significantly reduce
+simulation times.])
+
+RTEMS_BSPOPTS_SET([BSP_CONSOLE_MINOR],[*],[0])
+RTEMS_BSPOPTS_HELP([BSP_CONSOLE_MINOR],[minor number of console device])
+
+RTEMS_BSPOPTS_SET([CYCLONE_V_CONFIG_CONSOLE],[*],[0])
+RTEMS_BSPOPTS_HELP([CYCLONE_V_CONFIG_CONSOLE],[configuration for console (UART 0)])
+
+RTEMS_BSPOPTS_SET([CYCLONE_V_CONFIG_UART_1],[*],[0])
+RTEMS_BSPOPTS_HELP([CYCLONE_V_CONFIG_UART_1],[configuration for UART 1])
+
+RTEMS_BSPOPTS_SET([CYCLONE_V_UART_BAUD],[*],[115200U])
+RTEMS_BSPOPTS_HELP([CYCLONE_V_UART_BAUD],[baud for UARTs])
+
+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/altera-cyclone-v/console/console-config.c b/c/src/lib/libbsp/arm/altera-cyclone-v/console/console-config.c
new file mode 100644
index 0000000..4241a5a
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/console/console-config.c
@@ -0,0 +1,195 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <libchip/serial.h>
+#include <libchip/ns16550.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/alt_clock_manager.h>
+#include "socal/alt_rstmgr.h"
+#include "socal/socal.h"
+#include "socal/alt_uart.h"
+#include "socal/hps.h"
+
+bool altera_cyclone_v_uart_probe( int minor );
+
+static uint8_t altera_cyclone_v_uart_get_register(uintptr_t addr, uint8_t i)
+{
+  volatile uint32_t *reg = (volatile uint32_t *) addr;
+
+  return (uint8_t) reg [i];
+}
+
+static void altera_cyclone_v_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
+{
+  volatile uint32_t *reg = (volatile uint32_t *) addr;
+
+  reg [i] = val;
+}
+
+console_tbl Console_Configuration_Ports[] = {
+#ifdef CYCLONE_V_CONFIG_CONSOLE
+  {
+    .sDeviceName   = "/dev/ttyS0",
+    .deviceType    = SERIAL_NS16550,
+    .pDeviceFns    = &ns16550_fns,
+    .deviceProbe   = altera_cyclone_v_uart_probe,
+    .pDeviceFlow   = NULL,
+    .ulMargin      = 16,
+    .ulHysteresis  = 8,
+    .pDeviceParams = (void *)CYCLONE_V_UART_BAUD,
+    .ulCtrlPort1   = (uint32_t)ALT_UART0_ADDR,
+    .ulCtrlPort2   = 0,
+    .ulDataPort    = (uint32_t)ALT_UART0_ADDR,
+    .getRegister   = altera_cyclone_v_uart_get_register,
+    .setRegister   = altera_cyclone_v_uart_set_register,
+    .getData       = NULL,
+    .setData       = NULL,
+    .ulClock       = 0,
+    .ulIntVector   = ALT_INT_INTERRUPT_UART0
+  },
+#endif
+#ifdef CYCLONE_V_CONFIG_UART_1
+  {
+    .sDeviceName   = "/dev/ttyS1",
+    .deviceType    = SERIAL_NS16550,
+    .pDeviceFns    = &ns16550_fns,
+    .deviceProbe   = altera_cyclone_v_uart_probe,
+    .pDeviceFlow   = NULL,
+    .ulMargin      = 16,
+    .ulHysteresis  = 8,
+    .pDeviceParams = (void *)CYCLONE_V_UART_BAUD,
+    .ulCtrlPort1   = (uint32_t)ALT_UART1_ADDR,
+    .ulCtrlPort2   = 0,
+    .ulDataPort    = (uint32_t)ALT_UART1_ADDR,
+    .getRegister   = altera_cyclone_v_uart_get_register,
+    .setRegister   = altera_cyclone_v_uart_set_register,
+    .getData       = NULL,
+    .setData       = NULL,
+    .ulClock       = 0,
+    .ulIntVector   = ALT_INT_INTERRUPT_UART1
+  }
+#endif
+};
+
+
+unsigned long Console_Configuration_Count =
+  RTEMS_ARRAY_SIZE(Console_Configuration_Ports);
+
+bool altera_cyclone_v_uart_probe(int minor)
+{
+  bool            ret           = true;
+  uint32_t        uart_set_mask;
+  uint32_t        ucr;
+  ALT_STATUS_CODE sc;
+  void*           location;
+
+  /* The ALT_CLK_L4_SP is required for all SoCFPGA UARTs. 
+   * Check that it's enabled. */
+  assert( alt_clk_is_enabled(ALT_CLK_L4_SP) == ALT_E_TRUE );
+  if ( alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE ) {
+    ret = false;
+  }
+
+  if ( ret ) {
+    switch(minor)
+    {
+      case(0):
+        /* UART 0 */
+        uart_set_mask = ALT_RSTMGR_PERMODRST_UART0_SET_MSK;
+        location      = ALT_UART0_ADDR;
+      break;
+      case(1):
+        /* UART 1 */
+        uart_set_mask = ALT_RSTMGR_PERMODRST_UART1_SET_MSK;
+        location      = ALT_UART1_ADDR;
+      break;
+      default:
+        /* Unknown case */
+        assert( minor == 0 || minor == 1 );
+        ret = false;
+      break;
+    }
+  }
+  if ( ret ) {
+    sc = alt_clk_freq_get(ALT_CLK_L4_SP, &Console_Configuration_Ports[minor].ulClock);
+    assert( sc == ALT_E_SUCCESS );
+    if ( sc != ALT_E_SUCCESS ) {
+      ret = false;
+    }
+  }
+
+  if ( ret ) {
+    // Bring UART out of reset.
+    alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, uart_set_mask);
+
+    // Verify the UCR (UART Component Version)
+    ucr = alt_read_word( ALT_UART_UCV_ADDR( location ) );
+
+    assert( ucr == ALT_UART_UCV_UART_COMPONENT_VER_RESET );
+    if ( ucr != ALT_UART_UCV_UART_COMPONENT_VER_RESET ) {
+      ret = false;
+    }
+  }
+
+  if ( ret ) {
+    // Write SRR::UR (Shadow Reset Register :: UART Reset)
+    alt_write_word( ALT_UART_SRR_ADDR( location ), ALT_UART_SRR_UR_SET_MSK );
+
+    // Read the MSR to work around case:119085.
+    (void)alt_read_word( ALT_UART_MSR_ADDR( location ) );
+  }
+
+  return ret;
+}
+
+static void output_char(char c)
+{
+  int minor = (int) Console_Port_Minor;
+  const console_tbl *ct = Console_Port_Tbl != NULL ?
+    Console_Port_Tbl[minor] : &Console_Configuration_Ports[minor];
+  const console_fns *cf = ct->pDeviceFns;
+
+  if (c == '\n') {
+    (*cf->deviceWritePolled)(minor, '\r');
+  }
+
+  (*cf->deviceWritePolled)(minor, c);
+}
+
+static void output_char_init(char c)
+{
+  if (Console_Port_Tbl == NULL) {
+    int minor;
+    const console_fns *cf;
+
+    bsp_console_select();
+
+    minor = (int) Console_Port_Minor;
+    cf = Console_Configuration_Ports[minor].pDeviceFns;
+
+    (*cf->deviceInitialize)(minor);
+  }
+
+  BSP_output_char = output_char;
+  output_char(c);
+}
+
+BSP_output_char_function_type BSP_output_char = output_char_init;
+
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/include/bsp.h b/c/src/lib/libbsp/arm/altera-cyclone-v/include/bsp.h
new file mode 100644
index 0000000..694fd14
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/include/bsp.h
@@ -0,0 +1,65 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_ALTERY_CYCLONE_V_BSP_H
+#define LIBBSP_ARM_ALTERY_CYCLONE_V_BSP_H
+
+#include <bspopts.h>
+
+#define BSP_FEATURE_IRQ_EXTENSION
+
+#ifndef ASM
+
+#include <rtems.h>
+#include <rtems/console.h>
+#include <rtems/clockdrv.h>
+
+#include <bsp/default-initial-extension.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define BSP_ARM_A9MPCORE_SCU_BASE 0xFFFEC000
+
+#define BSP_ARM_GIC_CPUIF_BASE ( BSP_ARM_A9MPCORE_SCU_BASE + 0x00000100 )
+
+#define BSP_ARM_A9MPCORE_GT_BASE ( BSP_ARM_A9MPCORE_SCU_BASE + 0x00000200 )
+
+#define BSP_ARM_GIC_DIST_BASE ( BSP_ARM_A9MPCORE_SCU_BASE + 0x00001000 )
+
+#define BSP_ARM_L2CC_BASE 0xFFFEF000U
+
+/* Forward declaration */
+struct rtems_bsdnet_ifconfig;
+
+/** @brief Network interface attach detach
+ *
+ * Attaches a network interface tp the network stack.
+ * NOTE: Detaching is not supported!
+ */
+int altera_cyclone_v_network_if_attach_detach(
+  struct rtems_bsdnet_ifconfig *config,
+  int                           attaching );
+
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH altera_cyclone_v_network_if_attach_detach
+#define RTEMS_BSP_NETWORK_DRIVER_NAME "eth0"
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ASM */
+
+#endif /* LIBBSP_ARM_ALTERY_CYCLONE_V_BSP_H */
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/include/irq.h b/c/src/lib/libbsp/arm/altera-cyclone-v/include/irq.h
new file mode 100644
index 0000000..5a088ab
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/include/irq.h
@@ -0,0 +1,41 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_ALTERA_CYCLONE_V_IRQ_H
+#define LIBBSP_ARM_ALTERA_CYCLONE_V_IRQ_H
+
+#ifndef ASM
+
+#include <rtems/irq.h>
+#include <rtems/irq-extension.h>
+
+#include <bsp/arm-a9mpcore-irq.h>
+#include <bsp/arm-gic-irq.h>
+#include <bsp/alt_interrupt_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Use interrupt IDs as defined in alt_interrupt_common.h */
+#define BSP_INTERRUPT_VECTOR_MIN ALT_INT_INTERRUPT_SGI0
+#define BSP_INTERRUPT_VECTOR_MAX ALT_INT_INTERRUPT_RAM_ECC_UNCORRECTED_IRQ
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ASM */
+
+#endif /* LIBBSP_ARM_ALTERA_CYCLONE_V_IRQ_H */
\ No newline at end of file
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/include/nocache-heap.h b/c/src/lib/libbsp/arm/altera-cyclone-v/include/nocache-heap.h
new file mode 100644
index 0000000..73f56f3
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/include/nocache-heap.h
@@ -0,0 +1,55 @@
+/**
+ * @file
+ *
+ * @brief Heap handling for uncached RAM
+ */
+
+/*
+ * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef NOCACHE_HEAP_H_
+#define NOCACHE_HEAP_H_
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** @brief Initialize nocache heap.
+ *
+ * Initializes a heap for uncached RAM
+ */
+void altera_cyclone_v_nocache_init_heap( void );
+
+/** @brief Nocache alloc.
+ *
+ * Allocate memory from uncached heap.
+ * @param   size  Number of bytes to be allocated.
+ * @returns  Pointer to the allocated memory.
+ */
+void *altera_cyclone_v_nocache_malloc( const size_t size );
+
+/** @brief Nocache free.
+ *
+ * Release memory from uncached heap.
+ * @param ptr Address of the memory to be released.
+ */
+void altera_cyclone_v_nocache_free( void *ptr );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* NOCACHE_HEAP_H_ */
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/include/tm27.h b/c/src/lib/libbsp/arm/altera-cyclone-v/include/tm27.h
new file mode 100644
index 0000000..96ab469
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/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.com/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/altera-cyclone-v/make/custom/altcycv.inc b/c/src/lib/libbsp/arm/altera-cyclone-v/make/custom/altcycv.inc
new file mode 100644
index 0000000..bbe3f54
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/make/custom/altcycv.inc
@@ -0,0 +1,8 @@
+include $(RTEMS_ROOT)/make/custom/default.cfg
+
+RTEMS_CPU = arm
+
+CPU_CFLAGS = -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -mtune=cortex-a9
+
+#CFLAGS_OPTIMIZE_V ?= -O0 -g
+CFLAGS_OPTIMIZE_V ?= -O2 -g
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/make/custom/altcycv_devkit.cfg b/c/src/lib/libbsp/arm/altera-cyclone-v/make/custom/altcycv_devkit.cfg
new file mode 100644
index 0000000..ed54edf
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/make/custom/altcycv_devkit.cfg
@@ -0,0 +1 @@
+include $(RTEMS_ROOT)/make/custom/altcycv.inc
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/make/custom/altcycv_devkit_smp.cfg b/c/src/lib/libbsp/arm/altera-cyclone-v/make/custom/altcycv_devkit_smp.cfg
new file mode 100644
index 0000000..ed54edf
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/make/custom/altcycv_devkit_smp.cfg
@@ -0,0 +1 @@
+include $(RTEMS_ROOT)/make/custom/altcycv.inc
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/network/network.c b/c/src/lib/libbsp/arm/altera-cyclone-v/network/network.c
new file mode 100644
index 0000000..d2f669a
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/network/network.c
@@ -0,0 +1,1237 @@
+/**
+ * @file
+ *
+ * @brief Network Driver
+ *
+ * This driver is a wrapper for the DWMAC 1000 driver from libchip.
+ * The DWMAC 1000 driver is an on-chip Synopsys IP Ethernet controllers
+ */
+
+/*
+ * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#include <rtems.h>
+
+#if defined(RTEMS_NETWORKING)
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <rtems.h>
+#include <rtems/config.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/hwlib.h>
+#include <bsp/alt_clock_manager.h>
+#include <bsp/alt_generalpurpose_io.h>
+#include <bsp/nocache-heap.h>
+#include "socal/alt_rstmgr.h"
+#include "socal/hps.h"
+#include "socal/socal.h"
+#include <libchip/dwmac.h>
+
+/** @brief Pin mask for the interrupt from the ethernet PHY */
+#define NETWORK_PIN_MASK_PHY_INTERRUPT 0x00000040U
+
+/** @brief Ethernet PHY status */
+typedef enum {
+  /** @brief The ethernet PHY is off */
+  NETWORK_IF_PHY_STATUS_OFF,
+
+  /** @brief The ethernet PHY is on an initialized, but stopped */
+  NETWORK_IF_PHY_STATUS_STOPPED,
+
+  /** @brief The ethernet PHY is started and will generate requested events */
+  NETWORK_IF_PHY_STATUS_STARTED,
+
+  /** @brief Number of ethernet PHY statuses */
+  NETWORK_IF_PHY_STATUS_COUNT
+} network_if_phy_status;
+
+/** @brief Phy context
+ *
+ * ethernet PHY device context
+ */
+typedef struct {
+  /** @brief PHY device status */
+  network_if_phy_status status;
+
+  /** @brief Interrupt mask which corresponds to currently requested events */
+  uint16_t irq_mask;
+} network_if_phy_context;
+
+/** @brief Phy context initializer
+ *
+ * @retval Initialized network PHY context
+ */
+#define NETWORK_IF_PHY_CONTEXT_INITIALIZER( \
+    ) \
+  { \
+    NETWORK_IF_PHY_STATUS_OFF, \
+    0 \
+  }
+
+/** @brief Network interface controller ID
+ *
+ * Identifies the network interface controller handled by the driver
+ */
+typedef enum {
+  /** @brief ID for EMAC0 */
+  NETWORK_IF_NIC_ID_EMAC0,
+
+  /** @brief ID for EMAC1 */
+  NETWORK_IF_NIC_ID_EMAC1,
+
+  /** @brief Number of network interface controller IDs */
+  NETWORK_IF_NIC_ID_COUNT
+} network_if_nic_id;
+
+/** @brief Network interface context
+ *
+ * Context for the micro controller specific part of the DWMAC 1000 n
+ * etwork driver
+ */
+typedef struct {
+  /** @brief Network interface controller ID */
+  network_if_nic_id nic_id;
+
+  /** @brief Driver context
+   *
+   * Address of the context of the low level DWMAC 1000 driver from libchip */
+  void *driver_context;
+
+  /** @brief Ethernet PHY context */
+  network_if_phy_context phy;
+
+  /* TODO: Create network context on micro controller level */
+} network_if_context;
+
+/** @brief Network interface context initializer
+ *
+ * Initializer for the context of a network interface
+ * @param nic_id          ID of the network interface controller
+ * @param driver_context Address of the context of the low level DWMAC 1000
+ *                       driver from libchip
+ * @retval Initialized network interface context
+ */
+#define NETWORK_IF_CONTEXT_INITIALIZER( \
+    nic_id, \
+    driver_context \
+    ) \
+  { \
+    nic_id, \
+    driver_context, \
+    NETWORK_IF_PHY_CONTEXT_INITIALIZER() \
+  }
+
+/******************************************************************************
+* Helper Methods
+******************************************************************************/
+
+/** @brief Altera status code to errno
+ *
+ * Convert Altera status code to errno error number
+ * @param status  Altera status code as returned by methods from Alteras HWLib
+ * @retval Converted errno error number from errno.h
+ */
+static int network_if_altera_status_code_to_errno( ALT_STATUS_CODE status )
+{
+  int eno = 0;
+
+  switch ( status ) {
+    /*!
+     * Indicates a FALSE condition.
+     */
+    case ALT_E_FALSE:
+
+    /*!
+     * Indicates a TRUE condition.
+     */
+    case ALT_E_TRUE:
+
+      /*! The operation was successful. */
+      /* case ALT_E_SUCCESS: */
+      eno = 0;
+      break;
+
+    /*! The operation failed. */
+    case ALT_E_ERROR:
+
+    /*! An invalid option was selected. */
+    case ALT_E_INV_OPTION:
+      eno = EIO; /* I/O error */
+      break;
+
+    /*! FPGA configuration error detected.*/
+    case ALT_E_FPGA_CFG:
+      eno = ECANCELED; /* Operation canceled */
+      break;
+
+    /*! FPGA CRC error detected. */
+    case ALT_E_FPGA_CRC:
+
+    /*! An error occurred on the FPGA configuration bitstream input source. */
+    case ALT_E_FPGA_CFG_STM:
+      eno = EPROTO; /* Protocol error */
+      break;
+
+    /*! The FPGA is powered off. */
+    case ALT_E_FPGA_PWR_OFF:
+      eno = ENODEV; /* No such device */
+      break;
+
+    /*! The SoC does not currently control the FPGA. */
+    case ALT_E_FPGA_NO_SOC_CTRL:
+
+    /*! The FPGA is not in USER mode. */
+    case ALT_E_FPGA_NOT_USER_MODE:
+      eno = EPERM; /* Not super-user */
+      break;
+
+    /*! An argument violates a range constraint. */
+    case ALT_E_ARG_RANGE:
+
+    /*! A bad argument value was passed. */
+    case ALT_E_BAD_ARG:
+
+    /*! The argument value is reserved or unavailable. */
+    case ALT_E_RESERVED:
+      eno = EINVAL; /* Invalid argument */
+      break;
+
+    /*! The operation is invalid or illegal. */
+    case ALT_E_BAD_OPERATION:
+
+    /*! The version ID is invalid. */
+    case ALT_E_BAD_VERSION:
+      eno = EFAULT; /* Bad address */
+      break;
+
+    /*! An operation or response timeout period expired. */
+    case ALT_E_TMO:
+
+    /*! A clock is not enabled or violates an operational constraint. */
+    case ALT_E_BAD_CLK:
+      eno = ETIME; /* Timer expired */
+      break;
+
+    /*! The buffer does not contain enough free space for the operation. */
+    case ALT_E_BUF_OVF:
+      eno = ENOMEM; /* Not enough core */
+      break;
+    default:
+
+      /* Unknown case. Implement it! */
+      assert( 0 == 1 );
+      eno = EIO;
+      break;
+  }
+
+  return eno;
+}
+
+/** @brief PHY check chip ID
+ *
+ * Check the chip-ID of the KSZ8842 ethernet PHY.
+ * @param context Address of the network context
+ * @retval  0 if chip could be identified, error code from errno.h otherwise.
+ */
+static int network_if_phy_check_chip_id( network_if_context *context )
+{
+  int      eno;
+  uint16_t reg;
+
+  eno = dwmac_if_read_from_phy(
+    context->driver_context,
+    2,
+    &reg
+    );
+
+  if ( eno == 0 ) {
+    if ( reg != 0x0022 ) { /* PHY ID part 1 */
+      eno = ENXIO;
+    } else {
+      eno = dwmac_if_read_from_phy(
+        context->driver_context,
+        3,
+        &reg
+        );
+
+      if ( eno == 0 ) {
+        /* PHY ID part 2  and
+         * Manufacturers model number */
+        if ( ( ( reg & 0xFC00 ) >> 10 ) != 0x0005 ) { 
+          eno = ENXIO;
+        } else if ( ( ( reg & 0x03F0 ) >> 4 ) != 0x0021 ) {
+          eno = ENXIO;
+        }
+      }
+    }
+  }
+
+  return eno;
+}
+
+/******************************************************************************
+* Callback Methods
+******************************************************************************/
+
+/** @brief NIC enable
+ *
+ * Enables (powers up) the network interface card.
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_nic_enable( void *arg )
+{
+  int                 eno               = 0;
+  network_if_context *context           = (network_if_context *) arg;
+  ALT_CLK_t           module_clk        = ALT_CLK_EMAC0;
+  uint32_t            permodrst_clr_msk = ALT_RSTMGR_PERMODRST_EMAC0_CLR_MSK;
+
+  switch ( context->nic_id ) {
+    case NETWORK_IF_NIC_ID_EMAC0:
+    {
+      module_clk        = ALT_CLK_EMAC0;
+      permodrst_clr_msk = ALT_RSTMGR_PERMODRST_EMAC0_CLR_MSK;
+    }
+    break;
+    case NETWORK_IF_NIC_ID_EMAC1:
+    {
+      module_clk        = ALT_CLK_EMAC1;
+      permodrst_clr_msk = ALT_RSTMGR_PERMODRST_EMAC1_CLR_MSK;
+    }
+    break;
+
+    case NETWORK_IF_NIC_ID_COUNT:
+
+      /* Invalid case */
+      eno = ENODEV;
+      break;
+    default:
+
+      /* Unknown case */
+      eno = ENOTSUP;
+      break;
+  }
+
+  /* Pin mux configuration is handled by the Preloader. Thus no
+   * pin mux configuration here. */
+
+  /* Enable the clock for the EMAC module */
+  if ( eno == 0 ) {
+    if ( ALT_E_FALSE == alt_clk_is_enabled( module_clk ) ) {
+      ALT_STATUS_CODE status = alt_clk_clock_enable( module_clk );
+      eno = network_if_altera_status_code_to_errno( status );
+    }
+  }
+
+  /* Finish reset for the EMAC module */
+  if ( eno == 0 ) {
+    uint32_t reg = alt_read_word( ALT_RSTMGR_PERMODRST_ADDR );
+    alt_write_word( ALT_RSTMGR_PERMODRST_ADDR, reg & permodrst_clr_msk );
+  }
+
+  return eno;
+}
+
+/** @brief NIC disable.
+ *
+ * Disables (powers down) the network interface card.
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_nic_disable( void *arg )
+{
+  int                 eno               = 0;
+  network_if_context *context           = (network_if_context *) arg;
+  ALT_CLK_t           module_clk        = ALT_CLK_EMAC0;
+  uint32_t            permodrst_set_msk = ALT_RSTMGR_PERMODRST_EMAC0_SET_MSK;
+
+  switch ( context->nic_id ) {
+    case NETWORK_IF_NIC_ID_EMAC0:
+      module_clk        = ALT_CLK_EMAC0;
+      permodrst_set_msk = ALT_RSTMGR_PERMODRST_EMAC0_SET_MSK;
+      break;
+    case NETWORK_IF_NIC_ID_EMAC1:
+      module_clk        = ALT_CLK_EMAC1;
+      permodrst_set_msk = ALT_RSTMGR_PERMODRST_EMAC1_SET_MSK;
+      break;
+
+    case NETWORK_IF_NIC_ID_COUNT:
+
+      /* Invalid case */
+      eno = ENODEV;
+      break;
+    default:
+
+      /* Unknown case */
+      eno = ENOTSUP;
+      break;
+  }
+
+  /* Enter rest status for the EMAC module */
+  if ( eno == 0 ) {
+    uint32_t reg = alt_read_word( ALT_RSTMGR_PERMODRST_ADDR );
+    alt_write_word( ALT_RSTMGR_PERMODRST_ADDR, reg | permodrst_set_msk );
+  }
+
+  /* Disable the clock for the EMAC module */
+  if ( eno == 0 ) {
+    if ( ALT_E_TRUE == alt_clk_is_enabled( module_clk ) ) {
+      ALT_STATUS_CODE status = alt_clk_clock_disable( module_clk );
+      eno = network_if_altera_status_code_to_errno( status );
+    }
+  }
+
+  return eno;
+}
+
+/** @brief PHY disable.
+ *
+ * Disables (powers down) the network PHY.
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_phy_disable( void *arg )
+{
+  int                 eno  = 0;
+  network_if_context *self = (network_if_context *) arg;
+  uint32_t            mask;
+  ALT_STATUS_CODE     status_code;
+
+  /* The power pin of the PHY is hard wire to board power control and
+   * the PHY supports interrupts, This means we can not power it down
+   * and we don't need to stop a timer for polling PHY events. */
+
+  status_code = alt_gpio_port_int_mask_set(
+    ALT_GPIO_PORTB,
+    NETWORK_PIN_MASK_PHY_INTERRUPT,
+    NETWORK_PIN_MASK_PHY_INTERRUPT
+    );
+  eno = network_if_altera_status_code_to_errno( status_code );
+
+  if ( eno == 0 ) {
+    mask        = alt_gpio_port_int_enable_get( ALT_GPIO_PORTB );
+    status_code = alt_gpio_port_int_enable(
+      ALT_GPIO_PORTB,
+      mask & ~NETWORK_PIN_MASK_PHY_INTERRUPT
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+  }
+
+  if ( eno == 0 ) {
+    status_code = alt_gpio_port_int_status_clear(
+      ALT_GPIO_PORTB,
+      NETWORK_PIN_MASK_PHY_INTERRUPT
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+  }
+
+  if ( eno == 0 ) {
+    self->phy.status = NETWORK_IF_PHY_STATUS_OFF;
+  }
+
+  return eno;
+}
+
+/** @brief PHY enable.
+ *
+ * Enables (powers up) the network PHY.
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_phy_enable( void *arg )
+{
+  int                 eno  = 0;
+  network_if_context *self = (network_if_context *) arg;
+  ALT_STATUS_CODE     status_code;
+
+  /* The power pin of the PHY is hard wire to board power control and
+   * the PHY supports interrupts, This means we can not power it up
+   * and we don't need to start a timer for polling PHY events. */
+
+  eno = network_if_phy_check_chip_id( self );
+
+  if ( eno == 0 ) {
+    /* The phy is already enabled and we will reset it */
+    eno = network_if_phy_disable( self );
+
+    if ( eno == 0 ) {
+      rtems_task_wake_after( rtems_clock_get_ticks_per_second() / 100 );
+    }
+  } else {
+    eno = 0;
+  }
+
+  status_code = alt_gpio_port_datadir_set(
+    ALT_GPIO_PORTB,
+    NETWORK_PIN_MASK_PHY_INTERRUPT,
+    0
+    );
+  eno = network_if_altera_status_code_to_errno( status_code );
+
+  if ( eno == 0 ) {
+    status_code = alt_gpio_port_int_type_set(
+      ALT_GPIO_PORTB,
+      NETWORK_PIN_MASK_PHY_INTERRUPT,
+      0
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+  }
+
+  if ( eno == 0 ) {
+    status_code = alt_gpio_port_int_pol_set(
+      ALT_GPIO_PORTB,
+      NETWORK_PIN_MASK_PHY_INTERRUPT,
+      1
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+  }
+
+  if ( eno == 0 ) {
+    status_code = alt_gpio_port_debounce_set(
+      ALT_GPIO_PORTB,
+      NETWORK_PIN_MASK_PHY_INTERRUPT,
+      0
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+  }
+
+  if ( eno == 0 ) {
+    status_code = alt_gpio_port_int_enable(
+      ALT_GPIO_PORTB,
+      NETWORK_PIN_MASK_PHY_INTERRUPT
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+  }
+
+  if ( eno == 0 ) {
+    status_code = alt_gpio_port_int_mask_set(
+      ALT_GPIO_PORTB,
+      NETWORK_PIN_MASK_PHY_INTERRUPT,
+      0
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+  }
+
+  if ( eno == 0 ) {
+    status_code = alt_gpio_port_int_status_clear(
+      ALT_GPIO_PORTB,
+      NETWORK_PIN_MASK_PHY_INTERRUPT
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+  }
+
+  if ( eno == 0 ) {
+    self->phy.status = NETWORK_IF_PHY_STATUS_STOPPED;
+  }
+
+  return eno;
+}
+
+/** @brief Clear phy event status.
+ *
+ * Clears all PHY event statuses.
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_phy_event_status_clear( void *arg )
+{
+  int             eno;
+  ALT_STATUS_CODE status_code;
+
+  (void) arg;
+
+  /* Clear the interrupt status */
+  status_code = alt_gpio_port_int_status_clear(
+    ALT_GPIO_PORTB,
+    NETWORK_PIN_MASK_PHY_INTERRUPT
+    );
+  eno = network_if_altera_status_code_to_errno( status_code );
+
+  if ( eno == 0 ) {
+    /* Unmask the interrupt (was masked within interrupt handler) */
+    status_code = alt_gpio_port_int_mask_set(
+      ALT_GPIO_PORTB,
+      NETWORK_PIN_MASK_PHY_INTERRUPT,
+      0
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+  }
+
+  return eno;
+}
+
+/**
+ * @brief Get the PHY event status.
+ *
+ * Reports status on PHY events (e.g. PHY interrupts).
+ * @param[in]  arg        The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @param[out] event_set  Pointer to a buffer for a set of events for which a
+ *                        PHY status change was detected.
+ *                        For events see @see dwmac_phy_event.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_phy_events_status_get(
+  void            *arg,
+  dwmac_phy_event *event_set )
+{
+  int                 eno  = 0;
+  uint16_t            reg  = 0;
+  network_if_context *self = (network_if_context *) arg;
+
+  eno = dwmac_if_read_from_phy(
+    self->driver_context,
+    0x1B,
+    &reg
+    );
+
+  if ( eno == 0 ) {
+    if ( ( reg & 0x80 ) != 0 ) {
+      *event_set |= PHY_EVENT_JABBER;
+    }
+
+    if ( ( reg & 0x40 ) != 0 ) {
+      *event_set |= PHY_EVENT_RECEIVE_ERROR;
+    }
+
+    if ( ( reg & 0x20 ) != 0 ) {
+      *event_set |= PHY_EVENT_PAGE_RECEIVE;
+    }
+
+    if ( ( reg & 0x10 ) != 0 ) {
+      *event_set |= PHY_EVENT_PARALLEL_DETECT_FAULT;
+    }
+
+    if ( ( reg & 0x08 ) != 0 ) {
+      *event_set |= PHY_EVENT_LINK_PARTNER_ACK;
+    }
+
+    if ( ( reg & 0x04 ) != 0 ) {
+      *event_set |= PHY_EVENT_LINK_DOWN;
+    }
+
+    if ( ( reg & 0x02 ) != 0 ) {
+      *event_set |= PHY_EVENT_REMOTE_FAULT;
+    }
+
+    if ( ( reg & 0x01 ) != 0 ) {
+      *event_set |= PHY_EVENT_LINK_UP;
+    }
+  }
+
+  return eno;
+}
+
+/** @brief Network PHY interrupt handler
+ *
+ * Handling method for interrupts from the PHY.
+ * @param arg Address of the network interface context
+ */
+static void network_if_phy_interrupt_handler( void *arg )
+{
+  int                 eno  = 0;
+  network_if_context *self = (network_if_context *) arg;
+  uint32_t            reg;
+
+  reg = alt_gpio_port_int_status_get( ALT_GPIO_PORTB );
+
+  if ( reg & NETWORK_PIN_MASK_PHY_INTERRUPT ) {
+    /* We have a level interrupt and we expect the driver to do
+     * the actual interrupt handling from within a task context.
+     * Thus we have to mask the interrupt. A call to
+     * network_if_phy_event_status_clear() will unmask it */
+    ALT_STATUS_CODE status_code = alt_gpio_port_int_mask_set(
+      ALT_GPIO_PORTB,
+      NETWORK_PIN_MASK_PHY_INTERRUPT,
+      NETWORK_PIN_MASK_PHY_INTERRUPT
+      );
+    eno = network_if_altera_status_code_to_errno( status_code );
+
+    if ( eno == 0 ) {
+      eno = dwmac_if_handle_phy_event(
+        self->driver_context
+        );
+    }
+  }
+
+  assert( eno == 0 );
+}
+
+/** @brief PHY event enable.
+ *
+ * Enables generation of events for an event set.
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @param[in] event_set   Set of events. For these events shall get generated
+ *                        upon PHY status change.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_phy_event_enable(
+  void                 *arg,
+  const dwmac_phy_event event_set )
+{
+  int                   eno        = 0;
+  uint16_t              reg        = 0;
+  network_if_context   *self       = (network_if_context *) arg;
+  network_if_phy_status old_status = self->phy.status;
+
+  if ( arg != NULL ) {
+    switch ( self->phy.status ) {
+      case NETWORK_IF_PHY_STATUS_OFF:
+        break;
+      case NETWORK_IF_PHY_STATUS_STOPPED:
+        break;
+      case NETWORK_IF_PHY_STATUS_STARTED:
+      {
+        eno = dwmac_if_read_from_phy(
+          self->driver_context,
+          0x1B,
+          &reg
+          );
+
+        if ( eno == 0 ) {
+          /* Disable all interrupts, but leave interrupt status 
+           * bits untouched */
+          reg &= 0x00FF;
+          eno  = dwmac_if_write_to_phy(
+            self->driver_context,
+            0x1B,
+            reg
+            );
+        }
+
+        if ( eno == 0 ) {
+          self->phy.irq_mask = 0;
+          self->phy.status   = NETWORK_IF_PHY_STATUS_STOPPED;
+        }
+      }
+      break;
+      case NETWORK_IF_PHY_STATUS_COUNT:
+      {
+        /* Invalid case */
+        assert( self->phy.status != NETWORK_IF_PHY_STATUS_COUNT );
+        eno = ENOTSUP;
+      }
+      break;
+      default:
+      {
+        /* Unknown case */
+        assert(
+          self->phy.status == NETWORK_IF_PHY_STATUS_OFF
+          || self->phy.status == NETWORK_IF_PHY_STATUS_STOPPED
+          || self->phy.status == NETWORK_IF_PHY_STATUS_STARTED
+          );
+        eno = ENOTSUP;
+      }
+      break;
+    }
+
+    if ( eno == 0 ) {
+      /* Select interrupts to enable */
+      if ( ( event_set & PHY_EVENT_JABBER ) != 0 ) {
+        reg |= 0x8000;
+      }
+
+      if ( ( event_set & PHY_EVENT_RECEIVE_ERROR ) != 0 ) {
+        reg |= 0x4000;
+      }
+
+      if ( ( event_set & PHY_EVENT_PAGE_RECEIVE ) != 0 ) {
+        reg |= 0x2000;
+      }
+
+      if ( ( event_set & PHY_EVENT_PARALLEL_DETECT_FAULT ) != 0 ) {
+        reg |= 0x1000;
+      }
+
+      if ( ( event_set & PHY_EVENT_LINK_PARTNER_ACK ) != 0 ) {
+        reg |= 0x0800;
+      }
+
+      if ( ( event_set & PHY_EVENT_LINK_DOWN ) != 0 ) {
+        reg |= 0x0400;
+      }
+
+      if ( ( event_set & PHY_EVENT_REMOTE_FAULT ) != 0 ) {
+        reg |= 0x0200;
+      }
+
+      if ( ( event_set & PHY_EVENT_LINK_UP ) != 0 ) {
+        reg |= 0x100;
+      }
+
+      switch ( old_status ) {
+        case NETWORK_IF_PHY_STATUS_OFF:
+          break;
+        case NETWORK_IF_PHY_STATUS_STOPPED:
+          break;
+        case NETWORK_IF_PHY_STATUS_STARTED:
+        {
+          if ( eno == 0 ) {
+            /* Modify interrupt enable bits, but leave
+             * interrupt status bits untouched */
+            eno = dwmac_if_write_to_phy(
+              self->driver_context,
+              0x1B,
+              reg & 0xFF00
+              );
+          }
+        }
+        break;
+        case NETWORK_IF_PHY_STATUS_COUNT:
+        {
+          /* Invalid case */
+          assert( self->phy.status != NETWORK_IF_PHY_STATUS_COUNT );
+          eno = ENOTSUP;
+        }
+        break;
+        default:
+        {
+          /* Unknown case */
+          assert(
+            self->phy.status == NETWORK_IF_PHY_STATUS_OFF
+            || self->phy.status == NETWORK_IF_PHY_STATUS_STOPPED
+            || self->phy.status == NETWORK_IF_PHY_STATUS_STARTED
+            );
+          eno = ENOTSUP;
+        }
+        break;
+      }
+
+      if ( eno == 0 ) {
+        self->phy.irq_mask = reg & 0xFF00;
+      }
+    }
+  }
+
+  return eno;
+}
+
+/**
+ * @brief Stop the network PHY.
+ *
+ * Do anything necessary to stop the network PHY (stop generating events, ...).
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_phy_stop( void *arg )
+{
+  int                 eno  = 0;
+  rtems_status_code   sc   = RTEMS_SUCCESSFUL;
+  network_if_context *self = (network_if_context *) arg;
+
+  switch ( self->phy.status ) {
+    case NETWORK_IF_PHY_STATUS_OFF:
+      break;
+    case NETWORK_IF_PHY_STATUS_STOPPED:
+      break;
+    case NETWORK_IF_PHY_STATUS_STARTED:
+    {
+      /* Remove any selected interrupts */
+      eno = dwmac_if_write_to_phy(
+        self->driver_context,
+        0x1B,
+        0
+        );
+
+      if ( eno == 0 ) {
+        uint16_t reg;
+
+        /* Clear interrupt status bits by reading them */
+        eno = dwmac_if_read_from_phy(
+          self->driver_context,
+          0x1B,
+          &reg
+          );
+      }
+
+      if ( eno == 0 ) {
+        self->phy.irq_mask = 0;
+
+        /* Remove interrupt handler */
+        sc = rtems_interrupt_handler_remove(
+          ALT_INT_INTERRUPT_GPIO1,
+          network_if_phy_interrupt_handler,
+          self
+          );
+        eno = rtems_status_code_to_errno( sc );
+
+        if ( eno == 0 ) {
+          self->phy.status = NETWORK_IF_PHY_STATUS_STOPPED;
+        }
+      }
+    }
+    break;
+    case NETWORK_IF_PHY_STATUS_COUNT:
+    {
+      /* Invalid case */
+      assert( self->phy.status != NETWORK_IF_PHY_STATUS_COUNT );
+      eno = ENOTSUP;
+    }
+    break;
+    default:
+    {
+      /* Unknown case */
+      assert(
+        self->phy.status == NETWORK_IF_PHY_STATUS_OFF
+        || self->phy.status == NETWORK_IF_PHY_STATUS_STOPPED
+        || self->phy.status == NETWORK_IF_PHY_STATUS_STARTED
+        );
+      eno = ENOTSUP;
+    }
+    break;
+  }
+
+  return eno;
+}
+
+/**
+ * @brief Start the network PHY.
+ *
+ * Do anything necessary to start the network PHY (start generating
+ * events, ...).
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_phy_start( void *arg )
+{
+  int                 eno  = 0;
+  rtems_status_code   sc   = RTEMS_SUCCESSFUL;
+  network_if_context *self = (network_if_context *) arg;
+
+  switch ( self->phy.status ) {
+    case NETWORK_IF_PHY_STATUS_OFF:
+    {
+      assert( self->phy.status != NETWORK_IF_PHY_STATUS_OFF );
+      eno = EHOSTDOWN;
+    }
+    break;
+    case NETWORK_IF_PHY_STATUS_STOPPED:
+
+      /* Disable all interrupts */
+      eno = dwmac_if_write_to_phy(
+        self->driver_context,
+        0x1B,
+        0
+        );
+
+      if ( eno == 0 ) {
+      }
+
+      if ( eno == 0 ) {
+        /* Install interrupt handler */
+        sc = rtems_interrupt_handler_install(
+          ALT_INT_INTERRUPT_GPIO1,
+          NULL,
+          RTEMS_INTERRUPT_SHARED,
+          network_if_phy_interrupt_handler,
+          self
+          );
+        eno = rtems_status_code_to_errno( sc );
+      }
+
+      if ( eno == 0 ) {
+        /* Enable interrupts */
+        eno = dwmac_if_write_to_phy(
+          self->driver_context,
+          0x1B,
+          self->phy.irq_mask
+          );
+      }
+
+      break;
+    case NETWORK_IF_PHY_STATUS_STARTED:
+    {
+      uint16_t irq_mask = self->phy.irq_mask;
+
+      /* Re-start the phy */
+      eno = network_if_phy_stop( self );
+
+      if ( eno == 0 ) {
+        self->phy.irq_mask = irq_mask;
+
+        eno                = network_if_phy_start(
+          self
+          );
+      }
+    }
+    break;
+
+    case NETWORK_IF_PHY_STATUS_COUNT:
+    {
+      /* Invalid case */
+      assert( self->phy.status != NETWORK_IF_PHY_STATUS_COUNT );
+      eno = ENOTSUP;
+    }
+    break;
+    default:
+    {
+      /* Unknown case */
+      assert(
+        self->phy.status == NETWORK_IF_PHY_STATUS_OFF
+        || self->phy.status == NETWORK_IF_PHY_STATUS_STOPPED
+        || self->phy.status == NETWORK_IF_PHY_STATUS_STARTED
+        );
+      eno = ENOTSUP;
+    }
+    break;
+  }
+
+  if ( eno == 0 ) {
+    self->phy.status = NETWORK_IF_PHY_STATUS_STARTED;
+  }
+
+  return eno;
+}
+
+/**
+ * @brief Allocate nocache RAM.
+ *
+ * Allocate uncached RAM.
+ * @param[in]  arg        The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @param[out] memory     Pointer of a buffer to write the address of the
+ *                        allocated memory to.
+ * @param[in]  size       Number of bytes to be allocated
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_mem_alloc_nocache(
+  void        *arg,
+  void       **memory,
+  const size_t size )
+{
+  int eno = EINVAL;
+
+  (void) arg;
+
+  assert( memory != NULL );
+
+  if ( memory != NULL ) {
+    *memory = altera_cyclone_v_nocache_malloc( size );
+
+    if ( *memory != NULL ) {
+      eno = 0;
+    } else {
+      eno = ENOMEM;
+    }
+  }
+
+  return eno;
+}
+
+/**
+ * @brief Free nocache RAM.
+ *
+ * Release uncached RAM.
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @param[in] memory      Pointer to the memory to be freed.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_mem_free_nocache(
+  void *arg,
+  void *memory )
+{
+  int eno = EINVAL;
+
+  (void) arg;
+
+  assert( memory != NULL );
+
+  if ( memory != NULL ) {
+    altera_cyclone_v_nocache_free( memory );
+    eno = 0;
+  }
+
+  return eno;
+}
+
+/**
+ * @brief Bus setup.
+ *
+ * Callback method for setting up the system bus for the network driver.
+ * @param[in] arg         The void pointer argument passed to
+ *                        dwmac_network_if_attach_detach.
+ * @retval 0 on success, error code from errno.h on failure.
+ */
+static int network_if_bus_setup( void *arg )
+{
+  (void) arg;
+
+  /* Nothing to be done */
+  return 0;
+}
+
+/*****************************************************************************
+* Context Data
+******************************************************************************/
+
+/** @brief Network interface context */
+static network_if_context context = NETWORK_IF_CONTEXT_INITIALIZER(
+
+  /** @brief Use EMAC1 */
+  NETWORK_IF_NIC_ID_EMAC1,
+
+  /** @brief Address of driver context
+   *
+   * To be assigned with return value of dwmac_network_if_attach_detach */
+  NULL
+  );
+
+/** @brief Network driver DMA configuration data */
+static const dwmac_dma_cfg NETWORK_DMA_CFG = DWMAC_DMA_CFG_INITIALIZER(
+
+  /** @brief Bus mode burst length */
+  DWMAC_DMA_CFG_BUS_MODE_BURST_LENGTH_64,
+
+  /** @brief Bus mode fixed burst? */
+  DWMAC_DMA_CFG_BUS_MODE_BURST_MODE_SINGLE_OR_INCR,
+
+  /** @brief Bus mode mixed burst? */
+  DWMAC_DMA_CFG_BUS_MODE_BURST_NOT_MIXED,
+
+  /** @brief Permit AXI burst length of 4 */
+  DWMAC_DMA_CFG_AXI_BURST_LENGTH_4_NOT_SUPPORTED,
+
+  /** @brief Permit AXI burst length of 8 */
+  DWMAC_DMA_CFG_AXI_BURST_LENGTH_8_NOT_SUPPORTED,
+
+  /** @brief Permit AXI burst length of 16 */
+  DWMAC_DMA_CFG_AXI_BURST_LENGTH_16_NOT_SUPPORTED,
+
+  /** @brief Select boundary crossing mode */
+  DWMAC_DMA_CFG_AXI_BURST_BOUNDARY_4_KB
+  );
+
+/** @brief Network driver configuration data */
+static const dwmac_cfg NETWORK_DRIVER_CFG = DWMAC_CFG_INITIALIZER(
+
+  /** @brief GMII clock rate */
+  75000000,
+
+  /** @brief Address of the GMAC registers for emac1 */
+  ALT_EMAC1_GMACGRP_ADDR,
+
+  /** @brief Address of the DMA registers for emac1 */
+  ALT_EMAC1_DMAGRP_ADDR,
+
+  /** @brief Address of the PHY on the mdio bus */
+  4,
+
+  /** @brief Bytes per L1 cache line */
+  32,
+
+  /** @brief Interrupt number for the EMAC */
+  ALT_INT_INTERRUPT_EMAC1_IRQ,
+
+  /** @brief DMA configuration */
+  &NETWORK_DMA_CFG,
+
+  /** @brief Callback method for enabling the network controller */
+  network_if_nic_enable,
+
+  /** @brief Callback method for disabling the network controller */
+  network_if_nic_disable,
+
+  /** @brief Callback method for enabling the PHY */
+  network_if_phy_enable,
+
+  /** @brief Callback method for disabling the PHY */
+  network_if_phy_disable,
+
+  /** @brief Callback which enables PHY events for forwarding to driver */
+  network_if_phy_event_enable,
+
+  /** @brief Callback method for clearing PHY interrupt status */
+  network_if_phy_event_status_clear,
+
+  /** @brief Callback method for getting a set of events from the PHY */
+  network_if_phy_events_status_get,
+
+  /** @brief Callback method for making the PHY start forwarding events */
+  network_if_phy_start,
+
+  /** @brief Callback method for making the PHY stop forwarding events */
+  network_if_phy_stop,
+
+  /** @brief Callback method for allocating uncached memory */
+  network_if_mem_alloc_nocache,
+
+  /** @brief Callback method for freeing uncached memory */
+  network_if_mem_free_nocache,
+
+  /** @brief Callback method for setting up bus upon driver startup */
+  network_if_bus_setup,
+
+  /** @brief Operations for the ethernet mac 1000 */
+  &DWMAC_1000_ETHERNET_MAC_OPS,
+
+  /** @brief Operations for the enhanced DMA descriptors */
+  &DWMAC_DESCRIPTOR_OPS_ENHANCED
+  );
+
+/******************************************************************************
+* API
+******************************************************************************/
+
+/** @brief Network interface attach/detach
+ *
+ * The standard attach/detach method for network interfaces.
+ * This methods will call the DWMAC 1000 attach/detach method and pass
+ * configuration data and callback methods into it. Via these  the general
+ * DWMAC 1000 driver is able the handle micro controller specific things.
+ * NOTE: Detaching is NOT supported!
+ * @param config    Configuration parameters from and for the BSD network
+ *                  stack.
+ * @param attaching True if attaching the driver to the network stack, false if
+ *                  detaching.
+ * @retval 0 if successful, error code from errno.h if not.
+ */
+int altera_cyclone_v_network_if_attach_detach(
+  struct rtems_bsdnet_ifconfig *config,
+  int                           attaching )
+{
+  int eno = 0;
+
+  assert( config != NULL );
+
+  /* Network controller initialization */
+  context.driver_context = dwmac_network_if_attach_detach(
+    config,
+    &NETWORK_DRIVER_CFG,
+    &context,
+    attaching
+    );
+
+  if ( context.driver_context == NULL ) {
+    eno = EFAULT;
+  }
+
+  return eno;
+}
+
+#endif /* defined(RTEMS_NETWORKING) */
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/preinstall.am b/c/src/lib/libbsp/arm/altera-cyclone-v/preinstall.am
new file mode 100644
index 0000000..3f83665
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/preinstall.am
@@ -0,0 +1,200 @@
+## 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-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES = $(TMPINSTALL_FILES)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES += $(PREINSTALL_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_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/tod.h: ../../shared/tod.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/tod.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/tod.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-clock.h: ../shared/include/arm-a9mpcore-clock.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-a9mpcore-clock.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-a9mpcore-clock.h
+
+$(PROJECT_INCLUDE)/bsp/arm-a9mpcore-irq.h: ../shared/include/arm-a9mpcore-irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/arm-a9mpcore-irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/arm-a9mpcore-irq.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)/bsp/nocache-heap.h: include/nocache-heap.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/nocache-heap.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/nocache-heap.h
+
+$(PROJECT_INCLUDE)/bsp/alt_address_space.h: hwlib/include/alt_address_space.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_address_space.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_address_space.h
+
+$(PROJECT_INCLUDE)/bsp/alt_clock_group.h: hwlib/include/alt_clock_group.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_clock_group.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_clock_group.h
+
+$(PROJECT_INCLUDE)/bsp/alt_clock_manager.h: hwlib/include/alt_clock_manager.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_clock_manager.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_clock_manager.h
+
+$(PROJECT_INCLUDE)/bsp/alt_generalpurpose_io.h: hwlib/include/alt_generalpurpose_io.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_generalpurpose_io.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_generalpurpose_io.h
+
+$(PROJECT_INCLUDE)/bsp/alt_hwlibs_ver.h: hwlib/include/alt_hwlibs_ver.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_hwlibs_ver.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_hwlibs_ver.h
+
+$(PROJECT_INCLUDE)/bsp/alt_interrupt_common.h: hwlib/include/alt_interrupt_common.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_interrupt_common.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_interrupt_common.h
+
+$(PROJECT_INCLUDE)/bsp/alt_mpu_registers.h: hwlib/include/alt_mpu_registers.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_mpu_registers.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_mpu_registers.h
+
+$(PROJECT_INCLUDE)/bsp/alt_reset_manager.h: hwlib/include/alt_reset_manager.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/alt_reset_manager.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/alt_reset_manager.h
+
+$(PROJECT_INCLUDE)/bsp/hwlib.h: hwlib/include/hwlib.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/hwlib.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/hwlib.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_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.altcycv: startup/linkcmds.altcycv $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.altcycv
+TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds.altcycv
+
+$(PROJECT_LIB)/linkcmds.altcycv_devkit: startup/linkcmds.altcycv_devkit $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.altcycv_devkit
+TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds.altcycv_devkit
+
+$(PROJECT_LIB)/linkcmds.altcycv_devkit_smp: startup/linkcmds.altcycv_devkit_smp $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.altcycv_devkit_smp
+TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds.altcycv_devkit_smp
+
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/startup/bspreset.c b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/bspreset.c
new file mode 100644
index 0000000..65e8624
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/bspreset.c
@@ -0,0 +1,37 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#include <bsp/bootcard.h>
+#include <bsp/alt_reset_manager.h>
+#include "socal/alt_rstmgr.h"
+#include "socal/hps.h"
+
+void bsp_reset(void)
+{
+  uint32_t           self_cpu  = rtems_smp_get_current_processor();
+  volatile uint32_t *mpumodrst = ALT_RSTMGR_MPUMODRST_ADDR;
+  
+  if( self_cpu == 0 ) {
+    /* Reset CPU1 */
+    (*mpumodrst) |= ALT_RSTMGR_MPUMODRST_CPU1_SET_MSK;
+    
+    /* Simply call the reset method from alteras HWLIB */
+    (void) alt_reset_cold_reset();
+  } else {
+    /* Keep CPU1 waiting until it gets reset by CPU0 */
+    while ( true ) {
+      __asm__ volatile ("wfi");
+    }
+  }
+}
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/startup/bspstart.c b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/bspstart.c
new file mode 100644
index 0000000..abdcbfd
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/bspstart.c
@@ -0,0 +1,69 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/start.h>
+#include <bsp/nocache-heap.h>
+#include <rtems/config.h>
+#include "socal/alt_rstmgr.h"
+#include "socal/alt_sysmgr.h"
+#include "socal/hps.h"
+
+#ifndef MIN
+#define MIN( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) )
+#endif
+
+#define BSPSTART_MAX_CORES_PER_CONTROLLER 2
+
+static void bsp_start_secondary_cores( void )
+{
+#ifdef RTEMS_SMP
+  volatile uint32_t *mpumodrst       = ALT_RSTMGR_MPUMODRST_ADDR;
+  uint32_t          *cpu1_start_addr = (
+    ALT_SYSMGR_ROMCODE_ADDR + ALT_SYSMGR_ROMCODE_CPU1STARTADDR_OFST );
+  const uint32_t     CORES           = MIN(
+    (uintptr_t) bsp_processor_count,
+    rtems_configuration_get_maximum_processors() );
+  unsigned int       index;
+
+
+  /* Memory would get overwritten if a too small processor count
+   * would be specified */
+  assert( 
+    (uintptr_t) bsp_processor_count >= BSPSTART_MAX_CORES_PER_CONTROLLER );
+
+  if ( (uintptr_t) bsp_processor_count >= BSPSTART_MAX_CORES_PER_CONTROLLER ) {
+    for ( index = 1; index < CORES; ++index ) {
+      /* set the start address from where the core will execute */
+      (*cpu1_start_addr) = ALT_SYSMGR_ROMCODE_CPU1STARTADDR_VALUE_SET(
+        (uintptr_t) _start );
+
+      /* Make the core finish it's reset */
+      (*mpumodrst) &= ~ALT_RSTMGR_MPUMODRST_CPU1_SET_MSK;
+    }
+  }
+#endif /* #ifdef RTEMS_SMP */
+}
+
+void bsp_start( void )
+{
+  bsp_interrupt_initialize();
+  altera_cyclone_v_nocache_init_heap();
+  bsp_start_secondary_cores();
+}
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/startup/bspstarthooks.c b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/bspstarthooks.c
new file mode 100644
index 0000000..c8266a5
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/bspstarthooks.c
@@ -0,0 +1,204 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/arm-a9mpcore-start.h>
+#include <bsp/linker-symbols.h>
+#include <alt_address_space.h>
+#include "socal/socal.h"
+#include "socal/alt_sdr.h"
+#include "socal/hps.h"
+#include "../include/arm-cache-l1.h"
+
+/*#define DEBUG_ECC_ERROR*/ /* TODO: Delete DEBUG_ECC_ERROR after the implementation phase */
+
+#ifdef RTEMS_SMP
+  #define MMU_DATA_READ_WRITE ARMV7_MMU_DATA_READ_WRITE_SHAREABLE
+#else
+  #define MMU_DATA_READ_WRITE ARMV7_MMU_DATA_READ_WRITE_CACHED
+#endif
+
+/* 1 MB reset default value for address filtering start */
+#define BSPSTART_L2_CACHE_ADDR_FILTERING_START_RESET 0x100000
+
+#ifndef BSPSTARTHOOKS_MIN
+#define BSPSTARTHOOKS_MIN( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) )
+#endif
+
+LINKER_SYMBOL( bsp_section_nocache_size );
+LINKER_SYMBOL( bsp_section_nocache_end );
+LINKER_SYMBOL( bsp_section_nocache_begin );
+
+BSP_START_DATA_SECTION static const arm_cp15_start_section_config
+  altcycv_mmu_config_table[] = {
+  ARMV7_CP15_START_DEFAULT_SECTIONS,
+  {
+    .begin = (uint32_t) bsp_section_nocache_begin,
+    .end   = (uint32_t) bsp_section_nocache_end,
+
+    .flags = ARMV7_MMU_DATA_READ_WRITE | ARM_MMU_SECT_TEX_0
+  }, { /* Periphery area */
+    .begin = 0xFC000000U,
+    .end   = 0x00000000U,
+    .flags = ARMV7_MMU_DEVICE
+  }
+};
+
+BSP_START_TEXT_SECTION static void setup_mmu_and_cache( const uint32_t CPU_ID )
+{
+  uint32_t       ctrl  = arm_cp15_get_control();
+  const uint32_t CORES = BSPSTARTHOOKS_MIN(
+    (uintptr_t) bsp_processor_count,
+    rtems_configuration_get_maximum_processors() );
+
+  /* We expect the L1 caches and program flow prediction to be off */
+  assert( ( ctrl & ARM_CP15_CTRL_I ) == 0 );
+  assert( ( ctrl & ARM_CP15_CTRL_C ) == 0 );
+  assert( ( ctrl & ARM_CP15_CTRL_Z ) == 0 );
+
+  ctrl = arm_cp15_start_setup_mmu_and_cache(
+    ARM_CP15_CTRL_A | ARM_CP15_CTRL_M,
+    ARM_CP15_CTRL_AFE
+    );
+
+  if( CPU_ID == 0 ) {
+    arm_cp15_start_setup_translation_table(
+      (uint32_t *) bsp_translation_table_base,
+      ARM_MMU_DEFAULT_CLIENT_DOMAIN,
+      &altcycv_mmu_config_table[0],
+      RTEMS_ARRAY_SIZE( altcycv_mmu_config_table )
+    );
+  } else {
+    /* FIXME: Sharing the translation table between processors is brittle */
+    arm_cp15_set_translation_table_base((uint32_t *) bsp_translation_table_base);
+  }
+
+  /* Enable MMU */
+  ctrl |= ARM_CP15_CTRL_M;
+
+  arm_cp15_set_control( ctrl );
+  
+  if( CPU_ID == (CORES - 1) ) {
+    /* Enable all cache levels for the last core */
+    rtems_cache_enable_instruction();
+    rtems_cache_enable_data();
+  } else {
+    /* Enable only L1 cache */
+    arm_cache_l1_enable_data();
+    arm_cache_l1_enable_instruction();
+  }
+
+  /* Enable flow control prediction aka. branch prediction */
+
+/* TODO: With the current network stack 06-Feb2014 in_checksum()
+ * becomes a severe performance bottle neck with branch prediction enabled
+   ctrl |= ARM_CP15_CTRL_Z;
+   arm_cp15_set_control(ctrl);*/
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0( void )
+{
+  uint32_t ctrl;
+  volatile a9mpcore_scu *scu    = (volatile a9mpcore_scu *) BSP_ARM_A9MPCORE_SCU_BASE;
+  uint32_t               cpu_id = arm_cortex_a9_get_multiprocessor_cpu_id();
+  const uint32_t         CORES  = BSPSTARTHOOKS_MIN(
+    (uintptr_t) bsp_processor_count,
+    rtems_configuration_get_maximum_processors() );
+  
+  assert( cpu_id < CORES );
+  
+  if( cpu_id < CORES ) {
+    if( cpu_id == 0 ) {
+      ctrl = arm_cp15_mmu_disable( 32 );
+
+      ctrl &= ~( ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_Z );
+      arm_cp15_set_control( ctrl );
+      
+      /* Enable Snoop Control Unit (SCU) */
+      arm_a9mpcore_start_scu_enable( scu );
+    }
+
+#ifdef RTEMS_SMP
+    /* Enable cache coherency support for this processor */
+    uint32_t actlr = arm_cp15_get_auxiliary_control();
+    actlr |= ARM_CORTEX_A9_ACTL_SMP;
+    arm_cp15_set_auxiliary_control(actlr);
+#endif
+
+    if (cpu_id == 0) {
+      arm_a9mpcore_start_scu_invalidate(scu, cpu_id, 0xF);
+    }
+    
+    setup_mmu_and_cache( cpu_id );
+    
+#ifdef RTEMS_SMP
+    if (cpu_id != 0) {
+      arm_a9mpcore_start_set_vector_base();
+
+      arm_gic_irq_initialize_secondary_cpu();
+
+      arm_cp15_set_domain_access_control(
+        ARM_CP15_DAC_DOMAIN(ARM_MMU_DEFAULT_CLIENT_DOMAIN, ARM_CP15_DAC_CLIENT)
+      );
+      _SMP_Start_multitasking_on_secondary_processor();
+    }
+#endif
+  } else {
+    /* FIXME: Shutdown processor */
+    while (1) {
+      __asm__ volatile ("wfi");
+    }
+  }
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1( void )
+{
+  uint32_t addr_filt_start;
+  uint32_t addr_filt_end;
+
+  /* Disable ECC. Preloader respectively UBoot enable ECC.
+     But they do run without interrupts. Our BSP will enable interrupts
+     and get spurious ECC error interrupts. Thus we disasable ECC
+     until we either know about a better handling or Altera has modified
+     it's SDRAM settings to not create possibly false ECC errors */
+  uint32_t ctlcfg = alt_read_word( ALT_SDR_CTL_CTLCFG_ADDR );
+  ctlcfg &= ALT_SDR_CTL_CTLCFG_ECCEN_CLR_MSK;
+  alt_write_word( ALT_SDR_CTL_CTLCFG_ADDR, ctlcfg );
+
+  /* Perform L3 remap register programming first by setting the desired new MPU
+     address space 0 mapping. Assume BOOTROM in order to be able to boot the
+     second core. */
+  alt_addr_space_remap(
+    ALT_ADDR_SPACE_MPU_ZERO_AT_BOOTROM,
+    ALT_ADDR_SPACE_NONMPU_ZERO_AT_SDRAM,
+    ALT_ADDR_SPACE_H2F_ACCESSIBLE,
+    ALT_ADDR_SPACE_LWH2F_ACCESSIBLE );
+
+  /* Next, adjust the L2 cache address filtering range. Set the start address
+   * to the default reset value and retain the existing end address
+   * configuration. */
+  alt_l2_addr_filter_cfg_get( &addr_filt_start, &addr_filt_end );
+
+  if ( addr_filt_start != BSPSTART_L2_CACHE_ADDR_FILTERING_START_RESET ) {
+    alt_l2_addr_filter_cfg_set( BSPSTART_L2_CACHE_ADDR_FILTERING_START_RESET,
+                                addr_filt_end );
+  }
+
+  arm_a9mpcore_start_hook_1();
+  bsp_start_copy_sections();
+
+  bsp_start_clear_bss();
+}
\ No newline at end of file
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/startup/linkcmds.altcycv b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/linkcmds.altcycv
new file mode 100644
index 0000000..da4275f
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/linkcmds.altcycv
@@ -0,0 +1,26 @@
+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);
+
+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);
+
+INCLUDE linkcmds.armv4
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/startup/linkcmds.altcycv_devkit b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/linkcmds.altcycv_devkit
new file mode 100644
index 0000000..60f99a0
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/linkcmds.altcycv_devkit
@@ -0,0 +1,18 @@
+MEMORY {
+   RAM_MMU : ORIGIN = 0x00100000, LENGTH = 16k
+   NOCACHE : ORIGIN = 0x00200000, LENGTH = 1M
+   RAM     : ORIGIN = 0x00300000, LENGTH = 1024M - 1M - 1M - 1M
+}
+
+SECTIONS {
+  .nocache : {
+    bsp_section_nocache_begin = .;
+    *(SORT(.bsp_nocache*))
+    bsp_section_nocache_end = .;
+  } > NOCACHE AT > NOCACHE
+  bsp_section_nocache_size = bsp_section_nocache_end - bsp_section_nocache_begin;
+  bsp_section_nocache_load_begin = LOADADDR (.nocache);
+  bsp_section_nocache_load_end = bsp_section_nocache_load_begin + bsp_section_nocache_size;
+}
+
+INCLUDE linkcmds.altcycv
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/startup/linkcmds.altcycv_devkit_smp b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/linkcmds.altcycv_devkit_smp
new file mode 100644
index 0000000..2da0865
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/linkcmds.altcycv_devkit_smp
@@ -0,0 +1,3 @@
+bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 2;
+
+INCLUDE linkcmds.altcycv_devkit
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/startup/nocache-heap.c b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/nocache-heap.c
new file mode 100644
index 0000000..0f01989
--- /dev/null
+++ b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/nocache-heap.c
@@ -0,0 +1,89 @@
+/**
+ * @file
+ *
+ * @brief Heap handling for uncached RAM
+ */
+
+/*
+ * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <assert.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/nocache-heap.h>
+#include <rtems/score/heapimpl.h>
+#include <rtems/score/apimutex.h>
+
+/** @brief Uncached RAM pool
+ *
+ * Allocate the whole bsp_nocache for the nocache heap */
+static char nocache_pool[1024
+                         * 1024] __attribute__( ( section( ".bsp_nocache" ) ) );
+
+/** @brief Nocache heap
+ *
+ * Heap control for the uncached RAM heap */
+static Heap_Control nocache_heap;
+
+/** @brief Init nocache heap
+ *
+ * Constructor for the uncached RAM heap
+ * @returns 0 on succuss, error code from errno.h on failure
+ */
+void altera_cyclone_v_nocache_init_heap( void )
+{
+  uintptr_t heap_status = 0;
+
+  heap_status = _Heap_Initialize(
+    &nocache_heap,
+    &nocache_pool[0],
+    sizeof( nocache_pool ),
+    0
+    );
+  assert( heap_status != 0 );
+}
+
+/** @brief Allocate uncached RAM
+ *
+ * Allocates RAM from the uncached heap
+ * @param size  Number of bytes to be allocated
+ * @returns  Pointer to the allocated RAM
+ */
+void *altera_cyclone_v_nocache_malloc( const size_t size )
+{
+  void* ret = NULL;
+
+  _RTEMS_Lock_allocator();
+  ret = _Heap_Allocate( &nocache_heap, size );
+  _RTEMS_Unlock_allocator();
+
+  return ret;
+}
+
+/** @brief Free uncached RAM
+ *
+ * Releases RAM from the uncached heap
+ * @param ptr Address of the RAM to be released
+ */
+void altera_cyclone_v_nocache_free( void *ptr )
+{
+  if ( ptr != NULL ) {
+    bool ok;
+
+    _RTEMS_Lock_allocator();
+    ok = _Heap_Free( &nocache_heap, ptr );
+    _RTEMS_Unlock_allocator();
+
+    assert( ok );
+  }
+}




More information about the vc mailing list