summaryrefslogtreecommitdiffstats
path: root/bsps/sparc/shared/start/start.S
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 10:19:28 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 13:08:36 +0200
commitfbcd7c8fa65eb695e96a62ea1c1ac7a024fa9dfc (patch)
treea17e285cf22cd49cd42e8b3ad562febc3987d566 /bsps/sparc/shared/start/start.S
parentbsps: Move console drivers to bsps (diff)
downloadrtems-fbcd7c8fa65eb695e96a62ea1c1ac7a024fa9dfc.tar.bz2
bsps: Move start files to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'bsps/sparc/shared/start/start.S')
-rw-r--r--bsps/sparc/shared/start/start.S374
1 files changed, 374 insertions, 0 deletions
diff --git a/bsps/sparc/shared/start/start.S b/bsps/sparc/shared/start/start.S
new file mode 100644
index 0000000000..64498c6110
--- /dev/null
+++ b/bsps/sparc/shared/start/start.S
@@ -0,0 +1,374 @@
+/**
+ * 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.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * 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.org/license/LICENSE.
+ */
+
+#include <rtems/asm.h>
+#include <rtems/score/percpu.h>
+#include <bspopts.h>
+
+#if defined(RTEMS_SMP) && defined(BSP_LEON3_SMP)
+ #define START_LEON3_ENABLE_SMP
+#endif
+
+/*
+ * Unexpected trap will halt the processor by forcing it to error state
+ */
+#define BAD_TRAP \
+ ta 0; \
+ nop; \
+ nop; \
+ nop;
+
+/*
+ * System call optimized trap table entry
+ */
+#define FPDIS_TRAP(_handler) \
+ mov %psr, %l0 ; \
+ sethi %hi(_handler), %l4 ; \
+ jmp %l4+%lo(_handler); \
+ sethi %hi(SPARC_PSR_EF_MASK), %l3
+
+/*
+ * System call optimized trap table entry
+ */
+#define IRQDIS_TRAP(_handler) \
+ mov %psr, %l0 ; \
+ sethi %hi(_handler), %l4 ; \
+ jmp %l4+%lo(_handler); \
+ or %l0, 0x0f00, %l3; ! Set PIL=0xf to disable IRQ
+
+/*
+ * System call optimized trap table entry
+ */
+#define IRQEN_TRAP(_handler) \
+ mov %psr, %l0 ; \
+ sethi %hi(_handler), %l4 ; \
+ jmp %l4+%lo(_handler); \
+ andn %l0, 0xf00, %l3; ! Set PIL=0 to Enable IRQ
+
+/*
+ * Window Overflow optimized trap table entry
+ */
+#define WOTRAP(_vector, _handler) \
+ sethi %hi(_handler), %l4; \
+ jmp %l4+%lo(_handler); \
+ save; \
+ nop
+
+/*
+ * Window Underflow optimized trap table entry
+ */
+#define WUTRAP(_vector, _handler) \
+ mov %wim, %l3 ; \
+ sethi %hi(_handler), %l4 ; \
+ jmp %l4+%lo(_handler); \
+ sll %l3, 1, %l4 ! l4 = WIM << 1
+
+/*
+ * Software trap. Treat as BAD_TRAP for the time being...
+ */
+
+#define SOFT_TRAP BAD_TRAP
+
+ .section ".text"
+ PUBLIC(start)
+ .global start, __bsp_mem_init
+
+SYM(start):
+#if SYM(start) != start
+start:
+#endif
+
+/*
+ * 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
+#if defined(SPARC_USE_LAZY_FP_SWITCH)
+ FPDIS_TRAP(SYM(syscall_lazy_fp_switch)); ! 04 fp disabled
+#else
+ BAD_TRAP; ! 04 fp disabled
+#endif
+ WOTRAP(5, SYM(window_overflow_trap_handler)); ! 05 window overflow
+ WUTRAP(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)
+
+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 halt 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; ! 88
+
+ /*
+ * SW Trap 9-15 Reserved for Operating System
+ *
+ * SPARC_SWTRAP_IRQDIS
+ * SPARC_SWTRAP_IRQEN
+ */
+ IRQDIS_TRAP(SYM(syscall_irqdis)); ! 89 IRQ Disable syscall trap
+ IRQEN_TRAP(SYM(syscall_irqen)); ! 8A IRQ Enable syscall trap
+#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
+ IRQDIS_TRAP(SYM(syscall_irqdis_fp)); ! 8B IRQ disable
+ ! and set PSR[EF] syscall trap
+#else
+ SOFT_TRAP; ! 8B
+#endif
+ 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
+
+ mov %psr, %g1 ! Initialize WIM
+ add %g1, 1, %g2
+ and %g2, 0x7, %g2
+ set 1, %g3
+ sll %g3, %g2, %g3
+ mov %g3, %wim
+
+ or %g1, 0xf20, %g1
+ wr %g1, %psr ! enable traps and disable ints
+
+ nop
+ nop
+ nop
+
+ sethi %hi(_Per_CPU_Information), %g6 ! get per-CPU control
+ add %g6, %lo(_Per_CPU_Information), %g6
+
+#if defined(START_LEON3_ENABLE_SMP)
+ rd %asr17, %o0 ! get CPU identifier
+ srl %o0, LEON3_ASR17_PROCESSOR_INDEX_SHIFT, %o0
+
+ sll %o0, PER_CPU_CONTROL_SIZE_LOG2, %l0
+ add %g6, %l0, %g6
+
+ /* If LEON3_Boot_Cpu < 0 then assign us as boot CPU and continue. */
+ set SYM(LEON3_Boot_Cpu), %o1
+ ld [%o1], %o2
+ tst %o2
+ bneg .Lbootcpu
+ nop
+
+ ld [%g6 + PER_CPU_INTERRUPT_STACK_HIGH], %sp ! set stack pointer
+ sub %sp, 4, %sp ! stack starts at end of area - 4
+ andn %sp, 0x0f, %sp ! align stack on 16-byte boundary
+ mov %sp, %fp ! set frame pointer
+
+ call SYM(bsp_start_on_secondary_processor) ! does not return
+ sub %sp, SPARC_MINIMUM_STACK_FRAME_SIZE, %sp
+.Lbootcpu:
+ st %o0, [%o1]
+#endif
+
+ set (SYM(rdb_start)), %g5 ! End of RAM
+ st %sp, [%g5]
+ sub %sp, 4, %sp ! stack starts at end of RAM - 4
+ andn %sp, 0x0f, %sp ! align stack on 16-byte boundary
+ mov %sp, %fp ! Set frame pointer
+ nop
+
+ /*
+ * Copy the initialized data to RAM
+ *
+ * FROM: _data_load_start
+ * TO: _data_start
+ * LENGTH: (__bss_start - _data_start) bytes
+ */
+
+ sethi %hi(_data_load_start),%g1 ! g1 = start of initialized data in ROM
+ or %g1,%lo(_data_load_start),%g1
+
+ sethi %hi(_data_start),%g3 ! g3 = start of initialized data in RAM
+ or %g3,%lo(_data_start),%g3
+
+ sethi %hi(__bss_start), %g2 ! g2 = end of initialized data in RAM
+ or %g2,%lo(__bss_start),%g2
+
+ cmp %g1, %g3
+ be 1f
+ nop
+
+copy_data:
+ ldd [%g1], %g4
+ std %g4 , [%g3] ! copy this double word
+ add %g3, 8, %g3 ! bump the destination pointer
+ add %g1, 8, %g1 ! bump the source pointer
+ cmp %g3, %g2 ! Is the pointer past the end of dest?
+ bl copy_data
+ nop
+
+ /* clear the bss */
+1:
+
+ 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 %g0, %o0 ! command line
+ call SYM(boot_card) ! does not return
+ sub %sp, 0x60, %sp ! room for boot_card to save args
+
+/* end of file */