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 } 651