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
MosMessage(MOS_MESSAGE_LEVEL level,MOS_COMPONENT_ID compID,uint8_t subCompID,const PCCHAR functionName,int32_t lineNum,const PCCHAR message,...)34 void MosUtilDebug::MosMessage(
35 MOS_MESSAGE_LEVEL level,
36 MOS_COMPONENT_ID compID,
37 uint8_t subCompID,
38 const PCCHAR functionName,
39 int32_t lineNum,
40 const PCCHAR message,
41 ...)
42 {
43 }
44 #endif
45
46 void UltGetCmdBuf(PMOS_COMMAND_BUFFER pCmdBuffer);
47
48 extern char *g_driverPath;
49 extern vector<Platform_t> g_platform;
50
51 const char *g_platformName[] = {
52 "SKL",
53 "BXT",
54 "BDW",
55 };
56
DriverDllLoader()57 DriverDllLoader::DriverDllLoader()
58 {
59 if (g_driverPath)
60 {
61 m_driver_path = g_driverPath;
62 }
63 else
64 {
65 m_driver_path = "/opt/intel/mediasdk/lib64/iHD_drv_video.so";
66 }
67
68 m_platformArray = {
69 #ifdef IGFX_GEN9_SKL_SUPPORTED
70 igfxSKLAKE,
71 #endif
72 #ifdef IGFX_GEN9_BXT_SUPPORTED
73 igfxBROXTON,
74 #endif
75 #ifdef IGFX_GEN8_BDW_SUPPORTED
76 igfxBROADWELL,
77 #endif
78 };
79
80 if (g_platform.size() > 0)
81 {
82 m_platformArray = g_platform;
83 }
84 }
85
DriverDllLoader(char * path)86 DriverDllLoader::DriverDllLoader(char *path)
87 {
88 DriverDllLoader();
89 m_driver_path = path;
90 }
91
CloseDriver(bool detectMemLeak)92 VAStatus DriverDllLoader::CloseDriver(bool detectMemLeak)
93 {
94 VAStatus vaStatus = m_ctx.vtable->vaTerminate(&m_ctx);
95
96 if (detectMemLeak)
97 {
98 MemoryLeakDetector::Detect(m_drvSyms.MOS_GetMemNinjaCounter(),
99 m_drvSyms.MOS_GetMemNinjaCounterGfx(),
100 m_currentPlatform);
101 }
102
103 m_drvSyms = {};
104
105 if(m_umdhandle)
106 {
107 dlclose(m_umdhandle);
108 m_umdhandle = nullptr;
109 }
110
111 return vaStatus;
112 }
113
InitDriver(Platform_t platform_id)114 VAStatus DriverDllLoader::InitDriver(Platform_t platform_id)
115 {
116 int drm_fd = platform_id + 1 < 0 ? 1 : platform_id + 1;
117 m_drmstate.fd = drm_fd;
118 m_drmstate.auth_type = 3;
119 m_ctx.vtable = &m_vtable;
120 m_ctx.vtable_vpp = &m_vtable_vpp;
121 #if VA_CHECK_VERSION(1,11,0)
122 m_ctx.vtable_prot = &m_vtable_prot;
123 #endif
124 m_ctx.drm_state = &m_drmstate;
125 m_currentPlatform = platform_id;
126 m_ctx.vtable_tpi = nullptr;
127
128 if (LoadDriverSymbols() != VA_STATUS_SUCCESS)
129 {
130 return VA_STATUS_ERROR_UNKNOWN;
131 }
132 m_drvSyms.MOS_SetUltFlag(1);
133 *m_drvSyms.ppfnUltGetCmdBuf = UltGetCmdBuf;
134 return m_drvSyms.__vaDriverInit_(&m_ctx);
135 }
136
LoadDriverSymbols()137 VAStatus DriverDllLoader::LoadDriverSymbols()
138 {
139 const int buf_len = 256;
140 char init_func_s[buf_len] = {};
141
142 m_umdhandle = dlopen(m_driver_path, RTLD_NOW | RTLD_GLOBAL);
143 if (!m_umdhandle)
144 {
145 printf("ERROR: dlopen of %s failed.\n", m_driver_path);
146 char* pErrorStr = dlerror();
147 if(nullptr != pErrorStr)
148 {
149 printf("ERROR: %s\n", pErrorStr);
150 }
151 return VA_STATUS_ERROR_UNKNOWN;
152 }
153
154 for (int i = 0; i <= VA_MINOR_VERSION; i++)
155 {
156 sprintf_s(init_func_s, buf_len, "__vaDriverInit_%d_%d", VA_MAJOR_VERSION, i);
157 m_drvSyms.__vaDriverInit_ = (VADriverInit)dlsym(m_umdhandle, init_func_s);
158 if (m_drvSyms.__vaDriverInit_)
159 {
160 m_drvSyms.vaCmExtSendReqMsg = (CmExtSendReqMsgFunc)dlsym(m_umdhandle, "vaCmExtSendReqMsg");
161 m_drvSyms.MOS_SetUltFlag = (MOS_SetUltFlagFunc)dlsym(m_umdhandle, "MOS_SetUltFlag");
162 m_drvSyms.MOS_GetMemNinjaCounter = (MOS_GetMemNinjaCounterFunc)dlsym(m_umdhandle, "MOS_GetMemNinjaCounter");
163 m_drvSyms.MOS_GetMemNinjaCounterGfx = (MOS_GetMemNinjaCounterFunc)dlsym(m_umdhandle, "MOS_GetMemNinjaCounterGfx");
164 m_drvSyms.ppfnUltGetCmdBuf = (UltGetCmdBufFunc *)dlsym(m_umdhandle, "pfnUltGetCmdBuf");
165 break;
166 }
167 }
168
169 if (!m_drvSyms.Initialized())
170 {
171 printf("ERROR: not all driver symbols are successfully loaded.\n");
172 return VA_STATUS_ERROR_UNKNOWN;
173 }
174
175 return VA_STATUS_SUCCESS;
176 }
177