xref: /rk3399_rockchip-uboot/arch/nios2/cpu/start.S (revision 9208d7eba1c2f027cdd06e6ce6ec90d3889764bf)
137e4dafaSPeter Tyser/*
237e4dafaSPeter Tyser * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
337e4dafaSPeter Tyser * Scott McNutt <smcnutt@psyent.com>
437e4dafaSPeter Tyser *
51a459660SWolfgang Denk * SPDX-License-Identifier:	GPL-2.0+
637e4dafaSPeter Tyser */
737e4dafaSPeter Tyser
825ddd1fbSWolfgang Denk#include <asm-offsets.h>
937e4dafaSPeter Tyser#include <config.h>
1037e4dafaSPeter Tyser#include <version.h>
1137e4dafaSPeter Tyser
1255e2b4d4SThomas Chou/*
1355e2b4d4SThomas Chou * icache and dcache configuration used only for start.S.
1455e2b4d4SThomas Chou * the values are chosen so that it will work for all configuration.
1555e2b4d4SThomas Chou */
1655e2b4d4SThomas Chou#define ICACHE_LINE_SIZE	32 /* fixed 32 */
1755e2b4d4SThomas Chou#define ICACHE_SIZE_MAX		0x10000 /* 64k max */
1855e2b4d4SThomas Chou#define DCACHE_LINE_SIZE_MIN	4 /* 4, 16, 32 */
1955e2b4d4SThomas Chou#define DCACHE_SIZE_MAX		0x10000 /* 64k max */
2055e2b4d4SThomas Chou
214a572fa8SThomas Chou	/* RESTART */
2237e4dafaSPeter Tyser	.text
23b8112091SThomas Chou	.global _start, _except_start, _except_end
2437e4dafaSPeter Tyser
2537e4dafaSPeter Tyser_start:
26fd2712d0SThomas Chou	wrctl	status, r0		/* Disable interrupts */
274a572fa8SThomas Chou	/*
284a572fa8SThomas Chou	 * ICACHE INIT -- only the icache line at the reset address
2937e4dafaSPeter Tyser	 * is invalidated at reset. So the init must stay within
3037e4dafaSPeter Tyser	 * the cache line size (8 words). If GERMS is used, we'll
3137e4dafaSPeter Tyser	 * just be invalidating the cache a second time. If cache
3237e4dafaSPeter Tyser	 * is not implemented initi behaves as nop.
3337e4dafaSPeter Tyser	 */
3455e2b4d4SThomas Chou	ori	r4, r0, %lo(ICACHE_LINE_SIZE)
3555e2b4d4SThomas Chou	movhi	r5, %hi(ICACHE_SIZE_MAX)
3655e2b4d4SThomas Chou	ori	r5, r5, %lo(ICACHE_SIZE_MAX)
37fd2712d0SThomas Chou0:	initi	r5
38fd2712d0SThomas Chou	sub	r5, r5, r4
39fd2712d0SThomas Chou	bgt	r5, r0, 0b
4037e4dafaSPeter Tyser	br	_except_end	/* Skip the tramp */
4137e4dafaSPeter Tyser
424a572fa8SThomas Chou	/*
434a572fa8SThomas Chou	 * EXCEPTION TRAMPOLINE -- the following gets copied
4437e4dafaSPeter Tyser	 * to the exception address (below), but is otherwise at the
4537e4dafaSPeter Tyser	 * default exception vector offset (0x0020).
4637e4dafaSPeter Tyser	 */
4737e4dafaSPeter Tyser_except_start:
4837e4dafaSPeter Tyser	movhi	et, %hi(_exception)
4937e4dafaSPeter Tyser	ori	et, et, %lo(_exception)
5037e4dafaSPeter Tyser	jmp	et
5137e4dafaSPeter Tyser_except_end:
5237e4dafaSPeter Tyser
534a572fa8SThomas Chou	/*
544a572fa8SThomas Chou	 * INTERRUPTS -- for now, all interrupts masked and globally
5537e4dafaSPeter Tyser	 * disabled.
5637e4dafaSPeter Tyser	 */
5737e4dafaSPeter Tyser	wrctl	ienable, r0		/* All disabled	*/
5837e4dafaSPeter Tyser
594a572fa8SThomas Chou	/*
604a572fa8SThomas Chou	 * DCACHE INIT -- if dcache not implemented, initd behaves as
6137e4dafaSPeter Tyser	 * nop.
6237e4dafaSPeter Tyser	 */
6355e2b4d4SThomas Chou	ori	r4, r0, %lo(DCACHE_LINE_SIZE_MIN)
6455e2b4d4SThomas Chou	movhi	r5, %hi(DCACHE_SIZE_MAX)
6555e2b4d4SThomas Chou	ori	r5, r5, %lo(DCACHE_SIZE_MAX)
6637e4dafaSPeter Tyser	mov	r6, r0
6737e4dafaSPeter Tyser1:	initd	0(r6)
6837e4dafaSPeter Tyser	add	r6, r6, r4
6937e4dafaSPeter Tyser	bltu	r6, r5, 1b
7037e4dafaSPeter Tyser
714a572fa8SThomas Chou	/*
724a572fa8SThomas Chou	 * RELOCATE CODE, DATA & COMMAND TABLE -- the following code
7337e4dafaSPeter Tyser	 * assumes code, data and the command table are all
7437e4dafaSPeter Tyser	 * contiguous. This lets us relocate everything as a single
7537e4dafaSPeter Tyser	 * block. Make sure the linker script matches this ;-)
7637e4dafaSPeter Tyser	 */
7737e4dafaSPeter Tyser	nextpc	r4
7837e4dafaSPeter Tyser_cur:	movhi	r5, %hi(_cur - _start)
7937e4dafaSPeter Tyser	ori	r5, r5, %lo(_cur - _start)
8037e4dafaSPeter Tyser	sub	r4, r4, r5		/* r4 <- cur _start */
8137e4dafaSPeter Tyser	mov	r8, r4
8237e4dafaSPeter Tyser	movhi	r5, %hi(_start)
8337e4dafaSPeter Tyser	ori	r5, r5, %lo(_start)	/* r5 <- linked _start */
8465af9f69SThomas Chou	mov	sp, r5		/* initial stack below u-boot code */
8537e4dafaSPeter Tyser	beq	r4, r5, 3f
8637e4dafaSPeter Tyser
87e900298eSThomas Chou	movhi	r6, %hi(CONFIG_SYS_MONITOR_LEN)
88e900298eSThomas Chou	ori	r6, r6, %lo(CONFIG_SYS_MONITOR_LEN)
89e900298eSThomas Chou	add	r6, r6, r5
9037e4dafaSPeter Tyser2:	ldwio	r7, 0(r4)
9137e4dafaSPeter Tyser	addi	r4, r4, 4
9237e4dafaSPeter Tyser	stwio	r7, 0(r5)
9337e4dafaSPeter Tyser	addi	r5, r5, 4
9437e4dafaSPeter Tyser	bne	r5, r6, 2b
9537e4dafaSPeter Tyser3:
9637e4dafaSPeter Tyser
9737e4dafaSPeter Tyser	/* JUMP TO RELOC ADDR */
9837e4dafaSPeter Tyser	movhi	r4, %hi(_reloc)
9937e4dafaSPeter Tyser	ori	r4, r4, %lo(_reloc)
10037e4dafaSPeter Tyser	jmp	r4
10137e4dafaSPeter Tyser_reloc:
10237e4dafaSPeter Tyser
1034a572fa8SThomas Chou	/* STACK INIT -- zero top two words for call back chain. */
10437e4dafaSPeter Tyser	addi	sp, sp, -8
10537e4dafaSPeter Tyser	stw	r0, 0(sp)
10637e4dafaSPeter Tyser	stw	r0, 4(sp)
10737e4dafaSPeter Tyser	mov	fp, sp
10837e4dafaSPeter Tyser
1093e468e68SThomas Chou	/* Allocate and zero GD, update SP */
1103e468e68SThomas Chou	mov	r4, sp
1113e468e68SThomas Chou	movhi	r2, %hi(board_init_f_mem@h)
1123e468e68SThomas Chou	ori	r2, r2, %lo(board_init_f_mem@h)
1133e468e68SThomas Chou	callr	r2
1143e468e68SThomas Chou
1153e468e68SThomas Chou	/* Update stack- and frame-pointers */
1163e468e68SThomas Chou	mov	sp, r2
1173e468e68SThomas Chou	mov	fp, sp
1183e468e68SThomas Chou
1194a572fa8SThomas Chou	/* Call board_init_f -- never returns */
1205ff10aa7SThomas Chou	mov	r4, r0
1215ff10aa7SThomas Chou	movhi	r2, %hi(board_init_f@h)
1225ff10aa7SThomas Chou	ori	r2, r2, %lo(board_init_f@h)
1235ff10aa7SThomas Chou	callr	r2
12437e4dafaSPeter Tyser
1254a572fa8SThomas Chou	/*
1264a572fa8SThomas Chou	 * NEVER RETURNS -- but branch to the _start just
12737e4dafaSPeter Tyser	 * in case ;-)
12837e4dafaSPeter Tyser	 */
12937e4dafaSPeter Tyser	br	_start
13037e4dafaSPeter Tyser
1315ff10aa7SThomas Chou	/*
1325ff10aa7SThomas Chou	 * relocate_code -- Nios2 handles the relocation above. But
1335ff10aa7SThomas Chou	 * the generic board code monkeys with the heap, stack, etc.
1345ff10aa7SThomas Chou	 * (it makes some assumptions that may not be appropriate
1355ff10aa7SThomas Chou	 * for Nios). Nevertheless, we capitulate here.
1365ff10aa7SThomas Chou	 *
1375ff10aa7SThomas Chou	 * We'll call the board_init_r from here since this isn't
1385ff10aa7SThomas Chou	 * supposed to return.
1395ff10aa7SThomas Chou	 *
1405ff10aa7SThomas Chou	 * void relocate_code (ulong sp, gd_t *global_data,
1415ff10aa7SThomas Chou	 *			ulong reloc_addr)
1425ff10aa7SThomas Chou	 *			__attribute__ ((noreturn));
1435ff10aa7SThomas Chou	 */
1445ff10aa7SThomas Chou	.text
1455ff10aa7SThomas Chou	.global relocate_code
1465ff10aa7SThomas Chou
1475ff10aa7SThomas Chourelocate_code:
1485ff10aa7SThomas Chou	mov	sp, r4		/* Set the new sp */
1495ff10aa7SThomas Chou	mov	r4, r5
1504192b8c3SThomas Chou
1514192b8c3SThomas Chou	/*
1524192b8c3SThomas Chou	 * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
1534192b8c3SThomas Chou	 * and between __bss_start and __bss_end.
1544192b8c3SThomas Chou	 */
1554192b8c3SThomas Chou	movhi	r5, %hi(__bss_start)
1564192b8c3SThomas Chou	ori	r5, r5, %lo(__bss_start)
1574192b8c3SThomas Chou	movhi	r6, %hi(__bss_end)
1584192b8c3SThomas Chou	ori	r6, r6, %lo(__bss_end)
1594192b8c3SThomas Chou	beq	r5, r6, 5f
1604192b8c3SThomas Chou
161*9208d7ebSThomas Chou4:	stw	r0, 0(r5)
1624192b8c3SThomas Chou	addi	r5, r5, 4
1634192b8c3SThomas Chou	bne	r5, r6, 4b
1644192b8c3SThomas Chou5:
1654192b8c3SThomas Chou
1665ff10aa7SThomas Chou	movhi	r8, %hi(board_init_r@h)
1675ff10aa7SThomas Chou	ori	r8, r8, %lo(board_init_r@h)
1685ff10aa7SThomas Chou	callr	r8
1695ff10aa7SThomas Chou	ret
170