From 41c928242335a544b17b94c6a21baebdc5d8b995 Mon Sep 17 00:00:00 2001 From: Ralf Corsepius Date: Mon, 9 Jan 2006 10:41:21 +0000 Subject: Backport from rtems-4-6-branch. --- c/src/lib/libbsp/sparc/leon3/startup/bspstart.c | 228 ++++++++++++++++++++++++ c/src/lib/libbsp/sparc/leon3/startup/ithread.S | 31 ++++ c/src/lib/libbsp/sparc/leon3/startup/linkcmds | 184 +++++++++++++++++++ c/src/lib/libbsp/sparc/leon3/startup/setvec.c | 64 +++++++ c/src/lib/libbsp/sparc/leon3/startup/spurious.c | 184 +++++++++++++++++++ 5 files changed, 691 insertions(+) create mode 100644 c/src/lib/libbsp/sparc/leon3/startup/bspstart.c create mode 100644 c/src/lib/libbsp/sparc/leon3/startup/ithread.S create mode 100644 c/src/lib/libbsp/sparc/leon3/startup/linkcmds create mode 100644 c/src/lib/libbsp/sparc/leon3/startup/setvec.c create mode 100644 c/src/lib/libbsp/sparc/leon3/startup/spurious.c (limited to 'c/src/lib/libbsp/sparc/leon3/startup') diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bspstart.c b/c/src/lib/libbsp/sparc/leon3/startup/bspstart.c new file mode 100644 index 0000000000..bdce5fa780 --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon3/startup/bspstart.c @@ -0,0 +1,228 @@ +/* + * 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-1999. + * On-Line Applications Research Corporation (OAR). + * + * Modified for LEON3 BSP. + * COPYRIGHT (c) 2004. + * Gaisler Research. + * + * 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$ + */ + +/* must be identical to STACK_SIZE in start.S */ +#define STACK_SIZE 16 * 1024 + +#include + +#include +#include +#include + +/* + * 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; + +/* + * Tells us where to put the workspace in case remote debugger is present. + */ + +extern uint32_t rdb_start; + +/* + * Amount to increment itimer by each pass + * It is a variable instead of a #define to allow the 'looptest' + * script to bump it without recompiling rtems + */ + +uint32_t CPU_SPARC_CLICKS_PER_TICK; + +#if SIMSPARC_FAST_IDLE + +/* + * Many of the tests are very slow on the simulator because they have + * have 5 second delays hardwired in. + * + * Try to speed those tests up by speeding up the clock when in the idle task. + * + * NOTE: At the current setting, 5 second delays in the tests take + * approximately 5 seconds of wall time. + */ + +rtems_extension fast_idle_switch_hook( + rtems_tcb *current_task, + rtems_tcb *heir_task +) +{ + static uint32_t normal_clock = ~0; + static uint32_t fast_clock; + + /* init our params on first call */ + if (normal_clock == ~0) + { + normal_clock = CPU_SPARC_CLICKS_PER_TICK; + fast_clock = CPU_SPARC_CLICKS_PER_TICK / 0x08; + if (fast_clock == 0) /* handle pathological case */ + fast_clock++; + } + + /* + * Run the clock faster when idle is in place. + */ + + if (heir_task == _Thread_Idle) + CPU_SPARC_CLICKS_PER_TICK = fast_clock; + else if (current_task == _Thread_Idle) + CPU_SPARC_CLICKS_PER_TICK = normal_clock; +} + +#endif + +/* + * Use the shared implementations of the following routines + */ + +void bsp_postdriver_hook(void); +void bsp_libc_init( void *, uint32_t, int ); +extern void bsp_spurious_initialize(); + +/* + * bsp_pretasking_hook + * + * BSP pretasking hook. Called just before drivers are initialized. + * Used to setup libc and install any BSP extensions. + */ + +void bsp_pretasking_hook(void) +{ + extern int end; + uint32_t heap_start; + uint32_t heap_size; + + heap_start = (uint32_t) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + heap_size = BSP_Configuration.work_space_start - (void *)&end - STACK_SIZE; + heap_size &= 0xfffffff0; /* keep it as a multiple of 16 bytes */ + + bsp_libc_init((void *) heap_start, heap_size, 0); + +#if SIMSPARC_FAST_IDLE + /* + * Install the fast idle task switch extension + * + * On MP systems, might not want to do this; it confuses at least + * one test (mp06) if the simulators are running too far from real time. + */ + +#if 0 + if (BSP_Configuration.User_multiprocessing_table == 0) +#endif + { + rtems_extensions_table fast_idle_extension; + rtems_id extension_id; + rtems_status_code rc; + + memset(&fast_idle_extension, 0, sizeof(fast_idle_extension)); + + fast_idle_extension.thread_switch = fast_idle_switch_hook; + + rc = rtems_extension_create( + rtems_build_name('F', 'D', 'L', 'E'), + &fast_idle_extension, + &extension_id + ); + if (rc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(rc); + } +#endif + +#ifdef RTEMS_DEBUG + rtems_debug_enable( RTEMS_DEBUG_ALL_MASK ); +#endif + + bsp_spurious_initialize(); +} + +void bsp_leon3_predriver_hook(void); + +/* + * bsp_start + * + * This routine does the bulk of the system initialization. + */ + +void bsp_start( void ) +{ + unsigned char *work_space_start; + + /* + * 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.predriver_hook = bsp_leon3_predriver_hook; /* scan system bus */ + + /* + * SIS does zero out memory BUT only when IT begins execution. Thus + * if we want to have a clean slate in the workspace each time we + * begin execution of OUR application, then we must zero the workspace. + */ + Cpu_table.do_zero_of_workspace = TRUE; + + /* + * This should be enough interrupt stack. + */ + + Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY; + + work_space_start = + (unsigned char *)rdb_start - BSP_Configuration.work_space_size; + + if ( work_space_start <= (unsigned char *)&end ) { + DEBUG_puts( "bspstart: Not enough RAM!!!\n" ); + BSP_fatal_return(); + } + + BSP_Configuration.work_space_start = work_space_start; + +#if SIMSPARC_FAST_IDLE + /* + * Add 1 extension for fast idle + */ + + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add 1 extension for MPCI_fatal + */ + + if (BSP_Configuration.User_multiprocessing_table) + BSP_Configuration.maximum_extensions++; + + /* + * Set the "clicks per tick" for the simulator + * used by XXX/clock/clock.c to schedule interrupts + */ + + CPU_SPARC_CLICKS_PER_TICK = BSP_Configuration.microseconds_per_tick; +} diff --git a/c/src/lib/libbsp/sparc/leon3/startup/ithread.S b/c/src/lib/libbsp/sparc/leon3/startup/ithread.S new file mode 100644 index 0000000000..0d2b567d02 --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon3/startup/ithread.S @@ -0,0 +1,31 @@ +/* + * Idle Thread Body + * + * This routine puts LEON3 in power-down mode. + * + * COPYRIGHT (c) 2004. + * Gaisler Research. + * + * 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 + +/* LEON specific power-down function */ + + .align 4 + PUBLIC(_CPU_Thread_Idle_body) +SYM(_CPU_Thread_Idle_body): +pwdloop: mov %g0, %asr19 + ba pwdloop + nop + retl + nop + diff --git a/c/src/lib/libbsp/sparc/leon3/startup/linkcmds b/c/src/lib/libbsp/sparc/leon3/startup/linkcmds new file mode 100644 index 0000000000..4e4f06f2a6 --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon3/startup/linkcmds @@ -0,0 +1,184 @@ +/* linkcmds + * + * $Id$ + */ + +OUTPUT_ARCH(sparc) +__DYNAMIC = 0; + +/* + * The memory map looks like this: + * +--------------------+ <- low memory + * | .text | + * | etext | + * | ctor list | the ctor and dtor lists are for + * | dtor list | C++ support + * | _endtext | + * +--------------------+ + * | .data | initialized data goes here + * | _sdata | + * | _edata | + * +--------------------+ + * | .bss | + * | __bss_start | start of bss, cleared by crt0 + * | _end | start of heap, used by sbrk() + * +--------------------+ + * | heap space | + * | _ENDHEAP | + * | stack space | + * | __stack | top of stack + * +--------------------+ <- high memory + */ + + +/* + * User modifiable values: + * + * _CLOCK_SPEED in Mhz (used to program the counter/timers) + * + * _PROM_SIZE size of PROM (permissible values are 128K, 256K, + * 512K, 1M, 2M, 4M, 8M and 16M) + * _RAM_SIZE size of RAM (permissible values are 256K, 512K, + * 1M, 2M, 4M, 8M, 16M, and 32M) + * + */ + +/* Default values, can be overridden */ + +_PROM_SIZE = 2M; +_RAM_SIZE = 4M; + +_RAM_START = 0x40000000; +_RAM_END = _RAM_START + _RAM_SIZE; + +_PROM_START = 0x00000000; +_PROM_END = _PROM_START + _PROM_SIZE; + +/* + * Alternate names without leading _. + */ + +PROM_START = _PROM_START; +PROM_SIZE = _PROM_SIZE; +PROM_END = _PROM_END; + +RAM_START = _RAM_START; +RAM_SIZE = _RAM_SIZE; +RAM_END = _RAM_END; + +/* + * Base address of the on-CPU peripherals + */ + +_LEON_REG = 0x80000000; +LEON_REG = 0x80000000; + +/* these are the maximum values */ + +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 256M + ram : ORIGIN = 0x40000000, LENGTH = 1024M +} + +/* + * stick everything in ram (of course) + */ +SECTIONS +{ + .text : + { + CREATE_OBJECT_SYMBOLS + text_start = .; + _text_start = .; + *(.text) + . = ALIGN (16); + + /* + * Special FreeBSD sysctl sections. + */ + . = ALIGN (16); + __start_set_sysctl_set = .; + *(set_sysctl_*); + __stop_set_sysctl_set = ABSOLUTE(.); + *(set_domain_*); + *(set_pseudo_*); + + *(.eh_frame) + . = ALIGN (16); + + *(.gnu.linkonce.t*) + + /* + * C++ constructors + */ + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + + _rodata_start = . ; + *(.rodata*) + *(.gnu.linkonce.r*) + _erodata = ALIGN( 0x10 ) ; + + etext = ALIGN(0x10); + _etext = .; + *(.init) + *(.fini) + *(.lit) + *(.shdata) + . = ALIGN (16); + _endtext = .; + } > ram + .data : + { + data_start = .; + _data_start = .; + _sdata = . ; + *(.data) + *(.gnu.linkonce.d*) + *(.gcc_except_table) + . = ALIGN(0x10); + edata = .; + _edata = .; + } > ram + .dynamic : { *(.dynamic) } >ram + .jcr : { *(.jcr) } >ram + .got : { *(.got) } >ram + .plt : { *(.plt) } >ram + .hash : { *(.hash) } >ram + .dynrel : { *(.dynrel) } >ram + .dynsym : { *(.dynsym) } >ram + .dynstr : { *(.dynstr) } >ram + .hash : { *(.hash) } >ram + .shbss : + { + *(.shbss) + } > ram + .bss : + { + __bss_start = ALIGN(0x8); + _bss_start = .; + bss_start = .; + *(.bss) + *(COMMON) + end = .; + _end = ALIGN(0x8); + __end = ALIGN(0x8); + } > ram + .stab . (NOLOAD) : + { + [ .stab ] + } + .stabstr . (NOLOAD) : + { + [ .stabstr ] + } +} diff --git a/c/src/lib/libbsp/sparc/leon3/startup/setvec.c b/c/src/lib/libbsp/sparc/leon3/startup/setvec.c new file mode 100644 index 0000000000..123306c5db --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon3/startup/setvec.c @@ -0,0 +1,64 @@ +/* set_vector + * + * This routine installs an interrupt vector on the SPARC simulator. + * + * INPUT PARAMETERS: + * handler - interrupt handler entry point + * vector - vector number + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * OUTPUT PARAMETERS: NONE + * + * RETURNS: + * address of previous interrupt handler + * + * 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.com/license/LICENSE. + * + * Ported to LEON implementation of the SPARC by On-Line Applications + * Research Corporation (OAR) under contract to the European Space + * Agency (ESA). + * + * LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995. + * European Space Agency. + * + * $Id$ + */ + +#include + +rtems_isr_entry set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +) +{ + rtems_isr_entry previous_isr; + uint32_t real_trap; + uint32_t source; + + if ( type ) + rtems_interrupt_catch( handler, vector, &previous_isr ); + else + _CPU_ISR_install_raw_handler( vector, handler, (void *)&previous_isr ); + + real_trap = SPARC_REAL_TRAP_NUMBER( vector ); + + if ( LEON_INT_TRAP( real_trap ) ) { + + source = LEON_TRAP_SOURCE( real_trap ); + + LEON_Clear_interrupt( source ); + LEON_Unmask_interrupt( source ); + } + + return previous_isr; +} + + + diff --git a/c/src/lib/libbsp/sparc/leon3/startup/spurious.c b/c/src/lib/libbsp/sparc/leon3/startup/spurious.c new file mode 100644 index 0000000000..b638404eac --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon3/startup/spurious.c @@ -0,0 +1,184 @@ +/* + * LEON Spurious Trap Handler + * + * This is just enough of a trap handler to let us know what + * the likely source of the trap was. + * + * Developed as part of the port of RTEMS to the LEON implementation + * of the SPARC by On-Line Applications Research Corporation (OAR) + * under contract to the European Space Agency (ESA). + * + * COPYRIGHT (c) 1995. European Space Agency. + * + * Modified for LEON3 BSP. + * COPYRIGHT (c) 2004. + * Gaisler Research. + * + * This terms of the RTEMS license apply to this file. + * + * $Id$ + */ + +#include + +#include + +static const char digits[16] = "0123456789abcdef"; + +/* Simple integer-to-string conversion */ + +void itos(uint32_t u, char *s) +{ + int i; + + for (i=0; i<8; i++) { + s[i] = digits[(u >> (28 - (i*4))) & 0x0f]; + } +} + +/* + * bsp_spurious_handler + * + * Print a message on the debug console and then die + */ + +rtems_isr bsp_spurious_handler( + rtems_vector_number trap, + CPU_Interrupt_frame *isf +) +{ + char line[ 80 ]; + uint32_t real_trap; + + real_trap = SPARC_REAL_TRAP_NUMBER(trap); + + strcpy(line, "Unexpected trap (0x ) at address 0x "); + line[ 19 ] = digits[ real_trap >> 4 ]; + line[ 20 ] = digits[ real_trap & 0xf ]; + itos(isf->tpc, &line[36]); + DEBUG_puts( line ); + + switch (real_trap) { + + /* + * First the ones defined by the basic architecture + */ + + case 0x00: + DEBUG_puts( "reset" ); + break; + case 0x01: + DEBUG_puts( "instruction access exception" ); + break; + case 0x02: + DEBUG_puts( "illegal instruction" ); + break; + case 0x03: + DEBUG_puts( "privileged instruction" ); + break; + case 0x04: + DEBUG_puts( "fp disabled" ); + break; + case 0x07: + DEBUG_puts( "memory address not aligned" ); + break; + case 0x08: + DEBUG_puts( "fp exception" ); + break; + case 0x09: + strcpy(line, "data access exception at 0x " ); + /* itos(LEON_REG.Failed_Address, &line[27]); FIXME */ + DEBUG_puts( line ); + break; + case 0x0A: + DEBUG_puts( "tag overflow" ); + break; + + /* + * Then the ones defined by the LEON in particular + */ + /* FIXME */ + + /* + case LEON_TRAP_TYPE( LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR ): + DEBUG_puts( "LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_2_RX_TX ): + DEBUG_puts( "LEON_INTERRUPT_UART_2_RX_TX" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_1_RX_TX ): + DEBUG_puts( "LEON_INTERRUPT_UART_1_RX_TX" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_0 ): + DEBUG_puts( "LEON_INTERRUPT_EXTERNAL_0" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_1 ): + DEBUG_puts( "LEON_INTERRUPT_EXTERNAL_1" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_2 ): + DEBUG_puts( "LEON_INTERRUPT_EXTERNAL_2" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_3 ): + DEBUG_puts( "LEON_INTERRUPT_EXTERNAL_3" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER1 ): + DEBUG_puts( "LEON_INTERRUPT_TIMER1" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER2 ): + DEBUG_puts( "LEON_INTERRUPT_TIMER2" ); + break; + */ + + default: + break; + } + + /* + * What else can we do but stop ... + */ + + asm volatile( "mov 1, %g1; ta 0x0" ); +} + +/* + * bsp_spurious_initialize + * + * Install the spurious handler for most traps. Note that set_vector() + * will unmask the corresponding asynchronous interrupt, so the initial + * interrupt mask is restored after the handlers are installed. + */ + +void bsp_spurious_initialize() +{ + uint32_t trap; + uint32_t level; + /* uint32_t mask; */ + + level = sparc_disable_interrupts(); + /* mask = LEON3_IrqCtrl_Regs->mask_p0; */ + + for ( trap=0 ; trap<256 ; trap++ ) { + + /* + * Skip window overflow, underflow, and flush as well as software + * trap 0 which we will use as a shutdown. Also avoid trap 0x70 - 0x7f + * which cannot happen and where some of the space is used to pass + * paramaters to the program. + */ + + if (( trap == 5 || trap == 6 ) || + (( trap >= 0x11 ) && ( trap <= 0x1f )) || + (( trap >= 0x70 ) && ( trap <= 0x83 ))) + continue; + + set_vector( + (rtems_isr_entry) bsp_spurious_handler, + SPARC_SYNCHRONOUS_TRAP( trap ), + 1 + ); + } + + /* LEON3_IrqCtrl_Regs->mask_p0 = mask; */ + sparc_enable_interrupts(level); + +} -- cgit v1.2.3