diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2014-05-23 10:29:44 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-05-23 18:07:01 -0400 |
commit | b633648c5ad3cfbda0b3daea50d2135d44899259 (patch) | |
tree | 6100185cae10f36a55e71c3b220fc79cfa14b7c0 /arch/mips/include/asm/stackframe.h | |
parent | 8b2e62cc34feaaf1cac9440a93fb18ac0b1e81bc (diff) |
MIPS: MT: Remove SMTC support
Nobody is maintaining SMTC anymore and there also seems to be no userbase.
Which is a pity - the SMTC technology primarily developed by Kevin D.
Kissell <kevink@paralogos.com> is an ingenious demonstration for the MT
ASE's power and elegance.
Based on Markos Chandras <Markos.Chandras@imgtec.com> patch
https://patchwork.linux-mips.org/patch/6719/ which while very similar did
no longer apply cleanly when I tried to merge it plus some additional
post-SMTC cleanup - SMTC was a feature as tricky to remove as it was to
merge once upon a time.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/include/asm/stackframe.h')
-rw-r--r-- | arch/mips/include/asm/stackframe.h | 196 |
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 | ||
398 | 0: | ||
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 | ||
409 | 1: | ||
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 | ||
585 | 2: | ||
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 | ||