* Patch by Scott McNutt, 04 Oct 2003:
[platform/kernel/u-boot.git] / 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 1:      cmp     %g7, %g5
97         skps    cc_nz
98         br      2f
99         nop                             /* delay slot */
100
101         ld      %g0, [%g6]
102         addi    %g6, 4                  /* src++ */
103         st      [%g7], %g0
104         addi    %g7, 4                  /* dst++ */
105         br      1b
106         nop                             /* delay slot */
107 2:
108
109         /*
110          * Jump to relocation address
111          */
112          pfx    %hi(reloc@h)
113          movi   %g0, %lo(reloc@h)
114          pfx    %xhi(reloc@h)
115          movhi  %g0, %xlo(reloc@h)
116          jmp    %g0
117 reloc:
118
119         /*
120          * CLEAR BSS
121          */
122         pfx     %hi(__bss_end)
123         movi    %g5, %lo(__bss_end)
124         pfx     %xhi(__bss_end)
125         movhi   %g5, %xlo(__bss_end)    /* %g5 <- end address */
126         pfx     %hi(__bss_start)
127         movi    %g7, %lo(__bss_start)
128         pfx     %xhi(__bss_start)
129         movhi   %g7, %xlo(__bss_start)  /* %g7 <- end address */
130
131         movi    %g0, 0
132 3:      cmp     %g7, %g5
133         skps    cc_nz
134         br      4f
135         nop                             /* delay slot */
136
137         st      [%g7], %g0
138         addi    %g7, 4                  /* (delay slot) dst++ */
139         br      3b
140         nop                             /* delay slot */
141 4:
142
143         /*
144          * Call board_init -- never returns
145          */
146         pfx     %hi(board_init@h)
147         movi    %g1, %lo(board_init@h)
148         pfx     %xhi(board_init@h)
149         movhi   %g1, %xlo(board_init@h)
150         call    %g1
151         nop                             /* Delaly slot */
152         /* NEVER RETURNS */
153
154 /*
155  * dly_clks -- Nios doesn't have a time/clk reference for simple
156  * delay loops, so we do our best by counting instruction cycles.
157  * A control register that counts system clock cycles would be
158  * a handy feature -- hint for Altera ;-)
159  */
160         .globl dly_clks
161         /* Each loop is 4 instructions as delay slot is always
162          * executed. Each instruction is approximately 4 clocks
163          * (according to some lame info from Altera). So ...
164          * ... each loop is about 16 clocks.
165          */
166
167 dly_clks:
168         lsri    %o0, 4                  /* cnt/16 */
169
170 8:      skprnz  %o0
171         br      9f
172         subi    %o0, 1                  /* cnt--, Delay slot */
173         br      8b
174         nop
175
176 9:      lret
177         nop                             /* Delay slot */
178
179
180         .data
181         .globl  version_string
182
183 version_string:
184         .ascii U_BOOT_VERSION
185         .ascii " (", __DATE__, " - ", __TIME__, ")"
186         .ascii CONFIG_IDENT_STRING, "\0"