cxgbe(4): Initial import of the "collect" component of Chelsio unified

debug (cudbg) code, hooked up to the main driver via an ioctl.

The ioctl can be used to collect the chip's internal state in a
compressed dump file.  These dumps can be decoded with the "view"
component of cudbg.

Obtained from:	Chelsio Communications
MFC after:	2 months
Sponsored by:	Chelsio Communications
This commit is contained in:
Navdeep Parhar 2017-08-03 14:43:30 +00:00
parent 079f5b9b7b
commit f856f099cb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=322014
17 changed files with 9414 additions and 2 deletions

View File

@ -1352,6 +1352,18 @@ dev/cxgbe/common/t4_hw.c optional cxgbe pci \
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
dev/cxgbe/common/t4vf_hw.c optional cxgbev pci \
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
dev/cxgbe/cudbg/cudbg_common.c optional cxgbe \
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
dev/cxgbe/cudbg/cudbg_flash_utils.c optional cxgbe \
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
dev/cxgbe/cudbg/cudbg_lib.c optional cxgbe \
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
dev/cxgbe/cudbg/cudbg_wtp.c optional cxgbe \
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
dev/cxgbe/cudbg/fastlz.c optional cxgbe \
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
dev/cxgbe/cudbg/fastlz_api.c optional cxgbe \
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
t4fw_cfg.c optional cxgbe \
compile-with "${AWK} -f $S/tools/fw_stub.awk t4fw_cfg.fw:t4fw_cfg t4fw_cfg_uwire.fw:t4fw_cfg_uwire t4fw.fw:t4fw -mt4fw_cfg -c${.TARGET}" \
no-implicit-rule before-depend local \

View File

@ -276,8 +276,17 @@ enum {
FLASH_MIN_SIZE = FLASH_CFG_START + FLASH_CFG_MAX_SIZE,
/*
* Sectors 32-63 are reserved for FLASH failover.
* Sectors 32-63 for CUDBG.
*/
FLASH_CUDBG_START_SEC = 32,
FLASH_CUDBG_NSECS = 32,
FLASH_CUDBG_START = FLASH_START(FLASH_CUDBG_START_SEC),
FLASH_CUDBG_MAX_SIZE = FLASH_MAX_SIZE(FLASH_CUDBG_NSECS),
/*
* Size of defined FLASH regions.
*/
FLASH_END_SEC = 64,
};
#undef FLASH_START

474
sys/dev/cxgbe/cudbg/cudbg.h Normal file
View File

@ -0,0 +1,474 @@
/*-
* Copyright (c) 2017 Chelsio Communications, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*
*/
/*
* Chelsio Unified Debug Interface header file.
* Version 1.1
*/
#ifndef _CUDBG_IF_H_
#define _CUDBG_IF_H_
#ifdef __GNUC__
#define ATTRIBUTE_UNUSED __attribute__ ((unused))
#else
#define ATTRIBUTE_UNUSED
#endif
#if defined(CONFIG_CUDBG_DEBUG)
#define cudbg_debug(pdbg_init, format, ...) do {\
pdbg_init->print(format, ##__VA_ARGS__); \
} while (0)
#else
#define cudbg_debug(pdbg_init, format, ...) do { } while (0)
#endif
#define OUT
#define IN
#define INOUT
/* Error codes */
#define CUDBG_STATUS_SUCCESS 0
#define CUDBG_STATUS_NOSPACE -2
#define CUDBG_STATUS_FLASH_WRITE_FAIL -3
#define CUDBG_STATUS_FLASH_READ_FAIL -4
#define CUDBG_STATUS_UNDEFINED_OUT_BUF -5
#define CUDBG_STATUS_UNDEFINED_CBFN -6
#define CUDBG_STATUS_UNDEFINED_PRINTF_CBFN -7
#define CUDBG_STATUS_ADAP_INVALID -8
#define CUDBG_STATUS_FLASH_EMPTY -9
#define CUDBG_STATUS_NO_ADAPTER -10
#define CUDBG_STATUS_NO_SIGNATURE -11
#define CUDBG_STATUS_MULTIPLE_REG -12
#define CUDBG_STATUS_UNREGISTERED -13
#define CUDBG_STATUS_UNDEFINED_ENTITY -14
#define CUDBG_STATUS_REG_FAIlED -15
#define CUDBG_STATUS_DEVLOG_FAILED -16
#define CUDBG_STATUS_SMALL_BUFF -17
#define CUDBG_STATUS_CHKSUM_MISSMATCH -18
#define CUDBG_STATUS_NO_SCRATCH_MEM -19
#define CUDBG_STATUS_OUTBUFF_OVERFLOW -20
#define CUDBG_STATUS_INVALID_BUFF -21 /* Invalid magic */
#define CUDBG_STATUS_FILE_OPEN_FAIL -22
#define CUDBG_STATUS_DEVLOG_INT_FAIL -23
#define CUDBG_STATUS_ENTITY_NOT_FOUND -24
#define CUDBG_STATUS_DECOMPRESS_FAIL -25
#define CUDBG_STATUS_BUFFER_SHORT -26
#define CUDBG_METADATA_VERSION_MISMATCH -27
#define CUDBG_STATUS_NOT_IMPLEMENTED -28
#define CUDBG_SYSTEM_ERROR -29
#define CUDBG_STATUS_MMAP_FAILED -30
#define CUDBG_STATUS_FILE_WRITE_FAILED -31
#define CUDBG_STATUS_CCLK_NOT_DEFINED -32
#define CUDBG_STATUS_FLASH_FULL -33
#define CUDBG_STATUS_SECTOR_EMPTY -34
#define CUDBG_STATUS_ENTITY_NOT_REQUESTED -35
#define CUDBG_STATUS_NOT_SUPPORTED -36
#define CUDBG_STATUS_FILE_READ_FAILED -37
#define CUDBG_STATUS_CORRUPTED -38
#define CUDBG_STATUS_INVALID_INDEX -39
#define CUDBG_MAJOR_VERSION 1
#define CUDBG_MINOR_VERSION 14
#define CUDBG_BUILD_VERSION 0
#define CUDBG_FILE_NAME_LEN 256
#define CUDBG_DIR_NAME_LEN 256
#define CUDBG_MAX_BITMAP_LEN 16
static char ATTRIBUTE_UNUSED * err_msg[] = {
"Success",
"Unknown",
"No space",
"Flash write fail",
"Flash read fail",
"Undefined out buf",
"Callback function undefined",
"Print callback function undefined",
"ADAP invalid",
"Flash empty",
"No adapter",
"No signature",
"Multiple registration",
"Unregistered",
"Undefined entity",
"Reg failed",
"Devlog failed",
"Small buff",
"Checksum mismatch",
"No scratch memory",
"Outbuff overflow",
"Invalid buffer",
"File open fail",
"Devlog int fail",
"Entity not found",
"Decompress fail",
"Buffer short",
"Version mismatch",
"Not implemented",
"System error",
"Mmap failed",
"File write failed",
"cclk not defined",
"Flash full",
"Sector empty",
"Entity not requested",
"Not supported",
"File read fail",
"Corrupted",
"Invalid Index"
};
enum CUDBG_DBG_ENTITY_TYPE {
CUDBG_ALL = 0,
CUDBG_REG_DUMP = 1,
CUDBG_DEV_LOG = 2,
CUDBG_CIM_LA = 3,
CUDBG_CIM_MA_LA = 4,
CUDBG_CIM_QCFG = 5,
CUDBG_CIM_IBQ_TP0 = 6,
CUDBG_CIM_IBQ_TP1 = 7,
CUDBG_CIM_IBQ_ULP = 8,
CUDBG_CIM_IBQ_SGE0 = 9,
CUDBG_CIM_IBQ_SGE1 = 10,
CUDBG_CIM_IBQ_NCSI = 11,
CUDBG_CIM_OBQ_ULP0 = 12,
CUDBG_CIM_OBQ_ULP1 = 13,
CUDBG_CIM_OBQ_ULP2 = 14,
CUDBG_CIM_OBQ_ULP3 = 15,
CUDBG_CIM_OBQ_SGE = 16,
CUDBG_CIM_OBQ_NCSI = 17,
CUDBG_EDC0 = 18,
CUDBG_EDC1 = 19,
CUDBG_MC0 = 20,
CUDBG_MC1 = 21,
CUDBG_RSS = 22,
CUDBG_RSS_PF_CONF = 23,
CUDBG_RSS_KEY = 24,
CUDBG_RSS_VF_CONF = 25,
CUDBG_RSS_CONF = 26,
CUDBG_PATH_MTU = 27,
CUDBG_SW_STATE = 28,
CUDBG_WTP = 29,
CUDBG_PM_STATS = 30,
CUDBG_HW_SCHED = 31,
CUDBG_TCP_STATS = 32,
CUDBG_TP_ERR_STATS = 33,
CUDBG_FCOE_STATS = 34,
CUDBG_RDMA_STATS = 35,
CUDBG_TP_INDIRECT = 36,
CUDBG_SGE_INDIRECT = 37,
CUDBG_CPL_STATS = 38,
CUDBG_DDP_STATS = 39,
CUDBG_WC_STATS = 40,
CUDBG_ULPRX_LA = 41,
CUDBG_LB_STATS = 42,
CUDBG_TP_LA = 43,
CUDBG_MEMINFO = 44,
CUDBG_CIM_PIF_LA = 45,
CUDBG_CLK = 46,
CUDBG_CIM_OBQ_RXQ0 = 47,
CUDBG_CIM_OBQ_RXQ1 = 48,
CUDBG_MAC_STATS = 49,
CUDBG_PCIE_INDIRECT = 50,
CUDBG_PM_INDIRECT = 51,
CUDBG_FULL = 52,
CUDBG_TX_RATE = 53,
CUDBG_TID_INFO = 54,
CUDBG_PCIE_CONFIG = 55,
CUDBG_DUMP_CONTEXT = 56,
CUDBG_MPS_TCAM = 57,
CUDBG_VPD_DATA = 58,
CUDBG_LE_TCAM = 59,
CUDBG_CCTRL = 60,
CUDBG_MA_INDIRECT = 61,
CUDBG_ULPTX_LA = 62,
CUDBG_EXT_ENTITY = 63,
CUDBG_UP_CIM_INDIRECT = 64,
CUDBG_PBT_TABLE = 65,
CUDBG_MBOX_LOG = 66,
CUDBG_HMA_INDIRECT = 67,
CUDBG_MAX_ENTITY = 68,
};
#define ENTITY_FLAG_NULL 0
#define ENTITY_FLAG_REGISTER 1
#define ENTITY_FLAG_BINARY 2
#define ENTITY_FLAG_FW_NO_ATTACH 3
/* file_name matches Linux cxgb4 debugfs entry names. */
struct el {char *name; char *file_name; int bit; u32 flag; };
static struct el ATTRIBUTE_UNUSED entity_list[] = {
{"all", "all", CUDBG_ALL, ENTITY_FLAG_NULL},
{"regdump", "regdump", CUDBG_REG_DUMP, 1 << ENTITY_FLAG_REGISTER},
/* {"reg", CUDBG_REG_DUMP},*/
{"devlog", "devlog", CUDBG_DEV_LOG, ENTITY_FLAG_NULL},
{"cimla", "cim_la", CUDBG_CIM_LA, ENTITY_FLAG_NULL},
{"cimmala", "cim_ma_la", CUDBG_CIM_MA_LA, ENTITY_FLAG_NULL},
{"cimqcfg", "cim_qcfg", CUDBG_CIM_QCFG, ENTITY_FLAG_NULL},
{"ibqtp0", "ibq_tp0", CUDBG_CIM_IBQ_TP0, ENTITY_FLAG_NULL},
{"ibqtp1", "ibq_tp1", CUDBG_CIM_IBQ_TP1, ENTITY_FLAG_NULL},
{"ibqulp", "ibq_ulp", CUDBG_CIM_IBQ_ULP, ENTITY_FLAG_NULL},
{"ibqsge0", "ibq_sge0", CUDBG_CIM_IBQ_SGE0, ENTITY_FLAG_NULL},
{"ibqsge1", "ibq_sge1", CUDBG_CIM_IBQ_SGE1, ENTITY_FLAG_NULL},
{"ibqncsi", "ibq_ncsi", CUDBG_CIM_IBQ_NCSI, ENTITY_FLAG_NULL},
{"obqulp0", "obq_ulp0", CUDBG_CIM_OBQ_ULP0, ENTITY_FLAG_NULL},
/* {"cimobqulp1", CUDBG_CIM_OBQ_ULP1},*/
{"obqulp1", "obq_ulp1", CUDBG_CIM_OBQ_ULP1, ENTITY_FLAG_NULL},
{"obqulp2", "obq_ulp2", CUDBG_CIM_OBQ_ULP2, ENTITY_FLAG_NULL},
{"obqulp3", "obq_ulp3", CUDBG_CIM_OBQ_ULP3, ENTITY_FLAG_NULL},
{"obqsge", "obq_sge", CUDBG_CIM_OBQ_SGE, ENTITY_FLAG_NULL},
{"obqncsi", "obq_ncsi", CUDBG_CIM_OBQ_NCSI, ENTITY_FLAG_NULL},
{"edc0", "edc0", CUDBG_EDC0, (1 << ENTITY_FLAG_BINARY)},
{"edc1", "edc1", CUDBG_EDC1, (1 << ENTITY_FLAG_BINARY)},
{"mc0", "mc0", CUDBG_MC0, (1 << ENTITY_FLAG_BINARY)},
{"mc1", "mc1", CUDBG_MC1, (1 << ENTITY_FLAG_BINARY)},
{"rss", "rss", CUDBG_RSS, ENTITY_FLAG_NULL},
{"rss_pf_config", "rss_pf_config", CUDBG_RSS_PF_CONF, ENTITY_FLAG_NULL},
{"rss_key", "rss_key", CUDBG_RSS_KEY, ENTITY_FLAG_NULL},
{"rss_vf_config", "rss_vf_config", CUDBG_RSS_VF_CONF, ENTITY_FLAG_NULL},
{"rss_config", "rss_config", CUDBG_RSS_CONF, ENTITY_FLAG_NULL},
{"pathmtu", "path_mtus", CUDBG_PATH_MTU, ENTITY_FLAG_NULL},
{"swstate", "sw_state", CUDBG_SW_STATE, ENTITY_FLAG_NULL},
{"wtp", "wtp", CUDBG_WTP, ENTITY_FLAG_NULL},
{"pmstats", "pm_stats", CUDBG_PM_STATS, ENTITY_FLAG_NULL},
{"hwsched", "hw_sched", CUDBG_HW_SCHED, ENTITY_FLAG_NULL},
{"tcpstats", "tcp_stats", CUDBG_TCP_STATS, ENTITY_FLAG_NULL},
{"tperrstats", "tp_err_stats", CUDBG_TP_ERR_STATS, ENTITY_FLAG_NULL},
{"fcoestats", "fcoe_stats", CUDBG_FCOE_STATS, ENTITY_FLAG_NULL},
{"rdmastats", "rdma_stats", CUDBG_RDMA_STATS, ENTITY_FLAG_NULL},
{"tpindirect", "tp_indirect", CUDBG_TP_INDIRECT,
1 << ENTITY_FLAG_REGISTER},
{"sgeindirect", "sge_indirect", CUDBG_SGE_INDIRECT,
1 << ENTITY_FLAG_REGISTER},
{"cplstats", "cpl_stats", CUDBG_CPL_STATS, ENTITY_FLAG_NULL},
{"ddpstats", "ddp_stats", CUDBG_DDP_STATS, ENTITY_FLAG_NULL},
{"wcstats", "wc_stats", CUDBG_WC_STATS, ENTITY_FLAG_NULL},
{"ulprxla", "ulprx_la", CUDBG_ULPRX_LA, ENTITY_FLAG_NULL},
{"lbstats", "lb_stats", CUDBG_LB_STATS, ENTITY_FLAG_NULL},
{"tpla", "tp_la", CUDBG_TP_LA, ENTITY_FLAG_NULL},
{"meminfo", "meminfo", CUDBG_MEMINFO, ENTITY_FLAG_NULL},
{"cimpifla", "cim_pif_la", CUDBG_CIM_PIF_LA, ENTITY_FLAG_NULL},
{"clk", "clk", CUDBG_CLK, ENTITY_FLAG_NULL},
{"obq_sge_rx_q0", "obq_sge_rx_q0", CUDBG_CIM_OBQ_RXQ0,
ENTITY_FLAG_NULL},
{"obq_sge_rx_q1", "obq_sge_rx_q1", CUDBG_CIM_OBQ_RXQ1,
ENTITY_FLAG_NULL},
{"macstats", "mac_stats", CUDBG_MAC_STATS, ENTITY_FLAG_NULL},
{"pcieindirect", "pcie_indirect", CUDBG_PCIE_INDIRECT,
1 << ENTITY_FLAG_REGISTER},
{"pmindirect", "pm_indirect", CUDBG_PM_INDIRECT,
1 << ENTITY_FLAG_REGISTER},
{"full", "full", CUDBG_FULL, ENTITY_FLAG_NULL},
{"txrate", "tx_rate", CUDBG_TX_RATE, ENTITY_FLAG_NULL},
{"tidinfo", "tids", CUDBG_TID_INFO, ENTITY_FLAG_NULL |
(1 << ENTITY_FLAG_FW_NO_ATTACH)},
{"pcieconfig", "pcie_config", CUDBG_PCIE_CONFIG, ENTITY_FLAG_NULL},
{"dumpcontext", "dump_context", CUDBG_DUMP_CONTEXT, ENTITY_FLAG_NULL},
{"mpstcam", "mps_tcam", CUDBG_MPS_TCAM, ENTITY_FLAG_NULL},
{"vpddata", "vpd_data", CUDBG_VPD_DATA, ENTITY_FLAG_NULL},
{"letcam", "le_tcam", CUDBG_LE_TCAM, ENTITY_FLAG_NULL},
{"cctrl", "cctrl", CUDBG_CCTRL, ENTITY_FLAG_NULL},
{"maindirect", "ma_indirect", CUDBG_MA_INDIRECT,
1 << ENTITY_FLAG_REGISTER},
{"ulptxla", "ulptx_la", CUDBG_ULPTX_LA, ENTITY_FLAG_NULL},
{"extentity", "ext_entity", CUDBG_EXT_ENTITY, ENTITY_FLAG_NULL},
{"upcimindirect", "up_cim_indirect", CUDBG_UP_CIM_INDIRECT,
1 << ENTITY_FLAG_REGISTER},
{"pbttables", "pbt_tables", CUDBG_PBT_TABLE, ENTITY_FLAG_NULL},
{"mboxlog", "mboxlog", CUDBG_MBOX_LOG, ENTITY_FLAG_NULL},
{"hmaindirect", "hma_indirect", CUDBG_HMA_INDIRECT,
1 << ENTITY_FLAG_REGISTER},
};
typedef int (*cudbg_print_cb) (char *str, ...);
struct cudbg_init_hdr {
u8 major_ver;
u8 minor_ver;
u8 build_ver;
u8 res;
u16 init_struct_size;
};
struct cudbg_flash_hdr {
u32 signature;
u8 major_ver;
u8 minor_ver;
u8 build_ver;
u8 res;
u64 timestamp;
u64 time_res;
u32 hdr_len;
u32 data_len;
u32 hdr_flags;
u32 sec_seq_no;
u32 reserved[22];
};
struct cudbg_param {
u16 param_type;
u16 reserved;
union {
struct {
u32 memtype; /* which memory (EDC0, EDC1, MC) */
u32 start; /* start of log in firmware memory */
u32 size; /* size of log */
} devlog_param;
struct {
struct mbox_cmd_log *log;
u16 mbox_cmds;
} mboxlog_param;
struct {
u8 caller_string[100];
u8 os_type;
} sw_state_param;
u64 time;
u8 tcb_bit_param;
void *adap;
void *access_lock;
} u;
};
/* params for tcb_bit_param */
#define CUDBG_TCB_BRIEF_PARAM 0x1
#define CUDBG_TCB_FROM_CARD_PARAM 0x2
#define CUDBG_TCB_AS_SCB_PARAM 0x4
/*
* * What is OFFLINE_VIEW_ONLY mode?
*
* cudbg frame work will be used only to interpret previously collected
* data store in a file (i.e NOT hw flash)
*/
struct cudbg_init {
struct cudbg_init_hdr header;
struct adapter *adap; /* Pointer to adapter structure
with filled fields */
cudbg_print_cb print; /* Platform dependent print
function */
u32 verbose:1; /* Turn on verbose print */
u32 use_flash:1; /* Use flash to collect or view
debug */
u32 full_mode:1; /* If set, cudbg will pull in
common code */
u32 no_compress:1; /* Dont compress will storing
the collected debug */
u32 info:1; /* Show just the info, Dont
interpret */
u32 reserved:27;
u8 dbg_bitmap[CUDBG_MAX_BITMAP_LEN];
/* Bit map to select the dbg
data type to be collected
or viewed */
};
/********************************* Helper functions *************************/
static inline void set_dbg_bitmap(u8 *bitmap, enum CUDBG_DBG_ENTITY_TYPE type)
{
int index = type / 8;
int bit = type % 8;
bitmap[index] |= (1 << bit);
}
static inline void reset_dbg_bitmap(u8 *bitmap, enum CUDBG_DBG_ENTITY_TYPE type)
{
int index = type / 8;
int bit = type % 8;
bitmap[index] &= ~(1 << bit);
}
/********************************* End of Helper functions
* *************************/
/* API Prototypes */
/**
* cudbg_alloc_handle - Allocates and initializes a handle that represents
* cudbg state. Needs to called first before calling any other function.
*
* returns a pointer to memory that has a cudbg_init structure at the begining
* and enough space after that for internal book keeping.
*/
void *cudbg_alloc_handle(void);
static inline struct cudbg_init *cudbg_get_init(void *handle)
{
return (handle);
}
/**
* cudbg_collect - Collect and store debug information.
* ## Parameters ##
* @handle : A pointer returned by cudbg_alloc_handle.
* @outbuf : pointer to output buffer, to store the collected information
* or to use it as a scratch buffer in case HW flash is used to
* store the debug information.
* @outbuf_size : Size of output buffer.
* ## Return ##
* If the function succeeds, the return value will be size of debug information
* collected and stored.
* -ve value represent error.
*/
int cudbg_collect(void *handle, void *outbuf, u32 *outbuf_size);
/**
* cudbg_free_handle - Release cudbg resources.
* ## Parameters ##
* @handle : A pointer returned by cudbg_alloc_handle.
*/
void cudbg_free_handle(IN void *handle);
/**
* cudbg_read_flash_data - Read cudbg flash header from adapter flash.
* This will be used by the consumer mainly to
* know the size of the data in flash.
* ## Parameters ##
* @handle : A pointer returned by cudbg_hello.
* @data : A pointer to data/header buffer
*/
int cudbg_read_flash_details(void *handle, struct cudbg_flash_hdr *data);
/**
* cudbg_read_flash_data - Read cudbg dump contents stored in flash.
* ## Parameters ##
* @handle : A pointer returned by cudbg_hello.
* @data_buf : A pointer to data buffer.
* @data_buf_size : Data buffer size.
*/
int cudbg_read_flash_data(void *handle, void *data_buf, u32 data_buf_size);
#endif /* _CUDBG_IF_H_ */

View File

@ -0,0 +1,96 @@
/*-
* Copyright (c) 2017 Chelsio Communications, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include "common/common.h"
#include "cudbg.h"
#include "cudbg_lib_common.h"
int get_scratch_buff(struct cudbg_buffer *pdbg_buff, u32 size,
struct cudbg_buffer *pscratch_buff)
{
u32 scratch_offset;
int rc = 0;
scratch_offset = pdbg_buff->size - size;
if (pdbg_buff->offset > (int)scratch_offset || pdbg_buff->size < size) {
rc = CUDBG_STATUS_NO_SCRATCH_MEM;
goto err;
} else {
pscratch_buff->data = (char *)pdbg_buff->data + scratch_offset;
pscratch_buff->offset = 0;
pscratch_buff->size = size;
pdbg_buff->size -= size;
}
err:
return rc;
}
void release_scratch_buff(struct cudbg_buffer *pscratch_buff,
struct cudbg_buffer *pdbg_buff)
{
pdbg_buff->size += pscratch_buff->size;
/* Reset the used buffer to zero.
* If we dont do this, then it will effect the ext entity logic.
*/
memset(pscratch_buff->data, 0, pscratch_buff->size);
pscratch_buff->data = NULL;
pscratch_buff->offset = 0;
pscratch_buff->size = 0;
}
static inline void init_cudbg_hdr(struct cudbg_init_hdr *hdr)
{
hdr->major_ver = CUDBG_MAJOR_VERSION;
hdr->minor_ver = CUDBG_MINOR_VERSION;
hdr->build_ver = CUDBG_BUILD_VERSION;
hdr->init_struct_size = sizeof(struct cudbg_init);
}
void *
cudbg_alloc_handle(void)
{
struct cudbg_private *handle;
handle = malloc(sizeof(*handle), M_CXGBE, M_ZERO | M_WAITOK);
init_cudbg_hdr(&handle->dbg_init.header);
return (handle);
}
void
cudbg_free_handle(void *handle)
{
free(handle, M_CXGBE);
}

View File

@ -0,0 +1,909 @@
/*-
* Copyright (c) 2017 Chelsio Communications, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#ifndef __CUDBG_ENTITY_H__
#define __CUDBG_ENTITY_H__
#ifdef __GNUC__
#define ATTRIBUTE_UNUSED __attribute__ ((unused))
#else
#define ATTRIBUTE_UNUSED
#endif
#define MC0_FLAG 1
#define MC1_FLAG 2
#define EDC0_FLAG 3
#define EDC1_FLAG 4
#define NUM_PCIE_CONFIG_REGS 0x61
#define CUDBG_CTXT_SIZE_BYTES 24
#define CUDBG_MAX_INGRESS_QIDS 65536
#define CUDBG_MAX_FL_QIDS 2048
#define CUDBG_MAX_CNM_QIDS 1024
#define CUDBG_LOWMEM_MAX_CTXT_QIDS 256
#define ETH_ALEN 6
#define CUDBG_MAX_RPLC_SIZE 128
#define CUDBG_NUM_REQ_REGS 17
#define CUDBG_MAX_TCAM_TID 0x800
#define CUDBG_NUM_ULPTX 11
#define CUDBG_NUM_ULPTX_READ 512
#define SN_REG_ADDR 0x183f
#define BN_REG_ADDR 0x1819
#define NA_REG_ADDR 0x185a
#define MN_REG_ADDR 0x1803
#define A_MPS_VF_RPLCT_MAP0 0x1111c
#define A_MPS_VF_RPLCT_MAP1 0x11120
#define A_MPS_VF_RPLCT_MAP2 0x11124
#define A_MPS_VF_RPLCT_MAP3 0x11128
#define A_MPS_VF_RPLCT_MAP4 0x11300
#define A_MPS_VF_RPLCT_MAP5 0x11304
#define A_MPS_VF_RPLCT_MAP6 0x11308
#define A_MPS_VF_RPLCT_MAP7 0x1130c
#define PORT_TYPE_ADDR 0x1869
#define PORT_TYPE_LEN 8
/* For T6 */
#define SN_T6_ADDR 0x83f
#define BN_T6_ADDR 0x819
#define NA_T6_ADDR 0x85a
#define MN_T6_ADDR 0x803
#define SN_MAX_LEN 24
#define BN_MAX_LEN 16
#define NA_MAX_LEN 12
#define MN_MAX_LEN 16
#define MAX_VPD_DATA_LEN 32
#define VPD_VER_ADDR 0x18c7
#define VPD_VER_LEN 2
#define SCFG_VER_ADDR 0x06
#define SCFG_VER_LEN 4
#define CUDBG_CIM_BUSY_BIT (1 << 17)
#define CUDBG_CHAC_PBT_ADDR 0x2800
#define CUDBG_CHAC_PBT_LRF 0x3000
#define CUDBG_CHAC_PBT_DATA 0x3800
#define CUDBG_PBT_DYNAMIC_ENTRIES 8
#define CUDBG_PBT_STATIC_ENTRIES 16
#define CUDBG_LRF_ENTRIES 8
#define CUDBG_PBT_DATA_ENTRIES 512
#define CUDBG_ENTITY_SIGNATURE 0xCCEDB001
#define CUDBG_TID_INFO_REV 1
#define CUDBG_MAC_STATS_REV 1
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
struct cudbg_pbt_tables {
u32 pbt_dynamic[CUDBG_PBT_DYNAMIC_ENTRIES];
u32 pbt_static[CUDBG_PBT_STATIC_ENTRIES];
u32 lrf_table[CUDBG_LRF_ENTRIES];
u32 pbt_data[CUDBG_PBT_DATA_ENTRIES];
};
struct card_mem {
u16 size_mc0;
u16 size_mc1;
u16 size_edc0;
u16 size_edc1;
u16 mem_flag;
u16 res;
};
struct rss_pf_conf {
u32 rss_pf_map;
u32 rss_pf_mask;
u32 rss_pf_config;
};
struct cudbg_ch_cntxt {
uint32_t cntxt_type;
uint32_t cntxt_id;
uint32_t data[SGE_CTXT_SIZE / 4];
};
struct cudbg_tcam {
u32 filter_start;
u32 server_start;
u32 clip_start;
u32 routing_start;
u32 tid_hash_base;
u32 max_tid;
};
#if 0
struct cudbg_mbox_log {
struct mbox_cmd entry;
u32 hi[MBOX_LEN / 8];
u32 lo[MBOX_LEN / 8];
};
#endif
struct cudbg_tid_data {
u32 tid;
u32 dbig_cmd;
u32 dbig_conf;
u32 dbig_rsp_stat;
u32 data[CUDBG_NUM_REQ_REGS];
};
struct cudbg_cntxt_field {
char *name;
u32 start_bit;
u32 end_bit;
u32 shift;
u32 islog2;
};
struct cudbg_mps_tcam {
u64 mask;
u32 rplc[8];
u32 idx;
u32 cls_lo;
u32 cls_hi;
u32 rplc_size;
u32 vniy;
u32 vnix;
u32 dip_hit;
u32 vlan_vld;
u32 repli;
u16 ivlan;
u8 addr[ETH_ALEN];
u8 lookup_type;
u8 port_num;
u8 reserved[2];
};
struct rss_vf_conf {
u32 rss_vf_vfl;
u32 rss_vf_vfh;
};
struct rss_config {
u32 tp_rssconf; /* A_TP_RSS_CONFIG */
u32 tp_rssconf_tnl; /* A_TP_RSS_CONFIG_TNL */
u32 tp_rssconf_ofd; /* A_TP_RSS_CONFIG_OFD */
u32 tp_rssconf_syn; /* A_TP_RSS_CONFIG_SYN */
u32 tp_rssconf_vrt; /* A_TP_RSS_CONFIG_VRT */
u32 tp_rssconf_cng; /* A_TP_RSS_CONFIG_CNG */
u32 chip;
};
struct struct_pm_stats {
u32 tx_cnt[T6_PM_NSTATS];
u32 rx_cnt[T6_PM_NSTATS];
u64 tx_cyc[T6_PM_NSTATS];
u64 rx_cyc[T6_PM_NSTATS];
};
struct struct_hw_sched {
u32 kbps[NTX_SCHED];
u32 ipg[NTX_SCHED];
u32 pace_tab[NTX_SCHED];
u32 mode;
u32 map;
};
struct struct_tcp_stats {
struct tp_tcp_stats v4, v6;
};
struct struct_tp_err_stats {
struct tp_err_stats stats;
u32 nchan;
};
struct struct_tp_fcoe_stats {
struct tp_fcoe_stats stats[4];
u32 nchan;
};
struct struct_mac_stats {
u32 port_count;
struct port_stats stats[4];
};
struct struct_mac_stats_rev1 {
struct cudbg_ver_hdr ver_hdr;
u32 port_count;
u32 reserved;
struct port_stats stats[4];
};
struct struct_tp_cpl_stats {
struct tp_cpl_stats stats;
u32 nchan;
};
struct struct_wc_stats {
u32 wr_cl_success;
u32 wr_cl_fail;
};
struct struct_ulptx_la {
u32 rdptr[CUDBG_NUM_ULPTX];
u32 wrptr[CUDBG_NUM_ULPTX];
u32 rddata[CUDBG_NUM_ULPTX];
u32 rd_data[CUDBG_NUM_ULPTX][CUDBG_NUM_ULPTX_READ];
};
struct struct_ulprx_la {
u32 data[ULPRX_LA_SIZE * 8];
u32 size;
};
struct struct_cim_qcfg {
u8 chip;
u16 base[CIM_NUM_IBQ + CIM_NUM_OBQ_T5];
u16 size[CIM_NUM_IBQ + CIM_NUM_OBQ_T5];
u16 thres[CIM_NUM_IBQ];
u32 obq_wr[2 * CIM_NUM_OBQ_T5];
u32 stat[4 * (CIM_NUM_IBQ + CIM_NUM_OBQ_T5)];
};
enum region_index {
REGN_DBQ_CONTEXS_IDX,
REGN_IMSG_CONTEXTS_IDX,
REGN_FLM_CACHE_IDX,
REGN_TCBS_IDX,
REGN_PSTRUCT_IDX,
REGN_TIMERS_IDX,
REGN_RX_FL_IDX,
REGN_TX_FL_IDX,
REGN_PSTRUCT_FL_IDX,
REGN_TX_PAYLOAD_IDX,
REGN_RX_PAYLOAD_IDX,
REGN_LE_HASH_IDX,
REGN_ISCSI_IDX,
REGN_TDDP_IDX,
REGN_TPT_IDX,
REGN_STAG_IDX,
REGN_RQ_IDX,
REGN_RQUDP_IDX,
REGN_PBL_IDX,
REGN_TXPBL_IDX,
REGN_DBVFIFO_IDX,
REGN_ULPRX_STATE_IDX,
REGN_ULPTX_STATE_IDX,
#ifndef __NO_DRIVER_OCQ_SUPPORT__
REGN_ON_CHIP_Q_IDX,
#endif
};
static const char * const region[] = {
"DBQ contexts:", "IMSG contexts:", "FLM cache:", "TCBs:",
"Pstructs:", "Timers:", "Rx FL:", "Tx FL:", "Pstruct FL:",
"Tx payload:", "Rx payload:", "LE hash:", "iSCSI region:",
"TDDP region:", "TPT region:", "STAG region:", "RQ region:",
"RQUDP region:", "PBL region:", "TXPBL region:",
"DBVFIFO region:", "ULPRX state:", "ULPTX state:",
#ifndef __NO_DRIVER_OCQ_SUPPORT__
"On-chip queues:"
#endif
};
/* Info relative to memory region (i.e. wrt 0). */
struct struct_region_info {
bool exist; /* Does region exists in current memory region? */
u32 start; /* Start wrt 0 */
u32 end; /* End wrt 0 */
};
struct struct_port_usage {
u32 id;
u32 used;
u32 alloc;
};
struct struct_lpbk_usage {
u32 id;
u32 used;
u32 alloc;
};
struct struct_mem_desc {
u32 base;
u32 limit;
u32 idx;
};
enum string_size_units {
STRING_UNITS_10, /* use powers of 10^3 (standard SI) */
STRING_UNITS_2, /* use binary powers of 2^10 */
};
struct struct_meminfo {
struct struct_mem_desc avail[4];
struct struct_mem_desc mem[ARRAY_SIZE(region) + 3];
u32 avail_c;
u32 mem_c;
u32 up_ram_lo;
u32 up_ram_hi;
u32 up_extmem2_lo;
u32 up_extmem2_hi;
u32 rx_pages_data[3];
u32 tx_pages_data[4];
u32 p_structs;
struct struct_port_usage port_data[4];
u32 port_used[4];
u32 port_alloc[4];
u32 loopback_used[NCHAN];
u32 loopback_alloc[NCHAN];
};
#ifndef __GNUC__
#pragma warning(disable : 4200)
#endif
struct struct_lb_stats {
int nchan;
struct lb_port_stats s[0];
};
struct struct_clk_info {
u64 retransmit_min;
u64 retransmit_max;
u64 persist_timer_min;
u64 persist_timer_max;
u64 keepalive_idle_timer;
u64 keepalive_interval;
u64 initial_srtt;
u64 finwait2_timer;
u32 dack_timer;
u32 res;
u32 cclk_ps;
u32 tre;
u32 dack_re;
char core_clk_period[32];
char tp_timer_tick[32];
char tcp_tstamp_tick[32];
char dack_tick[32];
};
struct cim_pif_la {
int size;
u8 data[0];
};
struct struct_tp_la {
u32 size;
u32 mode;
u8 data[0];
};
struct field_desc {
const char *name;
u32 start;
u32 width;
};
struct tp_mib_type {
char *key;
u32 addr;
u32 value;
};
struct wtp_type_0 {
u32 sop;
u32 eop;
};
struct wtp_type_1 {
u32 sop[2];
u32 eop[2];
};
struct wtp_type_2 {
u32 sop[4];
u32 eop[4];
};
struct wtp_type_3 {
u32 sop[4];
u32 eop[4];
u32 drops;
};
struct wtp_data {
/*TX path, Request Work request sub-path:*/
struct wtp_type_1 sge_pcie_cmd_req; /*SGE_DEBUG PC_Req_xOPn*/
struct wtp_type_1 pcie_core_cmd_req; /*PCIE_CMDR_REQ_CNT*/
/*TX path, Work request to uP sub-path*/
struct wtp_type_1 core_pcie_cmd_rsp; /*PCIE_CMDR_RSP_CNT*/
struct wtp_type_1 pcie_sge_cmd_rsp; /*SGE_DEBUG PC_Rsp_xOPn*/
struct wtp_type_1 sge_cim; /*SGE_DEBUG CIM_xOPn*/
/*TX path, Data request path from ULP_TX to core*/
struct wtp_type_2 utx_sge_dma_req; /*SGE UD_Rx_xOPn*/
struct wtp_type_2 sge_pcie_dma_req; /*SGE PD_Req_Rdn (no eops)*/
struct wtp_type_2 pcie_core_dma_req; /*PCIE_DMAR_REQ_CNT (no eops)*/
/*Main TX path, from core to wire*/
struct wtp_type_2 core_pcie_dma_rsp; /*PCIE_DMAR_RSP_SOP_CNT/
PCIE_DMAR_EOP_CNT*/
struct wtp_type_2 pcie_sge_dma_rsp; /*SGE_DEBUG PD_Rsp_xOPn*/
struct wtp_type_2 sge_utx; /*SGE_DEBUG U_Tx_xOPn*/
struct wtp_type_2 utx_tp; /*ULP_TX_SE_CNT_CHn[xOP_CNT_ULP2TP]*/
struct wtp_type_2 utx_tpcside; /*TP_DBG_CSIDE_RXn[RxXoPCnt]*/
struct wtp_type_2 tpcside_rxpld;
struct wtp_type_2 tpcside_rxarb; /*TP_DBG_CSIDE_RXn[RxArbXopCnt]*/
struct wtp_type_2 tpcside_rxcpl;
struct wtp_type_2 tpeside_mps; /*TP_DBG_ESDIE_PKT0[TxXoPCnt]*/
struct wtp_type_2 tpeside_pm;
struct wtp_type_2 tpeside_pld;
/*Tx path, PCIE t5 DMA stat*/
struct wtp_type_2 pcie_t5_dma_stat3;
/*Tx path, SGE debug data high index 6*/
struct wtp_type_2 sge_debug_data_high_index_6;
/*Tx path, SGE debug data high index 3*/
struct wtp_type_2 sge_debug_data_high_index_3;
/*Tx path, ULP SE CNT CHx*/
struct wtp_type_2 ulp_se_cnt_chx;
/*pcie cmd stat 2*/
struct wtp_type_2 pcie_cmd_stat2;
/*pcie cmd stat 3*/
struct wtp_type_2 pcie_cmd_stat3;
struct wtp_type_2 pcie_dma1_stat2_core;
struct wtp_type_1 sge_work_req_pkt;
struct wtp_type_2 sge_debug_data_high_indx5;
/*Tx path, mac portx pkt count*/
struct wtp_type_2 mac_portx_pkt_count;
/*Rx path, mac porrx pkt count*/
struct wtp_type_2 mac_porrx_pkt_count;
/*Rx path, PCIE T5 dma1 stat 2*/
struct wtp_type_2 pcie_dma1_stat2;
/*Rx path, sge debug data high index 7*/
struct wtp_type_2 sge_debug_data_high_indx7;
/*Rx path, sge debug data high index 1*/
struct wtp_type_1 sge_debug_data_high_indx1;
/*Rx path, TP debug CSIDE Tx register*/
struct wtp_type_1 utx_tpcside_tx;
/*Rx path, LE DB response count*/
struct wtp_type_0 le_db_rsp_cnt;
/*Rx path, TP debug Eside PKTx*/
struct wtp_type_2 tp_dbg_eside_pktx;
/*Rx path, sge debug data high index 9*/
struct wtp_type_1 sge_debug_data_high_indx9;
/*Tx path, mac portx aFramesTransmittesok*/
struct wtp_type_2 mac_portx_aframestra_ok;
/*Rx path, mac portx aFramesTransmittesok*/
struct wtp_type_2 mac_porrx_aframestra_ok;
/*Tx path, MAC_PORT_MTIP_1G10G_RX_etherStatsPkts*/
struct wtp_type_1 mac_portx_etherstatspkts;
/*Rx path, MAC_PORT_MTIP_1G10G_RX_etherStatsPkts*/
struct wtp_type_1 mac_porrx_etherstatspkts;
struct wtp_type_3 tp_mps; /*MPS_TX_SE_CNT_TP01 and
MPS_TX_SE_CNT_TP34*/
struct wtp_type_3 mps_xgm; /*MPS_TX_SE_CNT_MAC01 and
MPS_TX_SE_CNT_MAC34*/
struct wtp_type_2 tx_xgm_xgm; /*XGMAC_PORT_PKT_CNT_PORT_n*/
struct wtp_type_2 xgm_wire; /*XGMAC_PORT_XGM_STAT_TX_FRAME_LOW_PORT_N
(clear on read)*/
/*RX path, from wire to core.*/
struct wtp_type_2 wire_xgm; /*XGMAC_PORT_XGM_STAT_RX_FRAMES_LOW_PORT_N
(clear on read)*/
struct wtp_type_2 rx_xgm_xgm; /*XGMAC_PORT_PKT_CNT_PORT_n*/
struct _xgm_mps { /*MPS_RX_SE_CNT_INn*/
u32 sop[8]; /* => undef,*/
u32 eop[8]; /* => undef,*/
u32 drop; /* => undef,*/
u32 cls_drop; /* => undef,*/
u32 err; /* => undef,*/
u32 bp; /* => undef,*/
} xgm_mps;
struct wtp_type_3 mps_tp; /*MPS_RX_SE_CNT_OUT01 and
MPS_RX_SE_CNT_OUT23*/
struct wtp_type_2 mps_tpeside; /*TP_DBG_ESIDE_PKTn*/
struct wtp_type_1 tpeside_pmrx; /*???*/
struct wtp_type_2 pmrx_ulprx; /*ULP_RX_SE_CNT_CHn[xOP_CNT_INn]*/
struct wtp_type_2 ulprx_tpcside; /*ULP_RX_SE_CNT_CHn[xOP_CNT_OUTn]*/
struct wtp_type_2 tpcside_csw; /*TP_DBG_CSIDE_TXn[TxSopCnt]*/
struct wtp_type_2 tpcside_pm;
struct wtp_type_2 tpcside_uturn;
struct wtp_type_2 tpcside_txcpl;
struct wtp_type_1 tp_csw; /*SGE_DEBUG CPLSW_TP_Rx_xOPn*/
struct wtp_type_1 csw_sge; /*SGE_DEBUG T_Rx_xOPn*/
struct wtp_type_2 sge_pcie; /*SGE_DEBUG PD_Req_SopN -
PD_Req_RdN - PD_ReqIntN*/
struct wtp_type_2 sge_pcie_ints; /*SGE_DEBUG PD_Req_IntN*/
struct wtp_type_2 pcie_core_dmaw; /*PCIE_DMAW_SOP_CNT and
PCIE_DMAW_EOP_CNT*/
struct wtp_type_2 pcie_core_dmai; /*PCIE_DMAI_CNT*/
};
struct tp_mib_data {
struct tp_mib_type TP_MIB_MAC_IN_ERR_0;
struct tp_mib_type TP_MIB_MAC_IN_ERR_1;
struct tp_mib_type TP_MIB_MAC_IN_ERR_2;
struct tp_mib_type TP_MIB_MAC_IN_ERR_3;
struct tp_mib_type TP_MIB_HDR_IN_ERR_0;
struct tp_mib_type TP_MIB_HDR_IN_ERR_1;
struct tp_mib_type TP_MIB_HDR_IN_ERR_2;
struct tp_mib_type TP_MIB_HDR_IN_ERR_3;
struct tp_mib_type TP_MIB_TCP_IN_ERR_0;
struct tp_mib_type TP_MIB_TCP_IN_ERR_1;
struct tp_mib_type TP_MIB_TCP_IN_ERR_2;
struct tp_mib_type TP_MIB_TCP_IN_ERR_3;
struct tp_mib_type TP_MIB_TCP_OUT_RST;
struct tp_mib_type TP_MIB_TCP_IN_SEG_HI;
struct tp_mib_type TP_MIB_TCP_IN_SEG_LO;
struct tp_mib_type TP_MIB_TCP_OUT_SEG_HI;
struct tp_mib_type TP_MIB_TCP_OUT_SEG_LO;
struct tp_mib_type TP_MIB_TCP_RXT_SEG_HI;
struct tp_mib_type TP_MIB_TCP_RXT_SEG_LO;
struct tp_mib_type TP_MIB_TNL_CNG_DROP_0;
struct tp_mib_type TP_MIB_TNL_CNG_DROP_1;
struct tp_mib_type TP_MIB_TNL_CNG_DROP_2;
struct tp_mib_type TP_MIB_TNL_CNG_DROP_3;
struct tp_mib_type TP_MIB_OFD_CHN_DROP_0;
struct tp_mib_type TP_MIB_OFD_CHN_DROP_1;
struct tp_mib_type TP_MIB_OFD_CHN_DROP_2;
struct tp_mib_type TP_MIB_OFD_CHN_DROP_3;
struct tp_mib_type TP_MIB_TNL_OUT_PKT_0;
struct tp_mib_type TP_MIB_TNL_OUT_PKT_1;
struct tp_mib_type TP_MIB_TNL_OUT_PKT_2;
struct tp_mib_type TP_MIB_TNL_OUT_PKT_3;
struct tp_mib_type TP_MIB_TNL_IN_PKT_0;
struct tp_mib_type TP_MIB_TNL_IN_PKT_1;
struct tp_mib_type TP_MIB_TNL_IN_PKT_2;
struct tp_mib_type TP_MIB_TNL_IN_PKT_3;
struct tp_mib_type TP_MIB_TCP_V6IN_ERR_0;
struct tp_mib_type TP_MIB_TCP_V6IN_ERR_1;
struct tp_mib_type TP_MIB_TCP_V6IN_ERR_2;
struct tp_mib_type TP_MIB_TCP_V6IN_ERR_3;
struct tp_mib_type TP_MIB_TCP_V6OUT_RST;
struct tp_mib_type TP_MIB_TCP_V6IN_SEG_HI;
struct tp_mib_type TP_MIB_TCP_V6IN_SEG_LO;
struct tp_mib_type TP_MIB_TCP_V6OUT_SEG_HI;
struct tp_mib_type TP_MIB_TCP_V6OUT_SEG_LO;
struct tp_mib_type TP_MIB_TCP_V6RXT_SEG_HI;
struct tp_mib_type TP_MIB_TCP_V6RXT_SEG_LO;
struct tp_mib_type TP_MIB_OFD_ARP_DROP;
struct tp_mib_type TP_MIB_OFD_DFR_DROP;
struct tp_mib_type TP_MIB_CPL_IN_REQ_0;
struct tp_mib_type TP_MIB_CPL_IN_REQ_1;
struct tp_mib_type TP_MIB_CPL_IN_REQ_2;
struct tp_mib_type TP_MIB_CPL_IN_REQ_3;
struct tp_mib_type TP_MIB_CPL_OUT_RSP_0;
struct tp_mib_type TP_MIB_CPL_OUT_RSP_1;
struct tp_mib_type TP_MIB_CPL_OUT_RSP_2;
struct tp_mib_type TP_MIB_CPL_OUT_RSP_3;
struct tp_mib_type TP_MIB_TNL_LPBK_0;
struct tp_mib_type TP_MIB_TNL_LPBK_1;
struct tp_mib_type TP_MIB_TNL_LPBK_2;
struct tp_mib_type TP_MIB_TNL_LPBK_3;
struct tp_mib_type TP_MIB_TNL_DROP_0;
struct tp_mib_type TP_MIB_TNL_DROP_1;
struct tp_mib_type TP_MIB_TNL_DROP_2;
struct tp_mib_type TP_MIB_TNL_DROP_3;
struct tp_mib_type TP_MIB_FCOE_DDP_0;
struct tp_mib_type TP_MIB_FCOE_DDP_1;
struct tp_mib_type TP_MIB_FCOE_DDP_2;
struct tp_mib_type TP_MIB_FCOE_DDP_3;
struct tp_mib_type TP_MIB_FCOE_DROP_0;
struct tp_mib_type TP_MIB_FCOE_DROP_1;
struct tp_mib_type TP_MIB_FCOE_DROP_2;
struct tp_mib_type TP_MIB_FCOE_DROP_3;
struct tp_mib_type TP_MIB_FCOE_BYTE_0_HI;
struct tp_mib_type TP_MIB_FCOE_BYTE_0_LO;
struct tp_mib_type TP_MIB_FCOE_BYTE_1_HI;
struct tp_mib_type TP_MIB_FCOE_BYTE_1_LO;
struct tp_mib_type TP_MIB_FCOE_BYTE_2_HI;
struct tp_mib_type TP_MIB_FCOE_BYTE_2_LO;
struct tp_mib_type TP_MIB_FCOE_BYTE_3_HI;
struct tp_mib_type TP_MIB_FCOE_BYTE_3_LO;
struct tp_mib_type TP_MIB_OFD_VLN_DROP_0;
struct tp_mib_type TP_MIB_OFD_VLN_DROP_1;
struct tp_mib_type TP_MIB_OFD_VLN_DROP_2;
struct tp_mib_type TP_MIB_OFD_VLN_DROP_3;
struct tp_mib_type TP_MIB_USM_PKTS;
struct tp_mib_type TP_MIB_USM_DROP;
struct tp_mib_type TP_MIB_USM_BYTES_HI;
struct tp_mib_type TP_MIB_USM_BYTES_LO;
struct tp_mib_type TP_MIB_TID_DEL;
struct tp_mib_type TP_MIB_TID_INV;
struct tp_mib_type TP_MIB_TID_ACT;
struct tp_mib_type TP_MIB_TID_PAS;
struct tp_mib_type TP_MIB_RQE_DFR_MOD;
struct tp_mib_type TP_MIB_RQE_DFR_PKT;
};
struct cudbg_reg_info {
const char *name;
unsigned int addr;
unsigned int len;
};
struct tp1_reg_info {
char addr[10];
char name[40];
};
struct ireg_field {
u32 ireg_addr;
u32 ireg_data;
u32 ireg_local_offset;
u32 ireg_offset_range;
};
struct ireg_buf {
struct ireg_field tp_pio;
u32 outbuf[32];
};
struct tx_rate {
u64 nrate[NCHAN];
u64 orate[NCHAN];
u32 nchan;
};
struct tid_info_region {
u32 ntids;
u32 nstids;
u32 stid_base;
u32 hash_base;
u32 natids;
u32 nftids;
u32 ftid_base;
u32 aftid_base;
u32 aftid_end;
/* Server filter region */
u32 sftid_base;
u32 nsftids;
/* UO context range */
u32 uotid_base;
u32 nuotids;
u32 sb;
u32 flags;
u32 le_db_conf;
u32 IP_users;
u32 IPv6_users;
u32 hpftid_base;
u32 nhpftids;
};
struct tid_info_region_rev1 {
struct cudbg_ver_hdr ver_hdr;
struct tid_info_region tid;
u32 tid_start;
u32 reserved[16];
};
struct struct_vpd_data {
u8 sn[SN_MAX_LEN + 1];
u8 bn[BN_MAX_LEN + 1];
u8 na[NA_MAX_LEN + 1];
u8 mn[MN_MAX_LEN + 1];
u16 fw_major;
u16 fw_minor;
u16 fw_micro;
u16 fw_build;
u32 scfg_vers;
u32 vpd_vers;
};
struct sw_state {
u32 fw_state;
u8 caller_string[100];
u8 os_type;
u8 reserved[3];
u32 reserved1[16];
};
static u32 ATTRIBUTE_UNUSED t6_tp_pio_array[][4] = {
{0x7e40, 0x7e44, 0x020, 28}, /* t6_tp_pio_regs_20_to_3b */
{0x7e40, 0x7e44, 0x040, 10}, /* t6_tp_pio_regs_40_to_49 */
{0x7e40, 0x7e44, 0x050, 10}, /* t6_tp_pio_regs_50_to_59 */
{0x7e40, 0x7e44, 0x060, 14}, /* t6_tp_pio_regs_60_to_6d */
{0x7e40, 0x7e44, 0x06F, 1}, /* t6_tp_pio_regs_6f */
{0x7e40, 0x7e44, 0x070, 6}, /* t6_tp_pio_regs_70_to_75 */
{0x7e40, 0x7e44, 0x130, 18}, /* t6_tp_pio_regs_130_to_141 */
{0x7e40, 0x7e44, 0x145, 19}, /* t6_tp_pio_regs_145_to_157 */
{0x7e40, 0x7e44, 0x160, 1}, /* t6_tp_pio_regs_160 */
{0x7e40, 0x7e44, 0x230, 25}, /* t6_tp_pio_regs_230_to_248 */
{0x7e40, 0x7e44, 0x24a, 3}, /* t6_tp_pio_regs_24c */
{0x7e40, 0x7e44, 0x8C0, 1} /* t6_tp_pio_regs_8c0 */
};
static u32 ATTRIBUTE_UNUSED t5_tp_pio_array[][4] = {
{0x7e40, 0x7e44, 0x020, 28}, /* t5_tp_pio_regs_20_to_3b */
{0x7e40, 0x7e44, 0x040, 19}, /* t5_tp_pio_regs_40_to_52 */
{0x7e40, 0x7e44, 0x054, 2}, /* t5_tp_pio_regs_54_to_55 */
{0x7e40, 0x7e44, 0x060, 13}, /* t5_tp_pio_regs_60_to_6c */
{0x7e40, 0x7e44, 0x06F, 1}, /* t5_tp_pio_regs_6f */
{0x7e40, 0x7e44, 0x120, 4}, /* t5_tp_pio_regs_120_to_123 */
{0x7e40, 0x7e44, 0x12b, 2}, /* t5_tp_pio_regs_12b_to_12c */
{0x7e40, 0x7e44, 0x12f, 21}, /* t5_tp_pio_regs_12f_to_143 */
{0x7e40, 0x7e44, 0x145, 19}, /* t5_tp_pio_regs_145_to_157 */
{0x7e40, 0x7e44, 0x230, 25}, /* t5_tp_pio_regs_230_to_248 */
{0x7e40, 0x7e44, 0x8C0, 1} /* t5_tp_pio_regs_8c0 */
};
static u32 ATTRIBUTE_UNUSED t6_ma_ireg_array[][4] = {
{0x78f8, 0x78fc, 0xa000, 23}, /* t6_ma_regs_a000_to_a016 */
{0x78f8, 0x78fc, 0xa400, 30}, /* t6_ma_regs_a400_to_a41e */
{0x78f8, 0x78fc, 0xa800, 20} /* t6_ma_regs_a800_to_a813 */
};
static u32 ATTRIBUTE_UNUSED t6_ma_ireg_array2[][4] = {
{0x78f8, 0x78fc, 0xe400, 17}, /* t6_ma_regs_e400_to_e600 */
{0x78f8, 0x78fc, 0xe640, 13} /* t6_ma_regs_e640_to_e7c0 */
};
static u32 ATTRIBUTE_UNUSED t6_hma_ireg_array[][4] = {
{0x51320, 0x51324, 0xa000, 32} /* t6_hma_regs_a000_to_a01f */
};
static u32 ATTRIBUTE_UNUSED t5_pcie_pdbg_array[][4] = {
{0x5a04, 0x5a0c, 0x00, 0x20}, /* t5_pcie_pdbg_regs_00_to_20 */
{0x5a04, 0x5a0c, 0x21, 0x20}, /* t5_pcie_pdbg_regs_21_to_40 */
{0x5a04, 0x5a0c, 0x41, 0x10}, /* t5_pcie_pdbg_regs_41_to_50 */
};
static u32 ATTRIBUTE_UNUSED t5_pcie_config_array[][2] = {
{0x0, 0x34},
{0x3c, 0x40},
{0x50, 0x64},
{0x70, 0x80},
{0x94, 0xa0},
{0xb0, 0xb8},
{0xd0, 0xd4},
{0x100, 0x128},
{0x140, 0x148},
{0x150, 0x164},
{0x170, 0x178},
{0x180, 0x194},
{0x1a0, 0x1b8},
{0x1c0, 0x208},
};
static u32 ATTRIBUTE_UNUSED t5_pcie_cdbg_array[][4] = {
{0x5a10, 0x5a18, 0x00, 0x20}, /* t5_pcie_cdbg_regs_00_to_20 */
{0x5a10, 0x5a18, 0x21, 0x18}, /* t5_pcie_cdbg_regs_21_to_37 */
};
static u32 ATTRIBUTE_UNUSED t6_tp_tm_pio_array[1][4] = {
{0x7e18, 0x7e1c, 0x0, 12}
};
static u32 ATTRIBUTE_UNUSED t5_tp_tm_pio_array[1][4] = {
{0x7e18, 0x7e1c, 0x0, 12}
};
static u32 ATTRIBUTE_UNUSED t5_pm_rx_array[][4] = {
{0x8FD0, 0x8FD4, 0x10000, 0x20}, /* t5_pm_rx_regs_10000_to_10020 */
{0x8FD0, 0x8FD4, 0x10021, 0x0D}, /* t5_pm_rx_regs_10021_to_1002c */
};
static u32 ATTRIBUTE_UNUSED t5_pm_tx_array[][4] = {
{0x8FF0, 0x8FF4, 0x10000, 0x20}, /* t5_pm_tx_regs_10000_to_10020 */
{0x8FF0, 0x8FF4, 0x10021, 0x1D}, /* t5_pm_tx_regs_10021_to_1003c */
};
static u32 ATTRIBUTE_UNUSED t6_tp_mib_index_array[6][4] = {
{0x7e50, 0x7e54, 0x0, 13},
{0x7e50, 0x7e54, 0x10, 6},
{0x7e50, 0x7e54, 0x18, 21},
{0x7e50, 0x7e54, 0x30, 32},
{0x7e50, 0x7e54, 0x50, 22},
{0x7e50, 0x7e54, 0x68, 12}
};
static u32 ATTRIBUTE_UNUSED t5_tp_mib_index_array[9][4] = {
{0x7e50, 0x7e54, 0x0, 13},
{0x7e50, 0x7e54, 0x10, 6},
{0x7e50, 0x7e54, 0x18, 8},
{0x7e50, 0x7e54, 0x20, 13},
{0x7e50, 0x7e54, 0x30, 16},
{0x7e50, 0x7e54, 0x40, 16},
{0x7e50, 0x7e54, 0x50, 16},
{0x7e50, 0x7e54, 0x60, 6},
{0x7e50, 0x7e54, 0x68, 4}
};
static u32 ATTRIBUTE_UNUSED t5_sge_dbg_index_array[9][4] = {
{0x10cc, 0x10d0, 0x0, 16},
{0x10cc, 0x10d4, 0x0, 16},
};
static u32 ATTRIBUTE_UNUSED t6_up_cim_reg_array[][4] = {
{0x7b50, 0x7b54, 0x2000, 0x20}, /* up_cim_2000_to_207c */
{0x7b50, 0x7b54, 0x2080, 0x1d}, /* up_cim_2080_to_20fc */
{0x7b50, 0x7b54, 0x00, 0x20}, /* up_cim_00_to_7c */
{0x7b50, 0x7b54, 0x80, 0x20}, /* up_cim_80_to_fc */
{0x7b50, 0x7b54, 0x100, 0x11}, /* up_cim_100_to_14c */
{0x7b50, 0x7b54, 0x200, 0x10}, /* up_cim_200_to_23c */
{0x7b50, 0x7b54, 0x240, 0x2}, /* up_cim_240_to_244 */
{0x7b50, 0x7b54, 0x250, 0x2}, /* up_cim_250_to_254 */
{0x7b50, 0x7b54, 0x260, 0x2}, /* up_cim_260_to_264 */
{0x7b50, 0x7b54, 0x270, 0x2}, /* up_cim_270_to_274 */
{0x7b50, 0x7b54, 0x280, 0x20}, /* up_cim_280_to_2fc */
{0x7b50, 0x7b54, 0x300, 0x20}, /* up_cim_300_to_37c */
{0x7b50, 0x7b54, 0x380, 0x14}, /* up_cim_380_to_3cc */
};
static u32 ATTRIBUTE_UNUSED t5_up_cim_reg_array[][4] = {
{0x7b50, 0x7b54, 0x2000, 0x20}, /* up_cim_2000_to_207c */
{0x7b50, 0x7b54, 0x2080, 0x19}, /* up_cim_2080_to_20ec */
{0x7b50, 0x7b54, 0x00, 0x20}, /* up_cim_00_to_7c */
{0x7b50, 0x7b54, 0x80, 0x20}, /* up_cim_80_to_fc */
{0x7b50, 0x7b54, 0x100, 0x11}, /* up_cim_100_to_14c */
{0x7b50, 0x7b54, 0x200, 0x10}, /* up_cim_200_to_23c */
{0x7b50, 0x7b54, 0x240, 0x2}, /* up_cim_240_to_244 */
{0x7b50, 0x7b54, 0x250, 0x2}, /* up_cim_250_to_254 */
{0x7b50, 0x7b54, 0x260, 0x2}, /* up_cim_260_to_264 */
{0x7b50, 0x7b54, 0x270, 0x2}, /* up_cim_270_to_274 */
{0x7b50, 0x7b54, 0x280, 0x20}, /* up_cim_280_to_2fc */
{0x7b50, 0x7b54, 0x300, 0x20}, /* up_cim_300_to_37c */
{0x7b50, 0x7b54, 0x380, 0x14}, /* up_cim_380_to_3cc */
};
#endif

View File

@ -0,0 +1,492 @@
/*-
* Copyright (c) 2017 Chelsio Communications, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include "common/common.h"
#include "common/t4_regs.h"
#include "cudbg.h"
#include "cudbg_lib_common.h"
enum {
SF_ATTEMPTS = 10, /* max retries for SF operations */
/* flash command opcodes */
SF_PROG_PAGE = 2, /* program page */
SF_WR_DISABLE = 4, /* disable writes */
SF_RD_STATUS = 5, /* read status register */
SF_WR_ENABLE = 6, /* enable writes */
SF_RD_DATA_FAST = 0xb, /* read flash */
SF_RD_ID = 0x9f, /* read ID */
SF_ERASE_SECTOR = 0xd8, /* erase sector */
};
int write_flash(struct adapter *adap, u32 start_sec, void *data, u32 size);
int read_flash(struct adapter *adap, u32 start_sec , void *data, u32 size,
u32 start_address);
void
update_skip_size(struct cudbg_flash_sec_info *sec_info, u32 size)
{
sec_info->skip_size += size;
}
static
void set_sector_availability(struct cudbg_flash_sec_info *sec_info,
int sector_nu, int avail)
{
sector_nu -= CUDBG_START_SEC;
if (avail)
set_dbg_bitmap(sec_info->sec_bitmap, sector_nu);
else
reset_dbg_bitmap(sec_info->sec_bitmap, sector_nu);
}
/* This function will return empty sector available for filling */
static int
find_empty_sec(struct cudbg_flash_sec_info *sec_info)
{
int i, index, bit;
for (i = CUDBG_START_SEC; i < CUDBG_SF_MAX_SECTOR; i++) {
index = (i - CUDBG_START_SEC) / 8;
bit = (i - CUDBG_START_SEC) % 8;
if (!(sec_info->sec_bitmap[index] & (1 << bit)))
return i;
}
return CUDBG_STATUS_FLASH_FULL;
}
/* This function will get header initially. If header is already there
* then it will update that header */
static void update_headers(void *handle, struct cudbg_buffer *dbg_buff,
u64 timestamp, u32 cur_entity_hdr_offset,
u32 start_offset, u32 ext_size)
{
struct cudbg_private *priv = handle;
struct cudbg_flash_sec_info *sec_info = &priv->sec_info;
void *sec_hdr;
struct cudbg_hdr *cudbg_hdr;
struct cudbg_flash_hdr *flash_hdr;
struct cudbg_entity_hdr *entity_hdr;
u32 hdr_offset;
u32 data_hdr_size;
u32 total_hdr_size;
u32 sec_hdr_start_addr;
data_hdr_size = CUDBG_MAX_ENTITY * sizeof(struct cudbg_entity_hdr) +
sizeof(struct cudbg_hdr);
total_hdr_size = data_hdr_size + sizeof(struct cudbg_flash_hdr);
sec_hdr_start_addr = CUDBG_SF_SECTOR_SIZE - total_hdr_size;
sec_hdr = sec_info->sec_data + sec_hdr_start_addr;
flash_hdr = (struct cudbg_flash_hdr *)(sec_hdr);
cudbg_hdr = (struct cudbg_hdr *)dbg_buff->data;
/* initially initialize flash hdr and copy all data headers and
* in next calling (else part) copy only current entity header
*/
if ((start_offset - sec_info->skip_size) == data_hdr_size) {
flash_hdr->signature = CUDBG_FL_SIGNATURE;
flash_hdr->major_ver = CUDBG_FL_MAJOR_VERSION;
flash_hdr->minor_ver = CUDBG_FL_MINOR_VERSION;
flash_hdr->build_ver = CUDBG_FL_BUILD_VERSION;
flash_hdr->hdr_len = sizeof(struct cudbg_flash_hdr);
hdr_offset = sizeof(struct cudbg_flash_hdr);
memcpy((void *)((char *)sec_hdr + hdr_offset),
(void *)((char *)dbg_buff->data), data_hdr_size);
} else
memcpy((void *)((char *)sec_hdr +
sizeof(struct cudbg_flash_hdr) +
cur_entity_hdr_offset),
(void *)((char *)dbg_buff->data +
cur_entity_hdr_offset),
sizeof(struct cudbg_entity_hdr));
hdr_offset = data_hdr_size + sizeof(struct cudbg_flash_hdr);
flash_hdr->data_len = cudbg_hdr->data_len - sec_info->skip_size;
flash_hdr->timestamp = timestamp;
entity_hdr = (struct cudbg_entity_hdr *)((char *)sec_hdr +
sizeof(struct cudbg_flash_hdr) +
cur_entity_hdr_offset);
/* big entity like mc need to be skipped */
entity_hdr->start_offset -= sec_info->skip_size;
cudbg_hdr = (struct cudbg_hdr *)((char *)sec_hdr +
sizeof(struct cudbg_flash_hdr));
cudbg_hdr->data_len = flash_hdr->data_len;
flash_hdr->data_len += ext_size;
}
/* Write CUDBG data into serial flash */
int cudbg_write_flash(void *handle, u64 timestamp, void *data,
u32 start_offset, u32 cur_entity_hdr_offset,
u32 cur_entity_size,
u32 ext_size)
{
struct cudbg_private *priv = handle;
struct cudbg_init *cudbg_init = &priv->dbg_init;
struct cudbg_flash_sec_info *sec_info = &priv->sec_info;
struct adapter *adap = cudbg_init->adap;
struct cudbg_flash_hdr *flash_hdr = NULL;
struct cudbg_buffer *dbg_buff = (struct cudbg_buffer *)data;
u32 data_hdr_size;
u32 total_hdr_size;
u32 tmp_size;
u32 sec_data_offset;
u32 sec_hdr_start_addr;
u32 sec_data_size;
u32 space_left;
int rc = 0;
int sec;
data_hdr_size = CUDBG_MAX_ENTITY * sizeof(struct cudbg_entity_hdr) +
sizeof(struct cudbg_hdr);
total_hdr_size = data_hdr_size + sizeof(struct cudbg_flash_hdr);
sec_hdr_start_addr = CUDBG_SF_SECTOR_SIZE - total_hdr_size;
sec_data_size = sec_hdr_start_addr;
cudbg_init->print("\tWriting %u bytes to flash\n", cur_entity_size);
/* this function will get header if sec_info->sec_data does not
* have any header and
* will update the header if it has header
*/
update_headers(handle, dbg_buff, timestamp,
cur_entity_hdr_offset,
start_offset, ext_size);
if (ext_size) {
cur_entity_size += sizeof(struct cudbg_entity_hdr);
start_offset = dbg_buff->offset - cur_entity_size;
}
flash_hdr = (struct cudbg_flash_hdr *)(sec_info->sec_data +
sec_hdr_start_addr);
if (flash_hdr->data_len > CUDBG_FLASH_SIZE) {
rc = CUDBG_STATUS_FLASH_FULL;
goto out;
}
space_left = CUDBG_FLASH_SIZE - flash_hdr->data_len;
if (cur_entity_size > space_left) {
rc = CUDBG_STATUS_FLASH_FULL;
goto out;
}
while (cur_entity_size > 0) {
sec = find_empty_sec(sec_info);
if (sec_info->par_sec) {
sec_data_offset = sec_info->par_sec_offset;
set_sector_availability(sec_info, sec_info->par_sec, 0);
sec_info->par_sec = 0;
sec_info->par_sec_offset = 0;
} else {
sec_info->cur_seq_no++;
flash_hdr->sec_seq_no = sec_info->cur_seq_no;
sec_data_offset = 0;
}
if (cur_entity_size + sec_data_offset > sec_data_size) {
tmp_size = sec_data_size - sec_data_offset;
} else {
tmp_size = cur_entity_size;
sec_info->par_sec = sec;
sec_info->par_sec_offset = cur_entity_size +
sec_data_offset;
}
memcpy((void *)((char *)sec_info->sec_data + sec_data_offset),
(void *)((char *)dbg_buff->data + start_offset),
tmp_size);
rc = write_flash(adap, sec, sec_info->sec_data,
CUDBG_SF_SECTOR_SIZE);
if (rc)
goto out;
cur_entity_size -= tmp_size;
set_sector_availability(sec_info, sec, 1);
start_offset += tmp_size;
}
out:
return rc;
}
int write_flash(struct adapter *adap, u32 start_sec, void *data, u32 size)
{
unsigned int addr;
unsigned int i, n;
unsigned int sf_sec_size;
int rc = 0;
u8 *ptr = (u8 *)data;
sf_sec_size = adap->params.sf_size/adap->params.sf_nsec;
addr = start_sec * CUDBG_SF_SECTOR_SIZE;
i = DIV_ROUND_UP(size,/* # of sectors spanned */
sf_sec_size);
rc = t4_flash_erase_sectors(adap, start_sec,
start_sec + i - 1);
/*
* If size == 0 then we're simply erasing the FLASH sectors associated
* with the on-adapter OptionROM Configuration File.
*/
if (rc || size == 0)
goto out;
/* this will write to the flash up to SF_PAGE_SIZE at a time */
for (i = 0; i < size; i += SF_PAGE_SIZE) {
if ((size - i) < SF_PAGE_SIZE)
n = size - i;
else
n = SF_PAGE_SIZE;
rc = t4_write_flash(adap, addr, n, ptr, 0);
if (rc)
goto out;
addr += n;
ptr += n;
}
return 0;
out:
return rc;
}
int cudbg_read_flash_details(void *handle, struct cudbg_flash_hdr *data)
{
int rc;
rc = cudbg_read_flash(handle, (void *)data,
sizeof(struct cudbg_flash_hdr), 0);
return rc;
}
int cudbg_read_flash_data(void *handle, void *buf, u32 buf_size)
{
int rc;
u32 total_hdr_size, data_header_size;
void *payload = NULL;
u32 payload_size = 0;
data_header_size = CUDBG_MAX_ENTITY * sizeof(struct cudbg_entity_hdr) +
sizeof(struct cudbg_hdr);
total_hdr_size = data_header_size + sizeof(struct cudbg_flash_hdr);
/* Copy flash header to buffer */
rc = cudbg_read_flash(handle, buf, total_hdr_size, 0);
if (rc != 0)
goto out;
payload = (char *)buf + total_hdr_size;
payload_size = buf_size - total_hdr_size;
/* Reading flash data to buf */
rc = cudbg_read_flash(handle, payload, payload_size, 1);
if (rc != 0)
goto out;
out:
return rc;
}
int cudbg_read_flash(void *handle, void *data, u32 size, int data_flag)
{
struct cudbg_private *priv = handle;
struct cudbg_init *cudbg_init = &priv->dbg_init;
struct cudbg_flash_sec_info *sec_info = &priv->sec_info;
struct adapter *adap = cudbg_init->adap;
struct cudbg_flash_hdr flash_hdr;
u32 total_hdr_size;
u32 data_hdr_size;
u32 sec_hdr_start_addr;
u32 tmp_size;
u32 data_offset = 0;
u32 i, j;
int rc;
rc = t4_get_flash_params(adap);
if (rc) {
cudbg_init->print("\nGet flash params failed."
"Try Again...readflash\n\n");
return rc;
}
data_hdr_size = CUDBG_MAX_ENTITY * sizeof(struct cudbg_entity_hdr) +
sizeof(struct cudbg_hdr);
total_hdr_size = data_hdr_size + sizeof(struct cudbg_flash_hdr);
sec_hdr_start_addr = CUDBG_SF_SECTOR_SIZE - total_hdr_size;
if (!data_flag) {
/* fill header */
if (!sec_info->max_timestamp) {
/* finding max time stamp because it may
* have older filled sector also
*/
memset(&flash_hdr, 0, sizeof(struct cudbg_flash_hdr));
rc = read_flash(adap, CUDBG_START_SEC, &flash_hdr,
sizeof(struct cudbg_flash_hdr),
sec_hdr_start_addr);
if (flash_hdr.signature == CUDBG_FL_SIGNATURE) {
sec_info->max_timestamp = flash_hdr.timestamp;
} else {
rc = read_flash(adap, CUDBG_START_SEC + 1,
&flash_hdr,
sizeof(struct cudbg_flash_hdr),
sec_hdr_start_addr);
if (flash_hdr.signature == CUDBG_FL_SIGNATURE)
sec_info->max_timestamp =
flash_hdr.timestamp;
else {
cudbg_init->print("\n\tNo cudbg dump "\
"found in flash\n\n");
return CUDBG_STATUS_NO_SIGNATURE;
}
}
/* finding max sequence number because max sequenced
* sector has updated header
*/
for (i = CUDBG_START_SEC; i <
CUDBG_SF_MAX_SECTOR; i++) {
memset(&flash_hdr, 0,
sizeof(struct cudbg_flash_hdr));
rc = read_flash(adap, i, &flash_hdr,
sizeof(struct cudbg_flash_hdr),
sec_hdr_start_addr);
if (flash_hdr.signature == CUDBG_FL_SIGNATURE &&
sec_info->max_timestamp ==
flash_hdr.timestamp &&
sec_info->max_seq_no <=
flash_hdr.sec_seq_no) {
if (sec_info->max_seq_no ==
flash_hdr.sec_seq_no) {
if (sec_info->hdr_data_len <
flash_hdr.data_len)
sec_info->max_seq_sec = i;
} else {
sec_info->max_seq_sec = i;
sec_info->hdr_data_len =
flash_hdr.data_len;
}
sec_info->max_seq_no = flash_hdr.sec_seq_no;
}
}
}
rc = read_flash(adap, sec_info->max_seq_sec,
(struct cudbg_flash_hdr *)data,
size, sec_hdr_start_addr);
if (rc)
cudbg_init->print("Read flash header failed, rc %d\n",
rc);
return rc;
}
/* finding sector sequence sorted */
for (i = 1; i <= sec_info->max_seq_no; i++) {
for (j = CUDBG_START_SEC; j < CUDBG_SF_MAX_SECTOR; j++) {
memset(&flash_hdr, 0, sizeof(struct cudbg_flash_hdr));
rc = read_flash(adap, j, &flash_hdr,
sizeof(struct cudbg_flash_hdr),
sec_hdr_start_addr);
if (flash_hdr.signature ==
CUDBG_FL_SIGNATURE &&
sec_info->max_timestamp ==
flash_hdr.timestamp &&
flash_hdr.sec_seq_no == i) {
if (size + total_hdr_size >
CUDBG_SF_SECTOR_SIZE)
tmp_size = CUDBG_SF_SECTOR_SIZE -
total_hdr_size;
else
tmp_size = size;
if ((i != sec_info->max_seq_no) ||
(i == sec_info->max_seq_no &&
j == sec_info->max_seq_sec)){
/* filling data buffer with sector data
* except sector header
*/
rc = read_flash(adap, j,
(void *)((char *)data +
data_offset),
tmp_size, 0);
data_offset += (tmp_size);
size -= (tmp_size);
break;
}
}
}
}
return rc;
}
int read_flash(struct adapter *adap, u32 start_sec , void *data, u32 size,
u32 start_address)
{
unsigned int addr, i, n;
int rc;
u32 *ptr = (u32 *)data;
addr = start_sec * CUDBG_SF_SECTOR_SIZE + start_address;
size = size / 4;
for (i = 0; i < size; i += SF_PAGE_SIZE) {
if ((size - i) < SF_PAGE_SIZE)
n = size - i;
else
n = SF_PAGE_SIZE;
rc = t4_read_flash(adap, addr, n, ptr, 0);
if (rc)
goto out;
addr = addr + (n*4);
ptr += n;
}
return 0;
out:
return rc;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,255 @@
/*-
* Copyright (c) 2017 Chelsio Communications, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#ifndef __CUDBG_LIB_H__
#define __CUDBG_LIB_H__
#ifndef min_t
#define min_t(type, _a, _b) (((type)(_a) < (type)(_b)) ? (type)(_a) : (type)(_b))
#endif
static int collect_reg_dump(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_fw_devlog(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_qcfg(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_la(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_ma_la(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_obq_ulp0(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_obq_ulp1(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_obq_ulp2(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_obq_ulp3(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_obq_sge(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_obq_ncsi(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_ibq_tp0(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_ibq_tp1(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_ibq_ulp(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_ibq_sge0(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_ibq_sge1(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_ibq_ncsi(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_edc0_meminfo(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_edc1_meminfo(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_mc0_meminfo(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_mc1_meminfo(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_rss(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_rss_key(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_rss_pf_config(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_rss_vf_config(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_rss_config(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_path_mtu(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_sw_state(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
int collect_wtp_data(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_pm_stats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_hw_sched(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_tcp_stats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_tp_err_stats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_fcoe_stats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_rdma_stats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_tp_indirect(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_sge_indirect(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cpl_stats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_ddp_stats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_wc_stats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_ulprx_la(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_lb_stats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_tp_la(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_meminfo(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cim_pif_la(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_clk_info(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_obq_sge_rx_q0(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_obq_sge_rx_q1(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_macstats(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_pcie_indirect(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_pm_indirect(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_full(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_tx_rate(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_tid(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_pcie_config(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_dump_context(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_mps_tcam(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_vpd_data(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_le_tcam(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_cctrl(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_ma_indirect(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_ulptx_la(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_up_cim_indirect(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_pbt_tables(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_mbox_log(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int collect_hma_indirect(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *);
static int (*process_entity[])
(struct cudbg_init *, struct cudbg_buffer *, struct cudbg_error *) = {
collect_reg_dump,
collect_fw_devlog,
collect_cim_la, /*3*/
collect_cim_ma_la,
collect_cim_qcfg,
collect_cim_ibq_tp0,
collect_cim_ibq_tp1,
collect_cim_ibq_ulp,
collect_cim_ibq_sge0,
collect_cim_ibq_sge1,
collect_cim_ibq_ncsi,
collect_cim_obq_ulp0,
collect_cim_obq_ulp1, /*13*/
collect_cim_obq_ulp2,
collect_cim_obq_ulp3,
collect_cim_obq_sge,
collect_cim_obq_ncsi,
collect_edc0_meminfo,
collect_edc1_meminfo,
collect_mc0_meminfo,
collect_mc1_meminfo,
collect_rss, /*22*/
collect_rss_pf_config,
collect_rss_key,
collect_rss_vf_config,
collect_rss_config, /*26*/
collect_path_mtu, /*27*/
collect_sw_state,
collect_wtp_data,
collect_pm_stats,
collect_hw_sched,
collect_tcp_stats,
collect_tp_err_stats,
collect_fcoe_stats,
collect_rdma_stats,
collect_tp_indirect,
collect_sge_indirect,
collect_cpl_stats,
collect_ddp_stats,
collect_wc_stats,
collect_ulprx_la,
collect_lb_stats,
collect_tp_la,
collect_meminfo,
collect_cim_pif_la,
collect_clk_info,
collect_obq_sge_rx_q0,
collect_obq_sge_rx_q1,
collect_macstats,
collect_pcie_indirect,
collect_pm_indirect,
collect_full,
collect_tx_rate,
collect_tid,
collect_pcie_config,
collect_dump_context,
collect_mps_tcam,
collect_vpd_data,
collect_le_tcam,
collect_cctrl,
collect_ma_indirect,
collect_ulptx_la,
NULL, /* ext entity */
collect_up_cim_indirect,
collect_pbt_tables,
collect_mbox_log,
collect_hma_indirect,
};
struct large_entity {
int entity_code;
int skip_flag;
int priority; /* 1 is high priority */
};
static int read_cim_ibq(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error * , int);
static int read_cim_obq(struct cudbg_init *, struct cudbg_buffer *,
struct cudbg_error *, int);
int get_entity_hdr(void *outbuf, int i, u32 size, struct cudbg_entity_hdr **);
void skip_entity(int entity_code);
void reset_skip_entity(void);
int is_large_entity(int entity_code);
#endif

View File

@ -0,0 +1,174 @@
/*-
* Copyright (c) 2017 Chelsio Communications, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#ifndef __CUDBG_LIB_COMMON_H__
#define __CUDBG_LIB_COMMON_H__
/* Extended entity
*
* Layout of the cudbg dump file when extended entity is present.
*
*
* ----------------
* | Global header |
* |---------------|
* |entity headers |
* |---------------|
* | Entity data |
* | * |
* | * |
* | * |
* |---------------|
* |extended entity|
* | header |
* |---------------|
* |extended entity|
* | data |
* -----------------
*
*
* Extended entity: This comes into picture only when cudbg_collect() is called
* multiple times.
*/
#ifndef CUDBG_LITE
#include "common/t4_hw.h"
#endif
#define CUDBG_SF_MAX_SECTOR (FLASH_CUDBG_START_SEC + FLASH_CUDBG_NSECS)
#define CUDBG_SF_SECTOR_SIZE SF_SEC_SIZE
#define CUDBG_START_SEC FLASH_CUDBG_START_SEC
#define CUDBG_FLASH_SIZE FLASH_CUDBG_MAX_SIZE
#define CUDBG_EXT_DATA_BIT 0
#define CUDBG_EXT_DATA_VALID (1 << CUDBG_EXT_DATA_BIT)
struct cudbg_hdr {
u32 signature;
u32 hdr_len;
u16 major_ver;
u16 minor_ver;
u32 data_len;
u32 hdr_flags;
u16 max_entities;
u8 chip_ver;
u8 reserved1;
u32 reserved[8];
};
struct cudbg_entity_hdr {
u32 entity_type;
u32 start_offset;
u32 size;
int hdr_flags;
u32 sys_warn;
u32 sys_err;
u8 num_pad;
u8 flag; /* bit 0 is used to indicate ext data */
u8 reserved1[2];
u32 next_ext_offset; /* pointer to next extended entity meta data */
u32 reserved[5];
};
struct cudbg_ver_hdr {
u32 signature;
u16 revision;
u16 size;
};
struct cudbg_buffer {
u32 size;
u32 offset;
char *data;
};
struct cudbg_error {
int sys_err;
int sys_warn;
int app_err;
};
struct cudbg_flash_sec_info {
int par_sec; /* Represent partially filled sector no */
int par_sec_offset; /* Offset in partially filled sector */
int cur_seq_no;
u32 max_seq_no;
u32 max_seq_sec;
u32 hdr_data_len; /* Total data */
u32 skip_size; /* Total size of large entities. */
u64 max_timestamp;
char sec_data[CUDBG_SF_SECTOR_SIZE];
u8 sec_bitmap[8];
};
struct cudbg_private {
struct cudbg_init dbg_init;
struct cudbg_flash_sec_info sec_info;
};
#define HTONL_NIBBLE(data) ( \
(((uint32_t)(data) >> 28) & 0x0000000F) | \
(((uint32_t)(data) >> 20) & 0x000000F0) | \
(((uint32_t)(data) >> 12) & 0x00000F00) | \
(((uint32_t)(data) >> 4) & 0x0000F000) | \
(((uint32_t)(data) << 4) & 0x000F0000) | \
(((uint32_t)(data) << 12) & 0x00F00000) | \
(((uint32_t)(data) << 20) & 0x0F000000) | \
(((uint32_t)(data) << 28) & 0xF0000000))
#define CDUMP_MAX_COMP_BUF_SIZE ((64 * 1024) - 1)
#define CUDBG_CHUNK_SIZE ((CDUMP_MAX_COMP_BUF_SIZE/1024) * 1024)
#define CUDBG_LEGACY_SIGNATURE 123
#define CUDBG_SIGNATURE 67856866 /* CUDB in ascii */
#define CUDBG_FL_SIGNATURE 0x4355464c /* CUFL in ascii */
#define CUDBG_FL_MAJOR_VERSION 1
#define CUDBG_FL_MINOR_VERSION 1
#define CUDBG_FL_BUILD_VERSION 0
void update_skip_size(struct cudbg_flash_sec_info *, u32);
int write_compression_hdr(struct cudbg_buffer *, struct cudbg_buffer *);
int compress_buff(struct cudbg_buffer *, struct cudbg_buffer *);
int get_scratch_buff(struct cudbg_buffer *, u32, struct cudbg_buffer *);
void release_scratch_buff(struct cudbg_buffer *, struct cudbg_buffer *);
int decompress_buffer(struct cudbg_buffer *, struct cudbg_buffer *);
int validate_buffer(struct cudbg_buffer *compressed_buffer);
int decompress_buffer_wrapper(struct cudbg_buffer *pc_buff,
struct cudbg_buffer *pdc_buff);
int get_entity_rev(struct cudbg_ver_hdr *ver_hdr);
void sort_t(void *base, int num, int size,
int (*cmp_func)(const void *, const void *),
void (*swap_func)(void *, void *, int size));
int cudbg_read_flash(void *handle, void *data, u32 size, int data_flag);
int cudbg_write_flash(void *handle, u64 timestamp, void *data,
u32 start_offset, u32 start_hdr_offset,
u32 cur_entity_size,
u32 ext_size);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,555 @@
/*
FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "osdep.h"
#include "fastlz.h"
#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
/*
* Always check for bound when decompressing.
* Generally it is best to leave it defined.
*/
#define FASTLZ_SAFE
#if defined(WIN32) || defined(__NT__) || defined(_WIN32) || defined(__WIN32__)
#if defined(_MSC_VER) || defined(__GNUC__)
/* #include <windows.h> */
#pragma warning(disable : 4242)
#pragma warning(disable : 4244)
#endif
#endif
/*
* Give hints to the compiler for branch prediction optimization.
*/
#if defined(__GNUC__) && (__GNUC__ > 2)
#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
#else
#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
#endif
/*
* Use inlined functions for supported systems.
*/
#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) ||\
defined(__WATCOMC__) || defined(__SUNPRO_C)
#define FASTLZ_INLINE inline
#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
#define FASTLZ_INLINE __inline
#else
#define FASTLZ_INLINE
#endif
/*
* Prevent accessing more than 8-bit at once, except on x86 architectures.
*/
#if !defined(FASTLZ_STRICT_ALIGN)
#define FASTLZ_STRICT_ALIGN
#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
#undef FASTLZ_STRICT_ALIGN
#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */
#undef FASTLZ_STRICT_ALIGN
#elif defined(_M_IX86) /* Intel, MSVC */
#undef FASTLZ_STRICT_ALIGN
#elif defined(__386)
#undef FASTLZ_STRICT_ALIGN
#elif defined(_X86_) /* MinGW */
#undef FASTLZ_STRICT_ALIGN
#elif defined(__I86__) /* Digital Mars */
#undef FASTLZ_STRICT_ALIGN
#endif
#endif
/*
* FIXME: use preprocessor magic to set this on different platforms!
*/
#define MAX_COPY 32
#define MAX_LEN 264 /* 256 + 8 */
#define MAX_DISTANCE 8192
#if !defined(FASTLZ_STRICT_ALIGN)
#define FASTLZ_READU16(p) (*((const unsigned short *)(p)))
#else
#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
#endif
#define HASH_LOG 13
#define HASH_SIZE (1 << HASH_LOG)
#define HASH_MASK (HASH_SIZE - 1)
#define HASH_FUNCTION(v, p) {\
v = FASTLZ_READU16(p);\
v ^= FASTLZ_READU16(p + 1)^\
(v>>(16 - HASH_LOG));\
v &= HASH_MASK;\
}
#undef FASTLZ_LEVEL
#define FASTLZ_LEVEL 1
#undef FASTLZ_COMPRESSOR
#undef FASTLZ_DECOMPRESSOR
#define FASTLZ_COMPRESSOR fastlz1_compress
#define FASTLZ_DECOMPRESSOR fastlz1_decompress
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void *input, int length,
void *output);
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void *input, int length,
void *output, int maxout);
#include "fastlz.c"
#undef FASTLZ_LEVEL
#define FASTLZ_LEVEL 2
#undef MAX_DISTANCE
#define MAX_DISTANCE 8191
#define MAX_FARDISTANCE (65535 + MAX_DISTANCE - 1)
#undef FASTLZ_COMPRESSOR
#undef FASTLZ_DECOMPRESSOR
#define FASTLZ_COMPRESSOR fastlz2_compress
#define FASTLZ_DECOMPRESSOR fastlz2_decompress
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void *input, int length,
void *output);
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void *input, int length,
void *output, int maxout);
#include "fastlz.c"
int fastlz_compress(const void *input, int length, void *output)
{
/* for short block, choose fastlz1 */
if (length < 65536)
return fastlz1_compress(input, length, output);
/* else... */
return fastlz2_compress(input, length, output);
}
int fastlz_decompress(const void *input, int length, void *output, int maxout)
{
/* magic identifier for compression level */
int level = ((*(const unsigned char *)input) >> 5) + 1;
if (level == 1)
return fastlz1_decompress(input, length, output, maxout);
if (level == 2)
return fastlz2_decompress(input, length, output, maxout);
/* unknown level, trigger error */
return 0;
}
int fastlz_compress_level(int level, const void *input, int length,
void *output)
{
if (level == 1)
return fastlz1_compress(input, length, output);
if (level == 2)
return fastlz2_compress(input, length, output);
return 0;
}
#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void *input, int length,
void *output)
{
const unsigned char *ip = (const unsigned char *) input;
const unsigned char *ip_bound = ip + length - 2;
const unsigned char *ip_limit = ip + length - 12;
unsigned char *op = (unsigned char *) output;
static const unsigned char *g_htab[HASH_SIZE];
const unsigned char **htab = g_htab;
const unsigned char **hslot;
unsigned int hval;
unsigned int copy;
/* sanity check */
if (FASTLZ_UNEXPECT_CONDITIONAL(length < 4)) {
if (length) {
/* create literal copy only */
*op++ = length - 1;
ip_bound++;
while (ip <= ip_bound)
*op++ = *ip++;
return length + 1;
} else
return 0;
}
/* initializes hash table */
for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
*hslot = ip;
/* we start with literal copy */
copy = 2;
*op++ = MAX_COPY - 1;
*op++ = *ip++;
*op++ = *ip++;
/* main loop */
while (FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) {
const unsigned char *ref;
unsigned int distance;
/* minimum match length */
unsigned int len = 3;
/* comparison starting-point */
const unsigned char *anchor = ip;
/* check for a run */
#if FASTLZ_LEVEL == 2
if (ip[0] == ip[-1] &&
FASTLZ_READU16(ip - 1) == FASTLZ_READU16(ip + 1)) {
distance = 1;
ip += 3;
ref = anchor - 1 + 3;
goto match;
}
#endif
/* find potential match */
HASH_FUNCTION(hval, ip);
hslot = htab + hval;
ref = htab[hval];
/* calculate distance to the match */
distance = anchor - ref;
/* update hash table */
*hslot = anchor;
if (!ref)
goto literal;
/* is this a match? check the first 3 bytes */
if (distance == 0 ||
#if FASTLZ_LEVEL == 1
(distance >= MAX_DISTANCE) ||
#else
(distance >= MAX_FARDISTANCE) ||
#endif
*ref++ != *ip++ || *ref++ != *ip++ ||
*ref++ != *ip++)
goto literal;
#if FASTLZ_LEVEL == 2
/* far, needs at least 5-byte match */
if (distance >= MAX_DISTANCE) {
if (*ip++ != *ref++ || *ip++ != *ref++)
goto literal;
len += 2;
}
match:
#endif
/* last matched byte */
ip = anchor + len;
/* distance is biased */
distance--;
if (!distance) {
/* zero distance means a run */
unsigned char x = ip[-1];
while (ip < ip_bound)
if (*ref++ != x)
break;
else
ip++;
} else
for (;;) {
/* safe because the outer check
* against ip limit */
if (*ref++ != *ip++)
break;
if (*ref++ != *ip++)
break;
if (*ref++ != *ip++)
break;
if (*ref++ != *ip++)
break;
if (*ref++ != *ip++)
break;
if (*ref++ != *ip++)
break;
if (*ref++ != *ip++)
break;
if (*ref++ != *ip++)
break;
while (ip < ip_bound)
if (*ref++ != *ip++)
break;
break;
}
/* if we have copied something, adjust the copy count */
if (copy)
/* copy is biased, '0' means 1 byte copy */
*(op - copy - 1) = copy - 1;
else
/* back, to overwrite the copy count */
op--;
/* reset literal counter */
copy = 0;
/* length is biased, '1' means a match of 3 bytes */
ip -= 3;
len = ip - anchor;
/* encode the match */
#if FASTLZ_LEVEL == 2
if (distance < MAX_DISTANCE) {
if (len < 7) {
*op++ = (len << 5) + (distance >> 8);
*op++ = (distance & 255);
} else {
*op++ = (7 << 5) + (distance >> 8);
for (len -= 7; len >= 255; len -= 255)
*op++ = 255;
*op++ = len;
*op++ = (distance & 255);
}
} else {
/* far away, but not yet in the another galaxy... */
if (len < 7) {
distance -= MAX_DISTANCE;
*op++ = (len << 5) + 31;
*op++ = 255;
*op++ = distance >> 8;
*op++ = distance & 255;
} else {
distance -= MAX_DISTANCE;
*op++ = (7 << 5) + 31;
for (len -= 7; len >= 255; len -= 255)
*op++ = 255;
*op++ = len;
*op++ = 255;
*op++ = distance >> 8;
*op++ = distance & 255;
}
}
#else
if (FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN - 2))
while (len > MAX_LEN - 2) {
*op++ = (7 << 5) + (distance >> 8);
*op++ = MAX_LEN - 2 - 7 - 2;
*op++ = (distance & 255);
len -= MAX_LEN - 2;
}
if (len < 7) {
*op++ = (len << 5) + (distance >> 8);
*op++ = (distance & 255);
} else {
*op++ = (7 << 5) + (distance >> 8);
*op++ = len - 7;
*op++ = (distance & 255);
}
#endif
/* update the hash at match boundary */
HASH_FUNCTION(hval, ip);
htab[hval] = ip++;
HASH_FUNCTION(hval, ip);
htab[hval] = ip++;
/* assuming literal copy */
*op++ = MAX_COPY - 1;
continue;
literal:
*op++ = *anchor++;
ip = anchor;
copy++;
if (FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) {
copy = 0;
*op++ = MAX_COPY - 1;
}
}
/* left-over as literal copy */
ip_bound++;
while (ip <= ip_bound) {
*op++ = *ip++;
copy++;
if (copy == MAX_COPY) {
copy = 0;
*op++ = MAX_COPY - 1;
}
}
/* if we have copied something, adjust the copy length */
if (copy)
*(op - copy - 1) = copy - 1;
else
op--;
#if FASTLZ_LEVEL == 2
/* marker for fastlz2 */
*(unsigned char *)output |= (1 << 5);
#endif
return op - (unsigned char *)output;
}
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void *input, int length,
void *output, int maxout)
{
const unsigned char *ip = (const unsigned char *) input;
const unsigned char *ip_limit = ip + length;
unsigned char *op = (unsigned char *) output;
unsigned char *op_limit = op + maxout;
unsigned int ctrl = (*ip++) & 31;
int loop = 1;
do {
const unsigned char *ref = op;
unsigned int len = ctrl >> 5;
unsigned int ofs = (ctrl & 31) << 8;
if (ctrl >= 32) {
#if FASTLZ_LEVEL == 2
unsigned char code;
#endif
len--;
ref -= ofs;
if (len == 7 - 1)
#if FASTLZ_LEVEL == 1
len += *ip++;
ref -= *ip++;
#else
do {
code = *ip++;
len += code;
} while (code == 255);
code = *ip++;
ref -= code;
/* match from 16-bit distance */
if (FASTLZ_UNEXPECT_CONDITIONAL(code == 255))
if (FASTLZ_EXPECT_CONDITIONAL(ofs ==
(31 << 8))) {
ofs = (*ip++) << 8;
ofs += *ip++;
ref = op - ofs - MAX_DISTANCE;
}
#endif
#ifdef FASTLZ_SAFE
if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 >
op_limit))
return 0;
if (FASTLZ_UNEXPECT_CONDITIONAL(ref - 1 <
(unsigned char *)output)
)
return 0;
#endif
if (FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
ctrl = *ip++;
else
loop = 0;
if (ref == op) {
/* optimize copy for a run */
unsigned char b = ref[-1];
*op++ = b;
*op++ = b;
*op++ = b;
for (; len; --len)
*op++ = b;
} else {
#if !defined(FASTLZ_STRICT_ALIGN)
const unsigned short *p;
unsigned short *q;
#endif
/* copy from reference */
ref--;
*op++ = *ref++;
*op++ = *ref++;
*op++ = *ref++;
#if !defined(FASTLZ_STRICT_ALIGN)
/* copy a byte, so that now it's word aligned */
if (len & 1) {
*op++ = *ref++;
len--;
}
/* copy 16-bit at once */
q = (unsigned short *) op;
op += len;
p = (const unsigned short *) ref;
for (len >>= 1; len > 4; len -= 4) {
*q++ = *p++;
*q++ = *p++;
*q++ = *p++;
*q++ = *p++;
}
for (; len; --len)
*q++ = *p++;
#else
for (; len; --len)
*op++ = *ref++;
#endif
}
} else {
ctrl++;
#ifdef FASTLZ_SAFE
if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
return 0;
if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
return 0;
#endif
*op++ = *ip++;
for (--ctrl; ctrl; ctrl--)
*op++ = *ip++;
loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
if (loop)
ctrl = *ip++;
}
} while (FASTLZ_EXPECT_CONDITIONAL(loop));
return op - (unsigned char *)output;
}
#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */

View File

@ -0,0 +1,62 @@
/*
FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
$FreeBSD$
*/
#ifndef FASTLZ_H
#define FASTLZ_H
#define FASTLZ_VERSION 0x000100
#define FASTLZ_VERSION_MAJOR 0
#define FASTLZ_VERSION_MINOR 0
#define FASTLZ_VERSION_REVISION 0
#define FASTLZ_VERSION_STRING "0.1.0"
struct cudbg_buffer;
int fastlz_compress(const void *input, int length, void *output);
int fastlz_compress_level(int level, const void *input, int length,
void *output);
int fastlz_decompress(const void *input, int length, void *output, int maxout);
/* prototypes */
int write_magic(struct cudbg_buffer *);
int detect_magic(struct cudbg_buffer *);
int write_to_buf(void *, u32, u32 *, void *, u32);
int read_from_buf(void *, u32, u32 *, void *, u32);
int write_chunk_header(struct cudbg_buffer *, int, int, unsigned long,
unsigned long, unsigned long);
int read_chunk_header(struct cudbg_buffer *, int* , int*, unsigned long*,
unsigned long*, unsigned long*);
unsigned long block_compress(const unsigned char *, unsigned long length,
unsigned char *);
#endif /* FASTLZ_H */

View File

@ -0,0 +1,531 @@
/*
FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "osdep.h"
#include "cudbg.h"
#include "cudbg_lib_common.h"
#include "fastlz.h"
static unsigned char sixpack_magic[8] = {137, '6', 'P', 'K', 13, 10, 26, 10};
#define CUDBG_BLOCK_SIZE (63*1024)
#define CUDBG_CHUNK_BUF_LEN 16
#define CUDBG_MIN_COMPR_LEN 32 /*min data length for applying compression*/
/* for Adler-32 checksum algorithm, see RFC 1950 Section 8.2 */
#define ADLER32_BASE 65521
static inline unsigned long update_adler32(unsigned long checksum,
const void *buf, int len)
{
const unsigned char *ptr = (const unsigned char *)buf;
unsigned long s1 = checksum & 0xffff;
unsigned long s2 = (checksum >> 16) & 0xffff;
while (len > 0) {
unsigned k = len < 5552 ? len : 5552;
len -= k;
while (k >= 8) {
s1 += *ptr++; s2 += s1;
s1 += *ptr++; s2 += s1;
s1 += *ptr++; s2 += s1;
s1 += *ptr++; s2 += s1;
s1 += *ptr++; s2 += s1;
s1 += *ptr++; s2 += s1;
s1 += *ptr++; s2 += s1;
s1 += *ptr++; s2 += s1;
k -= 8;
}
while (k-- > 0) {
s1 += *ptr++; s2 += s1;
}
s1 = s1 % ADLER32_BASE;
s2 = s2 % ADLER32_BASE;
}
return (s2 << 16) + s1;
}
int write_magic(struct cudbg_buffer *_out_buff)
{
int rc;
rc = write_to_buf(_out_buff->data, _out_buff->size, &_out_buff->offset,
sixpack_magic, 8);
return rc;
}
int write_to_buf(void *out_buf, u32 out_buf_size, u32 *offset, void *in_buf,
u32 in_buf_size)
{
int rc = 0;
if (*offset >= out_buf_size) {
rc = CUDBG_STATUS_OUTBUFF_OVERFLOW;
goto err;
}
memcpy((char *)out_buf + *offset, in_buf, in_buf_size);
*offset = *offset + in_buf_size;
err:
return rc;
}
int read_from_buf(void *in_buf, u32 in_buf_size, u32 *offset, void *out_buf,
u32 out_buf_size)
{
if (in_buf_size - *offset < out_buf_size)
return 0;
memcpy((char *)out_buf, (char *)in_buf + *offset, out_buf_size);
*offset = *offset + out_buf_size;
return out_buf_size;
}
int write_chunk_header(struct cudbg_buffer *_outbuf, int id, int options,
unsigned long size, unsigned long checksum,
unsigned long extra)
{
unsigned char buffer[CUDBG_CHUNK_BUF_LEN];
int rc = 0;
buffer[0] = id & 255;
buffer[1] = (unsigned char)(id >> 8);
buffer[2] = options & 255;
buffer[3] = (unsigned char)(options >> 8);
buffer[4] = size & 255;
buffer[5] = (size >> 8) & 255;
buffer[6] = (size >> 16) & 255;
buffer[7] = (size >> 24) & 255;
buffer[8] = checksum & 255;
buffer[9] = (checksum >> 8) & 255;
buffer[10] = (checksum >> 16) & 255;
buffer[11] = (checksum >> 24) & 255;
buffer[12] = extra & 255;
buffer[13] = (extra >> 8) & 255;
buffer[14] = (extra >> 16) & 255;
buffer[15] = (extra >> 24) & 255;
rc = write_to_buf(_outbuf->data, _outbuf->size, &_outbuf->offset,
buffer, 16);
return rc;
}
int write_compression_hdr(struct cudbg_buffer *pin_buff,
struct cudbg_buffer *pout_buff)
{
struct cudbg_buffer tmp_buffer;
unsigned long fsize = pin_buff->size;
unsigned char *buffer;
unsigned long checksum;
int rc;
char *shown_name = "abc";
/* Always release inner scratch buffer, before releasing outer. */
rc = get_scratch_buff(pout_buff, 10, &tmp_buffer);
if (rc)
goto err;
buffer = (unsigned char *)tmp_buffer.data;
rc = write_magic(pout_buff);
if (rc)
goto err1;
/* chunk for File Entry */
buffer[0] = fsize & 255;
buffer[1] = (fsize >> 8) & 255;
buffer[2] = (fsize >> 16) & 255;
buffer[3] = (fsize >> 24) & 255;
buffer[4] = 0;
buffer[5] = 0;
buffer[6] = 0;
buffer[7] = 0;
buffer[8] = (strlen(shown_name)+1) & 255;
buffer[9] = (unsigned char)((strlen(shown_name)+1) >> 8);
checksum = 1L;
checksum = update_adler32(checksum, buffer, 10);
checksum = update_adler32(checksum, shown_name,
(int)strlen(shown_name)+1);
rc = write_chunk_header(pout_buff, 1, 0,
10+(unsigned long)strlen(shown_name)+1,
checksum, 0);
if (rc)
goto err1;
rc = write_to_buf(pout_buff->data, pout_buff->size,
&(pout_buff->offset), buffer, 10);
if (rc)
goto err1;
rc = write_to_buf(pout_buff->data, pout_buff->size,
&(pout_buff->offset), shown_name,
(u32)strlen(shown_name)+1);
if (rc)
goto err1;
err1:
release_scratch_buff(&tmp_buffer, pout_buff);
err:
return rc;
}
int compress_buff(struct cudbg_buffer *pin_buff, struct cudbg_buffer *pout_buff)
{
struct cudbg_buffer tmp_buffer;
struct cudbg_hdr *cudbg_hdr;
unsigned long checksum;
unsigned char *result;
unsigned int bytes_read;
int chunk_size, level = 2, rc = 0;
int compress_method = 1;
bytes_read = pin_buff->size;
rc = get_scratch_buff(pout_buff, CUDBG_BLOCK_SIZE, &tmp_buffer);
if (rc)
goto err;
result = (unsigned char *)tmp_buffer.data;
if (bytes_read < 32)
compress_method = 0;
cudbg_hdr = (struct cudbg_hdr *) pout_buff->data;
switch (compress_method) {
case 1:
chunk_size = fastlz_compress_level(level, pin_buff->data,
bytes_read, result);
checksum = update_adler32(1L, result, chunk_size);
if ((chunk_size > 62000) && (cudbg_hdr->reserved[7] < (u32)
chunk_size)) /* 64512 */
cudbg_hdr->reserved[7] = (u32) chunk_size;
rc = write_chunk_header(pout_buff, 17, 1, chunk_size, checksum,
bytes_read);
if (rc)
goto err_put_buff;
rc = write_to_buf(pout_buff->data, pout_buff->size,
&pout_buff->offset, result, chunk_size);
if (rc)
goto err_put_buff;
break;
/* uncompressed, also fallback method */
case 0:
default:
checksum = update_adler32(1L, pin_buff->data, bytes_read);
rc = write_chunk_header(pout_buff, 17, 0, bytes_read, checksum,
bytes_read);
if (rc)
goto err_put_buff;
rc = write_to_buf(pout_buff->data, pout_buff->size,
&pout_buff->offset, pin_buff->data,
bytes_read);
if (rc)
goto err_put_buff;
break;
}
err_put_buff:
release_scratch_buff(&tmp_buffer, pout_buff);
err:
return rc;
}
/* return non-zero if magic sequence is detected */
/* warning: reset the read pointer to the beginning of the file */
int detect_magic(struct cudbg_buffer *_c_buff)
{
unsigned char buffer[8];
size_t bytes_read;
int c;
bytes_read = read_from_buf(_c_buff->data, _c_buff->size,
&_c_buff->offset, buffer, 8);
if (bytes_read < 8)
return 0;
for (c = 0; c < 8; c++)
if (buffer[c] != sixpack_magic[c])
return 0;
return -1;
}
static inline unsigned long readU16(const unsigned char *ptr)
{
return ptr[0]+(ptr[1]<<8);
}
static inline unsigned long readU32(const unsigned char *ptr)
{
return ptr[0]+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
}
int read_chunk_header(struct cudbg_buffer *pc_buff, int *pid, int *poptions,
unsigned long *psize, unsigned long *pchecksum,
unsigned long *pextra)
{
unsigned char buffer[CUDBG_CHUNK_BUF_LEN];
int byte_r = read_from_buf(pc_buff->data, pc_buff->size,
&pc_buff->offset, buffer, 16);
if (byte_r == 0)
return 0;
*pid = readU16(buffer) & 0xffff;
*poptions = readU16(buffer+2) & 0xffff;
*psize = readU32(buffer+4) & 0xffffffff;
*pchecksum = readU32(buffer+8) & 0xffffffff;
*pextra = readU32(buffer+12) & 0xffffffff;
return 0;
}
int validate_buffer(struct cudbg_buffer *compressed_buffer)
{
if (!detect_magic(compressed_buffer))
return CUDBG_STATUS_INVALID_BUFF;
return 0;
}
int decompress_buffer(struct cudbg_buffer *pc_buff,
struct cudbg_buffer *pd_buff)
{
struct cudbg_buffer tmp_compressed_buffer;
struct cudbg_buffer tmp_decompressed_buffer;
unsigned char *compressed_buffer;
unsigned char *decompressed_buffer;
unsigned char buffer[CUDBG_MIN_COMPR_LEN];
unsigned long chunk_size;
unsigned long chunk_checksum;
unsigned long chunk_extra;
unsigned long checksum;
unsigned long total_extracted = 0;
unsigned long r;
unsigned long remaining;
unsigned long bytes_read;
u32 decompressed_size = 0;
int chunk_id, chunk_options, rc;
if (pd_buff->size < 2 * CUDBG_BLOCK_SIZE)
return CUDBG_STATUS_SMALL_BUFF;
rc = get_scratch_buff(pd_buff, CUDBG_BLOCK_SIZE,
&tmp_compressed_buffer);
if (rc)
goto err_cbuff;
rc = get_scratch_buff(pd_buff, CUDBG_BLOCK_SIZE,
&tmp_decompressed_buffer);
if (rc)
goto err_dcbuff;
compressed_buffer = (unsigned char *)tmp_compressed_buffer.data;
decompressed_buffer = (unsigned char *)tmp_decompressed_buffer.data;
/* main loop */
for (;;) {
if (pc_buff->offset > pc_buff->size)
break;
rc = read_chunk_header(pc_buff, &chunk_id, &chunk_options,
&chunk_size, &chunk_checksum,
&chunk_extra);
if (rc != 0)
break;
/* skip 8+16 */
if ((chunk_id == 1) && (chunk_size > 10) &&
(chunk_size < CUDBG_BLOCK_SIZE)) {
bytes_read = read_from_buf(pc_buff->data, pc_buff->size,
&pc_buff->offset, buffer,
chunk_size);
if (bytes_read == 0)
return 0;
checksum = update_adler32(1L, buffer, chunk_size);
if (checksum != chunk_checksum)
return CUDBG_STATUS_CHKSUM_MISSMATCH;
decompressed_size = (u32)readU32(buffer);
if (pd_buff->size < decompressed_size) {
pd_buff->size = 2 * CUDBG_BLOCK_SIZE +
decompressed_size;
pc_buff->offset -= chunk_size + 16;
return CUDBG_STATUS_SMALL_BUFF;
}
total_extracted = 0;
}
if (chunk_size > CUDBG_BLOCK_SIZE) {
/* Release old allocated memory */
release_scratch_buff(&tmp_decompressed_buffer, pd_buff);
release_scratch_buff(&tmp_compressed_buffer, pd_buff);
/* allocate new memory with chunk_size size */
rc = get_scratch_buff(pd_buff, chunk_size,
&tmp_compressed_buffer);
if (rc)
goto err_cbuff;
rc = get_scratch_buff(pd_buff, chunk_size,
&tmp_decompressed_buffer);
if (rc)
goto err_dcbuff;
compressed_buffer = (unsigned char *)tmp_compressed_buffer.data;
decompressed_buffer = (unsigned char *)tmp_decompressed_buffer.data;
}
if ((chunk_id == 17) && decompressed_size) {
/* uncompressed */
switch (chunk_options) {
/* stored, simply copy to output */
case 0:
total_extracted += chunk_size;
remaining = chunk_size;
checksum = 1L;
for (;;) {
/* Write a funtion for this */
r = (CUDBG_BLOCK_SIZE < remaining) ?
CUDBG_BLOCK_SIZE : remaining;
bytes_read =
read_from_buf(pc_buff->data,
pc_buff->size,
&pc_buff->offset, buffer,
r);
if (bytes_read == 0)
return 0;
write_to_buf(pd_buff->data,
pd_buff->size,
&pd_buff->offset, buffer,
bytes_read);
checksum = update_adler32(checksum,
buffer,
bytes_read);
remaining -= bytes_read;
/* verify everything is written
* correctly */
if (checksum != chunk_checksum)
return
CUDBG_STATUS_CHKSUM_MISSMATCH;
}
break;
/* compressed using FastLZ */
case 1:
bytes_read = read_from_buf(pc_buff->data,
pc_buff->size,
&pc_buff->offset,
compressed_buffer,
chunk_size);
if (bytes_read == 0)
return 0;
checksum = update_adler32(1L, compressed_buffer,
chunk_size);
total_extracted += chunk_extra;
/* verify that the chunk data is correct */
if (checksum != chunk_checksum) {
return CUDBG_STATUS_CHKSUM_MISSMATCH;
} else {
/* decompress and verify */
remaining =
fastlz_decompress(compressed_buffer,
chunk_size,
decompressed_buffer,
chunk_extra);
if (remaining != chunk_extra) {
rc =
CUDBG_STATUS_DECOMPRESS_FAIL;
goto err;
} else {
write_to_buf(pd_buff->data,
pd_buff->size,
&pd_buff->offset,
decompressed_buffer,
chunk_extra);
}
}
break;
default:
break;
}
}
}
err:
release_scratch_buff(&tmp_decompressed_buffer, pd_buff);
err_dcbuff:
release_scratch_buff(&tmp_compressed_buffer, pd_buff);
err_cbuff:
return rc;
}

View File

@ -59,6 +59,7 @@ enum {
T4_LOAD_CFG, /* copy a config file to card's flash */
T4_LOAD_BOOT, /* flash boot rom */
T4_LOAD_BOOTCFG, /* flash bootcfg */
T4_CUDBG_DUMP, /* debug dump of chip state */
};
struct t4_reg {
@ -334,6 +335,13 @@ struct t4_tracer {
struct t4_trace_params tp;
};
struct t4_cudbg_dump {
uint8_t wr_flash;
uint8_t bitmap[16];
uint32_t len;
uint8_t *data;
};
#define CHELSIO_T4_GETREG _IOWR('f', T4_GETREG, struct t4_reg)
#define CHELSIO_T4_SETREG _IOW('f', T4_SETREG, struct t4_reg)
#define CHELSIO_T4_REGDUMP _IOWR('f', T4_REGDUMP, struct t4_regdump)
@ -357,4 +365,5 @@ struct t4_tracer {
#define CHELSIO_T4_LOAD_CFG _IOW('f', T4_LOAD_CFG, struct t4_data)
#define CHELSIO_T4_LOAD_BOOT _IOW('f', T4_LOAD_BOOT, struct t4_bootrom)
#define CHELSIO_T4_LOAD_BOOTCFG _IOW('f', T4_LOAD_BOOTCFG, struct t4_data)
#define CHELSIO_T4_CUDBG_DUMP _IOWR('f', T4_CUDBG_DUMP, struct t4_cudbg_dump)
#endif

View File

@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
#include "common/t4_msg.h"
#include "common/t4_regs.h"
#include "common/t4_regs_values.h"
#include "cudbg/cudbg.h"
#include "t4_ioctl.h"
#include "t4_l2t.h"
#include "t4_mp_ring.h"
@ -575,6 +576,7 @@ static int load_fw(struct adapter *, struct t4_data *);
static int load_cfg(struct adapter *, struct t4_data *);
static int load_boot(struct adapter *, struct t4_bootrom *);
static int load_bootcfg(struct adapter *, struct t4_data *);
static int cudbg_dump(struct adapter *, struct t4_cudbg_dump *);
static int read_card_mem(struct adapter *, int, struct t4_mem_range *);
static int read_i2c(struct adapter *, struct t4_i2c_data *);
#ifdef TCP_OFFLOAD
@ -9084,6 +9086,49 @@ load_bootcfg(struct adapter *sc, struct t4_data *bc)
return (rc);
}
static int
cudbg_dump(struct adapter *sc, struct t4_cudbg_dump *dump)
{
int rc;
struct cudbg_init *cudbg;
void *handle, *buf;
/* buf is large, don't block if no memory is available */
buf = malloc(dump->len, M_CXGBE, M_NOWAIT);
if (buf == NULL)
return (ENOMEM);
handle = cudbg_alloc_handle();
if (handle == NULL) {
rc = ENOMEM;
goto done;
}
cudbg = cudbg_get_init(handle);
cudbg->adap = sc;
cudbg->print = (cudbg_print_cb)printf;
#ifndef notyet
device_printf(sc->dev, "%s: wr_flash %u, len %u, data %p.\n",
__func__, dump->wr_flash, dump->len, dump->data);
#endif
if (dump->wr_flash)
cudbg->use_flash = 1;
MPASS(sizeof(cudbg->dbg_bitmap) == sizeof(dump->bitmap));
memcpy(cudbg->dbg_bitmap, dump->bitmap, sizeof(cudbg->dbg_bitmap));
rc = cudbg_collect(handle, buf, &dump->len);
if (rc != 0)
goto done;
rc = copyout(buf, dump->data, dump->len);
done:
cudbg_free_handle(handle);
free(buf, M_CXGBE);
return (rc);
}
#define MAX_READ_BUF_SIZE (128 * 1024)
static int
read_card_mem(struct adapter *sc, int win, struct t4_mem_range *mr)
@ -9432,6 +9477,9 @@ t4_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data, int fflag,
case CHELSIO_T4_LOAD_BOOTCFG:
rc = load_bootcfg(sc, (struct t4_data *)data);
break;
case CHELSIO_T4_CUDBG_DUMP:
rc = cudbg_dump(sc, (struct t4_cudbg_dump *)data);
break;
default:
rc = ENOTTY;
}

View File

@ -3,7 +3,7 @@
#
CXGBE= ${SRCTOP}/sys/dev/cxgbe
.PATH: ${CXGBE} ${CXGBE}/common
.PATH: ${CXGBE} ${CXGBE}/common ${CXGBE}/cudbg
KMOD= if_cxgbe
SRCS= bus_if.h
@ -24,6 +24,12 @@ SRCS+= t4_netmap.c
SRCS+= t4_sched.c
SRCS+= t4_sge.c
SRCS+= t4_tracer.c
SRCS+= cudbg_common.c
SRCS+= cudbg_flash_utils.c
SRCS+= cudbg_lib.c
SRCS+= cudbg_wtp.c
SRCS+= fastlz_api.c
SRCS+= fastlz.c
# Provide the timestamp of a packet in its header mbuf.
#CFLAGS+= -DT4_PKT_TIMESTAMP

View File

@ -90,6 +90,7 @@ usage(FILE *fp)
fprintf(fp,
"\tclearstats <port> clear port statistics\n"
"\tcontext <type> <id> show an SGE context\n"
"\tdumpstate <dump.bin> dump chip state\n"
"\tfilter <idx> [<param> <val>] ... set a filter\n"
"\tfilter <idx> delete|clear delete a filter\n"
"\tfilter list list all filters\n"
@ -1883,6 +1884,40 @@ loadcfg(int argc, const char *argv[])
return (rc);
}
static int
dumpstate(int argc, const char *argv[])
{
int rc, fd;
struct t4_cudbg_dump dump = {0};
const char *fname = argv[0];
if (argc != 1) {
warnx("dumpstate: incorrect number of arguments.");
return (EINVAL);
}
fd = open(fname, O_CREAT | O_TRUNC | O_EXCL | O_WRONLY);
if (fd < 0) {
warn("open(%s)", fname);
return (errno);
}
dump.wr_flash = 0;
memset(&dump.bitmap, 0xff, sizeof(dump.bitmap));
dump.len = 8 * 1024 * 1024;
dump.data = malloc(dump.len);
if (dump.data == NULL) {
close(fd);
return (ENOMEM);
}
rc = doit(CHELSIO_T4_CUDBG_DUMP, &dump);
write(fd, dump.data, dump.len);
free(dump.data);
close(fd);
return (rc);
}
static int
read_mem(uint32_t addr, uint32_t len, void (*output)(uint32_t *, uint32_t))
{
@ -2888,6 +2923,8 @@ run_cmd(int argc, const char *argv[])
rc = loadboot(argc, argv);
else if (!strcmp(cmd, "loadboot-cfg"))
rc = loadbootcfg(argc, argv);
else if (!strcmp(cmd, "dumpstate"))
rc = dumpstate(argc, argv);
else {
rc = EINVAL;
warnx("invalid command \"%s\"", cmd);