ARM: mmp: fix potential NULL dereference
[linux/fpc-iii.git] / arch / mips / kernel / bmips_vec.S
blobe908e81330b1bb8378458adcfc625148fe2b3287
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  */
11 #include <linux/init.h>
13 #include <asm/asm.h>
14 #include <asm/asmmacro.h>
15 #include <asm/cacheops.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>
23         .macro  BARRIER
24         .set    mips32
25         _ssnop
26         _ssnop
27         _ssnop
28         .set    mips0
29         .endm
31         __CPUINIT
33 /***********************************************************************
34  * Alternate CPU1 startup vector for BMIPS4350
35  *
36  * On some systems the bootloader has already started CPU1 and configured
37  * it to resume execution at 0x8000_0200 (!BEV IV vector) when it is
38  * triggered by the SW1 interrupt.  If that is the case we try to move
39  * it to a more convenient place: BMIPS_WARM_RESTART_VEC @ 0x8000_0380.
40  ***********************************************************************/
42 LEAF(bmips_smp_movevec)
43         la      k0, 1f
44         li      k1, CKSEG1
45         or      k0, k1
46         jr      k0
49         /* clear IV, pending IPIs */
50         mtc0    zero, CP0_CAUSE
52         /* re-enable IRQs to wait for SW1 */
53         li      k0, ST0_IE | ST0_BEV | STATUSF_IP1
54         mtc0    k0, CP0_STATUS
56         /* set up CPU1 CBR; move BASE to 0xa000_0000 */
57         li      k0, 0xff400000
58         mtc0    k0, $22, 6
59         li      k1, CKSEG1 | BMIPS_RELO_VECTOR_CONTROL_1
60         or      k0, k1
61         li      k1, 0xa0080000
62         sw      k1, 0(k0)
64         /* wait here for SW1 interrupt from bmips_boot_secondary() */
65         wait
67         la      k0, bmips_reset_nmi_vec
68         li      k1, CKSEG1
69         or      k0, k1
70         jr      k0
71 END(bmips_smp_movevec)
73 /***********************************************************************
74  * Reset/NMI vector
75  * For BMIPS processors that can relocate their exception vectors, this
76  * entire function gets copied to 0x8000_0000.
77  ***********************************************************************/
79 NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
80         .set    push
81         .set    noat
82         .align  4
84 #ifdef CONFIG_SMP
85         /* if the NMI bit is clear, assume this is a CPU1 reset instead */
86         li      k1, (1 << 19)
87         mfc0    k0, CP0_STATUS
88         and     k0, k1
89         beqz    k0, bmips_smp_entry
91 #if defined(CONFIG_CPU_BMIPS5000)
92         /* if we're not on core 0, this must be the SMP boot signal */
93         li      k1, (3 << 25)
94         mfc0    k0, $22
95         and     k0, k1
96         bnez    k0, bmips_smp_entry
97 #endif
98 #endif /* CONFIG_SMP */
100         /* nope, it's just a regular NMI */
101         SAVE_ALL
102         move    a0, sp
104         /* clear EXL, ERL, BEV so that TLB refills still work */
105         mfc0    k0, CP0_STATUS
106         li      k1, ST0_ERL | ST0_EXL | ST0_BEV | ST0_IE
107         or      k0, k1
108         xor     k0, k1
109         mtc0    k0, CP0_STATUS
110         BARRIER
112         /* jump to the NMI handler function */
113         la      k0, nmi_handler
114         jr      k0
116         RESTORE_ALL
117         .set    mips3
118         eret
120 /***********************************************************************
121  * CPU1 reset vector (used for the initial boot only)
122  * This is still part of bmips_reset_nmi_vec().
123  ***********************************************************************/
125 #ifdef CONFIG_SMP
127 bmips_smp_entry:
129         /* set up CP0 STATUS; enable FPU */
130         li      k0, 0x30000000
131         mtc0    k0, CP0_STATUS
132         BARRIER
134         /* set local CP0 CONFIG to make kseg0 cacheable, write-back */
135         mfc0    k0, CP0_CONFIG
136         ori     k0, 0x07
137         xori    k0, 0x04
138         mtc0    k0, CP0_CONFIG
140 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
141         /* initialize CPU1's local I-cache */
142         li      k0, 0x80000000
143         li      k1, 0x80010000
144         mtc0    zero, $28
145         mtc0    zero, $28, 1
146         BARRIER
148 1:      cache   Index_Store_Tag_I, 0(k0)
149         addiu   k0, 16
150         bne     k0, k1, 1b
151 #elif defined(CONFIG_CPU_BMIPS5000)
152         /* set exception vector base */
153         la      k0, ebase
154         lw      k0, 0(k0)
155         mtc0    k0, $15, 1
156         BARRIER
157 #endif
159         /* jump back to kseg0 in case we need to remap the kseg1 area */
160         la      k0, 1f
161         jr      k0
163         la      k0, bmips_enable_xks01
164         jalr    k0
166         /* use temporary stack to set up upper memory TLB */
167         li      sp, BMIPS_WARM_RESTART_VEC
168         la      k0, plat_wired_tlb_setup
169         jalr    k0
171         /* switch to permanent stack and continue booting */
173         .global bmips_secondary_reentry
174 bmips_secondary_reentry:
175         la      k0, bmips_smp_boot_sp
176         lw      sp, 0(k0)
177         la      k0, bmips_smp_boot_gp
178         lw      gp, 0(k0)
179         la      k0, start_secondary
180         jr      k0
182 #endif /* CONFIG_SMP */
184         .align  4
185         .global bmips_reset_nmi_vec_end
186 bmips_reset_nmi_vec_end:
188 END(bmips_reset_nmi_vec)
190         .set    pop
191         .previous
193 /***********************************************************************
194  * CPU1 warm restart vector (used for second and subsequent boots).
195  * Also used for S2 standby recovery (PM).
196  * This entire function gets copied to (BMIPS_WARM_RESTART_VEC)
197  ***********************************************************************/
199 LEAF(bmips_smp_int_vec)
201         .align  4
202         mfc0    k0, CP0_STATUS
203         ori     k0, 0x01
204         xori    k0, 0x01
205         mtc0    k0, CP0_STATUS
206         eret
208         .align  4
209         .global bmips_smp_int_vec_end
210 bmips_smp_int_vec_end:
212 END(bmips_smp_int_vec)
214 /***********************************************************************
215  * XKS01 support
216  * Certain CPUs support extending kseg0 to 1024MB.
217  ***********************************************************************/
219         __CPUINIT
221 LEAF(bmips_enable_xks01)
223 #if defined(CONFIG_XKS01)
225 #if defined(CONFIG_CPU_BMIPS4380)
226         mfc0    t0, $22, 3
227         li      t1, 0x1ff0
228         li      t2, (1 << 12) | (1 << 9)
229         or      t0, t1
230         xor     t0, t1
231         or      t0, t2
232         mtc0    t0, $22, 3
233         BARRIER
234 #elif defined(CONFIG_CPU_BMIPS5000)
235         mfc0    t0, $22, 5
236         li      t1, 0x01ff
237         li      t2, (1 << 8) | (1 << 5)
238         or      t0, t1
239         xor     t0, t1
240         or      t0, t2
241         mtc0    t0, $22, 5
242         BARRIER
243 #else
245 #error Missing XKS01 setup
247 #endif
249 #endif /* defined(CONFIG_XKS01) */
251         jr      ra
253 END(bmips_enable_xks01)
255         .previous