-
Notifications
You must be signed in to change notification settings - Fork 1
/
k8temp_libpci.c
115 lines (100 loc) · 2.27 KB
/
k8temp_libpci.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* k8temp functions for scanning PCI devices and reading/writing
* to registers on them, via NetBSD-style libpci and /dev/pci0
*
* Untested, unfinished. Beware of dog.
*/
#include <sysexits.h>
#include "k8temp_pci.h"
static int fd;
void
k8_pci_init(void)
{
if ((fd = open(_PATH_DEVPCI, O_RDWR, 0)) < 0)
err(EX_OSFILE, "open(\"%s\")", _PATH_DEVPCI);
}
void
k8_pci_close(void)
{
if (fd) close(fd);
}
int
k8_pci_vendor_device_list(uint32_t vendor_id, uint32_t device_id, k8_pcidev devs[], int maxdev)
{
int matches = -1;
uint8_t dev,func;
uint32_t pcireg;
k8_pcidev sel;
bzero(&sel, sizeof(k8_pcidev));
sel.pc_bus = 0;
for (dev=0; dev < 32; dev++)
{
sel.pc_dev = dev;
for (func=0; func < 8; func++)
{
sel.pc_func = func;
if (k8_pci_read_word(sel, 0, &pcireg) &&
(pcireg & 0xffff) == vendor_id &&
((pcireg >> 16) & 0xffff) == device_id &&
matches < maxdev)
{
memcpy(&devs[++matches], &sel, sizeof(k8_pcidev));
}
}
}
return(matches);
}
int
k8_pci_read(k8_pcidev dev, int offset, uint32_t *data, int width)
{
if (pcibus_conf_read(fd, dev.pc_bus, dev.pc_dev, dev.pc_func, offset, (uint32_t *)&data) < 0)
{
warn("Register read %x, %d bytes failed", offset, width);
return(0);
}
switch (width)
{
case 1:
*data = *data & 0xff;
break;
case 4:
break;
default:
warnx("Width %d register reads unsupported", width);
}
return(width);
}
int
k8_pci_read_byte(k8_pcidev dev, int offset, uint32_t *data)
{
return(k8_pci_read(dev, offset, data, 1));
}
int
k8_pci_read_word(k8_pcidev dev, int offset, uint32_t *data)
{
return(k8_pci_read(dev, offset, data, 4));
}
int
k8_pci_write(k8_pcidev dev, int offset, uint32_t data, int width)
{
/* XXX: Note, libpci doesn't support !4 byte writes.
* Luckily the upper 24 bits of Thermtrip is read-only, so it doesn't
* matter, but we should take care if we end up writing anywhere else.
*/
if (pcibus_conf_write(fd, dev.pc_bus, dev.pc_dev, dev.pc_func, offset, data) < 0)
{
warn("Register write %x, %d bytes failed", offset, width);
return(0);
}
return(4);
}
int
k8_pci_write_byte(k8_pcidev dev, int offset, uint32_t data)
{
return(k8_pci_write(dev, offset, data, 1));
}
int
k8_pci_write_word(k8_pcidev dev, int offset, uint32_t data)
{
return(k8_pci_write(dev, offset, data, 4));
}