xref: /rk3399_rockchip-uboot/arch/mips/cpu/start.S (revision f5868a5da119421a5274a15a049f799dd60ef49a)
1eef88dfbSDaniel Schwierzeck/*
2eef88dfbSDaniel Schwierzeck *  Startup Code for MIPS32 CPU-core
3eef88dfbSDaniel Schwierzeck *
4eef88dfbSDaniel Schwierzeck *  Copyright (c) 2003	Wolfgang Denk <wd@denx.de>
5eef88dfbSDaniel Schwierzeck *
6eef88dfbSDaniel Schwierzeck * SPDX-License-Identifier:	GPL-2.0+
7eef88dfbSDaniel Schwierzeck */
8eef88dfbSDaniel Schwierzeck
9eef88dfbSDaniel Schwierzeck#include <asm-offsets.h>
10eef88dfbSDaniel Schwierzeck#include <config.h>
11eef88dfbSDaniel Schwierzeck#include <asm/asm.h>
12eef88dfbSDaniel Schwierzeck#include <asm/regdef.h>
13eef88dfbSDaniel Schwierzeck#include <asm/mipsregs.h>
14eef88dfbSDaniel Schwierzeck
15eef88dfbSDaniel Schwierzeck#ifndef CONFIG_SYS_INIT_SP_ADDR
16eef88dfbSDaniel Schwierzeck#define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_SDRAM_BASE + \
17eef88dfbSDaniel Schwierzeck				CONFIG_SYS_INIT_SP_OFFSET)
18eef88dfbSDaniel Schwierzeck#endif
19eef88dfbSDaniel Schwierzeck
20eef88dfbSDaniel Schwierzeck#ifdef CONFIG_32BIT
21eef88dfbSDaniel Schwierzeck# define MIPS_RELOC	3
22eef88dfbSDaniel Schwierzeck# define STATUS_SET	0
23eef88dfbSDaniel Schwierzeck#endif
24eef88dfbSDaniel Schwierzeck
25eef88dfbSDaniel Schwierzeck#ifdef CONFIG_64BIT
26eef88dfbSDaniel Schwierzeck# ifdef CONFIG_SYS_LITTLE_ENDIAN
27eef88dfbSDaniel Schwierzeck#  define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
28eef88dfbSDaniel Schwierzeck	(((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
29eef88dfbSDaniel Schwierzeck# else
30eef88dfbSDaniel Schwierzeck#  define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
31eef88dfbSDaniel Schwierzeck	((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
32eef88dfbSDaniel Schwierzeck# endif
33eef88dfbSDaniel Schwierzeck# define MIPS_RELOC	MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03)
34eef88dfbSDaniel Schwierzeck# define STATUS_SET	ST0_KX
35eef88dfbSDaniel Schwierzeck#endif
36eef88dfbSDaniel Schwierzeck
37eef88dfbSDaniel Schwierzeck	.set noreorder
38eef88dfbSDaniel Schwierzeck
3965d297afSDaniel Schwierzeck	.macro init_wr sel
4065d297afSDaniel Schwierzeck	MTC0	zero, CP0_WATCHLO,\sel
4165d297afSDaniel Schwierzeck	mtc0	t1, CP0_WATCHHI,\sel
4265d297afSDaniel Schwierzeck	mfc0	t0, CP0_WATCHHI,\sel
4365d297afSDaniel Schwierzeck	bgez	t0, wr_done
4465d297afSDaniel Schwierzeck	 nop
4565d297afSDaniel Schwierzeck	.endm
46eef88dfbSDaniel Schwierzeck
47345490fcSDaniel Schwierzeck	.macro uhi_mips_exception
48345490fcSDaniel Schwierzeck	move	k0, t9		# preserve t9 in k0
49345490fcSDaniel Schwierzeck	move	k1, a0		# preserve a0 in k1
50345490fcSDaniel Schwierzeck	li	t9, 15		# UHI exception operation
51345490fcSDaniel Schwierzeck	li	a0, 0		# Use hard register context
52345490fcSDaniel Schwierzeck	sdbbp	1		# Invoke UHI operation
53345490fcSDaniel Schwierzeck	.endm
54345490fcSDaniel Schwierzeck
55c3e72ab8SDaniel Schwierzeck	.macro setup_stack_gd
56c3e72ab8SDaniel Schwierzeck	li	t0, -16
57c3e72ab8SDaniel Schwierzeck	PTR_LI	t1, CONFIG_SYS_INIT_SP_ADDR
58c3e72ab8SDaniel Schwierzeck	and	sp, t1, t0		# force 16 byte alignment
59c3e72ab8SDaniel Schwierzeck	PTR_SUBU \
60c3e72ab8SDaniel Schwierzeck		sp, sp, GD_SIZE		# reserve space for gd
61c3e72ab8SDaniel Schwierzeck	and	sp, sp, t0		# force 16 byte alignment
62c3e72ab8SDaniel Schwierzeck	move	k0, sp			# save gd pointer
63*f5868a5dSAndy Yan#if CONFIG_VAL(SYS_MALLOC_F_LEN)
64*f5868a5dSAndy Yan	li	t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
65c3e72ab8SDaniel Schwierzeck	PTR_SUBU \
66c3e72ab8SDaniel Schwierzeck		sp, sp, t2		# reserve space for early malloc
67c3e72ab8SDaniel Schwierzeck	and	sp, sp, t0		# force 16 byte alignment
68c3e72ab8SDaniel Schwierzeck#endif
69c3e72ab8SDaniel Schwierzeck	move	fp, sp
70c3e72ab8SDaniel Schwierzeck
71c3e72ab8SDaniel Schwierzeck	/* Clear gd */
72c3e72ab8SDaniel Schwierzeck	move	t0, k0
73c3e72ab8SDaniel Schwierzeck1:
74c3e72ab8SDaniel Schwierzeck	PTR_S	zero, 0(t0)
75c3e72ab8SDaniel Schwierzeck	blt	t0, t1, 1b
76c3e72ab8SDaniel Schwierzeck	 PTR_ADDIU t0, PTRSIZE
77c3e72ab8SDaniel Schwierzeck
78*f5868a5dSAndy Yan#if CONFIG_VAL(SYS_MALLOC_F_LEN)
79c3e72ab8SDaniel Schwierzeck	PTR_S	sp, GD_MALLOC_BASE(k0)	# gd->malloc_base offset
80c3e72ab8SDaniel Schwierzeck#endif
81c3e72ab8SDaniel Schwierzeck	.endm
82c3e72ab8SDaniel Schwierzeck
8311349298SDaniel SchwierzeckENTRY(_start)
84a187559eSBin Meng	/* U-Boot entry point */
85eef88dfbSDaniel Schwierzeck	b	reset
8665d297afSDaniel Schwierzeck	 mtc0	zero, CP0_COUNT	# clear cp0 count for most accurate boot timing
87eef88dfbSDaniel Schwierzeck
88eef88dfbSDaniel Schwierzeck#if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG)
89eef88dfbSDaniel Schwierzeck	/*
90eef88dfbSDaniel Schwierzeck	 * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to
91eef88dfbSDaniel Schwierzeck	 * access external NOR flashes. If the board boots from NOR flash the
92eef88dfbSDaniel Schwierzeck	 * internal BootROM does a blind read at address 0xB0000010 to read the
93eef88dfbSDaniel Schwierzeck	 * initial configuration for that EBU in order to access the flash
94eef88dfbSDaniel Schwierzeck	 * device with correct parameters. This config option is board-specific.
95eef88dfbSDaniel Schwierzeck	 */
96af3971f8SDaniel Schwierzeck	.org 0x10
97eef88dfbSDaniel Schwierzeck	.word CONFIG_SYS_XWAY_EBU_BOOTCFG
98eef88dfbSDaniel Schwierzeck	.word 0x0
99af3971f8SDaniel Schwierzeck#endif
100af3971f8SDaniel Schwierzeck#if defined(CONFIG_MALTA)
101eef88dfbSDaniel Schwierzeck	/*
102eef88dfbSDaniel Schwierzeck	 * Linux expects the Board ID here.
103eef88dfbSDaniel Schwierzeck	 */
104af3971f8SDaniel Schwierzeck	.org 0x10
105eef88dfbSDaniel Schwierzeck	.word 0x00000420	# 0x420 (Malta Board with CoreLV)
106eef88dfbSDaniel Schwierzeck	.word 0x00000000
107eef88dfbSDaniel Schwierzeck#endif
108eef88dfbSDaniel Schwierzeck
109af3971f8SDaniel Schwierzeck#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
110345490fcSDaniel Schwierzeck	/*
111345490fcSDaniel Schwierzeck	 * Exception vector entry points. When running from ROM, an exception
112345490fcSDaniel Schwierzeck	 * cannot be handled. Halt execution and transfer control to debugger,
113345490fcSDaniel Schwierzeck	 * if one is attached.
114345490fcSDaniel Schwierzeck	 */
115eef88dfbSDaniel Schwierzeck	.org 0x200
116eef88dfbSDaniel Schwierzeck	/* TLB refill, 32 bit task */
117345490fcSDaniel Schwierzeck	uhi_mips_exception
118eef88dfbSDaniel Schwierzeck
119eef88dfbSDaniel Schwierzeck	.org 0x280
120eef88dfbSDaniel Schwierzeck	/* XTLB refill, 64 bit task */
121345490fcSDaniel Schwierzeck	uhi_mips_exception
122eef88dfbSDaniel Schwierzeck
123eef88dfbSDaniel Schwierzeck	.org 0x300
124eef88dfbSDaniel Schwierzeck	/* Cache error exception */
125345490fcSDaniel Schwierzeck	uhi_mips_exception
126eef88dfbSDaniel Schwierzeck
127eef88dfbSDaniel Schwierzeck	.org 0x380
128eef88dfbSDaniel Schwierzeck	/* General exception */
129345490fcSDaniel Schwierzeck	uhi_mips_exception
130eef88dfbSDaniel Schwierzeck
131eef88dfbSDaniel Schwierzeck	.org 0x400
132eef88dfbSDaniel Schwierzeck	/* Catch interrupt exceptions */
133345490fcSDaniel Schwierzeck	uhi_mips_exception
134eef88dfbSDaniel Schwierzeck
135eef88dfbSDaniel Schwierzeck	.org 0x480
136eef88dfbSDaniel Schwierzeck	/* EJTAG debug exception */
137eef88dfbSDaniel Schwierzeck1:	b	1b
138eef88dfbSDaniel Schwierzeck	 nop
139eef88dfbSDaniel Schwierzeck
140af3971f8SDaniel Schwierzeck	.org 0x500
141af3971f8SDaniel Schwierzeck#endif
142af3971f8SDaniel Schwierzeck
143eef88dfbSDaniel Schwierzeckreset:
14431d36f74SPaul Burton#if __mips_isa_rev >= 6
14531d36f74SPaul Burton	mfc0	t0, CP0_CONFIG, 5
14631d36f74SPaul Burton	and	t0, t0, MIPS_CONF5_VP
14731d36f74SPaul Burton	beqz	t0, 1f
14831d36f74SPaul Burton	 nop
14931d36f74SPaul Burton
15031d36f74SPaul Burton	b	2f
15131d36f74SPaul Burton	 mfc0	t0, CP0_GLOBALNUMBER
15231d36f74SPaul Burton#endif
15331d36f74SPaul Burton
154ee422142SÁlvaro Fernández Rojas#ifdef CONFIG_ARCH_BMIPS
155ee422142SÁlvaro Fernández Rojas1:	mfc0	t0, CP0_DIAGNOSTIC, 3
156ee422142SÁlvaro Fernández Rojas	and	t0, t0, (1 << 31)
157ee422142SÁlvaro Fernández Rojas#else
15831d36f74SPaul Burton1:	mfc0	t0, CP0_EBASE
15931d36f74SPaul Burton	and	t0, t0, EBASE_CPUNUM
160ee422142SÁlvaro Fernández Rojas#endif
16131d36f74SPaul Burton
16231d36f74SPaul Burton	/* Hang if this isn't the first CPU in the system */
16331d36f74SPaul Burton2:	beqz	t0, 4f
16431d36f74SPaul Burton	 nop
16531d36f74SPaul Burton3:	wait
16631d36f74SPaul Burton	b	3b
16731d36f74SPaul Burton	 nop
168eef88dfbSDaniel Schwierzeck
16965d297afSDaniel Schwierzeck	/* Init CP0 Status */
17065d297afSDaniel Schwierzeck4:	mfc0	t0, CP0_STATUS
17165d297afSDaniel Schwierzeck	and	t0, ST0_IMPL
17265d297afSDaniel Schwierzeck	or	t0, ST0_BEV | ST0_ERL | STATUS_SET
17365d297afSDaniel Schwierzeck	mtc0	t0, CP0_STATUS
17465d297afSDaniel Schwierzeck
17565d297afSDaniel Schwierzeck	/*
17665d297afSDaniel Schwierzeck	 * Check whether CP0 Config1 is implemented. If not continue
17765d297afSDaniel Schwierzeck	 * with legacy Watch register initialization.
17865d297afSDaniel Schwierzeck	 */
17965d297afSDaniel Schwierzeck	mfc0	t0, CP0_CONFIG
18065d297afSDaniel Schwierzeck	bgez	t0, wr_legacy
18165d297afSDaniel Schwierzeck	 nop
18265d297afSDaniel Schwierzeck
18365d297afSDaniel Schwierzeck	/*
18465d297afSDaniel Schwierzeck	 * Check WR bit in CP0 Config1 to determine if Watch registers
18565d297afSDaniel Schwierzeck	 * are implemented.
18665d297afSDaniel Schwierzeck	 */
18765d297afSDaniel Schwierzeck	mfc0	t0, CP0_CONFIG, 1
18865d297afSDaniel Schwierzeck	andi	t0, (1 << 3)
18965d297afSDaniel Schwierzeck	beqz	t0, wr_done
19065d297afSDaniel Schwierzeck	 nop
19165d297afSDaniel Schwierzeck
19265d297afSDaniel Schwierzeck	/* Clear Watch Status bits and disable watch exceptions */
19365d297afSDaniel Schwierzeck	li	t1, 0x7		# Clear I, R and W conditions
19465d297afSDaniel Schwierzeck	init_wr	0
19565d297afSDaniel Schwierzeck	init_wr	1
19665d297afSDaniel Schwierzeck	init_wr	2
19765d297afSDaniel Schwierzeck	init_wr	3
19865d297afSDaniel Schwierzeck	init_wr	4
19965d297afSDaniel Schwierzeck	init_wr	5
20065d297afSDaniel Schwierzeck	init_wr	6
20165d297afSDaniel Schwierzeck	init_wr	7
20265d297afSDaniel Schwierzeck	b	wr_done
20365d297afSDaniel Schwierzeck	 nop
20465d297afSDaniel Schwierzeck
20565d297afSDaniel Schwierzeckwr_legacy:
20665d297afSDaniel Schwierzeck	MTC0	zero, CP0_WATCHLO
207e26e8dc8SDaniel Schwierzeck	mtc0	zero, CP0_WATCHHI
208eef88dfbSDaniel Schwierzeck
20965d297afSDaniel Schwierzeckwr_done:
21065d297afSDaniel Schwierzeck	/* Clear WP, IV and SW interrupts */
211eef88dfbSDaniel Schwierzeck	mtc0	zero, CP0_CAUSE
212eef88dfbSDaniel Schwierzeck
21365d297afSDaniel Schwierzeck	/* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
214eef88dfbSDaniel Schwierzeck	mtc0	zero, CP0_COMPARE
215eef88dfbSDaniel Schwierzeck
216eef88dfbSDaniel Schwierzeck#ifndef CONFIG_SKIP_LOWLEVEL_INIT
2174f9226b4SPaul Burton	mfc0	t0, CP0_CONFIG
2184f9226b4SPaul Burton	and	t0, t0, MIPS_CONF_IMPL
2194f9226b4SPaul Burton	or	t0, t0, CONF_CM_UNCACHED
220eef88dfbSDaniel Schwierzeck	mtc0	t0, CP0_CONFIG
221c5b8412dSPaul Burton	ehb
222eef88dfbSDaniel Schwierzeck#endif
223eef88dfbSDaniel Schwierzeck
224b2b135d9SPaul Burton#ifdef CONFIG_MIPS_CM
225b2b135d9SPaul Burton	PTR_LA	t9, mips_cm_map
226b2b135d9SPaul Burton	jalr	t9
227b2b135d9SPaul Burton	 nop
228b2b135d9SPaul Burton#endif
229b2b135d9SPaul Burton
230924ad866SDaniel Schwierzeck#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
231924ad866SDaniel Schwierzeck	/* Set up initial stack and global data */
232924ad866SDaniel Schwierzeck	setup_stack_gd
2330d159d68SDaniel Schwierzeck
2340d159d68SDaniel Schwierzeck# ifdef CONFIG_DEBUG_UART
2350d159d68SDaniel Schwierzeck	/* Earliest point to set up debug uart */
2360d159d68SDaniel Schwierzeck	PTR_LA	t9, debug_uart_init
2370d159d68SDaniel Schwierzeck	jalr	t9
2380d159d68SDaniel Schwierzeck	 nop
2390d159d68SDaniel Schwierzeck# endif
240924ad866SDaniel Schwierzeck#endif
241924ad866SDaniel Schwierzeck
242eef88dfbSDaniel Schwierzeck#ifndef CONFIG_SKIP_LOWLEVEL_INIT
243f8981277SPaul Burton# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
244eef88dfbSDaniel Schwierzeck	/* Initialize any external memory */
245eef88dfbSDaniel Schwierzeck	PTR_LA	t9, lowlevel_init
246eef88dfbSDaniel Schwierzeck	jalr	t9
247eef88dfbSDaniel Schwierzeck	 nop
248f8981277SPaul Burton# endif
249eef88dfbSDaniel Schwierzeck
250eef88dfbSDaniel Schwierzeck	/* Initialize caches... */
251eef88dfbSDaniel Schwierzeck	PTR_LA	t9, mips_cache_reset
252eef88dfbSDaniel Schwierzeck	jalr	t9
253eef88dfbSDaniel Schwierzeck	 nop
254f8981277SPaul Burton
255f8981277SPaul Burton# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
256f8981277SPaul Burton	/* Initialize any external memory */
257f8981277SPaul Burton	PTR_LA	t9, lowlevel_init
258f8981277SPaul Burton	jalr	t9
259f8981277SPaul Burton	 nop
260f8981277SPaul Burton# endif
261eef88dfbSDaniel Schwierzeck#endif
262eef88dfbSDaniel Schwierzeck
263924ad866SDaniel Schwierzeck#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
264c3e72ab8SDaniel Schwierzeck	/* Set up initial stack and global data */
265c3e72ab8SDaniel Schwierzeck	setup_stack_gd
2660d159d68SDaniel Schwierzeck
2670d159d68SDaniel Schwierzeck# ifdef CONFIG_DEBUG_UART
2680d159d68SDaniel Schwierzeck	/* Earliest point to set up debug uart */
2690d159d68SDaniel Schwierzeck	PTR_LA	t9, debug_uart_init
2700d159d68SDaniel Schwierzeck	jalr	t9
2710d159d68SDaniel Schwierzeck	 nop
2720d159d68SDaniel Schwierzeck# endif
273924ad866SDaniel Schwierzeck#endif
274e26e8dc8SDaniel Schwierzeck
275a6279099SPurna Chandra Mandal	move	a0, zero		# a0 <-- boot_flags = 0
276eef88dfbSDaniel Schwierzeck	PTR_LA	t9, board_init_f
277345490fcSDaniel Schwierzeck
278eef88dfbSDaniel Schwierzeck	jr	t9
279eef88dfbSDaniel Schwierzeck	 move	ra, zero
280eef88dfbSDaniel Schwierzeck
28111349298SDaniel Schwierzeck	END(_start)
282