summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Michalec <tm@semihalf.com>2021-11-25 14:19:22 +0100
committerCommit Bot <commit-bot@chromium.org>2021-12-01 13:39:13 +0000
commitfbacc63332b8fbb6662c717a575d824b24730365 (patch)
treed0a2513b707e7456023cacbfbead76fbcb8e666e
parent98ee126608f425ac4746df188dfea086f5e6c84b (diff)
downloadchrome-ec-fbacc63332b8fbb6662c717a575d824b24730365.tar.gz
zephyr: drivers: Add unit test for exiting G3
Add unit tests for exiting G3 using chipset_exit_hard_off() function and reboot AP on G3 host command. BUG=b:206903370 BRANCH=none TEST=zmake configure --test zephyr/test/drivers Signed-off-by: Tomasz Michalec <tm@semihalf.com> Change-Id: Idafe367da67ff4b6f5ec75aeee16549e14321122 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3302212 Tested-by: Tomasz Michalec <tmichalec@google.com> Commit-Queue: Tomasz Michalec <tmichalec@google.com> Reviewed-by: Fabio Baltieri <fabiobaltieri@google.com>
-rw-r--r--zephyr/test/drivers/include/stubs.h11
-rw-r--r--zephyr/test/drivers/src/bb_retimer.c16
-rw-r--r--zephyr/test/drivers/src/power_common.c122
-rw-r--r--zephyr/test/drivers/src/stubs.c46
-rw-r--r--zephyr/test/drivers/src/usb_mux.c8
5 files changed, 174 insertions, 29 deletions
diff --git a/zephyr/test/drivers/include/stubs.h b/zephyr/test/drivers/include/stubs.h
index 448d6c883b..0e96b777e1 100644
--- a/zephyr/test/drivers/include/stubs.h
+++ b/zephyr/test/drivers/include/stubs.h
@@ -13,7 +13,16 @@ enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_COUNT };
/* Structure used by usb_mux test. It is part of usb_muxes chain. */
extern struct usb_mux usbc1_virtual_usb_mux;
-void set_mock_power_state(enum power_state state);
+/**
+ * @brief Set state which should be returned by power_handle_state() and wake
+ * chipset task to immediately change state
+ *
+ * @param force If true @p state will be used as return for power_handle_state()
+ * and will wake up chipset task. If false argument of
+ * power_handle_state() will be used as return value
+ * @param state Power state to use when @p force is true
+ */
+void force_power_state(bool force, enum power_state state);
/**
* @brief Set product ID that should be returned by board_get_ps8xxx_product_id
diff --git a/zephyr/test/drivers/src/bb_retimer.c b/zephyr/test/drivers/src/bb_retimer.c
index 39af8da2c3..02a712aacb 100644
--- a/zephyr/test/drivers/src/bb_retimer.c
+++ b/zephyr/test/drivers/src/bb_retimer.c
@@ -441,13 +441,7 @@ static void test_bb_init(void)
emul = bb_emul_get(BB_RETIMER_ORD);
/* Set AP to normal state and wait for chipset task */
- set_mock_power_state(POWER_S0);
- /*
- * TODO(b/201420132) - setting power state requires to wake up
- * TASK_ID_CHIPSET Sleep is required to run chipset task before
- * continuing with test
- */
- k_msleep(1);
+ power_set_state(POWER_S0);
/* Setup emulator fail on read */
i2c_common_emul_set_read_fail_reg(emul, BB_RETIMER_REG_VENDOR_ID);
@@ -508,13 +502,7 @@ static void test_bb_init(void)
NULL);
/* Set AP to off state and wait for chipset task */
- set_mock_power_state(POWER_G3);
- /*
- * TODO(b/201420132) - setting power state requires to wake up
- * TASK_ID_CHIPSET Sleep is required to run chipset task before
- * continuing with test
- */
- k_msleep(1);
+ power_set_state(POWER_G3);
/* With AP off, init should fail and pins should be unset */
zassert_equal(EC_ERROR_NOT_POWERED,
diff --git a/zephyr/test/drivers/src/power_common.c b/zephyr/test/drivers/src/power_common.c
index 5ec268f2a5..fe056397d3 100644
--- a/zephyr/test/drivers/src/power_common.c
+++ b/zephyr/test/drivers/src/power_common.c
@@ -157,12 +157,130 @@ static void test_power_chipset_in_or_transitioning_to_state(void)
}
}
+/** Test using chipset_exit_hard_off() in different power states */
+static void test_power_exit_hard_off(void)
+{
+ /* Force initial state */
+ force_power_state(true, POWER_G3);
+ zassert_equal(POWER_G3, power_get_state(), NULL);
+
+ /* Stop forcing state */
+ force_power_state(false, 0);
+
+ /* Test after exit hard off, we reach G3S5 */
+ chipset_exit_hard_off();
+ /*
+ * TODO(b/201420132) - chipset_exit_hard_off() is waking up
+ * TASK_ID_CHIPSET Sleep is required to run chipset task before
+ * continuing with test
+ */
+ k_msleep(1);
+ zassert_equal(POWER_G3S5, power_get_state(), NULL);
+
+ /* Go back to G3 and check we stay there */
+ force_power_state(true, POWER_G3);
+ force_power_state(false, 0);
+ zassert_equal(POWER_G3, power_get_state(), NULL);
+
+ /* Exit G3 again */
+ chipset_exit_hard_off();
+ /* TODO(b/201420132) - see comment above */
+ k_msleep(1);
+ zassert_equal(POWER_G3S5, power_get_state(), NULL);
+
+ /* Go to S5G3 */
+ force_power_state(true, POWER_S5G3);
+ zassert_equal(POWER_S5G3, power_get_state(), NULL);
+
+ /* Test exit hard off in S5G3 -- should immedietly exit G3 */
+ chipset_exit_hard_off();
+ /* Go back to G3 and check we exit it to G3S5 */
+ force_power_state(true, POWER_G3);
+ zassert_equal(POWER_G3S5, power_get_state(), NULL);
+
+ /* Test exit hard off is cleared on entering S5 */
+ chipset_exit_hard_off();
+ force_power_state(true, POWER_S5);
+ zassert_equal(POWER_S5, power_get_state(), NULL);
+ /* Go back to G3 and check we stay in G3 */
+ force_power_state(true, POWER_G3);
+ force_power_state(false, 0);
+ zassert_equal(POWER_G3, power_get_state(), NULL);
+
+ /* Test exit hard off doesn't work on other states */
+ force_power_state(true, POWER_S5S3);
+ force_power_state(false, 0);
+ zassert_equal(POWER_S5S3, power_get_state(), NULL);
+ chipset_exit_hard_off();
+ /* TODO(b/201420132) - see comment above */
+ k_msleep(1);
+
+ /* Go back to G3 and check we stay in G3 */
+ force_power_state(true, POWER_G3);
+ force_power_state(false, 0);
+ zassert_equal(POWER_G3, power_get_state(), NULL);
+}
+
+/* Test reboot ap on g3 host command is triggering reboot */
+static void test_power_reboot_ap_at_g3(void)
+{
+ struct ec_params_reboot_ap_on_g3_v1 params;
+ struct host_cmd_handler_args args = {
+ .command = EC_CMD_REBOOT_AP_ON_G3,
+ .version = 0,
+ .send_response = stub_send_response_callback,
+ .params = &params,
+ .params_size = sizeof(params),
+ };
+ int offset_for_still_in_g3_test;
+ int delay_ms;
+
+ /* Force initial state S0 */
+ force_power_state(true, POWER_S0);
+ zassert_equal(POWER_S0, power_get_state(), NULL);
+
+ /* Test version 0 (no delay argument) */
+ zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL);
+
+ /* Go to G3 and check if reboot is triggered */
+ force_power_state(true, POWER_G3);
+ zassert_equal(POWER_G3S5, power_get_state(), NULL);
+
+ /* Test version 1 (with delay argument) */
+ args.version = 1;
+ delay_ms = 3000;
+ params.reboot_ap_at_g3_delay = delay_ms / 1000; /* in seconds */
+ zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL);
+
+ /* Go to G3 and check if reboot is triggered after delay */
+ force_power_state(true, POWER_G3);
+ force_power_state(false, 0);
+ zassert_equal(POWER_G3, power_get_state(), NULL);
+ /*
+ * Arbitrary chosen offset before end of reboot delay to check if G3
+ * state wasn't left too soon
+ */
+ offset_for_still_in_g3_test = 50;
+ k_msleep(delay_ms - offset_for_still_in_g3_test);
+ /* Test if still in G3 */
+ zassert_equal(POWER_G3, power_get_state(), NULL);
+ /*
+ * power_common_state() use for loop with 100ms sleeps. msleep() wait at
+ * least specified time, so wait 10% longer than specified delay to take
+ * this into account.
+ */
+ k_msleep(offset_for_still_in_g3_test + delay_ms / 10);
+ /* Test if reboot is triggered */
+ zassert_equal(POWER_G3S5, power_get_state(), NULL);
+}
+
void test_suite_power_common(void)
{
ztest_test_suite(power_common,
ztest_unit_test(test_power_chipset_in_state),
ztest_unit_test(
- test_power_chipset_in_or_transitioning_to_state)
- );
+ test_power_chipset_in_or_transitioning_to_state),
+ ztest_unit_test(test_power_exit_hard_off),
+ ztest_unit_test(test_power_reboot_ap_at_g3));
ztest_run_test_suite(power_common);
}
diff --git a/zephyr/test/drivers/src/stubs.c b/zephyr/test/drivers/src/stubs.c
index 4565ed5953..f90412089c 100644
--- a/zephyr/test/drivers/src/stubs.c
+++ b/zephyr/test/drivers/src/stubs.c
@@ -331,17 +331,53 @@ enum power_state power_chipset_init(void)
return POWER_G3;
}
-enum power_state mock_state = POWER_G3;
+static enum power_state forced_state;
+static bool force_state;
-void set_mock_power_state(enum power_state state)
+void force_power_state(bool force, enum power_state state)
{
- mock_state = state;
- task_wake(TASK_ID_CHIPSET);
+ forced_state = state;
+ force_state = force;
+
+ if (force) {
+ task_wake(TASK_ID_CHIPSET);
+ /*
+ * TODO(b/201420132) - setting power state requires to wake up
+ * TASK_ID_CHIPSET Sleep is required to run chipset task before
+ * continuing with test
+ */
+ k_msleep(1);
+ }
}
enum power_state power_handle_state(enum power_state state)
{
- return mock_state;
+ switch (state) {
+ case POWER_G3S5:
+ case POWER_S5S3:
+ case POWER_S3S0:
+ case POWER_S0S3:
+ case POWER_S3S5:
+ case POWER_S5G3:
+#ifdef CONFIG_POWER_S0IX
+ case POWER_S0ixS0:
+ case POWER_S0S0ix:
+#endif
+ /*
+ * Wait for event in transition states to prevent dead loop in
+ * chipset task
+ */
+ task_wait_event(-1);
+ break;
+ default:
+ break;
+ }
+
+ if (force_state) {
+ state = forced_state;
+ }
+
+ return state;
}
void chipset_reset(enum chipset_shutdown_reason reason)
diff --git a/zephyr/test/drivers/src/usb_mux.c b/zephyr/test/drivers/src/usb_mux.c
index a3d6b1c278..ea6483f406 100644
--- a/zephyr/test/drivers/src/usb_mux.c
+++ b/zephyr/test/drivers/src/usb_mux.c
@@ -342,13 +342,7 @@ static int mock_board_set(const struct usb_mux *me, mux_state_t mux_state)
static void test_usb_mux_init(void)
{
/* Set AP to normal state to init BB retimer */
- set_mock_power_state(POWER_S0);
- /*
- * TODO(b/201420132) - setting power state requires to wake up
- * TASK_ID_CHIPSET Sleep is required to run chipset task before
- * continuing with test
- */
- k_msleep(1);
+ power_set_state(POWER_S0);
/* Test successful initialisation */
setup_ztest_proxy_init(0, 2, EC_SUCCESS);