Merge tag 'spi-fix-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
[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 #endif
71         ; Config DSP_CTRL properly, so kernel may use integer multiply,
72         ; multiply-accumulate, and divide operations
73         DSP_EARLY_INIT
74 .endm
75
76         .section .init.text, "ax",@progbits
77
78 ;----------------------------------------------------------------
79 ; Default Reset Handler (jumped into from Reset vector)
80 ; - Don't clobber r0,r1,r2 as they might have u-boot provided args
81 ; - Platforms can override this weak version if needed
82 ;----------------------------------------------------------------
83 WEAK(res_service)
84         j       stext
85 END(res_service)
86
87 ;----------------------------------------------------------------
88 ; Kernel Entry point
89 ;----------------------------------------------------------------
90 ENTRY(stext)
91
92         CPU_EARLY_SETUP
93
94 #ifdef CONFIG_SMP
95         GET_CPU_ID  r5
96         cmp     r5, 0
97         mov.nz  r0, r5
98         bz      .Lmaster_proceed
99
100         ; Non-Masters wait for Master to boot enough and bring them up
101         ; when they resume, tail-call to entry point
102         mov     blink, @first_lines_of_secondary
103         j       arc_platform_smp_wait_to_boot
104
105 .Lmaster_proceed:
106 #endif
107
108         ; Clear BSS before updating any globals
109         ; XXX: use ZOL here
110         mov     r5, __bss_start
111         sub     r6, __bss_stop, r5
112         lsr.f   lp_count, r6, 2
113         lpnz    1f
114         st.ab   0, [r5, 4]
115 1:
116
117         ; Uboot - kernel ABI
118         ;    r0 = [0] No uboot interaction, [1] cmdline in r2, [2] DTB in r2
119         ;    r1 = magic number (always zero as of now)
120         ;    r2 = pointer to uboot provided cmdline or external DTB in mem
121         ; These are handled later in handle_uboot_args()
122         st      r0, [@uboot_tag]
123         st      r1, [@uboot_magic]
124         st      r2, [@uboot_arg]
125
126         ; setup "current" tsk and optionally cache it in dedicated r25
127         mov     r9, @init_task
128         SET_CURR_TASK_ON_CPU  r9, r0    ; r9 = tsk, r0 = scratch
129
130         ; setup stack (fp, sp)
131         mov     fp, 0
132
133         ; tsk->thread_info is really a PAGE, whose bottom hoists stack
134         GET_TSK_STACK_BASE r9, sp       ; r9 = tsk, sp = stack base(output)
135
136         j       start_kernel    ; "C" entry point
137 END(stext)
138
139 #ifdef CONFIG_SMP
140 ;----------------------------------------------------------------
141 ;     First lines of code run by secondary before jumping to 'C'
142 ;----------------------------------------------------------------
143         .section .text, "ax",@progbits
144 ENTRY(first_lines_of_secondary)
145
146         ; setup per-cpu idle task as "current" on this CPU
147         ld      r0, [@secondary_idle_tsk]
148         SET_CURR_TASK_ON_CPU  r0, r1
149
150         ; setup stack (fp, sp)
151         mov     fp, 0
152
153         ; set it's stack base to tsk->thread_info bottom
154         GET_TSK_STACK_BASE r0, sp
155
156         j       start_kernel_secondary
157 END(first_lines_of_secondary)
158 #endif