aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/bmips_vec.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/bmips_vec.S')
-rw-r--r--arch/mips/kernel/bmips_vec.S255
1 files changed, 255 insertions, 0 deletions
diff --git a/arch/mips/kernel/bmips_vec.S b/arch/mips/kernel/bmips_vec.S
new file mode 100644
index 000000000000..e908e81330b1
--- /dev/null
+++ b/arch/mips/kernel/bmips_vec.S
@@ -0,0 +1,255 @@
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#include <linux/init.h>
12
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>
22
23 .macro BARRIER
24 .set mips32
25 _ssnop
26 _ssnop
27 _ssnop
28 .set mips0
29 .endm
30
31 __CPUINIT
32
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 ***********************************************************************/
41
42LEAF(bmips_smp_movevec)
43 la k0, 1f
44 li k1, CKSEG1
45 or k0, k1
46 jr k0
47
481:
49 /* clear IV, pending IPIs */
50 mtc0 zero, CP0_CAUSE
51
52 /* re-enable IRQs to wait for SW1 */
53 li k0, ST0_IE | ST0_BEV | STATUSF_IP1
54 mtc0 k0, CP0_STATUS
55
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)
63
64 /* wait here for SW1 interrupt from bmips_boot_secondary() */
65 wait
66
67 la k0, bmips_reset_nmi_vec
68 li k1, CKSEG1
69 or k0, k1
70 jr k0
71END(bmips_smp_movevec)
72
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 ***********************************************************************/
78
79NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
80 .set push
81 .set noat
82 .align 4
83
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
90
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 */
99
100 /* nope, it's just a regular NMI */
101 SAVE_ALL
102 move a0, sp
103
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
111
112 /* jump to the NMI handler function */
113 la k0, nmi_handler
114 jr k0
115
116 RESTORE_ALL
117 .set mips3
118 eret
119
120/***********************************************************************
121 * CPU1 reset vector (used for the initial boot only)
122 * This is still part of bmips_reset_nmi_vec().
123 ***********************************************************************/
124
125#ifdef CONFIG_SMP
126
127bmips_smp_entry:
128
129 /* set up CP0 STATUS; enable FPU */
130 li k0, 0x30000000
131 mtc0 k0, CP0_STATUS
132 BARRIER
133
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
139
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
147
1481: 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
158
159 /* jump back to kseg0 in case we need to remap the kseg1 area */
160 la k0, 1f
161 jr k0
1621:
163 la k0, bmips_enable_xks01
164 jalr k0
165
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
170
171 /* switch to permanent stack and continue booting */
172
173 .global bmips_secondary_reentry
174bmips_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
181
182#endif /* CONFIG_SMP */
183
184 .align 4
185 .global bmips_reset_nmi_vec_end
186bmips_reset_nmi_vec_end:
187
188END(bmips_reset_nmi_vec)
189
190 .set pop
191 .previous
192
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 ***********************************************************************/
198
199LEAF(bmips_smp_int_vec)
200
201 .align 4
202 mfc0 k0, CP0_STATUS
203 ori k0, 0x01
204 xori k0, 0x01
205 mtc0 k0, CP0_STATUS
206 eret
207
208 .align 4
209 .global bmips_smp_int_vec_end
210bmips_smp_int_vec_end:
211
212END(bmips_smp_int_vec)
213
214/***********************************************************************
215 * XKS01 support
216 * Certain CPUs support extending kseg0 to 1024MB.
217 ***********************************************************************/
218
219 __CPUINIT
220
221LEAF(bmips_enable_xks01)
222
223#if defined(CONFIG_XKS01)
224
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
244
245#error Missing XKS01 setup
246
247#endif
248
249#endif /* defined(CONFIG_XKS01) */
250
251 jr ra
252
253END(bmips_enable_xks01)
254
255 .previous