343 lines
11 KiB
Diff
343 lines
11 KiB
Diff
|
|
From c28cf6381c20a707a2898503677facf304896752 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Bingquan Mou <moubingquan@huawei.com>
|
||
|
|
Date: Wed, 28 Jun 2023 11:13:03 +0800
|
||
|
|
Subject: [PATCH] hikptool: the PM trace function is added to the PCIe module.
|
||
|
|
|
||
|
|
The pm trace function of the PCIe module is added to improve the DFX.
|
||
|
|
|
||
|
|
Signed-off-by: Bingquan Mou <moubingquan@huawei.com>
|
||
|
|
---
|
||
|
|
pcie/func_lib/pcie_func/pcie_common.h | 1 +
|
||
|
|
pcie/func_lib/pcie_func/pcie_link_ltssm.c | 180 +++++++++++++++++++++
|
||
|
|
pcie/func_lib/pcie_func/pcie_link_ltssm.h | 7 +
|
||
|
|
pcie/usr_cmd/cmd_analysis/pcie_cmd_trace.c | 17 +-
|
||
|
|
pcie/usr_cmd/interface/pcie_common_api.c | 1 +
|
||
|
|
pcie/usr_cmd/interface/pcie_common_api.h | 1 +
|
||
|
|
6 files changed, 205 insertions(+), 2 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/pcie/func_lib/pcie_func/pcie_common.h b/pcie/func_lib/pcie_func/pcie_common.h
|
||
|
|
index 434b4ed..98d9e25 100644
|
||
|
|
--- a/pcie/func_lib/pcie_func/pcie_common.h
|
||
|
|
+++ b/pcie/func_lib/pcie_func/pcie_common.h
|
||
|
|
@@ -28,6 +28,7 @@ enum pcie_trace_cmd_type {
|
||
|
|
TRACE_CLEAR = 2,
|
||
|
|
TRACE_INFO = 3,
|
||
|
|
TRACE_MODE = 4,
|
||
|
|
+ TRACE_PM = 5,
|
||
|
|
};
|
||
|
|
|
||
|
|
enum pcie_info_cmd_type {
|
||
|
|
diff --git a/pcie/func_lib/pcie_func/pcie_link_ltssm.c b/pcie/func_lib/pcie_func/pcie_link_ltssm.c
|
||
|
|
index d57688b..9c4b70c 100644
|
||
|
|
--- a/pcie/func_lib/pcie_func/pcie_link_ltssm.c
|
||
|
|
+++ b/pcie/func_lib/pcie_func/pcie_link_ltssm.c
|
||
|
|
@@ -43,6 +43,31 @@ union ltssm_state_reg {
|
||
|
|
uint64_t val;
|
||
|
|
};
|
||
|
|
|
||
|
|
+union pm_state_reg {
|
||
|
|
+ struct {
|
||
|
|
+ uint64_t pm_state : 6; /* [0:5] */
|
||
|
|
+ uint64_t pm_clock : 18; /* [6:23] */
|
||
|
|
+ uint64_t reserved1 : 8; /* [24:31] */
|
||
|
|
+ uint64_t refclk_stable_vld : 1; /* [32] */
|
||
|
|
+ uint64_t enter_l12_case : 1; /* [33] */
|
||
|
|
+ uint64_t pm_t_dl_l2_gnt_timeout : 1; /* [34] */
|
||
|
|
+ uint64_t pm_t_dl_l1_gnt_timeout : 1; /* [35] */
|
||
|
|
+ uint64_t pm_t_dl_l0s_gnt_timeout : 1; /* [36] */
|
||
|
|
+ uint64_t pm_t_dl_lastack_timeout : 1; /* [37] */
|
||
|
|
+ uint64_t pme_turn_off_vld_hold : 1; /* [38] */
|
||
|
|
+ uint64_t pm_blk_tlp_timeout : 1; /* [39] */
|
||
|
|
+ uint64_t aspm_nak_vld : 1; /* [40] */
|
||
|
|
+ uint64_t retrain_link_vld : 1; /* [41] */
|
||
|
|
+ uint64_t pending_dllp_vld : 1; /* [42] */
|
||
|
|
+ uint64_t pm_wakeup_tol0_en : 1; /* [43] */
|
||
|
|
+ uint64_t mac2pm_rx_data_vld : 1; /* [44] */
|
||
|
|
+ uint64_t dfe_req : 1; /* [45] */
|
||
|
|
+ uint64_t pm_t_dfe_time_meet : 1; /* [46] */
|
||
|
|
+ uint64_t reserved2 : 17; /* [47:63] */
|
||
|
|
+ } bits;
|
||
|
|
+ uint64_t val;
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
static int pcie_get_ltssm_trace(uint32_t port_id, uint64_t *ltssm_status, uint32_t *ltssm_num)
|
||
|
|
{
|
||
|
|
struct hikp_cmd_header req_header;
|
||
|
|
@@ -280,3 +305,158 @@ free_cmd_ret:
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+static int pcie_get_pm_trace(uint32_t port_id, uint64_t *pm_status, uint32_t *pm_num)
|
||
|
|
+{
|
||
|
|
+ struct hikp_cmd_header req_header;
|
||
|
|
+ struct hikp_cmd_ret *cmd_ret = NULL;
|
||
|
|
+ struct pcie_trace_req_para req_data = { 0 };
|
||
|
|
+ size_t src_size, dst_size;
|
||
|
|
+ int ret;
|
||
|
|
+
|
||
|
|
+ req_data.port_id = port_id;
|
||
|
|
+ hikp_cmd_init(&req_header, PCIE_MOD, PCIE_TRACE, TRACE_PM);
|
||
|
|
+ cmd_ret = hikp_cmd_alloc(&req_header, &req_data, sizeof(req_data));
|
||
|
|
+ ret = hikp_rsp_normal_check(cmd_ret);
|
||
|
|
+ if (ret) {
|
||
|
|
+ Err("PCIe Base", "pcie pm trace cmd_ret check failed, ret: %d.\n", ret);
|
||
|
|
+ goto free_cmd_ret;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (cmd_ret->rsp_data_num == 0) {
|
||
|
|
+ Err("PCIe Base", "without rsp data.\n");
|
||
|
|
+ ret = -EINVAL;
|
||
|
|
+ goto free_cmd_ret;
|
||
|
|
+ }
|
||
|
|
+ /* 0: First uint32_t is pm trace num received from TF */
|
||
|
|
+ *pm_num = cmd_ret->rsp_data[0];
|
||
|
|
+
|
||
|
|
+ if ((cmd_ret->rsp_data_num - 1) * sizeof(uint32_t) != (*pm_num) * sizeof(uint64_t)) {
|
||
|
|
+ Err("PCIe Base", "rsp data number check failed, rsp_data_num: %u, pm_num: %u.\n",
|
||
|
|
+ cmd_ret->rsp_data_num, *pm_num);
|
||
|
|
+ ret = -EINVAL;
|
||
|
|
+ goto free_cmd_ret;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ src_size = (*pm_num) * sizeof(uint64_t);
|
||
|
|
+ dst_size = TRACER_DEPTH * sizeof(uint64_t);
|
||
|
|
+ if (src_size > dst_size) {
|
||
|
|
+ Err("PCIe Base", "size check failed, %u > %u.\n", src_size, dst_size);
|
||
|
|
+ ret = -EINVAL;
|
||
|
|
+ goto free_cmd_ret;
|
||
|
|
+ }
|
||
|
|
+ memcpy(pm_status, (cmd_ret->rsp_data + 1), src_size);
|
||
|
|
+
|
||
|
|
+free_cmd_ret:
|
||
|
|
+ free(cmd_ret);
|
||
|
|
+ return ret;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+struct pcie_pm_num_string g_pm_string_table[] = {
|
||
|
|
+ {0x0, "pm_pme_idle"},
|
||
|
|
+ {0x1, "pm_wait_dc_pme_msg_send_out"},
|
||
|
|
+ {0x2, "pm_wait_dc_tl_enter_l2"},
|
||
|
|
+ {0x3, "pm_wait_dc_dl_enter_l2"},
|
||
|
|
+ {0x4, "pm_wait_dc_mac_enter_l2"},
|
||
|
|
+ {0x5, "pm_dc_enter_l2"},
|
||
|
|
+ {0x6, "pm_wait_dc_tl_enter_pcipm_l1"},
|
||
|
|
+ {0x7, "pm_wait_dc_dl_enter_pcipm_l1"},
|
||
|
|
+ {0x8, "pm_wait_dc_tl_enter_aspm_l1"},
|
||
|
|
+ {0x9, "pm_wait_dc_dl_enter_aspm_l1"},
|
||
|
|
+ {0xa, "pm_wait_tl_enter_aspm_l0"},
|
||
|
|
+ {0xb, "pm_wait_dl_enter_aspm_l0"},
|
||
|
|
+ {0xc, "pm_wait_dc_mac_enter_l1"},
|
||
|
|
+ {0xd, "pm_wait_mac_enter_l0s"},
|
||
|
|
+ {0xe, "pm_device_in_l0s"},
|
||
|
|
+ {0xf, "pm_dc_device_in_l1"},
|
||
|
|
+ {0x10, "pm_wait_dc_enter_l0"},
|
||
|
|
+ {0x11, "pm_wait_uc_tl_enter_l2"},
|
||
|
|
+ {0x12, "pm_wait_uc_dl_enter_l2"},
|
||
|
|
+ {0x13, "pm_wait_uc_mac_enter_l2"},
|
||
|
|
+ {0x15, "pm_wait_uc_tl_enter_pcipm_l1"},
|
||
|
|
+ {0x17, "pm_wait_uc_dl_enter_aspm_l1"},
|
||
|
|
+ {0x18, "pm_wait_uc_tl_enter_aspm_l1"},
|
||
|
|
+ {0x1a, "pm_wait_uc_dl_enter_pcipm_l1"},
|
||
|
|
+ {0x1c, "pm_wait_uc_mac_enter_l1"},
|
||
|
|
+ {0x1d, "pm_wait_uc_pme_enter_l1_nak_sent_out"},
|
||
|
|
+ {0x1e, "pm_wait_uc_enter_l0"},
|
||
|
|
+ {0x20, "pm_device_will_enter_l1_substate"},
|
||
|
|
+ {0x21, "pm_device_in_l1_1"},
|
||
|
|
+ {0x22, "pm_device_will_exit_l1_substate"},
|
||
|
|
+ {0x23, "pm_device_in_l1_2_entry"},
|
||
|
|
+ {0x24, "pm_device_in_l1_2_idle"},
|
||
|
|
+ {0x25, "pm_device_in_l1_2_exit"},
|
||
|
|
+ {-1, "unknown"} /* end of array */
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static char *hisi_pcie_pm_string_get(uint32_t pm)
|
||
|
|
+{
|
||
|
|
+ int i = 0;
|
||
|
|
+
|
||
|
|
+ while (g_pm_string_table[i].pm >= 0) {
|
||
|
|
+ if ((uint32_t)g_pm_string_table[i].pm != pm) {
|
||
|
|
+ i++;
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return g_pm_string_table[i].pm_c;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static int pcie_print_pm_trace(const uint64_t *pm_status, uint32_t pm_num)
|
||
|
|
+{
|
||
|
|
+ uint32_t i;
|
||
|
|
+ char *pm_c = NULL;
|
||
|
|
+ union pm_state_reg pm_val;
|
||
|
|
+
|
||
|
|
+ if (pm_num > TRACER_DEPTH || pm_num == 0) {
|
||
|
|
+ Err("PCIe Base", "pm_num(%u) is over range or zero\n", pm_num);
|
||
|
|
+ return -EINVAL;
|
||
|
|
+ }
|
||
|
|
+ Info("PCIe Base", "pm tracer:\n");
|
||
|
|
+ Info("PCIe Base", "\ttrace state: %llx\n", pm_status[0]);
|
||
|
|
+ Info("PCIe Base",
|
||
|
|
+ "\tpm[ii]: BE8: 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 "
|
||
|
|
+ "BD8: 23:6 5:0 : pm state\n");
|
||
|
|
+ for (i = 1; i < pm_num; i++) {
|
||
|
|
+ pm_val.val = pm_status[i];
|
||
|
|
+ pm_c = hisi_pcie_pm_string_get((uint32_t)pm_val.bits.pm_state);
|
||
|
|
+ Info("PCIe Base",
|
||
|
|
+ "\tpm[%02u]:\t %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x 0x%06x 0x%02x %s\n",
|
||
|
|
+ i,
|
||
|
|
+ (uint32_t)pm_val.bits.pm_t_dfe_time_meet,
|
||
|
|
+ (uint32_t)pm_val.bits.dfe_req,
|
||
|
|
+ (uint32_t)pm_val.bits.mac2pm_rx_data_vld,
|
||
|
|
+ (uint32_t)pm_val.bits.pm_wakeup_tol0_en,
|
||
|
|
+ (uint32_t)pm_val.bits.pending_dllp_vld,
|
||
|
|
+ (uint32_t)pm_val.bits.retrain_link_vld,
|
||
|
|
+ (uint32_t)pm_val.bits.aspm_nak_vld,
|
||
|
|
+ (uint32_t)pm_val.bits.pm_blk_tlp_timeout,
|
||
|
|
+ (uint32_t)pm_val.bits.pme_turn_off_vld_hold,
|
||
|
|
+ (uint32_t)pm_val.bits.pm_t_dl_lastack_timeout,
|
||
|
|
+ (uint32_t)pm_val.bits.pm_t_dl_l0s_gnt_timeout,
|
||
|
|
+ (uint32_t)pm_val.bits.pm_t_dl_l1_gnt_timeout,
|
||
|
|
+ (uint32_t)pm_val.bits.pm_t_dl_l2_gnt_timeout,
|
||
|
|
+ (uint32_t)pm_val.bits.enter_l12_case,
|
||
|
|
+ (uint32_t)pm_val.bits.refclk_stable_vld,
|
||
|
|
+ (uint32_t)pm_val.bits.pm_clock,
|
||
|
|
+ (uint32_t)pm_val.bits.pm_state,
|
||
|
|
+ pm_c);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+int pcie_pm_trace(uint32_t port_id)
|
||
|
|
+{
|
||
|
|
+ int ret;
|
||
|
|
+ uint32_t pm_num = 0;
|
||
|
|
+ uint64_t pm_st_save[TRACER_DEPTH];
|
||
|
|
+
|
||
|
|
+ ret = pcie_get_pm_trace(port_id, pm_st_save, &pm_num);
|
||
|
|
+ if (ret)
|
||
|
|
+ return ret;
|
||
|
|
+
|
||
|
|
+ return pcie_print_pm_trace(pm_st_save, pm_num);
|
||
|
|
+}
|
||
|
|
\ No newline at end of file
|
||
|
|
diff --git a/pcie/func_lib/pcie_func/pcie_link_ltssm.h b/pcie/func_lib/pcie_func/pcie_link_ltssm.h
|
||
|
|
index eb57ead..8f3502b 100644
|
||
|
|
--- a/pcie/func_lib/pcie_func/pcie_link_ltssm.h
|
||
|
|
+++ b/pcie/func_lib/pcie_func/pcie_link_ltssm.h
|
||
|
|
@@ -18,12 +18,18 @@
|
||
|
|
|
||
|
|
#define TRACE_STR_NUM 0x20
|
||
|
|
#define TRACER_DEPTH 65
|
||
|
|
+#define PM_TRACE_STR_NUM 0x28
|
||
|
|
|
||
|
|
struct pcie_ltssm_num_string {
|
||
|
|
int ltssm;
|
||
|
|
char ltssm_c[TRACE_STR_NUM];
|
||
|
|
};
|
||
|
|
|
||
|
|
+struct pcie_pm_num_string {
|
||
|
|
+ int pm;
|
||
|
|
+ char pm_c[PM_TRACE_STR_NUM];
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
struct pcie_trace_req_para {
|
||
|
|
uint32_t port_id;
|
||
|
|
uint32_t trace_mode;
|
||
|
|
@@ -51,5 +57,6 @@ int pcie_ltssm_trace_show(uint32_t port_id);
|
||
|
|
int pcie_ltssm_trace_clear(uint32_t port_id);
|
||
|
|
int pcie_ltssm_trace_mode_set(uint32_t port_id, uint32_t mode);
|
||
|
|
int pcie_ltssm_link_status_get(uint32_t port_id);
|
||
|
|
+int pcie_pm_trace(uint32_t port_id);
|
||
|
|
|
||
|
|
#endif
|
||
|
|
diff --git a/pcie/usr_cmd/cmd_analysis/pcie_cmd_trace.c b/pcie/usr_cmd/cmd_analysis/pcie_cmd_trace.c
|
||
|
|
index e50b434..8ceb85a 100644
|
||
|
|
--- a/pcie/usr_cmd/cmd_analysis/pcie_cmd_trace.c
|
||
|
|
+++ b/pcie/usr_cmd/cmd_analysis/pcie_cmd_trace.c
|
||
|
|
@@ -37,6 +37,7 @@ static int pcie_trace_help(struct major_cmd_ctrl *self, const char *argv)
|
||
|
|
printf(" %s, %-25s %s\n", "-m", "--mode",
|
||
|
|
"set ltssm trace mode val 1:recver_en 0:recver_dis\n");
|
||
|
|
printf(" %s, %-25s %s\n", "-f", "--information", "display link information\n");
|
||
|
|
+ printf(" %s, %-25s %s\n", "-pm", "--pm-state", "show pm status\n");
|
||
|
|
printf("\n");
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
@@ -57,6 +58,13 @@ static int pcie_trace_show(struct major_cmd_ctrl *self, const char *argv)
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
+static int pcie_pm_show(struct major_cmd_ctrl *self, const char *argv)
|
||
|
|
+{
|
||
|
|
+ g_trace_cmd.cmd_type = TRACE_PM;
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static int pcie_trace_mode_set(struct major_cmd_ctrl *self, const char *argv)
|
||
|
|
{
|
||
|
|
int ret;
|
||
|
|
@@ -108,6 +116,8 @@ static int pcie_trace_excute_funs_call(int cmd_type)
|
||
|
|
return comm_api->ltssm_trace_mode_set(port_id, recover_en);
|
||
|
|
else if (cmd_type == TRACE_INFO)
|
||
|
|
return comm_api->ltssm_link_information_get(port_id);
|
||
|
|
+ else if (cmd_type == TRACE_PM)
|
||
|
|
+ return comm_api->pm_trace(port_id);
|
||
|
|
else
|
||
|
|
return -EINVAL;
|
||
|
|
}
|
||
|
|
@@ -120,14 +130,16 @@ static void pcie_trace_execute(struct major_cmd_ctrl *self)
|
||
|
|
"pcie_trace_show success.",
|
||
|
|
"pcie_trace_clear success.",
|
||
|
|
"get mac link information success.",
|
||
|
|
- "pcie_trace_mode_set success."
|
||
|
|
+ "pcie_trace_mode_set success.",
|
||
|
|
+ "pcie_pm_trace success."
|
||
|
|
};
|
||
|
|
const char *err_msg[] = {
|
||
|
|
"pcie_trace sub command type error.",
|
||
|
|
"pcie_trace_show error.",
|
||
|
|
"pcie_trace_clear error.",
|
||
|
|
"get mac link information error.",
|
||
|
|
- "pcie_trace_mode_set error."
|
||
|
|
+ "pcie_trace_mode_set error.",
|
||
|
|
+ "pcie_pm_trace error"
|
||
|
|
};
|
||
|
|
|
||
|
|
ret = pcie_trace_excute_funs_call(g_trace_cmd.cmd_type);
|
||
|
|
@@ -153,6 +165,7 @@ static void cmd_pcie_trace_init(void)
|
||
|
|
cmd_option_register("-m", "--mode", true, pcie_trace_mode_set);
|
||
|
|
cmd_option_register("-f", "--information", false, pcie_link_information_get);
|
||
|
|
cmd_option_register("-i", "--interface", true, pcie_port_id_set);
|
||
|
|
+ cmd_option_register("-pm", "--pm-state", false, pcie_pm_show);
|
||
|
|
}
|
||
|
|
|
||
|
|
HIKP_CMD_DECLARE("pcie_trace", "pcie ltssm trace", cmd_pcie_trace_init);
|
||
|
|
diff --git a/pcie/usr_cmd/interface/pcie_common_api.c b/pcie/usr_cmd/interface/pcie_common_api.c
|
||
|
|
index 491daf2..8875481 100644
|
||
|
|
--- a/pcie/usr_cmd/interface/pcie_common_api.c
|
||
|
|
+++ b/pcie/usr_cmd/interface/pcie_common_api.c
|
||
|
|
@@ -27,6 +27,7 @@ struct pcie_comm_api g_tools_api = {
|
||
|
|
.err_status_clear = pcie_error_state_clear,
|
||
|
|
.reg_dump = pcie_dumpreg_do_dump,
|
||
|
|
.reg_read = pcie_reg_read,
|
||
|
|
+ .pm_trace = pcie_pm_trace,
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
diff --git a/pcie/usr_cmd/interface/pcie_common_api.h b/pcie/usr_cmd/interface/pcie_common_api.h
|
||
|
|
index 9809575..08d4403 100644
|
||
|
|
--- a/pcie/usr_cmd/interface/pcie_common_api.h
|
||
|
|
+++ b/pcie/usr_cmd/interface/pcie_common_api.h
|
||
|
|
@@ -37,6 +37,7 @@ struct pcie_comm_api {
|
||
|
|
int (*err_status_clear)(uint32_t port_id);
|
||
|
|
int (*reg_dump)(uint32_t port_id, uint32_t dump_level);
|
||
|
|
int (*reg_read)(uint32_t port_id, uint32_t moudle_id, uint32_t offset);
|
||
|
|
+ int (*pm_trace)(uint32_t port_id);
|
||
|
|
};
|
||
|
|
|
||
|
|
struct pcie_comm_api *pcie_get_comm_api(void);
|
||
|
|
--
|
||
|
|
2.33.0
|