OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [libgloss/] [or32/] [crt0.S] - Blame information for rev 183

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 183 jeremybenn
/* crt0.S. C Runtime startup file.
2 148 jeremybenn
 
3 180 jeremybenn
   Copyright (C) 2004, Jacob Bower
4
   Copyright (C) 2010, Embecosm Limited 
5 148 jeremybenn
 
6 180 jeremybenn
   Contributor Jeremy Bennett 
7 148 jeremybenn
 
8 180 jeremybenn
   This file is part of Newlib.
9 148 jeremybenn
 
10 180 jeremybenn
   The original work by Jacob Bower is provided as-is without any kind of
11
   warranty. Use it at your own risk!
12 148 jeremybenn
 
13 180 jeremybenn
   All subsequent work is bound by version 3 of the GPL as follows.
14
 
15
   This program is free software; you can redistribute it and/or modify it
16
   under the terms of the GNU General Public License as published by the Free
17
   Software Foundation; either version 3 of the License, or (at your option)
18
   any later version.
19
 
20
   This program is distributed in the hope that it will be useful, but WITHOUT
21
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
23
   more details.
24
 
25
   You should have received a copy of the GNU General Public License along
26
   with this program.  If not, see .            */
27
/* -------------------------------------------------------------------------- */
28
/* This program is commented throughout in a fashion suitable for processing
29
   with Doxygen.                                                              */
30
/* -------------------------------------------------------------------------- */
31
 
32
#include "spr-defs.h"
33
#include "or1ksim-board.h"
34
 
35
 
36
/* -------------------------------------------------------------------------- */
37
/*!Macro for expressions which do not have their own handler.
38
 
39
   Construct the arguments for a call to printf, then exit. Being varargs, the
40
   arguments to printf must be on the stack, which we update using the
41
   standard prologue.
42
 
43
  @param[in] str  Label for a string describing the macro, suitable for
44
                  printf.                                                     */
45
/* -------------------------------------------------------------------------- */
46
#define UNHANDLED_EXCEPTION(str)                                         \
47
        l.addi  r1,r1,-20               /* Standard prologue */         ;\
48
        l.sw    16(r1),r2                                               ;\
49
        l.addi  r2,r1,20                                                ;\
50
        l.sw    12(r1),r9                                               ;\
51
                                                                        ;\
52
        l.movhi r3,hi(.Lfmt)            /* printf format string */      ;\
53
        l.ori   r3,r3,lo(.Lfmt)                                         ;\
54
        l.sw    0(r1),r3                                                ;\
55
        l.movhi r4,hi(str)              /* Name of exception */         ;\
56
        l.ori   r4,r4,lo(str)                                           ;\
57
        l.sw    4(r1),r4                                                ;\
58
        l.mfspr r5,r0,SPR_EPCR_BASE     /* Source of the interrupt */   ;\
59
        l.jal   _printf                                                 ;\
60
        l.sw    8(r1),r5                                                ;\
61
                                                                        ;\
62
        l.ori   r3,r0,0xffff            /* Failure RC */                ;\
63
        l.jal   _exit                                                   ;\
64
        l.nop                                                           ;\
65
                                                                        ;\
66
        l.rfe                           /* Never executed we hope */
67
 
68
 
69
/* -------------------------------------------------------------------------- */
70
/*!Text strings for the different exceptions                                  */
71
/* -------------------------------------------------------------------------- */
72
        .section .rodata
73
.Lfmt:  .string "Unhandled %s exception at address %08p\n"
74
.L200:  .string "bus error"
75
.L300:  .string "data page fault"
76
.L400:  .string "instruction page fault"
77
.L500:  .string "timer"
78
.L600:  .string "alignment"
79
.L700:  .string "illegal instruction"
80
.L800:  .string "external interrupt"
81
.L900:  .string "data TLB"
82
.La00:  .string "instruction TLB"
83
.Lb00:  .string "range"
84
.Lc00:  .string "syscall"
85
.Ld00:  .string "floating point"
86
.Le00:  .string "trap"
87
.Lf00:  .string "undefined 0xf00"
88
.L1000: .string "undefined 0x1000"
89
.L1100: .string "undefined 0x1100"
90
.L1200: .string "undefined 0x1200"
91
.L1300: .string "undefined 0x1300"
92
.L1400: .string "undefined 0x1400"
93
.L1500: .string "undefined 0x1500"
94
.L1600: .string "undefined 0x1600"
95
.L1700: .string "undefined 0x1700"
96
.L1800: .string "undefined 0x1800"
97
.L1900: .string "undefined 0x1900"
98
.L1a00: .string "undefined 0x1a00"
99
.L1b00: .string "undefined 0x1b00"
100
.L1c00: .string "undefined 0x1c00"
101
.L1d00: .string "undefined 0x1d00"
102
.L1e00: .string "undefined 0x1e00"
103
.L1f00: .string "undefined 0x1f00"
104
 
105
 
106
/* -------------------------------------------------------------------------- */
107
/*!Exception vectors                                                          */
108
/* -------------------------------------------------------------------------- */
109 148 jeremybenn
        .section .vectors,"ax"
110
 
111 180 jeremybenn
        /* 0x100: RESET exception */
112
        .org    0x100
113
_reset:
114 148 jeremybenn
        l.nop
115
 
116
        /* Jump to program initialisation code */
117
        l.movhi r2,hi(_start)
118
        l.ori   r2,r2,lo(_start)
119
        l.jr    r2
120
        l.nop
121
 
122 180 jeremybenn
        /* 0x200: BUS exception is special, because during startup we use it
123
           to detect where the stack should go. So we need some special code
124
           before we return, which wel will later overwrite with l.nop.
125 148 jeremybenn
 
126 180 jeremybenn
           We use registers we know will not interfere in this case. */
127
        .org    0x200
128
_buserr:
129
        l.mfspr r24,r0,SPR_EPCR_BASE
130
        l.addi  r24,r24,4               /* Return one instruction on */
131
        l.mtspr r0,r24,SPR_EPCR_BASE
132
        l.rfe
133
 
134
_buserr_std:
135
        UNHANDLED_EXCEPTION (.L200)
136
 
137
        /* 0x300: Data Page Fault exception */
138
        .org    0x300
139
        UNHANDLED_EXCEPTION (.L300)
140 148 jeremybenn
 
141 180 jeremybenn
        /* 0x400: Insn Page Fault exception */
142
        .org    0x400
143
        UNHANDLED_EXCEPTION (.L400)
144 148 jeremybenn
 
145 180 jeremybenn
        /* 0x500: Timer exception */
146
        .org    0x500
147
        UNHANDLED_EXCEPTION (.L500)
148 148 jeremybenn
 
149 180 jeremybenn
        /* 0x600: Aligment exception */
150
        .org    0x600
151
        UNHANDLED_EXCEPTION (.L600)
152 148 jeremybenn
 
153 180 jeremybenn
        /* 0x700: Illegal insn exception */
154
        .org    0x700
155
        UNHANDLED_EXCEPTION (.L700)
156 148 jeremybenn
 
157 180 jeremybenn
        /* 0x800: External interrupt exception */
158
        .org    0x800
159
        UNHANDLED_EXCEPTION (.L800)
160 148 jeremybenn
 
161 180 jeremybenn
        /* 0x900: DTLB miss exception */
162
        .org    0x900
163
        UNHANDLED_EXCEPTION (.L900)
164 148 jeremybenn
 
165 180 jeremybenn
        /* 0xa00: ITLB miss exception */
166
        .org    0xa00
167
        UNHANDLED_EXCEPTION (.La00)
168 148 jeremybenn
 
169 180 jeremybenn
        /* 0xb00: Range exception */
170
        .org    0xb00
171
        UNHANDLED_EXCEPTION (.Lb00)
172 148 jeremybenn
 
173 180 jeremybenn
        /* 0xc00: Syscall exception */
174
        .org    0xc00
175
        UNHANDLED_EXCEPTION (.Lc00)
176 148 jeremybenn
 
177 180 jeremybenn
        /* 0xd00: floating point exception */
178
        .org    0xd00
179
        UNHANDLED_EXCEPTION (.Ld00)
180 148 jeremybenn
 
181 180 jeremybenn
        /* 0xe00: Trap exception */
182
        .org    0xe00
183
        UNHANDLED_EXCEPTION (.Le00)
184 148 jeremybenn
 
185 180 jeremybenn
        /* 0xf00: Reserved exceptions */
186
        .org    0xf00
187
        UNHANDLED_EXCEPTION (.Lf00)
188 148 jeremybenn
 
189 180 jeremybenn
        .org    0x1000
190
        UNHANDLED_EXCEPTION (.L1000)
191 148 jeremybenn
 
192 180 jeremybenn
        .org    0x1100
193
        UNHANDLED_EXCEPTION (.L1100)
194 148 jeremybenn
 
195 180 jeremybenn
        .org    0x1200
196
        UNHANDLED_EXCEPTION (.L1200)
197 148 jeremybenn
 
198 180 jeremybenn
        .org    0x1300
199
        UNHANDLED_EXCEPTION (.L1300)
200 148 jeremybenn
 
201 180 jeremybenn
        .org    0x1400
202
        UNHANDLED_EXCEPTION (.L1400)
203 148 jeremybenn
 
204 180 jeremybenn
        .org    0x1500
205
        UNHANDLED_EXCEPTION (.L1500)
206 148 jeremybenn
 
207 180 jeremybenn
        .org    0x1600
208
        UNHANDLED_EXCEPTION (.L1600)
209 148 jeremybenn
 
210 180 jeremybenn
        .org    0x1700
211
        UNHANDLED_EXCEPTION (.L1700)
212 148 jeremybenn
 
213 180 jeremybenn
        .org    0x1800
214
        UNHANDLED_EXCEPTION (.L1800)
215 148 jeremybenn
 
216 180 jeremybenn
        .org    0x1900
217
        UNHANDLED_EXCEPTION (.L1900)
218 148 jeremybenn
 
219 180 jeremybenn
        .org    0x1a00
220
        UNHANDLED_EXCEPTION (.L1a00)
221 148 jeremybenn
 
222 180 jeremybenn
        .org    0x1b00
223
        UNHANDLED_EXCEPTION (.L1b00)
224 148 jeremybenn
 
225 180 jeremybenn
        .org    0x1c00
226
        UNHANDLED_EXCEPTION (.L1c00)
227 148 jeremybenn
 
228 180 jeremybenn
        .org    0x1d00
229
        UNHANDLED_EXCEPTION (.L1d00)
230 148 jeremybenn
 
231 180 jeremybenn
        .org    0x1e00
232
        UNHANDLED_EXCEPTION (.L1e00)
233 148 jeremybenn
 
234 180 jeremybenn
        .org    0x1f00
235
        UNHANDLED_EXCEPTION (.L1f00)
236 148 jeremybenn
 
237 180 jeremybenn
        /* Pad to the end */
238
        .org    0x1ffc
239
        l.nop
240 148 jeremybenn
 
241 180 jeremybenn
/* -------------------------------------------------------------------------- */
242
/*!Main entry point
243
 
244
   We initialise the stack and frame pointer first, before we set up the
245
   caches, since otherwise we'll need to disable the instruction cache when
246
   patching the bus error vector code.
247
 
248
   The remaining tasks are then:
249
   - optionally set up instruction and/or data caches
250
   - clear BSS
251
   - call global and static constructors
252
   - set up destructors to be called from exit
253
   - initialize the UART (may be dummy, if no UART supported)
254
   - jump to the main function
255
   - call exit if the main function ever returns.
256
   - loop forever (should never get here)                                     */
257
/* -------------------------------------------------------------------------- */
258
        /* The stack grows down from the top of writable memory. */
259
        .section .data
260
        .global _stack
261
_stack: .space  4,0
262
 
263
        .section .text
264 148 jeremybenn
        .global _start
265
        .type   _start,@function
266 180 jeremybenn
 
267 148 jeremybenn
_start:
268 180 jeremybenn
        /* Determine where the stack should end. Must be somewhere above the
269
           end of loaded memory. We look in blocks of 64KB. */
270
        l.movhi r30,hi(end)
271
        l.ori   r30,r30,lo(end)
272
        l.srli  r30,r30,16              /* Round down to 64KB boundary */
273
        l.slli  r30,r30,16
274 148 jeremybenn
 
275 180 jeremybenn
        l.addi  r28,r0,1                /* Constant 64KB in register */
276
        l.slli  r28,r28,16
277
 
278
        l.add   r30,r30,r28
279
        l.addi  r30,r30,-4              /* SP one word inside next 64KB? */
280
 
281
        l.movhi r26,0xaaaa              /* Test pattern to store in memory */
282
        l.ori   r26,r26,0xaaaa
283
 
284
        /* Is this a writeable location? */
285
.L3:
286
        l.sw    0(r30),r26
287
        l.lwz   r24,0(r30)
288
        l.sfeq  r24,r26
289
        l.bnf   .L4
290
        l.nop
291
 
292
        l.j     .L3
293
        l.add   r30,r30,r28             /* Try 64KB higher */
294
 
295
.L4:
296
        l.sub   r30,r30,r28             /* Previous value was wanted */
297
        l.movhi r26,hi(_stack)
298
        l.ori   r26,r26,lo(_stack)
299
        l.sw    0(r26),r30
300
 
301
        /* Initialise stack and frame pointer (set to same value) */
302
        l.add   r1,r30,r0
303
        l.add   r2,r30,r0
304
 
305
        /* Clear out the bus error vector special code. */
306
        l.movhi r30,hi(_buserr)
307
        l.ori   r30,r30,lo(_buserr)
308
        l.movhi r28,hi(_buserr_std)
309
        l.ori   r28,r28,lo(_buserr_std)
310
        l.movhi r26,0x1500              /* l.nop 0 */
311
        l.ori   r26,r26,0x0000
312
 
313
.L5:
314
        l.sfeq  r28,r30
315
        l.bf    .L6
316
        l.nop
317
 
318
        l.sw    0(r30),r26              /* Patch the instruction */
319
        l.j     .L5
320
        l.addi  r30,r30,4               /* Next instruction */
321
 
322
.L6:
323 148 jeremybenn
        /* Cache initialisation */
324
.if IC_ENABLE || DC_ENABLE
325
        /* Flush IC and/or DC */
326
        l.addi  r10,r0,0
327
        l.addi  r11,r0,0
328
        l.addi  r12,r0,0
329
.if IC_ENABLE
330
        l.addi  r11,r0,IC_SIZE
331
.endif
332
.if DC_ENABLE
333
        l.addi  r12,r0,DC_SIZE
334
.endif
335
        l.sfleu r12,r11
336
        l.bf    .L0
337
        l.nop
338
        l.add   r11,r0,r12
339
.L0:
340
.if IC_ENABLE
341
        l.mtspr r0,r10,SPR_ICBIR
342
.endif
343
.if DC_ENABLE
344
        l.mtspr r0,r10,SPR_DCBIR
345
.endif
346
        l.sfne  r10,r11
347
        l.bf    .L0
348
        l.addi  r10,r10,16
349
 
350
        /* Enable IC and/or DC */
351
        l.addi  r10,r0,(SPR_SR_SM)
352
.if IC_ENABLE
353
        l.ori   r10,r10,(SPR_SR_ICE)
354
.endif
355
.if DC_ENABLE
356
        l.ori   r10,r10,(SPR_SR_DCE)
357
.endif
358
        l.mtspr r0,r10,SPR_SR
359
        l.nop
360
        l.nop
361
        l.nop
362
        l.nop
363
        l.nop
364
.endif
365
 
366
        /* Clear BSS */
367 180 jeremybenn
        l.movhi r28,hi(__bss_start)
368
        l.ori   r28,r28,lo(__bss_start)
369
        l.movhi r30,hi(end)
370
        l.ori   r30,r30,lo(end)
371 148 jeremybenn
 
372
.L1:
373
        l.sw    (0)(r28),r0
374
        l.sfltu r28,r30
375
        l.bf    .L1
376
        l.addi  r28,r28,4
377
 
378
        /* Call global and static constructors */
379 180 jeremybenn
        l.movhi r3,hi(init)
380
        l.ori   r3,r3,lo(init)
381
        l.jalr  r3
382
 
383
        /* Set up destructors to be called from exit if main never returns */
384
        l.movhi r3,hi(fini)
385
        l.ori   r3,r3,lo(fini)
386
        l.jal   _atexit
387
 
388
        /* Initialise UART in a C function. If the UART isn't present, we'll */
389
        /* link against a dummy function. */
390
        l.jal    _uart_init
391
        l.nop
392
 
393 148 jeremybenn
        /* Jump to main program entry point (argc = argv = envp = 0) */
394
        l.or    r3,r0,r0
395
        l.or    r4,r0,r0
396
        l.jal   _main
397
        l.or    r5,r0,r0
398 180 jeremybenn
 
399 148 jeremybenn
        /* If program exits, call exit routine */
400
        l.jal   _exit
401
        l.addi  r3,r11,0
402
 
403 180 jeremybenn
        /* Loop forever */
404
.L2:
405
        l.j     .L2
406 148 jeremybenn
        l.nop
407
 
408 180 jeremybenn
        .size   _start, .-_start

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.