1 /*
2 * Copyright (c) 2009-2018, 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.c
24 //! \brief This module implements the MOS wrapper functions for Linux/Android
25 //!
26
27 #include "mos_utilities_specific.h"
28 #include "mos_utilities.h"
29 #include "mos_util_debug.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 #ifndef ANDROID
44 #include <sys/ipc.h> // System V IPC
45 #include <sys/types.h>
46 #include <sys/sem.h>
47 #include <signal.h>
48 #include <unistd.h> // fork
49 #else
50 #include <cutils/properties.h>
51 #endif // ANDROID
52
53 #include "mos_utilities_specific_next.h"
54 static const char* szUserFeatureFile = USER_FEATURE_FILE;
55
56 #if _MEDIA_RESERVED
57 static MediaUserSettingsMgr *codecUserFeatureExt = nullptr;
58 static MediaUserSettingsMgr *vpUserFeatureExt = nullptr;
59 #endif
60
61
62 #ifdef __cplusplus
63
startTick(std::string tag)64 void PerfUtility::startTick(std::string tag)
65 {
66 Tick newTick = {};
67 struct timespec ts = {};
68
69 // get start tick count
70 clock_gettime(CLOCK_REALTIME, &ts);
71 newTick.start = int(ts.tv_sec * 1000000) + int(ts.tv_nsec / 1000); // us
72
73 std::vector<Tick> *perf = nullptr;
74 std::map<std::string, std::vector<Tick>*>::iterator it;
75 it = records.find(tag);
76 if (it == records.end())
77 {
78 perf = new std::vector<Tick>;
79 perf->push_back(newTick);
80 records[tag] = perf;
81 }
82 else
83 {
84 it->second->push_back(newTick);
85 }
86 }
87
stopTick(std::string tag)88 void PerfUtility::stopTick(std::string tag)
89 {
90 struct timespec ts = {};
91 std::map<std::string, std::vector<Tick>*>::iterator it;
92 it = records.find(tag);
93 if (it == records.end())
94 {
95 // should not happen
96 return;
97 }
98
99 // get stop tick count
100 clock_gettime(CLOCK_REALTIME, &ts);
101 it->second->back().stop = int(ts.tv_sec * 1000000) + int(ts.tv_nsec / 1000); // us
102
103 // calculate time interval
104 it->second->back().time = double(it->second->back().stop - it->second->back().start) / 1000.0; // ms
105 }
106
107 #endif // __cplusplus
108
109 //!
110 //! \brief Get current run time
111 //! \details Get current run time in us
112 //! \return double
113 //! Returns time in us
114 //!
MOS_GetTime()115 double MOS_GetTime()
116 {
117 struct timespec ts = {};
118 clock_gettime(CLOCK_REALTIME, &ts);
119 return double(ts.tv_sec) * 1000000.0 + double(ts.tv_nsec) / 1000.0;
120 }
121
122 //!
123 //! \brief Linux specific user feature define, used in MOS_UserFeature_ParsePath
124 //! They can be unified with the win definitions, since they are identical.
125 //!
126 #define MOS_UF_SEPARATOR "\\"
127 #define MOS_UFKEY_EXT "UFKEY_EXTERNAL"
128 #define MOS_UFKEY_INT "UFKEY_INTERNAL"
129 PUFKEYOPS pUFKeyOps = nullptr;
130
131 extern int32_t MosMemAllocCounterNoUserFeature;
132 extern int32_t MosMemAllocCounterNoUserFeatureGfx;
133
134 //!
135 //! \brief Linux specific trace entry path and file description.
136 //!
137 const char * const MosTracePath = "/sys/kernel/debug/tracing/trace_marker";
138 static int32_t MosTraceFd = -1;
139
140 //!
141 //! \brief for int64_t/uint64_t format print warning
142 //!
143 #if __WORDSIZE == 64
144 #define __MOS64_PREFIX "l"
145 #else
146 #define __MOS64_PREFIX "ll"
147 #endif
148
149 #define MOSd64 __MOS64_PREFIX "d"
150 #define MOSu64 __MOS64_PREFIX "u"
151
152 //!
153 //! \brief mutex for mos utilities multi-threading protection
154 //!
155 MOS_MUTEX gMosUtilMutex = PTHREAD_MUTEX_INITIALIZER;
156
157 static uint32_t uiMOSUtilInitCount = 0; // number count of mos utilities init
158
MOS_SecureStrcat(char * strDestination,size_t numberOfElements,const char * const strSource)159 MOS_STATUS MOS_SecureStrcat(char *strDestination, size_t numberOfElements, const char * const strSource)
160 {
161 if ( (strDestination == nullptr) || (strSource == nullptr) )
162 {
163 return MOS_STATUS_INVALID_PARAMETER;
164 }
165
166 if(strnlen(strDestination, numberOfElements) == numberOfElements) // Not null terminated
167 {
168 return MOS_STATUS_INVALID_PARAMETER;
169 }
170
171 if((strlen(strDestination) + strlen(strSource)) >= numberOfElements) // checks space for null termination.
172 {
173 return MOS_STATUS_INVALID_PARAMETER;
174 }
175
176 strcat(strDestination, strSource);
177 return MOS_STATUS_SUCCESS;
178 }
179
MOS_SecureStrtok(char * strToken,const char * strDelimit,char ** contex)180 char *MOS_SecureStrtok(
181 char *strToken,
182 const char *strDelimit,
183 char **contex)
184 {
185 return strtok_r(strToken, strDelimit, contex);
186 }
187
MOS_SecureStrcpy(char * strDestination,size_t numberOfElements,const char * const strSource)188 MOS_STATUS MOS_SecureStrcpy(char *strDestination, size_t numberOfElements, const char * const strSource)
189 {
190 if ( (strDestination == nullptr) || (strSource == nullptr) )
191 {
192 return MOS_STATUS_INVALID_PARAMETER;
193 }
194
195 if ( numberOfElements <= strlen(strSource) ) // checks if there is space for null termination after copy.
196 {
197 return MOS_STATUS_INVALID_PARAMETER;
198 }
199
200 strcpy(strDestination, strSource);
201
202 return MOS_STATUS_SUCCESS;
203 }
204
MOS_SecureMemcpy(void * pDestination,size_t dstLength,PCVOID pSource,size_t srcLength)205 MOS_STATUS MOS_SecureMemcpy(void *pDestination, size_t dstLength, PCVOID pSource, size_t srcLength)
206 {
207 if ( (pDestination == nullptr) || (pSource == nullptr) )
208 {
209 return MOS_STATUS_INVALID_PARAMETER;
210 }
211
212 if ( dstLength < srcLength )
213 {
214 return MOS_STATUS_INVALID_PARAMETER;
215 }
216 if(pDestination != pSource)
217 {
218 memcpy(pDestination, pSource, srcLength);
219 }
220
221 return MOS_STATUS_SUCCESS;
222 }
223
MOS_SecureFileOpen(FILE ** ppFile,const char * filename,const char * mode)224 MOS_STATUS MOS_SecureFileOpen(
225 FILE **ppFile,
226 const char *filename,
227 const char *mode)
228 {
229 PFILE fp;
230
231 if ((ppFile == nullptr) || (filename == nullptr) || (mode == nullptr))
232 {
233 return MOS_STATUS_INVALID_PARAMETER;
234 }
235
236 fp = fopen(filename, mode);
237
238 if (fp == nullptr)
239 {
240 *ppFile = nullptr;
241 return MOS_STATUS_FILE_OPEN_FAILED;
242 }
243 else
244 {
245 *ppFile = fp;
246 return MOS_STATUS_SUCCESS;
247 }
248 }
249
MOS_SecureStringPrint(char * buffer,size_t bufSize,size_t length,const char * const format,...)250 int32_t MOS_SecureStringPrint(char *buffer, size_t bufSize, size_t length, const char * const format, ...)
251 {
252 int32_t iRet = -1;
253 va_list var_args;
254
255 if((buffer == nullptr) || (format == nullptr) || (bufSize < length))
256 {
257 return iRet;
258 }
259
260 va_start(var_args, format);
261
262 iRet = vsnprintf(buffer, length, format, var_args);
263
264 va_end(var_args);
265
266 return iRet;
267 }
268
MOS_SecureVStringPrint(char * buffer,size_t bufSize,size_t length,const char * const format,va_list var_args)269 MOS_STATUS MOS_SecureVStringPrint(char *buffer, size_t bufSize, size_t length, const char * const format, va_list var_args)
270 {
271 if((buffer == nullptr) || (format == nullptr) || (bufSize < length))
272 {
273 return MOS_STATUS_INVALID_PARAMETER;
274 }
275
276 vsnprintf(buffer, length, format, var_args);
277
278 return MOS_STATUS_SUCCESS;
279 }
280
MOS_GetFileSize(HANDLE hFile,uint32_t * lpFileSizeLow,uint32_t * lpFileSizeHigh)281 MOS_STATUS MOS_GetFileSize(
282 HANDLE hFile,
283 uint32_t *lpFileSizeLow,
284 uint32_t *lpFileSizeHigh)
285 {
286 struct stat Buf;
287 MOS_UNUSED(lpFileSizeHigh);
288
289 if((hFile == nullptr) || (lpFileSizeLow == nullptr))
290 {
291 return MOS_STATUS_INVALID_PARAMETER;
292 }
293
294 if ( (fstat((intptr_t)hFile, &Buf)) < 0 )
295 {
296 *lpFileSizeLow = 0;
297 return MOS_STATUS_INVALID_FILE_SIZE;
298 }
299 *lpFileSizeLow = (uint32_t)Buf.st_size;
300
301 //to-do, lpFileSizeHigh store high 32-bit of File size
302 return MOS_STATUS_SUCCESS;
303 }
304
MOS_CreateDirectory(char * const lpPathName)305 MOS_STATUS MOS_CreateDirectory(
306 char * const lpPathName)
307 {
308 uint32_t mode;
309 MOS_STATUS eStatus = MOS_STATUS_UNKNOWN;
310
311 MOS_OS_CHK_NULL(lpPathName);
312
313 // Set read/write access right for usr/group.
314 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP;
315 if (mkdir(lpPathName, mode) < 0 &&
316 errno != EEXIST) // Directory already exists, don't return failure in this case.
317 {
318 MOS_OS_ASSERTMESSAGE("Failed to create the directory '%s'. Error = %s", lpPathName, strerror(errno));
319 eStatus = MOS_STATUS_DIR_CREATE_FAILED;
320 goto finish;
321 }
322
323 eStatus = MOS_STATUS_SUCCESS;
324
325 finish:
326 return eStatus;
327 }
328
MOS_CreateFile(PHANDLE pHandle,char * const lpFileName,uint32_t iOpenFlag)329 MOS_STATUS MOS_CreateFile(
330 PHANDLE pHandle,
331 char * const lpFileName,
332 uint32_t iOpenFlag)
333 {
334 int32_t iFileDescriptor;
335 uint32_t mode;
336
337 if((lpFileName == nullptr) || (pHandle == nullptr))
338 {
339 return MOS_STATUS_INVALID_PARAMETER;
340 }
341 //set read/write access right for usr/group, mMode only takes effect when
342 //O_CREAT is set
343 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
344 if ( (iFileDescriptor = open(lpFileName, iOpenFlag, mode)) < 0 )
345 {
346 *pHandle = (HANDLE)((intptr_t) iFileDescriptor);
347 return MOS_STATUS_INVALID_HANDLE;
348 }
349
350 *pHandle = (HANDLE)((intptr_t) iFileDescriptor);
351 return MOS_STATUS_SUCCESS;
352 }
353
MOS_ReadFile(HANDLE hFile,void * lpBuffer,uint32_t bytesToRead,uint32_t * pBytesRead,void * lpOverlapped)354 MOS_STATUS MOS_ReadFile(
355 HANDLE hFile,
356 void *lpBuffer,
357 uint32_t bytesToRead,
358 uint32_t *pBytesRead,
359 void *lpOverlapped)
360 {
361 size_t nNumBytesToRead;
362 ssize_t nNumBytesRead;
363 MOS_UNUSED(lpOverlapped);
364
365 if((hFile == nullptr) || (lpBuffer == nullptr) || (pBytesRead == nullptr))
366 {
367 return MOS_STATUS_INVALID_PARAMETER;
368 }
369
370 nNumBytesToRead = (size_t)bytesToRead;
371 nNumBytesRead = 0;
372
373 //To-do: process lpOverlapped
374
375 if ((nNumBytesRead = read((intptr_t)hFile, lpBuffer, nNumBytesToRead)) < 0)
376 {
377 *pBytesRead = 0;
378 return MOS_STATUS_FILE_READ_FAILED;
379 }
380
381 *pBytesRead = (uint32_t)nNumBytesRead;
382 return MOS_STATUS_SUCCESS;
383 }
384
MOS_WriteFile(HANDLE hFile,void * lpBuffer,uint32_t bytesToWrite,uint32_t * pbytesWritten,void * lpOverlapped)385 MOS_STATUS MOS_WriteFile(
386 HANDLE hFile,
387 void *lpBuffer,
388 uint32_t bytesToWrite,
389 uint32_t *pbytesWritten,
390 void *lpOverlapped)
391 {
392 size_t nNumBytesToWrite;
393 ssize_t nNumBytesWritten;
394 MOS_UNUSED(lpOverlapped);
395
396 if((hFile == nullptr) || (lpBuffer == nullptr) || (pbytesWritten == nullptr))
397 {
398 return MOS_STATUS_INVALID_PARAMETER;
399 }
400
401 nNumBytesToWrite = (size_t)bytesToWrite;
402 nNumBytesWritten = 0;
403
404 //To-do, process lpOverlapped
405
406 if ((nNumBytesWritten = write((intptr_t)hFile, lpBuffer, nNumBytesToWrite)) < 0)
407 {
408 *pbytesWritten = 0;
409 return MOS_STATUS_FILE_WRITE_FAILED;
410 }
411
412 *pbytesWritten = (uint32_t)nNumBytesWritten;
413 return MOS_STATUS_SUCCESS;
414 }
415
MOS_SetFilePointer(HANDLE hFile,int32_t lDistanceToMove,int32_t * lpDistanceToMoveHigh,int32_t dwMoveMethod)416 MOS_STATUS MOS_SetFilePointer(
417 HANDLE hFile,
418 int32_t lDistanceToMove,
419 int32_t *lpDistanceToMoveHigh,
420 int32_t dwMoveMethod)
421 {
422 int32_t iOffSet;
423 int32_t iCurPos;
424
425 if(hFile == nullptr)
426 {
427 return MOS_STATUS_INVALID_PARAMETER;
428 }
429
430 if (lpDistanceToMoveHigh == nullptr)
431 {
432 iOffSet = lDistanceToMove;
433 }
434 else
435 {
436 //to-do, let lpDistanceToMoveHigh and lDistanceToMove form a 64-bit iOffSet
437 iOffSet = (int32_t)lDistanceToMove;
438 }
439
440 if ((iCurPos = lseek((intptr_t)hFile, iOffSet, dwMoveMethod)) < 0)
441 {
442 return MOS_STATUS_SET_FILE_POINTER_FAILED;
443 }
444
445 return MOS_STATUS_SUCCESS;
446 }
447
MOS_CloseHandle(HANDLE hObject)448 int32_t MOS_CloseHandle(HANDLE hObject)
449 {
450 int32_t iRet = false;
451
452 if(hObject != nullptr)
453 {
454 close((intptr_t)hObject);
455 iRet = true;
456 }
457
458 return iRet;
459 }
460
461 //library
MOS_LoadLibrary(const char * const lpLibFileName,PHMODULE phModule)462 MOS_STATUS MOS_LoadLibrary(const char * const lpLibFileName, PHMODULE phModule)
463 {
464 if (lpLibFileName == nullptr)
465 {
466 return MOS_STATUS_INVALID_PARAMETER;
467 }
468
469 *phModule = dlopen((const char *)lpLibFileName, RTLD_LAZY);
470
471 return ((*phModule != nullptr) ? MOS_STATUS_SUCCESS : MOS_STATUS_LOAD_LIBRARY_FAILED);
472 }
473
MOS_FreeLibrary(HMODULE hLibModule)474 int32_t MOS_FreeLibrary (HMODULE hLibModule)
475 {
476 uint32_t iRet = 10; // Initialize to some non-zero value
477
478 if(hLibModule != nullptr)
479 {
480 iRet = dlclose(hLibModule);
481 }
482 return (iRet == 0) ? true : false;
483 }
484
MOS_GetProcAddress(HMODULE hModule,const char * lpProcName)485 void *MOS_GetProcAddress(HMODULE hModule, const char *lpProcName)
486 {
487 void *pSym = nullptr;
488
489 if (hModule == nullptr ||
490 lpProcName == nullptr)
491 {
492 MOS_OS_ASSERTMESSAGE("Invalid parameter.");
493 }
494 else
495 {
496 pSym = dlsym(hModule, lpProcName);
497 }
498
499 return pSym;
500 }
501
MOS_GetPid()502 int32_t MOS_GetPid()
503 {
504 return(getpid());
505 }
506
507 //Performace
MOS_QueryPerformanceFrequency(uint64_t * pFrequency)508 int32_t MOS_QueryPerformanceFrequency(uint64_t *pFrequency)
509 {
510 struct timespec Res;
511 int32_t iRet;
512
513 if(pFrequency == nullptr)
514 {
515 return false;
516 }
517
518 if ( (iRet = clock_getres(CLOCK_MONOTONIC, &Res)) != 0 )
519 {
520 return false;
521 }
522
523 // resolution (precision) can't be in seconds for current machine and OS
524 if (Res.tv_sec != 0)
525 {
526 return false;
527 }
528 *pFrequency = (uint64_t)((1000 * 1000 * 1000) / Res.tv_nsec);
529
530 return true;
531 }
532
MOS_QueryPerformanceCounter(uint64_t * pPerformanceCount)533 int32_t MOS_QueryPerformanceCounter(uint64_t *pPerformanceCount)
534 {
535 struct timespec Res;
536 struct timespec t;
537 int32_t iRet;
538
539 if(pPerformanceCount == nullptr)
540 {
541 return false;
542 }
543 if ( (iRet = clock_getres (CLOCK_MONOTONIC, &Res)) != 0 )
544 {
545 return false;
546 }
547 if (Res.tv_sec != 0)
548 { // resolution (precision) can't be in seconds for current machine and OS
549 return false;
550 }
551 if( (iRet = clock_gettime(CLOCK_MONOTONIC, &t)) != 0)
552 {
553 return false;
554 }
555 *pPerformanceCount = (uint64_t)((1000 * 1000 * 1000 * t.tv_sec + t.tv_nsec) / Res.tv_nsec);
556
557 return true;
558 }
559
MOS_Sleep(uint32_t mSec)560 void MOS_Sleep(uint32_t mSec)
561 {
562 usleep(1000 * mSec);
563 }
564
565 //User Feature
566 /*----------------------------------------------------------------------------
567 | Name : _UserFeature_FindKey
568 | Purpose : This function finds a key in keys linked list according to key
569 | name.
570 | Arguments : pKeyList [in] Key Linked list.
571 | pcKeyName [in] Name to the key to find.
572 | Returns : Matched uf_key data. otherwise return NULL.
573 | Comments :
574 \---------------------------------------------------------------------------*/
_UserFeature_FindKey(MOS_PUF_KEYLIST pKeyList,char * const pcKeyName)575 static MOS_UF_KEY* _UserFeature_FindKey(MOS_PUF_KEYLIST pKeyList, char * const pcKeyName)
576 {
577 int32_t iResult;
578 MOS_PUF_KEYLIST pTempNode;
579
580 iResult = -1;
581
582 for(pTempNode = pKeyList; pTempNode; pTempNode = pTempNode->pNext)
583 {
584 iResult = strcmp(pTempNode->pElem->pcKeyName, pcKeyName);
585 if ( iResult == 0 )
586 {
587 return pTempNode->pElem;
588 }
589 }
590 return nullptr; //not found
591 }
592
593 /*----------------------------------------------------------------------------
594 | Name : _UserFeature_FindValue
595 | Purpose : Find a value in values array of a key. Return position in values
596 | array
597 | Arguments : UFKey [in] Searched Key node.
598 | pcValueName [in] Value name.
599 | Returns : Matched value No. if it can be found, otherwise, return
600 | NOT_FOUND(-1);
601 | Comments :
602 \---------------------------------------------------------------------------*/
_UserFeature_FindValue(MOS_UF_KEY UFKey,char * const pcValueName)603 static int32_t _UserFeature_FindValue(MOS_UF_KEY UFKey, char * const pcValueName)
604 {
605 int32_t iResult;
606 int32_t i;
607
608 iResult = -1;
609
610 for ( i = 0; i < (int32_t)UFKey.ulValueNum; i++ )
611 {
612 iResult = strcmp(UFKey.pValueArray[i].pcValueName, pcValueName);
613 if ( iResult == 0 )
614 {
615 return i;
616 }
617 }
618 return NOT_FOUND;
619 }
620
621 /*----------------------------------------------------------------------------
622 | Name : _UserFeature_Add
623 | Purpose : Add new key to keys' linked list.
624 | Arguments : pKeyList [in] Key linked list.
625 | NewKey [in] Added new key.
626 | Returns : MOS_STATUS_SUCCESS success
627 | MOS_STATUS_INVALID_PARAMETER invalid NewKey
628 | MOS_STATUS_NO_SPACE no space left for allocate
629 | Comments :
630 \---------------------------------------------------------------------------*/
_UserFeature_Add(MOS_PUF_KEYLIST * pKeyList,MOS_UF_KEY * NewKey)631 static MOS_STATUS _UserFeature_Add(MOS_PUF_KEYLIST *pKeyList, MOS_UF_KEY *NewKey)
632 {
633 MOS_UF_KEYNODE *pNewNode;
634 MOS_UF_KEYNODE *pTempNode;
635 MOS_UF_KEYNODE *pStartNode;
636
637 pNewNode = nullptr;
638 pTempNode = nullptr;
639 pStartNode = *pKeyList;
640
641 if ( NewKey == nullptr )
642 {
643 return MOS_STATUS_INVALID_PARAMETER;
644 }
645
646 pNewNode = (MOS_UF_KEYNODE*)MOS_AllocMemory(sizeof(MOS_UF_KEYNODE));
647 if (pNewNode == nullptr)
648 {
649 return MOS_STATUS_NO_SPACE;
650 }
651 pNewNode->pElem = NewKey;
652
653 if (*pKeyList == nullptr ) // the key list is empty
654 {
655 pNewNode->pNext = nullptr;
656 (*pKeyList) = pNewNode;
657 }
658 else // the key list is not empty, append to the front
659 {
660 pTempNode = pStartNode->pNext;
661 pStartNode->pNext = pNewNode;
662 pNewNode->pNext = pTempNode;
663 }
664 return MOS_STATUS_SUCCESS;
665 }
666
667 /*----------------------------------------------------------------------------
668 | Name : _UserFeature_Set
669 | Purpose : This function set a key to the key list.
670 | Arguments : pKeyList [in] Key linked list.
671 | NewKey [in] Set key content.
672 | Returns : MOS_STATUS_SUCCESS Operation success.
673 | MOS_STATUS_UNKNOWN Can't find key in User Feature File.
674 | MOS_STATUS_NO_SPACE no space left for allocate
675 | Comments :
676 \---------------------------------------------------------------------------*/
_UserFeature_Set(MOS_PUF_KEYLIST * pKeyList,MOS_UF_KEY NewKey)677 static MOS_STATUS _UserFeature_Set(MOS_PUF_KEYLIST *pKeyList, MOS_UF_KEY NewKey)
678 {
679 int32_t iPos;
680 MOS_UF_VALUE *pValueArray;
681 MOS_UF_KEY *Key;
682 void *ulValueBuf;
683
684 iPos = -1;
685 pValueArray = nullptr;
686
687 if ( (Key = _UserFeature_FindKey(*pKeyList, NewKey.pcKeyName)) == nullptr )
688 {
689 // can't find key in File
690 return MOS_STATUS_UNKNOWN;
691 }
692
693 // Prepare the ValueBuff of the NewKey
694 if ((ulValueBuf = MOS_AllocMemory(NewKey.pValueArray[0].ulValueLen)) == nullptr)
695 {
696 return MOS_STATUS_NO_SPACE;
697 }
698
699 if ( (iPos = _UserFeature_FindValue(*Key, NewKey.pValueArray[0].pcValueName)) == NOT_FOUND)
700 {
701 //not found, add a new value to key struct.
702 //reallocate memory for appending this value.
703 pValueArray = (MOS_UF_VALUE*)MOS_AllocMemory(sizeof(MOS_UF_VALUE)*(Key->ulValueNum+1));
704 if (pValueArray == nullptr)
705 {
706 MOS_FreeMemory(ulValueBuf);
707 return MOS_STATUS_NO_SPACE;
708 }
709
710 MOS_SecureMemcpy(pValueArray,
711 sizeof(MOS_UF_VALUE)*(Key->ulValueNum),
712 Key->pValueArray,
713 sizeof(MOS_UF_VALUE)*(Key->ulValueNum));
714
715 MOS_FreeMemory(Key->pValueArray);
716
717 Key->pValueArray = pValueArray;
718
719 iPos = Key->ulValueNum;
720 MOS_SecureStrcpy(Key->pValueArray[Key->ulValueNum].pcValueName,
721 MAX_USERFEATURE_LINE_LENGTH,
722 NewKey.pValueArray[0].pcValueName);
723 Key->ulValueNum ++;
724 }
725 else
726 {
727 //if found, the previous value buffer needs to be freed before reallocating
728 MOS_FreeMemory(Key->pValueArray[iPos].ulValueBuf);
729 }
730
731 Key->pValueArray[iPos].ulValueLen = NewKey.pValueArray[0].ulValueLen;
732 Key->pValueArray[iPos].ulValueType = NewKey.pValueArray[0].ulValueType;
733 Key->pValueArray[iPos].ulValueBuf = ulValueBuf;
734
735 MOS_ZeroMemory(Key->pValueArray[iPos].ulValueBuf, NewKey.pValueArray[0].ulValueLen);
736
737 MOS_SecureMemcpy(Key->pValueArray[iPos].ulValueBuf,
738 NewKey.pValueArray[0].ulValueLen,
739 NewKey.pValueArray[0].ulValueBuf,
740 NewKey.pValueArray[0].ulValueLen);
741
742 return MOS_STATUS_SUCCESS;
743 }
744
745 /*----------------------------------------------------------------------------
746 | Name : _UserFeature_Query
747 | Purpose : This function query a key's value and return matched key node
748 | content just with matched value content.
749 | Arguments : pKeyList [in] Key linked list.
750 | NewKey [in] New key content with matched value.
751 | Returns : MOS_STATUS_SUCCESS Operation success.
752 | MOS_STATUS_UNKNOWN Can't find key or value in User Feature File.
753 | Comments :
754 \---------------------------------------------------------------------------*/
_UserFeature_Query(MOS_PUF_KEYLIST pKeyList,MOS_UF_KEY * NewKey)755 static MOS_STATUS _UserFeature_Query(MOS_PUF_KEYLIST pKeyList, MOS_UF_KEY *NewKey)
756 {
757 int32_t iPos;
758 MOS_UF_VALUE *pValueArray;
759 MOS_UF_KEY *Key;
760
761 iPos = -1;
762 pValueArray = nullptr;
763
764 // can't find key in user feature
765 if ( (Key = _UserFeature_FindKey(pKeyList, NewKey->pcKeyName)) == nullptr )
766 {
767 return MOS_STATUS_UNKNOWN;
768 }
769
770 // can't find Value in the key
771 if ( (iPos = _UserFeature_FindValue(*Key, NewKey->pValueArray[0].pcValueName)) == NOT_FOUND)
772 {
773 return MOS_STATUS_UNKNOWN;
774 }
775
776 //get key content from user feature
777 MOS_SecureMemcpy(NewKey->pValueArray[0].ulValueBuf,
778 Key->pValueArray[iPos].ulValueLen,
779 Key->pValueArray[iPos].ulValueBuf,
780 Key->pValueArray[iPos].ulValueLen);
781
782 NewKey->pValueArray[0].ulValueLen = Key->pValueArray[iPos].ulValueLen;
783 NewKey->pValueArray[0].ulValueType = Key->pValueArray[iPos].ulValueType;
784
785 return MOS_STATUS_SUCCESS;
786 }
787
_UserFeature_ReadNextTokenFromFile(FILE * pFile,const char * szFormat,char * szToken)788 static MOS_STATUS _UserFeature_ReadNextTokenFromFile(FILE *pFile, const char *szFormat, char *szToken)
789 {
790 size_t nTokenSize = 0;
791
792 // Reads the next token from the given pFile.
793 if (fscanf(pFile, szFormat, szToken) <= 0)
794 {
795 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.");
796 return MOS_STATUS_FILE_READ_FAILED;
797 }
798
799 // Converts to Unix-style line endings to prevent compatibility problems.
800 nTokenSize = strnlen(szToken, MAX_USERFEATURE_LINE_LENGTH);
801 if (szToken[nTokenSize-1] == '\r')
802 {
803 szToken[nTokenSize-1] = '\0';
804 }
805
806 return MOS_STATUS_SUCCESS;
807 }
808
809 /*----------------------------------------------------------------------------
810 | Name : _UserFeature_DumpFile
811 | Purpose : This function read the whole User Feature File and dump User Feature File
812 | data to key linked list.
813 | Arguments : szFileName [in] User Feature File name.
814 | pKeyList [out] Key Linked list.
815 | Returns : MOS_STATUS_SUCCESS Operation success.
816 | MOS_STATUS_USER_FEATURE_KEY_READ_FAILED User Feature File can't be open as read.
817 | MOS_STATUS_NO_SPACE no space left for allocate
818 | MOS_STATUS_UNKNOWN unknown user feature type found in User Feature File
819 | MOS_STATUS_INVALID_PARAMETER unknown items found in User Feature File
820 | Comments :
821 \---------------------------------------------------------------------------*/
_UserFeature_DumpFile(const char * const szFileName,MOS_PUF_KEYLIST * pKeyList)822 static MOS_STATUS _UserFeature_DumpFile(const char * const szFileName, MOS_PUF_KEYLIST* pKeyList)
823 {
824 MOS_UF_KEY *CurKey;
825 MOS_UF_VALUE *CurValue;
826 char szTmp[MAX_USERFEATURE_LINE_LENGTH];
827 int32_t iResult;
828 size_t nSize;
829 int32_t bFirst;
830 int32_t iCount;
831 PFILE File;
832 int32_t bEmpty;
833 int32_t iCurId;
834 MOS_STATUS eStatus;
835 char *tmpChar; // Used in the 64-bit case to read uint64_t
836
837 CurValue = nullptr;
838 nSize = 0;
839 bFirst = 1; // 1 stand for "is the first key".
840 iCount = 0;
841 File = nullptr;
842 bEmpty = 0;
843 iCurId = 0;
844 eStatus = MOS_STATUS_SUCCESS;
845
846 CurKey = (MOS_UF_KEY*)MOS_AllocMemory(sizeof(MOS_UF_KEY));
847 if (CurKey == nullptr)
848 {
849 return MOS_STATUS_NO_SPACE;
850 }
851 CurKey->ulValueNum = 0;
852 CurKey->pcKeyName[0] = '\0';
853 CurKey->pValueArray = nullptr;
854
855 if ( (File = fopen(szFileName, "r")) == nullptr)
856 {
857 MOS_FreeMemory(CurKey);
858 return MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
859 }
860 while (feof(File) != EOF)
861 {
862 MOS_ZeroMemory(szTmp, MAX_USERFEATURE_LINE_LENGTH*sizeof(char ));
863 if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
864 {
865 break;
866 }
867
868 // set szDumpData with extracted File content.
869 iResult = strcmp(szTmp, UF_KEY_ID);
870 if ( iResult == 0 )
871 {
872 // It is a new key starting!
873 if (! bFirst )
874 {
875 // Add last key struct to contents when the key is not first.
876 // otherwise, continue to load key struct data.
877 CurKey->pValueArray = CurValue;
878 CurKey->ulValueNum = iCount;
879 if(_UserFeature_Add(pKeyList, CurKey) != MOS_STATUS_SUCCESS)
880 {
881 // if the CurKey didn't be added in pKeyList, free it.
882 MOS_FreeMemory(CurKey);
883 }
884 CurKey = (MOS_UF_KEY*)MOS_AllocMemory(sizeof(MOS_UF_KEY));
885 if (CurKey == nullptr)
886 {
887 eStatus = MOS_STATUS_NO_SPACE;
888 break;
889 }
890 } // if (! bFirst )
891
892 if (fscanf(File, "%x\n", &iCurId) <= 0)
893 {
894 break;
895 }
896
897 CurKey->UFKey = (void *)(intptr_t)iCurId;
898
899 MOS_ZeroMemory(szTmp, MAX_USERFEATURE_LINE_LENGTH * sizeof(char));
900 if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
901 {
902 break;
903 }
904
905 MOS_SecureStrcpy(CurKey->pcKeyName, MAX_USERFEATURE_LINE_LENGTH, szTmp);
906 CurKey->ulValueNum = 0;
907
908 // allocate capability length for valuearray.
909 CurValue = (MOS_UF_VALUE*)MOS_AllocMemory(sizeof(MOS_UF_VALUE)*UF_CAPABILITY);
910 if (CurValue == nullptr)
911 {
912 eStatus = MOS_STATUS_NO_SPACE;
913 break;
914 }
915 bFirst = 0;
916 iCount = 0; // next key's array number.
917 bEmpty = 1;
918 } // if ( iResult == 0 )
919 else // not a key
920 {
921 // Is it a value starting?
922 iResult = strcmp(szTmp, UF_VALUE_ID);
923 if ( iResult == 0 )
924 {
925 if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
926 {
927 break;
928 }
929
930 if (CurValue == nullptr)
931 {
932 break;
933 }
934
935 // Out of bounds technically based on how much memory we allocated
936 if (iCount < 0 || iCount >= UF_CAPABILITY)
937 {
938 eStatus = MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
939 break;
940 }
941
942 // Load value name;
943 MOS_SecureStrcpy(CurValue[iCount].pcValueName, MAX_USERFEATURE_LINE_LENGTH, szTmp);
944
945 // Load value type
946 if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
947 {
948 break;
949 }
950
951 CurValue[iCount].ulValueType = atoi(szTmp);
952
953 // Load value buffer.
954 switch ( CurValue[iCount].ulValueType )
955 {
956 case UF_DWORD: // 32-bit
957 if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
958 {
959 break;
960 }
961
962 CurValue[iCount].ulValueLen = sizeof(uint32_t);
963 CurValue[iCount].ulValueBuf = MOS_AllocMemory(sizeof(uint32_t));
964 if(CurValue[iCount].ulValueBuf == nullptr)
965 {
966 eStatus = MOS_STATUS_NO_SPACE;
967 break;
968 }
969 *(uint32_t*)(CurValue[iCount].ulValueBuf) = atoi(szTmp);
970 break;
971 case UF_QWORD: // 64-bit
972 if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
973 {
974 break;
975 }
976
977 CurValue[iCount].ulValueLen = sizeof(uint64_t);
978 CurValue[iCount].ulValueBuf = MOS_AllocMemory(sizeof(uint64_t));
979 if(CurValue[iCount].ulValueBuf == nullptr)
980 {
981 eStatus = MOS_STATUS_NO_SPACE;
982 break;
983 }
984 tmpChar = &szTmp[0];
985 *(uint64_t*)(CurValue[iCount].ulValueBuf) = strtoll(tmpChar,&tmpChar,0);
986 break;
987 case UF_SZ:
988 case UF_MULTI_SZ:
989 if (MOS_FAILED(_UserFeature_ReadNextTokenFromFile(File, MAX_UF_LINE_STRING_FORMAT, szTmp)))
990 {
991 break;
992 }
993
994 nSize = strlen(szTmp);
995 CurValue[iCount].ulValueLen = (nSize+1)*sizeof(char );
996 CurValue[iCount].ulValueBuf = MOS_AllocMemory(nSize+1);
997 if(CurValue[iCount].ulValueBuf == nullptr)
998 {
999 eStatus = MOS_STATUS_NO_SPACE;
1000 break;
1001 }
1002 MOS_ZeroMemory(CurValue[iCount].ulValueBuf, nSize+1);
1003 MOS_SecureMemcpy(CurValue[iCount].ulValueBuf, nSize, szTmp, nSize);
1004 break;
1005 default:
1006 eStatus = MOS_STATUS_UNKNOWN;
1007 }
1008 if (eStatus != MOS_STATUS_SUCCESS)
1009 {
1010 break;
1011 }
1012
1013 iCount ++; // do the error checking near the top
1014
1015 } // if ( iResult == 0 )
1016 else // It is not a value starting, it's bad User Feature File.
1017 {
1018 int32_t iResult = strcmp(szTmp, "");
1019 if ( !iResult )
1020 {
1021 continue;
1022 }
1023 else
1024 {
1025 eStatus = MOS_STATUS_INVALID_PARAMETER;
1026 break;
1027 }
1028 } // else ( iResult == 0 )
1029 }
1030 } // while (feof(File) != EOF)
1031
1032 if (eStatus == MOS_STATUS_SUCCESS)
1033 {
1034 if ( bEmpty && (strlen(CurKey->pcKeyName) > 0) &&
1035 (CurKey->ulValueNum == 0) )
1036 {
1037 CurKey->pValueArray = CurValue;
1038 CurKey->ulValueNum = iCount;
1039 if(_UserFeature_Add(pKeyList, CurKey) != MOS_STATUS_SUCCESS)
1040 {
1041 // if the CurKey didn't be added in pKeyList, free it.
1042 for (uint32_t i = 0; i < iCount; i++)
1043 {
1044 if (CurValue)
1045 {
1046 MOS_FreeMemory(CurValue[i].ulValueBuf);
1047 }
1048 }
1049 MOS_FreeMemory(CurValue);
1050 MOS_FreeMemory(CurKey);
1051 }
1052 }
1053 else
1054 {
1055 for (uint32_t i = 0; i < iCount; i++)
1056 {
1057 if (CurValue)
1058 {
1059 MOS_FreeMemory(CurValue[i].ulValueBuf);
1060 }
1061 }
1062 MOS_FreeMemory(CurValue);
1063 MOS_FreeMemory(CurKey);
1064 }
1065 }
1066 else
1067 {
1068 for (uint32_t i = 0; i < iCount; i++)
1069 {
1070 if (CurValue)
1071 {
1072 MOS_FreeMemory(CurValue[i].ulValueBuf);
1073 }
1074 }
1075 MOS_FreeMemory(CurValue);
1076 MOS_FreeMemory(CurKey);
1077 }
1078 fclose(File);
1079 return eStatus;
1080 }
1081
1082 /*----------------------------------------------------------------------------
1083 | Name : _UserFeature_DumpDataToFile
1084 | Purpose : This function dump key linked list data to File.
1085 | Arguments : szFileName [in] A handle to the File.
1086 | pKeyList [in] Reserved, any LPDWORD type value.
1087 | Returns : MOS_STATUS_SUCCESS Operation success.
1088 | MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED File can't be written.
1089 | Comments :
1090 \---------------------------------------------------------------------------*/
_UserFeature_DumpDataToFile(const char * szFileName,MOS_PUF_KEYLIST pKeyList)1091 static MOS_STATUS _UserFeature_DumpDataToFile(const char *szFileName, MOS_PUF_KEYLIST pKeyList)
1092 {
1093 int32_t iResult;
1094 PFILE File;
1095 MOS_PUF_KEYLIST pKeyTmp;
1096 int32_t j;
1097
1098 File = fopen(szFileName, "w+");
1099 if ( !File )
1100 {
1101 return MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
1102 }
1103
1104 for (pKeyTmp = pKeyList; pKeyTmp; pKeyTmp = pKeyTmp->pNext)
1105 {
1106 fprintf(File, "%s\n", UF_KEY_ID);
1107 fprintf(File, "\t0x%.8x\n", (uint32_t)(uintptr_t)pKeyTmp->pElem->UFKey);
1108 fprintf(File, "\t%s\n", pKeyTmp->pElem->pcKeyName);
1109 for ( j = 0; j < (int32_t)pKeyTmp->pElem->ulValueNum; j ++ )
1110 {
1111 fprintf(File, "\t\t%s\n", UF_VALUE_ID);
1112 if ( strlen(pKeyTmp->pElem->pValueArray[j].pcValueName) > 0 )
1113 {
1114 fprintf(File, "\t\t\t%s\n",
1115 pKeyTmp->pElem->pValueArray[j].pcValueName);
1116 }
1117 fprintf(File, "\t\t\t%d\n", pKeyTmp->pElem->pValueArray[j].ulValueType);
1118 if (pKeyTmp->pElem->pValueArray[j].ulValueBuf != nullptr)
1119 {
1120 switch (pKeyTmp->pElem->pValueArray[j].ulValueType)
1121 {
1122 case UF_SZ:
1123 fprintf(File, "\t\t\t%s\n",
1124 (char *)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1125 break;
1126 case UF_DWORD:
1127 case UF_QWORD:
1128 fprintf(File, "\t\t\t%d\n",
1129 *(uint32_t*)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1130 break;
1131 default:
1132 fprintf(File, "\t\t\t%s\n",
1133 (char *)(pKeyTmp->pElem->pValueArray[j].ulValueBuf));
1134 break;
1135 } //switch (pKeyTmp->pElem->pValueArray[j].ulValueType)
1136 }
1137 } // for ( j = 0; j < (int32_t)pKeyTmp->pElem->ulValueNum; j ++ )
1138 } //for (pKeyTmp = pKeyList; pKeyTmp; pKeyTmp = pKeyTmp->pNext)
1139 fclose(File);
1140 MOS_UserFeatureNotifyChangeKeyValue(nullptr, false, nullptr, true);
1141
1142 return MOS_STATUS_SUCCESS;
1143 }
1144
1145 /*----------------------------------------------------------------------------
1146 | Name : _UserFeature_FreeKeyList
1147 | Purpose : Free key list
1148 | Arguments : pKeyList [in] key list to be free.
1149 | Returns : None
1150 | Comments :
1151 \---------------------------------------------------------------------------*/
_UserFeature_FreeKeyList(MOS_PUF_KEYLIST pKeyList)1152 static void _UserFeature_FreeKeyList(MOS_PUF_KEYLIST pKeyList)
1153 {
1154 MOS_PUF_KEYLIST pKeyTmp;
1155 MOS_PUF_KEYLIST pKeyTmpNext;
1156 uint32_t i;
1157
1158 pKeyTmp = pKeyList;
1159 while(pKeyTmp)
1160 {
1161 pKeyTmpNext = pKeyTmp->pNext;
1162 for(i=0;i<pKeyTmp->pElem->ulValueNum;i++)
1163 {
1164 MOS_FreeMemory(pKeyTmp->pElem->pValueArray[i].ulValueBuf);
1165 }
1166 MOS_FreeMemory(pKeyTmp->pElem->pValueArray);
1167 MOS_FreeMemory(pKeyTmp->pElem);
1168 MOS_FreeMemory(pKeyTmp);
1169 pKeyTmp = pKeyTmpNext;
1170 }
1171 return;
1172 }
1173
1174 /*----------------------------------------------------------------------------
1175 | Name : _UserFeature_SetValue
1176 | Purpose : Modify or add a value of the specified user feature key.
1177 | Arguments : strKey [in] Pointer to user feature key name.
1178 | pcValueName [in] Pointer to a string containing the name of
1179 | the value to set. If a value with this name
1180 | is not already present in the key, the
1181 | function adds it to the key.
1182 | uiValueType [in] Type of information to be stored.
1183 | szValueData [in] Pointer to a null-terminated string
1184 | containing the data to set for the default
1185 | value of the specified key
1186 | uiValueDataLen [in] Size of the string pointed to by the
1187 | szValueData parameter, not including the
1188 | terminating null character, in bytes
1189 | Returns : MOS_STATUS_SUCCESS function success
1190 | MOS_STATUS_INVALID_PARAMETER invalid paramater
1191 | MOS_STATUS_USER_FEATURE_KEY_READ_FAILED User Feature File can't be open as read.
1192 | MOS_STATUS_NO_SPACE no space left for allocate
1193 | MOS_STATUS_UNKNOWN unknown user feature type found in User Feature File
1194 | MOS_STATUS_INVALID_PARAMETER unknown items found in User Feature File
1195 | MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED User Feature File can't be written.
1196 | Comments :
1197 \---------------------------------------------------------------------------*/
_UserFeature_SetValue(char * const strKey,const char * const pcValueName,uint32_t uiValueType,void * pData,int32_t nDataSize)1198 static MOS_STATUS _UserFeature_SetValue(
1199 char * const strKey,
1200 const char * const pcValueName,
1201 uint32_t uiValueType,
1202 void *pData,
1203 int32_t nDataSize)
1204 {
1205 MOS_UF_KEY NewKey;
1206 MOS_UF_VALUE NewValue;
1207 MOS_STATUS eStatus;
1208 MOS_PUF_KEYLIST pKeyList;
1209
1210 eStatus = MOS_STATUS_UNKNOWN;
1211 pKeyList = nullptr;
1212
1213 if ( (strKey== nullptr) || (pcValueName == nullptr) )
1214 {
1215 return MOS_STATUS_INVALID_PARAMETER;
1216 }
1217
1218 MOS_ZeroMemory(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH);
1219 MOS_SecureStrcpy(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH, pcValueName);
1220 NewValue.ulValueType = uiValueType;
1221 if( NewValue.ulValueType == UF_DWORD)
1222 {
1223 NewValue.ulValueLen = sizeof(uint32_t);
1224 }
1225 else
1226 {
1227 NewValue.ulValueLen = nDataSize;
1228 }
1229 NewValue.ulValueBuf = pData;
1230
1231 MOS_ZeroMemory(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH);
1232 MOS_SecureStrcpy(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH, strKey);
1233 NewKey.pValueArray = &NewValue;
1234 NewKey.ulValueNum = 1;
1235
1236 if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) != MOS_STATUS_SUCCESS )
1237 {
1238 MOS_FreeMemory(pKeyList);
1239 return eStatus;
1240 }
1241
1242 if ( ( eStatus = _UserFeature_Set(&pKeyList, NewKey)) == MOS_STATUS_SUCCESS )
1243 {
1244 eStatus = _UserFeature_DumpDataToFile(szUserFeatureFile, pKeyList);
1245 }
1246
1247 _UserFeature_FreeKeyList(pKeyList);
1248 return eStatus;
1249 }
1250
1251 /*----------------------------------------------------------------------------
1252 | Name : _UserFeature_QueryValue
1253 | Purpose : The QueryValue function retrieves the type and data for a
1254 | specified value name associated with a special user feature key.
1255 | Arguments : strKey [in] Pointer to user feature key name.
1256 | pcValueName [in] Pointer to a string containing the name
1257 | of the value to query.
1258 | uiValueType [out] Output Value's type
1259 | pData [out] Output value's content
1260 | nDataSize [out] Output the size of value's content.
1261 | Returns : MOS_STATUS_SUCCESS function success
1262 | MOS_STATUS_INVALID_PARAMETER invalid paramater
1263 | MOS_STATUS_USER_FEATURE_KEY_READ_FAILED User Feature File can't be open as read.
1264 | MOS_STATUS_NO_SPACE no space left for allocate
1265 | MOS_STATUS_UNKNOWN Can't find key or value in User Feature File.
1266 | Comments :
1267 \---------------------------------------------------------------------------*/
_UserFeature_QueryValue(char * const strKey,const char * const pcValueName,uint32_t * uiValueType,void * pData,int32_t * nDataSize)1268 static MOS_STATUS _UserFeature_QueryValue(
1269 char * const strKey,
1270 const char * const pcValueName,
1271 uint32_t *uiValueType,
1272 void *pData,
1273 int32_t *nDataSize)
1274 {
1275 MOS_UF_KEY NewKey;
1276 MOS_UF_VALUE NewValue;
1277 size_t nKeyLen, nValueLen;
1278 MOS_STATUS eStatus;
1279 MOS_PUF_KEYLIST pKeyList;
1280 char strTempKey[MAX_USERFEATURE_LINE_LENGTH];
1281 char strTempValueName[MAX_USERFEATURE_LINE_LENGTH];
1282
1283 eStatus = MOS_STATUS_UNKNOWN;
1284 pKeyList = nullptr;
1285
1286 if ( (strKey == nullptr) || (pcValueName == nullptr))
1287 {
1288 return MOS_STATUS_INVALID_PARAMETER;
1289 }
1290 MOS_ZeroMemory(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH);
1291 MOS_SecureStrcpy(NewValue.pcValueName, MAX_USERFEATURE_LINE_LENGTH, pcValueName);
1292 NewValue.ulValueBuf = pData;
1293
1294 MOS_ZeroMemory(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH);
1295 MOS_SecureStrcpy(NewKey.pcKeyName, MAX_USERFEATURE_LINE_LENGTH, strKey);
1296 NewKey.pValueArray = &NewValue;
1297 NewKey.ulValueNum = 1;
1298
1299 if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) == MOS_STATUS_SUCCESS)
1300 {
1301 if ( (eStatus = _UserFeature_Query(pKeyList, &NewKey)) == MOS_STATUS_SUCCESS )
1302 {
1303 if(uiValueType != nullptr)
1304 {
1305 *uiValueType = NewKey.pValueArray[0].ulValueType;
1306 }
1307 if (nDataSize != nullptr)
1308 {
1309 *nDataSize = NewKey.pValueArray[0].ulValueLen;
1310 }
1311 }
1312 }
1313 _UserFeature_FreeKeyList(pKeyList);
1314
1315 return eStatus;
1316 }
1317
1318 /*----------------------------------------------------------------------------
1319 | Name : _UserFeature_GetKeyIdbyName
1320 | Purpose : Get ID of the user feature key bu its name
1321 | Arguments : pcKeyName [in] Pointer to user feature key name.
1322 | pUFKey [out] A UFKEY pointer to store returned UFKey
1323 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1324 | If the function fails, the return value is a error code defined
1325 | in mos_utilities.h.
1326 | Comments :
1327 \---------------------------------------------------------------------------*/
_UserFeature_GetKeyIdbyName(const char * pcKeyName,void ** pUFKey)1328 static MOS_STATUS _UserFeature_GetKeyIdbyName(const char *pcKeyName, void **pUFKey)
1329 {
1330 MOS_PUF_KEYLIST pKeyList;
1331 int32_t iResult;
1332 MOS_STATUS eStatus;
1333 MOS_PUF_KEYLIST pTempNode;
1334
1335 pKeyList = nullptr;
1336 iResult = -1;
1337
1338 if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) !=
1339 MOS_STATUS_SUCCESS )
1340 {
1341 MOS_FreeMemory(pKeyList);
1342 return eStatus;
1343 }
1344
1345 eStatus = MOS_STATUS_INVALID_PARAMETER;
1346
1347 for(pTempNode=pKeyList; pTempNode; pTempNode=pTempNode->pNext)
1348 {
1349 iResult = strcmp(pTempNode->pElem->pcKeyName, pcKeyName);
1350 if ( iResult == 0 )
1351 {
1352 *pUFKey = pTempNode->pElem->UFKey;
1353 eStatus = MOS_STATUS_SUCCESS;
1354 break;
1355 }
1356 }
1357 _UserFeature_FreeKeyList(pKeyList);
1358
1359 return eStatus;
1360 }
1361
1362 /*----------------------------------------------------------------------------
1363 | Name : _UserFeature_GetKeyNamebyId
1364 | Purpose : Get name of the user feature key bu its ID
1365 | Arguments : UFKey [in] ID of the user feature key
1366 | pcKeyName [out] To store user feature key name.
1367 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1368 | If the function fails, the return value is a error code defined
1369 | in mos_utilities.h.
1370 | Comments :
1371 \---------------------------------------------------------------------------*/
_UserFeature_GetKeyNamebyId(void * UFKey,char * pcKeyName)1372 static MOS_STATUS _UserFeature_GetKeyNamebyId(void *UFKey, char *pcKeyName)
1373 {
1374 MOS_PUF_KEYLIST pKeyList;
1375 MOS_PUF_KEYLIST pTempNode;
1376 MOS_STATUS eStatus;
1377
1378 pKeyList = nullptr;
1379
1380 switch((uintptr_t)UFKey)
1381 {
1382 case UFKEY_INTERNAL:
1383 MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_INTERNAL);
1384 eStatus = MOS_STATUS_SUCCESS;
1385 break;
1386 case UFKEY_EXTERNAL:
1387 MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_EXTERNAL);
1388 eStatus = MOS_STATUS_SUCCESS;
1389 break;
1390 default:
1391 if ( (eStatus = _UserFeature_DumpFile(szUserFeatureFile, &pKeyList)) !=
1392 MOS_STATUS_SUCCESS )
1393 {
1394 MOS_FreeMemory(pKeyList);
1395 return eStatus;
1396 }
1397
1398 eStatus = MOS_STATUS_UNKNOWN;
1399
1400 for(pTempNode=pKeyList;pTempNode;pTempNode=pTempNode->pNext)
1401 {
1402 if(pTempNode->pElem->UFKey == UFKey)
1403 {
1404 MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, pTempNode->pElem->pcKeyName);
1405 eStatus = MOS_STATUS_SUCCESS;
1406 break;
1407 }
1408 }
1409 _UserFeature_FreeKeyList(pKeyList);
1410 break;
1411 }
1412
1413 return eStatus;
1414
1415 }
1416
1417 /*----------------------------------------------------------------------------
1418 | Name : MOS_CheckMountStatus
1419 | Purpose : check mount status
1420 | Arguments : pKeyWord [in] Keyword for the Mountpoint
1421 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1422 | If the function fails, the return value is a error code defined
1423 | in mos_utilities.h.
1424 | Comments :
1425 \---------------------------------------------------------------------------*/
MOS_CheckMountStatus(char * pKeyWord)1426 MOS_STATUS MOS_CheckMountStatus(char *pKeyWord)
1427 {
1428 char sPartitionPath[MAX_UF_PATH] = {'\0'};
1429 char sMountPoint[MAX_UF_PATH] = {'\0'};
1430 char sSystemType[MAX_UF_PATH] = {'\0'};
1431 char sTemp0[MAX_UF_PATH] = {'\0'};
1432 char sTemp1[MAX_UF_PATH] = {'\0'};
1433 char sTemp2[MAX_UF_PATH] = {'\0'};
1434 FILE* file;
1435 MOS_STATUS eStatus = MOS_STATUS_UNKNOWN;
1436
1437 file = fopen("/proc/mounts", "r");
1438 MOS_OS_CHK_NULL(file);
1439 MOS_OS_CHK_NULL(pKeyWord);
1440
1441 while( fscanf( file, "%255s %255s %255s %255s %255s %255s\n", sPartitionPath, sMountPoint, sSystemType, sTemp0, sTemp1, sTemp2 ) > 0 )
1442 {
1443 if( strcmp(sSystemType, pKeyWord) == 0 )
1444 {
1445 eStatus = MOS_STATUS_SUCCESS;
1446 break;
1447 }
1448 if( strcmp(sMountPoint, pKeyWord) == 0 )
1449 {
1450 eStatus = MOS_STATUS_SUCCESS;
1451 break;
1452 }
1453 }
1454 finish:
1455 if (file != nullptr)
1456 {
1457 fclose(file);
1458 }
1459 return eStatus;
1460 }
1461 #ifdef ANDROID
1462 /*----------------------------------------------------------------------------
1463 | Name : MOS_Strip_Chars
1464 | Purpose : Strip some characters from a string
1465 | Arguments : pstorestr [out] To store a striped string.
1466 | pstring [in] string needed to be striped.
1467 | pchars [in] stripped keyword.
1468 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1469 | If the function fails, the return value is an error code defined
1470 | in mos_utilities.h.
1471 | Comments :
1472 \---------------------------------------------------------------------------*/
MOS_StripChars(char * pstorestr,const char * pstring,const char * pchars)1473 MOS_STATUS MOS_StripChars(char *pstorestr, const char *pstring, const char *pchars)
1474 {
1475 int32_t counter = 0;
1476 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1477
1478 MOS_OS_CHK_NULL(pstring);
1479 MOS_OS_CHK_NULL(pchars);
1480
1481 for ( ; *pstring; pstring++)
1482 {
1483 if (!strchr(pchars, *pstring))
1484 {
1485 pstorestr[ counter ] = *pstring;
1486 ++ counter;
1487 }
1488 }
1489 pstorestr[counter] = 0;
1490 finish:
1491 return eStatus;
1492 }
1493
1494 /*----------------------------------------------------------------------------
1495 | Name : MOS_InitAndroidPropInfo
1496 | Purpose : Init Android Property Info
1497 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1498 | If the function fails, the return value is a error code defined
1499 | in mos_utilities.h.
1500 | Comments :
1501 \---------------------------------------------------------------------------*/
MOS_InitAndroidPropInfo()1502 MOS_STATUS MOS_InitAndroidPropInfo()
1503 {
1504 char prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1505 MOS_STATUS eStatus = MOS_STATUS_UNKNOWN;
1506 int32_t ret;
1507 int32_t iUFKeyEnable;
1508 MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
1509
1510 eStatus = MOS_CheckMountStatus((char *)"/system");
1511 if (eStatus == MOS_STATUS_SUCCESS)
1512 {
1513 eStatus = MOS_STATUS_UNKNOWN;
1514 if (property_get("debug.LibVa.RegKeyEnable", prop, nullptr) > 0)
1515 {
1516 if (sscanf(prop, "%d\n", &iUFKeyEnable) > 0)
1517 {
1518 if (iUFKeyEnable == 1)
1519 {
1520 eStatus = MOS_STATUS_SUCCESS;
1521 }
1522 }
1523 }
1524 }
1525 return eStatus;
1526 }
1527
1528 /*----------------------------------------------------------------------------
1529 | Name : MOS_GetAndroidPropPath
1530 | Purpose : get AndroidProp path
1531 | Arguments : pPath [out] store the path
1532 | pUserFeature [in] User Feature data for input User Feature Key
1533 | FuncType [in] Read/Write Type
1534 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1535 | If the function fails, the return value is a error code defined
1536 | in mos_utilities.h.
1537 | Comments :
1538 \---------------------------------------------------------------------------*/
MOS_GetAndroidPropPath(char * pPath,PMOS_USER_FEATURE_VALUE pUserFeature,LINUX_UF_FUNC_TYPE FuncType)1539 MOS_STATUS MOS_GetAndroidPropPath(
1540 char *pPath,
1541 PMOS_USER_FEATURE_VALUE pUserFeature,
1542 LINUX_UF_FUNC_TYPE FuncType)
1543 {
1544
1545 char sPath[MAX_UF_PATH];
1546 char sKey[MAX_UF_PATH];
1547 char sFuncType[MAX_UF_PATH];
1548 char pPrefixPath[MAX_UF_PATH];
1549 char sUFName[MAX_UF_PATH];
1550 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1551 MOS_OS_CHK_NULL(pUserFeature);
1552 MOS_OS_CHK_NULL(pPath);
1553
1554 MOS_ZeroMemory(sPath, MAX_UF_PATH);
1555 MOS_ZeroMemory(sKey, MAX_UF_PATH);
1556 switch(pUserFeature->Type)
1557 {
1558 case MOS_USER_FEATURE_TYPE_USER:
1559 MOS_SecureStrcpy(sKey, MAX_UF_PATH, UFINT_PATH_LINUX);
1560 break;
1561 case MOS_USER_FEATURE_TYPE_SYSTEM:
1562 MOS_SecureStrcpy(sKey, MAX_UF_PATH, UFEXT_PATH_LINUX);
1563 break;
1564 default:
1565 MOS_SecureStrcpy(sKey, MAX_UF_PATH, UFINT_PATH_LINUX);
1566 break;
1567 }// switch
1568
1569 MOS_ZeroMemory(sFuncType, MAX_UF_PATH);
1570 switch(FuncType)
1571 {
1572 case LINUX_UF_FUNCTYPE_READ:
1573 MOS_SecureStrcpy(sFuncType, MAX_UF_PATH, pUserFeature->pcPath);
1574 break;
1575 case LINUX_UF_FUNCTYPE_WRITE:
1576 MOS_SecureStrcpy(sFuncType, MAX_UF_PATH, pUserFeature->pcWritePath);
1577 break;
1578 default:
1579 MOS_SecureStrcpy(sFuncType, MAX_UF_PATH, pUserFeature->pcPath);
1580 break;
1581 }// switch
1582
1583 MOS_OS_CHK_STATUS(MOS_StripChars(sUFName,pUserFeature->pValueName," "));
1584 snprintf(
1585 sPath,
1586 sizeof(sPath),
1587 "%s.%s.%s",
1588 sKey,
1589 sFuncType,
1590 sUFName);
1591
1592 MOS_SecureMemcpy(pPath, strlen(sPath)+1, sPath, strlen(sPath)+1);
1593 finish:
1594 return eStatus;
1595 }
1596
1597 /*----------------------------------------------------------------------------
1598 | Name : MOS_AndroidPropOpenKey
1599 | Purpose : open a file for AndroidProp
1600 | Arguments : pPath [in]
1601 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1602 | If the function fails, the return value is a error code defined
1603 | in mos_utilities.h.
1604 | Comments :
1605 \---------------------------------------------------------------------------*/
MOS_AndroidPropOpenKey(char * pPath)1606 MOS_STATUS MOS_AndroidPropOpenKey(
1607 char *pPath)
1608 {
1609 MOS_STATUS eStatus = MOS_STATUS_FILE_OPEN_FAILED;
1610 char prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1611 MOS_OS_CHK_NULL(pPath);
1612
1613 if (property_get(pPath, prop, nullptr) > 0)
1614 {
1615 eStatus = MOS_STATUS_SUCCESS;
1616 }
1617 finish:
1618 return eStatus;
1619 }
1620
1621 /*----------------------------------------------------------------------------
1622 | Name : MOS_AndroidPropWriteValue
1623 | Purpose : write a AndroidProp User Feature Data Value
1624 | Arguments : pPath [in]
1625 | pUserData [in] user feature key write value
1626 | ValueType [in] Type of Data
1627 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1628 | If the function fails, the return value is a error code defined
1629 | in mos_utilities.h.
1630 | Comments :
1631 \---------------------------------------------------------------------------*/
MOS_AndroidPropWriteValue(char * pPath,PMOS_USER_FEATURE_VALUE_DATA pUserData,MOS_USER_FEATURE_VALUE_TYPE ValueType)1632 MOS_STATUS MOS_AndroidPropWriteValue(
1633 char *pPath,
1634 PMOS_USER_FEATURE_VALUE_DATA pUserData,
1635 MOS_USER_FEATURE_VALUE_TYPE ValueType)
1636 {
1637 MOS_STATUS eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
1638 char prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1639 int32_t ret = 0;
1640 MOS_OS_CHK_NULL(pPath);
1641 MOS_OS_CHK_NULL(pUserData);
1642
1643 switch(ValueType)
1644 {
1645 case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
1646 ret = snprintf(prop, sizeof(prop), "%d\n", pUserData->bData);
1647 break;
1648 case MOS_USER_FEATURE_VALUE_TYPE_INT32:
1649 ret = snprintf(prop, sizeof(prop), "%d\n", pUserData->i32Data);
1650 break;
1651 case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
1652 ret = snprintf(prop, sizeof(prop), "%u\n", pUserData->u32Data);
1653 break;
1654 case MOS_USER_FEATURE_VALUE_TYPE_INT64:
1655 ret = snprintf(prop, sizeof(prop), "%" MOSd64 "\n", pUserData->i64Data);
1656 break;
1657 case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
1658 ret = snprintf(prop, sizeof(prop), "%" MOSu64 "\n", pUserData->u64Data);
1659 break;
1660 case MOS_USER_FEATURE_VALUE_TYPE_STRING:
1661 if ((pUserData->StringData.pStringData != nullptr) && (strlen(pUserData->StringData.pStringData) != 0))
1662 {
1663 ret = snprintf(prop, sizeof(prop), "%s\n", pUserData->StringData.pStringData);
1664 }
1665 break;
1666 default:
1667 break;
1668 }
1669 if (ret > 0)
1670 {
1671 ret = property_set(pPath, prop);
1672 if (ret == 0)
1673 {
1674 eStatus = MOS_STATUS_SUCCESS;
1675 }
1676 }
1677 finish:
1678 return eStatus;
1679 }
1680
1681 /*----------------------------------------------------------------------------
1682 | Name : MOS_AndroidPropCreateKey
1683 | Purpose : set default value to AndroidProp User Feature Key according to userfeature
1684 | Arguments : pUserFeature [in] value for ceated key
1685 | FuncType [in] Type of function
1686 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1687 | If the function fails, the return value is a error code defined
1688 | in mos_utilities.h.
1689 | Comments :
1690 \---------------------------------------------------------------------------*/
MOS_AndroidPropCreateKey(PMOS_USER_FEATURE_VALUE pUserFeature,LINUX_UF_FUNC_TYPE FuncType)1691 MOS_STATUS MOS_AndroidPropCreateKey(
1692 PMOS_USER_FEATURE_VALUE pUserFeature,
1693 LINUX_UF_FUNC_TYPE FuncType)
1694 {
1695 char sPath[MAX_UF_PATH];
1696 MOS_STATUS eStatus = MOS_STATUS_DIR_CREATE_FAILED;
1697 MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
1698 MOS_USER_FEATURE_VALUE_TYPE ValueType = MOS_USER_FEATURE_VALUE_TYPE_INVALID;
1699 char prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1700 int32_t ret;
1701
1702 MOS_OS_CHK_NULL(pUserFeature);
1703 MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
1704
1705 // create key
1706 MOS_ZeroMemory(sPath, MAX_UF_PATH);
1707 MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, FuncType));
1708 // set the default Data and Type value according to default value and type in pUserFeature.
1709 MOS_OS_CHK_STATUS(MOS_AndroidPropWriteValue(sPath, &pUserFeature->Value, pUserFeature->ValueType));
1710 finish:
1711 return eStatus;
1712 }
1713
1714 /*----------------------------------------------------------------------------
1715 | Name : MOS_AndroidPropReadValue
1716 | Purpose : read a AndroidProp User Feature Data Value
1717 | Arguments : pPath [in]
1718 | pUserData [out] To store user feature key value.
1719 | ValueType [in] Type of Data
1720 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1721 | If the function fails, the return value is a error code defined
1722 | in mos_utilities.h.
1723 | Comments :
1724 \---------------------------------------------------------------------------*/
MOS_AndroidPropReadValue(char * pPath,PMOS_USER_FEATURE_VALUE_DATA pUserData,MOS_USER_FEATURE_VALUE_TYPE ValueType)1725 MOS_STATUS MOS_AndroidPropReadValue(
1726 char *pPath,
1727 PMOS_USER_FEATURE_VALUE_DATA pUserData,
1728 MOS_USER_FEATURE_VALUE_TYPE ValueType)
1729 {
1730 MOS_USER_FEATURE_VALUE_DATA UserData;
1731 char pcTmpStr[MOS_USER_CONTROL_MAX_DATA_SIZE];
1732 MOS_STATUS eStatus = MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
1733 char prop[MOS_USER_CONTROL_MAX_DATA_SIZE];
1734 int32_t ret = 0;
1735
1736 MOS_OS_CHK_NULL(pPath);
1737 MOS_OS_CHK_NULL(pUserData);
1738
1739 MOS_ZeroMemory(&UserData, sizeof(UserData));
1740
1741 if (property_get(pPath, prop, nullptr) > 0)
1742 {
1743 switch(ValueType)
1744 {
1745 case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
1746 ret = sscanf(prop, "%d\n", &pUserData->bData);
1747 break;
1748 case MOS_USER_FEATURE_VALUE_TYPE_INT32:
1749 ret = sscanf(prop, "%d\n", &pUserData->i32Data);
1750 break;
1751 case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
1752 ret = sscanf(prop, "%u\n", &pUserData->u32Data);
1753 break;
1754 case MOS_USER_FEATURE_VALUE_TYPE_INT64:
1755 ret = sscanf(prop, "%" MOSd64 "\n", &pUserData->i64Data);
1756 break;
1757 case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
1758 ret = sscanf(prop, "%" MOSu64 "\n", &pUserData->u64Data);
1759 break;
1760 case MOS_USER_FEATURE_VALUE_TYPE_STRING:
1761 if( sscanf( prop, "%s\n", pcTmpStr) > 0 )
1762 {
1763 if (strlen(pcTmpStr) > 0)
1764 {
1765 MOS_SafeFreeMemory(pUserData->StringData.pStringData);
1766 pUserData->StringData.pStringData = (char *)MOS_AllocAndZeroMemory(strlen(pcTmpStr)+1);
1767 MOS_SecureMemcpy(pUserData->StringData.pStringData, strlen(pcTmpStr), pcTmpStr, MOS_MIN(strlen(pcTmpStr), MOS_USER_CONTROL_MAX_DATA_SIZE));
1768 pUserData->StringData.uSize = strlen(pcTmpStr);
1769 ret = pUserData->StringData.uSize;
1770 }
1771 }
1772 break;
1773 default:
1774 break;
1775 }
1776 }
1777 if (ret > 0)
1778 {
1779 eStatus = MOS_STATUS_SUCCESS;
1780 }
1781 finish:
1782 return eStatus;
1783 }
1784
1785 /*----------------------------------------------------------------------------
1786 | Name : MOS_UserFeatureOpenKey_AndroidProp
1787 | Purpose : Opens the specified user feature key.
1788 | Arguments : UFKey [in] A handle to an open user feature key.
1789 | lpSubKey [in] The name of the user feature subkey to be opened.
1790 | ulOptions [in] This parameter is reserved and must be zero.
1791 | samDesired [in] Reserved, could be any REGSAM type value
1792 | phkResult [out] A pointer to a variable that receives a handle
1793 | to the opened key.
1794 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1795 | If the function fails, the return value is a error code defined
1796 | in mos_utilities.h.
1797 | Comments :
1798 \---------------------------------------------------------------------------*/
MOS_UserFeatureOpenKey_AndroidProp(void * UFKey,const char * lpSubKey,uint32_t ulOptions,uint32_t samDesired,void ** phkResult)1799 MOS_STATUS MOS_UserFeatureOpenKey_AndroidProp(
1800 void *UFKey,
1801 const char *lpSubKey,
1802 uint32_t ulOptions,
1803 uint32_t samDesired,
1804 void **phkResult)
1805 {
1806 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
1807 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1808 PMOS_USER_FEATURE_VALUE pUserFeature = nullptr;
1809 char sPath[MAX_UF_PATH];
1810 LINUX_UF_FUNC_TYPE FuncType = LINUX_UF_FUNCTYPE_INVALID;
1811 MOS_UNUSED(UFKey);
1812 MOS_UNUSED(ulOptions);
1813
1814 MOS_OS_CHK_NULL(lpSubKey);
1815 pUserFeature = (PMOS_USER_FEATURE_VALUE)*phkResult;
1816 MOS_OS_CHK_NULL(pUserFeature);
1817 if( strcmp(lpSubKey, pUserFeature->pcWritePath) == 0 )
1818 {
1819 FuncType = LINUX_UF_FUNCTYPE_WRITE;
1820 }
1821 else if( strcmp(lpSubKey, pUserFeature->pcPath) == 0 )
1822 {
1823 FuncType = LINUX_UF_FUNCTYPE_READ;
1824 }
1825 MOS_ZeroMemory(sPath, MAX_UF_PATH);
1826 MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, FuncType));
1827 if (MOS_AndroidPropOpenKey(sPath) != MOS_STATUS_SUCCESS)
1828 {
1829 // No Sub Key return directly
1830 eStatus = MOS_STATUS_FILE_OPEN_FAILED;
1831 // KEY_WRITE
1832 if (samDesired == KEY_WRITE)
1833 {
1834 if (MOS_AndroidPropCreateKey(pUserFeature, FuncType) != MOS_STATUS_SUCCESS)
1835 {
1836 eStatus = MOS_STATUS_DIR_CREATE_FAILED;
1837 }
1838 }
1839 else
1840 {
1841 eStatus = MOS_STATUS_FILE_OPEN_FAILED;
1842 }
1843 }
1844 finish:
1845 return eStatus;
1846 }
1847
1848 /*----------------------------------------------------------------------------
1849 | Name : MOS_UserFeatureGetValue_AndroidProp
1850 | Purpose : Retrieves the type and data for the specified user feature value.
1851 | Arguments : UFKey [in] A handle to an open user feature key.
1852 | lpSubKey [in] The name of the user feature key. This key must be a
1853 | subkey of the key specified by the UFKey parameter
1854 | lpValue [in] The name of the user feature value.
1855 | dwFlags [in] Reserved, could be any uint32_t type value
1856 | pdwType [out] A pointer to a variable that receives a code
1857 | indicating the type of data stored in the
1858 | specified value.
1859 | pvData [out] A pointer to a buffer that receives the value's
1860 | data.
1861 | pcbData [out] A pointer to a variable that specifies the size
1862 | of the buffer pointed to by the pvData parameter,
1863 | in bytes.
1864 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1865 | If the function fails, the return value is a error code defined
1866 | in mos_utilities.h.
1867 | Comments :
1868 \---------------------------------------------------------------------------*/
MOS_UserFeatureGetValue_AndroidProp(void * UFKey,const char * lpSubKey,const char * lpValue,uint32_t dwFlags,uint32_t * pdwType,void * pvData,uint32_t * pcbData)1869 MOS_STATUS MOS_UserFeatureGetValue_AndroidProp(
1870 void *UFKey,
1871 const char *lpSubKey,
1872 const char *lpValue,
1873 uint32_t dwFlags,
1874 uint32_t *pdwType,
1875 void *pvData,
1876 uint32_t *pcbData)
1877 {
1878 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
1879 int32_t dData;
1880 int32_t index = 0;
1881 PMOS_USER_FEATURE_VALUE pSettingsValue;
1882 PMOS_USER_FEATURE_VALUE pUserFeature = nullptr;
1883 char sPath[MAX_UF_PATH];
1884 MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
1885 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1886 MOS_UNUSED(lpSubKey);
1887 MOS_UNUSED(lpValue);
1888 MOS_UNUSED(dwFlags);
1889 MOS_UNUSED(pdwType);
1890
1891 if(UFKey == nullptr)
1892 {
1893 eStatus = MOS_STATUS_INVALID_PARAMETER;
1894 goto finish;
1895 }
1896 pUserFeature = (PMOS_USER_FEATURE_VALUE)UFKey;
1897
1898 MOS_ZeroMemory(sPath, MAX_UF_PATH);
1899 MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, LINUX_UF_FUNCTYPE_READ));
1900
1901 // Read Type
1902 MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
1903 if (MOS_AndroidPropReadValue(sPath, &UserFeatureData, pUserFeature->ValueType) == MOS_STATUS_SUCCESS)
1904 {
1905 // get key content from user feature
1906 switch(pUserFeature->ValueType)
1907 {
1908 case MOS_USER_FEATURE_VALUE_TYPE_BINARY:
1909 *(int32_t*)pvData = UserFeatureData.bData;
1910 *(uint32_t*)pcbData = sizeof(int32_t);
1911 break;
1912 case MOS_USER_FEATURE_VALUE_TYPE_INT32:
1913 *(int32_t*)pvData = UserFeatureData.i32Data;
1914 *(uint32_t*)pcbData = sizeof(int32_t);
1915 break;
1916 case MOS_USER_FEATURE_VALUE_TYPE_INT64:
1917 *(int64_t*)pvData = UserFeatureData.i64Data;
1918 *(uint32_t*)pcbData = sizeof(int64_t);
1919 break;
1920 case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
1921 *(uint32_t*)pvData = UserFeatureData.u32Data;
1922 *(uint32_t*)pcbData = sizeof(uint32_t);
1923 break;
1924 case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
1925 *(uint64_t*)pvData = UserFeatureData.u64Data;
1926 *(uint32_t*)pcbData = sizeof(uint64_t);
1927 break;
1928 case MOS_USER_FEATURE_VALUE_TYPE_STRING:
1929 MOS_SecureMemcpy(pvData, UserFeatureData.StringData.uSize, UserFeatureData.StringData.pStringData, UserFeatureData.StringData.uSize);
1930 MOS_SafeFreeMemory(UserFeatureData.StringData.pStringData);
1931 *(uint32_t*)pcbData = UserFeatureData.StringData.uSize;
1932 break;
1933 default:
1934 break;
1935 }// switch
1936 }
1937 else
1938 {
1939 eStatus = MOS_STATUS_FILE_NOT_FOUND;
1940 }
1941 finish:
1942 return eStatus;
1943 }
1944
1945 /*----------------------------------------------------------------------------
1946 | Name : MOS_UserFeatureSetValueEx_AndroidProp
1947 | Purpose : Sets the data and type of a specified value under a user feature key.
1948 | Arguments : UFKey [in] A handle to an open user feature key.
1949 | lpValueName [in] The name of the user feature value.
1950 | Reserved [in] This parameter is reserved and must be NULL.
1951 | dwType [in] The type of data pointed to by the lpData
1952 | parameter.
1953 | lpData [in] The data to be stored.
1954 | cbData [in] The size of the information pointed to by the
1955 | lpData parameter, in bytes.
1956 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
1957 | If the function fails, the return value is a error code defined
1958 | in mos_utilities.h.
1959 | Comments :
1960 \---------------------------------------------------------------------------*/
MOS_UserFeatureSetValueEx_AndroidProp(void * UFKey,const char * lpValueName,uint32_t Reserved,uint32_t dwType,uint8_t * lpData,uint32_t cbData)1961 MOS_STATUS MOS_UserFeatureSetValueEx_AndroidProp(
1962 void *UFKey,
1963 const char *lpValueName,
1964 uint32_t Reserved,
1965 uint32_t dwType,
1966 uint8_t *lpData,
1967 uint32_t cbData)
1968 {
1969 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
1970 int32_t dData;
1971 int32_t index = 0;
1972 uint32_t ui;
1973 PMOS_USER_FEATURE_VALUE pUserFeature = nullptr;
1974 char sPath[MAX_UF_PATH];
1975 MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
1976 MOS_USER_FEATURE_VALUE_TYPE ValueType = MOS_USER_FEATURE_VALUE_TYPE_INVALID;
1977 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1978 MOS_UNUSED(lpValueName);
1979 MOS_UNUSED(Reserved);
1980 MOS_UNUSED(dwType);
1981
1982 if(UFKey == nullptr)
1983 {
1984 eStatus = MOS_STATUS_INVALID_PARAMETER;
1985 goto finish;
1986 }
1987 pUserFeature = (PMOS_USER_FEATURE_VALUE)UFKey;
1988 for (ui = 0; ui < pUserFeature->uiNumOfValues; ui++)
1989 {
1990 // Check the Key exist or not
1991 MOS_ZeroMemory(sPath, MAX_UF_PATH);
1992 MOS_OS_CHK_STATUS(MOS_GetAndroidPropPath(sPath, pUserFeature, LINUX_UF_FUNCTYPE_WRITE));
1993
1994 if (MOS_AndroidPropOpenKey(sPath) != MOS_STATUS_SUCCESS){
1995 // create the Key according to pFeatureValue->ValueType
1996 if( MOS_AndroidPropCreateKey(pUserFeature, LINUX_UF_FUNCTYPE_WRITE) != MOS_STATUS_SUCCESS )
1997 {
1998 eStatus = MOS_STATUS_DIR_CREATE_FAILED;
1999 goto finish;
2000 }
2001 }
2002 MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
2003 ValueType = (MOS_USER_FEATURE_VALUE_TYPE)pUserFeature->ValueType;
2004 switch(ValueType)
2005 {
2006 case MOS_USER_FEATURE_VALUE_TYPE_BINARY:
2007 UserFeatureData.bData =*(int32_t*)lpData ;
2008 break;
2009 case MOS_USER_FEATURE_VALUE_TYPE_INT32:
2010 UserFeatureData.i32Data =*(int32_t*)lpData ;
2011 break;
2012 case MOS_USER_FEATURE_VALUE_TYPE_INT64:
2013 UserFeatureData.i64Data =*(int64_t*)lpData;
2014 break;
2015 case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
2016 UserFeatureData.u32Data = *(uint32_t*)lpData;
2017 break;
2018 case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
2019 UserFeatureData.u64Data =*(uint64_t*)lpData;
2020 break;
2021 case MOS_USER_FEATURE_VALUE_TYPE_STRING:
2022 UserFeatureData.StringData.pStringData =(char *)lpData;
2023 UserFeatureData.StringData.uSize = cbData;
2024 break;
2025 default:
2026 break;
2027 }//switch
2028 if (MOS_AndroidPropWriteValue(sPath, &UserFeatureData, ValueType) != MOS_STATUS_SUCCESS)
2029 {
2030 eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
2031 goto finish;
2032 }
2033 }
2034 finish:
2035 return eStatus;
2036 }
2037 #endif
2038
2039 /*----------------------------------------------------------------------------
2040 | Name : MOS_UserFeatureOpenKey_File
2041 | Purpose : Opens the specified user feature key.
2042 | Arguments : UFKey [in] A handle to an open user feature key.
2043 | lpSubKey [in] The name of the user feature subkey to be opened.
2044 | ulOptions [in] This parameter is reserved and must be zero.
2045 | samDesired [in] Reserved, could be any REGSAM type value
2046 | phkResult [out] A pointer to a variable that receives a handle
2047 | to the opened key.
2048 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
2049 | If the function fails, the return value is a error code defined
2050 | in mos_utilities.h.
2051 | Comments :
2052 \---------------------------------------------------------------------------*/
MOS_UserFeatureOpenKey_File(void * UFKey,const char * lpSubKey,uint32_t ulOptions,uint32_t samDesired,void ** phkResult)2053 MOS_STATUS MOS_UserFeatureOpenKey_File(
2054 void *UFKey,
2055 const char *lpSubKey,
2056 uint32_t ulOptions, // reserved
2057 uint32_t samDesired,
2058 void **phkResult)
2059 {
2060 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2061 MOS_STATUS iRet;
2062 uintptr_t h_key = (uintptr_t)UFKey;
2063 MOS_UNUSED(ulOptions);
2064 MOS_UNUSED(samDesired);
2065
2066 if((h_key == 0) /*|| (lpSubKey == nullptr)*/ || (phkResult == nullptr)) //[SH]: subkey can be NULL???
2067 {
2068 return MOS_STATUS_INVALID_PARAMETER;
2069 }
2070
2071 MOS_ZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH*sizeof(char));
2072 switch(h_key)
2073 {
2074 case UFKEY_INTERNAL:
2075 MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_INTERNAL);
2076 break;
2077 case UFKEY_EXTERNAL:
2078 MOS_SecureStrcpy(pcKeyName, MAX_USERFEATURE_LINE_LENGTH, USER_FEATURE_KEY_EXTERNAL);
2079 break;
2080 default:
2081 break;
2082 }
2083
2084 MOS_SecureStrcat(pcKeyName, sizeof(pcKeyName), lpSubKey);
2085 iRet = _UserFeature_GetKeyIdbyName(pcKeyName, phkResult);
2086
2087 return iRet;
2088 }
2089
2090 /*----------------------------------------------------------------------------
2091 | Name : MOS_UserFeatureGetValue_File
2092 | Purpose : Retrieves the type and data for the specified user feature value.
2093 | Arguments : UFKey [in] A handle to an open user feature key.
2094 | lpSubKey [in] The name of the user feature key. This key must be a
2095 | subkey of the key specified by the UFKey parameter
2096 | lpValue [in] The name of the user feature value.
2097 | dwFlags [in] Reserved, could be any uint32_t type value
2098 | pdwType [out] A pointer to a variable that receives a code
2099 | indicating the type of data stored in the
2100 | specified value.
2101 | pvData [out] A pointer to a buffer that receives the value's
2102 | data.
2103 | pcbData [out] A pointer to a variable that specifies the size
2104 | of the buffer pointed to by the pvData parameter,
2105 | in bytes.
2106 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
2107 | If the function fails, the return value is a error code defined
2108 | in mos_utilities.h.
2109 | Comments :
2110 \---------------------------------------------------------------------------*/
MOS_UserFeatureGetValue_File(void * UFKey,const char * lpSubKey,const char * lpValue,uint32_t dwFlags,uint32_t * pdwType,void * pvData,uint32_t * pcbData)2111 MOS_STATUS MOS_UserFeatureGetValue_File(
2112 void *UFKey,
2113 const char *lpSubKey,
2114 const char *lpValue,
2115 uint32_t dwFlags,
2116 uint32_t *pdwType,
2117 void *pvData,
2118 uint32_t *pcbData)
2119 {
2120 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2121 MOS_STATUS eStatus;
2122 MOS_UNUSED(dwFlags);
2123
2124 if(UFKey == nullptr)
2125 {
2126 return MOS_STATUS_INVALID_PARAMETER;
2127 }
2128
2129 eStatus = MOS_STATUS_UNKNOWN;
2130 MOS_ZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH * sizeof(char));
2131 if ( (eStatus = _UserFeature_GetKeyNamebyId(UFKey,pcKeyName)) != MOS_STATUS_SUCCESS)
2132 {
2133 return eStatus;
2134 }
2135
2136 if(lpSubKey != nullptr)
2137 {
2138 MOS_SecureStrcat(pcKeyName, sizeof(pcKeyName), lpSubKey);
2139 }
2140 eStatus = _UserFeature_QueryValue(pcKeyName,
2141 lpValue,
2142 (uint32_t*)pdwType,
2143 pvData,
2144 (int32_t*)pcbData);
2145
2146 return eStatus;
2147 }
2148
2149 /*----------------------------------------------------------------------------
2150 | Name : MOS_UserFeatureSetValueEx_File
2151 | Purpose : Sets the data and type of a specified value under a user feature key.
2152 | Arguments : UFKey [in] A handle to an open user feature key.
2153 | lpValueName [in] The name of the user feature value.
2154 | Reserved in] This parameter is reserved and must be NULL.
2155 | dwType [in] The type of data pointed to by the lpData
2156 | parameter.
2157 | lpData [in] The data to be stored.
2158 | cbData [in] The size of the information pointed to by the
2159 | lpData parameter, in bytes.
2160 | Returns : If the function succeeds, the return value is MOS_STATUS_SUCCESS.
2161 | If the function fails, the return value is a error code defined
2162 | in mos_utilities.h.
2163 | Comments :
2164 \---------------------------------------------------------------------------*/
MOS_UserFeatureSetValueEx_File(void * UFKey,const char * lpValueName,uint32_t Reserved,uint32_t dwType,uint8_t * lpData,uint32_t cbData)2165 MOS_STATUS MOS_UserFeatureSetValueEx_File(
2166 void *UFKey,
2167 const char *lpValueName,
2168 uint32_t Reserved,
2169 uint32_t dwType,
2170 uint8_t *lpData,
2171 uint32_t cbData)
2172 {
2173 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2174 MOS_STATUS eStatus;
2175 MOS_UNUSED(Reserved);
2176
2177 if (UFKey == nullptr)
2178 {
2179 return MOS_STATUS_INVALID_PARAMETER;
2180 }
2181 MOS_ZeroMemory(pcKeyName, MAX_USERFEATURE_LINE_LENGTH*sizeof(char));
2182 if ((eStatus = _UserFeature_GetKeyNamebyId(UFKey,pcKeyName)) != MOS_STATUS_SUCCESS)
2183 {
2184 return eStatus;
2185 }
2186
2187 eStatus = _UserFeature_SetValue(pcKeyName,lpValueName,dwType,lpData,cbData);
2188
2189 return eStatus;
2190 }
2191
MOS_OS_Utilities_Init(PMOS_USER_FEATURE_KEY_PATH_INFO userFeatureKeyPathInfo)2192 MOS_STATUS MOS_OS_Utilities_Init(PMOS_USER_FEATURE_KEY_PATH_INFO userFeatureKeyPathInfo)
2193 {
2194 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2195 MOS_UNUSED(userFeatureKeyPathInfo);
2196
2197 // lock mutex to avoid multi init in multi-threading env
2198 MOS_LockMutex(&gMosUtilMutex);
2199
2200 #if (_DEBUG || _RELEASE_INTERNAL)
2201 // Get use user feature file from env, instead of default.
2202 FILE* fp = nullptr;
2203 static char* tmpFile = getenv("GFX_FEATURE_FILE");
2204
2205 if (tmpFile != nullptr)
2206 {
2207 if ((fp = fopen(tmpFile, "r")) != nullptr)
2208 {
2209 szUserFeatureFile = tmpFile;
2210 fclose(fp);
2211 MOS_OS_NORMALMESSAGE("using %s for USER_FEATURE_FILE", szUserFeatureFile);
2212 }
2213 else
2214 {
2215 MOS_OS_ASSERTMESSAGE("Can't open %s for USER_FEATURE_FILE!!!", tmpFile);
2216 eStatus = MOS_STATUS_FILE_NOT_FOUND;
2217 goto finish;
2218 }
2219 }
2220 #endif
2221
2222 if (uiMOSUtilInitCount == 0)
2223 {
2224 pUFKeyOps = (PUFKEYOPS)MOS_AllocAndZeroMemory(sizeof(UFKEYOPS));
2225 MOS_OS_CHK_NULL(pUFKeyOps);
2226 #ifdef ANDROID
2227 if (MOS_InitAndroidPropInfo() == MOS_STATUS_SUCCESS)
2228 {
2229 pUFKeyOps->pfnUserFeatureOpenKey = MOS_UserFeatureOpenKey_AndroidProp;
2230 pUFKeyOps->pfnUserFeatureGetValue = MOS_UserFeatureGetValue_AndroidProp;
2231 pUFKeyOps->pfnUserFeatureSetValueEx = MOS_UserFeatureSetValueEx_AndroidProp;
2232 }
2233 else
2234 #endif
2235 {
2236 pUFKeyOps->pfnUserFeatureOpenKey = MOS_UserFeatureOpenKey_File;
2237 pUFKeyOps->pfnUserFeatureGetValue = MOS_UserFeatureGetValue_File;
2238 pUFKeyOps->pfnUserFeatureSetValueEx = MOS_UserFeatureSetValueEx_File;
2239 }
2240 //Init MOS User Feature Key from mos desc table
2241 eStatus = MOS_DeclareUserFeatureKeysForAllDescFields();
2242
2243 #if _MEDIA_RESERVED
2244 codecUserFeatureExt = new CodechalUserSettingsMgr();
2245 vpUserFeatureExt = new VphalUserSettingsMgr();
2246 #endif // _MEDIA_RESERVED
2247 eStatus = MOS_GenerateUserFeatureKeyXML();
2248 #if MOS_MESSAGES_ENABLED
2249 // Initialize MOS message params structure and HLT
2250 MOS_MessageInit();
2251 #endif // MOS_MESSAGES_ENABLED
2252 MosMemAllocCounter = 0;
2253 MosMemAllocFakeCounter = 0;
2254 MosMemAllocCounterGfx = 0;
2255 MOS_TraceEventInit();
2256 }
2257 uiMOSUtilInitCount++;
2258
2259 finish:
2260 MOS_UnlockMutex(&gMosUtilMutex);
2261 return eStatus;
2262 }
2263
MOS_OS_Utilities_Close()2264 MOS_STATUS MOS_OS_Utilities_Close()
2265 {
2266 int32_t MemoryCounter = 0;
2267 MOS_USER_FEATURE_VALUE_WRITE_DATA UserFeatureWriteData = __NULL_USER_FEATURE_VALUE_WRITE_DATA__;
2268 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2269
2270 // lock mutex to avoid multi close in multi-threading env
2271 MOS_LockMutex(&gMosUtilMutex);
2272 uiMOSUtilInitCount--;
2273 if (uiMOSUtilInitCount == 0 )
2274 {
2275 MOS_TraceEventClose();
2276 MosMemAllocCounter -= MosMemAllocFakeCounter;
2277 MemoryCounter = MosMemAllocCounter + MosMemAllocCounterGfx;
2278 MosMemAllocCounterNoUserFeature = MosMemAllocCounter;
2279 MosMemAllocCounterNoUserFeatureGfx = MosMemAllocCounterGfx;
2280 MOS_OS_VERBOSEMESSAGE("MemNinja leak detection end");
2281
2282 UserFeatureWriteData.Value.i32Data = MemoryCounter;
2283 UserFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_MEMNINJA_COUNTER_ID;
2284 MOS_UserFeature_WriteValues_ID(NULL, &UserFeatureWriteData, 1);
2285
2286 eStatus = MOS_DestroyUserFeatureKeysForAllDescFields();
2287 #if _MEDIA_RESERVED
2288 if (codecUserFeatureExt)
2289 {
2290 delete codecUserFeatureExt;
2291 codecUserFeatureExt = nullptr;
2292 }
2293 if (vpUserFeatureExt)
2294 {
2295 delete vpUserFeatureExt;
2296 vpUserFeatureExt = nullptr;
2297 }
2298 #endif // _MEDIA_RESERVED
2299 #if (_DEBUG || _RELEASE_INTERNAL)
2300 // MOS maintains a reference counter,
2301 // so if there still is another active lib instance, logs would still be printed.
2302 MOS_MessageClose();
2303 #endif
2304 MOS_FreeMemory(pUFKeyOps);
2305 pUFKeyOps = nullptr;
2306 }
2307 MOS_UnlockMutex(&gMosUtilMutex);
2308 return eStatus;
2309 }
2310
MOS_UserFeatureOpenKey(void * UFKey,const char * lpSubKey,uint32_t ulOptions,uint32_t samDesired,void ** phkResult)2311 MOS_STATUS MOS_UserFeatureOpenKey(
2312 void *UFKey,
2313 const char *lpSubKey,
2314 uint32_t ulOptions,
2315 uint32_t samDesired,
2316 void **phkResult)
2317 {
2318 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2319 MOS_STATUS iRet;
2320 intptr_t h_key = (intptr_t)UFKey;
2321
2322 if((h_key == 0) /*|| (lpSubKey == nullptr)*/ || (phkResult == nullptr)) //[SH]: subkey can be NULL???
2323 {
2324 return MOS_STATUS_INVALID_PARAMETER;
2325 }
2326 if (( pUFKeyOps != nullptr) && (pUFKeyOps->pfnUserFeatureOpenKey != nullptr))
2327 {
2328 return pUFKeyOps->pfnUserFeatureOpenKey(UFKey, lpSubKey, ulOptions, samDesired, phkResult);
2329 }
2330 else
2331 {
2332 return MOS_UserFeatureOpenKey_File(UFKey, lpSubKey, ulOptions, samDesired, phkResult);
2333 }
2334 }
2335
MOS_UserFeatureCloseKey(void * UFKey)2336 MOS_STATUS MOS_UserFeatureCloseKey(void *UFKey)
2337 {
2338 MOS_UNUSED(UFKey);
2339 //always return success, because we actually dong't have a key opened.
2340 return MOS_STATUS_SUCCESS;
2341 }
2342
MOS_UserFeatureGetValue(void * UFKey,const char * lpSubKey,const char * lpValue,uint32_t dwFlags,uint32_t * pdwType,void * pvData,uint32_t * pcbData)2343 MOS_STATUS MOS_UserFeatureGetValue(
2344 void *UFKey,
2345 const char *lpSubKey,
2346 const char *lpValue,
2347 uint32_t dwFlags,
2348 uint32_t *pdwType,
2349 void *pvData,
2350 uint32_t *pcbData)
2351 {
2352 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2353 MOS_STATUS eStatus;
2354
2355 if(UFKey == nullptr)
2356 {
2357 return MOS_STATUS_INVALID_PARAMETER;
2358 }
2359
2360 eStatus = MOS_STATUS_UNKNOWN;
2361 if (( pUFKeyOps != nullptr) && (pUFKeyOps->pfnUserFeatureGetValue != nullptr))
2362 {
2363 return pUFKeyOps->pfnUserFeatureGetValue(UFKey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData);
2364 }
2365 else
2366 {
2367 return MOS_UserFeatureGetValue_File(UFKey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData);
2368 }
2369
2370 }
2371
MOS_UserFeatureQueryValueEx(void * UFKey,char * lpValueName,uint32_t * lpReserved,uint32_t * lpType,char * lpData,uint32_t * lpcbData)2372 MOS_STATUS MOS_UserFeatureQueryValueEx(
2373 void *UFKey,
2374 char *lpValueName,
2375 uint32_t *lpReserved,
2376 uint32_t *lpType,
2377 char *lpData,
2378 uint32_t *lpcbData)
2379 {
2380 MOS_UNUSED(lpReserved);
2381 return MOS_UserFeatureGetValue(UFKey, "", lpValueName, 0, lpType, lpData, lpcbData);
2382 }
2383
MOS_UserFeatureSetValueEx(void * UFKey,const char * lpValueName,uint32_t Reserved,uint32_t dwType,uint8_t * lpData,uint32_t cbData)2384 MOS_STATUS MOS_UserFeatureSetValueEx(
2385 void *UFKey,
2386 const char *lpValueName,
2387 uint32_t Reserved,
2388 uint32_t dwType,
2389 uint8_t *lpData,
2390 uint32_t cbData)
2391 {
2392 char pcKeyName[MAX_USERFEATURE_LINE_LENGTH];
2393 MOS_STATUS eStatus;
2394
2395 if (UFKey == nullptr)
2396 {
2397 return MOS_STATUS_INVALID_PARAMETER;
2398 }
2399 if (( pUFKeyOps != nullptr) && (pUFKeyOps->pfnUserFeatureSetValueEx!= nullptr))
2400 {
2401 return pUFKeyOps->pfnUserFeatureSetValueEx(UFKey, lpValueName, Reserved, dwType, lpData, cbData);
2402 }
2403 else
2404 {
2405 return MOS_UserFeatureSetValueEx_File(UFKey, lpValueName, Reserved, dwType, lpData, cbData);
2406 }
2407 }
2408
2409 // Event Related Functions: Android does not support these
2410 #ifndef ANDROID
MOS_UserFeatureNotifyChangeKeyValue(void * UFKey,int32_t bWatchSubtree,HANDLE hEvent,int32_t fAsynchronous)2411 MOS_STATUS MOS_UserFeatureNotifyChangeKeyValue(
2412 void *UFKey,
2413 int32_t bWatchSubtree,
2414 HANDLE hEvent,
2415 int32_t fAsynchronous)
2416 {
2417 key_t key;
2418 int32_t semid;
2419 struct sembuf operation[1] ;
2420
2421 key = ftok(szUserFeatureFile,1);
2422 semid = semget(key,1,0);
2423 //change semaphore
2424 operation[0].sem_op = 1;
2425 operation[0].sem_num = 0;
2426 operation[0].sem_flg = SEM_UNDO;
2427 semop(semid, operation, 1);
2428
2429 return MOS_STATUS_SUCCESS;
2430 }
2431
MOS_CreateEventEx(void * lpEventAttributes,char * lpName,uint32_t dwFlags)2432 HANDLE MOS_CreateEventEx(
2433 void *lpEventAttributes,
2434 char *lpName,
2435 uint32_t dwFlags)
2436 {
2437 int32_t semid;
2438 key_t key;
2439 union semun
2440 {
2441 int32_t val;
2442 struct semid_ds *Buf;
2443 unsigned short *array;
2444 } semctl_arg;
2445
2446 semid = 0;
2447
2448 //Generate a unique key, U can also supply a value instead
2449 key = ftok(szUserFeatureFile, 1);
2450 semid = semget(key, 1, 0666 | IPC_CREAT );
2451 semctl_arg.val = 0; //Setting semval to 0
2452 semctl(semid, 0, SETVAL, semctl_arg);
2453
2454 HANDLE ret = reinterpret_cast<HANDLE>(semid);
2455
2456 return ret;
2457 }
2458
MOS_UserFeatureWaitForSingleObject(PTP_WAIT * phNewWaitObject,HANDLE hObject,void * Callback,void * Context)2459 int32_t MOS_UserFeatureWaitForSingleObject(
2460 PTP_WAIT* phNewWaitObject,
2461 HANDLE hObject,
2462 void *Callback,
2463 void *Context)
2464 {
2465 int32_t iRet;
2466 int32_t semid;
2467 struct sembuf operation[1];
2468 pid_t pid;
2469 MOS_UserFeatureCallback pCallback;
2470 LARGE_INTEGER largeInteger;
2471
2472 pCallback = (MOS_UserFeatureCallback)Callback;
2473
2474 iRet = 0;
2475
2476 largeInteger.QuadPart = (int64_t)hObject;
2477
2478 semid = largeInteger.u.LowPart;
2479
2480 if ((pid=fork()) == -1)
2481 {
2482 printf("error\n");
2483 }
2484 else if(pid == 0)
2485 {
2486 while(1)
2487 {
2488 operation[0].sem_op = -1;
2489 operation[0].sem_num = 0;
2490 //now waiting
2491 semop(semid, operation, 1);
2492 pCallback(Context, 0);
2493 }
2494 exit(0);
2495 }
2496 else
2497 {
2498 iRet = pid;
2499 }
2500
2501 *phNewWaitObject = reinterpret_cast<PTP_WAIT>(iRet);
2502
2503 return (iRet != 0);
2504 }
2505
MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle)2506 int32_t MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle)
2507 {
2508 int32_t iPid;
2509 LARGE_INTEGER largeInteger;
2510
2511 largeInteger.QuadPart = (int64_t)hWaitHandle;
2512
2513 iPid = largeInteger.u.LowPart;
2514 kill(iPid,SIGKILL);
2515 return true;
2516 }
2517
2518 /*----------------------------------------------------------------------------
2519 | Name : GMMDebugBreak
2520 | Purpose : Fix compiling issue for Gmmlib on debug mode
2521 | Arguments : N/A
2522 | Returns : void
2523 | Calls : N/A
2524 | Callers : Several
2525 \---------------------------------------------------------------------------*/
GMMDebugBreak(const char * file,const char * function,const int32_t line)2526 void GMMDebugBreak(const char *file, const char *function,const int32_t line)
2527 {
2528 // Not required for media driver
2529 return;
2530 }
2531
2532 /*----------------------------------------------------------------------------
2533 | Name : GMMPrintMessage
2534 | Purpose : Fix compiling issue for Gmmlib on debug mode
2535 | Arguments : N/A
2536 | Returns : void
2537 | Calls : N/A
2538 | Callers : Several
2539 \---------------------------------------------------------------------------*/
GMMPrintMessage(int32_t debuglevel,const char * function,...)2540 void GMMPrintMessage(int32_t debuglevel, const char *function, ...)
2541 {
2542 // Not Required for media driver
2543 return;
2544 }
2545
2546 #else // ANDROID
MOS_UserFeatureNotifyChangeKeyValue(void * UFKey,int32_t bWatchSubtree,HANDLE hEvent,int32_t fAsynchronous)2547 MOS_STATUS MOS_UserFeatureNotifyChangeKeyValue(
2548 void *UFKey,
2549 int32_t bWatchSubtree,
2550 HANDLE hEvent,
2551 int32_t fAsynchronous)
2552 {
2553 MOS_UNUSED(UFKey);
2554 MOS_UNUSED(bWatchSubtree);
2555 MOS_UNUSED(hEvent);
2556 MOS_UNUSED(fAsynchronous);
2557 return MOS_STATUS_SUCCESS;
2558 }
2559
MOS_CreateEventEx(void * lpEventAttributes,char * lpName,uint32_t dwFlags)2560 HANDLE MOS_CreateEventEx(
2561 void *lpEventAttributes,
2562 char *lpName,
2563 uint32_t dwFlags)
2564 {
2565 MOS_UNUSED(lpEventAttributes);
2566 MOS_UNUSED(lpName);
2567 MOS_UNUSED(dwFlags);
2568 return (HANDLE)1;
2569 }
2570
MOS_UserFeatureWaitForSingleObject(PTP_WAIT * phNewWaitObject,HANDLE hObject,void * Callback,void * Context)2571 int32_t MOS_UserFeatureWaitForSingleObject(
2572 PTP_WAIT* phNewWaitObject,
2573 HANDLE hObject,
2574 void *Callback,
2575 void *Context)
2576 {
2577 MOS_UNUSED(phNewWaitObject);
2578 MOS_UNUSED(hObject);
2579 MOS_UNUSED(Callback);
2580 MOS_UNUSED(Context);
2581 return true;
2582 }
2583
MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle)2584 int32_t MOS_UnregisterWaitEx(PTP_WAIT hWaitHandle)
2585 {
2586 MOS_UNUSED(hWaitHandle);
2587 return true;
2588 }
2589 #endif // !ANDROID
2590
MOS_UserFeature_ParsePath(PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,char * const pInputPath,PMOS_USER_FEATURE_TYPE pUserFeatureType,char ** ppSubPath)2591 MOS_STATUS MOS_UserFeature_ParsePath(
2592 PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,
2593 char * const pInputPath,
2594 PMOS_USER_FEATURE_TYPE pUserFeatureType,
2595 char **ppSubPath)
2596 {
2597 char *pValue;
2598 MOS_USER_FEATURE_TYPE UserFeatureType;
2599 size_t uUFKeyLen;
2600 size_t uHKeyLen;
2601 size_t uValLen;
2602 size_t uSepLen;
2603 MOS_UNUSED(pOsUserFeatureInterface);
2604
2605 //-------------------------------------------
2606 // the UserFeature interface is not currently an actual interface, just a collection
2607 // of functions, so pOsUserFeatureInterface will always be nullptr until this changes
2608 //MOS_OS_ASSERT(pOsUserFeatureInterface);
2609 MOS_OS_ASSERT(pInputPath);
2610 MOS_OS_ASSERT(strlen(pInputPath) > 0);
2611 MOS_OS_ASSERT(pUserFeatureType);
2612 MOS_OS_ASSERT(ppSubPath);
2613 //-------------------------------------------
2614
2615 pValue = nullptr;
2616
2617 pValue = strstr(pInputPath, MOS_UF_SEPARATOR);
2618
2619 if (!pValue)
2620 {
2621 MOS_OS_ASSERTMESSAGE("Invalid user feature key %s.", pInputPath);
2622 return MOS_STATUS_INVALID_PARAMETER;
2623 }
2624
2625 uUFKeyLen = strlen(pInputPath);
2626 uValLen = strlen(pValue);
2627 uSepLen = strlen(MOS_UF_SEPARATOR);
2628 uHKeyLen = uUFKeyLen - uValLen;
2629
2630 if (uHKeyLen == 0)
2631 {
2632 MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. Path separator in the begining.", pInputPath);
2633 return MOS_STATUS_INVALID_PARAMETER;
2634 }
2635
2636 if (uValLen <= uSepLen)
2637 {
2638 MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. No value after path separator.", pInputPath);
2639 return MOS_STATUS_INVALID_PARAMETER;
2640 }
2641
2642 if ((uHKeyLen == strlen(MOS_UFKEY_EXT)) &&
2643 (strncmp(pInputPath, MOS_UFKEY_EXT, uHKeyLen) == 0))
2644 {
2645 UserFeatureType = MOS_USER_FEATURE_TYPE_SYSTEM;
2646 }
2647 else if ((uHKeyLen == strlen(MOS_UFKEY_INT)) &&
2648 (strncmp(pInputPath, MOS_UFKEY_INT, uHKeyLen) == 0))
2649 {
2650 UserFeatureType = MOS_USER_FEATURE_TYPE_USER;
2651 }
2652 else
2653 {
2654 MOS_OS_ASSERTMESSAGE("Invalid user feature key %s. Expected %s or %s.", pInputPath, MOS_UFKEY_EXT, MOS_UFKEY_INT);
2655 return MOS_STATUS_INVALID_PARAMETER;
2656 }
2657
2658 pValue = pValue + uSepLen;
2659
2660 *pUserFeatureType = UserFeatureType;
2661 *ppSubPath = pValue;
2662
2663 return MOS_STATUS_SUCCESS;
2664 }
2665
MOS_GetLogicalCoreNumber()2666 uint32_t MOS_GetLogicalCoreNumber()
2667 {
2668 return sysconf(_SC_NPROCESSORS_CONF);
2669 }
2670
MOS_CreateThread(void * ThreadFunction,void * ThreadData)2671 MOS_THREADHANDLE MOS_CreateThread(
2672 void *ThreadFunction,
2673 void *ThreadData)
2674 {
2675 MOS_THREADHANDLE Thread;
2676
2677 if (0 != pthread_create(&Thread, nullptr, (void *(*)(void *))ThreadFunction, ThreadData))
2678 {
2679 Thread = 0;
2680 MOS_OS_ASSERTMESSAGE("Create thread failed.");
2681 }
2682
2683 return Thread;
2684 }
2685
MOS_GetThreadId(MOS_THREADHANDLE hThread)2686 uint32_t MOS_GetThreadId(
2687 MOS_THREADHANDLE hThread)
2688 {
2689 MOS_UNUSED(hThread);
2690 return 0;
2691 }
2692
MOS_GetCurrentThreadId()2693 uint32_t MOS_GetCurrentThreadId()
2694 {
2695 return (uint32_t)pthread_self();
2696 }
2697
MOS_WaitThread(MOS_THREADHANDLE hThread)2698 MOS_STATUS MOS_WaitThread(
2699 MOS_THREADHANDLE hThread)
2700 {
2701 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2702
2703 if (hThread == 0)
2704 {
2705 MOS_OS_ASSERTMESSAGE("MOS wait thread failed, invalid thread handle.");
2706 eStatus = MOS_STATUS_INVALID_PARAMETER;
2707 }
2708 else if (0 != pthread_join(hThread, nullptr))
2709 {
2710 MOS_OS_ASSERTMESSAGE("Failed to join thread.");
2711 eStatus = MOS_STATUS_UNKNOWN;
2712 }
2713
2714 return eStatus;
2715 }
2716
MOS_CreateMutex()2717 PMOS_MUTEX MOS_CreateMutex()
2718 {
2719 PMOS_MUTEX pMutex;
2720
2721 pMutex = (PMOS_MUTEX)MOS_AllocMemory(sizeof(*pMutex));
2722 if (pMutex != nullptr)
2723 {
2724 if (pthread_mutex_init(pMutex, nullptr))
2725 {
2726 MOS_FreeMemory(pMutex);
2727 pMutex = nullptr;
2728 }
2729 }
2730
2731 return pMutex;
2732 }
2733
MOS_DestroyMutex(PMOS_MUTEX pMutex)2734 MOS_STATUS MOS_DestroyMutex(PMOS_MUTEX pMutex)
2735 {
2736 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2737
2738 if (pMutex)
2739 {
2740 if (pthread_mutex_destroy(pMutex))
2741 {
2742 eStatus = MOS_STATUS_UNKNOWN;
2743 }
2744 MOS_FreeMemory(pMutex);
2745 }
2746
2747 return eStatus;
2748 }
2749
MOS_LockMutex(PMOS_MUTEX pMutex)2750 MOS_STATUS MOS_LockMutex(PMOS_MUTEX pMutex)
2751 {
2752 MOS_OS_CHK_NULL_RETURN(pMutex);
2753
2754 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2755
2756 if (pthread_mutex_lock(pMutex))
2757 {
2758 eStatus = MOS_STATUS_UNKNOWN;
2759 }
2760
2761 return eStatus;
2762 }
2763
MOS_UnlockMutex(PMOS_MUTEX pMutex)2764 MOS_STATUS MOS_UnlockMutex(PMOS_MUTEX pMutex)
2765 {
2766 MOS_OS_CHK_NULL_RETURN(pMutex);
2767
2768 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2769
2770 if (pthread_mutex_unlock(pMutex))
2771 {
2772 eStatus = MOS_STATUS_UNKNOWN;
2773 }
2774
2775 return eStatus;
2776 }
2777
MOS_CreateSemaphore(uint32_t uiInitialCount,uint32_t uiMaximumCount)2778 PMOS_SEMAPHORE MOS_CreateSemaphore(
2779 uint32_t uiInitialCount,
2780 uint32_t uiMaximumCount)
2781 {
2782 PMOS_SEMAPHORE pSemaphore = nullptr;
2783 MOS_UNUSED(uiMaximumCount);
2784
2785 pSemaphore = (PMOS_SEMAPHORE)MOS_AllocMemory(sizeof(*pSemaphore));
2786 if (!pSemaphore)
2787 return nullptr;
2788 if (sem_init(pSemaphore, 0, uiInitialCount))
2789 {
2790 MOS_SafeFreeMemory(pSemaphore);
2791 pSemaphore = nullptr;
2792 }
2793
2794 return pSemaphore;
2795 }
2796
MOS_DestroySemaphore(PMOS_SEMAPHORE pSemaphore)2797 MOS_STATUS MOS_DestroySemaphore(
2798 PMOS_SEMAPHORE pSemaphore)
2799 {
2800 MOS_SafeFreeMemory(pSemaphore);
2801
2802 return MOS_STATUS_SUCCESS;
2803 }
2804
MOS_WaitSemaphore(PMOS_SEMAPHORE pSemaphore,uint32_t uiMilliseconds)2805 MOS_STATUS MOS_WaitSemaphore(
2806 PMOS_SEMAPHORE pSemaphore,
2807 uint32_t uiMilliseconds)
2808 {
2809 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2810
2811 if (uiMilliseconds == INFINITE)
2812 {
2813 if (sem_wait(pSemaphore))
2814 {
2815 eStatus = MOS_STATUS_UNKNOWN;
2816 }
2817 }
2818 else
2819 {
2820 struct timespec time = {
2821 (int32_t)uiMilliseconds / 1000000,
2822 ((int32_t)uiMilliseconds % 1000000) * 1000};
2823
2824 if (sem_timedwait(pSemaphore, &time))
2825 {
2826 eStatus = MOS_STATUS_UNKNOWN;
2827 }
2828 }
2829
2830 return eStatus;
2831 }
2832
MOS_PostSemaphore(PMOS_SEMAPHORE pSemaphore,uint32_t uiPostCount)2833 MOS_STATUS MOS_PostSemaphore(
2834 PMOS_SEMAPHORE pSemaphore,
2835 uint32_t uiPostCount)
2836 {
2837 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2838
2839 if (uiPostCount > 0)
2840 {
2841 while (uiPostCount--)
2842 {
2843 if (sem_post(pSemaphore))
2844 {
2845 eStatus = MOS_STATUS_UNKNOWN;
2846 break;
2847 }
2848 }
2849 }
2850 else
2851 {
2852 eStatus = MOS_STATUS_UNKNOWN;
2853 }
2854
2855 return eStatus;
2856 }
2857
MOS_WaitForSingleObject(void * pObject,uint32_t uiMilliseconds)2858 uint32_t MOS_WaitForSingleObject(
2859 void *pObject,
2860 uint32_t uiMilliseconds)
2861 {
2862 uint32_t WaitSignal = 0;
2863 MOS_UNUSED(pObject);
2864 MOS_UNUSED(uiMilliseconds);
2865
2866 return WaitSignal;
2867 }
2868
MOS_WaitForMultipleObjects(uint32_t uiThreadCount,void ** ppObjects,uint32_t bWaitAll,uint32_t uiMilliseconds)2869 uint32_t MOS_WaitForMultipleObjects(
2870 uint32_t uiThreadCount,
2871 void **ppObjects,
2872 uint32_t bWaitAll,
2873 uint32_t uiMilliseconds)
2874 {
2875 MOS_UNUSED(uiThreadCount);
2876 MOS_UNUSED(ppObjects);
2877 MOS_UNUSED(bWaitAll);
2878 MOS_UNUSED(uiMilliseconds);
2879 return 0;
2880 }
2881
MOS_AtomicIncrement(int32_t * pValue)2882 int32_t MOS_AtomicIncrement(
2883 int32_t *pValue)
2884 {
2885 return __sync_fetch_and_add(pValue, 1);
2886 }
2887
MOS_AtomicDecrement(int32_t * pValue)2888 int32_t MOS_AtomicDecrement(
2889 int32_t *pValue)
2890 {
2891 return __sync_fetch_and_sub(pValue, 1);
2892 }
2893
MOS_StatusToOsResult(MOS_STATUS eStatus)2894 VAStatus MOS_StatusToOsResult(
2895 MOS_STATUS eStatus)
2896 {
2897 switch (eStatus)
2898 {
2899 case MOS_STATUS_SUCCESS: return VA_STATUS_SUCCESS;
2900 case MOS_STATUS_NO_SPACE: return VA_STATUS_ERROR_ALLOCATION_FAILED;
2901 case MOS_STATUS_INVALID_PARAMETER: return VA_STATUS_ERROR_INVALID_PARAMETER;
2902 case MOS_STATUS_INVALID_HANDLE: return VA_STATUS_ERROR_INVALID_BUFFER;
2903 case MOS_STATUS_NULL_POINTER: return VA_STATUS_ERROR_INVALID_CONTEXT;
2904 default: return VA_STATUS_ERROR_OPERATION_FAILED;
2905 }
2906
2907 return VA_STATUS_ERROR_OPERATION_FAILED;
2908 }
2909
OsResultToMOS_Status(VAStatus eResult)2910 MOS_STATUS OsResultToMOS_Status(
2911 VAStatus eResult)
2912 {
2913 switch (eResult)
2914 {
2915 case VA_STATUS_SUCCESS: return MOS_STATUS_SUCCESS;
2916 case VA_STATUS_ERROR_ALLOCATION_FAILED: return MOS_STATUS_NO_SPACE;
2917 case VA_STATUS_ERROR_INVALID_PARAMETER: return MOS_STATUS_INVALID_PARAMETER;
2918 case VA_STATUS_ERROR_INVALID_BUFFER: return MOS_STATUS_INVALID_HANDLE;
2919 case VA_STATUS_ERROR_INVALID_CONTEXT: return MOS_STATUS_NULL_POINTER;
2920 default: return MOS_STATUS_UNKNOWN;
2921 }
2922
2923 return MOS_STATUS_UNKNOWN;
2924 }
2925
MOS_GetLocalTime(struct tm * Tm)2926 MOS_STATUS MOS_GetLocalTime(
2927 struct tm* Tm)
2928 {
2929 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2930 struct tm *pTm;
2931 time_t lTime = time(nullptr);
2932 pTm = localtime(&lTime);
2933 if(pTm == nullptr)
2934 {
2935 MOS_OS_ASSERTMESSAGE("Failed to get localtime.");
2936 eStatus = MOS_STATUS_UNKNOWN;
2937 return eStatus;
2938 }
2939
2940 eStatus = MOS_SecureMemcpy(Tm, sizeof(struct tm), pTm, sizeof(struct tm));
2941 return eStatus;
2942 }
2943
MOS_TraceEventInit()2944 void MOS_TraceEventInit()
2945 {
2946 if (g_apoMosEnabled)
2947 {
2948 return MosUtilities::MosTraceEventInit();
2949 }
2950 // close first, if already opened.
2951 if (MosTraceFd >= 0)
2952 {
2953 close(MosTraceFd);
2954 MosTraceFd = -1;
2955 }
2956 MosTraceFd = open(MosTracePath, O_WRONLY);
2957 return;
2958 }
2959
MOS_TraceEventClose()2960 void MOS_TraceEventClose()
2961 {
2962 if (g_apoMosEnabled)
2963 {
2964 return MosUtilities::MosTraceEventClose();
2965 }
2966 if (MosTraceFd >= 0)
2967 {
2968 close(MosTraceFd);
2969 MosTraceFd = -1;
2970 }
2971 return;
2972 }
2973
MOS_TraceSetupInfo(uint32_t DrvVer,uint32_t PlatFamily,uint32_t RenderFamily,uint32_t DeviceID)2974 void MOS_TraceSetupInfo(uint32_t DrvVer, uint32_t PlatFamily, uint32_t RenderFamily, uint32_t DeviceID)
2975 {
2976 // not implemented
2977 }
2978
2979 #define TRACE_EVENT_MAX_SIZE 4096
MOS_TraceEvent(uint16_t usId,uint8_t ucType,void * const pArg1,uint32_t dwSize1,void * const pArg2,uint32_t dwSize2)2980 void MOS_TraceEvent(
2981 uint16_t usId,
2982 uint8_t ucType,
2983 void * const pArg1,
2984 uint32_t dwSize1,
2985 void * const pArg2,
2986 uint32_t dwSize2)
2987 {
2988 if (g_apoMosEnabled)
2989 {
2990 return MosUtilities::MosTraceEvent(usId, ucType, pArg1, dwSize1, pArg2, dwSize2);
2991 }
2992
2993 if (MosTraceFd >= 0)
2994 {
2995 char *pTraceBuf = (char *)MOS_AllocAndZeroMemory(TRACE_EVENT_MAX_SIZE);
2996 uint32_t nLen = 0;
2997
2998 if (pTraceBuf)
2999 {
3000 MOS_SecureStringPrint(pTraceBuf,
3001 TRACE_EVENT_MAX_SIZE,
3002 (TRACE_EVENT_MAX_SIZE-1),
3003 "IMTE|%d|%d", // magic number IMTE (IntelMediaTraceEvent)
3004 usId,
3005 ucType);
3006 nLen = strlen(pTraceBuf);
3007 if (pArg1)
3008 {
3009 // convert raw event data to string. native raw data will be supported
3010 // from linux kernel 4.10, hopefully we can skip this convert in the future.
3011 const static char n2c[] = "0123456789ABCDEF";
3012 unsigned char *pData = (unsigned char *)pArg1;
3013
3014 pTraceBuf[nLen++] = '|'; // prefix splite marker.
3015 while(dwSize1-- > 0 && nLen < TRACE_EVENT_MAX_SIZE-2)
3016 {
3017 pTraceBuf[nLen++] = n2c[(*pData) >> 4];
3018 pTraceBuf[nLen++] = n2c[(*pData++) & 0xf];
3019 }
3020 if (pArg2)
3021 {
3022 pData = (unsigned char *)pArg2;
3023 while(dwSize2-- > 0 && nLen < TRACE_EVENT_MAX_SIZE-2)
3024 {
3025 pTraceBuf[nLen++] = n2c[(*pData) >> 4];
3026 pTraceBuf[nLen++] = n2c[(*pData++) & 0xf];
3027 }
3028 }
3029 }
3030 size_t writeSize = write(MosTraceFd, pTraceBuf, nLen);
3031 MOS_FreeMemory(pTraceBuf);
3032 }
3033 }
3034 return;
3035 }
3036
MOS_TraceDataDump(const char * pcName,uint32_t flags,const void * pBuf,uint32_t dwSize)3037 void MOS_TraceDataDump(
3038 const char * pcName,
3039 uint32_t flags,
3040 const void * pBuf,
3041 uint32_t dwSize)
3042 {
3043 // not implemented
3044 }
3045
MOS_GfxInfoInit()3046 MOS_STATUS MOS_GfxInfoInit()
3047 {
3048 // not implemented
3049 return MOS_STATUS_SUCCESS;
3050 }
3051
MOS_GfxInfoClose()3052 void MOS_GfxInfoClose()
3053 {
3054 // not implemented
3055 }
3056
MOS_GfxInfo_RTErr(uint8_t ver,uint16_t compId,uint16_t FtrId,uint32_t ErrorCode,uint8_t num_of_triples,...)3057 void MOS_GfxInfo_RTErr(uint8_t ver,
3058 uint16_t compId,
3059 uint16_t FtrId,
3060 uint32_t ErrorCode,
3061 uint8_t num_of_triples,
3062 ...)
3063 {
3064 // not implemented
3065 }
3066
MOS_GfxInfo(uint8_t ver,uint16_t compId,uint32_t tmtryID,uint8_t num_of_triples,...)3067 void MOS_GfxInfo(
3068 uint8_t ver,
3069 uint16_t compId,
3070 uint32_t tmtryID,
3071 uint8_t num_of_triples,
3072 ...)
3073 {
3074 // not implemented
3075 }
3076