From 974b9dc6704522eebb57a806dfe240cb5516b2d1 Mon Sep 17 00:00:00 2001 From: Roger Wang Date: Fri, 19 Jul 2024 09:54:28 +0800 Subject: [PATCH] pm: enable unit test HSD: 15015857053 This commit is to enable unit test for PM D0ix flow. Signed-off-by: Roger Wang --- bsp_sedi/soc/intel_ish/pm/ish_pm.c | 9 + zephyr/iut_test/prj.conf | 17 ++ zephyr/iut_test/src/shell_iut.c | 24 ++- zephyr/iut_test/test_zephyr/CMakeLists.txt | 4 + zephyr/iut_test/test_zephyr/pm/test_pm.c | 199 +++++++++++++++++++++ 5 files changed, 245 insertions(+), 8 deletions(-) create mode 100644 zephyr/iut_test/test_zephyr/pm/test_pm.c diff --git a/bsp_sedi/soc/intel_ish/pm/ish_pm.c b/bsp_sedi/soc/intel_ish/pm/ish_pm.c index 375cd1f..df7b2a5 100644 --- a/bsp_sedi/soc/intel_ish/pm/ish_pm.c +++ b/bsp_sedi/soc/intel_ish/pm/ish_pm.c @@ -14,6 +14,7 @@ #include #include #include +#include /* defined in link script: soc/x86/intel_ish/scripts/ish_linker.ld */ extern uint32_t __text_region_start; @@ -742,3 +743,11 @@ void command_idle_stats(void) PM_LOG(" error counts: %u\n", aon_share->error_count); } } + +/** + * Reset low power idle statistics + */ +void reset_pm_stats(void) +{ + memset(&pm_stats, 0, sizeof(pm_stats)); +} diff --git a/zephyr/iut_test/prj.conf b/zephyr/iut_test/prj.conf index c7d3216..98019ab 100644 --- a/zephyr/iut_test/prj.conf +++ b/zephyr/iut_test/prj.conf @@ -4,6 +4,14 @@ # SPDX-License-Identifier: Apache-2.0 # +# kernel +CONFIG_TICKLESS_KERNEL=y +CONFIG_TIMESLICING=n + +# stack +CONFIG_MAIN_STACK_SIZE=4096 +CONFIG_IDLE_STACK_SIZE=1024 + CONFIG_MAIN_THREAD_PRIORITY=14 # basic @@ -45,3 +53,12 @@ CONFIG_GPIO=y CONFIG_SPI=y CONFIG_ASSERT=y + +# uart +CONFIG_SERIAL=y +CONFIG_UART_SEDI=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# PM +CONFIG_PM=y +CONFIG_PM_DEVICE=y diff --git a/zephyr/iut_test/src/shell_iut.c b/zephyr/iut_test/src/shell_iut.c index 55a0bc8..128e0c3 100644 --- a/zephyr/iut_test/src/shell_iut.c +++ b/zephyr/iut_test/src/shell_iut.c @@ -1,13 +1,14 @@ /* - * Copyright (c) 2023 Intel Corporation. + * Copyright (c) 2023-2024 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include #include -#include "iut.h" #include +#include +#include "iut.h" extern int iut_trigger(size_t argc, char **argv); @@ -56,8 +57,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_iut, SHELL_CMD_REGISTER(iut, &sub_iut, "IUT commands", NULL); -#ifdef _CONFIG_PM -static const struct shell_uart *sh_uart; +#ifdef CONFIG_PM +static SHELL_UART_STRUCT * sh_uart; void iut_shell_suspend(void) { @@ -71,22 +72,29 @@ void iut_shell_suspend(void) } /*get shell uart backend*/ - sh_uart = (const struct shell_uart *)shell_ptr->iface->ctx; + sh_uart = (SHELL_UART_STRUCT *)shell_ptr->iface->ctx; if (sh_uart == NULL) { iut_print("get shell UART pointer error!!!\n"); return; } } - - k_timer_stop(sh_uart->timer); +#ifdef CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN + uart_irq_rx_disable(sh_uart->common.dev); +#else + k_timer_stop(&sh_uart->rx_timer); +#endif } void iut_shell_resume(void) { if (sh_uart) { - k_timer_start(sh_uart->timer, K_NO_WAIT, +#ifdef CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN + uart_irq_rx_enable(sh_uart->common.dev); +#else + k_timer_start(&sh_uart->rx_timer, K_NO_WAIT, K_MSEC(CONFIG_SHELL_BACKEND_SERIAL_RX_POLL_PERIOD)); +#endif } } #endif diff --git a/zephyr/iut_test/test_zephyr/CMakeLists.txt b/zephyr/iut_test/test_zephyr/CMakeLists.txt index 125ea56..8ffc8e1 100644 --- a/zephyr/iut_test/test_zephyr/CMakeLists.txt +++ b/zephyr/iut_test/test_zephyr/CMakeLists.txt @@ -15,5 +15,9 @@ if(CONFIG_GPIO_SEDI) target_sources(app PRIVATE gpio/test_gpio.c) endif() +if(CONFIG_PM) + target_sources(app PRIVATE pm/test_pm.c) +endif() + target_sources(app PRIVATE x86/test_fatal.c) target_sources(app PRIVATE timer/test_sys_clock.c) diff --git a/zephyr/iut_test/test_zephyr/pm/test_pm.c b/zephyr/iut_test/test_zephyr/pm/test_pm.c new file mode 100644 index 0000000..c6a11fd --- /dev/null +++ b/zephyr/iut_test/test_zephyr/pm/test_pm.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2021-2024 Intel Corporation. All Rights Reserved. + * + * This software and the related documents are Intel copyrighted materials, + * and your use of them is governed by the express license under which they + * were provided to you ("License"). Unless the License provides otherwise, + * you may not use, modify, copy, publish, distribute, disclose or transmit + * this software or the related documents without Intel's prior written + * permission. + * + * This software and the related documents are provided as is, with no express + * or implied warranties, other than those that are expressly stated in the + * License. + */ + +#include +#include +#include +#include "iut.h" + +#define TEST_PM_D0I0_MS_SLEEP (1) +#define TEST_PM_D0I1_MS_SLEEP (3) +#define TEST_PM_D0I2_MS_SLEEP (1000) +#define TEST_PM_D0I3_MS_SLEEP (5000) + +#define PM_ENTER_D0 0 +#define PM_ENTER_D0i1 1 +#define PM_ENTER_D0i2 2 +#define PM_ENTER_D0i3 3 + +extern void iut_shell_suspend(void); +extern void iut_shell_resume(void); +extern void reset_pm_stats(void); +extern void command_idle_stats(void); + +/* usage: iut_run test_pm [pm level: 0-D0, 1-D0i1, 2-D0i2, 3-D0i3] [ms_sleep]*/ +static int test_pm_d0ix(int argc, char **argv); +DEFINE_IUT_CASE(pm_d0ix, test_pm, IUT_ATTRI_NONE); + +static int test_pm_d0i3(int argc, char **argv); +DEFINE_IUT_CASE(pm_d0i3, test_pm, IUT_ATTRI_AUTORUN); + +static int test_pm_d0i2(int argc, char **argv); +DEFINE_IUT_CASE(pm_d0i2, test_pm, IUT_ATTRI_NONE); + +static int test_pm_d0i1(int argc, char **argv); +DEFINE_IUT_CASE(pm_d0i1, test_pm, IUT_ATTRI_NONE); + +static int test_pm_d0(int argc, char **argv); +DEFINE_IUT_CASE(pm_d0, test_pm, IUT_ATTRI_NONE); + +static int test_pm_stress(int argc, char **argv); +DEFINE_IUT_CASE(pm_stress, test_pm, IUT_ATTRI_NONE); + +static const char *const pm_level_str[PM_ENTER_D0i3 + 1] = { + "D0", + "D0i1", + "D0i2", + "D0i3", +}; + +static inline void clear_pm_stats(void) +{ + reset_pm_stats(); +} + +static void dump_pm_stats(uint32_t ms_sleep) +{ + ARG_UNUSED(ms_sleep); + command_idle_stats(); +} + +static void _test_pm(uint32_t pm_level, uint32_t ms_sleep) +{ + clear_pm_stats(); + + iut_case_print("test [%s]: going to sleep %u ms\n", + pm_level_str[pm_level], ms_sleep); + + iut_shell_suspend(); + + k_msleep(ms_sleep); + + iut_shell_resume(); + + dump_pm_stats(ms_sleep); +} + +static inline int _test_pm_d0(uint32_t ms_sleep) +{ + _test_pm(PM_ENTER_D0, ms_sleep); + TEST_ASSERT_TRUE(1); + + return IUT_ERR_OK; +} + +static int test_pm_d0(int argc, char **argv) +{ + return _test_pm_d0(TEST_PM_D0I0_MS_SLEEP); +} + +static inline int _test_pm_d0i1(uint32_t ms_sleep) +{ + _test_pm(PM_ENTER_D0i1, ms_sleep); + TEST_ASSERT_TRUE(1); + + return IUT_ERR_OK; +} + +static int test_pm_d0i1(int argc, char **argv) +{ + return _test_pm_d0i1(TEST_PM_D0I1_MS_SLEEP); +} + +static inline int _test_pm_d0i2(uint32_t ms_sleep) +{ + _test_pm(PM_ENTER_D0i2, ms_sleep); + TEST_ASSERT_TRUE(1); + + return IUT_ERR_OK; +} + +static int test_pm_d0i2(int argc, char **argv) +{ + return _test_pm_d0i2(TEST_PM_D0I2_MS_SLEEP); +} + +static inline int _test_pm_d0i3(uint32_t ms_sleep) +{ + _test_pm(PM_ENTER_D0i3, ms_sleep); + TEST_ASSERT_TRUE(1); + + return IUT_ERR_OK; +} + +static int test_pm_d0i3(int argc, char **argv) +{ + return _test_pm_d0i3(TEST_PM_D0I3_MS_SLEEP); +} + +static int test_pm_d0ix(int argc, char **argv) +{ + uint32_t ms_sleep = TEST_PM_D0I3_MS_SLEEP; + uint32_t pm_level = PM_ENTER_D0i3; + + if (argc) { + pm_level = (uint32_t)strtoul(argv[0], NULL, 0); + } + if (argc > 1) { + ms_sleep = (uint32_t)strtoul(argv[1], NULL, 0); + } + + switch (pm_level) { + case PM_ENTER_D0: + _test_pm_d0(ms_sleep); + break; + case PM_ENTER_D0i1: + _test_pm_d0i1(ms_sleep); + break; + case PM_ENTER_D0i2: + _test_pm_d0i2(ms_sleep); + break; + case PM_ENTER_D0i3: + _test_pm_d0i3(ms_sleep); + break; + default: + iut_case_print("wrong pm_level %u out of (0 - 3), exit\n", + pm_level); + TEST_ASSERT_TRUE(0); + } + + return IUT_ERR_OK; +} + +typedef int (*pm_test_fn)(int argc, char **argv); +static pm_test_fn pm_test_funcs[] = { + &test_pm_d0i1, + &test_pm_d0i2, + &test_pm_d0i3, +}; + +#define PM_TEST_FUNC_NUM (ARRAY_SIZE(pm_test_funcs)) + +static int test_pm_stress(int argc, char **argv) +{ + uint32_t round = 5; + + if (argc) { + round = (uint32_t)strtoul(argv[0], NULL, 0); + } + while (round--) { + uint32_t idx = (uint32_t)z_tsc_read() % PM_TEST_FUNC_NUM; + + k_msleep(1000); + pm_test_funcs[idx](0, NULL); + } + + return IUT_ERR_OK; +}