/*
 * 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 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 "cpu.h"
#include "exec/exec-all.h"
#include "qemu-common.h"
#include "exec/gdbstub.h"
#include "qemu/host-utils.h"
#ifndef CONFIG_USER_ONLY
#include "hw/loader.h"
#endif

#ifndef CONFIG_USER_ONLY
int cpu_openrisc_get_phys_nommu(OpenRISCCPU *cpu,
                                hwaddr *physical,
                                int *prot, target_ulong address, int rw)
{
    *physical = address;
    *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
    return TLBRET_MATCH;
}

int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
                               hwaddr *physical,
                               int *prot, target_ulong address, int rw)
{
    int vpn = address >> TARGET_PAGE_BITS;
    int idx = vpn & ITLB_MASK;
    int right = 0;

    if ((cpu->env.tlb->itlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
        return TLBRET_NOMATCH;
    }
    if (!(cpu->env.tlb->itlb[0][idx].mr & 1)) {
        return TLBRET_INVALID;
    }

    if (cpu->env.sr & SR_SM) { /* supervisor mode */
        if (cpu->env.tlb->itlb[0][idx].tr & SXE) {
            right |= PAGE_EXEC;
        }
    } else {
        if (cpu->env.tlb->itlb[0][idx].tr & UXE) {
            right |= PAGE_EXEC;
        }
    }

    if ((rw & 2) && ((right & PAGE_EXEC) == 0)) {
        return TLBRET_BADADDR;
    }

    *physical = (cpu->env.tlb->itlb[0][idx].tr & TARGET_PAGE_MASK) |
                (address & (TARGET_PAGE_SIZE-1));
    *prot = right;
    return TLBRET_MATCH;
}

int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
                               hwaddr *physical,
                               int *prot, target_ulong address, int rw)
{
    int vpn = address >> TARGET_PAGE_BITS;
    int idx = vpn & DTLB_MASK;
    int right = 0;

    if ((cpu->env.tlb->dtlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
        return TLBRET_NOMATCH;
    }
    if (!(cpu->env.tlb->dtlb[0][idx].mr & 1)) {
        return TLBRET_INVALID;
    }

    if (cpu->env.sr & SR_SM) { /* supervisor mode */
        if (cpu->env.tlb->dtlb[0][idx].tr & SRE) {
            right |= PAGE_READ;
        }
        if (cpu->env.tlb->dtlb[0][idx].tr & SWE) {
            right |= PAGE_WRITE;
        }
    } else {
        if (cpu->env.tlb->dtlb[0][idx].tr & URE) {
            right |= PAGE_READ;
        }
        if (cpu->env.tlb->dtlb[0][idx].tr & UWE) {
            right |= PAGE_WRITE;
        }
    }

    if (!(rw & 1) && ((right & PAGE_READ) == 0)) {
        return TLBRET_BADADDR;
    }
    if ((rw & 1) && ((right & PAGE_WRITE) == 0)) {
        return TLBRET_BADADDR;
    }

    *physical = (cpu->env.tlb->dtlb[0][idx].tr & TARGET_PAGE_MASK) |
                (address & (TARGET_PAGE_SIZE-1));
    *prot = right;
    return TLBRET_MATCH;
}

static int cpu_openrisc_get_phys_addr(OpenRISCCPU *cpu,
                                      hwaddr *physical,
                                      int *prot, target_ulong address,
                                      int rw)
{
    int ret = TLBRET_MATCH;

    if (rw == MMU_INST_FETCH) {    /* ITLB */
       *physical = 0;
        ret = cpu->env.tlb->cpu_openrisc_map_address_code(cpu, physical,
                                                          prot, address, rw);
    } else {          /* DTLB */
        ret = cpu->env.tlb->cpu_openrisc_map_address_data(cpu, physical,
                                                          prot, address, rw);
    }

    return ret;
}
#endif

static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
                                             target_ulong address,
                                             int rw, int tlb_error)
{
    CPUState *cs = CPU(cpu);
    int exception = 0;

    switch (tlb_error) {
    default:
        if (rw == 2) {
            exception = EXCP_IPF;
        } else {
            exception = EXCP_DPF;
        }
        break;
#ifndef CONFIG_USER_ONLY
    case TLBRET_BADADDR:
        if (rw == 2) {
            exception = EXCP_IPF;
        } else {
            exception = EXCP_DPF;
        }
        break;
    case TLBRET_INVALID:
    case TLBRET_NOMATCH:
        /* No TLB match for a mapped address */
        if (rw == 2) {
            exception = EXCP_ITLBMISS;
        } else {
            exception = EXCP_DTLBMISS;
        }
        break;
#endif
    }

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

#ifndef CONFIG_USER_ONLY
int openrisc_cpu_handle_mmu_fault(CPUState *cs,
                                  vaddr address, int rw, int mmu_idx)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    int ret = 0;
    hwaddr physical = 0;
    int prot = 0;

    ret = cpu_openrisc_get_phys_addr(cpu, &physical, &prot,
                                     address, rw);

    if (ret == TLBRET_MATCH) {
        tlb_set_page(cs, address & TARGET_PAGE_MASK,
                     physical & TARGET_PAGE_MASK, prot,
                     mmu_idx, TARGET_PAGE_SIZE);
        ret = 0;
    } else if (ret < 0) {
        cpu_openrisc_raise_mmu_exception(cpu, address, rw, ret);
        ret = 1;
    }

    return ret;
}
#else
int openrisc_cpu_handle_mmu_fault(CPUState *cs,
                                  vaddr address, int rw, int mmu_idx)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    int ret = 0;

    cpu_openrisc_raise_mmu_exception(cpu, address, rw, ret);
    ret = 1;

    return ret;
}
#endif

#ifndef CONFIG_USER_ONLY
hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    hwaddr phys_addr;
    int prot;
    int miss;

    /* Check memory for any kind of address, since during debug the
       gdb can ask for anything, check data tlb for address */
    miss = cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0);

    /* Check instruction tlb */
    if (miss) {
        miss = cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr,
                                          MMU_INST_FETCH);
    }

    /* Last, fall back to a plain address */
    if (miss) {
        miss = cpu_openrisc_get_phys_nommu(cpu, &phys_addr, &prot, addr, 0);
    }

    if (miss) {
        return -1;
    } else {
        return phys_addr;
    }
}

void cpu_openrisc_mmu_init(OpenRISCCPU *cpu)
{
    cpu->env.tlb = g_malloc0(sizeof(CPUOpenRISCTLBContext));

    cpu->env.tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
    cpu->env.tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
}
#endif
