Revision cb06608e hw/ivshmem.c

b/hw/ivshmem.c
56 56

  
57 57
    CharDriverState **eventfd_chr;
58 58
    CharDriverState *server_chr;
59
    int ivshmem_mmio_io_addr;
59
    MemoryRegion ivshmem_mmio;
60 60

  
61 61
    pcibus_t mmio_addr;
62
    pcibus_t shm_pci_addr;
63
    uint64_t ivshmem_offset;
62
    /* We might need to register the BAR before we actually have the memory.
63
     * So prepare a container MemoryRegion for the BAR immediately and
64
     * add a subregion when we have the memory.
65
     */
66
    MemoryRegion bar;
67
    MemoryRegion ivshmem;
64 68
    uint64_t ivshmem_size; /* size of shared memory region */
65 69
    int shm_fd; /* shared memory file descriptor */
66 70

  
......
96 100
    return (x & (x - 1)) == 0;
97 101
}
98 102

  
99
static void ivshmem_map(PCIDevice *pci_dev, int region_num,
100
                    pcibus_t addr, pcibus_t size, int type)
101
{
102
    IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev);
103

  
104
    s->shm_pci_addr = addr;
105

  
106
    if (s->ivshmem_offset > 0) {
107
        cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size,
108
                                                            s->ivshmem_offset);
109
    }
110

  
111
    IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %"
112
        PRIu64 ", size = %" FMT_PCIBUS "\n", addr, s->ivshmem_offset, size);
113

  
114
}
115

  
116 103
/* accessing registers - based on rtl8139 */
117 104
static void ivshmem_update_irq(IVShmemState *s, int val)
118 105
{
......
168 155
    return ret;
169 156
}
170 157

  
171
static void ivshmem_io_writew(void *opaque, target_phys_addr_t addr,
172
                                                            uint32_t val)
173
{
174

  
175
    IVSHMEM_DPRINTF("We shouldn't be writing words\n");
176
}
177

  
178
static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr,
179
                                                            uint32_t val)
158
static void ivshmem_io_write(void *opaque, target_phys_addr_t addr,
159
                             uint64_t val, unsigned size)
180 160
{
181 161
    IVShmemState *s = opaque;
182 162

  
......
219 199
    }
220 200
}
221 201

  
222
static void ivshmem_io_writeb(void *opaque, target_phys_addr_t addr,
223
                                                                uint32_t val)
224
{
225
    IVSHMEM_DPRINTF("We shouldn't be writing bytes\n");
226
}
227

  
228
static uint32_t ivshmem_io_readw(void *opaque, target_phys_addr_t addr)
229
{
230

  
231
    IVSHMEM_DPRINTF("We shouldn't be reading words\n");
232
    return 0;
233
}
234

  
235
static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr)
202
static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr,
203
                                unsigned size)
236 204
{
237 205

  
238 206
    IVShmemState *s = opaque;
......
265 233
    return ret;
266 234
}
267 235

  
268
static uint32_t ivshmem_io_readb(void *opaque, target_phys_addr_t addr)
269
{
270
    IVSHMEM_DPRINTF("We shouldn't be reading bytes\n");
271

  
272
    return 0;
273
}
274

  
275
static CPUReadMemoryFunc * const ivshmem_mmio_read[3] = {
276
    ivshmem_io_readb,
277
    ivshmem_io_readw,
278
    ivshmem_io_readl,
279
};
280

  
281
static CPUWriteMemoryFunc * const ivshmem_mmio_write[3] = {
282
    ivshmem_io_writeb,
283
    ivshmem_io_writew,
284
    ivshmem_io_writel,
236
static const MemoryRegionOps ivshmem_mmio_ops = {
237
    .read = ivshmem_io_read,
238
    .write = ivshmem_io_write,
239
    .endianness = DEVICE_NATIVE_ENDIAN,
240
    .impl = {
241
        .min_access_size = 4,
242
        .max_access_size = 4,
243
    },
285 244
};
286 245

  
287 246
static void ivshmem_receive(void *opaque, const uint8_t *buf, int size)
......
371 330

  
372 331
    ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
373 332

  
374
    s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, "ivshmem.bar2",
375
                                                        s->ivshmem_size, ptr);
333
    memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, "ivshmem.bar2",
334
                               s->ivshmem_size, ptr);
335
    memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
376 336

  
377 337
    /* region for shared memory */
378
    pci_register_bar(&s->dev, 2, s->ivshmem_size,
379
                                PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
338
    pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
380 339
}
381 340

  
382 341
static void close_guest_eventfds(IVShmemState *s, int posn)
......
401 360

  
402 361
    for (i = 0; i <= s->max_peer; i++) {
403 362
        for (j = 0; j < s->peers[i].nb_eventfds; j++) {
404
            kvm_set_ioeventfd_mmio_long(s->peers[i].eventfds[j],
405
                    s->mmio_addr + DOORBELL, (i << 16) | j, 1);
363
            memory_region_add_eventfd(&s->ivshmem_mmio,
364
                                      DOORBELL,
365
                                      4,
366
                                      true,
367
                                      (i << 16) | j,
368
                                      s->peers[i].eventfds[j]);
406 369
        }
407 370
    }
408 371
}
......
483 446
        /* mmap the region and map into the BAR2 */
484 447
        map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED,
485 448
                                                            incoming_fd, 0);
486
        s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev,
487
                                    "ivshmem.bar2", s->ivshmem_size, map_ptr);
449
        memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev,
450
                                   "ivshmem.bar2", s->ivshmem_size, map_ptr);
488 451

  
489
        IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %"
490
                         PRIu64 ", size = %" PRIu64 "\n", s->shm_pci_addr,
452
        IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n",
491 453
                         s->ivshmem_offset, s->ivshmem_size);
492 454

  
493
        if (s->shm_pci_addr > 0) {
494
            /* map memory into BAR2 */
495
            cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size,
496
                                                            s->ivshmem_offset);
497
        }
455
        memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
498 456

  
499 457
        /* only store the fd if it is successfully mapped */
500 458
        s->shm_fd = incoming_fd;
......
549 507
    return;
550 508
}
551 509

  
552
static void ivshmem_mmio_map(PCIDevice *pci_dev, int region_num,
553
                       pcibus_t addr, pcibus_t size, int type)
554
{
555
    IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev);
556

  
557
    s->mmio_addr = addr;
558
    cpu_register_physical_memory(addr + 0, IVSHMEM_REG_BAR_SIZE,
559
                                                s->ivshmem_mmio_io_addr);
560

  
561
    if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
562
        setup_ioeventfds(s);
563
    }
564
}
565

  
566 510
static uint64_t ivshmem_get_size(IVShmemState * s) {
567 511

  
568 512
    uint64_t value;
......
710 654

  
711 655
    pci_config_set_interrupt_pin(pci_conf, 1);
712 656

  
713
    s->shm_pci_addr = 0;
714
    s->ivshmem_offset = 0;
715 657
    s->shm_fd = 0;
716 658

  
717
    s->ivshmem_mmio_io_addr = cpu_register_io_memory(ivshmem_mmio_read,
718
                                    ivshmem_mmio_write, s, DEVICE_NATIVE_ENDIAN);
659
    memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s,
660
                          "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE);
661

  
662
    if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
663
        setup_ioeventfds(s);
664
    }
665

  
719 666
    /* region for registers*/
720
    pci_register_bar(&s->dev, 0, IVSHMEM_REG_BAR_SIZE,
721
                           PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_mmio_map);
667
    pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
668
                            &s->ivshmem_mmio);
669

  
670
    memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size);
722 671

  
723 672
    if ((s->server_chr != NULL) &&
724 673
                        (strncmp(s->server_chr->filename, "unix:", 5) == 0)) {
......
744 693
        /* allocate/initialize space for interrupt handling */
745 694
        s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer));
746 695

  
747
        pci_register_bar(&s->dev, 2, s->ivshmem_size,
748
                                PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
696
        pci_register_bar_region(&s->dev, 2,
697
                                PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem);
749 698

  
750 699
        s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *));
751 700

  
......
792 741
{
793 742
    IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
794 743

  
795
    cpu_unregister_io_memory(s->ivshmem_mmio_io_addr);
744
    memory_region_destroy(&s->ivshmem_mmio);
745
    memory_region_del_subregion(&s->bar, &s->ivshmem);
746
    memory_region_destroy(&s->ivshmem);
747
    memory_region_destroy(&s->bar);
796 748
    unregister_savevm(&dev->qdev, "ivshmem", s);
797 749

  
798 750
    return 0;

Also available in: Unified diff