/* rapl_interface.h: rapl interface for power top
 *
 * Copyright (C) 2012 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 *
 * Author Name <Srinivas.Pandruvada@linux.intel.com>
 *
 */

#pragma once

#include <cstdint>

class c_rapl_interface
{
private:
	static constexpr int def_sampling_interval = 1; //In seconds
	bool powercap_sysfs_present = false;
	std::string powercap_core_path;
	std::string powercap_uncore_path;
	std::string powercap_dram_path;

	unsigned char rapl_domains = 0;
	int first_cpu = 0;

	double power_units = 0.0;
	double energy_status_units = 0.0;
	double time_units = 0.0;

	int read_msr(int cpu, unsigned int idx, uint64_t *val) const;
	int write_msr(int cpu, unsigned int idx, uint64_t val);

protected:
	int measurement_interval = 0;
	double last_pkg_energy_status = 0.0;
	double last_dram_energy_status = 0.0;
	double last_pp0_energy_status = 0.0;
	double last_pp1_energy_status = 0.0;

public:
	c_rapl_interface(const std::string &dev_name = "package-0", int cpu = 0);

	int get_rapl_power_unit(uint64_t *value) const;
	double get_power_unit() const;
	double get_energy_status_unit() const;
	double get_time_unit() const;

	int get_pkg_energy_status(double *status) const;
	int get_pkg_power_info(double *thermal_spec_power,
			double *max_power, double *min_power, double *max_time_window) const;
	int get_pkg_power_limit(uint64_t *value) const;
	int set_pkg_power_limit(uint64_t value);

	int get_dram_energy_status(double *status) const;
	int get_dram_power_info(double *thermal_spec_power,
			double *max_power, double *min_power, double *max_time_window) const;
	int get_dram_power_limit(uint64_t *value) const;
	int set_dram_power_limit(uint64_t value);

	int get_pp0_energy_status(double *status) const;
	int get_pp0_power_limit(uint64_t *value) const;
	int set_pp0_power_limit(uint64_t value);
	int get_pp0_power_policy(unsigned int *pp0_power_policy) const;

	int get_pp1_energy_status(double *status) const;
	int get_pp1_power_limit(uint64_t *value) const;
	int set_pp1_power_limit(uint64_t value);
	int get_pp1_power_policy(unsigned int *pp1_power_policy) const;

	bool pkg_domain_present() const;
	bool dram_domain_present() const;
	bool pp0_domain_present() const;
	bool pp1_domain_present() const;

	void rapl_measure_energy();
};

