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