コード例 #1
0
ファイル: mem_helper.c プロジェクト: 32bitmicro/riscv-qemu
/* xor on array */
uint32_t HELPER(xc)(CPUS390XState *env, uint32_t l, uint64_t dest,
                    uint64_t src)
{
    int i;
    unsigned char x;
    uint32_t cc = 0;

    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
               __func__, l, dest, src);

    /* xor with itself is the same as memset(0) */
    if (src == dest) {
        fast_memset(env, dest, 0, l + 1);
        return 0;
    }

    for (i = 0; i <= l; i++) {
        x = cpu_ldub_data(env, dest + i) ^ cpu_ldub_data(env, src + i);
        if (x) {
            cc = 1;
        }
        cpu_stb_data(env, dest + i, x);
    }
    return cc;
}
コード例 #2
0
ファイル: mem_helper.c プロジェクト: 32bitmicro/riscv-qemu
static void fast_memmove(CPUS390XState *env, uint64_t dest, uint64_t src,
                         uint32_t l)
{
    int mmu_idx = cpu_mmu_index(env, false);

    while (l > 0) {
        void *src_p = tlb_vaddr_to_host(env, src, MMU_DATA_LOAD, mmu_idx);
        void *dest_p = tlb_vaddr_to_host(env, dest, MMU_DATA_STORE, mmu_idx);
        if (src_p && dest_p) {
            /* Access to both whole pages granted.  */
            int l_adj = adj_len_to_page(l, src);
            l_adj = adj_len_to_page(l_adj, dest);
            memmove(dest_p, src_p, l_adj);
            src += l_adj;
            dest += l_adj;
            l -= l_adj;
        } else {
            /* We failed to get access to one or both whole pages. The next
               read or write access will likely fill the QEMU TLB for the
               next iteration.  */
            cpu_stb_data(env, dest, cpu_ldub_data(env, src));
            src++;
            dest++;
            l--;
        }
    }
}
コード例 #3
0
ファイル: mem_helper.c プロジェクト: 32bitmicro/riscv-qemu
/* memmove */
void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
{
    int i = 0;

    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
               __func__, l, dest, src);

    /* mvc with source pointing to the byte after the destination is the
       same as memset with the first source byte */
    if (dest == (src + 1)) {
        fast_memset(env, dest, cpu_ldub_data(env, src), l + 1);
        return;
    }

    /* mvc and memmove do not behave the same when areas overlap! */
    if ((dest < src) || (src + l < dest)) {
        fast_memmove(env, dest, src, l + 1);
        return;
    }

    /* slow version with byte accesses which always work */
    for (i = 0; i <= l; i++) {
        cpu_stb_data(env, dest + i, cpu_ldub_data(env, src + i));
    }
}
コード例 #4
0
ファイル: mem_helper.c プロジェクト: kimi8187/dpdk-ovs
static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
                             uint64_t src)
{
    hwaddr dest_phys;
    hwaddr src_phys;
    hwaddr len = l;
    void *dest_p;
    void *src_p;
    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
    int flags;

    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
        cpu_stb_data(env, dest, 0);
        cpu_abort(env, "should never reach here");
    }
    dest_phys |= dest & ~TARGET_PAGE_MASK;

    if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
        cpu_ldub_data(env, src);
        cpu_abort(env, "should never reach here");
    }
    src_phys |= src & ~TARGET_PAGE_MASK;

    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
    src_p = cpu_physical_memory_map(src_phys, &len, 0);

    memmove(dest_p, src_p, len);

    cpu_physical_memory_unmap(dest_p, 1, len, len);
    cpu_physical_memory_unmap(src_p, 0, len, len);
}
コード例 #5
0
ファイル: mem_helper.c プロジェクト: kimi8187/dpdk-ovs
/* xor on array */
uint32_t HELPER(xc)(CPUS390XState *env, uint32_t l, uint64_t dest,
                    uint64_t src)
{
    int i;
    unsigned char x;
    uint32_t cc = 0;

    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
               __func__, l, dest, src);

#ifndef CONFIG_USER_ONLY
    /* xor with itself is the same as memset(0) */
    if ((l > 32) && (src == dest) &&
            (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK)) {
        mvc_fast_memset(env, l + 1, dest, 0);
        return 0;
    }
#else
    if (src == dest) {
        memset(g2h(dest), 0, l + 1);
        return 0;
    }
#endif

    for (i = 0; i <= l; i++) {
        x = cpu_ldub_data(env, dest + i) ^ cpu_ldub_data(env, src + i);
        if (x) {
            cc = 1;
        }
        cpu_stb_data(env, dest + i, x);
    }
    return cc;
}
コード例 #6
0
ファイル: misc_helper.c プロジェクト: frenchleaf/qemu
/* Store Clock Extended */
uint32_t HELPER(stcke)(CPUS390XState *env, uint64_t a1)
{
    cpu_stb_data(env, a1, 0);
    /* basically the same value as stck */
    cpu_stq_data(env, a1 + 1, clock_value(env) | env->cpu_num);
    /* more fine grained than stck */
    cpu_stq_data(env, a1 + 9, 0);
    /* XXX programmable fields */
    cpu_stw_data(env, a1 + 17, 0);

    return 0;
}
コード例 #7
0
ファイル: mem_helper.c プロジェクト: 32bitmicro/riscv-qemu
/* or on array */
uint32_t HELPER(oc)(CPUS390XState *env, uint32_t l, uint64_t dest,
                    uint64_t src)
{
    int i;
    unsigned char x;
    uint32_t cc = 0;

    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
               __func__, l, dest, src);
    for (i = 0; i <= l; i++) {
        x = cpu_ldub_data(env, dest + i) | cpu_ldub_data(env, src + i);
        if (x) {
            cc = 1;
        }
        cpu_stb_data(env, dest + i, x);
    }
    return cc;
}
コード例 #8
0
ファイル: mem_helper.c プロジェクト: kimi8187/dpdk-ovs
/* memmove */
void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
{
    int i = 0;
    int x = 0;
    uint32_t l_64 = (l + 1) / 8;

    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
               __func__, l, dest, src);

#ifndef CONFIG_USER_ONLY
    if ((l > 32) &&
            (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
            (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
        if (dest == (src + 1)) {
            mvc_fast_memset(env, l + 1, dest, cpu_ldub_data(env, src));
            return;
        } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
            mvc_fast_memmove(env, l + 1, dest, src);
            return;
        }
    }
#else
    if (dest == (src + 1)) {
        memset(g2h(dest), cpu_ldub_data(env, src), l + 1);
        return;
    } else {
        memmove(g2h(dest), g2h(src), l + 1);
        return;
    }
#endif

    /* handle the parts that fit into 8-byte loads/stores */
    if (dest != (src + 1)) {
        for (i = 0; i < l_64; i++) {
            cpu_stq_data(env, dest + x, cpu_ldq_data(env, src + x));
            x += 8;
        }
    }

    /* slow version crossing pages with byte accesses */
    for (i = x; i <= l; i++) {
        cpu_stb_data(env, dest + i, cpu_ldub_data(env, src + i));
    }
}
コード例 #9
0
ファイル: mem_helper.c プロジェクト: kimi8187/dpdk-ovs
static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
                            uint8_t byte)
{
    hwaddr dest_phys;
    hwaddr len = l;
    void *dest_p;
    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
    int flags;

    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
        cpu_stb_data(env, dest, byte);
        cpu_abort(env, "should never reach here");
    }
    dest_phys |= dest & ~TARGET_PAGE_MASK;

    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);

    memset(dest_p, byte, len);

    cpu_physical_memory_unmap(dest_p, 1, len, len);
}
コード例 #10
0
ファイル: mem_helper.c プロジェクト: 32bitmicro/riscv-qemu
static void fast_memset(CPUS390XState *env, uint64_t dest, uint8_t byte,
                        uint32_t l)
{
    int mmu_idx = cpu_mmu_index(env, false);

    while (l > 0) {
        void *p = tlb_vaddr_to_host(env, dest, MMU_DATA_STORE, mmu_idx);
        if (p) {
            /* Access to the whole page in write mode granted.  */
            int l_adj = adj_len_to_page(l, dest);
            memset(p, byte, l_adj);
            dest += l_adj;
            l -= l_adj;
        } else {
            /* We failed to get access to the whole page. The next write
               access will likely fill the QEMU TLB for the next iteration.  */
            cpu_stb_data(env, dest, byte);
            dest++;
            l--;
        }
    }
}