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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [syn/] [components/] [sd_card/] [firmware/] [bsp/] [HAL/] [src/] [crt0.S] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 alfik
/******************************************************************************
2
*                                                                             *
3
* License Agreement                                                           *
4
*                                                                             *
5
* Copyright (c) 2006 Altera Corporation, San Jose, California, USA.           *
6
* All rights reserved.                                                        *
7
*                                                                             *
8
* Permission is hereby granted, free of charge, to any person obtaining a     *
9
* copy of this software and associated documentation files (the "Software"),  *
10
* to deal in the Software without restriction, including without limitation   *
11
* the rights to use, copy, modify, merge, publish, distribute, sublicense,    *
12
* and/or sell copies of the Software, and to permit persons to whom the       *
13
* Software is furnished to do so, subject to the following conditions:        *
14
*                                                                             *
15
* The above copyright notice and this permission notice shall be included in  *
16
* all copies or substantial portions of the Software.                         *
17
*                                                                             *
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  *
19
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    *
20
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      *
22
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     *
23
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         *
24
* DEALINGS IN THE SOFTWARE.                                                   *
25
*                                                                             *
26
* This agreement shall be governed in all respects by the laws of the State   *
27
* of California and by the laws of the United States of America.              *
28
*                                                                             *
29
******************************************************************************/
30
 
31
#include "system.h"
32
#include "nios2.h"
33
 
34
/* Setup header files to work with assembler code. */
35
#define ALT_ASM_SRC
36
 
37
/* Debug logging facility */
38
#include "sys/alt_log_printf.h"
39
 
40
/*************************************************************************\
41
|                                MACROS                                   |
42
\*************************************************************************/
43
 
44
/*
45
 * The new build tools explicitly define macros when alt_load()
46
 * must be called.  The define ALT_LOAD_EXPLICITLY_CONTROLLED tells us that
47
 * those macros are controlling if alt_load() needs to be called.
48
 */
49
#ifdef ALT_LOAD_EXPLICITLY_CONTROLLED
50
 
51
/* Need to call alt_load() if any of these sections are being copied. */
52
#if defined(ALT_LOAD_COPY_RODATA) || defined(ALT_LOAD_COPY_RWDATA) || defined(ALT_LOAD_COPY_EXCEPTIONS)
53
#define CALL_ALT_LOAD
54
#endif
55
 
56
#else /* !ALT_LOAD_EXPLICITLY_CONTROLLED */
57
 
58
/*
59
 * The legacy build tools use the following macros to detect when alt_load()
60
 * needs to be called.
61
 */
62
 
63
#define __ALT_LOAD_SECTIONS(res, text, rodata, exc) \
64
  ((res##_BASE != rodata##_BASE) ||                 \
65
   (res##_BASE != rwdata##_BASE) ||                 \
66
   (res##_BASE != exc##_BASE))
67
 
68
#define _ALT_LOAD_SECTIONS(res, text, rodata, exc) \
69
    __ALT_LOAD_SECTIONS(res, text, rodata, exc)
70
 
71
#define ALT_LOAD_SECTIONS _ALT_LOAD_SECTIONS(ALT_RESET_DEVICE,  \
72
                                             ALT_RODATA_DEVICE, \
73
                                             ALT_RWDATA_DEVICE, \
74
                                             ALT_EXCEPTIONS_DEVICE)
75
 
76
/* Call alt_load() if there is no bootloader and ALT_LOAD_SECTIONS isn't 0. */
77
#if defined(ALT_NO_BOOTLOADER) && ALT_LOAD_SECTIONS
78
#define CALL_ALT_LOAD
79
#endif
80
 
81
#endif /* !ALT_LOAD_EXPLICITLY_CONTROLLED */
82
 
83
/*
84
 * When the legacy build tools define a macro called ALT_NO_BOOTLOADER,
85
 * it indicates that initialization code is allowed at the reset address.
86
 * The new build tools define a macro called ALT_ALLOW_CODE_AT_RESET for
87
 * the same purpose.
88
 */
89
#ifdef ALT_NO_BOOTLOADER
90
#define ALT_ALLOW_CODE_AT_RESET
91
#endif
92
 
93
/*************************************************************************\
94
|                         EXTERNAL REFERENCES                             |
95
\*************************************************************************/
96
 
97
/*
98
 * The entry point for user code is either "main" in hosted mode, or
99
 * "alt_main" in standalone mode. These are explicitly referenced here,
100
 * to ensure they are built into the executable. This allows the user
101
 * to build them into libraries, rather than supplying them in object
102
 * files at link time.
103
 */
104
    .globl main
105
    .globl alt_main
106
 
107
/*
108
 * Create a reference to the software multiply/divide and trap handers,
109
 * so that if they are provided, they will appear in the executable.
110
 */
111
#ifndef ALT_NO_INSTRUCTION_EMULATION
112
    .globl alt_exception_muldiv
113
#endif
114
#ifdef ALT_TRAP_HANDLER
115
    .globl alt_exception_trap
116
#endif
117
 
118
/*
119
 * Linker defined symbols used to initialize bss.
120
 */
121
.globl __bss_start
122
.globl __bss_end
123
 
124
/*************************************************************************\
125
|                         RESET SECTION (.entry)                          |
126
\*************************************************************************/
127
 
128
/*
129
 * This is the reset entry point for Nios II.
130
 *
131
 * At reset, only the cache line which contain the reset vector is
132
 * initialized by the hardware. The code within the first cache line
133
 * initializes the remainder of the instruction cache.
134
 */
135
 
136
    .section .entry, "xa"
137
    .align 5
138
 
139
/*
140
 * Explicitly allow the use of r1 (the assembler temporary register)
141
 * within this code. This register is normally reserved for the use of
142
 * the assembler.
143
 */
144
    .set noat
145
 
146
/*
147
 * Some tools want to know where the reset vector is.
148
 * Code isn't always provided at the reset vector but at least the
149
 * __reset label always contains the reset vector address because
150
 * it is defined at the start of the .entry section.
151
 */
152
 
153
    .globl __reset
154
    .type __reset, @function
155
__reset:
156
 
157
/*
158
 * Initialize the instruction cache if present (i.e. size > 0) and
159
 * reset code is allowed unless optimizing for RTL simulation.
160
 * RTL simulations can ensure the instruction cache is already initialized
161
 * so skipping this loop speeds up RTL simulation.
162
 */
163
 
164
#if NIOS2_ICACHE_SIZE > 0 && defined(ALT_ALLOW_CODE_AT_RESET) && !defined(ALT_SIM_OPTIMIZE)
165
    /* Assume the instruction cache size is always a power of two. */
166
#if NIOS2_ICACHE_SIZE > 0x8000
167
    movhi r2, %hi(NIOS2_ICACHE_SIZE)
168
#else
169
    movui r2, NIOS2_ICACHE_SIZE
170
#endif
171
 
172
0:
173
    initi r2
174
    addi r2, r2, -NIOS2_ICACHE_LINE_SIZE
175
    bgt r2, zero, 0b
176
1:
177
 
178
    /*
179
     * The following debug information tells the ISS not to run the loop above
180
     * but to perform its actions using faster internal code.
181
     */
182
    .pushsection .debug_alt_sim_info
183
    .int 1, 1, 0b, 1b
184
    .popsection
185
#endif /* Initialize Instruction Cache */
186
 
187
/*
188
 * Jump to the _start entry point in the .text section if reset code
189
 * is allowed or if optimizing for RTL simulation.
190
 */
191
#if defined(ALT_ALLOW_CODE_AT_RESET) || defined(ALT_SIM_OPTIMIZE)
192
    /* Jump to the _start entry point in the .text section. */
193
    movhi r1, %hi(_start)
194
    ori r1, r1, %lo(_start)
195
    jmp r1
196
 
197
    .size __reset, . - __reset
198
#endif /* Jump to _start */
199
 
200
/*
201
 * When not using exit, provide an _exit symbol to prevent unresolved
202
 * references to _exit from the linker script.
203
 */
204
#ifdef ALT_NO_EXIT
205
    .globl _exit
206
_exit:
207
#endif
208
 
209
/*************************************************************************\
210
|                          TEXT SECTION (.text)                           |
211
\*************************************************************************/
212
 
213
/*
214
 * Start of the .text section, and also the code entry point when
215
 * the code is executed by a bootloader rather than directly from reset.
216
 */
217
    .section .text
218
    .align 2
219
 
220
    .globl _start
221
    .type _start, @function
222
_start:
223
 
224
#if (NIOS2_NUM_OF_SHADOW_REG_SETS > 0)
225
    /*
226
     * Ensure that the current register set is 0 upon
227
     * entry to this code.  Switch register set to 0 by
228
     * writing zero to SSTATUS register and executing an ERET instruction
229
     * to set STATUS.CRS to 0.
230
     */
231
 
232
    /* Get the current register set number (STATUS.CRS). */
233
    rdctl r2, status
234
    andi r2, r2, NIOS2_STATUS_CRS_MSK
235
 
236
    /* Skip switching register set if STATUS.CRS is 0.  */
237
    beq r2, zero, 0f
238
 
239
    /* Set SSTATUS to 0 to get to set SSTATUS.PRS to 0. */
240
    .set nobreak
241
    movui sstatus, 0
242
    .set break
243
 
244
    /* Switch to register set 0 and jump to label. */
245
    movhi ea, %hi(0f)
246
    ori ea, ea, %lo(0f)
247
    eret
248
 
249
0:
250
#endif /* NIOS2_NUM_OF_SHADOW_REG_SETS > 0 */
251
 
252
/*
253
 * Initialize the data cache if present (i.e. size > 0).
254
 * Skip initialization if optimizing for RTL simulation and ECC isn't present.
255
 * RTL simulations can ensure the data cache tag RAM is already initialized
256
 * (but not the data RAM for ECC) so skipping this speeds up RTL simulation.
257
 *
258
 * When ECC is present, need to execute initd for each word address
259
 * to ensure ECC parity bits in data RAM get initialized.
260
 * Otherwise, only need to execute initd for each line address.
261
 */
262
 
263
#if NIOS2_DCACHE_SIZE > 0 && (!defined(ALT_SIM_OPTIMIZE) || defined(NIOS2_ECC_PRESENT))
264
 
265
    /* Assume the data cache size is always a power of two. */
266
#if NIOS2_DCACHE_SIZE > 0x8000
267
    movhi r2, %hi(NIOS2_DCACHE_SIZE)
268
#else
269
    movui r2, NIOS2_DCACHE_SIZE
270
#endif
271
 
272
0:
273
    initd 0(r2)
274
#ifdef NIOS2_ECC_PRESENT
275
    addi r2, r2, -4
276
#else
277
    addi r2, r2, -NIOS2_DCACHE_LINE_SIZE
278
#endif
279
    bgt r2, zero, 0b
280
1:
281
 
282
    /*
283
     * The following debug information tells the ISS not to run the loop above
284
     * but to perform its actions using faster internal code.
285
     */
286
    .pushsection .debug_alt_sim_info
287
    .int 2, 1, 0b, 1b
288
    .popsection
289
#endif /* Initialize Data Cache */
290
 
291
    /* Log that caches have been initialized. */
292
    ALT_LOG_PUTS(alt_log_msg_cache)
293
 
294
    /* Log that the stack pointer is about to be setup. */
295
    ALT_LOG_PUTS(alt_log_msg_stackpointer)
296
 
297
    /*
298
     * Now that the caches are initialized, set up the stack pointer and global pointer.
299
     * The values provided by the linker are assumed to be correctly aligned.
300
     */
301
    movhi sp, %hi(__alt_stack_pointer)
302
    ori sp, sp, %lo(__alt_stack_pointer)
303
    movhi gp, %hi(_gp)
304
    ori gp, gp, %lo(_gp)
305
 
306
#ifdef NIOS2_ECC_PRESENT
307
    /*
308
     * Initialize all general-purpose registers so that ECC can be enabled
309
     * later without accidentally triggering a spurious ECC error.
310
     */
311
    movui r1, 0
312
    movui r2, 0
313
    movui r3, 0
314
    movui r4, 0
315
    movui r5, 0
316
    movui r6, 0
317
    movui r7, 0
318
    movui r8, 0
319
    movui r9, 0
320
    movui r10, 0
321
    movui r11, 0
322
    movui r12, 0
323
    movui r13, 0
324
    movui r14, 0
325
    movui r15, 0
326
    movui r16, 0
327
    movui r17, 0
328
    movui r18, 0
329
    movui r19, 0
330
    movui r20, 0
331
    movui r21, 0
332
    movui r22, 0
333
    movui r23, 0
334
    /* Skip r24 (et) because only exception handler should write it. */
335
    /* Skip r25 (bt) because only debugger should write it. */
336
    /* Skip r26 (gp) because it is already been initialized. */
337
    /* Skip r27 (sp) because it is already been initialized. */
338
    movui r28, 0    /* fp */
339
    movui r29, 0    /* ea */
340
    .set nobreak
341
    movui r30, 0    /* sstatus */
342
    .set break
343
    movui r31, 0    /* ra */
344
 
345
#endif /* NIOS2_ECC_PRESENT */
346
 
347
#if (NIOS2_NUM_OF_SHADOW_REG_SETS > 0)
348
    /*
349
     * Setup registers in shadow register sets
350
     * from 1 to NIOS2_NUM_OF_SHADOW_REG_SETS.
351
     */
352
 
353
    movui r2, 0     /* Contains value written into STATUS */
354
    movui r3, NIOS2_NUM_OF_SHADOW_REG_SETS  /* counter */
355
    movhi r4, 1     /* Constant to increment STATUS.PRS */
356
 
357
.Linitialize_shadow_registers:
358
    /* Increment STATUS.PRS */
359
    add r2, r2, r4
360
    wrctl status, r2
361
 
362
    /* Clear r0 in the shadow register set (not done by hardware) */
363
    wrprs r0, r0
364
 
365
    /* Write the GP in previous register set */
366
    wrprs gp, gp
367
 
368
    /*
369
     * Only write the SP in previous register set
370
     * if using the separate exception stack. For normal case (single stack),
371
     * funnel code would read the SP from previous register set with a RDPRS.
372
     */
373
#ifdef ALT_INTERRUPT_STACK
374
    movhi et, %hiadj(__alt_interrupt_stack_pointer)
375
    addi  et, et, %lo(__alt_interrupt_stack_pointer)
376
    wrprs sp, et
377
#endif /* ALT_INTERRUPT_STACK */
378
 
379
#ifdef NIOS2_ECC_PRESENT
380
    /*
381
     * Initialize all general-purpose registers so that ECC can be enabled
382
     * later without accidentally triggering a spurious ECC error.
383
     */
384
    wrprs r1, r0
385
    wrprs r2, r0
386
    wrprs r3, r0
387
    wrprs r4, r0
388
    wrprs r5, r0
389
    wrprs r6, r0
390
    wrprs r7, r0
391
    wrprs r8, r0
392
    wrprs r9, r0
393
    wrprs r10, r0
394
    wrprs r11, r0
395
    wrprs r12, r0
396
    wrprs r13, r0
397
    wrprs r14, r0
398
    wrprs r15, r0
399
    wrprs r16, r0
400
    wrprs r17, r0
401
    wrprs r18, r0
402
    wrprs r19, r0
403
    wrprs r20, r0
404
    wrprs r21, r0
405
    wrprs r22, r0
406
    wrprs r23, r0
407
    /* Skip r24 (et) because only exception handler should write it. */
408
    /* Skip r25 (bt) because only debugger should write it. */
409
    /* Skip r26 (gp) because it is already been initialized. */
410
    /* Skip r27 (sp) because it was initialized above or will be by a rdprs if not above */
411
    wrprs r28, r0    /* fp */
412
    wrprs r29, r0    /* ea */
413
    wrprs r30, r0    /* ba */
414
    wrprs r31, r0    /* ra */
415
#endif /* NIOS2_ECC_PRESENT */
416
 
417
    /* Decrement shadow register set counter */
418
    addi r3, r3, -1
419
 
420
    /* Done if index is 0. */
421
    bne r3, zero, .Linitialize_shadow_registers
422
#endif /* (NIOS2_NUM_OF_SHADOW_REG_SETS > 0) */
423
 
424
/*
425
 * Clear the BSS if not optimizing for RTL simulation.
426
 *
427
 * This uses the symbols: __bss_start and __bss_end, which are defined
428
 * by the linker script. They mark the begining and the end of the bss
429
 * region. The linker script guarantees that these values are word aligned.
430
 */
431
#ifndef ALT_SIM_OPTIMIZE
432
    /* Log that the BSS is about to be cleared. */
433
    ALT_LOG_PUTS(alt_log_msg_bss)
434
 
435
    movhi r2, %hi(__bss_start)
436
    ori r2, r2, %lo(__bss_start)
437
 
438
    movhi r3, %hi(__bss_end)
439
    ori r3, r3, %lo(__bss_end)
440
 
441
    beq r2, r3, 1f
442
 
443
0:
444
    stw zero, (r2)
445
    addi r2, r2, 4
446
    bltu r2, r3, 0b
447
 
448
1:
449
 
450
    /*
451
     * The following debug information tells the ISS not to run the loop above
452
     * but to perform its actions using faster internal code.
453
     */
454
    .pushsection .debug_alt_sim_info
455
    .int 3, 1, 0b, 1b
456
    .popsection
457
#endif /* ALT_SIM_OPTIMIZE */
458
 
459
/*
460
 * Turn off the use of r1 (the assembler temporary register)
461
 * so that call instructions can be safely relaxed across a
462
 * 256MB boundary if needed
463
 */
464
    .set at
465
 
466
/*
467
 * The alt_load() facility is normally used when there is no bootloader.
468
 * It copies some sections into RAM so it acts like a mini-bootloader.
469
 */
470
#ifdef CALL_ALT_LOAD
471
 
472
#ifdef ALT_STACK_CHECK
473
    /*
474
     * If the user has selected stack checking then we need to set up a safe
475
     * value in the stack limit register so that the relocation functions
476
     * don't think the stack has overflowed (the contents of the rwdata
477
     * section aren't defined until alt_load() has been called).
478
     */
479
    mov   et, zero
480
#endif
481
 
482
    call alt_load
483
 
484
#endif /* CALL_ALT_LOAD */
485
 
486
#ifdef ALT_STACK_CHECK
487
    /*
488
     * Set up the stack limit (if required).  The linker has set up the
489
     * copy of the variable which is in memory.
490
     */
491
 
492
    ldw   et, %gprel(alt_stack_limit_value)(gp)
493
#endif
494
 
495
    /* Log that alt_main is about to be called. */
496
    ALT_LOG_PUTS(alt_log_msg_alt_main)
497
 
498
    /* Call the C entry point. It should never return. */
499
    call alt_main
500
 
501
    /* Wait in infinite loop in case alt_main does return. */
502
alt_after_alt_main:
503
    br alt_after_alt_main
504
 
505
    .size _start, . - _start
506
 
507
/*
508
 * Add information about the stack base if stack overflow checking is enabled.
509
 */
510
#ifdef ALT_STACK_CHECK
511
    .globl  alt_stack_limit_value
512
    .section .sdata,"aws",@progbits
513
    .align  2
514
    .type   alt_stack_limit_value, @object
515
    .size   alt_stack_limit_value, 4
516
alt_stack_limit_value:
517
    .long   __alt_stack_limit
518
#endif

powered by: WebSVN 2.1.0

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