1 /*
2 * Copyright © 2020 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
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <string.h>
28 #include <inttypes.h>
29
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34
35 #include <xf86drm.h>
36
37 #include "intel_device_info.h"
38 #include "intel_hwconfig.h"
39
40 static int
error(char * fmt,...)41 error(char *fmt, ...)
42 {
43 va_list ap;
44 va_start(ap, fmt);
45 vfprintf(stderr, fmt, ap);
46 va_end(ap);
47
48 return EXIT_FAILURE;
49 }
50
51 static void
print_regions_info(const struct intel_device_info * devinfo)52 print_regions_info(const struct intel_device_info *devinfo)
53 {
54 if (devinfo->mem.sram.mappable.size > 0 ||
55 devinfo->mem.sram.unmappable.size > 0) {
56 fprintf(stdout, " sram:\n");
57 if (devinfo->mem.use_class_instance) {
58 fprintf(stdout, " class: %d; instance: %d\n",
59 devinfo->mem.sram.mem_class, devinfo->mem.sram.mem_instance);
60 }
61 fprintf(stdout, " mappable: %" PRId64 "; ",
62 devinfo->mem.sram.mappable.size);
63 fprintf(stdout, "free: %" PRId64 "\n",
64 devinfo->mem.sram.mappable.free);
65 if (devinfo->mem.sram.unmappable.size > 0) {
66 fprintf(stdout, " unmappable: %" PRId64 "; ",
67 devinfo->mem.sram.unmappable.size);
68 fprintf(stdout, "free: %" PRId64 "\n",
69 devinfo->mem.sram.unmappable.free);
70 }
71 }
72
73 if (devinfo->mem.vram.mappable.size > 0 ||
74 devinfo->mem.vram.unmappable.size > 0) {
75 fprintf(stdout, " vram:\n");
76 if (devinfo->mem.use_class_instance) {
77 fprintf(stdout, " class: %d; instance: %d\n",
78 devinfo->mem.vram.mem_class, devinfo->mem.vram.mem_instance);
79 }
80 fprintf(stdout, " mappable: %" PRId64 "; ",
81 devinfo->mem.vram.mappable.size);
82 fprintf(stdout, "free: %" PRId64 "\n",
83 devinfo->mem.vram.mappable.free);
84 if (devinfo->mem.vram.unmappable.size > 0) {
85 fprintf(stdout, " unmappable: %" PRId64 "; ",
86 devinfo->mem.vram.unmappable.size);
87 fprintf(stdout, "free: %" PRId64 "\n",
88 devinfo->mem.vram.unmappable.free);
89 }
90 }
91 }
92
93 int
main(int argc,char * argv[])94 main(int argc, char *argv[])
95 {
96 drmDevicePtr devices[8];
97 int max_devices;
98 bool print_hwconfig = argc > 1 && strcmp(argv[1], "--hwconfig") == 0;
99
100 max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
101 if (max_devices < 1)
102 return error("Not device found");
103
104 for (int i = 0; i < max_devices; i++) {
105 struct intel_device_info devinfo;
106 const char *path = devices[i]->nodes[DRM_NODE_RENDER];
107 int fd = open(path, O_RDWR | O_CLOEXEC);
108
109 if (fd < 0)
110 continue;
111
112 if (print_hwconfig) {
113 intel_get_and_print_hwconfig_table(fd);
114 }
115
116 bool success = intel_get_device_info_from_fd(fd, &devinfo);
117 close(fd);
118
119 if (!success)
120 continue;
121
122 fprintf(stdout, "devinfo struct size = %zu\n", sizeof(devinfo));
123
124 fprintf(stdout, "%s:\n", path);
125
126 fprintf(stdout, " name: %s\n", devinfo.name);
127 fprintf(stdout, " gen: %u\n", devinfo.ver);
128 fprintf(stdout, " PCI device id: 0x%x\n", devinfo.pci_device_id);
129 fprintf(stdout, " PCI domain: 0x%x\n", devinfo.pci_domain);
130 fprintf(stdout, " PCI bus: 0x%x\n", devinfo.pci_bus);
131 fprintf(stdout, " PCI dev: 0x%x\n", devinfo.pci_dev);
132 fprintf(stdout, " PCI function: 0x%x\n", devinfo.pci_func);
133 fprintf(stdout, " PCI revision id: 0x%x\n", devinfo.pci_revision_id);
134 fprintf(stdout, " revision: %u\n", devinfo.revision);
135
136 const char *subslice_name = devinfo.ver >= 12 ? "dualsubslice" : "subslice";
137 uint32_t n_s = 0, n_ss = 0, n_eus = 0;
138 for (unsigned s = 0; s < devinfo.max_slices; s++) {
139 n_s += (devinfo.slice_masks & (1u << s)) ? 1 : 0;
140 for (unsigned ss = 0; ss < devinfo.max_subslices_per_slice; ss++) {
141 fprintf(stdout, " slice%u.%s%u: ", s, subslice_name, ss);
142 if (intel_device_info_subslice_available(&devinfo, s, ss)) {
143 n_ss++;
144 for (unsigned eu = 0; eu < devinfo.max_eus_per_subslice; eu++) {
145 n_eus += intel_device_info_eu_available(&devinfo, s, ss, eu) ? 1 : 0;
146 fprintf(stdout, "%s", intel_device_info_eu_available(&devinfo, s, ss, eu) ? "1" : "0");
147 }
148 } else {
149 fprintf(stdout, "fused");
150 }
151 fprintf(stdout, "\n");
152 }
153 }
154 for (uint32_t pp = 0; pp < ARRAY_SIZE(devinfo.ppipe_subslices); pp++) {
155 fprintf(stdout, " pixel pipe %02u: %u\n",
156 pp, devinfo.ppipe_subslices[pp]);
157 }
158
159 fprintf(stdout, " slices: %u\n", n_s);
160 fprintf(stdout, " %s: %u\n", subslice_name, n_ss);
161 fprintf(stdout, " EUs: %u\n", n_eus);
162 fprintf(stdout, " EU threads: %u\n", n_eus * devinfo.num_thread_per_eu);
163
164 fprintf(stdout, " LLC: %u\n", devinfo.has_llc);
165 fprintf(stdout, " threads per EU: %u\n", devinfo.num_thread_per_eu);
166 fprintf(stdout, " URB size: %u\n", devinfo.urb.size);
167 fprintf(stdout, " L3 banks: %u\n", devinfo.l3_banks);
168 fprintf(stdout, " max VS threads: %u\n", devinfo.max_vs_threads);
169 fprintf(stdout, " max TCS threads: %u\n", devinfo.max_tcs_threads);
170 fprintf(stdout, " max TES threads: %u\n", devinfo.max_tes_threads);
171 fprintf(stdout, " max GS threads: %u\n", devinfo.max_gs_threads);
172 fprintf(stdout, " max WM threads: %u\n", devinfo.max_wm_threads);
173 fprintf(stdout, " max CS threads: %u\n", devinfo.max_cs_threads);
174 fprintf(stdout, " timestamp frequency: %" PRIu64 " / %.4f ns\n",
175 devinfo.timestamp_frequency, 1000000000.0 / devinfo.timestamp_frequency);
176
177 print_regions_info(&devinfo);
178 }
179
180 return EXIT_SUCCESS;
181 }
182