]> git.sur5r.net Git - u-boot/blob - cpu/nios/start.S
Merge branch 'master' of git://git.denx.de/u-boot-at91
[u-boot] / cpu / nios / start.S
1 /*
2  * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
3  * Scott McNutt <smcnutt@psyent.com>
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24
25 #include <config.h>
26 #include <timestamp.h>
27 #include <version.h>
28
29 #if !defined(CONFIG_IDENT_STRING)
30 #define CONFIG_IDENT_STRING ""
31 #endif
32
33 #define STATUS_INIT     0x8600          /* IE=1, IPRI=2 */
34
35 /*************************************************************************
36  * RESTART
37  ************************************************************************/
38
39         .text
40         .global _start
41
42 _start:
43         bsr     0f
44         nop
45         .long   _start
46
47         /* GERMS -- The "standard-32" configuration GERMS monitor looks
48          * for the string "Nios" at flash_base + 0xc (actually it only
49          * tests for 'N', 'i'). You can leave support for this in place
50          * as it's only a few words.
51          */
52         . = _start + 0x000c
53         .string "Nios"
54
55         .align 4
56 0:
57         /*
58          * Early setup -- set cwp = HI_LIMIT, IPRI = 2, IE = 1 to
59          * enable underflow exceptions. Disable cache.
60          * NOTE: %o7 has return addr -- save in %g7 use later.
61          */
62         mov     %g7, %o7
63
64         pfx     2                       /* WVALID */
65         rdctl   %g0
66         lsri    %g0, 1
67         pfx     %hi(STATUS_INIT)
68         or      %g0, %lo(STATUS_INIT)
69         wrctl   %g0                     /* update status */
70         nop
71
72         /*
73          * STACK
74          */
75         pfx     %hi(CONFIG_SYS_INIT_SP)
76         movi    %sp, %lo(CONFIG_SYS_INIT_SP)
77         pfx     %xhi(CONFIG_SYS_INIT_SP)
78         movhi   %sp, %xlo(CONFIG_SYS_INIT_SP)
79         mov     %fp, %sp
80
81         pfx     %hi(4*16)
82         subi    %sp, %lo(4*16)          /* Space for reg window mgmt */
83
84         /*
85          * RELOCATE -- %g7 has return addr from bsr at _start.
86          */
87         pfx     %hi(__u_boot_cmd_end)
88         movi    %g5, %lo(__u_boot_cmd_end)
89         pfx     %xhi(__u_boot_cmd_end)
90         movhi   %g5, %xlo(__u_boot_cmd_end) /* %g5 <- end address */
91
92         lsli    %g7, 1                  /* mem = retaddr << 1 */
93         mov     %g6, %g7
94         subi    %g6, 4                  /* %g6 <- src addr */
95         ld      %g7, [%g7]              /* %g7 <- dst addr */
96
97         /* No need to move text sections if we're already located
98          * at the proper address.
99          */
100         cmp     %g7, %g6
101         ifs     cc_z
102         br      reloc
103         nop                             /* delay slot */
104
105 1:      cmp     %g7, %g5
106         skps    cc_nz
107         br      2f
108         nop                             /* delay slot */
109
110         ld      %g0, [%g6]
111         addi    %g6, 4                  /* src++ */
112         st      [%g7], %g0
113         addi    %g7, 4                  /* dst++ */
114         br      1b
115         nop                             /* delay slot */
116 2:
117
118         /*
119          * Jump to relocation address
120          */
121          pfx    %hi(reloc@h)
122          movi   %g0, %lo(reloc@h)
123          pfx    %xhi(reloc@h)
124          movhi  %g0, %xlo(reloc@h)
125          jmp    %g0
126          nop                            /* delay slot */
127 reloc:
128
129         /*
130          * CLEAR BSS
131          */
132         pfx     %hi(__bss_end)
133         movi    %g5, %lo(__bss_end)
134         pfx     %xhi(__bss_end)
135         movhi   %g5, %xlo(__bss_end)    /* %g5 <- end address */
136         pfx     %hi(__bss_start)
137         movi    %g7, %lo(__bss_start)
138         pfx     %xhi(__bss_start)
139         movhi   %g7, %xlo(__bss_start)  /* %g7 <- end address */
140
141         movi    %g0, 0
142 3:      cmp     %g7, %g5
143         skps    cc_nz
144         br      4f
145         nop                             /* delay slot */
146
147         st      [%g7], %g0
148         addi    %g7, 4                  /* (delay slot) dst++ */
149         br      3b
150         nop                             /* delay slot */
151 4:
152
153         /*
154          * INIT VECTOR TABLE
155          */
156         pfx     %hi(CONFIG_SYS_VECT_BASE)
157         movi    %g0, %lo(CONFIG_SYS_VECT_BASE)
158         pfx     %xhi(CONFIG_SYS_VECT_BASE)
159         movhi   %g0, %xlo(CONFIG_SYS_VECT_BASE) /* dst */
160         mov     %l0, %g0
161
162         pfx     %hi(_vectors)
163         movi    %g1, %lo(_vectors)
164         pfx     %xhi(_vectors)
165         movhi   %g1, %xlo(_vectors)     /* src */
166         bgen    %g2, 6                  /* cnt = 64 */
167
168         ldp     %g3, [%l0, 3]           /* bkpt vector */
169         ldp     %g4, [%l0, 4]           /* single step vector */
170
171 5:      ld      %g7, [%g1]
172         addi    %g1, 4                  /* src++ */
173         st      [%g0], %g7
174         addi    %g0, 4                  /* dst++ */
175
176         subi    %g2, 1                  /* cnt-- */
177         ifrnz   %g2
178         br      5b
179         nop                             /* delay slot */
180
181 #if defined(CONFIG_ROM_STUBS)
182         /* Restore the breakpoint and single step exception
183          * vectors to their original values.
184          */
185         stp     [%l0,3], %g3            /* breakpoint */
186         stp     [%l0,4], %g4            /* single step */
187 #endif
188
189         /* For debug startup convenience ... software breakpoints
190          * set prior to this point may not succeed ;-)
191          */
192         .global __start
193 __start:
194
195         /*
196          * Call board_init -- never returns
197          */
198         pfx     %hi(board_init@h)
199         movi    %g1, %lo(board_init@h)
200         pfx     %xhi(board_init@h)
201         movhi   %g1, %xlo(board_init@h)
202         call    %g1
203         nop                             /* Delaly slot */
204         /* NEVER RETURNS */
205
206 /*
207  * dly_clks -- Nios doesn't have a time/clk reference for simple
208  * delay loops, so we do our best by counting instruction cycles.
209  * A control register that counts system clock cycles would be
210  * a handy feature -- hint for Altera ;-)
211  */
212         .globl dly_clks
213         /* Each loop is 4 instructions as delay slot is always
214          * executed. Each instruction is approximately 4 clocks
215          * (according to some lame info from Altera). So ...
216          * ... each loop is about 16 clocks.
217          */
218
219 dly_clks:
220         lsri    %o0, 4                  /* cnt/16 */
221
222 8:      skprnz  %o0
223         br      9f
224         subi    %o0, 1                  /* cnt--, Delay slot */
225         br      8b
226         nop
227
228 9:      lret
229         nop                             /* Delay slot */
230
231
232         .data
233         .globl  version_string
234
235 version_string:
236         .ascii U_BOOT_VERSION
237         .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
238         .ascii CONFIG_IDENT_STRING, "\0"