summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-04-05 19:05:24 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-07-02 08:28:42 +0000
commitcb4cec106b48f22f85732c94ea2aeb60d61e6687 (patch)
treee8f7694bb47675f0d626a032fb9edd587224bd91
parent04f3de90a89ffa5cf432c5fb674bfbdfdb8e208e (diff)
downloadchrome-ec-cb4cec106b48f22f85732c94ea2aeb60d61e6687.tar.gz
cr50: add vendor CCD subcommand to report CCD information
It is important for the OS to be able to find out the state of CCD and current capabilities settings of the device. This patch defines a structure to use to report information about CCD state from Cr50 to the host and adds a CCD vendor subcommand to allow to retrieve the information from Cr50. Some structure and variable definitions had to be moved into the .h file to make it possible to share them between Cr50 and gsctool. BRANCH=cr50, cr50-mp BUG=b:72718383 TEST=with the following patch applied verified that CCD info is properly reported. Also verified that other CCD subcommands still work as advertised. Change-Id: I4a783e6817ed364b9e64522ebbe968d4a657a84c Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/999825 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1122068 Reviewed-by: Marco Chen <marcochen@chromium.org> Commit-Queue: Marco Chen <marcochen@chromium.org> Tested-by: Marco Chen <marcochen@chromium.org>
-rw-r--r--common/ccd_config.c108
-rw-r--r--include/ccd_config.h67
2 files changed, 122 insertions, 53 deletions
diff --git a/common/ccd_config.c b/common/ccd_config.c
index 63088a03f3..70111b3e52 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -28,6 +28,9 @@
#define CPRINTS(format, args...) cprints(CC_CCD, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_CCD, format, ## args)
+/* Let's make sure that CCD capability state enum fits into two bits. */
+BUILD_ASSERT(CCD_CAP_STATE_COUNT <= 4);
+
/* Restriction state for ccdunlock when no password is set */
enum ccd_unlock_restrict {
/* Unrestricted */
@@ -46,24 +49,6 @@ enum ccd_unlock_restrict {
/* Current version of case-closed debugging configuration struct */
#define CCD_CONFIG_VERSION 0x10
-/* Capability states */
-enum ccd_capability_state {
- /* Default value */
- CCD_CAP_STATE_DEFAULT = 0,
-
- /* Always available (state >= CCD_STATE_LOCKED) */
- CCD_CAP_STATE_ALWAYS = 1,
-
- /* Unless locked (state >= CCD_STATE_UNLOCKED) */
- CCD_CAP_STATE_UNLESS_LOCKED = 2,
-
- /* Only if opened (state >= CCD_STATE_OPENED) */
- CCD_CAP_STATE_IF_OPENED = 3,
-
- /* Number of capability states */
- CCD_CAP_STATE_COUNT
-};
-
/*
* CCD command header; including the subcommand code used to demultiplex
* various CCD commands over the same TPM vendor command.
@@ -103,14 +88,6 @@ struct ccd_config {
uint8_t password_digest[CCD_PASSWORD_DIGEST_SIZE];
};
-struct ccd_capability_info {
- /* Capability name */
- const char *name;
-
- /* Default state, if config set to CCD_CAP_STATE_DEFAULT */
- enum ccd_capability_state default_state;
-};
-
/* Nvmem variable name for CCD config */
static const uint8_t k_ccd_config = NVMEM_VAR_CCD_CONFIG;
@@ -120,33 +97,11 @@ static const uint32_t k_public_flags =
CCD_FLAG_OVERRIDE_WP_STATE_ENABLED;
/* List of CCD capability info; must be in same order as enum ccd_capability */
-static const struct ccd_capability_info cap_info[CCD_CAP_COUNT] = {
- {"UartGscRxAPTx", CCD_CAP_STATE_ALWAYS},
- {"UartGscTxAPRx", CCD_CAP_STATE_ALWAYS},
- {"UartGscRxECTx", CCD_CAP_STATE_ALWAYS},
- {"UartGscTxECRx", CCD_CAP_STATE_IF_OPENED},
-
- {"FlashAP", CCD_CAP_STATE_IF_OPENED},
- {"FlashEC", CCD_CAP_STATE_IF_OPENED},
- {"OverrideWP", CCD_CAP_STATE_IF_OPENED},
- {"RebootECAP", CCD_CAP_STATE_IF_OPENED},
-
- {"GscFullConsole", CCD_CAP_STATE_IF_OPENED},
- {"UnlockNoReboot", CCD_CAP_STATE_ALWAYS},
- {"UnlockNoShortPP", CCD_CAP_STATE_ALWAYS},
- {"OpenNoTPMWipe", CCD_CAP_STATE_IF_OPENED},
-
- {"OpenNoLongPP", CCD_CAP_STATE_IF_OPENED},
- {"BatteryBypassPP", CCD_CAP_STATE_ALWAYS},
- {"UpdateNoTPMWipe", CCD_CAP_STATE_ALWAYS},
- {"I2C", CCD_CAP_STATE_IF_OPENED},
- {"FlashRead", CCD_CAP_STATE_ALWAYS},
-};
+static const struct ccd_capability_info cap_info[CCD_CAP_COUNT] = CAP_INFO_DATA;
-static const char *ccd_state_names[CCD_STATE_COUNT] = {
- "Locked", "Unlocked", "Opened"};
-static const char *ccd_cap_state_names[CCD_CAP_STATE_COUNT] = {
- "Default", "Always", "UnlessLocked", "IfOpened"};
+static const char *ccd_state_names[CCD_STATE_COUNT] = CCD_STATE_NAMES;
+static const char *ccd_cap_state_names[CCD_CAP_STATE_COUNT] =
+ CCD_CAP_STATE_NAMES;
static enum ccd_state ccd_state = CCD_STATE_LOCKED;
static struct ccd_config config;
@@ -1449,6 +1404,42 @@ static enum vendor_cmd_rc ccd_pp_poll_open(void *buf,
return VENDOR_RC_SUCCESS;
}
+static enum vendor_cmd_rc ccd_get_info(void *buf,
+ size_t input_size,
+ size_t *response_size)
+{
+ int i;
+ struct ccd_info_response response = {};
+
+ for (i = 0; i < CCD_CAP_COUNT; i++) {
+ int index;
+ int shift;
+
+ /* Each capability takes 2 bits. */
+ index = i / (32/2);
+ shift = (i % (32/2)) * 2;
+ response.ccd_caps_current[index] |= raw_get_cap(i, 1) << shift;
+ response.ccd_caps_defaults[index] |=
+ cap_info[i].default_state << shift;
+ }
+
+ response.ccd_flags = htobe32(raw_get_flags());
+ response.ccd_state = ccd_get_state();
+ response.ccd_has_password = raw_has_password();
+ response.ccd_force_disabled = force_disabled;
+ for (i = 0; i < ARRAY_SIZE(response.ccd_caps_current); i++) {
+ response.ccd_caps_current[i] =
+ htobe32(response.ccd_caps_current[i]);
+ response.ccd_caps_defaults[i] =
+ htobe32(response.ccd_caps_defaults[i]);
+ }
+
+ *response_size = sizeof(response);
+ memcpy(buf, &response, sizeof(response));
+
+ return VENDOR_RC_SUCCESS;
+}
+
/*
* Common TPM Vendor command handler used to demultiplex various CCD commands
* which need to be available both throuh CLI and over /dev/tpm0.
@@ -1495,13 +1486,24 @@ static enum vendor_cmd_rc ccd_vendor(enum vendor_cmd_cc code,
handler = ccd_pp_poll_open;
break;
+ case CCDV_GET_INFO:
+ handler = ccd_get_info;
+ break;
+
default:
CPRINTS("%s:%d - unknown subcommand\n", __func__, __LINE__);
break;
}
if (handler) {
- *response_size = 0; /* Let's be optimistic: 0 means success. */
+ /*
+ * Let's be optimistic: 0 usually means success.
+ *
+ * We know the buffer is large enough to accommodate any CCD
+ * subcommand response, so there is no size checks in the
+ * processing functions.
+ */
+ *response_size = 0;
rc = handler(buf + 1, input_size - 1, response_size);
diff --git a/include/ccd_config.h b/include/ccd_config.h
index c7243ecbb8..a71db37bba 100644
--- a/include/ccd_config.h
+++ b/include/ccd_config.h
@@ -7,6 +7,9 @@
#ifndef __CROS_EC_CCD_CONFIG_H
#define __CROS_EC_CCD_CONFIG_H
+#include <common.h>
+#include <stdint.h>
+
/* Case-closed debugging state */
enum ccd_state {
CCD_STATE_LOCKED = 0,
@@ -101,6 +104,58 @@ enum ccd_capability {
CCD_CAP_COUNT
};
+/* Capability states */
+enum ccd_capability_state {
+ /* Default value */
+ CCD_CAP_STATE_DEFAULT = 0,
+
+ /* Always available (state >= CCD_STATE_LOCKED) */
+ CCD_CAP_STATE_ALWAYS = 1,
+
+ /* Unless locked (state >= CCD_STATE_UNLOCKED) */
+ CCD_CAP_STATE_UNLESS_LOCKED = 2,
+
+ /* Only if opened (state >= CCD_STATE_OPENED) */
+ CCD_CAP_STATE_IF_OPENED = 3,
+
+ /* Number of capability states */
+ CCD_CAP_STATE_COUNT
+};
+
+struct ccd_capability_info {
+ /* Capability name */
+ const char *name;
+
+ /* Default state, if config set to CCD_CAP_STATE_DEFAULT */
+ enum ccd_capability_state default_state;
+};
+
+#define CAP_INFO_DATA { \
+ {"UartGscRxAPTx", CCD_CAP_STATE_ALWAYS}, \
+ {"UartGscTxAPRx", CCD_CAP_STATE_ALWAYS}, \
+ {"UartGscRxECTx", CCD_CAP_STATE_ALWAYS}, \
+ {"UartGscTxECRx", CCD_CAP_STATE_IF_OPENED}, \
+ \
+ {"FlashAP", CCD_CAP_STATE_IF_OPENED}, \
+ {"FlashEC", CCD_CAP_STATE_IF_OPENED}, \
+ {"OverrideWP", CCD_CAP_STATE_IF_OPENED}, \
+ {"RebootECAP", CCD_CAP_STATE_IF_OPENED}, \
+ \
+ {"GscFullConsole", CCD_CAP_STATE_IF_OPENED}, \
+ {"UnlockNoReboot", CCD_CAP_STATE_ALWAYS}, \
+ {"UnlockNoShortPP", CCD_CAP_STATE_ALWAYS}, \
+ {"OpenNoTPMWipe", CCD_CAP_STATE_IF_OPENED}, \
+ \
+ {"OpenNoLongPP", CCD_CAP_STATE_IF_OPENED}, \
+ {"BatteryBypassPP", CCD_CAP_STATE_ALWAYS}, \
+ {"UpdateNoTPMWipe", CCD_CAP_STATE_ALWAYS}, \
+ {"I2C", CCD_CAP_STATE_IF_OPENED}, \
+ {"FlashRead", CCD_CAP_STATE_ALWAYS}, \
+ }
+
+#define CCD_STATE_NAMES { "Locked", "Unlocked", "Opened" }
+#define CCD_CAP_STATE_NAMES { "Default", "Always", "UnlessLocked", "IfOpened" }
+
/*
* Subcommand code, used to pass different CCD commands using the same TPM
* vendor command.
@@ -112,6 +167,7 @@ enum ccd_vendor_subcommands {
CCDV_LOCK = 3,
CCDV_PP_POLL_UNLOCK = 4,
CCDV_PP_POLL_OPEN = 5,
+ CCDV_GET_INFO = 6
};
enum ccd_pp_state {
@@ -121,6 +177,17 @@ enum ccd_pp_state {
CCD_PP_DONE = 3
};
+/* Structure to communicate information about CCD state. */
+#define CCD_CAPS_WORDS ((CCD_CAP_COUNT * 2 + 31)/32)
+struct ccd_info_response {
+ uint32_t ccd_caps_current[CCD_CAPS_WORDS];
+ uint32_t ccd_caps_defaults[CCD_CAPS_WORDS];
+ uint32_t ccd_flags;
+ uint8_t ccd_state;
+ uint8_t ccd_force_disabled;
+ uint8_t ccd_has_password;
+} __packed;
+
/**
* Initialize CCD configuration at boot.
*