Imported Upstream version 17.05
[deb_dpdk.git] / drivers / crypto / dpaa2_sec / hw / rta / sec_run_time_asm.h
diff --git a/drivers/crypto/dpaa2_sec/hw/rta/sec_run_time_asm.h b/drivers/crypto/dpaa2_sec/hw/rta/sec_run_time_asm.h
new file mode 100644 (file)
index 0000000..c12edb0
--- /dev/null
@@ -0,0 +1,823 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ *   BSD LICENSE
+ *
+ * Copyright 2008-2016 Freescale Semiconductor Inc.
+ * Copyright (c) 2016 NXP.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *   GPL LICENSE SUMMARY
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __RTA_SEC_RUN_TIME_ASM_H__
+#define __RTA_SEC_RUN_TIME_ASM_H__
+
+#include "hw/desc.h"
+
+/* hw/compat.h is not delivered in kernel */
+#ifndef __KERNEL__
+#include "hw/compat.h"
+#endif
+
+/**
+ * enum rta_sec_era - SEC HW block revisions supported by the RTA library
+ * @RTA_SEC_ERA_1: SEC Era 1
+ * @RTA_SEC_ERA_2: SEC Era 2
+ * @RTA_SEC_ERA_3: SEC Era 3
+ * @RTA_SEC_ERA_4: SEC Era 4
+ * @RTA_SEC_ERA_5: SEC Era 5
+ * @RTA_SEC_ERA_6: SEC Era 6
+ * @RTA_SEC_ERA_7: SEC Era 7
+ * @RTA_SEC_ERA_8: SEC Era 8
+ * @MAX_SEC_ERA: maximum SEC HW block revision supported by RTA library
+ */
+enum rta_sec_era {
+       RTA_SEC_ERA_1,
+       RTA_SEC_ERA_2,
+       RTA_SEC_ERA_3,
+       RTA_SEC_ERA_4,
+       RTA_SEC_ERA_5,
+       RTA_SEC_ERA_6,
+       RTA_SEC_ERA_7,
+       RTA_SEC_ERA_8,
+       MAX_SEC_ERA = RTA_SEC_ERA_8
+};
+
+/**
+ * DEFAULT_SEC_ERA - the default value for the SEC era in case the user provides
+ * an unsupported value.
+ */
+#define DEFAULT_SEC_ERA        MAX_SEC_ERA
+
+/**
+ * USER_SEC_ERA - translates the SEC Era from internal to user representation.
+ * @sec_era: SEC Era in internal (library) representation
+ */
+#define USER_SEC_ERA(sec_era)  (sec_era + 1)
+
+/**
+ * INTL_SEC_ERA - translates the SEC Era from user representation to internal.
+ * @sec_era: SEC Era in user representation
+ */
+#define INTL_SEC_ERA(sec_era)  (sec_era - 1)
+
+/**
+ * enum rta_jump_type - Types of action taken by JUMP command
+ * @LOCAL_JUMP: conditional jump to an offset within the descriptor buffer
+ * @FAR_JUMP: conditional jump to a location outside the descriptor buffer,
+ *            indicated by the POINTER field after the JUMP command.
+ * @HALT: conditional halt - stop the execution of the current descriptor and
+ *        writes PKHA / Math condition bits as status / error code.
+ * @HALT_STATUS: conditional halt with user-specified status - stop the
+ *               execution of the current descriptor and writes the value of
+ *               "LOCAL OFFSET" JUMP field as status / error code.
+ * @GOSUB: conditional subroutine call - similar to @LOCAL_JUMP, but also saves
+ *         return address in the Return Address register; subroutine calls
+ *         cannot be nested.
+ * @RETURN: conditional subroutine return - similar to @LOCAL_JUMP, but the
+ *          offset is taken from the Return Address register.
+ * @LOCAL_JUMP_INC: similar to @LOCAL_JUMP, but increment the register specified
+ *                  in "SRC_DST" JUMP field before evaluating the jump
+ *                  condition.
+ * @LOCAL_JUMP_DEC: similar to @LOCAL_JUMP, but decrement the register specified
+ *                  in "SRC_DST" JUMP field before evaluating the jump
+ *                  condition.
+ */
+enum rta_jump_type {
+       LOCAL_JUMP,
+       FAR_JUMP,
+       HALT,
+       HALT_STATUS,
+       GOSUB,
+       RETURN,
+       LOCAL_JUMP_INC,
+       LOCAL_JUMP_DEC
+};
+
+/**
+ * enum rta_jump_cond - How test conditions are evaluated by JUMP command
+ * @ALL_TRUE: perform action if ALL selected conditions are true
+ * @ALL_FALSE: perform action if ALL selected conditions are false
+ * @ANY_TRUE: perform action if ANY of the selected conditions is true
+ * @ANY_FALSE: perform action if ANY of the selected conditions is false
+ */
+enum rta_jump_cond {
+       ALL_TRUE,
+       ALL_FALSE,
+       ANY_TRUE,
+       ANY_FALSE
+};
+
+/**
+ * enum rta_share_type - Types of sharing for JOB_HDR and SHR_HDR commands
+ * @SHR_NEVER: nothing is shared; descriptors can execute in parallel (i.e. no
+ *             dependencies are allowed between them).
+ * @SHR_WAIT: shared descriptor and keys are shared once the descriptor sets
+ *            "OK to share" in DECO Control Register (DCTRL).
+ * @SHR_SERIAL: shared descriptor and keys are shared once the descriptor has
+ *              completed.
+ * @SHR_ALWAYS: shared descriptor is shared anytime after the descriptor is
+ *              loaded.
+ * @SHR_DEFER: valid only for JOB_HDR; sharing type is the one specified
+ *             in the shared descriptor associated with the job descriptor.
+ */
+enum rta_share_type {
+       SHR_NEVER,
+       SHR_WAIT,
+       SHR_SERIAL,
+       SHR_ALWAYS,
+       SHR_DEFER
+};
+
+/**
+ * enum rta_data_type - Indicates how is the data provided and how to include it
+ *                      in the descriptor.
+ * @RTA_DATA_PTR: Data is in memory and accessed by reference; data address is a
+ *               physical (bus) address.
+ * @RTA_DATA_IMM: Data is inlined in descriptor and accessed as immediate data;
+ *               data address is a virtual address.
+ * @RTA_DATA_IMM_DMA: (AIOP only) Data is inlined in descriptor and accessed as
+ *                   immediate data; data address is a physical (bus) address
+ *                   in external memory and CDMA is programmed to transfer the
+ *                   data into descriptor buffer being built in Workspace Area.
+ */
+enum rta_data_type {
+       RTA_DATA_PTR = 1,
+       RTA_DATA_IMM,
+       RTA_DATA_IMM_DMA
+};
+
+/* Registers definitions */
+enum rta_regs {
+       /* CCB Registers */
+       CONTEXT1 = 1,
+       CONTEXT2,
+       KEY1,
+       KEY2,
+       KEY1SZ,
+       KEY2SZ,
+       ICV1SZ,
+       ICV2SZ,
+       DATA1SZ,
+       DATA2SZ,
+       ALTDS1,
+       IV1SZ,
+       AAD1SZ,
+       MODE1,
+       MODE2,
+       CCTRL,
+       DCTRL,
+       ICTRL,
+       CLRW,
+       CSTAT,
+       IFIFO,
+       NFIFO,
+       OFIFO,
+       PKASZ,
+       PKBSZ,
+       PKNSZ,
+       PKESZ,
+       /* DECO Registers */
+       MATH0,
+       MATH1,
+       MATH2,
+       MATH3,
+       DESCBUF,
+       JOBDESCBUF,
+       SHAREDESCBUF,
+       DPOVRD,
+       DJQDA,
+       DSTAT,
+       DPID,
+       DJQCTRL,
+       ALTSOURCE,
+       SEQINSZ,
+       SEQOUTSZ,
+       VSEQINSZ,
+       VSEQOUTSZ,
+       /* PKHA Registers */
+       PKA,
+       PKN,
+       PKA0,
+       PKA1,
+       PKA2,
+       PKA3,
+       PKB,
+       PKB0,
+       PKB1,
+       PKB2,
+       PKB3,
+       PKE,
+       /* Pseudo registers */
+       AB1,
+       AB2,
+       ABD,
+       IFIFOABD,
+       IFIFOAB1,
+       IFIFOAB2,
+       AFHA_SBOX,
+       MDHA_SPLIT_KEY,
+       JOBSRC,
+       ZERO,
+       ONE,
+       AAD1,
+       IV1,
+       IV2,
+       MSG1,
+       MSG2,
+       MSG,
+       MSG_CKSUM,
+       MSGOUTSNOOP,
+       MSGINSNOOP,
+       ICV1,
+       ICV2,
+       SKIP,
+       NONE,
+       RNGOFIFO,
+       RNG,
+       IDFNS,
+       ODFNS,
+       NFIFOSZ,
+       SZ,
+       PAD,
+       SAD1,
+       AAD2,
+       BIT_DATA,
+       NFIFO_SZL,
+       NFIFO_SZM,
+       NFIFO_L,
+       NFIFO_M,
+       SZL,
+       SZM,
+       JOBDESCBUF_EFF,
+       SHAREDESCBUF_EFF,
+       METADATA,
+       GTR,
+       STR,
+       OFIFO_SYNC,
+       MSGOUTSNOOP_ALT
+};
+
+/* Command flags */
+#define FLUSH1          BIT(0)
+#define LAST1           BIT(1)
+#define LAST2           BIT(2)
+#define IMMED           BIT(3)
+#define SGF             BIT(4)
+#define VLF             BIT(5)
+#define EXT             BIT(6)
+#define CONT            BIT(7)
+#define SEQ             BIT(8)
+#define AIDF           BIT(9)
+#define FLUSH2          BIT(10)
+#define CLASS1          BIT(11)
+#define CLASS2          BIT(12)
+#define BOTH            BIT(13)
+
+/**
+ * DCOPY - (AIOP only) command param is pointer to external memory
+ *
+ * CDMA must be used to transfer the key via DMA into Workspace Area.
+ * Valid only in combination with IMMED flag.
+ */
+#define DCOPY          BIT(30)
+
+#define COPY           BIT(31) /* command param is pointer (not immediate)
+                                * valid only in combination when IMMED
+                                */
+
+#define __COPY_MASK    (COPY | DCOPY)
+
+/* SEQ IN/OUT PTR Command specific flags */
+#define RBS             BIT(16)
+#define INL             BIT(17)
+#define PRE             BIT(18)
+#define RTO             BIT(19)
+#define RJD             BIT(20)
+#define SOP            BIT(21)
+#define RST            BIT(22)
+#define EWS            BIT(23)
+
+#define ENC             BIT(14)        /* Encrypted Key */
+#define EKT             BIT(15)        /* AES CCM Encryption (default is
+                                * AES ECB Encryption)
+                                */
+#define TK              BIT(16)        /* Trusted Descriptor Key (default is
+                                * Job Descriptor Key)
+                                */
+#define NWB             BIT(17)        /* No Write Back Key */
+#define PTS             BIT(18)        /* Plaintext Store */
+
+/* HEADER Command specific flags */
+#define RIF             BIT(16)
+#define DNR             BIT(17)
+#define CIF             BIT(18)
+#define PD              BIT(19)
+#define RSMS            BIT(20)
+#define TD              BIT(21)
+#define MTD             BIT(22)
+#define REO             BIT(23)
+#define SHR             BIT(24)
+#define SC             BIT(25)
+/* Extended HEADER specific flags */
+#define DSV            BIT(7)
+#define DSEL_MASK      0x00000007      /* DECO Select */
+#define FTD            BIT(8)
+
+/* JUMP Command specific flags */
+#define NIFP            BIT(20)
+#define NIP             BIT(21)
+#define NOP             BIT(22)
+#define NCP             BIT(23)
+#define CALM            BIT(24)
+
+#define MATH_Z          BIT(25)
+#define MATH_N          BIT(26)
+#define MATH_NV         BIT(27)
+#define MATH_C          BIT(28)
+#define PK_0            BIT(29)
+#define PK_GCD_1        BIT(30)
+#define PK_PRIME        BIT(31)
+#define SELF            BIT(0)
+#define SHRD            BIT(1)
+#define JQP             BIT(2)
+
+/* NFIFOADD specific flags */
+#define PAD_ZERO        BIT(16)
+#define PAD_NONZERO     BIT(17)
+#define PAD_INCREMENT   BIT(18)
+#define PAD_RANDOM      BIT(19)
+#define PAD_ZERO_N1     BIT(20)
+#define PAD_NONZERO_0   BIT(21)
+#define PAD_N1          BIT(23)
+#define PAD_NONZERO_N   BIT(24)
+#define OC              BIT(25)
+#define BM              BIT(26)
+#define PR              BIT(27)
+#define PS              BIT(28)
+#define BP              BIT(29)
+
+/* MOVE Command specific flags */
+#define WAITCOMP        BIT(16)
+#define SIZE_WORD      BIT(17)
+#define SIZE_BYTE      BIT(18)
+#define SIZE_DWORD     BIT(19)
+
+/* MATH command specific flags */
+#define IFB         MATH_IFB
+#define NFU         MATH_NFU
+#define STL         MATH_STL
+#define SSEL        MATH_SSEL
+#define SWP         MATH_SWP
+#define IMMED2      BIT(31)
+
+/**
+ * struct program - descriptor buffer management structure
+ * @current_pc:        current offset in descriptor
+ * @current_instruction: current instruction in descriptor
+ * @first_error_pc: offset of the first error in descriptor
+ * @start_pc: start offset in descriptor buffer
+ * @buffer: buffer carrying descriptor
+ * @shrhdr: shared descriptor header
+ * @jobhdr: job descriptor header
+ * @ps: pointer fields size; if ps is true, pointers will be 36bits in
+ *      length; if ps is false, pointers will be 32bits in length
+ * @bswap: if true, perform byte swap on a 4-byte boundary
+ */
+struct program {
+       unsigned int current_pc;
+       unsigned int current_instruction;
+       unsigned int first_error_pc;
+       unsigned int start_pc;
+       uint32_t *buffer;
+       uint32_t *shrhdr;
+       uint32_t *jobhdr;
+       bool ps;
+       bool bswap;
+};
+
+static inline void
+rta_program_cntxt_init(struct program *program,
+                      uint32_t *buffer, unsigned int offset)
+{
+       program->current_pc = 0;
+       program->current_instruction = 0;
+       program->first_error_pc = 0;
+       program->start_pc = offset;
+       program->buffer = buffer;
+       program->shrhdr = NULL;
+       program->jobhdr = NULL;
+       program->ps = false;
+       program->bswap = false;
+}
+
+static inline int
+rta_program_finalize(struct program *program)
+{
+       /* Descriptor is usually not allowed to go beyond 64 words size */
+       if (program->current_pc > MAX_CAAM_DESCSIZE)
+               pr_warn("Descriptor Size exceeded max limit of 64 words\n");
+
+       /* Descriptor is erroneous */
+       if (program->first_error_pc) {
+               pr_err("Descriptor creation error\n");
+               return -EINVAL;
+       }
+
+       /* Update descriptor length in shared and job descriptor headers */
+       if (program->shrhdr != NULL)
+               *program->shrhdr |= program->bswap ?
+                                       swab32(program->current_pc) :
+                                       program->current_pc;
+       else if (program->jobhdr != NULL)
+               *program->jobhdr |= program->bswap ?
+                                       swab32(program->current_pc) :
+                                       program->current_pc;
+
+       return (int)program->current_pc;
+}
+
+static inline unsigned int
+rta_program_set_36bit_addr(struct program *program)
+{
+       program->ps = true;
+       return program->current_pc;
+}
+
+static inline unsigned int
+rta_program_set_bswap(struct program *program)
+{
+       program->bswap = true;
+       return program->current_pc;
+}
+
+static inline void
+__rta_out32(struct program *program, uint32_t val)
+{
+       program->buffer[program->current_pc] = program->bswap ?
+                                               swab32(val) : val;
+       program->current_pc++;
+}
+
+static inline void
+__rta_out_be32(struct program *program, uint32_t val)
+{
+       program->buffer[program->current_pc] = cpu_to_be32(val);
+       program->current_pc++;
+}
+
+static inline void
+__rta_out_le32(struct program *program, uint32_t val)
+{
+       program->buffer[program->current_pc] = cpu_to_le32(val);
+       program->current_pc++;
+}
+
+static inline void
+__rta_out64(struct program *program, bool is_ext, uint64_t val)
+{
+       if (is_ext) {
+               /*
+                * Since we are guaranteed only a 4-byte alignment in the
+                * descriptor buffer, we have to do 2 x 32-bit (word) writes.
+                * For the order of the 2 words to be correct, we need to
+                * take into account the endianness of the CPU.
+                */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+               __rta_out32(program, program->bswap ? lower_32_bits(val) :
+                                                     upper_32_bits(val));
+
+               __rta_out32(program, program->bswap ? upper_32_bits(val) :
+                                                     lower_32_bits(val));
+#else
+               __rta_out32(program, program->bswap ? upper_32_bits(val) :
+                                                     lower_32_bits(val));
+
+               __rta_out32(program, program->bswap ? lower_32_bits(val) :
+                                                     upper_32_bits(val));
+#endif
+       } else {
+               __rta_out32(program, lower_32_bits(val));
+       }
+}
+
+static inline unsigned int
+rta_word(struct program *program, uint32_t val)
+{
+       unsigned int start_pc = program->current_pc;
+
+       __rta_out32(program, val);
+
+       return start_pc;
+}
+
+static inline unsigned int
+rta_dword(struct program *program, uint64_t val)
+{
+       unsigned int start_pc = program->current_pc;
+
+       __rta_out64(program, true, val);
+
+       return start_pc;
+}
+
+static inline uint32_t
+inline_flags(enum rta_data_type data_type)
+{
+       switch (data_type) {
+       case RTA_DATA_PTR:
+               return 0;
+       case RTA_DATA_IMM:
+               return IMMED | COPY;
+       case RTA_DATA_IMM_DMA:
+               return IMMED | DCOPY;
+       default:
+               /* warn and default to RTA_DATA_PTR */
+               pr_warn("RTA: defaulting to RTA_DATA_PTR parameter type\n");
+               return 0;
+       }
+}
+
+static inline unsigned int
+rta_copy_data(struct program *program, uint8_t *data, unsigned int length)
+{
+       unsigned int i;
+       unsigned int start_pc = program->current_pc;
+       uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
+
+       for (i = 0; i < length; i++)
+               *tmp++ = data[i];
+       program->current_pc += (length + 3) / 4;
+
+       return start_pc;
+}
+
+#if defined(__EWL__) && defined(AIOP)
+static inline void
+__rta_dma_data(void *ws_dst, uint64_t ext_address, uint16_t size)
+{ cdma_read(ws_dst, ext_address, size); }
+#else
+static inline void
+__rta_dma_data(void *ws_dst __maybe_unused,
+              uint64_t ext_address __maybe_unused,
+              uint16_t size __maybe_unused)
+{ pr_warn("RTA: DCOPY not supported, DMA will be skipped\n"); }
+#endif /* defined(__EWL__) && defined(AIOP) */
+
+static inline void
+__rta_inline_data(struct program *program, uint64_t data,
+                 uint32_t copy_data, uint32_t length)
+{
+       if (!copy_data) {
+               __rta_out64(program, length > 4, data);
+       } else if (copy_data & COPY) {
+               uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
+               uint32_t i;
+
+               for (i = 0; i < length; i++)
+                       *tmp++ = ((uint8_t *)(uintptr_t)data)[i];
+               program->current_pc += ((length + 3) / 4);
+       } else if (copy_data & DCOPY) {
+               __rta_dma_data(&program->buffer[program->current_pc], data,
+                              (uint16_t)length);
+               program->current_pc += ((length + 3) / 4);
+       }
+}
+
+static inline unsigned int
+rta_desc_len(uint32_t *buffer)
+{
+       if ((*buffer & CMD_MASK) == CMD_DESC_HDR)
+               return *buffer & HDR_DESCLEN_MASK;
+       else
+               return *buffer & HDR_DESCLEN_SHR_MASK;
+}
+
+static inline unsigned int
+rta_desc_bytes(uint32_t *buffer)
+{
+       return (unsigned int)(rta_desc_len(buffer) * CAAM_CMD_SZ);
+}
+
+/**
+ * split_key_len - Compute MDHA split key length for a given algorithm
+ * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* or
+ *        OP_PCLID_DKP_* - MD5, SHA1, SHA224, SHA256, SHA384, SHA512.
+ *
+ * Return: MDHA split key length
+ */
+static inline uint32_t
+split_key_len(uint32_t hash)
+{
+       /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
+       static const uint8_t mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
+       uint32_t idx;
+
+       idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT;
+
+       return (uint32_t)(mdpadlen[idx] * 2);
+}
+
+/**
+ * split_key_pad_len - Compute MDHA split key pad length for a given algorithm
+ * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
+ *        SHA224, SHA384, SHA512.
+ *
+ * Return: MDHA split key pad length
+ */
+static inline uint32_t
+split_key_pad_len(uint32_t hash)
+{
+       return ALIGN(split_key_len(hash), 16);
+}
+
+static inline unsigned int
+rta_set_label(struct program *program)
+{
+       return program->current_pc + program->start_pc;
+}
+
+static inline int
+rta_patch_move(struct program *program, int line, unsigned int new_ref)
+{
+       uint32_t opcode;
+       bool bswap = program->bswap;
+
+       if (line < 0)
+               return -EINVAL;
+
+       opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
+
+       opcode &= (uint32_t)~MOVE_OFFSET_MASK;
+       opcode |= (new_ref << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
+       program->buffer[line] = bswap ? swab32(opcode) : opcode;
+
+       return 0;
+}
+
+static inline int
+rta_patch_jmp(struct program *program, int line, unsigned int new_ref)
+{
+       uint32_t opcode;
+       bool bswap = program->bswap;
+
+       if (line < 0)
+               return -EINVAL;
+
+       opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
+
+       opcode &= (uint32_t)~JUMP_OFFSET_MASK;
+       opcode |= (new_ref - (line + program->start_pc)) & JUMP_OFFSET_MASK;
+       program->buffer[line] = bswap ? swab32(opcode) : opcode;
+
+       return 0;
+}
+
+static inline int
+rta_patch_header(struct program *program, int line, unsigned int new_ref)
+{
+       uint32_t opcode;
+       bool bswap = program->bswap;
+
+       if (line < 0)
+               return -EINVAL;
+
+       opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
+
+       opcode &= (uint32_t)~HDR_START_IDX_MASK;
+       opcode |= (new_ref << HDR_START_IDX_SHIFT) & HDR_START_IDX_MASK;
+       program->buffer[line] = bswap ? swab32(opcode) : opcode;
+
+       return 0;
+}
+
+static inline int
+rta_patch_load(struct program *program, int line, unsigned int new_ref)
+{
+       uint32_t opcode;
+       bool bswap = program->bswap;
+
+       if (line < 0)
+               return -EINVAL;
+
+       opcode = (bswap ? swab32(program->buffer[line]) :
+                        program->buffer[line]) & (uint32_t)~LDST_OFFSET_MASK;
+
+       if (opcode & (LDST_SRCDST_WORD_DESCBUF | LDST_CLASS_DECO))
+               opcode |= (new_ref << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
+       else
+               opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
+                         LDST_OFFSET_MASK;
+
+       program->buffer[line] = bswap ? swab32(opcode) : opcode;
+
+       return 0;
+}
+
+static inline int
+rta_patch_store(struct program *program, int line, unsigned int new_ref)
+{
+       uint32_t opcode;
+       bool bswap = program->bswap;
+
+       if (line < 0)
+               return -EINVAL;
+
+       opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
+
+       opcode &= (uint32_t)~LDST_OFFSET_MASK;
+
+       switch (opcode & LDST_SRCDST_MASK) {
+       case LDST_SRCDST_WORD_DESCBUF:
+       case LDST_SRCDST_WORD_DESCBUF_JOB:
+       case LDST_SRCDST_WORD_DESCBUF_SHARED:
+       case LDST_SRCDST_WORD_DESCBUF_JOB_WE:
+       case LDST_SRCDST_WORD_DESCBUF_SHARED_WE:
+               opcode |= ((new_ref) << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
+               break;
+       default:
+               opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
+                         LDST_OFFSET_MASK;
+       }
+
+       program->buffer[line] = bswap ? swab32(opcode) : opcode;
+
+       return 0;
+}
+
+static inline int
+rta_patch_raw(struct program *program, int line, unsigned int mask,
+             unsigned int new_val)
+{
+       uint32_t opcode;
+       bool bswap = program->bswap;
+
+       if (line < 0)
+               return -EINVAL;
+
+       opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
+
+       opcode &= (uint32_t)~mask;
+       opcode |= new_val & mask;
+       program->buffer[line] = bswap ? swab32(opcode) : opcode;
+
+       return 0;
+}
+
+static inline int
+__rta_map_opcode(uint32_t name, const uint32_t (*map_table)[2],
+                unsigned int num_of_entries, uint32_t *val)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_of_entries; i++)
+               if (map_table[i][0] == name) {
+                       *val = map_table[i][1];
+                       return 0;
+               }
+
+       return -EINVAL;
+}
+
+static inline void
+__rta_map_flags(uint32_t flags, const uint32_t (*flags_table)[2],
+               unsigned int num_of_entries, uint32_t *opcode)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_of_entries; i++) {
+               if (flags_table[i][0] & flags)
+                       *opcode |= flags_table[i][1];
+       }
+}
+
+#endif /* __RTA_SEC_RUN_TIME_ASM_H__ */