/************************************************************************** * Handle Image **************************************************************************/ u32 handle_imgp (u32 * pktsz) { DM_EXT_IMAGE_INFO_PACKET ext_imgp; DM_IMAGE_INFO_PACKET imgp; memset(&ext_imgp, 0, sizeof(DM_EXT_IMAGE_INFO_PACKET)); memset(&imgp, 0, sizeof(DM_IMAGE_INFO_PACKET)); DM_ENTRY_LOG (); mt_usbtty_getcn (DM_SZ_EXT_IMG_INFO_PKT, (u8 *) & ext_imgp); fill_internal_imgp(&imgp , &ext_imgp); check_imgp (&imgp, pktsz); mt_usbtty_puts (DM_STR_START_REQ); return *pktsz; }
static bool usb_listen(struct bldr_comport *comport, uint8 *data, uint32 size, uint32 tmo_ms) { ulong start_time = get_timer(0); uint32 dsz; uint32 tmo_en = (tmo_ms) ? 1 : 0; uint8 *ptr = data; if (!size) return FALSE; while (1) { if (tool_is_present()) mt_usbtty_puts(HSHK_COM_READY); /* "READY" */ if (tmo_en && (get_timer(start_time) > tmo_ms)) return FALSE; if (!tmo_en) { /* kick watchdog to avoid cpu reset */ platform_wdt_all_kick(); } dsz = mt_usbtty_query_data_size(); if (dsz) { dsz = dsz < size ? dsz : size; mt_usbtty_getcn(dsz, (char*)ptr); #if CFG_USB_DOWNLOAD && !CFG_LEGACY_USB_DOWNLOAD if (*ptr == 0xa0) { print("%s sync time %dms\n", MOD, get_timer(start_time)); usbdl_handler(comport, 300); print("%s : ignore %d bytes garbage data\n", MOD, dsz); continue; /* ingore received data */ } #endif ptr += dsz; size -= dsz; } if (size == 0) break; udelay(20000); /* 20ms */ } print("%s sync time %dms\n", MOD, get_timer(start_time)); return TRUE; }
/************************************************************************** * Middle State **************************************************************************/ void handle_midle_state (u8 * buf) { DM_PKT_TYPE pkt_type; DM_EXT_IMAGE_INFO_PACKET *ext_imgp; DM_PATCH_CMD_PACKET *patch_cmd; DM_IMAGE_INFO_PACKET imgp; u32 pktsz = 0; part_t *part; u8 *name = NULL; DM_ENTRY_LOG (); memset(&imgp, 0, sizeof(DM_IMAGE_INFO_PACKET)); reset_dm_descriptor (); /* receive a little bit data, check if it is REBOOT */ mt_usbtty_getcn (DM_SZ_REBOOT_STR, buf); pkt_type = judge_pkt_type ((const void *) buf); if (pkt_type == DM_PKT_REBT) { dm_ctx.dm_status = DM_STATUS_REBOOT; return; } if (pkt_type == DM_PKT_AUTO) { print ("autoboot mode !!!\n"); dm_ctx.dm_status = DM_STATUS_ATBOOT; return; } if (pkt_type == DM_PKT_UPDT) { print ("update partition table\n"); dm_ctx.dm_status = DM_STATUS_UPDATE; return; } /* pcaket type is IMGP */ if (pkt_type == DM_PKT_IMGP) { //print ("\nCASE 2 : pcaket type is DM_PKT_IMGP\n"); mt_usbtty_getcn (DM_SZ_EXT_IMG_INFO_PKT - DM_SZ_REBOOT_STR, (u8 *) (buf + DM_SZ_REBOOT_STR)); ext_imgp = (DM_EXT_IMAGE_INFO_PACKET *) buf; fill_internal_imgp (&imgp , &(*ext_imgp)); check_imgp (&imgp, &pktsz); mt_usbtty_puts (DM_STR_START_REQ); } else { print ("\nCASE 3 : others\n"); if (pkt_type != DM_PKT_IMGP) { print ("pkt_type = 0x%x\n", pkt_type); } ASSERT (0); } return; }
/************************************************************************** * 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; }