Skip to content

Commit 3454f58

Browse files
committed
sahara: add chipinfo command to read chip identity
QDL only ever drives Sahara in its image-transfer and memory-debug modes. Sahara also defines a command mode that lets the primary bootloader be queried for the device's identity before any programmer is uploaded. Expose that as a new "chipinfo" subcommand. It enters command mode by requesting SAHARA_MODE_COMMAND in the HELLO response and echoing the device's advertised protocol version, then drives EXECUTE transactions to read the chip serial number, the HW ID (broken out into MSM_ID / OEM_ID / MODEL_ID) and the OEM PK hash. Version 3 targets no longer answer MSM_HW_ID_READ, so the same fields are recovered through READ_CHIP_ID_V3 on those devices. Command mode is left by switching back to image-transfer mode, which returns the device to its power-on HELLO state and keeps it usable for a subsequent query or flash. A Sahara reset is deliberately avoided here: on some targets it leaves the device enumerated on PID 0x9008 but no longer answering Sahara until it is power-cycled back into EDL. This is handy for identifying an attached target and, in particular, for troubleshooting secure-boot provisioning: the fused OEM PK hash and OEM ID can be read straight from the PBL without loading a programmer. Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
1 parent 13a0c76 commit 3454f58

3 files changed

Lines changed: 393 additions & 4 deletions

File tree

include/qdl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ int firehose_read_buf(struct qdl_device *qdl, struct firehose_op *read_op, void
172172
int sahara_run(struct qdl_device *qdl, const struct sahara_image *images,
173173
const char *ramdump_path,
174174
const char *ramdump_filter);
175+
int sahara_chipinfo(struct qdl_device *qdl);
175176
int load_sahara_image(struct qdl_zip *zip, const char *filename, struct sahara_image *image);
176177
void sahara_images_free(struct sahara_image *images, size_t count);
177178
void print_hex_dump(const char *prefix, const void *buf, size_t len);

src/qdl.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ static void print_usage(FILE *out)
472472
fprintf(out, " %s [options] <prog.mbn> (erase <address>)...\n", __progname);
473473
fprintf(out, " %s [options] <prog.mbn> (sha256 <address>)...\n", __progname);
474474
fprintf(out, " %s list\n", __progname);
475+
fprintf(out, " %s chipinfo\n", __progname);
475476
fprintf(out, " %s ramdump [--debug] [-o <ramdump-path>] [<segment-filter>,...]\n", __progname);
476477
fprintf(out, " %s ks -p <sahara-dev-node> -s <id:file-path>...\n", __progname);
477478
fprintf(out, " %s flash (<flashmap>[::specifier] | <contents>[::<specifier>])\n", __progname);
@@ -640,6 +641,86 @@ static int qdl_ramdump(int argc, char **argv)
640641
return ret;
641642
}
642643

644+
/*
645+
* Chip identity ("chipinfo") subcommand.
646+
*
647+
* Enters Sahara command mode to read and print the device's serial number,
648+
* hardware ID (MSM/OEM/model) and OEM PK hash, then resets the device.
649+
*/
650+
static int qdl_chipinfo(int argc, char **argv)
651+
{
652+
struct qdl_device *qdl;
653+
char *serial = NULL;
654+
enum QDL_DEVICE_TYPE qdl_dev_type = QDL_DEVICE_AUTO;
655+
int ret = 0;
656+
int opt;
657+
658+
static struct option options[] = {
659+
{"debug", no_argument, 0, 'd'},
660+
{"version", no_argument, 0, 'v'},
661+
{"serial", required_argument, 0, 'S'},
662+
{"backend", required_argument, 0, OPT_BACKEND},
663+
{"help", no_argument, 0, 'h'},
664+
{0, 0, 0, 0}
665+
};
666+
667+
while ((opt = getopt_long(argc, argv, "dvS:h", options, NULL)) != -1) {
668+
switch (opt) {
669+
case 'd':
670+
qdl_debug = true;
671+
break;
672+
case 'v':
673+
print_version();
674+
return 0;
675+
case 'S':
676+
serial = optarg;
677+
break;
678+
case OPT_BACKEND:
679+
if (decode_backend(optarg, &qdl_dev_type) < 0)
680+
errx(1, "unknown backend \"%s\" (expected auto|usb|qud)", optarg);
681+
break;
682+
case 'h':
683+
print_usage(stdout);
684+
return 0;
685+
default:
686+
print_usage(stderr);
687+
return 1;
688+
}
689+
}
690+
691+
if (optind != argc) {
692+
print_usage(stderr);
693+
return 1;
694+
}
695+
696+
ux_init();
697+
698+
qdl = qdl_init(qdl_dev_type);
699+
if (!qdl) {
700+
ux_err("backend not available\n");
701+
return 1;
702+
}
703+
704+
if (qdl_debug)
705+
print_version();
706+
707+
ret = qdl_open(qdl, serial);
708+
if (ret) {
709+
ret = 1;
710+
goto out_cleanup;
711+
}
712+
713+
ret = sahara_chipinfo(qdl);
714+
if (ret < 0)
715+
ret = 1;
716+
717+
out_cleanup:
718+
qdl_close(qdl);
719+
qdl_deinit(qdl);
720+
721+
return ret;
722+
}
723+
643724
/*
644725
* Sahara kickstart ("ks") subcommand.
645726
*
@@ -1287,6 +1368,8 @@ int main(int argc, char **argv)
12871368
return qdl_list(stdout);
12881369
if (!strcmp(argv[i], "ramdump"))
12891370
return qdl_ramdump(argc - i, argv + i);
1371+
if (!strcmp(argv[i], "chipinfo"))
1372+
return qdl_chipinfo(argc - i, argv + i);
12901373
if (!strcmp(argv[i], "ks"))
12911374
return qdl_ks(argc - i, argv + i);
12921375
if (!strcmp(argv[i], "create-zip"))

0 commit comments

Comments
 (0)