diff options
author | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2008-09-08 09:55:39 +0000 |
---|---|---|
committer | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2008-09-08 09:55:39 +0000 |
commit | 63de714ce7c0869715687c728f84efd048cba550 (patch) | |
tree | 65af9691a920ba4300d1e1fe5209fb6696cd815f /c/src/lib/libbsp/powerpc/tqm8xx/startup | |
parent | added support for flexible PLL in MPC866 and friends (diff) | |
download | rtems-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.c | 234 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/tqm8xx/startup/cpuinit.c | 134 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.base | 316 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.tqm8xx | 15 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/tqm8xx/startup/mmutlbtab.c | 103 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/tqm8xx/startup/start.S | 287 |
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: |