xref: /aosp_15_r20/external/mesa3d/src/amd/drm-shim/amdgpu_dump_states.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2023 Google LLC
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <xf86drm.h>
11 #include <inttypes.h>
12 
13 #include "drm-uapi/amdgpu_drm.h"
14 #include "util/macros.h"
15 
16 static int
amdgpu_info_hw_ip_info(int fd,uint32_t type,struct drm_amdgpu_info_hw_ip * info)17 amdgpu_info_hw_ip_info(int fd, uint32_t type, struct drm_amdgpu_info_hw_ip *info)
18 {
19    struct drm_amdgpu_info arg = {
20       .return_pointer = (uint64_t)info,
21       .return_size = sizeof(*info),
22       .query = AMDGPU_INFO_HW_IP_INFO,
23       .query_hw_ip = {
24          .type = type,
25       },
26    };
27 
28    memset(info, 0, sizeof(*info));
29 
30    return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
31 }
32 
33 static int
amdgpu_info_fw_version(int fd,uint32_t type,struct drm_amdgpu_info_firmware * info)34 amdgpu_info_fw_version(int fd, uint32_t type, struct drm_amdgpu_info_firmware *info)
35 {
36    struct drm_amdgpu_info arg = {
37       .return_pointer = (uint64_t)info,
38       .return_size = sizeof(*info),
39       .query = AMDGPU_INFO_FW_VERSION,
40       .query_fw = {
41          .fw_type = type,
42       },
43    };
44 
45    memset(info, 0, sizeof(*info));
46 
47    return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
48 }
49 
50 static int
amdgpu_info_read_mmr_reg(int fd,uint32_t reg,uint32_t count,uint32_t instance,uint32_t * vals)51 amdgpu_info_read_mmr_reg(int fd, uint32_t reg, uint32_t count, uint32_t instance, uint32_t *vals)
52 {
53    struct drm_amdgpu_info arg = {
54       .return_pointer = (uint64_t)vals,
55       .return_size = sizeof(*vals) * count,
56       .query = AMDGPU_INFO_READ_MMR_REG,
57       .read_mmr_reg = {
58          .dword_offset = reg,
59          .count = count,
60          .instance = instance,
61       },
62    };
63 
64    memset(vals, 0, sizeof(*vals) * count);
65 
66    return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
67 }
68 
69 static int
amdgpu_info_dev_info(int fd,struct drm_amdgpu_info_device * info)70 amdgpu_info_dev_info(int fd, struct drm_amdgpu_info_device *info)
71 {
72    struct drm_amdgpu_info arg = {
73       .return_pointer = (uint64_t)info,
74       .return_size = sizeof(*info),
75       .query = AMDGPU_INFO_DEV_INFO,
76    };
77 
78    memset(info, 0, sizeof(*info));
79 
80    return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
81 }
82 
83 static int
amdgpu_info_memory(int fd,struct drm_amdgpu_memory_info * info)84 amdgpu_info_memory(int fd, struct drm_amdgpu_memory_info *info)
85 {
86    struct drm_amdgpu_info arg = {
87       .return_pointer = (uint64_t)info,
88       .return_size = sizeof(*info),
89       .query = AMDGPU_INFO_MEMORY,
90    };
91 
92    memset(info, 0, sizeof(*info));
93 
94    return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
95 }
96 
97 static void
amdgpu_dump_memory(int fd)98 amdgpu_dump_memory(int fd)
99 {
100    struct drm_amdgpu_memory_info info;
101    if (amdgpu_info_memory(fd, &info))
102       return;
103 
104    printf(".mem = {\n");
105    printf("   .vram = {\n");
106    printf("      .total_heap_size = UINT64_C(%"PRIu64"),\n", (uint64_t)info.vram.total_heap_size);
107    printf("      .usable_heap_size = UINT64_C(%"PRIu64"),\n", (uint64_t)info.vram.usable_heap_size);
108    printf("      .heap_usage = UINT64_C(%"PRIu64"),\n", (uint64_t)info.vram.heap_usage);
109    printf("      .max_allocation = UINT64_C(%"PRIu64"),\n", (uint64_t)info.vram.max_allocation);
110    printf("   },\n");
111    printf("   .cpu_accessible_vram = {\n");
112    printf("      .total_heap_size = UINT64_C(%"PRIu64"),\n",
113           (uint64_t)info.cpu_accessible_vram.total_heap_size);
114    printf("      .usable_heap_size = UINT64_C(%"PRIu64"),\n",
115           (uint64_t)info.cpu_accessible_vram.usable_heap_size);
116    printf("      .heap_usage = UINT64_C(%"PRIu64"),\n",
117           (uint64_t)info.cpu_accessible_vram.heap_usage);
118    printf("      .max_allocation = UINT64_C(%"PRIu64"),\n",
119           (uint64_t)info.cpu_accessible_vram.max_allocation);
120    printf("   },\n");
121    printf("   .gtt = {\n");
122    printf("      .total_heap_size = UINT64_C(%"PRIu64"),\n", (uint64_t)info.gtt.total_heap_size);
123    printf("      .usable_heap_size = UINT64_C(%"PRIu64"),\n", (uint64_t)info.gtt.usable_heap_size);
124    printf("      .heap_usage = UINT64_C(%"PRIu64"),\n", (uint64_t)info.gtt.heap_usage);
125    printf("      .max_allocation = UINT64_C(%"PRIu64"),\n", (uint64_t)info.gtt.max_allocation);
126    printf("   },\n");
127    printf("},\n");
128 }
129 
130 static void
amdgpu_dump_dev_info(int fd)131 amdgpu_dump_dev_info(int fd)
132 {
133    static const struct {
134       const char *name;
135       uint32_t family;
136    } families[] = {
137 #define FAMILY(x) { "AMDGPU_FAMILY_" #x, AMDGPU_FAMILY_##x }
138       /* clang-format off */
139       FAMILY(SI),
140       FAMILY(CI),
141       FAMILY(KV),
142       FAMILY(VI),
143       FAMILY(CZ),
144       FAMILY(AI),
145       FAMILY(RV),
146       FAMILY(NV),
147       FAMILY(VGH),
148       FAMILY(GC_11_0_0),
149       FAMILY(YC),
150       FAMILY(GC_11_0_1),
151       FAMILY(GC_10_3_6),
152       FAMILY(GC_10_3_7),
153       FAMILY(GC_11_5_0),
154    /* clang-format on */
155 #undef FAMILY
156    };
157 
158    struct drm_amdgpu_info_device info;
159    if (amdgpu_info_dev_info(fd, &info))
160       return;
161 
162    const char *family_name = NULL;
163    for (int i = 0; i < ARRAY_SIZE(families); i++) {
164       if (families[i].family == info.family) {
165          family_name = families[i].name;
166          break;
167       }
168    }
169    if (!family_name)
170       return;
171 
172    printf(".dev = {\n");
173    printf("   .device_id = 0x%04x,\n", info.device_id);
174    printf("   .chip_rev = 0x%02x,\n", info.chip_rev);
175    printf("   .external_rev = 0x%02x,\n", info.external_rev);
176    printf("   .pci_rev = 0x%02x,\n", info.pci_rev);
177 
178    printf("   .family = %s,\n", family_name);
179 
180    printf("   .num_shader_engines = %u,\n", info.num_shader_engines);
181    printf("   .num_shader_arrays_per_engine = %u,\n", info.num_shader_arrays_per_engine);
182    printf("   .gpu_counter_freq = %u,\n", info.gpu_counter_freq);
183    printf("   .max_engine_clock = UINT64_C(%"PRIu64"),\n", (uint64_t)info.max_engine_clock);
184    printf("   .max_memory_clock = UINT64_C(%"PRIu64"),\n", (uint64_t)info.max_memory_clock);
185    printf("   .cu_active_number = %u,\n", info.cu_active_number);
186    printf("   .cu_ao_mask = 0x%x,\n", info.cu_ao_mask);
187 
188    printf("   .cu_bitmap = {\n");
189    for (int i = 0; i < ARRAY_SIZE(info.cu_bitmap); i++) {
190       printf("      {");
191       for (int j = 0; j < ARRAY_SIZE(info.cu_bitmap[i]); j++)
192          printf(" 0x%x,", info.cu_bitmap[i][j]);
193       printf(" },\n");
194    }
195    printf("   },\n");
196 
197    printf("   .enabled_rb_pipes_mask = 0x%x,\n", info.enabled_rb_pipes_mask);
198    printf("   .num_rb_pipes = %u,\n", info.num_rb_pipes);
199    printf("   .num_hw_gfx_contexts = %u,\n", info.num_hw_gfx_contexts);
200    printf("   .pcie_gen = %u,\n", info.pcie_gen);
201    printf("   .ids_flags = UINT64_C(0x%"PRIx64"),\n", (uint64_t)info.ids_flags);
202    printf("   .virtual_address_offset = UINT64_C(0x%"PRIx64"),\n",
203           (uint64_t)info.virtual_address_offset);
204    printf("   .virtual_address_max = UINT64_C(0x%"PRIx64"),\n", (uint64_t)info.virtual_address_max);
205    printf("   .virtual_address_alignment = %u,\n", info.virtual_address_alignment);
206    printf("   .pte_fragment_size = %u,\n", info.pte_fragment_size);
207    printf("   .gart_page_size = %u,\n", info.gart_page_size);
208    printf("   .ce_ram_size = %u,\n", info.ce_ram_size);
209    printf("   .vram_type = %u,\n", info.vram_type);
210    printf("   .vram_bit_width = %u,\n", info.vram_bit_width);
211    printf("   .vce_harvest_config = %u,\n", info.vce_harvest_config);
212    printf("   .gc_double_offchip_lds_buf = %u,\n", info.gc_double_offchip_lds_buf);
213    printf("   .prim_buf_gpu_addr = UINT64_C(%"PRIu64"),\n", (uint64_t)info.prim_buf_gpu_addr);
214    printf("   .pos_buf_gpu_addr = UINT64_C(%"PRIu64"),\n", (uint64_t)info.pos_buf_gpu_addr);
215    printf("   .cntl_sb_buf_gpu_addr = UINT64_C(%"PRIu64"),\n", (uint64_t)info.cntl_sb_buf_gpu_addr);
216    printf("   .param_buf_gpu_addr = UINT64_C(%"PRIu64"),\n", (uint64_t)info.param_buf_gpu_addr);
217    printf("   .prim_buf_size = %u,\n", info.prim_buf_size);
218    printf("   .pos_buf_size = %u,\n", info.pos_buf_size);
219    printf("   .cntl_sb_buf_size = %u,\n", info.cntl_sb_buf_size);
220    printf("   .param_buf_size = %u,\n", info.param_buf_size);
221    printf("   .wave_front_size = %u,\n", info.wave_front_size);
222    printf("   .num_shader_visible_vgprs = %u,\n", info.num_shader_visible_vgprs);
223    printf("   .num_cu_per_sh = %u,\n", info.num_cu_per_sh);
224    printf("   .num_tcc_blocks = %u,\n", info.num_tcc_blocks);
225    printf("   .gs_vgt_table_depth = %u,\n", info.gs_vgt_table_depth);
226    printf("   .gs_prim_buffer_depth = %u,\n", info.gs_prim_buffer_depth);
227    printf("   .max_gs_waves_per_vgt = %u,\n", info.max_gs_waves_per_vgt);
228    printf("   .pcie_num_lanes = %u,\n", info.pcie_num_lanes);
229 
230    printf("   .cu_ao_bitmap = {\n");
231    for (int i = 0; i < ARRAY_SIZE(info.cu_ao_bitmap); i++) {
232       printf("      {");
233       for (int j = 0; j < ARRAY_SIZE(info.cu_ao_bitmap[i]); j++)
234          printf(" 0x%x,", info.cu_ao_bitmap[i][j]);
235       printf(" },\n");
236    }
237    printf("   },\n");
238 
239    printf("   .high_va_offset = UINT64_C(0x%"PRIx64"),\n", (uint64_t)info.high_va_offset);
240    printf("   .high_va_max = UINT64_C(0x%"PRIx64"),\n", (uint64_t)info.high_va_max);
241    printf("   .pa_sc_tile_steering_override = %u,\n", info.pa_sc_tile_steering_override);
242    printf("   .tcc_disabled_mask = UINT64_C(%"PRIu64"),\n", (uint64_t)info.tcc_disabled_mask);
243    printf("   .min_engine_clock = UINT64_C(%"PRIu64"),\n", (uint64_t)info.min_engine_clock);
244    printf("   .min_memory_clock = UINT64_C(%"PRIu64"),\n", (uint64_t)info.min_memory_clock);
245    printf("   .tcp_cache_size = %u,\n", info.tcp_cache_size);
246    printf("   .num_sqc_per_wgp = %u,\n", info.num_sqc_per_wgp);
247    printf("   .sqc_data_cache_size = %u,\n", info.sqc_data_cache_size);
248    printf("   .sqc_inst_cache_size = %u,\n", info.sqc_inst_cache_size);
249    printf("   .gl1c_cache_size = %u,\n", info.gl1c_cache_size);
250    printf("   .gl2c_cache_size = %u,\n", info.gl2c_cache_size);
251    printf("   .mall_size = UINT64_C(%"PRIu64"),\n", (uint64_t)info.mall_size);
252    printf("   .enabled_rb_pipes_mask_hi = %u,\n", info.enabled_rb_pipes_mask_hi);
253    printf("},\n");
254 }
255 
256 static void
amdgpu_dump_mmr_regs(int fd)257 amdgpu_dump_mmr_regs(int fd)
258 {
259    struct drm_amdgpu_info_device info;
260    if (amdgpu_info_dev_info(fd, &info))
261       return;
262 
263 #define READ_REG(fd, reg, cnt, instance, rec)                                                      \
264    do {                                                                                            \
265       if (rec.count + cnt > ARRAY_SIZE(rec.vals))                                                  \
266          return;                                                                                   \
267       if (amdgpu_info_read_mmr_reg(fd, reg, cnt, instance, rec.vals + rec.count))                  \
268          return;                                                                                   \
269       for (int i = 0; i < cnt; i++) {                                                              \
270          rec.regs[rec.count + i] = reg + i;                                                        \
271          rec.instances[rec.count + i] = instance;                                                  \
272       }                                                                                            \
273       rec.count += cnt;                                                                            \
274    } while (0)
275 
276    struct {
277       uint32_t regs[256];
278       uint32_t instances[256];
279       uint32_t vals[256];
280       uint32_t count;
281    } rec = { 0 };
282 
283    /* GB_ADDR_CONFIG */
284    READ_REG(fd, 0x263e, 1, 0xffffffff, rec);
285 
286    if (info.family < AMDGPU_FAMILY_AI) {
287       for (int i = 0; i < info.num_shader_engines; i++) {
288          const uint32_t instance =
289             (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
290             (AMDGPU_INFO_MMR_SH_INDEX_MASK << AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
291          /* CC_RB_BACKEND_DISABLE */
292          READ_REG(fd, 0x263d, 1, instance, rec);
293          /* PA_SC_RASTER_CONFIG */
294          READ_REG(fd, 0xa0d4, 1, instance, rec);
295          /* PA_SC_RASTER_CONFIG_1 */
296          if (info.family >= AMDGPU_FAMILY_CI)
297             READ_REG(fd, 0xa0d5, 1, instance, rec);
298       }
299 
300       /* MC_ARB_RAMCFG */
301       READ_REG(fd, 0x9d8, 1, 0xffffffff, rec);
302       /* GB_TILE_MODE0 */
303       READ_REG(fd, 0x2644, 32, 0xffffffff, rec);
304       /* GB_MACROTILE_MODE0 */
305       if (info.family >= AMDGPU_FAMILY_CI)
306          READ_REG(fd, 0x2664, 16, 0xffffffff, rec);
307    }
308 
309 #undef READ_REG
310 
311    printf(".mmr_regs = {\n");
312    for (int i = 0; i < rec.count; i++)
313       printf("   0x%04x, 0x%08x, 0x%08x,\n", rec.regs[i], rec.instances[i], rec.vals[i]);
314    printf("},\n");
315    printf(".mmr_reg_count = %d,\n", rec.count);
316 }
317 
318 static void
amdgpu_dump_fw_versions(int fd)319 amdgpu_dump_fw_versions(int fd)
320 {
321    static const struct {
322       const char *name;
323       uint32_t type;
324    } fw_vers[] = {
325       {
326          .name = "gfx_me",
327          .type = AMDGPU_INFO_FW_GFX_ME,
328       },
329       {
330          .name = "gfx_pfp",
331          .type = AMDGPU_INFO_FW_GFX_PFP,
332       },
333       {
334          .name = "gfx_mec",
335          .type = AMDGPU_INFO_FW_GFX_MEC,
336       },
337    };
338 
339    for (int i = 0; i < ARRAY_SIZE(fw_vers); i++) {
340       struct drm_amdgpu_info_firmware info;
341       if (amdgpu_info_fw_version(fd, fw_vers[i].type, &info))
342          continue;
343 
344       printf(".fw_%s = {\n", fw_vers[i].name);
345       printf("   .ver = %u,\n", info.ver);
346       printf("   .feature = %u,\n", info.feature);
347       printf("},\n");
348    }
349 }
350 
351 static void
amdgpu_dump_hw_ips(int fd)352 amdgpu_dump_hw_ips(int fd)
353 {
354    static const struct {
355       const char *name;
356       uint32_t type;
357    } hw_ips[] = {
358       {
359          .name = "gfx",
360          .type = AMDGPU_HW_IP_GFX,
361       },
362       {
363          .name = "compute",
364          .type = AMDGPU_HW_IP_COMPUTE,
365       },
366    };
367 
368    for (int i = 0; i < ARRAY_SIZE(hw_ips); i++) {
369       struct drm_amdgpu_info_hw_ip info;
370       if (amdgpu_info_hw_ip_info(fd, hw_ips[i].type, &info))
371          continue;
372 
373       printf(".hw_ip_%s = {\n", hw_ips[i].name);
374       printf("   .hw_ip_version_major = %u,\n", info.hw_ip_version_major);
375       printf("   .hw_ip_version_minor = %u,\n", info.hw_ip_version_minor);
376       printf("   .capabilities_flags = UINT64_C(%"PRIu64"),\n", (uint64_t)info.capabilities_flags);
377       printf("   .ib_start_alignment = %u,\n", info.ib_start_alignment);
378       printf("   .ib_size_alignment = %u,\n", info.ib_size_alignment);
379       printf("   .available_rings = 0x%x,\n", info.available_rings);
380       printf("   .ip_discovery_version = 0x%04x,\n", info.ip_discovery_version);
381       printf("},\n");
382    }
383 }
384 
385 static void
amdgpu_dump_version(int fd)386 amdgpu_dump_version(int fd)
387 {
388    const drmVersionPtr ver = drmGetVersion(fd);
389    if (!ver)
390       return;
391 
392    printf(".drm = {\n");
393    printf("   .version_major = %d,\n", ver->version_major);
394    printf("   .version_minor = %d,\n", ver->version_minor);
395    printf("   .version_patchlevel = %d,\n", ver->version_patchlevel);
396    printf("   .name = \"%s\",\n", ver->name);
397    printf("},\n");
398 
399    drmFreeVersion(ver);
400 }
401 
402 static void
amdgpu_dump_pci(drmDevicePtr dev)403 amdgpu_dump_pci(drmDevicePtr dev)
404 {
405    printf(".pci = {\n");
406    printf("   .vendor_id = 0x%04x,\n", dev->deviceinfo.pci->vendor_id);
407    printf("   .device_id = 0x%04x,\n", dev->deviceinfo.pci->device_id);
408    printf("   .subvendor_id = 0x%04x,\n", dev->deviceinfo.pci->subvendor_id);
409    printf("   .subdevice_id = 0x%04x,\n", dev->deviceinfo.pci->subdevice_id);
410    printf("   .revision_id = 0x%02x,\n", dev->deviceinfo.pci->revision_id);
411    printf("},\n");
412 }
413 
414 static void
amdgpu_dump(drmDevicePtr dev)415 amdgpu_dump(drmDevicePtr dev)
416 {
417    if (!(dev->available_nodes & (1 << DRM_NODE_RENDER)))
418       return;
419    if (dev->bustype != DRM_BUS_PCI)
420       return;
421    if (dev->deviceinfo.pci->vendor_id != 0x1002)
422       return;
423 
424    int fd = open(dev->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC);
425    if (fd < 0)
426       return;
427 
428    amdgpu_dump_pci(dev);
429    amdgpu_dump_version(fd);
430    amdgpu_dump_hw_ips(fd);
431    amdgpu_dump_fw_versions(fd);
432    amdgpu_dump_mmr_regs(fd);
433    amdgpu_dump_dev_info(fd);
434    amdgpu_dump_memory(fd);
435 
436    close(fd);
437 }
438 
439 int
main()440 main()
441 {
442    drmDevicePtr devs[8];
443    const int count = drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devs, ARRAY_SIZE(devs));
444 
445    for (int i = 0; i < count; i++)
446       amdgpu_dump(devs[i]);
447 
448    drmFreeDevices(devs, count);
449 
450    return 0;
451 }
452