From bf9ad82ee961b839654e2322f083c13532f2c0c6 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 11 Jul 2024 01:30:14 -0400 Subject: kernel/amd64: pci: Add support for PCI MSI-X Signed-off-by: Ian Moffett --- sys/dev/pci/pci.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'sys/dev') diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 587881a..65f315d 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,47 @@ pci_dev_exists(uint8_t bus, uint8_t slot, uint8_t func) return true; } +/* + * Attempt to search for a capability within the device + * capability list if it supports one. + * + * @dev: Target device. + * @id: Requested capability ID. + * + * The offset is returned if found, otherwise 0. + * A value less than zero is returned on error. + */ +static int +pci_get_cap(struct pci_device *dev, uint8_t id) +{ + uint16_t status; + uint32_t cap; + uint8_t curid; + uint8_t cap_ptr; + + /* Does the device even support this? */ + status = pci_readl(dev, PCIREG_CMDSTATUS) >> 16; + if (!ISSET(status, PCI_STATUS_CAPLIST)) { + return -ENOTSUP; + } + + cap_ptr = pci_readl(dev, PCIREG_CAPPTR) & 0xFF; + + /* Go through the capability list */ + while (cap_ptr != 0) { + cap = pci_readl(dev, cap_ptr); + curid = cap & 0xFF; + + if (curid == id) { + return cap_ptr; + } + + cap_ptr = (cap >> 8) & 0xFF; + } + + return 0; +} + /* * Sets other device information (device id, vendor id, etc) * @@ -85,6 +127,7 @@ pci_set_device_info(struct pci_device *dev) dev->bar[5] = pci_readl(dev, PCIREG_BAR5); dev->irq_line = pci_readl(dev, PCIREG_IRQLINE) & 0xFF; + dev->msix_capoff = pci_get_cap(dev, PCI_CAP_MSIX); } /* -- cgit v1.2.3