Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e765f37b authored by Srinivas Pandruvada's avatar Srinivas Pandruvada Committed by Andy Shevchenko
Browse files

platform/x86: ISST: Add Intel Speed Select PUNIT MSR interface



While using new non arhitectural features using PUNIT Mailbox and MMIO
read/write interface, still there is need to operate using MSRs to
control PUNIT. User space could have used user user-space MSR interface for
this, but when user space MSR access is disabled, then it can't. Here only
limited number of MSRs are allowed using this new interface.

Signed-off-by: default avatarSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
parent 71b21bd7
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -25,6 +25,11 @@

static struct isst_if_cmd_cb punit_callbacks[ISST_IF_DEV_MAX];

static int punit_msr_white_list[] = {
	MSR_TURBO_RATIO_LIMIT,
	MSR_CONFIG_TDP_CONTROL,
};

struct isst_valid_cmd_ranges {
	u16 cmd;
	u16 sub_cmd_beg;
@@ -229,6 +234,54 @@ static long isst_if_proc_phyid_req(u8 *cmd_ptr, int *write_only, int resume)
	return 0;
}

static bool match_punit_msr_white_list(int msr)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(punit_msr_white_list); ++i) {
		if (punit_msr_white_list[i] == msr)
			return true;
	}

	return false;
}

static long isst_if_msr_cmd_req(u8 *cmd_ptr, int *write_only, int resume)
{
	struct isst_if_msr_cmd *msr_cmd;
	int ret;

	msr_cmd = (struct isst_if_msr_cmd *)cmd_ptr;

	if (!match_punit_msr_white_list(msr_cmd->msr))
		return -EINVAL;

	if (msr_cmd->logical_cpu >= nr_cpu_ids)
		return -EINVAL;

	if (msr_cmd->read_write) {
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;

		ret = wrmsrl_safe_on_cpu(msr_cmd->logical_cpu,
					 msr_cmd->msr,
					 msr_cmd->data);
		*write_only = 1;
	} else {
		u64 data;

		ret = rdmsrl_safe_on_cpu(msr_cmd->logical_cpu,
					 msr_cmd->msr, &data);
		if (!ret) {
			msr_cmd->data = data;
			*write_only = 0;
		}
	}


	return ret;
}

static long isst_if_exec_multi_cmd(void __user *argp, struct isst_if_cmd_cb *cb)
{
	unsigned char __user *ptr;
@@ -309,6 +362,12 @@ static long isst_if_def_ioctl(struct file *file, unsigned int cmd,
		if (cb->registered)
			ret = isst_if_exec_multi_cmd(argp, cb);
		break;
	case ISST_IF_MSR_COMMAND:
		cmd_cb.cmd_size = sizeof(struct isst_if_msr_cmd);
		cmd_cb.offset = offsetof(struct isst_if_msr_cmds, msr_cmd);
		cmd_cb.cmd_callback = isst_if_msr_cmd_req;
		ret = isst_if_exec_multi_cmd(argp, &cmd_cb);
		break;
	default:
		break;
	}
+32 −0
Original line number Diff line number Diff line
@@ -132,9 +132,41 @@ struct isst_if_mbox_cmds {
	struct isst_if_mbox_cmd mbox_cmd[1];
};

/**
 * struct isst_if_msr_cmd - Structure to define msr command
 * @read_write:		Value 0: Read, 1: Write
 * @logical_cpu:	Logical CPU number
 * @msr:		MSR number
 * @data:		For write operation, data to write, for read
 *			place holder
 *
 * Structure to specify MSR command related to PUNIT.
 */
struct isst_if_msr_cmd {
	__u32 read_write; /* Read:0, Write:1 */
	__u32 logical_cpu;
	__u64 msr;
	__u64 data;
};

/**
 * struct isst_if_msr_cmds - structure for msr commands
 * @cmd_count:	Number of mailbox commands in msr_cmd[]
 * @msr_cmd[]:	Holds one or more msr commands
 *
 * This structure used with ioctl ISST_IF_MSR_COMMAND to send
 * one or more MSR commands. IOCTL return value indicates number of
 * commands sent or error number if no commands have been sent.
 */
struct isst_if_msr_cmds {
	__u32 cmd_count;
	struct isst_if_msr_cmd msr_cmd[1];
};

#define ISST_IF_MAGIC			0xFE
#define ISST_IF_GET_PLATFORM_INFO	_IOR(ISST_IF_MAGIC, 0, struct isst_if_platform_info *)
#define ISST_IF_GET_PHY_ID		_IOWR(ISST_IF_MAGIC, 1, struct isst_if_cpu_map *)
#define ISST_IF_IO_CMD		_IOW(ISST_IF_MAGIC, 2, struct isst_if_io_regs *)
#define ISST_IF_MBOX_COMMAND	_IOWR(ISST_IF_MAGIC, 3, struct isst_if_mbox_cmds *)
#define ISST_IF_MSR_COMMAND	_IOWR(ISST_IF_MAGIC, 4, struct isst_if_msr_cmds *)
#endif