]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/vga/pci.c
abaco: cleanup, handle image/x-icon, don't use backspace as a hotkey, and remove...
[plan9front.git] / sys / src / cmd / aux / vga / pci.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <fcall.h>
5
6 #include "pci.h"
7 #include "vga.h"
8
9 static Pcidev* pcilist;
10 static Pcidev* pcitail;
11
12 static void
13 pcicfginit(void)
14 {
15         int fd, i, j, n, bno, dno, fno;
16         char buf[1024], *base, *s;
17         Pcidev *p;
18         Dir *d;
19
20         trace("pcicfginit\n");
21         if((fd = open(base = "/dev/pci", OREAD)) < 0)
22                 if((fd = open(base = "#$/pci", OREAD)) < 0)
23                         return;
24         n = dirreadall(fd, &d);
25         close(fd);
26         
27         for(i=0; i<n; i++) {
28                 if(strstr(d[i].name, "ctl") == nil)
29                         continue;
30
31                 strncpy(buf, d[i].name, sizeof(buf));
32                 bno = strtoul(buf, &s, 10);
33                 dno = strtoul(s+1, &s, 10);
34                 fno = strtoul(s+1, nil, 10);
35         
36                 p = mallocz(sizeof(*p), 1);
37                 p->tbdf = MKBUS(BusPCI, bno, dno, fno);
38                 sprint(buf, "%s/%d.%d.%draw", base, bno, dno, fno);
39                 if((p->rawfd = open(buf, ORDWR)) < 0){
40                         free(p);
41                         continue;
42                 }
43                 sprint(buf, "%s/%d.%d.%dctl", base, bno, dno, fno);
44                 if((fd = open(buf, OREAD)) < 0){
45                         close(p->rawfd);
46                         free(p);
47                         continue;
48                 }
49                 if((j = read(fd, buf, sizeof(buf)-1)) <= 0){
50                         close(p->rawfd);
51                         close(fd);
52                         free(p);
53                         continue;
54                 }
55                 buf[j] = 0;
56                 close(fd);
57
58                 p->ccrb = strtol(buf, nil, 16);
59                 p->ccru = strtol(buf + 3, nil, 16);
60                 p->vid = strtol(buf + 9, &s, 16);
61                 p->did = strtol(s + 1, &s, 16);
62                 p->intl = strtol(s + 1, &s, 10);
63
64                 p->rid = pcicfgr8(p, PciRID);
65
66                 trace("%d.%d.%d: did=%X vid=%X rid=%X intl=%d ccru=%X\n",
67                         bno, dno, fno, p->did, p->vid, p->rid, p->intl, p->ccru);
68
69                 while(*s == ' '){
70                         j = strtol(s+1, &s, 10);
71                         if(j < 0 || j >= nelem(p->mem))
72                                 break;
73                         p->mem[j].bar = strtoul(s+1, &s, 16);
74                         p->mem[j].size = strtoul(s+1, &s, 10);
75                         trace("\tmem[%d] = %lux %d\n", j, p->mem[j].bar, p->mem[j].size);
76                 }
77
78                 if(pcilist != nil)
79                         pcitail->list = p;
80                 else
81                         pcilist = p;
82                 pcitail = p;
83         }
84 }
85
86 static int
87 pcicfgrw(Pcidev *pcidev, int rno, int data, int len, int read)
88 {
89         uchar buf[4];
90
91         if(read){
92                 memset(buf, 0, sizeof(buf));
93                 if(pread(pcidev->rawfd, buf, len, rno) != len)
94                         return -1;
95                 switch(len){
96                 case 1:
97                         return GBIT8(buf);
98                 case 2:
99                         return GBIT16(buf);
100                 case 4:
101                         return GBIT32(buf);
102                 default:
103                         abort();
104                 }
105         } else {
106                 switch(len){
107                 case 1:
108                         PBIT8(buf, data);
109                         break;
110                 case 2:
111                         PBIT16(buf, data);
112                         break;
113                 case 4:
114                         PBIT32(buf, data);
115                         break;
116                 default:
117                         abort();
118                 }
119                 if(pwrite(pcidev->rawfd, buf, len, rno) != len)
120                         return -1;
121         }
122         return 0;
123 }
124
125 int
126 pcicfgr8(Pcidev* pcidev, int rno)
127 {
128         return pcicfgrw(pcidev, rno, 0, 1, 1);
129 }
130
131 void
132 pcicfgw8(Pcidev* pcidev, int rno, int data)
133 {
134         pcicfgrw(pcidev, rno, data, 1, 0);
135 }
136
137 int
138 pcicfgr16(Pcidev* pcidev, int rno)
139 {
140         return pcicfgrw(pcidev, rno, 0, 2, 1);
141 }
142
143 void
144 pcicfgw16(Pcidev* pcidev, int rno, int data)
145 {
146         pcicfgrw(pcidev, rno, data, 2, 0);
147 }
148
149 int
150 pcicfgr32(Pcidev* pcidev, int rno)
151 {
152         return pcicfgrw(pcidev, rno, 0, 4, 1);
153 }
154
155 void
156 pcicfgw32(Pcidev* pcidev, int rno, int data)
157 {
158         pcicfgrw(pcidev, rno, data, 4, 0);
159 }
160
161 Pcidev*
162 pcimatch(Pcidev* prev, int vid, int did)
163 {
164         if(pcilist == nil)
165                 pcicfginit();
166
167         if(prev == nil)
168                 prev = pcilist;
169         else
170                 prev = prev->list;
171
172         while(prev != nil) {
173                 if(prev->vid == vid && (did == 0 || prev->did == did))
174                         break;
175                 prev = prev->list;
176         }
177         return prev;
178 }
179