source: rtems/c/src/lib/libbsp/sparc/shared/start/start.S @ 0d3b5d47

4.11
Last change on this file since 0d3b5d47 was 0d3b5d47, checked in by Daniel Hellstrom <daniel@…>, on Nov 11, 2014 at 2:18:01 PM

SPARC: optimize window underflow trap

Save five instructions on underflow handling.

By using an optimized trap entry we can move instructions from
the window underflow function into the trap entry vector. By
setting WIM=0 and using RESTORE it is possible to move the
new WIM register content from the trapped window into the
to-be-restored register window. It is then possible to avoid
the WIM write delay.

  • Property mode set to 100644
File size: 12.8 KB
Line 
1/**
2 *  Common start code for SPARC.
3 *
4 *  This is based on the file srt0.s provided with the binary
5 *  distribution of the SPARC Instruction Simulator (SIS) found
6 *  at ftp://ftp.estec.esa.nl/pub/ws/wsd/erc32.
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2011.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#include <rtems/asm.h>
19#include <rtems/score/percpu.h>
20#include <bspopts.h>
21
22#if defined(RTEMS_SMP) && defined(BSP_LEON3_SMP)
23  #define START_LEON3_ENABLE_SMP
24#endif
25
26/*
27 *  Unexpected trap will halt the processor by forcing it to error state
28 */
29#define BAD_TRAP \
30  ta 0; \
31  nop; \
32  nop; \
33  nop;
34
35/*
36 * System call optimized trap table entry
37 */
38#define SYSCALL_TRAP(_vector, _handler)  \
39  mov   %psr, %l0 ; \
40  sethi %hi(_handler), %l4 ; \
41  jmp   %l4+%lo(_handler); \
42   subcc %g1, 3, %g0; ! prepare for syscall 3 check
43
44/*
45 * Window Overflow optimized trap table entry
46 */
47#define WOTRAP(_vector, _handler)  \
48  sethi %hi(_handler), %l4; \
49  jmp   %l4+%lo(_handler); \
50    save; \
51  nop
52
53/*
54 * Window Underflow optimized trap table entry
55 */
56#define WUTRAP(_vector, _handler)  \
57  mov   %wim, %l3 ; \
58  sethi %hi(_handler), %l4 ; \
59  jmp   %l4+%lo(_handler); \
60   mov  %g0, %wim ! WIM = 0, so that we can restore regardless of WIM
61
62/*
63 *  Software trap. Treat as BAD_TRAP for the time being...
64 */
65
66#define SOFT_TRAP BAD_TRAP
67
68  .seg    "text"
69  PUBLIC(start)
70  .global start, __bsp_mem_init
71
72SYM(start):
73start:
74
75/*
76 *  The trap table has to be the first code in a boot PROM.  But because
77 *  the Memory Configuration comes up thinking we only have 4K of PROM, we
78 *  cannot have a full trap table and still have room left over to
79 *  reprogram the Memory Configuration register correctly.  This file
80 *  uses an abbreviated trap which has every entry which might be used
81 *  before RTEMS installs its own trap table.
82 */
83
84  PUBLIC(trap_table)
85SYM(trap_table):
86
87  RTRAP( 0, SYM(hard_reset) );                  ! 00 reset trap
88  BAD_TRAP;                                     ! 01 instruction access
89                                                !    exception
90  BAD_TRAP;                                     ! 02 illegal instruction
91  BAD_TRAP;                                     ! 03 privileged instruction
92  BAD_TRAP;                                     ! 04 fp disabled
93  WOTRAP(5, SYM(window_overflow_trap_handler)); ! 05 window overflow
94  WUTRAP(6, SYM(window_underflow_trap_handler));! 06 window underflow
95  BAD_TRAP;                                     ! 07 memory address not aligned
96  BAD_TRAP;                                     ! 08 fp exception
97  BAD_TRAP;                                     ! 09 data access exception
98  BAD_TRAP;                                     ! 0A tag overflow
99  BAD_TRAP;                                     ! 0B undefined
100  BAD_TRAP;                                     ! 0C undefined
101  BAD_TRAP;                                     ! 0D undefined
102  BAD_TRAP;                                     ! 0E undefined
103  BAD_TRAP;                                     ! 0F undefined
104  BAD_TRAP;                                     ! 10 undefined
105
106  /*
107   *  ERC32 defined traps
108   */
109
110  BAD_TRAP;                                     ! 11 masked errors
111  BAD_TRAP;                                     ! 12 external 1
112  BAD_TRAP;                                     ! 13 external 2
113  BAD_TRAP;                                     ! 14 UART A RX/TX
114  BAD_TRAP;                                     ! 15 UART B RX/TX
115  BAD_TRAP;                                     ! 16 correctable memory error
116  BAD_TRAP;                                     ! 17 UART error
117  BAD_TRAP;                                     ! 18 DMA access error
118  BAD_TRAP;                                     ! 19 DMA timeout
119  BAD_TRAP;                                     ! 1A external 3
120  BAD_TRAP;                                     ! 1B external 4
121  BAD_TRAP;                                     ! 1C general purpose timer
122  BAD_TRAP;                                     ! 1D real time clock
123  BAD_TRAP;                                     ! 1E external 5
124  BAD_TRAP;                                     ! 1F watchdog timeout
125
126  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 20 - 23 undefined
127  BAD_TRAP;                                     ! 24 cp_disabled
128            BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 25 - 27 undefined
129  BAD_TRAP;                                     ! 28 cp_exception
130            BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 29 - 2B undefined
131  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 2C - 2F undefined
132  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 30 - 33 undefined
133  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 34 - 37 undefined
134  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 38 - 3B undefined
135  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 3C - 3F undefined
136  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 40 - 43 undefined
137  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 44 - 47 undefined
138  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 48 - 4B undefined
139  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 4C - 4F undefined
140  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 50 - 53 undefined
141  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 54 - 57 undefined
142  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 58 - 5B undefined
143  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 5C - 5F undefined
144  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 60 - 63 undefined
145  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 64 - 67 undefined
146  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 68 - 6B undefined
147  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 6C - 6F undefined
148  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 70 - 73 undefined
149  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 74 - 77 undefined
150  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 78 - 7B undefined
151
152/*
153   This is a sad patch to make sure that we know where the
154   MEC timer control register mirror is so we can stop the timers
155   from an external debugger. It is needed because the control
156   register is write-only. Trap 0x7C cannot occure in ERC32...
157
158   We also use this location to store the last location of the
159   usable RAM in order not to overwrite the remote debugger with
160   the RTEMS work-space area.
161
162*/
163
164        .global SYM(_ERC32_MEC_Timer_Control_Mirror), SYM(rdb_start), SYM(CLOCK_SPEED)
165
166SYM(rdb_start):
167SYM(_ERC32_MEC_Timer_Control_Mirror):
168
169  BAD_TRAP; BAD_TRAP;                           ! 7C - 7D undefined
170
171SYM(CLOCK_SPEED):
172
173  .word 0x0a, 0, 0, 0                           ! 7E (10 MHz default)
174
175  BAD_TRAP;                                     ! 7F undefined
176
177  /*
178   *  Software traps
179   *
180   *  NOTE: At the risk of being redundant... this is not a full
181   *        table.  The setjmp on the SPARC requires a window flush trap
182   *        handler and RTEMS will preserve the entries that were
183   *        installed before.
184   */
185
186  SYSCALL_TRAP( 0x80, SYM(syscall) );           ! 80 syscall SW trap
187  SOFT_TRAP; SOFT_TRAP;                         ! 81 - 82
188  TRAP( 0x83, SYM(window_flush_trap_handler) ); ! 83 flush windows SW trap
189
190  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 84 - 87
191  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 88 - 8B
192  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 8C - 8F
193  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 90 - 93
194  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 94 - 97
195  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 98 - 9B
196  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 9C - 9F
197  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! A0 - A3
198  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! A4 - A7
199  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! A8 - AB
200  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! AC - AF
201  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! B0 - B3
202  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! B4 - B7
203  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! B8 - BB
204  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! BC - BF
205  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! C0 - C3
206  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! C4 - C7
207  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! C8 - CB
208  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! CC - CF
209  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! D0 - D3
210  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! D4 - D7
211  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! D8 - DB
212  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! DC - DF
213  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! E0 - E3
214  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! E4 - E7
215  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! E8 - EB
216  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! EC - EF
217  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! F0 - F3
218  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! F4 - F7
219  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! F8 - FB
220  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! FC - FF
221
222/*
223 *  This is the hard reset code.
224 */
225
226#define PSR_INIT   0x10c0       /* Disable traps, set s and ps */
227#define WIM_INIT   2
228#define STACK_SIZE 16 * 1024
229
230        PUBLIC(hard_reset)
231SYM(hard_reset):
232
233/* Common initialisation */
234
235        set     SYM(trap_table), %g1    ! Initialize TBR
236        mov     %g1, %tbr
237
238        mov     %psr, %g1               ! Initialize WIM
239        add     %g1, 1, %g2
240        and     %g2, 0x7, %g2
241        set     1, %g3
242        sll     %g3, %g2, %g3
243        mov     %g3, %wim
244
245        or      %g1, 0xf20, %g1
246        wr      %g1, %psr               ! enable traps and disable ints
247
248        nop
249        nop
250        nop
251
252        sethi   %hi(_Per_CPU_Information), %g6 ! get per-CPU control
253        add     %g6, %lo(_Per_CPU_Information), %g6
254
255#if defined(START_LEON3_ENABLE_SMP)
256        rd      %asr17, %o0             ! get CPU identifier
257        srl     %o0, LEON3_ASR17_PROCESSOR_INDEX_SHIFT, %o0
258
259        cmp     %o0, 0
260        beq     cpu0
261         nop
262
263        sll     %o0, PER_CPU_CONTROL_SIZE_LOG2, %l0
264        add     %g6, %l0, %g6
265
266        ld      [%g6 + PER_CPU_INTERRUPT_STACK_HIGH], %sp ! set stack pointer
267        sub     %sp, 4, %sp             ! stack starts at end of area - 4
268        andn    %sp, 0x0f, %sp          ! align stack on 16-byte boundary
269        mov     %sp, %fp                ! set frame pointer
270
271        call    SYM(bsp_start_on_secondary_processor) ! does not return
272         sub    %sp, CPU_MINIMUM_STACK_FRAME_SIZE, %sp
273cpu0:
274#endif
275
276        set     (SYM(rdb_start)), %g5   ! End of RAM
277        st      %sp, [%g5]
278        sub     %sp, 4, %sp             ! stack starts at end of RAM - 4
279        andn    %sp, 0x0f, %sp          ! align stack on 16-byte boundary
280        mov     %sp, %fp                ! Set frame pointer
281        nop
282
283#if ENABLE_SIS_QUIRKS==1
284
285#include <erc32.h>
286
287/* Check if MEC is initialised. If not, this means that we are
288   running on the simulator. Initiate some of the parameters
289   that are done by the boot-prom otherwise.
290*/
291
292        set     SYM(ERC32_MEC), %g3  ! g3 = base address of peripherals
293        ld      [%g3], %g2
294        set     0xfe080000, %g1
295        andcc   %g1, %g2, %g0
296        bne     2f
297
298 /* Set the correct memory size in MEC memory config register */
299
300        set     SYM(PROM_SIZE), %l0
301        set     0, %l1
302        srl     %l0, 18, %l0
3031:
304        tst     %l0
305        srl     %l0, 1, %l0
306        bne,a   1b
307        inc     %l1
308        sll     %l1, 8, %l1
309
310        set     SYM(RAM_SIZE), %l0
311        srl     %l0, 19, %l0
3121:
313        tst     %l0
314        srl     %l0, 1, %l0
315        bne,a   1b
316        inc     %l1
317        sll     %l1, 10, %l1
318
319        ! set the Memory Configuration
320        st     %l1, [ %g3 + ERC32_MEC_MEMORY_CONFIGURATION_OFFSET ]
321        !DISABLE THE HARDWARE WATCHDOG
322        st     %g0, [ %g3 + ERC32_MEC_WATCHDOG_TRAP_DOOR_SET_OFFSET ]
323        !Reduce the number of wait states to 0 for all memory areas.
324        st     %g0, [ %g3 + ERC32_MEC_WAIT_STATE_CONFIGURATION_OFFSET ]
325
326        set     SYM(RAM_START), %l1  ! Cannot use RAM_END due to bug in linker
327        set     SYM(RAM_SIZE), %l2
328        add     %l1, %l2, %sp
329        st      %sp, [%g5]
330
331
332        set     SYM(CLOCK_SPEED), %g5   ! Use 14 MHz in simulator
333        set     14, %g1
334        st      %g1, [%g5]
335
3362:
337#endif
338
339        /*
340         *  Copy the initialized data to RAM
341         *
342         *  FROM:   _endtext
343         *  TO:     _data_start
344         *  LENGTH: (__bss_start - _data_start) bytes
345         */
346
347        sethi %hi(_endtext),%g1
348        or    %g1,%lo(_endtext),%g1     ! g1 = start of initialized data in ROM
349
350        sethi %hi(_data_start),%g3
351        or    %g3,%lo(_data_start),%g3  ! g3 = start of initialized data in RAM
352
353        sethi %hi(__bss_start), %g2
354        or    %g2,%lo(__bss_start),%g2  ! g2 = end of initialized data in RAM
355
356        cmp   %g1, %g3
357        be    1f
358        nop
359
360copy_data:
361        ldd   [%g1], %g4
362        std   %g4 , [%g3]               ! copy this double word
363        add   %g3, 8, %g3               ! bump the destination pointer
364        add   %g1, 8, %g1               ! bump the source pointer
365        cmp   %g3, %g2                  ! Is the pointer past the end of dest?
366        bl    copy_data
367        nop
368
369        /* clear the bss */
3701:
371
372        sethi %hi(_end),%g3
373        or    %g3,%lo(_end),%g3         ! g3 = end of bss
374        mov   %g0,%g1                   ! so std has two zeros
375zerobss:
376        std    %g0,[%g2]
377        add    %g2,8,%g2
378        cmp    %g2,%g3
379        bleu,a zerobss
380        nop
381
382        mov     %0, %o0                 ! command line
383        call    SYM(boot_card)          ! does not return
384         sub     %sp, 0x60, %sp         ! room for boot_card to save args
385
386/* end of file */
Note: See TracBrowser for help on using the repository browser.