1/***********************license start*************** 2 * Copyright (c) 2003-2010 Cavium Inc. (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 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 21 * permission. 22 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 26 * countries. 27 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**************************************/ 39 40 41 42 43 44 45 46/** 47 * @file 48 * 49 * Interface to the CN31XX, CN38XX, and CN58XX hardware DFA engine. 50 * 51 * <hr>$Revision: 70030 $<hr> 52 */ 53 54#ifndef __CVMX_DFA_H__ 55#define __CVMX_DFA_H__ 56#include "cvmx-llm.h" 57#include "cvmx-wqe.h" 58#include "cvmx-fpa.h" 59 60#include "executive-config.h" 61#ifdef CVMX_ENABLE_DFA_FUNCTIONS 62#include "cvmx-config.h" 63#endif 64 65#define ENABLE_DEPRECATED /* Set to enable the old 18/36 bit names */ 66 67#ifdef __cplusplus 68extern "C" { 69#endif 70 71 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) 77 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 84#endif 85 86/** 87 * Which type of memory encoding is this graph using. Make sure you setup 88 * the LLM to match. 89 */ 90typedef enum 91{ 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 */ 97#endif 98} cvmx_dfa_graph_type_t; 99 100/** 101 * The possible node types. 102 */ 103typedef enum 104{ 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; 109 110/** 111 * The possible reasons the DFA stopped processing. 112 */ 113typedef enum 114{ 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; 120 121/** 122 * This format describes the DFA pointers in small mode 123 */ 124typedef union 125{ 126 uint64_t u64; 127 struct 128 { 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 */ 134 } w32; 135 struct 136 { 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 */ 142 } w36; 143 struct /**< @ this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1. */ 144 { 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. */ 156 { 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 */ 168 { 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 */ 174 }; 175#elif CVMX_COMPILED_FOR(OCTEON_CN38XX) 176 struct /**< @deprecated unnamed reference to members */ 177 { 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 */ 183 }; 184#else 185 /* Other chips don't support the deprecated unnamed unions */ 186#endif 187#endif 188} cvmx_dfa_node_next_sm_t; 189 190/** 191 * This format describes the DFA pointers in large mode 192 */ 193typedef union 194{ 195 uint64_t u64; 196 struct 197 { 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 */ 203 } w32; 204 struct 205 { 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. */ 213 } w36; 214#if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY() 215#if CVMX_COMPILED_FOR(OCTEON_CN31XX) 216 struct /**< @deprecated unnamed reference to members */ 217 { 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 */ 223 }; 224#elif CVMX_COMPILED_FOR(OCTEON_CN38XX) 225 struct /**< @deprecated unnamed reference to members */ 226 { 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. */ 234 }; 235#else 236 /* Other chips don't support the deprecated unnamed unions */ 237#endif 238#endif 239} cvmx_dfa_node_next_lg_t; 240 241/** 242 * This format describes the DFA pointers in large mode, another way 243 */ 244typedef union 245{ 246 uint64_t u64; 247 struct 248 { 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 */ 255 } w32; 256 struct 257 { 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. */ 265 } w36; 266#if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY() 267#if CVMX_COMPILED_FOR(OCTEON_CN31XX) 268 struct /**< @deprecated unnamed reference to members */ 269 { 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 */ 276 }; 277#elif CVMX_COMPILED_FOR(OCTEON_CN38XX) 278 struct /**< @deprecated unnamed reference to members */ 279 { 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. */ 287 }; 288#else 289 /* Other chips don't support the deprecated unnamed unions */ 290#endif 291#endif 292} cvmx_dfa_node_next_lgb_t; 293 294/** 295 * This format describes the DFA pointers in large mode 296 */ 297typedef union 298{ 299 uint64_t u64; 300 struct 301 { 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 */ 306 } w32; 307 struct 308 { 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 */ 312 } w36; 313#if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY() 314#if CVMX_COMPILED_FOR(OCTEON_CN31XX) 315 struct /**< @deprecated unnamed reference to members */ 316 { 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 */ 321 }; 322#elif CVMX_COMPILED_FOR(OCTEON_CN38XX) 323 struct /**< @deprecated unnamed reference to members */ 324 { 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 */ 328 }; 329#else 330 /* Other chips don't support the deprecated unnamed unions */ 331#endif 332#endif 333} cvmx_dfa_node_next_read_t; 334 335/** 336 * This structure defines the data format in the low-latency memory 337 */ 338typedef union 339{ 340 uint64_t u64; 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 */ 349#endif 350} cvmx_dfa_node_next_t; 351 352/** 353 * These structures define a DFA instruction 354 */ 355typedef union 356{ 357 uint64_t u64[4]; 358 uint32_t u32; 359 struct 360 { 361 // WORD 0 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. */ 368#if 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 */ 372#else 373 uint64_t start_node : 22; /**< Node to start the walk from, includes ID and snrepl, see notes above. */ 374#endif 375 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 */ 382 383 // WORD 1 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) */ 392 // WORD 2 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 */ 396 397 // WORD 3 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 */ 402 } s; 403} cvmx_dfa_command_t; 404 405/** 406 * Format of the first result word written by the hardware. 407 */ 408typedef union 409{ 410 uint64_t u64; 411 struct 412 { 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 */ 418 } s; 419} cvmx_dfa_result0_t; 420 421/** 422 * Format of the second result word and subsequent result words written by the hardware. 423 */ 424typedef union 425{ 426 uint64_t u64; 427 struct 428 { 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 */ 438 } s; 439 struct 440 { 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. */ 448 } s2; 449} cvmx_dfa_result1_t; 450 451/** 452 * Abstract DFA graph 453 */ 454typedef struct 455{ 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 */ 459 union { 460 struct { 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 */ 470 }; 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. */ 476 }; 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. */ 479} cvmx_dfa_graph_t; 480 481/** 482 * DFA internal global state -- stored in 8 bytes of FAU 483 */ 484typedef union 485{ 486 uint64_t u64; 487 struct { 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 498 uint8_t index; 499 uint8_t now_serving; 500 uint8_t ticket; 501 uint8_t ticket_loops; 502 uint32_t base_address_div16; 503#endif 504 } s; 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 513 uint64_t index : 8 ; 514 uint64_t now_serving : 8 ; 515 uint64_t total_tickets : 16; 516 uint64_t carry : 1; 517 uint64_t base_address_div32 : 31; 518#endif 519 } s2; 520} cvmx_dfa_state_t; 521 522/* CSR typedefs have been moved to cvmx-dfa-defs.h */ 523 524/** 525 * Write a small node edge to LLM. 526 * 527 * @param graph Graph to modify 528 * @param source_node 529 * Source node for this edge 530 * @param match_index 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). 536 */ 537static 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) 540{ 541 cvmx_llm_address_t address; 542 cvmx_dfa_node_next_t next_ptr; 543 544 address.u64 = graph->base_address + source_node * CVMX_DFA_NODESM_SIZE + match_index * 4; 545 546 next_ptr.u64 = 0; 547 if (OCTEON_IS_MODEL(OCTEON_CN31XX)) 548 { 549 next_ptr.sm.w32.next_node0 = destination_node0; 550 next_ptr.sm.w32.p0 = cvmx_llm_parity(destination_node0); 551 552 next_ptr.sm.w32.next_node1 = destination_node1; 553 next_ptr.sm.w32.p1 = cvmx_llm_parity(destination_node1); 554 } 555 else 556 { 557 next_ptr.sm.w36.next_node0 = destination_node0; 558 next_ptr.sm.w36.p0 = cvmx_llm_parity(destination_node0); 559 560 next_ptr.sm.w36.next_node1 = destination_node1; 561 next_ptr.sm.w36.p1 = cvmx_llm_parity(destination_node1); 562 } 563 564 cvmx_llm_write36(address, next_ptr.u64, 0); 565} 566#ifdef ENABLE_DEPRECATED 567#define cvmx_dfa_write_edge18 cvmx_dfa_write_edge_sm 568#endif 569 570 571/** 572 * Write a large node edge to LLM. 573 * 574 * @param graph Graph to modify 575 * @param source_node 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. 582 */ 583static 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) 586{ 587 cvmx_llm_address_t address; 588 cvmx_dfa_node_next_t next_ptr; 589 590 address.u64 = graph->base_address + source_node * CVMX_DFA_NODELG_SIZE + (uint64_t)match * 4; 591 592 next_ptr.u64 = 0; 593 if (OCTEON_IS_MODEL(OCTEON_CN31XX)) 594 { 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); 598 } 599 else 600 { 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); 604 } 605 606 cvmx_llm_write36(address, next_ptr.u64, 0); 607} 608#ifdef ENABLE_DEPRECATED 609#define cvmx_dfa_write_node36 cvmx_dfa_write_node_lg 610#endif 611 612/** 613 * Ring the DFA doorbell telling it that new commands are 614 * available. 615 * 616 * @param num_commands 617 * Number of new commands 618 */ 619static inline void cvmx_dfa_write_doorbell(uint64_t num_commands) 620{ 621 CVMX_SYNCWS; 622 cvmx_write_csr(CVMX_DFA_DBELL, num_commands); 623} 624 625/** 626 * @INTERNAL 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. 630 * 631 * @param command Command to write 632 */ 633 634#ifdef CVMX_ENABLE_DFA_FUNCTIONS 635static inline void __cvmx_dfa_write_command(cvmx_dfa_command_t *command) 636{ 637 cvmx_dfa_state_t cvmx_dfa_state; 638 uint64_t my_ticket; // needs to wrap to 8 bits 639 uint64_t index; 640 cvmx_dfa_command_t *head; 641 642 CVMX_PREFETCH0(command); 643 // take a ticket. 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; 646 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 653 } 654 655 // compute index and instruction queue head pointer 656 index = cvmx_dfa_state.s.index; 657 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 661 662 // copy the command to the instruction queue 663 *head++ = *command; 664 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 668 if (new_base) { 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); 674 } 675 else { 676 cvmx_dprintf("__cvmx_dfa_write_command: Out of memory. Expect crashes.\n"); 677 } 678 index=0; 679 } 680 681 cvmx_dfa_write_doorbell(1); 682 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); 687} 688 689 690/** 691 * Submit work to the DFA units for processing 692 * 693 * @param graph Graph to process 694 * @param start_node 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 701 * @param use_gather 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. 708 * @param max_results 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. 713 */ 714static 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) 717{ 718 cvmx_dfa_command_t command; 719 720 /* Make sure the result's first 64bit word is zero so we can tell when the 721 DFA is done. */ 722 result->u64 = 0; 723 724 // WORD 0 725 command.u64[0] = 0; 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; 733 734 // WORD 1 735 command.u64[1] = 0; 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); 742 743 // WORD 2 744 command.u64[2] = 0; 745 command.s.max_results = max_results; 746 command.s.result_ptr = cvmx_ptr_to_phys(result); 747 748 // WORD 3 749 command.u64[3] = 0; 750 if (graph->type == CVMX_DFA_GRAPH_TYPE_SM) 751 { 752 command.s.tsize = (graph->num_terminal_nodes + 255) / 256; 753 command.s.msize = graph->num_marked_nodes; 754 } 755 command.s.wq_ptr = cvmx_ptr_to_phys(work); 756 757 __cvmx_dfa_write_command(&command); // NOTE: this does synchronization and rings doorbell 758} 759#endif 760 761/** 762 * DFA gather list element 763 */ 764typedef struct { 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; 769 770 771/** 772 * Check if a DFA has completed processing 773 * 774 * @param result_ptr Result area the DFA is using 775 * @return Non zero if the DFA is done 776 */ 777static inline uint64_t cvmx_dfa_is_done(cvmx_dfa_result0_t *result_ptr) 778{ 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; 781} 782 783 784#ifdef CVMX_ENABLE_DFA_FUNCTIONS 785/** 786 * Initialize the DFA hardware before use 787 * Returns 0 on success, -1 on failure 788 */ 789int cvmx_dfa_initialize(void); 790 791 792/** 793 * Shutdown and cleanup resources used by the DFA 794 */ 795void cvmx_dfa_shutdown(void); 796#endif 797 798#ifdef __cplusplus 799} 800#endif 801 802#endif /* __CVMX_DFA_H__ */ 803