162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2015, Michael Neuling, IBM Corp. 462306a36Sopenharmony_ci * Original: Michael Neuling 19/7/2013 562306a36Sopenharmony_ci * Edited: Rashmica Gupta 01/12/2015 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Do some transactions, see if the tar is corrupted. 862306a36Sopenharmony_ci * If the transaction is aborted, the TAR should be rolled back to the 962306a36Sopenharmony_ci * checkpointed value before the transaction began. The value written to 1062306a36Sopenharmony_ci * TAR in suspended mode should only remain in TAR if the transaction 1162306a36Sopenharmony_ci * completes. 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <stdio.h> 1562306a36Sopenharmony_ci#include <stdlib.h> 1662306a36Sopenharmony_ci#include <unistd.h> 1762306a36Sopenharmony_ci#include <string.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "tm.h" 2062306a36Sopenharmony_ci#include "utils.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ciint num_loops = 10000; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ciint test_tar(void) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci int i; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci SKIP_IF(!have_htm()); 2962306a36Sopenharmony_ci SKIP_IF(htm_is_synthetic()); 3062306a36Sopenharmony_ci SKIP_IF(!is_ppc64le()); 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci for (i = 0; i < num_loops; i++) 3362306a36Sopenharmony_ci { 3462306a36Sopenharmony_ci uint64_t result = 0; 3562306a36Sopenharmony_ci asm __volatile__( 3662306a36Sopenharmony_ci "li 7, 1;" 3762306a36Sopenharmony_ci "mtspr %[tar], 7;" /* tar = 1 */ 3862306a36Sopenharmony_ci "tbegin.;" 3962306a36Sopenharmony_ci "beq 3f;" 4062306a36Sopenharmony_ci "li 4, 0x7000;" /* Loop lots, to use time */ 4162306a36Sopenharmony_ci "2:;" /* Start loop */ 4262306a36Sopenharmony_ci "li 7, 2;" 4362306a36Sopenharmony_ci "mtspr %[tar], 7;" /* tar = 2 */ 4462306a36Sopenharmony_ci "tsuspend.;" 4562306a36Sopenharmony_ci "li 7, 3;" 4662306a36Sopenharmony_ci "mtspr %[tar], 7;" /* tar = 3 */ 4762306a36Sopenharmony_ci "tresume.;" 4862306a36Sopenharmony_ci "subi 4, 4, 1;" 4962306a36Sopenharmony_ci "cmpdi 4, 0;" 5062306a36Sopenharmony_ci "bne 2b;" 5162306a36Sopenharmony_ci "tend.;" 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* Transaction sucess! TAR should be 3 */ 5462306a36Sopenharmony_ci "mfspr 7, %[tar];" 5562306a36Sopenharmony_ci "ori %[res], 7, 4;" // res = 3|4 = 7 5662306a36Sopenharmony_ci "b 4f;" 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci /* Abort handler. TAR should be rolled back to 1 */ 5962306a36Sopenharmony_ci "3:;" 6062306a36Sopenharmony_ci "mfspr 7, %[tar];" 6162306a36Sopenharmony_ci "ori %[res], 7, 8;" // res = 1|8 = 9 6262306a36Sopenharmony_ci "4:;" 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci : [res]"=r"(result) 6562306a36Sopenharmony_ci : [tar]"i"(SPRN_TAR) 6662306a36Sopenharmony_ci : "memory", "r0", "r4", "r7"); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci /* If result is anything else other than 7 or 9, the tar 6962306a36Sopenharmony_ci * value must have been corrupted. */ 7062306a36Sopenharmony_ci if ((result != 7) && (result != 9)) 7162306a36Sopenharmony_ci return 1; 7262306a36Sopenharmony_ci } 7362306a36Sopenharmony_ci return 0; 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ciint main(int argc, char *argv[]) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci /* A low number of iterations (eg 100) can cause a false pass */ 7962306a36Sopenharmony_ci if (argc > 1) { 8062306a36Sopenharmony_ci if (strcmp(argv[1], "-h") == 0) { 8162306a36Sopenharmony_ci printf("Syntax:\n\t%s [<num loops>]\n", 8262306a36Sopenharmony_ci argv[0]); 8362306a36Sopenharmony_ci return 1; 8462306a36Sopenharmony_ci } else { 8562306a36Sopenharmony_ci num_loops = atoi(argv[1]); 8662306a36Sopenharmony_ci } 8762306a36Sopenharmony_ci } 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci printf("Starting, %d loops\n", num_loops); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci return test_harness(test_tar, "tm_tar"); 9262306a36Sopenharmony_ci} 93