// SPDX-License-Identifier: GPL-2.0
/* Nehalem-EX/Westmere-EX uncore support */
#include "uncore.h"

/* NHM-EX event control */
#define NHMEX_PMON_CTL_EV_SEL_MASK	0x000000ff
#define NHMEX_PMON_CTL_UMASK_MASK	0x0000ff00
#define NHMEX_PMON_CTL_EN_BIT0		(1 << 0)
#define NHMEX_PMON_CTL_EDGE_DET		(1 << 18)
#define NHMEX_PMON_CTL_PMI_EN		(1 << 20)
#define NHMEX_PMON_CTL_EN_BIT22		(1 << 22)
#define NHMEX_PMON_CTL_INVERT		(1 << 23)
#define NHMEX_PMON_CTL_TRESH_MASK	0xff000000
#define NHMEX_PMON_RAW_EVENT_MASK	(NHMEX_PMON_CTL_EV_SEL_MASK | \
					 NHMEX_PMON_CTL_UMASK_MASK | \
					 NHMEX_PMON_CTL_EDGE_DET | \
					 NHMEX_PMON_CTL_INVERT | \
					 NHMEX_PMON_CTL_TRESH_MASK)

/* NHM-EX Ubox */
#define NHMEX_U_MSR_PMON_GLOBAL_CTL		0xc00
#define NHMEX_U_MSR_PMON_CTR			0xc11
#define NHMEX_U_MSR_PMON_EV_SEL			0xc10

#define NHMEX_U_PMON_GLOBAL_EN			(1 << 0)
#define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL	0x0000001e
#define NHMEX_U_PMON_GLOBAL_EN_ALL		(1 << 28)
#define NHMEX_U_PMON_GLOBAL_RST_ALL		(1 << 29)
#define NHMEX_U_PMON_GLOBAL_FRZ_ALL		(1 << 31)

#define NHMEX_U_PMON_RAW_EVENT_MASK		\
		(NHMEX_PMON_CTL_EV_SEL_MASK |	\
		 NHMEX_PMON_CTL_EDGE_DET)

/* NHM-EX Cbox */
#define NHMEX_C0_MSR_PMON_GLOBAL_CTL		0xd00
#define NHMEX_C0_MSR_PMON_CTR0			0xd11
#define NHMEX_C0_MSR_PMON_EV_SEL0		0xd10
#define NHMEX_C_MSR_OFFSET			0x20

/* NHM-EX Bbox */
#define NHMEX_B0_MSR_PMON_GLOBAL_CTL		0xc20
#define NHMEX_B0_MSR_PMON_CTR0			0xc31
#define NHMEX_B0_MSR_PMON_CTL0			0xc30
#define NHMEX_B_MSR_OFFSET			0x40
#define NHMEX_B0_MSR_MATCH			0xe45
#define NHMEX_B0_MSR_MASK			0xe46
#define NHMEX_B1_MSR_MATCH			0xe4d
#define NHMEX_B1_MSR_MASK			0xe4e

#define NHMEX_B_PMON_CTL_EN			(1 << 0)
#define NHMEX_B_PMON_CTL_EV_SEL_SHIFT		1
#define NHMEX_B_PMON_CTL_EV_SEL_MASK		\
		(0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT)
#define NHMEX_B_PMON_CTR_SHIFT		6
#define NHMEX_B_PMON_CTR_MASK		\
		(0x3 << NHMEX_B_PMON_CTR_SHIFT)
#define NHMEX_B_PMON_RAW_EVENT_MASK		\
		(NHMEX_B_PMON_CTL_EV_SEL_MASK | \
		 NHMEX_B_PMON_CTR_MASK)

/* NHM-EX Sbox */
#define NHMEX_S0_MSR_PMON_GLOBAL_CTL		0xc40
#define NHMEX_S0_MSR_PMON_CTR0			0xc51
#define NHMEX_S0_MSR_PMON_CTL0			0xc50
#define NHMEX_S_MSR_OFFSET			0x80
#define NHMEX_S0_MSR_MM_CFG			0xe48
#define NHMEX_S0_MSR_MATCH			0xe49
#define NHMEX_S0_MSR_MASK			0xe4a
#define NHMEX_S1_MSR_MM_CFG			0xe58
#define NHMEX_S1_MSR_MATCH			0xe59
#define NHMEX_S1_MSR_MASK			0xe5a

#define NHMEX_S_PMON_MM_CFG_EN			(0x1ULL << 63)
#define NHMEX_S_EVENT_TO_R_PROG_EV		0

/* NHM-EX Mbox */
#define NHMEX_M0_MSR_GLOBAL_CTL			0xca0
#define NHMEX_M0_MSR_PMU_DSP			0xca5
#define NHMEX_M0_MSR_PMU_ISS			0xca6
#define NHMEX_M0_MSR_PMU_MAP			0xca7
#define NHMEX_M0_MSR_PMU_MSC_THR		0xca8
#define NHMEX_M0_MSR_PMU_PGT			0xca9
#define NHMEX_M0_MSR_PMU_PLD			0xcaa
#define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC		0xcab
#define NHMEX_M0_MSR_PMU_CTL0			0xcb0
#define NHMEX_M0_MSR_PMU_CNT0			0xcb1
#define NHMEX_M_MSR_OFFSET			0x40
#define NHMEX_M0_MSR_PMU_MM_CFG			0xe54
#define NHMEX_M1_MSR_PMU_MM_CFG			0xe5c

#define NHMEX_M_PMON_MM_CFG_EN			(1ULL << 63)
#define NHMEX_M_PMON_ADDR_MATCH_MASK		0x3ffffffffULL
#define NHMEX_M_PMON_ADDR_MASK_MASK		0x7ffffffULL
#define NHMEX_M_PMON_ADDR_MASK_SHIFT		34

#define NHMEX_M_PMON_CTL_EN			(1 << 0)
#define NHMEX_M_PMON_CTL_PMI_EN			(1 << 1)
#define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT	2
#define NHMEX_M_PMON_CTL_COUNT_MODE_MASK	\
	(0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT)
#define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT	4
#define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK	\
	(0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT)
#define NHMEX_M_PMON_CTL_WRAP_MODE		(1 << 6)
#define NHMEX_M_PMON_CTL_FLAG_MODE		(1 << 7)
#define NHMEX_M_PMON_CTL_INC_SEL_SHIFT		9
#define NHMEX_M_PMON_CTL_INC_SEL_MASK		\
	(0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT	19
#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK	\
	(0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT)
#define NHMEX_M_PMON_RAW_EVENT_MASK			\
		(NHMEX_M_PMON_CTL_COUNT_MODE_MASK |	\
		 NHMEX_M_PMON_CTL_STORAGE_MODE_MASK |	\
		 NHMEX_M_PMON_CTL_WRAP_MODE |		\
		 NHMEX_M_PMON_CTL_FLAG_MODE |		\
		 NHMEX_M_PMON_CTL_INC_SEL_MASK |	\
		 NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)

#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK		(((1 << 11) - 1) | (1 << 23))
#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7ULL << (11 + 3 * (n)))

#define WSMEX_M_PMON_ZDP_CTL_FVC_MASK		(((1 << 12) - 1) | (1 << 24))
#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7ULL << (12 + 3 * (n)))

/*
 * use the 9~13 bits to select event If the 7th bit is not set,
 * otherwise use the 19~21 bits to select event.
 */
#define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
#define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \
				NHMEX_M_PMON_CTL_FLAG_MODE)
#define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \
			   NHMEX_M_PMON_CTL_FLAG_MODE)
#define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \
				NHMEX_M_PMON_CTL_FLAG_MODE)
#define MBOX_INC_SEL_EXTAR_REG(c, r) \
		EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \
				MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r)
#define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \
		EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \
				MBOX_SET_FLAG_SEL_MASK, \
				(u64)-1, NHMEX_M_##r)

/* NHM-EX Rbox */
#define NHMEX_R_MSR_GLOBAL_CTL			0xe00
#define NHMEX_R_MSR_PMON_CTL0			0xe10
#define NHMEX_R_MSR_PMON_CNT0			0xe11
#define NHMEX_R_MSR_OFFSET			0x20

#define NHMEX_R_MSR_PORTN_QLX_CFG(n)		\
		((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4))
#define NHMEX_R_MSR_PORTN_IPERF_CFG0(n)		(0xe04 + (n))
#define NHMEX_R_MSR_PORTN_IPERF_CFG1(n)		(0xe24 + (n))
#define NHMEX_R_MSR_PORTN_XBR_OFFSET(n)		\
		(((n) < 4 ? 0 : 0x10) + (n) * 4)
#define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n)	\
		(0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
#define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n)	\
		(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1)
#define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n)	\
		(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2)
#define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n)	\
		(0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
#define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n)	\
		(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1)
#define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n)	\
		(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2)

#define NHMEX_R_PMON_CTL_EN			(1 << 0)
#define NHMEX_R_PMON_CTL_EV_SEL_SHIFT		1
#define NHMEX_R_PMON_CTL_EV_SEL_MASK		\
		(0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT)
#define NHMEX_R_PMON_CTL_PMI_EN			(1 << 6)
#define NHMEX_R_PMON_RAW_EVENT_MASK		NHMEX_R_PMON_CTL_EV_SEL_MASK

/* NHM-EX Wbox */
#define NHMEX_W_MSR_GLOBAL_CTL			0xc80
#define NHMEX_W_MSR_PMON_CNT0			0xc90
#define NHMEX_W_MSR_PMON_EVT_SEL0		0xc91
#define NHMEX_W_MSR_PMON_FIXED_CTR		0x394
#define NHMEX_W_MSR_PMON_FIXED_CTL		0x395

#define NHMEX_W_PMON_GLOBAL_FIXED_EN		(1ULL << 31)

#define __BITS_VALUE(x, i, n)  ((typeof(x))(((x) >> ((i) * (n))) & \
				((1ULL << (n)) - 1)))

DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5");
DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7");
DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63");
DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63");

static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box)
{
	wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL);
}

static void nhmex_uncore_msr_exit_box(struct intel_uncore_box *box)
{
	wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, 0);
}

static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box)
{
	unsigned msr = uncore_msr_box_ctl(box);
	u64 config;

	if (msr) {
		rdmsrl(msr, config);
		config &= ~((1ULL << uncore_num_counters(box)) - 1);
		/* WBox has a fixed counter */
		if (uncore_msr_fixed_ctl(box))
			config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN;
		wrmsrl(msr, config);
	}
}

static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box)
{
	unsigned msr = uncore_msr_box_ctl(box);
	u64 config;

	if (msr) {
		rdmsrl(msr, config);
		config |= (1ULL << uncore_num_counters(box)) - 1;
		/* WBox has a fixed counter */
		if (uncore_msr_fixed_ctl(box))
			config |= NHMEX_W_PMON_GLOBAL_FIXED_EN;
		wrmsrl(msr, config);
	}
}

static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
{
	wrmsrl(event->hw.config_base, 0);
}

static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;

	if (hwc->idx == UNCORE_PMC_IDX_FIXED)
		wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0);
	else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0)
		wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
	else
		wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
}

#define NHMEX_UNCORE_OPS_COMMON_INIT()				\
	.init_box	= nhmex_uncore_msr_init_box,		\
	.exit_box	= nhmex_uncore_msr_exit_box,		\
	.disable_box	= nhmex_uncore_msr_disable_box,		\
	.enable_box	= nhmex_uncore_msr_enable_box,		\
	.disable_event	= nhmex_uncore_msr_disable_event,	\
	.read_counter	= uncore_msr_read_counter

static struct intel_uncore_ops nhmex_uncore_ops = {
	NHMEX_UNCORE_OPS_COMMON_INIT(),
	.enable_event	= nhmex_uncore_msr_enable_event,
};

static struct attribute *nhmex_uncore_ubox_formats_attr[] = {
	&format_attr_event.attr,
	&format_attr_edge.attr,
	NULL,
};

static const struct attribute_group nhmex_uncore_ubox_format_group = {
	.name		= "format",
	.attrs		= nhmex_uncore_ubox_formats_attr,
};

static struct intel_uncore_type nhmex_uncore_ubox = {
	.name		= "ubox",
	.num_counters	= 1,
	.num_boxes	= 1,
	.perf_ctr_bits	= 48,
	.event_ctl	= NHMEX_U_MSR_PMON_EV_SEL,
	.perf_ctr	= NHMEX_U_MSR_PMON_CTR,
	.event_mask	= NHMEX_U_PMON_RAW_EVENT_MASK,
	.box_ctl	= NHMEX_U_MSR_PMON_GLOBAL_CTL,
	.ops		= &nhmex_uncore_ops,
	.format_group	= &nhmex_uncore_ubox_format_group
};

static struct attribute *nhmex_uncore_cbox_formats_attr[] = {
	&format_attr_event.attr,
	&format_attr_umask.attr,
	&format_attr_edge.attr,
	&format_attr_inv.attr,
	&format_attr_thresh8.attr,
	NULL,
};

static const struct attribute_group nhmex_uncore_cbox_format_group = {
	.name = "format",
	.attrs = nhmex_uncore_cbox_formats_attr,
};

/* msr offset for each instance of cbox */
static unsigned nhmex_cbox_msr_offsets[] = {
	0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0,
};

static struct intel_uncore_type nhmex_uncore_cbox = {
	.name			= "cbox",
	.num_counters		= 6,
	.num_boxes		= 10,
	.perf_ctr_bits		= 48,
	.event_ctl		= NHMEX_C0_MSR_PMON_EV_SEL0,
	.perf_ctr		= NHMEX_C0_MSR_PMON_CTR0,
	.event_mask		= NHMEX_PMON_RAW_EVENT_MASK,
	.box_ctl		= NHMEX_C0_MSR_PMON_GLOBAL_CTL,
	.msr_offsets		= nhmex_cbox_msr_offsets,
	.pair_ctr_ctl		= 1,
	.ops			= &nhmex_uncore_ops,
	.format_group		= &nhmex_uncore_cbox_format_group
};

static struct uncore_event_desc nhmex_uncore_wbox_events[] = {
	INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"),
	{ /* end: all zeroes */ },
};

static struct intel_uncore_type nhmex_uncore_wbox = {
	.name			= "wbox",
	.num_counters		= 4,
	.num_boxes		= 1,
	.perf_ctr_bits		= 48,
	.event_ctl		= NHMEX_W_MSR_PMON_CNT0,
	.perf_ctr		= NHMEX_W_MSR_PMON_EVT_SEL0,
	.fixed_ctr		= NHMEX_W_MSR_PMON_FIXED_CTR,
	.fixed_ctl		= NHMEX_W_MSR_PMON_FIXED_CTL,
	.event_mask		= NHMEX_PMON_RAW_EVENT_MASK,
	.box_ctl		= NHMEX_W_MSR_GLOBAL_CTL,
	.pair_ctr_ctl		= 1,
	.event_descs		= nhmex_uncore_wbox_events,
	.ops			= &nhmex_uncore_ops,
	.format_group		= &nhmex_uncore_cbox_format_group
};

static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
	int ctr, ev_sel;

	ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >>
		NHMEX_B_PMON_CTR_SHIFT;
	ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >>
		  NHMEX_B_PMON_CTL_EV_SEL_SHIFT;

	/* events that do not use the match/mask registers */
	if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) ||
	    (ctr == 2 && ev_sel != 0x4) || ctr == 3)
		return 0;

	if (box->pmu->pmu_idx == 0)
		reg1->reg = NHMEX_B0_MSR_MATCH;
	else
		reg1->reg = NHMEX_B1_MSR_MATCH;
	reg1->idx = 0;
	reg1->config = event->attr.config1;
	reg2->config = event->attr.config2;
	return 0;
}

static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;

	if (reg1->idx != EXTRA_REG_NONE) {
		wrmsrl(reg1->reg, reg1->config);
		wrmsrl(reg1->reg + 1, reg2->config);
	}
	wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
		(hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK));
}

/*
 * The Bbox has 4 counters, but each counter monitors different events.
 * Use bits 6-7 in the event config to select counter.
 */
static struct event_constraint nhmex_uncore_bbox_constraints[] = {
	EVENT_CONSTRAINT(0 , 1, 0xc0),
	EVENT_CONSTRAINT(0x40, 2, 0xc0),
	EVENT_CONSTRAINT(0x80, 4, 0xc0),
	EVENT_CONSTRAINT(0xc0, 8, 0xc0),
	EVENT_CONSTRAINT_END,
};

static struct attribute *nhmex_uncore_bbox_formats_attr[] = {
	&format_attr_event5.attr,
	&format_attr_counter.attr,
	&format_attr_match.attr,
	&format_attr_mask.attr,
	NULL,
};

static const struct attribute_group nhmex_uncore_bbox_format_group = {
	.name = "format",
	.attrs = nhmex_uncore_bbox_formats_attr,
};

static struct intel_uncore_ops nhmex_uncore_bbox_ops = {
	NHMEX_UNCORE_OPS_COMMON_INIT(),
	.enable_event		= nhmex_bbox_msr_enable_event,
	.hw_config		= nhmex_bbox_hw_config,
	.get_constraint		= uncore_get_constraint,
	.put_constraint		= uncore_put_constraint,
};

static struct intel_uncore_type nhmex_uncore_bbox = {
	.name			= "bbox",
	.num_counters		= 4,
	.num_boxes		= 2,
	.perf_ctr_bits		= 48,
	.event_ctl		= NHMEX_B0_MSR_PMON_CTL0,
	.perf_ctr		= NHMEX_B0_MSR_PMON_CTR0,
	.event_mask		= NHMEX_B_PMON_RAW_EVENT_MASK,
	.box_ctl		= NHMEX_B0_MSR_PMON_GLOBAL_CTL,
	.msr_offset		= NHMEX_B_MSR_OFFSET,
	.pair_ctr_ctl		= 1,
	.num_shared_regs	= 1,
	.constraints		= nhmex_uncore_bbox_constraints,
	.ops			= &nhmex_uncore_bbox_ops,
	.format_group		= &nhmex_uncore_bbox_format_group
};

static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;

	/* only TO_R_PROG_EV event uses the match/mask register */
	if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) !=
	    NHMEX_S_EVENT_TO_R_PROG_EV)
		return 0;

	if (box->pmu->pmu_idx == 0)
		reg1->reg = NHMEX_S0_MSR_MM_CFG;
	else
		reg1->reg = NHMEX_S1_MSR_MM_CFG;
	reg1->idx = 0;
	reg1->config = event->attr.config1;
	reg2->config = event->attr.config2;
	return 0;
}

static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;

	if (reg1->idx != EXTRA_REG_NONE) {
		wrmsrl(reg1->reg, 0);
		wrmsrl(reg1->reg + 1, reg1->config);
		wrmsrl(reg1->reg + 2, reg2->config);
		wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN);
	}
	wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
}

static struct attribute *nhmex_uncore_sbox_formats_attr[] = {
	&format_attr_event.attr,
	&format_attr_umask.attr,
	&format_attr_edge.attr,
	&format_attr_inv.attr,
	&format_attr_thresh8.attr,
	&format_attr_match.attr,
	&format_attr_mask.attr,
	NULL,
};

static const struct attribute_group nhmex_uncore_sbox_format_group = {
	.name			= "format",
	.attrs			= nhmex_uncore_sbox_formats_attr,
};

static struct intel_uncore_ops nhmex_uncore_sbox_ops = {
	NHMEX_UNCORE_OPS_COMMON_INIT(),
	.enable_event		= nhmex_sbox_msr_enable_event,
	.hw_config		= nhmex_sbox_hw_config,
	.get_constraint		= uncore_get_constraint,
	.put_constraint		= uncore_put_constraint,
};

static struct intel_uncore_type nhmex_uncore_sbox = {
	.name			= "sbox",
	.num_counters		= 4,
	.num_boxes		= 2,
	.perf_ctr_bits		= 48,
	.event_ctl		= NHMEX_S0_MSR_PMON_CTL0,
	.perf_ctr		= NHMEX_S0_MSR_PMON_CTR0,
	.event_mask		= NHMEX_PMON_RAW_EVENT_MASK,
	.box_ctl		= NHMEX_S0_MSR_PMON_GLOBAL_CTL,
	.msr_offset		= NHMEX_S_MSR_OFFSET,
	.pair_ctr_ctl		= 1,
	.num_shared_regs	= 1,
	.ops			= &nhmex_uncore_sbox_ops,
	.format_group		= &nhmex_uncore_sbox_format_group
};

enum {
	EXTRA_REG_NHMEX_M_FILTER,
	EXTRA_REG_NHMEX_M_DSP,
	EXTRA_REG_NHMEX_M_ISS,
	EXTRA_REG_NHMEX_M_MAP,
	EXTRA_REG_NHMEX_M_MSC_THR,
	EXTRA_REG_NHMEX_M_PGT,
	EXTRA_REG_NHMEX_M_PLD,
	EXTRA_REG_NHMEX_M_ZDP_CTL_FVC,
};

static struct extra_reg nhmex_uncore_mbox_extra_regs[] = {
	MBOX_INC_SEL_EXTAR_REG(0x0, DSP),
	MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR),
	MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR),
	MBOX_INC_SEL_EXTAR_REG(0x9, ISS),
	/* event 0xa uses two extra registers */
	MBOX_INC_SEL_EXTAR_REG(0xa, ISS),
	MBOX_INC_SEL_EXTAR_REG(0xa, PLD),
	MBOX_INC_SEL_EXTAR_REG(0xb, PLD),
	/* events 0xd ~ 0x10 use the same extra register */
	MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC),
	MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC),
	MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC),
	MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC),
	MBOX_INC_SEL_EXTAR_REG(0x16, PGT),
	MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP),
	MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS),
	MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT),
	MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP),
	EVENT_EXTRA_END
};

/* Nehalem-EX or Westmere-EX ? */
static bool uncore_nhmex;

static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config)
{
	struct intel_uncore_extra_reg *er;
	unsigned long flags;
	bool ret = false;
	u64 mask;

	if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
		er = &box->shared_regs[idx];
		raw_spin_lock_irqsave(&er->lock, flags);
		if (!atomic_read(&er->ref) || er->config == config) {
			atomic_inc(&er->ref);
			er->config = config;
			ret = true;
		}
		raw_spin_unlock_irqrestore(&er->lock, flags);

		return ret;
	}
	/*
	 * The ZDP_CTL_FVC MSR has 4 fields which are used to control
	 * events 0xd ~ 0x10. Besides these 4 fields, there are additional
	 * fields which are shared.
	 */
	idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
	if (WARN_ON_ONCE(idx >= 4))
		return false;

	/* mask of the shared fields */
	if (uncore_nhmex)
		mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
	else
		mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK;
	er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];

	raw_spin_lock_irqsave(&er->lock, flags);
	/* add mask of the non-shared field if it's in use */
	if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) {
		if (uncore_nhmex)
			mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
		else
			mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
	}

	if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) {
		atomic_add(1 << (idx * 8), &er->ref);
		if (uncore_nhmex)
			mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
				NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
		else
			mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK |
				WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
		er->config &= ~mask;
		er->config |= (config & mask);
		ret = true;
	}
	raw_spin_unlock_irqrestore(&er->lock, flags);

	return ret;
}

static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx)
{
	struct intel_uncore_extra_reg *er;

	if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
		er = &box->shared_regs[idx];
		atomic_dec(&er->ref);
		return;
	}

	idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
	er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
	atomic_sub(1 << (idx * 8), &er->ref);
}

static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
	u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
	u64 config = reg1->config;

	/* get the non-shared control bits and shift them */
	idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
	if (uncore_nhmex)
		config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
	else
		config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
	if (new_idx > orig_idx) {
		idx = new_idx - orig_idx;
		config <<= 3 * idx;
	} else {
		idx = orig_idx - new_idx;
		config >>= 3 * idx;
	}

	/* add the shared control bits back */
	if (uncore_nhmex)
		config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
	else
		config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
	config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
	if (modify) {
		/* adjust the main event selector */
		if (new_idx > orig_idx)
			hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
		else
			hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
		reg1->config = config;
		reg1->idx = ~0xff | new_idx;
	}
	return config;
}

static struct event_constraint *
nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
	int i, idx[2], alloc = 0;
	u64 config1 = reg1->config;

	idx[0] = __BITS_VALUE(reg1->idx, 0, 8);
	idx[1] = __BITS_VALUE(reg1->idx, 1, 8);
again:
	for (i = 0; i < 2; i++) {
		if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
			idx[i] = 0xff;

		if (idx[i] == 0xff)
			continue;

		if (!nhmex_mbox_get_shared_reg(box, idx[i],
				__BITS_VALUE(config1, i, 32)))
			goto fail;
		alloc |= (0x1 << i);
	}

	/* for the match/mask registers */
	if (reg2->idx != EXTRA_REG_NONE &&
	    (uncore_box_is_fake(box) || !reg2->alloc) &&
	    !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config))
		goto fail;

	/*
	 * If it's a fake box -- as per validate_{group,event}() we
	 * shouldn't touch event state and we can avoid doing so
	 * since both will only call get_event_constraints() once
	 * on each event, this avoids the need for reg->alloc.
	 */
	if (!uncore_box_is_fake(box)) {
		if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8))
			nhmex_mbox_alter_er(event, idx[0], true);
		reg1->alloc |= alloc;
		if (reg2->idx != EXTRA_REG_NONE)
			reg2->alloc = 1;
	}
	return NULL;
fail:
	if (idx[0] != 0xff && !(alloc & 0x1) &&
	    idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
		/*
		 * events 0xd ~ 0x10 are functional identical, but are
		 * controlled by different fields in the ZDP_CTL_FVC
		 * register. If we failed to take one field, try the
		 * rest 3 choices.
		 */
		BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff);
		idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
		idx[0] = (idx[0] + 1) % 4;
		idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
		if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) {
			config1 = nhmex_mbox_alter_er(event, idx[0], false);
			goto again;
		}
	}

	if (alloc & 0x1)
		nhmex_mbox_put_shared_reg(box, idx[0]);
	if (alloc & 0x2)
		nhmex_mbox_put_shared_reg(box, idx[1]);
	return &uncore_constraint_empty;
}

static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;

	if (uncore_box_is_fake(box))
		return;

	if (reg1->alloc & 0x1)
		nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8));
	if (reg1->alloc & 0x2)
		nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8));
	reg1->alloc = 0;

	if (reg2->alloc) {
		nhmex_mbox_put_shared_reg(box, reg2->idx);
		reg2->alloc = 0;
	}
}

static int nhmex_mbox_extra_reg_idx(struct extra_reg *er)
{
	if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
		return er->idx;
	return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd;
}

static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
{
	struct intel_uncore_type *type = box->pmu->type;
	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
	struct extra_reg *er;
	unsigned msr;
	int reg_idx = 0;
	/*
	 * The mbox events may require 2 extra MSRs at the most. But only
	 * the lower 32 bits in these MSRs are significant, so we can use
	 * config1 to pass two MSRs' config.
	 */
	for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) {
		if (er->event != (event->hw.config & er->config_mask))
			continue;
		if (event->attr.config1 & ~er->valid_mask)
			return -EINVAL;

		msr = er->msr + type->msr_offset * box->pmu->pmu_idx;
		if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff))
			return -EINVAL;

		/* always use the 32~63 bits to pass the PLD config */
		if (er->idx == EXTRA_REG_NHMEX_M_PLD)
			reg_idx = 1;
		else if (WARN_ON_ONCE(reg_idx > 0))
			return -EINVAL;

		reg1->idx &= ~(0xff << (reg_idx * 8));
		reg1->reg &= ~(0xffff << (reg_idx * 16));
		reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8);
		reg1->reg |= msr << (reg_idx * 16);
		reg1->config = event->attr.config1;
		reg_idx++;
	}
	/*
	 * The mbox only provides ability to perform address matching
	 * for the PLD events.
	 */
	if (reg_idx == 2) {
		reg2->idx = EXTRA_REG_NHMEX_M_FILTER;
		if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN)
			reg2->config = event->attr.config2;
		else
			reg2->config = ~0ULL;
		if (box->pmu->pmu_idx == 0)
			reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG;
		else
			reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG;
	}
	return 0;
}

static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx)
{
	struct intel_uncore_extra_reg *er;
	unsigned long flags;
	u64 config;

	if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
		return box->shared_regs[idx].config;

	er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
	raw_spin_lock_irqsave(&er->lock, flags);
	config = er->config;
	raw_spin_unlock_irqrestore(&er->lock, flags);
	return config;
}

static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
	int idx;

	idx = __BITS_VALUE(reg1->idx, 0, 8);
	if (idx != 0xff)
		wrmsrl(__BITS_VALUE(reg1->reg, 0, 16),
			nhmex_mbox_shared_reg_config(box, idx));
	idx = __BITS_VALUE(reg1->idx, 1, 8);
	if (idx != 0xff)
		wrmsrl(__BITS_VALUE(reg1->reg, 1, 16),
			nhmex_mbox_shared_reg_config(box, idx));

	if (reg2->idx != EXTRA_REG_NONE) {
		wrmsrl(reg2->reg, 0);
		if (reg2->config != ~0ULL) {
			wrmsrl(reg2->reg + 1,
				reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK);
			wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK &
				(reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT));
			wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN);
		}
	}

	wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
}

DEFINE_UNCORE_FORMAT_ATTR(count_mode,		count_mode,	"config:2-3");
DEFINE_UNCORE_FORMAT_ATTR(storage_mode,		storage_mode,	"config:4-5");
DEFINE_UNCORE_FORMAT_ATTR(wrap_mode,		wrap_mode,	"config:6");
DEFINE_UNCORE_FORMAT_ATTR(flag_mode,		flag_mode,	"config:7");
DEFINE_UNCORE_FORMAT_ATTR(inc_sel,		inc_sel,	"config:9-13");
DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel,		set_flag_sel,	"config:19-21");
DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en,	filter_cfg_en,	"config2:63");
DEFINE_UNCORE_FORMAT_ATTR(filter_match,		filter_match,	"config2:0-33");
DEFINE_UNCORE_FORMAT_ATTR(filter_mask,		filter_mask,	"config2:34-61");
DEFINE_UNCORE_FORMAT_ATTR(dsp,			dsp,		"config1:0-31");
DEFINE_UNCORE_FORMAT_ATTR(thr,			thr,		"config1:0-31");
DEFINE_UNCORE_FORMAT_ATTR(fvc,			fvc,		"config1:0-31");
DEFINE_UNCORE_FORMAT_ATTR(pgt,			pgt,		"config1:0-31");
DEFINE_UNCORE_FORMAT_ATTR(map,			map,		"config1:0-31");
DEFINE_UNCORE_FORMAT_ATTR(iss,			iss,		"config1:0-31");
DEFINE_UNCORE_FORMAT_ATTR(pld,			pld,		"config1:32-63");

static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
	&format_attr_count_mode.attr,
	&format_attr_storage_mode.attr,
	&format_attr_wrap_mode.attr,
	&format_attr_flag_mode.attr,
	&format_attr_inc_sel.attr,
	&format_attr_set_flag_sel.attr,
	&format_attr_filter_cfg_en.attr,
	&format_attr_filter_match.attr,
	&format_attr_filter_mask.attr,
	&format_attr_dsp.attr,
	&format_attr_thr.attr,
	&format_attr_fvc.attr,
	&format_attr_pgt.attr,
	&format_attr_map.attr,
	&format_attr_iss.attr,
	&format_attr_pld.attr,
	NULL,
};

static const struct attribute_group nhmex_uncore_mbox_format_group = {
	.name		= "format",
	.attrs		= nhmex_uncore_mbox_formats_attr,
};

static struct uncore_event_desc nhmex_uncore_mbox_events[] = {
	INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"),
	INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"),
	{ /* end: all zeroes */ },
};

static struct uncore_event_desc wsmex_uncore_mbox_events[] = {
	INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"),
	INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"),
	{ /* end: all zeroes */ },
};

static struct intel_uncore_ops nhmex_uncore_mbox_ops = {
	NHMEX_UNCORE_OPS_COMMON_INIT(),
	.enable_event	= nhmex_mbox_msr_enable_event,
	.hw_config	= nhmex_mbox_hw_config,
	.get_constraint	= nhmex_mbox_get_constraint,
	.put_constraint	= nhmex_mbox_put_constraint,
};

static struct intel_uncore_type nhmex_uncore_mbox = {
	.name			= "mbox",
	.num_counters		= 6,
	.num_boxes		= 2,
	.perf_ctr_bits		= 48,
	.event_ctl		= NHMEX_M0_MSR_PMU_CTL0,
	.perf_ctr		= NHMEX_M0_MSR_PMU_CNT0,
	.event_mask		= NHMEX_M_PMON_RAW_EVENT_MASK,
	.box_ctl		= NHMEX_M0_MSR_GLOBAL_CTL,
	.msr_offset		= NHMEX_M_MSR_OFFSET,
	.pair_ctr_ctl		= 1,
	.num_shared_regs	= 8,
	.event_descs		= nhmex_uncore_mbox_events,
	.ops			= &nhmex_uncore_mbox_ops,
	.format_group		= &nhmex_uncore_mbox_format_group,
};

static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;

	/* adjust the main event selector and extra register index */
	if (reg1->idx % 2) {
		reg1->idx--;
		hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
	} else {
		reg1->idx++;
		hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
	}

	/* adjust extra register config */
	switch (reg1->idx % 6) {
	case 2:
		/* shift the 8~15 bits to the 0~7 bits */
		reg1->config >>= 8;
		break;
	case 3:
		/* shift the 0~7 bits to the 8~15 bits */
		reg1->config <<= 8;
		break;
	}
}

/*
 * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7.
 * An event set consists of 6 events, the 3rd and 4th events in
 * an event set use the same extra register. So an event set uses
 * 5 extra registers.
 */
static struct event_constraint *
nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
	struct intel_uncore_extra_reg *er;
	unsigned long flags;
	int idx, er_idx;
	u64 config1;
	bool ok = false;

	if (!uncore_box_is_fake(box) && reg1->alloc)
		return NULL;

	idx = reg1->idx % 6;
	config1 = reg1->config;
again:
	er_idx = idx;
	/* the 3rd and 4th events use the same extra register */
	if (er_idx > 2)
		er_idx--;
	er_idx += (reg1->idx / 6) * 5;

	er = &box->shared_regs[er_idx];
	raw_spin_lock_irqsave(&er->lock, flags);
	if (idx < 2) {
		if (!atomic_read(&er->ref) || er->config == reg1->config) {
			atomic_inc(&er->ref);
			er->config = reg1->config;
			ok = true;
		}
	} else if (idx == 2 || idx == 3) {
		/*
		 * these two events use different fields in a extra register,
		 * the 0~7 bits and the 8~15 bits respectively.
		 */
		u64 mask = 0xff << ((idx - 2) * 8);
		if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) ||
				!((er->config ^ config1) & mask)) {
			atomic_add(1 << ((idx - 2) * 8), &er->ref);
			er->config &= ~mask;
			er->config |= config1 & mask;
			ok = true;
		}
	} else {
		if (!atomic_read(&er->ref) ||
				(er->config == (hwc->config >> 32) &&
				 er->config1 == reg1->config &&
				 er->config2 == reg2->config)) {
			atomic_inc(&er->ref);
			er->config = (hwc->config >> 32);
			er->config1 = reg1->config;
			er->config2 = reg2->config;
			ok = true;
		}
	}
	raw_spin_unlock_irqrestore(&er->lock, flags);

	if (!ok) {
		/*
		 * The Rbox events are always in pairs. The paired
		 * events are functional identical, but use different
		 * extra registers. If we failed to take an extra
		 * register, try the alternative.
		 */
		idx ^= 1;
		if (idx != reg1->idx % 6) {
			if (idx == 2)
				config1 >>= 8;
			else if (idx == 3)
				config1 <<= 8;
			goto again;
		}
	} else {
		if (!uncore_box_is_fake(box)) {
			if (idx != reg1->idx % 6)
				nhmex_rbox_alter_er(box, event);
			reg1->alloc = 1;
		}
		return NULL;
	}
	return &uncore_constraint_empty;
}

static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
{
	struct intel_uncore_extra_reg *er;
	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
	int idx, er_idx;

	if (uncore_box_is_fake(box) || !reg1->alloc)
		return;

	idx = reg1->idx % 6;
	er_idx = idx;
	if (er_idx > 2)
		er_idx--;
	er_idx += (reg1->idx / 6) * 5;

	er = &box->shared_regs[er_idx];
	if (idx == 2 || idx == 3)
		atomic_sub(1 << ((idx - 2) * 8), &er->ref);
	else
		atomic_dec(&er->ref);

	reg1->alloc = 0;
}

static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
	struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
	int idx;

	idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >>
		NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
	if (idx >= 0x18)
		return -EINVAL;

	reg1->idx = idx;
	reg1->config = event->attr.config1;

	switch (idx % 6) {
	case 4:
	case 5:
		hwc->config |= event->attr.config & (~0ULL << 32);
		reg2->config = event->attr.config2;
		break;
	}
	return 0;
}

static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
	int idx, port;

	idx = reg1->idx;
	port = idx / 6 + box->pmu->pmu_idx * 4;

	switch (idx % 6) {
	case 0:
		wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config);
		break;
	case 1:
		wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config);
		break;
	case 2:
	case 3:
		wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port),
			uncore_shared_reg_config(box, 2 + (idx / 6) * 5));
		break;
	case 4:
		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port),
			hwc->config >> 32);
		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config);
		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config);
		break;
	case 5:
		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port),
			hwc->config >> 32);
		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config);
		wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config);
		break;
	}

	wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
		(hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK));
}

DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63");
DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63");
DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63");
DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15");
DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31");

static struct attribute *nhmex_uncore_rbox_formats_attr[] = {
	&format_attr_event5.attr,
	&format_attr_xbr_mm_cfg.attr,
	&format_attr_xbr_match.attr,
	&format_attr_xbr_mask.attr,
	&format_attr_qlx_cfg.attr,
	&format_attr_iperf_cfg.attr,
	NULL,
};

static const struct attribute_group nhmex_uncore_rbox_format_group = {
	.name = "format",
	.attrs = nhmex_uncore_rbox_formats_attr,
};

static struct uncore_event_desc nhmex_uncore_rbox_events[] = {
	INTEL_UNCORE_EVENT_DESC(qpi0_flit_send,		"event=0x0,iperf_cfg=0x80000000"),
	INTEL_UNCORE_EVENT_DESC(qpi1_filt_send,		"event=0x6,iperf_cfg=0x80000000"),
	INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt,		"event=0x0,iperf_cfg=0x40000000"),
	INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt,		"event=0x6,iperf_cfg=0x40000000"),
	INTEL_UNCORE_EVENT_DESC(qpi0_date_response,	"event=0x0,iperf_cfg=0xc4"),
	INTEL_UNCORE_EVENT_DESC(qpi1_date_response,	"event=0x6,iperf_cfg=0xc4"),
	{ /* end: all zeroes */ },
};

static struct intel_uncore_ops nhmex_uncore_rbox_ops = {
	NHMEX_UNCORE_OPS_COMMON_INIT(),
	.enable_event		= nhmex_rbox_msr_enable_event,
	.hw_config		= nhmex_rbox_hw_config,
	.get_constraint		= nhmex_rbox_get_constraint,
	.put_constraint		= nhmex_rbox_put_constraint,
};

static struct intel_uncore_type nhmex_uncore_rbox = {
	.name			= "rbox",
	.num_counters		= 8,
	.num_boxes		= 2,
	.perf_ctr_bits		= 48,
	.event_ctl		= NHMEX_R_MSR_PMON_CTL0,
	.perf_ctr		= NHMEX_R_MSR_PMON_CNT0,
	.event_mask		= NHMEX_R_PMON_RAW_EVENT_MASK,
	.box_ctl		= NHMEX_R_MSR_GLOBAL_CTL,
	.msr_offset		= NHMEX_R_MSR_OFFSET,
	.pair_ctr_ctl		= 1,
	.num_shared_regs	= 20,
	.event_descs		= nhmex_uncore_rbox_events,
	.ops			= &nhmex_uncore_rbox_ops,
	.format_group		= &nhmex_uncore_rbox_format_group
};

static struct intel_uncore_type *nhmex_msr_uncores[] = {
	&nhmex_uncore_ubox,
	&nhmex_uncore_cbox,
	&nhmex_uncore_bbox,
	&nhmex_uncore_sbox,
	&nhmex_uncore_mbox,
	&nhmex_uncore_rbox,
	&nhmex_uncore_wbox,
	NULL,
};

void nhmex_uncore_cpu_init(void)
{
	if (boot_cpu_data.x86_model == 46)
		uncore_nhmex = true;
	else
		nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
	if (nhmex_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
		nhmex_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
	uncore_msr_uncores = nhmex_msr_uncores;
}
/* end of Nehalem-EX uncore support */
