xref: /illumos-gate/usr/src/cmd/spd/spd.c (revision 1d0ec46fafb49266ae79840a692bb48af60ade70)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2023 Oxide Computer Company
14  */
15 
16 /*
17  * A private utility to dump the raw spd information nvlist.
18  */
19 
20 #include <err.h>
21 #include <libnvpair.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <libjedec.h>
27 
28 int
29 main(int argc, const char *argv[])
30 {
31 	int fd;
32 	struct stat st;
33 	uint8_t buf[4096];
34 	ssize_t ret;
35 	spd_error_t serr;
36 
37 	if (argc != 2) {
38 		errx(EXIT_FAILURE, "spd: file");
39 	}
40 
41 	fd = open(argv[1], O_RDONLY);
42 	if (fd < 0) {
43 		err(EXIT_FAILURE, "failed to open %s", argv[1]);
44 	}
45 
46 	if (fstat(fd, &st) != 0) {
47 		err(EXIT_FAILURE, "failed to get stat info for %s", argv[1]);
48 	}
49 
50 	if (st.st_size > sizeof (buf)) {
51 		errx(EXIT_FAILURE, "spd data exceeds internal 0x%zx internal "
52 		    "buffer: 0x%lx", sizeof (buf), st.st_size);
53 	}
54 
55 	ret = read(fd, buf, st.st_size);
56 	if (ret < 0) {
57 		err(EXIT_FAILURE, "failed to read %s", argv[1]);
58 	} else if (ret != st.st_size) {
59 		errx(EXIT_FAILURE, "failed to read %s in one go: got %ld "
60 		    "bytes, expected %ld", argv[1], ret, st.st_size);
61 	}
62 
63 	nvlist_t *nvl = libjedec_spd(buf, st.st_size, &serr);
64 	if (nvl == NULL) {
65 		errx(EXIT_FAILURE, "failed to parse spd info: 0x%x\n", serr);
66 	}
67 
68 	nvlist_print(stdout, nvl);
69 	return (EXIT_SUCCESS);
70 }
71