Lines Matching +full:x +full:- +full:size
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
9 #include "sof-priv.h"
10 #include "sof-audio.h"
11 #include "ipc3-priv.h"
20 memcpy(&sdev->fw_ready.version, &v->version, sizeof(v->version)); in ipc3_fw_ext_man_get_version()
21 sdev->fw_ready.flags = v->flags; in ipc3_fw_ext_man_get_version()
34 return sof_ipc3_get_ext_windows(sdev, &w->ipc_window.ext_hdr); in ipc3_fw_ext_man_get_windows()
44 return sof_ipc3_get_cc_info(sdev, &cc->cc_version.ext_hdr); in ipc3_fw_ext_man_get_cc_info()
53 if (sdev->first_boot) in ipc3_fw_ext_man_get_dbg_abi_info()
54 dev_dbg(sdev->dev, in ipc3_fw_ext_man_get_dbg_abi_info()
56 SOF_ABI_VERSION_MAJOR(dbg_abi->dbg_abi.abi_dbg_version), in ipc3_fw_ext_man_get_dbg_abi_info()
57 SOF_ABI_VERSION_MINOR(dbg_abi->dbg_abi.abi_dbg_version), in ipc3_fw_ext_man_get_dbg_abi_info()
58 SOF_ABI_VERSION_PATCH(dbg_abi->dbg_abi.abi_dbg_version)); in ipc3_fw_ext_man_get_dbg_abi_info()
75 elems_size = config->hdr.size - sizeof(struct sof_ext_man_elem_header); in ipc3_fw_ext_man_get_config_data()
78 dev_dbg(sdev->dev, "manifest can hold up to %d config elements\n", elems_counter); in ipc3_fw_ext_man_get_config_data()
81 elem = &config->elems[i]; in ipc3_fw_ext_man_get_config_data()
82 dev_dbg(sdev->dev, "get index %d token %d val %d\n", in ipc3_fw_ext_man_get_config_data()
83 i, elem->token, elem->value); in ipc3_fw_ext_man_get_config_data()
84 switch (elem->token) { in ipc3_fw_ext_man_get_config_data()
86 /* unused memory space is zero filled - mapped to EMPTY elements */ in ipc3_fw_ext_man_get_config_data()
89 /* TODO: use ipc msg size from config data */ in ipc3_fw_ext_man_get_config_data()
92 if (sdev->first_boot && elem->value) in ipc3_fw_ext_man_get_config_data()
96 dev_info(sdev->dev, in ipc3_fw_ext_man_get_config_data()
98 elem->token, elem->value); in ipc3_fw_ext_man_get_config_data()
102 dev_err(sdev->dev, in ipc3_fw_ext_man_get_config_data()
103 "%s: processing failed for token %d value %#x, %d\n", in ipc3_fw_ext_man_get_config_data()
104 __func__, elem->token, elem->value, ret); in ipc3_fw_ext_man_get_config_data()
116 head = (struct sof_ext_man_header *)fw->data; in ipc3_fw_ext_man_size()
119 * assert fw size is big enough to contain extended manifest header, in ipc3_fw_ext_man_size()
123 if (fw->size < sizeof(*head)) in ipc3_fw_ext_man_size()
124 return -EINVAL; in ipc3_fw_ext_man_size()
130 if (head->magic == SOF_EXT_MAN_MAGIC_NUMBER) in ipc3_fw_ext_man_size()
131 return head->full_size; in ipc3_fw_ext_man_size()
134 dev_dbg(sdev->dev, "Unexpected extended manifest magic number: %#x\n", in ipc3_fw_ext_man_size()
135 head->magic); in ipc3_fw_ext_man_size()
141 const struct firmware *fw = sdev->basefw.fw; in sof_ipc3_fw_parse_ext_man()
149 head = (struct sof_ext_man_header *)fw->data; in sof_ipc3_fw_parse_ext_man()
150 remaining = head->full_size - head->header_size; in sof_ipc3_fw_parse_ext_man()
151 if (remaining < 0 || remaining > sdev->basefw.fw->size) in sof_ipc3_fw_parse_ext_man()
152 return -EINVAL; in sof_ipc3_fw_parse_ext_man()
161 head->header_version)) { in sof_ipc3_fw_parse_ext_man()
162 dev_err(sdev->dev, in sof_ipc3_fw_parse_ext_man()
163 "extended manifest version %#x differ from used %#x\n", in sof_ipc3_fw_parse_ext_man()
164 head->header_version, SOF_EXT_MAN_VERSION); in sof_ipc3_fw_parse_ext_man()
165 return -EINVAL; in sof_ipc3_fw_parse_ext_man()
169 iptr = (uintptr_t)fw->data + head->header_size; in sof_ipc3_fw_parse_ext_man()
174 dev_dbg(sdev->dev, "found sof_ext_man header type %d size %#x\n", in sof_ipc3_fw_parse_ext_man()
175 elem_hdr->type, elem_hdr->size); in sof_ipc3_fw_parse_ext_man()
177 if (elem_hdr->size < sizeof(*elem_hdr) || in sof_ipc3_fw_parse_ext_man()
178 elem_hdr->size > remaining) { in sof_ipc3_fw_parse_ext_man()
179 dev_err(sdev->dev, in sof_ipc3_fw_parse_ext_man()
180 "invalid sof_ext_man header size, type %d size %#x\n", in sof_ipc3_fw_parse_ext_man()
181 elem_hdr->type, elem_hdr->size); in sof_ipc3_fw_parse_ext_man()
182 return -EINVAL; in sof_ipc3_fw_parse_ext_man()
186 switch (elem_hdr->type) { in sof_ipc3_fw_parse_ext_man()
206 dev_info(sdev->dev, in sof_ipc3_fw_parse_ext_man()
207 "unknown sof_ext_man header type %d size %#x\n", in sof_ipc3_fw_parse_ext_man()
208 elem_hdr->type, elem_hdr->size); in sof_ipc3_fw_parse_ext_man()
213 dev_err(sdev->dev, in sof_ipc3_fw_parse_ext_man()
214 "failed to parse sof_ext_man header type %d size %#x\n", in sof_ipc3_fw_parse_ext_man()
215 elem_hdr->type, elem_hdr->size); in sof_ipc3_fw_parse_ext_man()
219 remaining -= elem_hdr->size; in sof_ipc3_fw_parse_ext_man()
220 iptr += elem_hdr->size; in sof_ipc3_fw_parse_ext_man()
224 dev_err(sdev->dev, "error: sof_ext_man header is inconsistent\n"); in sof_ipc3_fw_parse_ext_man()
225 return -EINVAL; in sof_ipc3_fw_parse_ext_man()
240 dev_dbg(sdev->dev, "new module size %#x blocks %#x type %#x\n", in sof_ipc3_parse_module_memcpy()
241 module->size, module->num_blocks, module->type); in sof_ipc3_parse_module_memcpy()
245 /* module->size doesn't include header size */ in sof_ipc3_parse_module_memcpy()
246 remaining = module->size; in sof_ipc3_parse_module_memcpy()
247 for (count = 0; count < module->num_blocks; count++) { in sof_ipc3_parse_module_memcpy()
250 dev_err(sdev->dev, "not enough data remaining\n"); in sof_ipc3_parse_module_memcpy()
251 return -EINVAL; in sof_ipc3_parse_module_memcpy()
254 /* minus header size of block */ in sof_ipc3_parse_module_memcpy()
255 remaining -= sizeof(*block); in sof_ipc3_parse_module_memcpy()
257 if (block->size == 0) { in sof_ipc3_parse_module_memcpy()
258 dev_warn(sdev->dev, in sof_ipc3_parse_module_memcpy()
259 "warning: block %d size zero\n", count); in sof_ipc3_parse_module_memcpy()
260 dev_warn(sdev->dev, " type %#x offset %#x\n", in sof_ipc3_parse_module_memcpy()
261 block->type, block->offset); in sof_ipc3_parse_module_memcpy()
265 switch (block->type) { in sof_ipc3_parse_module_memcpy()
272 offset = block->offset; in sof_ipc3_parse_module_memcpy()
275 dev_err(sdev->dev, "%s: bad type %#x for block %#x\n", in sof_ipc3_parse_module_memcpy()
276 __func__, block->type, count); in sof_ipc3_parse_module_memcpy()
277 return -EINVAL; in sof_ipc3_parse_module_memcpy()
280 dev_dbg(sdev->dev, "block %d type %#x size %#x ==> offset %#x\n", in sof_ipc3_parse_module_memcpy()
281 count, block->type, block->size, offset); in sof_ipc3_parse_module_memcpy()
283 /* checking block->size to avoid unaligned access */ in sof_ipc3_parse_module_memcpy()
284 if (block->size % sizeof(u32)) { in sof_ipc3_parse_module_memcpy()
285 dev_err(sdev->dev, "%s: invalid block size %#x\n", in sof_ipc3_parse_module_memcpy()
286 __func__, block->size); in sof_ipc3_parse_module_memcpy()
287 return -EINVAL; in sof_ipc3_parse_module_memcpy()
289 ret = snd_sof_dsp_block_write(sdev, block->type, offset, in sof_ipc3_parse_module_memcpy()
290 block + 1, block->size); in sof_ipc3_parse_module_memcpy()
292 dev_err(sdev->dev, "%s: write to block type %#x failed\n", in sof_ipc3_parse_module_memcpy()
293 __func__, block->type); in sof_ipc3_parse_module_memcpy()
297 if (remaining < block->size) { in sof_ipc3_parse_module_memcpy()
298 dev_err(sdev->dev, "%s: not enough data remaining\n", __func__); in sof_ipc3_parse_module_memcpy()
299 return -EINVAL; in sof_ipc3_parse_module_memcpy()
302 /* minus body size of block */ in sof_ipc3_parse_module_memcpy()
303 remaining -= block->size; in sof_ipc3_parse_module_memcpy()
306 + block->size); in sof_ipc3_parse_module_memcpy()
314 u32 payload_offset = sdev->basefw.payload_offset; in sof_ipc3_load_fw_to_dsp()
315 const struct firmware *fw = sdev->basefw.fw; in sof_ipc3_load_fw_to_dsp()
323 return -EINVAL; in sof_ipc3_load_fw_to_dsp()
325 header = (struct snd_sof_fw_header *)(fw->data + payload_offset); in sof_ipc3_load_fw_to_dsp()
326 load_module = sof_ops(sdev)->load_module; in sof_ipc3_load_fw_to_dsp()
328 dev_dbg(sdev->dev, "Using generic module loading\n"); in sof_ipc3_load_fw_to_dsp()
331 dev_dbg(sdev->dev, "Using custom module loading\n"); in sof_ipc3_load_fw_to_dsp()
335 module = (struct snd_sof_mod_hdr *)(fw->data + payload_offset + sizeof(*header)); in sof_ipc3_load_fw_to_dsp()
336 remaining = fw->size - sizeof(*header) - payload_offset; in sof_ipc3_load_fw_to_dsp()
338 if (remaining > fw->size) { in sof_ipc3_load_fw_to_dsp()
339 dev_err(sdev->dev, "%s: fw size smaller than header size\n", __func__); in sof_ipc3_load_fw_to_dsp()
340 return -EINVAL; in sof_ipc3_load_fw_to_dsp()
343 for (count = 0; count < header->num_modules; count++) { in sof_ipc3_load_fw_to_dsp()
346 dev_err(sdev->dev, "%s: not enough data for a module\n", in sof_ipc3_load_fw_to_dsp()
348 return -EINVAL; in sof_ipc3_load_fw_to_dsp()
351 /* minus header size of module */ in sof_ipc3_load_fw_to_dsp()
352 remaining -= sizeof(*module); in sof_ipc3_load_fw_to_dsp()
357 dev_err(sdev->dev, "%s: invalid module %d\n", __func__, count); in sof_ipc3_load_fw_to_dsp()
361 if (remaining < module->size) { in sof_ipc3_load_fw_to_dsp()
362 dev_err(sdev->dev, "%s: not enough data remaining\n", __func__); in sof_ipc3_load_fw_to_dsp()
363 return -EINVAL; in sof_ipc3_load_fw_to_dsp()
366 /* minus body size of module */ in sof_ipc3_load_fw_to_dsp()
367 remaining -= module->size; in sof_ipc3_load_fw_to_dsp()
369 sizeof(*module) + module->size); in sof_ipc3_load_fw_to_dsp()
377 u32 payload_offset = sdev->basefw.payload_offset; in sof_ipc3_validate_firmware()
378 const struct firmware *fw = sdev->basefw.fw; in sof_ipc3_validate_firmware()
380 size_t fw_size = fw->size - payload_offset; in sof_ipc3_validate_firmware()
382 if (fw->size <= payload_offset) { in sof_ipc3_validate_firmware()
383 dev_err(sdev->dev, in sof_ipc3_validate_firmware()
384 "firmware size must be greater than firmware offset\n"); in sof_ipc3_validate_firmware()
385 return -EINVAL; in sof_ipc3_validate_firmware()
389 header = (struct snd_sof_fw_header *)(fw->data + payload_offset); in sof_ipc3_validate_firmware()
392 if (strncmp(header->sig, SND_SOF_FW_SIG, SND_SOF_FW_SIG_SIZE) != 0) { in sof_ipc3_validate_firmware()
393 dev_err(sdev->dev, "invalid firmware signature\n"); in sof_ipc3_validate_firmware()
394 return -EINVAL; in sof_ipc3_validate_firmware()
397 /* check size is valid */ in sof_ipc3_validate_firmware()
398 if (fw_size != header->file_size + sizeof(*header)) { in sof_ipc3_validate_firmware()
399 dev_err(sdev->dev, in sof_ipc3_validate_firmware()
400 "invalid filesize mismatch got 0x%zx expected 0x%zx\n", in sof_ipc3_validate_firmware()
401 fw_size, header->file_size + sizeof(*header)); in sof_ipc3_validate_firmware()
402 return -EINVAL; in sof_ipc3_validate_firmware()
405 dev_dbg(sdev->dev, "header size=0x%x modules=0x%x abi=0x%x size=%zu\n", in sof_ipc3_validate_firmware()
406 header->file_size, header->num_modules, in sof_ipc3_validate_firmware()
407 header->abi, sizeof(*header)); in sof_ipc3_validate_firmware()