amd/drm-shim: add amdgpu drm-shim
authorChia-I Wu <olvaffe@gmail.com>
Mon, 13 Mar 2023 21:35:55 +0000 (14:35 -0700)
committerMarge Bot <emma+marge@anholt.net>
Thu, 11 May 2023 00:58:02 +0000 (00:58 +0000)
This is enough to run offscreen apps such as vulkaninfo or deqp-vk.

v2: remove unnecessary idep_amdgfxregs_h dependency

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21892>

src/amd/drm-shim/README.md
src/amd/drm-shim/amdgpu_dump_states.c [new file with mode: 0644]
src/amd/drm-shim/amdgpu_noop_drm_shim.c [new file with mode: 0644]
src/amd/drm-shim/meson.build
src/drm-shim/device.c

index 966e249..e6c0cb5 100644 (file)
@@ -8,3 +8,23 @@ LD_PRELOAD=$prefix/lib/libradeon_noop_drm_shim.so`. (or r600 for r600-class HW)
 
 By default, rv515 is exposed.  The chip can be selected an environment
 variable like `RADEON_GPU_ID=CAYMAN` or `RADEON_GPU_ID=0x6740`.
+
+### amdgpu_noop backend
+
+This implements the minimum of the amdgpu kernel driver.  The submit ioctl is
+stubbed out to not execute anything.
+
+Export `LD_PRELOAD=$prefix/lib/libamdgpu_noop_drm_shim.so`.
+
+To specify the device to expose, set the environment variable `AMDGPU_GPU_ID`
+to
+
+ - `renoir` to expose a `CHIP_RENOIR` device
+ - `raven` to expose a `CHIP_RAVEN` device
+ - `stoney` to expose a `CHIP_STONEY` device
+
+By default, the `CHIP_RENOIR` device is exposed.
+
+To add a new device, `amdgpu_noop_drm_shim.c` needs to be modified.
+`amdgpu_dump_states` can be used to dump the relevant states from a real
+device.
diff --git a/src/amd/drm-shim/amdgpu_dump_states.c b/src/amd/drm-shim/amdgpu_dump_states.c
new file mode 100644 (file)
index 0000000..0d999d5
--- /dev/null
@@ -0,0 +1,444 @@
+/*
+ * Copyright 2023 Google LLC
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <xf86drm.h>
+
+#include "drm-uapi/amdgpu_drm.h"
+#include "util/macros.h"
+
+static int
+amdgpu_info_hw_ip_info(int fd, uint32_t type, struct drm_amdgpu_info_hw_ip *info)
+{
+   struct drm_amdgpu_info arg = {
+      .return_pointer = (uint64_t)info,
+      .return_size = sizeof(*info),
+      .query = AMDGPU_INFO_HW_IP_INFO,
+      .query_hw_ip = {
+         .type = type,
+      },
+   };
+
+   memset(info, 0, sizeof(*info));
+
+   return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
+}
+
+static int
+amdgpu_info_fw_version(int fd, uint32_t type, struct drm_amdgpu_info_firmware *info)
+{
+   struct drm_amdgpu_info arg = {
+      .return_pointer = (uint64_t)info,
+      .return_size = sizeof(*info),
+      .query = AMDGPU_INFO_FW_VERSION,
+      .query_fw = {
+         .fw_type = type,
+      },
+   };
+
+   memset(info, 0, sizeof(*info));
+
+   return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
+}
+
+static int
+amdgpu_info_read_mmr_reg(int fd, uint32_t reg, uint32_t count, uint32_t instance, uint32_t *vals)
+{
+   struct drm_amdgpu_info arg = {
+      .return_pointer = (uint64_t)vals,
+      .return_size = sizeof(*vals) * count,
+      .query = AMDGPU_INFO_READ_MMR_REG,
+      .read_mmr_reg = {
+         .dword_offset = reg,
+         .count = count,
+         .instance = instance,
+      },
+   };
+
+   memset(vals, 0, sizeof(*vals) * count);
+
+   return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
+}
+
+static int
+amdgpu_info_dev_info(int fd, struct drm_amdgpu_info_device *info)
+{
+   struct drm_amdgpu_info arg = {
+      .return_pointer = (uint64_t)info,
+      .return_size = sizeof(*info),
+      .query = AMDGPU_INFO_DEV_INFO,
+   };
+
+   memset(info, 0, sizeof(*info));
+
+   return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
+}
+
+static int
+amdgpu_info_memory(int fd, struct drm_amdgpu_memory_info *info)
+{
+   struct drm_amdgpu_info arg = {
+      .return_pointer = (uint64_t)info,
+      .return_size = sizeof(*info),
+      .query = AMDGPU_INFO_MEMORY,
+   };
+
+   memset(info, 0, sizeof(*info));
+
+   return drmIoctl(fd, DRM_IOCTL_AMDGPU_INFO, &arg);
+}
+
+static void
+amdgpu_dump_memory(int fd)
+{
+   struct drm_amdgpu_memory_info info;
+   if (amdgpu_info_memory(fd, &info))
+      return;
+
+   printf(".mem = {\n");
+   printf("   .vram = {\n");
+   printf("      .total_heap_size = %llu,\n", info.vram.total_heap_size);
+   printf("      .usable_heap_size = %llu,\n", info.vram.usable_heap_size);
+   printf("      .heap_usage = %llu,\n", info.vram.heap_usage);
+   printf("      .max_allocation = %llu,\n", info.vram.max_allocation);
+   printf("   },\n");
+   printf("   .cpu_accessible_vram = {\n");
+   printf("      .total_heap_size = %llu,\n", info.cpu_accessible_vram.total_heap_size);
+   printf("      .usable_heap_size = %llu,\n", info.cpu_accessible_vram.usable_heap_size);
+   printf("      .heap_usage = %llu,\n", info.cpu_accessible_vram.heap_usage);
+   printf("      .max_allocation = %llu,\n", info.cpu_accessible_vram.max_allocation);
+   printf("   },\n");
+   printf("   .gtt = {\n");
+   printf("      .total_heap_size = %llu,\n", info.gtt.total_heap_size);
+   printf("      .usable_heap_size = %llu,\n", info.gtt.usable_heap_size);
+   printf("      .heap_usage = %llu,\n", info.gtt.heap_usage);
+   printf("      .max_allocation = %llu,\n", info.gtt.max_allocation);
+   printf("   },\n");
+   printf("},\n");
+}
+
+static void
+amdgpu_dump_dev_info(int fd)
+{
+   static const struct {
+      const char *name;
+      uint32_t family;
+   } families[] = {
+#define FAMILY(x) { "AMDGPU_FAMILY_" #x, AMDGPU_FAMILY_##x }
+      /* clang-format off */
+      FAMILY(SI),
+      FAMILY(CI),
+      FAMILY(KV),
+      FAMILY(VI),
+      FAMILY(CZ),
+      FAMILY(AI),
+      FAMILY(RV),
+      FAMILY(NV),
+      FAMILY(VGH),
+      FAMILY(GC_11_0_0),
+      FAMILY(YC),
+      FAMILY(GC_11_0_1),
+      FAMILY(GC_10_3_6),
+      FAMILY(GC_10_3_7),
+   /* clang-format on */
+#undef FAMILY
+   };
+
+   struct drm_amdgpu_info_device info;
+   if (amdgpu_info_dev_info(fd, &info))
+      return;
+
+   const char *family_name = NULL;
+   for (int i = 0; i < ARRAY_SIZE(families); i++) {
+      if (families[i].family == info.family) {
+         family_name = families[i].name;
+         break;
+      }
+   }
+   if (!family_name)
+      return;
+
+   printf(".dev = {\n");
+   printf("   .device_id = 0x%04x,\n", info.device_id);
+   printf("   .chip_rev = 0x%02x,\n", info.chip_rev);
+   printf("   .external_rev = 0x%02x,\n", info.external_rev);
+   printf("   .pci_rev = 0x%02x,\n", info.pci_rev);
+
+   printf("   .family = %s,\n", family_name);
+
+   printf("   .num_shader_engines = %u,\n", info.num_shader_engines);
+   printf("   .num_shader_arrays_per_engine = %u,\n", info.num_shader_arrays_per_engine);
+   printf("   .gpu_counter_freq = %u,\n", info.gpu_counter_freq);
+   printf("   .max_engine_clock = %llullu,\n", info.max_engine_clock);
+   printf("   .max_memory_clock = %llullu,\n", info.max_memory_clock);
+   printf("   .cu_active_number = %u,\n", info.cu_active_number);
+   printf("   .cu_ao_mask = 0x%x,\n", info.cu_ao_mask);
+
+   printf("   .cu_bitmap = {\n");
+   for (int i = 0; i < ARRAY_SIZE(info.cu_bitmap); i++) {
+      printf("      {");
+      for (int j = 0; j < ARRAY_SIZE(info.cu_bitmap[i]); j++)
+         printf(" 0x%x,", info.cu_bitmap[i][j]);
+      printf(" },\n");
+   }
+   printf("   },\n");
+
+   printf("   .enabled_rb_pipes_mask = 0x%x,\n", info.enabled_rb_pipes_mask);
+   printf("   .num_rb_pipes = %u,\n", info.num_rb_pipes);
+   printf("   .num_hw_gfx_contexts = %u,\n", info.num_hw_gfx_contexts);
+   printf("   .pcie_gen = %u,\n", info.pcie_gen);
+   printf("   .ids_flags = 0x%llxllu,\n", info.ids_flags);
+   printf("   .virtual_address_offset = 0x%llxllu,\n", info.virtual_address_offset);
+   printf("   .virtual_address_max = 0x%llxllu,\n", info.virtual_address_max);
+   printf("   .virtual_address_alignment = %u,\n", info.virtual_address_alignment);
+   printf("   .pte_fragment_size = %u,\n", info.pte_fragment_size);
+   printf("   .gart_page_size = %u,\n", info.gart_page_size);
+   printf("   .ce_ram_size = %u,\n", info.ce_ram_size);
+   printf("   .vram_type = %u,\n", info.vram_type);
+   printf("   .vram_bit_width = %u,\n", info.vram_bit_width);
+   printf("   .vce_harvest_config = %u,\n", info.vce_harvest_config);
+   printf("   .gc_double_offchip_lds_buf = %u,\n", info.gc_double_offchip_lds_buf);
+   printf("   .prim_buf_gpu_addr = %llullu,\n", info.prim_buf_gpu_addr);
+   printf("   .pos_buf_gpu_addr = %llullu,\n", info.pos_buf_gpu_addr);
+   printf("   .cntl_sb_buf_gpu_addr = %llullu,\n", info.cntl_sb_buf_gpu_addr);
+   printf("   .param_buf_gpu_addr = %llullu,\n", info.param_buf_gpu_addr);
+   printf("   .prim_buf_size = %u,\n", info.prim_buf_size);
+   printf("   .pos_buf_size = %u,\n", info.pos_buf_size);
+   printf("   .cntl_sb_buf_size = %u,\n", info.cntl_sb_buf_size);
+   printf("   .param_buf_size = %u,\n", info.param_buf_size);
+   printf("   .wave_front_size = %u,\n", info.wave_front_size);
+   printf("   .num_shader_visible_vgprs = %u,\n", info.num_shader_visible_vgprs);
+   printf("   .num_cu_per_sh = %u,\n", info.num_cu_per_sh);
+   printf("   .num_tcc_blocks = %u,\n", info.num_tcc_blocks);
+   printf("   .gs_vgt_table_depth = %u,\n", info.gs_vgt_table_depth);
+   printf("   .gs_prim_buffer_depth = %u,\n", info.gs_prim_buffer_depth);
+   printf("   .max_gs_waves_per_vgt = %u,\n", info.max_gs_waves_per_vgt);
+   printf("   .pcie_num_lanes = %u,\n", info.pcie_num_lanes);
+
+   printf("   .cu_ao_bitmap = {\n");
+   for (int i = 0; i < ARRAY_SIZE(info.cu_ao_bitmap); i++) {
+      printf("      {");
+      for (int j = 0; j < ARRAY_SIZE(info.cu_ao_bitmap[i]); j++)
+         printf(" 0x%x,", info.cu_ao_bitmap[i][j]);
+      printf(" },\n");
+   }
+   printf("   },\n");
+
+   printf("   .high_va_offset = 0x%llxllu,\n", info.high_va_offset);
+   printf("   .high_va_max = 0x%llxllu,\n", info.high_va_max);
+   printf("   .pa_sc_tile_steering_override = %u,\n", info.pa_sc_tile_steering_override);
+   printf("   .tcc_disabled_mask = %llullu,\n", info.tcc_disabled_mask);
+   printf("   .min_engine_clock = %llullu,\n", info.min_engine_clock);
+   printf("   .min_memory_clock = %llullu,\n", info.min_memory_clock);
+   printf("   .tcp_cache_size = %u,\n", info.tcp_cache_size);
+   printf("   .num_sqc_per_wgp = %u,\n", info.num_sqc_per_wgp);
+   printf("   .sqc_data_cache_size = %u,\n", info.sqc_data_cache_size);
+   printf("   .sqc_inst_cache_size = %u,\n", info.sqc_inst_cache_size);
+   printf("   .gl1c_cache_size = %u,\n", info.gl1c_cache_size);
+   printf("   .gl2c_cache_size = %u,\n", info.gl2c_cache_size);
+   printf("   .mall_size = %llullu,\n", info.mall_size);
+   printf("   .enabled_rb_pipes_mask_hi = %u,\n", info.enabled_rb_pipes_mask_hi);
+   printf("},\n");
+}
+
+static void
+amdgpu_dump_mmr_regs(int fd)
+{
+   struct drm_amdgpu_info_device info;
+   if (amdgpu_info_dev_info(fd, &info))
+      return;
+
+#define READ_REG(fd, reg, cnt, instance, rec)                                                      \
+   do {                                                                                            \
+      if (rec.count + cnt > ARRAY_SIZE(rec.vals))                                                  \
+         return;                                                                                   \
+      if (amdgpu_info_read_mmr_reg(fd, reg, cnt, instance, rec.vals + rec.count))                  \
+         return;                                                                                   \
+      for (int i = 0; i < cnt; i++) {                                                              \
+         rec.regs[rec.count + i] = reg + i;                                                        \
+         rec.instances[rec.count + i] = instance;                                                  \
+      }                                                                                            \
+      rec.count += cnt;                                                                            \
+   } while (0)
+
+   struct {
+      uint32_t regs[256];
+      uint32_t instances[256];
+      uint32_t vals[256];
+      uint32_t count;
+   } rec = { 0 };
+
+   /* GB_ADDR_CONFIG */
+   READ_REG(fd, 0x263e, 1, 0xffffffff, rec);
+
+   if (info.family < AMDGPU_FAMILY_AI) {
+      for (int i = 0; i < info.num_shader_engines; i++) {
+         const uint32_t instance =
+            (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
+            (AMDGPU_INFO_MMR_SH_INDEX_MASK << AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
+         /* CC_RB_BACKEND_DISABLE */
+         READ_REG(fd, 0x263d, 1, instance, rec);
+         /* PA_SC_RASTER_CONFIG */
+         READ_REG(fd, 0xa0d4, 1, instance, rec);
+         /* PA_SC_RASTER_CONFIG_1 */
+         if (info.family >= AMDGPU_FAMILY_CI)
+            READ_REG(fd, 0xa0d5, 1, instance, rec);
+      }
+
+      /* MC_ARB_RAMCFG */
+      READ_REG(fd, 0x9d8, 1, 0xffffffff, rec);
+      /* GB_TILE_MODE0 */
+      READ_REG(fd, 0x2644, 32, 0xffffffff, rec);
+      /* GB_MACROTILE_MODE0 */
+      if (info.family >= AMDGPU_FAMILY_CI)
+         READ_REG(fd, 0x2664, 16, 0xffffffff, rec);
+   }
+
+#undef READ_REG
+
+   printf(".mmr_regs = {\n");
+   for (int i = 0; i < rec.count; i++)
+      printf("   0x%04x, 0x%08x, 0x%08x,\n", rec.regs[i], rec.instances[i], rec.vals[i]);
+   printf("},\n");
+   printf(".mmr_reg_count = %d,\n", rec.count);
+}
+
+static void
+amdgpu_dump_fw_versions(int fd)
+{
+   static const struct {
+      const char *name;
+      uint32_t type;
+   } fw_vers[] = {
+      {
+         .name = "gfx_me",
+         .type = AMDGPU_INFO_FW_GFX_ME,
+      },
+      {
+         .name = "gfx_pfp",
+         .type = AMDGPU_INFO_FW_GFX_PFP,
+      },
+      {
+         .name = "gfx_mec",
+         .type = AMDGPU_INFO_FW_GFX_MEC,
+      },
+   };
+
+   for (int i = 0; i < ARRAY_SIZE(fw_vers); i++) {
+      struct drm_amdgpu_info_firmware info;
+      if (amdgpu_info_fw_version(fd, fw_vers[i].type, &info))
+         continue;
+
+      printf(".fw_%s = {\n", fw_vers[i].name);
+      printf("   .ver = %u,\n", info.ver);
+      printf("   .feature = %u,\n", info.feature);
+      printf("},\n");
+   }
+}
+
+static void
+amdgpu_dump_hw_ips(int fd)
+{
+   static const struct {
+      const char *name;
+      uint32_t type;
+   } hw_ips[] = {
+      {
+         .name = "gfx",
+         .type = AMDGPU_HW_IP_GFX,
+      },
+      {
+         .name = "compute",
+         .type = AMDGPU_HW_IP_COMPUTE,
+      },
+   };
+
+   for (int i = 0; i < ARRAY_SIZE(hw_ips); i++) {
+      struct drm_amdgpu_info_hw_ip info;
+      if (amdgpu_info_hw_ip_info(fd, hw_ips[i].type, &info))
+         continue;
+
+      printf(".hw_ip_%s = {\n", hw_ips[i].name);
+      printf("   .hw_ip_version_major = %u,\n", info.hw_ip_version_major);
+      printf("   .hw_ip_version_minor = %u,\n", info.hw_ip_version_minor);
+      printf("   .capabilities_flags = %llullu,\n", info.capabilities_flags);
+      printf("   .ib_start_alignment = %u,\n", info.ib_start_alignment);
+      printf("   .ib_size_alignment = %u,\n", info.ib_size_alignment);
+      printf("   .available_rings = 0x%x,\n", info.available_rings);
+      printf("   .ip_discovery_version = 0x%04x,\n", info.ip_discovery_version);
+      printf("},\n");
+   }
+}
+
+static void
+amdgpu_dump_version(int fd)
+{
+   const drmVersionPtr ver = drmGetVersion(fd);
+   if (!ver)
+      return;
+
+   printf(".drm = {\n");
+   printf("   .version_major = %d,\n", ver->version_major);
+   printf("   .version_minor = %d,\n", ver->version_minor);
+   printf("   .version_patchlevel = %d,\n", ver->version_patchlevel);
+   printf("   .name = \"%s\",\n", ver->name);
+   printf("},\n");
+
+   drmFreeVersion(ver);
+}
+
+static void
+amdgpu_dump_pci(drmDevicePtr dev)
+{
+   printf(".pci = {\n");
+   printf("   .vendor_id = 0x%04x,\n", dev->deviceinfo.pci->vendor_id);
+   printf("   .device_id = 0x%04x,\n", dev->deviceinfo.pci->device_id);
+   printf("   .subvendor_id = 0x%04x,\n", dev->deviceinfo.pci->subvendor_id);
+   printf("   .subdevice_id = 0x%04x,\n", dev->deviceinfo.pci->subdevice_id);
+   printf("   .revision_id = 0x%02x,\n", dev->deviceinfo.pci->revision_id);
+   printf("},\n");
+}
+
+static void
+amdgpu_dump(drmDevicePtr dev)
+{
+   if (!(dev->available_nodes & (1 << DRM_NODE_RENDER)))
+      return;
+   if (dev->bustype != DRM_BUS_PCI)
+      return;
+   if (dev->deviceinfo.pci->vendor_id != 0x1002)
+      return;
+
+   int fd = open(dev->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC);
+   if (fd < 0)
+      return;
+
+   amdgpu_dump_pci(dev);
+   amdgpu_dump_version(fd);
+   amdgpu_dump_hw_ips(fd);
+   amdgpu_dump_fw_versions(fd);
+   amdgpu_dump_mmr_regs(fd);
+   amdgpu_dump_dev_info(fd);
+   amdgpu_dump_memory(fd);
+
+   close(fd);
+}
+
+int
+main()
+{
+   drmDevicePtr devs[8];
+   const int count = drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devs, ARRAY_SIZE(devs));
+
+   for (int i = 0; i < count; i++)
+      amdgpu_dump(devs[i]);
+
+   drmFreeDevices(devs, count);
+
+   return 0;
+}
diff --git a/src/amd/drm-shim/amdgpu_noop_drm_shim.c b/src/amd/drm-shim/amdgpu_noop_drm_shim.c
new file mode 100644 (file)
index 0000000..11fcedf
--- /dev/null
@@ -0,0 +1,569 @@
+/*
+ * Copyright 2023 Google LLC
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "common/amd_family.h"
+#include "drm-shim/drm_shim.h"
+#include "drm-uapi/amdgpu_drm.h"
+#include "util/log.h"
+
+struct amdgpu_device {
+   const char *name;
+   enum radeon_family radeon_family;
+
+   struct drm_amdgpu_info_hw_ip hw_ip_gfx;
+   struct drm_amdgpu_info_hw_ip hw_ip_compute;
+
+   struct drm_amdgpu_info_firmware fw_gfx_me;
+   struct drm_amdgpu_info_firmware fw_gfx_pfp;
+   struct drm_amdgpu_info_firmware fw_gfx_mec;
+
+   uint32_t mmr_regs[256 * 3];
+   uint32_t mmr_reg_count;
+
+   struct drm_amdgpu_info_device dev;
+   struct drm_amdgpu_memory_info mem;
+};
+
+static const struct amdgpu_device *amdgpu_dev;
+
+bool drm_shim_driver_prefers_first_render_node = true;
+
+static int
+amdgpu_ioctl_noop(int fd, unsigned long request, void *arg)
+{
+   return 0;
+}
+
+static int
+amdgpu_ioctl_gem_create(int fd, unsigned long request, void *_arg)
+{
+   union drm_amdgpu_gem_create *arg = _arg;
+   struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
+   struct shim_bo *bo = calloc(1, sizeof(*bo));
+   int ret;
+
+   ret = drm_shim_bo_init(bo, arg->in.bo_size);
+   if (ret) {
+      free(bo);
+      return ret;
+   }
+
+   arg->out.handle = drm_shim_bo_get_handle(shim_fd, bo);
+
+   drm_shim_bo_put(bo);
+
+   return 0;
+}
+
+static int
+amdgpu_ioctl_gem_mmap(int fd, unsigned long request, void *_arg)
+{
+   union drm_amdgpu_gem_mmap *arg = _arg;
+   struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
+   struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, arg->in.handle);
+
+   arg->out.addr_ptr = drm_shim_bo_get_mmap_offset(shim_fd, bo);
+
+   return 0;
+}
+
+static void
+amdgpu_info_hw_ip_info(uint32_t type, struct drm_amdgpu_info_hw_ip *out)
+{
+   switch (type) {
+   case AMDGPU_HW_IP_GFX:
+      *out = amdgpu_dev->hw_ip_gfx;
+      break;
+   case AMDGPU_HW_IP_COMPUTE:
+      *out = amdgpu_dev->hw_ip_compute;
+      break;
+   default:
+      break;
+   }
+}
+
+static void
+amdgpu_info_fw_version(uint32_t type, struct drm_amdgpu_info_firmware *out)
+{
+   switch (type) {
+   case AMDGPU_INFO_FW_GFX_ME:
+      *out = amdgpu_dev->fw_gfx_me;
+      break;
+   case AMDGPU_INFO_FW_GFX_PFP:
+      *out = amdgpu_dev->fw_gfx_pfp;
+      break;
+   case AMDGPU_INFO_FW_GFX_MEC:
+      *out = amdgpu_dev->fw_gfx_mec;
+      break;
+   default:
+      break;
+   }
+}
+
+static void
+amdgpu_info_read_mmr_reg(uint32_t reg, uint32_t count, uint32_t instance, uint32_t *vals)
+{
+   for (int i = 0; i < count; i++) {
+      /* linear search */
+      bool found = false;
+      uint32_t val = 0;
+      for (int j = 0; j < amdgpu_dev->mmr_reg_count; j++) {
+         const uint32_t *triple = &amdgpu_dev->mmr_regs[j * 3];
+         if (triple[0] == reg + i && triple[1] == instance) {
+            val = triple[2];
+            found = true;
+            break;
+         }
+      }
+
+      if (!found)
+         mesa_logw("reg 0x%04x is unknown", reg + i);
+
+      vals[i] = val;
+   }
+}
+
+static void
+amdgpu_info_dev_info(struct drm_amdgpu_info_device *out)
+{
+   *out = amdgpu_dev->dev;
+}
+
+static void
+amdgpu_info_memory(struct drm_amdgpu_memory_info *out)
+{
+   *out = amdgpu_dev->mem;
+
+   /* override all but total_heap_size */
+   out->vram.usable_heap_size = out->vram.total_heap_size;
+   out->vram.heap_usage = 0;
+   out->vram.max_allocation = out->vram.total_heap_size * 3 / 4;
+   out->cpu_accessible_vram.usable_heap_size = out->cpu_accessible_vram.total_heap_size;
+   out->cpu_accessible_vram.heap_usage = 0;
+   out->cpu_accessible_vram.max_allocation = out->cpu_accessible_vram.total_heap_size * 3 / 4;
+   out->gtt.usable_heap_size = out->gtt.total_heap_size;
+   out->gtt.heap_usage = 0;
+   out->gtt.max_allocation = out->gtt.total_heap_size * 3 / 4;
+}
+
+static void
+amdgpu_info_video_caps(uint32_t type, struct drm_amdgpu_info_video_caps *out)
+{
+   /* nop */
+}
+
+static int
+amdgpu_ioctl_info(int fd, unsigned long request, void *arg)
+{
+   const struct drm_amdgpu_info *info = arg;
+   union {
+      void *ptr;
+      uint32_t *ui32;
+   } out = { .ptr = (void *)info->return_pointer };
+
+   switch (info->query) {
+   case AMDGPU_INFO_ACCEL_WORKING:
+      *out.ui32 = 1;
+      break;
+   case AMDGPU_INFO_HW_IP_INFO:
+      amdgpu_info_hw_ip_info(info->query_hw_ip.type, out.ptr);
+      break;
+   case AMDGPU_INFO_FW_VERSION:
+      amdgpu_info_fw_version(info->query_fw.fw_type, out.ptr);
+      break;
+   case AMDGPU_INFO_READ_MMR_REG:
+      amdgpu_info_read_mmr_reg(info->read_mmr_reg.dword_offset, info->read_mmr_reg.count,
+                               info->read_mmr_reg.instance, out.ptr);
+      break;
+   case AMDGPU_INFO_DEV_INFO:
+      amdgpu_info_dev_info(out.ptr);
+      break;
+   case AMDGPU_INFO_MEMORY:
+      amdgpu_info_memory(out.ptr);
+      break;
+   case AMDGPU_INFO_VIDEO_CAPS:
+      amdgpu_info_video_caps(info->video_cap.type, out.ptr);
+      break;
+   default:
+      return -EINVAL;
+   }
+
+   return 0;
+}
+
+static ioctl_fn_t amdgpu_ioctls[] = {
+   [DRM_AMDGPU_GEM_CREATE] = amdgpu_ioctl_gem_create,
+   [DRM_AMDGPU_GEM_MMAP] = amdgpu_ioctl_gem_mmap,
+   [DRM_AMDGPU_CTX] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_BO_LIST] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_CS] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_INFO] = amdgpu_ioctl_info,
+   [DRM_AMDGPU_GEM_METADATA] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_GEM_WAIT_IDLE] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_GEM_VA] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_WAIT_CS] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_GEM_OP] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_GEM_USERPTR] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_WAIT_FENCES] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_VM] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_FENCE_TO_HANDLE] = amdgpu_ioctl_noop,
+   [DRM_AMDGPU_SCHED] = amdgpu_ioctl_noop,
+};
+
+static const struct amdgpu_device amdgpu_devices[] = {
+   {
+      .name = "renoir",
+      .radeon_family = CHIP_RENOIR,
+      .hw_ip_gfx = {
+         .hw_ip_version_major = 9,
+         .ib_start_alignment = 32,
+         .ib_size_alignment = 32,
+         .available_rings = 0x1,
+         .ip_discovery_version = 0x90300,
+      },
+      .hw_ip_compute = {
+         .hw_ip_version_major = 9,
+         .ib_start_alignment = 32,
+         .ib_size_alignment = 32,
+         .available_rings = 0xf,
+         .ip_discovery_version = 0x90300,
+      },
+      .fw_gfx_me = {
+         .ver = 166,
+         .feature = 53,
+      },
+      .fw_gfx_pfp = {
+         .ver = 194,
+         .feature = 53,
+      },
+      .fw_gfx_mec = {
+         .ver = 464,
+         .feature = 53,
+      },
+      .mmr_regs = {
+         0x263e, 0xffffffff, 0x26010042,
+      },
+      .mmr_reg_count = 1,
+      .dev = {
+         .device_id = 0x15e7,
+         .external_rev = 0xa1,
+         .pci_rev = 0xe9,
+         .family = AMDGPU_FAMILY_RV,
+         .num_shader_engines = 1,
+         .num_shader_arrays_per_engine = 1,
+         .gpu_counter_freq = 100000,
+         .max_engine_clock = 1800000,
+         .max_memory_clock = 1333000,
+         .cu_active_number = 7,
+         .cu_ao_mask = 0xfe,
+         .cu_bitmap[0][0] = 0xfe,
+         .enabled_rb_pipes_mask = 0x3,
+         .num_rb_pipes = 2,
+         .num_hw_gfx_contexts = 8,
+         .ids_flags = 0x5,
+         .virtual_address_offset = 0x200000,
+         .virtual_address_max = 0x800000000000llu,
+         .virtual_address_alignment = 4096,
+         .pte_fragment_size = 2097152,
+         .gart_page_size = 4096,
+         .ce_ram_size = 32768,
+         .vram_type = 11,
+         .vram_bit_width = 128,
+         .gc_double_offchip_lds_buf = 1,
+         .wave_front_size = 64,
+         .num_shader_visible_vgprs = 256,
+         .num_cu_per_sh = 8,
+         .num_tcc_blocks = 4,
+         .gs_vgt_table_depth = 32,
+         .gs_prim_buffer_depth = 1792,
+         .max_gs_waves_per_vgt = 32,
+         .cu_ao_bitmap[0][0] = 0xfe,
+         .high_va_offset = 0xffff800000000000llu,
+         .high_va_max = 0xffffffffffe00000llu,
+      },
+      .mem = {
+         .vram = {
+            .total_heap_size = 64ull << 20,
+         },
+         .cpu_accessible_vram = {
+            .total_heap_size = 64ull << 20,
+         },
+         .gtt = {
+            .total_heap_size = 4096ull << 20,
+         },
+      },
+   },
+   {
+      .name = "raven",
+      .radeon_family = CHIP_RAVEN,
+      .hw_ip_gfx = {
+         .hw_ip_version_major = 9,
+         .ib_start_alignment = 32,
+         .ib_size_alignment = 32,
+         .available_rings = 0x1,
+      },
+      .hw_ip_compute = {
+         .hw_ip_version_major = 9,
+         .ib_start_alignment = 32,
+         .ib_size_alignment = 32,
+         .available_rings = 0xf,
+      },
+      .fw_gfx_me = {
+         .ver = 162,
+         .feature = 47,
+      },
+      .fw_gfx_pfp = {
+         .ver = 185,
+         .feature = 47,
+      },
+      .fw_gfx_mec = {
+         .ver = 427,
+         .feature = 47,
+      },
+      .mmr_regs = {
+         0x263e, 0xffffffff, 0x24000042,
+      },
+      .mmr_reg_count = 1,
+      .dev = {
+         .device_id = 0x15d8,
+         .chip_rev = 0x01,
+         .external_rev = 0x42,
+         .pci_rev = 0xc1,
+         .family = AMDGPU_FAMILY_RV,
+         .num_shader_engines = 1,
+         .num_shader_arrays_per_engine = 1,
+         .gpu_counter_freq = 25000,
+         .max_engine_clock = 1400000,
+         .max_memory_clock = 1200000,
+         .cu_active_number = 10,
+         .cu_ao_mask = 0x3ff,
+         .cu_bitmap[0][0] = 0x3ff,
+         .enabled_rb_pipes_mask = 0x3,
+         .num_rb_pipes = 2,
+         .num_hw_gfx_contexts = 8,
+         .ids_flags = 0x1,
+         .virtual_address_offset = 0x200000,
+         .virtual_address_max = 0x800000000000llu,
+         .virtual_address_alignment = 4096,
+         .pte_fragment_size = 2097152,
+         .gart_page_size = 4096,
+         .ce_ram_size = 32768,
+         .vram_type = 8,
+         .vram_bit_width = 128,
+         .gc_double_offchip_lds_buf = 1,
+         .wave_front_size = 64,
+         .num_shader_visible_vgprs = 256,
+         .num_cu_per_sh = 11,
+         .num_tcc_blocks = 4,
+         .gs_vgt_table_depth = 32,
+         .gs_prim_buffer_depth = 1792,
+         .max_gs_waves_per_vgt = 32,
+         .cu_ao_bitmap[0][0] = 0x3ff,
+         .high_va_offset = 0xffff800000000000llu,
+         .high_va_max = 0xffffffffffe00000llu,
+      },
+      .mem = {
+         .vram = {
+            .total_heap_size = 64ull << 20,
+         },
+         .cpu_accessible_vram = {
+            .total_heap_size = 64ull << 20,
+         },
+         .gtt = {
+            .total_heap_size = 3072ull << 20,
+         },
+      },
+   },
+   {
+      .name = "stoney",
+      .radeon_family = CHIP_STONEY,
+      .hw_ip_gfx = {
+         .hw_ip_version_major = 8,
+         .hw_ip_version_minor = 1,
+         .ib_start_alignment = 32,
+         .ib_size_alignment = 32,
+         .available_rings = 0x1,
+      },
+      .hw_ip_compute = {
+         .hw_ip_version_major = 8,
+         .hw_ip_version_minor = 1,
+         .ib_start_alignment = 32,
+         .ib_size_alignment = 32,
+         .available_rings = 0xf,
+      },
+      .fw_gfx_me = {
+         .ver = 52,
+         .feature = 35,
+      },
+      .fw_gfx_pfp = {
+         .ver = 77,
+         .feature = 35,
+      },
+      .fw_gfx_mec = {
+         .ver = 134,
+         .feature = 35,
+      },
+      .mmr_regs = {
+         0x263e, 0xffffffff, 0x02010001,
+         0x263d, 0x0000ff00, 0x00000000,
+         0xa0d4, 0x0000ff00, 0x00000000,
+         0xa0d5, 0x0000ff00, 0x00000000,
+         0x09d8, 0xffffffff, 0x00007111,
+         0x2644, 0xffffffff, 0x00800010,
+         0x2645, 0xffffffff, 0x00800810,
+         0x2646, 0xffffffff, 0x00801010,
+         0x2647, 0xffffffff, 0x00801810,
+         0x2648, 0xffffffff, 0x00802810,
+         0x2649, 0xffffffff, 0x00802808,
+         0x264a, 0xffffffff, 0x00802814,
+         0x264b, 0xffffffff, 0x00000000,
+         0x264c, 0xffffffff, 0x00000004,
+         0x264d, 0xffffffff, 0x02000008,
+         0x264e, 0xffffffff, 0x02000010,
+         0x264f, 0xffffffff, 0x06000014,
+         0x2650, 0xffffffff, 0x00000000,
+         0x2651, 0xffffffff, 0x02400008,
+         0x2652, 0xffffffff, 0x02400010,
+         0x2653, 0xffffffff, 0x02400030,
+         0x2654, 0xffffffff, 0x06400014,
+         0x2655, 0xffffffff, 0x00000000,
+         0x2656, 0xffffffff, 0x0040000c,
+         0x2657, 0xffffffff, 0x0100000c,
+         0x2658, 0xffffffff, 0x0100001c,
+         0x2659, 0xffffffff, 0x01000034,
+         0x265a, 0xffffffff, 0x01000024,
+         0x265b, 0xffffffff, 0x00000000,
+         0x265c, 0xffffffff, 0x0040001c,
+         0x265d, 0xffffffff, 0x01000020,
+         0x265e, 0xffffffff, 0x01000038,
+         0x265f, 0xffffffff, 0x02c00008,
+         0x2660, 0xffffffff, 0x02c00010,
+         0x2661, 0xffffffff, 0x06c00014,
+         0x2662, 0xffffffff, 0x00000000,
+         0x2663, 0xffffffff, 0x00000000,
+         0x2664, 0xffffffff, 0x000000a8,
+         0x2665, 0xffffffff, 0x000000a4,
+         0x2666, 0xffffffff, 0x00000090,
+         0x2667, 0xffffffff, 0x00000090,
+         0x2668, 0xffffffff, 0x00000090,
+         0x2669, 0xffffffff, 0x00000090,
+         0x266a, 0xffffffff, 0x00000090,
+         0x266b, 0xffffffff, 0x00000000,
+         0x266c, 0xffffffff, 0x000000ee,
+         0x266d, 0xffffffff, 0x000000ea,
+         0x266e, 0xffffffff, 0x000000e9,
+         0x266f, 0xffffffff, 0x000000e5,
+         0x2670, 0xffffffff, 0x000000e4,
+         0x2671, 0xffffffff, 0x000000e0,
+         0x2672, 0xffffffff, 0x00000090,
+         0x2673, 0xffffffff, 0x00000000,
+      },
+      .mmr_reg_count = 53,
+      .dev = {
+         .device_id = 0x98e4,
+         .external_rev = 0x61,
+         .pci_rev = 0xeb,
+         .family = AMDGPU_FAMILY_CZ,
+         .num_shader_engines = 1,
+         .num_shader_arrays_per_engine = 1,
+         .gpu_counter_freq = 48000,
+         .max_engine_clock = 600000,
+         .max_memory_clock = 933000,
+         .cu_active_number = 3,
+         .cu_ao_mask = 0x3,
+         .cu_bitmap[0][0] = 0x7,
+         .enabled_rb_pipes_mask = 0x1,
+         .num_rb_pipes = 1,
+         .num_hw_gfx_contexts = 8,
+         .ids_flags = 0x1,
+         .virtual_address_offset = 0x200000,
+         .virtual_address_max = 0xfffe00000llu,
+         .virtual_address_alignment = 4096,
+         .pte_fragment_size = 2097152,
+         .gart_page_size = 4096,
+         .ce_ram_size = 32768,
+         .vram_bit_width = 64,
+         .vce_harvest_config = 2,
+         .wave_front_size = 64,
+         .num_shader_visible_vgprs = 256,
+         .num_cu_per_sh = 3,
+         .num_tcc_blocks = 2,
+         .max_gs_waves_per_vgt = 16,
+         .cu_ao_bitmap[0][0] = 0x3,
+      },
+      .mem = {
+         .vram = {
+            .total_heap_size = 16ull << 20,
+         },
+         .cpu_accessible_vram = {
+            .total_heap_size = 16ull << 20,
+         },
+         .gtt = {
+            .total_heap_size = 3072ull << 20,
+         },
+      },
+   },
+};
+
+static void
+amdgpu_select_device()
+{
+   const char *gpu_id = getenv("AMDGPU_GPU_ID");
+   if (gpu_id) {
+      for (uint32_t i = 0; i < ARRAY_SIZE(amdgpu_devices); i++) {
+         const struct amdgpu_device *dev = &amdgpu_devices[i];
+         if (!strcasecmp(dev->name, gpu_id)) {
+            amdgpu_dev = &amdgpu_devices[i];
+            break;
+         }
+      }
+   } else {
+      amdgpu_dev = &amdgpu_devices[0];
+   }
+
+   if (!amdgpu_dev) {
+      mesa_loge("Failed to find amdgpu GPU named \"%s\"\n", gpu_id);
+      abort();
+   }
+}
+
+void
+drm_shim_driver_init(void)
+{
+   amdgpu_select_device();
+
+   shim_device.bus_type = DRM_BUS_PCI;
+   shim_device.driver_name = "amdgpu";
+   shim_device.driver_ioctls = amdgpu_ioctls;
+   shim_device.driver_ioctl_count = ARRAY_SIZE(amdgpu_ioctls);
+
+   shim_device.version_major = 3;
+   shim_device.version_minor = 49;
+   shim_device.version_patchlevel = 0;
+
+   /* make drmGetDevices2 and drmProcessPciDevice happy */
+   static const char uevent_content[] =
+      "DRIVER=amdgpu\n"
+      "PCI_CLASS=30000\n"
+      "PCI_ID=1002:15E7\n"
+      "PCI_SUBSYS_ID=1028:1636\n"
+      "PCI_SLOT_NAME=0000:04:00.0\n"
+      "MODALIAS=pci:v00001002d000015E7sv00001002sd00001636bc03sc00i00\n";
+   drm_shim_override_file(uevent_content, "/sys/dev/char/%d:%d/device/uevent", DRM_MAJOR,
+                          render_node_minor);
+   drm_shim_override_file("0xe9\n", "/sys/dev/char/%d:%d/device/revision", DRM_MAJOR,
+                          render_node_minor);
+   drm_shim_override_file("0x1002", "/sys/dev/char/%d:%d/device/vendor", DRM_MAJOR,
+                          render_node_minor);
+   drm_shim_override_file("0x15e7", "/sys/dev/char/%d:%d/device/device", DRM_MAJOR,
+                          render_node_minor);
+   drm_shim_override_file("0x1002", "/sys/dev/char/%d:%d/device/subsystem_vendor", DRM_MAJOR,
+                          render_node_minor);
+   drm_shim_override_file("0x1636", "/sys/dev/char/%d:%d/device/subsystem_device", DRM_MAJOR,
+                          render_node_minor);
+}
index b7be863..3a267c3 100644 (file)
@@ -27,3 +27,21 @@ libradeon_noop_drm_shim = shared_library(
   gnu_symbol_visibility : 'hidden',
   install : true,
 )
+
+libamdgpu_noop_drm_shim = shared_library(
+  'amdgpu_noop_drm_shim',
+  'amdgpu_noop_drm_shim.c',
+  include_directories: [inc_include, inc_src, inc_amd],
+  dependencies: dep_drm_shim,
+  gnu_symbol_visibility : 'hidden',
+  install : true,
+)
+
+amdgpu_dump = executable(
+  'amdgpu_dump_states',
+  'amdgpu_dump_states.c',
+  include_directories: [inc_include, inc_src, inc_amd],
+  gnu_symbol_visibility: 'hidden',
+  dependencies: [dep_libdrm],
+  install: false,
+)
index 6c9c994..ddd58b1 100644 (file)
@@ -281,6 +281,7 @@ ioctl_fn_t core_ioctls[] = {
    [_IOC_NR(DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD)] = drm_shim_ioctl_stub,
    [_IOC_NR(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE)] = drm_shim_ioctl_stub,
    [_IOC_NR(DRM_IOCTL_SYNCOBJ_WAIT)] = drm_shim_ioctl_stub,
+   [_IOC_NR(DRM_IOCTL_SYNCOBJ_TRANSFER)] = drm_shim_ioctl_stub,
 };
 
 /**