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