[coreboot-gerrit] New patch to review for coreboot: f1adc72 uio_usbdebug: User-space-i/o framework for usbdebug
Nico Huber (nico.h@gmx.de)
gerrit at coreboot.org
Wed Jan 15 23:11:14 CET 2014
Nico Huber (nico.h at gmx.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4695
-gerrit
commit f1adc72ec897a1749a6394a0907d146dd0d4b20c
Author: Nico Huber <nico.h at gmx.de>
Date: Wed Jan 1 20:47:55 2014 +0100
uio_usbdebug: User-space-i/o framework for usbdebug
uio_usbdebug enables you to debug coreboot's usbdebug driver inside a
running operating system (only Linux at this time). This comes very
handy if you're hacking the usbdebug driver and don't have any other
debug output from coreboot itself.
Change-Id: Iaf0bcd4b4c01ae0b099d1206d553344054a62f31
Signed-off-by: Nico Huber <nico.h at gmx.de>
---
util/uio_usbdebug/Makefile | 42 +++++++++++++
util/uio_usbdebug/README | 77 ++++++++++++++++++++++++
util/uio_usbdebug/console/printk.c | 34 +++++++++++
util/uio_usbdebug/device/device_util.c | 24 ++++++++
util/uio_usbdebug/device/pci_device.c | 12 ++++
util/uio_usbdebug/device/pci_ops.c | 7 +++
util/uio_usbdebug/lib/cbmem.c | 8 +++
util/uio_usbdebug/linux/Makefile | 13 ++++
util/uio_usbdebug/linux/uio_ehci_pci.c | 107 +++++++++++++++++++++++++++++++++
util/uio_usbdebug/uio_usbdebug.c | 60 ++++++++++++++++++
util/uio_usbdebug/uio_usbdebug_intel.c | 40 ++++++++++++
11 files changed, 424 insertions(+)
diff --git a/util/uio_usbdebug/Makefile b/util/uio_usbdebug/Makefile
new file mode 100644
index 0000000..c0fce30
--- /dev/null
+++ b/util/uio_usbdebug/Makefile
@@ -0,0 +1,42 @@
+include ../../.config
+
+ARCHDIR-$(CONFIG_ARCH_ARMV7) := armv7
+ARCHDIR-$(CONFIG_ARCH_X86) := x86
+
+# Only Intel chipsets supported, currently.
+OBJ-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON) += uio_usbdebug_intel.o
+
+PROGRAM := uio_usbdebug
+
+CB_SRC := $(shell realpath ../../src)
+CB_SOURCES := lib/usbdebug.c
+OBJECTS := uio_usbdebug.o \
+ console/printk.o \
+ device/device_util.o device/pci_device.o device/pci_ops.o \
+ lib/cbmem.o \
+ $(OBJ-y) \
+ $(patsubst %.c,%.o,$(CB_SOURCES))
+
+CONFIG_H := ../../build/config.h
+
+CFLAGS += -m32 -g \
+ -Wall -Wextra -Werror \
+ -Wno-unused-parameter -Wno-error=sign-compare
+CPPFLAGS += -I../../src/include/ -I../../src/arch/$(ARCHDIR-y)/include/ \
+ -include$(CONFIG_H)
+
+all: $(PROGRAM)
+
+$(PROGRAM): $(OBJECTS) $(OBJ-y)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS)
+
+$(CB_SOURCES):
+ @mkdir -p $(dir $@)
+ @ln -sf $(CB_SRC)/$@ $@
+
+$(OBJECTS): $(CONFIG_H)
+
+clean:
+ - at rm -rf $(CB_SOURCES) $(OBJECTS) $(PROGRAM)
+
+.PHONY: all clean
diff --git a/util/uio_usbdebug/README b/util/uio_usbdebug/README
new file mode 100644
index 0000000..2d52338
--- /dev/null
+++ b/util/uio_usbdebug/README
@@ -0,0 +1,77 @@
+
+uio_usbdebug - Run coreboot's usbdebug driver in userspace
+==========================================================
+
+
+## Purpose
+
+uio_usbdebug enables you to debug coreboot's usbdebug driver inside a
+running operating system (only Linux at this time). This comes very
+handy if you're hacking the usbdebug driver and don't have any other
+debug output from coreboot itself.
+
+
+## State
+
+Currently only Intel chipsets are supported. Support for other chipsets
+should be straightforward (normally just some port-enable code has to
+be implemented).
+
+The Linux kernel driver (see linux/uio_ehci_pci.c) has only one PCI ID
+hardcoded (for ICH7). The whole setup has been developed and tested on
+a ThinkPad T60.
+
+### Files
+
+uio_usbdebug.c - The userspace part of the uio interface.
+
+uio_usbdebug_intel.c - Port enable code for Intel chipsets.
+
+linux/uio_ehci_pci.c - Kernel part of the uio interface.
+
+console/printk.c - A do_printk() implementation so you can see debug
+ output with CONFIG_DEBUG_USBDEBUG enabled.
+
+device/*.c lib/*.c - Some stubs for (hopefully) unneeded functions for
+ proper linking.
+
+
+## Usage
+
+### Preparations
+
+The MMIO space has to be a whole 4K page in size and alignment to be
+mapped into userspace. This is very uncommon, so you'll most probably
+have to remap the MMIO space. The Linux kernel does that for you with
+the `pci=resource_alignment=<pci address>` kernel parameter (e.g.
+`pci=resource_alignment=0:1d.7` for ICH7).
+
+If your PCI device isn't listed in the kernel driver yet, you might want
+to add it to the `ehci_pci_ids` table in `linux/uio_ehci_pci.c` (or do
+some module alias magic if you know how to).
+
+### Build / Install
+
+Somehow like this:
+
+$ # Configure coreboot for your board and enable CONFIG_USBDEBUG
+$ make menuconfig
+$ cd util/uio_usbdebug/
+$ make -Clinux/
+$ sudo make -Clinux/ install
+$ make
+
+### Run
+
+$ # Unload Linux' EHCI driver (high-speed devices will stop working)
+$ sudo modprobe -r ehci-pci
+$ # Load the uio driver
+$ sudo modprobe uio-ehci-pci
+$ # Find your uio device
+$ ls /sys/module/uio_ehci_pci/drivers/*/*/uio/
+uio0
+$ # Run uio_usbdebug on this device
+$ sudo ./uio_usbdebug /dev/uio0
+
+Sadly, uio_usbdebug has to be run with root privileges since there are
+port-80 writes in the usbdebug driver.
diff --git a/util/uio_usbdebug/console/printk.c b/util/uio_usbdebug/console/printk.c
new file mode 100644
index 0000000..3786103
--- /dev/null
+++ b/util/uio_usbdebug/console/printk.c
@@ -0,0 +1,34 @@
+/*
+ * This file is part of uio_usbdebug
+ *
+ * Copyright (C) 2013 Nico Huber <nico.h at gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <console/console.h>
+
+int do_printk(int msg_level, const char *const fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i = vfprintf (stderr, fmt, args);
+ va_end(args);
+
+ return i;
+}
diff --git a/util/uio_usbdebug/device/device_util.c b/util/uio_usbdebug/device/device_util.c
new file mode 100644
index 0000000..5284101
--- /dev/null
+++ b/util/uio_usbdebug/device/device_util.c
@@ -0,0 +1,24 @@
+
+#include <device/device.h>
+
+static char g_path[] = { '\0' };
+
+const char *dev_path(device_t dev)
+{
+ return g_path;
+}
+
+struct resource *find_resource(device_t dev, unsigned index)
+{
+ return NULL;
+}
+
+void report_resource_stored(device_t dev, struct resource *resource,
+ const char *comment)
+{
+}
+
+struct device *dev_find_slot(unsigned int bus, unsigned int devfn)
+{
+ return NULL;
+}
diff --git a/util/uio_usbdebug/device/pci_device.c b/util/uio_usbdebug/device/pci_device.c
new file mode 100644
index 0000000..97acb05
--- /dev/null
+++ b/util/uio_usbdebug/device/pci_device.c
@@ -0,0 +1,12 @@
+
+#include <device/pci.h>
+#include <device/device.h>
+
+unsigned int pci_match_simple_dev(device_t dev, pci_devfn_t sdev)
+{
+ return 0;
+}
+
+void pci_dev_read_resources(struct device *dev)
+{
+}
diff --git a/util/uio_usbdebug/device/pci_ops.c b/util/uio_usbdebug/device/pci_ops.c
new file mode 100644
index 0000000..cd1b3a5
--- /dev/null
+++ b/util/uio_usbdebug/device/pci_ops.c
@@ -0,0 +1,7 @@
+
+#include <device/device.h>
+
+u32 pci_read_config32(device_t dev, unsigned int where)
+{
+ return 0;
+}
diff --git a/util/uio_usbdebug/lib/cbmem.c b/util/uio_usbdebug/lib/cbmem.c
new file mode 100644
index 0000000..6d87880
--- /dev/null
+++ b/util/uio_usbdebug/lib/cbmem.c
@@ -0,0 +1,8 @@
+
+#include <stdint.h>
+#include <stddef.h>
+
+void *cbmem_find(u32 id)
+{
+ return NULL;
+}
diff --git a/util/uio_usbdebug/linux/Makefile b/util/uio_usbdebug/linux/Makefile
new file mode 100644
index 0000000..fd60b4f
--- /dev/null
+++ b/util/uio_usbdebug/linux/Makefile
@@ -0,0 +1,13 @@
+
+obj-m := uio_ehci_pci.o
+
+all: uio_ehci_pci.c
+ @$(MAKE) -C/lib/modules/`uname -r`/build M=$(CURDIR) modules
+
+install:
+ @$(MAKE) -C/lib/modules/`uname -r`/build M=$(CURDIR) modules_install
+
+clean:
+ -@$(MAKE) -C/lib/modules/`uname -r`/build M=$(CURDIR) clean
+
+.PHONY: all install clean
diff --git a/util/uio_usbdebug/linux/uio_ehci_pci.c b/util/uio_usbdebug/linux/uio_ehci_pci.c
new file mode 100644
index 0000000..185b4d6
--- /dev/null
+++ b/util/uio_usbdebug/linux/uio_ehci_pci.c
@@ -0,0 +1,107 @@
+/*
+ * uio_ehci_pci - UIO driver for PCI EHCI devices
+ *
+ * Copyright (C) 2013 Nico Huber <nico.h at gmx.de>
+ *
+ * This only implements MMIO access (no interrupts).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/uio_driver.h>
+
+#define DRIVER_VERSION "0.0.0"
+#define DRIVER_AUTHOR "Nico Huber <nico.h at gmx.de>"
+#define DRIVER_DESC "UIO driver for PCI EHCI devices"
+#define DRIVER_TAG "uio_ehci_pci"
+
+static int
+probe(struct pci_dev *const pci_dev, const struct pci_device_id *const did)
+{
+ struct uio_info *info;
+ int ret;
+
+ ret = pci_enable_device(pci_dev);
+ if (ret)
+ goto return_;
+
+ ret = pci_request_regions(pci_dev, DRIVER_TAG);
+ if (ret)
+ goto return_disable;
+
+ info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+ if (!info) {
+ ret = -ENOMEM;
+ goto return_release;
+ }
+
+ info->name = DRIVER_TAG;
+ info->version = DRIVER_VERSION;
+
+ info->mem[0].name = "EHCI MMIO area";
+ info->mem[0].addr = pci_resource_start(pci_dev, 0);
+ if (!info->mem[0].addr) {
+ ret = -ENODEV;
+ goto return_free;
+ }
+ info->mem[0].size = pci_resource_len(pci_dev, 0);
+ info->mem[0].memtype = UIO_MEM_PHYS;
+
+ ret = uio_register_device(&pci_dev->dev, info);
+ if (ret)
+ goto return_free;
+ pci_set_drvdata(pci_dev, info);
+
+ return 0;
+return_free:
+ kfree(info);
+return_release:
+ pci_release_regions(pci_dev);
+return_disable:
+ pci_disable_device(pci_dev);
+return_:
+ return ret;
+}
+
+static void
+remove(struct pci_dev *const pci_dev)
+{
+ struct uio_info *const info = pci_get_drvdata(pci_dev);
+
+ uio_unregister_device(info);
+ kfree(info);
+ pci_release_regions(pci_dev);
+ pci_disable_device(pci_dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(ehci_pci_ids) = {
+ { PCI_DEVICE(0x8086, 0x27cc) },
+ { 0, }
+};
+
+static struct pci_driver uio_ehci_pci_driver = {
+ .name = DRIVER_TAG,
+ .id_table = ehci_pci_ids,
+ .probe = probe,
+ .remove = remove,
+};
+
+module_pci_driver(uio_ehci_pci_driver);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/util/uio_usbdebug/uio_usbdebug.c b/util/uio_usbdebug/uio_usbdebug.c
new file mode 100644
index 0000000..375cfa6
--- /dev/null
+++ b/util/uio_usbdebug/uio_usbdebug.c
@@ -0,0 +1,60 @@
+/*
+ * uio_usbdebug - Run coreboot's usbdebug driver in userspace
+ *
+ * Copyright (C) 2013 Nico Huber <nico.h at gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+/* coreboot's arch/io.h conflicts with libc's sys/io.h, so declare this here: */
+int ioperm(unsigned long from, unsigned long num, int turn_on);
+
+#include <arch/io.h>
+#include <usbdebug.h>
+
+void *ehci_bar;
+
+int main(int argc, char *argv[])
+{
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <uio-dev>\n", argv[0]);
+ return 1;
+ }
+ const int fd = open(argv[1], O_RDWR);
+ if (fd < 0) {
+ perror("Failed to open uio device");
+ return 2;
+ }
+ ehci_bar =
+ mmap(NULL, 1 << 8, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (MAP_FAILED == ehci_bar) {
+ perror("Failed to map ehci bar");
+ close(fd);
+ return 3;
+ }
+
+ ioperm(0x80, 1, 1);
+
+ usbdebug_init((unsigned)ehci_bar);
+
+ munmap(ehci_bar, 1 << 8);
+ close(fd);
+ return 0;
+}
diff --git a/util/uio_usbdebug/uio_usbdebug_intel.c b/util/uio_usbdebug/uio_usbdebug_intel.c
new file mode 100644
index 0000000..fa9e1a4
--- /dev/null
+++ b/util/uio_usbdebug/uio_usbdebug_intel.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of uio_usbdebug
+ *
+ * Copyright (C) 2013 Nico Huber <nico.h at gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <usbdebug.h>
+
+extern void *ehci_bar;
+
+pci_devfn_t pci_ehci_dbg_dev(unsigned hcd_idx)
+{
+ return 0;
+}
+
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
+{
+ /* claim usb debug port */
+ const unsigned long dbgctl_addr =
+ ((unsigned long)ehci_bar) + CONFIG_EHCI_DEBUG_OFFSET;
+ write32(dbgctl_addr, read32(dbgctl_addr) | (1 << 30));
+}
+
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
+{
+}
More information about the coreboot-gerrit
mailing list