xref: /openbmc/qemu/hw/pci/pci.c (revision 022c62cb)
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  */
24c759b24fSMichael S. Tsirkin #include "hw/hw.h"
25c759b24fSMichael S. Tsirkin #include "hw/pci/pci.h"
26c759b24fSMichael S. Tsirkin #include "hw/pci/pci_bridge.h"
2706aac7bdSMichael S. Tsirkin #include "hw/pci/pci_bus.h"
28315a1350SMichael S. Tsirkin #include "monitor.h"
291422e32dSPaolo Bonzini #include "net/net.h"
30315a1350SMichael S. Tsirkin #include "sysemu.h"
31c759b24fSMichael S. Tsirkin #include "hw/loader.h"
32315a1350SMichael S. Tsirkin #include "range.h"
33315a1350SMichael S. Tsirkin #include "qmp-commands.h"
34c759b24fSMichael S. Tsirkin #include "hw/pci/msi.h"
35c759b24fSMichael S. Tsirkin #include "hw/pci/msix.h"
36*022c62cbSPaolo Bonzini #include "exec/address-spaces.h"
37315a1350SMichael S. Tsirkin 
38315a1350SMichael S. Tsirkin //#define DEBUG_PCI
39315a1350SMichael S. Tsirkin #ifdef DEBUG_PCI
40315a1350SMichael S. Tsirkin # define PCI_DPRINTF(format, ...)       printf(format, ## __VA_ARGS__)
41315a1350SMichael S. Tsirkin #else
42315a1350SMichael S. Tsirkin # define PCI_DPRINTF(format, ...)       do { } while (0)
43315a1350SMichael S. Tsirkin #endif
44315a1350SMichael S. Tsirkin 
45315a1350SMichael S. Tsirkin static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
46315a1350SMichael S. Tsirkin static char *pcibus_get_dev_path(DeviceState *dev);
47315a1350SMichael S. Tsirkin static char *pcibus_get_fw_dev_path(DeviceState *dev);
48315a1350SMichael S. Tsirkin static int pcibus_reset(BusState *qbus);
49315a1350SMichael S. Tsirkin 
50315a1350SMichael S. Tsirkin static Property pci_props[] = {
51315a1350SMichael S. Tsirkin     DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
52315a1350SMichael S. Tsirkin     DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
53315a1350SMichael S. Tsirkin     DEFINE_PROP_UINT32("rombar",  PCIDevice, rom_bar, 1),
54315a1350SMichael S. Tsirkin     DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
55315a1350SMichael S. Tsirkin                     QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
56315a1350SMichael S. Tsirkin     DEFINE_PROP_BIT("command_serr_enable", PCIDevice, cap_present,
57315a1350SMichael S. Tsirkin                     QEMU_PCI_CAP_SERR_BITNR, true),
58315a1350SMichael S. Tsirkin     DEFINE_PROP_END_OF_LIST()
59315a1350SMichael S. Tsirkin };
60315a1350SMichael S. Tsirkin 
61315a1350SMichael S. Tsirkin static void pci_bus_class_init(ObjectClass *klass, void *data)
62315a1350SMichael S. Tsirkin {
63315a1350SMichael S. Tsirkin     BusClass *k = BUS_CLASS(klass);
64315a1350SMichael S. Tsirkin 
65315a1350SMichael S. Tsirkin     k->print_dev = pcibus_dev_print;
66315a1350SMichael S. Tsirkin     k->get_dev_path = pcibus_get_dev_path;
67315a1350SMichael S. Tsirkin     k->get_fw_dev_path = pcibus_get_fw_dev_path;
68315a1350SMichael S. Tsirkin     k->reset = pcibus_reset;
69315a1350SMichael S. Tsirkin }
70315a1350SMichael S. Tsirkin 
71315a1350SMichael S. Tsirkin static const TypeInfo pci_bus_info = {
72315a1350SMichael S. Tsirkin     .name = TYPE_PCI_BUS,
73315a1350SMichael S. Tsirkin     .parent = TYPE_BUS,
74315a1350SMichael S. Tsirkin     .instance_size = sizeof(PCIBus),
75315a1350SMichael S. Tsirkin     .class_init = pci_bus_class_init,
76315a1350SMichael S. Tsirkin };
77315a1350SMichael S. Tsirkin 
78315a1350SMichael S. Tsirkin static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
79315a1350SMichael S. Tsirkin static void pci_update_mappings(PCIDevice *d);
80315a1350SMichael S. Tsirkin static void pci_set_irq(void *opaque, int irq_num, int level);
81315a1350SMichael S. Tsirkin static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom);
82315a1350SMichael S. Tsirkin static void pci_del_option_rom(PCIDevice *pdev);
83315a1350SMichael S. Tsirkin 
84315a1350SMichael S. Tsirkin static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
85315a1350SMichael S. Tsirkin static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
86315a1350SMichael S. Tsirkin 
87315a1350SMichael S. Tsirkin struct PCIHostBus {
88315a1350SMichael S. Tsirkin     int domain;
89315a1350SMichael S. Tsirkin     struct PCIBus *bus;
90315a1350SMichael S. Tsirkin     QLIST_ENTRY(PCIHostBus) next;
91315a1350SMichael S. Tsirkin };
92315a1350SMichael S. Tsirkin static QLIST_HEAD(, PCIHostBus) host_buses;
93315a1350SMichael S. Tsirkin 
94315a1350SMichael S. Tsirkin static const VMStateDescription vmstate_pcibus = {
95315a1350SMichael S. Tsirkin     .name = "PCIBUS",
96315a1350SMichael S. Tsirkin     .version_id = 1,
97315a1350SMichael S. Tsirkin     .minimum_version_id = 1,
98315a1350SMichael S. Tsirkin     .minimum_version_id_old = 1,
99315a1350SMichael S. Tsirkin     .fields      = (VMStateField []) {
100315a1350SMichael S. Tsirkin         VMSTATE_INT32_EQUAL(nirq, PCIBus),
101315a1350SMichael S. Tsirkin         VMSTATE_VARRAY_INT32(irq_count, PCIBus, nirq, 0, vmstate_info_int32, int32_t),
102315a1350SMichael S. Tsirkin         VMSTATE_END_OF_LIST()
103315a1350SMichael S. Tsirkin     }
104315a1350SMichael S. Tsirkin };
105315a1350SMichael S. Tsirkin static int pci_bar(PCIDevice *d, int reg)
106315a1350SMichael S. Tsirkin {
107315a1350SMichael S. Tsirkin     uint8_t type;
108315a1350SMichael S. Tsirkin 
109315a1350SMichael S. Tsirkin     if (reg != PCI_ROM_SLOT)
110315a1350SMichael S. Tsirkin         return PCI_BASE_ADDRESS_0 + reg * 4;
111315a1350SMichael S. Tsirkin 
112315a1350SMichael S. Tsirkin     type = d->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
113315a1350SMichael S. Tsirkin     return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS;
114315a1350SMichael S. Tsirkin }
115315a1350SMichael S. Tsirkin 
116315a1350SMichael S. Tsirkin static inline int pci_irq_state(PCIDevice *d, int irq_num)
117315a1350SMichael S. Tsirkin {
118315a1350SMichael S. Tsirkin 	return (d->irq_state >> irq_num) & 0x1;
119315a1350SMichael S. Tsirkin }
120315a1350SMichael S. Tsirkin 
121315a1350SMichael S. Tsirkin static inline void pci_set_irq_state(PCIDevice *d, int irq_num, int level)
122315a1350SMichael S. Tsirkin {
123315a1350SMichael S. Tsirkin 	d->irq_state &= ~(0x1 << irq_num);
124315a1350SMichael S. Tsirkin 	d->irq_state |= level << irq_num;
125315a1350SMichael S. Tsirkin }
126315a1350SMichael S. Tsirkin 
127315a1350SMichael S. Tsirkin static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
128315a1350SMichael S. Tsirkin {
129315a1350SMichael S. Tsirkin     PCIBus *bus;
130315a1350SMichael S. Tsirkin     for (;;) {
131315a1350SMichael S. Tsirkin         bus = pci_dev->bus;
132315a1350SMichael S. Tsirkin         irq_num = bus->map_irq(pci_dev, irq_num);
133315a1350SMichael S. Tsirkin         if (bus->set_irq)
134315a1350SMichael S. Tsirkin             break;
135315a1350SMichael S. Tsirkin         pci_dev = bus->parent_dev;
136315a1350SMichael S. Tsirkin     }
137315a1350SMichael S. Tsirkin     bus->irq_count[irq_num] += change;
138315a1350SMichael S. Tsirkin     bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
139315a1350SMichael S. Tsirkin }
140315a1350SMichael S. Tsirkin 
141315a1350SMichael S. Tsirkin int pci_bus_get_irq_level(PCIBus *bus, int irq_num)
142315a1350SMichael S. Tsirkin {
143315a1350SMichael S. Tsirkin     assert(irq_num >= 0);
144315a1350SMichael S. Tsirkin     assert(irq_num < bus->nirq);
145315a1350SMichael S. Tsirkin     return !!bus->irq_count[irq_num];
146315a1350SMichael S. Tsirkin }
147315a1350SMichael S. Tsirkin 
148315a1350SMichael S. Tsirkin /* Update interrupt status bit in config space on interrupt
149315a1350SMichael S. Tsirkin  * state change. */
150315a1350SMichael S. Tsirkin static void pci_update_irq_status(PCIDevice *dev)
151315a1350SMichael S. Tsirkin {
152315a1350SMichael S. Tsirkin     if (dev->irq_state) {
153315a1350SMichael S. Tsirkin         dev->config[PCI_STATUS] |= PCI_STATUS_INTERRUPT;
154315a1350SMichael S. Tsirkin     } else {
155315a1350SMichael S. Tsirkin         dev->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
156315a1350SMichael S. Tsirkin     }
157315a1350SMichael S. Tsirkin }
158315a1350SMichael S. Tsirkin 
159315a1350SMichael S. Tsirkin void pci_device_deassert_intx(PCIDevice *dev)
160315a1350SMichael S. Tsirkin {
161315a1350SMichael S. Tsirkin     int i;
162315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
163315a1350SMichael S. Tsirkin         qemu_set_irq(dev->irq[i], 0);
164315a1350SMichael S. Tsirkin     }
165315a1350SMichael S. Tsirkin }
166315a1350SMichael S. Tsirkin 
167315a1350SMichael S. Tsirkin /*
168315a1350SMichael S. Tsirkin  * This function is called on #RST and FLR.
169315a1350SMichael S. Tsirkin  * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
170315a1350SMichael S. Tsirkin  */
171315a1350SMichael S. Tsirkin void pci_device_reset(PCIDevice *dev)
172315a1350SMichael S. Tsirkin {
173315a1350SMichael S. Tsirkin     int r;
174315a1350SMichael S. Tsirkin 
175315a1350SMichael S. Tsirkin     qdev_reset_all(&dev->qdev);
176315a1350SMichael S. Tsirkin 
177315a1350SMichael S. Tsirkin     dev->irq_state = 0;
178315a1350SMichael S. Tsirkin     pci_update_irq_status(dev);
179315a1350SMichael S. Tsirkin     pci_device_deassert_intx(dev);
180315a1350SMichael S. Tsirkin     /* Clear all writable bits */
181315a1350SMichael S. Tsirkin     pci_word_test_and_clear_mask(dev->config + PCI_COMMAND,
182315a1350SMichael S. Tsirkin                                  pci_get_word(dev->wmask + PCI_COMMAND) |
183315a1350SMichael S. Tsirkin                                  pci_get_word(dev->w1cmask + PCI_COMMAND));
184315a1350SMichael S. Tsirkin     pci_word_test_and_clear_mask(dev->config + PCI_STATUS,
185315a1350SMichael S. Tsirkin                                  pci_get_word(dev->wmask + PCI_STATUS) |
186315a1350SMichael S. Tsirkin                                  pci_get_word(dev->w1cmask + PCI_STATUS));
187315a1350SMichael S. Tsirkin     dev->config[PCI_CACHE_LINE_SIZE] = 0x0;
188315a1350SMichael S. Tsirkin     dev->config[PCI_INTERRUPT_LINE] = 0x0;
189315a1350SMichael S. Tsirkin     for (r = 0; r < PCI_NUM_REGIONS; ++r) {
190315a1350SMichael S. Tsirkin         PCIIORegion *region = &dev->io_regions[r];
191315a1350SMichael S. Tsirkin         if (!region->size) {
192315a1350SMichael S. Tsirkin             continue;
193315a1350SMichael S. Tsirkin         }
194315a1350SMichael S. Tsirkin 
195315a1350SMichael S. Tsirkin         if (!(region->type & PCI_BASE_ADDRESS_SPACE_IO) &&
196315a1350SMichael S. Tsirkin             region->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
197315a1350SMichael S. Tsirkin             pci_set_quad(dev->config + pci_bar(dev, r), region->type);
198315a1350SMichael S. Tsirkin         } else {
199315a1350SMichael S. Tsirkin             pci_set_long(dev->config + pci_bar(dev, r), region->type);
200315a1350SMichael S. Tsirkin         }
201315a1350SMichael S. Tsirkin     }
202315a1350SMichael S. Tsirkin     pci_update_mappings(dev);
203315a1350SMichael S. Tsirkin 
204315a1350SMichael S. Tsirkin     msi_reset(dev);
205315a1350SMichael S. Tsirkin     msix_reset(dev);
206315a1350SMichael S. Tsirkin }
207315a1350SMichael S. Tsirkin 
208315a1350SMichael S. Tsirkin /*
209315a1350SMichael S. Tsirkin  * Trigger pci bus reset under a given bus.
210315a1350SMichael S. Tsirkin  * To be called on RST# assert.
211315a1350SMichael S. Tsirkin  */
212315a1350SMichael S. Tsirkin void pci_bus_reset(PCIBus *bus)
213315a1350SMichael S. Tsirkin {
214315a1350SMichael S. Tsirkin     int i;
215315a1350SMichael S. Tsirkin 
216315a1350SMichael S. Tsirkin     for (i = 0; i < bus->nirq; i++) {
217315a1350SMichael S. Tsirkin         bus->irq_count[i] = 0;
218315a1350SMichael S. Tsirkin     }
219315a1350SMichael S. Tsirkin     for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
220315a1350SMichael S. Tsirkin         if (bus->devices[i]) {
221315a1350SMichael S. Tsirkin             pci_device_reset(bus->devices[i]);
222315a1350SMichael S. Tsirkin         }
223315a1350SMichael S. Tsirkin     }
224315a1350SMichael S. Tsirkin }
225315a1350SMichael S. Tsirkin 
226315a1350SMichael S. Tsirkin static int pcibus_reset(BusState *qbus)
227315a1350SMichael S. Tsirkin {
228315a1350SMichael S. Tsirkin     pci_bus_reset(DO_UPCAST(PCIBus, qbus, qbus));
229315a1350SMichael S. Tsirkin 
230315a1350SMichael S. Tsirkin     /* topology traverse is done by pci_bus_reset().
231315a1350SMichael S. Tsirkin        Tell qbus/qdev walker not to traverse the tree */
232315a1350SMichael S. Tsirkin     return 1;
233315a1350SMichael S. Tsirkin }
234315a1350SMichael S. Tsirkin 
235315a1350SMichael S. Tsirkin static void pci_host_bus_register(int domain, PCIBus *bus)
236315a1350SMichael S. Tsirkin {
237315a1350SMichael S. Tsirkin     struct PCIHostBus *host;
238315a1350SMichael S. Tsirkin     host = g_malloc0(sizeof(*host));
239315a1350SMichael S. Tsirkin     host->domain = domain;
240315a1350SMichael S. Tsirkin     host->bus = bus;
241315a1350SMichael S. Tsirkin     QLIST_INSERT_HEAD(&host_buses, host, next);
242315a1350SMichael S. Tsirkin }
243315a1350SMichael S. Tsirkin 
244315a1350SMichael S. Tsirkin PCIBus *pci_find_root_bus(int domain)
245315a1350SMichael S. Tsirkin {
246315a1350SMichael S. Tsirkin     struct PCIHostBus *host;
247315a1350SMichael S. Tsirkin 
248315a1350SMichael S. Tsirkin     QLIST_FOREACH(host, &host_buses, next) {
249315a1350SMichael S. Tsirkin         if (host->domain == domain) {
250315a1350SMichael S. Tsirkin             return host->bus;
251315a1350SMichael S. Tsirkin         }
252315a1350SMichael S. Tsirkin     }
253315a1350SMichael S. Tsirkin 
254315a1350SMichael S. Tsirkin     return NULL;
255315a1350SMichael S. Tsirkin }
256315a1350SMichael S. Tsirkin 
257315a1350SMichael S. Tsirkin int pci_find_domain(const PCIBus *bus)
258315a1350SMichael S. Tsirkin {
259315a1350SMichael S. Tsirkin     PCIDevice *d;
260315a1350SMichael S. Tsirkin     struct PCIHostBus *host;
261315a1350SMichael S. Tsirkin 
262315a1350SMichael S. Tsirkin     /* obtain root bus */
263315a1350SMichael S. Tsirkin     while ((d = bus->parent_dev) != NULL) {
264315a1350SMichael S. Tsirkin         bus = d->bus;
265315a1350SMichael S. Tsirkin     }
266315a1350SMichael S. Tsirkin 
267315a1350SMichael S. Tsirkin     QLIST_FOREACH(host, &host_buses, next) {
268315a1350SMichael S. Tsirkin         if (host->bus == bus) {
269315a1350SMichael S. Tsirkin             return host->domain;
270315a1350SMichael S. Tsirkin         }
271315a1350SMichael S. Tsirkin     }
272315a1350SMichael S. Tsirkin 
273315a1350SMichael S. Tsirkin     abort();    /* should not be reached */
274315a1350SMichael S. Tsirkin     return -1;
275315a1350SMichael S. Tsirkin }
276315a1350SMichael S. Tsirkin 
277315a1350SMichael S. Tsirkin void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
278315a1350SMichael S. Tsirkin                          const char *name,
279315a1350SMichael S. Tsirkin                          MemoryRegion *address_space_mem,
280315a1350SMichael S. Tsirkin                          MemoryRegion *address_space_io,
281315a1350SMichael S. Tsirkin                          uint8_t devfn_min)
282315a1350SMichael S. Tsirkin {
283315a1350SMichael S. Tsirkin     qbus_create_inplace(&bus->qbus, TYPE_PCI_BUS, parent, name);
284315a1350SMichael S. Tsirkin     assert(PCI_FUNC(devfn_min) == 0);
285315a1350SMichael S. Tsirkin     bus->devfn_min = devfn_min;
286315a1350SMichael S. Tsirkin     bus->address_space_mem = address_space_mem;
287315a1350SMichael S. Tsirkin     bus->address_space_io = address_space_io;
288315a1350SMichael S. Tsirkin 
289315a1350SMichael S. Tsirkin     /* host bridge */
290315a1350SMichael S. Tsirkin     QLIST_INIT(&bus->child);
291315a1350SMichael S. Tsirkin     pci_host_bus_register(0, bus); /* for now only pci domain 0 is supported */
292315a1350SMichael S. Tsirkin 
293315a1350SMichael S. Tsirkin     vmstate_register(NULL, -1, &vmstate_pcibus, bus);
294315a1350SMichael S. Tsirkin }
295315a1350SMichael S. Tsirkin 
296315a1350SMichael S. Tsirkin PCIBus *pci_bus_new(DeviceState *parent, const char *name,
297315a1350SMichael S. Tsirkin                     MemoryRegion *address_space_mem,
298315a1350SMichael S. Tsirkin                     MemoryRegion *address_space_io,
299315a1350SMichael S. Tsirkin                     uint8_t devfn_min)
300315a1350SMichael S. Tsirkin {
301315a1350SMichael S. Tsirkin     PCIBus *bus;
302315a1350SMichael S. Tsirkin 
303315a1350SMichael S. Tsirkin     bus = g_malloc0(sizeof(*bus));
304315a1350SMichael S. Tsirkin     pci_bus_new_inplace(bus, parent, name, address_space_mem,
305315a1350SMichael S. Tsirkin                         address_space_io, devfn_min);
306315a1350SMichael S. Tsirkin     OBJECT(bus)->free = g_free;
307315a1350SMichael S. Tsirkin     return bus;
308315a1350SMichael S. Tsirkin }
309315a1350SMichael S. Tsirkin 
310315a1350SMichael S. Tsirkin void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
311315a1350SMichael S. Tsirkin                   void *irq_opaque, int nirq)
312315a1350SMichael S. Tsirkin {
313315a1350SMichael S. Tsirkin     bus->set_irq = set_irq;
314315a1350SMichael S. Tsirkin     bus->map_irq = map_irq;
315315a1350SMichael S. Tsirkin     bus->irq_opaque = irq_opaque;
316315a1350SMichael S. Tsirkin     bus->nirq = nirq;
317315a1350SMichael S. Tsirkin     bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
318315a1350SMichael S. Tsirkin }
319315a1350SMichael S. Tsirkin 
320315a1350SMichael S. Tsirkin void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *qdev)
321315a1350SMichael S. Tsirkin {
322315a1350SMichael S. Tsirkin     bus->qbus.allow_hotplug = 1;
323315a1350SMichael S. Tsirkin     bus->hotplug = hotplug;
324315a1350SMichael S. Tsirkin     bus->hotplug_qdev = qdev;
325315a1350SMichael S. Tsirkin }
326315a1350SMichael S. Tsirkin 
327315a1350SMichael S. Tsirkin PCIBus *pci_register_bus(DeviceState *parent, const char *name,
328315a1350SMichael S. Tsirkin                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
329315a1350SMichael S. Tsirkin                          void *irq_opaque,
330315a1350SMichael S. Tsirkin                          MemoryRegion *address_space_mem,
331315a1350SMichael S. Tsirkin                          MemoryRegion *address_space_io,
332315a1350SMichael S. Tsirkin                          uint8_t devfn_min, int nirq)
333315a1350SMichael S. Tsirkin {
334315a1350SMichael S. Tsirkin     PCIBus *bus;
335315a1350SMichael S. Tsirkin 
336315a1350SMichael S. Tsirkin     bus = pci_bus_new(parent, name, address_space_mem,
337315a1350SMichael S. Tsirkin                       address_space_io, devfn_min);
338315a1350SMichael S. Tsirkin     pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
339315a1350SMichael S. Tsirkin     return bus;
340315a1350SMichael S. Tsirkin }
341315a1350SMichael S. Tsirkin 
342315a1350SMichael S. Tsirkin int pci_bus_num(PCIBus *s)
343315a1350SMichael S. Tsirkin {
344315a1350SMichael S. Tsirkin     if (!s->parent_dev)
345315a1350SMichael S. Tsirkin         return 0;       /* pci host bridge */
346315a1350SMichael S. Tsirkin     return s->parent_dev->config[PCI_SECONDARY_BUS];
347315a1350SMichael S. Tsirkin }
348315a1350SMichael S. Tsirkin 
349315a1350SMichael S. Tsirkin static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
350315a1350SMichael S. Tsirkin {
351315a1350SMichael S. Tsirkin     PCIDevice *s = container_of(pv, PCIDevice, config);
352315a1350SMichael S. Tsirkin     uint8_t *config;
353315a1350SMichael S. Tsirkin     int i;
354315a1350SMichael S. Tsirkin 
355315a1350SMichael S. Tsirkin     assert(size == pci_config_size(s));
356315a1350SMichael S. Tsirkin     config = g_malloc(size);
357315a1350SMichael S. Tsirkin 
358315a1350SMichael S. Tsirkin     qemu_get_buffer(f, config, size);
359315a1350SMichael S. Tsirkin     for (i = 0; i < size; ++i) {
360315a1350SMichael S. Tsirkin         if ((config[i] ^ s->config[i]) &
361315a1350SMichael S. Tsirkin             s->cmask[i] & ~s->wmask[i] & ~s->w1cmask[i]) {
362315a1350SMichael S. Tsirkin             g_free(config);
363315a1350SMichael S. Tsirkin             return -EINVAL;
364315a1350SMichael S. Tsirkin         }
365315a1350SMichael S. Tsirkin     }
366315a1350SMichael S. Tsirkin     memcpy(s->config, config, size);
367315a1350SMichael S. Tsirkin 
368315a1350SMichael S. Tsirkin     pci_update_mappings(s);
369315a1350SMichael S. Tsirkin 
370315a1350SMichael S. Tsirkin     memory_region_set_enabled(&s->bus_master_enable_region,
371315a1350SMichael S. Tsirkin                               pci_get_word(s->config + PCI_COMMAND)
372315a1350SMichael S. Tsirkin                               & PCI_COMMAND_MASTER);
373315a1350SMichael S. Tsirkin 
374315a1350SMichael S. Tsirkin     g_free(config);
375315a1350SMichael S. Tsirkin     return 0;
376315a1350SMichael S. Tsirkin }
377315a1350SMichael S. Tsirkin 
378315a1350SMichael S. Tsirkin /* just put buffer */
379315a1350SMichael S. Tsirkin static void put_pci_config_device(QEMUFile *f, void *pv, size_t size)
380315a1350SMichael S. Tsirkin {
381315a1350SMichael S. Tsirkin     const uint8_t **v = pv;
382315a1350SMichael S. Tsirkin     assert(size == pci_config_size(container_of(pv, PCIDevice, config)));
383315a1350SMichael S. Tsirkin     qemu_put_buffer(f, *v, size);
384315a1350SMichael S. Tsirkin }
385315a1350SMichael S. Tsirkin 
386315a1350SMichael S. Tsirkin static VMStateInfo vmstate_info_pci_config = {
387315a1350SMichael S. Tsirkin     .name = "pci config",
388315a1350SMichael S. Tsirkin     .get  = get_pci_config_device,
389315a1350SMichael S. Tsirkin     .put  = put_pci_config_device,
390315a1350SMichael S. Tsirkin };
391315a1350SMichael S. Tsirkin 
392315a1350SMichael S. Tsirkin static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size)
393315a1350SMichael S. Tsirkin {
394315a1350SMichael S. Tsirkin     PCIDevice *s = container_of(pv, PCIDevice, irq_state);
395315a1350SMichael S. Tsirkin     uint32_t irq_state[PCI_NUM_PINS];
396315a1350SMichael S. Tsirkin     int i;
397315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
398315a1350SMichael S. Tsirkin         irq_state[i] = qemu_get_be32(f);
399315a1350SMichael S. Tsirkin         if (irq_state[i] != 0x1 && irq_state[i] != 0) {
400315a1350SMichael S. Tsirkin             fprintf(stderr, "irq state %d: must be 0 or 1.\n",
401315a1350SMichael S. Tsirkin                     irq_state[i]);
402315a1350SMichael S. Tsirkin             return -EINVAL;
403315a1350SMichael S. Tsirkin         }
404315a1350SMichael S. Tsirkin     }
405315a1350SMichael S. Tsirkin 
406315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
407315a1350SMichael S. Tsirkin         pci_set_irq_state(s, i, irq_state[i]);
408315a1350SMichael S. Tsirkin     }
409315a1350SMichael S. Tsirkin 
410315a1350SMichael S. Tsirkin     return 0;
411315a1350SMichael S. Tsirkin }
412315a1350SMichael S. Tsirkin 
413315a1350SMichael S. Tsirkin static void put_pci_irq_state(QEMUFile *f, void *pv, size_t size)
414315a1350SMichael S. Tsirkin {
415315a1350SMichael S. Tsirkin     int i;
416315a1350SMichael S. Tsirkin     PCIDevice *s = container_of(pv, PCIDevice, irq_state);
417315a1350SMichael S. Tsirkin 
418315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
419315a1350SMichael S. Tsirkin         qemu_put_be32(f, pci_irq_state(s, i));
420315a1350SMichael S. Tsirkin     }
421315a1350SMichael S. Tsirkin }
422315a1350SMichael S. Tsirkin 
423315a1350SMichael S. Tsirkin static VMStateInfo vmstate_info_pci_irq_state = {
424315a1350SMichael S. Tsirkin     .name = "pci irq state",
425315a1350SMichael S. Tsirkin     .get  = get_pci_irq_state,
426315a1350SMichael S. Tsirkin     .put  = put_pci_irq_state,
427315a1350SMichael S. Tsirkin };
428315a1350SMichael S. Tsirkin 
429315a1350SMichael S. Tsirkin const VMStateDescription vmstate_pci_device = {
430315a1350SMichael S. Tsirkin     .name = "PCIDevice",
431315a1350SMichael S. Tsirkin     .version_id = 2,
432315a1350SMichael S. Tsirkin     .minimum_version_id = 1,
433315a1350SMichael S. Tsirkin     .minimum_version_id_old = 1,
434315a1350SMichael S. Tsirkin     .fields      = (VMStateField []) {
435315a1350SMichael S. Tsirkin         VMSTATE_INT32_LE(version_id, PCIDevice),
436315a1350SMichael S. Tsirkin         VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
437315a1350SMichael S. Tsirkin                                    vmstate_info_pci_config,
438315a1350SMichael S. Tsirkin                                    PCI_CONFIG_SPACE_SIZE),
439315a1350SMichael S. Tsirkin         VMSTATE_BUFFER_UNSAFE_INFO(irq_state, PCIDevice, 2,
440315a1350SMichael S. Tsirkin 				   vmstate_info_pci_irq_state,
441315a1350SMichael S. Tsirkin 				   PCI_NUM_PINS * sizeof(int32_t)),
442315a1350SMichael S. Tsirkin         VMSTATE_END_OF_LIST()
443315a1350SMichael S. Tsirkin     }
444315a1350SMichael S. Tsirkin };
445315a1350SMichael S. Tsirkin 
446315a1350SMichael S. Tsirkin const VMStateDescription vmstate_pcie_device = {
447315a1350SMichael S. Tsirkin     .name = "PCIEDevice",
448315a1350SMichael S. Tsirkin     .version_id = 2,
449315a1350SMichael S. Tsirkin     .minimum_version_id = 1,
450315a1350SMichael S. Tsirkin     .minimum_version_id_old = 1,
451315a1350SMichael S. Tsirkin     .fields      = (VMStateField []) {
452315a1350SMichael S. Tsirkin         VMSTATE_INT32_LE(version_id, PCIDevice),
453315a1350SMichael S. Tsirkin         VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
454315a1350SMichael S. Tsirkin                                    vmstate_info_pci_config,
455315a1350SMichael S. Tsirkin                                    PCIE_CONFIG_SPACE_SIZE),
456315a1350SMichael S. Tsirkin         VMSTATE_BUFFER_UNSAFE_INFO(irq_state, PCIDevice, 2,
457315a1350SMichael S. Tsirkin 				   vmstate_info_pci_irq_state,
458315a1350SMichael S. Tsirkin 				   PCI_NUM_PINS * sizeof(int32_t)),
459315a1350SMichael S. Tsirkin         VMSTATE_END_OF_LIST()
460315a1350SMichael S. Tsirkin     }
461315a1350SMichael S. Tsirkin };
462315a1350SMichael S. Tsirkin 
463315a1350SMichael S. Tsirkin static inline const VMStateDescription *pci_get_vmstate(PCIDevice *s)
464315a1350SMichael S. Tsirkin {
465315a1350SMichael S. Tsirkin     return pci_is_express(s) ? &vmstate_pcie_device : &vmstate_pci_device;
466315a1350SMichael S. Tsirkin }
467315a1350SMichael S. Tsirkin 
468315a1350SMichael S. Tsirkin void pci_device_save(PCIDevice *s, QEMUFile *f)
469315a1350SMichael S. Tsirkin {
470315a1350SMichael S. Tsirkin     /* Clear interrupt status bit: it is implicit
471315a1350SMichael S. Tsirkin      * in irq_state which we are saving.
472315a1350SMichael S. Tsirkin      * This makes us compatible with old devices
473315a1350SMichael S. Tsirkin      * which never set or clear this bit. */
474315a1350SMichael S. Tsirkin     s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
475315a1350SMichael S. Tsirkin     vmstate_save_state(f, pci_get_vmstate(s), s);
476315a1350SMichael S. Tsirkin     /* Restore the interrupt status bit. */
477315a1350SMichael S. Tsirkin     pci_update_irq_status(s);
478315a1350SMichael S. Tsirkin }
479315a1350SMichael S. Tsirkin 
480315a1350SMichael S. Tsirkin int pci_device_load(PCIDevice *s, QEMUFile *f)
481315a1350SMichael S. Tsirkin {
482315a1350SMichael S. Tsirkin     int ret;
483315a1350SMichael S. Tsirkin     ret = vmstate_load_state(f, pci_get_vmstate(s), s, s->version_id);
484315a1350SMichael S. Tsirkin     /* Restore the interrupt status bit. */
485315a1350SMichael S. Tsirkin     pci_update_irq_status(s);
486315a1350SMichael S. Tsirkin     return ret;
487315a1350SMichael S. Tsirkin }
488315a1350SMichael S. Tsirkin 
489315a1350SMichael S. Tsirkin static void pci_set_default_subsystem_id(PCIDevice *pci_dev)
490315a1350SMichael S. Tsirkin {
491315a1350SMichael S. Tsirkin     pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
492315a1350SMichael S. Tsirkin                  pci_default_sub_vendor_id);
493315a1350SMichael S. Tsirkin     pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
494315a1350SMichael S. Tsirkin                  pci_default_sub_device_id);
495315a1350SMichael S. Tsirkin }
496315a1350SMichael S. Tsirkin 
497315a1350SMichael S. Tsirkin /*
498315a1350SMichael S. Tsirkin  * Parse [[<domain>:]<bus>:]<slot>, return -1 on error if funcp == NULL
499315a1350SMichael S. Tsirkin  *       [[<domain>:]<bus>:]<slot>.<func>, return -1 on error
500315a1350SMichael S. Tsirkin  */
501315a1350SMichael S. Tsirkin static int pci_parse_devaddr(const char *addr, int *domp, int *busp,
502315a1350SMichael S. Tsirkin                       unsigned int *slotp, unsigned int *funcp)
503315a1350SMichael S. Tsirkin {
504315a1350SMichael S. Tsirkin     const char *p;
505315a1350SMichael S. Tsirkin     char *e;
506315a1350SMichael S. Tsirkin     unsigned long val;
507315a1350SMichael S. Tsirkin     unsigned long dom = 0, bus = 0;
508315a1350SMichael S. Tsirkin     unsigned int slot = 0;
509315a1350SMichael S. Tsirkin     unsigned int func = 0;
510315a1350SMichael S. Tsirkin 
511315a1350SMichael S. Tsirkin     p = addr;
512315a1350SMichael S. Tsirkin     val = strtoul(p, &e, 16);
513315a1350SMichael S. Tsirkin     if (e == p)
514315a1350SMichael S. Tsirkin 	return -1;
515315a1350SMichael S. Tsirkin     if (*e == ':') {
516315a1350SMichael S. Tsirkin 	bus = val;
517315a1350SMichael S. Tsirkin 	p = e + 1;
518315a1350SMichael S. Tsirkin 	val = strtoul(p, &e, 16);
519315a1350SMichael S. Tsirkin 	if (e == p)
520315a1350SMichael S. Tsirkin 	    return -1;
521315a1350SMichael S. Tsirkin 	if (*e == ':') {
522315a1350SMichael S. Tsirkin 	    dom = bus;
523315a1350SMichael S. Tsirkin 	    bus = val;
524315a1350SMichael S. Tsirkin 	    p = e + 1;
525315a1350SMichael S. Tsirkin 	    val = strtoul(p, &e, 16);
526315a1350SMichael S. Tsirkin 	    if (e == p)
527315a1350SMichael S. Tsirkin 		return -1;
528315a1350SMichael S. Tsirkin 	}
529315a1350SMichael S. Tsirkin     }
530315a1350SMichael S. Tsirkin 
531315a1350SMichael S. Tsirkin     slot = val;
532315a1350SMichael S. Tsirkin 
533315a1350SMichael S. Tsirkin     if (funcp != NULL) {
534315a1350SMichael S. Tsirkin         if (*e != '.')
535315a1350SMichael S. Tsirkin             return -1;
536315a1350SMichael S. Tsirkin 
537315a1350SMichael S. Tsirkin         p = e + 1;
538315a1350SMichael S. Tsirkin         val = strtoul(p, &e, 16);
539315a1350SMichael S. Tsirkin         if (e == p)
540315a1350SMichael S. Tsirkin             return -1;
541315a1350SMichael S. Tsirkin 
542315a1350SMichael S. Tsirkin         func = val;
543315a1350SMichael S. Tsirkin     }
544315a1350SMichael S. Tsirkin 
545315a1350SMichael S. Tsirkin     /* if funcp == NULL func is 0 */
546315a1350SMichael S. Tsirkin     if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7)
547315a1350SMichael S. Tsirkin 	return -1;
548315a1350SMichael S. Tsirkin 
549315a1350SMichael S. Tsirkin     if (*e)
550315a1350SMichael S. Tsirkin 	return -1;
551315a1350SMichael S. Tsirkin 
552315a1350SMichael S. Tsirkin     *domp = dom;
553315a1350SMichael S. Tsirkin     *busp = bus;
554315a1350SMichael S. Tsirkin     *slotp = slot;
555315a1350SMichael S. Tsirkin     if (funcp != NULL)
556315a1350SMichael S. Tsirkin         *funcp = func;
557315a1350SMichael S. Tsirkin     return 0;
558315a1350SMichael S. Tsirkin }
559315a1350SMichael S. Tsirkin 
560315a1350SMichael S. Tsirkin int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
561315a1350SMichael S. Tsirkin                      unsigned *slotp)
562315a1350SMichael S. Tsirkin {
563315a1350SMichael S. Tsirkin     /* strip legacy tag */
564315a1350SMichael S. Tsirkin     if (!strncmp(addr, "pci_addr=", 9)) {
565315a1350SMichael S. Tsirkin         addr += 9;
566315a1350SMichael S. Tsirkin     }
567315a1350SMichael S. Tsirkin     if (pci_parse_devaddr(addr, domp, busp, slotp, NULL)) {
568315a1350SMichael S. Tsirkin         monitor_printf(mon, "Invalid pci address\n");
569315a1350SMichael S. Tsirkin         return -1;
570315a1350SMichael S. Tsirkin     }
571315a1350SMichael S. Tsirkin     return 0;
572315a1350SMichael S. Tsirkin }
573315a1350SMichael S. Tsirkin 
574315a1350SMichael S. Tsirkin PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
575315a1350SMichael S. Tsirkin {
576315a1350SMichael S. Tsirkin     int dom, bus;
577315a1350SMichael S. Tsirkin     unsigned slot;
578315a1350SMichael S. Tsirkin 
579315a1350SMichael S. Tsirkin     if (!devaddr) {
580315a1350SMichael S. Tsirkin         *devfnp = -1;
581315a1350SMichael S. Tsirkin         return pci_find_bus_nr(pci_find_root_bus(0), 0);
582315a1350SMichael S. Tsirkin     }
583315a1350SMichael S. Tsirkin 
584315a1350SMichael S. Tsirkin     if (pci_parse_devaddr(devaddr, &dom, &bus, &slot, NULL) < 0) {
585315a1350SMichael S. Tsirkin         return NULL;
586315a1350SMichael S. Tsirkin     }
587315a1350SMichael S. Tsirkin 
588315a1350SMichael S. Tsirkin     *devfnp = PCI_DEVFN(slot, 0);
589315a1350SMichael S. Tsirkin     return pci_find_bus_nr(pci_find_root_bus(dom), bus);
590315a1350SMichael S. Tsirkin }
591315a1350SMichael S. Tsirkin 
592315a1350SMichael S. Tsirkin static void pci_init_cmask(PCIDevice *dev)
593315a1350SMichael S. Tsirkin {
594315a1350SMichael S. Tsirkin     pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff);
595315a1350SMichael S. Tsirkin     pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff);
596315a1350SMichael S. Tsirkin     dev->cmask[PCI_STATUS] = PCI_STATUS_CAP_LIST;
597315a1350SMichael S. Tsirkin     dev->cmask[PCI_REVISION_ID] = 0xff;
598315a1350SMichael S. Tsirkin     dev->cmask[PCI_CLASS_PROG] = 0xff;
599315a1350SMichael S. Tsirkin     pci_set_word(dev->cmask + PCI_CLASS_DEVICE, 0xffff);
600315a1350SMichael S. Tsirkin     dev->cmask[PCI_HEADER_TYPE] = 0xff;
601315a1350SMichael S. Tsirkin     dev->cmask[PCI_CAPABILITY_LIST] = 0xff;
602315a1350SMichael S. Tsirkin }
603315a1350SMichael S. Tsirkin 
604315a1350SMichael S. Tsirkin static void pci_init_wmask(PCIDevice *dev)
605315a1350SMichael S. Tsirkin {
606315a1350SMichael S. Tsirkin     int config_size = pci_config_size(dev);
607315a1350SMichael S. Tsirkin 
608315a1350SMichael S. Tsirkin     dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
609315a1350SMichael S. Tsirkin     dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
610315a1350SMichael S. Tsirkin     pci_set_word(dev->wmask + PCI_COMMAND,
611315a1350SMichael S. Tsirkin                  PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
612315a1350SMichael S. Tsirkin                  PCI_COMMAND_INTX_DISABLE);
613315a1350SMichael S. Tsirkin     if (dev->cap_present & QEMU_PCI_CAP_SERR) {
614315a1350SMichael S. Tsirkin         pci_word_test_and_set_mask(dev->wmask + PCI_COMMAND, PCI_COMMAND_SERR);
615315a1350SMichael S. Tsirkin     }
616315a1350SMichael S. Tsirkin 
617315a1350SMichael S. Tsirkin     memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff,
618315a1350SMichael S. Tsirkin            config_size - PCI_CONFIG_HEADER_SIZE);
619315a1350SMichael S. Tsirkin }
620315a1350SMichael S. Tsirkin 
621315a1350SMichael S. Tsirkin static void pci_init_w1cmask(PCIDevice *dev)
622315a1350SMichael S. Tsirkin {
623315a1350SMichael S. Tsirkin     /*
624315a1350SMichael S. Tsirkin      * Note: It's okay to set w1cmask even for readonly bits as
625315a1350SMichael S. Tsirkin      * long as their value is hardwired to 0.
626315a1350SMichael S. Tsirkin      */
627315a1350SMichael S. Tsirkin     pci_set_word(dev->w1cmask + PCI_STATUS,
628315a1350SMichael S. Tsirkin                  PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
629315a1350SMichael S. Tsirkin                  PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
630315a1350SMichael S. Tsirkin                  PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY);
631315a1350SMichael S. Tsirkin }
632315a1350SMichael S. Tsirkin 
633315a1350SMichael S. Tsirkin static void pci_init_mask_bridge(PCIDevice *d)
634315a1350SMichael S. Tsirkin {
635315a1350SMichael S. Tsirkin     /* PCI_PRIMARY_BUS, PCI_SECONDARY_BUS, PCI_SUBORDINATE_BUS and
636315a1350SMichael S. Tsirkin        PCI_SEC_LETENCY_TIMER */
637315a1350SMichael S. Tsirkin     memset(d->wmask + PCI_PRIMARY_BUS, 0xff, 4);
638315a1350SMichael S. Tsirkin 
639315a1350SMichael S. Tsirkin     /* base and limit */
640315a1350SMichael S. Tsirkin     d->wmask[PCI_IO_BASE] = PCI_IO_RANGE_MASK & 0xff;
641315a1350SMichael S. Tsirkin     d->wmask[PCI_IO_LIMIT] = PCI_IO_RANGE_MASK & 0xff;
642315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_MEMORY_BASE,
643315a1350SMichael S. Tsirkin                  PCI_MEMORY_RANGE_MASK & 0xffff);
644315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_MEMORY_LIMIT,
645315a1350SMichael S. Tsirkin                  PCI_MEMORY_RANGE_MASK & 0xffff);
646315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_PREF_MEMORY_BASE,
647315a1350SMichael S. Tsirkin                  PCI_PREF_RANGE_MASK & 0xffff);
648315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_PREF_MEMORY_LIMIT,
649315a1350SMichael S. Tsirkin                  PCI_PREF_RANGE_MASK & 0xffff);
650315a1350SMichael S. Tsirkin 
651315a1350SMichael S. Tsirkin     /* PCI_PREF_BASE_UPPER32 and PCI_PREF_LIMIT_UPPER32 */
652315a1350SMichael S. Tsirkin     memset(d->wmask + PCI_PREF_BASE_UPPER32, 0xff, 8);
653315a1350SMichael S. Tsirkin 
654315a1350SMichael S. Tsirkin     /* Supported memory and i/o types */
655315a1350SMichael S. Tsirkin     d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_16;
656315a1350SMichael S. Tsirkin     d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_16;
657315a1350SMichael S. Tsirkin     pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_BASE,
658315a1350SMichael S. Tsirkin                                PCI_PREF_RANGE_TYPE_64);
659315a1350SMichael S. Tsirkin     pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT,
660315a1350SMichael S. Tsirkin                                PCI_PREF_RANGE_TYPE_64);
661315a1350SMichael S. Tsirkin 
662315a1350SMichael S. Tsirkin /* TODO: add this define to pci_regs.h in linux and then in qemu. */
663315a1350SMichael S. Tsirkin #define  PCI_BRIDGE_CTL_VGA_16BIT	0x10	/* VGA 16-bit decode */
664315a1350SMichael S. Tsirkin #define  PCI_BRIDGE_CTL_DISCARD		0x100	/* Primary discard timer */
665315a1350SMichael S. Tsirkin #define  PCI_BRIDGE_CTL_SEC_DISCARD	0x200	/* Secondary discard timer */
666315a1350SMichael S. Tsirkin #define  PCI_BRIDGE_CTL_DISCARD_STATUS	0x400	/* Discard timer status */
667315a1350SMichael S. Tsirkin #define  PCI_BRIDGE_CTL_DISCARD_SERR	0x800	/* Discard timer SERR# enable */
668315a1350SMichael S. Tsirkin     pci_set_word(d->wmask + PCI_BRIDGE_CONTROL,
669315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_PARITY |
670315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_SERR |
671315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_ISA |
672315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_VGA |
673315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_VGA_16BIT |
674315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_MASTER_ABORT |
675315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_BUS_RESET |
676315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_FAST_BACK |
677315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_DISCARD |
678315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_SEC_DISCARD |
679315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_DISCARD_SERR);
680315a1350SMichael S. Tsirkin     /* Below does not do anything as we never set this bit, put here for
681315a1350SMichael S. Tsirkin      * completeness. */
682315a1350SMichael S. Tsirkin     pci_set_word(d->w1cmask + PCI_BRIDGE_CONTROL,
683315a1350SMichael S. Tsirkin                  PCI_BRIDGE_CTL_DISCARD_STATUS);
684315a1350SMichael S. Tsirkin     d->cmask[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_MASK;
685315a1350SMichael S. Tsirkin     d->cmask[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_MASK;
686315a1350SMichael S. Tsirkin     pci_word_test_and_set_mask(d->cmask + PCI_PREF_MEMORY_BASE,
687315a1350SMichael S. Tsirkin                                PCI_PREF_RANGE_TYPE_MASK);
688315a1350SMichael S. Tsirkin     pci_word_test_and_set_mask(d->cmask + PCI_PREF_MEMORY_LIMIT,
689315a1350SMichael S. Tsirkin                                PCI_PREF_RANGE_TYPE_MASK);
690315a1350SMichael S. Tsirkin }
691315a1350SMichael S. Tsirkin 
692315a1350SMichael S. Tsirkin static int pci_init_multifunction(PCIBus *bus, PCIDevice *dev)
693315a1350SMichael S. Tsirkin {
694315a1350SMichael S. Tsirkin     uint8_t slot = PCI_SLOT(dev->devfn);
695315a1350SMichael S. Tsirkin     uint8_t func;
696315a1350SMichael S. Tsirkin 
697315a1350SMichael S. Tsirkin     if (dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
698315a1350SMichael S. Tsirkin         dev->config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION;
699315a1350SMichael S. Tsirkin     }
700315a1350SMichael S. Tsirkin 
701315a1350SMichael S. Tsirkin     /*
702315a1350SMichael S. Tsirkin      * multifunction bit is interpreted in two ways as follows.
703315a1350SMichael S. Tsirkin      *   - all functions must set the bit to 1.
704315a1350SMichael S. Tsirkin      *     Example: Intel X53
705315a1350SMichael S. Tsirkin      *   - function 0 must set the bit, but the rest function (> 0)
706315a1350SMichael S. Tsirkin      *     is allowed to leave the bit to 0.
707315a1350SMichael S. Tsirkin      *     Example: PIIX3(also in qemu), PIIX4(also in qemu), ICH10,
708315a1350SMichael S. Tsirkin      *
709315a1350SMichael S. Tsirkin      * So OS (at least Linux) checks the bit of only function 0,
710315a1350SMichael S. Tsirkin      * and doesn't see the bit of function > 0.
711315a1350SMichael S. Tsirkin      *
712315a1350SMichael S. Tsirkin      * The below check allows both interpretation.
713315a1350SMichael S. Tsirkin      */
714315a1350SMichael S. Tsirkin     if (PCI_FUNC(dev->devfn)) {
715315a1350SMichael S. Tsirkin         PCIDevice *f0 = bus->devices[PCI_DEVFN(slot, 0)];
716315a1350SMichael S. Tsirkin         if (f0 && !(f0->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)) {
717315a1350SMichael S. Tsirkin             /* function 0 should set multifunction bit */
718315a1350SMichael S. Tsirkin             error_report("PCI: single function device can't be populated "
719315a1350SMichael S. Tsirkin                          "in function %x.%x", slot, PCI_FUNC(dev->devfn));
720315a1350SMichael S. Tsirkin             return -1;
721315a1350SMichael S. Tsirkin         }
722315a1350SMichael S. Tsirkin         return 0;
723315a1350SMichael S. Tsirkin     }
724315a1350SMichael S. Tsirkin 
725315a1350SMichael S. Tsirkin     if (dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
726315a1350SMichael S. Tsirkin         return 0;
727315a1350SMichael S. Tsirkin     }
728315a1350SMichael S. Tsirkin     /* function 0 indicates single function, so function > 0 must be NULL */
729315a1350SMichael S. Tsirkin     for (func = 1; func < PCI_FUNC_MAX; ++func) {
730315a1350SMichael S. Tsirkin         if (bus->devices[PCI_DEVFN(slot, func)]) {
731315a1350SMichael S. Tsirkin             error_report("PCI: %x.0 indicates single function, "
732315a1350SMichael S. Tsirkin                          "but %x.%x is already populated.",
733315a1350SMichael S. Tsirkin                          slot, slot, func);
734315a1350SMichael S. Tsirkin             return -1;
735315a1350SMichael S. Tsirkin         }
736315a1350SMichael S. Tsirkin     }
737315a1350SMichael S. Tsirkin     return 0;
738315a1350SMichael S. Tsirkin }
739315a1350SMichael S. Tsirkin 
740315a1350SMichael S. Tsirkin static void pci_config_alloc(PCIDevice *pci_dev)
741315a1350SMichael S. Tsirkin {
742315a1350SMichael S. Tsirkin     int config_size = pci_config_size(pci_dev);
743315a1350SMichael S. Tsirkin 
744315a1350SMichael S. Tsirkin     pci_dev->config = g_malloc0(config_size);
745315a1350SMichael S. Tsirkin     pci_dev->cmask = g_malloc0(config_size);
746315a1350SMichael S. Tsirkin     pci_dev->wmask = g_malloc0(config_size);
747315a1350SMichael S. Tsirkin     pci_dev->w1cmask = g_malloc0(config_size);
748315a1350SMichael S. Tsirkin     pci_dev->used = g_malloc0(config_size);
749315a1350SMichael S. Tsirkin }
750315a1350SMichael S. Tsirkin 
751315a1350SMichael S. Tsirkin static void pci_config_free(PCIDevice *pci_dev)
752315a1350SMichael S. Tsirkin {
753315a1350SMichael S. Tsirkin     g_free(pci_dev->config);
754315a1350SMichael S. Tsirkin     g_free(pci_dev->cmask);
755315a1350SMichael S. Tsirkin     g_free(pci_dev->wmask);
756315a1350SMichael S. Tsirkin     g_free(pci_dev->w1cmask);
757315a1350SMichael S. Tsirkin     g_free(pci_dev->used);
758315a1350SMichael S. Tsirkin }
759315a1350SMichael S. Tsirkin 
760315a1350SMichael S. Tsirkin /* -1 for devfn means auto assign */
761315a1350SMichael S. Tsirkin static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
762315a1350SMichael S. Tsirkin                                          const char *name, int devfn)
763315a1350SMichael S. Tsirkin {
764315a1350SMichael S. Tsirkin     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
765315a1350SMichael S. Tsirkin     PCIConfigReadFunc *config_read = pc->config_read;
766315a1350SMichael S. Tsirkin     PCIConfigWriteFunc *config_write = pc->config_write;
767315a1350SMichael S. Tsirkin 
768315a1350SMichael S. Tsirkin     if (devfn < 0) {
769315a1350SMichael S. Tsirkin         for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
770315a1350SMichael S. Tsirkin             devfn += PCI_FUNC_MAX) {
771315a1350SMichael S. Tsirkin             if (!bus->devices[devfn])
772315a1350SMichael S. Tsirkin                 goto found;
773315a1350SMichael S. Tsirkin         }
774315a1350SMichael S. Tsirkin         error_report("PCI: no slot/function available for %s, all in use", name);
775315a1350SMichael S. Tsirkin         return NULL;
776315a1350SMichael S. Tsirkin     found: ;
777315a1350SMichael S. Tsirkin     } else if (bus->devices[devfn]) {
778315a1350SMichael S. Tsirkin         error_report("PCI: slot %d function %d not available for %s, in use by %s",
779315a1350SMichael S. Tsirkin                      PCI_SLOT(devfn), PCI_FUNC(devfn), name, bus->devices[devfn]->name);
780315a1350SMichael S. Tsirkin         return NULL;
781315a1350SMichael S. Tsirkin     }
782315a1350SMichael S. Tsirkin     pci_dev->bus = bus;
783315a1350SMichael S. Tsirkin     if (bus->dma_context_fn) {
784315a1350SMichael S. Tsirkin         pci_dev->dma = bus->dma_context_fn(bus, bus->dma_context_opaque, devfn);
785315a1350SMichael S. Tsirkin     } else {
786315a1350SMichael S. Tsirkin         /* FIXME: Make dma_context_fn use MemoryRegions instead, so this path is
787315a1350SMichael S. Tsirkin          * taken unconditionally */
788315a1350SMichael S. Tsirkin         /* FIXME: inherit memory region from bus creator */
789315a1350SMichael S. Tsirkin         memory_region_init_alias(&pci_dev->bus_master_enable_region, "bus master",
790315a1350SMichael S. Tsirkin                                  get_system_memory(), 0,
791315a1350SMichael S. Tsirkin                                  memory_region_size(get_system_memory()));
792315a1350SMichael S. Tsirkin         memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
793315a1350SMichael S. Tsirkin         address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region);
794315a1350SMichael S. Tsirkin         pci_dev->dma = g_new(DMAContext, 1);
795315a1350SMichael S. Tsirkin         dma_context_init(pci_dev->dma, &pci_dev->bus_master_as, NULL, NULL, NULL);
796315a1350SMichael S. Tsirkin     }
797315a1350SMichael S. Tsirkin     pci_dev->devfn = devfn;
798315a1350SMichael S. Tsirkin     pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
799315a1350SMichael S. Tsirkin     pci_dev->irq_state = 0;
800315a1350SMichael S. Tsirkin     pci_config_alloc(pci_dev);
801315a1350SMichael S. Tsirkin 
802315a1350SMichael S. Tsirkin     pci_config_set_vendor_id(pci_dev->config, pc->vendor_id);
803315a1350SMichael S. Tsirkin     pci_config_set_device_id(pci_dev->config, pc->device_id);
804315a1350SMichael S. Tsirkin     pci_config_set_revision(pci_dev->config, pc->revision);
805315a1350SMichael S. Tsirkin     pci_config_set_class(pci_dev->config, pc->class_id);
806315a1350SMichael S. Tsirkin 
807315a1350SMichael S. Tsirkin     if (!pc->is_bridge) {
808315a1350SMichael S. Tsirkin         if (pc->subsystem_vendor_id || pc->subsystem_id) {
809315a1350SMichael S. Tsirkin             pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
810315a1350SMichael S. Tsirkin                          pc->subsystem_vendor_id);
811315a1350SMichael S. Tsirkin             pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
812315a1350SMichael S. Tsirkin                          pc->subsystem_id);
813315a1350SMichael S. Tsirkin         } else {
814315a1350SMichael S. Tsirkin             pci_set_default_subsystem_id(pci_dev);
815315a1350SMichael S. Tsirkin         }
816315a1350SMichael S. Tsirkin     } else {
817315a1350SMichael S. Tsirkin         /* subsystem_vendor_id/subsystem_id are only for header type 0 */
818315a1350SMichael S. Tsirkin         assert(!pc->subsystem_vendor_id);
819315a1350SMichael S. Tsirkin         assert(!pc->subsystem_id);
820315a1350SMichael S. Tsirkin     }
821315a1350SMichael S. Tsirkin     pci_init_cmask(pci_dev);
822315a1350SMichael S. Tsirkin     pci_init_wmask(pci_dev);
823315a1350SMichael S. Tsirkin     pci_init_w1cmask(pci_dev);
824315a1350SMichael S. Tsirkin     if (pc->is_bridge) {
825315a1350SMichael S. Tsirkin         pci_init_mask_bridge(pci_dev);
826315a1350SMichael S. Tsirkin     }
827315a1350SMichael S. Tsirkin     if (pci_init_multifunction(bus, pci_dev)) {
828315a1350SMichael S. Tsirkin         pci_config_free(pci_dev);
829315a1350SMichael S. Tsirkin         return NULL;
830315a1350SMichael S. Tsirkin     }
831315a1350SMichael S. Tsirkin 
832315a1350SMichael S. Tsirkin     if (!config_read)
833315a1350SMichael S. Tsirkin         config_read = pci_default_read_config;
834315a1350SMichael S. Tsirkin     if (!config_write)
835315a1350SMichael S. Tsirkin         config_write = pci_default_write_config;
836315a1350SMichael S. Tsirkin     pci_dev->config_read = config_read;
837315a1350SMichael S. Tsirkin     pci_dev->config_write = config_write;
838315a1350SMichael S. Tsirkin     bus->devices[devfn] = pci_dev;
839315a1350SMichael S. Tsirkin     pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, PCI_NUM_PINS);
840315a1350SMichael S. Tsirkin     pci_dev->version_id = 2; /* Current pci device vmstate version */
841315a1350SMichael S. Tsirkin     return pci_dev;
842315a1350SMichael S. Tsirkin }
843315a1350SMichael S. Tsirkin 
844315a1350SMichael S. Tsirkin static void do_pci_unregister_device(PCIDevice *pci_dev)
845315a1350SMichael S. Tsirkin {
846315a1350SMichael S. Tsirkin     qemu_free_irqs(pci_dev->irq);
847315a1350SMichael S. Tsirkin     pci_dev->bus->devices[pci_dev->devfn] = NULL;
848315a1350SMichael S. Tsirkin     pci_config_free(pci_dev);
849315a1350SMichael S. Tsirkin 
850315a1350SMichael S. Tsirkin     if (!pci_dev->bus->dma_context_fn) {
851315a1350SMichael S. Tsirkin         address_space_destroy(&pci_dev->bus_master_as);
852315a1350SMichael S. Tsirkin         memory_region_destroy(&pci_dev->bus_master_enable_region);
853315a1350SMichael S. Tsirkin         g_free(pci_dev->dma);
854315a1350SMichael S. Tsirkin         pci_dev->dma = NULL;
855315a1350SMichael S. Tsirkin     }
856315a1350SMichael S. Tsirkin }
857315a1350SMichael S. Tsirkin 
858315a1350SMichael S. Tsirkin static void pci_unregister_io_regions(PCIDevice *pci_dev)
859315a1350SMichael S. Tsirkin {
860315a1350SMichael S. Tsirkin     PCIIORegion *r;
861315a1350SMichael S. Tsirkin     int i;
862315a1350SMichael S. Tsirkin 
863315a1350SMichael S. Tsirkin     for(i = 0; i < PCI_NUM_REGIONS; i++) {
864315a1350SMichael S. Tsirkin         r = &pci_dev->io_regions[i];
865315a1350SMichael S. Tsirkin         if (!r->size || r->addr == PCI_BAR_UNMAPPED)
866315a1350SMichael S. Tsirkin             continue;
867315a1350SMichael S. Tsirkin         memory_region_del_subregion(r->address_space, r->memory);
868315a1350SMichael S. Tsirkin     }
869315a1350SMichael S. Tsirkin }
870315a1350SMichael S. Tsirkin 
871315a1350SMichael S. Tsirkin static int pci_unregister_device(DeviceState *dev)
872315a1350SMichael S. Tsirkin {
873315a1350SMichael S. Tsirkin     PCIDevice *pci_dev = PCI_DEVICE(dev);
874315a1350SMichael S. Tsirkin     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
875315a1350SMichael S. Tsirkin 
876315a1350SMichael S. Tsirkin     pci_unregister_io_regions(pci_dev);
877315a1350SMichael S. Tsirkin     pci_del_option_rom(pci_dev);
878315a1350SMichael S. Tsirkin 
879315a1350SMichael S. Tsirkin     if (pc->exit) {
880315a1350SMichael S. Tsirkin         pc->exit(pci_dev);
881315a1350SMichael S. Tsirkin     }
882315a1350SMichael S. Tsirkin 
883315a1350SMichael S. Tsirkin     do_pci_unregister_device(pci_dev);
884315a1350SMichael S. Tsirkin     return 0;
885315a1350SMichael S. Tsirkin }
886315a1350SMichael S. Tsirkin 
887315a1350SMichael S. Tsirkin void pci_register_bar(PCIDevice *pci_dev, int region_num,
888315a1350SMichael S. Tsirkin                       uint8_t type, MemoryRegion *memory)
889315a1350SMichael S. Tsirkin {
890315a1350SMichael S. Tsirkin     PCIIORegion *r;
891315a1350SMichael S. Tsirkin     uint32_t addr;
892315a1350SMichael S. Tsirkin     uint64_t wmask;
893315a1350SMichael S. Tsirkin     pcibus_t size = memory_region_size(memory);
894315a1350SMichael S. Tsirkin 
895315a1350SMichael S. Tsirkin     assert(region_num >= 0);
896315a1350SMichael S. Tsirkin     assert(region_num < PCI_NUM_REGIONS);
897315a1350SMichael S. Tsirkin     if (size & (size-1)) {
898315a1350SMichael S. Tsirkin         fprintf(stderr, "ERROR: PCI region size must be pow2 "
899315a1350SMichael S. Tsirkin                     "type=0x%x, size=0x%"FMT_PCIBUS"\n", type, size);
900315a1350SMichael S. Tsirkin         exit(1);
901315a1350SMichael S. Tsirkin     }
902315a1350SMichael S. Tsirkin 
903315a1350SMichael S. Tsirkin     r = &pci_dev->io_regions[region_num];
904315a1350SMichael S. Tsirkin     r->addr = PCI_BAR_UNMAPPED;
905315a1350SMichael S. Tsirkin     r->size = size;
906315a1350SMichael S. Tsirkin     r->type = type;
907315a1350SMichael S. Tsirkin     r->memory = NULL;
908315a1350SMichael S. Tsirkin 
909315a1350SMichael S. Tsirkin     wmask = ~(size - 1);
910315a1350SMichael S. Tsirkin     addr = pci_bar(pci_dev, region_num);
911315a1350SMichael S. Tsirkin     if (region_num == PCI_ROM_SLOT) {
912315a1350SMichael S. Tsirkin         /* ROM enable bit is writable */
913315a1350SMichael S. Tsirkin         wmask |= PCI_ROM_ADDRESS_ENABLE;
914315a1350SMichael S. Tsirkin     }
915315a1350SMichael S. Tsirkin     pci_set_long(pci_dev->config + addr, type);
916315a1350SMichael S. Tsirkin     if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&
917315a1350SMichael S. Tsirkin         r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
918315a1350SMichael S. Tsirkin         pci_set_quad(pci_dev->wmask + addr, wmask);
919315a1350SMichael S. Tsirkin         pci_set_quad(pci_dev->cmask + addr, ~0ULL);
920315a1350SMichael S. Tsirkin     } else {
921315a1350SMichael S. Tsirkin         pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
922315a1350SMichael S. Tsirkin         pci_set_long(pci_dev->cmask + addr, 0xffffffff);
923315a1350SMichael S. Tsirkin     }
924315a1350SMichael S. Tsirkin     pci_dev->io_regions[region_num].memory = memory;
925315a1350SMichael S. Tsirkin     pci_dev->io_regions[region_num].address_space
926315a1350SMichael S. Tsirkin         = type & PCI_BASE_ADDRESS_SPACE_IO
927315a1350SMichael S. Tsirkin         ? pci_dev->bus->address_space_io
928315a1350SMichael S. Tsirkin         : pci_dev->bus->address_space_mem;
929315a1350SMichael S. Tsirkin }
930315a1350SMichael S. Tsirkin 
931315a1350SMichael S. Tsirkin pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
932315a1350SMichael S. Tsirkin {
933315a1350SMichael S. Tsirkin     return pci_dev->io_regions[region_num].addr;
934315a1350SMichael S. Tsirkin }
935315a1350SMichael S. Tsirkin 
936315a1350SMichael S. Tsirkin static pcibus_t pci_bar_address(PCIDevice *d,
937315a1350SMichael S. Tsirkin 				int reg, uint8_t type, pcibus_t size)
938315a1350SMichael S. Tsirkin {
939315a1350SMichael S. Tsirkin     pcibus_t new_addr, last_addr;
940315a1350SMichael S. Tsirkin     int bar = pci_bar(d, reg);
941315a1350SMichael S. Tsirkin     uint16_t cmd = pci_get_word(d->config + PCI_COMMAND);
942315a1350SMichael S. Tsirkin 
943315a1350SMichael S. Tsirkin     if (type & PCI_BASE_ADDRESS_SPACE_IO) {
944315a1350SMichael S. Tsirkin         if (!(cmd & PCI_COMMAND_IO)) {
945315a1350SMichael S. Tsirkin             return PCI_BAR_UNMAPPED;
946315a1350SMichael S. Tsirkin         }
947315a1350SMichael S. Tsirkin         new_addr = pci_get_long(d->config + bar) & ~(size - 1);
948315a1350SMichael S. Tsirkin         last_addr = new_addr + size - 1;
949315a1350SMichael S. Tsirkin         /* NOTE: we have only 64K ioports on PC */
950315a1350SMichael S. Tsirkin         if (last_addr <= new_addr || new_addr == 0 || last_addr > UINT16_MAX) {
951315a1350SMichael S. Tsirkin             return PCI_BAR_UNMAPPED;
952315a1350SMichael S. Tsirkin         }
953315a1350SMichael S. Tsirkin         return new_addr;
954315a1350SMichael S. Tsirkin     }
955315a1350SMichael S. Tsirkin 
956315a1350SMichael S. Tsirkin     if (!(cmd & PCI_COMMAND_MEMORY)) {
957315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
958315a1350SMichael S. Tsirkin     }
959315a1350SMichael S. Tsirkin     if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
960315a1350SMichael S. Tsirkin         new_addr = pci_get_quad(d->config + bar);
961315a1350SMichael S. Tsirkin     } else {
962315a1350SMichael S. Tsirkin         new_addr = pci_get_long(d->config + bar);
963315a1350SMichael S. Tsirkin     }
964315a1350SMichael S. Tsirkin     /* the ROM slot has a specific enable bit */
965315a1350SMichael S. Tsirkin     if (reg == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE)) {
966315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
967315a1350SMichael S. Tsirkin     }
968315a1350SMichael S. Tsirkin     new_addr &= ~(size - 1);
969315a1350SMichael S. Tsirkin     last_addr = new_addr + size - 1;
970315a1350SMichael S. Tsirkin     /* NOTE: we do not support wrapping */
971315a1350SMichael S. Tsirkin     /* XXX: as we cannot support really dynamic
972315a1350SMichael S. Tsirkin        mappings, we handle specific values as invalid
973315a1350SMichael S. Tsirkin        mappings. */
974315a1350SMichael S. Tsirkin     if (last_addr <= new_addr || new_addr == 0 ||
975315a1350SMichael S. Tsirkin         last_addr == PCI_BAR_UNMAPPED) {
976315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
977315a1350SMichael S. Tsirkin     }
978315a1350SMichael S. Tsirkin 
979315a1350SMichael S. Tsirkin     /* Now pcibus_t is 64bit.
980315a1350SMichael S. Tsirkin      * Check if 32 bit BAR wraps around explicitly.
981315a1350SMichael S. Tsirkin      * Without this, PC ide doesn't work well.
982315a1350SMichael S. Tsirkin      * TODO: remove this work around.
983315a1350SMichael S. Tsirkin      */
984315a1350SMichael S. Tsirkin     if  (!(type & PCI_BASE_ADDRESS_MEM_TYPE_64) && last_addr >= UINT32_MAX) {
985315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
986315a1350SMichael S. Tsirkin     }
987315a1350SMichael S. Tsirkin 
988315a1350SMichael S. Tsirkin     /*
989315a1350SMichael S. Tsirkin      * OS is allowed to set BAR beyond its addressable
990315a1350SMichael S. Tsirkin      * bits. For example, 32 bit OS can set 64bit bar
991315a1350SMichael S. Tsirkin      * to >4G. Check it. TODO: we might need to support
992315a1350SMichael S. Tsirkin      * it in the future for e.g. PAE.
993315a1350SMichael S. Tsirkin      */
994315a1350SMichael S. Tsirkin     if (last_addr >= HWADDR_MAX) {
995315a1350SMichael S. Tsirkin         return PCI_BAR_UNMAPPED;
996315a1350SMichael S. Tsirkin     }
997315a1350SMichael S. Tsirkin 
998315a1350SMichael S. Tsirkin     return new_addr;
999315a1350SMichael S. Tsirkin }
1000315a1350SMichael S. Tsirkin 
1001315a1350SMichael S. Tsirkin static void pci_update_mappings(PCIDevice *d)
1002315a1350SMichael S. Tsirkin {
1003315a1350SMichael S. Tsirkin     PCIIORegion *r;
1004315a1350SMichael S. Tsirkin     int i;
1005315a1350SMichael S. Tsirkin     pcibus_t new_addr;
1006315a1350SMichael S. Tsirkin 
1007315a1350SMichael S. Tsirkin     for(i = 0; i < PCI_NUM_REGIONS; i++) {
1008315a1350SMichael S. Tsirkin         r = &d->io_regions[i];
1009315a1350SMichael S. Tsirkin 
1010315a1350SMichael S. Tsirkin         /* this region isn't registered */
1011315a1350SMichael S. Tsirkin         if (!r->size)
1012315a1350SMichael S. Tsirkin             continue;
1013315a1350SMichael S. Tsirkin 
1014315a1350SMichael S. Tsirkin         new_addr = pci_bar_address(d, i, r->type, r->size);
1015315a1350SMichael S. Tsirkin 
1016315a1350SMichael S. Tsirkin         /* This bar isn't changed */
1017315a1350SMichael S. Tsirkin         if (new_addr == r->addr)
1018315a1350SMichael S. Tsirkin             continue;
1019315a1350SMichael S. Tsirkin 
1020315a1350SMichael S. Tsirkin         /* now do the real mapping */
1021315a1350SMichael S. Tsirkin         if (r->addr != PCI_BAR_UNMAPPED) {
1022315a1350SMichael S. Tsirkin             memory_region_del_subregion(r->address_space, r->memory);
1023315a1350SMichael S. Tsirkin         }
1024315a1350SMichael S. Tsirkin         r->addr = new_addr;
1025315a1350SMichael S. Tsirkin         if (r->addr != PCI_BAR_UNMAPPED) {
1026315a1350SMichael S. Tsirkin             memory_region_add_subregion_overlap(r->address_space,
1027315a1350SMichael S. Tsirkin                                                 r->addr, r->memory, 1);
1028315a1350SMichael S. Tsirkin         }
1029315a1350SMichael S. Tsirkin     }
1030315a1350SMichael S. Tsirkin }
1031315a1350SMichael S. Tsirkin 
1032315a1350SMichael S. Tsirkin static inline int pci_irq_disabled(PCIDevice *d)
1033315a1350SMichael S. Tsirkin {
1034315a1350SMichael S. Tsirkin     return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE;
1035315a1350SMichael S. Tsirkin }
1036315a1350SMichael S. Tsirkin 
1037315a1350SMichael S. Tsirkin /* Called after interrupt disabled field update in config space,
1038315a1350SMichael S. Tsirkin  * assert/deassert interrupts if necessary.
1039315a1350SMichael S. Tsirkin  * Gets original interrupt disable bit value (before update). */
1040315a1350SMichael S. Tsirkin static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled)
1041315a1350SMichael S. Tsirkin {
1042315a1350SMichael S. Tsirkin     int i, disabled = pci_irq_disabled(d);
1043315a1350SMichael S. Tsirkin     if (disabled == was_irq_disabled)
1044315a1350SMichael S. Tsirkin         return;
1045315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_PINS; ++i) {
1046315a1350SMichael S. Tsirkin         int state = pci_irq_state(d, i);
1047315a1350SMichael S. Tsirkin         pci_change_irq_level(d, i, disabled ? -state : state);
1048315a1350SMichael S. Tsirkin     }
1049315a1350SMichael S. Tsirkin }
1050315a1350SMichael S. Tsirkin 
1051315a1350SMichael S. Tsirkin uint32_t pci_default_read_config(PCIDevice *d,
1052315a1350SMichael S. Tsirkin                                  uint32_t address, int len)
1053315a1350SMichael S. Tsirkin {
1054315a1350SMichael S. Tsirkin     uint32_t val = 0;
1055315a1350SMichael S. Tsirkin 
1056315a1350SMichael S. Tsirkin     memcpy(&val, d->config + address, len);
1057315a1350SMichael S. Tsirkin     return le32_to_cpu(val);
1058315a1350SMichael S. Tsirkin }
1059315a1350SMichael S. Tsirkin 
1060315a1350SMichael S. Tsirkin void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
1061315a1350SMichael S. Tsirkin {
1062315a1350SMichael S. Tsirkin     int i, was_irq_disabled = pci_irq_disabled(d);
1063315a1350SMichael S. Tsirkin 
1064315a1350SMichael S. Tsirkin     for (i = 0; i < l; val >>= 8, ++i) {
1065315a1350SMichael S. Tsirkin         uint8_t wmask = d->wmask[addr + i];
1066315a1350SMichael S. Tsirkin         uint8_t w1cmask = d->w1cmask[addr + i];
1067315a1350SMichael S. Tsirkin         assert(!(wmask & w1cmask));
1068315a1350SMichael S. Tsirkin         d->config[addr + i] = (d->config[addr + i] & ~wmask) | (val & wmask);
1069315a1350SMichael S. Tsirkin         d->config[addr + i] &= ~(val & w1cmask); /* W1C: Write 1 to Clear */
1070315a1350SMichael S. Tsirkin     }
1071315a1350SMichael S. Tsirkin     if (ranges_overlap(addr, l, PCI_BASE_ADDRESS_0, 24) ||
1072315a1350SMichael S. Tsirkin         ranges_overlap(addr, l, PCI_ROM_ADDRESS, 4) ||
1073315a1350SMichael S. Tsirkin         ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) ||
1074315a1350SMichael S. Tsirkin         range_covers_byte(addr, l, PCI_COMMAND))
1075315a1350SMichael S. Tsirkin         pci_update_mappings(d);
1076315a1350SMichael S. Tsirkin 
1077315a1350SMichael S. Tsirkin     if (range_covers_byte(addr, l, PCI_COMMAND)) {
1078315a1350SMichael S. Tsirkin         pci_update_irq_disabled(d, was_irq_disabled);
1079315a1350SMichael S. Tsirkin         memory_region_set_enabled(&d->bus_master_enable_region,
1080315a1350SMichael S. Tsirkin                                   pci_get_word(d->config + PCI_COMMAND)
1081315a1350SMichael S. Tsirkin                                     & PCI_COMMAND_MASTER);
1082315a1350SMichael S. Tsirkin     }
1083315a1350SMichael S. Tsirkin 
1084315a1350SMichael S. Tsirkin     msi_write_config(d, addr, val, l);
1085315a1350SMichael S. Tsirkin     msix_write_config(d, addr, val, l);
1086315a1350SMichael S. Tsirkin }
1087315a1350SMichael S. Tsirkin 
1088315a1350SMichael S. Tsirkin /***********************************************************/
1089315a1350SMichael S. Tsirkin /* generic PCI irq support */
1090315a1350SMichael S. Tsirkin 
1091315a1350SMichael S. Tsirkin /* 0 <= irq_num <= 3. level must be 0 or 1 */
1092315a1350SMichael S. Tsirkin static void pci_set_irq(void *opaque, int irq_num, int level)
1093315a1350SMichael S. Tsirkin {
1094315a1350SMichael S. Tsirkin     PCIDevice *pci_dev = opaque;
1095315a1350SMichael S. Tsirkin     int change;
1096315a1350SMichael S. Tsirkin 
1097315a1350SMichael S. Tsirkin     change = level - pci_irq_state(pci_dev, irq_num);
1098315a1350SMichael S. Tsirkin     if (!change)
1099315a1350SMichael S. Tsirkin         return;
1100315a1350SMichael S. Tsirkin 
1101315a1350SMichael S. Tsirkin     pci_set_irq_state(pci_dev, irq_num, level);
1102315a1350SMichael S. Tsirkin     pci_update_irq_status(pci_dev);
1103315a1350SMichael S. Tsirkin     if (pci_irq_disabled(pci_dev))
1104315a1350SMichael S. Tsirkin         return;
1105315a1350SMichael S. Tsirkin     pci_change_irq_level(pci_dev, irq_num, change);
1106315a1350SMichael S. Tsirkin }
1107315a1350SMichael S. Tsirkin 
1108315a1350SMichael S. Tsirkin /* Special hooks used by device assignment */
1109315a1350SMichael S. Tsirkin void pci_bus_set_route_irq_fn(PCIBus *bus, pci_route_irq_fn route_intx_to_irq)
1110315a1350SMichael S. Tsirkin {
1111315a1350SMichael S. Tsirkin     assert(!bus->parent_dev);
1112315a1350SMichael S. Tsirkin     bus->route_intx_to_irq = route_intx_to_irq;
1113315a1350SMichael S. Tsirkin }
1114315a1350SMichael S. Tsirkin 
1115315a1350SMichael S. Tsirkin PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
1116315a1350SMichael S. Tsirkin {
1117315a1350SMichael S. Tsirkin     PCIBus *bus;
1118315a1350SMichael S. Tsirkin 
1119315a1350SMichael S. Tsirkin     do {
1120315a1350SMichael S. Tsirkin          bus = dev->bus;
1121315a1350SMichael S. Tsirkin          pin = bus->map_irq(dev, pin);
1122315a1350SMichael S. Tsirkin          dev = bus->parent_dev;
1123315a1350SMichael S. Tsirkin     } while (dev);
1124315a1350SMichael S. Tsirkin 
1125315a1350SMichael S. Tsirkin     if (!bus->route_intx_to_irq) {
1126315a1350SMichael S. Tsirkin         error_report("PCI: Bug - unimplemented PCI INTx routing (%s)\n",
1127315a1350SMichael S. Tsirkin                      object_get_typename(OBJECT(bus->qbus.parent)));
1128315a1350SMichael S. Tsirkin         return (PCIINTxRoute) { PCI_INTX_DISABLED, -1 };
1129315a1350SMichael S. Tsirkin     }
1130315a1350SMichael S. Tsirkin 
1131315a1350SMichael S. Tsirkin     return bus->route_intx_to_irq(bus->irq_opaque, pin);
1132315a1350SMichael S. Tsirkin }
1133315a1350SMichael S. Tsirkin 
1134315a1350SMichael S. Tsirkin bool pci_intx_route_changed(PCIINTxRoute *old, PCIINTxRoute *new)
1135315a1350SMichael S. Tsirkin {
1136315a1350SMichael S. Tsirkin     return old->mode != new->mode || old->irq != new->irq;
1137315a1350SMichael S. Tsirkin }
1138315a1350SMichael S. Tsirkin 
1139315a1350SMichael S. Tsirkin void pci_bus_fire_intx_routing_notifier(PCIBus *bus)
1140315a1350SMichael S. Tsirkin {
1141315a1350SMichael S. Tsirkin     PCIDevice *dev;
1142315a1350SMichael S. Tsirkin     PCIBus *sec;
1143315a1350SMichael S. Tsirkin     int i;
1144315a1350SMichael S. Tsirkin 
1145315a1350SMichael S. Tsirkin     for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
1146315a1350SMichael S. Tsirkin         dev = bus->devices[i];
1147315a1350SMichael S. Tsirkin         if (dev && dev->intx_routing_notifier) {
1148315a1350SMichael S. Tsirkin             dev->intx_routing_notifier(dev);
1149315a1350SMichael S. Tsirkin         }
1150315a1350SMichael S. Tsirkin         QLIST_FOREACH(sec, &bus->child, sibling) {
1151315a1350SMichael S. Tsirkin             pci_bus_fire_intx_routing_notifier(sec);
1152315a1350SMichael S. Tsirkin         }
1153315a1350SMichael S. Tsirkin     }
1154315a1350SMichael S. Tsirkin }
1155315a1350SMichael S. Tsirkin 
1156315a1350SMichael S. Tsirkin void pci_device_set_intx_routing_notifier(PCIDevice *dev,
1157315a1350SMichael S. Tsirkin                                           PCIINTxRoutingNotifier notifier)
1158315a1350SMichael S. Tsirkin {
1159315a1350SMichael S. Tsirkin     dev->intx_routing_notifier = notifier;
1160315a1350SMichael S. Tsirkin }
1161315a1350SMichael S. Tsirkin 
1162315a1350SMichael S. Tsirkin /*
1163315a1350SMichael S. Tsirkin  * PCI-to-PCI bridge specification
1164315a1350SMichael S. Tsirkin  * 9.1: Interrupt routing. Table 9-1
1165315a1350SMichael S. Tsirkin  *
1166315a1350SMichael S. Tsirkin  * the PCI Express Base Specification, Revision 2.1
1167315a1350SMichael S. Tsirkin  * 2.2.8.1: INTx interrutp signaling - Rules
1168315a1350SMichael S. Tsirkin  *          the Implementation Note
1169315a1350SMichael S. Tsirkin  *          Table 2-20
1170315a1350SMichael S. Tsirkin  */
1171315a1350SMichael S. Tsirkin /*
1172315a1350SMichael S. Tsirkin  * 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD
1173315a1350SMichael S. Tsirkin  * 0-origin unlike PCI interrupt pin register.
1174315a1350SMichael S. Tsirkin  */
1175315a1350SMichael S. Tsirkin int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin)
1176315a1350SMichael S. Tsirkin {
1177315a1350SMichael S. Tsirkin     return (pin + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS;
1178315a1350SMichael S. Tsirkin }
1179315a1350SMichael S. Tsirkin 
1180315a1350SMichael S. Tsirkin /***********************************************************/
1181315a1350SMichael S. Tsirkin /* monitor info on PCI */
1182315a1350SMichael S. Tsirkin 
1183315a1350SMichael S. Tsirkin typedef struct {
1184315a1350SMichael S. Tsirkin     uint16_t class;
1185315a1350SMichael S. Tsirkin     const char *desc;
1186315a1350SMichael S. Tsirkin     const char *fw_name;
1187315a1350SMichael S. Tsirkin     uint16_t fw_ign_bits;
1188315a1350SMichael S. Tsirkin } pci_class_desc;
1189315a1350SMichael S. Tsirkin 
1190315a1350SMichael S. Tsirkin static const pci_class_desc pci_class_descriptions[] =
1191315a1350SMichael S. Tsirkin {
1192315a1350SMichael S. Tsirkin     { 0x0001, "VGA controller", "display"},
1193315a1350SMichael S. Tsirkin     { 0x0100, "SCSI controller", "scsi"},
1194315a1350SMichael S. Tsirkin     { 0x0101, "IDE controller", "ide"},
1195315a1350SMichael S. Tsirkin     { 0x0102, "Floppy controller", "fdc"},
1196315a1350SMichael S. Tsirkin     { 0x0103, "IPI controller", "ipi"},
1197315a1350SMichael S. Tsirkin     { 0x0104, "RAID controller", "raid"},
1198315a1350SMichael S. Tsirkin     { 0x0106, "SATA controller"},
1199315a1350SMichael S. Tsirkin     { 0x0107, "SAS controller"},
1200315a1350SMichael S. Tsirkin     { 0x0180, "Storage controller"},
1201315a1350SMichael S. Tsirkin     { 0x0200, "Ethernet controller", "ethernet"},
1202315a1350SMichael S. Tsirkin     { 0x0201, "Token Ring controller", "token-ring"},
1203315a1350SMichael S. Tsirkin     { 0x0202, "FDDI controller", "fddi"},
1204315a1350SMichael S. Tsirkin     { 0x0203, "ATM controller", "atm"},
1205315a1350SMichael S. Tsirkin     { 0x0280, "Network controller"},
1206315a1350SMichael S. Tsirkin     { 0x0300, "VGA controller", "display", 0x00ff},
1207315a1350SMichael S. Tsirkin     { 0x0301, "XGA controller"},
1208315a1350SMichael S. Tsirkin     { 0x0302, "3D controller"},
1209315a1350SMichael S. Tsirkin     { 0x0380, "Display controller"},
1210315a1350SMichael S. Tsirkin     { 0x0400, "Video controller", "video"},
1211315a1350SMichael S. Tsirkin     { 0x0401, "Audio controller", "sound"},
1212315a1350SMichael S. Tsirkin     { 0x0402, "Phone"},
1213315a1350SMichael S. Tsirkin     { 0x0403, "Audio controller", "sound"},
1214315a1350SMichael S. Tsirkin     { 0x0480, "Multimedia controller"},
1215315a1350SMichael S. Tsirkin     { 0x0500, "RAM controller", "memory"},
1216315a1350SMichael S. Tsirkin     { 0x0501, "Flash controller", "flash"},
1217315a1350SMichael S. Tsirkin     { 0x0580, "Memory controller"},
1218315a1350SMichael S. Tsirkin     { 0x0600, "Host bridge", "host"},
1219315a1350SMichael S. Tsirkin     { 0x0601, "ISA bridge", "isa"},
1220315a1350SMichael S. Tsirkin     { 0x0602, "EISA bridge", "eisa"},
1221315a1350SMichael S. Tsirkin     { 0x0603, "MC bridge", "mca"},
1222315a1350SMichael S. Tsirkin     { 0x0604, "PCI bridge", "pci"},
1223315a1350SMichael S. Tsirkin     { 0x0605, "PCMCIA bridge", "pcmcia"},
1224315a1350SMichael S. Tsirkin     { 0x0606, "NUBUS bridge", "nubus"},
1225315a1350SMichael S. Tsirkin     { 0x0607, "CARDBUS bridge", "cardbus"},
1226315a1350SMichael S. Tsirkin     { 0x0608, "RACEWAY bridge"},
1227315a1350SMichael S. Tsirkin     { 0x0680, "Bridge"},
1228315a1350SMichael S. Tsirkin     { 0x0700, "Serial port", "serial"},
1229315a1350SMichael S. Tsirkin     { 0x0701, "Parallel port", "parallel"},
1230315a1350SMichael S. Tsirkin     { 0x0800, "Interrupt controller", "interrupt-controller"},
1231315a1350SMichael S. Tsirkin     { 0x0801, "DMA controller", "dma-controller"},
1232315a1350SMichael S. Tsirkin     { 0x0802, "Timer", "timer"},
1233315a1350SMichael S. Tsirkin     { 0x0803, "RTC", "rtc"},
1234315a1350SMichael S. Tsirkin     { 0x0900, "Keyboard", "keyboard"},
1235315a1350SMichael S. Tsirkin     { 0x0901, "Pen", "pen"},
1236315a1350SMichael S. Tsirkin     { 0x0902, "Mouse", "mouse"},
1237315a1350SMichael S. Tsirkin     { 0x0A00, "Dock station", "dock", 0x00ff},
1238315a1350SMichael S. Tsirkin     { 0x0B00, "i386 cpu", "cpu", 0x00ff},
1239315a1350SMichael S. Tsirkin     { 0x0c00, "Fireware contorller", "fireware"},
1240315a1350SMichael S. Tsirkin     { 0x0c01, "Access bus controller", "access-bus"},
1241315a1350SMichael S. Tsirkin     { 0x0c02, "SSA controller", "ssa"},
1242315a1350SMichael S. Tsirkin     { 0x0c03, "USB controller", "usb"},
1243315a1350SMichael S. Tsirkin     { 0x0c04, "Fibre channel controller", "fibre-channel"},
1244315a1350SMichael S. Tsirkin     { 0x0c05, "SMBus"},
1245315a1350SMichael S. Tsirkin     { 0, NULL}
1246315a1350SMichael S. Tsirkin };
1247315a1350SMichael S. Tsirkin 
1248315a1350SMichael S. Tsirkin static void pci_for_each_device_under_bus(PCIBus *bus,
1249315a1350SMichael S. Tsirkin                                           void (*fn)(PCIBus *b, PCIDevice *d,
1250315a1350SMichael S. Tsirkin                                                      void *opaque),
1251315a1350SMichael S. Tsirkin                                           void *opaque)
1252315a1350SMichael S. Tsirkin {
1253315a1350SMichael S. Tsirkin     PCIDevice *d;
1254315a1350SMichael S. Tsirkin     int devfn;
1255315a1350SMichael S. Tsirkin 
1256315a1350SMichael S. Tsirkin     for(devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
1257315a1350SMichael S. Tsirkin         d = bus->devices[devfn];
1258315a1350SMichael S. Tsirkin         if (d) {
1259315a1350SMichael S. Tsirkin             fn(bus, d, opaque);
1260315a1350SMichael S. Tsirkin         }
1261315a1350SMichael S. Tsirkin     }
1262315a1350SMichael S. Tsirkin }
1263315a1350SMichael S. Tsirkin 
1264315a1350SMichael S. Tsirkin void pci_for_each_device(PCIBus *bus, int bus_num,
1265315a1350SMichael S. Tsirkin                          void (*fn)(PCIBus *b, PCIDevice *d, void *opaque),
1266315a1350SMichael S. Tsirkin                          void *opaque)
1267315a1350SMichael S. Tsirkin {
1268315a1350SMichael S. Tsirkin     bus = pci_find_bus_nr(bus, bus_num);
1269315a1350SMichael S. Tsirkin 
1270315a1350SMichael S. Tsirkin     if (bus) {
1271315a1350SMichael S. Tsirkin         pci_for_each_device_under_bus(bus, fn, opaque);
1272315a1350SMichael S. Tsirkin     }
1273315a1350SMichael S. Tsirkin }
1274315a1350SMichael S. Tsirkin 
1275315a1350SMichael S. Tsirkin static const pci_class_desc *get_class_desc(int class)
1276315a1350SMichael S. Tsirkin {
1277315a1350SMichael S. Tsirkin     const pci_class_desc *desc;
1278315a1350SMichael S. Tsirkin 
1279315a1350SMichael S. Tsirkin     desc = pci_class_descriptions;
1280315a1350SMichael S. Tsirkin     while (desc->desc && class != desc->class) {
1281315a1350SMichael S. Tsirkin         desc++;
1282315a1350SMichael S. Tsirkin     }
1283315a1350SMichael S. Tsirkin 
1284315a1350SMichael S. Tsirkin     return desc;
1285315a1350SMichael S. Tsirkin }
1286315a1350SMichael S. Tsirkin 
1287315a1350SMichael S. Tsirkin static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
1288315a1350SMichael S. Tsirkin 
1289315a1350SMichael S. Tsirkin static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev)
1290315a1350SMichael S. Tsirkin {
1291315a1350SMichael S. Tsirkin     PciMemoryRegionList *head = NULL, *cur_item = NULL;
1292315a1350SMichael S. Tsirkin     int i;
1293315a1350SMichael S. Tsirkin 
1294315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_REGIONS; i++) {
1295315a1350SMichael S. Tsirkin         const PCIIORegion *r = &dev->io_regions[i];
1296315a1350SMichael S. Tsirkin         PciMemoryRegionList *region;
1297315a1350SMichael S. Tsirkin 
1298315a1350SMichael S. Tsirkin         if (!r->size) {
1299315a1350SMichael S. Tsirkin             continue;
1300315a1350SMichael S. Tsirkin         }
1301315a1350SMichael S. Tsirkin 
1302315a1350SMichael S. Tsirkin         region = g_malloc0(sizeof(*region));
1303315a1350SMichael S. Tsirkin         region->value = g_malloc0(sizeof(*region->value));
1304315a1350SMichael S. Tsirkin 
1305315a1350SMichael S. Tsirkin         if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
1306315a1350SMichael S. Tsirkin             region->value->type = g_strdup("io");
1307315a1350SMichael S. Tsirkin         } else {
1308315a1350SMichael S. Tsirkin             region->value->type = g_strdup("memory");
1309315a1350SMichael S. Tsirkin             region->value->has_prefetch = true;
1310315a1350SMichael S. Tsirkin             region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH);
1311315a1350SMichael S. Tsirkin             region->value->has_mem_type_64 = true;
1312315a1350SMichael S. Tsirkin             region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64);
1313315a1350SMichael S. Tsirkin         }
1314315a1350SMichael S. Tsirkin 
1315315a1350SMichael S. Tsirkin         region->value->bar = i;
1316315a1350SMichael S. Tsirkin         region->value->address = r->addr;
1317315a1350SMichael S. Tsirkin         region->value->size = r->size;
1318315a1350SMichael S. Tsirkin 
1319315a1350SMichael S. Tsirkin         /* XXX: waiting for the qapi to support GSList */
1320315a1350SMichael S. Tsirkin         if (!cur_item) {
1321315a1350SMichael S. Tsirkin             head = cur_item = region;
1322315a1350SMichael S. Tsirkin         } else {
1323315a1350SMichael S. Tsirkin             cur_item->next = region;
1324315a1350SMichael S. Tsirkin             cur_item = region;
1325315a1350SMichael S. Tsirkin         }
1326315a1350SMichael S. Tsirkin     }
1327315a1350SMichael S. Tsirkin 
1328315a1350SMichael S. Tsirkin     return head;
1329315a1350SMichael S. Tsirkin }
1330315a1350SMichael S. Tsirkin 
1331315a1350SMichael S. Tsirkin static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus,
1332315a1350SMichael S. Tsirkin                                            int bus_num)
1333315a1350SMichael S. Tsirkin {
1334315a1350SMichael S. Tsirkin     PciBridgeInfo *info;
1335315a1350SMichael S. Tsirkin 
1336315a1350SMichael S. Tsirkin     info = g_malloc0(sizeof(*info));
1337315a1350SMichael S. Tsirkin 
1338315a1350SMichael S. Tsirkin     info->bus.number = dev->config[PCI_PRIMARY_BUS];
1339315a1350SMichael S. Tsirkin     info->bus.secondary = dev->config[PCI_SECONDARY_BUS];
1340315a1350SMichael S. Tsirkin     info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS];
1341315a1350SMichael S. Tsirkin 
1342315a1350SMichael S. Tsirkin     info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range));
1343315a1350SMichael S. Tsirkin     info->bus.io_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
1344315a1350SMichael S. Tsirkin     info->bus.io_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
1345315a1350SMichael S. Tsirkin 
1346315a1350SMichael S. Tsirkin     info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range));
1347315a1350SMichael S. Tsirkin     info->bus.memory_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
1348315a1350SMichael S. Tsirkin     info->bus.memory_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
1349315a1350SMichael S. Tsirkin 
1350315a1350SMichael S. Tsirkin     info->bus.prefetchable_range = g_malloc0(sizeof(*info->bus.prefetchable_range));
1351315a1350SMichael S. Tsirkin     info->bus.prefetchable_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
1352315a1350SMichael S. Tsirkin     info->bus.prefetchable_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
1353315a1350SMichael S. Tsirkin 
1354315a1350SMichael S. Tsirkin     if (dev->config[PCI_SECONDARY_BUS] != 0) {
1355315a1350SMichael S. Tsirkin         PCIBus *child_bus = pci_find_bus_nr(bus, dev->config[PCI_SECONDARY_BUS]);
1356315a1350SMichael S. Tsirkin         if (child_bus) {
1357315a1350SMichael S. Tsirkin             info->has_devices = true;
1358315a1350SMichael S. Tsirkin             info->devices = qmp_query_pci_devices(child_bus, dev->config[PCI_SECONDARY_BUS]);
1359315a1350SMichael S. Tsirkin         }
1360315a1350SMichael S. Tsirkin     }
1361315a1350SMichael S. Tsirkin 
1362315a1350SMichael S. Tsirkin     return info;
1363315a1350SMichael S. Tsirkin }
1364315a1350SMichael S. Tsirkin 
1365315a1350SMichael S. Tsirkin static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
1366315a1350SMichael S. Tsirkin                                            int bus_num)
1367315a1350SMichael S. Tsirkin {
1368315a1350SMichael S. Tsirkin     const pci_class_desc *desc;
1369315a1350SMichael S. Tsirkin     PciDeviceInfo *info;
1370315a1350SMichael S. Tsirkin     uint8_t type;
1371315a1350SMichael S. Tsirkin     int class;
1372315a1350SMichael S. Tsirkin 
1373315a1350SMichael S. Tsirkin     info = g_malloc0(sizeof(*info));
1374315a1350SMichael S. Tsirkin     info->bus = bus_num;
1375315a1350SMichael S. Tsirkin     info->slot = PCI_SLOT(dev->devfn);
1376315a1350SMichael S. Tsirkin     info->function = PCI_FUNC(dev->devfn);
1377315a1350SMichael S. Tsirkin 
1378315a1350SMichael S. Tsirkin     class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
1379315a1350SMichael S. Tsirkin     info->class_info.class = class;
1380315a1350SMichael S. Tsirkin     desc = get_class_desc(class);
1381315a1350SMichael S. Tsirkin     if (desc->desc) {
1382315a1350SMichael S. Tsirkin         info->class_info.has_desc = true;
1383315a1350SMichael S. Tsirkin         info->class_info.desc = g_strdup(desc->desc);
1384315a1350SMichael S. Tsirkin     }
1385315a1350SMichael S. Tsirkin 
1386315a1350SMichael S. Tsirkin     info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
1387315a1350SMichael S. Tsirkin     info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID);
1388315a1350SMichael S. Tsirkin     info->regions = qmp_query_pci_regions(dev);
1389315a1350SMichael S. Tsirkin     info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
1390315a1350SMichael S. Tsirkin 
1391315a1350SMichael S. Tsirkin     if (dev->config[PCI_INTERRUPT_PIN] != 0) {
1392315a1350SMichael S. Tsirkin         info->has_irq = true;
1393315a1350SMichael S. Tsirkin         info->irq = dev->config[PCI_INTERRUPT_LINE];
1394315a1350SMichael S. Tsirkin     }
1395315a1350SMichael S. Tsirkin 
1396315a1350SMichael S. Tsirkin     type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
1397315a1350SMichael S. Tsirkin     if (type == PCI_HEADER_TYPE_BRIDGE) {
1398315a1350SMichael S. Tsirkin         info->has_pci_bridge = true;
1399315a1350SMichael S. Tsirkin         info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
1400315a1350SMichael S. Tsirkin     }
1401315a1350SMichael S. Tsirkin 
1402315a1350SMichael S. Tsirkin     return info;
1403315a1350SMichael S. Tsirkin }
1404315a1350SMichael S. Tsirkin 
1405315a1350SMichael S. Tsirkin static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num)
1406315a1350SMichael S. Tsirkin {
1407315a1350SMichael S. Tsirkin     PciDeviceInfoList *info, *head = NULL, *cur_item = NULL;
1408315a1350SMichael S. Tsirkin     PCIDevice *dev;
1409315a1350SMichael S. Tsirkin     int devfn;
1410315a1350SMichael S. Tsirkin 
1411315a1350SMichael S. Tsirkin     for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
1412315a1350SMichael S. Tsirkin         dev = bus->devices[devfn];
1413315a1350SMichael S. Tsirkin         if (dev) {
1414315a1350SMichael S. Tsirkin             info = g_malloc0(sizeof(*info));
1415315a1350SMichael S. Tsirkin             info->value = qmp_query_pci_device(dev, bus, bus_num);
1416315a1350SMichael S. Tsirkin 
1417315a1350SMichael S. Tsirkin             /* XXX: waiting for the qapi to support GSList */
1418315a1350SMichael S. Tsirkin             if (!cur_item) {
1419315a1350SMichael S. Tsirkin                 head = cur_item = info;
1420315a1350SMichael S. Tsirkin             } else {
1421315a1350SMichael S. Tsirkin                 cur_item->next = info;
1422315a1350SMichael S. Tsirkin                 cur_item = info;
1423315a1350SMichael S. Tsirkin             }
1424315a1350SMichael S. Tsirkin         }
1425315a1350SMichael S. Tsirkin     }
1426315a1350SMichael S. Tsirkin 
1427315a1350SMichael S. Tsirkin     return head;
1428315a1350SMichael S. Tsirkin }
1429315a1350SMichael S. Tsirkin 
1430315a1350SMichael S. Tsirkin static PciInfo *qmp_query_pci_bus(PCIBus *bus, int bus_num)
1431315a1350SMichael S. Tsirkin {
1432315a1350SMichael S. Tsirkin     PciInfo *info = NULL;
1433315a1350SMichael S. Tsirkin 
1434315a1350SMichael S. Tsirkin     bus = pci_find_bus_nr(bus, bus_num);
1435315a1350SMichael S. Tsirkin     if (bus) {
1436315a1350SMichael S. Tsirkin         info = g_malloc0(sizeof(*info));
1437315a1350SMichael S. Tsirkin         info->bus = bus_num;
1438315a1350SMichael S. Tsirkin         info->devices = qmp_query_pci_devices(bus, bus_num);
1439315a1350SMichael S. Tsirkin     }
1440315a1350SMichael S. Tsirkin 
1441315a1350SMichael S. Tsirkin     return info;
1442315a1350SMichael S. Tsirkin }
1443315a1350SMichael S. Tsirkin 
1444315a1350SMichael S. Tsirkin PciInfoList *qmp_query_pci(Error **errp)
1445315a1350SMichael S. Tsirkin {
1446315a1350SMichael S. Tsirkin     PciInfoList *info, *head = NULL, *cur_item = NULL;
1447315a1350SMichael S. Tsirkin     struct PCIHostBus *host;
1448315a1350SMichael S. Tsirkin 
1449315a1350SMichael S. Tsirkin     QLIST_FOREACH(host, &host_buses, next) {
1450315a1350SMichael S. Tsirkin         info = g_malloc0(sizeof(*info));
1451315a1350SMichael S. Tsirkin         info->value = qmp_query_pci_bus(host->bus, 0);
1452315a1350SMichael S. Tsirkin 
1453315a1350SMichael S. Tsirkin         /* XXX: waiting for the qapi to support GSList */
1454315a1350SMichael S. Tsirkin         if (!cur_item) {
1455315a1350SMichael S. Tsirkin             head = cur_item = info;
1456315a1350SMichael S. Tsirkin         } else {
1457315a1350SMichael S. Tsirkin             cur_item->next = info;
1458315a1350SMichael S. Tsirkin             cur_item = info;
1459315a1350SMichael S. Tsirkin         }
1460315a1350SMichael S. Tsirkin     }
1461315a1350SMichael S. Tsirkin 
1462315a1350SMichael S. Tsirkin     return head;
1463315a1350SMichael S. Tsirkin }
1464315a1350SMichael S. Tsirkin 
1465315a1350SMichael S. Tsirkin static const char * const pci_nic_models[] = {
1466315a1350SMichael S. Tsirkin     "ne2k_pci",
1467315a1350SMichael S. Tsirkin     "i82551",
1468315a1350SMichael S. Tsirkin     "i82557b",
1469315a1350SMichael S. Tsirkin     "i82559er",
1470315a1350SMichael S. Tsirkin     "rtl8139",
1471315a1350SMichael S. Tsirkin     "e1000",
1472315a1350SMichael S. Tsirkin     "pcnet",
1473315a1350SMichael S. Tsirkin     "virtio",
1474315a1350SMichael S. Tsirkin     NULL
1475315a1350SMichael S. Tsirkin };
1476315a1350SMichael S. Tsirkin 
1477315a1350SMichael S. Tsirkin static const char * const pci_nic_names[] = {
1478315a1350SMichael S. Tsirkin     "ne2k_pci",
1479315a1350SMichael S. Tsirkin     "i82551",
1480315a1350SMichael S. Tsirkin     "i82557b",
1481315a1350SMichael S. Tsirkin     "i82559er",
1482315a1350SMichael S. Tsirkin     "rtl8139",
1483315a1350SMichael S. Tsirkin     "e1000",
1484315a1350SMichael S. Tsirkin     "pcnet",
1485315a1350SMichael S. Tsirkin     "virtio-net-pci",
1486315a1350SMichael S. Tsirkin     NULL
1487315a1350SMichael S. Tsirkin };
1488315a1350SMichael S. Tsirkin 
1489315a1350SMichael S. Tsirkin /* Initialize a PCI NIC.  */
1490315a1350SMichael S. Tsirkin /* FIXME callers should check for failure, but don't */
1491315a1350SMichael S. Tsirkin PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
1492315a1350SMichael S. Tsirkin                         const char *default_devaddr)
1493315a1350SMichael S. Tsirkin {
1494315a1350SMichael S. Tsirkin     const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
1495315a1350SMichael S. Tsirkin     PCIBus *bus;
1496315a1350SMichael S. Tsirkin     int devfn;
1497315a1350SMichael S. Tsirkin     PCIDevice *pci_dev;
1498315a1350SMichael S. Tsirkin     DeviceState *dev;
1499315a1350SMichael S. Tsirkin     int i;
1500315a1350SMichael S. Tsirkin 
1501315a1350SMichael S. Tsirkin     i = qemu_find_nic_model(nd, pci_nic_models, default_model);
1502315a1350SMichael S. Tsirkin     if (i < 0)
1503315a1350SMichael S. Tsirkin         return NULL;
1504315a1350SMichael S. Tsirkin 
1505315a1350SMichael S. Tsirkin     bus = pci_get_bus_devfn(&devfn, devaddr);
1506315a1350SMichael S. Tsirkin     if (!bus) {
1507315a1350SMichael S. Tsirkin         error_report("Invalid PCI device address %s for device %s",
1508315a1350SMichael S. Tsirkin                      devaddr, pci_nic_names[i]);
1509315a1350SMichael S. Tsirkin         return NULL;
1510315a1350SMichael S. Tsirkin     }
1511315a1350SMichael S. Tsirkin 
1512315a1350SMichael S. Tsirkin     pci_dev = pci_create(bus, devfn, pci_nic_names[i]);
1513315a1350SMichael S. Tsirkin     dev = &pci_dev->qdev;
1514315a1350SMichael S. Tsirkin     qdev_set_nic_properties(dev, nd);
1515315a1350SMichael S. Tsirkin     if (qdev_init(dev) < 0)
1516315a1350SMichael S. Tsirkin         return NULL;
1517315a1350SMichael S. Tsirkin     return pci_dev;
1518315a1350SMichael S. Tsirkin }
1519315a1350SMichael S. Tsirkin 
1520315a1350SMichael S. Tsirkin PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,
1521315a1350SMichael S. Tsirkin                                const char *default_devaddr)
1522315a1350SMichael S. Tsirkin {
1523315a1350SMichael S. Tsirkin     PCIDevice *res;
1524315a1350SMichael S. Tsirkin 
1525315a1350SMichael S. Tsirkin     if (qemu_show_nic_models(nd->model, pci_nic_models))
1526315a1350SMichael S. Tsirkin         exit(0);
1527315a1350SMichael S. Tsirkin 
1528315a1350SMichael S. Tsirkin     res = pci_nic_init(nd, default_model, default_devaddr);
1529315a1350SMichael S. Tsirkin     if (!res)
1530315a1350SMichael S. Tsirkin         exit(1);
1531315a1350SMichael S. Tsirkin     return res;
1532315a1350SMichael S. Tsirkin }
1533315a1350SMichael S. Tsirkin 
1534315a1350SMichael S. Tsirkin PCIDevice *pci_vga_init(PCIBus *bus)
1535315a1350SMichael S. Tsirkin {
1536315a1350SMichael S. Tsirkin     switch (vga_interface_type) {
1537315a1350SMichael S. Tsirkin     case VGA_CIRRUS:
1538315a1350SMichael S. Tsirkin         return pci_create_simple(bus, -1, "cirrus-vga");
1539315a1350SMichael S. Tsirkin     case VGA_QXL:
1540315a1350SMichael S. Tsirkin         return pci_create_simple(bus, -1, "qxl-vga");
1541315a1350SMichael S. Tsirkin     case VGA_STD:
1542315a1350SMichael S. Tsirkin         return pci_create_simple(bus, -1, "VGA");
1543315a1350SMichael S. Tsirkin     case VGA_VMWARE:
1544315a1350SMichael S. Tsirkin         return pci_create_simple(bus, -1, "vmware-svga");
1545315a1350SMichael S. Tsirkin     case VGA_NONE:
1546315a1350SMichael S. Tsirkin     default: /* Other non-PCI types. Checking for unsupported types is already
1547315a1350SMichael S. Tsirkin                 done in vl.c. */
1548315a1350SMichael S. Tsirkin         return NULL;
1549315a1350SMichael S. Tsirkin     }
1550315a1350SMichael S. Tsirkin }
1551315a1350SMichael S. Tsirkin 
1552315a1350SMichael S. Tsirkin /* Whether a given bus number is in range of the secondary
1553315a1350SMichael S. Tsirkin  * bus of the given bridge device. */
1554315a1350SMichael S. Tsirkin static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
1555315a1350SMichael S. Tsirkin {
1556315a1350SMichael S. Tsirkin     return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) &
1557315a1350SMichael S. Tsirkin              PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */ &&
1558315a1350SMichael S. Tsirkin         dev->config[PCI_SECONDARY_BUS] < bus_num &&
1559315a1350SMichael S. Tsirkin         bus_num <= dev->config[PCI_SUBORDINATE_BUS];
1560315a1350SMichael S. Tsirkin }
1561315a1350SMichael S. Tsirkin 
1562315a1350SMichael S. Tsirkin static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
1563315a1350SMichael S. Tsirkin {
1564315a1350SMichael S. Tsirkin     PCIBus *sec;
1565315a1350SMichael S. Tsirkin 
1566315a1350SMichael S. Tsirkin     if (!bus) {
1567315a1350SMichael S. Tsirkin         return NULL;
1568315a1350SMichael S. Tsirkin     }
1569315a1350SMichael S. Tsirkin 
1570315a1350SMichael S. Tsirkin     if (pci_bus_num(bus) == bus_num) {
1571315a1350SMichael S. Tsirkin         return bus;
1572315a1350SMichael S. Tsirkin     }
1573315a1350SMichael S. Tsirkin 
1574315a1350SMichael S. Tsirkin     /* Consider all bus numbers in range for the host pci bridge. */
1575315a1350SMichael S. Tsirkin     if (bus->parent_dev &&
1576315a1350SMichael S. Tsirkin         !pci_secondary_bus_in_range(bus->parent_dev, bus_num)) {
1577315a1350SMichael S. Tsirkin         return NULL;
1578315a1350SMichael S. Tsirkin     }
1579315a1350SMichael S. Tsirkin 
1580315a1350SMichael S. Tsirkin     /* try child bus */
1581315a1350SMichael S. Tsirkin     for (; bus; bus = sec) {
1582315a1350SMichael S. Tsirkin         QLIST_FOREACH(sec, &bus->child, sibling) {
1583315a1350SMichael S. Tsirkin             assert(sec->parent_dev);
1584315a1350SMichael S. Tsirkin             if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) {
1585315a1350SMichael S. Tsirkin                 return sec;
1586315a1350SMichael S. Tsirkin             }
1587315a1350SMichael S. Tsirkin             if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) {
1588315a1350SMichael S. Tsirkin                 break;
1589315a1350SMichael S. Tsirkin             }
1590315a1350SMichael S. Tsirkin         }
1591315a1350SMichael S. Tsirkin     }
1592315a1350SMichael S. Tsirkin 
1593315a1350SMichael S. Tsirkin     return NULL;
1594315a1350SMichael S. Tsirkin }
1595315a1350SMichael S. Tsirkin 
1596315a1350SMichael S. Tsirkin PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
1597315a1350SMichael S. Tsirkin {
1598315a1350SMichael S. Tsirkin     bus = pci_find_bus_nr(bus, bus_num);
1599315a1350SMichael S. Tsirkin 
1600315a1350SMichael S. Tsirkin     if (!bus)
1601315a1350SMichael S. Tsirkin         return NULL;
1602315a1350SMichael S. Tsirkin 
1603315a1350SMichael S. Tsirkin     return bus->devices[devfn];
1604315a1350SMichael S. Tsirkin }
1605315a1350SMichael S. Tsirkin 
1606315a1350SMichael S. Tsirkin static int pci_qdev_init(DeviceState *qdev)
1607315a1350SMichael S. Tsirkin {
1608315a1350SMichael S. Tsirkin     PCIDevice *pci_dev = (PCIDevice *)qdev;
1609315a1350SMichael S. Tsirkin     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
1610315a1350SMichael S. Tsirkin     PCIBus *bus;
1611315a1350SMichael S. Tsirkin     int rc;
1612315a1350SMichael S. Tsirkin     bool is_default_rom;
1613315a1350SMichael S. Tsirkin 
1614315a1350SMichael S. Tsirkin     /* initialize cap_present for pci_is_express() and pci_config_size() */
1615315a1350SMichael S. Tsirkin     if (pc->is_express) {
1616315a1350SMichael S. Tsirkin         pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
1617315a1350SMichael S. Tsirkin     }
1618315a1350SMichael S. Tsirkin 
1619315a1350SMichael S. Tsirkin     bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
1620315a1350SMichael S. Tsirkin     pci_dev = do_pci_register_device(pci_dev, bus,
1621315a1350SMichael S. Tsirkin                                      object_get_typename(OBJECT(qdev)),
1622315a1350SMichael S. Tsirkin                                      pci_dev->devfn);
1623315a1350SMichael S. Tsirkin     if (pci_dev == NULL)
1624315a1350SMichael S. Tsirkin         return -1;
1625315a1350SMichael S. Tsirkin     if (qdev->hotplugged && pc->no_hotplug) {
1626315a1350SMichael S. Tsirkin         qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(pci_dev)));
1627315a1350SMichael S. Tsirkin         do_pci_unregister_device(pci_dev);
1628315a1350SMichael S. Tsirkin         return -1;
1629315a1350SMichael S. Tsirkin     }
1630315a1350SMichael S. Tsirkin     if (pc->init) {
1631315a1350SMichael S. Tsirkin         rc = pc->init(pci_dev);
1632315a1350SMichael S. Tsirkin         if (rc != 0) {
1633315a1350SMichael S. Tsirkin             do_pci_unregister_device(pci_dev);
1634315a1350SMichael S. Tsirkin             return rc;
1635315a1350SMichael S. Tsirkin         }
1636315a1350SMichael S. Tsirkin     }
1637315a1350SMichael S. Tsirkin 
1638315a1350SMichael S. Tsirkin     /* rom loading */
1639315a1350SMichael S. Tsirkin     is_default_rom = false;
1640315a1350SMichael S. Tsirkin     if (pci_dev->romfile == NULL && pc->romfile != NULL) {
1641315a1350SMichael S. Tsirkin         pci_dev->romfile = g_strdup(pc->romfile);
1642315a1350SMichael S. Tsirkin         is_default_rom = true;
1643315a1350SMichael S. Tsirkin     }
1644315a1350SMichael S. Tsirkin     pci_add_option_rom(pci_dev, is_default_rom);
1645315a1350SMichael S. Tsirkin 
1646315a1350SMichael S. Tsirkin     if (bus->hotplug) {
1647315a1350SMichael S. Tsirkin         /* Let buses differentiate between hotplug and when device is
1648315a1350SMichael S. Tsirkin          * enabled during qemu machine creation. */
1649315a1350SMichael S. Tsirkin         rc = bus->hotplug(bus->hotplug_qdev, pci_dev,
1650315a1350SMichael S. Tsirkin                           qdev->hotplugged ? PCI_HOTPLUG_ENABLED:
1651315a1350SMichael S. Tsirkin                           PCI_COLDPLUG_ENABLED);
1652315a1350SMichael S. Tsirkin         if (rc != 0) {
1653315a1350SMichael S. Tsirkin             int r = pci_unregister_device(&pci_dev->qdev);
1654315a1350SMichael S. Tsirkin             assert(!r);
1655315a1350SMichael S. Tsirkin             return rc;
1656315a1350SMichael S. Tsirkin         }
1657315a1350SMichael S. Tsirkin     }
1658315a1350SMichael S. Tsirkin     return 0;
1659315a1350SMichael S. Tsirkin }
1660315a1350SMichael S. Tsirkin 
1661315a1350SMichael S. Tsirkin static int pci_unplug_device(DeviceState *qdev)
1662315a1350SMichael S. Tsirkin {
1663315a1350SMichael S. Tsirkin     PCIDevice *dev = PCI_DEVICE(qdev);
1664315a1350SMichael S. Tsirkin     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
1665315a1350SMichael S. Tsirkin 
1666315a1350SMichael S. Tsirkin     if (pc->no_hotplug) {
1667315a1350SMichael S. Tsirkin         qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev)));
1668315a1350SMichael S. Tsirkin         return -1;
1669315a1350SMichael S. Tsirkin     }
1670315a1350SMichael S. Tsirkin     return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
1671315a1350SMichael S. Tsirkin                              PCI_HOTPLUG_DISABLED);
1672315a1350SMichael S. Tsirkin }
1673315a1350SMichael S. Tsirkin 
1674315a1350SMichael S. Tsirkin PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
1675315a1350SMichael S. Tsirkin                                     const char *name)
1676315a1350SMichael S. Tsirkin {
1677315a1350SMichael S. Tsirkin     DeviceState *dev;
1678315a1350SMichael S. Tsirkin 
1679315a1350SMichael S. Tsirkin     dev = qdev_create(&bus->qbus, name);
1680315a1350SMichael S. Tsirkin     qdev_prop_set_int32(dev, "addr", devfn);
1681315a1350SMichael S. Tsirkin     qdev_prop_set_bit(dev, "multifunction", multifunction);
1682315a1350SMichael S. Tsirkin     return PCI_DEVICE(dev);
1683315a1350SMichael S. Tsirkin }
1684315a1350SMichael S. Tsirkin 
1685315a1350SMichael S. Tsirkin PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
1686315a1350SMichael S. Tsirkin                                            bool multifunction,
1687315a1350SMichael S. Tsirkin                                            const char *name)
1688315a1350SMichael S. Tsirkin {
1689315a1350SMichael S. Tsirkin     PCIDevice *dev = pci_create_multifunction(bus, devfn, multifunction, name);
1690315a1350SMichael S. Tsirkin     qdev_init_nofail(&dev->qdev);
1691315a1350SMichael S. Tsirkin     return dev;
1692315a1350SMichael S. Tsirkin }
1693315a1350SMichael S. Tsirkin 
1694315a1350SMichael S. Tsirkin PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name)
1695315a1350SMichael S. Tsirkin {
1696315a1350SMichael S. Tsirkin     return pci_create_multifunction(bus, devfn, false, name);
1697315a1350SMichael S. Tsirkin }
1698315a1350SMichael S. Tsirkin 
1699315a1350SMichael S. Tsirkin PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
1700315a1350SMichael S. Tsirkin {
1701315a1350SMichael S. Tsirkin     return pci_create_simple_multifunction(bus, devfn, false, name);
1702315a1350SMichael S. Tsirkin }
1703315a1350SMichael S. Tsirkin 
1704315a1350SMichael S. Tsirkin static uint8_t pci_find_space(PCIDevice *pdev, uint8_t size)
1705315a1350SMichael S. Tsirkin {
1706315a1350SMichael S. Tsirkin     int offset = PCI_CONFIG_HEADER_SIZE;
1707315a1350SMichael S. Tsirkin     int i;
1708315a1350SMichael S. Tsirkin     for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i) {
1709315a1350SMichael S. Tsirkin         if (pdev->used[i])
1710315a1350SMichael S. Tsirkin             offset = i + 1;
1711315a1350SMichael S. Tsirkin         else if (i - offset + 1 == size)
1712315a1350SMichael S. Tsirkin             return offset;
1713315a1350SMichael S. Tsirkin     }
1714315a1350SMichael S. Tsirkin     return 0;
1715315a1350SMichael S. Tsirkin }
1716315a1350SMichael S. Tsirkin 
1717315a1350SMichael S. Tsirkin static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
1718315a1350SMichael S. Tsirkin                                         uint8_t *prev_p)
1719315a1350SMichael S. Tsirkin {
1720315a1350SMichael S. Tsirkin     uint8_t next, prev;
1721315a1350SMichael S. Tsirkin 
1722315a1350SMichael S. Tsirkin     if (!(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST))
1723315a1350SMichael S. Tsirkin         return 0;
1724315a1350SMichael S. Tsirkin 
1725315a1350SMichael S. Tsirkin     for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
1726315a1350SMichael S. Tsirkin          prev = next + PCI_CAP_LIST_NEXT)
1727315a1350SMichael S. Tsirkin         if (pdev->config[next + PCI_CAP_LIST_ID] == cap_id)
1728315a1350SMichael S. Tsirkin             break;
1729315a1350SMichael S. Tsirkin 
1730315a1350SMichael S. Tsirkin     if (prev_p)
1731315a1350SMichael S. Tsirkin         *prev_p = prev;
1732315a1350SMichael S. Tsirkin     return next;
1733315a1350SMichael S. Tsirkin }
1734315a1350SMichael S. Tsirkin 
1735315a1350SMichael S. Tsirkin static uint8_t pci_find_capability_at_offset(PCIDevice *pdev, uint8_t offset)
1736315a1350SMichael S. Tsirkin {
1737315a1350SMichael S. Tsirkin     uint8_t next, prev, found = 0;
1738315a1350SMichael S. Tsirkin 
1739315a1350SMichael S. Tsirkin     if (!(pdev->used[offset])) {
1740315a1350SMichael S. Tsirkin         return 0;
1741315a1350SMichael S. Tsirkin     }
1742315a1350SMichael S. Tsirkin 
1743315a1350SMichael S. Tsirkin     assert(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST);
1744315a1350SMichael S. Tsirkin 
1745315a1350SMichael S. Tsirkin     for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
1746315a1350SMichael S. Tsirkin          prev = next + PCI_CAP_LIST_NEXT) {
1747315a1350SMichael S. Tsirkin         if (next <= offset && next > found) {
1748315a1350SMichael S. Tsirkin             found = next;
1749315a1350SMichael S. Tsirkin         }
1750315a1350SMichael S. Tsirkin     }
1751315a1350SMichael S. Tsirkin     return found;
1752315a1350SMichael S. Tsirkin }
1753315a1350SMichael S. Tsirkin 
1754315a1350SMichael S. Tsirkin /* Patch the PCI vendor and device ids in a PCI rom image if necessary.
1755315a1350SMichael S. Tsirkin    This is needed for an option rom which is used for more than one device. */
1756315a1350SMichael S. Tsirkin static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
1757315a1350SMichael S. Tsirkin {
1758315a1350SMichael S. Tsirkin     uint16_t vendor_id;
1759315a1350SMichael S. Tsirkin     uint16_t device_id;
1760315a1350SMichael S. Tsirkin     uint16_t rom_vendor_id;
1761315a1350SMichael S. Tsirkin     uint16_t rom_device_id;
1762315a1350SMichael S. Tsirkin     uint16_t rom_magic;
1763315a1350SMichael S. Tsirkin     uint16_t pcir_offset;
1764315a1350SMichael S. Tsirkin     uint8_t checksum;
1765315a1350SMichael S. Tsirkin 
1766315a1350SMichael S. Tsirkin     /* Words in rom data are little endian (like in PCI configuration),
1767315a1350SMichael S. Tsirkin        so they can be read / written with pci_get_word / pci_set_word. */
1768315a1350SMichael S. Tsirkin 
1769315a1350SMichael S. Tsirkin     /* Only a valid rom will be patched. */
1770315a1350SMichael S. Tsirkin     rom_magic = pci_get_word(ptr);
1771315a1350SMichael S. Tsirkin     if (rom_magic != 0xaa55) {
1772315a1350SMichael S. Tsirkin         PCI_DPRINTF("Bad ROM magic %04x\n", rom_magic);
1773315a1350SMichael S. Tsirkin         return;
1774315a1350SMichael S. Tsirkin     }
1775315a1350SMichael S. Tsirkin     pcir_offset = pci_get_word(ptr + 0x18);
1776315a1350SMichael S. Tsirkin     if (pcir_offset + 8 >= size || memcmp(ptr + pcir_offset, "PCIR", 4)) {
1777315a1350SMichael S. Tsirkin         PCI_DPRINTF("Bad PCIR offset 0x%x or signature\n", pcir_offset);
1778315a1350SMichael S. Tsirkin         return;
1779315a1350SMichael S. Tsirkin     }
1780315a1350SMichael S. Tsirkin 
1781315a1350SMichael S. Tsirkin     vendor_id = pci_get_word(pdev->config + PCI_VENDOR_ID);
1782315a1350SMichael S. Tsirkin     device_id = pci_get_word(pdev->config + PCI_DEVICE_ID);
1783315a1350SMichael S. Tsirkin     rom_vendor_id = pci_get_word(ptr + pcir_offset + 4);
1784315a1350SMichael S. Tsirkin     rom_device_id = pci_get_word(ptr + pcir_offset + 6);
1785315a1350SMichael S. Tsirkin 
1786315a1350SMichael S. Tsirkin     PCI_DPRINTF("%s: ROM id %04x%04x / PCI id %04x%04x\n", pdev->romfile,
1787315a1350SMichael S. Tsirkin                 vendor_id, device_id, rom_vendor_id, rom_device_id);
1788315a1350SMichael S. Tsirkin 
1789315a1350SMichael S. Tsirkin     checksum = ptr[6];
1790315a1350SMichael S. Tsirkin 
1791315a1350SMichael S. Tsirkin     if (vendor_id != rom_vendor_id) {
1792315a1350SMichael S. Tsirkin         /* Patch vendor id and checksum (at offset 6 for etherboot roms). */
1793315a1350SMichael S. Tsirkin         checksum += (uint8_t)rom_vendor_id + (uint8_t)(rom_vendor_id >> 8);
1794315a1350SMichael S. Tsirkin         checksum -= (uint8_t)vendor_id + (uint8_t)(vendor_id >> 8);
1795315a1350SMichael S. Tsirkin         PCI_DPRINTF("ROM checksum %02x / %02x\n", ptr[6], checksum);
1796315a1350SMichael S. Tsirkin         ptr[6] = checksum;
1797315a1350SMichael S. Tsirkin         pci_set_word(ptr + pcir_offset + 4, vendor_id);
1798315a1350SMichael S. Tsirkin     }
1799315a1350SMichael S. Tsirkin 
1800315a1350SMichael S. Tsirkin     if (device_id != rom_device_id) {
1801315a1350SMichael S. Tsirkin         /* Patch device id and checksum (at offset 6 for etherboot roms). */
1802315a1350SMichael S. Tsirkin         checksum += (uint8_t)rom_device_id + (uint8_t)(rom_device_id >> 8);
1803315a1350SMichael S. Tsirkin         checksum -= (uint8_t)device_id + (uint8_t)(device_id >> 8);
1804315a1350SMichael S. Tsirkin         PCI_DPRINTF("ROM checksum %02x / %02x\n", ptr[6], checksum);
1805315a1350SMichael S. Tsirkin         ptr[6] = checksum;
1806315a1350SMichael S. Tsirkin         pci_set_word(ptr + pcir_offset + 6, device_id);
1807315a1350SMichael S. Tsirkin     }
1808315a1350SMichael S. Tsirkin }
1809315a1350SMichael S. Tsirkin 
1810315a1350SMichael S. Tsirkin /* Add an option rom for the device */
1811315a1350SMichael S. Tsirkin static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
1812315a1350SMichael S. Tsirkin {
1813315a1350SMichael S. Tsirkin     int size;
1814315a1350SMichael S. Tsirkin     char *path;
1815315a1350SMichael S. Tsirkin     void *ptr;
1816315a1350SMichael S. Tsirkin     char name[32];
1817315a1350SMichael S. Tsirkin     const VMStateDescription *vmsd;
1818315a1350SMichael S. Tsirkin 
1819315a1350SMichael S. Tsirkin     if (!pdev->romfile)
1820315a1350SMichael S. Tsirkin         return 0;
1821315a1350SMichael S. Tsirkin     if (strlen(pdev->romfile) == 0)
1822315a1350SMichael S. Tsirkin         return 0;
1823315a1350SMichael S. Tsirkin 
1824315a1350SMichael S. Tsirkin     if (!pdev->rom_bar) {
1825315a1350SMichael S. Tsirkin         /*
1826315a1350SMichael S. Tsirkin          * Load rom via fw_cfg instead of creating a rom bar,
1827315a1350SMichael S. Tsirkin          * for 0.11 compatibility.
1828315a1350SMichael S. Tsirkin          */
1829315a1350SMichael S. Tsirkin         int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
1830315a1350SMichael S. Tsirkin         if (class == 0x0300) {
1831315a1350SMichael S. Tsirkin             rom_add_vga(pdev->romfile);
1832315a1350SMichael S. Tsirkin         } else {
1833315a1350SMichael S. Tsirkin             rom_add_option(pdev->romfile, -1);
1834315a1350SMichael S. Tsirkin         }
1835315a1350SMichael S. Tsirkin         return 0;
1836315a1350SMichael S. Tsirkin     }
1837315a1350SMichael S. Tsirkin 
1838315a1350SMichael S. Tsirkin     path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
1839315a1350SMichael S. Tsirkin     if (path == NULL) {
1840315a1350SMichael S. Tsirkin         path = g_strdup(pdev->romfile);
1841315a1350SMichael S. Tsirkin     }
1842315a1350SMichael S. Tsirkin 
1843315a1350SMichael S. Tsirkin     size = get_image_size(path);
1844315a1350SMichael S. Tsirkin     if (size < 0) {
1845315a1350SMichael S. Tsirkin         error_report("%s: failed to find romfile \"%s\"",
1846315a1350SMichael S. Tsirkin                      __FUNCTION__, pdev->romfile);
1847315a1350SMichael S. Tsirkin         g_free(path);
1848315a1350SMichael S. Tsirkin         return -1;
1849315a1350SMichael S. Tsirkin     }
1850315a1350SMichael S. Tsirkin     if (size & (size - 1)) {
1851315a1350SMichael S. Tsirkin         size = 1 << qemu_fls(size);
1852315a1350SMichael S. Tsirkin     }
1853315a1350SMichael S. Tsirkin 
1854315a1350SMichael S. Tsirkin     vmsd = qdev_get_vmsd(DEVICE(pdev));
1855315a1350SMichael S. Tsirkin 
1856315a1350SMichael S. Tsirkin     if (vmsd) {
1857315a1350SMichael S. Tsirkin         snprintf(name, sizeof(name), "%s.rom", vmsd->name);
1858315a1350SMichael S. Tsirkin     } else {
1859315a1350SMichael S. Tsirkin         snprintf(name, sizeof(name), "%s.rom", object_get_typename(OBJECT(pdev)));
1860315a1350SMichael S. Tsirkin     }
1861315a1350SMichael S. Tsirkin     pdev->has_rom = true;
1862315a1350SMichael S. Tsirkin     memory_region_init_ram(&pdev->rom, name, size);
1863315a1350SMichael S. Tsirkin     vmstate_register_ram(&pdev->rom, &pdev->qdev);
1864315a1350SMichael S. Tsirkin     ptr = memory_region_get_ram_ptr(&pdev->rom);
1865315a1350SMichael S. Tsirkin     load_image(path, ptr);
1866315a1350SMichael S. Tsirkin     g_free(path);
1867315a1350SMichael S. Tsirkin 
1868315a1350SMichael S. Tsirkin     if (is_default_rom) {
1869315a1350SMichael S. Tsirkin         /* Only the default rom images will be patched (if needed). */
1870315a1350SMichael S. Tsirkin         pci_patch_ids(pdev, ptr, size);
1871315a1350SMichael S. Tsirkin     }
1872315a1350SMichael S. Tsirkin 
1873315a1350SMichael S. Tsirkin     qemu_put_ram_ptr(ptr);
1874315a1350SMichael S. Tsirkin 
1875315a1350SMichael S. Tsirkin     pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
1876315a1350SMichael S. Tsirkin 
1877315a1350SMichael S. Tsirkin     return 0;
1878315a1350SMichael S. Tsirkin }
1879315a1350SMichael S. Tsirkin 
1880315a1350SMichael S. Tsirkin static void pci_del_option_rom(PCIDevice *pdev)
1881315a1350SMichael S. Tsirkin {
1882315a1350SMichael S. Tsirkin     if (!pdev->has_rom)
1883315a1350SMichael S. Tsirkin         return;
1884315a1350SMichael S. Tsirkin 
1885315a1350SMichael S. Tsirkin     vmstate_unregister_ram(&pdev->rom, &pdev->qdev);
1886315a1350SMichael S. Tsirkin     memory_region_destroy(&pdev->rom);
1887315a1350SMichael S. Tsirkin     pdev->has_rom = false;
1888315a1350SMichael S. Tsirkin }
1889315a1350SMichael S. Tsirkin 
1890315a1350SMichael S. Tsirkin /*
1891315a1350SMichael S. Tsirkin  * if !offset
1892315a1350SMichael S. Tsirkin  * Reserve space and add capability to the linked list in pci config space
1893315a1350SMichael S. Tsirkin  *
1894315a1350SMichael S. Tsirkin  * if offset = 0,
1895315a1350SMichael S. Tsirkin  * Find and reserve space and add capability to the linked list
1896315a1350SMichael S. Tsirkin  * in pci config space */
1897315a1350SMichael S. Tsirkin int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
1898315a1350SMichael S. Tsirkin                        uint8_t offset, uint8_t size)
1899315a1350SMichael S. Tsirkin {
1900315a1350SMichael S. Tsirkin     uint8_t *config;
1901315a1350SMichael S. Tsirkin     int i, overlapping_cap;
1902315a1350SMichael S. Tsirkin 
1903315a1350SMichael S. Tsirkin     if (!offset) {
1904315a1350SMichael S. Tsirkin         offset = pci_find_space(pdev, size);
1905315a1350SMichael S. Tsirkin         if (!offset) {
1906315a1350SMichael S. Tsirkin             return -ENOSPC;
1907315a1350SMichael S. Tsirkin         }
1908315a1350SMichael S. Tsirkin     } else {
1909315a1350SMichael S. Tsirkin         /* Verify that capabilities don't overlap.  Note: device assignment
1910315a1350SMichael S. Tsirkin          * depends on this check to verify that the device is not broken.
1911315a1350SMichael S. Tsirkin          * Should never trigger for emulated devices, but it's helpful
1912315a1350SMichael S. Tsirkin          * for debugging these. */
1913315a1350SMichael S. Tsirkin         for (i = offset; i < offset + size; i++) {
1914315a1350SMichael S. Tsirkin             overlapping_cap = pci_find_capability_at_offset(pdev, i);
1915315a1350SMichael S. Tsirkin             if (overlapping_cap) {
1916315a1350SMichael S. Tsirkin                 fprintf(stderr, "ERROR: %04x:%02x:%02x.%x "
1917315a1350SMichael S. Tsirkin                         "Attempt to add PCI capability %x at offset "
1918315a1350SMichael S. Tsirkin                         "%x overlaps existing capability %x at offset %x\n",
1919315a1350SMichael S. Tsirkin                         pci_find_domain(pdev->bus), pci_bus_num(pdev->bus),
1920315a1350SMichael S. Tsirkin                         PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1921315a1350SMichael S. Tsirkin                         cap_id, offset, overlapping_cap, i);
1922315a1350SMichael S. Tsirkin                 return -EINVAL;
1923315a1350SMichael S. Tsirkin             }
1924315a1350SMichael S. Tsirkin         }
1925315a1350SMichael S. Tsirkin     }
1926315a1350SMichael S. Tsirkin 
1927315a1350SMichael S. Tsirkin     config = pdev->config + offset;
1928315a1350SMichael S. Tsirkin     config[PCI_CAP_LIST_ID] = cap_id;
1929315a1350SMichael S. Tsirkin     config[PCI_CAP_LIST_NEXT] = pdev->config[PCI_CAPABILITY_LIST];
1930315a1350SMichael S. Tsirkin     pdev->config[PCI_CAPABILITY_LIST] = offset;
1931315a1350SMichael S. Tsirkin     pdev->config[PCI_STATUS] |= PCI_STATUS_CAP_LIST;
1932315a1350SMichael S. Tsirkin     memset(pdev->used + offset, 0xFF, QEMU_ALIGN_UP(size, 4));
1933315a1350SMichael S. Tsirkin     /* Make capability read-only by default */
1934315a1350SMichael S. Tsirkin     memset(pdev->wmask + offset, 0, size);
1935315a1350SMichael S. Tsirkin     /* Check capability by default */
1936315a1350SMichael S. Tsirkin     memset(pdev->cmask + offset, 0xFF, size);
1937315a1350SMichael S. Tsirkin     return offset;
1938315a1350SMichael S. Tsirkin }
1939315a1350SMichael S. Tsirkin 
1940315a1350SMichael S. Tsirkin /* Unlink capability from the pci config space. */
1941315a1350SMichael S. Tsirkin void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
1942315a1350SMichael S. Tsirkin {
1943315a1350SMichael S. Tsirkin     uint8_t prev, offset = pci_find_capability_list(pdev, cap_id, &prev);
1944315a1350SMichael S. Tsirkin     if (!offset)
1945315a1350SMichael S. Tsirkin         return;
1946315a1350SMichael S. Tsirkin     pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];
1947315a1350SMichael S. Tsirkin     /* Make capability writable again */
1948315a1350SMichael S. Tsirkin     memset(pdev->wmask + offset, 0xff, size);
1949315a1350SMichael S. Tsirkin     memset(pdev->w1cmask + offset, 0, size);
1950315a1350SMichael S. Tsirkin     /* Clear cmask as device-specific registers can't be checked */
1951315a1350SMichael S. Tsirkin     memset(pdev->cmask + offset, 0, size);
1952315a1350SMichael S. Tsirkin     memset(pdev->used + offset, 0, QEMU_ALIGN_UP(size, 4));
1953315a1350SMichael S. Tsirkin 
1954315a1350SMichael S. Tsirkin     if (!pdev->config[PCI_CAPABILITY_LIST])
1955315a1350SMichael S. Tsirkin         pdev->config[PCI_STATUS] &= ~PCI_STATUS_CAP_LIST;
1956315a1350SMichael S. Tsirkin }
1957315a1350SMichael S. Tsirkin 
1958315a1350SMichael S. Tsirkin uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id)
1959315a1350SMichael S. Tsirkin {
1960315a1350SMichael S. Tsirkin     return pci_find_capability_list(pdev, cap_id, NULL);
1961315a1350SMichael S. Tsirkin }
1962315a1350SMichael S. Tsirkin 
1963315a1350SMichael S. Tsirkin static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
1964315a1350SMichael S. Tsirkin {
1965315a1350SMichael S. Tsirkin     PCIDevice *d = (PCIDevice *)dev;
1966315a1350SMichael S. Tsirkin     const pci_class_desc *desc;
1967315a1350SMichael S. Tsirkin     char ctxt[64];
1968315a1350SMichael S. Tsirkin     PCIIORegion *r;
1969315a1350SMichael S. Tsirkin     int i, class;
1970315a1350SMichael S. Tsirkin 
1971315a1350SMichael S. Tsirkin     class = pci_get_word(d->config + PCI_CLASS_DEVICE);
1972315a1350SMichael S. Tsirkin     desc = pci_class_descriptions;
1973315a1350SMichael S. Tsirkin     while (desc->desc && class != desc->class)
1974315a1350SMichael S. Tsirkin         desc++;
1975315a1350SMichael S. Tsirkin     if (desc->desc) {
1976315a1350SMichael S. Tsirkin         snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
1977315a1350SMichael S. Tsirkin     } else {
1978315a1350SMichael S. Tsirkin         snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
1979315a1350SMichael S. Tsirkin     }
1980315a1350SMichael S. Tsirkin 
1981315a1350SMichael S. Tsirkin     monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
1982315a1350SMichael S. Tsirkin                    "pci id %04x:%04x (sub %04x:%04x)\n",
1983315a1350SMichael S. Tsirkin                    indent, "", ctxt, pci_bus_num(d->bus),
1984315a1350SMichael S. Tsirkin                    PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
1985315a1350SMichael S. Tsirkin                    pci_get_word(d->config + PCI_VENDOR_ID),
1986315a1350SMichael S. Tsirkin                    pci_get_word(d->config + PCI_DEVICE_ID),
1987315a1350SMichael S. Tsirkin                    pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
1988315a1350SMichael S. Tsirkin                    pci_get_word(d->config + PCI_SUBSYSTEM_ID));
1989315a1350SMichael S. Tsirkin     for (i = 0; i < PCI_NUM_REGIONS; i++) {
1990315a1350SMichael S. Tsirkin         r = &d->io_regions[i];
1991315a1350SMichael S. Tsirkin         if (!r->size)
1992315a1350SMichael S. Tsirkin             continue;
1993315a1350SMichael S. Tsirkin         monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS
1994315a1350SMichael S. Tsirkin                        " [0x%"FMT_PCIBUS"]\n",
1995315a1350SMichael S. Tsirkin                        indent, "",
1996315a1350SMichael S. Tsirkin                        i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
1997315a1350SMichael S. Tsirkin                        r->addr, r->addr + r->size - 1);
1998315a1350SMichael S. Tsirkin     }
1999315a1350SMichael S. Tsirkin }
2000315a1350SMichael S. Tsirkin 
2001315a1350SMichael S. Tsirkin static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
2002315a1350SMichael S. Tsirkin {
2003315a1350SMichael S. Tsirkin     PCIDevice *d = (PCIDevice *)dev;
2004315a1350SMichael S. Tsirkin     const char *name = NULL;
2005315a1350SMichael S. Tsirkin     const pci_class_desc *desc =  pci_class_descriptions;
2006315a1350SMichael S. Tsirkin     int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
2007315a1350SMichael S. Tsirkin 
2008315a1350SMichael S. Tsirkin     while (desc->desc &&
2009315a1350SMichael S. Tsirkin           (class & ~desc->fw_ign_bits) !=
2010315a1350SMichael S. Tsirkin           (desc->class & ~desc->fw_ign_bits)) {
2011315a1350SMichael S. Tsirkin         desc++;
2012315a1350SMichael S. Tsirkin     }
2013315a1350SMichael S. Tsirkin 
2014315a1350SMichael S. Tsirkin     if (desc->desc) {
2015315a1350SMichael S. Tsirkin         name = desc->fw_name;
2016315a1350SMichael S. Tsirkin     }
2017315a1350SMichael S. Tsirkin 
2018315a1350SMichael S. Tsirkin     if (name) {
2019315a1350SMichael S. Tsirkin         pstrcpy(buf, len, name);
2020315a1350SMichael S. Tsirkin     } else {
2021315a1350SMichael S. Tsirkin         snprintf(buf, len, "pci%04x,%04x",
2022315a1350SMichael S. Tsirkin                  pci_get_word(d->config + PCI_VENDOR_ID),
2023315a1350SMichael S. Tsirkin                  pci_get_word(d->config + PCI_DEVICE_ID));
2024315a1350SMichael S. Tsirkin     }
2025315a1350SMichael S. Tsirkin 
2026315a1350SMichael S. Tsirkin     return buf;
2027315a1350SMichael S. Tsirkin }
2028315a1350SMichael S. Tsirkin 
2029315a1350SMichael S. Tsirkin static char *pcibus_get_fw_dev_path(DeviceState *dev)
2030315a1350SMichael S. Tsirkin {
2031315a1350SMichael S. Tsirkin     PCIDevice *d = (PCIDevice *)dev;
2032315a1350SMichael S. Tsirkin     char path[50], name[33];
2033315a1350SMichael S. Tsirkin     int off;
2034315a1350SMichael S. Tsirkin 
2035315a1350SMichael S. Tsirkin     off = snprintf(path, sizeof(path), "%s@%x",
2036315a1350SMichael S. Tsirkin                    pci_dev_fw_name(dev, name, sizeof name),
2037315a1350SMichael S. Tsirkin                    PCI_SLOT(d->devfn));
2038315a1350SMichael S. Tsirkin     if (PCI_FUNC(d->devfn))
2039315a1350SMichael S. Tsirkin         snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
2040315a1350SMichael S. Tsirkin     return g_strdup(path);
2041315a1350SMichael S. Tsirkin }
2042315a1350SMichael S. Tsirkin 
2043315a1350SMichael S. Tsirkin static char *pcibus_get_dev_path(DeviceState *dev)
2044315a1350SMichael S. Tsirkin {
2045315a1350SMichael S. Tsirkin     PCIDevice *d = container_of(dev, PCIDevice, qdev);
2046315a1350SMichael S. Tsirkin     PCIDevice *t;
2047315a1350SMichael S. Tsirkin     int slot_depth;
2048315a1350SMichael S. Tsirkin     /* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function.
2049315a1350SMichael S. Tsirkin      * 00 is added here to make this format compatible with
2050315a1350SMichael S. Tsirkin      * domain:Bus:Slot.Func for systems without nested PCI bridges.
2051315a1350SMichael S. Tsirkin      * Slot.Function list specifies the slot and function numbers for all
2052315a1350SMichael S. Tsirkin      * devices on the path from root to the specific device. */
2053315a1350SMichael S. Tsirkin     char domain[] = "DDDD:00";
2054315a1350SMichael S. Tsirkin     char slot[] = ":SS.F";
2055315a1350SMichael S. Tsirkin     int domain_len = sizeof domain - 1 /* For '\0' */;
2056315a1350SMichael S. Tsirkin     int slot_len = sizeof slot - 1 /* For '\0' */;
2057315a1350SMichael S. Tsirkin     int path_len;
2058315a1350SMichael S. Tsirkin     char *path, *p;
2059315a1350SMichael S. Tsirkin     int s;
2060315a1350SMichael S. Tsirkin 
2061315a1350SMichael S. Tsirkin     /* Calculate # of slots on path between device and root. */;
2062315a1350SMichael S. Tsirkin     slot_depth = 0;
2063315a1350SMichael S. Tsirkin     for (t = d; t; t = t->bus->parent_dev) {
2064315a1350SMichael S. Tsirkin         ++slot_depth;
2065315a1350SMichael S. Tsirkin     }
2066315a1350SMichael S. Tsirkin 
2067315a1350SMichael S. Tsirkin     path_len = domain_len + slot_len * slot_depth;
2068315a1350SMichael S. Tsirkin 
2069315a1350SMichael S. Tsirkin     /* Allocate memory, fill in the terminating null byte. */
2070315a1350SMichael S. Tsirkin     path = g_malloc(path_len + 1 /* For '\0' */);
2071315a1350SMichael S. Tsirkin     path[path_len] = '\0';
2072315a1350SMichael S. Tsirkin 
2073315a1350SMichael S. Tsirkin     /* First field is the domain. */
2074315a1350SMichael S. Tsirkin     s = snprintf(domain, sizeof domain, "%04x:00", pci_find_domain(d->bus));
2075315a1350SMichael S. Tsirkin     assert(s == domain_len);
2076315a1350SMichael S. Tsirkin     memcpy(path, domain, domain_len);
2077315a1350SMichael S. Tsirkin 
2078315a1350SMichael S. Tsirkin     /* Fill in slot numbers. We walk up from device to root, so need to print
2079315a1350SMichael S. Tsirkin      * them in the reverse order, last to first. */
2080315a1350SMichael S. Tsirkin     p = path + path_len;
2081315a1350SMichael S. Tsirkin     for (t = d; t; t = t->bus->parent_dev) {
2082315a1350SMichael S. Tsirkin         p -= slot_len;
2083315a1350SMichael S. Tsirkin         s = snprintf(slot, sizeof slot, ":%02x.%x",
2084315a1350SMichael S. Tsirkin                      PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
2085315a1350SMichael S. Tsirkin         assert(s == slot_len);
2086315a1350SMichael S. Tsirkin         memcpy(p, slot, slot_len);
2087315a1350SMichael S. Tsirkin     }
2088315a1350SMichael S. Tsirkin 
2089315a1350SMichael S. Tsirkin     return path;
2090315a1350SMichael S. Tsirkin }
2091315a1350SMichael S. Tsirkin 
2092315a1350SMichael S. Tsirkin static int pci_qdev_find_recursive(PCIBus *bus,
2093315a1350SMichael S. Tsirkin                                    const char *id, PCIDevice **pdev)
2094315a1350SMichael S. Tsirkin {
2095315a1350SMichael S. Tsirkin     DeviceState *qdev = qdev_find_recursive(&bus->qbus, id);
2096315a1350SMichael S. Tsirkin     if (!qdev) {
2097315a1350SMichael S. Tsirkin         return -ENODEV;
2098315a1350SMichael S. Tsirkin     }
2099315a1350SMichael S. Tsirkin 
2100315a1350SMichael S. Tsirkin     /* roughly check if given qdev is pci device */
2101315a1350SMichael S. Tsirkin     if (object_dynamic_cast(OBJECT(qdev), TYPE_PCI_DEVICE)) {
2102315a1350SMichael S. Tsirkin         *pdev = PCI_DEVICE(qdev);
2103315a1350SMichael S. Tsirkin         return 0;
2104315a1350SMichael S. Tsirkin     }
2105315a1350SMichael S. Tsirkin     return -EINVAL;
2106315a1350SMichael S. Tsirkin }
2107315a1350SMichael S. Tsirkin 
2108315a1350SMichael S. Tsirkin int pci_qdev_find_device(const char *id, PCIDevice **pdev)
2109315a1350SMichael S. Tsirkin {
2110315a1350SMichael S. Tsirkin     struct PCIHostBus *host;
2111315a1350SMichael S. Tsirkin     int rc = -ENODEV;
2112315a1350SMichael S. Tsirkin 
2113315a1350SMichael S. Tsirkin     QLIST_FOREACH(host, &host_buses, next) {
2114315a1350SMichael S. Tsirkin         int tmp = pci_qdev_find_recursive(host->bus, id, pdev);
2115315a1350SMichael S. Tsirkin         if (!tmp) {
2116315a1350SMichael S. Tsirkin             rc = 0;
2117315a1350SMichael S. Tsirkin             break;
2118315a1350SMichael S. Tsirkin         }
2119315a1350SMichael S. Tsirkin         if (tmp != -ENODEV) {
2120315a1350SMichael S. Tsirkin             rc = tmp;
2121315a1350SMichael S. Tsirkin         }
2122315a1350SMichael S. Tsirkin     }
2123315a1350SMichael S. Tsirkin 
2124315a1350SMichael S. Tsirkin     return rc;
2125315a1350SMichael S. Tsirkin }
2126315a1350SMichael S. Tsirkin 
2127315a1350SMichael S. Tsirkin MemoryRegion *pci_address_space(PCIDevice *dev)
2128315a1350SMichael S. Tsirkin {
2129315a1350SMichael S. Tsirkin     return dev->bus->address_space_mem;
2130315a1350SMichael S. Tsirkin }
2131315a1350SMichael S. Tsirkin 
2132315a1350SMichael S. Tsirkin MemoryRegion *pci_address_space_io(PCIDevice *dev)
2133315a1350SMichael S. Tsirkin {
2134315a1350SMichael S. Tsirkin     return dev->bus->address_space_io;
2135315a1350SMichael S. Tsirkin }
2136315a1350SMichael S. Tsirkin 
2137315a1350SMichael S. Tsirkin static void pci_device_class_init(ObjectClass *klass, void *data)
2138315a1350SMichael S. Tsirkin {
2139315a1350SMichael S. Tsirkin     DeviceClass *k = DEVICE_CLASS(klass);
2140315a1350SMichael S. Tsirkin     k->init = pci_qdev_init;
2141315a1350SMichael S. Tsirkin     k->unplug = pci_unplug_device;
2142315a1350SMichael S. Tsirkin     k->exit = pci_unregister_device;
2143315a1350SMichael S. Tsirkin     k->bus_type = TYPE_PCI_BUS;
2144315a1350SMichael S. Tsirkin     k->props = pci_props;
2145315a1350SMichael S. Tsirkin }
2146315a1350SMichael S. Tsirkin 
2147315a1350SMichael S. Tsirkin void pci_setup_iommu(PCIBus *bus, PCIDMAContextFunc fn, void *opaque)
2148315a1350SMichael S. Tsirkin {
2149315a1350SMichael S. Tsirkin     bus->dma_context_fn = fn;
2150315a1350SMichael S. Tsirkin     bus->dma_context_opaque = opaque;
2151315a1350SMichael S. Tsirkin }
2152315a1350SMichael S. Tsirkin 
2153315a1350SMichael S. Tsirkin static TypeInfo pci_device_type_info = {
2154315a1350SMichael S. Tsirkin     .name = TYPE_PCI_DEVICE,
2155315a1350SMichael S. Tsirkin     .parent = TYPE_DEVICE,
2156315a1350SMichael S. Tsirkin     .instance_size = sizeof(PCIDevice),
2157315a1350SMichael S. Tsirkin     .abstract = true,
2158315a1350SMichael S. Tsirkin     .class_size = sizeof(PCIDeviceClass),
2159315a1350SMichael S. Tsirkin     .class_init = pci_device_class_init,
2160315a1350SMichael S. Tsirkin };
2161315a1350SMichael S. Tsirkin 
2162315a1350SMichael S. Tsirkin static void pci_register_types(void)
2163315a1350SMichael S. Tsirkin {
2164315a1350SMichael S. Tsirkin     type_register_static(&pci_bus_info);
2165315a1350SMichael S. Tsirkin     type_register_static(&pci_device_type_info);
2166315a1350SMichael S. Tsirkin }
2167315a1350SMichael S. Tsirkin 
2168315a1350SMichael S. Tsirkin type_init(pci_register_types)
2169