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 2021 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
udf_readone(int fd,uint8_t inst,uint8_t func,uint16_t reg,boolean_t do64)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
main(int argc,char * argv[])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 exit(2);
91 }
92
93 errno = 0;
94 lval = strtoul(funcstr, &eptr, 0);
95 if (errno != 0 || lval > UINT8_MAX || *eptr != '\0') {
96 errx(EXIT_FAILURE, "failed to parse -f: %s", funcstr);
97 }
98 func = (uint8_t)lval;
99
100 lval = strtoul(inststr, &eptr, 0);
101 if (errno != 0 || lval > UINT8_MAX || *eptr != '\0') {
102 errx(EXIT_FAILURE, "failed to parse -i: %s", inststr);
103 }
104 inst = (uint8_t)lval;
105
106 lval = strtoul(regstr, &eptr, 0);
107 if (errno != 0 || lval > UINT16_MAX || *eptr != '\0') {
108 errx(EXIT_FAILURE, "failed to parse -r: %s", regstr);
109 }
110 reg = (uint16_t)lval;
111
112 if ((fd = open(device, O_RDONLY)) < 0) {
113 err(EXIT_FAILURE, "failed to open %s", device);
114 }
115
116 udf_readone(fd, inst, func, reg, do64);
117 (void) close(fd);
118 return (0);
119 }
120