[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