Ticket #2143: fbdtemp.c

File fbdtemp.c, 1.7 KB (added by ticket, 5 years 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
8int 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}