From f9c32660aa1f2bb08e801b104647fdf9b884bb9b Mon Sep 17 00:00:00 2001 From: Mahmoud Elsabbagh Date: Wed, 12 Feb 2025 13:43:02 +0000 Subject: [PATCH] mod/power_capping_hal: Add power notifications and threshold support Implement support in the Power capping HAL for sending notifications: - When the power averaging interval (PAI) changes. - When the average power consumption of the power capping domain, measured over PAI, is outside the threshold values set by the agent for the power capping domain. Also add support for setting low/high power thresholds using mod_pcapping_set_power_thresholds(), which allows agents to define when measurement-based notifications should occur for the power capping domain. Update scmi_power_capping to allow agents to subscribe to and process these new notifications. Signed-off-by: Mahmoud Elsabbagh --- .../power_capping/include/mod_power_capping.h | 34 ++- module/power_capping/src/mod_power_capping.c | 70 +++++- .../test/mod_power_capping_unit_test.c | 52 +++++ .../internal/scmi_power_capping_core.h | 4 + .../src/scmi_power_capping_core.c | 18 ++ .../src/scmi_power_capping_protocol.c | 11 + .../test/mocks/Mockmod_power_capping_extra.c | 182 +++++++++++++++ .../test/mocks/Mockmod_power_capping_extra.h | 18 ++ .../test/mocks/Mockscmi_power_capping_core.c | 214 ++++++++++++++++-- .../test/mocks/Mockscmi_power_capping_core.h | 28 ++- .../test/mod_power_capping_extra.h | 4 + .../test/mod_scmi_power_capping_unit_test.h | 3 + .../test/scmi_power_capping_core_unit_test.c | 68 ++++++ .../scmi_power_capping_protocol_unit_test.c | 8 + 14 files changed, 686 insertions(+), 28 deletions(-) diff --git a/module/power_capping/include/mod_power_capping.h b/module/power_capping/include/mod_power_capping.h index e1ebcedc1..7be7409b9 100644 --- a/module/power_capping/include/mod_power_capping.h +++ b/module/power_capping/include/mod_power_capping.h @@ -127,7 +127,8 @@ struct mod_power_capping_api { * \param id Power measurements domain ID. * \param[out] power Average power measured in microwatt. * - * \retval ::FWK_SUCCESS The requested cap was applied successfully. + * \retval ::FWK_SUCCESS The average power applied to the system + * measured over PAI interval was returned successfully. * \return One of the standard framework error codes. */ int (*get_average_power)(fwk_id_t id, uint32_t *power); @@ -138,7 +139,7 @@ struct mod_power_capping_api { * \param id Power measurements domain ID. * \param pai Averaging interval measured in microseconds. * - * \retval ::FWK_SUCCESS The requested cap was applied successfully. + * \retval ::FWK_SUCCESS The PAI was applied successfully. * \return One of the standard framework error codes. */ int (*set_averaging_interval)(fwk_id_t id, uint32_t pai); @@ -149,7 +150,7 @@ struct mod_power_capping_api { * \param id Power measurements domain ID. * \param[out] pai Averaging interval measured in microseconds. * - * \retval ::FWK_SUCCESS The requested cap was applied successfully. + * \retval ::FWK_SUCCESS The PAI was returned successfully. * \return One of the standard framework error codes. */ int (*get_averaging_interval)(fwk_id_t id, uint32_t *pai); @@ -161,7 +162,7 @@ struct mod_power_capping_api { * \param[out] pai_step The step size between two consecutive averaging * intervals in microseconds. * - * \retval ::FWK_SUCCESS The requested cap was applied successfully. + * \retval ::FWK_SUCCESS The PAI step was returned successfully. * \return One of the standard framework error codes. */ int (*get_averaging_interval_step)(fwk_id_t id, uint32_t *pai_step); @@ -173,13 +174,34 @@ struct mod_power_capping_api { * \param[out] min_pai Min averaging interval measured in microseconds. * \param[out] max_pai Max averaging interval measured in microseconds. * - * \retval ::FWK_SUCCESS The requested cap was applied successfully. + * \retval ::FWK_SUCCESS The averaging interval range was returned + * successfully. * \return One of the standard framework error codes. */ int (*get_averaging_interval_range)( fwk_id_t id, uint32_t *min_pai, uint32_t *max_pai); + + /*! + * \brief Set power thresholds specified in power units which are in use + * by this domain. The platform sends a notification to the agent when + * the average power consumption of the power capping domain, measured + * over PAI, is outside the threshold values. + * + * \param domain_id Power Capping domain ID. + * \param threshold_low The lower threshold specified in power units + * used by this domain. + * \param threshold_high The higher threshold specified in power units + * used by this domain. + * + * \retval ::FWK_SUCCESS The power thresholds were applied successfully. + * \return One of the standard framework error codes. + */ + int (*set_power_thresholds)( + fwk_id_t domain_id, + uint32_t threshold_low, + uint32_t threshold_high); }; /*! @@ -240,11 +262,13 @@ enum mod_power_capping_notification_idx { /*! Power cap change notification. */ MOD_POWER_CAPPING_NOTIFICATION_IDX_CAP_CHANGE, +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS /*! PAI changed notification. */ MOD_POWER_CAPPING_NOTIFICATION_IDX_PAI_CHANGED, /*! Measurements changed notification. */ MOD_POWER_CAPPING_NOTIFICATION_IDX_MEASUREMENTS_CHANGED, +#endif /*! Number of defined notifications. */ MOD_POWER_CAPPING_NOTIFICATION_IDX_COUNT, diff --git a/module/power_capping/src/mod_power_capping.c b/module/power_capping/src/mod_power_capping.c index d662e5110..cdf862e15 100644 --- a/module/power_capping/src/mod_power_capping.c +++ b/module/power_capping/src/mod_power_capping.c @@ -26,6 +26,8 @@ struct pcapping_domain_ctx { struct mod_power_capping_domain_config *config; uint32_t applied_cap; uint32_t requested_cap; + uint32_t threshold_low; + uint32_t threshold_high; uint32_t cookie; unsigned int notifications_sent_count; struct interface_power_management_api *power_management_api; @@ -44,6 +46,19 @@ static const fwk_id_t mod_pcapping_notification_id_cap_change = FWK_MODULE_IDX_POWER_CAPPING, MOD_POWER_CAPPING_NOTIFICATION_IDX_CAP_CHANGE); +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS +static const fwk_id_t mod_pcapping_notification_id_pai_changed = + FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_POWER_CAPPING, + MOD_POWER_CAPPING_NOTIFICATION_IDX_PAI_CHANGED); + +static const fwk_id_t mod_pcapping_notification_id_meas_changed = + FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_POWER_CAPPING, + MOD_POWER_CAPPING_NOTIFICATION_IDX_MEASUREMENTS_CHANGED); + +#endif + static int pcapping_get_ctx( fwk_id_t domain_id, struct pcapping_domain_ctx **domain_ctx) @@ -129,7 +144,18 @@ static int mod_pcapping_set_averaging_interval(fwk_id_t domain_id, uint32_t pai) return status; } - return FWK_SUCCESS; +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + struct fwk_event outbound_event = { + .id = mod_pcapping_notification_id_pai_changed, + .source_id = domain_id, + }; + + status = fwk_notification_notify( + &outbound_event, &(domain_ctx->notifications_sent_count)); + +#endif + + return status; } static int mod_pcapping_get_averaging_interval( @@ -203,6 +229,30 @@ static int mod_pcapping_get_averaging_interval_range( return FWK_SUCCESS; } +static int mod_pcapping_set_power_thresholds( + fwk_id_t domain_id, + uint32_t threshold_low, + uint32_t threshold_high) +{ + int status; + struct pcapping_domain_ctx *domain_ctx; + + status = pcapping_get_ctx(domain_id, &domain_ctx); + + if (status != FWK_SUCCESS) { + return status; + } + + if (threshold_low > threshold_high) { + return FWK_E_PARAM; + } + + domain_ctx->threshold_low = threshold_low; + domain_ctx->threshold_high = threshold_high; + + return FWK_SUCCESS; +} + static int mod_pcapping_get_power_limit( fwk_id_t domain_id, uint32_t *power_limit) @@ -225,6 +275,23 @@ static int mod_pcapping_get_power_limit( return status; } +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + if (power < domain_ctx->threshold_low || + power > domain_ctx->threshold_high) { + struct fwk_event outbound_event = { + .id = mod_pcapping_notification_id_meas_changed, + .source_id = domain_id, + }; + + status = fwk_notification_notify( + &outbound_event, &(domain_ctx->notifications_sent_count)); + + if (status != FWK_SUCCESS) { + return status; + } + } +#endif + status = domain_ctx->pid_ctrl_api->update( domain_ctx->config->pid_controller_id, power, &pid_output); @@ -251,6 +318,7 @@ struct mod_power_capping_api pcapping_api = { .get_averaging_interval_range = mod_pcapping_get_averaging_interval_range, .get_averaging_interval_step = mod_pcapping_get_averaging_interval_step, .set_averaging_interval = mod_pcapping_set_averaging_interval, + .set_power_thresholds = mod_pcapping_set_power_thresholds, }; struct interface_power_management_api power_management_api = { diff --git a/module/power_capping/test/mod_power_capping_unit_test.c b/module/power_capping/test/mod_power_capping_unit_test.c index 1c021a67c..fdf73d678 100644 --- a/module/power_capping/test/mod_power_capping_unit_test.c +++ b/module/power_capping/test/mod_power_capping_unit_test.c @@ -329,6 +329,55 @@ void utest_mod_pcapping_get_averaging_interval_range(void) } } +void utest_mod_pcapping_set_power_thresholds_success(void) +{ + int status; + fwk_id_t domain_id; + struct pcapping_domain_ctx *domain_ctx; + uint32_t threshold_low = 10U; + uint32_t threshold_high = 50U; + + for (unsigned int index = 0U; index < TEST_DOMAIN_COUNT; index++) { + domain_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_CAPPING, index); + domain_ctx = &pcapping_domain_ctx_table[index]; + + status = mod_pcapping_set_power_thresholds( + domain_id, threshold_low, threshold_high); + + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + TEST_ASSERT_EQUAL(domain_ctx->threshold_low, threshold_low); + TEST_ASSERT_EQUAL(domain_ctx->threshold_high, threshold_high); + } +} + +void utest_mod_pcapping_set_power_thresholds_invalid_thresholds(void) +{ + int status; + fwk_id_t domain_id; + uint32_t threshold_low = 60U; + uint32_t threshold_high = 40U; + + for (unsigned int index = 0U; index < TEST_DOMAIN_COUNT; index++) { + domain_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_CAPPING, index); + + status = mod_pcapping_set_power_thresholds( + domain_id, threshold_low, threshold_high); + TEST_ASSERT_EQUAL(status, FWK_E_PARAM); + } +} + +void utest_mod_pcapping_set_power_thresholds_invalid_id(void) +{ + int status; + + /*out-of-bounds*/ + fwk_id_t invalid_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_POWER_CAPPING, TEST_DOMAIN_COUNT); + + status = mod_pcapping_set_power_thresholds(invalid_id, 10U, 20U); + TEST_ASSERT_EQUAL(status, FWK_E_PARAM); +} + void utest_pcapping_init_success(void) { int status; @@ -565,6 +614,9 @@ int power_capping_test_main(void) RUN_TEST(utest_mod_pcapping_get_averaging_interval); RUN_TEST(utest_mod_pcapping_get_averaging_interval_step); RUN_TEST(utest_mod_pcapping_get_averaging_interval_range); + RUN_TEST(utest_mod_pcapping_set_power_thresholds_success); + RUN_TEST(utest_mod_pcapping_set_power_thresholds_invalid_thresholds); + RUN_TEST(utest_mod_pcapping_set_power_thresholds_invalid_id); RUN_TEST(utest_pcapping_init_success); RUN_TEST(utest_pcapping_domain_init_success); RUN_TEST(utest_mod_pcapping_process_notification_success); diff --git a/module/scmi_power_capping/include/internal/scmi_power_capping_core.h b/module/scmi_power_capping/include/internal/scmi_power_capping_core.h index 5f06e8b47..5bfb79cb9 100644 --- a/module/scmi_power_capping/include/internal/scmi_power_capping_core.h +++ b/module/scmi_power_capping/include/internal/scmi_power_capping_core.h @@ -36,6 +36,10 @@ int pcapping_core_get_pai(unsigned int domain_idx, uint32_t *pai); int pcapping_core_get_power(unsigned int domain_idx, uint32_t *power); +int pcapping_core_set_power_thresholds( + unsigned int domain_idx, + uint32_t threshold_low, + uint32_t threshold_high); struct pcapping_core_cap_pai_event_parameters { fwk_id_t service_id; uint32_t domain_idx; diff --git a/module/scmi_power_capping/src/scmi_power_capping_core.c b/module/scmi_power_capping/src/scmi_power_capping_core.c index f04f1e1a7..6daa42aa6 100644 --- a/module/scmi_power_capping/src/scmi_power_capping_core.c +++ b/module/scmi_power_capping/src/scmi_power_capping_core.c @@ -541,6 +541,24 @@ int pcapping_core_get_power(unsigned int domain_idx, uint32_t *power) return status; } +int pcapping_core_set_power_thresholds( + unsigned int domain_idx, + uint32_t threshold_low, + uint32_t threshold_high) +{ + int status; + struct mod_scmi_power_capping_domain_context *ctx; + + status = pcapping_core_get_domain_ctx(domain_idx, &ctx); + + if (status != FWK_SUCCESS) { + return status; + } + + return pcapping_core_ctx.power_capping_api->set_power_thresholds( + ctx->config->power_capping_domain_id, threshold_low, threshold_high); +} + bool pcapping_core_is_cap_request_async(uint32_t domain_idx) { if (domain_idx < pcapping_core_ctx.power_capping_domain_count) { diff --git a/module/scmi_power_capping/src/scmi_power_capping_protocol.c b/module/scmi_power_capping/src/scmi_power_capping_protocol.c index 12591d18e..42a1b9691 100644 --- a/module/scmi_power_capping/src/scmi_power_capping_protocol.c +++ b/module/scmi_power_capping/src/scmi_power_capping_protocol.c @@ -622,6 +622,17 @@ static int scmi_power_capping_measurements_notify_handler( parameters->domain_id, MOD_SCMI_POWER_CAPPING_MEASUREMENTS_NOTIFY, cap_service_id); + + if (status != FWK_SUCCESS) { + return scmi_power_capping_respond_error( + cap_service_id, SCMI_GENERIC_ERROR); + } + + status = pcapping_core_set_power_thresholds( + parameters->domain_id, + parameters->threshold_low, + parameters->threshold_high); + } else { status = pcapping_protocol_ctx.scmi_api->get_agent_id( cap_service_id, &agent_id); diff --git a/module/scmi_power_capping/test/mocks/Mockmod_power_capping_extra.c b/module/scmi_power_capping/test/mocks/Mockmod_power_capping_extra.c index 5ef51c615..3229d193c 100644 --- a/module/scmi_power_capping/test/mocks/Mockmod_power_capping_extra.c +++ b/module/scmi_power_capping/test/mocks/Mockmod_power_capping_extra.c @@ -20,6 +20,9 @@ static const char* CMockString_pai_step = "pai_step"; static const char* CMockString_power = "power"; static const char* CMockString_request_cap = "request_cap"; static const char* CMockString_set_averaging_interval = "set_averaging_interval"; +static const char* CMockString_set_power_thresholds = "set_power_thresholds"; +static const char* CMockString_threshold_high = "threshold_high"; +static const char* CMockString_threshold_low = "threshold_low"; typedef struct _CMOCK_get_applied_cap_CALL_INSTANCE { @@ -131,6 +134,20 @@ typedef struct _CMOCK_get_averaging_interval_range_CALL_INSTANCE } CMOCK_get_averaging_interval_range_CALL_INSTANCE; +typedef struct _CMOCK_set_power_thresholds_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + int ReturnVal; + fwk_id_t Expected_domain_id; + uint32_t Expected_threshold_low; + uint32_t Expected_threshold_high; + char IgnoreArg_domain_id; + char IgnoreArg_threshold_low; + char IgnoreArg_threshold_high; + +} CMOCK_set_power_thresholds_CALL_INSTANCE; + static struct Mockmod_power_capping_extraInstance { char get_applied_cap_IgnoreBool; @@ -175,6 +192,12 @@ static struct Mockmod_power_capping_extraInstance CMOCK_get_averaging_interval_range_CALLBACK get_averaging_interval_range_CallbackFunctionPointer; int get_averaging_interval_range_CallbackCalls; CMOCK_MEM_INDEX_TYPE get_averaging_interval_range_CallInstance; + char set_power_thresholds_IgnoreBool; + int set_power_thresholds_FinalReturn; + char set_power_thresholds_CallbackBool; + CMOCK_set_power_thresholds_CALLBACK set_power_thresholds_CallbackFunctionPointer; + int set_power_thresholds_CallbackCalls; + CMOCK_MEM_INDEX_TYPE set_power_thresholds_CallInstance; } Mock; extern jmp_buf AbortFrame; @@ -274,6 +297,19 @@ void Mockmod_power_capping_extra_Verify(void) call_instance = CMOCK_GUTS_NONE; (void)call_instance; } + call_instance = Mock.set_power_thresholds_CallInstance; + if (Mock.set_power_thresholds_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_set_power_thresholds); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.set_power_thresholds_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } } void Mockmod_power_capping_extra_Init(void) @@ -1415,3 +1451,149 @@ void get_averaging_interval_range_CMockIgnoreArg_max_pai(UNITY_LINE_TYPE cmock_l cmock_call_instance->IgnoreArg_max_pai = 1; } +int set_power_thresholds(fwk_id_t domain_id, uint32_t threshold_low, uint32_t threshold_high) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_set_power_thresholds_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_set_power_thresholds); + cmock_call_instance = (CMOCK_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.set_power_thresholds_CallInstance); + Mock.set_power_thresholds_CallInstance = CMock_Guts_MemNext(Mock.set_power_thresholds_CallInstance); + if (Mock.set_power_thresholds_IgnoreBool) + { + UNITY_CLR_DETAILS(); + if (cmock_call_instance == NULL) + return Mock.set_power_thresholds_FinalReturn; + Mock.set_power_thresholds_FinalReturn = cmock_call_instance->ReturnVal; + return cmock_call_instance->ReturnVal; + } + if (!Mock.set_power_thresholds_CallbackBool && + Mock.set_power_thresholds_CallbackFunctionPointer != NULL) + { + int cmock_cb_ret = Mock.set_power_thresholds_CallbackFunctionPointer(domain_id, threshold_low, threshold_high, Mock.set_power_thresholds_CallbackCalls++); + UNITY_CLR_DETAILS(); + return cmock_cb_ret; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (!cmock_call_instance->ExpectAnyArgsBool) + { + if (!cmock_call_instance->IgnoreArg_domain_id) + { + UNITY_SET_DETAILS(CMockString_set_power_thresholds,CMockString_domain_id); + UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_domain_id), (void*)(&domain_id), sizeof(fwk_id_t), cmock_line, CMockStringMismatch); + } + if (!cmock_call_instance->IgnoreArg_threshold_low) + { + UNITY_SET_DETAILS(CMockString_set_power_thresholds,CMockString_threshold_low); + UNITY_TEST_ASSERT_EQUAL_HEX32(cmock_call_instance->Expected_threshold_low, threshold_low, cmock_line, CMockStringMismatch); + } + if (!cmock_call_instance->IgnoreArg_threshold_high) + { + UNITY_SET_DETAILS(CMockString_set_power_thresholds,CMockString_threshold_high); + UNITY_TEST_ASSERT_EQUAL_HEX32(cmock_call_instance->Expected_threshold_high, threshold_high, cmock_line, CMockStringMismatch); + } + } + if (Mock.set_power_thresholds_CallbackFunctionPointer != NULL) + { + cmock_call_instance->ReturnVal = Mock.set_power_thresholds_CallbackFunctionPointer(domain_id, threshold_low, threshold_high, Mock.set_power_thresholds_CallbackCalls++); + } + UNITY_CLR_DETAILS(); + return cmock_call_instance->ReturnVal; +} + +void CMockExpectParameters_set_power_thresholds(CMOCK_set_power_thresholds_CALL_INSTANCE* cmock_call_instance, fwk_id_t domain_id, uint32_t threshold_low, uint32_t threshold_high); +void CMockExpectParameters_set_power_thresholds(CMOCK_set_power_thresholds_CALL_INSTANCE* cmock_call_instance, fwk_id_t domain_id, uint32_t threshold_low, uint32_t threshold_high) +{ + memcpy((void*)(&cmock_call_instance->Expected_domain_id), (void*)(&domain_id), + sizeof(fwk_id_t[sizeof(domain_id) == sizeof(fwk_id_t) ? 1 : -1])); /* add fwk_id_t to :treat_as_array if this causes an error */ + cmock_call_instance->IgnoreArg_domain_id = 0; + cmock_call_instance->Expected_threshold_low = threshold_low; + cmock_call_instance->IgnoreArg_threshold_low = 0; + cmock_call_instance->Expected_threshold_high = threshold_high; + cmock_call_instance->IgnoreArg_threshold_high = 0; +} + +void set_power_thresholds_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_set_power_thresholds_CALL_INSTANCE)); + CMOCK_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.set_power_thresholds_CallInstance = CMock_Guts_MemChain(Mock.set_power_thresholds_CallInstance, cmock_guts_index); + Mock.set_power_thresholds_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ReturnVal = cmock_to_return; + Mock.set_power_thresholds_IgnoreBool = (char)1; +} + +void set_power_thresholds_CMockStopIgnore(void) +{ + if(Mock.set_power_thresholds_IgnoreBool) + Mock.set_power_thresholds_CallInstance = CMock_Guts_MemNext(Mock.set_power_thresholds_CallInstance); + Mock.set_power_thresholds_IgnoreBool = (char)0; +} + +void set_power_thresholds_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_set_power_thresholds_CALL_INSTANCE)); + CMOCK_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.set_power_thresholds_CallInstance = CMock_Guts_MemChain(Mock.set_power_thresholds_CallInstance, cmock_guts_index); + Mock.set_power_thresholds_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ReturnVal = cmock_to_return; + cmock_call_instance->ExpectAnyArgsBool = (char)1; +} + +void set_power_thresholds_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, fwk_id_t domain_id, uint32_t threshold_low, uint32_t threshold_high, int cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_set_power_thresholds_CALL_INSTANCE)); + CMOCK_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.set_power_thresholds_CallInstance = CMock_Guts_MemChain(Mock.set_power_thresholds_CallInstance, cmock_guts_index); + Mock.set_power_thresholds_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + CMockExpectParameters_set_power_thresholds(cmock_call_instance, domain_id, threshold_low, threshold_high); + cmock_call_instance->ReturnVal = cmock_to_return; +} + +void set_power_thresholds_AddCallback(CMOCK_set_power_thresholds_CALLBACK Callback) +{ + Mock.set_power_thresholds_IgnoreBool = (char)0; + Mock.set_power_thresholds_CallbackBool = (char)1; + Mock.set_power_thresholds_CallbackFunctionPointer = Callback; +} + +void set_power_thresholds_Stub(CMOCK_set_power_thresholds_CALLBACK Callback) +{ + Mock.set_power_thresholds_IgnoreBool = (char)0; + Mock.set_power_thresholds_CallbackBool = (char)0; + Mock.set_power_thresholds_CallbackFunctionPointer = Callback; +} + +void set_power_thresholds_CMockIgnoreArg_domain_id(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.set_power_thresholds_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_domain_id = 1; +} + +void set_power_thresholds_CMockIgnoreArg_threshold_low(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.set_power_thresholds_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_threshold_low = 1; +} + +void set_power_thresholds_CMockIgnoreArg_threshold_high(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.set_power_thresholds_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_threshold_high = 1; +} + diff --git a/module/scmi_power_capping/test/mocks/Mockmod_power_capping_extra.h b/module/scmi_power_capping/test/mocks/Mockmod_power_capping_extra.h index 71ea7b54b..bb48e6ec6 100644 --- a/module/scmi_power_capping/test/mocks/Mockmod_power_capping_extra.h +++ b/module/scmi_power_capping/test/mocks/Mockmod_power_capping_extra.h @@ -172,6 +172,24 @@ void get_averaging_interval_range_CMockIgnoreArg_id(UNITY_LINE_TYPE cmock_line); void get_averaging_interval_range_CMockIgnoreArg_min_pai(UNITY_LINE_TYPE cmock_line); #define get_averaging_interval_range_IgnoreArg_max_pai() get_averaging_interval_range_CMockIgnoreArg_max_pai(__LINE__) void get_averaging_interval_range_CMockIgnoreArg_max_pai(UNITY_LINE_TYPE cmock_line); +#define set_power_thresholds_IgnoreAndReturn(cmock_retval) set_power_thresholds_CMockIgnoreAndReturn(__LINE__, cmock_retval) +void set_power_thresholds_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return); +#define set_power_thresholds_StopIgnore() set_power_thresholds_CMockStopIgnore() +void set_power_thresholds_CMockStopIgnore(void); +#define set_power_thresholds_ExpectAnyArgsAndReturn(cmock_retval) set_power_thresholds_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval) +void set_power_thresholds_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return); +#define set_power_thresholds_ExpectAndReturn(domain_id, threshold_low, threshold_high, cmock_retval) set_power_thresholds_CMockExpectAndReturn(__LINE__, domain_id, threshold_low, threshold_high, cmock_retval) +void set_power_thresholds_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, fwk_id_t domain_id, uint32_t threshold_low, uint32_t threshold_high, int cmock_to_return); +typedef int (* CMOCK_set_power_thresholds_CALLBACK)(fwk_id_t domain_id, uint32_t threshold_low, uint32_t threshold_high, int cmock_num_calls); +void set_power_thresholds_AddCallback(CMOCK_set_power_thresholds_CALLBACK Callback); +void set_power_thresholds_Stub(CMOCK_set_power_thresholds_CALLBACK Callback); +#define set_power_thresholds_StubWithCallback set_power_thresholds_Stub +#define set_power_thresholds_IgnoreArg_domain_id() set_power_thresholds_CMockIgnoreArg_domain_id(__LINE__) +void set_power_thresholds_CMockIgnoreArg_domain_id(UNITY_LINE_TYPE cmock_line); +#define set_power_thresholds_IgnoreArg_threshold_low() set_power_thresholds_CMockIgnoreArg_threshold_low(__LINE__) +void set_power_thresholds_CMockIgnoreArg_threshold_low(UNITY_LINE_TYPE cmock_line); +#define set_power_thresholds_IgnoreArg_threshold_high() set_power_thresholds_CMockIgnoreArg_threshold_high(__LINE__) +void set_power_thresholds_CMockIgnoreArg_threshold_high(UNITY_LINE_TYPE cmock_line); #if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__) #if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0))) diff --git a/module/scmi_power_capping/test/mocks/Mockscmi_power_capping_core.c b/module/scmi_power_capping/test/mocks/Mockscmi_power_capping_core.c index 945878e0a..a148589b4 100644 --- a/module/scmi_power_capping/test/mocks/Mockscmi_power_capping_core.c +++ b/module/scmi_power_capping/test/mocks/Mockscmi_power_capping_core.c @@ -8,7 +8,6 @@ static const char* CMockString_async_flag = "async_flag"; static const char* CMockString_cap = "cap"; static const char* CMockString_config = "config"; -static const char* CMockString_domain_id = "domain_id"; static const char* CMockString_domain_idx = "domain_idx"; static const char* CMockString_element_count = "element_count"; static const char* CMockString_fwk_notification_event = "fwk_notification_event"; @@ -30,10 +29,13 @@ static const char* CMockString_pcapping_core_is_cap_request_async = "pcapping_co static const char* CMockString_pcapping_core_process_fwk_notification = "pcapping_core_process_fwk_notification"; static const char* CMockString_pcapping_core_set_cap = "pcapping_core_set_cap"; static const char* CMockString_pcapping_core_set_pai = "pcapping_core_set_pai"; +static const char* CMockString_pcapping_core_set_power_thresholds = "pcapping_core_set_power_thresholds"; static const char* CMockString_pcapping_core_start = "pcapping_core_start"; static const char* CMockString_power = "power"; static const char* CMockString_service_id = "service_id"; static const char* CMockString_support = "support"; +static const char* CMockString_threshold_high = "threshold_high"; +static const char* CMockString_threshold_low = "threshold_low"; typedef struct _CMOCK_pcapping_core_set_cap_CALL_INSTANCE { @@ -113,6 +115,20 @@ typedef struct _CMOCK_pcapping_core_get_power_CALL_INSTANCE } CMOCK_pcapping_core_get_power_CALL_INSTANCE; +typedef struct _CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + int ReturnVal; + unsigned int Expected_domain_idx; + uint32_t Expected_threshold_low; + uint32_t Expected_threshold_high; + char IgnoreArg_domain_idx; + char IgnoreArg_threshold_low; + char IgnoreArg_threshold_high; + +} CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE; + typedef struct _CMOCK_pcapping_core_get_cap_support_CALL_INSTANCE { UNITY_LINE_TYPE LineNumber; @@ -186,8 +202,8 @@ typedef struct _CMOCK_pcapping_core_start_CALL_INSTANCE UNITY_LINE_TYPE LineNumber; char ExpectAnyArgsBool; int ReturnVal; - unsigned int Expected_domain_id; - char IgnoreArg_domain_id; + unsigned int Expected_domain_idx; + char IgnoreArg_domain_idx; } CMOCK_pcapping_core_start_CALL_INSTANCE; @@ -274,6 +290,12 @@ static struct Mockscmi_power_capping_coreInstance CMOCK_pcapping_core_get_power_CALLBACK pcapping_core_get_power_CallbackFunctionPointer; int pcapping_core_get_power_CallbackCalls; CMOCK_MEM_INDEX_TYPE pcapping_core_get_power_CallInstance; + char pcapping_core_set_power_thresholds_IgnoreBool; + int pcapping_core_set_power_thresholds_FinalReturn; + char pcapping_core_set_power_thresholds_CallbackBool; + CMOCK_pcapping_core_set_power_thresholds_CALLBACK pcapping_core_set_power_thresholds_CallbackFunctionPointer; + int pcapping_core_set_power_thresholds_CallbackCalls; + CMOCK_MEM_INDEX_TYPE pcapping_core_set_power_thresholds_CallInstance; char pcapping_core_get_cap_support_IgnoreBool; int pcapping_core_get_cap_support_FinalReturn; char pcapping_core_get_cap_support_CallbackBool; @@ -406,6 +428,19 @@ void Mockscmi_power_capping_core_Verify(void) call_instance = CMOCK_GUTS_NONE; (void)call_instance; } + call_instance = Mock.pcapping_core_set_power_thresholds_CallInstance; + if (Mock.pcapping_core_set_power_thresholds_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_pcapping_core_set_power_thresholds); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.pcapping_core_set_power_thresholds_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } call_instance = Mock.pcapping_core_get_cap_support_CallInstance; if (Mock.pcapping_core_get_cap_support_IgnoreBool) call_instance = CMOCK_GUTS_NONE; @@ -1350,6 +1385,151 @@ void pcapping_core_get_power_CMockIgnoreArg_power(UNITY_LINE_TYPE cmock_line) cmock_call_instance->IgnoreArg_power = 1; } +int pcapping_core_set_power_thresholds(unsigned int domain_idx, uint32_t threshold_low, uint32_t threshold_high) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_pcapping_core_set_power_thresholds); + cmock_call_instance = (CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.pcapping_core_set_power_thresholds_CallInstance); + Mock.pcapping_core_set_power_thresholds_CallInstance = CMock_Guts_MemNext(Mock.pcapping_core_set_power_thresholds_CallInstance); + if (Mock.pcapping_core_set_power_thresholds_IgnoreBool) + { + UNITY_CLR_DETAILS(); + if (cmock_call_instance == NULL) + return Mock.pcapping_core_set_power_thresholds_FinalReturn; + Mock.pcapping_core_set_power_thresholds_FinalReturn = cmock_call_instance->ReturnVal; + return cmock_call_instance->ReturnVal; + } + if (!Mock.pcapping_core_set_power_thresholds_CallbackBool && + Mock.pcapping_core_set_power_thresholds_CallbackFunctionPointer != NULL) + { + int cmock_cb_ret = Mock.pcapping_core_set_power_thresholds_CallbackFunctionPointer(domain_idx, threshold_low, threshold_high, Mock.pcapping_core_set_power_thresholds_CallbackCalls++); + UNITY_CLR_DETAILS(); + return cmock_cb_ret; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (!cmock_call_instance->ExpectAnyArgsBool) + { + if (!cmock_call_instance->IgnoreArg_domain_idx) + { + UNITY_SET_DETAILS(CMockString_pcapping_core_set_power_thresholds,CMockString_domain_idx); + UNITY_TEST_ASSERT_EQUAL_HEX32(cmock_call_instance->Expected_domain_idx, domain_idx, cmock_line, CMockStringMismatch); + } + if (!cmock_call_instance->IgnoreArg_threshold_low) + { + UNITY_SET_DETAILS(CMockString_pcapping_core_set_power_thresholds,CMockString_threshold_low); + UNITY_TEST_ASSERT_EQUAL_HEX32(cmock_call_instance->Expected_threshold_low, threshold_low, cmock_line, CMockStringMismatch); + } + if (!cmock_call_instance->IgnoreArg_threshold_high) + { + UNITY_SET_DETAILS(CMockString_pcapping_core_set_power_thresholds,CMockString_threshold_high); + UNITY_TEST_ASSERT_EQUAL_HEX32(cmock_call_instance->Expected_threshold_high, threshold_high, cmock_line, CMockStringMismatch); + } + } + if (Mock.pcapping_core_set_power_thresholds_CallbackFunctionPointer != NULL) + { + cmock_call_instance->ReturnVal = Mock.pcapping_core_set_power_thresholds_CallbackFunctionPointer(domain_idx, threshold_low, threshold_high, Mock.pcapping_core_set_power_thresholds_CallbackCalls++); + } + UNITY_CLR_DETAILS(); + return cmock_call_instance->ReturnVal; +} + +void CMockExpectParameters_pcapping_core_set_power_thresholds(CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE* cmock_call_instance, unsigned int domain_idx, uint32_t threshold_low, uint32_t threshold_high); +void CMockExpectParameters_pcapping_core_set_power_thresholds(CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE* cmock_call_instance, unsigned int domain_idx, uint32_t threshold_low, uint32_t threshold_high) +{ + cmock_call_instance->Expected_domain_idx = domain_idx; + cmock_call_instance->IgnoreArg_domain_idx = 0; + cmock_call_instance->Expected_threshold_low = threshold_low; + cmock_call_instance->IgnoreArg_threshold_low = 0; + cmock_call_instance->Expected_threshold_high = threshold_high; + cmock_call_instance->IgnoreArg_threshold_high = 0; +} + +void pcapping_core_set_power_thresholds_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE)); + CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.pcapping_core_set_power_thresholds_CallInstance = CMock_Guts_MemChain(Mock.pcapping_core_set_power_thresholds_CallInstance, cmock_guts_index); + Mock.pcapping_core_set_power_thresholds_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ReturnVal = cmock_to_return; + Mock.pcapping_core_set_power_thresholds_IgnoreBool = (char)1; +} + +void pcapping_core_set_power_thresholds_CMockStopIgnore(void) +{ + if(Mock.pcapping_core_set_power_thresholds_IgnoreBool) + Mock.pcapping_core_set_power_thresholds_CallInstance = CMock_Guts_MemNext(Mock.pcapping_core_set_power_thresholds_CallInstance); + Mock.pcapping_core_set_power_thresholds_IgnoreBool = (char)0; +} + +void pcapping_core_set_power_thresholds_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE)); + CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.pcapping_core_set_power_thresholds_CallInstance = CMock_Guts_MemChain(Mock.pcapping_core_set_power_thresholds_CallInstance, cmock_guts_index); + Mock.pcapping_core_set_power_thresholds_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ReturnVal = cmock_to_return; + cmock_call_instance->ExpectAnyArgsBool = (char)1; +} + +void pcapping_core_set_power_thresholds_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, unsigned int domain_idx, uint32_t threshold_low, uint32_t threshold_high, int cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE)); + CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.pcapping_core_set_power_thresholds_CallInstance = CMock_Guts_MemChain(Mock.pcapping_core_set_power_thresholds_CallInstance, cmock_guts_index); + Mock.pcapping_core_set_power_thresholds_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + CMockExpectParameters_pcapping_core_set_power_thresholds(cmock_call_instance, domain_idx, threshold_low, threshold_high); + cmock_call_instance->ReturnVal = cmock_to_return; +} + +void pcapping_core_set_power_thresholds_AddCallback(CMOCK_pcapping_core_set_power_thresholds_CALLBACK Callback) +{ + Mock.pcapping_core_set_power_thresholds_IgnoreBool = (char)0; + Mock.pcapping_core_set_power_thresholds_CallbackBool = (char)1; + Mock.pcapping_core_set_power_thresholds_CallbackFunctionPointer = Callback; +} + +void pcapping_core_set_power_thresholds_Stub(CMOCK_pcapping_core_set_power_thresholds_CALLBACK Callback) +{ + Mock.pcapping_core_set_power_thresholds_IgnoreBool = (char)0; + Mock.pcapping_core_set_power_thresholds_CallbackBool = (char)0; + Mock.pcapping_core_set_power_thresholds_CallbackFunctionPointer = Callback; +} + +void pcapping_core_set_power_thresholds_CMockIgnoreArg_domain_idx(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.pcapping_core_set_power_thresholds_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_domain_idx = 1; +} + +void pcapping_core_set_power_thresholds_CMockIgnoreArg_threshold_low(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.pcapping_core_set_power_thresholds_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_threshold_low = 1; +} + +void pcapping_core_set_power_thresholds_CMockIgnoreArg_threshold_high(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE* cmock_call_instance = (CMOCK_pcapping_core_set_power_thresholds_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.pcapping_core_set_power_thresholds_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_threshold_high = 1; +} + int pcapping_core_get_cap_support(uint32_t domain_idx, bool* support) { UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; @@ -1990,7 +2170,7 @@ void pcapping_core_get_domain_count_Stub(CMOCK_pcapping_core_get_domain_count_CA Mock.pcapping_core_get_domain_count_CallbackFunctionPointer = Callback; } -int pcapping_core_start(unsigned int domain_id) +int pcapping_core_start(unsigned int domain_idx) { UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; CMOCK_pcapping_core_start_CALL_INSTANCE* cmock_call_instance; @@ -2008,7 +2188,7 @@ int pcapping_core_start(unsigned int domain_id) if (!Mock.pcapping_core_start_CallbackBool && Mock.pcapping_core_start_CallbackFunctionPointer != NULL) { - int cmock_cb_ret = Mock.pcapping_core_start_CallbackFunctionPointer(domain_id, Mock.pcapping_core_start_CallbackCalls++); + int cmock_cb_ret = Mock.pcapping_core_start_CallbackFunctionPointer(domain_idx, Mock.pcapping_core_start_CallbackCalls++); UNITY_CLR_DETAILS(); return cmock_cb_ret; } @@ -2016,25 +2196,25 @@ int pcapping_core_start(unsigned int domain_id) cmock_line = cmock_call_instance->LineNumber; if (!cmock_call_instance->ExpectAnyArgsBool) { - if (!cmock_call_instance->IgnoreArg_domain_id) + if (!cmock_call_instance->IgnoreArg_domain_idx) { - UNITY_SET_DETAILS(CMockString_pcapping_core_start,CMockString_domain_id); - UNITY_TEST_ASSERT_EQUAL_HEX32(cmock_call_instance->Expected_domain_id, domain_id, cmock_line, CMockStringMismatch); + UNITY_SET_DETAILS(CMockString_pcapping_core_start,CMockString_domain_idx); + UNITY_TEST_ASSERT_EQUAL_HEX32(cmock_call_instance->Expected_domain_idx, domain_idx, cmock_line, CMockStringMismatch); } } if (Mock.pcapping_core_start_CallbackFunctionPointer != NULL) { - cmock_call_instance->ReturnVal = Mock.pcapping_core_start_CallbackFunctionPointer(domain_id, Mock.pcapping_core_start_CallbackCalls++); + cmock_call_instance->ReturnVal = Mock.pcapping_core_start_CallbackFunctionPointer(domain_idx, Mock.pcapping_core_start_CallbackCalls++); } UNITY_CLR_DETAILS(); return cmock_call_instance->ReturnVal; } -void CMockExpectParameters_pcapping_core_start(CMOCK_pcapping_core_start_CALL_INSTANCE* cmock_call_instance, unsigned int domain_id); -void CMockExpectParameters_pcapping_core_start(CMOCK_pcapping_core_start_CALL_INSTANCE* cmock_call_instance, unsigned int domain_id) +void CMockExpectParameters_pcapping_core_start(CMOCK_pcapping_core_start_CALL_INSTANCE* cmock_call_instance, unsigned int domain_idx); +void CMockExpectParameters_pcapping_core_start(CMOCK_pcapping_core_start_CALL_INSTANCE* cmock_call_instance, unsigned int domain_idx) { - cmock_call_instance->Expected_domain_id = domain_id; - cmock_call_instance->IgnoreArg_domain_id = 0; + cmock_call_instance->Expected_domain_idx = domain_idx; + cmock_call_instance->IgnoreArg_domain_idx = 0; } void pcapping_core_start_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return) @@ -2072,7 +2252,7 @@ void pcapping_core_start_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, cmock_call_instance->ExpectAnyArgsBool = (char)1; } -void pcapping_core_start_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, unsigned int domain_id, int cmock_to_return) +void pcapping_core_start_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, unsigned int domain_idx, int cmock_to_return) { CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_pcapping_core_start_CALL_INSTANCE)); CMOCK_pcapping_core_start_CALL_INSTANCE* cmock_call_instance = (CMOCK_pcapping_core_start_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); @@ -2082,7 +2262,7 @@ void pcapping_core_start_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, unsign Mock.pcapping_core_start_IgnoreBool = (char)0; cmock_call_instance->LineNumber = cmock_line; cmock_call_instance->ExpectAnyArgsBool = (char)0; - CMockExpectParameters_pcapping_core_start(cmock_call_instance, domain_id); + CMockExpectParameters_pcapping_core_start(cmock_call_instance, domain_idx); cmock_call_instance->ReturnVal = cmock_to_return; } @@ -2100,11 +2280,11 @@ void pcapping_core_start_Stub(CMOCK_pcapping_core_start_CALLBACK Callback) Mock.pcapping_core_start_CallbackFunctionPointer = Callback; } -void pcapping_core_start_CMockIgnoreArg_domain_id(UNITY_LINE_TYPE cmock_line) +void pcapping_core_start_CMockIgnoreArg_domain_idx(UNITY_LINE_TYPE cmock_line) { CMOCK_pcapping_core_start_CALL_INSTANCE* cmock_call_instance = (CMOCK_pcapping_core_start_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.pcapping_core_start_CallInstance)); UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); - cmock_call_instance->IgnoreArg_domain_id = 1; + cmock_call_instance->IgnoreArg_domain_idx = 1; } int pcapping_core_bind(void) diff --git a/module/scmi_power_capping/test/mocks/Mockscmi_power_capping_core.h b/module/scmi_power_capping/test/mocks/Mockscmi_power_capping_core.h index 22b460c96..d4979d62d 100644 --- a/module/scmi_power_capping/test/mocks/Mockscmi_power_capping_core.h +++ b/module/scmi_power_capping/test/mocks/Mockscmi_power_capping_core.h @@ -128,6 +128,24 @@ void pcapping_core_get_power_CMockReturnMemThruPtr_power(UNITY_LINE_TYPE cmock_l void pcapping_core_get_power_CMockIgnoreArg_domain_idx(UNITY_LINE_TYPE cmock_line); #define pcapping_core_get_power_IgnoreArg_power() pcapping_core_get_power_CMockIgnoreArg_power(__LINE__) void pcapping_core_get_power_CMockIgnoreArg_power(UNITY_LINE_TYPE cmock_line); +#define pcapping_core_set_power_thresholds_IgnoreAndReturn(cmock_retval) pcapping_core_set_power_thresholds_CMockIgnoreAndReturn(__LINE__, cmock_retval) +void pcapping_core_set_power_thresholds_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return); +#define pcapping_core_set_power_thresholds_StopIgnore() pcapping_core_set_power_thresholds_CMockStopIgnore() +void pcapping_core_set_power_thresholds_CMockStopIgnore(void); +#define pcapping_core_set_power_thresholds_ExpectAnyArgsAndReturn(cmock_retval) pcapping_core_set_power_thresholds_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval) +void pcapping_core_set_power_thresholds_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return); +#define pcapping_core_set_power_thresholds_ExpectAndReturn(domain_idx, threshold_low, threshold_high, cmock_retval) pcapping_core_set_power_thresholds_CMockExpectAndReturn(__LINE__, domain_idx, threshold_low, threshold_high, cmock_retval) +void pcapping_core_set_power_thresholds_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, unsigned int domain_idx, uint32_t threshold_low, uint32_t threshold_high, int cmock_to_return); +typedef int (* CMOCK_pcapping_core_set_power_thresholds_CALLBACK)(unsigned int domain_idx, uint32_t threshold_low, uint32_t threshold_high, int cmock_num_calls); +void pcapping_core_set_power_thresholds_AddCallback(CMOCK_pcapping_core_set_power_thresholds_CALLBACK Callback); +void pcapping_core_set_power_thresholds_Stub(CMOCK_pcapping_core_set_power_thresholds_CALLBACK Callback); +#define pcapping_core_set_power_thresholds_StubWithCallback pcapping_core_set_power_thresholds_Stub +#define pcapping_core_set_power_thresholds_IgnoreArg_domain_idx() pcapping_core_set_power_thresholds_CMockIgnoreArg_domain_idx(__LINE__) +void pcapping_core_set_power_thresholds_CMockIgnoreArg_domain_idx(UNITY_LINE_TYPE cmock_line); +#define pcapping_core_set_power_thresholds_IgnoreArg_threshold_low() pcapping_core_set_power_thresholds_CMockIgnoreArg_threshold_low(__LINE__) +void pcapping_core_set_power_thresholds_CMockIgnoreArg_threshold_low(UNITY_LINE_TYPE cmock_line); +#define pcapping_core_set_power_thresholds_IgnoreArg_threshold_high() pcapping_core_set_power_thresholds_CMockIgnoreArg_threshold_high(__LINE__) +void pcapping_core_set_power_thresholds_CMockIgnoreArg_threshold_high(UNITY_LINE_TYPE cmock_line); #define pcapping_core_get_cap_support_IgnoreAndReturn(cmock_retval) pcapping_core_get_cap_support_CMockIgnoreAndReturn(__LINE__, cmock_retval) void pcapping_core_get_cap_support_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return); #define pcapping_core_get_cap_support_StopIgnore() pcapping_core_get_cap_support_CMockStopIgnore() @@ -222,14 +240,14 @@ void pcapping_core_start_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cm void pcapping_core_start_CMockStopIgnore(void); #define pcapping_core_start_ExpectAnyArgsAndReturn(cmock_retval) pcapping_core_start_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval) void pcapping_core_start_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return); -#define pcapping_core_start_ExpectAndReturn(domain_id, cmock_retval) pcapping_core_start_CMockExpectAndReturn(__LINE__, domain_id, cmock_retval) -void pcapping_core_start_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, unsigned int domain_id, int cmock_to_return); -typedef int (* CMOCK_pcapping_core_start_CALLBACK)(unsigned int domain_id, int cmock_num_calls); +#define pcapping_core_start_ExpectAndReturn(domain_idx, cmock_retval) pcapping_core_start_CMockExpectAndReturn(__LINE__, domain_idx, cmock_retval) +void pcapping_core_start_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, unsigned int domain_idx, int cmock_to_return); +typedef int (* CMOCK_pcapping_core_start_CALLBACK)(unsigned int domain_idx, int cmock_num_calls); void pcapping_core_start_AddCallback(CMOCK_pcapping_core_start_CALLBACK Callback); void pcapping_core_start_Stub(CMOCK_pcapping_core_start_CALLBACK Callback); #define pcapping_core_start_StubWithCallback pcapping_core_start_Stub -#define pcapping_core_start_IgnoreArg_domain_id() pcapping_core_start_CMockIgnoreArg_domain_id(__LINE__) -void pcapping_core_start_CMockIgnoreArg_domain_id(UNITY_LINE_TYPE cmock_line); +#define pcapping_core_start_IgnoreArg_domain_idx() pcapping_core_start_CMockIgnoreArg_domain_idx(__LINE__) +void pcapping_core_start_CMockIgnoreArg_domain_idx(UNITY_LINE_TYPE cmock_line); #define pcapping_core_bind_IgnoreAndReturn(cmock_retval) pcapping_core_bind_CMockIgnoreAndReturn(__LINE__, cmock_retval) void pcapping_core_bind_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return); #define pcapping_core_bind_StopIgnore() pcapping_core_bind_CMockStopIgnore() diff --git a/module/scmi_power_capping/test/mod_power_capping_extra.h b/module/scmi_power_capping/test/mod_power_capping_extra.h index 85e38262c..b0b14cda1 100644 --- a/module/scmi_power_capping/test/mod_power_capping_extra.h +++ b/module/scmi_power_capping/test/mod_power_capping_extra.h @@ -21,4 +21,8 @@ int get_averaging_interval_range( fwk_id_t id, uint32_t *min_pai, uint32_t *max_pai); +int set_power_thresholds( + fwk_id_t domain_id, + uint32_t threshold_low, + uint32_t threshold_high); #endif /* MOD_POWER_CAPPING_EXTRA_H_ */ diff --git a/module/scmi_power_capping/test/mod_scmi_power_capping_unit_test.h b/module/scmi_power_capping/test/mod_scmi_power_capping_unit_test.h index 1eab5791f..c09c8658c 100644 --- a/module/scmi_power_capping/test/mod_scmi_power_capping_unit_test.h +++ b/module/scmi_power_capping/test/mod_scmi_power_capping_unit_test.h @@ -46,6 +46,9 @@ enum fake_power_capping_domains { #define MIN_DEFAULT_POWER_CAP (10u) #define MAX_DEFAULT_POWER_CAP (MIN_DEFAULT_POWER_CAP * 10u) +#define MIN_DEFAULT_POWER_THRESH (10u) +#define MAX_DEFAULT_POWER_THRESH (MIN_DEFAULT_POWER_THRESH * 10u) + #define DISABLE_CAP_VALUE ((uint32_t)0) #define POWER_CAP_NOTIFY_ENABLE (1) diff --git a/module/scmi_power_capping/test/scmi_power_capping_core_unit_test.c b/module/scmi_power_capping/test/scmi_power_capping_core_unit_test.c index 16aed853f..cfc3a3747 100644 --- a/module/scmi_power_capping/test/scmi_power_capping_core_unit_test.c +++ b/module/scmi_power_capping/test/scmi_power_capping_core_unit_test.c @@ -38,6 +38,7 @@ const struct mod_power_capping_api power_capping_api = { .get_averaging_interval_range = get_averaging_interval_range, .get_averaging_interval_step = get_averaging_interval_step, .set_averaging_interval = set_averaging_interval, + .set_power_thresholds = set_power_thresholds, }; @@ -696,6 +697,70 @@ void utest_pcapping_core_get_power_success(void) TEST_ASSERT_EQUAL(expected_power, returned_power); } +void utest_pcapping_core_set_power_thresholds_success(void) +{ + int status; + uint32_t threshold_low = 20; + uint32_t threshold_high = 50; + unsigned int domain_idx = FAKE_POWER_CAPPING_IDX_COUNT - 1u; + + struct mod_scmi_power_capping_domain_context *ctx = + &pcapping_core_ctx.power_capping_domain_ctx_table[domain_idx]; + + struct mod_scmi_power_capping_domain_config config = valid_config; + config.power_capping_domain_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_CAPPING, 0); + ctx->config = &config; + + set_power_thresholds_ExpectAndReturn( + config.power_capping_domain_id, + threshold_low, + threshold_high, + FWK_SUCCESS); + + status = pcapping_core_set_power_thresholds( + domain_idx, threshold_low, threshold_high); + + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); +} + +void utest_pcapping_core_set_power_thresholds_invalid_index(void) +{ + int status; + unsigned int invalid_idx = FAKE_POWER_CAPPING_IDX_COUNT; + + status = pcapping_core_set_power_thresholds(invalid_idx, 10, 20); + + TEST_ASSERT_EQUAL(status, FWK_E_RANGE); +} + +void utest_pcapping_core_set_power_thresholds_hal_error(void) +{ + int status; + uint32_t threshold_low = 20; + uint32_t threshold_high = 10; + unsigned int domain_idx = FAKE_POWER_CAPPING_IDX_COUNT - 1u; + + struct mod_scmi_power_capping_domain_context *ctx = + &pcapping_core_ctx.power_capping_domain_ctx_table[domain_idx]; + + struct mod_scmi_power_capping_domain_config config = valid_config; + config.power_capping_domain_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_CAPPING, 0); + ctx->config = &config; + + set_power_thresholds_ExpectAndReturn( + config.power_capping_domain_id, + threshold_low, + threshold_high, + FWK_E_PARAM); + + status = pcapping_core_set_power_thresholds( + domain_idx, threshold_low, threshold_high); + + TEST_ASSERT_EQUAL(status, FWK_E_PARAM); +} + int fwk_put_event_notifications_callback(struct fwk_event *event, int numCalls) { TEST_ASSERT_EQUAL_MEMORY( @@ -882,6 +947,9 @@ int scmi_test_main(void) RUN_TEST(utest_pcapping_core_get_pai_success); RUN_TEST(utest_pcapping_core_get_power_out_of_range); RUN_TEST(utest_pcapping_core_get_power_success); + RUN_TEST(utest_pcapping_core_set_power_thresholds_success); + RUN_TEST(utest_pcapping_core_set_power_thresholds_invalid_index); + RUN_TEST(utest_pcapping_core_set_power_thresholds_hal_error); RUN_TEST(utest_pcapping_core_process_cap_fwk_notification); #ifdef BUILD_HAS_SCMI_NOTIFICATIONS RUN_TEST( diff --git a/module/scmi_power_capping/test/scmi_power_capping_protocol_unit_test.c b/module/scmi_power_capping/test/scmi_power_capping_protocol_unit_test.c index 57fff4b2b..726af2789 100644 --- a/module/scmi_power_capping/test/scmi_power_capping_protocol_unit_test.c +++ b/module/scmi_power_capping/test/scmi_power_capping_protocol_unit_test.c @@ -707,9 +707,14 @@ void utest_message_handler_power_capping_cap_notify_valid_disable(void) void utest_message_handler_power_capping_measurements_notify_valid_enable(void) { + uint32_t threshold_low = MIN_DEFAULT_POWER_THRESH; + uint32_t threshold_high = MAX_DEFAULT_POWER_THRESH; + struct scmi_power_capping_measurements_notify_a2p cmd_payload = { .domain_id = FAKE_POWER_CAPPING_IDX_1, .notify_enable = MEASUREMENTS_NOTIFY_ENABLE, + .threshold_low = threshold_low, + .threshold_high = threshold_high, }; struct scmi_power_capping_measurements_notify_p2a ret_payload = { @@ -723,6 +728,9 @@ void utest_message_handler_power_capping_measurements_notify_valid_enable(void) service_id_1, FWK_SUCCESS); + pcapping_core_set_power_thresholds_ExpectAndReturn( + cmd_payload.domain_id, threshold_low, threshold_high, FWK_SUCCESS); + EXPECT_RESPONSE_SUCCESS(ret_payload); TEST_SCMI_COMMAND(MOD_SCMI_POWER_CAPPING_MEASUREMENTS_NOTIFY, cmd_payload); } -- GitLab