コード例 #1
0
ファイル: fw_cfg.c プロジェクト: MaddTheSane/qemu
static void fw_cfg_dma_transfer(FWCfgState *s)
{
    dma_addr_t len;
    FWCfgDmaAccess dma;
    int arch;
    FWCfgEntry *e;
    int read = 0, write = 0;
    dma_addr_t dma_addr;

    /* Reset the address before the next access */
    dma_addr = s->dma_addr;
    s->dma_addr = 0;

    if (dma_memory_read(s->dma_as, dma_addr, &dma, sizeof(dma))) {
        stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control),
                   FW_CFG_DMA_CTL_ERROR);
        return;
    }

    dma.address = be64_to_cpu(dma.address);
    dma.length = be32_to_cpu(dma.length);
    dma.control = be32_to_cpu(dma.control);

    if (dma.control & FW_CFG_DMA_CTL_SELECT) {
        fw_cfg_select(s, dma.control >> 16);
    }
コード例 #2
0
ファイル: ftgmac100.c プロジェクト: openbmc/qemu
static void ftgmac100_read_bd(Ftgmac100Desc *bd, dma_addr_t addr)
{
    dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd));
    bd->des0 = le32_to_cpu(bd->des0);
    bd->des1 = le32_to_cpu(bd->des1);
    bd->des2 = le32_to_cpu(bd->des2);
    bd->des3 = le32_to_cpu(bd->des3);
}
コード例 #3
0
ファイル: ftgmac100.c プロジェクト: openbmc/qemu
static void ftgmac100_do_tx(Ftgmac100State *s)
{
    int frame_size = 0;
    uint8_t frame[FTGMAC100_MAX_FRAME_SIZE(s)];
    uint8_t *ptr = frame;
    uint32_t addr;

    addr = ftgmac100_find_txdes(s, s->tx_descriptor);

    while (1) {
        Ftgmac100Desc bd;
        int len;

        ftgmac100_read_bd(&bd, addr);
        if ((bd.des0 & FTGMAC100_TXDES0_TXDMA_OWN) == 0) {
            /* Run out of descriptors to transmit.  */
            s->isr |= FTGMAC100_INT_NO_NPTXBUF;
            break;
        }
        len = bd.des0 & 0x3FFF;
        if (frame_size + len > FTGMAC100_MAX_FRAME_SIZE(s)) {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: frame too big : %d bytes\n",
                          __func__, len);
            len = FTGMAC100_MAX_FRAME_SIZE(s) - frame_size;
        }
        dma_memory_read(&address_space_memory, bd.des3, ptr, len);
        ptr += len;
        frame_size += len;
        if (bd.des0 & FTGMAC100_TXDES0_LTS) {
            /* Last buffer in frame.  */
            qemu_send_packet(qemu_get_queue(s->nic), frame, len);
            ptr = frame;
            frame_size = 0;
            if (bd.des1 & FTGMAC100_TXDES1_TXIC) {
                s->isr |= FTGMAC100_INT_XPKT_ETH;
            }
        }

        if (bd.des1 & FTGMAC100_TXDES1_TX2FIC) {
            s->isr |= FTGMAC100_INT_XPKT_FIFO;
        }
        bd.des0 &= ~FTGMAC100_TXDES0_TXDMA_OWN;

        /* Write back the modified descriptor.  */
        ftgmac100_write_bd(&bd, addr);
        /* Advance to the next descriptor.  */
        if (bd.des0 & ftgmac100_txdes0_edotr(s)) {
            addr = s->tx_ring;
        } else {
            addr += sizeof(Ftgmac100Desc);
        }
    }

    s->tx_descriptor = addr;

    ftgmac100_update_irq(s);
}
コード例 #4
0
ファイル: smmuv3.c プロジェクト: mcayland/qemu
/**
 * smmu_find_ste - Return the stream table entry associated
 * to the sid
 *
 * @s: smmuv3 handle
 * @sid: stream ID
 * @ste: returned stream table entry
 * @event: handle to an event info
 *
 * Supports linear and 2-level stream table
 * Return 0 on success, -EINVAL otherwise
 */
static int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste,
                         SMMUEventInfo *event)
{
    dma_addr_t addr;
    int ret;

    trace_smmuv3_find_ste(sid, s->features, s->sid_split);
    /* Check SID range */
    if (sid > (1 << SMMU_IDR1_SIDSIZE)) {
        event->type = SMMU_EVT_C_BAD_STREAMID;
        return -EINVAL;
    }
    if (s->features & SMMU_FEATURE_2LVL_STE) {
        int l1_ste_offset, l2_ste_offset, max_l2_ste, span;
        dma_addr_t strtab_base, l1ptr, l2ptr;
        STEDesc l1std;

        strtab_base = s->strtab_base & SMMU_BASE_ADDR_MASK;
        l1_ste_offset = sid >> s->sid_split;
        l2_ste_offset = sid & ((1 << s->sid_split) - 1);
        l1ptr = (dma_addr_t)(strtab_base + l1_ste_offset * sizeof(l1std));
        /* TODO: guarantee 64-bit single-copy atomicity */
        ret = dma_memory_read(&address_space_memory, l1ptr,
                              (uint8_t *)&l1std, sizeof(l1std));
        if (ret != MEMTX_OK) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "Could not read L1PTR at 0X%"PRIx64"\n", l1ptr);
            event->type = SMMU_EVT_F_STE_FETCH;
            event->u.f_ste_fetch.addr = l1ptr;
            return -EINVAL;
        }

        span = L1STD_SPAN(&l1std);

        if (!span) {
            /* l2ptr is not valid */
            qemu_log_mask(LOG_GUEST_ERROR,
                          "invalid sid=%d (L1STD span=0)\n", sid);
            event->type = SMMU_EVT_C_BAD_STREAMID;
            return -EINVAL;
        }
        max_l2_ste = (1 << span) - 1;
        l2ptr = l1std_l2ptr(&l1std);
        trace_smmuv3_find_ste_2lvl(s->strtab_base, l1ptr, l1_ste_offset,
                                   l2ptr, l2_ste_offset, max_l2_ste);
        if (l2_ste_offset > max_l2_ste) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "l2_ste_offset=%d > max_l2_ste=%d\n",
                          l2_ste_offset, max_l2_ste);
            event->type = SMMU_EVT_C_BAD_STE;
            return -EINVAL;
        }
        addr = l2ptr + l2_ste_offset * sizeof(*ste);
    } else {
コード例 #5
0
ファイル: smmuv3.c プロジェクト: mcayland/qemu
/* @ssid > 0 not supported yet */
static int smmu_get_cd(SMMUv3State *s, STE *ste, uint32_t ssid,
                       CD *buf, SMMUEventInfo *event)
{
    dma_addr_t addr = STE_CTXPTR(ste);
    int ret;

    trace_smmuv3_get_cd(addr);
    /* TODO: guarantee 64-bit single-copy atomicity */
    ret = dma_memory_read(&address_space_memory, addr,
                           (void *)buf, sizeof(*buf));
    if (ret != MEMTX_OK) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "Cannot fetch pte at address=0x%"PRIx64"\n", addr);
        event->type = SMMU_EVT_F_CD_FETCH;
        event->u.f_ste_fetch.addr = addr;
        return -EINVAL;
    }
    return 0;
}
コード例 #6
0
ファイル: smmuv3.c プロジェクト: mcayland/qemu
static inline MemTxResult queue_read(SMMUQueue *q, void *data)
{
    dma_addr_t addr = Q_CONS_ENTRY(q);

    return dma_memory_read(&address_space_memory, addr, data, q->entry_size);
}