0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/acpi.h>
0012 #include <linux/arm-smccc.h>
0013 #include <linux/module.h>
0014 #include <linux/platform_device.h>
0015
0016 #include "mlxbf-bootctl.h"
0017
0018 #define MLXBF_BOOTCTL_SB_SECURE_MASK 0x03
0019 #define MLXBF_BOOTCTL_SB_TEST_MASK 0x0c
0020
0021 #define MLXBF_SB_KEY_NUM 4
0022
0023
0024 static const char *mlxbf_bootctl_svc_uuid_str =
0025 "89c036b4-e7d7-11e6-8797-001aca00bfc4";
0026
0027 struct mlxbf_bootctl_name {
0028 u32 value;
0029 const char *name;
0030 };
0031
0032 static struct mlxbf_bootctl_name boot_names[] = {
0033 { MLXBF_BOOTCTL_EXTERNAL, "external" },
0034 { MLXBF_BOOTCTL_EMMC, "emmc" },
0035 { MLNX_BOOTCTL_SWAP_EMMC, "swap_emmc" },
0036 { MLXBF_BOOTCTL_EMMC_LEGACY, "emmc_legacy" },
0037 { MLXBF_BOOTCTL_NONE, "none" },
0038 };
0039
0040 static const char * const mlxbf_bootctl_lifecycle_states[] = {
0041 [0] = "Production",
0042 [1] = "GA Secured",
0043 [2] = "GA Non-Secured",
0044 [3] = "RMA",
0045 };
0046
0047
0048 static int mlxbf_bootctl_smc(unsigned int smc_op, int smc_arg)
0049 {
0050 struct arm_smccc_res res;
0051
0052 arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, &res);
0053
0054 return res.a0;
0055 }
0056
0057
0058 static int mlxbf_bootctl_reset_action_to_val(const char *action)
0059 {
0060 int i;
0061
0062 for (i = 0; i < ARRAY_SIZE(boot_names); i++)
0063 if (sysfs_streq(boot_names[i].name, action))
0064 return boot_names[i].value;
0065
0066 return -EINVAL;
0067 }
0068
0069
0070 static const char *mlxbf_bootctl_action_to_string(int action)
0071 {
0072 int i;
0073
0074 for (i = 0; i < ARRAY_SIZE(boot_names); i++)
0075 if (boot_names[i].value == action)
0076 return boot_names[i].name;
0077
0078 return "invalid action";
0079 }
0080
0081 static ssize_t post_reset_wdog_show(struct device *dev,
0082 struct device_attribute *attr, char *buf)
0083 {
0084 int ret;
0085
0086 ret = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_POST_RESET_WDOG, 0);
0087 if (ret < 0)
0088 return ret;
0089
0090 return sprintf(buf, "%d\n", ret);
0091 }
0092
0093 static ssize_t post_reset_wdog_store(struct device *dev,
0094 struct device_attribute *attr,
0095 const char *buf, size_t count)
0096 {
0097 unsigned long value;
0098 int ret;
0099
0100 ret = kstrtoul(buf, 10, &value);
0101 if (ret)
0102 return ret;
0103
0104 ret = mlxbf_bootctl_smc(MLXBF_BOOTCTL_SET_POST_RESET_WDOG, value);
0105 if (ret < 0)
0106 return ret;
0107
0108 return count;
0109 }
0110
0111 static ssize_t mlxbf_bootctl_show(int smc_op, char *buf)
0112 {
0113 int action;
0114
0115 action = mlxbf_bootctl_smc(smc_op, 0);
0116 if (action < 0)
0117 return action;
0118
0119 return sprintf(buf, "%s\n", mlxbf_bootctl_action_to_string(action));
0120 }
0121
0122 static int mlxbf_bootctl_store(int smc_op, const char *buf, size_t count)
0123 {
0124 int ret, action;
0125
0126 action = mlxbf_bootctl_reset_action_to_val(buf);
0127 if (action < 0)
0128 return action;
0129
0130 ret = mlxbf_bootctl_smc(smc_op, action);
0131 if (ret < 0)
0132 return ret;
0133
0134 return count;
0135 }
0136
0137 static ssize_t reset_action_show(struct device *dev,
0138 struct device_attribute *attr, char *buf)
0139 {
0140 return mlxbf_bootctl_show(MLXBF_BOOTCTL_GET_RESET_ACTION, buf);
0141 }
0142
0143 static ssize_t reset_action_store(struct device *dev,
0144 struct device_attribute *attr,
0145 const char *buf, size_t count)
0146 {
0147 return mlxbf_bootctl_store(MLXBF_BOOTCTL_SET_RESET_ACTION, buf, count);
0148 }
0149
0150 static ssize_t second_reset_action_show(struct device *dev,
0151 struct device_attribute *attr,
0152 char *buf)
0153 {
0154 return mlxbf_bootctl_show(MLXBF_BOOTCTL_GET_SECOND_RESET_ACTION, buf);
0155 }
0156
0157 static ssize_t second_reset_action_store(struct device *dev,
0158 struct device_attribute *attr,
0159 const char *buf, size_t count)
0160 {
0161 return mlxbf_bootctl_store(MLXBF_BOOTCTL_SET_SECOND_RESET_ACTION, buf,
0162 count);
0163 }
0164
0165 static ssize_t lifecycle_state_show(struct device *dev,
0166 struct device_attribute *attr, char *buf)
0167 {
0168 int lc_state;
0169
0170 lc_state = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
0171 MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE);
0172 if (lc_state < 0)
0173 return lc_state;
0174
0175 lc_state &=
0176 MLXBF_BOOTCTL_SB_TEST_MASK | MLXBF_BOOTCTL_SB_SECURE_MASK;
0177
0178
0179
0180
0181
0182 if (lc_state & MLXBF_BOOTCTL_SB_TEST_MASK) {
0183 lc_state &= MLXBF_BOOTCTL_SB_SECURE_MASK;
0184
0185 return sprintf(buf, "%s(test)\n",
0186 mlxbf_bootctl_lifecycle_states[lc_state]);
0187 }
0188
0189 return sprintf(buf, "%s\n", mlxbf_bootctl_lifecycle_states[lc_state]);
0190 }
0191
0192 static ssize_t secure_boot_fuse_state_show(struct device *dev,
0193 struct device_attribute *attr,
0194 char *buf)
0195 {
0196 int burnt, valid, key, key_state, buf_len = 0, upper_key_used = 0;
0197 const char *status;
0198
0199 key_state = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
0200 MLXBF_BOOTCTL_FUSE_STATUS_KEYS);
0201 if (key_state < 0)
0202 return key_state;
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 for (key = MLXBF_SB_KEY_NUM - 1; key >= 0; key--) {
0223 burnt = key_state & BIT(key);
0224 valid = key_state & BIT(key + MLXBF_SB_KEY_NUM);
0225
0226 if (burnt && valid)
0227 upper_key_used = 1;
0228
0229 if (upper_key_used) {
0230 if (burnt)
0231 status = valid ? "Used" : "Wasted";
0232 else
0233 status = valid ? "Invalid" : "Skipped";
0234 } else {
0235 if (burnt)
0236 status = valid ? "InUse" : "Incomplete";
0237 else
0238 status = valid ? "Invalid" : "Free";
0239 }
0240 buf_len += sprintf(buf + buf_len, "%d:%s ", key, status);
0241 }
0242 buf_len += sprintf(buf + buf_len, "\n");
0243
0244 return buf_len;
0245 }
0246
0247 static DEVICE_ATTR_RW(post_reset_wdog);
0248 static DEVICE_ATTR_RW(reset_action);
0249 static DEVICE_ATTR_RW(second_reset_action);
0250 static DEVICE_ATTR_RO(lifecycle_state);
0251 static DEVICE_ATTR_RO(secure_boot_fuse_state);
0252
0253 static struct attribute *mlxbf_bootctl_attrs[] = {
0254 &dev_attr_post_reset_wdog.attr,
0255 &dev_attr_reset_action.attr,
0256 &dev_attr_second_reset_action.attr,
0257 &dev_attr_lifecycle_state.attr,
0258 &dev_attr_secure_boot_fuse_state.attr,
0259 NULL
0260 };
0261
0262 ATTRIBUTE_GROUPS(mlxbf_bootctl);
0263
0264 static const struct acpi_device_id mlxbf_bootctl_acpi_ids[] = {
0265 {"MLNXBF04", 0},
0266 {}
0267 };
0268
0269 MODULE_DEVICE_TABLE(acpi, mlxbf_bootctl_acpi_ids);
0270
0271 static bool mlxbf_bootctl_guid_match(const guid_t *guid,
0272 const struct arm_smccc_res *res)
0273 {
0274 guid_t id = GUID_INIT(res->a0, res->a1, res->a1 >> 16,
0275 res->a2, res->a2 >> 8, res->a2 >> 16,
0276 res->a2 >> 24, res->a3, res->a3 >> 8,
0277 res->a3 >> 16, res->a3 >> 24);
0278
0279 return guid_equal(guid, &id);
0280 }
0281
0282 static int mlxbf_bootctl_probe(struct platform_device *pdev)
0283 {
0284 struct arm_smccc_res res = { 0 };
0285 guid_t guid;
0286 int ret;
0287
0288
0289 arm_smccc_smc(MLXBF_BOOTCTL_SIP_SVC_UID, 0, 0, 0, 0, 0, 0, 0, &res);
0290 guid_parse(mlxbf_bootctl_svc_uuid_str, &guid);
0291 if (!mlxbf_bootctl_guid_match(&guid, &res))
0292 return -ENODEV;
0293
0294
0295
0296
0297
0298
0299
0300 ret = mlxbf_bootctl_smc(MLXBF_BOOTCTL_SET_RESET_ACTION,
0301 MLXBF_BOOTCTL_EMMC);
0302 if (ret < 0)
0303 dev_warn(&pdev->dev, "Unable to reset the EMMC boot mode\n");
0304
0305 return 0;
0306 }
0307
0308 static struct platform_driver mlxbf_bootctl_driver = {
0309 .probe = mlxbf_bootctl_probe,
0310 .driver = {
0311 .name = "mlxbf-bootctl",
0312 .dev_groups = mlxbf_bootctl_groups,
0313 .acpi_match_table = mlxbf_bootctl_acpi_ids,
0314 }
0315 };
0316
0317 module_platform_driver(mlxbf_bootctl_driver);
0318
0319 MODULE_DESCRIPTION("Mellanox boot control driver");
0320 MODULE_LICENSE("GPL v2");
0321 MODULE_AUTHOR("Mellanox Technologies");