2000-11-13 Jiri Gaisler <jgais@ws.estec.esa.nl>

* ChangeLog, .cvsignore, Makefile.am, bspclean.c, bspstart.c,
	gnatcommon.c, start.S:  New files.  Largely moved from ERC32
	BSP to be able to be shared with LEON and other SPARC BSPs.
This commit is contained in:
Joel Sherrill
2000-11-13 22:31:22 +00:00
parent 270042352b
commit 3eec211fd2
5 changed files with 685 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
all-local:
EXTRA_DIST = bspclean.c bspstart.c gnatcommon.c start.S
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,37 @@
/* bspclean.c
*
* This file contains cleanup code executed when the application exits.
*
* COPYRIGHT (c) 1989-1999.
* 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.OARcorp.com/rtems/license.html.
*
* Ported to ERC32 implementation of the SPARC by On-Line Applications
* Research Corporation (OAR) under contract to the European Space
* Agency (ESA).
*
* ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995.
* European Space Agency.
*
* $Id$
*/
#include <bsp.h>
/*
* The app has "exited" (rtems_shutdown_executive returns control to main)
*/
void bsp_cleanup( void )
{
/*
* "halt" by trapping to the simulator command line.
* set %g1 to 1 to detect clean exit.
*/
asm volatile( "mov 1, %g1; ta 0" );
}

View File

@@ -0,0 +1,232 @@
/*
* 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).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* Ported to ERC32 implementation of the SPARC by On-Line Applications
* Research Corporation (OAR) under contract to the European Space
* Agency (ESA).
*
* ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995.
* European Space Agency.
*
* $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 rtems_unsigned32 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
*
* NOTE: This is based on the PA-RISC simulator. I don't know if we
* can actually pull this trick on the SPARC simulator.
*/
rtems_unsigned32 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 rtems_unsigned32 normal_clock = ~0;
static rtems_unsigned32 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 *, unsigned32, 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;
rtems_unsigned32 heap_start;
rtems_unsigned32 heap_size;
heap_start = (rtems_unsigned32) &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) on the PA-RISC simulator
*/
#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();
}
/*
* 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;
/*
* 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;
}

View File

@@ -0,0 +1,114 @@
/*
*
* Support for gnat/rtems interrupts and exception handling.
* Jiri Gaisler, ESA/ESTEC, 17-02-1999.
*
*/
#include <bsp.h>
#include <signal.h>
/*
* Synchronous trap handler. Map the trap number of SIGFPE, SIGSEGV
* or SIGILL to generate the corresponding Ada exception.
*/
rtems_isr __gnat_exception_handler
(rtems_vector_number trap)
{
rtems_unsigned32 real_trap;
rtems_unsigned32 signal;
real_trap = SPARC_REAL_TRAP_NUMBER (trap);
switch (real_trap)
{
case 0x08: /* FPU exception */
case 0x0A: /* TAG overflow */
case 0x82: /* divide by zero */
signal = SIGFPE; /* Will cause Constraint_Error */
break;
case 0x01: /* Instruction access exception */
case 0x09: /* Data access exception */
signal = SIGSEGV; /* Will cause Storage_Error */
break;
default: /* Anything else ... */
signal = SIGILL; /* Will cause Program_Error */
break;
}
kill (getpid (), signal);
}
/*
* Asynchronous trap handler. As it happens, the interrupt trap numbers for
* SPARC is 17 - 31, so we just map then directly on the same signal number.
*/
rtems_isr __gnat_interrupt_handler
(rtems_vector_number trap)
{
rtems_unsigned32 real_trap;
real_trap = SPARC_REAL_TRAP_NUMBER (trap);
kill (getpid (), real_trap);
}
/*
* Default signal handler with error reporting
*/
void
__gnat_signals_Abnormal_termination_handler (int signo)
{
switch (signo)
{
case SIGFPE:
DEBUG_puts ("\nConstraint_Error\n");
break;
case SIGSEGV:
DEBUG_puts ("\nStorage_Error\n");
break;
default:
DEBUG_puts ("\nProgram_Error\n");
break;
}
exit (1);
}
const struct sigaction __gnat_error_vector =
{0, -1,
{__gnat_signals_Abnormal_termination_handler}};
void
__gnat_install_handler_common (int t1, int t2)
{
rtems_unsigned32 trap;
rtems_isr_entry previous_isr;
sigaction (SIGSEGV, &__gnat_error_vector, NULL);
sigaction (SIGFPE, &__gnat_error_vector, NULL);
sigaction (SIGILL, &__gnat_error_vector, NULL);
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. 0x80 for system traps and
* 0x81 - 0x83 by the remote debugging stub.
* Avoid two bsp specific interrupts which normally are used
* by the real-time clock and UART B.
*/
if ((trap >= 0x11) && (trap <= 0x1f))
{
if ((trap != t1) && (trap != t2))
rtems_interrupt_catch (__gnat_interrupt_handler, trap, &previous_isr);
}
else if ((trap != 5 && trap != 6) && ((trap < 0x70) || (trap > 0x83)))
set_vector (__gnat_exception_handler, SPARC_SYNCHRONOUS_TRAP (trap), 1);
}
}

View File

@@ -0,0 +1,288 @@
/*
* start.s
*
* Common start code for SPARC.
*
* This is based on the file srt0.s provided with the binary
* distribution of the SPARC Instruction Simulator (SIS) found
* at ftp://ftp.estec.esa.nl/pub/ws/wsd/erc32.
*
* $Id$
*/
#include <asm.h>
/*
* Unexpected trap will halt the processor by forcing it to error state
*/
#define BAD_TRAP \
ta 0; \
nop; \
nop; \
nop;
/*
* Software trap. Treat as BAD_TRAP for the time being...
*/
#define SOFT_TRAP BAD_TRAP
.seg "text"
PUBLIC(start)
.global start, __bsp_mem_init
SYM(start):
start:
/*
* The trap table has to be the first code in a boot PROM. But because
* the Memory Configuration comes up thinking we only have 4K of PROM, we
* cannot have a full trap table and still have room left over to
* reprogram the Memory Configuration register correctly. This file
* uses an abbreviated trap which has every entry which might be used
* before RTEMS installs its own trap table.
*/
PUBLIC(trap_table)
SYM(trap_table):
RTRAP( 0, SYM(hard_reset) ); ! 00 reset trap
BAD_TRAP; ! 01 instruction access
! exception
BAD_TRAP; ! 02 illegal instruction
BAD_TRAP; ! 03 privileged instruction
BAD_TRAP; ! 04 fp disabled
TRAP( 5, SYM(window_overflow_trap_handler) ); ! 05 window overflow
TRAP( 6, SYM(window_underflow_trap_handler) );! 06 window underflow
BAD_TRAP; ! 07 memory address not aligned
BAD_TRAP; ! 08 fp exception
BAD_TRAP; ! 09 data access exception
BAD_TRAP; ! 0A tag overflow
BAD_TRAP; ! 0B undefined
BAD_TRAP; ! 0C undefined
BAD_TRAP; ! 0D undefined
BAD_TRAP; ! 0E undefined
BAD_TRAP; ! 0F undefined
BAD_TRAP; ! 10 undefined
/*
* ERC32 defined traps
*/
BAD_TRAP; ! 11 masked errors
BAD_TRAP; ! 12 external 1
BAD_TRAP; ! 13 external 2
BAD_TRAP; ! 14 UART A RX/TX
BAD_TRAP; ! 15 UART B RX/TX
BAD_TRAP; ! 16 correctable memory error
BAD_TRAP; ! 17 UART error
BAD_TRAP; ! 18 DMA access error
BAD_TRAP; ! 19 DMA timeout
BAD_TRAP; ! 1A external 3
BAD_TRAP; ! 1B external 4
BAD_TRAP; ! 1C general purpose timer
BAD_TRAP; ! 1D real time clock
BAD_TRAP; ! 1E external 5
BAD_TRAP; ! 1F watchdog timeout
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 20 - 23 undefined
BAD_TRAP; ! 24 cp_disabled
BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 25 - 27 undefined
BAD_TRAP; ! 28 cp_exception
BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 29 - 2B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 2C - 2F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30 - 33 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34 - 37 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38 - 3B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3C - 3F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40 - 43 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44 - 47 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48 - 4B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4C - 4F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50 - 53 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54 - 57 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58 - 5B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5C - 5F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60 - 63 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64 - 67 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68 - 6B undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6C - 6F undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70 - 73 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74 - 77 undefined
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78 - 7B undefined
/*
This is a sad patch to make sure that we know where the
MEC timer control register mirror is so we can stop the timers
from an external debugger. It is needed because the control
register is write-only. Trap 0x7C cannot occure in ERC32...
We also use this location to store the last location of the
usable RAM in order not to overwrite the remote debugger with
the RTEMS work-space area.
*/
.global SYM(_ERC32_MEC_Timer_Control_Mirror), SYM(rdb_start), SYM(CLOCK_SPEED)
.global SYM(Configuration)
SYM(rdb_start):
SYM(_ERC32_MEC_Timer_Control_Mirror):
BAD_TRAP; BAD_TRAP; ! 7C - 7D undefined
SYM(CLOCK_SPEED):
.word 0x0a, 0, 0, 0 ! 7E (10 MHz default)
BAD_TRAP; ! 7F undefined
/*
* Software traps
*
* NOTE: At the risk of being redundant... this is not a full
* table. The setjmp on the SPARC requires a window flush trap
* handler and RTEMS will preserve the entries that were
* installed before.
*/
TRAP( 0x80, SYM(syscall) ); ! 80 syscall SW trap
SOFT_TRAP; SOFT_TRAP; ! 81 - 82
TRAP( 0x83, SYM(window_flush_trap_handler) ); ! 83 flush windows SW trap
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84 - 87
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88 - 8B
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8C - 8F
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90 - 93
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94 - 97
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98 - 9B
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9C - 9F
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A0 - A3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A4 - A7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A8 - AB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! AC - AF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B0 - B3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B4 - B7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B8 - BB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! BC - BF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C0 - C3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C4 - C7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C8 - CB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! CC - CF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D0 - D3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D4 - D7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D8 - DB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! DC - DF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E0 - E3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E4 - E7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E8 - EB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! EC - EF
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F0 - F3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F4 - F7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F8 - FB
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! FC - FF
/*
* This is the hard reset code.
*/
#define PSR_INIT 0x10c0 /* Disable traps, set s and ps */
#define WIM_INIT 2
#define STACK_SIZE 16 * 1024
PUBLIC(hard_reset)
SYM(hard_reset):
/* Common initialisation */
set SYM(trap_table), %g1 ! Initialize TBR
mov %g1, %tbr
set WIM_INIT, %g1 ! Initialize WIM
mov %g1, %wim
set PSR_INIT, %g1
wr %g1, 0x20, %psr ! enable traps
nop
nop
nop
call __bsp_board_init
nop
set (SYM(rdb_start)), %g6 ! End of work-space area
st %sp, [%g6]
set (SYM(Configuration)), %l1
ld [%l1+4], %l3 ! work_space_size
sub %sp, %l3, %sp ! set %sp to area below work_space
andn %sp, 0x0f, %sp ! align stack on 16-byte boundary
mov %sp, %fp ! Set frame pointer
nop
/*
* Copy the initialized data to RAM
*
* FROM: _endtext
* TO: _data_start
* LENGTH: (__bss_start - _data_start) bytes
*/
sethi %hi(_endtext),%g2
or %g2,%lo(_endtext),%g2 ! g2 = start of initialized data in ROM
sethi %hi(_data_start),%g3
or %g3,%lo(_data_start),%g3 ! g3 = start of initialized data in RAM
sethi %hi(__bss_start),%g4
or %g4,%lo(__bss_start),%g4 ! g4 = end of initialized data in RAM
cmp %g2, %g3
be 1f
nop
copy_data:
ldd [ %g2 ], %g6
std %g6 , [ %g3 ] ! copy this double word
add %g3, 8, %g3 ! bump the destination pointer
add %g2, 8, %g2 ! bump the source pointer
cmp %g3, %g4 ! Is the pointer past the end of dest?
bl copy_data
nop
/* clear the bss */
1:
sethi %hi(_edata),%g2
or %g2,%lo(_edata),%g2 ! g2 = start of bss
sethi %hi(_end),%g3
or %g3,%lo(_end),%g3 ! g3 = end of bss
mov %g0,%g1 ! so std has two zeros
zerobss:
std %g0,[%g2]
add %g2,8,%g2
cmp %g2,%g3
bleu,a zerobss
nop
mov %0, %o2 ! environ
mov %0, %o1 ! argv
mov %0, %o0 ! argc
call SYM(boot_card)
sub %sp, 0x60, %sp ! room for boot_card to save args
nop
PUBLIC(BSP_fatal_return)
SYM(BSP_fatal_return):
mov 1, %g1
ta 0 ! Halt if _main returns ...
nop
/* end of file */