From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexander Gordeev Subject: [PATCH RFC 10/15] pci: Add pci_print() and pci_type_desc() Date: Mon, 11 Apr 2016 13:04:22 +0200 Message-ID: <61b7a4edb47fd1412874cefd22a39e1e42041d19.1460190352.git.agordeev@redhat.com> References: Cc: Alexander Gordeev , Thomas Huth , Andrew Jones To: kvm@vger.kernel.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:36632 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753371AbcDKLEx (ORCPT ); Mon, 11 Apr 2016 07:04:53 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F2B603D3 for ; Mon, 11 Apr 2016 11:04:47 +0000 (UTC) In-Reply-To: Sender: kvm-owner@vger.kernel.org List-ID: Cc: Thomas Huth Cc: Andrew Jones Signed-off-by: Alexander Gordeev --- lib/asm-generic/pci.h | 6 +++++ lib/pci.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/pci.h | 3 +++ 3 files changed, 76 insertions(+) diff --git a/lib/asm-generic/pci.h b/lib/asm-generic/pci.h index 15f23079f27e..3f2c6913f0d4 100644 --- a/lib/asm-generic/pci.h +++ b/lib/asm-generic/pci.h @@ -22,4 +22,10 @@ phys_addr_t pci_xlate_addr(pcidevaddr_t __unused dev, uint64_t addr) } #endif +#ifndef pci_print_arch +static inline void pci_print_arch(void) +{ +} +#endif + #endif diff --git a/lib/pci.c b/lib/pci.c index 46aee60e0f90..a3c680670fe0 100644 --- a/lib/pci.c +++ b/lib/pci.c @@ -116,3 +116,70 @@ bool pci_bar_is64(pcidevaddr_t dev, int bar_num) else return false; } + +void pci_type_desc(int type, char *desc, int len) +{ + if ((type & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { + strcpy(desc, "PIO"); /* strncpy() would be better */ + } else { + static char *str[] = { "32", "1M", "64" }; + int idx = (type & PCI_BASE_ADDRESS_MEM_TYPE_MASK) >> 1; + int pfetch = type & PCI_BASE_ADDRESS_MEM_PREFETCH; + snprintf(desc, len, "MEM%s%s", str[idx], pfetch ? "/p" : ""); + } +} + +static void pci_dev_print(pcidevaddr_t dev) +{ + uint16_t vendor_id = pci_config_readw(dev, PCI_VENDOR_ID); + uint16_t device_id = pci_config_readw(dev, PCI_DEVICE_ID); + 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 bar; + + printf("dev %2d fn %d vendor_id %04x device_id %04x type %02x " + "progif %02x class %02x subclass %02x\n", + dev / 8, dev % 8, vendor_id, device_id, header, + progif, class, subclass); + + if (header != PCI_HEADER_TYPE_NORMAL) + return; + + for (bar = 0; bar < 6; bar++) { + phys_addr_t start, end; + char desc[8]; + + if (!pci_bar_is_valid(dev, bar)) + break; + + start = pci_bar_addr(dev, bar); + end = start + pci_bar_size(dev, bar) - 1; + + pci_type_desc(bar, desc, sizeof(desc)); + + if (pci_bar_is64(dev, bar)) { + printf("\tBAR#%d,%d [%-7s %" PRIx64 "-%" PRIx64 "]\n", + bar, bar + 1, desc, start, end); + bar++; + } else { + printf("\tBAR#%d [%-7s %02x-%02x]\n", + bar, desc, (uint32_t)start, (uint32_t)end); + } + } +} + +void pci_print(void) +{ + pcidevaddr_t dev; + + pci_print_arch(); + + for (dev = 0; dev < 256; ++dev) { + if (pci_config_readw(dev, PCI_VENDOR_ID) != (uint16_t)~0 && + pci_config_readw(dev, PCI_DEVICE_ID) != (uint16_t)~0) { + pci_dev_print(dev); + } + } +} diff --git a/lib/pci.h b/lib/pci.h index 69d2a62f1b32..36dd67e19838 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -22,6 +22,9 @@ bool pci_bar_is64(pcidevaddr_t dev, int bar_num); bool pci_bar_is_memory(pcidevaddr_t dev, int bar_num); bool pci_bar_is_valid(pcidevaddr_t dev, int bar_num); +void pci_type_desc(int type, char *desc, int len); +void pci_print(void); + /* * pci-testdev is a driver for the pci-testdev qemu pci device. The * device enables testing mmio and portio exits, and measuring their -- 1.8.3.1