xref: /utopia/UTPA2-700.0.x/modules/msos/utopia_core/optee/utopia_dapi.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 #include "MsTypes.h"
2 #include "utopia_private.h"
3 #include <stdlib.h>
4 #include "MsOS.h"
5 #include <stdio.h>
6 #include "utopia.h"
7 #include <string.h>
8 #include "utopia_dapi.h"
9 #include "ULog.h"
10 
11 // length should be the same to definition
12 extern char moduleNames[][40];
13 extern char rpoolNames[][40];
14 extern char ResourceNames[][40];
15 
16 UTOPIA_SHM_ID* utopiaShmIdArray[50]; // FIXME: enum
17 MS_U32 utopiaShmIdIndex = 0;
18 
19 UTOPIA_MODULE_STR_LIST* UTOPIA_MODULE_STR_LIST_HEAD = NULL;
20 UTOPIA_MODULE_STR_LIST* UTOPIA_MODULE_STR_LIST_CURRENT = NULL;
21 UTOPIA_MODULE_STR_LIST* UTOPIA_MODULE_STR_LIST_PREV = NULL;
22 
23 // should directly refer to SHM_ARRAY_LENGTH in nuttx/MsOS_nuttx.c
24 // FIXME: for now, we do it with hardcode
25 #define SHM_ARRAY_LENGTH 200
26 
27 void* shmid2va_table[SHM_ARRAY_LENGTH] = {NULL};
28 
29 extern UTOPIA_PRIVATE* psUtopiaPrivate;
30 
31 //struct sembuf op_down[1] = {{0, -1, 0}}; // "0" means 0th semaphore in sem. set
32                                         // second "0" is flag, but I don't what it means
33 //struct sembuf op_up[1] = {{0, 1, 0}}; // "0" means 0th semaphore in sem. set
34                                         // second "0" is flag, but I don't what it means
35 //############################
36 //## Static Functions Start ##
37 //############################
obtain_sem(MS_U32 u32SemID)38 static void obtain_sem(MS_U32 u32SemID)
39 {
40     /* Perform down operation */
41     //semop(u32SemID, &op_down[0], 1);
42 	MsOS_ObtainSemaphore(u32SemID, MSOS_WAIT_FOREVER);
43 }
44 
release_sem(MS_U32 u32SemID)45 static void release_sem(MS_U32 u32SemID)
46 {
47     /* Perform down operation */
48     //semop(u32SemID, &op_up[0], 1);
49 	MsOS_ReleaseSemaphore(u32SemID);
50 }
51 
52 
shmid2va(MS_U32 u32ShmID)53 static inline void* shmid2va(MS_U32 u32ShmID)
54 {
55 	if (u32ShmID == 0xFFFFFFFF)
56 		return NULL;
57 	return shmid2va_table[u32ShmID];
58 }
59 
60 // u32ShmID: shmid2va table index
61 // u32ShmAddr: shmid2va table value
fill_shmid2va_table(MS_U32 u32ShmID,void * u32ShmAddr)62 static MS_U32 fill_shmid2va_table(MS_U32 u32ShmID, void* u32ShmAddr)
63 {
64 	if (shmid2va_table[u32ShmID] != NULL)
65 	{
66 		printf("error: register duplicated shared memory ID %d\n", (int)u32ShmID);
67 		//while(1);
68 		return -1;
69 	}
70 	else
71 	{
72 		shmid2va_table[u32ShmID] = u32ShmAddr;
73 		return 0;
74 	}
75 }
76 
77 // u32ShmSize: user specified shared memory size
78 // shmName: user specified shared memory name
79 // p32RetShmID: for returning shared memory id
80 // return: shared memory address in virtual
shm_malloc(MS_U32 u32ShmSize,char * shmName,MS_U32 * pu32RetShmID)81 static void* shm_malloc(MS_U32 u32ShmSize, char* shmName, MS_U32* pu32RetShmID)
82 {
83 	MS_U32 u32RetShmID, u32RetAddr, u32RetShmSize;
84 	MS_U32 u32Ret;
85 
86 	// u32Ret: TRUE for success, FALSE for failure
87 	u32Ret = MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_QUERY);
88 
89 	// MsOS_SHM_GetId need to be called for each process to set up per-process shmid2va table
90 	// it's ok for duplicated calls with same shmName
91 	MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_CREATE);
92 	fill_shmid2va_table(u32RetShmID, (void*)u32RetAddr);
93 
94 	// u32Ret: TRUE for success, FALSE for failure
95 	// if failure --> first time allocation, memset to 0
96 	if (u32Ret != 1)
97 		memset((void*)u32RetAddr, 0, u32RetShmSize);
98 
99 	*pu32RetShmID = u32RetShmID;
100 	return (void*)u32RetAddr;
101 }
102 
103 enum eObjectType
104 {
105 	E_TYPE_INSTANCE,
106 	E_TYPE_MODULE,
107 	E_TYPE_MODULE_SHM,
108 	E_TYPE_RESOURCE_POOL,
109 	E_TYPE_RESOURCE,
110 };
111 
next_resource(void * pUnkown,enum eObjectType eObjectType)112 static UTOPIA_RESOURCE* next_resource(void* pUnkown, enum eObjectType eObjectType)
113 {
114 	switch(eObjectType)
115 	{
116 		case E_TYPE_RESOURCE_POOL:
117 			return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE_POOL*)pUnkown)->shmid_resource_head.ID);
118 		case E_TYPE_RESOURCE:
119 			return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE*)pUnkown)->shmid_next_resource.ID);
120 		default:
121 			printf("[utopia error] type is not supported\n");
122 			while(1);
123 	}
124 }
125 
126 /*static MS_U32 isResourceInPool(UTOPIA_RESOURCE_POOL* psResourcePool, UTOPIA_RESOURCE* pResource)
127 {
128 	MS_U32 i;
129 	UTOPIA_RESOURCE* pResourceFound = NULL;
130 
131 	pResourceFound = nextResource(psResourcePool, E_TYPE_RESOURCE_POOL);
132 	for (i = 0; i < psResourcePool->u32ResourceTotal; i++)
133 	{
134 		if (pResource == pResourceFound)
135 			return 1;
136 		pResourceFound = nextResource(pResourceFound, E_TYPE_RESOURCE);
137 	}
138 	return 0;
139 }*/
140 
141 /*static UTOPIA_RESOURCE_POOL* nextResourcePool(void* pUnkown, enum eUtopiaType eUtopiaType)
142 {
143 	switch(eUtopiaType)
144 	{
145 		case E_TYPE_INSTANT:
146 			return (UTOPIA_RESOURCE_POOL*)shmid2va(((UTOPIA_INSTANCE*)pUnkown)->psModuleNode->psModuleNodeShm->shmid_UTOPIA_RESOURCE_POOL__Head.ID);
147 		case E_TYPE_MODULE_SHM:
148 			return (UTOPIA_RESOURCE_POOL*)shmid2va(((UTOPIA_MODULE_NODE_SHM*)pUnkown)->shmid_UTOPIA_RESOURCE_POOL__Head.ID);
149 		case E_TYPE_RESOURCE_POOL:
150 			return (UTOPIA_RESOURCE_POOL*)shmid2va(((UTOPIA_RESOURCE_POOL*)pUnkown)->shmid_UTOPIA_RESOURCE_POOL__Next.ID);
151 		default:
152 			printf("\n%s, %d, %s, what the fuck!\n", __FUNCTION__, __LINE__, __FILE__);
153 			while(1);
154 	}
155 }*/
156 
157 /*static UTOPIA_RESOURCE_POOL* locate_pool_by_instant_resource(UTOPIA_INSTANCE* psInstant, UTOPIA_RESOURCE* pResource)
158 {
159 	//MS_U32 u32ShmID = psInstant->psModuleNode->psModuleNodeShm->shmid_UTOPIA_RESOURCE_POOL__Head.ID;
160 	//UTOPIA_RESOURCE_POOL* psResourcePool = (UTOPIA_RESOURCE_POOL*)shmid2va(u32ShmID);
161 	UTOPIA_RESOURCE_POOL* psResourcePool = nextResourcePool(psInstant, E_TYPE_INSTANT);
162 	while (psResourcePool != NULL && !isResourceInPool(psResourcePool, pResource))
163 	{
164 		psResourcePool = nextResourcePool(psResourcePool, E_TYPE_RESOURCE_POOL);
165 	}
166 
167 	return psResourcePool;
168 }*/
169 
170 // return located module address or NULL if not found
locate_module(MS_U32 u32ModuleID)171 void* locate_module(MS_U32 u32ModuleID)
172 {
173 	UTOPIA_MODULE* pLocatedModule = psUtopiaPrivate->psModuleHead;
174 
175 	while (pLocatedModule != NULL && pLocatedModule->u32ModuleID != u32ModuleID)
176 		pLocatedModule = pLocatedModule->psNext;
177 
178 	return pLocatedModule;
179 }
180 
181 // case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
182 // case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
183 // case 3: at least one resource pool exists, and so is the located one --> *ppRPool != NULL & ppRPoolPrev doesn't matter
locate_resource_pool(UTOPIA_MODULE * pModule,MS_U32 u32LocatedRPoolID,UTOPIA_RESOURCE_POOL ** ppRPool,UTOPIA_RESOURCE_POOL ** ppRPoolPrev)184 static int locate_resource_pool(UTOPIA_MODULE* pModule, MS_U32 u32LocatedRPoolID
185 		, UTOPIA_RESOURCE_POOL** ppRPool, UTOPIA_RESOURCE_POOL** ppRPoolPrev)
186 {
187 	UTOPIA_RESOURCE_POOL* pRPool = TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
188 	UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
189 
190 	while (pRPool != NULL && pRPool->u32PoolID != u32LocatedRPoolID)
191 	{
192 		pRPoolPrev = pRPool;
193 		pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
194 	}
195 
196 	*ppRPool = pRPool;
197 	*ppRPoolPrev = pRPoolPrev;
198 	return 0;
199 }
200 
201 /*static void UtopiaResourcePoolLocate(MS_U32 u32PoolID, void** ppsResourcePoolTmp, void** ppsResourcePoolPrevTmp)
202 {
203 	UTOPIA_RESOURCE_POOL** ppsResourcePool = (UTOPIA_RESOURCE_POOL**)ppsResourcePoolTmp;
204 	UTOPIA_RESOURCE_POOL** ppsResourcePoolPrev = (UTOPIA_RESOURCE_POOL**)ppsResourcePoolPrevTmp;
205 	UTOPIA_RESOURCE_POOL* psResourcePool = *ppsResourcePool;
206 	UTOPIA_RESOURCE_POOL* psResourcePoolPrev = *ppsResourcePoolPrev = NULL;
207 
208 	while (psResourcePool != NULL && psResourcePool->u32PoolID != u32PoolID)
209 	{
210 		psResourcePoolPrev = psResourcePool;
211 		psResourcePool = (UTOPIA_RESOURCE_POOL*)shmid2va(psResourcePool->shmid_next_rpool.ID);
212 	}
213 	*ppsResourcePool = psResourcePool;
214 	*ppsResourcePoolPrev = psResourcePoolPrev;
215 }*/
216 
locate_resource(UTOPIA_RESOURCE_POOL * pRPool,MS_U32 u32LocatedResourceID,UTOPIA_RESOURCE ** ppResource,UTOPIA_RESOURCE ** ppResourcePrev)217 static int locate_resource(UTOPIA_RESOURCE_POOL* pRPool, MS_U32 u32LocatedResourceID
218 		, UTOPIA_RESOURCE** ppResource, UTOPIA_RESOURCE** ppResourcePrev)
219 {
220 	UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(shmid2va(pRPool->shmid_resource_head.ID));
221 	UTOPIA_RESOURCE* pResourcePrev = NULL;
222 
223 	while (pResource != NULL && (pResource->shmid_self.ID != u32LocatedResourceID))
224 	{
225 		pResourcePrev = pResource;
226 		pResource = TO_RESOURCE_PTR(shmid2va(pResource->shmid_next_resource.ID));
227 	}
228 
229 	*ppResource = pResource;
230 	*ppResourcePrev = pResourcePrev;
231 	return 0;
232 }
233 
234 //##########################
235 //## Static Functions End ##
236 //##########################
237 
238 //#############################
239 //## Instance Functions Start ##
240 //#############################
UtopiaInstanceCreate(MS_U32 u32PrivateSize,void ** ppInstance)241 MS_U32 UtopiaInstanceCreate(MS_U32 u32PrivateSize, void** ppInstance)
242 {
243     UTOPIA_INSTANCE* pInstance = NULL;
244 
245 	// check parameters
246 	if (ppInstance == NULL)
247 		printf("ppInstance should not be NULL\n");
248 
249     pInstance = malloc(sizeof(UTOPIA_INSTANCE));
250     memset((void*)pInstance, 0, sizeof(UTOPIA_INSTANCE));
251     if (u32PrivateSize != 0)
252     {
253         pInstance->pPrivate = malloc(u32PrivateSize);
254         memset(pInstance->pPrivate, 0, u32PrivateSize);
255     }
256     //pInstant->u32DeviceDebugLevel   = 0; // FIXME: u32DeviceDebugLevel is in UTOPIA_MODULE_NODE_SHM
257 
258 	*ppInstance = pInstance;
259     return 0; // FIXME: error code
260 }
261 
UtopiaInstanceDelete(void * pInstance)262 MS_U32 UtopiaInstanceDelete(void* pInstance)
263 {
264 	free(TO_INSTANCE_PTR(pInstance)->pPrivate);
265 	free(pInstance);
266 
267 	return 0; // FIXME: error code
268 }
269 
UtopiaInstanceGetPrivate(void * pInstance,void ** ppPrivate)270 MS_U32 UtopiaInstanceGetPrivate(void* pInstance, void** ppPrivate)
271 {
272 	*ppPrivate = TO_INSTANCE_PTR(pInstance)->pPrivate;
273 	return 0; // FIXME: error code
274 }
275 
UtopiaInstanceGetModule(void * pInstance,void ** ppModule)276 MS_U32 UtopiaInstanceGetModule(void* pInstance, void** ppModule)
277 {
278 	*ppModule = TO_INSTANCE_PTR(pInstance)->psModule;
279 	return 0; // FIXME: error code
280 }
281 
UtopiaInstanceGetModuleID(void * pInstance,MS_U32 * pu32ModuleID)282 MS_U32 UtopiaInstanceGetModuleID(void* pInstance, MS_U32* pu32ModuleID)
283 {
284 	*pu32ModuleID = TO_INSTANCE_PTR(pInstance)->psModule->u32ModuleID;
285 	return 0;
286 }
287 
UtopiaInstanceGetModuleVersion(void * pInstance,MS_U32 * pu32Version)288 MS_U32 UtopiaInstanceGetModuleVersion(void* pInstance, MS_U32* pu32Version)
289 {
290 	*pu32Version = TO_INSTANCE_PTR(pInstance)->psModule->u32Version;
291 	return 0;
292 }
293 
UtopiaInstanceGetAppRequiredModuleVersion(void * pInstance,MS_U32 * pu32ModuleVersion)294 MS_U32 UtopiaInstanceGetAppRequiredModuleVersion(void* pInstance, MS_U32* pu32ModuleVersion)
295 {
296 	*pu32ModuleVersion = TO_INSTANCE_PTR(pInstance)->u32AppRequireModuleVersion;
297 	return 0;
298 }
299 //###########################
300 //## Instant Functions End ##
301 //###########################
302 
303 //############################
304 //## Module Functions Start ##
305 //############################
306 // assume one module for each driver, otherwise they have to pass module name as parameter
UtopiaModuleCreate(MS_U32 u32ModuleID,MS_U32 u32PrivateSize,void ** ppModule)307 MS_U32 UtopiaModuleCreate(MS_U32 u32ModuleID, MS_U32 u32PrivateSize, void** ppModule)
308 {
309 	MS_U32 u32ShmID;
310 	UTOPIA_MODULE_SHM* pModuleShm = NULL;
311 	UTOPIA_MODULE* pModule = NULL;
312 	void* pPrivate = NULL;
313 	char privateName[50]; // FIXME: potential bug
314 
315 	// 1. create module@shm
316 	pModuleShm = shm_malloc(sizeof(UTOPIA_MODULE_SHM), moduleNames[u32ModuleID], &u32ShmID);
317 	pModuleShm->shmid_rpool_head.ID = 0xFFFFFFFF;
318 
319 	// 2. create module
320 	pModule = malloc(sizeof(UTOPIA_MODULE));
321     memset(pModule, 0, sizeof(UTOPIA_MODULE));
322 	pModule->u32ModuleID = u32ModuleID;
323 	pModule->psModuleShm = pModuleShm;
324 
325 	// 3. create private of module
326 	snprintf(privateName, sizeof(privateName), "%s_PRI", moduleNames[u32ModuleID]);
327 	pPrivate = shm_malloc(u32PrivateSize, privateName, &(pModule->shmid_private.ID));
328 
329 	// 4. initial str private
330 	pModule->shmid_str.ID=0xFFFFFFFF;
331 
332 	*ppModule = pModule;
333 	return 0; //FIXME: error code
334 }
335 
UtopiaModuleGetPrivate(void * pModule,void ** ppPrivate)336 MS_U32 UtopiaModuleGetPrivate(void* pModule, void** ppPrivate)
337 {
338 	*ppPrivate = shmid2va(TO_MODULE_PTR(pModule)->shmid_private.ID);
339 	return 0;
340 }
341 
UtopiaModuleSetSTRPrivate(void * pModule,MS_U32 u32STRPrivateSize)342 MS_U32 UtopiaModuleSetSTRPrivate(void* pModule, MS_U32 u32STRPrivateSize)
343 {
344 	char privateName[50]; // FIXME: potential bug
345 	void* pPrivate = NULL;
346 
347 	/* check str private exist? */
348 	if (!pModule)
349 	{
350 		printf("[utopia param error] module pointer should not be null\n");
351 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
352 	}
353 	if (0xFFFFFFFF != TO_MODULE_PTR(pModule)->shmid_str.ID)
354 	{
355 		printf("[utopia module error] set duplicated STR private of module: %s\n"
356 				, moduleNames[TO_MODULE_PTR(pModule)->u32ModuleID]);
357 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
358 	}
359 
360 	/* create str private of module */
361 	snprintf(privateName, sizeof(privateName)
362 			, "%s_STR", moduleNames[TO_MODULE_PTR(pModule)->u32ModuleID]);
363 	pPrivate = shm_malloc(u32STRPrivateSize, privateName,
364 			&(TO_MODULE_PTR(pModule)->shmid_str.ID));
365 
366 	if(pPrivate == NULL)  //Coverity
367 	{
368 		printu("[utopia malloc error] Line: %d shm_malloc fail\n",__LINE__);
369 	}
370 
371 	return 0;
372 }
373 
UtopiaModuleGetSTRPrivate(void * pModule,void ** ppPrivate)374 MS_U32 UtopiaModuleGetSTRPrivate(void* pModule, void** ppPrivate)
375 {
376 	/* check str private exist? */
377 	if (!pModule)
378 	{
379 		printu("[utopia param error] module pointer should not be null\n");
380 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
381 	}
382 	if (0xFFFFFFFF == TO_MODULE_PTR(pModule)->shmid_str.ID)
383 	{
384 		printf("[utopia module error] NULL STR private of module: %s\n"
385 				, moduleNames[TO_MODULE_PTR(pModule)->u32ModuleID]);
386 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
387 	}
388 
389 	*ppPrivate = shmid2va(TO_MODULE_PTR(pModule)->shmid_str.ID);
390 	return 0;
391 }
392 
UtopiaModuleRegister(void * pModuleTmp)393 MS_U32  UtopiaModuleRegister(void* pModuleTmp)
394 {
395 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
396 	UTOPIA_MODULE* pLocatedModule = NULL;
397 
398 	// check parameter
399 	if (pModule == NULL)
400 	{
401 		printf("module pointer can't be null\n");
402 		return 1; // FIXME: error code
403 	}
404 
405 	pLocatedModule = TO_MODULE_PTR(locate_module(pModule->u32ModuleID));
406 	if (pLocatedModule == NULL) // module is not yet registered
407 	{
408 		// insert module into list head
409 		printf("register module: %s\n", moduleNames[pModule->u32ModuleID]);
410 		pModule->psNext = psUtopiaPrivate->psModuleHead;
411 		psUtopiaPrivate->psModuleHead = pModule;
412 		return 0; // FIXME: error code
413 	}
414 	else  // module is already registered
415     {
416         printf("error: register duplicated module: %s\n", moduleNames[pModule->u32ModuleID]);
417         return 1; // FIXME: error code
418     }
419 }
420 
UtopiaModuleSetupFunctionPtr(void * pModuleTmp,FUtopiaOpen fpOpen,FUtopiaClose fpClose,FUtopiaIOctl fpIoctl)421 MS_U32 UtopiaModuleSetupFunctionPtr(void* pModuleTmp, FUtopiaOpen fpOpen, FUtopiaClose fpClose, FUtopiaIOctl fpIoctl)
422 {
423 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
424 
425 	pModule->fpOpen = fpOpen;
426 	pModule->fpClose = fpClose;
427 	pModule->fpIoctl = fpIoctl;
428 
429 	return 0; //FIXME: error code
430 }
431 
UtopiaModuleSetupSTRFunctionPtr(void * pModuleTmp,FUtopiaSTR fpSTR)432 MS_U32 UtopiaModuleSetupSTRFunctionPtr(void* pModuleTmp, FUtopiaSTR fpSTR)
433 {
434 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
435 
436 	if (!pModuleTmp)
437 	{
438 		printf("[utopia param error] module pointer should not be null\n");
439 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
440 	}
441 	pModule->fpSTR = fpSTR;
442 	/* insert linked list */
443 	UTOPIA_MODULE_STR_LIST_CURRENT = (UTOPIA_MODULE_STR_LIST*)malloc( sizeof(UTOPIA_MODULE_STR_LIST) );
444 	UTOPIA_MODULE_STR_LIST_CURRENT->fpSTR = fpSTR;
445 	UTOPIA_MODULE_STR_LIST_CURRENT->pModule = pModuleTmp;
446 	UTOPIA_MODULE_STR_LIST_CURRENT->next = NULL;
447 	if(UTOPIA_MODULE_STR_LIST_HEAD == NULL)
448 	{
449 		UTOPIA_MODULE_STR_LIST_HEAD = UTOPIA_MODULE_STR_LIST_CURRENT;
450 	}
451 	else
452 	{
453 		UTOPIA_MODULE_STR_LIST_PREV->next = UTOPIA_MODULE_STR_LIST_CURRENT;
454 	}
455 	UTOPIA_MODULE_STR_LIST_PREV = UTOPIA_MODULE_STR_LIST_CURRENT;
456 	return 0;
457 }
458 
UtopiaModuleSuspend(void)459 MS_U32 UtopiaModuleSuspend(void)
460 {
461 	UTOPIA_MODULE_STR_LIST_CURRENT = UTOPIA_MODULE_STR_LIST_HEAD;
462 	while(1)
463 	{
464 
465 		if(UTOPIA_MODULE_STR_LIST_CURRENT == NULL)
466 			break;
467 
468 		UTOPIA_MODULE_STR_LIST_CURRENT->fpSTR(E_POWER_SUSPEND, UTOPIA_MODULE_STR_LIST_CURRENT->pModule);
469 		if(UTOPIA_MODULE_STR_LIST_CURRENT->next == NULL)
470 		{
471 			break;
472 		}
473 		UTOPIA_MODULE_STR_LIST_CURRENT = UTOPIA_MODULE_STR_LIST_CURRENT->next;
474 	}
475 	return 0;
476 }
477 
UtopiaModuleResume(void)478 MS_U32 UtopiaModuleResume(void)
479 {
480     FUtopiaSTR fpSealSTR = NULL;
481     UTOPIA_MODULE_STR_LIST_CURRENT = UTOPIA_MODULE_STR_LIST_HEAD;
482     while(1)
483     {
484         if(UTOPIA_MODULE_STR_LIST_CURRENT == NULL)
485         {
486             break;
487         }
488         if(MODULE_SEAL == TO_MODULE_PTR(UTOPIA_MODULE_STR_LIST_CURRENT->pModule)->u32ModuleID)
489         {
490             fpSealSTR = UTOPIA_MODULE_STR_LIST_CURRENT->fpSTR;
491         }
492         else
493         {
494             UTOPIA_MODULE_STR_LIST_CURRENT->fpSTR(E_POWER_RESUME, UTOPIA_MODULE_STR_LIST_CURRENT->pModule);
495         }
496         if(UTOPIA_MODULE_STR_LIST_CURRENT->next == NULL)
497         {
498             break;
499         }
500         UTOPIA_MODULE_STR_LIST_CURRENT = UTOPIA_MODULE_STR_LIST_CURRENT->next;
501     }
502     if(fpSealSTR != NULL)
503     {
504         fpSealSTR(E_POWER_RESUME, UTOPIA_MODULE_STR_LIST_CURRENT->pModule);
505     }
506     return 0;
507 }
508 
UtopiaModuleSetVersion(void * pModule,MS_U32 u32Version)509 MS_U32 UtopiaModuleSetVersion(void* pModule, MS_U32 u32Version)
510 {
511 	TO_MODULE_PTR(pModule)->u32Version = u32Version;
512 
513 	return 0;
514 }
515 
UtopiaModuleGetDebugLevel(void * pInstance,MS_U32 * pu32DebugLevel)516 MS_U32 UtopiaModuleGetDebugLevel(void* pInstance, MS_U32* pu32DebugLevel)
517 {
518 	*pu32DebugLevel = TO_INSTANCE_PTR(pInstance)->psModule->u32DeviceDebugLevel;
519 	return 0;
520 }
521 
UtopiaModuleGetPtr(MS_U32 u32ModuleID,void ** ppModule)522 MS_U32 UtopiaModuleGetPtr(MS_U32 u32ModuleID, void** ppModule)
523 {
524 	*ppModule = locate_module(u32ModuleID);
525 
526 	return 0;
527 }
528 //##########################
529 //## Module Functions End ##
530 //##########################
531 
532 //##############################
533 //## Resource Functions Start ##
534 //##############################
UtopiaResourceCreate(char * resourceName,MS_U32 u32PrivateSize,void ** ppResource)535 MS_U32 UtopiaResourceCreate(char* resourceName, MS_U32 u32PrivateSize, void** ppResource)
536 {
537 	MS_U32 u32RetResourceShmID;
538 	UTOPIA_RESOURCE* pResource = NULL;
539 	char privateName[50]; // FIXME: potential bug
540 
541 	// 1. create resource
542 	pResource = shm_malloc(sizeof(UTOPIA_RESOURCE), resourceName, &(u32RetResourceShmID));
543 	pResource->shmid_self.ID = u32RetResourceShmID;
544 	pResource->shmid_next_resource.ID = 0xFFFFFFFF;
545 	*ppResource = pResource;
546 
547 	// 2. create resource private
548 	snprintf(privateName, sizeof(privateName), "%s_PRI", resourceName);
549 	shm_malloc(u32PrivateSize, privateName, &(pResource->shmid_private.ID));
550 
551 	return 0; // FIXME: error code
552 }
553 
UtopiaResourceGetPrivate(void * pResource,void ** ppPrivate)554 MS_U32 UtopiaResourceGetPrivate(void* pResource, void** ppPrivate)
555 {
556 	*ppPrivate = shmid2va(TO_RESOURCE_PTR(pResource)->shmid_private.ID);
557 	return 0;
558 }
559 
560 // case 1: no resource pool -> create resource pool & attach resource to it. combine with case 2
561 // case 2: resource pool exists, but no mathcing resource pool -> create resource pool & attach resource to it. combine with case 1
562 // case 3: resource pool exists, and there's matching resource pool -> attach resource to it
UtopiaResourceRegister(void * pModuleTmp,void * pResourceTmp,MS_U32 u32RPoolID)563 MS_U32 UtopiaResourceRegister(void* pModuleTmp, void* pResourceTmp, MS_U32 u32RPoolID)
564 {
565     //lock(u32ResourcePoolsMutex)
566     //insert psResouce into psModuleNode->psResourcePoolHeads->psResourceHeads->psResource
567 
568 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
569 	UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(pResourceTmp);
570 	char rpoolName[50];
571 
572 	// 1. deal with resource pool
573 	UTOPIA_RESOURCE_POOL* pRPool = NULL;
574 	UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
575 	locate_resource_pool(pModule, u32RPoolID, &pRPool, &pRPoolPrev);
576 	// case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
577 	// case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
578 	// case 3: at least one resource pool exists, and so is the located one --> *ppRPool != NULL & ppRPoolPrev doesn't matter
579 	if (pRPool == NULL) { // case 1 or 2
580 		MS_U32 u32RetRPoolShmID;
581 		MS_U32 u32ModuleID = pModule->u32ModuleID;
582 
583 		snprintf(rpoolName, sizeof(rpoolName), "%s_%d", rpoolNames[u32ModuleID], (int)u32RPoolID);
584 		pRPool = shm_malloc(sizeof(UTOPIA_RESOURCE_POOL), rpoolName, &u32RetRPoolShmID);
585 		pRPool->shmid_self.ID = u32RetRPoolShmID;
586 		pRPool->u32PoolID = u32RPoolID;
587 		pRPool->shmid_next_rpool.ID = 0xFFFFFFFF;
588 		pRPool->shmid_resource_head.ID = 0xFFFFFFFF;
589 
590 		// set up connection
591 		if (pRPoolPrev == NULL) // case 1
592 		{
593 			pModule->psModuleShm->shmid_rpool_head.ID = u32RetRPoolShmID;
594 		}
595 		else // case 2
596 		{
597 			pRPoolPrev->shmid_next_rpool.ID = u32RetRPoolShmID;
598 		}
599 
600 		pModule->psModuleShm->u32ResourcePoolTotal++;
601 	}
602 
603 	// 2. deal with resource
604 	pResource->shmid_rpool = pRPool->shmid_self;
605 
606 	UTOPIA_RESOURCE* pLocatedResource = NULL;
607 	UTOPIA_RESOURCE* pLocatedResourcePrev = NULL;
608 	locate_resource(pRPool, pResource->shmid_self.ID, &pLocatedResource, &pLocatedResourcePrev);
609 	// case 1: there's no resource in pool --> pLocatedResource = NULL, pLocatedResourcePrev = NULL
610 	// case 2: at least one resource exists, but not the located one --> pLocatedResource = NULL, pLocatedResourcePrev != NULL
611 	// case 3: at least one resource exists, and so is the located one --> pLocatedResource != NULL, pLocatedResourcePrev doesn't matter
612 	if (pLocatedResource == NULL) // case 1 or 2
613 	{
614 		if (pLocatedResourcePrev == NULL) // case 1
615 		{
616 			pRPool->shmid_resource_head.ID = pResource->shmid_self.ID;
617 		}
618 		else // case 2
619 		{
620 			pLocatedResourcePrev->shmid_next_resource.ID = pResource->shmid_self.ID;
621 		}
622 		pRPool->u32ResourceTotal++;
623 
624 		return 0;
625 	}
626 	else // case 3
627 	{
628 		// duplicated registration: it may be registered by other process
629 		return 1;
630 	}
631 
632     //unlock(u32ResourcePoolsMutex)
633 }
634 
635 
UtopiaResourceObtain(void * pModule,MS_U32 u32RPoolID,void ** ppResource)636 MS_U32 UtopiaResourceObtain(void* pModule, MS_U32 u32RPoolID, void** ppResource)
637 {
638     //Search and get one resource from psModuleNode->psResourcePoolHeads
639     //set flag bit0 to 1 for using
640 
641 	//UTOPIA_RESOURCE_POOL* psResourcePool = NULL;
642 	//psResourcePool = MODULE_PTR_TO_RPOOL_PTR(TO_MODULE_PTR(pModule));
643 	//UTOPIA_RESOURCE_POOL* psResourcePoolPrev = NULL;
644 	//UTOPIA_RESOURCE* psResource = NULL;
645 	UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
646 	UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
647 	UTOPIA_RESOURCE* pAvailResource = NULL;
648 	locate_resource_pool(TO_MODULE_PTR(pModule), u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
649 
650 
651     //semephone_lock(u32ResourcesSemaphore)
652 	obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
653 
654 	pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
655 	while (pAvailResource != NULL)
656 	{
657 		if (!(pAvailResource->bInUse))
658 		{
659 			pAvailResource->bInUse = true;
660 			*ppResource	= pAvailResource;
661 			return 0;
662 		}
663 		else
664 		{
665 			pAvailResource = next_resource(pAvailResource, E_TYPE_MODULE);
666 		}
667 	}
668 
669 	return 1; // what kind of situation? FIXME: error code
670 
671     //lock(u32ResourcesSemaphore)
672     //semephone_unlock(u32ResourcesSemaphore)
673 }
674 
UtopiaResourceRelease(void * pResource)675 MS_U32 UtopiaResourceRelease(void* pResource)
676 {
677 	UTOPIA_RESOURCE_POOL* pRPool = RESOURCE_PTR_TO_RPOOL_PTR(TO_RESOURCE_PTR(pResource));
678 
679 	// modify resource before releasing it, to avoid race condition
680 	TO_RESOURCE_PTR(pResource)->bInUse = false;
681 	release_sem(pRPool->u32ResourcesSemaphore);
682 
683 	return 0;
684 }
685 
UtopiaModuleAddResourceStart(void * psModuleTmp,MS_U32 u32PoolID)686 MS_U32 UtopiaModuleAddResourceStart(void* psModuleTmp, MS_U32 u32PoolID)
687 {
688 	return 0;
689 }
690 
691 #define PERMS 0666
692 // semaphore num isn't equal to resource count
693 #define SEMAPHORE_NUM 1
694 //MS_U32 u32LastUtopiaSemID = UTOPIA_SEM_START;
UtopiaModuleAddResourceEnd(void * pModuleTmp,MS_U32 u32RPoolID)695 MS_U32 UtopiaModuleAddResourceEnd(void* pModuleTmp, MS_U32 u32RPoolID)
696 {
697 	int u32SemaphoreID;
698 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
699 
700 	UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
701 	UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
702 	//psResourcePool = (UTOPIA_RESOURCE_POOL*)shmid2va(pModule->psModuleShm->shmid_rpool_head.ID);
703 	locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
704 
705 	if (pLocatedRPool->u32ResourcesSemaphore != 0 && pLocatedRPool->u32ResourcesSemaphore != 0xFFFFFFFF)
706 	{
707 		printf("semaphore id %d already exists\n", (int)pLocatedRPool->u32ResourcesSemaphore);
708 		return 1; // FIXME: error code
709 	}
710 
711 	//MS_U32* pu32SemKey = (MS_U32*)shmid2va(4);  // 4 for semaphore private
712 	MS_U32 u32PoolShmID = pModule->psModuleShm->shmid_rpool_head.ID;
713 	UTOPIA_RESOURCE_POOL* pResourcePool = shmid2va(u32PoolShmID);
714 	// FIXME: misuse? should I use utopia module resource instead?
715 	MS_U32* pu32SemKey = (MS_U32*)shmid2va(pResourcePool->shmid_resource_head.ID);
716 
717 	//u32SemID = semget(*pu32SemKey, 0, IPC_CREAT | PERMS);
718 	u32SemaphoreID = MsOS_InfoSemaphore(*pu32SemKey, &(pLocatedRPool->u32ResourceTotal), NULL, NULL);
719 
720 	//if(u32SemID == 0 || u32SemID == 0xFFFFFFFF)
721 	if(u32SemaphoreID == FALSE)
722     {
723 
724         //u32SemID = semget(*pu32SemKey, 1, IPC_CREAT | PERMS); // "1" means semaphore num, not its initial value
725 		u32SemaphoreID = MsOS_CreateSemaphore(pLocatedRPool->u32ResourceTotal,E_MSOS_FIFO ,"dont care");
726         //if ((u32SemID != 0 && u32SemID != 0xFFFFFFFF)) // create success, increase *pu32SemKey for next sem create
727         //{
728             (*pu32SemKey)++;
729         //}
730 
731         //while(u32SemID == 0 || u32SemID == 0xFFFFFFFF)
732         //{
733             //u32SemID = semget(*pu32SemKey, 1, IPC_CREAT | PERMS); // "1" means semaphore num, not its initial value
734 			//u32SemID = MsOS_CreateSemaphore(0,E_MSOS_FIFO ,"dont care");
735             //(*pu32SemKey)++;
736         //}
737         if (u32SemaphoreID < 0)
738         {
739             printf("Couldn't create semaphore!\n");
740             //exit(-1);
741         }
742 
743         //semctl(u32SemID, 0, SETVAL, psResourcePool->u32ResourceTotal); // "0" is the semaphore id in sem. set which we got by semget
744                                             //SEVAL, "1" set its initial value
745         //semctl(u32SemID, 0, SETVAL, 3); // "0" is the semaphore id in sem. set which we got by semget
746     }
747 	pLocatedRPool->u32ResourcesSemaphore = u32SemaphoreID;
748 
749 	return 0;
750 }
751