ppc/pnv: remove pecc->rp_model
[qemu.git] / hw / pci-host / pnv_phb.c
blobcc15a949c9130e4266ecf89730145f6713ec5317
1 /*
2 * QEMU PowerPC PowerNV Proxy PHB model
4 * Copyright (c) 2022, IBM Corporation.
6 * This code is licensed under the GPL version 2 or later. See the
7 * COPYING file in the top-level directory.
8 */
10 #include "qemu/osdep.h"
11 #include "qemu/log.h"
12 #include "qapi/visitor.h"
13 #include "qapi/error.h"
14 #include "hw/pci-host/pnv_phb.h"
15 #include "hw/pci-host/pnv_phb3.h"
16 #include "hw/pci-host/pnv_phb4.h"
17 #include "hw/ppc/pnv.h"
18 #include "hw/qdev-properties.h"
19 #include "qom/object.h"
22 static void pnv_phb_realize(DeviceState *dev, Error **errp)
24 PnvPHB *phb = PNV_PHB(dev);
25 PCIHostState *pci = PCI_HOST_BRIDGE(dev);
26 g_autofree char *phb_typename = NULL;
28 if (!phb->version) {
29 error_setg(errp, "version not specified");
30 return;
33 switch (phb->version) {
34 case 3:
35 phb_typename = g_strdup(TYPE_PNV_PHB3);
36 break;
37 case 4:
38 phb_typename = g_strdup(TYPE_PNV_PHB4);
39 break;
40 case 5:
41 phb_typename = g_strdup(TYPE_PNV_PHB5);
42 break;
43 default:
44 g_assert_not_reached();
47 phb->backend = object_new(phb_typename);
48 object_property_add_child(OBJECT(dev), "phb-backend", phb->backend);
50 /* Passthrough child device properties to the proxy device */
51 object_property_set_uint(phb->backend, "index", phb->phb_id, errp);
52 object_property_set_uint(phb->backend, "chip-id", phb->chip_id, errp);
53 object_property_set_link(phb->backend, "phb-base", OBJECT(phb), errp);
55 if (phb->version == 3) {
56 object_property_set_link(phb->backend, "chip",
57 OBJECT(phb->chip), errp);
58 } else {
59 object_property_set_link(phb->backend, "pec", OBJECT(phb->pec), errp);
62 if (!qdev_realize(DEVICE(phb->backend), NULL, errp)) {
63 return;
66 if (phb->version == 3) {
67 pnv_phb3_bus_init(dev, PNV_PHB3(phb->backend));
68 } else {
69 pnv_phb4_bus_init(dev, PNV_PHB4(phb->backend));
72 pnv_phb_attach_root_port(pci, phb->phb_id, phb->chip_id);
75 static const char *pnv_phb_root_bus_path(PCIHostState *host_bridge,
76 PCIBus *rootbus)
78 PnvPHB *phb = PNV_PHB(host_bridge);
80 snprintf(phb->bus_path, sizeof(phb->bus_path), "00%02x:%02x",
81 phb->chip_id, phb->phb_id);
82 return phb->bus_path;
85 static Property pnv_phb_properties[] = {
86 DEFINE_PROP_UINT32("index", PnvPHB, phb_id, 0),
87 DEFINE_PROP_UINT32("chip-id", PnvPHB, chip_id, 0),
88 DEFINE_PROP_UINT32("version", PnvPHB, version, 0),
90 DEFINE_PROP_LINK("chip", PnvPHB, chip, TYPE_PNV_CHIP, PnvChip *),
92 DEFINE_PROP_LINK("pec", PnvPHB, pec, TYPE_PNV_PHB4_PEC,
93 PnvPhb4PecState *),
95 DEFINE_PROP_END_OF_LIST(),
98 static void pnv_phb_class_init(ObjectClass *klass, void *data)
100 PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
101 DeviceClass *dc = DEVICE_CLASS(klass);
103 hc->root_bus_path = pnv_phb_root_bus_path;
104 dc->realize = pnv_phb_realize;
105 device_class_set_props(dc, pnv_phb_properties);
106 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
107 dc->user_creatable = false;
110 static void pnv_phb_root_port_reset(DeviceState *dev)
112 PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
113 PnvPHBRootPort *phb_rp = PNV_PHB_ROOT_PORT(dev);
114 PCIDevice *d = PCI_DEVICE(dev);
115 uint8_t *conf = d->config;
117 rpc->parent_reset(dev);
119 if (phb_rp->version == 3) {
120 return;
123 /* PHB4 and later requires these extra reset steps */
124 pci_byte_test_and_set_mask(conf + PCI_IO_BASE,
125 PCI_IO_RANGE_MASK & 0xff);
126 pci_byte_test_and_clear_mask(conf + PCI_IO_LIMIT,
127 PCI_IO_RANGE_MASK & 0xff);
128 pci_set_word(conf + PCI_MEMORY_BASE, 0);
129 pci_set_word(conf + PCI_MEMORY_LIMIT, 0xfff0);
130 pci_set_word(conf + PCI_PREF_MEMORY_BASE, 0x1);
131 pci_set_word(conf + PCI_PREF_MEMORY_LIMIT, 0xfff1);
132 pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0x1); /* Hack */
133 pci_set_long(conf + PCI_PREF_LIMIT_UPPER32, 0xffffffff);
134 pci_config_set_interrupt_pin(conf, 0);
137 static void pnv_phb_root_port_realize(DeviceState *dev, Error **errp)
139 PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
140 PnvPHBRootPort *phb_rp = PNV_PHB_ROOT_PORT(dev);
141 PCIDevice *pci = PCI_DEVICE(dev);
142 uint16_t device_id = 0;
143 Error *local_err = NULL;
145 rpc->parent_realize(dev, &local_err);
146 if (local_err) {
147 error_propagate(errp, local_err);
148 return;
151 switch (phb_rp->version) {
152 case 3:
153 device_id = PNV_PHB3_DEVICE_ID;
154 break;
155 case 4:
156 device_id = PNV_PHB4_DEVICE_ID;
157 break;
158 case 5:
159 device_id = PNV_PHB5_DEVICE_ID;
160 break;
161 default:
162 g_assert_not_reached();
165 pci_config_set_device_id(pci->config, device_id);
166 pci_config_set_interrupt_pin(pci->config, 0);
169 static Property pnv_phb_root_port_properties[] = {
170 DEFINE_PROP_UINT32("version", PnvPHBRootPort, version, 0),
172 DEFINE_PROP_END_OF_LIST(),
175 static void pnv_phb_root_port_class_init(ObjectClass *klass, void *data)
177 DeviceClass *dc = DEVICE_CLASS(klass);
178 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
179 PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
181 dc->desc = "IBM PHB PCIE Root Port";
183 device_class_set_props(dc, pnv_phb_root_port_properties);
184 device_class_set_parent_realize(dc, pnv_phb_root_port_realize,
185 &rpc->parent_realize);
186 device_class_set_parent_reset(dc, pnv_phb_root_port_reset,
187 &rpc->parent_reset);
188 dc->reset = &pnv_phb_root_port_reset;
189 dc->user_creatable = false;
191 k->vendor_id = PCI_VENDOR_ID_IBM;
192 /* device_id will be written during realize() */
193 k->device_id = 0;
194 k->revision = 0;
196 rpc->exp_offset = 0x48;
197 rpc->aer_offset = 0x100;
200 static const TypeInfo pnv_phb_type_info = {
201 .name = TYPE_PNV_PHB,
202 .parent = TYPE_PCIE_HOST_BRIDGE,
203 .instance_size = sizeof(PnvPHB),
204 .class_init = pnv_phb_class_init,
207 static const TypeInfo pnv_phb_root_port_info = {
208 .name = TYPE_PNV_PHB_ROOT_PORT,
209 .parent = TYPE_PCIE_ROOT_PORT,
210 .instance_size = sizeof(PnvPHBRootPort),
211 .class_init = pnv_phb_root_port_class_init,
214 static void pnv_phb_register_types(void)
216 type_register_static(&pnv_phb_type_info);
217 type_register_static(&pnv_phb_root_port_info);
220 type_init(pnv_phb_register_types)