Commit 52f6efdf authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman
Browse files

mei: add trc detection register to sysfs



The glitch detection HW (TRC) save it status information into
TRC status register.
Make it available to user-space via read-only sysfs file.
The TRC register is availab for PCH15 gen and newer, for older
platforms reading the sysfs file will fail with EOPNOTSUPP.

Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Link: https://lore.kernel.org/r/20191107104445.19101-1-tomas.winkler@intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 261e071a
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -80,3 +80,13 @@ Description: Display the ME device state.
		DISABLED
		POWER_DOWN
		POWER_UP

What:		/sys/class/mei/meiN/trc
Date:		Nov 2019
KernelVersion:	5.5
Contact:	Tomas Winkler <tomas.winkler@intel.com>
Description:	Display trc status register content

		The ME FW writes Glitch Detection HW (TRC)
		status information into trc status register
		for BIOS and OS to monitor fw health.
+2 −1
Original line number Diff line number Diff line
@@ -163,7 +163,8 @@ access to ME_CBD */
#define ME_IS_HRA         0x00000002
/* ME Interrupt Enable HRA - host read only access to ME_IE */
#define ME_IE_HRA         0x00000001

/* TRC control shadow register */
#define ME_TRC            0x00000030

/* H_HPG_CSR register bits */
#define H_HPG_CSR_PGIHEXR 0x00000001
+34 −0
Original line number Diff line number Diff line
@@ -172,6 +172,27 @@ static inline void mei_me_d0i3c_write(struct mei_device *dev, u32 reg)
	mei_me_reg_write(to_me_hw(dev), H_D0I3C, reg);
}

/**
 * mei_me_trc_status - read trc status register
 *
 * @dev: mei device
 * @trc: trc status register value
 *
 * Return: 0 on success, error otherwise
 */
static int mei_me_trc_status(struct mei_device *dev, u32 *trc)
{
	struct mei_me_hw *hw = to_me_hw(dev);

	if (!hw->cfg->hw_trc_supported)
		return -EOPNOTSUPP;

	*trc = mei_me_reg_read(hw, ME_TRC);
	trace_mei_reg_read(dev->dev, "ME_TRC", ME_TRC, *trc);

	return 0;
}

/**
 * mei_me_fw_status - read fw status register from pci config space
 *
@@ -1302,6 +1323,7 @@ end:

static const struct mei_hw_ops mei_me_hw_ops = {

	.trc_status = mei_me_trc_status,
	.fw_status = mei_me_fw_status,
	.pg_state  = mei_me_pg_state,

@@ -1392,6 +1414,9 @@ static bool mei_me_fw_type_sps(struct pci_dev *pdev)
	.dma_size[DMA_DSCR_DEVICE] = SZ_128K, \
	.dma_size[DMA_DSCR_CTRL] = PAGE_SIZE

#define MEI_CFG_TRC \
	.hw_trc_supported = 1

/* ICH Legacy devices */
static const struct mei_cfg mei_me_ich_cfg = {
	MEI_CFG_ICH_HFS,
@@ -1440,6 +1465,14 @@ static const struct mei_cfg mei_me_pch12_cfg = {
	MEI_CFG_DMA_128,
};

/* Tiger Lake and newer devices */
static const struct mei_cfg mei_me_pch15_cfg = {
	MEI_CFG_PCH8_HFS,
	MEI_CFG_FW_VER_SUPP,
	MEI_CFG_DMA_128,
	MEI_CFG_TRC,
};

/*
 * mei_cfg_list - A list of platform platform specific configurations.
 * Note: has to be synchronized with  enum mei_cfg_idx.
@@ -1454,6 +1487,7 @@ static const struct mei_cfg *const mei_cfg_list[] = {
	[MEI_ME_PCH8_CFG] = &mei_me_pch8_cfg,
	[MEI_ME_PCH8_SPS_CFG] = &mei_me_pch8_sps_cfg,
	[MEI_ME_PCH12_CFG] = &mei_me_pch12_cfg,
	[MEI_ME_PCH15_CFG] = &mei_me_pch15_cfg,
};

const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
+4 −0
Original line number Diff line number Diff line
@@ -21,12 +21,14 @@
 * @quirk_probe: device exclusion quirk
 * @dma_size: device DMA buffers size
 * @fw_ver_supported: is fw version retrievable from FW
 * @hw_trc_supported: does the hw support trc register
 */
struct mei_cfg {
	const struct mei_fw_status fw_status;
	bool (*quirk_probe)(struct pci_dev *pdev);
	size_t dma_size[DMA_DSCR_NUM];
	u32 fw_ver_supported:1;
	u32 hw_trc_supported:1;
};


@@ -78,6 +80,7 @@ struct mei_me_hw {
 *                         servers platforms with quirk for
 *                         SPS firmware exclusion.
 * @MEI_ME_PCH12_CFG:      Platform Controller Hub Gen12 and newer
 * @MEI_ME_PCH15_CFG:      Platform Controller Hub Gen15 and newer
 * @MEI_ME_NUM_CFG:        Upper Sentinel.
 */
enum mei_cfg_idx {
@@ -90,6 +93,7 @@ enum mei_cfg_idx {
	MEI_ME_PCH8_CFG,
	MEI_ME_PCH8_SPS_CFG,
	MEI_ME_PCH12_CFG,
	MEI_ME_PCH15_CFG,
	MEI_ME_NUM_CFG,
};

+24 −0
Original line number Diff line number Diff line
@@ -700,6 +700,29 @@ static int mei_fasync(int fd, struct file *file, int band)
	return fasync_helper(fd, file, band, &cl->ev_async);
}

/**
 * trc_show - mei device trc attribute show method
 *
 * @device: device pointer
 * @attr: attribute pointer
 * @buf:  char out buffer
 *
 * Return: number of the bytes printed into buf or error
 */
static ssize_t trc_show(struct device *device,
			struct device_attribute *attr, char *buf)
{
	struct mei_device *dev = dev_get_drvdata(device);
	u32 trc;
	int ret;

	ret = mei_trc_status(dev, &trc);
	if (ret)
		return ret;
	return sprintf(buf, "%08X\n", trc);
}
static DEVICE_ATTR_RO(trc);

/**
 * fw_status_show - mei device fw_status attribute show method
 *
@@ -887,6 +910,7 @@ static struct attribute *mei_attrs[] = {
	&dev_attr_tx_queue_limit.attr,
	&dev_attr_fw_ver.attr,
	&dev_attr_dev_state.attr,
	&dev_attr_trc.attr,
	NULL
};
ATTRIBUTE_GROUPS(mei);
Loading