xref: /aosp_15_r20/external/mesa3d/src/amd/drm-shim/amdgpu_noop_drm_shim.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2023 Google LLC
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include <stdbool.h>
7 #include <stdint.h>
8 #include <string.h>
9 #include "amdgpu_devices.h"
10 #include "common/amd_family.h"
11 #include "drm-shim/drm_shim.h"
12 #include "drm-uapi/amdgpu_drm.h"
13 #include "util/log.h"
14 
15 static const struct amdgpu_device *amdgpu_dev;
16 
17 bool drm_shim_driver_prefers_first_render_node = true;
18 
19 static int
amdgpu_ioctl_noop(int fd,unsigned long request,void * arg)20 amdgpu_ioctl_noop(int fd, unsigned long request, void *arg)
21 {
22    return 0;
23 }
24 
25 static int
amdgpu_ioctl_gem_create(int fd,unsigned long request,void * _arg)26 amdgpu_ioctl_gem_create(int fd, unsigned long request, void *_arg)
27 {
28    union drm_amdgpu_gem_create *arg = _arg;
29    struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
30    struct shim_bo *bo = calloc(1, sizeof(*bo));
31    int ret;
32 
33    ret = drm_shim_bo_init(bo, arg->in.bo_size);
34    if (ret) {
35       free(bo);
36       return ret;
37    }
38 
39    arg->out.handle = drm_shim_bo_get_handle(shim_fd, bo);
40 
41    drm_shim_bo_put(bo);
42 
43    return 0;
44 }
45 
46 static int
amdgpu_ioctl_gem_mmap(int fd,unsigned long request,void * _arg)47 amdgpu_ioctl_gem_mmap(int fd, unsigned long request, void *_arg)
48 {
49    union drm_amdgpu_gem_mmap *arg = _arg;
50    struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
51    struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, arg->in.handle);
52 
53    arg->out.addr_ptr = drm_shim_bo_get_mmap_offset(shim_fd, bo);
54 
55    return 0;
56 }
57 
58 static void
amdgpu_info_hw_ip_info(uint32_t type,struct drm_amdgpu_info_hw_ip * out)59 amdgpu_info_hw_ip_info(uint32_t type, struct drm_amdgpu_info_hw_ip *out)
60 {
61    switch (type) {
62    case AMDGPU_HW_IP_GFX:
63       *out = amdgpu_dev->hw_ip_gfx;
64       break;
65    case AMDGPU_HW_IP_COMPUTE:
66       *out = amdgpu_dev->hw_ip_compute;
67       break;
68    default:
69       break;
70    }
71 }
72 
73 static void
amdgpu_info_fw_version(uint32_t type,struct drm_amdgpu_info_firmware * out)74 amdgpu_info_fw_version(uint32_t type, struct drm_amdgpu_info_firmware *out)
75 {
76    switch (type) {
77    case AMDGPU_INFO_FW_GFX_ME:
78       *out = amdgpu_dev->fw_gfx_me;
79       break;
80    case AMDGPU_INFO_FW_GFX_PFP:
81       *out = amdgpu_dev->fw_gfx_pfp;
82       break;
83    case AMDGPU_INFO_FW_GFX_MEC:
84       *out = amdgpu_dev->fw_gfx_mec;
85       break;
86    default:
87       break;
88    }
89 }
90 
91 static void
amdgpu_info_read_mmr_reg(uint32_t reg,uint32_t count,uint32_t instance,uint32_t * vals)92 amdgpu_info_read_mmr_reg(uint32_t reg, uint32_t count, uint32_t instance, uint32_t *vals)
93 {
94    for (int i = 0; i < count; i++) {
95       /* linear search */
96       bool found = false;
97       uint32_t val = 0;
98       for (int j = 0; j < amdgpu_dev->mmr_reg_count; j++) {
99          const uint32_t *triple = &amdgpu_dev->mmr_regs[j * 3];
100          if (triple[0] == reg + i && triple[1] == instance) {
101             val = triple[2];
102             found = true;
103             break;
104          }
105       }
106 
107       if (!found)
108          mesa_logw("reg 0x%04x is unknown", reg + i);
109 
110       vals[i] = val;
111    }
112 }
113 
114 static void
amdgpu_info_dev_info(struct drm_amdgpu_info_device * out)115 amdgpu_info_dev_info(struct drm_amdgpu_info_device *out)
116 {
117    *out = amdgpu_dev->dev;
118 }
119 
120 static void
amdgpu_info_memory(struct drm_amdgpu_memory_info * out)121 amdgpu_info_memory(struct drm_amdgpu_memory_info *out)
122 {
123    *out = amdgpu_dev->mem;
124 
125    /* override all but total_heap_size */
126    out->vram.usable_heap_size = out->vram.total_heap_size;
127    out->vram.heap_usage = 0;
128    out->vram.max_allocation = out->vram.total_heap_size * 3 / 4;
129    out->cpu_accessible_vram.usable_heap_size = out->cpu_accessible_vram.total_heap_size;
130    out->cpu_accessible_vram.heap_usage = 0;
131    out->cpu_accessible_vram.max_allocation = out->cpu_accessible_vram.total_heap_size * 3 / 4;
132    out->gtt.usable_heap_size = out->gtt.total_heap_size;
133    out->gtt.heap_usage = 0;
134    out->gtt.max_allocation = out->gtt.total_heap_size * 3 / 4;
135 }
136 
137 static void
amdgpu_info_video_caps(uint32_t type,struct drm_amdgpu_info_video_caps * out)138 amdgpu_info_video_caps(uint32_t type, struct drm_amdgpu_info_video_caps *out)
139 {
140    /* nop */
141 }
142 
143 static int
amdgpu_ioctl_info(int fd,unsigned long request,void * arg)144 amdgpu_ioctl_info(int fd, unsigned long request, void *arg)
145 {
146    const struct drm_amdgpu_info *info = arg;
147    union {
148       void *ptr;
149       uint32_t *ui32;
150    } out = { .ptr = (void *)info->return_pointer };
151 
152    switch (info->query) {
153    case AMDGPU_INFO_ACCEL_WORKING:
154       *out.ui32 = 1;
155       break;
156    case AMDGPU_INFO_HW_IP_INFO:
157       amdgpu_info_hw_ip_info(info->query_hw_ip.type, out.ptr);
158       break;
159    case AMDGPU_INFO_FW_VERSION:
160       amdgpu_info_fw_version(info->query_fw.fw_type, out.ptr);
161       break;
162    case AMDGPU_INFO_READ_MMR_REG:
163       amdgpu_info_read_mmr_reg(info->read_mmr_reg.dword_offset, info->read_mmr_reg.count,
164                                info->read_mmr_reg.instance, out.ptr);
165       break;
166    case AMDGPU_INFO_DEV_INFO:
167       amdgpu_info_dev_info(out.ptr);
168       break;
169    case AMDGPU_INFO_MEMORY:
170       amdgpu_info_memory(out.ptr);
171       break;
172    case AMDGPU_INFO_VIDEO_CAPS:
173       amdgpu_info_video_caps(info->video_cap.type, out.ptr);
174       break;
175    default:
176       return -EINVAL;
177    }
178 
179    return 0;
180 }
181 
182 static ioctl_fn_t amdgpu_ioctls[] = {
183    [DRM_AMDGPU_GEM_CREATE] = amdgpu_ioctl_gem_create,
184    [DRM_AMDGPU_GEM_MMAP] = amdgpu_ioctl_gem_mmap,
185    [DRM_AMDGPU_CTX] = amdgpu_ioctl_noop,
186    [DRM_AMDGPU_BO_LIST] = amdgpu_ioctl_noop,
187    [DRM_AMDGPU_CS] = amdgpu_ioctl_noop,
188    [DRM_AMDGPU_INFO] = amdgpu_ioctl_info,
189    [DRM_AMDGPU_GEM_METADATA] = amdgpu_ioctl_noop,
190    [DRM_AMDGPU_GEM_WAIT_IDLE] = amdgpu_ioctl_noop,
191    [DRM_AMDGPU_GEM_VA] = amdgpu_ioctl_noop,
192    [DRM_AMDGPU_WAIT_CS] = amdgpu_ioctl_noop,
193    [DRM_AMDGPU_GEM_OP] = amdgpu_ioctl_noop,
194    [DRM_AMDGPU_GEM_USERPTR] = amdgpu_ioctl_noop,
195    [DRM_AMDGPU_WAIT_FENCES] = amdgpu_ioctl_noop,
196    [DRM_AMDGPU_VM] = amdgpu_ioctl_noop,
197    [DRM_AMDGPU_FENCE_TO_HANDLE] = amdgpu_ioctl_noop,
198    [DRM_AMDGPU_SCHED] = amdgpu_ioctl_noop,
199 };
200 
201 static void
amdgpu_select_device()202 amdgpu_select_device()
203 {
204    const char *gpu_id = getenv("AMDGPU_GPU_ID");
205    if (gpu_id) {
206       for (uint32_t i = 0; i < num_amdgpu_devices; i++) {
207          const struct amdgpu_device *dev = &amdgpu_devices[i];
208          if (!strcasecmp(dev->name, gpu_id)) {
209             amdgpu_dev = &amdgpu_devices[i];
210             break;
211          }
212       }
213    } else {
214       amdgpu_dev = &amdgpu_devices[0];
215    }
216 
217    if (!amdgpu_dev) {
218       mesa_loge("Failed to find amdgpu GPU named \"%s\"\n", gpu_id);
219       abort();
220    }
221 }
222 
223 void
drm_shim_driver_init(void)224 drm_shim_driver_init(void)
225 {
226    amdgpu_select_device();
227 
228    shim_device.bus_type = DRM_BUS_PCI;
229    shim_device.driver_name = "amdgpu";
230    shim_device.driver_ioctls = amdgpu_ioctls;
231    shim_device.driver_ioctl_count = ARRAY_SIZE(amdgpu_ioctls);
232 
233    shim_device.version_major = 3;
234    shim_device.version_minor = 49;
235    shim_device.version_patchlevel = 0;
236 
237    /* make drmGetDevices2 and drmProcessPciDevice happy */
238    static const char uevent_content[] =
239       "DRIVER=amdgpu\n"
240       "PCI_CLASS=30000\n"
241       "PCI_ID=1002:15E7\n"
242       "PCI_SUBSYS_ID=1028:1636\n"
243       "PCI_SLOT_NAME=0000:04:00.0\n"
244       "MODALIAS=pci:v00001002d000015E7sv00001002sd00001636bc03sc00i00\n";
245    drm_shim_override_file(uevent_content, "/sys/dev/char/%d:%d/device/uevent", DRM_MAJOR,
246                           render_node_minor);
247    drm_shim_override_file("0xe9\n", "/sys/dev/char/%d:%d/device/revision", DRM_MAJOR,
248                           render_node_minor);
249    drm_shim_override_file("0x1002", "/sys/dev/char/%d:%d/device/vendor", DRM_MAJOR,
250                           render_node_minor);
251    drm_shim_override_file("0x15e7", "/sys/dev/char/%d:%d/device/device", DRM_MAJOR,
252                           render_node_minor);
253    drm_shim_override_file("0x1002", "/sys/dev/char/%d:%d/device/subsystem_vendor", DRM_MAJOR,
254                           render_node_minor);
255    drm_shim_override_file("0x1636", "/sys/dev/char/%d:%d/device/subsystem_device", DRM_MAJOR,
256                           render_node_minor);
257 }
258