diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index 6e2ec037b925..728cca232aba 100644 --- a/src/audio/base_fw.c +++ b/src/audio/base_fw.c @@ -16,6 +16,10 @@ #if defined(CONFIG_SOC_SERIES_INTEL_ACE) #include #endif +#include +#include +#include +#include #if CONFIG_ACE_V1X_ART_COUNTER || CONFIG_ACE_V1X_RTC_COUNTER #include @@ -455,6 +459,50 @@ static int basefw_set_fw_config(bool first_block, return 0; } +int schedulers_info_get(uint32_t *data_off_size, + char *data, + uint32_t core_id) +{ + /* TODO + * Core id parameter is not yet used. For now we only get scheduler info from current core + * Other cores info can be added by implementing idc request for this data. + * Do this if Schedulers info get ipc has uses for accurate info per core + */ + + struct scheduler_props *scheduler_props; + /* the internal structs have irregular sizes so we cannot use indexing, and have to just + * to reassign pointers for each element + */ + struct schedulers_info *schedulers_info = (struct schedulers_info *)data; + + schedulers_info->scheduler_count = 0; + + /* smallest response possible is just zero schedulers count + * here we replace max_len from data_off_size to serve as output size + */ + *data_off_size = sizeof(struct schedulers_info); + + /* ===================== LL_TIMER SCHEDULER INFO ============================ */ + schedulers_info->scheduler_count++; + scheduler_props = (struct scheduler_props *)(data + *data_off_size); + scheduler_get_task_info_ll(scheduler_props, data_off_size); + + /* ===================== LL_DMA SCHEDULER INFO ============================ */ + /* Could not make this one work */ + /* schedulers_info->scheduler_count++; + * scheduler_props = (struct scheduler_props *)(data + *data_off_size); + * scheduler_get_task_info_ll_dma(scheduler_props, data_off_size); + */ + + /* ===================== DP SCHEDULER INFO ============================ */ +#if !CONFIG_TIGERLAKE + schedulers_info->scheduler_count++; + scheduler_props = (struct scheduler_props *)(data + *data_off_size); + scheduler_get_task_info_dp(scheduler_props, data_off_size); +#endif + return 0; +} + static int basefw_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, @@ -498,13 +546,15 @@ static int basefw_get_large_config(struct comp_dev *dev, break; case IPC4_POWER_STATE_INFO_GET: return basefw_power_state_info_get(data_offset, data); + case IPC4_SCHEDULERS_INFO_GET: + return schedulers_info_get(data_offset, data, + extended_param_id.part.parameter_instance); /* TODO: add more support */ case IPC4_DSP_RESOURCE_STATE: case IPC4_NOTIFICATION_MASK: case IPC4_MODULES_INFO_GET: case IPC4_PIPELINE_LIST_INFO_GET: case IPC4_PIPELINE_PROPS_GET: - case IPC4_SCHEDULERS_INFO_GET: case IPC4_GATEWAYS_INFO_GET: case IPC4_LIBRARIES_INFO_GET: case IPC4_PERF_MEASUREMENTS_STATE: diff --git a/src/include/ipc4/base_fw.h b/src/include/ipc4/base_fw.h index 5aa1f168b675..1d1648d73cd0 100644 --- a/src/include/ipc4/base_fw.h +++ b/src/include/ipc4/base_fw.h @@ -671,4 +671,34 @@ enum ipc4_power_state_type { IPC4_CORE_KCPS = 1, }; +/* Scheduler info get structures */ + +struct task_props { + /* Unique ID of task. */ + uint32_t task_id; + /* Specifies number of items in module_instance_id array. */ + uint32_t module_instance_count; + /* Array of IDs of module instances running inside the task. */ + uint32_t module_instance_id[]; +} __packed __aligned(4); + +struct scheduler_props { + /* Processing domain, one of: + * COMP_PROCESSING_DOMAIN_LL or COMP_PROCESSING_DOMAIN_DP + */ + uint32_t processing_domain; + /* ID of core that scheduler is running on. */ + uint32_t core_id; + /* Specifies number of items in task_info array. */ + uint32_t task_count; + struct task_props task_info[]; +} __packed __aligned(4); + +struct schedulers_info { + /* Specifies number of items in scheduler_info array. */ + uint32_t scheduler_count; + /* Array of scheduler properties. */ + struct scheduler_props scheduler_info[]; +} __packed __aligned(4); + #endif /* __SOF_IPC4_BASE_FW_H__ */ diff --git a/src/include/sof/schedule/dp_schedule.h b/src/include/sof/schedule/dp_schedule.h index 9b7f85c7e798..4a086ae448b1 100644 --- a/src/include/sof/schedule/dp_schedule.h +++ b/src/include/sof/schedule/dp_schedule.h @@ -12,6 +12,7 @@ #include #include #include +#include struct processing_module; @@ -76,4 +77,7 @@ int scheduler_dp_task_init(struct task **task, size_t stack_size, uint32_t task_priority); +void scheduler_get_task_info_dp(struct scheduler_props *scheduler_props, + uint32_t *data_off_size); + #endif /* __SOF_SCHEDULE_DP_SCHEDULE_H__ */ diff --git a/src/include/sof/schedule/ll_schedule.h b/src/include/sof/schedule/ll_schedule.h index 0d2d3d6d13de..31148c70abd9 100644 --- a/src/include/sof/schedule/ll_schedule.h +++ b/src/include/sof/schedule/ll_schedule.h @@ -17,6 +17,7 @@ #include #include #include +#include struct ll_schedule_domain; @@ -54,4 +55,10 @@ int zephyr_ll_task_init(struct task *task, #endif +void scheduler_get_task_info_ll(struct scheduler_props *scheduler_props, + uint32_t *data_off_size); + +void scheduler_get_task_info_ll_dma(struct scheduler_props *scheduler_props, + uint32_t *data_off_size); + #endif /* __SOF_SCHEDULE_LL_SCHEDULE_H__ */ diff --git a/src/include/sof/schedule/schedule.h b/src/include/sof/schedule/schedule.h index e503333942ac..927abe0983e0 100644 --- a/src/include/sof/schedule/schedule.h +++ b/src/include/sof/schedule/schedule.h @@ -17,6 +17,7 @@ #include #include #include +#include /** \addtogroup schedule_api Schedule API * @{ @@ -399,6 +400,9 @@ int schedule_task_init(struct task *task, */ void scheduler_init(int type, const struct scheduler_ops *ops, void *data); +void scheduler_get_task_info(struct scheduler_props *scheduler_props, + uint32_t *data_off_size, struct list_item *tasks, char *data); + /** @}*/ #endif /* __SOF_SCHEDULE_SCHEDULE_H__ */ diff --git a/src/schedule/schedule.c b/src/schedule/schedule.c index aefd13ca9c6a..cc0afd55f6ed 100644 --- a/src/schedule/schedule.c +++ b/src/schedule/schedule.c @@ -14,6 +14,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(schedule, CONFIG_SOF_LOG_LEVEL); @@ -75,3 +76,33 @@ void scheduler_init(int type, const struct scheduler_ops *ops, void *data) scheduler_register(sch); } + +void scheduler_get_task_info(struct scheduler_props *scheduler_props, + uint32_t *data_off_size, + struct list_item *tasks, char *data) +{ + /* TODO + * - container_of(tlist, struct task, list)->uid->id could possibly be used as task id, + * but currently accessing it crashes, so setting the value to 0 for now + */ + struct task_props *task_props; + struct list_item *tlist; + + scheduler_props->core_id = cpu_get_id(); + scheduler_props->task_count = 0; + *data_off_size += sizeof(struct scheduler_props); + + list_for_item(tlist, tasks) { + /* Fill SchedulerProps */ + scheduler_props->task_count++; + task_props = (struct task_props *) + ((uint8_t *)scheduler_props + sizeof(struct scheduler_props)); + + /* Fill TaskProps */ + task_props->task_id = 0; + *data_off_size += sizeof(struct task_props); + + /* Left unimplemented */ + task_props->module_instance_count = 0; + } +} diff --git a/src/schedule/zephyr_dp_schedule.c b/src/schedule/zephyr_dp_schedule.c index 2e3eed146586..77a32b507783 100644 --- a/src/schedule/zephyr_dp_schedule.c +++ b/src/schedule/zephyr_dp_schedule.c @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -533,3 +534,12 @@ int scheduler_dp_task_init(struct task **task, rfree(task_memory); return ret; } + +void scheduler_get_task_info_dp(struct scheduler_props *scheduler_props, uint32_t *data_off_size) +{ + scheduler_props->processing_domain = COMP_PROCESSING_DOMAIN_DP; + struct scheduler_dp_data *dp_sch = + (struct scheduler_dp_data *)scheduler_get_data(SOF_SCHEDULE_DP); + + scheduler_get_task_info(scheduler_props, data_off_size, &dp_sch->tasks, NULL); +} diff --git a/src/schedule/zephyr_ll.c b/src/schedule/zephyr_ll.c index 2069bb6585c4..63c531733759 100644 --- a/src/schedule/zephyr_ll.c +++ b/src/schedule/zephyr_ll.c @@ -14,6 +14,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(ll_schedule, CONFIG_SOF_LOG_LEVEL); @@ -527,3 +528,21 @@ int zephyr_ll_scheduler_init(struct ll_schedule_domain *domain) return 0; } + +void scheduler_get_task_info_ll(struct scheduler_props *scheduler_props, + uint32_t *data_off_size) +{ + scheduler_props->processing_domain = COMP_PROCESSING_DOMAIN_LL; + struct zephyr_ll *ll_sch = (struct zephyr_ll *)scheduler_get_data(SOF_SCHEDULE_LL_TIMER); + + scheduler_get_task_info(scheduler_props, data_off_size, &ll_sch->tasks, NULL); +} + +void scheduler_get_task_info_ll_dma(struct scheduler_props *scheduler_props, + uint32_t *data_off_size) +{ + scheduler_props->processing_domain = COMP_PROCESSING_DOMAIN_LL; + struct zephyr_ll *ll_sch = (struct zephyr_ll *)scheduler_get_data(SOF_SCHEDULE_LL_DMA); + + scheduler_get_task_info(scheduler_props, data_off_size, &ll_sch->tasks, NULL); +}