1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2 * 3 * Copyright 2008-2016 Freescale Semiconductor Inc. 4 * Copyright 2016,2019 NXP 5 */ 6 7 #ifndef __RTA_SEC_RUN_TIME_ASM_H__ 8 #define __RTA_SEC_RUN_TIME_ASM_H__ 9 10 #include "desc.h" 11 12 /* hw/compat.h is not delivered in kernel */ 13 #ifndef __KERNEL__ 14 #include "compat.h" 15 #endif 16 17 /** 18 * enum rta_sec_era - SEC HW block revisions supported by the RTA library 19 * @RTA_SEC_ERA_1: SEC Era 1 20 * @RTA_SEC_ERA_2: SEC Era 2 21 * @RTA_SEC_ERA_3: SEC Era 3 22 * @RTA_SEC_ERA_4: SEC Era 4 23 * @RTA_SEC_ERA_5: SEC Era 5 24 * @RTA_SEC_ERA_6: SEC Era 6 25 * @RTA_SEC_ERA_7: SEC Era 7 26 * @RTA_SEC_ERA_8: SEC Era 8 27 * @MAX_SEC_ERA: maximum SEC HW block revision supported by RTA library 28 */ 29 enum rta_sec_era { 30 RTA_SEC_ERA_1, 31 RTA_SEC_ERA_2, 32 RTA_SEC_ERA_3, 33 RTA_SEC_ERA_4, 34 RTA_SEC_ERA_5, 35 RTA_SEC_ERA_6, 36 RTA_SEC_ERA_7, 37 RTA_SEC_ERA_8, 38 RTA_SEC_ERA_9, 39 RTA_SEC_ERA_10, 40 MAX_SEC_ERA = RTA_SEC_ERA_10 41 }; 42 43 /** 44 * DEFAULT_SEC_ERA - the default value for the SEC era in case the user provides 45 * an unsupported value. 46 */ 47 #define DEFAULT_SEC_ERA MAX_SEC_ERA 48 49 /** 50 * USER_SEC_ERA - translates the SEC Era from internal to user representation. 51 * @sec_era: SEC Era in internal (library) representation 52 */ 53 #define USER_SEC_ERA(sec_era) (sec_era + 1) 54 55 /** 56 * INTL_SEC_ERA - translates the SEC Era from user representation to internal. 57 * @sec_era: SEC Era in user representation 58 */ 59 #define INTL_SEC_ERA(sec_era) (sec_era - 1) 60 61 /** 62 * enum rta_jump_type - Types of action taken by JUMP command 63 * @LOCAL_JUMP: conditional jump to an offset within the descriptor buffer 64 * @FAR_JUMP: conditional jump to a location outside the descriptor buffer, 65 * indicated by the POINTER field after the JUMP command. 66 * @HALT: conditional halt - stop the execution of the current descriptor and 67 * writes PKHA / Math condition bits as status / error code. 68 * @HALT_STATUS: conditional halt with user-specified status - stop the 69 * execution of the current descriptor and writes the value of 70 * "LOCAL OFFSET" JUMP field as status / error code. 71 * @GOSUB: conditional subroutine call - similar to @LOCAL_JUMP, but also saves 72 * return address in the Return Address register; subroutine calls 73 * cannot be nested. 74 * @RETURN: conditional subroutine return - similar to @LOCAL_JUMP, but the 75 * offset is taken from the Return Address register. 76 * @LOCAL_JUMP_INC: similar to @LOCAL_JUMP, but increment the register specified 77 * in "SRC_DST" JUMP field before evaluating the jump 78 * condition. 79 * @LOCAL_JUMP_DEC: similar to @LOCAL_JUMP, but decrement the register specified 80 * in "SRC_DST" JUMP field before evaluating the jump 81 * condition. 82 */ 83 enum rta_jump_type { 84 LOCAL_JUMP, 85 FAR_JUMP, 86 HALT, 87 HALT_STATUS, 88 GOSUB, 89 RETURN, 90 LOCAL_JUMP_INC, 91 LOCAL_JUMP_DEC 92 }; 93 94 /** 95 * enum rta_jump_cond - How test conditions are evaluated by JUMP command 96 * @ALL_TRUE: perform action if ALL selected conditions are true 97 * @ALL_FALSE: perform action if ALL selected conditions are false 98 * @ANY_TRUE: perform action if ANY of the selected conditions is true 99 * @ANY_FALSE: perform action if ANY of the selected conditions is false 100 */ 101 enum rta_jump_cond { 102 ALL_TRUE, 103 ALL_FALSE, 104 ANY_TRUE, 105 ANY_FALSE 106 }; 107 108 /** 109 * enum rta_share_type - Types of sharing for JOB_HDR and SHR_HDR commands 110 * @SHR_NEVER: nothing is shared; descriptors can execute in parallel (i.e. no 111 * dependencies are allowed between them). 112 * @SHR_WAIT: shared descriptor and keys are shared once the descriptor sets 113 * "OK to share" in DECO Control Register (DCTRL). 114 * @SHR_SERIAL: shared descriptor and keys are shared once the descriptor has 115 * completed. 116 * @SHR_ALWAYS: shared descriptor is shared anytime after the descriptor is 117 * loaded. 118 * @SHR_DEFER: valid only for JOB_HDR; sharing type is the one specified 119 * in the shared descriptor associated with the job descriptor. 120 */ 121 enum rta_share_type { 122 SHR_NEVER, 123 SHR_WAIT, 124 SHR_SERIAL, 125 SHR_ALWAYS, 126 SHR_DEFER 127 }; 128 129 /** 130 * enum rta_data_type - Indicates how is the data provided and how to include it 131 * in the descriptor. 132 * @RTA_DATA_PTR: Data is in memory and accessed by reference; data address is a 133 * physical (bus) address. 134 * @RTA_DATA_IMM: Data is inlined in descriptor and accessed as immediate data; 135 * data address is a virtual address. 136 * @RTA_DATA_IMM_DMA: (AIOP only) Data is inlined in descriptor and accessed as 137 * immediate data; data address is a physical (bus) address 138 * in external memory and CDMA is programmed to transfer the 139 * data into descriptor buffer being built in Workspace Area. 140 */ 141 enum rta_data_type { 142 RTA_DATA_PTR = 1, 143 RTA_DATA_IMM, 144 RTA_DATA_IMM_DMA 145 }; 146 147 /* Registers definitions */ 148 enum rta_regs { 149 /* CCB Registers */ 150 CONTEXT1 = 1, 151 CONTEXT2, 152 KEY1, 153 KEY2, 154 KEY1SZ, 155 KEY2SZ, 156 ICV1SZ, 157 ICV2SZ, 158 DATA1SZ, 159 DATA2SZ, 160 ALTDS1, 161 IV1SZ, 162 AAD1SZ, 163 MODE1, 164 MODE2, 165 CCTRL, 166 DCTRL, 167 ICTRL, 168 CLRW, 169 CSTAT, 170 IFIFO, 171 NFIFO, 172 OFIFO, 173 PKASZ, 174 PKBSZ, 175 PKNSZ, 176 PKESZ, 177 /* DECO Registers */ 178 MATH0, 179 MATH1, 180 MATH2, 181 MATH3, 182 DESCBUF, 183 JOBDESCBUF, 184 SHAREDESCBUF, 185 DPOVRD, 186 DJQDA, 187 DSTAT, 188 DPID, 189 DJQCTRL, 190 ALTSOURCE, 191 SEQINSZ, 192 SEQOUTSZ, 193 VSEQINSZ, 194 VSEQOUTSZ, 195 /* PKHA Registers */ 196 PKA, 197 PKN, 198 PKA0, 199 PKA1, 200 PKA2, 201 PKA3, 202 PKB, 203 PKB0, 204 PKB1, 205 PKB2, 206 PKB3, 207 PKE, 208 /* Pseudo registers */ 209 AB1, 210 AB2, 211 ABD, 212 IFIFOABD, 213 IFIFOAB1, 214 IFIFOAB2, 215 AFHA_SBOX, 216 MDHA_SPLIT_KEY, 217 JOBSRC, 218 ZERO, 219 ONE, 220 AAD1, 221 IV1, 222 IV2, 223 MSG1, 224 MSG2, 225 MSG, 226 MSG_CKSUM, 227 MSGOUTSNOOP, 228 MSGINSNOOP, 229 ICV1, 230 ICV2, 231 SKIP, 232 NONE, 233 RNGOFIFO, 234 RNG, 235 IDFNS, 236 ODFNS, 237 NFIFOSZ, 238 SZ, 239 PAD, 240 SAD1, 241 AAD2, 242 BIT_DATA, 243 NFIFO_SZL, 244 NFIFO_SZM, 245 NFIFO_L, 246 NFIFO_M, 247 SZL, 248 SZM, 249 JOBDESCBUF_EFF, 250 SHAREDESCBUF_EFF, 251 METADATA, 252 GTR, 253 STR, 254 OFIFO_SYNC, 255 MSGOUTSNOOP_ALT 256 }; 257 258 /* Command flags */ 259 #define FLUSH1 BIT(0) 260 #define LAST1 BIT(1) 261 #define LAST2 BIT(2) 262 #define IMMED BIT(3) 263 #define SGF BIT(4) 264 #define VLF BIT(5) 265 #define EXT BIT(6) 266 #define CONT BIT(7) 267 #define SEQ BIT(8) 268 #define AIDF BIT(9) 269 #define FLUSH2 BIT(10) 270 #define CLASS1 BIT(11) 271 #define CLASS2 BIT(12) 272 #define BOTH BIT(13) 273 274 /** 275 * DCOPY - (AIOP only) command param is pointer to external memory 276 * 277 * CDMA must be used to transfer the key via DMA into Workspace Area. 278 * Valid only in combination with IMMED flag. 279 */ 280 #define DCOPY BIT(30) 281 282 #define COPY BIT(31) /* command param is pointer (not immediate) 283 * valid only in combination when IMMED 284 */ 285 286 #define __COPY_MASK (COPY | DCOPY) 287 288 /* SEQ IN/OUT PTR Command specific flags */ 289 #define RBS BIT(16) 290 #define INL BIT(17) 291 #define PRE BIT(18) 292 #define RTO BIT(19) 293 #define RJD BIT(20) 294 #define SOP BIT(21) 295 #define RST BIT(22) 296 #define EWS BIT(23) 297 298 #define ENC BIT(14) /* Encrypted Key */ 299 #define EKT BIT(15) /* AES CCM Encryption (default is 300 * AES ECB Encryption) 301 */ 302 #define TK BIT(16) /* Trusted Descriptor Key (default is 303 * Job Descriptor Key) 304 */ 305 #define NWB BIT(17) /* No Write Back Key */ 306 #define PTS BIT(18) /* Plaintext Store */ 307 308 /* HEADER Command specific flags */ 309 #define RIF BIT(16) 310 #define DNR BIT(17) 311 #define CIF BIT(18) 312 #define PD BIT(19) 313 #define RSMS BIT(20) 314 #define TD BIT(21) 315 #define MTD BIT(22) 316 #define REO BIT(23) 317 #define SHR BIT(24) 318 #define SC BIT(25) 319 /* Extended HEADER specific flags */ 320 #define DSV BIT(7) 321 #define DSEL_MASK 0x00000007 /* DECO Select */ 322 #define FTD BIT(8) 323 324 /* JUMP Command specific flags */ 325 #define NIFP BIT(20) 326 #define NIP BIT(21) 327 #define NOP BIT(22) 328 #define NCP BIT(23) 329 #define CALM BIT(24) 330 331 #define MATH_Z BIT(25) 332 #define MATH_N BIT(26) 333 #define MATH_NV BIT(27) 334 #define MATH_C BIT(28) 335 #define PK_0 BIT(29) 336 #define PK_GCD_1 BIT(30) 337 #define PK_PRIME BIT(31) 338 #define SELF BIT(0) 339 #define SHRD BIT(1) 340 #define JQP BIT(2) 341 342 /* NFIFOADD specific flags */ 343 #define PAD_ZERO BIT(16) 344 #define PAD_NONZERO BIT(17) 345 #define PAD_INCREMENT BIT(18) 346 #define PAD_RANDOM BIT(19) 347 #define PAD_ZERO_N1 BIT(20) 348 #define PAD_NONZERO_0 BIT(21) 349 #define PAD_N1 BIT(23) 350 #define PAD_NONZERO_N BIT(24) 351 #define OC BIT(25) 352 #define BM BIT(26) 353 #define PR BIT(27) 354 #define PS BIT(28) 355 #define BP BIT(29) 356 357 /* MOVE Command specific flags */ 358 #define WAITCOMP BIT(16) 359 #define SIZE_WORD BIT(17) 360 #define SIZE_BYTE BIT(18) 361 #define SIZE_DWORD BIT(19) 362 363 /* MATH command specific flags */ 364 #define IFB MATH_IFB 365 #define NFU MATH_NFU 366 #define STL MATH_STL 367 #define SSEL MATH_SSEL 368 #define SWP MATH_SWP 369 #define IMMED2 BIT(31) 370 371 /** 372 * struct program - descriptor buffer management structure 373 * @current_pc: current offset in descriptor 374 * @current_instruction: current instruction in descriptor 375 * @first_error_pc: offset of the first error in descriptor 376 * @start_pc: start offset in descriptor buffer 377 * @buffer: buffer carrying descriptor 378 * @shrhdr: shared descriptor header 379 * @jobhdr: job descriptor header 380 * @ps: pointer fields size; if ps is true, pointers will be 36bits in 381 * length; if ps is false, pointers will be 32bits in length 382 * @bswap: if true, perform byte swap on a 4-byte boundary 383 */ 384 struct program { 385 unsigned int current_pc; 386 unsigned int current_instruction; 387 unsigned int first_error_pc; 388 unsigned int start_pc; 389 uint32_t *buffer; 390 uint32_t *shrhdr; 391 uint32_t *jobhdr; 392 bool ps; 393 bool bswap; 394 }; 395 396 static inline void 397 rta_program_cntxt_init(struct program *program, 398 uint32_t *buffer, unsigned int offset) 399 { 400 program->current_pc = 0; 401 program->current_instruction = 0; 402 program->first_error_pc = 0; 403 program->start_pc = offset; 404 program->buffer = buffer; 405 program->shrhdr = NULL; 406 program->jobhdr = NULL; 407 program->ps = false; 408 program->bswap = false; 409 } 410 411 static inline int 412 rta_program_finalize(struct program *program) 413 { 414 /* Descriptor is usually not allowed to go beyond 64 words size */ 415 if (program->current_pc > MAX_CAAM_DESCSIZE) 416 pr_warn("Descriptor Size exceeded max limit of 64 words\n"); 417 418 /* Descriptor is erroneous */ 419 if (program->first_error_pc) { 420 pr_err("Descriptor creation error\n"); 421 return -EINVAL; 422 } 423 424 /* Update descriptor length in shared and job descriptor headers */ 425 if (program->shrhdr != NULL) 426 *program->shrhdr |= program->bswap ? 427 swab32(program->current_pc) : 428 program->current_pc; 429 else if (program->jobhdr != NULL) 430 *program->jobhdr |= program->bswap ? 431 swab32(program->current_pc) : 432 program->current_pc; 433 434 return (int)program->current_pc; 435 } 436 437 static inline unsigned int 438 rta_program_set_36bit_addr(struct program *program) 439 { 440 program->ps = true; 441 return program->current_pc; 442 } 443 444 static inline unsigned int 445 rta_program_set_bswap(struct program *program) 446 { 447 program->bswap = true; 448 return program->current_pc; 449 } 450 451 static inline void 452 __rta_out32(struct program *program, uint32_t val) 453 { 454 program->buffer[program->current_pc] = program->bswap ? 455 swab32(val) : val; 456 program->current_pc++; 457 } 458 459 static inline void 460 __rta_out_be32(struct program *program, uint32_t val) 461 { 462 program->buffer[program->current_pc] = cpu_to_be32(val); 463 program->current_pc++; 464 } 465 466 static inline void 467 __rta_out_le32(struct program *program, uint32_t val) 468 { 469 program->buffer[program->current_pc] = cpu_to_le32(val); 470 program->current_pc++; 471 } 472 473 static inline void 474 __rta_out64(struct program *program, bool is_ext, uint64_t val) 475 { 476 if (is_ext) { 477 /* 478 * Since we are guaranteed only a 4-byte alignment in the 479 * descriptor buffer, we have to do 2 x 32-bit (word) writes. 480 * For the order of the 2 words to be correct, we need to 481 * take into account the endianness of the CPU. 482 */ 483 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 484 __rta_out32(program, program->bswap ? lower_32_bits(val) : 485 upper_32_bits(val)); 486 487 __rta_out32(program, program->bswap ? upper_32_bits(val) : 488 lower_32_bits(val)); 489 #else 490 __rta_out32(program, program->bswap ? upper_32_bits(val) : 491 lower_32_bits(val)); 492 493 __rta_out32(program, program->bswap ? lower_32_bits(val) : 494 upper_32_bits(val)); 495 #endif 496 } else { 497 __rta_out32(program, lower_32_bits(val)); 498 } 499 } 500 501 static inline void __rta_out_be64(struct program *program, bool is_ext, 502 uint64_t val) 503 { 504 if (is_ext) { 505 __rta_out_be32(program, upper_32_bits(val)); 506 __rta_out_be32(program, lower_32_bits(val)); 507 } else { 508 __rta_out_be32(program, lower_32_bits(val)); 509 } 510 } 511 512 static inline void __rta_out_le64(struct program *program, bool is_ext, 513 uint64_t val) 514 { 515 if (is_ext) { 516 __rta_out_le32(program, lower_32_bits(val)); 517 __rta_out_le32(program, upper_32_bits(val)); 518 } else { 519 __rta_out_le32(program, lower_32_bits(val)); 520 } 521 } 522 523 static inline unsigned int 524 rta_word(struct program *program, uint32_t val) 525 { 526 unsigned int start_pc = program->current_pc; 527 528 __rta_out32(program, val); 529 530 return start_pc; 531 } 532 533 static inline unsigned int 534 rta_dword(struct program *program, uint64_t val) 535 { 536 unsigned int start_pc = program->current_pc; 537 538 __rta_out64(program, true, val); 539 540 return start_pc; 541 } 542 543 static inline uint32_t 544 inline_flags(enum rta_data_type data_type) 545 { 546 switch (data_type) { 547 case RTA_DATA_PTR: 548 return 0; 549 case RTA_DATA_IMM: 550 return IMMED | COPY; 551 case RTA_DATA_IMM_DMA: 552 return IMMED | DCOPY; 553 default: 554 /* warn and default to RTA_DATA_PTR */ 555 pr_warn("RTA: defaulting to RTA_DATA_PTR parameter type\n"); 556 return 0; 557 } 558 } 559 560 static inline unsigned int 561 rta_copy_data(struct program *program, uint8_t *data, unsigned int length) 562 { 563 unsigned int i; 564 unsigned int start_pc = program->current_pc; 565 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc]; 566 567 for (i = 0; i < length; i++) 568 *tmp++ = data[i]; 569 program->current_pc += (length + 3) / 4; 570 571 return start_pc; 572 } 573 574 #if defined(__EWL__) && defined(AIOP) 575 static inline void 576 __rta_dma_data(void *ws_dst, uint64_t ext_address, uint16_t size) 577 { cdma_read(ws_dst, ext_address, size); } 578 #else 579 static inline void 580 __rta_dma_data(void *ws_dst __maybe_unused, 581 uint64_t ext_address __maybe_unused, 582 uint16_t size __maybe_unused) 583 { pr_warn("RTA: DCOPY not supported, DMA will be skipped\n"); } 584 #endif /* defined(__EWL__) && defined(AIOP) */ 585 586 static inline void 587 __rta_inline_data(struct program *program, uint64_t data, 588 uint32_t copy_data, uint32_t length) 589 { 590 if (!copy_data) { 591 __rta_out64(program, length > 4, data); 592 } else if (copy_data & COPY) { 593 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc]; 594 uint32_t i; 595 596 for (i = 0; i < length; i++) 597 *tmp++ = ((uint8_t *)(uintptr_t)data)[i]; 598 program->current_pc += ((length + 3) / 4); 599 } else if (copy_data & DCOPY) { 600 __rta_dma_data(&program->buffer[program->current_pc], data, 601 (uint16_t)length); 602 program->current_pc += ((length + 3) / 4); 603 } 604 } 605 606 static inline unsigned int 607 rta_desc_len(uint32_t *buffer) 608 { 609 if ((*buffer & CMD_MASK) == CMD_DESC_HDR) { 610 return *buffer & HDR_DESCLEN_MASK; 611 } else { 612 if (rta_sec_era >= RTA_SEC_ERA_10) 613 return *buffer & HDR_DESCLEN_SHR_MASK_ERA10; 614 else 615 return *buffer & HDR_DESCLEN_SHR_MASK; 616 } 617 } 618 619 static inline unsigned int 620 rta_desc_bytes(uint32_t *buffer) 621 { 622 return (unsigned int)(rta_desc_len(buffer) * CAAM_CMD_SZ); 623 } 624 625 /** 626 * split_key_len - Compute MDHA split key length for a given algorithm 627 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* or 628 * OP_PCLID_DKP_* - MD5, SHA1, SHA224, SHA256, SHA384, SHA512. 629 * 630 * Return: MDHA split key length 631 */ 632 static inline uint32_t 633 split_key_len(uint32_t hash) 634 { 635 /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */ 636 static const uint8_t mdpadlen[] = { 16, 20, 32, 32, 64, 64 }; 637 uint32_t idx; 638 639 idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT; 640 641 return (uint32_t)(mdpadlen[idx] * 2); 642 } 643 644 /** 645 * split_key_pad_len - Compute MDHA split key pad length for a given algorithm 646 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1, 647 * SHA224, SHA384, SHA512. 648 * 649 * Return: MDHA split key pad length 650 */ 651 static inline uint32_t 652 split_key_pad_len(uint32_t hash) 653 { 654 return ALIGN(split_key_len(hash), 16); 655 } 656 657 static inline unsigned int 658 rta_set_label(struct program *program) 659 { 660 return program->current_pc + program->start_pc; 661 } 662 663 static inline int 664 rta_patch_move(struct program *program, int line, unsigned int new_ref) 665 { 666 uint32_t opcode; 667 bool bswap = program->bswap; 668 669 if (line < 0) 670 return -EINVAL; 671 672 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line]; 673 674 opcode &= (uint32_t)~MOVE_OFFSET_MASK; 675 opcode |= (new_ref << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK; 676 program->buffer[line] = bswap ? swab32(opcode) : opcode; 677 678 return 0; 679 } 680 681 static inline int 682 rta_patch_jmp(struct program *program, int line, unsigned int new_ref) 683 { 684 uint32_t opcode; 685 bool bswap = program->bswap; 686 687 if (line < 0) 688 return -EINVAL; 689 690 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line]; 691 692 opcode &= (uint32_t)~JUMP_OFFSET_MASK; 693 opcode |= (new_ref - (line + program->start_pc)) & JUMP_OFFSET_MASK; 694 program->buffer[line] = bswap ? swab32(opcode) : opcode; 695 696 return 0; 697 } 698 699 static inline int 700 rta_patch_header(struct program *program, int line, unsigned int new_ref) 701 { 702 uint32_t opcode; 703 bool bswap = program->bswap; 704 705 if (line < 0) 706 return -EINVAL; 707 708 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line]; 709 if (rta_sec_era >= RTA_SEC_ERA_10) { 710 opcode &= (uint32_t)~HDR_START_IDX_MASK_ERA10; 711 opcode |= (new_ref << HDR_START_IDX_SHIFT) & 712 HDR_START_IDX_MASK_ERA10; 713 } else { 714 opcode &= (uint32_t)~HDR_START_IDX_MASK; 715 opcode |= (new_ref << HDR_START_IDX_SHIFT) & HDR_START_IDX_MASK; 716 } 717 718 program->buffer[line] = bswap ? swab32(opcode) : opcode; 719 720 return 0; 721 } 722 723 static inline int 724 rta_patch_load(struct program *program, int line, unsigned int new_ref) 725 { 726 uint32_t opcode; 727 bool bswap = program->bswap; 728 729 if (line < 0) 730 return -EINVAL; 731 732 opcode = (bswap ? swab32(program->buffer[line]) : 733 program->buffer[line]) & (uint32_t)~LDST_OFFSET_MASK; 734 735 if (opcode & (LDST_SRCDST_WORD_DESCBUF | LDST_CLASS_DECO)) 736 opcode |= (new_ref << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK; 737 else 738 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) & 739 LDST_OFFSET_MASK; 740 741 program->buffer[line] = bswap ? swab32(opcode) : opcode; 742 743 return 0; 744 } 745 746 static inline int 747 rta_patch_store(struct program *program, int line, unsigned int new_ref) 748 { 749 uint32_t opcode; 750 bool bswap = program->bswap; 751 752 if (line < 0) 753 return -EINVAL; 754 755 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line]; 756 757 opcode &= (uint32_t)~LDST_OFFSET_MASK; 758 759 switch (opcode & LDST_SRCDST_MASK) { 760 case LDST_SRCDST_WORD_DESCBUF: 761 case LDST_SRCDST_WORD_DESCBUF_JOB: 762 case LDST_SRCDST_WORD_DESCBUF_SHARED: 763 case LDST_SRCDST_WORD_DESCBUF_JOB_WE: 764 case LDST_SRCDST_WORD_DESCBUF_SHARED_WE: 765 opcode |= ((new_ref) << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK; 766 break; 767 default: 768 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) & 769 LDST_OFFSET_MASK; 770 } 771 772 program->buffer[line] = bswap ? swab32(opcode) : opcode; 773 774 return 0; 775 } 776 777 static inline int 778 rta_patch_raw(struct program *program, int line, unsigned int mask, 779 unsigned int new_val) 780 { 781 uint32_t opcode; 782 bool bswap = program->bswap; 783 784 if (line < 0) 785 return -EINVAL; 786 787 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line]; 788 789 opcode &= (uint32_t)~mask; 790 opcode |= new_val & mask; 791 program->buffer[line] = bswap ? swab32(opcode) : opcode; 792 793 return 0; 794 } 795 796 static inline int 797 __rta_map_opcode(uint32_t name, const uint32_t (*map_table)[2], 798 unsigned int num_of_entries, uint32_t *val) 799 { 800 unsigned int i; 801 802 for (i = 0; i < num_of_entries; i++) 803 if (map_table[i][0] == name) { 804 *val = map_table[i][1]; 805 return 0; 806 } 807 808 return -EINVAL; 809 } 810 811 static inline void 812 __rta_map_flags(uint32_t flags, const uint32_t (*flags_table)[2], 813 unsigned int num_of_entries, uint32_t *opcode) 814 { 815 unsigned int i; 816 817 for (i = 0; i < num_of_entries; i++) { 818 if (flags_table[i][0] & flags) 819 *opcode |= flags_table[i][1]; 820 } 821 } 822 823 #endif /* __RTA_SEC_RUN_TIME_ASM_H__ */ 824