mirror of https://github.com/F-Stack/f-stack.git
153 lines
5.3 KiB
C
153 lines
5.3 KiB
C
|
/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
|
||
|
*
|
||
|
* Copyright 2008-2016 Freescale Semiconductor Inc.
|
||
|
* Copyright 2016,2019 NXP
|
||
|
*/
|
||
|
|
||
|
#ifndef __RTA_STORE_CMD_H__
|
||
|
#define __RTA_STORE_CMD_H__
|
||
|
|
||
|
extern enum rta_sec_era rta_sec_era;
|
||
|
|
||
|
static const uint32_t store_src_table[][2] = {
|
||
|
/*1*/ { KEY1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG },
|
||
|
{ KEY2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG },
|
||
|
{ DJQDA, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_JQDAR },
|
||
|
{ MODE1, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_MODE_REG },
|
||
|
{ MODE2, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_MODE_REG },
|
||
|
{ DJQCTRL, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_JQCTRL },
|
||
|
{ DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG },
|
||
|
{ DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG },
|
||
|
{ DSTAT, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_STAT },
|
||
|
{ ICV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG },
|
||
|
{ ICV2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG },
|
||
|
{ DPID, LDST_CLASS_DECO | LDST_SRCDST_WORD_PID },
|
||
|
{ CCTRL, LDST_SRCDST_WORD_CHACTRL },
|
||
|
{ ICTRL, LDST_SRCDST_WORD_IRQCTRL },
|
||
|
{ CLRW, LDST_SRCDST_WORD_CLRW },
|
||
|
{ MATH0, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0 },
|
||
|
{ CSTAT, LDST_SRCDST_WORD_STAT },
|
||
|
{ MATH1, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1 },
|
||
|
{ MATH2, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2 },
|
||
|
{ AAD1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ },
|
||
|
{ MATH3, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3 },
|
||
|
{ IV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ },
|
||
|
{ PKASZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ },
|
||
|
{ PKBSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ },
|
||
|
{ PKESZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ },
|
||
|
{ PKNSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ },
|
||
|
{ CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT },
|
||
|
{ CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT },
|
||
|
{ DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF },
|
||
|
/*30*/ { JOBDESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF_JOB },
|
||
|
{ SHAREDESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF_SHARED },
|
||
|
/*32*/ { JOBDESCBUF_EFF, LDST_CLASS_DECO |
|
||
|
LDST_SRCDST_WORD_DESCBUF_JOB_WE },
|
||
|
{ SHAREDESCBUF_EFF, LDST_CLASS_DECO |
|
||
|
LDST_SRCDST_WORD_DESCBUF_SHARED_WE },
|
||
|
/*34*/ { GTR, LDST_CLASS_DECO | LDST_SRCDST_WORD_GTR },
|
||
|
{ STR, LDST_CLASS_DECO | LDST_SRCDST_WORD_STR }
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Allowed STORE sources for each SEC ERA.
|
||
|
* Values represent the number of entries from source_src_table[] that are
|
||
|
* supported.
|
||
|
*/
|
||
|
static const unsigned int store_src_table_sz[] = {29, 31, 33, 33,
|
||
|
33, 33, 35, 35,
|
||
|
35, 35};
|
||
|
|
||
|
static inline int
|
||
|
rta_store(struct program *program, uint64_t src,
|
||
|
uint16_t offset, uint64_t dst, uint32_t length,
|
||
|
uint32_t flags)
|
||
|
{
|
||
|
uint32_t opcode = 0, val;
|
||
|
int ret = -EINVAL;
|
||
|
unsigned int start_pc = program->current_pc;
|
||
|
|
||
|
if (flags & SEQ)
|
||
|
opcode = CMD_SEQ_STORE;
|
||
|
else
|
||
|
opcode = CMD_STORE;
|
||
|
|
||
|
/* parameters check */
|
||
|
if ((flags & IMMED) && (flags & SGF)) {
|
||
|
pr_err("STORE: Invalid flag. SEC PC: %d; Instr: %d\n",
|
||
|
program->current_pc, program->current_instruction);
|
||
|
goto err;
|
||
|
}
|
||
|
if ((flags & IMMED) && (offset != 0)) {
|
||
|
pr_err("STORE: Invalid flag. SEC PC: %d; Instr: %d\n",
|
||
|
program->current_pc, program->current_instruction);
|
||
|
goto err;
|
||
|
}
|
||
|
|
||
|
if ((flags & SEQ) && ((src == JOBDESCBUF) || (src == SHAREDESCBUF) ||
|
||
|
(src == JOBDESCBUF_EFF) ||
|
||
|
(src == SHAREDESCBUF_EFF))) {
|
||
|
pr_err("STORE: Invalid SRC type. SEC PC: %d; Instr: %d\n",
|
||
|
program->current_pc, program->current_instruction);
|
||
|
goto err;
|
||
|
}
|
||
|
|
||
|
if (flags & IMMED)
|
||
|
opcode |= LDST_IMM;
|
||
|
|
||
|
if ((flags & SGF) || (flags & VLF))
|
||
|
opcode |= LDST_VLF;
|
||
|
|
||
|
/*
|
||
|
* source for data to be stored can be specified as:
|
||
|
* - register location; set in src field[9-15];
|
||
|
* - if IMMED flag is set, data is set in value field [0-31];
|
||
|
* user can give this value as actual value or pointer to data
|
||
|
*/
|
||
|
if (!(flags & IMMED)) {
|
||
|
ret = __rta_map_opcode((uint32_t)src, store_src_table,
|
||
|
store_src_table_sz[rta_sec_era], &val);
|
||
|
if (ret < 0) {
|
||
|
pr_err("STORE: Invalid source. SEC PC: %d; Instr: %d\n",
|
||
|
program->current_pc,
|
||
|
program->current_instruction);
|
||
|
goto err;
|
||
|
}
|
||
|
opcode |= val;
|
||
|
}
|
||
|
|
||
|
/* DESC BUFFER: length / offset values are specified in 4-byte words */
|
||
|
if ((src == DESCBUF) || (src == JOBDESCBUF) || (src == SHAREDESCBUF) ||
|
||
|
(src == JOBDESCBUF_EFF) || (src == SHAREDESCBUF_EFF)) {
|
||
|
opcode |= (length >> 2);
|
||
|
opcode |= (uint32_t)((offset >> 2) << LDST_OFFSET_SHIFT);
|
||
|
} else {
|
||
|
opcode |= length;
|
||
|
opcode |= (uint32_t)(offset << LDST_OFFSET_SHIFT);
|
||
|
}
|
||
|
|
||
|
__rta_out32(program, opcode);
|
||
|
program->current_instruction++;
|
||
|
|
||
|
if ((src == JOBDESCBUF) || (src == SHAREDESCBUF) ||
|
||
|
(src == JOBDESCBUF_EFF) || (src == SHAREDESCBUF_EFF))
|
||
|
return (int)start_pc;
|
||
|
|
||
|
/* for STORE, a pointer to where the data will be stored if needed */
|
||
|
if (!(flags & SEQ))
|
||
|
__rta_out64(program, program->ps, dst);
|
||
|
|
||
|
/* for IMMED data, place the data here */
|
||
|
if (flags & IMMED)
|
||
|
__rta_inline_data(program, src, flags & __COPY_MASK, length);
|
||
|
|
||
|
return (int)start_pc;
|
||
|
|
||
|
err:
|
||
|
program->first_error_pc = start_pc;
|
||
|
program->current_instruction++;
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
#endif /* __RTA_STORE_CMD_H__ */
|