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

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

int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
                               target_phys_addr_t *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,
                               target_phys_addr_t *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 & 0) && ((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,
                                      target_phys_addr_t *physical,
                                      int *prot, target_ulong address,
                                      int rw)
{
    int ret = TLBRET_MATCH;

    /* [0x0000--0x2000]: unmapped */
    if (address < 0x2000 && (cpu->env.sr & SR_SM)) {
        *physical = address;
        *prot = PAGE_READ | PAGE_WRITE;
        return ret;
    }

    if (rw == 2) {    /* 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)
{
    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
    }

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

#ifndef CONFIG_USER_ONLY
int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
                                  target_ulong address, int rw, int mmu_idx)
{
    int ret = 0;
    target_phys_addr_t physical = 0;
    int prot = 0;
    OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));

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

    if (ret == TLBRET_MATCH) {
        tlb_set_page(env, address & TARGET_PAGE_MASK,
                     physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
                     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 cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
                                  target_ulong address, int rw, int mmu_idx)
{
    int ret = 0;
    OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));

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

    return ret;
}
#endif

#ifndef CONFIG_USER_ONLY
target_phys_addr_t cpu_get_phys_page_debug(CPUOpenRISCState *env,
                                           target_ulong addr)
{
    target_phys_addr_t phys_addr;
    int prot;
    OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));

    if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) {
        return -1;
    }

    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
