aboutsummaryrefslogtreecommitdiff
path: root/src/device/pci_ops.c
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2019-01-23 16:46:35 +0200
committerKyösti Mälkki <kyosti.malkki@gmail.com>2019-07-04 09:36:19 +0000
commit9c0e14e7c43e85e99c0bbfdff72019d908de1711 (patch)
treeef1a0ffee2d7a542a2c8ccb8d2f8cba74114628b /src/device/pci_ops.c
parentdace2498ecfadf645599aaa3ba8fef8cbb111c2d (diff)
device/pci_ops: Define pci_find_capability() just once
Wrap the simple romstage implementation to be called from ramstage. Change-Id: Iadadf3d550416850d6c37233bd4eda025f4d3960 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/31755 Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Martin Roth <martinroth@google.com> Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr> Reviewed-by: Angel Pons <th3fanbus@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/device/pci_ops.c')
-rw-r--r--src/device/pci_ops.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/device/pci_ops.c b/src/device/pci_ops.c
index 34f9d1e5b5..96133155be 100644
--- a/src/device/pci_ops.c
+++ b/src/device/pci_ops.c
@@ -11,6 +11,77 @@
* GNU General Public License for more details.
*/
+#define __SIMPLE_DEVICE__
+
#include <stdint.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <device/pci_type.h>
u8 *const pci_mmconf = (void *)(uintptr_t)CONFIG_MMCONF_BASE_ADDRESS;
+
+/**
+ * Given a device, a capability type, and a last position, return the next
+ * matching capability. Always start at the head of the list.
+ *
+ * @param dev Pointer to the device structure.
+ * @param cap PCI_CAP_LIST_ID of the PCI capability we're looking for.
+ * @param last Location of the PCI capability register to start from.
+ * @return The next matching capability.
+ */
+u16 pci_s_find_next_capability(pci_devfn_t dev, u16 cap, u16 last)
+{
+ u16 pos = 0;
+ u16 status;
+ int reps = 48;
+
+ status = pci_s_read_config16(dev, PCI_STATUS);
+ if (!(status & PCI_STATUS_CAP_LIST))
+ return 0;
+
+ u8 hdr_type = pci_s_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_s_read_config8(dev, pos);
+ while (reps-- && (pos >= 0x40)) { /* Loop through the linked list. */
+ int this_cap;
+
+ pos &= ~3;
+ this_cap = pci_s_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_s_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
+ }
+ return 0;
+}
+
+/**
+ * Given a device, and a capability type, return the next matching
+ * capability. Always start at the head of the list.
+ *
+ * @param dev Pointer to the device structure.
+ * @param cap PCI_CAP_LIST_ID of the PCI capability we're looking for.
+ * @return The next matching capability.
+ */
+u16 pci_s_find_capability(pci_devfn_t dev, u16 cap)
+{
+ return pci_s_find_next_capability(dev, cap, 0);
+}