diff options
author | Maciej W. Rozycki <macro@linux-mips.org> | 2007-05-21 08:47:22 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-06-11 13:20:53 -0400 |
commit | fbf6ede2ce05592661cec04e04b88f6bab00eb09 (patch) | |
tree | 774a6423cae546a8a1b6bc311eb85aba777c93a6 /include/asm-mips | |
parent | 85f6038f2170e3335dda09c3dfb0f83110e87019 (diff) |
[MIPS] Fix KMODE for the R3000
This must be the oldest bug that we have got. Leaving interrupts "as
they are" for the R3000 obviously means copying IEp to IEc. Since we have
got STATMASK now, I took this opportunity to mask the status register
"correctly" for the R3000 now too. Oh, and the R3000 hardly ever is
64-bit.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'include/asm-mips')
-rw-r--r-- | include/asm-mips/stackframe.h | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 7afa1fdf70ca..ed33366b85b8 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h | |||
@@ -17,6 +17,18 @@ | |||
17 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
18 | #include <asm/asm-offsets.h> | 18 | #include <asm/asm-offsets.h> |
19 | 19 | ||
20 | /* | ||
21 | * For SMTC kernel, global IE should be left set, and interrupts | ||
22 | * controlled exclusively via IXMT. | ||
23 | */ | ||
24 | #ifdef CONFIG_MIPS_MT_SMTC | ||
25 | #define STATMASK 0x1e | ||
26 | #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | ||
27 | #define STATMASK 0x3f | ||
28 | #else | ||
29 | #define STATMASK 0x1f | ||
30 | #endif | ||
31 | |||
20 | #ifdef CONFIG_MIPS_MT_SMTC | 32 | #ifdef CONFIG_MIPS_MT_SMTC |
21 | #include <asm/mipsmtregs.h> | 33 | #include <asm/mipsmtregs.h> |
22 | #endif /* CONFIG_MIPS_MT_SMTC */ | 34 | #endif /* CONFIG_MIPS_MT_SMTC */ |
@@ -236,10 +248,10 @@ | |||
236 | .set reorder | 248 | .set reorder |
237 | .set noat | 249 | .set noat |
238 | mfc0 a0, CP0_STATUS | 250 | mfc0 a0, CP0_STATUS |
239 | ori a0, 0x1f | ||
240 | xori a0, 0x1f | ||
241 | mtc0 a0, CP0_STATUS | ||
242 | li v1, 0xff00 | 251 | li v1, 0xff00 |
252 | ori a0, STATMASK | ||
253 | xori a0, STATMASK | ||
254 | mtc0 a0, CP0_STATUS | ||
243 | and a0, v1 | 255 | and a0, v1 |
244 | LONG_L v0, PT_STATUS(sp) | 256 | LONG_L v0, PT_STATUS(sp) |
245 | nor v1, $0, v1 | 257 | nor v1, $0, v1 |
@@ -249,10 +261,6 @@ | |||
249 | LONG_L $31, PT_R31(sp) | 261 | LONG_L $31, PT_R31(sp) |
250 | LONG_L $28, PT_R28(sp) | 262 | LONG_L $28, PT_R28(sp) |
251 | LONG_L $25, PT_R25(sp) | 263 | LONG_L $25, PT_R25(sp) |
252 | #ifdef CONFIG_64BIT | ||
253 | LONG_L $8, PT_R8(sp) | ||
254 | LONG_L $9, PT_R9(sp) | ||
255 | #endif | ||
256 | LONG_L $7, PT_R7(sp) | 264 | LONG_L $7, PT_R7(sp) |
257 | LONG_L $6, PT_R6(sp) | 265 | LONG_L $6, PT_R6(sp) |
258 | LONG_L $5, PT_R5(sp) | 266 | LONG_L $5, PT_R5(sp) |
@@ -273,16 +281,6 @@ | |||
273 | .endm | 281 | .endm |
274 | 282 | ||
275 | #else | 283 | #else |
276 | /* | ||
277 | * For SMTC kernel, global IE should be left set, and interrupts | ||
278 | * controlled exclusively via IXMT. | ||
279 | */ | ||
280 | |||
281 | #ifdef CONFIG_MIPS_MT_SMTC | ||
282 | #define STATMASK 0x1e | ||
283 | #else | ||
284 | #define STATMASK 0x1f | ||
285 | #endif | ||
286 | .macro RESTORE_SOME | 284 | .macro RESTORE_SOME |
287 | .set push | 285 | .set push |
288 | .set reorder | 286 | .set reorder |
@@ -385,9 +383,9 @@ | |||
385 | .macro CLI | 383 | .macro CLI |
386 | #if !defined(CONFIG_MIPS_MT_SMTC) | 384 | #if !defined(CONFIG_MIPS_MT_SMTC) |
387 | mfc0 t0, CP0_STATUS | 385 | mfc0 t0, CP0_STATUS |
388 | li t1, ST0_CU0 | 0x1f | 386 | li t1, ST0_CU0 | STATMASK |
389 | or t0, t1 | 387 | or t0, t1 |
390 | xori t0, 0x1f | 388 | xori t0, STATMASK |
391 | mtc0 t0, CP0_STATUS | 389 | mtc0 t0, CP0_STATUS |
392 | #else /* CONFIG_MIPS_MT_SMTC */ | 390 | #else /* CONFIG_MIPS_MT_SMTC */ |
393 | /* | 391 | /* |
@@ -420,9 +418,9 @@ | |||
420 | .macro STI | 418 | .macro STI |
421 | #if !defined(CONFIG_MIPS_MT_SMTC) | 419 | #if !defined(CONFIG_MIPS_MT_SMTC) |
422 | mfc0 t0, CP0_STATUS | 420 | mfc0 t0, CP0_STATUS |
423 | li t1, ST0_CU0 | 0x1f | 421 | li t1, ST0_CU0 | STATMASK |
424 | or t0, t1 | 422 | or t0, t1 |
425 | xori t0, 0x1e | 423 | xori t0, STATMASK & ~1 |
426 | mtc0 t0, CP0_STATUS | 424 | mtc0 t0, CP0_STATUS |
427 | #else /* CONFIG_MIPS_MT_SMTC */ | 425 | #else /* CONFIG_MIPS_MT_SMTC */ |
428 | /* | 426 | /* |
@@ -451,7 +449,8 @@ | |||
451 | .endm | 449 | .endm |
452 | 450 | ||
453 | /* | 451 | /* |
454 | * Just move to kernel mode and leave interrupts as they are. | 452 | * Just move to kernel mode and leave interrupts as they are. Note |
453 | * for the R3000 this means copying the previous enable from IEp. | ||
455 | * Set cp0 enable bit as sign that we're running on the kernel stack | 454 | * Set cp0 enable bit as sign that we're running on the kernel stack |
456 | */ | 455 | */ |
457 | .macro KMODE | 456 | .macro KMODE |
@@ -482,9 +481,14 @@ | |||
482 | move ra, t0 | 481 | move ra, t0 |
483 | #endif /* CONFIG_MIPS_MT_SMTC */ | 482 | #endif /* CONFIG_MIPS_MT_SMTC */ |
484 | mfc0 t0, CP0_STATUS | 483 | mfc0 t0, CP0_STATUS |
485 | li t1, ST0_CU0 | 0x1e | 484 | li t1, ST0_CU0 | (STATMASK & ~1) |
485 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | ||
486 | andi t2, t0, ST0_IEP | ||
487 | srl t2, 2 | ||
488 | or t0, t2 | ||
489 | #endif | ||
486 | or t0, t1 | 490 | or t0, t1 |
487 | xori t0, 0x1e | 491 | xori t0, STATMASK & ~1 |
488 | mtc0 t0, CP0_STATUS | 492 | mtc0 t0, CP0_STATUS |
489 | #ifdef CONFIG_MIPS_MT_SMTC | 493 | #ifdef CONFIG_MIPS_MT_SMTC |
490 | _ehb | 494 | _ehb |