diff options
author | Noe Rubinstein <nrubinstein@proformatique.com> | 2011-07-19 12:23:41 +0200 |
---|---|---|
committer | Noe Rubinstein <nrubinstein@proformatique.com> | 2011-07-19 12:23:41 +0200 |
commit | 8b34fb65574384bfce2ed73da289e61071ed88b6 (patch) | |
tree | ea5e70bc993a12d19423910bb9e7ff0de6fb44f9 | |
parent | 9177c2a2ace12dc29193e46d2daffca13c9e9cd2 (diff) |
Kernel module to dump IMCH registers
-rw-r--r-- | dump_stuff/Makefile | 13 | ||||
-rw-r--r-- | dump_stuff/module_lol.c | 114 |
2 files changed, 127 insertions, 0 deletions
diff --git a/dump_stuff/Makefile b/dump_stuff/Makefile new file mode 100644 index 0000000..9d04c39 --- /dev/null +++ b/dump_stuff/Makefile @@ -0,0 +1,13 @@ +PWD := $(shell pwd) + +KSRC ?= /bad__ksrc__not_set + +obj-m := module_lol.o +modules: + +modules modules_install clean: + $(MAKE) -C $(KSRC) M=$(PWD) $@ + +distclean: clean + rm -f Module.symvers modules.order + diff --git a/dump_stuff/module_lol.c b/dump_stuff/module_lol.c new file mode 100644 index 0000000..8839e9b --- /dev/null +++ b/dump_stuff/module_lol.c @@ -0,0 +1,114 @@ +#include <linux/module.h> +#include <linux/types.h> +#include <linux/pci.h> + +#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); + |