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 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 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