1 /* 2 * Generic PCI Express Root Port emulation 3 * 4 * Copyright (C) 2017 Red Hat Inc 5 * 6 * Authors: 7 * Marcel Apfelbaum <marcel@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "qapi/error.h" 15 #include "hw/pci/msix.h" 16 #include "hw/pci/pcie_port.h" 17 18 #define TYPE_GEN_PCIE_ROOT_PORT "pcie-root-port" 19 20 #define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100 21 #define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1 22 23 static uint8_t gen_rp_aer_vector(const PCIDevice *d) 24 { 25 return 0; 26 } 27 28 static int gen_rp_interrupts_init(PCIDevice *d, Error **errp) 29 { 30 int rc; 31 32 rc = msix_init_exclusive_bar(d, GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR, 0, errp); 33 34 if (rc < 0) { 35 assert(rc == -ENOTSUP); 36 } else { 37 msix_vector_use(d, 0); 38 } 39 40 return rc; 41 } 42 43 static void gen_rp_interrupts_uninit(PCIDevice *d) 44 { 45 msix_uninit_exclusive_bar(d); 46 } 47 48 static const VMStateDescription vmstate_rp_dev = { 49 .name = "pcie-root-port", 50 .version_id = 1, 51 .minimum_version_id = 1, 52 .post_load = pcie_cap_slot_post_load, 53 .fields = (VMStateField[]) { 54 VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj, PCIESlot), 55 VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.exp.aer_log, 56 PCIESlot, 0, vmstate_pcie_aer_log, PCIEAERLog), 57 VMSTATE_END_OF_LIST() 58 } 59 }; 60 61 static void gen_rp_dev_class_init(ObjectClass *klass, void *data) 62 { 63 DeviceClass *dc = DEVICE_CLASS(klass); 64 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 65 PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass); 66 67 k->vendor_id = PCI_VENDOR_ID_REDHAT; 68 k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_RP; 69 dc->desc = "PCI Express Root Port"; 70 dc->vmsd = &vmstate_rp_dev; 71 rpc->aer_vector = gen_rp_aer_vector; 72 rpc->interrupts_init = gen_rp_interrupts_init; 73 rpc->interrupts_uninit = gen_rp_interrupts_uninit; 74 rpc->aer_offset = GEN_PCIE_ROOT_PORT_AER_OFFSET; 75 } 76 77 static const TypeInfo gen_rp_dev_info = { 78 .name = TYPE_GEN_PCIE_ROOT_PORT, 79 .parent = TYPE_PCIE_ROOT_PORT, 80 .class_init = gen_rp_dev_class_init, 81 }; 82 83 static void gen_rp_register_types(void) 84 { 85 type_register_static(&gen_rp_dev_info); 86 } 87 type_init(gen_rp_register_types) 88