[coreboot-gerrit] Change in coreboot[master]: cr50: add marshaling/unmarshaling of vendor commands and pro...
Vadim Bendebury (Code Review)
gerrit at coreboot.org
Thu Mar 23 00:12:15 CET 2017
Vadim Bendebury has uploaded a new change for review. ( https://review.coreboot.org/18945 )
Change subject: cr50: add marshaling/unmarshaling of vendor commands and process turn_on
......................................................................
cr50: add marshaling/unmarshaling of vendor commands and process turn_on
The upcoming CR50 firmware changes will require the AP to turn on the
previously downloaded CR50 firmware updates. A new vendor command
(TPM2_CR50_SUB_CMD_TURN_UPDATE_ON) is used for that. The command
accepts one parameter - the timeout before CR50 resets the system in
case there was an enabled update. The command also returns a value,
which indicates to the host if the update was turned on and the reboot
is coming.
This patch also adds more formal vendor command
marshaling/unmarshaling to make future additions easier.
BRANCH=gru,reef
BUG=b:35580805
TEST=with the actual user of this code in the next patch verified that
the cr50 update is enabled as expected.
Change-Id: Ic76d384d637c0eeaad206e0a8242cbb8e2b19b37
Signed-off-by: Vadim Bendebury <vbendeb at chromium.org>
---
M src/include/tpm_lite/tlcl.h
M src/lib/tpm2_marshaling.c
M src/lib/tpm2_tlcl.c
M src/lib/tpm2_tlcl_structures.h
4 files changed, 82 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/45/18945/1
diff --git a/src/include/tpm_lite/tlcl.h b/src/include/tpm_lite/tlcl.h
index c8e68d2..c5951c7 100644
--- a/src/include/tpm_lite/tlcl.h
+++ b/src/include/tpm_lite/tlcl.h
@@ -162,4 +162,13 @@
*/
uint32_t tlcl_cr50_enable_nvcommits(void);
+/**
+ * CR50 specific tpm command to restore header(s) of the dormant RO/RW
+ * image(s) and in case there indeed was a dormant image, trigger reboot after
+ * the timeout milliseconds.
+ *
+ * Returns nonzero value in reset_pending if there were restored header(s).
+ */
+uint32_t tlcl_cr50_turn_update_on(uint16_t timeout_ms, uint8_t *reset_pending);
+
#endif /* TPM_LITE_TLCL_H_ */
diff --git a/src/lib/tpm2_marshaling.c b/src/lib/tpm2_marshaling.c
index 6d4d622..e606868 100644
--- a/src/lib/tpm2_marshaling.c
+++ b/src/lib/tpm2_marshaling.c
@@ -408,6 +408,10 @@
case TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS:
marshal_u16(buffer, *sub_command, buffer_space);
break;
+ case TPM2_CR50_SUB_CMD_TURN_UPDATE_ON:
+ marshal_u16(buffer, sub_command[0], buffer_space);
+ marshal_u16(buffer, sub_command[1], buffer_space);
+ break;
default:
/* Unsupported subcommand. */
printk(BIOS_WARNING, "Unsupported cr50 subcommand: 0x%04x\n",
@@ -596,6 +600,39 @@
*size = 0;
}
+static void unmarshal_vendor_command(void **buffer, int *size,
+ struct vc_response *vcr)
+{
+ vcr->vc_subcommand = unmarshal_u16(buffer, size);
+ if (size < 0) {
+ printk(BIOS_ERR,
+ "%s:%d - truncated vendor command response!\n",
+ __func__, __LINE__);
+ return;
+ }
+
+ switch(vcr->vc_subcommand) {
+ case TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS:
+ break;
+ case TPM2_CR50_SUB_CMD_TURN_UPDATE_ON:
+ if (*size != 1) {
+ *size = -1;
+ return;
+ }
+ vcr->turn_on = *((uint8_t *)(*buffer));
+ *buffer = ((uint8_t *)(*buffer)) + 1;
+ *size = 0;
+ break;
+ default:
+ printk(BIOS_ERR,
+ "%s:%d - unsupported vendor command %#04x!\n",
+ __func__, __LINE__, vcr->vc_subcommand);
+ break;
+ }
+
+ *size = 0; /* Not much else we can do. */
+}
+
struct tpm2_response *tpm_unmarshal_response(TPM_CC command,
void *response_body,
size_t in_size)
@@ -649,7 +686,8 @@
case TPM2_CR50_VENDOR_COMMAND:
/* Assume no other data returned for the time being. */
- cr_size = 0;
+ unmarshal_vendor_command(&response_body, &cr_size,
+ &tpm2_resp->vc);
break;
default:
diff --git a/src/lib/tpm2_tlcl.c b/src/lib/tpm2_tlcl.c
index 967612a..eefcb98 100644
--- a/src/lib/tpm2_tlcl.c
+++ b/src/lib/tpm2_tlcl.c
@@ -406,3 +406,28 @@
}
return TPM_SUCCESS;
}
+
+uint32_t tlcl_cr50_turn_update_on(uint16_t timeout_ms, uint8_t *reset_pending)
+{
+ struct tpm2_response *response;
+ uint16_t command_body[] = {
+ TPM2_CR50_SUB_CMD_TURN_UPDATE_ON, timeout_ms
+ };
+
+
+ printk(BIOS_INFO, "Checking cr50 for pending updates\n");
+
+ response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, command_body);
+
+ if (response == NULL || (response && response->hdr.tpm_code)) {
+ if (response)
+ printk(BIOS_INFO, "%s: failed %x\n", __func__,
+ response->hdr.tpm_code);
+ else
+ printk(BIOS_INFO, "%s: failed\n", __func__);
+ return TPM_E_IOERROR;
+ }
+
+ *reset_pending = response->vc.turn_on;
+ return TPM_SUCCESS;
+}
diff --git a/src/lib/tpm2_tlcl_structures.h b/src/lib/tpm2_tlcl_structures.h
index ec5b674..14e2865 100644
--- a/src/lib/tpm2_tlcl_structures.h
+++ b/src/lib/tpm2_tlcl_structures.h
@@ -78,6 +78,7 @@
knowledge of all commands. */
#define TPM2_CR50_VENDOR_COMMAND ((TPM_CC)(TPM_CC_VENDOR_BIT_MASK | 0))
#define TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS (21)
+#define TPM2_CR50_SUB_CMD_TURN_UPDATE_ON (24)
/* Startup values. */
#define TPM_SU_CLEAR 0
@@ -279,6 +280,13 @@
TPM2B_MAX_NV_BUFFER buffer;
};
+struct vc_response {
+ uint16_t vc_subcommand;
+ union {
+ uint8_t turn_on;
+ };
+};
+
struct tpm2_session_attrs {
uint8_t continueSession : 1;
uint8_t auditExclusive : 1;
@@ -311,6 +319,7 @@
struct get_cap_response gc;
struct nv_read_response nvr;
struct tpm2_session_header def_space;
+ struct vc_response vc;
};
};
--
To view, visit https://review.coreboot.org/18945
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic76d384d637c0eeaad206e0a8242cbb8e2b19b37
Gerrit-PatchSet: 1
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Vadim Bendebury <vbendeb at chromium.org>
More information about the coreboot-gerrit
mailing list