13842bf24SAlan Carew /*- 23842bf24SAlan Carew * BSD LICENSE 33842bf24SAlan Carew * 43842bf24SAlan Carew * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 53842bf24SAlan Carew * All rights reserved. 63842bf24SAlan Carew * 73842bf24SAlan Carew * Redistribution and use in source and binary forms, with or without 83842bf24SAlan Carew * modification, are permitted provided that the following conditions 93842bf24SAlan Carew * are met: 103842bf24SAlan Carew * 113842bf24SAlan Carew * * Redistributions of source code must retain the above copyright 123842bf24SAlan Carew * notice, this list of conditions and the following disclaimer. 133842bf24SAlan Carew * * Redistributions in binary form must reproduce the above copyright 143842bf24SAlan Carew * notice, this list of conditions and the following disclaimer in 153842bf24SAlan Carew * the documentation and/or other materials provided with the 163842bf24SAlan Carew * distribution. 173842bf24SAlan Carew * * Neither the name of Intel Corporation nor the names of its 183842bf24SAlan Carew * contributors may be used to endorse or promote products derived 193842bf24SAlan Carew * from this software without specific prior written permission. 203842bf24SAlan Carew * 213842bf24SAlan Carew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 223842bf24SAlan Carew * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 233842bf24SAlan Carew * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 243842bf24SAlan Carew * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 253842bf24SAlan Carew * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 263842bf24SAlan Carew * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 273842bf24SAlan Carew * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 283842bf24SAlan Carew * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 293842bf24SAlan Carew * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 303842bf24SAlan Carew * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 313842bf24SAlan Carew * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 323842bf24SAlan Carew */ 333842bf24SAlan Carew 343842bf24SAlan Carew #include <stdlib.h> 353842bf24SAlan Carew #include <stdint.h> 363842bf24SAlan Carew #include <inttypes.h> 373842bf24SAlan Carew #include <stdio.h> 383842bf24SAlan Carew #include <string.h> 393842bf24SAlan Carew #include <termios.h> 403842bf24SAlan Carew #include <errno.h> 413842bf24SAlan Carew 423842bf24SAlan Carew #include <cmdline_rdline.h> 433842bf24SAlan Carew #include <cmdline_parse.h> 443842bf24SAlan Carew #include <cmdline_parse_string.h> 453842bf24SAlan Carew #include <cmdline_parse_num.h> 463842bf24SAlan Carew #include <cmdline_socket.h> 473842bf24SAlan Carew #include <cmdline.h> 483842bf24SAlan Carew #include <rte_config.h> 493842bf24SAlan Carew 503842bf24SAlan Carew #include "vm_power_cli.h" 513842bf24SAlan Carew #include "channel_manager.h" 523842bf24SAlan Carew #include "channel_monitor.h" 533842bf24SAlan Carew #include "power_manager.h" 543842bf24SAlan Carew #include "channel_commands.h" 553842bf24SAlan Carew 563842bf24SAlan Carew struct cmd_quit_result { 573842bf24SAlan Carew cmdline_fixed_string_t quit; 583842bf24SAlan Carew }; 593842bf24SAlan Carew 603842bf24SAlan Carew static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result, 613842bf24SAlan Carew struct cmdline *cl, 623842bf24SAlan Carew __attribute__((unused)) void *data) 633842bf24SAlan Carew { 643842bf24SAlan Carew channel_monitor_exit(); 653842bf24SAlan Carew channel_manager_exit(); 663842bf24SAlan Carew power_manager_exit(); 673842bf24SAlan Carew cmdline_quit(cl); 683842bf24SAlan Carew } 693842bf24SAlan Carew 703842bf24SAlan Carew cmdline_parse_token_string_t cmd_quit_quit = 713842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit"); 723842bf24SAlan Carew 733842bf24SAlan Carew cmdline_parse_inst_t cmd_quit = { 743842bf24SAlan Carew .f = cmd_quit_parsed, /* function to call */ 753842bf24SAlan Carew .data = NULL, /* 2nd arg of func */ 763842bf24SAlan Carew .help_str = "close the application", 773842bf24SAlan Carew .tokens = { /* token list, NULL terminated */ 783842bf24SAlan Carew (void *)&cmd_quit_quit, 793842bf24SAlan Carew NULL, 803842bf24SAlan Carew }, 813842bf24SAlan Carew }; 823842bf24SAlan Carew 833842bf24SAlan Carew /* *** VM operations *** */ 843842bf24SAlan Carew struct cmd_show_vm_result { 853842bf24SAlan Carew cmdline_fixed_string_t show_vm; 863842bf24SAlan Carew cmdline_fixed_string_t vm_name; 873842bf24SAlan Carew }; 883842bf24SAlan Carew 893842bf24SAlan Carew static void 903842bf24SAlan Carew cmd_show_vm_parsed(void *parsed_result, struct cmdline *cl, 913842bf24SAlan Carew __attribute__((unused)) void *data) 923842bf24SAlan Carew { 933842bf24SAlan Carew struct cmd_show_vm_result *res = parsed_result; 943842bf24SAlan Carew struct vm_info info; 953842bf24SAlan Carew unsigned i; 963842bf24SAlan Carew 973842bf24SAlan Carew if (get_info_vm(res->vm_name, &info) != 0) 983842bf24SAlan Carew return; 993842bf24SAlan Carew cmdline_printf(cl, "VM: '%s', status = ", info.name); 1003842bf24SAlan Carew if (info.status == CHANNEL_MGR_VM_ACTIVE) 1013842bf24SAlan Carew cmdline_printf(cl, "ACTIVE\n"); 1023842bf24SAlan Carew else 1033842bf24SAlan Carew cmdline_printf(cl, "INACTIVE\n"); 1043842bf24SAlan Carew cmdline_printf(cl, "Channels %u\n", info.num_channels); 1053842bf24SAlan Carew for (i = 0; i < info.num_channels; i++) { 1063842bf24SAlan Carew cmdline_printf(cl, " [%u]: %s, status = ", i, 1073842bf24SAlan Carew info.channels[i].channel_path); 1083842bf24SAlan Carew switch (info.channels[i].status) { 1093842bf24SAlan Carew case CHANNEL_MGR_CHANNEL_CONNECTED: 1103842bf24SAlan Carew cmdline_printf(cl, "CONNECTED\n"); 1113842bf24SAlan Carew break; 1123842bf24SAlan Carew case CHANNEL_MGR_CHANNEL_DISCONNECTED: 1133842bf24SAlan Carew cmdline_printf(cl, "DISCONNECTED\n"); 1143842bf24SAlan Carew break; 1153842bf24SAlan Carew case CHANNEL_MGR_CHANNEL_DISABLED: 1163842bf24SAlan Carew cmdline_printf(cl, "DISABLED\n"); 1173842bf24SAlan Carew break; 1183842bf24SAlan Carew case CHANNEL_MGR_CHANNEL_PROCESSING: 1193842bf24SAlan Carew cmdline_printf(cl, "PROCESSING\n"); 1203842bf24SAlan Carew break; 1213842bf24SAlan Carew default: 1223842bf24SAlan Carew cmdline_printf(cl, "UNKNOWN\n"); 1233842bf24SAlan Carew break; 1243842bf24SAlan Carew } 1253842bf24SAlan Carew } 1263842bf24SAlan Carew cmdline_printf(cl, "Virtual CPU(s): %u\n", info.num_vcpus); 1273842bf24SAlan Carew for (i = 0; i < info.num_vcpus; i++) { 1283842bf24SAlan Carew cmdline_printf(cl, " [%u]: Physical CPU Mask 0x%"PRIx64"\n", i, 1293842bf24SAlan Carew info.pcpu_mask[i]); 1303842bf24SAlan Carew } 1313842bf24SAlan Carew } 1323842bf24SAlan Carew 1333842bf24SAlan Carew 1343842bf24SAlan Carew 1353842bf24SAlan Carew cmdline_parse_token_string_t cmd_vm_show = 1363842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result, 1373842bf24SAlan Carew show_vm, "show_vm"); 1383842bf24SAlan Carew cmdline_parse_token_string_t cmd_show_vm_name = 1393842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result, 1403842bf24SAlan Carew vm_name, NULL); 1413842bf24SAlan Carew 1423842bf24SAlan Carew cmdline_parse_inst_t cmd_show_vm_set = { 1433842bf24SAlan Carew .f = cmd_show_vm_parsed, 1443842bf24SAlan Carew .data = NULL, 1453842bf24SAlan Carew .help_str = "show_vm <vm_name>, prints the information on the " 1463842bf24SAlan Carew "specified VM(s), the information lists the number of vCPUS, the " 1473842bf24SAlan Carew "pinning to pCPU(s) as a bit mask, along with any communication " 1483842bf24SAlan Carew "channels associated with each VM", 1493842bf24SAlan Carew .tokens = { 1503842bf24SAlan Carew (void *)&cmd_vm_show, 1513842bf24SAlan Carew (void *)&cmd_show_vm_name, 1523842bf24SAlan Carew NULL, 1533842bf24SAlan Carew }, 1543842bf24SAlan Carew }; 1553842bf24SAlan Carew 1563842bf24SAlan Carew /* *** vCPU to pCPU mapping operations *** */ 1573842bf24SAlan Carew struct cmd_set_pcpu_mask_result { 1583842bf24SAlan Carew cmdline_fixed_string_t set_pcpu_mask; 1593842bf24SAlan Carew cmdline_fixed_string_t vm_name; 1603842bf24SAlan Carew uint8_t vcpu; 1613842bf24SAlan Carew uint64_t core_mask; 1623842bf24SAlan Carew }; 1633842bf24SAlan Carew 1643842bf24SAlan Carew static void 1653842bf24SAlan Carew cmd_set_pcpu_mask_parsed(void *parsed_result, struct cmdline *cl, 1663842bf24SAlan Carew __attribute__((unused)) void *data) 1673842bf24SAlan Carew { 1683842bf24SAlan Carew struct cmd_set_pcpu_mask_result *res = parsed_result; 1693842bf24SAlan Carew 1703842bf24SAlan Carew if (set_pcpus_mask(res->vm_name, res->vcpu, res->core_mask) == 0) 1713842bf24SAlan Carew cmdline_printf(cl, "Pinned vCPU(%"PRId8") to pCPU core " 1723842bf24SAlan Carew "mask(0x%"PRIx64")\n", res->vcpu, res->core_mask); 1733842bf24SAlan Carew else 1743842bf24SAlan Carew cmdline_printf(cl, "Unable to pin vCPU(%"PRId8") to pCPU core " 1753842bf24SAlan Carew "mask(0x%"PRIx64")\n", res->vcpu, res->core_mask); 1763842bf24SAlan Carew } 1773842bf24SAlan Carew 1783842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu_mask = 1793842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_mask_result, 1803842bf24SAlan Carew set_pcpu_mask, "set_pcpu_mask"); 1813842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu_mask_vm_name = 1823842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_mask_result, 1833842bf24SAlan Carew vm_name, NULL); 1843842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_mask_vcpu = 1853842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_mask_result, 1863842bf24SAlan Carew vcpu, UINT8); 1873842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_mask_core_mask = 1883842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_mask_result, 1893842bf24SAlan Carew core_mask, UINT64); 1903842bf24SAlan Carew 1913842bf24SAlan Carew 1923842bf24SAlan Carew cmdline_parse_inst_t cmd_set_pcpu_mask_set = { 1933842bf24SAlan Carew .f = cmd_set_pcpu_mask_parsed, 1943842bf24SAlan Carew .data = NULL, 1953842bf24SAlan Carew .help_str = "set_pcpu_mask <vm_name> <vcpu> <pcpu>, Set the binding " 1963842bf24SAlan Carew "of Virtual CPU on VM to the Physical CPU mask.", 1973842bf24SAlan Carew .tokens = { 1983842bf24SAlan Carew (void *)&cmd_set_pcpu_mask, 1993842bf24SAlan Carew (void *)&cmd_set_pcpu_mask_vm_name, 2003842bf24SAlan Carew (void *)&set_pcpu_mask_vcpu, 2013842bf24SAlan Carew (void *)&set_pcpu_mask_core_mask, 2023842bf24SAlan Carew NULL, 2033842bf24SAlan Carew }, 2043842bf24SAlan Carew }; 2053842bf24SAlan Carew 2063842bf24SAlan Carew struct cmd_set_pcpu_result { 2073842bf24SAlan Carew cmdline_fixed_string_t set_pcpu; 2083842bf24SAlan Carew cmdline_fixed_string_t vm_name; 2093842bf24SAlan Carew uint8_t vcpu; 2103842bf24SAlan Carew uint8_t core; 2113842bf24SAlan Carew }; 2123842bf24SAlan Carew 2133842bf24SAlan Carew static void 2143842bf24SAlan Carew cmd_set_pcpu_parsed(void *parsed_result, struct cmdline *cl, 2153842bf24SAlan Carew __attribute__((unused)) void *data) 2163842bf24SAlan Carew { 2173842bf24SAlan Carew struct cmd_set_pcpu_result *res = parsed_result; 2183842bf24SAlan Carew 2193842bf24SAlan Carew if (set_pcpu(res->vm_name, res->vcpu, res->core) == 0) 2203842bf24SAlan Carew cmdline_printf(cl, "Pinned vCPU(%"PRId8") to pCPU core " 2213842bf24SAlan Carew "%"PRId8")\n", res->vcpu, res->core); 2223842bf24SAlan Carew else 2233842bf24SAlan Carew cmdline_printf(cl, "Unable to pin vCPU(%"PRId8") to pCPU core " 2243842bf24SAlan Carew "%"PRId8")\n", res->vcpu, res->core); 2253842bf24SAlan Carew } 2263842bf24SAlan Carew 2273842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu = 2283842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result, 2293842bf24SAlan Carew set_pcpu, "set_pcpu"); 2303842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu_vm_name = 2313842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result, 2323842bf24SAlan Carew vm_name, NULL); 2333842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_vcpu = 2343842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result, 2353842bf24SAlan Carew vcpu, UINT8); 2363842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_core = 2373842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result, 2383842bf24SAlan Carew core, UINT64); 2393842bf24SAlan Carew 2403842bf24SAlan Carew 2413842bf24SAlan Carew cmdline_parse_inst_t cmd_set_pcpu_set = { 2423842bf24SAlan Carew .f = cmd_set_pcpu_parsed, 2433842bf24SAlan Carew .data = NULL, 2443842bf24SAlan Carew .help_str = "set_pcpu <vm_name> <vcpu> <pcpu>, Set the binding " 2453842bf24SAlan Carew "of Virtual CPU on VM to the Physical CPU.", 2463842bf24SAlan Carew .tokens = { 2473842bf24SAlan Carew (void *)&cmd_set_pcpu, 2483842bf24SAlan Carew (void *)&cmd_set_pcpu_vm_name, 2493842bf24SAlan Carew (void *)&set_pcpu_vcpu, 2503842bf24SAlan Carew (void *)&set_pcpu_core, 2513842bf24SAlan Carew NULL, 2523842bf24SAlan Carew }, 2533842bf24SAlan Carew }; 2543842bf24SAlan Carew 2553842bf24SAlan Carew struct cmd_vm_op_result { 2563842bf24SAlan Carew cmdline_fixed_string_t op_vm; 2573842bf24SAlan Carew cmdline_fixed_string_t vm_name; 2583842bf24SAlan Carew }; 2593842bf24SAlan Carew 2603842bf24SAlan Carew static void 2613842bf24SAlan Carew cmd_vm_op_parsed(void *parsed_result, struct cmdline *cl, 2623842bf24SAlan Carew __attribute__((unused)) void *data) 2633842bf24SAlan Carew { 2643842bf24SAlan Carew struct cmd_vm_op_result *res = parsed_result; 2653842bf24SAlan Carew 2663842bf24SAlan Carew if (!strcmp(res->op_vm, "add_vm")) { 2673842bf24SAlan Carew if (add_vm(res->vm_name) < 0) 2683842bf24SAlan Carew cmdline_printf(cl, "Unable to add VM '%s'\n", res->vm_name); 2693842bf24SAlan Carew } else if (remove_vm(res->vm_name) < 0) 2703842bf24SAlan Carew cmdline_printf(cl, "Unable to remove VM '%s'\n", res->vm_name); 2713842bf24SAlan Carew } 2723842bf24SAlan Carew 2733842bf24SAlan Carew cmdline_parse_token_string_t cmd_vm_op = 2743842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result, 2753842bf24SAlan Carew op_vm, "add_vm#rm_vm"); 2763842bf24SAlan Carew cmdline_parse_token_string_t cmd_vm_name = 2773842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result, 2783842bf24SAlan Carew vm_name, NULL); 2793842bf24SAlan Carew 2803842bf24SAlan Carew cmdline_parse_inst_t cmd_vm_op_set = { 2813842bf24SAlan Carew .f = cmd_vm_op_parsed, 2823842bf24SAlan Carew .data = NULL, 2833842bf24SAlan Carew .help_str = "add_vm|rm_vm <name>, add a VM for " 2843842bf24SAlan Carew "subsequent operations with the CLI or remove a previously added " 2853842bf24SAlan Carew "VM from the VM Power Manager", 2863842bf24SAlan Carew .tokens = { 2873842bf24SAlan Carew (void *)&cmd_vm_op, 2883842bf24SAlan Carew (void *)&cmd_vm_name, 2893842bf24SAlan Carew NULL, 2903842bf24SAlan Carew }, 2913842bf24SAlan Carew }; 2923842bf24SAlan Carew 2933842bf24SAlan Carew /* *** VM channel operations *** */ 2943842bf24SAlan Carew struct cmd_channels_op_result { 2953842bf24SAlan Carew cmdline_fixed_string_t op; 2963842bf24SAlan Carew cmdline_fixed_string_t vm_name; 2973842bf24SAlan Carew cmdline_fixed_string_t channel_list; 2983842bf24SAlan Carew }; 2993842bf24SAlan Carew static void 3003842bf24SAlan Carew cmd_channels_op_parsed(void *parsed_result, struct cmdline *cl, 3013842bf24SAlan Carew __attribute__((unused)) void *data) 3023842bf24SAlan Carew { 3033842bf24SAlan Carew unsigned num_channels = 0, channel_num, i; 3043842bf24SAlan Carew int channels_added; 3053842bf24SAlan Carew unsigned channel_list[CHANNEL_CMDS_MAX_VM_CHANNELS]; 3063842bf24SAlan Carew char *token, *remaining, *tail_ptr; 3073842bf24SAlan Carew struct cmd_channels_op_result *res = parsed_result; 3083842bf24SAlan Carew 3093842bf24SAlan Carew if (!strcmp(res->channel_list, "all")) { 3103842bf24SAlan Carew channels_added = add_all_channels(res->vm_name); 3113842bf24SAlan Carew cmdline_printf(cl, "Added %d channels for VM '%s'\n", 3123842bf24SAlan Carew channels_added, res->vm_name); 3133842bf24SAlan Carew return; 3143842bf24SAlan Carew } 3153842bf24SAlan Carew 3163842bf24SAlan Carew remaining = res->channel_list; 3173842bf24SAlan Carew while (1) { 3183842bf24SAlan Carew if (remaining == NULL || remaining[0] == '\0') 3193842bf24SAlan Carew break; 3203842bf24SAlan Carew 3213842bf24SAlan Carew token = strsep(&remaining, ","); 3223842bf24SAlan Carew if (token == NULL) 3233842bf24SAlan Carew break; 3243842bf24SAlan Carew errno = 0; 3253842bf24SAlan Carew channel_num = (unsigned)strtol(token, &tail_ptr, 10); 3265b628fe1SBruce Richardson if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0')) 3273842bf24SAlan Carew break; 3283842bf24SAlan Carew 3293842bf24SAlan Carew if (channel_num == CHANNEL_CMDS_MAX_VM_CHANNELS) { 3303842bf24SAlan Carew cmdline_printf(cl, "Channel number '%u' exceeds the maximum number " 3313842bf24SAlan Carew "of allowable channels(%u) for VM '%s'\n", channel_num, 3323842bf24SAlan Carew CHANNEL_CMDS_MAX_VM_CHANNELS, res->vm_name); 3333842bf24SAlan Carew return; 3343842bf24SAlan Carew } 3353842bf24SAlan Carew channel_list[num_channels++] = channel_num; 3363842bf24SAlan Carew } 3373842bf24SAlan Carew for (i = 0; i < num_channels; i++) 3383842bf24SAlan Carew cmdline_printf(cl, "[%u]: Adding channel %u\n", i, channel_list[i]); 3393842bf24SAlan Carew 3403842bf24SAlan Carew channels_added = add_channels(res->vm_name, channel_list, 3413842bf24SAlan Carew num_channels); 3423842bf24SAlan Carew cmdline_printf(cl, "Enabled %d channels for '%s'\n", channels_added, 3433842bf24SAlan Carew res->vm_name); 3443842bf24SAlan Carew } 3453842bf24SAlan Carew 3463842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_op = 3473842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result, 3483842bf24SAlan Carew op, "add_channels"); 3493842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_vm_name = 3503842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result, 3513842bf24SAlan Carew vm_name, NULL); 3523842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_list = 3533842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result, 3543842bf24SAlan Carew channel_list, NULL); 3553842bf24SAlan Carew 3563842bf24SAlan Carew cmdline_parse_inst_t cmd_channels_op_set = { 3573842bf24SAlan Carew .f = cmd_channels_op_parsed, 3583842bf24SAlan Carew .data = NULL, 3593842bf24SAlan Carew .help_str = "add_channels <vm_name> <list>|all, add " 3603842bf24SAlan Carew "communication channels for the specified VM, the " 3613842bf24SAlan Carew "virtio channels must be enabled in the VM " 3623842bf24SAlan Carew "configuration(qemu/libvirt) and the associated VM must be active. " 3633842bf24SAlan Carew "<list> is a comma-separated list of channel numbers to add, using " 3643842bf24SAlan Carew "the keyword 'all' will attempt to add all channels for the VM", 3653842bf24SAlan Carew .tokens = { 3663842bf24SAlan Carew (void *)&cmd_channels_op, 3673842bf24SAlan Carew (void *)&cmd_channels_vm_name, 3683842bf24SAlan Carew (void *)&cmd_channels_list, 3693842bf24SAlan Carew NULL, 3703842bf24SAlan Carew }, 3713842bf24SAlan Carew }; 3723842bf24SAlan Carew 3733842bf24SAlan Carew struct cmd_channels_status_op_result { 3743842bf24SAlan Carew cmdline_fixed_string_t op; 3753842bf24SAlan Carew cmdline_fixed_string_t vm_name; 3763842bf24SAlan Carew cmdline_fixed_string_t channel_list; 3773842bf24SAlan Carew cmdline_fixed_string_t status; 3783842bf24SAlan Carew }; 3793842bf24SAlan Carew 3803842bf24SAlan Carew static void 3813842bf24SAlan Carew cmd_channels_status_op_parsed(void *parsed_result, struct cmdline *cl, 3823842bf24SAlan Carew __attribute__((unused)) void *data) 3833842bf24SAlan Carew { 3843842bf24SAlan Carew unsigned num_channels = 0, channel_num; 3853842bf24SAlan Carew int changed; 3863842bf24SAlan Carew unsigned channel_list[CHANNEL_CMDS_MAX_VM_CHANNELS]; 3873842bf24SAlan Carew char *token, *remaining, *tail_ptr; 3883842bf24SAlan Carew struct cmd_channels_status_op_result *res = parsed_result; 3893842bf24SAlan Carew enum channel_status status; 3903842bf24SAlan Carew 3913842bf24SAlan Carew if (!strcmp(res->status, "enabled")) 3923842bf24SAlan Carew status = CHANNEL_MGR_CHANNEL_CONNECTED; 3933842bf24SAlan Carew else 3943842bf24SAlan Carew status = CHANNEL_MGR_CHANNEL_DISABLED; 3953842bf24SAlan Carew 3963842bf24SAlan Carew if (!strcmp(res->channel_list, "all")) { 3973842bf24SAlan Carew changed = set_channel_status_all(res->vm_name, status); 3983842bf24SAlan Carew cmdline_printf(cl, "Updated status of %d channels " 3993842bf24SAlan Carew "for VM '%s'\n", changed, res->vm_name); 4003842bf24SAlan Carew return; 4013842bf24SAlan Carew } 4023842bf24SAlan Carew remaining = res->channel_list; 4033842bf24SAlan Carew while (1) { 4043842bf24SAlan Carew if (remaining == NULL || remaining[0] == '\0') 4053842bf24SAlan Carew break; 4063842bf24SAlan Carew token = strsep(&remaining, ","); 4073842bf24SAlan Carew if (token == NULL) 4083842bf24SAlan Carew break; 4093842bf24SAlan Carew errno = 0; 4103842bf24SAlan Carew channel_num = (unsigned)strtol(token, &tail_ptr, 10); 4115b628fe1SBruce Richardson if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0')) 4123842bf24SAlan Carew break; 4133842bf24SAlan Carew 4143842bf24SAlan Carew if (channel_num == CHANNEL_CMDS_MAX_VM_CHANNELS) { 4153842bf24SAlan Carew cmdline_printf(cl, "%u exceeds the maximum number of allowable " 4163842bf24SAlan Carew "channels(%u) for VM '%s'\n", channel_num, 4173842bf24SAlan Carew CHANNEL_CMDS_MAX_VM_CHANNELS, res->vm_name); 4183842bf24SAlan Carew return; 4193842bf24SAlan Carew } 4203842bf24SAlan Carew channel_list[num_channels++] = channel_num; 4213842bf24SAlan Carew } 4223842bf24SAlan Carew changed = set_channel_status(res->vm_name, channel_list, num_channels, 4233842bf24SAlan Carew status); 4243842bf24SAlan Carew cmdline_printf(cl, "Updated status of %d channels " 4253842bf24SAlan Carew "for VM '%s'\n", changed, res->vm_name); 4263842bf24SAlan Carew } 4273842bf24SAlan Carew 4283842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status_op = 4293842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result, 4303842bf24SAlan Carew op, "set_channel_status"); 4313842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status_vm_name = 4323842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result, 4333842bf24SAlan Carew vm_name, NULL); 4343842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status_list = 4353842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result, 4363842bf24SAlan Carew channel_list, NULL); 4373842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status = 4383842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result, 4393842bf24SAlan Carew status, "enabled#disabled"); 4403842bf24SAlan Carew 4413842bf24SAlan Carew cmdline_parse_inst_t cmd_channels_status_op_set = { 4423842bf24SAlan Carew .f = cmd_channels_status_op_parsed, 4433842bf24SAlan Carew .data = NULL, 4443842bf24SAlan Carew .help_str = "set_channel_status <vm_name> <list>|all enabled|disabled, " 4453842bf24SAlan Carew " enable or disable the communication channels in " 4463842bf24SAlan Carew "list(comma-separated) for the specified VM, alternatively " 4473842bf24SAlan Carew "list can be replaced with keyword 'all'. " 4483842bf24SAlan Carew "Disabled channels will still receive packets on the host, " 4493842bf24SAlan Carew "however the commands they specify will be ignored. " 4503842bf24SAlan Carew "Set status to 'enabled' to begin processing requests again.", 4513842bf24SAlan Carew .tokens = { 4523842bf24SAlan Carew (void *)&cmd_channels_status_op, 4533842bf24SAlan Carew (void *)&cmd_channels_status_vm_name, 4543842bf24SAlan Carew (void *)&cmd_channels_status_list, 4553842bf24SAlan Carew (void *)&cmd_channels_status, 4563842bf24SAlan Carew NULL, 4573842bf24SAlan Carew }, 4583842bf24SAlan Carew }; 4593842bf24SAlan Carew 4603842bf24SAlan Carew /* *** CPU Frequency operations *** */ 4613842bf24SAlan Carew struct cmd_show_cpu_freq_mask_result { 4623842bf24SAlan Carew cmdline_fixed_string_t show_cpu_freq_mask; 4633842bf24SAlan Carew uint64_t core_mask; 4643842bf24SAlan Carew }; 4653842bf24SAlan Carew 4663842bf24SAlan Carew static void 4673842bf24SAlan Carew cmd_show_cpu_freq_mask_parsed(void *parsed_result, struct cmdline *cl, 4683842bf24SAlan Carew __attribute__((unused)) void *data) 4693842bf24SAlan Carew { 4703842bf24SAlan Carew struct cmd_show_cpu_freq_mask_result *res = parsed_result; 4713842bf24SAlan Carew unsigned i; 4723842bf24SAlan Carew uint64_t mask = res->core_mask; 4733842bf24SAlan Carew uint32_t freq; 4743842bf24SAlan Carew 4753842bf24SAlan Carew for (i = 0; mask; mask &= ~(1ULL << i++)) { 4763842bf24SAlan Carew if ((mask >> i) & 1) { 4773842bf24SAlan Carew freq = power_manager_get_current_frequency(i); 4783842bf24SAlan Carew if (freq > 0) 4793842bf24SAlan Carew cmdline_printf(cl, "Core %u: %"PRId32"\n", i, freq); 4803842bf24SAlan Carew } 4813842bf24SAlan Carew } 4823842bf24SAlan Carew } 4833842bf24SAlan Carew 4843842bf24SAlan Carew cmdline_parse_token_string_t cmd_show_cpu_freq_mask = 4853842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_show_cpu_freq_mask_result, 4863842bf24SAlan Carew show_cpu_freq_mask, "show_cpu_freq_mask"); 4873842bf24SAlan Carew cmdline_parse_token_num_t cmd_show_cpu_freq_mask_core_mask = 4883842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_show_cpu_freq_mask_result, 4893842bf24SAlan Carew core_mask, UINT64); 4903842bf24SAlan Carew 4913842bf24SAlan Carew cmdline_parse_inst_t cmd_show_cpu_freq_mask_set = { 4923842bf24SAlan Carew .f = cmd_show_cpu_freq_mask_parsed, 4933842bf24SAlan Carew .data = NULL, 4943842bf24SAlan Carew .help_str = "show_cpu_freq_mask <mask>, Get the current frequency for each " 4953842bf24SAlan Carew "core specified in the mask", 4963842bf24SAlan Carew .tokens = { 4973842bf24SAlan Carew (void *)&cmd_show_cpu_freq_mask, 4983842bf24SAlan Carew (void *)&cmd_show_cpu_freq_mask_core_mask, 4993842bf24SAlan Carew NULL, 5003842bf24SAlan Carew }, 5013842bf24SAlan Carew }; 5023842bf24SAlan Carew 5033842bf24SAlan Carew struct cmd_set_cpu_freq_mask_result { 5043842bf24SAlan Carew cmdline_fixed_string_t set_cpu_freq_mask; 5053842bf24SAlan Carew uint64_t core_mask; 5063842bf24SAlan Carew cmdline_fixed_string_t cmd; 5073842bf24SAlan Carew }; 5083842bf24SAlan Carew 5093842bf24SAlan Carew static void 5103842bf24SAlan Carew cmd_set_cpu_freq_mask_parsed(void *parsed_result, struct cmdline *cl, 5113842bf24SAlan Carew __attribute__((unused)) void *data) 5123842bf24SAlan Carew { 5133842bf24SAlan Carew struct cmd_set_cpu_freq_mask_result *res = parsed_result; 5143842bf24SAlan Carew int ret = -1; 5153842bf24SAlan Carew 5163842bf24SAlan Carew if (!strcmp(res->cmd , "up")) 5173842bf24SAlan Carew ret = power_manager_scale_mask_up(res->core_mask); 5183842bf24SAlan Carew else if (!strcmp(res->cmd , "down")) 5193842bf24SAlan Carew ret = power_manager_scale_mask_down(res->core_mask); 5203842bf24SAlan Carew else if (!strcmp(res->cmd , "min")) 5213842bf24SAlan Carew ret = power_manager_scale_mask_min(res->core_mask); 5223842bf24SAlan Carew else if (!strcmp(res->cmd , "max")) 5233842bf24SAlan Carew ret = power_manager_scale_mask_max(res->core_mask); 5243842bf24SAlan Carew if (ret < 0) { 5253842bf24SAlan Carew cmdline_printf(cl, "Error scaling core_mask(0x%"PRIx64") '%s' , not " 5263842bf24SAlan Carew "all cores specified have been scaled\n", 5273842bf24SAlan Carew res->core_mask, res->cmd); 5283842bf24SAlan Carew }; 5293842bf24SAlan Carew } 5303842bf24SAlan Carew 5313842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq_mask = 5323842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_mask_result, 5333842bf24SAlan Carew set_cpu_freq_mask, "set_cpu_freq_mask"); 5343842bf24SAlan Carew cmdline_parse_token_num_t cmd_set_cpu_freq_mask_core_mask = 5353842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_set_cpu_freq_mask_result, 5363842bf24SAlan Carew core_mask, UINT64); 5373842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq_mask_result = 5383842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_mask_result, 5393842bf24SAlan Carew cmd, "up#down#min#max"); 5403842bf24SAlan Carew 5413842bf24SAlan Carew cmdline_parse_inst_t cmd_set_cpu_freq_mask_set = { 5423842bf24SAlan Carew .f = cmd_set_cpu_freq_mask_parsed, 5433842bf24SAlan Carew .data = NULL, 5443842bf24SAlan Carew .help_str = "set_cpu_freq <core_mask> <up|down|min|max>, Set the current " 5453842bf24SAlan Carew "frequency for the cores specified in <core_mask> by scaling " 5463842bf24SAlan Carew "each up/down/min/max.", 5473842bf24SAlan Carew .tokens = { 5483842bf24SAlan Carew (void *)&cmd_set_cpu_freq_mask, 5493842bf24SAlan Carew (void *)&cmd_set_cpu_freq_mask_core_mask, 5503842bf24SAlan Carew (void *)&cmd_set_cpu_freq_mask_result, 5513842bf24SAlan Carew NULL, 5523842bf24SAlan Carew }, 5533842bf24SAlan Carew }; 5543842bf24SAlan Carew 5553842bf24SAlan Carew 5563842bf24SAlan Carew 5573842bf24SAlan Carew struct cmd_show_cpu_freq_result { 5583842bf24SAlan Carew cmdline_fixed_string_t show_cpu_freq; 5593842bf24SAlan Carew uint8_t core_num; 5603842bf24SAlan Carew }; 5613842bf24SAlan Carew 5623842bf24SAlan Carew static void 5633842bf24SAlan Carew cmd_show_cpu_freq_parsed(void *parsed_result, struct cmdline *cl, 5643842bf24SAlan Carew __attribute__((unused)) void *data) 5653842bf24SAlan Carew { 5663842bf24SAlan Carew struct cmd_show_cpu_freq_result *res = parsed_result; 5673842bf24SAlan Carew uint32_t curr_freq = power_manager_get_current_frequency(res->core_num); 5683842bf24SAlan Carew 5693842bf24SAlan Carew if (curr_freq == 0) { 5703842bf24SAlan Carew cmdline_printf(cl, "Unable to get frequency for core %u\n", 5713842bf24SAlan Carew res->core_num); 5723842bf24SAlan Carew return; 5733842bf24SAlan Carew } 5743842bf24SAlan Carew cmdline_printf(cl, "Core %u frequency: %"PRId32"\n", res->core_num, 5753842bf24SAlan Carew curr_freq); 5763842bf24SAlan Carew } 5773842bf24SAlan Carew 5783842bf24SAlan Carew cmdline_parse_token_string_t cmd_show_cpu_freq = 5793842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_show_cpu_freq_result, 5803842bf24SAlan Carew show_cpu_freq, "show_cpu_freq"); 5813842bf24SAlan Carew 5823842bf24SAlan Carew cmdline_parse_token_num_t cmd_show_cpu_freq_core_num = 5833842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_show_cpu_freq_result, 5843842bf24SAlan Carew core_num, UINT8); 5853842bf24SAlan Carew 5863842bf24SAlan Carew cmdline_parse_inst_t cmd_show_cpu_freq_set = { 5873842bf24SAlan Carew .f = cmd_show_cpu_freq_parsed, 5883842bf24SAlan Carew .data = NULL, 5893842bf24SAlan Carew .help_str = "Get the current frequency for the specified core", 5903842bf24SAlan Carew .tokens = { 5913842bf24SAlan Carew (void *)&cmd_show_cpu_freq, 5923842bf24SAlan Carew (void *)&cmd_show_cpu_freq_core_num, 5933842bf24SAlan Carew NULL, 5943842bf24SAlan Carew }, 5953842bf24SAlan Carew }; 5963842bf24SAlan Carew 5973842bf24SAlan Carew struct cmd_set_cpu_freq_result { 5983842bf24SAlan Carew cmdline_fixed_string_t set_cpu_freq; 5993842bf24SAlan Carew uint8_t core_num; 6003842bf24SAlan Carew cmdline_fixed_string_t cmd; 6013842bf24SAlan Carew }; 6023842bf24SAlan Carew 6033842bf24SAlan Carew static void 6043842bf24SAlan Carew cmd_set_cpu_freq_parsed(void *parsed_result, struct cmdline *cl, 6053842bf24SAlan Carew __attribute__((unused)) void *data) 6063842bf24SAlan Carew { 6073842bf24SAlan Carew int ret = -1; 6083842bf24SAlan Carew struct cmd_set_cpu_freq_result *res = parsed_result; 6093842bf24SAlan Carew 6103842bf24SAlan Carew if (!strcmp(res->cmd , "up")) 6113842bf24SAlan Carew ret = power_manager_scale_core_up(res->core_num); 6123842bf24SAlan Carew else if (!strcmp(res->cmd , "down")) 6133842bf24SAlan Carew ret = power_manager_scale_core_down(res->core_num); 6143842bf24SAlan Carew else if (!strcmp(res->cmd , "min")) 6153842bf24SAlan Carew ret = power_manager_scale_core_min(res->core_num); 6163842bf24SAlan Carew else if (!strcmp(res->cmd , "max")) 6173842bf24SAlan Carew ret = power_manager_scale_core_max(res->core_num); 6183842bf24SAlan Carew if (ret < 0) { 6193842bf24SAlan Carew cmdline_printf(cl, "Error scaling core(%u) '%s'\n", res->core_num, 6203842bf24SAlan Carew res->cmd); 6213842bf24SAlan Carew } 6223842bf24SAlan Carew } 6233842bf24SAlan Carew 6243842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq = 6253842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result, 6263842bf24SAlan Carew set_cpu_freq, "set_cpu_freq"); 627*b68bc0b8SOlivier Matz cmdline_parse_token_num_t cmd_set_cpu_freq_core_num = 6283842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_set_cpu_freq_result, 6293842bf24SAlan Carew core_num, UINT8); 6303842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq_cmd_cmd = 6313842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result, 6323842bf24SAlan Carew cmd, "up#down#min#max"); 6333842bf24SAlan Carew 6343842bf24SAlan Carew cmdline_parse_inst_t cmd_set_cpu_freq_set = { 6353842bf24SAlan Carew .f = cmd_set_cpu_freq_parsed, 6363842bf24SAlan Carew .data = NULL, 6373842bf24SAlan Carew .help_str = "set_cpu_freq <core_num> <up|down|min|max>, Set the current " 6383842bf24SAlan Carew "frequency for the specified core by scaling up/down/min/max", 6393842bf24SAlan Carew .tokens = { 6403842bf24SAlan Carew (void *)&cmd_set_cpu_freq, 6413842bf24SAlan Carew (void *)&cmd_set_cpu_freq_core_num, 6423842bf24SAlan Carew (void *)&cmd_set_cpu_freq_cmd_cmd, 6433842bf24SAlan Carew NULL, 6443842bf24SAlan Carew }, 6453842bf24SAlan Carew }; 6463842bf24SAlan Carew 6473842bf24SAlan Carew cmdline_parse_ctx_t main_ctx[] = { 6483842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_quit, 6493842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_vm_op_set, 6503842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_channels_op_set, 6513842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_channels_status_op_set, 6523842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_show_vm_set, 6533842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_show_cpu_freq_mask_set, 6543842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_set_cpu_freq_mask_set, 6553842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_show_cpu_freq_set, 6563842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_set_cpu_freq_set, 6573842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_set_pcpu_mask_set, 6583842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_set_pcpu_set, 6593842bf24SAlan Carew NULL, 6603842bf24SAlan Carew }; 6613842bf24SAlan Carew 6623842bf24SAlan Carew void 6633842bf24SAlan Carew run_cli(__attribute__((unused)) void *arg) 6643842bf24SAlan Carew { 6653842bf24SAlan Carew struct cmdline *cl; 6663842bf24SAlan Carew 6673842bf24SAlan Carew cl = cmdline_stdin_new(main_ctx, "vmpower> "); 6683842bf24SAlan Carew if (cl == NULL) 6693842bf24SAlan Carew return; 6703842bf24SAlan Carew 6713842bf24SAlan Carew cmdline_interact(cl); 6723842bf24SAlan Carew cmdline_stdin_exit(cl); 6733842bf24SAlan Carew } 674