1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606  * Copyright(c) 2010-2014 Intel Corporation
3a9643ea8Slogwang  */
4a9643ea8Slogwang 
5a9643ea8Slogwang #include <stdio.h>
65af785ecSfengbojiang(姜凤波) #include <stdlib.h>
75af785ecSfengbojiang(姜凤波) #include <signal.h>
8d30ea906Sjfb8856606 #include <getopt.h>
9d30ea906Sjfb8856606 #include <string.h>
10a9643ea8Slogwang 
11a9643ea8Slogwang #include <rte_lcore.h>
12a9643ea8Slogwang #include <rte_power.h>
13a9643ea8Slogwang #include <rte_debug.h>
14d30ea906Sjfb8856606 #include <rte_eal.h>
15d30ea906Sjfb8856606 #include <rte_log.h>
16a9643ea8Slogwang 
17a9643ea8Slogwang #include "vm_power_cli_guest.h"
18d30ea906Sjfb8856606 #include "parse.h"
19a9643ea8Slogwang 
20a9643ea8Slogwang static void
sig_handler(int signo)21a9643ea8Slogwang sig_handler(int signo)
22a9643ea8Slogwang {
23a9643ea8Slogwang 	printf("Received signal %d, exiting...\n", signo);
24a9643ea8Slogwang 	unsigned lcore_id;
25a9643ea8Slogwang 
26a9643ea8Slogwang 	RTE_LCORE_FOREACH(lcore_id) {
27a9643ea8Slogwang 		rte_power_exit(lcore_id);
28a9643ea8Slogwang 	}
29a9643ea8Slogwang 
30a9643ea8Slogwang }
31a9643ea8Slogwang 
32d30ea906Sjfb8856606 #define MAX_HOURS 24
33d30ea906Sjfb8856606 
34d30ea906Sjfb8856606 /* Parse the argument given in the command line of the application */
35d30ea906Sjfb8856606 static int
parse_args(int argc,char ** argv)36d30ea906Sjfb8856606 parse_args(int argc, char **argv)
37d30ea906Sjfb8856606 {
38d30ea906Sjfb8856606 	int opt, ret;
39d30ea906Sjfb8856606 	char **argvopt;
40d30ea906Sjfb8856606 	int option_index;
41d30ea906Sjfb8856606 	char *prgname = argv[0];
42d30ea906Sjfb8856606 	const struct option lgopts[] = {
43d30ea906Sjfb8856606 		{ "vm-name", required_argument, 0, 'n'},
44d30ea906Sjfb8856606 		{ "busy-hours", required_argument, 0, 'b'},
45d30ea906Sjfb8856606 		{ "quiet-hours", required_argument, 0, 'q'},
46d30ea906Sjfb8856606 		{ "port-list", required_argument, 0, 'p'},
47d30ea906Sjfb8856606 		{ "vcpu-list", required_argument, 0, 'l'},
48d30ea906Sjfb8856606 		{ "policy", required_argument, 0, 'o'},
49d30ea906Sjfb8856606 		{NULL, 0, 0, 0}
50d30ea906Sjfb8856606 	};
51d30ea906Sjfb8856606 	struct channel_packet *policy;
52d30ea906Sjfb8856606 	unsigned short int hours[MAX_HOURS];
53d30ea906Sjfb8856606 	unsigned short int cores[MAX_VCPU_PER_VM];
54d30ea906Sjfb8856606 	unsigned short int ports[MAX_VCPU_PER_VM];
55d30ea906Sjfb8856606 	int i, cnt, idx;
56d30ea906Sjfb8856606 
57d30ea906Sjfb8856606 	policy = get_policy();
58*4418919fSjohnjiang 	ret = set_policy_defaults(policy);
59*4418919fSjohnjiang 	if (ret != 0) {
60*4418919fSjohnjiang 		printf("Failed to set policy defaults\n");
61*4418919fSjohnjiang 		return -1;
62*4418919fSjohnjiang 	}
63d30ea906Sjfb8856606 
64d30ea906Sjfb8856606 	argvopt = argv;
65d30ea906Sjfb8856606 
66d30ea906Sjfb8856606 	while ((opt = getopt_long(argc, argvopt, "n:b:q:p:",
67d30ea906Sjfb8856606 				  lgopts, &option_index)) != EOF) {
68d30ea906Sjfb8856606 
69d30ea906Sjfb8856606 		switch (opt) {
70d30ea906Sjfb8856606 		/* portmask */
71d30ea906Sjfb8856606 		case 'n':
724b05018fSfengbojiang 			strlcpy(policy->vm_name, optarg, VM_MAX_NAME_SZ);
73d30ea906Sjfb8856606 			printf("Setting VM Name to [%s]\n", policy->vm_name);
74d30ea906Sjfb8856606 			break;
75d30ea906Sjfb8856606 		case 'b':
76d30ea906Sjfb8856606 		case 'q':
77d30ea906Sjfb8856606 			//printf("***Processing set using [%s]\n", optarg);
78d30ea906Sjfb8856606 			cnt = parse_set(optarg, hours, MAX_HOURS);
79d30ea906Sjfb8856606 			if (cnt < 0) {
80d30ea906Sjfb8856606 				printf("Invalid value passed to quiet/busy hours - [%s]\n",
81d30ea906Sjfb8856606 						optarg);
82d30ea906Sjfb8856606 				break;
83d30ea906Sjfb8856606 			}
84d30ea906Sjfb8856606 			idx = 0;
85d30ea906Sjfb8856606 			for (i = 0; i < MAX_HOURS; i++) {
86d30ea906Sjfb8856606 				if (hours[i]) {
87d30ea906Sjfb8856606 					if (opt == 'b') {
88d30ea906Sjfb8856606 						printf("***Busy Hour %d\n", i);
89d30ea906Sjfb8856606 						policy->timer_policy.busy_hours
90d30ea906Sjfb8856606 							[idx++] = i;
91d30ea906Sjfb8856606 					} else {
92d30ea906Sjfb8856606 						printf("***Quiet Hour %d\n", i);
93d30ea906Sjfb8856606 						policy->timer_policy.quiet_hours
94d30ea906Sjfb8856606 							[idx++] = i;
95d30ea906Sjfb8856606 					}
96d30ea906Sjfb8856606 				}
97d30ea906Sjfb8856606 			}
98d30ea906Sjfb8856606 			break;
99d30ea906Sjfb8856606 		case 'l':
100d30ea906Sjfb8856606 			cnt = parse_set(optarg, cores, MAX_VCPU_PER_VM);
101d30ea906Sjfb8856606 			if (cnt < 0) {
102d30ea906Sjfb8856606 				printf("Invalid value passed to vcpu-list - [%s]\n",
103d30ea906Sjfb8856606 						optarg);
104d30ea906Sjfb8856606 				break;
105d30ea906Sjfb8856606 			}
106d30ea906Sjfb8856606 			idx = 0;
107d30ea906Sjfb8856606 			for (i = 0; i < MAX_VCPU_PER_VM; i++) {
108d30ea906Sjfb8856606 				if (cores[i]) {
109d30ea906Sjfb8856606 					printf("***Using core %d\n", i);
110d30ea906Sjfb8856606 					policy->vcpu_to_control[idx++] = i;
111d30ea906Sjfb8856606 				}
112d30ea906Sjfb8856606 			}
113d30ea906Sjfb8856606 			policy->num_vcpu = idx;
114d30ea906Sjfb8856606 			printf("Total cores: %d\n", idx);
115d30ea906Sjfb8856606 			break;
116d30ea906Sjfb8856606 		case 'p':
117d30ea906Sjfb8856606 			cnt = parse_set(optarg, ports, MAX_VCPU_PER_VM);
118d30ea906Sjfb8856606 			if (cnt < 0) {
119d30ea906Sjfb8856606 				printf("Invalid value passed to port-list - [%s]\n",
120d30ea906Sjfb8856606 						optarg);
121d30ea906Sjfb8856606 				break;
122d30ea906Sjfb8856606 			}
123d30ea906Sjfb8856606 			idx = 0;
124d30ea906Sjfb8856606 			for (i = 0; i < MAX_VCPU_PER_VM; i++) {
125d30ea906Sjfb8856606 				if (ports[i]) {
126d30ea906Sjfb8856606 					printf("***Using port %d\n", i);
127*4418919fSjohnjiang 					if (set_policy_mac(i, idx++) != 0) {
128*4418919fSjohnjiang 						printf("Cannot set policy MAC");
129*4418919fSjohnjiang 						return -1;
130*4418919fSjohnjiang 					}
131d30ea906Sjfb8856606 				}
132d30ea906Sjfb8856606 			}
133d30ea906Sjfb8856606 			policy->nb_mac_to_monitor = idx;
134d30ea906Sjfb8856606 			printf("Total Ports: %d\n", idx);
135d30ea906Sjfb8856606 			break;
136d30ea906Sjfb8856606 		case 'o':
137d30ea906Sjfb8856606 			if (!strcmp(optarg, "TRAFFIC"))
138d30ea906Sjfb8856606 				policy->policy_to_use = TRAFFIC;
139d30ea906Sjfb8856606 			else if (!strcmp(optarg, "TIME"))
140d30ea906Sjfb8856606 				policy->policy_to_use = TIME;
141d30ea906Sjfb8856606 			else if (!strcmp(optarg, "WORKLOAD"))
142d30ea906Sjfb8856606 				policy->policy_to_use = WORKLOAD;
143d30ea906Sjfb8856606 			else if (!strcmp(optarg, "BRANCH_RATIO"))
144d30ea906Sjfb8856606 				policy->policy_to_use = BRANCH_RATIO;
145d30ea906Sjfb8856606 			else {
146d30ea906Sjfb8856606 				printf("Invalid policy specified: %s\n",
147d30ea906Sjfb8856606 						optarg);
148d30ea906Sjfb8856606 				return -1;
149d30ea906Sjfb8856606 			}
150d30ea906Sjfb8856606 			break;
151d30ea906Sjfb8856606 		/* long options */
152d30ea906Sjfb8856606 
153d30ea906Sjfb8856606 		case 0:
154d30ea906Sjfb8856606 			break;
155d30ea906Sjfb8856606 
156d30ea906Sjfb8856606 		default:
157d30ea906Sjfb8856606 			return -1;
158d30ea906Sjfb8856606 		}
159d30ea906Sjfb8856606 	}
160d30ea906Sjfb8856606 
161d30ea906Sjfb8856606 	if (optind >= 0)
162d30ea906Sjfb8856606 		argv[optind-1] = prgname;
163d30ea906Sjfb8856606 
164d30ea906Sjfb8856606 	ret = optind-1;
165d30ea906Sjfb8856606 	optind = 0; /* reset getopt lib */
166d30ea906Sjfb8856606 	return ret;
167d30ea906Sjfb8856606 }
168d30ea906Sjfb8856606 
169a9643ea8Slogwang int
main(int argc,char ** argv)170a9643ea8Slogwang main(int argc, char **argv)
171a9643ea8Slogwang {
172a9643ea8Slogwang 	int ret;
173a9643ea8Slogwang 	unsigned lcore_id;
174a9643ea8Slogwang 
175a9643ea8Slogwang 	ret = rte_eal_init(argc, argv);
176a9643ea8Slogwang 	if (ret < 0)
177a9643ea8Slogwang 		rte_panic("Cannot init EAL\n");
178a9643ea8Slogwang 
179a9643ea8Slogwang 	signal(SIGINT, sig_handler);
180a9643ea8Slogwang 	signal(SIGTERM, sig_handler);
181a9643ea8Slogwang 
182d30ea906Sjfb8856606 	argc -= ret;
183d30ea906Sjfb8856606 	argv += ret;
184d30ea906Sjfb8856606 
185d30ea906Sjfb8856606 	/* parse application arguments (after the EAL ones) */
186d30ea906Sjfb8856606 	ret = parse_args(argc, argv);
187d30ea906Sjfb8856606 	if (ret < 0)
188d30ea906Sjfb8856606 		rte_exit(EXIT_FAILURE, "Invalid arguments\n");
189d30ea906Sjfb8856606 
190a9643ea8Slogwang 	rte_power_set_env(PM_ENV_KVM_VM);
191a9643ea8Slogwang 	RTE_LCORE_FOREACH(lcore_id) {
192a9643ea8Slogwang 		rte_power_init(lcore_id);
193a9643ea8Slogwang 	}
194a9643ea8Slogwang 	run_cli(NULL);
195a9643ea8Slogwang 
196a9643ea8Slogwang 	return 0;
197a9643ea8Slogwang }
198