summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@google.com>2018-05-15 21:14:25 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-05-30 01:02:45 -0700
commit1e58d25a59cfcc407de56ff85e0a84a77a427d96 (patch)
tree99b3af75b369b606a4bdebcc0bde63ba52c54fd1
parentce57911110baa5c3ae8a196572d274097fd19992 (diff)
downloadchrome-ec-1e58d25a59cfcc407de56ff85e0a84a77a427d96.tar.gz
cr50: add support for enabling factory mode on boot
We have determined the checks to run for board_is_first_factory_boot. This change updates cr50 to check for those conditions and enable ccd when the system determines that it is first boot in the factory. This will check that the board id is erased and the inactive image is a GUC image. The factory updates Cr50 from the GUC image, because those GUC images don't have support for everything they need to do in the factory. To determine that cr50 just recovered from that factory update, it will check that the GUC image is still in the inactive region and no board id is set. There are 2 images installed in GUC 0.0.13 and 0.0.22, so cr50 will check these versions. Future GUC images will have a field in the header declaring that they are a GUC image. I still need to create the GUC field in the header and check that in inactive_image_is_guc_image. Factory mode can't be enabled on deep sleep resume. It is only enabled after power-on reset or hard reset. This change also moves factory stuff into a factory_mode file instead of keeping it in board.c This adds 200 bytes. BUG=b:77543904 BRANCH=cr50 TEST=Verify factory mode is only enabled when cr50 recovered from reboot not deep sleep resume, 0.0.13 or 0.0.22 are in the inactive region, and the board id is erased. Change-Id: Ibece878049658493e8ad159121ada63d7a6f6b79 Signed-off-by: Mary Ruthven <mruthven@google.com> Reviewed-on: https://chromium-review.googlesource.com/1059864 Commit-Ready: Mary Ruthven <mruthven@chromium.org> Tested-by: Mary Ruthven <mruthven@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--board/cr50/board.c20
-rw-r--r--board/cr50/build.mk1
-rw-r--r--board/cr50/factory_mode.c77
-rw-r--r--common/ccd_config.c3
4 files changed, 79 insertions, 22 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index ab976dc29b..ffd7b818cc 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -1273,26 +1273,6 @@ void i2cs_set_pinmux(void)
GWRITE_FIELD(PINMUX, EXITEN0, DIOA1, 1); /* enable powerdown exit */
}
-/**
- * Return non-zero if this is the first boot of a board in the factory.
- *
- * This is used to determine whether the default CCD configuration will be RMA
- * (things are unlocked for factory) or normal (things locked down because not
- * in factory).
- *
- * Suggested checks:
- * - If the board ID exists, this is not the first boot
- * - If the TPM is not blank, this is not the first boot
- */
-int board_is_first_factory_boot(void)
-{
- /*
- * TODO(rspangler): Add checks for factory boot. For now, always
- * return 0 so we're safely locked by default.
- */
- return 0;
-}
-
/* Determine key type based on the key ID. */
static const char *key_type(const struct SignedHeader *h)
{
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index e6c3725578..58254ed8aa 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -35,6 +35,7 @@ board-y += ec_state.o
board-y += power_button.o
board-y += servo_state.o
board-y += ap_uart_state.o
+board-y += factory_mode.o
board-${CONFIG_RDD} += rdd.o
board-${CONFIG_USB_SPI} += usb_spi.o
board-${CONFIG_USB_I2C} += usb_i2c.o
diff --git a/board/cr50/factory_mode.c b/board/cr50/factory_mode.c
new file mode 100644
index 0000000000..c8a5dd2cdd
--- /dev/null
+++ b/board/cr50/factory_mode.c
@@ -0,0 +1,77 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "board_id.h"
+#include "console.h"
+#include "system.h"
+
+#define CPRINTS(format, args...) cprints(CC_CCD, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_CCD, format, ## args)
+
+
+static int board_id_is_erased(void)
+{
+ struct board_id id;
+ /*
+ * If we can't read the board id for some reason, return 0 just to be
+ * safe
+ */
+ if (read_board_id(&id) != EC_SUCCESS) {
+ CPRINTS("%s: BID read error", __func__);
+ return 0;
+ }
+
+ /* If all of the fields are all 0xffffffff, the board id is not set */
+ if (~(id.type & id.type_inv & id.flags) == 0) {
+ CPRINTS("BID erased");
+ return 1;
+ }
+ return 0;
+}
+
+static int inactive_image_is_guc_image(void)
+{
+ enum system_image_copy_t inactive_copy;
+ const struct SignedHeader *other;
+
+ if (system_get_image_copy() == SYSTEM_IMAGE_RW_A)
+ inactive_copy = SYSTEM_IMAGE_RW_B;
+ else
+ inactive_copy = SYSTEM_IMAGE_RW_A;
+ other = (struct SignedHeader *) get_program_memory_addr(
+ inactive_copy);
+ /*
+ * Chips from GUC are manufactured with 0.0.13 or 0.0.22. Compare the
+ * versions to determine if the inactive image is a GUC image.
+ */
+ if (other->epoch_ == 0 && other->major_ == 0 &&
+ ((other->minor_ == 13) || (other->minor_ == 22))) {
+ CPRINTS("GUC in inactive RW");
+ return 1;
+ }
+ /*
+ * TODO(mruthven): Return true if factory image field of header is
+ * set
+ */
+ return 0;
+}
+
+/**
+ * Return non-zero if this is the first boot of a board in the factory.
+ *
+ * This is used to determine whether the default CCD configuration will be RMA
+ * (things are unlocked for factory) or normal (things locked down because not
+ * in factory).
+ *
+ * checks:
+ * - If the system recovered from reboot not deep sleep resume.
+ * - If the board ID exists, this is not the first boot
+ * - If the inactive image is not a GUC image, then we've left the factory
+ */
+int board_is_first_factory_boot(void)
+{
+ return (!(system_get_reset_flags() & RESET_FLAG_HIBERNATE) &&
+ inactive_image_is_guc_image() && board_id_is_erased());
+}
diff --git a/common/ccd_config.c b/common/ccd_config.c
index 28f393d87d..5866da0b8f 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -340,13 +340,12 @@ static void ccd_load_config(void)
if (board_is_first_factory_boot()) {
/* Give factory RMA access */
CPRINTS("CCD using factory config");
- ccd_reset_config(CCD_RESET_TEST_LAB | CCD_RESET_RMA);
+ ccd_reset_config(CCD_RESET_RMA);
} else {
/* Somehow we lost our config; normal defaults */
CPRINTS("CCD using default config");
ccd_reset_config(CCD_RESET_TEST_LAB);
}
-
ccd_config_loaded = 1;
return;
}