xref: /rk3399_rockchip-uboot/arch/nios2/cpu/start.S (revision 55e2b4d4e5dd179d748dca9f8c44585b7319f2e2)
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
12*55e2b4d4SThomas Chou/*
13*55e2b4d4SThomas Chou * icache and dcache configuration used only for start.S.
14*55e2b4d4SThomas Chou * the values are chosen so that it will work for all configuration.
15*55e2b4d4SThomas Chou */
16*55e2b4d4SThomas Chou#define ICACHE_LINE_SIZE	32 /* fixed 32 */
17*55e2b4d4SThomas Chou#define ICACHE_SIZE_MAX		0x10000 /* 64k max */
18*55e2b4d4SThomas Chou#define DCACHE_LINE_SIZE_MIN	4 /* 4, 16, 32 */
19*55e2b4d4SThomas Chou#define DCACHE_SIZE_MAX		0x10000 /* 64k max */
20*55e2b4d4SThomas Chou
214a572fa8SThomas Chou	/* RESTART */
2237e4dafaSPeter Tyser	.text
2337e4dafaSPeter Tyser	.global _start
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	 */
34*55e2b4d4SThomas Chou	ori	r4, r0, %lo(ICACHE_LINE_SIZE)
35*55e2b4d4SThomas Chou	movhi	r5, %hi(ICACHE_SIZE_MAX)
36*55e2b4d4SThomas 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	 */
63*55e2b4d4SThomas Chou	ori	r4, r0, %lo(DCACHE_LINE_SIZE_MIN)
64*55e2b4d4SThomas Chou	movhi	r5, %hi(DCACHE_SIZE_MAX)
65*55e2b4d4SThomas 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 */
8437e4dafaSPeter Tyser	beq	r4, r5, 3f
8537e4dafaSPeter Tyser
86e900298eSThomas Chou	movhi	r6, %hi(CONFIG_SYS_MONITOR_LEN)
87e900298eSThomas Chou	ori	r6, r6, %lo(CONFIG_SYS_MONITOR_LEN)
88e900298eSThomas Chou	add	r6, r6, r5
8937e4dafaSPeter Tyser2:	ldwio	r7, 0(r4)
9037e4dafaSPeter Tyser	addi	r4, r4, 4
9137e4dafaSPeter Tyser	stwio	r7, 0(r5)
9237e4dafaSPeter Tyser	addi	r5, r5, 4
9337e4dafaSPeter Tyser	bne	r5, r6, 2b
9437e4dafaSPeter Tyser3:
9537e4dafaSPeter Tyser
9637e4dafaSPeter Tyser	/* JUMP TO RELOC ADDR */
9737e4dafaSPeter Tyser	movhi	r4, %hi(_reloc)
9837e4dafaSPeter Tyser	ori	r4, r4, %lo(_reloc)
9937e4dafaSPeter Tyser	jmp	r4
10037e4dafaSPeter Tyser_reloc:
10137e4dafaSPeter Tyser
1024a572fa8SThomas Chou	/*
1034a572fa8SThomas Chou	 * COPY EXCEPTION TRAMPOLINE -- copy the tramp to the
10437e4dafaSPeter Tyser	 * exception address. Define CONFIG_ROM_STUBS to prevent
10537e4dafaSPeter Tyser	 * the copy (e.g. exception in flash or in other
10637e4dafaSPeter Tyser	 * softare/firmware component).
10737e4dafaSPeter Tyser	 */
10837e4dafaSPeter Tyser#if !defined(CONFIG_ROM_STUBS)
10937e4dafaSPeter Tyser	movhi	r4, %hi(_except_start)
11037e4dafaSPeter Tyser	ori	r4, r4, %lo(_except_start)
11137e4dafaSPeter Tyser	movhi	r5, %hi(_except_end)
11237e4dafaSPeter Tyser	ori	r5, r5, %lo(_except_end)
11337e4dafaSPeter Tyser	movhi	r6, %hi(CONFIG_SYS_EXCEPTION_ADDR)
11437e4dafaSPeter Tyser	ori	r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR)
11537e4dafaSPeter Tyser	beq	r4, r6, 7f	/* Skip if at proper addr */
11637e4dafaSPeter Tyser
11737e4dafaSPeter Tyser6:	ldwio	r7, 0(r4)
11837e4dafaSPeter Tyser	stwio	r7, 0(r6)
11937e4dafaSPeter Tyser	addi	r4, r4, 4
12037e4dafaSPeter Tyser	addi	r6, r6, 4
12137e4dafaSPeter Tyser	bne	r4, r5, 6b
12237e4dafaSPeter Tyser7:
12337e4dafaSPeter Tyser#endif
12437e4dafaSPeter Tyser
1254a572fa8SThomas Chou	/* STACK INIT -- zero top two words for call back chain. */
12637e4dafaSPeter Tyser	movhi	sp, %hi(CONFIG_SYS_INIT_SP)
12737e4dafaSPeter Tyser	ori	sp, sp, %lo(CONFIG_SYS_INIT_SP)
12837e4dafaSPeter Tyser	addi	sp, sp, -8
12937e4dafaSPeter Tyser	stw	r0, 0(sp)
13037e4dafaSPeter Tyser	stw	r0, 4(sp)
13137e4dafaSPeter Tyser	mov	fp, sp
13237e4dafaSPeter Tyser
1333e468e68SThomas Chou	/* Allocate and zero GD, update SP */
1343e468e68SThomas Chou	mov	r4, sp
1353e468e68SThomas Chou	movhi	r2, %hi(board_init_f_mem@h)
1363e468e68SThomas Chou	ori	r2, r2, %lo(board_init_f_mem@h)
1373e468e68SThomas Chou	callr	r2
1383e468e68SThomas Chou
1393e468e68SThomas Chou	/* Update stack- and frame-pointers */
1403e468e68SThomas Chou	mov	sp, r2
1413e468e68SThomas Chou	mov	fp, sp
1423e468e68SThomas Chou
1434a572fa8SThomas Chou	/* Call board_init_f -- never returns */
1445ff10aa7SThomas Chou	mov	r4, r0
1455ff10aa7SThomas Chou	movhi	r2, %hi(board_init_f@h)
1465ff10aa7SThomas Chou	ori	r2, r2, %lo(board_init_f@h)
1475ff10aa7SThomas Chou	callr	r2
14837e4dafaSPeter Tyser
1494a572fa8SThomas Chou	/*
1504a572fa8SThomas Chou	 * NEVER RETURNS -- but branch to the _start just
15137e4dafaSPeter Tyser	 * in case ;-)
15237e4dafaSPeter Tyser	 */
15337e4dafaSPeter Tyser	br	_start
15437e4dafaSPeter Tyser
1555ff10aa7SThomas Chou	/*
1565ff10aa7SThomas Chou	 * relocate_code -- Nios2 handles the relocation above. But
1575ff10aa7SThomas Chou	 * the generic board code monkeys with the heap, stack, etc.
1585ff10aa7SThomas Chou	 * (it makes some assumptions that may not be appropriate
1595ff10aa7SThomas Chou	 * for Nios). Nevertheless, we capitulate here.
1605ff10aa7SThomas Chou	 *
1615ff10aa7SThomas Chou	 * We'll call the board_init_r from here since this isn't
1625ff10aa7SThomas Chou	 * supposed to return.
1635ff10aa7SThomas Chou	 *
1645ff10aa7SThomas Chou	 * void relocate_code (ulong sp, gd_t *global_data,
1655ff10aa7SThomas Chou	 *			ulong reloc_addr)
1665ff10aa7SThomas Chou	 *			__attribute__ ((noreturn));
1675ff10aa7SThomas Chou	 */
1685ff10aa7SThomas Chou	.text
1695ff10aa7SThomas Chou	.global relocate_code
1705ff10aa7SThomas Chou
1715ff10aa7SThomas Chourelocate_code:
1725ff10aa7SThomas Chou	mov	sp, r4		/* Set the new sp */
1735ff10aa7SThomas Chou	mov	r4, r5
1744192b8c3SThomas Chou
1754192b8c3SThomas Chou	/*
1764192b8c3SThomas Chou	 * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
1774192b8c3SThomas Chou	 * and between __bss_start and __bss_end.
1784192b8c3SThomas Chou	 */
1794192b8c3SThomas Chou	movhi	r5, %hi(__bss_start)
1804192b8c3SThomas Chou	ori	r5, r5, %lo(__bss_start)
1814192b8c3SThomas Chou	movhi	r6, %hi(__bss_end)
1824192b8c3SThomas Chou	ori	r6, r6, %lo(__bss_end)
1834192b8c3SThomas Chou	beq	r5, r6, 5f
1844192b8c3SThomas Chou
1854192b8c3SThomas Chou4:	stwio	r0, 0(r5)
1864192b8c3SThomas Chou	addi	r5, r5, 4
1874192b8c3SThomas Chou	bne	r5, r6, 4b
1884192b8c3SThomas Chou5:
1894192b8c3SThomas Chou
1905ff10aa7SThomas Chou	movhi	r8, %hi(board_init_r@h)
1915ff10aa7SThomas Chou	ori	r8, r8, %lo(board_init_r@h)
1925ff10aa7SThomas Chou	callr	r8
1935ff10aa7SThomas Chou	ret
194