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 20 static void rp_aer_vector_update(PCIDevice *d) 21 { 22 PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); 23 24 if (rpc->aer_vector) { 25 pcie_aer_root_set_vector(d, rpc->aer_vector(d)); 26 } 27 } 28 29 static void rp_write_config(PCIDevice *d, uint32_t address, 30 uint32_t val, int len) 31 { 32 uint32_t root_cmd = 33 pci_get_long(d->config + d->exp.aer_cap + PCI_ERR_ROOT_COMMAND); 34 35 pci_bridge_write_config(d, address, val, len); 36 rp_aer_vector_update(d); 37 pcie_cap_slot_write_config(d, address, val, len); 38 pcie_aer_write_config(d, address, val, len); 39 pcie_aer_root_write_config(d, address, val, len, root_cmd); 40 } 41 42 static void rp_reset(DeviceState *qdev) 43 { 44 PCIDevice *d = PCI_DEVICE(qdev); 45 46 rp_aer_vector_update(d); 47 pcie_cap_root_reset(d); 48 pcie_cap_deverr_reset(d); 49 pcie_cap_slot_reset(d); 50 pcie_cap_arifwd_reset(d); 51 pcie_acs_reset(d); 52 pcie_aer_root_reset(d); 53 pci_bridge_reset(qdev); 54 pci_bridge_disable_base_limit(d); 55 } 56 57 static void rp_realize(PCIDevice *d, Error **errp) 58 { 59 PCIEPort *p = PCIE_PORT(d); 60 PCIESlot *s = PCIE_SLOT(d); 61 PCIDeviceClass *dc = PCI_DEVICE_GET_CLASS(d); 62 PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); 63 int rc; 64 65 pci_config_set_interrupt_pin(d->config, 1); 66 pci_bridge_initfn(d, TYPE_PCIE_BUS); 67 pcie_port_init_reg(d); 68 69 rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id, 70 rpc->ssid, errp); 71 if (rc < 0) { 72 error_append_hint(errp, "Can't init SSV ID, error %d\n", rc); 73 goto err_bridge; 74 } 75 76 if (rpc->interrupts_init) { 77 rc = rpc->interrupts_init(d, errp); 78 if (rc < 0) { 79 goto err_bridge; 80 } 81 } 82 83 rc = pcie_cap_init(d, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT, 84 p->port, errp); 85 if (rc < 0) { 86 error_append_hint(errp, "Can't add Root Port capability, " 87 "error %d\n", rc); 88 goto err_int; 89 } 90 91 pcie_cap_arifwd_init(d); 92 pcie_cap_deverr_init(d); 93 pcie_cap_slot_init(d, s->slot); 94 pcie_cap_root_init(d); 95 96 pcie_chassis_create(s->chassis); 97 rc = pcie_chassis_add_slot(s); 98 if (rc < 0) { 99 error_setg(errp, "Can't add chassis slot, error %d", rc); 100 goto err_pcie_cap; 101 } 102 103 rc = pcie_aer_init(d, PCI_ERR_VER, rpc->aer_offset, 104 PCI_ERR_SIZEOF, errp); 105 if (rc < 0) { 106 goto err; 107 } 108 pcie_aer_root_init(d); 109 rp_aer_vector_update(d); 110 111 if (rpc->acs_offset) { 112 pcie_acs_init(d, rpc->acs_offset); 113 } 114 return; 115 116 err: 117 pcie_chassis_del_slot(s); 118 err_pcie_cap: 119 pcie_cap_exit(d); 120 err_int: 121 if (rpc->interrupts_uninit) { 122 rpc->interrupts_uninit(d); 123 } 124 err_bridge: 125 pci_bridge_exitfn(d); 126 } 127 128 static void rp_exit(PCIDevice *d) 129 { 130 PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); 131 PCIESlot *s = PCIE_SLOT(d); 132 133 pcie_aer_exit(d); 134 pcie_chassis_del_slot(s); 135 pcie_cap_exit(d); 136 if (rpc->interrupts_uninit) { 137 rpc->interrupts_uninit(d); 138 } 139 pci_bridge_exitfn(d); 140 } 141 142 static Property rp_props[] = { 143 DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present, 144 QEMU_PCIE_SLTCAP_PCP_BITNR, true), 145 DEFINE_PROP_END_OF_LIST() 146 }; 147 148 static void rp_instance_post_init(Object *obj) 149 { 150 PCIESlot *s = PCIE_SLOT(obj); 151 152 if (!s->speed) { 153 s->speed = QEMU_PCI_EXP_LNK_2_5GT; 154 } 155 156 if (!s->width) { 157 s->width = QEMU_PCI_EXP_LNK_X1; 158 } 159 } 160 161 static void rp_class_init(ObjectClass *klass, void *data) 162 { 163 DeviceClass *dc = DEVICE_CLASS(klass); 164 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 165 166 k->is_bridge = true; 167 k->config_write = rp_write_config; 168 k->realize = rp_realize; 169 k->exit = rp_exit; 170 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 171 dc->reset = rp_reset; 172 dc->props = rp_props; 173 } 174 175 static const TypeInfo rp_info = { 176 .name = TYPE_PCIE_ROOT_PORT, 177 .parent = TYPE_PCIE_SLOT, 178 .instance_post_init = rp_instance_post_init, 179 .class_init = rp_class_init, 180 .abstract = true, 181 .class_size = sizeof(PCIERootPortClass), 182 .interfaces = (InterfaceInfo[]) { 183 { INTERFACE_PCIE_DEVICE }, 184 { } 185 }, 186 }; 187 188 static void rp_register_types(void) 189 { 190 type_register_static(&rp_info); 191 } 192 193 type_init(rp_register_types) 194