// SPDX-License-Identifier: Apache-2.0
/*
 * XIVE2: eXternal Interrupt Virtualization Engine. POWER10 interrupt
 * controller
 *
 * Copyright (c) 2016-2019, IBM Corporation.
 */

#define pr_fmt(fmt) "XIVE: " fmt

#include <skiboot.h>
#include <slw.h>
#include <xscom.h>
#include <chip.h>
#include <io.h>
#include <xive.h>
#include <xive2-regs.h>
#include <xscom-p10-regs.h>
#include <interrupts.h>
#include <timebase.h>
#include <bitmap.h>
#include <buddy.h>
#include <phys-map.h>
#include <p10_stop_api.H>


/* Verbose debug */
#undef XIVE_VERBOSE_DEBUG

/* Extra debug options used in debug builds */
#ifdef DEBUG
#define XIVE_CHECK_LOCKS
#define XIVE_DEBUG_INIT_CACHE_UPDATES
#define XIVE_EXTRA_CHECK_INIT_CACHE
#else
#undef  XIVE_CHECK_LOCKS
#undef  XIVE_DEBUG_INIT_CACHE_UPDATES
#undef  XIVE_EXTRA_CHECK_INIT_CACHE
#endif

/*
 * VSDs, blocks, set translation etc...
 *
 * For the following data structures, the XIVE use a mechanism called
 * Virtualization Structure Tables (VST) to manage the memory layout
 * and access: ESBs (Event State Buffers), EAS (Event assignment
 * structures), ENDs (Event Notification Descriptors) and NVT/NVP
 * (Notification Virtual Targets/Processors).
 *
 * These structures divide those tables into 16 "blocks". Each XIVE
 * instance has a definition for all 16 blocks that can either represent
 * an actual table in memory or a remote XIVE MMIO port to access a
 * block that is owned by that remote XIVE.
 *
 * Our SW design will consist of allocating one block per chip (and thus
 * per XIVE instance) for now, thus giving us up to 16 supported chips in
 * the system. We may have to revisit that if we ever support systems with
 * more than 16 chips but that isn't on our radar at the moment or if we
 * want to do like pHyp on some machines and dedicate 2 blocks per chip
 * for some structures.
 *
 * Thus we need to be careful that we never expose to Linux the concept
 * of block and block boundaries, but instead we provide full number ranges
 * so that consecutive blocks can be supported.
 *
 * Similarily, for MMIO access, the BARs support what is called "set
 * translation" which allows the BAR to be devided into a certain
 * number of sets. Each "set" can be routed to a specific block and
 * offset within a block.
 */

#define XIVE_MAX_BLOCKS		16
#define XIVE_VSD_SIZE		8

/*
 * Max number of ESBs. (direct table)
 *
 * The max number of ESBs supported in the P10 MMIO space is 1TB/128K: 8M.
 *
 * 1M is our current top limit of ESB entries and EAS entries
 * pre-allocated per chip. That allocates 256KB per chip for the state
 * bits and 8M per chip for the EAS.
 */

#define XIVE_INT_ORDER		20 /* 1M interrupts */
#define XIVE_INT_COUNT		(1ul << XIVE_INT_ORDER)

/*
 * First interrupt number, also the first logical interrupt number
 * allocated by Linux (maximum ISA interrupt number + 1)
 */
#define XIVE_INT_FIRST		0x10

/* Corresponding direct table sizes */
#define XIVE_ESB_SIZE		(XIVE_INT_COUNT / 4)
#define XIVE_EAT_SIZE		(XIVE_INT_COUNT * 8)

/* Use 64K for everything by default */
#define XIVE_ESB_SHIFT		(16 + 1) /* trigger + mgmt pages */
#define XIVE_ESB_PAGE_SIZE     (1ul << XIVE_ESB_SHIFT) /* 2 pages */

/*
 * Max number of ENDs. (indirect table)
 *
 * The max number of ENDs supported in the P10 MMIO space is 2TB/128K: 16M.
 * Since one END is 32 bytes, a 64K indirect subpage can hold 2K ENDs.
 * We need 8192 subpages, ie, 64K of memory for the indirect table.
 */
#define END_PER_PAGE		(PAGE_SIZE / sizeof(struct xive_end))

#define XIVE_END_ORDER		23 /* 8M ENDs */
#define XIVE_END_COUNT		(1ul << XIVE_END_ORDER)
#define XIVE_END_TABLE_SIZE	((XIVE_END_COUNT / END_PER_PAGE) * XIVE_VSD_SIZE)

#define XIVE_END_SHIFT		(16 + 1) /* ESn + ESe pages */

/* One bit per number of priorities configured */
#define xive_end_bitmap_size(x)	(XIVE_END_COUNT >> xive_cfg_vp_prio_shift(x))

/* Number of priorities (and thus ENDs) we allocate for each VP */
#define xive_cfg_vp_prio_shift(x) GETFIELD(CQ_XIVE_CFG_VP_INT_PRIO, (x)->config)
#define xive_cfg_vp_prio(x)	(1 << xive_cfg_vp_prio_shift(x))

/* Max priority number */
#define xive_max_prio(x)	(xive_cfg_vp_prio(x) - 1)

/* Priority used for gather/silent escalation (KVM) */
#define xive_escalation_prio(x)	xive_max_prio(x)

/*
 * Max number of VPs. (indirect table)
 *
 * The max number of NVPs we support in our MMIO space is 1TB/128K: 8M.
 * Since one NVP is 32 bytes, a 64K indirect subpage can hold 2K NVPs.
 * We need 4096 pointers, ie, 32K of memory for the indirect table.
 *
 * However, we use 8 priorities (by default) per NVP and the number of
 * ENDs is configured to 8M. Therefore, our VP space is limited to 1M.
 */
#define VP_PER_PAGE		(PAGE_SIZE / sizeof(struct xive_nvp))

#define XIVE_VP_ORDER(x)	(XIVE_END_ORDER - xive_cfg_vp_prio_shift(x))
#define XIVE_VP_COUNT(x)	(1ul << XIVE_VP_ORDER(x))
#define XIVE_VP_TABLE_SIZE(x)	((XIVE_VP_COUNT(x) / VP_PER_PAGE) * XIVE_VSD_SIZE)

#define XIVE_NVP_SHIFT		17 /* NVPG BAR: two pages, even NVP, odd NVG */

/* VP Space maximums in Gen1 and Gen2 modes */
#define VP_SHIFT_GEN1		19	/* in sync with END_W6_VP_OFFSET_GEN1 */
#define VP_SHIFT_GEN2		24	/* in sync with END_W6_VP_OFFSET */

/*
 * VP ids for HW threads.
 *
 * Depends on the thread id bits configuration of the IC. 8bit is the
 * default for P10 and 7bit for p9.
 *
 * These values are global because they should be common to all chips
 */
static uint32_t xive_threadid_shift;
static uint32_t	xive_hw_vp_base;
static uint32_t xive_hw_vp_count;

/*
 * The XIVE operation mode indicates the active "API" and corresponds
 * to the "version/mode" parameter of the opal_xive_reset() call
 */
static enum {
	/* No XICS emulation */
	XIVE_MODE_EXPL	= OPAL_XIVE_MODE_EXPL, /* default */
	XIVE_MODE_NONE,
} xive_mode = XIVE_MODE_NONE;

/*
 * The XIVE exploitation mode options indicates the active features and
 * is part of the mode parameter of the opal_xive_reset() call
 */
static uint64_t xive_expl_options;

#define XIVE_EXPL_ALL_OPTIONS 0

/*
 * Each source controller has one of these. There's one embedded in
 * the XIVE struct for IPIs
 */
struct xive_src {
	struct irq_source		is;
	const struct irq_source_ops	*orig_ops;
	struct xive			*xive;
	void				*esb_mmio;
	uint32_t			esb_base;
	uint32_t			esb_shift;
	uint32_t			flags;
};

struct xive_cpu_state {
	struct xive	*xive;
	void		*tm_ring1;

	/* Base HW VP and associated queues */
	uint32_t	vp_blk;
	uint32_t	vp_idx;
	uint32_t	end_blk;
	uint32_t	end_idx; /* Base end index of a block of 8 */

	struct lock	lock;
};

enum xive_generation {
	XIVE_GEN1 = 1, /* P9 compat mode */
	XIVE_GEN2 = 2, /* P10 default */
};

enum xive_quirks {
	/* HW527671 - 8bits Hardwired Thread Id range not implemented */
	XIVE_QUIRK_THREADID_7BITS	= 0x00000001,
	/* HW542974 - interrupt command priority checker not working properly */
	XIVE_QUIRK_BROKEN_PRIO_CHECK	= 0x00000002,
};

struct xive {
	uint32_t		 chip_id;
	uint32_t		 block_id;
	struct dt_node		*x_node;

	enum xive_generation	 generation;
	uint64_t		 capabilities;
	uint64_t		 config;

	uint64_t		 xscom_base;

	/* MMIO regions */
	void			*ic_base;
	uint64_t		 ic_size;
	uint32_t		 ic_shift;
	void			*ic_tm_direct_base;

	void			*tm_base;
	uint64_t		 tm_size;
	uint32_t		 tm_shift;
	void			*nvp_base;
	uint64_t		 nvp_size;
	void			*esb_base;
	uint64_t		 esb_size;
	void			*end_base;
	uint64_t		 end_size;

	/* Set on XSCOM register access error */
	bool			 last_reg_error;

	/* Per-XIVE mutex */
	struct lock		 lock;

	/* Pre-allocated tables.
	 *
	 * We setup all the VDS for actual tables (ie, by opposition to
	 * forwarding ports) as either direct pre-allocated or indirect
	 * and partially populated.
	 *
	 * Currently, the ESB and the EAS tables are direct and fully
	 * pre-allocated based on XIVE_INT_COUNT.
	 *
	 * The other tables are indirect, we thus pre-allocate the indirect
	 * table (ie, pages of pointers) and populate enough of the pages
	 * for our basic setup using 64K subpages.
	 *
	 * The size of the indirect tables are driven by XIVE_VP_COUNT
	 * and XIVE_END_COUNT. The number of pre-allocated ones are
	 * driven by xive_hw_vp_count for the HW threads. The number
	 * of END depends on number of VP.
	 */

	/* Direct SBE and EAT tables */
	void			*sbe_base;
	void			*eat_base;

	/* Indirect END table. NULL entries are unallocated, count is
	 * the numbre of pointers (ie, sub page placeholders).
	 */
	beint64_t		*end_ind_base;
	uint32_t		 end_ind_count;
	uint64_t 		 end_ind_size;

	/* END allocation bitmap. Each bit represent #priority ENDs */
	bitmap_t		*end_map;

	/* Indirect NVT/VP table. NULL entries are unallocated, count is
	 * the numbre of pointers (ie, sub page placeholders).
	 */
	beint64_t		*vp_ind_base;
	uint32_t		 vp_ind_count;
	uint64_t 		 vp_ind_size;

	/* VP space size. Depends on Gen1/2 mode */
	uint32_t		 vp_shift;

	/* Pool of donated pages for provisioning indirect END and VP pages */
	struct list_head	 donated_pages;

	/* To ease a possible change to supporting more than one block of
	 * interrupts per chip, we store here the "base" global number
	 * and max number of interrupts for this chip. The global number
	 * encompass the block number and index.
	 */
	uint32_t		 int_base;
	uint32_t		 int_count;

	/* Due to the overlap between IPIs and HW sources in the EAS table,
	 * we keep some kind of top-down allocator. It is used for HW sources
	 * to "allocate" interrupt entries and will limit what can be handed
	 * out as IPIs. Of course this assumes we "allocate" all HW sources
	 * before we start handing out IPIs.
	 *
	 * Note: The numbers here are global interrupt numbers so that we can
	 * potentially handle more than one block per chip in the future.
	 */
	uint32_t		 int_hw_bot;	/* Bottom of HW allocation */
	uint32_t		 int_ipi_top;	/* Highest IPI handed out so far + 1 */

	/* The IPI allocation bitmap */
	bitmap_t		*ipi_alloc_map;

	/* We keep track of which interrupts were ever enabled to
	 * speed up xive_reset
	 */
	bitmap_t		*int_enabled_map;

	/* Embedded source IPIs */
	struct xive_src		 ipis;

	/* Embedded escalation interrupts */
	struct xive_src		 esc_irqs;

	/* In memory queue overflow */
	void			*q_ovf;

	/* Cache/sync injection */
	uint64_t		 sync_inject_size;
	void			*sync_inject;

	/* INT HW Errata */
	uint64_t		quirks;
};

/* First XIVE unit configured on the system */
static struct xive *one_xive;

/* Global DT node */
static struct dt_node *xive_dt_node;

/* Block <-> Chip conversions.
 *
 * As chipIDs may not be within the range of 16 block IDs supported by XIVE,
 * we have a 2 way conversion scheme.
 *
 * From block to chip, use the global table below.
 *
 * From chip to block, a field in struct proc_chip contains the first block
 * of that chip. For now we only support one block per chip but that might
 * change in the future
 */
#define XIVE_INVALID_CHIP	0xffffffff
#define XIVE_MAX_CHIPS		16
static uint32_t xive_block_to_chip[XIVE_MAX_CHIPS];
static uint32_t xive_block_count;

static uint32_t xive_chip_to_block(uint32_t chip_id)
{
	struct proc_chip *c = get_chip(chip_id);

	assert(c);
	assert(c->xive);
	return c->xive->block_id;
}

/*
 * Conversion between GIRQ and block/index.
 *
 * ------------------------------------
 * |000E|BLOC|                   INDEX|
 * ------------------------------------
 *   4     4           24
 *
 * the E bit indicates that this is an escalation interrupt, in
 * that case, the BLOC/INDEX represents the END containing the
 * corresponding escalation descriptor.
 *
 * Global interrupt numbers for non-escalation interrupts are thus
 * limited to 28 bits.
 */

#define INT_SHIFT		24
#define INT_ESC_SHIFT		(INT_SHIFT + 4) /* 4bits block id */

#if XIVE_INT_ORDER > INT_SHIFT
#error "Too many ESBs for IRQ encoding"
#endif

#if XIVE_END_ORDER > INT_SHIFT
#error "Too many ENDs for escalation IRQ number encoding"
#endif

#define GIRQ_TO_BLK(__g)	(((__g) >> INT_SHIFT) & 0xf)
#define GIRQ_TO_IDX(__g)	((__g) & ((1 << INT_SHIFT) - 1))
#define BLKIDX_TO_GIRQ(__b,__i)	(((uint32_t)(__b)) << INT_SHIFT | (__i))

#define GIRQ_IS_ESCALATION(__g)	((__g) & (1 << INT_ESC_SHIFT))
#define MAKE_ESCALATION_GIRQ(__b,__i)(BLKIDX_TO_GIRQ(__b,__i) | (1 << INT_ESC_SHIFT))


/* Block/IRQ to chip# conversions */
#define PC_BLK_TO_CHIP(__b)	(xive_block_to_chip[__b])
#define VC_BLK_TO_CHIP(__b)	(xive_block_to_chip[__b])
#define GIRQ_TO_CHIP(__isn)	(VC_BLK_TO_CHIP(GIRQ_TO_BLK(__isn)))

/* Routing of physical processors to VPs */
#define PIR2VP_IDX( __pir)	(xive_hw_vp_base | P10_PIR2LOCALCPU(__pir))
#define PIR2VP_BLK(__pir)	(xive_chip_to_block(P10_PIR2GCID(__pir)))
#define VP2PIR(__blk, __idx)	(P10_PIRFROMLOCALCPU(VC_BLK_TO_CHIP(__blk), (__idx) & 0xff))

/* Decoding of OPAL API VP IDs. The VP IDs are encoded as follow
 *
 * Block group mode:
 *
 * -----------------------------------
 * |GVEOOOOO|                   INDEX|
 * -----------------------------------
 *  ||   |
 *  ||  Order
 *  |Virtual
 *  Group
 *
 * G (Group)   : Set to 1 for a group VP (not currently supported)
 * V (Virtual) : Set to 1 for an allocated VP (vs. a physical processor ID)
 * E (Error)   : Should never be 1, used internally for errors
 * O (Order)   : Allocation order of the VP block
 *
 * The conversion is thus done as follow (groups aren't implemented yet)
 *
 *  If V=0, O must be 0 and 24-bit INDEX value is the PIR
 *  If V=1, the order O group is allocated such that if N is the number of
 *          chip bits considered for allocation (*)
 *          then the INDEX is constructed as follow (bit numbers such as 0=LSB)
 *           - bottom O-N bits is the index within the "VP block"
 *           - next N bits is the XIVE blockID of the VP
 *           - the remaining bits is the per-chip "base"
 *          so the conversion consists of "extracting" the block ID and moving
 *          down the upper bits by N bits.
 *
 * In non-block-group mode, the difference is that the blockID is
 * on the left of the index (the entire VP block is in a single
 * block ID)
 */

#define VP_GROUP_SHIFT		31
#define VP_VIRTUAL_SHIFT	30
#define VP_ERROR_SHIFT		29
#define VP_ORDER_SHIFT		24

#define vp_group(vp)		(((vp) >> VP_GROUP_SHIFT) & 1)
#define vp_virtual(vp) 		(((vp) >> VP_VIRTUAL_SHIFT) & 1)
#define vp_order(vp)		(((vp) >> VP_ORDER_SHIFT) & 0x1f)
#define vp_index(vp)		((vp) & ((1 << VP_ORDER_SHIFT) - 1))

/* VP allocation */
static uint32_t xive_chips_alloc_bits = 0;
static struct buddy *xive_vp_buddy;
static struct lock xive_buddy_lock = LOCK_UNLOCKED;

/* VP# decoding/encoding */
static bool xive_decode_vp(uint32_t vp, uint32_t *blk, uint32_t *idx,
			   uint8_t *order, bool *group)
{
	uint32_t o = vp_order(vp);
	uint32_t n = xive_chips_alloc_bits;
	uint32_t index = vp_index(vp);
	uint32_t imask = (1 << (o - n)) - 1;

	/* Groups not supported yet */
	if (vp_group(vp))
		return false;
	if (group)
		*group = false;

	/* PIR case */
	if (!vp_virtual(vp)) {
		if (find_cpu_by_pir(index) == NULL)
			return false;
		if (blk)
			*blk = PIR2VP_BLK(index);
		if (idx)
			*idx = PIR2VP_IDX(index);
		return true;
	}

	/* Ensure o > n, we have *at least* 2 VPs per block */
	if (o <= n)
		return false;

	/* Combine the index base and index */
	if (idx)
		*idx = ((index >> n) & ~imask) | (index & imask);
	/* Extract block ID */
	if (blk)
		*blk = (index >> (o - n)) & ((1 << n) - 1);

	/* Return order as well if asked for */
	if (order)
		*order = o;

	return true;
}

static uint32_t xive_encode_vp(uint32_t blk, uint32_t idx, uint32_t order)
{
	uint32_t vp = (1 << VP_VIRTUAL_SHIFT) | (order << VP_ORDER_SHIFT);
	uint32_t n = xive_chips_alloc_bits;
	uint32_t imask = (1 << (order - n)) - 1;

	vp |= (idx & ~imask) << n;
	vp |= blk << (order - n);
	vp |= idx & imask;
	return  vp;
}

/*
 * XSCOM/MMIO helpers
 */
#define XIVE_NO_MMIO -1

#define xive_regw(__x, __r, __v) \
	__xive_regw(__x, __r, X_##__r, __v, #__r)
#define xive_regr(__x, __r) \
	__xive_regr(__x, __r, X_##__r, #__r)
#define xive_regwx(__x, __r, __v) \
	__xive_regw(__x, XIVE_NO_MMIO, X_##__r, __v, #__r)
#define xive_regrx(__x, __r) \
	__xive_regr(__x, XIVE_NO_MMIO, X_##__r, #__r)

#ifdef XIVE_VERBOSE_DEBUG
#define xive_vdbg(__x,__fmt,...)	prlog(PR_DEBUG,"[ IC %02x  ] " __fmt, (__x)->chip_id, ##__VA_ARGS__)
#define xive_cpu_vdbg(__c,__fmt,...)	prlog(PR_DEBUG,"[CPU %04x] " __fmt, (__c)->pir, ##__VA_ARGS__)
#else
#define xive_vdbg(x,fmt,...)		do { } while(0)
#define xive_cpu_vdbg(x,fmt,...)	do { } while(0)
#endif

#define xive_dbg(__x,__fmt,...)		prlog(PR_DEBUG,"[ IC %02x  ] " __fmt, (__x)->chip_id, ##__VA_ARGS__)
#define xive_cpu_dbg(__c,__fmt,...)	prlog(PR_DEBUG,"[CPU %04x] " __fmt, (__c)->pir, ##__VA_ARGS__)
#define xive_notice(__x,__fmt,...)	prlog(PR_NOTICE,"[ IC %02x  ] " __fmt, (__x)->chip_id, ##__VA_ARGS__)
#define xive_cpu_notice(__c,__fmt,...)	prlog(PR_NOTICE,"[CPU %04x] " __fmt, (__c)->pir, ##__VA_ARGS__)
#define xive_warn(__x,__fmt,...)	prlog(PR_WARNING,"[ IC %02x  ] " __fmt, (__x)->chip_id, ##__VA_ARGS__)
#define xive_cpu_warn(__c,__fmt,...)	prlog(PR_WARNING,"[CPU %04x] " __fmt, (__c)->pir, ##__VA_ARGS__)
#define xive_err(__x,__fmt,...)		prlog(PR_ERR,"[ IC %02x  ] " __fmt, (__x)->chip_id, ##__VA_ARGS__)
#define xive_cpu_err(__c,__fmt,...)	prlog(PR_ERR,"[CPU %04x] " __fmt, (__c)->pir, ##__VA_ARGS__)

/*
 * The XIVE subengine being accessed can be deduced from the XSCOM
 * reg, and from there, the page offset in the IC BAR.
 */
static void* xive_ic_page(struct xive *x, uint32_t x_reg)
{
	uint64_t pgoff = (x_reg >> 8) & 0x3;

	return x->ic_base + (pgoff << x->ic_shift);
}

static void __xive_regw(struct xive *x, uint32_t m_reg, uint32_t x_reg, uint64_t v,
			const char *rname)
{
	bool use_xscom = (m_reg == XIVE_NO_MMIO) || !x->ic_base;
	int64_t rc;

	x->last_reg_error = false;

	assert(x_reg != 0);

	if (use_xscom) {
		rc = xscom_write(x->chip_id, x->xscom_base + x_reg, v);
		if (rc) {
			if (!rname)
				rname = "???";
			xive_err(x, "Error writing register %s\n", rname);
			/* Anything else we can do here ? */
			x->last_reg_error = true;
		}
	} else {
		out_be64(xive_ic_page(x, x_reg) + m_reg, v);
	}
}

static uint64_t __xive_regr(struct xive *x, uint32_t m_reg, uint32_t x_reg,
			    const char *rname)
{
	bool use_xscom = (m_reg == XIVE_NO_MMIO) || !x->ic_base;
	int64_t rc;
	uint64_t val;

	x->last_reg_error = false;

	assert(x_reg != 0);

	if (use_xscom) {
		rc = xscom_read(x->chip_id, x->xscom_base + x_reg, &val);
		if (rc) {
			if (!rname)
				rname = "???";
			xive_err(x, "Error reading register %s\n", rname);
			/* Anything else we can do here ? */
			x->last_reg_error = true;
			return -1ull;
		}
	} else {
		val = in_be64(xive_ic_page(x, x_reg) + m_reg);
	}
	return val;
}

/* Locate a controller from an IRQ number */
static struct xive *xive_from_isn(uint32_t isn)
{
	uint32_t chip_id = GIRQ_TO_CHIP(isn);
	struct proc_chip *c = get_chip(chip_id);

	if (!c)
		return NULL;
	return c->xive;
}

static struct xive *xive_from_pc_blk(uint32_t blk)
{
	uint32_t chip_id = PC_BLK_TO_CHIP(blk);
	struct proc_chip *c = get_chip(chip_id);

	if (!c)
		return NULL;
	return c->xive;
}

static struct xive *xive_from_vc_blk(uint32_t blk)
{
	uint32_t chip_id = VC_BLK_TO_CHIP(blk);
	struct proc_chip *c = get_chip(chip_id);

	if (!c)
		return NULL;
	return c->xive;
}

static struct xive_end *xive_get_end(struct xive *x, unsigned int idx)
{
	struct xive_end *p;

	if (idx >= (x->end_ind_count * END_PER_PAGE))
		return NULL;
	p = (struct xive_end *)(be64_to_cpu(x->end_ind_base[idx / END_PER_PAGE]) &
			       VSD_ADDRESS_MASK);
	if (!p)
		return NULL;

	return &p[idx % END_PER_PAGE];
}

static struct xive_eas *xive_get_eas(struct xive *x, unsigned int isn)
{
	struct xive_eas *eat;
	uint32_t idx = GIRQ_TO_IDX(isn);

	if (GIRQ_IS_ESCALATION(isn)) {
		/* Allright, an escalation EAS is buried inside an END, let's
		 * try to find it
		 */
		struct xive_end *end;

		if (x->chip_id != VC_BLK_TO_CHIP(GIRQ_TO_BLK(isn))) {
			xive_err(x, "%s, ESC ISN 0x%x not on right chip\n",
				 __func__, isn);
			return NULL;
		}
		end = xive_get_end(x, idx);
		if (!end) {
			xive_err(x, "%s, ESC ISN 0x%x END not found\n",
				 __func__, isn);
			return NULL;
		}

		/* If using single-escalation, don't let anybody get
		 * to the individual escalation interrupts
		 */
		if (xive_get_field32(END_W0_UNCOND_ESCALATE, end->w0))
			return NULL;

		/* Grab the escalation END */
		return (struct xive_eas *)(char *)&end->w4;
	} else {
		/* Check the block matches */
		if (isn < x->int_base || isn >= x->int_count) {
			xive_err(x, "%s, ISN 0x%x not on right chip\n",
				 __func__, isn);
			return NULL;
		}
		assert (idx < XIVE_INT_COUNT);

		/* If we support >1 block per chip, this should still
		 * work as we are likely to make the table contiguous
		 * anyway
		 */
		eat = x->eat_base;
		assert(eat);

		return eat + idx;
	}
}

static struct xive_nvp *xive_get_vp(struct xive *x, unsigned int idx)
{
	struct xive_nvp *p;

	assert(idx < (x->vp_ind_count * VP_PER_PAGE));
	p = (struct xive_nvp *)(be64_to_cpu(x->vp_ind_base[idx / VP_PER_PAGE]) &
			       VSD_ADDRESS_MASK);
	if (!p)
		return NULL;

	return &p[idx % VP_PER_PAGE];
}

/*
 * Store the END base of the VP in W5, using the new architected field
 * in P10. Used to be the pressure relief interrupt field on P9.
 */
static void xive_vp_set_end_base(struct xive_nvp *vp,
				 uint32_t end_blk, uint32_t end_idx)
{
	vp->w5 = xive_set_field32(NVP_W5_VP_END_BLOCK, 0, end_blk) |
		xive_set_field32(NVP_W5_VP_END_INDEX, 0, end_idx);

	/* This is the criteria to know if a VP was allocated */
	assert(vp->w5 != 0);
}

static void xive_init_default_vp(struct xive_nvp *vp,
				 uint32_t end_blk, uint32_t end_idx)
{
	memset(vp, 0, sizeof(struct xive_nvp));

	xive_vp_set_end_base(vp, end_blk, end_idx);

	vp->w0 = xive_set_field32(NVP_W0_VALID, 0, 1);
}

/*
 * VPs of the HW threads have their own set of ENDs which is allocated
 * when XIVE is initialized. These are tagged with a FIRMWARE bit so
 * that they can be identified when the driver is reset (kexec).
 */
static void xive_init_hw_end(struct xive_end *end)
{
	memset(end, 0, sizeof(struct xive_end));
	end->w0 = xive_set_field32(END_W0_FIRMWARE1, 0, 1);
}

static void *xive_get_donated_page(struct xive *x)
{
	return (void *)list_pop_(&x->donated_pages, 0);
}

#define XIVE_ALLOC_IS_ERR(_idx)	((_idx) >= 0xfffffff0)

#define XIVE_ALLOC_NO_SPACE	0xffffffff /* No possible space */
#define XIVE_ALLOC_NO_IND	0xfffffffe /* Indirect need provisioning */
#define XIVE_ALLOC_NO_MEM	0xfffffffd /* Local allocation failed */

static uint32_t xive_alloc_end_set(struct xive *x, bool alloc_indirect)
{
	uint32_t ind_idx;
	int idx;
	int end_base_idx;

	xive_vdbg(x, "Allocating END set...\n");

	assert(x->end_map);

	/* Allocate from the END bitmap. Each bit is 8 ENDs */
	idx = bitmap_find_zero_bit(*x->end_map, 0, xive_end_bitmap_size(x));
	if (idx < 0) {
		xive_dbg(x, "Allocation from END bitmap failed !\n");
		return XIVE_ALLOC_NO_SPACE;
	}

	end_base_idx = idx << xive_cfg_vp_prio_shift(x);

	xive_vdbg(x, "Got ENDs 0x%x..0x%x\n", end_base_idx,
		  end_base_idx + xive_max_prio(x));

	/* Calculate the indirect page where the ENDs reside */
	ind_idx = end_base_idx / END_PER_PAGE;

	/* Is there an indirect page ? If not, check if we can provision it */
	if (!x->end_ind_base[ind_idx]) {
		/* Default flags */
		uint64_t vsd_flags = SETFIELD(VSD_TSIZE, 0ull, 4) |
			SETFIELD(VSD_MODE, 0ull, VSD_MODE_EXCLUSIVE);
		void *page;

		/* If alloc_indirect is set, allocate the memory from OPAL own,
		 * otherwise try to provision from the donated pool
		 */
		if (alloc_indirect) {
			/* Allocate/provision indirect page during boot only */
			xive_vdbg(x, "Indirect empty, provisioning from local pool\n");
			page = local_alloc(x->chip_id, PAGE_SIZE, PAGE_SIZE);
			if (!page) {
				xive_dbg(x, "provisioning failed !\n");
				return XIVE_ALLOC_NO_MEM;
			}
			vsd_flags |= VSD_FIRMWARE;
		} else {
			xive_vdbg(x, "Indirect empty, provisioning from donated pages\n");
			page = xive_get_donated_page(x);
			if (!page) {
				xive_vdbg(x, "no idirect pages available !\n");
				return XIVE_ALLOC_NO_IND;
			}
		}
		memset(page, 0, PAGE_SIZE);
		x->end_ind_base[ind_idx] = cpu_to_be64(vsd_flags |
			(((uint64_t)page) & VSD_ADDRESS_MASK));
		/* Any cache scrub needed ? */
	}

	bitmap_set_bit(*x->end_map, idx);
	return end_base_idx;
}

static void xive_free_end_set(struct xive *x, uint32_t ends)
{
	uint32_t idx;
	uint8_t  prio_mask = xive_max_prio(x);

	xive_vdbg(x, "Freeing END 0x%x..0x%x\n", ends, ends + xive_max_prio(x));

	assert((ends & prio_mask) == 0);
	assert(x->end_map);

	idx = ends >> xive_cfg_vp_prio_shift(x);
	bitmap_clr_bit(*x->end_map, idx);
}

static bool xive_provision_vp_ind(struct xive *x, uint32_t vp_idx, uint32_t order)
{
	uint32_t pbase, pend, i;

	pbase = vp_idx / VP_PER_PAGE;
	pend  = (vp_idx + (1 << order)) / VP_PER_PAGE;

	for (i = pbase; i <= pend; i++) {
		void *page;
		u64 vsd;

		/* Already provisioned ? */
		if (x->vp_ind_base[i])
			continue;

		/* Try to grab a donated page */
		page = xive_get_donated_page(x);
		if (!page)
			return false;

		/* Install the page */
		memset(page, 0, PAGE_SIZE);
		vsd = ((uint64_t)page) & VSD_ADDRESS_MASK;
		vsd |= SETFIELD(VSD_TSIZE, 0ull, 4);
		vsd |= SETFIELD(VSD_MODE, 0ull, VSD_MODE_EXCLUSIVE);
		x->vp_ind_base[i] = cpu_to_be64(vsd);
	}
	return true;
}

static void xive_init_vp_allocator(void)
{
	/* Initialize chip alloc bits */
	xive_chips_alloc_bits = ilog2(xive_block_count);

	prlog(PR_INFO, "%d chips considered for VP allocations\n",
	      1 << xive_chips_alloc_bits);

	/* Allocate a buddy big enough for XIVE_VP_ORDER allocations.
	 *
	 * each bit in the buddy represents 1 << xive_chips_alloc_bits
	 * VPs.
	 */
	xive_vp_buddy = buddy_create(XIVE_VP_ORDER(one_xive));
	assert(xive_vp_buddy);

	/*
	 * We reserve the whole range of VP ids representing HW threads.
	 */
	assert(buddy_reserve(xive_vp_buddy, xive_hw_vp_base,
			     xive_threadid_shift));
}

static uint32_t xive_alloc_vps(uint32_t order)
{
	uint32_t local_order, i;
	int vp;

	/* The minimum order is 2 VPs per chip */
	if (order < (xive_chips_alloc_bits + 1))
		order = xive_chips_alloc_bits + 1;

	/* We split the allocation */
	local_order = order - xive_chips_alloc_bits;

	/* We grab that in the global buddy */
	assert(xive_vp_buddy);
	lock(&xive_buddy_lock);
	vp = buddy_alloc(xive_vp_buddy, local_order);
	unlock(&xive_buddy_lock);
	if (vp < 0)
		return XIVE_ALLOC_NO_SPACE;

	/* Provision on every chip considered for allocation */
	for (i = 0; i < (1 << xive_chips_alloc_bits); i++) {
		struct xive *x = xive_from_pc_blk(i);
		bool success;

		/* Return internal error & log rather than assert ? */
		assert(x);
		lock(&x->lock);
		success = xive_provision_vp_ind(x, vp, local_order);
		unlock(&x->lock);
		if (!success) {
			lock(&xive_buddy_lock);
			buddy_free(xive_vp_buddy, vp, local_order);
			unlock(&xive_buddy_lock);
			return XIVE_ALLOC_NO_IND;
		}
	}

	/* Encode the VP number. "blk" is 0 as this represents
	 * all blocks and the allocation always starts at 0
	 */
	return xive_encode_vp(0, vp, order);
}

static void xive_free_vps(uint32_t vp)
{
	uint32_t idx;
	uint8_t order, local_order;

	assert(xive_decode_vp(vp, NULL, &idx, &order, NULL));

	/* We split the allocation */
	local_order = order - xive_chips_alloc_bits;

	/* Free that in the buddy */
	lock(&xive_buddy_lock);
	buddy_free(xive_vp_buddy, idx, local_order);
	unlock(&xive_buddy_lock);
}

enum xive_cache_type {
	xive_cache_easc,
	xive_cache_esbc,
	xive_cache_endc,
	xive_cache_nxc,
};

/*
 * Cache update
 */

#define FLUSH_CTRL_POLL_VALID PPC_BIT(0)  /* POLL bit is the same for all */

static int64_t __xive_cache_scrub(struct xive *x,
				  enum xive_cache_type ctype,
				  uint64_t block, uint64_t idx,
				  bool want_inval __unused, bool want_disable __unused)
{
	uint64_t ctrl_reg, x_ctrl_reg;
	uint64_t poll_val, ctrl_val;

#ifdef XIVE_CHECK_LOCKS
	assert(lock_held_by_me(&x->lock));
#endif
	switch (ctype) {
	case xive_cache_easc:
		poll_val =
			SETFIELD(VC_EASC_FLUSH_POLL_BLOCK_ID, 0ll, block) |
			SETFIELD(VC_EASC_FLUSH_POLL_OFFSET, 0ll, idx) |
			VC_EASC_FLUSH_POLL_BLOCK_ID_MASK |
			VC_EASC_FLUSH_POLL_OFFSET_MASK;
		xive_regw(x, VC_EASC_FLUSH_POLL, poll_val);
		ctrl_reg = VC_EASC_FLUSH_CTRL;
		x_ctrl_reg = X_VC_EASC_FLUSH_CTRL;
		break;
	case xive_cache_esbc:
		poll_val =
			SETFIELD(VC_ESBC_FLUSH_POLL_BLOCK_ID, 0ll, block) |
			SETFIELD(VC_ESBC_FLUSH_POLL_OFFSET, 0ll, idx) |
			VC_ESBC_FLUSH_POLL_BLOCK_ID_MASK |
			VC_ESBC_FLUSH_POLL_OFFSET_MASK;
		xive_regw(x, VC_ESBC_FLUSH_POLL, poll_val);
		ctrl_reg = VC_ESBC_FLUSH_CTRL;
		x_ctrl_reg = X_VC_ESBC_FLUSH_CTRL;
		break;
	case xive_cache_endc:
		poll_val =
			SETFIELD(VC_ENDC_FLUSH_POLL_BLOCK_ID, 0ll, block) |
			SETFIELD(VC_ENDC_FLUSH_POLL_OFFSET, 0ll, idx) |
			VC_ENDC_FLUSH_POLL_BLOCK_ID_MASK |
			VC_ENDC_FLUSH_POLL_OFFSET_MASK;
		xive_regw(x, VC_ENDC_FLUSH_POLL, poll_val);
		ctrl_reg = VC_ENDC_FLUSH_CTRL;
		x_ctrl_reg = X_VC_ENDC_FLUSH_CTRL;
		break;
	case xive_cache_nxc:
		poll_val =
			SETFIELD(PC_NXC_FLUSH_POLL_BLOCK_ID, 0ll, block) |
			SETFIELD(PC_NXC_FLUSH_POLL_OFFSET, 0ll, idx) |
			PC_NXC_FLUSH_POLL_BLOCK_ID_MASK |
			PC_NXC_FLUSH_POLL_OFFSET_MASK;
		xive_regw(x, PC_NXC_FLUSH_POLL, poll_val);
		ctrl_reg = PC_NXC_FLUSH_CTRL;
		x_ctrl_reg = X_PC_NXC_FLUSH_CTRL;
		break;
	default:
		return OPAL_INTERNAL_ERROR;
	}

	/* XXX Add timeout !!! */
	for (;;) {
		ctrl_val = __xive_regr(x, ctrl_reg, x_ctrl_reg, NULL);
		if (!(ctrl_val & FLUSH_CTRL_POLL_VALID))
			break;
		/* Small delay */
		time_wait(100);
	}
	sync();
	return 0;
}

static int64_t xive_easc_scrub(struct xive *x, uint64_t block, uint64_t idx)
{
	return __xive_cache_scrub(x, xive_cache_easc, block, idx, false, false);
}

static int64_t xive_nxc_scrub(struct xive *x, uint64_t block, uint64_t idx)
{
	return __xive_cache_scrub(x, xive_cache_nxc, block, idx, false, false);
}

static int64_t xive_nxc_scrub_clean(struct xive *x, uint64_t block, uint64_t idx)
{
	return __xive_cache_scrub(x, xive_cache_nxc, block, idx, true, false);
}

static int64_t xive_endc_scrub(struct xive *x, uint64_t block, uint64_t idx)
{
	return __xive_cache_scrub(x, xive_cache_endc, block, idx, false, false);
}

#define XIVE_CACHE_WATCH_MAX_RETRIES 10

static int64_t __xive_cache_watch(struct xive *x, enum xive_cache_type ctype,
				  uint64_t block, uint64_t idx,
				  uint32_t start_dword, uint32_t dword_count,
				  beint64_t *new_data, bool light_watch,
				  bool synchronous)
{
	uint64_t sreg, sregx, dreg0, dreg0x;
	uint64_t dval0, sval, status;
	int64_t i;
	int retries = 0;

#ifdef XIVE_CHECK_LOCKS
	assert(lock_held_by_me(&x->lock));
#endif
	switch (ctype) {
	case xive_cache_endc:
		sreg = VC_ENDC_WATCH0_SPEC;
		sregx = X_VC_ENDC_WATCH0_SPEC;
		dreg0 = VC_ENDC_WATCH0_DATA0;
		dreg0x = X_VC_ENDC_WATCH0_DATA0;
		sval = SETFIELD(VC_ENDC_WATCH_BLOCK_ID, idx, block);
		break;
	case xive_cache_nxc:
		sreg = PC_NXC_WATCH0_SPEC;
		sregx = X_PC_NXC_WATCH0_SPEC;
		dreg0 = PC_NXC_WATCH0_DATA0;
		dreg0x = X_PC_NXC_WATCH0_DATA0;
		sval = SETFIELD(PC_NXC_WATCH_BLOCK_ID, idx, block);
		break;
	default:
		return OPAL_INTERNAL_ERROR;
	}

	/* The full bit is in the same position for ENDC and NXC */
	if (!light_watch)
		sval |= VC_ENDC_WATCH_FULL;

	for (;;) {
		/* Write the cache watch spec */
		__xive_regw(x, sreg, sregx, sval, NULL);

		/* Load data0 register to populate the watch */
		dval0 = __xive_regr(x, dreg0, dreg0x, NULL);

		/* If new_data is NULL, this is a dummy watch used as a
		 * workaround for a HW bug
		 */
		if (!new_data) {
			__xive_regw(x, dreg0, dreg0x, dval0, NULL);
			return 0;
		}

		/* Write the words into the watch facility. We write in reverse
		 * order in case word 0 is part of it as it must be the last
		 * one written.
		 */
		for (i = start_dword + dword_count - 1; i >= start_dword ;i--) {
			uint64_t dw = be64_to_cpu(new_data[i - start_dword]);
			__xive_regw(x, dreg0 + i * 8, dreg0x + i, dw, NULL);
		}

		/* Write data0 register to trigger the update if word 0 wasn't
		 * written above
		 */
		if (start_dword > 0)
			__xive_regw(x, dreg0, dreg0x, dval0, NULL);

		/* This may not be necessary for light updates (it's possible
		 * that a sync in sufficient, TBD). Ensure the above is
		 * complete and check the status of the watch.
		 */
		status = __xive_regr(x, sreg, sregx, NULL);

		/* Bits FULL and CONFLICT are in the same position in
		 * ENDC and NXC
		 */
		if (!(status & VC_ENDC_WATCH_FULL) ||
		    !(status & VC_ENDC_WATCH_CONFLICT))
			break;
		if (!synchronous)
			return OPAL_BUSY;

		if (++retries == XIVE_CACHE_WATCH_MAX_RETRIES) {
			xive_err(x, "Reached maximum retries %d when doing "
				 "a %s cache update\n", retries,
				 ctype == xive_cache_endc ? "ENDC" : "NXC");
			return OPAL_BUSY;
		}
	}

	/* Perform a scrub with "want_invalidate" set to false to push the
	 * cache updates to memory as well
	 */
	return __xive_cache_scrub(x, ctype, block, idx, false, false);
}

#ifdef XIVE_DEBUG_INIT_CACHE_UPDATES
static bool xive_check_endc_update(struct xive *x, uint32_t idx, struct xive_end *end)
{
	struct xive_end *end_p = xive_get_end(x, idx);
	struct xive_end end2;

	assert(end_p);
	end2 = *end_p;
	end2.w0 &= ~END_W0_RESERVED;
	end2.w1 &= ~END_W1_RESERVED;
	end2.w7 &= ~END_W7_F0_RESERVED;
	if (memcmp(end, &end2, sizeof(struct xive_end)) != 0) {
		xive_err(x, "END update mismatch idx %d\n", idx);
		xive_err(x, "want: %08x %08x %08x %08x\n",
			 end->w0, end->w1, end->w2, end->w3);
		xive_err(x, "      %08x %08x %08x %08x\n",
			 end->w4, end->w5, end->w6, end->w7);
		xive_err(x, "got : %08x %08x %08x %08x\n",
			 end2.w0, end2.w1, end2.w2, end2.w3);
		xive_err(x, "      %08x %08x %08x %08x\n",
			 end2.w4, end2.w5, end2.w6, end2.w7);
		return false;
	}
	return true;
}

static bool xive_check_nxc_update(struct xive *x, uint32_t idx, struct xive_nvp *vp)
{
	struct xive_nvp *vp_p = xive_get_vp(x, idx);
	struct xive_nvp vp2;

	assert(vp_p);
	vp2 = *vp_p;
	if (memcmp(vp, &vp2, sizeof(struct xive_nvp)) != 0) {
		xive_err(x, "VP update mismatch idx %d\n", idx);
		xive_err(x, "want: %08x %08x %08x %08x\n",
			 vp->w0, vp->w1, vp->w2, vp->w3);
		xive_err(x, "      %08x %08x %08x %08x\n",
			 vp->w4, vp->w5, vp->w6, vp->w7);
		xive_err(x, "got : %08x %08x %08x %08x\n",
			 vp2.w0, vp2.w1, vp2.w2, vp2.w3);
		xive_err(x, "      %08x %08x %08x %08x\n",
			 vp2.w4, vp2.w5, vp2.w6, vp2.w7);
		return false;
	}
	return true;
}
#else
static inline bool xive_check_endc_update(struct xive *x __unused,
					uint32_t idx __unused,
					struct xive_end *end __unused)
{
	return true;
}

static inline bool xive_check_nxc_update(struct xive *x __unused,
					 uint32_t idx __unused,
					 struct xive_nvp *vp __unused)
{
	return true;
}
#endif

static int64_t xive_escalation_ive_cache_update(struct xive *x, uint64_t block,
				     uint64_t idx, struct xive_eas *eas,
				     bool synchronous)
{
	return __xive_cache_watch(x, xive_cache_endc, block, idx,
				  2, 1, &eas->w, true, synchronous);
}

static int64_t xive_endc_cache_update(struct xive *x, uint64_t block,
				     uint64_t idx, struct xive_end *end,
				     bool synchronous)
{
	int64_t ret;

	ret = __xive_cache_watch(x, xive_cache_endc, block, idx,
				 0, 4, (beint64_t *)end, false, synchronous);
	xive_check_endc_update(x, idx, end);
	return ret;
}

static int64_t xive_nxc_cache_update(struct xive *x, uint64_t block,
				     uint64_t idx, struct xive_nvp *vp,
				     bool synchronous)
{
	int64_t ret;

	ret = __xive_cache_watch(x, xive_cache_nxc, block, idx,
				 0, 4, (beint64_t *)vp, false, synchronous);
	xive_check_nxc_update(x, idx, vp);
	return ret;
}

/*
 * VSD
 */
static bool xive_set_vsd(struct xive *x, uint32_t tbl, uint32_t idx, uint64_t v)
{
	/* Set VC subengine */
	xive_regw(x, VC_VSD_TABLE_ADDR,
		  SETFIELD(VC_VSD_TABLE_SELECT, 0ull, tbl) |
		  SETFIELD(VC_VSD_TABLE_ADDRESS, 0ull, idx));
	if (x->last_reg_error)
		return false;
	xive_regw(x, VC_VSD_TABLE_DATA, v);
	if (x->last_reg_error)
		return false;

	/* also set PC subengine if table is used */
	if (tbl == VST_EAS || tbl == VST_ERQ || tbl == VST_IC)
		return true;

	xive_regw(x, PC_VSD_TABLE_ADDR,
		  SETFIELD(PC_VSD_TABLE_SELECT, 0ull, tbl) |
		  SETFIELD(PC_VSD_TABLE_ADDRESS, 0ull, idx));
	if (x->last_reg_error)
		return false;
	xive_regw(x, PC_VSD_TABLE_DATA, v);
	if (x->last_reg_error)
		return false;
	return true;
}

static bool xive_set_local_tables(struct xive *x)
{
	uint64_t base, i;

	/* These have to be power of 2 sized */
	assert(is_pow2(XIVE_ESB_SIZE));
	assert(is_pow2(XIVE_EAT_SIZE));

	/* All tables set as exclusive */
	base = SETFIELD(VSD_MODE, 0ull, VSD_MODE_EXCLUSIVE);

	/* ESB: direct mode */
	if (!xive_set_vsd(x, VST_ESB, x->block_id, base |
			  (((uint64_t)x->sbe_base) & VSD_ADDRESS_MASK) |
			  SETFIELD(VSD_TSIZE, 0ull, ilog2(XIVE_ESB_SIZE) - 12)))
		return false;

	/* EAS: direct mode */
	if (!xive_set_vsd(x, VST_EAS, x->block_id, base |
			  (((uint64_t)x->eat_base) & VSD_ADDRESS_MASK) |
			  SETFIELD(VSD_TSIZE, 0ull, ilog2(XIVE_EAT_SIZE) - 12)))
		return false;

	/* END: indirect mode with 64K subpages */
	if (!xive_set_vsd(x, VST_END, x->block_id, base |
			  (((uint64_t)x->end_ind_base) & VSD_ADDRESS_MASK) |
			  VSD_INDIRECT | SETFIELD(VSD_TSIZE, 0ull,
						  ilog2(x->end_ind_size) - 12)))
		return false;

	/* NVP: indirect mode with 64K subpages */
	if (!xive_set_vsd(x, VST_NVP, x->block_id, base |
			  (((uint64_t)x->vp_ind_base) & VSD_ADDRESS_MASK) |
			  VSD_INDIRECT | SETFIELD(VSD_TSIZE, 0ull,
						  ilog2(x->vp_ind_size) - 12)))
		return false;

	/* NVG: not used  */
	/* NVC: not used */

	/* INT and SYNC: indexed with the Topology# */
	if (!xive_set_vsd(x, VST_IC, x->chip_id, base |
			  (((uint64_t)x->ic_base) & VSD_ADDRESS_MASK) |
			  SETFIELD(VSD_TSIZE, 0ull, ilog2(x->ic_size) - 12)))
		return false;

	if (!xive_set_vsd(x, VST_SYNC, x->chip_id, base |
			  (((uint64_t)x->sync_inject) & VSD_ADDRESS_MASK) |
			  SETFIELD(VSD_TSIZE, 0ull, ilog2(x->sync_inject_size) - 12)))
		return false;

	/*
	 * ERQ: one 64K page for each queue overflow. Indexed with :
	 *
	 * 0:IPI, 1:HWD, 2:NxC, 3:INT, 4:OS-Queue, 5:Pool-Queue, 6:Hard-Queue
	 */
	for (i = 0; i < VC_QUEUE_COUNT; i++) {
		u64 addr = ((uint64_t)x->q_ovf) + i * PAGE_SIZE;
		u64 cfg, sreg, sregx;

		if (!xive_set_vsd(x, VST_ERQ, i, base |
				  (addr & VSD_ADDRESS_MASK) |
			  SETFIELD(VSD_TSIZE, 0ull, 4)))
			return false;

		sreg = VC_QUEUES_CFG_REM0 + i * 8;
		sregx = X_VC_QUEUES_CFG_REM0 + i;
		cfg = __xive_regr(x, sreg, sregx, NULL);
		cfg |= VC_QUEUES_CFG_MEMB_EN;
		cfg = SETFIELD(VC_QUEUES_CFG_MEMB_SZ, cfg, 4);
		__xive_regw(x, sreg, sregx, cfg, NULL);
	}

	return true;
}


/*
 * IC BAR layout
 *
 * Page 0:		Internal CQ register accesses (reads & writes)
 * Page 1:		Internal PC register accesses (reads & writes)
 * Page 2:		Internal VC register accesses (reads & writes)
 * Page 3:		Internal TCTXT (TIMA) reg accesses (read & writes)
 * Page 4:		Notify Port page (writes only, w/data),
 * Page 5:		Reserved
 * Page 6:		Sync Poll page (writes only, dataless)
 * Page 7:		Sync Inject page (writes only, dataless)
 * Page 8:		LSI Trigger page (writes only, dataless)
 * Page 9:		LSI SB Management page (reads & writes dataless)
 * Pages 10-255:	Reserved
 * Pages 256-383: 	Direct mapped Thread Context Area (reads & writes)
 *                	covering the 128 threads in P10.
 * Pages 384-511: 	Reserved
 */

#define XIVE_IC_CQ_PGOFF	0
#define XIVE_IC_PC_PGOFF	1
#define XIVE_IC_VC_PGOFF	2
#define XIVE_IC_TCTXT_PGOFF	3
#define XIVE_NOTIFY_PGOFF	4
#define XIVE_SYNC_POLL_PGOFF	6
#define XIVE_SYNC_INJECT_PGOFF	7
#define XIVE_LSI_TRIGGER_PGOFF	8
#define XIVE_LSI_MGMT_PGOFF	9
#define XIVE_IC_TM_DIRECT_PGOFF 256

static bool xive_configure_ic_bars(struct xive *x)
{
	uint64_t chip_id = x->chip_id;
	uint64_t val;

	/* Reset all bars to zero */
	xive_regwx(x, CQ_RST_CTL, CQ_RST_PB_BAR_RESET);

	/* IC BAR */
	phys_map_get(chip_id, XIVE_IC, 0, (uint64_t *)&x->ic_base, &x->ic_size);
	val = (uint64_t)x->ic_base | CQ_IC_BAR_VALID | CQ_IC_BAR_64K;
	x->ic_shift = 16;

	xive_regwx(x, CQ_IC_BAR, val);
	if (x->last_reg_error)
		return false;

	/*
	 * TM BAR, same address for each chip. Hence we create a fake
	 * chip 0 and use that for all phys_map_get(XIVE_TM) calls.
	 */
	phys_map_get(0, XIVE_TM, 0, (uint64_t *)&x->tm_base, &x->tm_size);
	val = (uint64_t)x->tm_base | CQ_TM_BAR_VALID | CQ_TM_BAR_64K;
	x->tm_shift = 16;

	xive_regwx(x, CQ_TM_BAR, val);
	if (x->last_reg_error)
		return false;

	/* IC BAR sub-pages shortcuts */
	x->ic_tm_direct_base = x->ic_base +
		(XIVE_IC_TM_DIRECT_PGOFF << x->ic_shift);

	return true;
}

/*
 * NVPG, NVC, ESB, END BARs have common attributes: 64k page and only
 * one set covering the whole BAR.
 */
static bool xive_configure_bars(struct xive *x)
{
	uint64_t chip_id = x->chip_id;
	uint64_t val;
	uint64_t esb_size;
	uint64_t end_size;
	uint64_t nvp_size;

	x->nvp_size = XIVE_VP_COUNT(x) << XIVE_NVP_SHIFT;
	x->esb_size = XIVE_INT_COUNT << XIVE_ESB_SHIFT;
	x->end_size = XIVE_END_COUNT << XIVE_END_SHIFT;

	/*
	 * NVC BAR is not configured because we do not use the XIVE2
	 * Crowd capability.
	 */

	/* NVPG BAR: two pages, even NVP, odd NVG */
	phys_map_get(chip_id, XIVE_NVPG, 0, (uint64_t *)&x->nvp_base, &nvp_size);
	if (x->nvp_size > nvp_size) {
		xive_err(x, "NVP table is larger than default: "
			 "0x%012llx > 0x%012llx\n", x->nvp_size, nvp_size);
		return false;
	}

	val = (uint64_t)x->nvp_base | CQ_BAR_VALID | CQ_BAR_64K |
		SETFIELD(CQ_BAR_RANGE, 0ull, ilog2(x->nvp_size) - 24);
	xive_regwx(x, CQ_NVPG_BAR, val);
	if (x->last_reg_error)
		return false;

	/* ESB BAR */
	phys_map_get(chip_id, XIVE_ESB, 0, (uint64_t *)&x->esb_base, &esb_size);
	if (x->esb_size > esb_size) {
		xive_err(x, "ESB table is larger than default: "
			 "0x%012llx > 0x%012llx\n", x->esb_size, esb_size);
		return false;
	}

	val = (uint64_t)x->esb_base | CQ_BAR_VALID | CQ_BAR_64K |
		SETFIELD(CQ_BAR_RANGE, 0ull, ilog2(x->esb_size) - 24);
	xive_regwx(x, CQ_ESB_BAR, val);
	if (x->last_reg_error)
		return false;

	/* END BAR */
	phys_map_get(chip_id, XIVE_END, 0, (uint64_t *)&x->end_base, &end_size);
	if (x->end_size > end_size) {
		xive_err(x, "END table is larger than default: "
			 "0x%012llx > 0x%012llx\n", x->end_size, end_size);
		return false;
	}

	val = (uint64_t)x->end_base | CQ_BAR_VALID | CQ_BAR_64K |
		SETFIELD(CQ_BAR_RANGE, 0ull, ilog2(x->end_size) - 24);
	xive_regwx(x, CQ_END_BAR, val);
	if (x->last_reg_error)
		return false;

	xive_dbg(x, "IC:  %14p [0x%012llx]\n", x->ic_base, x->ic_size);
	xive_dbg(x, "TM:  %14p [0x%012llx]\n", x->tm_base, x->tm_size);
	xive_dbg(x, "NVP: %14p [0x%012llx]\n", x->nvp_base, x->nvp_size);
	xive_dbg(x, "ESB: %14p [0x%012llx]\n", x->esb_base, x->esb_size);
	xive_dbg(x, "END: %14p [0x%012llx]\n", x->end_base, x->end_size);
	xive_dbg(x, "OVF: %14p [0x%012x]\n", x->q_ovf,
		 VC_QUEUE_COUNT * PAGE_SIZE);

	return true;
}

static void xive_dump_mmio(struct xive *x)
{
	prlog(PR_DEBUG, " CQ_CFG_PB_GEN = %016llx\n",
	      in_be64(x->ic_base + CQ_CFG_PB_GEN));
	prlog(PR_DEBUG, " CQ_MSGSND     = %016llx\n",
	      in_be64(x->ic_base + CQ_MSGSND));
}

static const struct {
	uint64_t bitmask;
	const char *name;
} xive_capabilities[] = {
	{ CQ_XIVE_CAP_PHB_PQ_DISABLE, "PHB PQ disable mode support" },
	{ CQ_XIVE_CAP_PHB_ABT, "PHB address based trigger mode support" },
	{ CQ_XIVE_CAP_EXPLOITATION_MODE, "Exploitation mode" },
	{ CQ_XIVE_CAP_STORE_EOI, "StoreEOI mode support" },
	{ CQ_XIVE_CAP_VP_SAVE_RESTORE, "VP Context Save and Restore" },
};

static void xive_dump_capabilities(struct xive *x, uint64_t cap_val)
{
	int i;

	xive_dbg(x, "capabilities: %016llx\n", cap_val);
	xive_dbg(x, "\tVersion: %lld\n",
		 GETFIELD(CQ_XIVE_CAP_VERSION, cap_val));
	xive_dbg(x, "\tUser interrupt priorities: [ 1 - %d ]\n",
		 1 << GETFIELD(CQ_XIVE_CAP_USER_INT_PRIO, cap_val));
	xive_dbg(x, "\tVP interrupt priorities: [ %d - 8 ]\n",
		 1 << GETFIELD(CQ_XIVE_CAP_VP_INT_PRIO, cap_val));
	xive_dbg(x, "\tExtended Blockid bits: %lld\n",
		 4 + GETFIELD(CQ_XIVE_CAP_BLOCK_ID_WIDTH, cap_val));

	for (i = 0; i < ARRAY_SIZE(xive_capabilities); i++) {
		if (xive_capabilities[i].bitmask & cap_val)
			xive_dbg(x, "\t%s\n", xive_capabilities[i].name);
	}
}

static const struct {
	uint64_t bitmask;
	const char *name;
} xive_configs[] = {
	{ CQ_XIVE_CFG_GEN1_TIMA_OS, "Gen1 mode TIMA OS" },
	{ CQ_XIVE_CFG_GEN1_TIMA_HYP, "Gen1 mode TIMA Hyp" },
	{ CQ_XIVE_CFG_GEN1_TIMA_HYP_BLK0, "Gen1 mode TIMA General Hypervisor Block0" },
	{ CQ_XIVE_CFG_GEN1_TIMA_CROWD_DIS, "Gen1 mode TIMA Crowd disable" },
	{ CQ_XIVE_CFG_GEN1_END_ESX, "Gen1 mode END ESx" },
	{ CQ_XIVE_CFG_EN_VP_SAVE_RESTORE, "VP Context Save and Restore" },
	{ CQ_XIVE_CFG_EN_VP_SAVE_REST_STRICT, "VP Context Save and Restore strict" },
};

static void xive_dump_configuration(struct xive *x, const char *prefix,
				    uint64_t cfg_val)
{
	int i ;

	xive_dbg(x, "%s configuration: %016llx\n", prefix, cfg_val);
	xive_dbg(x, "\tHardwired Thread Id range: %lld bits\n",
		 7 + GETFIELD(CQ_XIVE_CFG_HYP_HARD_RANGE, cfg_val));
	xive_dbg(x, "\tUser Interrupt priorities: [ 1 - %d ]\n",
		 1 << GETFIELD(CQ_XIVE_CFG_USER_INT_PRIO, cfg_val));
	xive_dbg(x, "\tVP Interrupt priorities: [ 0 - %d ]\n", xive_max_prio(x));
	xive_dbg(x, "\tBlockId bits: %lld bits\n",
		 4 + GETFIELD(CQ_XIVE_CFG_BLOCK_ID_WIDTH, cfg_val));
	if (CQ_XIVE_CFG_HYP_HARD_BLKID_OVERRIDE & cfg_val)
		xive_dbg(x, "\tHardwired BlockId: %lld\n",
			 GETFIELD(CQ_XIVE_CFG_HYP_HARD_BLOCK_ID, cfg_val));

	for (i = 0; i < ARRAY_SIZE(xive_configs); i++) {
		if (xive_configs[i].bitmask & cfg_val)
			xive_dbg(x, "\t%s\n", xive_configs[i].name);
	}
}

/*
 * Default XIVE configuration
 */
#define XIVE_CONFIGURATION                                        \
	(SETFIELD(CQ_XIVE_CFG_HYP_HARD_RANGE, 0ull, CQ_XIVE_CFG_THREADID_8BITS) | \
	 SETFIELD(CQ_XIVE_CFG_VP_INT_PRIO, 0ull, CQ_XIVE_CFG_INT_PRIO_8))

/*
 * Gen1 configuration for tests (QEMU)
 */
#define XIVE_CONFIGURATION_GEN1						\
	(SETFIELD(CQ_XIVE_CFG_HYP_HARD_RANGE, 0ull, CQ_XIVE_CFG_THREADID_7BITS) | \
	 SETFIELD(CQ_XIVE_CFG_VP_INT_PRIO, 0ull, CQ_XIVE_CFG_INT_PRIO_8) | \
	 CQ_XIVE_CFG_GEN1_TIMA_OS |					\
	 CQ_XIVE_CFG_GEN1_TIMA_HYP |					\
	 CQ_XIVE_CFG_GEN1_TIMA_HYP_BLK0 |				\
	 CQ_XIVE_CFG_GEN1_TIMA_CROWD_DIS |				\
	 CQ_XIVE_CFG_GEN1_END_ESX)

static bool xive_has_cap(struct xive *x, uint64_t cap)
{
	return !!x && !!(x->capabilities & cap);
}

#define XIVE_CAN_STORE_EOI(x) xive_has_cap(x, CQ_XIVE_CAP_STORE_EOI)

static bool xive_cfg_save_restore(struct xive *x)
{
	return !!(x->config & CQ_XIVE_CFG_EN_VP_SAVE_RESTORE);
}

/*
 * When PQ_disable is available, configure the ESB cache to improve
 * performance for PHB ESBs.
 *
 * split_mode :
 *   1/3rd of the cache is reserved for PHB ESBs and the rest to
 *   IPIs. This is sufficient to keep all the PHB ESBs in cache and
 *   avoid ESB cache misses during IO interrupt processing.
 *
 * hash_array_enable :
 *   Internal cache hashing optimization. The hash_array tracks for
 *   ESBs where the original trigger came from so that we avoid
 *   getting the EAS into the cache twice.
 */
static void xive_config_esb_cache(struct xive *x)
{
	uint64_t val = xive_regr(x, VC_ESBC_CFG);

	if (xive_has_cap(x, CQ_XIVE_CAP_PHB_PQ_DISABLE)) {
		val |= VC_ESBC_CFG_SPLIT_MODE | VC_ESBC_CFG_HASH_ARRAY_ENABLE;
		val = SETFIELD(VC_ESBC_CFG_MAX_ENTRIES_IN_MODIFIED, val, 0xE);
		xive_dbg(x, "ESB cache configured with split mode "
			 "and hash array. VC_ESBC_CFG=%016llx\n", val);
	} else
		val &= ~VC_ESBC_CFG_SPLIT_MODE;

	xive_regw(x, VC_ESBC_CFG, val);
}

static void xive_config_fused_core(struct xive *x)
{
	uint64_t val = xive_regr(x, TCTXT_CFG);

	if (this_cpu()->is_fused_core) {
		val |= TCTXT_CFG_FUSE_CORE_EN;
		xive_dbg(x, "configured for fused cores. "
			 "PC_TCTXT_CFG=%016llx\n", val);
	} else
		val &= ~TCTXT_CFG_FUSE_CORE_EN;
	xive_regw(x, TCTXT_CFG, val);
}

static void xive_config_reduced_priorities_fixup(struct xive *x)
{
	if (xive_cfg_vp_prio_shift(x) < CQ_XIVE_CFG_INT_PRIO_8 &&
	    x->quirks & XIVE_QUIRK_BROKEN_PRIO_CHECK) {
		uint64_t val = xive_regr(x, PC_ERR1_CFG1);

		val &= ~PC_ERR1_CFG1_INTERRUPT_INVALID_PRIO;
		xive_dbg(x, "workaround for reduced priorities. "
			 "PC_ERR1_CFG1=%016llx\n", val);
		xive_regw(x, PC_ERR1_CFG1, val);
	}
}

static bool xive_config_init(struct xive *x)
{
	x->capabilities = xive_regr(x, CQ_XIVE_CAP);
	xive_dump_capabilities(x, x->capabilities);

	x->generation = GETFIELD(CQ_XIVE_CAP_VERSION, x->capabilities);

	/*
	 * Allow QEMU to override version for tests
	 */
	if (x->generation != XIVE_GEN2 && !chip_quirk(QUIRK_QEMU)) {
		xive_err(x, "Invalid XIVE controller version %d\n",
			 x->generation);
		return false;
	}

	x->config = xive_regr(x, CQ_XIVE_CFG);
	xive_dump_configuration(x, "default", x->config);

	/* Start with default settings */
	x->config = x->generation == XIVE_GEN1 ? XIVE_CONFIGURATION_GEN1 :
		XIVE_CONFIGURATION;

	if (x->quirks & XIVE_QUIRK_THREADID_7BITS)
		x->config = SETFIELD(CQ_XIVE_CFG_HYP_HARD_RANGE, x->config,
				     CQ_XIVE_CFG_THREADID_7BITS);

	/*
	 * Hardwire the block ID. The default value is the topology ID
	 * of the chip which is different from the block.
	 */
	x->config |= CQ_XIVE_CFG_HYP_HARD_BLKID_OVERRIDE |
		SETFIELD(CQ_XIVE_CFG_HYP_HARD_BLOCK_ID, 0ull, x->block_id);

	/*
	 * Enable "VP Context Save and Restore" by default. it is
	 * compatible with KVM which currently does the context
	 * save&restore in the entry/exit path of the vCPU
	 */
	if (x->capabilities & CQ_XIVE_CAP_VP_SAVE_RESTORE)
		x->config |= CQ_XIVE_CFG_EN_VP_SAVE_RESTORE;

	xive_dump_configuration(x, "new", x->config);
	xive_regw(x, CQ_XIVE_CFG, x->config);
	if (xive_regr(x, CQ_XIVE_CFG) != x->config) {
		xive_err(x, "configuration setting failed\n");
	}

	/*
	 * Disable error reporting in the FIR for info errors from the VC.
	 */
	xive_regw(x, CQ_FIRMASK_OR, CQ_FIR_VC_INFO_ERROR_0_2);

	/*
	 * Mask CI Load and Store to bad location, as IPI trigger
	 * pages may be mapped to user space, and a read on the
	 * trigger page causes a checkstop
	 */
	xive_regw(x, CQ_FIRMASK_OR, CQ_FIR_PB_RCMDX_CI_ERR1);

	/*
	 * VP space settings. P9 mode is 19bits.
	 */
	x->vp_shift = x->generation == XIVE_GEN1 ?
		VP_SHIFT_GEN1 : VP_SHIFT_GEN2;

	/*
	 * VP ids for HW threads. These values are hardcoded in the
	 * CAM line of the HW context
	 *
	 *     POWER10     |chip|0000000000000001|threadid|
	 *     28bits        4           16          8
	 *
	 *     POWER9           |chip|000000000001|thrdid |
	 *     23bits              4      12          7
	 */

	/* TODO (cosmetic): set VP ids for HW threads only once */
	xive_threadid_shift = 7 + GETFIELD(CQ_XIVE_CFG_HYP_HARD_RANGE,
					   x->config);

	xive_hw_vp_base  = 1 << xive_threadid_shift;
	xive_hw_vp_count = 1 << xive_threadid_shift;

	xive_dbg(x, "store EOI is %savailable\n",
		 XIVE_CAN_STORE_EOI(x) ? "" : "not ");

	xive_config_fused_core(x);

	xive_config_esb_cache(x);

	xive_config_reduced_priorities_fixup(x);

	return true;
}

/* Set Translation tables : 1 block per chip */
static bool xive_setup_set_xlate(struct xive *x)
{
	unsigned int i;

	/* Configure ESBs */
	xive_regw(x, CQ_TAR,
		  CQ_TAR_AUTOINC | SETFIELD(CQ_TAR_SELECT, 0ull, CQ_TAR_ESB));
	if (x->last_reg_error)
		return false;
	for (i = 0; i < XIVE_MAX_BLOCKS; i++) {
		xive_regw(x, CQ_TDR, CQ_TDR_VALID |
			  SETFIELD(CQ_TDR_BLOCK_ID, 0ull, x->block_id));
		if (x->last_reg_error)
			return false;
	}

	/* Configure ENDs */
	xive_regw(x, CQ_TAR,
		  CQ_TAR_AUTOINC | SETFIELD(CQ_TAR_SELECT, 0ull, CQ_TAR_END));
	if (x->last_reg_error)
		return false;
	for (i = 0; i < XIVE_MAX_BLOCKS; i++) {
		xive_regw(x, CQ_TDR, CQ_TDR_VALID |
			  SETFIELD(CQ_TDR_BLOCK_ID, 0ull, x->block_id));
		if (x->last_reg_error)
			return false;
	}

	/* Configure NVPs */
	xive_regw(x, CQ_TAR,
		  CQ_TAR_AUTOINC | SETFIELD(CQ_TAR_SELECT, 0ull, CQ_TAR_NVPG));
	if (x->last_reg_error)
		return false;
	for (i = 0; i < XIVE_MAX_BLOCKS; i++) {
		xive_regw(x, CQ_TDR, CQ_TDR_VALID |
			  SETFIELD(CQ_TDR_BLOCK_ID, 0ull, x->block_id));
		if (x->last_reg_error)
			return false;
	}
	return true;
}

static bool xive_prealloc_tables(struct xive *x)
{
	uint32_t i;
	uint32_t pbase, pend;

	/* ESB has 4 entries per byte */
	x->sbe_base = local_alloc(x->chip_id, XIVE_ESB_SIZE, XIVE_ESB_SIZE);
	if (!x->sbe_base) {
		xive_err(x, "Failed to allocate SBE\n");
		return false;
	}

	/* PQs are initialized to 0b01 which corresponds to "ints off" */
	memset(x->sbe_base, 0x55, XIVE_ESB_SIZE);
	xive_dbg(x, "SBE  at %p size 0x%lx\n", x->sbe_base, XIVE_ESB_SIZE);

	/* EAS entries are 8 bytes */
	x->eat_base = local_alloc(x->chip_id, XIVE_EAT_SIZE, XIVE_EAT_SIZE);
	if (!x->eat_base) {
		xive_err(x, "Failed to allocate EAS\n");
		return false;
	}

	/*
	 * We clear the entries (non-valid). They will be initialized
	 * when actually used
	 */
	memset(x->eat_base, 0, XIVE_EAT_SIZE);
	xive_dbg(x, "EAT  at %p size 0x%lx\n", x->eat_base, XIVE_EAT_SIZE);

	/* Indirect END table. Limited to one top page. */
	x->end_ind_size = ALIGN_UP(XIVE_END_TABLE_SIZE, PAGE_SIZE);
	if (x->end_ind_size > PAGE_SIZE) {
		xive_err(x, "END indirect table is too big !\n");
		return false;
	}
	x->end_ind_base = local_alloc(x->chip_id, x->end_ind_size,
				      x->end_ind_size);
	if (!x->end_ind_base) {
		xive_err(x, "Failed to allocate END indirect table\n");
		return false;
	}
	memset(x->end_ind_base, 0, x->end_ind_size);
	xive_dbg(x, "ENDi at %p size 0x%llx #%ld entries\n", x->end_ind_base,
		 x->end_ind_size, XIVE_END_COUNT);
	x->end_ind_count = XIVE_END_TABLE_SIZE / XIVE_VSD_SIZE;

	/* Indirect VP table. Limited to one top page. */
	x->vp_ind_size = ALIGN_UP(XIVE_VP_TABLE_SIZE(x), PAGE_SIZE);
	if (x->vp_ind_size > PAGE_SIZE) {
		xive_err(x, "VP indirect table is too big !\n");
		return false;
	}
	x->vp_ind_base = local_alloc(x->chip_id, x->vp_ind_size,
				     x->vp_ind_size);
	if (!x->vp_ind_base) {
		xive_err(x, "Failed to allocate VP indirect table\n");
		return false;
	}
	xive_dbg(x, "VPi  at %p size 0x%llx #%ld entries\n", x->vp_ind_base,
		 x->vp_ind_size, XIVE_VP_COUNT(x));
	x->vp_ind_count = XIVE_VP_TABLE_SIZE(x) / XIVE_VSD_SIZE;
	memset(x->vp_ind_base, 0, x->vp_ind_size);

	/* Allocate pages for the VP ids representing HW threads */
	pbase = xive_hw_vp_base / VP_PER_PAGE;
	pend  = (xive_hw_vp_base + xive_hw_vp_count) / VP_PER_PAGE;

	xive_dbg(x, "Allocating pages %d to %d of VPs (for %d VPs)\n",
		 pbase, pend, xive_hw_vp_count);
	for (i = pbase; i <= pend; i++) {
		void *page;
		u64 vsd;

		/* Indirect entries have a VSD format */
		page = local_alloc(x->chip_id, PAGE_SIZE, PAGE_SIZE);
		if (!page) {
			xive_err(x, "Failed to allocate VP page\n");
			return false;
		}
		xive_dbg(x, "VP%d at %p size 0x%x\n", i, page, PAGE_SIZE);
		memset(page, 0, PAGE_SIZE);
		vsd = ((uint64_t)page) & VSD_ADDRESS_MASK;

		vsd |= SETFIELD(VSD_TSIZE, 0ull, 4);
		vsd |= SETFIELD(VSD_MODE, 0ull, VSD_MODE_EXCLUSIVE);
		vsd |= VSD_FIRMWARE;
		x->vp_ind_base[i] = cpu_to_be64(vsd);
	}

	/*
	 * Allocate page for cache and sync injection (512 * 128 hw
	 * threads) + one extra page for future use
	 */
	x->sync_inject_size = PAGE_SIZE + PAGE_SIZE;
	x->sync_inject = local_alloc(x->chip_id, x->sync_inject_size,
				     x->sync_inject_size);
	if (!x->sync_inject) {
		xive_err(x, "Failed to allocate sync pages\n");
		return false;
	}

	/*
	 * The Memory Coherence Directory uses 16M "granule" to track
	 * shared copies of a cache line. If any cache line within the
	 * 16M range gets touched by someone outside of the group, the
	 * MCD forces accesses to any cache line within the range to
	 * include everyone that might have a shared copy.
	 */
#define QUEUE_OVF_ALIGN (16 << 20) /* MCD granule size */

	/*
	 * Allocate the queue overflow pages and use a 16M alignment
	 * to avoid sharing with other structures and reduce traffic
	 * on the PowerBus.
	 */
	x->q_ovf = local_alloc(x->chip_id, VC_QUEUE_COUNT * PAGE_SIZE,
			       QUEUE_OVF_ALIGN);
	if (!x->q_ovf) {
		xive_err(x, "Failed to allocate queue overflow\n");
		return false;
	}
	return true;
}

static void xive_add_provisioning_properties(void)
{
	beint32_t chips[XIVE_MAX_CHIPS];
	uint32_t i, count;

	dt_add_property_cells(xive_dt_node,
			      "ibm,xive-provision-page-size", PAGE_SIZE);

	count = 1 << xive_chips_alloc_bits;
	for (i = 0; i < count; i++)
		chips[i] = cpu_to_be32(xive_block_to_chip[i]);
	dt_add_property(xive_dt_node, "ibm,xive-provision-chips",
			chips, 4 * count);
}

static void xive_create_mmio_dt_node(struct xive *x)
{
	uint64_t tb = (uint64_t)x->tm_base;
	uint32_t stride = 1u << x->tm_shift;

	xive_dt_node = dt_new_addr(dt_root, "interrupt-controller", tb);
	assert(xive_dt_node);

	dt_add_property_u64s(xive_dt_node, "reg",
			     tb + 0 * stride, stride,
			     tb + 1 * stride, stride,
			     tb + 2 * stride, stride,
			     tb + 3 * stride, stride);

	dt_add_property_strings(xive_dt_node, "compatible",
				"ibm,opal-xive-pe", "ibm,opal-xive-vc",
				"ibm,opal-intc");

	dt_add_property(xive_dt_node, "interrupt-controller", NULL, 0);
	dt_add_property_cells(xive_dt_node, "#address-cells", 0);
	dt_add_property_cells(xive_dt_node, "#interrupt-cells", 2);

	dt_add_property_cells(xive_dt_node, "ibm,xive-eq-sizes",
			      12, 16, 21, 24);

	dt_add_property_cells(xive_dt_node, "ibm,xive-#priorities",
			      xive_cfg_vp_prio(x));

	dt_add_property(xive_dt_node, "single-escalation-support", NULL, 0);

	if (XIVE_CAN_STORE_EOI(x))
		dt_add_property(xive_dt_node, "store-eoi", NULL, 0);

	if (xive_cfg_save_restore(x))
		dt_add_property(xive_dt_node, "vp-save-restore", NULL, 0);

	xive_add_provisioning_properties();

}

uint32_t xive2_get_phandle(void)
{
	if (!xive_dt_node)
		return 0;

	return xive_dt_node->phandle;
}

static void xive_setup_forward_ports(struct xive *x, struct proc_chip *remote_chip)
{
	struct xive *remote_xive = remote_chip->xive;
	uint64_t base = SETFIELD(VSD_MODE, 0ull, VSD_MODE_FORWARD);

	if (!xive_set_vsd(x, VST_ESB, remote_xive->block_id,
			  base | ((uint64_t)remote_xive->esb_base) |
			  SETFIELD(VSD_TSIZE, 0ull, ilog2(x->esb_size) - 12)))
		goto error;

	/* EAS: No remote */

	if (!xive_set_vsd(x, VST_END, remote_xive->block_id,
			  base | ((uint64_t)remote_xive->end_base) |
			  SETFIELD(VSD_TSIZE, 0ull, ilog2(x->end_size) - 12)))
		goto error;

	if (!xive_set_vsd(x, VST_NVP, remote_xive->block_id,
			  base | ((uint64_t)remote_xive->nvp_base) |
			  SETFIELD(VSD_TSIZE, 0ull, ilog2(x->nvp_size) - 12)))
		goto error;

	/* NVG: not used */
	/* NVC: not used */

	if (!xive_set_vsd(x, VST_IC, remote_xive->chip_id,
			  base | ((uint64_t)remote_xive->ic_base) |
			  SETFIELD(VSD_TSIZE, 0ull, ilog2(x->ic_size) - 12)))
		goto error;

	if (!xive_set_vsd(x, VST_SYNC, remote_xive->chip_id,
			  base | ((uint64_t)remote_xive->sync_inject) |
			  SETFIELD(VSD_TSIZE, 0ull, ilog2(x->sync_inject_size) - 12)))
		goto error;

	/* ERQ: No remote */

	return;

 error:
	xive_err(x, "Failure configuring forwarding ports\n");
}

static void late_init_one_xive(struct xive *x)
{
	struct proc_chip *chip;

	/* We need to setup the cross-chip forward ports. Let's
	 * iterate all chip and set them up accordingly
	 */
	for_each_chip(chip) {
		/* We skip ourselves or chips without a xive */
		if (chip->xive == x || !chip->xive)
			continue;

		/* Setup our forward ports to that chip */
		xive_setup_forward_ports(x, chip);
	}
}

static bool xive_check_ipi_free(struct xive *x, uint32_t irq, uint32_t count)
{
	uint32_t i, idx = GIRQ_TO_IDX(irq);

	for (i = 0; i < count; i++)
		if (bitmap_tst_bit(*x->ipi_alloc_map, idx + i))
			return false;
	return true;
}

uint32_t xive2_alloc_hw_irqs(uint32_t chip_id, uint32_t count,
				      uint32_t align)
{
	struct proc_chip *chip = get_chip(chip_id);
	struct xive *x;
	uint32_t base, i;

	assert(chip);
	assert(is_pow2(align));

	x = chip->xive;
	assert(x);

	lock(&x->lock);

	/* Allocate the HW interrupts */
	base = x->int_hw_bot - count;
	base &= ~(align - 1);
	if (base < x->int_ipi_top) {
		xive_err(x,
			 "HW alloc request for %d interrupts aligned to %d failed\n",
			 count, align);
		unlock(&x->lock);
		return XIVE_IRQ_ERROR;
	}
	if (!xive_check_ipi_free(x, base, count)) {
		xive_err(x, "HWIRQ boot allocator request overlaps dynamic allocator\n");
		unlock(&x->lock);
		return XIVE_IRQ_ERROR;
	}

	x->int_hw_bot = base;

	/* Initialize the corresponding EAS entries to sane defaults,
	 * IE entry is valid, not routed and masked, EQ data is set
	 * to the GIRQ number.
	 */
	for (i = 0; i < count; i++) {
		struct xive_eas *eas = xive_get_eas(x, base + i);

		eas->w = xive_set_field64(EAS_VALID, 0, 1) |
			 xive_set_field64(EAS_MASKED, 0, 1) |
			 xive_set_field64(EAS_END_DATA, 0, base + i);
	}

	unlock(&x->lock);
	return base;
}

uint32_t xive2_alloc_ipi_irqs(uint32_t chip_id, uint32_t count,
				       uint32_t align)
{
	struct proc_chip *chip = get_chip(chip_id);
	struct xive *x;
	uint32_t base, i;

	assert(chip);
	assert(is_pow2(align));

	x = chip->xive;
	assert(x);

	lock(&x->lock);

	/* Allocate the IPI interrupts */
	base = x->int_ipi_top + (align - 1);
	base &= ~(align - 1);
	if (base >= x->int_hw_bot) {
		xive_err(x,
			 "IPI alloc request for %d interrupts aligned to %d failed\n",
			 count, align);
		unlock(&x->lock);
		return XIVE_IRQ_ERROR;
	}
	if (!xive_check_ipi_free(x, base, count)) {
		xive_err(x, "IPI boot allocator request overlaps dynamic allocator\n");
		unlock(&x->lock);
		return XIVE_IRQ_ERROR;
	}

	x->int_ipi_top = base + count;

	/* Initialize the corresponding EAS entries to sane defaults,
	 * IE entry is valid, not routed and masked, END data is set
	 * to the GIRQ number.
	 */
	for (i = 0; i < count; i++) {
		struct xive_eas *eas = xive_get_eas(x, base + i);

		eas->w = xive_set_field64(EAS_VALID, 0, 1) |
			 xive_set_field64(EAS_MASKED, 0, 1) |
			 xive_set_field64(EAS_END_DATA, 0, base + i);
	}

	unlock(&x->lock);
	return base;
}

void *xive2_get_trigger_port(uint32_t girq)
{
	uint32_t idx = GIRQ_TO_IDX(girq);
	struct xive *x;

	/* Find XIVE on which the EAS resides */
	x = xive_from_isn(girq);
	if (!x)
		return NULL;

	if (GIRQ_IS_ESCALATION(girq)) {
		/* There is no trigger page for escalation interrupts */
		return NULL;
	} else {
		/* Make sure it's an IPI on that chip */
		if (girq < x->int_base ||
		    girq >= x->int_ipi_top)
			return NULL;

		return x->esb_base + idx * XIVE_ESB_PAGE_SIZE;
	}
}

/*
 *  Notify Port page (writes only, w/data), separated into two
 *  categories, both sent to VC:
 *   - IPI queue (Addr bit 52 = 0) (for NPU)
 *   - HW queue (Addr bit 52 = 1)
 */
uint64_t xive2_get_notify_port(uint32_t chip_id, uint32_t ent)
{
	struct proc_chip *chip = get_chip(chip_id);
	struct xive *x;
	uint32_t offset = 0;

	assert(chip);
	x = chip->xive;
	assert(x);

	/* This is where we can assign a different HW queue to a different
	 * source by offsetting into the cache lines of the notify port
	 *
	 * For now we keep it very basic, this will have to be looked at
	 * again on real HW with some proper performance analysis.
	 *
	 * Here's what Florian says on the matter:
	 *
	 * <<
	 * The first 2k of the notify port page can all be used for PCIe triggers
	 *
	 * However the idea would be that we try to use the first 4 cache lines to
	 * balance the PCIe Interrupt requests to use the least used snoop buses
	 * (we went from 2 to 4 snoop buses for P9). snoop 0 is heavily used
	 * (I think TLBIs are using that in addition to the normal addresses),
	 * snoop 3 is used for all Int commands, so I think snoop 2 (CL 2 in the
	 * page) is the least used overall. So we probably should that one for
	 * the Int commands from PCIe.
	 *
	 * In addition, our EAS cache supports hashing to provide "private" cache
	 * areas for the PHBs in the shared 1k EAS cache. This allows e.g. to avoid
	 * that one "thrashing" PHB thrashes the EAS cache for everyone, or provide
	 * a PHB with a private area that would allow high cache hits in case of a
	 * device using very few interrupts. The hashing is based on the offset within
	 * the cache line. So using that, you can e.g. set the EAS cache up so that
	 * IPIs use 512 entries, the x16 PHB uses 256 entries and the x8 PHBs 128
	 * entries each - or IPIs using all entries and sharing with PHBs, so PHBs
	 * would use 512 entries and 256 entries respectively.
	 *
	 * This is a tuning we would probably do later in the lab, but as a "prep"
	 * we should set up the different PHBs such that they are using different
	 * 8B-aligned offsets within the cache line, so e.g.
	 * PH4_0  addr        0x100        (CL 2 DW0
	 * PH4_1  addr        0x108        (CL 2 DW1)
	 * PH4_2  addr        0x110        (CL 2 DW2)
	 * etc.
	 * >>
	 *
	 * I'm using snoop1 for PHB0 and snoop2 for everybody else.
	 */

	/* Florian adds :
	 *
	 * we just set them up for a start to have different offsets
	 * within the cache line so that we could use the allocation
	 * restrictions that can be enforced in the interrupt
	 * controller
	 *
	 * P10 might now be randomizing the cache line bits in HW to
	 * balance snoop bus usage
	 */
	switch(ent) {
	case XIVE_HW_SRC_PHBn(0):
		offset = 0x800;
		break;
	case XIVE_HW_SRC_PHBn(1):
		offset = 0x908;
		break;
	case XIVE_HW_SRC_PHBn(2):
		offset = 0x910;
		break;
	case XIVE_HW_SRC_PHBn(3):
		offset = 0x918;
		break;
	case XIVE_HW_SRC_PHBn(4):
		offset = 0x920;
		break;
	case XIVE_HW_SRC_PHBn(5):
		offset = 0x928;
		break;
	case XIVE_HW_SRC_PSI:
		offset = 0x930;
		break;
	default:
		assert(false);
		return 0;
	}

	return ((uint64_t)x->ic_base) +
		(XIVE_NOTIFY_PGOFF << x->ic_shift) + offset;
}

/* Manufacture the powerbus packet bits 32:63 */
__attrconst uint32_t xive2_get_notify_base(uint32_t girq)
{
	return (GIRQ_TO_BLK(girq) << 28)  | GIRQ_TO_IDX(girq);
}

static bool xive_get_irq_targetting(uint32_t isn, uint32_t *out_target,
				    uint8_t *out_prio, uint32_t *out_lirq)
{
	struct xive_eas *eas;
	struct xive *x, *end_x;
	struct xive_end *end;
	uint32_t end_blk, end_idx;
	uint32_t vp_blk, vp_idx;
	uint32_t prio, server;
	bool is_escalation = GIRQ_IS_ESCALATION(isn);

	/* Find XIVE on which the EAS resides */
	x = xive_from_isn(isn);
	if (!x)
		return false;
	/* Grab the EAS */
	eas = xive_get_eas(x, isn);
	if (!eas)
		return false;
	if (!xive_get_field64(EAS_VALID, eas->w) && !is_escalation) {
		xive_err(x, "ISN %x lead to invalid EAS !\n", isn);
		return false;
	}

	if (out_lirq)
		*out_lirq = xive_get_field64(EAS_END_DATA, eas->w);

	/* Find the END and its xive instance */
	end_blk = xive_get_field64(EAS_END_BLOCK, eas->w);
	end_idx = xive_get_field64(EAS_END_INDEX, eas->w);
	end_x = xive_from_vc_blk(end_blk);

	/* This can fail if the interrupt hasn't been initialized yet
	 * but it should also be masked, so fail silently
	 */
	if (!end_x)
		goto pick_default;
	end = xive_get_end(end_x, end_idx);
	if (!end)
		goto pick_default;

	/* XXX Check valid and format 0 */

	/* No priority conversion, return the actual one ! */
	if (xive_get_field64(EAS_MASKED, eas->w))
		prio = 0xff;
	else
		prio = xive_get_field32(END_W7_F0_PRIORITY, end->w7);
	if (out_prio)
		*out_prio = prio;

	vp_blk = xive_get_field32(END_W6_VP_BLOCK, end->w6);
	vp_idx = xive_get_field32(END_W6_VP_OFFSET, end->w6);
	server = VP2PIR(vp_blk, vp_idx);

	if (out_target)
		*out_target = server;

	xive_vdbg(end_x, "END info for ISN %x: prio=%d, server=0x%x (VP %x/%x)\n",
		  isn, prio, server, vp_blk, vp_idx);
	return true;

pick_default:
	xive_vdbg(end_x, "END info for ISN %x: Using masked defaults\n", isn);

	if (out_prio)
		*out_prio = 0xff;
	/* Pick a random default, me will be fine ... */
	if (out_target)
		*out_target = mfspr(SPR_PIR);
	return true;
}

static inline bool xive_end_for_target(uint32_t target, uint8_t prio,
				      uint32_t *out_end_blk,
				      uint32_t *out_end_idx)
{
	struct xive *x;
	struct xive_nvp *vp;
	uint32_t vp_blk, vp_idx;
	uint32_t end_blk, end_idx;

	if (prio > xive_max_prio(one_xive))
		return false;

	/* Get the VP block/index from the target word */
	if (!xive_decode_vp(target, &vp_blk, &vp_idx, NULL, NULL))
		return false;

	/* Grab the target VP's XIVE */
	x = xive_from_pc_blk(vp_blk);
	if (!x)
		return false;

	/* Find the VP structrure where we stashed the END number */
	vp = xive_get_vp(x, vp_idx);
	if (!vp)
		return false;

	end_blk = xive_get_field32(NVP_W5_VP_END_BLOCK, vp->w5);
	end_idx = xive_get_field32(NVP_W5_VP_END_INDEX, vp->w5);

	/* Currently the END block and VP block should be the same */
	if (end_blk != vp_blk) {
		xive_err(x, "end_blk != vp_blk (%d vs. %d) for target 0x%08x/%d\n",
			 end_blk, vp_blk, target, prio);
		assert(false);
	}

	if (out_end_blk)
		*out_end_blk = end_blk;
	if (out_end_idx)
		*out_end_idx = end_idx + prio;

	return true;
}

static int64_t xive_set_irq_targetting(uint32_t isn, uint32_t target,
				       uint8_t prio, uint32_t lirq,
				       bool synchronous)
{
	struct xive *x;
	struct xive_eas *eas, new_eas;
	uint32_t end_blk, end_idx;
	bool is_escalation = GIRQ_IS_ESCALATION(isn);
	int64_t rc;

	/* Find XIVE on which the EAS resides */
	x = xive_from_isn(isn);
	if (!x)
		return OPAL_PARAMETER;
	/* Grab the EAS */
	eas = xive_get_eas(x, isn);
	if (!eas)
		return OPAL_PARAMETER;
	if (!xive_get_field64(EAS_VALID, eas->w) && !is_escalation) {
		xive_err(x, "ISN %x lead to invalid EAS !\n", isn);
		return OPAL_PARAMETER;
	}

	lock(&x->lock);

	/* Read existing EAS */
	new_eas = *eas;

	/* Are we masking ? */
	if (prio == 0xff && !is_escalation) {
		new_eas.w = xive_set_field64(EAS_MASKED, new_eas.w, 1);
		xive_vdbg(x, "ISN %x masked !\n", isn);

		/* Put prio 7 in the END */
		prio = xive_max_prio(x);
	} else {
		/* Unmasking */
		new_eas.w = xive_set_field64(EAS_MASKED, new_eas.w, 0);
		xive_vdbg(x, "ISN %x unmasked !\n", isn);

		/* For normal interrupt sources, keep track of which ones
		 * we ever enabled since the last reset
		 */
		if (!is_escalation)
			bitmap_set_bit(*x->int_enabled_map, GIRQ_TO_IDX(isn));
	}

	/* If prio isn't 0xff, re-target the EAS. First find the END
	 * correponding to the target
	 */
	if (prio != 0xff) {
		if (!xive_end_for_target(target, prio, &end_blk, &end_idx)) {
			xive_err(x, "Can't find END for target/prio 0x%x/%d\n",
				 target, prio);
			unlock(&x->lock);
			return OPAL_PARAMETER;
		}

		/* Try to update it atomically to avoid an intermediary
		 * stale state
		 */
		new_eas.w = xive_set_field64(EAS_END_BLOCK, new_eas.w, end_blk);
		new_eas.w = xive_set_field64(EAS_END_INDEX, new_eas.w, end_idx);
	}
	new_eas.w = xive_set_field64(EAS_END_DATA, new_eas.w, lirq);

	xive_vdbg(x,"ISN %x routed to end %x/%x lirq=%08x EAS=%016llx !\n",
		  isn, end_blk, end_idx, lirq, new_eas.w);

	/* Updating the cache differs between real EAS and escalation
	 * EAS inside an END
	 */
	if (is_escalation) {
		rc = xive_escalation_ive_cache_update(x, x->block_id,
				GIRQ_TO_IDX(isn), &new_eas, synchronous);
	} else {
		sync();
		*eas = new_eas;
		rc = xive_easc_scrub(x, x->block_id, GIRQ_TO_IDX(isn));
	}

	unlock(&x->lock);
	return rc;
}

static void xive_update_irq_mask(struct xive_src *s, uint32_t idx, bool masked)
{
	void *mmio_base = s->esb_mmio + (1ul << s->esb_shift) * idx;
	uint32_t offset;

	/* XXX FIXME: A quick mask/umask can make us shoot an interrupt
	 * more than once to a queue. We need to keep track better
	 */
	if (s->flags & XIVE_SRC_EOI_PAGE1)
		mmio_base += 1ull << (s->esb_shift - 1);
	if (masked)
		offset = XIVE_ESB_SET_PQ_01;
	else
		offset = XIVE_ESB_SET_PQ_00;

	in_be64(mmio_base + offset);
}

#define XIVE_SYNC_IPI      0x000
#define XIVE_SYNC_HW       0x080
#define XIVE_SYNC_NxC      0x100
#define XIVE_SYNC_INT      0x180
#define XIVE_SYNC_OS_ESC   0x200
#define XIVE_SYNC_POOL_ESC 0x280
#define XIVE_SYNC_HARD_ESC 0x300

static int64_t xive_sync(struct xive *x __unused)
{
	uint64_t r;
	void *sync_base;

	lock(&x->lock);

	sync_base = x->ic_base + (XIVE_SYNC_POLL_PGOFF << x->ic_shift);

	out_be64(sync_base + XIVE_SYNC_IPI, 0);
	out_be64(sync_base + XIVE_SYNC_HW, 0);
	out_be64(sync_base + XIVE_SYNC_NxC, 0);
	out_be64(sync_base + XIVE_SYNC_INT, 0);
	out_be64(sync_base + XIVE_SYNC_OS_ESC, 0);
	out_be64(sync_base + XIVE_SYNC_POOL_ESC, 0);
	out_be64(sync_base + XIVE_SYNC_HARD_ESC, 0);

	/* XXX Add timeout */
	for (;;) {
		r = xive_regr(x, VC_ENDC_SYNC_DONE);
		if ((r & VC_ENDC_SYNC_POLL_DONE) == VC_ENDC_SYNC_POLL_DONE)
			break;
		cpu_relax();
	}
	xive_regw(x, VC_ENDC_SYNC_DONE, r & ~VC_ENDC_SYNC_POLL_DONE);

	/*
	 * Do a read after clearing the sync done bit to prevent any
	 * race between CI write and next sync command
	 */
	xive_regr(x, VC_ENDC_SYNC_DONE);

	unlock(&x->lock);
	return 0;
}

static int64_t __xive_set_irq_config(struct irq_source *is, uint32_t girq,
				     uint64_t vp, uint8_t prio, uint32_t lirq,
				     bool update_esb, bool sync)
{
	struct xive_src *s = container_of(is, struct xive_src, is);
	uint32_t old_target, vp_blk;
	u8 old_prio;
	int64_t rc;

	/* Grab existing target */
	if (!xive_get_irq_targetting(girq, &old_target, &old_prio, NULL))
		return OPAL_PARAMETER;

	/* Let XIVE configure the END. We do the update without the
	 * synchronous flag, thus a cache update failure will result
	 * in us returning OPAL_BUSY
	 */
	rc = xive_set_irq_targetting(girq, vp, prio, lirq, false);
	if (rc)
		return rc;

	/* Do we need to update the mask ? */
	if (old_prio != prio && (old_prio == 0xff || prio == 0xff)) {
		/* The source has special variants of masking/unmasking */
		if (update_esb) {
			/* Ensure it's enabled/disabled in the source
			 * controller
			 */
			xive_update_irq_mask(s, girq - s->esb_base,
					     prio == 0xff);
		}
	}

	/*
	 * Synchronize the source and old target XIVEs to ensure that
	 * all pending interrupts to the old target have reached their
	 * respective queue.
	 *
	 * WARNING: This assumes the VP and it's queues are on the same
	 *          XIVE instance !
	 */
	if (!sync)
		return OPAL_SUCCESS;
	xive_sync(s->xive);
	if (xive_decode_vp(old_target, &vp_blk, NULL, NULL, NULL)) {
		struct xive *x = xive_from_pc_blk(vp_blk);
		if (x)
			xive_sync(x);
	}

	return OPAL_SUCCESS;
}

static int64_t xive_set_irq_config(uint32_t girq, uint64_t vp, uint8_t prio,
				   uint32_t lirq, bool update_esb)
{
	struct irq_source *is = irq_find_source(girq);

	return __xive_set_irq_config(is, girq, vp, prio, lirq, update_esb,
				     true);
}

static void xive_source_interrupt(struct irq_source *is, uint32_t isn)
{
	struct xive_src *s = container_of(is, struct xive_src, is);

	if (!s->orig_ops || !s->orig_ops->interrupt)
		return;
	s->orig_ops->interrupt(is, isn);
}

static uint64_t xive_source_attributes(struct irq_source *is, uint32_t isn)
{
	struct xive_src *s = container_of(is, struct xive_src, is);

	if (!s->orig_ops || !s->orig_ops->attributes)
		return IRQ_ATTR_TARGET_LINUX;
	return s->orig_ops->attributes(is, isn);
}

static char *xive_source_name(struct irq_source *is, uint32_t isn)
{
	struct xive_src *s = container_of(is, struct xive_src, is);

	if (!s->orig_ops || !s->orig_ops->name)
		return NULL;
	return s->orig_ops->name(is, isn);
}

void xive2_source_mask(struct irq_source *is, uint32_t isn)
{
	struct xive_src *s = container_of(is, struct xive_src, is);

	xive_update_irq_mask(s, isn - s->esb_base, true);
}

static const struct irq_source_ops xive_irq_source_ops = {
	.interrupt = xive_source_interrupt,
	.attributes = xive_source_attributes,
	.name = xive_source_name,
};

static void __xive_register_source(struct xive *x, struct xive_src *s,
				   uint32_t base, uint32_t count,
				   uint32_t shift, void *mmio, uint32_t flags,
				   bool secondary, void *data,
				   const struct irq_source_ops *orig_ops)
{
	s->esb_base = base;
	s->esb_shift = shift;
	s->esb_mmio = mmio;
	s->flags = flags;
	s->orig_ops = orig_ops;
	s->xive = x;
	s->is.start = base;
	s->is.end = base + count;
	s->is.ops = &xive_irq_source_ops;
	s->is.data = data;

	__register_irq_source(&s->is, secondary);
}

void xive2_register_hw_source(uint32_t base, uint32_t count, uint32_t shift,
			     void *mmio, uint32_t flags, void *data,
			     const struct irq_source_ops *ops)
{
	struct xive_src *s;
	struct xive *x = xive_from_isn(base);

	assert(x);

	s = malloc(sizeof(struct xive_src));
	assert(s);
	__xive_register_source(x, s, base, count, shift, mmio, flags,
			       false, data, ops);
}

static void __xive2_register_esb_source(uint32_t base, uint32_t count,
				void *data, const struct irq_source_ops *ops)
{
	struct xive_src *s;
	struct xive *x = xive_from_isn(base);
	uint32_t base_idx = GIRQ_TO_IDX(base);
	void *mmio_base;
	uint32_t flags = XIVE_SRC_EOI_PAGE1 | XIVE_SRC_TRIGGER_PAGE;

	assert(x);

	s = malloc(sizeof(struct xive_src));
	assert(s);

	if (XIVE_CAN_STORE_EOI(x))
		flags |= XIVE_SRC_STORE_EOI;

	/* Callbacks assume the MMIO base corresponds to the first
	 * interrupt of that source structure so adjust it
	 */
	mmio_base = x->esb_base + (1ul << XIVE_ESB_SHIFT) * base_idx;
	__xive_register_source(x, s, base, count, XIVE_ESB_SHIFT, mmio_base,
			       flags, false, data, ops);
}

/*
 * Check that IPI sources have interrupt numbers in the IPI interrupt
 * number range
 */
void xive2_register_ipi_source(uint32_t base, uint32_t count, void *data,
			       const struct irq_source_ops *ops)
{
	struct xive *x = xive_from_isn(base);

	assert(x);
	assert(base >= x->int_base && (base + count) <= x->int_ipi_top);

	__xive2_register_esb_source(base, count, data, ops);
}

/*
 * Some HW sources (PHB) can disable the use of their own ESB pages
 * and offload all the checks on ESB pages of the IC. The interrupt
 * numbers are not necessarily in the IPI range.
 */
void xive2_register_esb_source(uint32_t base, uint32_t count)
{
	__xive2_register_esb_source(base, count, NULL, NULL);
}

uint64_t xive2_get_esb_base(uint32_t base)
{
	struct xive *x = xive_from_isn(base);
	uint32_t base_idx = GIRQ_TO_IDX(base);

	assert(x);

	return (uint64_t) x->esb_base + (1ul << XIVE_ESB_SHIFT) * base_idx;
}

static void xive_set_quirks(struct xive *x, struct proc_chip *chip __unused)
{
	uint64_t quirks = 0;

	/* This extension is dropped for P10 */
	if (proc_gen == proc_gen_p10)
		quirks |= XIVE_QUIRK_THREADID_7BITS;

	/* Broken check on invalid priority when reduced priorities is in use */
	if (proc_gen == proc_gen_p10)
		quirks |= XIVE_QUIRK_BROKEN_PRIO_CHECK;

	xive_dbg(x, "setting XIVE quirks to %016llx\n", quirks);
	x->quirks = quirks;
}

static struct xive *init_one_xive(struct dt_node *np)
{
	struct xive *x;
	struct proc_chip *chip;
	uint32_t flags;

	x = zalloc(sizeof(struct xive));
	assert(x);
	x->x_node = np;
	x->xscom_base = dt_get_address(np, 0, NULL);
	x->chip_id = dt_get_chip_id(np);

	/* "Allocate" a new block ID for the chip */
	x->block_id = xive_block_count++;
	assert (x->block_id < XIVE_MAX_CHIPS);
	xive_block_to_chip[x->block_id] = x->chip_id;
	init_lock(&x->lock);

	chip = get_chip(x->chip_id);
	assert(chip);

	xive_notice(x, "Initializing XIVE block ID %d...\n", x->block_id);
	chip->xive = x;

	xive_set_quirks(x, chip);

	list_head_init(&x->donated_pages);

	/* Base interrupt numbers and allocator init */

	x->int_base	= BLKIDX_TO_GIRQ(x->block_id, 0);
	x->int_count	= x->int_base + XIVE_INT_COUNT;
	x->int_hw_bot	= x->int_count;
	x->int_ipi_top	= x->int_base;

	if (x->int_ipi_top < XIVE_INT_FIRST)
		x->int_ipi_top = XIVE_INT_FIRST;

	/* Allocate a few bitmaps */
	x->end_map = local_alloc(x->chip_id, BITMAP_BYTES(xive_end_bitmap_size(x)), PAGE_SIZE);
	assert(x->end_map);
	memset(x->end_map, 0, BITMAP_BYTES(xive_end_bitmap_size(x)));

	/*
	 * Allocate END index 0 to make sure it can not be used as an
	 * END base for a VP. This is the criteria to know if a VP was
	 * allocated.
	 */
	bitmap_set_bit(*x->end_map, 0);

	x->int_enabled_map = local_alloc(x->chip_id, BITMAP_BYTES(XIVE_INT_COUNT), PAGE_SIZE);
	assert(x->int_enabled_map);
	memset(x->int_enabled_map, 0, BITMAP_BYTES(XIVE_INT_COUNT));
	x->ipi_alloc_map = local_alloc(x->chip_id, BITMAP_BYTES(XIVE_INT_COUNT), PAGE_SIZE);
	assert(x->ipi_alloc_map);
	memset(x->ipi_alloc_map, 0, BITMAP_BYTES(XIVE_INT_COUNT));

	xive_dbg(x, "Handling interrupts [%08x..%08x]\n",
		 x->int_base, x->int_count - 1);

	/* Setup the IC BARs */
	if (!xive_configure_ic_bars(x))
		goto fail;

	/* Some basic global inits such as page sizes etc... */
	if (!xive_config_init(x))
		goto fail;

	/* Configure the set translations for MMIO */
	if (!xive_setup_set_xlate(x))
		goto fail;

	/* Dump some MMIO registers for diagnostics */
	xive_dump_mmio(x);

	/* Pre-allocate a number of tables */
	if (!xive_prealloc_tables(x))
		goto fail;

	/* Setup the XIVE structures BARs */
	if (!xive_configure_bars(x))
		goto fail;

	/*
	 * Configure local tables in VSDs (forward ports will be
	 * handled later)
	 */
	if (!xive_set_local_tables(x))
		goto fail;

	/* Register built-in source controllers (aka IPIs) */
	flags = XIVE_SRC_EOI_PAGE1 | XIVE_SRC_TRIGGER_PAGE;
	if (XIVE_CAN_STORE_EOI(x))
		flags |= XIVE_SRC_STORE_EOI;
	__xive_register_source(x, &x->ipis, x->int_base,
			       x->int_hw_bot - x->int_base, XIVE_ESB_SHIFT,
			       x->esb_base, flags, true, NULL, NULL);

	/* Register escalation sources (ENDs)
	 *
	 * The ESe PQ bits are used for coalescing and the END ESB for
	 * interrupt management. The word 4&5 of the END is the EAS
	 * for the escalation source and the indexing is the same as
	 * the END.
	 *
	 * This is an OPAL primary source, IPIs are secondary.
	 */
	__xive_register_source(x, &x->esc_irqs,
			       MAKE_ESCALATION_GIRQ(x->block_id, 0),
			       XIVE_END_COUNT, XIVE_END_SHIFT,
			       x->end_base, XIVE_SRC_EOI_PAGE1,
			       false, NULL, NULL);


	return x;
 fail:
	xive_err(x, "Initialization failed...\n");

	/* Should this be fatal ? */
	//assert(false);
	return NULL;
}

static void xive_reset_enable_thread(struct cpu_thread *c)
{
	struct proc_chip *chip = get_chip(c->chip_id);
	struct xive *x = chip->xive;
	uint32_t fc, bit;
	uint64_t enable;

	/* Get fused core number */
	fc = (c->pir >> 3) & 0xf;

	/* Get bit in register */
	bit = c->pir & 0x3f;

	/* Get which register to access */
	if (fc < 8) {
		xive_regw(x, TCTXT_EN0_RESET, PPC_BIT(bit));
		xive_regw(x, TCTXT_EN0_SET, PPC_BIT(bit));

		enable = xive_regr(x, TCTXT_EN0);
		if (!(enable & PPC_BIT(bit)))
			xive_cpu_err(c, "Failed to enable thread\n");
	} else {
		xive_regw(x, TCTXT_EN1_RESET, PPC_BIT(bit));
		xive_regw(x, TCTXT_EN1_SET, PPC_BIT(bit));

		enable = xive_regr(x, TCTXT_EN1);
		if (!(enable & PPC_BIT(bit)))
			xive_cpu_err(c, "Failed to enable thread\n");
	}
}

void xive2_cpu_callin(struct cpu_thread *cpu)
{
	struct xive_cpu_state *xs = cpu->xstate;
	uint8_t old_w2 __unused, w2 __unused;

	if (!xs)
		return;

	/* Reset the HW thread context and enable it */
	xive_reset_enable_thread(cpu);

	/* Set VT to 1 */
	old_w2 = in_8(xs->tm_ring1 + TM_QW3_HV_PHYS + TM_WORD2);
	out_8(xs->tm_ring1 + TM_QW3_HV_PHYS + TM_WORD2, 0x80);
	w2 = in_8(xs->tm_ring1 + TM_QW3_HV_PHYS + TM_WORD2);

	xive_cpu_vdbg(cpu, "Initialized TIMA VP=%x/%x W01=%016llx W2=%02x->%02x\n",
		      xs->vp_blk, xs->vp_idx,
		      in_be64(xs->tm_ring1 + TM_QW3_HV_PHYS),
		      old_w2, w2);
}

#ifdef XIVE_EXTRA_CHECK_INIT_CACHE
#define CHECK_INIT_CACHE_LOOP 0x100
static void xive_special_cache_check(struct xive *x, uint32_t blk, uint32_t idx)
{
	struct xive_nvp vp = {0};
	uint32_t i;

	/*
	 * SIMICS checks the value of reserved fields
	 */
	if (chip_quirk(QUIRK_SIMICS))
		return;

	for (i = 0; i < CHECK_INIT_CACHE_LOOP; i++) {
		struct xive_nvp *vp_m = xive_get_vp(x, idx);

		memset(vp_m, (~i) & 0xff, sizeof(*vp_m));
		vp_m->w0 = xive_set_field32(NVP_W0_VALID, vp_m->w0, 0);
		sync();
		vp.w1 = (i << 16) | i;
		assert(!xive_nxc_cache_update(x, blk, idx, &vp, true));
		if (!xive_check_nxc_update(x, idx, &vp)) {
			xive_dbg(x, "NXC update test failed at %d iterations\n", i);
			return;
		}
	}
	xive_dbg(x, "NXC update test passed for %d/0x%x\n", blk, idx);
}
#else
static inline void xive_special_cache_check(struct xive *x __unused,
					    uint32_t blk __unused,
					    uint32_t idx __unused)
{
}
#endif

static void xive_init_cpu_exploitation(struct xive_cpu_state *xs)
{
	struct xive_end end;
	struct xive_nvp vp;
	struct xive *x_vp, *x_end;
	int i;

	/* Grab the XIVE where the VP resides. It could be different from
	 * the local chip XIVE if not using block group mode
	 */
	x_vp = xive_from_pc_blk(xs->vp_blk);
	assert(x_vp);

	/* Grab the XIVE where the END resides. It should be the same
	 * as the VP.
	 */
	x_end = xive_from_vc_blk(xs->end_blk);
	assert(x_end);

	xive_init_hw_end(&end);

	/* Use the cache watch to update all ENDs reserved for HW VPs */
	lock(&x_end->lock);
	for (i = 0; i < xive_cfg_vp_prio(x_end); i++)
		xive_endc_cache_update(x_end, xs->end_blk, xs->end_idx + i,
				       &end, true);
	unlock(&x_end->lock);

	/* Initialize/enable the VP */
	xive_init_default_vp(&vp, xs->end_blk, xs->end_idx);

	/* Use the cache watch to write it out */
	lock(&x_vp->lock);
	xive_special_cache_check(x_vp, xs->vp_blk, xs->vp_idx);
	xive_nxc_cache_update(x_vp, xs->vp_blk, xs->vp_idx, &vp, true);
	unlock(&x_vp->lock);
}

static void xive_configure_ex_special_bar(struct xive *x, struct cpu_thread *c)
{
	uint64_t xa, val;
	int64_t rc;

	xive_cpu_vdbg(c, "Setting up special BAR\n");
	xa = XSCOM_ADDR_P10_NCU(pir_to_core_id(c->pir), P10_NCU_SPEC_BAR);
	val = (uint64_t)x->tm_base | P10_NCU_SPEC_BAR_ENABLE;
	if (x->tm_shift == 16)
		val |= P10_NCU_SPEC_BAR_256K;
	xive_cpu_vdbg(c, "NCU_SPEC_BAR_XA[%08llx]=%016llx\n", xa, val);
	rc = xscom_write(c->chip_id, xa, val);
	if (rc) {
		xive_cpu_err(c, "Failed to setup NCU_SPEC_BAR\n");
		/* XXXX  what do do now ? */
	}
}

void xive2_late_init(void)
{
	struct cpu_thread *c;

	prlog(PR_INFO, "SLW: Configuring self-restore for NCU_SPEC_BAR\n");
	for_each_present_cpu(c) {
		if(cpu_is_thread0(c)) {
			struct proc_chip *chip = get_chip(c->chip_id);
			struct xive *x = chip->xive;
			uint64_t xa, val, rc;
			xa = XSCOM_ADDR_P10_NCU(pir_to_core_id(c->pir), P10_NCU_SPEC_BAR);
			val = (uint64_t)x->tm_base | P10_NCU_SPEC_BAR_ENABLE;
			/* Bail out if wakeup engine has already failed */
			if (wakeup_engine_state != WAKEUP_ENGINE_PRESENT) {
				prlog(PR_ERR, "XIVE proc_stop_api fail detected\n");
				break;
			}
			rc = proc_stop_save_scom((void *)chip->homer_base, xa, val,
				PROC_STOP_SCOM_REPLACE, PROC_STOP_SECTION_L3);
			if (rc) {
				xive_cpu_err(c, "proc_stop_save_scom failed for NCU_SPEC_BAR rc=%lld\n",
					     rc);
				wakeup_engine_state = WAKEUP_ENGINE_FAILED;
			}
		}
	}
}

static void xive_provision_cpu(struct xive_cpu_state *xs, struct cpu_thread *c)
{
	struct xive *x;

	/* VP ids for HW threads are pre-allocated */
	xs->vp_blk = PIR2VP_BLK(c->pir);
	xs->vp_idx = PIR2VP_IDX(c->pir);

	/* For now we use identical block IDs for VC and PC but that might
	 * change. We allocate the ENDs on the same XIVE as the VP.
	 */
	xs->end_blk = xs->vp_blk;

	/* Grab the XIVE where the END resides. It could be different from
	 * the local chip XIVE if not using block group mode
	 */
	x = xive_from_vc_blk(xs->end_blk);
	assert(x);

	/* Allocate a set of ENDs for that VP */
	xs->end_idx = xive_alloc_end_set(x, true);
	assert(!XIVE_ALLOC_IS_ERR(xs->end_idx));
}

static void xive_init_cpu(struct cpu_thread *c)
{
	struct proc_chip *chip = get_chip(c->chip_id);
	struct xive *x = chip->xive;
	struct xive_cpu_state *xs;

	if (!x)
		return;

	/*
	 * Each core pair (EX) needs this special BAR setup to have the
	 * right powerbus cycle for the TM area (as it has the same address
	 * on all chips so it's somewhat special).
	 *
	 * Because we don't want to bother trying to figure out which core
	 * of a pair is present we just do the setup for each of them, which
	 * is harmless.
	 */
	if (cpu_is_thread0(c) || cpu_is_core_chiplet_primary(c))
		xive_configure_ex_special_bar(x, c);

	/* Initialize the state structure */
	c->xstate = xs = local_alloc(c->chip_id, sizeof(struct xive_cpu_state), 1);
	assert(xs);
	memset(xs, 0, sizeof(struct xive_cpu_state));
	xs->xive = x;

	init_lock(&xs->lock);

	/* Shortcut to TM HV ring */
	xs->tm_ring1 = x->tm_base + (1u << x->tm_shift);

	/* Provision a VP id and some ENDs for a HW thread */
	xive_provision_cpu(xs, c);

	xive_init_cpu_exploitation(xs);
}

static uint64_t xive_convert_irq_flags(uint64_t iflags)
{
	uint64_t oflags = 0;

	if (iflags & XIVE_SRC_STORE_EOI)
		oflags |= OPAL_XIVE_IRQ_STORE_EOI2;

	/* OPAL_XIVE_IRQ_TRIGGER_PAGE is only meant to be set if
	 * the interrupt has a *separate* trigger page.
	 */
	if ((iflags & XIVE_SRC_EOI_PAGE1) &&
	    (iflags & XIVE_SRC_TRIGGER_PAGE))
		oflags |= OPAL_XIVE_IRQ_TRIGGER_PAGE;

	if (iflags & XIVE_SRC_LSI)
		oflags |= OPAL_XIVE_IRQ_LSI;

	return oflags;
}

static int64_t opal_xive_get_irq_info(uint32_t girq,
				      beint64_t *out_flags,
				      beint64_t *out_eoi_page,
				      beint64_t *out_trig_page,
				      beint32_t *out_esb_shift,
				      beint32_t *out_src_chip)
{
	struct irq_source *is = irq_find_source(girq);
	struct xive_src *s = container_of(is, struct xive_src, is);
	uint32_t idx;
	uint64_t mm_base;
	uint64_t eoi_page = 0, trig_page = 0;

	if (xive_mode != XIVE_MODE_EXPL)
		return OPAL_WRONG_STATE;
	if (is == NULL || out_flags == NULL)
		return OPAL_PARAMETER;
	assert(is->ops == &xive_irq_source_ops);

	if (out_flags)
		*out_flags = cpu_to_be64(xive_convert_irq_flags(s->flags));

	idx = girq - s->esb_base;

	if (out_esb_shift)
		*out_esb_shift = cpu_to_be32(s->esb_shift);

	mm_base = (uint64_t)s->esb_mmio + (1ull << s->esb_shift) * idx;

	/* The EOI page can either be the first or second page */
	if (s->flags & XIVE_SRC_EOI_PAGE1) {
		uint64_t p1off = 1ull << (s->esb_shift - 1);
		eoi_page = mm_base + p1off;
	} else
		eoi_page = mm_base;

	/* The trigger page, if it exists, is always the first page */
	if (s->flags & XIVE_SRC_TRIGGER_PAGE)
		trig_page = mm_base;

	if (out_eoi_page)
		*out_eoi_page = cpu_to_be64(eoi_page);
	if (out_trig_page)
		*out_trig_page = cpu_to_be64(trig_page);
	if (out_src_chip)
		*out_src_chip = cpu_to_be32(GIRQ_TO_CHIP(girq));

	return OPAL_SUCCESS;
}

static int64_t opal_xive_get_irq_config(uint32_t girq,
					beint64_t *out_vp,
					uint8_t *out_prio,
					beint32_t *out_lirq)
{
	uint32_t vp;
	uint32_t lirq;
	uint8_t prio;

	if (xive_mode != XIVE_MODE_EXPL)
               return OPAL_WRONG_STATE;

	if (xive_get_irq_targetting(girq, &vp, &prio, &lirq)) {
		*out_vp = cpu_to_be64(vp);
		*out_prio = prio;
		*out_lirq = cpu_to_be32(lirq);
		return OPAL_SUCCESS;
	} else
		return OPAL_PARAMETER;
}

static int64_t opal_xive_set_irq_config(uint32_t girq,
					uint64_t vp,
					uint8_t prio,
					uint32_t lirq)
{
	/*
	 * This variant is meant for a XIVE-aware OS, thus it will
	 * *not* affect the ESB state of the interrupt. If used with
	 * a prio of FF, the EAS will be masked. In that case the
	 * races have to be handled by the OS.
	 */
	if (xive_mode != XIVE_MODE_EXPL)
               return OPAL_WRONG_STATE;

	return xive_set_irq_config(girq, vp, prio, lirq, false);
}

static int64_t opal_xive_get_queue_info(uint64_t vp, uint32_t prio,
					beint64_t *out_qpage,
					beint64_t *out_qsize,
					beint64_t *out_qeoi_page,
					beint32_t *out_escalate_irq,
					beint64_t *out_qflags)
{
	uint32_t blk, idx;
	struct xive *x;
	struct xive_end *end;

	if (xive_mode != XIVE_MODE_EXPL)
               return OPAL_WRONG_STATE;

	if (!xive_end_for_target(vp, prio, &blk, &idx))
		return OPAL_PARAMETER;

	x = xive_from_vc_blk(blk);
	if (!x)
		return OPAL_PARAMETER;

	end = xive_get_end(x, idx);
	if (!end)
		return OPAL_PARAMETER;

	if (out_escalate_irq) {
		uint32_t esc_idx = idx;

		/* If escalations are routed to a single queue, fix up
		 * the escalation interrupt number here.
		 */
		if (xive_get_field32(END_W0_UNCOND_ESCALATE, end->w0))
			esc_idx |= xive_escalation_prio(x);
		*out_escalate_irq =
			cpu_to_be32(MAKE_ESCALATION_GIRQ(blk, esc_idx));
	}

	/* If this is a single-escalation gather queue, that's all
	 * there is to return
	 */
	if (xive_get_field32(END_W0_SILENT_ESCALATE, end->w0)) {
		if (out_qflags)
			*out_qflags = 0;
		if (out_qpage)
			*out_qpage = 0;
		if (out_qsize)
			*out_qsize = 0;
		if (out_qeoi_page)
			*out_qeoi_page = 0;
		return OPAL_SUCCESS;
	}

	if (out_qpage) {
		if (xive_get_field32(END_W0_ENQUEUE, end->w0))
			*out_qpage = cpu_to_be64(
				((uint64_t)xive_get_field32(END_W2_EQ_ADDR_HI, end->w2) << 32) |
				xive_get_field32(END_W3_EQ_ADDR_LO, end->w3));
		else
			*out_qpage = 0;
	}
	if (out_qsize) {
		if (xive_get_field32(END_W0_ENQUEUE, end->w0))
			*out_qsize = cpu_to_be64(xive_get_field32(END_W3_QSIZE, end->w3) + 12);
		else
			*out_qsize = 0;
	}
	if (out_qeoi_page) {
		*out_qeoi_page = cpu_to_be64(
			(uint64_t)x->end_base + idx * XIVE_ESB_PAGE_SIZE);
	}
	if (out_qflags) {
		*out_qflags = 0;
		if (xive_get_field32(END_W0_VALID, end->w0))
			*out_qflags |= cpu_to_be64(OPAL_XIVE_EQ_ENABLED);
		if (xive_get_field32(END_W0_UCOND_NOTIFY, end->w0))
			*out_qflags |= cpu_to_be64(OPAL_XIVE_EQ_ALWAYS_NOTIFY);
		if (xive_get_field32(END_W0_ESCALATE_CTL, end->w0))
			*out_qflags |= cpu_to_be64(OPAL_XIVE_EQ_ESCALATE);
	}

	return OPAL_SUCCESS;
}

static void xive_cleanup_end(struct xive_end *end)
{
	end->w0 = xive_set_field32(END_W0_FIRMWARE1, 0, xive_end_is_firmware1(end));
	end->w1 = xive_set_field32(END_W1_ESe_Q, 0, 1) |
		  xive_set_field32(END_W1_ESn_Q, 0, 1);
	end->w2 = end->w3 = end->w4 = end->w5 = end->w6 = end->w7 = 0;
}

static int64_t opal_xive_set_queue_info(uint64_t vp, uint32_t prio,
					uint64_t qpage,
					uint64_t qsize,
					uint64_t qflags)
{
	uint32_t blk, idx;
	struct xive *x;
	struct xive_end *old_end;
	struct xive_end end;
	uint32_t vp_blk, vp_idx;
	bool group;
	int64_t rc;

	if (!xive_end_for_target(vp, prio, &blk, &idx))
		return OPAL_PARAMETER;

	x = xive_from_vc_blk(blk);
	if (!x)
		return OPAL_PARAMETER;

	old_end = xive_get_end(x, idx);
	if (!old_end)
		return OPAL_PARAMETER;

	/* If this is a silent escalation queue, it cannot be
	 * configured directly
	 */
	if (xive_get_field32(END_W0_SILENT_ESCALATE, old_end->w0))
		return OPAL_PARAMETER;

	/* This shouldn't fail or xive_end_for_target would have
	 * failed already
	 */
	if (!xive_decode_vp(vp, &vp_blk, &vp_idx, NULL, &group))
		return OPAL_PARAMETER;

	/*
	 * Make a local copy which we will later try to commit using
	 * the cache watch facility
	 */
	end = *old_end;

	if (qflags & OPAL_XIVE_EQ_ENABLED) {
		switch(qsize) {
			/* Supported sizes */
		case 12:
		case 16:
		case 21:
		case 24:
			end.w3 = cpu_to_be32(qpage & END_W3_EQ_ADDR_LO);
			end.w2 = cpu_to_be32((qpage >> 32) & END_W2_EQ_ADDR_HI);
			end.w3 = xive_set_field32(END_W3_QSIZE, end.w3, qsize - 12);
			end.w0 = xive_set_field32(END_W0_ENQUEUE, end.w0, 1);
			break;
		case 0:
			end.w2 = end.w3 = 0;
			end.w0 = xive_set_field32(END_W0_ENQUEUE, end.w0, 0);
			break;
		default:
			return OPAL_PARAMETER;
		}

		/* Ensure the priority and target are correctly set (they will
		 * not be right after allocation
		 */
		end.w6 = xive_set_field32(END_W6_VP_BLOCK, 0, vp_blk) |
			xive_set_field32(END_W6_VP_OFFSET, 0, vp_idx);
		end.w7 = xive_set_field32(END_W7_F0_PRIORITY, 0, prio);
		/* XXX Handle group i bit when needed */

		/* Always notify flag */
		if (qflags & OPAL_XIVE_EQ_ALWAYS_NOTIFY)
			end.w0 = xive_set_field32(END_W0_UCOND_NOTIFY, end.w0, 1);
		else
			end.w0 = xive_set_field32(END_W0_UCOND_NOTIFY, end.w0, 0);

		/* Escalation flag */
		if (qflags & OPAL_XIVE_EQ_ESCALATE)
			end.w0 = xive_set_field32(END_W0_ESCALATE_CTL, end.w0, 1);
		else
			end.w0 = xive_set_field32(END_W0_ESCALATE_CTL, end.w0, 0);

		/* Unconditionally clear the current queue pointer, set
		 * generation to 1 and disable escalation interrupts.
		 */
		end.w1 = xive_set_field32(END_W1_GENERATION, 0, 1) |
			 xive_set_field32(END_W1_ES, 0, xive_get_field32(END_W1_ES, old_end->w1));

		/* Enable. We always enable backlog for an enabled queue
		 * otherwise escalations won't work.
		 */
		end.w0 = xive_set_field32(END_W0_VALID, end.w0, 1);
		end.w0 = xive_set_field32(END_W0_BACKLOG, end.w0, 1);
	} else
		xive_cleanup_end(&end);

	/* Update END, non-synchronous */
	lock(&x->lock);
	rc = xive_endc_cache_update(x, blk, idx, &end, false);
	unlock(&x->lock);

	return rc;
}

static int64_t opal_xive_get_queue_state(uint64_t vp, uint32_t prio,
					 beint32_t *out_qtoggle,
					 beint32_t *out_qindex)
{
	uint32_t blk, idx;
	struct xive *x;
	struct xive_end *end;
	int64_t rc;

	if (xive_mode != XIVE_MODE_EXPL)
		return OPAL_WRONG_STATE;

	if (!out_qtoggle || !out_qindex ||
	    !xive_end_for_target(vp, prio, &blk, &idx))
		return OPAL_PARAMETER;

	x = xive_from_vc_blk(blk);
	if (!x)
		return OPAL_PARAMETER;

	end = xive_get_end(x, idx);
	if (!end)
		return OPAL_PARAMETER;

	/* Scrub the queue */
	lock(&x->lock);
	rc = xive_endc_scrub(x, blk, idx);
	unlock(&x->lock);
	if (rc)
		return rc;

	/* We don't do disable queues */
	if (!xive_get_field32(END_W0_VALID, end->w0))
		return OPAL_WRONG_STATE;

	*out_qtoggle = cpu_to_be32(xive_get_field32(END_W1_GENERATION, end->w1));
	*out_qindex  = cpu_to_be32(xive_get_field32(END_W1_PAGE_OFF, end->w1));

	return OPAL_SUCCESS;
}

static int64_t opal_xive_set_queue_state(uint64_t vp, uint32_t prio,
					 uint32_t qtoggle, uint32_t qindex)
{
	uint32_t blk, idx;
	struct xive *x;
	struct xive_end *end, new_end;
	int64_t rc;

	if (xive_mode != XIVE_MODE_EXPL)
		return OPAL_WRONG_STATE;

	if (!xive_end_for_target(vp, prio, &blk, &idx))
		return OPAL_PARAMETER;

	x = xive_from_vc_blk(blk);
	if (!x)
		return OPAL_PARAMETER;

	end = xive_get_end(x, idx);
	if (!end)
		return OPAL_PARAMETER;

	/* We don't do disable queues */
	if (!xive_get_field32(END_W0_VALID, end->w0))
		return OPAL_WRONG_STATE;

	new_end = *end;

	new_end.w1 = xive_set_field32(END_W1_GENERATION, new_end.w1, qtoggle);
	new_end.w1 = xive_set_field32(END_W1_PAGE_OFF, new_end.w1, qindex);

	lock(&x->lock);
	rc = xive_endc_cache_update(x, blk, idx, &new_end, false);
	unlock(&x->lock);

	return rc;
}

static int64_t opal_xive_donate_page(uint32_t chip_id, uint64_t addr)
{
	struct proc_chip *c = get_chip(chip_id);
	struct list_node *n;

	if (xive_mode != XIVE_MODE_EXPL)
		return OPAL_WRONG_STATE;
	if (!c)
		return OPAL_PARAMETER;
	if (!c->xive)
		return OPAL_PARAMETER;
	if (addr & 0xffff)
		return OPAL_PARAMETER;

	n = (struct list_node *)addr;
	lock(&c->xive->lock);
	list_add(&c->xive->donated_pages, n);
	unlock(&c->xive->lock);
	return OPAL_SUCCESS;
}

static int64_t opal_xive_get_vp_info(uint64_t vp_id,
				     beint64_t *out_flags,
				     beint64_t *out_cam_value,
				     beint64_t *out_report_cl_pair,
				     beint32_t *out_chip_id)
{
	struct xive *x;
	struct xive_nvp *vp;
	uint32_t blk, idx;
	bool group;

	if (!xive_decode_vp(vp_id, &blk, &idx, NULL, &group))
		return OPAL_PARAMETER;
	/* We don't do groups yet */
	if (group)
		return OPAL_PARAMETER;
	x = xive_from_pc_blk(blk);
	if (!x)
		return OPAL_PARAMETER;
	vp = xive_get_vp(x, idx);
	if (!vp)
		return OPAL_PARAMETER;

	if (out_flags) {
		uint32_t end_blk, end_idx;
		struct xive_end *end;
		struct xive *end_x;
		*out_flags = 0;

		/*
		 * We would like to a way to stash a SW bit in the VP
		 * to know whether silent escalation is enabled or
		 * not, but unlike what happens with ENDs, the PC
		 * cache watch doesn't implement the reserved bit in
		 * the VPs... so we have to go look at END 7 instead.
		 */

		/* Grab END for prio 7 to check for silent escalation */
		if (!xive_end_for_target(vp_id, xive_escalation_prio(x),
					 &end_blk, &end_idx))
			return OPAL_PARAMETER;

		end_x = xive_from_vc_blk(end_blk);
		if (!end_x)
			return OPAL_PARAMETER;

		end = xive_get_end(x, end_idx);
		if (!end)
			return OPAL_PARAMETER;
		if (xive_get_field32(NVP_W0_VALID, vp->w0))
			*out_flags |= cpu_to_be64(OPAL_XIVE_VP_ENABLED);
		if (xive_cfg_save_restore(x))
			*out_flags |= cpu_to_be64(OPAL_XIVE_VP_SAVE_RESTORE);
		if (xive_get_field32(END_W0_SILENT_ESCALATE, end->w0))
			*out_flags |= cpu_to_be64(OPAL_XIVE_VP_SINGLE_ESCALATION);
	}

	if (out_cam_value) {
		uint64_t cam_value;

		cam_value = (blk << x->vp_shift) | idx;

		/*
		 * If save-restore is enabled, force the CAM line
		 * value with the H bit.
		 */
		if (xive_cfg_save_restore(x))
			cam_value |= TM10_QW1W2_HO;

		*out_cam_value = cpu_to_be64(cam_value);
	}

	if (out_report_cl_pair) {
		uint64_t report_cl_pair;

		report_cl_pair = ((uint64_t)(be32_to_cpu(vp->w6) & 0x0fffffff)) << 32;
		report_cl_pair |= be32_to_cpu(vp->w7) & 0xffffff00;

		*out_report_cl_pair = cpu_to_be64(report_cl_pair);
	}

	if (out_chip_id)
		*out_chip_id = cpu_to_be32(xive_block_to_chip[blk]);

	return OPAL_SUCCESS;
}

static int64_t xive_setup_silent_gather(uint64_t vp_id, bool enable)
{
	uint32_t blk, idx, i;
	struct xive_end *end_orig;
	struct xive_end end;
	struct xive *x;
	int64_t rc;

	/* Get base END block */
	if (!xive_end_for_target(vp_id, 0, &blk, &idx)) {
		prlog(PR_ERR, "%s: Invalid VP 0x%08llx\n", __func__, vp_id);
		return OPAL_PARAMETER;
	}
	x = xive_from_vc_blk(blk);
	if (!x) {
		prlog(PR_ERR, "%s: VP 0x%08llx has invalid block %d\n", __func__,
		      vp_id, blk);
		return OPAL_PARAMETER;
	}

	/* Grab prio 7 */
	end_orig = xive_get_end(x, idx + xive_escalation_prio(x));
	if (!end_orig) {
		xive_err(x, "Failed to get silent gather END 0x%x for VP 0x%08llx\n",
			 idx + xive_escalation_prio(x), vp_id);
		return OPAL_PARAMETER;
	}

	/* If trying to enable silent gather, make sure prio 7 is not
	 * already enabled as a normal queue
	 */
	if (enable && xive_get_field32(END_W0_VALID, end_orig->w0) &&
	    !xive_get_field32(END_W0_SILENT_ESCALATE, end_orig->w0)) {
		xive_err(x, "silent gather END 0x%x already in use\n",
			 idx + xive_escalation_prio(x));
		return OPAL_PARAMETER;
	}

	end = *end_orig;

	if (enable) {
		/* W0: Enabled and "s" set, no other bit */
		end.w0 = xive_set_field32(END_W0_FIRMWARE1, end.w0, 0);
		end.w0 = xive_set_field32(END_W0_VALID, end.w0, 1);
		end.w0 = xive_set_field32(END_W0_SILENT_ESCALATE, end.w0, 1);
		end.w0 = xive_set_field32(END_W0_ESCALATE_CTL, end.w0, 1);
		end.w0 = xive_set_field32(END_W0_BACKLOG, end.w0, 1);

		/* Set new "N" for END escalation (vs. ESB)  */
		end.w0 = xive_set_field32(END_W0_ESCALATE_END, end.w0, 1);

		/* W1: Mark ESn as 01, ESe as 00 */
		end.w1 = xive_set_field32(END_W1_ESn_P, end.w1, 0);
		end.w1 = xive_set_field32(END_W1_ESn_Q, end.w1, 1);
		end.w1 = xive_set_field32(END_W1_ESe, end.w1, 0);
	} else if (xive_get_field32(END_W0_SILENT_ESCALATE, end.w0))
		xive_cleanup_end(&end);

	if (!memcmp(end_orig, &end, sizeof(end)))
		rc = 0;
	else
		rc = xive_endc_cache_update(x, blk, idx + xive_escalation_prio(x),
					    &end, false);
	if (rc)
		return rc;

	/* Mark/unmark all other prios with the new "u" bit and update
	 * escalation
	 */
	for (i = 0; i < xive_cfg_vp_prio(x); i++) {
		if (i == xive_escalation_prio(x))
			continue;
		end_orig = xive_get_end(x, idx + i);
		if (!end_orig)
			continue;
		end = *end_orig;
		if (enable) {
			/* Set "u" bit */
			end.w0 = xive_set_field32(END_W0_UNCOND_ESCALATE, end.w0, 1);

			/* Set new "N" for END escalation (vs. ESB)  */
			/* TODO (Gen2+) : use ESB escalation configuration */
			end.w0 = xive_set_field32(END_W0_ESCALATE_END, end.w0, 1);

			/* Re-route escalation interrupt (previous
			 * route is lost !) to the gather queue
			 */
			end.w4 = xive_set_field32(END_W4_END_BLOCK, end.w4, blk);
			end.w4 = xive_set_field32(END_W4_ESC_END_INDEX,
					  end.w4, idx + xive_escalation_prio(x));
		} else if (xive_get_field32(END_W0_UNCOND_ESCALATE, end.w0)) {
			/* Clear the "u" bit, disable escalations if it was set */
			end.w0 = xive_set_field32(END_W0_UNCOND_ESCALATE, end.w0, 0);
			end.w0 = xive_set_field32(END_W0_ESCALATE_CTL, end.w0, 0);
		}
		if (!memcmp(end_orig, &end, sizeof(end)))
			continue;
		rc = xive_endc_cache_update(x, blk, idx + i, &end, false);
		if (rc)
			break;
	}

	return rc;
}

static int64_t opal_xive_set_vp_info(uint64_t vp_id,
				     uint64_t flags,
				     uint64_t report_cl_pair)
{
	struct xive *x;
	struct xive_nvp *vp, vp_new;
	uint32_t blk, idx;
	bool group;
	int64_t rc;

	if (!xive_decode_vp(vp_id, &blk, &idx, NULL, &group))
		return OPAL_PARAMETER;
	/* We don't do groups yet */
	if (group)
		return OPAL_PARAMETER;
	if (report_cl_pair & 0xff)
		return OPAL_PARAMETER;
	x = xive_from_pc_blk(blk);
	if (!x)
		return OPAL_PARAMETER;
	vp = xive_get_vp(x, idx);
	if (!vp)
		return OPAL_PARAMETER;

	/* Consistency check. */
	if ((flags & OPAL_XIVE_VP_SAVE_RESTORE) && !xive_cfg_save_restore(x))
		return OPAL_PARAMETER;

	lock(&x->lock);

	vp_new = *vp;
	if (flags & OPAL_XIVE_VP_ENABLED) {
		vp_new.w0 = xive_set_field32(NVP_W0_VALID, vp_new.w0, 1);
		vp_new.w6 = cpu_to_be32(report_cl_pair >> 32);
		vp_new.w7 = cpu_to_be32(report_cl_pair & 0xffffffff);

		if (flags & OPAL_XIVE_VP_SINGLE_ESCALATION)
			rc = xive_setup_silent_gather(vp_id, true);
		else
			rc = xive_setup_silent_gather(vp_id, false);

		/*
		 * Prepare NVP to be HW owned for automatic save-restore
		 */
		if (xive_cfg_save_restore(x)) {
			/*
			 * Set NVP privilege level. Default to OS.
			 * This check only makes sense for KVM guests
			 * currently. We would need an extra flag to
			 * distinguish from pool level.
			 */
			vp_new.w0 = xive_set_field32(NVP_W0_VPRIV, vp_new.w0, 0);

			vp_new.w2 = xive_set_field32(NVP_W2_CPPR, vp_new.w2, 0xFF);
			vp_new.w0 = xive_set_field32(NVP_W0_HW, vp_new.w0, 1);
		}
	} else {
		/*
		 * TODO (kvm): disabling a VP invalidates the associated ENDs.
		 *
		 * The loads then return all 1s which can be an issue for the
		 * Linux code to handle.
		 */

		vp_new.w0 = vp_new.w6 = vp_new.w7 = 0;
		rc = xive_setup_silent_gather(vp_id, false);
	}

	if (rc) {
		if (rc != OPAL_BUSY)
			xive_dbg(x, "Silent gather setup failed with err %lld\n", rc);
		goto bail;
	}

	rc = xive_nxc_cache_update(x, blk, idx, &vp_new, false);
	if (rc)
		goto bail;

	/* When disabling, we scrub clean (invalidate the entry) so
	 * we can avoid cache ops in alloc/free
	 */
	if (!(flags & OPAL_XIVE_VP_ENABLED))
		xive_nxc_scrub_clean(x, blk, idx);

bail:
	unlock(&x->lock);
	return rc;
}

static int64_t opal_xive_get_vp_state(uint64_t vp_id, beint64_t *out_state)
{
	struct xive *x;
	struct xive_nvp *vp;
	uint32_t blk, idx;
	int64_t rc;
	bool group;

	if (!out_state || !xive_decode_vp(vp_id, &blk, &idx, NULL, &group))
		return OPAL_PARAMETER;
	if (group)
		return OPAL_PARAMETER;
	x = xive_from_pc_blk(blk);
	if (!x)
		return OPAL_PARAMETER;
	vp = xive_get_vp(x, idx);
	if (!vp)
		return OPAL_PARAMETER;

	/* Scrub the vp */
	lock(&x->lock);
	rc = xive_nxc_scrub(x, blk, idx);
	unlock(&x->lock);
	if (rc)
		return rc;

	if (!xive_get_field32(NVP_W0_VALID, vp->w0))
		return OPAL_WRONG_STATE;

	/*
	 * return a state matching the layout of WORD 0-1 of the TIMA
	 * as this is expected by current implementation.
	 */
	*out_state = cpu_to_be64(((uint64_t) 0x0) << 54 |
		(uint64_t)xive_get_field32(NVP_W2_CPPR, vp->w2)  << 48 |
		(uint64_t)xive_get_field32(NVP_W2_IPB,  vp->w2)  << 40 |
		(uint64_t)xive_get_field32(NVP_W2_LSMFB, vp->w2) << 32);

	return OPAL_SUCCESS;
}

static void *xive_cpu_get_tima(struct cpu_thread *c)
{
	struct xive_cpu_state *xs = c->xstate;
	struct xive *x = xs->xive;

	return x->ic_tm_direct_base + ((c->pir & 0xff) << x->ic_shift);
}

static void xive_cleanup_cpu_tima(struct cpu_thread *c)
{
	struct xive_cpu_state *xs __unused = c->xstate;
	void *cpu_tm_base = xive_cpu_get_tima(c);
	uint8_t old_w2 __unused, w2 __unused;

	/* Reset the HW context */
	xive_reset_enable_thread(c);

	/* Set VT to 1 */
	old_w2 = in_8(cpu_tm_base + TM_QW3_HV_PHYS + TM_WORD2);
	out_8(cpu_tm_base + TM_QW3_HV_PHYS + TM_WORD2, 0x80);
	w2 = in_8(cpu_tm_base + TM_QW3_HV_PHYS + TM_WORD2);

	/* Dump HV state */
	xive_cpu_vdbg(c, "[reset] VP TIMA VP=%x/%x W01=%016llx W2=%02x->%02x\n",
		      xs->vp_blk, xs->vp_idx,
		      in_be64(cpu_tm_base + TM_QW3_HV_PHYS),
		      old_w2, w2);
}

static int64_t xive_vc_ind_cache_kill(struct xive *x, uint64_t type)
{
	uint64_t val;

	/* We clear the whole thing */
	xive_regw(x, VC_AT_MACRO_KILL_MASK, 0);
	xive_regw(x, VC_AT_MACRO_KILL, VC_AT_MACRO_KILL_VALID |
		  SETFIELD(VC_AT_MACRO_KILL_VSD, 0ull, type));

	/* XXX Add timeout */
	for (;;) {
		val = xive_regr(x, VC_AT_MACRO_KILL);
		if (!(val & VC_AT_MACRO_KILL_VALID))
			break;
	}
	return 0;
}

static int64_t xive_pc_ind_cache_kill(struct xive *x)
{
	uint64_t val;

	/* We clear the whole thing */
	xive_regw(x, PC_AT_KILL_MASK, 0);
	xive_regw(x, PC_AT_KILL, PC_AT_KILL_VALID |
		  SETFIELD(VC_AT_MACRO_KILL_VSD, 0ull, VST_NVP));

	/* XXX Add timeout */
	for (;;) {
		val = xive_regr(x, PC_AT_KILL);
		if (!(val & PC_AT_KILL_VALID))
			break;
	}
	return 0;
}

static void xive_cleanup_vp_ind(struct xive *x)
{
	int i;

	xive_dbg(x, "Cleaning up %d VP ind entries...\n", x->vp_ind_count);
	for (i = 0; i < x->vp_ind_count; i++) {
		if (be64_to_cpu(x->vp_ind_base[i]) & VSD_FIRMWARE) {
			xive_dbg(x, " %04x ... skip (firmware)\n", i);
			continue;
		}
		if (x->vp_ind_base[i] != 0) {
			x->vp_ind_base[i] = 0;
			xive_dbg(x, " %04x ... cleaned\n", i);
		}
	}
	xive_pc_ind_cache_kill(x);
}

static void xive_cleanup_end_ind(struct xive *x)
{
	int i;

	xive_dbg(x, "Cleaning up %d END ind entries...\n", x->end_ind_count);
	for (i = 0; i < x->end_ind_count; i++) {
		if (be64_to_cpu(x->end_ind_base[i]) & VSD_FIRMWARE) {
			xive_dbg(x, " %04x ... skip (firmware)\n", i);
			continue;
		}
		if (x->end_ind_base[i] != 0) {
			x->end_ind_base[i] = 0;
			xive_dbg(x, " %04x ... cleaned\n", i);
		}
	}
	xive_vc_ind_cache_kill(x, VST_END);
}

static void xive_reset_one(struct xive *x)
{
	struct cpu_thread *c;
	bool end_firmware;
	int i;

	xive_notice(x, "Resetting one xive...\n");

	lock(&x->lock);

	/* Check all interrupts are disabled */
	i = bitmap_find_one_bit(*x->int_enabled_map, 0, XIVE_INT_COUNT);
	if (i >= 0)
		xive_warn(x, "Interrupt %d (and maybe more) not disabled"
			  " at reset !\n", i);

	/* Reset IPI allocation */
	xive_dbg(x, "freeing alloc map %p/%p\n",
		 x->ipi_alloc_map, *x->ipi_alloc_map);
	memset(x->ipi_alloc_map, 0, BITMAP_BYTES(XIVE_INT_COUNT));

	xive_dbg(x, "Resetting ENDs...\n");

	/* Reset all allocated ENDs and free the user ones */
	bitmap_for_each_one(*x->end_map, xive_end_bitmap_size(x), i) {
		struct xive_end end0;
		struct xive_end *end;
		int j;

		if (i == 0)
			continue;
		end_firmware = false;
		for (j = 0; j < xive_cfg_vp_prio(x); j++) {
			uint32_t idx = (i << xive_cfg_vp_prio_shift(x)) | j;

			end = xive_get_end(x, idx);
			if (!end)
				continue;

			/* We need to preserve the firmware bit, otherwise
			 * we will incorrectly free the ENDs that are reserved
			 * for the physical CPUs
			 */
			if (xive_get_field32(END_W0_VALID, end->w0)) {
				if (!xive_end_is_firmware1(end))
					xive_dbg(x, "END 0x%x:0x%x is valid at reset: %08x %08x\n",
						 x->block_id, idx, end->w0, end->w1);
				end0 = *end;
				xive_cleanup_end(&end0);
				xive_endc_cache_update(x, x->block_id, idx, &end0, true);
			}
			if (xive_end_is_firmware1(end))
				end_firmware = true;
		}
		if (!end_firmware)
			bitmap_clr_bit(*x->end_map, i);
	}

	/* Take out all VPs from HW and reset all CPPRs to 0 */
	for_each_present_cpu(c) {
		if (c->chip_id != x->chip_id)
			continue;
		if (!c->xstate)
			continue;
		xive_cleanup_cpu_tima(c);
	}

	/* Reset all user-allocated VPs. This is inefficient, we should
	 * either keep a bitmap of allocated VPs or add an iterator to
	 * the buddy which is trickier but doable.
	 */
	for (i = 0; i < XIVE_VP_COUNT(x); i++) {
		struct xive_nvp *vp;
		struct xive_nvp vp0 = {0};

		/* Ignore the physical CPU VPs */
		if (i >= xive_hw_vp_count &&
		    i < (xive_hw_vp_base + xive_hw_vp_count))
			continue;

		/* Is the VP valid ? */
		vp = xive_get_vp(x, i);
		if (!vp || !xive_get_field32(NVP_W0_VALID, vp->w0))
			continue;

		/* Clear it */
		xive_dbg(x, "VP 0x%x:0x%x is valid at reset\n", x->block_id, i);
		xive_nxc_cache_update(x, x->block_id, i, &vp0, true);
	}

	/* Forget about remaining donated pages */
	list_head_init(&x->donated_pages);

	/* And cleanup donated indirect VP and END pages */
	xive_cleanup_vp_ind(x);
	xive_cleanup_end_ind(x);

	/* The rest must not be called with the lock held */
	unlock(&x->lock);

	/* Re-configure VPs */
	for_each_present_cpu(c) {
		struct xive_cpu_state *xs = c->xstate;

		if (c->chip_id != x->chip_id || !xs)
			continue;

		xive_init_cpu_exploitation(xs);
	}
}

static void xive_reset_mask_source_cb(struct irq_source *is,
				      void *data __unused)
{
	struct xive_src *s = container_of(is, struct xive_src, is);
	struct xive *x;
	uint32_t isn;

	if (is->ops != &xive_irq_source_ops)
		return;

	/* Skip escalation sources */
	if (GIRQ_IS_ESCALATION(is->start))
		return;

	x = s->xive;

	/* Iterate all interrupts */
	for (isn = is->start; isn < is->end; isn++) {
		/* Has it ever been enabled ? */
		if (!bitmap_tst_bit(*x->int_enabled_map, GIRQ_TO_IDX(isn)))
			continue;
		/* Mask it and clear the enabled map bit */
		xive_vdbg(x, "[reset] disabling source 0x%x\n", isn);
		__xive_set_irq_config(is, isn, 0, 0xff, isn, true, false);
		bitmap_clr_bit(*x->int_enabled_map, GIRQ_TO_IDX(isn));
	}
}

void xive2_cpu_reset(void)
{
	struct cpu_thread *c = this_cpu();
	struct xive_cpu_state *xs = c->xstate;

	out_8(xs->tm_ring1 + TM_QW3_HV_PHYS + TM_CPPR, 0);

	in_be64(xs->tm_ring1 + TM_SPC_PULL_POOL_CTX);
}

static int64_t __xive_reset(uint64_t mode)
{
	struct proc_chip *chip;

	xive_mode = mode;

	/* Mask all interrupt sources */
	irq_for_each_source(xive_reset_mask_source_cb, NULL);

	/* For each XIVE do a sync... */
	for_each_chip(chip) {
		if (!chip->xive)
			continue;
		xive_sync(chip->xive);
	}

	/* For each XIVE reset everything else... */
	for_each_chip(chip) {
		if (!chip->xive)
			continue;
		xive_reset_one(chip->xive);
	}

	/* Cleanup global VP allocator */
	buddy_reset(xive_vp_buddy);

	/*
	 * We reserve the whole range of VP ids for HW threads.
	 */
	assert(buddy_reserve(xive_vp_buddy, xive_hw_vp_base, xive_threadid_shift));

	return OPAL_SUCCESS;
}

/* Called by fast reboot */
int64_t xive2_reset(void)
{
	if (xive_mode == XIVE_MODE_NONE)
		return OPAL_SUCCESS;
	return __xive_reset(XIVE_MODE_EXPL);
}

static int64_t opal_xive_reset(uint64_t mode)
{
	prlog(PR_DEBUG, "XIVE reset. mode = %llx\n", mode);

	if (!(mode & XIVE_MODE_EXPL)) {
		prlog(PR_NOTICE, "No emulation mode. XIVE exploitation mode "
		      "is the default\n");
	}

	xive_expl_options = mode & ~XIVE_MODE_EXPL;
	if (xive_expl_options & ~XIVE_EXPL_ALL_OPTIONS) {
		prerror("invalid XIVE exploitation mode option %016llx\n",
			xive_expl_options);
		return OPAL_PARAMETER;
	}

	return __xive_reset(XIVE_MODE_EXPL);
}

static int64_t opal_xive_free_vp_block(uint64_t vp_base)
{
	uint32_t blk, idx, i, j, count;
	uint8_t order;
	bool group;

	if (xive_mode != XIVE_MODE_EXPL)
		return OPAL_WRONG_STATE;

	if (!xive_decode_vp(vp_base, &blk, &idx, &order, &group))
		return OPAL_PARAMETER;
	if (group)
		return OPAL_PARAMETER;
	if (blk)
		return OPAL_PARAMETER;
	if (order < (xive_chips_alloc_bits + 1))
		return OPAL_PARAMETER;
	if (idx & ((1 << (order - xive_chips_alloc_bits)) - 1))
		return OPAL_PARAMETER;

	count = 1 << order;
	for (i = 0; i < count; i++) {
		uint32_t vp_id = vp_base + i;
		uint32_t blk, idx, end_blk, end_idx;
		struct xive *x;
		struct xive_nvp *vp;

		if (!xive_decode_vp(vp_id, &blk, &idx, NULL, NULL)) {
			prerror("Couldn't decode VP id %u\n", vp_id);
			return OPAL_INTERNAL_ERROR;
		}
		x = xive_from_pc_blk(blk);
		if (!x) {
			prerror("Instance not found for deallocated VP"
				" block %d\n", blk);
			return OPAL_INTERNAL_ERROR;
		}
		vp = xive_get_vp(x, idx);
		if (!vp) {
			prerror("VP not found for deallocation !");
			return OPAL_INTERNAL_ERROR;
		}

		/* VP must be disabled */
		if (xive_get_field32(NVP_W0_VALID, vp->w0)) {
			prlog(PR_ERR, "freeing active VP %d\n", vp_id);
			return OPAL_XIVE_FREE_ACTIVE;
		}

		/* Not populated */
		if (vp->w5 == 0)
			continue;

		end_blk = xive_get_field32(NVP_W5_VP_END_BLOCK, vp->w5);
		end_idx = xive_get_field32(NVP_W5_VP_END_INDEX, vp->w5);

		lock(&x->lock);

		/* Ensure ENDs are disabled and cleaned up. Ideally the caller
		 * should have done it but we double check it here
		 */
		for (j = 0; j < xive_cfg_vp_prio(x); j++) {
			struct xive *end_x = xive_from_vc_blk(end_blk);
			struct xive_end end, *orig_end = xive_get_end(end_x, end_idx + j);

			if (!xive_get_field32(END_W0_VALID, orig_end->w0))
				continue;

			prlog(PR_WARNING, "freeing VP %d with queue %d active\n",
			      vp_id, j);
			end = *orig_end;
			xive_cleanup_end(&end);
			xive_endc_cache_update(x, end_blk, end_idx + j, &end, true);
		}

		/* Mark it not populated so we don't try to free it again */
		vp->w5 = 0;

		if (end_blk != blk) {
			prerror("Block mismatch trying to free ENDs\n");
			unlock(&x->lock);
			return OPAL_INTERNAL_ERROR;
		}

		xive_free_end_set(x, end_idx);
		unlock(&x->lock);
	}

	xive_free_vps(vp_base);

	return OPAL_SUCCESS;
}

static int64_t opal_xive_alloc_vp_block(uint32_t alloc_order)
{
	uint32_t vp_base, ends, count, i;
	int64_t rc;

	if (xive_mode != XIVE_MODE_EXPL)
		return OPAL_WRONG_STATE;

	prlog(PR_TRACE, "opal_xive_alloc_vp_block(%d)\n", alloc_order);

	vp_base = xive_alloc_vps(alloc_order);
	if (XIVE_ALLOC_IS_ERR(vp_base)) {
		if (vp_base == XIVE_ALLOC_NO_IND)
			return OPAL_XIVE_PROVISIONING;
		return OPAL_RESOURCE;
	}

	/* Allocate ENDs and initialize VPs */
	count = 1 << alloc_order;
	for (i = 0; i < count; i++) {
		uint32_t vp_id = vp_base + i;
		uint32_t blk, idx;
		struct xive *x;
		struct xive_nvp *vp;

		if (!xive_decode_vp(vp_id, &blk, &idx, NULL, NULL)) {
			prerror("Couldn't decode VP id %u\n", vp_id);
			return OPAL_INTERNAL_ERROR;
		}
		x = xive_from_pc_blk(blk);
		if (!x) {
			prerror("Instance not found for allocated VP"
				" block %d\n", blk);
			rc = OPAL_INTERNAL_ERROR;
			goto fail;
		}
		vp = xive_get_vp(x, idx);
		if (!vp) {
			prerror("VP not found after allocation !");
			rc = OPAL_INTERNAL_ERROR;
			goto fail;
		}

		/* Allocate ENDs, if fails, free the VPs and return */
		lock(&x->lock);
		ends = xive_alloc_end_set(x, false);
		unlock(&x->lock);
		if (XIVE_ALLOC_IS_ERR(ends)) {
			if (ends == XIVE_ALLOC_NO_IND)
				rc = OPAL_XIVE_PROVISIONING;
			else
				rc = OPAL_RESOURCE;
			goto fail;
		}

		/* Initialize the VP structure. We don't use a cache watch
		 * as we have made sure when freeing the entries to scrub
		 * it out of the cache.
		 */
		memset(vp, 0, sizeof(*vp));

		/* Store the END base of the VP in W5 (new in p10) */
		xive_vp_set_end_base(vp, blk, ends);
	}
	return vp_base;
 fail:
	opal_xive_free_vp_block(vp_base);

	return rc;
}

static int64_t xive_try_allocate_irq(struct xive *x)
{
	int idx, base_idx, max_count, girq;
	struct xive_eas *eas;

	lock(&x->lock);

	base_idx = x->int_ipi_top - x->int_base;
	max_count = x->int_hw_bot - x->int_ipi_top;

	idx = bitmap_find_zero_bit(*x->ipi_alloc_map, base_idx, max_count);
	if (idx < 0) {
		unlock(&x->lock);
		return OPAL_RESOURCE;
	}
	bitmap_set_bit(*x->ipi_alloc_map, idx);
	girq = x->int_base + idx;

	/* Mark the EAS valid. Don't bother with the HW cache, it's
	 * still masked anyway, the cache will be updated when unmasked
	 * and configured.
	 */
	eas = xive_get_eas(x, girq);
	if (!eas) {
		bitmap_clr_bit(*x->ipi_alloc_map, idx);
		unlock(&x->lock);
		return OPAL_PARAMETER;
	}
	eas->w = xive_set_field64(EAS_VALID, 0, 1) |
		 xive_set_field64(EAS_MASKED, 0, 1) |
		 xive_set_field64(EAS_END_DATA, 0, girq);
	unlock(&x->lock);

	return girq;
}

static int64_t opal_xive_allocate_irq(uint32_t chip_id)
{
	struct proc_chip *chip;
	bool try_all = false;
	int64_t rc;

	if (xive_mode != XIVE_MODE_EXPL)
		return OPAL_WRONG_STATE;

	if (chip_id == OPAL_XIVE_ANY_CHIP) {
		try_all = true;
		chip_id = this_cpu()->chip_id;
	}
	chip = get_chip(chip_id);
	if (!chip)
		return OPAL_PARAMETER;

	/* Try initial target chip */
	if (!chip->xive)
		rc = OPAL_PARAMETER;
	else
		rc = xive_try_allocate_irq(chip->xive);
	if (rc >= 0 || !try_all)
		return rc;

	/* Failed and we try all... do so */
	for_each_chip(chip) {
		if (!chip->xive)
			continue;
		rc = xive_try_allocate_irq(chip->xive);
		if (rc >= 0)
			break;
	}
	return rc;
}

static int64_t opal_xive_free_irq(uint32_t girq)
{
	struct irq_source *is = irq_find_source(girq);
	struct xive_src *s = container_of(is, struct xive_src, is);
	struct xive *x = xive_from_isn(girq);
	struct xive_eas *eas;
	uint32_t idx;

	if (xive_mode != XIVE_MODE_EXPL)
               return OPAL_WRONG_STATE;
	if (!x || !is)
		return OPAL_PARAMETER;

	idx = GIRQ_TO_IDX(girq);

	lock(&x->lock);

	eas = xive_get_eas(x, girq);
	if (!eas) {
		unlock(&x->lock);
		return OPAL_PARAMETER;
	}

	/* Mask the interrupt source */
	xive_update_irq_mask(s, girq - s->esb_base, true);

	/* Mark the EAS masked and invalid */
	eas->w = xive_set_field64(EAS_VALID, 0, 1) |
		 xive_set_field64(EAS_MASKED, 0, 1);
	xive_easc_scrub(x, x->block_id, idx);

	/* Free it */
	if (!bitmap_tst_bit(*x->ipi_alloc_map, idx)) {
		unlock(&x->lock);
		return OPAL_PARAMETER;
	}
	bitmap_clr_bit(*x->ipi_alloc_map, idx);
	bitmap_clr_bit(*x->int_enabled_map, idx);
	unlock(&x->lock);

	return OPAL_SUCCESS;
}

static int64_t opal_xive_dump_tm(uint32_t offset, const char *n, uint32_t pir)
{
	struct cpu_thread *c = find_cpu_by_pir(pir);
	struct xive_cpu_state *xs;
	struct xive *x;
	void *cpu_tm_base;
	uint64_t v0,v1;

	if (!c)
		return OPAL_PARAMETER;
	xs = c->xstate;
	if (!xs || !xs->tm_ring1)
		return OPAL_INTERNAL_ERROR;
	x = xs->xive;
	cpu_tm_base = xive_cpu_get_tima(c);

	lock(&x->lock);
	v0 = in_be64(cpu_tm_base + offset);
	if (offset == TM_QW3_HV_PHYS) {
		v1 = in_8(cpu_tm_base + offset + 8);
		v1 <<= 56;
	} else {
		v1 = in_be32(cpu_tm_base + offset + 8);
		v1 <<= 32;
	}
	prlog(PR_INFO, "CPU[%04x]: TM state for QW %s\n", pir, n);
	prlog(PR_INFO, "CPU[%04x]: NSR CPPR IPB LSMFB ACK# INC AGE PIPR"
	      " W2       W3\n", pir);
	prlog(PR_INFO, "CPU[%04x]: %02x  %02x   %02x  %02x    %02x   "
	       "%02x  %02x  %02x   %08x %08x\n", pir,
	      (uint8_t)(v0 >> 58) & 0xff, (uint8_t)(v0 >> 48) & 0xff,
	      (uint8_t)(v0 >> 40) & 0xff, (uint8_t)(v0 >> 32) & 0xff,
	      (uint8_t)(v0 >> 24) & 0xff, (uint8_t)(v0 >> 16) & 0xff,
	      (uint8_t)(v0 >>  8) & 0xff, (uint8_t)(v0      ) & 0xff,
	      (uint32_t)(v1 >> 32) & 0xffffffff,
	      (uint32_t)(v1 & 0xffffffff));
	unlock(&x->lock);

	return OPAL_SUCCESS;
}

static int64_t opal_xive_dump_vp(uint32_t vp_id)
{
	uint32_t blk, idx;
	uint8_t order;
	bool group;
	struct xive *x;
	struct xive_nvp *vp;
	uint32_t *vpw;

	if (!xive_decode_vp(vp_id, &blk, &idx, &order, &group))
		return OPAL_PARAMETER;

	x = xive_from_vc_blk(blk);
	if (!x)
		return OPAL_PARAMETER;
	vp = xive_get_vp(x, idx);
	if (!vp)
		return OPAL_PARAMETER;
	lock(&x->lock);

	xive_nxc_scrub_clean(x, blk, idx);

	vpw = ((uint32_t *)vp) + (group ? 8 : 0);
	prlog(PR_INFO, "VP[%08x]: 0..3: %08x %08x %08x %08x\n", vp_id,
	      vpw[0], vpw[1], vpw[2], vpw[3]);
	prlog(PR_INFO, "VP[%08x]: 4..7: %08x %08x %08x %08x\n", vp_id,
	      vpw[4], vpw[5], vpw[6], vpw[7]);
	unlock(&x->lock);

	return OPAL_SUCCESS;
}

static int64_t opal_xive_sync_irq_src(uint32_t girq)
{
	struct xive *x = xive_from_isn(girq);

	if (!x)
		return OPAL_PARAMETER;
	return xive_sync(x);
}

static int64_t opal_xive_sync_irq_target(uint32_t girq)
{
	uint32_t target, vp_blk;
	struct xive *x;

	if (!xive_get_irq_targetting(girq, &target, NULL, NULL))
		return OPAL_PARAMETER;
	if (!xive_decode_vp(target, &vp_blk, NULL, NULL, NULL))
		return OPAL_PARAMETER;
	x = xive_from_pc_blk(vp_blk);
	if (!x)
		return OPAL_PARAMETER;
	return xive_sync(x);
}

static int64_t opal_xive_sync(uint32_t type, uint32_t id)
{
	int64_t rc = OPAL_SUCCESS;;

	if (type & XIVE_SYNC_EAS)
		rc = opal_xive_sync_irq_src(id);
	if (rc)
		return rc;
	if (type & XIVE_SYNC_QUEUE)
		rc = opal_xive_sync_irq_target(id);
	if (rc)
		return rc;

	/* Add more ... */

	return rc;
}

static int64_t opal_xive_dump(uint32_t type, uint32_t id)
{
	switch (type) {
	case XIVE_DUMP_TM_HYP:
		return opal_xive_dump_tm(TM_QW3_HV_PHYS, "PHYS", id);
	case XIVE_DUMP_TM_POOL:
		return opal_xive_dump_tm(TM_QW2_HV_POOL, "POOL", id);
	case XIVE_DUMP_TM_OS:
		return opal_xive_dump_tm(TM_QW1_OS, "OS  ", id);
	case XIVE_DUMP_TM_USER:
		return opal_xive_dump_tm(TM_QW0_USER, "USER", id);
	case XIVE_DUMP_VP:
		return opal_xive_dump_vp(id);
	default:
		return OPAL_PARAMETER;
	}
}

static void xive_init_globals(void)
{
	uint32_t i;

	for (i = 0; i < XIVE_MAX_CHIPS; i++)
		xive_block_to_chip[i] = XIVE_INVALID_CHIP;
}

/*
 * The global availability of some capabilities used in other drivers
 * (PHB, PSI) is deduced from the capabilities of the first XIVE chip
 * of the system. It should be common to all chips.
 */
bool xive2_cap_phb_pq_disable(void)
{
	return xive_has_cap(one_xive, CQ_XIVE_CAP_PHB_PQ_DISABLE);
}

bool xive2_cap_phb_abt(void)
{
	if (!xive_has_cap(one_xive, CQ_XIVE_CAP_PHB_ABT))
		return false;

	/*
	 * We need 'PQ disable' to use ABT mode, else the OS will use
	 * two different sets of ESB pages (PHB and IC) to control the
	 * interrupt sources. Can not work.
	 */
	if (!xive2_cap_phb_pq_disable()) {
		prlog_once(PR_ERR, "ABT mode is set without PQ disable. "
			   "Ignoring bogus configuration\n");
		return false;
	}

	return true;
}

bool xive2_cap_store_eoi(void)
{
	return xive_has_cap(one_xive, CQ_XIVE_CAP_STORE_EOI);
}

void xive2_init(void)
{
	struct dt_node *np;
	struct proc_chip *chip;
	struct cpu_thread *cpu;
	bool first = true;

	/* Look for xive nodes and do basic inits */
	dt_for_each_compatible(dt_root, np, "ibm,power10-xive-x") {
		struct xive *x;

		/* Initialize some global stuff */
		if (first)
			xive_init_globals();

		/* Create/initialize the xive instance */
		x = init_one_xive(np);
		if (first)
			one_xive = x;
		first = false;
	}
	if (first)
		return;

	/*
	 * P8 emulation is not supported on P10 anymore. Exploitation
	 * is the default XIVE mode. We might introduce a GEN2 mode.
	 */
	xive_mode = XIVE_MODE_EXPL;

	/* Init VP allocator */
	xive_init_vp_allocator();

	/* Create a device-tree node for Linux use */
	xive_create_mmio_dt_node(one_xive);

	/* Some inits must be done after all xive have been created
	 * such as setting up the forwarding ports
	 */
	for_each_chip(chip) {
		if (chip->xive)
			late_init_one_xive(chip->xive);
	}

	/* Initialize per-cpu structures */
	for_each_present_cpu(cpu) {
		xive_init_cpu(cpu);
	}

	/* Calling boot CPU */
	xive2_cpu_callin(this_cpu());

	/* Register XIVE exploitation calls */
	opal_register(OPAL_XIVE_RESET, opal_xive_reset, 1);
	opal_register(OPAL_XIVE_GET_IRQ_INFO, opal_xive_get_irq_info, 6);
	opal_register(OPAL_XIVE_GET_IRQ_CONFIG, opal_xive_get_irq_config, 4);
	opal_register(OPAL_XIVE_SET_IRQ_CONFIG, opal_xive_set_irq_config, 4);
	opal_register(OPAL_XIVE_GET_QUEUE_INFO, opal_xive_get_queue_info, 7);
	opal_register(OPAL_XIVE_SET_QUEUE_INFO, opal_xive_set_queue_info, 5);
	opal_register(OPAL_XIVE_DONATE_PAGE, opal_xive_donate_page, 2);
	opal_register(OPAL_XIVE_ALLOCATE_IRQ, opal_xive_allocate_irq, 1);
	opal_register(OPAL_XIVE_FREE_IRQ, opal_xive_free_irq, 1);
	opal_register(OPAL_XIVE_ALLOCATE_VP_BLOCK, opal_xive_alloc_vp_block, 1);
	opal_register(OPAL_XIVE_FREE_VP_BLOCK, opal_xive_free_vp_block, 1);
	opal_register(OPAL_XIVE_GET_VP_INFO, opal_xive_get_vp_info, 5);
	opal_register(OPAL_XIVE_SET_VP_INFO, opal_xive_set_vp_info, 3);
	opal_register(OPAL_XIVE_SYNC, opal_xive_sync, 2);
	opal_register(OPAL_XIVE_DUMP, opal_xive_dump, 2);
	opal_register(OPAL_XIVE_GET_QUEUE_STATE, opal_xive_get_queue_state, 4);
	opal_register(OPAL_XIVE_SET_QUEUE_STATE, opal_xive_set_queue_state, 4);
	opal_register(OPAL_XIVE_GET_VP_STATE, opal_xive_get_vp_state, 2);
}
