Commit 0a793977 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

nfp: bpf: separate I/O from checks for legacy data load

Move data load into a separate function and separate it from
packet length checks of legacy I/O.  This makes the code more
readable and easier to reuse.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 943c57b9
...@@ -515,63 +515,66 @@ static void wrp_reg_mov(struct nfp_prog *nfp_prog, u16 dst, u16 src) ...@@ -515,63 +515,66 @@ static void wrp_reg_mov(struct nfp_prog *nfp_prog, u16 dst, u16 src)
} }
static int static int
construct_data_ind_ld(struct nfp_prog *nfp_prog, u16 offset, data_ld(struct nfp_prog *nfp_prog, swreg offset, u8 dst_gpr, int size)
u16 src, bool src_valid, u8 size)
{ {
unsigned int i; unsigned int i;
u16 shift, sz; u16 shift, sz;
swreg tmp_reg;
/* We load the value from the address indicated in @offset and then /* We load the value from the address indicated in @offset and then
* shift out the data we don't need. Note: this is big endian! * shift out the data we don't need. Note: this is big endian!
*/ */
sz = size < 4 ? 4 : size; sz = max(size, 4);
shift = size < 4 ? 4 - size : 0; shift = size < 4 ? 4 - size : 0;
if (src_valid) { emit_cmd(nfp_prog, CMD_TGT_READ8, CMD_MODE_32b, 0,
/* Calculate the true offset (src_reg + imm) */ pptr_reg(nfp_prog), offset, sz - 1, true);
tmp_reg = ur_load_imm_any(nfp_prog, offset, imm_b(nfp_prog));
emit_alu(nfp_prog, imm_both(nfp_prog),
reg_a(src), ALU_OP_ADD, tmp_reg);
/* Check packet length (size guaranteed to fit b/c it's u8) */
emit_alu(nfp_prog, imm_a(nfp_prog),
imm_a(nfp_prog), ALU_OP_ADD, reg_imm(size));
emit_alu(nfp_prog, reg_none(),
plen_reg(nfp_prog), ALU_OP_SUB, imm_a(nfp_prog));
wrp_br_special(nfp_prog, BR_BLO, OP_BR_GO_ABORT);
/* Load data */
emit_cmd(nfp_prog, CMD_TGT_READ8, CMD_MODE_32b, 0,
pptr_reg(nfp_prog), imm_b(nfp_prog), sz - 1, true);
} else {
/* Check packet length */
tmp_reg = ur_load_imm_any(nfp_prog, offset + size,
imm_a(nfp_prog));
emit_alu(nfp_prog, reg_none(),
plen_reg(nfp_prog), ALU_OP_SUB, tmp_reg);
wrp_br_special(nfp_prog, BR_BLO, OP_BR_GO_ABORT);
/* Load data */
tmp_reg = re_load_imm_any(nfp_prog, offset, imm_b(nfp_prog));
emit_cmd(nfp_prog, CMD_TGT_READ8, CMD_MODE_32b, 0,
pptr_reg(nfp_prog), tmp_reg, sz - 1, true);
}
i = 0; i = 0;
if (shift) if (shift)
emit_shf(nfp_prog, reg_both(0), reg_none(), SHF_OP_NONE, emit_shf(nfp_prog, reg_both(dst_gpr), reg_none(), SHF_OP_NONE,
reg_xfer(0), SHF_SC_R_SHF, shift * 8); reg_xfer(0), SHF_SC_R_SHF, shift * 8);
else else
for (; i * 4 < size; i++) for (; i * 4 < size; i++)
wrp_mov(nfp_prog, reg_both(i), reg_xfer(i)); wrp_mov(nfp_prog, reg_both(dst_gpr + i), reg_xfer(i));
if (i < 2) if (i < 2)
wrp_immed(nfp_prog, reg_both(1), 0); wrp_immed(nfp_prog, reg_both(dst_gpr + 1), 0);
return 0; return 0;
} }
static int
construct_data_ind_ld(struct nfp_prog *nfp_prog, u16 offset, u16 src, u8 size)
{
swreg tmp_reg;
/* Calculate the true offset (src_reg + imm) */
tmp_reg = ur_load_imm_any(nfp_prog, offset, imm_b(nfp_prog));
emit_alu(nfp_prog, imm_both(nfp_prog), reg_a(src), ALU_OP_ADD, tmp_reg);
/* Check packet length (size guaranteed to fit b/c it's u8) */
emit_alu(nfp_prog, imm_a(nfp_prog),
imm_a(nfp_prog), ALU_OP_ADD, reg_imm(size));
emit_alu(nfp_prog, reg_none(),
plen_reg(nfp_prog), ALU_OP_SUB, imm_a(nfp_prog));
wrp_br_special(nfp_prog, BR_BLO, OP_BR_GO_ABORT);
/* Load data */
return data_ld(nfp_prog, imm_b(nfp_prog), 0, size);
}
static int construct_data_ld(struct nfp_prog *nfp_prog, u16 offset, u8 size) static int construct_data_ld(struct nfp_prog *nfp_prog, u16 offset, u8 size)
{ {
return construct_data_ind_ld(nfp_prog, offset, 0, false, size); swreg tmp_reg;
/* Check packet length */
tmp_reg = ur_load_imm_any(nfp_prog, offset + size, imm_a(nfp_prog));
emit_alu(nfp_prog, reg_none(), plen_reg(nfp_prog), ALU_OP_SUB, tmp_reg);
wrp_br_special(nfp_prog, BR_BLO, OP_BR_GO_ABORT);
/* Load data */
tmp_reg = re_load_imm_any(nfp_prog, offset, imm_b(nfp_prog));
return data_ld(nfp_prog, tmp_reg, 0, size);
} }
static void static void
...@@ -1055,19 +1058,19 @@ static int data_ld4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) ...@@ -1055,19 +1058,19 @@ static int data_ld4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
static int data_ind_ld1(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) static int data_ind_ld1(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
{ {
return construct_data_ind_ld(nfp_prog, meta->insn.imm, return construct_data_ind_ld(nfp_prog, meta->insn.imm,
meta->insn.src_reg * 2, true, 1); meta->insn.src_reg * 2, 1);
} }
static int data_ind_ld2(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) static int data_ind_ld2(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
{ {
return construct_data_ind_ld(nfp_prog, meta->insn.imm, return construct_data_ind_ld(nfp_prog, meta->insn.imm,
meta->insn.src_reg * 2, true, 2); meta->insn.src_reg * 2, 2);
} }
static int data_ind_ld4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) static int data_ind_ld4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
{ {
return construct_data_ind_ld(nfp_prog, meta->insn.imm, return construct_data_ind_ld(nfp_prog, meta->insn.imm,
meta->insn.src_reg * 2, true, 4); meta->insn.src_reg * 2, 4);
} }
static int mem_ldx_skb(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, static int mem_ldx_skb(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment