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); 33 34 if (rc < 0) { 35 assert(rc == -ENOTSUP); 36 error_setg(errp, "Unable to init msix vectors"); 37 } else { 38 msix_vector_use(d, 0); 39 } 40 41 return rc; 42 } 43 44 static void gen_rp_interrupts_uninit(PCIDevice *d) 45 { 46 msix_uninit_exclusive_bar(d); 47 } 48 49 static const VMStateDescription vmstate_rp_dev = { 50 .name = "pcie-root-port", 51 .version_id = 1, 52 .minimum_version_id = 1, 53 .post_load = pcie_cap_slot_post_load, 54 .fields = (VMStateField[]) { 55 VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj, PCIESlot), 56 VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.exp.aer_log, 57 PCIESlot, 0, vmstate_pcie_aer_log, PCIEAERLog), 58 VMSTATE_END_OF_LIST() 59 } 60 }; 61 62 static void gen_rp_dev_class_init(ObjectClass *klass, void *data) 63 { 64 DeviceClass *dc = DEVICE_CLASS(klass); 65 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 66 PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass); 67 68 k->vendor_id = PCI_VENDOR_ID_REDHAT; 69 k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_RP; 70 dc->desc = "PCI Express Root Port"; 71 dc->vmsd = &vmstate_rp_dev; 72 rpc->aer_vector = gen_rp_aer_vector; 73 rpc->interrupts_init = gen_rp_interrupts_init; 74 rpc->interrupts_uninit = gen_rp_interrupts_uninit; 75 rpc->aer_offset = GEN_PCIE_ROOT_PORT_AER_OFFSET; 76 } 77 78 static const TypeInfo gen_rp_dev_info = { 79 .name = TYPE_GEN_PCIE_ROOT_PORT, 80 .parent = TYPE_PCIE_ROOT_PORT, 81 .class_init = gen_rp_dev_class_init, 82 }; 83 84 static void gen_rp_register_types(void) 85 { 86 type_register_static(&gen_rp_dev_info); 87 } 88 type_init(gen_rp_register_types) 89