examples/vm_power: fix initialization of cmdline token
[dpdk.git] / examples / vm_power_manager / vm_power_cli.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdlib.h>
35 #include <stdint.h>
36 #include <inttypes.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <termios.h>
40 #include <errno.h>
41
42 #include <cmdline_rdline.h>
43 #include <cmdline_parse.h>
44 #include <cmdline_parse_string.h>
45 #include <cmdline_parse_num.h>
46 #include <cmdline_socket.h>
47 #include <cmdline.h>
48 #include <rte_config.h>
49
50 #include "vm_power_cli.h"
51 #include "channel_manager.h"
52 #include "channel_monitor.h"
53 #include "power_manager.h"
54 #include "channel_commands.h"
55
56 struct cmd_quit_result {
57         cmdline_fixed_string_t quit;
58 };
59
60 static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
61                 struct cmdline *cl,
62                 __attribute__((unused)) void *data)
63 {
64         channel_monitor_exit();
65         channel_manager_exit();
66         power_manager_exit();
67         cmdline_quit(cl);
68 }
69
70 cmdline_parse_token_string_t cmd_quit_quit =
71         TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
72
73 cmdline_parse_inst_t cmd_quit = {
74         .f = cmd_quit_parsed,  /* function to call */
75         .data = NULL,      /* 2nd arg of func */
76         .help_str = "close the application",
77         .tokens = {        /* token list, NULL terminated */
78                 (void *)&cmd_quit_quit,
79                 NULL,
80         },
81 };
82
83 /* *** VM operations *** */
84 struct cmd_show_vm_result {
85         cmdline_fixed_string_t show_vm;
86         cmdline_fixed_string_t vm_name;
87 };
88
89 static void
90 cmd_show_vm_parsed(void *parsed_result, struct cmdline *cl,
91                 __attribute__((unused)) void *data)
92 {
93         struct cmd_show_vm_result *res = parsed_result;
94         struct vm_info info;
95         unsigned i;
96
97         if (get_info_vm(res->vm_name, &info) != 0)
98                 return;
99         cmdline_printf(cl, "VM: '%s', status = ", info.name);
100         if (info.status == CHANNEL_MGR_VM_ACTIVE)
101                 cmdline_printf(cl, "ACTIVE\n");
102         else
103                 cmdline_printf(cl, "INACTIVE\n");
104         cmdline_printf(cl, "Channels %u\n", info.num_channels);
105         for (i = 0; i < info.num_channels; i++) {
106                 cmdline_printf(cl, "  [%u]: %s, status = ", i,
107                                 info.channels[i].channel_path);
108                 switch (info.channels[i].status) {
109                 case CHANNEL_MGR_CHANNEL_CONNECTED:
110                         cmdline_printf(cl, "CONNECTED\n");
111                         break;
112                 case CHANNEL_MGR_CHANNEL_DISCONNECTED:
113                         cmdline_printf(cl, "DISCONNECTED\n");
114                         break;
115                 case CHANNEL_MGR_CHANNEL_DISABLED:
116                         cmdline_printf(cl, "DISABLED\n");
117                         break;
118                 case CHANNEL_MGR_CHANNEL_PROCESSING:
119                         cmdline_printf(cl, "PROCESSING\n");
120                         break;
121                 default:
122                         cmdline_printf(cl, "UNKNOWN\n");
123                         break;
124                 }
125         }
126         cmdline_printf(cl, "Virtual CPU(s): %u\n", info.num_vcpus);
127         for (i = 0; i < info.num_vcpus; i++) {
128                 cmdline_printf(cl, "  [%u]: Physical CPU Mask 0x%"PRIx64"\n", i,
129                                 info.pcpu_mask[i]);
130         }
131 }
132
133
134
135 cmdline_parse_token_string_t cmd_vm_show =
136         TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result,
137                                 show_vm, "show_vm");
138 cmdline_parse_token_string_t cmd_show_vm_name =
139         TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result,
140                         vm_name, NULL);
141
142 cmdline_parse_inst_t cmd_show_vm_set = {
143         .f = cmd_show_vm_parsed,
144         .data = NULL,
145         .help_str = "show_vm <vm_name>, prints the information on the "
146                         "specified VM(s), the information lists the number of vCPUS, the "
147                         "pinning to pCPU(s) as a bit mask, along with any communication "
148                         "channels associated with each VM",
149         .tokens = {
150                 (void *)&cmd_vm_show,
151                 (void *)&cmd_show_vm_name,
152                 NULL,
153         },
154 };
155
156 /* *** vCPU to pCPU mapping operations *** */
157 struct cmd_set_pcpu_mask_result {
158         cmdline_fixed_string_t set_pcpu_mask;
159         cmdline_fixed_string_t vm_name;
160         uint8_t vcpu;
161         uint64_t core_mask;
162 };
163
164 static void
165 cmd_set_pcpu_mask_parsed(void *parsed_result, struct cmdline *cl,
166                 __attribute__((unused)) void *data)
167 {
168         struct cmd_set_pcpu_mask_result *res = parsed_result;
169
170         if (set_pcpus_mask(res->vm_name, res->vcpu, res->core_mask) == 0)
171                 cmdline_printf(cl, "Pinned vCPU(%"PRId8") to pCPU core "
172                                 "mask(0x%"PRIx64")\n", res->vcpu, res->core_mask);
173         else
174                 cmdline_printf(cl, "Unable to pin vCPU(%"PRId8") to pCPU core "
175                                 "mask(0x%"PRIx64")\n", res->vcpu, res->core_mask);
176 }
177
178 cmdline_parse_token_string_t cmd_set_pcpu_mask =
179                 TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_mask_result,
180                                 set_pcpu_mask, "set_pcpu_mask");
181 cmdline_parse_token_string_t cmd_set_pcpu_mask_vm_name =
182                 TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_mask_result,
183                                 vm_name, NULL);
184 cmdline_parse_token_num_t set_pcpu_mask_vcpu =
185                 TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_mask_result,
186                                 vcpu, UINT8);
187 cmdline_parse_token_num_t set_pcpu_mask_core_mask =
188                 TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_mask_result,
189                                 core_mask, UINT64);
190
191
192 cmdline_parse_inst_t cmd_set_pcpu_mask_set = {
193                 .f = cmd_set_pcpu_mask_parsed,
194                 .data = NULL,
195                 .help_str = "set_pcpu_mask <vm_name> <vcpu> <pcpu>, Set the binding "
196                                 "of Virtual CPU on VM to the Physical CPU mask.",
197                                 .tokens = {
198                                                 (void *)&cmd_set_pcpu_mask,
199                                                 (void *)&cmd_set_pcpu_mask_vm_name,
200                                                 (void *)&set_pcpu_mask_vcpu,
201                                                 (void *)&set_pcpu_mask_core_mask,
202                                                 NULL,
203                 },
204 };
205
206 struct cmd_set_pcpu_result {
207         cmdline_fixed_string_t set_pcpu;
208         cmdline_fixed_string_t vm_name;
209         uint8_t vcpu;
210         uint8_t core;
211 };
212
213 static void
214 cmd_set_pcpu_parsed(void *parsed_result, struct cmdline *cl,
215                 __attribute__((unused)) void *data)
216 {
217         struct cmd_set_pcpu_result *res = parsed_result;
218
219         if (set_pcpu(res->vm_name, res->vcpu, res->core) == 0)
220                 cmdline_printf(cl, "Pinned vCPU(%"PRId8") to pCPU core "
221                                 "%"PRId8")\n", res->vcpu, res->core);
222         else
223                 cmdline_printf(cl, "Unable to pin vCPU(%"PRId8") to pCPU core "
224                                 "%"PRId8")\n", res->vcpu, res->core);
225 }
226
227 cmdline_parse_token_string_t cmd_set_pcpu =
228                 TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result,
229                                 set_pcpu, "set_pcpu");
230 cmdline_parse_token_string_t cmd_set_pcpu_vm_name =
231                 TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result,
232                                 vm_name, NULL);
233 cmdline_parse_token_num_t set_pcpu_vcpu =
234                 TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result,
235                                 vcpu, UINT8);
236 cmdline_parse_token_num_t set_pcpu_core =
237                 TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result,
238                                 core, UINT64);
239
240
241 cmdline_parse_inst_t cmd_set_pcpu_set = {
242                 .f = cmd_set_pcpu_parsed,
243                 .data = NULL,
244                 .help_str = "set_pcpu <vm_name> <vcpu> <pcpu>, Set the binding "
245                                 "of Virtual CPU on VM to the Physical CPU.",
246                                 .tokens = {
247                                                 (void *)&cmd_set_pcpu,
248                                                 (void *)&cmd_set_pcpu_vm_name,
249                                                 (void *)&set_pcpu_vcpu,
250                                                 (void *)&set_pcpu_core,
251                                                 NULL,
252                 },
253 };
254
255 struct cmd_vm_op_result {
256         cmdline_fixed_string_t op_vm;
257         cmdline_fixed_string_t vm_name;
258 };
259
260 static void
261 cmd_vm_op_parsed(void *parsed_result, struct cmdline *cl,
262                 __attribute__((unused)) void *data)
263 {
264         struct cmd_vm_op_result *res = parsed_result;
265
266         if (!strcmp(res->op_vm, "add_vm")) {
267                 if (add_vm(res->vm_name) < 0)
268                         cmdline_printf(cl, "Unable to add VM '%s'\n", res->vm_name);
269         } else if (remove_vm(res->vm_name) < 0)
270                 cmdline_printf(cl, "Unable to remove VM '%s'\n", res->vm_name);
271 }
272
273 cmdline_parse_token_string_t cmd_vm_op =
274         TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result,
275                         op_vm, "add_vm#rm_vm");
276 cmdline_parse_token_string_t cmd_vm_name =
277         TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result,
278                         vm_name, NULL);
279
280 cmdline_parse_inst_t cmd_vm_op_set = {
281         .f = cmd_vm_op_parsed,
282         .data = NULL,
283         .help_str = "add_vm|rm_vm <name>, add a VM for "
284                         "subsequent operations with the CLI or remove a previously added "
285                         "VM from the VM Power Manager",
286         .tokens = {
287                 (void *)&cmd_vm_op,
288                 (void *)&cmd_vm_name,
289         NULL,
290         },
291 };
292
293 /* *** VM channel operations *** */
294 struct cmd_channels_op_result {
295         cmdline_fixed_string_t op;
296         cmdline_fixed_string_t vm_name;
297         cmdline_fixed_string_t channel_list;
298 };
299 static void
300 cmd_channels_op_parsed(void *parsed_result, struct cmdline *cl,
301                         __attribute__((unused)) void *data)
302 {
303         unsigned num_channels = 0, channel_num, i;
304         int channels_added;
305         unsigned channel_list[CHANNEL_CMDS_MAX_VM_CHANNELS];
306         char *token, *remaining, *tail_ptr;
307         struct cmd_channels_op_result *res = parsed_result;
308
309         if (!strcmp(res->channel_list, "all")) {
310                 channels_added = add_all_channels(res->vm_name);
311                 cmdline_printf(cl, "Added %d channels for VM '%s'\n",
312                                 channels_added, res->vm_name);
313                 return;
314         }
315
316         remaining = res->channel_list;
317         while (1) {
318                 if (remaining == NULL || remaining[0] == '\0')
319                         break;
320
321                 token = strsep(&remaining, ",");
322                 if (token == NULL)
323                         break;
324                 errno = 0;
325                 channel_num = (unsigned)strtol(token, &tail_ptr, 10);
326                 if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0'))
327                         break;
328
329                 if (channel_num == CHANNEL_CMDS_MAX_VM_CHANNELS) {
330                         cmdline_printf(cl, "Channel number '%u' exceeds the maximum number "
331                                         "of allowable channels(%u) for VM '%s'\n", channel_num,
332                                         CHANNEL_CMDS_MAX_VM_CHANNELS, res->vm_name);
333                         return;
334                 }
335                 channel_list[num_channels++] = channel_num;
336         }
337         for (i = 0; i < num_channels; i++)
338                 cmdline_printf(cl, "[%u]: Adding channel %u\n", i, channel_list[i]);
339
340         channels_added = add_channels(res->vm_name, channel_list,
341                         num_channels);
342         cmdline_printf(cl, "Enabled %d channels for '%s'\n", channels_added,
343                         res->vm_name);
344 }
345
346 cmdline_parse_token_string_t cmd_channels_op =
347         TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result,
348                                 op, "add_channels");
349 cmdline_parse_token_string_t cmd_channels_vm_name =
350         TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result,
351                         vm_name, NULL);
352 cmdline_parse_token_string_t cmd_channels_list =
353         TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result,
354                         channel_list, NULL);
355
356 cmdline_parse_inst_t cmd_channels_op_set = {
357         .f = cmd_channels_op_parsed,
358         .data = NULL,
359         .help_str = "add_channels <vm_name> <list>|all, add "
360                         "communication channels for the specified VM, the "
361                         "virtio channels must be enabled in the VM "
362                         "configuration(qemu/libvirt) and the associated VM must be active. "
363                         "<list> is a comma-separated list of channel numbers to add, using "
364                         "the keyword 'all' will attempt to add all channels for the VM",
365         .tokens = {
366                 (void *)&cmd_channels_op,
367                 (void *)&cmd_channels_vm_name,
368                 (void *)&cmd_channels_list,
369                 NULL,
370         },
371 };
372
373 struct cmd_channels_status_op_result {
374         cmdline_fixed_string_t op;
375         cmdline_fixed_string_t vm_name;
376         cmdline_fixed_string_t channel_list;
377         cmdline_fixed_string_t status;
378 };
379
380 static void
381 cmd_channels_status_op_parsed(void *parsed_result, struct cmdline *cl,
382                        __attribute__((unused)) void *data)
383 {
384         unsigned num_channels = 0, channel_num;
385         int changed;
386         unsigned channel_list[CHANNEL_CMDS_MAX_VM_CHANNELS];
387         char *token, *remaining, *tail_ptr;
388         struct cmd_channels_status_op_result *res = parsed_result;
389         enum channel_status status;
390
391         if (!strcmp(res->status, "enabled"))
392                 status = CHANNEL_MGR_CHANNEL_CONNECTED;
393         else
394                 status = CHANNEL_MGR_CHANNEL_DISABLED;
395
396         if (!strcmp(res->channel_list, "all")) {
397                 changed = set_channel_status_all(res->vm_name, status);
398                 cmdline_printf(cl, "Updated status of %d channels "
399                                 "for VM '%s'\n", changed, res->vm_name);
400                 return;
401         }
402         remaining = res->channel_list;
403         while (1) {
404                 if (remaining == NULL || remaining[0] == '\0')
405                         break;
406                 token = strsep(&remaining, ",");
407                 if (token == NULL)
408                         break;
409                 errno = 0;
410                 channel_num = (unsigned)strtol(token, &tail_ptr, 10);
411                 if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0'))
412                         break;
413
414                 if (channel_num == CHANNEL_CMDS_MAX_VM_CHANNELS) {
415                         cmdline_printf(cl, "%u exceeds the maximum number of allowable "
416                                         "channels(%u) for VM '%s'\n", channel_num,
417                                         CHANNEL_CMDS_MAX_VM_CHANNELS, res->vm_name);
418                         return;
419                 }
420                 channel_list[num_channels++] = channel_num;
421         }
422         changed = set_channel_status(res->vm_name, channel_list, num_channels,
423                         status);
424         cmdline_printf(cl, "Updated status of %d channels "
425                                         "for VM '%s'\n", changed, res->vm_name);
426 }
427
428 cmdline_parse_token_string_t cmd_channels_status_op =
429         TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
430                                 op, "set_channel_status");
431 cmdline_parse_token_string_t cmd_channels_status_vm_name =
432         TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
433                         vm_name, NULL);
434 cmdline_parse_token_string_t cmd_channels_status_list =
435         TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
436                         channel_list, NULL);
437 cmdline_parse_token_string_t cmd_channels_status =
438         TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
439                         status, "enabled#disabled");
440
441 cmdline_parse_inst_t cmd_channels_status_op_set = {
442         .f = cmd_channels_status_op_parsed,
443         .data = NULL,
444         .help_str = "set_channel_status <vm_name> <list>|all enabled|disabled, "
445                         " enable or disable the communication channels in "
446                         "list(comma-separated) for the specified VM, alternatively "
447                         "list can be replaced with keyword 'all'. "
448                         "Disabled channels will still receive packets on the host, "
449                         "however the commands they specify will be ignored. "
450                         "Set status to 'enabled' to begin processing requests again.",
451         .tokens = {
452                 (void *)&cmd_channels_status_op,
453                 (void *)&cmd_channels_status_vm_name,
454                 (void *)&cmd_channels_status_list,
455                 (void *)&cmd_channels_status,
456                 NULL,
457         },
458 };
459
460 /* *** CPU Frequency operations *** */
461 struct cmd_show_cpu_freq_mask_result {
462         cmdline_fixed_string_t show_cpu_freq_mask;
463         uint64_t core_mask;
464 };
465
466 static void
467 cmd_show_cpu_freq_mask_parsed(void *parsed_result, struct cmdline *cl,
468                        __attribute__((unused)) void *data)
469 {
470         struct cmd_show_cpu_freq_mask_result *res = parsed_result;
471         unsigned i;
472         uint64_t mask = res->core_mask;
473         uint32_t freq;
474
475         for (i = 0; mask; mask &= ~(1ULL << i++)) {
476                 if ((mask >> i) & 1) {
477                         freq = power_manager_get_current_frequency(i);
478                         if (freq > 0)
479                                 cmdline_printf(cl, "Core %u: %"PRId32"\n", i, freq);
480                 }
481         }
482 }
483
484 cmdline_parse_token_string_t cmd_show_cpu_freq_mask =
485         TOKEN_STRING_INITIALIZER(struct cmd_show_cpu_freq_mask_result,
486                         show_cpu_freq_mask, "show_cpu_freq_mask");
487 cmdline_parse_token_num_t cmd_show_cpu_freq_mask_core_mask =
488         TOKEN_NUM_INITIALIZER(struct cmd_show_cpu_freq_mask_result,
489                         core_mask, UINT64);
490
491 cmdline_parse_inst_t cmd_show_cpu_freq_mask_set = {
492         .f = cmd_show_cpu_freq_mask_parsed,
493         .data = NULL,
494         .help_str = "show_cpu_freq_mask <mask>, Get the current frequency for each "
495                         "core specified in the mask",
496         .tokens = {
497                 (void *)&cmd_show_cpu_freq_mask,
498                 (void *)&cmd_show_cpu_freq_mask_core_mask,
499                 NULL,
500         },
501 };
502
503 struct cmd_set_cpu_freq_mask_result {
504         cmdline_fixed_string_t set_cpu_freq_mask;
505         uint64_t core_mask;
506         cmdline_fixed_string_t cmd;
507 };
508
509 static void
510 cmd_set_cpu_freq_mask_parsed(void *parsed_result, struct cmdline *cl,
511                         __attribute__((unused)) void *data)
512 {
513         struct cmd_set_cpu_freq_mask_result *res = parsed_result;
514         int ret = -1;
515
516         if (!strcmp(res->cmd , "up"))
517                 ret = power_manager_scale_mask_up(res->core_mask);
518         else if (!strcmp(res->cmd , "down"))
519                 ret = power_manager_scale_mask_down(res->core_mask);
520         else if (!strcmp(res->cmd , "min"))
521                 ret = power_manager_scale_mask_min(res->core_mask);
522         else if (!strcmp(res->cmd , "max"))
523                 ret = power_manager_scale_mask_max(res->core_mask);
524         if (ret < 0) {
525                 cmdline_printf(cl, "Error scaling core_mask(0x%"PRIx64") '%s' , not "
526                                 "all cores specified have been scaled\n",
527                                 res->core_mask, res->cmd);
528         };
529 }
530
531 cmdline_parse_token_string_t cmd_set_cpu_freq_mask =
532         TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_mask_result,
533                         set_cpu_freq_mask, "set_cpu_freq_mask");
534 cmdline_parse_token_num_t cmd_set_cpu_freq_mask_core_mask =
535         TOKEN_NUM_INITIALIZER(struct cmd_set_cpu_freq_mask_result,
536                         core_mask, UINT64);
537 cmdline_parse_token_string_t cmd_set_cpu_freq_mask_result =
538         TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_mask_result,
539                         cmd, "up#down#min#max");
540
541 cmdline_parse_inst_t cmd_set_cpu_freq_mask_set = {
542         .f = cmd_set_cpu_freq_mask_parsed,
543         .data = NULL,
544         .help_str = "set_cpu_freq <core_mask> <up|down|min|max>, Set the current "
545                         "frequency for the cores specified in <core_mask> by scaling "
546                         "each up/down/min/max.",
547         .tokens = {
548                 (void *)&cmd_set_cpu_freq_mask,
549                 (void *)&cmd_set_cpu_freq_mask_core_mask,
550                 (void *)&cmd_set_cpu_freq_mask_result,
551                 NULL,
552         },
553 };
554
555
556
557 struct cmd_show_cpu_freq_result {
558         cmdline_fixed_string_t show_cpu_freq;
559         uint8_t core_num;
560 };
561
562 static void
563 cmd_show_cpu_freq_parsed(void *parsed_result, struct cmdline *cl,
564                        __attribute__((unused)) void *data)
565 {
566         struct cmd_show_cpu_freq_result *res = parsed_result;
567         uint32_t curr_freq = power_manager_get_current_frequency(res->core_num);
568
569         if (curr_freq == 0) {
570                 cmdline_printf(cl, "Unable to get frequency for core %u\n",
571                                 res->core_num);
572                 return;
573         }
574         cmdline_printf(cl, "Core %u frequency: %"PRId32"\n", res->core_num,
575                         curr_freq);
576 }
577
578 cmdline_parse_token_string_t cmd_show_cpu_freq =
579         TOKEN_STRING_INITIALIZER(struct cmd_show_cpu_freq_result,
580                         show_cpu_freq, "show_cpu_freq");
581
582 cmdline_parse_token_num_t cmd_show_cpu_freq_core_num =
583         TOKEN_NUM_INITIALIZER(struct cmd_show_cpu_freq_result,
584                         core_num, UINT8);
585
586 cmdline_parse_inst_t cmd_show_cpu_freq_set = {
587         .f = cmd_show_cpu_freq_parsed,
588         .data = NULL,
589         .help_str = "Get the current frequency for the specified core",
590         .tokens = {
591                 (void *)&cmd_show_cpu_freq,
592                 (void *)&cmd_show_cpu_freq_core_num,
593                 NULL,
594         },
595 };
596
597 struct cmd_set_cpu_freq_result {
598         cmdline_fixed_string_t set_cpu_freq;
599         uint8_t core_num;
600         cmdline_fixed_string_t cmd;
601 };
602
603 static void
604 cmd_set_cpu_freq_parsed(void *parsed_result, struct cmdline *cl,
605                        __attribute__((unused)) void *data)
606 {
607         int ret = -1;
608         struct cmd_set_cpu_freq_result *res = parsed_result;
609
610         if (!strcmp(res->cmd , "up"))
611                 ret = power_manager_scale_core_up(res->core_num);
612         else if (!strcmp(res->cmd , "down"))
613                 ret = power_manager_scale_core_down(res->core_num);
614         else if (!strcmp(res->cmd , "min"))
615                 ret = power_manager_scale_core_min(res->core_num);
616         else if (!strcmp(res->cmd , "max"))
617                 ret = power_manager_scale_core_max(res->core_num);
618         if (ret < 0) {
619                 cmdline_printf(cl, "Error scaling core(%u) '%s'\n", res->core_num,
620                                 res->cmd);
621         }
622 }
623
624 cmdline_parse_token_string_t cmd_set_cpu_freq =
625         TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result,
626                         set_cpu_freq, "set_cpu_freq");
627 cmdline_parse_token_num_t cmd_set_cpu_freq_core_num =
628         TOKEN_NUM_INITIALIZER(struct cmd_set_cpu_freq_result,
629                         core_num, UINT8);
630 cmdline_parse_token_string_t cmd_set_cpu_freq_cmd_cmd =
631         TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result,
632                         cmd, "up#down#min#max");
633
634 cmdline_parse_inst_t cmd_set_cpu_freq_set = {
635         .f = cmd_set_cpu_freq_parsed,
636         .data = NULL,
637         .help_str = "set_cpu_freq <core_num> <up|down|min|max>, Set the current "
638                         "frequency for the specified core by scaling up/down/min/max",
639         .tokens = {
640                 (void *)&cmd_set_cpu_freq,
641                 (void *)&cmd_set_cpu_freq_core_num,
642                 (void *)&cmd_set_cpu_freq_cmd_cmd,
643                 NULL,
644         },
645 };
646
647 cmdline_parse_ctx_t main_ctx[] = {
648                 (cmdline_parse_inst_t *)&cmd_quit,
649                 (cmdline_parse_inst_t *)&cmd_vm_op_set,
650                 (cmdline_parse_inst_t *)&cmd_channels_op_set,
651                 (cmdline_parse_inst_t *)&cmd_channels_status_op_set,
652                 (cmdline_parse_inst_t *)&cmd_show_vm_set,
653                 (cmdline_parse_inst_t *)&cmd_show_cpu_freq_mask_set,
654                 (cmdline_parse_inst_t *)&cmd_set_cpu_freq_mask_set,
655                 (cmdline_parse_inst_t *)&cmd_show_cpu_freq_set,
656                 (cmdline_parse_inst_t *)&cmd_set_cpu_freq_set,
657                 (cmdline_parse_inst_t *)&cmd_set_pcpu_mask_set,
658                 (cmdline_parse_inst_t *)&cmd_set_pcpu_set,
659                 NULL,
660 };
661
662 void
663 run_cli(__attribute__((unused)) void *arg)
664 {
665         struct cmdline *cl;
666
667         cl = cmdline_stdin_new(main_ctx, "vmpower> ");
668         if (cl == NULL)
669                 return;
670
671         cmdline_interact(cl);
672         cmdline_stdin_exit(cl);
673 }