/*
 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
 *
 * Author: Yu Liu, yu.liu@freescale.com
 *
 * Description:
 * This file is based on arch/powerpc/kvm/44x_tlb.h,
 * by Hollis Blanchard <hollisb@us.ibm.com>.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 */

#ifndef __KVM_E500_TLB_H__
#define __KVM_E500_TLB_H__

#include <linux/kvm_host.h>
#include <asm/mmu-book3e.h>
#include <asm/tlb.h>
#include <asm/kvm_e500.h>

#define KVM_E500_TLB0_WAY_SIZE_BIT	7	/* Fixed */
#define KVM_E500_TLB0_WAY_SIZE		(1UL << KVM_E500_TLB0_WAY_SIZE_BIT)
#define KVM_E500_TLB0_WAY_SIZE_MASK	(KVM_E500_TLB0_WAY_SIZE - 1)

#define KVM_E500_TLB0_WAY_NUM_BIT	1	/* No greater than 7 */
#define KVM_E500_TLB0_WAY_NUM		(1UL << KVM_E500_TLB0_WAY_NUM_BIT)
#define KVM_E500_TLB0_WAY_NUM_MASK	(KVM_E500_TLB0_WAY_NUM - 1)

#define KVM_E500_TLB0_SIZE  (KVM_E500_TLB0_WAY_SIZE * KVM_E500_TLB0_WAY_NUM)
#define KVM_E500_TLB1_SIZE  16

#define index_of(tlbsel, esel)	(((tlbsel) << 16) | ((esel) & 0xFFFF))
#define tlbsel_of(index)	((index) >> 16)
#define esel_of(index)		((index) & 0xFFFF)

#define E500_TLB_USER_PERM_MASK (MAS3_UX|MAS3_UR|MAS3_UW)
#define E500_TLB_SUPER_PERM_MASK (MAS3_SX|MAS3_SR|MAS3_SW)
#define MAS2_ATTRIB_MASK \
	  (MAS2_X0 | MAS2_X1)
#define MAS3_ATTRIB_MASK \
	  (MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3 \
	   | E500_TLB_USER_PERM_MASK | E500_TLB_SUPER_PERM_MASK)

extern void kvmppc_dump_tlbs(struct kvm_vcpu *);
extern int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *, ulong);
extern int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *);
extern int kvmppc_e500_emul_tlbre(struct kvm_vcpu *);
extern int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *, int, int);
extern int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *, int);
extern int kvmppc_e500_tlb_search(struct kvm_vcpu *, gva_t, unsigned int, int);
extern void kvmppc_e500_tlb_put(struct kvm_vcpu *);
extern void kvmppc_e500_tlb_load(struct kvm_vcpu *, int);
extern int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *);
extern void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *);
extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *);
extern void kvmppc_e500_recalc_shadow_pid(struct kvmppc_vcpu_e500 *);

/* TLB helper functions */
static inline unsigned int get_tlb_size(const struct tlbe *tlbe)
{
	return (tlbe->mas1 >> 7) & 0x1f;
}

static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
{
	return tlbe->mas2 & 0xfffff000;
}

static inline u64 get_tlb_bytes(const struct tlbe *tlbe)
{
	unsigned int pgsize = get_tlb_size(tlbe);
	return 1ULL << 10 << pgsize;
}

static inline gva_t get_tlb_end(const struct tlbe *tlbe)
{
	u64 bytes = get_tlb_bytes(tlbe);
	return get_tlb_eaddr(tlbe) + bytes - 1;
}

static inline u64 get_tlb_raddr(const struct tlbe *tlbe)
{
	u64 rpn = tlbe->mas7;
	return (rpn << 32) | (tlbe->mas3 & 0xfffff000);
}

static inline unsigned int get_tlb_tid(const struct tlbe *tlbe)
{
	return (tlbe->mas1 >> 16) & 0xff;
}

static inline unsigned int get_tlb_ts(const struct tlbe *tlbe)
{
	return (tlbe->mas1 >> 12) & 0x1;
}

static inline unsigned int get_tlb_v(const struct tlbe *tlbe)
{
	return (tlbe->mas1 >> 31) & 0x1;
}

static inline unsigned int get_tlb_iprot(const struct tlbe *tlbe)
{
	return (tlbe->mas1 >> 30) & 0x1;
}

static inline unsigned int get_cur_pid(struct kvm_vcpu *vcpu)
{
	return vcpu->arch.pid & 0xff;
}

static inline unsigned int get_cur_as(struct kvm_vcpu *vcpu)
{
	return !!(vcpu->arch.shared->msr & (MSR_IS | MSR_DS));
}

static inline unsigned int get_cur_pr(struct kvm_vcpu *vcpu)
{
	return !!(vcpu->arch.shared->msr & MSR_PR);
}

static inline unsigned int get_cur_spid(
		const struct kvmppc_vcpu_e500 *vcpu_e500)
{
	return (vcpu_e500->mas6 >> 16) & 0xff;
}

static inline unsigned int get_cur_sas(
		const struct kvmppc_vcpu_e500 *vcpu_e500)
{
	return vcpu_e500->mas6 & 0x1;
}

static inline unsigned int get_tlb_tlbsel(
		const struct kvmppc_vcpu_e500 *vcpu_e500)
{
	/*
	 * Manual says that tlbsel has 2 bits wide.
	 * Since we only have two TLBs, only lower bit is used.
	 */
	return (vcpu_e500->mas0 >> 28) & 0x1;
}

static inline unsigned int get_tlb_nv_bit(
		const struct kvmppc_vcpu_e500 *vcpu_e500)
{
	return vcpu_e500->mas0 & 0xfff;
}

static inline unsigned int get_tlb_esel_bit(
		const struct kvmppc_vcpu_e500 *vcpu_e500)
{
	return (vcpu_e500->mas0 >> 16) & 0xfff;
}

static inline unsigned int get_tlb_esel(
		const struct kvmppc_vcpu_e500 *vcpu_e500,
		int tlbsel)
{
	unsigned int esel = get_tlb_esel_bit(vcpu_e500);

	if (tlbsel == 0) {
		esel &= KVM_E500_TLB0_WAY_NUM_MASK;
		esel |= ((vcpu_e500->mas2 >> 12) & KVM_E500_TLB0_WAY_SIZE_MASK)
				<< KVM_E500_TLB0_WAY_NUM_BIT;
	} else {
		esel &= KVM_E500_TLB1_SIZE - 1;
	}

	return esel;
}

static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
			const struct tlbe *tlbe)
{
	gpa_t gpa;

	if (!get_tlb_v(tlbe))
		return 0;

	/* Does it match current guest AS? */
	/* XXX what about IS != DS? */
	if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS))
		return 0;

	gpa = get_tlb_raddr(tlbe);
	if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT))
		/* Mapping is not for RAM. */
		return 0;

	return 1;
}

#endif /* __KVM_E500_TLB_H__ */
