1 /*
2 * Copyright (c) 2019-2022, 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 //!
23 //! \file mos_utilities_specific.cpp
24 //! \brief This module implements the MOS wrapper functions for Linux/Android
25 //!
26
27 #include <fcntl.h> // open
28 #include <stdlib.h> // atoi
29 #include <string.h> // strlen, strcat, etc.
30 #include <errno.h> // strerror(errno)
31 #include <time.h> // get_clocktime
32 #include <dlfcn.h> // dlopen, dlsym, dlclose
33 #include <unistd.h>
34 #include <signal.h>
35 #include <unistd.h> // fork
36 #include <algorithm>
37 #include <sys/types.h>
38 #include <sys/stat.h> // fstat
39 #include <sys/ipc.h> // System V IPC
40 #include <sys/types.h>
41 #include <sys/sem.h>
42 #include <sys/mman.h>
43 #include "mos_user_setting.h"
44 #include "mos_utilities_specific.h"
45 #include "mos_utilities.h"
46 #include "mos_util_debug.h"
47 #include "inttypes.h"
48
49 int32_t g_mosMemAllocCounter = 0;
50 int32_t g_mosMemAllocFakeCounter = 0;
51 int32_t g_mosMemAllocCounterGfx = 0;
52 uint8_t g_mosUltFlag = 0;
53 int32_t g_mosMemAllocIndex = 0;
54
55 int32_t *MosUtilities::m_mosMemAllocCounter = &g_mosMemAllocCounter;
56 int32_t *MosUtilities::m_mosMemAllocFakeCounter = &g_mosMemAllocFakeCounter;
57 int32_t *MosUtilities::m_mosMemAllocCounterGfx = &g_mosMemAllocCounterGfx;
58 uint8_t *MosUtilities::m_mosUltFlag = &g_mosUltFlag;
59 int32_t *MosUtilities::m_mosMemAllocIndex = &g_mosMemAllocIndex;
60
61 const char *MosUtilitiesSpecificNext::m_szUserFeatureFile = USER_FEATURE_FILE;
62 MOS_PUF_KEYLIST MosUtilitiesSpecificNext::m_ufKeyList = nullptr;
63
64 #if (_DEBUG || _RELEASE_INTERNAL)
65 int32_t g_mosMemoryFailSimulateAllocCounter = 0;
66 int32_t *MosUtilities::m_mosAllocMemoryFailSimulateAllocCounter = &g_mosMemoryFailSimulateAllocCounter;
67 #endif
68
MosGetTime()69 double MosUtilities::MosGetTime()
70 {
71 struct timespec ts = {};
72 clock_gettime(CLOCK_REALTIME, &ts);
73 return double(ts.tv_sec) * 1000000.0 + double(ts.tv_nsec) / 1000.0;
74 }
75
76 //!
77 //! \brief Linux specific user feature define, used in MosUtilities::MosUserFeatureParsePath
78 //! They can be unified with the win definitions, since they are identical.
79 //!
80 #define MOS_UF_SEPARATOR "\\"
81 #define MOS_UFKEY_EXT "UFKEY_EXTERNAL"
82 #define MOS_UFKEY_INT "UFKEY_INTERNAL"
83
84 //!
85 //! \brief trace setting definition
86 //!
87 #define TRACE_SETTING_PATH "/dev/shm/GFX_MEDIA_TRACE"
88 #define TRACE_SETTING_SIZE sizeof(MtControlData)
89
90 //!
91 //! \brief Linux specific trace entry path and file description.
92 //!
93 const char *const MosUtilitiesSpecificNext::m_mosTracePath = "/sys/kernel/debug/tracing/trace_marker_raw";
94 int32_t MosUtilitiesSpecificNext::m_mosTraceFd = -1;
95 uint64_t MosUtilitiesSpecificNext::m_filterEnv = 0;
96 uint32_t MosUtilitiesSpecificNext::m_levelEnv = 0;
97
98 MosMutex MosUtilitiesSpecificNext::m_userSettingMutex;
99
100 //!
101 //! \brief trace event size definition
102 //!
103 #define TRACE_EVENT_MAX_SIZE (3072)
104 #define TRACE_EVENT_HEADER_SIZE (sizeof(uint32_t)*3)
105 #define TRACE_EVENT_MAX_DATA_SIZE (TRACE_EVENT_MAX_SIZE - TRACE_EVENT_HEADER_SIZE - sizeof(uint16_t)) // Trace info data size section is in uint16_t
106
107 //!
108 //! \brief for int64_t/uint64_t format print warning
109 //!
110 #if __WORDSIZE == 64
111 #define __MOS64_PREFIX "l"
112 #else
113 #define __MOS64_PREFIX "ll"
114 #endif
115
116 #define MOSd64 __MOS64_PREFIX "d"
117 #define MOSu64 __MOS64_PREFIX "u"
118
119
120 //!
121 //! \brief mutex for mos utilities multi-threading protection
122 //!
123 MosMutex MosUtilities::m_mutexLock;
124 uint32_t MosUtilities::m_mosUtilInitCount = 0; // number count of mos utilities init
125
126 MediaUserSettingsMgr *MosUtilities::m_mediaUserFeatureSpecific = nullptr;
127
MosSecureStrcat(char * strDestination,size_t numberOfElements,const char * const strSource)128 MOS_STATUS MosUtilities::MosSecureStrcat(char *strDestination, size_t numberOfElements, const char * const strSource)
129 {
130 if ( (strDestination == nullptr) || (strSource == nullptr) )
131 {
132 return MOS_STATUS_INVALID_PARAMETER;
133 }
134
135 if(strnlen(strDestination, numberOfElements) == numberOfElements) // Not null terminated
136 {
137 return MOS_STATUS_INVALID_PARAMETER;
138 }
139
140 if((strlen(strDestination) + strlen(strSource)) >= numberOfElements) // checks space for null termination.
141 {
142 return MOS_STATUS_INVALID_PARAMETER;
143 }
144
145 strcat(strDestination, strSource);
146 return MOS_STATUS_SUCCESS;
147 }
148
MosSecureStrtok(char * strToken,const char * strDelimit,char ** contex)149 char *MosUtilities::MosSecureStrtok(
150 char *strToken,
151 const char *strDelimit,
152 char **contex)
153 {
154 return strtok_r(strToken, strDelimit, contex);
155 }
156
MosSecureStrcpy(char * strDestination,size_t numberOfElements,const char * const strSource)157 MOS_STATUS MosUtilities::MosSecureStrcpy(char *strDestination, size_t numberOfElements, const char * const strSource)
158 {
159 if ( (strDestination == nullptr) || (strSource == nullptr) )
160 {
161 return MOS_STATUS_INVALID_PARAMETER;
162 }
163
164 if ( numberOfElements <= strlen(strSource) ) // checks if there is space for null termination after copy.
165 {
166 return MOS_STATUS_INVALID_PARAMETER;
167 }
168
169 strcpy(strDestination, strSource);
170
171 return MOS_STATUS_SUCCESS;
172 }
173
MosSecureStrncpy(char * strDestination,size_t destSz,const char * const strSource,size_t maxCount)174 MOS_STATUS MosUtilities::MosSecureStrncpy(char *strDestination, size_t destSz, const char* const strSource, size_t maxCount)
175 {
176 if ( (strDestination == nullptr) || (strSource == nullptr) )
177 {
178 return MOS_STATUS_INVALID_PARAMETER;
179 }
180
181 if ( destSz <= maxCount ) // checks if there is space for null termination after copy.
182 {
183 return MOS_STATUS_INVALID_PARAMETER;
184 }
185
186 strncpy(strDestination, strSource, maxCount);
187
188 return MOS_STATUS_SUCCESS;
189 }
190
MosSecureMemcpy(void * pDestination,size_t dstLength,PCVOID pSource,size_t srcLength)191 MOS_STATUS MosUtilities::MosSecureMemcpy(void *pDestination, size_t dstLength, PCVOID pSource, size_t srcLength)
192 {
193 if ( (pDestination == nullptr) || (pSource == nullptr) )
194 {
195 return MOS_STATUS_INVALID_PARAMETER;
196 }
197
198 if ( dstLength < srcLength )
199 {
200 return MOS_STATUS_INVALID_PARAMETER;
201 }
202 if(pDestination != pSource)
203 {
204 memcpy(pDestination, pSource, srcLength);
205 }
206
207 return MOS_STATUS_SUCCESS;
208 }
209
MosSecureFileOpen(FILE ** ppFile,const char * filename,const char * mode)210 MOS_STATUS MosUtilities::MosSecureFileOpen(
211 FILE **ppFile,
212 const char *filename,
213 const char *mode)
214 {
215 PFILE fp;
216
217 if ((ppFile == nullptr) || (filename == nullptr) || (mode == nullptr))
218 {
219 return MOS_STATUS_INVALID_PARAMETER;
220 }
221
222 fp = fopen(filename, mode);
223
224 if (fp == nullptr)
225 {
226 *ppFile = nullptr;
227 return MOS_STATUS_FILE_OPEN_FAILED;
228 }
229 else
230 {
231 *ppFile = fp;
232 return MOS_STATUS_SUCCESS;
233 }
234 }
235
MosSecureStringPrint(char * buffer,size_t bufSize,size_t length,const char * const format,...)236 int32_t MosUtilities::MosSecureStringPrint(char *buffer, size_t bufSize, size_t length, const char * const format, ...)
237 {
238 int32_t iRet = -1;
239 va_list var_args;
240
241 if((buffer == nullptr) || (format == nullptr) || (bufSize < length))
242 {
243 return iRet;
244 }
245
246 va_start(var_args, format);
247
248 iRet = vsnprintf(buffer, length, format, var_args);
249
250 va_end(var_args);
251
252 return iRet;
253 }
254
MosSecureVStringPrint(char * buffer,size_t bufSize,size_t length,const char * const format,va_list var_args)255 MOS_STATUS MosUtilities::MosSecureVStringPrint(char *buffer, size_t bufSize, size_t length, const char * const format, va_list var_args)
256 {
257 if((buffer == nullptr) || (format == nullptr) || (bufSize < length))
258 {
259 return MOS_STATUS_INVALID_PARAMETER;
260 }
261
262 vsnprintf(buffer, length, format, var_args);
263
264 return MOS_STATUS_SUCCESS;
265 }
266
MosGetFileSize(HANDLE hFile,uint32_t * lpFileSizeLow,uint32_t * lpFileSizeHigh)267 MOS_STATUS MosUtilities::MosGetFileSize(
268 HANDLE hFile,
269 uint32_t *lpFileSizeLow,
270 uint32_t *lpFileSizeHigh)
271 {
272 struct stat Buf;
273 MOS_UNUSED(lpFileSizeHigh);
274
275 if((hFile == nullptr) || (lpFileSizeLow == nullptr))
276 {
277 return MOS_STATUS_INVALID_PARAMETER;
278 }
279
280 if ( (fstat((intptr_t)hFile, &Buf)) < 0 )
281 {
282 *lpFileSizeLow = 0;
283 return MOS_STATUS_INVALID_FILE_SIZE;
284 }
285 *lpFileSizeLow = (uint32_t)Buf.st_size;
286
287 //to-do, lpFileSizeHigh store high 32-bit of File size
288 return MOS_STATUS_SUCCESS;
289 }
290
MosCreateDirectory(char * const lpPathName)291 MOS_STATUS MosUtilities::MosCreateDirectory(
292 char * const lpPathName)
293 {
294 uint32_t mode;
295
296 MOS_OS_CHK_NULL_RETURN(lpPathName);
297
298 // Set read/write access right for usr/group.
299 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP;
300 if (mkdir(lpPathName, mode) < 0 &&
301 errno != EEXIST) // Directory already exists, don't return failure in this case.
302 {
303 MOS_OS_ASSERTMESSAGE("Failed to create the directory '%s'. Error = %s", lpPathName, strerror(errno));
304 return MOS_STATUS_DIR_CREATE_FAILED;
305 }
306
307 return MOS_STATUS_SUCCESS;
308 }
309
MosCreateFile(PHANDLE pHandle,char * const lpFileName,uint32_t iOpenFlag)310 MOS_STATUS MosUtilities::MosCreateFile(
311 PHANDLE pHandle,
312 char * const lpFileName,
313 uint32_t iOpenFlag)
314 {
315 int32_t iFileDescriptor;
316 uint32_t mode;
317
318 if((lpFileName == nullptr) || (pHandle == nullptr))
319 {
320 return MOS_STATUS_INVALID_PARAMETER;
321 }
322 //set read/write access right for usr/group, mMode only takes effect when
323 //O_CREAT is set
324 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
325 if ( (iFileDescriptor = open(lpFileName, iOpenFlag, mode)) < 0 )
326 {
327 *pHandle = (HANDLE)((intptr_t) iFileDescriptor);
328 return MOS_STATUS_INVALID_HANDLE;
329 }
330
331 *pHandle = (HANDLE)((intptr_t) iFileDescriptor);
332 return MOS_STATUS_SUCCESS;
333 }
334
MosReadFile(HANDLE hFile,void * lpBuffer,uint32_t bytesToRead,uint32_t * pBytesRead,void * lpOverlapped)335 MOS_STATUS MosUtilities::MosReadFile(
336 HANDLE hFile,
337 void *lpBuffer,
338 uint32_t bytesToRead,
339 uint32_t *pBytesRead,
340 void *lpOverlapped)
341 {
342 size_t nNumBytesToRead;
343 ssize_t nNumBytesRead;
344 MOS_UNUSED(lpOverlapped);
345
346 if((hFile == nullptr) || (lpBuffer == nullptr) || (pBytesRead == nullptr))
347 {
348 return MOS_STATUS_INVALID_PARAMETER;
349 }
350
351 nNumBytesToRead = (size_t)bytesToRead;
352 nNumBytesRead = 0;
353
354 //To-do: process lpOverlapped
355
356 if ((nNumBytesRead = read((intptr_t)hFile, lpBuffer, nNumBytesToRead)) < 0)
357 {
358 *pBytesRead = 0;
359 return MOS_STATUS_FILE_READ_FAILED;
360 }
361
362 *pBytesRead = (uint32_t)nNumBytesRead;
363 return MOS_STATUS_SUCCESS;
364 }
365
MosWriteFile(HANDLE hFile,void * lpBuffer,uint32_t bytesToWrite,uint32_t * pbytesWritten,void * lpOverlapped)366 MOS_STATUS MosUtilities::MosWriteFile(
367 HANDLE hFile,
368 void *lpBuffer,
369 uint32_t bytesToWrite,
370 uint32_t *pbytesWritten,
371 void *lpOverlapped)
372 {
373 size_t nNumBytesToWrite;
374 ssize_t nNumBytesWritten;
375 MOS_UNUSED(lpOverlapped);
376
377 if((hFile == nullptr) || (lpBuffer == nullptr) || (pbytesWritten == nullptr))
378 {
379 return MOS_STATUS_INVALID_PARAMETER;
380 }
381
382 nNumBytesToWrite = (size_t)bytesToWrite;
383 nNumBytesWritten = 0;
384
385 //To-do, process lpOverlapped
386
387 if ((nNumBytesWritten = write((intptr_t)hFile, lpBuffer, nNumBytesToWrite)) < 0)
388 {
389 *pbytesWritten = 0;
390 return MOS_STATUS_FILE_WRITE_FAILED;
391 }
392
393 *pbytesWritten = (uint32_t)nNumBytesWritten;
394 return MOS_STATUS_SUCCESS;
395 }
396
MosSetFilePointer(HANDLE hFile,int32_t lDistanceToMove,int32_t * lpDistanceToMoveHigh,int32_t dwMoveMethod)397 MOS_STATUS MosUtilities::MosSetFilePointer(
398 HANDLE hFile,
399 int32_t lDistanceToMove,
400 int32_t *lpDistanceToMoveHigh,
401 int32_t dwMoveMethod)
402 {
403 int32_t iOffSet;
404 int32_t iCurPos;
405
406 if(hFile == nullptr)
407 {
408 return MOS_STATUS_INVALID_PARAMETER;
409 }
410
411 if (lpDistanceToMoveHigh == nullptr)
412 {
413 iOffSet = lDistanceToMove;
414 }
415 else
416 {
417 //to-do, let lpDistanceToMoveHigh and lDistanceToMove form a 64-bit iOffSet
418 iOffSet = (int32_t)lDistanceToMove;
419 }
420
421 if ((iCurPos = lseek((intptr_t)hFile, iOffSet, dwMoveMethod)) < 0)
422 {
423 return MOS_STATUS_SET_FILE_POINTER_FAILED;
424 }
425
426 return MOS_STATUS_SUCCESS;
427 }
428
MosCloseHandle(HANDLE hObject)429 int32_t MosUtilities::MosCloseHandle(HANDLE hObject)
430 {
431 int32_t iRet = false;
432
433 if(hObject != nullptr)
434 {
435 close((intptr_t)hObject);
436 iRet = true;
437 }
438
439 return iRet;
440 }
441
442 //library
MosLoadLibrary(const char * const lpLibFileName,PHMODULE phModule)443 MOS_STATUS MosUtilities::MosLoadLibrary(const char * const lpLibFileName, PHMODULE phModule)
444 {
445 if (lpLibFileName == nullptr)
446 {
447 return MOS_STATUS_INVALID_PARAMETER;
448 }
449
450 *phModule = dlopen((const char *)lpLibFileName, RTLD_LAZY);
451
452 return ((*phModule != nullptr) ? MOS_STATUS_SUCCESS : MOS_STATUS_LOAD_LIBRARY_FAILED);
453 }
454
MosFreeLibrary(HMODULE hLibModule)455 int32_t MosUtilities::MosFreeLibrary(HMODULE hLibModule)
456 {
457 uint32_t iRet = 10; // Initialize to some non-zero value
458
459 if(hLibModule != nullptr)
460 {
461 iRet = dlclose(hLibModule);
462 }
463 return (iRet == 0) ? true : false;
464 }
465
MosGetProcAddress(HMODULE hModule,const char * lpProcName)466 void *MosUtilities::MosGetProcAddress(HMODULE hModule, const char *lpProcName)
467 {
468 void *pSym = nullptr;
469
470 if (hModule == nullptr ||
471 lpProcName == nullptr)
472 {
473 MOS_OS_ASSERTMESSAGE("Invalid parameter.");
474 }
475 else
476 {
477 pSym = dlsym(hModule, lpProcName);
478 }
479
480 return pSym;
481 }
482
MosGetPid()483 int32_t MosUtilities::MosGetPid()
484 {
485 return(getpid());
486 }
487
488 //Performace
MosQueryPerformanceFrequency(uint64_t * pFrequency)489 int32_t MosUtilities::MosQueryPerformanceFrequency(uint64_t *pFrequency)
490 {
491 struct timespec Res;
492 int32_t iRet;
493
494 if(pFrequency == nullptr)
495 {
496 return false;
497 }
498
499 if ( (iRet = clock_getres(CLOCK_MONOTONIC, &Res)) != 0 )
500 {
501 return false;
502 }
503
504 // resolution (precision) can't be in seconds for current machine and OS
505 if (Res.tv_sec != 0)
506 {
507 return false;
508 }
509 *pFrequency = (uint64_t)((1000 * 1000 * 1000) / Res.tv_nsec);
510
511 return true;
512 }
513
MosQueryPerformanceCounter(uint64_t * pPerformanceCount)514 int32_t MosUtilities::MosQueryPerformanceCounter(uint64_t *pPerformanceCount)
515 {
516 struct timespec Res;
517 struct timespec t;
518 int32_t iRet;
519
520 if(pPerformanceCount == nullptr)
521 {
522 return false;
523 }
524 if ( (iRet = clock_getres (CLOCK_MONOTONIC, &Res)) != 0 )
525 {
526 return false;
527 }
528 if (Res.tv_sec != 0)
529 { // resolution (precision) can't be in seconds for current machine and OS
530 return false;
531 }
532 if( (iRet = clock_gettime(CLOCK_MONOTONIC, &t)) != 0)
533 {
534 return false;
535 }
536 *pPerformanceCount = (uint64_t)((1000 * 1000 * 1000 * t.tv_sec + t.tv_nsec) / Res.tv_nsec);
537
538 return true;
539 }
540
MosSleep(uint32_t mSec)541 void MosUtilities::MosSleep(uint32_t mSec)
542 {
543 usleep(1000 * mSec);
544 }
545
546 //User Feature
UserFeatureFindKey(MOS_PUF_KEYLIST pKeyList,char * const pcKeyName)547 MOS_UF_KEY* MosUtilitiesSpecificNext::UserFeatureFindKey(MOS_PUF_KEYLIST pKeyList, char * const pcKeyName)
548 {
549 int32_t iResult;
550 MOS_PUF_KEYLIST pTempNode;
551
552 iResult = -1;
553
554 for(pTempNode = pKeyList; pTempNode; pTempNode = pTempNode->pNext)
555 {
556 iResult = strcmp(pTempNode->pElem->pcKeyName, pcKeyName);
557 if ( iResult == 0 )
558 {
559 return pTempNode->pElem;
560 }
561 }
562 return nullptr; //not found
563 }
564
UserFeatureFindValue(MOS_UF_KEY UFKey,char * const pcValueName)565 int32_t MosUtilitiesSpecificNext::UserFeatureFindValue(MOS_UF_KEY UFKey, char * const pcValueName)
566 {
567 int32_t iResult;
568 int32_t i;
569
570 iResult = -1;
571
572 for ( i = 0; i < UFKey.valueNum; i++ )
573 {
574 iResult = strcmp(UFKey.pValueArray[i].pcValueName, pcValueName);
575 if ( iResult == 0 )
576 {
577 return i;
578 }
579 }
580 return NOT_FOUND;
581 }
582
UserFeatureAdd(MOS_PUF_KEYLIST * pKeyList,MOS_UF_KEY * NewKey)583 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureAdd(MOS_PUF_KEYLIST *pKeyList, MOS_UF_KEY *NewKey)
584 {
585 MOS_UF_KEYNODE *pNewNode;
586 MOS_UF_KEYNODE *pTempNode;
587 MOS_UF_KEYNODE *pStartNode;
588
589 pNewNode = nullptr;
590 pTempNode = nullptr;
591 pStartNode = *pKeyList;
592
593 if ( NewKey == nullptr )
594 {
595 return MOS_STATUS_INVALID_PARAMETER;
596 }
597
598 pNewNode = (MOS_UF_KEYNODE *)MOS_AllocAndZeroMemory(sizeof(MOS_UF_KEYNODE));
599 if (pNewNode == nullptr)
600 {
601 return MOS_STATUS_NO_SPACE;
602 }
603 pNewNode->pElem = NewKey;
604
605 if (*pKeyList == nullptr ) // the key list is empty
606 {
607 pNewNode->pNext = nullptr;
608 (*pKeyList) = pNewNode;
609 }
610 else // the key list is not empty, append to the front
611 {
612 pTempNode = pStartNode->pNext;
613 pStartNode->pNext = pNewNode;
614 pNewNode->pNext = pTempNode;
615 }
616 return MOS_STATUS_SUCCESS;
617 }
618
UserFeatureSet(MOS_PUF_KEYLIST * pKeyList,MOS_UF_KEY NewKey)619 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureSet(MOS_PUF_KEYLIST *pKeyList, MOS_UF_KEY NewKey)
620 {
621 int32_t iPos;
622 MOS_UF_VALUE *pValueArray;
623 MOS_UF_KEY *Key;
624 void *ulValueBuf;
625
626 iPos = -1;
627 pValueArray = nullptr;
628
629 if ( (Key = UserFeatureFindKey(*pKeyList, NewKey.pcKeyName)) == nullptr )
630 {
631 // can't find key in File
632 return MOS_STATUS_UNKNOWN;
633 }
634
635 // Prepare the ValueBuff of the NewKey
636 if ((ulValueBuf = MOS_AllocAndZeroMemory(NewKey.pValueArray[0].ulValueLen)) == nullptr)
637 {
638 return MOS_STATUS_NO_SPACE;
639 }
640 MosUtilities::MosAtomicIncrement(MosUtilities::m_mosMemAllocFakeCounter); //ulValueBuf does not count it, because it is freed after the MEMNJA final report.
641 MOS_OS_NORMALMESSAGE("ulValueBuf %p for key %s", ulValueBuf, NewKey.pValueArray[0].pcValueName);
642
643 m_userSettingMutex.Lock();
644 if ((iPos = UserFeatureFindValue(*Key, NewKey.pValueArray[0].pcValueName)) == NOT_FOUND)
645 {
646 //not found, add a new value to key struct.
647 //reallocate memory for appending this value.
648 iPos = MosUtilities::MosAtomicIncrement(&Key->valueNum);
649 iPos = iPos - 1;
650 if (iPos >= UF_CAPABILITY)
651 {
652 MOS_OS_ASSERTMESSAGE("user setting requires iPos (%d) < UF_CAPABILITY(64)", iPos);
653 Key->valueNum = UF_CAPABILITY;
654 MOS_SafeFreeMemory(ulValueBuf);
655 m_userSettingMutex.Unlock();
656 return MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
657 }
658 MosUtilities::MosSecureStrcpy(Key->pValueArray[iPos].pcValueName,
659 MAX_USERFEATURE_LINE_LENGTH,
660 NewKey.pValueArray[0].pcValueName);
661 }
662 else
663 {
664 //if found, the previous value buffer needs to be freed before reallocating
665 MOS_FreeMemory(Key->pValueArray[iPos].ulValueBuf);
666 MosUtilities::MosAtomicDecrement(MosUtilities::m_mosMemAllocFakeCounter);
667 MOS_OS_NORMALMESSAGE("ulValueBuf %p for key %s", ulValueBuf, NewKey.pValueArray[0].pcValueName);
668 }
669
670 Key->pValueArray[iPos].ulValueLen = NewKey.pValueArray[0].ulValueLen;
671 Key->pValueArray[iPos].ulValueType = NewKey.pValueArray[0].ulValueType;
672 Key->pValueArray[iPos].ulValueBuf = ulValueBuf;
673
674 MosUtilities::MosZeroMemory(Key->pValueArray[iPos].ulValueBuf, NewKey.pValueArray[0].ulValueLen);
675
676 MosUtilities::MosSecureMemcpy(Key->pValueArray[iPos].ulValueBuf,
677 NewKey.pValueArray[0].ulValueLen,
678 NewKey.pValueArray[0].ulValueBuf,
679 NewKey.pValueArray[0].ulValueLen);
680
681 m_userSettingMutex.Unlock();
682 return MOS_STATUS_SUCCESS;
683 }
684
UserFeatureQuery(MOS_PUF_KEYLIST pKeyList,MOS_UF_KEY * NewKey)685 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureQuery(MOS_PUF_KEYLIST pKeyList, MOS_UF_KEY *NewKey)
686 {
687 int32_t iPos;
688 MOS_UF_VALUE *pValueArray;
689 MOS_UF_KEY *Key;
690
691 iPos = -1;
692 pValueArray = nullptr;
693
694 // can't find key in user feature
695 if ( (Key = UserFeatureFindKey(pKeyList, NewKey->pcKeyName)) == nullptr )
696 {
697 return MOS_STATUS_UNKNOWN;
698 }
699
700 // can't find Value in the key
701 if ( (iPos = UserFeatureFindValue(*Key, NewKey->pValueArray[0].pcValueName)) == NOT_FOUND)
702 {
703 return MOS_STATUS_UNKNOWN;
704 }
705
706 //get key content from user feature
707 MosUtilities::MosSecureMemcpy(NewKey->pValueArray[0].ulValueBuf,
708 Key->pValueArray[iPos].ulValueLen,
709 Key->pValueArray[iPos].ulValueBuf,
710 Key->pValueArray[iPos].ulValueLen);
711
712 NewKey->pValueArray[0].ulValueLen = Key->pValueArray[iPos].ulValueLen;
713 NewKey->pValueArray[0].ulValueType = Key->pValueArray[iPos].ulValueType;
714
715 return MOS_STATUS_SUCCESS;
716 }
717
UserFeatureReadNextTokenFromFile(FILE * pFile,const char * szFormat,char * szToken)718 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureReadNextTokenFromFile(FILE *pFile, const char *szFormat, char *szToken)
719 {
720 size_t nTokenSize = 0;
721
722 // Reads the next token from the given pFile.
723 if (fscanf(pFile, szFormat, szToken) <= 0)
724 {
725 MOS_OS_VERBOSEMESSAGE("Failed reading the next token from the user feature file. This is probably because the token does not exist in the user feature file.");
726 return MOS_STATUS_FILE_READ_FAILED;
727 }
728
729 // Converts to Unix-style line endings to prevent compatibility problems.
730 nTokenSize = strnlen(szToken, MAX_USERFEATURE_LINE_LENGTH);
731 if (szToken[nTokenSize-1] == '\r')
732 {
733 szToken[nTokenSize-1] = '\0';
734 }
735
736 return MOS_STATUS_SUCCESS;
737 }
738
UserFeatureDumpFile(const char * const szFileName,MOS_PUF_KEYLIST * pKeyList)739 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureDumpFile(const char * const szFileName, MOS_PUF_KEYLIST* pKeyList)
740 {
741 MOS_UF_KEY *CurKey;
742 MOS_UF_VALUE *CurValue;
743 char szTmp[MAX_USERFEATURE_LINE_LENGTH];
744 int32_t iResult;
745 size_t nSize;
746 int32_t bFirst;
747 int32_t iCount;
748 PFILE File;
749 int32_t bEmpty;
750 uint32_t iCurId;
751 MOS_STATUS eStatus;
752 char *tmpChar; // Used in the 64-bit case to read uint64_t
753
754 CurValue = nullptr;
755 nSize = 0;
756 bFirst = 1; // 1 stand for "is the first key".
757 iCount = 0;
758 File = nullptr;
759 bEmpty = 0;
760 iCurId = 0;
761 eStatus = MOS_STATUS_SUCCESS;
762
763 CurKey = (MOS_UF_KEY *)MOS_AllocAndZeroMemory(sizeof(MOS_UF_KEY));
764 if (CurKey == nullptr)
765 {
766 return MOS_STATUS_NO_SPACE;
767 }
768 CurKey->valueNum = 0;
769 CurKey->pcKeyName[0] = '\0';
770 CurKey->pValueArray = nullptr;
771
772 if ( (File = fopen(szFileName, "r")) == nullptr)
773 {
774 MOS_FreeMemory(CurKey);
775 return MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
776 }
777 while (feof(File) != EOF)
778 {
779 MosUtilities::MosZeroMemory(szTmp, MAX_USERFEATURE_LINE_LENGTH*sizeof(char ));
780 if (MOS_FAILED(UserFeatureReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
781 {
782 break;
783 }
784
785 // set szDumpData with extracted File content.
786 iResult = strcmp(szTmp, UF_KEY_ID);
787 if ( iResult == 0 )
788 {
789 // It is a new key starting!
790 if (! bFirst )
791 {
792 // Add last key struct to contents when the key is not first.
793 // otherwise, continue to load key struct data.
794 CurKey->pValueArray = CurValue;
795 CurKey->valueNum = iCount;
796 if(UserFeatureAdd(pKeyList, CurKey) != MOS_STATUS_SUCCESS)
797 {
798 // if the CurKey didn't be added in pKeyList, free it.
799 MOS_FreeMemory(CurKey);
800 }
801 CurKey = (MOS_UF_KEY *)MOS_AllocAndZeroMemory(sizeof(MOS_UF_KEY));
802 if (CurKey == nullptr)
803 {
804 eStatus = MOS_STATUS_NO_SPACE;
805 break;
806 }
807 } // if (! bFirst )
808
809 if (fscanf(File, "%x\n", &iCurId) <= 0)
810 {
811 break;
812 }
813
814 CurKey->UFKey = (void *)(intptr_t)iCurId;
815
816 MosUtilities::MosZeroMemory(szTmp, MAX_USERFEATURE_LINE_LENGTH * sizeof(char));
817 if (MOS_FAILED(UserFeatureReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
818 {
819 break;
820 }
821
822 MosUtilities::MosSecureStrcpy(CurKey->pcKeyName, MAX_USERFEATURE_LINE_LENGTH, szTmp);
823 CurKey->valueNum = 0;
824
825 // allocate capability length for valuearray.
826 CurValue = (MOS_UF_VALUE *)MOS_AllocAndZeroMemory(sizeof(MOS_UF_VALUE) * UF_CAPABILITY);
827 if (CurValue == nullptr)
828 {
829 eStatus = MOS_STATUS_NO_SPACE;
830 break;
831 }
832 bFirst = 0;
833 iCount = 0; // next key's array number.
834 bEmpty = 1;
835 } // if ( iResult == 0 )
836 else // not a key
837 {
838 // Is it a value starting?
839 iResult = strcmp(szTmp, UF_VALUE_ID);
840 if ( iResult == 0 )
841 {
842 if (MOS_FAILED(UserFeatureReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
843 {
844 break;
845 }
846
847 if (CurValue == nullptr)
848 {
849 break;
850 }
851
852 // Out of bounds technically based on how much memory we allocated
853 if (iCount < 0 || iCount >= UF_CAPABILITY)
854 {
855 eStatus = MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
856 MOS_OS_ASSERTMESSAGE("user setting value icount %d, and it must meet 0 < icount < UF_CAPABILITY(64)", iCount);
857 break;
858 }
859
860 // Load value name;
861 MosUtilities::MosSecureStrcpy(CurValue[iCount].pcValueName, MAX_USERFEATURE_LINE_LENGTH, szTmp);
862
863 // Load value type
864 if (MOS_FAILED(UserFeatureReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
865 {
866 break;
867 }
868
869 CurValue[iCount].ulValueType = atoi(szTmp);
870
871 // Load value buffer.
872 switch ( CurValue[iCount].ulValueType )
873 {
874 case UF_DWORD: // 32-bit
875 if (MOS_FAILED(UserFeatureReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
876 {
877 break;
878 }
879
880 CurValue[iCount].ulValueLen = sizeof(uint32_t);
881 CurValue[iCount].ulValueBuf = MOS_AllocMemory(sizeof(uint32_t));
882 if(CurValue[iCount].ulValueBuf == nullptr)
883 {
884 eStatus = MOS_STATUS_NO_SPACE;
885 break;
886 }
887 *(uint32_t*)(CurValue[iCount].ulValueBuf) = atoi(szTmp);
888 break;
889 case UF_QWORD: // 64-bit
890 if (MOS_FAILED(UserFeatureReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
891 {
892 break;
893 }
894
895 CurValue[iCount].ulValueLen = sizeof(uint64_t);
896 CurValue[iCount].ulValueBuf = MOS_AllocMemory(sizeof(uint64_t));
897 if(CurValue[iCount].ulValueBuf == nullptr)
898 {
899 eStatus = MOS_STATUS_NO_SPACE;
900 break;
901 }
902 tmpChar = &szTmp[0];
903 *(uint64_t*)(CurValue[iCount].ulValueBuf) = strtoll(tmpChar,&tmpChar,0);
904 break;
905 case UF_SZ:
906 case UF_MULTI_SZ:
907 if (MOS_FAILED(UserFeatureReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
908 {
909 break;
910 }
911
912 nSize = strlen(szTmp);
913 CurValue[iCount].ulValueLen = (nSize+1)*sizeof(char );
914 CurValue[iCount].ulValueBuf = MOS_AllocMemory(nSize+1);
915 if(CurValue[iCount].ulValueBuf == nullptr)
916 {
917 eStatus = MOS_STATUS_NO_SPACE;
918 break;
919 }
920 MosUtilities::MosZeroMemory(CurValue[iCount].ulValueBuf, nSize+1);
921 MosUtilities::MosSecureMemcpy(CurValue[iCount].ulValueBuf, nSize, szTmp, nSize);
922 break;
923 default:
924 eStatus = MOS_STATUS_UNKNOWN;
925 }
926 if (eStatus != MOS_STATUS_SUCCESS)
927 {
928 break;
929 }
930
931 iCount ++; // do the error checking near the top
932
933 } // if ( iResult == 0 )
934 else // It is not a value starting, it's bad User Feature File.
935 {
936 int32_t iResult = strcmp(szTmp, "");
937 if ( !iResult )
938 {
939 continue;
940 }
941 else
942 {
943 eStatus = MOS_STATUS_INVALID_PARAMETER;
944 break;
945 }
946 } // else ( iResult == 0 )
947 }
948 } // while (feof(File) != EOF)
949
950 if (eStatus == MOS_STATUS_SUCCESS)
951 {
952 if ( bEmpty && (strlen(CurKey->pcKeyName) > 0) &&
953 (CurKey->valueNum == 0) )
954 {
955 CurKey->pValueArray = CurValue;
956 CurKey->valueNum = iCount;
957 if(UserFeatureAdd(pKeyList, CurKey) != MOS_STATUS_SUCCESS)
958 {
959 // if the CurKey didn't be added in pKeyList, free it.
960 for (uint32_t i = 0; i < iCount; i++)
961 {
962 if (CurValue)
963 {
964 MOS_FreeMemory(CurValue[i].ulValueBuf);
965 }
966 }
967 MOS_FreeMemory(CurValue);
968 MOS_FreeMemory(CurKey);
969 }
970 }
971 else
972 {
973 for (uint32_t i = 0; i < iCount; i++)
974 {
975 if (CurValue)
976 {
977 MOS_FreeMemory(CurValue[i].ulValueBuf);
978 }
979 }
980 MOS_FreeMemory(CurValue);
981 MOS_FreeMemory(CurKey);
982 }
983 }
984 else
985 {
986 for (uint32_t i = 0; i < iCount; i++)
987 {
988 if (CurValue)
989 {
990 MOS_FreeMemory(CurValue[i].ulValueBuf);
991 }
992 }
993 MOS_FreeMemory(CurValue);
994 MOS_FreeMemory(CurKey);
995 }
996 fclose(File);
997 return eStatus;
998 }
999
UserFeatureDumpDataToFile(const char * szFileName,MOS_PUF_KEYLIST pKeyList)1000 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureDumpDataToFile(const char *szFileName, MOS_PUF_KEYLIST pKeyList)
1001 {
1002 int32_t iResult;
1003 PFILE File;
1004 MOS_PUF_KEYLIST pKeyTmp;
1005 int32_t j;
1006
1007 // For release version: writes to the file if it exists,
1008 // skips if it does not exist
1009 // For other version: always writes to the file
1010
1011 #if(_RELEASE)
1012 File = fopen(szFileName, "r");
1013 if (File == NULL)
1014 {
1015 return MOS_STATUS_SUCCESS;
1016 }
1017 else
1018 {
1019 fclose(File);
1020 File = fopen(szFileName, "w+");
1021 }
1022 #else
1023 File = fopen(szFileName, "w+");
1024 #endif
1025
1026 if ( !File )
1027 {
1028 return MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
1029 }
1030
1031 for (pKeyTmp = pKeyList; pKeyTmp; pKeyTmp = pKeyTmp->pNext)
1032 {
1033 fprintf(File, "%s\n", UF_KEY_ID);
1034 fprintf(File, "\t0x%.8x\n", (uint32_t)(uintptr_t)pKeyTmp->pElem->UFKey);
1035 fprintf(File, "\t%s\n", pKeyTmp->pElem->pcKeyName);
1036 for ( j = 0; j < pKeyTmp->pElem->valueNum; j ++ )
1037 {
1038 fprintf(File, "\t\t%s\n", UF_VALUE_ID);
1039 if ( strlen(pKeyTmp->pElem->pValueArray[j].pcValueName) > 0 )
1040 {
1041 fprintf(File, "\t\t\t%s\n",
1042 pKeyTmp->pElem->pValueArray[j].pcValueName);
1043 }
1044 fprintf(File, "\t\t\t%d\n", pKeyTmp->pElem->pValueArray[j].ulValueType);
1045 if (pKeyTmp->pElem->pValueArray[j].ulValueBuf != nullptr)
1046 {
1047 switch (pKeyTmp->pElem->pValueArray[j].ulValueType)
1048 {
1049 case UF_SZ:
1050 fprintf(File, "\t\t\t%s\n",
1051 (char *)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1052 break;
1053 case UF_DWORD:
1054 fprintf(File, "\t\t\t%u\n",
1055 *(uint32_t*)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1056 break;
1057 case UF_QWORD:
1058 fprintf(File, "\t\t\t%" PRIu64"\n", *(uint64_t*)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1059 break;
1060 default:
1061 fprintf(File, "\t\t\t%s\n",
1062 (char *)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1063 break;
1064 } //switch (pKeyTmp->pElem->pValueArray[j].ulValueType)
1065 }
1066 } // for ( j = 0; j < pKeyTmp->pElem->valueNum; j ++ )
1067 } //for (pKeyTmp = pKeyList; pKeyTmp; pKeyTmp = pKeyTmp->pNext)
1068 fclose(File);
1069
1070 return MOS_STATUS_SUCCESS;
1071 }
1072
UserFeatureFreeKeyList(MOS_PUF_KEYLIST pKeyList)1073 void MosUtilitiesSpecificNext::UserFeatureFreeKeyList(MOS_PUF_KEYLIST pKeyList)
1074 {
1075 MOS_PUF_KEYLIST pKeyTmp;
1076 MOS_PUF_KEYLIST pKeyTmpNext;
1077 uint32_t i;
1078
1079 pKeyTmp = pKeyList;
1080 while(pKeyTmp)
1081 {
1082 pKeyTmpNext = pKeyTmp->pNext;
1083 for(i=0;i<pKeyTmp->pElem->valueNum;i++)
1084 {
1085 MOS_FreeMemory(pKeyTmp->pElem->pValueArray[i].ulValueBuf);
1086 }
1087 MOS_FreeMemory(pKeyTmp->pElem->pValueArray);
1088 MOS_FreeMemory(pKeyTmp->pElem);
1089 MOS_FreeMemory(pKeyTmp);
1090 pKeyTmp = pKeyTmpNext;
1091 }
1092 return;
1093 }
1094
UserFeatureSetValue(char * const strKey,const char * const pcValueName,uint32_t uiValueType,void * pData,int32_t nDataSize)1095 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureSetValue(
1096 char * const strKey,
1097 const char * const pcValueName,
1098 uint32_t uiValueType,
1099 void *pData,
1100 int32_t nDataSize)
1101 {
1102 MOS_UF_KEY NewKey;
1103 MOS_UF_VALUE NewValue;
1104 MOS_STATUS eStatus;
1105
1106 eStatus = MOS_STATUS_UNKNOWN;
1107
1108 if ((strKey == nullptr) || (pcValueName == nullptr) || (m_ufKeyList == nullptr))
1109 {
1110 return MOS_STATUS_INVALID_PARAMETER;
1111 }
1112
1113 MosUtilities::MosZeroMemory(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH);
1114 MosUtilities::MosSecureStrcpy(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH, pcValueName);
1115 NewValue.ulValueType = uiValueType;
1116 if( NewValue.ulValueType == UF_DWORD)
1117 {
1118 NewValue.ulValueLen = sizeof(uint32_t);
1119 }
1120 else
1121 {
1122 NewValue.ulValueLen = nDataSize;
1123 }
1124 NewValue.ulValueBuf = pData;
1125
1126 MosUtilities::MosZeroMemory(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH);
1127 MosUtilities::MosSecureStrcpy(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH, strKey);
1128 NewKey.pValueArray = &NewValue;
1129 NewKey.valueNum = 1;
1130
1131 if ( ( eStatus = UserFeatureSet(&MosUtilitiesSpecificNext::m_ufKeyList, NewKey)) == MOS_STATUS_SUCCESS )
1132 {
1133 MosUtilities::MosUserFeatureNotifyChangeKeyValue(nullptr, false, nullptr, true);
1134 }
1135
1136 return eStatus;
1137 }
1138
UserFeatureQueryValue(char * const strKey,const char * const pcValueName,uint32_t * uiValueType,void * pData,int32_t * nDataSize)1139 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureQueryValue(
1140 char * const strKey,
1141 const char * const pcValueName,
1142 uint32_t *uiValueType,
1143 void *pData,
1144 int32_t *nDataSize)
1145 {
1146 MOS_UF_KEY NewKey;
1147 MOS_UF_VALUE NewValue;
1148 size_t nKeyLen, nValueLen;
1149 MOS_STATUS eStatus;
1150 MOS_PUF_KEYLIST pKeyList;
1151 char strTempKey[MAX_USERFEATURE_LINE_LENGTH];
1152 char strTempValueName[MAX_USERFEATURE_LINE_LENGTH];
1153
1154 eStatus = MOS_STATUS_UNKNOWN;
1155 pKeyList = MosUtilitiesSpecificNext::m_ufKeyList;
1156
1157 if ( (strKey == nullptr) || (pcValueName == nullptr) || (pKeyList == nullptr))
1158 {
1159 return MOS_STATUS_INVALID_PARAMETER;
1160 }
1161 MosUtilities::MosZeroMemory(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH);
1162 MosUtilities::MosSecureStrcpy(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH, pcValueName);
1163 NewValue.ulValueBuf = pData;
1164
1165 MosUtilities::MosZeroMemory(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH);
1166 MosUtilities::MosSecureStrcpy(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH, strKey);
1167 NewKey.pValueArray = &NewValue;
1168 NewKey.valueNum = 1;
1169
1170 if ( (eStatus = UserFeatureQuery(pKeyList, &NewKey)) == MOS_STATUS_SUCCESS )
1171 {
1172 if(uiValueType != nullptr)
1173 {
1174 *uiValueType = NewKey.pValueArray[0].ulValueType;
1175 }
1176 if (nDataSize != nullptr)
1177 {
1178 *nDataSize = NewKey.pValueArray[0].ulValueLen;
1179 }
1180 }
1181
1182 return eStatus;
1183 }
1184
UserFeatureGetKeyIdbyName(const char * pcKeyName,void ** pUFKey)1185 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureGetKeyIdbyName(const char *pcKeyName, void **pUFKey)
1186 {
1187 MOS_PUF_KEYLIST pKeyList;
1188 int32_t iResult;
1189 MOS_STATUS eStatus;
1190 MOS_PUF_KEYLIST pTempNode;
1191
1192 pKeyList = MosUtilitiesSpecificNext::m_ufKeyList;
1193 iResult = -1;
1194
1195 eStatus = MOS_STATUS_INVALID_PARAMETER;
1196
1197 for(pTempNode=pKeyList; pTempNode; pTempNode=pTempNode->pNext)
1198 {
1199 iResult = strcmp(pTempNode->pElem->pcKeyName, pcKeyName);
1200 if ( iResult == 0 )
1201 {
1202 *pUFKey = pTempNode->pElem->UFKey;
1203 eStatus = MOS_STATUS_SUCCESS;
1204 break;
1205 }
1206 }
1207
1208 return eStatus;
1209 }
1210
UserFeatureGetKeyNamebyId(void * UFKey,char * pcKeyName)1211 MOS_STATUS MosUtilitiesSpecificNext::UserFeatureGetKeyNamebyId(void *UFKey, char *pcKeyName)
1212 {
1213 MOS_PUF_KEYLIST pKeyList;
1214 MOS_PUF_KEYLIST pTempNode;
1215 MOS_STATUS eStatus;
1216
1217 pKeyList = MosUtilitiesSpecificNext::m_ufKeyList;
1218
1219 switch((uintptr_t)UFKey)
1220 {
1221 case UFKEY_INTERNAL:
1222 MosUtilities::MosSecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_INTERNAL);
1223 eStatus = MOS_STATUS_SUCCESS;
1224 break;
1225 case UFKEY_EXTERNAL:
1226 MosUtilities::MosSecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_EXTERNAL);
1227 eStatus = MOS_STATUS_SUCCESS;
1228 break;
1229 default:
1230 eStatus = MOS_STATUS_UNKNOWN;
1231
1232 for(pTempNode=pKeyList;pTempNode;pTempNode=pTempNode->pNext)
1233 {
1234 if(pTempNode->pElem->UFKey == UFKey)
1235 {
1236 MosUtilities::MosSecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, pTempNode->pElem->pcKeyName);
1237 eStatus = MOS_STATUS_SUCCESS;
1238 break;
1239 }
1240 }
1241 break;
1242 }
1243
1244 return eStatus;
1245
1246 }
1247
MosUserFeatureOpenKeyFile(void * UFKey,const char * lpSubKey,uint32_t ulOptions,uint32_t samDesired,void ** phkResult)1248 MOS_STATUS MosUtilitiesSpecificNext::MosUserFeatureOpenKeyFile(
1249 void *UFKey,
1250 const char *lpSubKey,
1251 uint32_t ulOptions, // reserved
1252 uint32_t samDesired,
1253 void **phkResult)
1254 {
1255 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
1256 MOS_STATUS iRet;
1257 uintptr_t h_key = (uintptr_t)UFKey;
1258 MOS_UNUSED(ulOptions);
1259 MOS_UNUSED(samDesired);
1260
1261 if((h_key == 0) /*|| (lpSubKey == nullptr)*/ || (phkResult == nullptr)) //[SH]: subkey can be NULL???
1262 {
1263 return MOS_STATUS_INVALID_PARAMETER;
1264 }
1265
1266 MosUtilities::MosZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH*sizeof(char));
1267 switch(h_key)
1268 {
1269 case UFKEY_INTERNAL:
1270 MosUtilities::MosSecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_INTERNAL);
1271 break;
1272 case UFKEY_EXTERNAL:
1273 MosUtilities::MosSecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_EXTERNAL);
1274 break;
1275 default:
1276 break;
1277 }
1278
1279 MosUtilities::MosSecureStrcat(pcKeyName, sizeof(pcKeyName), lpSubKey);
1280 iRet = UserFeatureGetKeyIdbyName(pcKeyName, phkResult);
1281
1282 return iRet;
1283 }
1284
MosUserFeatureGetValueFile(void * UFKey,const char * lpSubKey,const char * lpValue,uint32_t dwFlags,uint32_t * pdwType,void * pvData,uint32_t * pcbData)1285 MOS_STATUS MosUtilitiesSpecificNext::MosUserFeatureGetValueFile(
1286 void *UFKey,
1287 const char *lpSubKey,
1288 const char *lpValue,
1289 uint32_t dwFlags,
1290 uint32_t *pdwType,
1291 void *pvData,
1292 uint32_t *pcbData)
1293 {
1294 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
1295 MOS_STATUS eStatus;
1296 MOS_UNUSED(dwFlags);
1297
1298 if(UFKey == nullptr)
1299 {
1300 return MOS_STATUS_INVALID_PARAMETER;
1301 }
1302
1303 eStatus = MOS_STATUS_UNKNOWN;
1304 MosUtilities::MosZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH * sizeof(char));
1305 if ( (eStatus = UserFeatureGetKeyNamebyId(UFKey,pcKeyName)) != MOS_STATUS_SUCCESS)
1306 {
1307 return eStatus;
1308 }
1309
1310 if(lpSubKey != nullptr)
1311 {
1312 MosUtilities::MosSecureStrcat(pcKeyName, sizeof(pcKeyName), lpSubKey);
1313 }
1314 eStatus = UserFeatureQueryValue(pcKeyName,
1315 lpValue,
1316 (uint32_t*)pdwType,
1317 pvData,
1318 (int32_t*)pcbData);
1319
1320 return eStatus;
1321 }
1322
MosUserFeatureSetValueExFile(void * UFKey,const char * lpValueName,uint32_t Reserved,uint32_t dwType,uint8_t * lpData,uint32_t cbData)1323 MOS_STATUS MosUtilitiesSpecificNext::MosUserFeatureSetValueExFile(
1324 void *UFKey,
1325 const char *lpValueName,
1326 uint32_t Reserved,
1327 uint32_t dwType,
1328 uint8_t *lpData,
1329 uint32_t cbData)
1330 {
1331 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
1332 MOS_STATUS eStatus;
1333 MOS_UNUSED(Reserved);
1334
1335 if (UFKey == nullptr)
1336 {
1337 return MOS_STATUS_INVALID_PARAMETER;
1338 }
1339 MosUtilities::MosZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH*sizeof(char));
1340 if ((eStatus = UserFeatureGetKeyNamebyId(UFKey,pcKeyName)) != MOS_STATUS_SUCCESS)
1341 {
1342 return eStatus;
1343 }
1344
1345 eStatus = UserFeatureSetValue(pcKeyName,lpValueName,dwType,lpData,cbData);
1346
1347 return eStatus;
1348 }
1349
MosOsUtilitiesInit(MediaUserSettingSharedPtr userSettingPtr)1350 MOS_STATUS MosUtilities::MosOsUtilitiesInit(MediaUserSettingSharedPtr userSettingPtr)
1351 {
1352 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1353
1354 // lock mutex to avoid multi init in multi-threading env
1355 m_mutexLock.Lock();
1356
1357 #if (_DEBUG || _RELEASE_INTERNAL)
1358 // Get use user feature file from env, instead of default.
1359 FILE* fp = nullptr;
1360 static char* tmpFile = getenv("GFX_FEATURE_FILE");
1361
1362 if (tmpFile != nullptr)
1363 {
1364 if ((fp = fopen(tmpFile, "r")) != nullptr)
1365 {
1366 MosUtilitiesSpecificNext::m_szUserFeatureFile = tmpFile;
1367 fclose(fp);
1368 MOS_OS_NORMALMESSAGE("using %s for USER_FEATURE_FILE", MosUtilitiesSpecificNext::m_szUserFeatureFile);
1369 }
1370 else
1371 {
1372 MOS_OS_ASSERTMESSAGE("Can't open %s for USER_FEATURE_FILE!!!", tmpFile);
1373 m_mutexLock.Unlock();
1374 return MOS_STATUS_FILE_NOT_FOUND;
1375 }
1376 }
1377 #endif
1378
1379 //The user setting is device based, no need to guard with the reference count.
1380 //It will be destroyed in media context termiation.
1381 eStatus = MosUserSetting::InitMosUserSetting(userSettingPtr);
1382
1383 if (m_mosUtilInitCount == 0)
1384 {
1385 //Init MOS User Feature Key from mos desc table
1386 MosUtilitiesSpecificNext::UserFeatureDumpFile(MosUtilitiesSpecificNext::m_szUserFeatureFile, &MosUtilitiesSpecificNext::m_ufKeyList);
1387 MosDeclareUserFeature();
1388
1389 #if MOS_MESSAGES_ENABLED
1390 // Initialize MOS message params structure and HLT
1391 MosUtilDebug::MosMessageInit(userSettingPtr);
1392 #endif // MOS_MESSAGES_ENABLED
1393 if (m_mosMemAllocCounter &&
1394 m_mosMemAllocCounterGfx &&
1395 m_mosMemAllocFakeCounter)
1396 {
1397 *m_mosMemAllocCounter = 0;
1398 *m_mosMemAllocFakeCounter = 0;
1399 *m_mosMemAllocCounterGfx = 0;
1400 }
1401 else
1402 {
1403 MOS_OS_ASSERTMESSAGE("MemNinja count pointers are nullptr");
1404 }
1405
1406 MosTraceEventInit();
1407 }
1408 m_mosUtilInitCount++;
1409
1410 m_mutexLock.Unlock();
1411 return eStatus;
1412 }
1413
MosOsUtilitiesClose(MediaUserSettingSharedPtr userSettingPtr)1414 MOS_STATUS MosUtilities::MosOsUtilitiesClose(MediaUserSettingSharedPtr userSettingPtr)
1415 {
1416 int32_t memoryCounter = 0;
1417 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1418
1419 // lock mutex to avoid multi close in multi-threading env
1420 m_mutexLock.Lock();
1421 m_mosUtilInitCount--;
1422 if (m_mosUtilInitCount == 0)
1423 {
1424 MosTraceEventClose();
1425 if (m_mosMemAllocCounter &&
1426 m_mosMemAllocCounterGfx &&
1427 m_mosMemAllocFakeCounter)
1428 {
1429 *m_mosMemAllocCounter -= *m_mosMemAllocFakeCounter;
1430 memoryCounter = *m_mosMemAllocCounter + *m_mosMemAllocCounterGfx;
1431 m_mosMemAllocCounterNoUserFeature = *m_mosMemAllocCounter;
1432 m_mosMemAllocCounterNoUserFeatureGfx = *m_mosMemAllocCounterGfx;
1433 MOS_OS_VERBOSEMESSAGE("MemNinja leak detection end");
1434 ReportUserSetting(
1435 userSettingPtr,
1436 __MEDIA_USER_FEATURE_VALUE_MEMNINJA_COUNTER,
1437 memoryCounter,
1438 MediaUserSetting::Group::Device);
1439 }
1440 MosDestroyUserFeature();
1441
1442 #if (_DEBUG || _RELEASE_INTERNAL)
1443 // MOS maintains a reference counter,
1444 // so if there still is another active lib instance, logs would still be printed.
1445 MosUtilDebug::MosMessageClose();
1446 #endif
1447 MosUtilitiesSpecificNext::UserFeatureDumpDataToFile(MosUtilitiesSpecificNext::m_szUserFeatureFile, MosUtilitiesSpecificNext::m_ufKeyList);
1448 MosUtilitiesSpecificNext::UserFeatureFreeKeyList(MosUtilitiesSpecificNext::m_ufKeyList);
1449 MosUtilitiesSpecificNext::m_ufKeyList = nullptr;
1450 }
1451 m_mutexLock.Unlock();
1452 return eStatus;
1453 }
1454
MosUserFeatureOpenKey(void * ufKey,const char * lpSubKey,uint32_t ulOptions,uint32_t samDesired,void ** phkResult,MOS_USER_FEATURE_KEY_PATH_INFO * ufInfo)1455 MOS_STATUS MosUtilities::MosUserFeatureOpenKey(
1456 void *ufKey,
1457 const char *lpSubKey,
1458 uint32_t ulOptions,
1459 uint32_t samDesired,
1460 void **phkResult,
1461 MOS_USER_FEATURE_KEY_PATH_INFO *ufInfo)
1462 {
1463 MOS_UNUSED(ufInfo);
1464
1465 return MosUtilitiesSpecificNext::MosUserFeatureOpenKeyFile(ufKey, lpSubKey, ulOptions, samDesired, phkResult);
1466 }
1467
MosUserFeatureCloseKey(void * ufKey)1468 MOS_STATUS MosUtilities::MosUserFeatureCloseKey(void *ufKey)
1469 {
1470 MOS_UNUSED(ufKey);
1471 //always return success, because we actually dong't have a key opened.
1472 return MOS_STATUS_SUCCESS;
1473 }
1474
MosUserFeatureGetValue(void * UFKey,const char * lpSubKey,const char * lpValue,uint32_t dwFlags,uint32_t * pdwType,void * pvData,uint32_t * pcbData)1475 MOS_STATUS MosUtilities::MosUserFeatureGetValue(
1476 void *UFKey,
1477 const char *lpSubKey,
1478 const char *lpValue,
1479 uint32_t dwFlags,
1480 uint32_t *pdwType,
1481 void *pvData,
1482 uint32_t *pcbData)
1483 {
1484 return MosUtilitiesSpecificNext::MosUserFeatureGetValueFile(UFKey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData);
1485
1486 }
1487
MosUserFeatureQueryValueEx(void * UFKey,char * lpValueName,uint32_t * lpReserved,uint32_t * lpType,char * lpData,uint32_t * lpcbData)1488 MOS_STATUS MosUtilities::MosUserFeatureQueryValueEx(
1489 void *UFKey,
1490 char *lpValueName,
1491 uint32_t *lpReserved,
1492 uint32_t *lpType,
1493 char *lpData,
1494 uint32_t *lpcbData)
1495 {
1496 MOS_UNUSED(lpReserved);
1497 return MosUserFeatureGetValue(UFKey, "", lpValueName, 0, lpType, lpData, lpcbData);
1498 }
1499
MosUserFeatureSetValueEx(void * UFKey,const char * lpValueName,uint32_t Reserved,uint32_t dwType,uint8_t * lpData,uint32_t cbData)1500 MOS_STATUS MosUtilities::MosUserFeatureSetValueEx(
1501 void *UFKey,
1502 const char *lpValueName,
1503 uint32_t Reserved,
1504 uint32_t dwType,
1505 uint8_t *lpData,
1506 uint32_t cbData)
1507 {
1508 if (dwType == UF_SZ || dwType == UF_MULTI_SZ)
1509 {
1510 if (lpData == nullptr || strlen((const char*)lpData) == 0)
1511 {
1512 MOS_OS_NORMALMESSAGE("NULL string, skip to report");
1513 return MOS_STATUS_SUCCESS;
1514 }
1515 }
1516
1517 return MosUtilitiesSpecificNext::MosUserFeatureSetValueExFile(UFKey, lpValueName, Reserved, dwType, lpData, cbData);
1518 }
1519
MosUserFeatureNotifyChangeKeyValue(void * UFKey,int32_t bWatchSubtree,HANDLE hEvent,int32_t fAsynchronous)1520 MOS_STATUS MosUtilities::MosUserFeatureNotifyChangeKeyValue(
1521 void *UFKey,
1522 int32_t bWatchSubtree,
1523 HANDLE hEvent,
1524 int32_t fAsynchronous)
1525 {
1526 key_t key;
1527 int32_t semid;
1528 struct sembuf operation[1] ;
1529
1530 key = ftok(MosUtilitiesSpecificNext::m_szUserFeatureFile, 1);
1531 semid = semget(key,1,0);
1532 //change semaphore
1533 operation[0].sem_op = 1;
1534 operation[0].sem_num = 0;
1535 operation[0].sem_flg = SEM_UNDO;
1536 semop(semid, operation, 1);
1537
1538 return MOS_STATUS_SUCCESS;
1539 }
1540
MosInitializeReg(RegBufferMap & regBufferMap)1541 MOS_STATUS MosUtilities::MosInitializeReg(RegBufferMap ®BufferMap)
1542 {
1543 MOS_STATUS status = MOS_STATUS_SUCCESS;
1544
1545 std::ifstream regStream;
1546 try
1547 {
1548 regStream.open(USER_FEATURE_FILE_NEXT);
1549 if (regStream.good())
1550 {
1551 std::string id = "";
1552 while(!regStream.eof())
1553 {
1554 std::string line = "";
1555 std::getline(regStream, line);
1556 auto endIndex = line.find("\r");
1557 if(endIndex != std::string::npos)
1558 {
1559 line = line.substr(0, endIndex);
1560 }
1561 if (std::string::npos != line.find(USER_SETTING_CONFIG_PATH))
1562 {
1563 id = USER_SETTING_CONFIG_PATH;
1564 }
1565 else if (std::string::npos != line.find(USER_SETTING_REPORT_PATH))
1566 {
1567 id = USER_SETTING_REPORT_PATH;
1568 }
1569 else if (line.find("]") != std::string::npos)
1570 {
1571 auto mkPos = line.find_last_of("]");
1572 id = line.substr(0, mkPos+1);
1573 }
1574 else
1575 {
1576 if (id == USER_SETTING_REPORT_PATH)
1577 {
1578 continue;
1579 }
1580
1581 std::size_t pos = line.find("=");
1582 if (std::string::npos != pos && !id.empty())
1583 {
1584 std::string name = line.substr(0,pos);
1585 std::string value = line.substr(pos+1);
1586 if (name.size() > 0 && value.size() > 0)
1587 {
1588 auto &keys = regBufferMap[id];
1589 keys[name] = value;
1590 }
1591 }
1592 }
1593 }
1594
1595 }
1596 }
1597 catch(const std::exception &e)
1598 {
1599 status = MOS_STATUS_FILE_OPEN_FAILED;
1600 }
1601
1602 regStream.close();
1603
1604 return status;
1605 }
1606
MosUninitializeReg(RegBufferMap & regBufferMap)1607 MOS_STATUS MosUtilities::MosUninitializeReg(RegBufferMap ®BufferMap)
1608 {
1609 MOS_STATUS status = MOS_STATUS_SUCCESS;
1610
1611 if (regBufferMap.size() == 0)
1612 {
1613 return MOS_STATUS_SUCCESS;
1614 }
1615
1616 auto iter = regBufferMap.find(USER_SETTING_REPORT_PATH);
1617 // No need to write the user setting files if no session [report].
1618 // The session [config] is read only.
1619 if(iter == regBufferMap.end() || iter->second.size() == 0)
1620 {
1621 MOS_OS_NORMALMESSAGE("no report session");
1622 return MOS_STATUS_SUCCESS;
1623 }
1624
1625 std::ofstream regStream;
1626 try
1627 {
1628 // For release version: writes to the file if it exists,
1629 // skips if it does not exist
1630 // For other version: always writes to the file
1631 #if(_RELEASE)
1632 std::ifstream regFile(USER_FEATURE_FILE_NEXT);
1633 if (regFile.good())
1634 {
1635 regFile.close();
1636 regStream.open(USER_FEATURE_FILE_REPORT, std::ios::out | std::ios::trunc);
1637 }
1638 else
1639 {
1640 regFile.close();
1641 return status;
1642 }
1643 #else
1644 regStream.open(USER_FEATURE_FILE_REPORT, std::ios::out | std::ios::trunc);
1645 #endif
1646 if (regStream.good())
1647 {
1648 regStream << iter->first << "\n";
1649
1650 auto &keys = iter->second;
1651 for (auto key: keys)
1652 {
1653 auto name = key.first;
1654 regStream << key.first << "=" << key.second << "\n";
1655 }
1656
1657 keys.clear();
1658 regStream << std::endl;
1659 regBufferMap.clear();
1660 regStream.flush();
1661 }
1662 }
1663 catch(const std::exception &e)
1664 {
1665 status = MOS_STATUS_FILE_WRITE_FAILED;
1666 }
1667
1668 regStream.close();
1669 return status;
1670 }
1671
MosCreateRegKey(UFKEY_NEXT keyHandle,const std::string & subKey,uint32_t samDesired,PUFKEY_NEXT key,RegBufferMap & regBufferMap)1672 MOS_STATUS MosUtilities::MosCreateRegKey(
1673 UFKEY_NEXT keyHandle,
1674 const std::string &subKey,
1675 uint32_t samDesired,
1676 PUFKEY_NEXT key,
1677 RegBufferMap ®BufferMap)
1678 {
1679 MOS_UNUSED(keyHandle);
1680 MOS_UNUSED(samDesired);
1681 MOS_OS_CHK_NULL_RETURN(key);
1682 auto ret = regBufferMap.find(subKey);
1683
1684 if (ret == regBufferMap.end())
1685 {
1686 regBufferMap[subKey] = {};
1687 }
1688
1689 *key = subKey;
1690 return MOS_STATUS_SUCCESS;
1691 }
1692
MosOpenRegKey(UFKEY_NEXT keyHandle,const std::string & subKey,uint32_t samDesired,PUFKEY_NEXT key,RegBufferMap & regBufferMap)1693 MOS_STATUS MosUtilities::MosOpenRegKey(
1694 UFKEY_NEXT keyHandle,
1695 const std::string &subKey,
1696 uint32_t samDesired,
1697 PUFKEY_NEXT key,
1698 RegBufferMap ®BufferMap)
1699 {
1700 std::string tempSubKey = subKey;
1701
1702 if (subKey.find_first_of("\\") != std::string::npos)
1703 {
1704 tempSubKey = subKey.substr(1);
1705 }
1706
1707 if (tempSubKey.find_first_of("[") == std::string::npos)
1708 {
1709 tempSubKey = "[" + tempSubKey + "]";
1710 }
1711 return MosCreateRegKey(keyHandle, tempSubKey, samDesired, key, regBufferMap);
1712 }
1713
MosCloseRegKey(UFKEY_NEXT keyHandle)1714 MOS_STATUS MosUtilities::MosCloseRegKey(
1715 UFKEY_NEXT keyHandle)
1716 {
1717 MOS_UNUSED(keyHandle);
1718 return MOS_STATUS_SUCCESS;
1719 }
1720
MosReadEnvVariable(const std::string & envName,MOS_USER_FEATURE_VALUE_TYPE defaultType,MediaUserSetting::Value & data)1721 MOS_STATUS MosUtilities::MosReadEnvVariable(
1722 const std::string &envName,
1723 MOS_USER_FEATURE_VALUE_TYPE defaultType,
1724 MediaUserSetting::Value &data)
1725 {
1726 char *retVal = getenv(envName.c_str());
1727 if (retVal != nullptr)
1728 {
1729 std::string strData = retVal;
1730 auto status = StrToMediaUserSettingValue(strData, defaultType, data);
1731 return status;
1732 }
1733
1734 return MOS_STATUS_INVALID_PARAMETER;
1735 }
1736
MosEnvVariableEqual(const std::string envName,const std::string targetVal)1737 bool MosUtilities::MosEnvVariableEqual(
1738 const std::string envName,
1739 const std::string targetVal)
1740 {
1741 char *retVal = getenv(envName.c_str());
1742 bool res = false;
1743 if (retVal != nullptr)
1744 {
1745 res = strcmp(retVal, targetVal.c_str()) ? false : true;
1746 }
1747 return res;
1748 }
1749
MosGetRegValue(UFKEY_NEXT keyHandle,const std::string & valueName,MOS_USER_FEATURE_VALUE_TYPE defaultType,MediaUserSetting::Value & data,RegBufferMap & regBufferMap)1750 MOS_STATUS MosUtilities::MosGetRegValue(
1751 UFKEY_NEXT keyHandle,
1752 const std::string &valueName,
1753 MOS_USER_FEATURE_VALUE_TYPE defaultType,
1754 MediaUserSetting::Value &data,
1755 RegBufferMap ®BufferMap)
1756 {
1757 MOS_STATUS status = MOS_STATUS_SUCCESS;
1758
1759 if (regBufferMap.end() == regBufferMap.find(keyHandle))
1760 {
1761 return MOS_STATUS_USER_FEATURE_KEY_OPEN_FAILED;
1762 }
1763
1764 try
1765 {
1766 auto keys = regBufferMap[keyHandle];
1767 auto it = keys.find(valueName);
1768 if (it == keys.end())
1769 {
1770 return MOS_STATUS_USER_FEATURE_KEY_OPEN_FAILED;
1771 }
1772 status = MosUtilities::StrToMediaUserSettingValue(it->second, defaultType, data);
1773 }
1774 catch(const std::exception &e)
1775 {
1776 status = MOS_STATUS_INVALID_PARAMETER;
1777 }
1778
1779 return status;
1780 }
1781
MosPrintCPUAllocateMemory(int32_t event_id,int32_t level,int32_t param_id_1,int64_t value_1,int32_t param_id_2,int64_t value_2,const char * funName,const char * fileName,int32_t line)1782 MOS_STATUS MosUtilities::MosPrintCPUAllocateMemory(int32_t event_id, int32_t level, int32_t param_id_1, int64_t value_1, int32_t param_id_2, int64_t value_2,
1783 const char *funName, const char *fileName, int32_t line)
1784 {
1785 #if (_RELEASE_INTERNAL)
1786 if (MOS_IS_MEMORY_FOOT_PRINT_ENABLED())
1787 {
1788 MosAtomicIncrement(m_mosMemAllocIndex);
1789 MT_LOG3(event_id, level, param_id_1, value_1, MT_MEMORY_INDEX, *MosUtilities::m_mosMemAllocIndex, param_id_2, value_2);
1790 }
1791
1792 #endif
1793 return MOS_STATUS_SUCCESS;
1794 }
1795
MosPrintCPUDestroyMemory(int32_t event_id,int32_t level,int32_t param_id_1,int64_t value_1,const char * funName,const char * fileName,int32_t line)1796 MOS_STATUS MosUtilities::MosPrintCPUDestroyMemory(int32_t event_id, int32_t level, int32_t param_id_1, int64_t value_1,
1797 const char *funName, const char *fileName, int32_t line)
1798 {
1799 #if (_RELEASE_INTERNAL)
1800 if (MOS_IS_MEMORY_FOOT_PRINT_ENABLED())
1801 {
1802 MosAtomicDecrement(m_mosMemAllocIndex);
1803 MT_LOG2(event_id, level, param_id_1, value_1, MT_MEMORY_INDEX, *MosUtilities::m_mosMemAllocIndex);
1804 }
1805 #endif
1806 return MOS_STATUS_SUCCESS;
1807 }
1808
MosSetRegValue(UFKEY_NEXT keyHandle,const std::string & valueName,const MediaUserSetting::Value & data,RegBufferMap & regBufferMap)1809 MOS_STATUS MosUtilities::MosSetRegValue(
1810 UFKEY_NEXT keyHandle,
1811 const std::string &valueName,
1812 const MediaUserSetting::Value &data,
1813 RegBufferMap ®BufferMap)
1814 {
1815 if (regBufferMap.end() == regBufferMap.find(keyHandle))
1816 {
1817 return MOS_STATUS_INVALID_PARAMETER;
1818 }
1819
1820 MOS_STATUS status = MOS_STATUS_SUCCESS;
1821 try
1822 {
1823 auto &keys = regBufferMap[keyHandle];
1824
1825 keys[valueName] = data.ConstString();
1826 }
1827 catch(const std::exception &e)
1828 {
1829 status = MOS_STATUS_INVALID_PARAMETER;
1830 }
1831
1832 return status;
1833 }
1834
MosCreateEventEx(void * lpEventAttributes,char * lpName,uint32_t dwFlags)1835 HANDLE MosUtilities::MosCreateEventEx(
1836 void *lpEventAttributes,
1837 char *lpName,
1838 uint32_t dwFlags)
1839 {
1840 int32_t semid;
1841 key_t key;
1842 union semun
1843 {
1844 int32_t val;
1845 struct semid_ds *Buf;
1846 unsigned short *array;
1847 } semctl_arg;
1848
1849 semid = 0;
1850
1851 //Generate a unique key, U can also supply a value instead
1852 key = ftok(MosUtilitiesSpecificNext::m_szUserFeatureFile, 1);
1853 semid = semget(key, 1, 0666 | IPC_CREAT );
1854 semctl_arg.val = 0; //Setting semval to 0
1855 semctl(semid, 0, SETVAL, semctl_arg);
1856
1857 HANDLE ret = reinterpret_cast<HANDLE>(semid);
1858
1859 return ret;
1860 }
1861
MosUserFeatureWaitForSingleObject(PTP_WAIT * phNewWaitObject,HANDLE hObject,void * Callback,void * Context)1862 int32_t MosUtilities::MosUserFeatureWaitForSingleObject(
1863 PTP_WAIT* phNewWaitObject,
1864 HANDLE hObject,
1865 void *Callback,
1866 void *Context)
1867 {
1868 int32_t iRet;
1869 int32_t semid;
1870 struct sembuf operation[1];
1871 pid_t pid;
1872 MOS_UserFeatureCallback pCallback;
1873 LARGE_INTEGER largeInteger;
1874
1875 pCallback = (MOS_UserFeatureCallback)Callback;
1876
1877 iRet = 0;
1878
1879 largeInteger.QuadPart = (int64_t)hObject;
1880
1881 semid = largeInteger.u.LowPart;
1882
1883 if ((pid=fork()) == -1)
1884 {
1885 printf("error\n");
1886 }
1887 else if(pid == 0)
1888 {
1889 while(1)
1890 {
1891 operation[0].sem_op = -1;
1892 operation[0].sem_num = 0;
1893 //now waiting
1894 semop(semid, operation, 1);
1895 pCallback(Context, 0);
1896 }
1897 exit(0);
1898 }
1899 else
1900 {
1901 iRet = pid;
1902 }
1903
1904 *phNewWaitObject = reinterpret_cast<PTP_WAIT>(iRet);
1905
1906 return (iRet != 0);
1907 }
1908
MosUnregisterWaitEx(PTP_WAIT hWaitHandle)1909 int32_t MosUtilities::MosUnregisterWaitEx(PTP_WAIT hWaitHandle)
1910 {
1911 int32_t iPid;
1912 LARGE_INTEGER largeInteger;
1913
1914 largeInteger.QuadPart = (int64_t)hWaitHandle;
1915
1916 iPid = largeInteger.u.LowPart;
1917 kill(iPid, SIGKILL);
1918 return true;
1919 }
1920
1921 #if (_DEBUG || _RELEASE_INTERNAL)
MosGetApoMosEnabledUserFeatureFile()1922 MOS_STATUS MosUtilities::MosGetApoMosEnabledUserFeatureFile()
1923 {
1924 // Get use user feature file from env, instead of default.
1925 FILE * fp = nullptr;
1926 static char *tmpFile = getenv("GFX_FEATURE_FILE");
1927
1928 if (tmpFile != nullptr)
1929 {
1930 if ((fp = fopen(tmpFile, "r")) != nullptr)
1931 {
1932 if (MosUtilitiesSpecificNext::m_szUserFeatureFile != tmpFile)
1933 MosUtilitiesSpecificNext::m_szUserFeatureFile = tmpFile;
1934 fclose(fp);
1935 MOS_OS_NORMALMESSAGE("using %s for USER_FEATURE_FILE", MosUtilitiesSpecificNext::m_szUserFeatureFile);
1936 }
1937 else
1938 {
1939 MOS_OS_ASSERTMESSAGE("Can't open %s for USER_FEATURE_FILE!!!", tmpFile);
1940 return MOS_STATUS_FILE_NOT_FOUND;
1941 }
1942 }
1943 return MOS_STATUS_SUCCESS;
1944 }
1945 #endif
1946
MosReadMediaSoloEnabledUserFeature(bool & mediasoloEnabled)1947 MOS_STATUS MosUtilities::MosReadMediaSoloEnabledUserFeature(bool &mediasoloEnabled)
1948 {
1949 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1950
1951 #if MOS_MEDIASOLO_SUPPORTED
1952
1953 void * UFKey = nullptr;
1954 uint32_t dwUFSize = 0;
1955 uint32_t data = 0;
1956
1957 #if (_DEBUG || _RELEASE_INTERNAL)
1958 eStatus = MosGetApoMosEnabledUserFeatureFile();
1959 if (eStatus != MOS_STATUS_SUCCESS)
1960 {
1961 MOS_OS_NORMALMESSAGE("Failed to get user feature file, error status %d.", eStatus);
1962 return eStatus;
1963 }
1964 #endif
1965
1966 eStatus = MosUserFeatureOpen(
1967 MOS_USER_FEATURE_TYPE_USER,
1968 __MEDIA_USER_FEATURE_SUBKEY_INTERNAL,
1969 KEY_READ,
1970 &UFKey,
1971 nullptr);
1972
1973 if (eStatus != MOS_STATUS_SUCCESS)
1974 {
1975 MOS_OS_NORMALMESSAGE("Failed to open user feature key , error status %d.", eStatus);
1976 return eStatus;
1977 }
1978
1979 eStatus = MosUserFeatureGetValue(
1980 UFKey,
1981 nullptr,
1982 __MEDIA_USER_FEATURE_VALUE_MEDIASOLO_ENABLE,
1983 RRF_RT_UF_DWORD,
1984 nullptr,
1985 &data,
1986 &dwUFSize);
1987
1988 if (eStatus == MOS_STATUS_SUCCESS && data > 0)
1989 {
1990 mediasoloEnabled = true;
1991 }
1992 MosUserFeatureCloseKey(UFKey);
1993
1994 #endif
1995 return eStatus;
1996 }
1997
MosReadApoDdiEnabledUserFeature(uint32_t & userfeatureValue,char * path,MediaUserSettingSharedPtr userSettingPtr)1998 MOS_STATUS MosUtilities::MosReadApoDdiEnabledUserFeature(uint32_t &userfeatureValue, char *path, MediaUserSettingSharedPtr userSettingPtr)
1999 {
2000 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2001 MOS_UNUSED(path);
2002
2003 uint32_t enableApoDdi = 0;
2004 eStatus = ReadUserSetting(
2005 userSettingPtr,
2006 enableApoDdi,
2007 "ApoDdiEnable",
2008 MediaUserSetting::Group::Device);
2009
2010 if (eStatus != MOS_STATUS_SUCCESS)
2011 {
2012 // It could be there is no this use feature key.
2013 MOS_OS_NORMALMESSAGE("Failed to read ApoDdiEnable user feature key value, error status %d", eStatus);
2014 }
2015 userfeatureValue = enableApoDdi ? true : false;
2016 return eStatus;
2017 }
2018
MosReadApoMosEnabledUserFeature(uint32_t & userfeatureValue,char * path,MediaUserSettingSharedPtr userSettingPtr)2019 MOS_STATUS MosUtilities::MosReadApoMosEnabledUserFeature(uint32_t &userfeatureValue, char *path, MediaUserSettingSharedPtr userSettingPtr)
2020 {
2021 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2022 MOS_USER_FEATURE_VALUE_DATA userFeatureData = {};
2023 MOS_UNUSED(path);
2024
2025
2026 uint32_t enableApoMos = 0;
2027 eStatus = ReadUserSetting(
2028 userSettingPtr,
2029 enableApoMos,
2030 "ApoMosEnable",
2031 MediaUserSetting::Group::Device);
2032
2033 if (eStatus != MOS_STATUS_SUCCESS)
2034 {
2035 // It could be there is no this use feature key.
2036 MOS_OS_NORMALMESSAGE("Failed to read ApoMosEnable user feature key value, error status %d", eStatus);
2037 }
2038 userfeatureValue = enableApoMos ? true : false;
2039 return eStatus;
2040 }
2041
MosUserFeatureParsePath(PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,char * const pInputPath,PMOS_USER_FEATURE_TYPE pUserFeatureType,char ** ppSubPath)2042 MOS_STATUS MosUtilities::MosUserFeatureParsePath(
2043 PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,
2044 char * const pInputPath,
2045 PMOS_USER_FEATURE_TYPE pUserFeatureType,
2046 char **ppSubPath)
2047 {
2048 char *pValue;
2049 MOS_USER_FEATURE_TYPE UserFeatureType;
2050 size_t uUFKeyLen;
2051 size_t uHKeyLen;
2052 size_t uValLen;
2053 size_t uSepLen;
2054 MOS_UNUSED(pOsUserFeatureInterface);
2055
2056 //-------------------------------------------
2057 // the UserFeature interface is not currently an actual interface, just a collection
2058 // of functions, so pOsUserFeatureInterface will always be nullptr until this changes
2059 //MOS_OS_ASSERT(pOsUserFeatureInterface);
2060 MOS_OS_ASSERT(pInputPath);
2061 MOS_OS_ASSERT(strlen(pInputPath) > 0);
2062 MOS_OS_ASSERT(pUserFeatureType);
2063 MOS_OS_ASSERT(ppSubPath);
2064 //-------------------------------------------
2065
2066 pValue = nullptr;
2067
2068 pValue = strstr(pInputPath, MOS_UF_SEPARATOR);
2069
2070 if (!pValue)
2071 {
2072 MOS_OS_ASSERTMESSAGE("Invalid user feature key %s.", pInputPath);
2073 return MOS_STATUS_INVALID_PARAMETER;
2074 }
2075
2076 uUFKeyLen = strlen(pInputPath);
2077 uValLen = strlen(pValue);
2078 uSepLen = strlen(MOS_UF_SEPARATOR);
2079 uHKeyLen = uUFKeyLen - uValLen;
2080
2081 if (uHKeyLen == 0)
2082 {
2083 MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. Path separator in the begining.", pInputPath);
2084 return MOS_STATUS_INVALID_PARAMETER;
2085 }
2086
2087 if (uValLen <= uSepLen)
2088 {
2089 MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. No value after path separator.", pInputPath);
2090 return MOS_STATUS_INVALID_PARAMETER;
2091 }
2092
2093 if ((uHKeyLen == strlen(MOS_UFKEY_EXT)) &&
2094 (strncmp(pInputPath, MOS_UFKEY_EXT, uHKeyLen) == 0))
2095 {
2096 UserFeatureType = MOS_USER_FEATURE_TYPE_SYSTEM;
2097 }
2098 else if ((uHKeyLen == strlen(MOS_UFKEY_INT)) &&
2099 (strncmp(pInputPath, MOS_UFKEY_INT, uHKeyLen) == 0))
2100 {
2101 UserFeatureType = MOS_USER_FEATURE_TYPE_USER;
2102 }
2103 else
2104 {
2105 MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. Expected %s or %s.", pInputPath, MOS_UFKEY_EXT, MOS_UFKEY_INT);
2106 return MOS_STATUS_INVALID_PARAMETER;
2107 }
2108
2109 pValue = pValue + uSepLen;
2110
2111 *pUserFeatureType = UserFeatureType;
2112 *ppSubPath = pValue;
2113
2114 return MOS_STATUS_SUCCESS;
2115 }
2116
MosGetLogicalCoreNumber()2117 uint32_t MosUtilities::MosGetLogicalCoreNumber()
2118 {
2119 return sysconf(_SC_NPROCESSORS_CONF);
2120 }
2121
MosCreateThread(void * ThreadFunction,void * ThreadData)2122 MOS_THREADHANDLE MosUtilities::MosCreateThread(
2123 void *ThreadFunction,
2124 void *ThreadData)
2125 {
2126 MOS_THREADHANDLE Thread;
2127
2128 if (0 != pthread_create(&Thread, nullptr, (void *(*)(void *))ThreadFunction, ThreadData))
2129 {
2130 Thread = 0;
2131 MOS_OS_ASSERTMESSAGE("Create thread failed.");
2132 }
2133
2134 return Thread;
2135 }
2136
MosGetThreadId(MOS_THREADHANDLE hThread)2137 uint32_t MosUtilities::MosGetThreadId(
2138 MOS_THREADHANDLE hThread)
2139 {
2140 MOS_UNUSED(hThread);
2141 return 0;
2142 }
2143
MosGetCurrentThreadId()2144 uint32_t MosUtilities::MosGetCurrentThreadId()
2145 {
2146 return (uint32_t)pthread_self();
2147 }
2148
MosWaitThread(MOS_THREADHANDLE hThread)2149 MOS_STATUS MosUtilities::MosWaitThread(
2150 MOS_THREADHANDLE hThread)
2151 {
2152 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2153
2154 if (hThread == 0)
2155 {
2156 MOS_OS_ASSERTMESSAGE("MOS wait thread failed, invalid thread handle.");
2157 eStatus = MOS_STATUS_INVALID_PARAMETER;
2158 }
2159 else if (0 != pthread_join(hThread, nullptr))
2160 {
2161 MOS_OS_ASSERTMESSAGE("Failed to join thread.");
2162 eStatus = MOS_STATUS_UNKNOWN;
2163 }
2164
2165 return eStatus;
2166 }
2167
MosCreateMutex(uint32_t spinCount)2168 PMOS_MUTEX MosUtilities::MosCreateMutex(uint32_t spinCount)
2169 {
2170 PMOS_MUTEX pMutex;
2171 MOS_UNUSED(spinCount);
2172 pMutex = (PMOS_MUTEX)MOS_AllocMemory(sizeof(*pMutex));
2173 if (pMutex != nullptr)
2174 {
2175 if (pthread_mutex_init(pMutex, nullptr))
2176 {
2177 MOS_FreeMemory(pMutex);
2178 pMutex = nullptr;
2179 }
2180 }
2181
2182 return pMutex;
2183 }
2184
MosDestroyMutex(PMOS_MUTEX & pMutex)2185 MOS_STATUS MosUtilities::MosDestroyMutex(PMOS_MUTEX &pMutex)
2186 {
2187 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2188
2189 if (pMutex)
2190 {
2191 if (pthread_mutex_destroy(pMutex))
2192 {
2193 eStatus = MOS_STATUS_UNKNOWN;
2194 }
2195 MOS_FreeMemAndSetNull(pMutex);
2196 }
2197
2198 return eStatus;
2199 }
2200
MosLockMutex(PMOS_MUTEX pMutex)2201 MOS_STATUS MosUtilities::MosLockMutex(PMOS_MUTEX pMutex)
2202 {
2203 MOS_OS_CHK_NULL_RETURN(pMutex);
2204
2205 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2206
2207 if (pthread_mutex_lock(pMutex))
2208 {
2209 eStatus = MOS_STATUS_UNKNOWN;
2210 }
2211
2212 return eStatus;
2213 }
2214
MosUnlockMutex(PMOS_MUTEX pMutex)2215 MOS_STATUS MosUtilities::MosUnlockMutex(PMOS_MUTEX pMutex)
2216 {
2217 MOS_OS_CHK_NULL_RETURN(pMutex);
2218
2219 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2220
2221 if (pthread_mutex_unlock(pMutex))
2222 {
2223 eStatus = MOS_STATUS_UNKNOWN;
2224 }
2225
2226 return eStatus;
2227 }
2228
MosCreateSemaphore(uint32_t uiInitialCount,uint32_t uiMaximumCount)2229 PMOS_SEMAPHORE MosUtilities::MosCreateSemaphore(
2230 uint32_t uiInitialCount,
2231 uint32_t uiMaximumCount)
2232 {
2233 PMOS_SEMAPHORE pSemaphore = nullptr;
2234 MOS_UNUSED(uiMaximumCount);
2235
2236 pSemaphore = (PMOS_SEMAPHORE)MOS_AllocMemory(sizeof(*pSemaphore));
2237 if (!pSemaphore)
2238 return nullptr;
2239 if (sem_init(pSemaphore, 0, uiInitialCount))
2240 {
2241 MOS_SafeFreeMemory(pSemaphore);
2242 pSemaphore = nullptr;
2243 }
2244
2245 return pSemaphore;
2246 }
2247
MosDestroySemaphore(PMOS_SEMAPHORE & pSemaphore)2248 MOS_STATUS MosUtilities::MosDestroySemaphore(
2249 PMOS_SEMAPHORE &pSemaphore)
2250 {
2251 MOS_FreeMemAndSetNull(pSemaphore);
2252 return MOS_STATUS_SUCCESS;
2253 }
2254
MosWaitSemaphore(PMOS_SEMAPHORE pSemaphore,uint32_t uiMilliseconds)2255 MOS_STATUS MosUtilities::MosWaitSemaphore(
2256 PMOS_SEMAPHORE pSemaphore,
2257 uint32_t uiMilliseconds)
2258 {
2259 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2260
2261 if (uiMilliseconds == INFINITE)
2262 {
2263 if (sem_wait(pSemaphore))
2264 {
2265 eStatus = MOS_STATUS_UNKNOWN;
2266 }
2267 }
2268 else
2269 {
2270 struct timespec time = {
2271 (int32_t)uiMilliseconds / 1000000,
2272 ((int32_t)uiMilliseconds % 1000000) * 1000};
2273
2274 if (sem_timedwait(pSemaphore, &time))
2275 {
2276 eStatus = MOS_STATUS_UNKNOWN;
2277 }
2278 }
2279
2280 return eStatus;
2281 }
2282
MosPostSemaphore(PMOS_SEMAPHORE pSemaphore,uint32_t uiPostCount)2283 MOS_STATUS MosUtilities::MosPostSemaphore(
2284 PMOS_SEMAPHORE pSemaphore,
2285 uint32_t uiPostCount)
2286 {
2287 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2288
2289 if (uiPostCount > 0)
2290 {
2291 while (uiPostCount--)
2292 {
2293 if (sem_post(pSemaphore))
2294 {
2295 eStatus = MOS_STATUS_UNKNOWN;
2296 break;
2297 }
2298 }
2299 }
2300 else
2301 {
2302 eStatus = MOS_STATUS_UNKNOWN;
2303 }
2304
2305 return eStatus;
2306 }
2307
MosWaitForSingleObject(void * pObject,uint32_t uiMilliseconds)2308 uint32_t MosUtilities::MosWaitForSingleObject(
2309 void *pObject,
2310 uint32_t uiMilliseconds)
2311 {
2312 uint32_t WaitSignal = 0;
2313 MOS_UNUSED(pObject);
2314 MOS_UNUSED(uiMilliseconds);
2315
2316 return WaitSignal;
2317 }
2318
MosWaitForMultipleObjects(uint32_t uiThreadCount,void ** ppObjects,uint32_t bWaitAll,uint32_t uiMilliseconds)2319 uint32_t MosUtilities::MosWaitForMultipleObjects(
2320 uint32_t uiThreadCount,
2321 void **ppObjects,
2322 uint32_t bWaitAll,
2323 uint32_t uiMilliseconds)
2324 {
2325 MOS_UNUSED(uiThreadCount);
2326 MOS_UNUSED(ppObjects);
2327 MOS_UNUSED(bWaitAll);
2328 MOS_UNUSED(uiMilliseconds);
2329 return 0;
2330 }
2331
MosAtomicIncrement(int32_t * pValue)2332 int32_t MosUtilities::MosAtomicIncrement(
2333 int32_t *pValue)
2334 {
2335 if (pValue != nullptr)
2336 {
2337 return __sync_add_and_fetch(pValue, 1);
2338 }
2339 return 0;
2340 }
2341
MosAtomicDecrement(int32_t * pValue)2342 int32_t MosUtilities::MosAtomicDecrement(
2343 int32_t *pValue)
2344 {
2345 if (pValue != nullptr)
2346 {
2347 return __sync_sub_and_fetch(pValue, 1);
2348 }
2349 return 0;
2350 }
2351
2352 #ifndef WDDM_LINUX
MosStatusToOsResult(MOS_STATUS eStatus)2353 VAStatus MosUtilities::MosStatusToOsResult(
2354 MOS_STATUS eStatus)
2355 {
2356 switch (eStatus)
2357 {
2358 case MOS_STATUS_SUCCESS: return VA_STATUS_SUCCESS;
2359 case MOS_STATUS_NO_SPACE: return VA_STATUS_ERROR_ALLOCATION_FAILED;
2360 case MOS_STATUS_INVALID_PARAMETER: return VA_STATUS_ERROR_INVALID_PARAMETER;
2361 case MOS_STATUS_INVALID_HANDLE: return VA_STATUS_ERROR_INVALID_BUFFER;
2362 case MOS_STATUS_NULL_POINTER: return VA_STATUS_ERROR_INVALID_CONTEXT;
2363 default: return VA_STATUS_ERROR_OPERATION_FAILED;
2364 }
2365
2366 return VA_STATUS_ERROR_OPERATION_FAILED;
2367 }
2368
OsResultToMOSStatus(VAStatus eResult)2369 MOS_STATUS MosUtilities::OsResultToMOSStatus(
2370 VAStatus eResult)
2371 {
2372 switch (eResult)
2373 {
2374 case VA_STATUS_SUCCESS: return MOS_STATUS_SUCCESS;
2375 case VA_STATUS_ERROR_ALLOCATION_FAILED: return MOS_STATUS_NO_SPACE;
2376 case VA_STATUS_ERROR_INVALID_PARAMETER: return MOS_STATUS_INVALID_PARAMETER;
2377 case VA_STATUS_ERROR_INVALID_BUFFER: return MOS_STATUS_INVALID_HANDLE;
2378 case VA_STATUS_ERROR_INVALID_CONTEXT: return MOS_STATUS_NULL_POINTER;
2379 default: return MOS_STATUS_UNKNOWN;
2380 }
2381
2382 return MOS_STATUS_UNKNOWN;
2383 }
2384 #else
MosStatusToOsResult(MOS_STATUS eStatus)2385 MOS_OSRESULT MosUtilities::MosStatusToOsResult(
2386 MOS_STATUS eStatus)
2387 {
2388 if (eStatus < MOS_STATUS_SUCCESS)
2389 {
2390 // It is in fact an HRESULT already, do nothing
2391 return (MOS_OSRESULT)eStatus;
2392 }
2393
2394 switch (eStatus)
2395 {
2396 case MOS_STATUS_SUCCESS:
2397 return MOS_OSSOK;
2398 case MOS_STATUS_NO_SPACE:
2399 return MOS_OSEOUTOFMEMORY;
2400 case MOS_STATUS_INVALID_PARAMETER:
2401 return MOS_OSEINVALIDARG;
2402 case MOS_STATUS_INVALID_HANDLE:
2403 return MOS_OSEHANDLE;
2404 case MOS_STATUS_NULL_POINTER:
2405 return MOS_OSEPOINTER;
2406 case MOS_STATUS_UNIMPLEMENTED:
2407 return MOS_OSENOTIMPL;
2408 default:
2409 return MOS_OSEFAIL;
2410 }
2411
2412 return MOS_OSEFAIL;
2413 }
2414
OsResultToMOSStatus(MOS_OSRESULT eResult)2415 MOS_STATUS MosUtilities::OsResultToMOSStatus(
2416 MOS_OSRESULT eResult)
2417 {
2418 switch (eResult)
2419 {
2420 case MOS_OSSOK:
2421 return MOS_STATUS_SUCCESS;
2422 case MOS_OSEOUTOFMEMORY:
2423 return MOS_STATUS_NO_SPACE;
2424 case MOS_OSEINVALIDARG:
2425 return MOS_STATUS_INVALID_PARAMETER;
2426 case MOS_OSEHANDLE:
2427 return MOS_STATUS_INVALID_HANDLE;
2428 case MOS_OSEPOINTER:
2429 return MOS_STATUS_NULL_POINTER;
2430 default:
2431 return MOS_STATUS_UNKNOWN;
2432 }
2433
2434 return MOS_STATUS_UNKNOWN;
2435 }
2436 #endif
MosGetLocalTime(struct tm * Tm)2437 MOS_STATUS MosUtilities::MosGetLocalTime(
2438 struct tm* Tm)
2439 {
2440 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2441 struct tm *pTm;
2442 time_t lTime = time(nullptr);
2443 pTm = localtime(&lTime);
2444 if(pTm == nullptr)
2445 {
2446 MOS_OS_ASSERTMESSAGE("Failed to get localtime.");
2447 eStatus = MOS_STATUS_UNKNOWN;
2448 return eStatus;
2449 }
2450
2451 eStatus = MosSecureMemcpy(Tm, sizeof(struct tm), pTm, sizeof(struct tm));
2452 return eStatus;
2453 }
2454
MosTraceEventInit()2455 void MosUtilities::MosTraceEventInit()
2456 {
2457 char *val = getenv("GFX_MEDIA_TRACE");
2458 if (val)
2459 {
2460 MosUtilitiesSpecificNext::m_filterEnv = strtoll(val, nullptr, 0);
2461 val = getenv("GFX_MEDIA_TRACE_LEVEL");
2462 if (val)
2463 {
2464 MosUtilitiesSpecificNext::m_levelEnv = static_cast<uint32_t>(strtoll(val, nullptr, 0));
2465 }
2466 m_mosTraceEnable = true;
2467 m_mosTraceFilter = &MosUtilitiesSpecificNext::m_filterEnv;
2468 m_mosTraceLevel = reinterpret_cast<uint8_t *>(&MosUtilitiesSpecificNext::m_levelEnv);
2469 }
2470 else
2471 {
2472 int fd = open(TRACE_SETTING_PATH, O_RDONLY);
2473 if (fd < 0)
2474 {
2475 return;
2476 }
2477 void *addr = mmap(NULL, TRACE_SETTING_SIZE, PROT_READ, MAP_SHARED, fd, 0);
2478 close(fd); // close first, map addr still valid after close
2479 if (addr == MAP_FAILED)
2480 {
2481 return;
2482 }
2483 m_mosTraceControlData = reinterpret_cast<const MtControlData *>(addr);
2484
2485 m_mosTraceEnable = &m_mosTraceControlData->enable;
2486 m_mosTraceFilter = {
2487 m_mosTraceControlData->filter,
2488 sizeof(m_mosTraceControlData->filter) / sizeof(uint64_t)};
2489 m_mosTraceLevel = &m_mosTraceControlData->level;
2490 }
2491
2492 // close first, if already opened.
2493 if (MosUtilitiesSpecificNext::m_mosTraceFd >= 0)
2494 {
2495 close(MosUtilitiesSpecificNext::m_mosTraceFd);
2496 MosUtilitiesSpecificNext::m_mosTraceFd = -1;
2497 }
2498 MosUtilitiesSpecificNext::m_mosTraceFd = open(MosUtilitiesSpecificNext::m_mosTracePath, O_WRONLY);
2499 return;
2500 }
2501
MosTraceEventClose()2502 void MosUtilities::MosTraceEventClose()
2503 {
2504 m_mosTraceEnable.Reset();
2505 m_mosTraceFilter.Reset();
2506 m_mosTraceLevel.Reset();
2507 if (m_mosTraceControlData)
2508 {
2509 munmap((void *)m_mosTraceControlData, TRACE_SETTING_SIZE);
2510 m_mosTraceControlData = nullptr;
2511 }
2512 if (MosUtilitiesSpecificNext::m_mosTraceFd >= 0)
2513 {
2514 close(MosUtilitiesSpecificNext::m_mosTraceFd);
2515 MosUtilitiesSpecificNext::m_mosTraceFd = -1;
2516 }
2517 MosUtilitiesSpecificNext::m_filterEnv = 0;
2518 MosUtilitiesSpecificNext::m_levelEnv = {};
2519 return;
2520 }
2521
MosTraceSetupInfo(uint32_t DrvVer,uint32_t PlatFamily,uint32_t RenderFamily,uint32_t DeviceID)2522 void MosUtilities::MosTraceSetupInfo(uint32_t DrvVer, uint32_t PlatFamily, uint32_t RenderFamily, uint32_t DeviceID)
2523 {
2524 // not implemented
2525 }
2526
MosTraceEvent(uint16_t usId,uint8_t ucType,const void * pArg1,uint32_t dwSize1,const void * pArg2,uint32_t dwSize2)2527 void MosUtilities::MosTraceEvent(
2528 uint16_t usId,
2529 uint8_t ucType,
2530 const void *pArg1,
2531 uint32_t dwSize1,
2532 const void *pArg2,
2533 uint32_t dwSize2)
2534 {
2535 if (!m_mosTraceEnable)
2536 {
2537 return; // skip if trace not enabled from share memory
2538 }
2539
2540 if (MosUtilitiesSpecificNext::m_mosTraceFd >= 0 &&
2541 TRACE_EVENT_MAX_SIZE > dwSize1 + dwSize2 + TRACE_EVENT_HEADER_SIZE)
2542 {
2543 uint8_t traceBuf[256];
2544 uint8_t *pTraceBuf = traceBuf;
2545
2546 // special handling for media runtime log, filter by component
2547 if (usId == EVENT_MEDIA_LOG && pArg1 != nullptr && dwSize1 >= 2*sizeof(int32_t))
2548 {
2549 int32_t comp = (*(int32_t*)pArg1) >> 24;
2550 int32_t level = *((int32_t*)pArg1 + 1);
2551
2552 if (!m_mosTraceFilter(TR_KEY_MOSMSG_ALL) || !m_mosTraceFilter(MEDIA_EVENT_FILTER_KEYID(comp + 16)))
2553 {
2554 // keyword not set for this component, skip it
2555 return;
2556 }
2557 }
2558
2559 if (dwSize1 + dwSize2 + TRACE_EVENT_HEADER_SIZE > sizeof(traceBuf))
2560 {
2561 pTraceBuf = (uint8_t *)MOS_AllocAndZeroMemory(TRACE_EVENT_MAX_SIZE);
2562 }
2563
2564 if (pTraceBuf)
2565 {
2566 // trace header
2567 uint32_t *header = (uint32_t *)pTraceBuf;
2568 uint32_t nLen = TRACE_EVENT_HEADER_SIZE;
2569
2570 header[0] = 0x494D5445; // IMTE (IntelMediaTraceEvent) as ftrace raw marker tag
2571 header[1] = (usId << 16) | (dwSize1 + dwSize2);
2572 header[2] = ucType;
2573
2574 if (pArg1 && dwSize1 > 0)
2575 {
2576 MOS_SecureMemcpy(pTraceBuf+nLen, dwSize1, pArg1, dwSize1);
2577 nLen += dwSize1;
2578 }
2579 if (pArg2 && dwSize2 > 0)
2580 {
2581 MOS_SecureMemcpy(pTraceBuf+nLen, dwSize2, pArg2, dwSize2);
2582 nLen += dwSize2;
2583 }
2584 size_t writeSize = write(MosUtilitiesSpecificNext::m_mosTraceFd, pTraceBuf, nLen);
2585 if (traceBuf != pTraceBuf)
2586 {
2587 MOS_FreeMemory(pTraceBuf);
2588 }
2589 }
2590 #if Backtrace_FOUND
2591 if (m_mosTraceFilter(TR_KEY_CALL_STACK))
2592 {
2593 // reserve space for header and stack size field.
2594 // max 32-2=30 layers call stack in 64bit driver.
2595 uint32_t nLen = 4*sizeof(uint32_t);
2596 void **stack = (void **)(traceBuf + nLen);
2597 int num = backtrace(stack, ((sizeof(traceBuf)-nLen)/sizeof(void *)));
2598 if (num > 0)
2599 {
2600 uint32_t *header = (uint32_t *)traceBuf;
2601
2602 header[0] = 0x494D5445; // IMTE (IntelMediaTraceEvent) as ftrace raw marker tag
2603 header[1] = (EVENT_CALL_STACK << 16) | (num*sizeof(void *)+sizeof(uint32_t));
2604 header[2] = 0;
2605 header[3] = (uint32_t)num;
2606 nLen += num*sizeof(void *);
2607 size_t ret = write(MosUtilitiesSpecificNext::m_mosTraceFd, traceBuf, nLen);
2608 }
2609 }
2610 #endif
2611 }
2612 return;
2613 }
2614
MosShouldTraceEventMsg(uint8_t level,uint8_t compID)2615 bool MosUtilities::MosShouldTraceEventMsg(
2616 uint8_t level,
2617 uint8_t compID)
2618 {
2619 return false;
2620 }
2621
MosTraceEventMsg(uint8_t level,uint8_t compID,void * message,void * functionName,uint32_t lineNum)2622 void MosUtilities::MosTraceEventMsg(
2623 uint8_t level,
2624 uint8_t compID,
2625 void *message,
2626 void *functionName,
2627 uint32_t lineNum)
2628 {
2629 }
2630
MosTraceDataDump(const char * pcName,uint32_t flags,const void * pBuf,uint32_t dwSize)2631 void MosUtilities::MosTraceDataDump(
2632 const char *pcName,
2633 uint32_t flags,
2634 const void *pBuf,
2635 uint32_t dwSize)
2636 {
2637 if (MosUtilitiesSpecificNext::m_mosTraceFd >= 0 && pBuf && pcName)
2638 {
2639 uint8_t *pTraceBuf = (uint8_t *)MOS_AllocAndZeroMemory(TRACE_EVENT_MAX_SIZE);
2640 size_t writeSize = 0;
2641
2642 if (pTraceBuf)
2643 {
2644 // trace header
2645 uint32_t *header = (uint32_t *)pTraceBuf;
2646 uint32_t nLen = strlen(pcName) & 0xff;// 255 max pcName length
2647
2648 header[0] = 0x494D5445; // IMTE (IntelMediaTraceEvent) as ftrace raw marker tag
2649 header[1] = (EVENT_DATA_DUMP << 16) | (8 + nLen + 1);
2650 header[2] = EVENT_TYPE_START;
2651 header[3] = dwSize;
2652 header[4] = flags;
2653 memcpy(&header[5], pcName, nLen);
2654 nLen += TRACE_EVENT_HEADER_SIZE + 8 + 1;
2655 writeSize = write(MosUtilitiesSpecificNext::m_mosTraceFd, pTraceBuf, nLen);
2656 // send dump data
2657 header[2] = EVENT_TYPE_INFO;
2658 const uint8_t *pData = static_cast<const uint8_t *>(pBuf);
2659 while (dwSize > 0)
2660 {
2661 uint32_t size = dwSize;
2662 if (size > TRACE_EVENT_MAX_DATA_SIZE)
2663 {
2664 size = TRACE_EVENT_MAX_DATA_SIZE;
2665 }
2666 uint16_t len = ((size + 3) & ~3) / sizeof(uint32_t);
2667 uint8_t *pDst = (uint8_t *)&header[3];
2668
2669 header[1] = (EVENT_DATA_DUMP << 16) | (size + sizeof(len));
2670 memcpy(pDst, &len, sizeof(len));
2671 memcpy(pDst+sizeof(len), pData, size);
2672 nLen = TRACE_EVENT_HEADER_SIZE + size + sizeof(len);
2673 writeSize = write(MosUtilitiesSpecificNext::m_mosTraceFd, pTraceBuf, nLen);
2674 dwSize -= size;
2675 pData += size;
2676 }
2677 // send dump end
2678 header[1] = EVENT_DATA_DUMP << 16;
2679 header[2] = EVENT_TYPE_END;
2680 writeSize = write(MosUtilitiesSpecificNext::m_mosTraceFd, pTraceBuf, TRACE_EVENT_HEADER_SIZE);
2681
2682 MOS_FreeMemory(pTraceBuf);
2683 }
2684 }
2685 }
2686
MosTraceDataDictionary(const char * pcName,const void * pBuf,uint32_t dwSize)2687 void MosUtilities::MosTraceDataDictionary(
2688 const char* pcName,
2689 const void* pBuf,
2690 uint32_t dwSize)
2691 {
2692 // not implemented
2693 }
2694
MosGfxInfoInit()2695 MOS_STATUS MosUtilities::MosGfxInfoInit()
2696 {
2697 // not implemented
2698 return MOS_STATUS_SUCCESS;
2699 }
2700
MosGfxInfoClose()2701 void MosUtilities::MosGfxInfoClose()
2702 {
2703 // not implemented
2704 }
2705
MosGfxInfoRTErrInternal(uint8_t ver,uint16_t compId,uint16_t FtrId,uint32_t ErrorCode,uint8_t num_of_triples,va_list args)2706 void MosUtilities::MosGfxInfoRTErrInternal(uint8_t ver,
2707 uint16_t compId,
2708 uint16_t FtrId,
2709 uint32_t ErrorCode,
2710 uint8_t num_of_triples,
2711 va_list args)
2712 {
2713 // not implemented
2714 }
2715
MosGfxInfoRTErr(uint8_t ver,uint16_t compId,uint16_t FtrId,uint32_t ErrorCode,uint8_t num_of_triples,...)2716 void MosUtilities::MosGfxInfoRTErr(uint8_t ver,
2717 uint16_t compId,
2718 uint16_t FtrId,
2719 uint32_t ErrorCode,
2720 uint8_t num_of_triples,
2721 ...)
2722 {
2723 // not implemented
2724 }
2725
MosGfxInfoInternal(uint8_t ver,uint16_t compId,uint32_t tmtryID,uint8_t num_of_triples,va_list args)2726 void MosUtilities::MosGfxInfoInternal(
2727 uint8_t ver,
2728 uint16_t compId,
2729 uint32_t tmtryID,
2730 uint8_t num_of_triples,
2731 va_list args)
2732 {
2733 // not implemented
2734 }
2735
MosIsProfilerDumpEnabled()2736 bool MosUtilities::MosIsProfilerDumpEnabled()
2737 {
2738 return true;
2739 }
2740
MosGfxInfo(uint8_t ver,uint16_t compId,uint32_t tmtryID,uint8_t num_of_triples,...)2741 void MosUtilities::MosGfxInfo(
2742 uint8_t ver,
2743 uint16_t compId,
2744 uint32_t tmtryID,
2745 uint8_t num_of_triples,
2746 ...)
2747 {
2748 // not implemented
2749 }
2750
2751 #if (_DEBUG || _RELEASE_INTERNAL)
MosMMPWriteFile(const std::string & name,const void * data,size_t size)2752 void MosUtilities::MosMMPWriteFile(
2753 const std::string &name,
2754 const void *data,
2755 size_t size)
2756 {
2757 std::ofstream ofs(name);
2758 ofs.write(static_cast<const char *>(data), size);
2759 }
2760 #endif //(_DEBUG || _RELEASE_INTERNAL)
startTick(std::string tag)2761 void PerfUtility::startTick(std::string tag)
2762 {
2763 std::lock_guard<std::mutex> lock(perfMutex);
2764 Tick newTick = {};
2765 struct timespec ts = {};
2766
2767 // get start tick count
2768 clock_gettime(CLOCK_REALTIME, &ts);
2769 newTick.start = int(ts.tv_sec * 1000000) + int(ts.tv_nsec / 1000); // us
2770
2771 std::vector<Tick> *perf = nullptr;
2772 std::map<std::string, std::vector<Tick>*>::iterator it;
2773 it = records.find(tag);
2774 if (it == records.end())
2775 {
2776 perf = new std::vector<Tick>;
2777 perf->push_back(newTick);
2778 records[tag] = perf;
2779 }
2780 else
2781 {
2782 it->second->push_back(newTick);
2783 }
2784 }
2785
stopTick(std::string tag)2786 void PerfUtility::stopTick(std::string tag)
2787 {
2788 std::lock_guard<std::mutex> lock(perfMutex);
2789 struct timespec ts = {};
2790 std::map<std::string, std::vector<Tick>*>::iterator it;
2791 it = records.find(tag);
2792 if (it == records.end())
2793 {
2794 // should not happen
2795 return;
2796 }
2797
2798 // get stop tick count
2799 clock_gettime(CLOCK_REALTIME, &ts);
2800 it->second->back().stop = int(ts.tv_sec * 1000000) + int(ts.tv_nsec / 1000); // us
2801
2802 // calculate time interval
2803 it->second->back().time = double(it->second->back().stop - it->second->back().start) / 1000.0; // ms
2804 }
2805
2806 /*----------------------------------------------------------------------------
2807 | Name : GMMDebugBreak
2808 | Purpose : Fix compiling issue for Gmmlib on debug mode
2809 | Arguments : N/A
2810 | Returns : void
2811 | Calls : N/A
2812 | Callers : Several
2813 \---------------------------------------------------------------------------*/
GMMDebugBreak(const char * file,const char * function,const int32_t line)2814 void GMMDebugBreak(const char *file, const char *function,const int32_t line)
2815 {
2816 // Not required for media driver
2817 return;
2818 }
2819
2820 /*----------------------------------------------------------------------------
2821 | Name : GMMPrintMessage
2822 | Purpose : Fix compiling issue for Gmmlib on debug mode
2823 | Arguments : N/A
2824 | Returns : void
2825 | Calls : N/A
2826 | Callers : Several
2827 \---------------------------------------------------------------------------*/
GMMPrintMessage(int32_t debuglevel,const char * function,...)2828 void GMMPrintMessage(int32_t debuglevel, const char *function, ...)
2829 {
2830 // Not Required for media driver
2831 return;
2832 }
2833