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

4.11
Last change on this file since dff1803 was dff1803, checked in by Daniel Hellstrom <daniel@…>, on Dec 3, 2014 at 10:35:52 AM

SPARC: optimize IRQ enable & disable

  • Coding style cleanups.
  • Use OS reserved trap 0x89 for IRQ Disable
  • Use OS reserved trap 0x8A for IRQ Enable
  • Add to SPARC CPU supplement documentation

This will result in faster Disable/Enable? code since the
system trap handler does not need to decode which function
the user wants. Besides the IRQ disable/enabled can now
be inline which avoids the caller to take into account that
o0-o7+g1-g4 registers are destroyed by trap handler.

It was also possible to reduce the interrupt trap handler by
five instructions due to this.

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