xref: /OK3568_Linux_fs/u-boot/arch/arc/lib/start.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/*
2*4882a593Smuzhiyun * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun#include <asm-offsets.h>
8*4882a593Smuzhiyun#include <config.h>
9*4882a593Smuzhiyun#include <linux/linkage.h>
10*4882a593Smuzhiyun#include <asm/arcregs.h>
11*4882a593Smuzhiyun
12*4882a593SmuzhiyunENTRY(_start)
13*4882a593Smuzhiyun; ARCompact devices are not supposed to be SMP so master/slave check
14*4882a593Smuzhiyun; makes no sense.
15*4882a593Smuzhiyun#ifdef CONFIG_ISA_ARCV2
16*4882a593Smuzhiyun	; Non-masters will be halted immediately, they might be kicked later
17*4882a593Smuzhiyun	; by platform code right before passing control to the Linux kernel
18*4882a593Smuzhiyun	; in bootm.c:boot_jump_linux().
19*4882a593Smuzhiyun	lr 	r5, [identity]
20*4882a593Smuzhiyun	lsr	r5, r5, 8
21*4882a593Smuzhiyun	bmsk	r5, r5, 7
22*4882a593Smuzhiyun	cmp	r5, 0
23*4882a593Smuzhiyun	mov.nz	r0, r5
24*4882a593Smuzhiyun	bz	.Lmaster_proceed
25*4882a593Smuzhiyun	flag	1
26*4882a593Smuzhiyun	nop
27*4882a593Smuzhiyun	nop
28*4882a593Smuzhiyun	nop
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun.Lmaster_proceed:
31*4882a593Smuzhiyun#endif
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun	/* Setup interrupt vector base that matches "__text_start" */
34*4882a593Smuzhiyun	sr	__ivt_start, [ARC_AUX_INTR_VEC_BASE]
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun	; Disable/enable I-cache according to configuration
37*4882a593Smuzhiyun	lr	r5, [ARC_BCR_IC_BUILD]
38*4882a593Smuzhiyun	breq	r5, 0, 1f		; I$ doesn't exist
39*4882a593Smuzhiyun	lr	r5, [ARC_AUX_IC_CTRL]
40*4882a593Smuzhiyun#ifndef CONFIG_SYS_ICACHE_OFF
41*4882a593Smuzhiyun	bclr	r5, r5, 0		; 0 - Enable, 1 is Disable
42*4882a593Smuzhiyun#else
43*4882a593Smuzhiyun	bset	r5, r5, 0		; I$ exists, but is not used
44*4882a593Smuzhiyun#endif
45*4882a593Smuzhiyun	sr	r5, [ARC_AUX_IC_CTRL]
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun1:
48*4882a593Smuzhiyun	; Disable/enable D-cache according to configuration
49*4882a593Smuzhiyun	lr	r5, [ARC_BCR_DC_BUILD]
50*4882a593Smuzhiyun	breq	r5, 0, 1f		; D$ doesn't exist
51*4882a593Smuzhiyun	lr	r5, [ARC_AUX_DC_CTRL]
52*4882a593Smuzhiyun	bclr	r5, r5, 6		; Invalidate (discard w/o wback)
53*4882a593Smuzhiyun#ifndef CONFIG_SYS_DCACHE_OFF
54*4882a593Smuzhiyun	bclr	r5, r5, 0		; Enable (+Inv)
55*4882a593Smuzhiyun#else
56*4882a593Smuzhiyun	bset	r5, r5, 0		; Disable (+Inv)
57*4882a593Smuzhiyun#endif
58*4882a593Smuzhiyun	sr	r5, [ARC_AUX_DC_CTRL]
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun1:
61*4882a593Smuzhiyun#ifdef CONFIG_ISA_ARCV2
62*4882a593Smuzhiyun	; Disable System-Level Cache (SLC)
63*4882a593Smuzhiyun	lr	r5, [ARC_BCR_SLC]
64*4882a593Smuzhiyun	breq	r5, 0, 1f		; SLC doesn't exist
65*4882a593Smuzhiyun	lr	r5, [ARC_AUX_SLC_CTRL]
66*4882a593Smuzhiyun	bclr	r5, r5, 6		; Invalidate (discard w/o wback)
67*4882a593Smuzhiyun	bclr	r5, r5, 0		; Enable (+Inv)
68*4882a593Smuzhiyun	sr	r5, [ARC_AUX_SLC_CTRL]
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun1:
71*4882a593Smuzhiyun#endif
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun	/* Establish C runtime stack and frame */
74*4882a593Smuzhiyun	mov	%sp, CONFIG_SYS_INIT_SP_ADDR
75*4882a593Smuzhiyun	mov	%fp, %sp
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun	/* Allocate reserved area from current top of stack */
78*4882a593Smuzhiyun	mov	%r0, %sp
79*4882a593Smuzhiyun	bl	board_init_f_alloc_reserve
80*4882a593Smuzhiyun	/* Set stack below reserved area, adjust frame pointer accordingly */
81*4882a593Smuzhiyun	mov	%sp, %r0
82*4882a593Smuzhiyun	mov	%fp, %sp
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun	/* Initialize reserved area - note: r0 already contains address */
85*4882a593Smuzhiyun	bl	board_init_f_init_reserve
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun	/* Zero the one and only argument of "board_init_f" */
88*4882a593Smuzhiyun	mov_s	%r0, 0
89*4882a593Smuzhiyun	j	board_init_f
90*4882a593SmuzhiyunENDPROC(_start)
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun/*
93*4882a593Smuzhiyun * void board_init_f_r_trampoline(stack-pointer address)
94*4882a593Smuzhiyun *
95*4882a593Smuzhiyun * This "function" does not return, instead it continues in RAM
96*4882a593Smuzhiyun * after relocating the monitor code.
97*4882a593Smuzhiyun *
98*4882a593Smuzhiyun * r0 = new stack-pointer
99*4882a593Smuzhiyun */
100*4882a593SmuzhiyunENTRY(board_init_f_r_trampoline)
101*4882a593Smuzhiyun	/* Set up the stack- and frame-pointers */
102*4882a593Smuzhiyun	mov	%sp, %r0
103*4882a593Smuzhiyun	mov	%fp, %sp
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun	/* Update position of intterupt vector table */
106*4882a593Smuzhiyun	lr	%r0, [ARC_AUX_INTR_VEC_BASE]
107*4882a593Smuzhiyun	ld	%r1, [%r25, GD_RELOC_OFF]
108*4882a593Smuzhiyun	add	%r0, %r0, %r1
109*4882a593Smuzhiyun	sr	%r0, [ARC_AUX_INTR_VEC_BASE]
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun	/* Re-enter U-Boot by calling board_init_f_r */
112*4882a593Smuzhiyun	j	board_init_f_r
113*4882a593SmuzhiyunENDPROC(board_init_f_r_trampoline)
114