From mboxrd@z Thu Jan 1 00:00:00 1970 From: Peter Xu Subject: [PATCH v3 09/25] pci: Add pci_print() Date: Mon, 14 Nov 2016 17:19:05 -0500 Message-ID: <1479161961-20304-10-git-send-email-peterx@redhat.com> References: <1479161961-20304-1-git-send-email-peterx@redhat.com> Cc: drjones@redhat.com, agordeev@redhat.com, jan.kiszka@web.de, rkrcmar@redhat.com, pbonzini@redhat.com, peterx@redhat.com To: kvm@vger.kernel.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:40526 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964810AbcKNWTe (ORCPT ); Mon, 14 Nov 2016 17:19:34 -0500 In-Reply-To: <1479161961-20304-1-git-send-email-peterx@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: From: Alexander Gordeev Cc: Thomas Huth Cc: Andrew Jones Cc: Peter Xu Suggested-by: Andrew Jones Reviewed-by: Andrew Jones Signed-off-by: Alexander Gordeev --- lib/pci.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/pci.h | 3 +++ 2 files changed, 92 insertions(+) diff --git a/lib/pci.c b/lib/pci.c index 42f47d9..e03c67c 100644 --- a/lib/pci.c +++ b/lib/pci.c @@ -126,3 +126,92 @@ bool pci_bar_is64(pcidevaddr_t dev, int bar_num) return (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64; } + +static void pci_bar_print(pcidevaddr_t dev, int bar_num) +{ + phys_addr_t size, start, end; + uint32_t bar; + + size = pci_bar_size(dev, bar_num); + if (!size) + return; + + bar = pci_bar_get(dev, bar_num); + start = pci_bar_get_addr(dev, bar_num); + end = start + size - 1; + + if (pci_bar_is64(dev, bar_num)) { + printf("BAR#%d,%d [%" PRIx64 "-%" PRIx64 " ", + bar_num, bar_num + 1, start, end); + } else { + printf("BAR#%d [%02x-%02x ", + bar_num, (uint32_t)start, (uint32_t)end); + } + + if (bar & PCI_BASE_ADDRESS_SPACE_IO) { + printf("PIO"); + } else { + printf("MEM"); + switch (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) { + case PCI_BASE_ADDRESS_MEM_TYPE_32: + printf("32"); + break; + case PCI_BASE_ADDRESS_MEM_TYPE_1M: + printf("1M"); + break; + case PCI_BASE_ADDRESS_MEM_TYPE_64: + printf("64"); + break; + default: + assert(0); + } + } + + if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) + printf("/p"); + + printf("]"); +} + +static void pci_dev_print_id(pcidevaddr_t dev) +{ + printf("00.%02x.%1x %04x:%04x", dev / 8, dev % 8, + pci_config_readw(dev, PCI_VENDOR_ID), + pci_config_readw(dev, PCI_DEVICE_ID)); +} + +static void pci_dev_print(pcidevaddr_t dev) +{ + uint8_t header = pci_config_readb(dev, PCI_HEADER_TYPE); + uint8_t progif = pci_config_readb(dev, PCI_CLASS_PROG); + uint8_t subclass = pci_config_readb(dev, PCI_CLASS_DEVICE); + uint8_t class = pci_config_readb(dev, PCI_CLASS_DEVICE + 1); + int i; + + pci_dev_print_id(dev); + printf(" type %02x progif %02x class %02x subclass %02x\n", + header, progif, class, subclass); + + if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL) + return; + + for (i = 0; i < 6; i++) { + if (pci_bar_size(dev, i)) { + printf("\t"); + pci_bar_print(dev, i); + printf("\n"); + } + if (pci_bar_is64(dev, i)) + i++; + } +} + +void pci_print(void) +{ + pcidevaddr_t dev; + + for (dev = 0; dev < 256; ++dev) { + if (pci_dev_exists(dev)) + pci_dev_print(dev); + } +} diff --git a/lib/pci.h b/lib/pci.h index 1462aa2..fc0940a 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -15,6 +15,7 @@ enum { PCIDEVADDR_INVALID = 0xffff, }; +extern void pci_print(void); extern bool pci_dev_exists(pcidevaddr_t dev); extern pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id); @@ -57,4 +58,6 @@ struct pci_test_dev_hdr { uint8_t name[]; }; +#define PCI_HEADER_TYPE_MASK 0x7f + #endif /* PCI_H */ -- 2.7.4