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 399

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 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
        /* Finding the end of stack means we need to handle the bus
274
           error. Patch in some special handler code. */
275 399 jeremybenn
        l.movhi r30,hi(__buserr)        /* Where to copy to */
276
        l.ori   r30,r30,lo(__buserr)
277
        l.movhi r28,hi(__buserr_std)    /* Where to stop copying */
278
        l.ori   r28,r28,lo(__buserr_std)
279
        l.movhi r26,hi(__buserr_special)/* Where to copy from */
280
        l.ori   r26,r26,lo(__buserr_special)
281 243 jeremybenn
 
282
.L11:   l.sfeq  r28,r30
283
        l.bf    .L12
284
        l.nop
285
 
286
        l.lwz   r24,0(r26)              /* Get the instruction */
287
        l.sw    0(r30),r24              /* Patch the instruction */
288
        l.addi  r26,r26,4               /* Next source instruction */
289
        l.j     .L11
290
        l.addi  r30,r30,4               /* Delay slot: next dest location */
291
 
292 207 jeremybenn
        /* Determine where the stack should end. Must be somewhere above the
293
           end of loaded memory. We look in blocks of 64KB. */
294 243 jeremybenn
.L12:   l.movhi r30,hi(end)
295 207 jeremybenn
        l.ori   r30,r30,lo(end)
296
        l.srli  r30,r30,16              /* Round down to 64KB boundary */
297
        l.slli  r30,r30,16
298
 
299
        l.addi  r28,r0,1                /* Constant 64KB in register */
300
        l.slli  r28,r28,16
301
 
302
        l.add   r30,r30,r28
303
        l.addi  r30,r30,-4              /* SP one word inside next 64KB? */
304
 
305
        l.movhi r26,0xaaaa              /* Test pattern to store in memory */
306
        l.ori   r26,r26,0xaaaa
307
 
308
        /* Is this a writeable location? */
309 243 jeremybenn
.L3:    l.sw    0(r30),r26
310 207 jeremybenn
        l.lwz   r24,0(r30)
311
        l.sfeq  r24,r26
312
        l.bnf   .L4
313
        l.nop
314
 
315
        l.j     .L3
316
        l.add   r30,r30,r28             /* Try 64KB higher */
317
 
318 243 jeremybenn
.L4:    l.sub   r30,r30,r28             /* Previous value was wanted */
319
        l.movhi r26,hi(stack)
320
        l.ori   r26,r26,lo(stack)
321 207 jeremybenn
        l.sw    0(r26),r30
322
 
323
        /* Initialise stack and frame pointer (set to same value) */
324
        l.add   r1,r30,r0
325
        l.add   r2,r30,r0
326
 
327
        /* Clear out the bus error vector special code. */
328 399 jeremybenn
        l.movhi r30,hi(__buserr)
329
        l.ori   r30,r30,lo(__buserr)
330
        l.movhi r28,hi(__buserr_std)
331
        l.ori   r28,r28,lo(__buserr_std)
332 207 jeremybenn
        l.movhi r26,0x1500              /* l.nop 0 */
333
        l.ori   r26,r26,0x0000
334
 
335 243 jeremybenn
.L5:    l.sfeq  r28,r30
336 207 jeremybenn
        l.bf    .L6
337
        l.nop
338
 
339
        l.sw    0(r30),r26              /* Patch the instruction */
340
        l.j     .L5
341
        l.addi  r30,r30,4               /* Delay slot: next instruction */
342
 
343 226 julius
        /* Instruction cache enable */
344
        /* Check if IC present and skip enabling otherwise */
345 243 jeremybenn
.L6:    l.mfspr r24,r0,SPR_UPR
346 226 julius
        l.andi  r26,r24,SPR_UPR_ICP
347
        l.sfeq  r26,r0
348
        l.bf    .L8
349
        l.nop
350
 
351
        /* Disable IC */
352
        l.mfspr r6,r0,SPR_SR
353
        l.addi  r5,r0,-1
354
        l.xori  r5,r5,SPR_SR_ICE
355
        l.and   r5,r6,r5
356
        l.mtspr r0,r5,SPR_SR
357
 
358
        /* Establish cache block size
359
        If BS=0, 16;
360
        If BS=1, 32;
361
        r14 contain block size
362
        */
363
        l.mfspr r24,r0,SPR_ICCFGR
364
        l.andi  r26,r24,SPR_ICCFGR_CBS
365
        l.srli  r28,r26,7
366
        l.ori   r30,r0,16
367
        l.sll   r14,r30,r28
368
 
369
        /* Establish number of cache sets
370
        r16 contains number of cache sets
371
        r28 contains log(# of cache sets)
372
        */
373
        l.andi  r26,r24,SPR_ICCFGR_NCS
374
        l.srli  r28,r26,3
375
        l.ori   r30,r0,1
376
        l.sll   r16,r30,r28
377
 
378
        /* Invalidate IC */
379
        l.addi  r6,r0,0
380
        l.sll   r5,r14,r28
381
 
382 243 jeremybenn
.L7:    l.mtspr r0,r6,SPR_ICBIR
383 226 julius
        l.sfne  r6,r5
384
        l.bf    .L7
385
        l.add   r6,r6,r14
386
 
387
        /* Enable IC */
388
        l.mfspr r6,r0,SPR_SR
389
        l.ori   r6,r6,SPR_SR_ICE
390
        l.mtspr r0,r6,SPR_SR
391
        l.nop
392
        l.nop
393
        l.nop
394
        l.nop
395
        l.nop
396
        l.nop
397
        l.nop
398
        l.nop
399
 
400
        /* Data cache enable */
401
        /* Check if DC present and skip enabling otherwise */
402 243 jeremybenn
.L8:    l.mfspr r24,r0,SPR_UPR
403 226 julius
        l.andi  r26,r24,SPR_UPR_DCP
404
        l.sfeq  r26,r0
405
        l.bf    .L10
406 207 jeremybenn
        l.nop
407 226 julius
        /* Disable DC */
408
        l.mfspr r6,r0,SPR_SR
409
        l.addi  r5,r0,-1
410
        l.xori  r5,r5,SPR_SR_DCE
411
        l.and   r5,r6,r5
412
        l.mtspr r0,r5,SPR_SR
413
        /* Establish cache block size
414
           If BS=0, 16;
415
           If BS=1, 32;
416
           r14 contain block size
417
        */
418
        l.mfspr r24,r0,SPR_DCCFGR
419
        l.andi  r26,r24,SPR_DCCFGR_CBS
420
        l.srli  r28,r26,7
421
        l.ori   r30,r0,16
422
        l.sll   r14,r30,r28
423
        /* Establish number of cache sets
424
           r16 contains number of cache sets
425
           r28 contains log(# of cache sets)
426
        */
427
        l.andi  r26,r24,SPR_DCCFGR_NCS
428
        l.srli  r28,r26,3
429
        l.ori   r30,r0,1
430
        l.sll   r16,r30,r28
431
        /* Invalidate DC */
432
        l.addi  r6,r0,0
433
        l.sll   r5,r14,r28
434 243 jeremybenn
 
435
.L9:    l.mtspr r0,r6,SPR_DCBIR
436 226 julius
        l.sfne  r6,r5
437
        l.bf    .L9
438
        l.add   r6,r6,r14
439
        /* Enable DC */
440
        l.mfspr r6,r0,SPR_SR
441
        l.ori   r6,r6,SPR_SR_DCE
442
        l.mtspr r0,r6,SPR_SR
443 207 jeremybenn
 
444
        /* Clear BSS */
445 243 jeremybenn
.L10:   l.movhi r28,hi(__bss_start)
446 207 jeremybenn
        l.ori   r28,r28,lo(__bss_start)
447
        l.movhi r30,hi(end)
448
        l.ori   r30,r30,lo(end)
449
 
450 243 jeremybenn
.L1:    l.sw    (0)(r28),r0
451 207 jeremybenn
        l.sfltu r28,r30
452
        l.bf    .L1
453
        l.addi  r28,r28,4               /* Delay slot */
454
 
455
        /* Call global and static constructors */
456 399 jeremybenn
        l.jal   __init
457 207 jeremybenn
        l.nop
458
 
459
        /* Set up destructors to be called from exit if main never returns */
460 399 jeremybenn
        l.movhi r3,hi(__fini)
461 243 jeremybenn
        l.jal   atexit
462 399 jeremybenn
        l.ori   r3,r3,lo(__fini)        /* Delay slot */
463 207 jeremybenn
 
464
        /* Initialise UART in a C function. If the UART isn't present, we'll */
465
        /* link against a dummy function. */
466 399 jeremybenn
        l.jal    __uart_init
467 207 jeremybenn
        l.nop
468
 
469
        /* Jump to main program entry point (argc = argv = envp = 0) */
470
        l.or    r3,r0,r0
471
        l.or    r4,r0,r0
472 243 jeremybenn
        l.jal   main
473 207 jeremybenn
        l.or    r5,r0,r0                /* Delay slot */
474
 
475
        /* If program exits, call exit routine */
476 399 jeremybenn
        l.jal   exit
477 207 jeremybenn
        l.addi  r3,r11,0                /* Delay slot */
478
 
479
        /* Loop forever */
480 243 jeremybenn
.L2:    l.j     .L2
481 207 jeremybenn
        l.nop
482
 
483
        .size   _start, .-_start

powered by: WebSVN 2.1.0

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