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