cvmx-dfa.h revision 210286
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 66extern "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 */ 88typedef 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 */ 101typedef 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 */ 111typedef 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 */ 122typedef 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 */ 191typedef 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 */ 242typedef 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 */ 295typedef 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 */ 336typedef 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 */ 353typedef 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 */ 406typedef 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 */ 422typedef 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 */ 452typedef 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 */ 482typedef 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 */ 535static 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 */ 581static 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 */ 617static 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 633static 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 */ 712static 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 */ 762typedef 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 */ 775static 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 */ 787int cvmx_dfa_initialize(void); 788 789 790/** 791 * Shutdown and cleanup resources used by the DFA 792 */ 793void cvmx_dfa_shutdown(void); 794#endif 795 796#ifdef __cplusplus 797} 798#endif 799 800#endif /* __CVMX_DFA_H__ */ 801