196d01610SSam bobroff /* Test context switching to see if the DSCR SPR is correctly preserved 296d01610SSam bobroff * when within a transaction. 396d01610SSam bobroff * 496d01610SSam bobroff * Note: We assume that the DSCR has been left at the default value (0) 596d01610SSam bobroff * for all CPUs. 696d01610SSam bobroff * 796d01610SSam bobroff * Method: 896d01610SSam bobroff * 996d01610SSam bobroff * Set a value into the DSCR. 1096d01610SSam bobroff * 1196d01610SSam bobroff * Start a transaction, and suspend it (*). 1296d01610SSam bobroff * 1396d01610SSam bobroff * Hard loop checking to see if the transaction has become doomed. 1496d01610SSam bobroff * 1596d01610SSam bobroff * Now that we *may* have been preempted, record the DSCR and TEXASR SPRS. 1696d01610SSam bobroff * 1796d01610SSam bobroff * If the abort was because of a context switch, check the DSCR value. 1896d01610SSam bobroff * Otherwise, try again. 1996d01610SSam bobroff * 2096d01610SSam bobroff * (*) If the transaction is not suspended we can't see the problem because 2196d01610SSam bobroff * the transaction abort handler will restore the DSCR to it's checkpointed 2296d01610SSam bobroff * value before we regain control. 2396d01610SSam bobroff */ 2496d01610SSam bobroff 2596d01610SSam bobroff #include <inttypes.h> 2696d01610SSam bobroff #include <stdio.h> 2796d01610SSam bobroff #include <stdlib.h> 2896d01610SSam bobroff #include <assert.h> 2996d01610SSam bobroff #include <asm/tm.h> 3096d01610SSam bobroff 31aa83f3d8SMichael Ellerman #include "utils.h" 32b319ee84SMichael Ellerman #include "tm.h" 33aa83f3d8SMichael Ellerman 3496d01610SSam bobroff #define SPRN_DSCR 0x03 3596d01610SSam bobroff 36aa83f3d8SMichael Ellerman int test_body(void) 37aa83f3d8SMichael Ellerman { 3896d01610SSam bobroff uint64_t rv, dscr1 = 1, dscr2, texasr; 3996d01610SSam bobroff 40b319ee84SMichael Ellerman SKIP_IF(!have_htm()); 41b319ee84SMichael Ellerman 4296d01610SSam bobroff printf("Check DSCR TM context switch: "); 4396d01610SSam bobroff fflush(stdout); 4496d01610SSam bobroff for (;;) { 4596d01610SSam bobroff rv = 1; 4696d01610SSam bobroff asm __volatile__ ( 4796d01610SSam bobroff /* set a known value into the DSCR */ 4896d01610SSam bobroff "ld 3, %[dscr1];" 4996d01610SSam bobroff "mtspr %[sprn_dscr], 3;" 5096d01610SSam bobroff 5196d01610SSam bobroff /* start and suspend a transaction */ 52*da3ddc3bSRashmica Gupta "tbegin.;" 5396d01610SSam bobroff "beq 1f;" 54*da3ddc3bSRashmica Gupta "tsuspend.;" 5596d01610SSam bobroff 5696d01610SSam bobroff /* hard loop until the transaction becomes doomed */ 5796d01610SSam bobroff "2: ;" 58*da3ddc3bSRashmica Gupta "tcheck 0;" 5996d01610SSam bobroff "bc 4, 0, 2b;" 6096d01610SSam bobroff 6196d01610SSam bobroff /* record DSCR and TEXASR */ 6296d01610SSam bobroff "mfspr 3, %[sprn_dscr];" 6396d01610SSam bobroff "std 3, %[dscr2];" 6496d01610SSam bobroff "mfspr 3, %[sprn_texasr];" 6596d01610SSam bobroff "std 3, %[texasr];" 6696d01610SSam bobroff 67*da3ddc3bSRashmica Gupta "tresume.;" 68*da3ddc3bSRashmica Gupta "tend.;" 6996d01610SSam bobroff "li %[rv], 0;" 7096d01610SSam bobroff "1: ;" 7196d01610SSam bobroff : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr) 7296d01610SSam bobroff : [dscr1]"m"(dscr1) 7396d01610SSam bobroff , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR) 7496d01610SSam bobroff : "memory", "r3" 7596d01610SSam bobroff ); 7696d01610SSam bobroff assert(rv); /* make sure the transaction aborted */ 7796d01610SSam bobroff if ((texasr >> 56) != TM_CAUSE_RESCHED) { 7896d01610SSam bobroff putchar('.'); 7996d01610SSam bobroff fflush(stdout); 8096d01610SSam bobroff continue; 8196d01610SSam bobroff } 8296d01610SSam bobroff if (dscr2 != dscr1) { 8396d01610SSam bobroff printf(" FAIL\n"); 84aa83f3d8SMichael Ellerman return 1; 8596d01610SSam bobroff } else { 8696d01610SSam bobroff printf(" OK\n"); 87aa83f3d8SMichael Ellerman return 0; 8896d01610SSam bobroff } 8996d01610SSam bobroff } 9096d01610SSam bobroff } 91aa83f3d8SMichael Ellerman 92aa83f3d8SMichael Ellerman int main(void) 93aa83f3d8SMichael Ellerman { 94aa83f3d8SMichael Ellerman return test_harness(test_body, "tm_resched_dscr"); 95aa83f3d8SMichael Ellerman } 96