summaryrefslogtreecommitdiffstats
path: root/bsps/powerpc
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/powerpc
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/powerpc')
-rw-r--r--bsps/powerpc/beatnik/start/bsp_specs9
-rw-r--r--bsps/powerpc/beatnik/start/bspclean.c25
-rw-r--r--bsps/powerpc/beatnik/start/bspreset.c18
-rw-r--r--bsps/powerpc/beatnik/start/bspstart.c387
-rw-r--r--bsps/powerpc/beatnik/start/i2c_init.c131
-rw-r--r--bsps/powerpc/beatnik/start/linkcmds5
-rw-r--r--bsps/powerpc/gen5200/start/bestcomm.c107
-rw-r--r--bsps/powerpc/gen5200/start/bsp_specs9
-rw-r--r--bsps/powerpc/gen5200/start/bspreset.c30
-rw-r--r--bsps/powerpc/gen5200/start/bspstart.c172
-rw-r--r--bsps/powerpc/gen5200/start/cpuinit.c348
-rw-r--r--bsps/powerpc/gen5200/start/linkcmds.brs5l15
-rw-r--r--bsps/powerpc/gen5200/start/linkcmds.brs6l15
-rw-r--r--bsps/powerpc/gen5200/start/linkcmds.dp215
-rw-r--r--bsps/powerpc/gen5200/start/linkcmds.gen5200_base357
-rw-r--r--bsps/powerpc/gen5200/start/linkcmds.icecube15
-rw-r--r--bsps/powerpc/gen5200/start/linkcmds.pm520_cr82515
-rw-r--r--bsps/powerpc/gen5200/start/linkcmds.pm520_ze3015
-rw-r--r--bsps/powerpc/gen5200/start/uboot_support.c23
-rw-r--r--bsps/powerpc/gen83xx/start/bsp_specs9
-rw-r--r--bsps/powerpc/gen83xx/start/bspreset.c22
-rw-r--r--bsps/powerpc/gen83xx/start/bsprestart.c47
-rw-r--r--bsps/powerpc/gen83xx/start/bspstart.c129
-rw-r--r--bsps/powerpc/gen83xx/start/cpuinit.c329
-rw-r--r--bsps/powerpc/gen83xx/start/linkcmds19
-rw-r--r--bsps/powerpc/gen83xx/start/linkcmds.br_uid10
-rw-r--r--bsps/powerpc/gen83xx/start/linkcmds.hsc_cm0110
-rw-r--r--bsps/powerpc/gen83xx/start/linkcmds.mpc8309som10
-rw-r--r--bsps/powerpc/gen83xx/start/linkcmds.mpc8313erdb10
-rw-r--r--bsps/powerpc/gen83xx/start/linkcmds.mpc8349eamds10
-rw-r--r--bsps/powerpc/gen83xx/start/linkcmds.mpc83xx47
-rw-r--r--bsps/powerpc/gen83xx/start/uboot_support.c24
-rw-r--r--bsps/powerpc/haleakala/start/bsp_specs10
-rw-r--r--bsps/powerpc/haleakala/start/bspstart.c195
-rw-r--r--bsps/powerpc/haleakala/start/linkcmds277
-rw-r--r--bsps/powerpc/motorola_powerpc/start/bsp_specs9
-rw-r--r--bsps/powerpc/motorola_powerpc/start/bspreset.c28
-rw-r--r--bsps/powerpc/motorola_powerpc/start/linkcmds6
-rw-r--r--bsps/powerpc/mpc55xxevb/start/bsp_specs9
-rw-r--r--bsps/powerpc/mpc55xxevb/start/bspgetworkarea.c53
-rw-r--r--bsps/powerpc/mpc55xxevb/start/bspreset.c38
-rw-r--r--bsps/powerpc/mpc55xxevb/start/bspstart.c104
-rw-r--r--bsps/powerpc/mpc55xxevb/start/exc-vector-base.S124
-rw-r--r--bsps/powerpc/mpc55xxevb/start/get-system-clock.c85
-rw-r--r--bsps/powerpc/mpc55xxevb/start/idle-thread.c34
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds1
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.gwlcfm27
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5566evb27
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5566evb_spe1
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc55xx22
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5643l_dpu1
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5643l_evb33
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5668g29
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu50851
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508_app8
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508_boot6
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_rsm66
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_rsm6_base28
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674fevb28
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674fevb_spe1
-rw-r--r--bsps/powerpc/mpc55xxevb/start/linkcmds.phycore_mpc555436
-rw-r--r--bsps/powerpc/mpc55xxevb/start/restart.c25
-rw-r--r--bsps/powerpc/mpc55xxevb/start/sd-card-init.c163
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-cache.S114
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-clock.c104
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-config-clock.c132
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-config-ebi-cs-cal.c257
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-config-ebi-cs.c164
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-config-ebi.c62
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-config-mmu-early.c64
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-config-mmu.c151
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-config-siu-pcr.c148
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-early.c216
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-flash.S139
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-prologue.c28
-rw-r--r--bsps/powerpc/mpc55xxevb/start/start-watchdog.c39
-rw-r--r--bsps/powerpc/mpc8260ads/start/bsp_specs9
-rw-r--r--bsps/powerpc/mpc8260ads/start/bspstart.c191
-rw-r--r--bsps/powerpc/mpc8260ads/start/cpuinit.c49
-rw-r--r--bsps/powerpc/mpc8260ads/start/linkcmds352
-rw-r--r--bsps/powerpc/mvme3100/start/bsp_specs9
-rw-r--r--bsps/powerpc/mvme3100/start/bspstart.c440
-rw-r--r--bsps/powerpc/mvme3100/start/linkcmds5
-rw-r--r--bsps/powerpc/mvme3100/start/misc.c131
-rw-r--r--bsps/powerpc/mvme5500/start/bootpstuff.c70
-rw-r--r--bsps/powerpc/mvme5500/start/bsp_specs9
-rw-r--r--bsps/powerpc/mvme5500/start/bspclean.c26
-rw-r--r--bsps/powerpc/mvme5500/start/bspreset.c22
-rw-r--r--bsps/powerpc/mvme5500/start/bspstart.c351
-rw-r--r--bsps/powerpc/mvme5500/start/linkcmds5
-rw-r--r--bsps/powerpc/mvme5500/start/pgtbl_activate.c37
-rw-r--r--bsps/powerpc/psim/start/bsp_specs9
-rw-r--r--bsps/powerpc/psim/start/bspstart.c113
-rw-r--r--bsps/powerpc/psim/start/device-tree4
-rw-r--r--bsps/powerpc/psim/start/linkcmds40
-rw-r--r--bsps/powerpc/qemuppc/start/bsp_specs9
-rw-r--r--bsps/powerpc/qemuppc/start/bspstart.c121
-rw-r--r--bsps/powerpc/qemuppc/start/cmain.c55
-rw-r--r--bsps/powerpc/qemuppc/start/linkcmds38
-rw-r--r--bsps/powerpc/qoriq/start/bsp_specs9
-rw-r--r--bsps/powerpc/qoriq/start/bspreset.c64
-rw-r--r--bsps/powerpc/qoriq/start/bsprestart.c146
-rw-r--r--bsps/powerpc/qoriq/start/bspsmp.c252
-rw-r--r--bsps/powerpc/qoriq/start/bspstart.c197
-rw-r--r--bsps/powerpc/qoriq/start/epapr_hcalls.S26
-rw-r--r--bsps/powerpc/qoriq/start/l1cache.S43
-rw-r--r--bsps/powerpc/qoriq/start/l2cache.S43
-rw-r--r--bsps/powerpc/qoriq/start/linkcmds.qoriq_core_038
-rw-r--r--bsps/powerpc/qoriq/start/linkcmds.qoriq_core_137
-rw-r--r--bsps/powerpc/qoriq/start/linkcmds.qoriq_e50038
-rw-r--r--bsps/powerpc/qoriq/start/linkcmds.qoriq_e6500_3241
-rw-r--r--bsps/powerpc/qoriq/start/linkcmds.qoriq_e6500_641
-rw-r--r--bsps/powerpc/qoriq/start/mmu-config.c352
-rw-r--r--bsps/powerpc/qoriq/start/mmu-tlb1.S107
-rw-r--r--bsps/powerpc/qoriq/start/mmu.c368
-rw-r--r--bsps/powerpc/qoriq/start/portal.c43
-rw-r--r--bsps/powerpc/qoriq/start/restart.S80
-rw-r--r--bsps/powerpc/shared/start/bspgetworkarea.c40
-rw-r--r--bsps/powerpc/shared/start/bspidle.c36
-rw-r--r--bsps/powerpc/shared/start/linkcmds.base436
-rw-r--r--bsps/powerpc/shared/start/linkcmds.share296
-rw-r--r--bsps/powerpc/shared/start/pgtbl_activate.c77
-rw-r--r--bsps/powerpc/shared/start/pgtbl_setup.c135
-rw-r--r--bsps/powerpc/shared/start/ppc_idle.c106
-rw-r--r--bsps/powerpc/shared/start/probeMemEnd.c219
-rw-r--r--bsps/powerpc/shared/start/sbrk.c147
-rw-r--r--bsps/powerpc/shared/start/zerobss.c42
-rw-r--r--bsps/powerpc/ss555/start/bsp_specs9
-rw-r--r--bsps/powerpc/ss555/start/bspstart.c97
-rw-r--r--bsps/powerpc/ss555/start/iss555.c148
-rw-r--r--bsps/powerpc/ss555/start/linkcmds328
-rw-r--r--bsps/powerpc/ss555/start/tm27supp.c14
-rw-r--r--bsps/powerpc/t32mppc/start/bsp_specs11
-rw-r--r--bsps/powerpc/t32mppc/start/bspreset.c24
-rw-r--r--bsps/powerpc/t32mppc/start/bspstart.c89
-rw-r--r--bsps/powerpc/t32mppc/start/linkcmds.t32mppc27
-rw-r--r--bsps/powerpc/tqm8xx/start/bsp_specs9
-rw-r--r--bsps/powerpc/tqm8xx/start/bspgetworkarea.c34
-rw-r--r--bsps/powerpc/tqm8xx/start/bspstart.c156
-rw-r--r--bsps/powerpc/tqm8xx/start/cpuinit.c133
-rw-r--r--bsps/powerpc/tqm8xx/start/linkcmds43
-rw-r--r--bsps/powerpc/tqm8xx/start/mmutlbtab.c103
-rw-r--r--bsps/powerpc/virtex/start/bsp_specs9
-rw-r--r--bsps/powerpc/virtex/start/bspstart.c105
-rw-r--r--bsps/powerpc/virtex/start/linkcmds.in35
-rw-r--r--bsps/powerpc/virtex4/start/bsp_specs10
-rw-r--r--bsps/powerpc/virtex4/start/bspclean.c54
-rw-r--r--bsps/powerpc/virtex4/start/bspstart.c219
-rw-r--r--bsps/powerpc/virtex4/start/dummy_console.c88
-rw-r--r--bsps/powerpc/virtex4/start/linkcmds288
-rw-r--r--bsps/powerpc/virtex5/start/bsp_specs10
-rw-r--r--bsps/powerpc/virtex5/start/bspclean.c54
-rw-r--r--bsps/powerpc/virtex5/start/bspstart.c240
-rw-r--r--bsps/powerpc/virtex5/start/dummy_console.c85
-rw-r--r--bsps/powerpc/virtex5/start/linkcmds285
155 files changed, 13691 insertions, 0 deletions
diff --git a/bsps/powerpc/beatnik/start/bsp_specs b/bsps/powerpc/beatnik/start/bsp_specs
new file mode 100644
index 0000000000..99ca0adb61
--- /dev/null
+++ b/bsps/powerpc/beatnik/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/beatnik/start/bspclean.c b/bsps/powerpc/beatnik/start/bspclean.c
new file mode 100644
index 0000000000..251d47a46d
--- /dev/null
+++ b/bsps/powerpc/beatnik/start/bspclean.c
@@ -0,0 +1,25 @@
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <rtems/bspIo.h>
+
+void bsp_fatal_extension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code error
+)
+{
+ printk("fatal source: %s\n", rtems_fatal_source_text(source));
+
+ if (source == RTEMS_FATAL_SOURCE_EXCEPTION) {
+ rtems_exception_frame_print((const rtems_exception_frame *) error);
+ }
+
+ /* We can't go back to MotLoad since we blew it's memory area
+ * and vectors. Just pull the reset line...
+ */
+ printk(
+ "bsp_fatal_extension(): RTEMS terminated -- no way back to MotLoad "
+ "so I reset the card\n"
+ );
+ bsp_reset();
+}
diff --git a/bsps/powerpc/beatnik/start/bspreset.c b/bsps/powerpc/beatnik/start/bspreset.c
new file mode 100644
index 0000000000..68540847ee
--- /dev/null
+++ b/bsps/powerpc/beatnik/start/bspreset.c
@@ -0,0 +1,18 @@
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <rtems/bspIo.h>
+#include <libcpu/io.h>
+#include <libcpu/stackTrace.h>
+#include <stdint.h>
+
+void bsp_reset()
+{
+
+ printk("Printing a stack trace for your convenience :-)\n");
+ CPU_print_stack();
+
+ printk("RTEMS terminated; Rebooting ...\n");
+ /* Mvme5500 board reset : 2004 S. Kate Feng <feng1@bnl.gov> */
+ out_8((volatile uint8_t*) (BSP_MV64x60_DEV1_BASE +2), 0x80);
+}
diff --git a/bsps/powerpc/beatnik/start/bspstart.c b/bsps/powerpc/beatnik/start/bspstart.c
new file mode 100644
index 0000000000..c3f2c0ceda
--- /dev/null
+++ b/bsps/powerpc/beatnik/start/bspstart.c
@@ -0,0 +1,387 @@
+/*
+ * This routine does the bulk of the system initialization.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-1998.
+ * 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.OARcorp.com/rtems/license.html.
+ *
+ * Modified to support the MCP750.
+ * Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ *
+ * Modified to support the Synergy VGM & Motorola PowerPC boards.
+ * (C) by Till Straumann, <strauman@slac.stanford.edu>, 2002, 2004, 2005
+ *
+ * Modified to support the mvme5500 BSP
+ * (C) by Kate Feng <feng1@bnl.gov>, 2003, 2004
+ * under the contract DE-AC02-98CH10886 with the Deaprtment of Energy
+ *
+ * T. Straumann: 2005-2007; stolen again for 'beatnik'...
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <rtems/system.h>
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+#include <rtems/powerpc/powerpc.h>
+#include <rtems/sysinit.h>
+/*#include <bsp/consoleIo.h>*/
+#include <libcpu/spr.h> /* registers.h is included here */
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/uart.h>
+#include <bsp/pci.h>
+#include <bsp/gtreg.h>
+#include <bsp/gt_timer.h>
+#include <libcpu/bat.h>
+#include <libcpu/pte121.h>
+#include <libcpu/cpuIdent.h>
+#include <bsp/vectors.h>
+#include <bsp/VME.h>
+#include <bsp/vpd.h>
+
+#define SHOW_MORE_INIT_SETTINGS
+
+BSP_output_char_function_type BSP_output_char = BSP_output_char_via_serial;
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
+
+extern Triv121PgTbl BSP_pgtbl_setup(unsigned int *);
+extern void BSP_pgtbl_activate(Triv121PgTbl);
+extern void BSP_motload_pci_fixup(void);
+
+extern unsigned long __rtems_end[];
+
+/* We really shouldn't use these since MMUoff also sets IP;
+ * nevertheless, during early init I don't care for now
+ */
+extern void MMUoff(void);
+extern void MMUon(void);
+
+extern uint32_t probeMemoryEnd(void);
+
+SPR_RW(SPRG0)
+SPR_RW(SPRG1)
+SPR_RO(HID1)
+
+/* Table of PLL multipliers for 7455/7457:
+01000 2 00010 7.5 00000 11.5 00001 17
+10000 3 11000 8 10111 12 00101 18
+10100 4 01100 8.5 11111 12.5 00111 20
+10110 5 01111 9 01011 13 01001 21
+10010 5.5 01110 9.5 11100 13.5 01101 24
+11010 6 10101 10 11001 14 11101 28
+01010 6.5 10001 10.5 00011 15 00110 bypass
+00100 7 10011 11 11011 16 11110 off
+*/
+
+/* Sorted according to CFG bits and multiplied by 2 it looks
+ * like this (note that this is in sequential order, not
+ * tabulated as above)
+ */
+signed char mpc7450PllMultByTwo[32] = {
+23, 34, 15, 30,
+14, 36, 2/*bypass*/, 40,
+4, 42, 13, 26,
+17, 48, 19, 18,
+6, 21, 11, 22,
+8, 20, 10, 24,
+16, 28, 12, 32,
+27, 56, 0/*off*/, 25,
+};
+
+uint32_t bsp_clicks_per_usec = 0;
+
+/*
+ * Total memory using probing.
+ */
+unsigned int BSP_mem_size;
+
+/*
+ * PCI Bus Frequency
+ */
+unsigned int BSP_bus_frequency = 0xdeadbeef;
+/*
+ * processor clock frequency
+ */
+unsigned int BSP_processor_frequency = 0xdeadbeef;
+
+/*
+ * Time base divisior (bus freq / TB clock)
+ */
+unsigned int BSP_time_base_divisor = 4000; /* most 604+ CPUs seem to use this */
+
+/* Board identification string */
+char BSP_productIdent[20] = {0};
+char BSP_serialNumber[20] = {0};
+
+/* VPD appends an extra char -- what for ? */
+char BSP_enetAddr0[7] = {0};
+char BSP_enetAddr1[7] = {0};
+
+char *rtems_progname;
+
+#define CMDLINE_BUF_SIZE 2048
+
+static char cmdline_buf[CMDLINE_BUF_SIZE];
+char *BSP_commandline_string = cmdline_buf;
+
+/* this routine is called early and must be safe with a not properly
+ * aligned stack
+ */
+char *save_boot_params(
+ void *r3,
+ void *r4,
+ void *r5,
+ char *cmdline_start,
+ char *cmdline_end
+)
+{
+int i=cmdline_end-cmdline_start;
+ if ( i >= CMDLINE_BUF_SIZE )
+ i = CMDLINE_BUF_SIZE-1;
+ else if ( i < 0 )
+ i = 0;
+ memmove(cmdline_buf, cmdline_start, i);
+ cmdline_buf[i]=0;
+ return cmdline_buf;
+}
+
+static BSP_BoardType board_type = Unknown;
+
+BSP_BoardType
+BSP_getBoardType( void )
+{
+ return board_type;
+}
+
+/*
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ */
+
+void bsp_start( void )
+{
+ unsigned char *stack;
+ char *chpt;
+ uint32_t intrStackStart;
+ uint32_t intrStackSize;
+
+ Triv121PgTbl pt=0;
+
+ VpdBufRec vpdData [] = {
+ { key: ProductIdent, instance: 0, buf: BSP_productIdent, buflen: sizeof(BSP_productIdent) - 1 },
+ { key: SerialNumber, instance: 0, buf: BSP_serialNumber, buflen: sizeof(BSP_serialNumber) - 1 },
+ { key: CpuClockHz, instance: 0, buf: &BSP_processor_frequency, buflen: sizeof(BSP_processor_frequency) },
+ { key: BusClockHz, instance: 0, buf: &BSP_bus_frequency, buflen: sizeof(BSP_bus_frequency) },
+ { key: EthernetAddr, instance: 0, buf: BSP_enetAddr0, buflen: sizeof(BSP_enetAddr0) },
+ { key: EthernetAddr, instance: 1, buf: BSP_enetAddr1, buflen: sizeof(BSP_enetAddr1) },
+ VPD_END
+ };
+
+ /* T. Straumann: 4/2005
+ *
+ * Need to map the system registers early, so we can printk...
+ * (otherwise we silently die)
+ */
+ /* map the PCI 0, 1 Domain I/O space, GT64260B registers
+ * and the reserved area so that the size is the power of 2.
+ */
+ setdbat(7, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_SIZE, IO_PAGE);
+
+ /* Intersperse messages with actions to help locate problems */
+ printk("-----------------------------------------\n");
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type() & friends functions
+ * store the result in global variables so that it can be used latter...
+ * This also verifies that we run on a known CPU.
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ /* Make sure we detect a known host bridge */
+ BSP_getDiscoveryVersion(/* assert detection */ 1);
+
+ printk("Welcome to RTEMS %s\n", _RTEMS_version );
+
+ /* Leave all caches as MotLoad left them. Seems to be fine */
+
+ /*
+ * the initial stack has aready been set to this value in start.S
+ * so there is no need to set it in r1 again... It is just for info
+ * so that it can be printed without accessing R1.
+ */
+ __asm__ volatile("mr %0, 1":"=r"(stack));
+
+ /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
+
+ *((uint32_t *)stack) = 0;
+
+ /*
+ * Initialize the interrupt related settings
+ * SPRG0 = interrupt nesting level count
+ * SPRG1 = software managed IRQ stack
+ *
+ * This could be done latter (e.g in IRQ_INIT) but it helps to understand
+ * some settings below...
+ */
+ intrStackStart = (uint32_t)__rtems_end;
+ intrStackSize = rtems_configuration_get_interrupt_stack_size();
+
+ /*
+ * Initialize default raw exception handlers. See vectors/vectors_init.c
+ */
+ ppc_exc_initialize(intrStackStart, intrStackSize);
+
+ printk("CPU: %s\n", get_ppc_cpu_type_name(current_ppc_cpu));
+
+ /*
+ * Initialize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mng_init(0);
+
+ BSP_vpdRetrieveFields(vpdData);
+
+ if ( !strncmp(BSP_productIdent,"MVME5500",8) )
+ board_type = MVME5500;
+ else if ( !strncmp(BSP_productIdent,"MVME6100",8) )
+ board_type = MVME6100;
+
+ printk("Board Type: %s (S/N %s)\n",
+ BSP_productIdent[0] ? BSP_productIdent : "n/a",
+ BSP_serialNumber[0] ? BSP_serialNumber : "n/a");
+
+ if ( 0xdeadbeef == BSP_bus_frequency ) {
+ BSP_bus_frequency = 133333333;
+ printk("Bus Clock Freq NOT FOUND in VPD; using %10u Hz\n",
+ BSP_bus_frequency);
+ } else {
+ printk("Bus Clock Freq: %10u Hz\n",
+ BSP_bus_frequency);
+ }
+
+ if ( 0xdeadbeef == BSP_processor_frequency ) {
+ BSP_processor_frequency = BSP_bus_frequency/2;
+ BSP_processor_frequency *= mpc7450PllMultByTwo[ (_read_HID1() >> (31-19)) & 31 ];
+ }
+ printk("CPU Clock Freq: %10u Hz\n", BSP_processor_frequency);
+
+ /* probe real memory size; if it's more than 256M we can't currently access it
+ * since at this point only BAT-0 maps 0..256M
+ */
+ BSP_mem_size = probeMemoryEnd();
+
+ if ( (chpt = strstr(BSP_commandline_string,"MEMSZ=")) ) {
+ char *endp;
+ uint32_t sz;
+ chpt+=6 /* strlen("MEMSZ=") */;
+ sz = strtoul(chpt, &endp, 0);
+ if ( endp != chpt )
+ BSP_mem_size = sz;
+ }
+
+ printk("Memory: %10u bytes\n", BSP_mem_size);
+
+ if ( BSP_mem_size > 0x10000000 ) {
+ uint32_t s;
+ if ( BSP_mem_size > 0x80000000 ) {
+ BSP_mem_size = 0x80000000;
+ printk("Memory clipped to 0x%08x for now, sorry\n", BSP_mem_size);
+ }
+ for ( s = 0x20000000; s < BSP_mem_size ; s<<=1)
+ ;
+ MMUoff();
+ /* since it's currently in use we must first surrender it */
+ setdbat(0, 0, 0, 0, 0);
+ setdbat(0, 0, 0, s, _PAGE_RW);
+ MMUon();
+ }
+
+ printk("-----------------------------------------\n");
+
+ /* Maybe not setup yet because of the warning message */
+
+ /* Allocate and set up the page table mappings
+ * This is only available on >604 CPUs.
+ *
+ * NOTE: This setup routine may modify the available memory
+ * size. It is essential to call it before
+ * calculating the workspace etc.
+ */
+ pt = BSP_pgtbl_setup(&BSP_mem_size);
+ if (!pt)
+ printk("WARNING: unable to setup page tables.\n");
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size);
+#endif
+
+ /*
+ * Set up our hooks
+ */
+
+ bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
+ rtems_counter_initialize_converter(
+ BSP_bus_frequency / (BSP_time_base_divisor / 1000)
+ );
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk(
+ "Configuration.work_space_size = %x\n",
+ rtems_configuration_get_work_space_size()
+ );
+#endif
+
+ /* Activate the page table mappings only after
+ * initializing interrupts because the irq_mng_init()
+ * routine needs to modify the text
+ */
+ if ( pt ) {
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Page table setup finished; will activate it NOW...\n");
+#endif
+ BSP_pgtbl_activate(pt);
+ }
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Going to start PCI buses scanning and initialization\n");
+#endif
+ BSP_pci_initialize();
+
+ /* need to tweak the motload setup */
+ BSP_motload_pci_fixup();
+
+ /* map 512M, 256 for PCI 256 for VME */
+ setdbat(5,BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_SIZE, IO_PAGE);
+ setdbat(6,BSP_PCI_HOSE1_MEM_BASE, BSP_PCI_HOSE1_MEM_BASE, 0x10000000, IO_PAGE);
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Number of PCI buses found is : %d\n", pci_bus_count());
+#endif
+
+ /*
+ * Initialize hardware timer facility (not used by BSP itself)
+ * Needs PCI to identify discovery version...
+ */
+ BSP_timers_initialize();
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("MSR 0x%lx \n", _read_MSR());
+ printk("Exit from bspstart\n");
+#endif
+}
+
+RTEMS_SYSINIT_ITEM(
+ BSP_vme_config,
+ RTEMS_SYSINIT_BSP_PRE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
diff --git a/bsps/powerpc/beatnik/start/i2c_init.c b/bsps/powerpc/beatnik/start/i2c_init.c
new file mode 100644
index 0000000000..bc5c5ead02
--- /dev/null
+++ b/bsps/powerpc/beatnik/start/i2c_init.c
@@ -0,0 +1,131 @@
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/libi2c.h>
+#include <libchip/i2c-2b-eeprom.h>
+#include <libchip/i2c-ds1621.h>
+#include <bsp/gti2c_busdrv.h>
+#include <rtems/libio.h>
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+/* Register i2c bus driver & devices */
+
+/*
+ * Authorship
+ * ----------
+ * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
+ * created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
+ * Stanford Linear Accelerator Center, Stanford University.
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * The 'beatnik' BSP was produced by
+ * the Stanford Linear Accelerator Center, Stanford University,
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software. Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+
+int
+BSP_i2c_initialize( void )
+{
+int busno;
+ /* Initialize the library */
+ if ( rtems_libi2c_initialize() ) {
+ fprintf(stderr,"Initializing I2C library failed\n");
+ return -1;
+ }
+
+ /* Register our bus driver */
+ if ( (busno=rtems_libi2c_register_bus(
+ BSP_I2C_BUS0_NAME,
+ BSP_I2C_BUS_DESCRIPTOR) ) < 0 ) {
+ perror("Registering gt64260 i2c bus driver");
+ return -1;
+ }
+
+ /* Now register higher level drivers; note that
+ * the i2c address in the manual is actually left-shifted
+ * by one bit, i.e., as it would go on the bus.
+ */
+
+ /* Use read-only driver for VPD */
+ if ( rtems_libi2c_register_drv(
+ BSP_I2C_VPD_EEPROM_NAME,
+ i2c_2b_eeprom_ro_driver_descriptor,
+ busno,
+ BSP_VPD_I2C_ADDR) < 0 ) {
+ perror("Registering i2c VPD eeprom driver failed");
+ return -1;
+ }
+
+ /* Use read-write driver for user eeprom -- you still might
+ * have to disable HW write-protection on your board.
+ */
+ if ( rtems_libi2c_register_drv(
+ BSP_I2C_USR_EEPROM_NAME,
+ i2c_2b_eeprom_driver_descriptor,
+ busno,
+ BSP_USR_I2C_ADDR) < 0 ) {
+ perror("Registering i2c USR eeprom driver failed");
+ return -1;
+ }
+
+ /* The thermostat */
+ if ( rtems_libi2c_register_drv(
+ BSP_I2C_DS1621_NAME,
+ i2c_ds1621_driver_descriptor,
+ busno,
+ BSP_THM_I2C_ADDR) < 0 ) {
+ perror("Registering i2c ds1621 temp sensor. driver failed");
+ return -1;
+ }
+
+ /* Finally, as an example, register raw access to the
+ * ds1621. The driver above just reads the 8 msb of the
+ * temperature but doesn't support anything else. Using
+ * the raw device node you can write/read individual
+ * control bytes yourself and e.g., program the thermostat...
+ */
+
+ if ( mknod(
+ BSP_I2C_DS1621_RAW_DEV_NAME,
+ 0666 | S_IFCHR,
+ rtems_filesystem_make_dev_t(rtems_libi2c_major,
+ RTEMS_LIBI2C_MAKE_MINOR(busno,BSP_THM_I2C_ADDR))) ) {
+ perror("Creating device node for raw ds1621 access failed");
+ return -1;
+ }
+ printf("I2C devices registered\n");
+ return 0;
+}
diff --git a/bsps/powerpc/beatnik/start/linkcmds b/bsps/powerpc/beatnik/start/linkcmds
new file mode 100644
index 0000000000..b30fb91277
--- /dev/null
+++ b/bsps/powerpc/beatnik/start/linkcmds
@@ -0,0 +1,5 @@
+STARTUP(motld_start.o)
+ENTRY(__rtems_entry_point)
+EXTERN(__vectors)
+
+INCLUDE linkcmds.share
diff --git a/bsps/powerpc/gen5200/start/bestcomm.c b/bsps/powerpc/gen5200/start/bestcomm.c
new file mode 100644
index 0000000000..ef59adcfd8
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/bestcomm.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010-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 NDEBUG
+
+#include <bsp/bestcomm.h>
+
+#include <string.h>
+
+#include <bsp/mpc5200.h>
+
+static void bestcomm_irq_handler(void *arg)
+{
+ bestcomm_irq *self = arg;
+
+ bestcomm_irq_clear(self);
+ bestcomm_irq_wakeup_event_task(self);
+}
+
+void bestcomm_irq_create(bestcomm_irq *self, int task_index)
+{
+ assert(task_index >= 0 && task_index <= 15);
+
+ self->task_index = task_index;
+ self->event_task_id = rtems_task_self();
+ bestcomm_glue_irq_install(task_index, bestcomm_irq_handler, self);
+}
+
+void bestcomm_irq_destroy(const bestcomm_irq *self)
+{
+ bestcomm_glue_irq_install(self->task_index, NULL, NULL);
+}
+
+void bestcomm_task_create(bestcomm_task *self, TaskId task_index)
+{
+ self->task_control_register = &mpc5200.sdma.tcr[task_index];
+ self->variable_table = BESTCOMM_TASK_ENTRY_TABLE[task_index].var_table;
+ self->task_index = task_index;
+ self->tdt_begin = NULL;
+ self->tdt_opcode_count = 0;
+ bestcomm_task_stop(self);
+ bestcomm_irq_create(&self->irq, task_index);
+}
+
+void bestcomm_task_create_and_load(
+ bestcomm_task *self,
+ TaskId task_index,
+ const uint32_t *tdt_source_begin,
+ size_t tdt_size
+)
+{
+ bestcomm_task_create(self, task_index);
+ bestcomm_task_load(self, tdt_source_begin, tdt_size);
+}
+
+void bestcomm_task_destroy(bestcomm_task *self)
+{
+ bestcomm_task_stop(self);
+ bestcomm_task_free_tdt(self);
+}
+
+void bestcomm_task_load(bestcomm_task *self, const uint32_t *tdt_source_begin, size_t tdt_size)
+{
+ assert(tdt_size % 4 == 0);
+
+ bestcomm_task_irq_disable(self);
+ bestcomm_task_stop(self);
+ bestcomm_task_irq_clear(self);
+ bestcomm_task_irq_enable(self);
+ bestcomm_task_free_tdt(self);
+ bestcomm_task_clear_variables(self);
+
+ self->tdt_opcode_count = tdt_size / 4;
+
+ self->tdt_begin = bestcomm_malloc(tdt_size);
+ assert(self->tdt_begin != NULL);
+ uint32_t *tdt_last = self->tdt_begin + self->tdt_opcode_count - 1;
+
+ memcpy(self->tdt_begin, tdt_source_begin, tdt_size);
+
+ volatile bestcomm_task_entry *entry = bestcomm_task_get_task_entry(self);
+ entry->tdt_begin = self->tdt_begin;
+ entry->tdt_last = tdt_last;
+
+ bestcomm_task_clear_pragmas(self);
+ bestcomm_task_set_priority(self, 0);
+}
+
+void bestcomm_task_clear_variables(const bestcomm_task *self)
+{
+ int i;
+
+ for (i = 0; i < 32; ++i) {
+ (*self->variable_table)[i] = 0;
+ }
+}
diff --git a/bsps/powerpc/gen5200/start/bsp_specs b/bsps/powerpc/gen5200/start/bsp_specs
new file mode 100644
index 0000000000..2625609327
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/gen5200/start/bspreset.c b/bsps/powerpc/gen5200/start/bspreset.c
new file mode 100644
index 0000000000..232ebfeac0
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/bspreset.c
@@ -0,0 +1,30 @@
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * 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.h>
+#include <bsp/mpc5200.h>
+#include <bsp/bootcard.h>
+
+void bsp_reset( void )
+{
+ #if (BENCHMARK_IRQ_PROCESSING == 1)
+ {
+ BSP_IRQ_Benchmarking_Report();
+ }
+ #endif
+
+ /*
+ * Now reset the CPU
+ */
+ mpc5200.gpt[0].count_in = 0xf;
+ mpc5200.gpt[0].emsel = 0x9004;
+
+ while(1) ;
+}
diff --git a/bsps/powerpc/gen5200/start/bspstart.c b/bsps/powerpc/gen5200/start/bspstart.c
new file mode 100644
index 0000000000..209cc7738e
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/bspstart.c
@@ -0,0 +1,172 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| 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. |
+| |
++-----------------------------------------------------------------+
+| this file contains the BSP initialization code |
+\*===============================================================*/
+/***********************************************************************/
+/* */
+/* Module: bspstart.c */
+/* Date: 07/17/2003 */
+/* Purpose: RTEMS MPC5x00 C level startup code */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Description: This routine starts the application. It includes */
+/* application, board, and monitor specific */
+/* initialization and configuration. The generic CPU */
+/* dependent initialization has been performed before */
+/* this routine is invoked. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Code */
+/* References: MPC8260ads C level startup code */
+/* Module: bspstart.c */
+/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */
+/* Version 1.2 */
+/* Date: 04/17/2002 */
+/* */
+/* Author(s) / Copyright(s): */
+/* */
+/* The MPC860 specific stuff was written by Jay Monkman */
+/* (jmonkman@frasca.com) */
+/* */
+/* Modified for the MPC8260ADS board by Andy Dachs */
+/* <a.dachs@sstl.co.uk> */
+/* Surrey Satellite Technology Limited, 2001 */
+/* A 40MHz system clock is assumed. */
+/* The PON. RST.CONF. Dip switches (DS1) are */
+/* 1 - Off */
+/* 2 - On */
+/* 3 - Off */
+/* 4 - On */
+/* 5 - Off */
+/* 6 - Off */
+/* 7 - Off */
+/* 8 - Off */
+/* Dip switches on DS2 and DS3 are all set to ON */
+/* The LEDs on the board are used to signal panic and fatal_error */
+/* conditions. */
+/* The mmu is unused at this time. */
+/* */
+/* COPYRIGHT (c) 1989-2007. */
+/* 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. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Partially based on the code references which are named above. */
+/* Adaptions, modifications, enhancements and any recent parts of */
+/* the code are under the right of */
+/* */
+/* IPR Engineering, Dachauer Straße 38, D-80335 München */
+/* Copyright(C) 2003 */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* IPR Engineering makes no representation or warranties with */
+/* respect to the performance of this computer program, and */
+/* specifically disclaims any responsibility for any damages, */
+/* special or consequential, connected with the use of this program. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Version history: 1.0 */
+/* */
+/***********************************************************************/
+
+#include <rtems.h>
+#include <rtems/counter.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/vectors.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/mpc5200.h>
+
+/* Configuration parameter for clock driver */
+uint32_t bsp_time_base_frequency;
+
+/* Legacy */
+uint32_t bsp_clicks_per_usec;
+
+void bsp_start(void)
+{
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function store the result in global variables so that it can be used
+ * later...
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ #if defined(HAS_UBOOT) && defined(SHOW_MORE_INIT_SETTINGS)
+ {
+ void dumpUBootBDInfo( bd_t * );
+ dumpUBootBDInfo( &bsp_uboot_board_info );
+ }
+ #endif
+
+ cpu_init();
+
+ if(get_ppc_cpu_revision() >= 0x2014) {
+ /* Special settings for MPC5200B (B variant) */
+ uint32_t xlb_cfg = mpc5200.config;
+
+ /* XXX: The Freescale documentation for BSDIS seems to be wrong */
+ xlb_cfg |= XLB_CFG_BSDIS;
+
+ xlb_cfg &= ~XLB_CFG_PLDIS;
+
+ mpc5200.config = xlb_cfg;
+ }
+
+ bsp_time_base_frequency = XLB_CLOCK / 4;
+ bsp_clicks_per_usec = (XLB_CLOCK/4000000);
+ rtems_counter_initialize_converter(bsp_time_base_frequency);
+
+ /* Initialize exception handler */
+ ppc_exc_cache_wb_check = 0;
+ ppc_exc_initialize(
+ (uintptr_t) bsp_interrupt_stack_start,
+ (uintptr_t) bsp_interrupt_stack_size
+ );
+ ppc_exc_set_handler(ASM_ALIGN_VECTOR, ppc_exc_alignment_handler);
+
+ /* Initalize interrupt support */
+ bsp_interrupt_initialize();
+
+ /*
+ * If the BSP was built with IRQ benchmarking enabled,
+ * then intialize it.
+ */
+ #if (BENCHMARK_IRQ_PROCESSING == 1)
+ BSP_IRQ_Benchmarking_Reset();
+ #endif
+
+ #ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Exit from bspstart\n");
+ #endif
+}
diff --git a/bsps/powerpc/gen5200/start/cpuinit.c b/bsps/powerpc/gen5200/start/cpuinit.c
new file mode 100644
index 0000000000..77787c4956
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/cpuinit.c
@@ -0,0 +1,348 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC5200 BSP |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| 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. |
+| |
++-----------------------------------------------------------------+
+| this file contains the code to initialize the cpu |
+\*===============================================================*/
+/***********************************************************************/
+/* */
+/* Module: cpuinit.c */
+/* Date: 07/17/2003 */
+/* Purpose: RTEMS MPC5x00 C level startup code */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Description: This file contains additional functions for */
+/* initializing the MPC5x00 CPU */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Code */
+/* References: MPC8260ads additional CPU initialization */
+/* Module: cpuinit.c */
+/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */
+/* Version 1.1 */
+/* Date: 10/22/2002 */
+/* */
+/* Author(s) / Copyright(s): */
+/* */
+/* Written by Jay Monkman (jmonkman@frasca.com) */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Partially based on the code references which are named above. */
+/* Adaptions, modifications, enhancements and any recent parts of */
+/* the code are under the right of */
+/* */
+/* IPR Engineering, Dachauer Straße 38, D-80335 München */
+/* Copyright(C) 2003 */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* IPR Engineering makes no representation or warranties with */
+/* respect to the performance of this computer program, and */
+/* specifically disclaims any responsibility for any damages, */
+/* special or consequential, connected with the use of this program. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Version history: 1.0 */
+/* */
+/***********************************************************************/
+
+#include <stdbool.h>
+#include <string.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <libcpu/mmu.h>
+
+#include <bsp.h>
+#include <bsp/mpc5200.h>
+
+#define SET_DBAT( n, uv, lv) \
+ do { \
+ PPC_SET_SPECIAL_PURPOSE_REGISTER( DBAT##n##L, lv); \
+ PPC_SET_SPECIAL_PURPOSE_REGISTER( DBAT##n##U, uv); \
+ } while (0)
+
+static void calc_dbat_regvals(
+ BAT *bat_ptr,
+ uint32_t base_addr,
+ uint32_t size,
+ bool flg_w,
+ bool flg_i,
+ bool flg_m,
+ bool flg_g,
+ uint32_t flg_bpp
+)
+{
+ uint32_t block_mask = 0xffffffff;
+ uint32_t end_addr = base_addr + size - 1;
+
+ /* Determine block mask, that overlaps the whole block */
+ while ((end_addr & block_mask) != (base_addr & block_mask)) {
+ block_mask <<= 1;
+ }
+
+ bat_ptr->batu.bepi = base_addr >> (32 - 15);
+ bat_ptr->batu.bl = ~(block_mask >> (28 - 11));
+ bat_ptr->batu.vs = 1;
+ bat_ptr->batu.vp = 1;
+
+ bat_ptr->batl.brpn = base_addr >> (32 - 15);
+ bat_ptr->batl.w = flg_w;
+ bat_ptr->batl.i = flg_i;
+ bat_ptr->batl.m = flg_m;
+ bat_ptr->batl.g = flg_g;
+ bat_ptr->batl.pp = flg_bpp;
+}
+
+static inline void enable_bat_4_to_7(void)
+{
+ PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(HID2, BSP_BBIT32(13));
+}
+
+static void cpu_init_bsp(void)
+{
+ BAT dbat;
+
+#if defined(MPC5200_BOARD_BRS5L) || defined(MPC5200_BOARD_BRS6L)
+ calc_dbat_regvals(
+ &dbat,
+ (uint32_t) bsp_ram_start,
+ (uint32_t) bsp_ram_size,
+ false,
+ false,
+ false,
+ false,
+ BPP_RW
+ );
+ SET_DBAT(0,dbat.batu,dbat.batl);
+
+ calc_dbat_regvals(
+ &dbat,
+ (uint32_t) bsp_rom_start,
+ (uint32_t) bsp_rom_size,
+ false,
+ false,
+ false,
+ false,
+ BPP_RX
+ );
+ SET_DBAT(1,dbat.batu,dbat.batl);
+
+ calc_dbat_regvals(
+ &dbat,
+ (uint32_t) MBAR,
+ 128 * 1024,
+ false,
+ true,
+ false,
+ true,
+ BPP_RW
+ );
+ SET_DBAT(2,dbat.batu,dbat.batl);
+#elif defined (HAS_UBOOT)
+ uint32_t start = 0;
+
+ /*
+ * Accesses (also speculative accesses) outside of the RAM area are a
+ * disaster especially in combination with the BestComm. For safety reasons
+ * we make the available RAM a little bit smaller to have an unused area at
+ * the end.
+ */
+ bsp_uboot_board_info.bi_memsize -= 4 * 1024;
+
+ /*
+ * Program BAT0 for RAM
+ */
+ calc_dbat_regvals(
+ &dbat,
+ bsp_uboot_board_info.bi_memstart,
+ bsp_uboot_board_info.bi_memsize,
+ false,
+ false,
+ false,
+ false,
+ BPP_RW
+ );
+ SET_DBAT(0,dbat.batu,dbat.batl);
+
+ /*
+ * Program BAT1 for Flash
+ *
+ * WARNING!! Some Freescale LITE5200B boards ship with a version of
+ * U-Boot that lies about the starting address of Flash. This check
+ * corrects that.
+ */
+ if ((bsp_uboot_board_info.bi_flashstart + bsp_uboot_board_info.bi_flashsize)
+ < bsp_uboot_board_info.bi_flashstart) {
+ start = 0 - bsp_uboot_board_info.bi_flashsize;
+ } else {
+ start = bsp_uboot_board_info.bi_flashstart;
+ }
+ calc_dbat_regvals(
+ &dbat,
+ start,
+ bsp_uboot_board_info.bi_flashsize,
+ false,
+ false,
+ false,
+ false,
+ BPP_RX
+ );
+ SET_DBAT(1,dbat.batu,dbat.batl);
+
+ /*
+ * Program BAT2 for the MBAR
+ */
+ calc_dbat_regvals(
+ &dbat,
+ (uint32_t) MBAR,
+ 128 * 1024,
+ false,
+ true,
+ false,
+ true,
+ BPP_RW
+ );
+ SET_DBAT(2,dbat.batu,dbat.batl);
+
+ /*
+ * If there is SRAM, program BAT3 for that memory
+ */
+ if (bsp_uboot_board_info.bi_sramsize != 0) {
+ calc_dbat_regvals(
+ &dbat,
+ bsp_uboot_board_info.bi_sramstart,
+ bsp_uboot_board_info.bi_sramsize,
+ false,
+ true,
+ true,
+ true,
+ BPP_RW
+ );
+ SET_DBAT(3,dbat.batu,dbat.batl);
+ }
+#else
+#warning "Using BAT register values set by environment"
+#endif
+
+#if defined(MPC5200_BOARD_DP2)
+ enable_bat_4_to_7();
+
+ /* FPGA */
+ calc_dbat_regvals(
+ &dbat,
+ 0xf0020000,
+ 128 * 1024,
+ false,
+ true,
+ false,
+ true,
+ BPP_RW
+ );
+ SET_DBAT(4, dbat.batu, dbat.batl);
+#elif defined(MPC5200_BOARD_PM520_ZE30)
+ enable_bat_4_to_7();
+
+ /* External CC770 CAN controller available in version 2 */
+ calc_dbat_regvals(
+ &dbat,
+ 0xf2000000,
+ 128 * 1024,
+ false,
+ true,
+ false,
+ true,
+ BPP_RW
+ );
+ SET_DBAT(4, dbat.batu, dbat.batl);
+#elif defined(MPC5200_BOARD_BRS5L)
+ calc_dbat_regvals(
+ &dbat,
+ (uint32_t) bsp_dpram_start,
+ 128 * 1024,
+ false,
+ true,
+ false,
+ true,
+ BPP_RW
+ );
+ SET_DBAT(3,dbat.batu,dbat.batl);
+#elif defined(MPC5200_BOARD_BRS6L)
+ enable_bat_4_to_7();
+
+ /* FPGA */
+ calc_dbat_regvals(
+ &dbat,
+ MPC5200_BRS6L_FPGA_BEGIN,
+ MPC5200_BRS6L_FPGA_SIZE,
+ false,
+ true,
+ false,
+ true,
+ BPP_RW
+ );
+ SET_DBAT(3,dbat.batu,dbat.batl);
+
+ /* MRAM */
+ calc_dbat_regvals(
+ &dbat,
+ MPC5200_BRS6L_MRAM_BEGIN,
+ MPC5200_BRS6L_MRAM_SIZE,
+ true,
+ false,
+ false,
+ false,
+ BPP_RW
+ );
+ SET_DBAT(4,dbat.batu,dbat.batl);
+#endif
+}
+
+void cpu_init(void)
+{
+ uint32_t msr;
+
+ #if BSP_INSTRUCTION_CACHE_ENABLED
+ rtems_cache_enable_instruction();
+ #endif
+
+ /* Set up DBAT registers in MMU */
+ cpu_init_bsp();
+
+ #if defined(SHOW_MORE_INIT_SETTINGS)
+ { extern void ShowBATS(void);
+ ShowBATS();
+ }
+ #endif
+
+ /* Read MSR */
+ msr = ppc_machine_state_register();
+
+ /* Enable data MMU in MSR */
+ msr |= MSR_DR;
+
+ /* Update MSR */
+ ppc_set_machine_state_register( msr);
+
+ #if BSP_DATA_CACHE_ENABLED
+ rtems_cache_enable_data();
+ #endif
+}
diff --git a/bsps/powerpc/gen5200/start/linkcmds.brs5l b/bsps/powerpc/gen5200/start/linkcmds.brs5l
new file mode 100644
index 0000000000..58407e5f56
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/linkcmds.brs5l
@@ -0,0 +1,15 @@
+/**
+ * @file
+ *
+ * Linker command file for the BRS5L board.
+ */
+
+MEMORY {
+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 128M - 4k
+ ROM : ORIGIN = 0xffe00000, LENGTH = 2M
+ DPRAM : ORIGIN = 0xff000000, LENGTH = 1k
+ REGS : ORIGIN = 0xf0000000, LENGTH = 64k
+}
+
+INCLUDE linkcmds.gen5200_base
diff --git a/bsps/powerpc/gen5200/start/linkcmds.brs6l b/bsps/powerpc/gen5200/start/linkcmds.brs6l
new file mode 100644
index 0000000000..ae80a72ad5
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/linkcmds.brs6l
@@ -0,0 +1,15 @@
+/**
+ * @file
+ *
+ * Linker command file for the BRS6L board.
+ */
+
+MEMORY {
+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 128M - 4k
+ ROM : ORIGIN = 0xff800000, LENGTH = 8M
+ DPRAM : ORIGIN = 0xff000000, LENGTH = 0
+ REGS : ORIGIN = 0xf0000000, LENGTH = 64k
+}
+
+INCLUDE linkcmds.gen5200_base
diff --git a/bsps/powerpc/gen5200/start/linkcmds.dp2 b/bsps/powerpc/gen5200/start/linkcmds.dp2
new file mode 100644
index 0000000000..4ad76d6fce
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/linkcmds.dp2
@@ -0,0 +1,15 @@
+/**
+ * @file
+ *
+ * Linker command file for the Direct Prototyping Data Processing board.
+ */
+
+MEMORY {
+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 64M - 4k
+ ROM : ORIGIN = 0xffe00000, LENGTH = 2M
+ REGS : ORIGIN = 0xf0000000, LENGTH = 64k
+ DPRAM : ORIGIN = 0x0, LENGTH = 0
+}
+
+INCLUDE linkcmds.gen5200_base
diff --git a/bsps/powerpc/gen5200/start/linkcmds.gen5200_base b/bsps/powerpc/gen5200/start/linkcmds.gen5200_base
new file mode 100644
index 0000000000..1a92c7c9dd
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/linkcmds.gen5200_base
@@ -0,0 +1,357 @@
+/**
+ * @file
+ *
+ * Derived from internal linker script of GNU ld (GNU Binutils) 2.18 for elf32ppc emulation.
+ */
+
+OUTPUT_FORMAT ("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+OUTPUT_ARCH (powerpc)
+ENTRY (start)
+STARTUP (start.o)
+
+bsp_ram_start = ORIGIN (RAM);
+bsp_ram_end = ORIGIN (RAM) + LENGTH (RAM);
+bsp_ram_size = LENGTH (RAM);
+
+bsp_rom_start = ORIGIN (ROM);
+bsp_rom_end = ORIGIN (ROM) + LENGTH (ROM);
+bsp_rom_size = LENGTH (ROM);
+
+bsp_dpram_start = ORIGIN (DPRAM);
+bsp_dpram_end = ORIGIN (DPRAM) + LENGTH (DPRAM);
+bsp_dpram_size = LENGTH (DPRAM);
+
+bsp_section_align = 32;
+
+RamBase = bsp_ram_start;
+RamSize = bsp_ram_size;
+HeapSize = DEFINED(HeapSize) ? HeapSize : 0x0;
+
+MEMORY {
+ UNEXPECTED_SECTIONS : ORIGIN = 0xffffffff, LENGTH = 0
+}
+
+SECTIONS {
+ /*
+ * BSP: MPC5200 registers
+ */
+ .regs (NOLOAD) : {
+ MBAR = .;
+ mpc5200 = .;
+ } > REGS
+
+ /*
+ * BSP: Exception vectors
+ */
+ .vectors 0x100 : {
+ *(.vectors)
+ } > RAM
+
+ /*
+ * BSP: The initial stack will live in this area - between the vectors
+ * and the text section.
+ */
+
+ .text 0x10000 : {
+ /*
+ * BSP: Start of text section
+ */
+ bsp_section_text_start = .;
+
+ /*
+ * BSP: System startup entry
+ */
+ KEEP (*(.entry))
+
+ /*
+ * BSP: Moved into .text from .init
+ */
+ KEEP (*(.init))
+
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ KEEP (*(.text.*personality*))
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.glink)
+
+ /*
+ * BSP: Special FreeBSD sysctl sections
+ */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ /*
+ * BSP: Moved into .text from .*
+ */
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ KEEP (*(SORT(.rtemsroset.*)))
+ *(.rodata1)
+ *(.interp)
+ *(.note.gnu.build-id)
+ *(.hash)
+ *(.gnu.hash)
+ *(.dynsym)
+ *(.dynstr)
+ *(.gnu.version)
+ *(.gnu.version_d)
+ *(.gnu.version_r)
+ *(.eh_frame_hdr)
+
+ /*
+ * BSP: Magic PPC stuff
+ */
+ *(.PPC.*)
+
+ /*
+ * BSP: Required by cpukit/score/src/threadhandler.c
+ */
+ PROVIDE (_fini = .);
+
+ /*
+ * BSP: Moved into .text from .fini
+ */
+ KEEP (*(.fini))
+
+ . = ALIGN (bsp_section_align);
+
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ } > RAM
+
+ .tdata : {
+ _TLS_Data_begin = .;
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ _TLS_Data_end = .;
+ } > RAM
+ .tbss : {
+ _TLS_BSS_begin = .;
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ _TLS_BSS_end = .;
+ } > RAM
+ _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));
+
+ .sdata2 : {
+ PROVIDE (_SDA2_BASE_ = 32768);
+
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+
+ . = ALIGN (bsp_section_align);
+ } > RAM
+
+ .sbss2 : {
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+
+ . = ALIGN (bsp_section_align);
+
+ /*
+ * BSP: End of text section
+ */
+ bsp_section_text_end = .;
+ } > RAM
+
+ .data : {
+ /*
+ * BSP: Start of data section
+ */
+ bsp_section_data_start = .;
+
+ /*
+ * BSP: Moved into .data from .ctors
+ */
+ /* 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))
+
+ /*
+ * BSP: Moved into .data from .dtors
+ */
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+
+ /*
+ * BSP: Moved into .data from .*
+ */
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ *(.data1)
+ KEEP (*(.eh_frame))
+ *(.gcc_except_table .gcc_except_table.*)
+ KEEP (*(.jcr))
+ *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*)
+ *(.fixup)
+ *(.got1)
+ *(.got2)
+ *(.dynamic)
+ *(.got)
+ *(.plt)
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.data .data.* .gnu.linkonce.d.*)
+ KEEP (*(SORT(.rtemsrwset.*)))
+ KEEP (*(.gnu.linkonce.d.*personality*))
+ SORT(CONSTRUCTORS)
+
+ . = ALIGN (bsp_section_align);
+ } > RAM
+
+ .sdata : {
+ PROVIDE (_SDA_BASE_ = 32768);
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+
+ . = ALIGN (bsp_section_align);
+
+ _edata = .;
+ PROVIDE (edata = .);
+
+ /*
+ * BSP: End of data section
+ */
+ bsp_section_data_end = .;
+ } > RAM
+
+ .sbss : {
+ /*
+ * BSP: Start of bss section
+ */
+ bsp_section_bss_start = .;
+
+ __bss_start = .;
+
+ PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);
+ *(.scommon)
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);
+
+ . = ALIGN (bsp_section_align);
+ } > RAM
+
+ .bss : {
+ *(COMMON)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+
+ . = ALIGN (bsp_section_align);
+
+ __end = .;
+ _end = .;
+ PROVIDE (end = .);
+
+ /*
+ * BSP: End of bss section
+ */
+ bsp_section_bss_end = .;
+ } > RAM
+
+ /*
+ * BSP: Section sizes
+ */
+ bsp_section_text_size = bsp_section_text_end - bsp_section_text_start;
+ bsp_section_data_size = bsp_section_data_end - bsp_section_data_start;
+ bsp_section_bss_size = bsp_section_bss_end - bsp_section_bss_start;
+
+ /*
+ * BSP: Interrupt stack
+ */
+ bsp_interrupt_stack_start = bsp_section_bss_end;
+ bsp_interrupt_stack_end = bsp_interrupt_stack_start + 32k;
+ bsp_interrupt_stack_size = bsp_interrupt_stack_end - bsp_interrupt_stack_start;
+
+ /*
+ * BSP: Work area start
+ */
+ bsp_work_area_start = bsp_interrupt_stack_end;
+ WorkAreaBase = bsp_work_area_start;
+
+ /* 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) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+
+ /DISCARD/ : {
+ *(.note.GNU-stack) *(.gnu_debuglink)
+ }
+
+ /*
+ * 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/powerpc/gen5200/start/linkcmds.icecube b/bsps/powerpc/gen5200/start/linkcmds.icecube
new file mode 100644
index 0000000000..c05d45a852
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/linkcmds.icecube
@@ -0,0 +1,15 @@
+/**
+ * @file
+ *
+ * Linker command file for the IceCube board.
+ */
+
+MEMORY {
+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 128M - 4k
+ ROM : ORIGIN = 0xffe00000, LENGTH = 2M
+ REGS : ORIGIN = 0xf0000000, LENGTH = 64k
+ DPRAM : ORIGIN = 0x0, LENGTH = 0
+}
+
+INCLUDE linkcmds.gen5200_base
diff --git a/bsps/powerpc/gen5200/start/linkcmds.pm520_cr825 b/bsps/powerpc/gen5200/start/linkcmds.pm520_cr825
new file mode 100644
index 0000000000..49d596b577
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/linkcmds.pm520_cr825
@@ -0,0 +1,15 @@
+/**
+ * @file
+ *
+ * Linker command file for the MicroSys PM520 board.
+ */
+
+MEMORY {
+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 64M - 4k
+ ROM : ORIGIN = 0xffe00000, LENGTH = 2M
+ REGS : ORIGIN = 0xf0000000, LENGTH = 64k
+ DPRAM : ORIGIN = 0xff000000, LENGTH = 1k
+}
+
+INCLUDE linkcmds.gen5200_base
diff --git a/bsps/powerpc/gen5200/start/linkcmds.pm520_ze30 b/bsps/powerpc/gen5200/start/linkcmds.pm520_ze30
new file mode 100644
index 0000000000..49d596b577
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/linkcmds.pm520_ze30
@@ -0,0 +1,15 @@
+/**
+ * @file
+ *
+ * Linker command file for the MicroSys PM520 board.
+ */
+
+MEMORY {
+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 64M - 4k
+ ROM : ORIGIN = 0xffe00000, LENGTH = 2M
+ REGS : ORIGIN = 0xf0000000, LENGTH = 64k
+ DPRAM : ORIGIN = 0xff000000, LENGTH = 1k
+}
+
+INCLUDE linkcmds.gen5200_base
diff --git a/bsps/powerpc/gen5200/start/uboot_support.c b/bsps/powerpc/gen5200/start/uboot_support.c
new file mode 100644
index 0000000000..f373f558e7
--- /dev/null
+++ b/bsps/powerpc/gen5200/start/uboot_support.c
@@ -0,0 +1,23 @@
+/*
+ * This file contains variables which assist the shared
+ * U-Boot code.
+ *
+ * COPYRIGHT (c) 1989-2008.
+ * 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 <stdint.h>
+
+#include <bsp.h>
+
+#if defined(HAS_UBOOT)
+/* Base address of U-Boot environment variables */
+const uint8_t *uboot_environment = (const uint8_t *)0xfff40000;
+
+/* Length of area reserved for U-Boot environment variables */
+const size_t uboot_environment_size = 0x10000;
+#endif
diff --git a/bsps/powerpc/gen83xx/start/bsp_specs b/bsps/powerpc/gen83xx/start/bsp_specs
new file mode 100644
index 0000000000..a37ec281c8
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s -u __vectors}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/gen83xx/start/bspreset.c b/bsps/powerpc/gen83xx/start/bspreset.c
new file mode 100644
index 0000000000..ebaf9f129f
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/bspreset.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2008
+ * 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 <bsp.h>
+#include <bsp/bootcard.h>
+
+#include <mpc83xx/mpc83xx.h>
+
+void bsp_reset(void)
+{
+ mpc83xx_reset();
+}
diff --git a/bsps/powerpc/gen83xx/start/bsprestart.c b/bsps/powerpc/gen83xx/start/bsprestart.c
new file mode 100644
index 0000000000..4a2d298de0
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/bsprestart.c
@@ -0,0 +1,47 @@
+/*
+ * 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 <bsp.h>
+#include <bsp/u-boot.h>
+
+#include <libcpu/powerpc-utility.h>
+
+void bsp_restart(void *addr)
+{
+ rtems_interrupt_level level;
+ void (*start)(void) = addr;
+ #ifdef HAS_UBOOT
+ const void *mem_begin = (const void *) bsp_uboot_board_info.bi_memstart;
+ size_t mem_size = bsp_uboot_board_info.bi_memsize;
+ #else /* HAS_UBOOT */
+ const void *mem_begin = bsp_ram_start;
+ size_t mem_size = (size_t) bsp_ram_size;
+ #endif /* HAS_UBOOT */
+ uint32_t hid0;
+
+ rtems_interrupt_disable(level);
+ (void) level; /* avoid set but not used warning */
+
+ hid0 = PPC_SPECIAL_PURPOSE_REGISTER(HID0);
+
+ if ((hid0 & HID0_DCE) != 0) {
+ rtems_cache_flush_multiple_data_lines(mem_begin, mem_size);
+ }
+
+ hid0 &= ~(HID0_DCE | HID0_ICE);
+
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(HID0, hid0);
+
+ (*start)();
+}
diff --git a/bsps/powerpc/gen83xx/start/bspstart.c b/bsps/powerpc/gen83xx/start/bspstart.c
new file mode 100644
index 0000000000..cd729a8e17
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/bspstart.c
@@ -0,0 +1,129 @@
+/**
+ * @file
+ *
+ * @ingroup mpc83xx
+ *
+ * @brief Source for BSP startup code.
+ */
+
+/*
+ * Copyright (c) 2008-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/counter.h>
+
+#include <libchip/ns16550.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/vectors.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/u-boot.h>
+#include <bsp/console-termios.h>
+
+/* Configuration parameters for console driver, ... */
+unsigned int BSP_bus_frequency;
+
+/* Configuration parameter for clock driver */
+uint32_t bsp_time_base_frequency;
+
+/* Legacy */
+uint32_t bsp_clicks_per_usec;
+
+/* Default decrementer exception handler */
+static int mpc83xx_decrementer_exception_handler( BSP_Exception_frame *frame, unsigned number)
+{
+ ppc_set_decrementer_register(UINT32_MAX);
+
+ return 0;
+}
+
+void bsp_start( void)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ unsigned long i = 0;
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
+ * store the result in global variables so that it can be used latter...
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ /* Basic CPU initialization */
+ cpu_init();
+
+ /*
+ * Enable instruction and data caches. Do not force writethrough mode.
+ */
+
+#ifdef BSP_INSTRUCTION_CACHE_ENABLED
+ rtems_cache_enable_instruction();
+#endif
+
+#ifdef BSP_DATA_CACHE_ENABLED
+ rtems_cache_enable_data();
+#endif
+
+ /*
+ * This is evaluated during runtime, so it should be ok to set it
+ * before we initialize the drivers.
+ */
+
+ /* Initialize some device driver parameters */
+
+#ifdef HAS_UBOOT
+ BSP_bus_frequency = bsp_uboot_board_info.bi_busfreq;
+#else /* HAS_UBOOT */
+ BSP_bus_frequency = BSP_CLKIN_FRQ * BSP_SYSPLL_MF / BSP_SYSPLL_CKID;
+#endif /* HAS_UBOOT */
+ bsp_time_base_frequency = BSP_bus_frequency / 4;
+ bsp_clicks_per_usec = bsp_time_base_frequency / 1000000;
+ rtems_counter_initialize_converter(bsp_time_base_frequency);
+
+ /* Initialize some console parameters */
+ for (i = 0; i < console_device_count; ++i) {
+ ns16550_context *ctx = (ns16550_context *) console_device_table[i].context;
+
+ ctx->clock = BSP_bus_frequency;
+
+ #ifdef HAS_UBOOT
+ ctx->initial_baud = bsp_uboot_board_info.bi_baudrate;
+ #endif
+ }
+
+ /* Initialize exception handler */
+#ifndef BSP_DATA_CACHE_ENABLED
+ ppc_exc_cache_wb_check = 0;
+#endif
+ ppc_exc_initialize(
+ (uintptr_t) bsp_section_work_begin,
+ rtems_configuration_get_interrupt_stack_size()
+ );
+
+ /* Install default handler for the decrementer exception */
+ sc = ppc_exc_set_handler( ASM_DEC_VECTOR, mpc83xx_decrementer_exception_handler);
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_panic("cannot install decrementer exception handler");
+ }
+
+ /* Initalize interrupt support */
+ bsp_interrupt_initialize();
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Exit from bspstart\n");
+#endif
+}
diff --git a/bsps/powerpc/gen83xx/start/cpuinit.c b/bsps/powerpc/gen83xx/start/cpuinit.c
new file mode 100644
index 0000000000..1b0fd1efef
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/cpuinit.c
@@ -0,0 +1,329 @@
+/*===============================================================*\
+| Project: RTEMS generic MPC83xx BSP |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below. |
+| Adaptions, modifications, enhancements and any recent parts of |
+| the code are: |
+| Copyright (c) 2005 |
+| 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. |
+| |
++-----------------------------------------------------------------+
+| this file contains the code to initialize the cpu |
+\*===============================================================*/
+
+
+/***********************************************************************/
+/* */
+/* Module: cpuinit.c */
+/* Date: 07/17/2003 */
+/* Purpose: RTEMS MPC5x00 C level startup code */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Description: This file contains additional functions for */
+/* initializing the MPC5x00 CPU */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Code */
+/* References: MPC8260ads additional CPU initialization */
+/* Module: cpuinit.c */
+/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */
+/* Version 1.1 */
+/* Date: 10/22/2002 */
+/* */
+/* Author(s) / Copyright(s): */
+/* */
+/* Written by Jay Monkman (jmonkman@frasca.com) */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Partially based on the code references which are named above. */
+/* Adaptions, modifications, enhancements and any recent parts of */
+/* the code are under the right of */
+/* */
+/* IPR Engineering, Dachauer Straße 38, D-80335 München */
+/* Copyright(C) 2003 */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* IPR Engineering makes no representation or warranties with */
+/* respect to the performance of this computer program, and */
+/* specifically disclaims any responsibility for any damages, */
+/* special or consequential, connected with the use of this program. */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* Version history: 1.0 */
+/* */
+/***********************************************************************/
+
+#include <stdbool.h>
+#include <string.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <libcpu/mmu.h>
+
+#include <mpc83xx/mpc83xx.h>
+
+#include <bsp.h>
+#include <bsp/u-boot.h>
+
+#define SET_DBAT( n, uv, lv) \
+ do { \
+ PPC_SET_SPECIAL_PURPOSE_REGISTER( DBAT##n##L, lv); \
+ PPC_SET_SPECIAL_PURPOSE_REGISTER( DBAT##n##U, uv); \
+ } while (0)
+
+#define SET_IBAT( n, uv, lv) \
+ do { \
+ PPC_SET_SPECIAL_PURPOSE_REGISTER( IBAT##n##L, lv); \
+ PPC_SET_SPECIAL_PURPOSE_REGISTER( IBAT##n##U, uv); \
+ } while (0)
+
+static void calc_dbat_regvals(
+ BAT *bat_ptr,
+ uint32_t base_addr,
+ uint32_t size,
+ bool flg_w,
+ bool flg_i,
+ bool flg_m,
+ bool flg_g,
+ uint32_t flg_bpp
+)
+{
+ uint32_t block_mask = 0xffffffff;
+ uint32_t end_addr = base_addr + size - 1;
+
+ /* Determine block mask, that overlaps the whole block */
+ while ((end_addr & block_mask) != (base_addr & block_mask)) {
+ block_mask <<= 1;
+ }
+
+ bat_ptr->batu.bepi = base_addr >> (32 - 15);
+ bat_ptr->batu.bl = ~(block_mask >> (28 - 11));
+ bat_ptr->batu.vs = 1;
+ bat_ptr->batu.vp = 1;
+
+ bat_ptr->batl.brpn = base_addr >> (32 - 15);
+ bat_ptr->batl.w = flg_w;
+ bat_ptr->batl.i = flg_i;
+ bat_ptr->batl.m = flg_m;
+ bat_ptr->batl.g = flg_g;
+ bat_ptr->batl.pp = flg_bpp;
+}
+
+static void clear_mmu_regs( void)
+{
+ uint32_t i;
+
+ /* Clear segment registers */
+ for (i = 0;i < 16;i++) {
+ __asm__ volatile( "mtsrin %0, %1\n" : : "r" (i * 0x1000), "r" (i << (31 - 3)));
+ }
+
+ /* Clear TLBs */
+ for (i = 0;i < 32;i++) {
+ __asm__ volatile( "tlbie %0\n" : : "r" (i << (31 - 19)));
+ }
+}
+
+void cpu_init( void)
+{
+ BAT dbat, ibat;
+ uint32_t msr;
+ uint32_t hid0;
+
+ /* Clear MMU and segment registers */
+ clear_mmu_regs();
+
+ /* Clear caches */
+ hid0 = PPC_SPECIAL_PURPOSE_REGISTER(HID0);
+ if ((hid0 & (HID0_ICE | HID0_DCE)) == 0) {
+ hid0 &= ~(HID0_ILOCK | HID0_DLOCK | HID0_ICE | HID0_DCE);
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(HID0, hid0);
+ hid0 |= HID0_ICFI | HID0_DCI;
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(HID0, hid0);
+ hid0 &= ~(HID0_ICFI | HID0_DCI);
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(HID0, hid0);
+ }
+
+ /*
+ * Set up IBAT registers in MMU
+ */
+
+ memset(&ibat, 0, sizeof( ibat));
+ SET_IBAT( 2, ibat.batu, ibat.batl);
+ SET_IBAT( 3, ibat.batu, ibat.batl);
+ SET_IBAT( 4, ibat.batu, ibat.batl);
+ SET_IBAT( 5, ibat.batu, ibat.batl);
+ SET_IBAT( 6, ibat.batu, ibat.batl);
+ SET_IBAT( 7, ibat.batu, ibat.batl);
+
+ calc_dbat_regvals(
+ &ibat,
+ #ifdef HAS_UBOOT
+ bsp_uboot_board_info.bi_memstart,
+ bsp_uboot_board_info.bi_memsize,
+ #else /* HAS_UBOOT */
+ (uint32_t) bsp_ram_start,
+ (uint32_t) bsp_ram_size,
+ #endif /* HAS_UBOOT */
+ false,
+ false,
+ false,
+ false,
+ BPP_RX
+ );
+ SET_IBAT( 0, ibat.batu, ibat.batl);
+
+ calc_dbat_regvals(
+ &ibat,
+ #ifdef HAS_UBOOT
+ bsp_uboot_board_info.bi_flashstart,
+ bsp_uboot_board_info.bi_flashsize,
+ #else /* HAS_UBOOT */
+ (uint32_t) bsp_rom_start,
+ (uint32_t) bsp_rom_size,
+ #endif /* HAS_UBOOT */
+ false,
+ false,
+ false,
+ false,
+ BPP_RX
+ );
+ SET_IBAT( 1, ibat.batu, ibat.batl);
+
+ /*
+ * Set up DBAT registers in MMU
+ */
+
+ memset(&dbat, 0, sizeof( dbat));
+ SET_DBAT( 3, dbat.batu, dbat.batl);
+ SET_DBAT( 4, dbat.batu, dbat.batl);
+ SET_DBAT( 5, dbat.batu, dbat.batl);
+ SET_DBAT( 6, dbat.batu, dbat.batl);
+ SET_DBAT( 7, dbat.batu, dbat.batl);
+
+ calc_dbat_regvals(
+ &dbat,
+ #ifdef HAS_UBOOT
+ bsp_uboot_board_info.bi_memstart,
+ bsp_uboot_board_info.bi_memsize,
+ #else /* HAS_UBOOT */
+ (uint32_t) bsp_ram_start,
+ (uint32_t) bsp_ram_size,
+ #endif /* HAS_UBOOT */
+ false,
+ false,
+ false,
+ false,
+ BPP_RW
+ );
+ SET_DBAT( 0, dbat.batu, dbat.batl);
+
+ calc_dbat_regvals(
+ &dbat,
+ #ifdef HAS_UBOOT
+ bsp_uboot_board_info.bi_flashstart,
+ bsp_uboot_board_info.bi_flashsize,
+ #else /* HAS_UBOOT */
+ (uint32_t) bsp_rom_start,
+ (uint32_t) bsp_rom_size,
+ #endif /* HAS_UBOOT */
+ #ifdef MPC83XX_HAS_NAND_LP_FLASH_ON_CS0
+ false,
+ true,
+ false,
+ true,
+ BPP_RW
+ #else
+ true,
+ false,
+ false,
+ false,
+ BPP_RX
+ #endif
+ );
+ SET_DBAT( 1, dbat.batu, dbat.batl);
+
+ calc_dbat_regvals(
+ &dbat,
+ #ifdef HAS_UBOOT
+ bsp_uboot_board_info.bi_immrbar,
+ #else /* HAS_UBOOT */
+ (uint32_t) IMMRBAR,
+ #endif /* HAS_UBOOT */
+ #if MPC83XX_CHIP_TYPE / 10 == 830
+ 2 * 1024 * 1024,
+ #else
+ 1024 * 1024,
+ #endif
+ false,
+ true,
+ false,
+ true,
+ BPP_RW
+ );
+ SET_DBAT( 2, dbat.batu, dbat.batl);
+
+#if defined(MPC83XX_BOARD_HSC_CM01)
+ calc_dbat_regvals(
+ &dbat,
+ FPGA_START,
+ FPGA_SIZE,
+ true,
+ true,
+ true,
+ false,
+ BPP_RW
+ );
+ SET_DBAT(3,dbat.batu,dbat.batl);
+#endif
+
+#ifdef MPC83XX_BOARD_MPC8313ERDB
+ /* Enhanced Local Bus Controller (eLBC) */
+ calc_dbat_regvals(
+ &dbat,
+ 0xfa000000,
+ 128 * 1024,
+ false,
+ true,
+ false,
+ true,
+ BPP_RW
+ );
+ SET_DBAT( 3, dbat.batu, dbat.batl);
+#endif /* MPC83XX_BOARD_MPC8313ERDB */
+
+ /* Read MSR */
+ msr = ppc_machine_state_register();
+
+ /* Enable data and instruction MMU in MSR */
+ msr |= MSR_DR | MSR_IR;
+
+ /* Enable FPU in MSR */
+ msr |= MSR_FP;
+
+ /* Update MSR */
+ ppc_set_machine_state_register( msr);
+
+ /*
+ * In HID0:
+ * - Enable dynamic power management
+ * - Enable machine check interrupts
+ */
+ PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( HID0, HID0_EMCP | HID0_DPM);
+
+ /* Enable timebase clock */
+ mpc83xx.syscon.spcr |= M83xx_SYSCON_SPCR_TBEN;
+}
diff --git a/bsps/powerpc/gen83xx/start/linkcmds b/bsps/powerpc/gen83xx/start/linkcmds
new file mode 100644
index 0000000000..094fdf51af
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/linkcmds
@@ -0,0 +1,19 @@
+/**
+ * @file
+ *
+ * Default linker script -- copy of linkcmds.mpc8313erdb
+ * for MPC8313E Reference Design Board.
+ *
+ * This exists simply for consistency so autoconf tests will
+ * be able to compile against this BSP.
+ */
+
+EXTERN (__vectors)
+
+MEMORY {
+ RAM : ORIGIN = 0x0, LENGTH = 128M
+ ROM : ORIGIN = 0xfe000000, LENGTH = 8M
+ MPC83XX_REGS : ORIGIN = 0xe0000000, LENGTH = 256k
+}
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/gen83xx/start/linkcmds.br_uid b/bsps/powerpc/gen83xx/start/linkcmds.br_uid
new file mode 100644
index 0000000000..3d8c3a154a
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/linkcmds.br_uid
@@ -0,0 +1,10 @@
+MEMORY {
+ RESCONF : ORIGIN = 0x0, LENGTH = 0x100
+ VECTORS : ORIGIN = 0x100, LENGTH = 0x10000 - 0x100
+ WORK : ORIGIN = 0x10000, LENGTH = 256M - 0x10000
+ ROM : ORIGIN = 0xfe000000, LENGTH = 2M
+}
+
+REGION_ALIAS ("START", WORK);
+
+INCLUDE linkcmds.mpc83xx
diff --git a/bsps/powerpc/gen83xx/start/linkcmds.hsc_cm01 b/bsps/powerpc/gen83xx/start/linkcmds.hsc_cm01
new file mode 100644
index 0000000000..d5b4b1e145
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/linkcmds.hsc_cm01
@@ -0,0 +1,10 @@
+MEMORY {
+ RESCONF : ORIGIN = 0x0, LENGTH = 0x100
+ VECTORS : ORIGIN = 0x100, LENGTH = 0x10000 - 0x100
+ WORK : ORIGIN = 0x10000, LENGTH = 256M - 0x10000
+ ROM : ORIGIN = 0xfe000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("START", WORK);
+
+INCLUDE linkcmds.mpc83xx
diff --git a/bsps/powerpc/gen83xx/start/linkcmds.mpc8309som b/bsps/powerpc/gen83xx/start/linkcmds.mpc8309som
new file mode 100644
index 0000000000..d5b4b1e145
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/linkcmds.mpc8309som
@@ -0,0 +1,10 @@
+MEMORY {
+ RESCONF : ORIGIN = 0x0, LENGTH = 0x100
+ VECTORS : ORIGIN = 0x100, LENGTH = 0x10000 - 0x100
+ WORK : ORIGIN = 0x10000, LENGTH = 256M - 0x10000
+ ROM : ORIGIN = 0xfe000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("START", WORK);
+
+INCLUDE linkcmds.mpc83xx
diff --git a/bsps/powerpc/gen83xx/start/linkcmds.mpc8313erdb b/bsps/powerpc/gen83xx/start/linkcmds.mpc8313erdb
new file mode 100644
index 0000000000..717b3b4866
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/linkcmds.mpc8313erdb
@@ -0,0 +1,10 @@
+MEMORY {
+ RESCONF : ORIGIN = 0x0, LENGTH = 0x100
+ VECTORS : ORIGIN = 0x100, LENGTH = 0x10000 - 0x100
+ WORK : ORIGIN = 0x10000, LENGTH = 128M - 0x10000
+ ROM : ORIGIN = 0xfe000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("START", WORK);
+
+INCLUDE linkcmds.mpc83xx
diff --git a/bsps/powerpc/gen83xx/start/linkcmds.mpc8349eamds b/bsps/powerpc/gen83xx/start/linkcmds.mpc8349eamds
new file mode 100644
index 0000000000..d5b4b1e145
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/linkcmds.mpc8349eamds
@@ -0,0 +1,10 @@
+MEMORY {
+ RESCONF : ORIGIN = 0x0, LENGTH = 0x100
+ VECTORS : ORIGIN = 0x100, LENGTH = 0x10000 - 0x100
+ WORK : ORIGIN = 0x10000, LENGTH = 256M - 0x10000
+ ROM : ORIGIN = 0xfe000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("START", WORK);
+
+INCLUDE linkcmds.mpc83xx
diff --git a/bsps/powerpc/gen83xx/start/linkcmds.mpc83xx b/bsps/powerpc/gen83xx/start/linkcmds.mpc83xx
new file mode 100644
index 0000000000..4ddbcd6f76
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/linkcmds.mpc83xx
@@ -0,0 +1,47 @@
+bsp_ram_start = ORIGIN (RESCONF);
+bsp_ram_end = ORIGIN (WORK) + LENGTH (WORK);
+bsp_ram_size = bsp_ram_end - bsp_ram_start;
+
+bsp_rom_start = ORIGIN (ROM);
+bsp_rom_size = LENGTH (ROM);
+bsp_rom_end = bsp_rom_start + bsp_rom_size;
+
+IMMRBAR = 0xe0000000;
+mpc83xx = IMMRBAR;
+
+EXTERN (__vectors)
+
+MEMORY {
+ EMPTY : ORIGIN = 0x0, LENGTH = 0
+}
+
+SECTIONS {
+ .resconf : {
+ *(.resconf)
+ } > RESCONF AT > RESCONF
+
+ .vectors : {
+ *(.vectors)
+ } > VECTORS AT > VECTORS
+}
+
+REGION_ALIAS ("REGION_START", START);
+REGION_ALIAS ("REGION_FAST_TEXT", WORK);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", WORK);
+REGION_ALIAS ("REGION_TEXT", WORK);
+REGION_ALIAS ("REGION_TEXT_LOAD", WORK);
+REGION_ALIAS ("REGION_RODATA", WORK);
+REGION_ALIAS ("REGION_RODATA_LOAD", WORK);
+REGION_ALIAS ("REGION_FAST_DATA", WORK);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", WORK);
+REGION_ALIAS ("REGION_DATA", WORK);
+REGION_ALIAS ("REGION_DATA_LOAD", WORK);
+REGION_ALIAS ("REGION_BSS", WORK);
+REGION_ALIAS ("REGION_RWEXTRA", WORK);
+REGION_ALIAS ("REGION_WORK", WORK);
+REGION_ALIAS ("REGION_STACK", WORK);
+REGION_ALIAS ("REGION_NOCACHE", EMPTY);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", EMPTY);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/gen83xx/start/uboot_support.c b/bsps/powerpc/gen83xx/start/uboot_support.c
new file mode 100644
index 0000000000..295059889d
--- /dev/null
+++ b/bsps/powerpc/gen83xx/start/uboot_support.c
@@ -0,0 +1,24 @@
+/*
+ * This file contains variables which assist the shared
+ * U-Boot code.
+ *
+ * COPYRIGHT (c) 1989-2008.
+ * 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 <stdint.h>
+
+#include <bsp.h>
+
+#if defined(HAS_UBOOT)
+/* XXX TODO fill in with real information */
+/* Base address of U-Boot environment variables */
+const uint8_t *uboot_environment = (const uint8_t *) 0x00000000;
+
+/* Length of area reserved for U-Boot environment variables */
+const size_t *uboot_environment_size = (const size_t *) 0x00010000;
+#endif
diff --git a/bsps/powerpc/haleakala/start/bsp_specs b/bsps/powerpc/haleakala/start/bsp_specs
new file mode 100644
index 0000000000..5752caaca0
--- /dev/null
+++ b/bsps/powerpc/haleakala/start/bsp_specs
@@ -0,0 +1,10 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
+
diff --git a/bsps/powerpc/haleakala/start/bspstart.c b/bsps/powerpc/haleakala/start/bspstart.c
new file mode 100644
index 0000000000..18b45f33df
--- /dev/null
+++ b/bsps/powerpc/haleakala/start/bspstart.c
@@ -0,0 +1,195 @@
+/*
+ * This routine does the bulk of the system initialization.
+ */
+
+/*
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ * IMD Ingenieurbuero fuer Microcomputertechnik
+ *
+ * COPYRIGHT (c) 1998 by IMD
+ *
+ * Changes from IMD are covered by the original distributions terms.
+ * This file has been derived from the papyrus BSP:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Modifications for spooling console driver and control of memory layout
+ * with linker command file by
+ * Thomas Doerfler <td@imd.m.isar.de>
+ * for these modifications:
+ * COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies. IMD makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c:
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modifications for PPC405GP by Dennis Ehlin
+ *
+ * Further modified for the PPC405EX Haleakala board by
+ * Michael Hamel ADInstruments Ltd May 2008
+ */
+#include <string.h>
+#include <fcntl.h>
+
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/uart.h>
+#include <bsp/irq.h>
+#include <libcpu/powerpc-utility.h>
+#include <bsp/vectors.h>
+#include <ppc4xx/ppc405gp.h>
+#include <ppc4xx/ppc405ex.h>
+
+#include <stdio.h>
+
+LINKER_SYMBOL(intrStack_start);
+LINKER_SYMBOL(intrStack_size);
+/*
+ * Driver configuration parameters
+ */
+
+/* Expected by clock.c */
+uint32_t bsp_clicks_per_usec;
+
+/*-------------------- Haleakala-specific UART setup -------------------------*/
+
+static void
+EarlyUARTInit(int baudRate)
+{
+ volatile uint8_t* up = (uint8_t*)(BSP_UART_IOBASE_COM1);
+ int divider = BSP_UART_BAUD_BASE / baudRate;
+ up[LCR] = DLAB; /* Access DLM/DLL */
+ up[DLL] = divider & 0x0FF;
+ up[DLM] = divider >> 8;
+ up[LCR] = CHR_8_BITS;
+ up[MCR] = DTR | RTS;
+ up[FCR] = FIFO_EN | XMIT_RESET | RCV_RESET;
+ up[THR] = '+';
+}
+
+
+static void
+InitUARTClock(void)
+{
+ uint32_t reg;
+ mfsdr(SDR0_UART0,reg);
+ reg &= ~0x008000FF;
+ reg |= 0x00800001; /* Ext clock, div 1 */
+ mtsdr(SDR0_UART0,reg);
+}
+
+static void GPIO_AlternateSelect(int bitnum, int source)
+/* PPC405EX: select a GPIO function for the specified pin */
+{
+ int shift;
+ unsigned long value, mask;
+ GPIORegisters* gpioPtr = (GPIORegisters*)(GPIOAddress);
+
+ shift = (31 - bitnum) & 0xF;
+ value = (source & 3) << (shift*2);
+ mask = 3 << (shift*2);
+ if (bitnum <= 15) {
+ gpioPtr->OSRL = (gpioPtr->OSRL & ~mask) | value;
+ gpioPtr->TSRL = (gpioPtr->TSRL & ~mask) | value;
+ } else {
+ gpioPtr->OSRH = (gpioPtr->OSRH & ~mask) | value;
+ gpioPtr->TSRH = (gpioPtr->TSRH & ~mask) | value;
+ }
+}
+
+static void Init_FPGA(void)
+{
+ /* Have to write to the FPGA to enable the UART drivers */
+ /* Have to enable CS2 as an output in GPIO to get the FPGA working */
+ mtebc(EBC0_B2CR,0xF0018000); /* Set up CS2 at 0xF0000000 */
+ mtebc(EBC0_B2AP,0x9400C800);
+ GPIO_AlternateSelect(9,1); /* GPIO9 = PerCS2 */
+ {
+ unsigned long *fpgaPtr = (unsigned long*)(0xF0000000);
+ unsigned long n;
+ n = *(fpgaPtr);
+ n &= ~0x00100; /* User LEDs on */
+ n |= 0x30000; /* UART 0 and 1 transcievers on! */
+ *fpgaPtr = n;
+ }
+}
+
+/*===================================================================*/
+
+static void
+DirectUARTWrite(const char c)
+{
+ volatile uint8_t* up = (uint8_t*)(BSP_UART_IOBASE_COM1);
+ while ((up[LSR] & THRE) == 0) { ; }
+ up[THR] = c;
+}
+
+/* We will provide our own printk output function as it may get used early */
+BSP_output_char_function_type BSP_output_char = DirectUARTWrite;
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
+
+/*===================================================================*/
+
+void bsp_start( void )
+{
+ /* Get the UART clock initialized first in case we call printk */
+
+ InitUARTClock();
+ Init_FPGA();
+ EarlyUARTInit(115200);
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function store the result in global variables
+ * so that it can be used later...
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ /*
+ * initialize the device driver parameters
+ */
+
+ /* Set globals visible to clock.c */
+ /* timebase register ticks/microsecond = CPU Clk in MHz */
+ bsp_clicks_per_usec = 400;
+ rtems_counter_initialize_converter(bsp_clicks_per_usec * 1000000);
+
+ /*
+ * Initialize default raw exception handlers.
+ */
+ ppc_exc_initialize(
+ (uintptr_t) intrStack_start,
+ (uintptr_t) intrStack_size
+ );
+
+ /*
+ * Install our own set of exception vectors
+ */
+ BSP_rtems_irq_mng_init(0);
+}
diff --git a/bsps/powerpc/haleakala/start/linkcmds b/bsps/powerpc/haleakala/start/linkcmds
new file mode 100644
index 0000000000..8c06a5103b
--- /dev/null
+++ b/bsps/powerpc/haleakala/start/linkcmds
@@ -0,0 +1,277 @@
+/*
+ * This file contains directives for the GNU linker which are specific
+ * to the 405GP/EX
+ * This file is intended to be used together with dlentry.s
+ * it will generate downloadable code
+ *
+ * Modifications for gen405 by Dennis Ehlin
+ * Modifications for virtex by Keith, Greg, and Bob
+ * Modifications for 405GP/EX by Michael Hamel
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+ENTRY(download_entry)
+EXTERN(__vectors)
+
+kIntrStackSize = 16K;
+kMainStackSize = 64K;
+
+RamBase = DEFINED(RamBase) ? RamBase : 0;
+RamSize = DEFINED(RamSize) ? RamSize : 256M;
+HeapSize = DEFINED(HeapSize) ? HeapSize : 0x0;
+
+MEMORY {
+ RAM : ORIGIN = 0, LENGTH = 256M
+ /*FLASH : ORIGIN = 0xFFE00000, LENGTH = 16M*/
+}
+
+
+SECTIONS
+{
+ /* First 16K is occupied by exception vectors and anything else we want to put there */
+ .text 0x4000:
+ {
+ text.start = . ;
+ *(.entry)
+ *(.entry2)
+ *(.text*)
+ *(.rodata*)
+ *(.rodata1)
+ KEEP (*(SORT(.rtemsroset.*)))
+
+ /*
+ * Special FreeBSD sysctl sections.
+ */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ /* C++ constructors/destructors */
+ *(.gnu.linkonce.t*)
+
+ /* Initialization and finalization code.
+ *
+ * Various files can provide initialization and finalization functions.
+ * The bodies of these functions are in .init and .fini sections. We
+ * accumulate the bodies here, and prepend function prologues from
+ * ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
+ * first; ecrtn.o must be linked last. Because these are wildcards, it
+ * doesn't matter if the user does not actually link against ecrti.o and
+ * ecrtn.o; the linker won't look for a file to match a wildcard. The
+ * wildcard also means that it doesn't matter which directory ecrti.o
+ * and ecrtn.o are in.
+ */
+ PROVIDE (_init = .);
+ *ecrti.o(.init)
+ *(.init)
+ *ecrtn.o(.init)
+
+ PROVIDE (_fini = .);
+ *ecrti.o(.fini)
+ *(.fini)
+ *ecrtn.o(.init)
+
+ /*
+ * C++ constructors and destructors for static objects.
+ * PowerPC EABI does not use crtstuff yet, so we build "old-style"
+ * constructor and destructor lists that begin with the list length
+ * end terminate with a NULL entry.
+ */
+
+ PROVIDE (__CTOR_LIST__ = .);
+ *crtbegin.o(.ctors)
+ *(.ctors)
+ *crtend.o(.ctors)
+ LONG(0)
+ PROVIDE (__CTOR_END__ = .);
+
+ PROVIDE (__DTOR_LIST__ = .);
+ *crtbegin.o(.dtors)
+ *(.dtors)
+ *crtend.o(.dtors)
+ LONG(0)
+ PROVIDE (__DTOR_END__ = .);
+
+ /* Exception frame info */
+ *(.eh_frame)
+ /* Miscellaneous read-only data */
+ _rodata_start = . ;
+ *(.gnu.linkonce.r*)
+ *(.lit)
+ *(.shdata)
+ *(.rodata)
+ *(.rodata1)
+ *(.descriptors)
+ *(rom_ver)
+ _erodata = .;
+
+ PROVIDE (__EXCEPT_START__ = .);
+ *(.gcc_except_table*)
+ PROVIDE (__EXCEPT_END__ = .);
+ __GOT_START__ = .;
+ s.got = .;
+ *(.got.plt)
+ *(.got)
+ *(.got1)
+ PROVIDE (__GOT2_START__ = .);
+ PROVIDE (_GOT2_START_ = .);
+ *(.got2)
+ PROVIDE (__GOT2_END__ = .);
+ PROVIDE (_GOT2_END_ = .);
+
+ PROVIDE (__FIXUP_START__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ *(.fixup)
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (__FIXUP_END__ = .);
+
+
+ /* Various possible names for the end of the .text section */
+ etext = ALIGN(0x10);
+ _etext = .;
+
+ *(.lit)
+ *(.shdata)
+ _endtext = ALIGN(0x10);
+ text.end = .;
+ text.size = text.end - text.start;
+ } >RAM
+
+ text.size = text.end - text.start;
+
+ .tdata : {
+ _TLS_Data_begin = .;
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ _TLS_Data_end = .;
+ } >RAM
+
+ .tbss : {
+ _TLS_BSS_begin = .;
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ _TLS_BSS_end = .;
+ } >RAM
+
+ _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));
+
+ .jcr : { KEEP (*(.jcr)) } >RAM
+
+ .rel.dyn : {
+ *(.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.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
+ *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
+ *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
+ *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ } >RAM
+ .rela.dyn : {
+ *(.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.got1)
+ *(.rela.got2)
+ *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
+ *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
+ *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
+ *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ } >RAM
+
+
+ /* Initialised large data */
+ .data ( . ) :
+ {
+ . = ALIGN (4);
+ data.start = .;
+ *(.data)
+ *(.data1)
+ KEEP (*(SORT(.rtemsrwset.*)))
+ *(.data.* .gnu.linkonce.d.*)
+ data.end = .;
+ } > RAM
+
+ /* Initialised small data addressed as offsets from r13 */
+ .sdata : {
+ . = ALIGN (4);
+ PROVIDE (__SDATA_START__ = .);
+ sdata.start = .;
+ *(.sdata*)
+ *(.gnu.linkonce.s.*)
+ sdata.end = .;
+ } > RAM
+
+ /* Zeroed small data addressed as offsets from r13 */
+ .sbss : {
+ . = ALIGN (4);
+ PROVIDE(__SBSS_START__ = .);
+ sbss.start = .;
+ *(.sbss .sbss.* *.gnu.linkonce.sb.*);
+ sbss.end = .;
+ } > RAM
+ PROVIDE(__SBSS_END__ = .);
+
+ /* Zeroed large data */
+ .bss : {
+ . = ALIGN (4);
+ bss.start = .;
+ *(.bss .bss* .gnu.linkonce.b*)
+ . = ALIGN(4);
+ bss.end = .;
+ } > RAM
+
+ bss.size = bss.end - bss.start;
+ sbss.size = sbss.end - sbss.start;
+
+ /* Interrupt stack: align to a cache-line boundary */
+ IntrStack_start = ALIGN(0x20);
+ . += kIntrStackSize;
+ intrStack = .;
+ PROVIDE(intrStackPtr = intrStack);
+ PROVIDE(intrStack_start = IntrStack_start);
+ PROVIDE(intrStack_size = kIntrStackSize);
+
+ /* Main stack: align to a cache-line boundary */
+ stack.start = ALIGN(0x20);
+ . += kMainStackSize;
+ stack.end = .;
+
+ /* RTEMS workspace: size specified by application */
+ WorkAreaBase = ALIGN(0x20);
+
+ /* Debugging information */
+ .line 0 : { *(.line) }
+ .debug 0 : { *(.debug) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_aregion 0 : { *(.debug_aregion) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+}
diff --git a/bsps/powerpc/motorola_powerpc/start/bsp_specs b/bsps/powerpc/motorola_powerpc/start/bsp_specs
new file mode 100644
index 0000000000..2625609327
--- /dev/null
+++ b/bsps/powerpc/motorola_powerpc/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/motorola_powerpc/start/bspreset.c b/bsps/powerpc/motorola_powerpc/start/bspreset.c
new file mode 100644
index 0000000000..0931badae4
--- /dev/null
+++ b/bsps/powerpc/motorola_powerpc/start/bspreset.c
@@ -0,0 +1,28 @@
+#include <bsp.h>
+#include <rtems/bspIo.h>
+#include <libcpu/stackTrace.h>
+#include <bsp/bootcard.h>
+
+/*-------------------------------------------------------------------------+
+| Function: bsp_reset
+| Description: Reboot the PC.
+| Global Variables: None.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+void bsp_reset(void)
+{
+ printk("Printing a stack trace for your convenience :-)\n");
+ CPU_print_stack();
+ /* shutdown and reboot */
+
+#if defined(mvme2100)
+ *(unsigned char*)0xffe00000 |= 0x80;
+#else
+ /* Memory-mapped Port 92 PIB device access
+ *(unsigned char*)0x80000092 |= 0x01;
+ */
+ outb(1, 0x92);
+
+#endif
+} /* bsp_reset */
diff --git a/bsps/powerpc/motorola_powerpc/start/linkcmds b/bsps/powerpc/motorola_powerpc/start/linkcmds
new file mode 100644
index 0000000000..ae44032d4f
--- /dev/null
+++ b/bsps/powerpc/motorola_powerpc/start/linkcmds
@@ -0,0 +1,6 @@
+INPUT(vectors_entry.o)
+STARTUP(start.o)
+ENTRY(__rtems_entry_point)
+EXTERN(_vectors)
+
+INCLUDE linkcmds.share
diff --git a/bsps/powerpc/mpc55xxevb/start/bsp_specs b/bsps/powerpc/mpc55xxevb/start/bsp_specs
new file mode 100644
index 0000000000..2625609327
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/mpc55xxevb/start/bspgetworkarea.c b/bsps/powerpc/mpc55xxevb/start/bspgetworkarea.c
new file mode 100644
index 0000000000..e7d988cf87
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/bspgetworkarea.c
@@ -0,0 +1,53 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ */
+
+/*
+ * Copyright (c) 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/bootcard.h>
+#include <bsp/linker-symbols.h>
+
+LINKER_SYMBOL(bsp_section_work_bonus_begin);
+LINKER_SYMBOL(bsp_section_work_bonus_size);
+
+void bsp_work_area_initialize(void)
+{
+ Heap_Area areas [] = {
+ {
+ bsp_section_work_begin,
+ (uintptr_t) bsp_section_work_size
+ }, {
+ bsp_section_work_bonus_begin,
+ (uintptr_t) bsp_section_work_bonus_size
+ }
+ };
+
+ #ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN
+ {
+ uint32_t stack_size = rtems_configuration_get_interrupt_stack_size();
+
+ areas [0].begin = (char *) areas [0].begin + stack_size;
+ areas [0].size -= stack_size;
+ }
+ #endif
+
+ bsp_work_area_initialize_with_table(
+ areas,
+ sizeof(areas) / sizeof(areas [0])
+ );
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/bspreset.c b/bsps/powerpc/mpc55xxevb/start/bspreset.c
new file mode 100644
index 0000000000..a99b3856d3
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/bspreset.c
@@ -0,0 +1,38 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief BSP reset.
+ */
+
+/*
+ * 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 <stdbool.h>
+
+#include <bsp/bootcard.h>
+
+#include <mpc55xx/regs.h>
+
+void bsp_reset(void)
+{
+ while (true) {
+ #if MPC55XX_CHIP_FAMILY == 564
+ /* TODO */
+ #else
+ SIU.SRCR.R = 1U << (31 - 0);
+ #endif
+ }
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/bspstart.c b/bsps/powerpc/mpc55xxevb/start/bspstart.c
new file mode 100644
index 0000000000..9042fc3864
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/bspstart.c
@@ -0,0 +1,104 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief BSP startup code.
+ */
+
+/*
+ * Copyright (c) 2008-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.
+ */
+
+#include <mpc55xx/mpc55xx.h>
+#include <mpc55xx/regs.h>
+#include <mpc55xx/edma.h>
+#include <mpc55xx/emios.h>
+
+#include <string.h>
+
+#include <rtems.h>
+#include <rtems/config.h>
+#include <rtems/counter.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <bsp/vectors.h>
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/start.h>
+#include <bsp/mpc55xx-config.h>
+
+/* Symbols defined in linker command file */
+LINKER_SYMBOL(mpc55xx_exc_vector_base);
+
+unsigned int bsp_clock_speed = 0;
+
+uint32_t bsp_clicks_per_usec = 0;
+
+static void null_pointer_protection(void)
+{
+#ifdef MPC55XX_NULL_POINTER_PROTECTION
+ struct MMU_tag mmu = { .MAS0 = { .B = { .TLBSEL = 1, .ESEL = 1 } } };
+
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS0, mmu.MAS0.R);
+ __asm__ volatile ("tlbre");
+ mmu.MAS1.R = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS1);
+ mmu.MAS1.B.VALID = 0;
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS1, mmu.MAS1.R);
+ __asm__ volatile ("tlbwe");
+#endif
+}
+
+void bsp_start(void)
+{
+ null_pointer_protection();
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function store the result in global variables so that it can be used
+ * latter...
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ /*
+ * determine clock speed
+ */
+ bsp_clock_speed = mpc55xx_get_system_clock() / MPC55XX_SYSTEM_CLOCK_DIVIDER;
+
+ /* Time reference value */
+ bsp_clicks_per_usec = bsp_clock_speed / 1000000;
+ rtems_counter_initialize_converter(bsp_clock_speed);
+
+ /* Initialize exceptions */
+ ppc_exc_initialize_with_vector_base(
+ (uintptr_t) bsp_section_work_begin,
+ rtems_configuration_get_interrupt_stack_size(),
+ mpc55xx_exc_vector_base
+ );
+
+ /* Initialize interrupts */
+ bsp_interrupt_initialize();
+
+ #if MPC55XX_CHIP_FAMILY != 566
+ mpc55xx_edma_init();
+ #endif
+
+ #ifdef MPC55XX_EMIOS_PRESCALER
+ mpc55xx_emios_initialize(MPC55XX_EMIOS_PRESCALER);
+ #endif
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/exc-vector-base.S b/bsps/powerpc/mpc55xxevb/start/exc-vector-base.S
new file mode 100644
index 0000000000..9d9e79f351
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/exc-vector-base.S
@@ -0,0 +1,124 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx_asm
+ *
+ * @brief Exception minimum prologues.
+ */
+
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup mpc55xx_asm Assembler files
+ *
+ * @ingroup mpc55xx
+ */
+
+#include <bspopts.h>
+
+#include <bsp/vectors.h>
+
+ .globl mpc55xx_exc_vector_base
+
+ .section ".bsp_text", "ax"
+
+#if 5510 <= MPC55XX_CHIP_TYPE && MPC55XX_CHIP_TYPE <= 5517
+ .align 12
+#else
+ .align 16
+#endif
+
+mpc55xx_exc_vector_base:
+
+ stw r1, ppc_exc_lock_crit@sdarel(r13)
+ stw r4, ppc_exc_vector_register_crit@sdarel(r13)
+ li r4, -32767
+ b ppc_exc_wrap_bookE_crit
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 2
+ b ppc_exc_wrap_nopush_bookE_crit
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 3
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 4
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
+ stw r3, GPR3_OFFSET(r1)
+ li r3, -32763
+ b ppc_exc_interrupt
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 6
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 7
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 8
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 12
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 24
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
+ stw r3, GPR3_OFFSET(r1)
+ li r3, -32752
+ b ppc_exc_interrupt
+ stwu r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
+ stw r3, GPR3_OFFSET(r1)
+ li r3, -32749
+ b ppc_exc_interrupt
+ stw r1, ppc_exc_lock_crit@sdarel(r13)
+ stw r4, ppc_exc_vector_register_crit@sdarel(r13)
+ li r4, -32748
+ b ppc_exc_wrap_bookE_crit
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 18
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 17
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 13
+ b ppc_exc_wrap_nopush_bookE_crit
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 10
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 25
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 26
+ b ppc_exc_wrap_nopush_std
+ stwu r1, -EXC_GENERIC_SIZE(r1)
+ stw r4, GPR4_OFFSET(r1)
+ li r4, 15
+ b ppc_exc_wrap_nopush_std
diff --git a/bsps/powerpc/mpc55xxevb/start/get-system-clock.c b/bsps/powerpc/mpc55xxevb/start/get-system-clock.c
new file mode 100644
index 0000000000..42e2b38327
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/get-system-clock.c
@@ -0,0 +1,85 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief System clock calculation.
+ */
+
+/*
+ * 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 <bsp.h>
+#include <bsp/start.h>
+#include <bsp/mpc55xx-config.h>
+
+uint32_t mpc55xx_get_system_clock(void)
+{
+ uint32_t system_clock = 0;
+
+ #ifdef MPC55XX_HAS_FMPLL
+ volatile struct FMPLL_tag *fmpll = &FMPLL;
+ union FMPLL_SYNSR_tag synsr = { .R = fmpll->SYNSR.R };
+ uint32_t reference_clock = MPC55XX_REFERENCE_CLOCK;
+ bool pll_clock_mode = synsr.B.MODE != 0;
+ bool crystal_or_external_reference_mode = synsr.B.PLLSEL != 0;
+
+ if (pll_clock_mode) {
+ if (crystal_or_external_reference_mode) {
+ union FMPLL_SYNCR_tag syncr = { .R = fmpll->SYNCR.R };
+ uint32_t prediv = syncr.B.PREDIV;
+ uint32_t mfd = syncr.B.MFD;
+ uint32_t rfd = syncr.B.RFD;
+
+ system_clock = ((reference_clock * (mfd + 4)) >> rfd) / (prediv + 1);
+ } else {
+ system_clock = 2 * reference_clock;
+ }
+ } else {
+ system_clock = reference_clock;
+ }
+ #endif
+
+ #ifdef MPC55XX_HAS_FMPLL_ENHANCED
+ volatile struct FMPLL_tag *fmpll = &FMPLL;
+ union FMPLL_ESYNCR1_tag esyncr1 = { .R = fmpll->ESYNCR1.R };
+ uint32_t reference_clock = MPC55XX_REFERENCE_CLOCK;
+ bool normal_mode = (esyncr1.B.CLKCFG & 0x4U) != 0;
+
+ if (normal_mode) {
+ union FMPLL_ESYNCR2_tag esyncr2 = { .R = fmpll->ESYNCR2.R };
+ uint32_t eprediv = esyncr1.B.EPREDIV;
+ uint32_t emfd = esyncr1.B.EMFD;
+ uint32_t erfd = esyncr2.B.ERFD;
+
+ system_clock = ((reference_clock / (eprediv + 1)) * (emfd + 16))
+ / (erfd + 1);
+ } else {
+ system_clock = reference_clock;
+ }
+ #endif
+
+ #ifdef MPC55XX_HAS_MODE_CONTROL
+ /* FIXME: Assumes normal mode and external oscillator */
+ PLLD_CR_32B_tag cr = { . R = CGM.FMPLL [0].CR.R };
+ uint32_t xosc = MPC55XX_REFERENCE_CLOCK;
+ uint32_t ldf = cr.B.NDIV;
+ uint32_t idf = cr.B.IDF + 1;
+ uint32_t odf = 2U << cr.B.ODF;
+
+ system_clock = (xosc * ldf) / (idf * odf);
+ #endif
+
+ return system_clock;
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/idle-thread.c b/bsps/powerpc/mpc55xxevb/start/idle-thread.c
new file mode 100644
index 0000000000..45bea8e418
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/idle-thread.c
@@ -0,0 +1,34 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief bsp_idle_thread() implementation.
+ */
+
+/*
+ * Copyright (c) 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 <mpc55xx/mpc55xx.h>
+
+void *bsp_idle_thread(uintptr_t arg)
+{
+ while (true) {
+ mpc55xx_wait_for_interrupt();
+ }
+
+ return NULL;
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds b/bsps/powerpc/mpc55xxevb/start/linkcmds
new file mode 100644
index 0000000000..5c2161deba
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds
@@ -0,0 +1 @@
+include linkcmds.mpc55xxevb
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.gwlcfm b/bsps/powerpc/mpc55xxevb/start/linkcmds.gwlcfm
new file mode 100644
index 0000000000..cabaac2201
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.gwlcfm
@@ -0,0 +1,27 @@
+MEMORY {
+ ROM : ORIGIN = 0x0, LENGTH = 1536K
+ RAM : ORIGIN = 0x40000000, LENGTH = 80K
+ RAM_EXT : ORIGIN = 0x20000000, LENGTH = 512K
+ NOCACHE : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("REGION_START", ROM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_TEXT", ROM);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_RODATA", ROM);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_RWEXTRA", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", NOCACHE);
+REGION_ALIAS ("REGION_NVRAM", NOCACHE);
+
+INCLUDE linkcmds.mpc55xx
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5566evb b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5566evb
new file mode 100644
index 0000000000..4f63fb0e0a
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5566evb
@@ -0,0 +1,27 @@
+MEMORY {
+ ROM : ORIGIN = 0x0, LENGTH = 3M
+ RAM : ORIGIN = 0x40000000, LENGTH = 128K
+ RAM_EXT : ORIGIN = 0x20000000, LENGTH = 512K
+ NOCACHE : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("REGION_START", ROM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_TEXT", ROM);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_RODATA", ROM);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_RWEXTRA", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", NOCACHE);
+REGION_ALIAS ("REGION_NVRAM", NOCACHE);
+
+INCLUDE linkcmds.mpc55xx
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5566evb_spe b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5566evb_spe
new file mode 100644
index 0000000000..9255b15076
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5566evb_spe
@@ -0,0 +1 @@
+INCLUDE linkcmds.mpc5566evb
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc55xx b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc55xx
new file mode 100644
index 0000000000..2c4e1e3f7b
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc55xx
@@ -0,0 +1,22 @@
+bsp_ram_start = ORIGIN (RAM);
+bsp_ram_size = LENGTH (RAM) + LENGTH (NOCACHE);
+bsp_ram_end = bsp_ram_start + bsp_ram_size;
+
+bsp_rom_start = ORIGIN (ROM);
+bsp_rom_size = LENGTH (ROM);
+bsp_rom_end = bsp_rom_start + bsp_rom_size;
+
+INCLUDE linkcmds.base
+
+SECTIONS {
+ .work_bonus : {
+ /*
+ * This section will occupy the remaining RAM_EXT region and may
+ * contain parts of the RTEMS work space and heap.
+ */
+ bsp_section_work_bonus_begin = .;
+ . += ORIGIN (RAM_EXT) + LENGTH (RAM_EXT) - ABSOLUTE (.);
+ bsp_section_work_bonus_end = .;
+ } > RAM_EXT AT > RAM_EXT
+ bsp_section_work_bonus_size = bsp_section_work_bonus_end - bsp_section_work_bonus_begin;
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5643l_dpu b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5643l_dpu
new file mode 100644
index 0000000000..2f7d80716d
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5643l_dpu
@@ -0,0 +1 @@
+INCLUDE linkcmds.mpc5643l_evb
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5643l_evb b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5643l_evb
new file mode 100644
index 0000000000..1977c92d59
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5643l_evb
@@ -0,0 +1,33 @@
+MEMORY {
+ ROM : ORIGIN = 0x0, LENGTH = 1M
+ RAM : ORIGIN = 0x40000000, LENGTH = 64K
+ RAM_1 : ORIGIN = 0x50000000, LENGTH = 64K
+ NOCACHE : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("RAM_EXT", RAM);
+
+bsp_ram_1_start = ORIGIN (RAM_1);
+bsp_ram_1_size = LENGTH (RAM_1);
+bsp_ram_1_end = bsp_ram_1_start + bsp_ram_1_size;
+
+REGION_ALIAS ("REGION_START", ROM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_TEXT", ROM);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_RODATA", ROM);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM);
+REGION_ALIAS ("REGION_WORK", RAM_1);
+REGION_ALIAS ("REGION_STACK", RAM_1);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", NOCACHE);
+REGION_ALIAS ("REGION_NVRAM", NOCACHE);
+
+INCLUDE linkcmds.mpc55xx
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5668g b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5668g
new file mode 100644
index 0000000000..6c8e5a64f1
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5668g
@@ -0,0 +1,29 @@
+MEMORY {
+ ROM : ORIGIN = 0x0, LENGTH = 2M
+ RAM : ORIGIN = 0x40000000, LENGTH = 256K - 16k
+ NOCACHE : ORIGIN = 0x4003c000, LENGTH = 16k
+ EMPTY : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("RAM_EXT", RAM);
+
+REGION_ALIAS ("REGION_START", ROM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_TEXT", ROM);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_RODATA", ROM);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", ROM);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+INCLUDE linkcmds.mpc55xx
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508 b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508
new file mode 100644
index 0000000000..1e52a3c6c3
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508
@@ -0,0 +1,51 @@
+MEMORY {
+ DSROM : ORIGIN = 0x00020000, LENGTH = 64k
+ SYSROM : ORIGIN = 0x00100000, LENGTH = 4k
+ RAM : ORIGIN = 0x40000000, LENGTH = 240k
+ NOCACHE : ORIGIN = 0x4003c000, LENGTH = 16k
+ DSRAM : ORIGIN = 0x20000000, LENGTH = 64k
+ RAM_EXT : ORIGIN = 0x20010000, LENGTH = 444k
+ SYSRAM : ORIGIN = 0x2007f000, LENGTH = 4k
+ NVRAM : ORIGIN = 0x3ffa0000, LENGTH = 128k
+}
+
+REGION_ALIAS ("REGION_START", STARTROM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_TEXT", ROM);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_RODATA", ROM);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", ROM);
+REGION_ALIAS ("REGION_NVRAM", NVRAM);
+
+SECTIONS {
+ .dsram (NOLOAD) : {
+ bsp_section_dsram_begin = .;
+ *(SORT(.bsp_dsram*))
+ bsp_section_dsram_end = .;
+ } > DSRAM AT > DSROM
+ bsp_section_dsram_size = bsp_section_dsram_end - bsp_section_dsram_begin;
+ bsp_section_dsram_load_begin = LOADADDR (.dsram);
+ bsp_section_dsram_load_end = bsp_section_dsram_load_begin + bsp_section_dsram_size;
+
+ .sysram : {
+ bsp_section_sysram_begin = .;
+ *(SORT(.bsp_sysram*))
+ bsp_section_sysram_end = .;
+ } > SYSRAM AT > SYSROM
+ bsp_section_sysram_size = bsp_section_sysram_end - bsp_section_sysram_begin;
+ bsp_section_sysram_load_begin = LOADADDR (.sysram);
+ bsp_section_sysram_load_end = bsp_section_sysram_load_begin + bsp_section_sysram_size;
+}
+
+INCLUDE linkcmds.mpc55xx
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508_app b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508_app
new file mode 100644
index 0000000000..4b94ac50c4
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508_app
@@ -0,0 +1,8 @@
+MEMORY {
+ /* Let space for the binary image library header */
+ ROM : ORIGIN = 0x00101000, LENGTH = 3064k
+}
+
+REGION_ALIAS ("STARTROM", ROM);
+
+INCLUDE linkcmds.mpc5674f_ecu508
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508_boot b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508_boot
new file mode 100644
index 0000000000..6dc5a7fcb0
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_ecu508_boot
@@ -0,0 +1,6 @@
+MEMORY {
+ STARTROM : ORIGIN = 0x0, LENGTH = 32k
+ ROM : ORIGIN = 0x40000, LENGTH = 768k
+}
+
+INCLUDE linkcmds.mpc5674f_ecu508
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_rsm6 b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_rsm6
new file mode 100644
index 0000000000..c96f8b9078
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_rsm6
@@ -0,0 +1,6 @@
+MEMORY {
+ STARTROM : ORIGIN = 0x0, LENGTH = 32k
+ ROM : ORIGIN = 0x40000, LENGTH = 768k
+}
+
+INCLUDE linkcmds.mpc5674f_rsm6_base
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_rsm6_base b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_rsm6_base
new file mode 100644
index 0000000000..8f6a403ca8
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674f_rsm6_base
@@ -0,0 +1,28 @@
+MEMORY {
+ RAM : ORIGIN = 0x40000000, LENGTH = 240k
+ NOCACHE : ORIGIN = 0x4003c000, LENGTH = 16k
+ MRAM : ORIGIN = 0x20000000, LENGTH = 4M
+}
+
+REGION_ALIAS ("RAM_EXT", RAM);
+
+REGION_ALIAS ("REGION_START", STARTROM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_TEXT", ROM);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_RODATA", ROM);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", ROM);
+REGION_ALIAS ("REGION_NVRAM", MRAM);
+
+INCLUDE linkcmds.mpc55xx
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674fevb b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674fevb
new file mode 100644
index 0000000000..3113fb20b7
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674fevb
@@ -0,0 +1,28 @@
+MEMORY {
+ ROM : ORIGIN = 0x0, LENGTH = 4M
+ RAM : ORIGIN = 0x40000000, LENGTH = 256K - 16k
+ RAM_EXT : ORIGIN = 0x20000000, LENGTH = 512K
+ NOCACHE : ORIGIN = 0x4003c000, LENGTH = 16k
+ EMPTY : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("REGION_START", ROM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_TEXT", ROM);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_RODATA", ROM);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", ROM);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+INCLUDE linkcmds.mpc55xx
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674fevb_spe b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674fevb_spe
new file mode 100644
index 0000000000..eab0907009
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.mpc5674fevb_spe
@@ -0,0 +1 @@
+INCLUDE linkcmds.mpc5674fevb
diff --git a/bsps/powerpc/mpc55xxevb/start/linkcmds.phycore_mpc5554 b/bsps/powerpc/mpc55xxevb/start/linkcmds.phycore_mpc5554
new file mode 100644
index 0000000000..77b8abc5e0
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/linkcmds.phycore_mpc5554
@@ -0,0 +1,36 @@
+/*
+ * Debug RAM is the top 4MB of external RAM and is swapped with the
+ * FLASH for development.
+ */
+MEMORY {
+ ROM : ORIGIN = 0x00000000, LENGTH = 2M
+ RAM : ORIGIN = 0x40000000, LENGTH = 64K
+ RAM_EXT : ORIGIN = 0x21000000, LENGTH = 4M
+ DEBUG_RAM : ORIGIN = 0x21400000, LENGTH = 4M
+ NOCACHE : ORIGIN = 0x0, LENGTH = 0
+}
+
+bsp_debug_ram_start = ORIGIN (DEBUG_RAM);
+bsp_debug_ram_end = ORIGIN (DEBUG_RAM) + LENGTH (DEBUG_RAM);
+bsp_debug_ram_size = LENGTH (DEBUG_RAM);
+
+REGION_ALIAS ("REGION_START", ROM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_TEXT", ROM);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_RODATA", ROM);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_BSS", RAM_EXT);
+REGION_ALIAS ("REGION_RWEXTRA", RAM_EXT);
+REGION_ALIAS ("REGION_WORK", RAM_EXT);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", NOCACHE);
+REGION_ALIAS ("REGION_NVRAM", NOCACHE);
+
+INCLUDE linkcmds.mpc55xx
diff --git a/bsps/powerpc/mpc55xxevb/start/restart.c b/bsps/powerpc/mpc55xxevb/start/restart.c
new file mode 100644
index 0000000000..495aa39a95
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/restart.c
@@ -0,0 +1,25 @@
+/*
+ * 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>
+
+void bsp_restart(void *addr)
+{
+ rtems_interrupt_level level;
+ void (*start)(void) = addr;
+
+ (void) level;
+ rtems_interrupt_disable(level);
+ (*start)();
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/sd-card-init.c b/bsps/powerpc/mpc55xxevb/start/sd-card-init.c
new file mode 100644
index 0000000000..f6e0484122
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/sd-card-init.c
@@ -0,0 +1,163 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief SD Card initialization code.
+ */
+
+/*
+ * Copyright (c) 2008
+ * 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 <stdio.h>
+
+#include <mpc55xx/mpc55xx.h>
+#include <mpc55xx/regs.h>
+#include <mpc55xx/dspi.h>
+
+#include <bsp.h>
+
+#include <rtems/status-checks.h>
+
+#ifdef MPC55XX_BOARD_MPC5566EVB
+
+static rtems_status_code mpc55xx_dspi_init(void)
+{
+ int rv = 0;
+ int i = 0;
+ char device_name [] = "/dev/spi0";
+ union SIU_PCR_tag pcr = MPC55XX_ZERO_FLAGS;
+
+ rv = rtems_libi2c_initialize();
+ RTEMS_CHECK_RV_SC( rv, "rtems_libi2c_initialize");
+
+ /* DSPI D inputs are taken from DSPI C */
+ SIU.DISR.R = 0x000000FC;
+
+ /* DSPI A signals */
+ pcr.B.PA = 1;
+ pcr.B.ODE = 0;
+ pcr.B.HYS = 0;
+ pcr.B.SRC = 3;
+ pcr.B.WPE = 1;
+ pcr.B.WPS = 1;
+
+ /* SCK */
+ pcr.B.OBE = 1;
+ pcr.B.IBE = 0;
+ SIU.PCR [93].R = pcr.R;
+
+ /* SIN */
+ pcr.B.OBE = 0;
+ pcr.B.IBE = 1;
+ SIU.PCR [94].R = pcr.R;
+
+ /* SOUT */
+ pcr.B.OBE = 1;
+ pcr.B.IBE = 0;
+ SIU.PCR [95].R = pcr.R;
+
+ /* PCSx */
+ pcr.B.OBE = 1;
+ pcr.B.IBE = 0;
+ SIU.PCR [96].R = pcr.R;
+ SIU.PCR [97].R = pcr.R;
+ SIU.PCR [98].R = pcr.R;
+ SIU.PCR [99].R = pcr.R;
+ SIU.PCR [100].R = pcr.R;
+ SIU.PCR [101].R = pcr.R;
+
+ mpc55xx_dspi_bus_table [3].master = 0;
+ for (i = 0; i < MPC55XX_DSPI_NUMBER; ++i) {
+ device_name [8] = (char) ('0' + i);
+ rv = rtems_libi2c_register_bus( device_name, (rtems_libi2c_bus_t *) &mpc55xx_dspi_bus_table [i]);
+ RTEMS_CHECK_RV_SC( rv, device_name);
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+#include <stdio.h>
+#include <rtems/fsmount.h>
+#include <rtems/dosfs.h>
+#include <rtems/bdpart.h>
+#include <rtems/console.h>
+
+#include <libchip/spi-sd-card.h>
+
+#define MPC55XX_DEVICE "sd-card-a"
+#define MPC55XX_DEVICE_FILE "/dev/" MPC55XX_DEVICE
+#define MPC55XX_PARTITION "/dev/sd-card-a1"
+#define MPC55XX_MOUNT_POINT "/mnt"
+
+static fstab_t mpc55xx_fs_table [] = { {
+ MPC55XX_PARTITION, MPC55XX_MOUNT_POINT,
+ "dosfs", RTEMS_FILESYSTEM_READ_WRITE,
+ FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
+ FSMOUNT_MNT_OK
+ }, {
+ MPC55XX_DEVICE_FILE, MPC55XX_MOUNT_POINT,
+ "dosfs", RTEMS_FILESYSTEM_READ_WRITE,
+ FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
+ 0
+ }
+};
+
+sd_card_driver_entry sd_card_driver_table [] = {
+ {
+ .device_name = "/dev/sd-card-a",
+ .bus = 0,
+ .transfer_mode = SD_CARD_TRANSFER_MODE_DEFAULT,
+ .command = SD_CARD_COMMAND_DEFAULT,
+ /* response : whatever, */
+ .response_index = SD_CARD_COMMAND_SIZE,
+ .n_ac_max = SD_CARD_N_AC_MAX_DEFAULT,
+ .block_number = 0,
+ .block_size = 0,
+ .block_size_shift = 0,
+ .busy = true,
+ .verbose = true,
+ .schedule_if_busy = false
+ }
+};
+
+size_t sd_card_driver_table_size = sizeof( sd_card_driver_table) / sizeof( sd_card_driver_table [0]);
+
+rtems_status_code mpc55xx_sd_card_init( bool mount)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ int rv = 0;
+ sd_card_driver_entry *e = &sd_card_driver_table [0];
+
+ RTEMS_DEBUG_PRINT( "Task started\n");
+
+ sc = mpc55xx_dspi_init();
+ RTEMS_CHECK_SC( rv, "Intitalize DSPI bus");
+
+ e->bus = mpc55xx_dspi_bus_table [0].bus_number;
+
+ sc = sd_card_register();
+ RTEMS_CHECK_SC( sc, "Register SD Card");
+
+ if (mount) {
+ sc = rtems_bdpart_register_from_disk( MPC55XX_DEVICE_FILE);
+ RTEMS_CHECK_SC( sc, "Initialize IDE partition table");
+
+ rv = rtems_fsmount( mpc55xx_fs_table, sizeof( mpc55xx_fs_table) / sizeof( mpc55xx_fs_table [0]), NULL);
+ RTEMS_CHECK_RV_SC( rv, "Mount file systems");
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+#endif /* MPC55XX_BOARD_MPC5566EVB */
diff --git a/bsps/powerpc/mpc55xxevb/start/start-cache.S b/bsps/powerpc/mpc55xxevb/start/start-cache.S
new file mode 100644
index 0000000000..c30de57fc6
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-cache.S
@@ -0,0 +1,114 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx_asm
+ *
+ * @brief Cache initialization.
+ */
+
+/*
+ * 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 <libcpu/powerpc-utility.h>
+
+#include <mpc55xx/regs.h>
+
+ .globl mpc55xx_start_cache
+
+ .section ".bsp_start_text", "ax"
+
+mpc55xx_start_cache:
+
+#ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
+
+ /* Load zero, CINV, and CABT) */
+ li r0, 0
+ li r3, 0x2
+ li r4, 0x4
+
+#if defined(BSP_INSTRUCTION_CACHE_ENABLED) \
+ && defined(MPC55XX_HAS_INSTRUCTION_CACHE)
+
+start_instruction_cache_invalidation:
+
+ /* Clear instruction cache invalidation abort */
+ mtspr FSL_EIS_L1CSR1, r0
+
+ /* Start instruction cache invalidation */
+ mtspr FSL_EIS_L1CSR1, r3
+
+get_instruction_cache_invalidation_status:
+
+ /* Get instruction cache invalidation status */
+ mfspr r5, FSL_EIS_L1CSR1
+
+ /* Check CABT */
+ and. r6, r5, r4
+ bne start_instruction_cache_invalidation
+
+ /* Check CINV */
+ and. r6, r5, r3
+ bne get_instruction_cache_invalidation_status
+
+ /* Save instruction cache settings */
+ LWI r6, 0x00010001
+ isync
+ msync
+ mtspr FSL_EIS_L1CSR1, r6
+
+#endif
+
+#if (defined(BSP_DATA_CACHE_ENABLED) && defined(MPC55XX_HAS_DATA_CACHE)) \
+ || ((defined(BSP_DATA_CACHE_ENABLED) \
+ || defined(BSP_INSTRUCTION_CACHE_ENABLED)) \
+ && defined(MPC55XX_HAS_UNIFIED_CACHE))
+
+start_data_cache_invalidation:
+
+ /* Clear data cache invalidation abort */
+ mtspr FSL_EIS_L1CSR0, r0
+
+ /* Start data cache invalidation */
+ mtspr FSL_EIS_L1CSR0, r3
+
+get_data_cache_invalidation_status:
+
+ /* Get data cache invalidation status */
+ mfspr r5, FSL_EIS_L1CSR0
+
+ /* Check CABT */
+ and. r6, r5, r4
+ bne start_data_cache_invalidation
+
+ /* Check CINV */
+ and. r6, r5, r3
+ bne get_data_cache_invalidation_status
+
+ /* Save data cache settings */
+#if MPC55XX_CHIP_FAMILY != 567
+ /* FIXME: CORG??? 0x00180011 */
+ LWI r6, 0x00100001
+#else
+ LWI r6, 0x00190001
+#endif
+ isync
+ msync
+ mtspr FSL_EIS_L1CSR0, r6
+
+#endif
+
+#endif /* MPC55XX_NEEDS_LOW_LEVEL_INIT */
+
+ /* Return */
+ blr
diff --git a/bsps/powerpc/mpc55xxevb/start/start-clock.c b/bsps/powerpc/mpc55xxevb/start/start-clock.c
new file mode 100644
index 0000000000..85468d5cb0
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-clock.c
@@ -0,0 +1,104 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief Clock and FMPLL initialization code.
+ */
+
+/*
+ * 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 <bsp.h>
+#include <bsp/fatal.h>
+#include <bsp/start.h>
+#include <bsp/bootcard.h>
+#include <bsp/mpc55xx-config.h>
+
+#ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
+ #if defined(MPC55XX_HAS_FMPLL) || defined(MPC55XX_HAS_FMPLL_ENHANCED)
+ static BSP_START_TEXT_SECTION void fmpll_wait_for_lock(void)
+ {
+ int i = 0;
+ bool lock = false;
+
+ while (!lock && i < 6000) {
+ lock = FMPLL.SYNSR.B.LOCK != 0;
+ ++i;
+ }
+
+ if (!lock) {
+ bsp_fatal(MPC55XX_FATAL_FMPLL_LOCK);
+ }
+ }
+ #endif
+#endif
+
+BSP_START_TEXT_SECTION void mpc55xx_start_clock(void)
+{
+ #ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
+ const mpc55xx_clock_config *cfg = mpc55xx_start_config_clock;
+
+ #ifdef MPC55XX_HAS_FMPLL
+ volatile struct FMPLL_tag *fmpll = &FMPLL;
+
+ fmpll->SYNCR.R = cfg->syncr_tmp.R;
+ fmpll->SYNCR.R;
+ fmpll_wait_for_lock();
+
+ fmpll->SYNCR.R = cfg->syncr_final.R;
+ fmpll->SYNCR.R;
+ fmpll_wait_for_lock();
+ #endif
+
+ #ifdef MPC55XX_HAS_FMPLL_ENHANCED
+ volatile struct FMPLL_tag *fmpll = &FMPLL;
+
+ fmpll->ESYNCR2.R = cfg->esyncr2_tmp.R;
+ fmpll->ESYNCR2.R;
+ fmpll->ESYNCR1.R = cfg->esyncr1_final.R;
+ fmpll->ESYNCR1.R;
+ fmpll_wait_for_lock();
+
+ fmpll->ESYNCR2.R = cfg->esyncr2_final.R;
+ fmpll->ESYNCR2.R;
+ fmpll_wait_for_lock();
+
+ #if MPC55XX_CHIP_FAMILY == 551 || MPC55XX_CHIP_FAMILY == 566
+ /* System clock supplied by PLL */
+ SIU.SYSCLK.B.SYSCLKSEL = 2;
+ #endif
+ #endif
+
+ #ifdef MPC55XX_HAS_MODE_CONTROL
+ volatile CGM_tag *cgm = &CGM;
+ size_t fmpll_count = sizeof(cfg->fmpll) / sizeof(cfg->fmpll [0]);
+ size_t auxclk_count = sizeof(cfg->auxclk) / sizeof(cfg->auxclk [0]);
+ size_t i = 0;
+
+ for (i = 0; i < auxclk_count; ++i) {
+ cgm->AUXCLK [i].AC_SC.R = cfg->auxclk [i].AC_SC.R;
+ cgm->AUXCLK [i].AC_DC0_3.R = cfg->auxclk [i].AC_DC0_3.R;
+ }
+
+ for (i = 0; i < fmpll_count; ++i) {
+ cgm->FMPLL [i].CR.R = cfg->fmpll [i].cr.R;
+ cgm->FMPLL [i].MR.R = cfg->fmpll [i].mr.R;
+ }
+
+ cgm->OC_EN.R = cfg->oc_en.R;
+ cgm->OCDS_SC.R = cfg->ocds_sc.R;
+ #endif
+ #endif
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/start-config-clock.c b/bsps/powerpc/mpc55xxevb/start/start-config-clock.c
new file mode 100644
index 0000000000..d820af3755
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-config-clock.c
@@ -0,0 +1,132 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief Clock and FMPLL configuration.
+ */
+
+/*
+ * 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/mpc55xx-config.h>
+
+const mpc55xx_clock_config mpc55xx_start_config_clock [1] = { {
+ #ifdef MPC55XX_HAS_FMPLL
+ .syncr_tmp = {
+ .B = {
+ .PREDIV = MPC55XX_FMPLL_PREDIV - 1,
+ .MFD = MPC55XX_FMPLL_MFD,
+ .RFD = 2,
+ .LOCEN = 1
+ }
+ },
+ .syncr_final = {
+ .B = {
+ .PREDIV = MPC55XX_FMPLL_PREDIV - 1,
+ .MFD = MPC55XX_FMPLL_MFD,
+ .RFD = 0,
+ .LOCEN = 1,
+ .LOLIRQ = 1,
+ .LOCIRQ = 1
+ }
+ }
+ #endif
+ #ifdef MPC55XX_HAS_FMPLL_ENHANCED
+ #define EPREDIV_VAL (MPC55XX_FMPLL_PREDIV-1)
+ #define EMFD_VAL (MPC55XX_FMPLL_MFD-16)
+ #define VCO_CLK_REF (MPC55XX_REFERENCE_CLOCK/(EPREDIV_VAL+1))
+ #define VCO_CLK_OUT (VCO_CLK_REF*(EMFD_VAL+16))
+ #define ERFD_VAL \
+ (((VCO_CLK_OUT + MPC55XX_SYSTEM_CLOCK - 1) / MPC55XX_SYSTEM_CLOCK)-1)
+
+ .esyncr2_tmp = {
+ .B = {
+ .LOCEN = 0,
+ .LOLRE = 0,
+ .LOCRE = 0,
+ .LOLIRQ = 0,
+ .LOCIRQ = 0,
+ .ERATE = 0,
+ .EDEPTH = 0,
+ .ERFD = ERFD_VAL + 2 /* reduce output clock during init */
+ }
+ },
+ .esyncr2_final = {
+ .B = {
+ .LOCEN = 0,
+ .LOLRE = 0,
+ .LOCRE = 0,
+ .LOLIRQ = 0,
+ .LOCIRQ = 0,
+ .ERATE = 0,
+ #if MPC55XX_CHIP_FAMILY == 567
+ .CLKCFG_DIS = 1,
+ #endif
+ .EDEPTH = 0,
+ .ERFD = ERFD_VAL /* nominal output clock after init */
+ }
+ },
+ .esyncr1_final = {
+ .B = {
+ .CLKCFG = MPC55XX_FMPLL_ESYNCR1_CLKCFG,
+ .EPREDIV = EPREDIV_VAL,
+ .EMFD = EMFD_VAL
+ }
+ }
+ #endif
+ #ifdef MPC55XX_HAS_MODE_CONTROL
+ .fmpll = {
+ {
+ .cr = {
+ #if MPC55XX_REFERENCE_CLOCK == 8000000
+ .B = { .IDF = 0, .ODF = 1, .NDIV = 60, .I_LOCK = 1, .PLL_ON = 1 }
+ #elif MPC55XX_REFERENCE_CLOCK == 40000000
+ .B = { .IDF = 3, .ODF = 1, .NDIV = 48, .I_LOCK = 1, .PLL_ON = 1 }
+ #else
+ #error "unexpected reference clock"
+ #endif
+ }
+ },
+ {
+ .cr = {
+ .B = { .IDF = 3, .ODF = 2, .NDIV = 32, .I_LOCK = 1, .PLL_ON = 1 }
+ }
+ }
+ },
+ .ocds_sc = {
+ .B = { .SELDIV = 2, .SELCTL = 2 }
+ },
+ .auxclk = {
+ [0] = {
+ .AC_SC = { .B = { .SELCTL = 4 } },
+ .AC_DC0_3 = { .B = { .DE0 = 1, .DIV0 = 0 } }
+ },
+ [1] = {
+ .AC_SC = { .B = { .SELCTL = 4 } },
+ .AC_DC0_3 = { .B = { .DE0 = 1, .DIV0 = 11 } }
+ },
+ [2] = {
+ .AC_SC = { .B = { .SELCTL = 4 } },
+ .AC_DC0_3 = { .B = { .DE0 = 1, .DIV0 = 11 } }
+ },
+ [3] = {
+ .AC_SC = { .B = { .SELCTL = 1 } }
+ },
+ [4] = {
+ .AC_SC = { .B = { .SELCTL = 1 } }
+ }
+ }
+ #endif
+} };
diff --git a/bsps/powerpc/mpc55xxevb/start/start-config-ebi-cs-cal.c b/bsps/powerpc/mpc55xxevb/start/start-config-ebi-cs-cal.c
new file mode 100644
index 0000000000..69f9b61a7d
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-config-ebi-cs-cal.c
@@ -0,0 +1,257 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief EBI calibration chip-select configuration.
+ */
+
+/*
+ * 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/mpc55xx-config.h>
+
+#ifdef MPC55XX_HAS_EBI
+
+const struct EBI_CAL_CS_tag mpc55xx_start_config_ebi_cal_cs [] = {
+#if defined(MPC55XX_BOARD_MPC5674FEVB)
+ /* External SRAM */
+ {
+ .BR = {
+ .B = {
+ .BA = 0x20000000 >> 15,
+ .PS = 0,
+ .AD_MUX = 1,
+ .BL = 1,
+ .WEBS = 0,
+ .TBDIP = 1,
+ .SETA = 0,
+ .BI = 0,
+ .V = 1
+ }
+ },
+ .OR = {
+ .B = {
+ .AM = 0xfff80000 >> 15,
+ .SCY = 0,
+ .BSCY = 0
+ }
+ }
+ },
+ /* External Ethernet controller */
+ {
+ .BR = {
+ .B = {
+ .BA = 0x3fff8000 >> 15,
+ .PS = 0,
+ .AD_MUX = 1,
+ .BL = 0,
+ .WEBS = 0,
+ .TBDIP = 0,
+ .SETA = 0,
+ .BI = 1,
+ .V = 1
+ }
+ },
+ .OR = {
+ .B = {
+ .AM = 0xfff80000 >> 15,
+ .SCY = 1,
+ .BSCY = 0
+ }
+ }
+ }
+#elif defined(MPC55XX_BOARD_MPC5674F_ECU508) \
+ && defined(MPC55XX_NEEDS_LOW_LEVEL_INIT)
+ /* D_CS0 for external SRAM */
+ {
+ .BR = {
+ .B = {
+ .BA = 0x20000000 >> 15,
+ .PS = 0,
+ .AD_MUX = 1,
+ .BL = 1,
+ .WEBS = 0,
+ .TBDIP = 1,
+ .SETA = 0,
+ .BI = 0,
+ .V = 1
+ }
+ },
+ .OR = {
+ .B = {
+ .AM = 0xffe00000 >> 15,
+ .SCY = 0,
+ .BSCY = 0
+ }
+ }
+ },
+
+ /* D_CS1 for Ethernet Controller */
+ {
+ .BR = {
+ .B = {
+ .BA = 0x3fff8000 >> 15,
+ .PS = 0,
+ .AD_MUX = 1,
+ .BL = 0,
+ .WEBS = 0,
+ .TBDIP = 0,
+ .SETA = 0,
+ .BI = 1,
+ .V = 1
+ }
+ },
+ .OR = {
+ .B = {
+ .AM = 0xffff8000 >> 15,
+ .SCY = 1,
+ .BSCY = 0
+ }
+ }
+ },
+
+ /* D_CS2 unused */
+ {
+ .BR = {
+ .B = {
+ .BA = 0x20000000 >> 15,
+ .PS = 0,
+ .AD_MUX = 1,
+ .BL = 0,
+ .WEBS = 0,
+ .TBDIP = 0,
+ .SETA = 0,
+ .BI = 1,
+ .V = 0
+ }
+ },
+ .OR = {
+ .B = {
+ .AM = 0xfff80000 >> 15,
+ .SCY = 0,
+ .BSCY = 0
+ }
+ }
+ },
+
+ /* D_CS3 for MRAM, ARCNET */
+ {
+ .BR = {
+ .B = {
+ .BA = 0x3ff80000 >> 15,
+ .PS = 1,
+ .AD_MUX = 1,
+ .BL = 0,
+ .WEBS = 1,
+ .TBDIP = 0,
+ .SETA = 0,
+ .BI = 1,
+ .V = 1
+ }
+ },
+ .OR = {
+ .B = {
+ .AM = 0xfff80000 >> 15,
+ .SCY = 1,
+ .BSCY = 0
+ }
+ }
+ }
+#elif defined(MPC55XX_BOARD_MPC5674F_RSM6)
+ /* D_CS0 for MRAM */
+ {
+ .BR = {
+ .B = {
+ .BA = 0x20000000 >> 15,
+ .PS = 0,
+ .AD_MUX = 1,
+ .BL = 0,
+ .WEBS = 1,
+ .TBDIP = 0,
+ .SETA = 0,
+ .BI = 1,
+ .V = 1
+ }
+ },
+ .OR = {
+ .B = {
+ .AM = 0xffc00000 >> 15,
+ .SCY = 4,
+ .BSCY = 0
+ }
+ }
+ },
+
+ /* D_CS1 for FPGA */
+ {
+ .BR = {
+ .B = {
+ .BA = 0x21000000 >> 15,
+ .PS = 0,
+ .AD_MUX = 1,
+ .BL = 0,
+ .WEBS = 0,
+ .TBDIP = 0,
+ .SETA = 0,
+ .BI = 1,
+ .V = 1
+ }
+ },
+ .OR = {
+ .B = {
+ .AM = 0xff800000 >> 15,
+ .SCY = 0,
+ .BSCY = 0
+ }
+ }
+ },
+
+ /* D_CS2 unused */
+ {
+ .BR = { .R = 0x20000002 },
+ .OR = { .R = 0xe0000000 }
+ },
+
+ /* D_CS3 for Ethernet Controller */
+ {
+ .BR = {
+ .B = {
+ .BA = 0x23000000 >> 15,
+ .PS = 1,
+ .AD_MUX = 1,
+ .BL = 0,
+ .WEBS = 1,
+ .TBDIP = 0,
+ .SETA = 0,
+ .BI = 1,
+ .V = 1
+ }
+ },
+ .OR = {
+ .B = {
+ .AM = 0xfff80000 >> 15,
+ .SCY = 8,
+ .BSCY = 0
+ }
+ }
+ }
+#endif
+};
+
+const size_t mpc55xx_start_config_ebi_cal_cs_count [] = {
+ RTEMS_ARRAY_SIZE(mpc55xx_start_config_ebi_cal_cs)
+};
+
+#endif /* MPC55XX_HAS_EBI */
diff --git a/bsps/powerpc/mpc55xxevb/start/start-config-ebi-cs.c b/bsps/powerpc/mpc55xxevb/start/start-config-ebi-cs.c
new file mode 100644
index 0000000000..d12d0fa059
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-config-ebi-cs.c
@@ -0,0 +1,164 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief EBI chip-select configuration.
+ */
+
+/*
+ * 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/mpc55xx-config.h>
+
+#ifdef MPC55XX_HAS_EBI
+
+const struct EBI_CS_tag mpc55xx_start_config_ebi_cs [] = {
+#if defined(MPC55XX_BOARD_GWLCFM)
+ /* CS0: External SRAM (16 bit, 1 wait states, 512kB, no burst) */
+ {
+ {
+ .B.BA = 0x20000000>>15,
+ .B.PS = 1,
+ .B.AD_MUX = 1,
+ .B.WEBS = 1,
+ .B.TBDIP = 0,
+ .B.BI = 1,
+ .B.V = 1
+ },
+ {
+ .B.AM = 0x1fff0,
+ .B.SCY = 1,
+ .B.BSCY = 0
+ }
+ },
+ /* CS1: External USB controller (16 bit, 3 wait states, 32kB, no burst) */
+ {
+ {
+ .B.BA = 0x22000000>>15,
+ .B.PS = 1,
+ .B.AD_MUX = 1,
+ .B.WEBS = 0,
+ .B.TBDIP = 0,
+ .B.BI = 1,
+ .B.V = 1
+ },
+ {
+ .B.AM = 0x1ffff,
+ .B.SCY = 3,
+ .B.BSCY = 0
+ }
+ },
+ /* CS2: Ethernet (16 bit, 2 wait states, 32kB, no burst) */
+ {
+ {
+ .B.BA = 0x22800000>>15,
+ .B.PS = 1,
+ .B.AD_MUX = 1,
+ .B.WEBS = 1,
+ .B.TBDIP = 0,
+ .B.BI = 1,
+ .B.V = 1
+ },
+ {
+ .B.AM = 0x1ffff,
+ .B.SCY = 1,
+ .B.BSCY = 0
+ }
+ },
+ { /* CS3: MOST Companion. */
+ {
+ .B.BA = 0x23000000>>15,
+ .B.PS = 1,
+ .B.AD_MUX = 1,
+ .B.WEBS = 0,
+ .B.TBDIP = 0,
+ .B.BI = 1,
+ .B.V = 1
+ },
+
+ {
+ .B.AM = 0x1fff0,
+ .B.SCY = 1,
+ .B.BSCY = 0
+ }
+ }
+#elif defined(MPC55XX_BOARD_PHYCORE_MPC5554)
+ /* CS0: External flash. */
+ {
+ { .R = 0x20000003 }, /* Base 0x2000000, Burst Inhibit, Valid */
+ { .R = 0xff000050 }
+ },
+ /* CS1: External synchronous burst mode SRAM. */
+ {
+ { .R = 0x21000051 }, /* Base 0x2100000, 4-word Burst Enabled, Valid */
+ { .R = 0xff000000 } /* No wait states. */
+ },
+ /* CS2: External LAN91C111 */
+ {
+ { .R = 0x22000003 }, /* Base 0x22000000, Burst inhibit, valid */
+ { .R = 0xff000010 }
+ },
+
+ /* CS3: External FPGA */
+ {
+ { .R = 0x23000003 }, /* Base 0x23000000, Burst inhibit, valid. */
+ { .R = 0xff000020 }
+ }
+#elif defined(MPC55XX_BOARD_MPC5566EVB)
+ /* CS0: External SRAM (2 wait states, 512kB, 4 word burst) */
+ {
+ {
+ .B.BA = 0,
+ .B.PS = 1,
+ .B.BL = 1,
+ .B.WEBS = 0,
+ .B.TBDIP = 0,
+ .B.BI = 1, /* TODO: Enable burst */
+ .B.V = 1
+ },
+
+ {
+ .B.AM = 0x1fff0,
+ .B.SCY = 0,
+ .B.BSCY = 0
+ }
+ },
+ { { .R = 0 }, { .R = 0 } }, /* CS1: Unused. */
+ { { .R = 0 }, { .R = 0 } }, /* CS2: Unused. */
+ { /* CS3: ethernet? */
+ {
+ .B.BA = 0x7fff,
+ .B.PS = 1,
+ .B.BL = 0,
+ .B.WEBS = 0,
+ .B.TBDIP = 0,
+ .B.BI = 1,
+ .B.V = 1
+ },
+
+ {
+ .B.AM = 0x1ffff,
+ .B.SCY = 1,
+ .B.BSCY = 0
+ }
+ }
+#endif
+};
+
+const size_t mpc55xx_start_config_ebi_cs_count [] = {
+ RTEMS_ARRAY_SIZE(mpc55xx_start_config_ebi_cs)
+};
+
+#endif /* MPC55XX_HAS_EBI */
diff --git a/bsps/powerpc/mpc55xxevb/start/start-config-ebi.c b/bsps/powerpc/mpc55xxevb/start/start-config-ebi.c
new file mode 100644
index 0000000000..1ce2b297d8
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-config-ebi.c
@@ -0,0 +1,62 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief EBI configuration.
+ */
+
+/*
+ * Copyright (c) 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/mpc55xx-config.h>
+
+#ifdef MPC55XX_HAS_EBI
+
+const mpc55xx_ebi_config mpc55xx_start_config_ebi [] = {
+ #if defined(MPC55XX_BOARD_GWLCFM)
+ {
+ .ebi_mcr = {
+ .B = {
+ .DBM = 1,
+ .AD_MUX = 1, /* use multiplexed bus */
+ .D16_31 = 1 /* use lower AD bus */
+ }
+ },
+ .siu_eccr_ebdf = 4 - 1 /* use CLK/4 as bus clock */
+ }
+ #elif (defined(MPC55XX_BOARD_MPC5674FEVB) \
+ || defined(MPC55XX_BOARD_MPC5674F_ECU508) \
+ || defined(MPC55XX_BOARD_MPC5674F_RSM6)) \
+ && defined(MPC55XX_NEEDS_LOW_LEVEL_INIT)
+ {
+ .ebi_mcr = {
+ .B = {
+ .ACGE = 0,
+ .MDIS = 0,
+ .D16_31 = 1,
+ .AD_MUX = 0,
+ .DBM = 0
+ }
+ },
+ .siu_eccr_ebdf = 2 - 1
+ }
+ #endif
+};
+
+const size_t mpc55xx_start_config_ebi_count [] = {
+ RTEMS_ARRAY_SIZE(mpc55xx_start_config_ebi)
+};
+
+#endif /* MPC55XX_HAS_EBI */
diff --git a/bsps/powerpc/mpc55xxevb/start/start-config-mmu-early.c b/bsps/powerpc/mpc55xxevb/start/start-config-mmu-early.c
new file mode 100644
index 0000000000..84e638d55c
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-config-mmu-early.c
@@ -0,0 +1,64 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief MMU early configuration.
+ */
+
+/*
+ * Copyright (c) 2011-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.
+ */
+
+#include <bsp/mpc55xx-config.h>
+
+const struct MMU_tag mpc55xx_start_config_mmu_early [] = {
+#if (defined(MPC55XX_BOARD_MPC5674F_ECU508) \
+ || defined(MPC55XX_BOARD_MPC5674F_RSM6)) \
+ && !defined(MPC55XX_NEEDS_LOW_LEVEL_INIT)
+ /* Used as cache-inhibited area later (ADC, DSPI queues) */
+ MPC55XX_MMU_TAG_INITIALIZER(14, 0x4003c000, MPC55XX_MMU_16K, 0, 1, 1, 0)
+#elif MPC55XX_CHIP_FAMILY == 555
+ /* Internal SRAM 96k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_256K, 1, 1, 1, 0),
+#elif MPC55XX_CHIP_FAMILY == 556
+ /* Internal SRAM 128k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_64K, 1, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(5, 0x40010000, MPC55XX_MMU_64K, 0, 1, 1, 0),
+#elif MPC55XX_CHIP_FAMILY == 564
+ /* Internal flash 1M */
+ MPC55XX_MMU_TAG_INITIALIZER(0, 0x00000000, MPC55XX_MMU_1M, 1, 0, 1, 1),
+ /* IO */
+ MPC55XX_MMU_TAG_INITIALIZER(1, 0xffe00000, MPC55XX_MMU_2M, 0, 1, 1, 1),
+ MPC55XX_MMU_TAG_INITIALIZER(2, 0xc3f00000, MPC55XX_MMU_1M, 0, 1, 1, 1),
+ /* Internal SRAM 64k + 64k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_64K, 1, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(4, 0x50000000, MPC55XX_MMU_64K, 0, 1, 1, 0)
+#elif MPC55XX_CHIP_FAMILY == 566
+ /* Internal flash 2M */
+ MPC55XX_MMU_TAG_INITIALIZER(1, 0x00000000, MPC55XX_MMU_1M, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(4, 0x00100000, MPC55XX_MMU_1M, 1, 0, 1, 0),
+ /* IO */
+ MPC55XX_MMU_TAG_INITIALIZER(2, 0xc3f00000, MPC55XX_MMU_1M, 0, 1, 1, 1),
+ /* Internal SRAM 512k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_256K, 1, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(5, 0x40040000, MPC55XX_MMU_256K, 1, 1, 1, 0)
+#elif MPC55XX_CHIP_FAMILY == 567
+ /* Internal SRAM 256k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_256K, 1, 1, 1, 0)
+#endif
+};
+
+const size_t mpc55xx_start_config_mmu_early_count [] = {
+ RTEMS_ARRAY_SIZE(mpc55xx_start_config_mmu_early)
+};
diff --git a/bsps/powerpc/mpc55xxevb/start/start-config-mmu.c b/bsps/powerpc/mpc55xxevb/start/start-config-mmu.c
new file mode 100644
index 0000000000..7cf319edd3
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-config-mmu.c
@@ -0,0 +1,151 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief MMU configuration.
+ */
+
+/*
+ * 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/mpc55xx-config.h>
+
+const struct MMU_tag mpc55xx_start_config_mmu [] = {
+#if defined(MPC55XX_BOARD_GWLCFM)
+ /* External Ethernet Controller 64k */
+ MPC55XX_MMU_TAG_INITIALIZER(5, 0x3fff8000, MPC55XX_MMU_64K, 0, 1, 1, 1)
+#elif defined(MPC55XX_BOARD_PHYCORE_MPC5554)
+ /* Arguments macro: idx, addr, size, x, w, r, io */
+ MPC55XX_MMU_TAG_INITIALIZER(8, 0x20000000, MPC55XX_MMU_8M, 1, 0, 1, 0), /* External FLASH 8M */
+ MPC55XX_MMU_TAG_INITIALIZER(2, 0x21000000, MPC55XX_MMU_4M, 0, 1, 1, 0), /* Lower half SRAM */
+ MPC55XX_MMU_TAG_INITIALIZER(5, 0x21400000, MPC55XX_MMU_4M, 1, 1, 1, 0), /* Upper half SRAM ("debug") */
+ MPC55XX_MMU_TAG_INITIALIZER(6, 0x22000000, MPC55XX_MMU_16M, 0, 1, 1, 1), /* LAN91C111 */
+ MPC55XX_MMU_TAG_INITIALIZER(7, 0x23000000, MPC55XX_MMU_16M, 0, 1, 1, 1), /* FPGA */
+#elif defined(MPC55XX_BOARD_MPC5566EVB)
+ /* Internal flash 3M */
+ MPC55XX_MMU_TAG_INITIALIZER(1, 0x00000000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(6, 0x00010000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(7, 0x00020000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(8, 0x00030000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(9, 0x00040000, MPC55XX_MMU_256K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(10, 0x00080000, MPC55XX_MMU_256K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(11, 0x000c0000, MPC55XX_MMU_256K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(12, 0x00100000, MPC55XX_MMU_1M, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(13, 0x00200000, MPC55XX_MMU_1M, 1, 0, 1, 0),
+ /* External SRAM 512k */
+ MPC55XX_MMU_TAG_INITIALIZER(2, 0x20000000, MPC55XX_MMU_256K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(14, 0x20040000, MPC55XX_MMU_256K, 0, 1, 1, 0),
+ /* Internal SRAM 128k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_64K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(5, 0x40010000, MPC55XX_MMU_64K, 0, 1, 1, 0),
+ /* External Ethernet Controller 64k */
+ MPC55XX_MMU_TAG_INITIALIZER(15, 0x3fff8000, MPC55XX_MMU_64K, 0, 1, 1, 1)
+#elif defined(MPC55XX_BOARD_MPC5674FEVB)
+ /* Internal flash 4M */
+ MPC55XX_MMU_TAG_INITIALIZER(1, 0x00000000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(5, 0x00010000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(6, 0x00020000, MPC55XX_MMU_128K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(7, 0x00040000, MPC55XX_MMU_256K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(8, 0x00080000, MPC55XX_MMU_512K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(9, 0x00100000, MPC55XX_MMU_1M, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(10, 0x00200000, MPC55XX_MMU_2M, 1, 0, 1, 0),
+ /* External SRAM 512k */
+ MPC55XX_MMU_TAG_INITIALIZER(2, 0x20000000, MPC55XX_MMU_512K, 0, 1, 1, 0),
+ /* Internal SRAM 256k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_128K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(11, 0x40020000, MPC55XX_MMU_64K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(12, 0x40030000, MPC55XX_MMU_32K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(13, 0x40038000, MPC55XX_MMU_16K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(14, 0x4003c000, MPC55XX_MMU_16K, 0, 1, 1, 1),
+ /* External Ethernet controller */
+ MPC55XX_MMU_TAG_INITIALIZER(15, 0x3fff8000, MPC55XX_MMU_64K, 0, 1, 1, 1)
+#elif defined(MPC55XX_BOARD_MPC5674F_ECU508)
+ #if defined(MPC55XX_NEEDS_LOW_LEVEL_INIT)
+ /* Arguments macro: idx, addr, size, x, w, r, io */
+
+ /* Internal flash 4M */
+ /* First 64k unused, to detect NULL pointer access */
+ MPC55XX_MMU_TAG_INITIALIZER(1, 0x00000000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(5, 0x00010000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(6, 0x00020000, MPC55XX_MMU_128K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(7, 0x00040000, MPC55XX_MMU_256K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(8, 0x00080000, MPC55XX_MMU_512K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(9, 0x00100000, MPC55XX_MMU_1M, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(10, 0x00200000, MPC55XX_MMU_2M, 1, 0, 1, 0),
+ /* External SRAM 2M */
+ #ifndef BSP_DATA_CACHE_USE_WRITE_THROUGH
+ MPC55XX_MMU_TAG_INITIALIZER(2, 0x20000000, MPC55XX_MMU_2M, 0, 1, 1, 0),
+ #else
+ MPC55XX_MMU_TAG_INITIALIZER(2, 0x20000000, MPC55XX_MMU_2M, 0, 1, 1, 2),
+ #endif
+ /* Internal SRAM 256k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_256K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(11, 0x40020000, MPC55XX_MMU_64K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(12, 0x40030000, MPC55XX_MMU_32K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(13, 0x40038000, MPC55XX_MMU_16K, 0, 1, 1, 0),
+ /* Used as cache-inhibited area (ADC, DSPI queues) */
+ MPC55XX_MMU_TAG_INITIALIZER(14, 0x4003c000, MPC55XX_MMU_16K, 0, 1, 1, 1),
+ /* External Ethernet controller */
+ MPC55XX_MMU_TAG_INITIALIZER(15, 0x3fff8000, MPC55XX_MMU_1K, 0, 1, 1, 1),
+ /* External MRAM 128k */
+ MPC55XX_MMU_TAG_INITIALIZER(16, 0x3ffa0000, MPC55XX_MMU_128K, 0, 1, 1, 0),
+ /* External ARCNET controller */
+ MPC55XX_MMU_TAG_INITIALIZER(17, 0x3ffc0000, MPC55XX_MMU_1K, 0, 1, 1, 1)
+ /* Peripheral Bridge A-Registers on MMU-table pos 4 */
+ /* Peripheral Bridge B-Registers on MMU-table pos 0 */
+ #else
+ /* Used as cache-inhibited area (ADC, DSPI queues) */
+ MPC55XX_MMU_TAG_INITIALIZER(14, 0x4003c000, MPC55XX_MMU_16K, 0, 1, 1, 1)
+ #endif
+#elif defined(MPC55XX_BOARD_MPC5674F_RSM6)
+ /* Arguments macro: idx, addr, size, x, w, r, io */
+
+ /* Internal flash 4M */
+ /* First 64k unused, to detect NULL pointer access */
+ MPC55XX_MMU_TAG_INITIALIZER(1, 0x00000000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(5, 0x00010000, MPC55XX_MMU_64K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(6, 0x00020000, MPC55XX_MMU_128K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(7, 0x00040000, MPC55XX_MMU_256K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(8, 0x00080000, MPC55XX_MMU_512K, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(9, 0x00100000, MPC55XX_MMU_1M, 1, 0, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(10, 0x00200000, MPC55XX_MMU_2M, 1, 0, 1, 0),
+ /* External MRAM 4M */
+ MPC55XX_MMU_TAG_INITIALIZER(2, 0x20000000, MPC55XX_MMU_4M, 0, 1, 1, 0),
+ /* Internal SRAM 256k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_256K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(11, 0x40020000, MPC55XX_MMU_64K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(12, 0x40030000, MPC55XX_MMU_32K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(13, 0x40038000, MPC55XX_MMU_16K, 0, 1, 1, 0),
+ /* Used as cache-inhibited area (ADC, DSPI queues) */
+ MPC55XX_MMU_TAG_INITIALIZER(14, 0x4003c000, MPC55XX_MMU_16K, 0, 1, 1, 1),
+ /* External FPGA */
+ MPC55XX_MMU_TAG_INITIALIZER(15, 0x21000000, MPC55XX_MMU_8M, 0, 1, 1, 1),
+ /* External Ethernet controller */
+ MPC55XX_MMU_TAG_INITIALIZER(16, 0x23000000, MPC55XX_MMU_1K, 0, 1, 1, 1)
+#elif MPC55XX_CHIP_FAMILY == 564
+ /* Internal flash 1M */
+ MPC55XX_MMU_TAG_INITIALIZER(0, 0x00000000, MPC55XX_MMU_1M, 1, 0, 1, 0),
+ /* IO */
+ MPC55XX_MMU_TAG_INITIALIZER(1, 0xffe00000, MPC55XX_MMU_2M, 0, 1, 1, 1),
+ MPC55XX_MMU_TAG_INITIALIZER(2, 0xc3f00000, MPC55XX_MMU_1M, 0, 1, 1, 1),
+ /* Internal SRAM 64k + 64k */
+ MPC55XX_MMU_TAG_INITIALIZER(3, 0x40000000, MPC55XX_MMU_64K, 0, 1, 1, 0),
+ MPC55XX_MMU_TAG_INITIALIZER(4, 0x50000000, MPC55XX_MMU_64K, 0, 1, 1, 0)
+#endif
+};
+
+const size_t mpc55xx_start_config_mmu_count [] = {
+ RTEMS_ARRAY_SIZE(mpc55xx_start_config_mmu)
+};
diff --git a/bsps/powerpc/mpc55xxevb/start/start-config-siu-pcr.c b/bsps/powerpc/mpc55xxevb/start/start-config-siu-pcr.c
new file mode 100644
index 0000000000..8355e647ca
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-config-siu-pcr.c
@@ -0,0 +1,148 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief SIU PCR configuration.
+ */
+
+/*
+ * 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/mpc55xx-config.h>
+
+const mpc55xx_siu_pcr_config mpc55xx_start_config_siu_pcr [] = {
+#if defined(MPC55XX_BOARD_GWLCFM)
+ { 0,16, 0, {.B.PA = 1, .B.WPE = 0}}, /* PA[ 0..15] analog input */
+ { 16, 4, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PB[ 0.. 4] LED/CAN_STBN out */
+ { 20, 2, 0, {.B.PA = 0,.B.IBE = 1,.B.WPE = 0}}, /* PB[ 5.. 6] CAN_ERR/USBFLGC in*/
+ { 22, 1, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PB[ 7 ] FR_A_EN out */
+ { 23, 4, 0, {.B.PA = 0,.B.IBE = 1,.B.WPE = 0}}, /* PB[ 8..10] IRQ/FR_A_ERR/USB_RDYin */
+ { 27, 1, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PB[11..11] FR_STBN out */
+
+ { 32, 2, 0, {.B.PA = 2,.B.OBE = 1,.B.WPE = 0}}, /* PC[ 0.. 1] FR_A_TX/TXEN out */
+ { 34, 1, 0, {.B.PA = 2,.B.IBE = 1,.B.WPE = 0}}, /* PC[ 2.. 2] FR_A_RX in */
+ { 35, 2, 0, {.B.PA = 0,.B.IBE = 1,.B.WPE = 0}}, /* PC[ 3.. 4] INIT_ERR/ISB_IRQ in */
+ { 37, 2, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PC[ 5.. 6] PWRO1/2_ON out */
+ { 39, 1, 0, {.B.PA = 2,.B.IBE = 1,.B.WPE = 0}}, /* PC[ 7.. 7] FR_B_RX in */
+ { 40, 2, 0, {.B.PA = 2,.B.OBE = 1,.B.WPE = 0}}, /* PC[ 8.. 9] FR_B_TX/TXEN out */
+ { 42, 1, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PC[10 ] FR_B_EN out */
+ { 43, 1, 0, {.B.PA = 0,.B.IBE = 1,.B.WPE = 0}}, /* PC[11 ] FOR_STATUS in */
+ { 44, 1, 0, {.B.PA = 0,.B.IBE = 1,.B.WPE = 0}}, /* PC[12 ] FR_B_ERRN in */
+ { 45, 1, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PC[13 ] HS_CAN_STBN out */
+ { 46, 1, 0, {.B.PA = 0,.B.IBE = 1,.B.WPE = 0}}, /* PC[14 ] HS_CAN_ERR in */
+ { 47, 1, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PC[15 ] HS_CAN_EN out */
+
+ { 48, 1, 0, {.B.PA = 1,.B.OBE = 1,.B.WPE = 0}}, /* PD[ 0 ] HS_CAN_TX out */
+ { 49, 1, 0, {.B.PA = 1,.B.IBE = 1,.B.WPE = 0}}, /* PD[ 1 ] HS_CAN_RX in */
+ { 50, 2, 0, {.B.PA = 0,.B.IBE = 1,.B.WPE = 0}}, /* PD[ 2.. 3] PWRO1/2_OC in */
+ { 52, 1, 0, {.B.PA = 1,.B.OBE = 1,.B.WPE = 0}}, /* PD[ 4 ] LS_CAN_TX out */
+ { 53, 1, 0, {.B.PA = 1,.B.IBE = 1,.B.WPE = 0}}, /* PD[ 5 ] LS_CAN_RX in */
+ { 54, 1, 0, {.B.PA = 1,.B.OBE = 1,.B.WPE = 0}}, /* PD[ 6 ] HS_CAN_TX out */
+ { 55, 1, 0, {.B.PA = 1,.B.IBE = 1,.B.WPE = 0}}, /* PD[ 7 ] HS_CAN_RX in */
+ { 56, 1, 0, {.B.PA = 2,.B.IBE = 1,.B.OBE = 1,.B.WPE = 0}},
+ /* PD[ 8 ] I2C_SCL in/out */
+ { 57, 1, 0, {.B.PA = 2,.B.IBE = 1,.B.OBE = 1,.B.WPE = 0}},
+ /* PD[ 9 ] I2C_SDA in/out */
+
+ { 58, 1, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PD[10] LS_CAN_EN out*/
+ { 59, 3, 0, {.B.PA = 0,.B.IBE = 1,.B.WPE = 0}},
+ /* PD[11..13] PWO1_OC, MOCO_INT in */
+
+ { 62, 4, 0, {.B.PA = 0,.B.IBE = 1,.B.WPE = 0}}, /* PD[14..15] USB_FLGA/B in */
+
+ { 64, 5, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PE[ 0.. 4] LED_EXT1-5. out*/
+ { 70, 1, 0, {.B.PA = 1,.B.SRC = 3,.B.WPE = 0}}, /* PE[ 6.. 6] CLKOUT out*/
+
+ { 80, 1, 0, {.B.PA = 1,.B.SRC = 1,.B.WPE = 0}}, /* PF[ 0.. 0] RD_WR out*/
+ { 81, 1, 0, {.B.PA = 0,.B.SRC = 0,.B.WPE = 0}}, /* PF[ 1.. 1] (nc) in */
+ { 82, 8, 0, {.B.PA = 2,.B.SRC = 1,.B.WPE = 0}}, /* PF[ 2..11] ADDR[8..15] out*/
+ { 90, 2, 0, {.B.PA = 1,.B.SRC = 1,.B.WPE = 0}}, /* PF[ 2..11] CS[0..1] out*/
+ { 92, 1, 0, {.B.PA = 3,.B.SRC = 3,.B.WPE = 0}}, /* PF[ 12] ALE out*/
+ { 93, 3, 0, {.B.PA = 1,.B.SRC = 1,.B.WPE = 0}}, /* PF[13..15] OE/WE out*/
+
+ { 96,16, 0, {.B.PA = 1,.B.SRC = 1,.B.WPE = 0}}, /* PG[ 0..15] AD16..31 in/out*/
+
+ {113, 1, 1, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PH[ 1.. 1] RES_MOSTComp out*/
+ {114, 1, 0, {.B.PA = 3,.B.OBE = 1,.B.WPE = 0}}, /* PH[ 2.. 2] CS3_MOSTComp out*/
+ {115, 1, 0, {.B.PA = 3,.B.OBE = 1,.B.WPE = 0}}, /* PH[ 3.. 3] CS2_ETH out*/
+ {116, 2, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PH[ 4.. 5] FR/HC_TERM out*/
+ {118, 1, 0, {.B.PA = 2,.B.OBE = 1,.B.WPE = 0}}, /* PH[ 6.. 6] LIN_Tx out*/
+ {119, 1, 0, {.B.PA = 2,.B.IBE = 1,.B.WPE = 0}}, /* PH[ 7.. 7] LIN_Rx in */
+ {120, 1, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PH[ 8..11] LIN_SLP,RST out*/
+ {121, 2, 1, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}}, /* PH[ 8..11] LIN_SLP,RST out*/
+ {120, 1, 0, {.B.PA = 0,.B.OBE = 1,.B.WPE = 0}} /* PH[ 8..11] LIN_SLP,RST out*/
+#elif defined(MPC55XX_BOARD_PHYCORE_MPC5554)
+ { 0, 4, 0, {.B.PA = 1, .B.DSC = 1,.B.WPE=1,.B.WPS=1}}, /* !CS [0:3] */
+ { 4,24, 0, {.B.PA = 1, .B.DSC = 1 }}, /* ADDR [8 : 31] */
+ { 28,32, 0, {.B.PA = 1, .B.DSC = 1 }}, /* DATA [0 : 31] */
+ { 60, 4, 0, {.B.PA = 1, .B.DSC = 1, }}, /* TSIZ[0:1], RD_!WR, BDIP */
+ { 64, 6, 0, {.B.PA = 1, .B.DSC = 1,.B.WPE=1,.B.WPS=1}}, /* RD_!WR, BDIP, !WE, !OE, !TS */
+ { 89, 4, 0, {.B.PA = 1 }}, /* ESCI_A and ESCI_B */
+ {229, 4, 0, { .B.OBE= 1,.B.DSC = 1 }} /* CLKOUT */
+#elif defined(MPC55XX_BOARD_MPC5566EVB)
+ { 0, 1, 0, {.B.PA = 1,.B.DSC = 1,.B.WPE=1,.B.WPS=1}}, /* !CS [0] */
+ { 3, 1, 0, {.B.PA = 1,.B.DSC = 1,.B.WPE=1,.B.WPS=1}}, /* !CS [3] */
+ { 4,24, 0, {.B.PA = 1,.B.DSC = 1 }}, /* ADDR [8 : 31] */
+ { 28,16, 0, {.B.PA = 1,.B.DSC = 1 }}, /* DATA [0 : 15] */
+ { 62, 8, 0, {.B.PA = 1,.B.DSC = 1,.B.WPE=1,.B.WPS=1}}, /* RD_!WR, BDIP,
+ !WE, !OE, !TS */
+ { 89, 2, 0, {.B.PA = 1 }} /* ESCI_B */
+#elif defined(MPC55XX_BOARD_MPC5674FEVB)
+ { 89, 2, 0, { .B = { .PA = 1 } } }, /* ESCI_A */
+ { 256, 1, 0, { .B = { .PA = 1, .DSC = 1 } } }, /* D_CS0 */
+ { 257, 1, 0, { .B = { .PA = 2, .DSC = 1 } } }, /* D_ADD_DAT31 */
+ { 259, 4, 0, { .B = { .PA = 1, .DSC = 1 } } }, /* D_ADD12 .. D_ADD15 */
+ { 263, 15, 0, { .B = { .PA = 2, .DSC = 1 } } }, /* D_ADD_DAT16 .. D_ADD_DAT30 */
+ { 278, 16, 0, { .B = { .PA = 1, .DSC = 1 } } }, /* D_ADD_DAT0 .. D_ADD_DAT15 */
+ { 294, 6, 0, { .B = { .PA = 1, .DSC = 1 } } }, /* D_RD_WR, D_WE0, D_WE1, D_OE, D_TS, D_ALE */
+ { 301, 1, 0, { .B = { .PA = 1, .DSC = 1 } } }, /* D_CS1 */
+ { 302, 6, 0, { .B = { .PA = 1, .DSC = 1 } } } /* D_BDIP, D_WE2, D_WE3, D_ADD9 .. D_ADD11 */
+#elif defined(MPC55XX_BOARD_MPC5674F_ECU508) \
+ && defined(MPC55XX_NEEDS_LOW_LEVEL_INIT)
+ { 196, 2, 0, { .B = { .PA = 0, .OBE = 1, .WPE = 0 } } }, /* EMIOS17 .. EMIOS18 (5VS_EN, 80V_EN) */
+ { 200, 4, 0, { .B = { .PA = 0, .OBE = 1, .WPE = 0 } } }, /* EMIOS21 .. EMIOS24 (\KS_RST, \LS_RST, \IGNINJ_RST, \INJDI_RST) */
+ { 204, 1, 1, { .B = { .PA = 0, .OBE = 1, .WPE = 0 } } }, /* EMIOS25 (HBR12_RST) */
+ { 244, 2, 0, { .B = { .PA = 1 } } }, /* ESCI_C */
+ { 256, 1, 0, { .B = { .PA = 1, .DSC = 0 } } }, /* D_CS0 */
+ { 257, 1, 0, { .B = { .PA = 2, .DSC = 1 } } }, /* D_ADD_DAT31 */
+ { 258, 1, 0, { .B = { .PA = 1, .DSC = 0 } } }, /* D_CS3 */
+ { 259, 4, 0, { .B = { .PA = 1, .DSC = 0 } } }, /* D_ADD12 .. D_ADD15 */
+ { 263, 15, 0, { .B = { .PA = 2, .DSC = 1 } } }, /* D_ADD_DAT16 .. D_ADD_DAT30 */
+ { 278, 16, 0, { .B = { .PA = 1, .DSC = 0 } } }, /* D_ADD_DAT0 .. D_ADD_DAT15 */
+ { 294, 6, 0, { .B = { .PA = 1, .DSC = 0 } } }, /* D_RD_WR, D_WE0, D_WE1, D_OE, D_TS, D_ALE */
+ { 301, 1, 0, { .B = { .PA = 1, .DSC = 0 } } }, /* D_CS1 */
+ { 302, 3, 0, { .B = { .PA = 1, .DSC = 0 } } }, /* D_BDIP, D_WE2, D_WE3 */
+ { 305, 3, 0, { .B = { .PA = 1, .DSC = 0 } } }, /* D_ADD9 .. D_ADD11 */
+ { 432, 1, 1, { .B = { .PA = 0, .OBE = 1, .WPE = 0 } } }, /* EMIOS26 (HBR34_RST) */
+ { 433, 1, 0, { .B = { .PA = 0, .OBE = 1, .WPE = 0 } } } /* EMIOS27 (\ETH_RST) */
+#elif defined(MPC55XX_BOARD_MPC5674F_RSM6)
+ { 89, 1, 0, { .B = { .PA = 1, .OBE = 1, .IBE = 1, .WPE = 1, .WPS = 1 } } }, /* TXD_A (ESCI_A)*/
+ { 90, 1, 0, { .B = { .PA = 1, .OBE = 0, .IBE = 1, .WPE = 1, .WPS = 1 } } }, /* RXD_A (ESCI_A)*/
+ { 256, 1, 0, { .B = { .PA = 1, .DSC = 3, .WPE = 1, .WPS = 1 } } }, /* D_CS0 */
+ { 257, 1, 0, { .B = { .PA = 2, .DSC = 3, .WPE = 1, .WPS = 1 } } }, /* D_ADD_DAT31 */
+ { 258, 1, 0, { .B = { .PA = 1, .DSC = 3, .WPE = 1, .WPS = 1 } } }, /* D_CS3 */
+ { 259, 4, 0, { .B = { .PA = 1, .DSC = 3, .WPE = 1, .WPS = 1 } } }, /* D_ADD12 .. D_ADD15 */
+ { 263, 15, 0, { .B = { .PA = 2, .DSC = 3, .WPE = 1, .WPS = 1 } } }, /* D_ADD_DAT16 .. D_ADD_DAT30 */
+ { 278, 16, 0, { .B = { .PA = 1, .DSC = 3, .WPE = 1, .WPS = 1 } } }, /* D_ADD_DAT0 .. D_ADD_DAT15 */
+ { 294, 6, 0, { .B = { .PA = 1, .DSC = 3, .WPE = 1, .WPS = 1 } } }, /* D_RD_WR, D_WE0, D_WE1, D_OE, D_TS, D_ALE */
+ { 301, 1, 0, { .B = { .PA = 1, .DSC = 3, .WPE = 1, .WPS = 1 } } }, /* D_CS1 */
+ { 302, 3, 0, { .B = { .PA = 1, .DSC = 3, .WPE = 1, .WPS = 1 } } }, /* D_BDIP, D_WE2, D_WE3 */
+ { 305, 3, 0, { .B = { .PA = 1, .DSC = 3, .WPE = 1, .WPS = 1 } } } /* D_ADD9 .. D_ADD11 */
+#endif
+};
+
+const size_t mpc55xx_start_config_siu_pcr_count [] = {
+ RTEMS_ARRAY_SIZE(mpc55xx_start_config_siu_pcr)
+};
diff --git a/bsps/powerpc/mpc55xxevb/start/start-early.c b/bsps/powerpc/mpc55xxevb/start/start-early.c
new file mode 100644
index 0000000000..e1a0b3da09
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-early.c
@@ -0,0 +1,216 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief Early initialization 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/mpc55xx-config.h>
+#include <bsp/linker-symbols.h>
+
+/* This function is defined in start.S */
+BSP_START_TEXT_SECTION void mpc55xx_start_load_section(
+ void *dst,
+ const void *src,
+ size_t n
+);
+
+static BSP_START_TEXT_SECTION void mpc55xx_start_mmu(void)
+{
+ #ifdef MPC55XX_BOOTFLAGS
+ /* If the low bit of bootflag 0 is clear don't change the MMU. */
+ bool do_mmu_config = (mpc55xx_bootflag_0 [0] & 1) != 0;
+ #else
+ bool do_mmu_config = true;
+ #endif
+
+ if (do_mmu_config) {
+ mpc55xx_start_mmu_apply_config(
+ &mpc55xx_start_config_mmu [0],
+ mpc55xx_start_config_mmu_count [0]
+ );
+ }
+}
+
+static BSP_START_TEXT_SECTION void mpc55xx_start_internal_ram(void)
+{
+ #ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
+ /* Initialize internal SRAM to zero (ECC) */
+ bsp_start_zero(
+ (char *) bsp_ram_start + MPC55XX_EARLY_STACK_SIZE,
+ (size_t) bsp_ram_size - MPC55XX_EARLY_STACK_SIZE
+ );
+ #ifdef MPC55XX_HAS_SECOND_INTERNAL_RAM_AREA
+ bsp_start_zero(&bsp_ram_1_start [0], (size_t) bsp_ram_1_size);
+ #endif
+ #else
+ bsp_start_zero(
+ bsp_section_sbss_begin,
+ (size_t) bsp_section_sbss_size
+ );
+ bsp_start_zero(
+ bsp_section_bss_begin,
+ (size_t) bsp_section_bss_size
+ );
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void mpc55xx_start_load_nocache_section(void)
+{
+ mpc55xx_start_load_section(
+ bsp_section_nocache_begin,
+ bsp_section_nocache_load_begin,
+ (size_t) bsp_section_nocache_size
+ );
+ rtems_cache_flush_multiple_data_lines(
+ bsp_section_nocache_begin,
+ (size_t) bsp_section_nocache_size
+ );
+}
+
+static BSP_START_TEXT_SECTION void mpc55xx_start_mode_change(void)
+{
+ #ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
+ #ifdef MPC55XX_HAS_MODE_CONTROL
+ uint32_t mctl_key1 = 0x5af0;
+ uint32_t mctl_key2 = 0xa50f;
+ int i = 0;
+
+ /* Clear any pending RGM status */
+ RGM.FES.R = 0xffff;
+ RGM.DES.R = 0xffff;
+
+ /* Make sure XOSC and PLLs are on in RUN0 state */
+ ME.DRUN_MC.R = 0x001f0074;
+ ME.RUN_MC [0].R = 0x001f0074;
+
+ /*
+ * Make sure all peripherals are active in DRUN and RUN0 state.
+ *
+ * FIXME: This might be optimized to reduce power consumtion.
+ */
+ for (i = 0; i < 8; ++i) {
+ ME_RUN_PC_32B_tag run_pc = { .R = ME.RUN_PC [i].R };
+
+ run_pc.B.DRUN = 1;
+ run_pc.B.RUN0 = 1;
+
+ ME.RUN_PC [i].R = run_pc.R;
+ }
+
+ /* Switch to RUN0 state */
+ ME.MCTL.R = 0x40000000 | mctl_key1;
+ ME.MCTL.R = 0x40000000 | mctl_key2;
+
+ while (ME.GS.B.S_MTRANS) {
+ /* Wait for mode switch to be completed */
+ }
+ #endif
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void mpc55xx_start_siu(void)
+{
+ size_t i = 0;
+
+ for (i = 0; i < mpc55xx_start_config_siu_pcr_count [0]; ++i) {
+ const mpc55xx_siu_pcr_config *e = &mpc55xx_start_config_siu_pcr [i];
+ int j = e->index;
+ int n = j + e->count;
+ uint8_t gpdo = e->output;
+ uint16_t pcr = e->pcr.R;
+
+ while (j < n) {
+ SIU.GPDO [j].R = gpdo;
+ SIU.PCR [j].R = pcr;
+ ++j;
+ }
+ }
+}
+
+static BSP_START_TEXT_SECTION void mpc55xx_start_ebi_chip_select(void)
+{
+ #ifdef MPC55XX_HAS_EBI
+ size_t i = 0;
+
+ for (i = 0; i < mpc55xx_start_config_ebi_cs_count [0]; ++i) {
+ EBI.CS [i] = mpc55xx_start_config_ebi_cs [i];
+ }
+
+ for (i = 0; i < mpc55xx_start_config_ebi_cal_cs_count [0]; ++i) {
+ EBI.CAL_CS [i] = mpc55xx_start_config_ebi_cal_cs [i];
+ }
+ #endif
+}
+
+static BSP_START_TEXT_SECTION void mpc55xx_start_ebi(void)
+{
+ #ifdef MPC55XX_HAS_EBI
+ size_t i = 0;
+
+ for (i = 0; i < mpc55xx_start_config_ebi_count [0]; ++i) {
+ SIU.ECCR.B.EBDF = mpc55xx_start_config_ebi [i].siu_eccr_ebdf;
+ EBI.MCR.R = mpc55xx_start_config_ebi [i].ebi_mcr.R;
+ }
+ #endif
+}
+
+#ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
+static BSP_START_TEXT_SECTION bool
+mpc55xx_start_is_in_internal_ram(const void *addr)
+{
+ return (size_t) addr - (size_t) bsp_ram_start < (size_t) bsp_ram_size;
+}
+#endif
+
+static BSP_START_TEXT_SECTION void mpc55xx_start_clear_bss(void)
+{
+ #ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
+ if (!mpc55xx_start_is_in_internal_ram(bsp_section_sbss_begin)) {
+ bsp_start_zero(
+ bsp_section_sbss_begin,
+ (size_t) bsp_section_sbss_size
+ );
+ }
+
+ if (!mpc55xx_start_is_in_internal_ram(bsp_section_bss_begin)) {
+ bsp_start_zero(
+ bsp_section_bss_begin,
+ (size_t) bsp_section_bss_size
+ );
+ }
+ #endif
+}
+
+BSP_START_TEXT_SECTION void mpc55xx_start_early(void)
+{
+ mpc55xx_start_watchdog();
+ mpc55xx_start_clock();
+ mpc55xx_start_flash();
+ #if defined(BSP_DATA_CACHE_ENABLED) || defined(BSP_INSTRUCTION_CACHE_ENABLED)
+ mpc55xx_start_cache();
+ #endif
+ mpc55xx_start_internal_ram();
+ mpc55xx_start_load_nocache_section();
+ mpc55xx_start_mmu();
+ mpc55xx_start_mode_change();
+ mpc55xx_start_siu();
+ mpc55xx_start_ebi_chip_select();
+ mpc55xx_start_ebi();
+ mpc55xx_start_clear_bss();
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/start-flash.S b/bsps/powerpc/mpc55xxevb/start/start-flash.S
new file mode 100644
index 0000000000..9c87d38a83
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-flash.S
@@ -0,0 +1,139 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx_asm
+ *
+ * @brief Flash configuration.
+ */
+
+/*
+ * Copyright (c) 2008-2015 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 <libcpu/powerpc-utility.h>
+#include <mpc55xx/reg-defs.h>
+
+ .section ".bsp_start_text", "ax"
+
+#if MPC55XX_CHIP_FAMILY == 551
+
+/* MPC5510 Microcontroller Family Data Sheet, Rev. 3, Table 16, Num 7 */
+.equ FLASH_CLOCK_0, 25000000
+.equ FLASH_CLOCK_1, 50000000
+.equ FLASH_CLOCK_2, 80000000
+.equ FLASH_CLOCK_3, FLASH_CLOCK_2
+.equ FLASH_SETTINGS_0, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_0 | FLASH_BUICR_RWSC_0 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_1 | FLASH_BUICR_IPFEN_1 | FLASH_BUICR_PFLIM_2 | FLASH_BUICR_BFEN
+.equ FLASH_SETTINGS_1, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_1 | FLASH_BUICR_RWSC_1 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_1 | FLASH_BUICR_IPFEN_1 | FLASH_BUICR_PFLIM_2 | FLASH_BUICR_BFEN
+.equ FLASH_SETTINGS_2, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_2 | FLASH_BUICR_RWSC_2 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_1 | FLASH_BUICR_IPFEN_1 | FLASH_BUICR_PFLIM_2 | FLASH_BUICR_BFEN
+.equ FLASH_SETTINGS_3, FLASH_SETTINGS_2
+
+#else
+
+/* Optimized flash configurations (Table 13-15 [MPC5567 Microcontroller Reference Manual]) */
+.equ FLASH_CLOCK_0, 82000000
+.equ FLASH_CLOCK_1, 102000000
+.equ FLASH_CLOCK_2, 132000000
+.equ FLASH_CLOCK_3, 264000000
+.equ FLASH_SETTINGS_0, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_1 | FLASH_BUICR_RWSC_1 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_3 | FLASH_BUICR_IPFEN_3 | FLASH_BUICR_PFLIM_6 | FLASH_BUICR_BFEN
+.equ FLASH_SETTINGS_1, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_1 | FLASH_BUICR_RWSC_2 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_3 | FLASH_BUICR_IPFEN_3 | FLASH_BUICR_PFLIM_6 | FLASH_BUICR_BFEN
+.equ FLASH_SETTINGS_2, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_2 | FLASH_BUICR_RWSC_3 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_3 | FLASH_BUICR_IPFEN_3 | FLASH_BUICR_PFLIM_6 | FLASH_BUICR_BFEN
+.equ FLASH_SETTINGS_3, 0x01716B15
+
+#endif
+
+/**
+ * @fn void mpc55xx_start_flash()
+ * @brief Optimized flash configuration.
+ * @warning Code will be copied and executed on the stack.
+ */
+GLOBAL_FUNCTION mpc55xx_start_flash
+#if !defined(MPC55XX_NEEDS_LOW_LEVEL_INIT) \
+ || MPC55XX_CHIP_FAMILY == 564 \
+ || MPC55XX_CHIP_FAMILY == 566
+ blr
+#else
+ .equ stack_size, 20
+ .equ lr_offset, 28
+
+ /* Reserve stack frame */
+ stwu r1, -stack_size(r1)
+ mflr r0
+ stw r0, lr_offset(r1)
+
+ /* Flash settings dependent on system clock */
+ bl mpc55xx_get_system_clock
+ LWI r4, FLASH_CLOCK_0
+ cmpw r3, r4
+ ble clock_0
+ LWI r4, FLASH_CLOCK_1
+ cmpw r3, r4
+ ble clock_1
+ LWI r4, FLASH_CLOCK_2
+ cmpw r3, r4
+ ble clock_2
+ LWI r4, FLASH_CLOCK_3
+ cmpw r3, r4
+ ble clock_3
+
+ /*
+ * In case we don't have the right flash settings for the system clock
+ * value, then rely on the BAM settings.
+ */
+ blr
+
+clock_0:
+ LWI r3, FLASH_SETTINGS_0
+ b settings_done
+clock_1:
+ LWI r3, FLASH_SETTINGS_1
+ b settings_done
+clock_2:
+ LWI r3, FLASH_SETTINGS_2
+ b settings_done
+clock_3:
+ LWI r3, FLASH_SETTINGS_3
+ b settings_done
+settings_done:
+
+ /* Copy store code on the stack */
+ LA r4, store_start
+ lwz r6, 0(r4)
+ lwz r7, 4(r4)
+ lwz r8, 8(r4)
+ stw r6, 8(r1)
+ stw r7, 12(r1)
+ stw r8, 16(r1)
+
+ /* Execute store code */
+ LA r4, FLASH_BIUCR
+ addi r5, r1, 8
+ mtctr r5
+ bctrl
+
+ /* Return */
+ lwz r0, lr_offset(r1)
+ addi r1, r1, stack_size
+ mtlr r0
+ blr
+
+/*
+ * Store flash settings
+ */
+
+store_start:
+
+ stw r3, 0(r4)
+ isync
+ blr
+
+#endif
diff --git a/bsps/powerpc/mpc55xxevb/start/start-prologue.c b/bsps/powerpc/mpc55xxevb/start/start-prologue.c
new file mode 100644
index 0000000000..872a96edfd
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-prologue.c
@@ -0,0 +1,28 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief Start prologue.
+ */
+
+/*
+ * Copyright (c) 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 <bsp/mpc55xx-config.h>
+
+BSP_START_TEXT_SECTION void mpc55xx_start_prologue(void)
+{
+ /* Do nothing */
+}
diff --git a/bsps/powerpc/mpc55xxevb/start/start-watchdog.c b/bsps/powerpc/mpc55xxevb/start/start-watchdog.c
new file mode 100644
index 0000000000..7cf36ef02f
--- /dev/null
+++ b/bsps/powerpc/mpc55xxevb/start/start-watchdog.c
@@ -0,0 +1,39 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief Watchdog initialization code.
+ */
+
+/*
+ * 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.h>
+#include <bsp/start.h>
+#include <bsp/mpc55xx-config.h>
+
+BSP_START_TEXT_SECTION void mpc55xx_start_watchdog(void)
+{
+ #ifdef MPC55XX_NEEDS_LOW_LEVEL_INIT
+ #ifdef MPC55XX_HAS_SWT
+ /* Write keys to clear soft lock bit */
+ SWT.SR.R = 0x0000c520;
+ SWT.SR.R = 0x0000d928;
+
+ /* Clear watchdog enable (WEN) */
+ SWT.CR.R = 0x8000010A;
+ #endif
+ #endif
+}
diff --git a/bsps/powerpc/mpc8260ads/start/bsp_specs b/bsps/powerpc/mpc8260ads/start/bsp_specs
new file mode 100644
index 0000000000..2625609327
--- /dev/null
+++ b/bsps/powerpc/mpc8260ads/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/mpc8260ads/start/bspstart.c b/bsps/powerpc/mpc8260ads/start/bspstart.c
new file mode 100644
index 0000000000..44ec072775
--- /dev/null
+++ b/bsps/powerpc/mpc8260ads/start/bspstart.c
@@ -0,0 +1,191 @@
+/*
+ * This routine does the bulk of the system initialization.
+ */
+
+/*
+ * The MPC860 specific stuff was written by Jay Monkman (jmonkman@frasca.com)
+ *
+ * Modified for the MPC8260ADS board by Andy Dachs <a.dachs@sstl.co.uk>
+ * Surrey Satellite Technology Limited, 2001
+ * A 40MHz system clock is assumed.
+ * The PON. RST.CONF. Dip switches (DS1) are
+ * 1 - Off
+ * 2 - On
+ * 3 - Off
+ * 4 - On
+ * 5 - Off
+ * 6 - Off
+ * 7 - Off
+ * 8 - Off
+ * Dip switches on DS2 and DS3 are all set to ON
+ * The LEDs on the board are used to signal panic and fatal_error
+ * conditions.
+ * The mmu is unused at this time.
+ *
+ * COPYRIGHT (c) 1989-2007.
+ * 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>
+
+/*
+#include <mmu.h>
+*/
+
+#include <mpc8260.h>
+#include <rtems/score/thread.h>
+#include <rtems/powerpc/powerpc.h>
+
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+#include <bsp/irq.h>
+#include <libcpu/cpuIdent.h>
+#include <libcpu/spr.h>
+
+#include <string.h>
+
+#define UART1_E 0x02000002 /* bit 6 of BCSR1 */
+#define UART2_E 0x01000001 /* bit 7 of BCSR1 */
+
+#define GP0_LED 0x02000002 /* bit 6 of BCSR0 */
+#define GP1_LED 0x01000001 /* bit 7 of BCSR0 */
+
+SPR_RW(SPRG1)
+
+/*
+ * Driver configuration parameters
+ */
+uint32_t bsp_clock_speed;
+uint32_t bsp_time_base_frequency;
+uint32_t bsp_clicks_per_usec;
+uint32_t bsp_serial_per_sec; /* Serial clocks per second */
+bool bsp_serial_external_clock;
+bool bsp_serial_xon_xoff;
+bool bsp_serial_cts_rts;
+uint32_t bsp_serial_rate;
+
+extern char IntrStack_start [];
+extern char intrStack [];
+
+static void _BSP_GPLED0_on(void)
+{
+ BCSR *csr;
+ csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
+ csr->bcsr0 &= ~GP0_LED; /* Turn on GP0 LED */
+}
+
+static void _BSP_GPLED0_off(void)
+{
+ BCSR *csr;
+ csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
+ csr->bcsr0 |= GP0_LED; /* Turn off GP0 LED */
+}
+
+static void _BSP_GPLED1_on(void)
+{
+ BCSR *csr;
+ csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
+ csr->bcsr0 &= ~GP1_LED; /* Turn on GP1 LED */
+}
+
+static void _BSP_GPLED1_off(void)
+{
+ BCSR *csr;
+ csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
+ csr->bcsr0 |= GP1_LED; /* Turn off GP1 LED */
+}
+
+static void _BSP_Uart1_enable(void)
+{
+ BCSR *csr;
+ csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
+ csr->bcsr1 &= ~UART1_E; /* Enable Uart1 */
+}
+
+static void _BSP_Uart2_enable(void)
+{
+ BCSR *csr;
+ csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
+ csr->bcsr1 &= ~UART2_E; /* Enable Uart2 */
+}
+
+void bsp_start(void)
+{
+ /* Set MPC8260ADS board LEDS and Uart enable lines */
+ _BSP_GPLED0_off();
+ _BSP_GPLED1_off();
+ _BSP_Uart1_enable();
+ _BSP_Uart2_enable();
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function stores the result in global variables so that it can be used
+ * later...
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ cpu_init();
+
+/*
+ mmu_init();
+*/
+
+ /* Initialize exception handler */
+ /* FIXME: Interrupt stack begin and size */
+ ppc_exc_initialize(
+ (uintptr_t) IntrStack_start,
+ (uintptr_t) intrStack - (uintptr_t) IntrStack_start
+ );
+
+ /* Initalize interrupt support */
+ bsp_interrupt_initialize();
+
+/*
+ mmu_init();
+*/
+
+ /*
+ * Enable instruction and data caches. Do not force writethrough mode.
+ */
+#if BSP_INSTRUCTION_CACHE_ENABLED
+ rtems_cache_enable_instruction();
+#endif
+#if BSP_DATA_CACHE_ENABLED
+ rtems_cache_enable_data();
+#endif
+
+ /*
+ * initialize the device driver parameters
+ */
+ bsp_time_base_frequency = 10000000;
+ bsp_clicks_per_usec = 10; /* for 40MHz extclk */
+ bsp_serial_per_sec = 40000000;
+ bsp_serial_external_clock = 0;
+ bsp_serial_xon_xoff = 0;
+ bsp_serial_cts_rts = 0;
+ bsp_serial_rate = 9600;
+ bsp_clock_speed = 40000000;
+ rtems_counter_initialize_converter(bsp_clock_speed);
+
+#ifdef REV_0_2
+ /* set up some board specific registers */
+ m8260.siumcr &= 0xF3FFFFFF; /* set TBEN ** BUG FIX ** */
+ m8260.siumcr |= 0x08000000;
+#endif
+
+ /* use BRG1 to generate 32kHz timebase */
+/*
+ m8260.brgc1 = M8260_BRG_EN + (uint32_t)(((uint16_t)((40016384)/(32768)) - 1) << 1) + 0;
+*/
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Exit from bspstart\n");
+#endif
+
+}
diff --git a/bsps/powerpc/mpc8260ads/start/cpuinit.c b/bsps/powerpc/mpc8260ads/start/cpuinit.c
new file mode 100644
index 0000000000..c56ec69362
--- /dev/null
+++ b/bsps/powerpc/mpc8260ads/start/cpuinit.c
@@ -0,0 +1,49 @@
+/*
+ * cpuinit.c - this file contains functions for initializing the CPU
+ *
+ * Written by Jay Monkman (jmonkman@frasca.com)
+ */
+
+#include <bsp.h>
+
+/* Macros for handling all the MMU SPRs */
+#define PUT_IC_CST(r) __asm__ volatile ("mtspr 0x230,%0\n" ::"r"(r))
+#define GET_IC_CST(r) __asm__ volatile ("mfspr %0,0x230\n" :"=r"(r))
+#define PUT_DC_CST(r) __asm__ volatile ("mtspr 0x238,%0\n" ::"r"(r))
+#define GET_DC_CST(r) __asm__ volatile ("mfspr %0,0x238\n" :"=r"(r))
+
+void cpu_init(void)
+{
+ /* BRGCLK is VCO_OUT/4 */
+/*
+ m8260.sccr = 0;
+*/
+
+#if 0
+ register unsigned long t1, t2;
+
+ /* Let's clear MSR[IR] and MSR[DR] */
+ t2 = PPC_MSR_IR | PPC_MSR_DR;
+ __asm__ volatile (
+ "mfmsr %0\n"
+ "andc %0, %0, %1\n"
+ "mtmsr %0\n" :"=r"(t1), "=r"(t2):
+ "1"(t2));
+
+ t1 = M8xx_CACHE_CMD_UNLOCK;
+ /* PUT_DC_CST(t1); */
+ PUT_IC_CST(t1);
+
+ t1 = M8xx_CACHE_CMD_INVALIDATE;
+ /* PUT_DC_CST(t1); */
+ PUT_IC_CST(t1);
+
+ t1 = M8xx_CACHE_CMD_ENABLE;
+ PUT_IC_CST(t1);
+
+ t1 = M8xx_CACHE_CMD_SFWT;
+ /* PUT_DC_CST(t1); */
+ t1 = M8xx_CACHE_CMD_ENABLE;
+ /* PUT_DC_CST(t1);*/
+#endif
+}
diff --git a/bsps/powerpc/mpc8260ads/start/linkcmds b/bsps/powerpc/mpc8260ads/start/linkcmds
new file mode 100644
index 0000000000..f3092b862d
--- /dev/null
+++ b/bsps/powerpc/mpc8260ads/start/linkcmds
@@ -0,0 +1,352 @@
+/*
+ * This file contains directives for the GNU linker which are specific
+ * to the MPC8260ADS Board
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
+ "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+
+ENTRY(start)
+STARTUP(start.o)
+EXTERN(__vectors)
+
+/*
+ * Declare some sizes.
+ * XXX: The assignment of ". += XyzSize;" fails in older gld's if the
+ * number used there is not constant. If this happens to you, edit
+ * the lines marked XXX below to use a constant value.
+ */
+StackSize = DEFINED(StackSize) ? StackSize : 0x8000;
+RamBase = DEFINED(RamBase) ? RamBase : 0x0;
+RamSize = DEFINED(RamSize) ? RamDiskSize : 0x0800000; /* 8M program ram */
+HeapSize = DEFINED(HeapSize) ? HeapSize : 0x0;
+RamDiskBase = DEFINED(RamDiskBase) ? RamDiskBase : 0x0800000;
+RamDiskSize = DEFINED(RamDiskSize) ? RamDiskSize : 0x0800000; /* 8M ram disk */
+
+MEMORY
+{
+ ram : org = 0x0, l = 8M
+ ramdisk : org = 0x0800000, l = 8M
+ dpram : org = 0x04700000, l = 128K
+ flash : org = 0xff800000, l = 8M
+}
+
+
+SECTIONS
+{
+ /*
+ * The stack will live in this area - between the vectors and
+ * the text section.
+ */
+
+ .text 0x10000:
+ {
+ _textbase = .;
+
+
+ text.start = .;
+
+ /* Entry point is the .entry section */
+ *(.entry)
+ *(.entry2)
+
+ /* Actual Code */
+ *(.text*)
+
+
+ *(.rodata*)
+ *(.rodata1)
+
+
+ /*
+ * Special FreeBSD sysctl sections.
+ */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ /* C++ constructors/destructors */
+ *(.gnu.linkonce.t*)
+
+ /* Initialization and finalization code.
+ *
+ * Various files can provide initialization and finalization functions.
+ * The bodies of these functions are in .init and .fini sections. We
+ * accumulate the bodies here, and prepend function prologues from
+ * ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
+ * first; ecrtn.o must be linked last. Because these are wildcards, it
+ * doesn't matter if the user does not actually link against ecrti.o and
+ * ecrtn.o; the linker won't look for a file to match a wildcard. The
+ * wildcard also means that it doesn't matter which directory ecrti.o
+ * and ecrtn.o are in.
+ */
+ PROVIDE (_init = .);
+ *ecrti.o(.init)
+ *(.init)
+ *ecrtn.o(.init)
+
+ PROVIDE (_fini = .);
+ *ecrti.o(.fini)
+ *(.fini)
+ *ecrtn.o(.init)
+
+ /*
+ * C++ constructors and destructors for static objects.
+ * PowerPC EABI does not use crtstuff yet, so we build "old-style"
+ * constructor and destructor lists that begin with the list length
+ * end terminate with a NULL entry.
+ */
+
+ PROVIDE (__CTOR_LIST__ = .);
+ /* LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) */
+ *crtbegin.o(.ctors)
+ *(.ctors)
+ *crtend.o(.ctors)
+ LONG(0)
+ PROVIDE (__CTOR_END__ = .);
+
+ PROVIDE (__DTOR_LIST__ = .);
+ /* LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) */
+ *crtbegin.o(.dtors)
+ *(.dtors)
+ *crtend.o(.dtors)
+ LONG(0)
+ PROVIDE (__DTOR_END__ = .);
+
+ /* Exception frame info */
+ *(.eh_frame)
+
+ /* Miscellaneous read-only data */
+ _rodata_start = . ;
+ *(.gnu.linkonce.r*)
+ *(.lit)
+ *(.shdata)
+ *(.rodata)
+ *(.rodata1)
+ KEEP (*(SORT(.rtemsroset.*)))
+ *(.descriptors)
+ *(rom_ver)
+ _erodata = .;
+
+
+ /* Various possible names for the end of the .text section */
+ etext = ALIGN(0x10);
+ _etext = .;
+ _endtext = .;
+ text.end = .;
+ PROVIDE (etext = .);
+ PROVIDE (__etext = .);
+
+ } > ram
+
+ .tdata : {
+ _TLS_Data_begin = .;
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ _TLS_Data_end = .;
+ } >ram
+
+ .tbss : {
+ _TLS_BSS_begin = .;
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ _TLS_BSS_end = .;
+ } >ram
+
+ _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));
+
+
+ .rel.dyn :
+ {
+ *(.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.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
+ *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
+ *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
+ *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ } >ram
+ .rela.dyn :
+ {
+ *(.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.got1)
+ *(.rela.got2)
+ *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
+ *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
+ *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
+ *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ } >ram
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+
+ PROVIDE (__EXCEPT_START__ = .);
+ .gcc_except_table : { *(.gcc_except_table*) } >ram
+ PROVIDE (__EXCEPT_END__ = .);
+ __GOT_START__ = .;
+ .got :
+ {
+ s.got = .;
+ *(.got.plt) *(.got)
+ } > ram
+ __GOT_END__ = .;
+
+ .got1 : { *(.got1) } >ram
+ PROVIDE (__GOT2_START__ = .);
+ PROVIDE (_GOT2_START_ = .);
+ .got2 : { *(.got2) } >ram
+ PROVIDE (__GOT2_END__ = .);
+ PROVIDE (_GOT2_END_ = .);
+
+ PROVIDE (__FIXUP_START__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) } >ram
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (__FIXUP_END__ = .);
+
+ .sdata : {
+ PROVIDE (_SDA_BASE_ = 32768);
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ } > ram
+
+ .sbss : {
+ __bss_start = .;
+
+ PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);
+ *(.scommon)
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);
+ } > ram
+
+ .sdata2 : {
+ PROVIDE (_SDA2_BASE_ = 32768);
+
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ } > ram =0
+
+ .sbss2 : {
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ } > ram =0
+
+ .bss :
+ {
+ bss.start = .;
+ *(.bss .bss* .gnu.linkonce.b*)
+ . = ALIGN(4);
+ bss.end = .;
+ } > ram
+
+ /* R/W Data */
+ .data ( . ) :
+ {
+ . = ALIGN (4);
+
+ data.start = .;
+
+ *(.data)
+ *(.data1)
+ *(.data.* .gnu.linkonce.d.*)
+ KEEP (*(SORT(.rtemsrwset.*)))
+ PROVIDE (__SDATA_START__ = .);
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ data.end = .;
+ } > ram
+
+ data.size = data.end - data.start;
+ bss.size = bss.end - bss.start;
+ text.size = text.end - text.start;
+
+ PROVIDE(_end = data.end);
+
+ .gzipmalloc : {
+ . = ALIGN (16);
+ _startmalloc = .;
+ } >ram
+
+
+ /*
+ * Interrupt stack setup
+ */
+ IntrStack_start = ALIGN(0x10);
+ . += 0x4000;
+ intrStack = .;
+ PROVIDE(intrStackPtr = intrStack);
+
+
+ clear_end = .;
+
+ WorkAreaBase = .;
+
+ /* Sections for compressed .text and .data */
+ /* after the .datarom section is an int specifying */
+ /* the length of the following compressed image */
+ /* Executes once then could get overwritten */
+ .textrom 0x100000 :
+ {
+ *(.textrom)
+ _endloader = .;
+ } > ram
+
+ .datarom :
+ {
+ _dr_start = .;
+ *(.datarom)
+ _dr_end = .;
+ } > ram
+ dr_len = _dr_end - _dr_start;
+
+ .dpram :
+ {
+ m8260 = .;
+ _m8260 = .;
+ . += (128 * 1024);
+ } > dpram
+
+
+ /* the reset vector is at 0xfff00000 which is */
+ /* located at offset 0x400000 from the base */
+ /* of flash */
+ .bootrom 0xFFF00000 :
+ {
+ *(.bootrom)
+ _endboot = .;
+ } > flash
+
+
+ .line 0 : { *(.line) }
+ .debug 0 : { *(.debug) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_aregion 0 : { *(.debug_aregion) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+}
diff --git a/bsps/powerpc/mvme3100/start/bsp_specs b/bsps/powerpc/mvme3100/start/bsp_specs
new file mode 100644
index 0000000000..2625609327
--- /dev/null
+++ b/bsps/powerpc/mvme3100/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/mvme3100/start/bspstart.c b/bsps/powerpc/mvme3100/start/bspstart.c
new file mode 100644
index 0000000000..27b483332c
--- /dev/null
+++ b/bsps/powerpc/mvme3100/start/bspstart.c
@@ -0,0 +1,440 @@
+/*
+ * This routine does the bulk of the system initialization.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-1998.
+ * 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.
+ *
+ * Modified to support the MCP750.
+ * Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ *
+ * Modified for mvme3100 by T. Straumann
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+#include <rtems/sysinit.h>
+#include <libcpu/spr.h>
+#include <libcpu/io.h>
+#include <libcpu/e500_mmu.h>
+#include <bsp/uart.h>
+#include <bsp/irq.h>
+#include <bsp/pci.h>
+#include <bsp/vpd.h>
+#include <libcpu/cpuIdent.h>
+#include <bsp/vectors.h>
+#include <bsp/VME.h>
+#include <rtems/powerpc/powerpc.h>
+
+#define SHOW_MORE_INIT_SETTINGS
+#undef DEBUG
+
+#define NumberOf(arr) (sizeof(arr)/sizeof(arr[0]))
+
+#ifdef DEBUG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+extern unsigned long __rtems_end[];
+extern unsigned ppc_exc_lock_std, ppc_exc_gpr3_std;
+
+/*
+ * Copy Additional boot param passed by boot loader
+ */
+#define CMDLINE_BUF_SIZE 2048
+
+static char cmdline_buf[CMDLINE_BUF_SIZE] = {0};
+char *BSP_commandline_string = cmdline_buf;
+
+/*
+ * Vital Board data Start using DATA RESIDUAL
+ */
+uint32_t bsp_clicks_per_usec = 0;
+/*
+ * Total memory using RESIDUAL DATA
+ */
+unsigned int BSP_mem_size = 0;
+/*
+ * PCI Bus Frequency
+ */
+unsigned int BSP_pci_bus_frequency = 0xdeadbeef;
+/*
+ * PPC Bus Frequency
+ */
+unsigned int BSP_bus_frequency = 0;
+/*
+ * processor clock frequency
+ */
+unsigned int BSP_processor_frequency = 0;
+/*
+ * Time base divisior (how many tick for 1 second).
+ */
+unsigned int BSP_time_base_divisor = 8000; /* if external RTC clock unused (HID0) */
+
+/* Board identification string */
+char BSP_productIdent[20] = {0};
+char BSP_serialNumber[20] = {0};
+
+/* VPD appends an extra char -- what for ? */
+char BSP_enetAddr0[7] = {0};
+char BSP_enetAddr1[7] = {0};
+char BSP_enetAddr2[7] = {0};
+
+static void
+prether(char *b, int idx)
+{
+int i;
+ printk("Ethernet %i %02X", idx, *b++);
+ for ( i=0; i<5; i++ )
+ printk(":%02X",*b++);
+ printk("\n");
+}
+
+BSP_output_char_function_type BSP_output_char = BSP_output_char_via_serial;
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
+
+char *rtems_progname;
+
+/*
+ * Use the shared implementations of the following routines
+ */
+char *save_boot_params(
+ void *r3,
+ void *r4,
+ void *r5,
+ char *cmdline_start,
+ char *cmdline_end
+)
+{
+
+ strncpy(cmdline_buf, cmdline_start, CMDLINE_BUF_SIZE);
+ cmdline_buf[CMDLINE_BUF_SIZE - 1] ='\0';
+ return cmdline_buf;
+}
+
+#define CS_CONFIG_CS_EN (1<<31)
+#define CS_BNDS_SA(x) ((((uint32_t)(x))>>(31-15)) & 0xff)
+#define CS_BNDS_EA(x) ((((uint32_t)(x))>>(31-31)) & 0xff)
+
+static inline uint32_t
+_ccsr_rd32(uint32_t off)
+{
+ return in_be32( (volatile uint32_t *)(BSP_8540_CCSR_BASE + off) );
+}
+
+static inline void
+_ccsr_wr32(uint32_t off, uint32_t val)
+{
+ out_be32( (volatile uint32_t *)(BSP_8540_CCSR_BASE + off), val );
+}
+
+
+STATIC uint32_t
+BSP_get_mem_size( void )
+{
+ int i;
+ uint32_t cs_bnds, cs_config;
+ uint32_t memsz=0;
+ uint32_t v;
+
+ for ( cs_bnds = 0x2000, cs_config=0x2080, i=0; i<4; i++, cs_bnds+=8, cs_config+=4 ) {
+ if ( CS_CONFIG_CS_EN & _ccsr_rd32( cs_config ) ) {
+ v = _ccsr_rd32( cs_bnds );
+
+ memsz += CS_BNDS_EA(v) - CS_BNDS_SA(v) + 1;
+ }
+ }
+ return memsz << 24;
+}
+
+STATIC void
+BSP_calc_freqs( void )
+{
+ uint32_t porpllsr = _ccsr_rd32( 0xe0000 );
+ unsigned plat_ratio = (porpllsr >> (31-30)) & 0x1f;
+ unsigned e500_ratio = (porpllsr >> (31-15)) & 0x3f;
+
+ switch ( plat_ratio ) {
+ case 2: case 3: case 4: case 5: case 6:
+ case 8: case 9: case 10: case 12: case 16:
+ /* supported ratios */
+ BSP_bus_frequency = BSP_pci_bus_frequency * plat_ratio;
+ break;
+
+ default:
+ rtems_panic("Unknown PLL sys-clock ratio; something's wrong here");
+ }
+
+ switch ( e500_ratio ) {
+ case 4: case 5: case 6: case 7:
+ BSP_processor_frequency = (BSP_pci_bus_frequency * e500_ratio) >> 1;
+ break;
+
+ default:
+ rtems_panic("Unknown PLL e500-clock ratio; something's wrong here");
+ }
+
+ printk("Core Complex Bus (CCB) Clock Freq: %10u Hz\n", BSP_bus_frequency);
+ printk("CPU Clock Freq: %10u Hz\n", BSP_processor_frequency);
+}
+
+/*
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ */
+
+#include <libcpu/spr.h>
+
+SPR_RW(HID1)
+
+void bsp_start( void )
+{
+ unsigned char *stack;
+ uintptr_t intrStackStart;
+ uintptr_t intrStackSize;
+ char *chpt;
+ int i;
+ ppc_cpu_id_t myCpu;
+ ppc_cpu_revision_t myCpuRevision;
+ E500_tlb_va_cache_t *tlb;
+
+VpdBufRec vpdData [] = {
+ { key: ProductIdent, instance: 0, buf: BSP_productIdent, buflen: sizeof(BSP_productIdent) - 1 },
+ { key: SerialNumber, instance: 0, buf: BSP_serialNumber, buflen: sizeof(BSP_serialNumber) - 1 },
+ { key: BusClockHz, instance: 0, buf: &BSP_pci_bus_frequency, buflen: sizeof(BSP_pci_bus_frequency) },
+ { key: EthernetAddr, instance: 0, buf: BSP_enetAddr0, buflen: sizeof(BSP_enetAddr0) },
+ { key: EthernetAddr, instance: 1, buf: BSP_enetAddr1, buflen: sizeof(BSP_enetAddr1) },
+ { key: EthernetAddr, instance: 2, buf: BSP_enetAddr2, buflen: sizeof(BSP_enetAddr2) },
+ VPD_END
+};
+
+ /* Intersperse messages with actions to help locate problems */
+ printk("-----------------------------------------\n");
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function store the result in global variables so that it can be used
+ * later...
+ */
+ myCpu = get_ppc_cpu_type();
+ myCpuRevision = get_ppc_cpu_revision();
+
+ printk("Welcome to %s\n", _RTEMS_version);
+ printk("BSP: %s, CVS Release ($Name$)\n", "mvme3100");
+
+ /*
+ * the initial stack has aready been set to this value in start.S
+ * so there is no need to set it in r1 again... It is just for info
+ * so that It can be printed without accessing R1.
+ */
+ asm volatile("mr %0, 1":"=r"(stack));
+
+ /* tag the bottom */
+ *((uint32_t*)stack) = 0;
+
+ /*
+ * Initialize the interrupt related settings.
+ */
+ intrStackStart = (uintptr_t) __rtems_end;
+ intrStackSize = rtems_configuration_get_interrupt_stack_size();
+
+ /*
+ * Initialize default raw exception handlers.
+ */
+ ppc_exc_initialize(intrStackStart, intrStackSize);
+
+ printk("CPU 0x%x - rev 0x%x\n", myCpu, myCpuRevision);
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Additionnal boot options are %s\n", BSP_commandline_string);
+ printk("Initial system stack at %" PRIxPTR "\n", (uintptr_t) stack);
+ printk("Software IRQ stack starts at %x with size %u\n", intrStackStart, intrStackSize);
+#endif
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Going to start PCI buses scanning and initialization\n");
+#endif
+
+ BSP_mem_size = BSP_get_mem_size();
+
+ {
+ /* memory-select errors were disabled in 'start.S';
+ * motload has all TLBs mapping a possible larger area as
+ * memory (not-guarded, caching-enabled) than actual physical
+ * memory is available.
+ * In case of speculative loads this may cause 'memory-select' errors
+ * which seem to raise 'core_fault_in' (found no description in
+ * the manual but I experienced this problem).
+ * Such errors (if HID1[RFXE] is clear) may *stall* execution
+ * leading to mysterious 'hangs'.
+ *
+ * Here we remove all mappings, re-enable memory-select
+ * errors and make sure we enable HID1[RFXE] to avoid
+ * stalls (since we don't implement handling individual
+ * error-handling interrupts).
+ */
+
+ /* enable machine check for bad bus errors */
+ _write_HID1( _read_HID1() | 0x20000 );
+
+ rtems_e500_initlb();
+
+ for ( i=0, tlb=rtems_e500_tlb_va_cache; i<NumberOf(rtems_e500_tlb_va_cache); i++, tlb++ ) {
+ /* disable TLBs for caching-enabled, non-guarded areas
+ * beyond physical memory
+ */
+ if ( tlb->att.v
+ && 0xa != (tlb->att.wimge & 0xa)
+ && (tlb->va.va_epn<<12) >= BSP_mem_size ) {
+ rtems_e500_clrtlb( E500_SELTLB_1 | i );
+ }
+ }
+
+ /* clear all pending memory errors */
+ _ccsr_wr32(0x2e40, 0xffffffff);
+ /* enable checking for memory-select errors */
+ _ccsr_wr32(0x2e44, _ccsr_rd32(0x2e44) & ~1 );
+ }
+
+ BSP_vpdRetrieveFields( vpdData );
+
+ printk("Board Type: %s (S/N %s)\n",
+ BSP_productIdent[0] ? BSP_productIdent : "n/a",
+ BSP_serialNumber[0] ? BSP_serialNumber : "n/a");
+
+ printk("External (=PCI Bus) Clock Freq ");
+ if ( 0xdeadbeef == BSP_pci_bus_frequency ) {
+ BSP_pci_bus_frequency = 66666666;
+ printk(" NOT FOUND in VPD; using %10u Hz\n",
+ BSP_pci_bus_frequency);
+ } else {
+ printk(": %10u Hz\n",
+ BSP_pci_bus_frequency);
+ }
+
+ /* Calculate CPU and CCB bus freqs */
+ BSP_calc_freqs();
+
+ pci_initialize();
+
+ prether(BSP_enetAddr0, 0);
+ prether(BSP_enetAddr1, 1);
+ prether(BSP_enetAddr2, 2);
+
+ /* need to tweak the motload setup */
+ BSP_motload_pci_fixup();
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Number of PCI buses found is : %d\n", pci_bus_count());
+ {
+ BSP_pciConfigDump_early();
+ }
+#endif
+
+ if ( (chpt = strstr(BSP_commandline_string,"MEMSZ=")) ) {
+ char *endp;
+ uint32_t sz;
+ chpt+=6 /* strlen("MEMSZ=") */;
+ sz = strtoul(chpt, &endp, 0);
+ if ( endp != chpt )
+ BSP_mem_size = sz;
+ }
+
+ printk("Memory: %10u bytes\n", BSP_mem_size);
+
+ BSP_bus_frequency = 333333333;
+ BSP_processor_frequency = 833333333;
+ BSP_time_base_divisor = 8000; /* if external RTC clock unused (HID0) */
+
+ /* clear hostbridge errors but leave MCP disabled -
+ * PCI config space scanning code will trip otherwise :-(
+ */
+ _BSP_clear_hostbridge_errors(0 /* enableMCP */, 0/*quiet*/);
+
+ bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
+ rtems_counter_initialize_converter(
+ BSP_bus_frequency / (BSP_time_base_divisor / 1000)
+ );
+
+ /*
+ * Initalize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mng_init(0);
+
+ if (1) {
+ int i;
+ unsigned msr,tcr;
+ asm volatile("mfmsr %0":"=r"(msr));
+ asm volatile("mftcr %0":"=r"(tcr));
+ printk("MSR is 0x%08x, TCR 0x%08x\n",msr,tcr);
+ asm volatile("mttcr %0"::"r"(0));
+ if (0) {
+ asm volatile("mtmsr %0"::"r"(msr|0x8000));
+ for (i=0; i<12; i++)
+ BSP_enable_irq_at_pic(i);
+ printk("IRQS enabled\n");
+ }
+ }
+
+ if (0) {
+ unsigned x;
+ asm volatile("mfivpr %0":"=r"(x));
+ printk("IVPR: 0x%08x\n",x);
+ asm volatile("mfivor8 %0":"=r"(x));
+ printk("IVOR8: 0x%08x\n",x);
+ printk("0x%08x\n",*(unsigned *)0xc00);
+ printk("0x%08x\n",*(unsigned *)0xc04);
+ printk("0x%08x\n",*(unsigned *)0xc08);
+ printk("0x%08x\n\n\n",*(unsigned *)0xc0c);
+ if (0) {
+ *(unsigned *)0xc08 = 0x4c000064;
+ asm volatile("dcbf 0, %0; icbi 0, %0; sync; isync"::"r"(0xc00));
+ }
+
+ printk("0x%08x\n", ppc_exc_lock_std);
+ printk("0x%08x\n", ppc_exc_gpr3_std);
+
+ asm volatile("sc");
+
+ printk("0x%08x\n", ppc_exc_lock_std);
+ printk("0x%08x\n", ppc_exc_gpr3_std);
+ }
+
+ printk("-----------------------------------------\n");
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Exit from bspstart\n");
+#endif
+}
+
+static void mvme3100_i2c_initialize(void)
+{
+ BSP_i2c_initialize();
+}
+
+RTEMS_SYSINIT_ITEM(
+ mvme3100_i2c_initialize,
+ RTEMS_SYSINIT_BSP_PRE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
+
+RTEMS_SYSINIT_ITEM(
+ BSP_vme_config,
+ RTEMS_SYSINIT_BSP_PRE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
diff --git a/bsps/powerpc/mvme3100/start/linkcmds b/bsps/powerpc/mvme3100/start/linkcmds
new file mode 100644
index 0000000000..b30fb91277
--- /dev/null
+++ b/bsps/powerpc/mvme3100/start/linkcmds
@@ -0,0 +1,5 @@
+STARTUP(motld_start.o)
+ENTRY(__rtems_entry_point)
+EXTERN(__vectors)
+
+INCLUDE linkcmds.share
diff --git a/bsps/powerpc/mvme3100/start/misc.c b/bsps/powerpc/mvme3100/start/misc.c
new file mode 100644
index 0000000000..3a15397480
--- /dev/null
+++ b/bsps/powerpc/mvme3100/start/misc.c
@@ -0,0 +1,131 @@
+/* Miscellaneous small BSP routines; reboot, board CSR, ... */
+
+/*
+ * Authorship
+ * ----------
+ * This software ('mvme3100' RTEMS BSP) was created by
+ *
+ * Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
+ * Stanford Linear Accelerator Center, Stanford University.
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * The 'mvme3100' BSP was produced by
+ * the Stanford Linear Accelerator Center, Stanford University,
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software. Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+
+void
+bsp_reset(void)
+{
+uint8_t v;
+ /*
+ * AFAIK, the hardest reset available; cleared
+ * some errors a VME-bus reset wouldn't (hung
+ * i2c bus)...
+ */
+ v = in_8( BSP_MVME3100_SYS_CR );
+ v &= ~BSP_MVME3100_SYS_CR_RESET_MSK;
+ v |= BSP_MVME3100_SYS_CR_RESET;
+ out_8( BSP_MVME3100_SYS_CR, v );
+}
+
+uint8_t
+BSP_setSysReg(volatile uint8_t *r, uint8_t mask)
+{
+uint8_t v;
+rtems_interrupt_level l;
+
+ if ( !mask )
+ return in_8( r );
+
+ rtems_interrupt_disable(l);
+ v = in_8( r );
+ if ( mask ) {
+ out_8( r, v | mask );
+ }
+ rtems_interrupt_enable(l);
+ return v;
+}
+
+uint8_t
+BSP_clrSysReg(volatile uint8_t *r, uint8_t mask)
+{
+uint8_t v;
+rtems_interrupt_level l;
+
+ if ( !mask )
+ return in_8( r );
+
+ rtems_interrupt_disable(l);
+ v = in_8( r );
+ if ( mask ) {
+ out_8( r, v & ~mask );
+ }
+ rtems_interrupt_enable(l);
+ return v;
+}
+
+uint8_t
+BSP_setLEDs(uint8_t mask)
+{
+ return BSP_setSysReg( BSP_MVME3100_SYS_IND_REG, mask );
+}
+
+uint8_t
+BSP_clrLEDs(uint8_t mask)
+{
+ return BSP_clrSysReg( BSP_MVME3100_SYS_IND_REG, mask );
+}
+
+uint8_t
+BSP_eeprom_write_protect(void)
+{
+uint8_t m = BSP_MVME3100_SYS_CR_EEPROM_WP;
+volatile uint8_t *r = BSP_MVME3100_SYS_CR;
+
+ return m & BSP_setSysReg( r, m );
+}
+
+uint8_t
+BSP_eeprom_write_enable(void)
+{
+uint8_t m = BSP_MVME3100_SYS_CR_EEPROM_WP;
+volatile uint8_t *r = BSP_MVME3100_SYS_CR;
+
+ return m & BSP_clrSysReg( r, m );
+}
diff --git a/bsps/powerpc/mvme5500/start/bootpstuff.c b/bsps/powerpc/mvme5500/start/bootpstuff.c
new file mode 100644
index 0000000000..518a43cdc8
--- /dev/null
+++ b/bsps/powerpc/mvme5500/start/bootpstuff.c
@@ -0,0 +1,70 @@
+#define FLAG_MAND 1
+#define FLAG_NOUSE 2 /* dont put into the commandline at all */
+#define FLAG_CLRBP 4 /* field needs to be cleared for bootp */
+
+typedef struct ParmRec_ {
+ char *name;
+ char **pval;
+ int flags;
+} ParmRec, *Parm;
+
+
+static char *boot_filename=0;
+static char *boot_srvname=0;
+static char *boot_use_bootp=0;
+static char *boot_my_ip=0;
+static char *boot_my_netmask=0;
+
+#define boot_cmdline BSP_commandline_string
+
+static ParmRec parmList[]={
+ { "BP_FILE=", &boot_filename,
+ FLAG_MAND,
+ },
+ { "BP_PARM=", &boot_cmdline,
+ 0,
+ },
+ { "BP_SRVR=", &boot_srvname,
+ FLAG_MAND,
+ },
+ { "BP_GTWY=", &net_config.gateway,
+ FLAG_CLRBP,
+ },
+ { "BP_MYIP=", &boot_my_ip,
+ FLAG_MAND | FLAG_CLRBP,
+ },
+ { "BP_MYMK=", &boot_my_netmask,
+ FLAG_MAND | FLAG_CLRBP,
+ },
+ { "BP_MYNM=", &net_config.hostname,
+ FLAG_CLRBP,
+ },
+ { "BP_MYDN=", &net_config.domainname,
+ FLAG_CLRBP,
+ },
+ { "BP_LOGH=", &net_config.log_host,
+ FLAG_CLRBP,
+ },
+ { "BP_DNS1=", &net_config.name_server[0],
+ FLAG_CLRBP,
+ },
+ { "BP_DNS2=", &net_config.name_server[1],
+ FLAG_CLRBP,
+ },
+ { "BP_DNS3=", &net_config.name_server[2],
+ FLAG_CLRBP,
+ },
+ { "BP_NTP1=", &net_config.ntp_server[0],
+ FLAG_CLRBP,
+ },
+ { "BP_NTP2=", &net_config.ntp_server[1],
+ FLAG_CLRBP,
+ },
+ { "BP_NTP3=", &net_config.ntp_server[2],
+ FLAG_CLRBP,
+ },
+ { "BP_ENBL=", &boot_use_bootp,
+ 0,
+ },
+ { 0, }
+};
diff --git a/bsps/powerpc/mvme5500/start/bsp_specs b/bsps/powerpc/mvme5500/start/bsp_specs
new file mode 100644
index 0000000000..2625609327
--- /dev/null
+++ b/bsps/powerpc/mvme5500/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/mvme5500/start/bspclean.c b/bsps/powerpc/mvme5500/start/bspclean.c
new file mode 100644
index 0000000000..bd332cc89c
--- /dev/null
+++ b/bsps/powerpc/mvme5500/start/bspclean.c
@@ -0,0 +1,26 @@
+/* Copyright 2003, Shuchen Kate Feng <feng1@bnl.gov>,
+ * NSLS,Brookhaven National Laboratory
+ */
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <rtems/bspIo.h>
+#include <libcpu/stackTrace.h>
+
+#define AUTO_BOOT 0
+
+void bsp_fatal_extension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code error
+)
+{
+#if AUTO_BOOT
+ /* Till Straumann <strauman@slac.stanford.edu> for SVGM */
+ bsp_reset();
+#else
+ /* Kate Feng <feng1@bnl.gov> for the MVME5500 */
+ printk("\nPrinting a stack trace for your convenience :-)\n");
+ CPU_print_stack();
+ printk("RTEMS terminated; Boot manually or turn on AUTO_BOOT.\n");
+#endif
+}
diff --git a/bsps/powerpc/mvme5500/start/bspreset.c b/bsps/powerpc/mvme5500/start/bspreset.c
new file mode 100644
index 0000000000..de15bc4972
--- /dev/null
+++ b/bsps/powerpc/mvme5500/start/bspreset.c
@@ -0,0 +1,22 @@
+/* Copyright 2003, Shuchen Kate Feng <feng1@bnl.gov>,
+ * NSLS,Brookhaven National Laboratory
+ *
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <rtems/bspIo.h>
+#include <libcpu/io.h>
+#include <libcpu/stackTrace.h>
+#include <stdint.h>
+
+void bsp_reset()
+{
+
+ printk("Printing a stack trace for your convenience :-)\n");
+ CPU_print_stack();
+
+ printk("RTEMS terminated; Rebooting ...\n");
+ /* Mvme5500 board reset : 2004 S. Kate Feng <feng1@bnl.gov> */
+ out_8((volatile uint8_t*) (GT64x60_DEV1_BASE +2), 0x80);
+}
diff --git a/bsps/powerpc/mvme5500/start/bspstart.c b/bsps/powerpc/mvme5500/start/bspstart.c
new file mode 100644
index 0000000000..279524eb8f
--- /dev/null
+++ b/bsps/powerpc/mvme5500/start/bspstart.c
@@ -0,0 +1,351 @@
+/*
+ * This routine does the bulk of the system initialization.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * 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.
+ *
+ * Modified to support the MCP750.
+ * Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ *
+ * Modified to support the Synergy VGM & Motorola PowerPC boards
+ * (C) by Till Straumann, <strauman@slac.stanford.edu>, 2002, 2004, 2005
+ *
+ * Modified to support the MVME5500 board.
+ * Also, the settings of L1, L2, and L3 caches is not necessary here.
+ * (C) by Brookhaven National Lab., S. Kate Feng <feng1@bnl.gov>, 2003-2009
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <rtems/sysinit.h>
+#include <rtems/system.h>
+#include <rtems/powerpc/powerpc.h>
+
+#include <libcpu/spr.h> /* registers.h is included here */
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/uart.h>
+#include <bsp/pci.h>
+#include <libcpu/bat.h>
+#include <libcpu/pte121.h>
+#include <libcpu/cpuIdent.h>
+#include <bsp/vectors.h>
+#include <bsp/VME.h>
+#include <bsp/bspException.h>
+
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+
+/*
+#define SHOW_MORE_INIT_SETTINGS
+#define SHOW_LCR1_REGISTER
+#define SHOW_LCR2_REGISTER
+#define SHOW_LCR3_REGISTER
+#define CONF_VPD
+*/
+
+extern uint32_t probeMemoryEnd(void); /* from shared/startup/probeMemoryEnd.c */
+
+BSP_output_char_function_type BSP_output_char = BSP_output_char_via_serial;
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
+
+extern void _return_to_ppcbug(void);
+extern unsigned long __rtems_end[];
+extern unsigned get_L1CR(void), get_L2CR(void), get_L3CR(void);
+extern Triv121PgTbl BSP_pgtbl_setup(unsigned int *);
+extern void BSP_pgtbl_activate(Triv121PgTbl);
+extern int I2Cread_eeprom(unsigned char I2cBusAddr, uint32_t devA2A1A0, uint32_t AddrBytes, unsigned char *pBuff, uint32_t numBytes);
+extern void BSP_vme_config(void);
+
+extern unsigned char ReadConfVPD_buff(int offset);
+
+uint32_t bsp_clicks_per_usec;
+
+typedef struct CmdLineRec_ {
+ unsigned long size;
+ char buf[0];
+} CmdLineRec, *CmdLine;
+
+
+#define mtspr(reg, val) \
+ __asm __volatile("mtspr %0,%1" : : "K"(reg), "r"(val))
+
+
+#define mfspr(reg) \
+ ( { unsigned val; \
+ __asm __volatile("mfspr %0,%1" : "=r"(val) : "K"(reg)); \
+ val; } )
+
+/*
+ * Copy Additional boot param passed by boot loader
+ */
+#define MAX_LOADER_ADD_PARM 80
+char loaderParam[MAX_LOADER_ADD_PARM];
+
+/*
+ * Total memory using RESIDUAL DATA
+ */
+unsigned int BSP_mem_size;
+/*
+ * PCI Bus Frequency
+ */
+unsigned int BSP_bus_frequency;
+/*
+ * processor clock frequency
+ */
+unsigned int BSP_processor_frequency;
+/*
+ * Time base divisior (how many tick for 1 second).
+ */
+unsigned int BSP_time_base_divisor;
+static unsigned char ConfVPD_buff[200];
+
+#define CMDLINE_BUF_SIZE 2048
+
+static char cmdline_buf[CMDLINE_BUF_SIZE];
+char *BSP_commandline_string = cmdline_buf;
+
+/* NOTE: we cannot simply malloc the commandline string;
+ * save_boot_params() is called during a very early stage when
+ * libc/malloc etc. are not yet initialized!
+ *
+ * Here's what we do:
+ *
+ * initial layout setup by the loader (preload.S):
+ *
+ * 0..RTEMS...__rtems_end | cmdline ....... TOP
+ *
+ * After the save_boot_params() routine returns, the stack area will be
+ * set up (start.S):
+ *
+ * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | ..... TOP
+ *
+ * initialize_executive_early() [called from boot_card()]
+ * will initialize the workspace:
+ *
+ * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | ...... | workspace | TOP
+ *
+ * and later calls our bsp_predriver_hook() which ends up initializing
+ * libc which in turn initializes the heap
+ *
+ * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | heap | workspace | TOP
+ *
+ * The idea here is to first move the commandline to the future 'heap' area
+ * from where it will be picked up by our bsp_predriver_hook().
+ * bsp_predriver_hook() then moves it either to INIT_STACK or the workspace
+ * area using proper allocation, initializes libc and finally moves
+ * the data to the environment / malloced areas...
+ */
+
+/* this routine is called early at shared/start/start.S
+ * and must be safe with a not properly aligned stack
+ */
+char *
+save_boot_params(
+ void *r3,
+ void *r4,
+ void* r5,
+ char *cmdline_start,
+ char *cmdline_end
+)
+{
+ int i=cmdline_end-cmdline_start;
+
+ if ( i >= CMDLINE_BUF_SIZE )
+ i = CMDLINE_BUF_SIZE-1;
+ else if ( i < 0 )
+ i = 0;
+
+ memmove(cmdline_buf, cmdline_start, i);
+ cmdline_buf[i]=0;
+ return cmdline_buf;
+}
+
+void bsp_start( void )
+{
+#ifdef CONF_VPD
+ int i;
+#endif
+#ifdef SHOW_LCR1_REGISTER
+ unsigned l1cr;
+#endif
+#ifdef SHOW_LCR2_REGISTER
+ unsigned l2cr;
+#endif
+#ifdef SHOW_LCR3_REGISTER
+ unsigned l3cr;
+#endif
+ uintptr_t intrStackStart;
+ uintptr_t intrStackSize;
+ Triv121PgTbl pt=0;
+
+ /* Till Straumann: 4/2005
+ * Need to map the system registers early, so we can printk...
+ * (otherwise we silently die)
+ */
+ /*
+ * Kate Feng : PCI 0 domain memory space, want to leave room for the VME window
+ */
+ setdbat(2, PCI0_MEM_BASE, PCI0_MEM_BASE, 0x10000000, IO_PAGE);
+
+ /* Till Straumann: 2004
+ * map the PCI 0, 1 Domain I/O space, GT64260B registers
+ * and the reserved area so that the size is the power of 2.
+ * 2009 : map the entire 256 M space
+ *
+ */
+ setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x10000000, IO_PAGE);
+
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function store the result in global variables so that it can be used later.
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+#ifdef SHOW_LCR1_REGISTER
+ l1cr = get_L1CR();
+ printk("Initial L1CR value = %x\n", l1cr);
+#endif
+
+ /*
+ * Initialize the interrupt related settings.
+ */
+ intrStackStart = (uintptr_t) __rtems_end;
+ intrStackSize = rtems_configuration_get_interrupt_stack_size();
+
+ /*
+ * Initialize default raw exception handlers.
+ */
+ ppc_exc_initialize(intrStackStart, intrStackSize);
+
+ /*
+ * Init MMU block address translation to enable hardware
+ * access
+ * More PCI1 memory mapping to be done after BSP_pgtbl_activate.
+ */
+ printk("-----------------------------------------\n");
+ printk("Welcome to %s on MVME5500-0163\n", _RTEMS_version );
+ printk("-----------------------------------------\n");
+
+ BSP_mem_size = probeMemoryEnd();
+
+ /* TODO: calculate the BSP_bus_frequency using the REF_CLK bit
+ * of System Status register
+ */
+ /* rtems_bsp_delay_in_bus_cycles are defined in registers.h */
+ BSP_bus_frequency = 133333333;
+ BSP_processor_frequency = 1000000000;
+ /* P94 : 7455 clocks the TB/DECR at 1/4 of the system bus clock frequency */
+ BSP_time_base_divisor = 4000;
+
+ /* Maybe not setup yet becuase of the warning message */
+ /* Allocate and set up the page table mappings
+ * This is only available on >604 CPUs.
+ *
+ * NOTE: This setup routine may modify the available memory
+ * size. It is essential to call it before
+ * calculating the workspace etc.
+ */
+ pt = BSP_pgtbl_setup(&BSP_mem_size);
+ if (!pt)
+ printk("WARNING: unable to setup page tables.\n");
+
+ printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size);
+
+ /* P94 : 7455 TB/DECR is clocked by the system bus clock frequency */
+
+ bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
+ rtems_counter_initialize_converter(
+ BSP_bus_frequency / (BSP_time_base_divisor / 1000)
+ );
+
+ /*
+ * Initalize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mng_init(0);
+
+#ifdef SHOW_LCR2_REGISTER
+ l2cr = get_L2CR();
+ printk("Initial L2CR value = %x\n", l2cr);
+#endif
+
+#ifdef SHOW_LCR3_REGISTER
+ /* L3CR needs DEC int. handler installed for bsp_delay()*/
+ l3cr = get_L3CR();
+ printk("Initial L3CR value = %x\n", l3cr);
+#endif
+
+
+ /* Activate the page table mappings only after
+ * initializing interrupts because the irq_mng_init()
+ * routine needs to modify the text
+ */
+ if (pt) {
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Page table setup finished; will activate it NOW...\n");
+#endif
+ BSP_pgtbl_activate(pt);
+ }
+ /* Read Configuration Vital Product Data (VPD) */
+ if ( I2Cread_eeprom(0xa8, 4,2, &ConfVPD_buff[0], 150))
+ printk("I2Cread_eeprom() error \n");
+ else {
+#ifdef CONF_VPD
+ printk("\n");
+ for (i=0; i<150; i++) {
+ printk("%2x ", ConfVPD_buff[i]);
+ if ((i % 20)==0 ) printk("\n");
+ }
+ printk("\n");
+#endif
+ }
+
+ /*
+ * PCI 1 domain memory space
+ */
+ setdbat(1, PCI1_MEM_BASE, PCI1_MEM_BASE, 0x10000000, IO_PAGE);
+
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Going to start PCI buses scanning and initialization\n");
+#endif
+ pci_initialize();
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Number of PCI buses found is : %d\n", pci_bus_count());
+#endif
+
+ /* Install our own exception handler (needs PCI) */
+ globalExceptHdl = BSP_exceptionHandler;
+
+ /* clear hostbridge errors. MCP signal is not used on the MVME5500
+ * PCI config space scanning code will trip otherwise :-(
+ */
+ _BSP_clear_hostbridge_errors(0, 1 /*quiet*/);
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("MSR %x \n", _read_MSR());
+ printk("Exit from bspstart\n");
+#endif
+
+}
+
+unsigned char ReadConfVPD_buff(int offset)
+{
+ return(ConfVPD_buff[offset]);
+}
+
+RTEMS_SYSINIT_ITEM(
+ BSP_vme_config,
+ RTEMS_SYSINIT_BSP_PRE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
diff --git a/bsps/powerpc/mvme5500/start/linkcmds b/bsps/powerpc/mvme5500/start/linkcmds
new file mode 100644
index 0000000000..384b623474
--- /dev/null
+++ b/bsps/powerpc/mvme5500/start/linkcmds
@@ -0,0 +1,5 @@
+STARTUP(mvme5500start.o)
+ENTRY(__rtems_entry_point)
+EXTERN(__vectors)
+
+INCLUDE linkcmds.share
diff --git a/bsps/powerpc/mvme5500/start/pgtbl_activate.c b/bsps/powerpc/mvme5500/start/pgtbl_activate.c
new file mode 100644
index 0000000000..79725c6a06
--- /dev/null
+++ b/bsps/powerpc/mvme5500/start/pgtbl_activate.c
@@ -0,0 +1,37 @@
+/*
+ * Default activation of the page tables. This is a weak
+ * alias, so applications may easily override this
+ * default activation procedure.
+ */
+
+/* Author: Till Straumann, <strauman@slac.stanford.edu>, 4/2002
+ * Kate Feng <feng1@bnl.gov> ported it to MVME5500, 4/2004
+ */
+
+#include <rtems.h>
+#include <libcpu/pte121.h>
+#include <libcpu/bat.h>
+
+static void
+__BSP_default_pgtbl_activate(Triv121PgTbl pt)
+{
+ if (!pt)
+ return;
+
+ /* switch the text/ro sements to RO only after
+ * initializing the interrupts because the irq_mng
+ * installs some code...
+ *
+ * activate the page table; it is still masked by the
+ * DBAT0, however
+ */
+ triv121PgTblActivate(pt);
+
+ /* finally, switch off DBAT0 & DBAT1 */
+ setdbat(0,0,0,0,0);
+ setdbat(1,0,0,0,0); /* <skf> */
+ /* At this point, DBAT0 is available for other use... */
+}
+
+void BSP_pgtbl_activate(Triv121PgTbl)
+ __attribute__ (( weak, alias("__BSP_default_pgtbl_activate") ));
diff --git a/bsps/powerpc/psim/start/bsp_specs b/bsps/powerpc/psim/start/bsp_specs
new file mode 100644
index 0000000000..2625609327
--- /dev/null
+++ b/bsps/powerpc/psim/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/psim/start/bspstart.c b/bsps/powerpc/psim/start/bspstart.c
new file mode 100644
index 0000000000..3a9809c022
--- /dev/null
+++ b/bsps/powerpc/psim/start/bspstart.c
@@ -0,0 +1,113 @@
+/*
+ * This set of routines starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before any of these are invoked.
+ *
+ * COPYRIGHT (c) 1989-2008.
+ * 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 <string.h>
+#include <fcntl.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <psim.h>
+#include <bsp/bootcard.h>
+#include <bsp/linker-symbols.h>
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+#include <rtems/powerpc/powerpc.h>
+
+#include <libcpu/cpuIdent.h>
+#include <libcpu/bat.h>
+#include <libcpu/spr.h>
+
+SPR_RW(SPRG1)
+
+/* On psim, each click of the decrementer register corresponds
+ * to 1 instruction. By setting this to 100, we are indicating
+ * that we are assuming it can execute 100 instructions per
+ * microsecond. This corresponds to sustaining 1 instruction
+ * per cycle at 100 Mhz. Whether this is a good guess or not
+ * is anyone's guess.
+ */
+extern int PSIM_INSTRUCTIONS_PER_MICROSECOND[];
+
+/*
+ * PCI Bus Frequency
+ */
+unsigned int BSP_bus_frequency;
+
+/*
+ * Driver configuration parameters
+ */
+uint32_t bsp_clicks_per_usec;
+
+/*
+ * Memory on this board.
+ */
+uint32_t BSP_mem_size = (uint32_t)RamSize;
+
+/*
+ * Time base divisior (how many tick for 1 second).
+ */
+unsigned int BSP_time_base_divisor;
+
+extern unsigned long __rtems_end[];
+
+/*
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ */
+void bsp_start( void )
+{
+ /*
+ * Note we can not get CPU identification dynamically.
+ * PVR has to be set to PPC_PSIM (0xfffe) from the device
+ * file.
+ */
+
+ get_ppc_cpu_type();
+
+ /*
+ * initialize the device driver parameters
+ */
+ BSP_bus_frequency = (unsigned int)PSIM_INSTRUCTIONS_PER_MICROSECOND;
+ bsp_clicks_per_usec = BSP_bus_frequency;
+ BSP_time_base_divisor = 1;
+ rtems_counter_initialize_converter(bsp_clicks_per_usec * 1000000);
+
+ /*
+ * Initialize default raw exception handlers.
+ */
+ ppc_exc_initialize_with_vector_base(
+ (uintptr_t) bsp_section_work_begin,
+ rtems_configuration_get_interrupt_stack_size(),
+ (void *) 0xfff00000
+ );
+
+ /*
+ * Initalize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mng_init(0);
+
+ /*
+ * Setup BATs and enable MMU
+ */
+ /* Memory */
+ setdbat(0, 0x0<<24, 0x0<<24, 2<<24, _PAGE_RW);
+ setibat(0, 0x0<<24, 0x0<<24, 2<<24, 0);
+ /* PCI */
+ setdbat(1, 0x8<<24, 0x8<<24, 1<<24, IO_PAGE);
+ setdbat(2, 0xc<<24, 0xc<<24, 1<<24, IO_PAGE);
+
+ _write_MSR(_read_MSR() | MSR_DR | MSR_IR);
+ __asm__ volatile("sync; isync");
+
+}
diff --git a/bsps/powerpc/psim/start/device-tree b/bsps/powerpc/psim/start/device-tree
new file mode 100644
index 0000000000..bd2a2a56ef
--- /dev/null
+++ b/bsps/powerpc/psim/start/device-tree
@@ -0,0 +1,4 @@
+#/openprom/init/register/pc 0
+#/openprom/options/smp 2
+#/openprom/options/oea-memory-size 4194304
+/openprom/options/oea-memory-size 8388608
diff --git a/bsps/powerpc/psim/start/linkcmds b/bsps/powerpc/psim/start/linkcmds
new file mode 100644
index 0000000000..ba9319c91d
--- /dev/null
+++ b/bsps/powerpc/psim/start/linkcmds
@@ -0,0 +1,40 @@
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * 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.
+ */
+
+EXTERN (__vectors)
+
+MEMORY {
+ RAM : ORIGIN = 0, LENGTH = 16M
+ EMPTY : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", 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_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", EMPTY);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", EMPTY);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+PROVIDE (PSIM_INSTRUCTIONS_PER_MICROSECOND = 10000);
+
+PSIM = 0x0c000000;
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/qemuppc/start/bsp_specs b/bsps/powerpc/qemuppc/start/bsp_specs
new file mode 100644
index 0000000000..2625609327
--- /dev/null
+++ b/bsps/powerpc/qemuppc/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/qemuppc/start/bspstart.c b/bsps/powerpc/qemuppc/start/bspstart.c
new file mode 100644
index 0000000000..94d7f4b84d
--- /dev/null
+++ b/bsps/powerpc/qemuppc/start/bspstart.c
@@ -0,0 +1,121 @@
+/*
+ * This set of routines starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before any of these are invoked.
+ *
+ * COPYRIGHT (c) 1989-2008.
+ * 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 <string.h>
+#include <fcntl.h>
+
+#include <rtems/counter.h>
+
+#include <libcpu/bat.h>
+#include <libcpu/spr.h>
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/vectors.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+
+/*
+ * CPU Bus Frequency
+ */
+unsigned int BSP_bus_frequency;
+
+/* Configuration parameter for clock driver */
+uint32_t bsp_time_base_frequency;
+
+/* Legacy */
+uint32_t bsp_clicks_per_usec;
+
+/*
+ * Memory on this board.
+ */
+extern char RamSize[];
+extern char bsp_interrupt_stack_start[];
+extern char bsp_interrupt_stack_end[];
+uint32_t BSP_mem_size = (uint32_t)RamSize;
+
+/* Default decrementer exception handler */
+static int default_decrementer_exception_handler( BSP_Exception_frame *frame, unsigned number)
+{
+ ppc_set_decrementer_register(UINT32_MAX);
+
+ return 0;
+}
+
+/*
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ */
+
+void bsp_start( void )
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ uintptr_t intrStackStart;
+ uintptr_t intrStackSize;
+
+ /*
+ * Note we can not get CPU identification dynamically, so
+ * force current_ppc_cpu.
+ */
+ current_ppc_cpu = PPC_PSIM;
+
+ /*
+ * initialize the device driver parameters
+ * assume we are running with 20MHz bus
+ * this should speed up some tests :-)
+ */
+ BSP_bus_frequency = 20;
+ bsp_time_base_frequency = 20000000;
+ bsp_clicks_per_usec = BSP_bus_frequency;
+ rtems_counter_initialize_converter(bsp_time_base_frequency);
+
+ /*
+ * Initialize the interrupt related settings.
+ */
+ intrStackStart = (uintptr_t) bsp_interrupt_stack_start;
+ intrStackSize = (uintptr_t) bsp_interrupt_stack_end - intrStackStart;
+
+ BSP_mem_size = (uint32_t )RamSize;
+
+ /*
+ * Initialize default raw exception handlers.
+ */
+ ppc_exc_initialize(intrStackStart, intrStackSize);
+
+ /* Install default handler for the decrementer exception */
+ sc = ppc_exc_set_handler( ASM_DEC_VECTOR, default_decrementer_exception_handler);
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_panic("cannot install decrementer exception handler");
+ }
+
+ /* Initalize interrupt support */
+ bsp_interrupt_initialize();
+
+#if 0
+ /*
+ * Setup BATs and enable MMU
+ */
+ /* Memory */
+ setdbat(0, 0x0<<24, 0x0<<24, 2<<24, _PAGE_RW);
+ setibat(0, 0x0<<24, 0x0<<24, 2<<24, 0);
+ /* PCI */
+ setdbat(1, 0x8<<24, 0x8<<24, 1<<24, IO_PAGE);
+ setdbat(2, 0xc<<24, 0xc<<24, 1<<24, IO_PAGE);
+
+ _write_MSR(_read_MSR() | MSR_DR | MSR_IR);
+ __asm__ volatile("sync; isync");
+#endif
+}
diff --git a/bsps/powerpc/qemuppc/start/cmain.c b/bsps/powerpc/qemuppc/start/cmain.c
new file mode 100644
index 0000000000..bf46d03177
--- /dev/null
+++ b/bsps/powerpc/qemuppc/start/cmain.c
@@ -0,0 +1,55 @@
+#include <bsp/bootcard.h>
+#include <bsp/linker-symbols.h>
+
+static void
+__outb(int port, unsigned char v)
+{
+ *((volatile unsigned char *)(0x80000000 + port)) = v;
+}
+
+#if 0
+/* currently unused but keep just in case */
+
+static unsigned char
+__inb(int port)
+{
+ return *((volatile unsigned char *)(0x80000000 + port));
+}
+#endif
+
+static void
+__memcpy (unsigned char *d, unsigned char *s, int len)
+{
+ while (len--)
+ *d++ = *s++;
+}
+
+static void
+__bzero (unsigned char *d, int len)
+{
+ while (len--)
+ *d++ = 0;
+}
+
+
+/*
+ * Prototype this here because it is just the entry symbol and
+ * not referenced from any compileable code.
+ */
+void cmain (void);
+
+void cmain (void)
+{
+ /*
+ * init variable sections
+ */
+ __memcpy (bsp_section_data_begin, bsp_section_data_load_begin, (int)bsp_section_data_size);
+ __bzero (bsp_section_bss_begin, (int)bsp_section_bss_size);
+ __bzero (bsp_section_sbss_begin, (int)bsp_section_sbss_size);
+ /* printk( "start of BSP\n"); */
+ boot_card(0);
+ /* printk( "end of BSP\n"); */
+ __outb (0x92, 0x01);
+ while (1)
+ ;
+}
diff --git a/bsps/powerpc/qemuppc/start/linkcmds b/bsps/powerpc/qemuppc/start/linkcmds
new file mode 100644
index 0000000000..3169ad2741
--- /dev/null
+++ b/bsps/powerpc/qemuppc/start/linkcmds
@@ -0,0 +1,38 @@
+EXTERN(__vectors)
+
+MEMORY
+ {
+ EMPTY : ORIGIN = 0, LENGTH = 0
+ RAM : ORIGIN = 0x2000, LENGTH = 4M - 0x2000
+ ROM : ORIGIN = 0xFFC00000, LENGTH = 4M
+ VECTORS : ORIGIN = 0xFFF00000, LENGTH = 0x20000
+ RESET : ORIGIN = 0xFFFFFFFC, LENGTH = 0x4
+ }
+
+REGION_ALIAS ("REGION_START", ROM);
+REGION_ALIAS ("REGION_FAST_TEXT", ROM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_TEXT", ROM);
+REGION_ALIAS ("REGION_TEXT_LOAD", ROM);
+REGION_ALIAS ("REGION_RODATA", ROM);
+REGION_ALIAS ("REGION_RODATA_LOAD", ROM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", ROM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", EMPTY);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", EMPTY);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+SECTIONS {
+ .reset :
+ {
+ KEEP(*(.reset))
+ } >RESET
+}
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/qoriq/start/bsp_specs b/bsps/powerpc/qoriq/start/bsp_specs
new file mode 100644
index 0000000000..001c45b3c4
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s rtems_crtn.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/qoriq/start/bspreset.c b/bsps/powerpc/qoriq/start/bspreset.c
new file mode 100644
index 0000000000..545aa28ee3
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/bspreset.c
@@ -0,0 +1,64 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQ
+ *
+ * @brief BSP reset.
+ */
+
+/*
+ * Copyright (c) 2010, 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/bootcard.h>
+#include <bsp/fdt.h>
+#include <bsp/qoriq.h>
+
+#include <libfdt.h>
+
+static int find_rstcr_node(const void *fdt, int node)
+{
+ return fdt_node_offset_by_prop_value(fdt, node, "fsl,has-rstcr", NULL, 0);
+}
+
+void bsp_reset(void)
+{
+ rtems_interrupt_level level;
+ const char *fdt;
+
+ rtems_interrupt_local_disable(level);
+ (void) level;
+
+ fdt = bsp_fdt_get();
+
+ /* If we do not find a RSTCR, then loop forever */
+ while (true) {
+ int node;
+
+ node = -1;
+
+ while ((node = find_rstcr_node(fdt, node)) >= 0) {
+ const uint32_t *reg;
+ int len;
+
+ reg = fdt_getprop(fdt, node, "reg", &len);
+ if (reg != NULL && len >= 4) {
+ volatile uint32_t *rstcr;
+
+ rstcr = (volatile uint32_t *)
+ ((uintptr_t) &qoriq + fdt32_to_cpu(reg[0]) + 0xb0);
+ *rstcr = 0x2;
+ }
+ }
+ }
+}
diff --git a/bsps/powerpc/qoriq/start/bsprestart.c b/bsps/powerpc/qoriq/start/bsprestart.c
new file mode 100644
index 0000000000..36e751e50d
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/bsprestart.c
@@ -0,0 +1,146 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQ
+ *
+ * @brief BSP restart.
+ */
+
+/*
+ * Copyright (c) 2016, 2018 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/irq.h>
+#include <bsp/fatal.h>
+#include <bsp/fdt.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/qoriq.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <string.h>
+
+static char fdt_copy[BSP_FDT_BLOB_SIZE_MAX];
+
+static RTEMS_NO_RETURN void do_restart(void *addr)
+{
+ void (*restart)(uintptr_t);
+
+ qoriq_reset_qman_and_bman();
+
+ memcpy(fdt_copy, bsp_fdt_get(), sizeof(fdt_copy));
+ rtems_cache_flush_multiple_data_lines(fdt_copy, sizeof(fdt_copy));
+
+ restart = addr;
+ (*restart)((uintptr_t) fdt_copy);
+ bsp_fatal(QORIQ_FATAL_RESTART_FAILED);
+}
+
+#if defined(RTEMS_SMP) && !defined(QORIQ_IS_HYPERVISOR_GUEST)
+
+#include <rtems/score/smpimpl.h>
+#include <rtems/score/smpbarrier.h>
+
+#define RESTART_IPI_INDEX 1
+
+static SMP_barrier_Control restart_barrier = SMP_BARRIER_CONTROL_INITIALIZER;
+
+static void restart_interrupt(void *arg)
+{
+ uint32_t cpu_self_index;
+ uint32_t thread_index;
+ rtems_interrupt_level level;
+ SMP_barrier_State bs;
+
+ rtems_interrupt_local_disable(level);
+ (void) level;
+
+ _SMP_barrier_State_initialize(&bs);
+ _SMP_barrier_Wait(&restart_barrier, &bs, _SMP_Processor_count);
+
+ cpu_self_index = rtems_get_current_processor();
+ thread_index = cpu_self_index % QORIQ_THREAD_COUNT;
+
+ if (cpu_self_index == 0) {
+ do_restart(arg);
+ } else if (thread_index == 0) {
+ uint32_t real_processor_index;
+ const qoriq_start_spin_table *spin_table;
+
+ real_processor_index = cpu_self_index / QORIQ_THREAD_COUNT;
+ spin_table = qoriq_start_spin_table_addr[real_processor_index];
+
+ qoriq_restart_secondary_processor(spin_table);
+ } else {
+ uint32_t pir_reset_value;
+
+ /* Restore reset PIR value */
+ pir_reset_value = (cpu_self_index & ~0x1U) << 2;
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_PIR, pir_reset_value);
+
+ /* Thread Enable Clear (TENC) */
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_TENC, 1U << thread_index);
+
+ RTEMS_UNREACHABLE();
+ }
+}
+
+static void raise_restart_interrupt(void)
+{
+ qoriq.pic.ipidr[RESTART_IPI_INDEX].reg =
+ _Processor_mask_To_uint32_t(_SMP_Get_online_processors(), 0);
+ ppc_synchronize_data();
+ ppc_synchronize_instructions();
+}
+
+void bsp_restart(void *addr)
+{
+ rtems_status_code sc;
+ size_t i;
+
+ for (i = 0; i < RTEMS_ARRAY_SIZE(qoriq_start_spin_table_addr); ++i) {
+ qoriq_start_spin_table *spin_table;
+
+ spin_table = qoriq_start_spin_table_addr[i];
+ memset(spin_table, 0, sizeof(*spin_table));
+ rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table));
+ }
+
+ sc = rtems_interrupt_handler_install(
+ QORIQ_IRQ_IPI_0 + RESTART_IPI_INDEX,
+ "Restart",
+ RTEMS_INTERRUPT_UNIQUE,
+ restart_interrupt,
+ addr
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_fatal(QORIQ_FATAL_RESTART_INSTALL_INTERRUPT);
+ }
+
+ raise_restart_interrupt();
+ bsp_fatal(QORIQ_FATAL_RESTART_INTERRUPT_FAILED);
+}
+
+#else /* !RTEMS_SMP || QORIQ_IS_HYPERVISOR_GUEST */
+
+void bsp_restart(void *addr)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ (void) level;
+ do_restart(addr);
+}
+
+#endif /* RTEMS_SMP && !QORIQ_IS_HYPERVISOR_GUEST */
diff --git a/bsps/powerpc/qoriq/start/bspsmp.c b/bsps/powerpc/qoriq/start/bspsmp.c
new file mode 100644
index 0000000000..a2d9fbede5
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/bspsmp.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2013, 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/score/smpimpl.h>
+
+#include <libfdt.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/fdt.h>
+#include <bsp/mmu.h>
+#include <bsp/fatal.h>
+#include <bsp/qoriq.h>
+#include <bsp/vectors.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+
+LINKER_SYMBOL(bsp_exc_vector_base);
+
+#if QORIQ_THREAD_COUNT > 1
+void _start_thread(void);
+#endif
+
+void _start_secondary_processor(void);
+
+#define IPI_INDEX 0
+
+#if QORIQ_THREAD_COUNT > 1
+static bool is_started_by_u_boot(uint32_t cpu_index)
+{
+ return cpu_index % QORIQ_THREAD_COUNT == 0;
+}
+
+void qoriq_start_thread(void)
+{
+ const Per_CPU_Control *cpu_self = _Per_CPU_Get();
+
+ ppc_exc_initialize_interrupt_stack(
+ (uintptr_t) cpu_self->interrupt_stack_low,
+ rtems_configuration_get_interrupt_stack_size()
+ );
+
+ bsp_interrupt_facility_initialize();
+
+ _SMP_Start_multitasking_on_secondary_processor();
+}
+#endif
+
+static void start_thread_if_necessary(uint32_t cpu_index_self)
+{
+#if QORIQ_THREAD_COUNT > 1
+ uint32_t i;
+
+ for (i = 1; i < QORIQ_THREAD_COUNT; ++i) {
+ uint32_t cpu_index_next = cpu_index_self + i;
+
+ if (
+ is_started_by_u_boot(cpu_index_self)
+ && cpu_index_next < rtems_configuration_get_maximum_processors()
+ && _SMP_Should_start_processor(cpu_index_next)
+ ) {
+ /* Thread Initial Next Instruction Address (INIA) */
+ PPC_SET_THREAD_MGMT_REGISTER(321, (uintptr_t) _start_thread);
+
+ /* Thread Initial Machine State (IMSR) */
+ PPC_SET_THREAD_MGMT_REGISTER(289, QORIQ_INITIAL_MSR);
+
+ /* Thread Enable Set (TENS) */
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_TENS, 1U << i);
+ }
+ }
+#endif
+}
+
+void bsp_start_on_secondary_processor(void)
+{
+ uint32_t cpu_index_self = _SMP_Get_current_processor();
+ const Per_CPU_Control *cpu_self = _Per_CPU_Get_by_index(cpu_index_self);
+
+ qoriq_initialize_exceptions(cpu_self->interrupt_stack_low);
+ bsp_interrupt_facility_initialize();
+
+ start_thread_if_necessary(cpu_index_self);
+
+ _SMP_Start_multitasking_on_secondary_processor();
+}
+
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
+static void bsp_inter_processor_interrupt(void *arg)
+{
+ _SMP_Inter_processor_interrupt_handler();
+}
+#endif
+
+static void setup_boot_page(void)
+{
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+ qoriq_mmu_context mmu_context;
+
+ qoriq_mmu_context_init(&mmu_context);
+ qoriq_mmu_add(
+ &mmu_context,
+ 0xfffff000,
+ 0xffffffff,
+ 0,
+ 0,
+ FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
+ 0
+ );
+ qoriq_mmu_partition(&mmu_context, 1);
+ qoriq_mmu_write_to_tlb1(&mmu_context, QORIQ_TLB1_ENTRY_COUNT - 1);
+#endif
+}
+
+static uint32_t discover_processors(void)
+{
+ const void *fdt = bsp_fdt_get();
+ int cpus = fdt_path_offset(fdt, "/cpus");
+ int node = fdt_first_subnode(fdt, cpus);
+ uint32_t cpu = 0;
+
+ while (node >= 0 && cpu < RTEMS_ARRAY_SIZE(qoriq_start_spin_table_addr)) {
+ int len;
+ fdt64_t *addr_fdt = (fdt64_t *)
+ fdt_getprop(fdt, node, "cpu-release-addr", &len);
+
+ if (addr_fdt != NULL) {
+ uintptr_t addr = (uintptr_t) fdt64_to_cpu(*addr_fdt);
+
+ qoriq_start_spin_table_addr[cpu] = (qoriq_start_spin_table *) addr;
+ }
+
+ ++cpu;
+ node = fdt_next_subnode(fdt, node);
+ }
+
+ return cpu * QORIQ_THREAD_COUNT;
+}
+
+uint32_t _CPU_SMP_Initialize(void)
+{
+ uint32_t cpu_count = 1;
+
+ if (rtems_configuration_get_maximum_processors() > 0) {
+ setup_boot_page();
+ cpu_count = discover_processors();
+ }
+
+ start_thread_if_necessary(0);
+
+ return cpu_count;
+}
+
+static bool release_processor(
+ qoriq_start_spin_table *spin_table,
+ uint32_t cpu_index
+)
+{
+ bool spin_table_present = (spin_table != NULL);
+
+ if (spin_table_present) {
+ const Per_CPU_Control *cpu = _Per_CPU_Get_by_index(cpu_index);
+
+ spin_table->pir = cpu_index;
+ spin_table->r3 = (uintptr_t) cpu->interrupt_stack_high;
+ rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table));
+ ppc_synchronize_data();
+ spin_table->addr = (uintptr_t) _start_secondary_processor;
+ rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table));
+ }
+
+ return spin_table_present;
+}
+
+static qoriq_start_spin_table *get_spin_table(uint32_t cpu_index)
+{
+ qoriq_start_spin_table *spin_table;
+
+ spin_table = qoriq_start_spin_table_addr[cpu_index / QORIQ_THREAD_COUNT];
+
+ return spin_table;
+}
+
+bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+{
+#if QORIQ_THREAD_COUNT > 1
+ if (is_started_by_u_boot(cpu_index)) {
+ qoriq_start_spin_table *spin_table = get_spin_table(cpu_index);
+
+ return release_processor(spin_table, cpu_index);
+ } else {
+ return _SMP_Should_start_processor(cpu_index - 1);
+ }
+#else
+ qoriq_start_spin_table *spin_table = get_spin_table(cpu_index);
+
+ return release_processor(spin_table, cpu_index);
+#endif
+}
+
+void _CPU_SMP_Finalize_initialization(uint32_t cpu_count)
+{
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+ (void) cpu_count;
+#else
+ if (cpu_count > 1) {
+ rtems_status_code sc;
+
+ sc = rtems_interrupt_handler_install(
+ QORIQ_IRQ_IPI_0 + IPI_INDEX,
+ "IPI",
+ RTEMS_INTERRUPT_UNIQUE,
+ bsp_inter_processor_interrupt,
+ NULL
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_fatal(QORIQ_FATAL_SMP_IPI_HANDLER_INSTALL);
+ }
+ }
+#endif
+}
+
+void _CPU_SMP_Prepare_start_multitasking(void)
+{
+ /* Do nothing */
+}
+
+void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
+{
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+ uint32_t msg;
+
+ /* DBELL message type */
+ msg = (0U << (63 - 36)) | target_processor_index;
+ __asm__ volatile ("msgsnd %0" : : "r" (msg));
+#else
+ qoriq.pic.ipidr [IPI_INDEX].reg = 1U << target_processor_index;
+#endif
+}
diff --git a/bsps/powerpc/qoriq/start/bspstart.c b/bsps/powerpc/qoriq/start/bspstart.c
new file mode 100644
index 0000000000..7d9fa0d3c7
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/bspstart.c
@@ -0,0 +1,197 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQ
+ *
+ * @brief BSP startup.
+ */
+
+/*
+ * Copyright (c) 2010, 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 <libfdt.h>
+
+#include <rtems.h>
+#include <rtems/config.h>
+#include <rtems/counter.h>
+#include <rtems/sysinit.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/console-termios.h>
+#include <bsp/fatal.h>
+#include <bsp/fdt.h>
+#include <bsp/intercom.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/mmu.h>
+#include <bsp/qoriq.h>
+#include <bsp/vectors.h>
+
+LINKER_SYMBOL(bsp_exc_vector_base);
+
+qoriq_start_spin_table *
+qoriq_start_spin_table_addr[QORIQ_CPU_COUNT / QORIQ_THREAD_COUNT];
+
+/* Configuration parameters for console driver, ... */
+unsigned int BSP_bus_frequency;
+
+/* Configuration parameter for clock driver, ... */
+uint32_t bsp_time_base_frequency;
+
+uint32_t qoriq_clock_frequency;
+
+static void initialize_frequency_parameters(void)
+{
+ const void *fdt = bsp_fdt_get();
+ int node;
+ int len;
+ fdt32_t *val_fdt;
+
+ node = fdt_node_offset_by_prop_value(fdt, -1, "device_type", "cpu", 4);
+
+ val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "bus-frequency", &len);
+ if (val_fdt == NULL || len != 4) {
+ bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY);
+ }
+ BSP_bus_frequency = fdt32_to_cpu(*val_fdt) / QORIQ_BUS_CLOCK_DIVIDER;
+
+ val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "timebase-frequency", &len);
+ if (val_fdt == NULL || len != 4) {
+ bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY);
+ }
+ bsp_time_base_frequency = fdt32_to_cpu(*val_fdt);
+
+ #ifdef __PPC_CPU_E6500__
+ val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "clock-frequency", &len);
+ if (val_fdt == NULL || len != 4) {
+ bsp_fatal(QORIQ_FATAL_FDT_NO_CLOCK_FREQUENCY);
+ }
+ qoriq_clock_frequency = fdt32_to_cpu(*val_fdt);
+ #endif
+ rtems_counter_initialize_converter(fdt32_to_cpu(*val_fdt));
+}
+
+#define MTIVPR(base) \
+ __asm__ volatile ("mtivpr %0" : : "r" (base))
+
+#ifdef __powerpc64__
+#define VECTOR_TABLE_ENTRY_SIZE 32
+#else
+#define VECTOR_TABLE_ENTRY_SIZE 16
+#endif
+
+#define MTIVOR(vec, offset) \
+ do { \
+ __asm__ volatile ("mtspr " RTEMS_XSTRING(vec) ", %0" : : "r" (offset)); \
+ offset += VECTOR_TABLE_ENTRY_SIZE; \
+ } while (0)
+
+void qoriq_initialize_exceptions(void *interrupt_stack_begin)
+{
+ uintptr_t addr;
+
+ ppc_exc_initialize_interrupt_stack(
+ (uintptr_t) interrupt_stack_begin,
+ rtems_configuration_get_interrupt_stack_size()
+ );
+
+ addr = (uintptr_t) bsp_exc_vector_base;
+ MTIVPR(addr);
+ MTIVOR(BOOKE_IVOR0, addr);
+ MTIVOR(BOOKE_IVOR1, addr);
+ MTIVOR(BOOKE_IVOR2, addr);
+ MTIVOR(BOOKE_IVOR3, addr);
+ MTIVOR(BOOKE_IVOR4, addr);
+ MTIVOR(BOOKE_IVOR5, addr);
+ MTIVOR(BOOKE_IVOR6, addr);
+#ifdef __PPC_CPU_E6500__
+ MTIVOR(BOOKE_IVOR7, addr);
+#endif
+ MTIVOR(BOOKE_IVOR8, addr);
+#ifdef __PPC_CPU_E6500__
+ MTIVOR(BOOKE_IVOR9, addr);
+#endif
+ MTIVOR(BOOKE_IVOR10, addr);
+ MTIVOR(BOOKE_IVOR11, addr);
+ MTIVOR(BOOKE_IVOR12, addr);
+ MTIVOR(BOOKE_IVOR13, addr);
+ MTIVOR(BOOKE_IVOR14, addr);
+ MTIVOR(BOOKE_IVOR15, addr);
+ MTIVOR(BOOKE_IVOR32, addr);
+ MTIVOR(BOOKE_IVOR33, addr);
+#ifndef __PPC_CPU_E6500__
+ MTIVOR(BOOKE_IVOR34, addr);
+#endif
+ MTIVOR(BOOKE_IVOR35, addr);
+#ifdef __PPC_CPU_E6500__
+ MTIVOR(BOOKE_IVOR36, addr);
+ MTIVOR(BOOKE_IVOR37, addr);
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
+ MTIVOR(BOOKE_IVOR38, addr);
+ MTIVOR(BOOKE_IVOR39, addr);
+ MTIVOR(BOOKE_IVOR40, addr);
+ MTIVOR(BOOKE_IVOR41, addr);
+ MTIVOR(BOOKE_IVOR42, addr);
+#endif
+#endif
+}
+
+void bsp_start(void)
+{
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
+ * store the result in global variables so that it can be used latter...
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ initialize_frequency_parameters();
+
+ qoriq_initialize_exceptions(bsp_section_work_begin);
+ bsp_interrupt_initialize();
+
+ rtems_cache_coherent_add_area(
+ bsp_section_nocacheheap_begin,
+ (uintptr_t) bsp_section_nocacheheap_size
+ );
+
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
+ /* Disable boot page translation */
+#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
+ qoriq.lcc.bstar &= ~LCC_BSTAR_EN;
+#else
+ qoriq.lcc.bptr &= ~BPTR_EN;
+#endif
+#endif
+}
+
+uint32_t bsp_fdt_map_intr(const uint32_t *intr, size_t icells)
+{
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
+ return intr[0] - 16;
+#else
+ return intr[0];
+#endif
+}
+
+#ifdef RTEMS_MULTIPROCESSING
+RTEMS_SYSINIT_ITEM(
+ qoriq_intercom_init,
+ RTEMS_SYSINIT_BSP_PRE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
+#endif
diff --git a/bsps/powerpc/qoriq/start/epapr_hcalls.S b/bsps/powerpc/qoriq/start/epapr_hcalls.S
new file mode 100644
index 0000000000..b019e5d710
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/epapr_hcalls.S
@@ -0,0 +1,26 @@
+/*
+ * 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 <libcpu/powerpc-utility.h>
+
+ .text
+
+ .global epapr_hypercall_start
+epapr_hypercall_start:
+
+ sc 1
+ nop
+ nop
+ nop
+ blr
diff --git a/bsps/powerpc/qoriq/start/l1cache.S b/bsps/powerpc/qoriq/start/l1cache.S
new file mode 100644
index 0000000000..bee3d28123
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/l1cache.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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 <libcpu/powerpc-utility.h>
+
+ .global qoriq_l1cache_invalidate
+
+ .section ".bsp_start_text", "ax"
+
+qoriq_l1cache_invalidate:
+
+ /* Invalidate L1 data cache */
+ mfspr r3, FSL_EIS_L1CSR0
+ ori r3, r3, FSL_EIS_L1CSR0_CFI
+ mtspr FSL_EIS_L1CSR0, r3
+1:
+ mfspr r3, FSL_EIS_L1CSR0
+ andi. r3, r3, FSL_EIS_L1CSR0_CFI
+ bne 1b
+ isync
+
+ /* Invalidate L1 instruction cache */
+ mfspr r3, FSL_EIS_L1CSR1
+ ori r3, r3, FSL_EIS_L1CSR1_ICFI
+ mtspr FSL_EIS_L1CSR1, r3
+1:
+ mfspr r3, FSL_EIS_L1CSR1
+ andi. r3, r3, FSL_EIS_L1CSR1_ICFI
+ bne 1b
+ isync
+
+ blr
diff --git a/bsps/powerpc/qoriq/start/l2cache.S b/bsps/powerpc/qoriq/start/l2cache.S
new file mode 100644
index 0000000000..1c57659aa1
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/l2cache.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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 <libcpu/powerpc-utility.h>
+
+ .global qoriq_l2cache_flush_invalidate
+
+ .section ".bsp_start_text", "ax"
+
+qoriq_l2cache_flush_invalidate:
+
+ /* Flush L2 cache */
+ lwz r4, 0(r3)
+ oris r4, r4, FSL_EIS_L2CSR0_L2FL >> 16
+ stw r4, 0(r3)
+1:
+ lwz r4, 0(r3)
+ andis. r4, r4, FSL_EIS_L2CSR0_L2FL >> 16
+ bne 1b
+ isync
+
+ /* Invalidate L2 cache */
+ lwz r4, 0(r3)
+ oris r4, r4, FSL_EIS_L2CSR0_L2FI >> 16
+ stw r4, 0(r3)
+1:
+ lwz r4, 0(r3)
+ andis. r4, r4, FSL_EIS_L2CSR0_L2FI >> 16
+ bne 1b
+ isync
+
+ blr
diff --git a/bsps/powerpc/qoriq/start/linkcmds.qoriq_core_0 b/bsps/powerpc/qoriq/start/linkcmds.qoriq_core_0
new file mode 100644
index 0000000000..80ae3937bf
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/linkcmds.qoriq_core_0
@@ -0,0 +1,38 @@
+/**
+ * @file
+ *
+ * @brief Memory map for QorIQ Core 0.
+ */
+
+EXTERN (__vectors)
+
+MEMORY {
+ LOW : ORIGIN = 0x4000, LENGTH = 16M - 16k
+ HIGH : ORIGIN = 0x1000000, LENGTH = 32M
+ EMPTY : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("REGION_START", LOW);
+REGION_ALIAS ("REGION_FAST_TEXT", LOW);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", LOW);
+REGION_ALIAS ("REGION_TEXT", LOW);
+REGION_ALIAS ("REGION_TEXT_LOAD", LOW);
+REGION_ALIAS ("REGION_RODATA", HIGH);
+REGION_ALIAS ("REGION_RODATA_LOAD", LOW);
+REGION_ALIAS ("REGION_FAST_DATA", HIGH);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", LOW);
+REGION_ALIAS ("REGION_DATA", HIGH);
+REGION_ALIAS ("REGION_DATA_LOAD", LOW);
+REGION_ALIAS ("REGION_BSS", HIGH);
+REGION_ALIAS ("REGION_RWEXTRA", HIGH);
+REGION_ALIAS ("REGION_WORK", HIGH);
+REGION_ALIAS ("REGION_STACK", HIGH);
+REGION_ALIAS ("REGION_NOCACHE", EMPTY);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", EMPTY);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+bsp_section_robarrier_align = 0x1000000;
+bsp_section_rwbarrier_align = 0x1000000;
+qoriq = 0xffe00000;
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/qoriq/start/linkcmds.qoriq_core_1 b/bsps/powerpc/qoriq/start/linkcmds.qoriq_core_1
new file mode 100644
index 0000000000..ecb601b9ef
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/linkcmds.qoriq_core_1
@@ -0,0 +1,37 @@
+/**
+ * @file
+ *
+ * @brief Memory map for QorIQ Core 1.
+ */
+
+EXTERN (__vectors)
+
+MEMORY {
+ RAM : ORIGIN = 0x4000000, LENGTH = 64M
+ EMPTY : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("REGION_START", 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_RWEXTRA", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", EMPTY);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", EMPTY);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+bsp_section_robarrier_align = 0x1000000;
+bsp_section_rwbarrier_align = 0x1000000;
+qoriq = 0xffe00000;
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/qoriq/start/linkcmds.qoriq_e500 b/bsps/powerpc/qoriq/start/linkcmds.qoriq_e500
new file mode 100644
index 0000000000..b727aefaa8
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/linkcmds.qoriq_e500
@@ -0,0 +1,38 @@
+/**
+ * @file
+ *
+ * Memory map for P1020RDB.
+ */
+
+EXTERN (__vectors)
+
+MEMORY {
+ LOW : ORIGIN = 0x4000, LENGTH = 16M - 16k
+ HIGH : ORIGIN = 0x1000000, LENGTH = 512M - 16M
+ EMPTY : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("REGION_START", LOW);
+REGION_ALIAS ("REGION_FAST_TEXT", LOW);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", LOW);
+REGION_ALIAS ("REGION_TEXT", LOW);
+REGION_ALIAS ("REGION_TEXT_LOAD", LOW);
+REGION_ALIAS ("REGION_RODATA", HIGH);
+REGION_ALIAS ("REGION_RODATA_LOAD", LOW);
+REGION_ALIAS ("REGION_FAST_DATA", HIGH);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", LOW);
+REGION_ALIAS ("REGION_DATA", HIGH);
+REGION_ALIAS ("REGION_DATA_LOAD", LOW);
+REGION_ALIAS ("REGION_BSS", HIGH);
+REGION_ALIAS ("REGION_RWEXTRA", HIGH);
+REGION_ALIAS ("REGION_WORK", HIGH);
+REGION_ALIAS ("REGION_STACK", HIGH);
+REGION_ALIAS ("REGION_NOCACHE", EMPTY);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", EMPTY);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+bsp_section_robarrier_align = 0x1000000;
+bsp_section_rwbarrier_align = 0x1000000;
+qoriq = 0xffe00000;
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/qoriq/start/linkcmds.qoriq_e6500_32 b/bsps/powerpc/qoriq/start/linkcmds.qoriq_e6500_32
new file mode 100644
index 0000000000..900147c163
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/linkcmds.qoriq_e6500_32
@@ -0,0 +1,41 @@
+/**
+ * @file
+ *
+ * Memory map for e6500 core based QorIQ chips, e.g. T2080, T4240.
+ */
+
+EXTERN (__vectors)
+
+MEMORY {
+ LOW : ORIGIN = 0x00004000, LENGTH = 16M - 16k
+ NOCACHE : ORIGIN = 0x01000000, LENGTH = 48M
+ HIGH : ORIGIN = 0x04000000, LENGTH = 512M - 64M
+ EMPTY : ORIGIN = 0x00000000, LENGTH = 0
+}
+
+REGION_ALIAS ("REGION_START", LOW);
+REGION_ALIAS ("REGION_FAST_TEXT", LOW);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", LOW);
+REGION_ALIAS ("REGION_TEXT", LOW);
+REGION_ALIAS ("REGION_TEXT_LOAD", LOW);
+REGION_ALIAS ("REGION_RODATA", HIGH);
+REGION_ALIAS ("REGION_RODATA_LOAD", LOW);
+REGION_ALIAS ("REGION_FAST_DATA", HIGH);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", LOW);
+REGION_ALIAS ("REGION_DATA", HIGH);
+REGION_ALIAS ("REGION_DATA_LOAD", LOW);
+REGION_ALIAS ("REGION_BSS", HIGH);
+REGION_ALIAS ("REGION_RWEXTRA", HIGH);
+REGION_ALIAS ("REGION_WORK", HIGH);
+REGION_ALIAS ("REGION_STACK", HIGH);
+REGION_ALIAS ("REGION_NOCACHE", NOCACHE);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", LOW);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+bsp_section_robarrier_align = 0x1000000;
+bsp_section_rwbarrier_align = 0x1000000;
+qoriq = 0xffe000000;
+qoriq_bman_portal = 0xff4000000;
+qoriq_qman_portal = 0xff6000000;
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/qoriq/start/linkcmds.qoriq_e6500_64 b/bsps/powerpc/qoriq/start/linkcmds.qoriq_e6500_64
new file mode 100644
index 0000000000..a4969756ec
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/linkcmds.qoriq_e6500_64
@@ -0,0 +1 @@
+INCLUDE linkcmds.qoriq_e6500_32
diff --git a/bsps/powerpc/qoriq/start/mmu-config.c b/bsps/powerpc/qoriq/start/mmu-config.c
new file mode 100644
index 0000000000..b59d9c7114
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/mmu-config.c
@@ -0,0 +1,352 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQMMU
+ *
+ * @brief MMU implementation.
+ */
+
+/*
+ * Copyright (c) 2011, 2018 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/fdt.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/mmu.h>
+#include <bsp/qoriq.h>
+
+#include <sys/param.h>
+
+#include <libfdt.h>
+
+#include <rtems/config.h>
+
+#define TEXT __attribute__((section(".bsp_start_text")))
+#define DATA __attribute__((section(".bsp_start_data")))
+
+typedef struct {
+ uintptr_t begin;
+ uintptr_t size;
+ uint32_t mas2;
+ uint32_t mas3;
+ uint32_t mas7;
+} entry;
+
+#define ENTRY_X(b, s) { \
+ .begin = (uintptr_t) b, \
+ .size = (uintptr_t) s, \
+ .mas2 = 0, \
+ .mas3 = FSL_EIS_MAS3_SX \
+}
+
+#define ENTRY_R(b, s) { \
+ .begin = (uintptr_t) b, \
+ .size = (uintptr_t) s, \
+ .mas2 = 0, \
+ .mas3 = FSL_EIS_MAS3_SR \
+}
+
+#ifdef RTEMS_SMP
+ #define ENTRY_RW_MAS2 FSL_EIS_MAS2_M
+#else
+ #define ENTRY_RW_MAS2 0
+#endif
+
+#define ENTRY_RW(b, s) { \
+ .begin = (uintptr_t) b, \
+ .size = (uintptr_t) s, \
+ .mas2 = ENTRY_RW_MAS2, \
+ .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \
+}
+
+#define ENTRY_IO(b, s) { \
+ .begin = (uintptr_t) b, \
+ .size = (uintptr_t) s, \
+ .mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \
+ .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \
+}
+
+#define ENTRY_DEV(b, s) { \
+ .begin = (uintptr_t) b, \
+ .size = (uintptr_t) s, \
+ .mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \
+ .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \
+ .mas7 = QORIQ_MMU_DEVICE_MAS7 \
+}
+
+/*
+ * MMU entry for BMan and QMan software portals.
+ *
+ * The M bit must be set if stashing is used, see 3.3.8.6 DQRR Entry Stashing
+ * and 3.3.8 Software Portals in T4240DPAARM.
+ *
+ * The G bit must be set, otherwise ECC errors in the QMan software portals
+ * will occur. No documentation reference for this is available.
+ */
+#define ENTRY_DEV_CACHED(b, s) { \
+ .begin = (uintptr_t) b, \
+ .size = (uintptr_t) s, \
+ .mas2 = FSL_EIS_MAS2_M | FSL_EIS_MAS2_G, \
+ .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \
+ .mas7 = QORIQ_MMU_DEVICE_MAS7 \
+}
+
+#define WORKSPACE_ENTRY_INDEX 0
+
+static entry DATA config[] = {
+ /* Must be first entry, see WORKSPACE_ENTRY_INDEX */
+ ENTRY_RW(bsp_section_work_begin, bsp_section_work_size),
+
+ #if defined(RTEMS_MULTIPROCESSING) && \
+ defined(QORIQ_INTERCOM_AREA_BEGIN) && \
+ defined(QORIQ_INTERCOM_AREA_SIZE)
+ {
+ .begin = QORIQ_INTERCOM_AREA_BEGIN,
+ .size = QORIQ_INTERCOM_AREA_SIZE,
+ .mas2 = FSL_EIS_MAS2_M,
+ .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW
+ },
+ #endif
+ ENTRY_X(bsp_section_start_begin, bsp_section_start_size),
+ ENTRY_R(bsp_section_fast_text_load_begin, bsp_section_fast_text_size),
+ ENTRY_X(bsp_section_fast_text_begin, bsp_section_fast_text_size),
+ ENTRY_X(bsp_section_text_begin, bsp_section_text_size),
+ ENTRY_R(bsp_section_rodata_load_begin, bsp_section_rodata_size),
+ ENTRY_R(bsp_section_rodata_begin, bsp_section_rodata_size),
+ ENTRY_R(bsp_section_fast_data_load_begin, bsp_section_fast_data_size),
+ ENTRY_RW(bsp_section_fast_data_begin, bsp_section_fast_data_size),
+ ENTRY_R(bsp_section_data_load_begin, bsp_section_data_size),
+ ENTRY_RW(bsp_section_data_begin, bsp_section_data_size),
+ ENTRY_RW(bsp_section_sbss_begin, bsp_section_sbss_size),
+ ENTRY_RW(bsp_section_bss_begin, bsp_section_bss_size),
+ ENTRY_RW(bsp_section_rwextra_begin, bsp_section_rwextra_size),
+ ENTRY_RW(bsp_section_stack_begin, bsp_section_stack_size),
+ ENTRY_IO(bsp_section_nocache_begin, bsp_section_nocache_size),
+ ENTRY_IO(bsp_section_nocachenoload_begin, bsp_section_nocachenoload_size),
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
+#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
+ /* BMan Portals */
+ ENTRY_DEV_CACHED(&qoriq_bman_portal[0][0], sizeof(qoriq_bman_portal[0])),
+ ENTRY_DEV(&qoriq_bman_portal[1][0], sizeof(qoriq_bman_portal[1])),
+ /* QMan Portals */
+ ENTRY_DEV_CACHED(&qoriq_qman_portal[0][0], sizeof(qoriq_qman_portal[0])),
+ ENTRY_DEV(&qoriq_qman_portal[1][0], sizeof(qoriq_qman_portal[1])),
+#endif
+ ENTRY_DEV(&qoriq, sizeof(qoriq))
+#endif
+};
+
+static DATA char memory_path[] = "/memory";
+
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+static void TEXT add_dpaa_bqman_portals(
+ qoriq_mmu_context *context,
+ const void *fdt,
+ const char *compatible
+)
+{
+ int node;
+
+ node = -1;
+
+ while (true) {
+ const void *val;
+ int len;
+ uintptr_t paddr;
+ uintptr_t size;
+
+ node = fdt_node_offset_by_compatible(fdt, node, compatible);
+ if (node < 0) {
+ break;
+ }
+
+ val = fdt_getprop(fdt, node, "reg", &len);
+ if (len != 32) {
+ continue;
+ }
+
+ paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[0]);
+ size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[1]);
+
+ qoriq_mmu_add(
+ context,
+ paddr,
+ paddr + size - 1,
+ 0,
+ FSL_EIS_MAS2_M | FSL_EIS_MAS2_G,
+ FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
+ QORIQ_MMU_DEVICE_MAS7
+ );
+
+ paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[2]);
+ size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[3]);
+
+ qoriq_mmu_add(
+ context,
+ paddr,
+ paddr + size - 1,
+ 0,
+ FSL_EIS_MAS2_I | FSL_EIS_MAS2_G,
+ FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
+ QORIQ_MMU_DEVICE_MAS7
+ );
+ }
+}
+
+static void TEXT add_dpaa_bpool(qoriq_mmu_context *context, const void *fdt)
+{
+ int node;
+
+ node = -1;
+
+ while (true) {
+ const void *val;
+ int len;
+ uintptr_t config_count;
+ uintptr_t size;
+ uintptr_t paddr;
+
+ node = fdt_node_offset_by_compatible(fdt, node, "fsl,bpool");
+ if (node < 0) {
+ break;
+ }
+
+ val = fdt_getprop(fdt, node, "fsl,bpool-ethernet-cfg", &len);
+ if (len != 24) {
+ continue;
+ }
+
+ config_count = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[0]);
+ size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[1]);
+ paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[2]);
+
+ qoriq_mmu_add(
+ context,
+ paddr,
+ paddr + config_count * size - 1,
+ 0,
+ FSL_EIS_MAS2_M,
+ FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
+ 0
+ );
+ }
+}
+#endif
+
+static void TEXT config_fdt_adjust(const void *fdt)
+{
+ int node;
+
+ node = fdt_path_offset_namelen(
+ fdt,
+ memory_path,
+ (int) sizeof(memory_path) - 1
+ );
+
+ if (node >= 0) {
+ int len;
+ const void *val;
+ uint64_t mem_begin;
+ uint64_t mem_size;
+
+ val = fdt_getprop(fdt, node, "reg", &len);
+ if (len == 8) {
+ mem_begin = fdt32_to_cpu(((fdt32_t *) val)[0]);
+ mem_size = fdt32_to_cpu(((fdt32_t *) val)[1]);
+ } else if (len == 16) {
+ mem_begin = fdt64_to_cpu(((fdt64_t *) val)[0]);
+ mem_size = fdt64_to_cpu(((fdt64_t *) val)[1]);
+ } else {
+ mem_begin = 0;
+ mem_size = 0;
+ }
+
+#ifndef __powerpc64__
+ mem_size = MIN(mem_size, 0x80000000U);
+#endif
+
+ if (
+ mem_begin == 0
+ && mem_size > (uintptr_t) bsp_section_work_end
+ && (uintptr_t) bsp_section_nocache_end
+ < (uintptr_t) bsp_section_work_end
+ ) {
+ /* Assign new value to allow a bsp_restart() */
+ config[WORKSPACE_ENTRY_INDEX].size = (uintptr_t) mem_size
+ - (uintptr_t) bsp_section_work_begin;
+ }
+ }
+}
+
+void TEXT qoriq_mmu_config(bool boot_processor, int first_tlb, int scratch_tlb)
+{
+ qoriq_mmu_context context;
+ const void *fdt;
+ int max_count;
+ int i;
+
+ for (i = 0; i < QORIQ_TLB1_ENTRY_COUNT; ++i) {
+ if (i != scratch_tlb) {
+ qoriq_tlb1_invalidate(i);
+ }
+ }
+
+ fdt = bsp_fdt_get();
+ qoriq_mmu_context_init(&context);
+
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+ add_dpaa_bqman_portals(&context, fdt, "fsl,bman-portal");
+ add_dpaa_bqman_portals(&context, fdt, "fsl,qman-portal");
+ add_dpaa_bpool(&context, fdt);
+ max_count = QORIQ_TLB1_ENTRY_COUNT - 1;
+#else
+ max_count = (3 * QORIQ_TLB1_ENTRY_COUNT) / 4;
+#endif
+
+ if (boot_processor) {
+ config_fdt_adjust(fdt);
+ }
+
+ for (i = 0; i < (int) (sizeof(config) / sizeof(config [0])); ++i) {
+ const entry *cur = &config [i];
+ if (cur->size > 0) {
+ qoriq_mmu_add(
+ &context,
+ cur->begin,
+ cur->begin + cur->size - 1,
+ 0,
+ cur->mas2,
+ cur->mas3,
+ cur->mas7
+ );
+ }
+ }
+
+ qoriq_mmu_partition(&context, max_count);
+ qoriq_mmu_write_to_tlb1(&context, first_tlb);
+}
+
+void TEXT bsp_work_area_initialize(void)
+{
+ const entry *we = &config[WORKSPACE_ENTRY_INDEX];
+ uintptr_t begin = we->begin;
+ uintptr_t end = begin + we->size;
+
+#ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN
+ begin += rtems_configuration_get_interrupt_stack_size();
+#endif
+
+ bsp_work_area_initialize_default((void *) begin, end - begin);
+}
diff --git a/bsps/powerpc/qoriq/start/mmu-tlb1.S b/bsps/powerpc/qoriq/start/mmu-tlb1.S
new file mode 100644
index 0000000000..2dd06e2ed8
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/mmu-tlb1.S
@@ -0,0 +1,107 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQMMU
+ *
+ * @brief qoriq_tlb1_write() and qoriq_tlb1_invalidate() implementation.
+ */
+
+/*
+ * Copyright (c) 2011, 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 <bspopts.h>
+
+#include <libcpu/powerpc-utility.h>
+
+ .global qoriq_tlb1_write
+ .global qoriq_tlb1_invalidate
+ .global qoriq_tlb1_invalidate_all_by_ts
+
+ .section ".bsp_start_text", "ax"
+
+qoriq_tlb1_write:
+ rlwinm r3, r3, 16, 10, 15
+#ifdef __powerpc64__
+ rldicr r8, r8, 0, 51
+#else
+ rlwinm r8, r8, 0, 0, 19
+#endif
+ oris r3, r3, 0x1000
+ mtspr FSL_EIS_MAS0, r3
+ oris r4, r4, 0xc000
+ rlwinm r9, r9, 8, 20, 23
+ or r9, r4, r9
+ mtspr FSL_EIS_MAS1, r9
+ or r5, r8, r5
+ mtspr FSL_EIS_MAS2, r5
+ or r6, r8, r6
+ mtspr FSL_EIS_MAS3, r6
+#ifdef __powerpc64__
+ srdi r8, r8, 32
+ or r7, r7, r8
+ mtspr FSL_EIS_MAS7, r7
+#endif
+ mtspr FSL_EIS_MAS7, r7
+#if defined(QORIQ_HAS_HYPERVISOR_MODE) && !defined(QORIQ_IS_HYPERVISOR_GUEST)
+ li r0, 0
+ mtspr FSL_EIS_MAS8, r0
+#endif
+ isync
+ msync
+ tlbwe
+ isync
+ blr
+
+qoriq_tlb1_invalidate:
+ rlwinm r3, r3, 16, 10, 15
+ oris r3, r3, 0x1000
+ mtspr FSL_EIS_MAS0, r3
+ li r0, 0
+ mtspr FSL_EIS_MAS1, r0
+ mtspr FSL_EIS_MAS2, r0
+ mtspr FSL_EIS_MAS3, r0
+ mtspr FSL_EIS_MAS7, r0
+#if defined(QORIQ_HAS_HYPERVISOR_MODE) && !defined(QORIQ_IS_HYPERVISOR_GUEST)
+ mtspr FSL_EIS_MAS8, r0
+#endif
+ isync
+ msync
+ tlbwe
+ isync
+ blr
+
+/* r3 = 0 for TS0, 1 for TS1 */
+qoriq_tlb1_invalidate_all_by_ts:
+ mflr r12
+ li r11, QORIQ_TLB1_ENTRY_COUNT
+ mtctr r11
+ li r11, 0
+ mr r10, r3
+
+2:
+ rlwinm r0, r11, 16, 10, 15
+ oris r0, r0, (FSL_EIS_MAS0_TLBSEL >> 16)
+ mtspr FSL_EIS_MAS0, r0
+ tlbre
+ mfspr r0, FSL_EIS_MAS1
+ rlwinm r0, r0, 20, 31, 31
+ cmpw r0, r10
+ bne 1f
+ mr r3, r11
+ bl qoriq_tlb1_invalidate
+1:
+ addi r11, r11, 1
+ bdnz 2b
+ mtlr r12
+ blr
diff --git a/bsps/powerpc/qoriq/start/mmu.c b/bsps/powerpc/qoriq/start/mmu.c
new file mode 100644
index 0000000000..2629c9f999
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/mmu.c
@@ -0,0 +1,368 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQMMU
+ *
+ * @brief MMU implementation.
+ */
+
+/*
+ * Copyright (c) 2011, 2018 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/mmu.h>
+#include <libcpu/powerpc-utility.h>
+
+#define TEXT __attribute__((section(".bsp_start_text")))
+
+static uintptr_t TEXT power_of_two(uintptr_t val)
+{
+ uintptr_t test_power = QORIQ_MMU_MIN_POWER;
+ uintptr_t power = test_power;
+ uintptr_t alignment = 1U << test_power;
+
+ while (test_power <= QORIQ_MMU_MAX_POWER && (val & (alignment - 1)) == 0) {
+ power = test_power;
+ alignment <<= QORIQ_MMU_POWER_STEP;
+ test_power += QORIQ_MMU_POWER_STEP;
+ }
+
+ return power;
+}
+
+static uintptr_t TEXT max_power_of_two(uintptr_t val)
+{
+ uintptr_t test_power = QORIQ_MMU_MIN_POWER;
+ uintptr_t power = test_power;
+ uintptr_t max = 1U << test_power;
+
+ do {
+ power = test_power;
+ max <<= QORIQ_MMU_POWER_STEP;
+ test_power += QORIQ_MMU_POWER_STEP;
+ } while (test_power <= QORIQ_MMU_MAX_POWER && max <= val);
+
+ return power;
+}
+
+void TEXT qoriq_mmu_context_init(qoriq_mmu_context *self)
+{
+ int *cur = (int *) self;
+ const int *end = cur + sizeof(*self) / sizeof(*cur);
+
+ while (cur != end) {
+ *cur = 0;
+ ++cur;
+ }
+}
+
+static void TEXT sort(qoriq_mmu_context *self)
+{
+ qoriq_mmu_entry *entries = self->entries;
+ int n = self->count;
+ int i = 0;
+
+ for (i = 1; i < n; ++i) {
+ qoriq_mmu_entry key = entries [i];
+ int j = 0;
+
+ for (j = i - 1; j >= 0 && entries [j].begin > key.begin; --j) {
+ entries [j + 1] = entries [j];
+ }
+
+ entries [j + 1] = key;
+ }
+}
+
+static bool TEXT mas_compatible(const qoriq_mmu_entry *a, const qoriq_mmu_entry *b)
+{
+ uint32_t m = FSL_EIS_MAS2_M;
+
+ return (a->mas2 & ~m) == (b->mas2 & ~m);
+}
+
+static bool TEXT can_merge(const qoriq_mmu_entry *prev, const qoriq_mmu_entry *cur)
+{
+ return mas_compatible(prev, cur)
+ && (prev->begin == cur->begin || prev->last >= cur->begin - 1);
+}
+
+static void TEXT merge(qoriq_mmu_context *self)
+{
+ qoriq_mmu_entry *entries = self->entries;
+ int n = self->count;
+ int i = 0;
+
+ for (i = 1; i < n; ++i) {
+ qoriq_mmu_entry *prev = &entries [i - 1];
+ qoriq_mmu_entry *cur = &entries [i];
+
+ if (can_merge(prev, cur)) {
+ int j = 0;
+
+ prev->mas1 |= cur->mas1;
+ prev->mas2 |= cur->mas2;
+ prev->mas3 |= cur->mas3;
+
+ if (cur->last > prev->last) {
+ prev->last = cur->last;
+ }
+
+ for (j = i + 1; j < n; ++j) {
+ entries [j - 1] = entries [j];
+ }
+
+ --i;
+ --n;
+ }
+ }
+
+ self->count = n;
+}
+
+static void TEXT compact(qoriq_mmu_context *self)
+{
+ sort(self);
+ merge(self);
+}
+
+static bool TEXT can_expand_down(
+ const qoriq_mmu_context *self,
+ const qoriq_mmu_entry *cur,
+ int i,
+ uintptr_t new_begin
+)
+{
+ int j;
+
+ for (j = 0; j < i; ++j) {
+ const qoriq_mmu_entry *before = &self->entries[j];
+
+ if (
+ before->begin <= new_begin
+ && new_begin <= before->last
+ && !mas_compatible(before, cur)
+ ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool TEXT can_expand_up(
+ const qoriq_mmu_context *self,
+ const qoriq_mmu_entry *cur,
+ int i,
+ int n,
+ uintptr_t new_last
+)
+{
+ int j;
+
+ for (j = i + 1; j < n; ++j) {
+ const qoriq_mmu_entry *after = &self->entries[j];
+
+ if (
+ after->begin <= new_last
+ && new_last <= after->last
+ && !mas_compatible(after, cur)
+ ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void TEXT align(qoriq_mmu_context *self, uintptr_t alignment)
+{
+ int n = self->count;
+ int i;
+
+ for (i = 0; i < n; ++i) {
+ qoriq_mmu_entry *cur = &self->entries[i];
+ uintptr_t new_begin = cur->begin & ~(alignment - 1);
+ uintptr_t new_last = alignment + (cur->last & ~(alignment - 1)) - 1;
+
+ if (
+ can_expand_down(self, cur, i, new_begin)
+ && can_expand_up(self, cur, i, n, new_last)
+ ) {
+ cur->begin = new_begin;
+ cur->last = new_last;
+ }
+ }
+}
+
+static bool TEXT is_full(qoriq_mmu_context *self)
+{
+ return self->count >= QORIQ_TLB1_ENTRY_COUNT;
+}
+
+static void TEXT append(qoriq_mmu_context *self, const qoriq_mmu_entry *new_entry)
+{
+ self->entries [self->count] = *new_entry;
+ ++self->count;
+}
+
+bool TEXT qoriq_mmu_add(
+ qoriq_mmu_context *self,
+ uintptr_t begin,
+ uintptr_t last,
+ uint32_t mas1,
+ uint32_t mas2,
+ uint32_t mas3,
+ uint32_t mas7
+)
+{
+ bool ok = true;
+
+ if (is_full(self)) {
+ compact(self);
+ }
+
+ if (!is_full(self)) {
+ if (begin < last) {
+ qoriq_mmu_entry new_entry = {
+ .begin = begin,
+ .last = last,
+ .mas1 = mas1,
+ .mas2 = mas2,
+ .mas3 = mas3,
+ .mas7 = mas7
+ };
+ append(self, &new_entry);
+ } else {
+ ok = false;
+ }
+ } else {
+ ok = false;
+ }
+
+ return ok;
+}
+
+static uintptr_t TEXT min(uintptr_t a, uintptr_t b)
+{
+ return a < b ? a : b;
+}
+
+static bool TEXT split(qoriq_mmu_context *self, qoriq_mmu_entry *cur)
+{
+ bool again = false;
+ uintptr_t begin = cur->begin;
+ uintptr_t end = cur->last + 1;
+ uintptr_t size = end - begin;
+ uintptr_t begin_power = power_of_two(begin);
+ uintptr_t size_power = max_power_of_two(size);
+ uintptr_t power = min(begin_power, size_power);
+ uintptr_t split_size = power < 32 ? (1U << power) : 0;
+ uintptr_t split_pos = begin + split_size;
+
+ if (split_pos != end && !is_full(self)) {
+ qoriq_mmu_entry new_entry = *cur;
+ cur->begin = split_pos;
+ new_entry.last = split_pos - 1;
+ append(self, &new_entry);
+ again = true;
+ }
+
+ return again;
+}
+
+static void TEXT split_all(qoriq_mmu_context *self)
+{
+ qoriq_mmu_entry *entries = self->entries;
+ int n = self->count;
+ int i = 0;
+
+ for (i = 0; i < n; ++i) {
+ qoriq_mmu_entry *cur = &entries [i];
+
+ while (split(self, cur)) {
+ /* Repeat */
+ }
+ }
+}
+
+static TEXT void partition(qoriq_mmu_context *self)
+{
+ compact(self);
+ split_all(self);
+ sort(self);
+}
+
+void TEXT qoriq_mmu_partition(qoriq_mmu_context *self, int max_count)
+{
+ uintptr_t alignment = 4096;
+
+ sort(self);
+
+ do {
+ align(self, alignment);
+ partition(self);
+ alignment *= 4;
+ } while (self->count > max_count);
+}
+
+void TEXT qoriq_mmu_write_to_tlb1(qoriq_mmu_context *self, int first_tlb)
+{
+ qoriq_mmu_entry *entries = self->entries;
+ int n = self->count;
+ int i = 0;
+
+ for (i = 0; i < n; ++i) {
+ qoriq_mmu_entry *cur = &entries [i];
+ uintptr_t ea = cur->begin;
+ uintptr_t size = cur->last - ea + 1;
+ uintptr_t tsize = (power_of_two(size) - 10) / 2;
+ int tlb = first_tlb + i;
+
+ qoriq_tlb1_write(
+ tlb,
+ cur->mas1,
+ cur->mas2,
+ cur->mas3,
+ cur->mas7,
+ ea,
+ (int) tsize
+ );
+ }
+}
+
+void qoriq_mmu_change_perm(uint32_t test, uint32_t set, uint32_t clear)
+{
+ int i = 0;
+
+ for (i = 0; i < 16; ++i) {
+ uint32_t mas0 = FSL_EIS_MAS0_TLBSEL | FSL_EIS_MAS0_ESEL(i);
+ uint32_t mas1 = 0;
+
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS0, mas0);
+ asm volatile ("tlbre");
+
+ mas1 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS1);
+ if ((mas1 & FSL_EIS_MAS1_V) != 0) {
+ uint32_t mask = 0x3ff;
+ uint32_t mas3 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS3);
+
+ if ((mas3 & mask) == test) {
+ mas3 &= ~(clear & mask);
+ mas3 |= set & mask;
+ PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS3, mas3);
+ asm volatile ("isync; msync; tlbwe; isync" : : : "memory");
+ }
+ }
+ }
+}
diff --git a/bsps/powerpc/qoriq/start/portal.c b/bsps/powerpc/qoriq/start/portal.c
new file mode 100644
index 0000000000..f20eaf4d28
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/portal.c
@@ -0,0 +1,43 @@
+/*
+ * 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/qoriq.h>
+
+#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
+
+#include <libcpu/powerpc-utility.h>
+
+void qoriq_clear_ce_portal(void *base, size_t size)
+{
+ size_t offset;
+
+ for (offset = 0; offset < size; offset += 64) {
+ ppc_data_cache_block_clear_to_zero_2(base, offset);
+ ppc_data_cache_block_flush_2(base, offset);
+ }
+}
+
+void qoriq_clear_ci_portal(void *base, size_t size)
+{
+ uint32_t zero;
+ size_t offset;
+
+ zero = 0;
+
+ for (offset = 0; offset < size; offset += 4) {
+ ppc_write_word(zero, (char *) base + offset);
+ }
+}
+
+#endif
diff --git a/bsps/powerpc/qoriq/start/restart.S b/bsps/powerpc/qoriq/start/restart.S
new file mode 100644
index 0000000000..7dd9eb198d
--- /dev/null
+++ b/bsps/powerpc/qoriq/start/restart.S
@@ -0,0 +1,80 @@
+/*
+ * 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 <libcpu/powerpc-utility.h>
+
+#define FIRST_TLB 0
+
+#define SCRATCH_TLB QORIQ_TLB1_ENTRY_COUNT - 1
+
+ .global qoriq_restart_secondary_processor
+
+ .section ".bsp_start_text", "ax"
+
+qoriq_restart_secondary_processor:
+
+ mr r14, r3
+
+ /* Invalidate all TS1 MMU entries */
+ li r3, 1
+ bl qoriq_tlb1_invalidate_all_by_ts
+
+ /* Add TS1 entry for the first 4GiB of RAM */
+ li r3, SCRATCH_TLB
+ li r4, FSL_EIS_MAS1_TS
+ li r5, FSL_EIS_MAS2_I
+ li r6, FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW | FSL_EIS_MAS3_SX
+ li r7, 0
+ li r8, 0
+ li r9, 11
+ bl qoriq_tlb1_write
+
+ bl qoriq_l1cache_invalidate
+
+ /* Set MSR and use TS1 for address translation */
+ LWI r0, QORIQ_INITIAL_MSR | MSR_IS | MSR_DS
+ mtmsr r0
+ isync
+
+ /* Invalidate all TS0 MMU entries */
+ li r3, 0
+ bl qoriq_tlb1_invalidate_all_by_ts
+
+ /* Add TS0 entry for the first 4GiB of RAM */
+ li r3, FIRST_TLB
+ li r4, 0
+ li r5, FSL_EIS_MAS2_I
+ li r6, FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW | FSL_EIS_MAS3_SX
+ li r7, 0
+ li r8, 0
+ li r9, 11
+ bl qoriq_tlb1_write
+
+ /* Use TS0 for address translation */
+ LWI r0, QORIQ_INITIAL_MSR
+ mtmsr r0
+ isync
+
+ bl qoriq_l1cache_invalidate
+
+ /* Wait for restart request */
+ li r0, 0
+.Lrestartagain:
+ lwz r4, 4(r14)
+ cmpw r0, r4
+ beq .Lrestartagain
+ isync
+ mtctr r4
+ lwz r3, 12(r14)
+ bctr
diff --git a/bsps/powerpc/shared/start/bspgetworkarea.c b/bsps/powerpc/shared/start/bspgetworkarea.c
new file mode 100644
index 0000000000..3c86905020
--- /dev/null
+++ b/bsps/powerpc/shared/start/bspgetworkarea.c
@@ -0,0 +1,40 @@
+/*
+ * 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 <libcpu/powerpc-utility.h>
+
+#include <rtems/sysinit.h>
+
+LINKER_SYMBOL(__rtems_end)
+
+void bsp_work_area_initialize(void)
+{
+ /*
+ * Cannot do work area initialization before bsp_start(), since BSP_mem_size
+ * and MMU is not set up.
+ */
+}
+
+static void bsp_work_area_initialize_later(void)
+{
+ uintptr_t work_size;
+ uintptr_t work_area;
+
+ work_area = (uintptr_t)__rtems_end +
+ rtems_configuration_get_interrupt_stack_size();
+ work_size = (uintptr_t)BSP_mem_size - work_area;
+
+ bsp_work_area_initialize_default((void *) work_area, work_size);
+}
+
+RTEMS_SYSINIT_ITEM(
+ bsp_work_area_initialize_later,
+ RTEMS_SYSINIT_BSP_START,
+ RTEMS_SYSINIT_ORDER_LAST
+);
diff --git a/bsps/powerpc/shared/start/bspidle.c b/bsps/powerpc/shared/start/bspidle.c
new file mode 100644
index 0000000000..de37fa1ced
--- /dev/null
+++ b/bsps/powerpc/shared/start/bspidle.c
@@ -0,0 +1,36 @@
+/*
+ * Moved to libbsp/powerpc/shared by Joel Sherrill (9 Sept 09).
+ */
+
+/*
+ * The MPC860 specific stuff was written by Jay Monkman (jmonkman@frasca.com)
+ *
+ * Modified for the MPC8260ADS board by Andy Dachs <a.dachs@sstl.co.uk>
+ * Surrey Satellite Technology Limited, 2001
+ *
+ * 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>
+
+/**
+ * @brief BSP Idle thread body.
+ *
+ * The MSR[POW] bit is set to put the CPU into the low power mode
+ * defined in HID0. HID0 is set during starup in start.S.
+ */
+void *bsp_idle_thread( uintptr_t ignored )
+{
+ for( ; ; ) {
+ __asm__ volatile(
+ "mfmsr 3; oris 3,3,4; sync; mtmsr 3; isync; ori 3,3,0; ori 3,3,0"
+ );
+ }
+
+ return 0; /* to remove warning */
+}
diff --git a/bsps/powerpc/shared/start/linkcmds.base b/bsps/powerpc/shared/start/linkcmds.base
new file mode 100644
index 0000000000..e0dfdcc914
--- /dev/null
+++ b/bsps/powerpc/shared/start/linkcmds.base
@@ -0,0 +1,436 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_linker
+ *
+ * @brief Linker command base file.
+ */
+
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+ENTRY (_start)
+STARTUP (start.o)
+
+/*
+ * Global symbols that may be defined externally
+ */
+
+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;
+
+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_TEXT AT > REGION_TEXT
+
+ .text : ALIGN_WITH_INPUT {
+ bsp_section_text_begin = .;
+ *(SORT(.bsp_text*))
+ *(.text.unlikely .text.*_unlikely)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ *(.gnu.warning)
+ *(.sfpr .glink)
+ } > REGION_TEXT AT > REGION_TEXT_LOAD
+ .init : ALIGN_WITH_INPUT {
+ KEEP (*(.init))
+ } > REGION_TEXT AT > REGION_TEXT_LOAD
+ .fini : ALIGN_WITH_INPUT {
+ PROVIDE (_fini = .);
+ 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;
+
+ .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;
+
+ .robarrier : ALIGN_WITH_INPUT {
+ . = ALIGN (bsp_section_robarrier_align);
+ } > REGION_RODATA AT > REGION_RODATA
+
+ .rodata : ALIGN_WITH_INPUT {
+ bsp_section_rodata_begin = .;
+ *(SORT(.bsp_rodata*))
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .rodata1 : ALIGN_WITH_INPUT {
+ *(.rodata1)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .sdata2 : ALIGN_WITH_INPUT {
+ PROVIDE (_SDA2_BASE_ = 32768);
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .sbss2 : ALIGN_WITH_INPUT {
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .eh_frame_hdr : ALIGN_WITH_INPUT {
+ *(.eh_frame_hdr)
+ } > 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 (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .ctors : ALIGN_WITH_INPUT {
+ KEEP (*ecrti.o(.ctors))
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o *ecrtn.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .dtors : ALIGN_WITH_INPUT {
+ KEEP (*ecrti.o(.dtors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o *ecrtn.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .jcr : ALIGN_WITH_INPUT {
+ KEEP (*(.jcr))
+ } > 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
+ .fixup : ALIGN_WITH_INPUT {
+ *(.fixup)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .dynamic : ALIGN_WITH_INPUT {
+ *(.dynamic)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .opd : ALIGN_WITH_INPUT {
+ KEEP (*(.opd))
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .tm_clone_table : ALIGN_WITH_INPUT {
+ *(.tm_clone_table)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .toc1 : ALIGN_WITH_INPUT {
+ *(.toc1)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .branch_lt : ALIGN_WITH_INPUT {
+ *(.branch_lt)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .got1 : ALIGN_WITH_INPUT {
+ *(.got1)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .got2 : ALIGN_WITH_INPUT {
+ *(.got2)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .got : ALIGN_WITH_INPUT {
+ *(.got)
+ } > REGION_RODATA AT > REGION_RODATA_LOAD
+ .toc : ALIGN_WITH_INPUT {
+ *(.toc)
+ } > 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
+ .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
+ .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.got1)
+ *(.rela.got2)
+ *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
+ *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
+ *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
+ *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
+ *(.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
+ .rela.plt : ALIGN_WITH_INPUT {
+ *(.rela.plt)
+ } > 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
+
+ .fast_data : ALIGN_WITH_INPUT {
+ bsp_section_fast_data_begin = .;
+ *(SORT(.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 = .;
+ *(SORT(.bsp_data*))
+ *(.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.*)))
+ } > REGION_DATA AT > REGION_DATA_LOAD
+ .sdata : ALIGN_WITH_INPUT {
+ PROVIDE (_SDA_BASE_ = 32768);
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ 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;
+
+ .sbss : ALIGN_WITH_INPUT {
+ bsp_section_sbss_begin = .;
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ bsp_section_sbss_end = .;
+ } > REGION_DATA AT > REGION_DATA
+ bsp_section_sbss_size = bsp_section_sbss_end - bsp_section_sbss_begin;
+
+ .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;
+
+ .rwextra : ALIGN_WITH_INPUT {
+ bsp_section_rwextra_begin = .;
+ *(.bsp_rwextra)
+ bsp_section_rwextra_end = .;
+ } > REGION_RWEXTRA AT > REGION_RWEXTRA
+ bsp_section_rwextra_size = bsp_section_rwextra_end - bsp_section_rwextra_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;
+
+ .nvram (NOLOAD) : ALIGN_WITH_INPUT {
+ bsp_section_nvram_begin = .;
+ *(SORT_BY_ALIGNMENT (SORT_BY_NAME (.bsp_nvram*)))
+ bsp_section_nvram_end = .;
+ } > REGION_NVRAM AT > REGION_NVRAM
+ bsp_section_nvram_size = bsp_section_nvram_end - bsp_section_nvram_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_line.* .debug_line_end ) }
+ .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) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+ .PPC.EMB.apuinfo 0 : { *(.PPC.EMB.apuinfo) }
+ /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/powerpc/shared/start/linkcmds.share b/bsps/powerpc/shared/start/linkcmds.share
new file mode 100644
index 0000000000..59f538e3a2
--- /dev/null
+++ b/bsps/powerpc/shared/start/linkcmds.share
@@ -0,0 +1,296 @@
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
+ "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+PROVIDE (__stack = 0);
+MEMORY {
+ VECTORS : ORIGIN = 0x0 , LENGTH = 0x3000
+ CODE : ORIGIN = 0x3000 , LENGTH = 32M - 0x3000
+}
+SECTIONS
+{
+ .entry_point_section :
+ {
+ KEEP(*(.entry_point_section))
+ } > VECTORS
+
+ /*
+ * This section is used only if NO_DYNAMIC_EXCEPTION_VECTOR_INSTALL
+ * is defined in vectors/vectors.S
+ */
+ .vectors :
+ {
+ *(.vectors)
+ } > VECTORS
+
+ /* Read-only sections, merged into text segment: */
+ .interp : { *(.interp) } > CODE
+ .hash : { *(.hash) } > CODE
+ .dynsym : { *(.dynsym) } > CODE
+ .dynstr : { *(.dynstr) } > CODE
+ .gnu.version : { *(.gnu.version) } > CODE
+ .gnu.version_d : { *(.gnu.version_d) } > CODE
+ .gnu.version_r : { *(.gnu.version_r) } > CODE
+ .rela.text :
+ { *(.rela.text) *(.rela.gnu.linkonce.t*) } > CODE
+ .rela.data :
+ { *(.rela.data) *(.rela.gnu.linkonce.d*) } > CODE
+ .rela.rodata :
+ { *(.rela.rodata*) *(.rela.gnu.linkonce.r*) } > CODE
+ .rela.got : { *(.rela.got) } > CODE
+ .rela.got1 : { *(.rela.got1) } > CODE
+ .rela.got2 : { *(.rela.got2) } > CODE
+ .rela.ctors : { *(.rela.ctors) } > CODE
+ .rela.dtors : { *(.rela.dtors) } > CODE
+ .rela.init : { *(.rela.init) } > CODE
+ .rela.fini : { *(.rela.fini) } > CODE
+ .rela.bss : { *(.rela.bss) } > CODE
+ .rela.plt : { *(.rela.plt) } > CODE
+ .rela.sdata : { *(.rela.sdata) } > CODE
+ .rela.sbss : { *(.rela.sbss) } > CODE
+ .rela.sdata2 : { *(.rela.sdata2) } > CODE
+ .rela.sbss2 : { *(.rela.sbss2) } > CODE
+ .rela.dyn : { *(.rela.dyn) } > CODE
+
+ .init : { KEEP(*(.init)) } > CODE
+
+ .text :
+ {
+ *(.text*)
+
+ /*
+ * Special FreeBSD sysctl sections.
+ */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } > CODE
+
+ .fini : { _fini = .; KEEP(*(.fini)) } > CODE
+
+ .rodata : { *(.rodata*) KEEP (*(SORT(.rtemsroset.*))) *(.gnu.linkonce.r*) } > CODE
+ .rodata1 : { *(.rodata1) } > CODE
+
+ .tdata : {
+ _TLS_Data_begin = .;
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ _TLS_Data_end = .;
+ } >CODE
+
+ .tbss : {
+ _TLS_BSS_begin = .;
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ _TLS_BSS_end = .;
+ } >CODE
+
+ _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));
+
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN(0x10000) + (. & (0x10000 - 1));
+ /* Ensure the __preinit_array_start label is properly aligned. We
+ could instead move the label definition inside the section, but
+ the linker would then create the section even if it turns out to
+ be empty, which isn't pretty. */
+ . = ALIGN(32 / 8);
+ PROVIDE (__preinit_array_start = .);
+ .preinit_array : { *(.preinit_array) } >CODE
+ PROVIDE (__preinit_array_end = .);
+ PROVIDE (__init_array_start = .);
+ .init_array : { *(.init_array) } >CODE
+ PROVIDE (__init_array_end = .);
+ PROVIDE (__fini_array_start = .);
+ .fini_array : { *(.fini_array) } >CODE
+ PROVIDE (__fini_array_end = .);
+
+ .sdata2 : {PROVIDE (_SDA2_BASE_ = 32768); *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } >CODE
+ .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ /* avoid empty sdata2/sbss2 area -- __eabi would not set up r2
+ * which may be important if run-time loading is used
+ */
+ . += 1;
+ PROVIDE (__SBSS2_END__ = .);
+ } >CODE
+ .eh_frame : { *(.eh_frame) } >CODE
+
+ /* NOTE: if the BSP uses page tables, the correctness of
+ * '_etext' (and __DATA_START__) is CRUCIAL - otherwise,
+ * an invalid mapping may result!!!
+ */
+ _etext = .;
+ PROVIDE (etext = .);
+
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ . = ALIGN(0x40000) + (ALIGN(8) & (0x40000 - 1));
+ The current expression does not correctly handle the case of a
+ text segment ending precisely at the end of a page; it causes the
+ data segment to skip a page. The above expression does not have
+ this problem, but it will currently (2/95) cause BFD to allocate
+ a single segment, combining both text and data, for this case.
+ This will prevent the text segment from being shared among
+ multiple executions of the program; I think that is more
+ important than losing a page of the virtual address space (note
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ . = ALIGN(0x1000);
+ .data ALIGN(0x1000) :
+ {
+ /* NOTE: if the BSP uses page tables, the correctness of
+ * '__DATA_START__' (and _etext) is CRUCIAL - otherwise,
+ * an invalid mapping may result!!!
+ */
+ PROVIDE(__DATA_START__ = ABSOLUTE(.) );
+ *(.data .data.* .gnu.linkonce.d*)
+ KEEP (*(SORT(.rtemsrwset.*)))
+ SORT(CONSTRUCTORS)
+ } > CODE
+ .data1 : { *(.data1) } > CODE
+ PROVIDE (__EXCEPT_START__ = .);
+ .gcc_except_table : { *(.gcc_except_table*) } > CODE
+ PROVIDE (__EXCEPT_END__ = .);
+ .got1 : { *(.got1) } > CODE
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ get relocated with -mrelocatable. Also put in the .fixup pointers.
+ The current compiler no longer needs this, but keep it around for 2.7.2 */
+ PROVIDE (_GOT2_START_ = .);
+ .got2 : { *(.got2) } > CODE
+ .dynamic : { *(.dynamic) } > CODE
+
+ .ctors :
+ {
+ /* 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))
+ /* We don't want to include the .ctor section from
+ 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 ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } > CODE
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } > CODE
+
+
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) } > CODE
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (_GOT2_END_ = .);
+ PROVIDE (_GOT_START_ = .);
+
+ .got : { *(.got) } > CODE
+ .got.plt : { *(.got.plt) } > CODE
+
+ PROVIDE (_GOT_END_ = .);
+
+ .jcr : { KEEP (*(.jcr)) } > CODE
+
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { PROVIDE (_SDA_BASE_ = 32768); *(.sdata*) *(.gnu.linkonce.s.*) } >CODE
+ _edata = .;
+ PROVIDE (edata = .);
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ *(.dynsbss)
+ *(.sbss* .gnu.linkonce.sb.*)
+ *(.scommon)
+ /* avoid empty sdata/sbss area -- __eabi would not set up r13
+ * which may be important if run-time loading is used
+ */
+ . += 1;
+ PROVIDE (__SBSS_END__ = .);
+ PROVIDE (__sbss_end = .);
+ } > CODE
+ .plt : { *(.plt) } > CODE
+ .bss :
+ {
+ PROVIDE (__bss_start = .);
+ *(.dynbss)
+ *(.bss .bss* .gnu.linkonce.b*)
+ *(COMMON)
+ . = ALIGN(16);
+ PROVIDE (__bss_end = .);
+ } > CODE
+ . = ALIGN(16);
+ . += 0x1000;
+ __stack = .;
+ _end = . ;
+ __rtems_end = . ;
+ PROVIDE (end = .);
+ /DISCARD/ :
+ {
+ *(.comment)
+ }
+
+
+ /* 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) }
+ .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) }
+ /* These must appear regardless of . */
+}
diff --git a/bsps/powerpc/shared/start/pgtbl_activate.c b/bsps/powerpc/shared/start/pgtbl_activate.c
new file mode 100644
index 0000000000..2455f1e06d
--- /dev/null
+++ b/bsps/powerpc/shared/start/pgtbl_activate.c
@@ -0,0 +1,77 @@
+#include <rtems.h>
+#include <libcpu/pte121.h>
+#include <libcpu/bat.h>
+
+/* Default activation of the page tables. This is a weak
+ * alias, so applications may easily override this
+ * default activation procedure.
+ */
+
+/*
+ * Authorship
+ * ----------
+ * This software was created by
+ * Till Straumann <strauman@slac.stanford.edu>, 4/2002,
+ * Stanford Linear Accelerator Center, Stanford University.
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ * the Stanford Linear Accelerator Center, Stanford University,
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software. Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+
+void __BSP_default_pgtbl_activate(Triv121PgTbl pt);
+void
+BSP_pgtbl_activate(Triv121PgTbl)
+ __attribute__ (( weak, alias("__BSP_default_pgtbl_activate") ));
+
+void
+__BSP_default_pgtbl_activate(Triv121PgTbl pt)
+{
+ if (!pt) return;
+
+ /* switch the text/ro sements to RO only after
+ * initializing the interrupts because the irq_mng
+ * installs some code...
+ *
+ * activate the page table; it is still masked by the
+ * DBAT0, however
+ */
+ triv121PgTblActivate(pt);
+
+ /* finally, switch off DBAT0 */
+ setdbat(0,0,0,0,0);
+ /* At this point, DBAT0 is available for other use... */
+}
diff --git a/bsps/powerpc/shared/start/pgtbl_setup.c b/bsps/powerpc/shared/start/pgtbl_setup.c
new file mode 100644
index 0000000000..8a8407bd49
--- /dev/null
+++ b/bsps/powerpc/shared/start/pgtbl_setup.c
@@ -0,0 +1,135 @@
+#include <rtems.h>
+#include <libcpu/mmu.h>
+#include <rtems/bspIo.h>
+#include <libcpu/pte121.h>
+
+/* Default setup of the page tables. This is a weak
+ * alias, so applications may easily override this
+ * default setup.
+ *
+ * NOTE: while it is possible to change the individual
+ * mappings, the page table itself MUST be
+ * allocated at the top of the physical memory!
+ * bspstart.c RELIES on this.
+ * Also, the 'setup' routine must reduce
+ * *pmemsize by the size of the page table.
+ */
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+
+/*
+ * Authorship
+ * ----------
+ * This software was created by
+ * Till Straumann <strauman@slac.stanford.edu>, 4/2002,
+ * Stanford Linear Accelerator Center, Stanford University.
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ * the Stanford Linear Accelerator Center, Stanford University,
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software. Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+
+Triv121PgTbl __BSP_default_pgtbl_setup(unsigned int *pmemsize);
+Triv121PgTbl BSP_pgtbl_setup(unsigned int *)
+ __attribute__ (( weak, alias("__BSP_default_pgtbl_setup") ));
+
+/* get those from the linker script.
+ * NOTE THAT THE CORRECTNESS OF THE LINKER SCRIPT IS CRUCIAL
+ */
+extern unsigned long __DATA_START__[], _etext[];
+
+Triv121PgTbl
+__BSP_default_pgtbl_setup(unsigned int *pmemsize)
+{
+Triv121PgTbl pt;
+unsigned ldPtSize,tmp;
+
+ /* Allocate a page table large enough to map
+ * the entire physical memory. We put the page
+ * table at the top of the physical memory.
+ */
+
+ /* get minimal size (log base 2) of PT for
+ * this board's memory
+ */
+ ldPtSize = triv121PgTblLdMinSize(*pmemsize);
+ ldPtSize++; /* double this amount -- then why? */
+
+ /* allocate the page table at the top of the physical
+ * memory - THIS IS NOT AN OPTION - bspstart.c RELIES
+ * ON THIS LAYOUT! (the size, however may be changed)
+ */
+ if ( (pt = triv121PgTblInit(*pmemsize - (1<<ldPtSize), ldPtSize)) ) {
+ /* map text and RO data read-only */
+ tmp = triv121PgTblMap(
+ pt,
+ TRIV121_121_VSID,
+ 0,
+ (PAGE_ALIGN((unsigned long)_etext) - 0) >> PG_SHIFT,
+ 0, /* WIMG */
+ TRIV121_PP_RO_PAGE);
+ if (TRIV121_MAP_SUCCESS != tmp) {
+ printk("Unable to map page index %i; reverting to BAT0\n",
+ tmp);
+ pt = 0;
+ } else {
+ /* map the rest (without the page table itself) RW */
+ tmp = triv121PgTblMap(
+ pt,
+ TRIV121_121_VSID,
+ (unsigned long)__DATA_START__,
+ (*pmemsize - (1<<ldPtSize) - (unsigned long)__DATA_START__ )>> PG_SHIFT,
+ 0, /* WIMG */
+ TRIV121_PP_RW_PAGE);
+ if (TRIV121_MAP_SUCCESS != tmp) {
+ printk("Unable to map page index %i; reverting to BAT0\n",
+ tmp);
+ pt = 0;
+ }
+ }
+ } else {
+ printk("WARNING: unable to allocate page table, keeping DBAT0\n");
+ }
+ if (pt) {
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Setting up page table mappings; protecting text/read-only data from write access\n");
+#endif
+ /* SUCCESS; reduce available memory by size of the page table */
+ *pmemsize -= (1<<ldPtSize);
+ }
+ return pt;
+}
diff --git a/bsps/powerpc/shared/start/ppc_idle.c b/bsps/powerpc/shared/start/ppc_idle.c
new file mode 100644
index 0000000000..44ae87311c
--- /dev/null
+++ b/bsps/powerpc/shared/start/ppc_idle.c
@@ -0,0 +1,106 @@
+/*
+ * ppc_idle.c
+ *
+ * Authorship
+ * ----------
+ * This software was created by
+ * Till Straumann <strauman@slac.stanford.edu>, 2010,
+ * Stanford Linear Accelerator Center, Stanford University.
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ * the Stanford Linear Accelerator Center, Stanford University,
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software. Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+#include <bsp.h>
+#include <stdint.h>
+
+#ifdef BSP_IDLE_TASK_BODY
+
+/* Provide an idle-task body which switches the
+ * CPU into power-save mode when idle. Any exception
+ * (including an interrupt/external-exception)
+ * wakes it up.
+ *
+ * IIRC - this cannot be used on real hardware due
+ * to errata on many chips which is a real
+ * pity. However, when used under qemu it
+ * saves host-CPU cycles.
+ * While qemu-0.12.4 needed to be patched
+ * (would otherwise hang because an exception
+ * didn't clear MSR_POW) qemu-0.14.1 seems
+ * to work fine.
+ */
+
+#include <rtems/powerpc/registers.h>
+#include <libcpu/cpuIdent.h>
+#include <libcpu/spr.h>
+
+SPR_RW(HID0)
+
+void *
+bsp_ppc_idle_task_body(uintptr_t ignored)
+{
+uint32_t msr;
+
+ switch ( current_ppc_cpu ) {
+
+ case PPC_7400:
+ case PPC_7455:
+ case PPC_7457:
+ /* Must enable NAP mode in HID0 for MSR_POW to work */
+ _write_HID0( _read_HID0() | HID0_NAP );
+ break;
+
+ default:
+ break;
+ }
+
+ for ( ;; ) {
+ _CPU_MSR_GET(msr);
+ msr |= MSR_POW;
+ asm volatile(
+ "1: sync \n"
+ " mtmsr %0 \n"
+ " isync \n"
+ " b 1b \n"
+ ::"r"(msr)
+ );
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/bsps/powerpc/shared/start/probeMemEnd.c b/bsps/powerpc/shared/start/probeMemEnd.c
new file mode 100644
index 0000000000..73b85d4709
--- /dev/null
+++ b/bsps/powerpc/shared/start/probeMemEnd.c
@@ -0,0 +1,219 @@
+/*
+ * Authorship
+ * ----------
+ * This software was created by
+ * Till Straumann <strauman@slac.stanford.edu>, 2005,
+ * Stanford Linear Accelerator Center, Stanford University.
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ * the Stanford Linear Accelerator Center, Stanford University,
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software. Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+
+#include <bsp.h>
+#include <libcpu/spr.h>
+#include <libcpu/cpuIdent.h>
+#include <rtems/bspIo.h>
+#include <inttypes.h>
+
+/* Simple memory probing routine
+ *
+ * - call from MMU-disabled section to avoid having to
+ * set up mappings.
+ * NOTE: this implies WIMG = 0011
+ * - call AFTER image is at its destination and PRIOR
+ * to setting up the heap or using any memory beyond
+ * __rtems_end, i.e., the probing algorithm may safely
+ * tamper with memory > __rtems_end.
+ * - MUST lock caches since we're gonna hit space with
+ * no memory attached.
+ *
+ * ASSUMPTIONS:
+ * o image occupies addresses between 0..__rtems_end
+ * o memory size is a multiple of 1<<LD_MEM_PROBE_STEP
+ *
+ * CAVEATS:
+ * o all caches must be disabled or locked (some
+ * boards really don't like it if you try to
+ * cache physical addresses with nothing attached)
+ * and this is highly CPU dependent :-(...
+ *
+ * - RETURNS size of memory detected in bytes or 0 on
+ * error.
+ */
+
+/* declare as an array so the compiler doesn't generate
+ * a reloc to .sdata & friends
+ */
+extern uint32_t __rtems_end[];
+
+#ifndef LD_MEM_PROBE_STEP
+#define LD_MEM_PROBE_STEP (24) /* 16MB */
+#endif
+
+#define TAG 0xfeedcafe
+
+#define __DO_ALIGN(a, s) (((uint32_t)(a) + (s)-1) & ~((s)-1))
+#define __ALIGN(a) __DO_ALIGN(a, (1<<LD_MEM_PROBE_STEP))
+
+#define SWITCH_MSR(msr) \
+ do { \
+ register uint32_t __rr; \
+ asm volatile( \
+ " mtsrr1 %0 \n" \
+ " bl 1f \n" \
+ "1: mflr %0 \n" \
+ " addi %0, %0, 1f-1b \n"\
+ " mtsrr0 %0 \n" \
+ " sync \n" \
+ " rfi \n" \
+ "1: \n" \
+ :"=b&"(__rr) \
+ :"0"(msr) \
+ :"lr","memory" \
+ ); \
+ } while (0)
+
+SPR_RW(L2CR)
+SPR_RW(L3CR)
+SPR_RO(PPC_PVR)
+SPR_RW(HID0)
+
+
+/* Shouldn't matter if the caches are enabled or not... */
+
+/* FIXME: This should go into libcpu, really... */
+static int
+CPU_lockUnlockCaches(register int doLock)
+{
+register uint32_t v, x;
+ if ( _read_MSR() & MSR_VE ) {
+#define DSSALL 0x7e00066c /* dssall opcode */
+ __asm__ volatile(" .long %0"::"i"(DSSALL));
+#undef DSSALL
+ }
+ asm volatile("sync");
+ switch ( _read_PPC_PVR()>>16 ) {
+ default: printk(__FILE__" CPU_lockUnlockCaches(): unknown CPU (PVR = 0x%08" PRIx32 ")\n",_read_PPC_PVR());
+ return -1;
+ case PPC_750: printk("CPU_lockUnlockCaches(): Can't lock L2 on a mpc750, sorry :-(\n");
+ return -2; /* cannot lock L2 :-( */
+ case PPC_7455:
+ case PPC_7457:
+ v = _read_L3CR();
+ x = 1<<(31-9);
+ v = doLock ? v | x : v & ~x;
+ _write_L3CR(v);
+
+ v = _read_L2CR();
+ x = 1<<(31-11);
+ v = doLock ? v | x : v & ~x;
+ _write_L2CR(v);
+ break;
+
+ case PPC_7400:
+ v = _read_L2CR();
+ x = 1<<(31-21);
+ v = doLock ? v | x : v & ~x;
+ _write_L2CR(v);
+ break;
+ case PPC_603:
+ case PPC_604:
+ case PPC_604e:
+ break;
+ }
+
+ v = _read_HID0();
+ x = 1<<(31-19);
+ v = doLock ? v | x : v & ~x;
+ _write_HID0(v);
+ asm volatile("sync":::"memory");
+ return 0;
+}
+
+uint32_t
+probeMemoryEnd(void)
+{
+register volatile uint32_t *probe;
+register uint32_t scratch;
+register uint32_t tag = TAG;
+register uint32_t flags;
+
+ probe = (volatile uint32_t *)__ALIGN(__rtems_end);
+
+ /* Start with some checks. We avoid using any services
+ * such as 'printk' so we can run at a very early stage.
+ * Also, we *try* to avoid to really rely on the memory
+ * being unused by restoring the probed locations and
+ * keeping everything in registers. Hence we could
+ * even probe our own stack :-)
+ */
+
+ if ( CPU_lockUnlockCaches(1) )
+ return 0;
+
+ _CPU_MSR_GET(flags);
+
+ SWITCH_MSR( flags & ~(MSR_EE|MSR_DR|MSR_IR) );
+
+ for ( ; (uint32_t)probe ; probe += (1<<LD_MEM_PROBE_STEP)/sizeof(*probe) ) {
+
+ /* see if by chance our tag is already there */
+ if ( tag == (scratch = *probe) ) {
+ /* try another tag */
+ tag = ~tag;
+ }
+ *probe = tag;
+
+ /* make sure it's written out */
+ asm volatile ("sync":::"memory");
+
+ /* try to read back */
+ if ( tag != *probe ) {
+ break;
+ }
+ /* restore */
+ *probe = scratch;
+ /* make sure the icache is not contaminated */
+ asm volatile ("sync; icbi 0, %0"::"r"(probe):"memory");
+ }
+
+ SWITCH_MSR(flags);
+
+ CPU_lockUnlockCaches(0);
+
+ return (uint32_t) probe;
+}
diff --git a/bsps/powerpc/shared/start/sbrk.c b/bsps/powerpc/shared/start/sbrk.c
new file mode 100644
index 0000000000..f17a1511e4
--- /dev/null
+++ b/bsps/powerpc/shared/start/sbrk.c
@@ -0,0 +1,147 @@
+/*
+ * sbrk.c
+ *
+ * Authorship
+ * ----------
+ * This software was created by
+ * Till Straumann <strauman@slac.stanford.edu>, 2002,
+ * Stanford Linear Accelerator Center, Stanford University.
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ * the Stanford Linear Accelerator Center, Stanford University,
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software. Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+
+/*
+ * Hack around the 32bit powerpc 32M problem:
+ *
+ * GCC by default uses relative branches which can not jump
+ * farther than 32M. Hence all program text is confined to
+ * a single 32M segment.
+ * This hack gives the RTEMS malloc region all memory below
+ * 32M at startup. Only when this region is exhausted will sbrk
+ * add more memory. Loading modules may fail at that point, hence
+ * the user is expected to load all modules at startup _prior_
+ * to malloc()ing lots of memory...
+ *
+ * NOTE: it would probably be better to have a separate region
+ * for module code.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <bsp/bootcard.h>
+
+#define INVALID_REMAINING_START ((uintptr_t) -1)
+
+static uintptr_t remaining_start = INVALID_REMAINING_START;
+static uintptr_t remaining_size = 0;
+
+/* App. may provide a value by defining the BSP_sbrk_policy
+ * variable.
+ *
+ * (-1) -> give all memory to the heap at initialization time
+ * > 0 -> value used as sbrk amount; initially give 32M
+ * 0 -> limit memory effectively to 32M.
+ *
+ */
+extern uintptr_t BSP_sbrk_policy[] __attribute__((weak));
+
+#define LIMIT_32M 0x02000000
+
+ptrdiff_t bsp_sbrk_init(Heap_Area *area, uintptr_t min_size)
+{
+ uintptr_t rval = 0;
+ uintptr_t policy;
+ uintptr_t remaining_end;
+
+ remaining_start = (uintptr_t) area->begin;
+ remaining_size = area->size;
+ remaining_end = remaining_start + remaining_size;
+
+ if (remaining_start < LIMIT_32M &&
+ remaining_end > LIMIT_32M &&
+ min_size <= LIMIT_32M - remaining_start) {
+ /* clip at LIMIT_32M */
+ rval = remaining_end - LIMIT_32M;
+ area->size = LIMIT_32M - remaining_start;
+ remaining_start = LIMIT_32M;
+ remaining_size = rval;
+ }
+
+ policy = (0 == BSP_sbrk_policy[0] ? (uintptr_t)(-1) : BSP_sbrk_policy[0]);
+ switch ( policy ) {
+ case (uintptr_t)(-1):
+ area->size += rval;
+ remaining_start = (uintptr_t) area->begin + area->size;
+ remaining_size = 0;
+ break;
+
+ case 0:
+ remaining_size = 0;
+ break;
+
+ default:
+ if ( rval > policy )
+ rval = policy;
+ break;
+ }
+
+ return (ptrdiff_t) (rval <= PTRDIFF_MAX ? rval : rval / 2);
+}
+
+/*
+ * This is just so the sbrk test can force its magic. All normal applications
+ * should just use the default implementation in this file.
+ */
+void *sbrk(ptrdiff_t incr) __attribute__ (( weak, alias("bsp_sbrk") ));
+static void *bsp_sbrk(ptrdiff_t incr)
+{
+ void *rval=(void*)-1;
+
+ if ( remaining_start != INVALID_REMAINING_START && incr <= remaining_size) {
+ remaining_size-=incr;
+ rval = (void *) remaining_start;
+ remaining_start += incr;
+ } else {
+ errno = ENOMEM;
+ }
+ #ifdef DEBUG
+ printk("************* SBRK 0x%08x (ret 0x%08x) **********\n", incr, rval);
+ #endif
+ return rval;
+}
diff --git a/bsps/powerpc/shared/start/zerobss.c b/bsps/powerpc/shared/start/zerobss.c
new file mode 100644
index 0000000000..b3ab1ad9d9
--- /dev/null
+++ b/bsps/powerpc/shared/start/zerobss.c
@@ -0,0 +1,42 @@
+/*
+ * zero the various bss areas.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * 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.
+ *
+ * Modified to support the MCP750.
+ * Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ */
+
+#include <string.h>
+#include <bsp.h>
+
+/* prevent these from being accessed in the short data areas */
+extern unsigned long __bss_start[], __SBSS_START__[], __SBSS_END__[];
+extern unsigned long __SBSS2_START__[], __SBSS2_END__[];
+extern unsigned long __bss_end[];
+
+void zero_bss(void)
+{
+ memset(
+ __SBSS_START__,
+ 0,
+ ((unsigned) __SBSS_END__) - ((unsigned)__SBSS_START__)
+ );
+ memset(
+ __SBSS2_START__,
+ 0,
+ ((unsigned) __SBSS2_END__) - ((unsigned)__SBSS2_START__)
+ );
+ memset(
+ __bss_start,
+ 0,
+ ((unsigned) __bss_end) - ((unsigned)__bss_start)
+ );
+}
diff --git a/bsps/powerpc/ss555/start/bsp_specs b/bsps/powerpc/ss555/start/bsp_specs
new file mode 100644
index 0000000000..2625609327
--- /dev/null
+++ b/bsps/powerpc/ss555/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/ss555/start/bspstart.c b/bsps/powerpc/ss555/start/bspstart.c
new file mode 100644
index 0000000000..f47ca7d5be
--- /dev/null
+++ b/bsps/powerpc/ss555/start/bspstart.c
@@ -0,0 +1,97 @@
+/*
+ * This routine does the bulk of the system initialization.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * 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.
+ *
+ * SS555 port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from c/src/lib/libbsp/powerpc/mbx8xx/startup/bspstart.c:
+ *
+ * Modifications for MBX860:
+ * Copyright (c) 1999, National Research Council of Canada
+ */
+
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+#include <bsp/bootcard.h>
+#include <rtems/powerpc/powerpc.h>
+
+#include <libcpu/cpuIdent.h>
+#include <libcpu/spr.h>
+
+#include <bsp/irq.h>
+#include <bsp.h>
+
+SPR_RW(SPRG1)
+
+extern unsigned long intrStackPtr;
+
+/*
+ * Driver configuration parameters
+ */
+uint32_t bsp_clicks_per_usec;
+uint32_t bsp_clock_speed; /* Serial clocks per second */
+
+/*
+ * bsp_start()
+ *
+ * Board-specific initialization code. Called from the generic boot_card()
+ * function defined in rtems/c/src/lib/libbsp/shared/main.c. That function
+ * does some of the board independent initialization. It is called from the
+ * SS555 entry point _start() defined in
+ * rtems/c/src/lib/libbsp/powerpc/ss555/start/start.S
+ *
+ * _start() has set up a stack, has zeroed the .bss section, has set up the
+ * .data section from contents stored in ROM, has turned off interrupts,
+ * and placed the processor in the supervisor mode. boot_card() has left
+ * the processor in that state when bsp_start() was called.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void bsp_start(void)
+{
+ register unsigned char* intrStack;
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function stores the result in global variables so that it can be used
+ * later.
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ /*
+ * Initialize some SPRG registers related to irq handling
+ */
+ intrStack = (((unsigned char*)&intrStackPtr) - PPC_MINIMUM_STACK_FRAME_SIZE);
+ _write_SPRG1((unsigned int)intrStack);
+
+ /*
+ * Install our own set of exception vectors
+ */
+ initialize_exceptions();
+
+ /*
+ * initialize the device driver parameters
+ */
+ bsp_clicks_per_usec = BSP_CRYSTAL_HZ / 4 / 1000000;
+ bsp_clock_speed = BSP_CLOCK_HZ; /* for SCI baud rate generator */
+ rtems_counter_initialize_converter(BSP_CRYSTAL_HZ / 4);
+
+ /*
+ * Initalize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mng_init(0);
+}
diff --git a/bsps/powerpc/ss555/start/iss555.c b/bsps/powerpc/ss555/start/iss555.c
new file mode 100644
index 0000000000..034ae74b1d
--- /dev/null
+++ b/bsps/powerpc/ss555/start/iss555.c
@@ -0,0 +1,148 @@
+/*
+ * Intec SS555 initialization routines.
+ */
+
+/*
+ * SS555 port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from c/src/lib/libbsp/powerpc/mbx8xx/startup/imbx8xx.c:
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * 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>
+
+SPR_RW(ICTRL);
+SPR_RW(PPC_DEC);
+SPR_RW(TBWU);
+SPR_RW(TBWL);
+SPR_RO(IMMR);
+SPR_RW(MI_GRA);
+SPR_RW(L2U_GRA);
+SPR_RW(BBCMCR);
+
+extern char int_ram_top[]; /* top of internal ram */
+
+/*
+ * Initialize SS555
+ */
+void _InitSS555 (void)
+{
+ register uint32_t plprcr, msr;
+
+ /*
+ * Initialize the System Protection Control Register (SYPCR).
+ * The SYPCR can only be written once after Reset.
+ */
+ usiu.sypcr =
+ USIU_SYPCR_SWTC(WATCHDOG_TIMEOUT) /* set watchdog timeout */
+ | USIU_SYPCR_BMT(0xFF) /* set bus monitor timeout */
+ | USIU_SYPCR_BME /* enable bus monitor */
+ | USIU_SYPCR_SWF /* watchdog halted in freeze */
+#if WATCHDOG_TIMEOUT != 0xFFFF
+ | USIU_SYPCR_SWE /* enable watchdog */
+#endif
+ | USIU_SYPCR_SWRI /* watchdog forces reset */
+ | USIU_SYPCR_SWP; /* prescale watchdog by 2048 */
+
+ TICKLE_WATCHDOG(); /* restart watchdog timer */
+
+ /*
+ * Re-tune the PLL to the desired system clock frequency.
+ */
+ usiu.plprck = USIU_UNLOCK_KEY; /* unlock PLPRCR */
+ usiu.plprcr =
+ USIU_PLPRCR_TEXPS /* assert TEXP always */
+ | USIU_PLPRCR_MF(BSP_CLOCK_HZ / BSP_CRYSTAL_HZ);
+ /* PLL multiplication factor */
+ usiu.plprck = 0; /* lock PLPRCR */
+
+ while (((plprcr = usiu.plprcr) & USIU_PLPRCR_SPLS) == 0)
+ ; /* wait for PLL to re-lock */
+
+ /*
+ * Enable the timebase and decrementer, then initialize decrementer
+ * register to a large value to guarantee that a decrementer interrupt
+ * will not be generated before the kernel is fully initialized.
+ * Initialize the timebase register to zero.
+ */
+ usiu.tbscrk = USIU_UNLOCK_KEY;
+ usiu.tbscr |= USIU_TBSCR_TBE; /* enable time base and decrementer */
+ usiu.tbscrk = 0;
+
+ usiu.tbk = USIU_UNLOCK_KEY;
+ _write_PPC_DEC(0x7FFFFFFF);
+ _write_TBWU(0x00000000 );
+ _write_TBWL(0x00000000 );
+ usiu.tbk = 0;
+
+ /*
+ * Run the Inter-Module Bus at full speed.
+ */
+ imb.uimb.umcr &= ~UIMB_UMCR_HSPEED;
+
+ /*
+ * Initialize Memory Controller for External RAM
+ *
+ * Initialize the Base and Option Registers (BR0-BR7 and OR0-OR7). Note
+ * that for all chip selects, ORx should be programmed before BRx.
+ *
+ * If booting from internal flash ROM, configure the external RAM to
+ * extend the internal RAM. If booting from external RAM, leave it at
+ * zero but set it up appropriately.
+ */
+ usiu.memc[0]._or =
+ USIU_MEMC_OR_512K /* bank size */
+ | USIU_MEMC_OR_SCY(0) /* wait states in first beat of burst */
+ | USIU_MEMC_OR_BSCY(0); /* wait states in subsequent beats */
+
+ usiu.memc[0]._br =
+ USIU_MEMC_BR_BA(_read_IMMR() & IMMR_FLEN
+ ? (uint32_t)int_ram_top : 0) /* base address */
+ | USIU_MEMC_BR_PS32 /* 32-bit data bus */
+ | USIU_MEMC_BR_TBDIP /* toggle bdip */
+ | USIU_MEMC_BR_V; /* base register valid */
+
+ /*
+ * Initialize Memory Controller for External CPLD
+ *
+ * The SS555 board includes a CPLD to control on-board features and
+ * off-board devices. (Configuration taken from Intec's hwhook.c)
+ */
+ usiu.memc[3]._or =
+ USIU_MEMC_OR_16M /* bank size */
+ | USIU_MEMC_OR_CSNT /* negate CS/WE early */
+ | USIU_MEMC_OR_ACS_HALF /* assert CS half cycle after address */
+ | USIU_MEMC_OR_SCY(15) /* wait states in first beat of burst */
+ | USIU_MEMC_OR_TRLX; /* relaxed timing */
+
+ usiu.memc[3]._br =
+ USIU_MEMC_BR_BA(&cpld) /* base address */
+ | USIU_MEMC_BR_PS16 /* 16-bit data bus */
+ | USIU_MEMC_BR_BI /* inhibit bursting */
+ | USIU_MEMC_BR_V; /* base register valid */
+
+ /*
+ * Disable show cycles and serialization so that burst accesses will work
+ * properly. A different value, such as 0x0, may be more appropriate for
+ * debugging, but can be set with the debugger, if needed.
+ */
+ _write_ICTRL(0x00000007);
+
+ /*
+ * Set up Burst Buffer Controller (BBC)
+ */
+ _write_BBCMCR(
+ BBCMCR_ETRE /* enable exception relocation */
+ | BBCMCR_BE); /* enable burst accesses */
+ _isync;
+
+ _CPU_MSR_GET(msr);
+ msr |= MSR_IP; /* set prefix for exception relocation */
+ _CPU_MSR_SET(msr);
+}
diff --git a/bsps/powerpc/ss555/start/linkcmds b/bsps/powerpc/ss555/start/linkcmds
new file mode 100644
index 0000000000..8282d6c605
--- /dev/null
+++ b/bsps/powerpc/ss555/start/linkcmds
@@ -0,0 +1,328 @@
+/*
+ * Linker command file for Intec SS555 board
+ *
+ * When debugging, we assume that the internal flash ROM will be replaced by
+ * the external RAM on the SS555 board. All sections are stacked starting
+ * at address zero. Nothing is placed in the internal RAM, since it's not
+ * contiguous with the external SRAM when the external RAM is placed at
+ * zero.
+ *
+ * For final production, we assume that the .text section will be burned
+ * into flash ROM starting at address zero. The .data, .bss, heap, and
+ * workspace will reside in RAM, starting at the beginning of the internal
+ * RAM. The system startup code will configure the external RAM to begin
+ * where the internal RAM ends, so as to make one large RAM block.
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+ENTRY(start)
+EXTERN(_vectors)
+
+int_ram_org = 0x003F9800; /* base of internal RAM */
+int_ram_top = 0x00400000; /* top of internal RAM */
+ext_ram_size = 0x00080000; /* size of external RAM */
+
+RamBase = DEFINED(_RamBase) ? RamBase : 0x003F9800;
+RamSize = DEFINED(_RamSize) ? RamSize : 0x00486800;
+HeapSize = DEFINED(_HeapSize) ? HeapSize : 0x0;
+
+SECTIONS
+{
+ .vectors 0x0:
+ {
+ /*
+ * For the MPC555, we use the compressed vector table format which puts
+ * all of the exception vectors before 0x100.
+ */
+ *(.vectors)
+ }
+
+ .text 0x100:
+ {
+ /* Read-only sections, merged into text segment: */
+
+ text.start = .;
+
+ /* Entry point is the .entry section */
+ *(.entry)
+ *(.entry2)
+
+ /* Actual code */
+ *(.text*)
+
+ /* C++ constructors/destructors */
+ *(.gnu.linkonce.t*)
+
+ /* Initialization and finalization code.
+ *
+ * Various files can provide initialization and finalization functions.
+ * The bodies of these functions are in .init and .fini sections. We
+ * accumulate the bodies here, and prepend function prologues from
+ * ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
+ * first; ecrtn.o must be linked last. Because these are wildcards, it
+ * doesn't matter if the user does not actually link against ecrti.o and
+ * ecrtn.o; the linker won't look for a file to match a wildcard. The
+ * wildcard also means that it doesn't matter which directory ecrti.o
+ * and ecrtn.o are in.
+ */
+ PROVIDE (_init = .);
+ *ecrti.o(.init)
+ *(.init)
+ *ecrtn.o(.init)
+
+ PROVIDE (_fini = .);
+ *ecrti.o(.fini)
+ *(.fini)
+ *ecrtn.o(.init)
+
+ /*
+ * C++ constructors and destructors for static objects.
+ * PowerPC EABI does not use crtstuff yet, so we build "old-style"
+ * constructor and destructor lists that begin with the list length
+ * end terminate with a NULL entry.
+ */
+ PROVIDE (__CTOR_LIST__ = .);
+ /* LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) */
+ *crtbegin.o(.ctors)
+ *(.ctors)
+ *crtend.o(.ctors)
+ LONG(0)
+ PROVIDE (__CTOR_END__ = .);
+
+ PROVIDE (__DTOR_LIST__ = .);
+ /* LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) */
+ *crtbegin.o(.dtors)
+ *(.dtors)
+ *crtend.o(.dtors)
+ LONG(0)
+ PROVIDE (__DTOR_END__ = .);
+
+ /*
+ * Special FreeBSD sysctl sections.
+ */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ /* Exception frame info */
+ *(.eh_frame)
+
+ /* Miscellaneous read-only data */
+ _rodata_start = . ;
+ *(.gnu.linkonce.r*)
+ *(.lit)
+ *(.shdata)
+ *(.rodata*)
+ *(.rodata1)
+ KEEP (*(SORT(.rtemsroset.*)))
+ *(.descriptors)
+ *(rom_ver)
+ _erodata = .;
+
+ /* Various possible names for the end of the .text section */
+ etext = ALIGN(0x10);
+ _etext = .;
+ _endtext = .;
+ text.end = .;
+ PROVIDE (etext = .);
+ PROVIDE (__etext = .);
+ }
+ text.size = text.end - text.start;
+
+ .tdata : {
+ _TLS_Data_begin = .;
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ _TLS_Data_end = .;
+
+ /*
+ * .data section contents, copied to RAM at system startup.
+ */
+ . = ALIGN(0x20);
+ data.contents.start = .;
+ }
+ .tbss : {
+ _TLS_BSS_begin = .;
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ _TLS_BSS_end = .;
+ }
+ _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));
+
+ /*
+ * If debugging, stack the read/write sections directly after the text
+ * section. Otherwise, stack the read/write sections starting at base of
+ * internal RAM.
+ */
+ . = DEFINED(RTEMS_DEBUG) ? . : int_ram_org;
+
+ .data : AT (data.contents.start)
+ {
+ data.start = .;
+
+ *(.data)
+ *(.data.*)
+ KEEP (*(SORT(.rtemsrwset.*)))
+ *(.data1)
+
+ PROVIDE (__SDATA_START__ = .);
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ PROVIDE (__SDATA_END__ = .);
+
+ PROVIDE (__EXCEPT_START__ = .);
+ *(.gcc_except_table*)
+ PROVIDE (__EXCEPT_END__ = .);
+
+ PROVIDE(__GOT_START__ = .);
+ *(.got.plt)
+ *(.got)
+ PROVIDE(__GOT_END__ = .);
+
+ *(.got1)
+
+ PROVIDE (__GOT2_START__ = .);
+ PROVIDE (_GOT2_START_ = .);
+ *(.got2)
+ PROVIDE (__GOT2_END__ = .);
+ PROVIDE (_GOT2_END_ = .);
+
+ PROVIDE (__FIXUP_START__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ *(.fixup)
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (__FIXUP_END__ = .);
+
+ /* We want the small data sections together, so single-instruction
+ * offsets can access them all.
+ */
+ PROVIDE (__SDATA2_START__ = .);
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+ PROVIDE (__SDATA2_END__ = .);
+
+ data.end = .;
+ }
+ data.size = data.end - data.start;
+
+ bss.start = .;
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);
+ }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss* .gnu.linkonce.b*)
+ *(COMMON)
+ . = ALIGN(4);
+ }
+ bss.end = .;
+ bss.size = bss.end - bss.start;
+
+ PROVIDE(_end = bss.end);
+
+ /*
+ * Initialization stack
+ */
+ InitStack_start = ALIGN(0x10);
+ . += 0x1000;
+ initStack = .;
+ PROVIDE(initStackPtr = initStack);
+
+ /*
+ * Interrupt stack
+ */
+ IntrStack_start = ALIGN(0x10);
+ . += 0x4000;
+ intrStack = .;
+ PROVIDE(intrStackPtr = intrStack);
+
+ /*
+ * Work Area
+ *
+ * The Work Area is configured at run-time to use all available memory. It
+ * begins just after the end of the Workspace and continues to the end of
+ * the external RAM.
+ */
+ . = DEFINED(RTEMS_DEBUG) ? 0 + ext_ram_size : int_ram_top + ext_ram_size;
+ WorkAreaBase = .;
+
+
+ /*
+ * Internal I/O devices
+ */
+ .usiu 0x002FC000: /* unified system interface unit */
+ {
+ usiu = .;
+ }
+
+ .imb 0x00300000: /* inter-module bus and devices */
+ {
+ imb = .;
+ }
+
+ .sram 0x00380000: /* internal SRAM control registers */
+ {
+ sram = .;
+ }
+
+ /*
+ * SS555 external devices managed by on-board CPLD
+ */
+ .cpld 0xFF000000: /* SS555 external CPLD devices */
+ {
+ cpld = .;
+ }
+
+
+ /* 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) }
+ .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) }
+ /* These must appear regardless of . */
+}
diff --git a/bsps/powerpc/ss555/start/tm27supp.c b/bsps/powerpc/ss555/start/tm27supp.c
new file mode 100644
index 0000000000..4c1660ff70
--- /dev/null
+++ b/bsps/powerpc/ss555/start/tm27supp.c
@@ -0,0 +1,14 @@
+/*
+ * Support routines for TM27
+ */
+
+#include <bsp.h>
+
+rtems_irq_connect_data tm27IrqData = {
+ CPU_USIU_EXT_IRQ_7,
+ (rtems_irq_hdl)0,
+ NULL,
+ NULL,
+ NULL
+};
+
diff --git a/bsps/powerpc/t32mppc/start/bsp_specs b/bsps/powerpc/t32mppc/start/bsp_specs
new file mode 100644
index 0000000000..f8bbffbdf6
--- /dev/null
+++ b/bsps/powerpc/t32mppc/start/bsp_specs
@@ -0,0 +1,11 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
+
diff --git a/bsps/powerpc/t32mppc/start/bspreset.c b/bsps/powerpc/t32mppc/start/bspreset.c
new file mode 100644
index 0000000000..9472192fab
--- /dev/null
+++ b/bsps/powerpc/t32mppc/start/bspreset.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 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 <stdbool.h>
+
+#include <bsp/bootcard.h>
+
+void bsp_reset(void)
+{
+ while (true) {
+ /* Do nothing */
+ }
+}
diff --git a/bsps/powerpc/t32mppc/start/bspstart.c b/bsps/powerpc/t32mppc/start/bspstart.c
new file mode 100644
index 0000000000..5fc36b4019
--- /dev/null
+++ b/bsps/powerpc/t32mppc/start/bspstart.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012, 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/config.h>
+#include <rtems/counter.h>
+
+#include <bsp.h>
+#include <bsp/vectors.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+
+LINKER_SYMBOL(bsp_exc_vector_base);
+
+/*
+ * Configuration parameter for clock driver. The Trace32 PowerPC simulator has
+ * an odd decrementer frequency. The time base frequency is one tick per
+ * instruction. The decrementer frequency is one tick per ten instructions.
+ * The clock driver assumes that the time base and decrementer frequencies are
+ * equal. For now we simulate processor that issues 10000000 instructions per
+ * second.
+ */
+uint32_t bsp_time_base_frequency = 10000000;
+
+#define MTIVPR(base) \
+ __asm__ volatile ("mtivpr %0" : : "r" (base))
+
+#define VECTOR_TABLE_ENTRY_SIZE 16
+
+#define MTIVOR(vec, offset) \
+ do { \
+ __asm__ volatile ("mtspr " RTEMS_XSTRING(vec) ", %0" : : "r" (offset)); \
+ offset += VECTOR_TABLE_ENTRY_SIZE; \
+ } while (0)
+
+static void t32mppc_initialize_exceptions(void *interrupt_stack_begin)
+{
+ uintptr_t addr;
+
+ ppc_exc_initialize_interrupt_stack(
+ (uintptr_t) interrupt_stack_begin,
+ rtems_configuration_get_interrupt_stack_size()
+ );
+
+ addr = (uintptr_t) bsp_exc_vector_base;
+ MTIVPR(addr);
+ MTIVOR(BOOKE_IVOR0, addr);
+ MTIVOR(BOOKE_IVOR1, addr);
+ MTIVOR(BOOKE_IVOR2, addr);
+ MTIVOR(BOOKE_IVOR3, addr);
+ MTIVOR(BOOKE_IVOR4, addr);
+ MTIVOR(BOOKE_IVOR5, addr);
+ MTIVOR(BOOKE_IVOR6, addr);
+ MTIVOR(BOOKE_IVOR7, addr);
+ MTIVOR(BOOKE_IVOR8, addr);
+ MTIVOR(BOOKE_IVOR9, addr);
+ MTIVOR(BOOKE_IVOR10, addr);
+ MTIVOR(BOOKE_IVOR11, addr);
+ MTIVOR(BOOKE_IVOR12, addr);
+ MTIVOR(BOOKE_IVOR13, addr);
+ MTIVOR(BOOKE_IVOR14, addr);
+ MTIVOR(BOOKE_IVOR15, addr);
+ MTIVOR(BOOKE_IVOR32, addr);
+ MTIVOR(BOOKE_IVOR33, addr);
+ MTIVOR(BOOKE_IVOR34, addr);
+ MTIVOR(BOOKE_IVOR35, addr);
+}
+
+void bsp_start(void)
+{
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ rtems_counter_initialize_converter(bsp_time_base_frequency);
+
+ t32mppc_initialize_exceptions(bsp_section_work_begin);
+ bsp_interrupt_initialize();
+}
diff --git a/bsps/powerpc/t32mppc/start/linkcmds.t32mppc b/bsps/powerpc/t32mppc/start/linkcmds.t32mppc
new file mode 100644
index 0000000000..02367f57d0
--- /dev/null
+++ b/bsps/powerpc/t32mppc/start/linkcmds.t32mppc
@@ -0,0 +1,27 @@
+EXTERN (__vectors)
+
+MEMORY {
+ RAM : ORIGIN = 0x0, LENGTH = 128M
+ EMPTY : ORIGIN = 0x0, LENGTH = 0
+}
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", 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_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", RAM);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/tqm8xx/start/bsp_specs b/bsps/powerpc/tqm8xx/start/bsp_specs
new file mode 100644
index 0000000000..b5cd6764ce
--- /dev/null
+++ b/bsps/powerpc/tqm8xx/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn%O%s}
diff --git a/bsps/powerpc/tqm8xx/start/bspgetworkarea.c b/bsps/powerpc/tqm8xx/start/bspgetworkarea.c
new file mode 100644
index 0000000000..4a0a4db534
--- /dev/null
+++ b/bsps/powerpc/tqm8xx/start/bspgetworkarea.c
@@ -0,0 +1,34 @@
+/**
+ * @file
+ *
+ * @ingroup tqm8xx
+ *
+ * @brief Source for BSP Get Work Area Memory
+ */
+
+/*
+ * Copyright (c) 2008, 2018 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/linker-symbols.h>
+
+void bsp_work_area_initialize(void)
+{
+ char *ram_end = (char *) (TQM_BD_INFO.sdram_size - (uint32_t)TopRamReserved);
+ void *area_start = bsp_section_work_begin;
+ uintptr_t area_size = (uintptr_t) ram_end - (uintptr_t) area_start;
+
+ bsp_work_area_initialize_default( area_start, area_size );
+}
diff --git a/bsps/powerpc/tqm8xx/start/bspstart.c b/bsps/powerpc/tqm8xx/start/bspstart.c
new file mode 100644
index 0000000000..df0581ce77
--- /dev/null
+++ b/bsps/powerpc/tqm8xx/start/bspstart.c
@@ -0,0 +1,156 @@
+/**
+ * @file
+ *
+ * @ingroup tqm8xx
+ *
+ * @brief Source for BSP startup code.
+ */
+
+/*
+ * Copyright (c) 2008
+ * 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 <stdlib.h>
+
+#include <rtems.h>
+#include <rtems/counter.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/vectors.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+
+#ifdef BSP_HAS_TQMMON
+/*
+ * FIXME: TQ Monitor structure
+ */
+#endif /* BSP_HAS_TQMMON */
+
+/* Configuration parameters for console driver, ... */
+uint32_t BSP_bus_frequency;
+
+/* Configuration parameter for clock driver */
+uint32_t bsp_time_base_frequency;
+
+/* Legacy */
+uint32_t bsp_clicks_per_usec; /* for PIT driver: OSCCLK */
+
+static const char *bsp_tqm_get_cib_string( const char *cib_id)
+{
+ char srch_pattern[10] = "";
+ char *fnd_str;
+ /*
+ * create search pattern
+ */
+ strcat(srch_pattern,"-");
+ strncat(srch_pattern,
+ cib_id,
+ sizeof(srch_pattern)-1-strlen(srch_pattern));
+ strncat(srch_pattern,
+ " ",
+ sizeof(srch_pattern)-1-strlen(srch_pattern));
+ /*
+ * search for pattern in info block (CIB)
+ */
+ fnd_str = strstr((const char *)TQM_CONF_INFO_BLOCK_ADDR,srch_pattern);
+
+ if (fnd_str == NULL) {
+ return NULL;
+ }
+ else {
+ /*
+ * found? then advance behind search pattern
+ */
+ return fnd_str + strlen(srch_pattern);
+ }
+}
+
+static rtems_status_code bsp_tqm_get_cib_uint32( const char *cib_id,
+ uint32_t *result)
+{
+ const char *item_ptr;
+ char *end_ptr;
+ item_ptr = bsp_tqm_get_cib_string(cib_id);
+ if (item_ptr == NULL) {
+ return RTEMS_INVALID_ID;
+ }
+ /*
+ * convert string to uint32
+ */
+ *result = strtoul(item_ptr,&end_ptr,10);
+ return RTEMS_SUCCESSFUL;
+}
+
+void bsp_start( void)
+{
+
+ uintptr_t interrupt_stack_start = (uintptr_t) bsp_interrupt_stack_start;
+ uintptr_t interrupt_stack_size = (uintptr_t) bsp_interrupt_stack_end
+ - interrupt_stack_start;
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function stores the result in global variables so that it can be used
+ * later...
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ /* Basic CPU initialization */
+ cpu_init();
+
+ /*
+ * Enable instruction and data caches. Do not force writethrough mode.
+ */
+
+#if BSP_INSTRUCTION_CACHE_ENABLED
+ rtems_cache_enable_instruction();
+#endif
+
+#if BSP_DATA_CACHE_ENABLED
+ rtems_cache_enable_data();
+#endif
+
+ /*
+ * This is evaluated during runtime, so it should be ok to set it
+ * before we initialize the drivers.
+ */
+
+ /* Initialize some device driver parameters */
+ /*
+ * get the (internal) bus frequency
+ * NOTE: the external bus may be clocked at a lower speed
+ * but this does not concern the internal units like PIT,
+ * DEC, baudrate generator etc)
+ */
+ if (RTEMS_SUCCESSFUL !=
+ bsp_tqm_get_cib_uint32("cu",
+ &BSP_bus_frequency)) {
+ rtems_panic("Cannot determine BUS frequency\n");
+ }
+
+ bsp_time_base_frequency = BSP_bus_frequency / 16;
+ bsp_clicks_per_usec = bsp_time_base_frequency / 1000000;
+ rtems_counter_initialize_converter(bsp_time_base_frequency);
+
+ /* Initialize exception handler */
+ ppc_exc_initialize(interrupt_stack_start, interrupt_stack_size);
+
+ /* Initalize interrupt support */
+ bsp_interrupt_initialize();
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Exit from bspstart\n");
+#endif
+}
diff --git a/bsps/powerpc/tqm8xx/start/cpuinit.c b/bsps/powerpc/tqm8xx/start/cpuinit.c
new file mode 100644
index 0000000000..5d34e07cfb
--- /dev/null
+++ b/bsps/powerpc/tqm8xx/start/cpuinit.c
@@ -0,0 +1,133 @@
+/*
+ * cpuinit.c
+ *
+ * TQM8xx initialization routines.
+ * derived from MBX8xx BSP
+ * adapted to TQM8xx by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * 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/tqm.h>
+
+
+/*
+ * Initialize TQM8xx
+ */
+void _InitTQM8xx (void)
+{
+ register uint32_t r1;
+
+ /*
+ * Initialize the Instruction Support Control Register (ICTRL) to a
+ * an appropriate value for normal operation. A different value,
+ * such as 0x0, may be more appropriate for debugging.
+ */
+ r1 = 0x00000007;
+ _mtspr( M8xx_ICTRL, r1 );
+
+ /*
+ * Disable and invalidate the instruction and data caches.
+ */
+ r1 = M8xx_CACHE_CMD_DISABLE;
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_UNLOCKALL;
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_INVALIDATE; /* invalidate all */
+ _mtspr( M8xx_IC_CST, r1 );
+ _isync;
+
+ r1 = M8xx_CACHE_CMD_DISABLE;
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_UNLOCKALL;
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+ r1 = M8xx_CACHE_CMD_INVALIDATE; /* invalidate all */
+ _mtspr( M8xx_DC_CST, r1 );
+ _isync;
+
+ /*
+ * Initialize the SIU Module Configuration Register (SIUMCR)
+ * m8xx.siumcr = 0x00602900, the default value.
+ */
+ m8xx.siumcr = M8xx_SIUMCR_EARP0 | M8xx_SIUMCR_DBGC3 | M8xx_SIUMCR_DBPC0 |
+ M8xx_SIUMCR_DPC | M8xx_SIUMCR_MLRC2 | M8xx_SIUMCR_SEME;
+
+ /*
+ * Initialize the System Protection Control Register (SYPCR).
+ * The SYPCR can only be written once after Reset.
+ * - Enable bus monitor
+ * - Disable software watchdog timer
+ * m8xx.sypcr = 0xFFFFFF88, the default MBX and firmware value.
+ */
+ m8xx.sypcr = M8xx_SYPCR_SWTC(0xFFFF) | M8xx_SYPCR_BMT(0xFF) |
+ M8xx_SYPCR_BME | M8xx_SYPCR_SWF;
+
+ /* Initialize the SIU Interrupt Edge Level Mask Register (SIEL) */
+ m8xx.siel = 0xAAAA0000; /* Default MBX and firmware value. */
+
+ /* Initialize the Transfer Error Status Register (TESR) */
+ m8xx.tesr = 0xFFFFFFFF; /* Default firmware value. */
+
+ /* Initialize the SDMA Configuration Register (SDCR) */
+ m8xx.sdcr = 0x00000001; /* Default firmware value. */
+
+ /*
+ * Initialize the Timebase Status and Control Register (TBSCR)
+ * m8xx.tbscr = 0x00C3, default MBX and firmware value.
+ */
+ m8xx.tbscrk = M8xx_UNLOCK_KEY; /* unlock TBSCR */
+ m8xx.tbscr = M8xx_TBSCR_REFA | M8xx_TBSCR_REFB |
+ M8xx_TBSCR_TBF | M8xx_TBSCR_TBE;
+
+ /* Initialize the Real-Time Clock Status and Control Register (RTCSC) */
+ m8xx.rtcsk = M8xx_UNLOCK_KEY; /* unlock RTCSC */
+ m8xx.rtcsc = 0x00C3; /* Default MBX and firmware value. */
+
+ /* Unlock other Real-Time Clock registers */
+ m8xx.rtck = M8xx_UNLOCK_KEY; /* unlock RTC */
+ m8xx.rtseck = M8xx_UNLOCK_KEY; /* unlock RTSEC */
+ m8xx.rtcalk = M8xx_UNLOCK_KEY; /* unlock RTCAL */
+
+ /* Initialize the Periodic Interrupt Status and Control Register (PISCR) */
+ m8xx.piscrk = M8xx_UNLOCK_KEY; /* unlock PISCR */
+ m8xx.piscr = 0x0083; /* Default MBX and firmware value. */
+
+ /* Initialize the System Clock and Reset Control Register (SCCR)
+ * Set the clock sources and division factors:
+ * Timebase Source is GCLK2 / 16
+ */
+ m8xx.sccrk = M8xx_UNLOCK_KEY; /* unlock SCCR */
+ m8xx.sccr |= 0x02000000;
+
+ /* Unlock the timebase and decrementer registers. */
+ m8xx.tbk = M8xx_UNLOCK_KEY;
+ /*
+ * Initialize decrementer register to a large value to
+ * guarantee that a decrementer interrupt will not be
+ * generated before the kernel is fully initialized.
+ */
+ r1 = 0x7FFFFFFF;
+ _mtspr( M8xx_DEC, r1 );
+
+ /* Initialize the timebase register (TB is 64 bits) */
+ r1 = 0x00000000;
+ _mtspr( M8xx_TBU_WR, r1 );
+ _mtspr( M8xx_TBL_WR, r1 );
+}
+/*
+ * further initialization (called from bsp_start)
+ */
+void cpu_init(void)
+{
+ /* mmu initialization */
+ mmu_init();
+}
diff --git a/bsps/powerpc/tqm8xx/start/linkcmds b/bsps/powerpc/tqm8xx/start/linkcmds
new file mode 100644
index 0000000000..7171d0230a
--- /dev/null
+++ b/bsps/powerpc/tqm8xx/start/linkcmds
@@ -0,0 +1,43 @@
+/**
+ * @file
+ *
+ * TQM8xx
+ */
+
+TopRamReserved = DEFINED(TopRamReserved) ? TopRamReserved : 0;
+
+MEMORY {
+ EMPTY : ORIGIN = 0, LENGTH = 0
+ RAM : ORIGIN = 0x10000, LENGTH = 128M - 64k
+ immr : org = 0xfa200000, l = 16K
+ ROM : ORIGIN = 0x40000000, LENGTH = 8M
+}
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", 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_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", EMPTY);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", EMPTY);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+SECTIONS {
+ dpram : {
+ m8xx = .;
+ _m8xx = .;
+ /* . += (16 * 1024); this makes the mbx loader crash */
+ } >immr
+}
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/tqm8xx/start/mmutlbtab.c b/bsps/powerpc/tqm8xx/start/mmutlbtab.c
new file mode 100644
index 0000000000..8b1ad90036
--- /dev/null
+++ b/bsps/powerpc/tqm8xx/start/mmutlbtab.c
@@ -0,0 +1,103 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by |
+| Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> |
+| Copyright (c) 2008 |
+| Embedded Brains GmbH |
+| Obere Lagerstr. 30 |
+| D-82178 Puchheim |
+| Germany |
+| rtems@embedded-brains.de |
+| |
+| See the other copyright notice below for the original parts. |
++-----------------------------------------------------------------+
+| 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. |
+| |
++-----------------------------------------------------------------+
+| this file contains the console driver |
+\*===============================================================*/
+/* derived from: */
+/*
+ * mmutlbtab.c
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * 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 <mpc8xx/mmu.h>
+/*
+ * This MMU_TLB_table is used to statically initialize the Table Lookaside
+ * Buffers in the MMU of the TQM8xx board.
+ *
+ * We initialize the entries in both the instruction and data TLBs
+ * with the same values - a few bits relevant to the data TLB are unused
+ * in the instruction TLB.
+ *
+ * An Effective Page Number (EPN), Tablewalk Control Register (TWC) and
+ * Real Page Number (RPN) value are supplied in the table for each TLB entry.
+ *
+ * The instruction and data TLBs each can hold 32 entries, so _TLB_Table must
+ * not have more than 32 lines in it!
+ *
+ * We set up the virtual memory map so that virtual address of a
+ * location is equal to its real address.
+ */
+MMU_TLB_table_t MMU_TLB_table[] = {
+ /*
+ * DRAM: Start address 0x00000000, 128M,
+ * ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
+ * R/W,X for all, no ASID comparison, not cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0x00000200, 0x0D, 0x000009FD }, /* DRAM - PS=8M */
+ { 0x00800200, 0x0D, 0x008009FD }, /* DRAM - PS=8M */
+ { 0x01000200, 0x0D, 0x010009FD }, /* DRAM - PS=8M */
+ { 0x01800200, 0x0D, 0x018009FD }, /* DRAM - PS=8M */
+ { 0x02000200, 0x0D, 0x020009FD }, /* DRAM - PS=8M */
+ { 0x02800200, 0x0D, 0x028009FD }, /* DRAM - PS=8M */
+ { 0x03000200, 0x0D, 0x030009FD }, /* DRAM - PS=8M */
+ { 0x03800200, 0x0D, 0x038009FD }, /* DRAM - PS=8M */
+ { 0x04000200, 0x0D, 0x040009FD }, /* DRAM - PS=8M */
+ { 0x04800200, 0x0D, 0x048009FD }, /* DRAM - PS=8M */
+ { 0x05000200, 0x0D, 0x050009FD }, /* DRAM - PS=8M */
+ { 0x05800200, 0x0D, 0x058009FD }, /* DRAM - PS=8M */
+ { 0x06000200, 0x0D, 0x060009FD }, /* DRAM - PS=8M */
+ { 0x06800200, 0x0D, 0x068009FD }, /* DRAM - PS=8M */
+ { 0x07000200, 0x0D, 0x070009FD }, /* DRAM - PS=8M */
+ { 0x07800200, 0x0D, 0x078009FD }, /* DRAM - PS=8M */
+ /*
+ *
+ * (IMMR-SPRs) Dual Port RAM: Start address 0xFA200000, 16K,
+ * ASID=0x0, APG=0x0, guarded memory, write-through data cache policy,
+ * R/W,X for all, no ASID comparison, cache-inhibited.
+ *
+ * Note: We use the value in MBXA/PG2, which is also the value that
+ * EPPC-Bug programmed into our boards. The alternative is the value
+ * in MBXA/PG1: 0xFFA00000. This value might well depend on the revision
+ * of the firmware.
+ * EPN TWC RPN
+ */
+ { 0xFA200200, 0x13, 0xFA2009FF }, /* IMMR - PS=16K */
+ /*
+ *
+ * Flash: Start address 0x40000000, 8M,
+ * ASID=0x0, APG=0x0, not guarded memory,
+ * R/O,X for all, no ASID comparison, not cache-inhibited.
+ * EPN TWC RPN
+ */
+ { 0x40000200, 0x0D, 0x40000CFD } /* Flash - PS=8M */
+};
+
+/*
+ * MMU_N_TLB_Table_Entries is defined here because the size of the
+ * MMU_TLB_table is only known in this file.
+ */
+int MMU_N_TLB_Table_Entries = ( sizeof(MMU_TLB_table) / sizeof(MMU_TLB_table[0]) );
diff --git a/bsps/powerpc/virtex/start/bsp_specs b/bsps/powerpc/virtex/start/bsp_specs
new file mode 100644
index 0000000000..6cb546f392
--- /dev/null
+++ b/bsps/powerpc/virtex/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/virtex/start/bspstart.c b/bsps/powerpc/virtex/start/bspstart.c
new file mode 100644
index 0000000000..5b4a4a135f
--- /dev/null
+++ b/bsps/powerpc/virtex/start/bspstart.c
@@ -0,0 +1,105 @@
+/* bsp_start()
+ *
+ * This routine starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before this routine is invoked.
+ *
+ * INPUT: NONE
+ *
+ * OUTPUT: NONE
+ *
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ * IMD Ingenieurbuero fuer Microcomputertechnik
+ *
+ * COPYRIGHT (c) 1998 by IMD
+ *
+ * Changes from IMD are covered by the original distributions terms.
+ * This file has been derived from the papyrus BSP:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Modifications for spooling console driver and control of memory layout
+ * with linker command file by
+ * Thomas Doerfler <td@imd.m.isar.de>
+ * for these modifications:
+ * COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies. IMD makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c:
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modifications for PPC405GP by Dennis Ehlin
+ */
+
+#include <rtems/counter.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/bootcard.h>
+#include <bsp/linker-symbols.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include RTEMS_XPARAMETERS_H
+
+/* Symbols defined in linker command file */
+LINKER_SYMBOL(virtex_exc_vector_base);
+
+/*
+ * Driver configuration parameters
+ */
+uint32_t bsp_time_base_frequency = XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ;
+
+/*
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ */
+void bsp_start( void )
+{
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function store the result in global variables
+ * so that it can be used latter...
+ */
+ get_ppc_cpu_type();
+ get_ppc_cpu_revision();
+
+ rtems_counter_initialize_converter(bsp_time_base_frequency);
+
+ /*
+ * Initialize default raw exception handlers.
+ */
+ ppc_exc_initialize_with_vector_base(
+ (uintptr_t) bsp_section_work_begin,
+ rtems_configuration_get_interrupt_stack_size(),
+ virtex_exc_vector_base
+ );
+ __asm__ volatile ("mtevpr %0" : : "r" (virtex_exc_vector_base));
+
+ bsp_interrupt_initialize();
+}
diff --git a/bsps/powerpc/virtex/start/linkcmds.in b/bsps/powerpc/virtex/start/linkcmds.in
new file mode 100644
index 0000000000..13f9217e9d
--- /dev/null
+++ b/bsps/powerpc/virtex/start/linkcmds.in
@@ -0,0 +1,35 @@
+EXTERN (__vectors)
+
+MEMORY {
+ RAM : ORIGIN = @VIRTEX_RAM_ORIGIN@, LENGTH = @VIRTEX_RAM_LENGTH@
+ FAST_RAM : ORIGIN = @VIRTEX_FAST_RAM_ORIGIN@, LENGTH = @VIRTEX_FAST_RAM_LENGTH@
+ RESET : ORIGIN = @VIRTEX_RESET_ORIGIN@, LENGTH = @VIRTEX_RESET_LENGTH@
+ EMPTY : ORIGIN = 0x0, LENGTH = 0x0
+}
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT", FAST_RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", 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_FAST_DATA", FAST_RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_RWEXTRA", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_STACK", RAM);
+REGION_ALIAS ("REGION_NOCACHE", EMPTY);
+REGION_ALIAS ("REGION_NOCACHE_LOAD", EMPTY);
+REGION_ALIAS ("REGION_NVRAM", EMPTY);
+
+SECTIONS {
+ .virtex_reset : {
+ KEEP (*(.virtex_reset))
+ } > RESET AT > RESET
+}
+
+INCLUDE linkcmds.base
diff --git a/bsps/powerpc/virtex4/start/bsp_specs b/bsps/powerpc/virtex4/start/bsp_specs
new file mode 100644
index 0000000000..ccbea2690c
--- /dev/null
+++ b/bsps/powerpc/virtex4/start/bsp_specs
@@ -0,0 +1,10 @@
+%rename startfile old_startfile
+%rename endfile old_endfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} \
+%{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/virtex4/start/bspclean.c b/bsps/powerpc/virtex4/start/bspclean.c
new file mode 100644
index 0000000000..bd5829e0b2
--- /dev/null
+++ b/bsps/powerpc/virtex4/start/bspclean.c
@@ -0,0 +1,54 @@
+/*
+ * This routine normally is part of start.s and usually returns
+ * control to a monitor.
+ *
+ * INPUT: NONE
+ *
+ * OUTPUT: NONE
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspclean.c:
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * 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>
+
+static void _noopfun(void) {}
+
+void app_bsp_cleanup(void)
+__attribute__(( weak, alias("_noopfun") ));
+
+void bsp_fatal_extension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code error
+)
+{
+ if ( source == RTEMS_FATAL_SOURCE_EXIT ) {
+ app_bsp_cleanup();
+ }
+
+ /* All done. Hang out. */
+ BSP_ask_for_reset();
+}
diff --git a/bsps/powerpc/virtex4/start/bspstart.c b/bsps/powerpc/virtex4/start/bspstart.c
new file mode 100644
index 0000000000..d5c255be6d
--- /dev/null
+++ b/bsps/powerpc/virtex4/start/bspstart.c
@@ -0,0 +1,219 @@
+/*
+ * This routine starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before this routine is invoked.
+ */
+
+/*
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ * IMD Ingenieurbuero fuer Microcomputertechnik
+ *
+ * COPYRIGHT (c) 1998 by IMD
+ *
+ * Changes from IMD are covered by the original distributions terms.
+ * This file has been derived from the papyrus BSP:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Modifications for spooling console driver and control of memory layout
+ * with linker command file by
+ * Thomas Doerfler <td@imd.m.isar.de>
+ * for these modifications:
+ * COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies. IMD makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c:
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modifications for PPC405GP by Dennis Ehlin
+ * Modifications for Virtex4 by Richard Claus <claus@slac.stanford.edu>
+ */
+#include <rtems.h>
+#include <rtems/config.h>
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+#include <rtems/sysinit.h>
+
+#include <libcpu/cpuIdent.h>
+#include <libcpu/spr.h>
+
+#include <bsp.h>
+#include <bsp/vectors.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#define DO_DOWN_ALIGN(x,a) ((x) & ~((a)-1))
+
+#define DO_UP_ALIGN(x,a) DO_DOWN_ALIGN(((x) + (a) - 1 ),a)
+
+#define CPU_DOWN_ALIGN(x) DO_DOWN_ALIGN(x, CPU_ALIGNMENT)
+#define CPU_UP_ALIGN(x) DO_UP_ALIGN(x, CPU_ALIGNMENT)
+
+
+/* Defined in linkcmds linker script */
+LINKER_SYMBOL(RamBase);
+LINKER_SYMBOL(RamSize);
+LINKER_SYMBOL(__bsp_ram_start);
+LINKER_SYMBOL(__bsp_ram_end);
+LINKER_SYMBOL(__rtems_end);
+LINKER_SYMBOL(_stack);
+LINKER_SYMBOL(StackSize);
+LINKER_SYMBOL(__stack_base);
+LINKER_SYMBOL(WorkAreaBase);
+LINKER_SYMBOL(MsgAreaBase);
+LINKER_SYMBOL(MsgAreaSize);
+LINKER_SYMBOL(__phy_ram_end);
+LINKER_SYMBOL(bsp_exc_vector_base);
+
+
+/* Expected by clock.c */
+uint32_t bsp_clicks_per_usec;
+
+
+/*
+ * Provide weak aliases so that RTEMS distribution builds
+ */
+static void _noopfun(void) {}
+
+
+void app_bsp_start(void)
+__attribute__(( weak, alias("_noopfun") ));
+
+void app_bsp_predriver_hook(void)
+__attribute__(( weak, alias("_noopfun") ));
+
+
+static char* bspMsgBuffer = (char*)MsgAreaBase;
+
+static void __bsp_outchar_to_memory(char c)
+{
+ static char* msgBuffer = (char*)MsgAreaBase;
+ *msgBuffer++ = c;
+ if (msgBuffer >= &bspMsgBuffer[(int)MsgAreaSize]) msgBuffer = bspMsgBuffer;
+ *msgBuffer = 0x00; /* Overwrite next location to show EOM */
+}
+
+
+void BSP_ask_for_reset(void)
+{
+ printk("\nSystem stopped, issue RESET");
+
+ for(;;);
+}
+
+
+/*===================================================================*/
+
+/*
+ * BSP start routine. Called by boot_card().
+ *
+ * This routine does the bulk of the system initialization.
+ */
+void bsp_start(void)
+{
+ uintptr_t intrStackStart;
+ uintptr_t intrStackSize;
+
+ ppc_cpu_id_t myCpu;
+ ppc_cpu_revision_t myCpuRevision;
+
+ /* Set the character output function; The application may override this */
+ BSP_output_char = __bsp_outchar_to_memory;
+
+ printk("RTEMS %s\n", rtems_get_version_string());
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function stores the result in global variables so that it can be used later...
+ */
+ myCpu = get_ppc_cpu_type();
+ myCpuRevision = get_ppc_cpu_revision();
+ printk("CPU: 0x%04x, Revision: 0x%04x = %d, Name: %s\n",
+ myCpu, myCpuRevision, myCpuRevision, get_ppc_cpu_type_name(myCpu));
+
+ /*
+ * Initialize the device driver parameters
+ */
+
+ /* Timebase register ticks/microsecond; The application may override these */
+ bsp_clicks_per_usec = 350;
+ rtems_counter_initialize_converter(bsp_clicks_per_usec * 1000000);
+
+ /*
+ * Initialize the interrupt related settings.
+ */
+ intrStackStart = CPU_UP_ALIGN((uint32_t)__bsp_ram_start);
+ intrStackSize = rtems_configuration_get_interrupt_stack_size();
+
+ ppc_exc_initialize(intrStackStart, intrStackSize);
+
+ /* Let the user know what parameters we were compiled with */
+ printk(" Base/Start End Size\n"
+ "RAM: %p %p\n"
+ "RTEMS: %p\n"
+ "Interrupt Stack: 0x%08x 0x%x\n"
+ "Stack: %p %p %p\n"
+ "Workspace: %p %p\n"
+ "MsgArea: %p %p\n"
+ "Physical RAM %p\n",
+ RamBase, RamSize,
+ __rtems_end,
+ intrStackStart, intrStackSize,
+ __stack_base, _stack, StackSize,
+ WorkAreaBase, __bsp_ram_end,
+ MsgAreaBase, MsgAreaSize,
+ __phy_ram_end);
+
+ /*
+ * Initialize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mngt_init(0);
+
+ /* Continue with application-specific initialization */
+ app_bsp_start();
+}
+
+
+/*
+ * BSP predriver hook. Called by boot_card() just before drivers are
+ * initialized. Clear out any stale interrupts here.
+ */
+static void virtex4_pre_driver_hook(void)
+{
+ app_bsp_predriver_hook();
+}
+
+RTEMS_SYSINIT_ITEM(
+ virtex4_pre_driver_hook,
+ RTEMS_SYSINIT_BSP_PRE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
diff --git a/bsps/powerpc/virtex4/start/dummy_console.c b/bsps/powerpc/virtex4/start/dummy_console.c
new file mode 100644
index 0000000000..642fe45618
--- /dev/null
+++ b/bsps/powerpc/virtex4/start/dummy_console.c
@@ -0,0 +1,88 @@
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/bspIo.h>
+#include <rtems/console.h>
+
+#include <string.h>
+
+ssize_t app_memory_write(int minor, const char* buf, size_t len)
+__attribute__(( weak, alias("__bsp_memory_write") ));
+
+ssize_t __bsp_memory_write(int minor, const char* buf, size_t len);
+rtems_device_driver console_initialize(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg);
+
+ssize_t __bsp_memory_write(int minor, const char* buf, size_t len)
+{
+ const char* const last = buf+len;
+ while (buf < last)
+ {
+ rtems_putc(*buf++);
+ }
+ return len;
+}
+
+static rtems_termios_callbacks gMemCallbacks = {
+ 0, /* firstOpen */
+ 0, /* lastClose */
+ 0, /* PollRead */
+ app_memory_write, /* write */
+ 0, /* SetAttr */
+ 0, /* stopRemoteTx */
+ 0, /* startRemoteTx */
+ 0 /* outputUsesInterrupts */
+};
+
+rtems_device_driver console_initialize(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ rtems_status_code status;
+
+ rtems_termios_initialize();
+
+ status = rtems_io_register_name("/dev/console", major, 0);
+
+ if (status != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (status);
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver console_open(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ rtems_status_code sc;
+
+ sc = rtems_termios_open (major, minor, arg, &gMemCallbacks);
+
+ return sc;
+}
+
+rtems_device_driver console_close(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ return rtems_termios_close(arg);
+}
+
+rtems_device_driver console_read(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ return rtems_termios_read(arg);
+}
+
+rtems_device_driver console_write(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ return rtems_termios_write(arg);
+}
+
+rtems_device_driver console_control(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ return rtems_termios_ioctl(arg);
+}
diff --git a/bsps/powerpc/virtex4/start/linkcmds b/bsps/powerpc/virtex4/start/linkcmds
new file mode 100644
index 0000000000..50d3a3f13c
--- /dev/null
+++ b/bsps/powerpc/virtex4/start/linkcmds
@@ -0,0 +1,288 @@
+/*
+ * This file contains directives for the GNU linker which are specific to the
+ * Virtex 4 PPC 405. No assumptions are made on the firmware in the FPGA.
+ * This file is intended to be used together with start.S to generate
+ * downloadable code.
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+
+ENTRY(download_entry)
+EXTERN(download_entry)
+EXTERN(__vectors)
+
+MsgAreaSize = DEFINED(MsgAreaSize) ? MsgAreaSize : 1M;
+RamBase = DEFINED(RamBase) ? RamBase : 0x0;
+RamSize = DEFINED(RamSize) ? RamSize : 128M - MsgAreaSize;
+IntrStackSize = DEFINED(IntrStackSize) ? IntrStackSize : 16K;
+StackSize = DEFINED(StackSize) ? StackSize : 64K;
+HeapSize = DEFINED(HeapSize) ? HeapSize : 0; /* 0=Use def */
+
+
+MEMORY
+{
+ VECTORS : ORIGIN = 0x00000000, LENGTH = 12K
+ RAM : ORIGIN = 0x00003000, LENGTH = 128M - 12K
+}
+
+
+SECTIONS
+{
+ bsp_exc_vector_base = 0x100;
+ __exeentry = download_entry;
+ __exestart = bsp_exc_vector_base;
+ .vectors bsp_exc_vector_base : { *(.vectors) } > VECTORS
+
+ /* Read-only sections, merged into text segment: */
+ .interp : { *(.interp) } > RAM
+ .hash : { *(.hash) } > RAM
+ .dynsym : { *(.dynsym) } > RAM
+ .dynstr : { *(.dynstr) } > RAM
+ .gnu.version : { *(.gnu.version) } > RAM
+ .gnu.version_d : { *(.gnu.version_d) } > RAM
+ .gnu.version_r : { *(.gnu.version_r) } > RAM
+ .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) } > RAM
+ .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) } > RAM
+ .rela.rodata : { *(.rela.rodata*) *(.rela.gnu.linkonce.r*) } > RAM
+ .rela.got : { *(.rela.got) } > RAM
+ .rela.got1 : { *(.rela.got1) } > RAM
+ .rela.got2 : { *(.rela.got2) } > RAM
+ .rela.ctors : { *(.rela.ctors) } > RAM
+ .rela.dtors : { *(.rela.dtors) } > RAM
+ .rela.init : { *(.rela.init) } > RAM
+ .rela.fini : { *(.rela.fini) } > RAM
+ .rela.bss : { *(.rela.bss) } > RAM
+ .rela.plt : { *(.rela.plt) } > RAM
+ .rela.sdata : { *(.rela.sdata) } > RAM
+ .rela.sbss : { *(.rela.sbss) } > RAM
+ .rela.sdata2 : { *(.rela.sdata2) } > RAM
+ .rela.sbss2 : { *(.rela.sbss2) } > RAM
+ .rela.dyn : { *(.rela.dyn) } > RAM
+
+ /* Initialization code */
+ .init : { PROVIDE (_init = .);
+ *ecrti.o(.init)
+ KEEP(*(.init))
+ *ecrtn.o(.init)
+ } > RAM
+
+ .text : { *(.entry)
+ *(.text)
+ *(.text.*)
+
+ /* Special FreeBSD sysctl sections */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ /* .gnu.warning sections are handled specially by elf32.em
+ */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } > RAM
+
+ /* Finalization code */
+ .fini : { PROVIDE (_fini = .);
+ *ecrti.o(.fini)
+ KEEP(*(.fini))
+ *ecrtn.o(.fini)
+ } > RAM
+
+ /* Miscellaneous read-only data */
+ .rodata : { *(.rodata.* .gnu.linkonce.r*) KEEP (*(SORT(.rtemsroset.*))) } > RAM
+ .rodata1 : { *(.rodata1) } > RAM
+
+ .tdata : {
+ _TLS_Data_begin = .;
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ _TLS_Data_end = .;
+ } >RAM
+
+ .tbss : {
+ _TLS_BSS_begin = .;
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ _TLS_BSS_end = .;
+ } >RAM
+
+ _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));
+
+ /* Initialised small data addressed as offsets from r2 */
+ .sdata2 : { PROVIDE (_SDA2_BASE_ = 32768); *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } > RAM
+
+ /* Zeroed small data addressed as offsets from r2 */
+ .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+
+ /* Avoid empty sdata2/sbss2 area: __eabi would not set up
+ * r2 which may be important if run-time loading is used
+ */
+ . += 1;
+
+ PROVIDE (__SBSS2_END__ = .);
+ } > RAM
+
+ /* Exception frame info */
+ .eh_frame : { *(.eh_frame .eh_frame.*) } > RAM
+ .eh_frame_hdr : { *(.eh_frame_hdr) } > RAM
+
+ /* Declares where the .text section ends */
+ _etext = .;
+ PROVIDE (etext = .);
+
+ /* Initialized R/W Data section goes in RAM */
+ .data : { PROVIDE(__DATA_START__ = ABSOLUTE(.) );
+ *(.data)
+ *(.data.*)
+ KEEP (*(SORT(.rtemsrwset.*)))
+ *(.gnu.linkonce.d*)
+ } > RAM
+
+ .data1 : { *(.data1) } > RAM
+
+ PROVIDE (__EXCEPT_START__ = .);
+ .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } > RAM
+ PROVIDE (__EXCEPT_END__ = .);
+
+ .got1 : { *(.got1) } > RAM
+
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ * get relocated with -mrelocatable. Also put in the .fixup pointers.
+ * The current compiler no longer needs this, but keep it around for 2.7.2.
+ */
+ PROVIDE (_GOT2_START_ = .);
+ .got2 : { *(.got2) } > RAM
+
+ .dynamic : { *(.dynamic) } > RAM
+
+ .ctors : { /* 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))
+ /* 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 ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } > RAM
+
+ .dtors : { KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } > RAM
+
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) } > RAM
+ PROVIDE (_FIXUP_END_ = .);
+
+ PROVIDE (_GOT2_END_ = .);
+
+ PROVIDE (_GOT_START_ = .);
+ .got : { __got_start = .;
+ *(.got)
+ } > RAM
+
+ .got.plt : { *(.got.plt) } > RAM
+ PROVIDE (_GOT_END_ = .);
+
+ .jcr : { KEEP (*(.jcr)) } > RAM
+
+ /* We want the small data sections together, so single-instruction offsets
+ * can access them all, and initialized data all before uninitialized, so
+ * we can shorten the on-disk segment size.
+ */
+ /* Initialised small data addressed as offsets from r13 */
+ .sdata : { PROVIDE (_SDA_BASE_ = 32768); *(.sdata* .gnu.linkonce.s.*) } > RAM
+
+ _edata = .;
+ PROVIDE (edata = .);
+
+ /* Zeroed small data addressed as offsets from r13 */
+ .sbss : { PROVIDE (__sbss_start = .);
+ *(.dynsbss)
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.scommon)
+
+ /* Avoid empty sdata/sbss area: __eabi would not set up
+ * r13, which may be important if run-time loading is used
+ */
+ . += 1;
+
+ PROVIDE (__SBSS_END__ = .);
+ PROVIDE (__sbss_end = .);
+ } > RAM
+
+ .plt : { *(.plt) } > RAM
+ .iplt : { *(.iplt) } > RAM
+
+ /* Zeroed large data */
+ .bss : { PROVIDE (__bss_start = .);
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(.gnu.linkonce.b*)
+ *(COMMON)
+
+ PROVIDE (__bss_end = ALIGN(4));
+ __bss_size = __bss_end - __bss_start;
+ } > RAM
+
+ __exeend = ALIGN(4);
+ __rtems_end = .;
+ . = ALIGN(0x10); /* Align to a cache-line boundary */
+ PROVIDE(__bsp_ram_start = .);
+
+ /* Interrupt stack: aligned on a cache-line boundary */
+ . += IntrStackSize;
+ __intrStack = .;
+
+ /* Main stack lives here */
+ _stack = ALIGN(0x10); /* Align to a cache-line boundary */
+ . += StackSize;
+ __stack_base = .; /* Initial stack builds downwards */
+
+ /* RTEMS workspace: size specified by application */
+ WorkAreaBase = ALIGN(0x10); /* Align to a cache-line boundary */
+
+ /* The heap comes after the work space */
+
+ . = RamBase + RamSize;
+ PROVIDE(__bsp_ram_end = .);
+
+ /* Message area for capturing early printk output */
+ /* Placed here to be easily findable with a debugger */
+ MsgAreaBase = .;
+ . += MsgAreaSize;
+
+ __phy_ram_end = .; /* True end of physical memory */
+
+ /DISCARD/ :
+ {
+ *(.comment)
+ }
+
+ /* Some configuration constants: Not clear why they're placed here */
+ __dccr = 0x80000000;
+ __iccr = 0x80000000;
+ __sgr = 0x7fffffff;
+ __vectors = 0;
+}
diff --git a/bsps/powerpc/virtex5/start/bsp_specs b/bsps/powerpc/virtex5/start/bsp_specs
new file mode 100644
index 0000000000..ccbea2690c
--- /dev/null
+++ b/bsps/powerpc/virtex5/start/bsp_specs
@@ -0,0 +1,10 @@
+%rename startfile old_startfile
+%rename endfile old_endfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} \
+%{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/bsps/powerpc/virtex5/start/bspclean.c b/bsps/powerpc/virtex5/start/bspclean.c
new file mode 100644
index 0000000000..bd5829e0b2
--- /dev/null
+++ b/bsps/powerpc/virtex5/start/bspclean.c
@@ -0,0 +1,54 @@
+/*
+ * This routine normally is part of start.s and usually returns
+ * control to a monitor.
+ *
+ * INPUT: NONE
+ *
+ * OUTPUT: NONE
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspclean.c:
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * 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>
+
+static void _noopfun(void) {}
+
+void app_bsp_cleanup(void)
+__attribute__(( weak, alias("_noopfun") ));
+
+void bsp_fatal_extension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code error
+)
+{
+ if ( source == RTEMS_FATAL_SOURCE_EXIT ) {
+ app_bsp_cleanup();
+ }
+
+ /* All done. Hang out. */
+ BSP_ask_for_reset();
+}
diff --git a/bsps/powerpc/virtex5/start/bspstart.c b/bsps/powerpc/virtex5/start/bspstart.c
new file mode 100644
index 0000000000..ff821574a9
--- /dev/null
+++ b/bsps/powerpc/virtex5/start/bspstart.c
@@ -0,0 +1,240 @@
+/*
+ *
+ * This routine starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before this routine is invoked.
+ */
+
+/*
+ * Author: Thomas Doerfler <td@imd.m.isar.de>
+ * IMD Ingenieurbuero fuer Microcomputertechnik
+ *
+ * COPYRIGHT (c) 1998 by IMD
+ *
+ * Changes from IMD are covered by the original distributions terms.
+ * This file has been derived from the papyrus BSP:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Modifications for spooling console driver and control of memory layout
+ * with linker command file by
+ * Thomas Doerfler <td@imd.m.isar.de>
+ * for these modifications:
+ * COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies. IMD makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c:
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modifications for PPC405GP by Dennis Ehlin
+ * Modifications for Virtex5 by Richard Claus <claus@slac.stanford.edu>
+ */
+#include <rtems.h>
+#include <rtems/config.h>
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+#include <rtems/sysinit.h>
+
+#include <libcpu/cpuIdent.h>
+#include <libcpu/spr.h>
+
+#include <bsp.h>
+#include <bsp/vectors.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#define DO_DOWN_ALIGN(x,a) ((x) & ~((a)-1))
+
+#define DO_UP_ALIGN(x,a) DO_DOWN_ALIGN(((x) + (a) - 1 ),a)
+
+#define CPU_DOWN_ALIGN(x) DO_DOWN_ALIGN(x, CPU_ALIGNMENT)
+#define CPU_UP_ALIGN(x) DO_UP_ALIGN(x, CPU_ALIGNMENT)
+
+
+/* Defined in linkcmds linker script */
+LINKER_SYMBOL(RamBase);
+LINKER_SYMBOL(RamSize);
+LINKER_SYMBOL(__bsp_ram_start);
+LINKER_SYMBOL(__bsp_ram_end);
+LINKER_SYMBOL(__rtems_end);
+LINKER_SYMBOL(_stack);
+LINKER_SYMBOL(StackSize);
+LINKER_SYMBOL(__stack_base);
+LINKER_SYMBOL(WorkAreaBase);
+LINKER_SYMBOL(MsgAreaBase);
+LINKER_SYMBOL(MsgAreaSize);
+LINKER_SYMBOL(__phy_ram_end);
+LINKER_SYMBOL(bsp_exc_vector_base);
+
+
+/* Expected by clock.c */
+uint32_t bsp_clicks_per_usec;
+
+/*
+ * Bus Frequency
+ */
+unsigned int BSP_bus_frequency;
+/*
+ * processor clock frequency
+ */
+unsigned int BSP_processor_frequency;
+
+/*
+ * Time base divisior (bus freq / TB clock)
+ */
+unsigned int BSP_time_base_divisor;
+
+/*
+ * Provide weak aliases so that RTEMS distribution builds
+ */
+static void _noopfun(void) {}
+
+
+void app_bsp_start(void)
+__attribute__(( weak, alias("_noopfun") ));
+
+void app_bsp_predriver_hook(void)
+__attribute__(( weak, alias("_noopfun") ));
+
+
+static char* bspMsgBuffer = (char*)MsgAreaBase;
+
+static void __bsp_outchar_to_memory(char c)
+{
+ static char* msgBuffer = (char*)MsgAreaBase;
+ *msgBuffer++ = c;
+ if (msgBuffer >= &bspMsgBuffer[(int)MsgAreaSize]) msgBuffer = bspMsgBuffer;
+ *msgBuffer = 0x00; /* Overwrite next location to show EOM */
+}
+
+
+void BSP_ask_for_reset(void)
+{
+ printk("\nSystem stopped, issue RESET");
+
+ for(;;);
+}
+
+
+/*===================================================================*/
+
+/*
+ * BSP start routine. Called by boot_card().
+ *
+ * This routine does the bulk of the system initialization.
+ */
+void bsp_start(void)
+{
+ uintptr_t intrStackStart;
+ uintptr_t intrStackSize;
+
+ ppc_cpu_id_t myCpu;
+ ppc_cpu_revision_t myCpuRevision;
+
+ /* Set the character output function; The application may override this */
+ BSP_output_char = __bsp_outchar_to_memory;
+
+ printk("RTEMS %s\n", rtems_get_version_string());
+
+ /*
+ * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
+ * function stores the result in global variables so that it can be used later...
+ */
+ myCpu = get_ppc_cpu_type();
+ myCpuRevision = get_ppc_cpu_revision();
+ printk("CPU: 0x%04x, Revision: 0x%04x = %d, Name: %s\n",
+ myCpu, myCpuRevision, myCpuRevision, get_ppc_cpu_type_name(myCpu));
+
+ /*
+ * Initialize the device driver parameters
+ */
+
+ /* For mpc6xx clock driver: */
+ BSP_bus_frequency = 465000000;
+ BSP_processor_frequency = 465000000; /* Measured with a DPM 440 2012/8/13 */
+ BSP_time_base_divisor = 1000;
+
+ /* Timebase register ticks/microsecond; The application may override these */
+ bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
+ rtems_counter_initialize_converter(
+ BSP_bus_frequency / (BSP_time_base_divisor / 1000)
+ );
+
+ /*
+ * Initialize the interrupt related settings.
+ */
+ intrStackStart = CPU_UP_ALIGN((uint32_t)__bsp_ram_start);
+ intrStackSize = rtems_configuration_get_interrupt_stack_size();
+
+ ppc_exc_initialize(intrStackStart, intrStackSize);
+
+ /* Let the user know what parameters we were compiled with */
+ printk(" Base/Start End Size\n"
+ "RAM: %p %p\n"
+ "RTEMS: %p\n"
+ "Interrupt Stack: 0x%08x 0x%x\n"
+ "Stack: %p %p %p\n"
+ "Workspace: %p %p\n"
+ "MsgArea: %p %p\n"
+ "Physical RAM %p\n",
+ RamBase, RamSize,
+ __rtems_end,
+ intrStackStart, intrStackSize,
+ __stack_base, _stack, StackSize,
+ WorkAreaBase, __bsp_ram_end,
+ MsgAreaBase, MsgAreaSize,
+ __phy_ram_end);
+
+ /*
+ * Initialize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mngt_init(0);
+
+ /* Continue with application-specific initialization */
+ app_bsp_start();
+}
+
+
+/*
+ * BSP predriver hook. Called by boot_card() just before drivers are
+ * initialized. Clear out any stale interrupts here.
+ */
+static void virtex5_pre_driver_hook(void)
+{
+ app_bsp_predriver_hook();
+}
+
+RTEMS_SYSINIT_ITEM(
+ virtex5_pre_driver_hook,
+ RTEMS_SYSINIT_BSP_PRE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
diff --git a/bsps/powerpc/virtex5/start/dummy_console.c b/bsps/powerpc/virtex5/start/dummy_console.c
new file mode 100644
index 0000000000..2cdab33c8c
--- /dev/null
+++ b/bsps/powerpc/virtex5/start/dummy_console.c
@@ -0,0 +1,85 @@
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/bspIo.h>
+#include <rtems/console.h>
+
+#include <string.h>
+
+ssize_t app_memory_write(int minor, const char* buf, size_t len)
+__attribute__(( weak, alias("__bsp_memory_write") ));
+
+ssize_t __bsp_memory_write(int minor, const char* buf, size_t len);
+
+ssize_t __bsp_memory_write(int minor, const char* buf, size_t len)
+{
+ const char* const last = buf+len;
+ while (buf < last)
+ {
+ rtems_putc(*buf++);
+ }
+ return len;
+}
+
+static rtems_termios_callbacks gMemCallbacks = {
+ 0, /* firstOpen */
+ 0, /* lastClose */
+ 0, /* PollRead */
+ app_memory_write, /* write */
+ 0, /* SetAttr */
+ 0, /* stopRemoteTx */
+ 0, /* startRemoteTx */
+ 0 /* outputUsesInterrupts */
+};
+
+rtems_device_driver console_initialize(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ rtems_status_code status;
+
+ rtems_termios_initialize();
+
+ status = rtems_io_register_name("/dev/console", major, 0);
+
+ if (status != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (status);
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver console_open(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ rtems_status_code sc;
+
+ sc = rtems_termios_open (major, minor, arg, &gMemCallbacks);
+
+ return sc;
+}
+
+rtems_device_driver console_close(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ return rtems_termios_close(arg);
+}
+
+rtems_device_driver console_read(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ return rtems_termios_read(arg);
+}
+
+rtems_device_driver console_write(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ return rtems_termios_write(arg);
+}
+
+rtems_device_driver console_control(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg)
+{
+ return rtems_termios_ioctl(arg);
+}
diff --git a/bsps/powerpc/virtex5/start/linkcmds b/bsps/powerpc/virtex5/start/linkcmds
new file mode 100644
index 0000000000..9bd7c2e67f
--- /dev/null
+++ b/bsps/powerpc/virtex5/start/linkcmds
@@ -0,0 +1,285 @@
+/*
+ * This file contains directives for the GNU linker which are specific to the
+ * Virtex 5 PPC 440. No assumptions are made on the firmware in the FPGA.
+ * This file is intended to be used together with start.S to generate
+ * downloadable code.
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+
+ENTRY(download_entry)
+EXTERN(download_entry)
+EXTERN(__vectors)
+
+MsgAreaSize = DEFINED(MsgAreaSize) ? MsgAreaSize : 1M;
+RamBase = DEFINED(RamBase) ? RamBase : 0x0;
+RamSize = DEFINED(RamSize) ? RamSize : 2048M - MsgAreaSize;
+IntrStackSize = DEFINED(IntrStackSize) ? IntrStackSize : 16K;
+StackSize = DEFINED(StackSize) ? StackSize : 64K;
+HeapSize = DEFINED(HeapSize) ? HeapSize : 0; /* 0=Use def */
+
+
+MEMORY
+{
+ VECTORS : ORIGIN = 0x00000000, LENGTH = 512
+ RAM : ORIGIN = 0x00000200, LENGTH = 2048M - 512
+}
+
+
+SECTIONS
+{
+ bsp_exc_vector_base = 0;
+ __exeentry = download_entry;
+ __exestart = bsp_exc_vector_base;
+ .vectors bsp_exc_vector_base : { *(.vectors) } > VECTORS
+
+ /* Read-only sections, merged into text segment: */
+ .interp : { *(.interp) } > RAM
+ .hash : { *(.hash) } > RAM
+ .dynsym : { *(.dynsym) } > RAM
+ .dynstr : { *(.dynstr) } > RAM
+ .gnu.version : { *(.gnu.version) } > RAM
+ .gnu.version_d : { *(.gnu.version_d) } > RAM
+ .gnu.version_r : { *(.gnu.version_r) } > RAM
+ .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) } > RAM
+ .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) } > RAM
+ .rela.rodata : { *(.rela.rodata*) *(.rela.gnu.linkonce.r*) } > RAM
+ .rela.got : { *(.rela.got) } > RAM
+ .rela.got1 : { *(.rela.got1) } > RAM
+ .rela.got2 : { *(.rela.got2) } > RAM
+ .rela.ctors : { *(.rela.ctors) } > RAM
+ .rela.dtors : { *(.rela.dtors) } > RAM
+ .rela.init : { *(.rela.init) } > RAM
+ .rela.fini : { *(.rela.fini) } > RAM
+ .rela.bss : { *(.rela.bss) } > RAM
+ .rela.plt : { *(.rela.plt) } > RAM
+ .rela.sdata : { *(.rela.sdata) } > RAM
+ .rela.sbss : { *(.rela.sbss) } > RAM
+ .rela.sdata2 : { *(.rela.sdata2) } > RAM
+ .rela.sbss2 : { *(.rela.sbss2) } > RAM
+ .rela.dyn : { *(.rela.dyn) } > RAM
+
+ /* Initialization code */
+ .init : { PROVIDE (_init = .);
+ *ecrti.o(.init)
+ KEEP(*(.init))
+ *ecrtn.o(.init)
+ } > RAM
+
+ .text : { *(.entry)
+ *(.text)
+ *(.text.*)
+
+ /* Special FreeBSD sysctl sections */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ /* .gnu.warning sections are handled specially by elf32.em
+ */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } > RAM
+
+ /* Finalization code */
+ .fini : { PROVIDE (_fini = .);
+ *ecrti.o(.fini)
+ KEEP(*(.fini))
+ *ecrtn.o(.fini)
+ } > RAM
+
+ /* Miscellaneous read-only data */
+ .rodata : { *(.rodata.* .gnu.linkonce.r*) KEEP (*(SORT(.rtemsroset.*))) } > RAM
+ .rodata1 : { *(.rodata1) } > RAM
+
+ .tdata : {
+ _TLS_Data_begin = .;
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ _TLS_Data_end = .;
+ } >RAM
+
+ .tbss : {
+ _TLS_BSS_begin = .;
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ _TLS_BSS_end = .;
+ } >RAM
+
+ _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));
+
+ /* Initialised small data addressed as offsets from r2 */
+ .sdata2 : { PROVIDE (_SDA2_BASE_ = 32768); *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } > RAM
+
+ /* Zeroed small data addressed as offsets from r2 */
+ .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+
+ /* Avoid empty sdata2/sbss2 area: __eabi would not set up
+ * r2 which may be important if run-time loading is used
+ */
+ . += 1;
+
+ PROVIDE (__SBSS2_END__ = .);
+ } > RAM
+
+ /* Exception frame info */
+ .eh_frame : { *(.eh_frame .eh_frame.*) } > RAM
+ .eh_frame_hdr : { *(.eh_frame_hdr) } > RAM
+
+ /* Declares where the .text section ends */
+ _etext = .;
+ PROVIDE (etext = .);
+
+ /* Initialized R/W Data section goes in RAM */
+ .data : { PROVIDE(__DATA_START__ = ABSOLUTE(.) );
+ *(.data)
+ *(.data.*)
+ KEEP (*(SORT(.rtemsrwset.*)))
+ *(.gnu.linkonce.d*)
+ } > RAM
+
+ .data1 : { *(.data1) } > RAM
+
+ PROVIDE (__EXCEPT_START__ = .);
+ .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } > RAM
+ PROVIDE (__EXCEPT_END__ = .);
+
+ .got1 : { *(.got1) } > RAM
+
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ * get relocated with -mrelocatable. Also put in the .fixup pointers.
+ * The current compiler no longer needs this, but keep it around for 2.7.2.
+ */
+ PROVIDE (_GOT2_START_ = .);
+ .got2 : { *(.got2) } > RAM
+
+ .dynamic : { *(.dynamic) } > RAM
+
+ .ctors : { /* 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))
+ /* 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 ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } > RAM
+
+ .dtors : { KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } > RAM
+
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) } > RAM
+ PROVIDE (_FIXUP_END_ = .);
+
+ PROVIDE (_GOT2_END_ = .);
+
+ PROVIDE (_GOT_START_ = .);
+ .got : { __got_start = .;
+ *(.got)
+ } > RAM
+
+ .got.plt : { *(.got.plt) } > RAM
+ PROVIDE (_GOT_END_ = .);
+
+ .jcr : { KEEP (*(.jcr)) } > RAM
+
+ /* We want the small data sections together, so single-instruction offsets
+ * can access them all, and initialized data all before uninitialized, so
+ * we can shorten the on-disk segment size.
+ */
+ /* Initialised small data addressed as offsets from r13 */
+ .sdata : { PROVIDE (_SDA_BASE_ = 32768); *(.sdata* .gnu.linkonce.s.*) } > RAM
+
+ _edata = .;
+ PROVIDE (edata = .);
+
+ /* Zeroed small data addressed as offsets from r13 */
+ .sbss : { PROVIDE (__sbss_start = .);
+ *(.dynsbss)
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.scommon)
+
+ /* Avoid empty sdata/sbss area: __eabi would not set up
+ * r13, which may be important if run-time loading is used
+ */
+ . += 1;
+
+ PROVIDE (__SBSS_END__ = .);
+ PROVIDE (__sbss_end = .);
+ } > RAM
+
+ .plt : { *(.plt) } > RAM
+ .iplt : { *(.iplt) } > RAM
+
+ /* Zeroed large data */
+ .bss : { PROVIDE (__bss_start = .);
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(.gnu.linkonce.b*)
+ *(COMMON)
+
+ PROVIDE (__bss_end = ALIGN(4));
+ __bss_size = __bss_end - __bss_start;
+ } > RAM
+
+ __exeend = ALIGN(4);
+ __rtems_end = .;
+ . = ALIGN(0x20); /* Align to a cache-line boundary */
+ PROVIDE(__bsp_ram_start = .);
+
+ /* Interrupt stack: aligned on a cache-line boundary */
+ . += IntrStackSize;
+ __intrStack = .;
+
+ /* Main stack lives here */
+ _stack = ALIGN(0x20); /* Align to a cache-line boundary */
+ . += StackSize;
+ __stack_base = .; /* Initial stack builds downwards */
+
+ /* RTEMS workspace: size specified by application */
+ WorkAreaBase = ALIGN(0x20); /* Align to a cache-line boundary */
+
+ /* The heap comes after the work space */
+
+ . = RamBase + RamSize;
+ PROVIDE(__bsp_ram_end = .);
+
+ /* Message area for capturing early printk output */
+ /* Placed here to be easily findable with a debugger */
+ MsgAreaBase = __bsp_ram_end;
+ . += MsgAreaSize;
+
+ __phy_ram_end = .; /* True end of physical memory */
+
+ /DISCARD/ :
+ {
+ *(.comment)
+ }
+
+ /* Some configuration constants */
+ __vectors = 0;
+}