xref: /openbmc/qemu/hw/pci-bridge/pci_bridge_dev.c (revision 59a3a1c0)
1 /*
2  * Standard PCI Bridge Device
3  *
4  * Copyright (c) 2011 Red Hat Inc. Author: Michael S. Tsirkin <mst@redhat.com>
5  *
6  * http://www.pcisig.com/specifications/conventional/pci_to_pci_bridge_architecture/
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "qemu/osdep.h"
23 #include "qapi/error.h"
24 #include "qemu/module.h"
25 #include "hw/pci/pci_bridge.h"
26 #include "hw/pci/pci_ids.h"
27 #include "hw/pci/msi.h"
28 #include "hw/pci/shpc.h"
29 #include "hw/pci/slotid_cap.h"
30 #include "hw/qdev-properties.h"
31 #include "exec/memory.h"
32 #include "hw/pci/pci_bus.h"
33 #include "hw/hotplug.h"
34 
35 #define TYPE_PCI_BRIDGE_DEV      "pci-bridge"
36 #define TYPE_PCI_BRIDGE_SEAT_DEV "pci-bridge-seat"
37 #define PCI_BRIDGE_DEV(obj) \
38     OBJECT_CHECK(PCIBridgeDev, (obj), TYPE_PCI_BRIDGE_DEV)
39 
40 struct PCIBridgeDev {
41     /*< private >*/
42     PCIBridge parent_obj;
43     /*< public >*/
44 
45     MemoryRegion bar;
46     uint8_t chassis_nr;
47 #define PCI_BRIDGE_DEV_F_SHPC_REQ 0
48     uint32_t flags;
49 
50     OnOffAuto msi;
51 
52     /* additional resources to reserve */
53     PCIResReserve res_reserve;
54 };
55 typedef struct PCIBridgeDev PCIBridgeDev;
56 
57 static void pci_bridge_dev_realize(PCIDevice *dev, Error **errp)
58 {
59     PCIBridge *br = PCI_BRIDGE(dev);
60     PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev);
61     int err;
62     Error *local_err = NULL;
63 
64     pci_bridge_initfn(dev, TYPE_PCI_BUS);
65 
66     if (bridge_dev->flags & (1 << PCI_BRIDGE_DEV_F_SHPC_REQ)) {
67         dev->config[PCI_INTERRUPT_PIN] = 0x1;
68         memory_region_init(&bridge_dev->bar, OBJECT(dev), "shpc-bar",
69                            shpc_bar_size(dev));
70         err = shpc_init(dev, &br->sec_bus, &bridge_dev->bar, 0, errp);
71         if (err) {
72             goto shpc_error;
73         }
74     } else {
75         /* MSI is not applicable without SHPC */
76         bridge_dev->msi = ON_OFF_AUTO_OFF;
77     }
78 
79     err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0, errp);
80     if (err) {
81         goto slotid_error;
82     }
83 
84     if (bridge_dev->msi != ON_OFF_AUTO_OFF) {
85         /* it means SHPC exists, because MSI is needed by SHPC */
86 
87         err = msi_init(dev, 0, 1, true, true, &local_err);
88         /* Any error other than -ENOTSUP(board's MSI support is broken)
89          * is a programming error */
90         assert(!err || err == -ENOTSUP);
91         if (err && bridge_dev->msi == ON_OFF_AUTO_ON) {
92             /* Can't satisfy user's explicit msi=on request, fail */
93             error_append_hint(&local_err, "You have to use msi=auto (default) "
94                     "or msi=off with this machine type.\n");
95             error_propagate(errp, local_err);
96             goto msi_error;
97         }
98         assert(!local_err || bridge_dev->msi == ON_OFF_AUTO_AUTO);
99         /* With msi=auto, we fall back to MSI off silently */
100         error_free(local_err);
101     }
102 
103     err = pci_bridge_qemu_reserve_cap_init(dev, 0,
104                                          bridge_dev->res_reserve, errp);
105     if (err) {
106         goto cap_error;
107     }
108 
109     if (shpc_present(dev)) {
110         /* TODO: spec recommends using 64 bit prefetcheable BAR.
111          * Check whether that works well. */
112         pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
113                          PCI_BASE_ADDRESS_MEM_TYPE_64, &bridge_dev->bar);
114     }
115     return;
116 
117 cap_error:
118     msi_uninit(dev);
119 msi_error:
120     slotid_cap_cleanup(dev);
121 slotid_error:
122     if (shpc_present(dev)) {
123         shpc_cleanup(dev, &bridge_dev->bar);
124     }
125 shpc_error:
126     pci_bridge_exitfn(dev);
127 }
128 
129 static void pci_bridge_dev_exitfn(PCIDevice *dev)
130 {
131     PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev);
132 
133     pci_del_capability(dev, PCI_CAP_ID_VNDR, sizeof(PCIBridgeQemuCap));
134     if (msi_present(dev)) {
135         msi_uninit(dev);
136     }
137     slotid_cap_cleanup(dev);
138     if (shpc_present(dev)) {
139         shpc_cleanup(dev, &bridge_dev->bar);
140     }
141     pci_bridge_exitfn(dev);
142 }
143 
144 static void pci_bridge_dev_instance_finalize(Object *obj)
145 {
146     /* this function is idempotent and handles (PCIDevice.shpc == NULL) */
147     shpc_free(PCI_DEVICE(obj));
148 }
149 
150 static void pci_bridge_dev_write_config(PCIDevice *d,
151                                         uint32_t address, uint32_t val, int len)
152 {
153     pci_bridge_write_config(d, address, val, len);
154     if (msi_present(d)) {
155         msi_write_config(d, address, val, len);
156     }
157     if (shpc_present(d)) {
158         shpc_cap_write_config(d, address, val, len);
159     }
160 }
161 
162 static void qdev_pci_bridge_dev_reset(DeviceState *qdev)
163 {
164     PCIDevice *dev = PCI_DEVICE(qdev);
165 
166     pci_bridge_reset(qdev);
167     if (shpc_present(dev)) {
168         shpc_reset(dev);
169     }
170 }
171 
172 static Property pci_bridge_dev_properties[] = {
173                     /* Note: 0 is not a legal chassis number. */
174     DEFINE_PROP_UINT8(PCI_BRIDGE_DEV_PROP_CHASSIS_NR, PCIBridgeDev, chassis_nr,
175                       0),
176     DEFINE_PROP_ON_OFF_AUTO(PCI_BRIDGE_DEV_PROP_MSI, PCIBridgeDev, msi,
177                             ON_OFF_AUTO_AUTO),
178     DEFINE_PROP_BIT(PCI_BRIDGE_DEV_PROP_SHPC, PCIBridgeDev, flags,
179                     PCI_BRIDGE_DEV_F_SHPC_REQ, true),
180     DEFINE_PROP_UINT32("bus-reserve", PCIBridgeDev,
181                        res_reserve.bus, -1),
182     DEFINE_PROP_SIZE("io-reserve", PCIBridgeDev,
183                      res_reserve.io, -1),
184     DEFINE_PROP_SIZE("mem-reserve", PCIBridgeDev,
185                      res_reserve.mem_non_pref, -1),
186     DEFINE_PROP_SIZE("pref32-reserve", PCIBridgeDev,
187                      res_reserve.mem_pref_32, -1),
188     DEFINE_PROP_SIZE("pref64-reserve", PCIBridgeDev,
189                      res_reserve.mem_pref_64, -1),
190 
191     DEFINE_PROP_END_OF_LIST(),
192 };
193 
194 static bool pci_device_shpc_present(void *opaque, int version_id)
195 {
196     PCIDevice *dev = opaque;
197 
198     return shpc_present(dev);
199 }
200 
201 static const VMStateDescription pci_bridge_dev_vmstate = {
202     .name = "pci_bridge",
203     .priority = MIG_PRI_PCI_BUS,
204     .fields = (VMStateField[]) {
205         VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
206         SHPC_VMSTATE(shpc, PCIDevice, pci_device_shpc_present),
207         VMSTATE_END_OF_LIST()
208     }
209 };
210 
211 void pci_bridge_dev_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
212                             Error **errp)
213 {
214     PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);
215 
216     if (!shpc_present(pci_hotplug_dev)) {
217         error_setg(errp, "standard hotplug controller has been disabled for "
218                    "this %s", object_get_typename(OBJECT(hotplug_dev)));
219         return;
220     }
221     shpc_device_plug_cb(hotplug_dev, dev, errp);
222 }
223 
224 void pci_bridge_dev_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
225                               Error **errp)
226 {
227     PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);
228 
229     g_assert(shpc_present(pci_hotplug_dev));
230     shpc_device_unplug_cb(hotplug_dev, dev, errp);
231 }
232 
233 void pci_bridge_dev_unplug_request_cb(HotplugHandler *hotplug_dev,
234                                       DeviceState *dev, Error **errp)
235 {
236     PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);
237 
238     if (!shpc_present(pci_hotplug_dev)) {
239         error_setg(errp, "standard hotplug controller has been disabled for "
240                    "this %s", object_get_typename(OBJECT(hotplug_dev)));
241         return;
242     }
243     shpc_device_unplug_request_cb(hotplug_dev, dev, errp);
244 }
245 
246 static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
247 {
248     DeviceClass *dc = DEVICE_CLASS(klass);
249     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
250     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
251 
252     k->realize = pci_bridge_dev_realize;
253     k->exit = pci_bridge_dev_exitfn;
254     k->config_write = pci_bridge_dev_write_config;
255     k->vendor_id = PCI_VENDOR_ID_REDHAT;
256     k->device_id = PCI_DEVICE_ID_REDHAT_BRIDGE;
257     k->class_id = PCI_CLASS_BRIDGE_PCI;
258     k->is_bridge = true;
259     dc->desc = "Standard PCI Bridge";
260     dc->reset = qdev_pci_bridge_dev_reset;
261     dc->props = pci_bridge_dev_properties;
262     dc->vmsd = &pci_bridge_dev_vmstate;
263     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
264     hc->plug = pci_bridge_dev_plug_cb;
265     hc->unplug = pci_bridge_dev_unplug_cb;
266     hc->unplug_request = pci_bridge_dev_unplug_request_cb;
267 }
268 
269 static const TypeInfo pci_bridge_dev_info = {
270     .name              = TYPE_PCI_BRIDGE_DEV,
271     .parent            = TYPE_PCI_BRIDGE,
272     .instance_size     = sizeof(PCIBridgeDev),
273     .class_init        = pci_bridge_dev_class_init,
274     .instance_finalize = pci_bridge_dev_instance_finalize,
275     .interfaces = (InterfaceInfo[]) {
276         { TYPE_HOTPLUG_HANDLER },
277         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
278         { }
279     }
280 };
281 
282 /*
283  * Multiseat bridge.  Same as the standard pci bridge, only with a
284  * different pci id, so we can match it easily in the guest for
285  * automagic multiseat configuration.  See docs/multiseat.txt for more.
286  */
287 static void pci_bridge_dev_seat_class_init(ObjectClass *klass, void *data)
288 {
289     DeviceClass *dc = DEVICE_CLASS(klass);
290     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
291 
292     k->device_id = PCI_DEVICE_ID_REDHAT_BRIDGE_SEAT;
293     dc->desc = "Standard PCI Bridge (multiseat)";
294 }
295 
296 static const TypeInfo pci_bridge_dev_seat_info = {
297     .name              = TYPE_PCI_BRIDGE_SEAT_DEV,
298     .parent            = TYPE_PCI_BRIDGE_DEV,
299     .instance_size     = sizeof(PCIBridgeDev),
300     .class_init        = pci_bridge_dev_seat_class_init,
301 };
302 
303 static void pci_bridge_dev_register(void)
304 {
305     type_register_static(&pci_bridge_dev_info);
306     type_register_static(&pci_bridge_dev_seat_info);
307 }
308 
309 type_init(pci_bridge_dev_register);
310