diff options
author | Madhurima Paruchuri <mparuchuri@google.com> | 2023-04-11 11:48:52 +0000 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-04-17 18:27:35 +0000 |
commit | 5093a223cb5d29197cd498c80c157c1e0b60c389 (patch) | |
tree | be37eaf99a690e71c36002ab4eed1fb533c0607b | |
parent | 74108a6ab365a110d70b4064ec2d99fa7ea9b73e (diff) | |
download | chrome-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.c | 85 | ||||
-rw-r--r-- | include/flash.h | 23 | ||||
-rw-r--r-- | zephyr/shim/include/cbi_flash.h | 28 | ||||
-rw-r--r-- | zephyr/shim/src/cbi/cbi_flash.c | 20 | ||||
-rw-r--r-- | zephyr/test/drivers/cbi_flash/src/cbi_flash.c | 8 | ||||
-rw-r--r-- | zephyr/test/drivers/flash/src/flash.c | 279 | ||||
-rw-r--r-- | zephyr/test/drivers/testcase.yaml | 9 |
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 |