/*
 * Copyright 2012 Michael Ellerman, IBM Corporation.
 * Copyright 2012 Benjamin Herrenschmidt, IBM Corporation
 *
 * 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_PPC_BOOK3S_XICS_H
#define _KVM_PPC_BOOK3S_XICS_H

/*
 * We use a two-level tree to store interrupt source information.
 * There are up to 1024 ICS nodes, each of which can represent
 * 1024 sources.
 */
#define KVMPPC_XICS_MAX_ICS_ID	1023
#define KVMPPC_XICS_ICS_SHIFT	10
#define KVMPPC_XICS_IRQ_PER_ICS	(1 << KVMPPC_XICS_ICS_SHIFT)
#define KVMPPC_XICS_SRC_MASK	(KVMPPC_XICS_IRQ_PER_ICS - 1)

/*
 * Interrupt source numbers below this are reserved, for example
 * 0 is "no interrupt", and 2 is used for IPIs.
 */
#define KVMPPC_XICS_FIRST_IRQ	16
#define KVMPPC_XICS_NR_IRQS	((KVMPPC_XICS_MAX_ICS_ID + 1) * \
				 KVMPPC_XICS_IRQ_PER_ICS)

/* Priority value to use for disabling an interrupt */
#define MASKED	0xff

/* State for one irq source */
struct ics_irq_state {
	u32 number;
	u32 server;
	u8  priority;
	u8  saved_priority;
	u8  resend;
	u8  masked_pending;
	u8  asserted; /* Only for LSI */
	u8  exists;
};

/* Atomic ICP state, updated with a single compare & swap */
union kvmppc_icp_state {
	unsigned long raw;
	struct {
		u8 out_ee:1;
		u8 need_resend:1;
		u8 cppr;
		u8 mfrr;
		u8 pending_pri;
		u32 xisr;
	};
};

/* One bit per ICS */
#define ICP_RESEND_MAP_SIZE	(KVMPPC_XICS_MAX_ICS_ID / BITS_PER_LONG + 1)

struct kvmppc_icp {
	struct kvm_vcpu *vcpu;
	unsigned long server_num;
	union kvmppc_icp_state state;
	unsigned long resend_map[ICP_RESEND_MAP_SIZE];

	/* Real mode might find something too hard, here's the action
	 * it might request from virtual mode
	 */
#define XICS_RM_KICK_VCPU	0x1
#define XICS_RM_CHECK_RESEND	0x2
#define XICS_RM_REJECT		0x4
#define XICS_RM_NOTIFY_EOI	0x8
	u32 rm_action;
	struct kvm_vcpu *rm_kick_target;
	struct kvmppc_icp *rm_resend_icp;
	u32  rm_reject;
	u32  rm_eoied_irq;

	/* Debug stuff for real mode */
	union kvmppc_icp_state rm_dbgstate;
	struct kvm_vcpu *rm_dbgtgt;
};

struct kvmppc_ics {
	struct mutex lock;
	u16 icsid;
	struct ics_irq_state irq_state[KVMPPC_XICS_IRQ_PER_ICS];
};

struct kvmppc_xics {
	struct kvm *kvm;
	struct kvm_device *dev;
	struct dentry *dentry;
	u32 max_icsid;
	bool real_mode;
	bool real_mode_dbg;
	struct kvmppc_ics *ics[KVMPPC_XICS_MAX_ICS_ID + 1];
};

static inline struct kvmppc_icp *kvmppc_xics_find_server(struct kvm *kvm,
							 u32 nr)
{
	struct kvm_vcpu *vcpu = NULL;
	int i;

	kvm_for_each_vcpu(i, vcpu, kvm) {
		if (vcpu->arch.icp && nr == vcpu->arch.icp->server_num)
			return vcpu->arch.icp;
	}
	return NULL;
}

static inline struct kvmppc_ics *kvmppc_xics_find_ics(struct kvmppc_xics *xics,
						      u32 irq, u16 *source)
{
	u32 icsid = irq >> KVMPPC_XICS_ICS_SHIFT;
	u16 src = irq & KVMPPC_XICS_SRC_MASK;
	struct kvmppc_ics *ics;

	if (source)
		*source = src;
	if (icsid > KVMPPC_XICS_MAX_ICS_ID)
		return NULL;
	ics = xics->ics[icsid];
	if (!ics)
		return NULL;
	return ics;
}


#endif /* _KVM_PPC_BOOK3S_XICS_H */
