xref: /openbmc/u-boot/arch/nios2/cpu/start.S (revision a47a12be)
1/*
2 * (C) Copyright 2004, 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/*************************************************************************
30 * RESTART
31 ************************************************************************/
32
33	.text
34	.global _start
35
36_start:
37	/* ICACHE INIT -- only the icache line at the reset address
38	 * is invalidated at reset. So the init must stay within
39	 * the cache line size (8 words). If GERMS is used, we'll
40	 * just be invalidating the cache a second time. If cache
41	 * is not implemented initi behaves as nop.
42	 */
43	ori	r4, r0, %lo(CONFIG_SYS_ICACHELINE_SIZE)
44	movhi	r5, %hi(CONFIG_SYS_ICACHE_SIZE)
45	ori	r5, r5, %lo(CONFIG_SYS_ICACHE_SIZE)
46	mov	r6, r0
470:	initi	r6
48	add	r6, r6, r4
49	bltu	r6, r5, 0b
50	br	_except_end	/* Skip the tramp */
51
52	/* EXCEPTION TRAMPOLINE -- the following gets copied
53	 * to the exception address (below), but is otherwise at the
54	 * default exception vector offset (0x0020).
55	 */
56_except_start:
57	movhi	et, %hi(_exception)
58	ori	et, et, %lo(_exception)
59	jmp	et
60_except_end:
61
62	/* INTERRUPTS -- for now, all interrupts masked and globally
63	 * disabled.
64	 */
65	wrctl	status, r0		/* Disable interrupts */
66	wrctl	ienable, r0		/* All disabled	*/
67
68	/* DCACHE INIT -- if dcache not implemented, initd behaves as
69	 * nop.
70	 */
71	movhi	r4, %hi(CONFIG_SYS_DCACHELINE_SIZE)
72	ori	r4, r4, %lo(CONFIG_SYS_DCACHELINE_SIZE)
73	movhi	r5, %hi(CONFIG_SYS_DCACHE_SIZE)
74	ori	r5, r5, %lo(CONFIG_SYS_DCACHE_SIZE)
75	mov	r6, r0
761:	initd	0(r6)
77	add	r6, r6, r4
78	bltu	r6, r5, 1b
79
80	/* RELOCATE CODE, DATA & COMMAND TABLE -- the following code
81	 * assumes code, data and the command table are all
82	 * contiguous. This lets us relocate everything as a single
83	 * block. Make sure the linker script matches this ;-)
84	 */
85	nextpc	r4
86_cur:	movhi	r5, %hi(_cur - _start)
87	ori	r5, r5, %lo(_cur - _start)
88	sub	r4, r4, r5		/* r4 <- cur _start */
89	mov	r8, r4
90	movhi	r5, %hi(_start)
91	ori	r5, r5, %lo(_start)	/* r5 <- linked _start */
92	beq	r4, r5, 3f
93
94	movhi	r6, %hi(_edata)
95	ori	r6, r6, %lo(_edata)
962:	ldwio	r7, 0(r4)
97	addi	r4, r4, 4
98	stwio	r7, 0(r5)
99	addi	r5, r5, 4
100	bne	r5, r6, 2b
1013:
102
103	/* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
104	 * and between __bss_start and _end.
105	 */
106	 movhi	r5, %hi(__bss_start)
107	 ori	r5, r5, %lo(__bss_start)
108	 movhi	r6, %hi(_end)
109	 ori	r6, r6, %lo(_end)
110	 beq	r5, r6, 5f
111
1124:	stwio	r0, 0(r5)
113	 addi	r5, r5, 4
114	 bne	r5, r6, 4b
1155:
116
117	/* GLOBAL POINTER -- the global pointer is used to reference
118	 * "small data" (see -G switch). The linker script must
119	 * provide the gp address.
120	 */
121	 movhi	gp, %hi(_gp)
122	 ori	gp, gp, %lo(_gp)
123
124	/* JUMP TO RELOC ADDR */
125	movhi	r4, %hi(_reloc)
126	ori	r4, r4, %lo(_reloc)
127	jmp	r4
128_reloc:
129
130	/* COPY EXCEPTION TRAMPOLINE -- copy the tramp to the
131	 * exception address. Define CONFIG_ROM_STUBS to prevent
132	 * the copy (e.g. exception in flash or in other
133	 * softare/firmware component).
134	 */
135#if !defined(CONFIG_ROM_STUBS)
136	movhi	r4, %hi(_except_start)
137	ori	r4, r4, %lo(_except_start)
138	movhi	r5, %hi(_except_end)
139	ori	r5, r5, %lo(_except_end)
140	movhi	r6, %hi(CONFIG_SYS_EXCEPTION_ADDR)
141	ori	r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR)
142	beq	r4, r6, 7f	/* Skip if at proper addr */
143
1446:	ldwio	r7, 0(r4)
145	stwio	r7, 0(r6)
146	addi	r4, r4, 4
147	addi	r6, r6, 4
148	bne	r4, r5, 6b
1497:
150#endif
151
152	/* STACK INIT -- zero top two words for call back chain.
153	 */
154	movhi	sp, %hi(CONFIG_SYS_INIT_SP)
155	ori	sp, sp, %lo(CONFIG_SYS_INIT_SP)
156	addi	sp, sp, -8
157	stw	r0, 0(sp)
158	stw	r0, 4(sp)
159	mov	fp, sp
160
161	/*
162	 * Call board_init -- never returns
163	 */
164	movhi	r4, %hi(board_init@h)
165	ori	r4, r4, %lo(board_init@h)
166	callr	r4
167
168	/* NEVER RETURNS -- but branch to the _start just
169	 * in case ;-)
170	 */
171	br	_start
172
173
174/*
175 * dly_clks -- Nios2 (like Nios1) doesn't have a timebase in
176 * the core. For simple delay loops, we do our best by counting
177 * instruction cycles.
178 *
179 * Instruction performance varies based on the core. For cores
180 * with icache and static/dynamic branch prediction (II/f, II/s):
181 *
182 *	Normal ALU (e.g. add, cmp, etc):	1 cycle
183 *	Branch (correctly predicted, taken):	2 cycles
184 *	Negative offset is predicted (II/s).
185 *
186 * For cores without icache and no branch prediction (II/e):
187 *
188 *	Normal ALU (e.g. add, cmp, etc):	6 cycles
189 *	Branch (no prediction):			6 cycles
190 *
191 * For simplicity, if an instruction cache is implemented we
192 * assume II/f or II/s. Otherwise, we use the II/e.
193 *
194 */
195	.globl dly_clks
196
197dly_clks:
198
199#if (CONFIG_SYS_ICACHE_SIZE > 0)
200	subi	r4, r4, 3		/* 3 clocks/loop	*/
201#else
202	subi	r4, r4, 12		/* 12 clocks/loop	*/
203#endif
204	bge	r4, r0, dly_clks
205	ret
206
207
208#if !defined(CONFIG_IDENT_STRING)
209#define CONFIG_IDENT_STRING ""
210#endif
211	.data
212	.globl	version_string
213
214version_string:
215	.ascii U_BOOT_VERSION
216	.ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
217	.ascii CONFIG_IDENT_STRING, "\0"
218