// SPDX-License-Identifier: GPL-2.0-only
/*
 *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <cpuidle.h>

#include "helpers/helpers.h"
#include "idle_monitor/cpupower-monitor.h"

#define CPUIDLE_STATES_MAX 10
static cstate_t cpuidle_cstates[CPUIDLE_STATES_MAX];
struct cpuidle_monitor cpuidle_sysfs_monitor;

static unsigned long long **previous_count;
static unsigned long long **current_count;
static struct timespec start_time;
static unsigned long long timediff;

static int cpuidle_get_count_percent(unsigned int id, double *percent,
				     unsigned int cpu)
{
	unsigned long long statediff = current_count[cpu][id]
		- previous_count[cpu][id];
	dprint("%s: - diff: %llu - percent: %f (%u)\n",
	       cpuidle_cstates[id].name, timediff, *percent, cpu);

	if (timediff == 0)
		*percent = 0.0;
	else
		*percent = ((100.0 * statediff) / timediff);

	dprint("%s: - timediff: %llu - statediff: %llu - percent: %f (%u)\n",
	       cpuidle_cstates[id].name, timediff, statediff, *percent, cpu);

	return 0;
}

static int cpuidle_start(void)
{
	int cpu, state;
	clock_gettime(CLOCK_REALTIME, &start_time);
	for (cpu = 0; cpu < cpu_count; cpu++) {
		for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num;
		     state++) {
			previous_count[cpu][state] =
				cpuidle_state_time(cpu, state);
			dprint("CPU %d - State: %d - Val: %llu\n",
			       cpu, state, previous_count[cpu][state]);
		}
	}
	return 0;
}

static int cpuidle_stop(void)
{
	int cpu, state;
	struct timespec end_time;
	clock_gettime(CLOCK_REALTIME, &end_time);
	timediff = timespec_diff_us(start_time, end_time);

	for (cpu = 0; cpu < cpu_count; cpu++) {
		for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num;
		     state++) {
			current_count[cpu][state] =
				cpuidle_state_time(cpu, state);
			dprint("CPU %d - State: %d - Val: %llu\n",
			       cpu, state, previous_count[cpu][state]);
		}
	}
	return 0;
}

void fix_up_intel_idle_driver_name(char *tmp, int num)
{
	/* fix up cpuidle name for intel idle driver */
	if (!strncmp(tmp, "NHM-", 4)) {
		switch (num) {
		case 1:
			strcpy(tmp, "C1");
			break;
		case 2:
			strcpy(tmp, "C3");
			break;
		case 3:
			strcpy(tmp, "C6");
			break;
		}
	} else if (!strncmp(tmp, "SNB-", 4)) {
		switch (num) {
		case 1:
			strcpy(tmp, "C1");
			break;
		case 2:
			strcpy(tmp, "C3");
			break;
		case 3:
			strcpy(tmp, "C6");
			break;
		case 4:
			strcpy(tmp, "C7");
			break;
		}
	} else if (!strncmp(tmp, "ATM-", 4)) {
		switch (num) {
		case 1:
			strcpy(tmp, "C1");
			break;
		case 2:
			strcpy(tmp, "C2");
			break;
		case 3:
			strcpy(tmp, "C4");
			break;
		case 4:
			strcpy(tmp, "C6");
			break;
		}
	}
}

#ifdef __powerpc__
void map_power_idle_state_name(char *tmp)
{
	if (!strncmp(tmp, "stop0_lite", CSTATE_NAME_LEN))
		strcpy(tmp, "stop0L");
	else if (!strncmp(tmp, "stop1_lite", CSTATE_NAME_LEN))
		strcpy(tmp, "stop1L");
	else if (!strncmp(tmp, "stop2_lite", CSTATE_NAME_LEN))
		strcpy(tmp, "stop2L");
}
#else
void map_power_idle_state_name(char *tmp) { }
#endif

static struct cpuidle_monitor *cpuidle_register(void)
{
	int num;
	char *tmp;
	int this_cpu;

	this_cpu = sched_getcpu();

	/* Assume idle state count is the same for all CPUs */
	cpuidle_sysfs_monitor.hw_states_num = cpuidle_state_count(this_cpu);

	if (cpuidle_sysfs_monitor.hw_states_num <= 0)
		return NULL;

	for (num = 0; num < cpuidle_sysfs_monitor.hw_states_num; num++) {
		tmp = cpuidle_state_name(this_cpu, num);
		if (tmp == NULL)
			continue;

		map_power_idle_state_name(tmp);
		fix_up_intel_idle_driver_name(tmp, num);
		strncpy(cpuidle_cstates[num].name, tmp, CSTATE_NAME_LEN - 1);
		free(tmp);

		tmp = cpuidle_state_desc(this_cpu, num);
		if (tmp == NULL)
			continue;
		strncpy(cpuidle_cstates[num].desc, tmp,	CSTATE_DESC_LEN - 1);
		free(tmp);

		cpuidle_cstates[num].range = RANGE_THREAD;
		cpuidle_cstates[num].id = num;
		cpuidle_cstates[num].get_count_percent =
			cpuidle_get_count_percent;
	}

	/* Free this at program termination */
	previous_count = malloc(sizeof(long long *) * cpu_count);
	current_count = malloc(sizeof(long long *) * cpu_count);
	for (num = 0; num < cpu_count; num++) {
		previous_count[num] = malloc(sizeof(long long) *
					cpuidle_sysfs_monitor.hw_states_num);
		current_count[num] = malloc(sizeof(long long) *
					cpuidle_sysfs_monitor.hw_states_num);
	}

	cpuidle_sysfs_monitor.name_len = strlen(cpuidle_sysfs_monitor.name);
	return &cpuidle_sysfs_monitor;
}

void cpuidle_unregister(void)
{
	int num;

	for (num = 0; num < cpu_count; num++) {
		free(previous_count[num]);
		free(current_count[num]);
	}
	free(previous_count);
	free(current_count);
}

struct cpuidle_monitor cpuidle_sysfs_monitor = {
	.name			= "Idle_Stats",
	.hw_states		= cpuidle_cstates,
	.start			= cpuidle_start,
	.stop			= cpuidle_stop,
	.do_register		= cpuidle_register,
	.unregister		= cpuidle_unregister,
	.flags.needs_root	= 0,
	.overflow_s		= UINT_MAX,
};
