linux/tools/testing/selftests/powerpc/tm/tm-tar.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright 2015, Michael Neuling, IBM Corp.
   4 * Original: Michael Neuling 19/7/2013
   5 * Edited: Rashmica Gupta 01/12/2015
   6 *
   7 * Do some transactions, see if the tar is corrupted.
   8 * If the transaction is aborted, the TAR should be rolled back to the
   9 * checkpointed value before the transaction began. The value written to
  10 * TAR in suspended mode should only remain in TAR if the transaction
  11 * completes.
  12 */
  13
  14#include <stdio.h>
  15#include <stdlib.h>
  16#include <unistd.h>
  17#include <string.h>
  18
  19#include "tm.h"
  20#include "utils.h"
  21
  22int     num_loops       = 10000;
  23
  24int test_tar(void)
  25{
  26        int i;
  27
  28        SKIP_IF(!have_htm());
  29        SKIP_IF(htm_is_synthetic());
  30        SKIP_IF(!is_ppc64le());
  31
  32        for (i = 0; i < num_loops; i++)
  33        {
  34                uint64_t result = 0;
  35                asm __volatile__(
  36                        "li     7, 1;"
  37                        "mtspr  %[tar], 7;"     /* tar = 1 */
  38                        "tbegin.;"
  39                        "beq    3f;"
  40                        "li     4, 0x7000;"     /* Loop lots, to use time */
  41                        "2:;"                   /* Start loop */
  42                        "li     7, 2;"
  43                        "mtspr  %[tar], 7;"     /* tar = 2 */
  44                        "tsuspend.;"
  45                        "li     7, 3;"
  46                        "mtspr  %[tar], 7;"     /* tar = 3 */
  47                        "tresume.;"
  48                        "subi   4, 4, 1;"
  49                        "cmpdi  4, 0;"
  50                        "bne    2b;"
  51                        "tend.;"
  52
  53                        /* Transaction sucess! TAR should be 3 */
  54                        "mfspr  7, %[tar];"
  55                        "ori    %[res], 7, 4;"  // res = 3|4 = 7
  56                        "b      4f;"
  57
  58                        /* Abort handler. TAR should be rolled back to 1 */
  59                        "3:;"
  60                        "mfspr  7, %[tar];"
  61                        "ori    %[res], 7, 8;"  // res = 1|8 = 9
  62                        "4:;"
  63
  64                        : [res]"=r"(result)
  65                        : [tar]"i"(SPRN_TAR)
  66                           : "memory", "r0", "r4", "r7");
  67
  68                /* If result is anything else other than 7 or 9, the tar
  69                 * value must have been corrupted. */
  70                if ((result != 7) && (result != 9))
  71                        return 1;
  72        }
  73        return 0;
  74}
  75
  76int main(int argc, char *argv[])
  77{
  78        /* A low number of iterations (eg 100) can cause a false pass */
  79        if (argc > 1) {
  80                if (strcmp(argv[1], "-h") == 0) {
  81                        printf("Syntax:\n\t%s [<num loops>]\n",
  82                               argv[0]);
  83                        return 1;
  84                } else {
  85                        num_loops = atoi(argv[1]);
  86                }
  87        }
  88
  89        printf("Starting, %d loops\n", num_loops);
  90
  91        return test_harness(test_tar, "tm_tar");
  92}
  93