File Index
Files and directories
Sign in
FILE

mlxbf-bootctl.c

File preview with syntax highlighting.

linux-6.19.14/drivers/platform/mellanox/mlxbf-bootctl.c C
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Mellanox boot control driver
   4 *
   5 * This driver provides a sysfs interface for systems management
   6 * software to manage reset-time actions.
   7 *
   8 * Copyright (C) 2019 Mellanox Technologies
   9 */
  10
  11#include <linux/acpi.h>
  12#include <linux/arm-smccc.h>
  13#include <linux/delay.h>
  14#include <linux/if_ether.h>
  15#include <linux/iopoll.h>
  16#include <linux/module.h>
  17#include <linux/platform_device.h>
  18
  19#include "mlxbf-bootctl.h"
  20
  21#define MLXBF_BOOTCTL_SB_SECURE_MASK		0x03
  22#define MLXBF_BOOTCTL_SB_TEST_MASK		0x0c
  23#define MLXBF_BOOTCTL_SB_DEV_MASK		BIT(4)
  24
  25#define MLXBF_SB_KEY_NUM			4
  26
  27/* UUID used to probe ATF service. */
  28static const char *mlxbf_bootctl_svc_uuid_str =
  29	"89c036b4-e7d7-11e6-8797-001aca00bfc4";
  30
  31struct mlxbf_bootctl_name {
  32	u32 value;
  33	const char *name;
  34};
  35
  36static struct mlxbf_bootctl_name boot_names[] = {
  37	{ MLXBF_BOOTCTL_EXTERNAL, "external" },
  38	{ MLXBF_BOOTCTL_EMMC, "emmc" },
  39	{ MLNX_BOOTCTL_SWAP_EMMC, "swap_emmc" },
  40	{ MLXBF_BOOTCTL_EMMC_LEGACY, "emmc_legacy" },
  41	{ MLXBF_BOOTCTL_NONE, "none" },
  42};
  43
  44enum {
  45	MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION = 0,
  46	MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE = 1,
  47	MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE = 2,
  48	MLXBF_BOOTCTL_SB_LIFECYCLE_RMA = 3
  49};
  50
  51static const char * const mlxbf_bootctl_lifecycle_states[] = {
  52	[MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION] = "Production",
  53	[MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE] = "GA Secured",
  54	[MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE] = "GA Non-Secured",
  55	[MLXBF_BOOTCTL_SB_LIFECYCLE_RMA] = "RMA",
  56};
  57
  58/* Log header format. */
  59#define MLXBF_RSH_LOG_TYPE_MASK		GENMASK_ULL(59, 56)
  60#define MLXBF_RSH_LOG_LEN_MASK		GENMASK_ULL(54, 48)
  61#define MLXBF_RSH_LOG_LEVEL_MASK	GENMASK_ULL(7, 0)
  62
  63/* Log module ID and type (only MSG type in Linux driver for now). */
  64#define MLXBF_RSH_LOG_TYPE_MSG		0x04ULL
  65
  66/* Log ctl/data register offset. */
  67#define MLXBF_RSH_SCRATCH_BUF_CTL_OFF	0
  68#define MLXBF_RSH_SCRATCH_BUF_DATA_OFF	0x10
  69
  70/* Log message levels. */
  71enum {
  72	MLXBF_RSH_LOG_INFO,
  73	MLXBF_RSH_LOG_WARN,
  74	MLXBF_RSH_LOG_ERR,
  75	MLXBF_RSH_LOG_ASSERT
  76};
  77
  78/* Mapped pointer for RSH_BOOT_FIFO_DATA and RSH_BOOT_FIFO_COUNT register. */
  79static void __iomem *mlxbf_rsh_boot_data;
  80static void __iomem *mlxbf_rsh_boot_cnt;
  81
  82/* Mapped pointer for rsh log semaphore/ctrl/data register. */
  83static void __iomem *mlxbf_rsh_semaphore;
  84static void __iomem *mlxbf_rsh_scratch_buf_ctl;
  85static void __iomem *mlxbf_rsh_scratch_buf_data;
  86
  87/* Rsh log levels. */
  88static const char * const mlxbf_rsh_log_level[] = {
  89	"INFO", "WARN", "ERR", "ASSERT"};
  90
  91static DEFINE_MUTEX(icm_ops_lock);
  92static DEFINE_MUTEX(os_up_lock);
  93static DEFINE_MUTEX(mfg_ops_lock);
  94static DEFINE_MUTEX(rtc_ops_lock);
  95
  96/*
  97 * Objects are stored within the MFG partition per type.
  98 * Type 0 is not supported.
  99 */
 100enum {
 101	MLNX_MFG_TYPE_OOB_MAC = 1,
 102	MLNX_MFG_TYPE_OPN_0,
 103	MLNX_MFG_TYPE_OPN_1,
 104	MLNX_MFG_TYPE_OPN_2,
 105	MLNX_MFG_TYPE_SKU_0,
 106	MLNX_MFG_TYPE_SKU_1,
 107	MLNX_MFG_TYPE_SKU_2,
 108	MLNX_MFG_TYPE_MODL_0,
 109	MLNX_MFG_TYPE_MODL_1,
 110	MLNX_MFG_TYPE_MODL_2,
 111	MLNX_MFG_TYPE_SN_0,
 112	MLNX_MFG_TYPE_SN_1,
 113	MLNX_MFG_TYPE_SN_2,
 114	MLNX_MFG_TYPE_UUID_0,
 115	MLNX_MFG_TYPE_UUID_1,
 116	MLNX_MFG_TYPE_UUID_2,
 117	MLNX_MFG_TYPE_UUID_3,
 118	MLNX_MFG_TYPE_UUID_4,
 119	MLNX_MFG_TYPE_REV,
 120};
 121
 122#define MLNX_MFG_OPN_VAL_LEN         24
 123#define MLNX_MFG_SKU_VAL_LEN         24
 124#define MLNX_MFG_MODL_VAL_LEN        24
 125#define MLNX_MFG_SN_VAL_LEN          24
 126#define MLNX_MFG_UUID_VAL_LEN        40
 127#define MLNX_MFG_REV_VAL_LEN         8
 128#define MLNX_MFG_VAL_QWORD_CNT(type) \
 129	(MLNX_MFG_##type##_VAL_LEN / sizeof(u64))
 130
 131/*
 132 * The MAC address consists of 6 bytes (2 digits each) separated by ':'.
 133 * The expected format is: "XX:XX:XX:XX:XX:XX"
 134 */
 135#define MLNX_MFG_OOB_MAC_FORMAT_LEN \
 136	((ETH_ALEN * 2) + (ETH_ALEN - 1))
 137
 138/* ARM SMC call which is atomic and no need for lock. */
 139static int mlxbf_bootctl_smc(unsigned int smc_op, int smc_arg)
 140{
 141	struct arm_smccc_res res;
 142
 143	arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, &res);
 144
 145	return res.a0;
 146}
 147
 148/* Return the action in integer or an error code. */
 149static int mlxbf_bootctl_reset_action_to_val(const char *action)
 150{
 151	int i;
 152
 153	for (i = 0; i < ARRAY_SIZE(boot_names); i++)
 154		if (sysfs_streq(boot_names[i].name, action))
 155			return boot_names[i].value;
 156
 157	return -EINVAL;
 158}
 159
 160/* Return the action in string. */
 161static const char *mlxbf_bootctl_action_to_string(int action)
 162{
 163	int i;
 164
 165	for (i = 0; i < ARRAY_SIZE(boot_names); i++)
 166		if (boot_names[i].value == action)
 167			return boot_names[i].name;
 168
 169	return "invalid action";
 170}
 171
 172static ssize_t post_reset_wdog_show(struct device *dev,
 173				    struct device_attribute *attr, char *buf)
 174{
 175	int ret;
 176
 177	ret = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_POST_RESET_WDOG, 0);
 178	if (ret < 0)
 179		return ret;
 180
 181	return sysfs_emit(buf, "%d\n", ret);
 182}
 183
 184static ssize_t post_reset_wdog_store(struct device *dev,
 185				     struct device_attribute *attr,
 186				     const char *buf, size_t count)
 187{
 188	unsigned long value;
 189	int ret;
 190
 191	ret = kstrtoul(buf, 10, &value);
 192	if (ret)
 193		return ret;
 194
 195	ret = mlxbf_bootctl_smc(MLXBF_BOOTCTL_SET_POST_RESET_WDOG, value);
 196	if (ret < 0)
 197		return ret;
 198
 199	return count;
 200}
 201
 202static ssize_t mlxbf_bootctl_show(int smc_op, char *buf)
 203{
 204	int action;
 205
 206	action = mlxbf_bootctl_smc(smc_op, 0);
 207	if (action < 0)
 208		return action;
 209
 210	return sysfs_emit(buf, "%s\n", mlxbf_bootctl_action_to_string(action));
 211}
 212
 213static int mlxbf_bootctl_store(int smc_op, const char *buf, size_t count)
 214{
 215	int ret, action;
 216
 217	action = mlxbf_bootctl_reset_action_to_val(buf);
 218	if (action < 0)
 219		return action;
 220
 221	ret = mlxbf_bootctl_smc(smc_op, action);
 222	if (ret < 0)
 223		return ret;
 224
 225	return count;
 226}
 227
 228static ssize_t reset_action_show(struct device *dev,
 229				 struct device_attribute *attr, char *buf)
 230{
 231	return mlxbf_bootctl_show(MLXBF_BOOTCTL_GET_RESET_ACTION, buf);
 232}
 233
 234static ssize_t reset_action_store(struct device *dev,
 235				  struct device_attribute *attr,
 236				  const char *buf, size_t count)
 237{
 238	return mlxbf_bootctl_store(MLXBF_BOOTCTL_SET_RESET_ACTION, buf, count);
 239}
 240
 241static ssize_t second_reset_action_show(struct device *dev,
 242					struct device_attribute *attr,
 243					char *buf)
 244{
 245	return mlxbf_bootctl_show(MLXBF_BOOTCTL_GET_SECOND_RESET_ACTION, buf);
 246}
 247
 248static ssize_t second_reset_action_store(struct device *dev,
 249					 struct device_attribute *attr,
 250					 const char *buf, size_t count)
 251{
 252	return mlxbf_bootctl_store(MLXBF_BOOTCTL_SET_SECOND_RESET_ACTION, buf,
 253				   count);
 254}
 255
 256static ssize_t lifecycle_state_show(struct device *dev,
 257				    struct device_attribute *attr, char *buf)
 258{
 259	int status_bits;
 260	int use_dev_key;
 261	int test_state;
 262	int lc_state;
 263
 264	status_bits = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
 265					MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE);
 266	if (status_bits < 0)
 267		return status_bits;
 268
 269	use_dev_key = status_bits & MLXBF_BOOTCTL_SB_DEV_MASK;
 270	test_state = status_bits & MLXBF_BOOTCTL_SB_TEST_MASK;
 271	lc_state = status_bits & MLXBF_BOOTCTL_SB_SECURE_MASK;
 272
 273	/*
 274	 * If the test bits are set, we specify that the current state may be
 275	 * due to using the test bits.
 276	 */
 277	if (test_state) {
 278		return sysfs_emit(buf, "%s(test)\n",
 279			       mlxbf_bootctl_lifecycle_states[lc_state]);
 280	} else if (use_dev_key &&
 281		   (lc_state == MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE)) {
 282		return sysfs_emit(buf, "Secured (development)\n");
 283	}
 284
 285	return sysfs_emit(buf, "%s\n", mlxbf_bootctl_lifecycle_states[lc_state]);
 286}
 287
 288static ssize_t secure_boot_fuse_state_show(struct device *dev,
 289					   struct device_attribute *attr,
 290					   char *buf)
 291{
 292	int burnt, valid, key, key_state, buf_len = 0, upper_key_used = 0;
 293	const char *status;
 294
 295	key_state = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
 296				      MLXBF_BOOTCTL_FUSE_STATUS_KEYS);
 297	if (key_state < 0)
 298		return key_state;
 299
 300	/*
 301	 * key_state contains the bits for 4 Key versions, loaded from eFuses
 302	 * after a hard reset. Lower 4 bits are a thermometer code indicating
 303	 * key programming has started for key n (0000 = none, 0001 = version 0,
 304	 * 0011 = version 1, 0111 = version 2, 1111 = version 3). Upper 4 bits
 305	 * are a thermometer code indicating key programming has completed for
 306	 * key n (same encodings as the start bits). This allows for detection
 307	 * of an interruption in the programming process which has left the key
 308	 * partially programmed (and thus invalid). The process is to burn the
 309	 * eFuse for the new key start bit, burn the key eFuses, then burn the
 310	 * eFuse for the new key complete bit.
 311	 *
 312	 * For example 0000_0000: no key valid, 0001_0001: key version 0 valid,
 313	 * 0011_0011: key 1 version valid, 0011_0111: key version 2 started
 314	 * programming but did not complete, etc. The most recent key for which
 315	 * both start and complete bit is set is loaded. On soft reset, this
 316	 * register is not modified.
 317	 */
 318	for (key = MLXBF_SB_KEY_NUM - 1; key >= 0; key--) {
 319		burnt = key_state & BIT(key);
 320		valid = key_state & BIT(key + MLXBF_SB_KEY_NUM);
 321
 322		if (burnt && valid)
 323			upper_key_used = 1;
 324
 325		if (upper_key_used) {
 326			if (burnt)
 327				status = valid ? "Used" : "Wasted";
 328			else
 329				status = valid ? "Invalid" : "Skipped";
 330		} else {
 331			if (burnt)
 332				status = valid ? "InUse" : "Incomplete";
 333			else
 334				status = valid ? "Invalid" : "Free";
 335		}
 336		buf_len += sysfs_emit_at(buf, buf_len, "%d:%s ", key, status);
 337	}
 338	buf_len += sysfs_emit_at(buf, buf_len, "\n");
 339
 340	return buf_len;
 341}
 342
 343static ssize_t fw_reset_store(struct device *dev,
 344			      struct device_attribute *attr,
 345			      const char *buf, size_t count)
 346{
 347	unsigned long key;
 348	int err;
 349
 350	err = kstrtoul(buf, 16, &key);
 351	if (err)
 352		return err;
 353
 354	if (mlxbf_bootctl_smc(MLXBF_BOOTCTL_FW_RESET, key) < 0)
 355		return -EINVAL;
 356
 357	return count;
 358}
 359
 360/* Size(8-byte words) of the log buffer. */
 361#define RSH_SCRATCH_BUF_CTL_IDX_MASK	0x7f
 362
 363/* 100ms timeout */
 364#define RSH_SCRATCH_BUF_POLL_TIMEOUT	100000
 365
 366static int mlxbf_rsh_log_sem_lock(void)
 367{
 368	unsigned long reg;
 369
 370	return readq_poll_timeout(mlxbf_rsh_semaphore, reg, !reg, 0,
 371				  RSH_SCRATCH_BUF_POLL_TIMEOUT);
 372}
 373
 374static void mlxbf_rsh_log_sem_unlock(void)
 375{
 376	writeq(0, mlxbf_rsh_semaphore);
 377}
 378
 379static ssize_t rsh_log_store(struct device *dev,
 380			     struct device_attribute *attr,
 381			     const char *buf, size_t count)
 382{
 383	int rc, idx, num, len, level = MLXBF_RSH_LOG_INFO;
 384	size_t size = count;
 385	u64 data;
 386
 387	if (!size)
 388		return -EINVAL;
 389
 390	if (!mlxbf_rsh_semaphore || !mlxbf_rsh_scratch_buf_ctl)
 391		return -EOPNOTSUPP;
 392
 393	/* Ignore line break at the end. */
 394	if (buf[size - 1] == '\n')
 395		size--;
 396
 397	/* Check the message prefix. */
 398	for (idx = 0; idx < ARRAY_SIZE(mlxbf_rsh_log_level); idx++) {
 399		len = strlen(mlxbf_rsh_log_level[idx]);
 400		if (len + 1 < size &&
 401		    !strncmp(buf, mlxbf_rsh_log_level[idx], len)) {
 402			buf += len;
 403			size -= len;
 404			level = idx;
 405			break;
 406		}
 407	}
 408
 409	/* Ignore leading spaces. */
 410	while (size > 0 && buf[0] == ' ') {
 411		size--;
 412		buf++;
 413	}
 414
 415	/* Take the semaphore. */
 416	rc = mlxbf_rsh_log_sem_lock();
 417	if (rc)
 418		return rc;
 419
 420	/* Calculate how many words are available. */
 421	idx = readq(mlxbf_rsh_scratch_buf_ctl);
 422	num = min((int)DIV_ROUND_UP(size, sizeof(u64)),
 423		  RSH_SCRATCH_BUF_CTL_IDX_MASK - idx - 1);
 424	if (num <= 0)
 425		goto done;
 426
 427	/* Write Header. */
 428	data = FIELD_PREP(MLXBF_RSH_LOG_TYPE_MASK, MLXBF_RSH_LOG_TYPE_MSG);
 429	data |= FIELD_PREP(MLXBF_RSH_LOG_LEN_MASK, num);
 430	data |= FIELD_PREP(MLXBF_RSH_LOG_LEVEL_MASK, level);
 431	writeq(data, mlxbf_rsh_scratch_buf_data);
 432
 433	/* Write message. */
 434	for (idx = 0; idx < num && size > 0; idx++) {
 435		if (size < sizeof(u64)) {
 436			data = 0;
 437			memcpy(&data, buf, size);
 438			size = 0;
 439		} else {
 440			memcpy(&data, buf, sizeof(u64));
 441			size -= sizeof(u64);
 442			buf += sizeof(u64);
 443		}
 444		writeq(data, mlxbf_rsh_scratch_buf_data);
 445	}
 446
 447done:
 448	/* Release the semaphore. */
 449	mlxbf_rsh_log_sem_unlock();
 450
 451	/* Ignore the rest if no more space. */
 452	return count;
 453}
 454
 455static ssize_t large_icm_show(struct device *dev,
 456				struct device_attribute *attr, char *buf)
 457{
 458	struct arm_smccc_res res;
 459
 460	mutex_lock(&icm_ops_lock);
 461	arm_smccc_smc(MLNX_HANDLE_GET_ICM_INFO, 0, 0, 0, 0,
 462		      0, 0, 0, &res);
 463	mutex_unlock(&icm_ops_lock);
 464	if (res.a0)
 465		return -EPERM;
 466
 467	return sysfs_emit(buf, "0x%lx", res.a1);
 468}
 469
 470static ssize_t large_icm_store(struct device *dev,
 471			       struct device_attribute *attr,
 472			       const char *buf, size_t count)
 473{
 474	struct arm_smccc_res res;
 475	unsigned long icm_data;
 476	int err;
 477
 478	err = kstrtoul(buf, MLXBF_LARGE_ICMC_MAX_STRING_SIZE, &icm_data);
 479	if (err)
 480		return err;
 481
 482	if ((icm_data != 0 && icm_data < MLXBF_LARGE_ICMC_SIZE_MIN) ||
 483	    icm_data > MLXBF_LARGE_ICMC_SIZE_MAX || icm_data % MLXBF_LARGE_ICMC_GRANULARITY)
 484		return -EPERM;
 485
 486	mutex_lock(&icm_ops_lock);
 487	arm_smccc_smc(MLNX_HANDLE_SET_ICM_INFO, icm_data, 0, 0, 0, 0, 0, 0, &res);
 488	mutex_unlock(&icm_ops_lock);
 489
 490	return res.a0 ? -EPERM : count;
 491}
 492
 493static ssize_t rtc_battery_show(struct device *dev,
 494				struct device_attribute *attr,
 495				char *buf)
 496{
 497	struct arm_smccc_res res;
 498
 499	mutex_lock(&rtc_ops_lock);
 500	arm_smccc_smc(MLNX_HANDLE_GET_RTC_LOW_BATT, 0, 0, 0, 0,
 501		      0, 0, 0, &res);
 502	mutex_unlock(&rtc_ops_lock);
 503
 504	if (res.a0)
 505		return -EPERM;
 506
 507	return sysfs_emit(buf, "0x%lx\n", res.a1);
 508}
 509
 510static ssize_t os_up_store(struct device *dev,
 511			   struct device_attribute *attr,
 512			   const char *buf, size_t count)
 513{
 514	struct arm_smccc_res res;
 515	unsigned long val;
 516	int err;
 517
 518	err = kstrtoul(buf, 10, &val);
 519	if (err)
 520		return err;
 521
 522	if (val != 1)
 523		return -EINVAL;
 524
 525	mutex_lock(&os_up_lock);
 526	arm_smccc_smc(MLNX_HANDLE_OS_UP, 0, 0, 0, 0, 0, 0, 0, &res);
 527	mutex_unlock(&os_up_lock);
 528
 529	return count;
 530}
 531
 532static ssize_t oob_mac_show(struct device *dev,
 533			    struct device_attribute *attr, char *buf)
 534{
 535	struct arm_smccc_res res;
 536	u8 *mac_byte_ptr;
 537
 538	mutex_lock(&mfg_ops_lock);
 539	arm_smccc_smc(MLXBF_BOOTCTL_GET_MFG_INFO, MLNX_MFG_TYPE_OOB_MAC, 0, 0, 0,
 540		      0, 0, 0, &res);
 541	mutex_unlock(&mfg_ops_lock);
 542	if (res.a0)
 543		return -EPERM;
 544
 545	mac_byte_ptr = (u8 *)&res.a1;
 546
 547	return sysfs_format_mac(buf, mac_byte_ptr, ETH_ALEN);
 548}
 549
 550static ssize_t oob_mac_store(struct device *dev,
 551			     struct device_attribute *attr,
 552			     const char *buf, size_t count)
 553{
 554	unsigned int byte[MLNX_MFG_OOB_MAC_FORMAT_LEN] = { 0 };
 555	struct arm_smccc_res res;
 556	int byte_idx, len;
 557	u64 mac_addr = 0;
 558	u8 *mac_byte_ptr;
 559
 560	if ((count - 1) != MLNX_MFG_OOB_MAC_FORMAT_LEN)
 561		return -EINVAL;
 562
 563	len = sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
 564		     &byte[0], &byte[1], &byte[2],
 565		     &byte[3], &byte[4], &byte[5]);
 566	if (len != ETH_ALEN)
 567		return -EINVAL;
 568
 569	mac_byte_ptr = (u8 *)&mac_addr;
 570
 571	for (byte_idx = 0; byte_idx < ETH_ALEN; byte_idx++)
 572		mac_byte_ptr[byte_idx] = (u8)byte[byte_idx];
 573
 574	mutex_lock(&mfg_ops_lock);
 575	arm_smccc_smc(MLXBF_BOOTCTL_SET_MFG_INFO, MLNX_MFG_TYPE_OOB_MAC,
 576		      ETH_ALEN, mac_addr, 0, 0, 0, 0, &res);
 577	mutex_unlock(&mfg_ops_lock);
 578
 579	return res.a0 ? -EPERM : count;
 580}
 581
 582static ssize_t opn_show(struct device *dev,
 583			struct device_attribute *attr, char *buf)
 584{
 585	u64 opn_data[MLNX_MFG_VAL_QWORD_CNT(OPN) + 1] = { 0 };
 586	struct arm_smccc_res res;
 587	int word;
 588
 589	mutex_lock(&mfg_ops_lock);
 590	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(OPN); word++) {
 591		arm_smccc_smc(MLXBF_BOOTCTL_GET_MFG_INFO,
 592			      MLNX_MFG_TYPE_OPN_0 + word,
 593			      0, 0, 0, 0, 0, 0, &res);
 594		if (res.a0) {
 595			mutex_unlock(&mfg_ops_lock);
 596			return -EPERM;
 597		}
 598		opn_data[word] = res.a1;
 599	}
 600	mutex_unlock(&mfg_ops_lock);
 601
 602	return sysfs_emit(buf, "%s", (char *)opn_data);
 603}
 604
 605static ssize_t opn_store(struct device *dev,
 606			 struct device_attribute *attr,
 607			 const char *buf, size_t count)
 608{
 609	u64 opn[MLNX_MFG_VAL_QWORD_CNT(OPN)] = { 0 };
 610	struct arm_smccc_res res;
 611	int word;
 612
 613	if (count > MLNX_MFG_OPN_VAL_LEN)
 614		return -EINVAL;
 615
 616	memcpy(opn, buf, count);
 617
 618	mutex_lock(&mfg_ops_lock);
 619	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(OPN); word++) {
 620		arm_smccc_smc(MLXBF_BOOTCTL_SET_MFG_INFO,
 621			      MLNX_MFG_TYPE_OPN_0 + word,
 622			      sizeof(u64), opn[word], 0, 0, 0, 0, &res);
 623		if (res.a0) {
 624			mutex_unlock(&mfg_ops_lock);
 625			return -EPERM;
 626		}
 627	}
 628	mutex_unlock(&mfg_ops_lock);
 629
 630	return count;
 631}
 632
 633static ssize_t sku_show(struct device *dev,
 634			struct device_attribute *attr, char *buf)
 635{
 636	u64 sku_data[MLNX_MFG_VAL_QWORD_CNT(SKU) + 1] = { 0 };
 637	struct arm_smccc_res res;
 638	int word;
 639
 640	mutex_lock(&mfg_ops_lock);
 641	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(SKU); word++) {
 642		arm_smccc_smc(MLXBF_BOOTCTL_GET_MFG_INFO,
 643			      MLNX_MFG_TYPE_SKU_0 + word,
 644			      0, 0, 0, 0, 0, 0, &res);
 645		if (res.a0) {
 646			mutex_unlock(&mfg_ops_lock);
 647			return -EPERM;
 648		}
 649		sku_data[word] = res.a1;
 650	}
 651	mutex_unlock(&mfg_ops_lock);
 652
 653	return sysfs_emit(buf, "%s", (char *)sku_data);
 654}
 655
 656static ssize_t sku_store(struct device *dev,
 657			 struct device_attribute *attr,
 658			 const char *buf, size_t count)
 659{
 660	u64 sku[MLNX_MFG_VAL_QWORD_CNT(SKU)] = { 0 };
 661	struct arm_smccc_res res;
 662	int word;
 663
 664	if (count > MLNX_MFG_SKU_VAL_LEN)
 665		return -EINVAL;
 666
 667	memcpy(sku, buf, count);
 668
 669	mutex_lock(&mfg_ops_lock);
 670	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(SKU); word++) {
 671		arm_smccc_smc(MLXBF_BOOTCTL_SET_MFG_INFO,
 672			      MLNX_MFG_TYPE_SKU_0 + word,
 673			      sizeof(u64), sku[word], 0, 0, 0, 0, &res);
 674		if (res.a0) {
 675			mutex_unlock(&mfg_ops_lock);
 676			return -EPERM;
 677		}
 678	}
 679	mutex_unlock(&mfg_ops_lock);
 680
 681	return count;
 682}
 683
 684static ssize_t modl_show(struct device *dev,
 685			 struct device_attribute *attr, char *buf)
 686{
 687	u64 modl_data[MLNX_MFG_VAL_QWORD_CNT(MODL) + 1] = { 0 };
 688	struct arm_smccc_res res;
 689	int word;
 690
 691	mutex_lock(&mfg_ops_lock);
 692	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(MODL); word++) {
 693		arm_smccc_smc(MLXBF_BOOTCTL_GET_MFG_INFO,
 694			      MLNX_MFG_TYPE_MODL_0 + word,
 695			      0, 0, 0, 0, 0, 0, &res);
 696		if (res.a0) {
 697			mutex_unlock(&mfg_ops_lock);
 698			return -EPERM;
 699		}
 700		modl_data[word] = res.a1;
 701	}
 702	mutex_unlock(&mfg_ops_lock);
 703
 704	return sysfs_emit(buf, "%s", (char *)modl_data);
 705}
 706
 707static ssize_t modl_store(struct device *dev,
 708			  struct device_attribute *attr,
 709			  const char *buf, size_t count)
 710{
 711	u64 modl[MLNX_MFG_VAL_QWORD_CNT(MODL)] = { 0 };
 712	struct arm_smccc_res res;
 713	int word;
 714
 715	if (count > MLNX_MFG_MODL_VAL_LEN)
 716		return -EINVAL;
 717
 718	memcpy(modl, buf, count);
 719
 720	mutex_lock(&mfg_ops_lock);
 721	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(MODL); word++) {
 722		arm_smccc_smc(MLXBF_BOOTCTL_SET_MFG_INFO,
 723			      MLNX_MFG_TYPE_MODL_0 + word,
 724			      sizeof(u64), modl[word], 0, 0, 0, 0, &res);
 725		if (res.a0) {
 726			mutex_unlock(&mfg_ops_lock);
 727			return -EPERM;
 728		}
 729	}
 730	mutex_unlock(&mfg_ops_lock);
 731
 732	return count;
 733}
 734
 735static ssize_t sn_show(struct device *dev,
 736		       struct device_attribute *attr, char *buf)
 737{
 738	u64 sn_data[MLNX_MFG_VAL_QWORD_CNT(SN) + 1] = { 0 };
 739	struct arm_smccc_res res;
 740	int word;
 741
 742	mutex_lock(&mfg_ops_lock);
 743	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(SN); word++) {
 744		arm_smccc_smc(MLXBF_BOOTCTL_GET_MFG_INFO,
 745			      MLNX_MFG_TYPE_SN_0 + word,
 746			      0, 0, 0, 0, 0, 0, &res);
 747		if (res.a0) {
 748			mutex_unlock(&mfg_ops_lock);
 749			return -EPERM;
 750		}
 751		sn_data[word] = res.a1;
 752	}
 753	mutex_unlock(&mfg_ops_lock);
 754
 755	return sysfs_emit(buf, "%s", (char *)sn_data);
 756}
 757
 758static ssize_t sn_store(struct device *dev,
 759			struct device_attribute *attr,
 760			const char *buf, size_t count)
 761{
 762	u64 sn[MLNX_MFG_VAL_QWORD_CNT(SN)] = { 0 };
 763	struct arm_smccc_res res;
 764	int word;
 765
 766	if (count > MLNX_MFG_SN_VAL_LEN)
 767		return -EINVAL;
 768
 769	memcpy(sn, buf, count);
 770
 771	mutex_lock(&mfg_ops_lock);
 772	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(SN); word++) {
 773		arm_smccc_smc(MLXBF_BOOTCTL_SET_MFG_INFO,
 774			      MLNX_MFG_TYPE_SN_0 + word,
 775			      sizeof(u64), sn[word], 0, 0, 0, 0, &res);
 776		if (res.a0) {
 777			mutex_unlock(&mfg_ops_lock);
 778			return -EPERM;
 779		}
 780	}
 781	mutex_unlock(&mfg_ops_lock);
 782
 783	return count;
 784}
 785
 786static ssize_t uuid_show(struct device *dev,
 787			 struct device_attribute *attr, char *buf)
 788{
 789	u64 uuid_data[MLNX_MFG_VAL_QWORD_CNT(UUID) + 1] = { 0 };
 790	struct arm_smccc_res res;
 791	int word;
 792
 793	mutex_lock(&mfg_ops_lock);
 794	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(UUID); word++) {
 795		arm_smccc_smc(MLXBF_BOOTCTL_GET_MFG_INFO,
 796			      MLNX_MFG_TYPE_UUID_0 + word,
 797			      0, 0, 0, 0, 0, 0, &res);
 798		if (res.a0) {
 799			mutex_unlock(&mfg_ops_lock);
 800			return -EPERM;
 801		}
 802		uuid_data[word] = res.a1;
 803	}
 804	mutex_unlock(&mfg_ops_lock);
 805
 806	return sysfs_emit(buf, "%s", (char *)uuid_data);
 807}
 808
 809static ssize_t uuid_store(struct device *dev,
 810			  struct device_attribute *attr,
 811			  const char *buf, size_t count)
 812{
 813	u64 uuid[MLNX_MFG_VAL_QWORD_CNT(UUID)] = { 0 };
 814	struct arm_smccc_res res;
 815	int word;
 816
 817	if (count > MLNX_MFG_UUID_VAL_LEN)
 818		return -EINVAL;
 819
 820	memcpy(uuid, buf, count);
 821
 822	mutex_lock(&mfg_ops_lock);
 823	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(UUID); word++) {
 824		arm_smccc_smc(MLXBF_BOOTCTL_SET_MFG_INFO,
 825			      MLNX_MFG_TYPE_UUID_0 + word,
 826			      sizeof(u64), uuid[word], 0, 0, 0, 0, &res);
 827		if (res.a0) {
 828			mutex_unlock(&mfg_ops_lock);
 829			return -EPERM;
 830		}
 831	}
 832	mutex_unlock(&mfg_ops_lock);
 833
 834	return count;
 835}
 836
 837static ssize_t rev_show(struct device *dev,
 838			struct device_attribute *attr, char *buf)
 839{
 840	u64 rev_data[MLNX_MFG_VAL_QWORD_CNT(REV) + 1] = { 0 };
 841	struct arm_smccc_res res;
 842	int word;
 843
 844	mutex_lock(&mfg_ops_lock);
 845	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(REV); word++) {
 846		arm_smccc_smc(MLXBF_BOOTCTL_GET_MFG_INFO,
 847			      MLNX_MFG_TYPE_REV + word,
 848			      0, 0, 0, 0, 0, 0, &res);
 849		if (res.a0) {
 850			mutex_unlock(&mfg_ops_lock);
 851			return -EPERM;
 852		}
 853		rev_data[word] = res.a1;
 854	}
 855	mutex_unlock(&mfg_ops_lock);
 856
 857	return sysfs_emit(buf, "%s", (char *)rev_data);
 858}
 859
 860static ssize_t rev_store(struct device *dev,
 861			 struct device_attribute *attr,
 862			 const char *buf, size_t count)
 863{
 864	u64 rev[MLNX_MFG_VAL_QWORD_CNT(REV)] = { 0 };
 865	struct arm_smccc_res res;
 866	int word;
 867
 868	if (count > MLNX_MFG_REV_VAL_LEN)
 869		return -EINVAL;
 870
 871	memcpy(rev, buf, count);
 872
 873	mutex_lock(&mfg_ops_lock);
 874	for (word = 0; word < MLNX_MFG_VAL_QWORD_CNT(REV); word++) {
 875		arm_smccc_smc(MLXBF_BOOTCTL_SET_MFG_INFO,
 876			      MLNX_MFG_TYPE_REV + word,
 877			      sizeof(u64), rev[word], 0, 0, 0, 0, &res);
 878		if (res.a0) {
 879			mutex_unlock(&mfg_ops_lock);
 880			return -EPERM;
 881		}
 882	}
 883	mutex_unlock(&mfg_ops_lock);
 884
 885	return count;
 886}
 887
 888static ssize_t mfg_lock_store(struct device *dev,
 889			      struct device_attribute *attr,
 890			      const char *buf, size_t count)
 891{
 892	struct arm_smccc_res res;
 893	unsigned long val;
 894	int err;
 895
 896	err = kstrtoul(buf, 10, &val);
 897	if (err)
 898		return err;
 899
 900	if (val != 1)
 901		return -EINVAL;
 902
 903	mutex_lock(&mfg_ops_lock);
 904	arm_smccc_smc(MLXBF_BOOTCTL_LOCK_MFG_INFO, 0, 0, 0, 0, 0, 0, 0, &res);
 905	mutex_unlock(&mfg_ops_lock);
 906
 907	return count;
 908}
 909
 910static DEVICE_ATTR_RW(post_reset_wdog);
 911static DEVICE_ATTR_RW(reset_action);
 912static DEVICE_ATTR_RW(second_reset_action);
 913static DEVICE_ATTR_RO(lifecycle_state);
 914static DEVICE_ATTR_RO(secure_boot_fuse_state);
 915static DEVICE_ATTR_WO(fw_reset);
 916static DEVICE_ATTR_WO(rsh_log);
 917static DEVICE_ATTR_RW(large_icm);
 918static DEVICE_ATTR_WO(os_up);
 919static DEVICE_ATTR_RW(oob_mac);
 920static DEVICE_ATTR_RW(opn);
 921static DEVICE_ATTR_RW(sku);
 922static DEVICE_ATTR_RW(modl);
 923static DEVICE_ATTR_RW(sn);
 924static DEVICE_ATTR_RW(uuid);
 925static DEVICE_ATTR_RW(rev);
 926static DEVICE_ATTR_WO(mfg_lock);
 927static DEVICE_ATTR_RO(rtc_battery);
 928
 929static struct attribute *mlxbf_bootctl_attrs[] = {
 930	&dev_attr_post_reset_wdog.attr,
 931	&dev_attr_reset_action.attr,
 932	&dev_attr_second_reset_action.attr,
 933	&dev_attr_lifecycle_state.attr,
 934	&dev_attr_secure_boot_fuse_state.attr,
 935	&dev_attr_fw_reset.attr,
 936	&dev_attr_rsh_log.attr,
 937	&dev_attr_large_icm.attr,
 938	&dev_attr_os_up.attr,
 939	&dev_attr_oob_mac.attr,
 940	&dev_attr_opn.attr,
 941	&dev_attr_sku.attr,
 942	&dev_attr_modl.attr,
 943	&dev_attr_sn.attr,
 944	&dev_attr_uuid.attr,
 945	&dev_attr_rev.attr,
 946	&dev_attr_mfg_lock.attr,
 947	&dev_attr_rtc_battery.attr,
 948	NULL
 949};
 950
 951ATTRIBUTE_GROUPS(mlxbf_bootctl);
 952
 953static const struct acpi_device_id mlxbf_bootctl_acpi_ids[] = {
 954	{"MLNXBF04", 0},
 955	{}
 956};
 957
 958MODULE_DEVICE_TABLE(acpi, mlxbf_bootctl_acpi_ids);
 959
 960static ssize_t mlxbf_bootctl_bootfifo_read(struct file *filp,
 961					   struct kobject *kobj,
 962					   const struct bin_attribute *bin_attr,
 963					   char *buf, loff_t pos,
 964					   size_t count)
 965{
 966	unsigned long timeout = msecs_to_jiffies(500);
 967	unsigned long expire = jiffies + timeout;
 968	u64 data, cnt = 0;
 969	char *p = buf;
 970
 971	while (count >= sizeof(data)) {
 972		/* Give up reading if no more data within 500ms. */
 973		if (!cnt) {
 974			cnt = readq(mlxbf_rsh_boot_cnt);
 975			if (!cnt) {
 976				if (time_after(jiffies, expire))
 977					break;
 978				usleep_range(10, 50);
 979				continue;
 980			}
 981		}
 982
 983		data = readq(mlxbf_rsh_boot_data);
 984		memcpy(p, &data, sizeof(data));
 985		count -= sizeof(data);
 986		p += sizeof(data);
 987		cnt--;
 988		expire = jiffies + timeout;
 989	}
 990
 991	return p - buf;
 992}
 993
 994static const struct bin_attribute mlxbf_bootctl_bootfifo_sysfs_attr = {
 995	.attr = { .name = "bootfifo", .mode = 0400 },
 996	.read = mlxbf_bootctl_bootfifo_read,
 997};
 998
 999static bool mlxbf_bootctl_guid_match(const guid_t *guid,
1000				     const struct arm_smccc_res *res)
1001{
1002	guid_t id = GUID_INIT(res->a0, res->a1, res->a1 >> 16,
1003			      res->a2, res->a2 >> 8, res->a2 >> 16,
1004			      res->a2 >> 24, res->a3, res->a3 >> 8,
1005			      res->a3 >> 16, res->a3 >> 24);
1006
1007	return guid_equal(guid, &id);
1008}
1009
1010static int mlxbf_bootctl_probe(struct platform_device *pdev)
1011{
1012	struct arm_smccc_res res = { 0 };
1013	void __iomem *reg;
1014	guid_t guid;
1015	int ret;
1016
1017	/* Map the resource of the bootfifo data register. */
1018	mlxbf_rsh_boot_data = devm_platform_ioremap_resource(pdev, 0);
1019	if (IS_ERR(mlxbf_rsh_boot_data))
1020		return PTR_ERR(mlxbf_rsh_boot_data);
1021
1022	/* Map the resource of the bootfifo counter register. */
1023	mlxbf_rsh_boot_cnt = devm_platform_ioremap_resource(pdev, 1);
1024	if (IS_ERR(mlxbf_rsh_boot_cnt))
1025		return PTR_ERR(mlxbf_rsh_boot_cnt);
1026
1027	/* Map the resource of the rshim semaphore register. */
1028	mlxbf_rsh_semaphore = devm_platform_ioremap_resource(pdev, 2);
1029	if (IS_ERR(mlxbf_rsh_semaphore))
1030		return PTR_ERR(mlxbf_rsh_semaphore);
1031
1032	/* Map the resource of the scratch buffer (log) registers. */
1033	reg = devm_platform_ioremap_resource(pdev, 3);
1034	if (IS_ERR(reg))
1035		return PTR_ERR(reg);
1036	mlxbf_rsh_scratch_buf_ctl = reg + MLXBF_RSH_SCRATCH_BUF_CTL_OFF;
1037	mlxbf_rsh_scratch_buf_data = reg + MLXBF_RSH_SCRATCH_BUF_DATA_OFF;
1038
1039	/* Ensure we have the UUID we expect for this service. */
1040	arm_smccc_smc(MLXBF_BOOTCTL_SIP_SVC_UID, 0, 0, 0, 0, 0, 0, 0, &res);
1041	guid_parse(mlxbf_bootctl_svc_uuid_str, &guid);
1042	if (!mlxbf_bootctl_guid_match(&guid, &res))
1043		return -ENODEV;
1044
1045	/*
1046	 * When watchdog is used, it sets boot mode to MLXBF_BOOTCTL_SWAP_EMMC
1047	 * in case of boot failures. However it doesn't clear the state if there
1048	 * is no failure. Restore the default boot mode here to avoid any
1049	 * unnecessary boot partition swapping.
1050	 */
1051	ret = mlxbf_bootctl_smc(MLXBF_BOOTCTL_SET_RESET_ACTION,
1052				MLXBF_BOOTCTL_EMMC);
1053	if (ret < 0)
1054		dev_warn(&pdev->dev, "Unable to reset the EMMC boot mode\n");
1055
1056	ret = sysfs_create_bin_file(&pdev->dev.kobj,
1057				    &mlxbf_bootctl_bootfifo_sysfs_attr);
1058	if (ret)
1059		pr_err("Unable to create bootfifo sysfs file, error %d\n", ret);
1060
1061	return ret;
1062}
1063
1064static void mlxbf_bootctl_remove(struct platform_device *pdev)
1065{
1066	sysfs_remove_bin_file(&pdev->dev.kobj,
1067			      &mlxbf_bootctl_bootfifo_sysfs_attr);
1068}
1069
1070static struct platform_driver mlxbf_bootctl_driver = {
1071	.probe = mlxbf_bootctl_probe,
1072	.remove = mlxbf_bootctl_remove,
1073	.driver = {
1074		.name = "mlxbf-bootctl",
1075		.dev_groups = mlxbf_bootctl_groups,
1076		.acpi_match_table = mlxbf_bootctl_acpi_ids,
1077	}
1078};
1079
1080module_platform_driver(mlxbf_bootctl_driver);
1081
1082MODULE_DESCRIPTION("Mellanox boot control driver");
1083MODULE_LICENSE("GPL v2");
1084MODULE_AUTHOR("Mellanox Technologies");
~/ Read-only file preview.