xrock/main.c
2024-09-30 18:20:48 +08:00

1002 lines
26 KiB
C

#include <rock.h>
static const char * manufacturer[] = {
"Samsung",
"Toshiba",
"Hynix",
"Infineon",
"Micron",
"Renesas",
"ST",
"Intel",
"SanDisk",
};
static void usage(void)
{
printf("xrock(v1.1.3) - https://github.com/xboot/xrock\r\n");
printf(" Copyright(c) Jianjun Jiang <8192542@qq.com>\r\n");
printf(" Mobile phone: +86-18665388956\r\n");
printf(" QQ: 8192542\r\n");
printf("usage:\r\n");
printf(" xrock maskrom <ddr> <usbplug> [--rc4-off] - Initial chip using ddr and usbplug in maskrom mode\r\n");
printf(" xrock download <loader> - Initial chip using loader in maskrom mode\r\n");
printf(" xrock upgrade <loader> - Upgrade loader to flash in loader mode\r\n");
printf(" xrock ready - Show chip ready or not\r\n");
printf(" xrock version - Show chip version\r\n");
printf(" xrock capability - Show capability information\r\n");
printf(" xrock reset [maskrom] - Reset chip to normal or maskrom mode\n");
printf(" xrock dump <address> <length> - Dump memory region in hex format\r\n");
printf(" xrock read <address> <length> <file> - Read memory to file\r\n");
printf(" xrock write <address> <file> - Write file to memory\r\n");
printf(" xrock exec <address> [dtb] - Call function address(Recommend to use extra command)\r\n");
printf(" xrock otp <length> - Dump otp memory in hex format\r\n");
printf(" xrock sn - Read serial number\r\n");
printf(" xrock sn <string> - Write serial number\r\n");
printf(" xrock vs dump <index> <length> [type] - Dump vendor storage in hex format\r\n");
printf(" xrock vs read <index> <length> <file> [type] - Read vendor storage\r\n");
printf(" xrock vs write <index> <file> [type] - Write vendor storage\r\n");
printf(" xrock storage - Read storage media list\r\n");
printf(" xrock storage <index> - Switch storage media and show list\r\n");
printf(" xrock flash - Detect flash and show information\r\n");
printf(" xrock flash erase <sector> <count> - Erase flash sector\r\n");
printf(" xrock flash read <sector> <count> <file> - Read flash sector to file\r\n");
printf(" xrock flash write <sector> <file> - Write file to flash sector\r\n");
printf("extra:\r\n");
printf(" xrock extra maskrom --rc4 <on|off> [--sram <file> --delay <ms>] [--dram <file> --delay <ms>] [...]\r\n");
printf(" xrock extra maskrom-dump-arm32 --rc4 <on|off> --uart <register> <address> <length>\r\n");
printf(" xrock extra maskrom-dump-arm64 --rc4 <on|off> --uart <register> <address> <length>\r\n");
printf(" xrock extra maskrom-write-arm32 --rc4 <on|off> <address> <file>\r\n");
printf(" xrock extra maskrom-write-arm64 --rc4 <on|off> <address> <file>\r\n");
printf(" xrock extra maskrom-exec-arm32 --rc4 <on|off> <address>\r\n");
printf(" xrock extra maskrom-exec-arm64 --rc4 <on|off> <address>\r\n");
}
int main(int argc, char * argv[])
{
struct xrock_ctx_t ctx;
if(argc < 2)
{
usage();
return 0;
}
for(int i = 1; i < argc; i++)
{
if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
{
usage();
return 0;
}
}
libusb_init(&ctx.context);
if(!xrock_init(&ctx))
{
printf("ERROR: Can't found any supported rockchip chips\r\n");
if(ctx.hdl)
libusb_close(ctx.hdl);
libusb_exit(ctx.context);
return -1;
}
if(!strcmp(argv[1], "maskrom"))
{
argc -= 2;
argv += 2;
if(argc >= 2)
{
if(ctx.maskrom)
{
int rc4 = 1;
if((argc == 3) && !strcmp(argv[2], "--rc4-off"))
rc4 = 0;
rock_maskrom_upload_file(&ctx, 0x471, argv[0], rc4);
usleep(10 * 1000);
rock_maskrom_upload_file(&ctx, 0x472, argv[1], rc4);
usleep(10 * 1000);
}
else
printf("ERROR: The chip '%s' does not in maskrom mode\r\n", ctx.chip->name);
}
else
usage();
}
else if(!strcmp(argv[1], "download"))
{
argc -= 2;
argv += 2;
if(argc == 1)
{
if(ctx.maskrom)
{
struct rkloader_ctx_t * lctx = rkloader_ctx_alloc(argv[0]);
if(lctx)
{
for(int i = 0; i < lctx->nentry; i++)
{
struct rkloader_entry_t * e = lctx->entry[i];
char str[256];
if(e->type == RKLOADER_ENTRY_471)
{
void * buf = (char *)lctx->buffer + get_unaligned_le32(&e->data_offset);
uint64_t len = get_unaligned_le32(&e->data_size);
uint32_t delay = get_unaligned_le32(&e->data_delay);
printf("Downloading '%s'\r\n", loader_wide2str(str, (uint8_t *)&e->name[0], sizeof(e->name)));
rock_maskrom_upload_memory(&ctx, 0x471, buf, len, lctx->is_rc4on);
usleep(delay * 1000);
}
else if(e->type == RKLOADER_ENTRY_472)
{
void * buf = (char *)lctx->buffer + get_unaligned_le32(&e->data_offset);
uint64_t len = get_unaligned_le32(&e->data_size);
uint32_t delay = get_unaligned_le32(&e->data_delay);
printf("Downloading '%s'\r\n", loader_wide2str(str, (uint8_t *)&e->name[0], sizeof(e->name)));
rock_maskrom_upload_memory(&ctx, 0x472, buf, len, lctx->is_rc4on);
usleep(delay * 1000);
}
}
rkloader_ctx_free(lctx);
}
else
printf("ERROR: Not a valid loader '%s'\r\n", argv[0]);
}
else
printf("ERROR: The chip '%s' does not in maskrom mode\r\n", ctx.chip->name);
}
else
usage();
}
else if(!strcmp(argv[1], "upgrade"))
{
argc -= 2;
argv += 2;
if(argc == 1)
{
struct rkloader_ctx_t * lctx = rkloader_ctx_alloc(argv[0]);
if(lctx)
{
uint32_t sec = 64;
enum storage_type_t type = rock_storage_read(&ctx);
switch(type)
{
case STORAGE_TYPE_FLASH:
sec = 64;
break;
case STORAGE_TYPE_EMMC:
sec = 64;
break;
case STORAGE_TYPE_SD:
sec = 64;
break;
case STORAGE_TYPE_SD1:
sec = 64;
break;
case STORAGE_TYPE_SPINOR:
sec = 128;
break;
case STORAGE_TYPE_SPINAND:
sec = 512;
break;
case STORAGE_TYPE_RAM:
sec = 64;
break;
case STORAGE_TYPE_USB:
sec = 64;
break;
case STORAGE_TYPE_SATA:
sec = 64;
break;
case STORAGE_TYPE_PCIE:
sec = 64;
break;
default:
break;
}
struct flash_info_t info;
if(rock_flash_detect(&ctx, &info))
{
if(!rock_flash_write_lba_progress(&ctx, sec, lctx->idblen / 512, lctx->idbbuf))
printf("Failed to write flash\r\n");
}
else
printf("Failed to detect flash\r\n");
rkloader_ctx_free(lctx);
}
else
printf("ERROR: Not a valid loader '%s'\r\n", argv[0]);
}
else
usage();
}
else if(!strcmp(argv[1], "ready"))
{
argc -= 2;
argv += 2;
if(argc == 0)
{
if(rock_ready(&ctx))
printf("The chip is ready\r\n");
else
printf("Failed to show chip ready status\r\n");
}
else
usage();
}
else if(!strcmp(argv[1], "version"))
{
argc -= 2;
argv += 2;
if(argc == 0)
{
uint8_t buf[16];
if(rock_version(&ctx, buf))
printf("%s(%c%c%c%c): 0x%02x%02x%02x%02x 0x%02x%02x%02x%02x 0x%02x%02x%02x%02x 0x%02x%02x%02x%02x\r\n", ctx.chip->name,
buf[ 3], buf[ 2], buf[ 1], buf[ 0],
buf[ 3], buf[ 2], buf[ 1], buf[ 0],
buf[ 7], buf[ 6], buf[ 5], buf[ 4],
buf[11], buf[10], buf[ 9], buf[ 8],
buf[15], buf[14], buf[13], buf[12]);
else
printf("Failed to get chip version\r\n");
}
else
usage();
}
else if(!strcmp(argv[1], "capability"))
{
argc -= 2;
argv += 2;
if(argc == 0)
{
uint8_t buf[8];
if(rock_capability(&ctx, buf))
{
printf("Capability: %02x %02x %02x %02x %02x %02x %02x %02x\r\n",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
printf(" Direct LBA: %s\r\n", (buf[0] & (1 << 0)) ? "enabled" : "disabled");
printf(" Vendor Storage: %s\r\n", (buf[0] & (1 << 1)) ? "enabled" : "disabled");
printf(" First 4M Access: %s\r\n", (buf[0] & (1 << 2)) ? "enabled" : "disabled");
printf(" Read LBA: %s\r\n", (buf[0] & (1 << 3)) ? "enabled" : "disabled");
printf(" New Vendor Storage: %s\r\n", (buf[0] & (1 << 4)) ? "enabled" : "disabled");
printf(" Read Com Log: %s\r\n", (buf[0] & (1 << 5)) ? "enabled" : "disabled");
printf(" Read IDB Config: %s\r\n", (buf[0] & (1 << 6)) ? "enabled" : "disabled");
printf(" Read Secure Mode: %s\r\n", (buf[0] & (1 << 7)) ? "enabled" : "disabled");
printf(" New IDB: %s\r\n", (buf[1] & (1 << 0)) ? "enabled" : "disabled");
printf(" Switch Storage: %s\r\n", (buf[1] & (1 << 1)) ? "enabled" : "disabled");
printf(" LBA Parity: %s\r\n", (buf[1] & (1 << 2)) ? "enabled" : "disabled");
printf(" Read OTP Chip: %s\r\n", (buf[1] & (1 << 3)) ? "enabled" : "disabled");
printf(" Switch USB3: %s\r\n", (buf[1] & (1 << 4)) ? "enabled" : "disabled");
}
else
printf("Failed to show capability information\r\n");
}
else
usage();
}
else if(!strcmp(argv[1], "reset"))
{
argc -= 2;
argv += 2;
if(argc > 0)
{
if(!strcmp(argv[0], "maskrom"))
rock_reset(&ctx, 1);
else
usage();
}
else
rock_reset(&ctx, 0);
}
else if(!strcmp(argv[1], "dump"))
{
argc -= 2;
argv += 2;
if(argc == 2)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
size_t len = strtoul(argv[1], NULL, 0);
char * buf = malloc(len);
if(buf)
{
rock_read(&ctx, addr, buf, len);
hexdump(addr, buf, len);
free(buf);
}
}
else
usage();
}
else if(!strcmp(argv[1], "read"))
{
argc -= 2;
argv += 2;
if(argc == 3)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
size_t len = strtoul(argv[1], NULL, 0);
char * buf = malloc(len);
if(buf)
{
rock_read_progress(&ctx, addr, buf, len);
file_save(argv[2], buf, len);
free(buf);
}
}
else
usage();
}
else if(!strcmp(argv[1], "write"))
{
argc -= 2;
argv += 2;
if(argc == 2)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
uint64_t len;
void * buf = file_load(argv[1], &len);
if(buf)
{
rock_write_progress(&ctx, addr, buf, len);
free(buf);
}
}
else
usage();
}
else if(!strcmp(argv[1], "exec"))
{
argc -= 2;
argv += 2;
if(argc >= 1)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
uint32_t dtb = (argc >= 2) ? strtoul(argv[1], NULL, 0) : 0;
rock_exec(&ctx, addr, dtb);
}
else
usage();
}
else if(!strcmp(argv[1], "otp"))
{
if(rock_capability_support(&ctx, CAPABILITY_TYPE_READ_OTP_CHIP))
{
argc -= 2;
argv += 2;
if(argc == 1)
{
int len = strtoul(argv[0], NULL, 0);
if(len > 0)
{
uint8_t * otp = malloc(len);
if(otp)
{
if(rock_otp_read(&ctx, otp, len))
hexdump(0, otp, len);
free(otp);
}
}
}
else
usage();
}
else
printf("The loader don't support dump otp\r\n");
}
else if(!strcmp(argv[1], "sn"))
{
if(rock_capability_support(&ctx, CAPABILITY_TYPE_VENDOR_STORAGE) || rock_capability_support(&ctx, CAPABILITY_TYPE_NEW_VENDOR_STORAGE))
{
argc -= 2;
argv += 2;
if(argc == 0)
{
char sn[512 - 8 + 1];
if(rock_sn_read(&ctx, sn))
printf("SN: %s\r\n", sn);
else
printf("No serial number\r\n");
}
else
{
if(argc == 1)
{
if(rock_sn_write(&ctx, argv[0]))
printf("Write serial number '%s'\r\n", argv[0]);
else
printf("Failed to write serial number\r\n");
}
else
usage();
}
}
else
printf("The loader don't support vendor storage\r\n");
}
else if(!strcmp(argv[1], "vs"))
{
if(rock_capability_support(&ctx, CAPABILITY_TYPE_VENDOR_STORAGE) || rock_capability_support(&ctx, CAPABILITY_TYPE_NEW_VENDOR_STORAGE))
{
argc -= 2;
argv += 2;
if(argc > 0)
{
if(!strcmp(argv[0], "dump") && (argc >= 3))
{
int index = strtoul(argv[1], NULL, 0);
int len = XMIN((int)strtoul(argv[2], NULL, 0), 512);
int type = (argc == 4) ? strtoul(argv[3], NULL, 0) : 0;
if(len > 0)
{
uint8_t * buf = malloc(len);
if(buf)
{
if(rock_vs_read(&ctx, type, index, buf, len))
hexdump(0, buf, len);
free(buf);
}
}
}
else if(!strcmp(argv[0], "read") && (argc >= 4))
{
int index = strtoul(argv[1], NULL, 0);
int len = XMIN((int)strtoul(argv[2], NULL, 0), 512);
int type = (argc == 5) ? strtoul(argv[4], NULL, 0) : 0;
if(len > 0)
{
uint8_t * buf = malloc(len);
if(buf)
{
if(rock_vs_read(&ctx, type, index, buf, len))
file_save(argv[3], buf, len);
free(buf);
}
}
}
else if(!strcmp(argv[0], "write") && (argc >= 3))
{
int index = strtoul(argv[1], NULL, 0);
int type = (argc == 4) ? strtoul(argv[3], NULL, 0) : 0;
uint64_t len;
void * buf = file_load(argv[2], &len);
if(buf && (len > 0))
{
if(!rock_vs_write(&ctx, type, index, buf, (len > 512) ? 512 : len))
printf("Failed to write vendor storage\r\n");
free(buf);
}
}
else
usage();
}
else
usage();
}
else
printf("The loader don't support vendor storage\r\n");
}
else if(!strcmp(argv[1], "storage"))
{
argc -= 2;
argv += 2;
if(argc == 0)
{
enum storage_type_t type = rock_storage_read(&ctx);
printf("%s 0.UNKNOWN\r\n", (type == STORAGE_TYPE_UNKNOWN) ? "-->" : " ");
printf("%s 1.FLASH\r\n", (type == STORAGE_TYPE_FLASH) ? "-->" : " ");
printf("%s 2.EMMC\r\n", (type == STORAGE_TYPE_EMMC) ? "-->" : " ");
printf("%s 3.SD\r\n", (type == STORAGE_TYPE_SD) ? "-->" : " ");
printf("%s 4.SD1\r\n", (type == STORAGE_TYPE_SD1) ? "-->" : " ");
printf("%s 5.SPINOR\r\n", (type == STORAGE_TYPE_SPINOR) ? "-->" : " ");
printf("%s 6.SPINAND\r\n", (type == STORAGE_TYPE_SPINAND) ? "-->" : " ");
printf("%s 7.RAM\r\n", (type == STORAGE_TYPE_RAM) ? "-->" : " ");
printf("%s 8.USB\r\n", (type == STORAGE_TYPE_USB) ? "-->" : " ");
printf("%s 9.SATA\r\n", (type == STORAGE_TYPE_SATA) ? "-->" : " ");
printf("%s10.PCIE\r\n", (type == STORAGE_TYPE_PCIE) ? "-->" : " ");
}
else
{
if(rock_capability_support(&ctx, CAPABILITY_TYPE_SWITCH_STORAGE))
{
if(argc == 1)
{
enum storage_type_t type = STORAGE_TYPE_UNKNOWN;
int index = strtol(argv[0], NULL, 0);
switch(index)
{
case 0:
type = STORAGE_TYPE_UNKNOWN;
break;
case 1:
type = STORAGE_TYPE_FLASH;
break;
case 2:
type = STORAGE_TYPE_EMMC;
break;
case 3:
type = STORAGE_TYPE_SD;
break;
case 4:
type = STORAGE_TYPE_SD1;
break;
case 5:
type = STORAGE_TYPE_SPINOR;
break;
case 6:
type = STORAGE_TYPE_SPINAND;
break;
case 7:
type = STORAGE_TYPE_RAM;
break;
case 8:
type = STORAGE_TYPE_USB;
break;
case 9:
type = STORAGE_TYPE_SATA;
break;
case 10:
type = STORAGE_TYPE_PCIE;
break;
default:
break;
}
rock_storage_switch(&ctx, type);
type = rock_storage_read(&ctx);
printf("%s 0.UNKNOWN\r\n", (type == STORAGE_TYPE_UNKNOWN) ? "-->" : " ");
printf("%s 1.FLASH\r\n", (type == STORAGE_TYPE_FLASH) ? "-->" : " ");
printf("%s 2.EMMC\r\n", (type == STORAGE_TYPE_EMMC) ? "-->" : " ");
printf("%s 3.SD\r\n", (type == STORAGE_TYPE_SD) ? "-->" : " ");
printf("%s 4.SD1\r\n", (type == STORAGE_TYPE_SD1) ? "-->" : " ");
printf("%s 5.SPINOR\r\n", (type == STORAGE_TYPE_SPINOR) ? "-->" : " ");
printf("%s 6.SPINAND\r\n", (type == STORAGE_TYPE_SPINAND) ? "-->" : " ");
printf("%s 7.RAM\r\n", (type == STORAGE_TYPE_RAM) ? "-->" : " ");
printf("%s 8.USB\r\n", (type == STORAGE_TYPE_USB) ? "-->" : " ");
printf("%s 9.SATA\r\n", (type == STORAGE_TYPE_SATA) ? "-->" : " ");
printf("%s10.PCIE\r\n", (type == STORAGE_TYPE_PCIE) ? "-->" : " ");
}
else
usage();
}
else
printf("The loader don't support switch storage\r\n");
}
}
else if(!strcmp(argv[1], "flash"))
{
argc -= 2;
argv += 2;
if(argc == 0)
{
struct flash_info_t info;
if(rock_flash_detect(&ctx, &info))
{
printf("Flash info:\r\n");
printf(" Manufacturer: %s (%d)\r\n", (info.manufacturer_id < ARRAY_SIZE(manufacturer))
? manufacturer[info.manufacturer_id] : "Unknown", info.manufacturer_id);
printf(" Capacity: %dMB\r\n", info.sector_total >> 11);
printf(" Sector size: %d\r\n", 512);
printf(" Sector count: %d\r\n", info.sector_total);
printf(" Block size: %dKB\r\n", info.block_size >> 1);
printf(" Page size: %dKB\r\n", info.page_size >> 1);
printf(" ECC bits: %d\r\n", info.ecc_bits);
printf(" Access time: %d\r\n", info.access_time);
printf(" Flash CS: %s%s%s%s\r\n",
info.chip_select & 1 ? "<0>" : "",
info.chip_select & 2 ? "<1>" : "",
info.chip_select & 4 ? "<2>" : "",
info.chip_select & 8 ? "<3>" : "");
printf(" Flash ID: %02x %02x %02x %02x %02x\r\n",
info.id[0], info.id[1], info.id[2], info.id[3], info.id[4]);
}
else
printf("Failed to detect flash\r\n");
}
else
{
if(!strcmp(argv[0], "erase") && (argc == 3))
{
argc -= 1;
argv += 1;
struct flash_info_t info;
uint32_t sec = strtoul(argv[0], NULL, 0);
uint32_t cnt = strtoul(argv[1], NULL, 0);
if(rock_flash_detect(&ctx, &info))
{
if(sec < info.sector_total)
{
if(cnt <= 0)
cnt = info.sector_total - sec;
else if(cnt > info.sector_total - sec)
cnt = info.sector_total - sec;
if(!rock_flash_erase_lba_progress(&ctx, sec, cnt))
printf("Failed to erase flash\r\n");
}
else
printf("The start sector is out of range\r\n");
}
else
printf("Failed to detect flash\r\n");
}
else if(!strcmp(argv[0], "read") && (argc == 4))
{
argc -= 1;
argv += 1;
struct flash_info_t info;
uint32_t sec = strtoul(argv[0], NULL, 0);
uint32_t cnt = strtoul(argv[1], NULL, 0);
if(rock_flash_detect(&ctx, &info))
{
if(sec < info.sector_total)
{
if(cnt <= 0)
cnt = info.sector_total - sec;
else if(cnt > info.sector_total - sec)
cnt = info.sector_total - sec;
if(!rock_flash_read_lba_to_file_progress(&ctx, sec, cnt, argv[2]))
printf("Failed to read flash\r\n");
}
else
printf("The start sector is out of range\r\n");
}
else
printf("Failed to detect flash\r\n");
}
else if(!strcmp(argv[0], "write") && (argc == 3))
{
argc -= 1;
argv += 1;
struct flash_info_t info;
uint32_t sec = strtoul(argv[0], NULL, 0);
if(rock_flash_detect(&ctx, &info))
{
if(sec < info.sector_total)
{
if(!rock_flash_write_lba_from_file_progress(&ctx, sec, info.sector_total, argv[1]))
printf("Failed to write flash\r\n");
}
else
printf("The start sector is out of range\r\n");
}
else
printf("Failed to detect flash\r\n");
}
else
usage();
}
}
else if(!strcmp(argv[1], "extra"))
{
argc -= 2;
argv += 2;
if(!strcmp(argv[0], "maskrom"))
{
argc -= 1;
argv += 1;
if(argc >= 2)
{
if(ctx.maskrom)
{
int rc4 = 0;
for(int i = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--rc4") && (argc > i + 1))
{
if(!strcmp(argv[i + 1], "on"))
rc4 = 1;
else if(!strcmp(argv[i + 1], "off"))
rc4 = 0;
i++;
}
else if(!strcmp(argv[i], "--sram") && (argc > i + 1))
{
rock_maskrom_upload_file(&ctx, 0x471, argv[i + 1], rc4);
i++;
}
else if(!strcmp(argv[i], "--dram") && (argc > i + 1))
{
rock_maskrom_upload_file(&ctx, 0x472, argv[i + 1], rc4);
i++;
}
else if(!strcmp(argv[i], "--delay") && (argc > i + 1))
{
uint32_t delay = strtoul(argv[i + 1], NULL, 0) * 1000;
usleep(delay);
i++;
}
else if(*argv[i] == '-')
{
usage();
}
else if(*argv[i] != '-' && strcmp(argv[i], "-") != 0)
{
usage();
}
}
}
else
printf("ERROR: The chip '%s' does not in maskrom mode\r\n", ctx.chip->name);
}
else
usage();
}
else if(!strcmp(argv[0], "maskrom-dump-arm32"))
{
argc -= 1;
argv += 1;
if(argc >= 2)
{
if(ctx.maskrom)
{
int rc4 = 0;
uint32_t uart = 0x0;
uint32_t addr = 0x0;
uint32_t len = 0x0;
for(int i = 0, idx = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--rc4") && (argc > i + 1))
{
if(!strcmp(argv[i + 1], "on"))
rc4 = 1;
else if(!strcmp(argv[i + 1], "off"))
rc4 = 0;
i++;
}
else if(!strcmp(argv[i], "--uart") && (argc > i + 1))
{
uart = strtoul(argv[i + 1], NULL, 0);
i++;
}
else if(*argv[i] == '-')
{
usage();
}
else if(*argv[i] != '-' && strcmp(argv[i], "-") != 0)
{
if(idx == 0)
addr = strtoul(argv[i], NULL, 0);
else if(idx == 1)
len = strtoul(argv[i], NULL, 0);
idx++;
}
}
rock_maskrom_dump_arm32(&ctx, uart, addr, len, rc4);
}
else
printf("ERROR: The chip '%s' does not in maskrom mode\r\n", ctx.chip->name);
}
else
usage();
}
else if(!strcmp(argv[0], "maskrom-dump-arm64"))
{
argc -= 1;
argv += 1;
if(argc >= 2)
{
if(ctx.maskrom)
{
int rc4 = 0;
uint32_t uart = 0x0;
uint32_t addr = 0x0;
uint32_t len = 0x0;
for(int i = 0, idx = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--rc4") && (argc > i + 1))
{
if(!strcmp(argv[i + 1], "on"))
rc4 = 1;
else if(!strcmp(argv[i + 1], "off"))
rc4 = 0;
i++;
}
else if(!strcmp(argv[i], "--uart") && (argc > i + 1))
{
uart = strtoul(argv[i + 1], NULL, 0);
i++;
}
else if(*argv[i] == '-')
{
usage();
}
else if(*argv[i] != '-' && strcmp(argv[i], "-") != 0)
{
if(idx == 0)
addr = strtoul(argv[i], NULL, 0);
else if(idx == 1)
len = strtoul(argv[i], NULL, 0);
idx++;
}
}
rock_maskrom_dump_arm64(&ctx, uart, addr, len, rc4);
}
else
printf("ERROR: The chip '%s' does not in maskrom mode\r\n", ctx.chip->name);
}
else
usage();
}
else if(!strcmp(argv[0], "maskrom-write-arm32"))
{
argc -= 1;
argv += 1;
if(argc >= 2)
{
if(ctx.maskrom)
{
int rc4 = 0;
char * filename = NULL;
uint32_t addr = 0x0;
for(int i = 0, idx = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--rc4") && (argc > i + 1))
{
if(!strcmp(argv[i + 1], "on"))
rc4 = 1;
else if(!strcmp(argv[i + 1], "off"))
rc4 = 0;
i++;
}
else if(*argv[i] == '-')
{
usage();
}
else if(*argv[i] != '-' && strcmp(argv[i], "-") != 0)
{
if(idx == 0)
addr = strtoul(argv[i], NULL, 0);
else if(idx == 1)
filename = argv[i];
idx++;
}
}
uint64_t len;
void * buf = file_load(filename, &len);
if(buf)
{
rock_maskrom_write_arm32_progress(&ctx, addr, buf, len, rc4);
free(buf);
}
}
else
printf("ERROR: The chip '%s' does not in maskrom mode\r\n", ctx.chip->name);
}
else
usage();
}
else if(!strcmp(argv[0], "maskrom-write-arm64"))
{
argc -= 1;
argv += 1;
if(argc >= 2)
{
if(ctx.maskrom)
{
int rc4 = 0;
char * filename = NULL;
uint32_t addr = 0x0;
for(int i = 0, idx = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--rc4") && (argc > i + 1))
{
if(!strcmp(argv[i + 1], "on"))
rc4 = 1;
else if(!strcmp(argv[i + 1], "off"))
rc4 = 0;
i++;
}
else if(*argv[i] == '-')
{
usage();
}
else if(*argv[i] != '-' && strcmp(argv[i], "-") != 0)
{
if(idx == 0)
addr = strtoul(argv[i], NULL, 0);
else if(idx == 1)
filename = argv[i];
idx++;
}
}
uint64_t len;
void * buf = file_load(filename, &len);
if(buf)
{
rock_maskrom_write_arm64_progress(&ctx, addr, buf, len, rc4);
free(buf);
}
}
else
printf("ERROR: The chip '%s' does not in maskrom mode\r\n", ctx.chip->name);
}
else
usage();
}
else if(!strcmp(argv[0], "maskrom-exec-arm32"))
{
argc -= 1;
argv += 1;
if(argc >= 2)
{
if(ctx.maskrom)
{
int rc4 = 0;
uint32_t addr = 0x0;
for(int i = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--rc4") && (argc > i + 1))
{
if(!strcmp(argv[i + 1], "on"))
rc4 = 1;
else if(!strcmp(argv[i + 1], "off"))
rc4 = 0;
i++;
}
else if(*argv[i] == '-')
{
usage();
}
else if(*argv[i] != '-' && strcmp(argv[i], "-") != 0)
{
addr = strtoul(argv[i], NULL, 0);
}
}
rock_maskrom_exec_arm32(&ctx, addr, rc4);
}
else
printf("ERROR: The chip '%s' does not in maskrom mode\r\n", ctx.chip->name);
}
else
usage();
}
else if(!strcmp(argv[0], "maskrom-exec-arm64"))
{
argc -= 1;
argv += 1;
if(argc >= 2)
{
if(ctx.maskrom)
{
int rc4 = 0;
uint32_t addr = 0x0;
for(int i = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--rc4") && (argc > i + 1))
{
if(!strcmp(argv[i + 1], "on"))
rc4 = 1;
else if(!strcmp(argv[i + 1], "off"))
rc4 = 0;
i++;
}
else if(*argv[i] == '-')
{
usage();
}
else if(*argv[i] != '-' && strcmp(argv[i], "-") != 0)
{
addr = strtoul(argv[i], NULL, 0);
}
}
rock_maskrom_exec_arm64(&ctx, addr, rc4);
}
else
printf("ERROR: The chip '%s' does not in maskrom mode\r\n", ctx.chip->name);
}
else
usage();
}
else
usage();
}
else
usage();
if(ctx.hdl)
libusb_close(ctx.hdl);
libusb_exit(ctx.context);
return 0;
}