// 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;
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,
	.needs_root		= 0,
	.overflow_s		= UINT_MAX,
};
