aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2013-07-09 04:19:22 +0300
committerStefan Reinauer <stefan.reinauer@coreboot.org>2013-07-10 23:24:20 +0200
commit41c10cd2d73198e61573af1341d5826654f1133a (patch)
tree9d8679061185e42ba6b166ac0c573aa920c2b63b /src/lib
parent9e7806a788f9617d3dd9139a74ab3f7b03eb9581 (diff)
usbdebug: Move EHCI BAR relocation code
There are other uses for EHCI debug port besides console, so move EHCI relocation code from console to lib. Change-Id: I95cddd31be529351d9ec68f14782cc3cbe08c617 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: http://review.coreboot.org/3626 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@google.com> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/usbdebug.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/lib/usbdebug.c b/src/lib/usbdebug.c
index 09306fdb09..9cf3579991 100644
--- a/src/lib/usbdebug.c
+++ b/src/lib/usbdebug.c
@@ -21,6 +21,7 @@
#include <stddef.h>
#include <console/console.h>
#include <arch/io.h>
+#include <device/pci.h>
#include <arch/byteorder.h>
#include <usb_ch9.h>
@@ -88,6 +89,8 @@
#if !defined(__PRE_RAM__) && !defined(__SMM__)
static struct ehci_debug_info glob_dbg_info;
+static struct device_operations *ehci_drv_ops;
+static struct device_operations ehci_dbg_ops;
#endif
static int dbgp_wait_until_complete(struct ehci_dbg_port *ehci_debug)
@@ -596,6 +599,62 @@ void usbdebug_tx_flush(struct ehci_debug_info *dbg_info)
}
}
+#if !defined(__PRE_RAM__) && !defined(__SMM__)
+static void usbdebug_re_enable(unsigned ehci_base)
+{
+ struct ehci_debug_info *dbg_info = dbgp_ehci_info();
+ unsigned diff;
+
+ if (!dbg_info->ehci_debug)
+ return;
+
+ diff = (unsigned)dbg_info->ehci_caps - ehci_base;
+ dbg_info->ehci_regs -= diff;
+ dbg_info->ehci_debug -= diff;
+ dbg_info->ehci_caps = (void*)ehci_base;
+ dbg_info->status |= DBGP_EP_ENABLED;
+}
+
+static void usbdebug_disable(void)
+{
+ struct ehci_debug_info *dbg_info = dbgp_ehci_info();
+ dbg_info->status &= ~DBGP_EP_ENABLED;
+}
+
+static void pci_ehci_set_resources(struct device *dev)
+{
+ struct resource *res;
+
+ printk(BIOS_DEBUG, "%s EHCI Debug Port hook triggered\n", dev_path(dev));
+ usbdebug_disable();
+
+ if (ehci_drv_ops->set_resources)
+ ehci_drv_ops->set_resources(dev);
+ res = find_resource(dev, EHCI_BAR_INDEX);
+ if (!res)
+ return;
+
+ usbdebug_re_enable((u32)res->base);
+ report_resource_stored(dev, res, "");
+ printk(BIOS_DEBUG, "%s EHCI Debug Port relocated\n", dev_path(dev));
+}
+
+void pci_ehci_read_resources(struct device *dev)
+{
+ if (!ehci_drv_ops) {
+ memcpy(&ehci_dbg_ops, dev->ops, sizeof(ehci_dbg_ops));
+ ehci_drv_ops = dev->ops;
+ ehci_dbg_ops.set_resources = pci_ehci_set_resources;
+ dev->ops = &ehci_dbg_ops;
+ printk(BIOS_DEBUG, "%s EHCI BAR hook registered\n", dev_path(dev));
+ } else {
+ printk(BIOS_DEBUG, "More than one caller of %s from %s\n", __func__, dev_path(dev));
+ }
+
+ pci_dev_read_resources(dev);
+}
+#endif
+
int dbgp_ep_is_active(struct ehci_debug_info *dbg_info)
{
return (dbg_info->status & DBGP_EP_STATMASK) == (DBGP_EP_VALID | DBGP_EP_ENABLED);