summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMadhurima Paruchuri <mparuchuri@google.com>2023-04-11 11:48:52 +0000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-04-17 18:27:35 +0000
commit5093a223cb5d29197cd498c80c157c1e0b60c389 (patch)
treebe37eaf99a690e71c36002ab4eed1fb533c0607b
parent74108a6ab365a110d70b4064ec2d99fa7ea9b73e (diff)
downloadchrome-ec-5093a223cb5d29197cd498c80c157c1e0b60c389.tar.gz
flash: cbi: Block the HCs from flash CBI section modification
BRANCH=None BUG=b:267629295 TEST=./twister -T zephyr/test -c Change-Id: Ibcf176f10860cc126b267908faba054df256c3d4 Signed-off-by: Madhurima Paruchuri <mparuchuri@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4414226 Reviewed-by: Wai-Hong Tam <waihong@google.com>
-rw-r--r--common/flash.c85
-rw-r--r--include/flash.h23
-rw-r--r--zephyr/shim/include/cbi_flash.h28
-rw-r--r--zephyr/shim/src/cbi/cbi_flash.c20
-rw-r--r--zephyr/test/drivers/cbi_flash/src/cbi_flash.c8
-rw-r--r--zephyr/test/drivers/flash/src/flash.c279
-rw-r--r--zephyr/test/drivers/testcase.yaml9
7 files changed, 422 insertions, 30 deletions
diff --git a/common/flash.c b/common/flash.c
index 8b1ca25089..05eceaedd0 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -6,6 +6,9 @@
/* Flash memory module for Chrome EC - common functions */
#include "builtin/assert.h"
+#ifdef CONFIG_ZEPHYR
+#include "cbi_flash.h"
+#endif /* CONFIG_ZEPHYR */
#include "common.h"
#include "console.h"
#include "cros_board_info.h"
@@ -666,7 +669,45 @@ int crec_flash_is_erased(uint32_t offset, int size)
return 1;
}
-test_mockable int crec_flash_read(int offset, int size, char *data)
+#if defined(CONFIG_ZEPHYR) && defined(CONFIG_PLATFORM_EC_CBI_FLASH)
+/**
+ * Check if the passed section overlaps with CBI section on EC flash.
+ *
+ * @param offset Flash offset.
+ * @param size Length of section in bytes.
+ * @return true if there is overlap, or false if there is no overlap.
+ */
+static bool check_cbi_section_overlap(int offset, int size)
+{
+ int cbi_start = CBI_FLASH_OFFSET;
+ int cbi_end = CBI_FLASH_OFFSET + CBI_IMAGE_SIZE;
+ int sec_start = offset;
+ int sec_end = offset + size;
+
+ return !((sec_end <= cbi_start) || (sec_start >= cbi_end));
+}
+
+/**
+ * Hide the information related to CBI(EC flash) if data contains any.
+ *
+ * @param offset Flash offset.
+ * @param size Length of section in bytes.
+ * @param data Flash data. Must be 32-bit aligned.
+ */
+static void protect_cbi_overlapped_section(int offset, int size, char *data)
+{
+ if (check_cbi_section_overlap(offset, size)) {
+ int cbi_end = CBI_FLASH_OFFSET + CBI_IMAGE_SIZE;
+ int sec_end = offset + size;
+ int cbi_fill_start = MAX(CBI_FLASH_OFFSET, offset);
+ int cbi_fill_size = MIN(cbi_end, sec_end) - cbi_fill_start;
+
+ memset(data + (cbi_fill_start - offset), 0xff, cbi_fill_size);
+ }
+}
+#endif
+
+test_mockable int crec_flash_unprotected_read(int offset, int size, char *data)
{
#ifdef CONFIG_MAPPED_STORAGE
const char *src;
@@ -683,6 +724,15 @@ test_mockable int crec_flash_read(int offset, int size, char *data)
#endif
}
+int crec_flash_read(int offset, int size, char *data)
+{
+ RETURN_ERROR(crec_flash_unprotected_read(offset, size, data));
+#if defined(CONFIG_ZEPHYR) && defined(CONFIG_PLATFORM_EC_CBI_FLASH)
+ protect_cbi_overlapped_section(offset, size, data);
+#endif
+ return EC_SUCCESS;
+}
+
static void flash_abort_or_invalidate_hash(int offset, int size)
{
#ifdef CONFIG_VBOOT_HASH
@@ -728,6 +778,23 @@ int crec_flash_write(int offset, int size, const char *data)
flash_abort_or_invalidate_hash(offset, size);
+#if defined(CONFIG_ZEPHYR) && defined(CONFIG_PLATFORM_EC_CBI_FLASH)
+ if (check_cbi_section_overlap(offset, size)) {
+ int cbi_end = CBI_FLASH_OFFSET + CBI_IMAGE_SIZE;
+ int sec_end = offset + size;
+
+ if (offset < CBI_FLASH_OFFSET) {
+ RETURN_ERROR(crec_flash_physical_write(
+ offset, CBI_FLASH_OFFSET - offset, data));
+ }
+ if (sec_end > cbi_end) {
+ RETURN_ERROR(crec_flash_physical_write(
+ cbi_end, sec_end - cbi_end,
+ data + cbi_end - offset));
+ }
+ return EC_SUCCESS;
+ }
+#endif
return crec_flash_physical_write(offset, size, data);
}
@@ -740,6 +807,22 @@ int crec_flash_erase(int offset, int size)
flash_abort_or_invalidate_hash(offset, size);
+#if defined(CONFIG_ZEPHYR) && defined(CONFIG_PLATFORM_EC_CBI_FLASH)
+ if (check_cbi_section_overlap(offset, size)) {
+ int cbi_end = CBI_FLASH_OFFSET + CBI_IMAGE_SIZE;
+ int sec_end = offset + size;
+
+ if (offset < CBI_FLASH_OFFSET) {
+ RETURN_ERROR(crec_flash_physical_erase(
+ offset, CBI_FLASH_OFFSET - offset));
+ }
+ if (sec_end > cbi_end) {
+ RETURN_ERROR(crec_flash_physical_erase(
+ cbi_end, sec_end - cbi_end));
+ }
+ return EC_SUCCESS;
+ }
+#endif
return crec_flash_physical_erase(offset, size);
}
diff --git a/include/flash.h b/include/flash.h
index 240db02d67..08f70182d7 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -320,15 +320,32 @@ int crec_flash_get_size(void);
int crec_flash_dataptr(int offset, int size_req, int align, const char **ptrp);
/**
+ * Read from flash without hiding protected sections data
+ *
+ * If flash is mapped (CONFIG_MAPPED_STORAGE), it is usually more efficient to
+ * use flash_dataptr() to get a pointer directly to the flash memory rather
+ * than use flash_read(), since the former saves a memcpy() operation.
+ *
+ * This method won't hide the protected flash sections data.
+ *
+ * @param offset Flash offset to read.
+ * @param size Number of bytes to read.
+ * @param data Destination buffer for data. Must be 32-bit aligned.
+ */
+int crec_flash_unprotected_read(int offset, int size, char *data);
+
+/**
* Read from flash.
*
* If flash is mapped (CONFIG_MAPPED_STORAGE), it is usually more efficient to
* use flash_dataptr() to get a pointer directly to the flash memory rather
* than use flash_read(), since the former saves a memcpy() operation.
*
- * @param offset Flash offset to write.
- * @param size Number of bytes to write.
- * @param data Destination buffer for data. Must be 32-bit aligned.
+ * This method hides the protected flash sections data.
+ *
+ * @param offset Flash offset to read.
+ * @param size Number of bytes to read.
+ * @param data Destination buffer for data. Must be 32-bit aligned.
*/
int crec_flash_read(int offset, int size, char *data);
diff --git a/zephyr/shim/include/cbi_flash.h b/zephyr/shim/include/cbi_flash.h
new file mode 100644
index 0000000000..9f2fc26cc4
--- /dev/null
+++ b/zephyr/shim/include/cbi_flash.h
@@ -0,0 +1,28 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __CROS_EC_CBI_FLASH_H
+#define __CROS_EC_CBI_FLASH_H
+
+#include "cros_board_info.h"
+
+#include <zephyr/devicetree.h>
+
+#define DT_DRV_COMPAT cros_ec_flash_layout
+
+#define CBI_FLASH_NODE DT_NODELABEL(cbi_flash)
+#define CBI_FLASH_OFFSET DT_PROP(CBI_FLASH_NODE, offset)
+#define CBI_FLASH_PRESERVE DT_PROP(CBI_FLASH_NODE, preserve)
+
+#if CONFIG_PLATFORM_EC_CBI_FLASH
+BUILD_ASSERT(DT_NODE_EXISTS(CBI_FLASH_NODE) == 1,
+ "CBI flash DT node label not found");
+BUILD_ASSERT((CBI_FLASH_OFFSET % CONFIG_FLASH_ERASE_SIZE) == 0,
+ "CBI flash offset is not erase-size aligned");
+BUILD_ASSERT((CBI_IMAGE_SIZE % CONFIG_FLASH_ERASE_SIZE) == 0,
+ "CBI flash size is not erase-size aligned");
+BUILD_ASSERT(CBI_IMAGE_SIZE > 0, "CBI flash size must be greater than zero");
+#endif /* CONFIG_PLATFORM_EC_CBI_FLASH */
+#endif /* __CROS_EC_CBI_FLASH_H */
diff --git a/zephyr/shim/src/cbi/cbi_flash.c b/zephyr/shim/src/cbi/cbi_flash.c
index bb63f66c59..60dac33ad1 100644
--- a/zephyr/shim/src/cbi/cbi_flash.c
+++ b/zephyr/shim/src/cbi/cbi_flash.c
@@ -3,8 +3,7 @@
* found in the LICENSE file.
*/
-#define DT_DRV_COMPAT cros_ec_flash_layout
-
+#include "cbi_flash.h"
#include "console.h"
#include "cros_board_info.h"
#include "flash.h"
@@ -12,26 +11,13 @@
#include "write_protect.h"
#include <zephyr/devicetree.h>
-#include <zephyr/drivers/gpio.h>
-#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(cbi_flash, LOG_LEVEL_ERR);
-#define CBI_FLASH_NODE DT_NODELABEL(cbi_flash)
-#define CBI_FLASH_OFFSET DT_PROP(CBI_FLASH_NODE, offset)
-#define CBI_FLASH_PRESERVE DT_PROP(CBI_FLASH_NODE, preserve)
-
-BUILD_ASSERT(DT_NODE_EXISTS(CBI_FLASH_NODE) == 1,
- "CBI flash DT node label not found");
-BUILD_ASSERT((CBI_FLASH_OFFSET % CONFIG_FLASH_ERASE_SIZE) == 0,
- "CBI flash offset is not erase-size aligned");
-BUILD_ASSERT((CBI_IMAGE_SIZE % CONFIG_FLASH_ERASE_SIZE) == 0,
- "CBI flash size is not erase-size aligned");
-BUILD_ASSERT(CBI_IMAGE_SIZE > 0, "CBI flash size must be greater than zero");
-
static int flash_load(uint8_t offset, uint8_t *data, int len)
{
- return crec_flash_read(CBI_FLASH_OFFSET, CBI_IMAGE_SIZE, (char *)data);
+ return crec_flash_unprotected_read(CBI_FLASH_OFFSET, CBI_IMAGE_SIZE,
+ (char *)data);
}
static int flash_is_write_protected(void)
diff --git a/zephyr/test/drivers/cbi_flash/src/cbi_flash.c b/zephyr/test/drivers/cbi_flash/src/cbi_flash.c
index 1c93da1d2c..7863983d52 100644
--- a/zephyr/test/drivers/cbi_flash/src/cbi_flash.c
+++ b/zephyr/test/drivers/cbi_flash/src/cbi_flash.c
@@ -16,7 +16,7 @@
#define CBI_FLASH_NODE DT_NODELABEL(cbi_flash)
#define CBI_FLASH_OFFSET DT_PROP(CBI_FLASH_NODE, offset)
-FAKE_VALUE_FUNC(int, crec_flash_read, int, int, char *);
+FAKE_VALUE_FUNC(int, crec_flash_unprotected_read, int, int, char *);
ZTEST(cbi_flash, test_cbi_flash_is_write_protected)
{
@@ -42,7 +42,7 @@ ZTEST(cbi_flash, test_cbi_flash_load)
input_data[index] = index % 255;
}
cbi_config.drv->store(input_data);
- crec_flash_read_fake.return_val = crec_flash_physical_read(
+ crec_flash_unprotected_read_fake.return_val = crec_flash_physical_read(
CBI_FLASH_OFFSET, CBI_IMAGE_SIZE, data);
zassert_ok(cbi_config.drv->load(0, data, 0));
@@ -55,7 +55,7 @@ ZTEST(cbi_flash, test_cbi_flash_load_error)
{
uint8_t data[CBI_IMAGE_SIZE];
- crec_flash_read_fake.return_val = EC_ERROR_INVAL;
+ crec_flash_unprotected_read_fake.return_val = EC_ERROR_INVAL;
zassert_equal(cbi_config.drv->load(0, data, 0), EC_ERROR_INVAL);
}
@@ -78,7 +78,7 @@ ZTEST(cbi_flash, test_cbi_flash_store_fail)
static void cbi_flash_before(void *fixture)
{
ARG_UNUSED(fixture);
- RESET_FAKE(crec_flash_read);
+ RESET_FAKE(crec_flash_unprotected_read);
}
ZTEST_SUITE(cbi_flash, drivers_predicate_post_main, NULL, cbi_flash_before,
diff --git a/zephyr/test/drivers/flash/src/flash.c b/zephyr/test/drivers/flash/src/flash.c
index 17bb1da373..c3d9c65b36 100644
--- a/zephyr/test/drivers/flash/src/flash.c
+++ b/zephyr/test/drivers/flash/src/flash.c
@@ -564,32 +564,301 @@ static uint16_t read_flash_helper32(uint32_t offset, uint32_t *output)
ZTEST_USER(flash, test_console_cmd_flash_erase__happy)
{
/* Immediately before the region to erase */
- zassert_ok(write_flash_helper32(0x40000 - 4, 0x5A5A5A5A));
+ zassert_ok(write_flash_helper32(0x10000 - 4, 0x5A5A5A5A));
/* Start and end of the region we will erase */
- zassert_ok(write_flash_helper32(0x40000, 0xA1B2C3D4));
- zassert_ok(write_flash_helper32(0x50000 - 4, 0x1A2B3C4D));
+ zassert_ok(write_flash_helper32(0x10000, 0xA1B2C3D4));
+ zassert_ok(write_flash_helper32(0x20000 - 4, 0x1A2B3C4D));
/* Immediately after the region to erase */
- zassert_ok(write_flash_helper32(0x50000, 0xA5A5A5A5));
+ zassert_ok(write_flash_helper32(0x20000, 0xA5A5A5A5));
+
+ CHECK_CONSOLE_CMD("flasherase 0x10000 0x10000", NULL, EC_SUCCESS);
+
+ uint32_t output;
+
+ /* These should remain untouched */
+ zassert_ok(read_flash_helper32(0x10000 - 4, &output));
+ zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x20000, &output));
+ zassert_equal(output, 0xA5A5A5A5, "Got %08x", output);
+
+ /* These are within the erase region and should be reset to all FF */
+ zassert_ok(read_flash_helper32(0x10000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x20000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+}
+
+#ifdef CONFIG_PLATFORM_EC_CBI_FLASH
+ZTEST_USER(flash, test_console_cmd_flash_erase__cbi_overlap_0)
+{
+ uint32_t output;
+
+ /* Immediately before the region to erase */
+ zassert_ok(write_flash_helper32(0x3F000 - 4, 0x5A5A5A5A));
+ /* Immediately after the region to erase */
+ zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5));
+
+ /* The CBI region */
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+
+ CHECK_CONSOLE_CMD("flasherase 0x3F000 0x1000", NULL, EC_SUCCESS);
+
+ /* These should remain untouched */
+ zassert_ok(read_flash_helper32(0x3F000 - 4, &output));
+ zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000, &output));
+ zassert_equal(output, 0xA5A5A5A5, "Got %08x", output);
+
+ /* These are within the erase region and should be reset to all FF */
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_erase__cbi_overlap_left)
+{
+ uint32_t output;
+
+ /* Immediately before the region to erase */
+ zassert_ok(write_flash_helper32(0x3F000 - 4, 0x5A5A5A5A));
+ /* Immediately after the region to erase */
+ zassert_ok(write_flash_helper32(0x50000, 0x5A5A5A5A));
+ /* Immediately after the CBI region */
+ zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5));
+ zassert_ok(read_flash_helper32(0x40000, &output));
+ zassert_equal(output, 0xA5A5A5A5, "Got %08x", output);
+
+ /* The CBI region */
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+
+ CHECK_CONSOLE_CMD("flasherase 0x3F000 0x11000", NULL, EC_SUCCESS);
+
+ /* These should remain untouched */
+ zassert_ok(read_flash_helper32(0x3F000 - 4, &output));
+ zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x50000, &output));
+ zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
+
+ /* These are within the erase region and should be reset to all FF */
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x50000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_erase__cbi_overlap_right)
+{
+ uint32_t output;
+
+ /* Immediately before the region to erase */
+ zassert_ok(write_flash_helper32(0x2F000 - 4, 0x5A5A5A5A));
+ /* Immediately after the region to erase */
+ zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5));
+ /* Immediately before the CBI region */
+ zassert_ok(write_flash_helper32(0x3F000 - 4, 0xA5A5A5AA));
+ zassert_ok(read_flash_helper32(0x3F000 - 4, &output));
+ zassert_equal(output, 0xA5A5A5AA, "Got %08x", output);
+
+ /* The CBI region */
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+
+ CHECK_CONSOLE_CMD("flasherase 0x2F000 0x11000", NULL, EC_SUCCESS);
+
+ /* These should remain untouched */
+ zassert_ok(read_flash_helper32(0x2F000 - 4, &output));
+ zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000, &output));
+ zassert_equal(output, 0xA5A5A5A5, "Got %08x", output);
+
+ /* These are within the erase region and should be reset to all FF */
+ zassert_ok(read_flash_helper32(0x2F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x3F000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+}
- CHECK_CONSOLE_CMD("flasherase 0x40000 0x10000", NULL, EC_SUCCESS);
+ZTEST_USER(flash, test_console_cmd_flash_erase__left)
+{
+ uint32_t output;
+ /* Immediately before the region to erase */
+ zassert_ok(write_flash_helper32(0x3E000 - 4, 0x5A5A5A5A));
+ zassert_ok(write_flash_helper32(0x3E000, 0x5A5AAA5A));
+ /* Immediately before the CBI region */
+ zassert_ok(write_flash_helper32(0x3F000 - 4, 0x5A5A5AAA));
+ /* Immediately after the CBI region */
+ zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5));
+
+ /* The CBI region */
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+
+ CHECK_CONSOLE_CMD("flasherase 0x3E000 0x1000", NULL, EC_SUCCESS);
+
+ /* These should remain untouched */
+ zassert_ok(read_flash_helper32(0x3E000 - 4, &output));
+ zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000, &output));
+ zassert_equal(output, 0xA5A5A5A5, "Got %08x", output);
+
+ /* These are within the erase region and should be reset to all FF */
+ zassert_ok(read_flash_helper32(0x3E000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x3F000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_erase__right)
+{
uint32_t output;
+ /* Immediately before the CBI region */
+ zassert_ok(write_flash_helper32(0x3F000 - 4, 0x5A5A5AAA));
+ /* Immediately after the CBI region */
+ zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5));
+ zassert_ok(write_flash_helper32(0x41000 - 4, 0x555A5A5A));
+ /* Immediately after the region to erase */
+ zassert_ok(write_flash_helper32(0x41000, 0x5A5A5A5A));
+
+ /* The CBI region */
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+
+ CHECK_CONSOLE_CMD("flasherase 0x40000 0x1000", NULL, EC_SUCCESS);
+
/* These should remain untouched */
+ zassert_ok(read_flash_helper32(0x3F000 - 4, &output));
+ zassert_equal(output, 0x5A5A5AAA, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x41000, &output));
+ zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
+
+ /* These are within the erase region and should be reset to all FF */
+ zassert_ok(read_flash_helper32(0x40000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x41000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_erase__cbi_overlap_1)
+{
+ uint32_t output;
+
+ /* Immediately before the region to erase */
+ zassert_ok(write_flash_helper32(0x20000 - 4, 0x5A5A5A5A));
+ /* Immediately after the region to erase */
+ zassert_ok(write_flash_helper32(0x50000, 0xA5A5A5A5));
+ /* Immediately before the CBI region */
+ zassert_ok(write_flash_helper32(0x3F000 - 4, 0x555A5A5A));
+ /* Immediately after the CBI region */
+ zassert_ok(write_flash_helper32(0x40000, 0xA5A555A5));
+
+ /* The CBI region */
+ zassert_ok(read_flash_helper32(0x3F000 - 4, &output));
+ zassert_equal(output, 0x555A5A5A, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000, &output));
+ zassert_equal(output, 0xA5A555A5, "Got %08x", output);
+
+ CHECK_CONSOLE_CMD("flasherase 0x20000 0x30000", NULL, EC_SUCCESS);
+
+ /* These should remain untouched */
+ zassert_ok(read_flash_helper32(0x20000 - 4, &output));
zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
zassert_ok(read_flash_helper32(0x50000, &output));
zassert_equal(output, 0xA5A5A5A5, "Got %08x", output);
/* These are within the erase region and should be reset to all FF */
+ zassert_ok(read_flash_helper32(0x20000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x3F000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
zassert_ok(read_flash_helper32(0x40000, &output));
zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
zassert_ok(read_flash_helper32(0x50000 - 4, &output));
zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
}
+ZTEST_USER(flash, test_console_cmd_flash_write__cbi_0)
+{
+ uint32_t output;
+
+ /* Immediately before the CBI region */
+ zassert_ok(write_flash_helper32(0x3F000 - 4, 0x555A5A5A));
+ zassert_ok(read_flash_helper32(0x3F000 - 4, &output));
+ zassert_equal(output, 0x555A5A5A, "Got %08x", output);
+ /* Immediately after the CBI region */
+ zassert_ok(write_flash_helper32(0x40000, 0xA5A555A5));
+ zassert_ok(read_flash_helper32(0x40000, &output));
+ zassert_equal(output, 0xA5A555A5, "Got %08x", output);
+
+ /* The CBI region */
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+
+ zassert_ok(write_flash_helper32(0x10000, 0x5A5A5A5A));
+ zassert_ok(read_flash_helper32(0x10000, &output));
+ zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
+
+ zassert_ok(write_flash_helper32(0x50000, 0x5AAA5A5A));
+ zassert_ok(read_flash_helper32(0x50000, &output));
+ zassert_equal(output, 0x5AAA5A5A, "Got %08x", output);
+
+ zassert_ok(write_flash_helper32(0x3F000, 0x5A5A5A5A));
+ zassert_ok(read_flash_helper32(0x3F000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+
+ zassert_ok(write_flash_helper32(0x40000 - 4, 0x5AAA5A5A));
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_write__cbi_1)
+{
+ uint32_t output;
+
+ /* At the start of CBI region */
+ zassert_ok(write_flash_helper32(0x3F000 - 2, 0x555A5A5A));
+ zassert_ok(read_flash_helper32(0x3F000 - 2, &output));
+ zassert_equal(output, 0xFFFF5A5A, "Got %08x", output);
+
+ /* At the end of CBI region */
+ zassert_ok(write_flash_helper32(0x40000 - 2, 0xA5A555A5));
+ zassert_ok(read_flash_helper32(0x40000 - 2, &output));
+ zassert_equal(output, 0xA5A5FFFF, "Got %08x", output);
+}
+#endif
+
ZTEST_USER(flash, test_console_cmd_flash_write__flash_locked)
{
/* Force write protection on */
diff --git a/zephyr/test/drivers/testcase.yaml b/zephyr/test/drivers/testcase.yaml
index 0373c0a97b..fb8d9b8fdc 100644
--- a/zephyr/test/drivers/testcase.yaml
+++ b/zephyr/test/drivers/testcase.yaml
@@ -482,3 +482,12 @@ tests:
- anx7452/usbc.dts
extra_configs:
- CONFIG_LINK_TEST_SUITE_ANX7452=y
+ drivers.flash_cbi:
+ extra_dtc_overlay_files:
+ - boards/native_posix.overlay
+ - cbi_flash/binman.dts
+ extra_configs:
+ - CONFIG_LINK_TEST_SUITE_FLASH=y
+ - CONFIG_PLATFORM_EC_CONSOLE_CMD_FLASH=y
+ - CONFIG_PLATFORM_EC_FLASH_SIZE_BYTES=0x80000
+ - CONFIG_PLATFORM_EC_CBI_FLASH=y