/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Access guest memory in blocks. */

#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/cpu_ldst.h"
#include "exec/exec-all.h"
#include "access.h"


void access_prepare_mmu(X86Access *ret, CPUX86State *env,
                        vaddr vaddr, unsigned size,
                        MMUAccessType type, int mmu_idx, uintptr_t ra)
{
    int size1, size2;
    void *haddr1, *haddr2;

    assert(size > 0 && size <= TARGET_PAGE_SIZE);

    size1 = MIN(size, -(vaddr | TARGET_PAGE_MASK)),
    size2 = size - size1;

    memset(ret, 0, sizeof(*ret));
    ret->vaddr = vaddr;
    ret->size = size;
    ret->size1 = size1;
    ret->mmu_idx = mmu_idx;
    ret->env = env;
    ret->ra = ra;

    haddr1 = probe_access(env, vaddr, size1, type, mmu_idx, ra);
    ret->haddr1 = haddr1;

    if (unlikely(size2)) {
        haddr2 = probe_access(env, vaddr + size1, size2, type, mmu_idx, ra);
        if (haddr2 == haddr1 + size1) {
            ret->size1 = size;
        } else {
#ifdef CONFIG_USER_ONLY
            g_assert_not_reached();
#else
            ret->haddr2 = haddr2;
#endif
        }
    }
}

void access_prepare(X86Access *ret, CPUX86State *env, vaddr vaddr,
                    unsigned size, MMUAccessType type, uintptr_t ra)
{
    int mmu_idx = cpu_mmu_index(env_cpu(env), false);
    access_prepare_mmu(ret, env, vaddr, size, type, mmu_idx, ra);
}

static void *access_ptr(X86Access *ac, vaddr addr, unsigned len)
{
    vaddr offset = addr - ac->vaddr;

    assert(addr >= ac->vaddr);

    /* No haddr means probe_access wants to force slow path */
    if (!ac->haddr1) {
        return NULL;
    }

#ifdef CONFIG_USER_ONLY
    assert(offset <= ac->size1 - len);
    return ac->haddr1 + offset;
#else
    if (likely(offset <= ac->size1 - len)) {
        return ac->haddr1 + offset;
    }
    assert(offset <= ac->size - len);
    /*
     * If the address is not naturally aligned, it might span both pages.
     * Only return ac->haddr2 if the area is entirely within the second page,
     * otherwise fall back to slow accesses.
     */
    if (likely(offset >= ac->size1)) {
        return ac->haddr2 + (offset - ac->size1);
    }
    return NULL;
#endif
}

uint8_t access_ldb(X86Access *ac, vaddr addr)
{
    void *p = access_ptr(ac, addr, sizeof(uint8_t));

    if (likely(p)) {
        return ldub_p(p);
    }
    return cpu_ldub_mmuidx_ra(ac->env, addr, ac->mmu_idx, ac->ra);
}

uint16_t access_ldw(X86Access *ac, vaddr addr)
{
    void *p = access_ptr(ac, addr, sizeof(uint16_t));

    if (likely(p)) {
        return lduw_le_p(p);
    }
    return cpu_lduw_le_mmuidx_ra(ac->env, addr, ac->mmu_idx, ac->ra);
}

uint32_t access_ldl(X86Access *ac, vaddr addr)
{
    void *p = access_ptr(ac, addr, sizeof(uint32_t));

    if (likely(p)) {
        return ldl_le_p(p);
    }
    return cpu_ldl_le_mmuidx_ra(ac->env, addr, ac->mmu_idx, ac->ra);
}

uint64_t access_ldq(X86Access *ac, vaddr addr)
{
    void *p = access_ptr(ac, addr, sizeof(uint64_t));

    if (likely(p)) {
        return ldq_le_p(p);
    }
    return cpu_ldq_le_mmuidx_ra(ac->env, addr, ac->mmu_idx, ac->ra);
}

void access_stb(X86Access *ac, vaddr addr, uint8_t val)
{
    void *p = access_ptr(ac, addr, sizeof(uint8_t));

    if (likely(p)) {
        stb_p(p, val);
    } else {
        cpu_stb_mmuidx_ra(ac->env, addr, val, ac->mmu_idx, ac->ra);
    }
}

void access_stw(X86Access *ac, vaddr addr, uint16_t val)
{
    void *p = access_ptr(ac, addr, sizeof(uint16_t));

    if (likely(p)) {
        stw_le_p(p, val);
    } else {
        cpu_stw_le_mmuidx_ra(ac->env, addr, val, ac->mmu_idx, ac->ra);
    }
}

void access_stl(X86Access *ac, vaddr addr, uint32_t val)
{
    void *p = access_ptr(ac, addr, sizeof(uint32_t));

    if (likely(p)) {
        stl_le_p(p, val);
    } else {
        cpu_stl_le_mmuidx_ra(ac->env, addr, val, ac->mmu_idx, ac->ra);
    }
}

void access_stq(X86Access *ac, vaddr addr, uint64_t val)
{
    void *p = access_ptr(ac, addr, sizeof(uint64_t));

    if (likely(p)) {
        stq_le_p(p, val);
    } else {
        cpu_stq_le_mmuidx_ra(ac->env, addr, val, ac->mmu_idx, ac->ra);
    }
}
