HEX
Server: nginx/1.22.1
System: Linux VM-16-9-centos 3.10.0-1160.99.1.el7.x86_64 #1 SMP Wed Sep 13 14:19:20 UTC 2023 x86_64
User: www (1001)
PHP: 7.3.31
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: //lib64/mft/python_tools/fwtrace/fwtrace.py
#!/usr/bin/env python
# --
#                 - Mellanox Confidential and Proprietary -
#
# Copyright (C) Jan 2013, Mellanox Technologies Ltd.  ALL RIGHTS RESERVED.
#
# Except as specifically permitted heeein, no portion of the information,
# including but not limited to object code and source code, may be reproduced,
# modified, distributed, republished or otherwise exploited in any form or by
# any means for any purpose without the prior written permission of Mellanox
# Technologies Ltd. Use of software subject to the terms and conditions
# detailed in the file "LICENSE.txt".
# --

from __future__ import print_function

import sys
import os

# Clear LD_LIBRARY_PATH to prevent pyinstaller compatibility issues
library_path_var = "LD_LIBRARY_PATH"
is_pyinstaller = getattr(sys, 'frozen', False)
if is_pyinstaller and library_path_var in os.environ:
    os.environ[library_path_var] = ""

import string
import getopt
import subprocess
import signal
import re
import shutil
import struct
import tempfile
import getpass
import glob
from secure_fw_trace import SecureFwTrace
from fw_trace_utilities import FwTraceUtilities


# mft imports
sys.path.append(os.path.join("..", "..", "common"))
sys.path.append(os.path.join("..", "..", "mtcr_py"))
sys.path.append(os.path.join("..", "..", "cmdif"))
sys.path.append(os.path.join("..", "..", "reg_access"))
import mtcr  # noqa
import cmdif  # noqa
import fwparse  # noqa
import regaccess  # noqa

# In case python version is higher/equal to 2.5 use hashlib
if sys.version_info >= (2, 5):
    from hashlib import md5
else:
    from md5 import md5


class UnbufferedStream(object):
   def __init__(self, stream):
       self.stream = stream
   def write(self, data):
       self.stream.write(data)
       self.stream.flush()
   def writelines(self, datas):
       self.stream.writelines(datas)
       self.stream.flush()
   def __getattr__(self, attr):
       return getattr(self.stream, attr)


sys.stdout = UnbufferedStream(sys.stdout)
EXEC_NAME = "fwtrace"
MLXTRACE_EXE = "mlxtrace"

proc = None


def signal_handler(signal, frame):
    print("\nInterrupted, exiting ...")
    global proc
    if proc is not None:
        proc.terminate()
        proc.wait()
        proc = None
    sys.exit(0)


#######################################################

def IsWindows():
    return os.name == "nt"


if IsWindows():  # windows
    if getattr(sys, 'frozen', False):
        appPath = os.path.dirname(sys.executable)
    elif __file__:
        appPath = os.path.dirname(__file__)

    CFG_DIR = os.path.join(appPath, "fwtrace_cfg")
else:  # Linux and bros
    CFG_DIR = "/etc/mft/fwtrace_cfg"

#######################################################
HCA_MASK_CLASSES = [
    ("DEBUG_INIT", 0), ("INIT", 1), ("ICM", 2), ("ICM_FREE_LIST", 3),
    ("HOST_MNG", 4), ("CMD_IF", 5), ("PHY_IB", 6), ("PHY_RX_ADAP", 7),
    ("LIBFHI", 8), ("PHY_COMMON", 9), ("PHY_MANAGER", 10),
    ("PWR", 11), ("FLR", 12), ("ICM_ACCESS", 13),
    ("MAD", 14), ("RXT_CHECKS", 15), ("I2C", 16), ("TRANSPORT", 17),
    ("FW_LL", 18), ("RX_ERRORS", 19), ("CMD_DRIVER", 20), ("PROFILING", 21),
    ("MANAGEMENT", 22), ("FLASH", 23), ("STEERING", 24),
    ("IFARM", 25), ("ICMD", 26), ("PCI", 27), ("DC_CLEANUP", 28),
    ("PHY_ETH", 29), ("VIRT", 30)]  # list of (trace type name, start_bit)

DEV_INFO_DB = [
    # we use list instead of dict to keep order,
    # new devices should be at head of the list
    {
        "name": "ConnectIB",
        "type": fwparse.DEVICE_CONNECTIB,
        "dev_id": [0x1ff],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": True,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_cib_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_cib_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_cib_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_cib_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_cib_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_cib_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_cib_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_cib_itrace_irisc7.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_cib_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "SwitchIB",
        "type": fwparse.DEVICE_SWITCHIB,
        "dev_id": [0x247],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0xffffffff, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_sib_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_sib_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_sib_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_sib_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_sib_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_sib_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_sib_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_sib_itrace_irisc7.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_sib_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": [("class1", 0), ("class2", 1)],
        "default_tracer_mode": "FIFO"
    },
    {
        "name": "ConnectX4",
        "type": fwparse.DEVICE_CONNECTX4,
        "dev_id": [0x209],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_cx4_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_cx4_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_cx4_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_cx4_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_cx4_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_cx4_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_cx4_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_cx4_itrace_irisc7.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_cx4_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "ConnectX5",
        "type": fwparse.DEVICE_CONNECTX5,
        "dev_id": [0x20d],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep + "mlxtrace_cx5_itrace_irisc9.cfg"),
            (10, "i10", CFG_DIR + os.sep +
             "mlxtrace_cx5_itrace_irisc10.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_cx5_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "BlueField",
        "type": fwparse.DEVICE_BLUEFIELD,
        "dev_id": [0x211],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc9.cfg"),
            (10, "i10", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace_irisc10.cfg"),
            (-1, "all", CFG_DIR + os.sep +
             "mlxtrace_bluefield_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "BlueField2",
        "type": fwparse.DEVICE_BLUEFIELD2,
        "dev_id": [0x214],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc9.cfg"),
            (10, "i10", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace_irisc10.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_bluefield2_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "BlueField3",
        "type": fwparse.DEVICE_BLUEFIELD3,
        "dev_id": [0x21c],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc9.cfg"),
            (10, "i10", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace_irisc10.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_bluefield3_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "ConnectX6",
        "type": fwparse.DEVICE_CONNECTX6,
        "dev_id": [0x20f],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep + "mlxtrace_cx6_itrace_irisc9.cfg"),
            (10, "i10", CFG_DIR + os.sep +
             "mlxtrace_cx6_itrace_irisc10.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_cx6_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "ConnectX6DX",
        "type": fwparse.DEVICE_CONNECTX6DX,
        "dev_id": [0x212],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace_irisc9.cfg"),
            (10, "i10", CFG_DIR + os.sep +
             "mlxtrace_cx6dx_itrace_irisc10.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_cx6dx_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "Spectrum",
        "type": fwparse.DEVICE_SPECTRUM,
        "dev_id": [0x249],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0xffffffff, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_sen_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_sen_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_sen_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_sen_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_sen_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_sen_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_sen_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_sen_itrace_irisc7.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_sen_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": [("class1", 0), ("class2", 1)],
        "default_tracer_mode": "FIFO"
    },
    {
        "name": "ConnectX4LX",
        "type": fwparse.DEVICE_CONNECTX4LX,
        "dev_id": [0x20b],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_cx4lx_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_cx4lx_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_cx4lx_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_cx4lx_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_cx4lx_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_cx4lx_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_cx4lx_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_cx4lx_itrace_irisc7.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_cx4lx_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "SwitchIB2",
        "type": fwparse.DEVICE_SWITCHIB2,
        "dev_id": [0x24B],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0xffffffff, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_sib2_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_sib2_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_sib2_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_sib2_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_sib2_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_sib2_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_sib2_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_sib2_itrace_irisc7.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_sib2_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": [("class1", 0), ("class2", 1)],
        "default_tracer_mode": "FIFO"
    },
    {
        "name": "Quantum",
        "type": fwparse.DEVICE_QUANTUM,
        "dev_id": [0x24D],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0xffffffff, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_quantum_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep +
             "mlxtrace_quantum_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_quantum_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_quantum_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_quantum_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_quantum_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_quantum_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_quantum_itrace_irisc7.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_quantum_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": [("class1", 0), ("class2", 1)],
        "default_tracer_mode": "FIFO"
    },
    {
        "name": "Spectrum2",
        "type": fwparse.DEVICE_SPECTRUM2,
        "dev_id": [0x24E],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0xffffffff, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep +
             "mlxtrace_spectrum2_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep +
             "mlxtrace_spectrum2_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep +
             "mlxtrace_spectrum2_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep +
             "mlxtrace_spectrum2_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep +
             "mlxtrace_spectrum2_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep +
             "mlxtrace_spectrum2_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep +
             "mlxtrace_spectrum2_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep +
             "mlxtrace_spectrum2_itrace_irisc7.cfg"),
            (-1, "all", CFG_DIR + os.sep +
             "mlxtrace_spectrum2_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": [("class1", 0), ("class2", 1)],
        "default_tracer_mode": "FIFO"
    },
    {
        "name": "Spectrum3",
        "type": fwparse.DEVICE_SPECTRUM3,
        "dev_id": [0x250],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0xffffffff, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace_irisc9.cfg"),
            (-1, "all", CFG_DIR + os.sep +
             "mlxtrace_spectrum3_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": [("class1", 0), ("class2", 1)],
        "default_tracer_mode": "FIFO"
    },
    {
        "name": "Spectrum4",
        "type": fwparse.DEVICE_SPECTRUM4,
        "dev_id": [0x254],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0xffffffff, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace_irisc9.cfg"),
            (-1, "all", CFG_DIR + os.sep +
             "mlxtrace_spectrum4_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": [("class1", 0), ("class2", 1)],
        "default_tracer_mode": "FIFO"
    },
    {
        "name": "ConnectX6LX",
        "type": fwparse.DEVICE_CONNECTX6LX,
        "dev_id": [0x216],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_cx6lx_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_cx6lx_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_cx6lx_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_cx6lx_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_cx6lx_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_cx6lx_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_cx6lx_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_cx6lx_itrace_irisc7.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_cx6lx_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "ConnectX7",
        "type": fwparse.DEVICE_CONNECTX7,
        "dev_id": [0x218],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0x24780, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep + "mlxtrace_cx7_itrace_irisc9.cfg"),
            (10, "i10", CFG_DIR + os.sep +
             "mlxtrace_cx7_itrace_irisc10.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_cx7_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": list(HCA_MASK_CLASSES),
        "default_tracer_mode": "MEM"
    },
    {
        "name": "Quantum2",
        "type": fwparse.DEVICE_QUANTUM2,
        "dev_id": [0x257],
        "chip_rev":-1,
        "embedded_fw_str_db": True,
        "fw_str_db_signature_exists": False,
        "fw_str_db_signature_addr": (0xffffffff, 0, 16),
        "iriscs": [
            (0, "i0", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc0.cfg"),
            (1, "iron", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc1.cfg"),
            (2, "i2", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc2.cfg"),
            (3, "i3", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc3.cfg"),
            (4, "i4", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc4.cfg"),
            (5, "i5", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc5.cfg"),
            (6, "i6", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc6.cfg"),
            (7, "i7", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc7.cfg"),
            (8, "i8", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc8.cfg"),
            (9, "i9", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace_irisc9.cfg"),
            (-1, "all", CFG_DIR + os.sep + "mlxtrace_quantum2_itrace.cfg")],
        "maskable": True,
        "mask_addr": None,
        # list of (trace type name, start_bit)
        "mask_classes": [("class1", 0), ("class2", 1)],
        "default_tracer_mode": "FIFO"
    },
]

#######################################################

MST_DEVICE = None
CMDIFDEV = None
DEV_NAME = None
DUMP_FILE = None
FW_STR_DB_FILE = None
IRISC_NAME = None
MASK = None
LEVEL = None
STRAMING_MODE = False
SNAPSHOT_MODE = False
TRACER_MODE = None
REAL_TS = False
MLXTRACE_CFG = None
BUF_SIZE = None
FLINT_OCR = ""
GVMI = 0
IGNORE_OLD_EVENTS = False
MEMACCESS_MODE = None
MAX_BUFFER_SIZE_MB = 0xFFFFFFFFFFFFFFFF

#######################################################
class TracerException(Exception):
    pass


#######################################################
def ParseCmdLineArgs():
    global DEV_NAME
    global DUMP_FILE
    global FW_STR_DB_FILE
    global IRISC_NAME
    global MASK
    global LEVEL
    global STRAMING_MODE
    global SNAPSHOT_MODE
    global TRACER_MODE
    global REAL_TS
    global MLXTRACE_CFG
    global BUF_SIZE
    global FLINT_OCR
    global GVMI
    global IGNORE_OLD_EVENTS
    global MEMACCESS_MODE

    try:
        opts, args = getopt.getopt(
            sys.argv[1:], "hd:f:i:m:l:snc:vS:G:",
            ["help", "device=", "fw_strings=", "irisc=",
             "mask=", "level=", "stream", "snapshot", "tracer_mode=",
             "mem_access=", "real_ts",
             "cfg=", "dump=", "version", "buf_size=", "ocr", "gvmi=", "ignore_old_events"])
        for o, a in opts:
            if o in ["-h", "--help"]:
                Help()
                sys.exit(0)
            elif o in ["-d", "--device"]:
                DEV_NAME = a
            elif o in ["--dump"]:
                DUMP_FILE = a
            elif o in ["-f", "--fw_strings"]:
                FW_STR_DB_FILE = a
            elif o in ["-i", "--irisc"]:
                IRISC_NAME = a
            elif o in ["-m", "--mask"]:
                MASK = a
            elif o in ["-l", "--level"]:
                LEVEL = a
            elif o in ["-s", "--stream"]:
                STRAMING_MODE = True
            elif o in ["-n", "--snapshot"]:
                SNAPSHOT_MODE = True
            elif o in ["--tracer_mode"]:
                TRACER_MODE = a
            elif o in ["--real_ts"]:
                REAL_TS = True
            elif o in ["-c", "--cfg"]:
                MLXTRACE_CFG = a
            elif o in ["-S", "--buf_size"]:
                BUF_SIZE = a
            elif o in ["--ocr"]:
                FLINT_OCR = "-ocr"
            elif o in ["-v", "--version"]:
                import tools_version
                tools_version.PrintVersionString(EXEC_NAME, None)
                sys.exit(0)
            elif o in ["-G", "--gvmi"]:
                GVMI = a
            elif o in ["--mem_access"]:
                MEMACCESS_MODE = a
            elif o in ["--ignore_old_events"]:
                IGNORE_OLD_EVENTS = True
            else:
                Usage()
                raise TracerException("Unhandled option: %s" % o)
    except getopt.GetoptError as exp:
        print(exp)
        Usage()
        sys.exit(1)


#######################################################
def GetStatusOutput(cmd):
    """Return (status, output) of executing cmd in a shell.
    This new implementation should work on all platforms.
    """
    pipe = subprocess.Popen(
        cmd, shell=True, universal_newlines=True,
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = str.join("", pipe.stdout.readlines())
    rc = pipe.wait()
    if rc is None:
        rc = 0
    return rc, output


#######################################################
def IsExternal():
    return GetStatusOutput("mlxtrace_int -h")[0] != 0


#######################################################
DEV_ID_MAP = {
    # samerd: tracer enum: trc_mlx_device_enum
    #         device info: device_info g_devs_info

    0xa:  # ConnectIB
        (0x1ff, 0),
    0xd:  # ConnectX-4
        (0x209, 0),
    0xc:  # SwitchIB
        (0x247, 0),
    0xe:  # Spectrum
        (0x249, 0),
    0xf:  # ConnectX-4LX
        (0x20b, 0),
    0x10:  # SwitchIB2
        (0x24b, 0),
    0x11:  # ConnectX-5
        (0x20d, 0),
    0x12:  # ConnectX-6
        (0x20f, 0),
    0x13:  # Quantum
        (0x24d, 0),
    0x14:  # Spectrum 2
        (0x24e, 0),
    0x15:  # BlueField
        (0x211, 0),
    0x16:  # ConnectX-6DX
        (0x212, 0),
    0x17:  # BlueField 2
        (0x214, 0),
    0x18:  # ConnectX-6LX
        (0x216, 0),
    0x19:  # Spectrum 3
        (0x250, 0),
    0x1a:  # ConnectX-7
        (0x218, 0), 
    0x1b:  # Quantum2
        (0x257, 0),
}


def GetDevInfoFromDumpFile(dumpFile):
    fd = open(dumpFile, "rb")
    fd.read()
    fd.seek(0x1c)
    deviceType, = struct.unpack(">I", fd.read(4))
    # NOTE: this is according to mlxtrace enum and not dev_mgt enum

    try:
        return DEV_ID_MAP[deviceType]
    except KeyError:
        raise TracerException(
            "Unknown/Unsupported device type: 0x%x" % deviceType)


#######################################################
def GetDeviceInfoFromDumpFile(dumpFile):
    print(dumpFile)
    devId, chipRev = GetDevInfoFromDumpFile(dumpFile)

    for devInfo in DEV_INFO_DB:
        if devId in devInfo["dev_id"] and \
                (devInfo["chip_rev"] == -1 or devInfo["chip_rev"] == chipRev):
            return devInfo

    raise TracerException(
        "Unknown/Unsupported device with DevId: 0x%x and ChipRev: 0x%x" %
        (devId, chipRev))


#######################################################
def GetDeviceInfo(dev):
    devIdChipRev = dev.read4(0xf0014)
    devId = devIdChipRev & 0xffff
    chipRev = (devIdChipRev >> 16) & 0xf

    for devInfo in DEV_INFO_DB:
        if devId in devInfo["dev_id"] and \
                (devInfo["chip_rev"] == -1 or devInfo["chip_rev"] == chipRev):
            return devInfo

    raise TracerException(
        "Unknown/Unsupported device with DevId: 0x%x and ChipRev: 0x%x" %
        (devId, chipRev))


#######################################################
def CheckSecureFwArgs(devInfo):
    
    if GVMI:
        raise TracerException("gvmi is not compatible with secure fw")
    
    if FW_STR_DB_FILE:
        raise TracerException("Fw strings db file is not compatible with secure fw")

    if IRISC_NAME:
        if IRISC_NAME != "all":
            raise TracerException("only all is compatible with secure fw")

    if SNAPSHOT_MODE:
        raise TracerException("Snapshot is not compatible with secure fw")
    
    if TRACER_MODE:
        if TRACER_MODE not in ["FIFO", "MEM"]:
            raise TracerException("Unknown tracer mode: %s" % TRACER_MODE)
        elif TRACER_MODE == "FIFO":
            raise TracerException("FIFO mode is not compatible with secure fw")

    if MEMACCESS_MODE:
        raise TracerException("memaccess is not compatible with secure fw")
    
    if DUMP_FILE:
        raise TracerException("dump file is not compatible with secure fw")

    maskable = devInfo["maskable"]
    if maskable is None or maskable is False:
        if MASK is not None:
            raise TracerException("This device traces can't be masked")

    if MASK and not IsNumeric(MASK):
        classes = MASK.split("+")
        for klass in classes:
            valid_class = False
            for mask_cls in devInfo["mask_classes"]:
                if mask_cls[0] == klass:
                    valid_class = True
            if not valid_class:
                raise TracerException("Unknown trace class: %s" % klass)

    if (MASK and LEVEL is None) or (LEVEL and MASK is None):
        raise TracerException("both --mask and --level must be provided")
    
    if BUF_SIZE:
        raise TracerException("buf_size is not compatible with secure fw")  
    
    if MLXTRACE_CFG:
        raise TracerException("cfg is not compatible with secure fw")
            
def CheckArgs(devInfo):
    embedded_fw_str_db = devInfo.get('embedded_fw_str_db')
    if not embedded_fw_str_db:
        if FW_STR_DB_FILE is None:
            raise TracerException("Missing fw strings db file")

    if FW_STR_DB_FILE:
        if not os.path.exists(FW_STR_DB_FILE):
            raise TracerException(
                "Fw strings db file doesn't exist: %s" % FW_STR_DB_FILE)

    if IRISC_NAME is None and SNAPSHOT_MODE is False:
        raise TracerException("Missing irisc name")

    if SNAPSHOT_MODE and STRAMING_MODE:
        raise TracerException(
            "Snapshot and Streaming mode cannot be both enabled")

    if IRISC_NAME:
        valid_irisc = False
        for irisc in devInfo["iriscs"]:
            if IRISC_NAME == irisc[1]:
                valid_irisc = True
        if not valid_irisc:
            raise TracerException("Unknown irisc: %s" % IRISC_NAME)

    if DUMP_FILE:
        if FW_STR_DB_FILE is None:
            raise TracerException(
                "In dump file mode you must specify the fw strings db file")
        if STRAMING_MODE:
            raise TracerException(
                "Streaming mode is invalid option in dump file mode")
        if SNAPSHOT_MODE:
            raise TracerException(
                "Snapshot mode is invalid option in dump file mode")

    maskable = devInfo["maskable"]
    if maskable is None or maskable is False:
        if MASK is not None:
            raise TracerException("This device traces can't be masked")

    if MASK and not IsNumeric(MASK):
        classes = MASK.split("+")
        for klass in classes:
            valid_class = False
            for mask_cls in devInfo["mask_classes"]:
                if mask_cls[0] == klass:
                    valid_class = True
            if not valid_class:
                raise TracerException("Unknown trace class: %s" % klass)

    if (MASK and LEVEL is None) or (LEVEL and MASK is None):
        raise TracerException("both --mask and --level must be provided")

    if TRACER_MODE:
        if TRACER_MODE not in ["FIFO", "MEM"]:
            raise TracerException("Unknown tracer mode: %s" % TRACER_MODE)

    if MEMACCESS_MODE:
        if MEMACCESS_MODE not in \
                ("OB_GW", "MEM", "DMEM", "FMEM", "VMEM", "UDRIVER"):
            raise TracerException(
                "Unknown memaccess mode: %s" % MEMACCESS_MODE)
    if BUF_SIZE:
        temp_size = BUF_SIZE
        try:
            if temp_size.startswith("0x"):
                temp_size = int(temp_size, 16)
            else:
                temp_size = int(temp_size)       
            if temp_size > MAX_BUFFER_SIZE_MB:
                raise TracerException("buffer size exceed the limit of 64 bit")
        except ValueError:
            raise TracerException("invalid buffer size: '{}'".format(BUF_SIZE))

#######################################################
def Usage():
    print("Usage:")
    print("\t%s -d|--device <device name>" % (EXEC_NAME),)
    print(" -f|--fw_strings <fw strings db file>",)
    print(" --tracer_mode <FIFO | MEM>",)
    print(" --real_ts",)
    print(" -i|--irisc <irisc name>",)
    print(" -s|--stream",)
    print(" -n|--snapshot",)
    print(" -c|--cfg <mlxtrace cfg file>",)
    print(" -S|--buf_size <buffer size>",)
    print("--dump <.trc dump file>",)
    print(" -m|--mask <class1+class2+...classN>",)
    print(" -l|--level <trace level>",)
    print(" --ignore_old_events",)
    print("")

    print("Run with \"-h\" to see the full list of iriscs and trace classes")


#######################################################
HELP_DESC = """\
    -h|--help                    Print this help message and exit
    -d|--device                  Mst device name
    -f|--fw_strings              Fw strings db file containing the FW strings
      |--tracer_mode             Tracer mode [FIFO | MEM]
      |--real_ts                 Print real timestamps in [hh:mm:ss.nsec]
      |--gvmi                    Global virtual machine interface     
      |--ignore_old_events       Ignore collecting old events \
      
format
    -i|--irisc                   Irisc name \
(See below for full list of irisc names)
    -s|--stream                  Run in streaming mode
    -c|--cfg                     HW tracer events cfg file
    -n|--snapshot                Take events snapshot - \
this assumes previous FW configurations
    -S|--buf_size                HW tracer MEM buffer size in [MB]
       --dump                    mlxtrace generated .trc file name
    -m|--mask                    Trace class mask, use \"+\" to enable \
multiple classes or use integer format, e.g: -m class1+class2+... or 0xff00ff00
    -l|--level                   Trace level
    -v|--version                 Print tool's version and exit


Device Specific Info:
====================
"""


def Help():
    print(HELP_DESC)
    for devInfo in DEV_INFO_DB:
        print("    %s:" % devInfo["name"])

        # Print irisc names
        irisc_names = []
        for irisc in devInfo["iriscs"]:
            irisc_names.append(irisc[1])
        print("        Irisc names: [%s]" % ", ".join(irisc_names))

        # Print itrace classes
        if devInfo['maskable']:
            trace_levels = []
            for m in devInfo["mask_classes"]:
                trace_levels.append(m[0])

            print("    Trace classes:")
            for i in range(0, len(trace_levels), 5):
                print("            " + \
                    ", ".join(trace_levels[i: i + 5]))


#######################################################
def CheckFwStringsDBSignature(devInfo, dev, fwStrDBContents):
    fw_str_db_signature_exists = devInfo.get('fw_str_db_signature_exists')
    if not fw_str_db_signature_exists:
        return

    signAddr = devInfo['fw_str_db_signature_addr']
    fwSign = dev.readField(signAddr[0], signAddr[1], signAddr[2])
    m = md5(fwStrDBContents)
    fileSign = int(m.hexdigest(), 16) & 0xffff
    if fwSign != fileSign:
        TracerException(
            "Fw strings db file signature: 0x%04x doesn't not match image "
            "signature: 0x%04x" % (fileSign, fwSign))


#######################################################
def GetCfgFile(devInfo):
    effCfgFile = GetTmpDir() + os.sep + "itrace_%d.cfg" % os.getpid()
    fwTraceCfg = None
    for irisc in devInfo["iriscs"]:
        if irisc[1] == IRISC_NAME:
            fwTraceCfg = irisc[2]

    if not fwTraceCfg:
        raise TracerException("Unknown irisc: %s" % IRISC_NAME)

    if IsExternal():
        fwTraceCfg += ".ext"
    else:
        fwTraceCfg += ".int"

    # if given mlxtrace cfg file then merge it with fwtrace file
    if MLXTRACE_CFG:
        try:
            hwCfgLines = open(MLXTRACE_CFG, "r").readlines()
            fwCfg = open(fwTraceCfg, "r").read()

            mergedCfg = fwCfg
            for line in hwCfgLines:
                if re.split("\s+", line)[1].find("ITRACE") == -1 and \
                        line.find("DEVICE") == -1:
                    mergedCfg += line

            f = open(effCfgFile, "w+")
            f.write(mergedCfg)
            f.close()
        except Exception as exp:
            raise TracerException(str(exp))

    else:
        shutil.copy(fwTraceCfg, effCfgFile)

    return effCfgFile


#######################################################
def IsNumeric(str):
    if str.startswith("0x") or str.startswith("0X") or str.isdigit():
        try:
            eval(str)
        except:
            return False
        return True
    return False


#######################################################
def ApplyMask(devInfo, dev, cmdifdev):
    if not MASK:
        return 0

    maskAddr = devInfo["mask_addr"]
    level = eval(LEVEL)
    if IsNumeric(MASK):
        mask = eval(MASK)
    else:
        maskClasses = devInfo["mask_classes"]
        reqClasses = MASK.split("+")
        mask = 0
        for reqClass in reqClasses:
            found = False
            for c in maskClasses:
                if c[0] == reqClass:
                    mask += 1 << c[1]
                    found = True
                    break
            if not found:
                raise TracerException("Unknown trace class: %s" % reqClass)

    if maskAddr:
        dev.write4(maskAddr[0], mask)
        dev.write(maskAddr[0] + 4, level)
    elif cmdifdev:
        cmdifdev.setItrace(mask, level)


#######################################################
def GetTracerMode(devInfo):
    if TRACER_MODE:
        return TRACER_MODE
    else:
        return devInfo["default_tracer_mode"]


#######################################################
def GetMemAccessModeFlag():
    if MEMACCESS_MODE:
        return ["-a", MEMACCESS_MODE]
    return []


#######################################################
def CreateDataTlv(startAddr, sectionData):
    return struct.pack(">IIIIII", 1, len(sectionData) + 16,
                       startAddr, 0, 0, 0) + sectionData


ITOC_RE = re.compile(
    "======== .*?itoc_entry ========.*?param0\s+:\s+(\S+)"
    ".*?cache_line_crc\s+:\s+(\S+).*?itoc_entry_crc\s+:\s+(\S+)"
    ".*?/(\S+)-(\S+)\s+\((\S+)\)/\s+\((\S+)\).*?CRC IGNORED$",
    re.DOTALL | re.MULTILINE)


#######################################################
def GetFwImageCrc():
    cmd = "flint -d %s %s v showitoc" % (DEV_NAME, FLINT_OCR)
    rc, out = GetStatusOutput(cmd)
    if rc:
        print(cmd)
        raise TracerException(
            "Failed to extract fw strings db file from image: %s" % out)

    totalCrc = ""
    for m in ITOC_RE.finditer(out):
        loadAddr, cacheLineCrc, crc, startAddr, endAddr, size, name = \
            m.groups()
        if name.endswith("_CODE"):
            totalCrc += "%x" % eval(crc)
    return totalCrc


#######################################################
def RemoveCacheLineCRC(data):
    # For each 64 data bytes we have 4 bytes crc
    # (actually crc16 and 2 bytes are reserved)
    newData = b""
    # if (len(data) % 68):
    #    print "-E- Fatal error section size isn't multiple of 68 bytes"
    for i in range(0, len(data), 68):
        if i + 68 >= len(data):
            break
        newData = b"".join([newData, data[i:i + 64]])

    return newData


#######################################################
def GetTmpDir():
    if IsWindows():
        return "c:\\tmp"
    else:
        return "/tmp"


def close_mst_dev():
    global MST_DEVICE
    global DUMP_FILE
    if DUMP_FILE:
        return
    if MST_DEVICE is not None:
        MST_DEVICE.close()
        MST_DEVICE = None


def open_mst_dev():
    global MST_DEVICE
    global CMDIFDEV
    global DUMP_FILE
    if DUMP_FILE:
        return
    if MST_DEVICE is None:
        MST_DEVICE = mtcr.MstDevice(DEV_NAME)
        if CMDIFDEV is not None:
            CMDIFDEV = cmdif.CmdIf(MST_DEVICE)


#######################################################
def GetFwStringsDBContents(devInfo, cmdifdev, mst_device):
    embedded_fw_str_db = devInfo.get("embedded_fw_str_db")
    if FW_STR_DB_FILE:
        fd = open(FW_STR_DB_FILE, "rb")
        out = fd.read()
        fd.close()
        return out

    elif embedded_fw_str_db:
        # create reaccess object
        regAccessObj = regaccess.RegAccess(mst_device)
        fwVer = ""
        # if regaccess obj exist, get the fw version through regaccess mgir (support dev branch)
        if regAccessObj:
            fwVer = regAccessObj.getFwVersion()

        # in case that the regacces failed or has no version information
        if fwVer == "":
            if cmdifdev:
                fwInfo = cmdifdev.getFwInfo()
                fwVer = "%d.%d.%d" % (fwInfo.MAJOR, fwInfo.MINOR, fwInfo.SUBMINOR)
            else:
                close_mst_dev()
                cmd = "flint -d %s %s -qq q | grep \"FW Version\"" % \
                    (DEV_NAME, FLINT_OCR)
                rc, out = GetStatusOutput(cmd)
                if rc:
                    print(cmd)
                    close_mst_dev()
                    raise TracerException("Failed to read FW version: %s" % out)
                fwVer = out.split(":")[-1].strip()

        # Try to find the fw string db in cache file
        user = getpass.getuser()
        close_mst_dev()
        imageCrc = GetFwImageCrc()
        cacheFName = GetTmpDir() + os.sep + \
            "fwtrace_str_db_cache_%s_%s_%s" % \
            (user, fwVer.replace(".", "_"), imageCrc)
        userCacheFiles = glob.glob(GetTmpDir() + os.sep +
                                   "fwtrace_str_db_cache_%s_*" % user)

        if len(userCacheFiles) > 0:
            # fix cache files, only one should be available for each user
            if len(userCacheFiles) > 1:
                for f in userCacheFiles:
                    try:
                        os.remove(f)
                    except:
                        pass

            if userCacheFiles[0] == cacheFName:
                data = open(cacheFName, "rb").read()
                if data != "":
                    print("-I- Found FW string db cache file, going to use it")
                    return data
            else:
                os.remove(userCacheFiles[0])

        # cache file wasn't found
        sys.stdout.write("Reading FW strings.")
        sys.stdout.flush()
        cmd = "flint -d %s %s v showitoc" % (DEV_NAME, FLINT_OCR)
        rc, out = GetStatusOutput(cmd)
        if rc:
            print(cmd)
            close_mst_dev()
            raise TracerException(
                "Failed to extract fw strings db file from image: %s" % out)

        tlvData = b""
        for m in ITOC_RE.finditer(out):
            sys.stdout.write(".")
            sys.stdout.flush()
            loadAddr, cacheLineCrc, crc, startAddr, endAddr, size, name = \
                m.groups()
            loadAddr = eval(loadAddr)
            cacheLineCrc = eval(cacheLineCrc)
            startAddr = eval(startAddr)
            endAddr = eval(endAddr)
            size = eval(size)
            # itocCrc = eval
            # print "name: %s, crc: %s, loadAddr 0x%x, startAddr 0x%x, \
            # endAddr 0x%x, size 0x%x" % (name, crc, loadAddr, startAddr, \
            # endAddr, size)

            if name.endswith("_CODE") and name != "ROM_CODE":
                tmpFile = tempfile.NamedTemporaryFile()
                tmpFileName = tmpFile.name
                tmpFile.close()

                cmd = "flint -d %s %s rb 0x%x 0x%x %s" % \
                    (DEV_NAME, FLINT_OCR, startAddr, size, tmpFileName)
                rc, out = GetStatusOutput(cmd)
                if rc:
                    print(cmd)
                    tmpFile.close()
                    close_mst_dev()
                    raise TracerException(
                        "Failed to read from flash: %s" % out)
                tmpFile = open(tmpFileName, "rb")
                data = tmpFile.read()
                tmpFile.close()

                if cacheLineCrc == 1:
                    data = RemoveCacheLineCRC(data)

                # print "Adding to tlv: name: %s, \
                # startAddr = 0x%x" % (name, loadAddr)
                tmp = CreateDataTlv(loadAddr, data)
                tlvData = b"".join([tlvData, tmp])

        print(".")
        # save cache file
        if tlvData == "":
            close_mst_dev()
            raise TracerException(
                "Failed to read fw strings db section from flash: %s" % out)

        fd = open(cacheFName, "w+b")
        fd.write(tlvData)
        fd.close()
        return tlvData

    else:
        raise TracerException(
            "FW strings db file isn't given and image doesn't contain "
            "embedded file, please run with \"-f\"")


#######################################################
def getIriscNameMap(devInfo):
    iriscMap = {}
    for i in devInfo['iriscs']:
        iriscMap[i[0]] = i[1]
    return iriscMap


#######################################################
def Clean():
    fwStrDBFile = GetTmpDir() + os.sep + "fw_str_db_%d.csv" % os.getpid()
    if os.path.exists(fwStrDBFile):
        os.remove(fwStrDBFile)

    itraceTxtFile = GetTmpDir() + os.sep + "itrace_%d.txt" % os.getpid()
    if os.path.exists(itraceTxtFile):
        os.remove(itraceTxtFile)

    itraceBinFile = GetTmpDir() + os.sep + "itrace_%d.trc" % os.getpid()
    if os.path.exists(itraceBinFile):
        os.remove(itraceBinFile)

    cfgFile = GetTmpDir() + os.sep + "itrace_%d.cfg" % os.getpid()
    if os.path.exists(cfgFile):
        os.remove(cfgFile)


def GetSkipOwnershipFlag():
    global MST_DEVICE
    skipOwnershipFlag = ""
    if MST_DEVICE is None:
        return skipOwnershipFlag

    regAccessObj = regaccess.RegAccess(MST_DEVICE)
    rc = regAccessObj.sendMtrcCapTakeOwnership()

    if rc == regaccess.ownershipEnum.REG_ACCESS_FAILED_TO_AQUIRE_OWNERSHIP:
        print("Failed to acquire ownership.")
    elif rc == regaccess.ownershipEnum.REG_ACCESS_NO_OWNERSHIP_REQUIRED:
        print("No ownership taking is required.")
    else:
        print("Got ownership successfully!")
        skipOwnershipFlag = "--skip_ownership"
    return skipOwnershipFlag


#######################################################
def StartTracer():
    
    try:
        ParseCmdLineArgs()
        if DEV_NAME is None and DUMP_FILE is None:
            Usage()
            return 1
        if DEV_NAME:
            global MST_DEVICE
            global CMDIFDEV
            MST_DEVICE = mtcr.MstDevice(DEV_NAME)
            if MST_DEVICE.is_cable() or MST_DEVICE.is_linkx():
                success_indication = 1
                raise TracerException("Device is not supported")
            devInfo = GetDeviceInfo(MST_DEVICE)
            CMDIFDEV = cmdif.CmdIf(MST_DEVICE)
        else:
            devInfo = GetDeviceInfoFromDumpFile(DUMP_FILE)

        if FwTraceUtilities.is_secure_fw(MST_DEVICE):
            success_indication = 0
            if FwTraceUtilities.is_driver_mem_mode_supported():
                try:
                    CheckSecureFwArgs(devInfo)
                    secure_fw_tracer = SecureFwTrace(MST_DEVICE, DEV_NAME, IGNORE_OLD_EVENTS, REAL_TS)               
                    open_mst_dev()           
                    ApplyMask(devInfo, MST_DEVICE, CMDIFDEV)
                    secure_fw_tracer.parse_driver_mem()
                except Exception as exp:
                    print("-E- %s" % exp)
                    success_indication = 1
            else:
                raise TracerException("Driver mem mode is not supported")
                success_indication = 1

            return success_indication
        
        CheckArgs(devInfo)
        
        fwStrDBContents = GetFwStringsDBContents(devInfo, CMDIFDEV, MST_DEVICE)
        open_mst_dev()
        skipOwnershipFlag = GetSkipOwnershipFlag()

 
        if DEV_NAME:
            CheckFwStringsDBSignature(devInfo, MST_DEVICE, fwStrDBContents)
            ApplyMask(devInfo, MST_DEVICE, CMDIFDEV)
        close_mst_dev()
        if not SNAPSHOT_MODE:
            cfgFile = GetCfgFile(devInfo)
        tracerMode = GetTracerMode(devInfo)
        memaccessMode = GetMemAccessModeFlag()
        iriscsNamesMap = getIriscNameMap(devInfo)
        fwParser = fwparse.FwTraceParser(
            devInfo['type'], fwStrDBContents, iriscsNamesMap)
        realTs = ""
        if REAL_TS:
            realTs = "--real_ts"
        gvmi = ""
        if GVMI != 0:
            gvmi = "--gvmi=%s" % GVMI
        ignore_old_events = ""
        if IGNORE_OLD_EVENTS != False:
            ignore_old_events = "--ignore_old_events"    
        if STRAMING_MODE:
            cmd = [MLXTRACE_EXE, "-d", DEV_NAME, "-m", tracerMode,
                   "-c", cfgFile, realTs, gvmi, skipOwnershipFlag, "-S", ignore_old_events]
            cmd += memaccessMode
            print(" ".join(cmd))
            global proc
            if IsWindows():
                proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                        shell=True)
            else:
                proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            try:
                while True:
                    if proc.poll():
                        for line in proc.stdout.readlines():
                            fwParser.pushLine(line)
                        print("Stopping ...")
                        break
                    else:
                        line = proc.stdout.readline()
                        fwParser.pushLine(line)
            except KeyboardInterrupt:
                try:
                    proc.terminate()
                    proc.wait()
                except:
                    pass
                print("\nStopping & Flushing... "\
                    "(messages below may have missing arguments)")
                fwParser.flushAll()
        else:
            if not DUMP_FILE:
                if memaccessMode is None:
                    memaccessModeFlag = ""
                else:
                    memaccessModeFlag = " ".join(memaccessMode)
                if SNAPSHOT_MODE:
                    cmd = "%s -d %s -m %s %s -o %s%sitrace_%d.trc -n" % \
                        (MLXTRACE_EXE, DEV_NAME, tracerMode, memaccessModeFlag,
                         GetTmpDir(), os.sep, os.getpid())
                else:
                    cmd = "%s -d %s -m %s %s -c %s -o %s%sitrace_%d.trc" % \
                        (MLXTRACE_EXE, DEV_NAME, tracerMode, memaccessModeFlag,
                         cfgFile, GetTmpDir(), os.sep, os.getpid())
                if BUF_SIZE:
                    cmd += " --buf_size=%s" % BUF_SIZE
                cmd += " %s" % gvmi
                cmd += " %s" % skipOwnershipFlag
                print(cmd)
                rc = os.system(cmd)
                if os.name != "nt":
                    if rc & 0xff:
                        print("Command was interrupted with signal %d" % (rc & 0xff))
                    rc = rc >> 8
                if rc:
                    raise TracerException("Failed while running mlxtrace (rc = %d)" % rc)

            if DUMP_FILE:
                cmd = "%s -p %s -i %s > %s%sitrace_%d.txt" % \
                    (MLXTRACE_EXE, realTs, DUMP_FILE, GetTmpDir(), os.sep,
                     os.getpid())
            else:
                dmp_file = "%s%sitrace_%d.trc" % \
                    (GetTmpDir(), os.sep, os.getpid())
                if not os.path.exists(dmp_file):
                    print("\n-I- No dump file were generated, exiting ...")
                    return 0
                cmd = "%s -p %s -i %s > %s%sitrace_%d.txt" % \
                    (MLXTRACE_EXE, realTs, dmp_file, GetTmpDir(), os.sep,
                     os.getpid())

            print(cmd)
            if os.system(cmd):
                raise TracerException("Failed to parse mlxtrace dump file")

            if os.path.exists("%s%sitrace_%d.txt" %
                              (GetTmpDir(), os.sep, os.getpid())):
                fd = open("%s%sitrace_%d.txt" %
                          (GetTmpDir(), os.sep, os.getpid()), "rb")
                try:
                    for line in fd:
                        fwParser.pushLine(line)
                except KeyboardInterrupt:
                    print("\nStopping & Flushing... "\
                        "(messages below may have missing arguments)")
                    fwParser.flushAll()

                fwParser.flushAll()
                fd.close()

        Clean()
    except Exception as exp:
        print("-E- %s" % exp)
        Clean()
        return 1

    return 0


#######################################################
if __name__ == "__main__":
    try:
        signal.signal(signal.SIGINT, signal_handler)
        rc = StartTracer()
    except Exception as exp:
        try:
            print("-E- %s" % str(exp))
        except:
            pass
        rc = 1
    sys.exit(rc)