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