aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/head.S
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-04-05 04:45:45 -0400
committerRalf Baechle <ralf@linux-mips.org>2006-04-18 22:14:28 -0400
commit41c594ab65fc89573af296d192aa5235d09717ab (patch)
tree562462512a320f386bdf49eabfbb26bb3ee761fa /arch/mips/kernel/head.S
parent2600990e640e3bef29ed89d565864cf16ee83833 (diff)
[MIPS] MT: Improved multithreading support.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/head.S')
-rw-r--r--arch/mips/kernel/head.S57
1 files changed, 57 insertions, 0 deletions
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 2e9122a4213a..bdf6f6eff721 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -18,6 +18,7 @@
18#include <linux/threads.h> 18#include <linux/threads.h>
19 19
20#include <asm/asm.h> 20#include <asm/asm.h>
21#include <asm/asmmacro.h>
21#include <asm/regdef.h> 22#include <asm/regdef.h>
22#include <asm/page.h> 23#include <asm/page.h>
23#include <asm/mipsregs.h> 24#include <asm/mipsregs.h>
@@ -82,12 +83,33 @@
82 */ 83 */
83 .macro setup_c0_status set clr 84 .macro setup_c0_status set clr
84 .set push 85 .set push
86#ifdef CONFIG_MIPS_MT_SMTC
87 /*
88 * For SMTC, we need to set privilege and disable interrupts only for
89 * the current TC, using the TCStatus register.
90 */
91 mfc0 t0, CP0_TCSTATUS
92 /* Fortunately CU 0 is in the same place in both registers */
93 /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
94 li t1, ST0_CU0 | 0x08001c00
95 or t0, t1
96 /* Clear TKSU, leave IXMT */
97 xori t0, 0x00001800
98 mtc0 t0, CP0_TCSTATUS
99 ehb
100 /* We need to leave the global IE bit set, but clear EXL...*/
101 mfc0 t0, CP0_STATUS
102 or t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr
103 xor t0, ST0_EXL | ST0_ERL | \clr
104 mtc0 t0, CP0_STATUS
105#else
85 mfc0 t0, CP0_STATUS 106 mfc0 t0, CP0_STATUS
86 or t0, ST0_CU0|\set|0x1f|\clr 107 or t0, ST0_CU0|\set|0x1f|\clr
87 xor t0, 0x1f|\clr 108 xor t0, 0x1f|\clr
88 mtc0 t0, CP0_STATUS 109 mtc0 t0, CP0_STATUS
89 .set noreorder 110 .set noreorder
90 sll zero,3 # ehb 111 sll zero,3 # ehb
112#endif
91 .set pop 113 .set pop
92 .endm 114 .endm
93 115
@@ -134,6 +156,24 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
134 156
135 ARC64_TWIDDLE_PC 157 ARC64_TWIDDLE_PC
136 158
159#ifdef CONFIG_MIPS_MT_SMTC
160 /*
161 * In SMTC kernel, "CLI" is thread-specific, in TCStatus.
162 * We still need to enable interrupts globally in Status,
163 * and clear EXL/ERL.
164 *
165 * TCContext is used to track interrupt levels under
166 * service in SMTC kernel. Clear for boot TC before
167 * allowing any interrupts.
168 */
169 mtc0 zero, CP0_TCCONTEXT
170
171 mfc0 t0, CP0_STATUS
172 ori t0, t0, 0xff1f
173 xori t0, t0, 0x001e
174 mtc0 t0, CP0_STATUS
175#endif /* CONFIG_MIPS_MT_SMTC */
176
137 PTR_LA t0, __bss_start # clear .bss 177 PTR_LA t0, __bss_start # clear .bss
138 LONG_S zero, (t0) 178 LONG_S zero, (t0)
139 PTR_LA t1, __bss_stop - LONGSIZE 179 PTR_LA t1, __bss_stop - LONGSIZE
@@ -166,8 +206,25 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
166 * function after setting up the stack and gp registers. 206 * function after setting up the stack and gp registers.
167 */ 207 */
168NESTED(smp_bootstrap, 16, sp) 208NESTED(smp_bootstrap, 16, sp)
209#ifdef CONFIG_MIPS_MT_SMTC
210 /*
211 * Read-modify-writes of Status must be atomic, and this
212 * is one case where CLI is invoked without EXL being
213 * necessarily set. The CLI and setup_c0_status will
214 * in fact be redundant for all but the first TC of
215 * each VPE being booted.
216 */
217 DMT 10 # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */
218 jal mips_ihb
219#endif /* CONFIG_MIPS_MT_SMTC */
169 setup_c0_status_sec 220 setup_c0_status_sec
170 smp_slave_setup 221 smp_slave_setup
222#ifdef CONFIG_MIPS_MT_SMTC
223 andi t2, t2, VPECONTROL_TE
224 beqz t2, 2f
225 EMT # emt
2262:
227#endif /* CONFIG_MIPS_MT_SMTC */
171 j start_secondary 228 j start_secondary
172 END(smp_bootstrap) 229 END(smp_bootstrap)
173#endif /* CONFIG_SMP */ 230#endif /* CONFIG_SMP */