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
This commit is contained in:
Daisuke Nojiri 2017-10-03 18:28:57 -07:00 committed by Commit Bot
parent 1c62421d79
commit b29d0808e2
7 changed files with 284 additions and 3 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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

195
test/cbi.c Normal file
View File

@ -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();
}

9
test/cbi.tasklist Normal file
View File

@ -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 */