Commit 3c19d5ad authored by Michael Ellerman's avatar Michael Ellerman
Browse files

Merge branch 'topic/xive' (early part) into next

This merges the arch part of the XIVE support, leaving the final commit
with the KVM specific pieces dangling on the branch for Paul to merge
via the kvm-ppc tree.
parents 17ed4c8f 08a1e650
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -55,6 +55,14 @@
#define PPC_BITEXTRACT(bits, ppc_bit, dst_bit)			\
#define PPC_BITEXTRACT(bits, ppc_bit, dst_bit)			\
	((((bits) >> PPC_BITLSHIFT(ppc_bit)) & 1) << (dst_bit))
	((((bits) >> PPC_BITLSHIFT(ppc_bit)) & 1) << (dst_bit))


#define PPC_BITLSHIFT32(be)	(32 - 1 - (be))
#define PPC_BIT32(bit)		(1UL << PPC_BITLSHIFT32(bit))
#define PPC_BITMASK32(bs, be)	((PPC_BIT32(bs) - PPC_BIT32(be))|PPC_BIT32(bs))

#define PPC_BITLSHIFT8(be)	(8 - 1 - (be))
#define PPC_BIT8(bit)		(1UL << PPC_BITLSHIFT8(bit))
#define PPC_BITMASK8(bs, be)	((PPC_BIT8(bs) - PPC_BIT8(be))|PPC_BIT8(bs))

#include <asm/barrier.h>
#include <asm/barrier.h>


/* Macro for generating the ***_bits() functions */
/* Macro for generating the ***_bits() functions */
+51 −47
Original line number Original line Diff line number Diff line
@@ -192,24 +192,8 @@ DEF_MMIO_OUT_D(out_le32, 32, stw);


#endif /* __BIG_ENDIAN */
#endif /* __BIG_ENDIAN */


/*
 * Cache inhibitied accessors for use in real mode, you don't want to use these
 * unless you know what you're doing.
 *
 * NB. These use the cpu byte ordering.
 */
DEF_MMIO_OUT_X(out_rm8,   8, stbcix);
DEF_MMIO_OUT_X(out_rm16, 16, sthcix);
DEF_MMIO_OUT_X(out_rm32, 32, stwcix);
DEF_MMIO_IN_X(in_rm8,   8, lbzcix);
DEF_MMIO_IN_X(in_rm16, 16, lhzcix);
DEF_MMIO_IN_X(in_rm32, 32, lwzcix);

#ifdef __powerpc64__
#ifdef __powerpc64__


DEF_MMIO_OUT_X(out_rm64, 64, stdcix);
DEF_MMIO_IN_X(in_rm64, 64, ldcix);

#ifdef __BIG_ENDIAN__
#ifdef __BIG_ENDIAN__
DEF_MMIO_OUT_D(out_be64, 64, std);
DEF_MMIO_OUT_D(out_be64, 64, std);
DEF_MMIO_IN_D(in_be64, 64, ld);
DEF_MMIO_IN_D(in_be64, 64, ld);
@@ -242,35 +226,6 @@ static inline void out_be64(volatile u64 __iomem *addr, u64 val)
#endif
#endif
#endif /* __powerpc64__ */
#endif /* __powerpc64__ */



/*
 * Simple Cache inhibited accessors
 * Unlike the DEF_MMIO_* macros, these don't include any h/w memory
 * barriers, callers need to manage memory barriers on their own.
 * These can only be used in hypervisor real mode.
 */

static inline u32 _lwzcix(unsigned long addr)
{
	u32 ret;

	__asm__ __volatile__("lwzcix %0,0, %1"
			     : "=r" (ret) : "r" (addr) : "memory");
	return ret;
}

static inline void _stbcix(u64 addr, u8 val)
{
	__asm__ __volatile__("stbcix %0,0,%1"
		: : "r" (val), "r" (addr) : "memory");
}

static inline void _stwcix(u64 addr, u32 val)
{
	__asm__ __volatile__("stwcix %0,0,%1"
		: : "r" (val), "r" (addr) : "memory");
}

/*
/*
 * Low level IO stream instructions are defined out of line for now
 * Low level IO stream instructions are defined out of line for now
 */
 */
@@ -417,15 +372,64 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
}
}


/*
/*
 * Real mode version of the above. stdcix is only supposed to be used
 * Real mode versions of the above. Those instructions are only supposed
 * in hypervisor real mode as per the architecture spec.
 * to be used in hypervisor real mode as per the architecture spec.
 */
 */
static inline void __raw_rm_writeb(u8 val, volatile void __iomem *paddr)
{
	__asm__ __volatile__("stbcix %0,0,%1"
		: : "r" (val), "r" (paddr) : "memory");
}

static inline void __raw_rm_writew(u16 val, volatile void __iomem *paddr)
{
	__asm__ __volatile__("sthcix %0,0,%1"
		: : "r" (val), "r" (paddr) : "memory");
}

static inline void __raw_rm_writel(u32 val, volatile void __iomem *paddr)
{
	__asm__ __volatile__("stwcix %0,0,%1"
		: : "r" (val), "r" (paddr) : "memory");
}

static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
{
{
	__asm__ __volatile__("stdcix %0,0,%1"
	__asm__ __volatile__("stdcix %0,0,%1"
		: : "r" (val), "r" (paddr) : "memory");
		: : "r" (val), "r" (paddr) : "memory");
}
}


static inline u8 __raw_rm_readb(volatile void __iomem *paddr)
{
	u8 ret;
	__asm__ __volatile__("lbzcix %0,0, %1"
			     : "=r" (ret) : "r" (paddr) : "memory");
	return ret;
}

static inline u16 __raw_rm_readw(volatile void __iomem *paddr)
{
	u16 ret;
	__asm__ __volatile__("lhzcix %0,0, %1"
			     : "=r" (ret) : "r" (paddr) : "memory");
	return ret;
}

static inline u32 __raw_rm_readl(volatile void __iomem *paddr)
{
	u32 ret;
	__asm__ __volatile__("lwzcix %0,0, %1"
			     : "=r" (ret) : "r" (paddr) : "memory");
	return ret;
}

static inline u64 __raw_rm_readq(volatile void __iomem *paddr)
{
	u64 ret;
	__asm__ __volatile__("ldcix %0,0, %1"
			     : "=r" (ret) : "r" (paddr) : "memory");
	return ret;
}
#endif /* __powerpc64__ */
#endif /* __powerpc64__ */


/*
/*
+1 −1
Original line number Original line Diff line number Diff line
@@ -110,7 +110,7 @@ struct kvmppc_host_state {
	u8 ptid;
	u8 ptid;
	struct kvm_vcpu *kvm_vcpu;
	struct kvm_vcpu *kvm_vcpu;
	struct kvmppc_vcore *kvm_vcore;
	struct kvmppc_vcore *kvm_vcore;
	unsigned long xics_phys;
	void __iomem *xics_phys;
	u32 saved_xirr;
	u32 saved_xirr;
	u64 dabr;
	u64 dabr;
	u64 host_mmcr[7];	/* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */
	u64 host_mmcr[7];	/* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */
+1 −9
Original line number Original line Diff line number Diff line
@@ -409,7 +409,7 @@ struct openpic;
extern void kvm_cma_reserve(void) __init;
extern void kvm_cma_reserve(void) __init;
static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
{
{
	paca[cpu].kvm_hstate.xics_phys = addr;
	paca[cpu].kvm_hstate.xics_phys = (void __iomem *)addr;
}
}


static inline u32 kvmppc_get_xics_latch(void)
static inline u32 kvmppc_get_xics_latch(void)
@@ -478,8 +478,6 @@ extern void kvmppc_free_host_rm_ops(void);
extern void kvmppc_free_pimap(struct kvm *kvm);
extern void kvmppc_free_pimap(struct kvm *kvm);
extern int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall);
extern int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall);
extern void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu);
extern void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu);
extern int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu, unsigned long server);
extern int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args);
extern int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd);
extern int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd);
extern u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu);
extern u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu);
extern int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval);
extern int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval);
@@ -507,12 +505,6 @@ static inline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)
static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)
	{ return 0; }
	{ return 0; }
static inline void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) { }
static inline void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) { }
static inline int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu,
					 unsigned long server)
	{ return -EINVAL; }
static inline int kvm_vm_ioctl_xics_irq(struct kvm *kvm,
					struct kvm_irq_level *args)
	{ return -ENOTTY; }
static inline int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
static inline int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
	{ return 0; }
	{ return 0; }
#endif
#endif
+72 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,8 @@
#define OPAL_I2C_ARBT_LOST	-22
#define OPAL_I2C_ARBT_LOST	-22
#define OPAL_I2C_NACK_RCVD	-23
#define OPAL_I2C_NACK_RCVD	-23
#define OPAL_I2C_STOP_ERR	-24
#define OPAL_I2C_STOP_ERR	-24
#define OPAL_XIVE_PROVISIONING	-31
#define OPAL_XIVE_FREE_ACTIVE	-32


/* API Tokens (in r0) */
/* API Tokens (in r0) */
#define OPAL_INVALID_CALL		       -1
#define OPAL_INVALID_CALL		       -1
@@ -168,6 +170,23 @@
#define OPAL_INT_SET_MFRR			125
#define OPAL_INT_SET_MFRR			125
#define OPAL_PCI_TCE_KILL			126
#define OPAL_PCI_TCE_KILL			126
#define OPAL_NMMU_SET_PTCR			127
#define OPAL_NMMU_SET_PTCR			127
#define OPAL_XIVE_RESET				128
#define OPAL_XIVE_GET_IRQ_INFO			129
#define OPAL_XIVE_GET_IRQ_CONFIG		130
#define OPAL_XIVE_SET_IRQ_CONFIG		131
#define OPAL_XIVE_GET_QUEUE_INFO		132
#define OPAL_XIVE_SET_QUEUE_INFO		133
#define OPAL_XIVE_DONATE_PAGE			134
#define OPAL_XIVE_ALLOCATE_VP_BLOCK		135
#define OPAL_XIVE_FREE_VP_BLOCK			136
#define OPAL_XIVE_GET_VP_INFO			137
#define OPAL_XIVE_SET_VP_INFO			138
#define OPAL_XIVE_ALLOCATE_IRQ			139
#define OPAL_XIVE_FREE_IRQ			140
#define OPAL_XIVE_SYNC				141
#define OPAL_XIVE_DUMP				142
#define OPAL_XIVE_RESERVED3			143
#define OPAL_XIVE_RESERVED4			144
#define OPAL_NPU_INIT_CONTEXT			146
#define OPAL_NPU_INIT_CONTEXT			146
#define OPAL_NPU_DESTROY_CONTEXT		147
#define OPAL_NPU_DESTROY_CONTEXT		147
#define OPAL_NPU_MAP_LPAR			148
#define OPAL_NPU_MAP_LPAR			148
@@ -931,6 +950,59 @@ enum {
	OPAL_PCI_TCE_KILL_ALL,
	OPAL_PCI_TCE_KILL_ALL,
};
};


/* The xive operation mode indicates the active "API" and
 * corresponds to the "mode" parameter of the opal_xive_reset()
 * call
 */
enum {
	OPAL_XIVE_MODE_EMU	= 0,
	OPAL_XIVE_MODE_EXPL	= 1,
};

/* Flags for OPAL_XIVE_GET_IRQ_INFO */
enum {
	OPAL_XIVE_IRQ_TRIGGER_PAGE	= 0x00000001,
	OPAL_XIVE_IRQ_STORE_EOI		= 0x00000002,
	OPAL_XIVE_IRQ_LSI		= 0x00000004,
	OPAL_XIVE_IRQ_SHIFT_BUG		= 0x00000008,
	OPAL_XIVE_IRQ_MASK_VIA_FW	= 0x00000010,
	OPAL_XIVE_IRQ_EOI_VIA_FW	= 0x00000020,
};

/* Flags for OPAL_XIVE_GET/SET_QUEUE_INFO */
enum {
	OPAL_XIVE_EQ_ENABLED		= 0x00000001,
	OPAL_XIVE_EQ_ALWAYS_NOTIFY	= 0x00000002,
	OPAL_XIVE_EQ_ESCALATE		= 0x00000004,
};

/* Flags for OPAL_XIVE_GET/SET_VP_INFO */
enum {
	OPAL_XIVE_VP_ENABLED		= 0x00000001,
};

/* "Any chip" replacement for chip ID for allocation functions */
enum {
	OPAL_XIVE_ANY_CHIP		= 0xffffffff,
};

/* Xive sync options */
enum {
	/* This bits are cumulative, arg is a girq */
	XIVE_SYNC_EAS			= 0x00000001, /* Sync irq source */
	XIVE_SYNC_QUEUE			= 0x00000002, /* Sync irq target */
};

/* Dump options */
enum {
	XIVE_DUMP_TM_HYP	= 0,
	XIVE_DUMP_TM_POOL	= 1,
	XIVE_DUMP_TM_OS		= 2,
	XIVE_DUMP_TM_USER	= 3,
	XIVE_DUMP_VP		= 4,
	XIVE_DUMP_EMU_STATE	= 5,
};

#endif /* __ASSEMBLY__ */
#endif /* __ASSEMBLY__ */


#endif /* __OPAL_API_H */
#endif /* __OPAL_API_H */
Loading