1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
4  */
5 
6 #ifndef __CPUIDLE_INFO_HW__
7 #define __CPUIDLE_INFO_HW__
8 
9 #include <stdarg.h>
10 #include <time.h>
11 
12 #include "idle_monitor/idle_monitors.h"
13 
14 #define MONITORS_MAX 20
15 #define MONITOR_NAME_LEN 20
16 
17 /* CSTATE_NAME_LEN is limited by header field width defined
18  * in cpupower-monitor.c. Header field width is defined to be
19  * sum of percent width and two spaces for padding.
20  */
21 #ifdef __powerpc__
22 #define CSTATE_NAME_LEN 7
23 #else
24 #define CSTATE_NAME_LEN 5
25 #endif
26 #define CSTATE_DESC_LEN 60
27 
28 int cpu_count;
29 
30 /* Hard to define the right names ...: */
31 enum power_range_e {
32 	RANGE_THREAD,	/* Lowest in topology hierarcy, AMD: core, Intel: thread
33 			   kernel sysfs: cpu */
34 	RANGE_CORE,	/* AMD: unit, Intel: core, kernel_sysfs: core_id */
35 	RANGE_PACKAGE,	/* Package, processor socket */
36 	RANGE_MACHINE,	/* Machine, platform wide */
37 	RANGE_MAX };
38 
39 typedef struct cstate {
40 	int  id;
41 	enum power_range_e range;
42 	char name[CSTATE_NAME_LEN];
43 	char desc[CSTATE_DESC_LEN];
44 
45 	/* either provide a percentage or a general count */
46 	int (*get_count_percent)(unsigned int self_id, double *percent,
47 				 unsigned int cpu);
48 	int (*get_count)(unsigned int self_id, unsigned long long *count,
49 			 unsigned int cpu);
50 } cstate_t;
51 
52 struct cpuidle_monitor {
53 	/* Name must not contain whitespaces */
54 	char name[MONITOR_NAME_LEN];
55 	int name_len;
56 	int hw_states_num;
57 	cstate_t *hw_states;
58 	int (*start) (void);
59 	int (*stop) (void);
60 	struct cpuidle_monitor* (*do_register) (void);
61 	void (*unregister)(void);
62 	unsigned int overflow_s;
63 	int needs_root;
64 };
65 
66 extern long long timespec_diff_us(struct timespec start, struct timespec end);
67 
68 #define print_overflow_err(mes, ov)						\
69 {										\
70 	fprintf(stderr, gettext("Measure took %u seconds, but registers could "	\
71 				"overflow at %u seconds, results "		\
72 				"could be inaccurate\n"), mes, ov);		\
73 }
74 
75 
76 /* Taken over from x86info project sources  -> return 0 on success */
77 #include <sched.h>
78 #include <sys/types.h>
79 #include <unistd.h>
80 static inline int bind_cpu(int cpu)
81 {
82 	cpu_set_t set;
83 
84 	if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
85 		CPU_ZERO(&set);
86 		CPU_SET(cpu, &set);
87 		return sched_setaffinity(getpid(), sizeof(set), &set);
88 	}
89 	return 1;
90 }
91 
92 #endif /* __CPUIDLE_INFO_HW__ */
93