IWL_DEBUG_FW(fwrt, "Paging: allocating mem for %d paging blocks, each block holds 8 pages, last block holds %d pages\n",
fwrt->num_of_paging_blk,
fwrt->num_of_pages_in_last_blk);
/* * Allocate CSS and paging blocks in dram.
*/ for (blk_idx = 0; blk_idx < fwrt->num_of_paging_blk + 1; blk_idx++) { /* For CSS allocate 4KB, for others PAGING_BLOCK_SIZE (32K) */
size = blk_idx ? PAGING_BLOCK_SIZE : FW_PAGING_SIZE;
order = get_order(size);
block = alloc_pages(GFP_KERNEL, order); if (!block) { /* free all the previous pages since we failed */
iwl_free_fw_paging(fwrt); return -ENOMEM;
}
phys = dma_map_page(fwrt->trans->dev, block, 0,
PAGE_SIZE << order,
DMA_BIDIRECTIONAL); if (dma_mapping_error(fwrt->trans->dev, phys)) { /* * free the previous pages and the current one * since we failed to map_page.
*/
iwl_free_fw_paging(fwrt); return -ENOMEM;
}
fwrt->fw_paging_db[blk_idx].fw_paging_phys = phys;
if (!blk_idx)
IWL_DEBUG_FW(fwrt, "Paging: allocated 4K(CSS) bytes (order %d) for firmware paging.\n",
order); else
IWL_DEBUG_FW(fwrt, "Paging: allocated 32K bytes (order %d) for firmware paging.\n",
order);
}
/* * find where is the paging image start point: * if CPU2 exist and it's in paging format, then the image looks like: * CPU1 sections (2 or more) * CPU1_CPU2_SEPARATOR_SECTION delimiter - separate between CPU1 to CPU2 * CPU2 sections (not paged) * PAGING_SEPARATOR_SECTION delimiter - separate between CPU2 * non paged to CPU2 paging sec * CPU2 paging CSS * CPU2 paging image (including instruction and data)
*/ for (sec_idx = 0; sec_idx < image->num_sec; sec_idx++) { if (image->sec[sec_idx].offset == PAGING_SEPARATOR_SECTION) {
sec_idx++; break;
}
}
/* * If paging is enabled there should be at least 2 more sections left * (one for CSS and one for Paging data)
*/ if (sec_idx >= image->num_sec - 1) {
IWL_ERR(fwrt, "Paging: Missing CSS and/or paging sections\n");
ret = -EINVAL; goto err;
}
/* copy the CSS block to the dram */
IWL_DEBUG_FW(fwrt, "Paging: load paging CSS to FW, sec = %d\n",
sec_idx);
if (image->sec[sec_idx].len > fwrt->fw_paging_db[0].fw_paging_size) {
IWL_ERR(fwrt, "CSS block is larger than paging size\n");
ret = -EINVAL; goto err;
}
IWL_DEBUG_FW(fwrt, "Paging: copied %d CSS bytes to first block\n",
fwrt->fw_paging_db[0].fw_paging_size);
sec_idx++;
/* * Copy the paging blocks to the dram. The loop index starts * from 1 since the CSS block (index 0) was already copied to * dram. We use num_of_paging_blk + 1 to account for that.
*/ for (idx = 1; idx < fwrt->num_of_paging_blk + 1; idx++) { struct iwl_fw_paging *block = &fwrt->fw_paging_db[idx]; int remaining = image->sec[sec_idx].len - offset; int len = block->fw_paging_size;
/* * For the last block, we copy all that is remaining, * for all other blocks, we copy fw_paging_size at a
* time. */ if (idx == fwrt->num_of_paging_blk) {
len = remaining; if (remaining !=
fwrt->num_of_pages_in_last_blk * FW_PAGING_SIZE) {
IWL_ERR(fwrt, "Paging: last block contains more data than expected %d\n",
remaining);
ret = -EINVAL; goto err;
}
} elseif (block->fw_paging_size > remaining) {
IWL_ERR(fwrt, "Paging: not enough data in other in block %d (%d)\n",
idx, remaining);
ret = -EINVAL; goto err;
}
int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type)
{ conststruct fw_img *fw = &fwrt->fw->img[type]; int ret;
if (fwrt->trans->mac_cfg->gen2) return 0;
/* * Configure and operate fw paging mechanism. * The driver configures the paging flow only once. * The CPU2 paging image is included in the IWL_UCODE_INIT image.
*/ if (!fw->paging_mem_size) return 0;
ret = iwl_save_fw_paging(fwrt, fw); if (ret) {
IWL_ERR(fwrt, "failed to save the FW paging image\n"); return ret;
}
ret = iwl_send_paging_cmd(fwrt, fw); if (ret) {
IWL_ERR(fwrt, "failed to send the paging cmd\n");
iwl_free_fw_paging(fwrt); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.