summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2017-10-03 18:28:57 -0700
committerCommit Bot <commit-bot@chromium.org>2020-08-07 21:16:39 +0000
commitb29d0808e22d30c3e9ce85dd31457ab8ff28dd2c (patch)
treeed5984d796061918350904ba20568944bc4f16ca
parent1c62421d797d31f2cbc05a5cfe6b9f1219f5484a (diff)
downloadchrome-ec-b29d0808e22d30c3e9ce85dd31457ab8ff28dd2c.tar.gz
CBI: Add unit test
This patch adds unit tests for Cros Board Info APIs. BUG=b:163038871 BRANCH=none TEST=buildall Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Change-Id: I7b2fdb2c4f13da12f8c0dc2ab526332cbd46d849 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2339393
-rw-r--r--board/host/board.c33
-rw-r--r--board/host/board.h8
-rw-r--r--common/cbi.c31
-rw-r--r--include/cros_board_info.h9
-rw-r--r--test/build.mk2
-rw-r--r--test/cbi.c195
-rw-r--r--test/cbi.tasklist9
7 files changed, 284 insertions, 3 deletions
diff --git a/board/host/board.c b/board/host/board.c
index 307ccac991..25abd9a0ad 100644
--- a/board/host/board.c
+++ b/board/host/board.c
@@ -6,6 +6,7 @@
#include "battery.h"
#include "button.h"
+#include "cros_board_info.h"
#include "extpower.h"
#include "gpio.h"
#include "host_command.h"
@@ -17,6 +18,7 @@
#include "power_button.h"
#include "spi.h"
#include "temp_sensor.h"
+#include "test_util.h"
#include "timer.h"
#include "util.h"
@@ -65,6 +67,8 @@ const struct i2c_port_t i2c_ports[] = {
{"lightbar", I2C_PORT_LIGHTBAR, 100, 0, 0},
#elif defined I2C_PORT_HOST_TCPC
{"tcpc", I2C_PORT_HOST_TCPC, 100, 0, 0},
+#elif defined I2C_PORT_EEPROM
+ {"eeprom", I2C_PORT_EEPROM, 100, 0, 0},
#endif
};
@@ -97,3 +101,32 @@ int board_get_entropy(void *buffer, int len)
return 1;
}
#endif
+
+static uint8_t eeprom[CBI_EEPROM_SIZE];
+
+int eeprom_i2c_xfer(int port, uint16_t addr_flags,
+ const uint8_t *out, int out_size,
+ uint8_t *in, int in_size, int flags)
+{
+ static int offset;
+
+ if (port != I2C_PORT_EEPROM || addr_flags != I2C_ADDR_EEPROM_FLAGS)
+ return EC_ERROR_INVAL;
+
+ if (out_size == 1 && (flags & I2C_XFER_START)) {
+ offset = *out;
+ } else {
+ if (offset + out_size > sizeof(eeprom))
+ return EC_ERROR_OVERFLOW;
+ memcpy(&eeprom[offset], out, out_size);
+ }
+
+ if (in) {
+ if (offset + in_size > sizeof(eeprom))
+ return EC_ERROR_OVERFLOW;
+ memcpy(in, &eeprom[offset], in_size);
+ }
+
+ return EC_SUCCESS;
+}
+DECLARE_TEST_I2C_XFER(eeprom_i2c_xfer);
diff --git a/board/host/board.h b/board/host/board.h
index 1e5d14476f..0eafedc2bc 100644
--- a/board/host/board.h
+++ b/board/host/board.h
@@ -12,6 +12,7 @@
/* Default-yes, override to no by including fake_battery module. */
#define CONFIG_BATTERY_PRESENT_CUSTOM
#undef CONFIG_CMD_PD
+#define CONFIG_CROS_BOARD_INFO
#define CONFIG_EXTPOWER_GPIO
#undef CONFIG_FMAP
#define CONFIG_POWER_BUTTON
@@ -86,4 +87,11 @@ enum {
#define CONFIG_RNG
void fps_event(enum gpio_signal signal);
+#define CONFIG_CRC8
+
+#define CONFIG_I2C
+#define CONFIG_I2C_MASTER
+#define I2C_PORT_EEPROM 0
+#define I2C_ADDR_EEPROM_FLAGS 0x50
+
#endif /* __CROS_EC_BOARD_H */
diff --git a/common/cbi.c b/common/cbi.c
index 5263407441..6918ad50dd 100644
--- a/common/cbi.c
+++ b/common/cbi.c
@@ -57,12 +57,12 @@ uint8_t *cbi_set_string(uint8_t *p, enum cbi_data_tag tag, const char *str)
return cbi_set_data(p, tag, str, strlen(str) + 1);
}
-struct cbi_data *cbi_find_tag(const void *cbi, enum cbi_data_tag tag)
+struct cbi_data *cbi_find_tag(const void *buf, enum cbi_data_tag tag)
{
struct cbi_data *d;
- const struct cbi_header *h = cbi;
+ const struct cbi_header *h = buf;
const uint8_t *p;
- for (p = h->data; p + sizeof(*d) < (uint8_t *)cbi + h->total_size;) {
+ for (p = h->data; p + sizeof(*d) < (uint8_t *)buf + h->total_size;) {
d = (struct cbi_data *)p;
if (d->tag == tag)
return d;
@@ -92,6 +92,26 @@ static int cached_read_result = EC_ERROR_CBI_CACHE_INVALID;
static uint8_t cbi[CBI_EEPROM_SIZE];
static struct cbi_header * const head = (struct cbi_header *)cbi;
+int cbi_create(void)
+{
+ struct cbi_header * const h = (struct cbi_header *)cbi;
+
+ memset(cbi, 0, sizeof(cbi));
+ memcpy(h->magic, cbi_magic, sizeof(cbi_magic));
+ h->total_size = sizeof(*h);
+ h->major_version = CBI_VERSION_MAJOR;
+ h->minor_version = CBI_VERSION_MINOR;
+ h->crc = cbi_crc8(h);
+ cached_read_result = EC_SUCCESS;
+
+ return EC_SUCCESS;
+}
+
+void cbi_invalidate_cache(void)
+{
+ cached_read_result = EC_ERROR_CBI_CACHE_INVALID;
+}
+
static int read_eeprom(uint8_t offset, uint8_t *in, int in_size)
{
return i2c_read_block(I2C_PORT_EEPROM, I2C_ADDR_EEPROM_FLAGS,
@@ -266,6 +286,11 @@ static int write_board_info(void)
return EC_SUCCESS;
}
+int cbi_write(void)
+{
+ return write_board_info();
+}
+
int cbi_get_board_version(uint32_t *ver)
{
uint8_t size = sizeof(*ver);
diff --git a/include/cros_board_info.h b/include/cros_board_info.h
index 25330779d5..57839ba4a5 100644
--- a/include/cros_board_info.h
+++ b/include/cros_board_info.h
@@ -144,4 +144,13 @@ struct cbi_data *cbi_find_tag(const void *cbi, enum cbi_data_tag tag);
*/
int cbi_board_override(enum cbi_data_tag tag, uint8_t *buf, uint8_t *size);
+#ifdef TEST_BUILD
+/**
+ * Test only declarations. Firmware shouldn't need them.
+ */
+int cbi_create(void);
+int cbi_write(void);
+void cbi_invalidate_cache(void);
+#endif
+
#endif /* __CROS_EC_CROS_BOARD_INFO_H */
diff --git a/test/build.mk b/test/build.mk
index 9f2e1eec33..c8fea42660 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -18,6 +18,7 @@ test-list-host += battery_get_params_smart
test-list-host += bklight_lid
test-list-host += bklight_passthru
test-list-host += button
+test-list-host += cbi
test-list-host += cec
test-list-host += charge_manager
test-list-host += charge_manager_drp_charging
@@ -121,6 +122,7 @@ battery_get_params_smart-y=battery_get_params_smart.o
bklight_lid-y=bklight_lid.o
bklight_passthru-y=bklight_passthru.o
button-y=button.o
+cbi-y=cbi.o
cec-y=cec.o
charge_manager-y=charge_manager.o
charge_manager_drp_charging-y=charge_manager.o
diff --git a/test/cbi.c b/test/cbi.c
new file mode 100644
index 0000000000..df57febb6f
--- /dev/null
+++ b/test/cbi.c
@@ -0,0 +1,195 @@
+/* Copyright 2020 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.
+ *
+ * Test CBI
+ */
+
+#include "common.h"
+#include "console.h"
+#include "cros_board_info.h"
+#include "gpio.h"
+#include "i2c.h"
+#include "test_util.h"
+#include "util.h"
+
+void before_test(void)
+{
+ cbi_create();
+ cbi_write();
+}
+
+static int test_uint8(void)
+{
+ uint8_t d8;
+ uint32_t d32;
+ uint8_t size;
+ const int tag = 0xff;
+
+ /* Set & get uint8_t */
+ d8 = 0xa5;
+ TEST_ASSERT(cbi_set_board_info(tag, &d8, sizeof(d8)) == EC_SUCCESS);
+ size = 1;
+ TEST_ASSERT(cbi_get_board_info(tag, &d8, &size) == EC_SUCCESS);
+ TEST_EQ(d8, 0xa5, "0x%x");
+ TEST_EQ(size, 1, "%x");
+
+ /* Size-up */
+ d32 = 0x1234abcd;
+ TEST_ASSERT(cbi_set_board_info(tag, (void *)&d32, sizeof(d32))
+ == EC_SUCCESS);
+ size = 4;
+ TEST_ASSERT(cbi_get_board_info(tag, (void *)&d32, &size) == EC_SUCCESS);
+ TEST_EQ(d32, 0x1234abcd, "0x%x");
+ TEST_EQ(size, 4, "%u");
+
+ return EC_SUCCESS;
+}
+
+static int test_uint32(void)
+{
+ uint8_t d8;
+ uint32_t d32;
+ uint8_t size;
+ const int tag = 0xff;
+
+ /* Set & get uint32_t */
+ d32 = 0x1234abcd;
+ TEST_ASSERT(cbi_set_board_info(tag, (void *)&d32, sizeof(d32))
+ == EC_SUCCESS);
+ size = 4;
+ TEST_ASSERT(cbi_get_board_info(tag, (void *)&d32, &size) == EC_SUCCESS);
+ TEST_EQ(d32, 0x1234abcd, "0x%x");
+ TEST_EQ(size, 4, "%u");
+
+ /* Size-down */
+ d8 = 0xa5;
+ TEST_ASSERT(cbi_set_board_info(tag, &d8, sizeof(d8)) == EC_SUCCESS);
+ size = 1;
+ TEST_ASSERT(cbi_get_board_info(tag, &d8, &size) == EC_SUCCESS);
+ TEST_EQ(d8, 0xa5, "0x%x");
+ TEST_EQ(size, 1, "%u");
+
+ return EC_SUCCESS;
+}
+
+static int test_string(void)
+{
+ const uint8_t string[] = "abcdefghijklmn";
+ uint8_t buf[32];
+ uint8_t size;
+ const int tag = 0xff;
+
+ /* Set & get string */
+ TEST_ASSERT(cbi_set_board_info(tag, string, sizeof(string))
+ == EC_SUCCESS);
+ size = sizeof(buf);
+ TEST_ASSERT(cbi_get_board_info(tag, buf, &size) == EC_SUCCESS);
+ TEST_ASSERT(strncmp(buf, string, sizeof(string)) == 0);
+ /* Size contains null byte */
+ TEST_EQ((size_t)size - 1, strlen(buf), "%zu");
+
+ /* Read buffer too small */
+ size = 4;
+ TEST_ASSERT(cbi_get_board_info(tag, buf, &size) == EC_ERROR_INVAL);
+
+ return EC_SUCCESS;
+}
+
+static int test_not_found(void)
+{
+ uint8_t d8;
+ const int tag = 0xff;
+ uint8_t size;
+
+ size = 1;
+ TEST_ASSERT(cbi_get_board_info(tag, &d8, &size) == EC_ERROR_UNKNOWN);
+
+ return EC_SUCCESS;
+}
+
+static int test_too_large(void)
+{
+ uint8_t buf[CBI_EEPROM_SIZE-1];
+ const int tag = 0xff;
+
+ /* Data too large */
+ memset(buf, 0xa5, sizeof(buf));
+ TEST_ASSERT(cbi_set_board_info(tag, buf, sizeof(buf))
+ == EC_ERROR_OVERFLOW);
+
+ return EC_SUCCESS;
+}
+
+static int test_all_tags(void)
+{
+ uint8_t d8;
+ uint32_t d32;
+
+ /* Populate all data and read out */
+ d8 = 0x12;
+ TEST_ASSERT(cbi_set_board_info(CBI_TAG_BOARD_VERSION, &d8, sizeof(d8))
+ == EC_SUCCESS);
+ TEST_ASSERT(cbi_set_board_info(CBI_TAG_OEM_ID, &d8, sizeof(d8))
+ == EC_SUCCESS);
+ TEST_ASSERT(cbi_set_board_info(CBI_TAG_SKU_ID, &d8, sizeof(d8))
+ == EC_SUCCESS);
+ TEST_ASSERT(cbi_set_board_info(CBI_TAG_MODEL_ID, &d8, sizeof(d8))
+ == EC_SUCCESS);
+ TEST_ASSERT(cbi_set_board_info(CBI_TAG_FW_CONFIG, &d8, sizeof(d8))
+ == EC_SUCCESS);
+ TEST_ASSERT(cbi_set_board_info(CBI_TAG_PCB_SUPPLIER, &d8, sizeof(d8))
+ == EC_SUCCESS);
+ TEST_ASSERT(cbi_get_board_version(&d32) == EC_SUCCESS);
+ TEST_EQ(d32, d8, "0x%x");
+ TEST_ASSERT(cbi_get_oem_id(&d32) == EC_SUCCESS);
+ TEST_EQ(d32, d8, "0x%x");
+ TEST_ASSERT(cbi_get_sku_id(&d32) == EC_SUCCESS);
+ TEST_EQ(d32, d8, "0x%x");
+ TEST_ASSERT(cbi_get_model_id(&d32) == EC_SUCCESS);
+ TEST_EQ(d32, d8, "0x%x");
+ TEST_ASSERT(cbi_get_fw_config(&d32) == EC_SUCCESS);
+ TEST_EQ(d32, d8, "0x%x");
+ TEST_ASSERT(cbi_get_pcb_supplier(&d32) == EC_SUCCESS);
+ TEST_EQ(d32, d8, "0x%x");
+
+ /* Write protect */
+ gpio_set_level(GPIO_WP, 1);
+ TEST_ASSERT(cbi_write() == EC_ERROR_ACCESS_DENIED);
+
+ return EC_SUCCESS;
+}
+
+static int test_bad_crc(void)
+{
+ uint8_t d8;
+ const int tag = 0xff;
+ uint8_t size;
+ int crc;
+
+ /* Bad CRC */
+ d8 = 0xa5;
+ TEST_ASSERT(cbi_set_board_info(tag, &d8, sizeof(d8)) == EC_SUCCESS);
+ i2c_read8(I2C_PORT_EEPROM, I2C_ADDR_EEPROM_FLAGS,
+ offsetof(struct cbi_header, crc), &crc);
+ i2c_write8(I2C_PORT_EEPROM, I2C_ADDR_EEPROM_FLAGS,
+ offsetof(struct cbi_header, crc), ++crc);
+ cbi_invalidate_cache();
+ size = sizeof(d8);
+ TEST_ASSERT(cbi_get_board_info(tag, &d8, &size) == EC_ERROR_UNKNOWN);
+
+ return EC_SUCCESS;
+}
+
+void run_test(int argc, char **argv)
+{
+ RUN_TEST(test_uint8);
+ RUN_TEST(test_uint32);
+ RUN_TEST(test_string);
+ RUN_TEST(test_not_found);
+ RUN_TEST(test_too_large);
+ RUN_TEST(test_all_tags);
+ RUN_TEST(test_bad_crc);
+
+ test_print_result();
+}
diff --git a/test/cbi.tasklist b/test/cbi.tasklist
new file mode 100644
index 0000000000..52c0d390ef
--- /dev/null
+++ b/test/cbi.tasklist
@@ -0,0 +1,9 @@
+/* Copyright 2020 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.
+ */
+
+/**
+ * See CONFIG_TASK_LIST in config.h for details.
+ */
+#define CONFIG_TEST_TASK_LIST /* No test task */