summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/tqm8xx/startup
diff options
context:
space:
mode:
authorThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2008-09-08 09:55:39 +0000
committerThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2008-09-08 09:55:39 +0000
commit63de714ce7c0869715687c728f84efd048cba550 (patch)
tree65af9691a920ba4300d1e1fe5209fb6696cd815f /c/src/lib/libbsp/powerpc/tqm8xx/startup
parentadded support for flexible PLL in MPC866 and friends (diff)
downloadrtems-63de714ce7c0869715687c728f84efd048cba550.tar.bz2
added new BSP for TQM8xx boards
Diffstat (limited to 'c/src/lib/libbsp/powerpc/tqm8xx/startup')
-rw-r--r--c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c234
-rw-r--r--c/src/lib/libbsp/powerpc/tqm8xx/startup/cpuinit.c134
-rw-r--r--c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.base316
-rw-r--r--c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.tqm8xx15
-rw-r--r--c/src/lib/libbsp/powerpc/tqm8xx/startup/mmutlbtab.c103
-rw-r--r--c/src/lib/libbsp/powerpc/tqm8xx/startup/start.S287
6 files changed, 1089 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c
new file mode 100644
index 0000000000..2b4b38fe87
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c
@@ -0,0 +1,234 @@
+/**
+ * @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.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+#include <rtems/score/thread.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+/* #include <bsp/irq-generic.h>
+ #include <bsp/ppc_exc_bspsupp.h> */
+
+#ifdef BSP_HAS_TQMMON
+/*
+ * FIXME: TQ Monitor structure
+ */
+#endif /* BSP_HAS_TQMMON */
+
+/* Configuration parameters for console driver, ... */
+unsigned int BSP_bus_frequency;
+
+/* Configuration parameters for clock driver, ... */
+uint32_t bsp_clicks_per_usec; /* for PIT driver: OSCCLK */
+uint32_t bsp_clock_speed ; /* needed for PIT driver */
+
+/*
+ * Use the shared implementations of the following routines.
+ * Look in rtems/c/src/lib/libbsp/shared/bsplibc.c.
+ */
+extern void cpu_init( void);
+
+void BSP_panic( char *s)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable( level);
+
+ printk( "%s PANIC %s\n", _RTEMS_version, s);
+
+ while (1) {
+ /* Do nothing */
+ }
+}
+
+void _BSP_Fatal_error( unsigned n)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable( level);
+
+ printk( "%s PANIC ERROR %u\n", _RTEMS_version, n);
+
+ while (1) {
+ /* Do nothing */
+ }
+}
+
+void bsp_pretasking_hook( void)
+{
+ /* Do noting */
+}
+
+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(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);
+ }
+}
+
+rtems_status_code bsp_tqm_get_cib_uint32( const char *cib_id,
+ uint32_t *result)
+{
+ const char *item_ptr;
+ const 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_get_work_area( void **work_area_start, size_t *work_area_size, void **heap_start, size_t *heap_size)
+{
+ char *ram_end = (char *) (TQM_BD_INFO.sdram_size - (uint32_t)TopRamReserved);
+
+ *work_area_start = bsp_work_area_start;
+ *work_area_size = ram_end - bsp_work_area_start;
+ *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
+ *heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT;
+}
+
+void bsp_start( void)
+{
+ ppc_cpu_id_t myCpu;
+ ppc_cpu_revision_t myCpuRevision;
+
+ uint32_t interrupt_stack_start = (uint32_t) bsp_interrupt_stack_start;
+ uint32_t interrupt_stack_size = (uint32_t) bsp_interrupt_stack_size;
+
+ /*
+ * 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...
+ */
+ myCpu = get_ppc_cpu_type();
+ myCpuRevision = get_ppc_cpu_revision();
+
+ /* Basic CPU initialization */
+ cpu_init();
+
+ /*
+ * Enable instruction and data caches. Do not force writethrough mode.
+ */
+
+#if INSTRUCTION_CACHE_ENABLE
+ rtems_cache_enable_instruction();
+#endif
+
+#if DATA_CACHE_ENABLE
+ 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)) {
+ BSP_panic("Cannot determine BUS frequency\n");
+ }
+
+ bsp_clicks_per_usec = 0; /* force to zero to control
+ * PIT clock driver from EXTCLK
+ */
+ bsp_clock_speed = BSP_bus_frequency;
+
+ /* Initialize exception handler */
+ ppc_exc_initialize(PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
+ interrupt_stack_start,
+ interrupt_stack_size
+ );
+
+ /* Initalize interrupt support */
+ if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
+ BSP_panic("Cannot intitialize interrupt support\n");
+ }
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Exit from bspstart\n");
+#endif
+}
+
+/**
+ * @brief Idle thread body.
+ *
+ * Replaces the one in c/src/exec/score/src/threadidlebody.c
+ * 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.
+ */
+Thread _Thread_Idle_body( uint32_t ignored)
+{
+
+ while (1) {
+ asm volatile (
+ "mfmsr 3;"
+ "oris 3, 3, 4;"
+ "sync;"
+ "mtmsr 3;"
+ "isync;"
+ "ori 3, 3, 0;"
+ "ori 3, 3, 0"
+ );
+ }
+
+ return NULL;
+}
diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/startup/cpuinit.c b/c/src/lib/libbsp/powerpc/tqm8xx/startup/cpuinit.c
new file mode 100644
index 0000000000..e99e9d9a6a
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/cpuinit.c
@@ -0,0 +1,134 @@
+/*
+ * 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.com/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)
+{
+ /*
+ * none up to now
+ */
+}
diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.base b/c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.base
new file mode 100644
index 0000000000..c4a0eec115
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.base
@@ -0,0 +1,316 @@
+/**
+ * @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)
+
+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_section_align = 32;
+
+SECTIONS {
+
+ dpram :
+ {
+ m8xx = .;
+ _m8xx = .;
+ /* . += (16 * 1024); this makes the mbx loader crash */
+ } >immr
+
+ /*
+ * 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.*)
+ *(.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
+
+ .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 and size of text section
+ */
+ bsp_section_text_end = .;
+ bsp_section_text_size = bsp_section_text_end - bsp_section_text_start;
+ } > 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 (*(.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 and size of data section
+ */
+ bsp_section_data_end = .;
+ bsp_section_data_size = bsp_section_data_end - bsp_section_data_start;
+ } > 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 and size of bss section
+ */
+ bsp_section_bss_end = .;
+ bsp_section_bss_size = bsp_section_bss_end - bsp_section_bss_start;
+ } > RAM
+
+ /*
+ * BSP: Interrupt stack
+ */
+ bsp_interrupt_stack_start = .;
+ bsp_interrupt_stack_end = bsp_interrupt_stack_start + 32k;
+ bsp_interrupt_stack_size = bsp_interrupt_stack_end - bsp_interrupt_stack_start;
+ . = bsp_interrupt_stack_end;
+
+ /*
+ * BSP: Work area start
+ */
+ 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) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+
+ /DISCARD/ : {
+ *(.note.GNU-stack) *(.gnu_debuglink)
+ }
+
+ /*
+ * BSP: Catch all unknown sections
+ */
+ .nirvana : {
+ *(*)
+ } > NIRVANA
+}
diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.tqm8xx b/c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.tqm8xx
new file mode 100644
index 0000000000..69b9c32799
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.tqm8xx
@@ -0,0 +1,15 @@
+/**
+ * @file
+ *
+ * TQM8xx
+ */
+
+TopRamReserved = DEFINED(TopRamReserved) ? TopRamReserved : 0;
+MEMORY {
+ RAM : ORIGIN = 0x0, LENGTH = 128M
+ immr : org = 0xfa200000, l = 16K
+ ROM : ORIGIN = 0x40000000, LENGTH = 8M
+ NIRVANA : ORIGIN = 0x0, LENGTH = 0
+}
+
+INCLUDE linkcmds.base
diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/startup/mmutlbtab.c b/c/src/lib/libbsp/powerpc/tqm8xx/startup/mmutlbtab.c
new file mode 100644
index 0000000000..6dc3aea712
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/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.com/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.com/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/c/src/lib/libbsp/powerpc/tqm8xx/startup/start.S b/c/src/lib/libbsp/powerpc/tqm8xx/startup/start.S
new file mode 100644
index 0000000000..42bbdb07d2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/start.S
@@ -0,0 +1,287 @@
+/*===============================================================*\
+| Project: RTEMS generic TQM8xx BSP |
++-----------------------------------------------------------------+
+| 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.com/license/LICENSE. |
+| |
++-----------------------------------------------------------------+
+| this file contains the startup assembly code |
+| it is based on the gen83xx BSP |
+\*===============================================================*/
+/* $Id$ */
+
+#include <libcpu/powerpc-utility.h>
+#include <rtems/powerpc/cache.h>
+#include <bsp.h>
+#include <mpc8xx.h>
+
+.extern boot_card
+
+.section ".entry"
+PUBLIC_VAR (start)
+start:
+
+ /*
+ * basic CPU setup:
+ * init MSR
+ */
+ mfmsr r30
+ SETBITS r30, r29, MSR_ME|MSR_RI
+ CLRBITS r30, r29, MSR_IP|MSR_EE
+ mtmsr r30 /* Set RI/ME, Clr EE in MSR */
+ /*
+ * init IMMR
+ */
+ LA r30,m8xx
+ mtspr immr,r30
+ /*
+ * determine current execution address offset
+ */
+ bl start_1
+start_1:
+ mflr r20
+ LA r30,start_1
+ sub. r20,r20,r30
+ /*
+ * execution address offset == 0?
+ * then do not relocate code and data
+ */
+ beq start_code_in_ram
+ /*
+ * ROM or relocatable startup: copy startup code to SDRAM
+ */
+ /* get start address of text section in RAM */
+ LA r29, bsp_section_text_start
+ /* get start address of text section in ROM (add reloc offset) */
+ add r30, r20, r29
+ /* get size of startup code */
+ LA r28, end_reloc_startup
+ LA r31, bsp_section_text_start
+ sub 28,r28,r31
+ /* copy startup code from ROM to RAM location */
+ bl copy_image
+
+ /*
+ * jump to code copy in SDRAM
+ */
+ /* get compile time address of label */
+ LA r29, copy_rest_of_text
+ mtlr r29
+ blr /* now further execution RAM */
+copy_rest_of_text:
+ /*
+ * ROM or relocatable startup: copy rest of code to SDRAM
+ */
+ /* get start address of rest of code in RAM */
+ LA r29, end_reloc_startup
+ /* get start address of text section in ROM (add reloc offset) */
+ add r30, r20, r29
+ /* get size of rest of code */
+ LA r28, bsp_section_text_start
+ LA r31, bsp_section_text_size
+ add r28,r28,r31
+ sub r28,r28,r29
+ bl copy_image /* copy text section from ROM to RAM location */
+
+ /*
+ * ROM or relocatable startup: copy data to SDRAM
+ */
+ /* get start address of data section in RAM */
+ LA r29, bsp_section_data_start
+ /* get start address of data section in ROM (add reloc offset) */
+ add r30, r20, r29
+ /* get size of RAM image */
+ LA r28, bsp_section_data_size
+ /* copy initialized data section from ROM to RAM location */
+ bl copy_image
+
+start_code_in_ram:
+
+ /*
+ * ROM/RAM startup: clear bss in SDRAM
+ */
+ LA r3, bsp_section_bss_start /* get start address of bss section */
+ LWI r4, bsp_section_bss_size /* get size of bss section */
+ bl mpc8xx_zero_4 /* Clear the bss section */
+ /*
+ * call boot_card
+ */
+
+ /* Set stack pointer (common for RAM/ROM startup) */
+ LA r1, bsp_section_text_start
+ addi r1, r1, -0x10 /* Set up stack pointer = beginning of text section - 0x10 */
+
+ /* Create NULL */
+ li r0, 0
+
+ /* Return address */
+ stw r0, 4(r1)
+
+ /* Back chain */
+ stw r0, 0(r1)
+
+ /* Read-only small data */
+ LA r2, _SDA2_BASE_
+
+ /* Read-write small data */
+ LA r13, _SDA_BASE_
+
+ /*
+ * init some CPU stuff
+ */
+ bl SYM (_InitTQM8xx)
+
+/* clear arguments and do further init. in C (common for RAM/ROM startup) */
+
+ /* Clear argc, argv and envp */
+ xor r3, r3, r3
+ xor r4, r4, r4
+ xor r5, r5, r5
+
+ bl SYM (boot_card) /* Call the first C routine */
+
+twiddle:
+ /* We don't expect to return from boot_card but if we do */
+ /* wait here for watchdog to kick us into hard reset */
+ b twiddle
+
+copy_with_watchdog:
+ addi r5,r5,16
+ rlwinm. r5,r5,28,4,31
+ mtctr r5
+
+copy_loop:
+ lwz r6,0(r3)
+ lwz r7,4(r3)
+ lwz r8,8(r3)
+ lwz r9,12(r3)
+ stw r6,0(r4)
+ stw r7,4(r4)
+ stw r8,8(r4)
+ stw r9,12(r4)
+ addi r3,r3,16
+ addi r4,r4,16
+ sth r28,14(r30)
+ sth r29,14(r30)
+ bdnz+ copy_loop
+ blr
+
+copy_image:
+ /*
+ * watchdog:
+ * r26 = immr
+ * r25 = watchdog magic 1
+ * r24 = watchdog magic 2
+ */
+ mfimmr r26
+ rlwinm. r26,r26,0,0,15
+ li r25,0x556c
+ li r24,0xffffaa39
+
+ mr r27, r28 /* determine number of 4word chunks */
+ srwi r28, r28, 4
+ mtctr r28
+
+ slwi r28, r28, 4
+ sub r27, r27, r28 /* determine residual bytes */
+copy_image_4word:
+ lwz r20, 0(r30) /* fetch data */
+ lwz r21, 4(r30)
+ lwz r22, 8(r30)
+ lwz r23,12(r30)
+ stw r20, 0(r29) /* store data */
+ stw r21, 4(r29)
+ stw r22, 8(r29)
+ stw r23,12(r29)
+
+ addi r30, r30, 0x10 /* increment source pointer */
+ addi r29, r29, 0x10 /* increment destination pointer */
+ /*
+ * trigger watchdog
+ */
+ sth r25,14(r26)
+ sth r24,14(r26)
+
+ bdnz copy_image_4word /* decrement ctr and branch if not 0 */
+
+ cmpwi r27, 0x00 /* copy image finished ? */
+ beq copy_image_end;
+ mtctr r27 /* reload counter for residual bytes */
+copy_image_byte:
+ lswi r28, r30, 0x01
+
+ stswi r28, r29, 0x01 /* do byte copy ROM -> RAM */
+
+
+ addi r30, r30, 0x01 /* increment source pointer */
+ addi r29, r29, 0x01 /* increment destination pointer */
+
+ bdnz copy_image_byte /* decrement ctr and branch if not 0 */
+
+copy_image_end:
+ blr
+
+
+/**
+ * @fn int mpc8xx_zero_4( void *dest, size_t n)
+ *
+ * @brief Zero all @a n bytes starting at @a dest with 4 byte writes.
+ *
+ * The address @a dest has to be aligned on 4 byte boundaries. The size @a n
+ * must be evenly divisible by 4.
+ */
+GLOBAL_FUNCTION mpc8xx_zero_4
+ /* Create zero */
+ xor r0, r0, r0
+
+ /* Set offset */
+ xor r5, r5, r5
+
+ /* Loop counter for the first bytes up to 16 bytes */
+ rlwinm. r9, r4, 30, 30, 31
+ beq mpc8xx_zero_4_more
+ mtctr r9
+
+mpc8xx_zero_4_head:
+
+ stwx r0, r3, r5
+ addi r5, r5, 4
+ bdnz mpc8xx_zero_4_head
+
+mpc8xx_zero_4_more:
+
+ /* More than 16 bytes? */
+ srwi. r9, r4, 4
+ beqlr
+ mtctr r9
+
+ /* Set offsets */
+ addi r6, r5, 4
+ addi r7, r5, 8
+ addi r8, r5, 12
+
+mpc8xx_zero_4_tail:
+
+ stwx r0, r3, r5
+ addi r5, r5, 16
+ stwx r0, r3, r6
+ addi r6, r6, 16
+ stwx r0, r3, r7
+ addi r7, r7, 16
+ stwx r0, r3, r8
+ addi r8, r8, 16
+ bdnz mpc8xx_zero_4_tail
+
+ /* Return */
+ blr
+
+end_reloc_startup: