#include #include #include #define DRIVER_NAME "dump_stuff" #define PFX DRIVER_NAME ": " #define BAR 0x90000000 #define SMRBASE 0x14 #define IMCH_TST2 0xf6 #define IMCH_TST2_SYSMMREN 6 static void dump_pci_config(struct pci_dev* dev) { int i, j; u8 b; printk(" f e d c b a 9 8 7 6 5 4 3 2 1 0"); for (i = 0xf; i >= 0; i--) { printk("\n%01x", i); for (j = 0xf; j >= 0; j--) { pci_read_config_byte(dev, (i << 4) | j, &b); printk(" %02x", b); } } printk("\n"); } static void dump_mmio(volatile void __iomem *start, int sz) { int i, j; printk(" f e d c b a 9 8 7 6 5 4 3 2 1 0"); for (i = (sz >> 4); i >= 0; i--) { printk("\n%02x ", i); for (j = 0xf; j >= 0; j--) printk(" %02x", readb(start + (i << 4) + j)); } printk("\n"); } static int imch_probe(struct pci_dev *dev, const struct pci_device_id *id) { u8 imch_tst2; int rc = 0; unsigned long base, size; void __iomem *mem; rc = pci_enable_device(dev); if (rc) { printk(PFX "Couldn't enable device\n"); goto err_enable_device; } rc = pci_request_regions(dev, DRIVER_NAME); if (rc) { printk(PFX "Couldn't request regions\n"); goto err_request_regions; } pci_read_config_byte(dev, IMCH_TST2, &imch_tst2); pci_write_config_byte(dev, IMCH_TST2, imch_tst2 | 1 << IMCH_TST2_SYSMMREN); pci_write_config_dword(dev, SMRBASE, BAR); //base = pci_resource_start(dev, SMRBASE); //size = pci_resource_len(dev, SMRBASE); base = BAR; size = 0x298; mem = ioremap(base, size); if (!mem) { printk(PFX "Couldn't map memory (0x%08lx,%ld)\n", base, size); rc = -ENOMEM; goto err_ioremap; } printk("Dumping IMCH PCI config registers\n"); dump_pci_config(dev); printk("Dumping SMRBASE registers\n"); dump_mmio(mem, size); iounmap(mem); err_ioremap: pci_release_regions(dev); err_request_regions: pci_disable_device(dev); err_enable_device: return rc; } static const struct pci_device_id dump_stuff_id_tbl[] = { {0x8086, 0x5020, PCI_ANY_ID, PCI_ANY_ID,}, /* EP80579 IMCH */ { }, }; MODULE_DEVICE_TABLE(pci, dump_stuff_id_tbl); static struct pci_driver dump_stuff = { .name = "dump_stuff", .id_table = dump_stuff_id_tbl, .probe = imch_probe, }; static int init_dump_stuff(void) { return pci_register_driver(&dump_stuff); } module_init(init_dump_stuff); static void exit_dump_stuff(void) { pci_unregister_driver(&dump_stuff); } module_exit(exit_dump_stuff);