summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mcp750/startup
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mcp750/startup')
-rw-r--r--c/src/lib/libbsp/powerpc/mcp750/startup/Makefile.in56
-rw-r--r--c/src/lib/libbsp/powerpc/mcp750/startup/bspstart.c303
-rw-r--r--c/src/lib/libbsp/powerpc/mcp750/startup/cEntry.c121
-rw-r--r--c/src/lib/libbsp/powerpc/mcp750/startup/linkcmds147
4 files changed, 627 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/mcp750/startup/Makefile.in b/c/src/lib/libbsp/powerpc/mcp750/startup/Makefile.in
new file mode 100644
index 0000000000..79838ba910
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mcp750/startup/Makefile.in
@@ -0,0 +1,56 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@:
+VPATH = @srcdir@:@srcdir@/../console:@srcdir@/../../../shared:
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=main bspstart bsppost bsplibc sbrk bspclean
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=consoleLib
+S_FILES=$(S_PIECES:%=%.S)
+S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(S_O_FILES) $(C_O_FILES) $(CC_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+all: ${ARCH} $(SRCS) $(OBJS)
+ $(INSTALL_VARIANT) -m 555 ${PGM} ${PROJECT_RELEASE}/lib
+ $(INSTALL_CHANGE) @srcdir@/linkcmds ${PROJECT_RELEASE}/lib
+
+${PROJECT_RELEASE}/lib/libbsp.a:
+ cd ../wrapup; $(MAKE)
diff --git a/c/src/lib/libbsp/powerpc/mcp750/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mcp750/startup/bspstart.c
new file mode 100644
index 0000000000..83703a2271
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mcp750/startup/bspstart.c
@@ -0,0 +1,303 @@
+/*
+ * 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.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <libcsupport.h>
+#include <string.h>
+#include <bsp/consoleIo.h>
+#include <libcpu/spr.h>
+#include <bsp/residual.h>
+#include <bsp/pci.h>
+#include <bsp/openpic.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <libcpu/bat.h>
+#include <bsp/vectors.h>
+
+extern void _return_to_ppcbug();
+extern unsigned long __rtems_end;
+extern unsigned long _end;
+extern unsigned long __bss_start;
+extern void L1_caches_enables();
+extern unsigned get_L2CR();
+extern void set_L2CR(unsigned);
+/*
+ * Copy of residuals passed by firmware
+ */
+RESIDUAL residualCopy;
+/*
+ * Copy Additional boot param passed by boot loader
+ */
+#define MAX_LOADER_ADD_PARM 80
+char loaderParam[MAX_LOADER_ADD_PARM];
+/*
+ * Vital Board data Start using DATA RESIDUAL
+ */
+/*
+ * 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;
+/*
+ * system init stack and soft ir stack size
+ */
+#define INIT_STACK_SIZE 0x1000
+#define INTR_STACK_SIZE 0x4000
+
+void BSP_panic(char *s)
+{
+ printk("RTEMS 4.x PANIC %s\n", s);
+ _return_to_ppcbug();
+}
+
+void _BSP_Fatal_error(unsigned int v)
+{
+ printk("RTEMS 4.x PANIC ERROR %x\n", v);
+ _return_to_ppcbug();
+}
+
+/*
+ * The original table from the application and our copy of it with
+ * some changes.
+ */
+
+extern rtems_configuration_table Configuration;
+
+rtems_configuration_table BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+
+char *rtems_progname;
+
+/*
+ * Use the shared implementations of the following routines
+ */
+
+void bsp_postdriver_hook(void);
+void bsp_libc_init( void *, unsigned32, int );
+
+/*
+ * Function: bsp_pretasking_hook
+ * Created: 95/03/10
+ *
+ * Description:
+ * BSP pretasking hook. Called just before drivers are initialized.
+ * Used to setup libc and install any BSP extensions.
+ *
+ * NOTES:
+ * Must not use libc (to do io) from here, since drivers are
+ * not yet initialized.
+ *
+ */
+
+void bsp_pretasking_hook(void)
+{
+ extern int end;
+ rtems_unsigned32 heap_start;
+
+ heap_start = ((rtems_unsigned32) &__rtems_end) +INIT_STACK_SIZE + INTR_STACK_SIZE;
+ if (heap_start & (CPU_ALIGNMENT-1))
+ heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
+
+ bsp_libc_init((void *) heap_start, 64 * 1024, 0);
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+void zero_bss()
+{
+ memset(&__bss_start, 0, &__rtems_end - &__bss_start);
+}
+
+void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
+{
+
+ residualCopy = *r3;
+ strncpy(loaderParam, additional_boot_options, MAX_LOADER_ADD_PARM);
+ loaderParam[MAX_LOADER_ADD_PARM - 1] ='\0';
+}
+
+/*
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ */
+
+void bsp_start( void )
+{
+ int err;
+ unsigned char *stack;
+ unsigned l2cr;
+ register unsigned char* intrStack;
+ register unsigned int intrNestingLevel = 0;
+ unsigned char *work_space_start;
+
+ /*
+ * enables L1 Cache
+ */
+ L1_caches_enables();
+ /*
+ * Enable L2 Cache
+ */
+ l2cr = get_L2CR();
+#ifdef SHOW_LCR2_REGISTER
+ printk("Initial L2CR value = %x\n", l2cr);
+#endif
+ if (! (l2cr & 0x80000000))
+ set_L2CR(0xb9A14000);
+ /*
+ * the initial stack has aready been set to this value in start.S
+ * so there is no need to set it in r1 again...
+ */
+ stack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE;
+ /*
+ * 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...
+ */
+ intrStack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE;
+ asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack));
+ asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel));
+ /*
+ * Initialize default raw exception hanlders. See vectors/vectors_init.c
+ */
+ initialize_exceptions();
+ select_console(CONSOLE_LOG);
+
+ /* We check that the keyboard is present and immediately
+ * select the serial console if not.
+ */
+ err = kbdreset();
+ if (err) select_console(CONSOLE_SERIAL);
+
+
+ printk("-----------------------------------------\n");
+ printk("Welcome to RTEMS 4.1.1 on Motorola MCP750\n");
+ printk("-----------------------------------------\n");
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Residuals are located at %x\n", (unsigned) &residualCopy);
+ printk("Additionnal boot options are %s\n", loaderParam);
+ printk("Initial system stack at %x\n",stack);
+ printk("Software IRQ stack at %x\n",intrStack);
+ printk("-----------------------------------------\n");
+#endif
+
+#ifdef TEST_RETURN_TO_PPCBUG
+ printk("Hit <Enter> to return to PPCBUG monitor\n");
+ printk("When Finished hit GO. It should print <Back from monitor>\n");
+ debug_getc();
+ _return_to_ppcbug();
+ printk("Back from monitor\n");
+ _return_to_ppcbug();
+#endif /* TEST_RETURN_TO_PPCBUG */
+
+ /*
+ * Init MMU block address translation to enable hardware
+ * access
+ */
+ /*
+ * PC legacy IO space used for inb/outb and all PC
+ * compatible hardware
+ */
+ setdbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
+ /*
+ * PCI devices memory area. Needed to access OPENPIC features
+ * provided by the RAVEN
+ */
+ setdbat(2, 0xc0000000, 0xc0000000, 0x08000000, IO_PAGE);
+ /*
+ * Must have acces to open pic PCI ACK registers
+ * provided by the RAVEN
+ */
+ setdbat(3, 0xfeff0000, 0xfeff0000, 0x10000, IO_PAGE);
+
+ printk("Going to start PCI buses scanning and initialization\n");
+ InitializePCI();
+ printk("Number of PCI buses is found : %d\n", BusCountPCI());
+
+#ifdef TEST_RAW_EXCEPTION_CODE
+ printk("Testing exception handling Part 1\n");
+ /*
+ * Cause a software exception
+ */
+ __asm__ __volatile ("sc");
+ /*
+ * Check we can still catch exceptions and returned coorectly.
+ */
+ printk("Testing exception handling Part 2\n");
+ __asm__ __volatile ("sc");
+#endif
+
+
+ BSP_mem_size = residualCopy.TotalMemory;
+ BSP_bus_frequency = residualCopy.VitalProductData.ProcessorBusHz;
+ BSP_processor_frequency = residualCopy.VitalProductData.ProcessorHz;
+ BSP_time_base_divisor = (residualCopy.VitalProductData.TimeBaseDivisor?
+ residualCopy.VitalProductData.TimeBaseDivisor : 4000);
+
+ /*
+ * Set up our hooks
+ * Make sure libc_init is done before drivers initialized so that
+ * they can use atexit()
+ */
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+ Cpu_table.do_zero_of_workspace = TRUE;
+ Cpu_table.interrupt_stack_size = INTR_STACK_SIZE;
+ Cpu_table.clicks_per_usec = BSP_processor_frequency/(BSP_time_base_divisor * 1000);
+ Cpu_table.exceptions_in_RAM = TRUE;
+
+ printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size);
+ work_space_start =
+ (unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size;
+
+ if ( work_space_start <= ((unsigned char *)&__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE) {
+ printk( "bspstart: Not enough RAM!!!\n" );
+ bsp_cleanup();
+ }
+
+ BSP_Configuration.work_space_start = work_space_start;
+
+ /*
+ * Account for the console's resources
+ */
+
+ console_reserve_resources( &BSP_Configuration );
+ /*
+ * Initalize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mng_init(0);
+ printk("Exit from bspstart\n");
+}
diff --git a/c/src/lib/libbsp/powerpc/mcp750/startup/cEntry.c b/c/src/lib/libbsp/powerpc/mcp750/startup/cEntry.c
new file mode 100644
index 0000000000..b92bff21be
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mcp750/startup/cEntry.c
@@ -0,0 +1,121 @@
+/*
+ *
+ */
+#include <bsp/consoleIo.h>
+#include <libcpu/spr.h>
+#include <bsp/residual.h>
+#include <bsp/pci.h>
+#include <bsp/openpic.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <libcpu/bat.h>
+
+extern void _return_to_ppcbug();
+extern unsigned long __rtems_end;
+
+RESIDUAL residualCopy;
+#define INIT_STACK_SIZE 0x1000
+#define INTR_STACK_SIZE 0x4000
+
+void BSP_panic(char *s)
+{
+ printk("RTEMS 4.x PANIC %s\n", s);
+ _return_to_ppcbug();
+}
+
+void _BSP_Fatal_error(unsigned int v)
+{
+ printk("RTEMS 4.x PANIC ERROR %x\n", v);
+ _return_to_ppcbug();
+}
+
+void
+boot_card(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
+{
+ int err;
+ unsigned char *stack;
+ unsigned l2cr;
+ register unsigned char* intrStack;
+ register unsigned int intrNestingLevel = 0;
+
+ L1_caches_enables();
+ stack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE;
+ intrStack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE;
+ asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack));
+ asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel));
+ residualCopy = *r3;
+#define NO_DYNAMIC_EXCEPTION_VECTOR_INSTALL
+#undef NO_DYNAMIC_EXCEPTION_VECTOR_INSTALL
+#ifndef NO_DYNAMIC_EXCEPTION_VECTOR_INSTALL
+ initialize_exceptions();
+#endif
+ select_console(CONSOLE_LOG);
+
+ /* We check that the keyboard is present and immediately
+ * select the serial console if not.
+ */
+ err = kbdreset();
+ if (err) select_console(CONSOLE_SERIAL);
+
+
+ printk("Welcome to RTEMS 4.0.2 on Motorola MCP750\n\n\n");
+ printk("-----------------------------------------\n");
+ printk("Residuals are located at %x\n", (unsigned) r3);
+ printk("Additionnal boot options are %s\n", additional_boot_options);
+ printk("-----------------------------------------\n");
+
+ printk("Initial system stack at %x\n",stack);
+ l2cr = get_L2CR();
+ printk("Initial L2CR value = %x\n", l2cr);
+ if (! (l2cr & 0x80000000))
+ set_L2CR(0xb9A14000);
+#ifdef TEST_RETURN_TO_PPCBUG
+ printk("Hit <Enter> to return to PPCBUG monitor\n");
+ printk("When Finished hit GO. It should print <Back from monitor>\n");
+ debug_getc();
+ _return_to_ppcbug();
+ printk("Back from monitor\n");
+ _return_to_ppcbug();
+#endif /* TEST_RETURN_TO_PPCBUG */
+
+ /*
+ * Init MMU block address translation to enable hardware
+ * access
+ */
+ /*
+ * PC legacy IO space used for inb/outb and all PC
+ * compatible hardware
+ */
+ setdbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
+ /*
+ * PCI devices memory area. Needed to access OPENPIC features
+ * provided by the RAVEN
+ */
+ setdbat(2, 0xc0000000, 0xc0000000, 0x08000000, IO_PAGE);
+ /*
+ * Must have acces to open pic PCI ACK registers
+ * provided by the RAVEN
+ */
+ setdbat(3, 0xfeff0000, 0xfeff0000, 0x10000, IO_PAGE);
+
+ printk("Going to start PCI buses scanning and initialization\n");
+ InitializePCI();
+ printk("Number of PCI buses is found : %d\n", BusCountPCI());
+#ifdef TEST_RAW_EXCEPTION_CODE
+ printk("Testing exception handling Part 1\n");
+ /*
+ * Cause a software exception
+ */
+ __asm__ __volatile ("sc");
+ /*
+ * Check we can still catch exceptions
+ */
+ printk("Testing exception handling Part 2\n");
+ __asm__ __volatile ("sc");
+#endif
+ BSP_rtems_irq_mng_init(0);
+ printk("Init done\n");
+ debug_getc();
+ while(1);
+}
+
diff --git a/c/src/lib/libbsp/powerpc/mcp750/startup/linkcmds b/c/src/lib/libbsp/powerpc/mcp750/startup/linkcmds
new file mode 100644
index 0000000000..0eb6628de9
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mcp750/startup/linkcmds
@@ -0,0 +1,147 @@
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
+ "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+ENTRY(_start)
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+PROVIDE (__stack = 0);
+MEMORY {
+ VECTORS : ORIGIN = 0x0 , LENGTH = 0x3000
+ CODE : ORIGIN = 0x3000 , LENGTH = 0x100000
+}
+SECTIONS
+{
+ .entry_point_section :
+ {
+ *(.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
+ .text :
+ {
+ *(.text)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } > CODE
+ .init : { *(.init) } > CODE
+ .fini : { *(.fini) } > CODE
+ .rodata : { *(.rodata) *(.gnu.linkonce.r*) } > CODE
+ .rodata1 : { *(.rodata1) } > CODE
+ _etext = .;
+ PROVIDE (etext = .);
+ .sdata2 : { *(.sdata2) } > CODE
+ .sbss2 : { *(.sbss2) } > CODE
+ /* 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 :
+ {
+ *(.data)
+ *(.gnu.linkonce.d*)
+ CONSTRUCTORS
+ } > CODE
+ .data1 : { *(.data1) } > CODE
+ PROVIDE (__EXCEPT_START__ = .);
+ .gcc_except_table : { *(.gcc_except_table) } > CODE
+ PROVIDE (__EXCEPT_END__ = .);
+ .got1 : { *(.got1) } > CODE
+ .dynamic : { *(.dynamic) } > 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
+ PROVIDE (__CTOR_LIST__ = .);
+ .ctors : { *(.ctors) } > CODE
+ PROVIDE (__CTOR_END__ = .);
+ PROVIDE (__DTOR_LIST__ = .);
+ .dtors : { *(.dtors) } > CODE
+ PROVIDE (__DTOR_END__ = .);
+ 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_ = .);
+ /* 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 : { *(.sdata) } > CODE
+ _edata = .;
+ PROVIDE (edata = .);
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ *(.sbss)
+ *(.scommon)
+ *(.dynsbss)
+ PROVIDE (__sbss_end = .);
+ } > CODE
+ .plt : { *(.plt) } > CODE
+ .bss :
+ {
+ PROVIDE (__bss_start = .);
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(16);
+ } > CODE
+ . = ALIGN(16);
+ _end = . ;
+ __rtems_end = . ;
+ PROVIDE (end = .);
+ /DISCARD/ :
+ {
+ *(.comment)
+ }
+}