]>
Commit | Line | Data |
---|---|---|
2d210c7f JJ |
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 */ |