#include "comdef.h"
#include "rextls.h"
#include "AEEBridle.h"

#if defined(AEE_SIMULATOR) && defined(_DEBUG)
#define BREAKPOINT()    _asm { int 3h }
#else
#define BREAKPOINT()    0
#endif /* if defined(AEE_SIMULATOR) && defined(_DEBUG) */

extern PFNSWIHANDLER g_bridle_SubSystems[];

#if __ARMCC_VERSION >= 120000 // ADS 1.2
#pragma arm section zidata = "bridle_util_zi"
#endif // __ARMCC_VERSION >= 120000 // ADS 1.2
static int gnInUserCallKey = 0;
#if __ARMCC_VERSION >= 120000 // ADS 1.2
#pragma arm section zidata
#endif // __ARMCC_VERSION >= 120000 // ADS 1.2

/*===========================================================================

FUNCTION   

DESCRIPTION
  
DEPENDENCIES

RETURN VALUE

SIDE EFFECTS

===========================================================================*/
int bridle_self_init(void *p)
{
   (void)p;
   return rex_tls_create(&gnInUserCallKey);
}

/*===========================================================================

FUNCTION   

DESCRIPTION
  
DEPENDENCIES

RETURN VALUE

SIDE EFFECTS

===========================================================================*/
boolean bridle_IsInUserCall(void)
{
   boolean *pbInUser = (boolean *)rex_tls_ptr(gnInUserCallKey);

   return *pbInUser;
}

/*===========================================================================

FUNCTION   

DESCRIPTION
  
DEPENDENCIES

RETURN VALUE

SIDE EFFECTS

===========================================================================*/
int bridle_CheckAccess(void *pBuf, int len, int aType, uint32 swinum)
{
#if !defined(AEE_SIMULATOR)
   return SUCCESS;
#else

   switch (aType) {
      case BRIDLE_WRITE_ACCESS:
         if(!IsBadWritePtr(pBuf, len))
            return SUCCESS;
         break;

      case BRIDLE_READ_ACCESS:
         if(!IsBadReadPtr(pBuf, len))
            return SUCCESS;
         break;

      case BRIDLE_READ_STRING_ACCESS:
         if(!IsBadReadPtr(pBuf, strlen(pBuf)+1))
            return SUCCESS;
         break;
   }

   BREAKPOINT();
	return EFAILED;
#endif // !defined(AEE_SIMULATOR)
}

/*===========================================================================

FUNCTION   

DESCRIPTION
  
DEPENDENCIES

RETURN VALUE

SIDE EFFECTS

===========================================================================*/
uint32 bridle_SystemCall(uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 swi_no)
{   
   int     subsys_no = BRIDLE_GET_SUBSYSNO(swi_no);
   uint32  uRet;
   boolean bInUserSave, *pbInUser;

   if (subsys_no < 0) {
      subsys_no = 0;
   }

   pbInUser = (boolean *)rex_tls_ptr(gnInUserCallKey);
   bInUserSave = *pbInUser;
   *pbInUser = FALSE;

   uRet = g_bridle_SubSystems[subsys_no](swi_no, arg1, arg2, arg3, arg4);

   *pbInUser = bInUserSave;

   return uRet;
}


/*===========================================================================

FUNCTION   

DESCRIPTION
  
DEPENDENCIES

RETURN VALUE

SIDE EFFECTS

===========================================================================*/
uint32 bridle_UserCall(uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, void (*fn)(void))
{
   uint32  uRet;
   boolean bInUserSave, *pbInUser;

   pbInUser = (boolean *)rex_tls_ptr(gnInUserCallKey);
   bInUserSave = *pbInUser;

   *pbInUser = TRUE;
   
   uRet = ((uint32 (*)(uint32,uint32,uint32,uint32))fn)(arg1, arg2, arg3, arg4);

   *pbInUser = bInUserSave;

   return uRet;
}

/*===========================================================================

FUNCTION   

DESCRIPTION
  
DEPENDENCIES

RETURN VALUE

SIDE EFFECTS

===========================================================================*/
boolean bridle_CheckMode(int mode)
{
   return (mode == BRIDLE_SVC_MODE);
}

/*===========================================================================

FUNCTION   

DESCRIPTION
  
DEPENDENCIES

RETURN VALUE

SIDE EFFECTS

===========================================================================*/
boolean bridle_IsEnabled(void)
{
   return FALSE;
}


