nfp: bpf: use the power of sparse to check we encode registers right
[linux-2.6-block.git] / drivers / net / ethernet / netronome / nfp / nfp_asm.h
CommitLineData
cd7df56e
JK
1/*
2 * Copyright (C) 2016 Netronome Systems, Inc.
3 *
4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree or the BSD 2-Clause License provided below. You have the
7 * option to license this software under the complete terms of either license.
8 *
9 * The BSD 2-Clause License:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34#ifndef __NFP_ASM_H__
35#define __NFP_ASM_H__ 1
36
b3f868df 37#include <linux/bitfield.h>
d9ae7f2b 38#include <linux/types.h>
cd7df56e
JK
39
40#define REG_NONE 0
41
42#define RE_REG_NO_DST 0x020
43#define RE_REG_IMM 0x020
44#define RE_REG_IMM_encode(x) \
45 (RE_REG_IMM | ((x) & 0x1f) | (((x) & 0x60) << 1))
46#define RE_REG_IMM_MAX 0x07fULL
47#define RE_REG_XFR 0x080
48
49#define UR_REG_XFR 0x180
50#define UR_REG_NN 0x280
51#define UR_REG_NO_DST 0x300
52#define UR_REG_IMM UR_REG_NO_DST
53#define UR_REG_IMM_encode(x) (UR_REG_IMM | (x))
54#define UR_REG_IMM_MAX 0x0ffULL
55
56#define OP_BR_BASE 0x0d800000020ULL
57#define OP_BR_BASE_MASK 0x0f8000c3ce0ULL
58#define OP_BR_MASK 0x0000000001fULL
59#define OP_BR_EV_PIP 0x00000000300ULL
60#define OP_BR_CSS 0x0000003c000ULL
61#define OP_BR_DEFBR 0x00000300000ULL
62#define OP_BR_ADDR_LO 0x007ffc00000ULL
63#define OP_BR_ADDR_HI 0x10000000000ULL
64
65#define nfp_is_br(_insn) \
66 (((_insn) & OP_BR_BASE_MASK) == OP_BR_BASE)
67
68enum br_mask {
69 BR_BEQ = 0x00,
70 BR_BNE = 0x01,
71 BR_BHS = 0x04,
72 BR_BLO = 0x05,
73 BR_BGE = 0x08,
74 BR_UNC = 0x18,
75};
76
77enum br_ev_pip {
78 BR_EV_PIP_UNCOND = 0,
79 BR_EV_PIP_COND = 1,
80};
81
82enum br_ctx_signal_state {
83 BR_CSS_NONE = 2,
84};
85
86#define OP_BBYTE_BASE 0x0c800000000ULL
87#define OP_BB_A_SRC 0x000000000ffULL
88#define OP_BB_BYTE 0x00000000300ULL
89#define OP_BB_B_SRC 0x0000003fc00ULL
90#define OP_BB_I8 0x00000040000ULL
91#define OP_BB_EQ 0x00000080000ULL
92#define OP_BB_DEFBR 0x00000300000ULL
93#define OP_BB_ADDR_LO 0x007ffc00000ULL
94#define OP_BB_ADDR_HI 0x10000000000ULL
95
96#define OP_BALU_BASE 0x0e800000000ULL
97#define OP_BA_A_SRC 0x000000003ffULL
98#define OP_BA_B_SRC 0x000000ffc00ULL
99#define OP_BA_DEFBR 0x00000300000ULL
100#define OP_BA_ADDR_HI 0x0007fc00000ULL
101
102#define OP_IMMED_A_SRC 0x000000003ffULL
103#define OP_IMMED_B_SRC 0x000000ffc00ULL
104#define OP_IMMED_IMM 0x0000ff00000ULL
105#define OP_IMMED_WIDTH 0x00060000000ULL
106#define OP_IMMED_INV 0x00080000000ULL
107#define OP_IMMED_SHIFT 0x00600000000ULL
108#define OP_IMMED_BASE 0x0f000000000ULL
109#define OP_IMMED_WR_AB 0x20000000000ULL
110
111enum immed_width {
112 IMMED_WIDTH_ALL = 0,
113 IMMED_WIDTH_BYTE = 1,
114 IMMED_WIDTH_WORD = 2,
115};
116
117enum immed_shift {
118 IMMED_SHIFT_0B = 0,
119 IMMED_SHIFT_1B = 1,
120 IMMED_SHIFT_2B = 2,
121};
122
123#define OP_SHF_BASE 0x08000000000ULL
124#define OP_SHF_A_SRC 0x000000000ffULL
125#define OP_SHF_SC 0x00000000300ULL
126#define OP_SHF_B_SRC 0x0000003fc00ULL
127#define OP_SHF_I8 0x00000040000ULL
128#define OP_SHF_SW 0x00000080000ULL
129#define OP_SHF_DST 0x0000ff00000ULL
130#define OP_SHF_SHIFT 0x001f0000000ULL
131#define OP_SHF_OP 0x00e00000000ULL
132#define OP_SHF_DST_AB 0x01000000000ULL
133#define OP_SHF_WR_AB 0x20000000000ULL
134
135enum shf_op {
136 SHF_OP_NONE = 0,
137 SHF_OP_AND = 2,
138 SHF_OP_OR = 5,
139};
140
141enum shf_sc {
142 SHF_SC_R_ROT = 0,
143 SHF_SC_R_SHF = 1,
144 SHF_SC_L_SHF = 2,
145 SHF_SC_R_DSHF = 3,
146};
147
148#define OP_ALU_A_SRC 0x000000003ffULL
149#define OP_ALU_B_SRC 0x000000ffc00ULL
150#define OP_ALU_DST 0x0003ff00000ULL
151#define OP_ALU_SW 0x00040000000ULL
152#define OP_ALU_OP 0x00f80000000ULL
153#define OP_ALU_DST_AB 0x01000000000ULL
154#define OP_ALU_BASE 0x0a000000000ULL
155#define OP_ALU_WR_AB 0x20000000000ULL
156
157enum alu_op {
158 ALU_OP_NONE = 0x00,
159 ALU_OP_ADD = 0x01,
160 ALU_OP_NEG = 0x04,
161 ALU_OP_AND = 0x08,
162 ALU_OP_SUB_C = 0x0d,
163 ALU_OP_ADD_C = 0x11,
164 ALU_OP_OR = 0x14,
165 ALU_OP_SUB = 0x15,
166 ALU_OP_XOR = 0x18,
167};
168
169enum alu_dst_ab {
170 ALU_DST_A = 0,
171 ALU_DST_B = 1,
172};
173
174#define OP_LDF_BASE 0x0c000000000ULL
175#define OP_LDF_A_SRC 0x000000000ffULL
176#define OP_LDF_SC 0x00000000300ULL
177#define OP_LDF_B_SRC 0x0000003fc00ULL
178#define OP_LDF_I8 0x00000040000ULL
179#define OP_LDF_SW 0x00000080000ULL
180#define OP_LDF_ZF 0x00000100000ULL
181#define OP_LDF_BMASK 0x0000f000000ULL
182#define OP_LDF_SHF 0x001f0000000ULL
183#define OP_LDF_WR_AB 0x20000000000ULL
184
185#define OP_CMD_A_SRC 0x000000000ffULL
186#define OP_CMD_CTX 0x00000000300ULL
187#define OP_CMD_B_SRC 0x0000003fc00ULL
188#define OP_CMD_TOKEN 0x000000c0000ULL
189#define OP_CMD_XFER 0x00001f00000ULL
190#define OP_CMD_CNT 0x0000e000000ULL
191#define OP_CMD_SIG 0x000f0000000ULL
192#define OP_CMD_TGT_CMD 0x07f00000000ULL
193#define OP_CMD_MODE 0x1c0000000000ULL
194
195struct cmd_tgt_act {
196 u8 token;
197 u8 tgt_cmd;
198};
199
200enum cmd_tgt_map {
201 CMD_TGT_READ8,
202 CMD_TGT_WRITE8,
203 CMD_TGT_READ_LE,
204 CMD_TGT_READ_SWAP_LE,
205 __CMD_TGT_MAP_SIZE,
206};
207
208enum cmd_mode {
209 CMD_MODE_40b_AB = 0,
210 CMD_MODE_40b_BA = 1,
211 CMD_MODE_32b = 4,
212};
213
214enum cmd_ctx_swap {
215 CMD_CTX_SWAP = 0,
216 CMD_CTX_NO_SWAP = 3,
217};
218
219#define OP_LCSR_BASE 0x0fc00000000ULL
220#define OP_LCSR_A_SRC 0x000000003ffULL
221#define OP_LCSR_B_SRC 0x000000ffc00ULL
222#define OP_LCSR_WRITE 0x00000200000ULL
223#define OP_LCSR_ADDR 0x001ffc00000ULL
224
225enum lcsr_wr_src {
226 LCSR_WR_AREG,
227 LCSR_WR_BREG,
228 LCSR_WR_IMM,
229};
230
231#define OP_CARB_BASE 0x0e000000000ULL
232#define OP_CARB_OR 0x00000010000ULL
233
b3f868df
JK
234/* Software register representation, independent of operand type */
235#define NN_REG_TYPE GENMASK(31, 24)
236#define NN_REG_VAL GENMASK(7, 0)
237
238enum nfp_bpf_reg_type {
239 NN_REG_GPR_A = BIT(0),
240 NN_REG_GPR_B = BIT(1),
241 NN_REG_GPR_BOTH = NN_REG_GPR_A | NN_REG_GPR_B,
242 NN_REG_NNR = BIT(2),
243 NN_REG_XFER = BIT(3),
244 NN_REG_IMM = BIT(4),
245 NN_REG_NONE = BIT(5),
246};
247
248#define reg_both(x) __enc_swreg((x), NN_REG_GPR_BOTH)
249#define reg_a(x) __enc_swreg((x), NN_REG_GPR_A)
250#define reg_b(x) __enc_swreg((x), NN_REG_GPR_B)
251#define reg_nnr(x) __enc_swreg((x), NN_REG_NNR)
252#define reg_xfer(x) __enc_swreg((x), NN_REG_XFER)
253#define reg_imm(x) __enc_swreg((x), NN_REG_IMM)
254#define reg_none() __enc_swreg(0, NN_REG_NONE)
255
256typedef __u32 __bitwise swreg;
257
258static inline swreg __enc_swreg(u16 id, u8 type)
259{
260 return (__force swreg)(id | FIELD_PREP(NN_REG_TYPE, type));
261}
262
263static inline u32 swreg_raw(swreg reg)
264{
265 return (__force u32)reg;
266}
267
268static inline enum nfp_bpf_reg_type swreg_type(swreg reg)
269{
270 return FIELD_GET(NN_REG_TYPE, swreg_raw(reg));
271}
272
273static inline u16 swreg_value(swreg reg)
274{
275 return FIELD_GET(NN_REG_VAL, swreg_raw(reg));
276}
277
cd7df56e 278#endif