summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/leon3/startup
diff options
context:
space:
mode:
authorRalf Corsepius <ralf.corsepius@rtems.org>2006-01-09 10:41:21 +0000
committerRalf Corsepius <ralf.corsepius@rtems.org>2006-01-09 10:41:21 +0000
commit41c928242335a544b17b94c6a21baebdc5d8b995 (patch)
tree62fe57379a186de08e0d08545401ed250463f6de /c/src/lib/libbsp/sparc/leon3/startup
parent2006-01-09 Ralf Corsepius <ralf.corsepius@rtems.org> (diff)
downloadrtems-41c928242335a544b17b94c6a21baebdc5d8b995.tar.bz2
Backport from rtems-4-6-branch.
Diffstat (limited to 'c/src/lib/libbsp/sparc/leon3/startup')
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/bspstart.c228
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/ithread.S31
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/linkcmds184
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/setvec.c64
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/spurious.c184
5 files changed, 691 insertions, 0 deletions
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 <string.h>
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+
+/*
+ * 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 <rtems/asm.h>
+
+/* 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 <bsp.h>
+
+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 <bsp.h>
+
+#include <string.h>
+
+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);
+
+}