GNU Linux-libre 4.4.300-gnu1
[releases.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)