/*
 * PAL/SAL call delegation
 *
 * Copyright (c) 2004 Li Susie <susie.li@intel.com>
 * Copyright (c) 2005 Yu Ke <ke.yu@intel.com>
 * Copyright (c) 2007 Xiantao Zhang <xiantao.zhang@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 */

#include <linux/kvm_host.h>
#include <linux/smp.h>

#include "vti.h"
#include "misc.h"

#include <asm/pal.h>
#include <asm/sal.h>
#include <asm/tlb.h>

/*
 * Handy macros to make sure that the PAL return values start out
 * as something meaningful.
 */
#define INIT_PAL_STATUS_UNIMPLEMENTED(x)		\
	{						\
		x.status = PAL_STATUS_UNIMPLEMENTED;	\
		x.v0 = 0;				\
		x.v1 = 0;				\
		x.v2 = 0;				\
	}

#define INIT_PAL_STATUS_SUCCESS(x)			\
	{						\
		x.status = PAL_STATUS_SUCCESS;		\
		x.v0 = 0;				\
		x.v1 = 0;				\
		x.v2 = 0;				\
    }

static void kvm_get_pal_call_data(struct kvm_vcpu *vcpu,
		u64 *gr28, u64 *gr29, u64 *gr30, u64 *gr31) {
	struct exit_ctl_data *p;

	if (vcpu) {
		p = &vcpu->arch.exit_data;
		if (p->exit_reason == EXIT_REASON_PAL_CALL) {
			*gr28 = p->u.pal_data.gr28;
			*gr29 = p->u.pal_data.gr29;
			*gr30 = p->u.pal_data.gr30;
			*gr31 = p->u.pal_data.gr31;
			return ;
		}
	}
	printk(KERN_DEBUG"Failed to get vcpu pal data!!!\n");
}

static void set_pal_result(struct kvm_vcpu *vcpu,
		struct ia64_pal_retval result) {

	struct exit_ctl_data *p;

	p = kvm_get_exit_data(vcpu);
	if (p && p->exit_reason == EXIT_REASON_PAL_CALL) {
		p->u.pal_data.ret = result;
		return ;
	}
	INIT_PAL_STATUS_UNIMPLEMENTED(p->u.pal_data.ret);
}

static void set_sal_result(struct kvm_vcpu *vcpu,
		struct sal_ret_values result) {
	struct exit_ctl_data *p;

	p = kvm_get_exit_data(vcpu);
	if (p && p->exit_reason == EXIT_REASON_SAL_CALL) {
		p->u.sal_data.ret = result;
		return ;
	}
	printk(KERN_WARNING"Failed to set sal result!!\n");
}

struct cache_flush_args {
	u64 cache_type;
	u64 operation;
	u64 progress;
	long status;
};

cpumask_t cpu_cache_coherent_map;

static void remote_pal_cache_flush(void *data)
{
	struct cache_flush_args *args = data;
	long status;
	u64 progress = args->progress;

	status = ia64_pal_cache_flush(args->cache_type, args->operation,
					&progress, NULL);
	if (status != 0)
	args->status = status;
}

static struct ia64_pal_retval pal_cache_flush(struct kvm_vcpu *vcpu)
{
	u64 gr28, gr29, gr30, gr31;
	struct ia64_pal_retval result = {0, 0, 0, 0};
	struct cache_flush_args args = {0, 0, 0, 0};
	long psr;

	gr28 = gr29 = gr30 = gr31 = 0;
	kvm_get_pal_call_data(vcpu, &gr28, &gr29, &gr30, &gr31);

	if (gr31 != 0)
		printk(KERN_ERR"vcpu:%p called cache_flush error!\n", vcpu);

	/* Always call Host Pal in int=1 */
	gr30 &= ~PAL_CACHE_FLUSH_CHK_INTRS;
	args.cache_type = gr29;
	args.operation = gr30;
	smp_call_function(remote_pal_cache_flush,
				(void *)&args, 1);
	if (args.status != 0)
		printk(KERN_ERR"pal_cache_flush error!,"
				"status:0x%lx\n", args.status);
	/*
	 * Call Host PAL cache flush
	 * Clear psr.ic when call PAL_CACHE_FLUSH
	 */
	local_irq_save(psr);
	result.status = ia64_pal_cache_flush(gr29, gr30, &result.v1,
						&result.v0);
	local_irq_restore(psr);
	if (result.status != 0)
		printk(KERN_ERR"vcpu:%p crashed due to cache_flush err:%ld"
				"in1:%lx,in2:%lx\n",
				vcpu, result.status, gr29, gr30);

#if 0
	if (gr29 == PAL_CACHE_TYPE_COHERENT) {
		cpus_setall(vcpu->arch.cache_coherent_map);
		cpu_clear(vcpu->cpu, vcpu->arch.cache_coherent_map);
		cpus_setall(cpu_cache_coherent_map);
		cpu_clear(vcpu->cpu, cpu_cache_coherent_map);
	}
#endif
	return result;
}

struct ia64_pal_retval pal_cache_summary(struct kvm_vcpu *vcpu)
{

	struct ia64_pal_retval result;

	PAL_CALL(result, PAL_CACHE_SUMMARY, 0, 0, 0);
	return result;
}

static struct ia64_pal_retval pal_freq_base(struct kvm_vcpu *vcpu)
{

	struct ia64_pal_retval result;

	PAL_CALL(result, PAL_FREQ_BASE, 0, 0, 0);

	/*
	 * PAL_FREQ_BASE may not be implemented in some platforms,
	 * call SAL instead.
	 */
	if (result.v0 == 0) {
		result.status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM,
							&result.v0,
							&result.v1);
		result.v2 = 0;
	}

	return result;
}

static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu)
{

	struct ia64_pal_retval result;

	PAL_CALL(result, PAL_FREQ_RATIOS, 0, 0, 0);
	return result;
}

static struct ia64_pal_retval pal_logical_to_physica(struct kvm_vcpu *vcpu)
{
	struct ia64_pal_retval result;

	INIT_PAL_STATUS_UNIMPLEMENTED(result);
	return result;
}

static struct ia64_pal_retval pal_platform_addr(struct kvm_vcpu *vcpu)
{

	struct ia64_pal_retval result;

	INIT_PAL_STATUS_SUCCESS(result);
	return result;
}

static struct ia64_pal_retval pal_proc_get_features(struct kvm_vcpu *vcpu)
{

	struct ia64_pal_retval result = {0, 0, 0, 0};
	long in0, in1, in2, in3;

	kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
	result.status = ia64_pal_proc_get_features(&result.v0, &result.v1,
			&result.v2, in2);

	return result;
}

static struct ia64_pal_retval pal_cache_info(struct kvm_vcpu *vcpu)
{

	pal_cache_config_info_t ci;
	long status;
	unsigned long in0, in1, in2, in3, r9, r10;

	kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
	status = ia64_pal_cache_config_info(in1, in2, &ci);
	r9 = ci.pcci_info_1.pcci1_data;
	r10 = ci.pcci_info_2.pcci2_data;
	return ((struct ia64_pal_retval){status, r9, r10, 0});
}

#define GUEST_IMPL_VA_MSB	59
#define GUEST_RID_BITS		18

static struct ia64_pal_retval pal_vm_summary(struct kvm_vcpu *vcpu)
{

	pal_vm_info_1_u_t vminfo1;
	pal_vm_info_2_u_t vminfo2;
	struct ia64_pal_retval result;

	PAL_CALL(result, PAL_VM_SUMMARY, 0, 0, 0);
	if (!result.status) {
		vminfo1.pvi1_val = result.v0;
		vminfo1.pal_vm_info_1_s.max_itr_entry = 8;
		vminfo1.pal_vm_info_1_s.max_dtr_entry = 8;
		result.v0 = vminfo1.pvi1_val;
		vminfo2.pal_vm_info_2_s.impl_va_msb = GUEST_IMPL_VA_MSB;
		vminfo2.pal_vm_info_2_s.rid_size = GUEST_RID_BITS;
		result.v1 = vminfo2.pvi2_val;
	}

	return result;
}

static struct ia64_pal_retval pal_vm_info(struct kvm_vcpu *vcpu)
{
	struct ia64_pal_retval result;

	INIT_PAL_STATUS_UNIMPLEMENTED(result);

	return result;
}

static  u64 kvm_get_pal_call_index(struct kvm_vcpu *vcpu)
{
	u64 index = 0;
	struct exit_ctl_data *p;

	p = kvm_get_exit_data(vcpu);
	if (p && (p->exit_reason == EXIT_REASON_PAL_CALL))
		index = p->u.pal_data.gr28;

	return index;
}

int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run)
{

	u64 gr28;
	struct ia64_pal_retval result;
	int ret = 1;

	gr28 = kvm_get_pal_call_index(vcpu);
	/*printk("pal_call index:%lx\n",gr28);*/
	switch (gr28) {
	case PAL_CACHE_FLUSH:
		result = pal_cache_flush(vcpu);
		break;
	case PAL_CACHE_SUMMARY:
		result = pal_cache_summary(vcpu);
		break;
	case PAL_HALT_LIGHT:
	{
		vcpu->arch.timer_pending = 1;
		INIT_PAL_STATUS_SUCCESS(result);
		if (kvm_highest_pending_irq(vcpu) == -1)
			ret = kvm_emulate_halt(vcpu);

	}
		break;

	case PAL_FREQ_RATIOS:
		result = pal_freq_ratios(vcpu);
		break;

	case PAL_FREQ_BASE:
		result = pal_freq_base(vcpu);
		break;

	case PAL_LOGICAL_TO_PHYSICAL :
		result = pal_logical_to_physica(vcpu);
		break;

	case PAL_VM_SUMMARY :
		result = pal_vm_summary(vcpu);
		break;

	case PAL_VM_INFO :
		result = pal_vm_info(vcpu);
		break;
	case PAL_PLATFORM_ADDR :
		result = pal_platform_addr(vcpu);
		break;
	case PAL_CACHE_INFO:
		result = pal_cache_info(vcpu);
		break;
	case PAL_PTCE_INFO:
		INIT_PAL_STATUS_SUCCESS(result);
		result.v1 = (1L << 32) | 1L;
		break;
	case PAL_VM_PAGE_SIZE:
		result.status = ia64_pal_vm_page_size(&result.v0,
							&result.v1);
		break;
	case PAL_RSE_INFO:
		result.status = ia64_pal_rse_info(&result.v0,
					(pal_hints_u_t *)&result.v1);
		break;
	case PAL_PROC_GET_FEATURES:
		result = pal_proc_get_features(vcpu);
		break;
	case PAL_DEBUG_INFO:
		result.status = ia64_pal_debug_info(&result.v0,
							&result.v1);
		break;
	case PAL_VERSION:
		result.status = ia64_pal_version(
				(pal_version_u_t *)&result.v0,
				(pal_version_u_t *)&result.v1);

		break;
	case PAL_FIXED_ADDR:
		result.status = PAL_STATUS_SUCCESS;
		result.v0 = vcpu->vcpu_id;
		break;
	default:
		INIT_PAL_STATUS_UNIMPLEMENTED(result);
		printk(KERN_WARNING"kvm: Unsupported pal call,"
					" index:0x%lx\n", gr28);
	}
	set_pal_result(vcpu, result);
	return ret;
}

static struct sal_ret_values sal_emulator(struct kvm *kvm,
				long index, unsigned long in1,
				unsigned long in2, unsigned long in3,
				unsigned long in4, unsigned long in5,
				unsigned long in6, unsigned long in7)
{
	unsigned long r9  = 0;
	unsigned long r10 = 0;
	long r11 = 0;
	long status;

	status = 0;
	switch (index) {
	case SAL_FREQ_BASE:
		status = ia64_sal_freq_base(in1, &r9, &r10);
		break;
	case SAL_PCI_CONFIG_READ:
		printk(KERN_WARNING"kvm: Not allowed to call here!"
			" SAL_PCI_CONFIG_READ\n");
		break;
	case SAL_PCI_CONFIG_WRITE:
		printk(KERN_WARNING"kvm: Not allowed to call here!"
			" SAL_PCI_CONFIG_WRITE\n");
		break;
	case SAL_SET_VECTORS:
		if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {
			if (in4 != 0 || in5 != 0 || in6 != 0 || in7 != 0) {
				status = -2;
			} else {
				kvm->arch.rdv_sal_data.boot_ip = in2;
				kvm->arch.rdv_sal_data.boot_gp = in3;
			}
			printk("Rendvous called! iip:%lx\n\n", in2);
		} else
			printk(KERN_WARNING"kvm: CALLED SAL_SET_VECTORS %lu."
							"ignored...\n", in1);
		break;
	case SAL_GET_STATE_INFO:
		/* No more info.  */
		status = -5;
		r9 = 0;
		break;
	case SAL_GET_STATE_INFO_SIZE:
		/* Return a dummy size.  */
		status = 0;
		r9 = 128;
		break;
	case SAL_CLEAR_STATE_INFO:
		/* Noop.  */
		break;
	case SAL_MC_RENDEZ:
		printk(KERN_WARNING
			"kvm: called SAL_MC_RENDEZ. ignored...\n");
		break;
	case SAL_MC_SET_PARAMS:
		printk(KERN_WARNING
			"kvm: called  SAL_MC_SET_PARAMS.ignored!\n");
		break;
	case SAL_CACHE_FLUSH:
		if (1) {
			/*Flush using SAL.
			This method is faster but has a side
			effect on other vcpu running on
			this cpu.  */
			status = ia64_sal_cache_flush(in1);
		} else {
			/*Maybe need to implement the method
			without side effect!*/
			status = 0;
		}
		break;
	case SAL_CACHE_INIT:
		printk(KERN_WARNING
			"kvm: called SAL_CACHE_INIT.  ignored...\n");
		break;
	case SAL_UPDATE_PAL:
		printk(KERN_WARNING
			"kvm: CALLED SAL_UPDATE_PAL.  ignored...\n");
		break;
	default:
		printk(KERN_WARNING"kvm: called SAL_CALL with unknown index."
						" index:%ld\n", index);
		status = -1;
		break;
	}
	return ((struct sal_ret_values) {status, r9, r10, r11});
}

static void kvm_get_sal_call_data(struct kvm_vcpu *vcpu, u64 *in0, u64 *in1,
		u64 *in2, u64 *in3, u64 *in4, u64 *in5, u64 *in6, u64 *in7){

	struct exit_ctl_data *p;

	p = kvm_get_exit_data(vcpu);

	if (p) {
		if (p->exit_reason == EXIT_REASON_SAL_CALL) {
			*in0 = p->u.sal_data.in0;
			*in1 = p->u.sal_data.in1;
			*in2 = p->u.sal_data.in2;
			*in3 = p->u.sal_data.in3;
			*in4 = p->u.sal_data.in4;
			*in5 = p->u.sal_data.in5;
			*in6 = p->u.sal_data.in6;
			*in7 = p->u.sal_data.in7;
			return ;
		}
	}
	*in0 = 0;
}

void kvm_sal_emul(struct kvm_vcpu *vcpu)
{

	struct sal_ret_values result;
	u64 index, in1, in2, in3, in4, in5, in6, in7;

	kvm_get_sal_call_data(vcpu, &index, &in1, &in2,
			&in3, &in4, &in5, &in6, &in7);
	result = sal_emulator(vcpu->kvm, index, in1, in2, in3,
					in4, in5, in6, in7);
	set_sal_result(vcpu, result);
}
