Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5196
-gerrit
commit ad93af5c5e48c4882a63447b9d3b8d1def8f7277 Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Tue Feb 11 19:56:57 2014 +0200
PCI: Add capability list parser to romstage
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 kyosti.malkki@gmail.com --- src/device/Makefile.inc | 3 ++- src/device/pci_early.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ src/include/device/pci.h | 6 +++-- 3 files changed, 74 insertions(+), 3 deletions(-)
diff --git a/src/device/Makefile.inc b/src/device/Makefile.inc index 1dbb510..ce412b7 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 0000000..c15a4d0 --- /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 <arch/io.h> +#include <device/pci.h> +#include <device/pci_def.h> + +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 7504cc7..29d988f 100644 --- a/src/include/device/pci.h +++ b/src/include/device/pci.h @@ -20,6 +20,7 @@ #include <stdint.h> #include <stddef.h> #include <arch/rules.h> +#include <arch/io.h> #include <device/pci_def.h> #include <device/resource.h> #include <device/device.h> @@ -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 */