1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606 * Copyright(c) 2010-2014 Intel Corporation
3a9643ea8Slogwang */
4a9643ea8Slogwang
5a9643ea8Slogwang #include <stdlib.h>
6a9643ea8Slogwang #include <stdint.h>
7a9643ea8Slogwang #include <inttypes.h>
8a9643ea8Slogwang #include <stdio.h>
9a9643ea8Slogwang #include <string.h>
10a9643ea8Slogwang #include <termios.h>
11a9643ea8Slogwang #include <errno.h>
12a9643ea8Slogwang
13a9643ea8Slogwang #include <cmdline_rdline.h>
14a9643ea8Slogwang #include <cmdline_parse.h>
15a9643ea8Slogwang #include <cmdline_parse_string.h>
16a9643ea8Slogwang #include <cmdline_parse_num.h>
17a9643ea8Slogwang #include <cmdline_socket.h>
18a9643ea8Slogwang #include <cmdline.h>
19a9643ea8Slogwang
20a9643ea8Slogwang #include "vm_power_cli.h"
21a9643ea8Slogwang #include "channel_manager.h"
22a9643ea8Slogwang #include "channel_monitor.h"
23a9643ea8Slogwang #include "power_manager.h"
24a9643ea8Slogwang #include "channel_commands.h"
25a9643ea8Slogwang
26a9643ea8Slogwang struct cmd_quit_result {
27a9643ea8Slogwang cmdline_fixed_string_t quit;
28a9643ea8Slogwang };
29a9643ea8Slogwang
cmd_quit_parsed(__rte_unused void * parsed_result,struct cmdline * cl,__rte_unused void * data)30*2d9fd380Sjfb8856606 static void cmd_quit_parsed(__rte_unused void *parsed_result,
31a9643ea8Slogwang struct cmdline *cl,
32*2d9fd380Sjfb8856606 __rte_unused void *data)
33a9643ea8Slogwang {
34a9643ea8Slogwang channel_monitor_exit();
35a9643ea8Slogwang channel_manager_exit();
36a9643ea8Slogwang power_manager_exit();
37a9643ea8Slogwang cmdline_quit(cl);
38a9643ea8Slogwang }
39a9643ea8Slogwang
40a9643ea8Slogwang cmdline_parse_token_string_t cmd_quit_quit =
41a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
42a9643ea8Slogwang
43a9643ea8Slogwang cmdline_parse_inst_t cmd_quit = {
44a9643ea8Slogwang .f = cmd_quit_parsed, /* function to call */
45a9643ea8Slogwang .data = NULL, /* 2nd arg of func */
46a9643ea8Slogwang .help_str = "close the application",
47a9643ea8Slogwang .tokens = { /* token list, NULL terminated */
48a9643ea8Slogwang (void *)&cmd_quit_quit,
49a9643ea8Slogwang NULL,
50a9643ea8Slogwang },
51a9643ea8Slogwang };
52a9643ea8Slogwang
53a9643ea8Slogwang /* *** VM operations *** */
54a9643ea8Slogwang struct cmd_show_vm_result {
55a9643ea8Slogwang cmdline_fixed_string_t show_vm;
56a9643ea8Slogwang cmdline_fixed_string_t vm_name;
57a9643ea8Slogwang };
58a9643ea8Slogwang
59a9643ea8Slogwang static void
cmd_show_vm_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)60a9643ea8Slogwang cmd_show_vm_parsed(void *parsed_result, struct cmdline *cl,
61*2d9fd380Sjfb8856606 __rte_unused void *data)
62a9643ea8Slogwang {
63a9643ea8Slogwang struct cmd_show_vm_result *res = parsed_result;
64a9643ea8Slogwang struct vm_info info;
65a9643ea8Slogwang unsigned i;
66a9643ea8Slogwang
67a9643ea8Slogwang if (get_info_vm(res->vm_name, &info) != 0)
68a9643ea8Slogwang return;
69a9643ea8Slogwang cmdline_printf(cl, "VM: '%s', status = ", info.name);
70a9643ea8Slogwang if (info.status == CHANNEL_MGR_VM_ACTIVE)
71a9643ea8Slogwang cmdline_printf(cl, "ACTIVE\n");
72a9643ea8Slogwang else
73a9643ea8Slogwang cmdline_printf(cl, "INACTIVE\n");
74a9643ea8Slogwang cmdline_printf(cl, "Channels %u\n", info.num_channels);
75a9643ea8Slogwang for (i = 0; i < info.num_channels; i++) {
76a9643ea8Slogwang cmdline_printf(cl, " [%u]: %s, status = ", i,
77a9643ea8Slogwang info.channels[i].channel_path);
78a9643ea8Slogwang switch (info.channels[i].status) {
79a9643ea8Slogwang case CHANNEL_MGR_CHANNEL_CONNECTED:
80a9643ea8Slogwang cmdline_printf(cl, "CONNECTED\n");
81a9643ea8Slogwang break;
82a9643ea8Slogwang case CHANNEL_MGR_CHANNEL_DISCONNECTED:
83a9643ea8Slogwang cmdline_printf(cl, "DISCONNECTED\n");
84a9643ea8Slogwang break;
85a9643ea8Slogwang case CHANNEL_MGR_CHANNEL_DISABLED:
86a9643ea8Slogwang cmdline_printf(cl, "DISABLED\n");
87a9643ea8Slogwang break;
88a9643ea8Slogwang case CHANNEL_MGR_CHANNEL_PROCESSING:
89a9643ea8Slogwang cmdline_printf(cl, "PROCESSING\n");
90a9643ea8Slogwang break;
91a9643ea8Slogwang default:
92a9643ea8Slogwang cmdline_printf(cl, "UNKNOWN\n");
93a9643ea8Slogwang break;
94a9643ea8Slogwang }
95a9643ea8Slogwang }
96a9643ea8Slogwang cmdline_printf(cl, "Virtual CPU(s): %u\n", info.num_vcpus);
97a9643ea8Slogwang for (i = 0; i < info.num_vcpus; i++) {
984418919fSjohnjiang cmdline_printf(cl, " [%u]: Physical CPU %d\n", i,
994418919fSjohnjiang info.pcpu_map[i]);
100a9643ea8Slogwang }
101a9643ea8Slogwang }
102a9643ea8Slogwang
103a9643ea8Slogwang
104a9643ea8Slogwang
105a9643ea8Slogwang cmdline_parse_token_string_t cmd_vm_show =
106a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result,
107a9643ea8Slogwang show_vm, "show_vm");
108a9643ea8Slogwang cmdline_parse_token_string_t cmd_show_vm_name =
109a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result,
110a9643ea8Slogwang vm_name, NULL);
111a9643ea8Slogwang
112a9643ea8Slogwang cmdline_parse_inst_t cmd_show_vm_set = {
113a9643ea8Slogwang .f = cmd_show_vm_parsed,
114a9643ea8Slogwang .data = NULL,
115a9643ea8Slogwang .help_str = "show_vm <vm_name>, prints the information on the "
116a9643ea8Slogwang "specified VM(s), the information lists the number of vCPUS, the "
117a9643ea8Slogwang "pinning to pCPU(s) as a bit mask, along with any communication "
118a9643ea8Slogwang "channels associated with each VM",
119a9643ea8Slogwang .tokens = {
120a9643ea8Slogwang (void *)&cmd_vm_show,
121a9643ea8Slogwang (void *)&cmd_show_vm_name,
122a9643ea8Slogwang NULL,
123a9643ea8Slogwang },
124a9643ea8Slogwang };
125a9643ea8Slogwang
126a9643ea8Slogwang /* *** vCPU to pCPU mapping operations *** */
127a9643ea8Slogwang
128a9643ea8Slogwang
129a9643ea8Slogwang struct cmd_set_pcpu_result {
130a9643ea8Slogwang cmdline_fixed_string_t set_pcpu;
131a9643ea8Slogwang cmdline_fixed_string_t vm_name;
132a9643ea8Slogwang uint8_t vcpu;
133a9643ea8Slogwang uint8_t core;
134a9643ea8Slogwang };
135a9643ea8Slogwang
136a9643ea8Slogwang static void
cmd_set_pcpu_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)137a9643ea8Slogwang cmd_set_pcpu_parsed(void *parsed_result, struct cmdline *cl,
138*2d9fd380Sjfb8856606 __rte_unused void *data)
139a9643ea8Slogwang {
140a9643ea8Slogwang struct cmd_set_pcpu_result *res = parsed_result;
141a9643ea8Slogwang
142a9643ea8Slogwang if (set_pcpu(res->vm_name, res->vcpu, res->core) == 0)
143a9643ea8Slogwang cmdline_printf(cl, "Pinned vCPU(%"PRId8") to pCPU core "
144a9643ea8Slogwang "%"PRId8")\n", res->vcpu, res->core);
145a9643ea8Slogwang else
146a9643ea8Slogwang cmdline_printf(cl, "Unable to pin vCPU(%"PRId8") to pCPU core "
147a9643ea8Slogwang "%"PRId8")\n", res->vcpu, res->core);
148a9643ea8Slogwang }
149a9643ea8Slogwang
150a9643ea8Slogwang cmdline_parse_token_string_t cmd_set_pcpu =
151a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result,
152a9643ea8Slogwang set_pcpu, "set_pcpu");
153a9643ea8Slogwang cmdline_parse_token_string_t cmd_set_pcpu_vm_name =
154a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result,
155a9643ea8Slogwang vm_name, NULL);
156a9643ea8Slogwang cmdline_parse_token_num_t set_pcpu_vcpu =
157a9643ea8Slogwang TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result,
158*2d9fd380Sjfb8856606 vcpu, RTE_UINT8);
159a9643ea8Slogwang cmdline_parse_token_num_t set_pcpu_core =
160a9643ea8Slogwang TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result,
161*2d9fd380Sjfb8856606 core, RTE_UINT64);
162a9643ea8Slogwang
163a9643ea8Slogwang
164a9643ea8Slogwang cmdline_parse_inst_t cmd_set_pcpu_set = {
165a9643ea8Slogwang .f = cmd_set_pcpu_parsed,
166a9643ea8Slogwang .data = NULL,
167a9643ea8Slogwang .help_str = "set_pcpu <vm_name> <vcpu> <pcpu>, Set the binding "
168a9643ea8Slogwang "of Virtual CPU on VM to the Physical CPU.",
169a9643ea8Slogwang .tokens = {
170a9643ea8Slogwang (void *)&cmd_set_pcpu,
171a9643ea8Slogwang (void *)&cmd_set_pcpu_vm_name,
172a9643ea8Slogwang (void *)&set_pcpu_vcpu,
173a9643ea8Slogwang (void *)&set_pcpu_core,
174a9643ea8Slogwang NULL,
175a9643ea8Slogwang },
176a9643ea8Slogwang };
177a9643ea8Slogwang
178a9643ea8Slogwang struct cmd_vm_op_result {
179a9643ea8Slogwang cmdline_fixed_string_t op_vm;
180a9643ea8Slogwang cmdline_fixed_string_t vm_name;
181a9643ea8Slogwang };
182a9643ea8Slogwang
183a9643ea8Slogwang static void
cmd_vm_op_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)184a9643ea8Slogwang cmd_vm_op_parsed(void *parsed_result, struct cmdline *cl,
185*2d9fd380Sjfb8856606 __rte_unused void *data)
186a9643ea8Slogwang {
187a9643ea8Slogwang struct cmd_vm_op_result *res = parsed_result;
188a9643ea8Slogwang
189a9643ea8Slogwang if (!strcmp(res->op_vm, "add_vm")) {
190a9643ea8Slogwang if (add_vm(res->vm_name) < 0)
191a9643ea8Slogwang cmdline_printf(cl, "Unable to add VM '%s'\n", res->vm_name);
192a9643ea8Slogwang } else if (remove_vm(res->vm_name) < 0)
193a9643ea8Slogwang cmdline_printf(cl, "Unable to remove VM '%s'\n", res->vm_name);
194a9643ea8Slogwang }
195a9643ea8Slogwang
196a9643ea8Slogwang cmdline_parse_token_string_t cmd_vm_op =
197a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result,
198a9643ea8Slogwang op_vm, "add_vm#rm_vm");
199a9643ea8Slogwang cmdline_parse_token_string_t cmd_vm_name =
200a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result,
201a9643ea8Slogwang vm_name, NULL);
202a9643ea8Slogwang
203a9643ea8Slogwang cmdline_parse_inst_t cmd_vm_op_set = {
204a9643ea8Slogwang .f = cmd_vm_op_parsed,
205a9643ea8Slogwang .data = NULL,
206a9643ea8Slogwang .help_str = "add_vm|rm_vm <name>, add a VM for "
207a9643ea8Slogwang "subsequent operations with the CLI or remove a previously added "
208a9643ea8Slogwang "VM from the VM Power Manager",
209a9643ea8Slogwang .tokens = {
210a9643ea8Slogwang (void *)&cmd_vm_op,
211a9643ea8Slogwang (void *)&cmd_vm_name,
212a9643ea8Slogwang NULL,
213a9643ea8Slogwang },
214a9643ea8Slogwang };
215a9643ea8Slogwang
216a9643ea8Slogwang /* *** VM channel operations *** */
217a9643ea8Slogwang struct cmd_channels_op_result {
218a9643ea8Slogwang cmdline_fixed_string_t op;
219a9643ea8Slogwang cmdline_fixed_string_t vm_name;
220a9643ea8Slogwang cmdline_fixed_string_t channel_list;
221a9643ea8Slogwang };
222a9643ea8Slogwang static void
cmd_channels_op_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)223a9643ea8Slogwang cmd_channels_op_parsed(void *parsed_result, struct cmdline *cl,
224*2d9fd380Sjfb8856606 __rte_unused void *data)
225a9643ea8Slogwang {
226a9643ea8Slogwang unsigned num_channels = 0, channel_num, i;
227a9643ea8Slogwang int channels_added;
2284418919fSjohnjiang unsigned int channel_list[RTE_MAX_LCORE];
229a9643ea8Slogwang char *token, *remaining, *tail_ptr;
230a9643ea8Slogwang struct cmd_channels_op_result *res = parsed_result;
231a9643ea8Slogwang
232a9643ea8Slogwang if (!strcmp(res->channel_list, "all")) {
233a9643ea8Slogwang channels_added = add_all_channels(res->vm_name);
234a9643ea8Slogwang cmdline_printf(cl, "Added %d channels for VM '%s'\n",
235a9643ea8Slogwang channels_added, res->vm_name);
236a9643ea8Slogwang return;
237a9643ea8Slogwang }
238a9643ea8Slogwang
239a9643ea8Slogwang remaining = res->channel_list;
240a9643ea8Slogwang while (1) {
241a9643ea8Slogwang if (remaining == NULL || remaining[0] == '\0')
242a9643ea8Slogwang break;
243a9643ea8Slogwang
244a9643ea8Slogwang token = strsep(&remaining, ",");
245a9643ea8Slogwang if (token == NULL)
246a9643ea8Slogwang break;
247a9643ea8Slogwang errno = 0;
248a9643ea8Slogwang channel_num = (unsigned)strtol(token, &tail_ptr, 10);
249a9643ea8Slogwang if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0'))
250a9643ea8Slogwang break;
251a9643ea8Slogwang
2524418919fSjohnjiang if (channel_num == RTE_MAX_LCORE) {
253a9643ea8Slogwang cmdline_printf(cl, "Channel number '%u' exceeds the maximum number "
254a9643ea8Slogwang "of allowable channels(%u) for VM '%s'\n", channel_num,
2554418919fSjohnjiang RTE_MAX_LCORE, res->vm_name);
256a9643ea8Slogwang return;
257a9643ea8Slogwang }
258a9643ea8Slogwang channel_list[num_channels++] = channel_num;
259a9643ea8Slogwang }
260a9643ea8Slogwang for (i = 0; i < num_channels; i++)
261a9643ea8Slogwang cmdline_printf(cl, "[%u]: Adding channel %u\n", i, channel_list[i]);
262a9643ea8Slogwang
263a9643ea8Slogwang channels_added = add_channels(res->vm_name, channel_list,
264a9643ea8Slogwang num_channels);
265a9643ea8Slogwang cmdline_printf(cl, "Enabled %d channels for '%s'\n", channels_added,
266a9643ea8Slogwang res->vm_name);
267a9643ea8Slogwang }
268a9643ea8Slogwang
269a9643ea8Slogwang cmdline_parse_token_string_t cmd_channels_op =
270a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result,
271a9643ea8Slogwang op, "add_channels");
272a9643ea8Slogwang cmdline_parse_token_string_t cmd_channels_vm_name =
273a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result,
274a9643ea8Slogwang vm_name, NULL);
275a9643ea8Slogwang cmdline_parse_token_string_t cmd_channels_list =
276a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result,
277a9643ea8Slogwang channel_list, NULL);
278a9643ea8Slogwang
279a9643ea8Slogwang cmdline_parse_inst_t cmd_channels_op_set = {
280a9643ea8Slogwang .f = cmd_channels_op_parsed,
281a9643ea8Slogwang .data = NULL,
282a9643ea8Slogwang .help_str = "add_channels <vm_name> <list>|all, add "
283a9643ea8Slogwang "communication channels for the specified VM, the "
284a9643ea8Slogwang "virtio channels must be enabled in the VM "
285a9643ea8Slogwang "configuration(qemu/libvirt) and the associated VM must be active. "
286a9643ea8Slogwang "<list> is a comma-separated list of channel numbers to add, using "
287a9643ea8Slogwang "the keyword 'all' will attempt to add all channels for the VM",
288a9643ea8Slogwang .tokens = {
289a9643ea8Slogwang (void *)&cmd_channels_op,
290a9643ea8Slogwang (void *)&cmd_channels_vm_name,
291a9643ea8Slogwang (void *)&cmd_channels_list,
292a9643ea8Slogwang NULL,
293a9643ea8Slogwang },
294a9643ea8Slogwang };
295a9643ea8Slogwang
2964418919fSjohnjiang struct cmd_set_query_result {
2974418919fSjohnjiang cmdline_fixed_string_t set_query;
2984418919fSjohnjiang cmdline_fixed_string_t vm_name;
2994418919fSjohnjiang cmdline_fixed_string_t query_status;
3004418919fSjohnjiang };
3014418919fSjohnjiang
3024418919fSjohnjiang static void
cmd_set_query_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)3034418919fSjohnjiang cmd_set_query_parsed(void *parsed_result,
3044418919fSjohnjiang __rte_unused struct cmdline *cl,
3054418919fSjohnjiang __rte_unused void *data)
3064418919fSjohnjiang {
3074418919fSjohnjiang struct cmd_set_query_result *res = parsed_result;
3084418919fSjohnjiang
3094418919fSjohnjiang if (!strcmp(res->query_status, "enable")) {
3104418919fSjohnjiang if (set_query_status(res->vm_name, true) < 0)
3114418919fSjohnjiang cmdline_printf(cl, "Unable to allow query for VM '%s'\n",
3124418919fSjohnjiang res->vm_name);
3134418919fSjohnjiang } else if (!strcmp(res->query_status, "disable")) {
3144418919fSjohnjiang if (set_query_status(res->vm_name, false) < 0)
3154418919fSjohnjiang cmdline_printf(cl, "Unable to disallow query for VM '%s'\n",
3164418919fSjohnjiang res->vm_name);
3174418919fSjohnjiang }
3184418919fSjohnjiang }
3194418919fSjohnjiang
3204418919fSjohnjiang cmdline_parse_token_string_t cmd_set_query =
3214418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_set_query_result,
3224418919fSjohnjiang set_query, "set_query");
3234418919fSjohnjiang cmdline_parse_token_string_t cmd_set_query_vm_name =
3244418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_set_query_result,
3254418919fSjohnjiang vm_name, NULL);
3264418919fSjohnjiang cmdline_parse_token_string_t cmd_set_query_status =
3274418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_set_query_result,
3284418919fSjohnjiang query_status, "enable#disable");
3294418919fSjohnjiang
3304418919fSjohnjiang cmdline_parse_inst_t cmd_set_query_set = {
3314418919fSjohnjiang .f = cmd_set_query_parsed,
3324418919fSjohnjiang .data = NULL,
3334418919fSjohnjiang .help_str = "set_query <vm_name> <enable|disable>, allow or disallow queries"
3344418919fSjohnjiang " for the specified VM",
3354418919fSjohnjiang .tokens = {
3364418919fSjohnjiang (void *)&cmd_set_query,
3374418919fSjohnjiang (void *)&cmd_set_query_vm_name,
3384418919fSjohnjiang (void *)&cmd_set_query_status,
3394418919fSjohnjiang NULL,
3404418919fSjohnjiang },
3414418919fSjohnjiang };
3424418919fSjohnjiang
343a9643ea8Slogwang struct cmd_channels_status_op_result {
344a9643ea8Slogwang cmdline_fixed_string_t op;
345a9643ea8Slogwang cmdline_fixed_string_t vm_name;
346a9643ea8Slogwang cmdline_fixed_string_t channel_list;
347a9643ea8Slogwang cmdline_fixed_string_t status;
348a9643ea8Slogwang };
349a9643ea8Slogwang
350a9643ea8Slogwang static void
cmd_channels_status_op_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)351a9643ea8Slogwang cmd_channels_status_op_parsed(void *parsed_result, struct cmdline *cl,
352*2d9fd380Sjfb8856606 __rte_unused void *data)
353a9643ea8Slogwang {
354a9643ea8Slogwang unsigned num_channels = 0, channel_num;
355a9643ea8Slogwang int changed;
3564418919fSjohnjiang unsigned int channel_list[RTE_MAX_LCORE];
357a9643ea8Slogwang char *token, *remaining, *tail_ptr;
358a9643ea8Slogwang struct cmd_channels_status_op_result *res = parsed_result;
359a9643ea8Slogwang enum channel_status status;
360a9643ea8Slogwang
361a9643ea8Slogwang if (!strcmp(res->status, "enabled"))
362a9643ea8Slogwang status = CHANNEL_MGR_CHANNEL_CONNECTED;
363a9643ea8Slogwang else
364a9643ea8Slogwang status = CHANNEL_MGR_CHANNEL_DISABLED;
365a9643ea8Slogwang
366a9643ea8Slogwang if (!strcmp(res->channel_list, "all")) {
367a9643ea8Slogwang changed = set_channel_status_all(res->vm_name, status);
368a9643ea8Slogwang cmdline_printf(cl, "Updated status of %d channels "
369a9643ea8Slogwang "for VM '%s'\n", changed, res->vm_name);
370a9643ea8Slogwang return;
371a9643ea8Slogwang }
372a9643ea8Slogwang remaining = res->channel_list;
373a9643ea8Slogwang while (1) {
374a9643ea8Slogwang if (remaining == NULL || remaining[0] == '\0')
375a9643ea8Slogwang break;
376a9643ea8Slogwang token = strsep(&remaining, ",");
377a9643ea8Slogwang if (token == NULL)
378a9643ea8Slogwang break;
379a9643ea8Slogwang errno = 0;
380a9643ea8Slogwang channel_num = (unsigned)strtol(token, &tail_ptr, 10);
381a9643ea8Slogwang if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0'))
382a9643ea8Slogwang break;
383a9643ea8Slogwang
3844418919fSjohnjiang if (channel_num == RTE_MAX_LCORE) {
385a9643ea8Slogwang cmdline_printf(cl, "%u exceeds the maximum number of allowable "
386a9643ea8Slogwang "channels(%u) for VM '%s'\n", channel_num,
3874418919fSjohnjiang RTE_MAX_LCORE, res->vm_name);
388a9643ea8Slogwang return;
389a9643ea8Slogwang }
390a9643ea8Slogwang channel_list[num_channels++] = channel_num;
391a9643ea8Slogwang }
392a9643ea8Slogwang changed = set_channel_status(res->vm_name, channel_list, num_channels,
393a9643ea8Slogwang status);
394a9643ea8Slogwang cmdline_printf(cl, "Updated status of %d channels "
395a9643ea8Slogwang "for VM '%s'\n", changed, res->vm_name);
396a9643ea8Slogwang }
397a9643ea8Slogwang
398a9643ea8Slogwang cmdline_parse_token_string_t cmd_channels_status_op =
399a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
400a9643ea8Slogwang op, "set_channel_status");
401a9643ea8Slogwang cmdline_parse_token_string_t cmd_channels_status_vm_name =
402a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
403a9643ea8Slogwang vm_name, NULL);
404a9643ea8Slogwang cmdline_parse_token_string_t cmd_channels_status_list =
405a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
406a9643ea8Slogwang channel_list, NULL);
407a9643ea8Slogwang cmdline_parse_token_string_t cmd_channels_status =
408a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
409a9643ea8Slogwang status, "enabled#disabled");
410a9643ea8Slogwang
411a9643ea8Slogwang cmdline_parse_inst_t cmd_channels_status_op_set = {
412a9643ea8Slogwang .f = cmd_channels_status_op_parsed,
413a9643ea8Slogwang .data = NULL,
414a9643ea8Slogwang .help_str = "set_channel_status <vm_name> <list>|all enabled|disabled, "
415a9643ea8Slogwang " enable or disable the communication channels in "
416a9643ea8Slogwang "list(comma-separated) for the specified VM, alternatively "
417a9643ea8Slogwang "list can be replaced with keyword 'all'. "
418a9643ea8Slogwang "Disabled channels will still receive packets on the host, "
419a9643ea8Slogwang "however the commands they specify will be ignored. "
420a9643ea8Slogwang "Set status to 'enabled' to begin processing requests again.",
421a9643ea8Slogwang .tokens = {
422a9643ea8Slogwang (void *)&cmd_channels_status_op,
423a9643ea8Slogwang (void *)&cmd_channels_status_vm_name,
424a9643ea8Slogwang (void *)&cmd_channels_status_list,
425a9643ea8Slogwang (void *)&cmd_channels_status,
426a9643ea8Slogwang NULL,
427a9643ea8Slogwang },
428a9643ea8Slogwang };
429a9643ea8Slogwang
430a9643ea8Slogwang /* *** CPU Frequency operations *** */
431a9643ea8Slogwang struct cmd_show_cpu_freq_result {
432a9643ea8Slogwang cmdline_fixed_string_t show_cpu_freq;
433a9643ea8Slogwang uint8_t core_num;
434a9643ea8Slogwang };
435a9643ea8Slogwang
436a9643ea8Slogwang static void
cmd_show_cpu_freq_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)437a9643ea8Slogwang cmd_show_cpu_freq_parsed(void *parsed_result, struct cmdline *cl,
438*2d9fd380Sjfb8856606 __rte_unused void *data)
439a9643ea8Slogwang {
440a9643ea8Slogwang struct cmd_show_cpu_freq_result *res = parsed_result;
441a9643ea8Slogwang uint32_t curr_freq = power_manager_get_current_frequency(res->core_num);
442a9643ea8Slogwang
443a9643ea8Slogwang if (curr_freq == 0) {
444a9643ea8Slogwang cmdline_printf(cl, "Unable to get frequency for core %u\n",
445a9643ea8Slogwang res->core_num);
446a9643ea8Slogwang return;
447a9643ea8Slogwang }
448a9643ea8Slogwang cmdline_printf(cl, "Core %u frequency: %"PRId32"\n", res->core_num,
449a9643ea8Slogwang curr_freq);
450a9643ea8Slogwang }
451a9643ea8Slogwang
452a9643ea8Slogwang cmdline_parse_token_string_t cmd_show_cpu_freq =
453a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_show_cpu_freq_result,
454a9643ea8Slogwang show_cpu_freq, "show_cpu_freq");
455a9643ea8Slogwang
456a9643ea8Slogwang cmdline_parse_token_num_t cmd_show_cpu_freq_core_num =
457a9643ea8Slogwang TOKEN_NUM_INITIALIZER(struct cmd_show_cpu_freq_result,
458*2d9fd380Sjfb8856606 core_num, RTE_UINT8);
459a9643ea8Slogwang
460a9643ea8Slogwang cmdline_parse_inst_t cmd_show_cpu_freq_set = {
461a9643ea8Slogwang .f = cmd_show_cpu_freq_parsed,
462a9643ea8Slogwang .data = NULL,
463a9643ea8Slogwang .help_str = "Get the current frequency for the specified core",
464a9643ea8Slogwang .tokens = {
465a9643ea8Slogwang (void *)&cmd_show_cpu_freq,
466a9643ea8Slogwang (void *)&cmd_show_cpu_freq_core_num,
467a9643ea8Slogwang NULL,
468a9643ea8Slogwang },
469a9643ea8Slogwang };
470a9643ea8Slogwang
471a9643ea8Slogwang struct cmd_set_cpu_freq_result {
472a9643ea8Slogwang cmdline_fixed_string_t set_cpu_freq;
473a9643ea8Slogwang uint8_t core_num;
474a9643ea8Slogwang cmdline_fixed_string_t cmd;
475a9643ea8Slogwang };
476a9643ea8Slogwang
477a9643ea8Slogwang static void
cmd_set_cpu_freq_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)478a9643ea8Slogwang cmd_set_cpu_freq_parsed(void *parsed_result, struct cmdline *cl,
479*2d9fd380Sjfb8856606 __rte_unused void *data)
480a9643ea8Slogwang {
481a9643ea8Slogwang int ret = -1;
482a9643ea8Slogwang struct cmd_set_cpu_freq_result *res = parsed_result;
483a9643ea8Slogwang
484a9643ea8Slogwang if (!strcmp(res->cmd , "up"))
485a9643ea8Slogwang ret = power_manager_scale_core_up(res->core_num);
486a9643ea8Slogwang else if (!strcmp(res->cmd , "down"))
487a9643ea8Slogwang ret = power_manager_scale_core_down(res->core_num);
488a9643ea8Slogwang else if (!strcmp(res->cmd , "min"))
489a9643ea8Slogwang ret = power_manager_scale_core_min(res->core_num);
490a9643ea8Slogwang else if (!strcmp(res->cmd , "max"))
491a9643ea8Slogwang ret = power_manager_scale_core_max(res->core_num);
4922bfe3f2eSlogwang else if (!strcmp(res->cmd, "enable_turbo"))
4932bfe3f2eSlogwang ret = power_manager_enable_turbo_core(res->core_num);
4942bfe3f2eSlogwang else if (!strcmp(res->cmd, "disable_turbo"))
4952bfe3f2eSlogwang ret = power_manager_disable_turbo_core(res->core_num);
496a9643ea8Slogwang if (ret < 0) {
497a9643ea8Slogwang cmdline_printf(cl, "Error scaling core(%u) '%s'\n", res->core_num,
498a9643ea8Slogwang res->cmd);
499a9643ea8Slogwang }
500a9643ea8Slogwang }
501a9643ea8Slogwang
502a9643ea8Slogwang cmdline_parse_token_string_t cmd_set_cpu_freq =
503a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result,
504a9643ea8Slogwang set_cpu_freq, "set_cpu_freq");
505a9643ea8Slogwang cmdline_parse_token_num_t cmd_set_cpu_freq_core_num =
506a9643ea8Slogwang TOKEN_NUM_INITIALIZER(struct cmd_set_cpu_freq_result,
507*2d9fd380Sjfb8856606 core_num, RTE_UINT8);
508a9643ea8Slogwang cmdline_parse_token_string_t cmd_set_cpu_freq_cmd_cmd =
509a9643ea8Slogwang TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result,
5102bfe3f2eSlogwang cmd, "up#down#min#max#enable_turbo#disable_turbo");
511a9643ea8Slogwang
512a9643ea8Slogwang cmdline_parse_inst_t cmd_set_cpu_freq_set = {
513a9643ea8Slogwang .f = cmd_set_cpu_freq_parsed,
514a9643ea8Slogwang .data = NULL,
5152bfe3f2eSlogwang .help_str = "set_cpu_freq <core_num> <up|down|min|max|enable_turbo|disable_turbo>, adjust the current "
5162bfe3f2eSlogwang "frequency for the specified core",
517a9643ea8Slogwang .tokens = {
518a9643ea8Slogwang (void *)&cmd_set_cpu_freq,
519a9643ea8Slogwang (void *)&cmd_set_cpu_freq_core_num,
520a9643ea8Slogwang (void *)&cmd_set_cpu_freq_cmd_cmd,
521a9643ea8Slogwang NULL,
522a9643ea8Slogwang },
523a9643ea8Slogwang };
524a9643ea8Slogwang
525a9643ea8Slogwang cmdline_parse_ctx_t main_ctx[] = {
526a9643ea8Slogwang (cmdline_parse_inst_t *)&cmd_quit,
527a9643ea8Slogwang (cmdline_parse_inst_t *)&cmd_vm_op_set,
528a9643ea8Slogwang (cmdline_parse_inst_t *)&cmd_channels_op_set,
529a9643ea8Slogwang (cmdline_parse_inst_t *)&cmd_channels_status_op_set,
530a9643ea8Slogwang (cmdline_parse_inst_t *)&cmd_show_vm_set,
531a9643ea8Slogwang (cmdline_parse_inst_t *)&cmd_show_cpu_freq_set,
532a9643ea8Slogwang (cmdline_parse_inst_t *)&cmd_set_cpu_freq_set,
533a9643ea8Slogwang (cmdline_parse_inst_t *)&cmd_set_pcpu_set,
5344418919fSjohnjiang (cmdline_parse_inst_t *)&cmd_set_query_set,
535a9643ea8Slogwang NULL,
536a9643ea8Slogwang };
537a9643ea8Slogwang
538a9643ea8Slogwang void
run_cli(__rte_unused void * arg)539*2d9fd380Sjfb8856606 run_cli(__rte_unused void *arg)
540a9643ea8Slogwang {
541a9643ea8Slogwang struct cmdline *cl;
542a9643ea8Slogwang
543a9643ea8Slogwang cl = cmdline_stdin_new(main_ctx, "vmpower> ");
544a9643ea8Slogwang if (cl == NULL)
545a9643ea8Slogwang return;
546a9643ea8Slogwang
547a9643ea8Slogwang cmdline_interact(cl);
548a9643ea8Slogwang cmdline_stdin_exit(cl);
549a9643ea8Slogwang }
550