/* * Description: PP micro-controllers Debug FS Interface * * SPDX-License-Identifier: GPL-2.0-only * Copyright (C) 2019-2020 Intel Corporation */ #define pr_fmt(fmt) "[PP_UC_DBG]:%s:%d: " fmt, __func__, __LINE__ #include #include #include #include #include #include #include #include #include #include "pp_common.h" #include "pp_regs.h" #include "pp_debugfs_common.h" #include "infra.h" #include "uc.h" #include "uc_regs.h" #include "uc_internal.h" /** * @brief main uc debugfs dir */ static struct dentry *dbgfs; static u32 gcid, gtid; static void uc_dbg_nf_cfg_set(char *cmd_buf, void *data) { u16 pid, qos_port, tx_queue, host_q; u32 nf; if (unlikely(sscanf(cmd_buf, "%u %hu %hu %hu %hu", &nf, &pid, &qos_port, &tx_queue, &host_q) != 5)) { pr_err("sscanf error\n"); return; } if (unlikely(uc_nf_set(nf, pid, qos_port, tx_queue, host_q))) { pr_err("failed to set nf\n"); return; } pr_info("UC_TYPE[EGRESS] NF[%u] PID[%hu] QOS_RX_PORT[%hu] QOS_TX_QUEUE[%hu]\n", nf, pid, qos_port, tx_queue); } static void uc_dbg_nf_cfg_help(struct seq_file *f) { seq_puts(f, " \n"); } PP_DEFINE_DEBUGFS(nf_cfg, uc_dbg_nf_cfg_help, uc_dbg_nf_cfg_set); static void uc_dbg_core_run_halt_set(char *cmd_buf, void *data) { u8 uc_type, cpu_id, enable; if (unlikely(sscanf(cmd_buf, "%hhu %hhu %hhu", &uc_type, &cpu_id, &enable) != 3)) { pr_err("sscanf error\n"); return; } if (unlikely(uc_type > 1)) { pr_err("invalid uc cluster %hhu\n", uc_type); return; } uc_run_set(!!uc_type, (u32)cpu_id, !!enable); pr_info("UC_TYPE[%s] CPU_ID[%hhu] ACTION[%s]\n", uc_type ? "EGRESS" : "INGRESS", cpu_id, enable ? "RUN" : "HALT"); } static void uc_dbg_core_run_halt_show(struct seq_file *f) { seq_puts(f, " \n"); } PP_DEFINE_DEBUGFS(core_run_halt, uc_dbg_core_run_halt_show, uc_dbg_core_run_halt_set); static void uc_dbg_uc_enable_set(char *cmd_buf, void *data) { u8 uc_type, cpu_id, enable; if (unlikely(sscanf(cmd_buf, "%hhu %hhu %hhu", &uc_type, &cpu_id, &enable) != 3)) { pr_err("Command format error\n"); pr_err(" \n"); return; } if (unlikely(uc_type > 1)) { pr_err("invalid uc cluster %hhu\n", uc_type); return; } uc_ccu_enable_set(!!uc_type, (u32)cpu_id, !!enable); pr_info("UC_TYPE[%s] CPU_ID[%hhu] ACTION[%s]\n", uc_type ? "EGRESS" : "INGRESS", cpu_id, BOOL2EN(enable)); } static void uc_dbg_uc_enable_show(struct seq_file *f) { u32 i; bool act; u8 hw_max_cpu, uc_types = 2; if (unlikely(!uc_is_cluster_valid(UC_IS_EGR) && !uc_is_cluster_valid(UC_IS_ING))) { seq_puts(f, "all uc cpus are disabled\n"); return; } seq_puts(f, "\n"); seq_puts(f, " +---------------------------------+\n"); seq_puts(f, " | UC CPU STATUS |\n"); seq_puts(f, " +---------------------------------+\n"); seq_puts(f, " | CLUSTER | CPU ID | STATUS |\n"); seq_puts(f, " +-----------+----------+----------+\n"); while (uc_types--) { if (unlikely(!uc_is_cluster_valid(!!uc_types))) continue; if (uc_ccu_maxcpus_get(!!uc_types, &hw_max_cpu)) { seq_printf(f, "failed to get the %s max cpus\n", !!uc_types ? "egress" : "ingress"); return; } for (i = 0; i < hw_max_cpu; i++) { act = uc_is_cpu_active(!!uc_types, i); seq_printf(f, " | %-9s | %-6u | %-8s |\n", !!uc_types ? "EGRESS" : "INGRESS", i, act ? "ACTIVE" : "INACTIVE"); seq_puts(f, " +-----------+----------+----------+\n"); } } seq_puts(f, "\n"); } PP_DEFINE_DEBUGFS(uc_enable, uc_dbg_uc_enable_show, uc_dbg_uc_enable_set); static void uc_dbg_fat_set(char *cmd_buf, void *data) { u8 uc_type; u32 ent, val, en; s32 ret; if (unlikely(sscanf(cmd_buf, "%hhu %x %x %u", &uc_type, &ent, &val, &en) != 4)) { pr_err("Command format error\n"); pr_err(" \n"); return; } if (unlikely(uc_type > 1)) { pr_err("invalid uc cluster %hhu\n", uc_type); return; } ret = uc_fat_set(!!uc_type, ent, val, !!en); if (unlikely(ret)) { pr_err("failed to set the cluster bridge fat\n"); return; } pr_info("UC_TYPE[%s] FAT_ENT[%#x] VAL[%#x] ACTION[%s]\n", uc_type ? "EGRESS" : "INGRESS", ent, val, BOOL2EN(en)); } static void uc_dbg_fat_show(struct seq_file *f) { u32 i, max_ent, val; bool enable; if (pp_silicon_step_get() == PP_SSTEP_A) max_ent = UC_A_FAT_MAX_ENT; else max_ent = UC_B_FAT_ALL_MAX_ENT; if (uc_is_cluster_valid(UC_IS_EGR)) { seq_puts(f, " +-------------------------------+\n"); seq_puts(f, " | EGRESS CLUSTER BRIDGE FAT |\n"); seq_puts(f, " +-------------------------------+\n"); seq_puts(f, " | ENTRY | IS_ENABLE | VALUE |\n"); seq_puts(f, " +-------+-----------+-----------+\n"); for (i = 0; i < max_ent; i++) { if (uc_fat_get(UC_IS_EGR, i, &val, &enable)) { seq_printf(f, "failed to get fat ent %u\n", i); break; } seq_printf(f, " | 0x%-2X | %-9s | 0x%-8X|\n", i, BOOL2EN(enable), val); seq_puts(f, " +-------+-----------+-----------+\n"); } } seq_puts(f, "\n"); if (uc_is_cluster_valid(UC_IS_ING)) { seq_puts(f, " +-------------------------------+\n"); seq_puts(f, " | INGRESS CLUSTER BRIDGE FAT |\n"); seq_puts(f, " +-------------------------------+\n"); seq_puts(f, " | ENTRY | IS_ENABLE | VALUE |\n"); seq_puts(f, " +-------+-----------+-----------+\n"); for (i = 0; i < max_ent; i++) { if (uc_fat_get(UC_IS_ING, i, &val, &enable)) { seq_printf(f, "failed to get fat ent %u\n", i); break; } seq_printf(f, " | 0x%-2X | %-9s | 0x%-8X|\n", i, BOOL2EN(enable), val); seq_puts(f, " +-------+-----------+-----------+\n"); } } seq_puts(f, "\n"); } PP_DEFINE_DEBUGFS(fat, uc_dbg_fat_show, uc_dbg_fat_set); static void uc_dbg_ccu_gpreg_set(char *cmd_buf, void *data) { u8 uc_type; u32 gpreg_id, val; if (unlikely(sscanf(cmd_buf, "%hhu %u %u", &uc_type, &gpreg_id, &val) != 3)) { pr_err("Command format error\n"); pr_err(" \n"); return; } if (unlikely(uc_type > 1)) { pr_err("invalid uc cluster %hhu\n", uc_type); return; } if (uc_ccu_gpreg_set(!!uc_type, gpreg_id, val)) { pr_err("failed to set gpreg %u\n", gpreg_id); return; } pr_info("UC_TYPE[%s] GPREG_ID[%u] VALUE[%u]\n", uc_type ? "EGRESS" : "INGRESS", gpreg_id, val); } static void uc_dbg_ccu_gpreg_show(struct seq_file *f) { u32 i, val; u8 uc_types = 2; if (unlikely(!uc_is_cluster_valid(UC_IS_EGR) && !uc_is_cluster_valid(UC_IS_ING))) { seq_puts(f, "uc clusters are disabled\n"); return; } seq_puts(f, "\n"); seq_puts(f, " +---------------------------------+\n"); seq_puts(f, " | UC CCU GPREG |\n"); seq_puts(f, " +---------------------------------+\n"); seq_puts(f, " | CLUSTER | GPREG ID | VALUE |\n"); seq_puts(f, " +-----------+----------+----------+\n"); while (uc_types--) { if (unlikely(!uc_is_cluster_valid(!!uc_types))) continue; for (i = 0; i < UC_CCU_GPREG_MAX; i++) { if (unlikely(uc_ccu_gpreg_get(!!uc_types, i, &val))) return; seq_printf(f, " | %-9s | %-6u |0x%08X|\n", !!uc_types ? "EGRESS" : "INGRESS", i, val); seq_puts(f, " +-----------+----------+----------+\n"); } } seq_puts(f, "\n"); } PP_DEFINE_DEBUGFS(ccu_gpreg, uc_dbg_ccu_gpreg_show, uc_dbg_ccu_gpreg_set); static void uc_dbg_ccu_irr_show(struct seq_file *f) { u32 irr; u8 uc_types = 2; if (unlikely(!uc_is_cluster_valid(UC_IS_EGR) && !uc_is_cluster_valid(UC_IS_ING))) { seq_puts(f, "uc clusters are disabled\n"); return; } seq_puts(f, "\n"); seq_puts(f, " +---------------------------------+\n"); seq_puts(f, " | UC CCU INTERRUPT REQUEST STATUS |\n"); seq_puts(f, " +---------------------------------+\n"); seq_puts(f, " | CLUSTER | CCU IRR REG VAL |\n"); seq_puts(f, " +-----------+---------------------+\n"); while (uc_types--) { if (unlikely(!uc_is_cluster_valid(!!uc_types))) continue; if (uc_ccu_irr_get(!!uc_types, &irr)) { seq_printf(f, "failed to get the %s irr value\n", !!uc_types ? "egress" : "ingress"); return; } seq_printf(f, " | %-9s | 0x%08X |\n", !!uc_types ? "EGRESS" : "INGRESS", irr); seq_puts(f, " +-----------+---------------------+\n"); } seq_puts(f, "\n"); } PP_DEFINE_DEBUGFS(ccu_irr, uc_dbg_ccu_irr_show, NULL); static void uc_dbg_reader_irr_show(struct seq_file *f) { u32 irr; u8 uc_types = 2; if (unlikely(!uc_is_cluster_valid(UC_IS_EGR) && !uc_is_cluster_valid(UC_IS_ING))) { seq_puts(f, "uc clusters are disabled\n"); return; } seq_puts(f, "\n"); seq_puts(f, " +------------------------------------+\n"); seq_puts(f, " | UC READER INTERRUPT REQUEST STATUS |\n"); seq_puts(f, " +------------------------------------+\n"); seq_puts(f, " | CLUSTER | READER IRR REG VAL |\n"); seq_puts(f, " +-----------+------------------------+\n"); while (uc_types--) { if (unlikely(!uc_is_cluster_valid(!!uc_types))) continue; if (uc_reader_irr_get(!!uc_types, &irr)) { seq_printf(f, "failed to get the %s irr value\n", !!uc_types ? "egress" : "ingress"); return; } seq_printf(f, " | %-9s | 0x%08X |\n", !!uc_types ? "EGRESS" : "INGRESS", irr); seq_puts(f, " +-----------+------------------------+\n"); } seq_puts(f, "\n"); } PP_DEFINE_DEBUGFS(reader_irr, uc_dbg_reader_irr_show, NULL); static void uc_dbg_version_show(struct seq_file *f) { u32 ver; seq_puts(f, "\n"); if (likely(!uc_ver_get(UC_IS_EGR, &ver))) { seq_printf(f, "EGRESS : MAJOR[%u], MINOR[%u], BUILD[%u]\n", (ver >> 16) & U8_MAX, (ver >> 8) & U8_MAX, ver & U8_MAX); } if (likely(!uc_ver_get(UC_IS_ING, &ver))) { seq_printf(f, "INGRESS : MAJOR[%u], MINOR[%u], BUILD[%u]\n", (ver >> 16) & U8_MAX, (ver >> 8) & U8_MAX, ver & U8_MAX); } } PP_DEFINE_DEBUGFS(version, uc_dbg_version_show, NULL); enum uc_log_opts { uc_log_opt_help = 1, uc_log_opt_reset, uc_log_opt_level, }; static const match_table_t uc_log_tokens = { { uc_log_opt_help, "help" }, { uc_log_opt_reset, "reset" }, { uc_log_opt_level, "level=%u" }, }; static void __uc_log_help(void) { pr_info("\n"); pr_info(" Brief: Print/configure UC logger\n"); pr_info(" Usage: echo