Statistics
| Branch: | Revision:

root / hw / pci.c @ 03587182

History | View | Annotate | Download (31.8 kB)

1 69b91039 bellard
/*
2 69b91039 bellard
 * QEMU PCI bus manager
3 69b91039 bellard
 *
4 69b91039 bellard
 * Copyright (c) 2004 Fabrice Bellard
5 5fafdf24 ths
 *
6 69b91039 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 69b91039 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 69b91039 bellard
 * in the Software without restriction, including without limitation the rights
9 69b91039 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 69b91039 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 69b91039 bellard
 * furnished to do so, subject to the following conditions:
12 69b91039 bellard
 *
13 69b91039 bellard
 * The above copyright notice and this permission notice shall be included in
14 69b91039 bellard
 * all copies or substantial portions of the Software.
15 69b91039 bellard
 *
16 69b91039 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 69b91039 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 69b91039 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 69b91039 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 69b91039 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 69b91039 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 69b91039 bellard
 * THE SOFTWARE.
23 69b91039 bellard
 */
24 87ecb68b pbrook
#include "hw.h"
25 87ecb68b pbrook
#include "pci.h"
26 376253ec aliguori
#include "monitor.h"
27 87ecb68b pbrook
#include "net.h"
28 880345c4 aliguori
#include "sysemu.h"
29 69b91039 bellard
30 69b91039 bellard
//#define DEBUG_PCI
31 d8d2e079 Isaku Yamahata
#ifdef DEBUG_PCI
32 d8d2e079 Isaku Yamahata
# define PCI_DPRINTF(format, ...)       printf(format, __VA_ARGS__)
33 d8d2e079 Isaku Yamahata
#else
34 d8d2e079 Isaku Yamahata
# define PCI_DPRINTF(format, ...)       do { } while (0)
35 d8d2e079 Isaku Yamahata
#endif
36 69b91039 bellard
37 30468f78 bellard
struct PCIBus {
38 02e2da45 Paul Brook
    BusState qbus;
39 30468f78 bellard
    int bus_num;
40 30468f78 bellard
    int devfn_min;
41 502a5395 pbrook
    pci_set_irq_fn set_irq;
42 d2b59317 pbrook
    pci_map_irq_fn map_irq;
43 30468f78 bellard
    uint32_t config_reg; /* XXX: suppress */
44 5d4e84c8 Juan Quintela
    void *irq_opaque;
45 30468f78 bellard
    PCIDevice *devices[256];
46 80b3ada7 pbrook
    PCIDevice *parent_dev;
47 80b3ada7 pbrook
    PCIBus *next;
48 d2b59317 pbrook
    /* The bus IRQ state is the logical OR of the connected devices.
49 d2b59317 pbrook
       Keep a count of the number of devices with raised IRQs.  */
50 52fc1d83 balrog
    int nirq;
51 10c4c98a Gerd Hoffmann
    int *irq_count;
52 10c4c98a Gerd Hoffmann
};
53 10c4c98a Gerd Hoffmann
54 10c4c98a Gerd Hoffmann
static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
55 10c4c98a Gerd Hoffmann
56 10c4c98a Gerd Hoffmann
static struct BusInfo pci_bus_info = {
57 10c4c98a Gerd Hoffmann
    .name       = "PCI",
58 10c4c98a Gerd Hoffmann
    .size       = sizeof(PCIBus),
59 10c4c98a Gerd Hoffmann
    .print_dev  = pcibus_dev_print,
60 ee6847d1 Gerd Hoffmann
    .props      = (Property[]) {
61 54586bd1 Gerd Hoffmann
        DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
62 54586bd1 Gerd Hoffmann
        DEFINE_PROP_END_OF_LIST()
63 ee6847d1 Gerd Hoffmann
    }
64 30468f78 bellard
};
65 69b91039 bellard
66 1941d19c bellard
static void pci_update_mappings(PCIDevice *d);
67 d537cf6c pbrook
static void pci_set_irq(void *opaque, int irq_num, int level);
68 1941d19c bellard
69 c227f099 Anthony Liguori
target_phys_addr_t pci_mem_base;
70 d350d97d aliguori
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
71 d350d97d aliguori
static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
72 30468f78 bellard
static PCIBus *first_bus;
73 30468f78 bellard
74 2d1e9f96 Juan Quintela
static const VMStateDescription vmstate_pcibus = {
75 2d1e9f96 Juan Quintela
    .name = "PCIBUS",
76 2d1e9f96 Juan Quintela
    .version_id = 1,
77 2d1e9f96 Juan Quintela
    .minimum_version_id = 1,
78 2d1e9f96 Juan Quintela
    .minimum_version_id_old = 1,
79 2d1e9f96 Juan Quintela
    .fields      = (VMStateField []) {
80 2d1e9f96 Juan Quintela
        VMSTATE_INT32_EQUAL(nirq, PCIBus),
81 2d1e9f96 Juan Quintela
        VMSTATE_INT32_VARRAY(irq_count, PCIBus, nirq),
82 2d1e9f96 Juan Quintela
        VMSTATE_END_OF_LIST()
83 52fc1d83 balrog
    }
84 2d1e9f96 Juan Quintela
};
85 52fc1d83 balrog
86 6eaa6847 Gleb Natapov
static void pci_bus_reset(void *opaque)
87 6eaa6847 Gleb Natapov
{
88 a60380a5 Juan Quintela
    PCIBus *bus = opaque;
89 6eaa6847 Gleb Natapov
    int i;
90 6eaa6847 Gleb Natapov
91 6eaa6847 Gleb Natapov
    for (i = 0; i < bus->nirq; i++) {
92 6eaa6847 Gleb Natapov
        bus->irq_count[i] = 0;
93 6eaa6847 Gleb Natapov
    }
94 6eaa6847 Gleb Natapov
    for (i = 0; i < 256; i++) {
95 6eaa6847 Gleb Natapov
        if (bus->devices[i])
96 6eaa6847 Gleb Natapov
            memset(bus->devices[i]->irq_state, 0,
97 6eaa6847 Gleb Natapov
                   sizeof(bus->devices[i]->irq_state));
98 6eaa6847 Gleb Natapov
    }
99 6eaa6847 Gleb Natapov
}
100 6eaa6847 Gleb Natapov
101 21eea4b3 Gerd Hoffmann
void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
102 21eea4b3 Gerd Hoffmann
                         const char *name, int devfn_min)
103 30468f78 bellard
{
104 52fc1d83 balrog
    static int nbus = 0;
105 52fc1d83 balrog
106 21eea4b3 Gerd Hoffmann
    qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
107 502a5395 pbrook
    bus->devfn_min = devfn_min;
108 425c608c Isaku Yamahata
    bus->next = first_bus;
109 30468f78 bellard
    first_bus = bus;
110 2d1e9f96 Juan Quintela
    vmstate_register(nbus++, &vmstate_pcibus, bus);
111 a08d4367 Jan Kiszka
    qemu_register_reset(pci_bus_reset, bus);
112 21eea4b3 Gerd Hoffmann
}
113 21eea4b3 Gerd Hoffmann
114 21eea4b3 Gerd Hoffmann
PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)
115 21eea4b3 Gerd Hoffmann
{
116 21eea4b3 Gerd Hoffmann
    PCIBus *bus;
117 21eea4b3 Gerd Hoffmann
118 21eea4b3 Gerd Hoffmann
    bus = qemu_mallocz(sizeof(*bus));
119 21eea4b3 Gerd Hoffmann
    bus->qbus.qdev_allocated = 1;
120 21eea4b3 Gerd Hoffmann
    pci_bus_new_inplace(bus, parent, name, devfn_min);
121 21eea4b3 Gerd Hoffmann
    return bus;
122 21eea4b3 Gerd Hoffmann
}
123 21eea4b3 Gerd Hoffmann
124 21eea4b3 Gerd Hoffmann
void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
125 21eea4b3 Gerd Hoffmann
                  void *irq_opaque, int nirq)
126 21eea4b3 Gerd Hoffmann
{
127 21eea4b3 Gerd Hoffmann
    bus->set_irq = set_irq;
128 21eea4b3 Gerd Hoffmann
    bus->map_irq = map_irq;
129 21eea4b3 Gerd Hoffmann
    bus->irq_opaque = irq_opaque;
130 21eea4b3 Gerd Hoffmann
    bus->nirq = nirq;
131 21eea4b3 Gerd Hoffmann
    bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
132 21eea4b3 Gerd Hoffmann
}
133 21eea4b3 Gerd Hoffmann
134 21eea4b3 Gerd Hoffmann
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
135 21eea4b3 Gerd Hoffmann
                         pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
136 21eea4b3 Gerd Hoffmann
                         void *irq_opaque, int devfn_min, int nirq)
137 21eea4b3 Gerd Hoffmann
{
138 21eea4b3 Gerd Hoffmann
    PCIBus *bus;
139 21eea4b3 Gerd Hoffmann
140 21eea4b3 Gerd Hoffmann
    bus = pci_bus_new(parent, name, devfn_min);
141 21eea4b3 Gerd Hoffmann
    pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
142 30468f78 bellard
    return bus;
143 30468f78 bellard
}
144 69b91039 bellard
145 03587182 Gerd Hoffmann
static void pci_register_secondary_bus(PCIBus *bus,
146 03587182 Gerd Hoffmann
                                       PCIDevice *dev,
147 03587182 Gerd Hoffmann
                                       pci_map_irq_fn map_irq,
148 03587182 Gerd Hoffmann
                                       const char *name)
149 80b3ada7 pbrook
{
150 03587182 Gerd Hoffmann
    qbus_create_inplace(&bus->qbus, &pci_bus_info, &dev->qdev, name);
151 80b3ada7 pbrook
    bus->map_irq = map_irq;
152 80b3ada7 pbrook
    bus->parent_dev = dev;
153 80b3ada7 pbrook
    bus->next = dev->bus->next;
154 80b3ada7 pbrook
    dev->bus->next = bus;
155 80b3ada7 pbrook
}
156 80b3ada7 pbrook
157 502a5395 pbrook
int pci_bus_num(PCIBus *s)
158 502a5395 pbrook
{
159 502a5395 pbrook
    return s->bus_num;
160 502a5395 pbrook
}
161 502a5395 pbrook
162 73534f2f Juan Quintela
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
163 30ca2aab bellard
{
164 73534f2f Juan Quintela
    PCIDevice *s = container_of(pv, PCIDevice, config);
165 73534f2f Juan Quintela
    uint8_t config[size];
166 52fc1d83 balrog
    int i;
167 52fc1d83 balrog
168 73534f2f Juan Quintela
    qemu_get_buffer(f, config, size);
169 73534f2f Juan Quintela
    for (i = 0; i < size; ++i)
170 bd4b65ee Michael S. Tsirkin
        if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i])
171 bd4b65ee Michael S. Tsirkin
            return -EINVAL;
172 73534f2f Juan Quintela
    memcpy(s->config, config, size);
173 bd4b65ee Michael S. Tsirkin
174 1941d19c bellard
    pci_update_mappings(s);
175 52fc1d83 balrog
176 30ca2aab bellard
    return 0;
177 30ca2aab bellard
}
178 30ca2aab bellard
179 73534f2f Juan Quintela
/* just put buffer */
180 84e2e3eb Juan Quintela
static void put_pci_config_device(QEMUFile *f, void *pv, size_t size)
181 73534f2f Juan Quintela
{
182 73534f2f Juan Quintela
    const uint8_t *v = pv;
183 73534f2f Juan Quintela
    qemu_put_buffer(f, v, size);
184 73534f2f Juan Quintela
}
185 73534f2f Juan Quintela
186 73534f2f Juan Quintela
static VMStateInfo vmstate_info_pci_config = {
187 73534f2f Juan Quintela
    .name = "pci config",
188 73534f2f Juan Quintela
    .get  = get_pci_config_device,
189 73534f2f Juan Quintela
    .put  = put_pci_config_device,
190 73534f2f Juan Quintela
};
191 73534f2f Juan Quintela
192 73534f2f Juan Quintela
const VMStateDescription vmstate_pci_device = {
193 73534f2f Juan Quintela
    .name = "PCIDevice",
194 73534f2f Juan Quintela
    .version_id = 2,
195 73534f2f Juan Quintela
    .minimum_version_id = 1,
196 73534f2f Juan Quintela
    .minimum_version_id_old = 1,
197 73534f2f Juan Quintela
    .fields      = (VMStateField []) {
198 73534f2f Juan Quintela
        VMSTATE_INT32_LE(version_id, PCIDevice),
199 73534f2f Juan Quintela
        VMSTATE_SINGLE(config, PCIDevice, 0, vmstate_info_pci_config,
200 73534f2f Juan Quintela
                       typeof_field(PCIDevice,config)),
201 73534f2f Juan Quintela
        VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, 4, 2),
202 73534f2f Juan Quintela
        VMSTATE_END_OF_LIST()
203 73534f2f Juan Quintela
    }
204 73534f2f Juan Quintela
};
205 73534f2f Juan Quintela
206 73534f2f Juan Quintela
void pci_device_save(PCIDevice *s, QEMUFile *f)
207 73534f2f Juan Quintela
{
208 73534f2f Juan Quintela
    vmstate_save_state(f, &vmstate_pci_device, s);
209 73534f2f Juan Quintela
}
210 73534f2f Juan Quintela
211 73534f2f Juan Quintela
int pci_device_load(PCIDevice *s, QEMUFile *f)
212 73534f2f Juan Quintela
{
213 73534f2f Juan Quintela
    return vmstate_load_state(f, &vmstate_pci_device, s, s->version_id);
214 73534f2f Juan Quintela
}
215 73534f2f Juan Quintela
216 d350d97d aliguori
static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
217 d350d97d aliguori
{
218 d350d97d aliguori
    uint16_t *id;
219 d350d97d aliguori
220 d350d97d aliguori
    id = (void*)(&pci_dev->config[PCI_SUBVENDOR_ID]);
221 d350d97d aliguori
    id[0] = cpu_to_le16(pci_default_sub_vendor_id);
222 d350d97d aliguori
    id[1] = cpu_to_le16(pci_default_sub_device_id);
223 d350d97d aliguori
    return 0;
224 d350d97d aliguori
}
225 d350d97d aliguori
226 880345c4 aliguori
/*
227 880345c4 aliguori
 * Parse [[<domain>:]<bus>:]<slot>, return -1 on error
228 880345c4 aliguori
 */
229 880345c4 aliguori
static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
230 880345c4 aliguori
{
231 880345c4 aliguori
    const char *p;
232 880345c4 aliguori
    char *e;
233 880345c4 aliguori
    unsigned long val;
234 880345c4 aliguori
    unsigned long dom = 0, bus = 0;
235 880345c4 aliguori
    unsigned slot = 0;
236 880345c4 aliguori
237 880345c4 aliguori
    p = addr;
238 880345c4 aliguori
    val = strtoul(p, &e, 16);
239 880345c4 aliguori
    if (e == p)
240 880345c4 aliguori
        return -1;
241 880345c4 aliguori
    if (*e == ':') {
242 880345c4 aliguori
        bus = val;
243 880345c4 aliguori
        p = e + 1;
244 880345c4 aliguori
        val = strtoul(p, &e, 16);
245 880345c4 aliguori
        if (e == p)
246 880345c4 aliguori
            return -1;
247 880345c4 aliguori
        if (*e == ':') {
248 880345c4 aliguori
            dom = bus;
249 880345c4 aliguori
            bus = val;
250 880345c4 aliguori
            p = e + 1;
251 880345c4 aliguori
            val = strtoul(p, &e, 16);
252 880345c4 aliguori
            if (e == p)
253 880345c4 aliguori
                return -1;
254 880345c4 aliguori
        }
255 880345c4 aliguori
    }
256 880345c4 aliguori
257 880345c4 aliguori
    if (dom > 0xffff || bus > 0xff || val > 0x1f)
258 880345c4 aliguori
        return -1;
259 880345c4 aliguori
260 880345c4 aliguori
    slot = val;
261 880345c4 aliguori
262 880345c4 aliguori
    if (*e)
263 880345c4 aliguori
        return -1;
264 880345c4 aliguori
265 880345c4 aliguori
    /* Note: QEMU doesn't implement domains other than 0 */
266 880345c4 aliguori
    if (dom != 0 || pci_find_bus(bus) == NULL)
267 880345c4 aliguori
        return -1;
268 880345c4 aliguori
269 880345c4 aliguori
    *domp = dom;
270 880345c4 aliguori
    *busp = bus;
271 880345c4 aliguori
    *slotp = slot;
272 880345c4 aliguori
    return 0;
273 880345c4 aliguori
}
274 880345c4 aliguori
275 e9283f8b Jan Kiszka
int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
276 e9283f8b Jan Kiszka
                     unsigned *slotp)
277 880345c4 aliguori
{
278 e9283f8b Jan Kiszka
    /* strip legacy tag */
279 e9283f8b Jan Kiszka
    if (!strncmp(addr, "pci_addr=", 9)) {
280 e9283f8b Jan Kiszka
        addr += 9;
281 e9283f8b Jan Kiszka
    }
282 e9283f8b Jan Kiszka
    if (pci_parse_devaddr(addr, domp, busp, slotp)) {
283 e9283f8b Jan Kiszka
        monitor_printf(mon, "Invalid pci address\n");
284 880345c4 aliguori
        return -1;
285 e9283f8b Jan Kiszka
    }
286 e9283f8b Jan Kiszka
    return 0;
287 880345c4 aliguori
}
288 880345c4 aliguori
289 5607c388 Markus Armbruster
static PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
290 5607c388 Markus Armbruster
{
291 5607c388 Markus Armbruster
    int dom, bus;
292 5607c388 Markus Armbruster
    unsigned slot;
293 5607c388 Markus Armbruster
294 5607c388 Markus Armbruster
    if (!devaddr) {
295 5607c388 Markus Armbruster
        *devfnp = -1;
296 5607c388 Markus Armbruster
        return pci_find_bus(0);
297 5607c388 Markus Armbruster
    }
298 5607c388 Markus Armbruster
299 5607c388 Markus Armbruster
    if (pci_parse_devaddr(devaddr, &dom, &bus, &slot) < 0) {
300 5607c388 Markus Armbruster
        return NULL;
301 5607c388 Markus Armbruster
    }
302 5607c388 Markus Armbruster
303 5607c388 Markus Armbruster
    *devfnp = slot << 3;
304 5607c388 Markus Armbruster
    return pci_find_bus(bus);
305 5607c388 Markus Armbruster
}
306 5607c388 Markus Armbruster
307 bd4b65ee Michael S. Tsirkin
static void pci_init_cmask(PCIDevice *dev)
308 bd4b65ee Michael S. Tsirkin
{
309 bd4b65ee Michael S. Tsirkin
    pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff);
310 bd4b65ee Michael S. Tsirkin
    pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff);
311 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_STATUS] = PCI_STATUS_CAP_LIST;
312 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_REVISION_ID] = 0xff;
313 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_CLASS_PROG] = 0xff;
314 bd4b65ee Michael S. Tsirkin
    pci_set_word(dev->cmask + PCI_CLASS_DEVICE, 0xffff);
315 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_HEADER_TYPE] = 0xff;
316 bd4b65ee Michael S. Tsirkin
    dev->cmask[PCI_CAPABILITY_LIST] = 0xff;
317 bd4b65ee Michael S. Tsirkin
}
318 bd4b65ee Michael S. Tsirkin
319 b7ee1603 Michael S. Tsirkin
static void pci_init_wmask(PCIDevice *dev)
320 b7ee1603 Michael S. Tsirkin
{
321 b7ee1603 Michael S. Tsirkin
    int i;
322 b7ee1603 Michael S. Tsirkin
    dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
323 b7ee1603 Michael S. Tsirkin
    dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
324 b7ee1603 Michael S. Tsirkin
    dev->wmask[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY
325 b7ee1603 Michael S. Tsirkin
                              | PCI_COMMAND_MASTER;
326 b7ee1603 Michael S. Tsirkin
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
327 b7ee1603 Michael S. Tsirkin
        dev->wmask[i] = 0xff;
328 b7ee1603 Michael S. Tsirkin
}
329 b7ee1603 Michael S. Tsirkin
330 69b91039 bellard
/* -1 for devfn means auto assign */
331 6b1b92d3 Paul Brook
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
332 6b1b92d3 Paul Brook
                                         const char *name, int devfn,
333 6b1b92d3 Paul Brook
                                         PCIConfigReadFunc *config_read,
334 6b1b92d3 Paul Brook
                                         PCIConfigWriteFunc *config_write)
335 69b91039 bellard
{
336 69b91039 bellard
    if (devfn < 0) {
337 30468f78 bellard
        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
338 30468f78 bellard
            if (!bus->devices[devfn])
339 69b91039 bellard
                goto found;
340 69b91039 bellard
        }
341 69b91039 bellard
        return NULL;
342 69b91039 bellard
    found: ;
343 07b7d053 Markus Armbruster
    } else if (bus->devices[devfn]) {
344 07b7d053 Markus Armbruster
        return NULL;
345 69b91039 bellard
    }
346 30468f78 bellard
    pci_dev->bus = bus;
347 69b91039 bellard
    pci_dev->devfn = devfn;
348 69b91039 bellard
    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
349 d2b59317 pbrook
    memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
350 d350d97d aliguori
    pci_set_default_subsystem_id(pci_dev);
351 bd4b65ee Michael S. Tsirkin
    pci_init_cmask(pci_dev);
352 b7ee1603 Michael S. Tsirkin
    pci_init_wmask(pci_dev);
353 0ac32c83 bellard
354 0ac32c83 bellard
    if (!config_read)
355 0ac32c83 bellard
        config_read = pci_default_read_config;
356 0ac32c83 bellard
    if (!config_write)
357 0ac32c83 bellard
        config_write = pci_default_write_config;
358 69b91039 bellard
    pci_dev->config_read = config_read;
359 69b91039 bellard
    pci_dev->config_write = config_write;
360 30468f78 bellard
    bus->devices[devfn] = pci_dev;
361 d537cf6c pbrook
    pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
362 f16c4abf Juan Quintela
    pci_dev->version_id = 2; /* Current pci device vmstate version */
363 69b91039 bellard
    return pci_dev;
364 69b91039 bellard
}
365 69b91039 bellard
366 6b1b92d3 Paul Brook
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
367 6b1b92d3 Paul Brook
                               int instance_size, int devfn,
368 6b1b92d3 Paul Brook
                               PCIConfigReadFunc *config_read,
369 6b1b92d3 Paul Brook
                               PCIConfigWriteFunc *config_write)
370 6b1b92d3 Paul Brook
{
371 6b1b92d3 Paul Brook
    PCIDevice *pci_dev;
372 6b1b92d3 Paul Brook
373 6b1b92d3 Paul Brook
    pci_dev = qemu_mallocz(instance_size);
374 6b1b92d3 Paul Brook
    pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,
375 6b1b92d3 Paul Brook
                                     config_read, config_write);
376 6b1b92d3 Paul Brook
    return pci_dev;
377 6b1b92d3 Paul Brook
}
378 c227f099 Anthony Liguori
static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
379 5851e08c aliguori
{
380 5851e08c aliguori
    return addr + pci_mem_base;
381 5851e08c aliguori
}
382 5851e08c aliguori
383 5851e08c aliguori
static void pci_unregister_io_regions(PCIDevice *pci_dev)
384 5851e08c aliguori
{
385 5851e08c aliguori
    PCIIORegion *r;
386 5851e08c aliguori
    int i;
387 5851e08c aliguori
388 5851e08c aliguori
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
389 5851e08c aliguori
        r = &pci_dev->io_regions[i];
390 5851e08c aliguori
        if (!r->size || r->addr == -1)
391 5851e08c aliguori
            continue;
392 5851e08c aliguori
        if (r->type == PCI_ADDRESS_SPACE_IO) {
393 5851e08c aliguori
            isa_unassign_ioport(r->addr, r->size);
394 5851e08c aliguori
        } else {
395 5851e08c aliguori
            cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
396 5851e08c aliguori
                                                     r->size,
397 5851e08c aliguori
                                                     IO_MEM_UNASSIGNED);
398 5851e08c aliguori
        }
399 5851e08c aliguori
    }
400 5851e08c aliguori
}
401 5851e08c aliguori
402 5851e08c aliguori
int pci_unregister_device(PCIDevice *pci_dev)
403 5851e08c aliguori
{
404 5851e08c aliguori
    int ret = 0;
405 5851e08c aliguori
406 5851e08c aliguori
    if (pci_dev->unregister)
407 5851e08c aliguori
        ret = pci_dev->unregister(pci_dev);
408 5851e08c aliguori
    if (ret)
409 5851e08c aliguori
        return ret;
410 5851e08c aliguori
411 5851e08c aliguori
    pci_unregister_io_regions(pci_dev);
412 5851e08c aliguori
413 5851e08c aliguori
    qemu_free_irqs(pci_dev->irq);
414 5851e08c aliguori
    pci_dev->bus->devices[pci_dev->devfn] = NULL;
415 02e2da45 Paul Brook
    qdev_free(&pci_dev->qdev);
416 5851e08c aliguori
    return 0;
417 5851e08c aliguori
}
418 5851e08c aliguori
419 28c2c264 Avi Kivity
void pci_register_bar(PCIDevice *pci_dev, int region_num,
420 5fafdf24 ths
                            uint32_t size, int type,
421 69b91039 bellard
                            PCIMapIORegionFunc *map_func)
422 69b91039 bellard
{
423 69b91039 bellard
    PCIIORegion *r;
424 d7ce493a pbrook
    uint32_t addr;
425 b7ee1603 Michael S. Tsirkin
    uint32_t wmask;
426 69b91039 bellard
427 8a8696a3 bellard
    if ((unsigned int)region_num >= PCI_NUM_REGIONS)
428 69b91039 bellard
        return;
429 a4c20c6a aliguori
430 a4c20c6a aliguori
    if (size & (size-1)) {
431 a4c20c6a aliguori
        fprintf(stderr, "ERROR: PCI region size must be pow2 "
432 a4c20c6a aliguori
                    "type=0x%x, size=0x%x\n", type, size);
433 a4c20c6a aliguori
        exit(1);
434 a4c20c6a aliguori
    }
435 a4c20c6a aliguori
436 69b91039 bellard
    r = &pci_dev->io_regions[region_num];
437 69b91039 bellard
    r->addr = -1;
438 69b91039 bellard
    r->size = size;
439 69b91039 bellard
    r->type = type;
440 69b91039 bellard
    r->map_func = map_func;
441 b7ee1603 Michael S. Tsirkin
442 b7ee1603 Michael S. Tsirkin
    wmask = ~(size - 1);
443 d7ce493a pbrook
    if (region_num == PCI_ROM_SLOT) {
444 d7ce493a pbrook
        addr = 0x30;
445 b7ee1603 Michael S. Tsirkin
        /* ROM enable bit is writeable */
446 b7ee1603 Michael S. Tsirkin
        wmask |= 1;
447 d7ce493a pbrook
    } else {
448 d7ce493a pbrook
        addr = 0x10 + region_num * 4;
449 d7ce493a pbrook
    }
450 d7ce493a pbrook
    *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
451 b7ee1603 Michael S. Tsirkin
    *(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask);
452 bd4b65ee Michael S. Tsirkin
    *(uint32_t *)(pci_dev->cmask + addr) = 0xffffffff;
453 69b91039 bellard
}
454 69b91039 bellard
455 0ac32c83 bellard
static void pci_update_mappings(PCIDevice *d)
456 0ac32c83 bellard
{
457 0ac32c83 bellard
    PCIIORegion *r;
458 0ac32c83 bellard
    int cmd, i;
459 8a8696a3 bellard
    uint32_t last_addr, new_addr, config_ofs;
460 3b46e624 ths
461 0ac32c83 bellard
    cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
462 8a8696a3 bellard
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
463 0ac32c83 bellard
        r = &d->io_regions[i];
464 8a8696a3 bellard
        if (i == PCI_ROM_SLOT) {
465 8a8696a3 bellard
            config_ofs = 0x30;
466 8a8696a3 bellard
        } else {
467 8a8696a3 bellard
            config_ofs = 0x10 + i * 4;
468 8a8696a3 bellard
        }
469 0ac32c83 bellard
        if (r->size != 0) {
470 0ac32c83 bellard
            if (r->type & PCI_ADDRESS_SPACE_IO) {
471 0ac32c83 bellard
                if (cmd & PCI_COMMAND_IO) {
472 5fafdf24 ths
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
473 8a8696a3 bellard
                                                         config_ofs));
474 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
475 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
476 0ac32c83 bellard
                    /* NOTE: we have only 64K ioports on PC */
477 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
478 0ac32c83 bellard
                        last_addr >= 0x10000) {
479 0ac32c83 bellard
                        new_addr = -1;
480 0ac32c83 bellard
                    }
481 0ac32c83 bellard
                } else {
482 0ac32c83 bellard
                    new_addr = -1;
483 0ac32c83 bellard
                }
484 0ac32c83 bellard
            } else {
485 0ac32c83 bellard
                if (cmd & PCI_COMMAND_MEMORY) {
486 5fafdf24 ths
                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
487 8a8696a3 bellard
                                                         config_ofs));
488 8a8696a3 bellard
                    /* the ROM slot has a specific enable bit */
489 8a8696a3 bellard
                    if (i == PCI_ROM_SLOT && !(new_addr & 1))
490 8a8696a3 bellard
                        goto no_mem_map;
491 0ac32c83 bellard
                    new_addr = new_addr & ~(r->size - 1);
492 0ac32c83 bellard
                    last_addr = new_addr + r->size - 1;
493 0ac32c83 bellard
                    /* NOTE: we do not support wrapping */
494 0ac32c83 bellard
                    /* XXX: as we cannot support really dynamic
495 0ac32c83 bellard
                       mappings, we handle specific values as invalid
496 0ac32c83 bellard
                       mappings. */
497 0ac32c83 bellard
                    if (last_addr <= new_addr || new_addr == 0 ||
498 0ac32c83 bellard
                        last_addr == -1) {
499 0ac32c83 bellard
                        new_addr = -1;
500 0ac32c83 bellard
                    }
501 0ac32c83 bellard
                } else {
502 8a8696a3 bellard
                no_mem_map:
503 0ac32c83 bellard
                    new_addr = -1;
504 0ac32c83 bellard
                }
505 0ac32c83 bellard
            }
506 0ac32c83 bellard
            /* now do the real mapping */
507 0ac32c83 bellard
            if (new_addr != r->addr) {
508 0ac32c83 bellard
                if (r->addr != -1) {
509 0ac32c83 bellard
                    if (r->type & PCI_ADDRESS_SPACE_IO) {
510 0ac32c83 bellard
                        int class;
511 0ac32c83 bellard
                        /* NOTE: specific hack for IDE in PC case:
512 0ac32c83 bellard
                           only one byte must be mapped. */
513 0ac32c83 bellard
                        class = d->config[0x0a] | (d->config[0x0b] << 8);
514 0ac32c83 bellard
                        if (class == 0x0101 && r->size == 4) {
515 0ac32c83 bellard
                            isa_unassign_ioport(r->addr + 2, 1);
516 0ac32c83 bellard
                        } else {
517 0ac32c83 bellard
                            isa_unassign_ioport(r->addr, r->size);
518 0ac32c83 bellard
                        }
519 0ac32c83 bellard
                    } else {
520 502a5395 pbrook
                        cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
521 5fafdf24 ths
                                                     r->size,
522 0ac32c83 bellard
                                                     IO_MEM_UNASSIGNED);
523 f65ed4c1 aliguori
                        qemu_unregister_coalesced_mmio(r->addr, r->size);
524 0ac32c83 bellard
                    }
525 0ac32c83 bellard
                }
526 0ac32c83 bellard
                r->addr = new_addr;
527 0ac32c83 bellard
                if (r->addr != -1) {
528 0ac32c83 bellard
                    r->map_func(d, i, r->addr, r->size, r->type);
529 0ac32c83 bellard
                }
530 0ac32c83 bellard
            }
531 0ac32c83 bellard
        }
532 0ac32c83 bellard
    }
533 0ac32c83 bellard
}
534 0ac32c83 bellard
535 5fafdf24 ths
uint32_t pci_default_read_config(PCIDevice *d,
536 0ac32c83 bellard
                                 uint32_t address, int len)
537 69b91039 bellard
{
538 0ac32c83 bellard
    uint32_t val;
539 a2d4e44b ths
540 0ac32c83 bellard
    switch(len) {
541 0ac32c83 bellard
    default:
542 0ac32c83 bellard
    case 4:
543 a2d4e44b ths
        if (address <= 0xfc) {
544 a2d4e44b ths
            val = le32_to_cpu(*(uint32_t *)(d->config + address));
545 a2d4e44b ths
            break;
546 a2d4e44b ths
        }
547 a2d4e44b ths
        /* fall through */
548 a2d4e44b ths
    case 2:
549 a2d4e44b ths
        if (address <= 0xfe) {
550 a2d4e44b ths
            val = le16_to_cpu(*(uint16_t *)(d->config + address));
551 a2d4e44b ths
            break;
552 a2d4e44b ths
        }
553 a2d4e44b ths
        /* fall through */
554 a2d4e44b ths
    case 1:
555 a2d4e44b ths
        val = d->config[address];
556 0ac32c83 bellard
        break;
557 0ac32c83 bellard
    }
558 0ac32c83 bellard
    return val;
559 0ac32c83 bellard
}
560 0ac32c83 bellard
561 b7ee1603 Michael S. Tsirkin
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
562 0ac32c83 bellard
{
563 b7ee1603 Michael S. Tsirkin
    uint8_t orig[PCI_CONFIG_SPACE_SIZE];
564 b7ee1603 Michael S. Tsirkin
    int i;
565 0ac32c83 bellard
566 0ac32c83 bellard
    /* not efficient, but simple */
567 b7ee1603 Michael S. Tsirkin
    memcpy(orig, d->config, PCI_CONFIG_SPACE_SIZE);
568 b7ee1603 Michael S. Tsirkin
    for(i = 0; i < l && addr < PCI_CONFIG_SPACE_SIZE; val >>= 8, ++i, ++addr) {
569 b7ee1603 Michael S. Tsirkin
        uint8_t wmask = d->wmask[addr];
570 b7ee1603 Michael S. Tsirkin
        d->config[addr] = (d->config[addr] & ~wmask) | (val & wmask);
571 0ac32c83 bellard
    }
572 b7ee1603 Michael S. Tsirkin
    if (memcmp(orig + PCI_BASE_ADDRESS_0, d->config + PCI_BASE_ADDRESS_0, 24)
573 b7ee1603 Michael S. Tsirkin
        || ((orig[PCI_COMMAND] ^ d->config[PCI_COMMAND])
574 b7ee1603 Michael S. Tsirkin
            & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)))
575 0ac32c83 bellard
        pci_update_mappings(d);
576 69b91039 bellard
}
577 69b91039 bellard
578 502a5395 pbrook
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
579 69b91039 bellard
{
580 30468f78 bellard
    PCIBus *s = opaque;
581 30468f78 bellard
    PCIDevice *pci_dev;
582 30468f78 bellard
    int config_addr, bus_num;
583 3b46e624 ths
584 d8d2e079 Isaku Yamahata
#if 0
585 d8d2e079 Isaku Yamahata
    PCI_DPRINTF("pci_data_write: addr=%08x val=%08x len=%d\n",
586 d8d2e079 Isaku Yamahata
                addr, val, len);
587 69b91039 bellard
#endif
588 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
589 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
590 80b3ada7 pbrook
        s = s->next;
591 80b3ada7 pbrook
    if (!s)
592 69b91039 bellard
        return;
593 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
594 69b91039 bellard
    if (!pci_dev)
595 69b91039 bellard
        return;
596 502a5395 pbrook
    config_addr = addr & 0xff;
597 d8d2e079 Isaku Yamahata
    PCI_DPRINTF("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
598 d8d2e079 Isaku Yamahata
                pci_dev->name, config_addr, val, len);
599 0ac32c83 bellard
    pci_dev->config_write(pci_dev, config_addr, val, len);
600 69b91039 bellard
}
601 69b91039 bellard
602 502a5395 pbrook
uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
603 69b91039 bellard
{
604 30468f78 bellard
    PCIBus *s = opaque;
605 30468f78 bellard
    PCIDevice *pci_dev;
606 30468f78 bellard
    int config_addr, bus_num;
607 69b91039 bellard
    uint32_t val;
608 69b91039 bellard
609 502a5395 pbrook
    bus_num = (addr >> 16) & 0xff;
610 80b3ada7 pbrook
    while (s && s->bus_num != bus_num)
611 80b3ada7 pbrook
        s= s->next;
612 80b3ada7 pbrook
    if (!s)
613 69b91039 bellard
        goto fail;
614 502a5395 pbrook
    pci_dev = s->devices[(addr >> 8) & 0xff];
615 69b91039 bellard
    if (!pci_dev) {
616 69b91039 bellard
    fail:
617 63ce9e0a bellard
        switch(len) {
618 63ce9e0a bellard
        case 1:
619 63ce9e0a bellard
            val = 0xff;
620 63ce9e0a bellard
            break;
621 63ce9e0a bellard
        case 2:
622 63ce9e0a bellard
            val = 0xffff;
623 63ce9e0a bellard
            break;
624 63ce9e0a bellard
        default:
625 63ce9e0a bellard
        case 4:
626 63ce9e0a bellard
            val = 0xffffffff;
627 63ce9e0a bellard
            break;
628 63ce9e0a bellard
        }
629 69b91039 bellard
        goto the_end;
630 69b91039 bellard
    }
631 502a5395 pbrook
    config_addr = addr & 0xff;
632 69b91039 bellard
    val = pci_dev->config_read(pci_dev, config_addr, len);
633 d8d2e079 Isaku Yamahata
    PCI_DPRINTF("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
634 d8d2e079 Isaku Yamahata
                pci_dev->name, config_addr, val, len);
635 69b91039 bellard
 the_end:
636 d8d2e079 Isaku Yamahata
#if 0
637 d8d2e079 Isaku Yamahata
    PCI_DPRINTF("pci_data_read: addr=%08x val=%08x len=%d\n",
638 d8d2e079 Isaku Yamahata
                addr, val, len);
639 69b91039 bellard
#endif
640 69b91039 bellard
    return val;
641 69b91039 bellard
}
642 69b91039 bellard
643 502a5395 pbrook
/***********************************************************/
644 502a5395 pbrook
/* generic PCI irq support */
645 30468f78 bellard
646 502a5395 pbrook
/* 0 <= irq_num <= 3. level must be 0 or 1 */
647 d537cf6c pbrook
static void pci_set_irq(void *opaque, int irq_num, int level)
648 69b91039 bellard
{
649 a60380a5 Juan Quintela
    PCIDevice *pci_dev = opaque;
650 80b3ada7 pbrook
    PCIBus *bus;
651 80b3ada7 pbrook
    int change;
652 3b46e624 ths
653 80b3ada7 pbrook
    change = level - pci_dev->irq_state[irq_num];
654 80b3ada7 pbrook
    if (!change)
655 80b3ada7 pbrook
        return;
656 d2b59317 pbrook
657 d2b59317 pbrook
    pci_dev->irq_state[irq_num] = level;
658 5e966ce6 pbrook
    for (;;) {
659 5e966ce6 pbrook
        bus = pci_dev->bus;
660 80b3ada7 pbrook
        irq_num = bus->map_irq(pci_dev, irq_num);
661 5e966ce6 pbrook
        if (bus->set_irq)
662 5e966ce6 pbrook
            break;
663 80b3ada7 pbrook
        pci_dev = bus->parent_dev;
664 80b3ada7 pbrook
    }
665 80b3ada7 pbrook
    bus->irq_count[irq_num] += change;
666 d2b59317 pbrook
    bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
667 69b91039 bellard
}
668 69b91039 bellard
669 502a5395 pbrook
/***********************************************************/
670 502a5395 pbrook
/* monitor info on PCI */
671 0ac32c83 bellard
672 6650ee6d pbrook
typedef struct {
673 6650ee6d pbrook
    uint16_t class;
674 6650ee6d pbrook
    const char *desc;
675 6650ee6d pbrook
} pci_class_desc;
676 6650ee6d pbrook
677 09bc878a blueswir1
static const pci_class_desc pci_class_descriptions[] =
678 6650ee6d pbrook
{
679 4ca9c76f pbrook
    { 0x0100, "SCSI controller"},
680 6650ee6d pbrook
    { 0x0101, "IDE controller"},
681 dcb5b19a ths
    { 0x0102, "Floppy controller"},
682 dcb5b19a ths
    { 0x0103, "IPI controller"},
683 dcb5b19a ths
    { 0x0104, "RAID controller"},
684 dcb5b19a ths
    { 0x0106, "SATA controller"},
685 dcb5b19a ths
    { 0x0107, "SAS controller"},
686 dcb5b19a ths
    { 0x0180, "Storage controller"},
687 6650ee6d pbrook
    { 0x0200, "Ethernet controller"},
688 dcb5b19a ths
    { 0x0201, "Token Ring controller"},
689 dcb5b19a ths
    { 0x0202, "FDDI controller"},
690 dcb5b19a ths
    { 0x0203, "ATM controller"},
691 dcb5b19a ths
    { 0x0280, "Network controller"},
692 6650ee6d pbrook
    { 0x0300, "VGA controller"},
693 dcb5b19a ths
    { 0x0301, "XGA controller"},
694 dcb5b19a ths
    { 0x0302, "3D controller"},
695 dcb5b19a ths
    { 0x0380, "Display controller"},
696 dcb5b19a ths
    { 0x0400, "Video controller"},
697 dcb5b19a ths
    { 0x0401, "Audio controller"},
698 dcb5b19a ths
    { 0x0402, "Phone"},
699 dcb5b19a ths
    { 0x0480, "Multimedia controller"},
700 dcb5b19a ths
    { 0x0500, "RAM controller"},
701 dcb5b19a ths
    { 0x0501, "Flash controller"},
702 dcb5b19a ths
    { 0x0580, "Memory controller"},
703 6650ee6d pbrook
    { 0x0600, "Host bridge"},
704 6650ee6d pbrook
    { 0x0601, "ISA bridge"},
705 dcb5b19a ths
    { 0x0602, "EISA bridge"},
706 dcb5b19a ths
    { 0x0603, "MC bridge"},
707 6650ee6d pbrook
    { 0x0604, "PCI bridge"},
708 dcb5b19a ths
    { 0x0605, "PCMCIA bridge"},
709 dcb5b19a ths
    { 0x0606, "NUBUS bridge"},
710 dcb5b19a ths
    { 0x0607, "CARDBUS bridge"},
711 dcb5b19a ths
    { 0x0608, "RACEWAY bridge"},
712 dcb5b19a ths
    { 0x0680, "Bridge"},
713 6650ee6d pbrook
    { 0x0c03, "USB controller"},
714 6650ee6d pbrook
    { 0, NULL}
715 6650ee6d pbrook
};
716 6650ee6d pbrook
717 502a5395 pbrook
static void pci_info_device(PCIDevice *d)
718 30468f78 bellard
{
719 376253ec aliguori
    Monitor *mon = cur_mon;
720 502a5395 pbrook
    int i, class;
721 502a5395 pbrook
    PCIIORegion *r;
722 09bc878a blueswir1
    const pci_class_desc *desc;
723 30468f78 bellard
724 376253ec aliguori
    monitor_printf(mon, "  Bus %2d, device %3d, function %d:\n",
725 376253ec aliguori
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
726 502a5395 pbrook
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
727 376253ec aliguori
    monitor_printf(mon, "    ");
728 6650ee6d pbrook
    desc = pci_class_descriptions;
729 6650ee6d pbrook
    while (desc->desc && class != desc->class)
730 6650ee6d pbrook
        desc++;
731 6650ee6d pbrook
    if (desc->desc) {
732 376253ec aliguori
        monitor_printf(mon, "%s", desc->desc);
733 6650ee6d pbrook
    } else {
734 376253ec aliguori
        monitor_printf(mon, "Class %04x", class);
735 72cc6cfe bellard
    }
736 376253ec aliguori
    monitor_printf(mon, ": PCI device %04x:%04x\n",
737 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
738 502a5395 pbrook
           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
739 30468f78 bellard
740 502a5395 pbrook
    if (d->config[PCI_INTERRUPT_PIN] != 0) {
741 376253ec aliguori
        monitor_printf(mon, "      IRQ %d.\n",
742 376253ec aliguori
                       d->config[PCI_INTERRUPT_LINE]);
743 30468f78 bellard
    }
744 80b3ada7 pbrook
    if (class == 0x0604) {
745 376253ec aliguori
        monitor_printf(mon, "      BUS %d.\n", d->config[0x19]);
746 80b3ada7 pbrook
    }
747 502a5395 pbrook
    for(i = 0;i < PCI_NUM_REGIONS; i++) {
748 502a5395 pbrook
        r = &d->io_regions[i];
749 502a5395 pbrook
        if (r->size != 0) {
750 376253ec aliguori
            monitor_printf(mon, "      BAR%d: ", i);
751 502a5395 pbrook
            if (r->type & PCI_ADDRESS_SPACE_IO) {
752 376253ec aliguori
                monitor_printf(mon, "I/O at 0x%04x [0x%04x].\n",
753 376253ec aliguori
                               r->addr, r->addr + r->size - 1);
754 502a5395 pbrook
            } else {
755 376253ec aliguori
                monitor_printf(mon, "32 bit memory at 0x%08x [0x%08x].\n",
756 376253ec aliguori
                               r->addr, r->addr + r->size - 1);
757 502a5395 pbrook
            }
758 502a5395 pbrook
        }
759 77d4bc34 bellard
    }
760 8ad12514 Gerd Hoffmann
    monitor_printf(mon, "      id \"%s\"\n", d->qdev.id ? d->qdev.id : "");
761 80b3ada7 pbrook
    if (class == 0x0604 && d->config[0x19] != 0) {
762 80b3ada7 pbrook
        pci_for_each_device(d->config[0x19], pci_info_device);
763 80b3ada7 pbrook
    }
764 384d8876 bellard
}
765 384d8876 bellard
766 80b3ada7 pbrook
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
767 384d8876 bellard
{
768 502a5395 pbrook
    PCIBus *bus = first_bus;
769 384d8876 bellard
    PCIDevice *d;
770 502a5395 pbrook
    int devfn;
771 3b46e624 ths
772 80b3ada7 pbrook
    while (bus && bus->bus_num != bus_num)
773 80b3ada7 pbrook
        bus = bus->next;
774 502a5395 pbrook
    if (bus) {
775 502a5395 pbrook
        for(devfn = 0; devfn < 256; devfn++) {
776 502a5395 pbrook
            d = bus->devices[devfn];
777 502a5395 pbrook
            if (d)
778 502a5395 pbrook
                fn(d);
779 502a5395 pbrook
        }
780 f2aa58c6 bellard
    }
781 f2aa58c6 bellard
}
782 f2aa58c6 bellard
783 376253ec aliguori
void pci_info(Monitor *mon)
784 f2aa58c6 bellard
{
785 80b3ada7 pbrook
    pci_for_each_device(0, pci_info_device);
786 77d4bc34 bellard
}
787 a41b2ff2 pbrook
788 1f5f6638 Markus Armbruster
PCIDevice *pci_create(const char *name, const char *devaddr)
789 5607c388 Markus Armbruster
{
790 5607c388 Markus Armbruster
    PCIBus *bus;
791 5607c388 Markus Armbruster
    int devfn;
792 5607c388 Markus Armbruster
    DeviceState *dev;
793 5607c388 Markus Armbruster
794 5607c388 Markus Armbruster
    bus = pci_get_bus_devfn(&devfn, devaddr);
795 5607c388 Markus Armbruster
    if (!bus) {
796 5607c388 Markus Armbruster
        fprintf(stderr, "Invalid PCI device address %s for device %s\n",
797 5607c388 Markus Armbruster
                devaddr, name);
798 5607c388 Markus Armbruster
        exit(1);
799 5607c388 Markus Armbruster
    }
800 5607c388 Markus Armbruster
801 5607c388 Markus Armbruster
    dev = qdev_create(&bus->qbus, name);
802 a6307b08 Gerd Hoffmann
    qdev_prop_set_uint32(dev, "addr", devfn);
803 5607c388 Markus Armbruster
    return (PCIDevice *)dev;
804 5607c388 Markus Armbruster
}
805 5607c388 Markus Armbruster
806 cb457d76 aliguori
static const char * const pci_nic_models[] = {
807 cb457d76 aliguori
    "ne2k_pci",
808 cb457d76 aliguori
    "i82551",
809 cb457d76 aliguori
    "i82557b",
810 cb457d76 aliguori
    "i82559er",
811 cb457d76 aliguori
    "rtl8139",
812 cb457d76 aliguori
    "e1000",
813 cb457d76 aliguori
    "pcnet",
814 cb457d76 aliguori
    "virtio",
815 cb457d76 aliguori
    NULL
816 cb457d76 aliguori
};
817 cb457d76 aliguori
818 9d07d757 Paul Brook
static const char * const pci_nic_names[] = {
819 9d07d757 Paul Brook
    "ne2k_pci",
820 9d07d757 Paul Brook
    "i82551",
821 9d07d757 Paul Brook
    "i82557b",
822 9d07d757 Paul Brook
    "i82559er",
823 9d07d757 Paul Brook
    "rtl8139",
824 9d07d757 Paul Brook
    "e1000",
825 9d07d757 Paul Brook
    "pcnet",
826 53c25cea Paul Brook
    "virtio-net-pci",
827 cb457d76 aliguori
    NULL
828 cb457d76 aliguori
};
829 cb457d76 aliguori
830 0148fde5 Luiz Capitulino
int pci_nic_supported(const char *model)
831 0148fde5 Luiz Capitulino
{
832 0148fde5 Luiz Capitulino
    int i;
833 0148fde5 Luiz Capitulino
834 0148fde5 Luiz Capitulino
    for (i = 0; pci_nic_names[i]; i++)
835 0148fde5 Luiz Capitulino
        if (strcmp(model, pci_nic_names[i]) == 0)
836 0148fde5 Luiz Capitulino
            return 1;
837 0148fde5 Luiz Capitulino
838 0148fde5 Luiz Capitulino
    return 0;
839 0148fde5 Luiz Capitulino
}
840 0148fde5 Luiz Capitulino
841 a41b2ff2 pbrook
/* Initialize a PCI NIC.  */
842 5607c388 Markus Armbruster
PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
843 5607c388 Markus Armbruster
                        const char *default_devaddr)
844 a41b2ff2 pbrook
{
845 5607c388 Markus Armbruster
    const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
846 5607c388 Markus Armbruster
    PCIDevice *pci_dev;
847 9d07d757 Paul Brook
    DeviceState *dev;
848 cb457d76 aliguori
    int i;
849 cb457d76 aliguori
850 cb457d76 aliguori
    qemu_check_nic_model_list(nd, pci_nic_models, default_model);
851 cb457d76 aliguori
852 9d07d757 Paul Brook
    for (i = 0; pci_nic_models[i]; i++) {
853 72da4208 aliguori
        if (strcmp(nd->model, pci_nic_models[i]) == 0) {
854 5607c388 Markus Armbruster
            pci_dev = pci_create(pci_nic_names[i], devaddr);
855 5607c388 Markus Armbruster
            dev = &pci_dev->qdev;
856 eb54b6dc Gerd Hoffmann
            if (nd->id)
857 eb54b6dc Gerd Hoffmann
                dev->id = qemu_strdup(nd->id);
858 ee6847d1 Gerd Hoffmann
            dev->nd = nd;
859 9d07d757 Paul Brook
            qdev_init(dev);
860 9d07d757 Paul Brook
            nd->private = dev;
861 5607c388 Markus Armbruster
            return pci_dev;
862 72da4208 aliguori
        }
863 9d07d757 Paul Brook
    }
864 72da4208 aliguori
865 72da4208 aliguori
    return NULL;
866 a41b2ff2 pbrook
}
867 a41b2ff2 pbrook
868 80b3ada7 pbrook
typedef struct {
869 80b3ada7 pbrook
    PCIDevice dev;
870 03587182 Gerd Hoffmann
    PCIBus bus;
871 03587182 Gerd Hoffmann
    uint32_t vid;
872 03587182 Gerd Hoffmann
    uint32_t did;
873 80b3ada7 pbrook
} PCIBridge;
874 80b3ada7 pbrook
875 9596ebb7 pbrook
static void pci_bridge_write_config(PCIDevice *d,
876 80b3ada7 pbrook
                             uint32_t address, uint32_t val, int len)
877 80b3ada7 pbrook
{
878 80b3ada7 pbrook
    PCIBridge *s = (PCIBridge *)d;
879 80b3ada7 pbrook
880 80b3ada7 pbrook
    pci_default_write_config(d, address, val, len);
881 03587182 Gerd Hoffmann
    s->bus.bus_num = d->config[PCI_SECONDARY_BUS];
882 80b3ada7 pbrook
}
883 80b3ada7 pbrook
884 3ae80618 aliguori
PCIBus *pci_find_bus(int bus_num)
885 3ae80618 aliguori
{
886 3ae80618 aliguori
    PCIBus *bus = first_bus;
887 3ae80618 aliguori
888 3ae80618 aliguori
    while (bus && bus->bus_num != bus_num)
889 3ae80618 aliguori
        bus = bus->next;
890 3ae80618 aliguori
891 3ae80618 aliguori
    return bus;
892 3ae80618 aliguori
}
893 3ae80618 aliguori
894 3ae80618 aliguori
PCIDevice *pci_find_device(int bus_num, int slot, int function)
895 3ae80618 aliguori
{
896 3ae80618 aliguori
    PCIBus *bus = pci_find_bus(bus_num);
897 3ae80618 aliguori
898 3ae80618 aliguori
    if (!bus)
899 3ae80618 aliguori
        return NULL;
900 3ae80618 aliguori
901 3ae80618 aliguori
    return bus->devices[PCI_DEVFN(slot, function)];
902 3ae80618 aliguori
}
903 3ae80618 aliguori
904 03587182 Gerd Hoffmann
static int pci_bridge_initfn(PCIDevice *dev)
905 80b3ada7 pbrook
{
906 03587182 Gerd Hoffmann
    PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
907 480b9f24 blueswir1
908 03587182 Gerd Hoffmann
    pci_config_set_vendor_id(s->dev.config, s->vid);
909 03587182 Gerd Hoffmann
    pci_config_set_device_id(s->dev.config, s->did);
910 480b9f24 blueswir1
911 80b3ada7 pbrook
    s->dev.config[0x04] = 0x06; // command = bus master, pci mem
912 80b3ada7 pbrook
    s->dev.config[0x05] = 0x00;
913 80b3ada7 pbrook
    s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
914 80b3ada7 pbrook
    s->dev.config[0x07] = 0x00; // status = fast devsel
915 80b3ada7 pbrook
    s->dev.config[0x08] = 0x00; // revision
916 80b3ada7 pbrook
    s->dev.config[0x09] = 0x00; // programming i/f
917 173a543b blueswir1
    pci_config_set_class(s->dev.config, PCI_CLASS_BRIDGE_PCI);
918 80b3ada7 pbrook
    s->dev.config[0x0D] = 0x10; // latency_timer
919 6407f373 Isaku Yamahata
    s->dev.config[PCI_HEADER_TYPE] =
920 6407f373 Isaku Yamahata
        PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
921 80b3ada7 pbrook
    s->dev.config[0x1E] = 0xa0; // secondary status
922 03587182 Gerd Hoffmann
    return 0;
923 03587182 Gerd Hoffmann
}
924 80b3ada7 pbrook
925 03587182 Gerd Hoffmann
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
926 03587182 Gerd Hoffmann
                        pci_map_irq_fn map_irq, const char *name)
927 03587182 Gerd Hoffmann
{
928 03587182 Gerd Hoffmann
    PCIDevice *dev;
929 03587182 Gerd Hoffmann
    PCIBridge *s;
930 03587182 Gerd Hoffmann
931 03587182 Gerd Hoffmann
    dev = pci_create_noinit(bus, devfn, "pci-bridge");
932 03587182 Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "vendorid", vid);
933 03587182 Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "deviceid", did);
934 03587182 Gerd Hoffmann
    qdev_init(&dev->qdev);
935 03587182 Gerd Hoffmann
936 03587182 Gerd Hoffmann
    s = DO_UPCAST(PCIBridge, dev, dev);
937 03587182 Gerd Hoffmann
    pci_register_secondary_bus(&s->bus, &s->dev, map_irq, name);
938 03587182 Gerd Hoffmann
    return &s->bus;
939 80b3ada7 pbrook
}
940 6b1b92d3 Paul Brook
941 81a322d4 Gerd Hoffmann
static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
942 6b1b92d3 Paul Brook
{
943 6b1b92d3 Paul Brook
    PCIDevice *pci_dev = (PCIDevice *)qdev;
944 02e2da45 Paul Brook
    PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
945 6b1b92d3 Paul Brook
    PCIBus *bus;
946 6b1b92d3 Paul Brook
    int devfn;
947 6b1b92d3 Paul Brook
948 02e2da45 Paul Brook
    bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
949 ee6847d1 Gerd Hoffmann
    devfn = pci_dev->devfn;
950 16eaedf2 Gerd Hoffmann
    pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
951 0aab0d3a Gerd Hoffmann
                                     info->config_read, info->config_write);
952 6b1b92d3 Paul Brook
    assert(pci_dev);
953 81a322d4 Gerd Hoffmann
    return info->init(pci_dev);
954 6b1b92d3 Paul Brook
}
955 6b1b92d3 Paul Brook
956 0aab0d3a Gerd Hoffmann
void pci_qdev_register(PCIDeviceInfo *info)
957 6b1b92d3 Paul Brook
{
958 02e2da45 Paul Brook
    info->qdev.init = pci_qdev_init;
959 10c4c98a Gerd Hoffmann
    info->qdev.bus_info = &pci_bus_info;
960 074f2fff Gerd Hoffmann
    qdev_register(&info->qdev);
961 6b1b92d3 Paul Brook
}
962 6b1b92d3 Paul Brook
963 0aab0d3a Gerd Hoffmann
void pci_qdev_register_many(PCIDeviceInfo *info)
964 0aab0d3a Gerd Hoffmann
{
965 0aab0d3a Gerd Hoffmann
    while (info->qdev.name) {
966 0aab0d3a Gerd Hoffmann
        pci_qdev_register(info);
967 0aab0d3a Gerd Hoffmann
        info++;
968 0aab0d3a Gerd Hoffmann
    }
969 0aab0d3a Gerd Hoffmann
}
970 0aab0d3a Gerd Hoffmann
971 71077c1c Gerd Hoffmann
PCIDevice *pci_create_noinit(PCIBus *bus, int devfn, const char *name)
972 6b1b92d3 Paul Brook
{
973 6b1b92d3 Paul Brook
    DeviceState *dev;
974 6b1b92d3 Paul Brook
975 02e2da45 Paul Brook
    dev = qdev_create(&bus->qbus, name);
976 a6307b08 Gerd Hoffmann
    qdev_prop_set_uint32(dev, "addr", devfn);
977 71077c1c Gerd Hoffmann
    return DO_UPCAST(PCIDevice, qdev, dev);
978 71077c1c Gerd Hoffmann
}
979 6b1b92d3 Paul Brook
980 71077c1c Gerd Hoffmann
PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
981 71077c1c Gerd Hoffmann
{
982 71077c1c Gerd Hoffmann
    PCIDevice *dev = pci_create_noinit(bus, devfn, name);
983 71077c1c Gerd Hoffmann
    qdev_init(&dev->qdev);
984 71077c1c Gerd Hoffmann
    return dev;
985 6b1b92d3 Paul Brook
}
986 6f4cbd39 Michael S. Tsirkin
987 6f4cbd39 Michael S. Tsirkin
static int pci_find_space(PCIDevice *pdev, uint8_t size)
988 6f4cbd39 Michael S. Tsirkin
{
989 6f4cbd39 Michael S. Tsirkin
    int offset = PCI_CONFIG_HEADER_SIZE;
990 6f4cbd39 Michael S. Tsirkin
    int i;
991 6f4cbd39 Michael S. Tsirkin
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
992 6f4cbd39 Michael S. Tsirkin
        if (pdev->used[i])
993 6f4cbd39 Michael S. Tsirkin
            offset = i + 1;
994 6f4cbd39 Michael S. Tsirkin
        else if (i - offset + 1 == size)
995 6f4cbd39 Michael S. Tsirkin
            return offset;
996 6f4cbd39 Michael S. Tsirkin
    return 0;
997 6f4cbd39 Michael S. Tsirkin
}
998 6f4cbd39 Michael S. Tsirkin
999 6f4cbd39 Michael S. Tsirkin
static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
1000 6f4cbd39 Michael S. Tsirkin
                                        uint8_t *prev_p)
1001 6f4cbd39 Michael S. Tsirkin
{
1002 6f4cbd39 Michael S. Tsirkin
    uint8_t next, prev;
1003 6f4cbd39 Michael S. Tsirkin
1004 6f4cbd39 Michael S. Tsirkin
    if (!(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST))
1005 6f4cbd39 Michael S. Tsirkin
        return 0;
1006 6f4cbd39 Michael S. Tsirkin
1007 6f4cbd39 Michael S. Tsirkin
    for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
1008 6f4cbd39 Michael S. Tsirkin
         prev = next + PCI_CAP_LIST_NEXT)
1009 6f4cbd39 Michael S. Tsirkin
        if (pdev->config[next + PCI_CAP_LIST_ID] == cap_id)
1010 6f4cbd39 Michael S. Tsirkin
            break;
1011 6f4cbd39 Michael S. Tsirkin
1012 6f4cbd39 Michael S. Tsirkin
    if (prev_p)
1013 6f4cbd39 Michael S. Tsirkin
        *prev_p = prev;
1014 6f4cbd39 Michael S. Tsirkin
    return next;
1015 6f4cbd39 Michael S. Tsirkin
}
1016 6f4cbd39 Michael S. Tsirkin
1017 6f4cbd39 Michael S. Tsirkin
/* Reserve space and add capability to the linked list in pci config space */
1018 6f4cbd39 Michael S. Tsirkin
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
1019 6f4cbd39 Michael S. Tsirkin
{
1020 6f4cbd39 Michael S. Tsirkin
    uint8_t offset = pci_find_space(pdev, size);
1021 6f4cbd39 Michael S. Tsirkin
    uint8_t *config = pdev->config + offset;
1022 6f4cbd39 Michael S. Tsirkin
    if (!offset)
1023 6f4cbd39 Michael S. Tsirkin
        return -ENOSPC;
1024 6f4cbd39 Michael S. Tsirkin
    config[PCI_CAP_LIST_ID] = cap_id;
1025 6f4cbd39 Michael S. Tsirkin
    config[PCI_CAP_LIST_NEXT] = pdev->config[PCI_CAPABILITY_LIST];
1026 6f4cbd39 Michael S. Tsirkin
    pdev->config[PCI_CAPABILITY_LIST] = offset;
1027 6f4cbd39 Michael S. Tsirkin
    pdev->config[PCI_STATUS] |= PCI_STATUS_CAP_LIST;
1028 6f4cbd39 Michael S. Tsirkin
    memset(pdev->used + offset, 0xFF, size);
1029 6f4cbd39 Michael S. Tsirkin
    /* Make capability read-only by default */
1030 6f4cbd39 Michael S. Tsirkin
    memset(pdev->wmask + offset, 0, size);
1031 bd4b65ee Michael S. Tsirkin
    /* Check capability by default */
1032 bd4b65ee Michael S. Tsirkin
    memset(pdev->cmask + offset, 0xFF, size);
1033 6f4cbd39 Michael S. Tsirkin
    return offset;
1034 6f4cbd39 Michael S. Tsirkin
}
1035 6f4cbd39 Michael S. Tsirkin
1036 6f4cbd39 Michael S. Tsirkin
/* Unlink capability from the pci config space. */
1037 6f4cbd39 Michael S. Tsirkin
void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
1038 6f4cbd39 Michael S. Tsirkin
{
1039 6f4cbd39 Michael S. Tsirkin
    uint8_t prev, offset = pci_find_capability_list(pdev, cap_id, &prev);
1040 6f4cbd39 Michael S. Tsirkin
    if (!offset)
1041 6f4cbd39 Michael S. Tsirkin
        return;
1042 6f4cbd39 Michael S. Tsirkin
    pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];
1043 6f4cbd39 Michael S. Tsirkin
    /* Make capability writeable again */
1044 6f4cbd39 Michael S. Tsirkin
    memset(pdev->wmask + offset, 0xff, size);
1045 bd4b65ee Michael S. Tsirkin
    /* Clear cmask as device-specific registers can't be checked */
1046 bd4b65ee Michael S. Tsirkin
    memset(pdev->cmask + offset, 0, size);
1047 6f4cbd39 Michael S. Tsirkin
    memset(pdev->used + offset, 0, size);
1048 6f4cbd39 Michael S. Tsirkin
1049 6f4cbd39 Michael S. Tsirkin
    if (!pdev->config[PCI_CAPABILITY_LIST])
1050 6f4cbd39 Michael S. Tsirkin
        pdev->config[PCI_STATUS] &= ~PCI_STATUS_CAP_LIST;
1051 6f4cbd39 Michael S. Tsirkin
}
1052 6f4cbd39 Michael S. Tsirkin
1053 6f4cbd39 Michael S. Tsirkin
/* Reserve space for capability at a known offset (to call after load). */
1054 6f4cbd39 Michael S. Tsirkin
void pci_reserve_capability(PCIDevice *pdev, uint8_t offset, uint8_t size)
1055 6f4cbd39 Michael S. Tsirkin
{
1056 6f4cbd39 Michael S. Tsirkin
    memset(pdev->used + offset, 0xff, size);
1057 6f4cbd39 Michael S. Tsirkin
}
1058 6f4cbd39 Michael S. Tsirkin
1059 6f4cbd39 Michael S. Tsirkin
uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id)
1060 6f4cbd39 Michael S. Tsirkin
{
1061 6f4cbd39 Michael S. Tsirkin
    return pci_find_capability_list(pdev, cap_id, NULL);
1062 6f4cbd39 Michael S. Tsirkin
}
1063 10c4c98a Gerd Hoffmann
1064 10c4c98a Gerd Hoffmann
static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
1065 10c4c98a Gerd Hoffmann
{
1066 10c4c98a Gerd Hoffmann
    PCIDevice *d = (PCIDevice *)dev;
1067 10c4c98a Gerd Hoffmann
    const pci_class_desc *desc;
1068 10c4c98a Gerd Hoffmann
    char ctxt[64];
1069 10c4c98a Gerd Hoffmann
    PCIIORegion *r;
1070 10c4c98a Gerd Hoffmann
    int i, class;
1071 10c4c98a Gerd Hoffmann
1072 10c4c98a Gerd Hoffmann
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
1073 10c4c98a Gerd Hoffmann
    desc = pci_class_descriptions;
1074 10c4c98a Gerd Hoffmann
    while (desc->desc && class != desc->class)
1075 10c4c98a Gerd Hoffmann
        desc++;
1076 10c4c98a Gerd Hoffmann
    if (desc->desc) {
1077 10c4c98a Gerd Hoffmann
        snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
1078 10c4c98a Gerd Hoffmann
    } else {
1079 10c4c98a Gerd Hoffmann
        snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
1080 10c4c98a Gerd Hoffmann
    }
1081 10c4c98a Gerd Hoffmann
1082 10c4c98a Gerd Hoffmann
    monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
1083 10c4c98a Gerd Hoffmann
                   "pci id %04x:%04x (sub %04x:%04x)\n",
1084 10c4c98a Gerd Hoffmann
                   indent, "", ctxt,
1085 10c4c98a Gerd Hoffmann
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7,
1086 10c4c98a Gerd Hoffmann
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
1087 10c4c98a Gerd Hoffmann
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))),
1088 10c4c98a Gerd Hoffmann
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_VENDOR_ID))),
1089 10c4c98a Gerd Hoffmann
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_ID))));
1090 10c4c98a Gerd Hoffmann
    for (i = 0; i < PCI_NUM_REGIONS; i++) {
1091 10c4c98a Gerd Hoffmann
        r = &d->io_regions[i];
1092 10c4c98a Gerd Hoffmann
        if (!r->size)
1093 10c4c98a Gerd Hoffmann
            continue;
1094 10c4c98a Gerd Hoffmann
        monitor_printf(mon, "%*sbar %d: %s at 0x%x [0x%x]\n", indent, "",
1095 10c4c98a Gerd Hoffmann
                       i, r->type & PCI_ADDRESS_SPACE_IO ? "i/o" : "mem",
1096 10c4c98a Gerd Hoffmann
                       r->addr, r->addr + r->size - 1);
1097 10c4c98a Gerd Hoffmann
    }
1098 10c4c98a Gerd Hoffmann
}
1099 03587182 Gerd Hoffmann
1100 03587182 Gerd Hoffmann
static PCIDeviceInfo bridge_info = {
1101 03587182 Gerd Hoffmann
    .qdev.name    = "pci-bridge",
1102 03587182 Gerd Hoffmann
    .qdev.size    = sizeof(PCIBridge),
1103 03587182 Gerd Hoffmann
    .init         = pci_bridge_initfn,
1104 03587182 Gerd Hoffmann
    .config_write = pci_bridge_write_config,
1105 03587182 Gerd Hoffmann
    .qdev.props   = (Property[]) {
1106 03587182 Gerd Hoffmann
        DEFINE_PROP_HEX32("vendorid", PCIBridge, vid, 0),
1107 03587182 Gerd Hoffmann
        DEFINE_PROP_HEX32("deviceid", PCIBridge, did, 0),
1108 03587182 Gerd Hoffmann
        DEFINE_PROP_END_OF_LIST(),
1109 03587182 Gerd Hoffmann
    }
1110 03587182 Gerd Hoffmann
};
1111 03587182 Gerd Hoffmann
1112 03587182 Gerd Hoffmann
static void pci_register_devices(void)
1113 03587182 Gerd Hoffmann
{
1114 03587182 Gerd Hoffmann
    pci_qdev_register(&bridge_info);
1115 03587182 Gerd Hoffmann
}
1116 03587182 Gerd Hoffmann
1117 03587182 Gerd Hoffmann
device_init(pci_register_devices)