2121#include <stddef.h>
2222#include <stdint.h>
2323
24+ #include <sof/lib_manager.h>
25+ #include <ipc4/base_fw_vendor.h>
26+
2427LOG_MODULE_DECLARE (ipc , CONFIG_SOF_LOG_LEVEL );
2528
2629#define PERFORMANCE_DATA_ENTRIES_COUNT (CONFIG_MEMORY_WIN_3_SIZE / sizeof(struct perf_data_item_comp))
@@ -37,6 +40,12 @@ struct perf_bitmap performance_data_bitmap;
3740
3841volatile struct perf_data_item_comp * perf_data_ ;
3942
43+ /* Note that ref. FW used one state per core, all set together to the same state
44+ * by one IPC but only for active cores. It may work slightly different in case
45+ * where we enable a core while perf meas is started.
46+ */
47+ enum ipc4_perf_measurements_state_set perf_measurements_state = IPC4_PERF_MEASUREMENTS_DISABLED ;
48+
4049int perf_bitmap_init (struct perf_bitmap * const bitmap , sys_bitarray_t * array , size_t size )
4150{
4251 bitmap -> array = array ;
@@ -198,9 +207,15 @@ int free_performance_data(struct perf_data_item_comp *item)
198207
199208 if (item ) {
200209 item -> item .is_removed = true;
201- ret = perf_data_free (item );
202- if (ret < 0 )
203- return - EINVAL ;
210+ /* if we don't get the disabled state now, item will be
211+ * deleted on next disable perf meas message
212+ */
213+ if (perf_measurements_state == IPC4_PERF_MEASUREMENTS_DISABLED ) {
214+ int ret = perf_data_free (item );
215+
216+ if (ret < 0 )
217+ return - EINVAL ;
218+ }
204219 }
205220 return IPC4_SUCCESS ;
206221}
@@ -266,7 +281,91 @@ int get_extended_performance_data(struct extended_global_perf_data * const ext_g
266281 return IPC4_SUCCESS ;
267282}
268283
269- //==============================================================================================
284+ enum ipc4_perf_measurements_state_set perf_meas_get_state (void )
285+ {
286+ return perf_measurements_state ;
287+ }
288+
289+ void perf_meas_set_state (enum ipc4_perf_measurements_state_set state )
290+ {
291+ perf_measurements_state = state ;
292+ }
293+
294+ void disable_performance_counters (void )
295+ {
296+ for (size_t idx = 0 ; idx < perf_bitmap_get_size (& performance_data_bitmap ); ++ idx ) {
297+ if (perf_bitmap_is_bit_clear (& performance_data_bitmap , idx ))
298+ continue ;
299+ if (perf_data_ [idx ].item .is_removed )
300+ perf_data_free (& perf_data_ [idx ]);
301+ }
302+ }
303+
304+ int enable_performance_counters (void )
305+ {
306+ //struct sof_man_fw_header header;
307+ struct sof_man_module * man_module ;
308+ struct comp_dev * dev ;
309+ uint32_t comp_id ;
310+ const struct sof_man_fw_desc * desc ;
311+
312+ if (perf_measurements_state != IPC4_PERF_MEASUREMENTS_DISABLED )
313+ return - EINVAL ;
314+
315+ for (int lib_id = 0 ; lib_id < LIB_MANAGER_MAX_LIBS ; ++ lib_id ) {
316+ if (lib_id == 0 ) {
317+ desc = basefw_vendor_get_manifest ();
318+ } else {
319+ #if CONFIG_LIBRARY_MANAGER
320+ desc = (struct sof_man_fw_desc * )lib_manager_get_library_manifest (lib_id );
321+ #else
322+ desc = NULL ;
323+ #endif
324+ }
325+ if (!desc )
326+ continue ;
327+
328+ for (int mod_id = 0 ; mod_id < desc -> header .num_module_entries ; mod_id ++ ) {
329+ man_module =
330+ (struct sof_man_module * )(desc + SOF_MAN_MODULE_OFFSET (mod_id ));
331+
332+ for (int inst_id = 0 ; inst_id < man_module -> instance_max_count ; inst_id ++ ) {
333+ comp_id = IPC4_COMP_ID (mod_id , inst_id );
334+ dev = ipc4_get_comp_dev (comp_id );
335+
336+ if (dev )
337+ comp_init_performance_data (dev );
338+ }
339+ }
340+ }
341+
342+ /* TODO clear totaldspcycles here once implemented */
343+ return IPC4_SUCCESS ;
344+ }
345+
346+ int reset_performance_counters (void )
347+ {
348+ if (perf_measurements_state == IPC4_PERF_MEASUREMENTS_DISABLED )
349+ return - EINVAL ;
350+
351+ struct telemetry_wnd_data * wnd_data =
352+ (struct telemetry_wnd_data * )ADSP_DW -> slots [SOF_DW_TELEMETRY_SLOT ];
353+ struct system_tick_info * systick_info =
354+ (struct system_tick_info * )wnd_data -> system_tick_info ;
355+
356+ for (size_t core_id = 0 ; core_id < CONFIG_MAX_CORE_COUNT ; ++ core_id ) {
357+ if (!(cpu_enabled_cores () & BIT (core_id )))
358+ continue ;
359+ systick_info [core_id ].peak_utilization = 0 ;
360+ }
361+ for (size_t idx = 0 ; idx < perf_bitmap_get_size (& performance_data_bitmap ); ++ idx ) {
362+ if (!perf_bitmap_is_bit_clear (& performance_data_bitmap , idx ))
363+ perf_data_item_comp_reset (& perf_data_ [idx ]);
364+ }
365+ /* TODO clear totaldspcycles here once implemented */
366+
367+ return IPC4_SUCCESS ;
368+ }
270369
271370/* Systic variables, one set per core */
272371static int telemetry_systick_counter [CONFIG_MAX_CORE_COUNT ];
0 commit comments