Example #1
0
File: fat.c Project: xl0/UBIBoot
static int get_first_partition(uint32_t *lba)
{
	struct mbr mbr;

	if (mmc_block_read((uint32_t *) &mbr, 0, 1)) {
		/* Unable to read bootsector. */
		SERIAL_PUTI(0x00);
		return -1;
	}

	if (mbr.signature != 0xAA55) {
		/* No MBR detected. */
		SERIAL_PUTI(0x01);
		return -1;
	}

	if (mbr.partitions[0].status
				&& mbr.partitions[0].status != 0x80) {
		/* Unable to detect first physical partition. */
		SERIAL_PUTI(0x02);
		return -1;
	}

	*lba =  mbr.partitions[0].lba;
	return 0;
}
Example #2
0
int mmc_readback_blks(int dev_id, unsigned long addr, int blks, int bootarea)
{
    int i, j, result = 0;
    u8 val;
    u8 *ext_csd;
    unsigned long blknr = addr / MMC_BLOCK_SIZE;
    unsigned char *buf = (unsigned char*)MMC_BUF_ADDR;
    struct mmc_card *card;
    struct mmc_host *host;

    host = mmc_get_host(dev_id);
    card = mmc_get_card(dev_id);
    ext_csd = &card->raw_ext_csd[0];

    if (bootarea && !mmc_card_sd(card)) {
        /* configure to specified partition */
        val = (ext_csd[EXT_CSD_PART_CFG] & ~0x7) | EXT_CSD_PART_CFG_BOOT_PART_1;
        if (mmc_set_part_config(card, val) != MMC_ERR_NONE) {
            result = -__LINE__;
            goto done;
        }
        if (mmc_read_ext_csd(host, card) != MMC_ERR_NONE) {
            result = -__LINE__;
            goto done;
        }
    }

    printf("[SD%d] Dump %d blks from 0x%x (FLASH)\n", dev_id, blks, 
        blknr * MMC_BLOCK_SIZE);
    for (i = 0; i < blks; i++) {
        memset(buf, 0, MMC_BLOCK_SIZE);
        if (MMC_ERR_NONE != mmc_block_read(dev_id, blknr + i, 1, (unsigned long*)buf)) {
            printf("\n[SD%d] Read from %dth block error\n", dev_id, blknr + i);
            break;
        }
        
        for (j = 0; j < MMC_BLOCK_SIZE; j++) {
            if (j % 16 == 0)
                printf("\n%xh: ", (blknr + i) * MMC_BLOCK_SIZE + j);
            printf("%x ",  buf[j]);
        }
        printf("\n");
        buf += MMC_BLOCK_SIZE;
    }
done:

    if (bootarea && !mmc_card_sd(card)) {
        /* configure to user partition */
        val = (ext_csd[EXT_CSD_PART_CFG] & ~0x7) | EXT_CSD_PART_CFG_DEFT_PART;
        if (mmc_set_part_config(card, val) != MMC_ERR_NONE)
            result = -__LINE__;
        if (mmc_read_ext_csd(host, card) != MMC_ERR_NONE) {
            result = -__LINE__;
        }
    }  

    return result;
}
Example #3
0
int dfu_read_medium_mmc(struct dfu_entity *dfu, void *buf, long *len)
{
	int ret = -1;

	switch (dfu->layout) {
	case DFU_RAW_ADDR:
		ret = mmc_block_read(dfu, buf, len);
		break;
	case DFU_FS_FAT:
		ret = mmc_file_read(dfu, buf, len);
		break;
	default:
		printf("%s: Layout (%s) not (yet) supported!\n", __func__,
		       dfu_get_layout(dfu->layout));
	}

	return ret;
}
Example #4
0
int
/****************************************************/
mmc_write(uchar *src, ulong dst, int size)
/****************************************************/
{
	ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
	ulong mmc_block_size, mmc_block_address;

	if (size == 0)
	{
		return 0;
	}

	if (!mmc_ready)
	{
		printf("Please initial the MMC first\n");
		return -1;
	}

	mmc_block_size = MMC_BLOCK_SIZE;
	mmc_block_address = ~(mmc_block_size - 1);

	dst -= CFG_MMC_BASE;
	end = dst + size;
	part_start = ~mmc_block_address & dst;
	part_end = ~mmc_block_address & end;
	aligned_start = mmc_block_address & dst;
	aligned_end = mmc_block_address & end;

	/* all block aligned accesses */
	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
	if (part_start)
	{
		part_len = mmc_block_size - part_start;
		debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
		(ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
		if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
		{
			return -1;
		}
		memcpy(mmc_buf+part_start, src, part_len);
		if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0)
		{
			return -1;
		}
		dst += part_len;
		src += part_len;
	}
	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
	for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size)
	{
		debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
		src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
		if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0)
		{
			return -1;
		}
	}
	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
	if (part_end && dst < end)
	{
		debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
		src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
		if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
		{
			return -1;
		}
		memcpy(mmc_buf, src, part_end);
		if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0)
		{
			return -1;
		}
	}
	return 0;
}
Example #5
0
int mmc_test_mem_card(struct mmc_test_config *cfg)
{
    int id, count, forever;
    int ret, chk_result, tid = 0, result = 0;
    unsigned int chunks, chunk_blks, left_blks, pass = 0, fail = 0;
    unsigned int total_blks;
    unsigned int i, j;
    unsigned int blksz;
    unsigned int clkhz;    
    char pattern = 0;
    char *buf;
    unsigned long blknr;
    struct mmc_host *host;
    struct mmc_card *card;

    id    = cfg->id;
    count = cfg->count;
    buf   = cfg->buf;
    blknr = cfg->blknr;
    blksz = cfg->blksz;

    chk_result = cfg->chk_result;
    chunk_blks = cfg->chunk_blks;
    total_blks = (cfg->total_size + blksz - 1) / blksz;
    forever    = (count == -1) ? 1 : 0;

    host = mmc_get_host(id);
    card = mmc_get_card(id);

    while (forever || count--) {
        printf("[TST] ==============================================\n");
        printf("[TST] BEGIN: %d/%d, No Stop(%d)\n", 
            (cfg->count != -1) ? cfg->count - count : 0, 
            (cfg->count != -1) ? cfg->count : 0, forever);
        printf("[TST] ----------------------------------------------\n");
        printf("[TST] Mode    : %d\n", cfg->mode);
        printf("[TST] Clock   : %d kHz\n", cfg->clock / 1000);
        printf("[TST] BusWidth: %d bits\n", cfg->buswidth);
        printf("[TST] BurstSz : %d bytes\n", 0x1 << cfg->burstsz);
        printf("[TST] BlkAddr : %xh\n", blknr);
        printf("[TST] BlkSize : %dbytes\n", blksz);
        printf("[TST] TstBlks : %d\n", total_blks);
#if defined(BB_MT6575)
        printf("[TST] AutoCMD : 12(%d), 23(%d)\n", 
            (cfg->autocmd & MSDC_AUTOCMD12) ? 1 : 0, 
            (cfg->autocmd & MSDC_AUTOCMD23) ? 1 : 0);
#endif
        printf("[TST] ----------------------------------------------\n");


        if (mmc_init_host(host, id) != 0) {
            result = -__LINE__;
            goto failure;
        }
        if (mmc_init_card(host, card) != 0) {
            result = -__LINE__;
            goto failure;
        }
#if defined(BB_MT6575)
        msdc_set_dma(host, (u8)cfg->burstsz, (u32)cfg->flags);
        msdc_set_autocmd(host, cfg->autocmd, 1);
#endif

        /* change uhs-1 mode */
#if 0        
        if (mmc_card_uhs1(card)) {
            if (mmc_switch_uhs1(host, card, cfg->uhsmode) != 0) {
                result = -__LINE__;
                goto failure;
            }
        }
#endif

        /* change clock */
        if (cfg->clock) {
            clkhz = card->maxhz < cfg->clock ? card->maxhz : cfg->clock;
            mmc_set_clock(host, mmc_card_ddr(card), clkhz); 
        }
        if (mmc_card_sd(card) && cfg->buswidth == HOST_BUS_WIDTH_8) {
            printf("[TST] SD card doesn't support 8-bit bus width (SKIP)\n");
            result = MMC_ERR_NONE;
        }
        if (mmc_set_bus_width(host, card, cfg->buswidth) != 0) {
            result = -__LINE__;
            goto failure;
        }

        /* cmd16 is illegal while card is in ddr mode */
        if (!(mmc_card_mmc(card) && mmc_card_ddr(card))) {
            if (mmc_set_blk_length(host, blksz) != 0) {
                result = -__LINE__;
                goto failure;            
            }
        }

#if defined(BB_MT6575)
        if (cfg->piobits) {
            printf("[TST] PIO bits: %d\n", cfg->piobits);
            msdc_set_pio_bits(host, cfg->piobits);
        }
#endif
        tid = result = 0;        

        if (mmc_erase_start(card, blknr * blksz) != MMC_ERR_NONE) {
            result = -__LINE__;
            goto failure;
        }
        if (mmc_erase_end(card, (blknr + total_blks) * blksz) != MMC_ERR_NONE) {
            result = -__LINE__;
            goto failure;
        }
        if (mmc_erase(card, MMC_ERASE_NORMAL) != MMC_ERR_NONE) {
            result = -__LINE__;
            goto failure;        
        }
        printf("[TST] 0x%x - 0x%x Erased\n", blknr * blksz, 
            (blknr + total_blks) * blksz);

        mmc_send_status(host, card, &status);

        if (cfg->tst_single) {
            /* single block write */
            for (i = 0; i < total_blks; i++) {
                pattern = (i + count) % 256;
                memset(buf, pattern, blksz);
                ret = mmc_block_write(id, blknr + i, 1, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    printf("test single block write failed (%d)\n", i);
                    result = -__LINE__;
                    goto failure;
                }
            }

            printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, 
                "test single block write\n");

            if (result)
                break;
            
            /* single block read */
            for (i = 0; i < total_blks && !result; i++) {
                pattern = (i + count) % 256;
                /* populate buffer with different pattern */
                memset(buf, pattern + 1, blksz);
                ret = mmc_block_read(id, blknr + i, 1, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    result = -__LINE__;
                    goto failure;
                }
                if (chk_result) {
                    for (j = 0; j < blksz; j++) {
                        if (buf[j] != pattern) {
                            result = -__LINE__;
                            goto failure;
                        }
                    }
                }
            }
            printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, 
                "test single block read\n");

            if (result) {
                printf("[SD%d]\t\tread back pattern(0x%.2x) failed\n", 
                    id, pattern);
                goto failure;
            }
        }

        mmc_send_status(host, card, &status);
        
        if (cfg->tst_multiple) {
            /* multiple block write */
            chunks = total_blks / chunk_blks;
            left_blks = total_blks % chunk_blks;   
            for (i = 0; i < chunks; i++) {
                pattern = (i + count) % 256;
                memset(buf, pattern, blksz * chunk_blks);
                ret = mmc_block_write(id, blknr + i * chunk_blks, 
                    chunk_blks, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    result = -__LINE__;
                    goto failure;
                }
            }
            
            if (!result && left_blks) {
                pattern = (i + count) % 256;
                memset(buf, pattern, blksz * left_blks);
                ret = mmc_block_write(id, blknr + chunks * chunk_blks, 
                    left_blks, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    result = -__LINE__;
                    goto failure;
                }
            }

            printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, 
                "test multiple block write\n");

            if (result)
                goto failure;

            /* multiple block read */
            for (i = 0; i < chunks; i++) {
                pattern = (i + count) % 256;
                /* populate buffer with different pattern */
                memset(buf, pattern + 1, blksz);
                ret = mmc_block_read(id, blknr + i * chunk_blks, 
                    chunk_blks, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    printf("[SD%d]\t\tread %d blks failed(ret = %d blks)\n",
                        host->id, chunk_blks, ret);
                    result = -__LINE__;
                    goto failure;
                }
                if (chk_result) {
                    for (j = 0; j < chunk_blks * blksz; j++) {
                        if (buf[j] == pattern)
                            continue;
                        result = -__LINE__;
                        printf("[SD%d]\t\t%xh = %x (!= %x)\n",
                            host->id, blknr + i * chunk_blks + j, buf[j], pattern);
                        goto failure;
                    }
                }
            }

            if (!result && left_blks) {
                pattern = i % 256;
                /* populate buffer with different pattern */
                memset(buf, pattern + 1, blksz);
                ret = mmc_block_read(id, blknr + chunks * chunk_blks, 
                    left_blks, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    printf("[SD%d]\t\tread %d blks failed(ret = %d blks)\n",
                        host->id, left_blks, ret);
                    result = -__LINE__;
                    goto failure;
                }
                if (chk_result) {
                    for (j = 0; j < left_blks * blksz; j++) {
                        if (buf[j] == pattern)
                            continue;
                        printf("[SD%d]\t\t%xh = %x (!= %x)\n",
                            host->id, blknr + chunks * chunk_blks + j, buf[j], pattern);
                        result = -__LINE__;
                        goto failure;
                    }
                }
            }

            printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, 
                "test multiple block read\n");

            if (result)
                goto failure;
        }

        mmc_send_status(host, card, &status);

        if (cfg->tst_interleave) {
            /* multiple block write */
            chunks = total_blks / chunk_blks;
            left_blks = total_blks % chunk_blks;   
            for (i = 0; i < chunks; i++) {
                pattern = (i + count) % 256;
                memset(buf, pattern, blksz * chunk_blks);
                ret = mmc_block_write(id, blknr + i * chunk_blks, 
                    chunk_blks, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    result = -__LINE__;
                    goto failure;
                }

                /* populate buffer with different pattern */
                memset(buf, pattern + 1, blksz * chunk_blks);
                ret = mmc_block_read(id, blknr + i * chunk_blks, 
                    chunk_blks, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    result = -__LINE__;
                    goto failure;
                }
                if (chk_result) {
                    for (j = 0; j < chunk_blks * blksz; j++) {
                        if (buf[j] == pattern) 
                            continue;
                        result = -__LINE__;
                        goto failure;
                    }
                }                
            }           

            if (!result && left_blks) {
                pattern = (i + count) % 256;
                memset(buf, pattern, blksz * left_blks);
                ret = mmc_block_write(id, blknr + chunks * chunk_blks, 
                    left_blks, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    result = -__LINE__;
                    goto failure;
                }

                /* populate buffer with different pattern */
                memset(buf, pattern + 1, blksz * left_blks);
                ret = mmc_block_read(id, blknr + chunks * chunk_blks, 
                    left_blks, (unsigned long*)buf);
                if (ret != MMC_ERR_NONE) {
                    result = -__LINE__;
                    break;
                }
                if (chk_result) {
                    for (j = 0; j < left_blks * blksz; j++) {
                        if (buf[j] == pattern)
                            continue;
                        result = -__LINE__;
                        goto failure;
                    }
                }
            }

            printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, 
                "test multiple block interleave write-read\n");

            if (result)
                goto failure;
        }
        if (cfg->desc) {
            printf("[TST] ----------------------------------------------\n");
            printf("[TST] Report - %s \n", cfg->desc);
            printf("[TST] ----------------------------------------------\n");
        }
        mmc_prof_dump(id);

failure:
        if (result) {
            printf("[SD%d] mmc test failed (%d)\n", host->id, result);
            fail++;
        } else {
            pass++;
        }
        printf("[TST] ----------------------------------------------\n");
        printf("[TST] Test Result: TOTAL(%d/%d), PASS(%d), FAIL(%d) \n", 
            cfg->count - count, cfg->count, pass, fail);
        printf("[TST] ----------------------------------------------\n");    
    	//mdelay(1000);
    }

    return result;
}
Example #6
0
int mmc_download(int dev_id, u32 imgaddr, u32 size, u32 addr, int bootarea)
{
    int ret;
    int i, j, result = 0;
    u8 val;
    u8 *ext_csd;    
    uchar *buf, *chkbuf;
    u32 chunks, chunk_blks = 128, left_blks, blknr;
    u32 total_blks;
    struct mmc_card *card;

    if (!size)
        return 0;

    if (addr % MMC_BLOCK_SIZE)
        return MMC_ERR_FAILED;

    card    = mmc_get_card(dev_id);
    ext_csd = &card->raw_ext_csd[0];    

    if (bootarea && !mmc_card_sd(card) && card->ext_csd.part_en) {
        /* configure to specified partition */
        val = (ext_csd[EXT_CSD_PART_CFG] & ~0x7) | EXT_CSD_PART_CFG_BOOT_PART_1;
        if (mmc_set_part_config(card, val) != MMC_ERR_NONE) {
            result = -__LINE__;
            goto done;
        }
    }

    blknr      = addr / MMC_BLOCK_SIZE;
    total_blks = (size + MMC_BLOCK_SIZE - 1) / MMC_BLOCK_SIZE;

    /* multiple block write */
    chunks    = total_blks / chunk_blks;
    left_blks = total_blks % chunk_blks;  
    buf       = (uchar*)imgaddr;
    chkbuf    = (uchar*)MMC_BUF_ADDR;

    for (i = 0; i < chunks; i++) {
        ret = mmc_block_write(dev_id, blknr + i * chunk_blks, 
            chunk_blks, (unsigned long*)buf);
        if (ret != MMC_ERR_NONE) {
            result = -__LINE__;
            goto done;
        }
        ret = mmc_block_read(dev_id, blknr + i * chunk_blks,
            chunk_blks, (unsigned long*)chkbuf);
        if (ret != MMC_ERR_NONE) {
            result = -__LINE__;
            goto done;
        }

        for (j = 0; j < chunk_blks * MMC_BLOCK_SIZE; j++) {
            if (buf[j] == chkbuf[j])
                continue;
            result = -__LINE__;
            goto done;
        }
        printf("[SD%d] Write %3d blocks from 0x%.8x(RAM) to 0x%.8x(FLASH).\n",
            dev_id, chunk_blks, (unsigned int)buf, 
            (blknr + i * chunk_blks) * MMC_BLOCK_SIZE);

        buf += (chunk_blks * MMC_BLOCK_SIZE);
    }
    
    if (left_blks) {
        ret = mmc_block_write(dev_id, blknr + chunks * chunk_blks, 
            left_blks, (unsigned long*)buf);
        if (ret != MMC_ERR_NONE) {
            result = -__LINE__;
            goto done;
        }
        ret = mmc_block_read(dev_id, blknr + chunks * chunk_blks,
            left_blks, (unsigned long*)chkbuf);
        if (ret != MMC_ERR_NONE) {
            result = -__LINE__;
            goto done;
        }
        for (j = 0; j < left_blks * MMC_BLOCK_SIZE; j++) {
            if (buf[j] == chkbuf[j])
                continue;
            printf("[SD%d] chkbuf[%d] = %xh (!= %xh) \n", dev_id,
                j, chkbuf[j], buf[j]);
            result = -__LINE__;
            goto done;
        }
        printf("[SD%d] Write %3d blocks from 0x%.8x(RAM) to 0x%.8x(FLASH).\n",
            dev_id, left_blks, (unsigned int)buf, 
            (blknr + chunks * chunk_blks) * MMC_BLOCK_SIZE);
    }

done:
    if (bootarea && !mmc_card_sd(card) && card->ext_csd.part_en) {
        /* configure to user partition */
        val = (ext_csd[EXT_CSD_PART_CFG] & ~0x7) | EXT_CSD_PART_CFG_DEFT_PART;
        if (mmc_set_part_config(card, val) != MMC_ERR_NONE)
            result = -__LINE__;
    }

    if (!result) {
        printf("[SD%d] Download %d blocks (%d bytes) to 0x%.8x successfully\n", 
            dev_id, total_blks, total_blks * MMC_BLOCK_SIZE, blknr * MMC_BLOCK_SIZE);
    } else {
        printf("[SD%d] Download %d blocks (%d bytes) to 0x%.8x failed %d\n", 
            dev_id, total_blks, total_blks * MMC_BLOCK_SIZE, blknr * MMC_BLOCK_SIZE, result);
    }    
    return result;
}
Example #7
0
File: sd_boot.c Project: ykli/misc
int sd_boot(num)
{
	u8 *resp;
	u32 ret = 0;
	u32 clk_set = 0, clkrt = 0;

	DBG("sd_boot\n");

	current_boot = SD_BOOT;
	ctl_num = num;

	if (ctl_num == 1)
		REG_CPM_CLKGR &= ~(1 << 11);

	sd_init();
	clk_set = jz_extal / 2;
	while (200000 < clk_set) {
		clkrt++;
		clk_set >>= 1;
	}

	if (clkrt > 7) {
		clkrt = 7;
	}

	REG_MSC_CLKRT(ctl_num) = clkrt;
	REG_MSC_LPM(ctl_num) = 1;

	/* cmd12 reset when we reading or writing from the card, send this cmd */
	resp = mmc_cmd(12, 0, 0x41, MSC_CMDAT_RESPONSE_R1);

	resp = mmc_cmd(0, 0, 0x80, MSC_CMDAT_RESPONSE_NONE);
	resp = mmc_cmd(8, 0x1aa, 0x1, MSC_CMDAT_RESPONSE_R1);

	resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1);

	if (resp[0] & 0x20){
		if (resp[5] == 0x37){
			resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
			if (resp[5] == 0x3f)
				ret = sd_found();
			else
				ret = mmc_found();
		} else {
			ret = mmc_found();
		}
	} else {
		ret = mmc_found();
	}

	if (ret)
		return error_handler(current_boot);

	ret = mmc_block_read(SPL_SIZE + redundancy_size, (u32 *)start_addr);	//SDRAM ADDR

	if(!ret)
	{
		if (!(REG32(start_addr) == 0x4d53504c)) {
			if (ctl_num == 0)
				return sd_boot(1);
			if (ctl_num == 1)
				return usb_boot();
		} else {
			return xfer_d2i(start_addr + jump_offset, SPL_SIZE);
		}
	} else {
		return error_handler(current_boot);
	}
}