summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoe Rubinstein <nrubinstein@proformatique.com>2011-07-19 12:23:41 +0200
committerNoe Rubinstein <nrubinstein@proformatique.com>2011-07-19 12:23:41 +0200
commit8b34fb65574384bfce2ed73da289e61071ed88b6 (patch)
treeea5e70bc993a12d19423910bb9e7ff0de6fb44f9
parent9177c2a2ace12dc29193e46d2daffca13c9e9cd2 (diff)
Kernel module to dump IMCH registers
-rw-r--r--dump_stuff/Makefile13
-rw-r--r--dump_stuff/module_lol.c114
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);
+