summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/extension.c16
-rw-r--r--common/tpm_registers.c31
2 files changed, 31 insertions, 16 deletions
diff --git a/common/extension.c b/common/extension.c
index a588ce892e..d28bfad337 100644
--- a/common/extension.c
+++ b/common/extension.c
@@ -10,10 +10,10 @@
#define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ## args)
-void extension_route_command(uint16_t command_code,
- void *buffer,
- size_t in_size,
- size_t *out_size)
+uint32_t extension_route_command(uint16_t command_code,
+ void *buffer,
+ size_t in_size,
+ size_t *out_size)
{
struct extension_command *cmd_p;
struct extension_command *end_p;
@@ -22,10 +22,9 @@ void extension_route_command(uint16_t command_code,
end_p = (struct extension_command *)&__extension_cmds_end;
while (cmd_p != end_p) {
- if (cmd_p->command_code == command_code) {
- cmd_p->handler(buffer, in_size, out_size);
- return;
- }
+ if (cmd_p->command_code == command_code)
+ return cmd_p->handler(command_code, buffer,
+ in_size, out_size);
cmd_p++;
}
@@ -33,4 +32,5 @@ void extension_route_command(uint16_t command_code,
/* This covers the case of the handler not found. */
*out_size = 0;
+ return VENDOR_RC_NO_SUCH_COMMAND;
}
diff --git a/common/tpm_registers.c b/common/tpm_registers.c
index 444ed52e20..b5c5f8b7e5 100644
--- a/common/tpm_registers.c
+++ b/common/tpm_registers.c
@@ -569,10 +569,21 @@ size_t tpm_get_burst_size(void)
#ifdef CONFIG_EXTENSION_COMMAND
+/* Recognize both original extension and new vendor-specific command codes */
+#define IS_CUSTOM_CODE(code) \
+ ((code == CONFIG_EXTENSION_COMMAND) || \
+ (code & TPM_CC_VENDOR_BIT_MASK))
+
static void call_extension_command(struct tpm_cmd_header *tpmh,
- size_t *total_size)
+ size_t *total_size)
{
size_t command_size = be32toh(tpmh->size);
+ uint32_t rc;
+
+ /*
+ * Note that we don't look for TPM_CC_VENDOR_CR50 anywhere. All
+ * vendor-specific commands are handled the same way for now.
+ */
/* Verify there is room for at least the extension command header. */
if (command_size >= sizeof(struct tpm_cmd_header)) {
@@ -582,14 +593,18 @@ static void call_extension_command(struct tpm_cmd_header *tpmh,
*total_size -= sizeof(struct tpm_cmd_header);
subcommand_code = be16toh(tpmh->subcommand_code);
- extension_route_command(subcommand_code,
- tpmh + 1,
- command_size -
- sizeof(struct tpm_cmd_header),
- total_size);
+ rc = extension_route_command(subcommand_code,
+ tpmh + 1,
+ command_size -
+ sizeof(struct tpm_cmd_header),
+ total_size);
/* Add the header size back. */
*total_size += sizeof(struct tpm_cmd_header);
tpmh->size = htobe32(*total_size);
+ /* Flag errors from commands as vendor-specific */
+ if (rc)
+ rc |= VENDOR_RC_ERR;
+ tpmh->command_code = htobe32(rc);
} else {
*total_size = command_size;
}
@@ -689,7 +704,7 @@ void tpm_task(void)
watchdog_reload();
#ifdef CONFIG_EXTENSION_COMMAND
- if (command_code == CONFIG_EXTENSION_COMMAND) {
+ if (IS_CUSTOM_CODE(command_code)) {
response_size = sizeof(tpm_.regs.data_fifo);
call_extension_command(tpmh, &response_size);
} else
@@ -711,7 +726,7 @@ void tpm_task(void)
if (command_code == TPM2_PCR_Read)
system_process_retry_counter();
#ifdef CONFIG_EXTENSION_COMMAND
- if (command_code != CONFIG_EXTENSION_COMMAND)
+ if (!IS_CUSTOM_CODE(command_code))
#endif
{
/*