/**************************************************************************
 * Handle Nand Flash Erase
 **************************************************************************/
u32 force_erase (DM_IMG_INFO * img_info, u32 pktsz)
{

    DM_TIME_BEGIN;
    // erase whole partition to keep data consistent
    {
        u32 erase_limit = 0;
        if (img_info->img_type == DM_IMG_TYPE_USRDATA)
        {
            erase_limit = g_nand_chip.chipsize;
            //print ("%s : erase limit address (0x%x)\n", MOD,erase_limit);
            //print ("%s : user data partition ! erase 0x%x ~ 0x%x\n",  MOD, img_info->addr_off, g_nand_chip.chipsize);
            if (FALSE ==  g_boot_dev.dev_erase_data (img_info->addr_off, g_nand_chip.chipsize, g_nand_chip.chipsize - img_info->addr_off))
            {
                DM_ASSERT (0);
                dm_ctx.dm_status = DM_STATUS_ERR_ONGOING;
                dm_ctx.dm_err = DM_ERR_NAND_ER_FAIL;
            }
        }
        else
        {
            erase_limit = dm_ctx.img_info.addr_off + dm_ctx.part_range;
            //print ("%s : erase limit address (0x%x)\n", MOD, erase_limit);
            if (FALSE == g_boot_dev.dev_erase_data (img_info->addr_off, erase_limit, dm_ctx.part_range))
            {
                DM_ASSERT (0);
                dm_ctx.dm_status = DM_STATUS_ERR_ONGOING;
                dm_ctx.dm_err = DM_ERR_NAND_ER_FAIL;
            }
        }
    }
    DM_TIME_END_NAND_ERASE;
}
Example #2
0
void Objects::validate(Entity& ent)
{
  DM_ASSERT(ent.is_object(), "Must be object");
  Object& o = (Object&) ent;
  bool found = false;
  for (auto& obj : objs) {
    if (obj.get() == &o) found = true;
  }
  DM_ASSERT(found, "Object must be in object list");
}
Example #3
0
 void call(Args&&... args)
 {
 	if (this->enabled()) {
     DM_ASSERT(m_script != nullptr, "Script was null");
     m_script->call(this->func, std::forward<Args>(args)...);
   }
 }
u32 get_part_range (DM_IMG_TYPE img_type)
{
    part_t *part;
    blkdev_t *blkdev = blkdev_get(CFG_BOOT_DEV);
    u8 *name = get_part_name (img_type);

    DM_ASSERT (name);
    if (name == NULL)
        return 0;

    part = part_get(name);

    DM_ASSERT (part);

    return ((part->pgnum) * blkdev->blksz);
}
Example #5
0
 int intcall(Args&&... args)
 {
 	if (this->enabled()) {
     DM_ASSERT(m_script != nullptr, "Script was null");
     return m_script->retcall(this->func, std::forward<Args>(args)...);
   }
   return -1;
 }
/**************************************************************************
 *  Allocate Buffer
 **************************************************************************/
u8 * prepare_data_buf (void)
{
#if 1 //CFG_FPGA_PLATFORM
    dm_ctx.data_buf = (u8 *) 0xF00000;
#else
    dm_ctx.data_buf = (u8 *) dm_rx_buf;
#endif 
    if (dm_ctx.data_buf)
        return dm_ctx.data_buf;

    DM_ASSERT (dm_ctx.data_buf);

    {
        DM_ERRCODE_PACKET errp = { DM_ERROR_PKT_PATN, 0 };
        errp.err_code = DM_ERR_NOMEM;   //TODO
        mt_usbtty_putcn (DM_SZ_ERR_CODE_PKT, (u8 *) & errp, TRUE);
        return NULL;
    }
}
Example #7
0
osGLOBAL void	
dmGetRequirements(
                  dmRoot_t 	  		*dmRoot,
                  dmSwConfig_t			*swConfig,
                  dmMemoryRequirement_t		*memoryRequirement,
                  bit32 			*usecsPerTick,
                  bit32				*maxNumLocks)
{
  bit32               memoryReqCount = 0;
  bit32               max_expander = DM_MAX_EXPANDER_DEV; 
  char    *buffer;
  bit32   buffLen;
  bit32   lenRecv = 0;
  static char    tmpBuffer[DEFAULT_KEY_BUFFER_SIZE];
  char    *pLastUsedChar = agNULL;
  char    globalStr[]     = "Global";
  char    iniParmsStr[]   = "InitiatorParms";
  char    SwParmsStr[]    = "SWParms";    
   
  DM_DBG3(("dmGetRequirements: start\n"));
  /* sanity check */
  DM_ASSERT((agNULL != swConfig), "");
  DM_ASSERT((agNULL != memoryRequirement), "");
  DM_ASSERT((agNULL != usecsPerTick), "");
  DM_ASSERT((agNULL != maxNumLocks), ""); 
  
  /* memory requirement for dmRoot, CACHE memory */
  memoryRequirement->dmMemory[DM_ROOT_MEM_INDEX].singleElementLength = sizeof(dmIntRoot_t);
  memoryRequirement->dmMemory[DM_ROOT_MEM_INDEX].numElements = 1;
  memoryRequirement->dmMemory[DM_ROOT_MEM_INDEX].totalLength = 
      (memoryRequirement->dmMemory[DM_ROOT_MEM_INDEX].singleElementLength) * (memoryRequirement->dmMemory[DM_ROOT_MEM_INDEX].numElements);
  memoryRequirement->dmMemory[DM_ROOT_MEM_INDEX].alignment = 4;
  memoryRequirement->dmMemory[DM_ROOT_MEM_INDEX].type = DM_CACHED_MEM;
  memoryReqCount++;
  
  /* memory requirement for Port Context Links, CACHE memory */
  memoryRequirement->dmMemory[DM_PORT_MEM_INDEX].singleElementLength = sizeof(dmIntPortContext_t);
  memoryRequirement->dmMemory[DM_PORT_MEM_INDEX].numElements = DM_MAX_PORT_CONTEXT; 
  memoryRequirement->dmMemory[DM_PORT_MEM_INDEX].totalLength = 
      (memoryRequirement->dmMemory[DM_PORT_MEM_INDEX].singleElementLength) * (memoryRequirement->dmMemory[DM_PORT_MEM_INDEX].numElements);
  memoryRequirement->dmMemory[DM_PORT_MEM_INDEX].alignment = 4;
  memoryRequirement->dmMemory[DM_PORT_MEM_INDEX].type = DM_CACHED_MEM;
  memoryReqCount++;

  /* memory requirement for Device Links, CACHE memory */
  memoryRequirement->dmMemory[DM_DEVICE_MEM_INDEX].singleElementLength = sizeof(dmDeviceData_t);
  memoryRequirement->dmMemory[DM_DEVICE_MEM_INDEX].numElements = DM_MAX_DEV; 
  memoryRequirement->dmMemory[DM_DEVICE_MEM_INDEX].totalLength = 
      (memoryRequirement->dmMemory[DM_DEVICE_MEM_INDEX].singleElementLength) * (memoryRequirement->dmMemory[DM_DEVICE_MEM_INDEX].numElements);
  memoryRequirement->dmMemory[DM_DEVICE_MEM_INDEX].alignment = 4;
  memoryRequirement->dmMemory[DM_DEVICE_MEM_INDEX].type = DM_CACHED_MEM;
  memoryReqCount++;

  /* memory requirement for Expander Device Links, CACHE memory */
  /*
     Maximum number of expanders are configurable
     The default is DM_MAX_EXPANDER_DEV
  */
  buffer = tmpBuffer;
  buffLen = sizeof(tmpBuffer);
  
  dm_memset(buffer, 0, buffLen);
  lenRecv = 0;
  
  if ((tddmGetTransportParam(
                             dmRoot, 
                             globalStr,
                             iniParmsStr,
                             agNULL,
                             agNULL,
                             agNULL, 
                             agNULL, 
                             "MaxExpanders",
                             buffer, 
                             buffLen, 
                             &lenRecv
                             ) == DM_RC_SUCCESS) && (lenRecv != 0))
  {
    if (osti_strncmp(buffer, "0x", 2) == 0)
    { 
      max_expander = osti_strtoul (buffer, &pLastUsedChar, 0);
    }
    else
    {
      max_expander = osti_strtoul (buffer, &pLastUsedChar, 10);
    }
  }
  DM_DBG3(("dmGetRequirements: max_expander %d\n", max_expander));
  
  
  memoryRequirement->dmMemory[DM_EXPANDER_MEM_INDEX].singleElementLength = sizeof(dmExpander_t);
  memoryRequirement->dmMemory[DM_EXPANDER_MEM_INDEX].numElements = max_expander; 
  memoryRequirement->dmMemory[DM_EXPANDER_MEM_INDEX].totalLength = 
      (memoryRequirement->dmMemory[DM_EXPANDER_MEM_INDEX].singleElementLength) * (memoryRequirement->dmMemory[DM_EXPANDER_MEM_INDEX].numElements);
  memoryRequirement->dmMemory[DM_EXPANDER_MEM_INDEX].alignment = 4;
  memoryRequirement->dmMemory[DM_EXPANDER_MEM_INDEX].type = DM_CACHED_MEM;
  memoryReqCount++;

  /* memory requirement for SMP command Links, CACHE memory */
  memoryRequirement->dmMemory[DM_SMP_MEM_INDEX].singleElementLength = sizeof(dmSMPRequestBody_t);
  memoryRequirement->dmMemory[DM_SMP_MEM_INDEX].numElements = DM_MAX_SMP; 
  memoryRequirement->dmMemory[DM_SMP_MEM_INDEX].totalLength = 
      (memoryRequirement->dmMemory[DM_SMP_MEM_INDEX].singleElementLength) * (memoryRequirement->dmMemory[DM_SMP_MEM_INDEX].numElements);
  memoryRequirement->dmMemory[DM_SMP_MEM_INDEX].alignment = 4;
  memoryRequirement->dmMemory[DM_SMP_MEM_INDEX].type = DM_CACHED_MEM;
  memoryReqCount++;
  
  /* memory requirement for INDIRECT SMP command/response Links, DMA memory */
  memoryRequirement->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].singleElementLength = SMP_INDIRECT_PAYLOAD; /* 512 */
  memoryRequirement->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].numElements = DM_MAX_INDIRECT_SMP; 
  memoryRequirement->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].totalLength = 
      (memoryRequirement->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].singleElementLength) * (memoryRequirement->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].numElements);
  memoryRequirement->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].alignment = 4;
  memoryRequirement->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].type = DM_DMA_MEM;
  memoryReqCount++;
  
  
  /* set up memory requirement count */
  memoryRequirement->count = memoryReqCount;
  
  /* requirement for locks */
  *maxNumLocks = DM_MAX_LOCKS;   

  /* setup the time tick */  
  *usecsPerTick = DM_USECS_PER_TICK;


  /* set up the number of Expander device handles */
  swConfig->numDevHandles = DM_MAX_DEV;
  swConfig->itNexusTimeout = IT_NEXUS_TIMEOUT;   /* default is 2000 ms*/

  dm_memset(buffer, 0, buffLen);
  lenRecv = 0;
  
  if ((tddmGetTransportParam(
                             dmRoot, 
                             globalStr,
                             SwParmsStr,
                             agNULL,
                             agNULL,
                             agNULL, 
                             agNULL, 
                             "IT_NEXUS_TIMEOUT",
                             buffer, 
                             buffLen, 
                             &lenRecv
                             ) == DM_RC_SUCCESS) && (lenRecv != 0))
  {
    if (osti_strncmp(buffer, "0x", 2) == 0)
    { 
      swConfig->itNexusTimeout = osti_strtoul (buffer, &pLastUsedChar, 0);
    }
    else
    {
      swConfig->itNexusTimeout = osti_strtoul (buffer, &pLastUsedChar, 10);
    }
  }

  DM_DBG1(("dmGetRequirements: swConfig->itNexusTimeout 0x%X\n", swConfig->itNexusTimeout));
  
  DM_DBG3(("dmGetRequirements: memoryReqCount %d\n", memoryRequirement->count));

  return;
}	   				
Example #8
0
/*
  ??? processing swConfig
*/
osGLOBAL bit32	
dmInitialize(
             dmRoot_t			*dmRoot,
             agsaRoot_t                 *agRoot,
             dmMemoryRequirement_t	*memoryAllocated,
             dmSwConfig_t		*swConfig,
             bit32			usecsPerTick )
{
  dmIntRoot_t               *dmIntRoot;
  dmIntPortContext_t        *dmIntPortContext;
  dmDeviceData_t            *dmDevice;  
  dmExpander_t              *dmExpander;
  dmSMPRequestBody_t        *dmSMPRequest; 
  bit8                      *dmIndirectSMPRequest; 
  dmIntContext_t            *dmAllShared;
  bit32              i;
  bit32               max_expander = DM_MAX_EXPANDER_DEV; 
  char    *buffer;
  bit32   buffLen;
  bit32   lenRecv = 0;
  static char    tmpBuffer[DEFAULT_KEY_BUFFER_SIZE];
  char    *pLastUsedChar = agNULL;
  char    globalStr[]     = "Global";
  char    iniParmsStr[]   = "InitiatorParms";
  char    SwParmsStr[]    = "SWParms"; 
  
  DM_DBG3(("dmInitialize: start\n"));
  /* sanity check */  
  DM_ASSERT((agNULL != dmRoot), "");
  DM_ASSERT((agNULL != agRoot), "");
  DM_ASSERT((agNULL != memoryAllocated), "");
  DM_ASSERT((agNULL != swConfig), "");
  DM_ASSERT((DM_ROOT_MEM_INDEX < memoryAllocated->count), "");
  DM_ASSERT((DM_PORT_MEM_INDEX < memoryAllocated->count), "");
  DM_ASSERT((DM_DEVICE_MEM_INDEX < memoryAllocated->count), "");
  DM_ASSERT((DM_EXPANDER_MEM_INDEX < memoryAllocated->count), "");
  DM_ASSERT((DM_SMP_MEM_INDEX < memoryAllocated->count), "");  
  DM_ASSERT((DM_INDIRECT_SMP_MEM_INDEX < memoryAllocated->count), "");  

  /* Check the memory allocated */
  for ( i = 0; i < memoryAllocated->count; i ++ )
  {
    /* If memory allocatation failed  */
    if (memoryAllocated->dmMemory[i].singleElementLength &&
        memoryAllocated->dmMemory[i].numElements)
    {
      if ( (0 != memoryAllocated->dmMemory[i].numElements)
          && (0 == memoryAllocated->dmMemory[i].totalLength) )
      {
        /* return failure */
        DM_DBG1(("dmInitialize: Memory[%d]  singleElementLength = 0x%0x  numElements = 0x%x NOT allocated!!!\n",
          i,
          memoryAllocated->dmMemory[i].singleElementLength,
          memoryAllocated->dmMemory[i].numElements));
        return DM_RC_FAILURE;
      }
    }
  }
  
  /* DM's internal root */
  dmIntRoot  = (dmIntRoot_t *) (memoryAllocated->dmMemory[DM_ROOT_MEM_INDEX].virtPtr);
  dmRoot->dmData = (void *) dmIntRoot;
  
  dmAllShared = (dmIntContext_t *)&(dmIntRoot->dmAllShared);
  /**<  Initialize the TDM data part of the interrupt context */
  dmAllShared->dmRootOsData.dmRoot     = dmRoot;
  dmAllShared->dmRootOsData.dmAllShared   = (void *) dmAllShared;
  
  /* Port Contexts */
  dmIntPortContext = (dmIntPortContext_t *) (memoryAllocated->dmMemory[DM_PORT_MEM_INDEX].virtPtr);
  dmAllShared->PortContextMem = (dmIntPortContext_t *)dmIntPortContext;
  
  /* Devices */
  dmDevice = (dmDeviceData_t *) (memoryAllocated->dmMemory[DM_DEVICE_MEM_INDEX].virtPtr);
  dmAllShared->DeviceMem = (dmDeviceData_t *)dmDevice;
  
  /* Expanders */
  dmExpander = (dmExpander_t *) (memoryAllocated->dmMemory[DM_EXPANDER_MEM_INDEX].virtPtr);
  dmAllShared->ExpanderMem = (dmExpander_t *)dmExpander;
  
  /* SMP commands */
  dmSMPRequest = (dmSMPRequestBody_t *) (memoryAllocated->dmMemory[DM_SMP_MEM_INDEX].virtPtr);
  dmAllShared->SMPMem = (dmSMPRequestBody_t *)dmSMPRequest;

  /* DMAable SMP request/reponse pointed by dmSMPRequestBody_t */
  dmIndirectSMPRequest = (bit8 *) (memoryAllocated->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].virtPtr);
  dmAllShared->IndirectSMPMem = (bit8 *)dmIndirectSMPRequest;
  dmAllShared->IndirectSMPUpper32 = memoryAllocated->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].physAddrUpper;
  dmAllShared->IndirectSMPLower32 = memoryAllocated->dmMemory[DM_INDIRECT_SMP_MEM_INDEX].physAddrLower;
    
  dmAllShared->agRoot = agRoot;
  
     
  dmAllShared->usecsPerTick = usecsPerTick;	   
  dmAllShared->itNexusTimeout = IT_NEXUS_TIMEOUT;/*swConfig->itNexusTimeout;*/
  dmAllShared->MaxRetryDiscovery = DISCOVERY_RETRIES;
  dmAllShared->RateAdjust = 0;
  /**< initializes timers */
  dmInitTimers(dmRoot);

  /**< initializes port contexts */
  dmPortContextInit(dmRoot);
  
  /**< initializes devices */
  dmDeviceDataInit(dmRoot);
  
  /**< initializes expander devices */
  buffer = tmpBuffer;
  buffLen = sizeof(tmpBuffer);
  
  dm_memset(buffer, 0, buffLen);
  lenRecv = 0;
  
  if ((tddmGetTransportParam(
                             dmRoot, 
                             globalStr,
                             iniParmsStr,
                             agNULL,
                             agNULL,
                             agNULL, 
                             agNULL, 
                             "MaxExpanders",
                             buffer, 
                             buffLen, 
                             &lenRecv
                             ) == DM_RC_SUCCESS) && (lenRecv != 0))
  {
    if (osti_strncmp(buffer, "0x", 2) == 0)
    { 
      max_expander = osti_strtoul (buffer, &pLastUsedChar, 0);
    }
    else
    {
      max_expander = osti_strtoul (buffer, &pLastUsedChar, 10);
    }
  }  

  dm_memset(buffer, 0, buffLen);
  lenRecv = 0;
  
  if ((tddmGetTransportParam(
                             dmRoot, 
                             globalStr,
                             SwParmsStr,
                             agNULL,
                             agNULL,
                             agNULL, 
                             agNULL, 
                             "IT_NEXUS_TIMEOUT",
                             buffer, 
                             buffLen, 
                             &lenRecv
                             ) == DM_RC_SUCCESS) && (lenRecv != 0))
  {
    if (osti_strncmp(buffer, "0x", 2) == 0)
    { 
      dmAllShared->itNexusTimeout = osti_strtoul (buffer, &pLastUsedChar, 0);
    }
    else
    {
      dmAllShared->itNexusTimeout = osti_strtoul (buffer, &pLastUsedChar, 10);
    }
  }

  DM_DBG1(("dmAllShared->itNexusTimeout %d \n", dmAllShared->itNexusTimeout)); 

  dm_memset(buffer, 0, buffLen);
  lenRecv = 0;
  
  if ((tddmGetTransportParam(
                             dmRoot, 
                             globalStr,
                             SwParmsStr,
                             agNULL,
                             agNULL,
                             agNULL, 
                             agNULL, 
                             "MaxRetryDiscovery",
                             buffer, 
                             buffLen, 
                             &lenRecv
                             ) == DM_RC_SUCCESS) && (lenRecv != 0))
  {
    if (osti_strncmp(buffer, "0x", 2) == 0)
    { 
      dmAllShared->MaxRetryDiscovery = osti_strtoul (buffer, &pLastUsedChar, 0);
    }
    else
    {
      dmAllShared->MaxRetryDiscovery = osti_strtoul (buffer, &pLastUsedChar, 10);
    }
  }

  DM_DBG1(("dmAllShared->MaxRetryDiscovery %d \n", dmAllShared->MaxRetryDiscovery)); 

  dm_memset(buffer, 0, buffLen);
  lenRecv = 0;
  if ((tddmGetTransportParam(
                             dmRoot, 
                             globalStr,
                             SwParmsStr,
                             agNULL,
                             agNULL,
                             agNULL, 
                             agNULL, 
                             "RateAdjust",
                             buffer, 
                             buffLen, 
                             &lenRecv
                             ) == DM_RC_SUCCESS) && (lenRecv != 0))
  {
    if (osti_strncmp(buffer, "0x", 2) == 0)
    { 
      dmAllShared->RateAdjust = osti_strtoul (buffer, &pLastUsedChar, 0);
    }
    else
    {
      dmAllShared->RateAdjust = osti_strtoul (buffer, &pLastUsedChar, 10);
    }
  }
  DM_DBG1(("dmAllShared->RateAdjust %d \n", dmAllShared->RateAdjust)); 

  dmExpanderDeviceDataInit(dmRoot, max_expander);
    
  /**< initializes SMP commands */
  dmSMPInit(dmRoot);

#ifdef DM_DEBUG
  gDMDebugLevel = swConfig->DMDebugLevel;
#endif
  return DM_RC_SUCCESS;
}
Example #9
0
	/// game ///
  auto& state() {
    DM_ASSERT(this->currentState != nullptr, "State must be initialized");
    return *this->currentState;
  }
Example #10
0
 // game inputs
 Inputs& inputs() noexcept {
   DM_ASSERT(current_inputs != nullptr, "Inputs must be initialized");
   return *current_inputs;
 }
Example #11
0
 // game camera
 Camera& camera() noexcept {
   DM_ASSERT(current_camera != nullptr, "Camera must be initialized");
   return *current_camera;
 }
Example #12
0
 // main protagonist
 Player& player() noexcept {
   DM_ASSERT(current_player != nullptr, "Player must be initialized");
   return *current_player;
 }
Example #13
0
 // current world
 World& world() noexcept {
   DM_ASSERT(current_world != nullptr, "World must be initialized");
   return *current_world;
 }
Example #14
0
	void create(int count, int speed = 4)
	{
    DM_ASSERT(count > 0, "Validate animation creation");
		this->anims.resize(count);
    this->frame_speed = speed;
	}
Example #15
0
 inline int frameCount(const int set, int d) {
   auto& anim = PANS.at(set)[d];
   DM_ASSERT(anim.size() > 0, "Animation needs frames");
   return anim.size();
 }
/**************************************************************************
 *  Check Image Information
 **************************************************************************/
u32 check_imgp (DM_IMAGE_INFO_PACKET * imgp, u32 * pktsz)
{
    print ("\n%s : ------------------ IMG ---------------\n", MOD);
    print ("%s : IMG fmt    = %s   \t type = %s\n", MOD, get_img_fmt (imgp->img_info.img_format),  get_img_type (imgp->img_info.img_type));
    print ("%s : IMG sz     = 0x%x \t addr = 0x%x\n", MOD,(imgp->img_info.img_size), (imgp->img_info.addr_off));
    print ("%s : addr       = 0x%x \t boundary = 0x%x\n", MOD, (imgp->img_info.addr_off), (imgp->img_info.addr_boundary));
    print ("%s : pkt sz     = 0x%x \n", MOD, (imgp->img_info.pkt_size));
    //print ("%s : --------------------------------------\n", MOD);
    print ("%s : IMG range  = 0x%x ~ 0x%x\n", MOD, (imgp->img_info.addr_off), (imgp->img_info.addr_off) + (imgp->img_info.img_size));
    //print ("%s : --------------------------------------\n", MOD);

    // image type is partition table inform
    if (DM_IMG_TYPE_PT_TABLE_INFORM == imgp->img_info.img_type)
    {
        print ("partition table inform\n");
        mt_usbtty_puts (DM_STR_START_REQ);
        handle_pt_cmd ();
        return;
    }
    
    // check image boundary  
    if (g_dl_safe_start_addr > imgp->img_info.addr_off)
    {
        print ("can't flash this image !\n");
        print ("current safe starting address for flashing (0x%x) > current image address (0x%x)\n", g_dl_safe_start_addr, imgp->img_info.addr_off);
        ASSERT (0);
    }

    DM_LOG ("%s : cur safe start addr for flashing (0x%x)\n", MOD, g_dl_safe_start_addr);
    g_dl_safe_start_addr = imgp->img_info.addr_off;

    if (imgp->pattern != DM_IMAGE_INFO_PKT_PATN)
    {
        DM_ASSERT (imgp->pattern == DM_IMAGE_INFO_PKT_PATN);
        dm_ctx.dm_status = DM_STATUS_ERR_ONGOING;
        dm_ctx.dm_err = DM_ERR_WRONG_SEQ;
    }
    // start address offset must be block alignment
    else if (imgp->img_info.addr_off % dm_ctx.block_size)
    {
        DM_ASSERT (imgp->img_info.addr_off % dm_ctx.block_size == 0);
        dm_ctx.dm_status = DM_STATUS_ERR_ONGOING;
        dm_ctx.dm_err = DM_ERR_WRONG_ADDR;
        *pktsz = save_imgp (imgp);
    }
    // packet size must be page size + spare size
    else if (imgp->img_info.pkt_size != dm_ctx.page_size + dm_ctx.spare_size)
    {
        DM_ASSERT (imgp->img_info.pkt_size == dm_ctx.page_size + dm_ctx.spare_size);
        dm_ctx.dm_status = DM_STATUS_ERR_ONGOING;
        dm_ctx.dm_err = DM_ERR_WRONG_PKT_SZ;
        *pktsz = save_imgp (imgp);
    }
    else
    {
        *pktsz = save_imgp (imgp);
         dm_ctx.dm_status = DM_STATUS_SECT_ONGING;
         DM_TIME_BEGIN;
         // erase whole partition to keep data consistent
         force_erase (&imgp->img_info, *pktsz);
         DM_TIME_END_NAND_ERASE;
    }

    return *pktsz;
}