Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 97 additions & 10 deletions qdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ static void print_usage(FILE *out)
fprintf(out, "Usage: %s [options] <prog.mbn> (<program-xml> | <patch-xml> | <read-xml>)...\n", __progname);
fprintf(out, " %s [options] <prog.mbn> ((read | write) <address> <binary>)...\n", __progname);
fprintf(out, " %s list\n", __progname);
fprintf(out, " %s ramdump [--debug] [-o <ramdump-path>] [<segment-filter>,...]\n", __progname);
fprintf(out, " -d, --debug\t\t\tPrint detailed debug info\n");
fprintf(out, " -v, --version\t\t\tPrint the current version and exit\n");
fprintf(out, " -n, --dry-run\t\t\tDry run execution, no device reading or flashing\n");
Expand All @@ -428,12 +429,14 @@ static void print_usage(FILE *out)
fprintf(out, " -T, --slot=T\t\t\tSet slot number T for multiple storage devices\n");
fprintf(out, " -D, --vip-table-path=T\t\tUse digest tables in the T folder for VIP\n");
fprintf(out, " -h, --help\t\t\tPrint this usage info\n");
fprintf(out, " <program-xml>\txml file containing <program> or <erase> directives\n");
fprintf(out, " <patch-xml>\txml file containing <patch> directives\n");
fprintf(out, " <read-xml>\txml file containing <read> directives\n");
fprintf(out, " <address>\tdisk address specifier, can be one of <P>, <P/S>, <P/S+L>, <name>, or\n");
fprintf(out, " \t<P/name>, to specify a physical partition number P, a starting sector\n");
fprintf(out, " \tnumber S, the number of sectors to follow L, or partition by \"name\"\n");
fprintf(out, " <program-xml>\t\txml file containing <program> or <erase> directives\n");
fprintf(out, " <patch-xml>\t\txml file containing <patch> directives\n");
fprintf(out, " <read-xml>\t\txml file containing <read> directives\n");
fprintf(out, " <address>\t\tdisk address specifier, can be one of <P>, <P/S>, <P/S+L>, <name>, or\n");
fprintf(out, " \t\t<P/name>, to specify a physical partition number P, a starting sector\n");
fprintf(out, " \t\tnumber S, the number of sectors to follow L, or partition by \"name\"\n");
fprintf(out, " <ramdump-path>\t\tpath where ramdump should stored\n");
fprintf(out, " <segment-filter>\toptional glob-pattern to select which segments to ramdump\n");
fprintf(out, "\n");
fprintf(out, "Example: %s prog_firehose_ddr.elf rawprogram*.xml patch*.xml\n", __progname);
}
Expand Down Expand Up @@ -461,7 +464,84 @@ static int qdl_list(FILE *out)
return 0;
}

int main(int argc, char **argv)
static int qdl_ramdump(int argc, char **argv)
{
struct qdl_device *qdl;
char *ramdump_path = ".";
char *filter = NULL;
char *serial = NULL;
int ret = 0;
int opt;

static struct option options[] = {
{"debug", no_argument, 0, 'd'},
{"version", no_argument, 0, 'v'},
{"output", required_argument, 0, 'o'},
{"serial", required_argument, 0, 'S'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};

while ((opt = getopt_long(argc, argv, "dvo:S:h", options, NULL)) != -1) {
switch (opt) {
case 'd':
qdl_debug = true;
break;
case 'v':
print_version();
return 0;
case 'o':
ramdump_path = optarg;
break;
case 'S':
serial = optarg;
break;
case 'h':
print_usage(stdout);
return 0;
default:
print_usage(stderr);
return 1;
}
}

if (optind < argc)
filter = argv[optind++];

if (optind != argc) {
print_usage(stderr);
return 1;
}

ux_init();

qdl = qdl_init(QDL_DEVICE_USB);
if (!qdl)
return 1;

if (qdl_debug)
print_version();

ret = qdl_open(qdl, serial);
if (ret) {
ret = 1;
goto out_cleanup;
}

ret = sahara_run(qdl, NULL, ramdump_path, filter);
if (ret < 0) {
ret = 1;
goto out_cleanup;
}

out_cleanup:
qdl_close(qdl);
qdl_deinit(qdl);

return ret;
}

static int qdl_flash(int argc, char **argv)
{
enum qdl_storage_type storage_type = QDL_STORAGE_UFS;
struct sahara_image sahara_images[MAPPING_SZ] = {};
Expand Down Expand Up @@ -498,9 +578,6 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};

if (argc == 2 && !strcmp(argv[1], "list"))
return qdl_list(stdout);

while ((opt = getopt_long(argc, argv, "dvi:lu:S:D:s:fcnt:T:h", options, NULL)) != -1) {
switch (opt) {
case 'd':
Expand Down Expand Up @@ -680,3 +757,13 @@ int main(int argc, char **argv)

return !!ret;
}

int main(int argc, char **argv)
{
if (argc == 2 && !strcmp(argv[1], "list"))
return qdl_list(stdout);
if (argc >= 2 && !strcmp(argv[1], "ramdump"))
return qdl_ramdump(argc - 1, argv + 1);

return qdl_flash(argc, argv);
}
2 changes: 2 additions & 0 deletions ramdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ int main(int argc, char **argv)
return 1;
}

ux_init();

if (qdl_debug)
print_version();

Expand Down
8 changes: 7 additions & 1 deletion sahara.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ static ssize_t sahara_debug64_one(struct qdl_device *qdl,
qdl_read(qdl, buf, DEBUG_BLOCK_SIZE, 10);

chunk += DEBUG_BLOCK_SIZE;

ux_progress("%s", chunk, region.length, region.filename);
}
out:

Expand Down Expand Up @@ -388,8 +390,10 @@ static void sahara_debug64(struct qdl_device *qdl, struct sahara_pkt *pkt,
return;

for (i = 0; i < pkt->debug64_req.length / sizeof(table[0]); i++) {
if (sahara_debug64_filter(table[i].filename, filter))
if (sahara_debug64_filter(table[i].filename, filter)) {
ux_info("%s skipped per filter\n", table[i].filename);
continue;
}

ux_debug("%-2d: type 0x%" PRIx64 " address: 0x%" PRIx64 " length: 0x%"
PRIx64 " region: %s filename: %s\n",
Expand All @@ -399,6 +403,8 @@ static void sahara_debug64(struct qdl_device *qdl, struct sahara_pkt *pkt,
n = sahara_debug64_one(qdl, table[i], ramdump_path);
if (n < 0)
break;

ux_info("%s dumped successfully\n", table[i].filename);
}

free(table);
Expand Down
3 changes: 3 additions & 0 deletions ux.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ void ux_progress(const char *fmt, unsigned int value, unsigned int max, ...)
return;
}

if (value > max)
value = max;

va_start(ap, max);
vsnprintf(task_name, sizeof(task_name), fmt, ap);
va_end(ap);
Expand Down
Loading