aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/stackframe.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/include/asm/stackframe.h')
-rw-r--r--arch/mips/include/asm/stackframe.h196
1 files changed, 1 insertions, 195 deletions
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index d301e108d5b8..b188c797565c 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -19,22 +19,12 @@
19#include <asm/asm-offsets.h> 19#include <asm/asm-offsets.h>
20#include <asm/thread_info.h> 20#include <asm/thread_info.h>
21 21
22/* 22#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
23 * For SMTC kernel, global IE should be left set, and interrupts
24 * controlled exclusively via IXMT.
25 */
26#ifdef CONFIG_MIPS_MT_SMTC
27#define STATMASK 0x1e
28#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
29#define STATMASK 0x3f 23#define STATMASK 0x3f
30#else 24#else
31#define STATMASK 0x1f 25#define STATMASK 0x1f
32#endif 26#endif
33 27
34#ifdef CONFIG_MIPS_MT_SMTC
35#include <asm/mipsmtregs.h>
36#endif /* CONFIG_MIPS_MT_SMTC */
37
38 .macro SAVE_AT 28 .macro SAVE_AT
39 .set push 29 .set push
40 .set noat 30 .set noat
@@ -186,16 +176,6 @@
186 mfc0 v1, CP0_STATUS 176 mfc0 v1, CP0_STATUS
187 LONG_S $2, PT_R2(sp) 177 LONG_S $2, PT_R2(sp)
188 LONG_S v1, PT_STATUS(sp) 178 LONG_S v1, PT_STATUS(sp)
189#ifdef CONFIG_MIPS_MT_SMTC
190 /*
191 * Ideally, these instructions would be shuffled in
192 * to cover the pipeline delay.
193 */
194 .set mips32
195 mfc0 k0, CP0_TCSTATUS
196 .set mips0
197 LONG_S k0, PT_TCSTATUS(sp)
198#endif /* CONFIG_MIPS_MT_SMTC */
199 LONG_S $4, PT_R4(sp) 179 LONG_S $4, PT_R4(sp)
200 mfc0 v1, CP0_CAUSE 180 mfc0 v1, CP0_CAUSE
201 LONG_S $5, PT_R5(sp) 181 LONG_S $5, PT_R5(sp)
@@ -321,36 +301,6 @@
321 .set push 301 .set push
322 .set reorder 302 .set reorder
323 .set noat 303 .set noat
324#ifdef CONFIG_MIPS_MT_SMTC
325 .set mips32r2
326 /*
327 * We need to make sure the read-modify-write
328 * of Status below isn't perturbed by an interrupt
329 * or cross-TC access, so we need to do at least a DMT,
330 * protected by an interrupt-inhibit. But setting IXMT
331 * also creates a few-cycle window where an IPI could
332 * be queued and not be detected before potentially
333 * returning to a WAIT or user-mode loop. It must be
334 * replayed.
335 *
336 * We're in the middle of a context switch, and
337 * we can't dispatch it directly without trashing
338 * some registers, so we'll try to detect this unlikely
339 * case and program a software interrupt in the VPE,
340 * as would be done for a cross-VPE IPI. To accommodate
341 * the handling of that case, we're doing a DVPE instead
342 * of just a DMT here to protect against other threads.
343 * This is a lot of cruft to cover a tiny window.
344 * If you can find a better design, implement it!
345 *
346 */
347 mfc0 v0, CP0_TCSTATUS
348 ori v0, TCSTATUS_IXMT
349 mtc0 v0, CP0_TCSTATUS
350 _ehb
351 DVPE 5 # dvpe a1
352 jal mips_ihb
353#endif /* CONFIG_MIPS_MT_SMTC */
354 mfc0 a0, CP0_STATUS 304 mfc0 a0, CP0_STATUS
355 ori a0, STATMASK 305 ori a0, STATMASK
356 xori a0, STATMASK 306 xori a0, STATMASK
@@ -362,59 +312,6 @@
362 and v0, v1 312 and v0, v1
363 or v0, a0 313 or v0, a0
364 mtc0 v0, CP0_STATUS 314 mtc0 v0, CP0_STATUS
365#ifdef CONFIG_MIPS_MT_SMTC
366/*
367 * Only after EXL/ERL have been restored to status can we
368 * restore TCStatus.IXMT.
369 */
370 LONG_L v1, PT_TCSTATUS(sp)
371 _ehb
372 mfc0 a0, CP0_TCSTATUS
373 andi v1, TCSTATUS_IXMT
374 bnez v1, 0f
375
376/*
377 * We'd like to detect any IPIs queued in the tiny window
378 * above and request an software interrupt to service them
379 * when we ERET.
380 *
381 * Computing the offset into the IPIQ array of the executing
382 * TC's IPI queue in-line would be tedious. We use part of
383 * the TCContext register to hold 16 bits of offset that we
384 * can add in-line to find the queue head.
385 */
386 mfc0 v0, CP0_TCCONTEXT
387 la a2, IPIQ
388 srl v0, v0, 16
389 addu a2, a2, v0
390 LONG_L v0, 0(a2)
391 beqz v0, 0f
392/*
393 * If we have a queue, provoke dispatch within the VPE by setting C_SW1
394 */
395 mfc0 v0, CP0_CAUSE
396 ori v0, v0, C_SW1
397 mtc0 v0, CP0_CAUSE
3980:
399 /*
400 * This test should really never branch but
401 * let's be prudent here. Having atomized
402 * the shared register modifications, we can
403 * now EVPE, and must do so before interrupts
404 * are potentially re-enabled.
405 */
406 andi a1, a1, MVPCONTROL_EVP
407 beqz a1, 1f
408 evpe
4091:
410 /* We know that TCStatua.IXMT should be set from above */
411 xori a0, a0, TCSTATUS_IXMT
412 or a0, a0, v1
413 mtc0 a0, CP0_TCSTATUS
414 _ehb
415
416 .set mips0
417#endif /* CONFIG_MIPS_MT_SMTC */
418 LONG_L v1, PT_EPC(sp) 315 LONG_L v1, PT_EPC(sp)
419 MTC0 v1, CP0_EPC 316 MTC0 v1, CP0_EPC
420 LONG_L $31, PT_R31(sp) 317 LONG_L $31, PT_R31(sp)
@@ -467,33 +364,11 @@
467 * Set cp0 enable bit as sign that we're running on the kernel stack 364 * Set cp0 enable bit as sign that we're running on the kernel stack
468 */ 365 */
469 .macro CLI 366 .macro CLI
470#if !defined(CONFIG_MIPS_MT_SMTC)
471 mfc0 t0, CP0_STATUS 367 mfc0 t0, CP0_STATUS
472 li t1, ST0_CU0 | STATMASK 368 li t1, ST0_CU0 | STATMASK
473 or t0, t1 369 or t0, t1
474 xori t0, STATMASK 370 xori t0, STATMASK
475 mtc0 t0, CP0_STATUS 371 mtc0 t0, CP0_STATUS
476#else /* CONFIG_MIPS_MT_SMTC */
477 /*
478 * For SMTC, we need to set privilege
479 * and disable interrupts only for the
480 * current TC, using the TCStatus register.
481 */
482 mfc0 t0, CP0_TCSTATUS
483 /* Fortunately CU 0 is in the same place in both registers */
484 /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
485 li t1, ST0_CU0 | 0x08001c00
486 or t0, t1
487 /* Clear TKSU, leave IXMT */
488 xori t0, 0x00001800
489 mtc0 t0, CP0_TCSTATUS
490 _ehb
491 /* We need to leave the global IE bit set, but clear EXL...*/
492 mfc0 t0, CP0_STATUS
493 ori t0, ST0_EXL | ST0_ERL
494 xori t0, ST0_EXL | ST0_ERL
495 mtc0 t0, CP0_STATUS
496#endif /* CONFIG_MIPS_MT_SMTC */
497 irq_disable_hazard 372 irq_disable_hazard
498 .endm 373 .endm
499 374
@@ -502,35 +377,11 @@
502 * Set cp0 enable bit as sign that we're running on the kernel stack 377 * Set cp0 enable bit as sign that we're running on the kernel stack
503 */ 378 */
504 .macro STI 379 .macro STI
505#if !defined(CONFIG_MIPS_MT_SMTC)
506 mfc0 t0, CP0_STATUS 380 mfc0 t0, CP0_STATUS
507 li t1, ST0_CU0 | STATMASK 381 li t1, ST0_CU0 | STATMASK
508 or t0, t1 382 or t0, t1
509 xori t0, STATMASK & ~1 383 xori t0, STATMASK & ~1
510 mtc0 t0, CP0_STATUS 384 mtc0 t0, CP0_STATUS
511#else /* CONFIG_MIPS_MT_SMTC */
512 /*
513 * For SMTC, we need to set privilege
514 * and enable interrupts only for the
515 * current TC, using the TCStatus register.
516 */
517 _ehb
518 mfc0 t0, CP0_TCSTATUS
519 /* Fortunately CU 0 is in the same place in both registers */
520 /* Set TCU0, TKSU (for later inversion) and IXMT */
521 li t1, ST0_CU0 | 0x08001c00
522 or t0, t1
523 /* Clear TKSU *and* IXMT */
524 xori t0, 0x00001c00
525 mtc0 t0, CP0_TCSTATUS
526 _ehb
527 /* We need to leave the global IE bit set, but clear EXL...*/
528 mfc0 t0, CP0_STATUS
529 ori t0, ST0_EXL
530 xori t0, ST0_EXL
531 mtc0 t0, CP0_STATUS
532 /* irq_enable_hazard below should expand to EHB for 24K/34K cpus */
533#endif /* CONFIG_MIPS_MT_SMTC */
534 irq_enable_hazard 385 irq_enable_hazard
535 .endm 386 .endm
536 387
@@ -540,32 +391,6 @@
540 * Set cp0 enable bit as sign that we're running on the kernel stack 391 * Set cp0 enable bit as sign that we're running on the kernel stack
541 */ 392 */
542 .macro KMODE 393 .macro KMODE
543#ifdef CONFIG_MIPS_MT_SMTC
544 /*
545 * This gets baroque in SMTC. We want to
546 * protect the non-atomic clearing of EXL
547 * with DMT/EMT, but we don't want to take
548 * an interrupt while DMT is still in effect.
549 */
550
551 /* KMODE gets invoked from both reorder and noreorder code */
552 .set push
553 .set mips32r2
554 .set noreorder
555 mfc0 v0, CP0_TCSTATUS
556 andi v1, v0, TCSTATUS_IXMT
557 ori v0, TCSTATUS_IXMT
558 mtc0 v0, CP0_TCSTATUS
559 _ehb
560 DMT 2 # dmt v0
561 /*
562 * We don't know a priori if ra is "live"
563 */
564 move t0, ra
565 jal mips_ihb
566 nop /* delay slot */
567 move ra, t0
568#endif /* CONFIG_MIPS_MT_SMTC */
569 mfc0 t0, CP0_STATUS 394 mfc0 t0, CP0_STATUS
570 li t1, ST0_CU0 | (STATMASK & ~1) 395 li t1, ST0_CU0 | (STATMASK & ~1)
571#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 396#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
@@ -576,25 +401,6 @@
576 or t0, t1 401 or t0, t1
577 xori t0, STATMASK & ~1 402 xori t0, STATMASK & ~1
578 mtc0 t0, CP0_STATUS 403 mtc0 t0, CP0_STATUS
579#ifdef CONFIG_MIPS_MT_SMTC
580 _ehb
581 andi v0, v0, VPECONTROL_TE
582 beqz v0, 2f
583 nop /* delay slot */
584 emt
5852:
586 mfc0 v0, CP0_TCSTATUS
587 /* Clear IXMT, then OR in previous value */
588 ori v0, TCSTATUS_IXMT
589 xori v0, TCSTATUS_IXMT
590 or v0, v1, v0
591 mtc0 v0, CP0_TCSTATUS
592 /*
593 * irq_disable_hazard below should expand to EHB
594 * on 24K/34K CPUS
595 */
596 .set pop
597#endif /* CONFIG_MIPS_MT_SMTC */
598 irq_disable_hazard 404 irq_disable_hazard
599 .endm 405 .endm
600 406