f-stack/dpdk/drivers/crypto/dpaa2_sec/hw/rta/load_cmd.h

303 lines
8.2 KiB
C
Raw Normal View History

2019-06-25 11:12:58 +00:00
/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
*
* Copyright 2008-2016 Freescale Semiconductor Inc.
2019-06-25 11:12:58 +00:00
* Copyright 2016 NXP
*
*/
#ifndef __RTA_LOAD_CMD_H__
#define __RTA_LOAD_CMD_H__
extern enum rta_sec_era rta_sec_era;
/* Allowed length and offset masks for each SEC Era in case DST = DCTRL */
static const uint32_t load_len_mask_allowed[] = {
0x000000ee,
0x000000fe,
0x000000fe,
0x000000fe,
0x000000fe,
0x000000fe,
0x000000fe,
0x000000fe
};
static const uint32_t load_off_mask_allowed[] = {
0x0000000f,
0x000000ff,
0x000000ff,
0x000000ff,
0x000000ff,
0x000000ff,
0x000000ff,
0x000000ff
};
#define IMM_MUST 0
#define IMM_CAN 1
#define IMM_NO 2
#define IMM_DSNM 3 /* it doesn't matter the src type */
enum e_lenoff {
LENOF_03,
LENOF_4,
LENOF_48,
LENOF_448,
LENOF_18,
LENOF_32,
LENOF_24,
LENOF_16,
LENOF_8,
LENOF_128,
LENOF_256,
DSNM /* it doesn't matter the length/offset values */
};
struct load_map {
uint32_t dst;
uint32_t dst_opcode;
enum e_lenoff len_off;
uint8_t imm_src;
};
static const struct load_map load_dst[] = {
/*1*/ { KEY1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
LENOF_4, IMM_MUST },
{ KEY2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
LENOF_4, IMM_MUST },
{ DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG,
LENOF_448, IMM_MUST },
{ DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG,
LENOF_448, IMM_MUST },
{ ICV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
LENOF_4, IMM_MUST },
{ ICV2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
LENOF_4, IMM_MUST },
{ CCTRL, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CHACTRL,
LENOF_4, IMM_MUST },
{ DCTRL, LDST_CLASS_DECO | LDST_IMM | LDST_SRCDST_WORD_DECOCTRL,
DSNM, IMM_DSNM },
{ ICTRL, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_IRQCTRL,
LENOF_4, IMM_MUST },
{ DPOVRD, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_PCLOVRD,
LENOF_4, IMM_MUST },
{ CLRW, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CLRW,
LENOF_4, IMM_MUST },
{ AAD1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ,
LENOF_4, IMM_MUST },
{ IV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ,
LENOF_4, IMM_MUST },
{ ALTDS1, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ALTDS_CLASS1,
LENOF_448, IMM_MUST },
{ PKASZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ,
LENOF_4, IMM_MUST, },
{ PKBSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ,
LENOF_4, IMM_MUST },
{ PKNSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ,
LENOF_4, IMM_MUST },
{ PKESZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ,
LENOF_4, IMM_MUST },
{ NFIFO, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_INFO_FIFO,
LENOF_48, IMM_MUST },
{ IFIFO, LDST_SRCDST_BYTE_INFIFO, LENOF_18, IMM_MUST },
{ OFIFO, LDST_SRCDST_BYTE_OUTFIFO, LENOF_18, IMM_MUST },
{ MATH0, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0,
LENOF_32, IMM_CAN },
{ MATH1, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1,
LENOF_24, IMM_CAN },
{ MATH2, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2,
LENOF_16, IMM_CAN },
{ MATH3, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3,
LENOF_8, IMM_CAN },
{ CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT,
LENOF_128, IMM_CAN },
{ CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT,
LENOF_128, IMM_CAN },
{ KEY1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_KEY,
LENOF_32, IMM_CAN },
{ KEY2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY,
LENOF_32, IMM_CAN },
{ DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF,
LENOF_256, IMM_NO },
{ DPID, LDST_CLASS_DECO | LDST_SRCDST_WORD_PID,
LENOF_448, IMM_MUST },
/*32*/ { IDFNS, LDST_SRCDST_WORD_IFNSR, LENOF_18, IMM_MUST },
{ ODFNS, LDST_SRCDST_WORD_OFNSR, LENOF_18, IMM_MUST },
{ ALTSOURCE, LDST_SRCDST_BYTE_ALTSOURCE, LENOF_18, IMM_MUST },
/*35*/ { NFIFO_SZL, LDST_SRCDST_WORD_INFO_FIFO_SZL, LENOF_48, IMM_MUST },
{ NFIFO_SZM, LDST_SRCDST_WORD_INFO_FIFO_SZM, LENOF_03, IMM_MUST },
{ NFIFO_L, LDST_SRCDST_WORD_INFO_FIFO_L, LENOF_48, IMM_MUST },
{ NFIFO_M, LDST_SRCDST_WORD_INFO_FIFO_M, LENOF_03, IMM_MUST },
{ SZL, LDST_SRCDST_WORD_SZL, LENOF_48, IMM_MUST },
/*40*/ { SZM, LDST_SRCDST_WORD_SZM, LENOF_03, IMM_MUST }
};
/*
* Allowed LOAD destinations for each SEC Era.
* Values represent the number of entries from load_dst[] that are supported.
*/
static const unsigned int load_dst_sz[] = { 31, 34, 34, 40, 40, 40, 40, 40 };
static inline int
load_check_len_offset(int pos, uint32_t length, uint32_t offset)
{
if ((load_dst[pos].dst == DCTRL) &&
((length & ~load_len_mask_allowed[rta_sec_era]) ||
(offset & ~load_off_mask_allowed[rta_sec_era])))
goto err;
switch (load_dst[pos].len_off) {
case (LENOF_03):
if ((length > 3) || (offset))
goto err;
break;
case (LENOF_4):
if ((length != 4) || (offset != 0))
goto err;
break;
case (LENOF_48):
if (!(((length == 4) && (offset == 0)) ||
((length == 8) && (offset == 0))))
goto err;
break;
case (LENOF_448):
if (!(((length == 4) && (offset == 0)) ||
((length == 4) && (offset == 4)) ||
((length == 8) && (offset == 0))))
goto err;
break;
case (LENOF_18):
if ((length < 1) || (length > 8) || (offset != 0))
goto err;
break;
case (LENOF_32):
if ((length > 32) || (offset > 32) || ((offset + length) > 32))
goto err;
break;
case (LENOF_24):
if ((length > 24) || (offset > 24) || ((offset + length) > 24))
goto err;
break;
case (LENOF_16):
if ((length > 16) || (offset > 16) || ((offset + length) > 16))
goto err;
break;
case (LENOF_8):
if ((length > 8) || (offset > 8) || ((offset + length) > 8))
goto err;
break;
case (LENOF_128):
if ((length > 128) || (offset > 128) ||
((offset + length) > 128))
goto err;
break;
case (LENOF_256):
if ((length < 1) || (length > 256) || ((length + offset) > 256))
goto err;
break;
case (DSNM):
break;
default:
goto err;
}
return 0;
err:
return -EINVAL;
}
static inline int
rta_load(struct program *program, uint64_t src, uint64_t dst,
uint32_t offset, uint32_t length, uint32_t flags)
{
uint32_t opcode = 0;
int pos = -1, ret = -EINVAL;
unsigned int start_pc = program->current_pc, i;
if (flags & SEQ)
opcode = CMD_SEQ_LOAD;
else
opcode = CMD_LOAD;
if ((length & 0xffffff00) || (offset & 0xffffff00)) {
pr_err("LOAD: Bad length/offset passed. Should be 8 bits\n");
goto err;
}
if (flags & SGF)
opcode |= LDST_SGF;
if (flags & VLF)
opcode |= LDST_VLF;
/* check load destination, length and offset and source type */
for (i = 0; i < load_dst_sz[rta_sec_era]; i++)
if (dst == load_dst[i].dst) {
pos = (int)i;
break;
}
if (-1 == pos) {
pr_err("LOAD: Invalid dst. SEC Program Line: %d\n",
program->current_pc);
goto err;
}
if (flags & IMMED) {
if (load_dst[pos].imm_src == IMM_NO) {
pr_err("LOAD: Invalid source type. SEC Program Line: %d\n",
program->current_pc);
goto err;
}
opcode |= LDST_IMM;
} else if (load_dst[pos].imm_src == IMM_MUST) {
pr_err("LOAD IMM: Invalid source type. SEC Program Line: %d\n",
program->current_pc);
goto err;
}
ret = load_check_len_offset(pos, length, offset);
if (ret < 0) {
pr_err("LOAD: Invalid length/offset. SEC Program Line: %d\n",
program->current_pc);
goto err;
}
opcode |= load_dst[pos].dst_opcode;
/* DESC BUFFER: length / offset values are specified in 4-byte words */
if (dst == DESCBUF) {
opcode |= (length >> 2);
opcode |= ((offset >> 2) << LDST_OFFSET_SHIFT);
} else {
opcode |= length;
opcode |= (offset << LDST_OFFSET_SHIFT);
}
__rta_out32(program, opcode);
program->current_instruction++;
/* DECO CONTROL: skip writing pointer of imm data */
if (dst == DCTRL)
return (int)start_pc;
/*
* For data copy, 3 possible ways to specify how to copy data:
* - IMMED & !COPY: copy data directly from src( max 8 bytes)
* - IMMED & COPY: copy data imm from the location specified by user
* - !IMMED and is not SEQ cmd: copy the address
*/
if (flags & IMMED)
__rta_inline_data(program, src, flags & __COPY_MASK, length);
else if (!(flags & SEQ))
__rta_out64(program, program->ps, src);
return (int)start_pc;
err:
program->first_error_pc = start_pc;
program->current_instruction++;
return ret;
}
#endif /* __RTA_LOAD_CMD_H__*/