1 /*
2 * Copyright (c) 2018-2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 #include <dlfcn.h>
23 #include <fcntl.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include "driver_loader.h"
28 #include "mos_util_debug.h"
29 #include "memory_leak_detector.h"
30
31 using namespace std;
32
33 #if MOS_MESSAGES_ENABLED
MOS_Message(MOS_MESSAGE_LEVEL level,const PCCHAR logtag,MOS_COMPONENT_ID compID,uint8_t subCompID,const PCCHAR functionName,int32_t lineNum,const PCCHAR message,...)34 extern "C" void MOS_Message(
35 MOS_MESSAGE_LEVEL level,
36 const PCCHAR logtag,
37 MOS_COMPONENT_ID compID,
38 uint8_t subCompID,
39 const PCCHAR functionName,
40 int32_t lineNum,
41 const PCCHAR message,
42 ...)
43 {
44 }
45 #endif
46
47 void UltGetCmdBuf(PMOS_COMMAND_BUFFER pCmdBuffer);
48
49 extern char *g_driverPath;
50 extern vector<Platform_t> g_platform;
51
52 const char *g_platformName[] = {
53 "SKL",
54 "BXT",
55 "BDW",
56 };
57
DriverDllLoader()58 DriverDllLoader::DriverDllLoader()
59 {
60 if (g_driverPath)
61 {
62 m_driver_path = g_driverPath;
63 }
64 else
65 {
66 m_driver_path = "/opt/intel/mediasdk/lib64/iHD_drv_video.so";
67 }
68
69 m_platformArray = {
70 #ifdef IGFX_GEN9_SKL_SUPPORTED
71 igfxSKLAKE,
72 #endif
73 #ifdef IGFX_GEN9_BXT_SUPPORTED
74 igfxBROXTON,
75 #endif
76 #ifdef IGFX_GEN8_BDW_SUPPORTED
77 igfxBROADWELL,
78 #endif
79 };
80
81 if (g_platform.size() > 0)
82 {
83 m_platformArray = g_platform;
84 }
85 }
86
DriverDllLoader(char * path)87 DriverDllLoader::DriverDllLoader(char *path)
88 {
89 DriverDllLoader();
90 m_driver_path = path;
91 }
92
CloseDriver(bool detectMemLeak)93 VAStatus DriverDllLoader::CloseDriver(bool detectMemLeak)
94 {
95 VAStatus vaStatus = m_ctx.vtable->vaTerminate(&m_ctx);
96
97 if (detectMemLeak)
98 {
99 MemoryLeakDetector::Detect(m_drvSyms.MOS_GetMemNinjaCounter(),
100 m_drvSyms.MOS_GetMemNinjaCounterGfx(),
101 m_currentPlatform);
102 }
103
104 m_drvSyms = {};
105
106 if(m_umdhandle)
107 {
108 dlclose(m_umdhandle);
109 m_umdhandle = nullptr;
110 }
111
112 return vaStatus;
113 }
114
InitDriver(Platform_t platform_id)115 VAStatus DriverDllLoader::InitDriver(Platform_t platform_id)
116 {
117 int drm_fd = platform_id + 1 < 0 ? 1 : platform_id + 1;
118 m_drmstate.fd = drm_fd;
119 m_drmstate.auth_type = 3;
120 m_ctx.vtable = &m_vtable;
121 m_ctx.vtable_vpp = &m_vtable_vpp;
122 #if VA_CHECK_VERSION(1,11,0)
123 m_ctx.vtable_prot = &m_vtable_prot;
124 #endif
125 m_ctx.drm_state = &m_drmstate;
126 m_currentPlatform = platform_id;
127 m_ctx.vtable_tpi = nullptr;
128
129 if (LoadDriverSymbols() != VA_STATUS_SUCCESS)
130 {
131 return VA_STATUS_ERROR_UNKNOWN;
132 }
133 m_drvSyms.MOS_SetUltFlag(1);
134 *m_drvSyms.ppfnUltGetCmdBuf = UltGetCmdBuf;
135 return m_drvSyms.__vaDriverInit_(&m_ctx);
136 }
137
LoadDriverSymbols()138 VAStatus DriverDllLoader::LoadDriverSymbols()
139 {
140 const int buf_len = 256;
141 char init_func_s[buf_len] = {};
142
143 m_umdhandle = dlopen(m_driver_path, RTLD_NOW | RTLD_GLOBAL);
144 if (!m_umdhandle)
145 {
146 printf("ERROR: dlopen of %s failed.\n", m_driver_path);
147 char* pErrorStr = dlerror();
148 if(nullptr != pErrorStr)
149 {
150 printf("ERROR: %s\n", pErrorStr);
151 }
152 return VA_STATUS_ERROR_UNKNOWN;
153 }
154
155 for (int i = 0; i <= VA_MINOR_VERSION; i++)
156 {
157 sprintf_s(init_func_s, buf_len, "__vaDriverInit_%d_%d", VA_MAJOR_VERSION, i);
158 m_drvSyms.__vaDriverInit_ = (VADriverInit)dlsym(m_umdhandle, init_func_s);
159 if (m_drvSyms.__vaDriverInit_)
160 {
161 m_drvSyms.vaCmExtSendReqMsg = (CmExtSendReqMsgFunc)dlsym(m_umdhandle, "vaCmExtSendReqMsg");
162 m_drvSyms.MOS_SetUltFlag = (MOS_SetUltFlagFunc)dlsym(m_umdhandle, "MOS_SetUltFlag");
163 m_drvSyms.MOS_GetMemNinjaCounter = (MOS_GetMemNinjaCounterFunc)dlsym(m_umdhandle, "MOS_GetMemNinjaCounter");
164 m_drvSyms.MOS_GetMemNinjaCounterGfx = (MOS_GetMemNinjaCounterFunc)dlsym(m_umdhandle, "MOS_GetMemNinjaCounterGfx");
165 m_drvSyms.ppfnUltGetCmdBuf = (UltGetCmdBufFunc *)dlsym(m_umdhandle, "pfnUltGetCmdBuf");
166 break;
167 }
168 }
169
170 if (!m_drvSyms.Initialized())
171 {
172 printf("ERROR: not all driver symbols are successfully loaded.\n");
173 return VA_STATUS_ERROR_UNKNOWN;
174 }
175
176 return VA_STATUS_SUCCESS;
177 }
178