]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - arch/mips/kernel/bmips_vec.S
d9495f3f3fad345521aa5968731cd1f51e65020c
[mirror_ubuntu-bionic-kernel.git] / arch / mips / kernel / bmips_vec.S
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2011 by Kevin Cernekee (cernekee@gmail.com)
7 *
8 * Reset/NMI/re-entry vectors for BMIPS processors
9 */
10
11
12 #include <asm/asm.h>
13 #include <asm/asmmacro.h>
14 #include <asm/cacheops.h>
15 #include <asm/cpu.h>
16 #include <asm/regdef.h>
17 #include <asm/mipsregs.h>
18 #include <asm/stackframe.h>
19 #include <asm/addrspace.h>
20 #include <asm/hazards.h>
21 #include <asm/bmips.h>
22
23 .macro BARRIER
24 .set mips32
25 _ssnop
26 _ssnop
27 _ssnop
28 .set mips0
29 .endm
30
31 /***********************************************************************
32 * Alternate CPU1 startup vector for BMIPS4350
33 *
34 * On some systems the bootloader has already started CPU1 and configured
35 * it to resume execution at 0x8000_0200 (!BEV IV vector) when it is
36 * triggered by the SW1 interrupt. If that is the case we try to move
37 * it to a more convenient place: BMIPS_WARM_RESTART_VEC @ 0x8000_0380.
38 ***********************************************************************/
39
40 LEAF(bmips_smp_movevec)
41 la k0, 1f
42 li k1, CKSEG1
43 or k0, k1
44 jr k0
45
46 1:
47 /* clear IV, pending IPIs */
48 mtc0 zero, CP0_CAUSE
49
50 /* re-enable IRQs to wait for SW1 */
51 li k0, ST0_IE | ST0_BEV | STATUSF_IP1
52 mtc0 k0, CP0_STATUS
53
54 /* set up CPU1 CBR; move BASE to 0xa000_0000 */
55 li k0, 0xff400000
56 mtc0 k0, $22, 6
57 /* set up relocation vector address based on thread ID */
58 mfc0 k1, $22, 3
59 srl k1, 16
60 andi k1, 0x8000
61 or k1, CKSEG1 | BMIPS_RELO_VECTOR_CONTROL_0
62 or k0, k1
63 li k1, 0xa0080000
64 sw k1, 0(k0)
65
66 /* wait here for SW1 interrupt from bmips_boot_secondary() */
67 wait
68
69 la k0, bmips_reset_nmi_vec
70 li k1, CKSEG1
71 or k0, k1
72 jr k0
73 END(bmips_smp_movevec)
74
75 /***********************************************************************
76 * Reset/NMI vector
77 * For BMIPS processors that can relocate their exception vectors, this
78 * entire function gets copied to 0x8000_0000.
79 ***********************************************************************/
80
81 NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
82 .set push
83 .set noat
84 .align 4
85
86 #ifdef CONFIG_SMP
87 /* if the NMI bit is clear, assume this is a CPU1 reset instead */
88 li k1, (1 << 19)
89 mfc0 k0, CP0_STATUS
90 and k0, k1
91 beqz k0, bmips_smp_entry
92
93 #if defined(CONFIG_CPU_BMIPS5000)
94 mfc0 k0, CP0_PRID
95 li k1, PRID_IMP_BMIPS5000
96 /* mask with PRID_IMP_BMIPS5000 to cover both variants */
97 andi k0, PRID_IMP_BMIPS5000
98 bne k0, k1, 1f
99
100 /* if we're not on core 0, this must be the SMP boot signal */
101 li k1, (3 << 25)
102 mfc0 k0, $22
103 and k0, k1
104 bnez k0, bmips_smp_entry
105 1:
106 #endif /* CONFIG_CPU_BMIPS5000 */
107 #endif /* CONFIG_SMP */
108
109 /* nope, it's just a regular NMI */
110 SAVE_ALL
111 move a0, sp
112
113 /* clear EXL, ERL, BEV so that TLB refills still work */
114 mfc0 k0, CP0_STATUS
115 li k1, ST0_ERL | ST0_EXL | ST0_BEV | ST0_IE
116 or k0, k1
117 xor k0, k1
118 mtc0 k0, CP0_STATUS
119 BARRIER
120
121 /* jump to the NMI handler function */
122 la k0, nmi_handler
123 jr k0
124
125 RESTORE_ALL
126 .set arch=r4000
127 eret
128
129 /***********************************************************************
130 * CPU1 reset vector (used for the initial boot only)
131 * This is still part of bmips_reset_nmi_vec().
132 ***********************************************************************/
133
134 #ifdef CONFIG_SMP
135
136 bmips_smp_entry:
137
138 /* set up CP0 STATUS; enable FPU */
139 li k0, 0x30000000
140 mtc0 k0, CP0_STATUS
141 BARRIER
142
143 /* set local CP0 CONFIG to make kseg0 cacheable, write-back */
144 mfc0 k0, CP0_CONFIG
145 ori k0, 0x07
146 xori k0, 0x04
147 mtc0 k0, CP0_CONFIG
148
149 mfc0 k0, CP0_PRID
150 andi k0, 0xff00
151 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
152 li k1, PRID_IMP_BMIPS43XX
153 bne k0, k1, 2f
154
155 /* initialize CPU1's local I-cache */
156 li k0, 0x80000000
157 li k1, 0x80010000
158 mtc0 zero, $28
159 mtc0 zero, $28, 1
160 BARRIER
161
162 1: cache Index_Store_Tag_I, 0(k0)
163 addiu k0, 16
164 bne k0, k1, 1b
165
166 b 3f
167 2:
168 #endif /* CONFIG_CPU_BMIPS4350 || CONFIG_CPU_BMIPS4380 */
169 #if defined(CONFIG_CPU_BMIPS5000)
170 /* mask with PRID_IMP_BMIPS5000 to cover both variants */
171 li k1, PRID_IMP_BMIPS5000
172 andi k0, PRID_IMP_BMIPS5000
173 bne k0, k1, 3f
174
175 /* set exception vector base */
176 la k0, ebase
177 lw k0, 0(k0)
178 mtc0 k0, $15, 1
179 BARRIER
180 #endif /* CONFIG_CPU_BMIPS5000 */
181 3:
182 /* jump back to kseg0 in case we need to remap the kseg1 area */
183 la k0, 1f
184 jr k0
185 1:
186 la k0, bmips_enable_xks01
187 jalr k0
188
189 /* use temporary stack to set up upper memory TLB */
190 li sp, BMIPS_WARM_RESTART_VEC
191 la k0, plat_wired_tlb_setup
192 jalr k0
193
194 /* switch to permanent stack and continue booting */
195
196 .global bmips_secondary_reentry
197 bmips_secondary_reentry:
198 la k0, bmips_smp_boot_sp
199 lw sp, 0(k0)
200 la k0, bmips_smp_boot_gp
201 lw gp, 0(k0)
202 la k0, start_secondary
203 jr k0
204
205 #endif /* CONFIG_SMP */
206
207 .align 4
208 .global bmips_reset_nmi_vec_end
209 bmips_reset_nmi_vec_end:
210
211 END(bmips_reset_nmi_vec)
212
213 .set pop
214
215 /***********************************************************************
216 * CPU1 warm restart vector (used for second and subsequent boots).
217 * Also used for S2 standby recovery (PM).
218 * This entire function gets copied to (BMIPS_WARM_RESTART_VEC)
219 ***********************************************************************/
220
221 LEAF(bmips_smp_int_vec)
222
223 .align 4
224 mfc0 k0, CP0_STATUS
225 ori k0, 0x01
226 xori k0, 0x01
227 mtc0 k0, CP0_STATUS
228 eret
229
230 .align 4
231 .global bmips_smp_int_vec_end
232 bmips_smp_int_vec_end:
233
234 END(bmips_smp_int_vec)
235
236 /***********************************************************************
237 * XKS01 support
238 * Certain CPUs support extending kseg0 to 1024MB.
239 ***********************************************************************/
240
241 LEAF(bmips_enable_xks01)
242
243 #if defined(CONFIG_XKS01)
244 mfc0 t0, CP0_PRID
245 andi t2, t0, 0xff00
246 #if defined(CONFIG_CPU_BMIPS4380)
247 li t1, PRID_IMP_BMIPS43XX
248 bne t2, t1, 1f
249
250 andi t0, 0xff
251 addiu t1, t0, -PRID_REV_BMIPS4380_HI
252 bgtz t1, 2f
253 addiu t0, -PRID_REV_BMIPS4380_LO
254 bltz t0, 2f
255
256 mfc0 t0, $22, 3
257 li t1, 0x1ff0
258 li t2, (1 << 12) | (1 << 9)
259 or t0, t1
260 xor t0, t1
261 or t0, t2
262 mtc0 t0, $22, 3
263 BARRIER
264 b 2f
265 1:
266 #endif /* CONFIG_CPU_BMIPS4380 */
267 #if defined(CONFIG_CPU_BMIPS5000)
268 li t1, PRID_IMP_BMIPS5000
269 /* mask with PRID_IMP_BMIPS5000 to cover both variants */
270 andi t2, PRID_IMP_BMIPS5000
271 bne t2, t1, 2f
272
273 mfc0 t0, $22, 5
274 li t1, 0x01ff
275 li t2, (1 << 8) | (1 << 5)
276 or t0, t1
277 xor t0, t1
278 or t0, t2
279 mtc0 t0, $22, 5
280 BARRIER
281 #endif /* CONFIG_CPU_BMIPS5000 */
282 2:
283 #endif /* defined(CONFIG_XKS01) */
284
285 jr ra
286
287 END(bmips_enable_xks01)