| 1 | /* |
|---|
| 2 | * crt0_cygmon.S -- Minimal startup file for MIPS targets running Cygmon. |
|---|
| 3 | * |
|---|
| 4 | * Copyright (c) 1995, 1996, 1997, 2000 Red Hat, Inc. |
|---|
| 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 | |
|---|
| 17 | /* |
|---|
| 18 | * This file contains the minimal startup code necessary. |
|---|
| 19 | * This will not do any hardware initialization. It is assumed that we are talking to Cygmon |
|---|
| 20 | * and therefore the hardware will be initialized properly. |
|---|
| 21 | */ |
|---|
| 22 | |
|---|
| 23 | #ifdef __mips16 |
|---|
| 24 | /* This file contains 32 bit assembly code. */ |
|---|
| 25 | .set nomips16 |
|---|
| 26 | #endif |
|---|
| 27 | |
|---|
| 28 | #include "regs.S" |
|---|
| 29 | |
|---|
| 30 | /* |
|---|
| 31 | * Set up some room for a stack. We just grab a chunk of memory. |
|---|
| 32 | */ |
|---|
| 33 | #define STACK_SIZE 0x4000 |
|---|
| 34 | #define GLOBAL_SIZE 0x2000 |
|---|
| 35 | |
|---|
| 36 | #define STARTUP_STACK_SIZE 0x0100 |
|---|
| 37 | |
|---|
| 38 | .comm __memsize, 12 |
|---|
| 39 | .comm __lstack, STARTUP_STACK_SIZE |
|---|
| 40 | .comm __stackbase,4 |
|---|
| 41 | |
|---|
| 42 | .text |
|---|
| 43 | .align 4 |
|---|
| 44 | /* |
|---|
| 45 | * Without the following nop, GDB thinks _start is a data variable. |
|---|
| 46 | * This is probably a bug in GDB in handling a symbol that is at the |
|---|
| 47 | * start of the .text section. |
|---|
| 48 | */ |
|---|
| 49 | nop |
|---|
| 50 | |
|---|
| 51 | .globl _start |
|---|
| 52 | .ent _start |
|---|
| 53 | _start: |
|---|
| 54 | .set noreorder |
|---|
| 55 | la gp, _gp # set the global data pointer, defined in the linker script |
|---|
| 56 | .end _start |
|---|
| 57 | |
|---|
| 58 | /* |
|---|
| 59 | * zero out the bss section. |
|---|
| 60 | */ |
|---|
| 61 | .globl __memsize |
|---|
| 62 | .globl get_mem_info .text |
|---|
| 63 | .globl zerobss |
|---|
| 64 | .ent zerobss |
|---|
| 65 | zerobss: |
|---|
| 66 | la v0, _fbss # These variables are defined in the linker script |
|---|
| 67 | la v1, _end |
|---|
| 68 | |
|---|
| 69 | 3: |
|---|
| 70 | sw zero, 0(v0) |
|---|
| 71 | bltu v0, v1, 3b |
|---|
| 72 | addiu v0, v0, 4 # executed in delay slot |
|---|
| 73 | |
|---|
| 74 | /* |
|---|
| 75 | * Setup a small stack so we can run some C code, |
|---|
| 76 | * and get the usable memory size. |
|---|
| 77 | */ |
|---|
| 78 | la t0, __lstack |
|---|
| 79 | addiu sp, t0, STARTUP_STACK_SIZE |
|---|
| 80 | la a0, __memsize |
|---|
| 81 | jal get_mem_info |
|---|
| 82 | nop |
|---|
| 83 | |
|---|
| 84 | /* |
|---|
| 85 | * Setup the stack pointer -- |
|---|
| 86 | * get_mem_info returns the top of memory, so just use that In |
|---|
| 87 | * addition, we must subtract 24 bytes for the 3 8 byte |
|---|
| 88 | * arguments to main, in case main wants to write them back to |
|---|
| 89 | * the stack. The caller is supposed to allocate stack space |
|---|
| 90 | * for parameters in registers in the old MIPS ABIs. We must |
|---|
| 91 | * do this even though we aren't passing arguments, because |
|---|
| 92 | * main might be declared to have them. |
|---|
| 93 | * Some ports need a larger alignment for the stack, so we |
|---|
| 94 | * subtract 32, which satisifes the stack for the arguments and |
|---|
| 95 | * keeps the stack pointer better aligned. |
|---|
| 96 | */ |
|---|
| 97 | subu v0, v0, 32 |
|---|
| 98 | move sp, v0 |
|---|
| 99 | |
|---|
| 100 | sw sp, __stackbase # keep this for future ref |
|---|
| 101 | .end zerobss |
|---|
| 102 | |
|---|
| 103 | /* |
|---|
| 104 | * initialize target specific stuff. Only execute these |
|---|
| 105 | * functions it they exist. |
|---|
| 106 | */ |
|---|
| 107 | .globl hardware_init_hook .text |
|---|
| 108 | .globl software_init_hook .text |
|---|
| 109 | .globl __do_global_dtors .text |
|---|
| 110 | .globl atexit .text |
|---|
| 111 | .globl exit .text |
|---|
| 112 | .globl init |
|---|
| 113 | .ent init |
|---|
| 114 | init: |
|---|
| 115 | la t9, hardware_init_hook # init the hardware if needed |
|---|
| 116 | beq t9, zero, 6f |
|---|
| 117 | nop |
|---|
| 118 | jal t9 |
|---|
| 119 | nop |
|---|
| 120 | 6: |
|---|
| 121 | la t9, software_init_hook # init the software if needed |
|---|
| 122 | beq t9, zero, 7f |
|---|
| 123 | nop |
|---|
| 124 | jal t9 |
|---|
| 125 | nop |
|---|
| 126 | 7: |
|---|
| 127 | la a0, __do_global_dtors |
|---|
| 128 | jal atexit |
|---|
| 129 | nop |
|---|
| 130 | |
|---|
| 131 | #ifdef GCRT0 |
|---|
| 132 | .globl _ftext |
|---|
| 133 | .globl _extext |
|---|
| 134 | la a0, _ftext |
|---|
| 135 | la a1, _etext |
|---|
| 136 | jal monstartup |
|---|
| 137 | nop |
|---|
| 138 | #endif |
|---|
| 139 | |
|---|
| 140 | move a0,zero # set argc to 0 |
|---|
| 141 | jal main # call the program start function |
|---|
| 142 | nop |
|---|
| 143 | |
|---|
| 144 | # fall through to the "exit" routine |
|---|
| 145 | jal exit # call libc exit to run the G++ |
|---|
| 146 | # destructors |
|---|
| 147 | move a0, v0 # pass through the exit code |
|---|
| 148 | .end init |
|---|
| 149 | |
|---|
| 150 | /* |
|---|
| 151 | * _exit -- Exit from the application. Normally we cause a user trap |
|---|
| 152 | * to return to the ROM monitor for another run. NOTE: This is |
|---|
| 153 | * the only other routine we provide in the crt0.o object, since |
|---|
| 154 | * it may be tied to the "_start" routine. It also allows |
|---|
| 155 | * executables that contain a complete world to be linked with |
|---|
| 156 | * just the crt0.o object. |
|---|
| 157 | */ |
|---|
| 158 | .globl _exit |
|---|
| 159 | .ent _exit |
|---|
| 160 | _exit: |
|---|
| 161 | 7: |
|---|
| 162 | #ifdef GCRT0 |
|---|
| 163 | jal _mcleanup |
|---|
| 164 | nop |
|---|
| 165 | #endif |
|---|
| 166 | # Cygmon expects a break 5 |
|---|
| 167 | break 5 |
|---|
| 168 | nop |
|---|
| 169 | b 7b # loop back just in-case |
|---|
| 170 | nop |
|---|
| 171 | .end _exit |
|---|
| 172 | |
|---|
| 173 | /* EOF crt0.S */ |
|---|