diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2013-07-09 04:19:22 +0300 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2013-07-10 23:24:20 +0200 |
commit | 41c10cd2d73198e61573af1341d5826654f1133a (patch) | |
tree | 9d8679061185e42ba6b166ac0c573aa920c2b63b /src/lib | |
parent | 9e7806a788f9617d3dd9139a74ab3f7b03eb9581 (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.c | 59 |
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); |