]>
Commit | Line | Data |
---|---|---|
f7d6f3fa MA |
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 | ||
ee640c62 | 32 | rc = msix_init_exclusive_bar(d, GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR, 0, errp); |
f7d6f3fa MA |
33 | |
34 | if (rc < 0) { | |
35 | assert(rc == -ENOTSUP); | |
f7d6f3fa MA |
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) |