pci.c 32.8 KB
Newer Older
B
bellard 已提交
1 2 3 4
/*
 * QEMU PCI bus manager
 *
 * Copyright (c) 2004 Fabrice Bellard
5
 *
B
bellard 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
P
pbrook 已提交
24 25
#include "hw.h"
#include "pci.h"
A
aliguori 已提交
26
#include "monitor.h"
P
pbrook 已提交
27
#include "net.h"
28
#include "sysemu.h"
29
#include "msix.h"
B
bellard 已提交
30 31

//#define DEBUG_PCI
32 33 34 35 36
#ifdef DEBUG_PCI
# define PCI_DPRINTF(format, ...)       printf(format, __VA_ARGS__)
#else
# define PCI_DPRINTF(format, ...)       do { } while (0)
#endif
B
bellard 已提交
37

38
struct PCIBus {
P
Paul Brook 已提交
39
    BusState qbus;
40 41
    int bus_num;
    int devfn_min;
P
pbrook 已提交
42
    pci_set_irq_fn set_irq;
43
    pci_map_irq_fn map_irq;
G
Gerd Hoffmann 已提交
44
    pci_hotplug_fn hotplug;
45
    uint32_t config_reg; /* XXX: suppress */
46
    void *irq_opaque;
47
    PCIDevice *devices[256];
P
pbrook 已提交
48 49
    PCIDevice *parent_dev;
    PCIBus *next;
50 51
    /* The bus IRQ state is the logical OR of the connected devices.
       Keep a count of the number of devices with raised IRQs.  */
52
    int nirq;
53 54 55 56 57 58 59 60 61
    int *irq_count;
};

static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);

static struct BusInfo pci_bus_info = {
    .name       = "PCI",
    .size       = sizeof(PCIBus),
    .print_dev  = pcibus_dev_print,
G
Gerd Hoffmann 已提交
62
    .props      = (Property[]) {
63 64
        DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
        DEFINE_PROP_END_OF_LIST()
G
Gerd Hoffmann 已提交
65
    }
66
};
B
bellard 已提交
67

B
bellard 已提交
68
static void pci_update_mappings(PCIDevice *d);
P
pbrook 已提交
69
static void pci_set_irq(void *opaque, int irq_num, int level);
B
bellard 已提交
70

A
Anthony Liguori 已提交
71
target_phys_addr_t pci_mem_base;
72 73
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
74 75
static PCIBus *first_bus;

J
Juan Quintela 已提交
76 77 78 79 80 81 82 83 84
static const VMStateDescription vmstate_pcibus = {
    .name = "PCIBUS",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField []) {
        VMSTATE_INT32_EQUAL(nirq, PCIBus),
        VMSTATE_INT32_VARRAY(irq_count, PCIBus, nirq),
        VMSTATE_END_OF_LIST()
85
    }
J
Juan Quintela 已提交
86
};
87

88 89 90 91 92 93 94
static inline int pci_bar(int reg)
{
    return reg == PCI_ROM_SLOT ? PCI_ROM_ADDRESS : PCI_BASE_ADDRESS_0 + reg * 4;
}

static void pci_device_reset(PCIDevice *dev)
{
95 96
    int r;

97
    memset(dev->irq_state, 0, sizeof dev->irq_state);
98 99 100 101 102 103 104 105 106 107 108
    dev->config[PCI_COMMAND] &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
                                  PCI_COMMAND_MASTER);
    dev->config[PCI_CACHE_LINE_SIZE] = 0x0;
    dev->config[PCI_INTERRUPT_LINE] = 0x0;
    for (r = 0; r < PCI_NUM_REGIONS; ++r) {
        if (!dev->io_regions[r].size) {
            continue;
        }
        pci_set_long(dev->config + pci_bar(r), dev->io_regions[r].type);
    }
    pci_update_mappings(dev);
109 110
}

G
Gleb Natapov 已提交
111 112
static void pci_bus_reset(void *opaque)
{
113
    PCIBus *bus = opaque;
G
Gleb Natapov 已提交
114 115 116 117 118
    int i;

    for (i = 0; i < bus->nirq; i++) {
        bus->irq_count[i] = 0;
    }
119 120 121 122
    for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
        if (bus->devices[i]) {
            pci_device_reset(bus->devices[i]);
        }
G
Gleb Natapov 已提交
123 124 125
    }
}

126 127
void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                         const char *name, int devfn_min)
128
{
129 130
    static int nbus = 0;

131
    qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
P
pbrook 已提交
132
    bus->devfn_min = devfn_min;
I
Isaku Yamahata 已提交
133
    bus->next = first_bus;
134
    first_bus = bus;
J
Juan Quintela 已提交
135
    vmstate_register(nbus++, &vmstate_pcibus, bus);
136
    qemu_register_reset(pci_bus_reset, bus);
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
}

PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)
{
    PCIBus *bus;

    bus = qemu_mallocz(sizeof(*bus));
    bus->qbus.qdev_allocated = 1;
    pci_bus_new_inplace(bus, parent, name, devfn_min);
    return bus;
}

void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                  void *irq_opaque, int nirq)
{
    bus->set_irq = set_irq;
    bus->map_irq = map_irq;
    bus->irq_opaque = irq_opaque;
    bus->nirq = nirq;
    bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
}

G
Gerd Hoffmann 已提交
159 160 161 162 163 164
void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug)
{
    bus->qbus.allow_hotplug = 1;
    bus->hotplug = hotplug;
}

165 166 167 168 169 170 171 172
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                         pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                         void *irq_opaque, int devfn_min, int nirq)
{
    PCIBus *bus;

    bus = pci_bus_new(parent, name, devfn_min);
    pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
173 174
    return bus;
}
B
bellard 已提交
175

G
Gerd Hoffmann 已提交
176 177 178 179
static void pci_register_secondary_bus(PCIBus *bus,
                                       PCIDevice *dev,
                                       pci_map_irq_fn map_irq,
                                       const char *name)
P
pbrook 已提交
180
{
G
Gerd Hoffmann 已提交
181
    qbus_create_inplace(&bus->qbus, &pci_bus_info, &dev->qdev, name);
P
pbrook 已提交
182 183 184 185 186 187
    bus->map_irq = map_irq;
    bus->parent_dev = dev;
    bus->next = dev->bus->next;
    dev->bus->next = bus;
}

P
pbrook 已提交
188 189 190 191 192
int pci_bus_num(PCIBus *s)
{
    return s->bus_num;
}

J
Juan Quintela 已提交
193
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
194
{
J
Juan Quintela 已提交
195 196
    PCIDevice *s = container_of(pv, PCIDevice, config);
    uint8_t config[size];
197 198
    int i;

J
Juan Quintela 已提交
199 200
    qemu_get_buffer(f, config, size);
    for (i = 0; i < size; ++i)
201 202
        if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i])
            return -EINVAL;
J
Juan Quintela 已提交
203
    memcpy(s->config, config, size);
204

B
bellard 已提交
205
    pci_update_mappings(s);
206

207 208 209
    return 0;
}

J
Juan Quintela 已提交
210
/* just put buffer */
211
static void put_pci_config_device(QEMUFile *f, void *pv, size_t size)
J
Juan Quintela 已提交
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
{
    const uint8_t *v = pv;
    qemu_put_buffer(f, v, size);
}

static VMStateInfo vmstate_info_pci_config = {
    .name = "pci config",
    .get  = get_pci_config_device,
    .put  = put_pci_config_device,
};

const VMStateDescription vmstate_pci_device = {
    .name = "PCIDevice",
    .version_id = 2,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField []) {
        VMSTATE_INT32_LE(version_id, PCIDevice),
        VMSTATE_SINGLE(config, PCIDevice, 0, vmstate_info_pci_config,
                       typeof_field(PCIDevice,config)),
        VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, 4, 2),
        VMSTATE_END_OF_LIST()
    }
};

void pci_device_save(PCIDevice *s, QEMUFile *f)
{
    vmstate_save_state(f, &vmstate_pci_device, s);
}

int pci_device_load(PCIDevice *s, QEMUFile *f)
{
    return vmstate_load_state(f, &vmstate_pci_device, s, s->version_id);
}

247 248 249 250 251 252 253 254 255 256
static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
{
    uint16_t *id;

    id = (void*)(&pci_dev->config[PCI_SUBVENDOR_ID]);
    id[0] = cpu_to_le16(pci_default_sub_vendor_id);
    id[1] = cpu_to_le16(pci_default_sub_device_id);
    return 0;
}

257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
/*
 * Parse [[<domain>:]<bus>:]<slot>, return -1 on error
 */
static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
{
    const char *p;
    char *e;
    unsigned long val;
    unsigned long dom = 0, bus = 0;
    unsigned slot = 0;

    p = addr;
    val = strtoul(p, &e, 16);
    if (e == p)
	return -1;
    if (*e == ':') {
	bus = val;
	p = e + 1;
	val = strtoul(p, &e, 16);
	if (e == p)
	    return -1;
	if (*e == ':') {
	    dom = bus;
	    bus = val;
	    p = e + 1;
	    val = strtoul(p, &e, 16);
	    if (e == p)
		return -1;
	}
    }

    if (dom > 0xffff || bus > 0xff || val > 0x1f)
	return -1;

    slot = val;

    if (*e)
	return -1;

    /* Note: QEMU doesn't implement domains other than 0 */
    if (dom != 0 || pci_find_bus(bus) == NULL)
	return -1;

    *domp = dom;
    *busp = bus;
    *slotp = slot;
    return 0;
}

306 307
int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
                     unsigned *slotp)
308
{
309 310 311 312 313 314
    /* strip legacy tag */
    if (!strncmp(addr, "pci_addr=", 9)) {
        addr += 9;
    }
    if (pci_parse_devaddr(addr, domp, busp, slotp)) {
        monitor_printf(mon, "Invalid pci address\n");
315
        return -1;
316 317
    }
    return 0;
318 319
}

320
PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
{
    int dom, bus;
    unsigned slot;

    if (!devaddr) {
        *devfnp = -1;
        return pci_find_bus(0);
    }

    if (pci_parse_devaddr(devaddr, &dom, &bus, &slot) < 0) {
        return NULL;
    }

    *devfnp = slot << 3;
    return pci_find_bus(bus);
}

338 339 340 341 342 343 344 345 346 347 348 349
static void pci_init_cmask(PCIDevice *dev)
{
    pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff);
    pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff);
    dev->cmask[PCI_STATUS] = PCI_STATUS_CAP_LIST;
    dev->cmask[PCI_REVISION_ID] = 0xff;
    dev->cmask[PCI_CLASS_PROG] = 0xff;
    pci_set_word(dev->cmask + PCI_CLASS_DEVICE, 0xffff);
    dev->cmask[PCI_HEADER_TYPE] = 0xff;
    dev->cmask[PCI_CAPABILITY_LIST] = 0xff;
}

350 351 352 353 354 355 356 357 358 359 360
static void pci_init_wmask(PCIDevice *dev)
{
    int i;
    dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
    dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
    dev->wmask[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY
                              | PCI_COMMAND_MASTER;
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
        dev->wmask[i] = 0xff;
}

B
bellard 已提交
361
/* -1 for devfn means auto assign */
P
Paul Brook 已提交
362 363 364 365
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
                                         const char *name, int devfn,
                                         PCIConfigReadFunc *config_read,
                                         PCIConfigWriteFunc *config_write)
B
bellard 已提交
366 367
{
    if (devfn < 0) {
368 369
        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
            if (!bus->devices[devfn])
B
bellard 已提交
370 371 372 373
                goto found;
        }
        return NULL;
    found: ;
374 375
    } else if (bus->devices[devfn]) {
        return NULL;
B
bellard 已提交
376
    }
377
    pci_dev->bus = bus;
B
bellard 已提交
378 379
    pci_dev->devfn = devfn;
    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
380
    memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
381
    pci_set_default_subsystem_id(pci_dev);
382
    pci_init_cmask(pci_dev);
383
    pci_init_wmask(pci_dev);
384 385 386 387 388

    if (!config_read)
        config_read = pci_default_read_config;
    if (!config_write)
        config_write = pci_default_write_config;
B
bellard 已提交
389 390
    pci_dev->config_read = config_read;
    pci_dev->config_write = config_write;
391
    bus->devices[devfn] = pci_dev;
P
pbrook 已提交
392
    pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
J
Juan Quintela 已提交
393
    pci_dev->version_id = 2; /* Current pci device vmstate version */
B
bellard 已提交
394 395 396
    return pci_dev;
}

P
Paul Brook 已提交
397 398 399 400 401 402 403 404 405 406 407 408
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                               int instance_size, int devfn,
                               PCIConfigReadFunc *config_read,
                               PCIConfigWriteFunc *config_write)
{
    PCIDevice *pci_dev;

    pci_dev = qemu_mallocz(instance_size);
    pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,
                                     config_read, config_write);
    return pci_dev;
}
A
Anthony Liguori 已提交
409
static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
{
    return addr + pci_mem_base;
}

static void pci_unregister_io_regions(PCIDevice *pci_dev)
{
    PCIIORegion *r;
    int i;

    for(i = 0; i < PCI_NUM_REGIONS; i++) {
        r = &pci_dev->io_regions[i];
        if (!r->size || r->addr == -1)
            continue;
        if (r->type == PCI_ADDRESS_SPACE_IO) {
            isa_unassign_ioport(r->addr, r->size);
        } else {
            cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
                                                     r->size,
                                                     IO_MEM_UNASSIGNED);
        }
    }
}

433
static int pci_unregister_device(DeviceState *dev)
434
{
435
    PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
436
    PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->info);
437 438
    int ret = 0;

439 440
    if (info->exit)
        ret = info->exit(pci_dev);
441 442 443
    if (ret)
        return ret;

444
    msix_uninit(pci_dev);
445 446 447 448 449 450 451
    pci_unregister_io_regions(pci_dev);

    qemu_free_irqs(pci_dev->irq);
    pci_dev->bus->devices[pci_dev->devfn] = NULL;
    return 0;
}

452
void pci_register_bar(PCIDevice *pci_dev, int region_num,
453
                            uint32_t size, int type,
B
bellard 已提交
454 455 456
                            PCIMapIORegionFunc *map_func)
{
    PCIIORegion *r;
P
pbrook 已提交
457
    uint32_t addr;
458
    uint32_t wmask;
B
bellard 已提交
459

460
    if ((unsigned int)region_num >= PCI_NUM_REGIONS)
B
bellard 已提交
461
        return;
462 463 464 465 466 467 468

    if (size & (size-1)) {
        fprintf(stderr, "ERROR: PCI region size must be pow2 "
                    "type=0x%x, size=0x%x\n", type, size);
        exit(1);
    }

B
bellard 已提交
469 470 471 472 473
    r = &pci_dev->io_regions[region_num];
    r->addr = -1;
    r->size = size;
    r->type = type;
    r->map_func = map_func;
474 475

    wmask = ~(size - 1);
476
    addr = pci_bar(region_num);
P
pbrook 已提交
477
    if (region_num == PCI_ROM_SLOT) {
478
        /* ROM enable bit is writeable */
479
        wmask |= PCI_ROM_ADDRESS_ENABLE;
P
pbrook 已提交
480 481
    }
    *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
482
    *(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask);
483
    *(uint32_t *)(pci_dev->cmask + addr) = 0xffffffff;
B
bellard 已提交
484 485
}

486 487 488 489
static void pci_update_mappings(PCIDevice *d)
{
    PCIIORegion *r;
    int cmd, i;
490
    uint32_t last_addr, new_addr;
491

492
    cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
493
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
494 495 496 497
        r = &d->io_regions[i];
        if (r->size != 0) {
            if (r->type & PCI_ADDRESS_SPACE_IO) {
                if (cmd & PCI_COMMAND_IO) {
498
                    new_addr = pci_get_long(d->config + pci_bar(i));
499 500 501 502 503 504 505 506 507 508 509 510
                    new_addr = new_addr & ~(r->size - 1);
                    last_addr = new_addr + r->size - 1;
                    /* NOTE: we have only 64K ioports on PC */
                    if (last_addr <= new_addr || new_addr == 0 ||
                        last_addr >= 0x10000) {
                        new_addr = -1;
                    }
                } else {
                    new_addr = -1;
                }
            } else {
                if (cmd & PCI_COMMAND_MEMORY) {
511
                    new_addr = pci_get_long(d->config + pci_bar(i));
512
                    /* the ROM slot has a specific enable bit */
513
                    if (i == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE))
514
                        goto no_mem_map;
515 516 517 518 519 520 521 522 523 524 525
                    new_addr = new_addr & ~(r->size - 1);
                    last_addr = new_addr + r->size - 1;
                    /* NOTE: we do not support wrapping */
                    /* XXX: as we cannot support really dynamic
                       mappings, we handle specific values as invalid
                       mappings. */
                    if (last_addr <= new_addr || new_addr == 0 ||
                        last_addr == -1) {
                        new_addr = -1;
                    }
                } else {
526
                no_mem_map:
527 528 529 530 531 532 533 534 535 536
                    new_addr = -1;
                }
            }
            /* now do the real mapping */
            if (new_addr != r->addr) {
                if (r->addr != -1) {
                    if (r->type & PCI_ADDRESS_SPACE_IO) {
                        int class;
                        /* NOTE: specific hack for IDE in PC case:
                           only one byte must be mapped. */
537
                        class = pci_get_word(d->config + PCI_CLASS_DEVICE);
538 539 540 541 542 543
                        if (class == 0x0101 && r->size == 4) {
                            isa_unassign_ioport(r->addr + 2, 1);
                        } else {
                            isa_unassign_ioport(r->addr, r->size);
                        }
                    } else {
P
pbrook 已提交
544
                        cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
545
                                                     r->size,
546
                                                     IO_MEM_UNASSIGNED);
A
aliguori 已提交
547
                        qemu_unregister_coalesced_mmio(r->addr, r->size);
548 549 550 551 552 553 554 555 556 557 558
                    }
                }
                r->addr = new_addr;
                if (r->addr != -1) {
                    r->map_func(d, i, r->addr, r->size, r->type);
                }
            }
        }
    }
}

559
uint32_t pci_default_read_config(PCIDevice *d,
560
                                 uint32_t address, int len)
B
bellard 已提交
561
{
562
    uint32_t val;
563

564 565 566
    switch(len) {
    default:
    case 4:
567 568 569 570 571 572 573 574 575 576 577 578 579
	if (address <= 0xfc) {
	    val = le32_to_cpu(*(uint32_t *)(d->config + address));
	    break;
	}
	/* fall through */
    case 2:
        if (address <= 0xfe) {
	    val = le16_to_cpu(*(uint16_t *)(d->config + address));
	    break;
	}
	/* fall through */
    case 1:
        val = d->config[address];
580 581 582 583 584
        break;
    }
    return val;
}

585
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
586
{
587 588
    uint8_t orig[PCI_CONFIG_SPACE_SIZE];
    int i;
589 590

    /* not efficient, but simple */
591 592 593 594
    memcpy(orig, d->config, PCI_CONFIG_SPACE_SIZE);
    for(i = 0; i < l && addr < PCI_CONFIG_SPACE_SIZE; val >>= 8, ++i, ++addr) {
        uint8_t wmask = d->wmask[addr];
        d->config[addr] = (d->config[addr] & ~wmask) | (val & wmask);
595
    }
596 597 598
    if (memcmp(orig + PCI_BASE_ADDRESS_0, d->config + PCI_BASE_ADDRESS_0, 24)
        || ((orig[PCI_COMMAND] ^ d->config[PCI_COMMAND])
            & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)))
599
        pci_update_mappings(d);
B
bellard 已提交
600 601
}

P
pbrook 已提交
602
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
B
bellard 已提交
603
{
604 605 606
    PCIBus *s = opaque;
    PCIDevice *pci_dev;
    int config_addr, bus_num;
607

608 609 610
#if 0
    PCI_DPRINTF("pci_data_write: addr=%08x val=%08x len=%d\n",
                addr, val, len);
B
bellard 已提交
611
#endif
P
pbrook 已提交
612
    bus_num = (addr >> 16) & 0xff;
P
pbrook 已提交
613 614 615
    while (s && s->bus_num != bus_num)
        s = s->next;
    if (!s)
B
bellard 已提交
616
        return;
P
pbrook 已提交
617
    pci_dev = s->devices[(addr >> 8) & 0xff];
B
bellard 已提交
618 619
    if (!pci_dev)
        return;
P
pbrook 已提交
620
    config_addr = addr & 0xff;
621 622
    PCI_DPRINTF("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
                pci_dev->name, config_addr, val, len);
623
    pci_dev->config_write(pci_dev, config_addr, val, len);
B
bellard 已提交
624 625
}

P
pbrook 已提交
626
uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
B
bellard 已提交
627
{
628 629 630
    PCIBus *s = opaque;
    PCIDevice *pci_dev;
    int config_addr, bus_num;
B
bellard 已提交
631 632
    uint32_t val;

P
pbrook 已提交
633
    bus_num = (addr >> 16) & 0xff;
P
pbrook 已提交
634 635 636
    while (s && s->bus_num != bus_num)
        s= s->next;
    if (!s)
B
bellard 已提交
637
        goto fail;
P
pbrook 已提交
638
    pci_dev = s->devices[(addr >> 8) & 0xff];
B
bellard 已提交
639 640
    if (!pci_dev) {
    fail:
641 642 643 644 645 646 647 648 649 650 651 652
        switch(len) {
        case 1:
            val = 0xff;
            break;
        case 2:
            val = 0xffff;
            break;
        default:
        case 4:
            val = 0xffffffff;
            break;
        }
B
bellard 已提交
653 654
        goto the_end;
    }
P
pbrook 已提交
655
    config_addr = addr & 0xff;
B
bellard 已提交
656
    val = pci_dev->config_read(pci_dev, config_addr, len);
657 658
    PCI_DPRINTF("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
                pci_dev->name, config_addr, val, len);
B
bellard 已提交
659
 the_end:
660 661 662
#if 0
    PCI_DPRINTF("pci_data_read: addr=%08x val=%08x len=%d\n",
                addr, val, len);
B
bellard 已提交
663 664 665 666
#endif
    return val;
}

P
pbrook 已提交
667 668
/***********************************************************/
/* generic PCI irq support */
669

P
pbrook 已提交
670
/* 0 <= irq_num <= 3. level must be 0 or 1 */
P
pbrook 已提交
671
static void pci_set_irq(void *opaque, int irq_num, int level)
B
bellard 已提交
672
{
673
    PCIDevice *pci_dev = opaque;
P
pbrook 已提交
674 675
    PCIBus *bus;
    int change;
676

P
pbrook 已提交
677 678 679
    change = level - pci_dev->irq_state[irq_num];
    if (!change)
        return;
680 681

    pci_dev->irq_state[irq_num] = level;
P
pbrook 已提交
682 683
    for (;;) {
        bus = pci_dev->bus;
P
pbrook 已提交
684
        irq_num = bus->map_irq(pci_dev, irq_num);
P
pbrook 已提交
685 686
        if (bus->set_irq)
            break;
P
pbrook 已提交
687 688 689
        pci_dev = bus->parent_dev;
    }
    bus->irq_count[irq_num] += change;
690
    bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
B
bellard 已提交
691 692
}

P
pbrook 已提交
693 694
/***********************************************************/
/* monitor info on PCI */
695

696 697 698 699 700
typedef struct {
    uint16_t class;
    const char *desc;
} pci_class_desc;

701
static const pci_class_desc pci_class_descriptions[] =
702
{
P
pbrook 已提交
703
    { 0x0100, "SCSI controller"},
704
    { 0x0101, "IDE controller"},
T
ths 已提交
705 706 707 708 709 710
    { 0x0102, "Floppy controller"},
    { 0x0103, "IPI controller"},
    { 0x0104, "RAID controller"},
    { 0x0106, "SATA controller"},
    { 0x0107, "SAS controller"},
    { 0x0180, "Storage controller"},
711
    { 0x0200, "Ethernet controller"},
T
ths 已提交
712 713 714 715
    { 0x0201, "Token Ring controller"},
    { 0x0202, "FDDI controller"},
    { 0x0203, "ATM controller"},
    { 0x0280, "Network controller"},
716
    { 0x0300, "VGA controller"},
T
ths 已提交
717 718 719 720 721 722 723 724 725 726
    { 0x0301, "XGA controller"},
    { 0x0302, "3D controller"},
    { 0x0380, "Display controller"},
    { 0x0400, "Video controller"},
    { 0x0401, "Audio controller"},
    { 0x0402, "Phone"},
    { 0x0480, "Multimedia controller"},
    { 0x0500, "RAM controller"},
    { 0x0501, "Flash controller"},
    { 0x0580, "Memory controller"},
727 728
    { 0x0600, "Host bridge"},
    { 0x0601, "ISA bridge"},
T
ths 已提交
729 730
    { 0x0602, "EISA bridge"},
    { 0x0603, "MC bridge"},
731
    { 0x0604, "PCI bridge"},
T
ths 已提交
732 733 734 735 736
    { 0x0605, "PCMCIA bridge"},
    { 0x0606, "NUBUS bridge"},
    { 0x0607, "CARDBUS bridge"},
    { 0x0608, "RACEWAY bridge"},
    { 0x0680, "Bridge"},
737 738 739 740
    { 0x0c03, "USB controller"},
    { 0, NULL}
};

P
pbrook 已提交
741
static void pci_info_device(PCIDevice *d)
742
{
A
aliguori 已提交
743
    Monitor *mon = cur_mon;
P
pbrook 已提交
744 745
    int i, class;
    PCIIORegion *r;
746
    const pci_class_desc *desc;
747

A
aliguori 已提交
748 749
    monitor_printf(mon, "  Bus %2d, device %3d, function %d:\n",
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
P
pbrook 已提交
750
    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
A
aliguori 已提交
751
    monitor_printf(mon, "    ");
752 753 754 755
    desc = pci_class_descriptions;
    while (desc->desc && class != desc->class)
        desc++;
    if (desc->desc) {
A
aliguori 已提交
756
        monitor_printf(mon, "%s", desc->desc);
757
    } else {
A
aliguori 已提交
758
        monitor_printf(mon, "Class %04x", class);
759
    }
A
aliguori 已提交
760
    monitor_printf(mon, ": PCI device %04x:%04x\n",
P
pbrook 已提交
761 762
           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
763

P
pbrook 已提交
764
    if (d->config[PCI_INTERRUPT_PIN] != 0) {
A
aliguori 已提交
765 766
        monitor_printf(mon, "      IRQ %d.\n",
                       d->config[PCI_INTERRUPT_LINE]);
767
    }
P
pbrook 已提交
768
    if (class == 0x0604) {
A
aliguori 已提交
769
        monitor_printf(mon, "      BUS %d.\n", d->config[0x19]);
P
pbrook 已提交
770
    }
P
pbrook 已提交
771 772 773
    for(i = 0;i < PCI_NUM_REGIONS; i++) {
        r = &d->io_regions[i];
        if (r->size != 0) {
A
aliguori 已提交
774
            monitor_printf(mon, "      BAR%d: ", i);
P
pbrook 已提交
775
            if (r->type & PCI_ADDRESS_SPACE_IO) {
A
aliguori 已提交
776 777
                monitor_printf(mon, "I/O at 0x%04x [0x%04x].\n",
                               r->addr, r->addr + r->size - 1);
P
pbrook 已提交
778
            } else {
A
aliguori 已提交
779 780
                monitor_printf(mon, "32 bit memory at 0x%08x [0x%08x].\n",
                               r->addr, r->addr + r->size - 1);
P
pbrook 已提交
781 782
            }
        }
B
bellard 已提交
783
    }
784
    monitor_printf(mon, "      id \"%s\"\n", d->qdev.id ? d->qdev.id : "");
P
pbrook 已提交
785 786 787
    if (class == 0x0604 && d->config[0x19] != 0) {
        pci_for_each_device(d->config[0x19], pci_info_device);
    }
788 789
}

P
pbrook 已提交
790
void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
791
{
P
pbrook 已提交
792
    PCIBus *bus = first_bus;
793
    PCIDevice *d;
P
pbrook 已提交
794
    int devfn;
795

P
pbrook 已提交
796 797
    while (bus && bus->bus_num != bus_num)
        bus = bus->next;
P
pbrook 已提交
798 799 800 801 802 803
    if (bus) {
        for(devfn = 0; devfn < 256; devfn++) {
            d = bus->devices[devfn];
            if (d)
                fn(d);
        }
B
bellard 已提交
804 805 806
    }
}

A
aliguori 已提交
807
void pci_info(Monitor *mon)
B
bellard 已提交
808
{
P
pbrook 已提交
809
    pci_for_each_device(0, pci_info_device);
B
bellard 已提交
810
}
811

812 813 814 815 816 817 818 819 820 821 822 823
static const char * const pci_nic_models[] = {
    "ne2k_pci",
    "i82551",
    "i82557b",
    "i82559er",
    "rtl8139",
    "e1000",
    "pcnet",
    "virtio",
    NULL
};

P
Paul Brook 已提交
824 825 826 827 828 829 830 831
static const char * const pci_nic_names[] = {
    "ne2k_pci",
    "i82551",
    "i82557b",
    "i82559er",
    "rtl8139",
    "e1000",
    "pcnet",
P
Paul Brook 已提交
832
    "virtio-net-pci",
833 834 835
    NULL
};

836 837 838 839 840 841 842 843 844 845 846
int pci_nic_supported(const char *model)
{
    int i;

    for (i = 0; pci_nic_names[i]; i++)
        if (strcmp(model, pci_nic_names[i]) == 0)
            return 1;

    return 0;
}

847
/* Initialize a PCI NIC.  */
848 849
PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
                        const char *default_devaddr)
850
{
851
    const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
852 853
    PCIBus *bus;
    int devfn;
854
    PCIDevice *pci_dev;
P
Paul Brook 已提交
855
    DeviceState *dev;
856 857
    int i;

858 859 860 861 862 863 864 865 866 867 868
    i = qemu_find_nic_model(nd, pci_nic_models, default_model);
    if (i < 0)
        return NULL;

    bus = pci_get_bus_devfn(&devfn, devaddr);
    if (!bus) {
        qemu_error("Invalid PCI device address %s for device %s\n",
                   devaddr, pci_nic_names[i]);
        return NULL;
    }

869
    pci_dev = pci_create(bus, devfn, pci_nic_names[i]);
870 871 872 873
    dev = &pci_dev->qdev;
    if (nd->id)
        dev->id = qemu_strdup(nd->id);
    dev->nd = nd;
874 875
    if (qdev_init(dev) < 0)
        return NULL;
876 877
    nd->private = dev;
    return pci_dev;
878 879
}

880 881 882 883 884 885 886 887 888 889 890 891 892 893
PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,
                               const char *default_devaddr)
{
    PCIDevice *res;

    if (qemu_show_nic_models(nd->model, pci_nic_models))
        exit(0);

    res = pci_nic_init(nd, default_model, default_devaddr);
    if (!res)
        exit(1);
    return res;
}

P
pbrook 已提交
894 895
typedef struct {
    PCIDevice dev;
G
Gerd Hoffmann 已提交
896 897 898
    PCIBus bus;
    uint32_t vid;
    uint32_t did;
P
pbrook 已提交
899 900
} PCIBridge;

901
static void pci_bridge_write_config(PCIDevice *d,
P
pbrook 已提交
902 903 904 905 906
                             uint32_t address, uint32_t val, int len)
{
    PCIBridge *s = (PCIBridge *)d;

    pci_default_write_config(d, address, val, len);
G
Gerd Hoffmann 已提交
907
    s->bus.bus_num = d->config[PCI_SECONDARY_BUS];
P
pbrook 已提交
908 909
}

910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
PCIBus *pci_find_bus(int bus_num)
{
    PCIBus *bus = first_bus;

    while (bus && bus->bus_num != bus_num)
        bus = bus->next;

    return bus;
}

PCIDevice *pci_find_device(int bus_num, int slot, int function)
{
    PCIBus *bus = pci_find_bus(bus_num);

    if (!bus)
        return NULL;

    return bus->devices[PCI_DEVFN(slot, function)];
}

G
Gerd Hoffmann 已提交
930
static int pci_bridge_initfn(PCIDevice *dev)
P
pbrook 已提交
931
{
G
Gerd Hoffmann 已提交
932
    PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
B
blueswir1 已提交
933

G
Gerd Hoffmann 已提交
934 935
    pci_config_set_vendor_id(s->dev.config, s->vid);
    pci_config_set_device_id(s->dev.config, s->did);
B
blueswir1 已提交
936

P
pbrook 已提交
937 938 939 940 941 942
    s->dev.config[0x04] = 0x06; // command = bus master, pci mem
    s->dev.config[0x05] = 0x00;
    s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
    s->dev.config[0x07] = 0x00; // status = fast devsel
    s->dev.config[0x08] = 0x00; // revision
    s->dev.config[0x09] = 0x00; // programming i/f
943
    pci_config_set_class(s->dev.config, PCI_CLASS_BRIDGE_PCI);
P
pbrook 已提交
944
    s->dev.config[0x0D] = 0x10; // latency_timer
I
Isaku Yamahata 已提交
945 946
    s->dev.config[PCI_HEADER_TYPE] =
        PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
P
pbrook 已提交
947
    s->dev.config[0x1E] = 0xa0; // secondary status
G
Gerd Hoffmann 已提交
948 949
    return 0;
}
P
pbrook 已提交
950

G
Gerd Hoffmann 已提交
951 952 953 954 955 956
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
                        pci_map_irq_fn map_irq, const char *name)
{
    PCIDevice *dev;
    PCIBridge *s;

957
    dev = pci_create(bus, devfn, "pci-bridge");
G
Gerd Hoffmann 已提交
958 959 960 961 962 963 964
    qdev_prop_set_uint32(&dev->qdev, "vendorid", vid);
    qdev_prop_set_uint32(&dev->qdev, "deviceid", did);
    qdev_init(&dev->qdev);

    s = DO_UPCAST(PCIBridge, dev, dev);
    pci_register_secondary_bus(&s->bus, &s->dev, map_irq, name);
    return &s->bus;
P
pbrook 已提交
965
}
P
Paul Brook 已提交
966

967
static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
P
Paul Brook 已提交
968 969
{
    PCIDevice *pci_dev = (PCIDevice *)qdev;
P
Paul Brook 已提交
970
    PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
P
Paul Brook 已提交
971
    PCIBus *bus;
G
Gerd Hoffmann 已提交
972
    int devfn, rc;
P
Paul Brook 已提交
973

P
Paul Brook 已提交
974
    bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
G
Gerd Hoffmann 已提交
975
    devfn = pci_dev->devfn;
G
Gerd Hoffmann 已提交
976
    pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
977
                                     info->config_read, info->config_write);
P
Paul Brook 已提交
978
    assert(pci_dev);
G
Gerd Hoffmann 已提交
979 980 981 982 983 984 985 986 987 988 989 990 991 992
    rc = info->init(pci_dev);
    if (rc != 0)
        return rc;
    if (qdev->hotplugged)
        bus->hotplug(pci_dev, 1);
    return 0;
}

static int pci_unplug_device(DeviceState *qdev)
{
    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);

    dev->bus->hotplug(dev, 0);
    return 0;
P
Paul Brook 已提交
993 994
}

995
void pci_qdev_register(PCIDeviceInfo *info)
P
Paul Brook 已提交
996
{
P
Paul Brook 已提交
997
    info->qdev.init = pci_qdev_init;
G
Gerd Hoffmann 已提交
998
    info->qdev.unplug = pci_unplug_device;
999
    info->qdev.exit = pci_unregister_device;
1000
    info->qdev.bus_info = &pci_bus_info;
1001
    qdev_register(&info->qdev);
P
Paul Brook 已提交
1002 1003
}

1004 1005 1006 1007 1008 1009 1010 1011
void pci_qdev_register_many(PCIDeviceInfo *info)
{
    while (info->qdev.name) {
        pci_qdev_register(info);
        info++;
    }
}

1012
PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name)
P
Paul Brook 已提交
1013 1014 1015
{
    DeviceState *dev;

P
Paul Brook 已提交
1016
    dev = qdev_create(&bus->qbus, name);
1017
    qdev_prop_set_uint32(dev, "addr", devfn);
1018 1019
    return DO_UPCAST(PCIDevice, qdev, dev);
}
P
Paul Brook 已提交
1020

1021 1022
PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
{
1023
    PCIDevice *dev = pci_create(bus, devfn, name);
1024 1025
    qdev_init(&dev->qdev);
    return dev;
P
Paul Brook 已提交
1026
}
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071

static int pci_find_space(PCIDevice *pdev, uint8_t size)
{
    int offset = PCI_CONFIG_HEADER_SIZE;
    int i;
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
        if (pdev->used[i])
            offset = i + 1;
        else if (i - offset + 1 == size)
            return offset;
    return 0;
}

static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
                                        uint8_t *prev_p)
{
    uint8_t next, prev;

    if (!(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST))
        return 0;

    for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
         prev = next + PCI_CAP_LIST_NEXT)
        if (pdev->config[next + PCI_CAP_LIST_ID] == cap_id)
            break;

    if (prev_p)
        *prev_p = prev;
    return next;
}

/* Reserve space and add capability to the linked list in pci config space */
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
{
    uint8_t offset = pci_find_space(pdev, size);
    uint8_t *config = pdev->config + offset;
    if (!offset)
        return -ENOSPC;
    config[PCI_CAP_LIST_ID] = cap_id;
    config[PCI_CAP_LIST_NEXT] = pdev->config[PCI_CAPABILITY_LIST];
    pdev->config[PCI_CAPABILITY_LIST] = offset;
    pdev->config[PCI_STATUS] |= PCI_STATUS_CAP_LIST;
    memset(pdev->used + offset, 0xFF, size);
    /* Make capability read-only by default */
    memset(pdev->wmask + offset, 0, size);
1072 1073
    /* Check capability by default */
    memset(pdev->cmask + offset, 0xFF, size);
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
    return offset;
}

/* Unlink capability from the pci config space. */
void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
{
    uint8_t prev, offset = pci_find_capability_list(pdev, cap_id, &prev);
    if (!offset)
        return;
    pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];
    /* Make capability writeable again */
    memset(pdev->wmask + offset, 0xff, size);
1086 1087
    /* Clear cmask as device-specific registers can't be checked */
    memset(pdev->cmask + offset, 0, size);
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
    memset(pdev->used + offset, 0, size);

    if (!pdev->config[PCI_CAPABILITY_LIST])
        pdev->config[PCI_STATUS] &= ~PCI_STATUS_CAP_LIST;
}

/* Reserve space for capability at a known offset (to call after load). */
void pci_reserve_capability(PCIDevice *pdev, uint8_t offset, uint8_t size)
{
    memset(pdev->used + offset, 0xff, size);
}

uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id)
{
    return pci_find_capability_list(pdev, cap_id, NULL);
}
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139

static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
{
    PCIDevice *d = (PCIDevice *)dev;
    const pci_class_desc *desc;
    char ctxt[64];
    PCIIORegion *r;
    int i, class;

    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
    desc = pci_class_descriptions;
    while (desc->desc && class != desc->class)
        desc++;
    if (desc->desc) {
        snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
    } else {
        snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
    }

    monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
                   "pci id %04x:%04x (sub %04x:%04x)\n",
                   indent, "", ctxt,
                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7,
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))),
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_VENDOR_ID))),
                   le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_ID))));
    for (i = 0; i < PCI_NUM_REGIONS; i++) {
        r = &d->io_regions[i];
        if (!r->size)
            continue;
        monitor_printf(mon, "%*sbar %d: %s at 0x%x [0x%x]\n", indent, "",
                       i, r->type & PCI_ADDRESS_SPACE_IO ? "i/o" : "mem",
                       r->addr, r->addr + r->size - 1);
    }
}
G
Gerd Hoffmann 已提交
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158

static PCIDeviceInfo bridge_info = {
    .qdev.name    = "pci-bridge",
    .qdev.size    = sizeof(PCIBridge),
    .init         = pci_bridge_initfn,
    .config_write = pci_bridge_write_config,
    .qdev.props   = (Property[]) {
        DEFINE_PROP_HEX32("vendorid", PCIBridge, vid, 0),
        DEFINE_PROP_HEX32("deviceid", PCIBridge, did, 0),
        DEFINE_PROP_END_OF_LIST(),
    }
};

static void pci_register_devices(void)
{
    pci_qdev_register(&bridge_info);
}

device_init(pci_register_devices)