1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #pragma once
9 #include "shared/source/helpers/aligned_memory.h"
10 #include "shared/source/helpers/hw_helper.h"
11 #include "shared/source/os_interface/linux/drm_memory_manager.h"
12 #include "shared/source/os_interface/linux/drm_neo.h"
13 #include "shared/test/common/helpers/default_hw_info.h"
14 
15 #include "drm/i915_drm.h"
16 #include "engine_node.h"
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
19 
20 #include <atomic>
21 #include <cstdint>
22 #include <iostream>
23 
24 using NEO::Drm;
25 using NEO::HwDeviceIdDrm;
26 using NEO::RootDeviceEnvironment;
27 
28 extern const int mockFd;
29 extern const char *mockPciPath;
30 
31 class DrmMockImpl : public Drm {
32   public:
DrmMockImpl(int fd,RootDeviceEnvironment & rootDeviceEnvironment)33     DrmMockImpl(int fd, RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<HwDeviceIdDrm>(fd, mockPciPath), rootDeviceEnvironment){};
34 
35     MOCK_METHOD2(ioctl, int(unsigned long request, void *arg));
36 };
37 
38 class DrmMockSuccess : public Drm {
39   public:
DrmMockSuccess(int fd,RootDeviceEnvironment & rootDeviceEnvironment)40     DrmMockSuccess(int fd, RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<HwDeviceIdDrm>(fd, mockPciPath), rootDeviceEnvironment) {}
41 
ioctl(unsigned long request,void * arg)42     int ioctl(unsigned long request, void *arg) override { return 0; };
43 };
44 
45 class DrmMockFail : public Drm {
46   public:
DrmMockFail(RootDeviceEnvironment & rootDeviceEnvironment)47     DrmMockFail(RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<HwDeviceIdDrm>(mockFd, mockPciPath), rootDeviceEnvironment) {}
48 
ioctl(unsigned long request,void * arg)49     int ioctl(unsigned long request, void *arg) override { return -1; };
50 };
51 
52 class DrmMockTime : public DrmMockSuccess {
53   public:
54     using DrmMockSuccess::DrmMockSuccess;
ioctl(unsigned long request,void * arg)55     int ioctl(unsigned long request, void *arg) override {
56         drm_i915_reg_read *reg = reinterpret_cast<drm_i915_reg_read *>(arg);
57         reg->val = getVal() << 32;
58         return 0;
59     };
60 
getVal()61     uint64_t getVal() {
62         static uint64_t val = 0;
63         return ++val;
64     }
65 };
66 
67 class DrmMockCustom : public Drm {
68   public:
69     using Drm::bindAvailable;
70     using Drm::cacheInfo;
71     using Drm::memoryInfo;
72 
73     struct IoctlResExt {
74         std::vector<int32_t> no;
75         int32_t res;
76 
IoctlResExtIoctlResExt77         IoctlResExt(int32_t no, int32_t res) : no(1u, no), res(res) {}
78     };
79 
80     class Ioctls {
81       public:
82         void reset();
83 
84         std::atomic<int32_t> total;
85         std::atomic<int32_t> execbuffer2;
86         std::atomic<int32_t> gemUserptr;
87         std::atomic<int32_t> gemCreate;
88         std::atomic<int32_t> gemSetTiling;
89         std::atomic<int32_t> gemGetTiling;
90         std::atomic<int32_t> primeFdToHandle;
91         std::atomic<int32_t> handleToPrimeFd;
92         std::atomic<int32_t> gemMmap;
93         std::atomic<int32_t> gemMmapOffset;
94         std::atomic<int32_t> gemSetDomain;
95         std::atomic<int32_t> gemWait;
96         std::atomic<int32_t> gemClose;
97         std::atomic<int32_t> regRead;
98         std::atomic<int32_t> getParam;
99         std::atomic<int32_t> contextGetParam;
100         std::atomic<int32_t> contextCreate;
101         std::atomic<int32_t> contextDestroy;
102     };
103 
104     struct WaitUserFenceCall {
105         uint64_t address = 0u;
106         uint64_t value = 0u;
107         uint32_t ctxId = 0u;
108         ValueWidth dataWidth = ValueWidth::U8;
109         int64_t timeout = 0;
110         uint16_t flags = 0;
111 
112         uint32_t called = 0u;
113     };
114 
115     struct IsVmBindAvailableCall {
116         bool callParent = true;
117         bool returnValue = true;
118         uint32_t called = 0u;
119     };
120 
121     DrmMockCustom(RootDeviceEnvironment &rootDeviceEnvironment);
122 
123     int waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout, uint16_t flags) override;
124 
125     bool isVmBindAvailable() override;
126 
127     void testIoctls();
128 
129     int ioctl(unsigned long request, void *arg) override;
130 
ioctlExtra(unsigned long request,void * arg)131     virtual int ioctlExtra(unsigned long request, void *arg) {
132         return -1;
133     }
134 
getErrno()135     int getErrno() override {
136         return errnoValue;
137     }
138 
reset()139     void reset() {
140         ioctl_res = 0;
141         ioctl_cnt.reset();
142         ioctl_expected.reset();
143         ioctl_res_ext = &NONE;
144     }
145 
146     Ioctls ioctl_cnt;
147     Ioctls ioctl_expected;
148 
149     IoctlResExt NONE = {-1, 0};
150 
151     WaitUserFenceCall waitUserFenceCall{};
152     IsVmBindAvailableCall isVmBindAvailableCall{};
153 
154     std::atomic<int> ioctl_res;
155     std::atomic<IoctlResExt *> ioctl_res_ext;
156 
157     //DRM_IOCTL_I915_GEM_EXECBUFFER2
158     drm_i915_gem_execbuffer2 execBuffer = {0};
159 
160     //First exec object
161     drm_i915_gem_exec_object2 execBufferBufferObjects = {0};
162 
163     //DRM_IOCTL_I915_GEM_CREATE
164     __u64 createParamsSize = 0;
165     __u32 createParamsHandle = 0;
166     //DRM_IOCTL_I915_GEM_SET_TILING
167     __u32 setTilingMode = 0;
168     __u32 setTilingHandle = 0;
169     __u32 setTilingStride = 0;
170     //DRM_IOCTL_I915_GEM_GET_TILING
171     __u32 getTilingModeOut = I915_TILING_NONE;
172     __u32 getTilingHandleIn = 0;
173     //DRM_IOCTL_PRIME_FD_TO_HANDLE
174     __u32 outputHandle = 0;
175     __s32 inputFd = 0;
176     //DRM_IOCTL_PRIME_HANDLE_TO_FD
177     __u32 inputHandle = 0;
178     __s32 outputFd = 0;
179     __s32 inputFlags = 0;
180     //DRM_IOCTL_I915_GEM_USERPTR
181     __u32 returnHandle = 0;
182     //DRM_IOCTL_I915_GEM_MMAP
183     __u32 mmapHandle = 0;
184     __u32 mmapPad = 0;
185     __u64 mmapOffset = 0;
186     __u64 mmapSize = 0;
187     __u64 mmapAddrPtr = 0x7F4000001000;
188     __u64 mmapFlags = 0;
189     //DRM_IOCTL_I915_GEM_SET_DOMAIN
190     __u32 setDomainHandle = 0;
191     __u32 setDomainReadDomains = 0;
192     __u32 setDomainWriteDomain = 0;
193     //DRM_IOCTL_I915_GETPARAM
194     drm_i915_getparam_t recordedGetParam = {0};
195     int getParamRetValue = 0;
196     //DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM
197     drm_i915_gem_context_param recordedGetContextParam = {0};
198     __u64 getContextParamRetValue = 0;
199     //DRM_IOCTL_I915_GEM_WAIT
200     int64_t gemWaitTimeout = 0;
201     //DRM_IOCTL_I915_GEM_MMAP_OFFSET
202     __u32 mmapOffsetHandle = 0;
203     __u32 mmapOffsetPad = 0;
204     __u64 mmapOffsetExpected = 0;
205     __u64 mmapOffsetFlags = 0;
206     bool failOnMmapOffset = false;
207 
208     int errnoValue = 0;
209 
210     bool returnIoctlExtraErrorValue = false;
211 };
212