summaryrefslogtreecommitdiffstats
path: root/bsps/arm
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 10:35:35 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 13:52:14 +0200
commit99648958668d3a33ee57974479b36201fe303f34 (patch)
tree6f27ea790e2823c6156e71219a4f54680263fac6 /bsps/arm
parentbsps: Move start files to bsps (diff)
downloadrtems-99648958668d3a33ee57974479b36201fe303f34.tar.bz2
bsps: Move startup files to bsps
Adjust build support files to new directory layout. This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'bsps/arm')
-rw-r--r--bsps/arm/altera-cyclone-v/start/bsp_specs9
-rw-r--r--bsps/arm/altera-cyclone-v/start/bspclean.c43
-rw-r--r--bsps/arm/altera-cyclone-v/start/bspgetworkarea.c175
-rw-r--r--bsps/arm/altera-cyclone-v/start/bspreset.c21
-rw-r--r--bsps/arm/altera-cyclone-v/start/bspsmp.c49
-rw-r--r--bsps/arm/altera-cyclone-v/start/bspstart.c104
-rw-r--r--bsps/arm/altera-cyclone-v/start/bspstarthooks.c94
-rw-r--r--bsps/arm/altera-cyclone-v/start/linkcmds.altcycv29
-rw-r--r--bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit7
-rw-r--r--bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit_smp3
-rw-r--r--bsps/arm/altera-cyclone-v/start/mmu-config.c27
-rw-r--r--bsps/arm/atsam/start/bsp_specs9
-rw-r--r--bsps/arm/atsam/start/bspstart.c37
-rw-r--r--bsps/arm/atsam/start/bspstarthooks.c156
-rw-r--r--bsps/arm/atsam/start/getentropy-trng.c61
-rw-r--r--bsps/arm/atsam/start/linkcmds21
-rw-r--r--bsps/arm/atsam/start/linkcmds.intsram23
-rw-r--r--bsps/arm/atsam/start/linkcmds.memory.in39
-rw-r--r--bsps/arm/atsam/start/linkcmds.qspiflash21
-rw-r--r--bsps/arm/atsam/start/linkcmds.sdram21
-rw-r--r--bsps/arm/atsam/start/pin-config.c42
-rw-r--r--bsps/arm/atsam/start/pmc-config.c47
-rw-r--r--bsps/arm/atsam/start/power-clock.c44
-rw-r--r--bsps/arm/atsam/start/power-rtc.c104
-rw-r--r--bsps/arm/atsam/start/power.c102
-rw-r--r--bsps/arm/atsam/start/restart.c39
-rw-r--r--bsps/arm/atsam/start/sdram-config.c136
-rw-r--r--bsps/arm/beagle/start/bsp_specs9
-rw-r--r--bsps/arm/beagle/start/bspreset.c42
-rw-r--r--bsps/arm/beagle/start/bspstart.c35
-rw-r--r--bsps/arm/beagle/start/bspstarthooks.c32
-rw-r--r--bsps/arm/beagle/start/bspstartmmu.c58
-rw-r--r--bsps/arm/beagle/start/linkcmds.beagle48
-rw-r--r--bsps/arm/csb336/start/bsp_specs9
-rw-r--r--bsps/arm/csb336/start/bspstart.c122
-rw-r--r--bsps/arm/csb336/start/linkcmds27
-rw-r--r--bsps/arm/csb336/start/memmap.c35
-rw-r--r--bsps/arm/csb337/start/bsp_specs9
-rw-r--r--bsps/arm/csb337/start/bspreset.c31
-rw-r--r--bsps/arm/csb337/start/bspstart.c158
-rw-r--r--bsps/arm/csb337/start/linkcmds.csb33727
-rw-r--r--bsps/arm/csb337/start/linkcmds.csb63727
-rw-r--r--bsps/arm/csb337/start/memmap.c50
-rw-r--r--bsps/arm/csb337/start/pmc.c96
-rw-r--r--bsps/arm/csb337/start/umonsupp.c25
-rw-r--r--bsps/arm/edb7312/start/bsp_specs9
-rw-r--r--bsps/arm/edb7312/start/bspreset.c22
-rw-r--r--bsps/arm/edb7312/start/bspstart.c45
-rw-r--r--bsps/arm/edb7312/start/linkcmds25
-rw-r--r--bsps/arm/gdbarmsim/start/bsp_specs9
-rw-r--r--bsps/arm/gdbarmsim/start/bspreset.c17
-rw-r--r--bsps/arm/gdbarmsim/start/bspstart.c22
-rw-r--r--bsps/arm/gdbarmsim/start/bspstarthooks.c20
-rw-r--r--bsps/arm/gdbarmsim/start/linkcmds23
-rw-r--r--bsps/arm/gdbarmsim/start/syscalls.c763
-rw-r--r--bsps/arm/gumstix/start/bsp_specs9
-rw-r--r--bsps/arm/gumstix/start/bspreset.c18
-rw-r--r--bsps/arm/gumstix/start/bspstart.c40
-rw-r--r--bsps/arm/gumstix/start/linkcmds27
-rw-r--r--bsps/arm/gumstix/start/memmap.c17
-rw-r--r--bsps/arm/imx/start/bsp_specs9
-rw-r--r--bsps/arm/imx/start/bspreset.c33
-rw-r--r--bsps/arm/imx/start/bspsmp.c47
-rw-r--r--bsps/arm/imx/start/bspstart.c92
-rw-r--r--bsps/arm/imx/start/bspstarthooks.c67
-rw-r--r--bsps/arm/imx/start/ccm.c33
-rw-r--r--bsps/arm/imx/start/imx_iomux.c424
-rw-r--r--bsps/arm/imx/start/linkcmds.imx737
-rw-r--r--bsps/arm/lm3s69xx/start/bsp_specs9
-rw-r--r--bsps/arm/lm3s69xx/start/bspstart.c155
-rw-r--r--bsps/arm/lm3s69xx/start/bspstarthook.c29
-rw-r--r--bsps/arm/lm3s69xx/start/io.c144
-rw-r--r--bsps/arm/lm3s69xx/start/linkcmds.lm3s374930
-rw-r--r--bsps/arm/lm3s69xx/start/linkcmds.lm3s696530
-rw-r--r--bsps/arm/lm3s69xx/start/linkcmds.lm3s6965_qemu30
-rw-r--r--bsps/arm/lm3s69xx/start/linkcmds.lm4f12030
-rw-r--r--bsps/arm/lm3s69xx/start/syscon.c115
-rw-r--r--bsps/arm/lpc176x/start/bsp_specs9
-rw-r--r--bsps/arm/lpc176x/start/bspstart.c91
-rw-r--r--bsps/arm/lpc176x/start/bspstarthooks.c227
-rw-r--r--bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed29
-rw-r--r--bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed_ahb_ram30
-rw-r--r--bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed_ahb_ram_eth41
-rw-r--r--bsps/arm/lpc24xx/start/bsp_specs9
-rw-r--r--bsps/arm/lpc24xx/start/bspreset-armv4.c51
-rw-r--r--bsps/arm/lpc24xx/start/bspstart.c96
-rw-r--r--bsps/arm/lpc24xx/start/bspstarthooks.c533
-rw-r--r--bsps/arm/lpc24xx/start/fb-config.c133
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc17xx_ea_ram27
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc17xx_ea_rom_int27
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc17xx_plx800_ram33
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc17xx_plx800_rom_int33
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc236270
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc23xx_tli80074
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ea59
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_ram60
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_rom_ext64
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_rom_int64
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc24xx_plx800_ram32
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc24xx_plx800_rom_int32
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc40xx_ea_ram1
-rw-r--r--bsps/arm/lpc24xx/start/linkcmds.lpc40xx_ea_rom_int1
-rw-r--r--bsps/arm/lpc24xx/start/start-config-emc-dynamic.c271
-rw-r--r--bsps/arm/lpc24xx/start/start-config-emc-static.c133
-rw-r--r--bsps/arm/lpc24xx/start/start-config-mpu.c86
-rw-r--r--bsps/arm/lpc24xx/start/start-config-pinsel.c74
-rw-r--r--bsps/arm/lpc32xx/start/bsp_specs9
-rw-r--r--bsps/arm/lpc32xx/start/bspreset.c48
-rw-r--r--bsps/arm/lpc32xx/start/bspstart.c38
-rw-r--r--bsps/arm/lpc32xx/start/bspstarthooks.c240
-rw-r--r--bsps/arm/lpc32xx/start/linkcmds.lpc32xx17
-rw-r--r--bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx69
-rw-r--r--bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx_stage_168
-rw-r--r--bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx_stage_267
-rw-r--r--bsps/arm/lpc32xx/start/linkcmds.lpc32xx_phycore68
-rw-r--r--bsps/arm/raspberrypi/start/bsp_specs9
-rw-r--r--bsps/arm/raspberrypi/start/bspgetworkarea.c78
-rw-r--r--bsps/arm/raspberrypi/start/bspreset.c26
-rw-r--r--bsps/arm/raspberrypi/start/bspsmp.c83
-rw-r--r--bsps/arm/raspberrypi/start/bspsmp_init.c81
-rw-r--r--bsps/arm/raspberrypi/start/bspstart.c29
-rw-r--r--bsps/arm/raspberrypi/start/bspstarthooks.c107
-rw-r--r--bsps/arm/raspberrypi/start/cmdline.c55
-rw-r--r--bsps/arm/raspberrypi/start/linkcmds.in70
-rw-r--r--bsps/arm/raspberrypi/start/mm_config_table.c96
-rw-r--r--bsps/arm/realview-pbx-a9/start/bsp_specs9
-rw-r--r--bsps/arm/realview-pbx-a9/start/bspreset.c26
-rw-r--r--bsps/arm/realview-pbx-a9/start/bspsmp.c24
-rw-r--r--bsps/arm/realview-pbx-a9/start/bspstart.c24
-rw-r--r--bsps/arm/realview-pbx-a9/start/bspstarthooks.c81
-rw-r--r--bsps/arm/realview-pbx-a9/start/fb-config.c64
-rw-r--r--bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu35
-rw-r--r--bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu_smp3
-rw-r--r--bsps/arm/rtl22xx/start/bsp_specs9
-rw-r--r--bsps/arm/rtl22xx/start/bspreset.c37
-rw-r--r--bsps/arm/rtl22xx/start/bspstart.c84
-rw-r--r--bsps/arm/rtl22xx/start/linkcmds24
-rw-r--r--bsps/arm/shared/start/bsp-start-in-hyp-support.S77
-rw-r--r--bsps/arm/shared/start/bsp-start-init-registers.S105
-rw-r--r--bsps/arm/shared/start/bsp-start-memcpy.S147
-rw-r--r--bsps/arm/shared/start/linkcmds.armv426
-rw-r--r--bsps/arm/shared/start/linkcmds.armv7m26
-rw-r--r--bsps/arm/shared/start/linkcmds.base487
-rw-r--r--bsps/arm/smdk2410/start/bsp_specs9
-rw-r--r--bsps/arm/smdk2410/start/bspidle.c23
-rw-r--r--bsps/arm/smdk2410/start/bspreset.c51
-rw-r--r--bsps/arm/smdk2410/start/bspstart.c83
-rw-r--r--bsps/arm/smdk2410/start/linkcmds26
-rw-r--r--bsps/arm/smdk2410/start/memmap.c27
-rw-r--r--bsps/arm/stm32f4/start/bsp_specs9
-rw-r--r--bsps/arm/stm32f4/start/bspreset.c27
-rw-r--r--bsps/arm/stm32f4/start/bspstart.c303
-rw-r--r--bsps/arm/stm32f4/start/bspstarthook.c29
-rw-r--r--bsps/arm/stm32f4/start/io.c249
-rw-r--r--bsps/arm/stm32f4/start/linkcmds.stm32f105rc24
-rw-r--r--bsps/arm/stm32f4/start/linkcmds.stm32f424
-rw-r--r--bsps/arm/stm32f4/start/rcc.c76
-rw-r--r--bsps/arm/stm32f4/start/start-config-io.c85
-rw-r--r--bsps/arm/tms570/start/bsp_specs9
-rw-r--r--bsps/arm/tms570/start/bspreset.c47
-rw-r--r--bsps/arm/tms570/start/bspstart.c75
-rw-r--r--bsps/arm/tms570/start/bspstarthooks.c41
-rw-r--r--bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk32
-rw-r--r--bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_intram32
-rw-r--r--bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_sdram32
-rw-r--r--bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_with_loader33
-rw-r--r--bsps/arm/xilinx-zynq/start/bsp_specs9
-rw-r--r--bsps/arm/xilinx-zynq/start/bspreset.c30
-rw-r--r--bsps/arm/xilinx-zynq/start/bspsmp.c39
-rw-r--r--bsps/arm/xilinx-zynq/start/bspstart.c34
-rw-r--r--bsps/arm/xilinx-zynq/start/bspstarthooks.c76
-rw-r--r--bsps/arm/xilinx-zynq/start/bspstartmmu.c62
-rw-r--r--bsps/arm/xilinx-zynq/start/linkcmds.in39
173 files changed, 11254 insertions, 0 deletions
diff --git a/bsps/arm/altera-cyclone-v/start/bsp_specs b/bsps/arm/altera-cyclone-v/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/altera-cyclone-v/start/bspclean.c b/bsps/arm/altera-cyclone-v/start/bspclean.c
new file mode 100644
index 0000000000..8b95deb801
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/bspclean.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <rtems/bspIo.h>
+#include <rtems/score/smpimpl.h>
+
+void bsp_fatal_extension(
+ rtems_fatal_source src,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+#ifdef RTEMS_SMP
+ if (src == RTEMS_FATAL_SOURCE_SMP && code == SMP_FATAL_SHUTDOWN_RESPONSE) {
+ while (true) {
+ _ARM_Wait_for_event();
+ }
+ }
+#endif
+
+#if BSP_PRINT_EXCEPTION_CONTEXT
+ if (src == RTEMS_FATAL_SOURCE_EXCEPTION) {
+ rtems_exception_frame_print((const rtems_exception_frame *) code);
+ }
+#endif
+
+#if BSP_RESET_BOARD_AT_EXIT
+ bsp_reset();
+#endif
+}
diff --git a/bsps/arm/altera-cyclone-v/start/bspgetworkarea.c b/bsps/arm/altera-cyclone-v/start/bspgetworkarea.c
new file mode 100644
index 0000000000..a3c702de98
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/bspgetworkarea.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/bootcard.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/fdt.h>
+#include <bsp/linker-symbols.h>
+
+#include <libcpu/arm-cp15.h>
+
+#include <libfdt.h>
+
+#define AREA_COUNT_MAX 16
+
+static const char memory_path[] = "/memory";
+
+static const char reserved_memory_path[] = "/reserved-memory";
+
+static void adjust_memory_size(const void *fdt, Heap_Area *area)
+{
+ int node;
+
+ node = fdt_path_offset_namelen(
+ fdt,
+ memory_path,
+ (int) sizeof(memory_path) - 1
+ );
+
+ if (node >= 0) {
+ int len;
+ const void *val;
+ uintptr_t begin;
+ uintptr_t size;
+ uintptr_t a_bit;
+
+ val = fdt_getprop(fdt, node, "reg", &len);
+ if (len == 8) {
+ begin = fdt32_to_cpu(((fdt32_t *) val)[0]);
+ size = fdt32_to_cpu(((fdt32_t *) val)[1]);
+ } else {
+ begin = 0;
+ size = 0;
+ }
+
+ /*
+ * Remove a bit to avoid problems with speculative memory accesses beyond
+ * the valid memory area.
+ */
+ a_bit = 0x100000;
+ if (size >= a_bit) {
+ size -= a_bit;
+ }
+
+ if (
+ begin == 0
+ && size > (uintptr_t) bsp_section_work_end
+ && (uintptr_t) bsp_section_nocache_end
+ < (uintptr_t) bsp_section_work_end
+ ) {
+ area->size += size - (uintptr_t) bsp_section_work_end;
+ }
+ }
+}
+
+static Heap_Area *find_area(
+ Heap_Area *areas,
+ size_t area_count,
+ uint32_t begin
+)
+{
+ size_t i;
+
+ for (i = 0; i < area_count; ++i) {
+ uintptr_t b;
+ uintptr_t e;
+
+ b = (uintptr_t) areas[i].begin;
+ e = b + (uintptr_t) areas[i].size;
+
+ if (b <= begin && begin < e) {
+ return &areas[i];
+ }
+ }
+
+ return NULL;
+}
+
+static size_t remove_reserved_memory(
+ const void *fdt,
+ Heap_Area *areas,
+ size_t area_count
+)
+{
+ int node;
+
+ node = fdt_path_offset_namelen(
+ fdt,
+ reserved_memory_path,
+ (int) sizeof(reserved_memory_path) - 1
+ );
+
+ if (node >= 0) {
+ node = fdt_first_subnode(fdt, node);
+
+ while (node >= 0) {
+ int len;
+ const void *val;
+ uintptr_t area_begin;
+ uintptr_t area_end;
+ uintptr_t hole_begin;
+ uintptr_t hole_end;
+ Heap_Area *area;
+
+ val = fdt_getprop(fdt, node, "reg", &len);
+ if (len == 8) {
+ hole_begin = fdt32_to_cpu(((fdt32_t *) val)[0]);
+ hole_end = hole_begin + fdt32_to_cpu(((fdt32_t *) val)[1]);
+ } else {
+ rtems_panic("unexpected reserved memory area");
+ }
+
+ area = find_area(areas, area_count, hole_begin);
+ area_begin = (uintptr_t) area->begin;
+ area_end = area_begin + (uintptr_t) area->size;
+ area->size = hole_begin - area_begin;
+
+ if (hole_end <= area_end) {
+ if (area_count >= AREA_COUNT_MAX) {
+ rtems_panic("too many reserved memory areas");
+ }
+
+ area = &areas[area_count];
+ ++area_count;
+ area->begin = (void *) hole_end;
+ area->size = area_end - hole_end;
+ }
+
+ node = fdt_next_subnode(fdt, node);
+ }
+ }
+
+ return area_count;
+}
+
+void bsp_work_area_initialize(void)
+{
+ const void *fdt;
+ Heap_Area areas[AREA_COUNT_MAX];
+ size_t area_count;
+ size_t i;
+
+ areas[0].begin = bsp_section_work_begin;
+ areas[0].size = (uintptr_t) bsp_section_work_size;
+ area_count = 1;
+
+ fdt = bsp_fdt_get();
+
+ adjust_memory_size(fdt, &areas[0]);
+ area_count = remove_reserved_memory(fdt, areas, area_count);
+
+ for (i = 0; i < area_count; ++i) {
+ arm_cp15_set_translation_table_entries(
+ areas[i].begin,
+ (void *) ((uintptr_t) areas[i].begin + areas[i].size),
+ ARMV7_MMU_READ_WRITE_CACHED
+ );
+ }
+
+ bsp_work_area_initialize_with_table(areas, area_count);
+}
diff --git a/bsps/arm/altera-cyclone-v/start/bspreset.c b/bsps/arm/altera-cyclone-v/start/bspreset.c
new file mode 100644
index 0000000000..c4af106fed
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/bspreset.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/bootcard.h>
+#include <bsp/alt_reset_manager.h>
+
+void bsp_reset(void)
+{
+ alt_reset_cold_reset();
+}
diff --git a/bsps/arm/altera-cyclone-v/start/bspsmp.c b/bsps/arm/altera-cyclone-v/start/bspsmp.c
new file mode 100644
index 0000000000..9c3c9dcffe
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/bspsmp.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/score/smpimpl.h>
+
+#include <bsp/start.h>
+
+#include <bsp/socal/alt_rstmgr.h>
+#include <bsp/socal/alt_sysmgr.h>
+#include <bsp/socal/hps.h>
+#include <bsp/socal/socal.h>
+
+bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+{
+ bool started;
+
+ if (cpu_index == 1) {
+ alt_write_word(
+ ALT_SYSMGR_ROMCODE_ADDR + ALT_SYSMGR_ROMCODE_CPU1STARTADDR_OFST,
+ ALT_SYSMGR_ROMCODE_CPU1STARTADDR_VALUE_SET((uint32_t) _start)
+ );
+
+ alt_clrbits_word(
+ ALT_RSTMGR_MPUMODRST_ADDR,
+ ALT_RSTMGR_MPUMODRST_CPU1_SET_MSK
+ );
+
+ /*
+ * Wait for secondary processor to complete its basic initialization so
+ * that we can enable the unified L2 cache.
+ */
+ started = _Per_CPU_State_wait_for_non_initial_state(cpu_index, 0);
+ } else {
+ started = false;
+ }
+
+ return started;
+}
diff --git a/bsps/arm/altera-cyclone-v/start/bspstart.c b/bsps/arm/altera-cyclone-v/start/bspstart.c
new file mode 100644
index 0000000000..0345a4c0a7
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/bspstart.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, 2018 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/bootcard.h>
+#include <bsp/arm-a9mpcore-clock.h>
+#include <bsp/fdt.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+
+#include <bsp/alt_clock_manager.h>
+
+#include <libfdt.h>
+
+uint32_t bsp_fdt_map_intr(const uint32_t *intr, size_t icells)
+{
+ return intr[1] + 32;
+}
+
+static void set_clock(
+ const void *fdt,
+ int parent,
+ ALT_CLK_t clk,
+ const char *name
+)
+{
+ int node;
+ int len;
+ const uint32_t *val;
+
+ node = fdt_subnode_offset(fdt, parent, name);
+ val = fdt_getprop(fdt, node, "clock-frequency", &len);
+
+ if (val != NULL && len >= 4) {
+ alt_clk_ext_clk_freq_set(clk, fdt32_to_cpu(val[0]));
+ }
+}
+
+static void set_clock_by_output_name(
+ const void *fdt,
+ ALT_CLK_t clk,
+ const char *clock_output_name
+)
+{
+ int node;
+ int len;
+ const uint32_t *val;
+
+ node = fdt_node_offset_by_prop_value(
+ fdt,
+ -1,
+ "clock-output-names",
+ clock_output_name,
+ strlen(clock_output_name) + 1
+ );
+ val = fdt_getprop(fdt, node, "clock-frequency", &len);
+
+ if (val != NULL && len >= 4) {
+ alt_clk_ext_clk_freq_set(clk, fdt32_to_cpu(val[0]));
+ }
+}
+
+static void update_clocks(void)
+{
+ const void *fdt;
+ int parent;
+
+ fdt = bsp_fdt_get();
+
+ /* Try to set by node name */
+ parent = fdt_node_offset_by_compatible(fdt, -1, "altr,clk-mgr");
+ parent = fdt_subnode_offset(fdt, parent, "clocks");
+ set_clock(fdt, parent, ALT_CLK_OSC1, "osc1");
+ set_clock(fdt, parent, ALT_CLK_IN_PIN_OSC2, "osc2");
+ set_clock(fdt, parent, ALT_CLK_F2H_PERIPH_REF, "f2s_periph_ref_clk");
+ set_clock(fdt, parent, ALT_CLK_F2H_SDRAM_REF, "f2s_sdram_ref_clk");
+
+ /* Try to set by "clock-output-names" property value */
+ set_clock_by_output_name(fdt, ALT_CLK_OSC1, "hps_0_eosc1-clk");
+ set_clock_by_output_name(fdt, ALT_CLK_IN_PIN_OSC2, "hps_0_eosc2-clk");
+ set_clock_by_output_name(fdt, ALT_CLK_F2H_PERIPH_REF, "hps_0_f2s_periph_ref_clk-clk");
+ set_clock_by_output_name(fdt, ALT_CLK_F2H_SDRAM_REF, "hps_0_f2s_sdram_ref_clk-clk");
+}
+
+void bsp_start(void)
+{
+ update_clocks();
+ a9mpcore_clock_initialize_early();
+ bsp_interrupt_initialize();
+ rtems_cache_coherent_add_area(
+ bsp_section_nocacheheap_begin,
+ (uintptr_t) bsp_section_nocacheheap_size
+ );
+}
diff --git a/bsps/arm/altera-cyclone-v/start/bspstarthooks.c b/bsps/arm/altera-cyclone-v/start/bspstarthooks.c
new file mode 100644
index 0000000000..69a178e3ad
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/bspstarthooks.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/arm-a9mpcore-start.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/alt_address_space.h>
+#include <bsp/socal/socal.h>
+#include <bsp/socal/alt_sdr.h>
+#include <bsp/socal/hps.h>
+
+/* 1 MB reset default value for address filtering start */
+#define BSPSTART_L2_CACHE_ADDR_FILTERING_START_RESET 0x100000
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0( void )
+{
+ arm_cp15_instruction_cache_invalidate();
+ arm_cp15_data_cache_invalidate_all_levels();
+ arm_a9mpcore_start_hook_0();
+}
+
+BSP_START_TEXT_SECTION static void setup_mmu_and_cache(void)
+{
+ uint32_t ctrl = arm_cp15_start_setup_mmu_and_cache(
+ ARM_CP15_CTRL_A | ARM_CP15_CTRL_M,
+ ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z
+ );
+
+ arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
+ ctrl,
+ (uint32_t *) bsp_translation_table_base,
+ ARM_MMU_DEFAULT_CLIENT_DOMAIN,
+ &arm_cp15_start_mmu_config_table[0],
+ arm_cp15_start_mmu_config_table_size
+ );
+}
+
+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();
+ setup_mmu_and_cache();
+#ifndef RTEMS_SMP
+ /* Enable unified L2 cache */
+ rtems_cache_enable_data();
+#endif
+ bsp_start_clear_bss();
+}
diff --git a/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv b/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv
new file mode 100644
index 0000000000..810c4eb1b8
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv
@@ -0,0 +1,29 @@
+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", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", NOCACHE);
+
+bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
+bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
+
+bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1M;
+
+bsp_vector_table_in_start_section = 1;
+
+bsp_translation_table_base = ORIGIN (RAM_MMU);
+bsp_translation_table_end = ORIGIN (RAM_MMU) + LENGTH (RAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit b/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit
new file mode 100644
index 0000000000..546db0e123
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit
@@ -0,0 +1,7 @@
+MEMORY {
+ RAM_MMU : ORIGIN = 0x00100000, LENGTH = 16k
+ NOCACHE : ORIGIN = 0x00200000, LENGTH = 1M
+ RAM : ORIGIN = 0x00300000, LENGTH = 256M - 1M - 1M - 1M
+}
+
+INCLUDE linkcmds.altcycv
diff --git a/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit_smp b/bsps/arm/altera-cyclone-v/start/linkcmds.altcycv_devkit_smp
new file mode 100644
index 0000000000..2da086579f
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/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/bsps/arm/altera-cyclone-v/start/mmu-config.c b/bsps/arm/altera-cyclone-v/start/mmu-config.c
new file mode 100644
index 0000000000..9d56e5c8f5
--- /dev/null
+++ b/bsps/arm/altera-cyclone-v/start/mmu-config.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/arm-cp15-start.h>
+
+const arm_cp15_start_section_config arm_cp15_start_mmu_config_table[] = {
+ ARMV7_CP15_START_DEFAULT_SECTIONS,
+ { /* Periphery area */
+ .begin = 0xFC000000U,
+ .end = 0x00000000U,
+ .flags = ARMV7_MMU_DEVICE
+ }
+};
+
+const size_t arm_cp15_start_mmu_config_table_size =
+ RTEMS_ARRAY_SIZE(arm_cp15_start_mmu_config_table);
diff --git a/bsps/arm/atsam/start/bsp_specs b/bsps/arm/atsam/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/atsam/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/atsam/start/bspstart.c b/bsps/arm/atsam/start/bspstart.c
new file mode 100644
index 0000000000..b463bab696
--- /dev/null
+++ b/bsps/arm/atsam/start/bspstart.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+
+#include <chip.h>
+
+RTEMS_STATIC_ASSERT(
+ PERIPH_COUNT_IRQn <= BSP_INTERRUPT_VECTOR_MAX,
+ PERIPH_COUNT_IRQn
+);
+
+void bsp_start(void)
+{
+ bsp_interrupt_initialize();
+ SCB_CleanDCache();
+ SCB_InvalidateICache();
+ rtems_cache_coherent_add_area(
+ bsp_section_nocacheheap_begin,
+ (uintptr_t) bsp_section_nocacheheap_size
+ );
+}
diff --git a/bsps/arm/atsam/start/bspstarthooks.c b/bsps/arm/atsam/start/bspstarthooks.c
new file mode 100644
index 0000000000..697ec88d67
--- /dev/null
+++ b/bsps/arm/atsam/start/bspstarthooks.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/pin-config.h>
+#include <bsp/atsam-clock-config.h>
+
+#include <chip.h>
+#include <include/board_lowlevel.h>
+#include <include/board_memories.h>
+
+#define SIZE_0K 0
+#define SIZE_32K (32 * 1024)
+#define SIZE_64K (64 * 1024)
+#define SIZE_128K (128 * 1024)
+
+#define ITCMCR_SZ_0K 0x0
+#define ITCMCR_SZ_32K 0x6
+#define ITCMCR_SZ_64K 0x7
+#define ITCMCR_SZ_128K 0x8
+
+static BSP_START_TEXT_SECTION void efc_send_command(uint32_t eefc)
+{
+ EFC->EEFC_FCR = eefc | EEFC_FCR_FKEY_PASSWD;
+}
+
+static BSP_START_TEXT_SECTION void tcm_enable(void)
+{
+ SCB->ITCMCR |= SCB_ITCMCR_EN_Msk;
+ SCB->DTCMCR |= SCB_DTCMCR_EN_Msk;
+}
+
+static BSP_START_TEXT_SECTION void tcm_disable(void)
+{
+ SCB->ITCMCR &= ~SCB_ITCMCR_EN_Msk;
+ SCB->DTCMCR &= ~SCB_DTCMCR_EN_Msk;
+}
+
+static BSP_START_TEXT_SECTION bool tcm_setup_and_check_if_do_efc_config(
+ uintptr_t tcm_size,
+ uint32_t itcmcr_sz
+)
+{
+ if (tcm_size == SIZE_0K && itcmcr_sz == ITCMCR_SZ_0K) {
+ tcm_disable();
+ return false;
+ } else if (tcm_size == SIZE_32K && itcmcr_sz == ITCMCR_SZ_32K) {
+ tcm_enable();
+ return false;
+ } else if (tcm_size == SIZE_64K && itcmcr_sz == ITCMCR_SZ_64K) {
+ tcm_enable();
+ return false;
+ } else if (tcm_size == SIZE_128K && itcmcr_sz == ITCMCR_SZ_128K) {
+ tcm_enable();
+ return false;
+ } else {
+ return true;
+ }
+}
+
+static bool ATSAM_START_SRAM_SECTION sdram_settings_unchanged(void)
+{
+ return (
+ (SDRAMC->SDRAMC_CR == BOARD_Sdram_Config.sdramc_cr) &&
+ (SDRAMC->SDRAMC_TR == BOARD_Sdram_Config.sdramc_tr) &&
+ (SDRAMC->SDRAMC_MDR == BOARD_Sdram_Config.sdramc_mdr) &&
+ (SDRAMC->SDRAMC_CFR1 == BOARD_Sdram_Config.sdramc_cfr1)
+ );
+}
+
+static void ATSAM_START_SRAM_SECTION setup_CPU_and_SDRAM(void)
+{
+ SystemInit();
+ if (!PMC_IsPeriphEnabled(ID_SDRAMC) || !sdram_settings_unchanged()) {
+ BOARD_ConfigureSdram();
+ }
+}
+
+static void configure_tcm(void)
+{
+ uintptr_t tcm_size;
+ uint32_t itcmcr_sz;
+
+ tcm_size = (uintptr_t) atsam_memory_itcm_size;
+ itcmcr_sz = (SCB->ITCMCR & SCB_ITCMCR_SZ_Msk) >> SCB_ITCMCR_SZ_Pos;
+
+ if (tcm_setup_and_check_if_do_efc_config(tcm_size, itcmcr_sz)) {
+ if (tcm_size == SIZE_128K) {
+ efc_send_command(EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(7));
+ efc_send_command(EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(8));
+ tcm_enable();
+ } else if (tcm_size == SIZE_64K) {
+ efc_send_command(EEFC_FCR_FCMD_CGPB | EEFC_FCR_FARG(7));
+ efc_send_command(EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(8));
+ tcm_enable();
+ } else if (tcm_size == SIZE_32K) {
+ efc_send_command(EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(7));
+ efc_send_command(EEFC_FCR_FCMD_CGPB | EEFC_FCR_FARG(8));
+ tcm_enable();
+ } else {
+ efc_send_command(EEFC_FCR_FCMD_CGPB | EEFC_FCR_FARG(7));
+ efc_send_command(EEFC_FCR_FCMD_CGPB | EEFC_FCR_FARG(8));
+ tcm_disable();
+ }
+ }
+}
+
+void BSP_START_TEXT_SECTION bsp_start_hook_0(void)
+{
+ system_init_flash(BOARD_MCK);
+
+ PIO_Configure(&atsam_pin_config[0], atsam_pin_config_count);
+ MATRIX->CCFG_SYSIO = atsam_matrix_ccfg_sysio;
+
+ configure_tcm();
+#if ATSAM_CHANGE_CLOCK_FROM_SRAM != 0
+ /* Early copy of .fast_text section for CPU and SDRAM setup. */
+ bsp_start_memcpy_libc(
+ bsp_section_fast_text_begin,
+ bsp_section_fast_text_load_begin,
+ (size_t) bsp_section_fast_text_size
+ );
+#endif
+ setup_CPU_and_SDRAM();
+
+ if ((SCB->CCR & SCB_CCR_IC_Msk) == 0) {
+ SCB_EnableICache();
+ }
+
+ if ((SCB->CCR & SCB_CCR_DC_Msk) == 0) {
+ SCB_EnableDCache();
+ }
+
+ _SetupMemoryRegion();
+}
+
+void BSP_START_TEXT_SECTION bsp_start_hook_1(void)
+{
+ bsp_start_copy_sections_compact();
+ SCB_CleanDCache();
+ SCB_InvalidateICache();
+ bsp_start_clear_bss();
+ WDT_Disable(WDT);
+}
diff --git a/bsps/arm/atsam/start/getentropy-trng.c b/bsps/arm/atsam/start/getentropy-trng.c
new file mode 100644
index 0000000000..11e24dcda1
--- /dev/null
+++ b/bsps/arm/atsam/start/getentropy-trng.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <libchip/chip.h>
+#include <unistd.h>
+#include <string.h>
+#include <rtems/sysinit.h>
+
+static void atsam_trng_enable(void)
+{
+ PMC_EnablePeripheral(ID_TRNG);
+ TRNG_Enable();
+}
+
+int getentropy(void *ptr, size_t n)
+{
+ while (n > 0) {
+ uint32_t random;
+ size_t copy;
+
+ while ((TRNG_GetStatus() & TRNG_ISR_DATRDY) == 0) {
+ /* wait */
+ }
+ random = TRNG_GetRandData();
+
+ /*
+ * Read TRNG status one more time to avoid race condition.
+ * Otherwise we can read (and clear) an old ready status but get
+ * a new value. The ready status for this value wouldn't be
+ * reset.
+ */
+ TRNG_GetStatus();
+
+ copy = sizeof(random);
+ if (n < copy ) {
+ copy = n;
+ }
+ memcpy(ptr, &random, copy);
+ n -= copy;
+ ptr += copy;
+ }
+
+ return 0;
+}
+
+RTEMS_SYSINIT_ITEM(
+ atsam_trng_enable,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_LAST
+);
diff --git a/bsps/arm/atsam/start/linkcmds b/bsps/arm/atsam/start/linkcmds
new file mode 100644
index 0000000000..79cdfc2b18
--- /dev/null
+++ b/bsps/arm/atsam/start/linkcmds
@@ -0,0 +1,21 @@
+INCLUDE linkcmds.memory
+
+REGION_ALIAS ("REGION_START", INTFLASH);
+REGION_ALIAS ("REGION_VECTOR", INTSRAM);
+REGION_ALIAS ("REGION_TEXT", INTFLASH);
+REGION_ALIAS ("REGION_TEXT_LOAD", INTFLASH);
+REGION_ALIAS ("REGION_RODATA", INTFLASH);
+REGION_ALIAS ("REGION_RODATA_LOAD", INTFLASH);
+REGION_ALIAS ("REGION_DATA", INTSRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", INTFLASH);
+REGION_ALIAS ("REGION_FAST_TEXT", ITCM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", INTFLASH);
+REGION_ALIAS ("REGION_FAST_DATA", DTCM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", INTFLASH);
+REGION_ALIAS ("REGION_BSS", INTSRAM);
+REGION_ALIAS ("REGION_WORK", INTSRAM);
+REGION_ALIAS ("REGION_STACK", INTSRAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", INTFLASH);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/atsam/start/linkcmds.intsram b/bsps/arm/atsam/start/linkcmds.intsram
new file mode 100644
index 0000000000..3e9d07e61c
--- /dev/null
+++ b/bsps/arm/atsam/start/linkcmds.intsram
@@ -0,0 +1,23 @@
+INCLUDE linkcmds.memory
+
+bsp_vector_table_in_start_section = 1;
+
+REGION_ALIAS ("REGION_START", INTSRAM);
+REGION_ALIAS ("REGION_VECTOR", INTSRAM);
+REGION_ALIAS ("REGION_TEXT", INTSRAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", INTSRAM);
+REGION_ALIAS ("REGION_RODATA", INTSRAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", INTSRAM);
+REGION_ALIAS ("REGION_DATA", INTSRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", INTSRAM);
+REGION_ALIAS ("REGION_FAST_TEXT", ITCM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", INTSRAM);
+REGION_ALIAS ("REGION_FAST_DATA", DTCM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", INTSRAM);
+REGION_ALIAS ("REGION_BSS", INTSRAM);
+REGION_ALIAS ("REGION_WORK", INTSRAM);
+REGION_ALIAS ("REGION_STACK", INTSRAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", INTSRAM);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/atsam/start/linkcmds.memory.in b/bsps/arm/atsam/start/linkcmds.memory.in
new file mode 100644
index 0000000000..de4d818283
--- /dev/null
+++ b/bsps/arm/atsam/start/linkcmds.memory.in
@@ -0,0 +1,39 @@
+MEMORY {
+ ITCM : ORIGIN = 0x00000000, LENGTH = @ATSAM_MEMORY_TCM_SIZE@
+ INTFLASH : ORIGIN = 0x00400000, LENGTH = @ATSAM_MEMORY_INTFLASH_SIZE@
+ DTCM : ORIGIN = 0x20000000, LENGTH = @ATSAM_MEMORY_TCM_SIZE@
+ INTSRAM : ORIGIN = 0x20400000, LENGTH = @ATSAM_MEMORY_INTSRAM_SIZE@ - 2 * @ATSAM_MEMORY_TCM_SIZE@ - @ATSAM_MEMORY_NOCACHE_SIZE@
+ NOCACHE : ORIGIN = 0x20400000 + @ATSAM_MEMORY_INTSRAM_SIZE@ - 2 * @ATSAM_MEMORY_TCM_SIZE@ - @ATSAM_MEMORY_NOCACHE_SIZE@, LENGTH = @ATSAM_MEMORY_NOCACHE_SIZE@
+ SDRAM : ORIGIN = 0x70000000, LENGTH = @ATSAM_MEMORY_SDRAM_SIZE@
+ QSPIFLASH : ORIGIN = 0x80000000, LENGTH = @ATSAM_MEMORY_QSPIFLASH_SIZE@
+}
+
+/* Must be used only for MPU definitions */
+
+atsam_memory_itcm_begin = ORIGIN (ITCM);
+atsam_memory_itcm_end = ORIGIN (ITCM) + LENGTH (ITCM);
+atsam_memory_itcm_size = LENGTH (ITCM);
+
+atsam_memory_intflash_begin = ORIGIN (INTFLASH);
+atsam_memory_intflash_end = ORIGIN (INTFLASH) + LENGTH (INTFLASH);
+atsam_memory_intflash_size = LENGTH (INTFLASH);
+
+atsam_memory_dtcm_begin = ORIGIN (DTCM);
+atsam_memory_dtcm_end = ORIGIN (DTCM) + LENGTH (DTCM);
+atsam_memory_dtcm_size = LENGTH (DTCM);
+
+atsam_memory_intsram_begin = ORIGIN (INTSRAM);
+atsam_memory_intsram_end = ORIGIN (INTSRAM) + LENGTH (INTSRAM);
+atsam_memory_intsram_size = LENGTH (INTSRAM);
+
+atsam_memory_nocache_begin = ORIGIN (NOCACHE);
+atsam_memory_nocache_end = ORIGIN (NOCACHE) + LENGTH (NOCACHE);
+atsam_memory_nocache_size = LENGTH (NOCACHE);
+
+atsam_memory_sdram_begin = ORIGIN (SDRAM);
+atsam_memory_sdram_end = ORIGIN (SDRAM) + LENGTH (SDRAM);
+atsam_memory_sdram_size = LENGTH (SDRAM);
+
+atsam_memory_qspiflash_begin = ORIGIN (QSPIFLASH);
+atsam_memory_qspiflash_end = ORIGIN (QSPIFLASH) + LENGTH (QSPIFLASH);
+atsam_memory_qspiflash_size = LENGTH (QSPIFLASH);
diff --git a/bsps/arm/atsam/start/linkcmds.qspiflash b/bsps/arm/atsam/start/linkcmds.qspiflash
new file mode 100644
index 0000000000..d7529f7484
--- /dev/null
+++ b/bsps/arm/atsam/start/linkcmds.qspiflash
@@ -0,0 +1,21 @@
+INCLUDE linkcmds.memory
+
+REGION_ALIAS ("REGION_START", QSPIFLASH);
+REGION_ALIAS ("REGION_VECTOR", INTSRAM);
+REGION_ALIAS ("REGION_TEXT", QSPIFLASH);
+REGION_ALIAS ("REGION_TEXT_LOAD", QSPIFLASH);
+REGION_ALIAS ("REGION_RODATA", QSPIFLASH);
+REGION_ALIAS ("REGION_RODATA_LOAD", QSPIFLASH);
+REGION_ALIAS ("REGION_DATA", INTSRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", QSPIFLASH);
+REGION_ALIAS ("REGION_FAST_TEXT", ITCM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", QSPIFLASH);
+REGION_ALIAS ("REGION_FAST_DATA", DTCM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", QSPIFLASH);
+REGION_ALIAS ("REGION_BSS", INTSRAM);
+REGION_ALIAS ("REGION_WORK", INTSRAM);
+REGION_ALIAS ("REGION_STACK", INTSRAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", QSPIFLASH);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/atsam/start/linkcmds.sdram b/bsps/arm/atsam/start/linkcmds.sdram
new file mode 100644
index 0000000000..958b128c6a
--- /dev/null
+++ b/bsps/arm/atsam/start/linkcmds.sdram
@@ -0,0 +1,21 @@
+INCLUDE linkcmds.memory
+
+REGION_ALIAS ("REGION_START", SDRAM);
+REGION_ALIAS ("REGION_VECTOR", INTSRAM);
+REGION_ALIAS ("REGION_TEXT", SDRAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_RODATA", SDRAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_DATA", SDRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT", ITCM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA", DTCM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_BSS", SDRAM);
+REGION_ALIAS ("REGION_WORK", SDRAM);
+REGION_ALIAS ("REGION_STACK", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", SDRAM);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/atsam/start/pin-config.c b/bsps/arm/atsam/start/pin-config.c
new file mode 100644
index 0000000000..8a18ae8df7
--- /dev/null
+++ b/bsps/arm/atsam/start/pin-config.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/pin-config.h>
+
+const Pin atsam_pin_config[] = {
+ /* Console */
+ {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT},
+ {PIO_PB4D_TXD1, PIOB, ID_PIOB, PIO_PERIPH_D, PIO_DEFAULT},
+
+ /* SDRAM */
+
+ /* D0_7 */ {0x000000FF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT},
+ /* D8_13 */ {0x0000003F, PIOE, ID_PIOE, PIO_PERIPH_A, PIO_DEFAULT},
+ /* D14_15 */ {0x00018000, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT},
+ /* A0_9 */ {0x3FF00000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT},
+ /* SDA10 */ {0x00002000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT},
+ /* CAS */ {0x00020000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT},
+ /* RAS */ {0x00010000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT},
+ /* SDCKE */ {0x00004000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT},
+ /* SDCK */ {0x00800000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT},
+ /* SDSC */ {0x00008000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT},
+ /* NBS0 */ {0x00040000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT},
+ /* NBS1 */ {0x00008000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT},
+ /* SDWE */ {0x20000000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT},
+ /* BA0 */ {0x00100000, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
+};
+
+const size_t atsam_pin_config_count = PIO_LISTSIZE(atsam_pin_config);
+
+const uint32_t atsam_matrix_ccfg_sysio = 0x20400010;
diff --git a/bsps/arm/atsam/start/pmc-config.c b/bsps/arm/atsam/start/pmc-config.c
new file mode 100644
index 0000000000..41902d03dd
--- /dev/null
+++ b/bsps/arm/atsam/start/pmc-config.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/atsam-clock-config.h>
+#include <bspopts.h>
+#include <chip.h>
+
+#if ATSAM_MCK == 123000000
+/* PLLA/HCLK/MCK clock is set to 492/246/123MHz */
+const struct atsam_clock_config atsam_clock_config = {
+ .pllar_init = (CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0x28U) |
+ CKGR_PLLAR_PLLACOUNT(0x3fU) | CKGR_PLLAR_DIVA(0x1U)),
+ .mckr_init = (PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK |
+ PMC_MCKR_MDIV_PCK_DIV2),
+ .mck_freq = 123*1000*1000
+};
+#elif ATSAM_MCK == 150000000
+/* PLLA/HCLK/MCK clock is set to 300/300/150MHz */
+const struct atsam_clock_config atsam_clock_config = {
+ .pllar_init = (CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0x18U) |
+ CKGR_PLLAR_PLLACOUNT(0x3fU) | CKGR_PLLAR_DIVA(0x1U)),
+ .mckr_init = (PMC_MCKR_PRES_CLK_1 | PMC_MCKR_CSS_PLLA_CLK |
+ PMC_MCKR_MDIV_PCK_DIV2),
+ .mck_freq = 150*1000*1000
+};
+#elif ATSAM_MCK == 60000000
+/* PLLA/HCLK/MCK clock is set to 60/60/60MHz */
+const struct atsam_clock_config atsam_clock_config = {
+ .pllar_init = (CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0x4U) |
+ CKGR_PLLAR_PLLACOUNT(0x3fU) | CKGR_PLLAR_DIVA(0x1U)),
+ .mckr_init = (PMC_MCKR_PRES_CLK_1 | PMC_MCKR_CSS_PLLA_CLK |
+ PMC_MCKR_MDIV_EQ_PCK),
+ .mck_freq = 60*1000*1000
+};
+#error Unknown ATSAM_MCK.
+#endif
diff --git a/bsps/arm/atsam/start/power-clock.c b/bsps/arm/atsam/start/power-clock.c
new file mode 100644
index 0000000000..e04933285e
--- /dev/null
+++ b/bsps/arm/atsam/start/power-clock.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/power.h>
+#include <bsp/irq.h>
+
+#include <libchip/chip.h>
+
+#include <rtems/score/armv7m.h>
+
+void atsam_power_handler_clock_driver(
+ const atsam_power_control *control,
+ atsam_power_state state
+)
+{
+ volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
+
+ (void) control;
+
+ switch (state) {
+ case ATSAM_POWER_ON:
+ systick->csr = ARMV7M_SYSTICK_CSR_ENABLE |
+ ARMV7M_SYSTICK_CSR_TICKINT |
+ ARMV7M_SYSTICK_CSR_CLKSOURCE;
+ break;
+ case ATSAM_POWER_OFF:
+ systick->csr = 0;
+ break;
+ default:
+ break;
+ }
+}
diff --git a/bsps/arm/atsam/start/power-rtc.c b/bsps/arm/atsam/start/power-rtc.c
new file mode 100644
index 0000000000..b60235ac29
--- /dev/null
+++ b/bsps/arm/atsam/start/power-rtc.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/power.h>
+#include <bsp/irq.h>
+
+#include <libchip/chip.h>
+
+#define ATSAM_ENABLE_ALARM_INTERRUPT (1u << 1)
+
+static void set_rtc_alarm_interrupt(uint8_t interval)
+{
+ Rtc *rtc = RTC;
+ rtems_time_of_day tod;
+
+ /* Clear current status register */
+ RTC_ClearSCCR(rtc, 0x3F);
+
+ atsam_rtc_get_time(&tod);
+ tod.second = (tod.second + interval) % 60;
+ tod.second = (((tod.second / 10) << 4) | (tod.second % 10));
+
+ rtc->RTC_TIMALR &= ~RTC_TIMALR_SECEN;
+ rtc->RTC_TIMALR = tod.second;
+ rtc->RTC_TIMALR |= RTC_TIMALR_SECEN;
+ RTC_EnableIt(rtc, ATSAM_ENABLE_ALARM_INTERRUPT);
+}
+
+static void rtc_interrupt_handler(void *arg)
+{
+ atsam_power_data_rtc_driver *rtc_data;
+
+ rtc_data = (atsam_power_data_rtc_driver *)arg;
+ set_rtc_alarm_interrupt(rtc_data->interval);
+}
+
+static void rtc_alarm_handler(void *arg)
+{
+ Rtc *rtc = RTC;
+ rtems_status_code sc;
+
+ /* Clear current status register */
+ RTC_ClearSCCR(rtc, 0x3F);
+
+ /* Switch off all RTC interrupts */
+ RTC_DisableIt(rtc, 0x1F);
+
+ /* Install RTC interrupt handler */
+ sc = rtems_interrupt_handler_install(RTC_IRQn,
+ "RTC",
+ RTEMS_INTERRUPT_UNIQUE,
+ rtc_interrupt_handler,
+ arg
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void set_time(void)
+{
+ rtems_time_of_day tod;
+ rtems_status_code sc;
+
+ atsam_rtc_get_time(&tod);
+ sc = rtems_clock_set(&tod);
+ assert(sc == RTEMS_SUCCESSFUL);
+}
+
+void atsam_power_handler_rtc_driver(
+ const atsam_power_control *control,
+ atsam_power_state state
+)
+{
+ atsam_power_data_rtc_driver *rtc_data;
+ Rtc *rtc = RTC;
+
+ rtc_data = (atsam_power_data_rtc_driver *)control->data.arg;
+
+ switch (state) {
+ case ATSAM_POWER_ON:
+ RTC_DisableIt(rtc, ATSAM_ENABLE_ALARM_INTERRUPT);
+ set_time();
+ break;
+ case ATSAM_POWER_OFF:
+ set_rtc_alarm_interrupt(rtc_data->interval);
+ break;
+ case ATSAM_POWER_INIT:
+ rtc_alarm_handler(rtc_data);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/bsps/arm/atsam/start/power.c b/bsps/arm/atsam/start/power.c
new file mode 100644
index 0000000000..f9b5a3925d
--- /dev/null
+++ b/bsps/arm/atsam/start/power.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/power.h>
+#include <bsp/irq.h>
+
+#include <libchip/chip.h>
+
+/* SCR Sleep deep bit */
+#define SCR_SLEEPDEEP (1u << 2)
+
+void atsam_power_change_state(
+ const atsam_power_control *controls,
+ size_t n,
+ atsam_power_state state
+)
+{
+ size_t i;
+
+ switch (state) {
+ case ATSAM_POWER_ON:
+ for (i = n; i > 0; --i) {
+ const atsam_power_control *c;
+
+ c = &controls[i - 1];
+ (*c->handler)(c, state);
+ }
+
+ break;
+ case ATSAM_POWER_INIT:
+ case ATSAM_POWER_OFF:
+ for (i = 0; i < n; ++i) {
+ const atsam_power_control *c;
+
+ c = &controls[i];
+ (*c->handler)(c, state);
+ }
+
+ break;
+ default:
+ break;
+ }
+}
+
+void atsam_power_handler_peripheral(
+ const atsam_power_control *control,
+ atsam_power_state state
+)
+{
+ uint32_t id;
+ uint32_t end;
+
+ id = control->data.peripherals.first;
+ end = control->data.peripherals.last + 1;
+
+ switch (state) {
+ case ATSAM_POWER_ON:
+ while (id != end) {
+ PMC_EnablePeripheral(id);
+ ++id;
+ }
+ break;
+ case ATSAM_POWER_OFF:
+ while (id != end) {
+ PMC_DisablePeripheral(id);
+ ++id;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void atsam_power_handler_sleep_mode(const atsam_power_control *control, atsam_power_state state)
+{
+ (void) control;
+
+ switch (state) {
+ case ATSAM_POWER_OFF:
+ /* Enable Low Power Mode in the Fast Startup Mode Register */
+ PMC->PMC_FSMR &= (uint32_t)~PMC_FSMR_LPM;
+ /* Do not set deep sleep, but "normal" sleep */
+ SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP;
+
+ __asm__ volatile ("wfi");
+ break;
+ default:
+ break;
+ }
+}
diff --git a/bsps/arm/atsam/start/restart.c b/bsps/arm/atsam/start/restart.c
new file mode 100644
index 0000000000..9934fbd298
--- /dev/null
+++ b/bsps/arm/atsam/start/restart.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/score/armv7m.h>
+#include <bsp.h>
+
+static void ARMV7M_Systick_cleanup(void)
+{
+ volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
+ systick->csr = 0;
+}
+
+void bsp_restart( const void *const addr )
+{
+ rtems_interrupt_level level;
+ void(*start)(void) = (void(*)(void))(addr);
+
+ rtems_interrupt_disable(level);
+ (void)level;
+ rtems_cache_disable_instruction();
+ rtems_cache_disable_data();
+ rtems_cache_invalidate_entire_instruction();
+ rtems_cache_invalidate_entire_data();
+ ARMV7M_Systick_cleanup();
+
+ start();
+}
diff --git a/bsps/arm/atsam/start/sdram-config.c b/bsps/arm/atsam/start/sdram-config.c
new file mode 100644
index 0000000000..a2f1158377
--- /dev/null
+++ b/bsps/arm/atsam/start/sdram-config.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bspopts.h>
+#include <chip.h>
+#include <include/board_memories.h>
+
+#if defined ATSAM_SDRAM_IS42S16100E_7BLI
+
+#if ATSAM_MCK != 123000000
+#error Please check SDRAM settings for this clock frequency.
+#endif
+
+const struct BOARD_Sdram_Config BOARD_Sdram_Config = {
+ /* FIXME: a lot of these values should be calculated using CPU frequency */
+ .sdramc_tr = 1562,
+ .sdramc_cr =
+ SDRAMC_CR_NC_COL8 /* 8 column bits */
+ | SDRAMC_CR_NR_ROW11 /* 12 row bits (4K) */
+ | SDRAMC_CR_CAS_LATENCY3 /* CAS Latency 3 */
+ | SDRAMC_CR_NB_BANK2 /* 2 banks */
+ | SDRAMC_CR_DBW /* 16 bit */
+ | SDRAMC_CR_TWR(5)
+ | SDRAMC_CR_TRC_TRFC(13) /* 63ns min */
+ | SDRAMC_CR_TRP(5) /* Command period (PRE to ACT) 21 ns min */
+ | SDRAMC_CR_TRCD(5) /* Active Command to R/W Cmd delay time 21ns min */
+ | SDRAMC_CR_TRAS(9) /* Command period (ACT to PRE) 42ns min */
+ | SDRAMC_CR_TXSR(15U), /* Exit self-refresh to active time 70ns Min */
+ .sdramc_mdr = SDRAMC_MDR_MD_SDRAM,
+ .sdramc_cfr1 = SDRAMC_CFR1_UNAL_SUPPORTED | SDRAMC_CFR1_TMRD(2)
+};
+
+#elif defined ATSAM_SDRAM_IS42S16320F_7BL
+
+#if ATSAM_MCK != 123000000
+#error Please check SDRAM settings for this clock frequency.
+#endif
+
+#define CLOCK_CYCLES_FROM_NS_MAX(ns) \
+ (((ns) * (ATSAM_MCK / 1000ul / 1000ul)) / 1000ul)
+#define CLOCK_CYCLES_FROM_NS_MIN(ns) (CLOCK_CYCLES_FROM_NS_MAX(ns) + 1)
+
+const struct BOARD_Sdram_Config BOARD_Sdram_Config = {
+ /* 8k refresh cycles every 64ms => 7.8125us */
+ .sdramc_tr = CLOCK_CYCLES_FROM_NS_MAX(7812ul),
+ .sdramc_cr =
+ SDRAMC_CR_NC_COL10
+ | SDRAMC_CR_NR_ROW13
+ | SDRAMC_CR_CAS_LATENCY3
+ | SDRAMC_CR_NB_BANK4
+ | SDRAMC_CR_DBW
+ /* t_WR = 30ns min (t_RC - t_RP - t_RCD;
+ * see data sheet November 2015 page 55);
+ * add some security margin */
+ | SDRAMC_CR_TWR(CLOCK_CYCLES_FROM_NS_MIN(40))
+ | SDRAMC_CR_TRC_TRFC(CLOCK_CYCLES_FROM_NS_MIN(60))
+ | SDRAMC_CR_TRP(CLOCK_CYCLES_FROM_NS_MIN(15))
+ | SDRAMC_CR_TRCD(CLOCK_CYCLES_FROM_NS_MIN(15))
+ | SDRAMC_CR_TRAS(CLOCK_CYCLES_FROM_NS_MIN(37))
+ | SDRAMC_CR_TXSR(CLOCK_CYCLES_FROM_NS_MIN(67)),
+ .sdramc_mdr = SDRAMC_MDR_MD_SDRAM,
+ .sdramc_cfr1 = SDRAMC_CFR1_UNAL_SUPPORTED |
+ SDRAMC_CFR1_TMRD(CLOCK_CYCLES_FROM_NS_MIN(14))
+};
+
+#elif defined ATSAM_SDRAM_MT48LC16M16A2P_6A
+
+/*
+ * Refresh: 7.81 us
+ * TWR: 12 ns
+ * TRC_TRFC: 60 ns
+ * TRP: 15 ns
+ * TRCD: 18 ns
+ * TRAS: 42 ns
+ * TXSR: 67 ns
+ * TMRD: 2 clock cycles
+ */
+
+#if ATSAM_MCK == 60000000
+const struct BOARD_Sdram_Config BOARD_Sdram_Config = {
+ .sdramc_tr = 0x1D4,
+ .sdramc_cr =
+ SDRAMC_CR_NC_COL9
+ | SDRAMC_CR_NR_ROW13
+ | SDRAMC_CR_NB_BANK4
+ | SDRAMC_CR_CAS_LATENCY3
+ | SDRAMC_CR_DBW
+ | SDRAMC_CR_TWR(3)
+ | SDRAMC_CR_TRC_TRFC(8)
+ | SDRAMC_CR_TRP(3)
+ | SDRAMC_CR_TRCD(3)
+ | SDRAMC_CR_TRAS(5)
+ | SDRAMC_CR_TXSR(9),
+ .sdramc_mdr = SDRAMC_MDR_MD_SDRAM,
+ .sdramc_cfr1 = SDRAMC_CFR1_UNAL_SUPPORTED |
+ SDRAMC_CFR1_TMRD(2)
+};
+
+#elif ATSAM_MCK == 123000000
+const struct BOARD_Sdram_Config BOARD_Sdram_Config = {
+ .sdramc_tr = 960,
+ .sdramc_cr =
+ SDRAMC_CR_NC_COL9
+ | SDRAMC_CR_NR_ROW13
+ | SDRAMC_CR_NB_BANK4
+ | SDRAMC_CR_CAS_LATENCY3
+ | SDRAMC_CR_DBW
+ | SDRAMC_CR_TWR(2)
+ | SDRAMC_CR_TRC_TRFC(8)
+ | SDRAMC_CR_TRP(2)
+ | SDRAMC_CR_TRCD(3)
+ | SDRAMC_CR_TRAS(6)
+ | SDRAMC_CR_TXSR(9),
+ .sdramc_mdr = SDRAMC_MDR_MD_SDRAM,
+ .sdramc_cfr1 = SDRAMC_CFR1_UNAL_SUPPORTED |
+ SDRAMC_CFR1_TMRD(2)
+};
+
+#else /* ATSAM_MCK unknown */
+#error Please check SDRAM settings for this frequency.
+#endif
+
+#else
+ #error SDRAM not supported.
+#endif
diff --git a/bsps/arm/beagle/start/bsp_specs b/bsps/arm/beagle/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/beagle/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/beagle/start/bspreset.c b/bsps/arm/beagle/start/bspreset.c
new file mode 100644
index 0000000000..5865b7badf
--- /dev/null
+++ b/bsps/arm/beagle/start/bspreset.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014 Ben Gras <beng@shrike-systems.com>. All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+
+#define AM335X_CM_BASE 0x44E00000
+#define AM335X_CM_SIZE 0x1000
+
+#define AM335X_PRM_DEVICE_OFFSET 0xf00
+#define AM335X_PRM_RSTCTRL_REG 0x00
+#define AM335X_RST_GLOBAL_WARM_SW_BIT 0
+
+#define DM37XX_CM_BASE 0x48307000
+#define DM37XX_CM_SIZE 0x1000
+#define DM37XX_PRM_RSTCTRL_REG 0x250
+#define DM37XX_RST_DPLL3_BIT 2
+
+void bsp_reset(void)
+{
+#if IS_DM3730
+ static uint32_t reset_base = DM37XX_CM_BASE;
+ while (true) {
+ mmio_set((reset_base + DM37XX_PRM_RSTCTRL_REG),
+ (1 << DM37XX_RST_DPLL3_BIT));
+ }
+#endif
+
+#if IS_AM335X
+ static uint32_t reset_base = AM335X_CM_BASE;
+ while (true) {
+ mmio_set((reset_base + AM335X_PRM_DEVICE_OFFSET +
+ AM335X_PRM_RSTCTRL_REG),
+ (1 << AM335X_RST_GLOBAL_WARM_SW_BIT));
+ }
+#endif
+}
diff --git a/bsps/arm/beagle/start/bspstart.c b/bsps/arm/beagle/start/bspstart.c
new file mode 100644
index 0000000000..292b576aef
--- /dev/null
+++ b/bsps/arm/beagle/start/bspstart.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+#include <bsp/fdt.h>
+
+void bsp_start(void)
+{
+#if IS_DM3730
+ const char* type = "dm3730-based";
+#endif
+#if IS_AM335X
+ const char* type = "am335x-based";
+#endif
+ bsp_interrupt_initialize();
+ printk("\nRTEMS Beagleboard: %s\n", type);
+}
+
+uint32_t bsp_fdt_map_intr(const uint32_t *intr, size_t icells)
+{
+ return intr[0];
+}
diff --git a/bsps/arm/beagle/start/bspstarthooks.c b/bsps/arm/beagle/start/bspstarthooks.c
new file mode 100644
index 0000000000..2efa3042a8
--- /dev/null
+++ b/bsps/arm/beagle/start/bspstarthooks.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/arm-a8core-start.h>
+
+#include <bsp/uart-output-char.h>
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+{
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+{
+ arm_a8core_start_hook_1();
+ bsp_start_copy_sections();
+ beagle_setup_mmu_and_cache();
+ bsp_start_clear_bss();
+}
diff --git a/bsps/arm/beagle/start/bspstartmmu.c b/bsps/arm/beagle/start/bspstartmmu.c
new file mode 100644
index 0000000000..157edfa0a7
--- /dev/null
+++ b/bsps/arm/beagle/start/bspstartmmu.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * Copyright (c) 2014 Chris Johns. All rights reserved.
+ *
+ * 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/start.h>
+#include <bsp/arm-cp15-start.h>
+
+#define ARM_SECTIONS 4096 /* all sections needed to describe the
+ virtual address space */
+#define ARM_SECTION_SIZE (1024 * 1024) /* how much virtual memory is described
+ by one section */
+
+//static uint32_t pagetable[ARM_SECTIONS] __attribute__((aligned (1024*16)));
+
+BSP_START_DATA_SECTION static const arm_cp15_start_section_config
+beagle_mmu_config_table[] = {
+ ARMV7_CP15_START_DEFAULT_SECTIONS,
+ {
+ .begin = 0x40000000U,
+ .end = 0x4FFFFFFFU,
+ .flags = ARMV7_MMU_DEVICE
+ }
+};
+
+/*
+ * Make weak and let the user override.
+ */
+BSP_START_TEXT_SECTION void beagle_setup_mmu_and_cache(void) __attribute__ ((weak));
+
+BSP_START_TEXT_SECTION void beagle_setup_mmu_and_cache(void)
+{
+ /* turn mmu off first in case it's on */
+ uint32_t ctrl = arm_cp15_start_setup_mmu_and_cache(
+ ARM_CP15_CTRL_M | ARM_CP15_CTRL_A, /* clear - mmu off */
+ ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z
+ );
+
+ arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
+ ctrl,
+ (uint32_t *) bsp_translation_table_base,
+ ARM_MMU_DEFAULT_CLIENT_DOMAIN,
+ &beagle_mmu_config_table[0],
+ RTEMS_ARRAY_SIZE(beagle_mmu_config_table)
+ );
+}
diff --git a/bsps/arm/beagle/start/linkcmds.beagle b/bsps/arm/beagle/start/linkcmds.beagle
new file mode 100644
index 0000000000..20ea3eb195
--- /dev/null
+++ b/bsps/arm/beagle/start/linkcmds.beagle
@@ -0,0 +1,48 @@
+/**
+ * @file
+ *
+ * @ingroup arm_beagle
+ *
+ * @brief Linker script for beagles.
+ */
+
+MEMORY {
+ /* Beagleboards and beaglebones all
+ * have either 256M or 512M memory. We just
+ * use 256M for all.
+ */
+ RAM : ORIGIN = 0x80000000, LENGTH = 256M - 4M
+ RAM_MMU : ORIGIN = 0x80000000 + 256M - 4M, LENGTH = 16k
+}
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_VECTOR", RAM);
+REGION_ALIAS ("REGION_TEXT", RAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_RODATA", RAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", RAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM);
+
+bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
+bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
+
+bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1M;
+
+bsp_vector_table_in_start_section = 1;
+
+bsp_translation_table_base = ORIGIN (RAM_MMU);
+bsp_translation_table_end = ORIGIN (RAM_MMU) + LENGTH (RAM_MMU);
+
+INCLUDE linkcmds.armv4
+
+HeapSize = 1024 * 1024;
diff --git a/bsps/arm/csb336/start/bsp_specs b/bsps/arm/csb336/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/csb336/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/csb336/start/bspstart.c b/bsps/arm/csb336/start/bspstart.c
new file mode 100644
index 0000000000..8970dfbe4a
--- /dev/null
+++ b/bsps/arm/csb336/start/bspstart.c
@@ -0,0 +1,122 @@
+/*
+ * Cogent CSB336 - MC9328MXL SBC startup code
+ */
+
+/*
+ * Copyright (c) 2004 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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/irq-generic.h>
+#include <rtems/bspIo.h>
+#include <mc9328mxl.h>
+#include <libcpu/mmu.h>
+
+/*
+ * bsp_start_default - BSP initialization function
+ *
+ * This function is called before RTEMS is initialized and used
+ * adjust the kernel's configuration.
+ *
+ * This function also configures the CPU's memory protection unit.
+ *
+ * RESTRICTIONS/LIMITATIONS:
+ * Since RTEMS is not configured, no RTEMS functions can be called.
+ *
+ */
+static void bsp_start_default( void )
+{
+ int i;
+
+ /* Set the MCU prescaler to divide by 1 */
+ MC9328MXL_PLL_CSCR &= ~MC9328MXL_PLL_CSCR_PRESC;
+
+ /* Enable the MCU PLL */
+ MC9328MXL_PLL_CSCR |= MC9328MXL_PLL_CSCR_MPEN;
+
+ /* Delay to allow time for PLL to get going */
+ for (i = 0; i < 100; i++) {
+ __asm__ volatile ("nop\n");
+ }
+
+ /* Set the CPU to asynchrous clock mode, so it uses its fastest clock */
+ mmu_set_cpu_async_mode();
+
+ /* disable interrupts */
+ MC9328MXL_AITC_INTENABLEL = 0;
+ MC9328MXL_AITC_INTENABLEH = 0;
+
+ /* Set interrupt priority to -1 (allow all priorities) */
+ MC9328MXL_AITC_NIMASK = 0x1f;
+
+ /*
+ * Init rtems interrupt management
+ */
+ bsp_interrupt_initialize();
+} /* bsp_start */
+
+/* Calcuate the frequency for perclk1 */
+int get_perclk1_freq(void)
+{
+ unsigned int fin;
+ unsigned int fpll;
+ unsigned int pd;
+ unsigned int mfd;
+ unsigned int mfi;
+ unsigned int mfn;
+ uint32_t reg;
+ int perclk1;
+
+ if (MC9328MXL_PLL_CSCR & MC9328MXL_PLL_CSCR_SYSSEL) {
+ /* Use external oscillator */
+ fin = BSP_OSC_FREQ;
+ } else {
+ /* Use scaled xtal freq */
+ fin = BSP_XTAL_FREQ * 512;
+ }
+
+ /* calculate the output of the system PLL */
+ reg = MC9328MXL_PLL_SPCTL0;
+ pd = ((reg & MC9328MXL_PLL_SPCTL_PD_MASK) >>
+ MC9328MXL_PLL_SPCTL_PD_SHIFT);
+ mfd = ((reg & MC9328MXL_PLL_SPCTL_MFD_MASK) >>
+ MC9328MXL_PLL_SPCTL_MFD_SHIFT);
+ mfi = ((reg & MC9328MXL_PLL_SPCTL_MFI_MASK) >>
+ MC9328MXL_PLL_SPCTL_MFI_SHIFT);
+ mfn = ((reg & MC9328MXL_PLL_SPCTL_MFN_MASK) >>
+ MC9328MXL_PLL_SPCTL_MFN_SHIFT);
+
+#if 0
+ printk("fin = %d\n", fin);
+ printk("pd = %d\n", pd);
+ printk("mfd = %d\n", mfd);
+ printk("mfi = %d\n", mfi);
+ printk("mfn = %d\n", mfn);
+ printk("rounded (fin * mfi) / (pd + 1) = %d\n", (fin * mfi) / (pd + 1));
+ printk("rounded (fin * mfn) / ((pd + 1) * (mfd + 1)) = %d\n",
+ ((long long)fin * mfn) / ((pd + 1) * (mfd + 1)));
+#endif
+
+ fpll = 2 * ( ((fin * mfi + (pd + 1) / 2) / (pd + 1)) +
+ (((long long)fin * mfn + ((pd + 1) * (mfd + 1)) / 2) /
+ ((pd + 1) * (mfd + 1))) );
+
+ /* calculate the output of the PERCLK1 divider */
+ reg = MC9328MXL_PLL_PCDR;
+ perclk1 = fpll / (1 + ((reg & MC9328MXL_PLL_PCDR_PCLK1_MASK) >>
+ MC9328MXL_PLL_PCDR_PCLK1_SHIFT));
+
+ return perclk1;
+}
+
+/*
+ * By making this a weak alias for bsp_start_default, a brave soul
+ * can override the actual bsp_start routine used.
+ */
+void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
+
diff --git a/bsps/arm/csb336/start/linkcmds b/bsps/arm/csb336/start/linkcmds
new file mode 100644
index 0000000000..2f6f8bd89d
--- /dev/null
+++ b/bsps/arm/csb336/start/linkcmds
@@ -0,0 +1,27 @@
+MEMORY {
+ SDRAM_VEC : ORIGIN = 0x08200000, LENGTH = 16k
+ SDRAM_MMU : ORIGIN = 0x08204000, LENGTH = 16k
+ SDRAM : ORIGIN = 0x08208000, LENGTH = 30M - 32k
+}
+
+REGION_ALIAS ("REGION_START", SDRAM_VEC);
+REGION_ALIAS ("REGION_VECTOR", SDRAM);
+REGION_ALIAS ("REGION_TEXT", SDRAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_RODATA", SDRAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_DATA", SDRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_BSS", SDRAM);
+REGION_ALIAS ("REGION_WORK", SDRAM);
+REGION_ALIAS ("REGION_STACK", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", SDRAM);
+
+_ttbl_base = ORIGIN (SDRAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/csb336/start/memmap.c b/bsps/arm/csb336/start/memmap.c
new file mode 100644
index 0000000000..a61fc6e2cf
--- /dev/null
+++ b/bsps/arm/csb336/start/memmap.c
@@ -0,0 +1,35 @@
+/*
+ * CSB336 Memory Map
+ *
+ * Copyright (c) 2004 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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 <libcpu/mmu.h>
+
+/* Remember, the ARM920 has 64 TLBs. If you have more 1MB sections than
+ * that, you'll have TLB lookups, which could hurt performance.
+ */
+mmu_sect_map_t mem_map[] = {
+/* <phys addr> <virt addr> <size> <flags> */
+ {0x08200000, 0x00000000, 1, MMU_CACHE_WBACK}, /* Mirror of SDRAM */
+ {0x00100000, 0x00100000, 1, MMU_CACHE_NONE}, /* Bootstrap ROM */
+ {0x00200000, 0x00200000, 2, MMU_CACHE_NONE}, /* Internal Regs + eSRAM */
+
+ {0x08000000, 0x08000000, 1, MMU_CACHE_NONE}, /* SDRAM */
+ {0x08100000, 0x08100000, 1, MMU_CACHE_WTHROUGH}, /* SDRAM */
+ {0x08200000, 0x08200000, 30, MMU_CACHE_WBACK}, /* SDRAM */
+
+ {0x10000000, 0x10000000, 8, MMU_CACHE_NONE}, /* CS0 - Flash */
+ {0x12000000, 0x12000000, 1, MMU_CACHE_NONE}, /* CS1 - enet */
+ {0x13000000, 0x13000000, 1, MMU_CACHE_NONE}, /* CS2 - */
+ {0x14000000, 0x14000000, 1, MMU_CACHE_NONE}, /* CS3 - */
+ {0x15000000, 0x15000000, 1, MMU_CACHE_NONE}, /* CS4 - */
+ {0x16000000, 0x16000000, 1, MMU_CACHE_NONE}, /* CS5 - */
+ {0x50000000, 0x50000000, 1, MMU_CACHE_NONE}, /* ARM Test Regs */
+ {0x00000000, 0x00000000, 0, 0} /* The end */
+};
diff --git a/bsps/arm/csb337/start/bsp_specs b/bsps/arm/csb337/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/csb337/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/csb337/start/bspreset.c b/bsps/arm/csb337/start/bspreset.c
new file mode 100644
index 0000000000..a4605dcaf3
--- /dev/null
+++ b/bsps/arm/csb337/start/bspreset.c
@@ -0,0 +1,31 @@
+/*
+ * Cogent CSB337 - AT91RM9200 Startup code
+ */
+
+/*
+ * Copyright (c) 2004 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+*/
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <at91rm9200.h>
+#include <at91rm9200_pmc.h>
+#include <at91rm9200_emac.h>
+
+void bsp_reset(void)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+ (void) level; /* avoid set but not used warning */
+
+ /* Enable the watchdog timer, then wait for the world to end. */
+ ST_REG(ST_WDMR) = ST_WDMR_RSTEN | 1;
+
+ while(1)
+ ;
+}
diff --git a/bsps/arm/csb337/start/bspstart.c b/bsps/arm/csb337/start/bspstart.c
new file mode 100644
index 0000000000..a47198598c
--- /dev/null
+++ b/bsps/arm/csb337/start/bspstart.c
@@ -0,0 +1,158 @@
+/*
+ * Cogent CSB337 - AT91RM9200 Startup Code
+ *
+ * Copyright (c) 2004 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ * Modified by Joel Sherill
+ * from OAR Corporation and
+ * Fernando Nicodemos <fgnicodemos@terra.com.br>
+ * from NCB - Sistemas Embarcados Ltda. (Brazil)
+ *
+ * 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/irq-generic.h>
+#include <at91rm9200.h>
+#include <at91rm9200_pmc.h>
+#include <at91rm9200_emac.h>
+#include <at91rm9200_gpio.h>
+#include <at91rm9200_usart.h>
+
+/* Function prototypes */
+static void fix_mac_addr(void);
+void bsp_usart_init(void);
+
+/*
+ * bsp_start_default - BSP initialization function
+ *
+ * This function is called before RTEMS is initialized and used
+ * adjust the kernel's configuration.
+ *
+ * This function also configures the CPU's memory protection unit.
+ *
+ * RESTRICTIONS/LIMITATIONS:
+ * Since RTEMS is not configured, no RTEMS functions can be called.
+ */
+static void bsp_start_default( void )
+{
+ /* disable interrupts */
+ AIC_CTL_REG(AIC_IDCR) = 0xffffffff;
+
+ /*
+ * Some versions of the bootloader have the MAC address
+ * reversed. This fixes it, if necessary.
+ */
+ fix_mac_addr();
+
+ /*
+ * Init rtems PIO configuration for USARTs
+ */
+ bsp_usart_init();
+
+ /*
+ * Init rtems interrupt management
+ */
+ bsp_interrupt_initialize();
+
+} /* bsp_start */
+
+/*
+ * Some versions of the bootloader shipped with the CSB337
+ * reverse the MAC address. This function tests for that,
+ * and fixes the MAC address.
+ */
+static void fix_mac_addr(void)
+{
+ uint8_t addr[6];
+
+ /* Read the MAC address */
+ addr[0] = (EMAC_REG(EMAC_SA1L) >> 0) & 0xff;
+ addr[1] = (EMAC_REG(EMAC_SA1L) >> 8) & 0xff;
+ addr[2] = (EMAC_REG(EMAC_SA1L) >> 16) & 0xff;
+ addr[3] = (EMAC_REG(EMAC_SA1L) >> 24) & 0xff;
+ addr[4] = (EMAC_REG(EMAC_SA1H) >> 0) & 0xff;
+ addr[5] = (EMAC_REG(EMAC_SA1H) >> 8) & 0xff;
+
+ /* Check which 3 bytes have Cogent's OUI */
+ if ((addr[5] == 0x00) && (addr[4] == 0x23) && (addr[3] == 0x31)) {
+ EMAC_REG(EMAC_SA1L) = ((addr[5] << 0) |
+ (addr[4] << 8) |
+ (addr[3] << 16) |
+ (addr[2] << 24));
+
+ EMAC_REG(EMAC_SA1H) = ((addr[1] << 0) |
+ (addr[0] << 8));
+ }
+}
+
+/*
+ *
+ * NAME: bsp_usart_init - Function to setup the PIO in USART mode
+ * before startup
+ *
+ * DESCRIPTION:
+ * This function is called before usart driver is initialized and is
+ * used to setup the proper mode of PIO operation for USART.
+ *
+ * NOTES:
+ * The initialization could be done smarter by programming only the
+ * bits you need to program for each USART when the port is ENABLED.
+ *
+ */
+void bsp_usart_init(void)
+{
+ /*
+ * Configure shared pins for USARTs.
+ * Disables the PIO from controlling the corresponding pin.
+ */
+ PIOA_REG(PIO_PDR) |= ( BIT5 | /* USART3 TXD3 */
+ BIT6 | /* USART3 RXD3 */
+ BIT17 | /* USART0 TXD0 */
+ BIT18 | /* USART0 RXD0 */
+ BIT22 | /* USART2 RXD2 */
+ BIT23 ); /* USART2 TXD2 */
+
+ PIOB_REG(PIO_PDR) |= ( BIT20 | /* USART1 TXD1 */
+ BIT21 ); /* USART1 RXD1 */
+
+ /**** PIO Controller A - Pins you want in mode B ****/
+ PIOA_REG(PIO_BSR) |= ( BIT5 | /* USART3 TXD3 */ /* add */
+ BIT6 ); /* USART3 RXD3 */
+ PIOA_REG(PIO_ASR) &= ~( BIT5 | /* USART3 TXD3 */
+ BIT6 ); /* USART3 RXD3 */
+
+ /**** PIO Controller A - Pins you want in mode A ****/
+ PIOA_REG(PIO_ASR) |= ( BIT17 | /* USART0 TXD0 */
+ BIT18 | /* USART0 RXD0 */
+ BIT22 | /* USART2 RXD2 */
+ BIT23 ); /* USART2 TXD2 */
+ PIOA_REG(PIO_BSR) &= ~( BIT17 | /* USART0 TXD0 */ /* add */
+ BIT18 | /* USART0 RXD0 */
+ BIT22 | /* USART2 RXD2 */
+ BIT23 ); /* USART2 TXD2 */
+
+ /**** PIO Controller B - Pins you want in mode A ****/
+ PIOB_REG(PIO_ASR) |= ( BIT20 | /* USART1 TXD1 */
+ BIT21 ); /* USART1 RXD1 */
+ PIOB_REG(PIO_BSR) &= ~( BIT20 | /* USART1 TXD1 */
+ BIT21 ); /* USART1 RXD1 */
+
+ /**** PIO Controller B - Pins you want in mode B ****/
+ /**** none ****/
+
+ /* Enable the clock to the USARTs */
+ PMC_REG(PMC_PCER) |= ( PMC_PCR_PID_US0 | /* USART 0 Peripheral Clock */
+ PMC_PCR_PID_US1 | /* USART 1 Peripheral Clock */
+ PMC_PCR_PID_US2 | /* USART 2 Peripheral Clock */
+ PMC_PCR_PID_US3 ); /* USART 3 Peripheral Clock */
+}
+
+/*
+ * By making this a weak alias for bsp_start_default, a brave soul
+ * can override the actual bsp_start routine used.
+ */
+void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
diff --git a/bsps/arm/csb337/start/linkcmds.csb337 b/bsps/arm/csb337/start/linkcmds.csb337
new file mode 100644
index 0000000000..f59a33c703
--- /dev/null
+++ b/bsps/arm/csb337/start/linkcmds.csb337
@@ -0,0 +1,27 @@
+MEMORY {
+ SDRAM : ORIGIN = 0x20100000, LENGTH = 15M - 16k
+ SDRAM_MMU : ORIGIN = 0x20ffc000, LENGTH = 16k
+ SRAM : ORIGIN = 0x00200000, LENGTH = 16k
+}
+
+REGION_ALIAS ("REGION_START", SDRAM);
+REGION_ALIAS ("REGION_VECTOR", SRAM);
+REGION_ALIAS ("REGION_TEXT", SDRAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_RODATA", SDRAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_DATA", SDRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_BSS", SDRAM);
+REGION_ALIAS ("REGION_WORK", SDRAM);
+REGION_ALIAS ("REGION_STACK", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", SDRAM);
+
+_ttbl_base = ORIGIN (SDRAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/csb337/start/linkcmds.csb637 b/bsps/arm/csb337/start/linkcmds.csb637
new file mode 100644
index 0000000000..91a34b7229
--- /dev/null
+++ b/bsps/arm/csb337/start/linkcmds.csb637
@@ -0,0 +1,27 @@
+MEMORY {
+ SDRAM : ORIGIN = 0x20100000, LENGTH = 63M - 16k
+ SDRAM_MMU : ORIGIN = 0x23ffc000, LENGTH = 16k
+ SRAM : ORIGIN = 0x00200000, LENGTH = 16k
+}
+
+REGION_ALIAS ("REGION_START", SDRAM);
+REGION_ALIAS ("REGION_VECTOR", SRAM);
+REGION_ALIAS ("REGION_TEXT", SDRAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_RODATA", SDRAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_DATA", SDRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_BSS", SDRAM);
+REGION_ALIAS ("REGION_WORK", SDRAM);
+REGION_ALIAS ("REGION_STACK", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", SDRAM);
+
+_ttbl_base = ORIGIN (SDRAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/csb337/start/memmap.c b/bsps/arm/csb337/start/memmap.c
new file mode 100644
index 0000000000..bdd5487432
--- /dev/null
+++ b/bsps/arm/csb337/start/memmap.c
@@ -0,0 +1,50 @@
+/*
+ * CSB337 and CSB637 (KIT637_V6) Memory map
+ *
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
+ * File from the old CSB337 RTEMS BSP
+ *
+ * Modified by Joel Sherill
+ * from OAR Corporation and
+ * Fernando Nicodemos <fgnicodemos@terra.com.br>
+ * from NCB - Sistemas Embarcados Ltda. (Brazil)
+ *
+ * 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 <libcpu/mmu.h>
+
+#include <bspopts.h>
+
+/* Remember, the ARM920 has 64 TLBs. If you have more 1MB sections than
+ * that, you'll have TLB lookups, which could hurt performance.
+ */
+mmu_sect_map_t mem_map[] = {
+/* <phys addr> <virt addr> <size> <flags> */
+ {0x00200000, 0x00000000, 1, MMU_CACHE_NONE}, /* SRAM */
+ {0x00200000, 0x00200000, 1, MMU_CACHE_NONE}, /* SRAM */
+ {0x10000000, 0x10000000, 8, MMU_CACHE_NONE}, /* FLASH */
+#if csb637 /* CSB637 or KIT637_V6 */
+ {0x20000000, 0x20000000, 64, MMU_CACHE_WTHROUGH}, /* SDRAM */
+#elif kit637_v6
+ {0x20000000, 0x20000000, 64, MMU_CACHE_WTHROUGH}, /* SDRAM */
+#else /* CSB337 */
+ {0x20000000, 0x20000000, 32, MMU_CACHE_WTHROUGH}, /* SDRAM */
+#endif
+#if ENABLE_LCD /* KIT637_V6 Video buffer */
+ {0x30000000, 0x30000000, 8, MMU_CACHE_NONE}, /* Video buffer - 8MB */
+#else /* CSB337 Video buffer */
+ {0x30000000, 0x30000000, 1, MMU_CACHE_NONE}, /* Video buffer - 1MB */
+#endif
+ {0x40000000, 0x40000000, 1, MMU_CACHE_NONE}, /* Expansion CS0 */
+ {0x50000000, 0x50000000, 1, MMU_CACHE_NONE}, /* CF CE 1 */
+ {0x60000000, 0x60000000, 1, MMU_CACHE_NONE}, /* CF CE 1 */
+ {0x70000000, 0x70000000, 1, MMU_CACHE_NONE}, /* CF CE 2 */
+ {0x80000000, 0x80000000, 1, MMU_CACHE_NONE}, /* Expansion CS0 */
+ {0xfff00000, 0xfff00000, 1, MMU_CACHE_NONE}, /* Internal regs */
+ {0x00000000, 0x00000000, 0, 0} /* The end */
+};
+
diff --git a/bsps/arm/csb337/start/pmc.c b/bsps/arm/csb337/start/pmc.c
new file mode 100644
index 0000000000..a15bf3c075
--- /dev/null
+++ b/bsps/arm/csb337/start/pmc.c
@@ -0,0 +1,96 @@
+/*
+ * Atmel AT91RM9200 PMC functions
+ *
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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 <bsp.h>
+#include <at91rm9200.h>
+#include <at91rm9200_pmc.h>
+
+int at91rm9200_get_mainclk(void)
+{
+ return BSP_MAIN_FREQ;
+}
+
+int at91rm9200_get_slck(void)
+{
+ return BSP_SLCK_FREQ;
+}
+
+int at91rm9200_get_mck(void)
+{
+ uint32_t mck_reg;
+ uint32_t mck_freq = 0; /* to avoid warnings */
+ uint32_t pll_reg;
+ int prescaler = 0; /* to avoid warnings */
+
+ mck_reg = PMC_REG(PMC_MCKR);
+
+ switch(mck_reg & PMC_MCKR_PRES_MASK) {
+ case PMC_MCKR_PRES_1:
+ prescaler = 1;
+ break;
+ case PMC_MCKR_PRES_2:
+ prescaler = 2;
+ break;
+ case PMC_MCKR_PRES_4:
+ prescaler = 4;
+ break;
+ case PMC_MCKR_PRES_8:
+ prescaler = 8;
+ break;
+ case PMC_MCKR_PRES_16:
+ prescaler = 16;
+ break;
+ case PMC_MCKR_PRES_32:
+ prescaler = 32;
+ break;
+ case PMC_MCKR_PRES_64:
+ prescaler = 64;
+ break;
+ }
+
+ /* Let's find out what MCK's source is */
+ switch (mck_reg & PMC_MCKR_CSS_MASK) {
+ case PMC_MCKR_CSS_SLOW:
+ /* I'm assuming the slow clock is 32.768 MHz */
+ mck_freq = at91rm9200_get_slck() / prescaler;
+ break;
+
+ case PMC_MCKR_CSS_MAIN:
+ mck_freq = at91rm9200_get_mainclk() / prescaler;
+ break;
+
+ case PMC_MCKR_CSS_PLLA:
+ pll_reg = PMC_REG(PMC_PLLAR);
+ mck_freq = at91rm9200_get_mainclk() / prescaler;
+ mck_freq = mck_freq / (pll_reg & PMC_PLLAR_DIV_MASK);
+ mck_freq = mck_freq * (((pll_reg & PMC_PLLAR_MUL_MASK) >> 16) + 1);
+ break;
+
+ case PMC_MCKR_CSS_PLLB:
+ pll_reg = PMC_REG(PMC_PLLBR);
+ mck_freq = at91rm9200_get_mainclk() / prescaler;
+ mck_freq = mck_freq / (pll_reg & PMC_PLLBR_DIV_MASK);
+ mck_freq = mck_freq * (((pll_reg & PMC_PLLBR_MUL_MASK) >> 16) + 1);
+ break;
+ }
+
+ if ((mck_reg & PMC_MCKR_MDIV_MASK) == PMC_MCKR_MDIV_2) {
+ mck_freq = mck_freq / 2;
+ } else if ((mck_reg & PMC_MCKR_MDIV_MASK) == PMC_MCKR_MDIV_3) {
+ mck_freq = mck_freq / 3;
+ } else if ((mck_reg & PMC_MCKR_MDIV_MASK) == PMC_MCKR_MDIV_4) {
+ mck_freq = mck_freq / 4;
+ }
+
+
+ return mck_freq;
+}
+
diff --git a/bsps/arm/csb337/start/umonsupp.c b/bsps/arm/csb337/start/umonsupp.c
new file mode 100644
index 0000000000..d4bf731c5d
--- /dev/null
+++ b/bsps/arm/csb337/start/umonsupp.c
@@ -0,0 +1,25 @@
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modified by Fernando Nicodemos <fgnicodemos@terra.com.br>
+ * from NCB - Sistemas Embarcados Ltda. (Brazil)
+ *
+ * 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/umon.h>
+
+/*
+ * BSP specific routine to help when calling monConnect(). This
+ * returns the value known to uMon as MONCOMPTR.
+ */
+
+void *rtems_bsp_get_umon_monptr(void)
+{
+ return (void *)0x10000020;
+}
+
diff --git a/bsps/arm/edb7312/start/bsp_specs b/bsps/arm/edb7312/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/edb7312/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/edb7312/start/bspreset.c b/bsps/arm/edb7312/start/bspreset.c
new file mode 100644
index 0000000000..436bdf09e4
--- /dev/null
+++ b/bsps/arm/edb7312/start/bspreset.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <ep7312.h>
+
+void bsp_reset(void)
+{
+#if ON_SKYEYE == 1
+ #define SKYEYE_MAGIC_ADDRESS (*(volatile unsigned int *)(0xb0000000))
+
+ SKYEYE_MAGIC_ADDRESS = 0xff;
+#else
+ __asm__ volatile ("b _start");
+#endif
+}
diff --git a/bsps/arm/edb7312/start/bspstart.c b/bsps/arm/edb7312/start/bspstart.c
new file mode 100644
index 0000000000..0f9c64d2d8
--- /dev/null
+++ b/bsps/arm/edb7312/start/bspstart.c
@@ -0,0 +1,45 @@
+/*
+ * Cirrus EP7312 Startup code
+ */
+
+/*
+ * Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
+ *
+ * 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/irq-generic.h>
+#include <ep7312.h>
+#include <uart.h>
+
+/*
+ * NAME: bsp_start_default - BSP initialization function
+ *
+ * This function is called before RTEMS is initialized
+ * This function also configures the CPU's memory protection unit.
+ *
+ *
+ * RESTRICTIONS/LIMITATIONS:
+ * Since RTEMS is not configured, no RTEMS functions can be called.
+ *
+ */
+static void bsp_start_default( void )
+{
+ /* disable interrupts */
+ *EP7312_INTMR1 = 0;
+ *EP7312_INTMR2 = 0;
+
+ /*
+ * Init rtems interrupt management
+ */
+ bsp_interrupt_initialize();
+} /* bsp_start */
+
+/*
+ * By making this a weak alias for bsp_start_default, a brave soul
+ * can override the actual bsp_start routine used.
+ */
+void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
diff --git a/bsps/arm/edb7312/start/linkcmds b/bsps/arm/edb7312/start/linkcmds
new file mode 100644
index 0000000000..a0afc0ad5e
--- /dev/null
+++ b/bsps/arm/edb7312/start/linkcmds
@@ -0,0 +1,25 @@
+MEMORY {
+ SDRAM : ORIGIN = 0x00000000, LENGTH = 16M
+}
+
+REGION_ALIAS ("REGION_START", SDRAM);
+REGION_ALIAS ("REGION_VECTOR", SDRAM);
+REGION_ALIAS ("REGION_TEXT", SDRAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_RODATA", SDRAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_DATA", SDRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_BSS", SDRAM);
+REGION_ALIAS ("REGION_WORK", SDRAM);
+REGION_ALIAS ("REGION_STACK", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", SDRAM);
+
+bsp_vector_table_in_start_section = 1;
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/gdbarmsim/start/bsp_specs b/bsps/arm/gdbarmsim/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/gdbarmsim/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/gdbarmsim/start/bspreset.c b/bsps/arm/gdbarmsim/start/bspreset.c
new file mode 100644
index 0000000000..b32c80e4e1
--- /dev/null
+++ b/bsps/arm/gdbarmsim/start/bspreset.c
@@ -0,0 +1,17 @@
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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 <bsp/bootcard.h>
+#include <bsp/swi.h>
+
+void bsp_reset( void )
+{
+ __asm__ ("swi %a0" :: "i" (SWI_Exit));
+}
diff --git a/bsps/arm/gdbarmsim/start/bspstart.c b/bsps/arm/gdbarmsim/start/bspstart.c
new file mode 100644
index 0000000000..de3126499d
--- /dev/null
+++ b/bsps/arm/gdbarmsim/start/bspstart.c
@@ -0,0 +1,22 @@
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+
+void initialise_monitor_handles(void);
+
+/*
+ * This routine would usually do the bulk of the system initialization.
+ * But if a BSP doesn't need to do anything, it can use this version.
+ */
+void bsp_start( void )
+{
+ initialise_monitor_handles(void);
+}
diff --git a/bsps/arm/gdbarmsim/start/bspstarthooks.c b/bsps/arm/gdbarmsim/start/bspstarthooks.c
new file mode 100644
index 0000000000..996d35859d
--- /dev/null
+++ b/bsps/arm/gdbarmsim/start/bspstarthooks.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 Chris Johns <chrisj@rtems.org> All rights reserved.
+ *
+ * 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/start.h>
+#
+BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+{
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+{
+ bsp_start_copy_sections();
+ bsp_start_clear_bss();
+}
diff --git a/bsps/arm/gdbarmsim/start/linkcmds b/bsps/arm/gdbarmsim/start/linkcmds
new file mode 100644
index 0000000000..536dbf5fee
--- /dev/null
+++ b/bsps/arm/gdbarmsim/start/linkcmds
@@ -0,0 +1,23 @@
+MEMORY {
+ RAM : ORIGIN = 0x00000000, LENGTH = 4M
+}
+
+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);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/gdbarmsim/start/syscalls.c b/bsps/arm/gdbarmsim/start/syscalls.c
new file mode 100644
index 0000000000..2e761dd28b
--- /dev/null
+++ b/bsps/arm/gdbarmsim/start/syscalls.c
@@ -0,0 +1,763 @@
+/*
+ * Copied from libgloss 1 Oct 2009.
+ * Minor modifications to work with RTEMS.
+ */
+
+/* Support files for GNU libc. Files in the system namespace go here.
+ Files in the C namespace (ie those that do not start with an
+ underscore) go in .c. */
+
+/*
+ * Rename all the functions present here to stop then clashing with RTEMS
+ * names.
+ */
+
+#include <_ansi.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <errno.h>
+#include <reent.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <bsp/swi.h>
+
+#include <bsp.h>
+
+/* Forward prototypes. */
+static int checkerror(int);
+static int error(int);
+static int get_errno(void);
+
+/* Struct used to keep track of the file position, just so we
+ can implement fseek(fh,x,SEEK_CUR). */
+struct fdent
+{
+ int handle;
+ int pos;
+};
+
+#define MAX_OPEN_FILES 20
+
+/* User file descriptors (fd) are integer indexes into
+ the openfiles[] array. Error checking is done by using
+ findslot().
+
+ This openfiles array is manipulated directly by only
+ these 5 functions:
+
+ findslot() - Translate entry.
+ newslot() - Find empty entry.
+ initilise_monitor_handles() - Initialize entries.
+ _swiopen() - Initialize entry.
+ _close() - Handle stdout == stderr case.
+
+ Every other function must use findslot(). */
+
+static struct fdent openfiles [MAX_OPEN_FILES];
+
+static struct fdent* findslot (int);
+static int newslot (void);
+
+/* Register name faking - works in collusion with the linker. */
+register char * stack_ptr __asm__ ("sp");
+
+
+/* following is copied from libc/stdio/local.h to check std streams */
+extern void __sinit(struct _reent *);
+#define CHECK_INIT(ptr) \
+ do \
+ { \
+ if ((ptr) && !(ptr)->__sdidinit) \
+ __sinit (ptr); \
+ } \
+ while (0)
+
+static int monitor_stdin;
+static int monitor_stdout;
+static int monitor_stderr;
+
+/* Return a pointer to the structure associated with
+ the user file descriptor fd. */
+static struct fdent*
+findslot (int fd)
+{
+ CHECK_INIT(_REENT);
+
+ /* User file descriptor is out of range. */
+ if ((unsigned int)fd >= MAX_OPEN_FILES)
+ return NULL;
+
+ /* User file descriptor is open? */
+ if (openfiles[fd].handle == -1)
+ return NULL;
+
+ /* Valid. */
+ return &openfiles[fd];
+}
+
+/* Return the next lowest numbered free file
+ structure, or -1 if we can't find one. */
+static int
+newslot (void)
+{
+ int i;
+
+ for (i = 0; i < MAX_OPEN_FILES; i++)
+ if (openfiles[i].handle == -1)
+ break;
+
+ if (i == MAX_OPEN_FILES)
+ return -1;
+
+ return i;
+}
+
+void
+initialise_monitor_handles (void)
+{
+ int i;
+
+ /* Open the standard file descriptors by opening the special
+ * teletype device, ":tt", read-only to obtain a descritpor for
+ * standard input and write-only to obtain a descriptor for standard
+ * output. Finally, open ":tt" in append mode to obtain a descriptor
+ * for standard error. Since this is a write mode, most kernels will
+ * probably return the same value as for standard output, but the
+ * kernel can differentiate the two using the mode flag and return a
+ * different descriptor for standard error.
+ */
+
+#ifdef ARM_RDI_MONITOR
+ int volatile block[3];
+
+ block[0] = (int) ":tt";
+ block[2] = 3; /* length of filename */
+ block[1] = 0; /* mode "r" */
+ monitor_stdin = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
+
+ block[0] = (int) ":tt";
+ block[2] = 3; /* length of filename */
+ block[1] = 4; /* mode "w" */
+ monitor_stdout = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
+
+ block[0] = (int) ":tt";
+ block[2] = 3; /* length of filename */
+ block[1] = 8; /* mode "a" */
+ monitor_stderr = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
+#else
+ int fh;
+ const char * name;
+
+ name = ":tt";
+ __asm__ ("mov r0,%2; mov r1, #0; swi %a1; mov %0, r0"
+ : "=r"(fh)
+ : "i" (SWI_Open),"r"(name)
+ : "r0","r1");
+ monitor_stdin = fh;
+
+ name = ":tt";
+ __asm__ ("mov r0,%2; mov r1, #4; swi %a1; mov %0, r0"
+ : "=r"(fh)
+ : "i" (SWI_Open),"r"(name)
+ : "r0","r1");
+ monitor_stdout = fh;
+
+ name = ":tt";
+ __asm__ ("mov r0,%2; mov r1, #8; swi %a1; mov %0, r0"
+ : "=r"(fh)
+ : "i" (SWI_Open),"r"(name)
+ : "r0","r1");
+ monitor_stderr = fh;
+#endif
+
+ /* If we failed to open stderr, redirect to stdout. */
+ if (monitor_stderr == -1)
+ monitor_stderr = monitor_stdout;
+
+ for (i = 0; i < MAX_OPEN_FILES; i ++)
+ openfiles[i].handle = -1;
+
+ openfiles[0].handle = monitor_stdin;
+ openfiles[0].pos = 0;
+ openfiles[1].handle = monitor_stdout;
+ openfiles[1].pos = 0;
+ openfiles[2].handle = monitor_stderr;
+ openfiles[2].pos = 0;
+}
+
+static int
+get_errno (void)
+{
+#ifdef ARM_RDI_MONITOR
+ return do_AngelSWI (AngelSWI_Reason_Errno, NULL);
+#else
+ register int r0 __asm__ ("r0");
+ __asm__ ("swi %a1" : "=r"(r0) : "i" (SWI_GetErrno));
+ return r0;
+#endif
+}
+
+/* Set errno and return result. */
+static int
+error (int result)
+{
+ errno = get_errno ();
+ return result;
+}
+
+/* Check the return and set errno appropriately. */
+static int
+checkerror (int result)
+{
+ if (result == -1)
+ return error (-1);
+ return result;
+}
+
+/* fh, is a valid internal file handle.
+ ptr, is a null terminated string.
+ len, is the length in bytes to read.
+ Returns the number of bytes *not* written. */
+int
+gdbarmsim_swiread (int fh,
+ char * ptr,
+ int len)
+{
+#ifdef ARM_RDI_MONITOR
+ int block[3];
+
+ block[0] = fh;
+ block[1] = (int) ptr;
+ block[2] = len;
+
+ return checkerror (do_AngelSWI (AngelSWI_Reason_Read, block));
+#else
+ register int r0 __asm__ ("r0");
+ register int r1 __asm__ ("r1");
+ register int r2 __asm__ ("r2");
+ r0 = fh;
+ r1 = (int)ptr;
+ r2 = len;
+ __asm__ ("swi %a4"
+ : "=r" (r0)
+ : "0"(r0), "r"(r1), "r"(r2), "i"(SWI_Read));
+ return checkerror (r0);
+#endif
+}
+
+/* fd, is a valid user file handle.
+ Translates the return of _swiread into
+ bytes read. */
+int
+gdbarmsim_read (int fd,
+ char * ptr,
+ int len)
+{
+ int res;
+ struct fdent *pfd;
+
+ pfd = findslot (fd);
+ if (pfd == NULL)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ res = gdbarmsim_swiread (pfd->handle, ptr, len);
+
+ if (res == -1)
+ return res;
+
+ pfd->pos += len - res;
+
+ /* res == len is not an error,
+ at least if we want feof() to work. */
+ return len - res;
+}
+
+/* fd, is a user file descriptor. */
+int
+gdbarmsim_swilseek (int fd,
+ int ptr,
+ int dir)
+{
+ int res;
+ struct fdent *pfd;
+
+ /* Valid file descriptor? */
+ pfd = findslot (fd);
+ if (pfd == NULL)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ /* Valid whence? */
+ if ((dir != SEEK_CUR)
+ && (dir != SEEK_SET)
+ && (dir != SEEK_END))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Convert SEEK_CUR to SEEK_SET */
+ if (dir == SEEK_CUR)
+ {
+ ptr = pfd->pos + ptr;
+ /* The resulting file offset would be negative. */
+ if (ptr < 0)
+ {
+ errno = EINVAL;
+ if ((pfd->pos > 0) && (ptr > 0))
+ errno = EOVERFLOW;
+ return -1;
+ }
+ dir = SEEK_SET;
+ }
+
+#ifdef ARM_RDI_MONITOR
+ int block[2];
+ if (dir == SEEK_END)
+ {
+ block[0] = pfd->handle;
+ res = checkerror (do_AngelSWI (AngelSWI_Reason_FLen, block));
+ if (res == -1)
+ return -1;
+ ptr += res;
+ }
+
+ /* This code only does absolute seeks. */
+ block[0] = pfd->handle;
+ block[1] = ptr;
+ res = checkerror (do_AngelSWI (AngelSWI_Reason_Seek, block));
+#else
+ if (dir == SEEK_END)
+ {
+ __asm__ ("mov r0, %2; swi %a1; mov %0, r0"
+ : "=r" (res)
+ : "i" (SWI_Flen), "r" (pfd->handle)
+ : "r0");
+ checkerror (res);
+ if (res == -1)
+ return -1;
+ ptr += res;
+ }
+
+ /* This code only does absolute seeks. */
+ __asm__ ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0"
+ : "=r" (res)
+ : "i" (SWI_Seek), "r" (pfd->handle), "r" (ptr)
+ : "r0", "r1");
+ checkerror (res);
+#endif
+ /* At this point ptr is the current file position. */
+ if (res >= 0)
+ {
+ pfd->pos = ptr;
+ return ptr;
+ }
+ else
+ return -1;
+}
+
+int
+gdbarmsim_lseek (int fd,
+ int ptr,
+ int dir)
+{
+ return gdbarmsim_swilseek (fd, ptr, dir);
+}
+
+/* write a single character out the hosts stdout */
+int
+gdbarmsim_writec (const char c)
+{
+#ifdef ARM_RDI_MONITOR
+ int block[1];
+
+ block[0] = ((int) c) & 0xff;;
+
+ return checkerror (do_AngelSWI (AngelSWI_Reason_WriteC, block));
+#else
+ register int r0 __asm__ ("r0");
+ r0 = ((int) c) & 0xff;
+ __asm__ ("swi %a2"
+ : "=r" (r0)
+ : "0"(r0), "i"(SWI_WriteC));
+ return checkerror (r0);
+#endif
+}
+
+/* fh, is a valid internal file handle.
+ Returns the number of bytes *not* written. */
+int
+gdbarmsim_swiwrite (int fh,
+ char * ptr,
+ int len)
+{
+#ifdef ARM_RDI_MONITOR
+ int block[3];
+
+ block[0] = fh;
+ block[1] = (int) ptr;
+ block[2] = len;
+
+ return checkerror (do_AngelSWI (AngelSWI_Reason_Write, block));
+#else
+ register int r0 __asm__ ("r0");
+ register int r1 __asm__ ("r1");
+ register int r2 __asm__ ("r2");
+ r0 = fh;
+ r1 = (int)ptr;
+ r2 = len;
+ __asm__ ("swi %a4"
+ : "=r" (r0)
+ : "0"(r0), "r"(r1), "r"(r2), "i"(SWI_Write));
+ return checkerror (r0);
+#endif
+}
+
+/* fd, is a user file descriptor. */
+int
+gdbarmsim_write (int fd,
+ char * ptr,
+ int len)
+{
+ int res;
+ struct fdent *pfd;
+
+ pfd = findslot (fd);
+ if (pfd == NULL)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ res = gdbarmsim_swiwrite (pfd->handle, ptr,len);
+
+ /* Clearly an error. */
+ if (res < 0)
+ return -1;
+
+ pfd->pos += len - res;
+
+ /* We wrote 0 bytes?
+ Retrieve errno just in case. */
+ if ((len - res) == 0)
+ return error (0);
+
+ return (len - res);
+}
+
+int
+gdbarmsim_swiopen (const char * path, int flags)
+{
+ int aflags = 0, fh;
+#ifdef ARM_RDI_MONITOR
+ int block[3];
+#endif
+
+ int fd = newslot ();
+
+ if (fd == -1)
+ {
+ errno = EMFILE;
+ return -1;
+ }
+
+ /* It is an error to open a file that already exists. */
+ if ((flags & O_CREAT)
+ && (flags & O_EXCL))
+ {
+ struct stat st;
+ int res;
+ res = gdbarmsim_stat (path, &st);
+ if (res != -1)
+ {
+ errno = EEXIST;
+ return -1;
+ }
+ }
+
+ /* The flags are Unix-style, so we need to convert them. */
+#ifdef O_BINARY
+ if (flags & O_BINARY)
+ aflags |= 1;
+#endif
+
+ /* In O_RDONLY we expect aflags == 0. */
+
+ if (flags & O_RDWR)
+ aflags |= 2;
+
+ if ((flags & O_CREAT)
+ || (flags & O_TRUNC)
+ || (flags & O_WRONLY))
+ aflags |= 4;
+
+ if (flags & O_APPEND)
+ {
+ /* Can't ask for w AND a; means just 'a'. */
+ aflags &= ~4;
+ aflags |= 8;
+ }
+
+#ifdef ARM_RDI_MONITOR
+ block[0] = (int) path;
+ block[2] = strlen (path);
+ block[1] = aflags;
+
+ fh = do_AngelSWI (AngelSWI_Reason_Open, block);
+
+#else
+ __asm__ ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0"
+ : "=r"(fh)
+ : "i" (SWI_Open),"r"(path),"r"(aflags)
+ : "r0","r1");
+#endif
+
+ /* Return a user file descriptor or an error. */
+ if (fh >= 0)
+ {
+ openfiles[fd].handle = fh;
+ openfiles[fd].pos = 0;
+ return fd;
+ }
+ else
+ return error (fh);
+}
+
+int
+gdbarmsim_open (const char * path, int flags, ...)
+{
+ return gdbarmsim_swiopen (path, flags);
+}
+
+/* fh, is a valid internal file handle. */
+int
+gdbarmsim_swiclose (int fh)
+{
+#ifdef ARM_RDI_MONITOR
+ return checkerror (do_AngelSWI (AngelSWI_Reason_Close, &fh));
+#else
+ register int r0 __asm__ ("r0");
+ r0 = fh;
+ __asm__ ("swi %a2"
+ : "=r"(r0)
+ : "0"(r0), "i" (SWI_Close));
+ return checkerror (r0);
+#endif
+}
+
+/* fd, is a user file descriptor. */
+int
+gdbarmsim_close (int fd)
+{
+ int res;
+ struct fdent *pfd;
+
+ pfd = findslot (fd);
+ if (pfd == NULL)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ /* Handle stderr == stdout. */
+ if ((fd == 1 || fd == 2)
+ && (openfiles[1].handle == openfiles[2].handle))
+ {
+ pfd->handle = -1;
+ return 0;
+ }
+
+ /* Attempt to close the handle. */
+ res = gdbarmsim_swiclose (pfd->handle);
+
+ /* Reclaim handle? */
+ if (res == 0)
+ pfd->handle = -1;
+
+ return res;
+}
+
+int
+gdbarmsim_swistat (int fd, struct stat * st)
+{
+ struct fdent *pfd;
+ int res;
+
+ pfd = findslot (fd);
+ if (pfd == NULL)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ /* Always assume a character device,
+ with 1024 byte blocks. */
+ st->st_mode |= S_IFCHR;
+ st->st_blksize = 1024;
+#ifdef ARM_RDI_MONITOR
+ res = checkerror (do_AngelSWI (AngelSWI_Reason_FLen, &pfd->handle));
+#else
+ __asm__ ("mov r0, %2; swi %a1; mov %0, r0"
+ : "=r" (res)
+ : "i" (SWI_Flen), "r" (pfd->handle)
+ : "r0");
+ checkerror (res);
+#endif
+ if (res == -1)
+ return -1;
+ /* Return the file size. */
+ st->st_size = res;
+ return 0;
+}
+
+int
+gdbarmsim_fstat (int fd, struct stat * st)
+{
+ memset (st, 0, sizeof (* st));
+ return gdbarmsim_swistat (fd, st);
+}
+
+int
+gdbarmsim_stat (const char *fname, struct stat *st)
+{
+ int fd, res;
+ memset (st, 0, sizeof (* st));
+ /* The best we can do is try to open the file readonly.
+ If it exists, then we can guess a few things about it. */
+ if ((fd = gdbarmsim_open (fname, O_RDONLY)) == -1)
+ return -1;
+ st->st_mode |= S_IFREG | S_IREAD;
+ res = gdbarmsim_swistat (fd, st);
+ /* Not interested in the error. */
+ gdbarmsim_close (fd);
+ return res;
+}
+
+int
+gdbarmsim_unlink (const char *path)
+{
+ int res;
+#ifdef ARM_RDI_MONITOR
+ int block[2];
+ block[0] = (int)path;
+ block[1] = strlen(path);
+ res = do_AngelSWI (AngelSWI_Reason_Remove, block);
+#else
+ register int r0 __asm__ ("r0");
+ r0 = (int)path;
+ __asm__ ("swi %a2"
+ : "=r"(r0)
+ : "0"(r0), "i" (SWI_Remove));
+ res = r0;
+#endif
+ if (res == -1)
+ return error (res);
+ return 0;
+}
+
+/* Return a clock that ticks at 100Hz. */
+clock_t
+gdbarmsim_clock (void)
+{
+ clock_t timeval;
+
+#ifdef ARM_RDI_MONITOR
+ timeval = do_AngelSWI (AngelSWI_Reason_Clock,NULL);
+#else
+ __asm__ ("swi %a1; mov %0, r0" : "=r" (timeval): "i" (SWI_Clock) : "r0");
+#endif
+ return timeval;
+}
+
+int
+gdbarmsim__isatty (int fd)
+{
+ struct fdent *pfd;
+
+ pfd = findslot (fd);
+ if (pfd == NULL)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+#ifdef ARM_RDI_MONITOR
+ return checkerror (do_AngelSWI (AngelSWI_Reason_IsTTY, &pfd->handle));
+#else
+ register int r0 __asm__ ("r0");
+ r0 = pfd->handle;
+ __asm__ ("swi %a2"
+ : "=r" (r0)
+ : "0"(r0), "i" (SWI_IsTTY));
+ return checkerror (r0);
+#endif
+}
+
+int
+gdbarmsim_system (const char *s)
+{
+#ifdef ARM_RDI_MONITOR
+ int block[2];
+ int e;
+
+ /* Hmmm. The ARM debug interface specification doesn't say whether
+ SYS_SYSTEM does the right thing with a null argument, or assign any
+ meaning to its return value. Try to do something reasonable.... */
+ if (!s)
+ return 1; /* maybe there is a shell available? we can hope. :-P */
+ block[0] = (int)s;
+ block[1] = strlen (s);
+ e = checkerror (do_AngelSWI (AngelSWI_Reason_System, block));
+ if ((e >= 0) && (e < 256))
+ {
+ /* We have to convert e, an exit status to the encoded status of
+ the command. To avoid hard coding the exit status, we simply
+ loop until we find the right position. */
+ int exit_code;
+
+ for (exit_code = e; e && WEXITSTATUS (e) != exit_code; e <<= 1)
+ continue;
+ }
+ return e;
+#else
+ register int r0 __asm__ ("r0");
+ r0 = (int)s;
+ __asm__ ("swi %a2"
+ : "=r" (r0)
+ : "0"(r0), "i" (SWI_CLI));
+ return checkerror (r0);
+#endif
+}
+
+int
+gdbarmsim_rename (const char * oldpath, const char * newpath)
+{
+#ifdef ARM_RDI_MONITOR
+ int block[4];
+ block[0] = (int)oldpath;
+ block[1] = strlen(oldpath);
+ block[2] = (int)newpath;
+ block[3] = strlen(newpath);
+ return checkerror (do_AngelSWI (AngelSWI_Reason_Rename, block)) ? -1 : 0;
+#else
+ register int r0 __asm__ ("r0");
+ register int r1 __asm__ ("r1");
+ r0 = (int)oldpath;
+ r1 = (int)newpath;
+ __asm__ ("swi %a3"
+ : "=r" (r0)
+ : "0" (r0), "r" (r1), "i" (SWI_Rename));
+ return checkerror (r0);
+#endif
+}
diff --git a/bsps/arm/gumstix/start/bsp_specs b/bsps/arm/gumstix/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/gumstix/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/gumstix/start/bspreset.c b/bsps/arm/gumstix/start/bspreset.c
new file mode 100644
index 0000000000..ab7c5ffc8f
--- /dev/null
+++ b/bsps/arm/gumstix/start/bspreset.c
@@ -0,0 +1,18 @@
+/*
+ * By Yang Xi <hiyangxi@gmail.com>.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <pxa255.h>
+
+void bsp_reset( void )
+{
+#if ON_SKYEYE == 1
+ SKYEYE_MAGIC_ADDRESS = 0xff;
+#endif
+}
diff --git a/bsps/arm/gumstix/start/bspstart.c b/bsps/arm/gumstix/start/bspstart.c
new file mode 100644
index 0000000000..f86bf3d6e3
--- /dev/null
+++ b/bsps/arm/gumstix/start/bspstart.c
@@ -0,0 +1,40 @@
+/*
+ * By Yang Xi <hiyangxi@gmail.com>.
+ *
+ * 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/irq-generic.h>
+#include <rtems/libcsupport.h>
+#include <rtems/libio.h>
+#include <pxa255.h>
+
+/*
+ *
+ * NAME: bsp_start_default - BSP initialization function
+ *
+ * DESCRIPTION:
+ * This function is called before RTEMS is initialized and used
+ * adjust the kernel's configuration.
+ *
+ * This function also configures the CPU's memory protection unit.
+ *
+ * RESTRICTIONS/LIMITATIONS:
+ * Since RTEMS is not configured, no RTEMS functions can be called.
+ *
+ */
+static void bsp_start_default( void )
+{
+ /* disable interrupts */
+ XSCALE_INT_ICMR = 0x0;
+ bsp_interrupt_initialize();
+} /* bsp_start */
+
+/*
+ * By making this a weak alias for bsp_start_default, a brave soul
+ * can override the actual bsp_start routine used.
+ */
+void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
diff --git a/bsps/arm/gumstix/start/linkcmds b/bsps/arm/gumstix/start/linkcmds
new file mode 100644
index 0000000000..08cb2fc47a
--- /dev/null
+++ b/bsps/arm/gumstix/start/linkcmds
@@ -0,0 +1,27 @@
+MEMORY {
+ SDRAM_MMU : ORIGIN = 0xa0000000, LENGTH = 16k
+ SDRAM : ORIGIN = 0xa0004000, LENGTH = 64M - 16k
+ SRAM : ORIGIN = 0x00000000, LENGTH = 16k
+}
+
+REGION_ALIAS ("REGION_START", SDRAM);
+REGION_ALIAS ("REGION_VECTOR", SDRAM);
+REGION_ALIAS ("REGION_TEXT", SDRAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_RODATA", SDRAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_DATA", SDRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_BSS", SDRAM);
+REGION_ALIAS ("REGION_WORK", SDRAM);
+REGION_ALIAS ("REGION_STACK", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", SDRAM);
+
+_ttbl_base = ORIGIN (SDRAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/gumstix/start/memmap.c b/bsps/arm/gumstix/start/memmap.c
new file mode 100644
index 0000000000..8923083576
--- /dev/null
+++ b/bsps/arm/gumstix/start/memmap.c
@@ -0,0 +1,17 @@
+/*
+ * Gumstix Memory Map
+ * 2008 By Yang Xi <hiyangxi@gmail.com>
+ * Copyright (c) 2004 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ */
+
+#include <rtems.h>
+#include <libcpu/mmu.h>
+
+mmu_sect_map_t mem_map[] = {
+/* <phys addr> <virt addr> <size> <flags> */
+ {0x40000000, 0x40000000, 1216, MMU_CACHE_NONE}, /*Map I/O*/
+ {0xA0000000, 0x00000000, 1, MMU_CACHE_NONE}, /*sram*/
+ {0xA0000000, 0xA0000000, 64, MMU_CACHE_WBACK}, /* SDRAM */
+ {0x00000000, 0x00000000, 0, 0} /* The end */
+};
diff --git a/bsps/arm/imx/start/bsp_specs b/bsps/arm/imx/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/imx/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/imx/start/bspreset.c b/bsps/arm/imx/start/bspreset.c
new file mode 100644
index 0000000000..c3c9f69566
--- /dev/null
+++ b/bsps/arm/imx/start/bspreset.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/bootcard.h>
+#include <bsp.h>
+#include <arm/freescale/imx/imx_wdogreg.h>
+
+void bsp_reset(void)
+{
+ volatile uint16_t *pcr;
+
+ imx_uart_console_drain();
+
+ pcr = (volatile uint16_t *) 0x30280000;
+ *pcr = WDOG_CR_WDE;
+ *pcr = WDOG_CR_WDE;
+ *pcr = WDOG_CR_WDE;
+
+ while (true) {
+ /* Wait */
+ }
+}
diff --git a/bsps/arm/imx/start/bspsmp.c b/bsps/arm/imx/start/bspsmp.c
new file mode 100644
index 0000000000..51c7aef12a
--- /dev/null
+++ b/bsps/arm/imx/start/bspsmp.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/score/smpimpl.h>
+
+#include <arm/freescale/imx/imx_srcreg.h>
+#include <arm/freescale/imx/imx_gpcreg.h>
+
+#include <bsp/start.h>
+
+bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+{
+ bool started;
+
+ if (cpu_index == 1) {
+ volatile imx_src *src = (volatile imx_src *) 0x30390000;
+ volatile imx_gpc *gpc = (volatile imx_gpc *) 0x303a0000;
+
+ src->gpr3 = (uint32_t) _start;
+ gpc->pgc_a7core0_ctrl |= IMX_GPC_PGC_CTRL_PCR;
+ gpc->cpu_pgc_sw_pup_req |= IMX_GPC_CPU_PGC_CORE1_A7;
+
+ while ((gpc->cpu_pgc_pup_status1 & IMX_GPC_CPU_PGC_CORE1_A7) != 0) {
+ /* Wait */
+ }
+
+ gpc->pgc_a7core0_ctrl &= ~IMX_GPC_PGC_CTRL_PCR;
+ src->a7rcr1 |= IMX_SRC_A7RCR1_A7_CORE1_ENABLE;
+
+ started = true;
+ } else {
+ started = false;
+ }
+
+ return started;
+}
diff --git a/bsps/arm/imx/start/bspstart.c b/bsps/arm/imx/start/bspstart.c
new file mode 100644
index 0000000000..046336655b
--- /dev/null
+++ b/bsps/arm/imx/start/bspstart.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/fatal.h>
+#include <bsp/fdt.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+
+#include <libfdt.h>
+
+#define MAGIC_IRQ_OFFSET 32
+
+void *imx_get_reg_of_node(const void *fdt, int node)
+{
+ int len;
+ const uint32_t *val;
+
+ val = fdt_getprop(fdt, node, "reg", &len);
+ if (val == NULL || len < 4) {
+ return NULL;
+ }
+
+ return (void *) fdt32_to_cpu(val[0]);
+}
+
+rtems_vector_number imx_get_irq_of_node(
+ const void *fdt,
+ int node,
+ size_t index
+)
+{
+ int len;
+ const uint32_t *val;
+
+ val = fdt_getprop(fdt, node, "interrupts", &len);
+ if (val == NULL || len < (int) ((index + 1) * 12)) {
+ return UINT32_MAX;
+ }
+
+ return fdt32_to_cpu(val[index * 3 + 1]) + MAGIC_IRQ_OFFSET;
+}
+
+uint32_t bsp_fdt_map_intr(const uint32_t *intr, size_t icells)
+{
+ return intr[1] + MAGIC_IRQ_OFFSET;
+}
+
+void arm_generic_timer_get_config(
+ uint32_t *frequency,
+ uint32_t *irq
+)
+{
+ const void *fdt;
+ int node;
+ int len;
+ const uint32_t *val;
+
+ fdt = bsp_fdt_get();
+ node = fdt_path_offset(fdt, "/timer");
+
+ val = fdt_getprop(fdt, node, "clock-frequency", &len);
+ if (val != NULL && len >= 4) {
+ *frequency = fdt32_to_cpu(val[0]);
+ } else {
+ bsp_fatal(IMX_FATAL_GENERIC_TIMER_FREQUENCY);
+ }
+
+ /* FIXME: Figure out how Linux gets a proper IRQ number */
+ *irq = imx_get_irq_of_node(fdt, node, 0) - 16;
+}
+
+void bsp_start(void)
+{
+ bsp_interrupt_initialize();
+ rtems_cache_coherent_add_area(
+ bsp_section_nocacheheap_begin,
+ (uintptr_t) bsp_section_nocacheheap_size
+ );
+}
diff --git a/bsps/arm/imx/start/bspstarthooks.c b/bsps/arm/imx/start/bspstarthooks.c
new file mode 100644
index 0000000000..c75b03415b
--- /dev/null
+++ b/bsps/arm/imx/start/bspstarthooks.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/arm-a9mpcore-start.h>
+
+BSP_START_DATA_SECTION static const arm_cp15_start_section_config
+imx_mmu_config_table[] = {
+ ARMV7_CP15_START_DEFAULT_SECTIONS,
+ {
+ .begin = 0x07000000U,
+ .end = 0x70000000U,
+ .flags = ARMV7_MMU_DEVICE
+ }
+};
+
+BSP_START_TEXT_SECTION static void setup_mmu_and_cache(void)
+{
+ uint32_t ctrl = arm_cp15_start_setup_mmu_and_cache(
+ ARM_CP15_CTRL_A,
+ ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z
+ );
+
+ arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
+ ctrl,
+ (uint32_t *) bsp_translation_table_base,
+ ARM_MMU_DEFAULT_CLIENT_DOMAIN,
+ &imx_mmu_config_table[0],
+ RTEMS_ARRAY_SIZE(imx_mmu_config_table)
+ );
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+{
+#ifdef RTEMS_SMP
+ uint32_t cpu_id = arm_cortex_a9_get_multiprocessor_cpu_id();
+
+ arm_a9mpcore_start_enable_smp_in_auxiliary_control();
+
+ if (cpu_id != 0) {
+ arm_a9mpcore_start_on_secondary_processor();
+ }
+#endif
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+{
+ arm_a9mpcore_start_set_vector_base();
+ bsp_start_copy_sections();
+ setup_mmu_and_cache();
+ bsp_start_clear_bss();
+}
diff --git a/bsps/arm/imx/start/ccm.c b/bsps/arm/imx/start/ccm.c
new file mode 100644
index 0000000000..bbb72db639
--- /dev/null
+++ b/bsps/arm/imx/start/ccm.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdint.h>
+#include <bspopts.h>
+
+#include <arm/freescale/imx/imx_ccmvar.h>
+
+uint32_t imx_ccm_ipg_hz(void)
+{
+ return IMX_CCM_IPG_HZ;
+}
+
+uint32_t imx_ccm_uart_hz(void)
+{
+ return IMX_CCM_UART_HZ;
+}
+
+uint32_t imx_ccm_ahb_hz(void)
+{
+ return IMX_CCM_AHB_HZ;
+}
diff --git a/bsps/arm/imx/start/imx_iomux.c b/bsps/arm/imx/start/imx_iomux.c
new file mode 100644
index 0000000000..cd4591fa6f
--- /dev/null
+++ b/bsps/arm/imx/start/imx_iomux.c
@@ -0,0 +1,424 @@
+/*-
+ * Copyright (c) 2014 Ian Lepore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/sys/arm/freescale/imx/imx_iomux.c 321938 2017-08-02 18:28:06Z ian $
+ */
+
+/*
+ * Pin mux and pad control driver for imx5 and imx6.
+ *
+ * This driver implements the fdt_pinctrl interface for configuring the gpio and
+ * peripheral pins based on fdt configuration data.
+ *
+ * When the driver attaches, it walks the entire fdt tree and automatically
+ * configures the pins for each device which has a pinctrl-0 property and whose
+ * status is "okay". In addition it implements the fdt_pinctrl_configure()
+ * method which any other driver can call at any time to reconfigure its pins.
+ *
+ * The nature of the fsl,pins property in fdt data makes this driver's job very
+ * easy. Instead of representing each pin and pad configuration using symbolic
+ * properties such as pullup-enable="true" and so on, the data simply contains
+ * the addresses of the registers that control the pins, and the raw values to
+ * store in those registers.
+ *
+ * The imx5 and imx6 SoCs also have a small number of "general purpose
+ * registers" in the iomuxc device which are used to control an assortment
+ * of completely unrelated aspects of SoC behavior. This driver provides other
+ * drivers with direct access to those registers via simple accessor functions.
+ */
+
+#include <sys/param.h>
+#ifndef __rtems__
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/fdt/fdt_pinctrl.h>
+#endif /* __rtems__ */
+
+#include <arm/freescale/imx/imx_iomuxvar.h>
+#ifndef __rtems__
+#include <arm/freescale/imx/imx_machdep.h>
+#else /* __rtems__ */
+#include <bsp.h>
+#include <bsp/fdt.h>
+#include <rtems/sysinit.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <stdlib.h>
+
+typedef size_t bus_size_t;
+typedef int phandle_t;
+#endif /* __rtems__ */
+
+struct iomux_softc {
+#ifndef __rtems__
+ device_t dev;
+ struct resource *mem_res;
+ u_int last_gpregaddr;
+#else /* __rtems__ */
+ volatile uint32_t *regs;
+#endif /* __rtems__ */
+};
+
+#ifndef __rtems__
+static struct iomux_softc *iomux_sc;
+
+static struct ofw_compat_data compat_data[] = {
+ {"fsl,imx6dl-iomuxc", true},
+ {"fsl,imx6q-iomuxc", true},
+ {"fsl,imx6sl-iomuxc", true},
+ {"fsl,imx6ul-iomuxc", true},
+ {"fsl,imx6sx-iomuxc", true},
+ {"fsl,imx53-iomuxc", true},
+ {"fsl,imx51-iomuxc", true},
+ {NULL, false},
+};
+#else /* __rtems__ */
+static struct iomux_softc iomux_sc_instance;
+
+#define iomux_sc (&iomux_sc_instance);
+
+static void
+imx_iomux_init(void)
+{
+ const void *fdt;
+ int node;
+ struct iomux_softc *sc;
+
+ fdt = bsp_fdt_get();
+ node = fdt_node_offset_by_compatible(fdt, -1, "fsl,imx7d-iomuxc");
+ sc = iomux_sc;
+ sc->regs = imx_get_reg_of_node(fdt, node);
+}
+
+RTEMS_SYSINIT_ITEM(imx_iomux_init, RTEMS_SYSINIT_BSP_START,
+ RTEMS_SYSINIT_ORDER_MIDDLE);
+
+#define OF_node_from_xref(phandle) fdt_node_offset_by_phandle(fdt, phandle)
+
+static int
+imx_iomux_getencprop_alloc(const char *fdt, int node, const char *name,
+ size_t elsz, void **buf)
+{
+ int len;
+ const uint32_t *val;
+ int i;
+ uint32_t *cell;
+
+ val = fdt_getprop(fdt, node, "fsl,pins", &len);
+ if (val == NULL || len < 0 || len % elsz != 0) {
+ return (-1);
+ }
+
+ cell = malloc((size_t)len);
+ *buf = cell;
+ if (cell == NULL) {
+ return (-1);
+ }
+
+ for (i = 0; i < len / 4; ++i) {
+ cell[i] = fdt32_to_cpu(val[i]);
+ }
+
+ return (len / (int)elsz);
+}
+
+#define OF_getencprop_alloc(node, name, elsz, buf) \
+ imx_iomux_getencprop_alloc(fdt, node, name, elsz, buf)
+
+#define OF_prop_free(buf) free(buf)
+#endif /* __rtems__ */
+
+/*
+ * Each tuple in an fsl,pins property contains these fields.
+ */
+struct pincfg {
+ uint32_t mux_reg;
+ uint32_t padconf_reg;
+ uint32_t input_reg;
+ uint32_t mux_val;
+ uint32_t input_val;
+ uint32_t padconf_val;
+};
+
+#define PADCONF_NONE (1U << 31) /* Do not configure pad. */
+#define PADCONF_SION (1U << 30) /* Force SION bit in mux register. */
+#define PADMUX_SION (1U << 4) /* The SION bit in the mux register. */
+
+static inline uint32_t
+RD4(struct iomux_softc *sc, bus_size_t off)
+{
+
+#ifndef __rtems__
+ return (bus_read_4(sc->mem_res, off));
+#else /* __rtems__ */
+ return (sc->regs[off / 4]);
+#endif /* __rtems__ */
+}
+
+static inline void
+WR4(struct iomux_softc *sc, bus_size_t off, uint32_t val)
+{
+
+#ifndef __rtems__
+ bus_write_4(sc->mem_res, off, val);
+#else /* __rtems__ */
+ sc->regs[off / 4] = val;
+#endif /* __rtems__ */
+}
+
+static void
+iomux_configure_input(struct iomux_softc *sc, uint32_t reg, uint32_t val)
+{
+ u_int select, mask, shift, width;
+
+ /* If register and value are zero, there is nothing to configure. */
+ if (reg == 0 && val == 0)
+ return;
+
+ /*
+ * If the config value has 0xff in the high byte it is encoded:
+ * 31 23 15 7 0
+ * | 0xff | shift | width | select |
+ * We need to mask out the old select value and OR in the new, using a
+ * mask of the given width and shifting the values up by shift.
+ */
+ if ((val & 0xff000000) == 0xff000000) {
+ select = val & 0x000000ff;
+ width = (val & 0x0000ff00) >> 8;
+ shift = (val & 0x00ff0000) >> 16;
+ mask = ((1u << width) - 1) << shift;
+ val = (RD4(sc, reg) & ~mask) | (select << shift);
+ }
+ WR4(sc, reg, val);
+}
+
+#ifndef __rtems__
+static int
+iomux_configure_pins(device_t dev, phandle_t cfgxref)
+#else /* __rtems__ */
+int imx_iomux_configure_pins(const void *fdt, uint32_t cfgxref)
+#endif /* __rtems__ */
+{
+ struct iomux_softc *sc;
+ struct pincfg *cfgtuples, *cfg;
+ phandle_t cfgnode;
+ int i, ntuples;
+ uint32_t sion;
+
+#ifndef __rtems__
+ sc = device_get_softc(dev);
+#else /* __rtems__ */
+ sc = iomux_sc;
+#endif /* __rtems__ */
+ cfgnode = OF_node_from_xref(cfgxref);
+ ntuples = OF_getencprop_alloc(cfgnode, "fsl,pins", sizeof(*cfgtuples),
+ (void **)&cfgtuples);
+ if (ntuples < 0)
+ return (ENOENT);
+ if (ntuples == 0)
+ return (0); /* Empty property is not an error. */
+ for (i = 0, cfg = cfgtuples; i < ntuples; i++, cfg++) {
+ sion = (cfg->padconf_val & PADCONF_SION) ? PADMUX_SION : 0;
+ WR4(sc, cfg->mux_reg, cfg->mux_val | sion);
+ iomux_configure_input(sc, cfg->input_reg, cfg->input_val);
+ if ((cfg->padconf_val & PADCONF_NONE) == 0)
+ WR4(sc, cfg->padconf_reg, cfg->padconf_val);
+#ifndef __rtems__
+ if (bootverbose) {
+ char name[32];
+ OF_getprop(cfgnode, "name", &name, sizeof(name));
+ printf("%16s: muxreg 0x%04x muxval 0x%02x "
+ "inpreg 0x%04x inpval 0x%02x "
+ "padreg 0x%04x padval 0x%08x\n",
+ name, cfg->mux_reg, cfg->mux_val | sion,
+ cfg->input_reg, cfg->input_val,
+ cfg->padconf_reg, cfg->padconf_val);
+ }
+#endif /* __rtems__ */
+ }
+ OF_prop_free(cfgtuples);
+ return (0);
+}
+
+#ifndef __rtems__
+static int
+iomux_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+ return (ENXIO);
+
+ device_set_desc(dev, "Freescale i.MX pin configuration");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+iomux_detach(device_t dev)
+{
+
+ /* This device is always present. */
+ return (EBUSY);
+}
+
+static int
+iomux_attach(device_t dev)
+{
+ struct iomux_softc * sc;
+ int rid;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ switch (imx_soc_type()) {
+ case IMXSOC_51:
+ sc->last_gpregaddr = 1 * sizeof(uint32_t);
+ break;
+ case IMXSOC_53:
+ sc->last_gpregaddr = 2 * sizeof(uint32_t);
+ break;
+ case IMXSOC_6DL:
+ case IMXSOC_6S:
+ case IMXSOC_6SL:
+ case IMXSOC_6Q:
+ sc->last_gpregaddr = 13 * sizeof(uint32_t);
+ break;
+ case IMXSOC_6UL:
+ sc->last_gpregaddr = 14 * sizeof(uint32_t);
+ break;
+ default:
+ device_printf(dev, "Unknown SoC type\n");
+ return (ENXIO);
+ }
+
+ rid = 0;
+ sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (sc->mem_res == NULL) {
+ device_printf(dev, "Cannot allocate memory resources\n");
+ return (ENXIO);
+ }
+
+ iomux_sc = sc;
+
+ /*
+ * Register as a pinctrl device, and call the convenience function that
+ * walks the entire device tree invoking FDT_PINCTRL_CONFIGURE() on any
+ * pinctrl-0 property cells whose xref phandle refers to a configuration
+ * that is a child node of our node in the tree.
+ *
+ * The pinctrl bindings documentation specifically mentions that the
+ * pinctrl device itself may have a pinctrl-0 property which contains
+ * static configuration to be applied at device init time. The tree
+ * walk will automatically handle this for us when it passes through our
+ * node in the tree.
+ */
+ fdt_pinctrl_register(dev, "fsl,pins");
+ fdt_pinctrl_configure_tree(dev);
+
+ return (0);
+}
+
+uint32_t
+imx_iomux_gpr_get(u_int regaddr)
+{
+ struct iomux_softc * sc;
+
+ sc = iomux_sc;
+ KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__));
+ KASSERT(regaddr >= 0 && regaddr <= sc->last_gpregaddr,
+ ("%s bad regaddr %u, max %u", __FUNCTION__, regaddr,
+ sc->last_gpregaddr));
+
+ return (RD4(iomux_sc, regaddr));
+}
+
+void
+imx_iomux_gpr_set(u_int regaddr, uint32_t val)
+{
+ struct iomux_softc * sc;
+
+ sc = iomux_sc;
+ KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__));
+ KASSERT(regaddr >= 0 && regaddr <= sc->last_gpregaddr,
+ ("%s bad regaddr %u, max %u", __FUNCTION__, regaddr,
+ sc->last_gpregaddr));
+
+ WR4(iomux_sc, regaddr, val);
+}
+
+void
+imx_iomux_gpr_set_masked(u_int regaddr, uint32_t clrbits, uint32_t setbits)
+{
+ struct iomux_softc * sc;
+ uint32_t val;
+
+ sc = iomux_sc;
+ KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__));
+ KASSERT(regaddr >= 0 && regaddr <= sc->last_gpregaddr,
+ ("%s bad regaddr %u, max %u", __FUNCTION__, regaddr,
+ sc->last_gpregaddr));
+
+ val = RD4(iomux_sc, regaddr * 4);
+ val = (val & ~clrbits) | setbits;
+ WR4(iomux_sc, regaddr, val);
+}
+
+static device_method_t imx_iomux_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, iomux_probe),
+ DEVMETHOD(device_attach, iomux_attach),
+ DEVMETHOD(device_detach, iomux_detach),
+
+ /* fdt_pinctrl interface */
+ DEVMETHOD(fdt_pinctrl_configure,iomux_configure_pins),
+
+ DEVMETHOD_END
+};
+
+static driver_t imx_iomux_driver = {
+ "imx_iomux",
+ imx_iomux_methods,
+ sizeof(struct iomux_softc),
+};
+
+static devclass_t imx_iomux_devclass;
+
+EARLY_DRIVER_MODULE(imx_iomux, simplebus, imx_iomux_driver,
+ imx_iomux_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_LATE);
+
+#endif /* __rtems__ */
diff --git a/bsps/arm/imx/start/linkcmds.imx7 b/bsps/arm/imx/start/linkcmds.imx7
new file mode 100644
index 0000000000..750e1def1d
--- /dev/null
+++ b/bsps/arm/imx/start/linkcmds.imx7
@@ -0,0 +1,37 @@
+MEMORY {
+ RAM_MMU : ORIGIN = 0x80000000, LENGTH = 16k
+ NOCACHE : ORIGIN = 0x80100000, LENGTH = 1M
+ RAM : ORIGIN = 0x80200000, LENGTH = 512M - 2M
+}
+
+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", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", NOCACHE);
+
+bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 2;
+
+bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
+bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
+
+bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1M;
+
+bsp_vector_table_in_start_section = 1;
+
+bsp_translation_table_base = ORIGIN (RAM_MMU);
+bsp_translation_table_end = ORIGIN (RAM_MMU) + LENGTH (RAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lm3s69xx/start/bsp_specs b/bsps/arm/lm3s69xx/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/lm3s69xx/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/lm3s69xx/start/bspstart.c b/bsps/arm/lm3s69xx/start/bspstart.c
new file mode 100644
index 0000000000..da3029e58c
--- /dev/null
+++ b/bsps/arm/lm3s69xx/start/bspstart.c
@@ -0,0 +1,155 @@
+/*
+ * This routine does the bulk of the system initialization.
+ */
+
+/*
+ * Copyright © 2013 Eugeniy Meshcheryakov <eugen@debian.org>
+ *
+ * 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/bootcard.h>
+#include <bsp/irq-generic.h>
+#include <bsp/lm3s69xx.h>
+#include <bsp/io.h>
+#include <bsp/syscon.h>
+#include <assert.h>
+
+static void init_main_osc(void)
+{
+ volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON;
+
+ uint32_t sysdiv_val = LM3S69XX_PLL_FREQUENCY / LM3S69XX_SYSTEM_CLOCK;
+#if defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM3S3749)
+ assert(sysdiv_val * LM3S69XX_SYSTEM_CLOCK == LM3S69XX_PLL_FREQUENCY);
+#endif
+ assert((sysdiv_val >= 4) && (sysdiv_val <= 16));
+
+ uint32_t rcc = syscon->rcc;
+ uint32_t rcc2 = syscon->rcc2;
+
+ rcc = (rcc & ~SYSCONRCC_USESYSDIV) | SYSCONRCC_BYPASS;
+ rcc2 |= SYSCONRCC2_BYPASS2;
+
+ syscon->rcc = rcc;
+ syscon->rcc2 = rcc2;
+
+ /*
+ As per a note in Stellaris® LM4F120H5QR Microcontroller Data
+ Sheet on page 219: "When transitioning the system clock
+ configuration to use the MOSC as the fundamental clock source, the
+ MOSCDIS bit must be set prior to reselecting the MOSC or an
+ undefined system clock configuration can sporadically occur."
+ */
+
+ rcc |= SYSCONRCC_MOSCDIS;
+ syscon->rcc = rcc;
+
+ rcc = (rcc & ~(SYSCONRCC_XTAL_MSK))
+ | SYSCONRCC_XTAL(LM3S69XX_XTAL_CONFIG);
+ rcc2 = (rcc2 & ~(SYSCONRCC2_PWRDN2 | SYSCONRCC2_OSCSRC2_MSK))
+ | SYSCONRCC2_USERCC2 | SYSCONRCC2_OSCSRC2(0x0);
+
+ /* clear PLL lock interrupt */
+ syscon->misc &= (SYSCONMISC_PLLLMIS);
+
+ syscon->rcc = rcc;
+ syscon->rcc2 = rcc2;
+ lm3s69xx_syscon_delay_3x_clocks(16);
+
+ /* since now, we'll use only RCC2 as SYSCONRCC2_USERCC2 and XTAL
+ (only available in RCC) are already set */
+
+ if (sysdiv_val % 2 == 0) {
+ rcc2 = (rcc2 & ~SYSCONRCC2_SYSDIV2_MSK) | SYSCONRCC2_SYSDIV2(sysdiv_val / 2 - 1);
+
+ rcc2 &= ~(SYSCONRCC2_DIV400);
+ }
+ else {
+ /* need to use DIV400 */
+ rcc2 = (rcc2 & ~SYSCONRCC2_SYSDIV2EXT_MSK) | SYSCONRCC2_SYSDIV2EXT(sysdiv_val - 1)
+ | SYSCONRCC2_DIV400;
+ }
+ syscon->rcc2 = rcc2;
+
+ while ((syscon->ris & SYSCONRIS_PLLLRIS) == 0)
+ /* Wait for PLL lock */;
+
+ rcc2 &= ~(SYSCONRCC2_BYPASS2);
+
+ syscon->rcc2 = rcc2;
+ lm3s69xx_syscon_delay_3x_clocks(16);
+}
+
+static const lm3s69xx_gpio_config start_config_gpio[] = {
+#ifdef LM3S69XX_ENABLE_UART_0
+#if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM4F120)
+ LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_A, 0),
+ LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_A, 1),
+#else
+#error No GPIO pin configuration for UART 0
+#endif
+#endif /* LM3S69XX_ENABLE_UART_0 */
+
+#ifdef LM3S69XX_ENABLE_UART_1
+#if defined(LM3S69XX_MCU_LM3S3749)
+ LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_B, 0),
+ LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_B, 1),
+#elif defined(LM3S69XX_MCU_LM3S6965)
+ LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_D, 2),
+ LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_D, 3),
+#elif defined(LM3S69XX_MCU_LM4F120)
+ LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_B, 0),
+ LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_B, 1),
+ LM3S69XX_PIN_UART_RTS(LM3S69XX_PORT_C, 4),
+ LM3S69XX_PIN_UART_CTS(LM3S69XX_PORT_C, 5),
+#else
+#error No GPIO pin configuration for UART 1
+#endif
+#endif /* LM3S69XX_ENABLE_UART_1 */
+
+#ifdef LM3S69XX_ENABLE_UART_2
+#if defined(LM3S69XX_MCU_LM3S3749)
+ LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_D, 0),
+ LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_D, 1),
+#elif defined(LM3S69XX_MCU_LM3S6965)
+ LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_G, 0),
+ LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_G, 1),
+#else
+#error No GPIO pin configuration for UART 2
+#endif
+#endif /* LM3S69XX_ENABLE_UART_2 */
+};
+
+static void init_gpio(void)
+{
+#if LM3S69XX_USE_AHB_FOR_GPIO
+ volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON;
+
+ syscon->gpiohbctl |= SYSCONGPIOHBCTL_PORTA | SYSCONGPIOHBCTL_PORTB
+ | SYSCONGPIOHBCTL_PORTC | SYSCONGPIOHBCTL_PORTD
+ | SYSCONGPIOHBCTL_PORTE | SYSCONGPIOHBCTL_PORTF
+#if LM3S69XX_NUM_GPIO_BLOCKS > 6
+ | SYSCONGPIOHBCTL_PORTG
+#if LM3S69XX_NUM_GPIO_BLOCKS > 7
+ | SYSCONGPIOHBCTL_PORTH
+#endif
+#endif
+ ;
+
+#endif /* LM3S69XX_USE_AHB_FOR_GPIO */
+
+ lm3s69xx_gpio_set_config_array(start_config_gpio,
+ sizeof(start_config_gpio) / sizeof(start_config_gpio[0]));
+}
+
+void bsp_start(void)
+{
+ init_main_osc();
+ init_gpio();
+ bsp_interrupt_initialize();
+}
diff --git a/bsps/arm/lm3s69xx/start/bspstarthook.c b/bsps/arm/lm3s69xx/start/bspstarthook.c
new file mode 100644
index 0000000000..0524577ea7
--- /dev/null
+++ b/bsps/arm/lm3s69xx/start/bspstarthook.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011-2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/start.h>
+
+void BSP_START_TEXT_SECTION bsp_start_hook_0(void)
+{
+ /* Do nothing */
+}
+
+void BSP_START_TEXT_SECTION bsp_start_hook_1(void)
+{
+ bsp_start_copy_sections();
+ bsp_start_clear_bss();
+
+ /* At this point we can use objects outside the .start section */
+}
diff --git a/bsps/arm/lm3s69xx/start/io.c b/bsps/arm/lm3s69xx/start/io.c
new file mode 100644
index 0000000000..b476e7b6dd
--- /dev/null
+++ b/bsps/arm/lm3s69xx/start/io.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2013 Eugeniy Meshcheryakov <eugen@debian.org>
+ *
+ * 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/io.h>
+#include <bsp/lm3s69xx.h>
+#include <bsp/syscon.h>
+#include <rtems.h>
+
+static void set_bit(volatile uint32_t *reg, unsigned index, uint32_t set)
+{
+ uint32_t mask = 1U;
+ uint32_t val = *reg;
+
+ val &= ~(mask << index);
+ val |= set << index;
+
+ *reg = val;
+}
+
+static void set_config(unsigned int pin, const lm3s69xx_gpio_config *config)
+{
+ unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
+ volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
+ unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+
+ lm3s69xx_syscon_enable_gpio_clock(port, true);
+
+ /* Disable digital and analog functions before reconfiguration. */
+ set_bit(&gpio->den, index, 0);
+ set_bit(&gpio->amsel, index, 0);
+
+ set_bit(&gpio->afsel, index, config->alternate);
+ set_bit(&gpio->dir, index, config->dir);
+ set_bit(&gpio->odr, index, config->otype);
+
+ switch (config->drive) {
+ case LM3S69XX_GPIO_DRIVE_4MA:
+ gpio->dr4r |= 1 << index;
+ break;
+ case LM3S69XX_GPIO_DRIVE_8MA:
+ gpio->dr8r |= 1 << index;
+ break;
+ default:
+ gpio->dr2r |= 1 << index;
+ break;
+ }
+
+ switch (config->pull) {
+ case LM3S69XX_GPIO_PULL_UP:
+ gpio->pur |= 1 << index;
+ break;
+ case LM3S69XX_GPIO_PULL_DOWN:
+ gpio->pdr |= 1 << index;
+ break;
+ default:
+ set_bit(&gpio->pdr, index, 0);
+ set_bit(&gpio->pur, index, 0);
+ break;
+ }
+
+ set_bit(&gpio->slr, index, config->slr);
+
+ set_bit(&gpio->den, index, config->digital);
+ set_bit(&gpio->amsel, index, config->analog);
+
+ rtems_interrupt_enable(level);
+}
+
+void lm3s69xx_gpio_set_config(const lm3s69xx_gpio_config *config)
+{
+ unsigned int current = config->pin_first;
+ unsigned int last = config->pin_last;
+
+ while (current <= last) {
+ set_config(current, config);
+ current++;
+ }
+}
+
+void lm3s69xx_gpio_set_config_array(const lm3s69xx_gpio_config *configs, unsigned int count)
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++)
+ lm3s69xx_gpio_set_config(&configs[i]);
+}
+
+/**
+ * Enables/disables digital function on the specified pin.
+ */
+void lm3s69xx_gpio_digital_enable(unsigned int pin, bool enable)
+{
+ unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
+ volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
+ unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+ set_bit(&gpio->den, index, enable);
+ rtems_interrupt_enable(level);
+}
+
+/**
+ * Enables/disables analog mode on the specified pin.
+ */
+void lm3s69xx_gpio_analog_mode_select(unsigned int pin, bool enable)
+{
+ unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
+ volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
+ unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+ set_bit(&gpio->amsel, index, enable);
+ rtems_interrupt_enable(level);
+}
+
+void lm3s69xx_gpio_set_pin(unsigned int pin, bool set)
+{
+ unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
+ volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
+ unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
+ uint32_t mask = 1U << index;
+
+ gpio->data[mask] = set ? mask : 0;
+}
+
+bool lm3s69xx_gpio_get_pin(unsigned int pin)
+{
+ unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin);
+ volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port);
+ unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin);
+ uint32_t mask = 1U << index;
+
+ return gpio->data[mask] != 0;
+}
diff --git a/bsps/arm/lm3s69xx/start/linkcmds.lm3s3749 b/bsps/arm/lm3s69xx/start/linkcmds.lm3s3749
new file mode 100644
index 0000000000..ff165c7835
--- /dev/null
+++ b/bsps/arm/lm3s69xx/start/linkcmds.lm3s3749
@@ -0,0 +1,30 @@
+/**
+ * @file
+ *
+ * @brief Memory map.
+ */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x20000000, LENGTH = 64K
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 128K
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965 b/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965
new file mode 100644
index 0000000000..02d2487dc9
--- /dev/null
+++ b/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965
@@ -0,0 +1,30 @@
+/**
+ * @file
+ *
+ * @brief Memory map.
+ */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x20000000, LENGTH = 64K
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 256K
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965_qemu b/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965_qemu
new file mode 100644
index 0000000000..a4d3a1972d
--- /dev/null
+++ b/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965_qemu
@@ -0,0 +1,30 @@
+/**
+ * @file
+ *
+ * @brief Memory map.
+ */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x20000000, LENGTH = 16M
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 64M
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lm3s69xx/start/linkcmds.lm4f120 b/bsps/arm/lm3s69xx/start/linkcmds.lm4f120
new file mode 100644
index 0000000000..e995a3ddbf
--- /dev/null
+++ b/bsps/arm/lm3s69xx/start/linkcmds.lm4f120
@@ -0,0 +1,30 @@
+/**
+ * @file
+ *
+ * @brief Memory map.
+ */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x20000000, LENGTH = 32K
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 256K
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lm3s69xx/start/syscon.c b/bsps/arm/lm3s69xx/start/syscon.c
new file mode 100644
index 0000000000..1f5a1a3596
--- /dev/null
+++ b/bsps/arm/lm3s69xx/start/syscon.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2013 Eugeniy Meshcheryakov <eugen@debian.org>
+ *
+ * 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/syscon.h>
+#include <bsp/lm3s69xx.h>
+#include <rtems.h>
+
+static void delay_3_clocks(void)
+{
+ asm volatile(
+ "nop\n\t"
+ "nop\n\t"
+ "nop");
+}
+
+void __attribute__((naked)) lm3s69xx_syscon_delay_3x_clocks(unsigned long x_count)
+{
+ asm volatile(
+ "subs r0, #1\n\t"
+ "bne lm3s69xx_syscon_delay_3x_clocks\n\t"
+ "bx lr"
+ );
+}
+
+void lm3s69xx_syscon_enable_gpio_clock(unsigned int port, bool enable)
+{
+ volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON;
+ uint32_t mask = 1 << port;
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+
+ if (enable)
+ syscon->rcgc2 |= mask;
+ else
+ syscon->rcgc2 &= ~mask;
+
+ delay_3_clocks();
+
+ rtems_interrupt_enable(level);
+}
+
+void lm3s69xx_syscon_enable_uart_clock(unsigned int port, bool enable)
+{
+ volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON;
+ uint32_t mask = 1 << port;
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+
+ if (enable)
+ syscon->rcgc1 |= mask;
+ else
+ syscon->rcgc1 &= ~mask;
+
+ delay_3_clocks();
+
+ rtems_interrupt_enable(level);
+}
+
+void lm3s69xx_syscon_enable_ssi_clock(unsigned int port, bool enable)
+{
+ volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON;
+ uint32_t mask = 1 << (port + 4);
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+
+ if (enable)
+ syscon->rcgc1 |= mask;
+ else
+ syscon->rcgc1 &= ~mask;
+
+ delay_3_clocks();
+
+ rtems_interrupt_enable(level);
+}
+
+void lm3s69xx_syscon_enable_pwm_clock(bool enable)
+{
+ volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON;
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+
+ if (enable)
+ syscon->rcgc0 |= SYSCONRCGC0_PWM;
+ else
+ syscon->rcgc0 &= ~SYSCONRCGC0_PWM;
+
+ delay_3_clocks();
+
+ rtems_interrupt_enable(level);
+}
+
+/**
+ * Sets PWMDIV field in the RCC register.
+ *
+ * @note div should be one of SCRCC_PWMDIV_DIV?_VAL constants.
+ */
+void lm3s69xx_syscon_set_pwmdiv(unsigned int div)
+{
+ volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON;
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable(level);
+ syscon->rcc = (syscon->rcc & ~SYSCONRCC_PWMDIV_MSK) | SYSCONRCC_PWMDIV(div)
+ | SYSCONRCC_USEPWMDIV;
+ rtems_interrupt_enable(level);
+}
diff --git a/bsps/arm/lpc176x/start/bsp_specs b/bsps/arm/lpc176x/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/lpc176x/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/lpc176x/start/bspstart.c b/bsps/arm/lpc176x/start/bspstart.c
new file mode 100644
index 0000000000..f1aba444fc
--- /dev/null
+++ b/bsps/arm/lpc176x/start/bspstart.c
@@ -0,0 +1,91 @@
+/**
+ * @file
+ *
+ * @ingroup lpc176x
+ *
+ * @brief Startup code.
+ */
+
+/*
+ * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/io.h>
+#include <bsp/irq.h>
+#include <bsp/dma.h>
+#include <bsp/bootcard.h>
+#include <bsp/timer.h>
+#include <bsp/irq-generic.h>
+#include <bsp/system-clocks.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/common-types.h>
+#include <bsp/uart-output-char.h>
+
+#ifdef LPC176X_HEAP_EXTEND
+LINKER_SYMBOL( lpc176x_region_heap_0_begin );
+LINKER_SYMBOL( lpc176x_region_heap_0_size );
+LINKER_SYMBOL( lpc176x_region_heap_0_end );
+LINKER_SYMBOL( lpc176x_region_heap_1_begin );
+LINKER_SYMBOL( lpc176x_region_heap_1_size );
+LINKER_SYMBOL( lpc176x_region_heap_1_end );
+extern Heap_Control *RTEMS_Malloc_Heap;
+#endif
+
+static void heap_extend( void )
+{
+#ifdef LPC176X_HEAP_EXTEND
+ _Heap_Extend( RTEMS_Malloc_Heap,
+ lpc176x_region_heap_0_begin,
+ (uintptr_t) lpc176x_region_heap_0_size,
+ NULL );
+ _Heap_Extend( RTEMS_Malloc_Heap,
+ lpc176x_region_heap_1_begin,
+ (uintptr_t) lpc176x_region_heap_1_size,
+ NULL );
+#endif
+}
+
+/**
+ * @brief Console initialization
+ */
+static void initialize_console( void )
+{
+#ifdef LPC176X_CONFIG_CONSOLE
+
+ lpc176x_module_enable( LPC176X_MODULE_UART_0, LPC176X_MODULE_PCLK_DEFAULT );
+
+ lpc176x_pin_select( LPC176X_PIN_UART_0_TXD, LPC176X_PIN_FUNCTION_01 );
+ lpc176x_pin_select( LPC176X_PIN_UART_0_RXD, LPC176X_PIN_FUNCTION_01 );
+
+ BSP_CONSOLE_UART_INIT( LPC176X_PCLK / 16 / LPC176X_UART_BAUD );
+#endif
+}
+
+void bsp_start( void )
+{
+ /* Initialize console */
+ initialize_console();
+
+ /*Initialize timer*/
+ lpc176x_timer_init( LPC176X_TIMER_1 );
+ lpc176x_timer_start( LPC176X_TIMER_1 );
+
+ /* Interrupts */
+ bsp_interrupt_initialize();
+
+ /* DMA */
+ lpc176x_dma_initialize();
+
+ heap_extend();
+}
diff --git a/bsps/arm/lpc176x/start/bspstarthooks.c b/bsps/arm/lpc176x/start/bspstarthooks.c
new file mode 100644
index 0000000000..a60c5bdf89
--- /dev/null
+++ b/bsps/arm/lpc176x/start/bspstarthooks.c
@@ -0,0 +1,227 @@
+/**
+ * @file bspstarthooks.c
+ *
+ * @ingroup lpc176x
+ *
+ * @brief First configurations and initializations to the correct
+ * functionality of the board.
+ */
+
+/*
+ * Copyright (c) 2014 Taller Technologies.
+ *
+ * @author Boretto Martin (martin.boretto@tallertechnologies.com)
+ * @author Diaz Marcos (marcos.diaz@tallertechnologies.com)
+ * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com)
+ * @author Daniel Chicco (daniel.chicco@tallertechnologies.com)
+ *
+ * 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/start.h>
+#include <bsp/io.h>
+
+/**
+ * @brief Initializes the oscillator according to the lpc176x board.
+ */
+static BSP_START_TEXT_SECTION void lpc176x_init_main_oscillator( void )
+{
+ if ( ( LPC176X_SCB.scs & LPC176X_SCB_SCS_OSC_STATUS ) == 0u ) {
+ LPC176X_SCB.scs |= LPC176X_SCB_SCS_OSC_ENABLE;
+
+ while ( ( LPC176X_SCB.scs & LPC176X_SCB_SCS_OSC_STATUS ) == 0u ) {
+ /* Wait. */
+ }
+ }
+
+ /* else implies that the oscillator is initialized. Also,
+ there is nothing to do. */
+}
+
+/**
+ * @brief Sets the PLL configuration.
+ *
+ * @param pll Value to set.
+ * @param val Set value.
+ */
+static BSP_START_TEXT_SECTION void lpc176x_pll_config( const uint32_t val )
+{
+ ( LPC176X_SCB.pll_0 ).con = val;
+ /* The two register writes must be in correct sequence. */
+ ( LPC176X_SCB.pll_0 ).feed = LPC176X_PLL0CON;
+ ( LPC176X_SCB.pll_0 ).feed = LPC176X_PLL0CFG;
+}
+
+/**
+ * @brief Sets the PLL.
+ *
+ * @param msel Multiplier value.
+ * @param psel Divider value.
+ * @param cclkdiv Divisor clock.
+ */
+static BSP_START_TEXT_SECTION void lpc176x_set_pll(
+ const unsigned msel,
+ const unsigned psel,
+ const unsigned cclkdiv
+)
+{
+ const uint32_t pllcfg = LPC176X_PLL_SEL_MSEL( msel ) |
+ LPC176X_PLL_SEL_PSEL( psel );
+ const uint32_t pllstat = LPC176X_PLL_STAT_PLLE | LPC176X_PLL_STAT_PLOCK |
+ pllcfg;
+ const uint32_t cclksel_cclkdiv = LPC176X_SCB_CCLKSEL_CCLKDIV( cclkdiv );
+
+ if ( ( LPC176X_SCB.pll_0 ).stat != pllstat
+ || LPC176X_SCB.cclksel != cclksel_cclkdiv
+ || LPC176X_SCB.clksrcsel != LPC176X_SCB_CLKSRCSEL_CLKSRC ) {
+ lpc176x_pll_config( ( LPC176X_SCB.pll_0 ).con & ~LPC176X_PLL_CON_PLLC );
+
+ /* Turn off USB. */
+ LPC176X_SCB.usbclksel = 0u;
+
+ /* Disable PLL. */
+ lpc176x_pll_config( 0u );
+
+ /* Use SYSCLK for CCLK. */
+ LPC176X_SCB.cclksel = LPC176X_SCB_CCLKSEL_CCLKDIV( 0u );
+
+ /* Set the CCLK, PCLK and EMCCLK divider. */
+ LPC176X_SCB.cclksel = cclksel_cclkdiv;
+
+ /* Select main oscillator as clock source. */
+ LPC176X_SCB.clksrcsel = LPC176X_SCB_CLKSRCSEL_CLKSRC;
+
+ /* The two register writes must be in correct sequence. */
+ /* Set PLL configuration. */
+ ( LPC176X_SCB.pll_0 ).cfg = pllcfg;
+ ( LPC176X_SCB.pll_0 ).feed = LPC176X_PLL0CON;
+ ( LPC176X_SCB.pll_0 ).feed = LPC176X_PLL0CFG;
+
+ /* Enable PLL. */
+ lpc176x_pll_config( LPC176X_PLL_CON_PLLE );
+
+ /* Wait for lock. */
+ while ( ( ( LPC176X_SCB.pll_0 ).stat & LPC176X_PLL_STAT_PLOCK ) == 0u ) {
+ /* Wait */
+ }
+
+ /* Connect PLL. */
+ lpc176x_pll_config( ( LPC176X_PLL_CON_PLLE | LPC176X_PLL_CON_PLLC ) );
+
+ /* Wait for connected and enabled. */
+ while ( ( ( LPC176X_SCB.pll_0 ).stat & ( LPC176X_PLL_STAT_PLLE |
+ LPC176X_PLL_STAT_PLLC ) ) ==
+ 0u ) {
+ /* Wait */
+ }
+ }
+
+ /* else implies that the pll has a wrong value. Also,
+ there is nothing to do. */
+}
+
+/**
+ * @brief Pll initialization.
+ */
+static BSP_START_TEXT_SECTION void lpc176x_init_pll( void )
+{
+#if ( LPC176X_OSCILLATOR_MAIN == 12000000u )
+#if ( LPC176X_CCLK == 96000000U )
+ lpc176x_set_pll( 11u, 0u, 2u );
+#else
+#error "unexpected CCLK"
+#endif
+#else
+#error "unexpected main oscillator frequency"
+#endif
+}
+
+/**
+ * @brief Memory map initialization.
+ */
+static BSP_START_TEXT_SECTION void lpc176x_init_memory_map( void )
+{
+ LPC176X_SCB.memmap = LPC176X_SCB_MEMMAP_MAP;
+}
+
+/**
+ * @brief Memory accelerator initialization.
+ */
+static BSP_START_TEXT_SECTION void lpc176x_init_memory_accelerator( void )
+{
+#if ( LPC176X_CCLK <= 20000000U )
+ LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x0U );
+#elif ( LPC176X_CCLK <= 40000000U )
+ LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x1U );
+#elif ( LPC176X_CCLK <= 60000000U )
+ LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x2U );
+#elif ( LPC176X_CCLK <= 80000000U )
+ LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x3U );
+#elif ( LPC176X_CCLK <= 100000000U )
+ LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x4U );
+#else
+ LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x5U );
+#endif
+}
+
+/**
+ * @brief Stops the gpdma device.
+ */
+static BSP_START_TEXT_SECTION void lpc176x_stop_gpdma( void )
+{
+#ifdef LPC176X_STOP_GPDMA
+
+ bool has_power = ( LPC176X_SCB.pconp & LPC176X_SCB_PCONP_GPDMA ) != 0u;
+
+ if ( has_power ) {
+ GPDMA_CONFIG = 0u;
+ LPC176X_SCB.pconp &= ~LPC176X_SCB_PCONP_GPDMA;
+ }
+
+ /* else implies that the current module (gpdma) is turn off. Also,
+ there is nothing to do. */
+
+#endif
+}
+
+/**
+ * @brief Stops the usb device.
+ */
+static BSP_START_TEXT_SECTION void lpc176x_stop_usb( void )
+{
+#ifdef LPC176X_STOP_USB
+
+ bool has_power = ( LPC176X_SCB.pconp & LPC176X_SCB_PCONP_USB ) != 0u;
+
+ if ( has_power ) {
+ OTG_CLK_CTRL = 0u;
+
+ LPC176X_SCB.pconp &= ~LPC176X_SCB_PCONP_USB;
+ LPC176X_SCB.usbclksel = 0u;
+ }
+
+ /* else implies that the current module (usb) is turn off. Also,
+ there is nothing to do. */
+#endif
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0( void )
+{
+ lpc176x_init_main_oscillator();
+ lpc176x_init_pll();
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1( void )
+{
+ lpc176x_init_memory_map();
+ lpc176x_init_memory_accelerator();
+ lpc176x_stop_gpdma();
+ lpc176x_stop_usb();
+ bsp_start_copy_sections();
+ bsp_start_clear_bss();
+
+ /* At this point we can use objects outside the .start section */
+} \ No newline at end of file
diff --git a/bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed b/bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed
new file mode 100644
index 0000000000..133d2f487c
--- /dev/null
+++ b/bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed
@@ -0,0 +1,29 @@
+/* LPC1768 OEM Board from Embedded Artists */
+
+MEMORY {
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 512k
+ RAM_INT (AIW) : ORIGIN = 0x10000000, LENGTH = 32k
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024;
+bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed_ahb_ram b/bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed_ahb_ram
new file mode 100644
index 0000000000..75bdd75d83
--- /dev/null
+++ b/bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed_ahb_ram
@@ -0,0 +1,30 @@
+/* LPC1768 OEM Board from Embedded Artists */
+
+MEMORY {
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 512k
+ RAM_INT (AIW) : ORIGIN = 0x10000000, LENGTH = 32k
+ RAM_AHB (AIW) : ORIGIN = 0x2007C000, LENGTH = 32k
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_AHB);
+REGION_ALIAS ("REGION_STACK", RAM_AHB);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024;
+bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed_ahb_ram_eth b/bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed_ahb_ram_eth
new file mode 100644
index 0000000000..7d91d8a5ef
--- /dev/null
+++ b/bsps/arm/lpc176x/start/linkcmds.lpc1768_mbed_ahb_ram_eth
@@ -0,0 +1,41 @@
+/* LPC1768 OEM Board from Embedded Artists */
+
+MEMORY {
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 512k
+ RAM_INT (AIW) : ORIGIN = 0x10000000, LENGTH = 32k
+ RAM_AHB1 (AIW) : ORIGIN = 0x2007C000, LENGTH = 16k
+ RAM_AHB2 (AIW) : ORIGIN = 0x20080000, LENGTH = 16k
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_AHB1);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_ETH", RAM_AHB2);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024;
+bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
+
+SECTIONS {
+ .eth (NOLOAD) : ALIGN_WITH_INPUT {
+ bsp_section_eth_begin = .;
+ *(.eth)
+ bsp_section_eth_end = .;
+ } > REGION_ETH AT > REGION_ETH
+ bsp_section_eth_size = bsp_section_eth_end - bsp_section_eth_begin;
+}
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lpc24xx/start/bsp_specs b/bsps/arm/lpc24xx/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/lpc24xx/start/bspreset-armv4.c b/bsps/arm/lpc24xx/start/bspreset-armv4.c
new file mode 100644
index 0000000000..c53b4e2447
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/bspreset-armv4.c
@@ -0,0 +1,51 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx
+ *
+ * @brief Reset code.
+ */
+
+/*
+ * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/score/armv7m.h>
+
+#include <bsp/bootcard.h>
+#include <bsp/lpc24xx.h>
+#include <bsp/start.h>
+
+#ifdef ARM_MULTILIB_ARCH_V4
+
+BSP_START_TEXT_SECTION __attribute__((flatten)) void bsp_reset(void)
+{
+ rtems_interrupt_level level;
+
+ (void) level;
+ rtems_interrupt_disable(level);
+
+ /* Trigger watchdog reset */
+ WDCLKSEL = 0;
+ WDTC = 0xff;
+ WDMOD = 0x3;
+ WDFEED = 0xaa;
+ WDFEED = 0x55;
+
+ while (true) {
+ /* Do nothing */
+ }
+}
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/bsps/arm/lpc24xx/start/bspstart.c b/bsps/arm/lpc24xx/start/bspstart.c
new file mode 100644
index 0000000000..6f00f35f99
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/bspstart.c
@@ -0,0 +1,96 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx
+ *
+ * @brief Startup code.
+ */
+
+/*
+ * Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/dma.h>
+#include <bsp/io.h>
+#include <bsp/irq-generic.h>
+#include <bsp/irq.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/lpc24xx.h>
+#include <bsp/system-clocks.h>
+#include <bsp/uart-output-char.h>
+
+#ifdef LPC24XX_HEAP_EXTEND
+ LINKER_SYMBOL(lpc24xx_region_heap_0_begin);
+ LINKER_SYMBOL(lpc24xx_region_heap_0_size);
+ LINKER_SYMBOL(lpc24xx_region_heap_0_end);
+
+ LINKER_SYMBOL(lpc24xx_region_heap_1_begin);
+ LINKER_SYMBOL(lpc24xx_region_heap_1_size);
+ LINKER_SYMBOL(lpc24xx_region_heap_1_end);
+
+ extern Heap_Control *RTEMS_Malloc_Heap;
+#endif
+
+static void heap_extend(void)
+{
+ #ifdef LPC24XX_HEAP_EXTEND
+ _Heap_Extend(
+ RTEMS_Malloc_Heap,
+ lpc24xx_region_heap_0_begin,
+ (uintptr_t) lpc24xx_region_heap_0_size,
+ 0
+ );
+ _Heap_Extend(
+ RTEMS_Malloc_Heap,
+ lpc24xx_region_heap_1_begin,
+ (uintptr_t) lpc24xx_region_heap_1_size,
+ 0
+ );
+ #endif
+}
+
+static void initialize_console(void)
+{
+ #ifdef LPC24XX_CONFIG_CONSOLE
+ static const lpc24xx_pin_range pins [] = {
+ LPC24XX_PIN_UART_0_TXD,
+ LPC24XX_PIN_UART_0_RXD,
+ LPC24XX_PIN_TERMINAL
+ };
+
+ lpc24xx_module_enable(LPC24XX_MODULE_UART_0, LPC24XX_MODULE_PCLK_DEFAULT);
+ lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
+ BSP_CONSOLE_UART_INIT(LPC24XX_PCLK / 16 / LPC24XX_UART_BAUD);
+ #endif
+}
+
+void bsp_start(void)
+{
+ /* Initialize Timer 1 */
+ lpc24xx_module_enable(LPC24XX_MODULE_TIMER_1, LPC24XX_MODULE_PCLK_DEFAULT);
+
+ /* Initialize standard timer */
+ lpc24xx_timer_initialize();
+
+ initialize_console();
+
+ /* Interrupts */
+ bsp_interrupt_initialize();
+
+ /* DMA */
+ lpc24xx_dma_initialize();
+
+ heap_extend();
+}
diff --git a/bsps/arm/lpc24xx/start/bspstarthooks.c b/bsps/arm/lpc24xx/start/bspstarthooks.c
new file mode 100644
index 0000000000..6ceb066935
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/bspstarthooks.c
@@ -0,0 +1,533 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx
+ *
+ * @brief Startup code.
+ */
+
+/*
+ * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/io.h>
+#include <bsp/start.h>
+#include <bsp/lpc24xx.h>
+#include <bsp/lpc-emc.h>
+#include <bsp/start-config.h>
+
+static BSP_START_TEXT_SECTION void lpc24xx_cpu_delay(unsigned ticks)
+{
+ unsigned i = 0;
+
+ /* One loop execution needs four instructions */
+ ticks /= 4;
+
+ for (i = 0; i <= ticks; ++i) {
+ __asm__ volatile ("nop");
+ }
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_udelay(unsigned us)
+{
+ lpc24xx_cpu_delay(us * (LPC24XX_CCLK / 1000000));
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_init_pinsel(void)
+{
+ lpc24xx_pin_config(
+ &lpc24xx_start_config_pinsel [0],
+ LPC24XX_PIN_SET_FUNCTION
+ );
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_init_emc_static(void)
+{
+ size_t i = 0;
+ size_t chip_count = lpc24xx_start_config_emc_static_chip_count;
+
+ for (i = 0; i < chip_count; ++i) {
+ const lpc24xx_emc_static_chip_config *chip_config =
+ &lpc24xx_start_config_emc_static_chip [i];
+ lpc24xx_emc_static_chip_config chip_config_on_stack;
+ size_t config_size = sizeof(chip_config_on_stack.config);
+
+ bsp_start_memcpy(
+ (int *) &chip_config_on_stack.config,
+ (const int *) &chip_config->config,
+ config_size
+ );
+ bsp_start_memcpy(
+ (int *) chip_config->chip_select,
+ (const int *) &chip_config_on_stack.config,
+ config_size
+ );
+ }
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_init_emc_dynamic(void)
+{
+ size_t chip_count = lpc24xx_start_config_emc_dynamic_chip_count;
+
+ if (chip_count > 0) {
+ bool do_initialization = true;
+ size_t i = 0;
+
+ for (i = 0; do_initialization && i < chip_count; ++i) {
+ const lpc24xx_emc_dynamic_chip_config *chip_cfg =
+ &lpc24xx_start_config_emc_dynamic_chip [i];
+ volatile lpc_emc_dynamic *chip_select = chip_cfg->chip_select;
+
+ do_initialization = (chip_select->config & EMC_DYN_CFG_B) == 0;
+ }
+
+ if (do_initialization) {
+ volatile lpc_emc *emc = (volatile lpc_emc *) EMC_BASE_ADDR;
+ const lpc24xx_emc_dynamic_config *cfg =
+ &lpc24xx_start_config_emc_dynamic [0];
+ uint32_t dynamiccontrol = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS;
+
+ #ifdef ARM_MULTILIB_ARCH_V7M
+ volatile lpc17xx_scb *scb = &LPC17XX_SCB;
+
+ /* Delay control */
+ scb->emcdlyctl = cfg->emcdlyctl;
+ #endif
+
+ emc->dynamicreadconfig = cfg->readconfig;
+
+ /* Timings */
+ emc->dynamictrp = cfg->trp;
+ emc->dynamictras = cfg->tras;
+ emc->dynamictsrex = cfg->tsrex;
+ emc->dynamictapr = cfg->tapr;
+ emc->dynamictdal = cfg->tdal;
+ emc->dynamictwr = cfg->twr;
+ emc->dynamictrc = cfg->trc;
+ emc->dynamictrfc = cfg->trfc;
+ emc->dynamictxsr = cfg->txsr;
+ emc->dynamictrrd = cfg->trrd;
+ emc->dynamictmrd = cfg->tmrd;
+
+ /* NOP period */
+ emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_NOP;
+ lpc24xx_udelay(200);
+
+ /* Precharge */
+ emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_PALL;
+ emc->dynamicrefresh = 1;
+
+ /*
+ * Perform several refresh cycles with a memory refresh every 16 AHB
+ * clock cycles. Wait until eight SDRAM refresh cycles have occurred
+ * (128 AHB clock cycles).
+ */
+ lpc24xx_cpu_delay(128);
+
+ /* Refresh timing */
+ emc->dynamicrefresh = cfg->refresh;
+ lpc24xx_cpu_delay(128);
+
+ for (i = 0; i < chip_count; ++i) {
+ const lpc24xx_emc_dynamic_chip_config *chip_cfg =
+ &lpc24xx_start_config_emc_dynamic_chip [i];
+ volatile lpc_emc_dynamic *chip_select = chip_cfg->chip_select;
+ uint32_t config = chip_cfg->config;
+
+ /* Chip select */
+ chip_select->config = config;
+ chip_select->rascas = chip_cfg->rascas;
+
+ /* Set modes */
+ emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_MODE;
+ *(volatile uint32_t *)(chip_cfg->address + chip_cfg->mode);
+
+ /* Enable buffer */
+ chip_select->config = config | EMC_DYN_CFG_B;
+ }
+
+ emc->dynamiccontrol = 0;
+ }
+ }
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_init_main_oscillator(void)
+{
+ #ifdef ARM_MULTILIB_ARCH_V4
+ if ((SCS & 0x40) == 0) {
+ SCS |= 0x20;
+ while ((SCS & 0x40) == 0) {
+ /* Wait */
+ }
+ }
+ #else
+ volatile lpc17xx_scb *scb = &LPC17XX_SCB;
+
+ if ((scb->scs & LPC17XX_SCB_SCS_OSC_STATUS) == 0) {
+ scb->scs |= LPC17XX_SCB_SCS_OSC_ENABLE;
+ while ((scb->scs & LPC17XX_SCB_SCS_OSC_STATUS) == 0) {
+ /* Wait */
+ }
+ }
+ #endif
+}
+
+#ifdef ARM_MULTILIB_ARCH_V4
+
+static BSP_START_TEXT_SECTION void lpc24xx_pll_config(
+ uint32_t val
+)
+{
+ PLLCON = val;
+ PLLFEED = 0xaa;
+ PLLFEED = 0x55;
+}
+
+/**
+ * @brief Sets the Phase Locked Loop (PLL).
+ *
+ * All parameter values are the actual register field values.
+ *
+ * @param clksrc Selects the clock source for the PLL.
+ *
+ * @param nsel Selects PLL pre-divider value (sometimes named psel).
+ *
+ * @param msel Selects PLL multiplier value.
+ *
+ * @param cclksel Selects the divide value for creating the CPU clock (CCLK)
+ * from the PLL output.
+ */
+static BSP_START_TEXT_SECTION void lpc24xx_set_pll(
+ unsigned clksrc,
+ unsigned nsel,
+ unsigned msel,
+ unsigned cclksel
+)
+{
+ uint32_t pllstat = PLLSTAT;
+ uint32_t pllcfg = SET_PLLCFG_NSEL(0, nsel) | SET_PLLCFG_MSEL(0, msel);
+ uint32_t clksrcsel = SET_CLKSRCSEL_CLKSRC(0, clksrc);
+ uint32_t cclkcfg = SET_CCLKCFG_CCLKSEL(0, cclksel | 1);
+ bool pll_enabled = (pllstat & PLLSTAT_PLLE) != 0;
+
+ /* Disconnect PLL if necessary */
+ if ((pllstat & PLLSTAT_PLLC) != 0) {
+ if (pll_enabled) {
+ /* Check if we run already with the desired settings */
+ if (PLLCFG == pllcfg && CLKSRCSEL == clksrcsel && CCLKCFG == cclkcfg) {
+ /* Nothing to do */
+ return;
+ }
+ lpc24xx_pll_config(PLLCON_PLLE);
+ } else {
+ lpc24xx_pll_config(0);
+ }
+ }
+
+ /* Set CPU clock divider to a reasonable save value */
+ CCLKCFG = 0;
+
+ /* Disable PLL if necessary */
+ if (pll_enabled) {
+ lpc24xx_pll_config(0);
+ }
+
+ /* Select clock source */
+ CLKSRCSEL = clksrcsel;
+
+ /* Set PLL Configuration Register */
+ PLLCFG = pllcfg;
+
+ /* Enable PLL */
+ lpc24xx_pll_config(PLLCON_PLLE);
+
+ /* Wait for lock */
+ while ((PLLSTAT & PLLSTAT_PLOCK) == 0) {
+ /* Wait */
+ }
+
+ /* Set CPU clock divider and ensure that we have an odd value */
+ CCLKCFG = cclkcfg;
+
+ /* Connect PLL */
+ lpc24xx_pll_config(PLLCON_PLLE | PLLCON_PLLC);
+}
+
+#else /* ARM_MULTILIB_ARCH_V4 */
+
+static BSP_START_TEXT_SECTION void lpc17xx_pll_config(
+ volatile lpc17xx_pll *pll,
+ uint32_t val
+)
+{
+ pll->con = val;
+ pll->feed = 0xaa;
+ pll->feed = 0x55;
+}
+
+static BSP_START_TEXT_SECTION void lpc17xx_set_pll(
+ unsigned msel,
+ unsigned psel,
+ unsigned cclkdiv
+)
+{
+ volatile lpc17xx_scb *scb = &LPC17XX_SCB;
+ volatile lpc17xx_pll *pll = &scb->pll_0;
+ uint32_t pllcfg = LPC17XX_PLL_SEL_MSEL(msel)
+ | LPC17XX_PLL_SEL_PSEL(psel);
+ uint32_t pllstat = LPC17XX_PLL_STAT_PLLE
+ | LPC17XX_PLL_STAT_PLOCK | pllcfg;
+ uint32_t cclksel_cclkdiv = LPC17XX_SCB_CCLKSEL_CCLKDIV(cclkdiv);
+ uint32_t cclksel = LPC17XX_SCB_CCLKSEL_CCLKSEL | cclksel_cclkdiv;
+
+ if (
+ pll->stat != pllstat
+ || scb->cclksel != cclksel
+ || scb->clksrcsel != LPC17XX_SCB_CLKSRCSEL_CLKSRC
+ ) {
+ /* Use SYSCLK for CCLK */
+ scb->cclksel = LPC17XX_SCB_CCLKSEL_CCLKDIV(1);
+
+ /* Turn off USB */
+ scb->usbclksel = 0;
+
+ /* Disable PLL */
+ lpc17xx_pll_config(pll, 0);
+
+ /* Select main oscillator as clock source */
+ scb->clksrcsel = LPC17XX_SCB_CLKSRCSEL_CLKSRC;
+
+ /* Set PLL configuration */
+ pll->cfg = pllcfg;
+
+ /* Set the CCLK, PCLK and EMCCLK divider */
+ scb->cclksel = cclksel_cclkdiv;
+ scb->pclksel = LPC17XX_SCB_PCLKSEL_PCLKDIV(cclkdiv * LPC24XX_PCLKDIV);
+ scb->emcclksel = LPC24XX_EMCCLKDIV == 1 ? 0 : LPC17XX_SCB_EMCCLKSEL_EMCDIV;
+
+ /* Enable PLL */
+ lpc17xx_pll_config(pll, LPC17XX_PLL_CON_PLLE);
+
+ /* Wait for lock */
+ while ((pll->stat & LPC17XX_PLL_STAT_PLOCK) == 0) {
+ /* Wait */
+ }
+
+ /* Use the PLL clock */
+ scb->cclksel = cclksel;
+ }
+}
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
+
+static BSP_START_TEXT_SECTION void lpc24xx_init_pll(void)
+{
+ #ifdef ARM_MULTILIB_ARCH_V4
+ #if LPC24XX_OSCILLATOR_MAIN == 12000000U
+ #if LPC24XX_CCLK == 72000000U
+ lpc24xx_set_pll(1, 0, 11, 3);
+ #elif LPC24XX_CCLK == 51612800U
+ lpc24xx_set_pll(1, 30, 399, 5);
+ #else
+ #error "unexpected CCLK"
+ #endif
+ #elif LPC24XX_OSCILLATOR_MAIN == 3686400U
+ #if LPC24XX_CCLK == 58982400U
+ lpc24xx_set_pll(1, 0, 47, 5);
+ #else
+ #error "unexpected CCLK"
+ #endif
+ #else
+ #error "unexpected main oscillator frequency"
+ #endif
+ #else
+ #if LPC24XX_OSCILLATOR_MAIN == 12000000U
+ #if LPC24XX_CCLK == 120000000U
+ lpc17xx_set_pll(9, 0, 1);
+ #elif LPC24XX_CCLK == 96000000U
+ lpc17xx_set_pll(7, 0, 1);
+ #elif LPC24XX_CCLK == 72000000U
+ lpc17xx_set_pll(5, 1, 1);
+ #elif LPC24XX_CCLK == 48000000U
+ lpc17xx_set_pll(3, 1, 1);
+ #else
+ #error "unexpected CCLK"
+ #endif
+ #else
+ #error "unexpected main oscillator frequency"
+ #endif
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_init_memory_map(void)
+{
+ #ifdef ARM_MULTILIB_ARCH_V4
+ /* Re-map interrupt vectors to internal RAM */
+ MEMMAP = SET_MEMMAP_MAP(MEMMAP, 2);
+ #else
+ volatile lpc17xx_scb *scb = &LPC17XX_SCB;
+
+ scb->memmap = LPC17XX_SCB_MEMMAP_MAP;
+ #endif
+
+ /* Use normal memory map */
+ EMC_CTRL &= ~0x2U;
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_init_memory_accelerator(void)
+{
+ #ifdef ARM_MULTILIB_ARCH_V4
+ /* Fully enable memory accelerator module functions (MAM) */
+ MAMCR = 0;
+ #if LPC24XX_CCLK <= 20000000U
+ MAMTIM = 0x1;
+ #elif LPC24XX_CCLK <= 40000000U
+ MAMTIM = 0x2;
+ #elif LPC24XX_CCLK <= 60000000U
+ MAMTIM = 0x3;
+ #else
+ MAMTIM = 0x4;
+ #endif
+ MAMCR = 0x2;
+
+ /* Enable fast IO for ports 0 and 1 */
+ SCS |= 0x1;
+ #else
+ volatile lpc17xx_scb *scb = &LPC17XX_SCB;
+
+ #if LPC24XX_CCLK <= 20000000U
+ scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x0);
+ #elif LPC24XX_CCLK <= 40000000U
+ scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x1);
+ #elif LPC24XX_CCLK <= 60000000U
+ scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x2);
+ #elif LPC24XX_CCLK <= 80000000U
+ scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x3);
+ #elif LPC24XX_CCLK <= 100000000U
+ scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x4);
+ #else
+ scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x5);
+ #endif
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_stop_gpdma(void)
+{
+ #ifdef LPC24XX_STOP_GPDMA
+ #ifdef ARM_MULTILIB_ARCH_V4
+ bool has_power = (PCONP & PCONP_GPDMA) != 0;
+ #else
+ volatile lpc17xx_scb *scb = &LPC17XX_SCB;
+ bool has_power = (scb->pconp & LPC17XX_SCB_PCONP_GPDMA) != 0;
+ #endif
+
+ if (has_power) {
+ GPDMA_CONFIG = 0;
+
+ #ifdef ARM_MULTILIB_ARCH_V4
+ PCONP &= ~PCONP_GPDMA;
+ #else
+ scb->pconp &= ~LPC17XX_SCB_PCONP_GPDMA;
+ #endif
+ }
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_stop_ethernet(void)
+{
+ #ifdef LPC24XX_STOP_ETHERNET
+ #ifdef ARM_MULTILIB_ARCH_V4
+ bool has_power = (PCONP & PCONP_ETHERNET) != 0;
+ #else
+ volatile lpc17xx_scb *scb = &LPC17XX_SCB;
+ bool has_power = (scb->pconp & LPC17XX_SCB_PCONP_ENET) != 0;
+ #endif
+
+ if (has_power) {
+ MAC_COMMAND = 0x38;
+ MAC_MAC1 = 0xcf00;
+ MAC_MAC1 = 0;
+
+ #ifdef ARM_MULTILIB_ARCH_V4
+ PCONP &= ~PCONP_ETHERNET;
+ #else
+ scb->pconp &= ~LPC17XX_SCB_PCONP_ENET;
+ #endif
+ }
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_stop_usb(void)
+{
+ #ifdef LPC24XX_STOP_USB
+ #ifdef ARM_MULTILIB_ARCH_V4
+ bool has_power = (PCONP & PCONP_USB) != 0;
+ #else
+ volatile lpc17xx_scb *scb = &LPC17XX_SCB;
+ bool has_power = (scb->pconp & LPC17XX_SCB_PCONP_USB) != 0;
+ #endif
+
+ if (has_power) {
+ OTG_CLK_CTRL = 0;
+
+ #ifdef ARM_MULTILIB_ARCH_V4
+ PCONP &= ~PCONP_USB;
+ #else
+ scb->pconp &= ~LPC17XX_SCB_PCONP_USB;
+ scb->usbclksel = 0;
+ #endif
+ }
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void lpc24xx_init_mpu(void)
+{
+ #ifdef ARM_MULTILIB_ARCH_V7M
+ volatile ARMV7M_MPU *mpu = _ARMV7M_MPU;
+ size_t region_count = lpc24xx_start_config_mpu_region_count;
+ size_t i = 0;
+
+ for (i = 0; i < region_count; ++i) {
+ mpu->rbar = lpc24xx_start_config_mpu_region [i].rbar;
+ mpu->rasr = lpc24xx_start_config_mpu_region [i].rasr;
+ }
+
+ if (region_count > 0) {
+ mpu->ctrl = ARMV7M_MPU_CTRL_ENABLE;
+ }
+ #endif
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+{
+ lpc24xx_init_main_oscillator();
+ lpc24xx_init_pll();
+ lpc24xx_init_pinsel();
+ lpc24xx_init_emc_static();
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+{
+ lpc24xx_init_memory_map();
+ lpc24xx_init_memory_accelerator();
+ lpc24xx_init_emc_dynamic();
+ lpc24xx_init_mpu();
+ lpc24xx_stop_gpdma();
+ lpc24xx_stop_ethernet();
+ lpc24xx_stop_usb();
+ bsp_start_copy_sections();
+ bsp_start_clear_bss();
+
+ /* At this point we can use objects outside the .start section */
+}
diff --git a/bsps/arm/lpc24xx/start/fb-config.c b/bsps/arm/lpc24xx/start/fb-config.c
new file mode 100644
index 0000000000..d1fa33c95a
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/fb-config.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/arm-pl111-fb.h>
+
+#include <bsp.h>
+#include <bsp/fatal.h>
+#include <bsp/io.h>
+#include <bsp/lcd.h>
+#include <bsp/lpc24xx.h>
+
+static const lpc24xx_pin_range tft_16_bit_5_6_5_pins[] = {
+ LPC24XX_PIN_LCD_DCLK,
+ LPC24XX_PIN_LCD_FP,
+ LPC24XX_PIN_LCD_LP,
+ LPC24XX_PIN_LCD_VD_3_P4_29,
+ LPC24XX_PIN_LCD_VD_4_P2_6,
+ LPC24XX_PIN_LCD_VD_5_P2_7,
+ LPC24XX_PIN_LCD_VD_6_P2_8,
+ LPC24XX_PIN_LCD_VD_7_P2_9,
+ LPC24XX_PIN_LCD_VD_10_P1_20,
+ LPC24XX_PIN_LCD_VD_11_P1_21,
+ LPC24XX_PIN_LCD_VD_12_P1_22,
+ LPC24XX_PIN_LCD_VD_13_P1_23,
+ LPC24XX_PIN_LCD_VD_14_P1_24,
+ LPC24XX_PIN_LCD_VD_15_P1_25,
+ LPC24XX_PIN_LCD_VD_19_P2_13,
+ LPC24XX_PIN_LCD_VD_20_P1_26,
+ LPC24XX_PIN_LCD_VD_21_P1_27,
+ LPC24XX_PIN_LCD_VD_22_P1_28,
+ LPC24XX_PIN_LCD_VD_23_P1_29,
+ LPC24XX_PIN_TERMINAL
+};
+
+static void fb_set_up(const pl111_fb_config *cfg)
+{
+ rtems_status_code sc;
+
+ sc = lpc24xx_module_enable(LPC24XX_MODULE_LCD, LPC24XX_MODULE_PCLK_DEFAULT);
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_fatal(LPC24XX_FATAL_PL111_SET_UP);
+ }
+
+ #ifdef ARM_MULTILIB_ARCH_V4
+ PINSEL11 = BSP_FLD32(LCD_MODE_TFT_16_BIT_5_6_5, 1, 3) | BSP_BIT32(0);
+ #endif
+
+ #ifdef ARM_MULTILIB_ARCH_V7M
+ volatile lpc17xx_scb *scb = &LPC17XX_SCB;
+
+ scb->matrixarb = 0x0c09;
+ #endif
+}
+
+static void fb_pins_set_up(const pl111_fb_config *cfg)
+{
+ rtems_status_code sc;
+
+ sc = lpc24xx_pin_config(tft_16_bit_5_6_5_pins, LPC24XX_PIN_SET_FUNCTION);
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_fatal(LPC24XX_FATAL_PL111_PINS_SET_UP);
+ }
+}
+
+static void fb_pins_tear_down(const pl111_fb_config *cfg)
+{
+ rtems_status_code sc;
+
+ sc = lpc24xx_pin_config(tft_16_bit_5_6_5_pins, LPC24XX_PIN_SET_INPUT);
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_fatal(LPC24XX_FATAL_PL111_PINS_TEAR_DOWN);
+ }
+}
+
+static void fb_tear_down(const pl111_fb_config *cfg)
+{
+ rtems_status_code sc;
+
+ #ifdef ARM_MULTILIB_ARCH_V4
+ PINSEL11 = 0;
+ #endif
+
+ sc = lpc24xx_module_disable(LPC24XX_MODULE_LCD);
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_fatal(LPC24XX_FATAL_PL111_TEAR_DOWN);
+ }
+}
+
+static const pl111_fb_config fb_config = {
+ .regs = (volatile pl111 *) LCD_BASE_ADDR,
+
+ .timing0 = PL111_LCD_TIMING0_PPL(640 / 16 - 1)
+ | PL111_LCD_TIMING0_HSW(0x1d)
+ | PL111_LCD_TIMING0_HFP(0x0f)
+ | PL111_LCD_TIMING0_HBP(0x71),
+ .timing1 = PL111_LCD_TIMING1_LPP(480 - 1)
+ | PL111_LCD_TIMING1_VSW(0x02)
+ | PL111_LCD_TIMING1_VFP(0x0a)
+ | PL111_LCD_TIMING1_VBP(0x20),
+ .timing2 = PL111_LCD_TIMING2_PCD_LO(0x3)
+ | PL111_LCD_TIMING2_ACB(0x0)
+ | PL111_LCD_TIMING2_IVS
+ | PL111_LCD_TIMING2_IHS
+ | PL111_LCD_TIMING2_IPC
+ | PL111_LCD_TIMING2_CPL(640 - 1)
+ | PL111_LCD_TIMING2_PCD_HI(0x0),
+ .timing3 = 0x0,
+ .control = PL111_LCD_CONTROL_LCD_TFT
+ | PL111_LCD_CONTROL_LCD_BPP(PL111_LCD_CONTROL_LCD_BPP_16)
+ | PL111_LCD_CONTROL_BGR,
+ .power_delay_in_us = 100000,
+
+ .set_up = fb_set_up,
+ .pins_set_up = fb_pins_set_up,
+ .pins_tear_down = fb_pins_tear_down,
+ .tear_down = fb_tear_down
+};
+
+const pl111_fb_config *arm_pl111_fb_get_config(void)
+{
+ return &fb_config;
+}
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_ea_ram b/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_ea_ram
new file mode 100644
index 0000000000..d98626108d
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_ea_ram
@@ -0,0 +1,27 @@
+/* LPC1788 OEM Board from Embedded Artists */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x10000000, LENGTH = 64k
+ RAM_PER (AIW) : ORIGIN = 0x20000000, LENGTH = 32k
+ RAM_EXT (AIW) : ORIGIN = 0xa0000000, LENGTH = 32M
+}
+
+REGION_ALIAS ("REGION_START", RAM_EXT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_ea_rom_int b/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_ea_rom_int
new file mode 100644
index 0000000000..db8c27f37f
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_ea_rom_int
@@ -0,0 +1,27 @@
+/* LPC1788 OEM Board from Embedded Artists */
+
+MEMORY {
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 512k
+ RAM_INT (AIW) : ORIGIN = 0x10000000, LENGTH = 64k
+ RAM_EXT (AIW) : ORIGIN = 0xa0000000, LENGTH = 32M
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_EXT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_EXT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_EXT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_plx800_ram b/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_plx800_ram
new file mode 100644
index 0000000000..e507877a84
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_plx800_ram
@@ -0,0 +1,33 @@
+/**
+ * @file
+ *
+ * @brief Memory map for PLX800 (LPC1778).
+ */
+
+MEMORY {
+ ROM_INT : ORIGIN = 0x00000000, LENGTH = 512k
+ RAM_INT : ORIGIN = 0x10000000, LENGTH = 64k
+ RAM_PER : ORIGIN = 0x20000000, LENGTH = 32k
+ ROM_EXT : ORIGIN = 0x80000000, LENGTH = 4M
+ RAM_EXT : ORIGIN = 0xa0000000, LENGTH = 32M
+}
+
+REGION_ALIAS ("REGION_START", RAM_EXT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_plx800_rom_int b/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_plx800_rom_int
new file mode 100644
index 0000000000..2ae0a58840
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc17xx_plx800_rom_int
@@ -0,0 +1,33 @@
+/**
+ * @file
+ *
+ * @brief Memory map for PLX800 (LPC1778).
+ */
+
+MEMORY {
+ ROM_INT : ORIGIN = 0x00000000, LENGTH = 512k
+ RAM_INT : ORIGIN = 0x10000000, LENGTH = 64k
+ RAM_PER : ORIGIN = 0x20000000, LENGTH = 32k
+ ROM_EXT : ORIGIN = 0x80000000, LENGTH = 4M
+ RAM_EXT : ORIGIN = 0xa0000000, LENGTH = 32M
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc2362 b/bsps/arm/lpc24xx/start/linkcmds.lpc2362
new file mode 100644
index 0000000000..e5bae18075
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc2362
@@ -0,0 +1,70 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx_linker_lpc2362
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc24xx_linker_lpc2362 LPC2362 Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief LPC2362 memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_INT</td><td>0x40000000</td><td>32k</td></tr>
+ * <tr><td>RAM_USB</td><td>0x7fd00000</td><td>8k</td></tr>
+ * <tr><td>RAM_ETH</td><td>0x7fe00000</td><td>16k</td></tr>
+ * <tr><td>ROM_INT</td><td>0x00000000</td><td>128k</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>ROM_INT</td><td></td></tr>
+ * <tr><td>.text</td><td>ROM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.rodata</td><td>ROM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.data</td><td>RAM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.fast</td><td>RAM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.bss</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x40000000, LENGTH = 32k
+ RAM_USB (AIW) : ORIGIN = 0x7fd00000, LENGTH = 8k
+ RAM_ETH (AIW) : ORIGIN = 0x7fe00000, LENGTH = 16k
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 128k
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+lpc24xx_region_heap_0_begin = ORIGIN (RAM_ETH);
+lpc24xx_region_heap_0_size = LENGTH (RAM_ETH);
+lpc24xx_region_heap_0_end = lpc24xx_region_heap_0_begin + lpc24xx_region_heap_0_size;
+
+lpc24xx_region_heap_1_begin = ORIGIN (RAM_USB);
+lpc24xx_region_heap_1_size = LENGTH (RAM_USB);
+lpc24xx_region_heap_1_end = lpc24xx_region_heap_1_begin + lpc24xx_region_heap_1_size;
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc23xx_tli800 b/bsps/arm/lpc24xx/start/linkcmds.lpc23xx_tli800
new file mode 100644
index 0000000000..697b040a84
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc23xx_tli800
@@ -0,0 +1,74 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx_linker_lpc23xx_tli800
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc24xx_linker_lpc23xx_tli800 TLI800 Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief TLI800 memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_INT</td><td>0x40000000</td><td>32k</td></tr>
+ * <tr><td>RAM_USB</td><td>0x7fd00000</td><td>8k</td></tr>
+ * <tr><td>RAM_ETH</td><td>0x7fe00000</td><td>16k</td></tr>
+ * <tr><td>ROM_BOOT</td><td>0x00000000</td><td>4k</td></tr>
+ * <tr><td>ROM_CFG</td><td>0x00001000</td><td>4k</td></tr>
+ * <tr><td>ROM_INT</td><td>0x00002000</td><td>120k</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>ROM_BOOT</td><td></td></tr>
+ * <tr><td>.text</td><td>ROM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.rodata</td><td>ROM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.data</td><td>RAM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.fast</td><td>RAM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.bss</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x40000000, LENGTH = 32k
+ RAM_USB (AIW) : ORIGIN = 0x7fd00000, LENGTH = 8k
+ RAM_ETH (AIW) : ORIGIN = 0x7fe00000, LENGTH = 16k
+ ROM_BOOT (RX) : ORIGIN = 0x00000000, LENGTH = 4k
+ ROM_CFG (RX) : ORIGIN = 0x00001000, LENGTH = 4k
+ ROM_INT (RX) : ORIGIN = 0x00002000, LENGTH = 120k
+}
+
+REGION_ALIAS ("REGION_START", ROM_BOOT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+lpc24xx_region_heap_0_begin = ORIGIN (RAM_ETH);
+lpc24xx_region_heap_0_size = LENGTH (RAM_ETH);
+lpc24xx_region_heap_0_end = lpc24xx_region_heap_0_begin + lpc24xx_region_heap_0_size;
+
+lpc24xx_region_heap_1_begin = ORIGIN (RAM_USB);
+lpc24xx_region_heap_1_size = LENGTH (RAM_USB);
+lpc24xx_region_heap_1_end = lpc24xx_region_heap_1_begin + lpc24xx_region_heap_1_size;
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ea b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ea
new file mode 100644
index 0000000000..80b1e13187
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ea
@@ -0,0 +1,59 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx_linker_ea
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc24xx_linker_ea QVGA Base Board Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief QVGA Base Board from Embedded Artists (LPC2478) memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_INT</td><td>0x40000000</td><td>64k</td></tr>
+ * <tr><td>RAM_EXT</td><td>0xa0000000</td><td>32M</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.vector</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.text</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.rodata</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.data</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.fast</td><td>RAM_INT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.bss</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x40000000, LENGTH = 64k
+ RAM_EXT (AIW) : ORIGIN = 0xa0000000, LENGTH = 32M
+}
+
+REGION_ALIAS ("REGION_START", RAM_EXT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_ram b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_ram
new file mode 100644
index 0000000000..9f421f3555
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_ram
@@ -0,0 +1,60 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx_linker_ncs_ram
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc24xx_linker_ncs_ram NCS Application Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief NCS application memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_INT</td><td>0x40000000</td><td>64k</td></tr>
+ * <tr><td>RAM_EXT</td><td>0xa0000000</td><td>8M</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.vector</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.text</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.rodata</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.data</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.fast</td><td>RAM_INT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.bss</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x40000000, LENGTH = 64k
+ RAM_USB (AIW) : ORIGIN = 0x7fd00000, LENGTH = 16k
+ RAM_EXT (AIW) : ORIGIN = 0xa0000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("REGION_START", RAM_EXT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_USB);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_rom_ext b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_rom_ext
new file mode 100644
index 0000000000..7618a342bd
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_rom_ext
@@ -0,0 +1,64 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx_linker_ncs_rom_ext
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc24xx_linker_ncs_rom_ext NCS Bootloader (LPC2470) Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief NCS bootloader (LPC2470) memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_INT</td><td>0x40000000</td><td>64k</td></tr>
+ * <tr><td>RAM_EXT</td><td>0xa0400000</td><td>4M</td></tr>
+ * <tr><td>ROM_BOOT</td><td>0x81000000</td><td>16k</td></tr>
+ * <tr><td>ROM_EXT</td><td>0x81010000</td><td>2M - 64k</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>ROM_BOOT</td><td></td></tr>
+ * <tr><td>.vector</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.text</td><td>RAM_EXT</td><td>ROM_EXT</td></tr>
+ * <tr><td>.rodata</td><td>RAM_EXT</td><td>ROM_EXT</td></tr>
+ * <tr><td>.data</td><td>RAM_EXT</td><td>ROM_EXT</td></tr>
+ * <tr><td>.fast</td><td>RAM_INT</td><td>ROM_BOOT</td></tr>
+ * <tr><td>.bss</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ RAM_INT (AIW) : ORIGIN = 0x40000000, LENGTH = 64k
+ RAM_USB (AIW) : ORIGIN = 0x7fd00000, LENGTH = 16k
+ RAM_EXT (AIW) : ORIGIN = 0xa0400000, LENGTH = 4M
+ ROM_BOOT (RX) : ORIGIN = 0x81000000, LENGTH = 16k
+ ROM_EXT (RX) : ORIGIN = 0x81010000, LENGTH = 2M - 64k
+}
+
+REGION_ALIAS ("REGION_START", ROM_BOOT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_BOOT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_USB);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_BOOT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_rom_int b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_rom_int
new file mode 100644
index 0000000000..47b79e7b5c
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_ncs_rom_int
@@ -0,0 +1,64 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx_linker_ncs_rom_int
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc24xx_linker_ncs_rom_int NCS Bootloader (LPC2478) Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief NCS bootloader (LPC2478) memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_VEC</td><td>0x40000000</td><td>32k</td></tr>
+ * <tr><td>RAM_INT</td><td>0x40008000</td><td>32k</td></tr>
+ * <tr><td>RAM_EXT</td><td>0xa0400000</td><td>4M</td></tr>
+ * <tr><td>ROM_INT</td><td>0x00000000</td><td>512k - 8k</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>ROM_INT</td><td></td></tr>
+ * <tr><td>.vector</td><td>RAM_VEC</td><td></td></tr>
+ * <tr><td>.text</td><td>ROM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.rodata</td><td>ROM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.data</td><td>RAM_EXT</td><td>ROM_INT</td></tr>
+ * <tr><td>.fast</td><td>RAM_INT</td><td>ROM_INT</td></tr>
+ * <tr><td>.bss</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ */
+
+
+MEMORY {
+ RAM_VEC (AIW) : ORIGIN = 0x40000000, LENGTH = 32k
+ RAM_INT (AIW) : ORIGIN = 0x40008000, LENGTH = 32k
+ RAM_USB (AIW) : ORIGIN = 0x7fd00000, LENGTH = 16k
+ RAM_EXT (AIW) : ORIGIN = 0xa0400000, LENGTH = 4M
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 512k - 8k
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_VEC);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_USB);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_plx800_ram b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_plx800_ram
new file mode 100644
index 0000000000..2dcc6d233f
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_plx800_ram
@@ -0,0 +1,32 @@
+/**
+ * @file
+ *
+ * @brief Memory map for PLX800 (LPC2478).
+ */
+
+MEMORY {
+ RAM_INT : ORIGIN = 0x40000000, LENGTH = 64k
+ RAM_EXT : ORIGIN = 0xa0000000, LENGTH = 32M
+ ROM_INT : ORIGIN = 0x00000000, LENGTH = 512k - 8k
+ ROM_EXT : ORIGIN = 0x80000000, LENGTH = 4M
+}
+
+REGION_ALIAS ("REGION_START", RAM_EXT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_plx800_rom_int b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_plx800_rom_int
new file mode 100644
index 0000000000..f00c1d8f93
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc24xx_plx800_rom_int
@@ -0,0 +1,32 @@
+/**
+ * @file
+ *
+ * @brief Memory map for PLX800 (LPC2478).
+ */
+
+MEMORY {
+ RAM_INT : ORIGIN = 0x40000000, LENGTH = 64k
+ RAM_EXT : ORIGIN = 0xa0000000, LENGTH = 32M
+ ROM_INT : ORIGIN = 0x00000000, LENGTH = 512k - 8k
+ ROM_EXT : ORIGIN = 0x80000000, LENGTH = 4M
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc40xx_ea_ram b/bsps/arm/lpc24xx/start/linkcmds.lpc40xx_ea_ram
new file mode 100644
index 0000000000..d4535963cb
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc40xx_ea_ram
@@ -0,0 +1 @@
+INCLUDE linkcmds.lpc17xx_ea_ram
diff --git a/bsps/arm/lpc24xx/start/linkcmds.lpc40xx_ea_rom_int b/bsps/arm/lpc24xx/start/linkcmds.lpc40xx_ea_rom_int
new file mode 100644
index 0000000000..612f4916d3
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/linkcmds.lpc40xx_ea_rom_int
@@ -0,0 +1 @@
+INCLUDE linkcmds.lpc17xx_ea_rom_int
diff --git a/bsps/arm/lpc24xx/start/start-config-emc-dynamic.c b/bsps/arm/lpc24xx/start/start-config-emc-dynamic.c
new file mode 100644
index 0000000000..3a08f0b49d
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/start-config-emc-dynamic.c
@@ -0,0 +1,271 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx
+ *
+ * @brief BSP start EMC dynamic memory configuration.
+ */
+
+/*
+ * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/start-config.h>
+#include <bsp/lpc24xx.h>
+
+/*
+ * FIXME: The NXP example code uses different values for the follwing two
+ * defines. In the NXP example code they depend on the EMCCLK. It is unclear
+ * how these values are determined. The values from the NXP example code do
+ * not work.
+ */
+
+/* Use command delayed strategy */
+#define LPC24XX_EMC_DYNAMIC_READCONFIG_DEFAULT 0x1
+
+#define LPC24XX_EMCDLYCTL_DEFAULT 0x1112
+
+BSP_START_DATA_SECTION const lpc24xx_emc_dynamic_config
+ lpc24xx_start_config_emc_dynamic [] = {
+#if defined(LPC24XX_EMC_MT48LC4M16A2)
+ /* Dynamic Memory 0: Micron M T48LC 4M16 A2 P 75 IT */
+ {
+ /* 15.6 us */
+ .refresh = LPC24XX_PS_TO_EMCCLK(15600000, 0) / 16,
+
+ .readconfig = LPC24XX_EMC_DYNAMIC_READCONFIG_DEFAULT,
+
+ /* Precharge command period 20 ns */
+ .trp = 1,
+
+ /* Active to precharge command period 44 ns */
+ .tras = 3,
+
+ /* FIXME */
+ .tsrex = 5,
+
+ /* FIXME */
+ .tapr = 2,
+
+ /* Data-in to active command period tWR + tRP */
+ .tdal = 4,
+
+ /* Write recovery time 15 ns */
+ .twr = 1,
+
+ /* Active to active command period 66 ns */
+ .trc = 4,
+
+ /* Auto refresh period 66 ns */
+ .trfc = 4,
+
+ /* Exit self refresh to active command period 75 ns */
+ .txsr = 5,
+
+ /* Active bank a to active bank b command period 15 ns */
+ .trrd = 1,
+
+ /* Load mode register to active or refresh command period 2 tCK */
+ .tmrd = 1
+ }
+#elif defined(LPC24XX_EMC_IS42S32800D7)
+ /* Dynamic Memory 0: ISSI IS42S32800D7 */
+ {
+ /* 15.6 us */
+ .refresh = LPC24XX_PS_TO_EMCCLK(15600000, 0) / 16,
+
+ .readconfig = LPC24XX_EMC_DYNAMIC_READCONFIG_DEFAULT,
+
+ /* 20ns */
+ .trp = LPC24XX_PS_TO_EMCCLK(20000, 1),
+
+ /* 45ns */
+ .tras = LPC24XX_PS_TO_EMCCLK(45000, 1),
+
+ /* 70ns (tXSR) */
+ .tsrex = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* 20ns (tRCD) */
+ .tapr = LPC24XX_PS_TO_EMCCLK(20000, 1),
+
+ /* n clock cycles -> 38.8ns >= 35ns */
+ .tdal = LPC24XX_PS_TO_EMCCLK(35000, 0),
+
+ /* 14ns (tDPL) */
+ .twr = LPC24XX_PS_TO_EMCCLK(14000, 1),
+
+ /* 67.5ns */
+ .trc = LPC24XX_PS_TO_EMCCLK(67500, 1),
+
+ /* 67.5ns (tRC) */
+ .trfc = LPC24XX_PS_TO_EMCCLK(67500, 1),
+
+ /* 70ns */
+ .txsr = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* 14ns */
+ .trrd = LPC24XX_PS_TO_EMCCLK(14000, 1),
+
+ /* 14ns */
+ .tmrd = LPC24XX_PS_TO_EMCCLK(14000, 1),
+
+ .emcdlyctl = LPC24XX_EMCDLYCTL_DEFAULT
+ }
+#elif defined(LPC24XX_EMC_W9825G2JB75I)
+ /* Dynamic Memory 0: Winbond W9825G2JB75I */
+ {
+ /* 15.6 us */
+ .refresh = LPC24XX_PS_TO_EMCCLK(15600000, 0) / 16,
+
+ .readconfig = LPC24XX_EMC_DYNAMIC_READCONFIG_DEFAULT,
+
+ /* 20ns */
+ .trp = LPC24XX_PS_TO_EMCCLK(20000, 1),
+
+ /* 45ns */
+ .tras = LPC24XX_PS_TO_EMCCLK(45000, 1),
+
+ /* 75ns (tXSR) */
+ .tsrex = LPC24XX_PS_TO_EMCCLK(75000, 1),
+
+ /* 20ns (tRCD) */
+ .tapr = LPC24XX_PS_TO_EMCCLK(20000, 1),
+
+ /* tWR + tRP -> 2 * tCK + 20ns */
+ .tdal = 2 + LPC24XX_PS_TO_EMCCLK(20000, 0),
+
+ /* (n + 1) clock cycles == 2 * tCK */
+ .twr = 1,
+
+ /* 65ns */
+ .trc = LPC24XX_PS_TO_EMCCLK(65000, 1),
+
+ /* 65ns (tRC) */
+ .trfc = LPC24XX_PS_TO_EMCCLK(65000, 1),
+
+ /* 75ns */
+ .txsr = LPC24XX_PS_TO_EMCCLK(50000, 1),
+
+ /* (n + 1) clock cycles == 2 * tCK */
+ .trrd = 1,
+
+ /* (n + 1) clock cycles == 2 * tCK (tRSC)*/
+ .tmrd = 1,
+
+ .emcdlyctl = LPC24XX_EMCDLYCTL_DEFAULT
+ }
+#elif defined(LPC24XX_EMC_K4S561632E)
+ {
+ .refresh = 35,
+ .readconfig = LPC24XX_EMC_DYNAMIC_READCONFIG_DEFAULT,
+ .trp = 2,
+ .tras = 4,
+ .tsrex = 5,
+ .tapr = 1,
+ .tdal = 5,
+ .twr = 3,
+ .trc = 5,
+ .trfc = 5,
+ .txsr = 5,
+ .trrd = 3,
+ .tmrd = 2
+ }
+#elif defined(LPC24XX_EMC_IS42S32800B)
+ {
+ /* 15.6us */
+ .refresh = LPC24XX_PS_TO_EMCCLK(15600000, 0) / 16,
+
+ .readconfig = LPC24XX_EMC_DYNAMIC_READCONFIG_DEFAULT,
+
+ /* 20ns */
+ .trp = LPC24XX_PS_TO_EMCCLK(20000, 1),
+
+ /* 45ns */
+ .tras = LPC24XX_PS_TO_EMCCLK(45000, 1),
+
+ /* 70ns (tRC) */
+ .tsrex = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* FIXME */
+ .tapr = LPC24XX_PS_TO_EMCCLK(40000, 1),
+
+ /* tWR + tRP -> 2 * tCK + 20ns */
+ .tdal = 2 + LPC24XX_PS_TO_EMCCLK(20000, 0),
+
+ /* (n + 1) clock cycles == 2 * tCK */
+ .twr = 1,
+
+ /* 70ns */
+ .trc = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* 70ns */
+ .trfc = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* 70ns (tRC) */
+ .txsr = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* 14ns */
+ .trrd = LPC24XX_PS_TO_EMCCLK(14000, 1),
+
+ /* (n + 1) clock cycles == 2 * tCK */
+ .tmrd = 1,
+
+ .emcdlyctl = LPC24XX_EMCDLYCTL_DEFAULT
+ }
+#endif
+};
+
+BSP_START_DATA_SECTION const lpc24xx_emc_dynamic_chip_config
+ lpc24xx_start_config_emc_dynamic_chip [] = {
+#if defined(LPC24XX_EMC_MT48LC4M16A2)
+ {
+ .chip_select = (volatile lpc_emc_dynamic *) &EMC_DYN_CFG0,
+
+ /*
+ * Use SDRAM, 0 0 001 01 address mapping, disabled buffer, unprotected
+ * writes. 4 banks, 12 row lines, 8 column lines.
+ */
+ .config = 0x280,
+
+ .rascas = EMC_DYN_RASCAS_RAS(2) | EMC_DYN_RASCAS_CAS(2, 0),
+ .mode = 0xa0000000 | (0x23 << (1 + 2 + 8))
+ }
+#elif defined(LPC24XX_EMC_W9825G2JB75I) \
+ || defined(LPC24XX_EMC_IS42S32800D7) \
+ || defined(LPC24XX_EMC_IS42S32800B)
+ {
+ .chip_select = (volatile lpc_emc_dynamic *) &EMC_DYN_CFG0,
+
+ /* 32-bit data bus, 4 banks, 12 row lines, 9 column lines, RBC */
+ .config = 0x4480,
+
+ /* RAS based on tRCD = 20ns */
+ .rascas = EMC_DYN_RASCAS_RAS(2) | EMC_DYN_RASCAS_CAS(2, 0),
+
+ /* CAS 2, burst length 4 */
+ .mode = 0xa0000000 | (0x22 << (2 + 2 + 9))
+ }
+#elif defined(LPC24XX_EMC_K4S561632E)
+ {
+ .chip_select = (volatile lpc_emc_dynamic *) &EMC_DYN_CFG0,
+ .config = 0x680,
+ .rascas = EMC_DYN_RASCAS_RAS(3) | EMC_DYN_RASCAS_CAS(3, 0),
+ .mode = 0xa0000000 | (0x33 << 12)
+ }
+#endif
+};
+
+BSP_START_DATA_SECTION const size_t
+ lpc24xx_start_config_emc_dynamic_chip_count =
+ sizeof(lpc24xx_start_config_emc_dynamic_chip)
+ / sizeof(lpc24xx_start_config_emc_dynamic_chip [0]);
diff --git a/bsps/arm/lpc24xx/start/start-config-emc-static.c b/bsps/arm/lpc24xx/start/start-config-emc-static.c
new file mode 100644
index 0000000000..4a427664f6
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/start-config-emc-static.c
@@ -0,0 +1,133 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx
+ *
+ * @brief BSP start EMC static memory configuration.
+ */
+
+/*
+ * Copyright (c) 2011 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/start-config.h>
+#include <bsp/lpc24xx.h>
+
+BSP_START_DATA_SECTION const lpc24xx_emc_static_chip_config
+ lpc24xx_start_config_emc_static_chip [] = {
+#if defined(LPC24XX_EMC_M29W160E)
+ /*
+ * Static Memory 1: Numonyx M29W160EB
+ *
+ * 1 clock cycle = 1/72MHz = 13.9ns
+ */
+ {
+ .chip_select = (volatile lpc_emc_static *) EMC_STA_BASE_1,
+ .config = {
+ /*
+ * 16 bit, page mode disabled, active LOW chip select, extended wait
+ * disabled, writes not protected, byte lane state LOW/LOW (!).
+ */
+ .config = 0x81,
+
+ /* 1 clock cycles delay from the chip select 1 to the write enable */
+ .waitwen = 0,
+
+ /*
+ * 0 clock cycles delay from the chip select 1 or address change
+ * (whichever is later) to the output enable
+ */
+ .waitoen = 0,
+
+ /* 7 clock cycles delay from the chip select 1 to the read access */
+ .waitrd = 0x6,
+
+ /*
+ * 32 clock cycles delay for asynchronous page mode sequential accesses
+ */
+ .waitpage = 0x1f,
+
+ /* 5 clock cycles delay from the chip select 1 to the write access */
+ .waitwr = 0x3,
+
+ /* 16 bus turnaround cycles */
+ .waitrun = 0xf
+ }
+ }
+#elif defined(LPC24XX_EMC_M29W320E70)
+ /* Static Memory 0: M29W320E70 */
+ {
+ .chip_select = (volatile lpc_emc_static *) EMC_STA_BASE_0,
+ .config = {
+ /*
+ * 16 bit, page mode disabled, active LOW chip select, extended wait
+ * disabled, writes not protected, byte lane state LOW/LOW.
+ */
+ .config = 0x81,
+
+ /* 30ns (tWHWL) */
+ .waitwen = LPC24XX_PS_TO_EMCCLK(30000, 1),
+
+ /* 0ns */
+ .waitoen = LPC24XX_PS_TO_EMCCLK(0, 1),
+
+ /* 70ns (tAVQV, tELQV) */
+ .waitrd = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* 70ns (tAVQV, tELQV) */
+ .waitpage = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* max(30ns (tWHWL) + 45ns (tWLWH), 70ns (tAVAV)) */
+ .waitwr = LPC24XX_PS_TO_EMCCLK(75000, 2),
+
+ /* 25ns (tEHQZ) */
+ .waitrun = LPC24XX_PS_TO_EMCCLK(25000, 1)
+ }
+ }
+#elif defined(LPC24XX_EMC_SST39VF3201)
+ /* Static Memory 0: SST39VF3201 */
+ {
+ .chip_select = (volatile lpc_emc_static *) EMC_STA_BASE_0,
+ .config = {
+ /*
+ * 16 bit, page mode disabled, active LOW chip select, extended wait
+ * disabled, writes not protected, byte lane state LOW/LOW.
+ */
+ .config = 0x81,
+
+ /* 0ns (tCS, tAS) */
+ .waitwen = LPC24XX_PS_TO_EMCCLK(0, 1),
+
+ /* 0ns (tOES) */
+ .waitoen = LPC24XX_PS_TO_EMCCLK(0, 1),
+
+ /* 70ns (tRC) */
+ .waitrd = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* 70ns (tRC) */
+ .waitpage = LPC24XX_PS_TO_EMCCLK(70000, 1),
+
+ /* 20ns (tCHZ, TOHZ) */
+ .waitwr = LPC24XX_PS_TO_EMCCLK(20000, 2),
+
+ /* 20ns (tCHZ, TOHZ) */
+ .waitrun = LPC24XX_PS_TO_EMCCLK(20000, 1)
+ }
+ }
+#endif
+};
+
+BSP_START_DATA_SECTION const size_t
+ lpc24xx_start_config_emc_static_chip_count =
+ sizeof(lpc24xx_start_config_emc_static_chip)
+ / sizeof(lpc24xx_start_config_emc_static_chip [0]);
diff --git a/bsps/arm/lpc24xx/start/start-config-mpu.c b/bsps/arm/lpc24xx/start/start-config-mpu.c
new file mode 100644
index 0000000000..9d9846c69a
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/start-config-mpu.c
@@ -0,0 +1,86 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx
+ *
+ * @brief BSP start MPU configuration.
+ */
+
+/*
+ * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/start-config.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+ BSP_START_DATA_SECTION const ARMV7M_MPU_Region
+ lpc24xx_start_config_mpu_region [] = {
+ #if defined(LPC24XX_EMC_IS42S32800D7) \
+ || defined(LPC24XX_EMC_W9825G2JB75I) \
+ || defined(LPC24XX_EMC_IS42S32800B)
+ ARMV7M_MPU_REGION_INITIALIZER(
+ 0,
+ 0x00000000,
+ ARMV7M_MPU_SIZE_512_KB,
+ ARMV7M_MPU_ATTR_RX
+ ),
+ ARMV7M_MPU_REGION_INITIALIZER(
+ 1,
+ 0x10000000,
+ ARMV7M_MPU_SIZE_64_KB,
+ ARMV7M_MPU_ATTR_RWX
+ ),
+ ARMV7M_MPU_REGION_INITIALIZER(
+ 2,
+ 0x20000000,
+ ARMV7M_MPU_SIZE_32_KB,
+ ARMV7M_MPU_ATTR_RWX
+ ),
+ ARMV7M_MPU_REGION_INITIALIZER(
+ 3,
+ 0xa0000000,
+ ARMV7M_MPU_SIZE_32_MB,
+ ARMV7M_MPU_ATTR_RWX
+ ),
+ ARMV7M_MPU_REGION_INITIALIZER(
+ 4,
+ 0x20080000,
+ ARMV7M_MPU_SIZE_128_KB,
+ ARMV7M_MPU_ATTR_IO
+ ),
+ ARMV7M_MPU_REGION_INITIALIZER(
+ 5,
+ 0x40000000,
+ ARMV7M_MPU_SIZE_1_MB,
+ ARMV7M_MPU_ATTR_IO
+ ),
+ #if defined(LPC24XX_EMC_M29W320E70) \
+ || defined(LPC24XX_EMC_SST39VF3201)
+ ARMV7M_MPU_REGION_INITIALIZER(
+ 6,
+ 0x80000000,
+ ARMV7M_MPU_SIZE_4_MB,
+ ARMV7M_MPU_ATTR_RWX
+ ),
+ #else
+ ARMV7M_MPU_REGION_DISABLED_INITIALIZER(6),
+ #endif
+ ARMV7M_MPU_REGION_DISABLED_INITIALIZER(7)
+ #endif
+ };
+
+ BSP_START_DATA_SECTION const size_t
+ lpc24xx_start_config_mpu_region_count =
+ sizeof(lpc24xx_start_config_mpu_region)
+ / sizeof(lpc24xx_start_config_mpu_region [0]);
+#endif
diff --git a/bsps/arm/lpc24xx/start/start-config-pinsel.c b/bsps/arm/lpc24xx/start/start-config-pinsel.c
new file mode 100644
index 0000000000..db44099664
--- /dev/null
+++ b/bsps/arm/lpc24xx/start/start-config-pinsel.c
@@ -0,0 +1,74 @@
+/**
+ * @file
+ *
+ * @ingroup lpc24xx
+ *
+ * @brief BSP start pin selection configuration.
+ */
+
+/*
+ * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/start-config.h>
+
+BSP_START_DATA_SECTION const lpc24xx_pin_range
+ lpc24xx_start_config_pinsel [] = {
+#if defined(LPC24XX_EMC_MT48LC4M16A2) \
+ && defined(LPC24XX_EMC_M29W160E)
+ LPC24XX_PIN_EMC_A_0_20,
+ LPC24XX_PIN_EMC_D_0_15,
+ LPC24XX_PIN_EMC_RAS,
+ LPC24XX_PIN_EMC_CAS,
+ LPC24XX_PIN_EMC_WE,
+ LPC24XX_PIN_EMC_DYCS_0,
+ LPC24XX_PIN_EMC_CLK_0,
+ LPC24XX_PIN_EMC_CKE_0,
+ LPC24XX_PIN_EMC_DQM_0,
+ LPC24XX_PIN_EMC_DQM_1,
+ LPC24XX_PIN_EMC_OE,
+ LPC24XX_PIN_EMC_CS_1,
+#endif
+#if (defined(LPC24XX_EMC_IS42S32800D7) || defined(LPC24XX_EMC_W9825G2JB75I)) \
+ && (defined(LPC24XX_EMC_M29W320E70) || defined(LPC24XX_EMC_SST39VF3201))
+ LPC24XX_PIN_EMC_A_0_22,
+ LPC24XX_PIN_EMC_D_0_31,
+ LPC24XX_PIN_EMC_RAS,
+ LPC24XX_PIN_EMC_CAS,
+ LPC24XX_PIN_EMC_WE,
+ LPC24XX_PIN_EMC_DYCS_0,
+ LPC24XX_PIN_EMC_CLK_0,
+ LPC24XX_PIN_EMC_CKE_0,
+ LPC24XX_PIN_EMC_DQM_0,
+ LPC24XX_PIN_EMC_DQM_1,
+ LPC24XX_PIN_EMC_DQM_2,
+ LPC24XX_PIN_EMC_DQM_3,
+ LPC24XX_PIN_EMC_OE,
+ LPC24XX_PIN_EMC_CS_0,
+#endif
+#if defined(LPC24XX_EMC_IS42S32800B)
+ LPC24XX_PIN_EMC_A_0_14,
+ LPC24XX_PIN_EMC_D_0_31,
+ LPC24XX_PIN_EMC_RAS,
+ LPC24XX_PIN_EMC_CAS,
+ LPC24XX_PIN_EMC_WE,
+ LPC24XX_PIN_EMC_DYCS_0,
+ LPC24XX_PIN_EMC_CLK_0,
+ LPC24XX_PIN_EMC_CKE_0,
+ LPC24XX_PIN_EMC_DQM_0,
+ LPC24XX_PIN_EMC_DQM_1,
+ LPC24XX_PIN_EMC_DQM_2,
+ LPC24XX_PIN_EMC_DQM_3,
+#endif
+ LPC24XX_PIN_TERMINAL
+};
diff --git a/bsps/arm/lpc32xx/start/bsp_specs b/bsps/arm/lpc32xx/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/lpc32xx/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/lpc32xx/start/bspreset.c b/bsps/arm/lpc32xx/start/bspreset.c
new file mode 100644
index 0000000000..e3c4cfbbd2
--- /dev/null
+++ b/bsps/arm/lpc32xx/start/bspreset.c
@@ -0,0 +1,48 @@
+/**
+ * @file
+ *
+ * @ingroup arm_lpc32xx
+ *
+ * @brief Reset code.
+ */
+
+/*
+ * Copyright (c) 2009-2010 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdbool.h>
+
+#include <bspopts.h>
+#include <bsp/bootcard.h>
+#include <bsp/lpc32xx.h>
+
+static void watchdog_reset(void)
+{
+ #ifdef LPC32XX_ENABLE_WATCHDOG_RESET
+ LPC32XX_TIMCLK_CTRL |= TIMCLK_CTRL_WDT;
+ lpc32xx.wdt.mctrl |= WDTTIM_MCTRL_M_RES1 | WDTTIM_MCTRL_M_RES2;
+ lpc32xx.wdt.emr = WDTTIM_EMR_MATCH_CTRL_SET(lpc32xx.wdt.emr, 0x2);
+ lpc32xx.wdt.ctrl |= WDTTIM_CTRL_COUNT_ENAB;
+ lpc32xx.wdt.match0 = 1;
+ lpc32xx.wdt.counter = 0;
+ #endif
+}
+
+void bsp_reset( void)
+{
+ watchdog_reset();
+
+ while (true) {
+ /* Do nothing */
+ }
+}
diff --git a/bsps/arm/lpc32xx/start/bspstart.c b/bsps/arm/lpc32xx/start/bspstart.c
new file mode 100644
index 0000000000..7ade16bbb8
--- /dev/null
+++ b/bsps/arm/lpc32xx/start/bspstart.c
@@ -0,0 +1,38 @@
+/**
+ * @file
+ *
+ * @ingroup arm_lpc32xx
+ *
+ * @brief Startup code.
+ */
+
+/*
+ * Copyright (c) 2009-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/counter.h>
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+
+CPU_Counter_ticks _CPU_Counter_read(void)
+{
+ return lpc32xx_timer();
+}
+
+void bsp_start(void)
+{
+ rtems_counter_initialize_converter(LPC32XX_PERIPH_CLK);
+ bsp_interrupt_initialize();
+}
diff --git a/bsps/arm/lpc32xx/start/bspstarthooks.c b/bsps/arm/lpc32xx/start/bspstarthooks.c
new file mode 100644
index 0000000000..1df21b4343
--- /dev/null
+++ b/bsps/arm/lpc32xx/start/bspstarthooks.c
@@ -0,0 +1,240 @@
+/**
+ * @file
+ *
+ * @ingroup arm_lpc32xx
+ *
+ * @brief Startup code.
+ */
+
+/*
+ * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/lpc32xx.h>
+#include <bsp/mmu.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/uart-output-char.h>
+
+#ifdef LPC32XX_DISABLE_READ_WRITE_DATA_CACHE
+ #define LPC32XX_MMU_READ_WRITE_DATA LPC32XX_MMU_READ_WRITE
+#else
+ #define LPC32XX_MMU_READ_WRITE_DATA LPC32XX_MMU_READ_WRITE_CACHED
+#endif
+
+#ifdef LPC32XX_DISABLE_READ_ONLY_PROTECTION
+ #define LPC32XX_MMU_READ_ONLY_DATA LPC32XX_MMU_READ_WRITE_CACHED
+ #define LPC32XX_MMU_CODE LPC32XX_MMU_READ_WRITE_CACHED
+#else
+ #define LPC32XX_MMU_READ_ONLY_DATA LPC32XX_MMU_READ_ONLY_CACHED
+ #define LPC32XX_MMU_CODE LPC32XX_MMU_READ_ONLY_CACHED
+#endif
+
+#ifndef LPC32XX_DISABLE_MMU
+ static const BSP_START_DATA_SECTION arm_cp15_start_section_config
+ lpc32xx_mmu_config_table [] = {
+ {
+ .begin = (uint32_t) bsp_section_fast_text_begin,
+ .end = (uint32_t) bsp_section_fast_text_end,
+ .flags = LPC32XX_MMU_CODE
+ }, {
+ .begin = (uint32_t) bsp_section_fast_data_begin,
+ .end = (uint32_t) bsp_section_fast_data_end,
+ .flags = LPC32XX_MMU_READ_WRITE_DATA
+#ifdef LPC32XX_SCRATCH_AREA_SIZE
+ }, {
+ .begin = (uint32_t) &lpc32xx_scratch_area [0],
+ .end = (uint32_t) &lpc32xx_scratch_area [LPC32XX_SCRATCH_AREA_SIZE],
+ .flags = LPC32XX_MMU_READ_ONLY_DATA
+#endif
+ }, {
+ .begin = (uint32_t) bsp_section_start_begin,
+ .end = (uint32_t) bsp_section_start_end,
+ .flags = LPC32XX_MMU_CODE
+ }, {
+ .begin = (uint32_t) bsp_section_vector_begin,
+ .end = (uint32_t) bsp_section_vector_end,
+ .flags = LPC32XX_MMU_READ_WRITE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_text_begin,
+ .end = (uint32_t) bsp_section_text_end,
+ .flags = LPC32XX_MMU_CODE
+ }, {
+ .begin = (uint32_t) bsp_section_rodata_begin,
+ .end = (uint32_t) bsp_section_rodata_end,
+ .flags = LPC32XX_MMU_READ_ONLY_DATA
+ }, {
+ .begin = (uint32_t) bsp_section_data_begin,
+ .end = (uint32_t) bsp_section_data_end,
+ .flags = LPC32XX_MMU_READ_WRITE_DATA
+ }, {
+ .begin = (uint32_t) bsp_section_bss_begin,
+ .end = (uint32_t) bsp_section_bss_end,
+ .flags = LPC32XX_MMU_READ_WRITE_DATA
+ }, {
+ .begin = (uint32_t) bsp_section_work_begin,
+ .end = (uint32_t) bsp_section_work_end,
+ .flags = LPC32XX_MMU_READ_WRITE_DATA
+ }, {
+ .begin = (uint32_t) bsp_section_stack_begin,
+ .end = (uint32_t) bsp_section_stack_end,
+ .flags = LPC32XX_MMU_READ_WRITE_DATA
+ }, {
+ .begin = 0x0U,
+ .end = 0x100000U,
+ .flags = LPC32XX_MMU_READ_ONLY_CACHED
+ }, {
+ .begin = 0x20000000U,
+ .end = 0x200c0000U,
+ .flags = LPC32XX_MMU_READ_WRITE
+ }, {
+ .begin = 0x30000000U,
+ .end = 0x32000000U,
+ .flags = LPC32XX_MMU_READ_WRITE
+ }, {
+ .begin = 0x40000000U,
+ .end = 0x40100000U,
+ .flags = LPC32XX_MMU_READ_WRITE
+ }, {
+ .begin = (uint32_t) lpc32xx_magic_zero_begin,
+ .end = (uint32_t) lpc32xx_magic_zero_end,
+ .flags = LPC32XX_MMU_READ_WRITE_DATA
+ }
+ };
+#endif
+
+static BSP_START_TEXT_SECTION void setup_mmu_and_cache(void)
+{
+ uint32_t ctrl = arm_cp15_start_setup_mmu_and_cache(
+ ARM_CP15_CTRL_I | ARM_CP15_CTRL_R | ARM_CP15_CTRL_C
+ | ARM_CP15_CTRL_V | ARM_CP15_CTRL_M,
+ ARM_CP15_CTRL_S | ARM_CP15_CTRL_A
+ );
+
+ arm_cp15_cache_invalidate();
+
+ #ifndef LPC32XX_DISABLE_MMU
+ arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
+ ctrl,
+ (uint32_t *) bsp_translation_table_base,
+ LPC32XX_MMU_CLIENT_DOMAIN,
+ &lpc32xx_mmu_config_table [0],
+ RTEMS_ARRAY_SIZE(lpc32xx_mmu_config_table)
+ );
+ #endif
+}
+
+BSP_START_TEXT_SECTION bool lpc32xx_start_pll_setup(
+ uint32_t hclkpll_ctrl,
+ uint32_t hclkdiv_ctrl,
+ bool force
+)
+{
+ uint32_t pwr_ctrl = LPC32XX_PWR_CTRL;
+ bool settings_ok =
+ ((LPC32XX_HCLKPLL_CTRL ^ hclkpll_ctrl) & BSP_MSK32(1, 16)) == 0
+ && ((LPC32XX_HCLKDIV_CTRL ^ hclkdiv_ctrl) & BSP_MSK32(0, 8)) == 0;
+
+ if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) == 0 || (!settings_ok && force)) {
+ /* Disable HCLK PLL output */
+ LPC32XX_PWR_CTRL = pwr_ctrl & ~PWR_NORMAL_RUN_MODE;
+
+ /* Configure HCLK PLL */
+ LPC32XX_HCLKPLL_CTRL = hclkpll_ctrl;
+ while ((LPC32XX_HCLKPLL_CTRL & HCLK_PLL_LOCK) == 0) {
+ /* Wait */
+ }
+
+ /* Setup HCLK divider */
+ LPC32XX_HCLKDIV_CTRL = hclkdiv_ctrl;
+
+ /* Enable HCLK PLL output */
+ LPC32XX_PWR_CTRL = pwr_ctrl | PWR_NORMAL_RUN_MODE;
+ }
+
+ return settings_ok;
+}
+
+#if LPC32XX_OSCILLATOR_MAIN != 13000000U
+ #error "unexpected main oscillator frequency"
+#endif
+
+static BSP_START_TEXT_SECTION void setup_pll(void)
+{
+ uint32_t hclkpll_ctrl = LPC32XX_HCLKPLL_CTRL_INIT_VALUE;
+ uint32_t hclkdiv_ctrl = LPC32XX_HCLKDIV_CTRL_INIT_VALUE;
+
+ lpc32xx_start_pll_setup(hclkpll_ctrl, hclkdiv_ctrl, false);
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+{
+ setup_pll();
+}
+
+static BSP_START_TEXT_SECTION void stop_dma_activities(void)
+{
+ #ifdef LPC32XX_STOP_GPDMA
+ LPC32XX_DO_STOP_GPDMA;
+ #endif
+
+ #ifdef LPC32XX_STOP_ETHERNET
+ LPC32XX_DO_STOP_ETHERNET;
+ #endif
+
+ #ifdef LPC32XX_STOP_USB
+ LPC32XX_DO_STOP_USB;
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void setup_uarts(void)
+{
+ LPC32XX_UART_CTRL = 0x0;
+ LPC32XX_UART_LOOP = 0x0;
+
+ #ifdef LPC32XX_UART_5_BAUD
+ LPC32XX_UARTCLK_CTRL |= 1U << 2;
+ LPC32XX_U5CLK = LPC32XX_CONFIG_U5CLK;
+ LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 8, 9);
+ BSP_CONSOLE_UART_INIT(0x01);
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void setup_timer(void)
+{
+ volatile lpc_timer *timer = LPC32XX_STANDARD_TIMER;
+
+ LPC32XX_TIMCLK_CTRL1 = (1U << 2) | (1U << 3);
+
+ timer->tcr = LPC_TIMER_TCR_RST;
+ timer->ctcr = 0x0;
+ timer->pr = 0x0;
+ timer->ir = 0xff;
+ timer->mcr = 0x0;
+ timer->ccr = 0x0;
+ timer->tcr = LPC_TIMER_TCR_EN;
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+{
+ stop_dma_activities();
+ bsp_start_copy_sections();
+ setup_mmu_and_cache();
+ setup_uarts();
+ setup_timer();
+ bsp_start_clear_bss();
+}
diff --git a/bsps/arm/lpc32xx/start/linkcmds.lpc32xx b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx
new file mode 100644
index 0000000000..200e7f3e04
--- /dev/null
+++ b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx
@@ -0,0 +1,17 @@
+/**
+ * @file
+ *
+ * @ingroup lpc32xx_linker
+ *
+ * @brief Linker support.
+ */
+
+bsp_translation_table_base = ORIGIN (RAM_MMU);
+
+lpc32xx = 0x20020000;
+
+lpc32xx_magic_zero_begin = 0x05000000;
+lpc32xx_magic_zero_end = 0x07000000;
+lpc32xx_magic_zero_size = lpc32xx_magic_zero_end - lpc32xx_magic_zero_end;
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx
new file mode 100644
index 0000000000..127a82f79a
--- /dev/null
+++ b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx
@@ -0,0 +1,69 @@
+/**
+ * @file
+ *
+ * @ingroup lpc32xx_linker_mzx
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc32xx_linker_mzx MZX Application Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief MZX application memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_INT</td><td>0x08000000</td><td>256k</td></tr>
+ * <tr><td>RAM_MMU</td><td>0x80000000</td><td>16k</td></tr>
+ * <tr><td>RAM_EXT</td><td>0x80004000</td><td>32M - 16k</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.vector</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.text</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.rodata</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.data</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.fast</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.bss</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ RAM_INT : ORIGIN = 0x08000000, LENGTH = 256k
+ RAM_MMU : ORIGIN = 0x80000000, LENGTH = 16k /* SDRAM on DYCS0 */
+ RAM_SCRATCH : ORIGIN = 0x80004000, LENGTH = 4k /* SDRAM on DYCS0 */
+ RAM_EXT : ORIGIN = 0x80005000, LENGTH = 32M - 20k /* SDRAM on DYCS0 */
+}
+
+REGION_ALIAS ("REGION_START", RAM_EXT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+lpc32xx_scratch_area = ORIGIN (RAM_SCRATCH);
+
+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;
+
+INCLUDE linkcmds.lpc32xx
diff --git a/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx_stage_1 b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx_stage_1
new file mode 100644
index 0000000000..eae076e235
--- /dev/null
+++ b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx_stage_1
@@ -0,0 +1,68 @@
+/**
+ * @file
+ *
+ * @ingroup lpc32xx_linker_mzx_stage_1
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc32xx_linker_mzx_stage_1 MZX Stage-1 Program Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief MZX stage-1 program memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_INT</td><td>0x08000000</td><td>232k</td></tr>
+ * <tr><td>RAM_MMU</td><td>0x0803a000</td><td>16k</td></tr>
+ * <tr><td>RAM_VEC</td><td>0x0803d000</td><td>8k</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.vector</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.text</td><td>RAM_INT</td><td>RAM_INT</td></tr>
+ * <tr><td>.rodata</td><td>RAM_INT</td><td>RAM_INT</td></tr>
+ * <tr><td>.data</td><td>RAM_INT</td><td>RAM_INT</td></tr>
+ * <tr><td>.fast</td><td>RAM_INT</td><td>RAM_INT</td></tr>
+ * <tr><td>.bss</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ RAM_INT : ORIGIN = 0x08000000, LENGTH = 232k
+ RAM_VEC : ORIGIN = 0x0803a000, LENGTH = 8k
+ RAM_MMU : ORIGIN = 0x0803c000, LENGTH = 16k
+ RAM_SCRATCH : ORIGIN = 0x80004000, LENGTH = 4k /* SDRAM on DYCS0 */
+}
+
+REGION_ALIAS ("REGION_START", RAM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_VEC);
+REGION_ALIAS ("REGION_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_RODATA", RAM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+lpc32xx_scratch_area = ORIGIN (RAM_SCRATCH);
+
+bsp_stack_svc_size = DEFINED (bsp_stack_svc_size) ? bsp_stack_svc_size : 7168;
+
+bsp_vector_table_in_start_section = 1;
+
+INCLUDE linkcmds.lpc32xx
diff --git a/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx_stage_2 b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx_stage_2
new file mode 100644
index 0000000000..2aa8c34091
--- /dev/null
+++ b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_mzx_stage_2
@@ -0,0 +1,67 @@
+/**
+ * @file
+ *
+ * @ingroup lpc32xx_linker_mzx_stage_2
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc32xx_linker_mzx_stage_2 MZX Stage-2 Program Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief MZX stage-2 program memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_INT</td><td>0x08000000</td><td>256k</td></tr>
+ * <tr><td>RAM_MMU</td><td>0x81c00000</td><td>16k</td></tr>
+ * <tr><td>RAM_EXT</td><td>0x81c04000</td><td>4M - 16k</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.vector</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.text</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.rodata</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.data</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.fast</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.bss</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ RAM_INT : ORIGIN = 0x08000000, LENGTH = 240k
+ RAM_FAST : ORIGIN = 0x0803c000, LENGTH = 16k
+ RAM_MMU : ORIGIN = 0x80000000, LENGTH = 16k /* SDRAM on DYCS0 */
+ RAM_SCRATCH : ORIGIN = 0x80004000, LENGTH = 4k /* SDRAM on DYCS0 */
+ RAM_EXT : ORIGIN = 0x81c00000, LENGTH = 4M /* SDRAM on DYCS0 */
+}
+
+REGION_ALIAS ("REGION_START", RAM_EXT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_FAST);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_FAST);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+lpc32xx_scratch_area = ORIGIN (RAM_SCRATCH);
+
+bsp_stack_svc_size = DEFINED (bsp_stack_svc_size) ? bsp_stack_svc_size : 8192;
+
+INCLUDE linkcmds.lpc32xx
diff --git a/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_phycore b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_phycore
new file mode 100644
index 0000000000..d874c46152
--- /dev/null
+++ b/bsps/arm/lpc32xx/start/linkcmds.lpc32xx_phycore
@@ -0,0 +1,68 @@
+/**
+ * @file
+ *
+ * @ingroup lpc32xx_linker_phycore
+ *
+ * @brief Memory map.
+ */
+
+/**
+ * @defgroup lpc32xx_linker_phycore phyCORE-LPC3250 Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief phyCORE-LPC3250 memory map.
+ *
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>RAM_INT</td><td>0x08000000</td><td>256k</td></tr>
+ * <tr><td>RAM_MMU</td><td>0x80000000</td><td>16k</td></tr>
+ * <tr><td>RAM_EXT</td><td>0x80004000</td><td>64M - 16k</td></tr>
+ * <tr><td>ROM_EXT</td><td>0xe0000000</td><td>2M</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.vector</td><td>RAM_INT</td><td></td></tr>
+ * <tr><td>.text</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.rodata</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.data</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.fast</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
+ * <tr><td>.bss</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM_EXT</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ RAM_INT : ORIGIN = 0x08000000, LENGTH = 256k
+ RAM_MMU : ORIGIN = 0x80000000, LENGTH = 16k /* SDRAM on DYCS0 */
+ RAM_EXT : ORIGIN = 0x80004000, LENGTH = 64M - 16k /* SDRAM on DYCS0 */
+ ROM_EXT : ORIGIN = 0xe0000000, LENGTH = 2M /* NOR flash on CS0 */
+}
+
+REGION_ALIAS ("REGION_START", RAM_EXT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+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;
+
+INCLUDE linkcmds.lpc32xx
diff --git a/bsps/arm/raspberrypi/start/bsp_specs b/bsps/arm/raspberrypi/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/raspberrypi/start/bspgetworkarea.c b/bsps/arm/raspberrypi/start/bspgetworkarea.c
new file mode 100644
index 0000000000..6a43e3c437
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/bspgetworkarea.c
@@ -0,0 +1,78 @@
+/**
+ * @file
+ *
+ * @ingroup arm_start
+ *
+ * @brief Raspberry pi workarea initialization.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2011-2012 embedded brains GmbH.
+ *
+ * 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.
+ *
+ * Copyright (c) 2015 YANG Qiao
+ *
+ * Code is based on c/src/lib/libbsp/shared/bspgetworkarea.c
+ */
+
+#include <string.h>
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/vc.h>
+#ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN
+ #include <rtems/config.h>
+#endif
+
+#if defined(HAS_UBOOT) && !defined(BSP_DISABLE_UBOOT_WORK_AREA_CONFIG)
+ #define USE_UBOOT
+#endif
+
+/*
+ * These are provided by the linkcmds for ALL of the BSPs which use this file.
+ */
+extern char WorkAreaBase[];
+
+/*
+ * We may get the size information from U-Boot or the linker scripts.
+ */
+#ifdef USE_UBOOT
+ #include <bsp/u-boot.h>
+#else
+ extern char RamBase[];
+ extern char RamSize[];
+#endif
+
+void bsp_work_area_initialize(void)
+{
+ uintptr_t work_base = (uintptr_t) WorkAreaBase;
+ uintptr_t ram_end;
+ bcm2835_get_vc_memory_entries vc_entry;
+ /*
+ * bcm2835_get_arm_memory_entries arm_entry;
+ * is another alternative how to obtain usable memory size
+ */
+
+ #ifdef USE_UBOOT
+ ram_end = (uintptr_t) bsp_uboot_board_info.bi_memstart +
+ bsp_uboot_board_info.bi_memsize;
+ #else
+ ram_end = (uintptr_t)RamBase + (uintptr_t)RamSize;
+ #endif
+
+ #ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN
+ work_base += rtems_configuration_get_interrupt_stack_size();
+ #endif
+
+ memset( &vc_entry, 0, sizeof(vc_entry) );
+ if (bcm2835_mailbox_get_vc_memory( &vc_entry ) >= 0) {
+ if (vc_entry.base > 10 * 1024 *1024)
+ ram_end = ram_end > vc_entry.base? vc_entry.base: ram_end;
+ }
+ bsp_work_area_initialize_default( (void *) work_base, ram_end - work_base );
+}
diff --git a/bsps/arm/raspberrypi/start/bspreset.c b/bsps/arm/raspberrypi/start/bspreset.c
new file mode 100644
index 0000000000..98c28bea9d
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/bspreset.c
@@ -0,0 +1,26 @@
+/**
+ * @file
+ *
+ * @ingroup raspberrypi
+ *
+ * @brief Raspberry pi restart chip function
+ */
+
+#include <bsp/bootcard.h>
+#include <bsp/raspberrypi.h>
+#include <bsp.h>
+#include <rtems.h>
+
+void bsp_reset(void)
+{
+ uint32_t rstc;
+
+ BCM2835_REG(BCM2835_PM_WDOG) = BCM2835_PM_PASSWD_MAGIC | 20;
+ rstc = BCM2835_REG(BCM2835_PM_RSTC);
+ rstc &= ~BCM2835_PM_RSTC_WRCFG;
+ rstc |= BCM2835_PM_PASSWD_MAGIC | BCM2835_PM_RSTC_WRCFG_FULL;
+ BCM2835_REG(BCM2835_PM_RSTC) = rstc;
+ BCM2835_REG(BCM2835_PM_WDOG) = BCM2835_PM_PASSWD_MAGIC | 1;
+
+ while (1) ;
+}
diff --git a/bsps/arm/raspberrypi/start/bspsmp.c b/bsps/arm/raspberrypi/start/bspsmp.c
new file mode 100644
index 0000000000..c3e5451442
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/bspsmp.c
@@ -0,0 +1,83 @@
+/**
+ * @file
+ *
+ * @ingroup raspberrypi
+ *
+ * @brief Raspberry pi SMP management functions provided to SuperCore
+ */
+
+/*
+ * Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ *
+ * Czech Technical University in Prague
+ * Zikova 1903/4
+ * 166 36 Praha 6
+ * Czech Republic
+ *
+ * Reuses some ideas from Rohini Kulkarni <krohini1593@gmail.com>
+ * GSoC 2015 project and Altera Cyclone-V SMP code
+ * by embedded brains GmbH
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/score/smpimpl.h>
+
+#include <bsp/start.h>
+#include <bsp/raspberrypi.h>
+#include <bsp.h>
+#include <bsp/arm-cp15-start.h>
+#include <libcpu/arm-cp15.h>
+#include <rtems.h>
+#include <bsp/irq-generic.h>
+#include <assert.h>
+
+bool _CPU_SMP_Start_processor( uint32_t cpu_index )
+{
+ bool started;
+ uint32_t cpu_index_self = _SMP_Get_current_processor();
+
+ if (cpu_index != cpu_index_self) {
+
+ BCM2835_REG(BCM2836_MAILBOX_3_WRITE_SET_BASE + 0x10 * cpu_index) = (uint32_t)_start;
+
+ /*
+ * Wait for secondary processor to complete its basic initialization so
+ * that we can enable the unified L2 cache.
+ */
+ started = _Per_CPU_State_wait_for_non_initial_state(cpu_index, 0);
+ } else {
+ started = false;
+ }
+
+ return started;
+}
+
+uint32_t _CPU_SMP_Initialize(void)
+{
+ uint32_t cpu_count = (uint32_t)bsp_processor_count;
+
+ if ( cpu_count > 4 )
+ cpu_count = 4;
+
+ return cpu_count;
+}
+
+void _CPU_SMP_Finalize_initialization( uint32_t cpu_count )
+{
+ /* Do nothing */
+}
+
+void _CPU_SMP_Prepare_start_multitasking( void )
+{
+ /* Do nothing */
+}
+
+void _CPU_SMP_Send_interrupt( uint32_t target_cpu_index )
+{
+ /* Generates IPI */
+ BCM2835_REG(BCM2836_MAILBOX_3_WRITE_SET_BASE +
+ 0x10 * target_cpu_index) = 0x1;
+}
diff --git a/bsps/arm/raspberrypi/start/bspsmp_init.c b/bsps/arm/raspberrypi/start/bspsmp_init.c
new file mode 100644
index 0000000000..8c8cd74712
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/bspsmp_init.c
@@ -0,0 +1,81 @@
+/**
+ * @file
+ *
+ * @ingroup raspberrypi
+ *
+ * @brief Raspberry pi secondary CPU and IPI HW initialization
+ */
+
+/*
+ * Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ *
+ * Czech Technical University in Prague
+ * Zikova 1903/4
+ * 166 36 Praha 6
+ * Czech Republic
+ *
+ * Reuses some ideas from Rohini Kulkarni <krohini1593@gmail.com>
+ * GSoC 2015 project and Altera Cyclone-V SMP code
+ * by embedded brains GmbH
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/score/smpimpl.h>
+
+#include <bsp/start.h>
+#include <bsp/raspberrypi.h>
+#include <bsp.h>
+#include <bsp/arm-cp15-start.h>
+#include <libcpu/arm-cp15.h>
+#include <rtems.h>
+#include <bsp/irq-generic.h>
+#include <assert.h>
+
+void rpi_ipi_initialize(void)
+{
+ uint32_t cpu_index_self = _SMP_Get_current_processor();
+
+ /*
+ * Includes support only for mailbox 3 interrupt.
+ * Further interrupt support has to be added. This will have to be integrated
+ * with existing interrupt support for Raspberry Pi
+ */
+
+ /* reset mailbox 3 contents to zero */
+ BCM2835_REG(BCM2836_MAILBOX_3_READ_CLEAR_BASE + 0x10 * cpu_index_self) = 0xffffffff;
+
+ BCM2835_REG(BCM2836_MAILBOX_IRQ_CTRL(cpu_index_self)) =
+ BCM2836_MAILBOX_IRQ_CTRL_MBOX3_IRQ;
+}
+
+void rpi_start_rtems_on_secondary_processor(void)
+{
+ uint32_t ctrl;
+
+ ctrl = arm_cp15_start_setup_mmu_and_cache(
+ 0,
+ ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z
+ );
+
+ rpi_ipi_initialize();
+
+ arm_cp15_set_domain_access_control(
+ ARM_CP15_DAC_DOMAIN(ARM_MMU_DEFAULT_CLIENT_DOMAIN, ARM_CP15_DAC_CLIENT)
+ );
+
+ /* FIXME: Sharing the translation table between processors is brittle */
+ arm_cp15_set_translation_table_base(
+ (uint32_t *) bsp_translation_table_base
+ );
+
+ arm_cp15_tlb_invalidate();
+
+ ctrl |= ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M;
+ ctrl &= ~ARM_CP15_CTRL_V;
+ arm_cp15_set_control(ctrl);
+
+ _SMP_Start_multitasking_on_secondary_processor();
+}
diff --git a/bsps/arm/raspberrypi/start/bspstart.c b/bsps/arm/raspberrypi/start/bspstart.c
new file mode 100644
index 0000000000..c5786bfa4a
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/bspstart.c
@@ -0,0 +1,29 @@
+/**
+ * @file
+ *
+ * @ingroup arm_start
+ *
+ * @brief Raspberry pi startup code.
+ */
+
+/*
+ * Copyright (c) 2013 by Alan Cudmore
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.org/license/LICENSE
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+#include <bsp/irq.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/stackalloc.h>
+#include <bsp/raspberrypi.h>
+
+void bsp_start(void)
+{
+ bsp_interrupt_initialize();
+}
diff --git a/bsps/arm/raspberrypi/start/bspstarthooks.c b/bsps/arm/raspberrypi/start/bspstarthooks.c
new file mode 100644
index 0000000000..165a555880
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/bspstarthooks.c
@@ -0,0 +1,107 @@
+/**
+ * @file
+ *
+ * @ingroup arm_start
+ *
+ * @brief Rasberry Pi startup code.
+ */
+
+/*
+ * Copyright (c) 2013. Hesham AL-Matary
+ * Copyright (c) 2013 by Alan Cudmore
+ * based on work by:
+ * Copyright (c) 2009
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE
+ */
+
+#include <bspopts.h>
+#include <bsp/start.h>
+#include <bsp/raspberrypi.h>
+#include <bsp/mm.h>
+#include <libcpu/arm-cp15.h>
+#include <bsp.h>
+
+#ifdef RTEMS_SMP
+#include <rtems/score/smp.h>
+#endif
+
+void BSP_START_TEXT_SECTION bsp_start_hook_0(void)
+{
+ uint32_t sctlr_val;
+#ifdef RTEMS_SMP
+ uint32_t cpu_index_self = _SMP_Get_current_processor();
+#endif /* RTEMS_SMP */
+
+ sctlr_val = arm_cp15_get_control();
+
+ /*
+ * 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_val & (ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M)) {
+ if (sctlr_val & (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.
+ */
+#ifdef RTEMS_SMP
+ if (cpu_index_self != 0) {
+ arm_cp15_data_cache_clean_level(0);
+ arm_cp15_cache_invalidate_level(0, 0);
+ } else
+#endif /* RTEMS_SMP */
+ {
+ rtems_cache_flush_entire_data();
+ rtems_cache_invalidate_entire_data();
+ }
+ }
+ arm_cp15_flush_prefetch_buffer();
+ sctlr_val &= ~(ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M | ARM_CP15_CTRL_A);
+ arm_cp15_set_control(sctlr_val);
+ }
+#ifdef RTEMS_SMP
+ if (cpu_index_self != 0) {
+ arm_cp15_cache_invalidate_level(0, 0);
+ } else
+#endif /* RTEMS_SMP */
+ {
+ rtems_cache_invalidate_entire_data();
+ }
+ rtems_cache_invalidate_entire_instruction();
+ arm_cp15_branch_predictor_invalidate_all();
+ arm_cp15_tlb_invalidate();
+ arm_cp15_flush_prefetch_buffer();
+
+ /* Clear Translation Table Base Control Register */
+ arm_cp15_set_translation_table_base_control_register(0);
+
+ /* Clear Secure or Non-secure Vector Base Address Register */
+ arm_cp15_set_vector_base_address(0);
+
+#ifdef RTEMS_SMP
+ if (cpu_index_self == 0) {
+ rpi_ipi_initialize();
+ } else {
+ rpi_start_rtems_on_secondary_processor();
+ }
+#endif
+}
+
+void BSP_START_TEXT_SECTION bsp_start_hook_1(void)
+{
+ bsp_start_copy_sections();
+ bsp_memory_management_initialize();
+ bsp_start_clear_bss();
+
+ rpi_video_init();
+}
diff --git a/bsps/arm/raspberrypi/start/cmdline.c b/bsps/arm/raspberrypi/start/cmdline.c
new file mode 100644
index 0000000000..222b21eb63
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/cmdline.c
@@ -0,0 +1,55 @@
+/**
+ * @file
+ *
+ * @ingroup raspberrypi
+ *
+ * @brief mailbox support.
+ */
+/*
+ * Copyright (c) 2015 Yang Qiao
+ *
+ * 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/vc.h>
+
+#include <string.h>
+
+#define MAX_CMDLINE_LENGTH 1024
+static int rpi_cmdline_ready = -1;
+static char rpi_cmdline_cached[MAX_CMDLINE_LENGTH] = "force .data placement";
+static bcm2835_get_cmdline_entries rpi_cmdline_entries;
+
+const char *rpi_cmdline_get_raw(void)
+{
+ memset(&rpi_cmdline_entries, 0, sizeof(rpi_cmdline_entries));
+ if (bcm2835_mailbox_get_cmdline(&rpi_cmdline_entries) < 0)
+ return NULL;
+ return rpi_cmdline_entries.cmdline;
+}
+
+const char *rpi_cmdline_get_cached(void)
+{
+ if (rpi_cmdline_ready <= 0) {
+ const char *line = rpi_cmdline_get_raw();
+ if (line != NULL)
+ strncpy(rpi_cmdline_cached, line, MAX_CMDLINE_LENGTH - 1);
+ rpi_cmdline_cached[MAX_CMDLINE_LENGTH - 1] = 0;
+ rpi_cmdline_ready = 1;
+ }
+ return rpi_cmdline_cached;
+}
+
+const char *rpi_cmdline_get_arg(const char* arg)
+{
+ const char *opt_data;
+ opt_data = strstr(rpi_cmdline_get_cached(), arg);
+ if (opt_data)
+ opt_data += strlen(arg);
+ return opt_data;
+}
diff --git a/bsps/arm/raspberrypi/start/linkcmds.in b/bsps/arm/raspberrypi/start/linkcmds.in
new file mode 100644
index 0000000000..829716c11c
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/linkcmds.in
@@ -0,0 +1,70 @@
+/**
+ * @file
+ *
+ * @ingroup raspberrypi_linker
+ *
+ * @brief Memory map
+ */
+
+/**
+ * @defgroup raspberrypi_linker Raspberry Pi Memory Map
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief Raspberry Pi memory map.
+ */
+
+/**
+ * <table>
+ * <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
+ * <tr><td>VECTOR_RAM</td><td>0x08000000</td><td>8k</td></tr>
+ * <tr><td>RAM</td><td>0x80008000</td><td>128M</td></tr>
+ * </table>
+ *
+ * <table>
+ * <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
+ * <tr><td>.start</td><td>RAM</td><td></td></tr>
+ * <tr><td>.vector</td><td>VECTOR_RAM</td><td></td></tr>
+ * <tr><td>.text</td><td>RAM</td><td>RAM_EXT</td></tr>
+ * <tr><td>.rodata</td><td>RAM</td><td>RAM_EXT</td></tr>
+ * <tr><td>.data</td><td>RAM</td><td>RAM_EXT</td></tr>
+ * <tr><td>.fast</td><td>RAM</td><td>RAM_EXT</td></tr>
+ * <tr><td>.bss</td><td>RAM</td><td></td></tr>
+ * <tr><td>.work</td><td>RAM</td><td></td></tr>
+ * <tr><td>.stack</td><td>RAM</td><td></td></tr>
+ * </table>
+ */
+
+MEMORY {
+ VECTOR_RAM (AIW) : ORIGIN = 0x0 , LENGTH = 16k
+ RAM_MMU (AIW) : ORIGIN = 0x00004000, LENGTH = 16k
+ RAM (AIW) : ORIGIN = 0x00008000, LENGTH = 128M - 32k
+}
+
+bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : @RASPBERRYPI_CPUS@;
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_VECTOR", 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 : 3008;
+bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
+
+bsp_section_robarrier_align = DEFINED (bsp_section_robarrier_align) ? bsp_section_robarrier_align : 1M;
+bsp_translation_table_base = ORIGIN (RAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/raspberrypi/start/mm_config_table.c b/bsps/arm/raspberrypi/start/mm_config_table.c
new file mode 100644
index 0000000000..27fa76b355
--- /dev/null
+++ b/bsps/arm/raspberrypi/start/mm_config_table.c
@@ -0,0 +1,96 @@
+/**
+ * @file
+ *
+ * @ingroup arm_start
+ *
+ * @brief Raspberry Pi low level start
+ */
+
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/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 contentent
+ * and rest is used for writeable section
+ */
+
+const arm_cp15_start_section_config arm_cp15_start_mmu_config_table[] = {
+ {
+ .begin = (uint32_t) bsp_section_fast_text_begin,
+ .end = (uint32_t) bsp_section_fast_text_end,
+ .flags = ARMV7_MMU_CODE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_start_begin,
+ .end = (uint32_t) bsp_section_start_end,
+ .flags = ARMV7_MMU_CODE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_text_begin,
+ .end = (uint32_t) bsp_section_text_end,
+ .flags = ARMV7_MMU_CODE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_rodata_begin,
+ .end = (uint32_t) bsp_section_rodata_end,
+ .flags = ARMV7_MMU_DATA_READ_ONLY_CACHED
+ }, {
+ .begin = (uint32_t) bsp_translation_table_base,
+ .end = (uint32_t) bsp_translation_table_base + 0x4000,
+ .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_fast_data_begin,
+ .end = (uint32_t) bsp_section_fast_data_end,
+ .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_vector_begin,
+ .end = (uint32_t) bsp_section_vector_end,
+ .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_data_begin,
+ .end = (uint32_t) bsp_section_data_end,
+ .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_bss_begin,
+ .end = (uint32_t) bsp_section_bss_end,
+ .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_work_begin,
+ .end = (uint32_t) bsp_section_work_end,
+ .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED
+ }, {
+ .begin = (uint32_t) bsp_section_stack_begin,
+ .end = (uint32_t) bsp_section_stack_end,
+ .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED
+ }, {
+ .begin = RPI_PERIPHERAL_BASE,
+ .end = RPI_PERIPHERAL_BASE + RPI_PERIPHERAL_SIZE,
+ .flags = ARMV7_MMU_DEVICE
+ }
+#if (BSP_IS_RPI2 == 1)
+ /* Core local peripherals area - timer, mailboxes */
+ , {
+ .begin = BCM2836_CORE_LOCAL_PERIPH_BASE,
+ .end = BCM2836_CORE_LOCAL_PERIPH_BASE + BCM2836_CORE_LOCAL_PERIPH_SIZE,
+ .flags = ARMV7_MMU_DEVICE
+ }
+#endif
+};
+
+const size_t arm_cp15_start_mmu_config_table_size =
+ RTEMS_ARRAY_SIZE(arm_cp15_start_mmu_config_table);
diff --git a/bsps/arm/realview-pbx-a9/start/bsp_specs b/bsps/arm/realview-pbx-a9/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/realview-pbx-a9/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/realview-pbx-a9/start/bspreset.c b/bsps/arm/realview-pbx-a9/start/bspreset.c
new file mode 100644
index 0000000000..15ff7193f1
--- /dev/null
+++ b/bsps/arm/realview-pbx-a9/start/bspreset.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/bootcard.h>
+
+void bsp_reset(void)
+{
+ volatile uint32_t *sys_lock = (volatile uint32_t *) 0x10000020;
+ volatile uint32_t *sys_resetctl = (volatile uint32_t *) 0x10000040;
+
+ while (true) {
+ *sys_lock = 0xa05f;
+ *sys_resetctl = 0xf4;
+ }
+}
diff --git a/bsps/arm/realview-pbx-a9/start/bspsmp.c b/bsps/arm/realview-pbx-a9/start/bspsmp.c
new file mode 100644
index 0000000000..471e7e5f29
--- /dev/null
+++ b/bsps/arm/realview-pbx-a9/start/bspsmp.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/score/smpimpl.h>
+
+bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+{
+ (void) cpu_index;
+
+ /* Nothing to do */
+
+ return true;
+}
diff --git a/bsps/arm/realview-pbx-a9/start/bspstart.c b/bsps/arm/realview-pbx-a9/start/bspstart.c
new file mode 100644
index 0000000000..0be515c057
--- /dev/null
+++ b/bsps/arm/realview-pbx-a9/start/bspstart.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/arm-a9mpcore-clock.h>
+#include <bsp/irq-generic.h>
+
+void bsp_start(void)
+{
+ a9mpcore_clock_initialize_early();
+ bsp_interrupt_initialize();
+}
diff --git a/bsps/arm/realview-pbx-a9/start/bspstarthooks.c b/bsps/arm/realview-pbx-a9/start/bspstarthooks.c
new file mode 100644
index 0000000000..ab766e8626
--- /dev/null
+++ b/bsps/arm/realview-pbx-a9/start/bspstarthooks.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/arm-a9mpcore-start.h>
+
+BSP_START_DATA_SECTION static const arm_cp15_start_section_config
+rvpbxa9_mmu_config_table[] = {
+ ARMV7_CP15_START_DEFAULT_SECTIONS,
+ {
+ .begin = 0x10000000U,
+ .end = 0x10020000U,
+ .flags = ARMV7_MMU_DEVICE
+ }, {
+ .begin = 0x1f000000U,
+ .end = 0x20000000U,
+ .flags = ARMV7_MMU_DEVICE
+ }, {
+ .begin = 0x4e000000U,
+ .end = 0x4f000000U,
+ .flags = ARMV7_MMU_DEVICE
+ }
+};
+
+BSP_START_TEXT_SECTION static void setup_mmu_and_cache(void)
+{
+ uint32_t ctrl = arm_cp15_start_setup_mmu_and_cache(
+ ARM_CP15_CTRL_A,
+ ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z
+ );
+
+ arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
+ ctrl,
+ (uint32_t *) bsp_translation_table_base,
+ ARM_MMU_DEFAULT_CLIENT_DOMAIN,
+ &rvpbxa9_mmu_config_table[0],
+ RTEMS_ARRAY_SIZE(rvpbxa9_mmu_config_table)
+ );
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+{
+#ifdef RTEMS_SMP
+ uint32_t cpu_id = arm_cortex_a9_get_multiprocessor_cpu_id();
+
+ /*
+ * QEMU jumps to the entry point of the ELF file on all processors. Prevent
+ * a SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR this way.
+ */
+ if ( cpu_id >= rtems_configuration_get_maximum_processors() ) {
+ while (true) {
+ _ARM_Wait_for_event();
+ }
+ }
+#endif
+
+ arm_a9mpcore_start_hook_0();
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+{
+ arm_a9mpcore_start_hook_1();
+ bsp_start_copy_sections();
+ setup_mmu_and_cache();
+ bsp_start_clear_bss();
+}
diff --git a/bsps/arm/realview-pbx-a9/start/fb-config.c b/bsps/arm/realview-pbx-a9/start/fb-config.c
new file mode 100644
index 0000000000..a756c9ab22
--- /dev/null
+++ b/bsps/arm/realview-pbx-a9/start/fb-config.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/arm-pl111-fb.h>
+#include <bsp.h>
+
+static void fb_set_up(const pl111_fb_config *cfg)
+{
+ /* TODO */
+}
+
+static void fb_pins_set_up(const pl111_fb_config *cfg)
+{
+ /* TODO */
+}
+
+static void fb_pins_tear_down(const pl111_fb_config *cfg)
+{
+ /* TODO */
+}
+
+static void fb_tear_down(const pl111_fb_config *cfg)
+{
+ /* TODO */
+}
+
+static const pl111_fb_config fb_config = {
+ .regs = (volatile pl111 *) 0x10020000,
+
+ /*
+ * Values obtained from "RealView Platform Baseboard Explore for Cortex-A9
+ * User Guide" section 4.6.1 "Display resolutions and display memory
+ * organization".
+ */
+ .timing0 = 0x3f1f3f9c,
+ .timing1 = 0x090b61df,
+ .timing2 = 0x067f1800,
+
+ .timing3 = 0x0,
+ .control = PL111_LCD_CONTROL_LCD_TFT
+ | PL111_LCD_CONTROL_LCD_BPP(PL111_LCD_CONTROL_LCD_BPP_16)
+ | PL111_LCD_CONTROL_BGR,
+ .power_delay_in_us = 100000,
+ .set_up = fb_set_up,
+ .pins_set_up = fb_pins_set_up,
+ .pins_tear_down = fb_pins_tear_down,
+ .tear_down = fb_tear_down
+};
+
+const pl111_fb_config *arm_pl111_fb_get_config(void)
+{
+ return &fb_config;
+}
diff --git a/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu b/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu
new file mode 100644
index 0000000000..e3b5b471b4
--- /dev/null
+++ b/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu
@@ -0,0 +1,35 @@
+MEMORY {
+ /* Waste the first 1MiB for NULL pointer protection */
+ RAM : ORIGIN = 0x00100000, LENGTH = 255M - 16k
+ RAM_MMU : ORIGIN = 0x0fffc000, LENGTH = 16k
+}
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_VECTOR", RAM);
+REGION_ALIAS ("REGION_TEXT", RAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_RODATA", RAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", RAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM);
+
+bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
+bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
+
+bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1M;
+
+bsp_vector_table_in_start_section = 1;
+
+bsp_translation_table_base = ORIGIN (RAM_MMU);
+bsp_translation_table_end = ORIGIN (RAM_MMU) + LENGTH (RAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu_smp b/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu_smp
new file mode 100644
index 0000000000..d31c4f08ae
--- /dev/null
+++ b/bsps/arm/realview-pbx-a9/start/linkcmds.realview_pbx_a9_qemu_smp
@@ -0,0 +1,3 @@
+bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 8;
+
+INCLUDE linkcmds.realview_pbx_a9_qemu
diff --git a/bsps/arm/rtl22xx/start/bsp_specs b/bsps/arm/rtl22xx/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/rtl22xx/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/rtl22xx/start/bspreset.c b/bsps/arm/rtl22xx/start/bspreset.c
new file mode 100644
index 0000000000..573b4a2aa8
--- /dev/null
+++ b/bsps/arm/rtl22xx/start/bspreset.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2007 by Ray Xu <rayx.cn@gmail.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <lpc22xx.h>
+
+void bsp_reset(void)
+{
+#if ON_SKYEYE == 1
+ #define SKYEYE_MAGIC_ADDRESS (*(volatile unsigned int *)(0xb0000000))
+
+ SKYEYE_MAGIC_ADDRESS = 0xff;
+#else
+ rtems_interrupt_level level;
+
+ (void) level;
+ rtems_interrupt_disable(level);
+
+ #ifdef __thumb__
+ int tmp;
+ __asm__ volatile (" .code 16 \n" \
+ "ldr %[tmp], =_start \n" \
+ "bx %[tmp] \n" \
+ "nop \n" \
+ : [tmp]"=&r" (tmp) );
+ #else
+ __asm__ volatile ("b _start");
+ #endif
+ while(1);
+#endif
+}
diff --git a/bsps/arm/rtl22xx/start/bspstart.c b/bsps/arm/rtl22xx/start/bspstart.c
new file mode 100644
index 0000000000..fa128d9054
--- /dev/null
+++ b/bsps/arm/rtl22xx/start/bspstart.c
@@ -0,0 +1,84 @@
+/*
+ * LPC22XX/LPC21xx Startup code
+ */
+
+/*
+ * Copyright (c) 2007 by Ray Xu <rayx.cn@gmail.com>
+ *
+ * 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/irq-generic.h>
+#include <lpc22xx.h>
+
+/*
+ * bsp_start_default - BSP initialization function
+ *
+ * This function is called before RTEMS is initialized and used
+ * adjust the kernel's configuration.
+ *
+ * This function also configures the CPU's memory protection unit.
+ *
+ * RESTRICTIONS/LIMITATIONS:
+ * Since RTEMS is not configured, no RTEMS functions can be called.
+ */
+static void bsp_start_default( void )
+{
+ PINSEL2 =0x0f814914;
+ BCFG0 = 0x1000ffef;
+ BCFG1 = 0x1000ffef;
+
+ MEMMAP = 0x2; //debug and excute outside chip
+
+ PLLCON = 1;
+ #if (Fpclk / (Fcclk / 4)) == 1
+ VPBDIV = 0;
+ #endif
+ #if (Fpclk / (Fcclk / 4)) == 2
+ VPBDIV = 2;
+ #endif
+ #if (Fpclk / (Fcclk / 4)) == 4
+ VPBDIV = 1;
+ #endif
+
+ #if (Fcco / Fcclk) == 2
+ PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5);
+ #endif
+ #if (Fcco / Fcclk) == 4
+ PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5);
+ #endif
+ #if (Fcco / Fcclk) == 8
+ PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5);
+ #endif
+ #if (Fcco / Fcclk) == 16
+ PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5);
+ #endif
+ PLLFEED = 0xaa;
+ PLLFEED = 0x55;
+ while((PLLSTAT & (1 << 10)) == 0);
+ PLLCON = 3;
+ PLLFEED = 0xaa;
+ PLLFEED = 0x55;
+
+ /* memory configure */
+ /* it is not needed in my formatter board */
+ //MAMCR = 0;
+ // MAMTIM = 3;
+ //MAMCR = 2;
+
+ UART0_Ini();
+
+ /*
+ * Init rtems interrupt management
+ */
+ bsp_interrupt_initialize();
+} /* bsp_start */
+
+/*
+ * By making this a weak alias for bsp_start_default, a brave soul
+ * can override the actual bsp_start routine used.
+ */
+void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
diff --git a/bsps/arm/rtl22xx/start/linkcmds b/bsps/arm/rtl22xx/start/linkcmds
new file mode 100644
index 0000000000..d39dcb12bd
--- /dev/null
+++ b/bsps/arm/rtl22xx/start/linkcmds
@@ -0,0 +1,24 @@
+MEMORY {
+ SDRAM : ORIGIN = 0x81000000, LENGTH = 512k
+ SRAM : ORIGIN = 0x40000000, LENGTH = 16k
+}
+
+REGION_ALIAS ("REGION_START", SDRAM);
+REGION_ALIAS ("REGION_VECTOR", SRAM);
+REGION_ALIAS ("REGION_TEXT", SDRAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_RODATA", SDRAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_DATA", SDRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_BSS", SDRAM);
+REGION_ALIAS ("REGION_WORK", SDRAM);
+REGION_ALIAS ("REGION_STACK", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", SDRAM);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/shared/start/bsp-start-in-hyp-support.S b/bsps/arm/shared/start/bsp-start-in-hyp-support.S
new file mode 100644
index 0000000000..b608c59fa8
--- /dev/null
+++ b/bsps/arm/shared/start/bsp-start-in-hyp-support.S
@@ -0,0 +1,77 @@
+/**
+ * @file
+ *
+ * @brief Boot and system start code.
+ */
+
+ /*
+ * Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ *
+ * Czech Technical University in Prague
+ * Zikova 1903/4
+ * 166 36 Praha 6
+ * Czech Republic
+ *
+ * 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/asm.h>
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+
+#include <bspopts.h>
+#include <bsp/irq.h>
+#include <bsp/linker-symbols.h>
+
+ .extern bsp_start_hyp_vector_table_begin
+ .globl bsp_start_arm_drop_hyp_mode
+ .globl bsp_arm_drop_hyp_mode_only
+
+.arm
+
+/*
+ * The routine is called from startup code and it should
+ * preserve all registers except r2 and r3. r0 can be used
+ * as pass though argument in some cases, a1 is used for
+ * CPU stack offset during startup and r4 to r6 to preserve
+ * booloader arguments
+ */
+
+bsp_start_arm_drop_hyp_mode:
+ ldr r2, bsp_start_hyp_vector_table_begin_addr
+ mcr p15, 4, r2, c12, c0, 0
+
+ mov r2, #0
+ mcr p15, 4, r2, c1, c1, 0
+ mcr p15, 4, r2, c1, c1, 2
+ mcr p15, 4, r2, c1, c1, 3
+/*
+ * HSCTLR.TE
+ * optional start of hypervisor handlers in Thumb mode
+ * orr r0, #(1 << 30)
+ */
+ mcr p15, 4, r2, c1, c0, 0 /* HSCTLR */
+ mrc p15, 4, r2, c1, c1, 1 /* HDCR */
+ and r2, #0x1f /* Preserve HPMN */
+ mcr p15, 4, r2, c1, c1, 1 /* HDCR */
+
+bsp_arm_drop_hyp_mode_only:
+ /* Prepare SVC mode for eret */
+ mrs r2, cpsr
+ bic r2, r2, #ARM_PSR_M_MASK
+ orr r2, r2, #ARM_PSR_M_SVC
+ msr spsr_cxsf, r2
+
+ adr r2, 1f
+ .inst 0xe12ef302 /* msr ELR_hyp, r2 */
+ mov r2, sp
+ mov r3, lr
+ .inst 0xe160006e /* eret */
+1: mov sp, r2
+ mov lr, r3
+ bx lr
+
+bsp_start_hyp_vector_table_begin_addr:
+ .word bsp_start_hyp_vector_table_begin
diff --git a/bsps/arm/shared/start/bsp-start-init-registers.S b/bsps/arm/shared/start/bsp-start-init-registers.S
new file mode 100644
index 0000000000..2e308ce5de
--- /dev/null
+++ b/bsps/arm/shared/start/bsp-start-init-registers.S
@@ -0,0 +1,105 @@
+/**
+ * @file bsp-start-init-registers.S
+ *
+ * @brief ARM register initialization routines.
+ */
+
+/*
+ * Copyright (c) 2015 Taller Technologies. All rights reserved.
+ *
+ * @author Martin Galvan <martin.galvan@tallertechnologies.com>
+ *
+ * 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.
+ */
+
+/*
+ * These routines initialize the core and VFP registers of ARM CPUs.
+ * This is necessary for boards that operate in a 1oo1D fashion,
+ * such as the TMS570.
+ */
+
+#include <rtems/asm.h>
+
+.section .text
+.syntax unified
+.cpu cortex-r4
+.arm
+
+/* Initialization of the ARM core registers. */
+FUNCTION_ENTRY(bsp_start_init_registers_core)
+ mov r0, #0
+ mov r1, #0
+ mov r2, #0
+ mov r3, #0
+ mov r4, #0
+ mov r5, #0
+ mov r6, #0
+ mov r7, #0
+ mov r8, #0
+ mov r9, #0
+ mov r10, #0
+ mov r11, #0
+ mov r12, #0
+ mov r13, #0
+
+ bx lr
+FUNCTION_END(bsp_start_init_registers_core)
+
+/* Initialization of the FIQ mode banked registers. */
+FUNCTION_ENTRY(bsp_start_init_registers_banked_fiq)
+ mov r8, #0
+ mov r9, #0
+ mov r10, #0
+ mov r11, #0
+ mov r12, #0
+
+ bx lr
+FUNCTION_END(bsp_start_init_registers_banked_fiq)
+
+#ifdef ARM_MULTILIB_VFP
+
+/* Initialization of the FPU registers. */
+FUNCTION_ENTRY(bsp_start_init_registers_vfp)
+ mov r0, #0
+ vmov d0, r0, r0
+ vmov d1, r0, r0
+ vmov d2, r0, r0
+ vmov d3, r0, r0
+ vmov d4, r0, r0
+ vmov d5, r0, r0
+ vmov d6, r0, r0
+ vmov d7, r0, r0
+ vmov d8, r0, r0
+ vmov d9, r0, r0
+ vmov d10, r0, r0
+ vmov d11, r0, r0
+ vmov d12, r0, r0
+ vmov d13, r0, r0
+ vmov d14, r0, r0
+ vmov d15, r0, r0
+
+#ifdef ARM_MULTILIB_VFP_D32
+ vmov d16, r0, r0
+ vmov d17, r0, r0
+ vmov d18, r0, r0
+ vmov d19, r0, r0
+ vmov d20, r0, r0
+ vmov d21, r0, r0
+ vmov d22, r0, r0
+ vmov d23, r0, r0
+ vmov d24, r0, r0
+ vmov d25, r0, r0
+ vmov d26, r0, r0
+ vmov d27, r0, r0
+ vmov d28, r0, r0
+ vmov d29, r0, r0
+ vmov d30, r0, r0
+ vmov d31, r0, r0
+#endif /* ARM_MULTILIB_VFP_D32 */
+
+ bx lr
+FUNCTION_END(bsp_start_init_registers_vfp)
+
+#endif /* ARM_MULTILIB_VFP */
diff --git a/bsps/arm/shared/start/bsp-start-memcpy.S b/bsps/arm/shared/start/bsp-start-memcpy.S
new file mode 100644
index 0000000000..cb97eb47f8
--- /dev/null
+++ b/bsps/arm/shared/start/bsp-start-memcpy.S
@@ -0,0 +1,147 @@
+/**
+ * @file
+ *
+ * @brief bsp_start_memcpy() implementation.
+ */
+
+/*
+ * Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/asm.h>
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+
+ .section ".bsp_start_text", "ax"
+
+#if defined(ARM_MULTILIB_ARCH_V4)
+
+DEFINE_FUNCTION_ARM(bsp_start_memcpy)
+
+ /* Return if dest == src */
+ cmp r0, r1
+#ifdef __thumb__
+ bxeq lr
+#else
+ moveq pc, lr
+#endif
+
+ /* Return if length is zero */
+ mov r3, #0
+ cmp r3, r2
+#ifdef __thumb__
+ bxeq lr
+#else
+ moveq pc, lr
+#endif
+
+ /* Save non-volatile registers */
+ push {r4-r8, lr}
+
+ /* Copy worker routine to stack */
+ adr ip, worker_begin
+ ldm ip, {r3-r8}
+ push {r3-r8}
+
+ /* Execute worker routine */
+ mov r3, #0
+ mov ip, sp
+ mov lr, pc
+#ifdef __thumb__
+ bx ip
+#else
+ mov pc, ip
+#endif
+
+ /* Restore stack and non-volatile registers */
+ add sp, sp, #24
+ pop {r4-r8, lr}
+
+ /* Return */
+#ifdef __thumb__
+ bx lr
+#else
+ mov pc, lr
+#endif
+
+worker_begin:
+
+ /* Worker routine */
+ ldr ip, [r1, r3]
+ str ip, [r0, r3]
+ add r3, r3, #4
+ cmp r3, r2
+ bcc worker_begin
+#ifdef __thumb__
+ bx lr
+#else
+ mov pc, lr
+#endif
+
+#elif defined(ARM_MULTILIB_ARCH_V7M)
+
+ .syntax unified
+
+ .align 2
+ .globl bsp_start_memcpy
+ .thumb
+ .thumb_func
+ .type bsp_start_memcpy, %function
+
+bsp_start_memcpy:
+
+ /* Return if dest == src */
+ cmp r0, r1
+ beq return
+
+ /* Return if length is zero */
+ movs r3, #0
+ cmp r3, r2
+ beq return
+
+ /* Save non-volatile registers */
+ push {r4-r7, lr}
+
+ /* Copy worker routine to stack */
+ adr r3, worker_begin
+ ldm r3, {r4-r7}
+ push {r4-r7}
+
+ /* Execute worker routine */
+ add r3, sp, #1
+ adds r2, r2, #3
+ bic r2, r2, #3
+ adds r2, r2, r1
+ blx r3
+
+ /* Restore stack and non-volatile registers */
+ add sp, sp, #16
+ pop {r4-r7, lr}
+
+return:
+
+ /* Return */
+ bx lr
+
+ .align 2
+
+worker_begin:
+
+ /* Worker routine */
+ ldr r3, [r1], #4
+ cmp r2, r1
+ str r3, [r0], #4
+ bne worker_begin
+ bx lr
+
+#endif /* defined(ARM_MULTILIB_ARCH_V7M) */
diff --git a/bsps/arm/shared/start/linkcmds.armv4 b/bsps/arm/shared/start/linkcmds.armv4
new file mode 100644
index 0000000000..33e419f5be
--- /dev/null
+++ b/bsps/arm/shared/start/linkcmds.armv4
@@ -0,0 +1,26 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief Linker command file for ARMv4T architecture.
+ */
+
+/*
+ * Copyright (c) 2010-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 1024;
+bsp_stack_irq_size = ALIGN (bsp_stack_irq_size, bsp_stack_align);
+
+INCLUDE linkcmds.base
diff --git a/bsps/arm/shared/start/linkcmds.armv7m b/bsps/arm/shared/start/linkcmds.armv7m
new file mode 100644
index 0000000000..f0fb2cde1f
--- /dev/null
+++ b/bsps/arm/shared/start/linkcmds.armv7m
@@ -0,0 +1,26 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief Linker command file for ARMv7 architecture.
+ */
+
+/*
+ * Copyright (c) 2010 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 4096;
+bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
+
+INCLUDE linkcmds.base
diff --git a/bsps/arm/shared/start/linkcmds.base b/bsps/arm/shared/start/linkcmds.base
new file mode 100644
index 0000000000..c6314547eb
--- /dev/null
+++ b/bsps/arm/shared/start/linkcmds.base
@@ -0,0 +1,487 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief Linker command base file.
+ */
+
+/*
+ * Copyright (c) 2008, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+
+OUTPUT_ARCH (arm)
+
+ENTRY (_start)
+STARTUP (start.o)
+
+/*
+ * Global symbols that may be defined externally
+ */
+
+bsp_vector_table_size = DEFINED (bsp_vector_table_size) ? bsp_vector_table_size : 64;
+
+bsp_section_xbarrier_align = DEFINED (bsp_section_xbarrier_align) ? bsp_section_xbarrier_align : 1;
+bsp_section_robarrier_align = DEFINED (bsp_section_robarrier_align) ? bsp_section_robarrier_align : 1;
+bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1;
+
+bsp_stack_align = DEFINED (bsp_stack_align) ? bsp_stack_align : 8;
+
+bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 0;
+bsp_stack_abt_size = ALIGN (bsp_stack_abt_size, bsp_stack_align);
+
+bsp_stack_fiq_size = DEFINED (bsp_stack_fiq_size) ? bsp_stack_fiq_size : 0;
+bsp_stack_fiq_size = ALIGN (bsp_stack_fiq_size, bsp_stack_align);
+
+bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 0;
+bsp_stack_irq_size = ALIGN (bsp_stack_irq_size, bsp_stack_align);
+
+bsp_stack_svc_size = DEFINED (bsp_stack_svc_size) ? bsp_stack_svc_size : 0;
+bsp_stack_svc_size = ALIGN (bsp_stack_svc_size, bsp_stack_align);
+
+bsp_stack_und_size = DEFINED (bsp_stack_und_size) ? bsp_stack_und_size : 0;
+bsp_stack_und_size = ALIGN (bsp_stack_und_size, bsp_stack_align);
+
+bsp_stack_hyp_size = DEFINED (bsp_stack_hyp_size) ? bsp_stack_hyp_size : 0;
+bsp_stack_hyp_size = ALIGN (bsp_stack_hyp_size, bsp_stack_align);
+
+bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 0;
+bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
+
+bsp_stack_all_size = bsp_stack_abt_size + bsp_stack_fiq_size + bsp_stack_irq_size + bsp_stack_svc_size + bsp_stack_und_size + bsp_stack_hyp_size + bsp_stack_main_size;
+
+bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 1;
+
+MEMORY {
+ UNEXPECTED_SECTIONS : ORIGIN = 0xffffffff, LENGTH = 0
+}
+
+SECTIONS {
+ .start : ALIGN_WITH_INPUT {
+ bsp_section_start_begin = .;
+ KEEP (*(.bsp_start_text))
+ KEEP (*(.bsp_start_data))
+ bsp_section_start_end = .;
+ } > REGION_START AT > REGION_START
+ bsp_section_start_size = bsp_section_start_end - bsp_section_start_begin;
+
+ .xbarrier : ALIGN_WITH_INPUT {
+ . = ALIGN (bsp_section_xbarrier_align);
+ } > REGION_VECTOR AT > REGION_VECTOR
+
+ .text : ALIGN_WITH_INPUT {
+ bsp_section_text_begin = .;
+ *(.text.unlikely .text.*_unlikely)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
+ } > REGION_TEXT AT > REGION_TEXT_LOAD
+ .init : ALIGN_WITH_INPUT {
+ KEEP (*(.init))
+ } > REGION_TEXT AT > REGION_TEXT_LOAD
+ .fini : ALIGN_WITH_INPUT {
+ KEEP (*(.fini))
+ bsp_section_text_end = .;
+ } > REGION_TEXT AT > REGION_TEXT_LOAD
+ bsp_section_text_size = bsp_section_text_end - bsp_section_text_begin;
+ bsp_section_text_load_begin = LOADADDR (.text);
+ bsp_section_text_load_end = bsp_section_text_load_begin + bsp_section_text_size;
+
+ .robarrier : ALIGN_WITH_INPUT {
+ . = ALIGN (bsp_section_robarrier_align);
+ } > REGION_RODATA AT > REGION_RODATA
+
+ .rodata : ALIGN_WITH_INPUT {
+ bsp_section_rodata_begin = .;
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .rodata1 : ALIGN_WITH_INPUT {
+ *(.rodata1)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .ARM.extab : ALIGN_WITH_INPUT {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .ARM.exidx : ALIGN_WITH_INPUT {
+ __exidx_start = .;
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ __exidx_end = .;
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .eh_frame : ALIGN_WITH_INPUT {
+ KEEP (*(.eh_frame))
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .gcc_except_table : ALIGN_WITH_INPUT {
+ *(.gcc_except_table .gcc_except_table.*)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .tdata : ALIGN_WITH_INPUT {
+ _TLS_Data_begin = .;
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ _TLS_Data_end = .;
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .tbss : ALIGN_WITH_INPUT {
+ _TLS_BSS_begin = .;
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ _TLS_BSS_end = .;
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ _TLS_Data_size = _TLS_Data_end - _TLS_Data_begin;
+ _TLS_Data_begin = _TLS_Data_size != 0 ? _TLS_Data_begin : _TLS_BSS_begin;
+ _TLS_Data_end = _TLS_Data_size != 0 ? _TLS_Data_end : _TLS_BSS_begin;
+ _TLS_BSS_size = _TLS_BSS_end - _TLS_BSS_begin;
+ _TLS_Size = _TLS_BSS_end - _TLS_Data_begin;
+ _TLS_Alignment = MAX (ALIGNOF (.tdata), ALIGNOF (.tbss));
+ .preinit_array : ALIGN_WITH_INPUT {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .init_array : ALIGN_WITH_INPUT {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .fini_array : ALIGN_WITH_INPUT {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .ctors : ALIGN_WITH_INPUT {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .dtors : ALIGN_WITH_INPUT {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .data.rel.ro : ALIGN_WITH_INPUT {
+ *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*)
+ *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .jcr : ALIGN_WITH_INPUT {
+ KEEP (*(.jcr))
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .interp : ALIGN_WITH_INPUT {
+ *(.interp)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .note.gnu.build-id : ALIGN_WITH_INPUT {
+ *(.note.gnu.build-id)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .hash : ALIGN_WITH_INPUT {
+ *(.hash)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .gnu.hash : ALIGN_WITH_INPUT {
+ *(.gnu.hash)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .dynsym : ALIGN_WITH_INPUT {
+ *(.dynsym)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .dynstr : ALIGN_WITH_INPUT {
+ *(.dynstr)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .gnu.version : ALIGN_WITH_INPUT {
+ *(.gnu.version)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .gnu.version_d : ALIGN_WITH_INPUT {
+ *(.gnu.version_d)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .gnu.version_r : ALIGN_WITH_INPUT {
+ *(.gnu.version_r)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .rel.dyn : ALIGN_WITH_INPUT {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ PROVIDE_HIDDEN (__rel_iplt_start = .);
+ *(.rel.iplt)
+ PROVIDE_HIDDEN (__rel_iplt_end = .);
+ PROVIDE_HIDDEN (__rela_iplt_start = .);
+ PROVIDE_HIDDEN (__rela_iplt_end = .);
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .rela.dyn : ALIGN_WITH_INPUT {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ *(.rela.rtemsroset*)
+ *(.rela.rtemsrwset*)
+ PROVIDE_HIDDEN (__rel_iplt_start = .);
+ PROVIDE_HIDDEN (__rel_iplt_end = .);
+ PROVIDE_HIDDEN (__rela_iplt_start = .);
+ *(.rela.iplt)
+ PROVIDE_HIDDEN (__rela_iplt_end = .);
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .rel.plt : ALIGN_WITH_INPUT {
+ *(.rel.plt)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .rela.plt : ALIGN_WITH_INPUT {
+ *(.rela.plt)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .plt : ALIGN_WITH_INPUT {
+ *(.plt)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .iplt : ALIGN_WITH_INPUT {
+ *(.iplt)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .dynamic : ALIGN_WITH_INPUT {
+ *(.dynamic)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .got : ALIGN_WITH_INPUT {
+ *(.got.plt) *(.igot.plt) *(.got) *(.igot)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .rtemsroset : ALIGN_WITH_INPUT {
+ /* Special FreeBSD linker set sections */
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = .;
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ KEEP (*(SORT(.rtemsroset.*)))
+ bsp_section_rodata_end = .;
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ bsp_section_rodata_size = bsp_section_rodata_end - bsp_section_rodata_begin;
+ bsp_section_rodata_load_begin = LOADADDR (.rodata);
+ bsp_section_rodata_load_end = bsp_section_rodata_load_begin + bsp_section_rodata_size;
+
+ .rwbarrier : ALIGN_WITH_INPUT {
+ . = ALIGN (bsp_section_rwbarrier_align);
+ } > REGION_DATA AT > REGION_DATA
+
+ .vector : ALIGN_WITH_INPUT {
+ bsp_section_vector_begin = .;
+
+ . = . + DEFINED (bsp_vector_table_in_start_section) ? 0 : bsp_vector_table_size;
+
+ . = ALIGN (bsp_stack_align);
+
+ bsp_stack_irq_begin = .;
+ . = . + bsp_stack_irq_size;
+ bsp_stack_irq_end = .;
+
+ bsp_stack_svc_begin = .;
+ . = . + bsp_stack_svc_size;
+ bsp_stack_svc_end = .;
+
+ bsp_stack_fiq_begin = .;
+ . = . + bsp_stack_fiq_size;
+ bsp_stack_fiq_end = .;
+
+ bsp_stack_und_begin = .;
+ . = . + bsp_stack_und_size;
+ bsp_stack_und_end = .;
+
+ bsp_stack_hyp_begin = .;
+ . = . + bsp_stack_hyp_size;
+ bsp_stack_hyp_end = .;
+
+ bsp_stack_abt_begin = .;
+ . = . + bsp_stack_abt_size;
+ bsp_stack_abt_end = .;
+
+ bsp_stack_main_begin = .;
+ . = . + bsp_stack_main_size;
+ bsp_stack_main_end = .;
+
+ bsp_stack_secondary_processors_begin = .;
+ . = . + (bsp_processor_count - 1) * bsp_stack_all_size;
+ bsp_stack_secondary_processors_end = .;
+
+ *(.bsp_vector)
+ bsp_section_vector_end = .;
+ } > REGION_VECTOR AT > REGION_VECTOR
+ bsp_section_vector_size = bsp_section_vector_end - bsp_section_vector_begin;
+ bsp_vector_table_begin = DEFINED (bsp_vector_table_in_start_section) ? bsp_section_start_begin : bsp_section_vector_begin;
+ bsp_vector_table_end = bsp_vector_table_begin + bsp_vector_table_size;
+
+ .fast_text : ALIGN_WITH_INPUT {
+ bsp_section_fast_text_begin = .;
+ *(.bsp_fast_text)
+ bsp_section_fast_text_end = .;
+ } > REGION_FAST_TEXT AT > REGION_FAST_TEXT_LOAD
+ bsp_section_fast_text_size = bsp_section_fast_text_end - bsp_section_fast_text_begin;
+ bsp_section_fast_text_load_begin = LOADADDR (.fast_text);
+ bsp_section_fast_text_load_end = bsp_section_fast_text_load_begin + bsp_section_fast_text_size;
+
+ .fast_data : ALIGN_WITH_INPUT {
+ bsp_section_fast_data_begin = .;
+ *(.bsp_fast_data)
+ bsp_section_fast_data_end = .;
+ } > REGION_FAST_DATA AT > REGION_FAST_DATA_LOAD
+ bsp_section_fast_data_size = bsp_section_fast_data_end - bsp_section_fast_data_begin;
+ bsp_section_fast_data_load_begin = LOADADDR (.fast_data);
+ bsp_section_fast_data_load_end = bsp_section_fast_data_load_begin + bsp_section_fast_data_size;
+
+ .data : ALIGN_WITH_INPUT {
+ bsp_section_data_begin = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ SORT(CONSTRUCTORS)
+ } > REGION_DATA AT > REGION_DATA_LOAD
+ .data1 : ALIGN_WITH_INPUT {
+ *(.data1)
+ } > REGION_DATA AT > REGION_DATA_LOAD
+ .rtemsrwset : ALIGN_WITH_INPUT {
+ KEEP (*(SORT(.rtemsrwset.*)))
+ bsp_section_data_end = .;
+ } > REGION_DATA AT > REGION_DATA_LOAD
+ bsp_section_data_size = bsp_section_data_end - bsp_section_data_begin;
+ bsp_section_data_load_begin = LOADADDR (.data);
+ bsp_section_data_load_end = bsp_section_data_load_begin + bsp_section_data_size;
+
+ .bss : ALIGN_WITH_INPUT {
+ bsp_section_bss_begin = .;
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ bsp_section_bss_end = .;
+ } > REGION_BSS AT > REGION_BSS
+ bsp_section_bss_size = bsp_section_bss_end - bsp_section_bss_begin;
+
+ .work : ALIGN_WITH_INPUT {
+ /*
+ * The work section will occupy the remaining REGION_WORK region and
+ * contains the RTEMS work space and heap.
+ */
+ bsp_section_work_begin = .;
+ . += ORIGIN (REGION_WORK) + LENGTH (REGION_WORK) - ABSOLUTE (.);
+ bsp_section_work_end = .;
+ } > REGION_WORK AT > REGION_WORK
+ bsp_section_work_size = bsp_section_work_end - bsp_section_work_begin;
+
+ .stack : ALIGN_WITH_INPUT {
+ /*
+ * The stack section will occupy the remaining REGION_STACK region and may
+ * contain the task stacks. Depending on the region distribution this
+ * section may be of zero size.
+ */
+ bsp_section_stack_begin = .;
+ . += ORIGIN (REGION_STACK) + LENGTH (REGION_STACK) - ABSOLUTE (.);
+ bsp_section_stack_end = .;
+ } > REGION_STACK AT > REGION_STACK
+ bsp_section_stack_size = bsp_section_stack_end - bsp_section_stack_begin;
+
+ .nocache : ALIGN_WITH_INPUT {
+ bsp_section_nocache_begin = .;
+ *(SORT_BY_ALIGNMENT (SORT_BY_NAME (.bsp_nocache*)))
+ bsp_section_nocache_end = .;
+ } > REGION_NOCACHE AT > REGION_NOCACHE_LOAD
+ 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;
+
+ .nocachenoload (NOLOAD) : ALIGN_WITH_INPUT {
+ bsp_section_nocachenoload_begin = .;
+ *(SORT_BY_ALIGNMENT (SORT_BY_NAME (.bsp_noload_nocache*)))
+ bsp_section_nocacheheap_begin = .;
+ . += ORIGIN (REGION_NOCACHE) + LENGTH (REGION_NOCACHE) - ABSOLUTE (.);
+ bsp_section_nocacheheap_end = .;
+ bsp_section_nocachenoload_end = .;
+ } > REGION_NOCACHE AT > REGION_NOCACHE
+ bsp_section_nocacheheap_size = bsp_section_nocacheheap_end - bsp_section_nocacheheap_begin;
+ bsp_section_nocachenoload_size = bsp_section_nocachenoload_end - bsp_section_nocachenoload_begin;
+
+ /* FIXME */
+ RamBase = ORIGIN (REGION_WORK);
+ RamSize = LENGTH (REGION_WORK);
+ WorkAreaBase = bsp_section_work_begin;
+ HeapSize = 0;
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ /* DWARF extension */
+ .debug_macro 0 : { *(.debug_macro) }
+ .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+
+ /*
+ * This is a RTEMS specific section to catch all unexpected input
+ * sections. In case you get an error like
+ * "section `.unexpected_sections' will not fit in region
+ * `UNEXPECTED_SECTIONS'"
+ * you have to figure out the offending input section and add it to the
+ * appropriate output section definition above.
+ */
+ .unexpected_sections : { *(*) } > UNEXPECTED_SECTIONS
+}
diff --git a/bsps/arm/smdk2410/start/bsp_specs b/bsps/arm/smdk2410/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/smdk2410/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/smdk2410/start/bspidle.c b/bsps/arm/smdk2410/start/bspidle.c
new file mode 100644
index 0000000000..0f96f1f09b
--- /dev/null
+++ b/bsps/arm/smdk2410/start/bspidle.c
@@ -0,0 +1,23 @@
+/*
+ * BSP specific Idle thread
+ */
+
+/*
+ * Copyright (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * 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>
+
+void *bsp_idle_thread(uintptr_t ignored)
+{
+ while(1) {
+ __asm__ volatile ("MCR p15,0,r0,c7,c0,4 \n");
+ }
+ return NULL;
+}
+
diff --git a/bsps/arm/smdk2410/start/bspreset.c b/bsps/arm/smdk2410/start/bspreset.c
new file mode 100644
index 0000000000..365a22f14f
--- /dev/null
+++ b/bsps/arm/smdk2410/start/bspreset.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+
+void bsp_reset(void)
+{
+#if ON_SKYEYE == 1
+ #define SKYEYE_MAGIC_ADDRESS (*(volatile unsigned int *)(0xb0000000))
+
+ SKYEYE_MAGIC_ADDRESS = 0xff;
+#else
+ /* TODO: This code was initially copied from the gp32 BSP. That BSP has
+ * been obsoleted and removed but this code may still benefit from being
+ * in a shared place.
+ */
+ rtems_interrupt_level level;
+
+ (void) level;
+ rtems_interrupt_disable(level);
+ /* disable mmu, invalide i-cache and call swi #4 */
+ __asm__ volatile(""
+ "mrc p15,0,r0,c1,c0,0 \n"
+ "bic r0,r0,#1 \n"
+ "mcr p15,0,r0,c1,c0,0 \n"
+ "nop \n"
+ "nop \n"
+ "nop \n"
+ "nop \n"
+ "nop \n"
+ "mov r0,#0 \n"
+ "MCR p15,0,r0,c7,c5,0 \n"
+ "nop \n"
+ "nop \n"
+ "nop \n"
+ "nop \n"
+ "nop \n"
+ "swi #4 "
+ :
+ :
+ : "r0"
+ );
+ /* we should be back in bios now */
+#endif
+}
diff --git a/bsps/arm/smdk2410/start/bspstart.c b/bsps/arm/smdk2410/start/bspstart.c
new file mode 100644
index 0000000000..c70de1f291
--- /dev/null
+++ b/bsps/arm/smdk2410/start/bspstart.c
@@ -0,0 +1,83 @@
+/*
+ * This file contains the ARM BSP startup package. It includes application,
+ * board, and monitor specific initialization and configuration. The generic CPU
+ * dependent initialization has been performed before this routine is invoked.
+ */
+
+/*
+ * Copyright (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * 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/irq-generic.h>
+#include <rtems/bspIo.h>
+#include <s3c24xx.h>
+
+/*
+ * BSP Specific Initialization in C
+ */
+static void bsp_start_default( void )
+{
+ uint32_t cr;
+ uint32_t pend,last;
+ uint32_t REFCNT;
+ int i;
+
+ /* stop RTC */
+ #ifdef CPU_S3C2400
+ rTICINT = 0x0;
+ #else
+ rTICNT = 0x0;
+ #endif
+ /* stop watchdog,ADC and timers */
+ rWTCON = 0x0;
+ rTCON = 0x0;
+ rADCCON = 0x0;
+
+ /* disable interrupts */
+ rINTMOD = 0x0;
+ rINTMSK = BIT_ALLMSK; /* unmasked by drivers */
+
+ last = 0;
+ for(i=0; i<4; i++) {
+ pend = rSRCPND;
+ if(pend == 0 || pend == last)
+ break;
+ rSRCPND = pend;
+ rINTPND = pend;
+ last = pend;
+ }
+
+ /* setup clocks */
+ rCLKDIVN = M_CLKDIVN;
+ rMPLLCON = ((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV);
+ /* setup rREFRESH
+ * period = 15.6 us, HCLK=66Mhz, (2048+1-15.6*66)
+ */
+ REFCNT = 2048+1-(15.6*get_HCLK()/1000000);
+ rREFRESH = ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT);
+
+ /* set prescaler for timers 2,3,4 to 16(15+1) */
+ cr = rTCFG0 & 0xFFFF00FF;
+ rTCFG0 = (cr | (15<<8));
+
+ /* set prescaler for timers 0,1 to 1(0+1) */
+ cr = rTCFG0 & 0xFFFFFF00;
+ rTCFG0 = (cr | (0<<0));
+
+ /*
+ * Init rtems interrupt management
+ */
+ bsp_interrupt_initialize();
+}
+
+/*
+ * By making this a weak alias for bsp_start_default, a brave soul
+ * can override the actual bsp_start routine used.
+ */
+void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
diff --git a/bsps/arm/smdk2410/start/linkcmds b/bsps/arm/smdk2410/start/linkcmds
new file mode 100644
index 0000000000..9cd68886a7
--- /dev/null
+++ b/bsps/arm/smdk2410/start/linkcmds
@@ -0,0 +1,26 @@
+MEMORY {
+ SDRAM_MMU : ORIGIN = 0x30000000, LENGTH = 16k
+ SDRAM : ORIGIN = 0x30004000, LENGTH = 64M - 16k
+}
+
+REGION_ALIAS ("REGION_START", SDRAM);
+REGION_ALIAS ("REGION_VECTOR", SDRAM);
+REGION_ALIAS ("REGION_TEXT", SDRAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_RODATA", SDRAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_DATA", SDRAM);
+REGION_ALIAS ("REGION_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT", SDRAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA", SDRAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", SDRAM);
+REGION_ALIAS ("REGION_BSS", SDRAM);
+REGION_ALIAS ("REGION_WORK", SDRAM);
+REGION_ALIAS ("REGION_STACK", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE", SDRAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", SDRAM);
+
+_ttbl_base = ORIGIN (SDRAM_MMU);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/smdk2410/start/memmap.c b/bsps/arm/smdk2410/start/memmap.c
new file mode 100644
index 0000000000..21ba35b21b
--- /dev/null
+++ b/bsps/arm/smdk2410/start/memmap.c
@@ -0,0 +1,27 @@
+/*
+ * SMDK2410 Memory Map
+ */
+
+/*
+ * Copyright (c) 2004 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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 <libcpu/mmu.h>
+
+/* Remember, the ARM920 has 64 TLBs. If you have more 1MB sections than
+ * that, you'll have TLB lookups, which could hurt performance.
+ */
+mmu_sect_map_t mem_map[] = {
+/* <phys addr> <virt addr> <size> <flags> */
+ {0x30000000, 0x00000000, 1, MMU_CACHE_NONE}, /* SDRAM for vectors */
+ {0x30000000, 0x30000000, 32, MMU_CACHE_WTHROUGH}, /* SDRAM W cache */
+ {0x32000000, 0x32000000, 32, MMU_CACHE_NONE}, /* SDRAM W/O cache */
+ {0x48000000, 0x48000000, 256, MMU_CACHE_NONE}, /* Internals Regs - */
+ {0x50000000, 0x50000000, 256, MMU_CACHE_NONE}, /* Internal Regs - */
+ {0x00000000, 0x00000000, 0, 0} /* The end */
+};
diff --git a/bsps/arm/stm32f4/start/bsp_specs b/bsps/arm/stm32f4/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/stm32f4/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/stm32f4/start/bspreset.c b/bsps/arm/stm32f4/start/bspreset.c
new file mode 100644
index 0000000000..ff46d4f86b
--- /dev/null
+++ b/bsps/arm/stm32f4/start/bspreset.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+
+#include <bsp/bootcard.h>
+
+void bsp_reset(void)
+{
+ rtems_interrupt_level level;
+
+ (void) level;
+ rtems_interrupt_disable(level);
+
+ while (1);
+}
diff --git a/bsps/arm/stm32f4/start/bspstart.c b/bsps/arm/stm32f4/start/bspstart.c
new file mode 100644
index 0000000000..8d4bf6b82b
--- /dev/null
+++ b/bsps/arm/stm32f4/start/bspstart.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/io.h>
+#include <bsp/irq.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+#include <assert.h>
+#include <bsp/stm32f4.h>
+
+#ifdef STM32F4_FAMILY_F4XXXX
+
+#include <bsp/stm32f4xxxx_rcc.h>
+#include <bsp/stm32f4xxxx_flash.h>
+
+static rtems_status_code set_system_clk(
+ uint32_t sys_clk,
+ uint32_t hse_clk,
+ uint32_t hse_flag
+);
+
+static void init_main_osc( void )
+{
+ volatile stm32f4_rcc *rcc = STM32F4_RCC;
+ rtems_status_code status;
+
+ /* Revert to reset values */
+ rcc->cr |= RCC_CR_HSION; /* turn on HSI */
+
+ while ( !( rcc->cr & RCC_CR_HSIRDY ) ) ;
+
+ rcc->cfgr &= 0x00000300; /* all prescalers to 0, clock source to HSI */
+
+ rcc->cr &= 0xF0F0FFFD; /* turn off all clocks and PLL except HSI */
+
+ status = set_system_clk( STM32F4_SYSCLK / 1000000L,
+ STM32F4_HSE_OSCILLATOR / 1000000L,
+ 1 );
+
+ assert( rtems_is_status_successful( status ) );
+}
+
+/**
+ * @brief Sets up clocks configuration.
+ *
+ * Set up clocks configuration to achieve desired system clock
+ * as close as possible with simple math.
+ *
+ * Limitations:
+ * It is assumed that 1MHz resolution is enough.
+ * Best fits for the clocks are achieved with multiplies of 42MHz.
+ * Even though APB1, APB2 and AHB are calculated user is still required
+ * to provide correct values for the bsp configuration for the:
+ * STM32F4_PCLK1
+ * STM32F4_PCLK2
+ * STM32F4_HCLK
+ * as those are used for the peripheral clocking calculations.
+ *
+ * @param sys_clk Desired system clock in MHz.
+ * @param hse_clk External clock speed in MHz.
+ * @param hse_flag Flag determining which clock source to use, 1 for HSE,
+ * 0 for HSI.
+ *
+ * @retval RTEMS_SUCCESSFUL Configuration has been succesfully aplied for the
+ * requested clock speed.
+ * @retval RTEMS_TIMEOUT HSE clock didn't start or PLL didn't lock.
+ * @retval RTEMS_INVALID_NUMBER Requested clock speed is out of range.
+ */
+static rtems_status_code set_system_clk(
+ uint32_t sys_clk,
+ uint32_t hse_clk,
+ uint32_t hse_flag
+)
+{
+ volatile stm32f4_rcc *rcc = STM32F4_RCC;
+ volatile stm32f4_flash *flash = STM32F4_FLASH;
+ long timeout = 0;
+
+ int src_clk = 0;
+
+ uint32_t pll_m = 0;
+ uint32_t pll_n = 0;
+ uint32_t pll_p = 0;
+ uint32_t pll_q = 0;
+
+ uint32_t ahbpre = 0;
+ uint32_t apbpre1 = 0;
+ uint32_t apbpre2 = 0;
+
+ if ( sys_clk == 16 && hse_clk != 16 ) {
+ /* Revert to reset values */
+ rcc->cr |= RCC_CR_HSION; /* turn on HSI */
+
+ while ( !( rcc->cr & RCC_CR_HSIRDY ) ) ;
+
+ /* all prescalers to 0, clock source to HSI */
+ rcc->cfgr &= 0x00000300 | RCC_CFGR_SW_HSI;
+ rcc->cr &= 0xF0F0FFFD; /* turn off all clocks and PLL except HSI */
+ flash->acr = 0; /* slow clock so no cache, no prefetch, no latency */
+
+ return RTEMS_SUCCESSFUL;
+ }
+
+ if ( sys_clk == hse_clk ) {
+ /* Revert to reset values */
+ rcc->cr |= RCC_CR_HSEON; /* turn on HSE */
+ timeout = 400;
+
+ while ( !( rcc->cr & RCC_CR_HSERDY ) && --timeout ) ;
+
+ assert( timeout != 0 );
+
+ if ( timeout == 0 ) {
+ return RTEMS_TIMEOUT;
+ }
+
+ /* all prescalers to 0, clock source to HSE */
+ rcc->cfgr &= 0x00000300;
+ rcc->cfgr |= RCC_CFGR_SW_HSE;
+ /* turn off all clocks and PLL except HSE */
+ rcc->cr &= 0xF0F0FFFC | RCC_CR_HSEON;
+ flash->acr = 0; /* slow clock so no cache, no prefetch, no latency */
+
+ return RTEMS_SUCCESSFUL;
+ }
+
+ /*
+ * Lets use 1MHz input for PLL so we get higher VCO output
+ * this way we get better value for the PLL_Q divader for the USB
+ *
+ * Though you might want to use 2MHz as per CPU specification:
+ *
+ * Caution:The software has to set these bits correctly to ensure
+ * that the VCO input frequency ranges from 1 to 2 MHz.
+ * It is recommended to select a frequency of 2 MHz to limit PLL jitter.
+ */
+
+ if ( sys_clk > 180 ) {
+ return RTEMS_INVALID_NUMBER;
+ } else if ( sys_clk >= 96 ) {
+ pll_n = sys_clk << 1;
+ pll_p = RCC_PLLCFGR_PLLP_BY_2;
+ } else if ( sys_clk >= 48 ) {
+ pll_n = sys_clk << 2;
+ pll_p = RCC_PLLCFGR_PLLP_BY_4;
+ } else if ( sys_clk >= 24 ) {
+ pll_n = sys_clk << 3;
+ pll_p = RCC_PLLCFGR_PLLP_BY_8;
+ } else {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ if ( hse_clk == 0 || hse_flag == 0 ) {
+ src_clk = 16;
+ hse_flag = 0;
+ } else {
+ src_clk = hse_clk;
+ }
+
+ pll_m = src_clk; /* divide by the oscilator speed in MHz */
+
+ /* pll_q is a prescaler from VCO for the USB OTG FS, SDIO and RNG,
+ * best if results in the 48MHz for the USB
+ */
+ pll_q = ( (long) ( src_clk * pll_n ) ) / pll_m / 48;
+
+ if ( pll_q < 2 ) {
+ pll_q = 2;
+ }
+
+ /* APB1 prescaler, APB1 clock must be < 42MHz */
+ apbpre1 = ( sys_clk * 100 ) / 42;
+
+ if ( apbpre1 <= 100 ) {
+ apbpre1 = RCC_CFGR_PPRE1_BY_1;
+ } else if ( apbpre1 <= 200 ) {
+ apbpre1 = RCC_CFGR_PPRE1_BY_2;
+ } else if ( apbpre1 <= 400 ) {
+ apbpre1 = RCC_CFGR_PPRE1_BY_4;
+ } else if ( apbpre1 <= 800 ) {
+ apbpre1 = RCC_CFGR_PPRE1_BY_8;
+ } else if ( apbpre1 ) {
+ apbpre1 = RCC_CFGR_PPRE1_BY_16;
+ }
+
+ /* APB2 prescaler, APB2 clock must be < 84MHz */
+ apbpre2 = ( sys_clk * 100 ) / 84;
+
+ if ( apbpre2 <= 100 ) {
+ apbpre2 = RCC_CFGR_PPRE2_BY_1;
+ } else if ( apbpre2 <= 200 ) {
+ apbpre2 = RCC_CFGR_PPRE2_BY_2;
+ } else if ( apbpre2 <= 400 ) {
+ apbpre2 = RCC_CFGR_PPRE2_BY_4;
+ } else if ( apbpre2 <= 800 ) {
+ apbpre2 = RCC_CFGR_PPRE2_BY_8;
+ } else {
+ apbpre2 = RCC_CFGR_PPRE2_BY_16;
+ }
+
+ rcc->cr |= RCC_CR_HSION; /* turn on HSI */
+
+ while ( ( !( rcc->cr & RCC_CR_HSIRDY ) ) ) ;
+
+ /* all prescalers to 0, clock source to HSI */
+ rcc->cfgr &= 0x00000300;
+ rcc->cfgr |= RCC_CFGR_SW_HSI;
+
+ while ( ( ( rcc->cfgr & RCC_CFGR_SWS_MSK ) != RCC_CFGR_SWS_HSI ) ) ;
+
+ /* turn off PLL */
+ rcc->cr &= ~( RCC_CR_PLLON | RCC_CR_PLLRDY );
+
+ /* turn on HSE */
+ if ( hse_flag ) {
+ rcc->cr |= RCC_CR_HSEON;
+ timeout = 400;
+
+ while ( ( !( rcc->cr & RCC_CR_HSERDY ) ) && timeout-- ) ;
+
+ assert( timeout != 0 );
+
+ if ( timeout == 0 ) {
+ return RTEMS_TIMEOUT;
+ }
+ }
+
+ rcc->pllcfgr &= 0xF0BC8000; /* clear PLL prescalers */
+
+ /* set pll parameters */
+ rcc->pllcfgr |= RCC_PLLCFGR_PLLM( pll_m ) | /* input divider */
+ RCC_PLLCFGR_PLLN( pll_n ) | /* multiplier */
+ pll_p | /* output divider from table */
+ /* HSE v HSI */
+ ( hse_flag ? RCC_PLLCFGR_PLLSRC_HSE : RCC_PLLCFGR_PLLSRC_HSI )
+ |
+ RCC_PLLCFGR_PLLQ( pll_q ); /* PLLQ divider */
+
+ /* set prescalers for the internal busses */
+ rcc->cfgr |= apbpre1 |
+ apbpre2 |
+ ahbpre;
+
+ /*
+ * Set flash parameters, hard coded for now for fast system clocks.
+ * TODO implement some math to use flash on as low latancy as possible
+ */
+ flash->acr = STM32F4_FLASH_ACR_LATENCY( 5 ) | /* latency */
+ STM32F4_FLASH_ACR_ICEN | /* instruction cache */
+ STM32F4_FLASH_ACR_DCEN | /* data cache */
+ STM32F4_FLASH_ACR_PRFTEN;
+
+ /* turn on PLL */
+ rcc->cr |= RCC_CR_PLLON;
+ timeout = 40000;
+
+ while ( ( !( rcc->cr & RCC_CR_PLLRDY ) ) && --timeout ) ;
+
+ assert( timeout != 0 );
+
+ if ( timeout == 0 ) {
+ return RTEMS_TIMEOUT;
+ }
+
+ /* clock source to PLL */
+ rcc->cfgr = ( rcc->cfgr & ~RCC_CFGR_SW_MSK ) | RCC_CFGR_SW_PLL;
+
+ while ( ( ( rcc->cfgr & RCC_CFGR_SWS_MSK ) != RCC_CFGR_SWS_PLL ) ) ;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+#endif /* STM32F4_FAMILY_F4XXXX */
+
+#ifdef STM32F4_FAMILY_F10XXX
+
+static void init_main_osc( void )
+{
+
+}
+
+#endif /* STM32F4_FAMILY_F10XXX */
+
+void bsp_start( void )
+{
+ init_main_osc();
+
+ stm32f4_gpio_set_config_array( &stm32f4_start_config_gpio[ 0 ] );
+
+ bsp_interrupt_initialize();
+}
diff --git a/bsps/arm/stm32f4/start/bspstarthook.c b/bsps/arm/stm32f4/start/bspstarthook.c
new file mode 100644
index 0000000000..8e9295b853
--- /dev/null
+++ b/bsps/arm/stm32f4/start/bspstarthook.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/start.h>
+
+void BSP_START_TEXT_SECTION bsp_start_hook_0(void)
+{
+ /* Do nothing */
+}
+
+void BSP_START_TEXT_SECTION bsp_start_hook_1(void)
+{
+ bsp_start_copy_sections();
+ bsp_start_clear_bss();
+
+ /* At this point we can use objects outside the .start section */
+}
diff --git a/bsps/arm/stm32f4/start/io.c b/bsps/arm/stm32f4/start/io.c
new file mode 100644
index 0000000000..dcbdb70ff5
--- /dev/null
+++ b/bsps/arm/stm32f4/start/io.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/io.h>
+#include <bsp/rcc.h>
+#include <bsp/stm32f4.h>
+
+#include <rtems.h>
+
+RTEMS_STATIC_ASSERT(sizeof(stm32f4_gpio_config) == 4, size_of_config);
+
+void stm32f4_gpio_set_clock(int pin, bool set)
+{
+ int port = STM32F4_GPIO_PORT_OF_PIN(pin);
+ stm32f4_rcc_index index = STM32F4_RCC_GPIOA + port;
+
+ stm32f4_rcc_set_clock(index, set);
+}
+
+static void clear_and_set(
+ volatile uint32_t *reg,
+ unsigned index,
+ unsigned width,
+ uint32_t set
+)
+{
+ uint32_t mask = (1U << width) - 1U;
+ unsigned shift = width * index;
+ uint32_t val = *reg;
+
+ val &= ~(mask << shift);
+ val |= set << shift;
+
+ *reg = val;
+}
+
+#ifdef STM32F4_FAMILY_F10XXX
+#define STM32F4_AFIO_REMAP_ENTRY(mod, afio_reg_v, start_v, width_v, value_v) \
+ [mod] = { \
+ .afio_reg = afio_reg_v, \
+ .start = start_v, \
+ .width = width_v, \
+ .value = value_v, \
+ .reserved = 0 \
+ }
+
+typedef struct {
+ uint16_t afio_reg : 3;
+ uint16_t start : 5;
+ uint16_t width : 2;
+ uint16_t value : 3;
+ uint16_t reserved : 3;
+} stm32f4_afio_remap_entry;
+
+static const stm32f4_afio_remap_entry stm32f4_afio_remap_table [] = {
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_DONT_CHANGE, 0, 0, 0, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_SPI1_0, 1, 0, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_SPI1_1, 1, 0, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_I2C1_0, 1, 1, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_I2C1_1, 1, 1, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_USART1_0, 1, 2, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_USART1_1, 1, 2, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_USART2_0, 1, 3, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_USART2_1, 1, 3, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_USART3_0, 1, 4, 2, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_USART3_1, 1, 4, 2, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_USART3_3, 1, 4, 2, 3),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM1_0, 1, 6, 2, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM1_1, 1, 6, 2, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM1_3, 1, 6, 2, 3),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM2_0, 1, 8, 2, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM2_1, 1, 8, 2, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM2_2, 1, 8, 2, 2),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM2_3, 1, 8, 2, 3),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM3_0, 1, 10, 2, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM3_2, 1, 10, 2, 2),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM3_3, 1, 10, 2, 3),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM4_0, 1, 12, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM4_1, 1, 12, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_CAN1_0, 1, 13, 2, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_CAN1_2, 1, 13, 2, 2),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_CAN1_3, 1, 13, 2, 3),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_PD01_0, 1, 15, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_PD01_1, 1, 15, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM5CH4_0, 1, 16, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM5CH4_1, 1, 16, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ADC1_ETRGINJ_0, 1, 17, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ADC1_ETRGINJ_1, 1, 17, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ADC1_ETRGREG_0, 1, 18, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ADC1_ETRGREG_1, 1, 18, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ADC2_ETRGINJ_0, 1, 19, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ADC2_ETRGINJ_1, 1, 19, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ADC2_ETRGREG_0, 1, 20, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ADC2_ETRGREG_1, 1, 20, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ETH_0, 1, 21, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_ETH_1, 1, 21, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_CAN2_0, 1, 22, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_CAN2_1, 1, 22, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_MII_RMII_0, 1, 23, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_MII_RMII_1, 1, 23, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_SWJ_0, 1, 24, 3, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_SWJ_1, 1, 24, 3, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_SWJ_2, 1, 24, 3, 2),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_SWJ_4, 1, 24, 3, 4),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_SPI3_0, 1, 28, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_SPI3_1, 1, 28, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM2ITR1_0, 1, 29, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM2ITR1_1, 1, 29, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_PTP_PPS_0, 1, 30, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_PTP_PPS_1, 1, 30, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM15_0, 6, 0, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM15_1, 6, 0, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM16_0, 6, 1, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM16_1, 6, 1, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM17_0, 6, 2, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM17_1, 6, 2, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_CEC_0, 6, 3, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_CEC_1, 6, 3, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM1_DMA_0, 6, 4, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM1_DMA_1, 6, 4, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM9_0, 6, 5, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM9_1, 6, 5, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM10_0, 6, 6, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM10_1, 6, 6, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM11_0, 6, 7, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM11_1, 6, 7, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM13_0, 6, 8, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM13_1, 6, 8, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM14_0, 6, 9, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM14_1, 6, 9, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_FSMC_0, 6, 10, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_FSMC_1, 6, 10, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM67_DAC_DMA_0, 6, 11, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM67_DAC_DMA_1, 6, 11, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM12_0, 6, 12, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_TIM12_1, 6, 12, 1, 1),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_MISC_0, 6, 13, 1, 0),
+ STM32F4_AFIO_REMAP_ENTRY(STM32F4_GPIO_REMAP_MISC_1, 6, 13, 1, 1),
+};
+
+static void set_remap_config(stm32f4_gpio_remap remap)
+{
+ if(remap != STM32F4_GPIO_REMAP_DONT_CHANGE)
+ {
+ stm32f4_afio_remap_entry entry = stm32f4_afio_remap_table[remap];
+ volatile stm32f4_afio *afio = STM32F4_AFIO;
+ volatile uint32_t *reg = ((uint32_t*) afio) + entry.afio_reg;
+ uint32_t mask = (1 << entry.width) - 1;
+ uint32_t value = *reg;
+
+ value &= mask << entry.start;
+ value |= entry.value << entry.start;
+
+ *reg = value;
+ }
+}
+
+#endif /* STM32F4_FAMILY_F10XXX */
+
+static void set_config(unsigned pin, const stm32f4_gpio_config *config)
+{
+ unsigned port = STM32F4_GPIO_PORT_OF_PIN(pin);
+ volatile stm32f4_gpio *gpio = STM32F4_GPIO(port);
+ unsigned index = STM32F4_GPIO_INDEX_OF_PIN(pin);
+ rtems_interrupt_level level;
+ int set_or_clear_offset = config->fields.output ? 0 : 16;
+#ifdef STM32F4_FAMILY_F4XXXX
+ unsigned af_reg = index >> 3;
+ unsigned af_index = index & 0x7;
+
+ rtems_interrupt_disable(level);
+ gpio->bsrr = 1U << (index + set_or_clear_offset);
+ clear_and_set(&gpio->pupdr, index, 2, config->fields.pupd);
+ clear_and_set(&gpio->otyper, index, 1, config->fields.otype);
+ clear_and_set(&gpio->ospeedr, index, 2, config->fields.ospeed);
+ clear_and_set(&gpio->afr [af_reg], af_index, 4, config->fields.af);
+ clear_and_set(&gpio->moder, index, 2, config->fields.mode);
+ rtems_interrupt_enable(level);
+
+#endif /* STM32F4_FAMILY_F4XXXX */
+#ifdef STM32F4_FAMILY_F10XXX
+ unsigned cr_reg = index >> 3;
+ unsigned cr_index = index & 0x7;
+
+ rtems_interrupt_disable(level);
+ gpio->bsrr = 1U << (index + set_or_clear_offset);
+ clear_and_set(&gpio->cr[cr_reg], cr_index, 4,
+ (config->fields.cnf << 2) | config->fields.mode);
+ set_remap_config(config->fields.remap);
+ rtems_interrupt_enable(level);
+
+#endif /* STM32F4_FAMILY_F10XXX */
+}
+
+void stm32f4_gpio_set_config(const stm32f4_gpio_config *config)
+{
+ int current = config->fields.pin_first;
+ int last = config->fields.pin_last;
+
+#ifdef STM32F4_FAMILY_F10XXX
+ stm32f4_rcc_set_clock(STM32F4_RCC_AFIO, true);
+#endif /* STM32F4_FAMILY_F10XXX */
+
+ while (current <= last) {
+ stm32f4_gpio_set_clock(current, true);
+ set_config(current, config);
+ ++current;
+ }
+}
+
+void stm32f4_gpio_set_config_array(const stm32f4_gpio_config *configs)
+{
+ stm32f4_gpio_config terminal = STM32F4_GPIO_CONFIG_TERMINAL;
+
+ while (configs->value != terminal.value) {
+ stm32f4_gpio_set_config(configs);
+ ++configs;
+ }
+}
+
+void stm32f4_gpio_set_output(int pin, bool set)
+{
+ int port = STM32F4_GPIO_PORT_OF_PIN(pin);
+ volatile stm32f4_gpio *gpio = STM32F4_GPIO(port);
+ int index = STM32F4_GPIO_INDEX_OF_PIN(pin);
+ int set_or_clear_offset = set ? 0 : 16;
+
+ gpio->bsrr = 1U << (index + set_or_clear_offset);
+}
+
+bool stm32f4_gpio_get_input(int pin)
+{
+ int port = STM32F4_GPIO_PORT_OF_PIN(pin);
+ volatile stm32f4_gpio *gpio = STM32F4_GPIO(port);
+ int index = STM32F4_GPIO_INDEX_OF_PIN(pin);
+
+ return (gpio->idr & (1U << index)) != 0;
+}
diff --git a/bsps/arm/stm32f4/start/linkcmds.stm32f105rc b/bsps/arm/stm32f4/start/linkcmds.stm32f105rc
new file mode 100644
index 0000000000..d3ea200f2b
--- /dev/null
+++ b/bsps/arm/stm32f4/start/linkcmds.stm32f105rc
@@ -0,0 +1,24 @@
+MEMORY {
+ RAM_INT : ORIGIN = 0x20000000, LENGTH = 64k
+ ROM_INT : ORIGIN = 0x00000000, LENGTH = 256k
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/stm32f4/start/linkcmds.stm32f4 b/bsps/arm/stm32f4/start/linkcmds.stm32f4
new file mode 100644
index 0000000000..1d16cfdde9
--- /dev/null
+++ b/bsps/arm/stm32f4/start/linkcmds.stm32f4
@@ -0,0 +1,24 @@
+MEMORY {
+ RAM_INT : ORIGIN = 0x20000000, LENGTH = 128k
+ ROM_INT : ORIGIN = 0x00000000, LENGTH = 1M
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+INCLUDE linkcmds.armv7m
diff --git a/bsps/arm/stm32f4/start/rcc.c b/bsps/arm/stm32f4/start/rcc.c
new file mode 100644
index 0000000000..ed0b2f1610
--- /dev/null
+++ b/bsps/arm/stm32f4/start/rcc.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/rcc.h>
+#include <bsp/stm32f4.h>
+
+#include <rtems.h>
+
+static void rcc_set(
+ stm32f4_rcc_index index,
+ bool set,
+ volatile uint32_t *regs
+)
+{
+ int reg = index >> 5;
+ uint32_t one = 1;
+ uint32_t bit = one << (index & 0x1f);
+ rtems_interrupt_level level;
+ uint32_t val;
+
+ rtems_interrupt_disable(level);
+ val = regs [reg];
+ if (set) {
+ val |= bit;
+ } else {
+ val &= ~bit;
+ }
+ regs [reg] = val;
+ rtems_interrupt_enable(level);
+}
+
+void stm32f4_rcc_reset(stm32f4_rcc_index index)
+{
+ stm32f4_rcc_set_reset(index, true);
+ stm32f4_rcc_set_reset(index, false);
+}
+
+void stm32f4_rcc_set_reset(stm32f4_rcc_index index, bool set)
+{
+ volatile stm32f4_rcc *rcc = STM32F4_RCC;
+
+#ifdef STM32F4_FAMILY_F4XXXX
+ rcc_set(index, set, &rcc->ahbrstr [0]);
+#endif/* STM32F4_FAMILY_F4XXXX */
+#ifdef STM32F4_FAMILY_F10XXX
+ /* The first register is missing for the reset-block */
+ rcc_set(index, set, &rcc->cir);
+#endif /* STM32F4_FAMILY_F10XXX */
+}
+
+void stm32f4_rcc_set_clock(stm32f4_rcc_index index, bool set)
+{
+ volatile stm32f4_rcc *rcc = STM32F4_RCC;
+
+ rcc_set(index, set, &rcc->ahbenr [0]);
+}
+
+#ifdef STM32F4_FAMILY_F4XXXX
+void stm32f4_rcc_set_low_power_clock(stm32f4_rcc_index index, bool set)
+{
+ volatile stm32f4_rcc *rcc = STM32F4_RCC;
+
+ rcc_set(index, set, &rcc->ahblpenr [0]);
+}
+#endif /* STM32F4_FAMILY_F4XXXX */
diff --git a/bsps/arm/stm32f4/start/start-config-io.c b/bsps/arm/stm32f4/start/start-config-io.c
new file mode 100644
index 0000000000..712fd0705b
--- /dev/null
+++ b/bsps/arm/stm32f4/start/start-config-io.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/io.h>
+#include <bsp.h>
+
+const stm32f4_gpio_config stm32f4_start_config_gpio [] = {
+#ifdef STM32F4_FAMILY_F4XXXX
+ #ifdef STM32F4_ENABLE_USART_1
+ STM32F4_PIN_USART1_TX_PA9,
+ STM32F4_PIN_USART1_RX_PA10,
+ #endif
+ #ifdef STM32F4_ENABLE_USART_2
+ STM32F4_PIN_USART2_TX_PA2,
+ STM32F4_PIN_USART2_RX_PA3,
+ #endif
+ #ifdef STM32F4_ENABLE_USART_3
+ STM32F4_PIN_USART3_TX_PD8,
+ STM32F4_PIN_USART3_RX_PD9,
+ #endif
+ #ifdef STM32F4_ENABLE_UART_4
+ STM32F4_PIN_UART4_TX_PA0,
+ STM32F4_PIN_UART4_RX_PA1,
+ #endif
+ #ifdef STM32F4_ENABLE_UART_5
+ STM32F4_PIN_UART5_TX_PC12,
+ STM32F4_PIN_UART5_RX_PD2,
+ #endif
+ #ifdef STM32F4_ENABLE_USART_6
+ STM32F4_PIN_USART6_TX_PC6,
+ STM32F4_PIN_USART6_RX_PC7,
+ #endif
+ #ifdef STM32F4_ENABLE_I2C1
+ #error Not implemented.
+ #endif
+ #ifdef STM32F4_ENABLE_I2C2
+ #error Not implemented.
+ #endif
+#endif /* STM32F4_FAMILY_F4XXXX */
+#ifdef STM32F4_FAMILY_F10XXX
+ #ifdef STM32F4_ENABLE_USART_1
+ STM32F4_PIN_USART1_TX_MAP_0,
+ STM32F4_PIN_USART1_RX_MAP_0,
+ #endif
+ #ifdef STM32F4_ENABLE_USART_2
+ STM32F4_PIN_USART2_TX_MAP_0,
+ STM32F4_PIN_USART2_RX_MAP_0,
+ #endif
+ #ifdef STM32F4_ENABLE_USART_3
+ STM32F4_PIN_USART3_TX_MAP_0,
+ STM32F4_PIN_USART3_RX_MAP_0,
+ #endif
+ #ifdef STM32F4_ENABLE_UART_4
+ STM32F4_PIN_UART4_TX,
+ STM32F4_PIN_UART4_RX,
+ #endif
+ #ifdef STM32F4_ENABLE_UART_5
+ STM32F4_PIN_UART5_TX,
+ STM32F4_PIN_UART5_RX,
+ #endif
+ #ifdef STM32F4_ENABLE_USART_6
+ #error STM32F10XXX has no USART 6
+ #endif
+ #ifdef STM32F4_ENABLE_I2C1
+ STM32F4_PIN_I2C1_SCL_MAP0,
+ STM32F4_PIN_I2C1_SDA_MAP0,
+ #endif
+ #ifdef STM32F4_ENABLE_I2C2
+ STM32F4_PIN_I2C2_SCL,
+ STM32F4_PIN_I2C2_SDA,
+ #endif
+#endif /* STM32F4_FAMILY_F10XXX */
+ STM32F4_GPIO_CONFIG_TERMINAL
+};
diff --git a/bsps/arm/tms570/start/bsp_specs b/bsps/arm/tms570/start/bsp_specs
new file mode 100644
index 0000000000..9c4b57c578
--- /dev/null
+++ b/bsps/arm/tms570/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s }
diff --git a/bsps/arm/tms570/start/bspreset.c b/bsps/arm/tms570/start/bspreset.c
new file mode 100644
index 0000000000..f6bdee27e1
--- /dev/null
+++ b/bsps/arm/tms570/start/bspreset.c
@@ -0,0 +1,47 @@
+/**
+ * @file bspreset.c
+ *
+ * @ingroup tms570
+ *
+ * @brief Reset code.
+ */
+
+/*
+ * Copyright (c) 2015 Taller Technologies.
+ *
+ * @author Martin Galvan <martin.galvan@tallertechnologies.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/tms570.h>
+#include <bsp/start.h>
+
+static void handle_esm_errors(uint32_t esm_irq_channel)
+{
+ /* ESMR3 errors don't generate interrupts. */
+ if (esm_irq_channel < 0x20u) {
+ TMS570_ESM.SR[0] = 1 << esm_irq_channel;
+ } else if (esm_irq_channel < 0x40u) {
+ TMS570_ESM.SR[1] = 1 << (esm_irq_channel - 32u);
+ } else if (esm_irq_channel < 0x60u) {
+ TMS570_ESM.SR4 = 1 << (esm_irq_channel - 64u);
+ }
+}
+
+void bsp_reset(void)
+{
+ uint32_t esm_irq_channel = TMS570_ESM.IOFFHR - 1;
+
+ if (esm_irq_channel) {
+ handle_esm_errors(esm_irq_channel);
+ }
+
+ /* Reset the board */
+ /* write of value other than 1 cause system reset */
+ TMS570_SYS1.SYSECR = TMS570_SYS1_SYSECR_RESET(2);
+}
diff --git a/bsps/arm/tms570/start/bspstart.c b/bsps/arm/tms570/start/bspstart.c
new file mode 100644
index 0000000000..025bb741d2
--- /dev/null
+++ b/bsps/arm/tms570/start/bspstart.c
@@ -0,0 +1,75 @@
+/**
+ * @file bspstart.c
+ *
+ * @ingroup tms570
+ *
+ * @brief Startup code.
+ */
+
+/*
+ * Copyright (c) 2014 Premysl Houdek <kom541000@gmail.com>
+ *
+ * Google Summer of Code 2014 at
+ * Czech Technical University in Prague
+ * Zikova 1903/4
+ * 166 36 Praha 6
+ * Czech Republic
+ *
+ * Based on LPC24xx and LPC1768 BSP
+ *
+ * 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/tms570-pom.h>
+#include <bsp/irq-generic.h>
+#include <bsp/start.h>
+#include <bsp/bootcard.h>
+#include <bsp/linker-symbols.h>
+#include <rtems/endian.h>
+
+void bsp_start( void )
+{
+ void *need_remap_ptr;
+ unsigned int need_remap_int;
+
+ tms570_initialize_and_clear();
+
+ /*
+ * If RTEMS image does not start at address 0x00000000
+ * then first level exception table at memory begin has
+ * to be replaced to point to RTEMS handlers addresses.
+ *
+ * There is no VBAR or other option because Cortex-R
+ * does provides only fixed address 0x00000000 for exceptions
+ * (0xFFFF0000-0xFFFF001C alternative SCTLR.V = 1 cannot
+ * be used because target area corersponds to PMM peripheral
+ * registers on TMS570).
+ *
+ * Alternative is to use jumps over SRAM based trampolines
+ * but that is not compatible with
+ * Check TCRAM1 ECC error detection logic
+ * which intentionally introduces data abort during startup
+ * to check SRAM and if exception processing goes through
+ * SRAM then it leads to CPU error halt.
+ *
+ * So use of POM to replace jumps to vectors target
+ * addresses seems to be the best option for now.
+ *
+ * The passing of linker symbol (represented as start address
+ * of global array) through dummy asm block ensures that C compiler
+ * cannot optimize comparison out on premise that reference cannot
+ * evaluate to NULL definition in standard.
+ */
+ need_remap_ptr = bsp_start_vector_table_begin;
+ asm volatile ("\n": "=r" (need_remap_int): "0" (need_remap_ptr));
+ if ( need_remap_int != 0 ) {
+ tms570_pom_remap();
+ }
+
+ /* Interrupts */
+ bsp_interrupt_initialize();
+
+}
diff --git a/bsps/arm/tms570/start/bspstarthooks.c b/bsps/arm/tms570/start/bspstarthooks.c
new file mode 100644
index 0000000000..a9e189b6b8
--- /dev/null
+++ b/bsps/arm/tms570/start/bspstarthooks.c
@@ -0,0 +1,41 @@
+/**
+ * @file bspstarthooks.c
+ *
+ * @ingroup tms570
+ *
+ * @brief First configurations and initializations to the correct
+ * functionality of the board.
+ */
+
+/*
+ * Copyright (c) 2014 Premysl Houdek <kom541000@gmail.com>
+ *
+ * Google Summer of Code 2014 at
+ * Czech Technical University in Prague
+ * Zikova 1903/4
+ * 166 36 Praha 6
+ * Czech Republic
+ *
+ * Based on LPC24xx and LPC1768 BSP
+ * by embedded brains GmbH and others
+ *
+ * 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/start.h>
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0( void )
+{
+ ;
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1( void )
+{
+ bsp_start_copy_sections();
+ bsp_start_clear_bss();
+
+ /* At this point we can use objects outside the .start section */
+}
diff --git a/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk b/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk
new file mode 100644
index 0000000000..a32562fc6b
--- /dev/null
+++ b/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk
@@ -0,0 +1,32 @@
+
+MEMORY {
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 3M
+ RAM_INT_VEC : ORIGIN = 0x08000000, LENGTH = 256
+ RAM_INT (AIWX) : ORIGIN = 0x08000100, LENGTH = 256k - 256
+ RAM_EXT (AIWX) : ORIGIN = 0x80000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024;
+bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
+
+bsp_int_vec_overlay_start = ORIGIN(RAM_INT_VEC);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_intram b/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_intram
new file mode 100644
index 0000000000..7cb683de3d
--- /dev/null
+++ b/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_intram
@@ -0,0 +1,32 @@
+
+MEMORY {
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 3M
+ RAM_INT_VEC : ORIGIN = 0x08000000, LENGTH = 256
+ RAM_INT (AIWX) : ORIGIN = 0x08000100, LENGTH = 256k - 256
+ RAM_EXT (AIW) : ORIGIN = 0x80000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("REGION_START", RAM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_RODATA", RAM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024;
+bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
+
+bsp_int_vec_overlay_start = ORIGIN(RAM_INT_VEC);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_sdram b/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_sdram
new file mode 100644
index 0000000000..0117410467
--- /dev/null
+++ b/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_sdram
@@ -0,0 +1,32 @@
+
+MEMORY {
+ ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 3M
+ RAM_INT_VEC : ORIGIN = 0x08000000, LENGTH = 256
+ RAM_INT (AIWX) : ORIGIN = 0x08000100, LENGTH = 256k - 256
+ RAM_EXT (AIWX) : ORIGIN = 0x80000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("REGION_START", RAM_EXT);
+REGION_ALIAS ("REGION_VECTOR", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA", RAM_EXT);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_EXT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM_EXT);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM_EXT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_EXT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_EXT);
+
+bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024;
+bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
+
+bsp_int_vec_overlay_start = ORIGIN(RAM_INT_VEC);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_with_loader b/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_with_loader
new file mode 100644
index 0000000000..940f303030
--- /dev/null
+++ b/bsps/arm/tms570/start/linkcmds.tms570ls3137_hdk_with_loader
@@ -0,0 +1,33 @@
+
+MEMORY {
+ ROM_BOOT(RX) : ORIGIN = 0x00000000, LENGTH = 256k
+ ROM_INT (RX) : ORIGIN = 0x00040000, LENGTH = 3M-256k
+ RAM_INT_VEC : ORIGIN = 0x08000000, LENGTH = 256
+ RAM_INT (AIWX) : ORIGIN = 0x08000100, LENGTH = 256k - 256
+ RAM_EXT (AIWX) : ORIGIN = 0x80000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("REGION_START", ROM_INT);
+REGION_ALIAS ("REGION_VECTOR", RAM_INT);
+REGION_ALIAS ("REGION_TEXT", ROM_INT);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_RODATA", ROM_INT);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_DATA", RAM_INT);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_FAST_DATA", RAM_INT);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT);
+REGION_ALIAS ("REGION_BSS", RAM_INT);
+REGION_ALIAS ("REGION_WORK", RAM_INT);
+REGION_ALIAS ("REGION_STACK", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE", RAM_INT);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT);
+
+bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024;
+bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align);
+
+bsp_int_vec_overlay_start = ORIGIN(RAM_INT_VEC);
+
+INCLUDE linkcmds.armv4
diff --git a/bsps/arm/xilinx-zynq/start/bsp_specs b/bsps/arm/xilinx-zynq/start/bsp_specs
new file mode 100644
index 0000000000..47dd31d46b
--- /dev/null
+++ b/bsps/arm/xilinx-zynq/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/arm/xilinx-zynq/start/bspreset.c b/bsps/arm/xilinx-zynq/start/bspreset.c
new file mode 100644
index 0000000000..b57354c9e2
--- /dev/null
+++ b/bsps/arm/xilinx-zynq/start/bspreset.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/zynq-uart.h>
+
+void bsp_reset(void)
+{
+ volatile uint32_t *slcr_unlock = (volatile uint32_t *) 0xf8000008;
+ volatile uint32_t *pss_rst_ctrl = (volatile uint32_t *) 0xf8000200;
+
+ zynq_uart_reset_tx_flush(&zynq_uart_instances[BSP_CONSOLE_MINOR]);
+
+ while (true) {
+ *slcr_unlock = 0xdf0d;
+ *pss_rst_ctrl = 0x1;
+ }
+}
diff --git a/bsps/arm/xilinx-zynq/start/bspsmp.c b/bsps/arm/xilinx-zynq/start/bspsmp.c
new file mode 100644
index 0000000000..b516823243
--- /dev/null
+++ b/bsps/arm/xilinx-zynq/start/bspsmp.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/score/smpimpl.h>
+
+#include <bsp/start.h>
+
+bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+{
+ /*
+ * Enable the second CPU.
+ */
+ if (cpu_index != 0) {
+ volatile uint32_t* const kick_address = (uint32_t*) 0xfffffff0UL;
+ _ARM_Data_synchronization_barrier();
+ _ARM_Instruction_synchronization_barrier();
+ *kick_address = (uint32_t) _start;
+ _ARM_Data_synchronization_barrier();
+ _ARM_Instruction_synchronization_barrier();
+ _ARM_Send_event();
+ }
+
+ /*
+ * Wait for secondary processor to complete its basic initialization so that
+ * we can enable the unified L2 cache.
+ */
+ return _Per_CPU_State_wait_for_non_initial_state(cpu_index, 0);
+}
diff --git a/bsps/arm/xilinx-zynq/start/bspstart.c b/bsps/arm/xilinx-zynq/start/bspstart.c
new file mode 100644
index 0000000000..14a20df7ef
--- /dev/null
+++ b/bsps/arm/xilinx-zynq/start/bspstart.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013-2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/arm-a9mpcore-clock.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+
+__attribute__ ((weak)) uint32_t zynq_clock_cpu_1x(void)
+{
+ return ZYNQ_CLOCK_CPU_1X;
+}
+
+void bsp_start(void)
+{
+ a9mpcore_clock_initialize_early();
+ bsp_interrupt_initialize();
+ rtems_cache_coherent_add_area(
+ bsp_section_nocacheheap_begin,
+ (uintptr_t) bsp_section_nocacheheap_size
+ );
+}
diff --git a/bsps/arm/xilinx-zynq/start/bspstarthooks.c b/bsps/arm/xilinx-zynq/start/bspstarthooks.c
new file mode 100644
index 0000000000..5372380c24
--- /dev/null
+++ b/bsps/arm/xilinx-zynq/start/bspstarthooks.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/arm-a9mpcore-start.h>
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+{
+ uint32_t sctlr_val;
+
+ sctlr_val = arm_cp15_get_control();
+
+ /*
+ * 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_val & (ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M ) ) {
+ if ( sctlr_val & (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();
+ }
+ arm_cp15_flush_prefetch_buffer();
+ sctlr_val &= ~ ( ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M | ARM_CP15_CTRL_A );
+ arm_cp15_set_control( sctlr_val );
+ }
+ arm_cp15_instruction_cache_invalidate();
+ /*
+ * The care should be taken there that no shared levels
+ * are invalidated by secondary CPUs in SMP case.
+ * It is not problem on Zynq because level of coherency
+ * is L1 only and higher level is not maintained and seen
+ * by CP15. So no special care to limit levels on the secondary
+ * are required there.
+ */
+ arm_cp15_data_cache_invalidate_all_levels();
+ arm_cp15_branch_predictor_invalidate_all();
+ arm_cp15_tlb_invalidate();
+ arm_cp15_flush_prefetch_buffer();
+ arm_a9mpcore_start_hook_0();
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+{
+ arm_a9mpcore_start_hook_1();
+ bsp_start_copy_sections();
+ zynq_setup_mmu_and_cache();
+
+#if !defined(RTEMS_SMP) \
+ && (defined(BSP_DATA_CACHE_ENABLED) \
+ || defined(BSP_INSTRUCTION_CACHE_ENABLED))
+ /* Enable unified L2 cache */
+ rtems_cache_enable_data();
+#endif
+
+ bsp_start_clear_bss();
+}
diff --git a/bsps/arm/xilinx-zynq/start/bspstartmmu.c b/bsps/arm/xilinx-zynq/start/bspstartmmu.c
new file mode 100644
index 0000000000..e0a7743e57
--- /dev/null
+++ b/bsps/arm/xilinx-zynq/start/bspstartmmu.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/arm-cp15-start.h>
+#include <bsp/arm-a9mpcore-start.h>
+
+BSP_START_DATA_SECTION static const arm_cp15_start_section_config
+zynq_mmu_config_table[] = {
+ ARMV7_CP15_START_DEFAULT_SECTIONS,
+#if defined(RTEMS_SMP)
+ {
+ .begin = 0xffff0000U,
+ .end = 0xffffffffU,
+ .flags = ARMV7_MMU_DEVICE
+ },
+#endif
+ {
+ .begin = 0xe0000000U,
+ .end = 0xe0200000U,
+ .flags = ARMV7_MMU_DEVICE
+ }, {
+ .begin = 0xf8000000U,
+ .end = 0xf9000000U,
+ .flags = ARMV7_MMU_DEVICE
+ }
+};
+
+/*
+ * Make weak and let the user override.
+ */
+BSP_START_TEXT_SECTION void zynq_setup_mmu_and_cache(void) __attribute__ ((weak));
+
+BSP_START_TEXT_SECTION void zynq_setup_mmu_and_cache(void)
+{
+ uint32_t ctrl = arm_cp15_start_setup_mmu_and_cache(
+ ARM_CP15_CTRL_A,
+ ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z
+ );
+
+ arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache(
+ ctrl,
+ (uint32_t *) bsp_translation_table_base,
+ ARM_MMU_DEFAULT_CLIENT_DOMAIN,
+ &zynq_mmu_config_table[0],
+ RTEMS_ARRAY_SIZE(zynq_mmu_config_table)
+ );
+}
diff --git a/bsps/arm/xilinx-zynq/start/linkcmds.in b/bsps/arm/xilinx-zynq/start/linkcmds.in
new file mode 100644
index 0000000000..7fd6e2772d
--- /dev/null
+++ b/bsps/arm/xilinx-zynq/start/linkcmds.in
@@ -0,0 +1,39 @@
+MEMORY {
+ RAM_INT_0 : ORIGIN = @ZYNQ_RAM_INT_0_ORIGIN@, LENGTH = @ZYNQ_RAM_INT_0_LENGTH@
+ RAM_INT_1 : ORIGIN = @ZYNQ_RAM_INT_1_ORIGIN@, LENGTH = @ZYNQ_RAM_INT_1_LENGTH@
+ RAM_MMU : ORIGIN = @ZYNQ_RAM_MMU@, LENGTH = @ZYNQ_RAM_MMU_LENGTH@
+ RAM : ORIGIN = @ZYNQ_RAM_ORIGIN_AVAILABLE@, LENGTH = @ZYNQ_RAM_LENGTH_AVAILABLE@ - @ZYNQ_RAM_NOCACHE_LENGTH@
+ NOCACHE : ORIGIN = @ZYNQ_RAM_ORIGIN_AVAILABLE@ + @ZYNQ_RAM_LENGTH_AVAILABLE@ - @ZYNQ_RAM_NOCACHE_LENGTH@, LENGTH = @ZYNQ_RAM_NOCACHE_LENGTH@
+}
+
+bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : @ZYNQ_CPUS@;
+
+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", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", NOCACHE);
+
+bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
+bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
+
+bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1M;
+
+bsp_vector_table_in_start_section = 1;
+
+bsp_translation_table_base = ORIGIN (RAM_MMU);
+bsp_translation_table_end = ORIGIN (RAM_MMU) + LENGTH (RAM_MMU);
+
+INCLUDE linkcmds.armv4