History

tpm_crb: Add idle support for the Arm FF-A start method

According to the CRB over FF-A specification [1], a TPM that implements the ABI must comply with the TCG PTP specification. This requires support for the Idle and Ready states. This patch implements CRB control area requests for goIdle and cmdReady on FF-A based TPMs. The FF-A message used to notify the TPM of CRB updates includes a locality parameter, which provides a hint to the TPM about which locality modified the CRB. This patch adds a locality parameter to __crb_go_idle() and __crb_cmd_ready() to support this. [1] https://developer.arm.com/documentation/den0138/latest/

Stuart Yoder committed 1 year ago

Commit dbfdaeb1 parent f4060551 file · +20 −9Browse files

Unified · Split

drivers/char/tpm/tpm_crb.c+20−9
@@ -133,8 +133,7 @@ static inline bool tpm_crb_has_idle(u32 start_method) · 132 unmodified lines
133{133{
134 return !(start_method == ACPI_TPM2_START_METHOD ||134 return !(start_method == ACPI_TPM2_START_METHOD ||
135 start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD ||135 start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD ||
136 start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC ||136 start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC);
137 start_method == ACPI_TPM2_CRB_WITH_ARM_FFA);
138}137}
139 138
140static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,139static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
@@ -191,7 +190,7 @@ static int crb_try_pluton_doorbell(struct crb_priv *priv, bool wait_for_complete · 50 unmodified lines
191 *190 *
192 * Return: 0 always191 * Return: 0 always
193 */192 */
194static int __crb_go_idle(struct device *dev, struct crb_priv *priv)193static int __crb_go_idle(struct device *dev, struct crb_priv *priv, int loc)
195{194{
196 int rc;195 int rc;
197 196
@@ -200,6 +199,12 @@ static int __crb_go_idle(struct device *dev, struct crb_priv *priv) · 2 unmodified lines
200 199
201 iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);200 iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
202 201
202 if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) {
203 rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, loc);
204 if (rc)
205 return rc;
206 }
207
203 rc = crb_try_pluton_doorbell(priv, true);208 rc = crb_try_pluton_doorbell(priv, true);
204 if (rc)209 if (rc)
205 return rc;210 return rc;
@@ -220,7 +225,7 @@ static int crb_go_idle(struct tpm_chip *chip) · 14 unmodified lines
220 struct device *dev = &chip->dev;225 struct device *dev = &chip->dev;
221 struct crb_priv *priv = dev_get_drvdata(dev);226 struct crb_priv *priv = dev_get_drvdata(dev);
222 227
223 return __crb_go_idle(dev, priv);228 return __crb_go_idle(dev, priv, chip->locality);
224}229}
225 230
226/**231/**
@@ -238,7 +243,7 @@ static int crb_go_idle(struct tpm_chip *chip) · 11 unmodified lines
238 *243 *
239 * Return: 0 on success -ETIME on timeout;244 * Return: 0 on success -ETIME on timeout;
240 */245 */
241static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv)246static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv, int loc)
242{247{
243 int rc;248 int rc;
244 249
@@ -247,6 +252,12 @@ static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv) · 2 unmodified lines
247 252
248 iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);253 iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
249 254
255 if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) {
256 rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, loc);
257 if (rc)
258 return rc;
259 }
260
250 rc = crb_try_pluton_doorbell(priv, true);261 rc = crb_try_pluton_doorbell(priv, true);
251 if (rc)262 if (rc)
252 return rc;263 return rc;
@@ -267,7 +278,7 @@ static int crb_cmd_ready(struct tpm_chip *chip) · 14 unmodified lines
267 struct device *dev = &chip->dev;278 struct device *dev = &chip->dev;
268 struct crb_priv *priv = dev_get_drvdata(dev);279 struct crb_priv *priv = dev_get_drvdata(dev);
269 280
270 return __crb_cmd_ready(dev, priv);281 return __crb_cmd_ready(dev, priv, chip->locality);
271}282}
272 283
273static int __crb_request_locality(struct device *dev,284static int __crb_request_locality(struct device *dev,
@@ -444,7 +455,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len) · 170 unmodified lines
444 455
445 /* Seems to be necessary for every command */456 /* Seems to be necessary for every command */
446 if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON)457 if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON)
447 __crb_cmd_ready(&chip->dev, priv);458 __crb_cmd_ready(&chip->dev, priv, chip->locality);
448 459
449 memcpy_toio(priv->cmd, buf, len);460 memcpy_toio(priv->cmd, buf, len);
450 461
@@ -672,7 +683,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, · 221 unmodified lines
672 * PTT HW bug w/a: wake up the device to access683 * PTT HW bug w/a: wake up the device to access
673 * possibly not retained registers.684 * possibly not retained registers.
674 */685 */
675 ret = __crb_cmd_ready(dev, priv);686 ret = __crb_cmd_ready(dev, priv, 0);
676 if (ret)687 if (ret)
677 goto out_relinquish_locality;688 goto out_relinquish_locality;
678 689
@@ -744,7 +755,7 @@ out: · 65 unmodified lines
744 if (!ret)755 if (!ret)
745 priv->cmd_size = cmd_size;756 priv->cmd_size = cmd_size;
746 757
747 __crb_go_idle(dev, priv);758 __crb_go_idle(dev, priv, 0);
748 759
749out_relinquish_locality:760out_relinquish_locality:
750 761