14f19048fSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
27fe2f639SDominik Brodowski /*
37fe2f639SDominik Brodowski  *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
47fe2f639SDominik Brodowski  */
57fe2f639SDominik Brodowski 
67fe2f639SDominik Brodowski #ifndef __CPUIDLE_INFO_HW__
77fe2f639SDominik Brodowski #define __CPUIDLE_INFO_HW__
87fe2f639SDominik Brodowski 
97fe2f639SDominik Brodowski #include <stdarg.h>
107fe2f639SDominik Brodowski #include <time.h>
117fe2f639SDominik Brodowski 
127fe2f639SDominik Brodowski #include "idle_monitor/idle_monitors.h"
137fe2f639SDominik Brodowski 
147fe2f639SDominik Brodowski #define MONITORS_MAX 20
157fe2f639SDominik Brodowski #define MONITOR_NAME_LEN 20
16f9652d5cSAbhishek Goel 
17f9652d5cSAbhishek Goel /* CSTATE_NAME_LEN is limited by header field width defined
18f9652d5cSAbhishek Goel  * in cpupower-monitor.c. Header field width is defined to be
19f9652d5cSAbhishek Goel  * sum of percent width and two spaces for padding.
20f9652d5cSAbhishek Goel  */
21f9652d5cSAbhishek Goel #ifdef __powerpc__
22f9652d5cSAbhishek Goel #define CSTATE_NAME_LEN 7
23f9652d5cSAbhishek Goel #else
247fe2f639SDominik Brodowski #define CSTATE_NAME_LEN 5
25f9652d5cSAbhishek Goel #endif
267fe2f639SDominik Brodowski #define CSTATE_DESC_LEN 60
277fe2f639SDominik Brodowski 
282de7fb60SMike Gilbert extern int cpu_count;
297fe2f639SDominik Brodowski 
307fe2f639SDominik Brodowski /* Hard to define the right names ...: */
317fe2f639SDominik Brodowski enum power_range_e {
327fe2f639SDominik Brodowski 	RANGE_THREAD,	/* Lowest in topology hierarcy, AMD: core, Intel: thread
337fe2f639SDominik Brodowski 			   kernel sysfs: cpu */
347fe2f639SDominik Brodowski 	RANGE_CORE,	/* AMD: unit, Intel: core, kernel_sysfs: core_id */
357fe2f639SDominik Brodowski 	RANGE_PACKAGE,	/* Package, processor socket */
367fe2f639SDominik Brodowski 	RANGE_MACHINE,	/* Machine, platform wide */
377fe2f639SDominik Brodowski 	RANGE_MAX };
387fe2f639SDominik Brodowski 
397fe2f639SDominik Brodowski typedef struct cstate {
407fe2f639SDominik Brodowski 	int  id;
417fe2f639SDominik Brodowski 	enum power_range_e range;
427fe2f639SDominik Brodowski 	char name[CSTATE_NAME_LEN];
437fe2f639SDominik Brodowski 	char desc[CSTATE_DESC_LEN];
447fe2f639SDominik Brodowski 
457fe2f639SDominik Brodowski 	/* either provide a percentage or a general count */
467fe2f639SDominik Brodowski 	int (*get_count_percent)(unsigned int self_id, double *percent,
477fe2f639SDominik Brodowski 				 unsigned int cpu);
487fe2f639SDominik Brodowski 	int (*get_count)(unsigned int self_id, unsigned long long *count,
497fe2f639SDominik Brodowski 			 unsigned int cpu);
507fe2f639SDominik Brodowski } cstate_t;
517fe2f639SDominik Brodowski 
527fe2f639SDominik Brodowski struct cpuidle_monitor {
537fe2f639SDominik Brodowski 	/* Name must not contain whitespaces */
547fe2f639SDominik Brodowski 	char name[MONITOR_NAME_LEN];
557fe2f639SDominik Brodowski 	int name_len;
567fe2f639SDominik Brodowski 	int hw_states_num;
577fe2f639SDominik Brodowski 	cstate_t *hw_states;
587fe2f639SDominik Brodowski 	int (*start) (void);
597fe2f639SDominik Brodowski 	int (*stop) (void);
607fe2f639SDominik Brodowski 	struct cpuidle_monitor* (*do_register) (void);
617fe2f639SDominik Brodowski 	void (*unregister)(void);
627fe2f639SDominik Brodowski 	unsigned int overflow_s;
63d3f5d2a1SJanakarajan Natarajan 	struct {
64d3f5d2a1SJanakarajan Natarajan 		unsigned int needs_root:1;
657adafe54SJanakarajan Natarajan 		unsigned int per_cpu_schedule:1;
66d3f5d2a1SJanakarajan Natarajan 	} flags;
677fe2f639SDominik Brodowski };
687fe2f639SDominik Brodowski 
697fe2f639SDominik Brodowski extern long long timespec_diff_us(struct timespec start, struct timespec end);
707fe2f639SDominik Brodowski 
717fe2f639SDominik Brodowski #define print_overflow_err(mes, ov)						\
727fe2f639SDominik Brodowski {										\
737fe2f639SDominik Brodowski 	fprintf(stderr, gettext("Measure took %u seconds, but registers could "	\
747fe2f639SDominik Brodowski 				"overflow at %u seconds, results "		\
757fe2f639SDominik Brodowski 				"could be inaccurate\n"), mes, ov);		\
767fe2f639SDominik Brodowski }
777fe2f639SDominik Brodowski 
78c8cfc3c6SThomas Renninger 
79c8cfc3c6SThomas Renninger /* Taken over from x86info project sources  -> return 0 on success */
80c8cfc3c6SThomas Renninger #include <sched.h>
81c8cfc3c6SThomas Renninger #include <sys/types.h>
82c8cfc3c6SThomas Renninger #include <unistd.h>
bind_cpu(int cpu)83c8cfc3c6SThomas Renninger static inline int bind_cpu(int cpu)
84c8cfc3c6SThomas Renninger {
85c8cfc3c6SThomas Renninger 	cpu_set_t set;
86c8cfc3c6SThomas Renninger 
87c8cfc3c6SThomas Renninger 	if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
88c8cfc3c6SThomas Renninger 		CPU_ZERO(&set);
89c8cfc3c6SThomas Renninger 		CPU_SET(cpu, &set);
90c8cfc3c6SThomas Renninger 		return sched_setaffinity(getpid(), sizeof(set), &set);
91c8cfc3c6SThomas Renninger 	}
92c8cfc3c6SThomas Renninger 	return 1;
93c8cfc3c6SThomas Renninger }
94c8cfc3c6SThomas Renninger 
957fe2f639SDominik Brodowski #endif /* __CPUIDLE_INFO_HW__ */
96