-
Notifications
You must be signed in to change notification settings - Fork 347
Code to decode pipeline create messages payload #10265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a850601
e5b4b43
17d11a5
35f67ed
73710ca
6f79982
d9de565
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -139,8 +139,8 @@ __cold struct comp_dev *comp_new_ipc4(struct ipc4_module_init_instance *module_i | |
| ipc_config.ipc_config_size = module_init->extension.r.param_block_size * sizeof(uint32_t); | ||
| ipc_config.ipc_extended_init = module_init->extension.r.extended_init; | ||
|
|
||
| dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, | ||
| MAILBOX_HOSTBOX_SIZE); | ||
| sys_cache_data_invd_range((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, | ||
| ipc_config.ipc_config_size); | ||
|
|
||
| data = ipc4_get_comp_new_data(); | ||
|
|
||
|
|
@@ -229,7 +229,92 @@ struct ipc_comp_dev *ipc_get_comp_by_ppl_id(struct ipc *ipc, uint16_t type, | |
| return NULL; | ||
| } | ||
|
|
||
| __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc) | ||
| /* | ||
| * This function currently only decodes the payload and prints out | ||
| * data it finds, but it does not store it anywhere. | ||
| */ | ||
| __cold static int ipc4_create_pipeline_payload_decode(char *data, struct pipeline_params *pparams) | ||
| { | ||
| const struct ipc4_pipeline_ext_payload *hdr = | ||
| (struct ipc4_pipeline_ext_payload *)data; | ||
| const struct ipc4_pipeline_ext_object *obj; | ||
| size_t hdr_cache_size = ALIGN_UP(sizeof(*hdr), CONFIG_DCACHE_LINE_SIZE); | ||
| bool last_object; | ||
| size_t size; | ||
|
|
||
| sys_cache_data_invd_range((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, | ||
| hdr_cache_size); | ||
| size = hdr->payload_words * sizeof(uint32_t); | ||
| last_object = !hdr->data_obj_array; | ||
|
|
||
| if (hdr->payload_words * sizeof(uint32_t) < sizeof(*hdr)) { | ||
| tr_err(&ipc_tr, "Payload size too small: %u : %#x", hdr->payload_words, | ||
| *((uint32_t *)hdr)); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| tr_info(&ipc_tr, "payload size %u array %u: %#x", hdr->payload_words, hdr->data_obj_array, | ||
| *((uint32_t *)hdr)); | ||
|
|
||
| if (ALIGN_UP(size, CONFIG_DCACHE_LINE_SIZE) > hdr_cache_size) | ||
| sys_cache_data_invd_range((__sparse_force void __sparse_cache *) | ||
| ((char *)MAILBOX_HOSTBOX_BASE + hdr_cache_size), | ||
| ALIGN_UP(size, CONFIG_DCACHE_LINE_SIZE) - | ||
| hdr_cache_size); | ||
|
|
||
| obj = (const struct ipc4_pipeline_ext_object *)(hdr + 1); | ||
| while (!last_object) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like while() better, especially as its now a better match to module_ext_init_decode() implementation |
||
| const struct ipc4_pipeline_ext_object *next_obj; | ||
|
|
||
| /* Check if there is space for the object header */ | ||
| if ((char *)(obj + 1) - data > size) { | ||
| tr_err(&ipc_tr, "obj header overflow, %u > %u", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't the format be |
||
| (char *)(obj + 1) - data, size); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| /* Calculate would be next object position and check if current object fits */ | ||
| next_obj = (const struct ipc4_pipeline_ext_object *) | ||
| (((uint32_t *)(obj + 1)) + obj->object_words); | ||
| if ((char *)next_obj - data > size) { | ||
| tr_err(&ipc_tr, "object size overflow, %u > %u", | ||
| (char *)obj - data, size); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| switch (obj->object_id) { | ||
| case IPC4_GLB_PIPE_EXT_OBJ_ID_MEM_DATA: | ||
| { | ||
| /* Get mem_data struct that follows the obj struct */ | ||
| const struct ipc4_pipeline_ext_obj_mem_data *mem_data = | ||
| (const struct ipc4_pipeline_ext_obj_mem_data *)(obj + 1); | ||
|
|
||
| if (obj->object_words * sizeof(uint32_t) < sizeof(*mem_data)) { | ||
| tr_err(&ipc_tr, "mem_data object does not fit %u < %u", | ||
| obj->object_words * sizeof(uint32_t), sizeof(*mem_data)); | ||
| return -EINVAL; | ||
| } | ||
| tr_info(&ipc_tr, | ||
| "init_ext_obj_mem_data domain %u stack %u heap %u lifetime %u shared %u", | ||
| mem_data->domain_id, mem_data->stack_bytes, mem_data->heap_bytes, | ||
| mem_data->lifetime_bytes, mem_data->shared_bytes); | ||
| break; | ||
| } | ||
| default: | ||
| tr_info(&ipc_tr, "Unknown ext init object id %u of %u words", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you have agains info 😄? If I must change this I'd go with warn, as if somebody is indeed reading the logs, it could be useful to know that the firmware is not able to use all info from the pipeline create payload.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. supposedly we have all the different logging levels for a reason, so we might as well use them ;-) It's just that a message, beginning with "Unknown" but with a neutral status is a bit unclear to me. Is it bad or not? If it isn't bad - do I need to know about it? If not - maybe make it |
||
| obj->object_id, obj->object_words); | ||
| } | ||
| /* Read the last object flag from obj header */ | ||
| last_object = obj->last_object; | ||
| /* Move to next object */ | ||
| obj = next_obj; | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc, | ||
| struct pipeline_params *pparams) | ||
| { | ||
| struct ipc_comp_dev *ipc_pipe; | ||
| struct pipeline *pipe; | ||
|
|
@@ -246,7 +331,8 @@ __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc) | |
| } | ||
|
|
||
| /* create the pipeline */ | ||
| pipe = pipeline_new(pipe_desc->primary.r.instance_id, pipe_desc->primary.r.ppl_priority, 0); | ||
| pipe = pipeline_new(pipe_desc->primary.r.instance_id, pipe_desc->primary.r.ppl_priority, 0, | ||
| pparams); | ||
| if (!pipe) { | ||
| tr_err(&ipc_tr, "ipc: pipeline_new() failed"); | ||
| return IPC4_OUT_OF_MEMORY; | ||
|
|
@@ -280,11 +366,28 @@ __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc) | |
| return IPC4_SUCCESS; | ||
| } | ||
|
|
||
| #if CONFIG_LIBRARY | ||
| static inline char *ipc4_get_pipe_create_data(void) | ||
| { | ||
| struct ipc *ipc = ipc_get(); | ||
| char *data = (char *)ipc->comp_data + sizeof(struct ipc4_pipeline_create); | ||
|
|
||
| return data; | ||
| } | ||
| #else | ||
| __cold static inline char *ipc4_get_pipe_create_data(void) | ||
| { | ||
| assert_can_be_cold(); | ||
|
|
||
| return (char *)MAILBOX_HOSTBOX_BASE; | ||
| } | ||
| #endif | ||
|
|
||
| /* Only called from ipc4_new_pipeline(), which is __cold */ | ||
| __cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc) | ||
| { | ||
| struct ipc4_pipeline_create *pipe_desc = ipc_from_pipe_new(_pipe_desc); | ||
|
|
||
| struct pipeline_params pparams; | ||
| assert_can_be_cold(); | ||
|
|
||
| tr_dbg(&ipc_tr, "ipc: pipeline id = %u", (uint32_t)pipe_desc->primary.r.instance_id); | ||
|
|
@@ -293,7 +396,15 @@ __cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc) | |
| if (!cpu_is_me(pipe_desc->extension.r.core_id)) | ||
| return ipc4_process_on_core(pipe_desc->extension.r.core_id, false); | ||
|
|
||
| return ipc4_create_pipeline(pipe_desc); | ||
| if (pipe_desc->extension.r.payload) { | ||
| char *data; | ||
|
|
||
| data = ipc4_get_pipe_create_data(); | ||
|
|
||
| ipc4_create_pipeline_payload_decode(data, &pparams); | ||
| } | ||
|
|
||
| return ipc4_create_pipeline(pipe_desc, &pparams); | ||
| } | ||
|
|
||
| __cold static inline int ipc_comp_free_remote(struct comp_dev *dev) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on the one hand bytes are simple to understand and work with. OTOH if we use a larger unit (words, or cache lines, or pages), then we (1) can potentially use a smaller integer, (2) avoid the need to check and enforce alignment. No strong preference, just a thought
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bytes fine here since these are uint32_t - we should have enough space.