diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 05f66f700ca..8363ca73195 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -57,6 +57,12 @@ enum { SYSCON_COUNT }; +/** + */ +enum cros_ec_test_t { + CROSECT_BREAK_HELLO = BIT(1), +}; + /** * sandbox_i2c_set_test_mode() - set test mode for running unit tests * @@ -260,4 +266,12 @@ uint sandbox_pci_read_bar(u32 barval, int type, uint size); */ void sandbox_set_enable_memio(bool enable); +/** + * sandbox_cros_ec_set_test_flags() - Set behaviour for testing purposes + * + * @dev: Device to check + * @flags: Flags to control behaviour (CROSECT_...) + */ +void sandbox_cros_ec_set_test_flags(struct udevice *dev, uint flags); + #endif diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index f03b7d55d64..013c67e0464 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -591,6 +591,25 @@ static int cros_ec_invalidate_hash(struct udevice *dev) return 0; } +int cros_ec_hello(struct udevice *dev, uint *handshakep) +{ + struct ec_params_hello req; + struct ec_response_hello *resp; + + req.in_data = 0x12345678; + if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), + (uint8_t **)&resp, sizeof(*resp)) < 0) + return -EIO; + if (resp->out_data != req.in_data + 0x01020304) { + printf("Received invalid handshake %x\n", resp->out_data); + if (handshakep) + *handshakep = req.in_data; + return -ENOTSYNC; + } + + return 0; +} + int cros_ec_reboot(struct udevice *dev, enum ec_reboot_cmd cmd, uint8_t flags) { struct ec_params_reboot_ec p; @@ -738,7 +757,6 @@ static int cros_ec_check_version(struct udevice *dev) { struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); struct ec_params_hello req; - struct ec_response_hello *resp; struct dm_cros_ec_ops *ops; int ret; @@ -767,14 +785,14 @@ static int cros_ec_check_version(struct udevice *dev) /* Try sending a version 3 packet */ cdev->protocol_version = 3; req.in_data = 0; - if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), - (uint8_t **)&resp, sizeof(*resp)) > 0) + ret = cros_ec_hello(dev, NULL); + if (!ret || ret == -ENOTSYNC) return 0; /* Try sending a version 2 packet */ cdev->protocol_version = 2; - if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), - (uint8_t **)&resp, sizeof(*resp)) > 0) + ret = cros_ec_hello(dev, NULL); + if (!ret || ret == -ENOTSYNC) return 0; /* @@ -790,18 +808,16 @@ static int cros_ec_check_version(struct udevice *dev) int cros_ec_test(struct udevice *dev) { - struct ec_params_hello req; - struct ec_response_hello *resp; + uint out_data; + int ret; - req.in_data = 0x12345678; - if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), - (uint8_t **)&resp, sizeof(*resp)) < sizeof(*resp)) { + ret = cros_ec_hello(dev, &out_data); + if (ret == -ENOTSYNC) { + printf("Received invalid handshake %x\n", out_data); + return ret; + } else if (ret) { printf("ec_command_inptr() returned error\n"); - return -1; - } - if (resp->out_data != req.in_data + 0x01020304) { - printf("Received invalid handshake %x\n", resp->out_data); - return -1; + return ret; } return 0; diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index 9fd6cc2086c..1922a9c1b96 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -18,6 +18,7 @@ #include #include #include +#include #include /* @@ -73,6 +74,7 @@ struct ec_keymatrix_entry { * @matrix: Information about keyboard matrix * @keyscan: Current keyscan information (bit set for each row/column pressed) * @recovery_req: Keyboard recovery requested + * @test_flags: Flags that control behaviour for tests */ struct ec_state { u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2]; @@ -84,6 +86,7 @@ struct ec_state { struct ec_keymatrix_entry *matrix; /* the key matrix info */ uint8_t keyscan[KEYBOARD_COLS]; bool recovery_req; + uint test_flags; } s_state, *g_state; /** @@ -295,6 +298,8 @@ static int process_cmd(struct ec_state *ec, struct ec_response_hello *resp = resp_data; resp->out_data = req->in_data + 0x01020304; + if (ec->test_flags & CROSECT_BREAK_HELLO) + resp->out_data++; len = sizeof(*resp); break; } @@ -518,6 +523,13 @@ void cros_ec_check_keyboard(struct udevice *dev) } } +void sandbox_cros_ec_set_test_flags(struct udevice *dev, uint flags) +{ + struct ec_state *ec = dev_get_priv(dev); + + ec->test_flags = flags; +} + int cros_ec_probe(struct udevice *dev) { struct ec_state *ec = dev_get_priv(dev); diff --git a/include/cros_ec.h b/include/cros_ec.h index f187bd0d4b5..f57e0cc4501 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -497,4 +497,15 @@ int cros_ec_get_lid_shutdown_mask(struct udevice *dev); */ int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable); +/** + * cros_ec_hello() - Send a hello message + * + * Sends a message with a fixed input value and checks that the expected output + * value is received + * + * @dev: CROS-EC device + * @handshakep: If non-NULL, returns received handshake value on error + * @return 0 if OK, -ve on error + */ +int cros_ec_hello(struct udevice *dev, uint *handshakep); #endif diff --git a/test/dm/Makefile b/test/dm/Makefile index 46e076ed099..afcabfacc1b 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_BLK) += blk.o obj-$(CONFIG_BUTTON) += button.o obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o obj-$(CONFIG_CLK) += clk.o clk_ccf.o +obj-$(CONFIG_CROS_EC) += cros_ec.o obj-$(CONFIG_DEVRES) += devres.o obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o obj-$(CONFIG_DM_ETH) += eth.o diff --git a/test/dm/cros_ec.c b/test/dm/cros_ec.c new file mode 100644 index 00000000000..823245ca70b --- /dev/null +++ b/test/dm/cros_ec.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2021 Google LLC + */ + +#include +#include +#include +#include +#include +#include + +static int dm_test_cros_ec_hello(struct unit_test_state *uts) +{ + struct udevice *dev; + uint val; + + ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev)); + + ut_assertok(cros_ec_hello(dev, NULL)); + + val = 0xdead1357; + ut_assertok(cros_ec_hello(dev, &val)); + ut_asserteq(0xdead1357, val); + + sandbox_cros_ec_set_test_flags(dev, CROSECT_BREAK_HELLO); + ut_asserteq(-ENOTSYNC, cros_ec_hello(dev, &val)); + ut_asserteq(0x12345678, val); + + return 0; +} +DM_TEST(dm_test_cros_ec_hello, UT_TESTF_SCAN_FDT);