1 /***********************license start***************
2 * Copyright (c) 2003-2008 Cavium Networks (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 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
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.
35 * For any questions regarding licensing please contact marketing@caviumnetworks.com
37 ***********************license end**************************************/
47 * Interface to the hardware DFA engine.
49 * <hr>$Revision: 41586 $<hr>
52 #ifndef __CVMX_DFA_H__
53 #define __CVMX_DFA_H__
58 #include "executive-config.h"
59 #ifdef CVMX_ENABLE_DFA_FUNCTIONS
60 #include "cvmx-config.h"
63 #define ENABLE_DEPRECATED /* Set to enable the old 18/36 bit names */
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)
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
85 * Which type of memory encoding is this graph using. Make sure you setup
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 */
96 } cvmx_dfa_graph_type_t;
99 * The possible node types.
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;
109 * The possible reasons the DFA stopped processing.
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;
120 * This format describes the DFA pointers in small mode
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 */
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 */
141 struct /**< @ this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1. */
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. */
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 */
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 */
173 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
174 struct /**< @deprecated unnamed reference to members */
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 */
183 /* Other chips don't support the deprecated unnamed unions */
186 } cvmx_dfa_node_next_sm_t;
189 * This format describes the DFA pointers in large mode
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 */
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. */
212 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
213 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
214 struct /**< @deprecated unnamed reference to members */
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 */
222 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
223 struct /**< @deprecated unnamed reference to members */
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. */
234 /* Other chips don't support the deprecated unnamed unions */
237 } cvmx_dfa_node_next_lg_t;
240 * This format describes the DFA pointers in large mode, another way
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 */
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. */
264 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
265 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
266 struct /**< @deprecated unnamed reference to members */
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 */
275 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
276 struct /**< @deprecated unnamed reference to members */
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. */
287 /* Other chips don't support the deprecated unnamed unions */
290 } cvmx_dfa_node_next_lgb_t;
293 * This format describes the DFA pointers in large mode
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 */
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 */
311 #if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
312 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
313 struct /**< @deprecated unnamed reference to members */
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 */
320 #elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
321 struct /**< @deprecated unnamed reference to members */
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 */
328 /* Other chips don't support the deprecated unnamed unions */
331 } cvmx_dfa_node_next_read_t;
334 * This structure defines the data format in the low-latency memory
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 */
348 } cvmx_dfa_node_next_t;
351 * These structures define a DFA instruction
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. */
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 */
371 uint64_t start_node : 22; /**< Node to start the walk from, includes ID and snrepl, see notes above. */
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 */
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) */
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 */
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 */
401 } cvmx_dfa_command_t;
404 * Format of the first result word written by the hardware.
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 */
417 } cvmx_dfa_result0_t;
420 * Format of the second result word and subsequent result words written by the hardware.
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 */
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. */
447 } cvmx_dfa_result1_t;
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 */
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 */
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. */
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. */
480 * DFA internal global state -- stored in 8 bytes of FAU
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
499 uint8_t ticket_loops;
500 uint32_t base_address_div16;
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
512 uint64_t now_serving : 8 ;
513 uint64_t total_tickets : 16;
515 uint64_t base_address_div32 : 31;
520 /* CSR typedefs have been moved to cvmx-csr-*.h */
523 * Write a small node edge to LLM.
525 * @param graph Graph to modify
527 * Source node for this edge
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).
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)
539 cvmx_llm_address_t address;
540 cvmx_dfa_node_next_t next_ptr;
542 address.u64 = graph->base_address + source_node * CVMX_DFA_NODESM_SIZE + match_index * 4;
545 if (OCTEON_IS_MODEL(OCTEON_CN31XX))
547 next_ptr.sm.w32.next_node0 = destination_node0;
548 next_ptr.sm.w32.p0 = cvmx_llm_parity(destination_node0);
550 next_ptr.sm.w32.next_node1 = destination_node1;
551 next_ptr.sm.w32.p1 = cvmx_llm_parity(destination_node1);
555 next_ptr.sm.w36.next_node0 = destination_node0;
556 next_ptr.sm.w36.p0 = cvmx_llm_parity(destination_node0);
558 next_ptr.sm.w36.next_node1 = destination_node1;
559 next_ptr.sm.w36.p1 = cvmx_llm_parity(destination_node1);
562 cvmx_llm_write36(address, next_ptr.u64, 0);
564 #ifdef ENABLE_DEPRECATED
565 #define cvmx_dfa_write_edge18 cvmx_dfa_write_edge_sm
570 * Write a large node edge to LLM.
572 * @param graph Graph to modify
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.
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)
585 cvmx_llm_address_t address;
586 cvmx_dfa_node_next_t next_ptr;
588 address.u64 = graph->base_address + source_node * CVMX_DFA_NODELG_SIZE + (uint64_t)match * 4;
591 if (OCTEON_IS_MODEL(OCTEON_CN31XX))
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);
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);
604 cvmx_llm_write36(address, next_ptr.u64, 0);
606 #ifdef ENABLE_DEPRECATED
607 #define cvmx_dfa_write_node36 cvmx_dfa_write_node_lg
611 * Ring the DFA doorbell telling it that new commands are
614 * @param num_commands
615 * Number of new commands
617 static inline void cvmx_dfa_write_doorbell(uint64_t num_commands)
620 cvmx_write_csr(CVMX_DFA_DBELL, num_commands);
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.
629 * @param command Command to write
632 #ifdef CVMX_ENABLE_DFA_FUNCTIONS
633 static inline void __cvmx_dfa_write_command(cvmx_dfa_command_t *command)
635 cvmx_dfa_state_t cvmx_dfa_state;
636 uint64_t my_ticket; // needs to wrap to 8 bits
638 cvmx_dfa_command_t *head;
640 CVMX_PREFETCH0(command);
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;
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
653 // compute index and instruction queue head pointer
654 index = cvmx_dfa_state.s.index;
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
660 // copy the command to the instruction queue
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
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);
674 cvmx_dprintf("__cvmx_dfa_write_command: Out of memory. Expect crashes.\n");
679 cvmx_dfa_write_doorbell(1);
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);
689 * Submit work to the DFA units for processing
691 * @param graph Graph to process
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
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.
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.
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)
716 cvmx_dfa_command_t command;
718 /* Make sure the result's first 64bit word is zero so we can tell when the
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;
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);
743 command.s.max_results = max_results;
744 command.s.result_ptr = cvmx_ptr_to_phys(result);
748 if (graph->type == CVMX_DFA_GRAPH_TYPE_SM)
750 command.s.tsize = (graph->num_terminal_nodes + 255) / 256;
751 command.s.msize = graph->num_marked_nodes;
753 command.s.wq_ptr = cvmx_ptr_to_phys(work);
755 __cvmx_dfa_write_command(&command); // NOTE: this does synchronization and rings doorbell
760 * DFA gather list element
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;
770 * Check if a DFA has completed processing
772 * @param result_ptr Result area the DFA is using
773 * @return Non zero if the DFA is done
775 static inline uint64_t cvmx_dfa_is_done(cvmx_dfa_result0_t *result_ptr)
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;
782 #ifdef CVMX_ENABLE_DFA_FUNCTIONS
784 * Initialize the DFA hardware before use
785 * Returns 0 on success, -1 on failure
787 int cvmx_dfa_initialize(void);
791 * Shutdown and cleanup resources used by the DFA
793 void cvmx_dfa_shutdown(void);
800 #endif /* __CVMX_DFA_H__ */