This commit is contained in:
刘可亮
2024-01-27 08:47:24 +08:00
parent d3bd993b5f
commit 9f7ba67007
2345 changed files with 74421 additions and 76616 deletions

View File

@@ -120,6 +120,8 @@ static void CMD_SET_FWC_META_end(struct upg_cmd *cmd)
set_current_device_id(0);
}
fwc->start_us = aic_get_time_us();
dev_type = get_current_device_type();
printf(" Media: %s(%d)\n", get_current_device_name(dev_type),
dev_type);
@@ -338,6 +340,8 @@ static void CMD_SEND_FWC_DATA_end(struct upg_cmd *cmd)
{
enum upg_dev_type dev_type;
struct fwc_info *fwc;
u64 total_len = 0;
u32 start_us;
fwc = (struct fwc_info *)cmd->priv;
@@ -371,6 +375,15 @@ static void CMD_SEND_FWC_DATA_end(struct upg_cmd *cmd)
cmd->priv = 0;
cmd_state_set_next(cmd, CMD_STATE_IDLE);
}
total_len = fwc->trans_size;
start_us = aic_get_time_us() - fwc->start_us;
pr_info(" Partition: %s programming done.\n", fwc->meta.partition);
pr_info(" Used time: %u.%u sec, Speed: %lu.%lu KB/s.\n",
start_us / 1000000, start_us / 1000 % 1000,
(ulong)((total_len * 1000000) / start_us / 1024),
(ulong)((total_len * 1000000) / start_us % 1024));
pr_debug("%s, l: %d\n", __func__, __LINE__);
}

View File

@@ -7,17 +7,29 @@
*/
#include <string.h>
#include <aic_common.h>
#include <aic_core.h>
#include <aicupg.h>
#include <mmc.h>
#include <sparse_format.h>
#include <partition_table.h>
#include <disk_part.h>
#include "upg_internal.h"
#define MMC_BLOCK_SIZE 512
#define SPARSE_FILLBUF_SIZE (1024 * 1024)
struct aicupg_mmc_priv {
struct aic_sdmc *host;
struct aic_partition *parts;
sparse_header_t sparse_header;
chunk_header_t chunk_header;
unsigned char remain_data[MMC_BLOCK_SIZE];
unsigned int remain_len;
ulong blkstart;
int cur_chunk;
int cur_chunk_remain_data_sz;
int cur_chunk_burned_data_sz;
int is_sparse;
};
int mmc_is_exist()
@@ -38,10 +50,24 @@ s32 mmc_fwc_prepare(struct fwc_info *fwc, u32 mmc_id)
return ret;
}
static unsigned long mmc_write(struct blk_desc *block_dev, u64 start,
u64 blkcnt, void *buffer)
{
return mmc_bwrite(block_dev->priv, start, blkcnt, buffer);
}
static unsigned long mmc_read(struct blk_desc *block_dev, u64 start, u64 blkcnt,
const void *buffer)
{
return mmc_bread(block_dev->priv, start, blkcnt, (void *)buffer);
}
void mmc_fwc_start(struct fwc_info *fwc)
{
struct aicupg_mmc_priv *priv;
int mmc_id = 0;
struct disk_blk_ops ops;
struct blk_desc dev_desc;
int mmc_id = 0, ret;
mmc_id = get_current_device_id();
@@ -67,6 +93,19 @@ void mmc_fwc_start(struct fwc_info *fwc)
fwc->burn_result = 0;
fwc->run_result = 0;
ops.blk_write = mmc_write;
ops.blk_read = mmc_read;
aic_disk_part_set_ops(&ops);
dev_desc.blksz = MMC_BLOCK_SIZE;
dev_desc.lba_count = priv->host->dev->card_capacity * 2;
dev_desc.priv = priv->host;
ret = aic_disk_write_gpt(&dev_desc, priv->parts);
if (ret) {
printf("Write PART table failed.\n");
}
mmc_block_refresh(priv->host);
return;
out:
if (priv->parts)
@@ -76,7 +115,333 @@ out:
free(priv);
}
s32 mmc_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
{
struct aicupg_mmc_priv *priv;
struct aic_partition *parts;
sparse_header_t *sheader;
chunk_header_t *cheader;
u8 *wbuf, *p;
s32 clen = 0, remain, total_len;
u32 chunk;
u64 chunk_data_sz, chunk_blkcnt, remain_blkcnt;
u32 total_blocks = 0, blks;
u32 remain_blks, redund_blks, erase_group;
u32 *fill_buf, fill_val, fill_buf_num_blks;
int i, j, break_flag = 0;
wbuf = malloc(ROUNDUP(len + MMC_BLOCK_SIZE, fwc->block_size));
if (!wbuf) {
pr_err("malloc failed.\n");
return 0;
}
p = wbuf;
priv = (struct aicupg_mmc_priv *)fwc->priv;
if (!priv) {
pr_err("MMC FWC get priv failed.\n");
goto out;
}
if (priv->remain_len > 0) {
memcpy(wbuf, priv->remain_data, priv->remain_len);
memcpy(wbuf + priv->remain_len, buf, len);
} else {
memcpy(wbuf, buf, len);
}
total_len = (priv->remain_len + len);
remain = total_len;
parts = priv->parts;
while (parts) {
if (!strcmp(parts->name, fwc->meta.partition))
break;
parts = parts->next;
}
if (!parts)
pr_err("not find %s part info.\n", fwc->meta.partition);
sheader = &(priv->sparse_header);
if (is_sparse_image(wbuf)) {
priv->is_sparse = 1;
memcpy(sheader, wbuf, sizeof(sparse_header_t));
wbuf += sheader->file_hdr_sz;
clen += sheader->file_hdr_sz;
remain -= sheader->file_hdr_sz;
if (sheader->file_hdr_sz > sizeof(sparse_header_t)) {
wbuf += (sheader->file_hdr_sz - sizeof(sparse_header_t));
clen += (sheader->file_hdr_sz - sizeof(sparse_header_t));
remain -= (sheader->file_hdr_sz - sizeof(sparse_header_t));
}
pr_info("=== Sparse Image Header ===\n");
pr_info("magic: 0x%x\n", sheader->magic);
pr_info("major_version: 0x%x\n", sheader->major_version);
pr_info("minor_version: 0x%x\n", sheader->minor_version);
pr_info("file_hdr_sz: %d\n", sheader->file_hdr_sz);
pr_info("chunk_hdr_sz: %d\n", sheader->chunk_hdr_sz);
pr_info("blk_sz: %d\n", sheader->blk_sz);
pr_info("total_blks: %d\n", sheader->total_blks);
pr_info("total_chunks: %d\n", sheader->total_chunks);
}
pr_debug("Flashing Sparse Image\n");
/* Start processing chunks */
for (chunk = priv->cur_chunk; chunk < sheader->total_chunks; chunk++) {
/* Read and skip over chunk header */
cheader = (chunk_header_t *)wbuf;
if (cheader->chunk_type != CHUNK_TYPE_RAW) {
pr_debug("=== Chunk Header ===\n");
pr_debug("chunk_type: 0x%x\n", cheader->chunk_type);
pr_debug("chunk_data_sz: 0x%x\n", cheader->chunk_sz);
pr_debug("total_size: 0x%x\n", cheader->total_sz);
}
if (cheader->chunk_type != CHUNK_TYPE_RAW &&
cheader->chunk_type != CHUNK_TYPE_FILL &&
cheader->chunk_type != CHUNK_TYPE_DONT_CARE &&
cheader->chunk_type != CHUNK_TYPE_CRC32) {
cheader = &(priv->chunk_header);
chunk_data_sz = priv->cur_chunk_remain_data_sz;
} else {
wbuf += sheader->chunk_hdr_sz;
clen += sheader->chunk_hdr_sz;
remain -= sheader->chunk_hdr_sz;
memcpy(&(priv->chunk_header), cheader, sizeof(chunk_header_t));
if (sheader->chunk_hdr_sz > sizeof(chunk_header_t)) {
/*
* Skip the remaining bytes in a header that is longer
* than we expected.
*/
wbuf += (sheader->chunk_hdr_sz - sizeof(chunk_header_t));
clen += (sheader->chunk_hdr_sz - sizeof(chunk_header_t));
remain -= (sheader->chunk_hdr_sz - sizeof(chunk_header_t));
}
chunk_data_sz = ((u64)sheader->blk_sz) * cheader->chunk_sz;
priv->cur_chunk_remain_data_sz = chunk_data_sz;
priv->cur_chunk_burned_data_sz = 0;
}
chunk_blkcnt = DIV_ROUND_UP(chunk_data_sz, MMC_BLOCK_SIZE);
remain_blkcnt = remain / MMC_BLOCK_SIZE;
switch (cheader->chunk_type) {
case CHUNK_TYPE_RAW:
if (cheader->total_sz !=
(sheader->chunk_hdr_sz + chunk_data_sz +
priv->cur_chunk_burned_data_sz)) {
pr_err("Bogus chunk size for chunk type Raw\n");
goto out;
}
if (priv->blkstart + chunk_blkcnt >
(parts->size / MMC_BLOCK_SIZE)) {
pr_err("Request would exceed partition size!\n");
goto out;
}
if (remain_blkcnt > chunk_blkcnt &&
(remain - chunk_data_sz) >= 16) {
blks = mmc_bwrite(priv->host,
(parts->start / MMC_BLOCK_SIZE) +
priv->blkstart,
chunk_blkcnt, wbuf);
if (blks <
chunk_blkcnt) { /* blks might be > blkcnt (eg. NAND bad-blocks) */
pr_err("Write failed, block %llu[%u]\n",
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
blks);
goto out;
}
remain = remain - chunk_data_sz;
priv->cur_chunk_remain_data_sz = 0;
priv->cur_chunk_burned_data_sz += chunk_data_sz;
} else {
blks = mmc_bwrite(priv->host,
(parts->start / MMC_BLOCK_SIZE) +
priv->blkstart,
remain_blkcnt, wbuf);
if (blks <
remain_blkcnt) { /* blks might be > blkcnt (eg. NAND bad-blocks) */
pr_err("Write failed, block %llu[%u]\n",
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
blks);
goto out;
}
priv->cur_chunk_remain_data_sz -=
remain_blkcnt * MMC_BLOCK_SIZE;
priv->cur_chunk_burned_data_sz +=
remain_blkcnt * MMC_BLOCK_SIZE;
remain = remain % MMC_BLOCK_SIZE;
}
priv->blkstart += blks;
total_blocks += blks;
wbuf += blks * MMC_BLOCK_SIZE;
clen += blks * MMC_BLOCK_SIZE;
if ((priv->cur_chunk_remain_data_sz > 0 &&
(remain > 0 && remain < MMC_BLOCK_SIZE)) ||
remain < sizeof(chunk_header_t))
break_flag = 1;
break;
case CHUNK_TYPE_FILL:
if (cheader->total_sz !=
(sheader->chunk_hdr_sz + sizeof(uint32_t))) {
pr_err("Bogus chunk size for chunk type FILL\n");
goto out;
}
fill_buf = (u32 *)aicos_malloc_align(
0, ROUNDUP(SPARSE_FILLBUF_SIZE, CACHE_LINE_SIZE),
CACHE_LINE_SIZE);
if (!fill_buf) {
pr_err("Malloc failed for: CHUNK_TYPE_FILL\n");
goto out;
}
fill_val = *(uint32_t *)wbuf;
wbuf = (u8 *)wbuf + sizeof(u32);
clen += sizeof(uint32_t);
remain -= sizeof(uint32_t);
if (remain < sizeof(chunk_header_t))
break_flag = 1;
if (priv->blkstart + chunk_blkcnt >
(parts->size / MMC_BLOCK_SIZE)) {
pr_err("Request would exceed partition size!\n");
goto out;
}
for (i = 0; i < (SPARSE_FILLBUF_SIZE / sizeof(fill_val)); i++)
fill_buf[i] = fill_val;
remain_blks =
ROUNDUP((parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
0x400) -
((parts->start / MMC_BLOCK_SIZE) + priv->blkstart);
if (chunk_blkcnt >= (remain_blks + 0x400) &&
fill_val == 0x0) { // 512K
blks = mmc_bwrite(priv->host,
(parts->start / MMC_BLOCK_SIZE) +
priv->blkstart,
remain_blks, (u8 *)fill_buf);
if (blks <
remain_blks) { /* blks might be > j (eg. NAND bad-blocks) */
pr_err("Write failed, block %llu[%d]\n",
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
remain_blks);
free(fill_buf);
goto out;
}
priv->blkstart += blks;
erase_group = (chunk_blkcnt - remain_blks) / 0x400;
blks = mmc_berase(priv->host,
(parts->start / MMC_BLOCK_SIZE) +
priv->blkstart,
erase_group * 0x400);
if (blks !=
(erase_group *
0x400)) { /* blks might be > j (eg. NAND bad-blocks) */
pr_err("Erase failed, block %llu[%d]\n",
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
erase_group * 0x400);
free(fill_buf);
goto out;
}
priv->blkstart += blks;
redund_blks =
chunk_blkcnt - remain_blks - (erase_group * 0x400);
blks = mmc_bwrite(priv->host,
(parts->start / MMC_BLOCK_SIZE) +
priv->blkstart,
redund_blks, (u8 *)fill_buf);
if (blks <
redund_blks) { /* blks might be > j (eg. NAND bad-blocks) */
pr_err("Write failed, block %llu[%d]\n",
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
redund_blks);
free(fill_buf);
goto out;
}
priv->blkstart += blks;
} else {
fill_buf_num_blks = SPARSE_FILLBUF_SIZE / MMC_BLOCK_SIZE;
for (i = 0; i < chunk_blkcnt;) {
j = chunk_blkcnt - i;
if (j > fill_buf_num_blks)
j = fill_buf_num_blks;
blks = mmc_bwrite(priv->host,
(parts->start / MMC_BLOCK_SIZE) +
priv->blkstart,
j, (u8 *)fill_buf);
if (blks <
j) { /* blks might be > j (eg. NAND bad-blocks) */
pr_err("Write failed, block %llu[%d]\n",
(parts->start / MMC_BLOCK_SIZE) +
priv->blkstart,
j);
free(fill_buf);
goto out;
}
priv->blkstart += blks;
i += j;
}
}
total_blocks += DIV_ROUND_UP(chunk_data_sz, sheader->blk_sz);
free(fill_buf);
break;
case CHUNK_TYPE_DONT_CARE:
priv->blkstart += chunk_blkcnt;
total_blocks += cheader->chunk_sz;
break;
case CHUNK_TYPE_CRC32:
if (cheader->total_sz != sheader->chunk_hdr_sz) {
pr_err("Bogus chunk size for chunk type Dont Care\n");
goto out;
}
total_blocks += cheader->chunk_sz;
wbuf += chunk_data_sz;
clen += chunk_data_sz;
remain -= chunk_data_sz;
break;
default:
printf("Unknown chunk type: %x\n", cheader->chunk_type);
cheader = &(priv->chunk_header);
}
if (break_flag)
break;
}
priv->remain_len = remain;
if (priv->remain_len) {
priv->cur_chunk = chunk;
memcpy(priv->remain_data, wbuf, priv->remain_len);
}
fwc->trans_size += clen;
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
out:
if (p)
free(p);
return len;
}
s32 mmc_fwc_raw_write(struct fwc_info *fwc, u8 *buf, s32 len)
{
struct aicupg_mmc_priv *priv;
struct aic_partition *parts = NULL;
@@ -106,7 +471,7 @@ s32 mmc_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
if (len % MMC_BLOCK_SIZE)
blkcnt++;
if ((blkstart + blkcnt) > parts->size) {
if ((blkstart + blkcnt) > (parts->size / MMC_BLOCK_SIZE)) {
pr_err("Data size exceed the partition size.\n");
goto out;
}
@@ -129,6 +494,20 @@ out:
return clen;
}
s32 mmc_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
{
struct aicupg_mmc_priv *priv;
priv = (struct aicupg_mmc_priv *)fwc->priv;
if (!is_sparse_image(buf) && !priv->is_sparse) {
pr_debug("Not a sparse image\n");
return mmc_fwc_raw_write(fwc, buf, len);
} else {
pr_debug("A sparse image\n");
return mmc_fwc_sparse_write(fwc, buf, len);
}
}
s32 mmc_fwc_data_read(struct fwc_info *fwc, u8 *buf, s32 len)
{
return 0;

View File

@@ -196,8 +196,8 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
struct aicupg_nand_priv *priv;
struct mtd_dev *mtd;
unsigned long offset, erase_offset;
int i, dolen = 0, ret = 0, pages = 0;
int total_len = 0, data_len = 0, remain_offset = 0;
int i, dolen = 0, ret = 0;
int total_len = 0, remain_offset = 0;
u8 *wbuf = NULL, *pbuf = NULL;
wbuf = malloc(ROUNDUP(len, fwc->block_size));
@@ -215,7 +215,6 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
}
total_len = (priv->remain_len + len);
pages = total_len / fwc->block_size;
if (total_len % fwc->block_size) {
priv->remain_len = total_len % fwc->block_size;
remain_offset = total_len - priv->remain_len;
@@ -230,23 +229,23 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
if (!mtd)
continue;
data_len = pages * mtd->writesize;
offset = priv->start_offset[i];
if ((offset + data_len) > (mtd->size)) {
if ((offset + len) > (mtd->size)) {
pr_err("Not enough space to write mtd %s\n", mtd->name);
goto out;
}
/* erase 1 sector when offset+len more than erased address */
erase_offset = priv->erase_offset[i];
while ((offset + data_len) > erase_offset) {
while ((offset + len) > erase_offset) {
if (mtd_block_isbad(mtd, erase_offset)) {
pr_err("Erase block is bad, skip it.\n");
priv->erase_offset[i] = erase_offset + mtd->erasesize;
erase_offset = priv->erase_offset[i];
continue;
}
ret = mtd_erase(mtd, erase_offset, mtd->erasesize);
ret = mtd_erase(mtd, erase_offset, ROUNDUP(len, mtd->erasesize));
if (ret) {
pr_err("Erase block is bad, mark it.\n");
ret = mtd_block_markbad(mtd, erase_offset);
@@ -255,12 +254,12 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
continue;
}
priv->erase_offset[i] = erase_offset + mtd->erasesize;
priv->erase_offset[i] = erase_offset + ROUNDUP(len, mtd->erasesize);
erase_offset = priv->erase_offset[i];
}
pbuf = wbuf;
while (dolen < data_len) {
while (dolen < len) {
if (!data_is_blank(offset + dolen, pbuf + mtd->writesize, 64)) {
if (mtd_block_isbad(mtd, ALIGN_DOWN(offset, mtd->erasesize))) {
pr_err(" Write block is bad, skip it.\n");
@@ -283,7 +282,7 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
pbuf += fwc->block_size;
dolen += mtd->writesize;
}
priv->start_offset[i] = offset + data_len;
priv->start_offset[i] = offset + len;
}
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
@@ -325,9 +324,10 @@ s32 nand_fwc_mtd_write(struct fwc_info *fwc, u8 *buf, s32 len)
pr_err("Erase block is bad, skip it.\n");
priv->erase_offset[i] = erase_offset + mtd->erasesize;
erase_offset = priv->erase_offset[i];
continue;
}
ret = mtd_erase(mtd, erase_offset, mtd->erasesize);
ret = mtd_erase(mtd, erase_offset, ROUNDUP(len, mtd->erasesize));
if (ret) {
pr_err("Erase block is bad, mark it.\n");
ret = mtd_block_markbad(mtd, erase_offset);
@@ -336,7 +336,7 @@ s32 nand_fwc_mtd_write(struct fwc_info *fwc, u8 *buf, s32 len)
continue;
}
priv->erase_offset[i] = erase_offset + mtd->erasesize;
priv->erase_offset[i] = erase_offset + ROUNDUP(len, mtd->erasesize);
erase_offset = priv->erase_offset[i];
}

View File

@@ -65,12 +65,21 @@ static s32 get_good_blocks_for_spl(struct mtd_dev *mtd, u32 *spl_blocks,
ulong offset;
s32 i, blkidx, ret = 0, cnt = 0;
u8 buf[2];
struct aic_spinand *flash = (struct aic_spinand *)mtd->priv;
for (i = 0; i < num; i++)
spl_blocks[i] = SPL_INVALID_BLOCK_IDX;
for (i = 0; i < SPL_CANDIDATE_BLOCK_NUM; i++) {
blkidx = spl_candidate_block_table[i];
/* For multi-plane device, don't use block 1 & 3, because
* boot rom cannot read data from block 1 and 3
*/
if ((flash->info->planes_per_lun != 1) &&
(blkidx == 1 || blkidx == 3))
continue;
offset = mtd->erasesize * blkidx;
if (mtd_block_isbad(mtd, offset)) {
pr_err("Block %d is bad.\n", blkidx);

View File

@@ -142,12 +142,12 @@ s32 nor_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
/* erase 1 sector when offset+len more than erased address */
erase_offset = priv->erase_offset[i];
while ((offset + len) > erase_offset) {
ret = mtd_erase(mtd, erase_offset, mtd->erasesize);
ret = mtd_erase(mtd, erase_offset, ROUNDUP(len, mtd->erasesize));
if (ret) {
pr_err("MTD erase sector failed!\n");
return 0;
}
priv->erase_offset[i] = erase_offset + mtd->erasesize;
priv->erase_offset[i] = erase_offset + ROUNDUP(len, mtd->erasesize);
erase_offset = priv->erase_offset[i];
}

View File

@@ -111,6 +111,7 @@ s32 aicupg_fat_write(char *image_name, char *protection,
int i, cnt, ret;
u32 start_us;
ulong actread, write_len = 0;
u64 total_len = 0;
pmeta = NULL;
pmeta = (struct fwc_meta *)aicos_malloc_align(0, header->meta_size, FRAME_LIST_SIZE);
@@ -155,12 +156,13 @@ s32 aicupg_fat_write(char *image_name, char *protection,
write_len += ret;
}
total_len = write_len;
start_us = aic_get_time_us() - start_us;
printf("All firmaware components programming done.\n");
printf(" Used time: %d.%d sec, Speed: %ld.%ld MB/s.\n",
printf(" Used time: %u.%u sec, Speed: %lu.%lu MB/s.\n",
start_us / 1000000, start_us / 1000 % 1000,
(write_len * 1000000 / start_us) / 1024 / 1024,
(write_len * 1000000 / start_us) / 1024 % 1024);
(ulong)((total_len * 1000000 / start_us) / 1024 / 1024),
(ulong)((total_len * 1000000 / start_us) / 1024 % 1024));
aicos_free_align(0, pmeta);
return write_len;

View File

@@ -115,6 +115,7 @@ struct fwc_info {
u32 calc_partition_crc;
s32 burn_result;
s32 run_result;
u32 start_us;
void *priv;
};

View File

@@ -651,7 +651,7 @@ static s32 fat_read_from_fatfs(struct fat_volume *vol, char *filename,
s32 ret;
/* Reuse one global var to reduce memory use */
file = malloc(sizeof(struct fat_file));
file = aicos_malloc_align(0, sizeof(struct fat_file), CACHE_LINE_SIZE);
if (!file) {
pr_err("malloc fat file failed.\n");
return -1;
@@ -695,12 +695,12 @@ static s32 fat_read_from_fatfs(struct fat_volume *vol, char *filename,
*actread = min((u32)file->size, (u32)maxsize);
free(file);
aicos_free(0, file);
return 0;
out:
if (file)
free(file);
aicos_free(0, file);
return ret;
}

View File

@@ -15,8 +15,11 @@
#include <aic_core.h>
#include <libfdt.h>
#include <hexdump.h>
#include <aic_crc32.h>
#include "fitimage.h"
//#define CRC32_MTD_READ
int fit_find_config_node(const void *fdt)
{
const char *name;
@@ -237,6 +240,9 @@ int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry);
}
/*
* offset: The offset relative to the itb file start location
*/
static int spl_read(struct spl_load_info *info, ulong offset, void *buf, int size)
{
int rdlen = 0;
@@ -261,6 +267,14 @@ static int spl_read(struct spl_load_info *info, ulong offset, void *buf, int siz
rdlen = info->bl_len * blkcnt;
rdlen = min(rdlen, size);
#endif
} else if (info->dev_type == DEVICE_XIPNOR) {
ulong xip_base = (ulong)info->priv;
int i;
for (i = 0; i < size; i++)
*(u8 *)(buf + i) = *(u8 *)(xip_base + offset + i);
rdlen = size;
}
return rdlen;
@@ -294,22 +308,27 @@ int spl_load_fit_image(struct spl_load_info *info, struct spl_fit_info *ctx, int
if (external_data)
{
if (fit_image_get_data_size(fit, node, &length))
return -1;
goto __get_entry;
start_us = aic_get_time_us();
ret = spl_read(info, offset, (u8 *)load_addr, length);
show_speed("spl read", length, aic_get_time_us() - start_us);
if (info->dev_type == DEVICE_XIPNOR && load_addr >= 0x60000000)
goto __get_entry;
else
{
start_us = aic_get_time_us();
ret = spl_read(info, offset, (u8 *)load_addr, length);
show_speed("spl read", length, aic_get_time_us() - start_us);
#ifdef CRC32_MTD_READ
unsigned int crc32_val = crc32(0, NULL, 0);
crc32_val = crc32(crc32_val, (u8 *)load_addr, length);
printf("mtd read crc32 = 0x%x KB/s\n", crc32_val);
unsigned int crc32_val = crc32(0, NULL, 0);
crc32_val = crc32(crc32_val, (u8 *)load_addr, length);
printf("mtd read crc32 = 0x%x KB/s\n", crc32_val);
#endif
if (ret < 0)
{
printf("spl read external_data error\n");
return -1;
if (ret < 0)
{
printf("spl read external_data error\n");
return -1;
}
}
}
else
@@ -318,6 +337,7 @@ int spl_load_fit_image(struct spl_load_info *info, struct spl_fit_info *ctx, int
return -1;
}
__get_entry:
if (entry_point)
{
if (fit_image_get_entry(fit, node, entry_point))