diff options
Diffstat (limited to 'arch/mips/kernel/head.S')
| -rw-r--r-- | arch/mips/kernel/head.S | 57 |
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 | */ |
| 168 | NESTED(smp_bootstrap, 16, sp) | 208 | NESTED(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 | ||
| 226 | 2: | ||
| 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 */ |
