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 226

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 226 julius
        /* Instruction cache enable */
320
        /* Check if IC present and skip enabling otherwise */
321
        l.mfspr r24,r0,SPR_UPR
322
        l.andi  r26,r24,SPR_UPR_ICP
323
        l.sfeq  r26,r0
324
        l.bf    .L8
325
        l.nop
326
 
327
        /* Disable IC */
328
        l.mfspr r6,r0,SPR_SR
329
        l.addi  r5,r0,-1
330
        l.xori  r5,r5,SPR_SR_ICE
331
        l.and   r5,r6,r5
332
        l.mtspr r0,r5,SPR_SR
333
 
334
        /* Establish cache block size
335
        If BS=0, 16;
336
        If BS=1, 32;
337
        r14 contain block size
338
        */
339
        l.mfspr r24,r0,SPR_ICCFGR
340
        l.andi  r26,r24,SPR_ICCFGR_CBS
341
        l.srli  r28,r26,7
342
        l.ori   r30,r0,16
343
        l.sll   r14,r30,r28
344
 
345
        /* Establish number of cache sets
346
        r16 contains number of cache sets
347
        r28 contains log(# of cache sets)
348
        */
349
        l.andi  r26,r24,SPR_ICCFGR_NCS
350
        l.srli  r28,r26,3
351
        l.ori   r30,r0,1
352
        l.sll   r16,r30,r28
353
 
354
        /* Invalidate IC */
355
        l.addi  r6,r0,0
356
        l.sll   r5,r14,r28
357
 
358
.L7:
359
        l.mtspr r0,r6,SPR_ICBIR
360
        l.sfne  r6,r5
361
        l.bf    .L7
362
        l.add   r6,r6,r14
363
 
364
        /* Enable IC */
365
        l.mfspr r6,r0,SPR_SR
366
        l.ori   r6,r6,SPR_SR_ICE
367
        l.mtspr r0,r6,SPR_SR
368
        l.nop
369
        l.nop
370
        l.nop
371
        l.nop
372
        l.nop
373
        l.nop
374
        l.nop
375
        l.nop
376
 
377
.L8:
378
        /* Data cache enable */
379
        /* Check if DC present and skip enabling otherwise */
380
        l.mfspr r24,r0,SPR_UPR
381
        l.andi  r26,r24,SPR_UPR_DCP
382
        l.sfeq  r26,r0
383
        l.bf    .L10
384 207 jeremybenn
        l.nop
385 226 julius
        /* Disable DC */
386
        l.mfspr r6,r0,SPR_SR
387
        l.addi  r5,r0,-1
388
        l.xori  r5,r5,SPR_SR_DCE
389
        l.and   r5,r6,r5
390
        l.mtspr r0,r5,SPR_SR
391
        /* Establish cache block size
392
           If BS=0, 16;
393
           If BS=1, 32;
394
           r14 contain block size
395
        */
396
        l.mfspr r24,r0,SPR_DCCFGR
397
        l.andi  r26,r24,SPR_DCCFGR_CBS
398
        l.srli  r28,r26,7
399
        l.ori   r30,r0,16
400
        l.sll   r14,r30,r28
401
        /* Establish number of cache sets
402
           r16 contains number of cache sets
403
           r28 contains log(# of cache sets)
404
        */
405
        l.andi  r26,r24,SPR_DCCFGR_NCS
406
        l.srli  r28,r26,3
407
        l.ori   r30,r0,1
408
        l.sll   r16,r30,r28
409
        /* Invalidate DC */
410
        l.addi  r6,r0,0
411
        l.sll   r5,r14,r28
412
.L9:
413
        l.mtspr r0,r6,SPR_DCBIR
414
        l.sfne  r6,r5
415
        l.bf    .L9
416
        l.add   r6,r6,r14
417
        /* Enable DC */
418
        l.mfspr r6,r0,SPR_SR
419
        l.ori   r6,r6,SPR_SR_DCE
420
        l.mtspr r0,r6,SPR_SR
421 207 jeremybenn
 
422 226 julius
.L10:
423 207 jeremybenn
        /* Clear BSS */
424
        l.movhi r28,hi(__bss_start)
425
        l.ori   r28,r28,lo(__bss_start)
426
        l.movhi r30,hi(end)
427
        l.ori   r30,r30,lo(end)
428
 
429
.L1:
430
        l.sw    (0)(r28),r0
431
        l.sfltu r28,r30
432
        l.bf    .L1
433
        l.addi  r28,r28,4               /* Delay slot */
434
 
435
        /* Call global and static constructors */
436
        l.jal   init
437
        l.nop
438
 
439
        /* Set up destructors to be called from exit if main never returns */
440
        l.movhi r3,hi(fini)
441
        l.jal   _atexit
442
        l.ori   r3,r3,lo(fini)          /* Delay slot */
443
 
444
        /* Initialise UART in a C function. If the UART isn't present, we'll */
445
        /* link against a dummy function. */
446
        l.jal    __uart_init
447
        l.nop
448
 
449
        /* Jump to main program entry point (argc = argv = envp = 0) */
450
        l.or    r3,r0,r0
451
        l.or    r4,r0,r0
452
        l.jal   _main
453
        l.or    r5,r0,r0                /* Delay slot */
454
 
455
        /* If program exits, call exit routine */
456
        l.jal   _exit
457
        l.addi  r3,r11,0                /* Delay slot */
458
 
459
        /* Loop forever */
460
.L2:
461
        l.j     .L2
462
        l.nop
463
 
464
        .size   _start, .-_start

powered by: WebSVN 2.1.0

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