loader.c (ed32f8d42cee118b075e4372a55c7739a11094b2) | loader.c (83ee7ab1627b7597bbb9acc26b37e9f96fff40c9) |
---|---|
1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2// 3// This file is provided under a dual BSD/GPLv2 license. When using or 4// redistributing this file, you may do so under either license. 5// 6// Copyright(c) 2018 Intel Corporation. All rights reserved. 7// 8// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> --- 73 unchanged lines hidden (view full) --- 82 ext_hdr = ext_data; 83 } 84 85 kfree(ext_data); 86 return ret; 87} 88EXPORT_SYMBOL(snd_sof_fw_parse_ext_data); 89 | 1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2// 3// This file is provided under a dual BSD/GPLv2 license. When using or 4// redistributing this file, you may do so under either license. 5// 6// Copyright(c) 2018 Intel Corporation. All rights reserved. 7// 8// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> --- 73 unchanged lines hidden (view full) --- 82 ext_hdr = ext_data; 83 } 84 85 kfree(ext_data); 86 return ret; 87} 88EXPORT_SYMBOL(snd_sof_fw_parse_ext_data); 89 |
90/* 91 * IPC Firmware ready. 92 */ 93static void sof_get_windows(struct snd_sof_dev *sdev) 94{ 95 struct sof_ipc_window_elem *elem; 96 u32 outbox_offset = 0; 97 u32 stream_offset = 0; 98 u32 inbox_offset = 0; 99 u32 outbox_size = 0; 100 u32 stream_size = 0; 101 u32 inbox_size = 0; 102 int window_offset; 103 int bar; 104 int i; 105 106 if (!sdev->info_window) { 107 dev_err(sdev->dev, "error: have no window info\n"); 108 return; 109 } 110 111 bar = snd_sof_dsp_get_bar_index(sdev, SOF_FW_BLK_TYPE_SRAM); 112 if (bar < 0) { 113 dev_err(sdev->dev, "error: have no bar mapping\n"); 114 return; 115 } 116 117 for (i = 0; i < sdev->info_window->num_windows; i++) { 118 elem = &sdev->info_window->window[i]; 119 120 window_offset = snd_sof_dsp_get_window_offset(sdev, elem->id); 121 if (window_offset < 0) { 122 dev_warn(sdev->dev, "warn: no offset for window %d\n", 123 elem->id); 124 continue; 125 } 126 127 switch (elem->type) { 128 case SOF_IPC_REGION_UPBOX: 129 inbox_offset = window_offset + elem->offset; 130 inbox_size = elem->size; 131 snd_sof_debugfs_io_item(sdev, 132 sdev->bar[bar] + 133 inbox_offset, 134 elem->size, "inbox", 135 SOF_DEBUGFS_ACCESS_D0_ONLY); 136 break; 137 case SOF_IPC_REGION_DOWNBOX: 138 outbox_offset = window_offset + elem->offset; 139 outbox_size = elem->size; 140 snd_sof_debugfs_io_item(sdev, 141 sdev->bar[bar] + 142 outbox_offset, 143 elem->size, "outbox", 144 SOF_DEBUGFS_ACCESS_D0_ONLY); 145 break; 146 case SOF_IPC_REGION_TRACE: 147 snd_sof_debugfs_io_item(sdev, 148 sdev->bar[bar] + 149 window_offset + 150 elem->offset, 151 elem->size, "etrace", 152 SOF_DEBUGFS_ACCESS_D0_ONLY); 153 break; 154 case SOF_IPC_REGION_DEBUG: 155 snd_sof_debugfs_io_item(sdev, 156 sdev->bar[bar] + 157 window_offset + 158 elem->offset, 159 elem->size, "debug", 160 SOF_DEBUGFS_ACCESS_D0_ONLY); 161 break; 162 case SOF_IPC_REGION_STREAM: 163 stream_offset = window_offset + elem->offset; 164 stream_size = elem->size; 165 snd_sof_debugfs_io_item(sdev, 166 sdev->bar[bar] + 167 stream_offset, 168 elem->size, "stream", 169 SOF_DEBUGFS_ACCESS_D0_ONLY); 170 break; 171 case SOF_IPC_REGION_REGS: 172 snd_sof_debugfs_io_item(sdev, 173 sdev->bar[bar] + 174 window_offset + 175 elem->offset, 176 elem->size, "regs", 177 SOF_DEBUGFS_ACCESS_D0_ONLY); 178 break; 179 case SOF_IPC_REGION_EXCEPTION: 180 sdev->dsp_oops_offset = window_offset + elem->offset; 181 snd_sof_debugfs_io_item(sdev, 182 sdev->bar[bar] + 183 window_offset + 184 elem->offset, 185 elem->size, "exception", 186 SOF_DEBUGFS_ACCESS_D0_ONLY); 187 break; 188 default: 189 dev_err(sdev->dev, "error: get illegal window info\n"); 190 return; 191 } 192 } 193 194 if (outbox_size == 0 || inbox_size == 0) { 195 dev_err(sdev->dev, "error: get illegal mailbox window\n"); 196 return; 197 } 198 199 snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size, 200 outbox_offset, outbox_size); 201 sdev->stream_box.offset = stream_offset; 202 sdev->stream_box.size = stream_size; 203 204 dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n", 205 inbox_offset, inbox_size); 206 dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n", 207 outbox_offset, outbox_size); 208 dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n", 209 stream_offset, stream_size); 210} 211 212/* check for ABI compatibility and create memory windows on first boot */ 213int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) 214{ 215 struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready; 216 int offset; 217 int bar; 218 int ret; 219 220 /* mailbox must be on 4k boundary */ 221 offset = snd_sof_dsp_get_mailbox_offset(sdev); 222 if (offset < 0) { 223 dev_err(sdev->dev, "error: have no mailbox offset\n"); 224 return offset; 225 } 226 227 bar = snd_sof_dsp_get_bar_index(sdev, SOF_FW_BLK_TYPE_SRAM); 228 if (bar < 0) { 229 dev_err(sdev->dev, "error: have no bar mapping\n"); 230 return -EINVAL; 231 } 232 233 dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n", 234 msg_id, offset); 235 236 /* no need to re-check version/ABI for subsequent boots */ 237 if (!sdev->first_boot) 238 return 0; 239 240 /* copy data from the DSP FW ready offset */ 241 sof_block_read(sdev, bar, offset, fw_ready, sizeof(*fw_ready)); 242 243 /* make sure ABI version is compatible */ 244 ret = snd_sof_ipc_valid(sdev); 245 if (ret < 0) 246 return ret; 247 248 /* now check for extended data */ 249 snd_sof_fw_parse_ext_data(sdev, bar, offset + 250 sizeof(struct sof_ipc_fw_ready)); 251 252 sof_get_windows(sdev); 253 254 return 0; 255} 256EXPORT_SYMBOL(sof_fw_ready); 257 |
|
90/* generic module parser for mmaped DSPs */ 91int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, 92 struct snd_sof_mod_hdr *module) 93{ 94 struct snd_sof_blk_hdr *block; | 258/* generic module parser for mmaped DSPs */ 259int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, 260 struct snd_sof_mod_hdr *module) 261{ 262 struct snd_sof_blk_hdr *block; |
95 int count; | 263 int count, bar; |
96 u32 offset; 97 size_t remaining; 98 99 dev_dbg(sdev->dev, "new module size 0x%x blocks 0x%x type 0x%x\n", 100 module->size, module->num_blocks, module->type); 101 102 block = (struct snd_sof_blk_hdr *)((u8 *)module + sizeof(*module)); 103 --- 14 unchanged lines hidden (view full) --- 118 "warning: block %d size zero\n", count); 119 dev_warn(sdev->dev, " type 0x%x offset 0x%x\n", 120 block->type, block->offset); 121 continue; 122 } 123 124 switch (block->type) { 125 case SOF_FW_BLK_TYPE_RSRVD0: | 264 u32 offset; 265 size_t remaining; 266 267 dev_dbg(sdev->dev, "new module size 0x%x blocks 0x%x type 0x%x\n", 268 module->size, module->num_blocks, module->type); 269 270 block = (struct snd_sof_blk_hdr *)((u8 *)module + sizeof(*module)); 271 --- 14 unchanged lines hidden (view full) --- 286 "warning: block %d size zero\n", count); 287 dev_warn(sdev->dev, " type 0x%x offset 0x%x\n", 288 block->type, block->offset); 289 continue; 290 } 291 292 switch (block->type) { 293 case SOF_FW_BLK_TYPE_RSRVD0: |
126 case SOF_FW_BLK_TYPE_SRAM...SOF_FW_BLK_TYPE_RSRVD14: | 294 case SOF_FW_BLK_TYPE_ROM...SOF_FW_BLK_TYPE_RSRVD14: |
127 continue; /* not handled atm */ 128 case SOF_FW_BLK_TYPE_IRAM: 129 case SOF_FW_BLK_TYPE_DRAM: | 295 continue; /* not handled atm */ 296 case SOF_FW_BLK_TYPE_IRAM: 297 case SOF_FW_BLK_TYPE_DRAM: |
298 case SOF_FW_BLK_TYPE_SRAM: |
|
130 offset = block->offset; | 299 offset = block->offset; |
300 bar = snd_sof_dsp_get_bar_index(sdev, block->type); 301 if (bar < 0) { 302 dev_err(sdev->dev, 303 "error: no BAR mapping for block type 0x%x\n", 304 block->type); 305 return bar; 306 } |
|
131 break; 132 default: 133 dev_err(sdev->dev, "error: bad type 0x%x for block 0x%x\n", 134 block->type, count); 135 return -EINVAL; 136 } 137 138 dev_dbg(sdev->dev, 139 "block %d type 0x%x size 0x%x ==> offset 0x%x\n", 140 count, block->type, block->size, offset); 141 142 /* checking block->size to avoid unaligned access */ 143 if (block->size % sizeof(u32)) { 144 dev_err(sdev->dev, "error: invalid block size 0x%x\n", 145 block->size); 146 return -EINVAL; 147 } | 307 break; 308 default: 309 dev_err(sdev->dev, "error: bad type 0x%x for block 0x%x\n", 310 block->type, count); 311 return -EINVAL; 312 } 313 314 dev_dbg(sdev->dev, 315 "block %d type 0x%x size 0x%x ==> offset 0x%x\n", 316 count, block->type, block->size, offset); 317 318 /* checking block->size to avoid unaligned access */ 319 if (block->size % sizeof(u32)) { 320 dev_err(sdev->dev, "error: invalid block size 0x%x\n", 321 block->size); 322 return -EINVAL; 323 } |
148 snd_sof_dsp_block_write(sdev, sdev->mmio_bar, offset, | 324 snd_sof_dsp_block_write(sdev, bar, offset, |
149 block + 1, block->size); 150 151 if (remaining < block->size) { 152 dev_err(sdev->dev, "error: not enough data remaining\n"); 153 return -EINVAL; 154 } 155 156 /* minus body size of block */ --- 244 unchanged lines hidden --- | 325 block + 1, block->size); 326 327 if (remaining < block->size) { 328 dev_err(sdev->dev, "error: not enough data remaining\n"); 329 return -EINVAL; 330 } 331 332 /* minus body size of block */ --- 244 unchanged lines hidden --- |