ARC: ARCv2: handle DSP presence in HW
[oweals/u-boot.git] / arch / arc / lib / start.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
4  */
5
6 #include <asm-offsets.h>
7 #include <config.h>
8 #include <linux/linkage.h>
9 #include <asm/arcregs.h>
10
11 ENTRY(_start)
12         /* Setup interrupt vector base that matches "__text_start" */
13         sr      __ivt_start, [ARC_AUX_INTR_VEC_BASE]
14
15         ; Disable/enable I-cache according to configuration
16         lr      r5, [ARC_BCR_IC_BUILD]
17         breq    r5, 0, 1f               ; I$ doesn't exist
18         lr      r5, [ARC_AUX_IC_CTRL]
19 #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
20         bclr    r5, r5, 0               ; 0 - Enable, 1 is Disable
21 #else
22         bset    r5, r5, 0               ; I$ exists, but is not used
23 #endif
24         sr      r5, [ARC_AUX_IC_CTRL]
25
26         mov     r5, 1
27         sr      r5, [ARC_AUX_IC_IVIC]
28         ; As per ARC HS databook (see chapter 5.3.3.2)
29         ; it is required to add 3 NOPs after each write to IC_IVIC.
30         nop
31         nop
32         nop
33
34 1:
35         ; Disable/enable D-cache according to configuration
36         lr      r5, [ARC_BCR_DC_BUILD]
37         breq    r5, 0, 1f               ; D$ doesn't exist
38         lr      r5, [ARC_AUX_DC_CTRL]
39         bclr    r5, r5, 6               ; Invalidate (discard w/o wback)
40 #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
41         bclr    r5, r5, 0               ; Enable (+Inv)
42 #else
43         bset    r5, r5, 0               ; Disable (+Inv)
44 #endif
45         sr      r5, [ARC_AUX_DC_CTRL]
46
47         mov     r5, 1
48         sr      r5, [ARC_AUX_DC_IVDC]
49
50
51 1:
52 #ifdef CONFIG_ISA_ARCV2
53         ; Disable System-Level Cache (SLC)
54         lr      r5, [ARC_BCR_SLC]
55         breq    r5, 0, 1f               ; SLC doesn't exist
56         lr      r5, [ARC_AUX_SLC_CTRL]
57         bclr    r5, r5, 6               ; Invalidate (discard w/o wback)
58         bclr    r5, r5, 0               ; Enable (+Inv)
59         sr      r5, [ARC_AUX_SLC_CTRL]
60
61 1:
62 #endif
63
64 #ifdef CONFIG_ISA_ARCV2
65         ; In case of DSP extension presence in HW some instructions
66         ; (related to integer multiply, multiply-accumulate, and divide
67         ; operation) executes on this DSP execution unit. So their
68         ; execution will depend on dsp configuration register (DSP_CTRL)
69         ; As we want these instructions to execute the same way regardless
70         ; of DSP presence we need to set DSP_CTRL properly.
71         lr      r5, [ARC_AUX_DSP_BUILD]
72         bmsk    r5, r5, 7
73         breq    r5, 0, 1f
74         mov     r5, 0
75         sr      r5, [ARC_AUX_DSP_CTRL]
76 1:
77 #endif
78
79 #ifdef __ARC_UNALIGNED__
80         /*
81          * Enable handling of unaligned access in the CPU as by default
82          * this HW feature is disabled while GCC starting from 8.1.0
83          * unconditionally uses it for ARC HS cores.
84          */
85         flag    1 << STATUS_AD_BIT
86 #endif
87
88         /* Establish C runtime stack and frame */
89         mov     %sp, CONFIG_SYS_INIT_SP_ADDR
90         mov     %fp, %sp
91
92         /* Allocate reserved area from current top of stack */
93         mov     %r0, %sp
94         bl      board_init_f_alloc_reserve
95         /* Set stack below reserved area, adjust frame pointer accordingly */
96         mov     %sp, %r0
97         mov     %fp, %sp
98
99         /* Initialize reserved area - note: r0 already contains address */
100         bl      board_init_f_init_reserve
101
102 #ifdef CONFIG_DEBUG_UART
103         /* Earliest point to set up early debug uart */
104         bl      debug_uart_init
105 #endif
106
107         /* Zero the one and only argument of "board_init_f" */
108         mov_s   %r0, 0
109         bl      board_init_f
110
111         /* We only get here if relocation is disabled by GD_FLG_SKIP_RELOC */
112         /* Make sure we don't lose GD overwritten by zero new GD */
113         mov     %r0, %r25
114         mov     %r1, 0
115         bl      board_init_r
116 ENDPROC(_start)
117
118 /*
119  * void board_init_f_r_trampoline(stack-pointer address)
120  *
121  * This "function" does not return, instead it continues in RAM
122  * after relocating the monitor code.
123  *
124  * r0 = new stack-pointer
125  */
126 ENTRY(board_init_f_r_trampoline)
127         /* Set up the stack- and frame-pointers */
128         mov     %sp, %r0
129         mov     %fp, %sp
130
131         /* Update position of intterupt vector table */
132         lr      %r0, [ARC_AUX_INTR_VEC_BASE]
133         ld      %r1, [%r25, GD_RELOC_OFF]
134         add     %r0, %r0, %r1
135         sr      %r0, [ARC_AUX_INTR_VEC_BASE]
136
137         /* Re-enter U-Boot by calling board_init_f_r */
138         j       board_init_f_r
139 ENDPROC(board_init_f_r_trampoline)