0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <inttypes.h>
0027 #include <stdio.h>
0028 #include <stdlib.h>
0029 #include <assert.h>
0030 #include <asm/tm.h>
0031
0032 #include "utils.h"
0033 #include "tm.h"
0034 #include "../pmu/lib.h"
0035
0036 #define SPRN_DSCR 0x03
0037
0038 int test_body(void)
0039 {
0040 uint64_t rv, dscr1 = 1, dscr2, texasr;
0041
0042 SKIP_IF(!have_htm());
0043 SKIP_IF(htm_is_synthetic());
0044
0045 printf("Check DSCR TM context switch: ");
0046 fflush(stdout);
0047 for (;;) {
0048 asm __volatile__ (
0049
0050 "ld 3, %[dscr1];"
0051 "mtspr %[sprn_dscr], 3;"
0052
0053 "li %[rv], 1;"
0054
0055 "tbegin.;"
0056 "beq 1f;"
0057 "tsuspend.;"
0058
0059
0060 "2: ;"
0061 "tcheck 0;"
0062 "bc 4, 0, 2b;"
0063
0064
0065 "mfspr 3, %[sprn_dscr];"
0066 "std 3, %[dscr2];"
0067 "mfspr 3, %[sprn_texasr];"
0068 "std 3, %[texasr];"
0069
0070 "tresume.;"
0071 "tend.;"
0072 "li %[rv], 0;"
0073 "1: ;"
0074 : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr)
0075 : [dscr1]"m"(dscr1)
0076 , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR)
0077 : "memory", "r3"
0078 );
0079 assert(rv);
0080 if ((texasr >> 56) != TM_CAUSE_RESCHED) {
0081 continue;
0082 }
0083 if (dscr2 != dscr1) {
0084 printf(" FAIL\n");
0085 return 1;
0086 } else {
0087 printf(" OK\n");
0088 return 0;
0089 }
0090 }
0091 }
0092
0093 static int tm_resched_dscr(void)
0094 {
0095 return eat_cpu(test_body);
0096 }
0097
0098 int main(int argc, const char *argv[])
0099 {
0100 return test_harness(tm_resched_dscr, "tm_resched_dscr");
0101 }