Exemple #1
0
static int write_env_area(char *env_buf)
{
#ifdef MTK_EMMC_SUPPORT
	int reval;
#endif
	int i,checksum = 0;


	memcpy(env_buf,ENV_SIG,sizeof(g_env.sig));
	memcpy(env_buf+CFG_ENV_SIG_1_OFFSET,ENV_SIG,sizeof(g_env.sig));

	for(i=0;i<(CFG_ENV_DATA_SIZE);i++){
		checksum += *(env_buf+CFG_ENV_DATA_OFFSET+i);
	}

	*((int *)env_buf+CFG_ENV_CHECKSUM_OFFSET/4) = checksum;

#ifdef MTK_EMMC_SUPPORT
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT 
    reval = eMMC_rw_x((loff_t)env_addr,(u32*)env_buf,0,1,CFG_ENV_SIZE,1,EMMC_PART_USER);
#else
    reval = eMMC_rw_x((loff_t)env_addr,(u32*)env_buf,0,1,CFG_ENV_SIZE,1,USER);
#endif
    if (reval) {
		return -EIO;
    }
#endif
	return 0;

}
Exemple #2
0
static int read_env_area(char *env_buf)
{
#ifdef MTK_EMMC_SUPPORT
	int reval;
#ifdef MTK_NEW_COMBO_EMMC_SUPPORT 
	reval = eMMC_rw_x((loff_t)env_addr,(u32*)env_buf,0,0,CFG_ENV_SIZE,1,EMMC_PART_USER);
#else
	reval = eMMC_rw_x((loff_t)env_addr,(u32*)env_buf,0,0,CFG_ENV_SIZE,1,USER);
#endif
 	if (reval) {
		return -EIO;
  	}
#endif
	return 0;
}
Exemple #3
0
static int pmt_region_write(struct pmt_region *region, void *buf)
{
    int err;

	err = eMMC_rw_x(region->base_addr, (unsigned int *)buf, 0, 1, region->size, 1, EMMC_PART_USER);
	if (err) {
        pmt_err("[%s]write %s error\n", __func__, region->name);
	}

    return err;
}
static int pmt_region_read(struct pmt_region *region, void *buf)
{
    int err;

    err = eMMC_rw_x(region->base_addr, (unsigned int *)buf, 0, 0, region->size, 1, USER);
    if (err) {
        pmt_err("[%s]read %s error\n", __func__, region->name);
    }
	//pmt_info("pmt_region_read 0x%x",(unsigned int *)buf);

    return err;
}
static int update_pmt(pt_resident *new_part, int table_size)
{
	int ret = -1;
	u64 pt_addr = 0;
	char sig_buf[PT_SIG_SIZE];
	
    pt_addr = emmc_size - PMT_REGION_OFFSET - 0x600000;

	if ((pi.pt_changed != 1) && (pi.pt_has_space == 1)) {
		printk("pt may be not update\n");
		return 0;
	}

	memset(pmt_buf, 0x00, PMT_REGION_SIZE);

	ret = eMMC_rw_x(pt_addr, (u32 *)pmt_buf, 0, 1, PMT_REGION_SIZE, 1, USER);
	if (ret) {
		printk("clear pt error\n");
		goto end;
	}
	
	*(int *)sig_buf = PT_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(pt_addr,(u32 *)pmt_buf, 0, 1, PMT_REGION_SIZE, 1, USER);
    if (ret) {
		printk("write pt error\n");
	}

end:
	return ret;
}
Exemple #6
0
static int __update_msdos_partition(int px, unsigned long long start, unsigned long long size)
{
    int err = 0;

	int i, slot; 
	int xbr_idx = 0;
	char *this_name = NULL;
	unsigned long long this_addr;

	unsigned char *buf = NULL;
	struct partition *p;
		
	buf = kzalloc(512, GFP_KERNEL);
	if (!buf) {
		err = -ENOMEM;
		pmt_err("update_msdos_partition: malloc buf fail\n");
		goto fail_malloc;
	}
	
	//find px in which mbr/ebr.
	for (i = 0;i < MBR_COUNT; i++) {
		for (slot = 0; slot < 4; slot++) {
			if (MBR_EBR_px[i].part_index[slot] == px) {
                /* this_name is mbr or ebrx */
				xbr_idx = i;
				this_name = MBR_EBR_px[i].part_name;  
                goto found;
			}
		}
	}

	if (slot >= 4) {
		pmt_err("p%d can not be found in mbr\n", px);
		err = -EINVAL;
		goto out;
	}

found:
	pmt_info("update %s\n", this_name);

    /* check mbr or ebrx partition info */
	for (i = 0; i < PART_NUM; i++) {
		if (!strcmp(this_name, PartInfo[i].name)) {
			this_addr = PartInfo[i].start_address;
			pmt_info("update %s addr %llx\n", this_name, this_addr);
			break;
		}
	}

	if (i == PART_NUM) {
		pmt_err("can not find %s\n", this_name);
		err = -EINVAL;
		goto out;
	} 

    /* read mbr or ebr into buf */
	err = eMMC_rw_x(this_addr, (u32*)buf, 0, 0, 512, 1, EMMC_PART_USER);
	if (err || !msdos_magic_present(buf + 510)) {
		pmt_err("read %s error\n", this_name);
        err = -EIO;
		goto out;
	}

	if (!msdos_magic_present(buf + 510)) {
		pmt_err("read MBR/EBR fail\n");
		err = -1;
		goto out;
	}

	p = (struct partition *) (buf + 0x1be);

	p[slot].start_sect = (unsigned int)((start - this_addr) / 512);
	p[slot].nr_sects = (unsigned int)(size / 512);

	err = eMMC_rw_x(this_addr, (u32*)buf, 0, 1, 512, 1, EMMC_PART_USER);
	if (err) {
		pmt_err("write %s error\n", this_name);
        err = -EIO;
		goto out;
	}

out:
	kfree(buf);
fail_malloc:
	return err;
}
static int update_MBR_or_EBR(int px, u64 start_addr, u64 length)
{
	int i,ret,j;
	int found_mbr = 0;
	loff_t update_addr = 0;
	int index_in_mbr = 0;
	int mbr_index = 0;
	char *change_pt_name = NULL;
	struct partition *p;
	u8 *page_buf = NULL;
	ret =0;
		
	page_buf = kmalloc(512, GFP_KERNEL);
	if (!page_buf) {
		ret = -ENOMEM;
		printk("update_MBR_or_EBR: malloc page_buf fail\n");
		goto fail_malloc;
	}
	//data -1MB
/*	for(i=0;i<PART_NUM;i++){
		if((PartInfo[i].partition_idx == px)&&((!strncmp(PartInfo[i].name,"usrdata",7))||(!strncmp(PartInfo[i].name,"sec_ro",6))||(!strncmp(PartInfo[i].name,"android",7))||(!strncmp(PartInfo[i].name,"cache",5)))){
			printk("update %s,need reduce 1MB in MBR\n",PartInfo[i].name);
			length -= 0x100000;
		}
	}*/
	
	
	//find px in which mbr/ebr.
	for(i=0;i<MBR_COUNT;i++){
		for(j=0;j<SLOT_PER_MBR;j++){
			if(MBR_EBR_px[i].part_index[j]==px){
				found_mbr = 1;
				change_pt_name = MBR_EBR_px[i].part_name;
				index_in_mbr = j;
				mbr_index = i;
			}
		}
	}
	if(found_mbr!=1){
		printk("p%d can not be found in mbr\n",px);
		ret = -1;
		goto end;
	}
	printk("update %s\n",change_pt_name);

	for(i=0; i<PART_NUM;i++){
		if(!strcmp(change_pt_name,PartInfo[i].name)){
			update_addr = PartInfo[i].start_address - MBR_START_ADDR;
			printk("update %s addr %llx\n",change_pt_name,update_addr);
			break;
		}
	}
	if(i==PART_MAX_COUNT){
		printk("can not find %s\n",change_pt_name);
		ret = -1;
		goto end;
	}
	ret = eMMC_rw_x(update_addr,(u32*)page_buf,0,0,512,1,USER);
	if(ret){
		printk("read %s error\n",change_pt_name);
		goto end;
	}
	if (!msdos_magic_present(page_buf + 510)) {
		printk("read MBR/EBR fail\n");
		ret = -1;
		goto end;
	}
	p = (struct partition *) (page_buf + 0x1be);

	for(i=0;i<4;i++){
		if(MBR_EBR_px[mbr_index].part_index[i]!=0){
			printk("p%d: %x %x\n",MBR_EBR_px[mbr_index].part_index[i],p[i].start_sect,p[i].nr_sects);
			if(i==index_in_mbr){
				printk("p%d: change to %x %x\n",MBR_EBR_px[mbr_index].part_index[i],(u32)((start_addr-update_addr)/512),(u32)(length/512));
				p[i].start_sect = (u32)((start_addr-update_addr)/512);
				p[i].nr_sects = (u32)(length/512);
			}
		}
	}

	ret = eMMC_rw_x(update_addr,(u32*)page_buf,0,1,512,1,USER);
	if(ret){
		printk("write %s error\n",change_pt_name);
		goto end;
	}
end:
	kfree(page_buf);
fail_malloc:
	return ret;
}
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;
}