OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

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

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

Line No. Rev Author Line
1 207 jeremybenn
/* crt0.S. C Runtime startup file.
2
 
3
   Copyright (C) 2004, Jacob Bower
4
   Copyright (C) 2010, Embecosm Limited 
5
 
6
   Contributor Jeremy Bennett 
7
 
8
   This file is part of Newlib.
9
 
10
   The original work by Jacob Bower is provided as-is without any kind of
11
   warranty. Use it at your own risk!
12
 
13
   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
        .section .vectors,"ax"
110
 
111
        /* 0x100: RESET exception */
112
        .org    0x100
113
_reset:
114
        /* Jump to program initialisation code */
115
        l.j     _start
116
        l.nop
117
 
118
        /* 0x200: BUS exception is special, because during startup we use it
119
           to detect where the stack should go. So we need some special code
120
           before we return, which wel will later overwrite with l.nop.
121
 
122
           We use registers we know will not interfere in this case. */
123
        .org    0x200
124
_buserr:
125
        l.mfspr r24,r0,SPR_EPCR_BASE
126
        l.addi  r24,r24,4               /* Return one instruction on */
127
        l.mtspr r0,r24,SPR_EPCR_BASE
128
        l.rfe
129
 
130
_buserr_std:
131
        UNHANDLED_EXCEPTION (.L200)
132
 
133
        /* 0x300: Data Page Fault exception */
134
        .org    0x300
135
        UNHANDLED_EXCEPTION (.L300)
136
 
137
        /* 0x400: Insn Page Fault exception */
138
        .org    0x400
139
        UNHANDLED_EXCEPTION (.L400)
140
 
141
        /* 0x500: Timer exception */
142
        .org    0x500
143
        UNHANDLED_EXCEPTION (.L500)
144
 
145
        /* 0x600: Aligment exception */
146
        .org    0x600
147
        UNHANDLED_EXCEPTION (.L600)
148
 
149
        /* 0x700: Illegal insn exception */
150
        .org    0x700
151
        UNHANDLED_EXCEPTION (.L700)
152
 
153
        /* 0x800: External interrupt exception */
154
        .org    0x800
155
        UNHANDLED_EXCEPTION (.L800)
156
 
157
        /* 0x900: DTLB miss exception */
158
        .org    0x900
159
        UNHANDLED_EXCEPTION (.L900)
160
 
161
        /* 0xa00: ITLB miss exception */
162
        .org    0xa00
163
        UNHANDLED_EXCEPTION (.La00)
164
 
165
        /* 0xb00: Range exception */
166
        .org    0xb00
167
        UNHANDLED_EXCEPTION (.Lb00)
168
 
169
        /* 0xc00: Syscall exception */
170
        .org    0xc00
171
        UNHANDLED_EXCEPTION (.Lc00)
172
 
173
        /* 0xd00: floating point exception */
174
        .org    0xd00
175
        UNHANDLED_EXCEPTION (.Ld00)
176
 
177
        /* 0xe00: Trap exception */
178
        .org    0xe00
179
        UNHANDLED_EXCEPTION (.Le00)
180
 
181
        /* 0xf00: Reserved exceptions */
182
        .org    0xf00
183
        UNHANDLED_EXCEPTION (.Lf00)
184
 
185
        .org    0x1000
186
        UNHANDLED_EXCEPTION (.L1000)
187
 
188
        .org    0x1100
189
        UNHANDLED_EXCEPTION (.L1100)
190
 
191
        .org    0x1200
192
        UNHANDLED_EXCEPTION (.L1200)
193
 
194
        .org    0x1300
195
        UNHANDLED_EXCEPTION (.L1300)
196
 
197
        .org    0x1400
198
        UNHANDLED_EXCEPTION (.L1400)
199
 
200
        .org    0x1500
201
        UNHANDLED_EXCEPTION (.L1500)
202
 
203
        .org    0x1600
204
        UNHANDLED_EXCEPTION (.L1600)
205
 
206
        .org    0x1700
207
        UNHANDLED_EXCEPTION (.L1700)
208
 
209
        .org    0x1800
210
        UNHANDLED_EXCEPTION (.L1800)
211
 
212
        .org    0x1900
213
        UNHANDLED_EXCEPTION (.L1900)
214
 
215
        .org    0x1a00
216
        UNHANDLED_EXCEPTION (.L1a00)
217
 
218
        .org    0x1b00
219
        UNHANDLED_EXCEPTION (.L1b00)
220
 
221
        .org    0x1c00
222
        UNHANDLED_EXCEPTION (.L1c00)
223
 
224
        .org    0x1d00
225
        UNHANDLED_EXCEPTION (.L1d00)
226
 
227
        .org    0x1e00
228
        UNHANDLED_EXCEPTION (.L1e00)
229
 
230
        .org    0x1f00
231
        UNHANDLED_EXCEPTION (.L1f00)
232
 
233
        /* Pad to the end */
234
        .org    0x1ffc
235
        l.nop
236
 
237
/* -------------------------------------------------------------------------- */
238
/*!Main entry point
239
 
240
   We initialise the stack and frame pointer first, before we set up the
241
   caches, since otherwise we'll need to disable the instruction cache when
242
   patching the bus error vector code.
243
 
244
   The remaining tasks are then:
245
   - optionally set up instruction and/or data caches
246
   - clear BSS
247
   - call global and static constructors
248
   - set up destructors to be called from exit
249
   - initialize the UART (may be dummy, if no UART supported)
250
   - jump to the main function
251
   - call exit if the main function ever returns.
252
   - loop forever (should never get here)                                     */
253
/* -------------------------------------------------------------------------- */
254
        /* The stack grows down from the top of writable memory. */
255
        .section .data
256
        .global _stack
257
_stack: .space  4,0
258
 
259
        .section .text
260
        .global _start
261
        .type   _start,@function
262
 
263
_start:
264
        /* Determine where the stack should end. Must be somewhere above the
265
           end of loaded memory. We look in blocks of 64KB. */
266
        l.movhi r30,hi(end)
267
        l.ori   r30,r30,lo(end)
268
        l.srli  r30,r30,16              /* Round down to 64KB boundary */
269
        l.slli  r30,r30,16
270
 
271
        l.addi  r28,r0,1                /* Constant 64KB in register */
272
        l.slli  r28,r28,16
273
 
274
        l.add   r30,r30,r28
275
        l.addi  r30,r30,-4              /* SP one word inside next 64KB? */
276
 
277
        l.movhi r26,0xaaaa              /* Test pattern to store in memory */
278
        l.ori   r26,r26,0xaaaa
279
 
280
        /* Is this a writeable location? */
281
.L3:
282
        l.sw    0(r30),r26
283
        l.lwz   r24,0(r30)
284
        l.sfeq  r24,r26
285
        l.bnf   .L4
286
        l.nop
287
 
288
        l.j     .L3
289
        l.add   r30,r30,r28             /* Try 64KB higher */
290
 
291
.L4:
292
        l.sub   r30,r30,r28             /* Previous value was wanted */
293
        l.movhi r26,hi(_stack)
294
        l.ori   r26,r26,lo(_stack)
295
        l.sw    0(r26),r30
296
 
297
        /* Initialise stack and frame pointer (set to same value) */
298
        l.add   r1,r30,r0
299
        l.add   r2,r30,r0
300
 
301
        /* Clear out the bus error vector special code. */
302
        l.movhi r30,hi(_buserr)
303
        l.ori   r30,r30,lo(_buserr)
304
        l.movhi r28,hi(_buserr_std)
305
        l.ori   r28,r28,lo(_buserr_std)
306
        l.movhi r26,0x1500              /* l.nop 0 */
307
        l.ori   r26,r26,0x0000
308
 
309
.L5:
310
        l.sfeq  r28,r30
311
        l.bf    .L6
312
        l.nop
313
 
314
        l.sw    0(r30),r26              /* Patch the instruction */
315
        l.j     .L5
316
        l.addi  r30,r30,4               /* Delay slot: next instruction */
317
 
318
.L6:
319
        /* Cache initialisation. Enable IC and/or DC */
320
.if IC_ENABLE || DC_ENABLE
321
        l.mfspr r10,r0,SPR_SR
322
.if IC_ENABLE
323
        l.ori   r10,r10,SPR_SR_ICE
324
.endif
325
.if DC_ENABLE
326
        l.ori   r10,r10,SPR_SR_DCE
327
.endif
328
        l.mtspr r0,r10,SPR_SR
329
        l.nop                           /* Flush the pipeline. */
330
        l.nop
331
        l.nop
332
        l.nop
333
        l.nop
334
.endif
335
 
336
        /* Clear BSS */
337
        l.movhi r28,hi(__bss_start)
338
        l.ori   r28,r28,lo(__bss_start)
339
        l.movhi r30,hi(end)
340
        l.ori   r30,r30,lo(end)
341
 
342
.L1:
343
        l.sw    (0)(r28),r0
344
        l.sfltu r28,r30
345
        l.bf    .L1
346
        l.addi  r28,r28,4               /* Delay slot */
347
 
348
        /* Call global and static constructors */
349
        l.jal   init
350
        l.nop
351
 
352
        /* Set up destructors to be called from exit if main never returns */
353
        l.movhi r3,hi(fini)
354
        l.jal   _atexit
355
        l.ori   r3,r3,lo(fini)          /* Delay slot */
356
 
357
        /* Initialise UART in a C function. If the UART isn't present, we'll */
358
        /* link against a dummy function. */
359
        l.jal    __uart_init
360
        l.nop
361
 
362
        /* Jump to main program entry point (argc = argv = envp = 0) */
363
        l.or    r3,r0,r0
364
        l.or    r4,r0,r0
365
        l.jal   _main
366
        l.or    r5,r0,r0                /* Delay slot */
367
 
368
        /* If program exits, call exit routine */
369
        l.jal   _exit
370
        l.addi  r3,r11,0                /* Delay slot */
371
 
372
        /* Loop forever */
373
.L2:
374
        l.j     .L2
375
        l.nop
376
 
377
        .size   _start, .-_start

powered by: WebSVN 2.1.0

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