blob: 3aef31ab1fa3e38fffbe630452cec8aeede509c0 [file] [log] [blame]
/*
<:copyright-BRCM:2016:DUAL/GPL:standard
Broadcom Proprietary and Confidential.(c) 2016 Broadcom
All Rights Reserved
Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:
As a special exception, the copyright holders of this software give
you permission to link this software with independent modules, and
to copy and distribute the resulting executable under terms of your
choice, provided that you also meet, for each linked independent
module, the terms and conditions of the license of that module.
An independent module is a module which is not derived from this
software. The special exception does not apply to any modifications
of the software.
Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.
:>
*/
#include <bcmos_cli.h>
static bcmcli_entry *os_cli_dir;
static bcmcli_enum_val trace_level_table[] =
{
{ .name="none", .val=BCMOS_TRACE_LEVEL_NONE },
{ .name="error", .val=BCMOS_TRACE_LEVEL_ERROR },
{ .name="info", .val=BCMOS_TRACE_LEVEL_INFO },
{ .name="verbose_info", .val=BCMOS_TRACE_LEVEL_VERBOSE },
{ .name="debug", .val=BCMOS_TRACE_LEVEL_DEBUG },
BCMCLI_ENUM_LAST
};
/*
* Command handlers
*/
static bcmos_errno _oscli_trace_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
bcmos_trace_level level = (bcmos_trace_level)parm[0].value.number;
if (bcmcli_parm_is_set(session, &parm[0]))
{
bcmos_trace_level old_level;
old_level = bcmos_trace_level_set(level);
bcmcli_session_print(session, "OS trace level: old=%s new=%s\n",
bcmcli_enum_stringval(trace_level_table, old_level),
bcmcli_enum_stringval(trace_level_table, level));
}
else
{
bcmcli_session_print(session, "OS trace level: %s\n",
bcmcli_enum_stringval(trace_level_table, bcmos_trace_level_get()));
}
return BCM_ERR_OK;
}
static bcmos_errno _oscli_task_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
bcmos_task *task = NULL;
int nt = 0;
bcmcli_session_print(session, "%-20s %4s %4s %-10s %s\n", "task", "prio", "core", "timeout", "handler");
while (bcmos_task_get_next(&task) == BCM_ERR_OK)
{
bcmos_task_parm tp = {};
bcmos_task_query(task, &tp);
if (!name || (name && tp.name && strstr(tp.name, name)))
{
char core_name[10];
if (tp.core != BCMOS_CPU_CORE_ANY)
{
snprintf(core_name, sizeof(core_name), "%d", tp.core - 1);
}
else
{
strcpy(core_name, "any");
}
bcmcli_session_print(session, "%-20s %-4d %-4s %-10u %p\n",
tp.name, tp.priority, core_name,
(tp.msg_wait_timeout == BCMOS_WAIT_FOREVER) ? 0 : tp.msg_wait_timeout, tp.handler);
++nt;
}
}
bcmcli_session_print(session, "%d tasks listed\n", nt);
return BCM_ERR_OK;
}
static void _oscli_print_qinfo_hdr(bcmcli_session *session, const char *prefix)
{
bcmcli_session_print(session, "%-9s %-9s %-10s %-10s %-10s %-10s %-8s %-8s %-10s congested\n",
prefix ? prefix : "", "size", "in", "put", "get", "discard", "l_thresh", "h_thresh", "near-full");
}
static void _oscli_print_qinfo(bcmcli_session *session, bcmos_msg_queue_info *qi, const char *prefix)
{
bcmcli_session_print(session, "%-s %-9d %-10u %-10u %-10u %-10u %-8d %-8d %-10u %s\n",
prefix ? prefix : "", (int)qi->parm.size, qi->stat.msg_in,
qi->stat.msg_sent, qi->stat.msg_received,
qi->stat.msg_discarded, (int)qi->parm.low_wm, (int)qi->parm.high_wm,
qi->stat.msg_almost_full, qi->stat.is_congested ? "yes" : "no");
}
static bcmos_errno _oscli_module_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
bcmos_module_id id = bcmcli_parm_is_set(session, &parm[0]) ?
(bcmos_module_id)parm[0].value.number : BCMOS_MODULE_ID_NONE;
bcmos_module_id i;
int nm = 0;
/* Heading */
_oscli_print_qinfo_hdr(session, "Module Task ");
for (i = BCMOS_MODULE_ID_NONE + 1; i < BCMOS_MODULE_ID__NUM_OF; i++)
{
bcmos_errno rc;
const bcmos_task *t = NULL;
bcmos_msg_queue_info qi = {};
rc = bcmos_module_query(i, &t, &qi);
if ((id == BCMOS_MODULE_ID_NONE || id == i) && rc == BCM_ERR_OK)
{
bcmos_task_parm tp = {};
bcmos_task_query(t, &tp);
bcmcli_session_print(session, "%-6d %-20s", i, (t && t->parm.name) ? t->parm.name : "*unknown*");
_oscli_print_qinfo(session, &qi, " ");
++nm;
}
}
bcmcli_session_print(session, "%d modules listed\n", nm);
return BCM_ERR_OK;
}
static bcmos_errno _oscli_blk_pool_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
const bcmos_blk_pool *bp = NULL;
int nb = 0;
bcmcli_session_print(session, "%-24s %-9s %-9s %-9s %-10s %-10s %-10s %-10s\n",
"name", "pool_size", "blocks", "blk_size", "free", "allocated", "released", "failed");
while (bcmos_blk_pool_get_next(&bp) == BCM_ERR_OK)
{
bcmos_blk_pool_info pi = {};
bcmos_blk_pool_query(bp, &pi);
if (name == NULL || (pi.parm.name && strstr(pi.parm.name, name)))
{
bcmcli_session_print(session, "%-24s %-9u %-9u %-9u %-10u %-10u %-10u %-10u\n",
pi.parm.name ? pi.parm.name : "", pi.parm.pool_size, pi.parm.num_blks, pi.parm.blk_size,
pi.stat.free, pi.stat.allocated, pi.stat.released, pi.stat.alloc_failed);
++nb;
}
}
bcmcli_session_print(session, "Total memory occupied by all block pools: %u bytes\n", bcmos_total_blk_pool_size);
bcmcli_session_print(session, "%d block pools listed\n", nb);
return BCM_ERR_OK;
}
static bcmos_errno _oscli_msg_pool_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
const bcmos_msg_pool *mp = NULL;
int np = 0;
bcmcli_session_print(session, "%-24s %-9s %-9s %-10s %-10s %-10s %-10s\n",
"name", "size", "data_size", "free", "allocated", "released", "failed");
while (bcmos_msg_pool_get_next(&mp) == BCM_ERR_OK)
{
bcmos_msg_pool_info pi = {};
bcmos_msg_pool_query(mp, &pi);
if (name == NULL || (pi.parm.name && strstr(pi.parm.name, name)))
{
bcmcli_session_print(session, "%-24s %-9u %-9u %-10u %-10u %-10u %-10u\n",
pi.parm.name ? pi.parm.name : "", pi.parm.size, pi.parm.data_size,
pi.stat.free, pi.stat.allocated, pi.stat.released, pi.stat.alloc_failed);
++np;
}
}
bcmcli_session_print(session, "Total memory occupied by all message pools: %u bytes\n", bcmos_total_msg_pool_size);
bcmcli_session_print(session, "%d msg pools listed\n", np);
return BCM_ERR_OK;
}
static bcmos_errno _oscli_msg_queue_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
const bcmos_msg_queue *mq = NULL;
int nq = 0;
_oscli_print_qinfo_hdr(session, "name ");
while (bcmos_msg_queue_get_next(&mq) == BCM_ERR_OK)
{
bcmos_msg_queue_info qi = {};
bcmos_msg_queue_query(mq, &qi);
if (name == NULL || (qi.parm.name && strstr(qi.parm.name, name)))
{
bcmcli_session_print(session, "%-20s", qi.parm.name ? qi.parm.name : "");
_oscli_print_qinfo(session, &qi, " ");
++nq;
}
}
bcmcli_session_print(session, "%d msg queues listed\n", nq);
return BCM_ERR_OK;
}
static void _oscli_print_qgroup_info_hdr(bcmcli_session *session)
{
bcmcli_session_print(session, "%-12s %-6s %-9s %-10s %-10s %-10s %-10s %-8s %-8s %-10s congested\n",
"name", "queues", "size", "in", "put", "get", "discard", "l_thresh", "h_thresh", "near-full");
}
static void _oscli_print_qgroup_info(bcmcli_session *session, bcmos_msg_qgroup_info *qi)
{
bcmcli_session_print(session, "%-12s %-6d %-9d %-10u %-10u %-10u %-10u %-8d %-8d %-10u %s\n",
qi->parm.name ? qi->parm.name : "", (int)qi->parm.nqueues, (int)qi->parm.size, qi->stat.msg_in,
qi->stat.msg_sent, qi->stat.msg_received,
qi->stat.msg_discarded, (int)qi->parm.low_wm, (int)qi->parm.high_wm,
qi->stat.msg_almost_full, qi->stat.is_congested ? "yes" : "no");
}
static bcmos_errno _oscli_msg_qgroup_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL;
const bcmos_msg_qgroup *qgrp = NULL;
int ngroups = 0;
_oscli_print_qgroup_info_hdr(session);
while (bcmos_msg_qgroup_get_next(&qgrp) == BCM_ERR_OK)
{
bcmos_msg_qgroup_info qi = {};
bcmos_msg_qgroup_query(qgrp, &qi);
if (name == NULL || (qi.parm.name && strstr(qi.parm.name, name)))
{
_oscli_print_qgroup_info(session, &qi);
++ngroups;
}
}
bcmcli_session_print(session, "%d msg queue groups listed\n", ngroups);
return BCM_ERR_OK;
}
#ifdef BCM_OS_THREADX
extern TX_THREAD __sys_shell__;
extern TX_THREAD *__usr_shell__;
static bcmos_errno _oscli_sys_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
bcmcli_session_print(session, "Application CLI is suspended. Type \"suspend\" in system shell to resume\n");
tx_thread_resume(&__sys_shell__);
tx_thread_suspend(tx_thread_identify());
tx_thread_wait_abort(tx_thread_identify());
bcmcli_session_print(session, "Application CLI is resumed\n");
return BCM_ERR_OK;
}
#endif
/*
* Init / exit interface
*/
bcmos_errno bcmos_cli_init(bcmcli_entry *top_dir)
{
if (os_cli_dir)
{
return BCM_ERR_ALREADY;
}
/*
* rx directory
*/
os_cli_dir = bcmcli_dir_add(top_dir, "os", "OS Abstraction", BCMCLI_ACCESS_GUEST, NULL);
BCMOS_CHECK_RETURN_ERROR(!os_cli_dir, BCM_ERR_INTERNAL);
BCMCLI_MAKE_CMD(os_cli_dir, "trace", "Get/Set trace level", _oscli_trace_handler,
BCMCLI_MAKE_PARM_ENUM("level", "Trace level", trace_level_table, BCMCLI_PARM_FLAG_OPTIONAL));
BCMCLI_MAKE_CMD(os_cli_dir, "task", "Task info", _oscli_task_handler,
BCMCLI_MAKE_PARM("name", "Task name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
BCMCLI_MAKE_CMD(os_cli_dir, "module", "Module(s)", _oscli_module_handler,
BCMCLI_MAKE_PARM_RANGE("id", "Module id", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_OPTIONAL,
BCMOS_MODULE_ID_NONE + 1, BCMOS_MODULE_ID__NUM_OF - 1));
BCMCLI_MAKE_CMD(os_cli_dir, "blk_pool", "Block pool(s)", _oscli_blk_pool_handler,
BCMCLI_MAKE_PARM("name", "Block pool name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
BCMCLI_MAKE_CMD(os_cli_dir, "msg_pool", "Message pool(s)", _oscli_msg_pool_handler,
BCMCLI_MAKE_PARM("name", "Message pool name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
BCMCLI_MAKE_CMD(os_cli_dir, "queue", "Message queue(s)", _oscli_msg_queue_handler,
BCMCLI_MAKE_PARM("name", "Message queue name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
BCMCLI_MAKE_CMD(os_cli_dir, "qgroup", "Message queue group(s)", _oscli_msg_qgroup_handler,
BCMCLI_MAKE_PARM("name", "Message queue group name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL));
#ifdef BCM_OS_THREADX
BCMCLI_MAKE_CMD_NOPARM(os_cli_dir, "sys", "System shell", _oscli_sys_handler);
#endif
return BCM_ERR_OK;
}
void bcmos_cli_exit(void)
{
if (os_cli_dir)
{
bcmcli_token_destroy(os_cli_dir);
os_cli_dir = NULL;
}
}