diff --git a/src/libosd/cl_scm.c b/src/libosd/cl_scm.c index d872822..036aa9a 100644 --- a/src/libosd/cl_scm.c +++ b/src/libosd/cl_scm.c @@ -52,6 +52,17 @@ osd_result osd_cl_scm_cpus_stop(struct osd_hostmod_ctx *hostmod_ctx, /** * Read the system information from the device, as stored in the SCM */ +API_EXPORT +osd_result osd_cl_scm_system_reset(struct osd_hostmod_ctx *hostmod_ctx, + unsigned int subnet_addr, bool reset) +{ + return osd_hostmod_reg_setbit(hostmod_ctx, OSD_REG_SCM_SYSRST_SYS_RST_BIT, + reset, + get_scm_diaddr(subnet_addr), + OSD_REG_SCM_SYSRST, 16, + OSD_HOSTMOD_BLOCKING); +} + API_EXPORT osd_result osd_cl_scm_get_subnetinfo(struct osd_hostmod_ctx *hostmod_ctx, unsigned int subnet_addr, diff --git a/src/libosd/include/osd/cl_scm.h b/src/libosd/include/osd/cl_scm.h index 2d04d40..8979d1e 100644 --- a/src/libosd/include/osd/cl_scm.h +++ b/src/libosd/include/osd/cl_scm.h @@ -54,6 +54,18 @@ osd_result osd_cl_scm_cpus_start(struct osd_hostmod_ctx *hostmod_ctx, osd_result osd_cl_scm_cpus_stop(struct osd_hostmod_ctx *hostmod_ctx, unsigned int subnet_addr); +/** + * Set or unset the system reset in a given subnet + * + * The exact meaning of "system reset" is platform-dependent. + * + * @param hostmod_ctx hostmodule context + * @param subnet_addr target subnet + * @param reset Value of the reset: 1 to set the reset signal, 0 to unset it + */ +osd_result osd_cl_scm_system_reset(struct osd_hostmod_ctx *hostmod_ctx, + unsigned int subnet_addr, bool reset); + /** * Get a description of a given subnet from the SCM */ diff --git a/tests/unit/check_cl_scm.c b/tests/unit/check_cl_scm.c index d57bd82..21f5648 100644 --- a/tests/unit/check_cl_scm.c +++ b/tests/unit/check_cl_scm.c @@ -80,6 +80,48 @@ START_TEST(test_cpus_stop) } END_TEST +START_TEST(test_system_reset_set) +{ + osd_result rv; + + uint16_t old_reg_val = 0xDE0C; + uint16_t new_reg_val = 0xDE0D; + + mock_hostmod_expect_reg_read16(old_reg_val, + osd_diaddr_build(subnet_addr, 0), + OSD_REG_SCM_SYSRST, + OSD_OK); + mock_hostmod_expect_reg_write16(new_reg_val, + osd_diaddr_build(subnet_addr, 0), + OSD_REG_SCM_SYSRST, + OSD_OK); + + rv = osd_cl_scm_system_reset(mock_hostmod_get_ctx(), subnet_addr, 1); + ck_assert_int_eq(rv, OSD_OK); +} +END_TEST + +START_TEST(test_system_reset_unset) +{ + osd_result rv; + + uint16_t old_reg_val = 0xde0D; + uint16_t new_reg_val = 0xde0C; + + mock_hostmod_expect_reg_read16(old_reg_val, + osd_diaddr_build(subnet_addr, 0), + OSD_REG_SCM_SYSRST, + OSD_OK); + mock_hostmod_expect_reg_write16(new_reg_val, + osd_diaddr_build(subnet_addr, 0), + OSD_REG_SCM_SYSRST, + OSD_OK); + + rv = osd_cl_scm_system_reset(mock_hostmod_get_ctx(), subnet_addr, 0); + ck_assert_int_eq(rv, OSD_OK); +} +END_TEST + START_TEST(test_get_subnetinfo) { osd_result rv; @@ -118,6 +160,8 @@ Suite *suite(void) tcase_add_checked_fixture(tc_core, setup, teardown); tcase_add_test(tc_core, test_cpus_start); tcase_add_test(tc_core, test_cpus_stop); + tcase_add_test(tc_core, test_system_reset_set); + tcase_add_test(tc_core, test_system_reset_unset); tcase_add_test(tc_core, test_get_subnetinfo); suite_add_tcase(s, tc_core);