int mmc_berase(int dev_num, unsigned long start, unsigned blkcnt) { int err = 0; struct mmc *mmc = find_mmc_device(dev_num); // unsigned blk = 0, blk_r = 0; void* src = (void*)0x41000000; if (!mmc) return -1; memset(src, 0, 512*blkcnt); mmcinfo("erase blk %d ~ %d\n", start, start + blkcnt - 1); err = mmc_bwrite(dev_num, start, blkcnt, src); return err; /* if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size)) mmcdbg("\n\nCaution! Your devices Erase group is 0x%x\n" "The erase range would be change to 0x%x~0x%x\n\n", mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1), ((start + blkcnt + mmc->erase_grp_size) & ~(mmc->erase_grp_size - 1)) - 1); while (blk < blkcnt) { blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? mmc->erase_grp_size : (blkcnt - blk); err = mmc_erase_t(mmc, start + blk, blk_r); if (err) break; blk += blk_r; } return blk; */ }
int do_mmc_write (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int device_num = 1; ulong dev_id = 0; ulong addr,block_num,bytes,blk_cnt; ulong ret; if (argc < 4) { printf("Usage:\n%s\n", cmdtp->usage); return 1; } /*get device id*/ dev_id = simple_strtoul(argv[1], NULL, 16); if (dev_id == 0 || dev_id == 1 || dev_id == 2 || dev_id == 3)//add dev_id == 3 by eason 2012/3/27 device_num = dev_id; else { printf("dev_id Invalid\n"); return 1; } /*get memory address*/ addr = simple_strtoul (argv[2], NULL, 16); if (addr < 0) { printf("addr Invalid\n"); return 1; } /*get card block address*/ block_num = simple_strtoul (argv[3], NULL, 16); if (block_num < 0) { printf("block_num Invalid\n"); return 1; } /*get transfer size is bytes*/ bytes = simple_strtoul (argv[4], NULL, 16); if (bytes < 0) { printf("bytes Invalid\n"); return 1; } if (bytes == 0) return 0; /*calculate transfer block count*/ blk_cnt = (bytes / 512); if (bytes % 512) blk_cnt++; //printf("device_num = %x block_num = %x addr = %x bytes = %x blk_cnt =%x\n",device_num,block_num,addr,bytes,blk_cnt); ret = mmc_bwrite(device_num,block_num,blk_cnt,(ulong *)addr); if (ret != blk_cnt) { printf("Write Data Fail\n"); return 1; } else { printf("Write Data Success\n"); } return 0; }
/* update_mmc [dev no] <type> 'mem' 'addr' 'length' [load addr] */ int do_update_mmc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { block_dev_desc_t *desc; uint64_t dst_addr = 0, mem_len = 0; unsigned int mem_addr = 0; unsigned char *p; char cmd[32]; lbaint_t blk, cnt; int ret, dev; if (6 > argc) goto usage; ret = get_device("mmc", argv[1], &desc); if (0 > ret) { printf ("** Not find device mmc.%s **\n", argv[1]); return 1; } dev = simple_strtoul (argv[1], NULL, 10); sprintf(cmd, "mmc dev %d", dev); if (0 > run_command(cmd, 0)) /* mmc device */ return -1; if (0 != strcmp(argv[2], "2ndboot") && 0 != strcmp(argv[2], "boot") && 0 != strcmp(argv[2], "raw") && 0 != strcmp(argv[2], "part")) goto usage; mem_addr = simple_strtoul (argv[3], NULL, 16); dst_addr = simple_strtoull(argv[4], NULL, 16); mem_len = simple_strtoull(argv[5], NULL, 16); p = (unsigned char *)mem_addr; blk = (dst_addr/MMC_BLOCK_SIZE); cnt = (mem_len/MMC_BLOCK_SIZE) + ((mem_len & (MMC_BLOCK_SIZE-1)) ? 1 : 0); flush_dcache_all(); if (! strcmp(argv[2], "2ndboot")) { struct boot_dev_head *bh = (struct boot_dev_head *)mem_addr; struct boot_dev_mmc *bd = (struct boot_dev_mmc *)&bh->bdi; bd->port_no = dev; /* set u-boot device port num */ printf("head boot dev = %d\n", bd->port_no); goto do_write; } if (! strcmp(argv[2], "boot")) { struct boot_dev_head head; struct boot_dev_head *bh = &head; struct boot_dev_mmc *bd = (struct boot_dev_mmc *)&bh->bdi; int len = sizeof(head); unsigned int load = CONFIG_SYS_TEXT_BASE; if (argc == 7) load = simple_strtoul (argv[6], NULL, 16); memset((void*)&head, 0x00, len); bh->load_addr = (unsigned int)load; bh->jump_addr = bh->load_addr; bh->load_size = (unsigned int)mem_len; bh->signature = SIGNATURE_ID; bd->port_no = dev; printf("head boot dev = %d\n", bd->port_no); printf("head load addr = 0x%08x\n", bh->load_addr); printf("head load size = 0x%08x\n", bh->load_size); printf("head gignature = 0x%08x\n", bh->signature); p -= len; memcpy(p, bh, len); mem_len += MMC_BLOCK_SIZE; cnt = (mem_len/MMC_BLOCK_SIZE) + ((mem_len & (MMC_BLOCK_SIZE-1)) ? 1 : 0); goto do_write; } if (strcmp(argv[2], "part") == 0) { uint64_t parts[4][2] = { {0,0}, }; uint64_t part_len = 0; int partno = (int)dst_addr; int num = 0; if (0 > mmc_get_part_table(desc, parts, &num)) return 1; if (partno > num || 1 > partno) { printf ("** Invalid mmc.%d partition number %d (1 ~ %d) **\n", dev, partno, num); return 1; } dst_addr = parts[partno-1][0]; /* set write addr from part table */ part_len = parts[partno-1][1]; blk = (dst_addr/MMC_BLOCK_SIZE); if (0 == check_compress_ext4((char*)p, part_len)) { printf("update mmc.%d compressed ext4 = 0x%llx(%d) ~ 0x%llx(%d): ", dev, dst_addr, (unsigned int)blk, mem_len, (unsigned int)cnt); ret = write_compressed_ext4((char*)p, blk); printf("%s\n", ret?"Fail":"Done"); return 1; } goto do_write; } do_write: if (! blk) { printf("-- Fail: start %d block(0x%llx) is in MBR zone (0x200) --\n", (int)blk, dst_addr); return -1; } printf("update mmc.%d type %s = 0x%llx(0x%x) ~ 0x%llx(0x%x): ", dev, argv[2], dst_addr, (unsigned int)blk, mem_len, (unsigned int)cnt); ret = mmc_bwrite(dev, blk, cnt, (void const*)p); printf("%s\n", ret?"Done":"Fail"); return ret; usage: cmd_usage(cmdtp); return 1; }
/******************************************************************************* Reset environment variables. ********************************************************************************/ int resetenv_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #if defined(CONFIG_ENV_IS_IN_FLASH ) ulong stop_addr; ulong start_addr; #elif defined(CONFIG_ENV_IS_IN_MMC) lbaint_t start_lba; lbaint_t blk_count; ulong blk_erased; ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); struct mmc *mmc; int err; #endif #if defined(CONFIG_ENV_IS_IN_NAND) size_t env_offset = CONFIG_ENV_OFFSET; nand_info_t *nand = &nand_info[0]; printf("Erasing 0x%x - 0x%x:",env_offset, env_offset + CONFIG_ENV_RANGE); nand_erase(nand, env_offset, CONFIG_ENV_RANGE); puts ("[Done]\n"); #elif defined(CONFIG_ENV_IS_IN_SPI_FLASH) u32 sector = 1; if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) sector++; } #ifdef CONFIG_SPI_FLASH_PROTECTION printf("Unprotecting flash:"); spi_flash_protect(flash, 0); printf("\t\t[Done]\n"); #endif printf("Erasing 0x%x - 0x%x:",CONFIG_ENV_OFFSET, CONFIG_ENV_OFFSET + sector * CONFIG_ENV_SECT_SIZE); if(!flash) { flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE); if (!flash) { printf("Failed to probe SPI Flash\n"); set_default_env("!spi_flash_probe() failed"); return 0; } } if (spi_flash_erase(flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE)) return 1; puts("\t[Done]\n"); #ifdef CONFIG_SPI_FLASH_PROTECTION printf("Protecting flash:"); spi_flash_protect(flash, 1); printf("\t\t[Done]\n"); #endif #elif defined(CONFIG_ENV_IS_IN_FLASH ) start_addr = CONFIG_ENV_ADDR; stop_addr = start_addr + CONFIG_ENV_SIZE - 1; printf("Erasing sector 0x%x:",CONFIG_ENV_OFFSET); flash_sect_protect (0, start_addr, stop_addr); flash_sect_erase (start_addr, stop_addr); flash_sect_protect (1, start_addr, stop_addr); printf("\t[Done]\n"); #elif defined(CONFIG_ENV_IS_IN_MMC) start_lba = CONFIG_ENV_ADDR / CONFIG_ENV_SECT_SIZE; blk_count = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); if (!mmc) { printf("No MMC card found\n"); return 1; } if (mmc_init(mmc)) { printf("MMC(%d) init failed\n", CONFIG_SYS_MMC_ENV_DEV); return 1; } #ifdef CONFIG_SYS_MMC_ENV_PART /* Valid for MMC/eMMC only - switch to ENV partition */ if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num) { if (mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, CONFIG_SYS_MMC_ENV_PART)) { printf("MMC partition switch failed\n"); return 1; } } #endif printf("Erasing 0x"LBAF" blocks starting at sector 0x"LBAF" :", blk_count, start_lba); /* For some unknown reason the mmc_berase() fails with timeout if called before any futher write to MMC/SD (for instance, right after u-boot bring up). However the mmc_bwrite() always succeds. Writing zeroes into SD/MMC blocks is similar operation as doing so to IDE/SATA disk and therefore can be used for erasing the imformation stored on the media. blk_erased = mmc_berase(CONFIG_SYS_MMC_ENV_DEV, start_lba, blk_count); */ memset(buf, 0, CONFIG_ENV_SIZE); blk_erased = mmc_bwrite(CONFIG_SYS_MMC_ENV_DEV, start_lba, blk_count, buf); if (blk_erased != blk_count) { printf("\t[FAIL] - erased %#lx blocks\n", blk_erased); err = 1; } else { printf("\t[Done]\n"); err = 0; } #ifdef CONFIG_SYS_MMC_ENV_PART /* Valid for MMC/eMMC only - restore current partition */ if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num) mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, mmc->part_num); #endif if (err) return err; #endif printf("Warning: Default Environment Variables will take effect Only after RESET\n"); return 0; }