1 /***********************license start***************
2 * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
18 * * Neither the name of Cavium Inc. nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written
23 * This Software, including technical data, may be subject to U.S. export control
24 * laws, including the U.S. Export Administration Act and its associated
25 * regulations, and may be subject to export or import regulations in other
28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
37 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38 ***********************license end**************************************/
49 * Interface to the CN31XX, CN38XX, and CN58XX hardware DFA engine.
51 * <hr>$Revision: 70030 $<hr>
54 #ifndef __CVMX_DFA_H__
55 #define __CVMX_DFA_H__
60 #include "executive-config.h"
61 #ifdef CVMX_ENABLE_DFA_FUNCTIONS
62 #include "cvmx-config.h"
65 #define ENABLE_DEPRECATED /* Set to enable the old 18/36 bit names */
72 /* Maximum nodes available in a small encoding */
73 #define CVMX_DFA_NODESM_MAX_NODES ((OCTEON_IS_MODEL(OCTEON_CN31XX)) ? 0x8000 : 0x20000)
74 #define CVMX_DFA_NODESM_SIZE 512 /* Size of each node for small encoding */
75 #define CVMX_DFA_NODELG_SIZE 1024 /* Size of each node for large encoding */
76 #define CVMX_DFA_NODESM_LAST_TERMINAL (CVMX_DFA_NODESM_MAX_NODES-1)
78 #ifdef ENABLE_DEPRECATED
79 /* These defines are for compatability with old code. They are deprecated */
80 #define CVMX_DFA_NODE18_SIZE CVMX_DFA_NODESM_SIZE
81 #define CVMX_DFA_NODE36_SIZE CVMX_DFA_NODELG_SIZE
82 #define CVMX_DFA_NODE18_MAX_NODES CVMX_DFA_NODESM_MAX_NODES
83 #define CVMX_DFA_NODE18_LAST_TERMINAL CVMX_DFA_NODESM_LAST_TERMINAL
87 * Which type of memory encoding is this graph using. Make sure you setup
92 CVMX_DFA_GRAPH_TYPE_SM = 0,
93 CVMX_DFA_GRAPH_TYPE_LG = 1,
94 #ifdef ENABLE_DEPRECATED
95 CVMX_DFA_GRAPH_TYPE_18b = 0, /* Deprecated */
96 CVMX_DFA_GRAPH_TYPE_36b = 1 /* Deprecated */
98 } cvmx_dfa_graph_type_t;
101 * The possible node types.
105 CVMX_DFA_NODE_TYPE_NORMAL = 0, /**< Node is a branch */
106 CVMX_DFA_NODE_TYPE_MARKED = 1, /**< Node is marked special */
107 CVMX_DFA_NODE_TYPE_TERMINAL = 2 /**< Node is a terminal leaf */
108 } cvmx_dfa_node_type_t;
111 * The possible reasons the DFA stopped processing.
115 CVMX_DFA_STOP_REASON_DATA_GONE = 0, /**< DFA ran out of data */
116 CVMX_DFA_STOP_REASON_PARITY_ERROR = 1, /**< DFA encountered a memory error */
117 CVMX_DFA_STOP_REASON_FULL = 2, /**< DFA is full */
118 CVMX_DFA_STOP_REASON_TERMINAL = 3 /**< DFA hit a terminal */
119 } cvmx_dfa_stop_reason_t;
122 * This format describes the DFA pointers in small mode
129 uint64_t mbz :32;/**< Must be zero */
130 uint64_t p1 : 1;/**< Set if next_node1 is odd parity */
131 uint64_t next_node1 :15;/**< Next node if an odd character match */
132 uint64_t p0 : 1;/**< Set if next_node0 is odd parity */
133 uint64_t next_node0 :15;/**< Next node if an even character match */
137 uint64_t mbz :28;/**< Must be zero */
138 uint64_t p1 : 1;/**< Set if next_node1 is odd parity */
139 uint64_t next_node1 :17;/**< Next node if an odd character match */
140 uint64_t p0 : 1;/**< Set if next_node0 is odd parity */
141 uint64_t next_node0 :17;/**< Next node if an even character match */
143 struct /**< @ this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1. */
145 uint64_t mbz :28;/**< Must be zero */
146 uint64_t p1 : 1;/**< Set if next_node1 is odd parity */
147 uint64_t per_node_repl1 : 1;/**< enable for extra replicaiton for next node (CN58XX) */
148 uint64_t next_node_repl1 : 2;/**< extra replicaiton for next node (CN58XX) (if per_node_repl1 is set) */
149 uint64_t next_node1 :14;/**< Next node if an odd character match - IWORD3[Msize], if per_node_repl1==1. */
150 uint64_t p0 : 1;/**< Set if next_node0 is odd parity */
151 uint64_t per_node_repl0 : 1;/**< enable for extra replicaiton for next node (CN58XX) */
152 uint64_t next_node_repl0 : 2;/**< extra replicaiton for next node (CN58XX) (if per_node_repl0 is set) */
153 uint64_t next_node0 :14;/**< Next node if an odd character match - IWORD3[Msize], if per_node_repl0==1. */
154 } w36nrepl_en; /**< use when next_node_repl[01] is 1. */
155 struct /**< this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1. */
157 uint64_t mbz :28;/**< Must be zero */
158 uint64_t p1 : 1;/**< Set if next_node1 is odd parity */
159 uint64_t per_node_repl1 : 1;/**< enable for extra replicaiton for next node (CN58XX) */
160 uint64_t next_node1 :16;/**< Next node if an odd character match, if per_node_repl1==0. */
161 uint64_t p0 : 1;/**< Set if next_node0 is odd parity */
162 uint64_t per_node_repl0 : 1;/**< enable for extra replicaiton for next node (CN58XX) */
163 uint64_t next_node0 :16;/**< Next node if an odd character match, if per_node_repl0==0. */
164 } w36nrepl_dis; /**< use when next_node_repl[01] is 0. */
165 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
166 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
167 struct /**< @deprecated unnamed reference to members */
169 uint64_t mbz :32;/**< Must be zero */
170 uint64_t p1 : 1;/**< Set if next_node1 is odd parity */
171 uint64_t next_node1 :15;/**< Next node if an odd character match */
172 uint64_t p0 : 1;/**< Set if next_node0 is odd parity */
173 uint64_t next_node0 :15;/**< Next node if an even character match */
175 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
176 struct /**< @deprecated unnamed reference to members */
178 uint64_t mbz :28;/**< Must be zero */
179 uint64_t p1 : 1;/**< Set if next_node1 is odd parity */
180 uint64_t next_node1 :17;/**< Next node if an odd character match */
181 uint64_t p0 : 1;/**< Set if next_node0 is odd parity */
182 uint64_t next_node0 :17;/**< Next node if an even character match */
185 /* Other chips don't support the deprecated unnamed unions */
188 } cvmx_dfa_node_next_sm_t;
191 * This format describes the DFA pointers in large mode
198 uint64_t mbz :32;/**< Must be zero */
199 uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */
200 cvmx_dfa_node_type_t type : 2;/**< Node type */
201 uint64_t mbz2 : 3;/**< Must be zero */
202 uint64_t next_node :20;/**< Next node */
206 uint64_t mbz :28;/**< Must be zero */
207 uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */
208 cvmx_dfa_node_type_t type : 2;/**< Node type */
209 uint64_t extra_bits : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
210 uint64_t next_node_repl : 2;/**< extra replicaiton for next node (PASS3/CN58XX), Must be zero previously */
211 uint64_t next_node :20;/**< Next node ID, Note, combine with next_node_repl to use as start_node
212 for continuation, as in cvmx_dfa_node_next_lgb_t. */
214 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
215 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
216 struct /**< @deprecated unnamed reference to members */
218 uint64_t mbz :32;/**< Must be zero */
219 uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */
220 cvmx_dfa_node_type_t type : 2;/**< Node type */
221 uint64_t mbz2 : 3;/**< Must be zero */
222 uint64_t next_node :20;/**< Next node */
224 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
225 struct /**< @deprecated unnamed reference to members */
227 uint64_t mbz :28;/**< Must be zero */
228 uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */
229 cvmx_dfa_node_type_t type : 2;/**< Node type */
230 uint64_t extra_bits : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
231 uint64_t next_node_repl : 2;/**< extra replicaiton for next node (PASS3/CN58XX), Must be zero previously */
232 uint64_t next_node :20;/**< Next node ID, Note, combine with next_node_repl to use as start_node
233 for continuation, as in cvmx_dfa_node_next_lgb_t. */
236 /* Other chips don't support the deprecated unnamed unions */
239 } cvmx_dfa_node_next_lg_t;
242 * This format describes the DFA pointers in large mode, another way
249 uint64_t mbz :32;/**< Must be zero */
250 uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */
251 uint64_t type_terminal : 1;/**< Node type */
252 uint64_t type_marked : 1;/**< Node type */
253 uint64_t mbz2 : 3;/**< Must be zero */
254 uint64_t next_node :20;/**< Next node */
258 uint64_t mbz :28;/**< Must be zero */
259 uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */
260 uint64_t type_terminal : 1;/**< Node type */
261 uint64_t type_marked : 1;/**< Node type */
262 uint64_t extra_bits : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
263 uint64_t next_node_id_and_repl :22;/**< Next node ID (and repl for PASS3/CN58XX or repl=0 if not),
264 use this as start node for continuation. */
266 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
267 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
268 struct /**< @deprecated unnamed reference to members */
270 uint64_t mbz :32;/**< Must be zero */
271 uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */
272 uint64_t type_terminal : 1;/**< Node type */
273 uint64_t type_marked : 1;/**< Node type */
274 uint64_t mbz2 : 3;/**< Must be zero */
275 uint64_t next_node :20;/**< Next node */
277 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
278 struct /**< @deprecated unnamed reference to members */
280 uint64_t mbz :28;/**< Must be zero */
281 uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */
282 uint64_t type_terminal : 1;/**< Node type */
283 uint64_t type_marked : 1;/**< Node type */
284 uint64_t extra_bits : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
285 uint64_t next_node_id_and_repl :22;/**< Next node ID (and repl for PASS3/CN58XX or repl=0 if not),
286 use this as start node for continuation. */
289 /* Other chips don't support the deprecated unnamed unions */
292 } cvmx_dfa_node_next_lgb_t;
295 * This format describes the DFA pointers in large mode
302 uint64_t mbz :27;/**< Must be zero */
303 uint64_t x0 : 1;/**< XOR of the rest of the bits */
304 uint64_t reserved : 4;/**< Must be zero */
305 uint64_t data :32;/**< LLM Data */
309 uint64_t mbz :27;/**< Must be zero */
310 uint64_t x0 : 1;/**< XOR of the rest of the bits */
311 uint64_t data :36;/**< LLM Data */
313 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
314 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
315 struct /**< @deprecated unnamed reference to members */
317 uint64_t mbz :27;/**< Must be zero */
318 uint64_t x0 : 1;/**< XOR of the rest of the bits */
319 uint64_t reserved : 4;/**< Must be zero */
320 uint64_t data :32;/**< LLM Data */
322 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
323 struct /**< @deprecated unnamed reference to members */
325 uint64_t mbz :27;/**< Must be zero */
326 uint64_t x0 : 1;/**< XOR of the rest of the bits */
327 uint64_t data :36;/**< LLM Data */
330 /* Other chips don't support the deprecated unnamed unions */
333 } cvmx_dfa_node_next_read_t;
336 * This structure defines the data format in the low-latency memory
341 cvmx_dfa_node_next_sm_t sm; /**< This format describes the DFA pointers in small mode */
342 cvmx_dfa_node_next_lg_t lg; /**< This format describes the DFA pointers in large mode */
343 cvmx_dfa_node_next_lgb_t lgb; /**< This format describes the DFA pointers in large mode, another way */
344 cvmx_dfa_node_next_read_t read; /**< This format describes the DFA pointers in large mode */
345 #ifdef ENABLE_DEPRECATED
346 cvmx_dfa_node_next_sm_t s18; /**< Deprecated */
347 cvmx_dfa_node_next_lg_t s36; /**< Deprecated */
348 cvmx_dfa_node_next_lgb_t s36b; /**< Deprecated */
350 } cvmx_dfa_node_next_t;
353 * These structures define a DFA instruction
362 uint64_t gxor : 8; /**< Graph XOR value (PASS3/CN58XX), Must be zero for other chips
363 or if DFA_CFG[GXOR_ENA] == 0. */
364 uint64_t nxoren : 1; /**< Node XOR enable (PASS3/CN58XX), Must be zero for other chips
365 or if DFA_CFG[NXOR_ENA] == 0. */
366 uint64_t nreplen : 1; /**< Node Replication mode enable (PASS3/CN58XX), Must be zero for other chips
367 or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0. */
369 uint64_t snrepl : 2; /**< Start_Node Replication (PASS3/CN58XX), Must be zero for other chips
370 or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0 or IWORD0[NREPLEN] == 0. */
371 uint64_t start_node_id : 20; /**< Node to start the walk from */
373 uint64_t start_node : 22; /**< Node to start the walk from, includes ID and snrepl, see notes above. */
376 uint64_t unused02 : 2; /**< Must be zero */
377 cvmx_llm_replication_t replication : 2; /**< Type of memory replication to use */
378 uint64_t unused03 : 3; /**< Must be zero */
379 cvmx_dfa_graph_type_t type : 1; /**< Type of graph */
380 uint64_t unused04 : 4; /**< Must be zero */
381 uint64_t base : 20; /**< All tables start on 1KB boundary */
384 uint64_t input_length : 16; /**< In bytes, # pointers in gather case */
385 uint64_t use_gather : 1; /**< Set to use gather */
386 uint64_t no_L2_alloc : 1; /**< Set to disable loading of the L2 cache by the DFA */
387 uint64_t full_block_write : 1; /**< If set, HW can write entire cache blocks @ result_ptr */
388 uint64_t little_endian : 1; /**< Affects only packet data, not instruction, gather list, or result */
389 uint64_t unused1 : 8; /**< Must be zero */
390 uint64_t data_ptr : 36; /**< Either directly points to data or the gather list. If gather list,
391 data_ptr<2:0> must be zero (i.e. 8B aligned) */
393 uint64_t max_results : 16; /**< in 64-bit quantities, mbz for store */
394 uint64_t unused2 : 12; /**< Must be zero */
395 uint64_t result_ptr : 36; /**< must be 128 byte aligned */
398 uint64_t tsize : 8; /**< tsize*256 is the number of terminal nodes for GRAPH_TYPE_SM */
399 uint64_t msize : 16; /**< msize is the number of marked nodes for GRAPH_TYPE_SM */
400 uint64_t unused3 : 4; /**< Must be zero */
401 uint64_t wq_ptr : 36; /**< 0 for no work queue entry creation */
403 } cvmx_dfa_command_t;
406 * Format of the first result word written by the hardware.
413 cvmx_dfa_stop_reason_t reas : 2;/**< Reason the DFA stopped */
414 uint64_t mbz :44;/**< Zero */
415 uint64_t last_marked : 1;/**< Set if the last entry written is marked */
416 uint64_t done : 1;/**< Set to 1 when the DFA completes */
417 uint64_t num_entries :16;/**< Number of result words written */
419 } cvmx_dfa_result0_t;
422 * Format of the second result word and subsequent result words written by the hardware.
429 uint64_t byte_offset : 16; /**< Number of bytes consumed */
430 uint64_t extra_bits_high: 4; /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
431 then set to <27:24> of the last next-node pointer. Else set to 0x0. */
432 uint64_t prev_node : 20; /**< Index of the previous node */
433 uint64_t extra_bits_low : 2; /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
434 then set to <23:22> of the last next-node pointer. Else set to 0x0. */
435 uint64_t next_node_repl : 2; /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1, then set
436 to next_node_repl (<21:20>) of the last next-node pointer. Else set to 0x0. */
437 uint64_t current_node : 20; /**< Index of the current node */
441 uint64_t byte_offset : 16; /**< Number of bytes consumed */
442 uint64_t extra_bits_high: 4; /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
443 then set to <27:24> of the last next-node pointer. Else set to 0x0. */
444 uint64_t prev_node : 20; /**< Index of the previous node */
445 uint64_t extra_bits_low : 2; /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
446 then set to <23:22> of the last next-node pointer. Else set to 0x0. */
447 uint64_t curr_id_and_repl:22; /**< Use ths as start_node for continuation. */
449 } cvmx_dfa_result1_t;
456 cvmx_llm_replication_t replication; /**< Level of memory replication to use. Must match the LLM setup */
457 cvmx_dfa_graph_type_t type; /**< Type of graph */
458 uint64_t base_address; /**< LLM start address of the graph */
461 uint64_t gxor : 8; /**< Graph XOR value (PASS3/CN58XX), Must be zero for other chips
462 or if DFA_CFG[GXOR_ENA] == 0. */
463 uint64_t nxoren : 1; /**< Node XOR enable (PASS3/CN58XX), Must be zero for other chips
464 or if DFA_CFG[NXOR_ENA] == 0. */
465 uint64_t nreplen : 1; /**< Node Replication mode enable (PASS3/CN58XX), Must be zero for other chips
466 or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0. */
467 uint64_t snrepl : 2; /**< Start_Node Replication (PASS3/CN58XX), Must be zero for other chips
468 or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0 or IWORD0[NREPLEN] == 0.*/
469 uint64_t start_node_id : 20; /**< Start node index for the root of the graph */
471 uint32_t start_node; /**< Start node index for the root of the graph, incl. snrepl (PASS3/CN58XX)
472 NOTE: for backwards compatibility this name includes the the
473 gxor, nxoren, nreplen, and snrepl fields which will all be
474 zero in applicaitons existing before the introduction of these
475 fields, so that existing applicaiton do not need to change. */
477 int num_terminal_nodes; /**< Number of terminal nodes in the graph. Only needed for small graphs. */
478 int num_marked_nodes; /**< Number of marked nodes in the graph. Only needed for small graphs. */
482 * DFA internal global state -- stored in 8 bytes of FAU
488 #define CVMX_DFA_STATE_TICKET_BIT_POS 16
489 #ifdef __BIG_ENDIAN_BITFIELD
490 // NOTE: must clear LSB of base_address_div16 due to ticket overflow
491 uint32_t base_address_div16; /**< Current DFA instruction queue chunck base address/16 (clear LSB). */
492 uint8_t ticket_loops; /**< bits [15:8] of total number of tickets requested. */
493 uint8_t ticket; /**< bits [7:0] of total number of tickets requested (current ticket held). */
494 // NOTE: index and now_serving are written together
495 uint8_t now_serving; /**< current ticket being served (or ready to be served). */
496 uint8_t index; /**< index into current chunk: (base_address_div16*16)[index] = next entry. */
497 #else // NOTE: little endian mode probably won't work
501 uint8_t ticket_loops;
502 uint32_t base_address_div16;
505 struct { // a bitfield version of the same thing to extract base address while clearing carry.
506 #ifdef __BIG_ENDIAN_BITFIELD
507 uint64_t base_address_div32 : 31; /**< Current DFA instruction queue chunck base address/32. */
508 uint64_t carry : 1; /**< Carry out from total_tickets. */
509 uint64_t total_tickets : 16; /**< Total tickets. */
510 uint64_t now_serving : 8 ; /**< current ticket being served (or ready to be served). */
511 uint64_t index : 8 ; /**< index into current chunk. */
512 #else // NOTE: little endian mode probably won't work
514 uint64_t now_serving : 8 ;
515 uint64_t total_tickets : 16;
517 uint64_t base_address_div32 : 31;
522 /* CSR typedefs have been moved to cvmx-dfa-defs.h */
525 * Write a small node edge to LLM.
527 * @param graph Graph to modify
529 * Source node for this edge
531 * Index into the node edge table. This is the match character/2.
532 * @param destination_node0
533 * Destination if the character matches (match_index*2).
534 * @param destination_node1
535 * Destination if the character matches (match_index*2+1).
537 static inline void cvmx_dfa_write_edge_sm(const cvmx_dfa_graph_t *graph,
538 uint64_t source_node, uint64_t match_index,
539 uint64_t destination_node0, uint64_t destination_node1)
541 cvmx_llm_address_t address;
542 cvmx_dfa_node_next_t next_ptr;
544 address.u64 = graph->base_address + source_node * CVMX_DFA_NODESM_SIZE + match_index * 4;
547 if (OCTEON_IS_MODEL(OCTEON_CN31XX))
549 next_ptr.sm.w32.next_node0 = destination_node0;
550 next_ptr.sm.w32.p0 = cvmx_llm_parity(destination_node0);
552 next_ptr.sm.w32.next_node1 = destination_node1;
553 next_ptr.sm.w32.p1 = cvmx_llm_parity(destination_node1);
557 next_ptr.sm.w36.next_node0 = destination_node0;
558 next_ptr.sm.w36.p0 = cvmx_llm_parity(destination_node0);
560 next_ptr.sm.w36.next_node1 = destination_node1;
561 next_ptr.sm.w36.p1 = cvmx_llm_parity(destination_node1);
564 cvmx_llm_write36(address, next_ptr.u64, 0);
566 #ifdef ENABLE_DEPRECATED
567 #define cvmx_dfa_write_edge18 cvmx_dfa_write_edge_sm
572 * Write a large node edge to LLM.
574 * @param graph Graph to modify
576 * Source node for this edge
577 * @param match Character to match before taking this edge.
578 * @param destination_node
579 * Destination node of the edge.
580 * @param destination_type
581 * Node type at the end of this edge.
583 static inline void cvmx_dfa_write_node_lg(const cvmx_dfa_graph_t *graph,
584 uint64_t source_node, unsigned char match,
585 uint64_t destination_node, cvmx_dfa_node_type_t destination_type)
587 cvmx_llm_address_t address;
588 cvmx_dfa_node_next_t next_ptr;
590 address.u64 = graph->base_address + source_node * CVMX_DFA_NODELG_SIZE + (uint64_t)match * 4;
593 if (OCTEON_IS_MODEL(OCTEON_CN31XX))
595 next_ptr.lg.w32.type = destination_type;
596 next_ptr.lg.w32.next_node = destination_node;
597 next_ptr.lg.w32.ecc = cvmx_llm_ecc(next_ptr.u64);
601 next_ptr.lg.w36.type = destination_type;
602 next_ptr.lg.w36.next_node = destination_node;
603 next_ptr.lg.w36.ecc = cvmx_llm_ecc(next_ptr.u64);
606 cvmx_llm_write36(address, next_ptr.u64, 0);
608 #ifdef ENABLE_DEPRECATED
609 #define cvmx_dfa_write_node36 cvmx_dfa_write_node_lg
613 * Ring the DFA doorbell telling it that new commands are
616 * @param num_commands
617 * Number of new commands
619 static inline void cvmx_dfa_write_doorbell(uint64_t num_commands)
622 cvmx_write_csr(CVMX_DFA_DBELL, num_commands);
627 * Write a new command to the DFA. Calls to this function
628 * are internally synchronized across all processors, and
629 * the doorbell is rung during this function.
631 * @param command Command to write
634 #ifdef CVMX_ENABLE_DFA_FUNCTIONS
635 static inline void __cvmx_dfa_write_command(cvmx_dfa_command_t *command)
637 cvmx_dfa_state_t cvmx_dfa_state;
638 uint64_t my_ticket; // needs to wrap to 8 bits
640 cvmx_dfa_command_t *head;
642 CVMX_PREFETCH0(command);
644 cvmx_dfa_state.u64 = cvmx_fau_fetch_and_add64(CVMX_FAU_DFA_STATE, 1ull<<CVMX_DFA_STATE_TICKET_BIT_POS);
645 my_ticket = cvmx_dfa_state.s.ticket;
647 // see if it is our turn
648 while (my_ticket != cvmx_dfa_state.s.now_serving) {
649 int delta = my_ticket - cvmx_dfa_state.s.now_serving;
650 if (delta < 0) delta += 256;
651 cvmx_wait(10*delta); // reduce polling load on system
652 cvmx_dfa_state.u64 = cvmx_fau_fetch_and_add64(CVMX_FAU_DFA_STATE, 0); // poll for my_ticket==now_serving
655 // compute index and instruction queue head pointer
656 index = cvmx_dfa_state.s.index;
658 // NOTE: the DFA only supports 36-bit addressing
659 head = &((CASTPTR(cvmx_dfa_command_t, (cvmx_dfa_state.s2.base_address_div32 * 32ull))[index]));
660 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
662 // copy the command to the instruction queue
665 // check if a new chunk is needed
666 if (cvmx_unlikely((++index >= ((CVMX_FPA_DFA_POOL_SIZE-8)/sizeof(cvmx_dfa_command_t))))) {
667 uint64_t *new_base = (uint64_t*)cvmx_fpa_alloc(CVMX_FPA_DFA_POOL); // could make this async
669 // put the link into the instruction queue's "Next Chunk Buffer Ptr"
670 *(uint64_t *)head = cvmx_ptr_to_phys(new_base);
671 // update our state (note 32-bit write to not disturb other fields)
672 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))),
673 (CAST64(new_base))/16);
676 cvmx_dprintf("__cvmx_dfa_write_command: Out of memory. Expect crashes.\n");
681 cvmx_dfa_write_doorbell(1);
683 // update index and now_serving in the DFA state FAU location (NOTE: this write16 updates to 8-bit values.)
684 // NOTE: my_ticket+1 carry out is lost due to write16 and index has already been wrapped to fit in uint8.
685 cvmx_fau_atomic_write16((cvmx_fau_reg_16_t)(CVMX_FAU_DFA_STATE+(CAST64(&cvmx_dfa_state.s.now_serving) - CAST64(&cvmx_dfa_state))),
686 ((my_ticket+1)<<8) | index);
691 * Submit work to the DFA units for processing
693 * @param graph Graph to process
695 * The node to start (or continue) walking from
696 * includes. start_node_id and snrepl (PASS3/CN58XX), but gxor,
697 * nxoren, and nreplen are taken from the graph structure
698 * @param input The input to match against
699 * @param input_length
700 * The length of the input in bytes
702 * The input and input_length are of a gather list
703 * @param is_little_endian
704 * Set to 1 if the input is in little endian format and must
705 * be swapped before compare.
706 * @param result Location the DFA should put the results in. This must be
707 * an area sized in multiples of a cache line.
709 * The maximum number of 64-bit result1 words after result0.
710 * That is, "size of the result area in 64-bit words" - 1.
711 * max_results must be at least 1.
712 * @param work Work queue entry to submit when DFA completes. Can be NULL.
714 static inline void cvmx_dfa_submit(const cvmx_dfa_graph_t *graph, int start_node,
715 void *input, int input_length, int use_gather, int is_little_endian,
716 cvmx_dfa_result0_t *result, int max_results, cvmx_wqe_t *work)
718 cvmx_dfa_command_t command;
720 /* Make sure the result's first 64bit word is zero so we can tell when the
726 command.s.gxor = graph->gxor; // (PASS3/CN58XX)
727 command.s.nxoren = graph->nxoren; // (PASS3/CN58XX)
728 command.s.nreplen = graph->nreplen; // (PASS3/CN58XX)
729 command.s.start_node = start_node; // includes snrepl (PASS3/CN58XX)
730 command.s.replication = graph->replication;
731 command.s.type = graph->type;
732 command.s.base = graph->base_address>>10;
736 command.s.input_length = input_length;
737 command.s.use_gather = use_gather;
738 command.s.no_L2_alloc = 0;
739 command.s.full_block_write = 1;
740 command.s.little_endian = is_little_endian;
741 command.s.data_ptr = cvmx_ptr_to_phys(input);
745 command.s.max_results = max_results;
746 command.s.result_ptr = cvmx_ptr_to_phys(result);
750 if (graph->type == CVMX_DFA_GRAPH_TYPE_SM)
752 command.s.tsize = (graph->num_terminal_nodes + 255) / 256;
753 command.s.msize = graph->num_marked_nodes;
755 command.s.wq_ptr = cvmx_ptr_to_phys(work);
757 __cvmx_dfa_write_command(&command); // NOTE: this does synchronization and rings doorbell
762 * DFA gather list element
765 uint64_t length : 16; /**< length of piece of data at addr */
766 uint64_t reserved : 12; /**< reserved, set to 0 */
767 uint64_t addr : 36; /**< pointer to piece of data */
768 } cvmx_dfa_gather_entry_t;
772 * Check if a DFA has completed processing
774 * @param result_ptr Result area the DFA is using
775 * @return Non zero if the DFA is done
777 static inline uint64_t cvmx_dfa_is_done(cvmx_dfa_result0_t *result_ptr)
779 /* DFA sets the first result 64bit word to non zero when it's done */
780 return ((volatile cvmx_dfa_result0_t *)result_ptr)->s.done;
784 #ifdef CVMX_ENABLE_DFA_FUNCTIONS
786 * Initialize the DFA hardware before use
787 * Returns 0 on success, -1 on failure
789 int cvmx_dfa_initialize(void);
793 * Shutdown and cleanup resources used by the DFA
795 void cvmx_dfa_shutdown(void);
802 #endif /* __CVMX_DFA_H__ */