cros_ec: Add a function for the hello message

This is used several times in this file. Put it in a function to avoid
code duplication.

Also add a test for this function. There are no cros_ec tests at present,
so it is time to update the code.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2021-01-16 14:52:22 -07:00
parent 3096ee866e
commit d8e9a93895
6 changed files with 101 additions and 15 deletions

View File

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

View File

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

View File

@ -18,6 +18,7 @@
#include <asm/malloc.h>
#include <asm/state.h>
#include <asm/sdl.h>
#include <asm/test.h>
#include <linux/input.h>
/*
@ -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);

View File

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

View File

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

32
test/dm/cros_ec.c Normal file
View File

@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2021 Google LLC
*/
#include <common.h>
#include <cros_ec.h>
#include <dm.h>
#include <asm/test.h>
#include <dm/test.h>
#include <test/ut.h>
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);