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 469

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 243 jeremybenn
        l.jal   printf                                                  ;\
60 207 jeremybenn
        l.sw    8(r1),r5                                                ;\
61
                                                                        ;\
62
        l.ori   r3,r0,0xffff            /* Failure RC */                ;\
63 399 jeremybenn
        l.jal   exit                                                    ;\
64 207 jeremybenn
        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 399 jeremybenn
__reset:
114 207 jeremybenn
        /* 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 243 jeremybenn
           before we return, which wel will later overwrite with l.nop. We
121
           need to deal with the case when _start is called multiple times, so
122
           this code must be copied into the bus error vector each time. It is
123
           position independent to allow this copying.
124 207 jeremybenn
 
125
           We use registers we know will not interfere in this case. */
126
        .org    0x200
127 399 jeremybenn
__buserr:
128 243 jeremybenn
        l.nop                           /* Will be overwritten */
129
        l.nop
130
        l.nop
131
        l.nop
132
 
133 399 jeremybenn
__buserr_std:
134 243 jeremybenn
        UNHANDLED_EXCEPTION (.L200)
135
 
136 399 jeremybenn
__buserr_special:
137 207 jeremybenn
        l.mfspr r24,r0,SPR_EPCR_BASE
138
        l.addi  r24,r24,4               /* Return one instruction on */
139
        l.mtspr r0,r24,SPR_EPCR_BASE
140
        l.rfe
141
 
142
        /* 0x300: Data Page Fault exception */
143
        .org    0x300
144
        UNHANDLED_EXCEPTION (.L300)
145
 
146
        /* 0x400: Insn Page Fault exception */
147
        .org    0x400
148
        UNHANDLED_EXCEPTION (.L400)
149
 
150
        /* 0x500: Timer exception */
151
        .org    0x500
152
        UNHANDLED_EXCEPTION (.L500)
153
 
154
        /* 0x600: Aligment exception */
155
        .org    0x600
156
        UNHANDLED_EXCEPTION (.L600)
157
 
158
        /* 0x700: Illegal insn exception */
159
        .org    0x700
160
        UNHANDLED_EXCEPTION (.L700)
161
 
162
        /* 0x800: External interrupt exception */
163
        .org    0x800
164
        UNHANDLED_EXCEPTION (.L800)
165
 
166
        /* 0x900: DTLB miss exception */
167
        .org    0x900
168
        UNHANDLED_EXCEPTION (.L900)
169
 
170
        /* 0xa00: ITLB miss exception */
171
        .org    0xa00
172
        UNHANDLED_EXCEPTION (.La00)
173
 
174
        /* 0xb00: Range exception */
175
        .org    0xb00
176
        UNHANDLED_EXCEPTION (.Lb00)
177
 
178
        /* 0xc00: Syscall exception */
179
        .org    0xc00
180
        UNHANDLED_EXCEPTION (.Lc00)
181
 
182
        /* 0xd00: floating point exception */
183
        .org    0xd00
184
        UNHANDLED_EXCEPTION (.Ld00)
185
 
186
        /* 0xe00: Trap exception */
187
        .org    0xe00
188
        UNHANDLED_EXCEPTION (.Le00)
189
 
190
        /* 0xf00: Reserved exceptions */
191
        .org    0xf00
192
        UNHANDLED_EXCEPTION (.Lf00)
193
 
194
        .org    0x1000
195
        UNHANDLED_EXCEPTION (.L1000)
196
 
197
        .org    0x1100
198
        UNHANDLED_EXCEPTION (.L1100)
199
 
200
        .org    0x1200
201
        UNHANDLED_EXCEPTION (.L1200)
202
 
203
        .org    0x1300
204
        UNHANDLED_EXCEPTION (.L1300)
205
 
206
        .org    0x1400
207
        UNHANDLED_EXCEPTION (.L1400)
208
 
209
        .org    0x1500
210
        UNHANDLED_EXCEPTION (.L1500)
211
 
212
        .org    0x1600
213
        UNHANDLED_EXCEPTION (.L1600)
214
 
215
        .org    0x1700
216
        UNHANDLED_EXCEPTION (.L1700)
217
 
218
        .org    0x1800
219
        UNHANDLED_EXCEPTION (.L1800)
220
 
221
        .org    0x1900
222
        UNHANDLED_EXCEPTION (.L1900)
223
 
224
        .org    0x1a00
225
        UNHANDLED_EXCEPTION (.L1a00)
226
 
227
        .org    0x1b00
228
        UNHANDLED_EXCEPTION (.L1b00)
229
 
230
        .org    0x1c00
231
        UNHANDLED_EXCEPTION (.L1c00)
232
 
233
        .org    0x1d00
234
        UNHANDLED_EXCEPTION (.L1d00)
235
 
236
        .org    0x1e00
237
        UNHANDLED_EXCEPTION (.L1e00)
238
 
239
        .org    0x1f00
240
        UNHANDLED_EXCEPTION (.L1f00)
241
 
242
        /* Pad to the end */
243
        .org    0x1ffc
244
        l.nop
245
 
246
/* -------------------------------------------------------------------------- */
247
/*!Main entry point
248
 
249
   We initialise the stack and frame pointer first, before we set up the
250
   caches, since otherwise we'll need to disable the instruction cache when
251
   patching the bus error vector code.
252
 
253
   The remaining tasks are then:
254
   - optionally set up instruction and/or data caches
255
   - clear BSS
256
   - call global and static constructors
257
   - set up destructors to be called from exit
258
   - initialize the UART (may be dummy, if no UART supported)
259
   - jump to the main function
260
   - call exit if the main function ever returns.
261
   - loop forever (should never get here)                                     */
262
/* -------------------------------------------------------------------------- */
263
        /* The stack grows down from the top of writable memory. */
264
        .section .data
265 243 jeremybenn
        .global stack
266
stack:  .space  4,0
267 207 jeremybenn
 
268
        .section .text
269
        .global _start
270
        .type   _start,@function
271
 
272 243 jeremybenn
_start:
273 469 julius
        /* First, clear r0. */
274
        l.movhi r0,0
275 243 jeremybenn
        /* Finding the end of stack means we need to handle the bus
276
           error. Patch in some special handler code. */
277 399 jeremybenn
        l.movhi r30,hi(__buserr)        /* Where to copy to */
278
        l.ori   r30,r30,lo(__buserr)
279
        l.movhi r28,hi(__buserr_std)    /* Where to stop copying */
280
        l.ori   r28,r28,lo(__buserr_std)
281
        l.movhi r26,hi(__buserr_special)/* Where to copy from */
282
        l.ori   r26,r26,lo(__buserr_special)
283 243 jeremybenn
 
284
.L11:   l.sfeq  r28,r30
285
        l.bf    .L12
286
        l.nop
287
 
288
        l.lwz   r24,0(r26)              /* Get the instruction */
289
        l.sw    0(r30),r24              /* Patch the instruction */
290
        l.addi  r26,r26,4               /* Next source instruction */
291
        l.j     .L11
292
        l.addi  r30,r30,4               /* Delay slot: next dest location */
293
 
294 207 jeremybenn
        /* Determine where the stack should end. Must be somewhere above the
295
           end of loaded memory. We look in blocks of 64KB. */
296 243 jeremybenn
.L12:   l.movhi r30,hi(end)
297 207 jeremybenn
        l.ori   r30,r30,lo(end)
298
        l.srli  r30,r30,16              /* Round down to 64KB boundary */
299
        l.slli  r30,r30,16
300
 
301
        l.addi  r28,r0,1                /* Constant 64KB in register */
302
        l.slli  r28,r28,16
303
 
304
        l.add   r30,r30,r28
305
        l.addi  r30,r30,-4              /* SP one word inside next 64KB? */
306
 
307
        l.movhi r26,0xaaaa              /* Test pattern to store in memory */
308
        l.ori   r26,r26,0xaaaa
309
 
310
        /* Is this a writeable location? */
311 243 jeremybenn
.L3:    l.sw    0(r30),r26
312 207 jeremybenn
        l.lwz   r24,0(r30)
313
        l.sfeq  r24,r26
314
        l.bnf   .L4
315
        l.nop
316
 
317
        l.j     .L3
318
        l.add   r30,r30,r28             /* Try 64KB higher */
319
 
320 243 jeremybenn
.L4:    l.sub   r30,r30,r28             /* Previous value was wanted */
321
        l.movhi r26,hi(stack)
322
        l.ori   r26,r26,lo(stack)
323 207 jeremybenn
        l.sw    0(r26),r30
324
 
325
        /* Initialise stack and frame pointer (set to same value) */
326
        l.add   r1,r30,r0
327
        l.add   r2,r30,r0
328
 
329
        /* Clear out the bus error vector special code. */
330 399 jeremybenn
        l.movhi r30,hi(__buserr)
331
        l.ori   r30,r30,lo(__buserr)
332
        l.movhi r28,hi(__buserr_std)
333
        l.ori   r28,r28,lo(__buserr_std)
334 207 jeremybenn
        l.movhi r26,0x1500              /* l.nop 0 */
335
        l.ori   r26,r26,0x0000
336
 
337 243 jeremybenn
.L5:    l.sfeq  r28,r30
338 207 jeremybenn
        l.bf    .L6
339
        l.nop
340
 
341
        l.sw    0(r30),r26              /* Patch the instruction */
342
        l.j     .L5
343
        l.addi  r30,r30,4               /* Delay slot: next instruction */
344
 
345 226 julius
        /* Instruction cache enable */
346
        /* Check if IC present and skip enabling otherwise */
347 243 jeremybenn
.L6:    l.mfspr r24,r0,SPR_UPR
348 226 julius
        l.andi  r26,r24,SPR_UPR_ICP
349
        l.sfeq  r26,r0
350
        l.bf    .L8
351
        l.nop
352
 
353
        /* Disable IC */
354
        l.mfspr r6,r0,SPR_SR
355
        l.addi  r5,r0,-1
356
        l.xori  r5,r5,SPR_SR_ICE
357
        l.and   r5,r6,r5
358
        l.mtspr r0,r5,SPR_SR
359
 
360
        /* Establish cache block size
361
        If BS=0, 16;
362
        If BS=1, 32;
363
        r14 contain block size
364
        */
365
        l.mfspr r24,r0,SPR_ICCFGR
366
        l.andi  r26,r24,SPR_ICCFGR_CBS
367
        l.srli  r28,r26,7
368
        l.ori   r30,r0,16
369
        l.sll   r14,r30,r28
370
 
371
        /* Establish number of cache sets
372
        r16 contains number of cache sets
373
        r28 contains log(# of cache sets)
374
        */
375
        l.andi  r26,r24,SPR_ICCFGR_NCS
376
        l.srli  r28,r26,3
377
        l.ori   r30,r0,1
378
        l.sll   r16,r30,r28
379
 
380
        /* Invalidate IC */
381
        l.addi  r6,r0,0
382
        l.sll   r5,r14,r28
383
 
384 243 jeremybenn
.L7:    l.mtspr r0,r6,SPR_ICBIR
385 226 julius
        l.sfne  r6,r5
386
        l.bf    .L7
387
        l.add   r6,r6,r14
388
 
389
        /* Enable IC */
390
        l.mfspr r6,r0,SPR_SR
391
        l.ori   r6,r6,SPR_SR_ICE
392
        l.mtspr r0,r6,SPR_SR
393
        l.nop
394
        l.nop
395
        l.nop
396
        l.nop
397
        l.nop
398
        l.nop
399
        l.nop
400
        l.nop
401
 
402
        /* Data cache enable */
403
        /* Check if DC present and skip enabling otherwise */
404 243 jeremybenn
.L8:    l.mfspr r24,r0,SPR_UPR
405 226 julius
        l.andi  r26,r24,SPR_UPR_DCP
406
        l.sfeq  r26,r0
407
        l.bf    .L10
408 207 jeremybenn
        l.nop
409 226 julius
        /* Disable DC */
410
        l.mfspr r6,r0,SPR_SR
411
        l.addi  r5,r0,-1
412
        l.xori  r5,r5,SPR_SR_DCE
413
        l.and   r5,r6,r5
414
        l.mtspr r0,r5,SPR_SR
415
        /* Establish cache block size
416
           If BS=0, 16;
417
           If BS=1, 32;
418
           r14 contain block size
419
        */
420
        l.mfspr r24,r0,SPR_DCCFGR
421
        l.andi  r26,r24,SPR_DCCFGR_CBS
422
        l.srli  r28,r26,7
423
        l.ori   r30,r0,16
424
        l.sll   r14,r30,r28
425
        /* Establish number of cache sets
426
           r16 contains number of cache sets
427
           r28 contains log(# of cache sets)
428
        */
429
        l.andi  r26,r24,SPR_DCCFGR_NCS
430
        l.srli  r28,r26,3
431
        l.ori   r30,r0,1
432
        l.sll   r16,r30,r28
433
        /* Invalidate DC */
434
        l.addi  r6,r0,0
435
        l.sll   r5,r14,r28
436 243 jeremybenn
 
437
.L9:    l.mtspr r0,r6,SPR_DCBIR
438 226 julius
        l.sfne  r6,r5
439
        l.bf    .L9
440
        l.add   r6,r6,r14
441
        /* Enable DC */
442
        l.mfspr r6,r0,SPR_SR
443
        l.ori   r6,r6,SPR_SR_DCE
444
        l.mtspr r0,r6,SPR_SR
445 207 jeremybenn
 
446
        /* Clear BSS */
447 243 jeremybenn
.L10:   l.movhi r28,hi(__bss_start)
448 207 jeremybenn
        l.ori   r28,r28,lo(__bss_start)
449
        l.movhi r30,hi(end)
450
        l.ori   r30,r30,lo(end)
451
 
452 243 jeremybenn
.L1:    l.sw    (0)(r28),r0
453 207 jeremybenn
        l.sfltu r28,r30
454
        l.bf    .L1
455
        l.addi  r28,r28,4               /* Delay slot */
456
 
457
        /* Call global and static constructors */
458 399 jeremybenn
        l.jal   __init
459 207 jeremybenn
        l.nop
460
 
461
        /* Set up destructors to be called from exit if main never returns */
462 399 jeremybenn
        l.movhi r3,hi(__fini)
463 243 jeremybenn
        l.jal   atexit
464 399 jeremybenn
        l.ori   r3,r3,lo(__fini)        /* Delay slot */
465 207 jeremybenn
 
466
        /* Initialise UART in a C function. If the UART isn't present, we'll */
467
        /* link against a dummy function. */
468 399 jeremybenn
        l.jal    __uart_init
469 207 jeremybenn
        l.nop
470
 
471
        /* Jump to main program entry point (argc = argv = envp = 0) */
472
        l.or    r3,r0,r0
473
        l.or    r4,r0,r0
474 243 jeremybenn
        l.jal   main
475 207 jeremybenn
        l.or    r5,r0,r0                /* Delay slot */
476
 
477
        /* If program exits, call exit routine */
478 399 jeremybenn
        l.jal   exit
479 207 jeremybenn
        l.addi  r3,r11,0                /* Delay slot */
480
 
481
        /* Loop forever */
482 243 jeremybenn
.L2:    l.j     .L2
483 207 jeremybenn
        l.nop
484
 
485
        .size   _start, .-_start

powered by: WebSVN 2.1.0

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