/*
 *  Microblaze MMU emulation for qemu.
 *
 *  Copyright (c) 2009 Edgar E. Iglesias
 *  Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
 *
 * 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"

static unsigned int tlb_decode_size(unsigned int f)
{
    static const unsigned int sizes[] = {
        1 * 1024, 4 * 1024, 16 * 1024, 64 * 1024, 256 * 1024,
        1 * 1024 * 1024, 4 * 1024 * 1024, 16 * 1024 * 1024
    };
    assert(f < ARRAY_SIZE(sizes));
    return sizes[f];
}

static void mmu_flush_idx(CPUMBState *env, unsigned int idx)
{
    CPUState *cs = env_cpu(env);
    MicroBlazeMMU *mmu = &env->mmu;
    unsigned int tlb_size;
    uint32_t tlb_tag, end, t;

    t = mmu->rams[RAM_TAG][idx];
    if (!(t & TLB_VALID))
        return;

    tlb_tag = t & TLB_EPN_MASK;
    tlb_size = tlb_decode_size((t & TLB_PAGESZ_MASK) >> 7);
    end = tlb_tag + tlb_size;

    while (tlb_tag < end) {
        tlb_flush_page(cs, tlb_tag);
        tlb_tag += TARGET_PAGE_SIZE;
    }
}

static void mmu_change_pid(CPUMBState *env, unsigned int newpid) 
{
    MicroBlazeMMU *mmu = &env->mmu;
    unsigned int i;
    uint32_t t;

    if (newpid & ~0xff)
        qemu_log_mask(LOG_GUEST_ERROR, "Illegal rpid=%x\n", newpid);

    for (i = 0; i < ARRAY_SIZE(mmu->rams[RAM_TAG]); i++) {
        /* Lookup and decode.  */
        t = mmu->rams[RAM_TAG][i];
        if (t & TLB_VALID) {
            if (mmu->tids[i] && ((mmu->regs[MMU_R_PID] & 0xff) == mmu->tids[i]))
                mmu_flush_idx(env, i);
        }
    }
}

/* rw - 0 = read, 1 = write, 2 = fetch.  */
unsigned int mmu_translate(MicroBlazeCPU *cpu, MicroBlazeMMULookup *lu,
                           target_ulong vaddr, int rw, int mmu_idx)
{
    MicroBlazeMMU *mmu = &cpu->env.mmu;
    unsigned int i, hit = 0;
    unsigned int tlb_ex = 0, tlb_wr = 0, tlb_zsel;
    uint64_t tlb_tag, tlb_rpn, mask;
    uint32_t tlb_size, t0;

    lu->err = ERR_MISS;
    for (i = 0; i < ARRAY_SIZE(mmu->rams[RAM_TAG]); i++) {
        uint64_t t, d;

        /* Lookup and decode.  */
        t = mmu->rams[RAM_TAG][i];
        if (t & TLB_VALID) {
            tlb_size = tlb_decode_size((t & TLB_PAGESZ_MASK) >> 7);
            if (tlb_size < TARGET_PAGE_SIZE) {
                qemu_log_mask(LOG_UNIMP, "%d pages not supported\n", tlb_size);
                abort();
            }

            mask = ~((uint64_t)tlb_size - 1);
            tlb_tag = t & TLB_EPN_MASK;
            if ((vaddr & mask) != (tlb_tag & mask)) {
                continue;
            }
            if (mmu->tids[i]
                && ((mmu->regs[MMU_R_PID] & 0xff) != mmu->tids[i])) {
                continue;
            }

            /* Bring in the data part.  */
            d = mmu->rams[RAM_DATA][i];
            tlb_ex = d & TLB_EX;
            tlb_wr = d & TLB_WR;

            /* Now let's see if there is a zone that overrides the protbits.  */
            tlb_zsel = (d >> 4) & 0xf;
            t0 = mmu->regs[MMU_R_ZPR] >> (30 - (tlb_zsel * 2));
            t0 &= 0x3;

            if (tlb_zsel > cpu->cfg.mmu_zones) {
                qemu_log_mask(LOG_GUEST_ERROR,
                              "tlb zone select out of range! %d\n", tlb_zsel);
                t0 = 1; /* Ignore.  */
            }

            if (cpu->cfg.mmu == 1) {
                t0 = 1; /* Zones are disabled.  */
            }

            switch (t0) {
                case 0:
                    if (mmu_idx == MMU_USER_IDX)
                        continue;
                    break;
                case 2:
                    if (mmu_idx != MMU_USER_IDX) {
                        tlb_ex = 1;
                        tlb_wr = 1;
                    }
                    break;
                case 3:
                    tlb_ex = 1;
                    tlb_wr = 1;
                    break;
                default: break;
            }

            lu->err = ERR_PROT;
            lu->prot = PAGE_READ;
            if (tlb_wr)
                lu->prot |= PAGE_WRITE;
            else if (rw == 1)
                goto done;
            if (tlb_ex)
                lu->prot |=PAGE_EXEC;
            else if (rw == 2) {
                goto done;
            }

            tlb_rpn = d & TLB_RPN_MASK;

            lu->vaddr = tlb_tag;
            lu->paddr = tlb_rpn & cpu->cfg.addr_mask;
            lu->size = tlb_size;
            lu->err = ERR_HIT;
            lu->idx = i;
            hit = 1;
            goto done;
        }
    }
done:
    qemu_log_mask(CPU_LOG_MMU,
                  "MMU vaddr=%" PRIx64 " rw=%d tlb_wr=%d tlb_ex=%d hit=%d\n",
                  vaddr, rw, tlb_wr, tlb_ex, hit);
    return hit;
}

/* Writes/reads to the MMU's special regs end up here.  */
uint32_t mmu_read(CPUMBState *env, bool ext, uint32_t rn)
{
    MicroBlazeCPU *cpu = env_archcpu(env);
    unsigned int i;
    uint32_t r = 0;

    if (cpu->cfg.mmu < 2 || !cpu->cfg.mmu_tlb_access) {
        qemu_log_mask(LOG_GUEST_ERROR, "MMU access on MMU-less system\n");
        return 0;
    }
    if (ext && rn != MMU_R_TLBLO) {
        qemu_log_mask(LOG_GUEST_ERROR, "Extended access only to TLBLO.\n");
        return 0;
    }

    switch (rn) {
        /* Reads to HI/LO trig reads from the mmu rams.  */
        case MMU_R_TLBLO:
        case MMU_R_TLBHI:
            if (!(cpu->cfg.mmu_tlb_access & 1)) {
                qemu_log_mask(LOG_GUEST_ERROR,
                              "Invalid access to MMU reg %d\n", rn);
                return 0;
            }

            i = env->mmu.regs[MMU_R_TLBX] & 0xff;
            r = extract64(env->mmu.rams[rn & 1][i], ext * 32, 32);
            if (rn == MMU_R_TLBHI)
                env->mmu.regs[MMU_R_PID] = env->mmu.tids[i];
            break;
        case MMU_R_PID:
        case MMU_R_ZPR:
            if (!(cpu->cfg.mmu_tlb_access & 1)) {
                qemu_log_mask(LOG_GUEST_ERROR,
                              "Invalid access to MMU reg %d\n", rn);
                return 0;
            }
            r = env->mmu.regs[rn];
            break;
        case MMU_R_TLBX:
            r = env->mmu.regs[rn];
            break;
        case MMU_R_TLBSX:
            qemu_log_mask(LOG_GUEST_ERROR, "TLBSX is write-only.\n");
            break;
        default:
            qemu_log_mask(LOG_GUEST_ERROR, "Invalid MMU register %d.\n", rn);
            break;
    }
    qemu_log_mask(CPU_LOG_MMU, "%s rn=%d=%x\n", __func__, rn, r);
    return r;
}

void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
{
    MicroBlazeCPU *cpu = env_archcpu(env);
    uint64_t tmp64;
    unsigned int i;

    qemu_log_mask(CPU_LOG_MMU,
                  "%s rn=%d=%x old=%x\n", __func__, rn, v, env->mmu.regs[rn]);

    if (cpu->cfg.mmu < 2 || !cpu->cfg.mmu_tlb_access) {
        qemu_log_mask(LOG_GUEST_ERROR, "MMU access on MMU-less system\n");
        return;
    }
    if (ext && rn != MMU_R_TLBLO) {
        qemu_log_mask(LOG_GUEST_ERROR, "Extended access only to TLBLO.\n");
        return;
    }

    switch (rn) {
        /* Writes to HI/LO trig writes to the mmu rams.  */
        case MMU_R_TLBLO:
        case MMU_R_TLBHI:
            i = env->mmu.regs[MMU_R_TLBX] & 0xff;
            if (rn == MMU_R_TLBHI) {
                if (i < 3 && !(v & TLB_VALID) && qemu_loglevel_mask(~0))
                    qemu_log_mask(LOG_GUEST_ERROR,
                                  "invalidating index %x at pc=%x\n",
                                  i, env->pc);
                env->mmu.tids[i] = env->mmu.regs[MMU_R_PID] & 0xff;
                mmu_flush_idx(env, i);
            }
            tmp64 = env->mmu.rams[rn & 1][i];
            env->mmu.rams[rn & 1][i] = deposit64(tmp64, ext * 32, 32, v);
            break;
        case MMU_R_ZPR:
            if (cpu->cfg.mmu_tlb_access <= 1) {
                qemu_log_mask(LOG_GUEST_ERROR,
                              "Invalid access to MMU reg %d\n", rn);
                return;
            }

            /* Changes to the zone protection reg flush the QEMU TLB.
               Fortunately, these are very uncommon.  */
            if (v != env->mmu.regs[rn]) {
                tlb_flush(env_cpu(env));
            }
            env->mmu.regs[rn] = v;
            break;
        case MMU_R_PID:
            if (cpu->cfg.mmu_tlb_access <= 1) {
                qemu_log_mask(LOG_GUEST_ERROR,
                              "Invalid access to MMU reg %d\n", rn);
                return;
            }

            if (v != env->mmu.regs[rn]) {
                mmu_change_pid(env, v);
                env->mmu.regs[rn] = v;
            }
            break;
        case MMU_R_TLBX:
            /* Bit 31 is read-only.  */
            env->mmu.regs[rn] = deposit32(env->mmu.regs[rn], 0, 31, v);
            break;
        case MMU_R_TLBSX:
        {
            MicroBlazeMMULookup lu;
            int hit;

            if (cpu->cfg.mmu_tlb_access <= 1) {
                qemu_log_mask(LOG_GUEST_ERROR,
                              "Invalid access to MMU reg %d\n", rn);
                return;
            }

            hit = mmu_translate(cpu, &lu, v & TLB_EPN_MASK,
                                0, cpu_mmu_index(env, false));
            if (hit) {
                env->mmu.regs[MMU_R_TLBX] = lu.idx;
            } else {
                env->mmu.regs[MMU_R_TLBX] |= R_TBLX_MISS_MASK;
            }
            break;
        }
        default:
            qemu_log_mask(LOG_GUEST_ERROR, "Invalid MMU register %d.\n", rn);
            break;
   }
}

void mmu_init(MicroBlazeMMU *mmu)
{
    int i;
    for (i = 0; i < ARRAY_SIZE(mmu->regs); i++) {
        mmu->regs[i] = 0;
    }
}
