Chinaunix首页 | 论坛 | 博客
  • 博客访问: 120494
  • 博文数量: 8
  • 博客积分: 2560
  • 博客等级: 少校
  • 技术积分: 192
  • 用 户 组: 普通用户
  • 注册时间: 2006-01-15 09:22
文章分类

全部博文(8)

文章存档

2012年(1)

2009年(2)

2008年(5)

我的朋友

分类: LINUX

2012-03-31 11:45:09

pcidumper 主要功能是打印 x86 PCI 配置空间的内容,原来是 C 语言编写,现在用 golang 重写。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/io.h>


  4. #define PCI_CONFIG_ADDRESS_PORT    0x0CF8
  5. #define PCI_CONFIG_DATA_PORT    0x0CFC

  6. #define PCI_BUS_MASK        0xFFU
  7. #define PCI_DEV_MASK        0x1FU
  8. #define PCI_FUNC_MASK        0x07U
  9. #define PCI_REG_MASK        0xFCU

  10. #define PCI_BUS_LIMIT        (PCI_BUS_MASK + 1)
  11. #define PCI_DEV_LIMIT        (PCI_DEV_MASK + 1)
  12. #define PCI_FUNC_LIMIT        (PCI_FUNC_MASK + 1)
  13. #define PCI_REG_LIMIT        (PCI_REG_MASK + 4)


  14. static inline void privilege_level(int level)
  15. {
  16.     int rc;

  17.     rc = iopl(level);
  18.     if (rc == -1) {
  19.         perror("iopl");

  20.         exit(EXIT_FAILURE);
  21.     }
  22. }

  23. static inline u_int32_t
  24. x86_io_address(u_int32_t bus, u_int32_t dev, u_int32_t func,
  25.      u_int32_t reg)
  26. {
  27.     u_int32_t address;

  28.     address = (0x80000000U) |
  29.          ((bus & PCI_BUS_MASK) << 16) |
  30.          ((dev & PCI_DEV_MASK) << 11) |
  31.          ((func & PCI_FUNC_MASK) << 8) |
  32.          ((reg & PCI_REG_MASK));

  33.     return address;
  34. }

  35. static u_int32_t
  36. pci_read_conf_reg(u_int32_t bus, u_int32_t dev, u_int32_t func,
  37.          u_int32_t reg)
  38. {
  39.     u_int32_t value;
  40.     u_int32_t address;

  41.     address = x86_io_address(bus, dev, func, reg);

  42.     outl(address, PCI_CONFIG_ADDRESS_PORT);

  43.     value = inl(PCI_CONFIG_DATA_PORT);

  44.     return value;
  45. }

  46. static inline void
  47. pci_dump_header(u_int32_t bus, u_int32_t dev, u_int32_t func)
  48. {
  49.     u_int32_t value;
  50.     u_int32_t offset;

  51.     value = pci_read_conf_reg(bus, dev, func, 0);
  52.     /* check PCI Vendor ID */
  53.     if ((value & 0xFFFFU) == 0xFFFFU) {
  54.         return;
  55.     }

  56.     printf("%d:%d.%d\n00 : 0x%08x ", bus, dev, func, value);

  57.     for (offset = 4; offset < PCI_REG_LIMIT; offset += 4) {
  58.         value = pci_read_conf_reg(bus, dev, func, offset);
  59.         if (((offset & 0x0CU) == 0x0CU)) {
  60.             if (offset != (PCI_BUS_LIMIT - 4)) {
  61.                 printf("0x%08x\n%02x : ", value, (offset + 4));
  62.             } else {
  63.                 printf("0x%08x\n", value);
  64.             }
  65.         } else {
  66.             printf("0x%08x ", value);
  67.         }
  68.     }
  69. }

  70. int main(int argc, char **argv)
  71. {
  72.     int bus;
  73.     int dev;
  74.     int func;

  75.     /* go to privilege level 3 */
  76.     privilege_level(3);

  77.     /* scan pci buses */
  78.     for (bus = 0; bus < PCI_BUS_LIMIT; bus++) {
  79.         for (dev = 0; dev < PCI_DEV_LIMIT; dev++ ) {
  80.             for (func = 0; func < PCI_FUNC_LIMIT; func++) {
  81.                 pci_dump_header(bus, dev, func);
  82.             }
  83.         }
  84.     }

  85.     /* back to privilege level for a normal process */
  86.     privilege_level(0);

  87.     return 0;
  88. }
再看一下 golang 版本的 pcidumper

点击(此处)折叠或打开

  1. package main

  2. /*
  3. #include <sys/io.h>
  4. */
  5. import "C"

  6. import (
  7.     "fmt"
  8.     "os"
  9.     "syscall"
  10. )

  11. const (
  12.     PciAddrPort = 0x0cf8
  13.     PciDataPort = 0x0cfc

  14.     PciBusMask = 0xff
  15.     PciDevMask = 0x1f
  16.     PciFuncMask = 0x07
  17.     PciRegMask = 0xfc

  18.     PciBusLimit = PciBusMask + 1
  19.     PciDevLimit = PciDevMask + 1
  20.     PciFuncLimit = PciFuncMask + 1
  21.     PciRegLimit = PciRegMask + 1
  22. )

  23. func ioLevel(level int) {
  24.     if err := syscall.Iopl(level); err != nil {
  25.         fmt.Print(err)

  26.         os.Exit(1)
  27.     }
  28. }

  29. func pciReadConfReg(bus, dev, function, offset uint32) (value uint32) {

  30.     address := 0x80000000 |
  31.         (bus&PciBusMask)<<16 |
  32.         (dev&PciDevMask)<<11 |
  33.         (function&PciFuncMask)<<8 |
  34.         (offset & PciRegMask)

  35.     C.outl(C.uint(address), PciAddrPort)

  36.     value = uint32(C.inl(PciDataPort))

  37.     return
  38. }

  39. func pciDumpHeader(bus, dev, function uint32) {
  40.     var offset uint32

  41.     /* check PCI Vendor ID */
  42.     value := pciReadConfReg(bus, dev, function, 0)
  43.     if value&0xffff == 0xffff {
  44.         return
  45.     }

  46.     fmt.Printf("%d:%d.%d\n00 : 0x%08x ", bus, dev, function, value)

  47.     for offset = 4; offset < PciRegLimit; offset += 4 {
  48.         value = pciReadConfReg(bus, dev, function, offset)
  49.         if offset&0x0c == 0x0c {
  50.             if offset != (PciBusLimit - 4) {
  51.                 fmt.Printf("0x%08x\n%02x : ", value, (offset + 4))
  52.             } else {
  53.                 fmt.Printf("0x%08x\n", value)
  54.             }
  55.         } else {
  56.             fmt.Printf("0x%08x ", value)
  57.         }
  58.     }
  59. }

  60. func main() {
  61.     var bus uint32
  62.     var dev uint32
  63.     var function uint32

  64.     ioLevel(3)

  65.     /* scan pci buses */
  66.     for bus = 0; bus < PciBusLimit; bus++ {
  67.         for dev = 0; dev < PciDevLimit; dev++ {
  68.             for function = 0; function < PciFuncLimit; function++ {
  69.                 pciDumpHeader(bus, dev, function)
  70.             }
  71.         }
  72.     }

  73.     ioLevel(0)
  74. }
稍后再添加评论
阅读(3424) | 评论(0) | 转发(0) |
0

上一篇:我做的视频的地址链接

下一篇:没有了

给主人留下些什么吧!~~