usbdebug: Split PCI EHCI part
There are EHCI compatible host controllers on ARM without PCI bus architecture. Currently we have not come across one with the debug capability though. Change-Id: I8775c9814f6fdf8754f97265118a7186369d721d Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: http://review.coreboot.org/5175 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@google.com>
This commit is contained in:
parent
48e899d2d5
commit
cb141bce35
|
@ -1,3 +1,3 @@
|
|||
romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += ehci_debug.c
|
||||
romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += ehci_debug.c pci_ehci.c
|
||||
|
||||
ramstage-$(CONFIG_USBDEBUG) += ehci_debug.c
|
||||
ramstage-$(CONFIG_USBDEBUG) += ehci_debug.c pci_ehci.c
|
||||
|
|
|
@ -21,15 +21,13 @@
|
|||
#include <stddef.h>
|
||||
#include <console/console.h>
|
||||
#include <console/usb.h>
|
||||
#include <device/pci_ehci.h>
|
||||
#include <arch/io.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <arch/byteorder.h>
|
||||
#include <arch/early_variables.h>
|
||||
#include <string.h>
|
||||
#include <cbmem.h>
|
||||
|
||||
#include "ehci_debug.h"
|
||||
#include "usb_ch9.h"
|
||||
#include "ehci.h"
|
||||
|
||||
|
@ -107,8 +105,6 @@ static int dbgp_enabled(void);
|
|||
#define USB_PID_DATA_TOGGLE 0x88
|
||||
#define DBGP_CLAIM (DBGP_OWNER | DBGP_ENABLED | DBGP_INUSE)
|
||||
|
||||
#define PCI_CAP_ID_EHCI_DEBUG 0xa
|
||||
|
||||
#define HUB_ROOT_RESET_TIME 50 /* times are in msec */
|
||||
#define HUB_SHORT_RESET_TIME 10
|
||||
#define HUB_LONG_RESET_TIME 200
|
||||
|
@ -119,10 +115,6 @@ static int dbgp_enabled(void);
|
|||
#define DBGP_MAX_PACKET 8
|
||||
|
||||
static struct ehci_debug_info glob_dbg_info CAR_GLOBAL;
|
||||
#if !defined(__PRE_RAM__) && !defined(__SMM__)
|
||||
static struct device_operations *ehci_drv_ops;
|
||||
static struct device_operations ehci_dbg_ops;
|
||||
#endif
|
||||
|
||||
static inline struct ehci_debug_info *dbgp_ehci_info(void)
|
||||
{
|
||||
|
@ -580,19 +572,6 @@ err:
|
|||
}
|
||||
#endif /* CONFIG_USBDEBUG_OPTIONAL_HUB_PORT */
|
||||
|
||||
static void enable_usbdebug(void)
|
||||
{
|
||||
#if defined(__PRE_RAM__) || !CONFIG_USBDEBUG_IN_ROMSTAGE
|
||||
pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
|
||||
pci_ehci_dbg_enable(dbg_dev, CONFIG_EHCI_BAR);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void set_debug_port(unsigned int port)
|
||||
{
|
||||
pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
|
||||
pci_ehci_dbg_set_port(dbg_dev, port);
|
||||
}
|
||||
|
||||
static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_info *info)
|
||||
{
|
||||
|
@ -617,9 +596,9 @@ static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_
|
|||
memset(&info->ep_pipe, 0, sizeof (info->ep_pipe));
|
||||
|
||||
if (CONFIG_USBDEBUG_DEFAULT_PORT > 0)
|
||||
set_debug_port(CONFIG_USBDEBUG_DEFAULT_PORT);
|
||||
ehci_debug_select_port(CONFIG_USBDEBUG_DEFAULT_PORT);
|
||||
else
|
||||
set_debug_port(1);
|
||||
ehci_debug_select_port(1);
|
||||
|
||||
try_next_time:
|
||||
port_map_tried = 0;
|
||||
|
@ -640,7 +619,7 @@ try_next_port:
|
|||
|
||||
if(port_map_tried && (new_debug_port != debug_port)) {
|
||||
if(--playtimes) {
|
||||
set_debug_port(debug_port);
|
||||
ehci_debug_select_port(debug_port);
|
||||
goto try_next_time;
|
||||
}
|
||||
return -1;
|
||||
|
@ -847,11 +826,11 @@ next_debug_port:
|
|||
port_map_tried |= (1 << (debug_port - 1));
|
||||
new_debug_port = ((debug_port-1 + 1) % n_ports) + 1;
|
||||
if (port_map_tried != ((1 << n_ports) - 1)) {
|
||||
set_debug_port(new_debug_port);
|
||||
ehci_debug_select_port(new_debug_port);
|
||||
goto try_next_port;
|
||||
}
|
||||
if (--playtimes) {
|
||||
set_debug_port(new_debug_port);
|
||||
ehci_debug_select_port(new_debug_port);
|
||||
goto try_next_time;
|
||||
}
|
||||
#else
|
||||
|
@ -930,7 +909,7 @@ unsigned char usbdebug_rx_byte(struct dbgp_pipe *pipe)
|
|||
}
|
||||
|
||||
#if !defined(__PRE_RAM__) && !defined(__SMM__)
|
||||
static void usbdebug_re_enable(unsigned ehci_base)
|
||||
void usbdebug_re_enable(unsigned ehci_base)
|
||||
{
|
||||
struct ehci_debug_info *dbg_info = dbgp_ehci_info();
|
||||
unsigned diff;
|
||||
|
@ -948,7 +927,7 @@ static void usbdebug_re_enable(unsigned ehci_base)
|
|||
dbg_info->ep_pipe[i].status |= DBGP_EP_ENABLED;
|
||||
}
|
||||
|
||||
static void usbdebug_disable(void)
|
||||
void usbdebug_disable(void)
|
||||
{
|
||||
struct ehci_debug_info *dbg_info = dbgp_ehci_info();
|
||||
int i;
|
||||
|
@ -956,40 +935,6 @@ static void usbdebug_disable(void)
|
|||
dbg_info->ep_pipe[i].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)
|
||||
{
|
||||
pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
|
||||
|
||||
if (!ehci_drv_ops && pci_match_simple_dev(dev, dbg_dev)) {
|
||||
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
|
||||
|
||||
#if !defined(__PRE_RAM__) && !defined(__SMM__)
|
||||
|
@ -1022,17 +967,6 @@ static void migrate_ehci_debug(void)
|
|||
CAR_MIGRATE(migrate_ehci_debug);
|
||||
#endif
|
||||
|
||||
unsigned long pci_ehci_base_regs(pci_devfn_t sdev)
|
||||
{
|
||||
#ifdef __SIMPLE_DEVICE__
|
||||
unsigned long base = pci_read_config32(sdev, EHCI_BAR_INDEX) & ~0x0f;
|
||||
#else
|
||||
device_t dev = dev_find_slot(PCI_DEV2SEGBUS(sdev), PCI_DEV2DEVFN(sdev));
|
||||
unsigned long base = pci_read_config32(dev, EHCI_BAR_INDEX) & ~0x0f;
|
||||
#endif
|
||||
return base + HC_LENGTH(read32(base));
|
||||
}
|
||||
|
||||
int dbgp_ep_is_active(struct dbgp_pipe *pipe)
|
||||
{
|
||||
return (pipe->status & DBGP_EP_STATMASK) == (DBGP_EP_VALID | DBGP_EP_ENABLED);
|
||||
|
@ -1056,6 +990,6 @@ int usbdebug_init(void)
|
|||
if (!get_usbdebug_from_cbmem(dbg_info))
|
||||
return 0;
|
||||
#endif
|
||||
enable_usbdebug();
|
||||
ehci_debug_hw_enable();
|
||||
return usbdebug_init_(CONFIG_EHCI_BAR, CONFIG_EHCI_DEBUG_OFFSET, dbg_info);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007 AMD
|
||||
* Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _EHCI_DEBUG_H_
|
||||
#define _EHCI_DEBUG_H_
|
||||
|
||||
void usbdebug_re_enable(unsigned ehci_base);
|
||||
void usbdebug_disable(void);
|
||||
|
||||
void ehci_debug_hw_enable(void);
|
||||
void ehci_debug_select_port(unsigned int port);
|
||||
|
||||
#endif /* _EHCI_DEBUG_H_ */
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2006 Eric Biederman (ebiederm@xmission.com)
|
||||
* Copyright (C) 2007 AMD
|
||||
*
|
||||
* 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 <stddef.h>
|
||||
#include <console/console.h>
|
||||
#include <device/pci_ehci.h>
|
||||
#include <arch/io.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ehci_debug.h"
|
||||
#include "ehci.h"
|
||||
|
||||
#if !defined(__PRE_RAM__) && !defined(__SMM__)
|
||||
static struct device_operations *ehci_drv_ops;
|
||||
static struct device_operations ehci_dbg_ops;
|
||||
#endif
|
||||
|
||||
void ehci_debug_hw_enable(void)
|
||||
{
|
||||
#if defined(__PRE_RAM__) || !CONFIG_USBDEBUG_IN_ROMSTAGE
|
||||
pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
|
||||
pci_ehci_dbg_enable(dbg_dev, CONFIG_EHCI_BAR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ehci_debug_select_port(unsigned int port)
|
||||
{
|
||||
pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
|
||||
pci_ehci_dbg_set_port(dbg_dev, port);
|
||||
}
|
||||
|
||||
#if !defined(__PRE_RAM__) && !defined(__SMM__)
|
||||
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)
|
||||
{
|
||||
pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
|
||||
|
||||
if (!ehci_drv_ops && pci_match_simple_dev(dev, dbg_dev)) {
|
||||
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
|
||||
|
||||
unsigned long pci_ehci_base_regs(pci_devfn_t sdev)
|
||||
{
|
||||
#ifdef __SIMPLE_DEVICE__
|
||||
unsigned long base = pci_read_config32(sdev, EHCI_BAR_INDEX) & ~0x0f;
|
||||
#else
|
||||
device_t dev = dev_find_slot(PCI_DEV2SEGBUS(sdev), PCI_DEV2DEVFN(sdev));
|
||||
unsigned long base = pci_read_config32(dev, EHCI_BAR_INDEX) & ~0x0f;
|
||||
#endif
|
||||
return base + HC_LENGTH(read32(base));
|
||||
}
|
||||
|
|
@ -181,6 +181,7 @@
|
|||
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
|
||||
#define PCI_CAP_ID_PCIX 0x07 /* PCIX */
|
||||
#define PCI_CAP_ID_HT 0x08 /* Hypertransport */
|
||||
#define PCI_CAP_ID_EHCI_DEBUG 0x0A /* EHCI debug port */
|
||||
#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
|
||||
#define PCI_CAP_ID_PCIE 0x10 /* PCI Express */
|
||||
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
|
||||
|
|
Loading…
Reference in New Issue