[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