From df387306d6bea860e69025f8079892b8429a6ab9 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 13 Mar 2023 14:35:55 -0700 Subject: [PATCH] amd/drm-shim: add amdgpu drm-shim This is enough to run offscreen apps such as vulkaninfo or deqp-vk. v2: remove unnecessary idep_amdgfxregs_h dependency Part-of: --- src/amd/drm-shim/README.md | 20 ++ src/amd/drm-shim/amdgpu_dump_states.c | 444 +++++++++++++++++++++++++ src/amd/drm-shim/amdgpu_noop_drm_shim.c | 569 ++++++++++++++++++++++++++++++++ src/amd/drm-shim/meson.build | 18 + src/drm-shim/device.c | 1 + 5 files changed, 1052 insertions(+) create mode 100644 src/amd/drm-shim/amdgpu_dump_states.c create mode 100644 src/amd/drm-shim/amdgpu_noop_drm_shim.c diff --git a/src/amd/drm-shim/README.md b/src/amd/drm-shim/README.md index 966e249..e6c0cb5 100644 --- a/src/amd/drm-shim/README.md +++ b/src/amd/drm-shim/README.md @@ -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 index 0000000..0d999d5 --- /dev/null +++ b/src/amd/drm-shim/amdgpu_dump_states.c @@ -0,0 +1,444 @@ +/* + * Copyright 2023 Google LLC + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include + +#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 index 0000000..11fcedf --- /dev/null +++ b/src/amd/drm-shim/amdgpu_noop_drm_shim.c @@ -0,0 +1,569 @@ +/* + * Copyright 2023 Google LLC + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#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); +} diff --git a/src/amd/drm-shim/meson.build b/src/amd/drm-shim/meson.build index b7be863..3a267c3 100644 --- a/src/amd/drm-shim/meson.build +++ b/src/amd/drm-shim/meson.build @@ -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, +) diff --git a/src/drm-shim/device.c b/src/drm-shim/device.c index 6c9c994..ddd58b1 100644 --- a/src/drm-shim/device.c +++ b/src/drm-shim/device.c @@ -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, }; /** -- 2.7.4