]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - sys/contrib/octeon-sdk/cvmx-dfa.h
Merge MIPS platform support to 8-STABLE.
[FreeBSD/stable/8.git] / sys / contrib / octeon-sdk / cvmx-dfa.h
1 /***********************license start***************
2  *  Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
3  *  reserved.
4  *
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions are
8  *  met:
9  *
10  *      * Redistributions of source code must retain the above copyright
11  *        notice, this list of conditions and the following disclaimer.
12  *
13  *      * Redistributions in binary form must reproduce the above
14  *        copyright notice, this list of conditions and the following
15  *        disclaimer in the documentation and/or other materials provided
16  *        with the distribution.
17  *
18  *      * Neither the name of Cavium Networks nor the names of
19  *        its contributors may be used to endorse or promote products
20  *        derived from this software without specific prior written
21  *        permission.
22  *
23  *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24  *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25  *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26  *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27  *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28  *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29  *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30  *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31  *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
32  *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
33  *
34  *
35  *  For any questions regarding licensing please contact marketing@caviumnetworks.com
36  *
37  ***********************license end**************************************/
38
39
40
41
42
43
44 /**
45  * @file
46  *
47  * Interface to the hardware DFA engine.
48  *
49  * <hr>$Revision: 41586 $<hr>
50  */
51
52 #ifndef __CVMX_DFA_H__
53 #define __CVMX_DFA_H__
54 #include "cvmx-llm.h"
55 #include "cvmx-wqe.h"
56 #include "cvmx-fpa.h"
57
58 #include "executive-config.h"
59 #ifdef CVMX_ENABLE_DFA_FUNCTIONS
60 #include "cvmx-config.h"
61 #endif
62
63 #define ENABLE_DEPRECATED   /* Set to enable the old 18/36 bit names */
64
65 #ifdef  __cplusplus
66 extern "C" {
67 #endif
68
69
70 /* Maximum nodes available in a small encoding */
71 #define CVMX_DFA_NODESM_MAX_NODES       ((OCTEON_IS_MODEL(OCTEON_CN31XX)) ? 0x8000 : 0x20000)
72 #define CVMX_DFA_NODESM_SIZE            512     /* Size of each node for small encoding */
73 #define CVMX_DFA_NODELG_SIZE            1024    /* Size of each node for large encoding */
74 #define CVMX_DFA_NODESM_LAST_TERMINAL  (CVMX_DFA_NODESM_MAX_NODES-1)
75
76 #ifdef ENABLE_DEPRECATED
77 /* These defines are for compatability with old code. They are deprecated */
78 #define CVMX_DFA_NODE18_SIZE            CVMX_DFA_NODESM_SIZE
79 #define CVMX_DFA_NODE36_SIZE            CVMX_DFA_NODELG_SIZE
80 #define CVMX_DFA_NODE18_MAX_NODES       CVMX_DFA_NODESM_MAX_NODES
81 #define CVMX_DFA_NODE18_LAST_TERMINAL   CVMX_DFA_NODESM_LAST_TERMINAL
82 #endif
83
84 /**
85  * Which type of memory encoding is this graph using. Make sure you setup
86  * the LLM to match.
87  */
88 typedef enum
89 {
90     CVMX_DFA_GRAPH_TYPE_SM              = 0,
91     CVMX_DFA_GRAPH_TYPE_LG              = 1,
92 #ifdef ENABLE_DEPRECATED
93     CVMX_DFA_GRAPH_TYPE_18b             = 0,    /* Deprecated */
94     CVMX_DFA_GRAPH_TYPE_36b             = 1     /* Deprecated */
95 #endif
96 } cvmx_dfa_graph_type_t;
97
98 /**
99  * The possible node types.
100  */
101 typedef enum
102 {
103     CVMX_DFA_NODE_TYPE_NORMAL           = 0,    /**< Node is a branch */
104     CVMX_DFA_NODE_TYPE_MARKED           = 1,    /**< Node is marked special */
105     CVMX_DFA_NODE_TYPE_TERMINAL         = 2     /**< Node is a terminal leaf */
106 } cvmx_dfa_node_type_t;
107
108 /**
109  * The possible reasons the DFA stopped processing.
110  */
111 typedef enum
112 {
113     CVMX_DFA_STOP_REASON_DATA_GONE      = 0,    /**< DFA ran out of data */
114     CVMX_DFA_STOP_REASON_PARITY_ERROR   = 1,    /**< DFA encountered a memory error */
115     CVMX_DFA_STOP_REASON_FULL           = 2,    /**< DFA is full */
116     CVMX_DFA_STOP_REASON_TERMINAL       = 3     /**< DFA hit a terminal */
117 } cvmx_dfa_stop_reason_t;
118
119 /**
120  * This format describes the DFA pointers in small mode
121  */
122 typedef union
123 {
124     uint64_t u64;
125     struct
126     {
127         uint64_t                mbz         :32;/**< Must be zero */
128         uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
129         uint64_t                next_node1  :15;/**< Next node if an odd character match */
130         uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
131         uint64_t                next_node0  :15;/**< Next node if an even character match */
132     } w32;
133     struct
134     {
135         uint64_t                mbz         :28;/**< Must be zero */
136         uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
137         uint64_t                next_node1  :17;/**< Next node if an odd character match */
138         uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
139         uint64_t                next_node0  :17;/**< Next node if an even character match */
140     } w36;
141     struct /**< @ this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1.  */
142     {
143         uint64_t                mbz         :28;/**< Must be zero */
144         uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
145         uint64_t                per_node_repl1  : 1;/**< enable for extra replicaiton for next node (CN58XX) */
146         uint64_t                next_node_repl1 : 2;/**< extra replicaiton for next node (CN58XX) (if per_node_repl1 is set) */
147         uint64_t                next_node1  :14;/**< Next node if an odd character match - IWORD3[Msize], if per_node_repl1==1. */
148         uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
149         uint64_t                per_node_repl0  : 1;/**< enable for extra replicaiton for next node (CN58XX) */
150         uint64_t                next_node_repl0 : 2;/**< extra replicaiton for next node (CN58XX) (if per_node_repl0 is set) */
151         uint64_t                next_node0  :14;/**< Next node if an odd character match - IWORD3[Msize], if per_node_repl0==1. */
152     } w36nrepl_en; /**< use when next_node_repl[01] is 1. */
153     struct /**< this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1.  */
154     {
155         uint64_t                mbz         :28;/**< Must be zero */
156         uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
157         uint64_t                per_node_repl1  : 1;/**< enable for extra replicaiton for next node (CN58XX) */
158         uint64_t                next_node1  :16;/**< Next node if an odd character match, if per_node_repl1==0. */
159         uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
160         uint64_t                per_node_repl0  : 1;/**< enable for extra replicaiton for next node (CN58XX) */
161         uint64_t                next_node0  :16;/**< Next node if an odd character match, if per_node_repl0==0. */
162     } w36nrepl_dis; /**< use when next_node_repl[01] is 0. */
163 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
164 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
165     struct /**< @deprecated unnamed reference to members */
166     {
167         uint64_t                mbz         :32;/**< Must be zero */
168         uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
169         uint64_t                next_node1  :15;/**< Next node if an odd character match */
170         uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
171         uint64_t                next_node0  :15;/**< Next node if an even character match */
172     };
173 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
174     struct /**< @deprecated unnamed reference to members */
175     {
176         uint64_t                mbz         :28;/**< Must be zero */
177         uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
178         uint64_t                next_node1  :17;/**< Next node if an odd character match */
179         uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
180         uint64_t                next_node0  :17;/**< Next node if an even character match */
181     };
182 #else
183     /* Other chips don't support the deprecated unnamed unions */
184 #endif
185 #endif
186 } cvmx_dfa_node_next_sm_t;
187
188 /**
189  * This format describes the DFA pointers in large mode
190  */
191 typedef union
192 {
193     uint64_t u64;
194     struct
195     {
196         uint64_t                mbz         :32;/**< Must be zero */
197         uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
198         cvmx_dfa_node_type_t    type        : 2;/**< Node type */
199         uint64_t                mbz2        : 3;/**< Must be zero */
200         uint64_t                next_node   :20;/**< Next node */
201     } w32;
202     struct
203     {
204         uint64_t                mbz         :28;/**< Must be zero */
205         uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
206         cvmx_dfa_node_type_t    type        : 2;/**< Node type */
207         uint64_t                extra_bits     : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
208         uint64_t                next_node_repl : 2;/**< extra replicaiton for next node (PASS3/CN58XX), Must be zero previously */
209         uint64_t                next_node   :20;/**< Next node ID,  Note, combine with next_node_repl to use as start_node
210                                                      for continuation, as in cvmx_dfa_node_next_lgb_t. */
211     } w36;
212 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
213 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
214     struct /**< @deprecated unnamed reference to members */
215     {
216         uint64_t                mbz         :32;/**< Must be zero */
217         uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
218         cvmx_dfa_node_type_t    type        : 2;/**< Node type */
219         uint64_t                mbz2        : 3;/**< Must be zero */
220         uint64_t                next_node   :20;/**< Next node */
221     };
222 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
223     struct /**< @deprecated unnamed reference to members */
224     {
225         uint64_t                mbz         :28;/**< Must be zero */
226         uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
227         cvmx_dfa_node_type_t    type        : 2;/**< Node type */
228         uint64_t                extra_bits     : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
229         uint64_t                next_node_repl : 2;/**< extra replicaiton for next node (PASS3/CN58XX), Must be zero previously */
230         uint64_t                next_node   :20;/**< Next node ID,  Note, combine with next_node_repl to use as start_node
231                                                      for continuation, as in cvmx_dfa_node_next_lgb_t. */
232     };
233 #else
234     /* Other chips don't support the deprecated unnamed unions */
235 #endif
236 #endif
237 } cvmx_dfa_node_next_lg_t;
238
239 /**
240  * This format describes the DFA pointers in large mode, another way
241  */
242 typedef union
243 {
244     uint64_t u64;
245     struct
246     {
247         uint64_t                mbz         :32;/**< Must be zero */
248         uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
249         uint64_t                type_terminal : 1;/**< Node type */
250         uint64_t                type_marked   : 1;/**< Node type */
251         uint64_t                mbz2        : 3;/**< Must be zero */
252         uint64_t                next_node   :20;/**< Next node */
253     } w32;
254     struct
255     {
256         uint64_t                mbz         :28;/**< Must be zero */
257         uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
258         uint64_t                type_terminal : 1;/**< Node type */
259         uint64_t                type_marked   : 1;/**< Node type */
260         uint64_t                extra_bits     : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
261         uint64_t                next_node_id_and_repl   :22;/**< Next node ID (and repl for PASS3/CN58XX or repl=0 if not),
262                                                                  use this as start node for continuation. */
263     } w36;
264 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
265 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
266     struct /**< @deprecated unnamed reference to members */
267     {
268         uint64_t                mbz         :32;/**< Must be zero */
269         uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
270         uint64_t                type_terminal : 1;/**< Node type */
271         uint64_t                type_marked   : 1;/**< Node type */
272         uint64_t                mbz2        : 3;/**< Must be zero */
273         uint64_t                next_node   :20;/**< Next node */
274     };
275 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
276     struct /**< @deprecated unnamed reference to members */
277     {
278         uint64_t                mbz         :28;/**< Must be zero */
279         uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
280         uint64_t                type_terminal : 1;/**< Node type */
281         uint64_t                type_marked   : 1;/**< Node type */
282         uint64_t                extra_bits     : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
283         uint64_t                next_node_id_and_repl   :22;/**< Next node ID (and repl for PASS3/CN58XX or repl=0 if not),
284                                                                  use this as start node for continuation. */
285     };
286 #else
287     /* Other chips don't support the deprecated unnamed unions */
288 #endif
289 #endif
290 } cvmx_dfa_node_next_lgb_t;
291
292 /**
293  * This format describes the DFA pointers in large mode
294  */
295 typedef union
296 {
297     uint64_t u64;
298     struct
299     {
300         uint64_t                mbz         :27;/**< Must be zero */
301         uint64_t                x0          : 1;/**< XOR of the rest of the bits */
302         uint64_t                reserved    : 4;/**< Must be zero */
303         uint64_t                data        :32;/**< LLM Data */
304     } w32;
305     struct
306     {
307         uint64_t                mbz         :27;/**< Must be zero */
308         uint64_t                x0          : 1;/**< XOR of the rest of the bits */
309         uint64_t                data        :36;/**< LLM Data */
310     } w36;
311 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
312 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
313     struct /**< @deprecated unnamed reference to members */
314     {
315         uint64_t                mbz         :27;/**< Must be zero */
316         uint64_t                x0          : 1;/**< XOR of the rest of the bits */
317         uint64_t                reserved    : 4;/**< Must be zero */
318         uint64_t                data        :32;/**< LLM Data */
319     };
320 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
321     struct /**< @deprecated unnamed reference to members */
322     {
323         uint64_t                mbz         :27;/**< Must be zero */
324         uint64_t                x0          : 1;/**< XOR of the rest of the bits */
325         uint64_t                data        :36;/**< LLM Data */
326     };
327 #else
328     /* Other chips don't support the deprecated unnamed unions */
329 #endif
330 #endif
331 } cvmx_dfa_node_next_read_t;
332
333 /**
334  * This structure defines the data format in the low-latency memory
335  */
336 typedef union
337 {
338     uint64_t u64;
339     cvmx_dfa_node_next_sm_t     sm;     /**< This format describes the DFA pointers in small mode */
340     cvmx_dfa_node_next_lg_t     lg;     /**< This format describes the DFA pointers in large mode */
341     cvmx_dfa_node_next_lgb_t    lgb;    /**< This format describes the DFA pointers in large mode, another way */
342     cvmx_dfa_node_next_read_t   read;   /**< This format describes the DFA pointers in large mode */
343 #ifdef ENABLE_DEPRECATED
344     cvmx_dfa_node_next_sm_t     s18;    /**< Deprecated */
345     cvmx_dfa_node_next_lg_t     s36;    /**< Deprecated */
346     cvmx_dfa_node_next_lgb_t    s36b;   /**< Deprecated */
347 #endif
348 } cvmx_dfa_node_next_t;
349
350 /**
351  * These structures define a DFA instruction
352  */
353 typedef union
354 {
355     uint64_t u64[4];
356     uint32_t u32;
357     struct
358     {
359         // WORD 0
360         uint64_t gxor                   : 8;   /**< Graph XOR value (PASS3/CN58XX), Must be zero for other chips
361                                                      or if DFA_CFG[GXOR_ENA] == 0.  */
362         uint64_t nxoren                 : 1;   /**< Node XOR enable (PASS3/CN58XX), Must be zero for other chips
363                                                      or if DFA_CFG[NXOR_ENA] == 0.  */
364         uint64_t nreplen                : 1;   /**< Node Replication mode enable (PASS3/CN58XX), Must be zero for other chips
365                                                      or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0.  */
366 #if 0
367         uint64_t snrepl                 : 2;   /**< Start_Node Replication (PASS3/CN58XX), Must be zero for other chips
368                                                      or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0 or IWORD0[NREPLEN] == 0.  */
369         uint64_t start_node_id          : 20;   /**< Node to start the walk from */
370 #else
371         uint64_t start_node             : 22;   /**< Node to start the walk from, includes ID and snrepl, see notes above. */
372 #endif
373
374         uint64_t unused02               :  2;   /**< Must be zero */
375         cvmx_llm_replication_t replication : 2; /**< Type of memory replication to use */
376         uint64_t unused03               :  3;   /**< Must be zero */
377         cvmx_dfa_graph_type_t type      :  1;   /**< Type of graph */
378         uint64_t unused04               :  4;   /**< Must be zero */
379         uint64_t base                   : 20;   /**< All tables start on 1KB boundary */
380
381         // WORD 1
382         uint64_t input_length           : 16;   /**< In bytes, # pointers in gather case */
383         uint64_t use_gather             :  1;   /**< Set to use gather */
384         uint64_t no_L2_alloc            :  1;   /**< Set to disable loading of the L2 cache by the DFA */
385         uint64_t full_block_write       :  1;   /**< If set, HW can write entire cache blocks @ result_ptr */
386         uint64_t little_endian          :  1;   /**< Affects only packet data, not instruction, gather list, or result */
387         uint64_t unused1                :  8;   /**< Must be zero */
388         uint64_t data_ptr               : 36;   /**< Either directly points to data or the gather list. If gather list,
389                                                     data_ptr<2:0> must be zero (i.e. 8B aligned) */
390         // WORD 2
391         uint64_t max_results            : 16;   /**< in 64-bit quantities, mbz for store */
392         uint64_t unused2                : 12;   /**< Must be zero */
393         uint64_t result_ptr             : 36;   /**< must be 128 byte aligned */
394
395         // WORD 3
396         uint64_t tsize                  :  8;   /**< tsize*256 is the number of terminal nodes for GRAPH_TYPE_SM */
397         uint64_t msize                  : 16;   /**< msize is the number of marked nodes for GRAPH_TYPE_SM */
398         uint64_t unused3                :  4;   /**< Must be zero */
399         uint64_t wq_ptr                 : 36;   /**< 0 for no work queue entry creation */
400     } s;
401 } cvmx_dfa_command_t;
402
403 /**
404  * Format of the first result word written by the hardware.
405  */
406 typedef union
407 {
408     uint64_t u64;
409     struct
410     {
411         cvmx_dfa_stop_reason_t  reas        : 2;/**< Reason the DFA stopped */
412         uint64_t                mbz         :44;/**< Zero */
413         uint64_t                last_marked : 1;/**< Set if the last entry written is marked */
414         uint64_t                done        : 1;/**< Set to 1 when the DFA completes */
415         uint64_t                num_entries :16;/**< Number of result words written */
416     } s;
417 } cvmx_dfa_result0_t;
418
419 /**
420  * Format of the second result word and subsequent result words written by the hardware.
421  */
422 typedef union
423 {
424     uint64_t u64;
425     struct
426     {
427         uint64_t byte_offset    : 16;   /**< Number of bytes consumed */
428         uint64_t extra_bits_high:  4;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
429                                              then set to <27:24> of the last next-node pointer. Else set to 0x0.  */
430         uint64_t prev_node      : 20;   /**< Index of the previous node */
431         uint64_t extra_bits_low :  2;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
432                                              then set to <23:22> of the last next-node pointer. Else set to 0x0.  */
433         uint64_t next_node_repl :  2;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1, then set
434                                              to next_node_repl (<21:20>) of the last next-node pointer. Else set to 0x0.  */
435         uint64_t current_node   : 20;   /**< Index of the current node */
436     } s;
437     struct
438     {
439         uint64_t byte_offset    : 16;   /**< Number of bytes consumed */
440         uint64_t extra_bits_high:  4;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
441                                              then set to <27:24> of the last next-node pointer. Else set to 0x0.  */
442         uint64_t prev_node      : 20;   /**< Index of the previous node */
443         uint64_t extra_bits_low :  2;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
444                                              then set to <23:22> of the last next-node pointer. Else set to 0x0.  */
445         uint64_t curr_id_and_repl:22;   /**< Use ths as start_node for continuation. */
446     } s2;
447 } cvmx_dfa_result1_t;
448
449 /**
450  * Abstract DFA graph
451  */
452 typedef struct
453 {
454     cvmx_llm_replication_t      replication;        /**< Level of memory replication to use. Must match the LLM setup */
455     cvmx_dfa_graph_type_t       type;               /**< Type of graph */
456     uint64_t                    base_address;       /**< LLM start address of the graph */
457     union {
458         struct {
459             uint64_t            gxor         : 8;   /**< Graph XOR value (PASS3/CN58XX), Must be zero for other chips
460                                                           or if DFA_CFG[GXOR_ENA] == 0.  */
461             uint64_t            nxoren       : 1;   /**< Node XOR enable (PASS3/CN58XX), Must be zero for other chips
462                                                           or if DFA_CFG[NXOR_ENA] == 0.  */
463             uint64_t            nreplen      : 1;   /**< Node Replication mode enable (PASS3/CN58XX), Must be zero for other chips
464                                                           or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0.  */
465             uint64_t            snrepl       : 2;   /**< Start_Node Replication (PASS3/CN58XX), Must be zero for other chips
466                                                           or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0 or IWORD0[NREPLEN] == 0.*/
467             uint64_t            start_node_id : 20; /**< Start node index for the root of the graph */
468         };
469         uint32_t                start_node;         /**< Start node index for the root of the graph, incl. snrepl (PASS3/CN58XX)
470                                                            NOTE: for backwards compatibility this name includes the the
471                                                                  gxor, nxoren, nreplen, and snrepl fields which will all be
472                                                                  zero in applicaitons existing before the introduction of these
473                                                                  fields, so that existing applicaiton do not need to change. */
474     };
475     int                         num_terminal_nodes; /**< Number of terminal nodes in the graph. Only needed for small graphs. */
476     int                         num_marked_nodes;   /**< Number of marked nodes in the graph. Only needed for small graphs. */
477 } cvmx_dfa_graph_t;
478
479 /**
480  * DFA internal global state -- stored in 8 bytes of FAU
481  */
482 typedef union
483 {
484     uint64_t u64;
485     struct {
486 #define CVMX_DFA_STATE_TICKET_BIT_POS 16
487 #if __BYTE_ORDER == __BIG_ENDIAN
488         // NOTE:  must clear LSB of base_address_div16 due to ticket overflow
489         uint32_t                base_address_div16;  /**< Current DFA instruction queue chunck base address/16 (clear LSB). */
490         uint8_t                 ticket_loops;        /**< bits [15:8] of total number of tickets requested. */
491         uint8_t                 ticket;              /**< bits [7:0] of total number of tickets requested (current ticket held). */
492         // NOTE: index and now_serving are written together
493         uint8_t                 now_serving;         /**< current ticket being served (or ready to be served). */
494         uint8_t                 index;               /**< index into current chunk: (base_address_div16*16)[index] = next entry. */
495 #else   // NOTE: little endian mode probably won't work
496         uint8_t                 index;
497         uint8_t                 now_serving;
498         uint8_t                 ticket;
499         uint8_t                 ticket_loops;
500         uint32_t                base_address_div16;
501 #endif
502     } s;
503     struct {    // a bitfield version of the same thing to extract base address while clearing carry.
504 #if __BYTE_ORDER == __BIG_ENDIAN
505         uint64_t                base_address_div32      : 31;   /**< Current DFA instruction queue chunck base address/32. */
506         uint64_t                carry                   : 1;    /**< Carry out from total_tickets. */
507         uint64_t                total_tickets           : 16;   /**< Total tickets. */
508         uint64_t                now_serving             : 8 ;   /**< current ticket being served (or ready to be served). */
509         uint64_t                index                   : 8 ;   /**< index into current chunk. */
510 #else   // NOTE: little endian mode probably won't work
511         uint64_t                index                   : 8 ;
512         uint64_t                now_serving             : 8 ;
513         uint64_t                total_tickets           : 16;
514         uint64_t                carry                   : 1;
515         uint64_t                base_address_div32      : 31;
516 #endif
517     } s2;
518 } cvmx_dfa_state_t;
519
520 /* CSR typedefs have been moved to cvmx-csr-*.h */
521
522 /**
523  * Write a small node edge to LLM.
524  *
525  * @param graph  Graph to modify
526  * @param source_node
527  *               Source node for this edge
528  * @param match_index
529  *               Index into the node edge table. This is the match character/2.
530  * @param destination_node0
531  *               Destination if the character matches (match_index*2).
532  * @param destination_node1
533  *               Destination if the character matches (match_index*2+1).
534  */
535 static inline void cvmx_dfa_write_edge_sm(const cvmx_dfa_graph_t *graph,
536                                          uint64_t source_node, uint64_t match_index,
537                                          uint64_t destination_node0, uint64_t destination_node1)
538 {
539     cvmx_llm_address_t address;
540     cvmx_dfa_node_next_t    next_ptr;
541
542     address.u64 = graph->base_address + source_node * CVMX_DFA_NODESM_SIZE + match_index * 4;
543
544     next_ptr.u64 = 0;
545     if (OCTEON_IS_MODEL(OCTEON_CN31XX))
546     {
547         next_ptr.sm.w32.next_node0 = destination_node0;
548         next_ptr.sm.w32.p0 = cvmx_llm_parity(destination_node0);
549
550         next_ptr.sm.w32.next_node1 = destination_node1;
551         next_ptr.sm.w32.p1 = cvmx_llm_parity(destination_node1);
552     }
553     else
554     {
555         next_ptr.sm.w36.next_node0 = destination_node0;
556         next_ptr.sm.w36.p0 = cvmx_llm_parity(destination_node0);
557
558         next_ptr.sm.w36.next_node1 = destination_node1;
559         next_ptr.sm.w36.p1 = cvmx_llm_parity(destination_node1);
560     }
561
562     cvmx_llm_write36(address, next_ptr.u64, 0);
563 }
564 #ifdef ENABLE_DEPRECATED
565 #define cvmx_dfa_write_edge18 cvmx_dfa_write_edge_sm
566 #endif
567
568
569 /**
570  * Write a large node edge to LLM.
571  *
572  * @param graph  Graph to modify
573  * @param source_node
574  *               Source node for this edge
575  * @param match  Character to match before taking this edge.
576  * @param destination_node
577  *               Destination node of the edge.
578  * @param destination_type
579  *               Node type at the end of this edge.
580  */
581 static inline void cvmx_dfa_write_node_lg(const cvmx_dfa_graph_t *graph,
582                                          uint64_t source_node, unsigned char match,
583                                          uint64_t destination_node, cvmx_dfa_node_type_t destination_type)
584 {
585     cvmx_llm_address_t      address;
586     cvmx_dfa_node_next_t    next_ptr;
587
588     address.u64 = graph->base_address + source_node * CVMX_DFA_NODELG_SIZE + (uint64_t)match * 4;
589
590     next_ptr.u64 = 0;
591     if (OCTEON_IS_MODEL(OCTEON_CN31XX))
592     {
593         next_ptr.lg.w32.type = destination_type;
594         next_ptr.lg.w32.next_node = destination_node;
595         next_ptr.lg.w32.ecc = cvmx_llm_ecc(next_ptr.u64);
596     }
597     else
598     {
599         next_ptr.lg.w36.type = destination_type;
600         next_ptr.lg.w36.next_node = destination_node;
601         next_ptr.lg.w36.ecc = cvmx_llm_ecc(next_ptr.u64);
602     }
603
604     cvmx_llm_write36(address, next_ptr.u64, 0);
605 }
606 #ifdef ENABLE_DEPRECATED
607 #define cvmx_dfa_write_node36 cvmx_dfa_write_node_lg
608 #endif
609
610 /**
611  * Ring the DFA doorbell telling it that new commands are
612  * available.
613  *
614  * @param num_commands
615  *               Number of new commands
616  */
617 static inline void cvmx_dfa_write_doorbell(uint64_t num_commands)
618 {
619     CVMX_SYNCWS;
620     cvmx_write_csr(CVMX_DFA_DBELL, num_commands);
621 }
622
623 /**
624  * @INTERNAL
625  * Write a new command to the DFA. Calls to this function
626  * are internally synchronized across all processors, and
627  * the doorbell is rung during this function.
628  *
629  * @param command Command to write
630  */
631
632 #ifdef CVMX_ENABLE_DFA_FUNCTIONS
633 static inline void __cvmx_dfa_write_command(cvmx_dfa_command_t *command)
634 {
635     cvmx_dfa_state_t cvmx_dfa_state;
636     uint64_t my_ticket; // needs to wrap to 8 bits
637     uint64_t index;
638     cvmx_dfa_command_t *head;
639
640     CVMX_PREFETCH0(command);
641     // take a ticket.
642     cvmx_dfa_state.u64 = cvmx_fau_fetch_and_add64(CVMX_FAU_DFA_STATE, 1ull<<CVMX_DFA_STATE_TICKET_BIT_POS);
643     my_ticket = cvmx_dfa_state.s.ticket;
644
645     // see if it is our turn
646     while (my_ticket != cvmx_dfa_state.s.now_serving) {
647         int delta = my_ticket - cvmx_dfa_state.s.now_serving;
648         if (delta < 0) delta += 256;
649         cvmx_wait(10*delta);    // reduce polling load on system
650         cvmx_dfa_state.u64 = cvmx_fau_fetch_and_add64(CVMX_FAU_DFA_STATE, 0);           // poll for my_ticket==now_serving
651     }
652
653     // compute index and instruction queue head pointer
654     index = cvmx_dfa_state.s.index;
655
656     // NOTE: the DFA only supports 36-bit addressing
657     head = &((CASTPTR(cvmx_dfa_command_t, (cvmx_dfa_state.s2.base_address_div32 * 32ull))[index]));
658     head = (cvmx_dfa_command_t*)cvmx_phys_to_ptr(CAST64(head)); // NOTE: since we are not storing bit 63 of address, we must set it now
659
660     // copy the command to the instruction queue
661     *head++ = *command;
662
663     // check if a new chunk is needed
664     if (cvmx_unlikely((++index >= ((CVMX_FPA_DFA_POOL_SIZE-8)/sizeof(cvmx_dfa_command_t))))) {
665         uint64_t *new_base = (uint64_t*)cvmx_fpa_alloc(CVMX_FPA_DFA_POOL);      // could make this async
666         if (new_base) {
667             // put the link into the instruction queue's "Next Chunk Buffer Ptr"
668             *(uint64_t *)head = cvmx_ptr_to_phys(new_base);
669             // update our state (note 32-bit write to not disturb other fields)
670             cvmx_fau_atomic_write32((cvmx_fau_reg_32_t)(CVMX_FAU_DFA_STATE + (CAST64(&cvmx_dfa_state.s.base_address_div16)-CAST64(&cvmx_dfa_state))),
671                     (CAST64(new_base))/16);
672         }
673         else {
674             cvmx_dprintf("__cvmx_dfa_write_command: Out of memory. Expect crashes.\n");
675         }
676         index=0;
677     }
678
679     cvmx_dfa_write_doorbell(1);
680
681     // update index and now_serving in the DFA state FAU location (NOTE: this write16 updates to 8-bit values.)
682     // NOTE: my_ticket+1 carry out is lost due to write16 and index has already been wrapped to fit in uint8.
683     cvmx_fau_atomic_write16((cvmx_fau_reg_16_t)(CVMX_FAU_DFA_STATE+(CAST64(&cvmx_dfa_state.s.now_serving) - CAST64(&cvmx_dfa_state))),
684             ((my_ticket+1)<<8) | index);
685 }
686
687
688 /**
689  * Submit work to the DFA units for processing
690  *
691  * @param graph   Graph to process
692  * @param start_node
693  *                The node to start (or continue) walking from
694  *                includes. start_node_id and snrepl (PASS3/CN58XX), but gxor,
695  *                nxoren, and nreplen are taken from the graph structure
696  * @param input   The input to match against
697  * @param input_length
698  *                The length of the input in bytes
699  * @param use_gather
700  *                The input and input_length are of a gather list
701  * @param is_little_endian
702  *                Set to 1 if the input is in little endian format and must
703  *                be swapped before compare.
704  * @param result  Location the DFA should put the results in. This must be
705  *                an area sized in multiples of a cache line.
706  * @param max_results
707  *                The maximum number of 64-bit result1 words after result0.
708  *                That is, "size of the result area in 64-bit words" - 1.
709  *                max_results must be at least 1.
710  * @param work    Work queue entry to submit when DFA completes. Can be NULL.
711  */
712 static inline void cvmx_dfa_submit(const cvmx_dfa_graph_t *graph, int start_node,
713                                   void *input, int input_length, int use_gather, int is_little_endian,
714                                   cvmx_dfa_result0_t *result, int max_results, cvmx_wqe_t *work)
715 {
716     cvmx_dfa_command_t command;
717
718     /* Make sure the result's first 64bit word is zero so we can tell when the
719         DFA is done. */
720     result->u64 = 0;
721
722     // WORD 0
723     command.u64[0] = 0;
724     command.s.gxor          = graph->gxor;      // (PASS3/CN58XX)
725     command.s.nxoren        = graph->nxoren;    // (PASS3/CN58XX)
726     command.s.nreplen       = graph->nreplen;   // (PASS3/CN58XX)
727     command.s.start_node    = start_node;       // includes snrepl (PASS3/CN58XX)
728     command.s.replication   = graph->replication;
729     command.s.type          = graph->type;
730     command.s.base          = graph->base_address>>10;
731
732     // WORD 1
733     command.u64[1] = 0;
734     command.s.input_length  = input_length;
735     command.s.use_gather   = use_gather;
736     command.s.no_L2_alloc   = 0;
737     command.s.full_block_write = 1;
738     command.s.little_endian = is_little_endian;
739     command.s.data_ptr      = cvmx_ptr_to_phys(input);
740
741     // WORD 2
742     command.u64[2] = 0;
743     command.s.max_results   = max_results;
744     command.s.result_ptr    = cvmx_ptr_to_phys(result);
745
746     // WORD 3
747     command.u64[3] = 0;
748     if (graph->type == CVMX_DFA_GRAPH_TYPE_SM)
749     {
750         command.s.tsize     = (graph->num_terminal_nodes + 255) / 256;
751         command.s.msize     = graph->num_marked_nodes;
752     }
753     command.s.wq_ptr        = cvmx_ptr_to_phys(work);
754
755     __cvmx_dfa_write_command(&command); // NOTE: this does synchronization and rings doorbell
756 }
757 #endif
758
759 /**
760  * DFA gather list element
761  */
762 typedef struct {
763     uint64_t length         : 16;   /**< length of piece of data at addr */
764     uint64_t reserved       : 12;   /**< reserved, set to 0 */
765     uint64_t addr           : 36;   /**< pointer to piece of data */
766 } cvmx_dfa_gather_entry_t;
767
768
769 /**
770  * Check if a DFA has completed processing
771  *
772  * @param result_ptr Result area the DFA is using
773  * @return Non zero if the DFA is done
774  */
775 static inline uint64_t cvmx_dfa_is_done(cvmx_dfa_result0_t *result_ptr)
776 {
777     /* DFA sets the first result 64bit word to non zero when it's done */
778     return ((volatile cvmx_dfa_result0_t *)result_ptr)->s.done;
779 }
780
781
782 #ifdef CVMX_ENABLE_DFA_FUNCTIONS
783 /**
784  * Initialize the DFA hardware before use
785  * Returns 0 on success, -1 on failure
786  */
787 int cvmx_dfa_initialize(void);
788
789
790 /**
791  * Shutdown and cleanup resources used by the DFA
792  */
793 void cvmx_dfa_shutdown(void);
794 #endif
795
796 #ifdef  __cplusplus
797 }
798 #endif
799
800 #endif /* __CVMX_DFA_H__ */