/*
 * OpenRISC MMU.
 *
 * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
 *                         Zhizhou Zhang <etouzh@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
#include "qemu/host-utils.h"
#include "hw/loader.h"

static inline void get_phys_nommu(hwaddr *phys_addr, int *prot,
                                  target_ulong address)
{
    *phys_addr = address;
    *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
}

static int get_phys_mmu(OpenRISCCPU *cpu, hwaddr *phys_addr, int *prot,
                        target_ulong addr, int need, bool super)
{
    int idx = (addr >> TARGET_PAGE_BITS) & TLB_MASK;
    uint32_t imr = cpu->env.tlb.itlb[idx].mr;
    uint32_t itr = cpu->env.tlb.itlb[idx].tr;
    uint32_t dmr = cpu->env.tlb.dtlb[idx].mr;
    uint32_t dtr = cpu->env.tlb.dtlb[idx].tr;
    int right, match, valid;

    /* If the ITLB and DTLB indexes map to the same page, we want to
       load all permissions all at once.  If the destination pages do
       not match, zap the one we don't need.  */
    if (unlikely((itr ^ dtr) & TARGET_PAGE_MASK)) {
        if (need & PAGE_EXEC) {
            dmr = dtr = 0;
        } else {
            imr = itr = 0;
        }
    }

    /* Check if either of the entries matches the source address.  */
    match  = (imr ^ addr) & TARGET_PAGE_MASK ? 0 : PAGE_EXEC;
    match |= (dmr ^ addr) & TARGET_PAGE_MASK ? 0 : PAGE_READ | PAGE_WRITE;

    /* Check if either of the entries is valid.  */
    valid  = imr & 1 ? PAGE_EXEC : 0;
    valid |= dmr & 1 ? PAGE_READ | PAGE_WRITE : 0;
    valid &= match;

    /* Collect the permissions from the entries.  */
    right  = itr & (super ? SXE : UXE) ? PAGE_EXEC : 0;
    right |= dtr & (super ? SRE : URE) ? PAGE_READ : 0;
    right |= dtr & (super ? SWE : UWE) ? PAGE_WRITE : 0;
    right &= valid;

    /* Note that above we validated that itr and dtr match on page.
       So oring them together changes nothing without having to
       check which one we needed.  We also want to store to these
       variables even on failure, as it avoids compiler warnings.  */
    *phys_addr = ((itr | dtr) & TARGET_PAGE_MASK) | (addr & ~TARGET_PAGE_MASK);
    *prot = right;

    qemu_log_mask(CPU_LOG_MMU,
                  "MMU lookup: need %d match %d valid %d right %d -> %s\n",
                  need, match, valid, right, (need & right) ? "OK" : "FAIL");

    /* Check the collective permissions are present.  */
    if (likely(need & right)) {
        return 0;  /* success! */
    }

    /* Determine what kind of failure we have.  */
    if (need & valid) {
        return need & PAGE_EXEC ? EXCP_IPF : EXCP_DPF;
    } else {
        return need & PAGE_EXEC ? EXCP_ITLBMISS : EXCP_DTLBMISS;
    }
}

static void raise_mmu_exception(OpenRISCCPU *cpu, target_ulong address,
                                int exception)
{
    CPUState *cs = CPU(cpu);

    cs->exception_index = exception;
    cpu->env.eear = address;
    cpu->env.lock_addr = -1;
}

bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
                           MMUAccessType access_type, int mmu_idx,
                           bool probe, uintptr_t retaddr)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    int excp = EXCP_DPF;
    int prot;
    hwaddr phys_addr;

    if (mmu_idx == MMU_NOMMU_IDX) {
        /* The mmu is disabled; lookups never fail.  */
        get_phys_nommu(&phys_addr, &prot, addr);
        excp = 0;
    } else {
        bool super = mmu_idx == MMU_SUPERVISOR_IDX;
        int need = (access_type == MMU_INST_FETCH ? PAGE_EXEC
                    : access_type == MMU_DATA_STORE ? PAGE_WRITE
                    : PAGE_READ);
        excp = get_phys_mmu(cpu, &phys_addr, &prot, addr, need, super);
    }

    if (likely(excp == 0)) {
        tlb_set_page(cs, addr & TARGET_PAGE_MASK,
                     phys_addr & TARGET_PAGE_MASK, prot,
                     mmu_idx, TARGET_PAGE_SIZE);
        return true;
    }
    if (probe) {
        return false;
    }

    raise_mmu_exception(cpu, addr, excp);
    cpu_loop_exit_restore(cs, retaddr);
}

hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    int prot, excp, sr = cpu->env.sr;
    hwaddr phys_addr;

    switch (sr & (SR_DME | SR_IME)) {
    case SR_DME | SR_IME:
        /* The mmu is definitely enabled.  */
        excp = get_phys_mmu(cpu, &phys_addr, &prot, addr,
                            PAGE_READ,
                            (sr & SR_SM) != 0);
        if (!excp) {
            return phys_addr;
        }
        excp = get_phys_mmu(cpu, &phys_addr, &prot, addr,
                            PAGE_EXEC,
                            (sr & SR_SM) != 0);
        return excp ? -1 : phys_addr;

    default:
        /* The mmu is partially enabled, and we don't really have
           a "real" access type.  Begin by trying the mmu, but if
           that fails try again without.  */
        excp = get_phys_mmu(cpu, &phys_addr, &prot, addr,
                            PAGE_EXEC | PAGE_READ | PAGE_WRITE,
                            (sr & SR_SM) != 0);
        if (!excp) {
            return phys_addr;
        }
        /* fallthru */

    case 0:
        /* The mmu is definitely disabled; lookups never fail.  */
        get_phys_nommu(&phys_addr, &prot, addr);
        return phys_addr;
    }
}
