xref: /utopia/UTPA2-700.0.x/modules/msos/utopia_core/ucos/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 
10 #define PRINT_DEBUG_INFO    0
11 #if PRINT_DEBUG_INFO
12 #define PRINT_INFO(fmt, args...)  printf("[Utopia Info]" fmt, ## args)
13 #else
14 #define PRINT_INFO(fmt, args...)
15 #endif
16 
17 // length should be the same to definition
18 extern char moduleNames[][40];
19 extern char rpoolNames[][40];
20 extern char ResourceNames[][40];
21 
22 struct shm_info {
23 	void* va;
24 	char name[40]; // FIXME: array length should be unify
25 };
26 
27 /*
28  * could be equal to MAX_CLIENT_NUM=32 defined in MsOS_eCos.c
29  * cause we ues shm id as table index, there may be holes in the table
30  */
31 #define SHM_INFO_TABLE_LENGTH 200
32 struct shm_info shm_info_table[SHM_INFO_TABLE_LENGTH] = {{NULL, ""}};
33 
34 extern UTOPIA_PRIVATE* psUtopiaPrivate;
35 
36 //############################
37 //## Static Functions Start ##
38 //############################
39 enum eObjectType
40 {
41 	E_TYPE_INSTANCE,
42 	E_TYPE_MODULE,
43 	E_TYPE_MODULE_SHM,
44 	E_TYPE_RESOURCE_POOL,
45 	E_TYPE_RESOURCE,
46 };
47 
obtain_sem(MS_U32 u32SemID)48 static void obtain_sem(MS_U32 u32SemID)
49 {
50     /* Perform down operation */
51 	MsOS_ObtainSemaphore(u32SemID, MSOS_WAIT_FOREVER);
52 }
53 
release_sem(MS_U32 u32SemID)54 static void release_sem(MS_U32 u32SemID)
55 {
56     /* Perform down operation */
57 	MsOS_ReleaseSemaphore(u32SemID);
58 }
59 
60 
shmid2va(MS_U32 u32ShmID)61 static inline void* shmid2va(MS_U32 u32ShmID)
62 {
63 	if (u32ShmID == 0xFFFFFFFF)
64 		return NULL;
65 	return shm_info_table[u32ShmID].va;
66 }
67 
isFirstCreation(void * pUnknown,enum eObjectType eObjectType)68 static inline int isFirstCreation(void* pUnknown, enum eObjectType eObjectType)
69 {
70 	switch(eObjectType)
71 	{
72 		case E_TYPE_MODULE_SHM:
73 			return TO_MODULE_SHM_PTR(pUnknown)->shmid_self.ID == 0;
74 		case E_TYPE_RESOURCE:
75 			return TO_RESOURCE_PTR(pUnknown)->shmid_self.ID == 0;
76 		case E_TYPE_RESOURCE_POOL:
77 			return TO_RPOOL_PTR(pUnknown)->shmid_self.ID == 0;
78 		default:
79 			printf("[utopia error] type is not supported\n");
80 			RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
81 	}
82 }
83 
84 /*
85  * u32ShmSize: user specified shared memory size
86  * shmName: user specified shared memory name
87  * p32RetShmID: for returning shared memory id
88  * return: shared memory address in virtual
89  */
shm_malloc(MS_U32 u32ShmSize,char * shmName,MS_U32 * pu32RetShmID)90 static void* shm_malloc(MS_U32 u32ShmSize, char* shmName, MS_U32* pu32RetShmID)
91 {
92     MS_U32 u32RetShmID=0, u32RetAddr=0, u32RetShmSize=0;
93 	MS_U32 u32Ret;
94 
95 	/* check param. */
96 	if (strcmp(shmName, "") == 0)
97 	{
98 		printf("shmem name string should not be empty\n");
99 		while(1);
100 	}
101 
102 	/*
103 	 * u32Ret: 0 for not found
104 	 *         1 for existence
105 	 * u32RetShmID: 0 for not found(original value)
106 	 *              n for created share mem id, start from 1
107 	 */
108 	u32Ret = MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_QUERY);
109 
110 	/*
111 	 * MsOS_SHM_GetId need to be called for each process
112 	 * to set up per-process shmid2va table
113 	 * it's ok for duplicated calls with same shmName
114 	 */
115 	MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_CREATE);
116 
117 	/*
118 	 * check whether table limit is reached?
119 	 */
120     // shm_info_table is for the shm_id and shm_addr mapping
121 	if(u32RetShmID >= SHM_INFO_TABLE_LENGTH)
122 	{
123 		printf("[%s error] returned shm id %d exceeds shm-info table length %d\n"
124 				, __FUNCTION__, (int)u32RetShmID, SHM_INFO_TABLE_LENGTH);
125 		while(1);
126 	}
127 	if(shm_info_table[u32RetShmID].va != NULL)
128 	{
129 		printf("error: register duplicated shared memory ID %d: %s@%p\n"
130 		, (int)u32RetShmID, shm_info_table[u32RetShmID].name, shm_info_table[u32RetShmID].va);
131 		while(1);
132 	}
133     else
134     {
135 		shm_info_table[u32RetShmID].va = (void*)u32RetAddr;
136 		strncpy(shm_info_table[u32RetShmID].name, shmName, sizeof(shm_info_table[u32RetShmID].name)); // FIXME: potential bug
137         if(!(0 == strcmp(shm_info_table[u32RetShmID].name, shmName)))
138         {
139             printf("\033[35mFunction = %s, Line = %d, error, strncpy failed!!\033[m\n", __FUNCTION__, __LINE__);
140             while(1);
141         }
142 		PRINT_INFO("shm_info_table[%d] = %s@%p\n", (int)u32RetShmID, shmName, (void*)u32RetAddr);
143 	}
144 
145 	// u32Ret: TRUE for success, FALSE for failure
146 	// if failure --> first time allocation, memset to 0
147 	if(u32Ret != 1)
148 		memset((void*)u32RetAddr, 0, u32RetShmSize);
149 
150 	*pu32RetShmID = u32RetShmID;
151 	return (void*)u32RetAddr;
152 }
153 
next_resource(void * pUnkown,enum eObjectType eObjectType)154 static UTOPIA_RESOURCE* next_resource(void* pUnkown, enum eObjectType eObjectType)
155 {
156 	switch(eObjectType)
157 	{
158 		case E_TYPE_RESOURCE_POOL:
159 			return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE_POOL*)pUnkown)->shmid_resource_head.ID);
160 		case E_TYPE_RESOURCE:
161 			return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE*)pUnkown)->shmid_next_resource.ID);
162 		default:
163 			printf("%s, %d, %s, [utopia error] type is not supported\n", __FUNCTION__, __LINE__, __FILE__);
164 			RET_OR_BLOCK(NULL);
165 	}
166 }
167 
168 /* return located module address or NULL if not found */
locate_module(MS_U32 u32ModuleID)169 static void* locate_module(MS_U32 u32ModuleID)
170 {
171 	UTOPIA_MODULE* pLocatedModule = psUtopiaPrivate->psModuleHead;
172 
173 	while (pLocatedModule != NULL && pLocatedModule->u32ModuleID != u32ModuleID)
174 		pLocatedModule = pLocatedModule->psNext;
175 
176 	return pLocatedModule;
177 }
178 
179 // case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
180 // case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
181 // 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)182 static int locate_resource_pool(UTOPIA_MODULE* pModule, MS_U32 u32LocatedRPoolID
183 		, UTOPIA_RESOURCE_POOL** ppRPool, UTOPIA_RESOURCE_POOL** ppRPoolPrev)
184 {
185 	UTOPIA_RESOURCE_POOL* pRPool = TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
186 	UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
187 
188 	while (pRPool != NULL && pRPool->u32PoolID != u32LocatedRPoolID)
189 	{
190 		pRPoolPrev = pRPool;
191 		pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
192 	}
193 
194 	*ppRPool = pRPool;
195 	*ppRPoolPrev = pRPoolPrev;
196 	return 0;
197 }
198 
locate_resource(UTOPIA_RESOURCE_POOL * pRPool,MS_U32 u32LocatedResourceID,UTOPIA_RESOURCE ** ppResource,UTOPIA_RESOURCE ** ppResourcePrev)199 static int locate_resource(UTOPIA_RESOURCE_POOL* pRPool, MS_U32 u32LocatedResourceID
200 		, UTOPIA_RESOURCE** ppResource, UTOPIA_RESOURCE** ppResourcePrev)
201 {
202 	UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(shmid2va(pRPool->shmid_resource_head.ID));
203 	UTOPIA_RESOURCE* pResourcePrev = NULL;
204 
205 	while (pResource != NULL && (pResource->shmid_self.ID != u32LocatedResourceID))
206 	{
207 		pResourcePrev = pResource;
208 		pResource = TO_RESOURCE_PTR(shmid2va(pResource->shmid_next_resource.ID));
209 	}
210 
211 	*ppResource = pResource;
212 	*ppResourcePrev = pResourcePrev;
213 	return 0;
214 }
215 
check_rpool_semaphore(MS_U32 u32ModuleID)216 int check_rpool_semaphore(MS_U32 u32ModuleID)
217 {
218 	/* locate target module in stupid way */
219 	UTOPIA_MODULE* pModule = NULL;
220 	pModule = psUtopiaPrivate->psModuleHead;
221 	while (pModule != NULL && pModule->u32ModuleID != u32ModuleID)
222 	{
223 		pModule = pModule->psNext;
224 	}
225 
226 	/* locate corresponding rpool in stupid way */
227 	UTOPIA_RESOURCE_POOL* pRPool = NULL;
228 	if (pModule != NULL) /* found */
229 	{
230 		pRPool = TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
231 	}
232     else
233     {
234 		printf("[utopia error] module of u32ModuleID isn't found\n");
235 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
236 	}
237 
238 	/* check rpool semaphore one by one */
239 	while (pRPool != NULL)
240 	{
241 		if (!(pRPool->u32ResourcesSemaphore))
242 		{
243 			printf("[utopia error] resource pool %s has no semaphore\n", pRPool->shmid_self.name);
244 			RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
245 		}
246 		pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
247 	}
248 
249 	return 0;
250 }
251 //##########################
252 //## Static Functions End ##
253 //##########################
254 
255 //#############################
256 //## Instance Functions Start ##
257 //#############################
UtopiaInstanceCreate(MS_U32 u32PrivateSize,void ** ppInstance)258 MS_U32 UtopiaInstanceCreate(MS_U32 u32PrivateSize, void** ppInstance)
259 {
260     UTOPIA_INSTANCE* pInstance = NULL;
261 
262 	/* check param. */
263 	if (ppInstance == NULL)
264 	{
265 		printf("[utopia error] instance ppointer should not be null\n");
266 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
267 	}
268 
269     pInstance = malloc(sizeof(UTOPIA_INSTANCE));
270     memset(pInstance, 0, sizeof(UTOPIA_INSTANCE));
271     pInstance->pPrivate = malloc(u32PrivateSize);
272     memset(pInstance->pPrivate, 0, u32PrivateSize);
273 	PRINT_INFO("create instance at %p with private size %d bytes at %p\n" \
274 			, pInstance, (int)u32PrivateSize, pInstance->pPrivate);
275 
276 	*ppInstance = pInstance;
277     return UTOPIA_STATUS_SUCCESS;
278 }
279 
UtopiaInstanceDelete(void * pInstance)280 MS_U32 UtopiaInstanceDelete(void* pInstance)
281 {
282 	free(TO_INSTANCE_PTR(pInstance)->pPrivate);
283 	free(pInstance);
284 
285 	return UTOPIA_STATUS_SUCCESS;
286 }
287 
UtopiaInstanceGetPrivate(void * pInstance,void ** ppPrivate)288 MS_U32 UtopiaInstanceGetPrivate(void* pInstance, void** ppPrivate)
289 {
290 	/* check param. */
291 	if (pInstance == NULL)
292 	{
293 		printf("[utopia error] instance pointer should not be null\n");
294 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
295 	}
296 	if (ppPrivate == NULL)
297 	{
298 		printf("[utopia error] private ppointer should not be null\n");
299 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
300 	}
301 
302 	*ppPrivate = TO_INSTANCE_PTR(pInstance)->pPrivate;
303 	return UTOPIA_STATUS_SUCCESS;
304 }
305 
UtopiaInstanceGetModule(void * pInstance,void ** ppModule)306 MS_U32 UtopiaInstanceGetModule(void* pInstance, void** ppModule)
307 {
308 	/* check param. */
309 	if (pInstance == NULL)
310 	{
311 		printf("[uopia error] instance pointer should not be null\n");
312 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
313 	}
314 	if (ppModule == NULL)
315 	{
316 		printf("[utopia error] module ppointer should not be null\n");
317 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
318 	}
319 
320 	*ppModule = TO_INSTANCE_PTR(pInstance)->psModule;
321 	return UTOPIA_STATUS_SUCCESS;
322 }
323 
UtopiaInstanceGetModuleID(void * pInstance,MS_U32 * pu32ModuleID)324 MS_U32 UtopiaInstanceGetModuleID(void* pInstance, MS_U32* pu32ModuleID)
325 {
326 	*pu32ModuleID = TO_INSTANCE_PTR(pInstance)->psModule->u32ModuleID;
327 	return UTOPIA_STATUS_SUCCESS;
328 }
329 
UtopiaInstanceGetModuleVersion(void * pInstance,MS_U32 * pu32Version)330 MS_U32 UtopiaInstanceGetModuleVersion(void* pInstance, MS_U32* pu32Version)
331 {
332 	*pu32Version = TO_INSTANCE_PTR(pInstance)->psModule->u32Version;
333 	return UTOPIA_STATUS_SUCCESS;
334 }
335 
UtopiaInstanceGetAppRequiredModuleVersion(void * pInstance,MS_U32 * pu32ModuleVersion)336 MS_U32 UtopiaInstanceGetAppRequiredModuleVersion(void* pInstance, MS_U32* pu32ModuleVersion)
337 {
338 	*pu32ModuleVersion = TO_INSTANCE_PTR(pInstance)->u32AppRequireModuleVersion;
339 	return UTOPIA_STATUS_SUCCESS;
340 }
341 //###########################
342 //## Instant Functions End ##
343 //###########################
344 
345 //############################
346 //## Module Functions Start ##
347 //############################
348 // assume one module for each driver, otherwise they have to pass module name as parameter
UtopiaModuleCreate(MS_U32 u32ModuleID,MS_U32 u32PrivateSize,void ** ppModule)349 MS_U32 UtopiaModuleCreate(MS_U32 u32ModuleID, MS_U32 u32PrivateSize, void** ppModule)
350 {
351 	MS_U32 u32ShmID;
352 	UTOPIA_MODULE_SHM* pModuleShm = NULL;
353 	UTOPIA_MODULE* pModule = NULL;
354 	void* pPrivate = NULL;
355 	char privateName[50]; // FIXME: potential bug
356 
357 	/* 1. create module@shm */
358 	pModuleShm = shm_malloc(sizeof(UTOPIA_MODULE_SHM), moduleNames[u32ModuleID], &u32ShmID);
359 	if (isFirstCreation(pModuleShm, E_TYPE_MODULE_SHM))
360 	{
361 		pModuleShm->shmid_self.ID = u32ShmID;
362 		strcpy(pModuleShm->shmid_self.name, moduleNames[u32ModuleID]);
363 		pModuleShm->shmid_rpool_head.ID = 0xFFFFFFFF;
364 	}
365 	PRINT_INFO("create module@shm %s at %p\n", moduleNames[u32ModuleID], pModuleShm);
366 
367 	/* 2. create module */
368 	pModule = malloc(sizeof(UTOPIA_MODULE));
369     memset(pModule, 0, sizeof(UTOPIA_MODULE));
370 	pModule->u32ModuleID = u32ModuleID;
371 	pModule->psModuleShm = pModuleShm;
372 	PRINT_INFO("create module %s at %p\n", moduleNames[u32ModuleID], pModule);
373 
374 	/* 3. create private of module */
375 	sprintf(privateName, "%s_PRI", moduleNames[u32ModuleID]); // FIXME: potential bug
376 	pPrivate = shm_malloc(u32PrivateSize, privateName, &(pModule->shmid_private.ID));
377 	PRINT_INFO("create private of module %s at %p\n", privateName, pPrivate);
378 
379 	*ppModule = pModule;
380 	return UTOPIA_STATUS_SUCCESS;
381 }
382 
UtopiaModuleGetPrivate(void * pModule,void ** ppPrivate)383 MS_U32 UtopiaModuleGetPrivate(void* pModule, void** ppPrivate)
384 {
385 	*ppPrivate = shmid2va(TO_MODULE_PTR(pModule)->shmid_private.ID);
386 	return UTOPIA_STATUS_SUCCESS;
387 }
388 
UtopiaModuleRegister(void * pModuleTmp)389 MS_U32  UtopiaModuleRegister(void* pModuleTmp)
390 {
391 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
392 	UTOPIA_MODULE* pLocatedModule = NULL;
393 
394 	/* check para. */
395 	if (pModule == NULL)
396 	{
397 		printf("module pointer can't be null\n");
398 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
399 	}
400 
401 	pLocatedModule = TO_MODULE_PTR(locate_module(pModule->u32ModuleID));
402 	if (pLocatedModule == NULL) /* module is not yet registered */
403 	{
404 		/* insert module into list head */
405 		PRINT_INFO("register module: %s\n", moduleNames[pModule->u32ModuleID]);
406 		pModule->psNext = psUtopiaPrivate->psModuleHead;
407 		psUtopiaPrivate->psModuleHead = pModule;
408 		return UTOPIA_STATUS_SUCCESS;
409 	}
410 	else  /* module is already registered */
411     {
412         printf("error: register duplicated module: %s\n", moduleNames[pModule->u32ModuleID]);
413         RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
414     }
415 }
416 
UtopiaModuleSetupFunctionPtr(void * pModuleTmp,FUtopiaOpen fpOpen,FUtopiaClose fpClose,FUtopiaIOctl fpIoctl)417 MS_U32 UtopiaModuleSetupFunctionPtr(void* pModuleTmp, FUtopiaOpen fpOpen, FUtopiaClose fpClose, FUtopiaIOctl fpIoctl)
418 {
419 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
420 
421 	PRINT_INFO("setup function pointers of module %s\n", moduleNames[pModule->u32ModuleID]);
422 	pModule->fpOpen = fpOpen;
423 	pModule->fpClose = fpClose;
424 	pModule->fpIoctl = fpIoctl;
425 
426 	return UTOPIA_STATUS_SUCCESS;
427 }
428 
UtopiaModuleSetVersion(void * pModule,MS_U32 u32Version)429 MS_U32 UtopiaModuleSetVersion(void* pModule, MS_U32 u32Version)
430 {
431 	TO_MODULE_PTR(pModule)->u32Version = u32Version;
432 
433 	return UTOPIA_STATUS_SUCCESS;
434 }
435 
UtopiaModuleGetDebugLevel(void * pInstance,MS_U32 * pu32DebugLevel)436 MS_U32 UtopiaModuleGetDebugLevel(void* pInstance, MS_U32* pu32DebugLevel)
437 {
438 	*pu32DebugLevel = TO_INSTANCE_PTR(pInstance)->psModule->u32DeviceDebugLevel;
439 	return UTOPIA_STATUS_SUCCESS;
440 }
441 
UtopiaModuleGetPtr(MS_U32 u32ModuleID,void ** ppModule)442 MS_U32 UtopiaModuleGetPtr(MS_U32 u32ModuleID, void** ppModule)
443 {
444 	*ppModule = locate_module(u32ModuleID);
445 
446 	return UTOPIA_STATUS_SUCCESS;
447 }
448 //##########################
449 //## Module Functions End ##
450 //##########################
451 
452 //##############################
453 //## Resource Functions Start ##
454 //##############################
UtopiaResourceCreate(char * resourceName,MS_U32 u32PrivateSize,void ** ppResource)455 MS_U32 UtopiaResourceCreate(char* resourceName, MS_U32 u32PrivateSize, void** ppResource)
456 {
457 	MS_U32 u32RetShmID;
458 	UTOPIA_RESOURCE* pResource = NULL;
459 	char privateName[50]; // FIXME: potential bug
460 
461 	/* 1. create resource */
462 	PRINT_INFO("create resource %s\n", resourceName);
463 	pResource = shm_malloc(sizeof(UTOPIA_RESOURCE), resourceName, &(u32RetShmID));
464 	if (isFirstCreation(pResource, E_TYPE_RESOURCE))
465 	{
466 		pResource->shmid_self.ID = u32RetShmID;
467 		pResource->shmid_next_resource.ID = 0xFFFFFFFF;
468 	}
469 	*ppResource = pResource;
470 
471 	/* 2. create resource private */
472 	sprintf(privateName, "%s_PRI", resourceName); // FIXME: potential bug
473 	PRINT_INFO("create private %s of resource %s\n", privateName, resourceName);
474 	shm_malloc(u32PrivateSize, privateName, &(pResource->shmid_private.ID));
475 
476 	return UTOPIA_STATUS_SUCCESS;
477 }
478 
UtopiaResourceGetPrivate(void * pResource,void ** ppPrivate)479 MS_U32 UtopiaResourceGetPrivate(void* pResource, void** ppPrivate)
480 {
481 	*ppPrivate = shmid2va(TO_RESOURCE_PTR(pResource)->shmid_private.ID);
482 	return 0;
483 }
484 
485 // case 1: no resource pool -> create resource pool & attach resource to it. combine with case 2
486 // case 2: resource pool exists, but no mathcing resource pool -> create resource pool & attach resource to it. combine with case 1
487 // case 3: resource pool exists, and there's matching resource pool -> attach resource to it
UtopiaResourceRegister(void * pModuleTmp,void * pResourceTmp,MS_U32 u32RPoolID)488 MS_U32 UtopiaResourceRegister(void* pModuleTmp, void* pResourceTmp, MS_U32 u32RPoolID)
489 {
490     //lock(u32ResourcePoolsMutex)
491     //insert psResouce into psModuleNode->psResourcePoolHeads->psResourceHeads->psResource
492 
493 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
494 	UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(pResourceTmp);
495 	char rpoolName[50];
496 
497 	/* 1. deal with resource pool */
498 	UTOPIA_RESOURCE_POOL* pRPool = NULL;
499 	UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
500 	locate_resource_pool(pModule, u32RPoolID, &pRPool, &pRPoolPrev);
501 
502 	/* rpool semaphore has been created */
503 	if (pRPool != NULL && pRPool->u32ResourcesSemaphore != 0) // if rpool semaphore has been created
504 	{
505 		printf("%s has already created semaphroe for %s\n", moduleNames[pModule->u32ModuleID], pRPool->shmid_self.name);
506 		return UTOPIA_STATUS_FAIL;
507 	}
508 
509 	// case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
510 	// case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
511 	// case 3: at least one resource pool exists, and so is the located one --> *ppRPool != NULL & ppRPoolPrev doesn't matter
512 	if (pRPool == NULL) { // case 1 or 2
513 		MS_U32 u32RetRPoolShmID;
514 		MS_U32 u32ModuleID = pModule->u32ModuleID;
515 
516 		sprintf(rpoolName, "%s_%d", rpoolNames[u32ModuleID], (int)u32RPoolID);
517 		pRPool = shm_malloc(sizeof(UTOPIA_RESOURCE_POOL), rpoolName, &u32RetRPoolShmID);
518 		if (isFirstCreation(pRPool, E_TYPE_RESOURCE_POOL))
519 		{
520 			pRPool->shmid_self.ID = u32RetRPoolShmID;
521 			strncpy(pRPool->shmid_self.name, rpoolName, sizeof(pRPool->shmid_self.name)); // FIXME: potential bug
522             if(!(0 == strcmp(pRPool->shmid_self.name, rpoolName)))
523             {
524                 printf("\033[35mFunction = %s, Line = %d, error, strncpy failed!!\033[m\n", __FUNCTION__, __LINE__);
525                 while(1);
526             }
527 			pRPool->u32PoolID = u32RPoolID;
528 			pRPool->shmid_next_rpool.ID = 0xFFFFFFFF;
529 			pRPool->shmid_resource_head.ID = 0xFFFFFFFF;
530 			pRPool->u32MutexID = MsOS_CreateMutex(E_MSOS_FIFO, rpoolName, MSOS_PROCESS_SHARED);
531 		}
532 		PRINT_INFO("create resource pool %s at %p\n", rpoolName, pRPool);
533 		/* check param. */
534 		if (pResource->shmid_rpool.ID != 0)
535 		{
536 			return UTOPIA_STATUS_SUCCESS;
537 		}
538 
539 		/* set up connection */
540 		if (pRPoolPrev == NULL) // case 1
541 		{
542 			pModule->psModuleShm->shmid_rpool_head.ID = u32RetRPoolShmID;
543 		}
544 		else /* case 2 */
545 		{
546 			pRPoolPrev->shmid_next_rpool.ID = u32RetRPoolShmID;
547 		}
548 
549 		pModule->psModuleShm->u32ResourcePoolTotal++;
550 	}
551 
552 	/* 2. deal with resource */
553 	pResource->shmid_rpool = pRPool->shmid_self;
554 
555 	UTOPIA_RESOURCE* pLocatedResource = NULL;
556 	UTOPIA_RESOURCE* pLocatedResourcePrev = NULL;
557 	locate_resource(pRPool, pResource->shmid_self.ID, &pLocatedResource, &pLocatedResourcePrev);
558 	// case 1: there's no resource in pool --> pLocatedResource = NULL, pLocatedResourcePrev = NULL
559 	// case 2: at least one resource exists, but not the located one --> pLocatedResource = NULL, pLocatedResourcePrev != NULL
560 	// case 3: at least one resource exists, and so is the located one --> pLocatedResource != NULL, pLocatedResourcePrev doesn't matter
561 	if (pLocatedResource == NULL) // case 1 or 2
562 	{
563 		PRINT_INFO("register resource into pool %s\n", rpoolName);
564 		if (pLocatedResourcePrev == NULL) // case 1
565 		{
566 			pRPool->shmid_resource_head.ID = pResource->shmid_self.ID;
567 		}
568 		else /* case 2 */
569 		{
570 			pLocatedResourcePrev->shmid_next_resource.ID = pResource->shmid_self.ID;
571 		}
572 		pRPool->u32ResourceTotal++;
573 
574 		return UTOPIA_STATUS_SUCCESS;
575 	}
576 	else /* case 3 */
577 	{
578 		/* duplicated registration: it may be registered by other process */
579 		return UTOPIA_STATUS_FAIL;
580 	}
581 }
582 
UtopiaResourceTryObtain(void * pModuleTmp,MS_U32 u32RPoolID,void ** ppResource)583 MS_U32 UtopiaResourceTryObtain(void* pModuleTmp, MS_U32 u32RPoolID, void** ppResource)
584 {
585     //Search and get one resource from psModuleNode->psResourcePoolHeads
586     //set flag bit0 to 1 for using
587 
588 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
589 	UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
590 	UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
591 	UTOPIA_RESOURCE* pAvailResource = NULL;
592 	locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
593 
594 	/* to avoid obtaining resource before UtopiaModuleAddResourceEnd() */
595 	//check_rpool_semaphore(pModule->u32ModuleID);
596 	if (!(pLocatedRPool->u32ResourceAvail))
597 		return UTOPIA_STATUS_FAIL;
598 	obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
599 
600 	pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
601 	MsOS_ObtainMutex(pLocatedRPool->u32MutexID, MSOS_WAIT_FOREVER);
602 	while (pAvailResource != NULL)
603 	{
604 		if (!(pAvailResource->bInUse))
605 		{
606 			pAvailResource->bInUse = true;
607 			*ppResource	= pAvailResource;
608 			pLocatedRPool->u32ResourceAvail--;
609 			MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
610 			return UTOPIA_STATUS_SUCCESS;
611 		}
612 		else
613 		{
614 			pAvailResource = next_resource(pAvailResource, E_TYPE_RESOURCE);
615 		}
616 	}
617 	MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
618 
619 	return UTOPIA_STATUS_FAIL;
620 }
621 
UtopiaResourceObtain(void * pModTmp,MS_U32 u32RPoolID,void ** ppResource)622 MS_U32 UtopiaResourceObtain(void* pModTmp, MS_U32 u32RPoolID, void** ppResource)
623 {
624     //Search and get one resource from psModuleNode->psResourcePoolHeads
625     //set flag bit0 to 1 for using
626 
627 	/* check param. */
628 	if (pModTmp == NULL)
629 	{
630 		printf("module pointer should not be null\n");
631 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
632 	}
633 	if (ppResource == NULL)
634 	{
635 		printf("resource ppointer should not be null\n");
636 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
637 	}
638 
639 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModTmp);
640 	UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
641 	UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
642 	UTOPIA_RESOURCE* pAvailResource = NULL;
643 	locate_resource_pool(pModule, u32RPoolID
644 			, &pLocatedRPool, &pLocatedRPoolPrev);
645 
646 	// to avoid obtaining resource before UtopiaModuleAddResourceEnd()
647 	PRINT_INFO("%s try to obtain %s semaphore\n", moduleNames[pModule->u32ModuleID], pLocatedRPool->shmid_self.name);
648 	//check_rpool_semaphore(pModule->u32ModuleID);
649 	obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
650 
651 	pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
652 	MsOS_ObtainMutex(pLocatedRPool->u32MutexID, MSOS_WAIT_FOREVER);
653 	while (pAvailResource != NULL)
654 	{
655 		if (!(pAvailResource->bInUse))
656 		{
657 			pAvailResource->bInUse = true;
658 			*ppResource	= pAvailResource;
659 			pLocatedRPool->u32ResourceAvail--;
660 			MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
661 			return UTOPIA_STATUS_SUCCESS;
662 		}
663 		else
664 		{
665 			pAvailResource = next_resource(pAvailResource, E_TYPE_RESOURCE);
666 		}
667 	}
668 	MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
669 
670 	return UTOPIA_STATUS_FAIL;
671 }
672 
UtopiaResourceRelease(void * pResource)673 MS_U32 UtopiaResourceRelease(void* pResource)
674 {
675 	UTOPIA_RESOURCE_POOL* pRPool = RESOURCE_PTR_TO_RPOOL_PTR(TO_RESOURCE_PTR(pResource));
676 
677 	// modify resource before releasing it, to avoid race condition
678 	MsOS_ObtainMutex(pRPool->u32MutexID, MSOS_WAIT_FOREVER);
679 	TO_RESOURCE_PTR(pResource)->bInUse = false;
680 	pRPool->u32ResourceAvail++;
681 	release_sem(pRPool->u32ResourcesSemaphore);
682 	MsOS_ReleaseMutex(pRPool->u32MutexID);
683 
684 	return UTOPIA_STATUS_SUCCESS;
685 }
686 
UtopiaModuleAddResourceStart(void * psModuleTmp,MS_U32 u32PoolID)687 MS_U32 UtopiaModuleAddResourceStart(void* psModuleTmp, MS_U32 u32PoolID)
688 {
689 	return UTOPIA_STATUS_SUCCESS;
690 }
691 
UtopiaModuleAddResourceEnd(void * pModuleTmp,MS_U32 u32RPoolID)692 MS_U32 UtopiaModuleAddResourceEnd(void* pModuleTmp, MS_U32 u32RPoolID)
693 {
694 	int u32SemaphoreID;
695     UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
696 
697     UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
698     UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
699     locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
700 
701     /* Check RPool Semaphore ID*/
702     if (pLocatedRPool->u32ResourcesSemaphore != 0 && pLocatedRPool->u32ResourcesSemaphore != 0xFFFFFFFF)
703     {
704         printf("semaphore id %d already exists\n", (int)pLocatedRPool->u32ResourcesSemaphore);
705         return UTOPIA_STATUS_FAIL;
706     }
707 
708     /* Create RPOOL Semaphore */
709     u32SemaphoreID = MsOS_CreateSemaphore(pLocatedRPool->u32ResourceTotal, E_MSOS_FIFO , "dont care");
710     if (u32SemaphoreID < 0)
711     {
712         printf("[utopia error] create semaphore fail\n");
713         RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
714     }
715 	pLocatedRPool->u32ResourceAvail = pLocatedRPool->u32ResourceTotal;
716 
717 	pLocatedRPool->u32ResourcesSemaphore = u32SemaphoreID;
718 	return UTOPIA_STATUS_SUCCESS;
719 }
720 //############################
721 //## Resource Functions End ##
722 //############################
723 
724 #if 0
725 
726  UTOPIA_HIBERNATE_HEADER* pHibernateHeaderStartVA=NULL;
727  UTOPIA_HIBERNATE_BLOCK* pHibernateBlockStartVA=NULL;
728  MS_U32 u32HibernateMaxBlock=0;
729  MS_U32 u32HibernateHeaderSizeTotal = 0;
730  MS_U32 u32HibernateBlockSizeTotal = 0;
731  MS_U32 u32HibernateCurrentBlkNum = 0;
732  MS_U32 u32HibernateCurrentFileNum = 0;
733  MS_BOOL bHibernateInit=false;
734 
735 
736 MS_U32 _serch_empyblock(void)
737 {
738     UTOPIA_HIBERNATE_BLOCK* pBlockVA = pHibernateBlockStartVA;
739 	MS_U32 ret = 0;
740 	MS_U32 u32Count=0;
741 	while(pBlockVA->u32NextBlock != 0x0 && u32Count <= u32HibernateMaxBlock )
742 	{
743 	   u32Count+=1;
744 	   pBlockVA = pHibernateBlockStartVA + sizeof(UTOPIA_HIBERNATE_BLOCK)*u32Count;
745 
746 	}
747 
748 	if(u32Count == u32HibernateMaxBlock)
749 		ret = u32HibernateMaxBlock;
750 
751     return ret;
752 }
753 
754 
755 void _EndOfFile(MS_U32 u32BlockNum)
756 {
757     UTOPIA_HIBERNATE_BLOCK* pBlockVA = pHibernateBlockStartVA+sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
758 	pBlockVA->u32NextBlock = END_OF_BLOCK_LINKLIST;
759 }
760 
761 
762 
763 MS_U32 UtopiaHibernateInit(MS_U8 u8MiuSel,MS_U32 pBAddrMem,MS_U32 u32size,MS_BOOL bFormat) //return: Sucessed
764 {
765 
766 
767 
768     if(MsOS_MPool_Mapping(u8MiuSel, pBAddrMem, u32size, 0) == false)
769     {
770         printf("[%s] MsOS_MPool_Mapping fail\n",__FUNCTION__);
771         return false;
772     }
773 
774 	u32HibernateHeaderSizeTotal = sizeof(UTOPIA_HIBERNATE_HEADER)*MAX_FILE_NUM;
775 
776 	if(u32HibernateHeaderSizeTotal>u32size)
777 	{
778 		    return UTOPIA_STATUS_FAIL;
779 	}
780 
781 
782 
783     u32HibernateBlockSizeTotal = u32size - u32HibernateHeaderSizeTotal;
784 	u32HibernateMaxBlock = u32HibernateBlockSizeTotal/BLOCK_SIZE;
785 
786     pHibernateHeaderStartVA = (void*)MsOS_MPool_PA2KSEG1(pBAddrMem);
787     pHibernateBlockStartVA = (void*)MsOS_MPool_PA2KSEG1(pBAddrMem+u32HibernateHeaderSizeTotal);
788 
789 	if(bFormat)
790     {
791        memset(pHibernateHeaderStartVA,u32size,0);
792     }
793 
794 	bHibernateInit=UTOPIA_STATUS_SUCCESS;
795 	return UTOPIA_STATUS_SUCCESS;
796 
797 
798 }
799 
800 
801 
802 MS_U32 UtopiaHibernateCreate(char* hibernateName)  //return: Sucessed
803 {
804      UTOPIA_HIBERNATE_HEADER* TEMPaa=pHibernateHeaderStartVA;
805 	 MS_U32 ret = UTOPIA_STATUS_FAIL;
806 	 MS_U32 u32CountTmp=0;
807 
808 	 if(pHibernateHeaderStartVA == NULL)
809         return ret;
810 
811 	 for(u32CountTmp =0;u32CountTmp<MAX_FILE_NUM;u32CountTmp++)
812 	 {
813 	    TEMPaa = TEMPaa + sizeof(UTOPIA_HIBERNATE_HEADER)*u32CountTmp;
814 	    if(TEMPaa->u32HibernateFileExist != 0x0)
815 	    {
816 	       if(strcmp(TEMPaa->HibernateName,hibernateName)==0)
817             ret =  UTOPIA_STATUS_SHM_EXIST ;
818 		    break;
819 	    }else
820 	    {
821 	       TEMPaa->u32HibernateFileExist=0x1;
822 		   strcpy(TEMPaa->HibernateName,hibernateName);
823 		   //TEMPaa->u32FirstBlock= _serch_empyblock();
824 		   u32HibernateCurrentFileNum = u32HibernateCurrentFileNum +1;
825 		   ret = UTOPIA_STATUS_SUCCESS ;
826 		   break;
827 	    }
828 	 }
829 
830 	 return ret;
831 
832 
833 }
834 
835 
836 MS_U32 UtopiaHibernateOpen(char* hibernateName)//return: ID
837 {  MS_U32 ret = -1;
838    UTOPIA_HIBERNATE_HEADER* TEMPaa=pHibernateHeaderStartVA;
839    MS_U32 u32CountTmp=0;
840 
841    if(pHibernateHeaderStartVA == NULL )
842         return ret;
843 
844    for(u32CountTmp =0;u32CountTmp<MAX_FILE_NUM;u32CountTmp++)
845 	 {
846 	    TEMPaa = TEMPaa + sizeof(UTOPIA_HIBERNATE_HEADER)*u32CountTmp;
847 	    if(TEMPaa->u32HibernateFileExist != 0x0)
848 	    {
849 	       if(strcmp(TEMPaa->HibernateName,hibernateName)==0)
850                 {
851                     TEMPaa->bUSE=1;
852                     ret = u32CountTmp;
853                 }
854 	    }else
855 	       break;
856 	 }
857 
858    return ret;
859 
860 
861 }
862 
863 
864 MS_U32 UtopiaHibernateWrite(MS_U32 FILEid, void* buff, MS_U32 size) //return: size
865 {
866     MS_U32 ret=0;
867 	UTOPIA_HIBERNATE_HEADER* TEMPaa = NULL;
868 	UTOPIA_HIBERNATE_BLOCK* TEMPBLKaa = NULL ;
869 	MS_U32 u32BlockNum=0;
870 	void* pTemBuff = buff;
871 	//MS_U32 u32NextBlockNum=0;
872 	//MS_U32 u32writeCount=size;
873 	//MS_U8 u8ArrayBlockContact[BLOCK_CONTACT_SIZE] = {0};
874 
875 	MS_U32 u32BlockNumOfFile = size/BLOCK_CONTACT_SIZE;
876 	MS_U32 u32RemanderOfFile = size%BLOCK_CONTACT_SIZE;
877 
878 	TEMPaa = pHibernateHeaderStartVA + sizeof(UTOPIA_HIBERNATE_HEADER)*FILEid;;
879 
880 	if(TEMPaa->bUSE ==0 || bHibernateInit == false || size==0)
881 		return ret;
882 
883 	if((u32HibernateMaxBlock-u32HibernateCurrentFileNum) < u32BlockNumOfFile)
884 		return ret;
885 
886 
887     TEMPaa->u32FirstBlock=_serch_empyblock();
888 	u32BlockNum = TEMPaa->u32FirstBlock;
889 
890 	TEMPBLKaa = pHibernateBlockStartVA+ sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
891 
892   //  u32BlockNum
893     while(u32BlockNumOfFile>0)
894     {
895        // u32BlockNum = _serch_empyblock();
896 		if(u32BlockNum>=u32HibernateMaxBlock)
897 			break;
898 		pTemBuff = (void*)((MS_U32)pTemBuff +ret);
899         memcpy((void*)TEMPBLKaa->u8File,pTemBuff,BLOCK_CONTACT_SIZE);
900 		_EndOfFile(u32BlockNum);
901         ret = ret+BLOCK_CONTACT_SIZE;
902 		u32BlockNumOfFile=u32BlockNumOfFile-1;
903 
904 		if(u32BlockNumOfFile==0)
905 			break;
906 
907 	    u32BlockNum = _serch_empyblock();
908 	    TEMPBLKaa->u32NextBlock = u32BlockNum;
909 	    TEMPBLKaa = pHibernateBlockStartVA+ sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
910 
911     }
912 
913 
914 
915 
916 
917 	if(u32RemanderOfFile > 0)
918 	{
919        u32BlockNum = _serch_empyblock();
920 	   TEMPBLKaa->u32NextBlock = u32BlockNum;
921 	   TEMPBLKaa = pHibernateBlockStartVA+ sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
922 
923 	   pTemBuff = (void*)((MS_U32)pTemBuff +ret);
924 	   memcpy((void*)TEMPBLKaa->u8File,pTemBuff,u32RemanderOfFile);
925 	   _EndOfFile(u32BlockNum);
926 	   ret+=u32RemanderOfFile;
927 	}
928 
929     return ret;
930 
931 }
932 
933 
934 MS_U32 UtopiaHibernateRead(MS_U32 FILEid,void* buff , MS_U32 size) ////return: size
935 {
936    MS_U32 ret=0;
937    UTOPIA_HIBERNATE_HEADER* TEMPaa = pHibernateHeaderStartVA + sizeof(UTOPIA_HIBERNATE_HEADER)*FILEid;
938    UTOPIA_HIBERNATE_BLOCK* TEMPBLKaa = NULL ;
939    //MS_U32 u32writeCount=size;
940    MS_U32 u32BlockNum=0;
941 
942    MS_U32 u32BlockNumOfFile = size/BLOCK_CONTACT_SIZE;
943    MS_U32 u32RemanderOfFile = size%BLOCK_CONTACT_SIZE;
944 
945    void* pTemBuff = buff;
946 
947 
948    if(TEMPaa->bUSE ==0)
949 		return ret;
950 
951    if(u32RemanderOfFile>0)
952       u32BlockNumOfFile = u32BlockNumOfFile + 1;
953 
954 
955    u32BlockNum = TEMPaa->u32FirstBlock;
956    TEMPBLKaa = pHibernateBlockStartVA+sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
957 
958    while((TEMPBLKaa->u32NextBlock != 0) && (u32BlockNumOfFile > 0))
959    {
960       if(TEMPBLKaa->u32NextBlock ==END_OF_BLOCK_LINKLIST )
961       {
962           pTemBuff = (void*)((MS_U32)pTemBuff +ret);
963 		  if(u32RemanderOfFile == 0)
964 		  {
965               memcpy(pTemBuff,(void*)TEMPBLKaa->u8File,BLOCK_CONTACT_SIZE);
966 			  ret = ret + BLOCK_CONTACT_SIZE;
967 		  }
968 		  else
969 		  {
970                     memcpy(pTemBuff,(void*)TEMPBLKaa->u8File,u32RemanderOfFile);
971 			  ret = ret + u32RemanderOfFile;
972 		  }
973 
974 		  u32BlockNumOfFile = u32BlockNumOfFile -1;
975 
976 
977 
978       }else
979       {
980           pTemBuff = (void*)((MS_U32)pTemBuff +ret);
981 		  memcpy(pTemBuff,(void*)TEMPBLKaa->u8File,BLOCK_CONTACT_SIZE);
982 	      ret = ret + BLOCK_CONTACT_SIZE;
983           u32BlockNumOfFile = u32BlockNumOfFile -1;
984           u32BlockNum = TEMPBLKaa->u32NextBlock;
985 		  TEMPBLKaa = pHibernateBlockStartVA+sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
986 
987         }
988    }
989 
990 
991 
992    return ret;
993 
994 
995 }
996 
997 #endif
998