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
28extern int cpu_count;
29
30/* Hard to define the right names ...: */
31enum 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
39typedef 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
52struct 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	struct {
64		unsigned int needs_root:1;
65		unsigned int per_cpu_schedule:1;
66	} flags;
67};
68
69extern long long timespec_diff_us(struct timespec start, struct timespec end);
70
71#define print_overflow_err(mes, ov)						\
72{										\
73	fprintf(stderr, gettext("Measure took %u seconds, but registers could "	\
74				"overflow at %u seconds, results "		\
75				"could be inaccurate\n"), mes, ov);		\
76}
77
78
79/* Taken over from x86info project sources  -> return 0 on success */
80#include <sched.h>
81#include <sys/types.h>
82#include <unistd.h>
83static inline int bind_cpu(int cpu)
84{
85	cpu_set_t set;
86
87	if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
88		CPU_ZERO(&set);
89		CPU_SET(cpu, &set);
90		return sched_setaffinity(getpid(), sizeof(set), &set);
91	}
92	return 1;
93}
94
95#endif /* __CPUIDLE_INFO_HW__ */
96