xref: /illumos-gate/usr/src/cmd/amdzen/udf.c (revision f641a59486e69100969f92a7ec309574f76b238d)
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 2020 Oxide Computer Company
14  */
15 
16 /*
17  * Facilitate access to the AMD Zen data fabric
18  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <err.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <strings.h>
29 #include <zen_udf.h>
30 
31 static void
32 udf_readone(int fd, uint8_t inst, uint8_t func, uint16_t reg, boolean_t do64)
33 {
34 	int ret;
35 	zen_udf_io_t zui;
36 
37 	bzero(&zui, sizeof (zui));
38 	zui.zui_inst = inst;
39 	zui.zui_func = func;
40 	zui.zui_reg = reg;
41 
42 	ret = ioctl(fd, do64 ? ZEN_UDF_READ64 : ZEN_UDF_READ32, &zui);
43 	if (ret != 0) {
44 		err(EXIT_FAILURE, "failed to issue read ioctl");
45 	}
46 
47 	(void) printf("ifr %x/%x/%x: 0x%" PRIx64 "\n",
48 	    inst, func, reg, zui.zui_data);
49 }
50 
51 int
52 main(int argc, char *argv[])
53 {
54 	int c, fd;
55 	const char *device = NULL;
56 	const char *funcstr = NULL;
57 	const char *inststr = NULL;
58 	const char *regstr = NULL;
59 	uint8_t func, inst;
60 	uint16_t reg;
61 	unsigned long lval;
62 	char *eptr;
63 	boolean_t do64 = B_FALSE;
64 
65 	while ((c = getopt(argc, argv, "d:f:i:r:l")) != -1) {
66 		switch (c) {
67 		case 'd':
68 			device = optarg;
69 			break;
70 		case 'f':
71 			funcstr = optarg;
72 			break;
73 		case 'i':
74 			inststr = optarg;
75 			break;
76 		case 'l':
77 			do64 = B_TRUE;
78 			break;
79 		case 'r':
80 			regstr = optarg;
81 			break;
82 		}
83 	}
84 
85 	if (device == NULL || funcstr == NULL || inststr == NULL ||
86 	    regstr == NULL) {
87 		warnx("missing required arguments");
88 		(void) fprintf(stderr, "Usage: udf [-l] -d device -f func -i "
89 		    "inst -r reg\n");
90 	}
91 
92 	errno = 0;
93 	lval = strtoul(funcstr, &eptr, 0);
94 	if (errno != 0 || lval > UINT8_MAX || *eptr != '\0') {
95 		errx(EXIT_FAILURE, "failed to parse -f: %s", funcstr);
96 	}
97 	func = (uint8_t)lval;
98 
99 	lval = strtoul(inststr, &eptr, 0);
100 	if (errno != 0 || lval > UINT8_MAX || *eptr != '\0') {
101 		errx(EXIT_FAILURE, "failed to parse -i: %s", inststr);
102 	}
103 	inst = (uint8_t)lval;
104 
105 	lval = strtoul(regstr, &eptr, 0);
106 	if (errno != 0 || lval > UINT16_MAX || *eptr != '\0') {
107 		errx(EXIT_FAILURE, "failed to parse -r: %s", regstr);
108 	}
109 	reg = (uint16_t)lval;
110 
111 	if ((fd = open(device, O_RDONLY)) < 0) {
112 		err(EXIT_FAILURE, "failed to open %s", device);
113 	}
114 
115 	udf_readone(fd, inst, func, reg, do64);
116 	(void) close(fd);
117 	return (0);
118 }
119