Пример #1
0
static int load_pt_from_fixed_addr(u8 *buf, part_dev_t *dev)
{
    int reval = ERR_NO_EXIST;
    u64 pt_start; 
    u64 mpt_start; 
    int pt_size = PMT_REGION_SIZE; 
    int buffer_size = pt_size; 

    pt_start = g_emmc_size - PMT_REGION_OFFSET;
    mpt_start = pt_start + PMT_REGION_SIZE;

    printf("============func=%s===scan pmt from %llx=====\n", __func__, pt_start);
    /* try to find the pmt at fixed address, signature:0x50547631 */

    dev->read(dev, pt_start, (u8*)page_buf, buffer_size); 
    if (is_valid_pt(page_buf)) {
        if (!memcmp(page_buf + PT_SIG_SIZE, PMT_VER_V1, PMT_VER_SIZE)) {
            if (is_valid_pt(&page_buf[pt_size - PT_SIG_SIZE])) {
                printf("find pt at %llx\n", pt_start); 
                memcpy(buf, page_buf + PT_SIG_SIZE + PMT_VER_SIZE, PART_MAX_COUNT * sizeof(pt_resident));
                reval = DM_ERR_OK;
                return reval;
            } else {
                printf("invalid tail pt format\n");
                reval = ERR_NO_EXIST;
            }
        } else {
            printf("invalid pt version %s\n", page_buf + PT_SIG_SIZE);
            reval = ERR_NO_EXIST;
        }
    }

    
    dev->read(dev, mpt_start, (u8*)page_buf, buffer_size); 
    if (is_valid_mpt(page_buf)) { 
        if (!memcmp(page_buf + PT_SIG_SIZE, PMT_VER_V1, PMT_VER_SIZE)) {
            if (is_valid_mpt(&page_buf[pt_size - PT_SIG_SIZE])) {
                printf("find mpt at %llx\n", mpt_start); 
                memcpy(buf, page_buf + PT_SIG_SIZE + PMT_VER_SIZE, PART_MAX_COUNT * sizeof(pt_resident));
                reval = DM_ERR_OK;
                return reval;
            } else {
                printf("invalid tail mpt format\n");
                reval = ERR_NO_EXIST;
            }
        } else {
            printf("invalid mpt version %s\n", page_buf + PT_SIG_SIZE);
            reval = ERR_NO_EXIST;
        }
    }

	return reval;      
}
Пример #2
0
//int load_exist_part_tab(u8 *buf,struct mtd_info *mtd)
int load_exist_part_tab(u8 * buf)
{
    int pt_start_addr;
    int pt_cur_addr;
    int pt_locate;
    int reval = DM_ERR_OK;
    int mirror_address;

    //u8 pmt_spare[PT_SIG_SIZE];
    struct mtd_oob_ops ops_pt;
    struct mtd_info *mtd;
    mtd = &host->mtd;

    block_size = mtd->erasesize;    // devinfo.blocksize*1024;
    page_size = mtd->writesize; // devinfo.pagesize;
    pt_start_addr = (int)(mtd->size);
    //pt_start_addr=PT_LOCATION*block_size;
    printk(KERN_INFO "load_exist_part_tab %x\n", pt_start_addr);
    ops_pt.datbuf = (uint8_t *) page_buf;
    ops_pt.mode = MTD_OPS_AUTO_OOB;
    ops_pt.len = mtd->writesize;
    ops_pt.retlen = 0;
    ops_pt.ooblen = 16;
    ops_pt.oobretlen = 0;
    ops_pt.oobbuf = (page_buf + page_size);
    ops_pt.ooboffs = 0;

    printk(KERN_INFO "ops_pt.len %x \n", ops_pt.len);
    if (mtd->_read_oob == NULL)
    {
        printk(KERN_INFO "shoud not happpen \n");
    }
    for (pt_locate = 0; pt_locate < (block_size / page_size); pt_locate++)
    {
        pt_cur_addr = pt_start_addr + pt_locate * page_size;
        //memset(pmt_spare,0xFF,PT_SIG_SIZE);

        //printk (KERN_INFO "load_pt read pt %x \n",pt_cur_addr);

        if (mtd->_read_oob(mtd, (loff_t) pt_cur_addr, &ops_pt) != 0)
        {
            printk(KERN_INFO "load_pt read pt failded: %x\n", (u32) pt_cur_addr);
        }
#if 0
        {
            int i;
            for (i = 0; i < 8; i++)
            {
                printk(KERN_INFO "%x %x \n", *(page_buf + i), *(page_buf + 2048 + i));
            }

        }
#endif
        //memcpy(pmt_spare,&page_buf[LPAGE] ,PT_SIG_SIZE); //do not need skip bad block flag
        if (is_valid_pt(page_buf) && is_valid_pt(page_buf + mtd->writesize))
        {
            pi.sequencenumber = page_buf[PT_SIG_SIZE + page_size];
            printk(KERN_INFO "load_pt find valid pt at %x sq %x \n", pt_start_addr, pi.sequencenumber);
            break;
        } else
        {
            continue;
        }
    }
    //for test
    //pt_locate=(block_size/page_size);
    if (pt_locate == (block_size / page_size))
    {
        //first download or download is not compelte after erase or can not download last time
        printk(KERN_INFO "load_pt find pt failed \n");
        pi.pt_has_space = 0;    //or before download pt power lost

        if (!find_mirror_pt_from_bottom(&mirror_address, mtd))
        {
            printk(KERN_INFO "First time download \n");
            reval = ERR_NO_EXIST;
            return reval;
        } else
        {
            //used the last valid mirror pt, at lease one is valid.
            mtd->_read_oob(mtd, (loff_t) mirror_address, &ops_pt);
        }
    }
    memcpy(&lastest_part, &page_buf[PT_SIG_SIZE], sizeof(lastest_part));

    return reval;
}
Пример #3
0
int load_exist_part_tab(u8 *buf,part_dev_t *dev)
{
		#ifdef MTK_EMMC_SUPPORT
			int reval = ERR_NO_EXIST;
			int index = 0;
			int i,j;
			int len=0;
			char *buf_p;
			int pt_start = g_user_virt_addr + 1024;
			int mpt_start = pt_start + 2048;
		
		
			int PAGE_SIZE = 512;
			pt_resident* lp_pmt;
		
		
			printf("============func=%s===scan pmt from %x=====\n", __func__,pt_start);
			/* try to find the pmt at fixed address, signature:0x50547631 */
			for(i=0;i<CFG_EMMC_PMT_SIZE/4096;i++)
			{
				buf_p = page_buf;
			  	dev->read(dev,pt_start + i*4096,(u8*)page_buf,4096);
			  	for(j=0;j<4096/PAGE_SIZE;j++){
			  	
			//	printf("search %x %x\n",buf_p,pt_start + i*4096+j*PAGE_SIZE);
					if(is_valid_pt(buf_p)){
				
						printf("find h-pt at %x \n",pt_start + i*4096+j*PAGE_SIZE);
						if(j*PAGE_SIZE > 2048){
							len = 4096- j*PAGE_SIZE;
							printf("left %d j=%d\n",len,j);
							memcpy(backup_buf,&buf_p[PT_SIG_SIZE],len-PT_SIG_SIZE);
							dev->read(dev,pt_start + (i+1)*4096,(u8*)page_buf,2048);
							if(is_valid_pt(&page_buf[2048-4-len])){
								printf("find pt at %x \n",pt_start + i*4096+j*PAGE_SIZE);
								memcpy(&backup_buf[len-PT_SIG_SIZE],page_buf,sizeof(lastest_part)-len+PT_SIG_SIZE);
								memcpy(buf,backup_buf,sizeof(lastest_part));
								reval=DM_ERR_OK;
								goto find;//return reval;
							}
							
						}else{
							if(is_valid_pt(&buf_p[2048-4])){
								printf("find pt at %x \n",pt_start + i*4096+j*PAGE_SIZE);
								memcpy(buf,&buf_p[PT_SIG_SIZE],sizeof(lastest_part));
								reval=DM_ERR_OK;
								goto find;//return reval;
							}
						}
						break;
					}
				buf_p += PAGE_SIZE;
			  }
			}
			if(i == CFG_EMMC_PMT_SIZE/4096)
			{
				for(i=0;i<CFG_EMMC_PMT_SIZE/4096;i++){
				/* try to find the backup pmt at fixed address, signature:0x4d505431 */
				buf_p = page_buf;
				dev->read(dev,mpt_start + i*4096,(u8*)page_buf,4096);
				
				for(j=0;j<4096/PAGE_SIZE;j++){

					if(is_valid_mpt(buf_p)){
				
						printf("find h-pt at %x \n",mpt_start + i*4096+j*PAGE_SIZE);
						if(j*PAGE_SIZE > 2048){
							len = 4096- j*PAGE_SIZE;
							printf("left %d j=%d\n",len,j);
							memcpy(backup_buf,&buf_p[PT_SIG_SIZE],len-PT_SIG_SIZE);
							dev->read(dev,mpt_start + (i+1)*4096,(u8*)page_buf,2048);
							if(is_valid_mpt(&page_buf[2048-4-len])){
								printf("find mpt at %x \n",pt_start + i*4096+j*PAGE_SIZE);
								memcpy(&backup_buf[len-PT_SIG_SIZE],page_buf,sizeof(lastest_part)-len+PT_SIG_SIZE);
								memcpy(buf,backup_buf,sizeof(lastest_part));
								reval=DM_ERR_OK;
								goto find;//return reval;
							}
							
						}else{
							if(is_valid_mpt(&buf_p[2048-4])){
								printf("find mpt at %x \n",mpt_start + i*4096+j*PAGE_SIZE);
								memcpy(buf,&buf_p[PT_SIG_SIZE],sizeof(lastest_part));
								reval=DM_ERR_OK;
								goto find;//return reval;
							}
						}
						break;
					}
					buf_p += PAGE_SIZE;
				}
				}
				
				}
			if(i == CFG_EMMC_PMT_SIZE/4096)
				printf("find no pt or mpt\n");
			return reval;
		find:

		if(g_emmc_size<0x100000000){ //32bit
			printf("32bit parse PMT\n");
			memcpy(&lastest_part32,buf,PART_MAX_COUNT*sizeof(pt_resident32));
			
			memset(&lastest_part,0,PART_MAX_COUNT*sizeof(pt_resident));
			for(i=0;i<PART_MAX_COUNT;i++)
			{
				if(lastest_part32[i].size!=0){
					memcpy(lastest_part[i].name,lastest_part32[i].name,MAX_PARTITION_NAME_LEN);
					lastest_part[i].size= lastest_part32[i].size;
					lastest_part[i].offset= lastest_part32[i].offset;
					lastest_part[i].mask_flags= lastest_part32[i].mask_flags;
				}
			}
		}else{
			printf("64bit parse PMT, size pt = %d\n",sizeof(pt_resident));
		}

	return reval;
		
		
#else
	int pt_start_addr;
	int pt_cur_addr;
	int pt_locate;
	int reval=DM_ERR_OK;
	int mirror_address;
	char pmt_spare[PT_SIG_SIZE];

	block_size= devinfo.blocksize*1024;
	page_size = devinfo.pagesize;
	
	//page_buf = malloc(page_size);	 

	pt_start_addr = total_size;
	printf("load_pt from 0x%x \n",pt_start_addr);
	//pt_start_addr=PT_LOCATION*block_size;
	for(pt_locate=0;pt_locate<(block_size/page_size);pt_locate++)
	{
		pt_cur_addr = pt_start_addr+pt_locate*page_size;
		memset(pmt_spare,0xFF,PT_SIG_SIZE);

		if(!dev->read(dev,pt_cur_addr, page_buf,page_size))
		{
			printf ("load_pt read pt failded: %x\n",pt_cur_addr);
		}
             memcpy(&page_buf[page_size],g_kCMD.au1OOB,16);
		#if 0
		{
			int i;
			for(i=0;i<8;i++)
			{
				printf ("%x %x \n",page_buf[i],page_buf[2048+i]);
			}

		}
		#endif
		memcpy(pmt_spare,&page_buf[page_size] ,PT_SIG_SIZE); //skip bad block flag
		if(is_valid_pt(page_buf)&&is_valid_pt(pmt_spare))
		{
			pi.sequencenumber = page_buf[PT_SIG_SIZE+page_size];
			printf("load_pt find valid pt at %x sq %x \n",pt_start_addr,pi.sequencenumber);
			break;
		}
		else
		{
			continue;
		}
	}
	//for test 
	//pt_locate==(block_size/page_size);
	if(pt_locate==(block_size/page_size))
	{
		//first download or download is not compelte after erase or can not download last time
		printf ("load_pt find pt failed \n");
		pi.pt_has_space = 0; //or before download pt power lost
		
		if(!find_mirror_pt_from_bottom(&mirror_address,dev))
		{
			printf ("First time download \n");
			reval=ERR_NO_EXIST;
			return reval;
		}
		else
		{
			//used the last valid mirror pt, at lease one is valid.
			dev->read(dev,mirror_address, page_buf,page_size);
		}
	}
	memcpy(buf,&page_buf[PT_SIG_SIZE],sizeof(lastest_part));

	return reval;
#endif
}
/* int load_exist_part_tab(u8 *buf,struct mtd_info *mtd) */
int load_exist_part_tab(u8 *buf)
{
	u64 pt_start_addr;
	u64 pt_cur_addr;
	int pt_locate, i;
	int reval = DM_ERR_OK;
	u64 mirror_address;

	/* u8 pmt_spare[PT_SIG_SIZE]; */
	struct mtd_oob_ops ops_pt;
	struct mtd_info *mtd;

	mtd = &host->mtd;


	block_size = mtd->erasesize;	/* gn_devinfo.blocksize*1024; */
	page_size = mtd->writesize;	/* gn_devinfo.pagesize; */
	/* if(host->hw->nand_sec_shift == 10) //MLC */
	/* block_size = block_size >> 1; */
	pt_start_addr = (mtd->size);
	/* pt_start_addr=PT_LOCATION*block_size; */
	pr_debug("load_exist_part_tab %llx\n", pt_start_addr);
	ops_pt.datbuf = (uint8_t *) page_buf;
	ops_pt.mode = MTD_OPS_AUTO_OOB;
	ops_pt.len = mtd->writesize;
	ops_pt.retlen = 0;
	ops_pt.ooblen = 16;
	ops_pt.oobretlen = 0;
	ops_pt.oobbuf = (page_buf + page_size);
	ops_pt.ooboffs = 0;

	pr_debug("ops_pt.len %x\n", ops_pt.len);
	if (mtd->_read_oob == NULL)
		pr_debug("should not happpen\n");

	for (pt_locate = 0, i = 0; pt_locate < (block_size / page_size); pt_locate++) {
		pt_cur_addr = pt_start_addr + pt_locate * page_size;
		/* memset(pmt_spare,0xFF,PT_SIG_SIZE); */

		/* pr_err( (KERN_INFO "load_pt read pt %x\n",pt_cur_addr); */

		if (mtd->_read_oob(mtd, (loff_t) pt_cur_addr, &ops_pt) != 0)
			pr_debug("load_pt read pt failded: %llx\n", (u64) pt_cur_addr);

		/* memcpy(pmt_spare,&page_buf[LPAGE] ,PT_SIG_SIZE); //do not need skip bad block flag */
		if (is_valid_pt(page_buf) && is_valid_pt(page_buf + mtd->writesize)) {
			pi.sequencenumber = page_buf[PT_SIG_SIZE + page_size];
			pr_debug("load_pt find valid pt at %llx sq %x\n", pt_start_addr,
			       pi.sequencenumber);
			break;
		}
		continue;
	}
	/* for test */
	/* pt_locate=(block_size/page_size); */
	if (pt_locate == (block_size / page_size)) {
		/* first download or download is not compelte after erase or can not download last time */
		pr_debug("load_pt find pt failed\n");
		pi.pt_has_space = 0;	/* or before download pt power lost */

		if (!find_mirror_pt_from_bottom(&mirror_address, mtd)) {
			pr_debug("First time download\n");
			reval = ERR_NO_EXIST;
			return reval;
		}
		/* used the last valid mirror pt, at lease one is valid. */
		mtd->_read_oob(mtd, (loff_t) mirror_address, &ops_pt);
	}
	memcpy(&lastest_part, &page_buf[PT_SIG_SIZE], sizeof(lastest_part));

	return reval;
}
Пример #5
0
static int load_pt_from_fixed_addr(u8 * buf)
{
    int reval = ERR_NO_EXIST;
    u64 pt_start;
    u64 mpt_start;

    int pt_size = PMT_REGION_SIZE;

    pt_start = emmc_size - PMT_REGION_OFFSET - 0x600000;		
    mpt_start = pt_start + PMT_REGION_SIZE;

    printk(KERN_NOTICE "============func=%s===scan pmt from %llx=====\n", __func__,pt_start);

    reval = eMMC_rw_x(pt_start, (u32 *)pmt_buf, 0, 0, PMT_REGION_SIZE, 1, USER);
    if (reval) {
        printk(KERN_ERR "read pt error\n");
        goto try;
    }

    if (is_valid_pt(pmt_buf)) {
        if (!memcmp(pmt_buf + PT_SIG_SIZE, PMT_VER_V1, PMT_VER_SIZE)) {
            if (is_valid_pt(&pmt_buf[pt_size - PT_SIG_SIZE])) {
                memcpy(buf, pmt_buf + PT_SIG_SIZE + PMT_VER_SIZE, PART_MAX_COUNT * sizeof(pt_resident));
                reval = DM_ERR_OK;
                printk(KERN_NOTICE "find pt at %llx\n", pt_start);
                return reval;
            } else {
                reval = ERR_NO_EXIST;
                printk(KERN_ERR "invalid tail pt format\n");
            }
        } else {
            reval = ERR_NO_EXIST;
            printk(KERN_ERR "invalid pt version %s\n", pmt_buf + PT_SIG_SIZE);
        }
    }

try:
    reval = eMMC_rw_x(mpt_start, (u32 *)pmt_buf, 0, 0, PMT_REGION_SIZE, 1, USER);
    if (reval) {
        printk(KERN_ERR "read mpt error\n");
        reval = ERR_NO_EXIST;
        return reval;
    }

    if (is_valid_mpt(pmt_buf)) {
        if (!memcmp(pmt_buf + PT_SIG_SIZE, PMT_VER_V1, PMT_VER_SIZE)) {
            if (is_valid_mpt(&pmt_buf[pt_size - PT_SIG_SIZE])) {
                memcpy(buf, pmt_buf + PT_SIG_SIZE + PMT_VER_SIZE, PART_MAX_COUNT * sizeof(pt_resident));
                reval = DM_ERR_OK;
                printk(KERN_NOTICE "find mpt at %llx\n", mpt_start);
                return reval;
            } else {
                reval = ERR_NO_EXIST;
                printk(KERN_ERR "invalid tail mpt format\n");
            }
        } else {
            reval = ERR_NO_EXIST;
            printk(KERN_ERR "invalid mpt version %s\n", pmt_buf + PT_SIG_SIZE);
        }
    }

    return reval;
}

static int new_pmt(pt_resident *new_part, int table_size)
{
	int ret = -1;
	u64 mpt_addr = 0;
	char sig_buf[PT_SIG_SIZE];

    mpt_addr = emmc_size - PMT_REGION_OFFSET - 0x600000 + PMT_REGION_SIZE;

	pi.pt_changed = 1;
	pi.tool_or_sd_update = 2;
	pi.sequencenumber += 1;

	memset(pmt_buf, 0x00, PMT_REGION_SIZE);
	
	ret = eMMC_rw_x(mpt_addr, (u32 *)pmt_buf, 0, 1, PMT_REGION_SIZE, 1, USER);
	if (ret) {
        printk("clear mpt error\n");
		goto end;
	}
	
	*(int *)sig_buf = MPT_SIG;
	memcpy(pmt_buf, &sig_buf, PT_SIG_SIZE);
    memcpy(pmt_buf + PT_SIG_SIZE, PMT_VER_V1, PMT_VER_SIZE);
	memcpy(pmt_buf + PT_SIG_SIZE + PMT_VER_SIZE, &new_part[0], (table_size * sizeof(pt_resident)));
	memcpy(pmt_buf + PMT_REGION_SIZE - PT_SIG_SIZE - sizeof(pi), &pi, sizeof(pi));
	memcpy(pmt_buf + PMT_REGION_SIZE - PT_SIG_SIZE, &sig_buf, PT_SIG_SIZE);

	ret = eMMC_rw_x(mpt_addr,(u32 *)pmt_buf, 0, 1, PMT_REGION_SIZE, 1, USER);
    if(ret) {
		printk("write mpt error\n");
	}

end:
	return ret;
}
Пример #6
0
int load_exist_part_tab(u8 *buf,part_dev_t *dev)
{
#ifndef MTK_EMMC_SUPPORT
	u64 pt_start_addr;
	u64 pt_cur_addr;
	u64 pt_locate;
	int reval=DM_ERR_OK;
	u64 mirror_address;
	char pmt_spare[PT_SIG_SIZE];

	block_size= devinfo.blocksize*1024;
	page_size = devinfo.pagesize;
	
	//page_buf = malloc(page_size);	 

	pt_start_addr = total_size;
	printf("load_pt from 0x%x \n",pt_start_addr);
	//pt_start_addr=PT_LOCATION*block_size;
	for(pt_locate=0;pt_locate<(block_size/page_size);pt_locate++)
	{
		pt_cur_addr = pt_start_addr+pt_locate*page_size;
		memset(pmt_spare,0xFF,PT_SIG_SIZE);

		if(!dev->read(dev,pt_cur_addr, page_buf,page_size))
		{
			printf ("load_pt read pt failded: %x\n",pt_cur_addr);
		}
          	 memcpy(&page_buf[page_size],g_kCMD.au1OOB,16);

		memcpy(pmt_spare,&page_buf[page_size] ,PT_SIG_SIZE); //skip bad block flag
		if(is_valid_pt(page_buf)&&is_valid_pt(pmt_spare))
		{
			pi.sequencenumber = page_buf[PT_SIG_SIZE+page_size];
			printf("load_pt find valid pt at %x sq %x \n",pt_start_addr,pi.sequencenumber);
			break;
		}
		else
		{
			continue;
		}
	}
	//for test 
	//pt_locate==(block_size/page_size);
	if(pt_locate==(block_size/page_size))
	{
		//first download or download is not compelte after erase or can not download last time
		printf ("load_pt find pt failed \n");
		pi.pt_has_space = 0; //or before download pt power lost
		
		if(!find_mirror_pt_from_bottom(&mirror_address,dev))
		{
			printf ("First time download \n");
			reval=ERR_NO_EXIST;
			return reval;
		}
		else
		{
			//used the last valid mirror pt, at lease one is valid.
			dev->read(dev,mirror_address, page_buf,page_size);
		}
	}
	memcpy(buf,&page_buf[PT_SIG_SIZE],sizeof(lastest_part));

	return reval;
#endif
	return DM_ERR_OK; //should not happen
}
Пример #7
0
int load_exist_part_tab(u8 *buf)
{
#ifndef MTK_EMMC_SUPPORT
	int pt_start_addr;
	int pt_cur_addr;
	int pt_locate;
	int reval=DM_ERR_OK;
	int mirror_address;
	char pmt_spare[PT_SIG_SIZE];
	
	PAGE_SIZE = (u32) g_nand_chip.page_size;
	BLOCK_SIZE = (u32) g_nand_chip.erasesize;
	total_size = (int)(g_nand_chip.chipsize);
	
	pt_start_addr = total_size;

	MSG (INIT, "load_pt from %x\n",pt_start_addr);
	memset(&pi,0xFF,sizeof(pi));
	for(pt_locate=0;pt_locate<(BLOCK_SIZE/PAGE_SIZE);pt_locate++)
	{
		pt_cur_addr = pt_start_addr+pt_locate*PAGE_SIZE;
		memset(pmt_spare,0xFF,PT_SIG_SIZE);
		memset(g_nand_spare,0xFF,64);
		if(!mtk_nand_read_page_hwecc(pt_cur_addr, page_readbuf))
		{
			MSG (INIT, "load_pt read pt failded\n");
		}
		memcpy(pmt_spare,&g_nand_spare[1] ,PT_SIG_SIZE);
		if(is_valid_pt(page_readbuf)&&is_valid_pt(pmt_spare))
		{
			pi.sequencenumber = g_nand_spare[5];
			MSG (INIT, "load_pt find valid pt at %x sq %x \n",pt_start_addr,pi.sequencenumber);
			break;
		}
		else
		{
			continue;
		}
	}

	if(pt_locate==(BLOCK_SIZE/PAGE_SIZE))
	{
		//first download or download is not compelte after erase or can not download last time
		MSG (INIT, "load_pt find pt failed \n");
		pi.pt_has_space = 0; //or before download pt power lost
		
		if(!find_mirror_pt_from_bottom(&mirror_address))
		{
			MSG (INIT, "First time download \n");
			reval=ERR_NO_EXIST;
			return reval;
		}
		else
		{
			//used the last valid mirror pt, at lease one is valid.
			mtk_nand_read_page_hwecc(mirror_address, page_readbuf);
		}
	}
	memcpy(buf,&page_readbuf[PT_SIG_SIZE],sizeof(lastest_part));

	return reval;
#endif
}