diff chipsetsw/riviera/rvm/rvm_swe_hdlr.c @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/chipsetsw/riviera/rvm/rvm_swe_hdlr.c	Mon Jun 01 03:24:05 2015 +0000
@@ -0,0 +1,1251 @@
+/**
+ *                                                                          
+ *  @file	rvm_swe_hdlr.c                                              
+ *                                                                          
+ *  This file contains the functions related to SWEs management within RVM.
+ *
+ * @author	David Lamy-Charrier (d-lamy@ti.com)	
+ * @version	0.1
+ *
+ */
+
+/*
+ * Revision History:																			
+ *
+ * 10/26/2001	David Lamy-Charrier		Create for Riviera 1.6.
+ *																			
+ * (C) Copyright 2001 by Texas Instruments Incorporated, All Rights Reserved
+ */
+#include <stdio.h>
+#include "rvf/rvf_env.h"
+#include "rvm/rvm_gen.h"
+#include "rvm/rvm_api.h"
+#include "rvm/rvm_i.h"
+
+#include "rvf/rvf_i.h"			/* ET2 rvf private invocation API */
+#include "rvf/rvf_api.h"		/* A-M-E-N-D-E-D! */
+
+/* temporary inclusion for HCI pb on WINDOWS */
+/* TO DO: remove it. */
+#include "rvm/rvm_use_id_list.h"
+
+#include <string.h>
+
+extern T_RVM_CONST_SWE_INFO RVM_SWE_GET_INFO_ARRAY[];
+
+extern T_RVM_USE_ID * RVM_TYPE2_SWE_GROUPS[];
+
+extern BOOLEAN rvm_allocated_task_id [MAX_RVF_TASKS];
+
+extern T_RVM_KNOWN_SWE	* rvm_swe_array;
+
+
+/* private      */
+T_RVM_RETURN _fatal(T_RVM_PROCESSING_SWE* appli, UINT8 rm);
+
+/***********************************************************************
+* Function         _resolve_t2_grouping   (private)
+*
+* Description      resolves number of group directives & ret. group count
+*************************************************************************/
+UINT8 _resolve_t2_grouping(T_RVM_PROCESSING_SWE* appli, T_RVM_GROUP_DIRECTIVE* gd) {
+	T_RVM_INFO_SWE			swe_info;
+	T_RVM_PROCESSING_SWE*	cur_swe = appli;
+	UINT8 i=0, j=0, k=0;
+
+	for(; cur_swe != NULL;)	{
+		UINT8 swe_index = cur_swe->swe_id;
+
+		rvm_swe_array[swe_index].swe_get_info(&swe_info);
+
+		if (rvm_swe_array[swe_index].swe_state !=SWE_RUNNING && //== SWE_NOT_STARTED && 
+			swe_info.swe_type==RVM_SWE_TYPE_2) {
+
+			for(i=0; i<MAX_GRPS; i++) {
+				if(swe_info.type_info.type2.swe_group_directive == gd[i].group_directive) {
+					for(k=0; gd[i].hosted_swe_db_index[k]!=0; k++);
+					if(k<MAX_COMPOSITES) {
+						gd[i].hosted_swe_db_index[k]=swe_index;
+					} else {
+						/* TO DO ... ERROR !!! */
+					}
+//					RVM_TRACE_WARNING_PARAM("rvm.SweHndlr.resolve_t2_grouping(), appended to grp entry , nb=",\
+//											 (UINT32)swe_index);
+//printf("rvm.SweHndlr.resolve_t2_grouping(): appended %d to group: %d\n",gd[i].hosted_swe_db_index[k], gd[i].host_task_addr); 
+
+					break;
+				} else if(	swe_info.type_info.type2.swe_group_directive != gd[i].group_directive &&
+							gd[i].host_task_addr==0 ) {
+
+					/* Constraint! Expects all group priorites and stack sz to be equal 
+					 * Additional method must be used to set highest entity	pri. or resolve			*/
+					gd[i].host_task_addr=RVF_INVALID_ADDR_ID; //rvm_allocate_task_id(1);
+					gd[i].group_directive=swe_info.type_info.type2.swe_group_directive;	
+					gd[i].task_priority=swe_info.type_info.type2.priority;
+					gd[i].stack_size=swe_info.type_info.type2.stack_size;
+
+					gd[i].hosted_swe_db_index[0]=swe_index;
+					j++;
+//					RVM_TRACE_WARNING_PARAM("rvm.SweHndlr.resolve_t2_grouping(), created grp entry , nb=",\
+//											 (UINT32)swe_index);
+//printf("rvm.SweHndlr.resolve_t2_grouping(): created host group: %d AND append %d\n",gd[i].host_task_addr, gd[i].hosted_swe_db_index[0]); 
+					break;	
+				} 			
+			}
+
+		} else RVM_TRACE_WARNING_PARAM("rvm.SweHndlr.resolve_t2_grouping(), SWE Not type 2: ", rvm_swe_array[swe_index].swe_use_id); 
+		cur_swe = cur_swe->next_swe; /* process next SWE */
+	}
+//printf("rvm.SweHndlr.resolve_t2_grouping(): total group count: %d\n", j);
+
+//for(i=0; i<j; i++) /* de'bugger only!! */
+//	for(k=0; k<MAX_COMPOSITES && gd[i].hosted_swe_db_index[k]!=0; k++) 
+//		printf("host addr: %d, T2 swe_db_index %d\n",
+//		gd[i].host_task_addr, gd[i].hosted_swe_db_index[k]);
+
+	return j;
+}
+
+/*******************************************************************************
+** Function         rvm_allocate_task_id
+**
+** Description      Internal function which allocate the first available
+**					task id to a SWE in creation
+*******************************************************************************/
+T_RVM_TASK_ID rvm_allocate_task_id(UINT8 isRealTask) {
+/*	UINT8 i=0;	*/
+
+	/*	Find the 1st free task id
+		If we reach the max: all task ids are allocated => not possible to start SWE.*/
+	/* while (rvm_allocated_task_id[i] == TRUE)
+	{
+		i++;
+		if (i == MAX_RVF_TASKS)
+			return RVF_INVALID_TASK;
+	}*/
+
+	/* Lock task id and return its value. */
+	/* rvm_allocated_task_id[i] = TRUE; */
+	/* return ((T_RVM_TASK_ID) i); */
+	return (T_RVM_TASK_ID) rvf_allocate_task_id(isRealTask); /* A-M-E-N-D-E-D! */
+}
+
+
+/*******************************************************************************
+**
+** Function         rvm_set_swe_info
+**
+** Description      This function call the set_info function of each SWEs required 
+**					to start a specified SWE.
+**
+** Parameters:		T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters.
+**
+** Returns          T_RVM_RETURN: RVM_OK if successful.
+**
+*******************************************************************************/
+T_RVM_RETURN	rvm_set_swe_info(T_RVM_PROCESSING_SWE * appli)
+{	
+	T_RVM_PROCESSING_SWE * cur_swe = appli;
+	UINT8 i;
+	T_RVF_MB_ID	_bk_id_table[RVM_MAX_NB_MEM_BK];
+
+	/* for each SWE in the list */
+	while( cur_swe != NULL )
+	{
+		UINT8 swe_index = cur_swe->swe_id;
+
+		if (rvm_swe_array[swe_index].swe_state != SWE_RUNNING)
+			/* Call the set_info function for only those for which MB were just created	*/
+		{
+			/* First build return path	*/
+			T_RVM_INFO_SWE		swe_info;
+			T_RV_RETURN_PATH	return_path[RVM_MAX_NB_LINKED_SWE];
+			T_RVM_USE_ID		linked_swe_use_id[RVM_MAX_NB_LINKED_SWE];
+			UINT8				nb_linked_swe = 0;
+
+			rvm_swe_array[swe_index].swe_get_info(&swe_info);
+
+			switch( swe_info.swe_type)
+			{
+			case(RVM_SWE_TYPE_1):
+				{	nb_linked_swe = swe_info.type_info.type1.nb_linked_swe;
+					memcpy( linked_swe_use_id, swe_info.type_info.type1.linked_swe_id, RVM_MAX_NB_LINKED_SWE * sizeof(T_RVM_USE_ID) );
+					if(rvm_swe_array[swe_index].swe_state != SWE_NOT_STARTED) {
+						for(i=0;i<swe_info.type_info.type1.nb_mem_bank; i++) {
+							rvf_get_mb_id((char*)&swe_info.type_info.type1.mem_bank[i],
+							&_bk_id_table[i]);
+						}
+					}
+					break;
+				}
+			case(RVM_SWE_TYPE_2):
+				{	nb_linked_swe = swe_info.type_info.type2.nb_linked_swe;
+					memcpy( linked_swe_use_id, swe_info.type_info.type2.linked_swe_id, RVM_MAX_NB_LINKED_SWE * sizeof(T_RVM_USE_ID) );
+					if((rvm_swe_array[cur_swe->swe_id].swe_addr_id = rvm_allocate_task_id(0))==RVF_INVALID_ADDR_ID) {
+						return RVM_INTERNAL_ERR;
+					}
+					if(rvm_swe_array[swe_index].swe_state != SWE_NOT_STARTED) {
+						for(i=0;i<swe_info.type_info.type2.nb_mem_bank; i++) {
+							rvf_get_mb_id((char*)&swe_info.type_info.type2.mem_bank[i],
+							&_bk_id_table[i]);
+						}
+					}
+					break;
+				}
+			case(RVM_SWE_TYPE_3):
+				{	nb_linked_swe = swe_info.type_info.type3.nb_linked_swe;
+					memcpy( linked_swe_use_id, swe_info.type_info.type3.linked_swe_id, RVM_MAX_NB_LINKED_SWE * sizeof(T_RVM_USE_ID) );
+					if((rvm_swe_array[cur_swe->swe_id].swe_addr_id = rvm_allocate_task_id(1))==RVF_INVALID_ADDR_ID) {
+						return RVM_INTERNAL_ERR;
+					}
+					if(rvm_swe_array[swe_index].swe_state != SWE_NOT_STARTED) {
+						for(i=0;i<swe_info.type_info.type3.nb_mem_bank; i++) {
+							rvf_get_mb_id((char*)&swe_info.type_info.type3.mem_bank[i],
+							&_bk_id_table[i]);
+						}					
+					}
+					break;
+				}
+			case(RVM_SWE_TYPE_4):
+				{	nb_linked_swe = swe_info.type_info.type4.nb_linked_swe;
+					memcpy( linked_swe_use_id, swe_info.type_info.type4.linked_swe_id, RVM_MAX_NB_LINKED_SWE * sizeof(T_RVM_USE_ID) );
+					if((rvm_swe_array[cur_swe->swe_id].swe_addr_id = rvm_allocate_task_id(1))==RVF_INVALID_ADDR_ID) {
+						return RVM_INTERNAL_ERR;
+					}
+					if(rvm_swe_array[swe_index].swe_state != SWE_NOT_STARTED) {
+						for(i=0;i<swe_info.type_info.type4.nb_mem_bank; i++) {
+							rvf_get_mb_id((char*)&swe_info.type_info.type4.mem_bank[i],
+							&_bk_id_table[i]);
+						}					
+					}
+					break;
+				}
+			}
+			rvm_swe_array[cur_swe->swe_id].swe_return_path.addr_id=rvm_swe_array[cur_swe->swe_id].swe_addr_id;
+
+			for (i=0; i < nb_linked_swe; i++)
+			{
+				UINT8 linked_swe_index;
+				if (rvm_get_swe_index(&linked_swe_index, linked_swe_use_id[i]) != RVM_OK)
+				{
+					return RVM_INTERNAL_ERR;
+				}
+				return_path[i].callback_func	= rvm_swe_array[linked_swe_index].swe_return_path.callback_func;
+				/* TO DO: manage addr_id for GROUP_MEMBER SWEs */
+				return_path[i].addr_id			= rvm_swe_array[linked_swe_index].swe_addr_id;
+			}
+
+
+			if (cur_swe->rvm_functions.set_info != NULL ) {
+				if(rvm_swe_array[swe_index].swe_state == SWE_NOT_STARTED) {
+				cur_swe->rvm_functions.set_info(rvm_swe_array[cur_swe->swe_id].swe_addr_id, \
+												return_path, \
+												cur_swe->bk_id_table, \
+												rvm_error);
+				} else {
+					cur_swe->rvm_functions.set_info(rvm_swe_array[cur_swe->swe_id].swe_addr_id, \
+													return_path, \
+													_bk_id_table, \
+													rvm_error);
+				}
+			}
+		}
+
+		cur_swe = cur_swe->next_swe; /* process next SWE */
+	}
+	return RVM_OK;
+}
+
+
+/*******************************************************************************
+**
+** Function         rvm_initialize_swe
+**
+** Description      This function initialize all the required SWEs which are not running.
+**					It also creates the tasks in a suspend state.
+**					Then it resumes the tasks and call the start function of each SWE.
+**
+** Parameters:		T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters.
+**
+** Returns          T_RVM_RETURN: RVM_OK if successful.
+**
+*******************************************************************************/
+T_RVM_RETURN		rvm_initialize_swe( T_RVM_PROCESSING_SWE * appli,
+										T_RVM_GROUP_DIRECTIVE* gd, 
+										UINT8 t2cnt) {	
+	T_RVM_PROCESSING_SWE * cur_swe = appli;
+	UINT8 i=0, j=0;
+	UINT16 tuid=0;
+	T_RVF_BUFFER* stack_ptr=NULL;
+	T_RVM_INFO_SWE swe_info;
+
+#ifdef _WINDOWS
+	BOOLEAN hci_started = FALSE;
+#endif
+
+	/* for each SWE in the list, initialize it */
+	while( cur_swe != NULL )
+	{	
+		UINT8 swe_index = cur_swe->swe_id;
+
+		if ( rvm_swe_array[swe_index].swe_state != SWE_RUNNING)
+		{
+			/* call its init function */
+			if (cur_swe->rvm_functions.init)
+			{
+				if (cur_swe->rvm_functions.init() != RVM_OK)
+				{
+					rvf_send_trace("RVM: Error Calling init function of swe nb ", 43, \
+								(UINT32)swe_index, RV_TRACE_LEVEL_ERROR, RVM_USE_ID );
+				}
+			}
+		}
+		cur_swe = cur_swe->next_swe;
+	}
+
+
+	/* for each SWE in the list, create the task if necessary. */
+	cur_swe = appli;
+	while( cur_swe != NULL )
+	{
+		UINT8 swe_index = cur_swe->swe_id;
+
+		if ( rvm_swe_array[swe_index].swe_state != SWE_RUNNING)		{
+			/* start the task if necessary in SUSPEND mode */
+
+			if ( cur_swe->swe_type == RVM_SWE_TYPE_4) {
+				/* allocate a buffer for the stack */
+				if ( rvm_allocate_stack_buffer( cur_swe->stack_size,
+					 &rvm_swe_array[swe_index].stack_ptr) != RVM_OK) {
+
+					rvf_send_trace("RVM: Error allocating stack nb:", 28, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_ERROR, RVM_USE_ID);
+
+					/* TO DO: manage the error case */
+					return RVF_MEMORY_ERR;
+				}
+
+				/* start the task in suspend mode */
+				if (rvf_create_task((TASKPTR) cur_swe->rvm_functions.core, \
+									(UINT8)rvm_swe_array[swe_index].swe_addr_id,\
+									rvm_swe_array[swe_index].swe_name, \
+									rvm_swe_array[swe_index].stack_ptr, \
+									cur_swe->stack_size, \
+									cur_swe->priority, \
+									ET4_TASK,\
+									DEFAULT_TIME_SLICING, \
+									SUSPEND ) != RV_OK) {
+
+					rvf_send_trace("RVM: Error Creating Task nb:", 28, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_ERROR, RVM_USE_ID);
+				}
+
+				rvf_setRtAddrSweIndex(rvm_swe_array[swe_index].swe_addr_id, 
+									  swe_index);
+
+				rvf_send_trace("RVM: Created task nb ", 21, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID);
+
+			} else if (cur_swe->swe_type == RVM_SWE_TYPE_3) {
+				/* allocate a buffer for the stack */
+				if ( rvm_allocate_stack_buffer( cur_swe->stack_size,
+					 &rvm_swe_array[swe_index].stack_ptr) != RVM_OK) {
+
+					rvf_send_trace("RVM: Error allocating stack nb:", 28, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_ERROR, RVM_USE_ID);
+					/* TO DO: manage the error case */
+					return RVF_MEMORY_ERR;
+				}
+
+				/* start the task in suspend mode */
+				if (rvf_create_task((TASKPTR)rvm_t3_proxy, \
+									(UINT8)rvm_swe_array[swe_index].swe_addr_id,\
+									rvm_swe_array[swe_index].swe_name, \
+									rvm_swe_array[swe_index].stack_ptr, \
+									cur_swe->stack_size, \
+									cur_swe->priority, \
+									ET3_TASK,\
+									DEFAULT_TIME_SLICING, \
+									SUSPEND ) != RV_OK) {
+
+					rvf_send_trace("RVM: Error Creating E3 Task nb:", 28, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_ERROR, RVM_USE_ID);
+				}
+			
+				rvf_register_t3_handlers(rvm_swe_array[swe_index].swe_addr_id,
+										 cur_swe->rvm_functions.handle_message, /* traverse list hence: cur_swe->rvm_functions */
+										 cur_swe->rvm_functions.handle_timer );
+
+				rvf_setRtAddrSweIndex(rvm_swe_array[swe_index].swe_addr_id, 
+									  swe_index);
+
+				rvf_send_trace("RVM: Created task nb ", 21, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID);
+	
+			
+			}
+		}
+		cur_swe = cur_swe->next_swe; /* process next SWE */
+	} 
+	/* resolve T2 grouping			*/
+	for(i=0; i<t2cnt; i++) {
+		gd[i].host_task_addr=rvf_resolveHostingAddrId(gd[i]);
+		if( gd[i].host_task_addr==RVF_INVALID_ADDR_ID) {
+
+		if ( rvm_allocate_stack_buffer( gd[i].stack_size, &stack_ptr) != RVM_OK){
+			/* TO DO: manage the error case - ABORT & Clean-up if one or more linked Ent. fail */
+			//break;
+			return RVF_MEMORY_ERR;
+		} 
+
+			gd[i].host_task_addr=rvm_allocate_task_id(1);
+		rvf_create_task((TASKPTR)rvm_t2_proxy,
+						gd[i].host_task_addr, //
+						"hosting_task",
+						stack_ptr,
+						gd[i].stack_size,
+						gd[i].task_priority,
+						ET2_HOST_TASK,		
+						DEFAULT_TIME_SLICING,
+						SUSPEND);
+
+			rvf_associateGrpToHost(gd[i].host_task_addr, gd[i].group_directive);
+		}  
+
+		for(j=0; j<MAX_COMPOSITES && gd[i].hosted_swe_db_index[j]!=0; j++) {
+			/* create virtual task for each "hosted_swe_db_index[]" */
+			rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_get_info(&swe_info);
+
+			rvf_create_virtual_task(swe_info.type_info.type2.handle_message,
+									swe_info.type_info.type2.handle_timer,
+									rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_addr_id,
+									gd[i].host_task_addr,
+									rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_name,
+									rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_priority,
+									ET2_VTASK);
+			rvf_setRtAddrSweIndex(rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_addr_id, 
+								  gd[i].hosted_swe_db_index[j]);
+
+			/* register	each with associate host						     */
+			rvf_registerToHost( gd[i].host_task_addr, 
+								rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_addr_id);
+		}
+	
+	}
+
+	/* resume all hosting tasks...		*/
+	for(i=0; i<t2cnt; i++) rvf_resume_task((UINT8)gd[i].host_task_addr); 
+
+	/* start composites or virtual tasks   */
+	for(i=0; i<t2cnt; i++) {
+		rvm_start_group_req((UINT8)gd[i].host_task_addr, 
+		gd[i].hosted_swe_db_index);
+	}
+
+	/* for each SWE in the list, start it if necessary. */
+	for(cur_swe = appli; cur_swe != NULL; ) {	
+		UINT8 swe_index = cur_swe->swe_id;
+
+		if ( rvm_swe_array[swe_index].swe_state != SWE_RUNNING)	{
+			/* if the SWE is a task, resume it */
+			if ( (cur_swe->swe_type == RVM_SWE_TYPE_3)
+				|| (cur_swe->swe_type == RVM_SWE_TYPE_4) ) {
+
+				/* TO DO: check the return value */
+				if(rvf_resume_task((UINT8)rvm_swe_array[swe_index].swe_addr_id )!=RVF_OK) {
+					RVM_TRACE_WARNING("RVM: ERROR! UNABLE TO RESUME SWE");
+					return RVF_INTERNAL_ERR;
+				}
+				rvf_send_trace("RVM: Resumed task nb ", 21, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID);
+				rvf_send_trace("RVM: Resumed SWE ", 17, (UINT32)rvm_swe_array[swe_index].swe_use_id, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID);
+
+#ifdef _WINDOWS
+				if (rvm_swe_array[swe_index].swe_use_id ==  HCI_USE_ID ) {
+						hci_started = TRUE;
+				}
+#endif
+
+			} else if(cur_swe->swe_type==RVM_SWE_TYPE_1) {	/* A-M-E-N-D-E-D! */
+			
+				/* call its init function */
+				if (cur_swe->rvm_functions.start) {
+					if (cur_swe->rvm_functions.start() != RVM_OK) {
+						rvf_send_trace("RVM: Error Calling start function of swe nb ", 44, \
+									(UINT32)swe_index, RV_TRACE_LEVEL_ERROR, RVM_USE_ID);
+					}
+				}
+			}
+		}
+
+		/* increment the number of using swe and points to the using appli */
+		/* DOES NOT DEPEND ON THE STATE */
+		/*rvm_swe_array[swe_index].swe_get_info(&swe_info);
+		switch( swe_info.swe_type) {
+			case RVM_SWE_TYPE_1: 
+				if(!swe_info.type_info.type1.nb_linked_swe) rvm_swe_array[swe_index].nb_using_appli=0;
+			break;
+			case RVM_SWE_TYPE_2:
+				if(!swe_info.type_info.type2.nb_linked_swe) rvm_swe_array[swe_index].nb_using_appli=0;
+			break;
+			case RVM_SWE_TYPE_3:
+				if(!swe_info.type_info.type3.nb_linked_swe) rvm_swe_array[swe_index].nb_using_appli=0;
+			break;
+			case RVM_SWE_TYPE_4:
+				if(!swe_info.type_info.type4.nb_linked_swe) rvm_swe_array[swe_index].nb_using_appli=0;
+			break;
+			default: rvm_swe_array[swe_index].nb_using_appli=0;
+		}*/
+
+//		if(rvm_swe_array[swe_index].nb_using_appli) {
+//		rvm_swe_array[swe_index].using_appli[rvm_swe_array[swe_index].nb_using_appli++] = appli->swe_id;
+//
+//		}
+
+		if(rvm_swe_array[appli->swe_id].nb_using_appli<RVM_MAX_SWE_USING ) {
+			rvm_swe_array[appli->swe_id].using_appli[rvm_swe_array[appli->swe_id].nb_using_appli++]=swe_index;
+		} else {
+			RVM_TRACE_WARNING_PARAM("RVM: Unable to track 'Using Appli' list is full nb=", appli->swe_id);
+		}
+		
+		cur_swe = cur_swe->next_swe; /* process next SWE */
+	}
+
+	for(cur_swe=appli; cur_swe!=NULL; ) {
+		rvm_swe_array[cur_swe->swe_id].swe_state = SWE_RUNNING;
+		cur_swe = cur_swe->next_swe; 
+	}
+
+#ifdef _WINDOWS
+	if (hci_started == TRUE) {
+		rvf_delay(RVF_MS_TO_TICKS(1000));
+	}
+#endif
+
+	return RVM_OK;
+}
+
+
+/*******************************************************************************
+**
+** Function         rvm_stop_swe_list
+**
+** Description      This function will call the stop functions when possible.
+**
+** Parameters:		T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters.
+**
+** Returns          T_RVM_OK if all allocation are successful,
+**                  else T_RVM_INTERNAL_ERR (then some SWE are not stopped.
+**
+*******************************************************************************/
+T_RVM_RETURN rvm_stop_swe_list( T_RVM_PROCESSING_SWE * appli, T_RV_HDR* hdr)
+{	
+	T_RVM_PROCESSING_SWE * cur_swe = appli;
+	T_RVM_INFO_SWE swe_info;
+	volatile T_RVM_RETURN rvm_ret_value = RVM_OK;
+	T_RVM_STOP_MSG* p_msg=NULL;
+	UINT8 i=0;
+	
+
+	/* for each SWE in the list */
+	while (cur_swe != NULL )
+	{
+		UINT8 swe_index = cur_swe->swe_id;
+
+		/* If nb_using_appli > 1, SWE cannot be stopped	*/
+/*		if (rvm_swe_array[swe_index].nb_using_appli > 1) {
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+		// If nb_using_appli == 1 but using_appli != appli, SWE cannot be stopped 
+		if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \
+			(rvm_swe_array[swe_index].using_appli[0] != appli->swe_id))	{
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+*/
+		if (cur_swe->swe_type==RVM_SWE_TYPE_1) { //cater for de-init of lib
+			if(cur_swe->rvm_functions.stop1)cur_swe->rvm_functions.stop1();
+			if(cur_swe->rvm_functions.kill)cur_swe->rvm_functions.kill();
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+		if 	(cur_swe->swe_type==RVM_SWE_TYPE_4) { // etype 4 restriction
+			RVM_TRACE_WARNING_PARAM("RVM: Stop & Kill is not applicable to Type 4 entities, nb=", (UINT32)swe_index);
+			for (rvm_swe_array[swe_index].nb_using_appli=0,i=0; i<RVM_MAX_SWE_USING; i++) {  //reset using appli - workaround! 
+				rvm_swe_array[swe_index].using_appli[i] = RVM_INVALID_SWE_INDEX;
+			}
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+		/* Retrieve stop function with a get_info */
+		if (rvm_swe_array[swe_index].swe_get_info == NULL)
+		{
+			RVM_TRACE_WARNING_PARAM("RVM: SWE with no get info, cannot be stopped, nb=", (UINT32)swe_index);
+			cur_swe = cur_swe->next_swe;
+			rvm_ret_value = RVM_INTERNAL_ERR;
+			continue;
+		}
+		rvm_swe_array[swe_index].swe_get_info( &swe_info);
+
+		if (cur_swe->rvm_functions.stop == NULL) {
+			RVM_TRACE_WARNING_PARAM("RVM: SWE with no stop function, cannot be stopped, nb=", (UINT32)swe_index);
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+
+		if (rvf_get_buf( rvm_mem_bank, sizeof(T_RVM_STOP_MSG), (void **)&p_msg) == RVF_RED ) {
+			RVM_TRACE_WARNING_PARAM("RVM: Unable to create STOP msg, nb=", (UINT32)swe_index);
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+
+		p_msg->header.msg_id			= RVM_STOP_MSG;
+		p_msg->header.src_addr_id		= hdr->src_addr_id; 
+		p_msg->header.dest_addr_id		= hdr->dest_addr_id;
+//		p_msg->header.callback_func		= hdr->callback_func; 
+		p_msg->rp.callback_func			= ((T_RVM_STOP_MSG*)hdr)->rp.callback_func;
+		p_msg->status					= SWE_STOPPING;
+		p_msg->swe_num					= swe_index; //((T_RVM_STOP_MSG*)hdr)->swe_num;
+
+		if ( rvf_send_msg( rvm_swe_array[swe_index].swe_addr_id, p_msg) != RVF_OK)	{
+			rvm_ret_value = RVM_INTERNAL_ERR;
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+
+		rvm_swe_array[swe_index].swe_state=SWE_STOPPING;
+
+/*printf("SHUTDOWN: SWE %s nb %d USING APPLI= %d\n",rvm_swe_array[swe_index].swe_name, swe_index, rvm_swe_array[swe_index].nb_using_appli);
+for(i=0; i<rvm_swe_array[swe_index].nb_using_appli; i++)printf(" %d, ", rvm_swe_array[swe_index].using_appli[i]);
+printf("\n");*/
+
+		for (rvm_swe_array[swe_index].nb_using_appli=0,i=0; i<RVM_MAX_SWE_USING; i++) {  //reset using appli - workaround! 
+			rvm_swe_array[swe_index].using_appli[i] = RVM_INVALID_SWE_INDEX;
+		}
+
+/*printf("SHUTDOWN: SWE %s nb %d USING APPLI= %d\n",rvm_swe_array[swe_index].swe_name, swe_index, rvm_swe_array[swe_index].nb_using_appli);
+for(i=0; i<rvm_swe_array[swe_index].nb_using_appli; i++)printf(" %d, ", rvm_swe_array[swe_index].using_appli[i]);
+printf("\n");*/
+
+		/* Stop SWE - amended to ASYNC	*/
+		/* TO DO: for type 2 and 3 SWEs, send a message to the host to call the stop function */
+		//cur_swe->rvm_functions.stop(NULL);
+
+		/* Proceed to the next SWE	*/
+		cur_swe = cur_swe->next_swe;
+	}
+
+	return rvm_ret_value;
+}
+
+
+/*******************************************************************************
+**
+** Function         rvm_suspend_swe_tasks
+**
+** Description      This function will suspend all SWE that are tasks.
+**
+** Parameters:		T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters.
+**
+** Returns          T_RVM_OK if all allocation are successful,
+**                  else T_RVM_INTERNAL_ERR (then some SWE are not stopped.
+**
+*******************************************************************************/
+T_RVM_RETURN rvm_suspend_swe_tasks( T_RVM_PROCESSING_SWE * appli)
+{	
+	T_RVM_PROCESSING_SWE * cur_swe = appli;
+	T_RVM_INFO_SWE swe_info;
+	volatile T_RVM_RETURN rvm_ret_value = RVM_OK;
+	
+	/* for each SWE in the list */
+	while (cur_swe != NULL )
+	{
+		UINT8 swe_index = cur_swe->swe_id;
+
+		/* If nb_using_appli > 1, SWE cannot be stopped	*/
+		if (rvm_swe_array[swe_index].nb_using_appli > 1)
+		{
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+		/* If nb_using_appli == 1 but using_appli != appli, SWE cannot be stopped */
+		if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \
+			(rvm_swe_array[swe_index].using_appli[0] != appli->swe_id))
+		{
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+
+		/* Retrieve task info with a get_info */
+		if (rvm_swe_array[swe_index].swe_get_info == NULL)
+		{
+			RVM_TRACE_WARNING_PARAM("RVM: SWE with no get info, cannot be stopped, nb=", (UINT32)swe_index);
+			cur_swe = cur_swe->next_swe;
+			rvm_ret_value = RVM_INTERNAL_ERR;
+			continue;
+		}
+		rvm_swe_array[swe_index].swe_get_info( &swe_info);
+
+		/* If SWE is not a task, continue */
+		/* TO DO: manage group member SWEs */
+		if ( (swe_info.swe_type == RVM_SWE_TYPE_1) ||
+			 (swe_info.swe_type == RVM_SWE_TYPE_2) )
+		{
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+
+		/* Suspend SWE task	*/
+		rvf_suspend_task( (UINT8)rvm_swe_array[swe_index].swe_return_path.addr_id);
+		RVM_TRACE_DEBUG_LOW_PARAM("RVM: Suspended task nb ", (UINT32) (rvm_swe_array[swe_index].swe_return_path.addr_id & 0x000000FF) );
+
+		/* Proceed to the next SWE */
+		cur_swe = cur_swe->next_swe;
+	}
+
+	return rvm_ret_value;
+}
+
+
+/*******************************************************************************
+**
+** Function         rvm_kill_swe_list
+**
+** Description      This function will call the kill functions when possible.
+**                  It will also delete the task, the stack and the used MBs.
+**
+** Parameters:		T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters.
+**
+** Returns          T_RVM_OK if everything is successful,
+**                  else T_RVM_INTERNAL_ERR (then some SWE are not killed).
+**
+*******************************************************************************/
+T_RVM_RETURN rvm_kill_swe_list( T_RVM_PROCESSING_SWE * appli)
+{	
+	T_RVM_PROCESSING_SWE * cur_swe = appli;
+	T_RVM_INFO_SWE swe_info;
+	volatile T_RVM_RETURN rvm_ret_value = RVM_OK;
+	
+	/* for each SWE in the list */
+	while (cur_swe != NULL )
+	{
+		UINT8 swe_index = cur_swe->swe_id;
+
+		/* If nb_using_appli > 1, SWE cannot be killed */
+		if (rvm_swe_array[swe_index].nb_using_appli > 1)
+		{
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+
+		/* If nb_using_appli == 1 but using_appli != appli, SWE cannot be killed */
+		if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \
+			(rvm_swe_array[swe_index].using_appli[0] != appli->swe_id))
+		{
+			cur_swe = cur_swe->next_swe;
+			continue;
+		}
+
+		/* Retrieve kill function with a get_info */
+		if (rvm_swe_array[swe_index].swe_get_info == NULL)
+		{
+			RVM_TRACE_WARNING_PARAM("RVM: SWE with no get info, cannot be killed, nb=", (UINT32)swe_index);
+			cur_swe = cur_swe->next_swe;
+			rvm_ret_value = RVM_INTERNAL_ERR;
+			continue;
+		}
+		rvm_swe_array[swe_index].swe_get_info( &swe_info);
+
+		if (cur_swe->rvm_functions.kill == NULL)
+		{
+			RVM_TRACE_WARNING_PARAM("RVM: SWE with no kill function, cannot be killed, nb=", (UINT32)swe_index);
+			cur_swe = cur_swe->next_swe;
+			rvm_ret_value = RVM_INTERNAL_ERR;
+			continue;
+		}
+
+		/* Kill SWE	*/
+		cur_swe->rvm_functions.kill();
+		
+		/* TO DO: manage group member SWEs */
+		/* If the SWE is a task, the task should be deleted, as well as its stack */
+		if ( (swe_info.swe_type == RVM_SWE_TYPE_3) ||
+			 (swe_info.swe_type == RVM_SWE_TYPE_4) )
+		{
+			rvf_exit_task((UINT8)(rvm_swe_array[swe_index].swe_return_path.addr_id));
+ 			rvf_free_buf(rvm_swe_array[swe_index].stack_ptr);
+			RVM_TRACE_DEBUG_LOW_PARAM("RVM: Deleted task nb ", (UINT32)(rvm_swe_array[swe_index].swe_return_path.addr_id & 0x000000FF));
+			rvf_free_sys_resources(rvm_swe_array[swe_index].swe_addr_id, 2);
+
+		} else if(swe_info.swe_type == RVM_SWE_TYPE_2) {
+			rvf_free_sys_resources(rvm_swe_array[swe_index].swe_addr_id, 0);
+		}
+
+		/* Proceed to the next SWE	*/
+		cur_swe = cur_swe->next_swe;
+	}
+
+	return rvm_ret_value;
+}
+
+
+/*******************************************************************************
+**
+** Function         rvm_launch_appli
+**
+** Description      Called by the main RVM task to start a specified known application
+**
+** Parameters:		T_RVM_MSG msg: containing the return path and the index of the 
+**					application to start in the array of known SWEs.
+**
+** Returns          None
+**
+*******************************************************************************/
+void rvm_launch_appli( T_RVM_MSG * msg_Ptr) {
+	T_RVM_GROUP_DIRECTIVE GroupDirectives[MAX_GRPS]; 
+	UINT8 gdCount=0;
+	T_RVM_PROCESSING_SWE	* appli = NULL; /* pointer to the first element of the list */
+	T_RV_RETURN_PATH		appli_return_path;
+	UINT8	i,j=0;
+
+	for(i=0; i<MAX_GRPS; i++) {
+		GroupDirectives[i].group_directive=0;
+		GroupDirectives[i].host_task_addr=0;
+		GroupDirectives[i].stack_size=0;
+		memset(&GroupDirectives[i].hosted_swe_db_index, 0, (sizeof(UINT8)*MAX_COMPOSITES));
+	}
+
+	/* store the return path of the caller */
+	appli_return_path.callback_func	= msg_Ptr->rp.callback_func;
+	appli_return_path.addr_id		= msg_Ptr->header.src_addr_id;
+	
+	/* recursively call all get_info functions and build the list of running swe */	
+	if ( rvm_build_swe_list( &appli, msg_Ptr->swe_num, 0) != RVM_OK )
+	{	
+		/* Display error message
+		   error case: use the return_path to inform the caller that an error occurs*/
+		rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INVALID_PARAMETER, msg_Ptr->swe_num, appli_return_path);
+		RVM_TRACE_ERROR("RVM: SWE list built error");
+		return;
+	}
+
+	gdCount=_resolve_t2_grouping(appli, GroupDirectives);
+
+	if(!appli) {
+		// error case: use return_path to inform the caller about memory lack 
+		// Unlock state of SWE and free memory	
+		RVM_TRACE_WARNING_PARAM("RVM: ABORTED, Stand-alone ENTITY start request!", (UINT32)msg_Ptr->swe_num);
+		rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_NOT_READY, msg_Ptr->swe_num, appli_return_path);
+		rvm_delete_used_memory (appli);
+		return;
+	}
+
+	RVM_TRACE_DEBUG_HIGH("RVM: SWE list built success");
+	RVM_TRACE_DEBUG_HIGH_PARAM("RVM: trying to launch SWE", rvm_swe_array[appli->swe_id].swe_use_id);
+	
+	/* check if there is enough available memory */
+	if ( rvm_verify_memory_requirement( appli, GroupDirectives, gdCount) != RVM_OK)
+	{
+		/* error case: use return_path to inform the caller about memory lack */
+		/* Unlock state of SWE and free memory	*/
+		RVM_TRACE_WARNING_PARAM("RVM: SWE not enough memory: unable to launch Appli nb", (UINT32)appli->swe_id);
+		rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_MEMORY_ERR, msg_Ptr->swe_num, appli_return_path);
+		rvm_delete_used_memory (appli);
+		return;
+	}
+
+	/* allocates memory banks */
+	 if ( rvm_allocate_mb( appli) != RVM_OK )
+	 {	/* error case: use return_path to inform the caller about memory lack */
+		rvm_delete_used_memory (appli);
+		rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_MEMORY_ERR, msg_Ptr->swe_num, appli_return_path);
+		RVM_TRACE_WARNING("RVM: SWE memory bank allocation error - launch aborted!");
+		return;
+	 }
+	 RVM_TRACE_DEBUG_LOW("RVM: SWE memory bank allocation success");
+
+	/* call set_info function for each SWE */
+	 if ( rvm_set_swe_info( appli) != RVM_OK)
+	 {	/* error case: use return_path to inform the caller that an error occurs */
+		RVM_TRACE_WARNING("RVM: SWE set info functions error");
+		_fatal(appli, 0);
+		rvm_delete_created_mb(appli);
+		rvm_delete_used_memory (appli);
+		rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INTERNAL_ERR, msg_Ptr->swe_num, appli_return_path);
+		return;
+	 }
+	 RVM_TRACE_DEBUG_LOW("RVM: SWE set info functions called");
+
+
+	 /* call the init and start functions */
+	 if ( rvm_initialize_swe( appli, GroupDirectives, gdCount) != RVM_OK)
+	 {	/* error case: use return_path to inform the caller that an error occurs */
+		RVM_TRACE_WARNING("RVM: SWE initialization error");
+		rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INTERNAL_ERR, msg_Ptr->swe_num, appli_return_path);
+		_fatal(appli, 2);
+		rvm_delete_created_mb(appli);
+		rvm_delete_used_memory (appli);
+		return;
+	 }
+	 RVM_TRACE_DEBUG_LOW("RVM: SWE initialization success");
+
+	 /* build a message and send the response to the caller */
+	 /* send a result using the return_path */
+	 rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_OK, msg_Ptr->swe_num, appli_return_path);
+	
+
+	 /* and store the return_path */
+	 rvm_swe_array[ msg_Ptr->swe_num ].mmi_return_path.callback_func = msg_Ptr->rp.callback_func;
+	 rvm_swe_array[ msg_Ptr->swe_num ].mmi_return_path.addr_id = msg_Ptr->header.src_addr_id;
+	 	
+	 /* Once Everything is back in stand-by, release used memory */
+	 rvm_delete_used_memory (appli);
+}
+
+
+/*******************************************************************************
+**
+** Function         rvm_shut_down_appli
+**
+** Description      Called by the main RVM task to stop a specified known application
+**
+** Parameters:		T_RVM_MSG msg: containing the return path and the index of the 
+**					application to stop in the array of known SWEs.
+**
+** Returns          None
+**
+*******************************************************************************/
+void rvm_stop_appli( T_RVM_STOP_MSG* msg_Ptr) {
+	T_RVM_PROCESSING_SWE	* appli = NULL; /* pointer to the first element of the list */
+	T_RVM_RETURN		ret_value;
+	UINT8				swe_idx = 200;
+	T_RV_RETURN_PATH	appli_return_path;
+
+	appli_return_path.callback_func = msg_Ptr->rp.callback_func;
+	appli_return_path.addr_id		= msg_Ptr->header.src_addr_id;
+	
+
+	RVM_TRACE_DEBUG_HIGH_PARAM("RVM: trying to stop Appli nb ", (UINT32)swe_idx);
+	
+	if (rvm_swe_array[msg_Ptr->swe_num].nb_using_appli > 1) {
+		RVM_TRACE_WARNING_PARAM("RVM: SWE has dependencies, nb=", (UINT32)msg_Ptr->swe_num);
+		return;
+	}
+	// ??? If nb_using_appli == 1 but using_appli != appli, SWE cannot be stopped 
+	if ((rvm_swe_array[msg_Ptr->swe_num].nb_using_appli == 1) && \
+		(rvm_swe_array[msg_Ptr->swe_num].using_appli[0] != msg_Ptr->swe_num))	{
+		RVM_TRACE_WARNING_PARAM("RVM: SWE has dependencies, nb=", (UINT32)msg_Ptr->swe_num);
+		return;
+	}
+
+
+	/* TO DO : REBUILD SWE LIST !!!! */
+	if ( rvm_build_swe_list( &appli, msg_Ptr->swe_num, 1) != RVM_OK )
+	{	
+		/* Display error message
+		   error case: use the return_path to inform the caller that an error occurs*/
+		rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INVALID_PARAMETER, msg_Ptr->swe_num, appli_return_path);
+		RVM_TRACE_ERROR("RVM: SWE list built error");
+		return;
+	}
+
+	/* Stop all swe in the list that are used only once	*/
+	if ((ret_value = rvm_stop_swe_list(appli, (T_RV_HDR*)msg_Ptr)) != RVM_OK )
+	{
+		/* Display error message
+		   TO DO: error case: use the return_path to inform the caller that an error occurs	*/
+		RVM_TRACE_WARNING_PARAM("RVM: Error in SWE stop", (UINT32)ret_value);
+		return;
+	}
+
+	rvm_delete_used_memory (appli);
+
+	RVM_TRACE_DEBUG_LOW("RVM: SWE stop broadcast!");
+
+}
+
+// NOTE: presently no timeout exists, if the ENT. fails to reply 
+// to stop with rvm_swe_stopped() RVM doesn't kill it.
+void rvm_swe_has_stopped(T_RVM_STOP_MSG* msg) {
+	T_RVM_STOP_MSG* p_msg=(T_RVM_STOP_MSG*)msg;
+	T_RV_RETURN_PATH	appli_return_path;
+
+	appli_return_path.callback_func = msg->rp.callback_func;
+	appli_return_path.addr_id		= msg->header.src_addr_id;
+
+	if(msg->status!=SWE_STOPPING) {
+		// inform upper of problem
+		rvm_snd_msg_to_upper(RVM_STOP_APPLI, RVM_INVALID_PARAMETER, msg->swe_num, appli_return_path);
+		RVM_TRACE_ERROR("RVM: Entity declines STOP REQ");
+		rvf_free_msg((T_RV_HDR*)msg);
+		return;
+	}
+
+	// cont. with shutdown - MUST DO ERROR CASE !
+	rvm_shutdown_swe(p_msg->swe_num);
+
+	// set stopped status
+	rvm_swe_array[p_msg->swe_num].swe_state=SWE_KILLED; //SWE_STOPPING;
+
+	/* build a message and send the response to the caller */
+	/* send a result using the return_path */
+	if(rvm_get_mb_level(p_msg->swe_num) ){
+		rvm_snd_msg_to_upper(RVM_STOP_APPLI, RV_MEMORY_REMAINING, msg->swe_num, appli_return_path);
+	} else {
+		rvm_snd_msg_to_upper(RVM_STOP_APPLI, RVM_OK, msg->swe_num, appli_return_path);
+	}
+	
+	/* and store the return_path */
+	rvm_swe_array[ msg->swe_num ].mmi_return_path.callback_func = msg->rp.callback_func;
+	rvm_swe_array[ msg->swe_num ].mmi_return_path.addr_id		= msg->header.src_addr_id;
+
+}
+
+void rvm_shutdown_swe(UINT8 index) { //should ret. ok or fail
+	rvm_suspend_swe(index);
+	rvm_kill_swe(index);
+}
+
+void rvm_suspend_swe(UINT8 swe_index) {
+		volatile T_RVM_RETURN rvm_ret_value = RVM_OK;
+		T_RVM_INFO_SWE swe_info;
+
+		/* ??? If nb_using_appli > 1, SWE cannot be stopped	
+		if (rvm_swe_array[swe_index].nb_using_appli > 1) {
+			RVM_TRACE_WARNING_PARAM("RVM-SUSPEND: SWE has dependencies, nb=", (UINT32)swe_index);
+		}
+		// ??? If nb_using_appli == 1 but using_appli != appli, SWE cannot be stopped 
+		if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \
+			(rvm_swe_array[swe_index].using_appli[0] != swe_index))	{
+			RVM_TRACE_WARNING_PARAM("RVM-SUSPEND: SWE has dependencies, nb=", (UINT32)swe_index);
+		}*/
+
+		/* Retrieve task info with a get_info */
+		if (rvm_swe_array[swe_index].swe_get_info == NULL) {
+			RVM_TRACE_WARNING_PARAM("RVM: SWE with no get info, cannot be stopped, nb=", (UINT32)swe_index);
+			rvm_ret_value = RVM_INTERNAL_ERR;
+			return;
+		}
+		rvm_swe_array[swe_index].swe_get_info( &swe_info);
+
+		/* If SWE is not a task, continue */
+		/* TO DO: manage group member SWEs */
+		if ( (swe_info.swe_type == RVM_SWE_TYPE_1) ||
+			 (swe_info.swe_type == RVM_SWE_TYPE_2) ) {
+			return;
+		}
+	
+		/* Suspend SWE task	*/
+		rvf_suspend_task( (UINT8)rvm_swe_array[swe_index].swe_return_path.addr_id);
+		RVM_TRACE_DEBUG_LOW_PARAM("RVM: Suspended task nb ", (UINT32) (rvm_swe_array[swe_index].swe_return_path.addr_id & 0x000000FF) );
+}
+
+T_RVM_RETURN rvm_kill_swe(UINT8 swe_index) {
+		T_RVM_INFO_SWE swe_info;
+		volatile T_RVM_RETURN rvm_ret_value = RVM_OK;
+		UINT8 isVirtual=0;
+		T_RVF_G_ADDR_ID	gid=RVF_INVALID_ADDR_ID;
+		UINT8 isIdle=0;
+		UINT8 i=0;
+
+		/* If nb_using_appli > 1, SWE cannot be killed 
+		if (rvm_swe_array[swe_index].nb_using_appli > 1) return rvm_ret_value;
+
+		// If nb_using_appli == 1 but using_appli != appli, SWE cannot be killed 
+		if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \
+			(rvm_swe_array[swe_index].using_appli[0] != swe_index)) {
+			RVM_TRACE_WARNING_PARAM("RVM-KILL: SWE has dependencies, nb=", (UINT32)swe_index);
+			return rvm_ret_value;
+		}*/
+
+		/* Retrieve kill function with a get_info */
+		if (rvm_swe_array[swe_index].swe_get_info == NULL){
+			RVM_TRACE_WARNING_PARAM("RVM-KILL: SWE has no kill function defined, nb=", (UINT32)swe_index);
+			rvm_ret_value = RVM_INTERNAL_ERR;
+		}
+
+		rvm_swe_array[swe_index].swe_get_info(&swe_info);
+		switch( swe_info.swe_type) {
+			case RVM_SWE_TYPE_1: 
+//				if(swe_info.type_info.type1.kill) swe_info.type_info.type1.kill() ;
+				isVirtual=1;
+			break;
+			case RVM_SWE_TYPE_2:
+				gid=resolveHostAddrId(rvm_swe_array[swe_index].swe_addr_id);
+				rvf_unregisterFromHost(gid, rvm_swe_array[swe_index].swe_addr_id);
+				rvf_isHostingTaskIdle(gid, &isIdle);
+				if(isIdle) { 	// Defered suspend of hosting task: 
+					rvf_suspend_task(gid);
+					rvf_exit_task(gid);
+					rvf_free_sys_resources(gid, 2);
+				}
+				if(swe_info.type_info.type2.kill) swe_info.type_info.type2.kill();
+				isVirtual=1;
+			break;
+			case RVM_SWE_TYPE_3:
+				if(swe_info.type_info.type3.kill) swe_info.type_info.type3.kill();
+			break;
+			case RVM_SWE_TYPE_4:
+				if(swe_info.type_info.type4.kill) swe_info.type_info.type4.kill();
+			break;
+			default: 
+				RVM_TRACE_WARNING_PARAM("RVM: SWE with no kill function, cannot be killed, nb=", (UINT32)swe_index);
+		}
+
+		if(!isVirtual) {
+			rvf_exit_task((UINT8)(rvm_swe_array[swe_index].swe_return_path.addr_id));
+			rvf_free_buf(rvm_swe_array[swe_index].stack_ptr);
+			RVM_TRACE_DEBUG_LOW_PARAM("RVM: Deleted task nb ", (UINT32)(rvm_swe_array[swe_index].swe_return_path.addr_id & 0x000000FF));
+			rvf_free_sys_resources(rvm_swe_array[swe_index].swe_addr_id, 2);
+		} else {
+			rvf_free_sys_resources(rvm_swe_array[swe_index].swe_addr_id, 0);
+		}
+
+	return rvm_ret_value;
+}
+
+UINT8 rvm_get_mb_level(UINT8 swe_index) {
+	T_RVM_INFO_SWE swe_info;
+	INT8 i=0;
+	UINT8 isUsed=0;
+	
+	rvm_swe_array[swe_index].swe_get_info(&swe_info);
+		switch( swe_info.swe_type) {
+			case RVM_SWE_TYPE_1: 
+				if(swe_info.type_info.type1.nb_mem_bank!=0)
+					for(i=0; i<swe_info.type_info.type1.nb_mem_bank; i++) {
+						rvf_mb_is_used(swe_info.type_info.type1.mem_bank[i].bank_name, &isUsed);
+						if(isUsed)	return isUsed;
+					}
+			return isUsed;
+			case RVM_SWE_TYPE_2:
+				if(swe_info.type_info.type2.nb_mem_bank!=0)
+					for(i=0; i<swe_info.type_info.type2.nb_mem_bank; i++) {
+						rvf_mb_is_used(swe_info.type_info.type2.mem_bank[i].bank_name, &isUsed);
+						if(isUsed)	return isUsed;
+					}
+					return isUsed;
+			case RVM_SWE_TYPE_3:
+				if(swe_info.type_info.type3.nb_mem_bank!=0)
+					for(i=0; i<swe_info.type_info.type3.nb_mem_bank; i++) {
+						rvf_mb_is_used(swe_info.type_info.type3.mem_bank[i].bank_name, &isUsed);
+						if(isUsed)	return isUsed;
+					}
+			return isUsed;
+			case RVM_SWE_TYPE_4:
+				if(swe_info.type_info.type4.nb_mem_bank!=0)
+					for(i=0; i<swe_info.type_info.type4.nb_mem_bank; i++) {
+						rvf_mb_is_used(swe_info.type_info.type4.mem_bank[i].bank_name, &isUsed);
+						if(isUsed)	return isUsed;
+					}
+			return isUsed;
+			default: RVM_TRACE_DEBUG_LOW("RVM: Error rvm_get_mb_level()");
+			return isUsed;
+		}
+}
+
+void rvm_shut_down_appli( T_RVM_MSG * msg_Ptr) {
+	T_RVM_PROCESSING_SWE	* appli = NULL; /* pointer to the first element of the list */
+	T_RVM_RETURN		ret_value;
+	UINT8				swe_idx = 200;
+	T_RV_RETURN_PATH	appli_return_path;
+
+	
+	appli_return_path.callback_func = msg_Ptr->rp.callback_func;
+	appli_return_path.addr_id		= msg_Ptr->header.src_addr_id;
+
+
+	RVM_TRACE_DEBUG_HIGH_PARAM("RVM: trying to stop Appli nb ", (UINT32)swe_idx);
+	
+	/* TO DO : REBUILD SWE LIST !!!! */
+	if ( rvm_build_swe_list( &appli, msg_Ptr->swe_num, 1) != RVM_OK )
+	{	
+		/* Display error message
+		   error case: use the return_path to inform the caller that an error occurs*/
+		rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INVALID_PARAMETER, msg_Ptr->swe_num, appli_return_path);
+		RVM_TRACE_ERROR("RVM: SWE list built error");
+		return;
+	}
+
+	/* Stop all swe in the list that are used only once	*/
+	if ((ret_value = rvm_stop_swe_list(appli, (T_RV_HDR*)msg_Ptr)) != RVM_OK )
+	{
+		/* Display error message
+		   TO DO: error case: use the return_path to inform the caller that an error occurs	*/
+		RVM_TRACE_WARNING_PARAM("RVM: Error in SWE stop", (UINT32)ret_value);
+		return;
+	}
+	RVM_TRACE_DEBUG_LOW("RVM: SWE stop success");
+
+
+	/* Suspend all swe that are tasks */
+	if ((ret_value = rvm_suspend_swe_tasks(appli)) != RVM_OK )
+	{
+		/* Display error message
+		   TO DO: error case: use the return_path to inform the caller that an error occurs	*/
+		RVM_TRACE_WARNING_PARAM("RVM: Error in tasks suspension", (UINT32)ret_value);
+		return;
+	}
+	RVM_TRACE_DEBUG_LOW("RVM: SWE task supsended");
+
+	/* Kill all SWEs */
+	if ((ret_value = rvm_kill_swe_list(appli)) != RVM_OK)
+	{
+		/* Display error message
+		   TO DO: error case: use the return_path to inform the caller that an error occurs	*/
+		RVM_TRACE_WARNING_PARAM("RVM: Error in SWE killing", (UINT32)ret_value);
+		return;
+	}
+	RVM_TRACE_DEBUG_LOW("RVM: SWE kill success");
+
+	
+	/* Delete the swe Memory Banks */
+	rvm_delete_created_mb(appli);
+
+	/* Delete memory used and restore NOT_STARTED states */
+	if ((ret_value = rvm_clean_env(appli)) != RVM_OK)
+	{
+		/* Display error message
+		   TO DO: error case: use the return_path to inform the caller that an error occurs */
+		RVM_TRACE_WARNING_PARAM("RVM: Error in Memory cleaning", (UINT32)ret_value);
+		return;
+	}
+	RVM_TRACE_DEBUG_LOW("RVM: Memory cleaning success");
+
+
+	/* build a message and send the response to the caller */
+	/* send a result using the return_path */
+	rvm_snd_msg_to_upper(RVM_STOP_APPLI, RVM_OK, msg_Ptr->swe_num, appli_return_path);
+
+	
+	/* and store the return_path */
+	rvm_swe_array[ msg_Ptr->swe_num ].mmi_return_path.callback_func = msg_Ptr->rp.callback_func;
+	rvm_swe_array[ msg_Ptr->swe_num ].mmi_return_path.addr_id		= msg_Ptr->header.src_addr_id;
+}
+
+T_RVM_RETURN _fatal( T_RVM_PROCESSING_SWE * appli, UINT8 rm) {
+	T_RVM_PROCESSING_SWE * cur_swe =  NULL;
+//	T_RVM_INFO_SWE swe_info;
+	
+	RVM_TRACE_DEBUG_LOW("RVM: Fatality handler: reclaiming system resources!");
+	/* free all appli's system resources */
+	for (cur_swe = appli; cur_swe!=NULL; ) {
+		if(rvm_swe_array[cur_swe->swe_id].swe_state!=SWE_RUNNING)
+			rvf_free_sys_resources(rvm_swe_array[cur_swe->swe_id].swe_addr_id, rm);
+	}
+	
+
+	return RVM_OK;
+}
+
+/*******************************************************************************
+**
+** Function         rvm_generic_swe_core
+**
+** Description      This is the main task core used for GROUP_MEMBER SWEs hosting
+**					and for SINGLE SWEs.
+**
+** Parameters:		useless, may be for future evolutions if Nucleus really 
+**					supports it.
+**
+** Returns          None
+**
+*******************************************************************************/
+T_RVM_RETURN rvm_generic_swe_core(void)
+{
+   return RVM_OK;
+}