From 2161c1d792fedecfad32587b6fde657c19d647d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Tue, 11 Feb 2014 19:56:57 +0200 Subject: PCI: Add capability list parser to romstage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are almost one-to-one copies from pci_device.c. However, devicetree has not been enumerated yet and we have no console. Change-Id: Ic80c781626521d03adde05bdb1916acce31290ea Signed-off-by: Kyösti Mälkki Reviewed-on: http://review.coreboot.org/5196 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Aaron Durbin --- src/device/Makefile.inc | 3 ++- src/device/pci_early.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ src/include/device/pci.h | 6 +++-- 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 src/device/pci_early.c (limited to 'src') diff --git a/src/device/Makefile.inc b/src/device/Makefile.inc index 1dbb510024..ce412b7840 100644 --- a/src/device/Makefile.inc +++ b/src/device/Makefile.inc @@ -13,7 +13,8 @@ ramstage-$(CONFIG_ARCH_X86) += pnp_device.c ramstage-$(CONFIG_PCI) += pci_ops.c ramstage-y += smbus_ops.c -romstage-y+= device_romstage.c +romstage-y += device_romstage.c +romstage-$(CONFIG_PCI) += pci_early.c subdirs-y += oprom diff --git a/src/device/pci_early.c b/src/device/pci_early.c new file mode 100644 index 0000000000..c15a4d0f77 --- /dev/null +++ b/src/device/pci_early.c @@ -0,0 +1,68 @@ +/* + * This file is part of the coreboot project. + * + * 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 +#include +#include + +unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last) +{ + unsigned pos = 0; + u16 status; + unsigned reps = 48; + + status = pci_read_config16(dev, PCI_STATUS); + if (!(status & PCI_STATUS_CAP_LIST)) + return 0; + + u8 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); + switch (hdr_type & 0x7f) { + case PCI_HEADER_TYPE_NORMAL: + case PCI_HEADER_TYPE_BRIDGE: + pos = PCI_CAPABILITY_LIST; + break; + case PCI_HEADER_TYPE_CARDBUS: + pos = PCI_CB_CAPABILITY_LIST; + break; + default: + return 0; + } + + pos = pci_read_config8(dev, pos); + while (reps-- && (pos >= 0x40)) { /* Loop through the linked list. */ + int this_cap; + + pos &= ~3; + this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID); + if (this_cap == 0xff) + break; + + if (!last && (this_cap == cap)) + return pos; + + if (last == pos) + last = 0; + + pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT); + } + return 0; +} + +unsigned pci_find_capability(device_t dev, unsigned cap) +{ + return pci_find_next_capability(dev, cap, 0); +} diff --git a/src/include/device/pci.h b/src/include/device/pci.h index 7504cc7269..29d988fd9e 100644 --- a/src/include/device/pci.h +++ b/src/include/device/pci.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -76,8 +77,6 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devf uint8_t pci_moving_config8(struct device *dev, unsigned reg); uint16_t pci_moving_config16(struct device *dev, unsigned reg); uint32_t pci_moving_config32(struct device *dev, unsigned reg); -unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last); -unsigned pci_find_capability(device_t dev, unsigned cap); struct resource *pci_get_resource(struct device *dev, unsigned long index); void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device); void pci_dev_init(struct device *dev); @@ -101,6 +100,9 @@ static inline const struct pci_operations *ops_pci(device_t dev) #endif /* ! __SIMPLE_DEVICE__ */ +unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last); +unsigned pci_find_capability(device_t dev, unsigned cap); + #endif /* CONFIG_PCI */ #endif /* PCI_H */ -- cgit v1.2.3