xref: /linux/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c (revision 26fbb4c8c7c3ee9a4c3b4de555a8587b5a19154e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * POWER Data Stream Control Register (DSCR) explicit test
4  *
5  * This test modifies the DSCR value using mtspr instruction and
6  * verifies the change with mfspr instruction. It uses both the
7  * privilege state SPR and the problem state SPR for this purpose.
8  *
9  * When using the privilege state SPR, the instructions such as
10  * mfspr or mtspr are priviledged and the kernel emulates them
11  * for us. Instructions using problem state SPR can be exuecuted
12  * directly without any emulation if the HW supports them. Else
13  * they also get emulated by the kernel.
14  *
15  * Copyright 2012, Anton Blanchard, IBM Corporation.
16  * Copyright 2015, Anshuman Khandual, IBM Corporation.
17  */
18 #include "dscr.h"
19 
20 int dscr_explicit(void)
21 {
22 	unsigned long i, dscr = 0;
23 
24 	SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
25 
26 	srand(getpid());
27 	set_dscr(dscr);
28 
29 	for (i = 0; i < COUNT; i++) {
30 		unsigned long cur_dscr, cur_dscr_usr;
31 		double ret = uniform_deviate(rand());
32 
33 		if (ret < 0.001) {
34 			dscr++;
35 			if (dscr > DSCR_MAX)
36 				dscr = 0;
37 
38 			set_dscr(dscr);
39 		}
40 
41 		cur_dscr = get_dscr();
42 		if (cur_dscr != dscr) {
43 			fprintf(stderr, "Kernel DSCR should be %ld but "
44 					"is %ld\n", dscr, cur_dscr);
45 			return 1;
46 		}
47 
48 		ret = uniform_deviate(rand());
49 		if (ret < 0.001) {
50 			dscr++;
51 			if (dscr > DSCR_MAX)
52 				dscr = 0;
53 
54 			set_dscr_usr(dscr);
55 		}
56 
57 		cur_dscr_usr = get_dscr_usr();
58 		if (cur_dscr_usr != dscr) {
59 			fprintf(stderr, "User DSCR should be %ld but "
60 					"is %ld\n", dscr, cur_dscr_usr);
61 			return 1;
62 		}
63 	}
64 	return 0;
65 }
66 
67 int main(int argc, char *argv[])
68 {
69 	return test_harness(dscr_explicit, "dscr_explicit_test");
70 }
71