| 1 | /* | 
|---|
| 2 |  * C startup code for the Fujitsu SPARClite demo board | 
|---|
| 3 |  * | 
|---|
| 4 |  * Copyright (c) 1995, 1996 Cygnus Support | 
|---|
| 5 |  * | 
|---|
| 6 |  * The authors hereby grant permission to use, copy, modify, distribute, | 
|---|
| 7 |  * and license this software and its documentation for any purpose, provided | 
|---|
| 8 |  * that existing copyright notices are retained in all copies and that this | 
|---|
| 9 |  * notice is included verbatim in any distributions. No written agreement, | 
|---|
| 10 |  * license, or royalty fee is required for any of the authorized uses. | 
|---|
| 11 |  * Modifications to this software may be copyrighted by their authors | 
|---|
| 12 |  * and need not follow the licensing terms described here, provided that | 
|---|
| 13 |  * the new terms are clearly indicated on the first page of each file where | 
|---|
| 14 |  * they apply. | 
|---|
| 15 |  */ | 
|---|
| 16 | #include "asm.h" | 
|---|
| 17 |  | 
|---|
| 18 | #ifdef TARGET_CPU_SPARC64 | 
|---|
| 19 | #define STACK_BIAS 2047 | 
|---|
| 20 | #define SAVE_SIZE -128 | 
|---|
| 21 | #else | 
|---|
| 22 | #define SAVE_SIZE -64 | 
|---|
| 23 | #endif | 
|---|
| 24 |  | 
|---|
| 25 | .register %g2, #scratch | 
|---|
| 26 | .register %g3, #scratch | 
|---|
| 27 |          | 
|---|
| 28 | .data | 
|---|
| 29 |         .align  8 | 
|---|
| 30 | SYM(environ):                   ! this is the first address in the data section | 
|---|
| 31 |         .long   0 | 
|---|
| 32 |  | 
|---|
| 33 | SYM(argc): | 
|---|
| 34 |         .long   0 | 
|---|
| 35 |  | 
|---|
| 36 |         .text | 
|---|
| 37 |         .align 8 | 
|---|
| 38 |  | 
|---|
| 39 |         .globl SYM(start) | 
|---|
| 40 |         .globl start | 
|---|
| 41 | SYM(start): | 
|---|
| 42 | start: | 
|---|
| 43 |         /* see if the stack is already setup. if not, then default | 
|---|
| 44 |          *  to using the value of %sp as set by the ROM monitor | 
|---|
| 45 |          */ | 
|---|
| 46 |         sethi   %hi(__stack), %g1 | 
|---|
| 47 |         or      %g1,%lo(__stack),%g1 | 
|---|
| 48 |         cmp     %g0,%g1 | 
|---|
| 49 |         be      1f | 
|---|
| 50 |         nop | 
|---|
| 51 | #ifdef STACK_BIAS | 
|---|
| 52 |         sub     %g1, STACK_BIAS, %g1 | 
|---|
| 53 | #endif | 
|---|
| 54 |         mov     %g1, %sp                                ! set the stack pointer | 
|---|
| 55 |         mov     0, %fp | 
|---|
| 56 | 1:       | 
|---|
| 57 |  | 
|---|
| 58 |         /* zero the bss section */ | 
|---|
| 59 |         sethi %hi(__bss_start),%g2 | 
|---|
| 60 |         or    %g2,%lo(__bss_start),%g2          ! start of bss | 
|---|
| 61 |         sethi %hi(_end),%g3 | 
|---|
| 62 |         or    %g3,%lo(_end),%g3                 ! end of bss | 
|---|
| 63 |         mov   %g0,%g1                           ! so std has two zeros | 
|---|
| 64 | zerobss: | 
|---|
| 65 |         std    %g0,[%g2] | 
|---|
| 66 |         add    %g2,8,%g2 | 
|---|
| 67 |         cmp    %g2,%g3 | 
|---|
| 68 |         bleu,a zerobss | 
|---|
| 69 |         nop | 
|---|
| 70 |          | 
|---|
| 71 | /* | 
|---|
| 72 |  * initialize target specific stuff. Only execute these | 
|---|
| 73 |  * functions it they exist. | 
|---|
| 74 |  */ | 
|---|
| 75 | init: | 
|---|
| 76 |         sethi   %hi(SYM(hardware_init_hook)), %g1 | 
|---|
| 77 |         or      %g1,%lo(SYM(hardware_init_hook)),%g1 | 
|---|
| 78 |         cmp     %g0,%g1 | 
|---|
| 79 |         be      1f | 
|---|
| 80 |         nop | 
|---|
| 81 |         call    SYM(hardware_init_hook) | 
|---|
| 82 |         nop | 
|---|
| 83 |  | 
|---|
| 84 | 1:       | 
|---|
| 85 |         sethi   %hi(SYM(software_init_hook)), %g1 | 
|---|
| 86 |         or      %g1,%lo(SYM(software_init_hook)),%g1 | 
|---|
| 87 |         cmp     %g0,%g1 | 
|---|
| 88 |         be      2f | 
|---|
| 89 |         nop | 
|---|
| 90 |         call    SYM(software_init_hook) | 
|---|
| 91 |         nop | 
|---|
| 92 | 2: | 
|---|
| 93 |         set     SYM(__sigtramp), %o0 | 
|---|
| 94 |         call    SYM(__install_signal_handler) | 
|---|
| 95 |         nop | 
|---|
| 96 |  | 
|---|
| 97 |         set     do_dtors,%o0 | 
|---|
| 98 |         call    SYM(atexit) | 
|---|
| 99 |         nop | 
|---|
| 100 |  | 
|---|
| 101 |         call    do_ctors | 
|---|
| 102 |         nop | 
|---|
| 103 |  | 
|---|
| 104 |         set     SYM(argc), %o0 | 
|---|
| 105 |         call    SYM(__getProgramArgs) | 
|---|
| 106 |         nop | 
|---|
| 107 |  | 
|---|
| 108 |         mov     %o0, %o1 | 
|---|
| 109 |         set     SYM(argc), %o0 | 
|---|
| 110 |         ld      [%o0], %o0 | 
|---|
| 111 |         call SYM(main) | 
|---|
| 112 |         nop | 
|---|
| 113 |  | 
|---|
| 114 |         /* call exit from the C library so atexit gets called, and the | 
|---|
| 115 |          * C++ destructors get run. This calls our exit routine below     | 
|---|
| 116 |          * when it's done. | 
|---|
| 117 |          */ | 
|---|
| 118 |         call    SYM(exit) | 
|---|
| 119 |         nop | 
|---|
| 120 |  | 
|---|
| 121 | do_ctors: | 
|---|
| 122 |         save    %sp,SAVE_SIZE,%sp | 
|---|
| 123 |         set     __CTOR_LIST__,%l0 | 
|---|
| 124 | our_entry: | 
|---|
| 125 |         ld      [%l0],%l1 | 
|---|
| 126 |         add     %l0,4,%l0 | 
|---|
| 127 |         tst     %l1 | 
|---|
| 128 | 1: | 
|---|
| 129 |         beq     2f | 
|---|
| 130 |         nop | 
|---|
| 131 |         ld      [%l0],%l2 | 
|---|
| 132 |         add     %l0,4,%l0 | 
|---|
| 133 |  | 
|---|
| 134 |         call    %l2 | 
|---|
| 135 |         nop | 
|---|
| 136 |         deccc   %l1 | 
|---|
| 137 |         b       1b | 
|---|
| 138 |         nop | 
|---|
| 139 | 2: | 
|---|
| 140 |         ret | 
|---|
| 141 |         restore | 
|---|
| 142 |  | 
|---|
| 143 | do_dtors: | 
|---|
| 144 |         save    %sp,SAVE_SIZE,%sp | 
|---|
| 145 |         set     __DTOR_LIST__,%l0 | 
|---|
| 146 |         b       our_entry | 
|---|
| 147 |         nop | 
|---|