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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [syn/] [components/] [sd_card/] [software/] [exe_bsp/] [HAL/] [src/] [crt0.S] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 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
/*
225
 * Initialize the data cache if present (i.e. size > 0) and not
226
 * optimizing for RTL simulation.
227
 * RTL simulations can ensure the data cache is already initialized
228
 * so skipping this loop speeds up RTL simulation.
229
 */
230
 
231
#if NIOS2_DCACHE_SIZE > 0 && !defined(ALT_SIM_OPTIMIZE)
232
 
233
    /* Assume the data cache size is always a power of two. */
234
#if NIOS2_DCACHE_SIZE > 0x8000
235
    movhi r2, %hi(NIOS2_DCACHE_SIZE)
236
#else
237
    movui r2, NIOS2_DCACHE_SIZE
238
#endif
239
 
240
0:
241
    initd 0(r2)
242
    addi r2, r2, -NIOS2_DCACHE_LINE_SIZE
243
    bgt r2, zero, 0b
244
1:
245
 
246
    /*
247
     * The following debug information tells the ISS not to run the loop above
248
     * but to perform its actions using faster internal code.
249
     */
250
    .pushsection .debug_alt_sim_info
251
    .int 2, 1, 0b, 1b
252
    .popsection
253
 
254
#endif /* Initialize Data Cache */
255
 
256
    /* Log that caches have been initialized. */
257
    ALT_LOG_PUTS(alt_log_msg_cache)
258
 
259
    /* Log that the stack pointer is about to be setup. */
260
    ALT_LOG_PUTS(alt_log_msg_stackpointer)
261
 
262
#if (NIOS2_NUM_OF_SHADOW_REG_SETS == 0)
263
    /*
264
     * Now that the caches are initialized, set up the stack pointer.
265
     * The value provided by the linker is assumed to be correctly aligned.
266
     */
267
    movhi sp, %hi(__alt_stack_pointer)
268
    ori sp, sp, %lo(__alt_stack_pointer)
269
 
270
    /* Set up the global pointer. */
271
    movhi gp, %hi(_gp)
272
    ori gp, gp, %lo(_gp)
273
 
274
#else /* NIOS2_NUM_OF_SHADOW_REG_SETS > 0 */
275
 
276
    /*
277
     * Set up the GP and SP in all shadow register sets.
278
     */
279
 
280
    /*
281
     * Check current register set number, if CPU resets into a shadow register
282
     * set, switch register set to 0 by writing zero to SSTATUS register and
283
     * execute an ERET instruction that just jumps to the next PC address
284
     * (use the NEXTPC instruction to get this).
285
     */
286
 
287
    rdctl r2, status
288
 
289
    /* Get the current register set number (STATUS.CRS). */
290
    andi r3, r2, NIOS2_STATUS_CRS_MSK
291
 
292
    /* Skip switch register set if STATUS.CRS is 0.  */
293
    beq r3, zero, .Lskip_switch_reg_set
294
 
295
    .set nobreak
296
 
297
    /* Current register set is non-zero, set SSTATUS to 0. */
298
    mov sstatus, zero
299
 
300
    /* Get next pc and store in ea. */
301
    nextpc ea
302
 
303
    /* Point to instruction after eret. */
304
    addi ea, ea, 8
305
 
306
    /*
307
     * Execute ERET instruction that just jumps to the next PC address
308
     */
309
    eret
310
 
311
.Lskip_switch_reg_set:
312
    mov r2, zero
313
 
314
    /* Reset STATUS register */
315
    wrctl status, r2
316
 
317
    movui r3, NIOS2_NUM_OF_SHADOW_REG_SETS
318
 
319
    /* Set up the stack pointer in register set 0. */
320
    movhi sp, %hi(__alt_stack_pointer)
321
    ori sp, sp, %lo(__alt_stack_pointer)
322
 
323
    /* Set up the global pointer in register set 0. */
324
    movhi gp, %hi(_gp)
325
    ori gp, gp, %lo(_gp)
326
 
327
.Lsetup_sp_and_gp_loop:
328
    /*
329
     * Setup GP and SP for shadow register set
330
     * from NIOS2_NUM_OF_SHADOW_REG_SETS to 0
331
     */
332
 
333
    /* Skip if number of register sets is 0. */
334
    beq r3, zero, .Lno_shadow_register_set
335
 
336
 
337
    /* Add previous register set STATUS.PRS by 1 */
338
    movhi r4, 1
339
    add r2, r2, r4
340
 
341
    /* Write STATUS */
342
    wrctl status, r2
343
 
344
    /* Clear r0 in the shadow register set (not done by hardware) */
345
    wrprs r0, r0
346
 
347
    /* Write the GP in previous register set */
348
    wrprs gp, gp
349
 
350
    /* Only write the SP in previous register set
351
     * if using the seperate exception stack. For normal case (single stack),
352
     * funnel code would read the SP from previous register set.
353
     */
354
#ifdef ALT_INTERRUPT_STACK
355
 
356
    movhi et, %hiadj(__alt_interrupt_stack_pointer)
357
    addi  et, et, %lo(__alt_interrupt_stack_pointer)
358
    wrprs sp, et
359
 
360
#endif /* ALT_INTERRUPT_STACK */
361
 
362
    /* Decrease number of register set counter by 1 */
363
    addi r3, r3, -1
364
 
365
    br .Lsetup_sp_and_gp_loop
366
.Lno_shadow_register_set:
367
 
368
#endif /* NIOS2_NUM_OF_SHADOW_REG_SETS */
369
/*
370
 * Clear the BSS if not optimizing for RTL simulation.
371
 *
372
 * This uses the symbols: __bss_start and __bss_end, which are defined
373
 * by the linker script. They mark the begining and the end of the bss
374
 * region. The linker script guarantees that these values are word aligned.
375
 */
376
#ifndef ALT_SIM_OPTIMIZE
377
    /* Log that the BSS is about to be cleared. */
378
    ALT_LOG_PUTS(alt_log_msg_bss)
379
 
380
    movhi r2, %hi(__bss_start)
381
    ori r2, r2, %lo(__bss_start)
382
 
383
    movhi r3, %hi(__bss_end)
384
    ori r3, r3, %lo(__bss_end)
385
 
386
    beq r2, r3, 1f
387
 
388
0:
389
    stw zero, (r2)
390
    addi r2, r2, 4
391
    bltu r2, r3, 0b
392
 
393
1:
394
 
395
    /*
396
     * The following debug information tells the ISS not to run the loop above
397
     * but to perform its actions using faster internal code.
398
     */
399
    .pushsection .debug_alt_sim_info
400
    .int 3, 1, 0b, 1b
401
    .popsection
402
#endif /* ALT_SIM_OPTIMIZE */
403
 
404
/*
405
 * The alt_load() facility is normally used when there is no bootloader.
406
 * It copies some sections into RAM so it acts like a mini-bootloader.
407
 */
408
#ifdef CALL_ALT_LOAD
409
 
410
#ifdef ALT_STACK_CHECK
411
    /*
412
     * If the user has selected stack checking then we need to set up a safe
413
     * value in the stack limit register so that the relocation functions
414
     * don't think the stack has overflowed (the contents of the rwdata
415
     * section aren't defined until alt_load() has been called).
416
     */
417
    mov   et, zero
418
#endif
419
 
420
    call alt_load
421
 
422
#endif /* CALL_ALT_LOAD */
423
 
424
#ifdef ALT_STACK_CHECK
425
    /*
426
     * Set up the stack limit (if required).  The linker has set up the
427
     * copy of the variable which is in memory.
428
     */
429
 
430
    ldw   et, %gprel(alt_stack_limit_value)(gp)
431
#endif
432
 
433
    /* Log that alt_main is about to be called. */
434
    ALT_LOG_PUTS(alt_log_msg_alt_main)
435
 
436
    /* Call the C entry point. It should never return. */
437
    call alt_main
438
 
439
    /* Wait in infinite loop in case alt_main does return. */
440
alt_after_alt_main:
441
    br alt_after_alt_main
442
 
443
    .size _start, . - _start
444
 
445
/*
446
 * Add information about the stack base if stack overflow checking is enabled.
447
 */
448
#ifdef ALT_STACK_CHECK
449
    .globl  alt_stack_limit_value
450
    .section .sdata,"aws",@progbits
451
    .align  2
452
    .type   alt_stack_limit_value, @object
453
    .size   alt_stack_limit_value, 4
454
alt_stack_limit_value:
455
    .long   __alt_stack_limit
456
#endif

powered by: WebSVN 2.1.0

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