/*
 * S390x MMU related functions
 *
 * Copyright (c) 2011 Alexander Graf
 * Copyright (c) 2015 Thomas Huth, IBM Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "exec/address-spaces.h"
#include "cpu.h"
#include "s390x-internal.h"
#include "kvm/kvm_s390x.h"
#include "sysemu/kvm.h"
#include "sysemu/tcg.h"
#include "exec/exec-all.h"
#include "trace.h"
#include "hw/hw.h"
#include "hw/s390x/storage-keys.h"
#include "hw/boards.h"

/* Fetch/store bits in the translation exception code: */
#define FS_READ  0x800
#define FS_WRITE 0x400

static void trigger_access_exception(CPUS390XState *env, uint32_t type,
                                     uint64_t tec)
{
    S390CPU *cpu = env_archcpu(env);

    if (kvm_enabled()) {
        kvm_s390_access_exception(cpu, type, tec);
    } else {
        CPUState *cs = env_cpu(env);
        if (type != PGM_ADDRESSING) {
            stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
        }
        trigger_pgm_exception(env, type);
    }
}

/* check whether the address would be proteted by Low-Address Protection */
static bool is_low_address(uint64_t addr)
{
    return addr <= 511 || (addr >= 4096 && addr <= 4607);
}

/* check whether Low-Address Protection is enabled for mmu_translate() */
static bool lowprot_enabled(const CPUS390XState *env, uint64_t asc)
{
    if (!(env->cregs[0] & CR0_LOWPROT)) {
        return false;
    }
    if (!(env->psw.mask & PSW_MASK_DAT)) {
        return true;
    }

    /* Check the private-space control bit */
    switch (asc) {
    case PSW_ASC_PRIMARY:
        return !(env->cregs[1] & ASCE_PRIVATE_SPACE);
    case PSW_ASC_SECONDARY:
        return !(env->cregs[7] & ASCE_PRIVATE_SPACE);
    case PSW_ASC_HOME:
        return !(env->cregs[13] & ASCE_PRIVATE_SPACE);
    default:
        /* We don't support access register mode */
        error_report("unsupported addressing mode");
        exit(1);
    }
}

/**
 * Translate real address to absolute (= physical)
 * address by taking care of the prefix mapping.
 */
target_ulong mmu_real2abs(CPUS390XState *env, target_ulong raddr)
{
    if (raddr < 0x2000) {
        return raddr + env->psa;    /* Map the lowcore. */
    } else if (raddr >= env->psa && raddr < env->psa + 0x2000) {
        return raddr - env->psa;    /* Map the 0 page. */
    }
    return raddr;
}

bool mmu_absolute_addr_valid(target_ulong addr, bool is_write)
{
    return address_space_access_valid(&address_space_memory,
                                      addr & TARGET_PAGE_MASK,
                                      TARGET_PAGE_SIZE, is_write,
                                      MEMTXATTRS_UNSPECIFIED);
}

static inline bool read_table_entry(CPUS390XState *env, hwaddr gaddr,
                                    uint64_t *entry)
{
    CPUState *cs = env_cpu(env);

    /*
     * According to the PoP, these table addresses are "unpredictably real
     * or absolute". Also, "it is unpredictable whether the address wraps
     * or an addressing exception is recognized".
     *
     * We treat them as absolute addresses and don't wrap them.
     */
    if (unlikely(address_space_read(cs->as, gaddr, MEMTXATTRS_UNSPECIFIED,
                                    entry, sizeof(*entry)) !=
                 MEMTX_OK)) {
        return false;
    }
    *entry = be64_to_cpu(*entry);
    return true;
}

static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
                              uint64_t asc, uint64_t asce, target_ulong *raddr,
                              int *flags)
{
    const bool edat1 = (env->cregs[0] & CR0_EDAT) &&
                       s390_has_feat(S390_FEAT_EDAT);
    const bool edat2 = edat1 && s390_has_feat(S390_FEAT_EDAT_2);
    const bool iep = (env->cregs[0] & CR0_IEP) &&
                     s390_has_feat(S390_FEAT_INSTRUCTION_EXEC_PROT);
    const int asce_tl = asce & ASCE_TABLE_LENGTH;
    const int asce_p = asce & ASCE_PRIVATE_SPACE;
    hwaddr gaddr = asce & ASCE_ORIGIN;
    uint64_t entry;

    if (asce & ASCE_REAL_SPACE) {
        /* direct mapping */
        *raddr = vaddr;
        return 0;
    }

    switch (asce & ASCE_TYPE_MASK) {
    case ASCE_TYPE_REGION1:
        if (VADDR_REGION1_TL(vaddr) > asce_tl) {
            return PGM_REG_FIRST_TRANS;
        }
        gaddr += VADDR_REGION1_TX(vaddr) * 8;
        break;
    case ASCE_TYPE_REGION2:
        if (VADDR_REGION1_TX(vaddr)) {
            return PGM_ASCE_TYPE;
        }
        if (VADDR_REGION2_TL(vaddr) > asce_tl) {
            return PGM_REG_SEC_TRANS;
        }
        gaddr += VADDR_REGION2_TX(vaddr) * 8;
        break;
    case ASCE_TYPE_REGION3:
        if (VADDR_REGION1_TX(vaddr) || VADDR_REGION2_TX(vaddr)) {
            return PGM_ASCE_TYPE;
        }
        if (VADDR_REGION3_TL(vaddr) > asce_tl) {
            return PGM_REG_THIRD_TRANS;
        }
        gaddr += VADDR_REGION3_TX(vaddr) * 8;
        break;
    case ASCE_TYPE_SEGMENT:
        if (VADDR_REGION1_TX(vaddr) || VADDR_REGION2_TX(vaddr) ||
            VADDR_REGION3_TX(vaddr)) {
            return PGM_ASCE_TYPE;
        }
        if (VADDR_SEGMENT_TL(vaddr) > asce_tl) {
            return PGM_SEGMENT_TRANS;
        }
        gaddr += VADDR_SEGMENT_TX(vaddr) * 8;
        break;
    }

    switch (asce & ASCE_TYPE_MASK) {
    case ASCE_TYPE_REGION1:
        if (!read_table_entry(env, gaddr, &entry)) {
            return PGM_ADDRESSING;
        }
        if (entry & REGION_ENTRY_I) {
            return PGM_REG_FIRST_TRANS;
        }
        if ((entry & REGION_ENTRY_TT) != REGION_ENTRY_TT_REGION1) {
            return PGM_TRANS_SPEC;
        }
        if (VADDR_REGION2_TL(vaddr) < (entry & REGION_ENTRY_TF) >> 6 ||
            VADDR_REGION2_TL(vaddr) > (entry & REGION_ENTRY_TL)) {
            return PGM_REG_SEC_TRANS;
        }
        if (edat1 && (entry & REGION_ENTRY_P)) {
            *flags &= ~PAGE_WRITE;
        }
        gaddr = (entry & REGION_ENTRY_ORIGIN) + VADDR_REGION2_TX(vaddr) * 8;
        /* fall through */
    case ASCE_TYPE_REGION2:
        if (!read_table_entry(env, gaddr, &entry)) {
            return PGM_ADDRESSING;
        }
        if (entry & REGION_ENTRY_I) {
            return PGM_REG_SEC_TRANS;
        }
        if ((entry & REGION_ENTRY_TT) != REGION_ENTRY_TT_REGION2) {
            return PGM_TRANS_SPEC;
        }
        if (VADDR_REGION3_TL(vaddr) < (entry & REGION_ENTRY_TF) >> 6 ||
            VADDR_REGION3_TL(vaddr) > (entry & REGION_ENTRY_TL)) {
            return PGM_REG_THIRD_TRANS;
        }
        if (edat1 && (entry & REGION_ENTRY_P)) {
            *flags &= ~PAGE_WRITE;
        }
        gaddr = (entry & REGION_ENTRY_ORIGIN) + VADDR_REGION3_TX(vaddr) * 8;
        /* fall through */
    case ASCE_TYPE_REGION3:
        if (!read_table_entry(env, gaddr, &entry)) {
            return PGM_ADDRESSING;
        }
        if (entry & REGION_ENTRY_I) {
            return PGM_REG_THIRD_TRANS;
        }
        if ((entry & REGION_ENTRY_TT) != REGION_ENTRY_TT_REGION3) {
            return PGM_TRANS_SPEC;
        }
        if (edat2 && (entry & REGION3_ENTRY_CR) && asce_p) {
            return PGM_TRANS_SPEC;
        }
        if (edat1 && (entry & REGION_ENTRY_P)) {
            *flags &= ~PAGE_WRITE;
        }
        if (edat2 && (entry & REGION3_ENTRY_FC)) {
            if (iep && (entry & REGION3_ENTRY_IEP)) {
                *flags &= ~PAGE_EXEC;
            }
            *raddr = (entry & REGION3_ENTRY_RFAA) |
                     (vaddr & ~REGION3_ENTRY_RFAA);
            return 0;
        }
        if (VADDR_SEGMENT_TL(vaddr) < (entry & REGION_ENTRY_TF) >> 6 ||
            VADDR_SEGMENT_TL(vaddr) > (entry & REGION_ENTRY_TL)) {
            return PGM_SEGMENT_TRANS;
        }
        gaddr = (entry & REGION_ENTRY_ORIGIN) + VADDR_SEGMENT_TX(vaddr) * 8;
        /* fall through */
    case ASCE_TYPE_SEGMENT:
        if (!read_table_entry(env, gaddr, &entry)) {
            return PGM_ADDRESSING;
        }
        if (entry & SEGMENT_ENTRY_I) {
            return PGM_SEGMENT_TRANS;
        }
        if ((entry & SEGMENT_ENTRY_TT) != SEGMENT_ENTRY_TT_SEGMENT) {
            return PGM_TRANS_SPEC;
        }
        if ((entry & SEGMENT_ENTRY_CS) && asce_p) {
            return PGM_TRANS_SPEC;
        }
        if (entry & SEGMENT_ENTRY_P) {
            *flags &= ~PAGE_WRITE;
        }
        if (edat1 && (entry & SEGMENT_ENTRY_FC)) {
            if (iep && (entry & SEGMENT_ENTRY_IEP)) {
                *flags &= ~PAGE_EXEC;
            }
            *raddr = (entry & SEGMENT_ENTRY_SFAA) |
                     (vaddr & ~SEGMENT_ENTRY_SFAA);
            return 0;
        }
        gaddr = (entry & SEGMENT_ENTRY_ORIGIN) + VADDR_PAGE_TX(vaddr) * 8;
        break;
    }

    if (!read_table_entry(env, gaddr, &entry)) {
        return PGM_ADDRESSING;
    }
    if (entry & PAGE_ENTRY_I) {
        return PGM_PAGE_TRANS;
    }
    if (entry & PAGE_ENTRY_0) {
        return PGM_TRANS_SPEC;
    }
    if (entry & PAGE_ENTRY_P) {
        *flags &= ~PAGE_WRITE;
    }
    if (iep && (entry & PAGE_ENTRY_IEP)) {
        *flags &= ~PAGE_EXEC;
    }

    *raddr = entry & TARGET_PAGE_MASK;
    return 0;
}

static void mmu_handle_skey(target_ulong addr, int rw, int *flags)
{
    static S390SKeysClass *skeyclass;
    static S390SKeysState *ss;
    uint8_t key, old_key;
    int rc;

    /*
     * We expect to be called with an absolute address that has already been
     * validated, such that we can reliably use it to lookup the storage key.
     */
    if (unlikely(!ss)) {
        ss = s390_get_skeys_device();
        skeyclass = S390_SKEYS_GET_CLASS(ss);
    }

    /*
     * Don't enable storage keys if they are still disabled, i.e., no actual
     * storage key instruction was issued yet.
     */
    if (!skeyclass->skeys_are_enabled(ss)) {
        return;
    }

    /*
     * Whenever we create a new TLB entry, we set the storage key reference
     * bit. In case we allow write accesses, we set the storage key change
     * bit. Whenever the guest changes the storage key, we have to flush the
     * TLBs of all CPUs (the whole TLB or all affected entries), so that the
     * next reference/change will result in an MMU fault and make us properly
     * update the storage key here.
     *
     * Note 1: "record of references ... is not necessarily accurate",
     *         "change bit may be set in case no storing has occurred".
     *         -> We can set reference/change bits even on exceptions.
     * Note 2: certain accesses seem to ignore storage keys. For example,
     *         DAT translation does not set reference bits for table accesses.
     *
     * TODO: key-controlled protection. Only CPU accesses make use of the
     *       PSW key. CSS accesses are different - we have to pass in the key.
     *
     * TODO: we have races between getting and setting the key.
     */
    rc = skeyclass->get_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
    if (rc) {
        trace_get_skeys_nonzero(rc);
        return;
    }
    old_key = key;

    switch (rw) {
    case MMU_DATA_LOAD:
    case MMU_INST_FETCH:
        /*
         * The TLB entry has to remain write-protected on read-faults if
         * the storage key does not indicate a change already. Otherwise
         * we might miss setting the change bit on write accesses.
         */
        if (!(key & SK_C)) {
            *flags &= ~PAGE_WRITE;
        }
        break;
    case MMU_DATA_STORE:
        key |= SK_C;
        break;
    default:
        g_assert_not_reached();
    }

    /* Any store/fetch sets the reference bit */
    key |= SK_R;

    if (key != old_key) {
        rc = skeyclass->set_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
        if (rc) {
            trace_set_skeys_nonzero(rc);
        }
    }
}

/**
 * Translate a virtual (logical) address into a physical (absolute) address.
 * @param vaddr  the virtual address
 * @param rw     0 = read, 1 = write, 2 = code fetch, < 0 = load real address
 * @param asc    address space control (one of the PSW_ASC_* modes)
 * @param raddr  the translated address is stored to this pointer
 * @param flags  the PAGE_READ/WRITE/EXEC flags are stored to this pointer
 * @param tec    the translation exception code if stored to this pointer if
 *               there is an exception to raise
 * @return       0 = success, != 0, the exception to raise
 */
int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
                  target_ulong *raddr, int *flags, uint64_t *tec)
{
    uint64_t asce;
    int r;

    *tec = (vaddr & TARGET_PAGE_MASK) | (asc >> 46) |
            (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ);
    *flags = PAGE_READ | PAGE_WRITE | PAGE_EXEC;

    if (is_low_address(vaddr & TARGET_PAGE_MASK) && lowprot_enabled(env, asc)) {
        /*
         * If any part of this page is currently protected, make sure the
         * TLB entry will not be reused.
         *
         * As the protected range is always the first 512 bytes of the
         * two first pages, we are able to catch all writes to these areas
         * just by looking at the start address (triggering the tlb miss).
         */
        *flags |= PAGE_WRITE_INV;
        if (is_low_address(vaddr) && rw == MMU_DATA_STORE) {
            /* LAP sets bit 56 */
            *tec |= 0x80;
            return PGM_PROTECTION;
        }
    }

    vaddr &= TARGET_PAGE_MASK;

    if (rw != MMU_S390_LRA && !(env->psw.mask & PSW_MASK_DAT)) {
        *raddr = vaddr;
        goto nodat;
    }

    switch (asc) {
    case PSW_ASC_PRIMARY:
        asce = env->cregs[1];
        break;
    case PSW_ASC_HOME:
        asce = env->cregs[13];
        break;
    case PSW_ASC_SECONDARY:
        asce = env->cregs[7];
        break;
    case PSW_ASC_ACCREG:
    default:
        hw_error("guest switched to unknown asc mode\n");
        break;
    }

    /* perform the DAT translation */
    r = mmu_translate_asce(env, vaddr, asc, asce, raddr, flags);
    if (unlikely(r)) {
        return r;
    }

    /* check for DAT protection */
    if (unlikely(rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE))) {
        /* DAT sets bit 61 only */
        *tec |= 0x4;
        return PGM_PROTECTION;
    }

    /* check for Instruction-Execution-Protection */
    if (unlikely(rw == MMU_INST_FETCH && !(*flags & PAGE_EXEC))) {
        /* IEP sets bit 56 and 61 */
        *tec |= 0x84;
        return PGM_PROTECTION;
    }

nodat:
    if (rw >= 0) {
        /* Convert real address -> absolute address */
        *raddr = mmu_real2abs(env, *raddr);

        if (!mmu_absolute_addr_valid(*raddr, rw == MMU_DATA_STORE)) {
            *tec = 0; /* unused */
            return PGM_ADDRESSING;
        }

        mmu_handle_skey(*raddr, rw, flags);
    }
    return 0;
}

/**
 * translate_pages: Translate a set of consecutive logical page addresses
 * to absolute addresses. This function is used for TCG and old KVM without
 * the MEMOP interface.
 */
static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
                           target_ulong *pages, bool is_write, uint64_t *tec)
{
    uint64_t asc = cpu->env.psw.mask & PSW_MASK_ASC;
    CPUS390XState *env = &cpu->env;
    int ret, i, pflags;

    for (i = 0; i < nr_pages; i++) {
        ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, tec);
        if (ret) {
            return ret;
        }
        addr += TARGET_PAGE_SIZE;
    }

    return 0;
}

int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
                       int len, bool is_write)
{
    int ret;

    if (kvm_enabled()) {
        ret = kvm_s390_mem_op_pv(cpu, offset, hostbuf, len, is_write);
    } else {
        /* Protected Virtualization is a KVM/Hardware only feature */
        g_assert_not_reached();
    }
    return ret;
}

/**
 * s390_cpu_virt_mem_rw:
 * @laddr:     the logical start address
 * @ar:        the access register number
 * @hostbuf:   buffer in host memory. NULL = do only checks w/o copying
 * @len:       length that should be transferred
 * @is_write:  true = write, false = read
 * Returns:    0 on success, non-zero if an exception occurred
 *
 * Copy from/to guest memory using logical addresses. Note that we inject a
 * program interrupt in case there is an error while accessing the memory.
 *
 * This function will always return (also for TCG), make sure to call
 * s390_cpu_virt_mem_handle_exc() to properly exit the CPU loop.
 */
int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
                         int len, bool is_write)
{
    int currlen, nr_pages, i;
    target_ulong *pages;
    uint64_t tec;
    int ret;

    if (kvm_enabled()) {
        ret = kvm_s390_mem_op(cpu, laddr, ar, hostbuf, len, is_write);
        if (ret >= 0) {
            return ret;
        }
    }

    nr_pages = (((laddr & ~TARGET_PAGE_MASK) + len - 1) >> TARGET_PAGE_BITS)
               + 1;
    pages = g_malloc(nr_pages * sizeof(*pages));

    ret = translate_pages(cpu, laddr, nr_pages, pages, is_write, &tec);
    if (ret) {
        trigger_access_exception(&cpu->env, ret, tec);
    } else if (hostbuf != NULL) {
        /* Copy data by stepping through the area page by page */
        for (i = 0; i < nr_pages; i++) {
            currlen = MIN(len, TARGET_PAGE_SIZE - (laddr % TARGET_PAGE_SIZE));
            cpu_physical_memory_rw(pages[i] | (laddr & ~TARGET_PAGE_MASK),
                                   hostbuf, currlen, is_write);
            laddr += currlen;
            hostbuf += currlen;
            len -= currlen;
        }
    }

    g_free(pages);
    return ret;
}

void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra)
{
    /* KVM will handle the interrupt automatically, TCG has to exit the TB */
#ifdef CONFIG_TCG
    if (tcg_enabled()) {
        cpu_loop_exit_restore(CPU(cpu), ra);
    }
#endif
}

/**
 * Translate a real address into a physical (absolute) address.
 * @param raddr  the real address
 * @param rw     0 = read, 1 = write, 2 = code fetch
 * @param addr   the translated address is stored to this pointer
 * @param flags  the PAGE_READ/WRITE/EXEC flags are stored to this pointer
 * @return       0 = success, != 0, the exception to raise
 */
int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
                       target_ulong *addr, int *flags, uint64_t *tec)
{
    const bool lowprot_enabled = env->cregs[0] & CR0_LOWPROT;

    *flags = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
    if (is_low_address(raddr & TARGET_PAGE_MASK) && lowprot_enabled) {
        /* see comment in mmu_translate() how this works */
        *flags |= PAGE_WRITE_INV;
        if (is_low_address(raddr) && rw == MMU_DATA_STORE) {
            /* LAP sets bit 56 */
            *tec = (raddr & TARGET_PAGE_MASK) | FS_WRITE | 0x80;
            return PGM_PROTECTION;
        }
    }

    *addr = mmu_real2abs(env, raddr & TARGET_PAGE_MASK);

    if (!mmu_absolute_addr_valid(*addr, rw == MMU_DATA_STORE)) {
        /* unused */
        *tec = 0;
        return PGM_ADDRESSING;
    }

    mmu_handle_skey(*addr, rw, flags);
    return 0;
}
