Ticket #2143: fbdtemp.c

File fbdtemp.c, 1.7 kB (added by ticket, 1 year ago)

Display the FB-DIMM temperature and thermal trip points

Line 
1 #include <sys/mman.h>
2 #include <sys/stat.h>
3 #include <pci/pci.h>
4 #include <fcntl.h>
5 #include <errno.h>
6 #include <stdio.h>
7
8 int main(int argc, char *argv[]) {
9   struct pci_access *pacc = pci_alloc();
10   struct pci_dev *dev;
11
12   // Find the FSB Registers of the Intel 5000 chipset. It's always on
13   // bus 0, device 16, function 0.
14   // I have no idea what the domain argument is...
15   pci_init(pacc);
16   dev = pci_get_dev(pacc, 0, 0, 16, 0);
17   if (dev == NULL) {
18     error(1, 0, "Unsupported memory controller");
19   }
20
21   pci_fill_info(dev, PCI_FILL_IDENT);
22   if(dev->vendor_id != PCI_VENDOR_ID_INTEL || dev->device_id != 0x25F0) {
23     error(1, 0, "Unsupported memory controller");
24   }
25
26   u64 am_base = (u64) pci_read_long(dev, 0x48) |
27                 (u64) pci_read_long(dev, 0x4C) << 32;
28   u32 am_range = pci_read_long(dev, 0x50);
29   pci_cleanup(pacc);
30
31   int fd = open("/dev/mem", O_RDONLY);
32   if (fd == -1) {
33     error(1, errno, "Cannot open /dev/mem");
34   }
35  
36   u8 * addr = mmap(0, am_range, PROT_READ, MAP_PRIVATE, fd, am_base);
37   if (addr == MAP_FAILED) {
38     error(1, errno, "Cannot mmap AMB registers");
39   }
40
41   unsigned idx;
42   for (idx = 0;  idx < am_range;  idx += 0x800 /* 2KB per AMB */) {
43
44     // Check for Intel 6400/6402
45     if ((addr[idx  ] | addr[idx+1] << 8) != PCI_VENDOR_ID_INTEL) continue;
46     if ((addr[idx+2] | addr[idx+3] << 8) != 0xA620) continue;
47
48     // function 3
49     int func3 = idx + 0x300;
50     printf("DIMM_%1d_%1X Temp: %5.1f C     "
51            "(low = %5.1f C, mid = %5.1f C, high = %5.1f C)\n",
52            idx >> 15, (idx >> 11) & 0x0F,
53            addr[func3 + 0x85] / 2.0,
54            addr[func3 + 0x80] / 2.0,
55            addr[func3 + 0x81] / 2.0,
56            addr[func3 + 0x82] / 2.0);
57   }
58  
59   munmap(addr, am_range);
60   close(fd);
61   return 0;
62 }