1 /* 2 * Base class for PCI Express Root Ports 3 * 4 * Copyright (C) 2017 Red Hat Inc 5 * 6 * Authors: 7 * Marcel Apfelbaum <marcel@redhat.com> 8 * 9 * Most of the code was migrated from hw/pci-bridge/ioh3420. 10 * 11 * This work is licensed under the terms of the GNU GPL, version 2 or later. 12 * See the COPYING file in the top-level directory. 13 */ 14 15 #include "qemu/osdep.h" 16 #include "qapi/error.h" 17 #include "qemu/module.h" 18 #include "hw/pci/pcie_port.h" 19 #include "hw/qdev-properties.h" 20 21 static void rp_aer_vector_update(PCIDevice *d) 22 { 23 PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); 24 25 if (rpc->aer_vector) { 26 pcie_aer_root_set_vector(d, rpc->aer_vector(d)); 27 } 28 } 29 30 static void rp_write_config(PCIDevice *d, uint32_t address, 31 uint32_t val, int len) 32 { 33 uint32_t root_cmd = 34 pci_get_long(d->config + d->exp.aer_cap + PCI_ERR_ROOT_COMMAND); 35 uint16_t slt_ctl, slt_sta; 36 37 pcie_cap_slot_get(d, &slt_ctl, &slt_sta); 38 39 pci_bridge_write_config(d, address, val, len); 40 rp_aer_vector_update(d); 41 pcie_cap_slot_write_config(d, slt_ctl, slt_sta, address, val, len); 42 pcie_aer_write_config(d, address, val, len); 43 pcie_aer_root_write_config(d, address, val, len, root_cmd); 44 } 45 46 static void rp_reset(DeviceState *qdev) 47 { 48 PCIDevice *d = PCI_DEVICE(qdev); 49 50 rp_aer_vector_update(d); 51 pcie_cap_root_reset(d); 52 pcie_cap_deverr_reset(d); 53 pcie_cap_slot_reset(d); 54 pcie_cap_arifwd_reset(d); 55 pcie_acs_reset(d); 56 pcie_aer_root_reset(d); 57 pci_bridge_reset(qdev); 58 pci_bridge_disable_base_limit(d); 59 } 60 61 static void rp_realize(PCIDevice *d, Error **errp) 62 { 63 PCIEPort *p = PCIE_PORT(d); 64 PCIESlot *s = PCIE_SLOT(d); 65 PCIDeviceClass *dc = PCI_DEVICE_GET_CLASS(d); 66 PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); 67 int rc; 68 69 pci_config_set_interrupt_pin(d->config, 1); 70 if (d->cap_present & QEMU_PCIE_CAP_CXL) { 71 pci_bridge_initfn(d, TYPE_CXL_BUS); 72 } else { 73 pci_bridge_initfn(d, TYPE_PCIE_BUS); 74 } 75 pcie_port_init_reg(d); 76 77 rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id, 78 rpc->ssid, errp); 79 if (rc < 0) { 80 error_append_hint(errp, "Can't init SSV ID, error %d\n", rc); 81 goto err_bridge; 82 } 83 84 if (rpc->interrupts_init) { 85 rc = rpc->interrupts_init(d, errp); 86 if (rc < 0) { 87 goto err_bridge; 88 } 89 } 90 91 rc = pcie_cap_init(d, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT, 92 p->port, errp); 93 if (rc < 0) { 94 error_append_hint(errp, "Can't add Root Port capability, " 95 "error %d\n", rc); 96 goto err_int; 97 } 98 99 pcie_cap_arifwd_init(d); 100 pcie_cap_deverr_init(d); 101 pcie_cap_slot_init(d, s); 102 pcie_cap_root_init(d); 103 104 pcie_chassis_create(s->chassis); 105 rc = pcie_chassis_add_slot(s); 106 if (rc < 0) { 107 error_setg(errp, "Can't add chassis slot, error %d", rc); 108 goto err_pcie_cap; 109 } 110 111 rc = pcie_aer_init(d, PCI_ERR_VER, rpc->aer_offset, 112 PCI_ERR_SIZEOF, errp); 113 if (rc < 0) { 114 goto err; 115 } 116 pcie_aer_root_init(d); 117 rp_aer_vector_update(d); 118 119 if (rpc->acs_offset && !s->disable_acs) { 120 pcie_acs_init(d, rpc->acs_offset); 121 } 122 return; 123 124 err: 125 pcie_chassis_del_slot(s); 126 err_pcie_cap: 127 pcie_cap_exit(d); 128 err_int: 129 if (rpc->interrupts_uninit) { 130 rpc->interrupts_uninit(d); 131 } 132 err_bridge: 133 pci_bridge_exitfn(d); 134 } 135 136 static void rp_exit(PCIDevice *d) 137 { 138 PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); 139 PCIESlot *s = PCIE_SLOT(d); 140 141 pcie_aer_exit(d); 142 pcie_chassis_del_slot(s); 143 pcie_cap_exit(d); 144 if (rpc->interrupts_uninit) { 145 rpc->interrupts_uninit(d); 146 } 147 pci_bridge_exitfn(d); 148 } 149 150 static Property rp_props[] = { 151 DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present, 152 QEMU_PCIE_SLTCAP_PCP_BITNR, true), 153 DEFINE_PROP_BOOL("disable-acs", PCIESlot, disable_acs, false), 154 DEFINE_PROP_END_OF_LIST() 155 }; 156 157 static void rp_instance_post_init(Object *obj) 158 { 159 PCIESlot *s = PCIE_SLOT(obj); 160 161 if (!s->speed) { 162 s->speed = QEMU_PCI_EXP_LNK_2_5GT; 163 } 164 165 if (!s->width) { 166 s->width = QEMU_PCI_EXP_LNK_X1; 167 } 168 } 169 170 static void rp_class_init(ObjectClass *klass, void *data) 171 { 172 DeviceClass *dc = DEVICE_CLASS(klass); 173 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 174 175 k->is_bridge = true; 176 k->config_write = rp_write_config; 177 k->realize = rp_realize; 178 k->exit = rp_exit; 179 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 180 dc->reset = rp_reset; 181 device_class_set_props(dc, rp_props); 182 } 183 184 static const TypeInfo rp_info = { 185 .name = TYPE_PCIE_ROOT_PORT, 186 .parent = TYPE_PCIE_SLOT, 187 .instance_post_init = rp_instance_post_init, 188 .class_init = rp_class_init, 189 .abstract = true, 190 .class_size = sizeof(PCIERootPortClass), 191 .interfaces = (InterfaceInfo[]) { 192 { INTERFACE_PCIE_DEVICE }, 193 { } 194 }, 195 }; 196 197 static void rp_register_types(void) 198 { 199 type_register_static(&rp_info); 200 } 201 202 type_init(rp_register_types) 203