dpdk/drivers/common/dpaax/caamflib/rta/load_cmd.h
<<
>>
Prefs
   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_LOAD_CMD_H__
   8#define __RTA_LOAD_CMD_H__
   9
  10extern enum rta_sec_era rta_sec_era;
  11
  12/* Allowed length and offset masks for each SEC Era in case DST = DCTRL */
  13static const uint32_t load_len_mask_allowed[] = {
  14        0x000000ee,
  15        0x000000fe,
  16        0x000000fe,
  17        0x000000fe,
  18        0x000000fe,
  19        0x000000fe,
  20        0x000000fe,
  21        0x000000fe,
  22        0x000000fe,
  23        0x000000fe
  24};
  25
  26static const uint32_t load_off_mask_allowed[] = {
  27        0x0000000f,
  28        0x000000ff,
  29        0x000000ff,
  30        0x000000ff,
  31        0x000000ff,
  32        0x000000ff,
  33        0x000000ff,
  34        0x000000ff,
  35        0x000000ff,
  36        0x000000ff
  37};
  38
  39#define IMM_MUST 0
  40#define IMM_CAN  1
  41#define IMM_NO   2
  42#define IMM_DSNM 3 /* it doesn't matter the src type */
  43
  44enum e_lenoff {
  45        LENOF_03,
  46        LENOF_4,
  47        LENOF_48,
  48        LENOF_448,
  49        LENOF_18,
  50        LENOF_32,
  51        LENOF_24,
  52        LENOF_16,
  53        LENOF_8,
  54        LENOF_128,
  55        LENOF_256,
  56        DSNM /* it doesn't matter the length/offset values */
  57};
  58
  59struct load_map {
  60        uint32_t dst;
  61        uint32_t dst_opcode;
  62        enum e_lenoff len_off;
  63        uint8_t imm_src;
  64
  65};
  66
  67static const struct load_map load_dst[] = {
  68/*1*/   { KEY1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
  69                   LENOF_4,   IMM_MUST },
  70        { KEY2SZ,  LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
  71                   LENOF_4,   IMM_MUST },
  72        { DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG,
  73                   LENOF_448, IMM_MUST },
  74        { DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG,
  75                   LENOF_448, IMM_MUST },
  76        { ICV1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
  77                   LENOF_4,   IMM_MUST },
  78        { ICV2SZ,  LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
  79                   LENOF_4,   IMM_MUST },
  80        { CCTRL,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CHACTRL,
  81                   LENOF_4,   IMM_MUST },
  82        { DCTRL,   LDST_CLASS_DECO | LDST_IMM | LDST_SRCDST_WORD_DECOCTRL,
  83                   DSNM,      IMM_DSNM },
  84        { ICTRL,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_IRQCTRL,
  85                   LENOF_4,   IMM_MUST },
  86        { DPOVRD,  LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_PCLOVRD,
  87                   LENOF_4,   IMM_MUST },
  88        { CLRW,    LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CLRW,
  89                   LENOF_4,   IMM_MUST },
  90        { AAD1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ,
  91                   LENOF_4,   IMM_MUST },
  92        { IV1SZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ,
  93                   LENOF_4,   IMM_MUST },
  94        { ALTDS1,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ALTDS_CLASS1,
  95                   LENOF_448, IMM_MUST },
  96        { PKASZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ,
  97                   LENOF_4,   IMM_MUST, },
  98        { PKBSZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ,
  99                   LENOF_4,   IMM_MUST },
 100        { PKNSZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ,
 101                   LENOF_4,   IMM_MUST },
 102        { PKESZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ,
 103                   LENOF_4,   IMM_MUST },
 104        { NFIFO,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_INFO_FIFO,
 105                   LENOF_48,  IMM_MUST },
 106        { IFIFO,   LDST_SRCDST_BYTE_INFIFO,  LENOF_18, IMM_MUST },
 107        { OFIFO,   LDST_SRCDST_BYTE_OUTFIFO, LENOF_18, IMM_MUST },
 108        { MATH0,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0,
 109                   LENOF_32,  IMM_CAN },
 110        { MATH1,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1,
 111                   LENOF_24,  IMM_CAN },
 112        { MATH2,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2,
 113                   LENOF_16,  IMM_CAN },
 114        { MATH3,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3,
 115                   LENOF_8,   IMM_CAN },
 116        { CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT,
 117                   LENOF_128, IMM_CAN },
 118        { CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT,
 119                   LENOF_128, IMM_CAN },
 120        { KEY1,    LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_KEY,
 121                   LENOF_32,  IMM_CAN },
 122        { KEY2,    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY,
 123                   LENOF_32,  IMM_CAN },
 124        { DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF,
 125                   LENOF_256,  IMM_NO },
 126        { DPID,    LDST_CLASS_DECO | LDST_SRCDST_WORD_PID,
 127                   LENOF_448, IMM_MUST },
 128/*32*/  { IDFNS,   LDST_SRCDST_WORD_IFNSR, LENOF_18,  IMM_MUST },
 129        { ODFNS,   LDST_SRCDST_WORD_OFNSR, LENOF_18,  IMM_MUST },
 130        { ALTSOURCE, LDST_SRCDST_BYTE_ALTSOURCE, LENOF_18,  IMM_MUST },
 131/*35*/  { NFIFO_SZL, LDST_SRCDST_WORD_INFO_FIFO_SZL, LENOF_48, IMM_MUST },
 132        { NFIFO_SZM, LDST_SRCDST_WORD_INFO_FIFO_SZM, LENOF_03, IMM_MUST },
 133        { NFIFO_L, LDST_SRCDST_WORD_INFO_FIFO_L, LENOF_48, IMM_MUST },
 134        { NFIFO_M, LDST_SRCDST_WORD_INFO_FIFO_M, LENOF_03, IMM_MUST },
 135        { SZL,     LDST_SRCDST_WORD_SZL, LENOF_48, IMM_MUST },
 136/*40*/  { SZM,     LDST_SRCDST_WORD_SZM, LENOF_03, IMM_MUST }
 137};
 138
 139/*
 140 * Allowed LOAD destinations for each SEC Era.
 141 * Values represent the number of entries from load_dst[] that are supported.
 142 */
 143static const unsigned int load_dst_sz[] = { 31, 34, 34, 40, 40,
 144                                            40, 40, 40, 40, 40};
 145
 146static inline int
 147load_check_len_offset(int pos, uint32_t length, uint32_t offset)
 148{
 149        if ((load_dst[pos].dst == DCTRL) &&
 150            ((length & ~load_len_mask_allowed[rta_sec_era]) ||
 151             (offset & ~load_off_mask_allowed[rta_sec_era])))
 152                goto err;
 153
 154        switch (load_dst[pos].len_off) {
 155        case (LENOF_03):
 156                if ((length > 3) || (offset))
 157                        goto err;
 158                break;
 159        case (LENOF_4):
 160                if ((length != 4) || (offset != 0))
 161                        goto err;
 162                break;
 163        case (LENOF_48):
 164                if (!(((length == 4) && (offset == 0)) ||
 165                      ((length == 8) && (offset == 0))))
 166                        goto err;
 167                break;
 168        case (LENOF_448):
 169                if (!(((length == 4) && (offset == 0)) ||
 170                      ((length == 4) && (offset == 4)) ||
 171                      ((length == 8) && (offset == 0))))
 172                        goto err;
 173                break;
 174        case (LENOF_18):
 175                if ((length < 1) || (length > 8) || (offset != 0))
 176                        goto err;
 177                break;
 178        case (LENOF_32):
 179                if ((length > 32) || (offset > 32) || ((offset + length) > 32))
 180                        goto err;
 181                break;
 182        case (LENOF_24):
 183                if ((length > 24) || (offset > 24) || ((offset + length) > 24))
 184                        goto err;
 185                break;
 186        case (LENOF_16):
 187                if ((length > 16) || (offset > 16) || ((offset + length) > 16))
 188                        goto err;
 189                break;
 190        case (LENOF_8):
 191                if ((length > 8) || (offset > 8) || ((offset + length) > 8))
 192                        goto err;
 193                break;
 194        case (LENOF_128):
 195                if ((length > 128) || (offset > 128) ||
 196                    ((offset + length) > 128))
 197                        goto err;
 198                break;
 199        case (LENOF_256):
 200                if ((length < 1) || (length > 256) || ((length + offset) > 256))
 201                        goto err;
 202                break;
 203        case (DSNM):
 204                break;
 205        default:
 206                goto err;
 207        }
 208
 209        return 0;
 210err:
 211        return -EINVAL;
 212}
 213
 214static inline int
 215rta_load(struct program *program, uint64_t src, uint64_t dst,
 216         uint32_t offset, uint32_t length, uint32_t flags)
 217{
 218        uint32_t opcode = 0;
 219        int pos = -1, ret = -EINVAL;
 220        unsigned int start_pc = program->current_pc, i;
 221
 222        if (flags & SEQ)
 223                opcode = CMD_SEQ_LOAD;
 224        else
 225                opcode = CMD_LOAD;
 226
 227        if ((length & 0xffffff00) || (offset & 0xffffff00)) {
 228                pr_err("LOAD: Bad length/offset passed. Should be 8 bits\n");
 229                goto err;
 230        }
 231
 232        if (flags & SGF)
 233                opcode |= LDST_SGF;
 234        if (flags & VLF)
 235                opcode |= LDST_VLF;
 236
 237        /* check load destination, length and offset and source type */
 238        for (i = 0; i < load_dst_sz[rta_sec_era]; i++)
 239                if (dst == load_dst[i].dst) {
 240                        pos = (int)i;
 241                        break;
 242                }
 243        if (-1 == pos) {
 244                pr_err("LOAD: Invalid dst. SEC Program Line: %d\n",
 245                       program->current_pc);
 246                goto err;
 247        }
 248
 249        if (flags & IMMED) {
 250                if (load_dst[pos].imm_src == IMM_NO) {
 251                        pr_err("LOAD: Invalid source type. SEC Program Line: %d\n",
 252                               program->current_pc);
 253                        goto err;
 254                }
 255                opcode |= LDST_IMM;
 256        } else if (load_dst[pos].imm_src == IMM_MUST) {
 257                pr_err("LOAD IMM: Invalid source type. SEC Program Line: %d\n",
 258                       program->current_pc);
 259                goto err;
 260        }
 261
 262        ret = load_check_len_offset(pos, length, offset);
 263        if (ret < 0) {
 264                pr_err("LOAD: Invalid length/offset. SEC Program Line: %d\n",
 265                       program->current_pc);
 266                goto err;
 267        }
 268
 269        opcode |= load_dst[pos].dst_opcode;
 270
 271        /* DESC BUFFER: length / offset values are specified in 4-byte words */
 272        if (dst == DESCBUF) {
 273                opcode |= (length >> 2);
 274                opcode |= ((offset >> 2) << LDST_OFFSET_SHIFT);
 275        } else {
 276                opcode |= length;
 277                opcode |= (offset << LDST_OFFSET_SHIFT);
 278        }
 279
 280        __rta_out32(program, opcode);
 281        program->current_instruction++;
 282
 283        /* DECO CONTROL: skip writing pointer of imm data */
 284        if (dst == DCTRL)
 285                return (int)start_pc;
 286
 287        /*
 288         * For data copy, 3 possible ways to specify how to copy data:
 289         *  - IMMED & !COPY: copy data directly from src( max 8 bytes)
 290         *  - IMMED & COPY: copy data imm from the location specified by user
 291         *  - !IMMED and is not SEQ cmd: copy the address
 292         */
 293        if (flags & IMMED)
 294                __rta_inline_data(program, src, flags & __COPY_MASK, length);
 295        else if (!(flags & SEQ))
 296                __rta_out64(program, program->ps, src);
 297
 298        return (int)start_pc;
 299
 300 err:
 301        program->first_error_pc = start_pc;
 302        program->current_instruction++;
 303        return ret;
 304}
 305
 306#endif /* __RTA_LOAD_CMD_H__*/
 307