Commit df32fd1c authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

dma: eliminate DMAContext



The DMAContext is a simple pointer to an AddressSpace that is now always
already available.  Make everyone hold the address space directly,
and clean up the DMA API to use the AddressSpace directly.

Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 96478592
Loading
Loading
Loading
Loading
+7 −17
Original line number Diff line number Diff line
@@ -14,11 +14,9 @@

/* #define DEBUG_IOMMU */

int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len)
int dma_memory_set(AddressSpace *as, dma_addr_t addr, uint8_t c, dma_addr_t len)
{
    AddressSpace *as = dma->as;

    dma_barrier(dma, DMA_DIRECTION_FROM_DEVICE);
    dma_barrier(as, DMA_DIRECTION_FROM_DEVICE);

#define FILLBUF_SIZE 512
    uint8_t fillbuf[FILLBUF_SIZE];
@@ -36,13 +34,13 @@ int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len)
    return error;
}

void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, DMAContext *dma)
void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, AddressSpace *as)
{
    qsg->sg = g_malloc(alloc_hint * sizeof(ScatterGatherEntry));
    qsg->nsg = 0;
    qsg->nalloc = alloc_hint;
    qsg->size = 0;
    qsg->dma = dma;
    qsg->as = as;
}

void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len)
@@ -102,7 +100,7 @@ static void dma_bdrv_unmap(DMAAIOCB *dbs)
    int i;

    for (i = 0; i < dbs->iov.niov; ++i) {
        dma_memory_unmap(dbs->sg->dma, dbs->iov.iov[i].iov_base,
        dma_memory_unmap(dbs->sg->as, dbs->iov.iov[i].iov_base,
                         dbs->iov.iov[i].iov_len, dbs->dir,
                         dbs->iov.iov[i].iov_len);
    }
@@ -150,7 +148,7 @@ static void dma_bdrv_cb(void *opaque, int ret)
    while (dbs->sg_cur_index < dbs->sg->nsg) {
        cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte;
        cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte;
        mem = dma_memory_map(dbs->sg->dma, cur_addr, &cur_len, dbs->dir);
        mem = dma_memory_map(dbs->sg->as, cur_addr, &cur_len, dbs->dir);
        if (!mem)
            break;
        qemu_iovec_add(&dbs->iov, mem, cur_len);
@@ -247,7 +245,7 @@ static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg,
    while (len > 0) {
        ScatterGatherEntry entry = sg->sg[sg_cur_index++];
        int32_t xfer = MIN(len, entry.len);
        dma_memory_rw(sg->dma, entry.base, ptr, xfer, dir);
        dma_memory_rw(sg->as, entry.base, ptr, xfer, dir);
        ptr += xfer;
        len -= xfer;
        resid -= xfer;
@@ -271,11 +269,3 @@ void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
{
    bdrv_acct_start(bs, cookie, sg->size, type);
}

void dma_context_init(DMAContext *dma, AddressSpace *as)
{
#ifdef DEBUG_IOMMU
    fprintf(stderr, "dma_context_init(%p -> %p)\n", dma, as);
#endif
    dma->as = as;
}
+0 −3
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ static MemoryRegion *system_io;

AddressSpace address_space_io;
AddressSpace address_space_memory;
DMAContext dma_context_memory;

MemoryRegion io_mem_rom, io_mem_notdirty;
static MemoryRegion io_mem_unassigned;
@@ -1839,8 +1838,6 @@ static void memory_map_init(void)
    memory_listener_register(&core_memory_listener, &address_space_memory);
    memory_listener_register(&io_memory_listener, &address_space_io);
    memory_listener_register(&tcg_memory_listener, &address_space_memory);

    dma_context_init(&dma_context_memory, &address_space_memory);
}

MemoryRegion *get_system_memory(void)
+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, uint64_t prp1, uint64_t prp2,
        return NVME_INVALID_FIELD | NVME_DNR;
    }

    qemu_sglist_init(qsg, num_prps, pci_dma_context(&n->parent_obj));
    pci_dma_sglist_init(qsg, &n->parent_obj, num_prps);
    qemu_sglist_add(qsg, prp1, trans_len);
    len -= trans_len;
    if (len) {
+4 −4
Original line number Diff line number Diff line
@@ -1074,7 +1074,7 @@ static inline const PL330InsnDesc *pl330_fetch_insn(PL330Chan *ch)
    uint8_t opcode;
    int i;

    dma_memory_read(&dma_context_memory, ch->pc, &opcode, 1);
    dma_memory_read(&address_space_memory, ch->pc, &opcode, 1);
    for (i = 0; insn_desc[i].size; i++) {
        if ((opcode & insn_desc[i].opmask) == insn_desc[i].opcode) {
            return &insn_desc[i];
@@ -1088,7 +1088,7 @@ static inline void pl330_exec_insn(PL330Chan *ch, const PL330InsnDesc *insn)
    uint8_t buf[PL330_INSN_MAXSIZE];

    assert(insn->size <= PL330_INSN_MAXSIZE);
    dma_memory_read(&dma_context_memory, ch->pc, buf, insn->size);
    dma_memory_read(&address_space_memory, ch->pc, buf, insn->size);
    insn->exec(ch, buf[0], &buf[1], insn->size - 1);
}

@@ -1153,7 +1153,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
    if (q != NULL && q->len <= pl330_fifo_num_free(&s->fifo)) {
        int len = q->len - (q->addr & (q->len - 1));

        dma_memory_read(&dma_context_memory, q->addr, buf, len);
        dma_memory_read(&address_space_memory, q->addr, buf, len);
        if (PL330_ERR_DEBUG > 1) {
            DB_PRINT("PL330 read from memory @%08x (size = %08x):\n",
                      q->addr, len);
@@ -1185,7 +1185,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
            fifo_res = pl330_fifo_get(&s->fifo, buf, len, q->tag);
        }
        if (fifo_res == PL330_FIFO_OK || q->z) {
            dma_memory_write(&dma_context_memory, q->addr, buf, len);
            dma_memory_write(&address_space_memory, q->addr, buf, len);
            if (PL330_ERR_DEBUG > 1) {
                DB_PRINT("PL330 read from memory @%08x (size = %08x):\n",
                         q->addr, len);
+9 −9
Original line number Diff line number Diff line
@@ -597,7 +597,7 @@ static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis)
    if (!cmd_fis) {
        /* map cmd_fis */
        uint64_t tbl_addr = le64_to_cpu(ad->cur_cmd->tbl_addr);
        cmd_fis = dma_memory_map(ad->hba->dma, tbl_addr, &cmd_len,
        cmd_fis = dma_memory_map(ad->hba->as, tbl_addr, &cmd_len,
                                 DMA_DIRECTION_TO_DEVICE);
        cmd_mapped = 1;
    }
@@ -630,7 +630,7 @@ static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis)
    ahci_trigger_irq(ad->hba, ad, PORT_IRQ_D2H_REG_FIS);

    if (cmd_mapped) {
        dma_memory_unmap(ad->hba->dma, cmd_fis, cmd_len,
        dma_memory_unmap(ad->hba->as, cmd_fis, cmd_len,
                         DMA_DIRECTION_TO_DEVICE, cmd_len);
    }
}
@@ -657,7 +657,7 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
    }

    /* map PRDT */
    if (!(prdt = dma_memory_map(ad->hba->dma, prdt_addr, &prdt_len,
    if (!(prdt = dma_memory_map(ad->hba->as, prdt_addr, &prdt_len,
                                DMA_DIRECTION_TO_DEVICE))){
        DPRINTF(ad->port_no, "map failed\n");
        return -1;
@@ -691,7 +691,7 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
            goto out;
        }

        qemu_sglist_init(sglist, (sglist_alloc_hint - off_idx), ad->hba->dma);
        qemu_sglist_init(sglist, (sglist_alloc_hint - off_idx), ad->hba->as);
        qemu_sglist_add(sglist, le64_to_cpu(tbl[off_idx].addr + off_pos),
                        le32_to_cpu(tbl[off_idx].flags_size) + 1 - off_pos);

@@ -703,7 +703,7 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
    }

out:
    dma_memory_unmap(ad->hba->dma, prdt, prdt_len,
    dma_memory_unmap(ad->hba->as, prdt, prdt_len,
                     DMA_DIRECTION_TO_DEVICE, prdt_len);
    return r;
}
@@ -836,7 +836,7 @@ static int handle_cmd(AHCIState *s, int port, int slot)
    tbl_addr = le64_to_cpu(cmd->tbl_addr);

    cmd_len = 0x80;
    cmd_fis = dma_memory_map(s->dma, tbl_addr, &cmd_len,
    cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
                             DMA_DIRECTION_FROM_DEVICE);

    if (!cmd_fis) {
@@ -963,7 +963,7 @@ static int handle_cmd(AHCIState *s, int port, int slot)
    }

out:
    dma_memory_unmap(s->dma, cmd_fis, cmd_len, DMA_DIRECTION_FROM_DEVICE,
    dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_FROM_DEVICE,
                     cmd_len);

    if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
@@ -1145,12 +1145,12 @@ static const IDEDMAOps ahci_dma_ops = {
    .reset = ahci_dma_reset,
};

void ahci_init(AHCIState *s, DeviceState *qdev, DMAContext *dma, int ports)
void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
{
    qemu_irq *irqs;
    int i;

    s->dma = dma;
    s->as = as;
    s->ports = ports;
    s->dev = g_malloc0(sizeof(AHCIDevice) * ports);
    ahci_reg_init(s);
Loading