xref: /rk3399_rockchip-uboot/arch/nios2/cpu/start.S (revision 4a572fa8519dba165677a88897a8ef0104f06d12)
1/*
2 * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
3 * Scott McNutt <smcnutt@psyent.com>
4 *
5 * SPDX-License-Identifier:	GPL-2.0+
6 */
7
8#include <asm-offsets.h>
9#include <config.h>
10#include <version.h>
11
12	/* RESTART */
13	.text
14	.global _start
15
16_start:
17	wrctl	status, r0		/* Disable interrupts */
18	/*
19	 * ICACHE INIT -- only the icache line at the reset address
20	 * is invalidated at reset. So the init must stay within
21	 * the cache line size (8 words). If GERMS is used, we'll
22	 * just be invalidating the cache a second time. If cache
23	 * is not implemented initi behaves as nop.
24	 */
25	ori	r4, r0, %lo(CONFIG_SYS_ICACHELINE_SIZE)
26	movhi	r5, %hi(CONFIG_SYS_ICACHE_SIZE)
27	ori	r5, r5, %lo(CONFIG_SYS_ICACHE_SIZE)
280:	initi	r5
29	sub	r5, r5, r4
30	bgt	r5, r0, 0b
31	br	_except_end	/* Skip the tramp */
32
33	/*
34	 * EXCEPTION TRAMPOLINE -- the following gets copied
35	 * to the exception address (below), but is otherwise at the
36	 * default exception vector offset (0x0020).
37	 */
38_except_start:
39	movhi	et, %hi(_exception)
40	ori	et, et, %lo(_exception)
41	jmp	et
42_except_end:
43
44	/*
45	 * INTERRUPTS -- for now, all interrupts masked and globally
46	 * disabled.
47	 */
48	wrctl	ienable, r0		/* All disabled	*/
49
50	/*
51	 * DCACHE INIT -- if dcache not implemented, initd behaves as
52	 * nop.
53	 */
54	movhi	r4, %hi(CONFIG_SYS_DCACHELINE_SIZE)
55	ori	r4, r4, %lo(CONFIG_SYS_DCACHELINE_SIZE)
56	movhi	r5, %hi(CONFIG_SYS_DCACHE_SIZE)
57	ori	r5, r5, %lo(CONFIG_SYS_DCACHE_SIZE)
58	mov	r6, r0
591:	initd	0(r6)
60	add	r6, r6, r4
61	bltu	r6, r5, 1b
62
63	/*
64	 * RELOCATE CODE, DATA & COMMAND TABLE -- the following code
65	 * assumes code, data and the command table are all
66	 * contiguous. This lets us relocate everything as a single
67	 * block. Make sure the linker script matches this ;-)
68	 */
69	nextpc	r4
70_cur:	movhi	r5, %hi(_cur - _start)
71	ori	r5, r5, %lo(_cur - _start)
72	sub	r4, r4, r5		/* r4 <- cur _start */
73	mov	r8, r4
74	movhi	r5, %hi(_start)
75	ori	r5, r5, %lo(_start)	/* r5 <- linked _start */
76	beq	r4, r5, 3f
77
78	movhi	r6, %hi(CONFIG_SYS_MONITOR_LEN)
79	ori	r6, r6, %lo(CONFIG_SYS_MONITOR_LEN)
80	add	r6, r6, r5
812:	ldwio	r7, 0(r4)
82	addi	r4, r4, 4
83	stwio	r7, 0(r5)
84	addi	r5, r5, 4
85	bne	r5, r6, 2b
863:
87
88	/* JUMP TO RELOC ADDR */
89	movhi	r4, %hi(_reloc)
90	ori	r4, r4, %lo(_reloc)
91	jmp	r4
92_reloc:
93
94	/*
95	 * COPY EXCEPTION TRAMPOLINE -- copy the tramp to the
96	 * exception address. Define CONFIG_ROM_STUBS to prevent
97	 * the copy (e.g. exception in flash or in other
98	 * softare/firmware component).
99	 */
100#if !defined(CONFIG_ROM_STUBS)
101	movhi	r4, %hi(_except_start)
102	ori	r4, r4, %lo(_except_start)
103	movhi	r5, %hi(_except_end)
104	ori	r5, r5, %lo(_except_end)
105	movhi	r6, %hi(CONFIG_SYS_EXCEPTION_ADDR)
106	ori	r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR)
107	beq	r4, r6, 7f	/* Skip if at proper addr */
108
1096:	ldwio	r7, 0(r4)
110	stwio	r7, 0(r6)
111	addi	r4, r4, 4
112	addi	r6, r6, 4
113	bne	r4, r5, 6b
1147:
115#endif
116
117	/* STACK INIT -- zero top two words for call back chain. */
118	movhi	sp, %hi(CONFIG_SYS_INIT_SP)
119	ori	sp, sp, %lo(CONFIG_SYS_INIT_SP)
120	addi	sp, sp, -8
121	stw	r0, 0(sp)
122	stw	r0, 4(sp)
123	mov	fp, sp
124
125	/* Allocate and zero GD, update SP */
126	mov	r4, sp
127	movhi	r2, %hi(board_init_f_mem@h)
128	ori	r2, r2, %lo(board_init_f_mem@h)
129	callr	r2
130
131	/* Update stack- and frame-pointers */
132	mov	sp, r2
133	mov	fp, sp
134
135	/* Call board_init_f -- never returns */
136	mov	r4, r0
137	movhi	r2, %hi(board_init_f@h)
138	ori	r2, r2, %lo(board_init_f@h)
139	callr	r2
140
141	/*
142	 * NEVER RETURNS -- but branch to the _start just
143	 * in case ;-)
144	 */
145	br	_start
146
147	/*
148	 * relocate_code -- Nios2 handles the relocation above. But
149	 * the generic board code monkeys with the heap, stack, etc.
150	 * (it makes some assumptions that may not be appropriate
151	 * for Nios). Nevertheless, we capitulate here.
152	 *
153	 * We'll call the board_init_r from here since this isn't
154	 * supposed to return.
155	 *
156	 * void relocate_code (ulong sp, gd_t *global_data,
157	 *			ulong reloc_addr)
158	 *			__attribute__ ((noreturn));
159	 */
160	.text
161	.global relocate_code
162
163relocate_code:
164	mov	sp, r4		/* Set the new sp */
165	mov	r4, r5
166
167	/*
168	 * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
169	 * and between __bss_start and __bss_end.
170	 */
171	movhi	r5, %hi(__bss_start)
172	ori	r5, r5, %lo(__bss_start)
173	movhi	r6, %hi(__bss_end)
174	ori	r6, r6, %lo(__bss_end)
175	beq	r5, r6, 5f
176
1774:	stwio	r0, 0(r5)
178	addi	r5, r5, 4
179	bne	r5, r6, 4b
1805:
181
182	movhi	r8, %hi(board_init_r@h)
183	ori	r8, r8, %lo(board_init_r@h)
184	callr	r8
185	ret
186