xref: /openbmc/u-boot/arch/nios2/cpu/start.S (revision e8f80a5a)
1*83d290c5STom Rini/* SPDX-License-Identifier: GPL-2.0+ */
237e4dafaSPeter Tyser/*
337e4dafaSPeter Tyser * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
437e4dafaSPeter Tyser * Scott McNutt <smcnutt@psyent.com>
537e4dafaSPeter Tyser */
637e4dafaSPeter Tyser
725ddd1fbSWolfgang Denk#include <asm-offsets.h>
837e4dafaSPeter Tyser#include <config.h>
937e4dafaSPeter Tyser#include <version.h>
1037e4dafaSPeter Tyser
1155e2b4d4SThomas Chou/*
1255e2b4d4SThomas Chou * icache and dcache configuration used only for start.S.
1355e2b4d4SThomas Chou * the values are chosen so that it will work for all configuration.
1455e2b4d4SThomas Chou */
1555e2b4d4SThomas Chou#define ICACHE_LINE_SIZE	32 /* fixed 32 */
1655e2b4d4SThomas Chou#define ICACHE_SIZE_MAX		0x10000 /* 64k max */
1755e2b4d4SThomas Chou#define DCACHE_LINE_SIZE_MIN	4 /* 4, 16, 32 */
1855e2b4d4SThomas Chou#define DCACHE_SIZE_MAX		0x10000 /* 64k max */
1955e2b4d4SThomas Chou
204a572fa8SThomas Chou	/* RESTART */
2137e4dafaSPeter Tyser	.text
22b8112091SThomas Chou	.global _start, _except_start, _except_end
2337e4dafaSPeter Tyser
2437e4dafaSPeter Tyser_start:
25fd2712d0SThomas Chou	wrctl	status, r0		/* Disable interrupts */
264a572fa8SThomas Chou	/*
274a572fa8SThomas Chou	 * ICACHE INIT -- only the icache line at the reset address
2837e4dafaSPeter Tyser	 * is invalidated at reset. So the init must stay within
2937e4dafaSPeter Tyser	 * the cache line size (8 words). If GERMS is used, we'll
3037e4dafaSPeter Tyser	 * just be invalidating the cache a second time. If cache
3137e4dafaSPeter Tyser	 * is not implemented initi behaves as nop.
3237e4dafaSPeter Tyser	 */
3355e2b4d4SThomas Chou	ori	r4, r0, %lo(ICACHE_LINE_SIZE)
3455e2b4d4SThomas Chou	movhi	r5, %hi(ICACHE_SIZE_MAX)
3555e2b4d4SThomas Chou	ori	r5, r5, %lo(ICACHE_SIZE_MAX)
36fd2712d0SThomas Chou0:	initi	r5
37fd2712d0SThomas Chou	sub	r5, r5, r4
38fd2712d0SThomas Chou	bgt	r5, r0, 0b
3937e4dafaSPeter Tyser	br	_except_end	/* Skip the tramp */
4037e4dafaSPeter Tyser
414a572fa8SThomas Chou	/*
424a572fa8SThomas Chou	 * EXCEPTION TRAMPOLINE -- the following gets copied
4337e4dafaSPeter Tyser	 * to the exception address (below), but is otherwise at the
4437e4dafaSPeter Tyser	 * default exception vector offset (0x0020).
4537e4dafaSPeter Tyser	 */
4637e4dafaSPeter Tyser_except_start:
4737e4dafaSPeter Tyser	movhi	et, %hi(_exception)
4837e4dafaSPeter Tyser	ori	et, et, %lo(_exception)
4937e4dafaSPeter Tyser	jmp	et
5037e4dafaSPeter Tyser_except_end:
5137e4dafaSPeter Tyser
524a572fa8SThomas Chou	/*
534a572fa8SThomas Chou	 * INTERRUPTS -- for now, all interrupts masked and globally
5437e4dafaSPeter Tyser	 * disabled.
5537e4dafaSPeter Tyser	 */
5637e4dafaSPeter Tyser	wrctl	ienable, r0		/* All disabled	*/
5737e4dafaSPeter Tyser
584a572fa8SThomas Chou	/*
594a572fa8SThomas Chou	 * DCACHE INIT -- if dcache not implemented, initd behaves as
6037e4dafaSPeter Tyser	 * nop.
6137e4dafaSPeter Tyser	 */
6255e2b4d4SThomas Chou	ori	r4, r0, %lo(DCACHE_LINE_SIZE_MIN)
6355e2b4d4SThomas Chou	movhi	r5, %hi(DCACHE_SIZE_MAX)
6455e2b4d4SThomas Chou	ori	r5, r5, %lo(DCACHE_SIZE_MAX)
6537e4dafaSPeter Tyser	mov	r6, r0
6637e4dafaSPeter Tyser1:	initd	0(r6)
6737e4dafaSPeter Tyser	add	r6, r6, r4
6837e4dafaSPeter Tyser	bltu	r6, r5, 1b
6937e4dafaSPeter Tyser
704a572fa8SThomas Chou	/*
714a572fa8SThomas Chou	 * RELOCATE CODE, DATA & COMMAND TABLE -- the following code
7237e4dafaSPeter Tyser	 * assumes code, data and the command table are all
7337e4dafaSPeter Tyser	 * contiguous. This lets us relocate everything as a single
7437e4dafaSPeter Tyser	 * block. Make sure the linker script matches this ;-)
7537e4dafaSPeter Tyser	 */
7637e4dafaSPeter Tyser	nextpc	r4
7737e4dafaSPeter Tyser_cur:	movhi	r5, %hi(_cur - _start)
7837e4dafaSPeter Tyser	ori	r5, r5, %lo(_cur - _start)
7937e4dafaSPeter Tyser	sub	r4, r4, r5		/* r4 <- cur _start */
8037e4dafaSPeter Tyser	mov	r8, r4
8137e4dafaSPeter Tyser	movhi	r5, %hi(_start)
8237e4dafaSPeter Tyser	ori	r5, r5, %lo(_start)	/* r5 <- linked _start */
8365af9f69SThomas Chou	mov	sp, r5		/* initial stack below u-boot code */
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	/* STACK INIT -- zero top two words for call back chain. */
10337e4dafaSPeter Tyser	addi	sp, sp, -8
10437e4dafaSPeter Tyser	stw	r0, 0(sp)
10537e4dafaSPeter Tyser	stw	r0, 4(sp)
10637e4dafaSPeter Tyser	mov	fp, sp
10737e4dafaSPeter Tyser
108e4f348baSThomas Chou#ifdef CONFIG_DEBUG_UART
109e4f348baSThomas Chou	/* Set up the debug UART */
110e4f348baSThomas Chou	movhi	r2, %hi(debug_uart_init@h)
111e4f348baSThomas Chou	ori	r2, r2, %lo(debug_uart_init@h)
112e4f348baSThomas Chou	callr	r2
113e4f348baSThomas Chou#endif
114e4f348baSThomas Chou
115ecc30663SAlbert ARIBAUD	/* Allocate and initialize reserved area, update SP */
1163e468e68SThomas Chou	mov	r4, sp
117ecc30663SAlbert ARIBAUD	movhi	r2, %hi(board_init_f_alloc_reserve@h)
118ecc30663SAlbert ARIBAUD	ori	r2, r2, %lo(board_init_f_alloc_reserve@h)
119ecc30663SAlbert ARIBAUD	callr	r2
120ecc30663SAlbert ARIBAUD	mov	sp, r2
121ecc30663SAlbert ARIBAUD	mov	r4, sp
122ecc30663SAlbert ARIBAUD	movhi	r2, %hi(board_init_f_init_reserve@h)
123ecc30663SAlbert ARIBAUD	ori	r2, r2, %lo(board_init_f_init_reserve@h)
1243e468e68SThomas Chou	callr	r2
1253e468e68SThomas Chou
126ecc30663SAlbert ARIBAUD	/* Update frame-pointer */
1273e468e68SThomas Chou	mov	fp, sp
1283e468e68SThomas Chou
1294a572fa8SThomas Chou	/* Call board_init_f -- never returns */
1305ff10aa7SThomas Chou	mov	r4, r0
1315ff10aa7SThomas Chou	movhi	r2, %hi(board_init_f@h)
1325ff10aa7SThomas Chou	ori	r2, r2, %lo(board_init_f@h)
1335ff10aa7SThomas Chou	callr	r2
13437e4dafaSPeter Tyser
1354a572fa8SThomas Chou	/*
1364a572fa8SThomas Chou	 * NEVER RETURNS -- but branch to the _start just
13737e4dafaSPeter Tyser	 * in case ;-)
13837e4dafaSPeter Tyser	 */
13937e4dafaSPeter Tyser	br	_start
14037e4dafaSPeter Tyser
1415ff10aa7SThomas Chou	/*
1425ff10aa7SThomas Chou	 * relocate_code -- Nios2 handles the relocation above. But
1435ff10aa7SThomas Chou	 * the generic board code monkeys with the heap, stack, etc.
1445ff10aa7SThomas Chou	 * (it makes some assumptions that may not be appropriate
1455ff10aa7SThomas Chou	 * for Nios). Nevertheless, we capitulate here.
1465ff10aa7SThomas Chou	 *
1475ff10aa7SThomas Chou	 * We'll call the board_init_r from here since this isn't
1485ff10aa7SThomas Chou	 * supposed to return.
1495ff10aa7SThomas Chou	 *
1505ff10aa7SThomas Chou	 * void relocate_code (ulong sp, gd_t *global_data,
1515ff10aa7SThomas Chou	 *			ulong reloc_addr)
1525ff10aa7SThomas Chou	 *			__attribute__ ((noreturn));
1535ff10aa7SThomas Chou	 */
1545ff10aa7SThomas Chou	.text
1555ff10aa7SThomas Chou	.global relocate_code
1565ff10aa7SThomas Chou
1575ff10aa7SThomas Chourelocate_code:
1585ff10aa7SThomas Chou	mov	sp, r4		/* Set the new sp */
1595ff10aa7SThomas Chou	mov	r4, r5
1604192b8c3SThomas Chou
1614192b8c3SThomas Chou	/*
1624192b8c3SThomas Chou	 * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
1634192b8c3SThomas Chou	 * and between __bss_start and __bss_end.
1644192b8c3SThomas Chou	 */
1654192b8c3SThomas Chou	movhi	r5, %hi(__bss_start)
1664192b8c3SThomas Chou	ori	r5, r5, %lo(__bss_start)
1674192b8c3SThomas Chou	movhi	r6, %hi(__bss_end)
1684192b8c3SThomas Chou	ori	r6, r6, %lo(__bss_end)
1694192b8c3SThomas Chou	beq	r5, r6, 5f
1704192b8c3SThomas Chou
1719208d7ebSThomas Chou4:	stw	r0, 0(r5)
1724192b8c3SThomas Chou	addi	r5, r5, 4
1734192b8c3SThomas Chou	bne	r5, r6, 4b
1744192b8c3SThomas Chou5:
1754192b8c3SThomas Chou
1765ff10aa7SThomas Chou	movhi	r8, %hi(board_init_r@h)
1775ff10aa7SThomas Chou	ori	r8, r8, %lo(board_init_r@h)
1785ff10aa7SThomas Chou	callr	r8
1795ff10aa7SThomas Chou	ret
180