1/* 2 This file is provided under a dual BSD/GPLv2 license. When using or 3 redistributing this file, you may do so under either license. 4 5 GPL LICENSE SUMMARY 6 Copyright(c) 2014 Intel Corporation. 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of version 2 of the GNU General Public License as 9 published by the Free Software Foundation. 10 11 This program is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 Contact Information: 17 qat-linux@intel.com 18 19 BSD LICENSE 20 Copyright(c) 2014 Intel Corporation. 21 Redistribution and use in source and binary forms, with or without 22 modification, are permitted provided that the following conditions 23 are met: 24 25 * Redistributions of source code must retain the above copyright 26 notice, this list of conditions and the following disclaimer. 27 * Redistributions in binary form must reproduce the above copyright 28 notice, this list of conditions and the following disclaimer in 29 the documentation and/or other materials provided with the 30 distribution. 31 * Neither the name of Intel Corporation nor the names of its 32 contributors may be used to endorse or promote products derived 33 from this software without specific prior written permission. 34 35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46*/ 47#include <linux/slab.h> 48#include <linux/ctype.h> 49#include <linux/kernel.h> 50 51#include "adf_accel_devices.h" 52#include "adf_common_drv.h" 53#include "icp_qat_uclo.h" 54#include "icp_qat_hal.h" 55#include "icp_qat_fw_loader_handle.h" 56 57#define UWORD_CPYBUF_SIZE 1024 58#define INVLD_UWORD 0xffffffffffull 59#define PID_MINOR_REV 0xf 60#define PID_MAJOR_REV (0xf << 4) 61 62static int qat_uclo_init_ae_data(struct icp_qat_uclo_objhandle *obj_handle, 63 unsigned int ae, unsigned int image_num) 64{ 65 struct icp_qat_uclo_aedata *ae_data; 66 struct icp_qat_uclo_encapme *encap_image; 67 struct icp_qat_uclo_page *page = NULL; 68 struct icp_qat_uclo_aeslice *ae_slice = NULL; 69 70 ae_data = &obj_handle->ae_data[ae]; 71 encap_image = &obj_handle->ae_uimage[image_num]; 72 ae_slice = &ae_data->ae_slices[ae_data->slice_num]; 73 ae_slice->encap_image = encap_image; 74 75 if (encap_image->img_ptr) { 76 ae_slice->ctx_mask_assigned = 77 encap_image->img_ptr->ctx_assigned; 78 ae_data->eff_ustore_size = obj_handle->ustore_phy_size; 79 } else { 80 ae_slice->ctx_mask_assigned = 0; 81 } 82 ae_slice->region = kzalloc(sizeof(*ae_slice->region), GFP_KERNEL); 83 if (!ae_slice->region) 84 return -ENOMEM; 85 ae_slice->page = kzalloc(sizeof(*ae_slice->page), GFP_KERNEL); 86 if (!ae_slice->page) 87 goto out_err; 88 page = ae_slice->page; 89 page->encap_page = encap_image->page; 90 ae_slice->page->region = ae_slice->region; 91 ae_data->slice_num++; 92 return 0; 93out_err: 94 kfree(ae_slice->region); 95 ae_slice->region = NULL; 96 return -ENOMEM; 97} 98 99static int qat_uclo_free_ae_data(struct icp_qat_uclo_aedata *ae_data) 100{ 101 unsigned int i; 102 103 if (!ae_data) { 104 pr_err("QAT: bad argument, ae_data is NULL\n "); 105 return -EINVAL; 106 } 107 108 for (i = 0; i < ae_data->slice_num; i++) { 109 kfree(ae_data->ae_slices[i].region); 110 ae_data->ae_slices[i].region = NULL; 111 kfree(ae_data->ae_slices[i].page); 112 ae_data->ae_slices[i].page = NULL; 113 } 114 return 0; 115} 116 117static char *qat_uclo_get_string(struct icp_qat_uof_strtable *str_table, 118 unsigned int str_offset) 119{ 120 if ((!str_table->table_len) || (str_offset > str_table->table_len)) 121 return NULL; 122 return (char *)(((unsigned long)(str_table->strings)) + str_offset); 123} 124 125static int qat_uclo_check_format(struct icp_qat_uof_filehdr *hdr) 126{ 127 int maj = hdr->maj_ver & 0xff; 128 int min = hdr->min_ver & 0xff; 129 130 if (hdr->file_id != ICP_QAT_UOF_FID) { 131 pr_err("QAT: Invalid header 0x%x\n", hdr->file_id); 132 return -EINVAL; 133 } 134 if (min != ICP_QAT_UOF_MINVER || maj != ICP_QAT_UOF_MAJVER) { 135 pr_err("QAT: bad UOF version, major 0x%x, minor 0x%x\n", 136 maj, min); 137 return -EINVAL; 138 } 139 return 0; 140} 141 142static void qat_uclo_wr_sram_by_words(struct icp_qat_fw_loader_handle *handle, 143 unsigned int addr, unsigned int *val, 144 unsigned int num_in_bytes) 145{ 146 unsigned int outval; 147 unsigned char *ptr = (unsigned char *)val; 148 149 while (num_in_bytes) { 150 memcpy(&outval, ptr, 4); 151 SRAM_WRITE(handle, addr, outval); 152 num_in_bytes -= 4; 153 ptr += 4; 154 addr += 4; 155 } 156} 157 158static void qat_uclo_wr_umem_by_words(struct icp_qat_fw_loader_handle *handle, 159 unsigned char ae, unsigned int addr, 160 unsigned int *val, 161 unsigned int num_in_bytes) 162{ 163 unsigned int outval; 164 unsigned char *ptr = (unsigned char *)val; 165 166 addr >>= 0x2; /* convert to uword address */ 167 168 while (num_in_bytes) { 169 memcpy(&outval, ptr, 4); 170 qat_hal_wr_umem(handle, ae, addr++, 1, &outval); 171 num_in_bytes -= 4; 172 ptr += 4; 173 } 174} 175 176static void qat_uclo_batch_wr_umem(struct icp_qat_fw_loader_handle *handle, 177 unsigned char ae, 178 struct icp_qat_uof_batch_init 179 *umem_init_header) 180{ 181 struct icp_qat_uof_batch_init *umem_init; 182 183 if (!umem_init_header) 184 return; 185 umem_init = umem_init_header->next; 186 while (umem_init) { 187 unsigned int addr, *value, size; 188 189 ae = umem_init->ae; 190 addr = umem_init->addr; 191 value = umem_init->value; 192 size = umem_init->size; 193 qat_uclo_wr_umem_by_words(handle, ae, addr, value, size); 194 umem_init = umem_init->next; 195 } 196} 197 198static void 199qat_uclo_cleanup_batch_init_list(struct icp_qat_fw_loader_handle *handle, 200 struct icp_qat_uof_batch_init **base) 201{ 202 struct icp_qat_uof_batch_init *umem_init; 203 204 umem_init = *base; 205 while (umem_init) { 206 struct icp_qat_uof_batch_init *pre; 207 208 pre = umem_init; 209 umem_init = umem_init->next; 210 kfree(pre); 211 } 212 *base = NULL; 213} 214 215static int qat_uclo_parse_num(char *str, unsigned int *num) 216{ 217 char buf[16] = {0}; 218 unsigned long ae = 0; 219 int i; 220 221 strncpy(buf, str, 15); 222 for (i = 0; i < 16; i++) { 223 if (!isdigit(buf[i])) { 224 buf[i] = '\0'; 225 break; 226 } 227 } 228 if ((kstrtoul(buf, 10, &ae))) 229 return -EFAULT; 230 231 *num = (unsigned int)ae; 232 return 0; 233} 234 235static int qat_uclo_fetch_initmem_ae(struct icp_qat_fw_loader_handle *handle, 236 struct icp_qat_uof_initmem *init_mem, 237 unsigned int size_range, unsigned int *ae) 238{ 239 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 240 char *str; 241 242 if ((init_mem->addr + init_mem->num_in_bytes) > (size_range << 0x2)) { 243 pr_err("QAT: initmem is out of range"); 244 return -EINVAL; 245 } 246 if (init_mem->scope != ICP_QAT_UOF_LOCAL_SCOPE) { 247 pr_err("QAT: Memory scope for init_mem error\n"); 248 return -EINVAL; 249 } 250 str = qat_uclo_get_string(&obj_handle->str_table, init_mem->sym_name); 251 if (!str) { 252 pr_err("QAT: AE name assigned in UOF init table is NULL\n"); 253 return -EINVAL; 254 } 255 if (qat_uclo_parse_num(str, ae)) { 256 pr_err("QAT: Parse num for AE number failed\n"); 257 return -EINVAL; 258 } 259 if (*ae >= ICP_QAT_UCLO_MAX_AE) { 260 pr_err("QAT: ae %d out of range\n", *ae); 261 return -EINVAL; 262 } 263 return 0; 264} 265 266static int qat_uclo_create_batch_init_list(struct icp_qat_fw_loader_handle 267 *handle, struct icp_qat_uof_initmem 268 *init_mem, unsigned int ae, 269 struct icp_qat_uof_batch_init 270 **init_tab_base) 271{ 272 struct icp_qat_uof_batch_init *init_header, *tail; 273 struct icp_qat_uof_batch_init *mem_init, *tail_old; 274 struct icp_qat_uof_memvar_attr *mem_val_attr; 275 unsigned int i, flag = 0; 276 277 mem_val_attr = 278 (struct icp_qat_uof_memvar_attr *)((unsigned long)init_mem + 279 sizeof(struct icp_qat_uof_initmem)); 280 281 init_header = *init_tab_base; 282 if (!init_header) { 283 init_header = kzalloc(sizeof(*init_header), GFP_KERNEL); 284 if (!init_header) 285 return -ENOMEM; 286 init_header->size = 1; 287 *init_tab_base = init_header; 288 flag = 1; 289 } 290 tail_old = init_header; 291 while (tail_old->next) 292 tail_old = tail_old->next; 293 tail = tail_old; 294 for (i = 0; i < init_mem->val_attr_num; i++) { 295 mem_init = kzalloc(sizeof(*mem_init), GFP_KERNEL); 296 if (!mem_init) 297 goto out_err; 298 mem_init->ae = ae; 299 mem_init->addr = init_mem->addr + mem_val_attr->offset_in_byte; 300 mem_init->value = &mem_val_attr->value; 301 mem_init->size = 4; 302 mem_init->next = NULL; 303 tail->next = mem_init; 304 tail = mem_init; 305 init_header->size += qat_hal_get_ins_num(); 306 mem_val_attr++; 307 } 308 return 0; 309out_err: 310 while (tail_old) { 311 mem_init = tail_old->next; 312 kfree(tail_old); 313 tail_old = mem_init; 314 } 315 if (flag) 316 kfree(*init_tab_base); 317 return -ENOMEM; 318} 319 320static int qat_uclo_init_lmem_seg(struct icp_qat_fw_loader_handle *handle, 321 struct icp_qat_uof_initmem *init_mem) 322{ 323 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 324 unsigned int ae; 325 326 if (qat_uclo_fetch_initmem_ae(handle, init_mem, 327 ICP_QAT_UCLO_MAX_LMEM_REG, &ae)) 328 return -EINVAL; 329 if (qat_uclo_create_batch_init_list(handle, init_mem, ae, 330 &obj_handle->lm_init_tab[ae])) 331 return -EINVAL; 332 return 0; 333} 334 335static int qat_uclo_init_umem_seg(struct icp_qat_fw_loader_handle *handle, 336 struct icp_qat_uof_initmem *init_mem) 337{ 338 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 339 unsigned int ae, ustore_size, uaddr, i; 340 341 ustore_size = obj_handle->ustore_phy_size; 342 if (qat_uclo_fetch_initmem_ae(handle, init_mem, ustore_size, &ae)) 343 return -EINVAL; 344 if (qat_uclo_create_batch_init_list(handle, init_mem, ae, 345 &obj_handle->umem_init_tab[ae])) 346 return -EINVAL; 347 /* set the highest ustore address referenced */ 348 uaddr = (init_mem->addr + init_mem->num_in_bytes) >> 0x2; 349 for (i = 0; i < obj_handle->ae_data[ae].slice_num; i++) { 350 if (obj_handle->ae_data[ae].ae_slices[i]. 351 encap_image->uwords_num < uaddr) 352 obj_handle->ae_data[ae].ae_slices[i]. 353 encap_image->uwords_num = uaddr; 354 } 355 return 0; 356} 357 358#define ICP_DH895XCC_PESRAM_BAR_SIZE 0x80000 359static int qat_uclo_init_ae_memory(struct icp_qat_fw_loader_handle *handle, 360 struct icp_qat_uof_initmem *init_mem) 361{ 362 unsigned int i; 363 struct icp_qat_uof_memvar_attr *mem_val_attr; 364 365 mem_val_attr = 366 (struct icp_qat_uof_memvar_attr *)((unsigned long)init_mem + 367 sizeof(struct icp_qat_uof_initmem)); 368 369 switch (init_mem->region) { 370 case ICP_QAT_UOF_SRAM_REGION: 371 if ((init_mem->addr + init_mem->num_in_bytes) > 372 ICP_DH895XCC_PESRAM_BAR_SIZE) { 373 pr_err("QAT: initmem on SRAM is out of range"); 374 return -EINVAL; 375 } 376 for (i = 0; i < init_mem->val_attr_num; i++) { 377 qat_uclo_wr_sram_by_words(handle, 378 init_mem->addr + 379 mem_val_attr->offset_in_byte, 380 &mem_val_attr->value, 4); 381 mem_val_attr++; 382 } 383 break; 384 case ICP_QAT_UOF_LMEM_REGION: 385 if (qat_uclo_init_lmem_seg(handle, init_mem)) 386 return -EINVAL; 387 break; 388 case ICP_QAT_UOF_UMEM_REGION: 389 if (qat_uclo_init_umem_seg(handle, init_mem)) 390 return -EINVAL; 391 break; 392 default: 393 pr_err("QAT: initmem region error. region type=0x%x\n", 394 init_mem->region); 395 return -EINVAL; 396 } 397 return 0; 398} 399 400static int qat_uclo_init_ustore(struct icp_qat_fw_loader_handle *handle, 401 struct icp_qat_uclo_encapme *image) 402{ 403 unsigned int i; 404 struct icp_qat_uclo_encap_page *page; 405 struct icp_qat_uof_image *uof_image; 406 unsigned char ae; 407 unsigned int ustore_size; 408 unsigned int patt_pos; 409 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 410 uint64_t *fill_data; 411 412 uof_image = image->img_ptr; 413 fill_data = kcalloc(ICP_QAT_UCLO_MAX_USTORE, sizeof(uint64_t), 414 GFP_KERNEL); 415 if (!fill_data) 416 return -ENOMEM; 417 for (i = 0; i < ICP_QAT_UCLO_MAX_USTORE; i++) 418 memcpy(&fill_data[i], &uof_image->fill_pattern, 419 sizeof(uint64_t)); 420 page = image->page; 421 422 for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) { 423 if (!test_bit(ae, (unsigned long *)&uof_image->ae_assigned)) 424 continue; 425 ustore_size = obj_handle->ae_data[ae].eff_ustore_size; 426 patt_pos = page->beg_addr_p + page->micro_words_num; 427 428 qat_hal_wr_uwords(handle, (unsigned char)ae, 0, 429 page->beg_addr_p, &fill_data[0]); 430 qat_hal_wr_uwords(handle, (unsigned char)ae, patt_pos, 431 ustore_size - patt_pos + 1, 432 &fill_data[page->beg_addr_p]); 433 } 434 kfree(fill_data); 435 return 0; 436} 437 438static int qat_uclo_init_memory(struct icp_qat_fw_loader_handle *handle) 439{ 440 int i, ae; 441 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 442 struct icp_qat_uof_initmem *initmem = obj_handle->init_mem_tab.init_mem; 443 444 for (i = 0; i < obj_handle->init_mem_tab.entry_num; i++) { 445 if (initmem->num_in_bytes) { 446 if (qat_uclo_init_ae_memory(handle, initmem)) 447 return -EINVAL; 448 } 449 initmem = (struct icp_qat_uof_initmem *)((unsigned long)( 450 (unsigned long)initmem + 451 sizeof(struct icp_qat_uof_initmem)) + 452 (sizeof(struct icp_qat_uof_memvar_attr) * 453 initmem->val_attr_num)); 454 } 455 for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) { 456 if (qat_hal_batch_wr_lm(handle, ae, 457 obj_handle->lm_init_tab[ae])) { 458 pr_err("QAT: fail to batch init lmem for AE %d\n", ae); 459 return -EINVAL; 460 } 461 qat_uclo_cleanup_batch_init_list(handle, 462 &obj_handle->lm_init_tab[ae]); 463 qat_uclo_batch_wr_umem(handle, ae, 464 obj_handle->umem_init_tab[ae]); 465 qat_uclo_cleanup_batch_init_list(handle, 466 &obj_handle-> 467 umem_init_tab[ae]); 468 } 469 return 0; 470} 471 472static void *qat_uclo_find_chunk(struct icp_qat_uof_objhdr *obj_hdr, 473 char *chunk_id, void *cur) 474{ 475 int i; 476 struct icp_qat_uof_chunkhdr *chunk_hdr = 477 (struct icp_qat_uof_chunkhdr *) 478 ((unsigned long)obj_hdr + sizeof(struct icp_qat_uof_objhdr)); 479 480 for (i = 0; i < obj_hdr->num_chunks; i++) { 481 if ((cur < (void *)&chunk_hdr[i]) && 482 !strncmp(chunk_hdr[i].chunk_id, chunk_id, 483 ICP_QAT_UOF_OBJID_LEN)) { 484 return &chunk_hdr[i]; 485 } 486 } 487 return NULL; 488} 489 490static unsigned int qat_uclo_calc_checksum(unsigned int reg, int ch) 491{ 492 int i; 493 unsigned int topbit = 1 << 0xF; 494 unsigned int inbyte = (unsigned int)((reg >> 0x18) ^ ch); 495 496 reg ^= inbyte << 0x8; 497 for (i = 0; i < 0x8; i++) { 498 if (reg & topbit) 499 reg = (reg << 1) ^ 0x1021; 500 else 501 reg <<= 1; 502 } 503 return reg & 0xFFFF; 504} 505 506static unsigned int qat_uclo_calc_str_checksum(char *ptr, int num) 507{ 508 unsigned int chksum = 0; 509 510 if (ptr) 511 while (num--) 512 chksum = qat_uclo_calc_checksum(chksum, *ptr++); 513 return chksum; 514} 515 516static struct icp_qat_uclo_objhdr * 517qat_uclo_map_chunk(char *buf, struct icp_qat_uof_filehdr *file_hdr, 518 char *chunk_id) 519{ 520 struct icp_qat_uof_filechunkhdr *file_chunk; 521 struct icp_qat_uclo_objhdr *obj_hdr; 522 char *chunk; 523 int i; 524 525 file_chunk = (struct icp_qat_uof_filechunkhdr *) 526 (buf + sizeof(struct icp_qat_uof_filehdr)); 527 for (i = 0; i < file_hdr->num_chunks; i++) { 528 if (!strncmp(file_chunk->chunk_id, chunk_id, 529 ICP_QAT_UOF_OBJID_LEN)) { 530 chunk = buf + file_chunk->offset; 531 if (file_chunk->checksum != qat_uclo_calc_str_checksum( 532 chunk, file_chunk->size)) 533 break; 534 obj_hdr = kzalloc(sizeof(*obj_hdr), GFP_KERNEL); 535 if (!obj_hdr) 536 break; 537 obj_hdr->file_buff = chunk; 538 obj_hdr->checksum = file_chunk->checksum; 539 obj_hdr->size = file_chunk->size; 540 return obj_hdr; 541 } 542 file_chunk++; 543 } 544 return NULL; 545} 546 547static unsigned int 548qat_uclo_check_image_compat(struct icp_qat_uof_encap_obj *encap_uof_obj, 549 struct icp_qat_uof_image *image) 550{ 551 struct icp_qat_uof_objtable *uc_var_tab, *imp_var_tab, *imp_expr_tab; 552 struct icp_qat_uof_objtable *neigh_reg_tab; 553 struct icp_qat_uof_code_page *code_page; 554 555 code_page = (struct icp_qat_uof_code_page *) 556 ((char *)image + sizeof(struct icp_qat_uof_image)); 557 uc_var_tab = (struct icp_qat_uof_objtable *)(encap_uof_obj->beg_uof + 558 code_page->uc_var_tab_offset); 559 imp_var_tab = (struct icp_qat_uof_objtable *)(encap_uof_obj->beg_uof + 560 code_page->imp_var_tab_offset); 561 imp_expr_tab = (struct icp_qat_uof_objtable *) 562 (encap_uof_obj->beg_uof + 563 code_page->imp_expr_tab_offset); 564 if (uc_var_tab->entry_num || imp_var_tab->entry_num || 565 imp_expr_tab->entry_num) { 566 pr_err("QAT: UOF can't contain imported variable to be parsed"); 567 return -EINVAL; 568 } 569 neigh_reg_tab = (struct icp_qat_uof_objtable *) 570 (encap_uof_obj->beg_uof + 571 code_page->neigh_reg_tab_offset); 572 if (neigh_reg_tab->entry_num) { 573 pr_err("QAT: UOF can't contain shared control store feature"); 574 return -EINVAL; 575 } 576 if (image->numpages > 1) { 577 pr_err("QAT: UOF can't contain multiple pages"); 578 return -EINVAL; 579 } 580 if (ICP_QAT_SHARED_USTORE_MODE(image->ae_mode)) { 581 pr_err("QAT: UOF can't use shared control store feature"); 582 return -EFAULT; 583 } 584 if (RELOADABLE_CTX_SHARED_MODE(image->ae_mode)) { 585 pr_err("QAT: UOF can't use reloadable feature"); 586 return -EFAULT; 587 } 588 return 0; 589} 590 591static void qat_uclo_map_image_page(struct icp_qat_uof_encap_obj 592 *encap_uof_obj, 593 struct icp_qat_uof_image *img, 594 struct icp_qat_uclo_encap_page *page) 595{ 596 struct icp_qat_uof_code_page *code_page; 597 struct icp_qat_uof_code_area *code_area; 598 struct icp_qat_uof_objtable *uword_block_tab; 599 struct icp_qat_uof_uword_block *uwblock; 600 int i; 601 602 code_page = (struct icp_qat_uof_code_page *) 603 ((char *)img + sizeof(struct icp_qat_uof_image)); 604 page->def_page = code_page->def_page; 605 page->page_region = code_page->page_region; 606 page->beg_addr_v = code_page->beg_addr_v; 607 page->beg_addr_p = code_page->beg_addr_p; 608 code_area = (struct icp_qat_uof_code_area *)(encap_uof_obj->beg_uof + 609 code_page->code_area_offset); 610 page->micro_words_num = code_area->micro_words_num; 611 uword_block_tab = (struct icp_qat_uof_objtable *) 612 (encap_uof_obj->beg_uof + 613 code_area->uword_block_tab); 614 page->uwblock_num = uword_block_tab->entry_num; 615 uwblock = (struct icp_qat_uof_uword_block *)((char *)uword_block_tab + 616 sizeof(struct icp_qat_uof_objtable)); 617 page->uwblock = (struct icp_qat_uclo_encap_uwblock *)uwblock; 618 for (i = 0; i < uword_block_tab->entry_num; i++) 619 page->uwblock[i].micro_words = 620 (unsigned long)encap_uof_obj->beg_uof + uwblock[i].uword_offset; 621} 622 623static int qat_uclo_map_uimage(struct icp_qat_uclo_objhandle *obj_handle, 624 struct icp_qat_uclo_encapme *ae_uimage, 625 int max_image) 626{ 627 int i, j; 628 struct icp_qat_uof_chunkhdr *chunk_hdr = NULL; 629 struct icp_qat_uof_image *image; 630 struct icp_qat_uof_objtable *ae_regtab; 631 struct icp_qat_uof_objtable *init_reg_sym_tab; 632 struct icp_qat_uof_objtable *sbreak_tab; 633 struct icp_qat_uof_encap_obj *encap_uof_obj = 634 &obj_handle->encap_uof_obj; 635 636 for (j = 0; j < max_image; j++) { 637 chunk_hdr = qat_uclo_find_chunk(encap_uof_obj->obj_hdr, 638 ICP_QAT_UOF_IMAG, chunk_hdr); 639 if (!chunk_hdr) 640 break; 641 image = (struct icp_qat_uof_image *)(encap_uof_obj->beg_uof + 642 chunk_hdr->offset); 643 ae_regtab = (struct icp_qat_uof_objtable *) 644 (image->reg_tab_offset + 645 obj_handle->obj_hdr->file_buff); 646 ae_uimage[j].ae_reg_num = ae_regtab->entry_num; 647 ae_uimage[j].ae_reg = (struct icp_qat_uof_ae_reg *) 648 (((char *)ae_regtab) + 649 sizeof(struct icp_qat_uof_objtable)); 650 init_reg_sym_tab = (struct icp_qat_uof_objtable *) 651 (image->init_reg_sym_tab + 652 obj_handle->obj_hdr->file_buff); 653 ae_uimage[j].init_regsym_num = init_reg_sym_tab->entry_num; 654 ae_uimage[j].init_regsym = (struct icp_qat_uof_init_regsym *) 655 (((char *)init_reg_sym_tab) + 656 sizeof(struct icp_qat_uof_objtable)); 657 sbreak_tab = (struct icp_qat_uof_objtable *) 658 (image->sbreak_tab + obj_handle->obj_hdr->file_buff); 659 ae_uimage[j].sbreak_num = sbreak_tab->entry_num; 660 ae_uimage[j].sbreak = (struct icp_qat_uof_sbreak *) 661 (((char *)sbreak_tab) + 662 sizeof(struct icp_qat_uof_objtable)); 663 ae_uimage[j].img_ptr = image; 664 if (qat_uclo_check_image_compat(encap_uof_obj, image)) 665 goto out_err; 666 ae_uimage[j].page = 667 kzalloc(sizeof(struct icp_qat_uclo_encap_page), 668 GFP_KERNEL); 669 if (!ae_uimage[j].page) 670 goto out_err; 671 qat_uclo_map_image_page(encap_uof_obj, image, 672 ae_uimage[j].page); 673 } 674 return j; 675out_err: 676 for (i = 0; i < j; i++) 677 kfree(ae_uimage[i].page); 678 return 0; 679} 680 681static int qat_uclo_map_ae(struct icp_qat_fw_loader_handle *handle, int max_ae) 682{ 683 int i, ae; 684 int mflag = 0; 685 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 686 687 for (ae = 0; ae <= max_ae; ae++) { 688 if (!test_bit(ae, 689 (unsigned long *)&handle->hal_handle->ae_mask)) 690 continue; 691 for (i = 0; i < obj_handle->uimage_num; i++) { 692 if (!test_bit(ae, (unsigned long *) 693 &obj_handle->ae_uimage[i].img_ptr->ae_assigned)) 694 continue; 695 mflag = 1; 696 if (qat_uclo_init_ae_data(obj_handle, ae, i)) 697 return -EINVAL; 698 } 699 } 700 if (!mflag) { 701 pr_err("QAT: uimage uses AE not set"); 702 return -EINVAL; 703 } 704 return 0; 705} 706 707static struct icp_qat_uof_strtable * 708qat_uclo_map_str_table(struct icp_qat_uclo_objhdr *obj_hdr, 709 char *tab_name, struct icp_qat_uof_strtable *str_table) 710{ 711 struct icp_qat_uof_chunkhdr *chunk_hdr; 712 713 chunk_hdr = qat_uclo_find_chunk((struct icp_qat_uof_objhdr *) 714 obj_hdr->file_buff, tab_name, NULL); 715 if (chunk_hdr) { 716 int hdr_size; 717 718 memcpy(&str_table->table_len, obj_hdr->file_buff + 719 chunk_hdr->offset, sizeof(str_table->table_len)); 720 hdr_size = (char *)&str_table->strings - (char *)str_table; 721 str_table->strings = (unsigned long)obj_hdr->file_buff + 722 chunk_hdr->offset + hdr_size; 723 return str_table; 724 } 725 return NULL; 726} 727 728static void 729qat_uclo_map_initmem_table(struct icp_qat_uof_encap_obj *encap_uof_obj, 730 struct icp_qat_uclo_init_mem_table *init_mem_tab) 731{ 732 struct icp_qat_uof_chunkhdr *chunk_hdr; 733 734 chunk_hdr = qat_uclo_find_chunk(encap_uof_obj->obj_hdr, 735 ICP_QAT_UOF_IMEM, NULL); 736 if (chunk_hdr) { 737 memmove(&init_mem_tab->entry_num, encap_uof_obj->beg_uof + 738 chunk_hdr->offset, sizeof(unsigned int)); 739 init_mem_tab->init_mem = (struct icp_qat_uof_initmem *) 740 (encap_uof_obj->beg_uof + chunk_hdr->offset + 741 sizeof(unsigned int)); 742 } 743} 744 745static int qat_uclo_check_uof_compat(struct icp_qat_uclo_objhandle *obj_handle) 746{ 747 unsigned int maj_ver, prod_type = obj_handle->prod_type; 748 749 if (!(prod_type & obj_handle->encap_uof_obj.obj_hdr->cpu_type)) { 750 pr_err("QAT: UOF type 0x%x not match with cur platform 0x%x\n", 751 obj_handle->encap_uof_obj.obj_hdr->cpu_type, prod_type); 752 return -EINVAL; 753 } 754 maj_ver = obj_handle->prod_rev & 0xff; 755 if ((obj_handle->encap_uof_obj.obj_hdr->max_cpu_ver < maj_ver) || 756 (obj_handle->encap_uof_obj.obj_hdr->min_cpu_ver > maj_ver)) { 757 pr_err("QAT: UOF majVer 0x%x out of range\n", maj_ver); 758 return -EINVAL; 759 } 760 return 0; 761} 762 763static int qat_uclo_init_reg(struct icp_qat_fw_loader_handle *handle, 764 unsigned char ae, unsigned char ctx_mask, 765 enum icp_qat_uof_regtype reg_type, 766 unsigned short reg_addr, unsigned int value) 767{ 768 switch (reg_type) { 769 case ICP_GPA_ABS: 770 case ICP_GPB_ABS: 771 ctx_mask = 0; 772 case ICP_GPA_REL: 773 case ICP_GPB_REL: 774 return qat_hal_init_gpr(handle, ae, ctx_mask, reg_type, 775 reg_addr, value); 776 case ICP_SR_ABS: 777 case ICP_DR_ABS: 778 case ICP_SR_RD_ABS: 779 case ICP_DR_RD_ABS: 780 ctx_mask = 0; 781 case ICP_SR_REL: 782 case ICP_DR_REL: 783 case ICP_SR_RD_REL: 784 case ICP_DR_RD_REL: 785 return qat_hal_init_rd_xfer(handle, ae, ctx_mask, reg_type, 786 reg_addr, value); 787 case ICP_SR_WR_ABS: 788 case ICP_DR_WR_ABS: 789 ctx_mask = 0; 790 case ICP_SR_WR_REL: 791 case ICP_DR_WR_REL: 792 return qat_hal_init_wr_xfer(handle, ae, ctx_mask, reg_type, 793 reg_addr, value); 794 case ICP_NEIGH_REL: 795 return qat_hal_init_nn(handle, ae, ctx_mask, reg_addr, value); 796 default: 797 pr_err("QAT: UOF uses not supported reg type 0x%x\n", reg_type); 798 return -EFAULT; 799 } 800 return 0; 801} 802 803static int qat_uclo_init_reg_sym(struct icp_qat_fw_loader_handle *handle, 804 unsigned int ae, 805 struct icp_qat_uclo_encapme *encap_ae) 806{ 807 unsigned int i; 808 unsigned char ctx_mask; 809 struct icp_qat_uof_init_regsym *init_regsym; 810 811 if (ICP_QAT_CTX_MODE(encap_ae->img_ptr->ae_mode) == 812 ICP_QAT_UCLO_MAX_CTX) 813 ctx_mask = 0xff; 814 else 815 ctx_mask = 0x55; 816 817 for (i = 0; i < encap_ae->init_regsym_num; i++) { 818 unsigned int exp_res; 819 820 init_regsym = &encap_ae->init_regsym[i]; 821 exp_res = init_regsym->value; 822 switch (init_regsym->init_type) { 823 case ICP_QAT_UOF_INIT_REG: 824 qat_uclo_init_reg(handle, ae, ctx_mask, 825 (enum icp_qat_uof_regtype) 826 init_regsym->reg_type, 827 (unsigned short)init_regsym->reg_addr, 828 exp_res); 829 break; 830 case ICP_QAT_UOF_INIT_REG_CTX: 831 /* check if ctx is appropriate for the ctxMode */ 832 if (!((1 << init_regsym->ctx) & ctx_mask)) { 833 pr_err("QAT: invalid ctx num = 0x%x\n", 834 init_regsym->ctx); 835 return -EINVAL; 836 } 837 qat_uclo_init_reg(handle, ae, 838 (unsigned char) 839 (1 << init_regsym->ctx), 840 (enum icp_qat_uof_regtype) 841 init_regsym->reg_type, 842 (unsigned short)init_regsym->reg_addr, 843 exp_res); 844 break; 845 case ICP_QAT_UOF_INIT_EXPR: 846 pr_err("QAT: INIT_EXPR feature not supported\n"); 847 return -EINVAL; 848 case ICP_QAT_UOF_INIT_EXPR_ENDIAN_SWAP: 849 pr_err("QAT: INIT_EXPR_ENDIAN_SWAP feature not supported\n"); 850 return -EINVAL; 851 default: 852 break; 853 } 854 } 855 return 0; 856} 857 858static int qat_uclo_init_globals(struct icp_qat_fw_loader_handle *handle) 859{ 860 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 861 unsigned int s, ae; 862 863 if (obj_handle->global_inited) 864 return 0; 865 if (obj_handle->init_mem_tab.entry_num) { 866 if (qat_uclo_init_memory(handle)) { 867 pr_err("QAT: initialize memory failed\n"); 868 return -EINVAL; 869 } 870 } 871 for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) { 872 for (s = 0; s < obj_handle->ae_data[ae].slice_num; s++) { 873 if (!obj_handle->ae_data[ae].ae_slices[s].encap_image) 874 continue; 875 if (qat_uclo_init_reg_sym(handle, ae, 876 obj_handle->ae_data[ae]. 877 ae_slices[s].encap_image)) 878 return -EINVAL; 879 } 880 } 881 obj_handle->global_inited = 1; 882 return 0; 883} 884 885static int qat_uclo_set_ae_mode(struct icp_qat_fw_loader_handle *handle) 886{ 887 unsigned char ae, nn_mode, s; 888 struct icp_qat_uof_image *uof_image; 889 struct icp_qat_uclo_aedata *ae_data; 890 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 891 892 for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) { 893 if (!test_bit(ae, 894 (unsigned long *)&handle->hal_handle->ae_mask)) 895 continue; 896 ae_data = &obj_handle->ae_data[ae]; 897 for (s = 0; s < min_t(unsigned int, ae_data->slice_num, 898 ICP_QAT_UCLO_MAX_CTX); s++) { 899 if (!obj_handle->ae_data[ae].ae_slices[s].encap_image) 900 continue; 901 uof_image = ae_data->ae_slices[s].encap_image->img_ptr; 902 if (qat_hal_set_ae_ctx_mode(handle, ae, 903 (char)ICP_QAT_CTX_MODE 904 (uof_image->ae_mode))) { 905 pr_err("QAT: qat_hal_set_ae_ctx_mode error\n"); 906 return -EFAULT; 907 } 908 nn_mode = ICP_QAT_NN_MODE(uof_image->ae_mode); 909 if (qat_hal_set_ae_nn_mode(handle, ae, nn_mode)) { 910 pr_err("QAT: qat_hal_set_ae_nn_mode error\n"); 911 return -EFAULT; 912 } 913 if (qat_hal_set_ae_lm_mode(handle, ae, ICP_LMEM0, 914 (char)ICP_QAT_LOC_MEM0_MODE 915 (uof_image->ae_mode))) { 916 pr_err("QAT: qat_hal_set_ae_lm_mode LMEM0 error\n"); 917 return -EFAULT; 918 } 919 if (qat_hal_set_ae_lm_mode(handle, ae, ICP_LMEM1, 920 (char)ICP_QAT_LOC_MEM1_MODE 921 (uof_image->ae_mode))) { 922 pr_err("QAT: qat_hal_set_ae_lm_mode LMEM1 error\n"); 923 return -EFAULT; 924 } 925 } 926 } 927 return 0; 928} 929 930static void qat_uclo_init_uword_num(struct icp_qat_fw_loader_handle *handle) 931{ 932 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 933 struct icp_qat_uclo_encapme *image; 934 int a; 935 936 for (a = 0; a < obj_handle->uimage_num; a++) { 937 image = &obj_handle->ae_uimage[a]; 938 image->uwords_num = image->page->beg_addr_p + 939 image->page->micro_words_num; 940 } 941} 942 943static int qat_uclo_parse_uof_obj(struct icp_qat_fw_loader_handle *handle) 944{ 945 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 946 unsigned int ae; 947 948 obj_handle->uword_buf = kcalloc(UWORD_CPYBUF_SIZE, sizeof(uint64_t), 949 GFP_KERNEL); 950 if (!obj_handle->uword_buf) 951 return -ENOMEM; 952 obj_handle->encap_uof_obj.beg_uof = obj_handle->obj_hdr->file_buff; 953 obj_handle->encap_uof_obj.obj_hdr = (struct icp_qat_uof_objhdr *) 954 obj_handle->obj_hdr->file_buff; 955 obj_handle->uword_in_bytes = 6; 956 obj_handle->prod_type = ICP_QAT_AC_C_CPU_TYPE; 957 obj_handle->prod_rev = PID_MAJOR_REV | 958 (PID_MINOR_REV & handle->hal_handle->revision_id); 959 if (qat_uclo_check_uof_compat(obj_handle)) { 960 pr_err("QAT: UOF incompatible\n"); 961 return -EINVAL; 962 } 963 obj_handle->ustore_phy_size = ICP_QAT_UCLO_MAX_USTORE; 964 if (!obj_handle->obj_hdr->file_buff || 965 !qat_uclo_map_str_table(obj_handle->obj_hdr, ICP_QAT_UOF_STRT, 966 &obj_handle->str_table)) { 967 pr_err("QAT: UOF doesn't have effective images\n"); 968 goto out_err; 969 } 970 obj_handle->uimage_num = 971 qat_uclo_map_uimage(obj_handle, obj_handle->ae_uimage, 972 ICP_QAT_UCLO_MAX_AE * ICP_QAT_UCLO_MAX_CTX); 973 if (!obj_handle->uimage_num) 974 goto out_err; 975 if (qat_uclo_map_ae(handle, handle->hal_handle->ae_max_num)) { 976 pr_err("QAT: Bad object\n"); 977 goto out_check_uof_aemask_err; 978 } 979 qat_uclo_init_uword_num(handle); 980 qat_uclo_map_initmem_table(&obj_handle->encap_uof_obj, 981 &obj_handle->init_mem_tab); 982 if (qat_uclo_set_ae_mode(handle)) 983 goto out_check_uof_aemask_err; 984 return 0; 985out_check_uof_aemask_err: 986 for (ae = 0; ae < obj_handle->uimage_num; ae++) 987 kfree(obj_handle->ae_uimage[ae].page); 988out_err: 989 kfree(obj_handle->uword_buf); 990 return -EFAULT; 991} 992 993int qat_uclo_map_uof_obj(struct icp_qat_fw_loader_handle *handle, 994 void *addr_ptr, int mem_size) 995{ 996 struct icp_qat_uof_filehdr *filehdr; 997 struct icp_qat_uclo_objhandle *objhdl; 998 999 BUILD_BUG_ON(ICP_QAT_UCLO_MAX_AE >= 1000 (sizeof(handle->hal_handle->ae_mask) * 8)); 1001 1002 if (!handle || !addr_ptr || mem_size < 24) 1003 return -EINVAL; 1004 objhdl = kzalloc(sizeof(*objhdl), GFP_KERNEL); 1005 if (!objhdl) 1006 return -ENOMEM; 1007 objhdl->obj_buf = kmemdup(addr_ptr, mem_size, GFP_KERNEL); 1008 if (!objhdl->obj_buf) 1009 goto out_objbuf_err; 1010 filehdr = (struct icp_qat_uof_filehdr *)objhdl->obj_buf; 1011 if (qat_uclo_check_format(filehdr)) 1012 goto out_objhdr_err; 1013 objhdl->obj_hdr = qat_uclo_map_chunk((char *)objhdl->obj_buf, filehdr, 1014 ICP_QAT_UOF_OBJS); 1015 if (!objhdl->obj_hdr) { 1016 pr_err("QAT: object file chunk is null\n"); 1017 goto out_objhdr_err; 1018 } 1019 handle->obj_handle = objhdl; 1020 if (qat_uclo_parse_uof_obj(handle)) 1021 goto out_overlay_obj_err; 1022 return 0; 1023 1024out_overlay_obj_err: 1025 handle->obj_handle = NULL; 1026 kfree(objhdl->obj_hdr); 1027out_objhdr_err: 1028 kfree(objhdl->obj_buf); 1029out_objbuf_err: 1030 kfree(objhdl); 1031 return -ENOMEM; 1032} 1033 1034void qat_uclo_del_uof_obj(struct icp_qat_fw_loader_handle *handle) 1035{ 1036 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 1037 unsigned int a; 1038 1039 if (!obj_handle) 1040 return; 1041 1042 kfree(obj_handle->uword_buf); 1043 for (a = 0; a < obj_handle->uimage_num; a++) 1044 kfree(obj_handle->ae_uimage[a].page); 1045 1046 for (a = 0; a < handle->hal_handle->ae_max_num; a++) 1047 qat_uclo_free_ae_data(&obj_handle->ae_data[a]); 1048 1049 kfree(obj_handle->obj_hdr); 1050 kfree(obj_handle->obj_buf); 1051 kfree(obj_handle); 1052 handle->obj_handle = NULL; 1053} 1054 1055static void qat_uclo_fill_uwords(struct icp_qat_uclo_objhandle *obj_handle, 1056 struct icp_qat_uclo_encap_page *encap_page, 1057 uint64_t *uword, unsigned int addr_p, 1058 unsigned int raddr, uint64_t fill) 1059{ 1060 uint64_t uwrd = 0; 1061 unsigned int i; 1062 1063 if (!encap_page) { 1064 *uword = fill; 1065 return; 1066 } 1067 for (i = 0; i < encap_page->uwblock_num; i++) { 1068 if (raddr >= encap_page->uwblock[i].start_addr && 1069 raddr <= encap_page->uwblock[i].start_addr + 1070 encap_page->uwblock[i].words_num - 1) { 1071 raddr -= encap_page->uwblock[i].start_addr; 1072 raddr *= obj_handle->uword_in_bytes; 1073 memcpy(&uwrd, (void *)(((unsigned long) 1074 encap_page->uwblock[i].micro_words) + raddr), 1075 obj_handle->uword_in_bytes); 1076 uwrd = uwrd & 0xbffffffffffull; 1077 } 1078 } 1079 *uword = uwrd; 1080 if (*uword == INVLD_UWORD) 1081 *uword = fill; 1082} 1083 1084static void qat_uclo_wr_uimage_raw_page(struct icp_qat_fw_loader_handle *handle, 1085 struct icp_qat_uclo_encap_page 1086 *encap_page, unsigned int ae) 1087{ 1088 unsigned int uw_physical_addr, uw_relative_addr, i, words_num, cpylen; 1089 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 1090 uint64_t fill_pat; 1091 1092 /* load the page starting at appropriate ustore address */ 1093 /* get fill-pattern from an image -- they are all the same */ 1094 memcpy(&fill_pat, obj_handle->ae_uimage[0].img_ptr->fill_pattern, 1095 sizeof(uint64_t)); 1096 uw_physical_addr = encap_page->beg_addr_p; 1097 uw_relative_addr = 0; 1098 words_num = encap_page->micro_words_num; 1099 while (words_num) { 1100 if (words_num < UWORD_CPYBUF_SIZE) 1101 cpylen = words_num; 1102 else 1103 cpylen = UWORD_CPYBUF_SIZE; 1104 1105 /* load the buffer */ 1106 for (i = 0; i < cpylen; i++) 1107 qat_uclo_fill_uwords(obj_handle, encap_page, 1108 &obj_handle->uword_buf[i], 1109 uw_physical_addr + i, 1110 uw_relative_addr + i, fill_pat); 1111 1112 /* copy the buffer to ustore */ 1113 qat_hal_wr_uwords(handle, (unsigned char)ae, 1114 uw_physical_addr, cpylen, 1115 obj_handle->uword_buf); 1116 1117 uw_physical_addr += cpylen; 1118 uw_relative_addr += cpylen; 1119 words_num -= cpylen; 1120 } 1121} 1122 1123static void qat_uclo_wr_uimage_page(struct icp_qat_fw_loader_handle *handle, 1124 struct icp_qat_uof_image *image) 1125{ 1126 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 1127 unsigned int ctx_mask, s; 1128 struct icp_qat_uclo_page *page; 1129 unsigned char ae; 1130 int ctx; 1131 1132 if (ICP_QAT_CTX_MODE(image->ae_mode) == ICP_QAT_UCLO_MAX_CTX) 1133 ctx_mask = 0xff; 1134 else 1135 ctx_mask = 0x55; 1136 /* load the default page and set assigned CTX PC 1137 * to the entrypoint address */ 1138 for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) { 1139 if (!test_bit(ae, (unsigned long *)&image->ae_assigned)) 1140 continue; 1141 /* find the slice to which this image is assigned */ 1142 for (s = 0; s < obj_handle->ae_data[ae].slice_num; s++) { 1143 if (image->ctx_assigned & obj_handle->ae_data[ae]. 1144 ae_slices[s].ctx_mask_assigned) 1145 break; 1146 } 1147 if (s >= obj_handle->ae_data[ae].slice_num) 1148 continue; 1149 page = obj_handle->ae_data[ae].ae_slices[s].page; 1150 if (!page->encap_page->def_page) 1151 continue; 1152 qat_uclo_wr_uimage_raw_page(handle, page->encap_page, ae); 1153 1154 page = obj_handle->ae_data[ae].ae_slices[s].page; 1155 for (ctx = 0; ctx < ICP_QAT_UCLO_MAX_CTX; ctx++) 1156 obj_handle->ae_data[ae].ae_slices[s].cur_page[ctx] = 1157 (ctx_mask & (1 << ctx)) ? page : NULL; 1158 qat_hal_set_live_ctx(handle, (unsigned char)ae, 1159 image->ctx_assigned); 1160 qat_hal_set_pc(handle, (unsigned char)ae, image->ctx_assigned, 1161 image->entry_address); 1162 } 1163} 1164 1165int qat_uclo_wr_all_uimage(struct icp_qat_fw_loader_handle *handle) 1166{ 1167 struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle; 1168 unsigned int i; 1169 1170 if (qat_uclo_init_globals(handle)) 1171 return -EINVAL; 1172 for (i = 0; i < obj_handle->uimage_num; i++) { 1173 if (!obj_handle->ae_uimage[i].img_ptr) 1174 return -EINVAL; 1175 if (qat_uclo_init_ustore(handle, &obj_handle->ae_uimage[i])) 1176 return -EINVAL; 1177 qat_uclo_wr_uimage_page(handle, 1178 obj_handle->ae_uimage[i].img_ptr); 1179 } 1180 return 0; 1181} 1182