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