1 /*
2 * Author: Daniel De Graaf <dgdegra@tycho.nsa.gov>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2,
6 * as published by the Free Software Foundation.
7 */
8
9 #include <stdlib.h>
10 #include <errno.h>
11 #include <stdio.h>
12 #include <xenctrl.h>
13 #include <fcntl.h>
14 #include <sys/mman.h>
15 #include <sys/stat.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <inttypes.h>
19
20 /* Pulled from linux/include/linux/ioport.h */
21 #define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */
22 #define IORESOURCE_IO 0x00000100
23 #define IORESOURCE_MEM 0x00000200
24 #define IORESOURCE_IRQ 0x00000400
25 #define IORESOURCE_DMA 0x00000800
26 #define IORESOURCE_BUS 0x00001000
27
28
usage(int argCnt,char * argv[])29 static void usage (int argCnt, char *argv[])
30 {
31 fprintf(stderr, "Usage: %s SBDF label\n", argv[0]);
32 exit(1);
33 }
34
main(int argCnt,char * argv[])35 int main (int argCnt, char *argv[])
36 {
37 int ret, err = 0;
38 xc_interface *xch = 0;
39 int seg, bus, dev, fn;
40 uint32_t sbdf;
41 uint64_t start, end, flags;
42 char buf[1024];
43 FILE *f;
44
45 if (argCnt != 3)
46 usage(argCnt, argv);
47
48 xch = xc_interface_open(0,0,0);
49 if ( !xch )
50 {
51 fprintf(stderr, "Unable to create interface to xenctrl: %s\n",
52 strerror(errno));
53 err = 1;
54 goto done;
55 }
56
57 sscanf(argv[1], "%x:%x:%x.%d", &seg, &bus, &dev, &fn);
58 sbdf = (seg << 16) | (bus << 8) | (dev << 3) | fn;
59
60 snprintf(buf, sizeof(buf), "/sys/bus/pci/devices/%04x:%02x:%02x.%d/resource",
61 seg, bus, dev, fn);
62
63 f = fopen(buf, "r");
64 if (!f) {
65 fprintf(stderr, "Unable to find device %s: %s\n", argv[1],
66 strerror(errno));
67 err = 1;
68 goto done;
69 }
70
71 ret = xc_flask_add_device(xch, sbdf, argv[2]);
72 if (ret) {
73 fprintf(stderr, "xc_flask_add_device: Unable to set context of PCI device %s (0x%x) to %s: %d\n",
74 argv[1], sbdf, argv[2], ret);
75 err = 2;
76 goto done;
77 }
78
79 while (fscanf(f, "0x%"SCNx64" 0x%"SCNx64" 0x%"SCNx64"\n", &start, &end, &flags) == 3) {
80 if (flags & IORESOURCE_IO) {
81 // printf("Port %"PRIx64"-%"PRIx64"\n", start, end);
82 ret = xc_flask_add_ioport(xch, start, end, argv[2]);
83 if (ret) {
84 fprintf(stderr, "xc_flask_add_ioport %"PRIx64"-%"PRIx64" failed: %d\n",
85 start, end, ret);
86 err = 2;
87 }
88 } else if (flags & IORESOURCE_MEM) {
89 start >>= 12;
90 end >>= 12;
91 // printf("IOMEM %"PRIx64"-%"PRIx64"\n", start, end);
92 ret = xc_flask_add_iomem(xch, start, end, argv[2]);
93 if (ret) {
94 fprintf(stderr, "xc_flask_add_iomem %"PRIx64"-%"PRIx64" failed: %d\n",
95 start, end, ret);
96 err = 2;
97 }
98 }
99 }
100 fclose(f);
101
102 snprintf(buf, sizeof(buf), "/sys/bus/pci/devices/%04x:%02x:%02x.%d/irq",
103 seg, bus, dev, fn);
104 f = fopen(buf, "r");
105 if (!f)
106 goto done;
107 if (fscanf(f, "%" SCNu64, &start) != 1)
108 start = 0;
109 if (start) {
110 ret = xc_flask_add_pirq(xch, start, argv[2]);
111 if (ret) {
112 fprintf(stderr, "xc_flask_add_pirq %"PRIu64" failed: %d\n",
113 start, ret);
114 err = 2;
115 }
116 }
117 fclose(f);
118 done:
119 if ( xch )
120 xc_interface_close(xch);
121
122 return err;
123 }
124