1*5ef4a0cbSMarkus Armbruster /* 2*5ef4a0cbSMarkus Armbruster * HMP commands related to PCI 3*5ef4a0cbSMarkus Armbruster * 4*5ef4a0cbSMarkus Armbruster * Copyright IBM, Corp. 2011 5*5ef4a0cbSMarkus Armbruster * 6*5ef4a0cbSMarkus Armbruster * Authors: 7*5ef4a0cbSMarkus Armbruster * Anthony Liguori <aliguori@us.ibm.com> 8*5ef4a0cbSMarkus Armbruster * 9*5ef4a0cbSMarkus Armbruster * This work is licensed under the terms of the GNU GPL, version 2. See 10*5ef4a0cbSMarkus Armbruster * the COPYING file in the top-level directory. 11*5ef4a0cbSMarkus Armbruster * 12*5ef4a0cbSMarkus Armbruster * Contributions after 2012-01-13 are licensed under the terms of the 13*5ef4a0cbSMarkus Armbruster * GNU GPL, version 2 or (at your option) any later version. 14*5ef4a0cbSMarkus Armbruster */ 15*5ef4a0cbSMarkus Armbruster 16*5ef4a0cbSMarkus Armbruster #include "qemu/osdep.h" 17*5ef4a0cbSMarkus Armbruster #include "monitor/hmp.h" 18*5ef4a0cbSMarkus Armbruster #include "monitor/monitor.h" 19*5ef4a0cbSMarkus Armbruster #include "qapi/error.h" 20*5ef4a0cbSMarkus Armbruster #include "qapi/qapi-commands-pci.h" 21*5ef4a0cbSMarkus Armbruster 22*5ef4a0cbSMarkus Armbruster static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev) 23*5ef4a0cbSMarkus Armbruster { 24*5ef4a0cbSMarkus Armbruster PciMemoryRegionList *region; 25*5ef4a0cbSMarkus Armbruster 26*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " Bus %2" PRId64 ", ", dev->bus); 27*5ef4a0cbSMarkus Armbruster monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n", 28*5ef4a0cbSMarkus Armbruster dev->slot, dev->function); 29*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " "); 30*5ef4a0cbSMarkus Armbruster 31*5ef4a0cbSMarkus Armbruster if (dev->class_info->desc) { 32*5ef4a0cbSMarkus Armbruster monitor_puts(mon, dev->class_info->desc); 33*5ef4a0cbSMarkus Armbruster } else { 34*5ef4a0cbSMarkus Armbruster monitor_printf(mon, "Class %04" PRId64, dev->class_info->q_class); 35*5ef4a0cbSMarkus Armbruster } 36*5ef4a0cbSMarkus Armbruster 37*5ef4a0cbSMarkus Armbruster monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n", 38*5ef4a0cbSMarkus Armbruster dev->id->vendor, dev->id->device); 39*5ef4a0cbSMarkus Armbruster if (dev->id->has_subsystem_vendor && dev->id->has_subsystem) { 40*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " PCI subsystem %04" PRIx64 ":%04" PRIx64 "\n", 41*5ef4a0cbSMarkus Armbruster dev->id->subsystem_vendor, dev->id->subsystem); 42*5ef4a0cbSMarkus Armbruster } 43*5ef4a0cbSMarkus Armbruster 44*5ef4a0cbSMarkus Armbruster if (dev->has_irq) { 45*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " IRQ %" PRId64 ", pin %c\n", 46*5ef4a0cbSMarkus Armbruster dev->irq, (char)('A' + dev->irq_pin - 1)); 47*5ef4a0cbSMarkus Armbruster } 48*5ef4a0cbSMarkus Armbruster 49*5ef4a0cbSMarkus Armbruster if (dev->pci_bridge) { 50*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " BUS %" PRId64 ".\n", 51*5ef4a0cbSMarkus Armbruster dev->pci_bridge->bus->number); 52*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " secondary bus %" PRId64 ".\n", 53*5ef4a0cbSMarkus Armbruster dev->pci_bridge->bus->secondary); 54*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " subordinate bus %" PRId64 ".\n", 55*5ef4a0cbSMarkus Armbruster dev->pci_bridge->bus->subordinate); 56*5ef4a0cbSMarkus Armbruster 57*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n", 58*5ef4a0cbSMarkus Armbruster dev->pci_bridge->bus->io_range->base, 59*5ef4a0cbSMarkus Armbruster dev->pci_bridge->bus->io_range->limit); 60*5ef4a0cbSMarkus Armbruster 61*5ef4a0cbSMarkus Armbruster monitor_printf(mon, 62*5ef4a0cbSMarkus Armbruster " memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n", 63*5ef4a0cbSMarkus Armbruster dev->pci_bridge->bus->memory_range->base, 64*5ef4a0cbSMarkus Armbruster dev->pci_bridge->bus->memory_range->limit); 65*5ef4a0cbSMarkus Armbruster 66*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " prefetchable memory range " 67*5ef4a0cbSMarkus Armbruster "[0x%08"PRIx64", 0x%08"PRIx64"]\n", 68*5ef4a0cbSMarkus Armbruster dev->pci_bridge->bus->prefetchable_range->base, 69*5ef4a0cbSMarkus Armbruster dev->pci_bridge->bus->prefetchable_range->limit); 70*5ef4a0cbSMarkus Armbruster } 71*5ef4a0cbSMarkus Armbruster 72*5ef4a0cbSMarkus Armbruster for (region = dev->regions; region; region = region->next) { 73*5ef4a0cbSMarkus Armbruster uint64_t addr, size; 74*5ef4a0cbSMarkus Armbruster 75*5ef4a0cbSMarkus Armbruster addr = region->value->address; 76*5ef4a0cbSMarkus Armbruster size = region->value->size; 77*5ef4a0cbSMarkus Armbruster 78*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " BAR%" PRId64 ": ", region->value->bar); 79*5ef4a0cbSMarkus Armbruster 80*5ef4a0cbSMarkus Armbruster if (!strcmp(region->value->type, "io")) { 81*5ef4a0cbSMarkus Armbruster monitor_printf(mon, "I/O at 0x%04" PRIx64 82*5ef4a0cbSMarkus Armbruster " [0x%04" PRIx64 "].\n", 83*5ef4a0cbSMarkus Armbruster addr, addr + size - 1); 84*5ef4a0cbSMarkus Armbruster } else { 85*5ef4a0cbSMarkus Armbruster monitor_printf(mon, "%d bit%s memory at 0x%08" PRIx64 86*5ef4a0cbSMarkus Armbruster " [0x%08" PRIx64 "].\n", 87*5ef4a0cbSMarkus Armbruster region->value->mem_type_64 ? 64 : 32, 88*5ef4a0cbSMarkus Armbruster region->value->prefetch ? " prefetchable" : "", 89*5ef4a0cbSMarkus Armbruster addr, addr + size - 1); 90*5ef4a0cbSMarkus Armbruster } 91*5ef4a0cbSMarkus Armbruster } 92*5ef4a0cbSMarkus Armbruster 93*5ef4a0cbSMarkus Armbruster monitor_printf(mon, " id \"%s\"\n", dev->qdev_id); 94*5ef4a0cbSMarkus Armbruster 95*5ef4a0cbSMarkus Armbruster if (dev->pci_bridge) { 96*5ef4a0cbSMarkus Armbruster if (dev->pci_bridge->has_devices) { 97*5ef4a0cbSMarkus Armbruster PciDeviceInfoList *cdev; 98*5ef4a0cbSMarkus Armbruster for (cdev = dev->pci_bridge->devices; cdev; cdev = cdev->next) { 99*5ef4a0cbSMarkus Armbruster hmp_info_pci_device(mon, cdev->value); 100*5ef4a0cbSMarkus Armbruster } 101*5ef4a0cbSMarkus Armbruster } 102*5ef4a0cbSMarkus Armbruster } 103*5ef4a0cbSMarkus Armbruster } 104*5ef4a0cbSMarkus Armbruster 105*5ef4a0cbSMarkus Armbruster void hmp_info_pci(Monitor *mon, const QDict *qdict) 106*5ef4a0cbSMarkus Armbruster { 107*5ef4a0cbSMarkus Armbruster PciInfoList *info_list, *info; 108*5ef4a0cbSMarkus Armbruster Error *err = NULL; 109*5ef4a0cbSMarkus Armbruster 110*5ef4a0cbSMarkus Armbruster info_list = qmp_query_pci(&err); 111*5ef4a0cbSMarkus Armbruster if (err) { 112*5ef4a0cbSMarkus Armbruster monitor_printf(mon, "PCI devices not supported\n"); 113*5ef4a0cbSMarkus Armbruster error_free(err); 114*5ef4a0cbSMarkus Armbruster return; 115*5ef4a0cbSMarkus Armbruster } 116*5ef4a0cbSMarkus Armbruster 117*5ef4a0cbSMarkus Armbruster for (info = info_list; info; info = info->next) { 118*5ef4a0cbSMarkus Armbruster PciDeviceInfoList *dev; 119*5ef4a0cbSMarkus Armbruster 120*5ef4a0cbSMarkus Armbruster for (dev = info->value->devices; dev; dev = dev->next) { 121*5ef4a0cbSMarkus Armbruster hmp_info_pci_device(mon, dev->value); 122*5ef4a0cbSMarkus Armbruster } 123*5ef4a0cbSMarkus Armbruster } 124*5ef4a0cbSMarkus Armbruster 125*5ef4a0cbSMarkus Armbruster qapi_free_PciInfoList(info_list); 126*5ef4a0cbSMarkus Armbruster } 127