/*
 *  SH4 emulation
 *
 *  Copyright (c) 2005 Samuel Tardieu
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <signal.h>
#include <assert.h>

#include "cpu.h"
#include "exec-all.h"
#include "hw/sh_intc.h"

#if defined(CONFIG_USER_ONLY)

void do_interrupt (CPUState *env)
{
  env->exception_index = -1;
}

int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
			     int mmu_idx, int is_softmmu)
{
    env->tea = address;
    env->exception_index = 0;
    switch (rw) {
    case 0:
	env->tea = address;
        env->exception_index = 0x0a0;
        break;
    case 1:
	env->tea = address;
        env->exception_index = 0x0c0;
        break;
    }
    return 1;
}

target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
{
    return addr;
}

#else /* !CONFIG_USER_ONLY */

#define MMU_OK                   0
#define MMU_ITLB_MISS            (-1)
#define MMU_ITLB_MULTIPLE        (-2)
#define MMU_ITLB_VIOLATION       (-3)
#define MMU_DTLB_MISS_READ       (-4)
#define MMU_DTLB_MISS_WRITE      (-5)
#define MMU_DTLB_INITIAL_WRITE   (-6)
#define MMU_DTLB_VIOLATION_READ  (-7)
#define MMU_DTLB_VIOLATION_WRITE (-8)
#define MMU_DTLB_MULTIPLE        (-9)
#define MMU_DTLB_MISS            (-10)

void do_interrupt(CPUState * env)
{
    int do_irq = env->interrupt_request & CPU_INTERRUPT_HARD;
    int do_exp, irq_vector = env->exception_index;

    /* prioritize exceptions over interrupts */

    do_exp = env->exception_index != -1;
    do_irq = do_irq && (env->exception_index == -1);

    if (env->sr & SR_BL) {
        if (do_exp && env->exception_index != 0x1e0) {
            env->exception_index = 0x000; /* masked exception -> reset */
        }
        if (do_irq) {
            return; /* masked */
        }
    }

    if (do_irq) {
        irq_vector = sh_intc_get_pending_vector(env->intc_handle,
						(env->sr >> 4) & 0xf);
        if (irq_vector == -1) {
            return; /* masked */
	}
    }

    if (loglevel & CPU_LOG_INT) {
	const char *expname;
	switch (env->exception_index) {
	case 0x0e0:
	    expname = "addr_error";
	    break;
	case 0x040:
	    expname = "tlb_miss";
	    break;
	case 0x0a0:
	    expname = "tlb_violation";
	    break;
	case 0x180:
	    expname = "illegal_instruction";
	    break;
	case 0x1a0:
	    expname = "slot_illegal_instruction";
	    break;
	case 0x800:
	    expname = "fpu_disable";
	    break;
	case 0x820:
	    expname = "slot_fpu";
	    break;
	case 0x100:
	    expname = "data_write";
	    break;
	case 0x060:
	    expname = "dtlb_miss_write";
	    break;
	case 0x0c0:
	    expname = "dtlb_violation_write";
	    break;
	case 0x120:
	    expname = "fpu_exception";
	    break;
	case 0x080:
	    expname = "initial_page_write";
	    break;
	case 0x160:
	    expname = "trapa";
	    break;
	default:
            expname = do_irq ? "interrupt" : "???";
            break;
	}
	fprintf(logfile, "exception 0x%03x [%s] raised\n",
		irq_vector, expname);
	cpu_dump_state(env, logfile, fprintf, 0);
    }

    env->ssr = env->sr;
    env->spc = env->pc;
    env->sgr = env->gregs[15];
    env->sr |= SR_BL | SR_MD | SR_RB;

    if (do_exp) {
        env->expevt = env->exception_index;
        switch (env->exception_index) {
        case 0x000:
        case 0x020:
        case 0x140:
            env->sr &= ~SR_FD;
            env->sr |= 0xf << 4; /* IMASK */
            env->pc = 0xa0000000;
            break;
        case 0x040:
        case 0x060:
            env->pc = env->vbr + 0x400;
            break;
        case 0x160:
            env->spc += 2; /* special case for TRAPA */
            /* fall through */
        default:
            env->pc = env->vbr + 0x100;
            break;
        }
        return;
    }

    if (do_irq) {
        env->intevt = irq_vector;
        env->pc = env->vbr + 0x600;
        return;
    }
}

static void update_itlb_use(CPUState * env, int itlbnb)
{
    uint8_t or_mask = 0, and_mask = (uint8_t) - 1;

    switch (itlbnb) {
    case 0:
	and_mask = 0x7f;
	break;
    case 1:
	and_mask = 0xe7;
	or_mask = 0x80;
	break;
    case 2:
	and_mask = 0xfb;
	or_mask = 0x50;
	break;
    case 3:
	or_mask = 0x2c;
	break;
    }

    env->mmucr &= (and_mask << 24);
    env->mmucr |= (or_mask << 24);
}

static int itlb_replacement(CPUState * env)
{
    if ((env->mmucr & 0xe0000000) == 0xe0000000)
	return 0;
    if ((env->mmucr & 0x98000000) == 0x08000000)
	return 1;
    if ((env->mmucr & 0x54000000) == 0x04000000)
	return 2;
    if ((env->mmucr & 0x2c000000) == 0x00000000)
	return 3;
    assert(0);
}

/* Find the corresponding entry in the right TLB
   Return entry, MMU_DTLB_MISS or MMU_DTLB_MULTIPLE
*/
static int find_tlb_entry(CPUState * env, target_ulong address,
			  tlb_t * entries, uint8_t nbtlb, int use_asid)
{
    int match = MMU_DTLB_MISS;
    uint32_t start, end;
    uint8_t asid;
    int i;

    asid = env->pteh & 0xff;

    for (i = 0; i < nbtlb; i++) {
	if (!entries[i].v)
	    continue;		/* Invalid entry */
	if (use_asid && entries[i].asid != asid && !entries[i].sh)
	    continue;		/* Bad ASID */
#if 0
	switch (entries[i].sz) {
	case 0:
	    size = 1024;	/* 1kB */
	    break;
	case 1:
	    size = 4 * 1024;	/* 4kB */
	    break;
	case 2:
	    size = 64 * 1024;	/* 64kB */
	    break;
	case 3:
	    size = 1024 * 1024;	/* 1MB */
	    break;
	default:
	    assert(0);
	}
#endif
	start = (entries[i].vpn << 10) & ~(entries[i].size - 1);
	end = start + entries[i].size - 1;
	if (address >= start && address <= end) {	/* Match */
	    if (match != -1)
		return MMU_DTLB_MULTIPLE;	/* Multiple match */
	    match = i;
	}
    }
    return match;
}

/* Find itlb entry - update itlb from utlb if necessary and asked for
   Return entry, MMU_ITLB_MISS, MMU_ITLB_MULTIPLE or MMU_DTLB_MULTIPLE
   Update the itlb from utlb if update is not 0
*/
int find_itlb_entry(CPUState * env, target_ulong address,
		    int use_asid, int update)
{
    int e, n;

    e = find_tlb_entry(env, address, env->itlb, ITLB_SIZE, use_asid);
    if (e == MMU_DTLB_MULTIPLE)
	e = MMU_ITLB_MULTIPLE;
    else if (e == MMU_DTLB_MISS && update) {
	e = find_tlb_entry(env, address, env->utlb, UTLB_SIZE, use_asid);
	if (e >= 0) {
	    n = itlb_replacement(env);
	    env->itlb[n] = env->utlb[e];
	    e = n;
	}
    }
    if (e >= 0)
	update_itlb_use(env, e);
    return e;
}

/* Find utlb entry
   Return entry, MMU_DTLB_MISS, MMU_DTLB_MULTIPLE */
int find_utlb_entry(CPUState * env, target_ulong address, int use_asid)
{
    uint8_t urb, urc;

    /* Increment URC */
    urb = ((env->mmucr) >> 18) & 0x3f;
    urc = ((env->mmucr) >> 10) & 0x3f;
    urc++;
    if (urc == urb || urc == UTLB_SIZE - 1)
	urc = 0;
    env->mmucr = (env->mmucr & 0xffff03ff) | (urc << 10);

    /* Return entry */
    return find_tlb_entry(env, address, env->utlb, UTLB_SIZE, use_asid);
}

/* Match address against MMU
   Return MMU_OK, MMU_DTLB_MISS_READ, MMU_DTLB_MISS_WRITE,
   MMU_DTLB_INITIAL_WRITE, MMU_DTLB_VIOLATION_READ,
   MMU_DTLB_VIOLATION_WRITE, MMU_ITLB_MISS,
   MMU_ITLB_MULTIPLE, MMU_ITLB_VIOLATION
*/
static int get_mmu_address(CPUState * env, target_ulong * physical,
			   int *prot, target_ulong address,
			   int rw, int access_type)
{
    int use_asid, is_code, n;
    tlb_t *matching = NULL;

    use_asid = (env->mmucr & MMUCR_SV) == 0 && (env->sr & SR_MD) == 0;
    is_code = env->pc == address;	/* Hack */

    /* Use a hack to find if this is an instruction or data access */
    if (env->pc == address && !(rw & PAGE_WRITE)) {
	n = find_itlb_entry(env, address, use_asid, 1);
	if (n >= 0) {
	    matching = &env->itlb[n];
	    if ((env->sr & SR_MD) & !(matching->pr & 2))
		n = MMU_ITLB_VIOLATION;
	    else
		*prot = PAGE_READ;
	}
    } else {
	n = find_utlb_entry(env, address, use_asid);
	if (n >= 0) {
	    matching = &env->utlb[n];
	    switch ((matching->pr << 1) | ((env->sr & SR_MD) ? 1 : 0)) {
	    case 0:		/* 000 */
	    case 2:		/* 010 */
		n = (rw & PAGE_WRITE) ? MMU_DTLB_VIOLATION_WRITE :
		    MMU_DTLB_VIOLATION_READ;
		break;
	    case 1:		/* 001 */
	    case 4:		/* 100 */
	    case 5:		/* 101 */
		if (rw & PAGE_WRITE)
		    n = MMU_DTLB_VIOLATION_WRITE;
		else
		    *prot = PAGE_READ;
		break;
	    case 3:		/* 011 */
	    case 6:		/* 110 */
	    case 7:		/* 111 */
		*prot = rw & (PAGE_READ | PAGE_WRITE);
		break;
	    }
	} else if (n == MMU_DTLB_MISS) {
	    n = (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
		MMU_DTLB_MISS_READ;
	}
    }
    if (n >= 0) {
	*physical = ((matching->ppn << 10) & ~(matching->size - 1)) |
	    (address & (matching->size - 1));
	if ((rw & PAGE_WRITE) & !matching->d)
	    n = MMU_DTLB_INITIAL_WRITE;
	else
	    n = MMU_OK;
    }
    return n;
}

int get_physical_address(CPUState * env, target_ulong * physical,
			 int *prot, target_ulong address,
			 int rw, int access_type)
{
    /* P1, P2 and P4 areas do not use translation */
    if ((address >= 0x80000000 && address < 0xc0000000) ||
	address >= 0xe0000000) {
	if (!(env->sr & SR_MD)
	    && (address < 0xe0000000 || address > 0xe4000000)) {
	    /* Unauthorized access in user mode (only store queues are available) */
	    fprintf(stderr, "Unauthorized access\n");
	    return (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
		MMU_DTLB_MISS_READ;
	}
	/* Mask upper 3 bits */
	*physical = address & 0x1FFFFFFF;
	*prot = PAGE_READ | PAGE_WRITE;
	return MMU_OK;
    }

    /* If MMU is disabled, return the corresponding physical page */
    if (!env->mmucr & MMUCR_AT) {
	*physical = address & 0x1FFFFFFF;
	*prot = PAGE_READ | PAGE_WRITE;
	return MMU_OK;
    }

    /* We need to resort to the MMU */
    return get_mmu_address(env, physical, prot, address, rw, access_type);
}

int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
			     int mmu_idx, int is_softmmu)
{
    target_ulong physical, page_offset, page_size;
    int prot, ret, access_type;

    /* XXXXX */
#if 0
    fprintf(stderr, "%s pc %08x ad %08x rw %d mmu_idx %d smmu %d\n",
	    __func__, env->pc, address, rw, mmu_idx, is_softmmu);
#endif

    access_type = ACCESS_INT;
    ret =
	get_physical_address(env, &physical, &prot, address, rw,
			     access_type);

    if (ret != MMU_OK) {
	env->tea = address;
	switch (ret) {
	case MMU_ITLB_MISS:
	case MMU_DTLB_MISS_READ:
	    env->exception_index = 0x040;
	    break;
	case MMU_DTLB_MULTIPLE:
	case MMU_ITLB_MULTIPLE:
	    env->exception_index = 0x140;
	    break;
	case MMU_ITLB_VIOLATION:
	    env->exception_index = 0x0a0;
	    break;
	case MMU_DTLB_MISS_WRITE:
	    env->exception_index = 0x060;
	    break;
	case MMU_DTLB_INITIAL_WRITE:
	    env->exception_index = 0x080;
	    break;
	case MMU_DTLB_VIOLATION_READ:
	    env->exception_index = 0x0a0;
	    break;
	case MMU_DTLB_VIOLATION_WRITE:
	    env->exception_index = 0x0c0;
	    break;
	default:
	    assert(0);
	}
	return 1;
    }

    page_size = TARGET_PAGE_SIZE;
    page_offset =
	(address - (address & TARGET_PAGE_MASK)) & ~(page_size - 1);
    address = (address & TARGET_PAGE_MASK) + page_offset;
    physical = (physical & TARGET_PAGE_MASK) + page_offset;

    return tlb_set_page(env, address, physical, prot, mmu_idx, is_softmmu);
}

target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
{
    target_ulong physical;
    int prot;

    get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
    return physical;
}

#endif
