Working switch2led demonstration on tic55x
[firmerware] / include / 0cpm / netcmd.h
1 /*
2  * bpfcmd.h -- Berkeley Packet Filter (ish) command set.
3  *
4  * This defines a virtual machine which is based on the BPF
5  * machine, as that is very suitable for taking apart packets,
6  * storing juicy parts on a scratchpad, and finally deciding
7  * what to do with it.
8  *
9  * The implementation, although inspired on the original
10  * BPF code, is a full reimplementation, mainly because the
11  * purpose is different: We want to generate code that is
12  * as efficient as possible, and that can be overridden
13  * locally by code that generates real assembler instructions
14  * optimised for a particular target platform.
15  *
16  * From: Rick van Rein <rick@openfortress.nl>
17  */
18
19
20
21 /* Enable overriding per target, if so desired.  This supports
22  * direct translation of these instructions into real assembler,
23  * fit for very fast execution of these vital bits of network
24  * code.  The utility of this code is that it is simple and is
25  * a delay in the actual handling of the network packet.  The
26  * BPF setup is geared towards efficiency, although the added
27  * value of this implementation is even better -- compile-time
28  * translation into real machine instructions at the expense of
29  * the flexibility that BPF needs but that we can live without.
30  *
31  * All data is stored in network byte order.  For some machines,
32  * that implies conversions.  The commands below do as much of
33  * these conversions on constants, counting on a clever compiler
34  * to precalculate it before it turns into code.
35  */
36
37 #ifdef HAVE_BPF_ASM_INLINES
38 #include <asm/bpfcmd.h>
39 #else
40
41
42 /* The following functions mark the structure of a program:
43  *
44  * BPF_BEGIN(selhdr)
45  *      ...insn...
46  * BPF_LABEL(skip)
47  *      ...insn...
48  * BPF_END()
49  *
50  * main () {
51  *      uint32_t memspace [20];
52  *      uint8_t *pkt = ...;
53  *      uint32_t pktlen = ...;
54  *      uint32_t outcome = selhdr (pkt, pktlen, memspace);
55  *      ...
56  * }
57  */
58
59 #define BPF_BEGIN(fname) intptr_t fname (uint8_t *P, uint32_t L, uint32_t *M) { register uint32_t A, X=htonl ((uint32_t) P), S; register int k;
60 #define BPF_LABEL(l) l:
61 #define BPF_END() }
62 #define BPF_TAIL(fname) return (fname) (P, L, M);
63
64
65 /* Opcodes and their meaning:
66  *
67  * LDB_ load byte and expand into accu A, unsigned
68  * LDH_ load halfword and expand into accu A, unsigned
69  * LDW_ load word into accu A
70  * LDX_ load word into indexreg X
71  * STB_ store byte from accu A
72  * STH_ store halfword from accu A
73  * STW_ store accu A
74  * STX_ store indexreg X
75  * JMP_ jump always
76  * JEQ_ jump on equal
77  * JNE_ jump on not equal
78  * JGT_ jump on greater
79  * JGE_ jump on greater or equal
80  * JLT_ jump on less
81  * JLE_ jump on less or equal
82  * JMN_ jump on nonzero after masking
83  * JMZ_ jump on zero after masking
84  * ADD_ add to accu A
85  * SUB_ subtract from accu A
86  * MUL_ multiply into accu A
87  * DIV_ divide accu A by
88  * AND_ bitwise and with accu A
89  * IOR_ bitwise inclusive or with accu A
90  * LSH_ left shift accu A
91  * RSH_ right shift accu A
92  * RET_ return value (finish program)
93  * 
94  * Note: TAX is renamed to LDX_ACC, TXA is renamed to LDW_REX
95  *
96  * Addressing modes
97  *
98  * _PKT k       [k]
99  * _IDX k       [X+k]   (X not shown as an operand)
100  * _LIT k       #k
101  * _LEN         #len    (not shown as an operand)
102  * _MEM k       M[k]    (M not shown as an operand)
103  * _ACC         A       (not shown as an operand)
104  * _TOP         A       (not shown, top half is used)
105  * _REX         X       (not shown as an operand)
106  * _ALW                 (no operand)
107  * _IP4         4*([k]&0x0f)    (not used in this phone)
108  * _SUM         S       (not shown as an operand)
109  *
110  * Local extensions:
111  * Commands     XOR_ STH_ STB_ SUM_ CLR_
112  * Modes        _TOP _SUM
113  * Combinations ST*_PKT ST*_IDX 
114  */
115
116
117
118 /* A few utility macros */
119
120 #define BPF_GET32(a,o) htonl ( (((uint8_t *)a)[o+0] << 24) | (((uint8_t *)a)[o+1] << 16) | (((uint8_t *)a)[o+2] << 8) | ((uint8_t *)a)[o+3] )
121 #define BPF_GET16(a,o) htonl (                                   (((uint8_t *)a)[o+0] << 8) | ((uint8_t *)a)[o+1] )
122 #define BPF_GET08(a,o) htonl (                                                   ((uint8_t *)a)[o+0] )
123
124 #define BPF_PUT32(a,o,v) ((uint8_t *)a)[o+0] = ((v) >> 24) & 0xff; \
125                          ((uint8_t *)a)[o+1] = ((v) >> 16) & 0xff; \
126                          ((uint8_t *)a)[o+2] = ((v) >>  8) & 0xff; \
127                          ((uint8_t *)a)[o+3] = ((v)      ) & 0xff;
128 #define BPF_PUT16(a,o,v) ((uint8_t *)a)[o+0] = ((v) >>  8) & 0xff; \
129                          ((uint8_t *)a)[o+1] = ((v)      ) & 0xff;
130 #define BPF_PUT08(a,o,v) ((uint8_t *)a)[o+0] = ((v)      ) & 0xff;
131
132
133 /* Instruction macros.  These can be overridden by
134  * real assembly instructions for a particular target
135  * platform if HAVE_BPF_ASM_INLINES is defined for it.
136  *
137  * TODO: Handle _PKT mode boundaries?  How about _IDX?
138  */
139
140 #ifdef DEBUG
141 #  include <stdio.h>
142 #  define DEBUG_REGS printf ("%d: A=%08X X=%08X\n", __LINE__, htonl (A), htonl (X))
143 #  define DEBUG_REGS_PLUS printf ("%d: A=%08X X=%08X, S=%08X\n", __LINE__, htonl (A), htonl (X), S)
144 #else
145 #  define DEBUG_REGS
146 #  define DEBUG_REGS_PLUS
147 #endif
148
149 #define RET_LIT(k)      return (uint32_t) (k);                  DEBUG_REGS;
150 #define RET_ACC()       return A;                               DEBUG_REGS;
151 #define LDW_PKT(k)      A = BPF_GET32 (P, (k));                 DEBUG_REGS;
152 #define LDH_PKT(k)      A = BPF_GET16 (P, (k));                 DEBUG_REGS;
153 #define LDB_PKT(k)      A = BPF_GET08 (P, (k));                 DEBUG_REGS;
154 #define LDW_LEN()       A = htonl (L);                          DEBUG_REGS;
155 #define LDX_LIT(k)      X = htonl (k);                          DEBUG_REGS;
156 #define LDX_LEN()       X = htonl (L);                          DEBUG_REGS;
157 #define LDW_IDX(k)      A = BPF_GET32 (ntohl(X), (k));          DEBUG_REGS;
158 #define STW_IDX(k)      BPF_PUT32 (ntohl(X), (k), ntohl (A));   DEBUG_REGS;
159 #define LDH_IDX(k)      A = BPF_GET16 (ntohl(X), (k));          DEBUG_REGS;
160 #define STH_IDX(k)      BPF_PUT16 (ntohl(X), (k), ntohl (A));   DEBUG_REGS;
161 #define LDB_IDX(k)      A = BPF_GET08 (ntohl(X), (k));          DEBUG_REGS;
162 #define STB_IDX(k)      BPF_PUT08 (ntohl(X), (k), ntohl (A));   DEBUG_REGS;
163 #define LDX_IP4(k)      A = (P [k] & 0x0f) << 2;                DEBUG_REGS;
164 #define LDW_LIT(k)      A = htonl ((k) & 0xffffffff);           DEBUG_REGS;
165 #define LDH_LIT(k)      A = htonl ((k) & 0x0000ffff);           DEBUG_REGS;
166 #define LDB_LIT(k)      A = htonl ((k) & 0x000000ff);           DEBUG_REGS;
167 #define LDW_MEM(k)      A = htonl (M[k]);                       DEBUG_REGS;
168 #define LDX_MEM(k)      X = htonl (M[k]);                       DEBUG_REGS;
169 #define STW_MEM(k)      M[k] = ntohl (A);                       DEBUG_REGS;
170 #define STX_MEM(k)      M[k] = ntohl (X);                       DEBUG_REGS;
171 #define JMP_ALW(t)      goto t;         DEBUG_REGS;
172 #define JGT_LIT(k,t)    if (ntohl(A) >  (k)) goto t;            DEBUG_REGS;
173 #define JGE_LIT(k,t)    if (ntohl(A) >= (k)) goto t;            DEBUG_REGS;
174 #define JLT_LIT(k,t)    if (ntohl(A) <  (k)) goto t;            DEBUG_REGS;
175 #define JLE_LIT(k,t)    if (ntohl(A) <= (k)) goto t;            DEBUG_REGS;
176 #define JEQ_LIT(k,t)    if (ntohl(A) == (k)) goto t;            DEBUG_REGS;
177 #define JNE_LIT(k,t)    if (ntohl(A) != (k)) goto t;            DEBUG_REGS;
178 #define JMN_LIT(k,t)    if ((ntohl(A) &  (k)) != 0) goto t;     DEBUG_REGS;
179 #define JMZ_LIT(k,t)    if ((ntohl(A) &  (k)) == 0) goto t;     DEBUG_REGS;
180 #define ADD_REX()       A = htonl (ntohl (A) + ntohl (X));      DEBUG_REGS;
181 #define SUB_REX()       A = htonl (ntohl (A) - ntohl (X));      DEBUG_REGS;
182 #define MUL_REX()       A = htonl (ntohl (A) * ntohl (X));      DEBUG_REGS;
183 #define DIV_REX()       if (X == 0) return 0; A = htonl (ntohl (A) / ntohl (X)); \
184                                                                 DEBUG_REGS;
185 #define AND_REX()       A = A & X;                              DEBUG_REGS;
186 #define IOR_REX()       A = A | X;                              DEBUG_REGS;
187 #define XOR_REX()       A = A ^ X;                              DEBUG_REGS;
188 #define LSH_REX()       A = htonl (ntohl (A) << ntohl (X));     DEBUG_REGS;
189 #define RSH_REX()       A = htonl (ntohl (A) >> ntohl (X));     DEBUG_REGS;
190 #define ADD_LIT(k)      A = htonl (ntohl (A) + (k));            DEBUG_REGS;
191 #define SUB_LIT(k)      A = htonl (ntohl (A) - (k));            DEBUG_REGS;
192 #define MUL_LIT(k)      A = htonl (ntohl (A) * (k));            DEBUG_REGS;
193 #define DIV_LIT(k)      if ((k) == 0) return 0; A = htonl (ntohl (A) / (k)); \
194                                                                 DEBUG_REGS;
195 #define AND_LIT(k)      A = A & htonl ((k));                    DEBUG_REGS;
196 #define IOR_LIT(k)      A = A | htonl ((k));                    DEBUG_REGS;
197 #define XOR_LIT(k)      A = A ^ htonl ((k));                    DEBUG_REGS;
198 #define LSH_LIT(k)      A = htonl (ntohl (A) << (k))            DEBUG_REGS;
199 #define RSH_LIT(k)      A = htonl (ntohl (A) >> (k))            DEBUG_REGS;
200 #define NEG_ACC()       A = htonl (-ntohl (A))                  DEBUG_REGS;
201 #define LDX_ACC()       X = A;                                  DEBUG_REGS;
202 #define LDW_REX()       A = A;                                  DEBUG_REGS;
203 #define SUM_PKT(k)      S += ntohl (BPF_GET16 (P, (k)));        DEBUG_REGS_PLUS;
204 #define SUM_IDX(k)      S += ntohl (BPF_GET16 (ntohl(X), (k))); DEBUG_REGS_PLUS;
205 #define SUM_ACC()       S += ntohl (A) & 0xffff;                DEBUG_REGS_PLUS;
206 #define SUM_TOP()       S += ntohl (A) >> 16;                   DEBUG_REGS_PLUS;
207 #define LDH_SUM()       printf ("S_pre = %08x\n", S); S = ((S & 0xffff) + (S >> 16)) & 0xffff; A = htonl (S) ^ 0xffff; printf ("S_post= %08x\n", S); \
208                                                                 DEBUG_REGS_PLUS;
209 #define CLR_SUM()       S = 0;                                  DEBUG_REGS_PLUS;
210
211
212 #endif // HAVE_BPF_ASM_INLINES
213