summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2019-04-02 12:42:51 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-04-10 18:07:12 -0700
commit2b00d45486ea6f827bf3f4a58d802279360d583e (patch)
treea7e6166537b4caecee3025d3bf41e2ee12c12066 /chip
parentbeee9cedb0f9458154cbf0f98987df05637d746c (diff)
downloadchrome-ec-2b00d45486ea6f827bf3f4a58d802279360d583e.tar.gz
cr50: add INFO1 RW MAP erasing to CR50_SQA mode
When building with CR50_SQA defined, the resulting image is supposed to allow transitioning the H1 chip it is running on from pre-pvt to MP track. This should include preserving the Board ID value, but setting the board id flags to zero, and erasing the INFO1 RW map, because older MP image could have a less restrictive mask. The rest of the INFO1 space should be preserved. Sometimes there is a need to set flags to a non-zero value and migrate from MP to pre-pvt. This would be possible if image is compiled with CR50_SQA set 2 or a larger numeric value. This patch creates a structure describing the layout of the INFO1 space and modifies the 'eraseflashinfo' command to behave differently depending on the build time configuration. In addition to erasing the INFO1 RW map: - when CR50_DEV is set - everything but INFO1 RO map is erased - when CR50_SQA is set to 1, the board ID flags are set to zero, and INFO1 RW map is erased. - when CR50_SQA is set to 1, the board ID flags can be set to a value which would not lock out the currently running image and INFO1 RW map is erased. With these modifications the 'eraseflashinfo' command can be used instead of 'bid force_pvt', and previously erased INFO1 RO map is preserved. BRANCH=none BUG=none TEST=tried running 'eraseflashinfo' in three kinds of images (CR50_DEV=1, CR50_SQA=1, and CR50_SQA=2) and with various board ID flags set in the image header, and observed the desired behavior. Change-Id: Icf26dc3a4a4bb6fac2fcec630749c81aa46e16ae Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1549981 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r--chip/g/board_id.c26
-rw-r--r--chip/g/board_space.h12
-rw-r--r--chip/g/flash.c101
-rw-r--r--chip/g/flash_config.h2
4 files changed, 84 insertions, 57 deletions
diff --git a/chip/g/board_id.c b/chip/g/board_id.c
index b871f8b6ca..1f46bd8226 100644
--- a/chip/g/board_id.c
+++ b/chip/g/board_id.c
@@ -242,35 +242,11 @@ static int command_board_id(int argc, char **argv)
rv = write_board_id(&id, 0);
}
#endif
-#ifdef CR50_RELAXED
- else if (argc == 2) {
- int clear_flags;
-
- if (strcasecmp(argv[1], "force_pvt"))
- return EC_ERROR_PARAM2;
-
- clear_flags = 1;
- rv = read_board_id(&id);
- if (rv != EC_SUCCESS) {
- CPRINTS("%s: error reading Board ID", __func__);
- return rv;
- }
- if (board_id_is_blank(&id)) {
- CPRINTS("%s: Board ID isn't set", __func__);
- return EC_ERROR_INVAL;
- }
- id.flags = 0;
- rv = write_board_id(&id, clear_flags);
-
- }
-#endif
return rv;
}
DECLARE_SAFE_CONSOLE_COMMAND(bid, command_board_id,
#ifdef CR50_DEV
- "[force_pvt | bid flags]",
-#elif defined(CR50_RELAXED)
- "[force_pvt]",
+ "[bid flags]",
#else
NULL,
#endif
diff --git a/chip/g/board_space.h b/chip/g/board_space.h
index 1884a5c74c..b71733c210 100644
--- a/chip/g/board_space.h
+++ b/chip/g/board_space.h
@@ -8,6 +8,7 @@
#define __EC_CHIP_G_BOARD_SPACE_H
#include "compile_time_macros.h"
+#include "flash_config.h"
#include "flash_info.h"
#include "stdint.h"
@@ -47,6 +48,17 @@ struct info1_board_space {
struct sn_data sn;
};
+/* Layout of the entire 2K INFO1 space. */
+struct info1_layout {
+ uint8_t ro_info_map[INFO_RO_MAP_SIZE];
+ uint8_t rw_info_map[INFO_RW_MAP_SIZE];
+ struct info1_board_space board_space;
+ uint8_t padding[FLASH_INFO_MANUFACTURE_STATE_OFFSET - INFO_RO_MAP_SIZE -
+ INFO_RW_MAP_SIZE - sizeof(struct info1_board_space)];
+ uint8_t manufacture_space[FLASH_INFO_MANUFACTURE_STATE_SIZE];
+};
+BUILD_ASSERT(sizeof(struct info1_layout) == FLASH_INFO_SIZE);
+
#define INFO_BOARD_ID_SIZE sizeof(struct board_id)
#define INFO_BOARD_ID_OFFSET (INFO_BOARD_SPACE_OFFSET + \
offsetof(struct info1_board_space, \
diff --git a/chip/g/flash.c b/chip/g/flash.c
index 8012a34430..2f567d89b4 100644
--- a/chip/g/flash.c
+++ b/chip/g/flash.c
@@ -39,12 +39,11 @@
*/
#include "common.h"
+#include "board_id.h"
#include "console.h"
#include "cryptoc/util.h"
#include "flash.h"
-#include "flash_config.h"
#include "flash_log.h"
-#include "flash_info.h"
#include "registers.h"
#include "shared_mem.h"
#include "task.h"
@@ -191,7 +190,7 @@ static int do_flash_op(enum flash_op op, int is_info_bank,
/* What are we doing? */
switch (op) {
case OP_ERASE_BLOCK:
-#ifndef CR50_DEV
+#ifndef CR50_RELAXED
if (is_info_bank)
/* Erasing the INFO bank from the RW section is
* unsupported. */
@@ -502,37 +501,77 @@ void flash_open_ro_window(uint32_t offset, size_t size_b)
GWRITE_FIELD(GLOBALSEC, FLASH_REGION6_CTRL, WR_EN, 1);
}
-#ifdef CR50_DEV
+#ifdef CR50_RELAXED
static int command_erase_flash_info(int argc, char **argv)
{
- uint32_t *preserved_manufacture_state;
- const size_t manuf_word_count = FLASH_INFO_MANUFACTURE_STATE_SIZE /
- sizeof(uint32_t);
int i;
- int rv = EC_ERROR_BUSY;
+ int rv;
+ struct info1_layout *info1;
+ uint32_t *p;
- if (shared_mem_acquire(FLASH_INFO_MANUFACTURE_STATE_SIZE,
- (char **)&preserved_manufacture_state) !=
- EC_SUCCESS) {
- ccprintf("Failed to allocate memory for manufacture state!\n");
+ rv = shared_mem_acquire(sizeof(*info1), (char **)&info1);
+ if (rv != EC_SUCCESS) {
+ ccprintf("Failed to allocate memory for info1!\n");
return rv;
}
flash_info_read_enable(0, 2048);
flash_info_write_enable(0, 2048);
- /* Preserve manufacturing information. */
- for (i = 0; i < manuf_word_count; i++) {
- if (flash_physical_info_read_word
- (FLASH_INFO_MANUFACTURE_STATE_OFFSET +
- i * sizeof(uint32_t),
- preserved_manufacture_state + i) != EC_SUCCESS) {
+ /* Read the entire info1. */
+ p = (uint32_t *)info1;
+ for (i = 0; i < (sizeof(*info1) / sizeof(*p)); i++) {
+ if (flash_physical_info_read_word(i * sizeof(*p), p + i) !=
+ EC_SUCCESS) {
ccprintf("Failed to read word %d!\n", i);
goto exit;
}
}
+#ifdef CR50_SQA
+ /*
+ * SQA images erase INFO1 RW mask, but do not allow erasing board ID.
+ *
+ * If compiled with CR50_SQA=1, board ID flags will set to zero, if
+ * compiled with CR50_SQA=2 or greater, board ID flags can be set to
+ * an arbitrary value passed in on the command line, but guaranteeing
+ * not to lock out the currently running image.
+ */
+ {
+ uint32_t flags = 0;
+#if CR50_SQA > 1
+ if (argc > 1) {
+ char *e;
+
+ flags = strtoi(argv[1], &e, 0);
+ if (*e) {
+ rv = EC_ERROR_PARAM1;
+ goto exit;
+ }
+ }
+#endif
+ info1->board_space.bid.flags = flags;
+ if (check_board_id_vs_header(&info1->board_space.bid,
+ get_current_image_header())) {
+ ccprintf("Flags %x would lock out current image\n",
+ flags);
+ rv = EC_ERROR_PARAM1;
+ goto exit;
+ }
+ }
+#else /* CR50_SQA ^^^^^^ defined vvvvvvv Not defined. */
+ /*
+ * This must be CR50_DEV=1 image, just erase the entire board and
+ * manufacture spaces.
+ */
+ memset(&info1->board_space, 0xff, sizeof(info1->board_space));
+ memset(&info1->manufacture_space, 0xff,
+ sizeof(info1->manufacture_space));
+#endif /* CR50_SQA Not defined. */
+
+ memset(info1->rw_info_map, 0xff, sizeof(info1->rw_info_map));
+
mutex_lock(&flash_mtx);
rv = do_flash_op(OP_ERASE_BLOCK, 1, 0, 512);
@@ -544,23 +583,21 @@ static int command_erase_flash_info(int argc, char **argv)
goto exit;
}
- if (flash_info_physical_write
- (FLASH_INFO_MANUFACTURE_STATE_OFFSET,
- FLASH_INFO_MANUFACTURE_STATE_SIZE,
- (char *)preserved_manufacture_state) != EC_SUCCESS) {
- ccprintf("Failed to restore manufacture state!\n");
- goto exit;
- }
+ rv = flash_info_physical_write(0, sizeof(*info1), (char *)info1);
+ if (rv != EC_SUCCESS)
+ ccprintf("Failed write back info1 contents!\n");
- rv = EC_SUCCESS;
exit:
- always_memset(preserved_manufacture_state, 0,
- FLASH_INFO_MANUFACTURE_STATE_SIZE);
- shared_mem_release(preserved_manufacture_state);
flash_info_write_disable();
+ always_memset(info1, 0, sizeof(*info1));
+ shared_mem_release(info1);
return rv;
}
-DECLARE_CONSOLE_COMMAND(eraseflashinfo, command_erase_flash_info,
- "",
- "Erase INFO1 flash space");
+DECLARE_SAFE_CONSOLE_COMMAND(eraseflashinfo, command_erase_flash_info,
+#if defined(CR50_SQA) && (CR50_SQA > 1)
+ "[bid flags]",
+ "Erase INFO1 flash space and set Board ID flags");
+#else
+ "", "Erase INFO1 flash space");
+#endif
#endif
diff --git a/chip/g/flash_config.h b/chip/g/flash_config.h
index d1bec36871..73dd2eec60 100644
--- a/chip/g/flash_config.h
+++ b/chip/g/flash_config.h
@@ -5,6 +5,8 @@
#ifndef __EC_CHIP_G_FLASH_CONFIG_H
#define __EC_CHIP_G_FLASH_CONFIG_H
+#include "stdint.h"
+
#define FLASH_INFO_SIZE (2 * 1024)
#define FLASH_INFO_MEMORY_BASE 0x28000
/* INFO is a 2-KB flash page that consists of four regions. The