Merge tag 'locks-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton...
[linux-2.6-microblaze.git] / arch / arc / kernel / head.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * ARC CPU startup Code
4  *
5  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
6  *
7  * Vineetg: Dec 2007
8  *  -Check if we are running on Simulator or on real hardware
9  *      to skip certain things during boot on simulator
10  */
11
12 #include <linux/linkage.h>
13 #include <asm/asm-offsets.h>
14 #include <asm/entry.h>
15 #include <asm/arcregs.h>
16 #include <asm/cache.h>
17 #include <asm/dsp-impl.h>
18 #include <asm/irqflags.h>
19
20 .macro CPU_EARLY_SETUP
21
22         ; Setting up Vectror Table (in case exception happens in early boot
23         sr      @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
24
25         ; Disable I-cache/D-cache if kernel so configured
26         lr      r5, [ARC_REG_IC_BCR]
27         breq    r5, 0, 1f               ; I$ doesn't exist
28         lr      r5, [ARC_REG_IC_CTRL]
29 #ifdef CONFIG_ARC_HAS_ICACHE
30         bclr    r5, r5, 0               ; 0 - Enable, 1 is Disable
31 #else
32         bset    r5, r5, 0               ; I$ exists, but is not used
33 #endif
34         sr      r5, [ARC_REG_IC_CTRL]
35
36 1:
37         lr      r5, [ARC_REG_DC_BCR]
38         breq    r5, 0, 1f               ; D$ doesn't exist
39         lr      r5, [ARC_REG_DC_CTRL]
40         bclr    r5, r5, 6               ; Invalidate (discard w/o wback)
41 #ifdef CONFIG_ARC_HAS_DCACHE
42         bclr    r5, r5, 0               ; Enable (+Inv)
43 #else
44         bset    r5, r5, 0               ; Disable (+Inv)
45 #endif
46         sr      r5, [ARC_REG_DC_CTRL]
47
48 1:
49
50 #ifdef CONFIG_ISA_ARCV2
51         ; Unaligned access is disabled at reset, so re-enable early as
52         ; gcc 7.3.1 (ARC GNU 2018.03) onwards generates unaligned access
53         ; by default
54         lr      r5, [status32]
55 #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS
56         bset    r5, r5, STATUS_AD_BIT
57 #else
58         ; Although disabled at reset, bootloader might have enabled it
59         bclr    r5, r5, STATUS_AD_BIT
60 #endif
61         kflag   r5
62
63 #ifdef CONFIG_ARC_LPB_DISABLE
64         lr      r5, [ARC_REG_LPB_BUILD]
65         breq    r5, 0, 1f               ; LPB doesn't exist
66         mov     r5, 1
67         sr      r5, [ARC_REG_LPB_CTRL]
68 1:
69 #endif /* CONFIG_ARC_LPB_DISABLE */
70
71         /* On HSDK, CCMs need to remapped super early */
72 #ifdef CONFIG_ARC_SOC_HSDK
73         mov     r6, 0x60000000
74         lr      r5, [ARC_REG_ICCM_BUILD]
75         breq    r5, 0, 1f
76         sr      r6, [ARC_REG_AUX_ICCM]
77 1:
78         lr      r5, [ARC_REG_DCCM_BUILD]
79         breq    r5, 0, 2f
80         sr      r6, [ARC_REG_AUX_DCCM]
81 2:
82 #endif  /* CONFIG_ARC_SOC_HSDK */
83
84 #endif  /* CONFIG_ISA_ARCV2 */
85
86         ; Config DSP_CTRL properly, so kernel may use integer multiply,
87         ; multiply-accumulate, and divide operations
88         DSP_EARLY_INIT
89 .endm
90
91         .section .init.text, "ax",@progbits
92
93 ;----------------------------------------------------------------
94 ; Default Reset Handler (jumped into from Reset vector)
95 ; - Don't clobber r0,r1,r2 as they might have u-boot provided args
96 ; - Platforms can override this weak version if needed
97 ;----------------------------------------------------------------
98 WEAK(res_service)
99         j       stext
100 END(res_service)
101
102 ;----------------------------------------------------------------
103 ; Kernel Entry point
104 ;----------------------------------------------------------------
105 ENTRY(stext)
106
107         CPU_EARLY_SETUP
108
109 #ifdef CONFIG_SMP
110         GET_CPU_ID  r5
111         cmp     r5, 0
112         mov.nz  r0, r5
113         bz      .Lmaster_proceed
114
115         ; Non-Masters wait for Master to boot enough and bring them up
116         ; when they resume, tail-call to entry point
117         mov     blink, @first_lines_of_secondary
118         j       arc_platform_smp_wait_to_boot
119
120 .Lmaster_proceed:
121 #endif
122
123         ; Clear BSS before updating any globals
124         ; XXX: use ZOL here
125         mov     r5, __bss_start
126         sub     r6, __bss_stop, r5
127         lsr.f   lp_count, r6, 2
128         lpnz    1f
129         st.ab   0, [r5, 4]
130 1:
131
132         ; Uboot - kernel ABI
133         ;    r0 = [0] No uboot interaction, [1] cmdline in r2, [2] DTB in r2
134         ;    r1 = magic number (always zero as of now)
135         ;    r2 = pointer to uboot provided cmdline or external DTB in mem
136         ; These are handled later in handle_uboot_args()
137         st      r0, [@uboot_tag]
138         st      r1, [@uboot_magic]
139         st      r2, [@uboot_arg]
140
141         ; setup "current" tsk and optionally cache it in dedicated r25
142         mov     r9, @init_task
143         SET_CURR_TASK_ON_CPU  r9, r0    ; r9 = tsk, r0 = scratch
144
145         ; setup stack (fp, sp)
146         mov     fp, 0
147
148         ; tsk->thread_info is really a PAGE, whose bottom hoists stack
149         GET_TSK_STACK_BASE r9, sp       ; r9 = tsk, sp = stack base(output)
150
151         j       start_kernel    ; "C" entry point
152 END(stext)
153
154 #ifdef CONFIG_SMP
155 ;----------------------------------------------------------------
156 ;     First lines of code run by secondary before jumping to 'C'
157 ;----------------------------------------------------------------
158         .section .text, "ax",@progbits
159 ENTRY(first_lines_of_secondary)
160
161         ; setup per-cpu idle task as "current" on this CPU
162         ld      r0, [@secondary_idle_tsk]
163         SET_CURR_TASK_ON_CPU  r0, r1
164
165         ; setup stack (fp, sp)
166         mov     fp, 0
167
168         ; set it's stack base to tsk->thread_info bottom
169         GET_TSK_STACK_BASE r0, sp
170
171         j       start_kernel_secondary
172 END(first_lines_of_secondary)
173 #endif