cvmx-dfa.h revision 259065
12739Sjlahoda/***********************license start*************** 23170Svasya * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights 32739Sjlahoda * reserved. 42739Sjlahoda * 52739Sjlahoda * 62739Sjlahoda * Redistribution and use in source and binary forms, with or without 72739Sjlahoda * modification, are permitted provided that the following conditions are 82739Sjlahoda * met: 92739Sjlahoda * 102739Sjlahoda * * Redistributions of source code must retain the above copyright 112739Sjlahoda * notice, this list of conditions and the following disclaimer. 122739Sjlahoda * 132739Sjlahoda * * Redistributions in binary form must reproduce the above 142739Sjlahoda * copyright notice, this list of conditions and the following 152739Sjlahoda * disclaimer in the documentation and/or other materials provided 162739Sjlahoda * with the distribution. 172739Sjlahoda 182739Sjlahoda * * Neither the name of Cavium Inc. nor the names of 192739Sjlahoda * its contributors may be used to endorse or promote products 202739Sjlahoda * derived from this software without specific prior written 212739Sjlahoda * permission. 222739Sjlahoda 232739Sjlahoda * This Software, including technical data, may be subject to U.S. export control 242739Sjlahoda * laws, including the U.S. Export Administration Act and its associated 252739Sjlahoda * regulations, and may be subject to export or import regulations in other 262739Sjlahoda * countries. 272739Sjlahoda 282933Sakulyakh * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 292739Sjlahoda * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR 302739Sjlahoda * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 312739Sjlahoda * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 322739Sjlahoda * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 332739Sjlahoda * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 342739Sjlahoda * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 352739Sjlahoda * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 362739Sjlahoda * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 372739Sjlahoda * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 382739Sjlahoda ***********************license end**************************************/ 392739Sjlahoda 402739Sjlahoda 412739Sjlahoda 422739Sjlahoda 432739Sjlahoda 442739Sjlahoda 452739Sjlahoda 462739Sjlahoda/** 472739Sjlahoda * @file 482739Sjlahoda * 492739Sjlahoda * Interface to the CN31XX, CN38XX, and CN58XX hardware DFA engine. 502739Sjlahoda * 512739Sjlahoda * <hr>$Revision: 70030 $<hr> 522739Sjlahoda */ 532739Sjlahoda 542739Sjlahoda#ifndef __CVMX_DFA_H__ 552739Sjlahoda#define __CVMX_DFA_H__ 562739Sjlahoda#include "cvmx-llm.h" 572739Sjlahoda#include "cvmx-wqe.h" 582739Sjlahoda#include "cvmx-fpa.h" 592739Sjlahoda 602739Sjlahoda#include "executive-config.h" 612739Sjlahoda#ifdef CVMX_ENABLE_DFA_FUNCTIONS 622739Sjlahoda#include "cvmx-config.h" 632739Sjlahoda#endif 642739Sjlahoda 652739Sjlahoda#define ENABLE_DEPRECATED /* Set to enable the old 18/36 bit names */ 662739Sjlahoda 672739Sjlahoda#ifdef __cplusplus 682739Sjlahodaextern "C" { 692739Sjlahoda#endif 702739Sjlahoda 712739Sjlahoda 722739Sjlahoda/* Maximum nodes available in a small encoding */ 732739Sjlahoda#define CVMX_DFA_NODESM_MAX_NODES ((OCTEON_IS_MODEL(OCTEON_CN31XX)) ? 0x8000 : 0x20000) 742739Sjlahoda#define CVMX_DFA_NODESM_SIZE 512 /* Size of each node for small encoding */ 752739Sjlahoda#define CVMX_DFA_NODELG_SIZE 1024 /* Size of each node for large encoding */ 762739Sjlahoda#define CVMX_DFA_NODESM_LAST_TERMINAL (CVMX_DFA_NODESM_MAX_NODES-1) 772739Sjlahoda 782739Sjlahoda#ifdef ENABLE_DEPRECATED 792739Sjlahoda/* These defines are for compatability with old code. They are deprecated */ 802739Sjlahoda#define CVMX_DFA_NODE18_SIZE CVMX_DFA_NODESM_SIZE 812739Sjlahoda#define CVMX_DFA_NODE36_SIZE CVMX_DFA_NODELG_SIZE 822739Sjlahoda#define CVMX_DFA_NODE18_MAX_NODES CVMX_DFA_NODESM_MAX_NODES 832739Sjlahoda#define CVMX_DFA_NODE18_LAST_TERMINAL CVMX_DFA_NODESM_LAST_TERMINAL 842739Sjlahoda#endif 852739Sjlahoda 862739Sjlahoda/** 872739Sjlahoda * Which type of memory encoding is this graph using. Make sure you setup 882739Sjlahoda * the LLM to match. 892739Sjlahoda */ 902739Sjlahodatypedef enum 912739Sjlahoda{ 922739Sjlahoda CVMX_DFA_GRAPH_TYPE_SM = 0, 932739Sjlahoda CVMX_DFA_GRAPH_TYPE_LG = 1, 942739Sjlahoda#ifdef ENABLE_DEPRECATED 952739Sjlahoda CVMX_DFA_GRAPH_TYPE_18b = 0, /* Deprecated */ 962739Sjlahoda CVMX_DFA_GRAPH_TYPE_36b = 1 /* Deprecated */ 972739Sjlahoda#endif 982739Sjlahoda} cvmx_dfa_graph_type_t; 992739Sjlahoda 1002739Sjlahoda/** 1012739Sjlahoda * The possible node types. 1022739Sjlahoda */ 1032739Sjlahodatypedef enum 1042739Sjlahoda{ 1052739Sjlahoda CVMX_DFA_NODE_TYPE_NORMAL = 0, /**< Node is a branch */ 1062739Sjlahoda CVMX_DFA_NODE_TYPE_MARKED = 1, /**< Node is marked special */ 1072739Sjlahoda CVMX_DFA_NODE_TYPE_TERMINAL = 2 /**< Node is a terminal leaf */ 1082739Sjlahoda} cvmx_dfa_node_type_t; 1092739Sjlahoda 1102739Sjlahoda/** 1112739Sjlahoda * The possible reasons the DFA stopped processing. 1122739Sjlahoda */ 1132739Sjlahodatypedef enum 1142739Sjlahoda{ 1152739Sjlahoda CVMX_DFA_STOP_REASON_DATA_GONE = 0, /**< DFA ran out of data */ 1162739Sjlahoda CVMX_DFA_STOP_REASON_PARITY_ERROR = 1, /**< DFA encountered a memory error */ 1172739Sjlahoda CVMX_DFA_STOP_REASON_FULL = 2, /**< DFA is full */ 1182739Sjlahoda CVMX_DFA_STOP_REASON_TERMINAL = 3 /**< DFA hit a terminal */ 1192739Sjlahoda} cvmx_dfa_stop_reason_t; 1202739Sjlahoda 1212739Sjlahoda/** 1222739Sjlahoda * This format describes the DFA pointers in small mode 1232739Sjlahoda */ 1242739Sjlahodatypedef union 1252739Sjlahoda{ 1262739Sjlahoda uint64_t u64; 1272739Sjlahoda struct 1282739Sjlahoda { 1292739Sjlahoda uint64_t mbz :32;/**< Must be zero */ 1302739Sjlahoda uint64_t p1 : 1;/**< Set if next_node1 is odd parity */ 1312739Sjlahoda uint64_t next_node1 :15;/**< Next node if an odd character match */ 1322739Sjlahoda uint64_t p0 : 1;/**< Set if next_node0 is odd parity */ 1332739Sjlahoda uint64_t next_node0 :15;/**< Next node if an even character match */ 1342739Sjlahoda } w32; 1352739Sjlahoda struct 1362739Sjlahoda { 1372739Sjlahoda uint64_t mbz :28;/**< Must be zero */ 1382739Sjlahoda uint64_t p1 : 1;/**< Set if next_node1 is odd parity */ 1392739Sjlahoda uint64_t next_node1 :17;/**< Next node if an odd character match */ 1402739Sjlahoda uint64_t p0 : 1;/**< Set if next_node0 is odd parity */ 1412739Sjlahoda uint64_t next_node0 :17;/**< Next node if an even character match */ 1422739Sjlahoda } w36; 1432739Sjlahoda struct /**< @ this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1. */ 1442739Sjlahoda { 1452739Sjlahoda uint64_t mbz :28;/**< Must be zero */ 1462739Sjlahoda uint64_t p1 : 1;/**< Set if next_node1 is odd parity */ 1472739Sjlahoda uint64_t per_node_repl1 : 1;/**< enable for extra replicaiton for next node (CN58XX) */ 1482739Sjlahoda uint64_t next_node_repl1 : 2;/**< extra replicaiton for next node (CN58XX) (if per_node_repl1 is set) */ 1492739Sjlahoda uint64_t next_node1 :14;/**< Next node if an odd character match - IWORD3[Msize], if per_node_repl1==1. */ 1502739Sjlahoda uint64_t p0 : 1;/**< Set if next_node0 is odd parity */ 1512739Sjlahoda uint64_t per_node_repl0 : 1;/**< enable for extra replicaiton for next node (CN58XX) */ 1522739Sjlahoda uint64_t next_node_repl0 : 2;/**< extra replicaiton for next node (CN58XX) (if per_node_repl0 is set) */ 1532739Sjlahoda uint64_t next_node0 :14;/**< Next node if an odd character match - IWORD3[Msize], if per_node_repl0==1. */ 1542739Sjlahoda } w36nrepl_en; /**< use when next_node_repl[01] is 1. */ 1552739Sjlahoda struct /**< this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1. */ 1562739Sjlahoda { 1572739Sjlahoda uint64_t mbz :28;/**< Must be zero */ 1582739Sjlahoda uint64_t p1 : 1;/**< Set if next_node1 is odd parity */ 1592739Sjlahoda uint64_t per_node_repl1 : 1;/**< enable for extra replicaiton for next node (CN58XX) */ 1602739Sjlahoda uint64_t next_node1 :16;/**< Next node if an odd character match, if per_node_repl1==0. */ 1612739Sjlahoda uint64_t p0 : 1;/**< Set if next_node0 is odd parity */ 1622739Sjlahoda uint64_t per_node_repl0 : 1;/**< enable for extra replicaiton for next node (CN58XX) */ 1632739Sjlahoda uint64_t next_node0 :16;/**< Next node if an odd character match, if per_node_repl0==0. */ 1642739Sjlahoda } w36nrepl_dis; /**< use when next_node_repl[01] is 0. */ 1652739Sjlahoda#if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY() 1662739Sjlahoda#if CVMX_COMPILED_FOR(OCTEON_CN31XX) 1672739Sjlahoda struct /**< @deprecated unnamed reference to members */ 1682739Sjlahoda { 1692739Sjlahoda uint64_t mbz :32;/**< Must be zero */ 1702739Sjlahoda uint64_t p1 : 1;/**< Set if next_node1 is odd parity */ 1712739Sjlahoda uint64_t next_node1 :15;/**< Next node if an odd character match */ 1722739Sjlahoda uint64_t p0 : 1;/**< Set if next_node0 is odd parity */ 1732739Sjlahoda uint64_t next_node0 :15;/**< Next node if an even character match */ 1742739Sjlahoda }; 1752739Sjlahoda#elif CVMX_COMPILED_FOR(OCTEON_CN38XX) 1762739Sjlahoda struct /**< @deprecated unnamed reference to members */ 1772739Sjlahoda { 1782739Sjlahoda uint64_t mbz :28;/**< Must be zero */ 1792739Sjlahoda uint64_t p1 : 1;/**< Set if next_node1 is odd parity */ 1802739Sjlahoda uint64_t next_node1 :17;/**< Next node if an odd character match */ 1812739Sjlahoda uint64_t p0 : 1;/**< Set if next_node0 is odd parity */ 1822739Sjlahoda uint64_t next_node0 :17;/**< Next node if an even character match */ 1832739Sjlahoda }; 1842739Sjlahoda#else 1852739Sjlahoda /* Other chips don't support the deprecated unnamed unions */ 1862739Sjlahoda#endif 1872739Sjlahoda#endif 1882739Sjlahoda} cvmx_dfa_node_next_sm_t; 1892739Sjlahoda 1902739Sjlahoda/** 1912739Sjlahoda * This format describes the DFA pointers in large mode 1922739Sjlahoda */ 1932739Sjlahodatypedef union 1942739Sjlahoda{ 1952739Sjlahoda uint64_t u64; 1962739Sjlahoda struct 1972739Sjlahoda { 1982739Sjlahoda uint64_t mbz :32;/**< Must be zero */ 1992739Sjlahoda uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */ 2002739Sjlahoda cvmx_dfa_node_type_t type : 2;/**< Node type */ 2012739Sjlahoda uint64_t mbz2 : 3;/**< Must be zero */ 2022739Sjlahoda uint64_t next_node :20;/**< Next node */ 2032739Sjlahoda } w32; 2042739Sjlahoda struct 2052739Sjlahoda { 2062739Sjlahoda uint64_t mbz :28;/**< Must be zero */ 2072739Sjlahoda uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */ 2082739Sjlahoda cvmx_dfa_node_type_t type : 2;/**< Node type */ 2092739Sjlahoda uint64_t extra_bits : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */ 2102739Sjlahoda uint64_t next_node_repl : 2;/**< extra replicaiton for next node (PASS3/CN58XX), Must be zero previously */ 2112739Sjlahoda uint64_t next_node :20;/**< Next node ID, Note, combine with next_node_repl to use as start_node 2122739Sjlahoda for continuation, as in cvmx_dfa_node_next_lgb_t. */ 2132739Sjlahoda } w36; 2142739Sjlahoda#if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY() 2152739Sjlahoda#if CVMX_COMPILED_FOR(OCTEON_CN31XX) 2162739Sjlahoda struct /**< @deprecated unnamed reference to members */ 2172739Sjlahoda { 2182739Sjlahoda uint64_t mbz :32;/**< Must be zero */ 2192739Sjlahoda uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */ 2202739Sjlahoda cvmx_dfa_node_type_t type : 2;/**< Node type */ 2212739Sjlahoda uint64_t mbz2 : 3;/**< Must be zero */ 2222739Sjlahoda uint64_t next_node :20;/**< Next node */ 2232739Sjlahoda }; 2242739Sjlahoda#elif CVMX_COMPILED_FOR(OCTEON_CN38XX) 2252739Sjlahoda struct /**< @deprecated unnamed reference to members */ 2262739Sjlahoda { 2272739Sjlahoda uint64_t mbz :28;/**< Must be zero */ 2282739Sjlahoda uint64_t ecc : 7;/**< ECC checksum on the rest of the bits */ 2292739Sjlahoda cvmx_dfa_node_type_t type : 2;/**< Node type */ 2302739Sjlahoda uint64_t extra_bits : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */ 2312739Sjlahoda uint64_t next_node_repl : 2;/**< extra replicaiton for next node (PASS3/CN58XX), Must be zero previously */ 2322739Sjlahoda uint64_t next_node :20;/**< Next node ID, Note, combine with next_node_repl to use as start_node 2332739Sjlahoda for continuation, as in cvmx_dfa_node_next_lgb_t. */ 2342739Sjlahoda }; 2352739Sjlahoda#else 2362739Sjlahoda /* Other chips don't support the deprecated unnamed unions */ 2372739Sjlahoda#endif 2382739Sjlahoda#endif 2392739Sjlahoda} cvmx_dfa_node_next_lg_t; 2402739Sjlahoda 2412739Sjlahoda/** 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