1 |
30 |
unneback |
/*
|
2 |
|
|
* startsis.s
|
3 |
|
|
*
|
4 |
|
|
* Start code for the ERC32.
|
5 |
|
|
*
|
6 |
|
|
* This is based on the file srt0.s provided with the binary
|
7 |
|
|
* distribution of the SPARC Instruction Simulator (SIS) found
|
8 |
|
|
* at ftp://ftp.estec.esa.nl/pub/ws/wsd/erc32.
|
9 |
|
|
*
|
10 |
|
|
* $Id: start.S,v 1.2 2001-09-27 12:01:13 chris Exp $
|
11 |
|
|
*/
|
12 |
|
|
|
13 |
|
|
#include
|
14 |
|
|
#include
|
15 |
|
|
|
16 |
|
|
/*
|
17 |
|
|
* Unexpected trap will halt the processor by forcing it to error state
|
18 |
|
|
*/
|
19 |
|
|
|
20 |
|
|
#define BAD_TRAP \
|
21 |
|
|
ta 0; \
|
22 |
|
|
nop; \
|
23 |
|
|
nop; \
|
24 |
|
|
nop;
|
25 |
|
|
|
26 |
|
|
/*
|
27 |
|
|
* Software trap. Treat as BAD_TRAP for the time being...
|
28 |
|
|
*/
|
29 |
|
|
|
30 |
|
|
#define SOFT_TRAP BAD_TRAP
|
31 |
|
|
|
32 |
|
|
|
33 |
|
|
.seg "text"
|
34 |
|
|
PUBLIC(start)
|
35 |
|
|
.global start
|
36 |
|
|
|
37 |
|
|
SYM(start):
|
38 |
|
|
start:
|
39 |
|
|
|
40 |
|
|
/*
|
41 |
|
|
* The trap table has to be the first code in a boot PROM. But because
|
42 |
|
|
* the Memory Configuration comes up thinking we only have 4K of PROM, we
|
43 |
|
|
* cannot have a full trap table and still have room left over to
|
44 |
|
|
* reprogram the Memory Configuration register correctly. This file
|
45 |
|
|
* uses an abbreviated trap which has every entry which might be used
|
46 |
|
|
* before RTEMS installs its own trap table.
|
47 |
|
|
*/
|
48 |
|
|
|
49 |
|
|
|
50 |
|
|
PUBLIC(trap_table)
|
51 |
|
|
SYM(trap_table):
|
52 |
|
|
|
53 |
|
|
RTRAP( 0, SYM(hard_reset) ); ! 00 reset trap
|
54 |
|
|
BAD_TRAP; ! 01 instruction access
|
55 |
|
|
! exception
|
56 |
|
|
BAD_TRAP; ! 02 illegal instruction
|
57 |
|
|
BAD_TRAP; ! 03 privileged instruction
|
58 |
|
|
BAD_TRAP; ! 04 fp disabled
|
59 |
|
|
TRAP( 5, SYM(window_overflow_trap_handler) ); ! 05 window overflow
|
60 |
|
|
TRAP( 6, SYM(window_underflow_trap_handler) );! 06 window underflow
|
61 |
|
|
BAD_TRAP; ! 07 memory address not aligned
|
62 |
|
|
BAD_TRAP; ! 08 fp exception
|
63 |
|
|
BAD_TRAP; ! 09 data access exception
|
64 |
|
|
BAD_TRAP; ! 0A tag overflow
|
65 |
|
|
BAD_TRAP; ! 0B undefined
|
66 |
|
|
BAD_TRAP; ! 0C undefined
|
67 |
|
|
BAD_TRAP; ! 0D undefined
|
68 |
|
|
BAD_TRAP; ! 0E undefined
|
69 |
|
|
BAD_TRAP; ! 0F undefined
|
70 |
|
|
BAD_TRAP; ! 10 undefined
|
71 |
|
|
|
72 |
|
|
/*
|
73 |
|
|
* ERC32 defined traps
|
74 |
|
|
*/
|
75 |
|
|
|
76 |
|
|
BAD_TRAP; ! 11 masked errors
|
77 |
|
|
BAD_TRAP; ! 12 external 1
|
78 |
|
|
BAD_TRAP; ! 13 external 2
|
79 |
|
|
BAD_TRAP; ! 14 UART A RX/TX
|
80 |
|
|
BAD_TRAP; ! 15 UART B RX/TX
|
81 |
|
|
BAD_TRAP; ! 16 correctable memory error
|
82 |
|
|
BAD_TRAP; ! 17 UART error
|
83 |
|
|
BAD_TRAP; ! 18 DMA access error
|
84 |
|
|
BAD_TRAP; ! 19 DMA timeout
|
85 |
|
|
BAD_TRAP; ! 1A external 3
|
86 |
|
|
BAD_TRAP; ! 1B external 4
|
87 |
|
|
BAD_TRAP; ! 1C general purpose timer
|
88 |
|
|
BAD_TRAP; ! 1D real time clock
|
89 |
|
|
BAD_TRAP; ! 1E external 5
|
90 |
|
|
BAD_TRAP; ! 1F watchdog timeout
|
91 |
|
|
|
92 |
|
|
|
93 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 20 - 23 undefined
|
94 |
|
|
BAD_TRAP; ! 24 cp_disabled
|
95 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 25 - 27 undefined
|
96 |
|
|
BAD_TRAP; ! 28 cp_exception
|
97 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 29 - 2B undefined
|
98 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 2C - 2F undefined
|
99 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30 - 33 undefined
|
100 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34 - 37 undefined
|
101 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38 - 3B undefined
|
102 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3C - 3F undefined
|
103 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40 - 43 undefined
|
104 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44 - 47 undefined
|
105 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48 - 4B undefined
|
106 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4C - 4F undefined
|
107 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50 - 53 undefined
|
108 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54 - 57 undefined
|
109 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58 - 5B undefined
|
110 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5C - 5F undefined
|
111 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60 - 63 undefined
|
112 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64 - 67 undefined
|
113 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68 - 6B undefined
|
114 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6C - 6F undefined
|
115 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70 - 73 undefined
|
116 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74 - 77 undefined
|
117 |
|
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78 - 7B undefined
|
118 |
|
|
|
119 |
|
|
/*
|
120 |
|
|
This is a sad patch to make sure that we know where the
|
121 |
|
|
MEC timer control register mirror is so we can stop the timers
|
122 |
|
|
from an external debugger. It is needed because the control
|
123 |
|
|
register is write-only. Trap 0x7C cannot occure in ERC32...
|
124 |
|
|
|
125 |
|
|
We also use this location to store the last location of the
|
126 |
|
|
usable RAM in order not to overwrite the remote debugger with
|
127 |
|
|
the RTEMS work-space area.
|
128 |
|
|
|
129 |
|
|
*/
|
130 |
|
|
|
131 |
|
|
.global __ERC32_MEC_Timer_Control_Mirror, SYM(rdb_start), SYM(CLOCK_SPEED)
|
132 |
|
|
|
133 |
|
|
SYM(rdb_start):
|
134 |
|
|
__ERC32_MEC_Timer_Control_Mirror:
|
135 |
|
|
|
136 |
|
|
BAD_TRAP; BAD_TRAP; ! 7C - 7D undefined
|
137 |
|
|
|
138 |
|
|
SYM(CLOCK_SPEED):
|
139 |
|
|
|
140 |
|
|
.word 0x0a, 0, 0, 0 ! 7E (10 MHz default)
|
141 |
|
|
|
142 |
|
|
BAD_TRAP; ! 7F undefined
|
143 |
|
|
|
144 |
|
|
/*
|
145 |
|
|
* Software traps
|
146 |
|
|
*
|
147 |
|
|
* NOTE: At the risk of being redundant... this is not a full
|
148 |
|
|
* table. The setjmp on the SPARC requires a window flush trap
|
149 |
|
|
* handler and RTEMS will preserve the entries that were
|
150 |
|
|
* installed before.
|
151 |
|
|
*/
|
152 |
|
|
|
153 |
|
|
TRAP( 0x80, SYM(syscall) ); ! 80 syscall SW trap
|
154 |
|
|
SOFT_TRAP; SOFT_TRAP; ! 81 - 82
|
155 |
|
|
TRAP( 0x83, SYM(window_flush_trap_handler) ); ! 83 flush windows SW trap
|
156 |
|
|
|
157 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84 - 87
|
158 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88 - 8B
|
159 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8C - 8F
|
160 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90 - 93
|
161 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94 - 97
|
162 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98 - 9B
|
163 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9C - 9F
|
164 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A0 - A3
|
165 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A4 - A7
|
166 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A8 - AB
|
167 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! AC - AF
|
168 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B0 - B3
|
169 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B4 - B7
|
170 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B8 - BB
|
171 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! BC - BF
|
172 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C0 - C3
|
173 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C4 - C7
|
174 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C8 - CB
|
175 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! CC - CF
|
176 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D0 - D3
|
177 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D4 - D7
|
178 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D8 - DB
|
179 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! DC - DF
|
180 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E0 - E3
|
181 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E4 - E7
|
182 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E8 - EB
|
183 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! EC - EF
|
184 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F0 - F3
|
185 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F4 - F7
|
186 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F8 - FB
|
187 |
|
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! FC - FF
|
188 |
|
|
|
189 |
|
|
/*
|
190 |
|
|
* This is the hard reset code.
|
191 |
|
|
*/
|
192 |
|
|
|
193 |
|
|
#define PSR_INIT 0x10c0 /* Disable traps, set s and ps */
|
194 |
|
|
#define WIM_INIT 2
|
195 |
|
|
#define STACK_SIZE 16 * 1024
|
196 |
|
|
|
197 |
|
|
PUBLIC(hard_reset)
|
198 |
|
|
SYM(hard_reset):
|
199 |
|
|
|
200 |
|
|
set SYM(trap_table), %g1 ! Initialize TBR
|
201 |
|
|
mov %g1, %tbr
|
202 |
|
|
|
203 |
|
|
set (SYM(rdb_start)), %g6 ! End of work-space area
|
204 |
|
|
st %sp, [%g6]
|
205 |
|
|
|
206 |
|
|
|
207 |
|
|
/* Check if MEC is initialised. If not, this means that we are
|
208 |
|
|
running on the simulator. Initiate some of the parameters
|
209 |
|
|
that are done by the boot-prom otherwise.
|
210 |
|
|
*/
|
211 |
|
|
|
212 |
|
|
set SYM(ERC32_MEC), %g3 ! g3 = base address of peripherals
|
213 |
|
|
ld [%g3], %g2
|
214 |
|
|
set 0xfe080000, %g1
|
215 |
|
|
andcc %g1, %g2, %g0
|
216 |
|
|
bne 2f
|
217 |
|
|
|
218 |
|
|
/* Set the correct memory size in MEC memory config register */
|
219 |
|
|
|
220 |
|
|
set SYM(PROM_SIZE), %l0
|
221 |
|
|
set 0, %l1
|
222 |
|
|
srl %l0, 18, %l0
|
223 |
|
|
1:
|
224 |
|
|
tst %l0
|
225 |
|
|
srl %l0, 1, %l0
|
226 |
|
|
bne,a 1b
|
227 |
|
|
inc %l1
|
228 |
|
|
sll %l1, 8, %l1
|
229 |
|
|
|
230 |
|
|
set SYM(RAM_SIZE), %l0
|
231 |
|
|
srl %l0, 19, %l0
|
232 |
|
|
1:
|
233 |
|
|
tst %l0
|
234 |
|
|
srl %l0, 1, %l0
|
235 |
|
|
bne,a 1b
|
236 |
|
|
inc %l1
|
237 |
|
|
sll %l1, 10, %l1
|
238 |
|
|
|
239 |
|
|
! set the Memory Configuration
|
240 |
|
|
st %l1, [ %g3 + ERC32_MEC_MEMORY_CONFIGURATION_OFFSET ]
|
241 |
|
|
|
242 |
|
|
set SYM(RAM_START), %l1 ! Cannot use RAM_END due to bug in linker
|
243 |
|
|
set SYM(RAM_SIZE), %l2
|
244 |
|
|
add %l1, %l2, %sp
|
245 |
|
|
st %sp, [%g6]
|
246 |
|
|
|
247 |
|
|
|
248 |
|
|
set SYM(CLOCK_SPEED), %g6 ! Use 14 MHz in simulator
|
249 |
|
|
set 14, %g1
|
250 |
|
|
st %g1, [%g6]
|
251 |
|
|
|
252 |
|
|
/* Common initialisation */
|
253 |
|
|
2:
|
254 |
|
|
set WIM_INIT, %g1 ! Initialize WIM
|
255 |
|
|
mov %g1, %wim
|
256 |
|
|
|
257 |
|
|
set PSR_INIT, %g1
|
258 |
|
|
wr %g1, 0x20, %psr ! enable traps
|
259 |
|
|
|
260 |
|
|
nop
|
261 |
|
|
nop
|
262 |
|
|
nop
|
263 |
|
|
|
264 |
|
|
sethi %hi(stack_space + STACK_SIZE), %g1
|
265 |
|
|
or %g1,%lo(stack_space + STACK_SIZE),%g1
|
266 |
|
|
! g1 = top of stack
|
267 |
|
|
mov %g1, %sp ! Set stack pointer
|
268 |
|
|
mov %sp, %fp ! Set frame pointer
|
269 |
|
|
nop
|
270 |
|
|
|
271 |
|
|
/*
|
272 |
|
|
* Copy the initialized data to RAM
|
273 |
|
|
*
|
274 |
|
|
* FROM: _endtext
|
275 |
|
|
* TO: _data_start
|
276 |
|
|
* LENGTH: (__bss_start - _data_start) bytes
|
277 |
|
|
*/
|
278 |
|
|
|
279 |
|
|
|
280 |
|
|
sethi %hi(_endtext),%g2
|
281 |
|
|
or %g2,%lo(_endtext),%g2 ! g2 = start of initialized data in ROM
|
282 |
|
|
|
283 |
|
|
sethi %hi(_data_start),%g3
|
284 |
|
|
or %g3,%lo(_data_start),%g3 ! g3 = start of initialized data in RAM
|
285 |
|
|
|
286 |
|
|
sethi %hi(__bss_start),%g4
|
287 |
|
|
or %g4,%lo(__bss_start),%g4 ! g4 = end of initialized data in RAM
|
288 |
|
|
|
289 |
|
|
cmp %g2, %g3
|
290 |
|
|
be 1f
|
291 |
|
|
nop
|
292 |
|
|
|
293 |
|
|
copy_data:
|
294 |
|
|
ldd [ %g2 ], %g6
|
295 |
|
|
std %g6 , [ %g3 ] ! copy this double word
|
296 |
|
|
add %g3, 8, %g3 ! bump the destination pointer
|
297 |
|
|
add %g2, 8, %g2 ! bump the source pointer
|
298 |
|
|
cmp %g3, %g4 ! Is the pointer past the end of dest?
|
299 |
|
|
bl copy_data
|
300 |
|
|
nop
|
301 |
|
|
|
302 |
|
|
/* clear the bss */
|
303 |
|
|
1:
|
304 |
|
|
|
305 |
|
|
sethi %hi(_edata),%g2
|
306 |
|
|
or %g2,%lo(_edata),%g2 ! g2 = start of bss
|
307 |
|
|
sethi %hi(_end),%g3
|
308 |
|
|
or %g3,%lo(_end),%g3 ! g3 = end of bss
|
309 |
|
|
mov %g0,%g1 ! so std has two zeros
|
310 |
|
|
zerobss:
|
311 |
|
|
std %g0,[%g2]
|
312 |
|
|
add %g2,8,%g2
|
313 |
|
|
cmp %g2,%g3
|
314 |
|
|
bleu,a zerobss
|
315 |
|
|
nop
|
316 |
|
|
|
317 |
|
|
mov %0, %o2 ! environ
|
318 |
|
|
mov %0, %o1 ! argv
|
319 |
|
|
mov %0, %o0 ! argc
|
320 |
|
|
call SYM(boot_card)
|
321 |
|
|
sub %sp, 0x60, %sp ! room for boot_card to save args
|
322 |
|
|
nop
|
323 |
|
|
|
324 |
|
|
PUBLIC(BSP_fatal_return)
|
325 |
|
|
SYM(BSP_fatal_return):
|
326 |
|
|
mov 1, %g1
|
327 |
|
|
ta 0 ! Halt if _main returns ...
|
328 |
|
|
nop
|
329 |
|
|
|
330 |
|
|
/*
|
331 |
|
|
* There does not seem to be a way to get this aligned AND
|
332 |
|
|
* in the BSS.
|
333 |
|
|
*/
|
334 |
|
|
|
335 |
|
|
.align 32
|
336 |
|
|
.comm stack_space, STACK_SIZE
|
337 |
|
|
|
338 |
|
|
/* end of file */
|