Skip to content

Commit

Permalink
[xfel]add splwrite command support
Browse files Browse the repository at this point in the history
  • Loading branch information
jianjunjiang committed Dec 10, 2021
1 parent 04ec56b commit f0f1319
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 18 deletions.
52 changes: 34 additions & 18 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,25 @@ static void usage(void)
{
printf("xfel(v1.2.1) - https://github.com/xboot/xfel\r\n");
printf("usage:\r\n");
printf(" xfel version - Show chip version\r\n");
printf(" xfel hexdump <address> <length> - Dumps memory region in hex\r\n");
printf(" xfel dump <address> <length> - Binary memory dump to stdout\r\n");
printf(" xfel exec <address> - Call function address\r\n");
printf(" xfel read32 <address> - Read 32-bits value from device memory\r\n");
printf(" xfel write32 <address> <value> - Write 32-bits value to device memory\r\n");
printf(" xfel read <address> <length> <file> - Read memory to file\r\n");
printf(" xfel write <address> <file> - Write file to memory\r\n");
printf(" xfel reset - Reset device using watchdog\r\n");
printf(" xfel sid - Show sid information\r\n");
printf(" xfel jtag - Enable jtag debug\r\n");
printf(" xfel ddr [type] - Initial ddr controller with optional type\r\n");
printf(" xfel spinor - Detect spi nor flash\r\n");
printf(" xfel spinor read <address> <length> <file> - Read spi nor flash to file\r\n");
printf(" xfel spinor write <address> <file> - Write file to spi nor flash\r\n");
printf(" xfel spinand - Detect spi nand flash\r\n");
printf(" xfel spinand read <address> <length> <file> - Read spi nand flash to file\r\n");
printf(" xfel spinand write <address> <file> - Write file to spi nand flash\r\n");
printf(" xfel version - Show chip version\r\n");
printf(" xfel hexdump <address> <length> - Dumps memory region in hex\r\n");
printf(" xfel dump <address> <length> - Binary memory dump to stdout\r\n");
printf(" xfel exec <address> - Call function address\r\n");
printf(" xfel read32 <address> - Read 32-bits value from device memory\r\n");
printf(" xfel write32 <address> <value> - Write 32-bits value to device memory\r\n");
printf(" xfel read <address> <length> <file> - Read memory to file\r\n");
printf(" xfel write <address> <file> - Write file to memory\r\n");
printf(" xfel reset - Reset device using watchdog\r\n");
printf(" xfel sid - Show sid information\r\n");
printf(" xfel jtag - Enable jtag debug\r\n");
printf(" xfel ddr [type] - Initial ddr controller with optional type\r\n");
printf(" xfel spinor - Detect spi nor flash\r\n");
printf(" xfel spinor read <address> <length> <file> - Read spi nor flash to file\r\n");
printf(" xfel spinor write <address> <file> - Write file to spi nor flash\r\n");
printf(" xfel spinand - Detect spi nand flash\r\n");
printf(" xfel spinand read <address> <length> <file> - Read spi nand flash to file\r\n");
printf(" xfel spinand write <address> <file> - Write file to spi nand flash\r\n");
printf(" xfel spinand splwrite <valid-page-size> <address> <file> - Write file to spi nand flash with spl mode\r\n");
}

int main(int argc, char * argv[])
Expand Down Expand Up @@ -383,6 +384,21 @@ int main(int argc, char * argv[])
free(buf);
}
}
else if(!strcmp(argv[0], "splwrite") && (argc == 4))
{
argc -= 1;
argv += 1;
uint32_t pagesz = strtoul(argv[0], NULL, 0);
uint64_t addr = strtoull(argv[1], NULL, 0);
uint64_t len;
void * buf = file_load(argv[2], &len);
if(buf)
{
if(!spinand_splwrite(&ctx, pagesz, addr, buf, len))
printf("Can't write spi nand flash with spl mode\r\n");
free(buf);
}
}
else
usage();
}
Expand Down
116 changes: 116 additions & 0 deletions spinand.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,3 +488,119 @@ int spinand_write(struct xfel_ctx_t * ctx, uint64_t addr, void * buf, uint64_t l
}
return 0;
}

int spinand_splwrite(struct xfel_ctx_t * ctx, uint32_t pagesz, uint64_t addr, void * buf, uint64_t len)
{
struct spinand_pdata_t pdat;
struct progress_t p;
uint64_t base, n;
int64_t cnt;
uint32_t esize, emask;
void * nbuf;
uint64_t nlen;

if(spinand_helper_init(ctx, &pdat))
{
esize = pdat.info.page_size * pdat.info.pages_per_block;
emask = esize - 1;
if((pagesz <= 0) || (pagesz > pdat.info.page_size))
pagesz = pdat.info.page_size;
if(pagesz & 0x3ff)
{
printf("The valid page size is not 1k alignable and thus not supported\r\n");
return 0;
}
uint8_t * pbuf = buf;
if(memcmp(&pbuf[4], "eGON.BT0", 8) != 0)
{
printf("Invalid a eGON boot image\r\n");
return 0;
}
uint32_t splsz = (pbuf[19] << 24) | (pbuf[18] << 16) | (pbuf[17] << 8) | (pbuf[16] << 0);
if(splsz > len)
{
printf("The spl size is too large, please check!\r\n");
return 0;
}
uint32_t tsplsz = (splsz * pdat.info.page_size / pagesz + esize) & ~emask;
if(addr >= tsplsz)
{
int copies = 0;
nlen = 0;
while(nlen < addr)
{
nlen += tsplsz;
copies++;
}
nlen += len;
nbuf = malloc(nlen);
if(nbuf)
{
uint8_t * pb = buf;
uint8_t * pnb = nbuf;
memset(pnb, 0xff, nlen);
for(int i = 0; i < splsz; i += pagesz)
{
memcpy(pnb, pb, pagesz);
pb += pagesz;
pnb += pdat.info.page_size;
}
for(int i = 1; i < copies; i++)
{
memcpy(nbuf + tsplsz * i, nbuf, tsplsz);
}
memcpy(nbuf + (nlen - len), buf, len);
}
else
return 0;
}
else
{
nlen = tsplsz;
nbuf = malloc(nlen);
if(nbuf)
{
uint8_t * pb = buf;
uint8_t * pnb = nbuf;
memset(pnb, 0xff, nlen);
for(int i = 0; i < splsz; i += pagesz)
{
memcpy(pnb, pb, pagesz);
pb += pagesz;
pnb += pdat.info.page_size;
}
}
else
return 0;
}
uint8_t * pnbuf = nbuf;
base = 0 & ~emask;
cnt = ((0 & emask) + nlen + esize) & ~emask;
progress_start(&p, cnt);
while(cnt > 0)
{
n = cnt > esize ? esize : cnt;
spinand_helper_erase(ctx, &pdat, base, n);
base += n;
cnt -= n;
progress_update(&p, n);
}
base = 0;
cnt = nlen;
progress_start(&p, cnt);
while(cnt > 0)
{
n = cnt > 65536 ? 65536 : cnt;
spinand_helper_write(ctx, &pdat, base, pnbuf, n);
base += n;
cnt -= n;
pnbuf += n;
progress_update(&p, n);
}
progress_stop(&p);
if(nbuf)
free(nbuf);
return 1;
}
return 0;
}
1 change: 1 addition & 0 deletions spinand.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern "C" {
int spinand_detect(struct xfel_ctx_t * ctx, char * name, uint64_t * capacity);
int spinand_read(struct xfel_ctx_t * ctx, uint64_t addr, void * buf, uint64_t len);
int spinand_write(struct xfel_ctx_t * ctx, uint64_t addr, void * buf, uint64_t len);
int spinand_splwrite(struct xfel_ctx_t * ctx, uint32_t pagesz, uint64_t addr, void * buf, uint64_t len);

#ifdef __cplusplus
}
Expand Down

0 comments on commit f0f1319

Please sign in to comment.