/*
 * 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 (!(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;
}
