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