xref: /openbmc/qemu/hw/pci/pci.c (revision e688df6b)
1315a1350SMichael S. Tsirkin /*
2315a1350SMichael S. Tsirkin  * QEMU PCI bus manager
3315a1350SMichael S. Tsirkin  *
4315a1350SMichael S. Tsirkin  * Copyright (c) 2004 Fabrice Bellard
5315a1350SMichael S. Tsirkin  *
6315a1350SMichael S. Tsirkin  * Permission is hereby granted, free of charge, to any person obtaining a copy
7315a1350SMichael S. Tsirkin  * of this software and associated documentation files (the "Software"), to deal
8315a1350SMichael S. Tsirkin  * in the Software without restriction, including without limitation the rights
9315a1350SMichael S. Tsirkin  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10315a1350SMichael S. Tsirkin  * copies of the Software, and to permit persons to whom the Software is
11315a1350SMichael S. Tsirkin  * furnished to do so, subject to the following conditions:
12315a1350SMichael S. Tsirkin  *
13315a1350SMichael S. Tsirkin  * The above copyright notice and this permission notice shall be included in
14315a1350SMichael S. Tsirkin  * all copies or substantial portions of the Software.
15315a1350SMichael S. Tsirkin  *
16315a1350SMichael S. Tsirkin  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17315a1350SMichael S. Tsirkin  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18315a1350SMichael S. Tsirkin  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19315a1350SMichael S. Tsirkin  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20315a1350SMichael S. Tsirkin  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21315a1350SMichael S. Tsirkin  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22315a1350SMichael S. Tsirkin  * THE SOFTWARE.
23315a1350SMichael S. Tsirkin  */
24*e688df6bSMarkus Armbruster 
2597d5408fSPeter Maydell #include "qemu/osdep.h"
26c759b24fSMichael S. Tsirkin #include "hw/hw.h"
27c759b24fSMichael S. Tsirkin #include "hw/pci/pci.h"
28c759b24fSMichael S. Tsirkin #include "hw/pci/pci_bridge.h"
2906aac7bdSMichael S. Tsirkin #include "hw/pci/pci_bus.h"
30568f0690SDavid Gibson #include "hw/pci/pci_host.h"
3183c9089eSPaolo Bonzini #include "monitor/monitor.h"
321422e32dSPaolo Bonzini #include "net/net.h"
339c17d615SPaolo Bonzini #include "sysemu/sysemu.h"
34c759b24fSMichael S. Tsirkin #include "hw/loader.h"
35d49b6836SMarkus Armbruster #include "qemu/error-report.h"
361de7afc9SPaolo Bonzini #include "qemu/range.h"
37315a1350SMichael S. Tsirkin #include "qmp-commands.h"
387828d750SDon Koch #include "trace.h"
39c759b24fSMichael S. Tsirkin #include "hw/pci/msi.h"
40c759b24fSMichael S. Tsirkin #include "hw/pci/msix.h"
41022c62cbSPaolo Bonzini #include "exec/address-spaces.h"
425e954943SIgor Mammedov #include "hw/hotplug.h"
43e4024630SLaurent Vivier #include "hw/boards.h"
44*e688df6bSMarkus Armbruster #include "qapi/error.h"
45f348b6d1SVeronia Bahaa #include "qemu/cutils.h"
46315a1350SMichael S. Tsirkin 
47315a1350SMichael S. Tsirkin //#define DEBUG_PCI
48315a1350SMichael S. Tsirkin #ifdef DEBUG_PCI
49315a1350SMichael S. Tsirkin # define PCI_DPRINTF(format, ...)       printf(format, ## __VA_ARGS__)
50315a1350SMichael S. Tsirkin #else
51315a1350SMichael S. Tsirkin # define PCI_DPRINTF(format, ...)       do { } while (0)
52315a1350SMichael S. Tsirkin #endif
53315a1350SMichael S. Tsirkin 
5488c725c7SCornelia Huck bool pci_available = true;
5588c725c7SCornelia Huck 
56315a1350SMichael S. Tsirkin static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
57315a1350SMichael S. Tsirkin static char *pcibus_get_dev_path(DeviceState *dev);
58315a1350SMichael S. Tsirkin static char *pcibus_get_fw_dev_path(DeviceState *dev);
59dcc20931SPaolo Bonzini static void pcibus_reset(BusState *qbus);
60315a1350SMichael S. Tsirkin 
61315a1350SMichael S. Tsirkin static Property pci_props[] = {
62315a1350SMichael S. Tsirkin     DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
63315a1350SMichael S. Tsirkin     DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
64315a1350SMichael S. Tsirkin     DEFINE_PROP_UINT32("rombar",  PCIDevice, rom_bar, 1),
65315a1350SMichael S. Tsirkin     DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
66315a1350SMichael S. Tsirkin                     QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
67315a1350SMichael S. Tsirkin     DEFINE_PROP_BIT("command_serr_enable", PCIDevice, cap_present,
68315a1350SMichael S. Tsirkin                     QEMU_PCI_CAP_SERR_BITNR, true),
696b449540SMichael S. Tsirkin     DEFINE_PROP_BIT("x-pcie-lnksta-dllla", PCIDevice, cap_present,
706b449540SMichael S. Tsirkin                     QEMU_PCIE_LNKSTA_DLLLA_BITNR, true),
71f03d8ea3SMarcel Apfelbaum     DEFINE_PROP_BIT("x-pcie-extcap-init", PCIDevice, cap_present,
72f03d8ea3SMarcel Apfelbaum                     QEMU_PCIE_EXTCAP_INIT_BITNR, true),
73315a1350SMichael S. Tsirkin     DEFINE_PROP_END_OF_LIST()
74315a1350SMichael S. Tsirkin };
75315a1350SMichael S. Tsirkin 
76d2f69df7SBandan Das static const VMStateDescription vmstate_pcibus = {
77d2f69df7SBandan Das     .name = "PCIBUS",
78d2f69df7SBandan Das     .version_id = 1,
79d2f69df7SBandan Das     .minimum_version_id = 1,
80d2f69df7SBandan Das     .fields = (VMStateField[]) {
81d2164ad3SHalil Pasic         VMSTATE_INT32_EQUAL(nirq, PCIBus, NULL),
82d2f69df7SBandan Das         VMSTATE_VARRAY_INT32(irq_count, PCIBus,
83d2f69df7SBandan Das                              nirq, 0, vmstate_info_int32,
84d2f69df7SBandan Das                              int32_t),
85d2f69df7SBandan Das         VMSTATE_END_OF_LIST()
86d2f69df7SBandan Das     }
87d2f69df7SBandan Das };
88d2f69df7SBandan Das 
89b86eacb8SMarcel Apfelbaum static void pci_init_bus_master(PCIDevice *pci_dev)
90b86eacb8SMarcel Apfelbaum {
91b86eacb8SMarcel Apfelbaum     AddressSpace *dma_as = pci_device_iommu_address_space(pci_dev);
92b86eacb8SMarcel Apfelbaum 
93b86eacb8SMarcel Apfelbaum     memory_region_init_alias(&pci_dev->bus_master_enable_region,
94b86eacb8SMarcel Apfelbaum                              OBJECT(pci_dev), "bus master",
95b86eacb8SMarcel Apfelbaum                              dma_as->root, 0, memory_region_size(dma_as->root));
96b86eacb8SMarcel Apfelbaum     memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
973716d590SJason Wang     memory_region_add_subregion(&pci_dev->bus_master_container_region, 0,
983716d590SJason Wang                                 &pci_dev->bus_master_enable_region);
99b86eacb8SMarcel Apfelbaum }
100b86eacb8SMarcel Apfelbaum 
101b86eacb8SMarcel Apfelbaum static void pcibus_machine_done(Notifier *notifier, void *data)
102b86eacb8SMarcel Apfelbaum {
103b86eacb8SMarcel Apfelbaum     PCIBus *bus = container_of(notifier, PCIBus, machine_done);
104b86eacb8SMarcel Apfelbaum     int i;
105b86eacb8SMarcel Apfelbaum 
106b86eacb8SMarcel Apfelbaum     for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
107b86eacb8SMarcel Apfelbaum         if (bus->devices[i]) {
108b86eacb8SMarcel Apfelbaum             pci_init_bus_master(bus->devices[i]);
109b86eacb8SMarcel Apfelbaum         }
110b86eacb8SMarcel Apfelbaum     }
111b86eacb8SMarcel Apfelbaum }
112b86eacb8SMarcel Apfelbaum 
113d2f69df7SBandan Das static void pci_bus_realize(BusState *qbus, Error **errp)
114d2f69df7SBandan Das {
115d2f69df7SBandan Das     PCIBus *bus = PCI_BUS(qbus);
116d2f69df7SBandan Das 
117b86eacb8SMarcel Apfelbaum     bus->machine_done.notify = pcibus_machine_done;
118b86eacb8SMarcel Apfelbaum     qemu_add_machine_init_done_notifier(&bus->machine_done);
119b86eacb8SMarcel Apfelbaum 
120d2f69df7SBandan Das     vmstate_register(NULL, -1, &vmstate_pcibus, bus);
121d2f69df7SBandan Das }
122d2f69df7SBandan Das 
123d2f69df7SBandan Das static void pci_bus_unrealize(BusState *qbus, Error **errp)
124d2f69df7SBandan Das {
125d2f69df7SBandan Das     PCIBus *bus = PCI_BUS(qbus);
126d2f69df7SBandan Das 
127b86eacb8SMarcel Apfelbaum     qemu_remove_machine_init_done_notifier(&bus->machine_done);
128b86eacb8SMarcel Apfelbaum 
129d2f69df7SBandan Das     vmstate_unregister(NULL, &vmstate_pcibus, bus);
130d2f69df7SBandan Das }
131d2f69df7SBandan Das 
132ce6a28eeSMarcel Apfelbaum static bool pcibus_is_root(PCIBus *bus)
133ce6a28eeSMarcel Apfelbaum {
134ce6a28eeSMarcel Apfelbaum     return !bus->parent_dev;
135ce6a28eeSMarcel Apfelbaum }
136ce6a28eeSMarcel Apfelbaum 
137602141d9SMarcel Apfelbaum static int pcibus_num(PCIBus *bus)
138602141d9SMarcel Apfelbaum {
139602141d9SMarcel Apfelbaum     if (pcibus_is_root(bus)) {
140602141d9SMarcel Apfelbaum         return 0; /* pci host bridge */
141602141d9SMarcel Apfelbaum     }
142602141d9SMarcel Apfelbaum     return bus->parent_dev->config[PCI_SECONDARY_BUS];
143602141d9SMarcel Apfelbaum }
144602141d9SMarcel Apfelbaum 
1456a3042b2SMarcel Apfelbaum static uint16_t pcibus_numa_node(PCIBus *bus)
1466a3042b2SMarcel Apfelbaum {
1476a3042b2SMarcel Apfelbaum     return NUMA_NODE_UNASSIGNED;
1486a3042b2SMarcel Apfelbaum }
1496a3042b2SMarcel Apfelbaum 
150315a1350SMichael S. Tsirkin static void pci_bus_class_init(ObjectClass *klass, void *data)
151315a1350SMichael S. Tsirkin {
152315a1350SMichael S. Tsirkin     BusClass *k = BUS_CLASS(klass);
153ce6a28eeSMarcel Apfelbaum     PCIBusClass *pbc = PCI_BUS_CLASS(klass);
154315a1350SMichael S. Tsirkin 
155315a1350SMichael S. Tsirkin     k->print_dev = pcibus_dev_print;
156315a1350SMichael S. Tsirkin     k->get_dev_path = pcibus_get_dev_path;
157315a1350SMichael S. Tsirkin     k->get_fw_dev_path = pcibus_get_fw_dev_path;
158d2f69df7SBandan Das     k->realize = pci_bus_realize;
159d2f69df7SBandan Das     k->unrealize = pci_bus_unrealize;
160315a1350SMichael S. Tsirkin     k->reset = pcibus_reset;
161ce6a28eeSMarcel Apfelbaum 
162ce6a28eeSMarcel Apfelbaum     pbc->is_root = pcibus_is_root;
163602141d9SMarcel Apfelbaum     pbc->bus_num = pcibus_num;
1646a3042b2SMarcel Apfelbaum     pbc->numa_node = pcibus_numa_node;
165315a1350SMichael S. Tsirkin }
166315a1350SMichael S. Tsirkin 
167315a1350SMichael S. Tsirkin static const TypeInfo pci_bus_info = {
168315a1350SMichael S. Tsirkin     .name = TYPE_PCI_BUS,
169315a1350SMichael S. Tsirkin     .parent = TYPE_BUS,
170315a1350SMichael S. Tsirkin     .instance_size = sizeof(PCIBus),
171ce6a28eeSMarcel Apfelbaum     .class_size = sizeof(PCIBusClass),
172315a1350SMichael S. Tsirkin     .class_init = pci_bus_class_init,
173315a1350SMichael S. Tsirkin };
174315a1350SMichael S. Tsirkin 
175619f02aeSEduardo Habkost static const TypeInfo pcie_interface_info = {
176619f02aeSEduardo Habkost     .name          = INTERFACE_PCIE_DEVICE,
177619f02aeSEduardo Habkost     .parent        = TYPE_INTERFACE,
178619f02aeSEduardo Habkost };
179619f02aeSEduardo Habkost 
180619f02aeSEduardo Habkost static const TypeInfo conventional_pci_interface_info = {
181619f02aeSEduardo Habkost     .name          = INTERFACE_CONVENTIONAL_PCI_DEVICE,
182619f02aeSEduardo Habkost     .parent        = TYPE_INTERFACE,
183619f02aeSEduardo Habkost };
184619f02aeSEduardo Habkost 
1853a861c46SAlex Williamson static const TypeInfo pcie_bus_info = {
1863a861c46SAlex Williamson     .name = TYPE_PCIE_BUS,
1873a861c46SAlex Williamson     .parent = TYPE_PCI_BUS,
1883a861c46SAlex Williamson };
1893a861c46SAlex Williamson 
190315a1350SMichael S. Tsirkin static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
191315a1350SMichael S. Tsirkin static void pci_update_mappings(PCIDevice *d);
192d98f08f5SMarcel Apfelbaum static void pci_irq_handler(void *opaque, int irq_num, int level);
193133e9b22SMarkus Armbruster static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, Error **);
194315a1350SMichael S. Tsirkin static void pci_del_option_rom(PCIDevice *pdev);
195315a1350SMichael S. Tsirkin 
196315a1350SMichael S. Tsirkin static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
197315a1350SMichael S. Tsirkin static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
198315a1350SMichael S. Tsirkin 
1997588e2b0SDavid Gibson static QLIST_HEAD(, PCIHostState) pci_host_bridges;
200315a1350SMichael S. Tsirkin 
201cf8c704dSMichael Roth int pci_bar(PCIDevice *d, int reg)
202315a1350SMichael S. Tsirkin {
203315a1350SMichael S. Tsirkin     uint8_t type;
204315a1350SMichael S. Tsirkin 
205315a1350SMichael S. Tsirkin     if (reg != PCI_ROM_SLOT)
206315a1350SMichael S. Tsirkin         return PCI_BASE_ADDRESS_0 + reg * 4;
207315a1350SMichael S. Tsirkin 
208315a1350SMichael S. Tsirkin     type = d->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
209315a1350SMichael S. Tsirkin     return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS;
210315a1350SMichael S. Tsirkin }
211315a1350SMichael S. Tsirkin 
212315a1350SMichael S. Tsirkin static inline int pci_irq_state(PCIDevice *d, int irq_num)
213315a1350SMichael S. Tsirkin {
214315a1350SMichael S. Tsirkin 	return (d->irq_state >> irq_num) & 0x1;
215315a1350SMichael S. Tsirkin }
216315a1350SMichael S. Tsirkin 
217315a1350SMichael S. Tsirkin static inline void pci_set_irq_state(PCIDevice *d, int irq_num, int level)
218315a1350SMichael S. Tsirkin {
219315a1350SMichael S. Tsirkin 	d->irq_state &= ~(0x1 << irq_num);
220315a1350SMichael S. Tsirkin 	d->irq_state |= level << irq_num;
221315a1350SMichael S. Tsirkin }
222315a1350SMichael S. Tsirkin 
223315a1350SMichael S. Tsirkin static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
224315a1350SMichael S. Tsirkin {
225315a1350SMichael S. Tsirkin     PCIBus *bus;
226315a1350SMichael S. Tsirkin     for (;;) {
227fd56e061SDavid Gibson         bus = pci_get_bus(pci_dev);
228315a1350SMichael S. Tsirkin         irq_num = bus->map_irq(pci_dev, irq_num);
229315a1350SMichael S. Tsirkin         if (bus->set_irq)
230315a1350SMichael S. Tsirkin             break;
231315a1350SMichael S. Tsirkin         pci_dev = bus->parent_dev;
232315a1350SMichael S. Tsirkin     }
233315a1350SMichael S. Tsirkin     bus->irq_count[irq_num] += change;
234315a1350SMichael S. Tsirkin     bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
235315a1350SMichael S. Tsirkin }
236315a1350SMichael S. Tsirkin 
237315a1350SMichael S. Tsirkin int pci_bus_get_irq_level(PCIBus *bus, int irq_num)
238315a1350SMichael S. Tsirkin {
239315a1350SMichael S. Tsirkin     assert(irq_num >= 0);
240315a1350SMichael S. Tsirkin     assert(irq_num < bus->nirq);
241315a1350SMichael S. Tsirkin     return !!bus->irq_count[irq_num];
242315a1350SMichael S. Tsirkin }
243315a1350SMichael S. Tsirkin 
244315a1350SMichael S. Tsirkin /* Update interrupt status bit in config space on interrupt
245315a1350SMichael S. Tsirkin  * state change. */
246315a1350SMichael S. Tsirkin static void pci_update_irq_status(PCIDevice *dev)
247315a1350SMichael S. Tsirkin {
248315a1350SMichael S. Tsirkin     if (dev->irq_state) {
249315a1350SMichael S. Tsirkin         dev->config[PCI_STATUS] |= PCI_STATUS_INTERRUPT;
250315a1350SMichael S. Tsirkin     } else {
251315a1350SMichael S. Tsirkin         dev->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
252315a1350SMichael S. Tsirkin     }
253315a1350SMichael S. Tsirkin }
254315a1350SMichael S. Tsirkin 
255315a1350SMichael S. Tsirkin void pci_device_deassert_intx(PCIDevice *dev)
256315a1350SMichael S. Tsirkin {
257315a1350SMichael S. Tsirkin     int i;
258315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
259d98f08f5SMarcel Apfelbaum         pci_irq_handler(dev, i, 0);
260315a1350SMichael S. Tsirkin     }
261315a1350SMichael S. Tsirkin }
262315a1350SMichael S. Tsirkin 
263dcc20931SPaolo Bonzini static void pci_do_device_reset(PCIDevice *dev)
264315a1350SMichael S. Tsirkin {
265315a1350SMichael S. Tsirkin     int r;
266315a1350SMichael S. Tsirkin 
267315a1350SMichael S. Tsirkin     pci_device_deassert_intx(dev);
26858b59014SCole Robinson     assert(dev->irq_state == 0);
26958b59014SCole Robinson 
270315a1350SMichael S. Tsirkin     /* Clear all writable bits */
271315a1350SMichael S. Tsirkin     pci_word_test_and_clear_mask(dev->config + PCI_COMMAND,
272315a1350SMichael S. Tsirkin                                  pci_get_word(dev->wmask + PCI_COMMAND) |
273315a1350SMichael S. Tsirkin                                  pci_get_word(dev->w1cmask + PCI_COMMAND));
274315a1350SMichael S. Tsirkin     pci_word_test_and_clear_mask(dev->config + PCI_STATUS,
275315a1350SMichael S. Tsirkin                                  pci_get_word(dev->wmask + PCI_STATUS) |
276315a1350SMichael S. Tsirkin                                  pci_get_word(dev->w1cmask + PCI_STATUS));
277315a1350SMichael S. Tsirkin     dev->config[PCI_CACHE_LINE_SIZE] = 0x0;
278315a1350SMichael S. Tsirkin     dev->config[PCI_INTERRUPT_LINE] = 0x0;
279315a1350SMichael S. Tsirkin     for (r = 0; r < PCI_NUM_REGIONS; ++r) {
280315a1350SMichael S. Tsirkin         PCIIORegion *region = &dev->io_regions[r];
281315a1350SMichael S. Tsirkin         if (!region->size) {
282315a1350SMichael S. Tsirkin             continue;
283315a1350SMichael S. Tsirkin         }
284315a1350SMichael S. Tsirkin 
285315a1350SMichael S. Tsirkin         if (!(region->type & PCI_BASE_ADDRESS_SPACE_IO) &&
286315a1350SMichael S. Tsirkin             region->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
287315a1350SMichael S. Tsirkin             pci_set_quad(dev->config + pci_bar(dev, r), region->type);
288315a1350SMichael S. Tsirkin         } else {
289315a1350SMichael S. Tsirkin             pci_set_long(dev->config + pci_bar(dev, r), region->type);
290315a1350SMichael S. Tsirkin         }
291315a1350SMichael S. Tsirkin     }
292315a1350SMichael S. Tsirkin     pci_update_mappings(dev);
293315a1350SMichael S. Tsirkin 
294315a1350SMichael S. Tsirkin     msi_reset(dev);
295315a1350SMichael S. Tsirkin     msix_reset(dev);
296315a1350SMichael S. Tsirkin }
297315a1350SMichael S. Tsirkin 
298315a1350SMichael S. Tsirkin /*
299dcc20931SPaolo Bonzini  * This function is called on #RST and FLR.
300dcc20931SPaolo Bonzini  * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
301315a1350SMichael S. Tsirkin  */
302dcc20931SPaolo Bonzini void pci_device_reset(PCIDevice *dev)
303dcc20931SPaolo Bonzini {
304dcc20931SPaolo Bonzini     qdev_reset_all(&dev->qdev);
305dcc20931SPaolo Bonzini     pci_do_device_reset(dev);
306dcc20931SPaolo Bonzini }
307dcc20931SPaolo Bonzini 
308dcc20931SPaolo Bonzini /*
309dcc20931SPaolo Bonzini  * Trigger pci bus reset under a given bus.
310dcc20931SPaolo Bonzini  * Called via qbus_reset_all on RST# assert, after the devices
311dcc20931SPaolo Bonzini  * have been reset qdev_reset_all-ed already.
312dcc20931SPaolo Bonzini  */
313dcc20931SPaolo Bonzini static void pcibus_reset(BusState *qbus)
314315a1350SMichael S. Tsirkin {
31581e3e75bSPaolo Bonzini     PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
316315a1350SMichael S. Tsirkin     int i;
317315a1350SMichael S. Tsirkin 
318315a1350SMichael S. Tsirkin     for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
319315a1350SMichael S. Tsirkin         if (bus->devices[i]) {
320dcc20931SPaolo Bonzini             pci_do_device_reset(bus->devices[i]);
321315a1350SMichael S. Tsirkin         }
322315a1350SMichael S. Tsirkin     }
323315a1350SMichael S. Tsirkin 
3249bdbbfc3SPaolo Bonzini     for (i = 0; i < bus->nirq; i++) {
3259bdbbfc3SPaolo Bonzini         assert(bus->irq_count[i] == 0);
3269bdbbfc3SPaolo Bonzini     }
327315a1350SMichael S. Tsirkin }
328315a1350SMichael S. Tsirkin 
3293dbc01aeSCao jin static void pci_host_bus_register(DeviceState *host)
330315a1350SMichael S. Tsirkin {
3313dbc01aeSCao jin     PCIHostState *host_bridge = PCI_HOST_BRIDGE(host);
3327588e2b0SDavid Gibson 
3337588e2b0SDavid Gibson     QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next);
334315a1350SMichael S. Tsirkin }
335315a1350SMichael S. Tsirkin 
336c473d18dSDavid Gibson PCIBus *pci_device_root_bus(const PCIDevice *d)
337315a1350SMichael S. Tsirkin {
338fd56e061SDavid Gibson     PCIBus *bus = pci_get_bus(d);
339315a1350SMichael S. Tsirkin 
340ce6a28eeSMarcel Apfelbaum     while (!pci_bus_is_root(bus)) {
341ce6a28eeSMarcel Apfelbaum         d = bus->parent_dev;
342ce6a28eeSMarcel Apfelbaum         assert(d != NULL);
343ce6a28eeSMarcel Apfelbaum 
344fd56e061SDavid Gibson         bus = pci_get_bus(d);
345315a1350SMichael S. Tsirkin     }
346315a1350SMichael S. Tsirkin 
347c473d18dSDavid Gibson     return bus;
348315a1350SMichael S. Tsirkin }
349315a1350SMichael S. Tsirkin 
350568f0690SDavid Gibson const char *pci_root_bus_path(PCIDevice *dev)
351c473d18dSDavid Gibson {
352568f0690SDavid Gibson     PCIBus *rootbus = pci_device_root_bus(dev);
353568f0690SDavid Gibson     PCIHostState *host_bridge = PCI_HOST_BRIDGE(rootbus->qbus.parent);
354568f0690SDavid Gibson     PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_GET_CLASS(host_bridge);
355c473d18dSDavid Gibson 
356568f0690SDavid Gibson     assert(host_bridge->bus == rootbus);
357568f0690SDavid Gibson 
358568f0690SDavid Gibson     if (hc->root_bus_path) {
359568f0690SDavid Gibson         return (*hc->root_bus_path)(host_bridge, rootbus);
360315a1350SMichael S. Tsirkin     }
361315a1350SMichael S. Tsirkin 
362568f0690SDavid Gibson     return rootbus->qbus.name;
363315a1350SMichael S. Tsirkin }
364315a1350SMichael S. Tsirkin 
3651115ff6dSDavid Gibson static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
366315a1350SMichael S. Tsirkin                               MemoryRegion *address_space_mem,
367315a1350SMichael S. Tsirkin                               MemoryRegion *address_space_io,
368315a1350SMichael S. Tsirkin                               uint8_t devfn_min)
369315a1350SMichael S. Tsirkin {
370315a1350SMichael S. Tsirkin     assert(PCI_FUNC(devfn_min) == 0);
371315a1350SMichael S. Tsirkin     bus->devfn_min = devfn_min;
3728b884984SMark Cave-Ayland     bus->slot_reserved_mask = 0x0;
373315a1350SMichael S. Tsirkin     bus->address_space_mem = address_space_mem;
374315a1350SMichael S. Tsirkin     bus->address_space_io = address_space_io;
375315a1350SMichael S. Tsirkin 
376315a1350SMichael S. Tsirkin     /* host bridge */
377315a1350SMichael S. Tsirkin     QLIST_INIT(&bus->child);
3782b8cc89aSDavid Gibson 
3793dbc01aeSCao jin     pci_host_bus_register(parent);
380315a1350SMichael S. Tsirkin }
381315a1350SMichael S. Tsirkin 
3828c0bf9e2SAlex Williamson bool pci_bus_is_express(PCIBus *bus)
3838c0bf9e2SAlex Williamson {
3848c0bf9e2SAlex Williamson     return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
3858c0bf9e2SAlex Williamson }
3868c0bf9e2SAlex Williamson 
3870889464aSAlex Williamson bool pci_bus_is_root(PCIBus *bus)
3880889464aSAlex Williamson {
389ce6a28eeSMarcel Apfelbaum     return PCI_BUS_GET_CLASS(bus)->is_root(bus);
3900889464aSAlex Williamson }
3910889464aSAlex Williamson 
3921115ff6dSDavid Gibson void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
3934fec6404SPaolo Bonzini                               const char *name,
3944fec6404SPaolo Bonzini                               MemoryRegion *address_space_mem,
3954fec6404SPaolo Bonzini                               MemoryRegion *address_space_io,
39660a0e443SAlex Williamson                               uint8_t devfn_min, const char *typename)
3974fec6404SPaolo Bonzini {
398fb17dfe0SAndreas Färber     qbus_create_inplace(bus, bus_size, typename, parent, name);
3991115ff6dSDavid Gibson     pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
4001115ff6dSDavid Gibson                       devfn_min);
4014fec6404SPaolo Bonzini }
4024fec6404SPaolo Bonzini 
4031115ff6dSDavid Gibson PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
404315a1350SMichael S. Tsirkin                          MemoryRegion *address_space_mem,
405315a1350SMichael S. Tsirkin                          MemoryRegion *address_space_io,
40660a0e443SAlex Williamson                          uint8_t devfn_min, const char *typename)
407315a1350SMichael S. Tsirkin {
408315a1350SMichael S. Tsirkin     PCIBus *bus;
409315a1350SMichael S. Tsirkin 
41060a0e443SAlex Williamson     bus = PCI_BUS(qbus_create(typename, parent, name));
4111115ff6dSDavid Gibson     pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
4121115ff6dSDavid Gibson                       devfn_min);
413315a1350SMichael S. Tsirkin     return bus;
414315a1350SMichael S. Tsirkin }
415315a1350SMichael S. Tsirkin 
416315a1350SMichael S. Tsirkin void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
417315a1350SMichael S. Tsirkin                   void *irq_opaque, int nirq)
418315a1350SMichael S. Tsirkin {
419315a1350SMichael S. Tsirkin     bus->set_irq = set_irq;
420315a1350SMichael S. Tsirkin     bus->map_irq = map_irq;
421315a1350SMichael S. Tsirkin     bus->irq_opaque = irq_opaque;
422315a1350SMichael S. Tsirkin     bus->nirq = nirq;
423315a1350SMichael S. Tsirkin     bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
424315a1350SMichael S. Tsirkin }
425315a1350SMichael S. Tsirkin 
4261115ff6dSDavid Gibson PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
427315a1350SMichael S. Tsirkin                               pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
428315a1350SMichael S. Tsirkin                               void *irq_opaque,
429315a1350SMichael S. Tsirkin                               MemoryRegion *address_space_mem,
430315a1350SMichael S. Tsirkin                               MemoryRegion *address_space_io,
4311115ff6dSDavid Gibson                               uint8_t devfn_min, int nirq,
4321115ff6dSDavid Gibson                               const char *typename)
433315a1350SMichael S. Tsirkin {
434315a1350SMichael S. Tsirkin     PCIBus *bus;
435315a1350SMichael S. Tsirkin 
4361115ff6dSDavid Gibson     bus = pci_root_bus_new(parent, name, address_space_mem,
43760a0e443SAlex Williamson                            address_space_io, devfn_min, typename);
438315a1350SMichael S. Tsirkin     pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
439315a1350SMichael S. Tsirkin     return bus;
440315a1350SMichael S. Tsirkin }
441315a1350SMichael S. Tsirkin 
442315a1350SMichael S. Tsirkin int pci_bus_num(PCIBus *s)
443315a1350SMichael S. Tsirkin {
444602141d9SMarcel Apfelbaum     return PCI_BUS_GET_CLASS(s)->bus_num(s);
445315a1350SMichael S. Tsirkin }
446315a1350SMichael S. Tsirkin 
4476a3042b2SMarcel Apfelbaum int pci_bus_numa_node(PCIBus *bus)
4486a3042b2SMarcel Apfelbaum {
4496a3042b2SMarcel Apfelbaum     return PCI_BUS_GET_CLASS(bus)->numa_node(bus);
450315a1350SMichael S. Tsirkin }
451315a1350SMichael S. Tsirkin 
4522c21ee76SJianjun Duan static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
4532c21ee76SJianjun Duan                                  VMStateField *field)
454315a1350SMichael S. Tsirkin {
455315a1350SMichael S. Tsirkin     PCIDevice *s = container_of(pv, PCIDevice, config);
456e78e9ae4SDon Koch     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(s);
457315a1350SMichael S. Tsirkin     uint8_t *config;
458315a1350SMichael S. Tsirkin     int i;
459315a1350SMichael S. Tsirkin 
460315a1350SMichael S. Tsirkin     assert(size == pci_config_size(s));
461315a1350SMichael S. Tsirkin     config = g_malloc(size);
462315a1350SMichael S. Tsirkin 
463315a1350SMichael S. Tsirkin     qemu_get_buffer(f, config, size);
464315a1350SMichael S. Tsirkin     for (i = 0; i < size; ++i) {
465315a1350SMichael S. Tsirkin         if ((config[i] ^ s->config[i]) &
466315a1350SMichael S. Tsirkin             s->cmask[i] & ~s->wmask[i] & ~s->w1cmask[i]) {
4677c59364dSDr. David Alan Gilbert             error_report("%s: Bad config data: i=0x%x read: %x device: %x "
4687c59364dSDr. David Alan Gilbert                          "cmask: %x wmask: %x w1cmask:%x", __func__,
4697c59364dSDr. David Alan Gilbert                          i, config[i], s->config[i],
4707c59364dSDr. David Alan Gilbert                          s->cmask[i], s->wmask[i], s->w1cmask[i]);
471315a1350SMichael S. Tsirkin             g_free(config);
472315a1350SMichael S. Tsirkin             return -EINVAL;
473315a1350SMichael S. Tsirkin         }
474315a1350SMichael S. Tsirkin     }
475315a1350SMichael S. Tsirkin     memcpy(s->config, config, size);
476315a1350SMichael S. Tsirkin 
477315a1350SMichael S. Tsirkin     pci_update_mappings(s);
478e78e9ae4SDon Koch     if (pc->is_bridge) {
479f055e96bSAndreas Färber         PCIBridge *b = PCI_BRIDGE(s);
480e78e9ae4SDon Koch         pci_bridge_update_mappings(b);
481e78e9ae4SDon Koch     }
482315a1350SMichael S. Tsirkin 
483315a1350SMichael S. Tsirkin     memory_region_set_enabled(&s->bus_master_enable_region,
484315a1350SMichael S. Tsirkin                               pci_get_word(s->config + PCI_COMMAND)
485315a1350SMichael S. Tsirkin                               & PCI_COMMAND_MASTER);
486315a1350SMichael S. Tsirkin 
487315a1350SMichael S. Tsirkin     g_free(config);
488315a1350SMichael S. Tsirkin     return 0;
489315a1350SMichael S. Tsirkin }
490315a1350SMichael S. Tsirkin 
491315a1350SMichael S. Tsirkin /* just put buffer */
4922c21ee76SJianjun Duan static int put_pci_config_device(QEMUFile *f, void *pv, size_t size,
4932c21ee76SJianjun Duan                                  VMStateField *field, QJSON *vmdesc)
494315a1350SMichael S. Tsirkin {
495315a1350SMichael S. Tsirkin     const uint8_t **v = pv;
496315a1350SMichael S. Tsirkin     assert(size == pci_config_size(container_of(pv, PCIDevice, config)));
497315a1350SMichael S. Tsirkin     qemu_put_buffer(f, *v, size);
4982c21ee76SJianjun Duan 
4992c21ee76SJianjun Duan     return 0;
500315a1350SMichael S. Tsirkin }
501315a1350SMichael S. Tsirkin 
502315a1350SMichael S. Tsirkin static VMStateInfo vmstate_info_pci_config = {
503315a1350SMichael S. Tsirkin     .name = "pci config",
504315a1350SMichael S. Tsirkin     .get  = get_pci_config_device,
505315a1350SMichael S. Tsirkin     .put  = put_pci_config_device,
506315a1350SMichael S. Tsirkin };
507315a1350SMichael S. Tsirkin 
5082c21ee76SJianjun Duan static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size,
5092c21ee76SJianjun Duan                              VMStateField *field)
510315a1350SMichael S. Tsirkin {
511315a1350SMichael S. Tsirkin     PCIDevice *s = container_of(pv, PCIDevice, irq_state);
512315a1350SMichael S. Tsirkin     uint32_t irq_state[PCI_NUM_PINS];
513315a1350SMichael S. Tsirkin     int i;
514315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
515315a1350SMichael S. Tsirkin         irq_state[i] = qemu_get_be32(f);
516315a1350SMichael S. Tsirkin         if (irq_state[i] != 0x1 && irq_state[i] != 0) {
517315a1350SMichael S. Tsirkin             fprintf(stderr, "irq state %d: must be 0 or 1.\n",
518315a1350SMichael S. Tsirkin                     irq_state[i]);
519315a1350SMichael S. Tsirkin             return -EINVAL;
520315a1350SMichael S. Tsirkin         }
521315a1350SMichael S. Tsirkin     }
522315a1350SMichael S. Tsirkin 
523315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
524315a1350SMichael S. Tsirkin         pci_set_irq_state(s, i, irq_state[i]);
525315a1350SMichael S. Tsirkin     }
526315a1350SMichael S. Tsirkin 
527315a1350SMichael S. Tsirkin     return 0;
528315a1350SMichael S. Tsirkin }
529315a1350SMichael S. Tsirkin 
5302c21ee76SJianjun Duan static int put_pci_irq_state(QEMUFile *f, void *pv, size_t size,
5312c21ee76SJianjun Duan                              VMStateField *field, QJSON *vmdesc)
532315a1350SMichael S. Tsirkin {
533315a1350SMichael S. Tsirkin     int i;
534315a1350SMichael S. Tsirkin     PCIDevice *s = container_of(pv, PCIDevice, irq_state);
535315a1350SMichael S. Tsirkin 
536315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
537315a1350SMichael S. Tsirkin         qemu_put_be32(f, pci_irq_state(s, i));
538315a1350SMichael S. Tsirkin     }
5392c21ee76SJianjun Duan 
5402c21ee76SJianjun Duan     return 0;
541315a1350SMichael S. Tsirkin }
542315a1350SMichael S. Tsirkin 
543315a1350SMichael S. Tsirkin static VMStateInfo vmstate_info_pci_irq_state = {
544315a1350SMichael S. Tsirkin     .name = "pci irq state",
545315a1350SMichael S. Tsirkin     .get  = get_pci_irq_state,
546315a1350SMichael S. Tsirkin     .put  = put_pci_irq_state,
547315a1350SMichael S. Tsirkin };
548315a1350SMichael S. Tsirkin 
54920daa90aSDr. David Alan Gilbert static bool migrate_is_pcie(void *opaque, int version_id)
55020daa90aSDr. David Alan Gilbert {
55120daa90aSDr. David Alan Gilbert     return pci_is_express((PCIDevice *)opaque);
55220daa90aSDr. David Alan Gilbert }
55320daa90aSDr. David Alan Gilbert 
55420daa90aSDr. David Alan Gilbert static bool migrate_is_not_pcie(void *opaque, int version_id)
55520daa90aSDr. David Alan Gilbert {
55620daa90aSDr. David Alan Gilbert     return !pci_is_express((PCIDevice *)opaque);
55720daa90aSDr. David Alan Gilbert }
55820daa90aSDr. David Alan Gilbert 
559315a1350SMichael S. Tsirkin const VMStateDescription vmstate_pci_device = {
560315a1350SMichael S. Tsirkin     .name = "PCIDevice",
561315a1350SMichael S. Tsirkin     .version_id = 2,
562315a1350SMichael S. Tsirkin     .minimum_version_id = 1,
563315a1350SMichael S. Tsirkin     .fields = (VMStateField[]) {
5643476436aSMichael S. Tsirkin         VMSTATE_INT32_POSITIVE_LE(version_id, PCIDevice),
56520daa90aSDr. David Alan Gilbert         VMSTATE_BUFFER_UNSAFE_INFO_TEST(config, PCIDevice,
56620daa90aSDr. David Alan Gilbert                                    migrate_is_not_pcie,
56720daa90aSDr. David Alan Gilbert                                    0, vmstate_info_pci_config,
568315a1350SMichael S. Tsirkin                                    PCI_CONFIG_SPACE_SIZE),
56920daa90aSDr. David Alan Gilbert         VMSTATE_BUFFER_UNSAFE_INFO_TEST(config, PCIDevice,
57020daa90aSDr. David Alan Gilbert                                    migrate_is_pcie,
57120daa90aSDr. David Alan Gilbert                                    0, vmstate_info_pci_config,
572315a1350SMichael S. Tsirkin                                    PCIE_CONFIG_SPACE_SIZE),
573315a1350SMichael S. Tsirkin         VMSTATE_BUFFER_UNSAFE_INFO(irq_state, PCIDevice, 2,
574315a1350SMichael S. Tsirkin 				   vmstate_info_pci_irq_state,
575315a1350SMichael S. Tsirkin 				   PCI_NUM_PINS * sizeof(int32_t)),
576315a1350SMichael S. Tsirkin         VMSTATE_END_OF_LIST()
577315a1350SMichael S. Tsirkin     }
578315a1350SMichael S. Tsirkin };
579315a1350SMichael S. Tsirkin 
580315a1350SMichael S. Tsirkin 
581315a1350SMichael S. Tsirkin void pci_device_save(PCIDevice *s, QEMUFile *f)
582315a1350SMichael S. Tsirkin {
583315a1350SMichael S. Tsirkin     /* Clear interrupt status bit: it is implicit
584315a1350SMichael S. Tsirkin      * in irq_state which we are saving.
585315a1350SMichael S. Tsirkin      * This makes us compatible with old devices
586315a1350SMichael S. Tsirkin      * which never set or clear this bit. */
587315a1350SMichael S. Tsirkin     s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
58820daa90aSDr. David Alan Gilbert     vmstate_save_state(f, &vmstate_pci_device, s, NULL);
589315a1350SMichael S. Tsirkin     /* Restore the interrupt status bit. */
590315a1350SMichael S. Tsirkin     pci_update_irq_status(s);
591315a1350SMichael S. Tsirkin }
592315a1350SMichael S. Tsirkin 
593315a1350SMichael S. Tsirkin int pci_device_load(PCIDevice *s, QEMUFile *f)
594315a1350SMichael S. Tsirkin {
595315a1350SMichael S. Tsirkin     int ret;
59620daa90aSDr. David Alan Gilbert     ret = vmstate_load_state(f, &vmstate_pci_device, s, s->version_id);
597315a1350SMichael S. Tsirkin     /* Restore the interrupt status bit. */
598315a1350SMichael S. Tsirkin     pci_update_irq_status(s);
599315a1350SMichael S. Tsirkin     return ret;
600315a1350SMichael S. Tsirkin }
601315a1350SMichael S. Tsirkin 
602315a1350SMichael S. Tsirkin static void pci_set_default_subsystem_id(PCIDevice *pci_dev)
603315a1350SMichael S. Tsirkin {
604315a1350SMichael S. Tsirkin     pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
605315a1350SMichael S. Tsirkin                  pci_default_sub_vendor_id);
606315a1350SMichael S. Tsirkin     pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
607315a1350SMichael S. Tsirkin                  pci_default_sub_device_id);
608315a1350SMichael S. Tsirkin }
609315a1350SMichael S. Tsirkin 
610315a1350SMichael S. Tsirkin /*
611315a1350SMichael S. Tsirkin  * Parse [[<domain>:]<bus>:]<slot>, return -1 on error if funcp == NULL
612315a1350SMichael S. Tsirkin  *       [[<domain>:]<bus>:]<slot>.<func>, return -1 on error
613315a1350SMichael S. Tsirkin  */
6146dbcb819SMarkus Armbruster static int pci_parse_devaddr(const char *addr, int *domp, int *busp,
615315a1350SMichael S. Tsirkin                              unsigned int *slotp, unsigned int *funcp)
616315a1350SMichael S. Tsirkin {
617315a1350SMichael S. Tsirkin     const char *p;
618315a1350SMichael S. Tsirkin     char *e;
619315a1350SMichael S. Tsirkin     unsigned long val;
620315a1350SMichael S. Tsirkin     unsigned long dom = 0, bus = 0;
621315a1350SMichael S. Tsirkin     unsigned int slot = 0;
622315a1350SMichael S. Tsirkin     unsigned int func = 0;
623315a1350SMichael S. Tsirkin 
624315a1350SMichael S. Tsirkin     p = addr;
625315a1350SMichael S. Tsirkin     val = strtoul(p, &e, 16);
626315a1350SMichael S. Tsirkin     if (e == p)
627315a1350SMichael S. Tsirkin 	return -1;
628315a1350SMichael S. Tsirkin     if (*e == ':') {
629315a1350SMichael S. Tsirkin 	bus = val;
630315a1350SMichael S. Tsirkin 	p = e + 1;
631315a1350SMichael S. Tsirkin 	val = strtoul(p, &e, 16);
632315a1350SMichael S. Tsirkin 	if (e == p)
633315a1350SMichael S. Tsirkin 	    return -1;
634315a1350SMichael S. Tsirkin 	if (*e == ':') {
635315a1350SMichael S. Tsirkin 	    dom = bus;
636315a1350SMichael S. Tsirkin 	    bus = val;
637315a1350SMichael S. Tsirkin 	    p = e + 1;
638315a1350SMichael S. Tsirkin 	    val = strtoul(p, &e, 16);
639315a1350SMichael S. Tsirkin 	    if (e == p)
640315a1350SMichael S. Tsirkin 		return -1;
641315a1350SMichael S. Tsirkin 	}
642315a1350SMichael S. Tsirkin     }
643315a1350SMichael S. Tsirkin 
644315a1350SMichael S. Tsirkin     slot = val;
645315a1350SMichael S. Tsirkin 
646315a1350SMichael S. Tsirkin     if (funcp != NULL) {
647315a1350SMichael S. Tsirkin         if (*e != '.')
648315a1350SMichael S. Tsirkin             return -1;
649315a1350SMichael S. Tsirkin 
650315a1350SMichael S. Tsirkin         p = e + 1;
651315a1350SMichael S. Tsirkin         val = strtoul(p, &e, 16);
652315a1350SMichael S. Tsirkin         if (e == p)
653315a1350SMichael S. Tsirkin             return -1;
654315a1350SMichael S. Tsirkin 
655315a1350SMichael S. Tsirkin         func = val;
656315a1350SMichael S. Tsirkin     }
657315a1350SMichael S. Tsirkin 
658315a1350SMichael S. Tsirkin     /* if funcp == NULL func is 0 */
659315a1350SMichael S. Tsirkin     if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7)
660315a1350SMichael S. Tsirkin 	return -1;
661315a1350SMichael S. Tsirkin 
662315a1350SMichael S. Tsirkin     if (*e)
663315a1350SMichael S. Tsirkin 	return -1;
664315a1350SMichael S. Tsirkin 
665315a1350SMichael S. Tsirkin     *domp = dom;
666315a1350SMichael S. Tsirkin     *busp = bus;
667315a1350SMichael S. Tsirkin     *slotp = slot;
668315a1350SMichael S. Tsirkin     if (funcp != NULL)
669315a1350SMichael S. Tsirkin         *funcp = func;
670315a1350SMichael S. Tsirkin     return 0;
671315a1350SMichael S. Tsirkin }
672315a1350SMichael S. Tsirkin 
6736dbcb819SMarkus Armbruster static PCIBus *pci_get_bus_devfn(int *devfnp, PCIBus *root,
6746dbcb819SMarkus Armbruster                                  const char *devaddr)
675315a1350SMichael S. Tsirkin {
676315a1350SMichael S. Tsirkin     int dom, bus;
677315a1350SMichael S. Tsirkin     unsigned slot;
678315a1350SMichael S. Tsirkin 
6791ef7a2a2SDavid Gibson     if (!root) {
6801ef7a2a2SDavid Gibson         fprintf(stderr, "No primary PCI bus\n");
6811ef7a2a2SDavid Gibson         return NULL;
6821ef7a2a2SDavid Gibson     }
6831ef7a2a2SDavid Gibson 
684b645000eSSaravanakumar     assert(!root->parent_dev);
685b645000eSSaravanakumar 
686315a1350SMichael S. Tsirkin     if (!devaddr) {
687315a1350SMichael S. Tsirkin         *devfnp = -1;
6881ef7a2a2SDavid Gibson         return pci_find_bus_nr(root, 0);
689315a1350SMichael S. Tsirkin     }
690315a1350SMichael S. Tsirkin 
691315a1350SMichael S. Tsirkin     if (pci_parse_devaddr(devaddr, &dom, &bus, &slot, NULL) < 0) {
692315a1350SMichael S. Tsirkin         return NULL;
693315a1350SMichael S. Tsirkin     }
694315a1350SMichael S. Tsirkin 
6951ef7a2a2SDavid Gibson     if (dom != 0) {
6961ef7a2a2SDavid Gibson         fprintf(stderr, "No support for non-zero PCI domains\n");
6971ef7a2a2SDavid Gibson         return NULL;
6981ef7a2a2SDavid Gibson     }
6991ef7a2a2SDavid Gibson 
700315a1350SMichael S. Tsirkin     *devfnp = PCI_DEVFN(slot, 0);
7011ef7a2a2SDavid Gibson     return pci_find_bus_nr(root, bus);
702315a1350SMichael S. Tsirkin }
703315a1350SMichael S. Tsirkin 
704315a1350SMichael S. Tsirkin static void pci_init_cmask(PCIDevice *dev)
705315a1350SMichael S. Tsirkin {
706315a1350SMichael S. Tsirkin     pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff);
707315a1350SMichael S. Tsirkin     pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff);
708315a1350SMichael S. Tsirkin     dev->cmask[PCI_STATUS] = PCI_STATUS_CAP_LIST;
709315a1350SMichael S. Tsirkin     dev->cmask[PCI_REVISION_ID] = 0xff;
710315a1350SMichael S. Tsirkin     dev->cmask[PCI_CLASS_PROG] = 0xff;
711315a1350SMichael S. Tsirkin     pci_set_word(dev->cmask + PCI_CLASS_DEVICE, 0xffff);
712315a1350SMichael S. Tsirkin     dev->cmask[PCI_HEADER_TYPE] = 0xff;
713315a1350SMichael S. Tsirkin     dev->cmask[PCI_CAPABILITY_LIST] = 0xff;
714315a1350SMichael S. Tsirkin }
715315a1350SMichael S. Tsirkin 
716315a1350SMichael S. Tsirkin static void pci_init_wmask(PCIDevice *dev)
717315a1350SMichael S. Tsirkin {
718315a1350SMichael S. Tsirkin     int config_size = pci_config_size(dev);
719315a1350SMichael S. Tsirkin 
720315a1350SMichael S. Tsirkin     dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
721315a1350SMichael S. Tsirkin     dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
722315a1350SMichael S. Tsirkin     pci_set_word(dev->wmask + PCI_COMMAND,
723315a1350SMichael S. Tsirkin                  PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
724315a1350SMichael S. Tsirkin                  PCI_COMMAND_INTX_DISABLE);
725315a1350SMichael S. Tsirkin     if (dev->cap_present & QEMU_PCI_CAP_SERR) {
726315a1350SMichael S. Tsirkin         pci_word_test_and_set_mask(dev->wmask + PCI_COMMAND, PCI_COMMAND_SERR);
727315a1350SMichael S. Tsirkin     }
728315a1350SMichael S. Tsirkin 
729315a1350SMichael S. Tsirkin     memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff,
730315a1350SMichael S. Tsirkin            config_size - PCI_CONFIG_HEADER_SIZE);
731315a1350SMichael S. Tsirkin }
732315a1350SMichael S. Tsirkin 
733315a1350SMichael S. Tsirkin static void pci_init_w1cmask(PCIDevice *dev)
734315a1350SMichael S. Tsirkin {
735315a1350SMichael S. Tsirkin     /*
736315a1350SMichael S. Tsirkin      * Note: It's okay to set w1cmask even for readonly bits as
737315a1350SMichael S. Tsirkin      * long as their value is hardwired to 0.
738315a1350SMichael S. Tsirkin      */
739315a1350SMichael S. Tsirkin     pci_set_word(dev->w1cmask + PCI_STATUS,
740315a1350SMichael S. Tsirkin                  PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
741315a1350SMichael S. Tsirkin                  PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
742315a1350SMichael S. Tsirkin                  PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY);
743315a1350SMichael S. Tsirkin }
744315a1350SMichael S. Tsirkin 
745315a1350SMichael S. Tsirkin static void pci_init_mask_bridge(PCIDevice *d)
746315a1350SMichael S. Tsirkin {
747315a1350SMichael S. Tsirkin     /* PCI_PRIMARY_BUS, PCI_SECONDARY_BUS, PCI_SUBORDINATE_BUS and
748315a1350SMichael S. Tsirkin        PCI_SEC_LETENCY_TIMER */
749315a1350SMichael S. Tsirkin     memset(d->wmask + PCI_PRIMARY_BUS, 0xff, 4);
750315a1350SMichael S. Tsirkin 
751315a1350SMichael S. Tsirkin     /* base and limit */
752315a1350SMichael S. Tsirkin     d->wmask[PCI_IO_BASE] = PCI_IO_RANGE_MASK & 0xff;
753315a1350SMichael S. Tsirkin     d->wmask[PCI_IO_LIMIT] = PCI_IO_RANGE_MASK & 0xff;
754315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_MEMORY_BASE,
755315a1350SMichael S. Tsirkin                  PCI_MEMORY_RANGE_MASK & 0xffff);
756315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_MEMORY_LIMIT,
757315a1350SMichael S. Tsirkin                  PCI_MEMORY_RANGE_MASK & 0xffff);
758315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_PREF_MEMORY_BASE,
759315a1350SMichael S. Tsirkin                  PCI_PREF_RANGE_MASK & 0xffff);
760315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_PREF_MEMORY_LIMIT,
761315a1350SMichael S. Tsirkin                  PCI_PREF_RANGE_MASK & 0xffff);
762315a1350SMichael S. Tsirkin 
763315a1350SMichael S. Tsirkin     /* PCI_PREF_BASE_UPPER32 and PCI_PREF_LIMIT_UPPER32 */
764315a1350SMichael S. Tsirkin     memset(d->wmask + PCI_PREF_BASE_UPPER32, 0xff, 8);
765315a1350SMichael S. Tsirkin 
766315a1350SMichael S. Tsirkin     /* Supported memory and i/o types */
767315a1350SMichael S. Tsirkin     d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_16;
768315a1350SMichael S. Tsirkin     d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_16;
769315a1350SMichael S. Tsirkin     pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_BASE,
770315a1350SMichael S. Tsirkin                                PCI_PREF_RANGE_TYPE_64);
771315a1350SMichael S. Tsirkin     pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT,
772315a1350SMichael S. Tsirkin                                PCI_PREF_RANGE_TYPE_64);
773315a1350SMichael S. Tsirkin 
774ba7d8515SAlex Williamson     /*
775ba7d8515SAlex Williamson      * TODO: Bridges default to 10-bit VGA decoding but we currently only
776ba7d8515SAlex Williamson      * implement 16-bit decoding (no alias support).
777ba7d8515SAlex Williamson      */
778315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_BRIDGE_CONTROL,
779315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_PARITY |
780315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_SERR |
781315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_ISA |
782315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_VGA |
783315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_VGA_16BIT |
784315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_MASTER_ABORT |
785315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_BUS_RESET |
786315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_FAST_BACK |
787315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_DISCARD |
788315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_SEC_DISCARD |
789315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_DISCARD_SERR);
790315a1350SMichael S. Tsirkin     /* Below does not do anything as we never set this bit, put here for
791315a1350SMichael S. Tsirkin      * completeness. */
792315a1350SMichael S. Tsirkin     pci_set_word(d->w1cmask + PCI_BRIDGE_CONTROL,
793315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_DISCARD_STATUS);
794315a1350SMichael S. Tsirkin     d->cmask[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_MASK;
795315a1350SMichael S. Tsirkin     d->cmask[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_MASK;
796315a1350SMichael S. Tsirkin     pci_word_test_and_set_mask(d->cmask + PCI_PREF_MEMORY_BASE,
797315a1350SMichael S. Tsirkin                                PCI_PREF_RANGE_TYPE_MASK);
798315a1350SMichael S. Tsirkin     pci_word_test_and_set_mask(d->cmask + PCI_PREF_MEMORY_LIMIT,
799315a1350SMichael S. Tsirkin                                PCI_PREF_RANGE_TYPE_MASK);
800315a1350SMichael S. Tsirkin }
801315a1350SMichael S. Tsirkin 
802133e9b22SMarkus Armbruster static void pci_init_multifunction(PCIBus *bus, PCIDevice *dev, Error **errp)
803315a1350SMichael S. Tsirkin {
804315a1350SMichael S. Tsirkin     uint8_t slot = PCI_SLOT(dev->devfn);
805315a1350SMichael S. Tsirkin     uint8_t func;
806315a1350SMichael S. Tsirkin 
807315a1350SMichael S. Tsirkin     if (dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
808315a1350SMichael S. Tsirkin         dev->config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION;
809315a1350SMichael S. Tsirkin     }
810315a1350SMichael S. Tsirkin 
811315a1350SMichael S. Tsirkin     /*
812315a1350SMichael S. Tsirkin      * multifunction bit is interpreted in two ways as follows.
813315a1350SMichael S. Tsirkin      *   - all functions must set the bit to 1.
814315a1350SMichael S. Tsirkin      *     Example: Intel X53
815315a1350SMichael S. Tsirkin      *   - function 0 must set the bit, but the rest function (> 0)
816315a1350SMichael S. Tsirkin      *     is allowed to leave the bit to 0.
817315a1350SMichael S. Tsirkin      *     Example: PIIX3(also in qemu), PIIX4(also in qemu), ICH10,
818315a1350SMichael S. Tsirkin      *
819315a1350SMichael S. Tsirkin      * So OS (at least Linux) checks the bit of only function 0,
820315a1350SMichael S. Tsirkin      * and doesn't see the bit of function > 0.
821315a1350SMichael S. Tsirkin      *
822315a1350SMichael S. Tsirkin      * The below check allows both interpretation.
823315a1350SMichael S. Tsirkin      */
824315a1350SMichael S. Tsirkin     if (PCI_FUNC(dev->devfn)) {
825315a1350SMichael S. Tsirkin         PCIDevice *f0 = bus->devices[PCI_DEVFN(slot, 0)];
826315a1350SMichael S. Tsirkin         if (f0 && !(f0->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)) {
827315a1350SMichael S. Tsirkin             /* function 0 should set multifunction bit */
828133e9b22SMarkus Armbruster             error_setg(errp, "PCI: single function device can't be populated "
829315a1350SMichael S. Tsirkin                        "in function %x.%x", slot, PCI_FUNC(dev->devfn));
830133e9b22SMarkus Armbruster             return;
831315a1350SMichael S. Tsirkin         }
832133e9b22SMarkus Armbruster         return;
833315a1350SMichael S. Tsirkin     }
834315a1350SMichael S. Tsirkin 
835315a1350SMichael S. Tsirkin     if (dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
836133e9b22SMarkus Armbruster         return;
837315a1350SMichael S. Tsirkin     }
838315a1350SMichael S. Tsirkin     /* function 0 indicates single function, so function > 0 must be NULL */
839315a1350SMichael S. Tsirkin     for (func = 1; func < PCI_FUNC_MAX; ++func) {
840315a1350SMichael S. Tsirkin         if (bus->devices[PCI_DEVFN(slot, func)]) {
841133e9b22SMarkus Armbruster             error_setg(errp, "PCI: %x.0 indicates single function, "
842315a1350SMichael S. Tsirkin                        "but %x.%x is already populated.",
843315a1350SMichael S. Tsirkin                        slot, slot, func);
844133e9b22SMarkus Armbruster             return;
845315a1350SMichael S. Tsirkin         }
846315a1350SMichael S. Tsirkin     }
847315a1350SMichael S. Tsirkin }
848315a1350SMichael S. Tsirkin 
849315a1350SMichael S. Tsirkin static void pci_config_alloc(PCIDevice *pci_dev)
850315a1350SMichael S. Tsirkin {
851315a1350SMichael S. Tsirkin     int config_size = pci_config_size(pci_dev);
852315a1350SMichael S. Tsirkin 
853315a1350SMichael S. Tsirkin     pci_dev->config = g_malloc0(config_size);
854315a1350SMichael S. Tsirkin     pci_dev->cmask = g_malloc0(config_size);
855315a1350SMichael S. Tsirkin     pci_dev->wmask = g_malloc0(config_size);
856315a1350SMichael S. Tsirkin     pci_dev->w1cmask = g_malloc0(config_size);
857315a1350SMichael S. Tsirkin     pci_dev->used = g_malloc0(config_size);
858315a1350SMichael S. Tsirkin }
859315a1350SMichael S. Tsirkin 
860315a1350SMichael S. Tsirkin static void pci_config_free(PCIDevice *pci_dev)
861315a1350SMichael S. Tsirkin {
862315a1350SMichael S. Tsirkin     g_free(pci_dev->config);
863315a1350SMichael S. Tsirkin     g_free(pci_dev->cmask);
864315a1350SMichael S. Tsirkin     g_free(pci_dev->wmask);
865315a1350SMichael S. Tsirkin     g_free(pci_dev->w1cmask);
866315a1350SMichael S. Tsirkin     g_free(pci_dev->used);
867315a1350SMichael S. Tsirkin }
868315a1350SMichael S. Tsirkin 
86930607764SMarcel Apfelbaum static void do_pci_unregister_device(PCIDevice *pci_dev)
87030607764SMarcel Apfelbaum {
871fd56e061SDavid Gibson     pci_get_bus(pci_dev)->devices[pci_dev->devfn] = NULL;
87230607764SMarcel Apfelbaum     pci_config_free(pci_dev);
87330607764SMarcel Apfelbaum 
874193982c6SAlexey Kardashevskiy     if (memory_region_is_mapped(&pci_dev->bus_master_enable_region)) {
875c53598edSAlexey Kardashevskiy         memory_region_del_subregion(&pci_dev->bus_master_container_region,
876c53598edSAlexey Kardashevskiy                                     &pci_dev->bus_master_enable_region);
877193982c6SAlexey Kardashevskiy     }
87830607764SMarcel Apfelbaum     address_space_destroy(&pci_dev->bus_master_as);
87930607764SMarcel Apfelbaum }
88030607764SMarcel Apfelbaum 
8814a94b3aaSPeter Xu /* Extract PCIReqIDCache into BDF format */
8824a94b3aaSPeter Xu static uint16_t pci_req_id_cache_extract(PCIReqIDCache *cache)
8834a94b3aaSPeter Xu {
8844a94b3aaSPeter Xu     uint8_t bus_n;
8854a94b3aaSPeter Xu     uint16_t result;
8864a94b3aaSPeter Xu 
8874a94b3aaSPeter Xu     switch (cache->type) {
8884a94b3aaSPeter Xu     case PCI_REQ_ID_BDF:
8894a94b3aaSPeter Xu         result = pci_get_bdf(cache->dev);
8904a94b3aaSPeter Xu         break;
8914a94b3aaSPeter Xu     case PCI_REQ_ID_SECONDARY_BUS:
892fd56e061SDavid Gibson         bus_n = pci_dev_bus_num(cache->dev);
8934a94b3aaSPeter Xu         result = PCI_BUILD_BDF(bus_n, 0);
8944a94b3aaSPeter Xu         break;
8954a94b3aaSPeter Xu     default:
8964a94b3aaSPeter Xu         error_printf("Invalid PCI requester ID cache type: %d\n",
8974a94b3aaSPeter Xu                      cache->type);
8984a94b3aaSPeter Xu         exit(1);
8994a94b3aaSPeter Xu         break;
9004a94b3aaSPeter Xu     }
9014a94b3aaSPeter Xu 
9024a94b3aaSPeter Xu     return result;
9034a94b3aaSPeter Xu }
9044a94b3aaSPeter Xu 
9054a94b3aaSPeter Xu /* Parse bridges up to the root complex and return requester ID
9064a94b3aaSPeter Xu  * cache for specific device.  For full PCIe topology, the cache
9074a94b3aaSPeter Xu  * result would be exactly the same as getting BDF of the device.
9084a94b3aaSPeter Xu  * However, several tricks are required when system mixed up with
9094a94b3aaSPeter Xu  * legacy PCI devices and PCIe-to-PCI bridges.
9104a94b3aaSPeter Xu  *
9114a94b3aaSPeter Xu  * Here we cache the proxy device (and type) not requester ID since
9124a94b3aaSPeter Xu  * bus number might change from time to time.
9134a94b3aaSPeter Xu  */
9144a94b3aaSPeter Xu static PCIReqIDCache pci_req_id_cache_get(PCIDevice *dev)
9154a94b3aaSPeter Xu {
9164a94b3aaSPeter Xu     PCIDevice *parent;
9174a94b3aaSPeter Xu     PCIReqIDCache cache = {
9184a94b3aaSPeter Xu         .dev = dev,
9194a94b3aaSPeter Xu         .type = PCI_REQ_ID_BDF,
9204a94b3aaSPeter Xu     };
9214a94b3aaSPeter Xu 
922fd56e061SDavid Gibson     while (!pci_bus_is_root(pci_get_bus(dev))) {
9234a94b3aaSPeter Xu         /* We are under PCI/PCIe bridges */
924fd56e061SDavid Gibson         parent = pci_get_bus(dev)->parent_dev;
9254a94b3aaSPeter Xu         if (pci_is_express(parent)) {
9264a94b3aaSPeter Xu             if (pcie_cap_get_type(parent) == PCI_EXP_TYPE_PCI_BRIDGE) {
9274a94b3aaSPeter Xu                 /* When we pass through PCIe-to-PCI/PCIX bridges, we
9284a94b3aaSPeter Xu                  * override the requester ID using secondary bus
9294a94b3aaSPeter Xu                  * number of parent bridge with zeroed devfn
9304a94b3aaSPeter Xu                  * (pcie-to-pci bridge spec chap 2.3). */
9314a94b3aaSPeter Xu                 cache.type = PCI_REQ_ID_SECONDARY_BUS;
9324a94b3aaSPeter Xu                 cache.dev = dev;
9334a94b3aaSPeter Xu             }
9344a94b3aaSPeter Xu         } else {
9354a94b3aaSPeter Xu             /* Legacy PCI, override requester ID with the bridge's
9364a94b3aaSPeter Xu              * BDF upstream.  When the root complex connects to
9374a94b3aaSPeter Xu              * legacy PCI devices (including buses), it can only
9384a94b3aaSPeter Xu              * obtain requester ID info from directly attached
9394a94b3aaSPeter Xu              * devices.  If devices are attached under bridges, only
9404a94b3aaSPeter Xu              * the requester ID of the bridge that is directly
9414a94b3aaSPeter Xu              * attached to the root complex can be recognized. */
9424a94b3aaSPeter Xu             cache.type = PCI_REQ_ID_BDF;
9434a94b3aaSPeter Xu             cache.dev = parent;
9444a94b3aaSPeter Xu         }
9454a94b3aaSPeter Xu         dev = parent;
9464a94b3aaSPeter Xu     }
9474a94b3aaSPeter Xu 
9484a94b3aaSPeter Xu     return cache;
9494a94b3aaSPeter Xu }
9504a94b3aaSPeter Xu 
9514a94b3aaSPeter Xu uint16_t pci_requester_id(PCIDevice *dev)
9524a94b3aaSPeter Xu {
9534a94b3aaSPeter Xu     return pci_req_id_cache_extract(&dev->requester_id_cache);
9544a94b3aaSPeter Xu }
9554a94b3aaSPeter Xu 
9569b717a3aSMark Cave-Ayland static bool pci_bus_devfn_available(PCIBus *bus, int devfn)
9579b717a3aSMark Cave-Ayland {
9589b717a3aSMark Cave-Ayland     return !(bus->devices[devfn]);
9599b717a3aSMark Cave-Ayland }
9609b717a3aSMark Cave-Ayland 
9618b884984SMark Cave-Ayland static bool pci_bus_devfn_reserved(PCIBus *bus, int devfn)
9628b884984SMark Cave-Ayland {
9638b884984SMark Cave-Ayland     return bus->slot_reserved_mask & (1UL << PCI_SLOT(devfn));
9648b884984SMark Cave-Ayland }
9658b884984SMark Cave-Ayland 
966315a1350SMichael S. Tsirkin /* -1 for devfn means auto assign */
967fd56e061SDavid Gibson static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
968133e9b22SMarkus Armbruster                                          const char *name, int devfn,
969133e9b22SMarkus Armbruster                                          Error **errp)
970315a1350SMichael S. Tsirkin {
971315a1350SMichael S. Tsirkin     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
972315a1350SMichael S. Tsirkin     PCIConfigReadFunc *config_read = pc->config_read;
973315a1350SMichael S. Tsirkin     PCIConfigWriteFunc *config_write = pc->config_write;
974133e9b22SMarkus Armbruster     Error *local_err = NULL;
9753f1e1478SCao jin     DeviceState *dev = DEVICE(pci_dev);
976fd56e061SDavid Gibson     PCIBus *bus = pci_get_bus(pci_dev);
9773f1e1478SCao jin 
9780144f6f1SMarcel Apfelbaum     /* Only pci bridges can be attached to extra PCI root buses */
9790144f6f1SMarcel Apfelbaum     if (pci_bus_is_root(bus) && bus->parent_dev && !pc->is_bridge) {
9800144f6f1SMarcel Apfelbaum         error_setg(errp,
9810144f6f1SMarcel Apfelbaum                    "PCI: Only PCI/PCIe bridges can be plugged into %s",
9820144f6f1SMarcel Apfelbaum                     bus->parent_dev->name);
9830144f6f1SMarcel Apfelbaum         return NULL;
9840144f6f1SMarcel Apfelbaum     }
985315a1350SMichael S. Tsirkin 
986315a1350SMichael S. Tsirkin     if (devfn < 0) {
987315a1350SMichael S. Tsirkin         for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
988315a1350SMichael S. Tsirkin             devfn += PCI_FUNC_MAX) {
9898b884984SMark Cave-Ayland             if (pci_bus_devfn_available(bus, devfn) &&
9908b884984SMark Cave-Ayland                    !pci_bus_devfn_reserved(bus, devfn)) {
991315a1350SMichael S. Tsirkin                 goto found;
992315a1350SMichael S. Tsirkin             }
9939b717a3aSMark Cave-Ayland         }
9948b884984SMark Cave-Ayland         error_setg(errp, "PCI: no slot/function available for %s, all in use "
9958b884984SMark Cave-Ayland                    "or reserved", name);
996315a1350SMichael S. Tsirkin         return NULL;
997315a1350SMichael S. Tsirkin     found: ;
9988b884984SMark Cave-Ayland     } else if (pci_bus_devfn_reserved(bus, devfn)) {
9998b884984SMark Cave-Ayland         error_setg(errp, "PCI: slot %d function %d not available for %s,"
10008b884984SMark Cave-Ayland                    " reserved",
10018b884984SMark Cave-Ayland                    PCI_SLOT(devfn), PCI_FUNC(devfn), name);
10028b884984SMark Cave-Ayland         return NULL;
10039b717a3aSMark Cave-Ayland     } else if (!pci_bus_devfn_available(bus, devfn)) {
1004133e9b22SMarkus Armbruster         error_setg(errp, "PCI: slot %d function %d not available for %s,"
1005133e9b22SMarkus Armbruster                    " in use by %s",
1006133e9b22SMarkus Armbruster                    PCI_SLOT(devfn), PCI_FUNC(devfn), name,
1007133e9b22SMarkus Armbruster                    bus->devices[devfn]->name);
1008315a1350SMichael S. Tsirkin         return NULL;
10093f1e1478SCao jin     } else if (dev->hotplugged &&
10103f1e1478SCao jin                pci_get_function_0(pci_dev)) {
10113f1e1478SCao jin         error_setg(errp, "PCI: slot %d function 0 already ocuppied by %s,"
10123f1e1478SCao jin                    " new func %s cannot be exposed to guest.",
1013d93ddfb1SMichael S. Tsirkin                    PCI_SLOT(pci_get_function_0(pci_dev)->devfn),
1014d93ddfb1SMichael S. Tsirkin                    pci_get_function_0(pci_dev)->name,
10153f1e1478SCao jin                    name);
10163f1e1478SCao jin 
10173f1e1478SCao jin        return NULL;
1018315a1350SMichael S. Tsirkin     }
1019e00387d5SAvi Kivity 
1020efc8188eSLe Tan     pci_dev->devfn = devfn;
10214a94b3aaSPeter Xu     pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
1022d06bce95SAlexey Kardashevskiy     pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
1023e00387d5SAvi Kivity 
10243716d590SJason Wang     memory_region_init(&pci_dev->bus_master_container_region, OBJECT(pci_dev),
10253716d590SJason Wang                        "bus master container", UINT64_MAX);
10263716d590SJason Wang     address_space_init(&pci_dev->bus_master_as,
10273716d590SJason Wang                        &pci_dev->bus_master_container_region, pci_dev->name);
10283716d590SJason Wang 
1029b86eacb8SMarcel Apfelbaum     if (qdev_hotplug) {
1030b86eacb8SMarcel Apfelbaum         pci_init_bus_master(pci_dev);
1031b86eacb8SMarcel Apfelbaum     }
1032315a1350SMichael S. Tsirkin     pci_dev->irq_state = 0;
1033315a1350SMichael S. Tsirkin     pci_config_alloc(pci_dev);
1034315a1350SMichael S. Tsirkin 
1035315a1350SMichael S. Tsirkin     pci_config_set_vendor_id(pci_dev->config, pc->vendor_id);
1036315a1350SMichael S. Tsirkin     pci_config_set_device_id(pci_dev->config, pc->device_id);
1037315a1350SMichael S. Tsirkin     pci_config_set_revision(pci_dev->config, pc->revision);
1038315a1350SMichael S. Tsirkin     pci_config_set_class(pci_dev->config, pc->class_id);
1039315a1350SMichael S. Tsirkin 
1040315a1350SMichael S. Tsirkin     if (!pc->is_bridge) {
1041315a1350SMichael S. Tsirkin         if (pc->subsystem_vendor_id || pc->subsystem_id) {
1042315a1350SMichael S. Tsirkin             pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
1043315a1350SMichael S. Tsirkin                          pc->subsystem_vendor_id);
1044315a1350SMichael S. Tsirkin             pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
1045315a1350SMichael S. Tsirkin                          pc->subsystem_id);
1046315a1350SMichael S. Tsirkin         } else {
1047315a1350SMichael S. Tsirkin             pci_set_default_subsystem_id(pci_dev);
1048315a1350SMichael S. Tsirkin         }
1049315a1350SMichael S. Tsirkin     } else {
1050315a1350SMichael S. Tsirkin         /* subsystem_vendor_id/subsystem_id are only for header type 0 */
1051315a1350SMichael S. Tsirkin         assert(!pc->subsystem_vendor_id);
1052315a1350SMichael S. Tsirkin         assert(!pc->subsystem_id);
1053315a1350SMichael S. Tsirkin     }
1054315a1350SMichael S. Tsirkin     pci_init_cmask(pci_dev);
1055315a1350SMichael S. Tsirkin     pci_init_wmask(pci_dev);
1056315a1350SMichael S. Tsirkin     pci_init_w1cmask(pci_dev);
1057315a1350SMichael S. Tsirkin     if (pc->is_bridge) {
1058315a1350SMichael S. Tsirkin         pci_init_mask_bridge(pci_dev);
1059315a1350SMichael S. Tsirkin     }
1060133e9b22SMarkus Armbruster     pci_init_multifunction(bus, pci_dev, &local_err);
1061133e9b22SMarkus Armbruster     if (local_err) {
1062133e9b22SMarkus Armbruster         error_propagate(errp, local_err);
106330607764SMarcel Apfelbaum         do_pci_unregister_device(pci_dev);
1064315a1350SMichael S. Tsirkin         return NULL;
1065315a1350SMichael S. Tsirkin     }
1066315a1350SMichael S. Tsirkin 
1067315a1350SMichael S. Tsirkin     if (!config_read)
1068315a1350SMichael S. Tsirkin         config_read = pci_default_read_config;
1069315a1350SMichael S. Tsirkin     if (!config_write)
1070315a1350SMichael S. Tsirkin         config_write = pci_default_write_config;
1071315a1350SMichael S. Tsirkin     pci_dev->config_read = config_read;
1072315a1350SMichael S. Tsirkin     pci_dev->config_write = config_write;
1073315a1350SMichael S. Tsirkin     bus->devices[devfn] = pci_dev;
1074315a1350SMichael S. Tsirkin     pci_dev->version_id = 2; /* Current pci device vmstate version */
1075315a1350SMichael S. Tsirkin     return pci_dev;
1076315a1350SMichael S. Tsirkin }
1077315a1350SMichael S. Tsirkin 
1078315a1350SMichael S. Tsirkin static void pci_unregister_io_regions(PCIDevice *pci_dev)
1079315a1350SMichael S. Tsirkin {
1080315a1350SMichael S. Tsirkin     PCIIORegion *r;
1081315a1350SMichael S. Tsirkin     int i;
1082315a1350SMichael S. Tsirkin 
1083315a1350SMichael S. Tsirkin     for(i = 0; i < PCI_NUM_REGIONS; i++) {
1084315a1350SMichael S. Tsirkin         r = &pci_dev->io_regions[i];
1085315a1350SMichael S. Tsirkin         if (!r->size || r->addr == PCI_BAR_UNMAPPED)
1086315a1350SMichael S. Tsirkin             continue;
1087315a1350SMichael S. Tsirkin         memory_region_del_subregion(r->address_space, r->memory);
1088315a1350SMichael S. Tsirkin     }
1089e01fd687SAlex Williamson 
1090e01fd687SAlex Williamson     pci_unregister_vga(pci_dev);
1091315a1350SMichael S. Tsirkin }
1092315a1350SMichael S. Tsirkin 
1093133e9b22SMarkus Armbruster static void pci_qdev_unrealize(DeviceState *dev, Error **errp)
1094315a1350SMichael S. Tsirkin {
1095315a1350SMichael S. Tsirkin     PCIDevice *pci_dev = PCI_DEVICE(dev);
1096315a1350SMichael S. Tsirkin     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
1097315a1350SMichael S. Tsirkin 
1098315a1350SMichael S. Tsirkin     pci_unregister_io_regions(pci_dev);
1099315a1350SMichael S. Tsirkin     pci_del_option_rom(pci_dev);
1100315a1350SMichael S. Tsirkin 
1101315a1350SMichael S. Tsirkin     if (pc->exit) {
1102315a1350SMichael S. Tsirkin         pc->exit(pci_dev);
1103315a1350SMichael S. Tsirkin     }
1104315a1350SMichael S. Tsirkin 
11053936161fSHerongguang (Stephen)     pci_device_deassert_intx(pci_dev);
1106315a1350SMichael S. Tsirkin     do_pci_unregister_device(pci_dev);
1107315a1350SMichael S. Tsirkin }
1108315a1350SMichael S. Tsirkin 
1109315a1350SMichael S. Tsirkin void pci_register_bar(PCIDevice *pci_dev, int region_num,
1110315a1350SMichael S. Tsirkin                       uint8_t type, MemoryRegion *memory)
1111315a1350SMichael S. Tsirkin {
1112315a1350SMichael S. Tsirkin     PCIIORegion *r;
11135178ecd8SCao jin     uint32_t addr; /* offset in pci config space */
1114315a1350SMichael S. Tsirkin     uint64_t wmask;
1115315a1350SMichael S. Tsirkin     pcibus_t size = memory_region_size(memory);
1116315a1350SMichael S. Tsirkin 
1117315a1350SMichael S. Tsirkin     assert(region_num >= 0);
1118315a1350SMichael S. Tsirkin     assert(region_num < PCI_NUM_REGIONS);
1119315a1350SMichael S. Tsirkin     if (size & (size-1)) {
11200151abe4SAlistair Francis         error_report("ERROR: PCI region size must be pow2 "
11210151abe4SAlistair Francis                     "type=0x%x, size=0x%"FMT_PCIBUS"", type, size);
1122315a1350SMichael S. Tsirkin         exit(1);
1123315a1350SMichael S. Tsirkin     }
1124315a1350SMichael S. Tsirkin 
1125315a1350SMichael S. Tsirkin     r = &pci_dev->io_regions[region_num];
1126315a1350SMichael S. Tsirkin     r->addr = PCI_BAR_UNMAPPED;
1127315a1350SMichael S. Tsirkin     r->size = size;
1128315a1350SMichael S. Tsirkin     r->type = type;
11295178ecd8SCao jin     r->memory = memory;
11305178ecd8SCao jin     r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO
1131fd56e061SDavid Gibson                         ? pci_get_bus(pci_dev)->address_space_io
1132fd56e061SDavid Gibson                         : pci_get_bus(pci_dev)->address_space_mem;
1133315a1350SMichael S. Tsirkin 
1134315a1350SMichael S. Tsirkin     wmask = ~(size - 1);
1135315a1350SMichael S. Tsirkin     if (region_num == PCI_ROM_SLOT) {
1136315a1350SMichael S. Tsirkin         /* ROM enable bit is writable */
1137315a1350SMichael S. Tsirkin         wmask |= PCI_ROM_ADDRESS_ENABLE;
1138315a1350SMichael S. Tsirkin     }
11395178ecd8SCao jin 
11405178ecd8SCao jin     addr = pci_bar(pci_dev, region_num);
1141315a1350SMichael S. Tsirkin     pci_set_long(pci_dev->config + addr, type);
11425178ecd8SCao jin 
1143315a1350SMichael S. Tsirkin     if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&
1144315a1350SMichael S. Tsirkin         r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
1145315a1350SMichael S. Tsirkin         pci_set_quad(pci_dev->wmask + addr, wmask);
1146315a1350SMichael S. Tsirkin         pci_set_quad(pci_dev->cmask + addr, ~0ULL);
1147315a1350SMichael S. Tsirkin     } else {
1148315a1350SMichael S. Tsirkin         pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
1149315a1350SMichael S. Tsirkin         pci_set_long(pci_dev->cmask + addr, 0xffffffff);
1150315a1350SMichael S. Tsirkin     }
1151315a1350SMichael S. Tsirkin }
1152315a1350SMichael S. Tsirkin 
1153e01fd687SAlex Williamson static void pci_update_vga(PCIDevice *pci_dev)
1154e01fd687SAlex Williamson {
1155e01fd687SAlex Williamson     uint16_t cmd;
1156e01fd687SAlex Williamson 
1157e01fd687SAlex Williamson     if (!pci_dev->has_vga) {
1158e01fd687SAlex Williamson         return;
1159e01fd687SAlex Williamson     }
1160e01fd687SAlex Williamson 
1161e01fd687SAlex Williamson     cmd = pci_get_word(pci_dev->config + PCI_COMMAND);
1162e01fd687SAlex Williamson 
1163e01fd687SAlex Williamson     memory_region_set_enabled(pci_dev->vga_regions[QEMU_PCI_VGA_MEM],
1164e01fd687SAlex Williamson                               cmd & PCI_COMMAND_MEMORY);
1165e01fd687SAlex Williamson     memory_region_set_enabled(pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO],
1166e01fd687SAlex Williamson                               cmd & PCI_COMMAND_IO);
1167e01fd687SAlex Williamson     memory_region_set_enabled(pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI],
1168e01fd687SAlex Williamson                               cmd & PCI_COMMAND_IO);
1169e01fd687SAlex Williamson }
1170e01fd687SAlex Williamson 
1171e01fd687SAlex Williamson void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
1172e01fd687SAlex Williamson                       MemoryRegion *io_lo, MemoryRegion *io_hi)
1173e01fd687SAlex Williamson {
1174fd56e061SDavid Gibson     PCIBus *bus = pci_get_bus(pci_dev);
1175fd56e061SDavid Gibson 
1176e01fd687SAlex Williamson     assert(!pci_dev->has_vga);
1177e01fd687SAlex Williamson 
1178e01fd687SAlex Williamson     assert(memory_region_size(mem) == QEMU_PCI_VGA_MEM_SIZE);
1179e01fd687SAlex Williamson     pci_dev->vga_regions[QEMU_PCI_VGA_MEM] = mem;
1180fd56e061SDavid Gibson     memory_region_add_subregion_overlap(bus->address_space_mem,
1181e01fd687SAlex Williamson                                         QEMU_PCI_VGA_MEM_BASE, mem, 1);
1182e01fd687SAlex Williamson 
1183e01fd687SAlex Williamson     assert(memory_region_size(io_lo) == QEMU_PCI_VGA_IO_LO_SIZE);
1184e01fd687SAlex Williamson     pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO] = io_lo;
1185fd56e061SDavid Gibson     memory_region_add_subregion_overlap(bus->address_space_io,
1186e01fd687SAlex Williamson                                         QEMU_PCI_VGA_IO_LO_BASE, io_lo, 1);
1187e01fd687SAlex Williamson 
1188e01fd687SAlex Williamson     assert(memory_region_size(io_hi) == QEMU_PCI_VGA_IO_HI_SIZE);
1189e01fd687SAlex Williamson     pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI] = io_hi;
1190fd56e061SDavid Gibson     memory_region_add_subregion_overlap(bus->address_space_io,
1191e01fd687SAlex Williamson                                         QEMU_PCI_VGA_IO_HI_BASE, io_hi, 1);
1192e01fd687SAlex Williamson     pci_dev->has_vga = true;
1193e01fd687SAlex Williamson 
1194e01fd687SAlex Williamson     pci_update_vga(pci_dev);
1195e01fd687SAlex Williamson }
1196e01fd687SAlex Williamson 
1197e01fd687SAlex Williamson void pci_unregister_vga(PCIDevice *pci_dev)
1198e01fd687SAlex Williamson {
1199fd56e061SDavid Gibson     PCIBus *bus = pci_get_bus(pci_dev);
1200fd56e061SDavid Gibson 
1201e01fd687SAlex Williamson     if (!pci_dev->has_vga) {
1202e01fd687SAlex Williamson         return;
1203e01fd687SAlex Williamson     }
1204e01fd687SAlex Williamson 
1205fd56e061SDavid Gibson     memory_region_del_subregion(bus->address_space_mem,
1206e01fd687SAlex Williamson                                 pci_dev->vga_regions[QEMU_PCI_VGA_MEM]);
1207fd56e061SDavid Gibson     memory_region_del_subregion(bus->address_space_io,
1208e01fd687SAlex Williamson                                 pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO]);
1209fd56e061SDavid Gibson     memory_region_del_subregion(bus->address_space_io,
1210e01fd687SAlex Williamson                                 pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI]);
1211e01fd687SAlex Williamson     pci_dev->has_vga = false;
1212e01fd687SAlex Williamson }
1213e01fd687SAlex Williamson 
1214315a1350SMichael S. Tsirkin pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
1215315a1350SMichael S. Tsirkin {
1216315a1350SMichael S. Tsirkin     return pci_dev->io_regions[region_num].addr;
1217315a1350SMichael S. Tsirkin }
1218315a1350SMichael S. Tsirkin 
1219315a1350SMichael S. Tsirkin static pcibus_t pci_bar_address(PCIDevice *d,
1220315a1350SMichael S. Tsirkin 				int reg, uint8_t type, pcibus_t size)
1221315a1350SMichael S. Tsirkin {
1222315a1350SMichael S. Tsirkin     pcibus_t new_addr, last_addr;
1223315a1350SMichael S. Tsirkin     int bar = pci_bar(d, reg);
1224315a1350SMichael S. Tsirkin     uint16_t cmd = pci_get_word(d->config + PCI_COMMAND);
1225e4024630SLaurent Vivier     Object *machine = qdev_get_machine();
1226e4024630SLaurent Vivier     ObjectClass *oc = object_get_class(machine);
1227e4024630SLaurent Vivier     MachineClass *mc = MACHINE_CLASS(oc);
1228e4024630SLaurent Vivier     bool allow_0_address = mc->pci_allow_0_address;
1229315a1350SMichael S. Tsirkin 
1230315a1350SMichael S. Tsirkin     if (type & PCI_BASE_ADDRESS_SPACE_IO) {
1231315a1350SMichael S. Tsirkin         if (!(cmd & PCI_COMMAND_IO)) {
1232315a1350SMichael S. Tsirkin             return PCI_BAR_UNMAPPED;
1233315a1350SMichael S. Tsirkin         }
1234315a1350SMichael S. Tsirkin         new_addr = pci_get_long(d->config + bar) & ~(size - 1);
1235315a1350SMichael S. Tsirkin         last_addr = new_addr + size - 1;
12369f1a029aSHervé Poussineau         /* Check if 32 bit BAR wraps around explicitly.
12379f1a029aSHervé Poussineau          * TODO: make priorities correct and remove this work around.
12389f1a029aSHervé Poussineau          */
1239e4024630SLaurent Vivier         if (last_addr <= new_addr || last_addr >= UINT32_MAX ||
1240e4024630SLaurent Vivier             (!allow_0_address && new_addr == 0)) {
1241315a1350SMichael S. Tsirkin             return PCI_BAR_UNMAPPED;
1242315a1350SMichael S. Tsirkin         }
1243315a1350SMichael S. Tsirkin         return new_addr;
1244315a1350SMichael S. Tsirkin     }
1245315a1350SMichael S. Tsirkin 
1246315a1350SMichael S. Tsirkin     if (!(cmd & PCI_COMMAND_MEMORY)) {
1247315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
1248315a1350SMichael S. Tsirkin     }
1249315a1350SMichael S. Tsirkin     if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
1250315a1350SMichael S. Tsirkin         new_addr = pci_get_quad(d->config + bar);
1251315a1350SMichael S. Tsirkin     } else {
1252315a1350SMichael S. Tsirkin         new_addr = pci_get_long(d->config + bar);
1253315a1350SMichael S. Tsirkin     }
1254315a1350SMichael S. Tsirkin     /* the ROM slot has a specific enable bit */
1255315a1350SMichael S. Tsirkin     if (reg == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE)) {
1256315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
1257315a1350SMichael S. Tsirkin     }
1258315a1350SMichael S. Tsirkin     new_addr &= ~(size - 1);
1259315a1350SMichael S. Tsirkin     last_addr = new_addr + size - 1;
1260315a1350SMichael S. Tsirkin     /* NOTE: we do not support wrapping */
1261315a1350SMichael S. Tsirkin     /* XXX: as we cannot support really dynamic
1262315a1350SMichael S. Tsirkin        mappings, we handle specific values as invalid
1263315a1350SMichael S. Tsirkin        mappings. */
1264e4024630SLaurent Vivier     if (last_addr <= new_addr || last_addr == PCI_BAR_UNMAPPED ||
1265e4024630SLaurent Vivier         (!allow_0_address && new_addr == 0)) {
1266315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
1267315a1350SMichael S. Tsirkin     }
1268315a1350SMichael S. Tsirkin 
1269315a1350SMichael S. Tsirkin     /* Now pcibus_t is 64bit.
1270315a1350SMichael S. Tsirkin      * Check if 32 bit BAR wraps around explicitly.
1271315a1350SMichael S. Tsirkin      * Without this, PC ide doesn't work well.
1272315a1350SMichael S. Tsirkin      * TODO: remove this work around.
1273315a1350SMichael S. Tsirkin      */
1274315a1350SMichael S. Tsirkin     if  (!(type & PCI_BASE_ADDRESS_MEM_TYPE_64) && last_addr >= UINT32_MAX) {
1275315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
1276315a1350SMichael S. Tsirkin     }
1277315a1350SMichael S. Tsirkin 
1278315a1350SMichael S. Tsirkin     /*
1279315a1350SMichael S. Tsirkin      * OS is allowed to set BAR beyond its addressable
1280315a1350SMichael S. Tsirkin      * bits. For example, 32 bit OS can set 64bit bar
1281315a1350SMichael S. Tsirkin      * to >4G. Check it. TODO: we might need to support
1282315a1350SMichael S. Tsirkin      * it in the future for e.g. PAE.
1283315a1350SMichael S. Tsirkin      */
1284315a1350SMichael S. Tsirkin     if (last_addr >= HWADDR_MAX) {
1285315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
1286315a1350SMichael S. Tsirkin     }
1287315a1350SMichael S. Tsirkin 
1288315a1350SMichael S. Tsirkin     return new_addr;
1289315a1350SMichael S. Tsirkin }
1290315a1350SMichael S. Tsirkin 
1291315a1350SMichael S. Tsirkin static void pci_update_mappings(PCIDevice *d)
1292315a1350SMichael S. Tsirkin {
1293315a1350SMichael S. Tsirkin     PCIIORegion *r;
1294315a1350SMichael S. Tsirkin     int i;
1295315a1350SMichael S. Tsirkin     pcibus_t new_addr;
1296315a1350SMichael S. Tsirkin 
1297315a1350SMichael S. Tsirkin     for(i = 0; i < PCI_NUM_REGIONS; i++) {
1298315a1350SMichael S. Tsirkin         r = &d->io_regions[i];
1299315a1350SMichael S. Tsirkin 
1300315a1350SMichael S. Tsirkin         /* this region isn't registered */
1301315a1350SMichael S. Tsirkin         if (!r->size)
1302315a1350SMichael S. Tsirkin             continue;
1303315a1350SMichael S. Tsirkin 
1304315a1350SMichael S. Tsirkin         new_addr = pci_bar_address(d, i, r->type, r->size);
1305315a1350SMichael S. Tsirkin 
1306315a1350SMichael S. Tsirkin         /* This bar isn't changed */
1307315a1350SMichael S. Tsirkin         if (new_addr == r->addr)
1308315a1350SMichael S. Tsirkin             continue;
1309315a1350SMichael S. Tsirkin 
1310315a1350SMichael S. Tsirkin         /* now do the real mapping */
1311315a1350SMichael S. Tsirkin         if (r->addr != PCI_BAR_UNMAPPED) {
1312fd56e061SDavid Gibson             trace_pci_update_mappings_del(d, pci_dev_bus_num(d),
13137828d750SDon Koch                                           PCI_SLOT(d->devfn),
13140f288f85SLaszlo Ersek                                           PCI_FUNC(d->devfn),
13157828d750SDon Koch                                           i, r->addr, r->size);
1316315a1350SMichael S. Tsirkin             memory_region_del_subregion(r->address_space, r->memory);
1317315a1350SMichael S. Tsirkin         }
1318315a1350SMichael S. Tsirkin         r->addr = new_addr;
1319315a1350SMichael S. Tsirkin         if (r->addr != PCI_BAR_UNMAPPED) {
1320fd56e061SDavid Gibson             trace_pci_update_mappings_add(d, pci_dev_bus_num(d),
13217828d750SDon Koch                                           PCI_SLOT(d->devfn),
13220f288f85SLaszlo Ersek                                           PCI_FUNC(d->devfn),
13237828d750SDon Koch                                           i, r->addr, r->size);
1324315a1350SMichael S. Tsirkin             memory_region_add_subregion_overlap(r->address_space,
1325315a1350SMichael S. Tsirkin                                                 r->addr, r->memory, 1);
1326315a1350SMichael S. Tsirkin         }
1327315a1350SMichael S. Tsirkin     }
1328e01fd687SAlex Williamson 
1329e01fd687SAlex Williamson     pci_update_vga(d);
1330315a1350SMichael S. Tsirkin }
1331315a1350SMichael S. Tsirkin 
1332315a1350SMichael S. Tsirkin static inline int pci_irq_disabled(PCIDevice *d)
1333315a1350SMichael S. Tsirkin {
1334315a1350SMichael S. Tsirkin     return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE;
1335315a1350SMichael S. Tsirkin }
1336315a1350SMichael S. Tsirkin 
1337315a1350SMichael S. Tsirkin /* Called after interrupt disabled field update in config space,
1338315a1350SMichael S. Tsirkin  * assert/deassert interrupts if necessary.
1339315a1350SMichael S. Tsirkin  * Gets original interrupt disable bit value (before update). */
1340315a1350SMichael S. Tsirkin static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled)
1341315a1350SMichael S. Tsirkin {
1342315a1350SMichael S. Tsirkin     int i, disabled = pci_irq_disabled(d);
1343315a1350SMichael S. Tsirkin     if (disabled == was_irq_disabled)
1344315a1350SMichael S. Tsirkin         return;
1345315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
1346315a1350SMichael S. Tsirkin         int state = pci_irq_state(d, i);
1347315a1350SMichael S. Tsirkin         pci_change_irq_level(d, i, disabled ? -state : state);
1348315a1350SMichael S. Tsirkin     }
1349315a1350SMichael S. Tsirkin }
1350315a1350SMichael S. Tsirkin 
1351315a1350SMichael S. Tsirkin uint32_t pci_default_read_config(PCIDevice *d,
1352315a1350SMichael S. Tsirkin                                  uint32_t address, int len)
1353315a1350SMichael S. Tsirkin {
1354315a1350SMichael S. Tsirkin     uint32_t val = 0;
1355315a1350SMichael S. Tsirkin 
1356315a1350SMichael S. Tsirkin     memcpy(&val, d->config + address, len);
1357315a1350SMichael S. Tsirkin     return le32_to_cpu(val);
1358315a1350SMichael S. Tsirkin }
1359315a1350SMichael S. Tsirkin 
1360d7efb7e0SKnut Omang void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int l)
1361315a1350SMichael S. Tsirkin {
1362315a1350SMichael S. Tsirkin     int i, was_irq_disabled = pci_irq_disabled(d);
1363d7efb7e0SKnut Omang     uint32_t val = val_in;
1364315a1350SMichael S. Tsirkin 
1365315a1350SMichael S. Tsirkin     for (i = 0; i < l; val >>= 8, ++i) {
1366315a1350SMichael S. Tsirkin         uint8_t wmask = d->wmask[addr + i];
1367315a1350SMichael S. Tsirkin         uint8_t w1cmask = d->w1cmask[addr + i];
1368315a1350SMichael S. Tsirkin         assert(!(wmask & w1cmask));
1369315a1350SMichael S. Tsirkin         d->config[addr + i] = (d->config[addr + i] & ~wmask) | (val & wmask);
1370315a1350SMichael S. Tsirkin         d->config[addr + i] &= ~(val & w1cmask); /* W1C: Write 1 to Clear */
1371315a1350SMichael S. Tsirkin     }
1372315a1350SMichael S. Tsirkin     if (ranges_overlap(addr, l, PCI_BASE_ADDRESS_0, 24) ||
1373315a1350SMichael S. Tsirkin         ranges_overlap(addr, l, PCI_ROM_ADDRESS, 4) ||
1374315a1350SMichael S. Tsirkin         ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) ||
1375315a1350SMichael S. Tsirkin         range_covers_byte(addr, l, PCI_COMMAND))
1376315a1350SMichael S. Tsirkin         pci_update_mappings(d);
1377315a1350SMichael S. Tsirkin 
1378315a1350SMichael S. Tsirkin     if (range_covers_byte(addr, l, PCI_COMMAND)) {
1379315a1350SMichael S. Tsirkin         pci_update_irq_disabled(d, was_irq_disabled);
1380315a1350SMichael S. Tsirkin         memory_region_set_enabled(&d->bus_master_enable_region,
1381315a1350SMichael S. Tsirkin                                   pci_get_word(d->config + PCI_COMMAND)
1382315a1350SMichael S. Tsirkin                                     & PCI_COMMAND_MASTER);
1383315a1350SMichael S. Tsirkin     }
1384315a1350SMichael S. Tsirkin 
1385d7efb7e0SKnut Omang     msi_write_config(d, addr, val_in, l);
1386d7efb7e0SKnut Omang     msix_write_config(d, addr, val_in, l);
1387315a1350SMichael S. Tsirkin }
1388315a1350SMichael S. Tsirkin 
1389315a1350SMichael S. Tsirkin /***********************************************************/
1390315a1350SMichael S. Tsirkin /* generic PCI irq support */
1391315a1350SMichael S. Tsirkin 
1392315a1350SMichael S. Tsirkin /* 0 <= irq_num <= 3. level must be 0 or 1 */
1393d98f08f5SMarcel Apfelbaum static void pci_irq_handler(void *opaque, int irq_num, int level)
1394315a1350SMichael S. Tsirkin {
1395315a1350SMichael S. Tsirkin     PCIDevice *pci_dev = opaque;
1396315a1350SMichael S. Tsirkin     int change;
1397315a1350SMichael S. Tsirkin 
1398315a1350SMichael S. Tsirkin     change = level - pci_irq_state(pci_dev, irq_num);
1399315a1350SMichael S. Tsirkin     if (!change)
1400315a1350SMichael S. Tsirkin         return;
1401315a1350SMichael S. Tsirkin 
1402315a1350SMichael S. Tsirkin     pci_set_irq_state(pci_dev, irq_num, level);
1403315a1350SMichael S. Tsirkin     pci_update_irq_status(pci_dev);
1404315a1350SMichael S. Tsirkin     if (pci_irq_disabled(pci_dev))
1405315a1350SMichael S. Tsirkin         return;
1406315a1350SMichael S. Tsirkin     pci_change_irq_level(pci_dev, irq_num, change);
1407315a1350SMichael S. Tsirkin }
1408315a1350SMichael S. Tsirkin 
1409d98f08f5SMarcel Apfelbaum static inline int pci_intx(PCIDevice *pci_dev)
1410d98f08f5SMarcel Apfelbaum {
1411d98f08f5SMarcel Apfelbaum     return pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;
1412d98f08f5SMarcel Apfelbaum }
1413d98f08f5SMarcel Apfelbaum 
1414d98f08f5SMarcel Apfelbaum qemu_irq pci_allocate_irq(PCIDevice *pci_dev)
1415d98f08f5SMarcel Apfelbaum {
1416d98f08f5SMarcel Apfelbaum     int intx = pci_intx(pci_dev);
1417d98f08f5SMarcel Apfelbaum 
1418d98f08f5SMarcel Apfelbaum     return qemu_allocate_irq(pci_irq_handler, pci_dev, intx);
1419d98f08f5SMarcel Apfelbaum }
1420d98f08f5SMarcel Apfelbaum 
1421d98f08f5SMarcel Apfelbaum void pci_set_irq(PCIDevice *pci_dev, int level)
1422d98f08f5SMarcel Apfelbaum {
1423d98f08f5SMarcel Apfelbaum     int intx = pci_intx(pci_dev);
1424d98f08f5SMarcel Apfelbaum     pci_irq_handler(pci_dev, intx, level);
1425d98f08f5SMarcel Apfelbaum }
1426d98f08f5SMarcel Apfelbaum 
1427315a1350SMichael S. Tsirkin /* Special hooks used by device assignment */
1428315a1350SMichael S. Tsirkin void pci_bus_set_route_irq_fn(PCIBus *bus, pci_route_irq_fn route_intx_to_irq)
1429315a1350SMichael S. Tsirkin {
14300889464aSAlex Williamson     assert(pci_bus_is_root(bus));
1431315a1350SMichael S. Tsirkin     bus->route_intx_to_irq = route_intx_to_irq;
1432315a1350SMichael S. Tsirkin }
1433315a1350SMichael S. Tsirkin 
1434315a1350SMichael S. Tsirkin PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
1435315a1350SMichael S. Tsirkin {
1436315a1350SMichael S. Tsirkin     PCIBus *bus;
1437315a1350SMichael S. Tsirkin 
1438315a1350SMichael S. Tsirkin     do {
1439fd56e061SDavid Gibson         bus = pci_get_bus(dev);
1440315a1350SMichael S. Tsirkin         pin = bus->map_irq(dev, pin);
1441315a1350SMichael S. Tsirkin         dev = bus->parent_dev;
1442315a1350SMichael S. Tsirkin     } while (dev);
1443315a1350SMichael S. Tsirkin 
1444315a1350SMichael S. Tsirkin     if (!bus->route_intx_to_irq) {
1445312fd5f2SMarkus Armbruster         error_report("PCI: Bug - unimplemented PCI INTx routing (%s)",
1446315a1350SMichael S. Tsirkin                      object_get_typename(OBJECT(bus->qbus.parent)));
1447315a1350SMichael S. Tsirkin         return (PCIINTxRoute) { PCI_INTX_DISABLED, -1 };
1448315a1350SMichael S. Tsirkin     }
1449315a1350SMichael S. Tsirkin 
1450315a1350SMichael S. Tsirkin     return bus->route_intx_to_irq(bus->irq_opaque, pin);
1451315a1350SMichael S. Tsirkin }
1452315a1350SMichael S. Tsirkin 
1453315a1350SMichael S. Tsirkin bool pci_intx_route_changed(PCIINTxRoute *old, PCIINTxRoute *new)
1454315a1350SMichael S. Tsirkin {
1455315a1350SMichael S. Tsirkin     return old->mode != new->mode || old->irq != new->irq;
1456315a1350SMichael S. Tsirkin }
1457315a1350SMichael S. Tsirkin 
1458315a1350SMichael S. Tsirkin void pci_bus_fire_intx_routing_notifier(PCIBus *bus)
1459315a1350SMichael S. Tsirkin {
1460315a1350SMichael S. Tsirkin     PCIDevice *dev;
1461315a1350SMichael S. Tsirkin     PCIBus *sec;
1462315a1350SMichael S. Tsirkin     int i;
1463315a1350SMichael S. Tsirkin 
1464315a1350SMichael S. Tsirkin     for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
1465315a1350SMichael S. Tsirkin         dev = bus->devices[i];
1466315a1350SMichael S. Tsirkin         if (dev && dev->intx_routing_notifier) {
1467315a1350SMichael S. Tsirkin             dev->intx_routing_notifier(dev);
1468315a1350SMichael S. Tsirkin         }
1469e5368f0dSAlex Williamson     }
1470e5368f0dSAlex Williamson 
1471315a1350SMichael S. Tsirkin     QLIST_FOREACH(sec, &bus->child, sibling) {
1472315a1350SMichael S. Tsirkin         pci_bus_fire_intx_routing_notifier(sec);
1473315a1350SMichael S. Tsirkin     }
1474315a1350SMichael S. Tsirkin }
1475315a1350SMichael S. Tsirkin 
1476315a1350SMichael S. Tsirkin void pci_device_set_intx_routing_notifier(PCIDevice *dev,
1477315a1350SMichael S. Tsirkin                                           PCIINTxRoutingNotifier notifier)
1478315a1350SMichael S. Tsirkin {
1479315a1350SMichael S. Tsirkin     dev->intx_routing_notifier = notifier;
1480315a1350SMichael S. Tsirkin }
1481315a1350SMichael S. Tsirkin 
1482315a1350SMichael S. Tsirkin /*
1483315a1350SMichael S. Tsirkin  * PCI-to-PCI bridge specification
1484315a1350SMichael S. Tsirkin  * 9.1: Interrupt routing. Table 9-1
1485315a1350SMichael S. Tsirkin  *
1486315a1350SMichael S. Tsirkin  * the PCI Express Base Specification, Revision 2.1
1487315a1350SMichael S. Tsirkin  * 2.2.8.1: INTx interrutp signaling - Rules
1488315a1350SMichael S. Tsirkin  *          the Implementation Note
1489315a1350SMichael S. Tsirkin  *          Table 2-20
1490315a1350SMichael S. Tsirkin  */
1491315a1350SMichael S. Tsirkin /*
1492315a1350SMichael S. Tsirkin  * 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD
1493315a1350SMichael S. Tsirkin  * 0-origin unlike PCI interrupt pin register.
1494315a1350SMichael S. Tsirkin  */
1495315a1350SMichael S. Tsirkin int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin)
1496315a1350SMichael S. Tsirkin {
1497315a1350SMichael S. Tsirkin     return (pin + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS;
1498315a1350SMichael S. Tsirkin }
1499315a1350SMichael S. Tsirkin 
1500315a1350SMichael S. Tsirkin /***********************************************************/
1501315a1350SMichael S. Tsirkin /* monitor info on PCI */
1502315a1350SMichael S. Tsirkin 
1503315a1350SMichael S. Tsirkin typedef struct {
1504315a1350SMichael S. Tsirkin     uint16_t class;
1505315a1350SMichael S. Tsirkin     const char *desc;
1506315a1350SMichael S. Tsirkin     const char *fw_name;
1507315a1350SMichael S. Tsirkin     uint16_t fw_ign_bits;
1508315a1350SMichael S. Tsirkin } pci_class_desc;
1509315a1350SMichael S. Tsirkin 
1510315a1350SMichael S. Tsirkin static const pci_class_desc pci_class_descriptions[] =
1511315a1350SMichael S. Tsirkin {
1512315a1350SMichael S. Tsirkin     { 0x0001, "VGA controller", "display"},
1513315a1350SMichael S. Tsirkin     { 0x0100, "SCSI controller", "scsi"},
1514315a1350SMichael S. Tsirkin     { 0x0101, "IDE controller", "ide"},
1515315a1350SMichael S. Tsirkin     { 0x0102, "Floppy controller", "fdc"},
1516315a1350SMichael S. Tsirkin     { 0x0103, "IPI controller", "ipi"},
1517315a1350SMichael S. Tsirkin     { 0x0104, "RAID controller", "raid"},
1518315a1350SMichael S. Tsirkin     { 0x0106, "SATA controller"},
1519315a1350SMichael S. Tsirkin     { 0x0107, "SAS controller"},
1520315a1350SMichael S. Tsirkin     { 0x0180, "Storage controller"},
1521315a1350SMichael S. Tsirkin     { 0x0200, "Ethernet controller", "ethernet"},
1522315a1350SMichael S. Tsirkin     { 0x0201, "Token Ring controller", "token-ring"},
1523315a1350SMichael S. Tsirkin     { 0x0202, "FDDI controller", "fddi"},
1524315a1350SMichael S. Tsirkin     { 0x0203, "ATM controller", "atm"},
1525315a1350SMichael S. Tsirkin     { 0x0280, "Network controller"},
1526315a1350SMichael S. Tsirkin     { 0x0300, "VGA controller", "display", 0x00ff},
1527315a1350SMichael S. Tsirkin     { 0x0301, "XGA controller"},
1528315a1350SMichael S. Tsirkin     { 0x0302, "3D controller"},
1529315a1350SMichael S. Tsirkin     { 0x0380, "Display controller"},
1530315a1350SMichael S. Tsirkin     { 0x0400, "Video controller", "video"},
1531315a1350SMichael S. Tsirkin     { 0x0401, "Audio controller", "sound"},
1532315a1350SMichael S. Tsirkin     { 0x0402, "Phone"},
1533315a1350SMichael S. Tsirkin     { 0x0403, "Audio controller", "sound"},
1534315a1350SMichael S. Tsirkin     { 0x0480, "Multimedia controller"},
1535315a1350SMichael S. Tsirkin     { 0x0500, "RAM controller", "memory"},
1536315a1350SMichael S. Tsirkin     { 0x0501, "Flash controller", "flash"},
1537315a1350SMichael S. Tsirkin     { 0x0580, "Memory controller"},
1538315a1350SMichael S. Tsirkin     { 0x0600, "Host bridge", "host"},
1539315a1350SMichael S. Tsirkin     { 0x0601, "ISA bridge", "isa"},
1540315a1350SMichael S. Tsirkin     { 0x0602, "EISA bridge", "eisa"},
1541315a1350SMichael S. Tsirkin     { 0x0603, "MC bridge", "mca"},
15424c41425dSGerd Hoffmann     { 0x0604, "PCI bridge", "pci-bridge"},
1543315a1350SMichael S. Tsirkin     { 0x0605, "PCMCIA bridge", "pcmcia"},
1544315a1350SMichael S. Tsirkin     { 0x0606, "NUBUS bridge", "nubus"},
1545315a1350SMichael S. Tsirkin     { 0x0607, "CARDBUS bridge", "cardbus"},
1546315a1350SMichael S. Tsirkin     { 0x0608, "RACEWAY bridge"},
1547315a1350SMichael S. Tsirkin     { 0x0680, "Bridge"},
1548315a1350SMichael S. Tsirkin     { 0x0700, "Serial port", "serial"},
1549315a1350SMichael S. Tsirkin     { 0x0701, "Parallel port", "parallel"},
1550315a1350SMichael S. Tsirkin     { 0x0800, "Interrupt controller", "interrupt-controller"},
1551315a1350SMichael S. Tsirkin     { 0x0801, "DMA controller", "dma-controller"},
1552315a1350SMichael S. Tsirkin     { 0x0802, "Timer", "timer"},
1553315a1350SMichael S. Tsirkin     { 0x0803, "RTC", "rtc"},
1554315a1350SMichael S. Tsirkin     { 0x0900, "Keyboard", "keyboard"},
1555315a1350SMichael S. Tsirkin     { 0x0901, "Pen", "pen"},
1556315a1350SMichael S. Tsirkin     { 0x0902, "Mouse", "mouse"},
1557315a1350SMichael S. Tsirkin     { 0x0A00, "Dock station", "dock", 0x00ff},
1558315a1350SMichael S. Tsirkin     { 0x0B00, "i386 cpu", "cpu", 0x00ff},
1559315a1350SMichael S. Tsirkin     { 0x0c00, "Fireware contorller", "fireware"},
1560315a1350SMichael S. Tsirkin     { 0x0c01, "Access bus controller", "access-bus"},
1561315a1350SMichael S. Tsirkin     { 0x0c02, "SSA controller", "ssa"},
1562315a1350SMichael S. Tsirkin     { 0x0c03, "USB controller", "usb"},
1563315a1350SMichael S. Tsirkin     { 0x0c04, "Fibre channel controller", "fibre-channel"},
1564315a1350SMichael S. Tsirkin     { 0x0c05, "SMBus"},
1565315a1350SMichael S. Tsirkin     { 0, NULL}
1566315a1350SMichael S. Tsirkin };
1567315a1350SMichael S. Tsirkin 
1568a8eeafdaSGreg Kurz static void pci_for_each_device_under_bus_reverse(PCIBus *bus,
1569a8eeafdaSGreg Kurz                                                   void (*fn)(PCIBus *b,
1570a8eeafdaSGreg Kurz                                                              PCIDevice *d,
1571a8eeafdaSGreg Kurz                                                              void *opaque),
1572a8eeafdaSGreg Kurz                                                   void *opaque)
1573a8eeafdaSGreg Kurz {
1574a8eeafdaSGreg Kurz     PCIDevice *d;
1575a8eeafdaSGreg Kurz     int devfn;
1576a8eeafdaSGreg Kurz 
1577a8eeafdaSGreg Kurz     for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
1578a8eeafdaSGreg Kurz         d = bus->devices[ARRAY_SIZE(bus->devices) - 1 - devfn];
1579a8eeafdaSGreg Kurz         if (d) {
1580a8eeafdaSGreg Kurz             fn(bus, d, opaque);
1581a8eeafdaSGreg Kurz         }
1582a8eeafdaSGreg Kurz     }
1583a8eeafdaSGreg Kurz }
1584a8eeafdaSGreg Kurz 
1585a8eeafdaSGreg Kurz void pci_for_each_device_reverse(PCIBus *bus, int bus_num,
1586a8eeafdaSGreg Kurz                          void (*fn)(PCIBus *b, PCIDevice *d, void *opaque),
1587a8eeafdaSGreg Kurz                          void *opaque)
1588a8eeafdaSGreg Kurz {
1589a8eeafdaSGreg Kurz     bus = pci_find_bus_nr(bus, bus_num);
1590a8eeafdaSGreg Kurz 
1591a8eeafdaSGreg Kurz     if (bus) {
1592a8eeafdaSGreg Kurz         pci_for_each_device_under_bus_reverse(bus, fn, opaque);
1593a8eeafdaSGreg Kurz     }
1594a8eeafdaSGreg Kurz }
1595a8eeafdaSGreg Kurz 
1596315a1350SMichael S. Tsirkin static void pci_for_each_device_under_bus(PCIBus *bus,
1597315a1350SMichael S. Tsirkin                                           void (*fn)(PCIBus *b, PCIDevice *d,
1598315a1350SMichael S. Tsirkin                                                      void *opaque),
1599315a1350SMichael S. Tsirkin                                           void *opaque)
1600315a1350SMichael S. Tsirkin {
1601315a1350SMichael S. Tsirkin     PCIDevice *d;
1602315a1350SMichael S. Tsirkin     int devfn;
1603315a1350SMichael S. Tsirkin 
1604315a1350SMichael S. Tsirkin     for(devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
1605315a1350SMichael S. Tsirkin         d = bus->devices[devfn];
1606315a1350SMichael S. Tsirkin         if (d) {
1607315a1350SMichael S. Tsirkin             fn(bus, d, opaque);
1608315a1350SMichael S. Tsirkin         }
1609315a1350SMichael S. Tsirkin     }
1610315a1350SMichael S. Tsirkin }
1611315a1350SMichael S. Tsirkin 
1612315a1350SMichael S. Tsirkin void pci_for_each_device(PCIBus *bus, int bus_num,
1613315a1350SMichael S. Tsirkin                          void (*fn)(PCIBus *b, PCIDevice *d, void *opaque),
1614315a1350SMichael S. Tsirkin                          void *opaque)
1615315a1350SMichael S. Tsirkin {
1616315a1350SMichael S. Tsirkin     bus = pci_find_bus_nr(bus, bus_num);
1617315a1350SMichael S. Tsirkin 
1618315a1350SMichael S. Tsirkin     if (bus) {
1619315a1350SMichael S. Tsirkin         pci_for_each_device_under_bus(bus, fn, opaque);
1620315a1350SMichael S. Tsirkin     }
1621315a1350SMichael S. Tsirkin }
1622315a1350SMichael S. Tsirkin 
1623315a1350SMichael S. Tsirkin static const pci_class_desc *get_class_desc(int class)
1624315a1350SMichael S. Tsirkin {
1625315a1350SMichael S. Tsirkin     const pci_class_desc *desc;
1626315a1350SMichael S. Tsirkin 
1627315a1350SMichael S. Tsirkin     desc = pci_class_descriptions;
1628315a1350SMichael S. Tsirkin     while (desc->desc && class != desc->class) {
1629315a1350SMichael S. Tsirkin         desc++;
1630315a1350SMichael S. Tsirkin     }
1631315a1350SMichael S. Tsirkin 
1632315a1350SMichael S. Tsirkin     return desc;
1633315a1350SMichael S. Tsirkin }
1634315a1350SMichael S. Tsirkin 
1635315a1350SMichael S. Tsirkin static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
1636315a1350SMichael S. Tsirkin 
1637315a1350SMichael S. Tsirkin static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev)
1638315a1350SMichael S. Tsirkin {
1639315a1350SMichael S. Tsirkin     PciMemoryRegionList *head = NULL, *cur_item = NULL;
1640315a1350SMichael S. Tsirkin     int i;
1641315a1350SMichael S. Tsirkin 
1642315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_REGIONS; i++) {
1643315a1350SMichael S. Tsirkin         const PCIIORegion *r = &dev->io_regions[i];
1644315a1350SMichael S. Tsirkin         PciMemoryRegionList *region;
1645315a1350SMichael S. Tsirkin 
1646315a1350SMichael S. Tsirkin         if (!r->size) {
1647315a1350SMichael S. Tsirkin             continue;
1648315a1350SMichael S. Tsirkin         }
1649315a1350SMichael S. Tsirkin 
1650315a1350SMichael S. Tsirkin         region = g_malloc0(sizeof(*region));
1651315a1350SMichael S. Tsirkin         region->value = g_malloc0(sizeof(*region->value));
1652315a1350SMichael S. Tsirkin 
1653315a1350SMichael S. Tsirkin         if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
1654315a1350SMichael S. Tsirkin             region->value->type = g_strdup("io");
1655315a1350SMichael S. Tsirkin         } else {
1656315a1350SMichael S. Tsirkin             region->value->type = g_strdup("memory");
1657315a1350SMichael S. Tsirkin             region->value->has_prefetch = true;
1658315a1350SMichael S. Tsirkin             region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH);
1659315a1350SMichael S. Tsirkin             region->value->has_mem_type_64 = true;
1660315a1350SMichael S. Tsirkin             region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64);
1661315a1350SMichael S. Tsirkin         }
1662315a1350SMichael S. Tsirkin 
1663315a1350SMichael S. Tsirkin         region->value->bar = i;
1664315a1350SMichael S. Tsirkin         region->value->address = r->addr;
1665315a1350SMichael S. Tsirkin         region->value->size = r->size;
1666315a1350SMichael S. Tsirkin 
1667315a1350SMichael S. Tsirkin         /* XXX: waiting for the qapi to support GSList */
1668315a1350SMichael S. Tsirkin         if (!cur_item) {
1669315a1350SMichael S. Tsirkin             head = cur_item = region;
1670315a1350SMichael S. Tsirkin         } else {
1671315a1350SMichael S. Tsirkin             cur_item->next = region;
1672315a1350SMichael S. Tsirkin             cur_item = region;
1673315a1350SMichael S. Tsirkin         }
1674315a1350SMichael S. Tsirkin     }
1675315a1350SMichael S. Tsirkin 
1676315a1350SMichael S. Tsirkin     return head;
1677315a1350SMichael S. Tsirkin }
1678315a1350SMichael S. Tsirkin 
1679315a1350SMichael S. Tsirkin static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus,
1680315a1350SMichael S. Tsirkin                                            int bus_num)
1681315a1350SMichael S. Tsirkin {
1682315a1350SMichael S. Tsirkin     PciBridgeInfo *info;
16839fa02cd1SEric Blake     PciMemoryRange *range;
1684315a1350SMichael S. Tsirkin 
16859fa02cd1SEric Blake     info = g_new0(PciBridgeInfo, 1);
1686315a1350SMichael S. Tsirkin 
16879fa02cd1SEric Blake     info->bus = g_new0(PciBusInfo, 1);
16889fa02cd1SEric Blake     info->bus->number = dev->config[PCI_PRIMARY_BUS];
16899fa02cd1SEric Blake     info->bus->secondary = dev->config[PCI_SECONDARY_BUS];
16909fa02cd1SEric Blake     info->bus->subordinate = dev->config[PCI_SUBORDINATE_BUS];
1691315a1350SMichael S. Tsirkin 
16929fa02cd1SEric Blake     range = info->bus->io_range = g_new0(PciMemoryRange, 1);
16939fa02cd1SEric Blake     range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
16949fa02cd1SEric Blake     range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
1695315a1350SMichael S. Tsirkin 
16969fa02cd1SEric Blake     range = info->bus->memory_range = g_new0(PciMemoryRange, 1);
16979fa02cd1SEric Blake     range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
16989fa02cd1SEric Blake     range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
1699315a1350SMichael S. Tsirkin 
17009fa02cd1SEric Blake     range = info->bus->prefetchable_range = g_new0(PciMemoryRange, 1);
17019fa02cd1SEric Blake     range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
17029fa02cd1SEric Blake     range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
1703315a1350SMichael S. Tsirkin 
1704315a1350SMichael S. Tsirkin     if (dev->config[PCI_SECONDARY_BUS] != 0) {
1705315a1350SMichael S. Tsirkin         PCIBus *child_bus = pci_find_bus_nr(bus, dev->config[PCI_SECONDARY_BUS]);
1706315a1350SMichael S. Tsirkin         if (child_bus) {
1707315a1350SMichael S. Tsirkin             info->has_devices = true;
1708315a1350SMichael S. Tsirkin             info->devices = qmp_query_pci_devices(child_bus, dev->config[PCI_SECONDARY_BUS]);
1709315a1350SMichael S. Tsirkin         }
1710315a1350SMichael S. Tsirkin     }
1711315a1350SMichael S. Tsirkin 
1712315a1350SMichael S. Tsirkin     return info;
1713315a1350SMichael S. Tsirkin }
1714315a1350SMichael S. Tsirkin 
1715315a1350SMichael S. Tsirkin static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
1716315a1350SMichael S. Tsirkin                                            int bus_num)
1717315a1350SMichael S. Tsirkin {
1718315a1350SMichael S. Tsirkin     const pci_class_desc *desc;
1719315a1350SMichael S. Tsirkin     PciDeviceInfo *info;
1720315a1350SMichael S. Tsirkin     uint8_t type;
1721315a1350SMichael S. Tsirkin     int class;
1722315a1350SMichael S. Tsirkin 
17239fa02cd1SEric Blake     info = g_new0(PciDeviceInfo, 1);
1724315a1350SMichael S. Tsirkin     info->bus = bus_num;
1725315a1350SMichael S. Tsirkin     info->slot = PCI_SLOT(dev->devfn);
1726315a1350SMichael S. Tsirkin     info->function = PCI_FUNC(dev->devfn);
1727315a1350SMichael S. Tsirkin 
17289fa02cd1SEric Blake     info->class_info = g_new0(PciDeviceClass, 1);
1729315a1350SMichael S. Tsirkin     class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
17309fa02cd1SEric Blake     info->class_info->q_class = class;
1731315a1350SMichael S. Tsirkin     desc = get_class_desc(class);
1732315a1350SMichael S. Tsirkin     if (desc->desc) {
17339fa02cd1SEric Blake         info->class_info->has_desc = true;
17349fa02cd1SEric Blake         info->class_info->desc = g_strdup(desc->desc);
1735315a1350SMichael S. Tsirkin     }
1736315a1350SMichael S. Tsirkin 
17379fa02cd1SEric Blake     info->id = g_new0(PciDeviceId, 1);
17389fa02cd1SEric Blake     info->id->vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
17399fa02cd1SEric Blake     info->id->device = pci_get_word(dev->config + PCI_DEVICE_ID);
1740315a1350SMichael S. Tsirkin     info->regions = qmp_query_pci_regions(dev);
1741315a1350SMichael S. Tsirkin     info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
1742315a1350SMichael S. Tsirkin 
1743315a1350SMichael S. Tsirkin     if (dev->config[PCI_INTERRUPT_PIN] != 0) {
1744315a1350SMichael S. Tsirkin         info->has_irq = true;
1745315a1350SMichael S. Tsirkin         info->irq = dev->config[PCI_INTERRUPT_LINE];
1746315a1350SMichael S. Tsirkin     }
1747315a1350SMichael S. Tsirkin 
1748315a1350SMichael S. Tsirkin     type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
1749315a1350SMichael S. Tsirkin     if (type == PCI_HEADER_TYPE_BRIDGE) {
1750315a1350SMichael S. Tsirkin         info->has_pci_bridge = true;
1751315a1350SMichael S. Tsirkin         info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
1752315a1350SMichael S. Tsirkin     }
1753315a1350SMichael S. Tsirkin 
1754315a1350SMichael S. Tsirkin     return info;
1755315a1350SMichael S. Tsirkin }
1756315a1350SMichael S. Tsirkin 
1757315a1350SMichael S. Tsirkin static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num)
1758315a1350SMichael S. Tsirkin {
1759315a1350SMichael S. Tsirkin     PciDeviceInfoList *info, *head = NULL, *cur_item = NULL;
1760315a1350SMichael S. Tsirkin     PCIDevice *dev;
1761315a1350SMichael S. Tsirkin     int devfn;
1762315a1350SMichael S. Tsirkin 
1763315a1350SMichael S. Tsirkin     for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
1764315a1350SMichael S. Tsirkin         dev = bus->devices[devfn];
1765315a1350SMichael S. Tsirkin         if (dev) {
1766315a1350SMichael S. Tsirkin             info = g_malloc0(sizeof(*info));
1767315a1350SMichael S. Tsirkin             info->value = qmp_query_pci_device(dev, bus, bus_num);
1768315a1350SMichael S. Tsirkin 
1769315a1350SMichael S. Tsirkin             /* XXX: waiting for the qapi to support GSList */
1770315a1350SMichael S. Tsirkin             if (!cur_item) {
1771315a1350SMichael S. Tsirkin                 head = cur_item = info;
1772315a1350SMichael S. Tsirkin             } else {
1773315a1350SMichael S. Tsirkin                 cur_item->next = info;
1774315a1350SMichael S. Tsirkin                 cur_item = info;
1775315a1350SMichael S. Tsirkin             }
1776315a1350SMichael S. Tsirkin         }
1777315a1350SMichael S. Tsirkin     }
1778315a1350SMichael S. Tsirkin 
1779315a1350SMichael S. Tsirkin     return head;
1780315a1350SMichael S. Tsirkin }
1781315a1350SMichael S. Tsirkin 
1782315a1350SMichael S. Tsirkin static PciInfo *qmp_query_pci_bus(PCIBus *bus, int bus_num)
1783315a1350SMichael S. Tsirkin {
1784315a1350SMichael S. Tsirkin     PciInfo *info = NULL;
1785315a1350SMichael S. Tsirkin 
1786315a1350SMichael S. Tsirkin     bus = pci_find_bus_nr(bus, bus_num);
1787315a1350SMichael S. Tsirkin     if (bus) {
1788315a1350SMichael S. Tsirkin         info = g_malloc0(sizeof(*info));
1789315a1350SMichael S. Tsirkin         info->bus = bus_num;
1790315a1350SMichael S. Tsirkin         info->devices = qmp_query_pci_devices(bus, bus_num);
1791315a1350SMichael S. Tsirkin     }
1792315a1350SMichael S. Tsirkin 
1793315a1350SMichael S. Tsirkin     return info;
1794315a1350SMichael S. Tsirkin }
1795315a1350SMichael S. Tsirkin 
1796315a1350SMichael S. Tsirkin PciInfoList *qmp_query_pci(Error **errp)
1797315a1350SMichael S. Tsirkin {
1798315a1350SMichael S. Tsirkin     PciInfoList *info, *head = NULL, *cur_item = NULL;
17997588e2b0SDavid Gibson     PCIHostState *host_bridge;
1800315a1350SMichael S. Tsirkin 
18017588e2b0SDavid Gibson     QLIST_FOREACH(host_bridge, &pci_host_bridges, next) {
1802315a1350SMichael S. Tsirkin         info = g_malloc0(sizeof(*info));
1803cb2ed8b3SMarcel Apfelbaum         info->value = qmp_query_pci_bus(host_bridge->bus,
1804cb2ed8b3SMarcel Apfelbaum                                         pci_bus_num(host_bridge->bus));
1805315a1350SMichael S. Tsirkin 
1806315a1350SMichael S. Tsirkin         /* XXX: waiting for the qapi to support GSList */
1807315a1350SMichael S. Tsirkin         if (!cur_item) {
1808315a1350SMichael S. Tsirkin             head = cur_item = info;
1809315a1350SMichael S. Tsirkin         } else {
1810315a1350SMichael S. Tsirkin             cur_item->next = info;
1811315a1350SMichael S. Tsirkin             cur_item = info;
1812315a1350SMichael S. Tsirkin         }
1813315a1350SMichael S. Tsirkin     }
1814315a1350SMichael S. Tsirkin 
1815315a1350SMichael S. Tsirkin     return head;
1816315a1350SMichael S. Tsirkin }
1817315a1350SMichael S. Tsirkin 
1818315a1350SMichael S. Tsirkin static const char * const pci_nic_models[] = {
1819315a1350SMichael S. Tsirkin     "ne2k_pci",
1820315a1350SMichael S. Tsirkin     "i82551",
1821315a1350SMichael S. Tsirkin     "i82557b",
1822315a1350SMichael S. Tsirkin     "i82559er",
1823315a1350SMichael S. Tsirkin     "rtl8139",
1824315a1350SMichael S. Tsirkin     "e1000",
1825315a1350SMichael S. Tsirkin     "pcnet",
1826315a1350SMichael S. Tsirkin     "virtio",
1827f85504b2SBenjamin Herrenschmidt     "sungem",
1828315a1350SMichael S. Tsirkin     NULL
1829315a1350SMichael S. Tsirkin };
1830315a1350SMichael S. Tsirkin 
1831315a1350SMichael S. Tsirkin static const char * const pci_nic_names[] = {
1832315a1350SMichael S. Tsirkin     "ne2k_pci",
1833315a1350SMichael S. Tsirkin     "i82551",
1834315a1350SMichael S. Tsirkin     "i82557b",
1835315a1350SMichael S. Tsirkin     "i82559er",
1836315a1350SMichael S. Tsirkin     "rtl8139",
1837315a1350SMichael S. Tsirkin     "e1000",
1838315a1350SMichael S. Tsirkin     "pcnet",
1839315a1350SMichael S. Tsirkin     "virtio-net-pci",
1840f85504b2SBenjamin Herrenschmidt     "sungem",
1841315a1350SMichael S. Tsirkin     NULL
1842315a1350SMichael S. Tsirkin };
1843315a1350SMichael S. Tsirkin 
1844315a1350SMichael S. Tsirkin /* Initialize a PCI NIC.  */
184551f7cb97SThomas Huth PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
184629b358f9SDavid Gibson                                const char *default_model,
184751f7cb97SThomas Huth                                const char *default_devaddr)
1848315a1350SMichael S. Tsirkin {
1849315a1350SMichael S. Tsirkin     const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
1850315a1350SMichael S. Tsirkin     PCIBus *bus;
1851315a1350SMichael S. Tsirkin     PCIDevice *pci_dev;
1852315a1350SMichael S. Tsirkin     DeviceState *dev;
185351f7cb97SThomas Huth     int devfn;
1854315a1350SMichael S. Tsirkin     int i;
1855315a1350SMichael S. Tsirkin 
185651f7cb97SThomas Huth     if (qemu_show_nic_models(nd->model, pci_nic_models)) {
185751f7cb97SThomas Huth         exit(0);
185851f7cb97SThomas Huth     }
185951f7cb97SThomas Huth 
1860315a1350SMichael S. Tsirkin     i = qemu_find_nic_model(nd, pci_nic_models, default_model);
186151f7cb97SThomas Huth     if (i < 0) {
186251f7cb97SThomas Huth         exit(1);
186351f7cb97SThomas Huth     }
1864315a1350SMichael S. Tsirkin 
186529b358f9SDavid Gibson     bus = pci_get_bus_devfn(&devfn, rootbus, devaddr);
1866315a1350SMichael S. Tsirkin     if (!bus) {
1867315a1350SMichael S. Tsirkin         error_report("Invalid PCI device address %s for device %s",
1868315a1350SMichael S. Tsirkin                      devaddr, pci_nic_names[i]);
186951f7cb97SThomas Huth         exit(1);
1870315a1350SMichael S. Tsirkin     }
1871315a1350SMichael S. Tsirkin 
1872315a1350SMichael S. Tsirkin     pci_dev = pci_create(bus, devfn, pci_nic_names[i]);
1873315a1350SMichael S. Tsirkin     dev = &pci_dev->qdev;
1874315a1350SMichael S. Tsirkin     qdev_set_nic_properties(dev, nd);
1875a023b7acSAlex Kompel     qdev_init_nofail(dev);
187651f7cb97SThomas Huth 
187751f7cb97SThomas Huth     return pci_dev;
1878315a1350SMichael S. Tsirkin }
1879315a1350SMichael S. Tsirkin 
1880315a1350SMichael S. Tsirkin PCIDevice *pci_vga_init(PCIBus *bus)
1881315a1350SMichael S. Tsirkin {
1882315a1350SMichael S. Tsirkin     switch (vga_interface_type) {
1883315a1350SMichael S. Tsirkin     case VGA_CIRRUS:
1884315a1350SMichael S. Tsirkin         return pci_create_simple(bus, -1, "cirrus-vga");
1885315a1350SMichael S. Tsirkin     case VGA_QXL:
1886315a1350SMichael S. Tsirkin         return pci_create_simple(bus, -1, "qxl-vga");
1887315a1350SMichael S. Tsirkin     case VGA_STD:
1888315a1350SMichael S. Tsirkin         return pci_create_simple(bus, -1, "VGA");
1889315a1350SMichael S. Tsirkin     case VGA_VMWARE:
1890315a1350SMichael S. Tsirkin         return pci_create_simple(bus, -1, "vmware-svga");
1891a94f0c5cSGerd Hoffmann     case VGA_VIRTIO:
1892a94f0c5cSGerd Hoffmann         return pci_create_simple(bus, -1, "virtio-vga");
1893315a1350SMichael S. Tsirkin     case VGA_NONE:
1894315a1350SMichael S. Tsirkin     default: /* Other non-PCI types. Checking for unsupported types is already
1895315a1350SMichael S. Tsirkin                 done in vl.c. */
1896315a1350SMichael S. Tsirkin         return NULL;
1897315a1350SMichael S. Tsirkin     }
1898315a1350SMichael S. Tsirkin }
1899315a1350SMichael S. Tsirkin 
1900315a1350SMichael S. Tsirkin /* Whether a given bus number is in range of the secondary
1901315a1350SMichael S. Tsirkin  * bus of the given bridge device. */
1902315a1350SMichael S. Tsirkin static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
1903315a1350SMichael S. Tsirkin {
1904315a1350SMichael S. Tsirkin     return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) &
1905315a1350SMichael S. Tsirkin              PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */ &&
190609e5b819SMarcel Apfelbaum         dev->config[PCI_SECONDARY_BUS] <= bus_num &&
1907315a1350SMichael S. Tsirkin         bus_num <= dev->config[PCI_SUBORDINATE_BUS];
1908315a1350SMichael S. Tsirkin }
1909315a1350SMichael S. Tsirkin 
191009e5b819SMarcel Apfelbaum /* Whether a given bus number is in a range of a root bus */
191109e5b819SMarcel Apfelbaum static bool pci_root_bus_in_range(PCIBus *bus, int bus_num)
191209e5b819SMarcel Apfelbaum {
191309e5b819SMarcel Apfelbaum     int i;
191409e5b819SMarcel Apfelbaum 
191509e5b819SMarcel Apfelbaum     for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
191609e5b819SMarcel Apfelbaum         PCIDevice *dev = bus->devices[i];
191709e5b819SMarcel Apfelbaum 
191809e5b819SMarcel Apfelbaum         if (dev && PCI_DEVICE_GET_CLASS(dev)->is_bridge) {
191909e5b819SMarcel Apfelbaum             if (pci_secondary_bus_in_range(dev, bus_num)) {
192009e5b819SMarcel Apfelbaum                 return true;
192109e5b819SMarcel Apfelbaum             }
192209e5b819SMarcel Apfelbaum         }
192309e5b819SMarcel Apfelbaum     }
192409e5b819SMarcel Apfelbaum 
192509e5b819SMarcel Apfelbaum     return false;
192609e5b819SMarcel Apfelbaum }
192709e5b819SMarcel Apfelbaum 
1928315a1350SMichael S. Tsirkin static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
1929315a1350SMichael S. Tsirkin {
1930315a1350SMichael S. Tsirkin     PCIBus *sec;
1931315a1350SMichael S. Tsirkin 
1932315a1350SMichael S. Tsirkin     if (!bus) {
1933315a1350SMichael S. Tsirkin         return NULL;
1934315a1350SMichael S. Tsirkin     }
1935315a1350SMichael S. Tsirkin 
1936315a1350SMichael S. Tsirkin     if (pci_bus_num(bus) == bus_num) {
1937315a1350SMichael S. Tsirkin         return bus;
1938315a1350SMichael S. Tsirkin     }
1939315a1350SMichael S. Tsirkin 
1940315a1350SMichael S. Tsirkin     /* Consider all bus numbers in range for the host pci bridge. */
19410889464aSAlex Williamson     if (!pci_bus_is_root(bus) &&
1942315a1350SMichael S. Tsirkin         !pci_secondary_bus_in_range(bus->parent_dev, bus_num)) {
1943315a1350SMichael S. Tsirkin         return NULL;
1944315a1350SMichael S. Tsirkin     }
1945315a1350SMichael S. Tsirkin 
1946315a1350SMichael S. Tsirkin     /* try child bus */
1947315a1350SMichael S. Tsirkin     for (; bus; bus = sec) {
1948315a1350SMichael S. Tsirkin         QLIST_FOREACH(sec, &bus->child, sibling) {
194909e5b819SMarcel Apfelbaum             if (pci_bus_num(sec) == bus_num) {
1950315a1350SMichael S. Tsirkin                 return sec;
1951315a1350SMichael S. Tsirkin             }
195209e5b819SMarcel Apfelbaum             /* PXB buses assumed to be children of bus 0 */
195309e5b819SMarcel Apfelbaum             if (pci_bus_is_root(sec)) {
195409e5b819SMarcel Apfelbaum                 if (pci_root_bus_in_range(sec, bus_num)) {
195509e5b819SMarcel Apfelbaum                     break;
195609e5b819SMarcel Apfelbaum                 }
195709e5b819SMarcel Apfelbaum             } else {
1958315a1350SMichael S. Tsirkin                 if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) {
1959315a1350SMichael S. Tsirkin                     break;
1960315a1350SMichael S. Tsirkin                 }
1961315a1350SMichael S. Tsirkin             }
1962315a1350SMichael S. Tsirkin         }
196309e5b819SMarcel Apfelbaum     }
1964315a1350SMichael S. Tsirkin 
1965315a1350SMichael S. Tsirkin     return NULL;
1966315a1350SMichael S. Tsirkin }
1967315a1350SMichael S. Tsirkin 
1968eb0acfddSMichael S. Tsirkin void pci_for_each_bus_depth_first(PCIBus *bus,
1969eb0acfddSMichael S. Tsirkin                                   void *(*begin)(PCIBus *bus, void *parent_state),
1970eb0acfddSMichael S. Tsirkin                                   void (*end)(PCIBus *bus, void *state),
1971eb0acfddSMichael S. Tsirkin                                   void *parent_state)
1972eb0acfddSMichael S. Tsirkin {
1973eb0acfddSMichael S. Tsirkin     PCIBus *sec;
1974eb0acfddSMichael S. Tsirkin     void *state;
1975eb0acfddSMichael S. Tsirkin 
1976eb0acfddSMichael S. Tsirkin     if (!bus) {
1977eb0acfddSMichael S. Tsirkin         return;
1978eb0acfddSMichael S. Tsirkin     }
1979eb0acfddSMichael S. Tsirkin 
1980eb0acfddSMichael S. Tsirkin     if (begin) {
1981eb0acfddSMichael S. Tsirkin         state = begin(bus, parent_state);
1982eb0acfddSMichael S. Tsirkin     } else {
1983eb0acfddSMichael S. Tsirkin         state = parent_state;
1984eb0acfddSMichael S. Tsirkin     }
1985eb0acfddSMichael S. Tsirkin 
1986eb0acfddSMichael S. Tsirkin     QLIST_FOREACH(sec, &bus->child, sibling) {
1987eb0acfddSMichael S. Tsirkin         pci_for_each_bus_depth_first(sec, begin, end, state);
1988eb0acfddSMichael S. Tsirkin     }
1989eb0acfddSMichael S. Tsirkin 
1990eb0acfddSMichael S. Tsirkin     if (end) {
1991eb0acfddSMichael S. Tsirkin         end(bus, state);
1992eb0acfddSMichael S. Tsirkin     }
1993eb0acfddSMichael S. Tsirkin }
1994eb0acfddSMichael S. Tsirkin 
1995eb0acfddSMichael S. Tsirkin 
1996315a1350SMichael S. Tsirkin PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
1997315a1350SMichael S. Tsirkin {
1998315a1350SMichael S. Tsirkin     bus = pci_find_bus_nr(bus, bus_num);
1999315a1350SMichael S. Tsirkin 
2000315a1350SMichael S. Tsirkin     if (!bus)
2001315a1350SMichael S. Tsirkin         return NULL;
2002315a1350SMichael S. Tsirkin 
2003315a1350SMichael S. Tsirkin     return bus->devices[devfn];
2004315a1350SMichael S. Tsirkin }
2005315a1350SMichael S. Tsirkin 
2006133e9b22SMarkus Armbruster static void pci_qdev_realize(DeviceState *qdev, Error **errp)
2007315a1350SMichael S. Tsirkin {
2008315a1350SMichael S. Tsirkin     PCIDevice *pci_dev = (PCIDevice *)qdev;
2009315a1350SMichael S. Tsirkin     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
2010133e9b22SMarkus Armbruster     Error *local_err = NULL;
2011315a1350SMichael S. Tsirkin     bool is_default_rom;
2012315a1350SMichael S. Tsirkin 
2013315a1350SMichael S. Tsirkin     /* initialize cap_present for pci_is_express() and pci_config_size() */
2014315a1350SMichael S. Tsirkin     if (pc->is_express) {
2015315a1350SMichael S. Tsirkin         pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
2016315a1350SMichael S. Tsirkin     }
2017315a1350SMichael S. Tsirkin 
2018fd56e061SDavid Gibson     pci_dev = do_pci_register_device(pci_dev,
2019315a1350SMichael S. Tsirkin                                      object_get_typename(OBJECT(qdev)),
2020133e9b22SMarkus Armbruster                                      pci_dev->devfn, errp);
2021315a1350SMichael S. Tsirkin     if (pci_dev == NULL)
2022133e9b22SMarkus Armbruster         return;
20232897ae02SIgor Mammedov 
20247ee6c1e1SMarkus Armbruster     if (pc->realize) {
20257ee6c1e1SMarkus Armbruster         pc->realize(pci_dev, &local_err);
20267ee6c1e1SMarkus Armbruster         if (local_err) {
20277ee6c1e1SMarkus Armbruster             error_propagate(errp, local_err);
2028315a1350SMichael S. Tsirkin             do_pci_unregister_device(pci_dev);
2029133e9b22SMarkus Armbruster             return;
2030315a1350SMichael S. Tsirkin         }
2031315a1350SMichael S. Tsirkin     }
2032315a1350SMichael S. Tsirkin 
2033315a1350SMichael S. Tsirkin     /* rom loading */
2034315a1350SMichael S. Tsirkin     is_default_rom = false;
2035315a1350SMichael S. Tsirkin     if (pci_dev->romfile == NULL && pc->romfile != NULL) {
2036315a1350SMichael S. Tsirkin         pci_dev->romfile = g_strdup(pc->romfile);
2037315a1350SMichael S. Tsirkin         is_default_rom = true;
2038315a1350SMichael S. Tsirkin     }
2039178e785fSMarcel Apfelbaum 
2040133e9b22SMarkus Armbruster     pci_add_option_rom(pci_dev, is_default_rom, &local_err);
2041133e9b22SMarkus Armbruster     if (local_err) {
2042133e9b22SMarkus Armbruster         error_propagate(errp, local_err);
2043133e9b22SMarkus Armbruster         pci_qdev_unrealize(DEVICE(pci_dev), NULL);
2044133e9b22SMarkus Armbruster         return;
2045178e785fSMarcel Apfelbaum     }
2046315a1350SMichael S. Tsirkin }
2047315a1350SMichael S. Tsirkin 
20487ee6c1e1SMarkus Armbruster static void pci_default_realize(PCIDevice *dev, Error **errp)
20497ee6c1e1SMarkus Armbruster {
20507ee6c1e1SMarkus Armbruster     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
20517ee6c1e1SMarkus Armbruster 
20527ee6c1e1SMarkus Armbruster     if (pc->init) {
20537ee6c1e1SMarkus Armbruster         if (pc->init(dev) < 0) {
20547ee6c1e1SMarkus Armbruster             error_setg(errp, "Device initialization failed");
20557ee6c1e1SMarkus Armbruster             return;
20567ee6c1e1SMarkus Armbruster         }
20577ee6c1e1SMarkus Armbruster     }
20587ee6c1e1SMarkus Armbruster }
20597ee6c1e1SMarkus Armbruster 
2060315a1350SMichael S. Tsirkin PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
2061315a1350SMichael S. Tsirkin                                     const char *name)
2062315a1350SMichael S. Tsirkin {
2063315a1350SMichael S. Tsirkin     DeviceState *dev;
2064315a1350SMichael S. Tsirkin 
2065315a1350SMichael S. Tsirkin     dev = qdev_create(&bus->qbus, name);
2066315a1350SMichael S. Tsirkin     qdev_prop_set_int32(dev, "addr", devfn);
2067315a1350SMichael S. Tsirkin     qdev_prop_set_bit(dev, "multifunction", multifunction);
2068315a1350SMichael S. Tsirkin     return PCI_DEVICE(dev);
2069315a1350SMichael S. Tsirkin }
2070315a1350SMichael S. Tsirkin 
2071315a1350SMichael S. Tsirkin PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
2072315a1350SMichael S. Tsirkin                                            bool multifunction,
2073315a1350SMichael S. Tsirkin                                            const char *name)
2074315a1350SMichael S. Tsirkin {
2075315a1350SMichael S. Tsirkin     PCIDevice *dev = pci_create_multifunction(bus, devfn, multifunction, name);
2076315a1350SMichael S. Tsirkin     qdev_init_nofail(&dev->qdev);
2077315a1350SMichael S. Tsirkin     return dev;
2078315a1350SMichael S. Tsirkin }
2079315a1350SMichael S. Tsirkin 
2080315a1350SMichael S. Tsirkin PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name)
2081315a1350SMichael S. Tsirkin {
2082315a1350SMichael S. Tsirkin     return pci_create_multifunction(bus, devfn, false, name);
2083315a1350SMichael S. Tsirkin }
2084315a1350SMichael S. Tsirkin 
2085315a1350SMichael S. Tsirkin PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
2086315a1350SMichael S. Tsirkin {
2087315a1350SMichael S. Tsirkin     return pci_create_simple_multifunction(bus, devfn, false, name);
2088315a1350SMichael S. Tsirkin }
2089315a1350SMichael S. Tsirkin 
2090315a1350SMichael S. Tsirkin static uint8_t pci_find_space(PCIDevice *pdev, uint8_t size)
2091315a1350SMichael S. Tsirkin {
2092315a1350SMichael S. Tsirkin     int offset = PCI_CONFIG_HEADER_SIZE;
2093315a1350SMichael S. Tsirkin     int i;
2094315a1350SMichael S. Tsirkin     for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i) {
2095315a1350SMichael S. Tsirkin         if (pdev->used[i])
2096315a1350SMichael S. Tsirkin             offset = i + 1;
2097315a1350SMichael S. Tsirkin         else if (i - offset + 1 == size)
2098315a1350SMichael S. Tsirkin             return offset;
2099315a1350SMichael S. Tsirkin     }
2100315a1350SMichael S. Tsirkin     return 0;
2101315a1350SMichael S. Tsirkin }
2102315a1350SMichael S. Tsirkin 
2103315a1350SMichael S. Tsirkin static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
2104315a1350SMichael S. Tsirkin                                         uint8_t *prev_p)
2105315a1350SMichael S. Tsirkin {
2106315a1350SMichael S. Tsirkin     uint8_t next, prev;
2107315a1350SMichael S. Tsirkin 
2108315a1350SMichael S. Tsirkin     if (!(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST))
2109315a1350SMichael S. Tsirkin         return 0;
2110315a1350SMichael S. Tsirkin 
2111315a1350SMichael S. Tsirkin     for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
2112315a1350SMichael S. Tsirkin          prev = next + PCI_CAP_LIST_NEXT)
2113315a1350SMichael S. Tsirkin         if (pdev->config[next + PCI_CAP_LIST_ID] == cap_id)
2114315a1350SMichael S. Tsirkin             break;
2115315a1350SMichael S. Tsirkin 
2116315a1350SMichael S. Tsirkin     if (prev_p)
2117315a1350SMichael S. Tsirkin         *prev_p = prev;
2118315a1350SMichael S. Tsirkin     return next;
2119315a1350SMichael S. Tsirkin }
2120315a1350SMichael S. Tsirkin 
2121315a1350SMichael S. Tsirkin static uint8_t pci_find_capability_at_offset(PCIDevice *pdev, uint8_t offset)
2122315a1350SMichael S. Tsirkin {
2123315a1350SMichael S. Tsirkin     uint8_t next, prev, found = 0;
2124315a1350SMichael S. Tsirkin 
2125315a1350SMichael S. Tsirkin     if (!(pdev->used[offset])) {
2126315a1350SMichael S. Tsirkin         return 0;
2127315a1350SMichael S. Tsirkin     }
2128315a1350SMichael S. Tsirkin 
2129315a1350SMichael S. Tsirkin     assert(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST);
2130315a1350SMichael S. Tsirkin 
2131315a1350SMichael S. Tsirkin     for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
2132315a1350SMichael S. Tsirkin          prev = next + PCI_CAP_LIST_NEXT) {
2133315a1350SMichael S. Tsirkin         if (next <= offset && next > found) {
2134315a1350SMichael S. Tsirkin             found = next;
2135315a1350SMichael S. Tsirkin         }
2136315a1350SMichael S. Tsirkin     }
2137315a1350SMichael S. Tsirkin     return found;
2138315a1350SMichael S. Tsirkin }
2139315a1350SMichael S. Tsirkin 
2140315a1350SMichael S. Tsirkin /* Patch the PCI vendor and device ids in a PCI rom image if necessary.
2141315a1350SMichael S. Tsirkin    This is needed for an option rom which is used for more than one device. */
2142315a1350SMichael S. Tsirkin static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
2143315a1350SMichael S. Tsirkin {
2144315a1350SMichael S. Tsirkin     uint16_t vendor_id;
2145315a1350SMichael S. Tsirkin     uint16_t device_id;
2146315a1350SMichael S. Tsirkin     uint16_t rom_vendor_id;
2147315a1350SMichael S. Tsirkin     uint16_t rom_device_id;
2148315a1350SMichael S. Tsirkin     uint16_t rom_magic;
2149315a1350SMichael S. Tsirkin     uint16_t pcir_offset;
2150315a1350SMichael S. Tsirkin     uint8_t checksum;
2151315a1350SMichael S. Tsirkin 
2152315a1350SMichael S. Tsirkin     /* Words in rom data are little endian (like in PCI configuration),
2153315a1350SMichael S. Tsirkin        so they can be read / written with pci_get_word / pci_set_word. */
2154315a1350SMichael S. Tsirkin 
2155315a1350SMichael S. Tsirkin     /* Only a valid rom will be patched. */
2156315a1350SMichael S. Tsirkin     rom_magic = pci_get_word(ptr);
2157315a1350SMichael S. Tsirkin     if (rom_magic != 0xaa55) {
2158315a1350SMichael S. Tsirkin         PCI_DPRINTF("Bad ROM magic %04x\n", rom_magic);
2159315a1350SMichael S. Tsirkin         return;
2160315a1350SMichael S. Tsirkin     }
2161315a1350SMichael S. Tsirkin     pcir_offset = pci_get_word(ptr + 0x18);
2162315a1350SMichael S. Tsirkin     if (pcir_offset + 8 >= size || memcmp(ptr + pcir_offset, "PCIR", 4)) {
2163315a1350SMichael S. Tsirkin         PCI_DPRINTF("Bad PCIR offset 0x%x or signature\n", pcir_offset);
2164315a1350SMichael S. Tsirkin         return;
2165315a1350SMichael S. Tsirkin     }
2166315a1350SMichael S. Tsirkin 
2167315a1350SMichael S. Tsirkin     vendor_id = pci_get_word(pdev->config + PCI_VENDOR_ID);
2168315a1350SMichael S. Tsirkin     device_id = pci_get_word(pdev->config + PCI_DEVICE_ID);
2169315a1350SMichael S. Tsirkin     rom_vendor_id = pci_get_word(ptr + pcir_offset + 4);
2170315a1350SMichael S. Tsirkin     rom_device_id = pci_get_word(ptr + pcir_offset + 6);
2171315a1350SMichael S. Tsirkin 
2172315a1350SMichael S. Tsirkin     PCI_DPRINTF("%s: ROM id %04x%04x / PCI id %04x%04x\n", pdev->romfile,
2173315a1350SMichael S. Tsirkin                 vendor_id, device_id, rom_vendor_id, rom_device_id);
2174315a1350SMichael S. Tsirkin 
2175315a1350SMichael S. Tsirkin     checksum = ptr[6];
2176315a1350SMichael S. Tsirkin 
2177315a1350SMichael S. Tsirkin     if (vendor_id != rom_vendor_id) {
2178315a1350SMichael S. Tsirkin         /* Patch vendor id and checksum (at offset 6 for etherboot roms). */
2179315a1350SMichael S. Tsirkin         checksum += (uint8_t)rom_vendor_id + (uint8_t)(rom_vendor_id >> 8);
2180315a1350SMichael S. Tsirkin         checksum -= (uint8_t)vendor_id + (uint8_t)(vendor_id >> 8);
2181315a1350SMichael S. Tsirkin         PCI_DPRINTF("ROM checksum %02x / %02x\n", ptr[6], checksum);
2182315a1350SMichael S. Tsirkin         ptr[6] = checksum;
2183315a1350SMichael S. Tsirkin         pci_set_word(ptr + pcir_offset + 4, vendor_id);
2184315a1350SMichael S. Tsirkin     }
2185315a1350SMichael S. Tsirkin 
2186315a1350SMichael S. Tsirkin     if (device_id != rom_device_id) {
2187315a1350SMichael S. Tsirkin         /* Patch device id and checksum (at offset 6 for etherboot roms). */
2188315a1350SMichael S. Tsirkin         checksum += (uint8_t)rom_device_id + (uint8_t)(rom_device_id >> 8);
2189315a1350SMichael S. Tsirkin         checksum -= (uint8_t)device_id + (uint8_t)(device_id >> 8);
2190315a1350SMichael S. Tsirkin         PCI_DPRINTF("ROM checksum %02x / %02x\n", ptr[6], checksum);
2191315a1350SMichael S. Tsirkin         ptr[6] = checksum;
2192315a1350SMichael S. Tsirkin         pci_set_word(ptr + pcir_offset + 6, device_id);
2193315a1350SMichael S. Tsirkin     }
2194315a1350SMichael S. Tsirkin }
2195315a1350SMichael S. Tsirkin 
2196315a1350SMichael S. Tsirkin /* Add an option rom for the device */
2197133e9b22SMarkus Armbruster static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
2198133e9b22SMarkus Armbruster                                Error **errp)
2199315a1350SMichael S. Tsirkin {
2200315a1350SMichael S. Tsirkin     int size;
2201315a1350SMichael S. Tsirkin     char *path;
2202315a1350SMichael S. Tsirkin     void *ptr;
2203315a1350SMichael S. Tsirkin     char name[32];
2204315a1350SMichael S. Tsirkin     const VMStateDescription *vmsd;
2205315a1350SMichael S. Tsirkin 
2206315a1350SMichael S. Tsirkin     if (!pdev->romfile)
2207133e9b22SMarkus Armbruster         return;
2208315a1350SMichael S. Tsirkin     if (strlen(pdev->romfile) == 0)
2209133e9b22SMarkus Armbruster         return;
2210315a1350SMichael S. Tsirkin 
2211315a1350SMichael S. Tsirkin     if (!pdev->rom_bar) {
2212315a1350SMichael S. Tsirkin         /*
2213315a1350SMichael S. Tsirkin          * Load rom via fw_cfg instead of creating a rom bar,
2214315a1350SMichael S. Tsirkin          * for 0.11 compatibility.
2215315a1350SMichael S. Tsirkin          */
2216315a1350SMichael S. Tsirkin         int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
2217db80c7b9SMarcel Apfelbaum 
2218db80c7b9SMarcel Apfelbaum         /*
2219db80c7b9SMarcel Apfelbaum          * Hot-plugged devices can't use the option ROM
2220db80c7b9SMarcel Apfelbaum          * if the rom bar is disabled.
2221db80c7b9SMarcel Apfelbaum          */
2222db80c7b9SMarcel Apfelbaum         if (DEVICE(pdev)->hotplugged) {
2223133e9b22SMarkus Armbruster             error_setg(errp, "Hot-plugged device without ROM bar"
2224133e9b22SMarkus Armbruster                        " can't have an option ROM");
2225133e9b22SMarkus Armbruster             return;
2226db80c7b9SMarcel Apfelbaum         }
2227db80c7b9SMarcel Apfelbaum 
2228315a1350SMichael S. Tsirkin         if (class == 0x0300) {
2229315a1350SMichael S. Tsirkin             rom_add_vga(pdev->romfile);
2230315a1350SMichael S. Tsirkin         } else {
2231315a1350SMichael S. Tsirkin             rom_add_option(pdev->romfile, -1);
2232315a1350SMichael S. Tsirkin         }
2233133e9b22SMarkus Armbruster         return;
2234315a1350SMichael S. Tsirkin     }
2235315a1350SMichael S. Tsirkin 
2236315a1350SMichael S. Tsirkin     path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
2237315a1350SMichael S. Tsirkin     if (path == NULL) {
2238315a1350SMichael S. Tsirkin         path = g_strdup(pdev->romfile);
2239315a1350SMichael S. Tsirkin     }
2240315a1350SMichael S. Tsirkin 
2241315a1350SMichael S. Tsirkin     size = get_image_size(path);
2242315a1350SMichael S. Tsirkin     if (size < 0) {
2243133e9b22SMarkus Armbruster         error_setg(errp, "failed to find romfile \"%s\"", pdev->romfile);
22448c7f3dd0SStefan Hajnoczi         g_free(path);
2245133e9b22SMarkus Armbruster         return;
22468c7f3dd0SStefan Hajnoczi     } else if (size == 0) {
2247133e9b22SMarkus Armbruster         error_setg(errp, "romfile \"%s\" is empty", pdev->romfile);
2248315a1350SMichael S. Tsirkin         g_free(path);
2249133e9b22SMarkus Armbruster         return;
2250315a1350SMichael S. Tsirkin     }
22519bff5d81SPeter Maydell     size = pow2ceil(size);
2252315a1350SMichael S. Tsirkin 
2253315a1350SMichael S. Tsirkin     vmsd = qdev_get_vmsd(DEVICE(pdev));
2254315a1350SMichael S. Tsirkin 
2255315a1350SMichael S. Tsirkin     if (vmsd) {
2256315a1350SMichael S. Tsirkin         snprintf(name, sizeof(name), "%s.rom", vmsd->name);
2257315a1350SMichael S. Tsirkin     } else {
2258315a1350SMichael S. Tsirkin         snprintf(name, sizeof(name), "%s.rom", object_get_typename(OBJECT(pdev)));
2259315a1350SMichael S. Tsirkin     }
2260315a1350SMichael S. Tsirkin     pdev->has_rom = true;
2261fefa9256SPeter Maydell     memory_region_init_rom(&pdev->rom, OBJECT(pdev), name, size, &error_fatal);
2262315a1350SMichael S. Tsirkin     ptr = memory_region_get_ram_ptr(&pdev->rom);
2263315a1350SMichael S. Tsirkin     load_image(path, ptr);
2264315a1350SMichael S. Tsirkin     g_free(path);
2265315a1350SMichael S. Tsirkin 
2266315a1350SMichael S. Tsirkin     if (is_default_rom) {
2267315a1350SMichael S. Tsirkin         /* Only the default rom images will be patched (if needed). */
2268315a1350SMichael S. Tsirkin         pci_patch_ids(pdev, ptr, size);
2269315a1350SMichael S. Tsirkin     }
2270315a1350SMichael S. Tsirkin 
2271315a1350SMichael S. Tsirkin     pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
2272315a1350SMichael S. Tsirkin }
2273315a1350SMichael S. Tsirkin 
2274315a1350SMichael S. Tsirkin static void pci_del_option_rom(PCIDevice *pdev)
2275315a1350SMichael S. Tsirkin {
2276315a1350SMichael S. Tsirkin     if (!pdev->has_rom)
2277315a1350SMichael S. Tsirkin         return;
2278315a1350SMichael S. Tsirkin 
2279315a1350SMichael S. Tsirkin     vmstate_unregister_ram(&pdev->rom, &pdev->qdev);
2280315a1350SMichael S. Tsirkin     pdev->has_rom = false;
2281315a1350SMichael S. Tsirkin }
2282315a1350SMichael S. Tsirkin 
2283315a1350SMichael S. Tsirkin /*
228427841278SMao Zhongyi  * On success, pci_add_capability() returns a positive value
2285eacbc632SMao Zhongyi  * that the offset of the pci capability.
2286eacbc632SMao Zhongyi  * On failure, it sets an error and returns a negative error
2287eacbc632SMao Zhongyi  * code.
2288eacbc632SMao Zhongyi  */
228927841278SMao Zhongyi int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
2290cd9aa33eSLaszlo Ersek                        uint8_t offset, uint8_t size,
2291cd9aa33eSLaszlo Ersek                        Error **errp)
2292cd9aa33eSLaszlo Ersek {
2293315a1350SMichael S. Tsirkin     uint8_t *config;
2294315a1350SMichael S. Tsirkin     int i, overlapping_cap;
2295315a1350SMichael S. Tsirkin 
2296315a1350SMichael S. Tsirkin     if (!offset) {
2297315a1350SMichael S. Tsirkin         offset = pci_find_space(pdev, size);
229897fe42f1SCao jin         /* out of PCI config space is programming error */
229997fe42f1SCao jin         assert(offset);
2300315a1350SMichael S. Tsirkin     } else {
2301315a1350SMichael S. Tsirkin         /* Verify that capabilities don't overlap.  Note: device assignment
2302315a1350SMichael S. Tsirkin          * depends on this check to verify that the device is not broken.
2303315a1350SMichael S. Tsirkin          * Should never trigger for emulated devices, but it's helpful
2304315a1350SMichael S. Tsirkin          * for debugging these. */
2305315a1350SMichael S. Tsirkin         for (i = offset; i < offset + size; i++) {
2306315a1350SMichael S. Tsirkin             overlapping_cap = pci_find_capability_at_offset(pdev, i);
2307315a1350SMichael S. Tsirkin             if (overlapping_cap) {
2308cd9aa33eSLaszlo Ersek                 error_setg(errp, "%s:%02x:%02x.%x "
2309315a1350SMichael S. Tsirkin                            "Attempt to add PCI capability %x at offset "
2310cd9aa33eSLaszlo Ersek                            "%x overlaps existing capability %x at offset %x",
2311fd56e061SDavid Gibson                            pci_root_bus_path(pdev), pci_dev_bus_num(pdev),
2312315a1350SMichael S. Tsirkin                            PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
2313315a1350SMichael S. Tsirkin                            cap_id, offset, overlapping_cap, i);
2314315a1350SMichael S. Tsirkin                 return -EINVAL;
2315315a1350SMichael S. Tsirkin             }
2316315a1350SMichael S. Tsirkin         }
2317315a1350SMichael S. Tsirkin     }
2318315a1350SMichael S. Tsirkin 
2319315a1350SMichael S. Tsirkin     config = pdev->config + offset;
2320315a1350SMichael S. Tsirkin     config[PCI_CAP_LIST_ID] = cap_id;
2321315a1350SMichael S. Tsirkin     config[PCI_CAP_LIST_NEXT] = pdev->config[PCI_CAPABILITY_LIST];
2322315a1350SMichael S. Tsirkin     pdev->config[PCI_CAPABILITY_LIST] = offset;
2323315a1350SMichael S. Tsirkin     pdev->config[PCI_STATUS] |= PCI_STATUS_CAP_LIST;
2324315a1350SMichael S. Tsirkin     memset(pdev->used + offset, 0xFF, QEMU_ALIGN_UP(size, 4));
2325315a1350SMichael S. Tsirkin     /* Make capability read-only by default */
2326315a1350SMichael S. Tsirkin     memset(pdev->wmask + offset, 0, size);
2327315a1350SMichael S. Tsirkin     /* Check capability by default */
2328315a1350SMichael S. Tsirkin     memset(pdev->cmask + offset, 0xFF, size);
2329315a1350SMichael S. Tsirkin     return offset;
2330315a1350SMichael S. Tsirkin }
2331315a1350SMichael S. Tsirkin 
2332315a1350SMichael S. Tsirkin /* Unlink capability from the pci config space. */
2333315a1350SMichael S. Tsirkin void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
2334315a1350SMichael S. Tsirkin {
2335315a1350SMichael S. Tsirkin     uint8_t prev, offset = pci_find_capability_list(pdev, cap_id, &prev);
2336315a1350SMichael S. Tsirkin     if (!offset)
2337315a1350SMichael S. Tsirkin         return;
2338315a1350SMichael S. Tsirkin     pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];
2339315a1350SMichael S. Tsirkin     /* Make capability writable again */
2340315a1350SMichael S. Tsirkin     memset(pdev->wmask + offset, 0xff, size);
2341315a1350SMichael S. Tsirkin     memset(pdev->w1cmask + offset, 0, size);
2342315a1350SMichael S. Tsirkin     /* Clear cmask as device-specific registers can't be checked */
2343315a1350SMichael S. Tsirkin     memset(pdev->cmask + offset, 0, size);
2344315a1350SMichael S. Tsirkin     memset(pdev->used + offset, 0, QEMU_ALIGN_UP(size, 4));
2345315a1350SMichael S. Tsirkin 
2346315a1350SMichael S. Tsirkin     if (!pdev->config[PCI_CAPABILITY_LIST])
2347315a1350SMichael S. Tsirkin         pdev->config[PCI_STATUS] &= ~PCI_STATUS_CAP_LIST;
2348315a1350SMichael S. Tsirkin }
2349315a1350SMichael S. Tsirkin 
2350315a1350SMichael S. Tsirkin uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id)
2351315a1350SMichael S. Tsirkin {
2352315a1350SMichael S. Tsirkin     return pci_find_capability_list(pdev, cap_id, NULL);
2353315a1350SMichael S. Tsirkin }
2354315a1350SMichael S. Tsirkin 
2355315a1350SMichael S. Tsirkin static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
2356315a1350SMichael S. Tsirkin {
2357315a1350SMichael S. Tsirkin     PCIDevice *d = (PCIDevice *)dev;
2358315a1350SMichael S. Tsirkin     const pci_class_desc *desc;
2359315a1350SMichael S. Tsirkin     char ctxt[64];
2360315a1350SMichael S. Tsirkin     PCIIORegion *r;
2361315a1350SMichael S. Tsirkin     int i, class;
2362315a1350SMichael S. Tsirkin 
2363315a1350SMichael S. Tsirkin     class = pci_get_word(d->config + PCI_CLASS_DEVICE);
2364315a1350SMichael S. Tsirkin     desc = pci_class_descriptions;
2365315a1350SMichael S. Tsirkin     while (desc->desc && class != desc->class)
2366315a1350SMichael S. Tsirkin         desc++;
2367315a1350SMichael S. Tsirkin     if (desc->desc) {
2368315a1350SMichael S. Tsirkin         snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
2369315a1350SMichael S. Tsirkin     } else {
2370315a1350SMichael S. Tsirkin         snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
2371315a1350SMichael S. Tsirkin     }
2372315a1350SMichael S. Tsirkin 
2373315a1350SMichael S. Tsirkin     monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
2374315a1350SMichael S. Tsirkin                    "pci id %04x:%04x (sub %04x:%04x)\n",
2375fd56e061SDavid Gibson                    indent, "", ctxt, pci_dev_bus_num(d),
2376315a1350SMichael S. Tsirkin                    PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
2377315a1350SMichael S. Tsirkin                    pci_get_word(d->config + PCI_VENDOR_ID),
2378315a1350SMichael S. Tsirkin                    pci_get_word(d->config + PCI_DEVICE_ID),
2379315a1350SMichael S. Tsirkin                    pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
2380315a1350SMichael S. Tsirkin                    pci_get_word(d->config + PCI_SUBSYSTEM_ID));
2381315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_REGIONS; i++) {
2382315a1350SMichael S. Tsirkin         r = &d->io_regions[i];
2383315a1350SMichael S. Tsirkin         if (!r->size)
2384315a1350SMichael S. Tsirkin             continue;
2385315a1350SMichael S. Tsirkin         monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS
2386315a1350SMichael S. Tsirkin                        " [0x%"FMT_PCIBUS"]\n",
2387315a1350SMichael S. Tsirkin                        indent, "",
2388315a1350SMichael S. Tsirkin                        i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
2389315a1350SMichael S. Tsirkin                        r->addr, r->addr + r->size - 1);
2390315a1350SMichael S. Tsirkin     }
2391315a1350SMichael S. Tsirkin }
2392315a1350SMichael S. Tsirkin 
2393315a1350SMichael S. Tsirkin static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
2394315a1350SMichael S. Tsirkin {
2395315a1350SMichael S. Tsirkin     PCIDevice *d = (PCIDevice *)dev;
2396315a1350SMichael S. Tsirkin     const char *name = NULL;
2397315a1350SMichael S. Tsirkin     const pci_class_desc *desc =  pci_class_descriptions;
2398315a1350SMichael S. Tsirkin     int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
2399315a1350SMichael S. Tsirkin 
2400315a1350SMichael S. Tsirkin     while (desc->desc &&
2401315a1350SMichael S. Tsirkin           (class & ~desc->fw_ign_bits) !=
2402315a1350SMichael S. Tsirkin           (desc->class & ~desc->fw_ign_bits)) {
2403315a1350SMichael S. Tsirkin         desc++;
2404315a1350SMichael S. Tsirkin     }
2405315a1350SMichael S. Tsirkin 
2406315a1350SMichael S. Tsirkin     if (desc->desc) {
2407315a1350SMichael S. Tsirkin         name = desc->fw_name;
2408315a1350SMichael S. Tsirkin     }
2409315a1350SMichael S. Tsirkin 
2410315a1350SMichael S. Tsirkin     if (name) {
2411315a1350SMichael S. Tsirkin         pstrcpy(buf, len, name);
2412315a1350SMichael S. Tsirkin     } else {
2413315a1350SMichael S. Tsirkin         snprintf(buf, len, "pci%04x,%04x",
2414315a1350SMichael S. Tsirkin                  pci_get_word(d->config + PCI_VENDOR_ID),
2415315a1350SMichael S. Tsirkin                  pci_get_word(d->config + PCI_DEVICE_ID));
2416315a1350SMichael S. Tsirkin     }
2417315a1350SMichael S. Tsirkin 
2418315a1350SMichael S. Tsirkin     return buf;
2419315a1350SMichael S. Tsirkin }
2420315a1350SMichael S. Tsirkin 
2421315a1350SMichael S. Tsirkin static char *pcibus_get_fw_dev_path(DeviceState *dev)
2422315a1350SMichael S. Tsirkin {
2423315a1350SMichael S. Tsirkin     PCIDevice *d = (PCIDevice *)dev;
2424315a1350SMichael S. Tsirkin     char path[50], name[33];
2425315a1350SMichael S. Tsirkin     int off;
2426315a1350SMichael S. Tsirkin 
2427315a1350SMichael S. Tsirkin     off = snprintf(path, sizeof(path), "%s@%x",
2428315a1350SMichael S. Tsirkin                    pci_dev_fw_name(dev, name, sizeof name),
2429315a1350SMichael S. Tsirkin                    PCI_SLOT(d->devfn));
2430315a1350SMichael S. Tsirkin     if (PCI_FUNC(d->devfn))
2431315a1350SMichael S. Tsirkin         snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
2432315a1350SMichael S. Tsirkin     return g_strdup(path);
2433315a1350SMichael S. Tsirkin }
2434315a1350SMichael S. Tsirkin 
2435315a1350SMichael S. Tsirkin static char *pcibus_get_dev_path(DeviceState *dev)
2436315a1350SMichael S. Tsirkin {
2437315a1350SMichael S. Tsirkin     PCIDevice *d = container_of(dev, PCIDevice, qdev);
2438315a1350SMichael S. Tsirkin     PCIDevice *t;
2439315a1350SMichael S. Tsirkin     int slot_depth;
2440315a1350SMichael S. Tsirkin     /* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function.
2441315a1350SMichael S. Tsirkin      * 00 is added here to make this format compatible with
2442315a1350SMichael S. Tsirkin      * domain:Bus:Slot.Func for systems without nested PCI bridges.
2443315a1350SMichael S. Tsirkin      * Slot.Function list specifies the slot and function numbers for all
2444315a1350SMichael S. Tsirkin      * devices on the path from root to the specific device. */
2445568f0690SDavid Gibson     const char *root_bus_path;
2446568f0690SDavid Gibson     int root_bus_len;
2447315a1350SMichael S. Tsirkin     char slot[] = ":SS.F";
2448315a1350SMichael S. Tsirkin     int slot_len = sizeof slot - 1 /* For '\0' */;
2449315a1350SMichael S. Tsirkin     int path_len;
2450315a1350SMichael S. Tsirkin     char *path, *p;
2451315a1350SMichael S. Tsirkin     int s;
2452315a1350SMichael S. Tsirkin 
2453568f0690SDavid Gibson     root_bus_path = pci_root_bus_path(d);
2454568f0690SDavid Gibson     root_bus_len = strlen(root_bus_path);
2455568f0690SDavid Gibson 
2456315a1350SMichael S. Tsirkin     /* Calculate # of slots on path between device and root. */;
2457315a1350SMichael S. Tsirkin     slot_depth = 0;
2458fd56e061SDavid Gibson     for (t = d; t; t = pci_get_bus(t)->parent_dev) {
2459315a1350SMichael S. Tsirkin         ++slot_depth;
2460315a1350SMichael S. Tsirkin     }
2461315a1350SMichael S. Tsirkin 
2462568f0690SDavid Gibson     path_len = root_bus_len + slot_len * slot_depth;
2463315a1350SMichael S. Tsirkin 
2464315a1350SMichael S. Tsirkin     /* Allocate memory, fill in the terminating null byte. */
2465315a1350SMichael S. Tsirkin     path = g_malloc(path_len + 1 /* For '\0' */);
2466315a1350SMichael S. Tsirkin     path[path_len] = '\0';
2467315a1350SMichael S. Tsirkin 
2468568f0690SDavid Gibson     memcpy(path, root_bus_path, root_bus_len);
2469315a1350SMichael S. Tsirkin 
2470315a1350SMichael S. Tsirkin     /* Fill in slot numbers. We walk up from device to root, so need to print
2471315a1350SMichael S. Tsirkin      * them in the reverse order, last to first. */
2472315a1350SMichael S. Tsirkin     p = path + path_len;
2473fd56e061SDavid Gibson     for (t = d; t; t = pci_get_bus(t)->parent_dev) {
2474315a1350SMichael S. Tsirkin         p -= slot_len;
2475315a1350SMichael S. Tsirkin         s = snprintf(slot, sizeof slot, ":%02x.%x",
2476315a1350SMichael S. Tsirkin                      PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
2477315a1350SMichael S. Tsirkin         assert(s == slot_len);
2478315a1350SMichael S. Tsirkin         memcpy(p, slot, slot_len);
2479315a1350SMichael S. Tsirkin     }
2480315a1350SMichael S. Tsirkin 
2481315a1350SMichael S. Tsirkin     return path;
2482315a1350SMichael S. Tsirkin }
2483315a1350SMichael S. Tsirkin 
2484315a1350SMichael S. Tsirkin static int pci_qdev_find_recursive(PCIBus *bus,
2485315a1350SMichael S. Tsirkin                                    const char *id, PCIDevice **pdev)
2486315a1350SMichael S. Tsirkin {
2487315a1350SMichael S. Tsirkin     DeviceState *qdev = qdev_find_recursive(&bus->qbus, id);
2488315a1350SMichael S. Tsirkin     if (!qdev) {
2489315a1350SMichael S. Tsirkin         return -ENODEV;
2490315a1350SMichael S. Tsirkin     }
2491315a1350SMichael S. Tsirkin 
2492315a1350SMichael S. Tsirkin     /* roughly check if given qdev is pci device */
2493315a1350SMichael S. Tsirkin     if (object_dynamic_cast(OBJECT(qdev), TYPE_PCI_DEVICE)) {
2494315a1350SMichael S. Tsirkin         *pdev = PCI_DEVICE(qdev);
2495315a1350SMichael S. Tsirkin         return 0;
2496315a1350SMichael S. Tsirkin     }
2497315a1350SMichael S. Tsirkin     return -EINVAL;
2498315a1350SMichael S. Tsirkin }
2499315a1350SMichael S. Tsirkin 
2500315a1350SMichael S. Tsirkin int pci_qdev_find_device(const char *id, PCIDevice **pdev)
2501315a1350SMichael S. Tsirkin {
25027588e2b0SDavid Gibson     PCIHostState *host_bridge;
2503315a1350SMichael S. Tsirkin     int rc = -ENODEV;
2504315a1350SMichael S. Tsirkin 
25057588e2b0SDavid Gibson     QLIST_FOREACH(host_bridge, &pci_host_bridges, next) {
25067588e2b0SDavid Gibson         int tmp = pci_qdev_find_recursive(host_bridge->bus, id, pdev);
2507315a1350SMichael S. Tsirkin         if (!tmp) {
2508315a1350SMichael S. Tsirkin             rc = 0;
2509315a1350SMichael S. Tsirkin             break;
2510315a1350SMichael S. Tsirkin         }
2511315a1350SMichael S. Tsirkin         if (tmp != -ENODEV) {
2512315a1350SMichael S. Tsirkin             rc = tmp;
2513315a1350SMichael S. Tsirkin         }
2514315a1350SMichael S. Tsirkin     }
2515315a1350SMichael S. Tsirkin 
2516315a1350SMichael S. Tsirkin     return rc;
2517315a1350SMichael S. Tsirkin }
2518315a1350SMichael S. Tsirkin 
2519315a1350SMichael S. Tsirkin MemoryRegion *pci_address_space(PCIDevice *dev)
2520315a1350SMichael S. Tsirkin {
2521fd56e061SDavid Gibson     return pci_get_bus(dev)->address_space_mem;
2522315a1350SMichael S. Tsirkin }
2523315a1350SMichael S. Tsirkin 
2524315a1350SMichael S. Tsirkin MemoryRegion *pci_address_space_io(PCIDevice *dev)
2525315a1350SMichael S. Tsirkin {
2526fd56e061SDavid Gibson     return pci_get_bus(dev)->address_space_io;
2527315a1350SMichael S. Tsirkin }
2528315a1350SMichael S. Tsirkin 
2529315a1350SMichael S. Tsirkin static void pci_device_class_init(ObjectClass *klass, void *data)
2530315a1350SMichael S. Tsirkin {
2531315a1350SMichael S. Tsirkin     DeviceClass *k = DEVICE_CLASS(klass);
25327ee6c1e1SMarkus Armbruster     PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
25337ee6c1e1SMarkus Armbruster 
2534133e9b22SMarkus Armbruster     k->realize = pci_qdev_realize;
2535133e9b22SMarkus Armbruster     k->unrealize = pci_qdev_unrealize;
2536315a1350SMichael S. Tsirkin     k->bus_type = TYPE_PCI_BUS;
2537315a1350SMichael S. Tsirkin     k->props = pci_props;
25387ee6c1e1SMarkus Armbruster     pc->realize = pci_default_realize;
2539315a1350SMichael S. Tsirkin }
2540315a1350SMichael S. Tsirkin 
25412fefa16cSEduardo Habkost static void pci_device_class_base_init(ObjectClass *klass, void *data)
25422fefa16cSEduardo Habkost {
25432fefa16cSEduardo Habkost     if (!object_class_is_abstract(klass)) {
25442fefa16cSEduardo Habkost         ObjectClass *conventional =
25452fefa16cSEduardo Habkost             object_class_dynamic_cast(klass, INTERFACE_CONVENTIONAL_PCI_DEVICE);
25462fefa16cSEduardo Habkost         ObjectClass *pcie =
25472fefa16cSEduardo Habkost             object_class_dynamic_cast(klass, INTERFACE_PCIE_DEVICE);
25482fefa16cSEduardo Habkost         assert(conventional || pcie);
25492fefa16cSEduardo Habkost     }
25502fefa16cSEduardo Habkost }
25512fefa16cSEduardo Habkost 
25529eda7d37SAlexey Kardashevskiy AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
25539eda7d37SAlexey Kardashevskiy {
2554fd56e061SDavid Gibson     PCIBus *bus = pci_get_bus(dev);
25555af2ae23SBenjamin Herrenschmidt     PCIBus *iommu_bus = bus;
25569eda7d37SAlexey Kardashevskiy 
25575af2ae23SBenjamin Herrenschmidt     while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus->parent_dev) {
2558fd56e061SDavid Gibson         iommu_bus = pci_get_bus(iommu_bus->parent_dev);
25599eda7d37SAlexey Kardashevskiy     }
25605af2ae23SBenjamin Herrenschmidt     if (iommu_bus && iommu_bus->iommu_fn) {
25615af2ae23SBenjamin Herrenschmidt         return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev->devfn);
25629eda7d37SAlexey Kardashevskiy     }
25639eda7d37SAlexey Kardashevskiy     return &address_space_memory;
25649eda7d37SAlexey Kardashevskiy }
25659eda7d37SAlexey Kardashevskiy 
2566e00387d5SAvi Kivity void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque)
2567315a1350SMichael S. Tsirkin {
2568e00387d5SAvi Kivity     bus->iommu_fn = fn;
2569e00387d5SAvi Kivity     bus->iommu_opaque = opaque;
2570315a1350SMichael S. Tsirkin }
2571315a1350SMichael S. Tsirkin 
257243864069SMichael S. Tsirkin static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
257343864069SMichael S. Tsirkin {
257443864069SMichael S. Tsirkin     Range *range = opaque;
257543864069SMichael S. Tsirkin     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
257643864069SMichael S. Tsirkin     uint16_t cmd = pci_get_word(dev->config + PCI_COMMAND);
257777d6f4eaSMichael S. Tsirkin     int i;
257843864069SMichael S. Tsirkin 
257943864069SMichael S. Tsirkin     if (!(cmd & PCI_COMMAND_MEMORY)) {
258043864069SMichael S. Tsirkin         return;
258143864069SMichael S. Tsirkin     }
258243864069SMichael S. Tsirkin 
258343864069SMichael S. Tsirkin     if (pc->is_bridge) {
258443864069SMichael S. Tsirkin         pcibus_t base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
258543864069SMichael S. Tsirkin         pcibus_t limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
258643864069SMichael S. Tsirkin 
258743864069SMichael S. Tsirkin         base = MAX(base, 0x1ULL << 32);
258843864069SMichael S. Tsirkin 
258943864069SMichael S. Tsirkin         if (limit >= base) {
259043864069SMichael S. Tsirkin             Range pref_range;
2591a0efbf16SMarkus Armbruster             range_set_bounds(&pref_range, base, limit);
259243864069SMichael S. Tsirkin             range_extend(range, &pref_range);
259343864069SMichael S. Tsirkin         }
259443864069SMichael S. Tsirkin     }
259577d6f4eaSMichael S. Tsirkin     for (i = 0; i < PCI_NUM_REGIONS; ++i) {
259677d6f4eaSMichael S. Tsirkin         PCIIORegion *r = &dev->io_regions[i];
2597a0efbf16SMarkus Armbruster         pcibus_t lob, upb;
259843864069SMichael S. Tsirkin         Range region_range;
259943864069SMichael S. Tsirkin 
260077d6f4eaSMichael S. Tsirkin         if (!r->size ||
260177d6f4eaSMichael S. Tsirkin             (r->type & PCI_BASE_ADDRESS_SPACE_IO) ||
260277d6f4eaSMichael S. Tsirkin             !(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64)) {
260343864069SMichael S. Tsirkin             continue;
260443864069SMichael S. Tsirkin         }
260577d6f4eaSMichael S. Tsirkin 
2606a0efbf16SMarkus Armbruster         lob = pci_bar_address(dev, i, r->type, r->size);
2607a0efbf16SMarkus Armbruster         upb = lob + r->size - 1;
2608a0efbf16SMarkus Armbruster         if (lob == PCI_BAR_UNMAPPED) {
260977d6f4eaSMichael S. Tsirkin             continue;
261077d6f4eaSMichael S. Tsirkin         }
261143864069SMichael S. Tsirkin 
2612a0efbf16SMarkus Armbruster         lob = MAX(lob, 0x1ULL << 32);
261343864069SMichael S. Tsirkin 
2614a0efbf16SMarkus Armbruster         if (upb >= lob) {
2615a0efbf16SMarkus Armbruster             range_set_bounds(&region_range, lob, upb);
261643864069SMichael S. Tsirkin             range_extend(range, &region_range);
261743864069SMichael S. Tsirkin         }
261843864069SMichael S. Tsirkin     }
261943864069SMichael S. Tsirkin }
262043864069SMichael S. Tsirkin 
262143864069SMichael S. Tsirkin void pci_bus_get_w64_range(PCIBus *bus, Range *range)
262243864069SMichael S. Tsirkin {
2623a0efbf16SMarkus Armbruster     range_make_empty(range);
262443864069SMichael S. Tsirkin     pci_for_each_device_under_bus(bus, pci_dev_get_w64, range);
262543864069SMichael S. Tsirkin }
262643864069SMichael S. Tsirkin 
26273f1e1478SCao jin static bool pcie_has_upstream_port(PCIDevice *dev)
26283f1e1478SCao jin {
2629fd56e061SDavid Gibson     PCIDevice *parent_dev = pci_bridge_get_device(pci_get_bus(dev));
26303f1e1478SCao jin 
26313f1e1478SCao jin     /* Device associated with an upstream port.
26323f1e1478SCao jin      * As there are several types of these, it's easier to check the
26333f1e1478SCao jin      * parent device: upstream ports are always connected to
26343f1e1478SCao jin      * root or downstream ports.
26353f1e1478SCao jin      */
26363f1e1478SCao jin     return parent_dev &&
26373f1e1478SCao jin         pci_is_express(parent_dev) &&
26383f1e1478SCao jin         parent_dev->exp.exp_cap &&
26393f1e1478SCao jin         (pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_ROOT_PORT ||
26403f1e1478SCao jin          pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_DOWNSTREAM);
26413f1e1478SCao jin }
26423f1e1478SCao jin 
26433f1e1478SCao jin PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
26443f1e1478SCao jin {
2645fd56e061SDavid Gibson     PCIBus *bus = pci_get_bus(pci_dev);
2646fd56e061SDavid Gibson 
26473f1e1478SCao jin     if(pcie_has_upstream_port(pci_dev)) {
26483f1e1478SCao jin         /* With an upstream PCIe port, we only support 1 device at slot 0 */
2649fd56e061SDavid Gibson         return bus->devices[0];
26503f1e1478SCao jin     } else {
26513f1e1478SCao jin         /* Other bus types might support multiple devices at slots 0-31 */
2652fd56e061SDavid Gibson         return bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
26533f1e1478SCao jin     }
26543f1e1478SCao jin }
26553f1e1478SCao jin 
2656e1d4fb2dSPeter Xu MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
2657e1d4fb2dSPeter Xu {
2658e1d4fb2dSPeter Xu     MSIMessage msg;
2659e1d4fb2dSPeter Xu     if (msix_enabled(dev)) {
2660e1d4fb2dSPeter Xu         msg = msix_get_message(dev, vector);
2661e1d4fb2dSPeter Xu     } else if (msi_enabled(dev)) {
2662e1d4fb2dSPeter Xu         msg = msi_get_message(dev, vector);
2663e1d4fb2dSPeter Xu     } else {
2664e1d4fb2dSPeter Xu         /* Should never happen */
2665e1d4fb2dSPeter Xu         error_report("%s: unknown interrupt type", __func__);
2666e1d4fb2dSPeter Xu         abort();
2667e1d4fb2dSPeter Xu     }
2668e1d4fb2dSPeter Xu     return msg;
2669e1d4fb2dSPeter Xu }
2670e1d4fb2dSPeter Xu 
26718c43a6f0SAndreas Färber static const TypeInfo pci_device_type_info = {
2672315a1350SMichael S. Tsirkin     .name = TYPE_PCI_DEVICE,
2673315a1350SMichael S. Tsirkin     .parent = TYPE_DEVICE,
2674315a1350SMichael S. Tsirkin     .instance_size = sizeof(PCIDevice),
2675315a1350SMichael S. Tsirkin     .abstract = true,
2676315a1350SMichael S. Tsirkin     .class_size = sizeof(PCIDeviceClass),
2677315a1350SMichael S. Tsirkin     .class_init = pci_device_class_init,
26782fefa16cSEduardo Habkost     .class_base_init = pci_device_class_base_init,
2679315a1350SMichael S. Tsirkin };
2680315a1350SMichael S. Tsirkin 
2681315a1350SMichael S. Tsirkin static void pci_register_types(void)
2682315a1350SMichael S. Tsirkin {
2683315a1350SMichael S. Tsirkin     type_register_static(&pci_bus_info);
26843a861c46SAlex Williamson     type_register_static(&pcie_bus_info);
2685619f02aeSEduardo Habkost     type_register_static(&conventional_pci_interface_info);
2686619f02aeSEduardo Habkost     type_register_static(&pcie_interface_info);
2687315a1350SMichael S. Tsirkin     type_register_static(&pci_device_type_info);
2688315a1350SMichael S. Tsirkin }
2689315a1350SMichael S. Tsirkin 
2690315a1350SMichael S. Tsirkin type_init(pci_register_types)
2691