| 1 | /* | 
|---|
| 2 |  * crt0.S -- startup file for hppa. | 
|---|
| 3 |  *              rob@cygnus.com (Rob Savoye) | 
|---|
| 4 |  */ | 
|---|
| 5 |         .VERSION "0.2" | 
|---|
| 6 |         .COPYRIGHT "crt0.S for hppa" | 
|---|
| 7 |  | 
|---|
| 8 | ;sp      .equ    %r30                   ; stack pointer | 
|---|
| 9 | ;dp      .equ    %r27                   ; global data pointer | 
|---|
| 10 | ;arg0    .equ    %r26                   ; argument | 
|---|
| 11 | ;arg1    .equ    %r25                   ; argument or high part of double argument | 
|---|
| 12 | ;arg2    .equ    %r24                   ; argument | 
|---|
| 13 | ;arg3    .equ    %r23                   ; argument or high part of double argument | 
|---|
| 14 |  | 
|---|
| 15 | #define         IMM(a,b)        ldil L%a,b  ! ldo  R%a(b),b | 
|---|
| 16 | #define         imm(i,t)        ldil LS%i,t ! addi RS%i,t,t | 
|---|
| 17 |  | 
|---|
| 18 |         .DATA | 
|---|
| 19 |  | 
|---|
| 20 | /**** | 
|---|
| 21 |  * FIXME: these are just a gross hack so this will assemble | 
|---|
| 22 |  ****/ | 
|---|
| 23 | _bss_start      .WORD | 
|---|
| 24 | _bss_end        .WORD | 
|---|
| 25 | _foobar  | 
|---|
| 26 |                 .STRINGZ "Foo Bar...\r\n" | 
|---|
| 27 |  | 
|---|
| 28 | ;;_SYSTEM_ID    .WORD | 
|---|
| 29 | ;;              .EXPORT _SYSTEM_ID      ; FIXME this is only so it'll | 
|---|
| 30 |                                         ; link | 
|---|
| 31 |          | 
|---|
| 32 | /*  | 
|---|
| 33 |  * Set up the standard spaces (sections) These definitions come | 
|---|
| 34 |  * from /lib/pcc_prefix.s. | 
|---|
| 35 |  */ | 
|---|
| 36 |         .space  $TEXT$,0 | 
|---|
| 37 |          | 
|---|
| 38 |         .SUBSPA $BOOT$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=4 | 
|---|
| 39 |         .IMPORT _start | 
|---|
| 40 |  | 
|---|
| 41 | /* | 
|---|
| 42 |  * stuff we need that's defined elsewhere. | 
|---|
| 43 |  */ | 
|---|
| 44 |         .IMPORT main, CODE | 
|---|
| 45 |         .IMPORT _bss_start, DATA | 
|---|
| 46 |         .IMPORT _bss_end, DATA | 
|---|
| 47 |         .IMPORT environ, DATA | 
|---|
| 48 |  | 
|---|
| 49 | /* | 
|---|
| 50 |  * start -- set things up so the application will run. | 
|---|
| 51 |  * | 
|---|
| 52 |  */ | 
|---|
| 53 |         .PROC | 
|---|
| 54 |         .CALLINFO SAVE_SP, FRAME=48 | 
|---|
| 55 |         .EXPORT $START$,ENTRY | 
|---|
| 56 | $START$ | 
|---|
| 57 |  | 
|---|
| 58 |         /* FIXME: this writes to page zero */ | 
|---|
| 59 |         ;; setup the %30 (stack pointer) with some memory | 
|---|
| 60 |         ldil    L%_stack+48,%r30 | 
|---|
| 61 |         ldo     R%_stack+48(%r30),%r30          ; should be %r30 (sp) but then | 
|---|
| 62 |                                                 ; we'd kill our test program :-) | 
|---|
| 63 |         ;; we need to set %r27 (global data pointer) here too  | 
|---|
| 64 |         ldil    L%$global$,%r27 | 
|---|
| 65 |         ldo     R%$global$(%r27),%r27           ; same problem as above | 
|---|
| 66 |  | 
|---|
| 67 | /* | 
|---|
| 68 |  * zerobss -- zero out the bss section | 
|---|
| 69 |  */ | 
|---|
| 70 |         ; load the start of bss | 
|---|
| 71 |         ldil    L%_bss_start,%r4 | 
|---|
| 72 |         ldo     R%_bss_start(%r4),%r4 | 
|---|
| 73 |  | 
|---|
| 74 |         ;  load the end of bss | 
|---|
| 75 |         ldil    L%_bss_end,%r5 | 
|---|
| 76 |         ldo     R%_bss_end(%r5),%r5 | 
|---|
| 77 |  | 
|---|
| 78 |  | 
|---|
| 79 | bssloop | 
|---|
| 80 |         addi    -1,%r5,%r5                      ; decrement _bss_end | 
|---|
| 81 |         stb     %r0,0(0,%r5)                    ; we do this by bytes for now even | 
|---|
| 82 |                                                 ; though it's slower, it's safer | 
|---|
| 83 |         combf,= %r4,%r5, bssloop         | 
|---|
| 84 |         nop | 
|---|
| 85 |          | 
|---|
| 86 |         ldi     1,%ret0 | 
|---|
| 87 |  | 
|---|
| 88 | /* | 
|---|
| 89 |  * Call the main routine from the application to get it going. | 
|---|
| 90 |  * main (argc, argv, environ) | 
|---|
| 91 |  * We pass argv as a pointer to NULL. | 
|---|
| 92 |  */ | 
|---|
| 93 |  | 
|---|
| 94 |         bl      main,%r2 | 
|---|
| 95 |         nop | 
|---|
| 96 |  | 
|---|
| 97 |         .PROCEND | 
|---|
| 98 | /* | 
|---|
| 99 |  * _exit -- Exit from the application. Normally we cause a user trap | 
|---|
| 100 |  *          to return to the ROM monitor for another run, but with | 
|---|
| 101 |  *          this monitor we can't. Still, "C" wants this symbol, it | 
|---|
| 102 |  *          should be here. Jumping to 0xF0000004 jumps back into the | 
|---|
| 103 |  *          firmware, while writing a 5 to 0xFFFE0030 causes a reset. | 
|---|
| 104 |  */ | 
|---|
| 105 |         .EXPORT _exit, ENTRY | 
|---|
| 106 | _exit | 
|---|
| 107 |         .PROC | 
|---|
| 108 |         .CALLINFO | 
|---|
| 109 |         .ENTRY | 
|---|
| 110 | ;;      ldil    L%0xf0000004,%r1 | 
|---|
| 111 | ;;      bl      %r1, %r2 | 
|---|
| 112 |          | 
|---|
| 113 |         ldil    L'4026531844,%r19 | 
|---|
| 114 |         ldo     R'4026531844(%r19),%r19 | 
|---|
| 115 |         blr     %r19, %r2 | 
|---|
| 116 |         nop | 
|---|
| 117 |          | 
|---|
| 118 |         ;; This just causes a breakpoint exception | 
|---|
| 119 | ;;      break   0x0e,0xa5a | 
|---|
| 120 | ;;      bv,n    (%rp) | 
|---|
| 121 |         nop | 
|---|
| 122 |         .EXIT | 
|---|
| 123 |         .PROCEND | 
|---|
| 124 |  | 
|---|
| 125 |         .subspa $UNWIND_START$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=56 | 
|---|
| 126 |         .export $UNWIND_START | 
|---|
| 127 | $UNWIND_START | 
|---|
| 128 |         .subspa $UNWIND$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=64 | 
|---|
| 129 |         .subspa $UNWIND_END$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=72 | 
|---|
| 130 |         .export $UNWIND_END | 
|---|
| 131 | $UNWIND_END | 
|---|
| 132 |         .subspa $RECOVER_START$,QUAD=0,ALIGN=4,ACCESS=0x2c,SORT=73 | 
|---|
| 133 |         .export $RECOVER_START | 
|---|
| 134 | $RECOVER_START | 
|---|
| 135 |         .subspa $RECOVER$,QUAD=0,ALIGN=4,ACCESS=0x2c,SORT=80 | 
|---|
| 136 |         .subspa $RECOVER_END$,QUAD=0,ALIGN=4,ACCESS=0x2c,SORT=88 | 
|---|
| 137 |         .export $RECOVER_END | 
|---|
| 138 | $RECOVER_END | 
|---|
| 139 |  | 
|---|
| 140 | ; The following declarations are, by default in the data space ($PRIVATE$) | 
|---|
| 141 |  | 
|---|
| 142 | ;;        .space  $PRIVATE$,1 | 
|---|
| 143 |  | 
|---|
| 144 | /* | 
|---|
| 145 |  * Here we set up the standard date sub spaces. | 
|---|
| 146 |  * _dp is for the WinBond board. | 
|---|
| 147 |  * | 
|---|
| 148 |  * Set up some room for a stack. We just grab a chunk of memory. | 
|---|
| 149 |  * We also setup some space for the global variable space, which | 
|---|
| 150 |  * must be done using the reserved name "$global$" so "C" code | 
|---|
| 151 |  * can find it. The stack grows towards the higher addresses. | 
|---|
| 152 |  */ | 
|---|
| 153 |  | 
|---|
| 154 |         .subspa $DATA$,QUAD=1,ALIGN=8,ACCESS=0x1f,SORT=16 | 
|---|
| 155 |         .subspa $SHORTDATA$,QUAD=1,ALIGN=8,ACCESS=0x1f,SORT=24 | 
|---|
| 156 |         .subspa $GLOBAL$,QUAD=1,ALIGN=8,ACCESS=0x1f,SORT=40 | 
|---|
| 157 |         .export $global$ | 
|---|
| 158 |         .export _dp | 
|---|
| 159 | $global$ | 
|---|
| 160 | _dp | 
|---|
| 161 |         .subspa $SHORTBSS$,QUAD=1,ALIGN=8,ACCESS=0x1f,SORT=80,ZERO | 
|---|
| 162 |         .subspa $BSS$,QUAD=1,ALIGN=8,ACCESS=0x1f,SORT=82,ZERO | 
|---|
| 163 |  | 
|---|
| 164 |        .subspa $STACK$,QUAD=1,ALIGN=8,ACCESS=0x1f,SORT=88,ZERO | 
|---|
| 165 |         .export _stack | 
|---|
| 166 | _stack | 
|---|
| 167 |         .BLOCK          0x2000 | 
|---|
| 168 |  | 
|---|
| 169 | /* | 
|---|
| 170 |  * The heap follows the stack. To use dynamic memory routines in an | 
|---|
| 171 |  * application, some space MUST be assigned to the stack. | 
|---|
| 172 |  */ | 
|---|
| 173 |  | 
|---|
| 174 |         .subspa $HEAP$,QUAD=1,ALIGN=8,ACCESS=0x1f,SORT=96,ZERO | 
|---|
| 175 |         .export _heap | 
|---|
| 176 | _heap | 
|---|
| 177 |         .end | 
|---|