Shad Ansari | 2f7f9be | 2017-06-07 13:34:53 -0700 | [diff] [blame] | 1 | /* |
| 2 | <:copyright-BRCM:2016:DUAL/GPL:standard |
| 3 | |
| 4 | Broadcom Proprietary and Confidential.(c) 2016 Broadcom |
| 5 | All Rights Reserved |
| 6 | |
| 7 | Unless you and Broadcom execute a separate written software license |
| 8 | agreement governing use of this software, this software is licensed |
| 9 | to you under the terms of the GNU General Public License version 2 |
| 10 | (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| 11 | with the following added to such license: |
| 12 | |
| 13 | As a special exception, the copyright holders of this software give |
| 14 | you permission to link this software with independent modules, and |
| 15 | to copy and distribute the resulting executable under terms of your |
| 16 | choice, provided that you also meet, for each linked independent |
| 17 | module, the terms and conditions of the license of that module. |
| 18 | An independent module is a module which is not derived from this |
| 19 | software. The special exception does not apply to any modifications |
| 20 | of the software. |
| 21 | |
| 22 | Not withstanding the above, under no circumstances may you combine |
| 23 | this software in any way with any other Broadcom software provided |
| 24 | under a license other than the GPL, without Broadcom's express prior |
| 25 | written consent. |
| 26 | |
| 27 | :> |
| 28 | */ |
| 29 | |
| 30 | #include <bcmos_cli.h> |
| 31 | |
| 32 | static bcmcli_entry *os_cli_dir; |
| 33 | |
| 34 | static bcmcli_enum_val trace_level_table[] = |
| 35 | { |
| 36 | { .name="none", .val=BCMOS_TRACE_LEVEL_NONE }, |
| 37 | { .name="error", .val=BCMOS_TRACE_LEVEL_ERROR }, |
| 38 | { .name="info", .val=BCMOS_TRACE_LEVEL_INFO }, |
| 39 | { .name="verbose_info", .val=BCMOS_TRACE_LEVEL_VERBOSE }, |
| 40 | { .name="debug", .val=BCMOS_TRACE_LEVEL_DEBUG }, |
| 41 | BCMCLI_ENUM_LAST |
| 42 | }; |
| 43 | |
| 44 | /* |
| 45 | * Command handlers |
| 46 | */ |
| 47 | |
| 48 | static bcmos_errno _oscli_trace_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms) |
| 49 | { |
| 50 | bcmos_trace_level level = (bcmos_trace_level)parm[0].value.number; |
| 51 | |
| 52 | if (bcmcli_parm_is_set(session, &parm[0])) |
| 53 | { |
| 54 | bcmos_trace_level old_level; |
| 55 | |
| 56 | old_level = bcmos_trace_level_set(level); |
| 57 | bcmcli_session_print(session, "OS trace level: old=%s new=%s\n", |
| 58 | bcmcli_enum_stringval(trace_level_table, old_level), |
| 59 | bcmcli_enum_stringval(trace_level_table, level)); |
| 60 | } |
| 61 | else |
| 62 | { |
| 63 | bcmcli_session_print(session, "OS trace level: %s\n", |
| 64 | bcmcli_enum_stringval(trace_level_table, bcmos_trace_level_get())); |
| 65 | } |
| 66 | return BCM_ERR_OK; |
| 67 | } |
| 68 | |
| 69 | static bcmos_errno _oscli_task_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms) |
| 70 | { |
| 71 | const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL; |
| 72 | bcmos_task *task = NULL; |
| 73 | int nt = 0; |
| 74 | |
| 75 | bcmcli_session_print(session, "%-20s %4s %4s %-10s %s\n", "task", "prio", "core", "timeout", "handler"); |
| 76 | while (bcmos_task_get_next(&task) == BCM_ERR_OK) |
| 77 | { |
| 78 | bcmos_task_parm tp = {}; |
| 79 | bcmos_task_query(task, &tp); |
| 80 | if (!name || (name && tp.name && strstr(tp.name, name))) |
| 81 | { |
| 82 | char core_name[10]; |
| 83 | if (tp.core != BCMOS_CPU_CORE_ANY) |
| 84 | { |
| 85 | snprintf(core_name, sizeof(core_name), "%d", tp.core - 1); |
| 86 | } |
| 87 | else |
| 88 | { |
| 89 | strcpy(core_name, "any"); |
| 90 | } |
| 91 | bcmcli_session_print(session, "%-20s %-4d %-4s %-10u %p\n", |
| 92 | tp.name, tp.priority, core_name, |
| 93 | (tp.msg_wait_timeout == BCMOS_WAIT_FOREVER) ? 0 : tp.msg_wait_timeout, tp.handler); |
| 94 | ++nt; |
| 95 | } |
| 96 | } |
| 97 | bcmcli_session_print(session, "%d tasks listed\n", nt); |
| 98 | |
| 99 | return BCM_ERR_OK; |
| 100 | } |
| 101 | |
| 102 | static void _oscli_print_qinfo_hdr(bcmcli_session *session, const char *prefix) |
| 103 | { |
| 104 | bcmcli_session_print(session, "%-9s %-9s %-10s %-10s %-10s %-10s %-8s %-8s %-10s congested\n", |
| 105 | prefix ? prefix : "", "size", "in", "put", "get", "discard", "l_thresh", "h_thresh", "near-full"); |
| 106 | } |
| 107 | |
| 108 | static void _oscli_print_qinfo(bcmcli_session *session, bcmos_msg_queue_info *qi, const char *prefix) |
| 109 | { |
| 110 | bcmcli_session_print(session, "%-s %-9d %-10u %-10u %-10u %-10u %-8d %-8d %-10u %s\n", |
| 111 | prefix ? prefix : "", (int)qi->parm.size, qi->stat.msg_in, |
| 112 | qi->stat.msg_sent, qi->stat.msg_received, |
| 113 | qi->stat.msg_discarded, (int)qi->parm.low_wm, (int)qi->parm.high_wm, |
| 114 | qi->stat.msg_almost_full, qi->stat.is_congested ? "yes" : "no"); |
| 115 | } |
| 116 | |
| 117 | static bcmos_errno _oscli_module_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms) |
| 118 | { |
| 119 | bcmos_module_id id = bcmcli_parm_is_set(session, &parm[0]) ? |
| 120 | (bcmos_module_id)parm[0].value.number : BCMOS_MODULE_ID_NONE; |
| 121 | bcmos_module_id i; |
| 122 | int nm = 0; |
| 123 | |
| 124 | /* Heading */ |
| 125 | _oscli_print_qinfo_hdr(session, "Module Task "); |
| 126 | |
| 127 | for (i = BCMOS_MODULE_ID_NONE + 1; i < BCMOS_MODULE_ID__NUM_OF; i++) |
| 128 | { |
| 129 | bcmos_errno rc; |
| 130 | const bcmos_task *t = NULL; |
| 131 | bcmos_msg_queue_info qi = {}; |
| 132 | |
| 133 | rc = bcmos_module_query(i, &t, &qi); |
| 134 | if ((id == BCMOS_MODULE_ID_NONE || id == i) && rc == BCM_ERR_OK) |
| 135 | { |
| 136 | bcmos_task_parm tp = {}; |
| 137 | |
| 138 | bcmos_task_query(t, &tp); |
| 139 | bcmcli_session_print(session, "%-6d %-20s", i, (t && t->parm.name) ? t->parm.name : "*unknown*"); |
| 140 | _oscli_print_qinfo(session, &qi, " "); |
| 141 | ++nm; |
| 142 | } |
| 143 | } |
| 144 | bcmcli_session_print(session, "%d modules listed\n", nm); |
| 145 | |
| 146 | return BCM_ERR_OK; |
| 147 | } |
| 148 | |
| 149 | static bcmos_errno _oscli_blk_pool_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms) |
| 150 | { |
| 151 | const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL; |
| 152 | const bcmos_blk_pool *bp = NULL; |
| 153 | int nb = 0; |
| 154 | |
| 155 | bcmcli_session_print(session, "%-24s %-9s %-9s %-9s %-10s %-10s %-10s %-10s\n", |
| 156 | "name", "pool_size", "blocks", "blk_size", "free", "allocated", "released", "failed"); |
| 157 | while (bcmos_blk_pool_get_next(&bp) == BCM_ERR_OK) |
| 158 | { |
| 159 | bcmos_blk_pool_info pi = {}; |
| 160 | |
| 161 | bcmos_blk_pool_query(bp, &pi); |
| 162 | if (name == NULL || (pi.parm.name && strstr(pi.parm.name, name))) |
| 163 | { |
| 164 | bcmcli_session_print(session, "%-24s %-9u %-9u %-9u %-10u %-10u %-10u %-10u\n", |
| 165 | pi.parm.name ? pi.parm.name : "", pi.parm.pool_size, pi.parm.num_blks, pi.parm.blk_size, |
| 166 | pi.stat.free, pi.stat.allocated, pi.stat.released, pi.stat.alloc_failed); |
| 167 | ++nb; |
| 168 | } |
| 169 | } |
| 170 | bcmcli_session_print(session, "Total memory occupied by all block pools: %u bytes\n", bcmos_total_blk_pool_size); |
| 171 | bcmcli_session_print(session, "%d block pools listed\n", nb); |
| 172 | |
| 173 | return BCM_ERR_OK; |
| 174 | } |
| 175 | |
| 176 | static bcmos_errno _oscli_msg_pool_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms) |
| 177 | { |
| 178 | const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL; |
| 179 | const bcmos_msg_pool *mp = NULL; |
| 180 | int np = 0; |
| 181 | |
| 182 | bcmcli_session_print(session, "%-24s %-9s %-9s %-10s %-10s %-10s %-10s\n", |
| 183 | "name", "size", "data_size", "free", "allocated", "released", "failed"); |
| 184 | while (bcmos_msg_pool_get_next(&mp) == BCM_ERR_OK) |
| 185 | { |
| 186 | bcmos_msg_pool_info pi = {}; |
| 187 | |
| 188 | bcmos_msg_pool_query(mp, &pi); |
| 189 | if (name == NULL || (pi.parm.name && strstr(pi.parm.name, name))) |
| 190 | { |
| 191 | bcmcli_session_print(session, "%-24s %-9u %-9u %-10u %-10u %-10u %-10u\n", |
| 192 | pi.parm.name ? pi.parm.name : "", pi.parm.size, pi.parm.data_size, |
| 193 | pi.stat.free, pi.stat.allocated, pi.stat.released, pi.stat.alloc_failed); |
| 194 | ++np; |
| 195 | } |
| 196 | } |
| 197 | bcmcli_session_print(session, "Total memory occupied by all message pools: %u bytes\n", bcmos_total_msg_pool_size); |
| 198 | bcmcli_session_print(session, "%d msg pools listed\n", np); |
| 199 | |
| 200 | return BCM_ERR_OK; |
| 201 | } |
| 202 | |
| 203 | static bcmos_errno _oscli_msg_queue_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms) |
| 204 | { |
| 205 | const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL; |
| 206 | const bcmos_msg_queue *mq = NULL; |
| 207 | int nq = 0; |
| 208 | |
| 209 | _oscli_print_qinfo_hdr(session, "name "); |
| 210 | while (bcmos_msg_queue_get_next(&mq) == BCM_ERR_OK) |
| 211 | { |
| 212 | bcmos_msg_queue_info qi = {}; |
| 213 | |
| 214 | bcmos_msg_queue_query(mq, &qi); |
| 215 | if (name == NULL || (qi.parm.name && strstr(qi.parm.name, name))) |
| 216 | { |
| 217 | bcmcli_session_print(session, "%-20s", qi.parm.name ? qi.parm.name : ""); |
| 218 | _oscli_print_qinfo(session, &qi, " "); |
| 219 | ++nq; |
| 220 | } |
| 221 | } |
| 222 | bcmcli_session_print(session, "%d msg queues listed\n", nq); |
| 223 | |
| 224 | return BCM_ERR_OK; |
| 225 | } |
| 226 | |
| 227 | static void _oscli_print_qgroup_info_hdr(bcmcli_session *session) |
| 228 | { |
| 229 | bcmcli_session_print(session, "%-12s %-6s %-9s %-10s %-10s %-10s %-10s %-8s %-8s %-10s congested\n", |
| 230 | "name", "queues", "size", "in", "put", "get", "discard", "l_thresh", "h_thresh", "near-full"); |
| 231 | } |
| 232 | |
| 233 | static void _oscli_print_qgroup_info(bcmcli_session *session, bcmos_msg_qgroup_info *qi) |
| 234 | { |
| 235 | bcmcli_session_print(session, "%-12s %-6d %-9d %-10u %-10u %-10u %-10u %-8d %-8d %-10u %s\n", |
| 236 | qi->parm.name ? qi->parm.name : "", (int)qi->parm.nqueues, (int)qi->parm.size, qi->stat.msg_in, |
| 237 | qi->stat.msg_sent, qi->stat.msg_received, |
| 238 | qi->stat.msg_discarded, (int)qi->parm.low_wm, (int)qi->parm.high_wm, |
| 239 | qi->stat.msg_almost_full, qi->stat.is_congested ? "yes" : "no"); |
| 240 | } |
| 241 | |
| 242 | static bcmos_errno _oscli_msg_qgroup_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms) |
| 243 | { |
| 244 | const char *name = bcmcli_parm_is_set(session, &parm[0]) ? (const char *)parm[0].value.string : NULL; |
| 245 | const bcmos_msg_qgroup *qgrp = NULL; |
| 246 | int ngroups = 0; |
| 247 | |
| 248 | _oscli_print_qgroup_info_hdr(session); |
| 249 | while (bcmos_msg_qgroup_get_next(&qgrp) == BCM_ERR_OK) |
| 250 | { |
| 251 | bcmos_msg_qgroup_info qi = {}; |
| 252 | |
| 253 | bcmos_msg_qgroup_query(qgrp, &qi); |
| 254 | if (name == NULL || (qi.parm.name && strstr(qi.parm.name, name))) |
| 255 | { |
| 256 | _oscli_print_qgroup_info(session, &qi); |
| 257 | ++ngroups; |
| 258 | } |
| 259 | } |
| 260 | bcmcli_session_print(session, "%d msg queue groups listed\n", ngroups); |
| 261 | |
| 262 | return BCM_ERR_OK; |
| 263 | } |
| 264 | |
| 265 | #ifdef BCM_OS_THREADX |
| 266 | |
| 267 | extern TX_THREAD __sys_shell__; |
| 268 | extern TX_THREAD *__usr_shell__; |
| 269 | |
| 270 | static bcmos_errno _oscli_sys_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms) |
| 271 | { |
| 272 | bcmcli_session_print(session, "Application CLI is suspended. Type \"suspend\" in system shell to resume\n"); |
| 273 | tx_thread_resume(&__sys_shell__); |
| 274 | tx_thread_suspend(tx_thread_identify()); |
| 275 | tx_thread_wait_abort(tx_thread_identify()); |
| 276 | bcmcli_session_print(session, "Application CLI is resumed\n"); |
| 277 | return BCM_ERR_OK; |
| 278 | } |
| 279 | #endif |
| 280 | |
| 281 | /* |
| 282 | * Init / exit interface |
| 283 | */ |
| 284 | |
| 285 | |
| 286 | bcmos_errno bcmos_cli_init(bcmcli_entry *top_dir) |
| 287 | { |
| 288 | if (os_cli_dir) |
| 289 | { |
| 290 | return BCM_ERR_ALREADY; |
| 291 | } |
| 292 | |
| 293 | /* |
| 294 | * rx directory |
| 295 | */ |
| 296 | os_cli_dir = bcmcli_dir_add(top_dir, "os", "OS Abstraction", BCMCLI_ACCESS_GUEST, NULL); |
| 297 | BCMOS_CHECK_RETURN_ERROR(!os_cli_dir, BCM_ERR_INTERNAL); |
| 298 | |
| 299 | BCMCLI_MAKE_CMD(os_cli_dir, "trace", "Get/Set trace level", _oscli_trace_handler, |
| 300 | BCMCLI_MAKE_PARM_ENUM("level", "Trace level", trace_level_table, BCMCLI_PARM_FLAG_OPTIONAL)); |
| 301 | |
| 302 | BCMCLI_MAKE_CMD(os_cli_dir, "task", "Task info", _oscli_task_handler, |
| 303 | BCMCLI_MAKE_PARM("name", "Task name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL)); |
| 304 | |
| 305 | BCMCLI_MAKE_CMD(os_cli_dir, "module", "Module(s)", _oscli_module_handler, |
| 306 | BCMCLI_MAKE_PARM_RANGE("id", "Module id", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_OPTIONAL, |
| 307 | BCMOS_MODULE_ID_NONE + 1, BCMOS_MODULE_ID__NUM_OF - 1)); |
| 308 | |
| 309 | BCMCLI_MAKE_CMD(os_cli_dir, "blk_pool", "Block pool(s)", _oscli_blk_pool_handler, |
| 310 | BCMCLI_MAKE_PARM("name", "Block pool name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL)); |
| 311 | |
| 312 | BCMCLI_MAKE_CMD(os_cli_dir, "msg_pool", "Message pool(s)", _oscli_msg_pool_handler, |
| 313 | BCMCLI_MAKE_PARM("name", "Message pool name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL)); |
| 314 | |
| 315 | BCMCLI_MAKE_CMD(os_cli_dir, "queue", "Message queue(s)", _oscli_msg_queue_handler, |
| 316 | BCMCLI_MAKE_PARM("name", "Message queue name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL)); |
| 317 | |
| 318 | BCMCLI_MAKE_CMD(os_cli_dir, "qgroup", "Message queue group(s)", _oscli_msg_qgroup_handler, |
| 319 | BCMCLI_MAKE_PARM("name", "Message queue group name or partial name", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_OPTIONAL)); |
| 320 | |
| 321 | #ifdef BCM_OS_THREADX |
| 322 | BCMCLI_MAKE_CMD_NOPARM(os_cli_dir, "sys", "System shell", _oscli_sys_handler); |
| 323 | #endif |
| 324 | |
| 325 | return BCM_ERR_OK; |
| 326 | } |
| 327 | |
| 328 | void bcmos_cli_exit(void) |
| 329 | { |
| 330 | if (os_cli_dir) |
| 331 | { |
| 332 | bcmcli_token_destroy(os_cli_dir); |
| 333 | os_cli_dir = NULL; |
| 334 | } |
| 335 | } |