LCOV - code coverage report
Current view: top level - drivers/common/dpaax/caamflib/rta - move_cmd.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 142 0.0 %
Date: 2024-04-01 19:00:53 Functions: 0 2 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 98 0.0 %

           Branch data     Line data    Source code
       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_MOVE_CMD_H__
       8                 :            : #define __RTA_MOVE_CMD_H__
       9                 :            : 
      10                 :            : #define MOVE_SET_AUX_SRC        0x01
      11                 :            : #define MOVE_SET_AUX_DST        0x02
      12                 :            : #define MOVE_SET_AUX_LS         0x03
      13                 :            : #define MOVE_SET_LEN_16b        0x04
      14                 :            : 
      15                 :            : #define MOVE_SET_AUX_MATH       0x10
      16                 :            : #define MOVE_SET_AUX_MATH_SRC   (MOVE_SET_AUX_SRC | MOVE_SET_AUX_MATH)
      17                 :            : #define MOVE_SET_AUX_MATH_DST   (MOVE_SET_AUX_DST | MOVE_SET_AUX_MATH)
      18                 :            : 
      19                 :            : #define MASK_16b  0xFF
      20                 :            : 
      21                 :            : /* MOVE command type */
      22                 :            : #define __MOVE          1
      23                 :            : #define __MOVEB         2
      24                 :            : #define __MOVEDW        3
      25                 :            : 
      26                 :            : extern enum rta_sec_era rta_sec_era;
      27                 :            : 
      28                 :            : static const uint32_t move_src_table[][2] = {
      29                 :            : /*1*/   { CONTEXT1, MOVE_SRC_CLASS1CTX },
      30                 :            :         { CONTEXT2, MOVE_SRC_CLASS2CTX },
      31                 :            :         { OFIFO,    MOVE_SRC_OUTFIFO },
      32                 :            :         { DESCBUF,  MOVE_SRC_DESCBUF },
      33                 :            :         { MATH0,    MOVE_SRC_MATH0 },
      34                 :            :         { MATH1,    MOVE_SRC_MATH1 },
      35                 :            :         { MATH2,    MOVE_SRC_MATH2 },
      36                 :            :         { MATH3,    MOVE_SRC_MATH3 },
      37                 :            : /*9*/   { IFIFOABD, MOVE_SRC_INFIFO },
      38                 :            :         { IFIFOAB1, MOVE_SRC_INFIFO_CL | MOVE_AUX_LS },
      39                 :            :         { IFIFOAB2, MOVE_SRC_INFIFO_CL },
      40                 :            : /*12*/  { ABD,      MOVE_SRC_INFIFO_NO_NFIFO },
      41                 :            :         { AB1,      MOVE_SRC_INFIFO_NO_NFIFO | MOVE_AUX_LS },
      42                 :            :         { AB2,      MOVE_SRC_INFIFO_NO_NFIFO | MOVE_AUX_MS }
      43                 :            : };
      44                 :            : 
      45                 :            : /* Allowed MOVE / MOVE_LEN sources for each SEC Era.
      46                 :            :  * Values represent the number of entries from move_src_table[] that are
      47                 :            :  * supported.
      48                 :            :  */
      49                 :            : static const unsigned int move_src_table_sz[] = {9, 11, 14, 14, 14, 14, 14, 14,
      50                 :            :                                                  14, 14};
      51                 :            : 
      52                 :            : static const uint32_t move_dst_table[][2] = {
      53                 :            : /*1*/   { CONTEXT1,  MOVE_DEST_CLASS1CTX },
      54                 :            :         { CONTEXT2,  MOVE_DEST_CLASS2CTX },
      55                 :            :         { OFIFO,     MOVE_DEST_OUTFIFO },
      56                 :            :         { DESCBUF,   MOVE_DEST_DESCBUF },
      57                 :            :         { MATH0,     MOVE_DEST_MATH0 },
      58                 :            :         { MATH1,     MOVE_DEST_MATH1 },
      59                 :            :         { MATH2,     MOVE_DEST_MATH2 },
      60                 :            :         { MATH3,     MOVE_DEST_MATH3 },
      61                 :            :         { IFIFOAB1,  MOVE_DEST_CLASS1INFIFO },
      62                 :            :         { IFIFOAB2,  MOVE_DEST_CLASS2INFIFO },
      63                 :            :         { PKA,       MOVE_DEST_PK_A },
      64                 :            :         { KEY1,      MOVE_DEST_CLASS1KEY },
      65                 :            :         { KEY2,      MOVE_DEST_CLASS2KEY },
      66                 :            : /*14*/  { IFIFO,     MOVE_DEST_INFIFO },
      67                 :            : /*15*/  { ALTSOURCE,  MOVE_DEST_ALTSOURCE}
      68                 :            : };
      69                 :            : 
      70                 :            : /* Allowed MOVE / MOVE_LEN destinations for each SEC Era.
      71                 :            :  * Values represent the number of entries from move_dst_table[] that are
      72                 :            :  * supported.
      73                 :            :  */
      74                 :            : static const
      75                 :            : unsigned int move_dst_table_sz[] = {13, 14, 14, 15, 15, 15, 15, 15, 15, 15};
      76                 :            : 
      77                 :            : static inline int
      78                 :            : set_move_offset(struct program *program __maybe_unused,
      79                 :            :                 uint64_t src, uint16_t src_offset,
      80                 :            :                 uint64_t dst, uint16_t dst_offset,
      81                 :            :                 uint16_t *offset, uint16_t *opt);
      82                 :            : 
      83                 :            : static inline int
      84                 :            : math_offset(uint16_t offset);
      85                 :            : 
      86                 :            : static inline int
      87                 :          0 : rta_move(struct program *program, int cmd_type, uint64_t src,
      88                 :            :          uint16_t src_offset, uint64_t dst,
      89                 :            :          uint16_t dst_offset, uint32_t length, uint32_t flags)
      90                 :            : {
      91                 :            :         uint32_t opcode = 0;
      92                 :          0 :         uint16_t offset = 0, opt = 0;
      93                 :            :         uint32_t val = 0;
      94                 :            :         int ret = -EINVAL;
      95                 :            :         bool is_move_len_cmd = false;
      96                 :          0 :         unsigned int start_pc = program->current_pc;
      97                 :            : 
      98                 :            :         /* write command type */
      99         [ #  # ]:          0 :         if (cmd_type == __MOVEB) {
     100                 :            :                 opcode = CMD_MOVEB;
     101         [ #  # ]:          0 :         } else if (cmd_type == __MOVEDW) {
     102                 :            :                 opcode = CMD_MOVEDW;
     103         [ #  # ]:          0 :         } else if (!(flags & IMMED)) {
     104                 :          0 :                 if ((length != MATH0) && (length != MATH1) &&
     105         [ #  # ]:          0 :                     (length != MATH2) && (length != MATH3)) {
     106                 :          0 :                         pr_err("MOVE: MOVE_LEN length must be MATH[0-3]. SEC PC: %d; Instr: %d\n",
     107                 :            :                                program->current_pc,
     108                 :            :                                program->current_instruction);
     109                 :          0 :                         goto err;
     110                 :            :                 }
     111                 :            : 
     112                 :            :                 opcode = CMD_MOVE_LEN;
     113                 :            :                 is_move_len_cmd = true;
     114                 :            :         } else {
     115                 :            :                 opcode = CMD_MOVE;
     116                 :            :         }
     117                 :            : 
     118                 :            :         /* write offset first, to check for invalid combinations or incorrect
     119                 :            :          * offset values sooner; decide which offset should be here
     120                 :            :          * (src or dst)
     121                 :            :          */
     122                 :          0 :         ret = set_move_offset(program, src, src_offset, dst, dst_offset,
     123                 :            :                               &offset, &opt);
     124         [ #  # ]:          0 :         if (ret < 0)
     125                 :          0 :                 goto err;
     126                 :            : 
     127                 :          0 :         opcode |= (offset << MOVE_OFFSET_SHIFT) & MOVE_OFFSET_MASK;
     128                 :            : 
     129                 :            :         /* set AUX field if required */
     130         [ #  # ]:          0 :         if (opt == MOVE_SET_AUX_SRC) {
     131                 :          0 :                 opcode |= ((src_offset / 16) << MOVE_AUX_SHIFT) & MOVE_AUX_MASK;
     132         [ #  # ]:          0 :         } else if (opt == MOVE_SET_AUX_DST) {
     133                 :          0 :                 opcode |= ((dst_offset / 16) << MOVE_AUX_SHIFT) & MOVE_AUX_MASK;
     134         [ #  # ]:          0 :         } else if (opt == MOVE_SET_AUX_LS) {
     135                 :          0 :                 opcode |= MOVE_AUX_LS;
     136         [ #  # ]:          0 :         } else if (opt & MOVE_SET_AUX_MATH) {
     137         [ #  # ]:          0 :                 if (opt & MOVE_SET_AUX_SRC)
     138                 :          0 :                         offset = src_offset;
     139                 :            :                 else
     140                 :          0 :                         offset = dst_offset;
     141                 :            : 
     142         [ #  # ]:          0 :                 ret = math_offset(offset);
     143         [ #  # ]:          0 :                 if (ret < 0) {
     144                 :          0 :                         pr_err("MOVE: Invalid offset in MATH register. SEC PC: %d; Instr: %d\n",
     145                 :            :                                program->current_pc,
     146                 :            :                                program->current_instruction);
     147                 :          0 :                         goto err;
     148                 :            :                 }
     149                 :            : 
     150                 :          0 :                 opcode |= (uint32_t)ret;
     151                 :            :         }
     152                 :            : 
     153                 :            :         /* write source field */
     154                 :          0 :         ret = __rta_map_opcode((uint32_t)src, move_src_table,
     155                 :          0 :                                move_src_table_sz[rta_sec_era], &val);
     156                 :            :         if (ret < 0) {
     157                 :          0 :                 pr_err("MOVE: Invalid SRC. SEC PC: %d; Instr: %d\n",
     158                 :            :                        program->current_pc, program->current_instruction);
     159                 :          0 :                 goto err;
     160                 :            :         }
     161                 :          0 :         opcode |= val;
     162                 :            : 
     163                 :            :         /* write destination field */
     164                 :          0 :         ret = __rta_map_opcode((uint32_t)dst, move_dst_table,
     165                 :          0 :                                move_dst_table_sz[rta_sec_era], &val);
     166                 :            :         if (ret < 0) {
     167                 :          0 :                 pr_err("MOVE: Invalid DST. SEC PC: %d; Instr: %d\n",
     168                 :            :                        program->current_pc, program->current_instruction);
     169                 :          0 :                 goto err;
     170                 :            :         }
     171                 :          0 :         opcode |= val;
     172                 :            : 
     173                 :            :         /* write flags */
     174         [ #  # ]:          0 :         if (flags & (FLUSH1 | FLUSH2))
     175                 :          0 :                 opcode |= MOVE_AUX_MS;
     176         [ #  # ]:          0 :         if (flags & (LAST2 | LAST1))
     177                 :          0 :                 opcode |= MOVE_AUX_LS;
     178         [ #  # ]:          0 :         if (flags & WAITCOMP)
     179                 :          0 :                 opcode |= MOVE_WAITCOMP;
     180                 :            : 
     181         [ #  # ]:          0 :         if (!is_move_len_cmd) {
     182                 :            :                 /* write length */
     183         [ #  # ]:          0 :                 if (opt == MOVE_SET_LEN_16b)
     184                 :          0 :                         opcode |= (length & (MOVE_OFFSET_MASK | MOVE_LEN_MASK));
     185                 :            :                 else
     186                 :          0 :                         opcode |= (length & MOVE_LEN_MASK);
     187                 :            :         } else {
     188                 :            :                 /* write mrsel */
     189   [ #  #  #  # ]:          0 :                 switch (length) {
     190                 :            :                 case (MATH0):
     191                 :            :                         /*
     192                 :            :                          * opcode |= MOVELEN_MRSEL_MATH0;
     193                 :            :                          * MOVELEN_MRSEL_MATH0 is 0
     194                 :            :                          */
     195                 :            :                         break;
     196                 :          0 :                 case (MATH1):
     197                 :          0 :                         opcode |= MOVELEN_MRSEL_MATH1;
     198                 :          0 :                         break;
     199                 :          0 :                 case (MATH2):
     200                 :          0 :                         opcode |= MOVELEN_MRSEL_MATH2;
     201                 :          0 :                         break;
     202                 :          0 :                 case (MATH3):
     203                 :          0 :                         opcode |= MOVELEN_MRSEL_MATH3;
     204                 :          0 :                         break;
     205                 :            :                 }
     206                 :            : 
     207                 :            :                 /* write size */
     208         [ #  # ]:          0 :                 if (rta_sec_era >= RTA_SEC_ERA_7) {
     209         [ #  # ]:          0 :                         if (flags & SIZE_WORD)
     210                 :          0 :                                 opcode |= MOVELEN_SIZE_WORD;
     211         [ #  # ]:          0 :                         else if (flags & SIZE_BYTE)
     212                 :          0 :                                 opcode |= MOVELEN_SIZE_BYTE;
     213         [ #  # ]:          0 :                         else if (flags & SIZE_DWORD)
     214                 :          0 :                                 opcode |= MOVELEN_SIZE_DWORD;
     215                 :            :                 }
     216                 :            :         }
     217                 :            : 
     218                 :          0 :         __rta_out32(program, opcode);
     219                 :          0 :         program->current_instruction++;
     220                 :            : 
     221                 :          0 :         return (int)start_pc;
     222                 :            : 
     223                 :          0 :  err:
     224                 :          0 :         program->first_error_pc = start_pc;
     225                 :          0 :         program->current_instruction++;
     226                 :          0 :         return ret;
     227                 :            : }
     228                 :            : 
     229                 :            : static inline int
     230                 :          0 : set_move_offset(struct program *program __maybe_unused,
     231                 :            :                 uint64_t src, uint16_t src_offset,
     232                 :            :                 uint64_t dst, uint16_t dst_offset,
     233                 :            :                 uint16_t *offset, uint16_t *opt)
     234                 :            : {
     235   [ #  #  #  #  :          0 :         switch (src) {
                   #  # ]
     236                 :          0 :         case (CONTEXT1):
     237                 :            :         case (CONTEXT2):
     238         [ #  # ]:          0 :                 if (dst == DESCBUF) {
     239                 :          0 :                         *opt = MOVE_SET_AUX_SRC;
     240                 :          0 :                         *offset = dst_offset;
     241         [ #  # ]:          0 :                 } else if ((dst == KEY1) || (dst == KEY2)) {
     242         [ #  # ]:          0 :                         if ((src_offset) && (dst_offset)) {
     243                 :          0 :                                 pr_err("MOVE: Bad offset. SEC PC: %d; Instr: %d\n",
     244                 :            :                                        program->current_pc,
     245                 :            :                                        program->current_instruction);
     246                 :          0 :                                 goto err;
     247                 :            :                         }
     248         [ #  # ]:          0 :                         if (dst_offset) {
     249                 :          0 :                                 *opt = MOVE_SET_AUX_LS;
     250                 :          0 :                                 *offset = dst_offset;
     251                 :            :                         } else {
     252                 :          0 :                                 *offset = src_offset;
     253                 :            :                         }
     254                 :            :                 } else {
     255                 :          0 :                         if ((dst == MATH0) || (dst == MATH1) ||
     256         [ #  # ]:          0 :                             (dst == MATH2) || (dst == MATH3)) {
     257                 :          0 :                                 *opt = MOVE_SET_AUX_MATH_DST;
     258   [ #  #  #  # ]:          0 :                         } else if (((dst == OFIFO) || (dst == ALTSOURCE)) &&
     259                 :            :                             (src_offset % 4)) {
     260                 :          0 :                                 pr_err("MOVE: Bad offset alignment. SEC PC: %d; Instr: %d\n",
     261                 :            :                                        program->current_pc,
     262                 :            :                                        program->current_instruction);
     263                 :          0 :                                 goto err;
     264                 :            :                         }
     265                 :            : 
     266                 :          0 :                         *offset = src_offset;
     267                 :            :                 }
     268                 :            :                 break;
     269                 :            : 
     270                 :          0 :         case (OFIFO):
     271         [ #  # ]:          0 :                 if (dst == OFIFO) {
     272                 :          0 :                         pr_err("MOVE: Invalid DST. SEC PC: %d; Instr: %d\n",
     273                 :            :                                program->current_pc,
     274                 :            :                                program->current_instruction);
     275                 :          0 :                         goto err;
     276                 :            :                 }
     277                 :          0 :                 if (((dst == IFIFOAB1) || (dst == IFIFOAB2) ||
     278         [ #  # ]:          0 :                      (dst == IFIFO) || (dst == PKA)) &&
     279         [ #  # ]:          0 :                     (src_offset || dst_offset)) {
     280                 :          0 :                         pr_err("MOVE: Offset should be zero. SEC PC: %d; Instr: %d\n",
     281                 :            :                                program->current_pc,
     282                 :            :                                program->current_instruction);
     283                 :          0 :                         goto err;
     284                 :            :                 }
     285                 :          0 :                 *offset = dst_offset;
     286                 :          0 :                 break;
     287                 :            : 
     288                 :          0 :         case (DESCBUF):
     289         [ #  # ]:          0 :                 if ((dst == CONTEXT1) || (dst == CONTEXT2)) {
     290                 :          0 :                         *opt = MOVE_SET_AUX_DST;
     291                 :          0 :                 } else if ((dst == MATH0) || (dst == MATH1) ||
     292         [ #  # ]:          0 :                            (dst == MATH2) || (dst == MATH3)) {
     293                 :          0 :                         *opt = MOVE_SET_AUX_MATH_DST;
     294         [ #  # ]:          0 :                 } else if (dst == DESCBUF) {
     295                 :          0 :                         pr_err("MOVE: Invalid DST. SEC PC: %d; Instr: %d\n",
     296                 :            :                                program->current_pc,
     297                 :            :                                program->current_instruction);
     298                 :          0 :                         goto err;
     299   [ #  #  #  # ]:          0 :                 } else if (((dst == OFIFO) || (dst == ALTSOURCE)) &&
     300                 :            :                     (src_offset % 4)) {
     301                 :          0 :                         pr_err("MOVE: Invalid offset alignment. SEC PC: %d; Instr %d\n",
     302                 :            :                                program->current_pc,
     303                 :            :                                program->current_instruction);
     304                 :          0 :                         goto err;
     305                 :            :                 }
     306                 :            : 
     307                 :          0 :                 *offset = src_offset;
     308                 :          0 :                 break;
     309                 :            : 
     310                 :          0 :         case (MATH0):
     311                 :            :         case (MATH1):
     312                 :            :         case (MATH2):
     313                 :            :         case (MATH3):
     314         [ #  # ]:          0 :                 if ((dst == OFIFO) || (dst == ALTSOURCE)) {
     315         [ #  # ]:          0 :                         if (src_offset % 4) {
     316                 :          0 :                                 pr_err("MOVE: Bad offset alignment. SEC PC: %d; Instr: %d\n",
     317                 :            :                                        program->current_pc,
     318                 :            :                                        program->current_instruction);
     319                 :          0 :                                 goto err;
     320                 :            :                         }
     321                 :          0 :                         *offset = src_offset;
     322                 :          0 :                 } else if ((dst == IFIFOAB1) || (dst == IFIFOAB2) ||
     323         [ #  # ]:          0 :                            (dst == IFIFO) || (dst == PKA)) {
     324                 :          0 :                         *offset = src_offset;
     325                 :            :                 } else {
     326                 :          0 :                         *offset = dst_offset;
     327                 :            : 
     328                 :            :                         /*
     329                 :            :                          * This condition is basically the negation of:
     330                 :            :                          * dst in { CONTEXT[1-2], MATH[0-3] }
     331                 :            :                          */
     332         [ #  # ]:          0 :                         if ((dst != KEY1) && (dst != KEY2))
     333                 :          0 :                                 *opt = MOVE_SET_AUX_MATH_SRC;
     334                 :            :                 }
     335                 :            :                 break;
     336                 :            : 
     337                 :          0 :         case (IFIFOABD):
     338                 :            :         case (IFIFOAB1):
     339                 :            :         case (IFIFOAB2):
     340                 :            :         case (ABD):
     341                 :            :         case (AB1):
     342                 :            :         case (AB2):
     343                 :          0 :                 if ((dst == IFIFOAB1) || (dst == IFIFOAB2) ||
     344   [ #  #  #  # ]:          0 :                     (dst == IFIFO) || (dst == PKA) || (dst == ALTSOURCE)) {
     345                 :          0 :                         pr_err("MOVE: Bad DST. SEC PC: %d; Instr: %d\n",
     346                 :            :                                program->current_pc,
     347                 :            :                                program->current_instruction);
     348                 :          0 :                         goto err;
     349                 :            :                 } else {
     350         [ #  # ]:          0 :                         if (dst == OFIFO) {
     351                 :          0 :                                 *opt = MOVE_SET_LEN_16b;
     352                 :            :                         } else {
     353         [ #  # ]:          0 :                                 if (dst_offset % 4) {
     354                 :          0 :                                         pr_err("MOVE: Bad offset alignment. SEC PC: %d; Instr: %d\n",
     355                 :            :                                                program->current_pc,
     356                 :            :                                                program->current_instruction);
     357                 :          0 :                                         goto err;
     358                 :            :                                 }
     359                 :          0 :                                 *offset = dst_offset;
     360                 :            :                         }
     361                 :            :                 }
     362                 :            :                 break;
     363                 :            :         default:
     364                 :            :                 break;
     365                 :            :         }
     366                 :            : 
     367                 :            :         return 0;
     368                 :            :  err:
     369                 :            :         return -EINVAL;
     370                 :            : }
     371                 :            : 
     372                 :            : static inline int
     373                 :            : math_offset(uint16_t offset)
     374                 :            : {
     375                 :            :         switch (offset) {
     376                 :            :         case 0:
     377                 :            :                 return 0;
     378                 :            :         case 4:
     379                 :            :                 return MOVE_AUX_LS;
     380                 :            :         case 6:
     381                 :            :                 return MOVE_AUX_MS;
     382                 :            :         case 7:
     383                 :            :                 return MOVE_AUX_LS | MOVE_AUX_MS;
     384                 :            :         }
     385                 :            : 
     386                 :            :         return -EINVAL;
     387                 :            : }
     388                 :            : 
     389                 :            : #endif /* __RTA_MOVE_CMD_H__ */

Generated by: LCOV version 1.14