#ifndef __ASM_IA64_KVM_H
#define __ASM_IA64_KVM_H

/*
 * asm-ia64/kvm.h: kvm structure definitions  for ia64
 *
 * 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 <asm/types.h>

#include <linux/ioctl.h>

/* Architectural interrupt line count. */
#define KVM_NR_INTERRUPTS 256

#define KVM_IOAPIC_NUM_PINS  48

struct kvm_ioapic_state {
	__u64 base_address;
	__u32 ioregsel;
	__u32 id;
	__u32 irr;
	__u32 pad;
	union {
		__u64 bits;
		struct {
			__u8 vector;
			__u8 delivery_mode:3;
			__u8 dest_mode:1;
			__u8 delivery_status:1;
			__u8 polarity:1;
			__u8 remote_irr:1;
			__u8 trig_mode:1;
			__u8 mask:1;
			__u8 reserve:7;
			__u8 reserved[4];
			__u8 dest_id;
		} fields;
	} redirtbl[KVM_IOAPIC_NUM_PINS];
};

#define KVM_IRQCHIP_PIC_MASTER   0
#define KVM_IRQCHIP_PIC_SLAVE    1
#define KVM_IRQCHIP_IOAPIC       2

#define KVM_CONTEXT_SIZE	8*1024

struct kvm_fpreg {
	union {
		unsigned long bits[2];
		long double __dummy;	/* force 16-byte alignment */
	} u;
};

union context {
	/* 8K size */
	char	dummy[KVM_CONTEXT_SIZE];
	struct {
		unsigned long       psr;
		unsigned long       pr;
		unsigned long       caller_unat;
		unsigned long       pad;
		unsigned long       gr[32];
		unsigned long       ar[128];
		unsigned long       br[8];
		unsigned long       cr[128];
		unsigned long       rr[8];
		unsigned long       ibr[8];
		unsigned long       dbr[8];
		unsigned long       pkr[8];
		struct kvm_fpreg   fr[128];
	};
};

struct thash_data {
	union {
		struct {
			unsigned long p    :  1; /* 0 */
			unsigned long rv1  :  1; /* 1 */
			unsigned long ma   :  3; /* 2-4 */
			unsigned long a    :  1; /* 5 */
			unsigned long d    :  1; /* 6 */
			unsigned long pl   :  2; /* 7-8 */
			unsigned long ar   :  3; /* 9-11 */
			unsigned long ppn  : 38; /* 12-49 */
			unsigned long rv2  :  2; /* 50-51 */
			unsigned long ed   :  1; /* 52 */
			unsigned long ig1  : 11; /* 53-63 */
		};
		struct {
			unsigned long __rv1 : 53;     /* 0-52 */
			unsigned long contiguous : 1; /*53 */
			unsigned long tc : 1;         /* 54 TR or TC */
			unsigned long cl : 1;
			/* 55 I side or D side cache line */
			unsigned long len  :  4;      /* 56-59 */
			unsigned long io  : 1;	/* 60 entry is for io or not */
			unsigned long nomap : 1;
			/* 61 entry cann't be inserted into machine TLB.*/
			unsigned long checked : 1;
			/* 62 for VTLB/VHPT sanity check */
			unsigned long invalid : 1;
			/* 63 invalid entry */
		};
		unsigned long page_flags;
	};                  /* same for VHPT and TLB */

	union {
		struct {
			unsigned long rv3  :  2;
			unsigned long ps   :  6;
			unsigned long key  : 24;
			unsigned long rv4  : 32;
		};
		unsigned long itir;
	};
	union {
		struct {
			unsigned long ig2  :  12;
			unsigned long vpn  :  49;
			unsigned long vrn  :   3;
		};
		unsigned long ifa;
		unsigned long vadr;
		struct {
			unsigned long tag  :  63;
			unsigned long ti   :  1;
		};
		unsigned long etag;
	};
	union {
		struct thash_data *next;
		unsigned long rid;
		unsigned long gpaddr;
	};
};

#define	NITRS	8
#define NDTRS	8

struct saved_vpd {
	unsigned long  vhpi;
	unsigned long  vgr[16];
	unsigned long  vbgr[16];
	unsigned long  vnat;
	unsigned long  vbnat;
	unsigned long  vcpuid[5];
	unsigned long  vpsr;
	unsigned long  vpr;
	unsigned long  vcr[128];
};

struct kvm_regs {
	char *saved_guest;
	char *saved_stack;
	struct saved_vpd vpd;
	/*Arch-regs*/
	int mp_state;
	unsigned long vmm_rr;
	/* TR and TC.  */
	struct thash_data itrs[NITRS];
	struct thash_data dtrs[NDTRS];
	/* Bit is set if there is a tr/tc for the region.  */
	unsigned char itr_regions;
	unsigned char dtr_regions;
	unsigned char tc_regions;

	char irq_check;
	unsigned long saved_itc;
	unsigned long itc_check;
	unsigned long timer_check;
	unsigned long timer_pending;
	unsigned long last_itc;

	unsigned long vrr[8];
	unsigned long ibr[8];
	unsigned long dbr[8];
	unsigned long insvc[4];		/* Interrupt in service.  */
	unsigned long xtp;

	unsigned long metaphysical_rr0; /* from kvm_arch (so is pinned) */
	unsigned long metaphysical_rr4;	/* from kvm_arch (so is pinned) */
	unsigned long metaphysical_saved_rr0; /* from kvm_arch          */
	unsigned long metaphysical_saved_rr4; /* from kvm_arch          */
	unsigned long fp_psr;       /*used for lazy float register */
	unsigned long saved_gp;
	/*for phycial  emulation */
};

struct kvm_sregs {
};

struct kvm_fpu {
};

#endif
