Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Mellanox boot control driver
0004  *
0005  * This driver provides a sysfs interface for systems management
0006  * software to manage reset-time actions.
0007  *
0008  * Copyright (C) 2019 Mellanox Technologies
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 /* UUID used to probe ATF service. */
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 /* ARM SMC call which is atomic and no need for lock. */
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 /* Return the action in integer or an error code. */
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 /* Return the action in string. */
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      * If the test bits are set, we specify that the current state may be
0180      * due to using the test bits.
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      * key_state contains the bits for 4 Key versions, loaded from eFuses
0206      * after a hard reset. Lower 4 bits are a thermometer code indicating
0207      * key programming has started for key n (0000 = none, 0001 = version 0,
0208      * 0011 = version 1, 0111 = version 2, 1111 = version 3). Upper 4 bits
0209      * are a thermometer code indicating key programming has completed for
0210      * key n (same encodings as the start bits). This allows for detection
0211      * of an interruption in the programming process which has left the key
0212      * partially programmed (and thus invalid). The process is to burn the
0213      * eFuse for the new key start bit, burn the key eFuses, then burn the
0214      * eFuse for the new key complete bit.
0215      *
0216      * For example 0000_0000: no key valid, 0001_0001: key version 0 valid,
0217      * 0011_0011: key 1 version valid, 0011_0111: key version 2 started
0218      * programming but did not complete, etc. The most recent key for which
0219      * both start and complete bit is set is loaded. On soft reset, this
0220      * register is not modified.
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     /* Ensure we have the UUID we expect for this service. */
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      * When watchdog is used, it sets boot mode to MLXBF_BOOTCTL_SWAP_EMMC
0296      * in case of boot failures. However it doesn't clear the state if there
0297      * is no failure. Restore the default boot mode here to avoid any
0298      * unnecessary boot partition swapping.
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");