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