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