From 3a3682abd45edf421d9bc9a2e8dcce62e490e28c Mon Sep 17 00:00:00 2001 From: Bing Xia Date: Thu, 17 Apr 2025 19:29:49 +0800 Subject: [PATCH] hikptool: ras: Add support for exporting black box data to file. 1. support export black box data e.g. hikptool bbox_export 2. support clear black box data e.g. hikptool bbox_export -c Signed-off-by: Bing Xia xiabing14@h-partners.com Match-id-6bd3deff946891cabb1547cec9e1e6d068d3c74a --- ...-support-for-exporting-black-box-dat.patch | 713 ++++++++++++++++++ hikptool.spec | 6 +- 2 files changed, 718 insertions(+), 1 deletion(-) create mode 100644 0099-hikptool-ras-Add-support-for-exporting-black-box-dat.patch diff --git a/0099-hikptool-ras-Add-support-for-exporting-black-box-dat.patch b/0099-hikptool-ras-Add-support-for-exporting-black-box-dat.patch new file mode 100644 index 0000000..fe1d504 --- /dev/null +++ b/0099-hikptool-ras-Add-support-for-exporting-black-box-dat.patch @@ -0,0 +1,713 @@ +From 2cfa1ab8d699bc0336063409942ff5afb86394a8 Mon Sep 17 00:00:00 2001 +From: Bing Xia +Date: Wed, 12 Mar 2025 10:24:21 +0800 +Subject: [PATCH] hikptool: ras: Add support for exporting black box data to + file. + +1. support export black box data + e.g. hikptool bbox_export +2. support clear black box data + e.g. hikptool bbox_export -c + +Signed-off-by: Bing Xia xiabing14@h-partners.com +--- + CMakeLists.txt | 1 + + libhikptdev/include/hikptdev_plug.h | 3 +- + ras/ras_func/ras_common.h | 26 ++ + ras/ras_func/ras_dump_data.c | 389 ++++++++++++++++++++++++++++ + ras/ras_func/ras_dump_data.h | 88 +++++++ + ras/user_cmd/ras_cmd_dump.c | 99 +++++++ + ras/user_cmd/ras_tools_include.h | 25 ++ + 7 files changed, 630 insertions(+), 1 deletion(-) + create mode 100644 ras/ras_func/ras_common.h + create mode 100644 ras/ras_func/ras_dump_data.c + create mode 100644 ras/ras_func/ras_dump_data.h + create mode 100644 ras/user_cmd/ras_cmd_dump.c + create mode 100644 ras/user_cmd/ras_tools_include.h + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 4f4eb03..d50e2ac 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -47,6 +47,7 @@ file(GLOB_RECURSE HIKPTOOL_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/socip/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/hccs/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/sdma/*.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/ras/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/tool_lib/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/info_collect/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/hikp_init_main.c +diff --git a/libhikptdev/include/hikptdev_plug.h b/libhikptdev/include/hikptdev_plug.h +index 375fb89..bb58496 100644 +--- a/libhikptdev/include/hikptdev_plug.h ++++ b/libhikptdev/include/hikptdev_plug.h +@@ -45,7 +45,8 @@ enum cmd_module_type { + CXL_MOD = 10, + UB_MOD = 11, + HCCS_MOD = 16, +- SDMA_MOD = 17 ++ SDMA_MOD = 17, ++ RAS_MOD = 19 + }; + + void hikp_unlock(void); +diff --git a/ras/ras_func/ras_common.h b/ras/ras_func/ras_common.h +new file mode 100644 +index 0000000..9b9a486 +--- /dev/null ++++ b/ras/ras_func/ras_common.h +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (c) 2025 Hisilicon Technologies Co., Ltd. ++ * Hikptool is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef RAS_COMMON_H ++#define RAS_COMMON_H ++ ++enum { ++ RAS_DUMP, ++}; ++ ++enum ras_dump_cmd_type { ++ DUMP_DFX = 0, ++ DUMP_CLEAR, ++}; ++ ++#endif /* RAS_COMMON_H */ +diff --git a/ras/ras_func/ras_dump_data.c b/ras/ras_func/ras_dump_data.c +new file mode 100644 +index 0000000..6230a48 +--- /dev/null ++++ b/ras/ras_func/ras_dump_data.c +@@ -0,0 +1,389 @@ ++/* ++ * Copyright (c) 2025 Hisilicon Technologies Co., Ltd. ++ * Hikptool is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * ++ * See the Mulan PSL v2 for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "hikptdev_plug.h" ++#include "op_logs.h" ++#include "ras_common.h" ++#include "ras_dump_data.h" ++ ++static struct dfx_reg_dump_header header; ++ ++static int ras_get_data(uint32_t ras_cmd_type, struct ras_dump_req_para *req_data, ++ struct ras_rsp *ras_rsp_data) ++{ ++ uint32_t i; ++ struct hikp_cmd_ret *cmd_ret; ++ struct hikp_cmd_header req_header; ++ ++ hikp_cmd_init(&req_header, RAS_MOD, RAS_DUMP, ras_cmd_type); ++ cmd_ret = hikp_cmd_alloc(&req_header, req_data, RAS_REQ_DATA_LEN); ++ if (cmd_ret == NULL || cmd_ret->status != 0 || ++ cmd_ret->rsp_data_num > HIKP_RSP_ALL_DATA_MAX) { ++ printf("hikp_data_proc err\n"); ++ hikp_cmd_free(&cmd_ret); ++ return -1; ++ } ++ ++ ras_rsp_data->rsp_data_num = cmd_ret->rsp_data_num; ++ for (i = 0; i < ras_rsp_data->rsp_data_num; i++) { ++ ras_rsp_data->rsp_data[i] = cmd_ret->rsp_data[i]; ++ } ++ ++ hikp_cmd_free(&cmd_ret); ++ return 0; ++} ++ ++static void ras_print_time(struct file_seq *s) ++{ ++ time_t time_seconds = time(0); ++ struct tm timeinfo; ++ ++ (void)localtime_r(&time_seconds, &timeinfo); ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, "Time: %d-%d-%d %d:%d:%d\n", ++ timeinfo.tm_year + START_YEAR, timeinfo.tm_mon + 1, timeinfo.tm_mday, ++ timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); ++} ++ ++static int ras_parse_data(uint32_t *reg_save, uint32_t reg_num, uint32_t reg_off, struct file_seq *s) ++{ ++ uint32_t i, j; ++ uint32_t cycle; ++ uint32_t reg_count, pkt_reg_num; ++ uint32_t off = reg_off; ++ ++ pkt_reg_num = header.pkt_length / sizeof(uint32_t); ++ cycle = reg_num / pkt_reg_num; ++ if (!cycle) ++ return -1; ++ ++ for (i = 0; i < cycle; i++) { ++ if ((off + pkt_reg_num) > HIKP_RSP_ALL_DATA_MAX) { ++ HIKP_ERROR_PRINT("off is %u, pkt_reg_num is %u,\ ++ reg_save index will exceed max reg_save length\n", ++ off, pkt_reg_num); ++ return -1; ++ } ++ ++ ras_print_time(s); ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, "Socket: 0X%hhX\t", ++ (reg_save[off + DFX_HEAD_INFO_DW0] >> DFX_HEAD_SKT_ID_OFF) & 0xff); ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, "DIE: 0X%hhX\t", ++ (reg_save[off + DFX_HEAD_INFO_DW0] >> DFX_HEAD_DIE_ID_OFF) & 0xff); ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, "Module: 0X%hhX\t", ++ (reg_save[off + DFX_HEAD_INFO_DW1] >> DFX_HEAD_MODULE_ID_OFF) & 0xff); ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, "Sub Module: 0X%hhX\t", ++ (reg_save[off + DFX_HEAD_INFO_DW1] >> DFX_HEAD_SUBMODULE_ID_OFF) & 0xff); ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, "SequenceNum: 0X%hhX\t", ++ (reg_save[off + DFX_HEAD_INFO_DW1] >> DFX_HEAD_SEQUENCE_NUM_OFF) & 0xff); ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, "Version: 0X%hhX\n", ++ (reg_save[off + DFX_HEAD_INFO_DW0] >> DFX_HEAD_VERSION_OFF) & 0xff); ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, ++ "----------------------- DFX REGISTER DUMP -----------------------\n"); ++ ++ reg_count = (reg_save[off + DFX_HEAD_INFO_DW1] >> DFX_HEAD_REG_COUNT_OFF) & 0xff; ++ if (!reg_count || reg_count > pkt_reg_num - DFX_REG_PACKET_HEAD_LEN) { ++ HIKP_ERROR_PRINT("reg_count is %u, value is not within the reasonable range(1-%u).\n", ++ reg_count, pkt_reg_num - DFX_REG_PACKET_HEAD_LEN); ++ return -1; ++ } ++ ++ for (j = 0; j < reg_count; j++) ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, "0X%X\n", ++ reg_save[off + DFX_COMMON_MAIN_TEXT_BEGIN + j]); ++ ++ s->len += snprintf(s->buffer + s->len, s->buffer_size - s->len, "\n"); ++ off += pkt_reg_num; ++ } ++ ++ return 0; ++} ++ ++static int ras_generate_file_name(struct file_seq *s) ++{ ++ time_t time_seconds = time(0); ++ struct tm timeinfo; ++ int ret; ++ ++ (void)localtime_r(&time_seconds, &timeinfo); ++ ret = snprintf(s->file_name, MAX_LOG_NAME_LEN, "rasdfx_%d_%d_%d_%d_%d_%d.log", ++ timeinfo.tm_year + START_YEAR, timeinfo.tm_mon + 1, timeinfo.tm_mday, ++ timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); ++ if (ret < 0 || (uint32_t)ret >= MAX_LOG_NAME_LEN) { ++ HIKP_ERROR_PRINT("generate file name failed, errno is %d\n", errno); ++ return -errno; ++ } ++ ++ return 0; ++} ++ ++static int ras_store_data(struct file_seq *s) ++{ ++ char file_path[OP_LOG_FILE_PATH_MAXLEN]; ++ size_t write_cnt; ++ FILE *fp; ++ int rc; ++ ++ rc = snprintf(file_path, sizeof(file_path), HIKP_LOG_DIR_PATH"%s", s->file_name); ++ if (rc < 0) { ++ HIKP_ERROR_PRINT("creat log file path fail.\n"); ++ return -EIO; ++ } ++ ++ fp = fopen(file_path, "a"); ++ if (fp == NULL) { ++ HIKP_ERROR_PRINT("open %s failed, errno is %d\n", file_path, errno); ++ return -errno; ++ } ++ ++ write_cnt = fwrite(s->buffer, 1, s->len, fp); ++ if (write_cnt != (uint32_t)s->len) { ++ fclose(fp); ++ HIKP_ERROR_PRINT("write %s failed, write cnt %zu.\n", file_path, write_cnt); ++ return -EAGAIN; ++ } ++ ++ printf("dump imp log completed, log file: %s.\n", file_path); ++ /* Set the file permission to 0440 */ ++ if (chmod(file_path, 0440)) ++ HIKP_ERROR_PRINT("chmod %s failed, errno is %d\n", file_path, errno); ++ ++ if (fclose(fp)) { ++ HIKP_ERROR_PRINT("close %s failed, errno is %d\n", file_path, errno); ++ return -errno; ++ } ++ ++ s->len = 0; ++ ++ return 0; ++} ++ ++static int file_seq_init(struct file_seq *s, uint32_t size) ++{ ++ if (!size) ++ return -1; ++ ++ s->buffer_size = size; ++ s->len = 0; ++ s->buffer = (char*)malloc(s->buffer_size); ++ if (!s->buffer) ++ return -1; ++ ++ return 0; ++} ++ ++static void file_seq_destroy(struct file_seq *s) ++{ ++ free(s->buffer); ++ s->buffer = NULL; ++} ++ ++static void ras_rsp_init(struct ras_rsp *ras_rsp_data) ++{ ++ ras_rsp_data->first_pkt_begin = 0; ++ ras_rsp_data->last_pkt_end = 0; ++ ras_rsp_data->rsp_data_num = 0; ++ ras_rsp_data->packet_buffer_len = 0; ++ ++ memset(ras_rsp_data->rsp_data, 0, sizeof(ras_rsp_data->rsp_data)); ++ memset(ras_rsp_data->packet_buffer, 0, sizeof(ras_rsp_data->packet_buffer)); ++} ++ ++static int parse_packet_buffer_data(struct ras_rsp *ras_rsp_data, ++ uint32_t pkt_reg_num, struct file_seq *s) ++{ ++ int ret; ++ ++ if (pkt_reg_num > MAX_DFX_PACKET_LEN) { ++ HIKP_ERROR_PRINT("pkt_reg_num is %u, has exceeded max packet length\n", pkt_reg_num); ++ return -1; ++ } ++ ++ if (ras_rsp_data->packet_buffer_len) { ++ uint32_t rest_pkt_length; ++ ++ rest_pkt_length = pkt_reg_num - ras_rsp_data->packet_buffer_len; ++ memcpy(ras_rsp_data->packet_buffer + ras_rsp_data->packet_buffer_len, ++ ras_rsp_data->rsp_data, rest_pkt_length); ++ ++ ras_rsp_data->first_pkt_begin = rest_pkt_length; ++ ret = ras_parse_data(ras_rsp_data->packet_buffer, pkt_reg_num, 0, s); ++ if (ret) { ++ HIKP_ERROR_PRINT("ras parse packet_buffer_data is failed\n"); ++ return ret; ++ } ++ } else { ++ ras_rsp_data->first_pkt_begin = 0; ++ } ++ ++ if (ras_rsp_data->first_pkt_begin == ras_rsp_data->rsp_data_num) ++ return 0; ++ ++ ras_rsp_data->packet_buffer_len = ++ (ras_rsp_data->rsp_data_num - ras_rsp_data->first_pkt_begin) % pkt_reg_num; ++ ras_rsp_data->last_pkt_end = ras_rsp_data->rsp_data_num - ras_rsp_data->packet_buffer_len - 1; ++ ras_rsp_data->rsp_data_num = ras_rsp_data->last_pkt_end - ras_rsp_data->first_pkt_begin + 1; ++ ++ memcpy(ras_rsp_data->packet_buffer, ras_rsp_data->rsp_data + ras_rsp_data->last_pkt_end + 1, ++ ras_rsp_data->packet_buffer_len); ++ ++ return 0; ++} ++ ++static int ras_dump_pkt_pre(struct ras_rsp *ras_rsp_data, struct file_seq *s) ++{ ++ int ret; ++ uint32_t reg_num, max_pkt_num, s_buffer_size; ++ ++ max_pkt_num = (HIKP_RSP_DATA_SIZE_MAX / header.pkt_length) + 1; ++ reg_num = header.pkt_length / sizeof(uint32_t) - DFX_REG_PACKET_HEAD_LEN; ++ s_buffer_size = max_pkt_num * ++ (reg_num * DFX_FILE_SINGLE_REG_SIZE + DFX_FILE_SINGLE_PACKET_HEAD_SIZE); ++ ras_rsp_data->rsp_data_num = 0; ++ ++ ret = file_seq_init(s, s_buffer_size); ++ if (ret) { ++ HIKP_ERROR_PRINT("malloc file_seq buffer is failed\n"); ++ return ret; ++ } ++ ++ ret = ras_generate_file_name(s); ++ if (ret) { ++ HIKP_ERROR_PRINT("ras generate file name is failed\n"); ++ file_seq_destroy(s); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static int ras_dump_packet(struct tool_ras_cmd *cmd, struct ras_rsp *ras_rsp_data, ++ struct ras_dump_req_para *req_data) ++{ ++ int ret; ++ uint32_t i, cmd_num; ++ bool has_printed_socid = false; ++ struct file_seq s; ++ ++ ret = ras_dump_pkt_pre(ras_rsp_data, &s); ++ if (ret) ++ return ret; ++ ++ cmd_num = (header.pkt_num * header.pkt_length + ++ HIKP_RSP_DATA_SIZE_MAX - 1) / HIKP_RSP_DATA_SIZE_MAX; ++ /* 0: get header info; 1-n: get packet data */ ++ for (i = 0; i < cmd_num; i++) { ++ req_data->cmd_id = i + 1; ++ ret = ras_get_data(cmd->ras_cmd_type, req_data, ras_rsp_data); ++ if (ret) { ++ HIKP_ERROR_PRINT("ras dump cmd %u is failed\n", req_data->cmd_id); ++ goto err_out_free; ++ } ++ ++ if (!has_printed_socid) { ++ s.len += snprintf(s.buffer + s.len, s.buffer_size - s.len, "SocID: %hhX\n", ++ (ras_rsp_data->rsp_data[DFX_HEAD_INFO_DW0] >> DFX_HEAD_SOC_ID_OFF) & 0xff); ++ s.len += snprintf(s.buffer + s.len, s.buffer_size - s.len, "\n"); ++ ++ has_printed_socid = true; ++ } ++ ++ ret = parse_packet_buffer_data(ras_rsp_data, header.pkt_length / sizeof(uint32_t), &s); ++ if (ret) { ++ HIKP_ERROR_PRINT("ras parse packet buffer data is failed\n"); ++ goto err_out_free; ++ } ++ ++ if (ras_rsp_data->first_pkt_begin != ras_rsp_data->rsp_data_num) { ++ ret = ras_parse_data(ras_rsp_data->rsp_data, ras_rsp_data->rsp_data_num, ++ ras_rsp_data->first_pkt_begin, &s); ++ if (ret) { ++ HIKP_ERROR_PRINT("ras parse rsp_data is failed\n"); ++ goto err_out_free; ++ } ++ } ++ ++ ret = ras_store_data(&s); ++ if (ret) { ++ HIKP_ERROR_PRINT("ras store rsp_data is failed\n"); ++ goto err_out_free; ++ } ++ } ++ ++err_out_free: ++ file_seq_destroy(&s); ++ return ret; ++} ++ ++int ras_data_dump(struct tool_ras_cmd *cmd) ++{ ++ int ret; ++ struct ras_rsp ras_rsp_data; ++ struct ras_dump_req_para req_data = {0}; ++ ++ if (cmd == NULL) ++ return -ENOSPC; ++ ++ ras_rsp_init(&ras_rsp_data); ++ ret = ras_get_data(cmd->ras_cmd_type, &req_data, &ras_rsp_data); ++ if (ret || (ras_rsp_data.rsp_data_num != DFX_REG_DUMP_HEADER_LEN)) { ++ HIKP_ERROR_PRINT("ras dump header is failed, rsp_data_num is %u\n", ++ ras_rsp_data.rsp_data_num); ++ return -1; ++ } ++ ++ if (!ras_rsp_data.rsp_data[HEAD_MAGIC]) { ++ HIKP_ERROR_PRINT("ras dfx dump is failed, data does not exist or has been cleared.\n"); ++ return -1; ++ } ++ ++ header.pkt_num = ras_rsp_data.rsp_data[PKT_NUM]; ++ header.pkt_length = ras_rsp_data.rsp_data[PKT_LENGTH]; ++ if (header.pkt_num == 0 || header.pkt_length < DFX_REG_PACKET_HEAD_LEN) { ++ HIKP_ERROR_PRINT("ras dfx dump is failed, pkt_num is %u, pkt_length is %u\n", ++ header.pkt_num, header.pkt_length); ++ return -1; ++ } ++ ++ ret = ras_dump_packet(cmd, &ras_rsp_data, &req_data); ++ if (ret) ++ HIKP_ERROR_PRINT("ras dump packet is failed\n"); ++ ++ return ret; ++} ++ ++int ras_data_clear(struct tool_ras_cmd *cmd) ++{ ++ int ret; ++ struct ras_rsp ras_rsp_data; ++ struct ras_dump_req_para req_data = { 0 }; ++ ++ if (cmd == NULL) ++ return -ENOSPC; ++ ++ ras_rsp_init(&ras_rsp_data); ++ ret = ras_get_data(cmd->ras_cmd_type, &req_data, &ras_rsp_data); ++ if (ret || ras_rsp_data.rsp_data_num != DFX_REG_DUMP_HEADER_LEN || ++ ras_rsp_data.rsp_data[HEAD_MAGIC] != DFX_DATA_IS_CLEARED) { ++ HIKP_ERROR_PRINT("ras dfx data clear is failed\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ +diff --git a/ras/ras_func/ras_dump_data.h b/ras/ras_func/ras_dump_data.h +new file mode 100644 +index 0000000..9b326b3 +--- /dev/null ++++ b/ras/ras_func/ras_dump_data.h +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (c) 2025 Hisilicon Technologies Co., Ltd. ++ * Hikptool is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef RAS_DUMP_REG_H ++#define RAS_DUMP_REG_H ++ ++#include "ras_tools_include.h" ++#include "hikpt_rciep.h" ++#include "tool_lib.h" ++ ++#define RAS_FILE_HEAD_BUF_LEN 256 ++#define MAX_DFX_PACKET_LEN 256 ++#define RAS_REQ_DATA_LEN 4 ++#define DFX_REG_DUMP_HEADER_LEN 6 ++#define DFX_REG_PACKET_HEAD_LEN 3 ++ ++struct dfx_reg_dump_header { ++ uint32_t head_magic; // 文件头的magic数字,特定值表示有效记录。 ++ uint32_t version; // 存储格式版本 ++ uint32_t cap_bits; // bit0表示是否开启crc,其余bit保留。 ++ uint32_t pkt_num; // packet数量 ++ uint32_t pkt_length; // 单个packet占用内存空间,单位bytes ++ uint32_t reserved; ++}; ++ ++struct file_seq { ++ char *buffer; ++ uint32_t buffer_size; ++ int len; ++ char file_name[MAX_LOG_NAME_LEN]; ++}; ++ ++struct ras_rsp { ++ uint32_t rsp_data[HIKP_RSP_ALL_DATA_MAX]; ++ uint32_t first_pkt_begin; ++ uint32_t last_pkt_end; ++ uint32_t rsp_data_num; ++ uint32_t packet_buffer[MAX_DFX_PACKET_LEN]; ++ uint32_t packet_buffer_len; ++}; ++ ++struct ras_dump_req_para { ++ uint32_t cmd_id; ++}; ++ ++enum reg_dump_header_index { ++ HEAD_MAGIC, ++ VERSION, ++ CAP_BITS, ++ PKT_NUM, ++ PKT_LENGTH ++}; ++ ++enum dfx_packet_index { ++ DFX_HEAD_INFO_DW0, ++ DFX_HEAD_INFO_DW1, ++ DFX_COMMON_MAIN_TEXT_BEGIN = 3 ++}; ++ ++#define DFX_HEAD_VERSION_OFF 0 ++#define DFX_HEAD_SOC_ID_OFF 8 ++#define DFX_HEAD_SKT_ID_OFF 16 ++#define DFX_HEAD_DIE_ID_OFF 24 ++#define DFX_HEAD_MODULE_ID_OFF 0 ++#define DFX_HEAD_SUBMODULE_ID_OFF 8 ++#define DFX_HEAD_SEQUENCE_NUM_OFF 16 ++#define DFX_HEAD_REG_COUNT_OFF 24 ++ ++#define DFX_DATA_IS_CLEARED 0 ++ ++#define DFX_FILE_SINGLE_PACKET_HEAD_SIZE 256 ++#define DFX_FILE_SINGLE_REG_SIZE 10 ++ ++ ++int ras_data_dump(struct tool_ras_cmd *cmd); ++int ras_data_clear(struct tool_ras_cmd *cmd); ++ ++#endif /* RAS_DUMP_REG_H */ +diff --git a/ras/user_cmd/ras_cmd_dump.c b/ras/user_cmd/ras_cmd_dump.c +new file mode 100644 +index 0000000..f8ae828 +--- /dev/null ++++ b/ras/user_cmd/ras_cmd_dump.c +@@ -0,0 +1,99 @@ ++/* ++ * Copyright (c) 2025 Hisilicon Technologies Co., Ltd. ++ * Hikptool is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#include ++#include "tool_cmd.h" ++#include "ras_tools_include.h" ++#include "ras_dump_data.h" ++ ++struct tool_ras_cmd g_ras_dump_cmd = { ++ .ras_cmd_type = DUMP_DFX, ++}; ++ ++static int ras_dump_help(struct major_cmd_ctrl *self, const char *argv) ++{ ++ HIKP_SET_USED(argv); ++ ++ printf("\n Usage: %s\n", self->cmd_ptr->name); ++ printf("\n %s\n", self->cmd_ptr->help_info); ++ printf("\n Options:\n\n"); ++ printf(" %s, %-25s %s\n", "-h", "--help", "display this help and exit\n"); ++ printf(" %s, %-25s %s\n", "-c", "--clear", "clearing memory dfx data\n"); ++ printf("\n"); ++ ++ return 0; ++} ++ ++static enum ras_dump_cmd_type ras_get_cmd_type(void) ++{ ++ return g_ras_dump_cmd.ras_cmd_type; ++} ++ ++static void ras_set_cmd_type(enum ras_dump_cmd_type type) ++{ ++ g_ras_dump_cmd.ras_cmd_type = type; ++} ++ ++static int ras_set_clear(struct major_cmd_ctrl *self, const char *argv) ++{ ++ HIKP_SET_USED(self); ++ HIKP_SET_USED(argv); ++ ++ ras_set_cmd_type(DUMP_CLEAR); ++ return 0; ++} ++ ++static int ras_dump_execute_process(void) ++{ ++ if (ras_get_cmd_type() == DUMP_DFX) ++ return ras_data_dump(&g_ras_dump_cmd); ++ else if (ras_get_cmd_type() == DUMP_CLEAR) ++ return ras_data_clear(&g_ras_dump_cmd); ++ else ++ return -EINVAL; ++} ++ ++static void ras_dump_execute(struct major_cmd_ctrl *self) ++{ ++ int ret; ++ const char *suc_msg[] = { ++ "ras dfx data dump success.", ++ "ras dfx data clear success." ++ }; ++ const char *err_msg[] = { ++ "ras dfx data dump error.", ++ "ras dfx data clear error." ++ }; ++ ++ ret = ras_dump_execute_process(); ++ if (ret == 0) { ++ printf("%s\n", suc_msg[ras_get_cmd_type()]); ++ } else { ++ snprintf(self->err_str, sizeof(self->err_str), "%s\n", ++ err_msg[ras_get_cmd_type()]); ++ self->err_no = ret; ++ } ++} ++ ++static void cmd_ras_dump_init(void) ++{ ++ struct major_cmd_ctrl *major_cmd = get_major_cmd(); ++ ++ major_cmd->option_count = 0; ++ major_cmd->execute = ras_dump_execute; ++ ++ cmd_option_register("-c", "--clear", false, ras_set_clear); ++ cmd_option_register("-h", "--help", false, ras_dump_help); ++} ++ ++HIKP_CMD_DECLARE("bbox_export", "export black box data to file", cmd_ras_dump_init); +diff --git a/ras/user_cmd/ras_tools_include.h b/ras/user_cmd/ras_tools_include.h +new file mode 100644 +index 0000000..a999b8a +--- /dev/null ++++ b/ras/user_cmd/ras_tools_include.h +@@ -0,0 +1,25 @@ ++/* ++ * Copyright (c) 2025 Hisilicon Technologies Co., Ltd. ++ * Hikptool is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * ++ * See the Mulan PSL v2 for more details. ++ */ ++ ++#ifndef RAS_TOOLS_INCLUDE_H ++#define RAS_TOOLS_INCLUDE_H ++ ++#include "hikptdev_plug.h" ++#include "tool_lib.h" ++#include "ras_common.h" ++ ++struct tool_ras_cmd { ++ enum ras_dump_cmd_type ras_cmd_type; ++}; ++ ++#endif /* RAS_TOOLS_INCLUDE_H */ +-- +2.33.0 + diff --git a/hikptool.spec b/hikptool.spec index bf86034..ecdf999 100644 --- a/hikptool.spec +++ b/hikptool.spec @@ -3,7 +3,7 @@ Name: hikptool Summary: A userspace tool for Linux providing problem location on Kunpeng chips Version: 1.0.0 -Release: 17 +Release: 18 License: MulanPSL2 Source: %{name}-%{version}.tar.gz ExclusiveOS: linux @@ -114,6 +114,7 @@ Patch0095: 0095-hikptool-pcie-Resolved-the-problem-that-it-takes-a-l.patch Patch0096: 0096-Hikptool-add-support-dump-SDMA-register-information-.patch Patch0097: 0097-Add-support-collect-sdma-hikptool-dump-reg-info.patch Patch0098: 0098-hikptool-Update-the-tool-version-number-to-1.1.4.patch +Patch0099: 0099-hikptool-ras-Add-support-for-exporting-black-box-dat.patch %description This package contains the hikptool @@ -166,6 +167,9 @@ fi /sbin/ldconfig %changelog +* Fri Apr 18 2025 Bing Xia 1.0.0-18 +- hikptool: ras: Add support for exporting black box data to file. + * Tue Mar 18 2025 veega2022 1.0.0-17 - The HCCS and SDMA modules and the log collection function are added -- Gitee