The window description can be extracted from the extended manifest content. This information known at build time does not need to be provided in a mailbox.
Unified · Split
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #define __SOF_FIRMWARE_EXT_MANIFEST_H__ |
| 18 | 18 | |
| 19 | 19 | #include <linux/const.h> |
| 20 | +#include <sound/sof/info.h> | |
| 20 | 21 | |
| 21 | 22 | /* In ASCII `XMan` */ |
| 22 | 23 | #define SOF_EXT_MAN_MAGIC_NUMBER 0x6e614d58 |
| @@ -54,6 +55,7 @@ struct sof_ext_man_header { · 31 unmodified lines | ||
| 54 | 55 | /* Extended manifest elements types */ |
| 55 | 56 | enum sof_ext_man_elem_type { |
| 56 | 57 | SOF_EXT_MAN_ELEM_FW_VERSION = 0, |
| 58 | + SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW, | |
| 57 | 59 | }; |
| 58 | 60 | |
| 59 | 61 | /* extended manifest element header */ |
| @@ -71,4 +73,11 @@ struct sof_ext_man_fw_version { · 11 unmodified lines | ||
| 71 | 73 | uint32_t flags; |
| 72 | 74 | } __packed; |
| 73 | 75 | |
| 76 | +/* extended data memory windows for IPC, trace and debug */ | |
| 77 | +struct sof_ext_man_window { | |
| 78 | + struct sof_ext_man_elem_header hdr; | |
| 79 | + /* use sof_ipc struct because of code re-use */ | |
| 80 | + struct sof_ipc_window ipc_window; | |
| 81 | +} __packed; | |
| 82 | + | |
| 74 | 83 | #endif /* __SOF_FIRMWARE_EXT_MANIFEST_H__ */ |
| @@ -20,13 +20,21 @@ static int get_ext_windows(struct snd_sof_dev *sdev, · 19 unmodified lines | ||
| 20 | 20 | { |
| 21 | 21 | const struct sof_ipc_window *w = |
| 22 | 22 | container_of(ext_hdr, struct sof_ipc_window, ext_hdr); |
| 23 | + size_t w_size = struct_size(w, window, w->num_windows); | |
| 24 | + | |
| 25 | + if (sdev->info_window) { | |
| 26 | + if (memcmp(sdev->info_window, w, w_size)) { | |
| 27 | + dev_err(sdev->dev, "error: mistmatch between window descriptor from extended manifest and mailbox"); | |
| 28 | + return -EINVAL; | |
| 29 | + } | |
| 30 | + return 0; | |
| 31 | + } | |
| 23 | 32 | |
| 24 | 33 | if (w->num_windows == 0 || w->num_windows > SOF_IPC_MAX_ELEMS) |
| 25 | 34 | return -EINVAL; |
| 26 | 35 | |
| 27 | 36 | /* keep a local copy of the data */ |
| 28 | − sdev->info_window = kmemdup(w, struct_size(w, window, w->num_windows), | |
| 29 | − GFP_KERNEL); | |
| 37 | + sdev->info_window = kmemdup(w, w_size, GFP_KERNEL); | |
| 30 | 38 | if (!sdev->info_window) |
| 31 | 39 | return -ENOMEM; |
| 32 | 40 | |
| @@ -141,6 +149,18 @@ static int ext_man_get_fw_version(struct snd_sof_dev *sdev, · 108 unmodified lines | ||
| 141 | 149 | return snd_sof_ipc_valid(sdev); |
| 142 | 150 | } |
| 143 | 151 | |
| 152 | +static int ext_man_get_windows(struct snd_sof_dev *sdev, | |
| 153 | + const struct sof_ext_man_elem_header *hdr) | |
| 154 | +{ | |
| 155 | + const struct sof_ipc_ext_data_hdr *w_ipc; | |
| 156 | + const struct sof_ext_man_window *w; | |
| 157 | + | |
| 158 | + w = container_of(hdr, struct sof_ext_man_window, hdr); | |
| 159 | + w_ipc = (const struct sof_ipc_ext_data_hdr *)&w->ipc_window; | |
| 160 | + | |
| 161 | + return get_ext_windows(sdev, w_ipc); | |
| 162 | +} | |
| 163 | + | |
| 144 | 164 | static ssize_t snd_sof_ext_man_size(const struct firmware *fw) |
| 145 | 165 | { |
| 146 | 166 | const struct sof_ext_man_header *head = (void *)fw->data; |
| @@ -218,6 +238,9 @@ static int snd_sof_fw_ext_man_parse(struct snd_sof_dev *sdev, · 71 unmodified lines | ||
| 218 | 238 | case SOF_EXT_MAN_ELEM_FW_VERSION: |
| 219 | 239 | ret = ext_man_get_fw_version(sdev, elem_hdr); |
| 220 | 240 | break; |
| 241 | + case SOF_EXT_MAN_ELEM_WINDOW: | |
| 242 | + ret = ext_man_get_windows(sdev, elem_hdr); | |
| 243 | + break; | |
| 221 | 244 | default: |
| 222 | 245 | dev_warn(sdev->dev, "warning: unknown sof_ext_man header type %d size 0x%X\n", |
| 223 | 246 | elem_hdr->type, elem_hdr->size); |