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 | #define __SOF_FIRMWARE_EXT_MANIFEST_H__ | 17 | #define __SOF_FIRMWARE_EXT_MANIFEST_H__ |
| 18 | 18 | ||
| 19 | #include <linux/const.h> | 19 | #include <linux/const.h> |
| 20 | #include <sound/sof/info.h> | ||
| 20 | 21 | ||
| 21 | /* In ASCII `XMan` */ | 22 | /* In ASCII `XMan` */ |
| 22 | #define SOF_EXT_MAN_MAGIC_NUMBER 0x6e614d58 | 23 | #define SOF_EXT_MAN_MAGIC_NUMBER 0x6e614d58 |
| @@ -54,6 +55,7 @@ struct sof_ext_man_header { · 31 unmodified lines | |||
| 54 | /* Extended manifest elements types */ | 55 | /* Extended manifest elements types */ |
| 55 | enum sof_ext_man_elem_type { | 56 | enum sof_ext_man_elem_type { |
| 56 | SOF_EXT_MAN_ELEM_FW_VERSION = 0, | 57 | SOF_EXT_MAN_ELEM_FW_VERSION = 0, |
| 58 | SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW, | ||
| 57 | }; | 59 | }; |
| 58 | 60 | ||
| 59 | /* extended manifest element header */ | 61 | /* extended manifest element header */ |
| @@ -71,4 +73,11 @@ struct sof_ext_man_fw_version { · 11 unmodified lines | |||
| 71 | uint32_t flags; | 73 | uint32_t flags; |
| 72 | } __packed; | 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 | #endif /* __SOF_FIRMWARE_EXT_MANIFEST_H__ */ | 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 | const struct sof_ipc_window *w = | 21 | const struct sof_ipc_window *w = |
| 22 | container_of(ext_hdr, struct sof_ipc_window, ext_hdr); | 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 | if (w->num_windows == 0 || w->num_windows > SOF_IPC_MAX_ELEMS) | 33 | if (w->num_windows == 0 || w->num_windows > SOF_IPC_MAX_ELEMS) |
| 25 | return -EINVAL; | 34 | return -EINVAL; |
| 26 | 35 | ||
| 27 | /* keep a local copy of the data */ | 36 | /* keep a local copy of the data */ |
| 28 | sdev->info_window = kmemdup(w, struct_size(w, window, w->num_windows), | 37 | sdev->info_window = kmemdup(w, w_size, GFP_KERNEL); |
| 29 | GFP_KERNEL); | ||
| 30 | if (!sdev->info_window) | 38 | if (!sdev->info_window) |
| 31 | return -ENOMEM; | 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 | return snd_sof_ipc_valid(sdev); | 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 | static ssize_t snd_sof_ext_man_size(const struct firmware *fw) | 164 | static ssize_t snd_sof_ext_man_size(const struct firmware *fw) |
| 145 | { | 165 | { |
| 146 | const struct sof_ext_man_header *head = (void *)fw->data; | 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 | case SOF_EXT_MAN_ELEM_FW_VERSION: | 238 | case SOF_EXT_MAN_ELEM_FW_VERSION: |
| 219 | ret = ext_man_get_fw_version(sdev, elem_hdr); | 239 | ret = ext_man_get_fw_version(sdev, elem_hdr); |
| 220 | break; | 240 | break; |
| 241 | case SOF_EXT_MAN_ELEM_WINDOW: | ||
| 242 | ret = ext_man_get_windows(sdev, elem_hdr); | ||
| 243 | break; | ||
| 221 | default: | 244 | default: |
| 222 | dev_warn(sdev->dev, "warning: unknown sof_ext_man header type %d size 0x%X\n", | 245 | dev_warn(sdev->dev, "warning: unknown sof_ext_man header type %d size 0x%X\n", |
| 223 | elem_hdr->type, elem_hdr->size); | 246 | elem_hdr->type, elem_hdr->size); |