Revision a9f49946 hw/pci.c

b/hw/pci.c
23 23
 */
24 24
#include "hw.h"
25 25
#include "pci.h"
26
#include "pci_host.h"
26 27
#include "monitor.h"
27 28
#include "net.h"
28 29
#include "sysemu.h"
......
248 249
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
249 250
{
250 251
    PCIDevice *s = container_of(pv, PCIDevice, config);
251
    uint8_t config[PCI_CONFIG_SPACE_SIZE];
252
    uint8_t *config;
252 253
    int i;
253 254

  
254
    assert(size == sizeof config);
255
    qemu_get_buffer(f, config, sizeof config);
256
    for (i = 0; i < sizeof config; ++i)
257
        if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i])
255
    assert(size == pci_config_size(s));
256
    config = qemu_malloc(size);
257

  
258
    qemu_get_buffer(f, config, size);
259
    for (i = 0; i < size; ++i) {
260
        if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i]) {
261
            qemu_free(config);
258 262
            return -EINVAL;
259
    memcpy(s->config, config, sizeof config);
263
        }
264
    }
265
    memcpy(s->config, config, size);
260 266

  
261 267
    pci_update_mappings(s);
262 268

  
269
    qemu_free(config);
263 270
    return 0;
264 271
}
265 272

  
......
267 274
static void put_pci_config_device(QEMUFile *f, void *pv, size_t size)
268 275
{
269 276
    const uint8_t *v = pv;
277
    assert(size == pci_config_size(container_of(pv, PCIDevice, config)));
270 278
    qemu_put_buffer(f, v, size);
271 279
}
272 280

  
......
283 291
    .minimum_version_id_old = 1,
284 292
    .fields      = (VMStateField []) {
285 293
        VMSTATE_INT32_LE(version_id, PCIDevice),
286
        VMSTATE_SINGLE(config, PCIDevice, 0, vmstate_info_pci_config,
287
                       typeof_field(PCIDevice,config)),
294
        VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
295
                                   vmstate_info_pci_config,
296
                                   PCI_CONFIG_SPACE_SIZE),
297
        VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, PCI_NUM_PINS, 2),
298
        VMSTATE_END_OF_LIST()
299
    }
300
};
301

  
302
const VMStateDescription vmstate_pcie_device = {
303
    .name = "PCIDevice",
304
    .version_id = 2,
305
    .minimum_version_id = 1,
306
    .minimum_version_id_old = 1,
307
    .fields      = (VMStateField []) {
308
        VMSTATE_INT32_LE(version_id, PCIDevice),
309
        VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
310
                                   vmstate_info_pci_config,
311
                                   PCIE_CONFIG_SPACE_SIZE),
288 312
        VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, PCI_NUM_PINS, 2),
289 313
        VMSTATE_END_OF_LIST()
290 314
    }
291 315
};
292 316

  
317
static inline const VMStateDescription *pci_get_vmstate(PCIDevice *s)
318
{
319
    return pci_is_express(s) ? &vmstate_pcie_device : &vmstate_pci_device;
320
}
321

  
293 322
void pci_device_save(PCIDevice *s, QEMUFile *f)
294 323
{
295
    vmstate_save_state(f, &vmstate_pci_device, s);
324
    vmstate_save_state(f, pci_get_vmstate(s), s);
296 325
}
297 326

  
298 327
int pci_device_load(PCIDevice *s, QEMUFile *f)
299 328
{
300
    return vmstate_load_state(f, &vmstate_pci_device, s, s->version_id);
329
    return vmstate_load_state(f, pci_get_vmstate(s), s, s->version_id);
301 330
}
302 331

  
303 332
static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
......
406 435
static void pci_init_wmask(PCIDevice *dev)
407 436
{
408 437
    int i;
438
    int config_size = pci_config_size(dev);
439

  
409 440
    dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
410 441
    dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
411 442
    pci_set_word(dev->wmask + PCI_COMMAND,
412 443
                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
413
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
444
    for (i = PCI_CONFIG_HEADER_SIZE; i < config_size; ++i)
414 445
        dev->wmask[i] = 0xff;
415 446
}
416 447

  
448
static void pci_config_alloc(PCIDevice *pci_dev)
449
{
450
    int config_size = pci_config_size(pci_dev);
451

  
452
    pci_dev->config = qemu_mallocz(config_size);
453
    pci_dev->cmask = qemu_mallocz(config_size);
454
    pci_dev->wmask = qemu_mallocz(config_size);
455
    pci_dev->used = qemu_mallocz(config_size);
456
}
457

  
458
static void pci_config_free(PCIDevice *pci_dev)
459
{
460
    qemu_free(pci_dev->config);
461
    qemu_free(pci_dev->cmask);
462
    qemu_free(pci_dev->wmask);
463
    qemu_free(pci_dev->used);
464
}
465

  
417 466
/* -1 for devfn means auto assign */
418 467
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
419 468
                                         const char *name, int devfn,
......
434 483
    pci_dev->devfn = devfn;
435 484
    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
436 485
    memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
486
    pci_config_alloc(pci_dev);
437 487
    pci_set_default_subsystem_id(pci_dev);
438 488
    pci_init_cmask(pci_dev);
439 489
    pci_init_wmask(pci_dev);
......
501 551

  
502 552
    qemu_free_irqs(pci_dev->irq);
503 553
    pci_dev->bus->devices[pci_dev->devfn] = NULL;
554
    pci_config_free(pci_dev);
504 555
    return 0;
505 556
}
506 557

  
......
641 692
{
642 693
    uint32_t val = 0;
643 694
    assert(len == 1 || len == 2 || len == 4);
644
    len = MIN(len, PCI_CONFIG_SPACE_SIZE - address);
695
    len = MIN(len, pci_config_size(d) - address);
645 696
    memcpy(&val, d->config + address, len);
646 697
    return le32_to_cpu(val);
647 698
}
......
650 701
{
651 702
    uint8_t orig[PCI_CONFIG_SPACE_SIZE];
652 703
    int i;
704
    uint32_t config_size = pci_config_size(d);
653 705

  
654 706
    /* not efficient, but simple */
655 707
    memcpy(orig, d->config, PCI_CONFIG_SPACE_SIZE);
656
    for(i = 0; i < l && addr < PCI_CONFIG_SPACE_SIZE; val >>= 8, ++i, ++addr) {
708
    for(i = 0; i < l && addr < config_size; val >>= 8, ++i, ++addr) {
657 709
        uint8_t wmask = d->wmask[addr];
658 710
        d->config[addr] = (d->config[addr] & ~wmask) | (val & wmask);
659 711
    }
......
1001 1053
    PCIBus *bus;
1002 1054
    int devfn, rc;
1003 1055

  
1056
    /* initialize cap_present for pci_is_express() and pci_config_size() */
1057
    if (info->is_express) {
1058
        pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
1059
    }
1060

  
1004 1061
    bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
1005 1062
    devfn = pci_dev->devfn;
1006 1063
    pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
......
1057 1114

  
1058 1115
static int pci_find_space(PCIDevice *pdev, uint8_t size)
1059 1116
{
1117
    int config_size = pci_config_size(pdev);
1060 1118
    int offset = PCI_CONFIG_HEADER_SIZE;
1061 1119
    int i;
1062
    for (i = PCI_CONFIG_HEADER_SIZE; i < PCI_CONFIG_SPACE_SIZE; ++i)
1120
    for (i = PCI_CONFIG_HEADER_SIZE; i < config_size; ++i)
1063 1121
        if (pdev->used[i])
1064 1122
            offset = i + 1;
1065 1123
        else if (i - offset + 1 == size)

Also available in: Unified diff