1 /*
2  * Copyright © 2017 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 #include "config.h"
24 #include "igt.h"
25 #include <stdio.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <libgen.h>
30 #include <unistd.h>
31 #include <linux/limits.h>
32 
33 #define TOOLS "../tools/"
34 
35 struct line_check {
36 	int found;
37 	const char *substr;
38 };
39 
40 /**
41  * Our igt_log_buffer_inspect handler. Checks the output of the
42  * intel_l3_parity tool and increments line_check::found if a specific
43  * substring is found.
44  */
check_cmd_output(const char * line,void * data)45 static bool check_cmd_output(const char *line, void *data)
46 {
47 	struct line_check *check = data;
48 
49 	if (strstr(line, check->substr)) {
50 		check->found++;
51 	}
52 
53 	return false;
54 }
55 
assert_cmd_success(int exec_return)56 static void assert_cmd_success(int exec_return)
57 {
58 	igt_skip_on_f(exec_return == IGT_EXIT_SKIP,
59 		      "intel_l3_parity not supported\n");
60 	igt_assert_eq(exec_return, IGT_EXIT_SUCCESS);
61 }
62 
chdir_to_tools_dir(void)63 static bool chdir_to_tools_dir(void)
64 {
65 	char path[PATH_MAX];
66 
67 	/* Try TOOLS relative to cwd */
68 	if (chdir(TOOLS) == 0)
69 		return true;
70 
71 	/* Try TOOLS and install dir relative to test binary */
72 	if (readlink("/proc/self/exe", path, sizeof(path)) > 0)
73 		chdir(dirname(path));
74 
75 	return chdir(TOOLS) == 0 || chdir("../../bin") == 0;
76 }
77 
78 igt_main
79 {
80 	igt_skip_on_simulation();
81 
82 	igt_fixture {
83 		char *path;
84 
85 		igt_require_f(chdir_to_tools_dir(),
86 			      "Unable to determine the tools directory, expecting them in $cwd/" TOOLS " or $path/" TOOLS "\n");
87 		path = get_current_dir_name();
88 		igt_info("Using tools from %s\n", path);
89 		free(path);
90 	}
91 
92 	igt_subtest("sysfs_l3_parity") {
93 		int exec_return;
94 		struct line_check line;
95 
96 		igt_require(access("intel_l3_parity", X_OK) == 0);
97 
98 		/* Sanity check that l3 parity tool is usable: Enable
99 		 * row,bank,subbank 0,0,0.
100 		 *
101 		 * TODO: Better way to find intel_l3_parity. This path
102 		 * is relative to piglit's path, when run through
103 		 * piglit.
104 		 */
105 		igt_system_cmd(exec_return,
106 			       "./intel_l3_parity -r 0 -b 0 "
107 			       "-s 0 -e");
108 		assert_cmd_success(exec_return);
109 
110 		/* Disable row,bank,subbank 0,0,0. */
111 		igt_system_cmd(exec_return,
112 			       "./intel_l3_parity -r 0 -b 0 "
113 			       "-s 0 -d");
114 		assert_cmd_success(exec_return);
115 
116 		/* Check that disabling was successful */
117 		igt_system_cmd(exec_return,
118 			       "./intel_l3_parity -l");
119 		assert_cmd_success(exec_return);
120 		line.substr = "Row 0, Bank 0, Subbank 0 is disabled";
121 		line.found = 0;
122 		igt_log_buffer_inspect(check_cmd_output, &line);
123 		igt_assert_eq(line.found, 1);
124 
125 		/* Re-enable row,bank,subbank 0,0,0 */
126 		igt_system_cmd(exec_return,
127 			       "./intel_l3_parity -r 0 -b 0 "
128 			       "-s 0 -e");
129 		assert_cmd_success(exec_return);
130 
131 		/* Check that re-enabling was successful:
132 		 * intel_l3_parity -l should now not print that Row 0,
133 		 * Bank 0, Subbank 0 is disabled.
134 		 *
135 		 * The previously printed line is already in the log
136 		 * buffer so we check for count 1.
137 		 */
138 		igt_system_cmd(exec_return,
139 			       "./intel_l3_parity -l");
140 		assert_cmd_success(exec_return);
141 		line.substr = "Row 0, Bank 0, Subbank 0 is disabled";
142 		line.found = 0;
143 		igt_log_buffer_inspect(check_cmd_output,
144 				       &line);
145 		igt_assert_eq(line.found, 1);
146 	}
147 
148 	igt_subtest("tools_test") {
149 		igt_require(access("intel_reg", X_OK) == 0);
150 
151 		igt_assert_eq(igt_system_quiet("./intel_reg read 0x4030"),
152 			      IGT_EXIT_SUCCESS);
153 
154 		igt_assert_eq(igt_system_quiet("./intel_reg dump"),
155 			      IGT_EXIT_SUCCESS);
156 	}
157 }
158