1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2020 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <stdio.h> 25bf215546Sopenharmony_ci#include <stdlib.h> 26bf215546Sopenharmony_ci#include <stdarg.h> 27bf215546Sopenharmony_ci#include <string.h> 28bf215546Sopenharmony_ci#include <inttypes.h> 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include <sys/types.h> 31bf215546Sopenharmony_ci#include <sys/stat.h> 32bf215546Sopenharmony_ci#include <fcntl.h> 33bf215546Sopenharmony_ci#include <unistd.h> 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#include <xf86drm.h> 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "intel_device_info.h" 38bf215546Sopenharmony_ci#include "intel_hwconfig.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_cistatic int 41bf215546Sopenharmony_cierror(char *fmt, ...) 42bf215546Sopenharmony_ci{ 43bf215546Sopenharmony_ci va_list ap; 44bf215546Sopenharmony_ci va_start(ap, fmt); 45bf215546Sopenharmony_ci vfprintf(stderr, fmt, ap); 46bf215546Sopenharmony_ci va_end(ap); 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci return EXIT_FAILURE; 49bf215546Sopenharmony_ci} 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_cistatic void 52bf215546Sopenharmony_ciprint_regions_info(const struct intel_device_info *devinfo) 53bf215546Sopenharmony_ci{ 54bf215546Sopenharmony_ci if (devinfo->mem.sram.mappable.size > 0 || 55bf215546Sopenharmony_ci devinfo->mem.sram.unmappable.size > 0) { 56bf215546Sopenharmony_ci fprintf(stdout, " sram:\n"); 57bf215546Sopenharmony_ci if (devinfo->mem.use_class_instance) { 58bf215546Sopenharmony_ci fprintf(stdout, " class: %d; instance: %d\n", 59bf215546Sopenharmony_ci devinfo->mem.sram.mem_class, devinfo->mem.sram.mem_instance); 60bf215546Sopenharmony_ci } 61bf215546Sopenharmony_ci fprintf(stdout, " mappable: %" PRId64 "; ", 62bf215546Sopenharmony_ci devinfo->mem.sram.mappable.size); 63bf215546Sopenharmony_ci fprintf(stdout, "free: %" PRId64 "\n", 64bf215546Sopenharmony_ci devinfo->mem.sram.mappable.free); 65bf215546Sopenharmony_ci if (devinfo->mem.sram.unmappable.size > 0) { 66bf215546Sopenharmony_ci fprintf(stdout, " unmappable: %" PRId64 "; ", 67bf215546Sopenharmony_ci devinfo->mem.sram.unmappable.size); 68bf215546Sopenharmony_ci fprintf(stdout, "free: %" PRId64 "\n", 69bf215546Sopenharmony_ci devinfo->mem.sram.unmappable.free); 70bf215546Sopenharmony_ci } 71bf215546Sopenharmony_ci } 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci if (devinfo->mem.vram.mappable.size > 0 || 74bf215546Sopenharmony_ci devinfo->mem.vram.unmappable.size > 0) { 75bf215546Sopenharmony_ci fprintf(stdout, " vram:\n"); 76bf215546Sopenharmony_ci if (devinfo->mem.use_class_instance) { 77bf215546Sopenharmony_ci fprintf(stdout, " class: %d; instance: %d\n", 78bf215546Sopenharmony_ci devinfo->mem.vram.mem_class, devinfo->mem.vram.mem_instance); 79bf215546Sopenharmony_ci } 80bf215546Sopenharmony_ci fprintf(stdout, " mappable: %" PRId64 "; ", 81bf215546Sopenharmony_ci devinfo->mem.vram.mappable.size); 82bf215546Sopenharmony_ci fprintf(stdout, "free: %" PRId64 "\n", 83bf215546Sopenharmony_ci devinfo->mem.vram.mappable.free); 84bf215546Sopenharmony_ci if (devinfo->mem.vram.unmappable.size > 0) { 85bf215546Sopenharmony_ci fprintf(stdout, " unmappable: %" PRId64 "; ", 86bf215546Sopenharmony_ci devinfo->mem.vram.unmappable.size); 87bf215546Sopenharmony_ci fprintf(stdout, "free: %" PRId64 "\n", 88bf215546Sopenharmony_ci devinfo->mem.vram.unmappable.free); 89bf215546Sopenharmony_ci } 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci} 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ciint 94bf215546Sopenharmony_cimain(int argc, char *argv[]) 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci drmDevicePtr devices[8]; 97bf215546Sopenharmony_ci int max_devices; 98bf215546Sopenharmony_ci bool print_hwconfig = argc > 1 && strcmp(argv[1], "--hwconfig") == 0; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices)); 101bf215546Sopenharmony_ci if (max_devices < 1) 102bf215546Sopenharmony_ci return error("Not device found"); 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci for (int i = 0; i < max_devices; i++) { 105bf215546Sopenharmony_ci struct intel_device_info devinfo; 106bf215546Sopenharmony_ci const char *path = devices[i]->nodes[DRM_NODE_RENDER]; 107bf215546Sopenharmony_ci int fd = open(path, O_RDWR | O_CLOEXEC); 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci if (fd < 0) 110bf215546Sopenharmony_ci continue; 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci if (print_hwconfig) { 113bf215546Sopenharmony_ci intel_get_and_print_hwconfig_table(fd); 114bf215546Sopenharmony_ci } 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci bool success = intel_get_device_info_from_fd(fd, &devinfo); 117bf215546Sopenharmony_ci close(fd); 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci if (!success) 120bf215546Sopenharmony_ci continue; 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci fprintf(stdout, "devinfo struct size = %zu\n", sizeof(devinfo)); 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci fprintf(stdout, "%s:\n", path); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci fprintf(stdout, " name: %s\n", devinfo.name); 127bf215546Sopenharmony_ci fprintf(stdout, " gen: %u\n", devinfo.ver); 128bf215546Sopenharmony_ci fprintf(stdout, " PCI device id: 0x%x\n", devinfo.pci_device_id); 129bf215546Sopenharmony_ci fprintf(stdout, " PCI domain: 0x%x\n", devinfo.pci_domain); 130bf215546Sopenharmony_ci fprintf(stdout, " PCI bus: 0x%x\n", devinfo.pci_bus); 131bf215546Sopenharmony_ci fprintf(stdout, " PCI dev: 0x%x\n", devinfo.pci_dev); 132bf215546Sopenharmony_ci fprintf(stdout, " PCI function: 0x%x\n", devinfo.pci_func); 133bf215546Sopenharmony_ci fprintf(stdout, " PCI revision id: 0x%x\n", devinfo.pci_revision_id); 134bf215546Sopenharmony_ci fprintf(stdout, " revision: %u\n", devinfo.revision); 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci const char *subslice_name = devinfo.ver >= 12 ? "dualsubslice" : "subslice"; 137bf215546Sopenharmony_ci uint32_t n_s = 0, n_ss = 0, n_eus = 0; 138bf215546Sopenharmony_ci for (unsigned s = 0; s < devinfo.max_slices; s++) { 139bf215546Sopenharmony_ci n_s += (devinfo.slice_masks & (1u << s)) ? 1 : 0; 140bf215546Sopenharmony_ci for (unsigned ss = 0; ss < devinfo.max_subslices_per_slice; ss++) { 141bf215546Sopenharmony_ci fprintf(stdout, " slice%u.%s%u: ", s, subslice_name, ss); 142bf215546Sopenharmony_ci if (intel_device_info_subslice_available(&devinfo, s, ss)) { 143bf215546Sopenharmony_ci n_ss++; 144bf215546Sopenharmony_ci for (unsigned eu = 0; eu < devinfo.max_eus_per_subslice; eu++) { 145bf215546Sopenharmony_ci n_eus += intel_device_info_eu_available(&devinfo, s, ss, eu) ? 1 : 0; 146bf215546Sopenharmony_ci fprintf(stdout, "%s", intel_device_info_eu_available(&devinfo, s, ss, eu) ? "1" : "0"); 147bf215546Sopenharmony_ci } 148bf215546Sopenharmony_ci } else { 149bf215546Sopenharmony_ci fprintf(stdout, "fused"); 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci fprintf(stdout, "\n"); 152bf215546Sopenharmony_ci } 153bf215546Sopenharmony_ci } 154bf215546Sopenharmony_ci for (uint32_t pp = 0; pp < ARRAY_SIZE(devinfo.ppipe_subslices); pp++) { 155bf215546Sopenharmony_ci fprintf(stdout, " pixel pipe %02u: %u\n", 156bf215546Sopenharmony_ci pp, devinfo.ppipe_subslices[pp]); 157bf215546Sopenharmony_ci } 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci fprintf(stdout, " slices: %u\n", n_s); 160bf215546Sopenharmony_ci fprintf(stdout, " %s: %u\n", subslice_name, n_ss); 161bf215546Sopenharmony_ci fprintf(stdout, " EUs: %u\n", n_eus); 162bf215546Sopenharmony_ci fprintf(stdout, " EU threads: %u\n", n_eus * devinfo.num_thread_per_eu); 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci fprintf(stdout, " LLC: %u\n", devinfo.has_llc); 165bf215546Sopenharmony_ci fprintf(stdout, " threads per EU: %u\n", devinfo.num_thread_per_eu); 166bf215546Sopenharmony_ci fprintf(stdout, " URB size: %u\n", devinfo.urb.size); 167bf215546Sopenharmony_ci fprintf(stdout, " L3 banks: %u\n", devinfo.l3_banks); 168bf215546Sopenharmony_ci fprintf(stdout, " max VS threads: %u\n", devinfo.max_vs_threads); 169bf215546Sopenharmony_ci fprintf(stdout, " max TCS threads: %u\n", devinfo.max_tcs_threads); 170bf215546Sopenharmony_ci fprintf(stdout, " max TES threads: %u\n", devinfo.max_tes_threads); 171bf215546Sopenharmony_ci fprintf(stdout, " max GS threads: %u\n", devinfo.max_gs_threads); 172bf215546Sopenharmony_ci fprintf(stdout, " max WM threads: %u\n", devinfo.max_wm_threads); 173bf215546Sopenharmony_ci fprintf(stdout, " max CS threads: %u\n", devinfo.max_cs_threads); 174bf215546Sopenharmony_ci fprintf(stdout, " timestamp frequency: %" PRIu64 " / %.4f ns\n", 175bf215546Sopenharmony_ci devinfo.timestamp_frequency, 1000000000.0 / devinfo.timestamp_frequency); 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci print_regions_info(&devinfo); 178bf215546Sopenharmony_ci } 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci return EXIT_SUCCESS; 181bf215546Sopenharmony_ci} 182