cregit-Linux how code gets into the kernel

Release 4.14 drivers/powercap/intel_rapl.c

Directory: drivers/powercap
/*
 * Intel Running Average Power Limit (RAPL) Driver
 * Copyright (c) 2013, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 *
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/log2.h>
#include <linux/bitmap.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/cpu.h>
#include <linux/powercap.h>
#include <asm/iosf_mbi.h>

#include <asm/processor.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>

/* Local defines */

#define MSR_PLATFORM_POWER_LIMIT	0x0000065C

/* bitmasks for RAPL MSRs, used by primitive access functions */

#define ENERGY_STATUS_MASK      0xffffffff


#define POWER_LIMIT1_MASK       0x7FFF

#define POWER_LIMIT1_ENABLE     BIT(15)

#define POWER_LIMIT1_CLAMP      BIT(16)


#define POWER_LIMIT2_MASK       (0x7FFFULL<<32)

#define POWER_LIMIT2_ENABLE     BIT_ULL(47)

#define POWER_LIMIT2_CLAMP      BIT_ULL(48)

#define POWER_PACKAGE_LOCK      BIT_ULL(63)

#define POWER_PP_LOCK           BIT(31)


#define TIME_WINDOW1_MASK       (0x7FULL<<17)

#define TIME_WINDOW2_MASK       (0x7FULL<<49)


#define POWER_UNIT_OFFSET	0

#define POWER_UNIT_MASK		0x0F


#define ENERGY_UNIT_OFFSET	0x08

#define ENERGY_UNIT_MASK	0x1F00


#define TIME_UNIT_OFFSET	0x10

#define TIME_UNIT_MASK		0xF0000


#define POWER_INFO_MAX_MASK     (0x7fffULL<<32)

#define POWER_INFO_MIN_MASK     (0x7fffULL<<16)

#define POWER_INFO_MAX_TIME_WIN_MASK     (0x3fULL<<48)

#define POWER_INFO_THERMAL_SPEC_MASK     0x7fff


#define PERF_STATUS_THROTTLE_TIME_MASK 0xffffffff

#define PP_POLICY_MASK         0x1F

/* Non HW constants */

#define RAPL_PRIMITIVE_DERIVED       BIT(1) 
/* not from raw data */

#define RAPL_PRIMITIVE_DUMMY         BIT(2)


#define TIME_WINDOW_MAX_MSEC 40000

#define TIME_WINDOW_MIN_MSEC 250

#define ENERGY_UNIT_SCALE    1000 
/* scale from driver unit to powercap unit */

enum unit_type {
	
ARBITRARY_UNIT, /* no translation */
	
POWER_UNIT,
	
ENERGY_UNIT,
	
TIME_UNIT,
};


enum rapl_domain_type {
	
RAPL_DOMAIN_PACKAGE, /* entire package/socket */
	
RAPL_DOMAIN_PP0, /* core power plane */
	
RAPL_DOMAIN_PP1, /* graphics uncore */
	
RAPL_DOMAIN_DRAM,/* DRAM control_type */
	
RAPL_DOMAIN_PLATFORM, /* PSys control_type */
	
RAPL_DOMAIN_MAX,
};


enum rapl_domain_msr_id {
	
RAPL_DOMAIN_MSR_LIMIT,
	
RAPL_DOMAIN_MSR_STATUS,
	
RAPL_DOMAIN_MSR_PERF,
	
RAPL_DOMAIN_MSR_POLICY,
	
RAPL_DOMAIN_MSR_INFO,
	
RAPL_DOMAIN_MSR_MAX,
};

/* per domain data, some are optional */

enum rapl_primitives {
	
ENERGY_COUNTER,
	
POWER_LIMIT1,
	
POWER_LIMIT2,
	
FW_LOCK,

	
PL1_ENABLE,  /* power limit 1, aka long term */
	
PL1_CLAMP,   /* allow frequency to go below OS request */
	
PL2_ENABLE,  /* power limit 2, aka short term, instantaneous */
	
PL2_CLAMP,

	
TIME_WINDOW1, /* long term */
	
TIME_WINDOW2, /* short term */
	
THERMAL_SPEC_POWER,
	
MAX_POWER,

	
MIN_POWER,
	
MAX_TIME_WINDOW,
	
THROTTLED_TIME,
	
PRIORITY_LEVEL,

	/* below are not raw primitive data */
	
AVERAGE_POWER,
	
NR_RAPL_PRIMITIVES,
};


#define NR_RAW_PRIMITIVES (NR_RAPL_PRIMITIVES - 2)

/* Can be expanded to include events, etc.*/

struct rapl_domain_data {
	
u64 primitives[NR_RAPL_PRIMITIVES];
	
unsigned long timestamp;
};


struct msrl_action {
	
u32 msr_no;
	
u64 clear_mask;
	
u64 set_mask;
	
int err;
};


#define	DOMAIN_STATE_INACTIVE           BIT(0)

#define	DOMAIN_STATE_POWER_LIMIT_SET    BIT(1)

#define DOMAIN_STATE_BIOS_LOCKED        BIT(2)


#define NR_POWER_LIMITS (2)

struct rapl_power_limit {
	
struct powercap_zone_constraint *constraint;
	
int prim_id; /* primitive ID used to enable */
	
struct rapl_domain *domain;
	
const char *name;
};


static const char pl1_name[] = "long_term";

static const char pl2_name[] = "short_term";

struct rapl_package;

struct rapl_domain {
	
const char *name;
	
enum rapl_domain_type id;
	
int msrs[RAPL_DOMAIN_MSR_MAX];
	
struct powercap_zone power_zone;
	
struct rapl_domain_data rdd;
	
struct rapl_power_limit rpl[NR_POWER_LIMITS];
	
u64 attr_map; /* track capabilities */
	
unsigned int state;
	
unsigned int domain_energy_unit;
	
struct rapl_package *rp;
};

#define power_zone_to_rapl_domain(_zone) \
	container_of(_zone, struct rapl_domain, power_zone)


/* Each physical package contains multiple domains, these are the common
 * data across RAPL domains within a package.
 */

struct rapl_package {
	
unsigned int id; /* physical package/socket id */
	
unsigned int nr_domains;
	
unsigned long domain_map; /* bit map of active domains */
	
unsigned int power_unit;
	
unsigned int energy_unit;
	
unsigned int time_unit;
	
struct rapl_domain *domains; /* array of domains, sized at runtime */
	
struct powercap_zone *power_zone; /* keep track of parent zone */
	
unsigned long power_limit_irq; /* keep track of package power limit
                                        * notify interrupt enable status.
                                        */
	
struct list_head plist;
	
int lead_cpu; /* one active cpu per package for access */
	/* Track active cpus */
	
struct cpumask cpumask;
};


struct rapl_defaults {
	
u8 floor_freq_reg_addr;
	
int (*check_unit)(struct rapl_package *rp, int cpu);
	
void (*set_floor_freq)(struct rapl_domain *rd, bool mode);
	
u64 (*compute_time_window)(struct rapl_package *rp, u64 val,
				bool to_raw);
	
unsigned int dram_domain_energy_unit;
};

static struct rapl_defaults *rapl_defaults;

/* Sideband MBI registers */

#define IOSF_CPU_POWER_BUDGET_CTL_BYT (0x2)

#define IOSF_CPU_POWER_BUDGET_CTL_TNG (0xdf)


#define PACKAGE_PLN_INT_SAVED   BIT(0)

#define MAX_PRIM_NAME (32)

/* per domain data. used to describe individual knobs such that access function
 * can be consolidated into one instead of many inline functions.
 */

struct rapl_primitive_info {
	
const char *name;
	
u64 mask;
	
int shift;
	
enum rapl_domain_msr_id id;
	
enum unit_type unit;
	
u32 flag;
};


#define PRIMITIVE_INFO_INIT(p, m, s, i, u, f) {       \
                .name = #p,                     \
                .mask = m,                      \
                .shift = s,                     \
                .id = i,                        \
                .unit = u,                      \
                .flag = f                       \
        }

static void rapl_init_domains(struct rapl_package *rp);
static int rapl_read_data_raw(struct rapl_domain *rd,
			enum rapl_primitives prim,
			bool xlate, u64 *data);
static int rapl_write_data_raw(struct rapl_domain *rd,
			enum rapl_primitives prim,
			unsigned long long value);
static u64 rapl_unit_xlate(struct rapl_domain *rd,
			enum unit_type type, u64 value,
			int to_raw);
static void package_power_limit_irq_save(struct rapl_package *rp);

static LIST_HEAD(rapl_packages); /* guarded by CPU hotplug lock */


static const char * const rapl_domain_names[] = {
	"package",
	"core",
	"uncore",
	"dram",
	"psys",
};


static struct powercap_control_type *control_type; 
/* PowerCap Controller */

static struct rapl_domain *platform_rapl_domain; 
/* Platform (PSys) domain */

/* caller to ensure CPU hotplug lock is held */

static struct rapl_package *find_package_by_id(int id) { struct rapl_package *rp; list_for_each_entry(rp, &rapl_packages, plist) { if (rp->id == id) return rp; } return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan40100.00%1100.00%
Total40100.00%1100.00%


static int get_energy_counter(struct powercap_zone *power_zone, u64 *energy_raw) { struct rapl_domain *rd; u64 energy_now; /* prevent CPU hotplug, make sure the RAPL domain does not go * away while reading the counter. */ get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); if (!rapl_read_data_raw(rd, ENERGY_COUNTER, true, &energy_now)) { *energy_raw = energy_now; put_online_cpus(); return 0; } put_online_cpus(); return -EIO; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan69100.00%1100.00%
Total69100.00%1100.00%


static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy) { struct rapl_domain *rd = power_zone_to_rapl_domain(pcd_dev); *energy = rapl_unit_xlate(rd, ENERGY_UNIT, ENERGY_STATUS_MASK, 0); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan42100.00%2100.00%
Total42100.00%2100.00%


static int release_zone(struct powercap_zone *power_zone) { struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone); struct rapl_package *rp = rd->rp; /* package zone is the last zone of a package, we can free * memory here since all children has been unregistered. */ if (rd->id == RAPL_DOMAIN_PACKAGE) { kfree(rd); rp->domains = NULL; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan55100.00%2100.00%
Total55100.00%2100.00%


static int find_nr_power_limit(struct rapl_domain *rd) { int i, nr_pl = 0; for (i = 0; i < NR_POWER_LIMITS; i++) { if (rd->rpl[i].name) nr_pl++; } return nr_pl; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan50100.00%2100.00%
Total50100.00%2100.00%


static int set_domain_enable(struct powercap_zone *power_zone, bool mode) { struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone); if (rd->state & DOMAIN_STATE_BIOS_LOCKED) return -EACCES; get_online_cpus(); rapl_write_data_raw(rd, PL1_ENABLE, mode); if (rapl_defaults->set_floor_freq) rapl_defaults->set_floor_freq(rd, mode); put_online_cpus(); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan6391.30%266.67%
Ajay Thomas68.70%133.33%
Total69100.00%3100.00%


static int get_domain_enable(struct powercap_zone *power_zone, bool *mode) { struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone); u64 val; if (rd->state & DOMAIN_STATE_BIOS_LOCKED) { *mode = false; return 0; } get_online_cpus(); if (rapl_read_data_raw(rd, PL1_ENABLE, true, &val)) { put_online_cpus(); return -EIO; } *mode = val; put_online_cpus(); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan83100.00%1100.00%
Total83100.00%1100.00%

/* per RAPL domain ops, in the order of rapl_domain_type */ static const struct powercap_zone_ops zone_ops[] = { /* RAPL_DOMAIN_PACKAGE */ { .get_energy_uj = get_energy_counter, .get_max_energy_range_uj = get_max_energy_counter, .release = release_zone, .set_enable = set_domain_enable, .get_enable = get_domain_enable, }, /* RAPL_DOMAIN_PP0 */ { .get_energy_uj = get_energy_counter, .get_max_energy_range_uj = get_max_energy_counter, .release = release_zone, .set_enable = set_domain_enable, .get_enable = get_domain_enable, }, /* RAPL_DOMAIN_PP1 */ { .get_energy_uj = get_energy_counter, .get_max_energy_range_uj = get_max_energy_counter, .release = release_zone, .set_enable = set_domain_enable, .get_enable = get_domain_enable, }, /* RAPL_DOMAIN_DRAM */ { .get_energy_uj = get_energy_counter, .get_max_energy_range_uj = get_max_energy_counter, .release = release_zone, .set_enable = set_domain_enable, .get_enable = get_domain_enable, }, /* RAPL_DOMAIN_PLATFORM */ { .get_energy_uj = get_energy_counter, .get_max_energy_range_uj = get_max_energy_counter, .release = release_zone, .set_enable = set_domain_enable, .get_enable = get_domain_enable, }, }; /* * Constraint index used by powercap can be different than power limit (PL) * index in that some PLs maybe missing due to non-existant MSRs. So we * need to convert here by finding the valid PLs only (name populated). */
static int contraint_to_pl(struct rapl_domain *rd, int cid) { int i, j; for (i = 0, j = 0; i < NR_POWER_LIMITS; i++) { if ((rd->rpl[i].name) && j++ == cid) { pr_debug("%s: index %d\n", __func__, i); return i; } } pr_err("Cannot find matching power limit for constraint %d\n", cid); return -EINVAL; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan81100.00%2100.00%
Total81100.00%2100.00%


static int set_power_limit(struct powercap_zone *power_zone, int cid, u64 power_limit) { struct rapl_domain *rd; struct rapl_package *rp; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); if (id < 0) { ret = id; goto set_exit; } rp = rd->rp; if (rd->state & DOMAIN_STATE_BIOS_LOCKED) { dev_warn(&power_zone->dev, "%s locked by BIOS, monitoring only\n", rd->name); ret = -EACCES; goto set_exit; } switch (rd->rpl[id].prim_id) { case PL1_ENABLE: rapl_write_data_raw(rd, POWER_LIMIT1, power_limit); break; case PL2_ENABLE: rapl_write_data_raw(rd, POWER_LIMIT2, power_limit); break; default: ret = -EINVAL; } if (!ret) package_power_limit_irq_save(rp); set_exit: put_online_cpus(); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan170100.00%4100.00%
Total170100.00%4100.00%


static int get_current_power_limit(struct powercap_zone *power_zone, int cid, u64 *data) { struct rapl_domain *rd; u64 val; int prim; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); if (id < 0) { ret = id; goto get_exit; } switch (rd->rpl[id].prim_id) { case PL1_ENABLE: prim = POWER_LIMIT1; break; case PL2_ENABLE: prim = POWER_LIMIT2; break; default: put_online_cpus(); return -EINVAL; } if (rapl_read_data_raw(rd, prim, true, &val)) ret = -EIO; else *data = val; get_exit: put_online_cpus(); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan141100.00%3100.00%
Total141100.00%3100.00%


static int set_time_window(struct powercap_zone *power_zone, int cid, u64 window) { struct rapl_domain *rd; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); if (id < 0) { ret = id; goto set_time_exit; } switch (rd->rpl[id].prim_id) { case PL1_ENABLE: rapl_write_data_raw(rd, TIME_WINDOW1, window); break; case PL2_ENABLE: rapl_write_data_raw(rd, TIME_WINDOW2, window); break; default: ret = -EINVAL; } set_time_exit: put_online_cpus(); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan117100.00%3100.00%
Total117100.00%3100.00%


static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data) { struct rapl_domain *rd; u64 val; int ret = 0; int id; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); if (id < 0) { ret = id; goto get_time_exit; } switch (rd->rpl[id].prim_id) { case PL1_ENABLE: ret = rapl_read_data_raw(rd, TIME_WINDOW1, true, &val); break; case PL2_ENABLE: ret = rapl_read_data_raw(rd, TIME_WINDOW2, true, &val); break; default: put_online_cpus(); return -EINVAL; } if (!ret) *data = val; get_time_exit: put_online_cpus(); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan143100.00%3100.00%
Total143100.00%3100.00%


static const char *get_constraint_name(struct powercap_zone *power_zone, int cid) { struct rapl_domain *rd; int id; rd = power_zone_to_rapl_domain(power_zone); id = contraint_to_pl(rd, cid); if (id >= 0) return rd->rpl[id].name; return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan59100.00%2100.00%
Total59100.00%2100.00%


static int get_max_power(struct powercap_zone *power_zone, int id, u64 *data) { struct rapl_domain *rd; u64 val; int prim; int ret = 0; get_online_cpus(); rd = power_zone_to_rapl_domain(power_zone); switch (rd->rpl[id].prim_id) { case PL1_ENABLE: prim = THERMAL_SPEC_POWER; break; case PL2_ENABLE: prim = MAX_POWER; break; default: put_online_cpus(); return -EINVAL; } if (rapl_read_data_raw(rd, prim, true, &val)) ret = -EIO; else *data = val; put_online_cpus(); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan112100.00%1100.00%
Total112100.00%1100.00%

static const struct powercap_zone_constraint_ops constraint_ops = { .set_power_limit_uw = set_power_limit, .get_power_limit_uw = get_current_power_limit, .set_time_window_us = set_time_window, .get_time_window_us = get_time_window, .get_max_power_uw = get_max_power, .get_name = get_constraint_name, }; /* called after domain detection and package level data are set */
static void rapl_init_domains(struct rapl_package *rp) { int i; struct rapl_domain *rd = rp->domains; for (i = 0; i < RAPL_DOMAIN_MAX; i++) { unsigned int mask = rp->domain_map & (1 << i); switch (mask) { case BIT(RAPL_DOMAIN_PACKAGE): rd->name = rapl_domain_names[RAPL_DOMAIN_PACKAGE]; rd->id = RAPL_DOMAIN_PACKAGE; rd->msrs[0] = MSR_PKG_POWER_LIMIT; rd->msrs[1] = MSR_PKG_ENERGY_STATUS; rd->msrs[2] = MSR_PKG_PERF_STATUS; rd->msrs[3] = 0; rd->msrs[4] = MSR_PKG_POWER_INFO; rd->rpl[0].prim_id = PL1_ENABLE; rd->rpl[0].name = pl1_name; rd->rpl[1].prim_id = PL2_ENABLE; rd->rpl[1].name = pl2_name; break; case BIT(RAPL_DOMAIN_PP0): rd->name = rapl_domain_names[RAPL_DOMAIN_PP0]; rd->id = RAPL_DOMAIN_PP0; rd->msrs[0] = MSR_PP0_POWER_LIMIT; rd->msrs[1] = MSR_PP0_ENERGY_STATUS; rd->msrs[2] = 0; rd->msrs[3] = MSR_PP0_POLICY; rd->msrs[4] = 0; rd->rpl[0].prim_id = PL1_ENABLE; rd->rpl[0].name = pl1_name; break; case BIT(RAPL_DOMAIN_PP1): rd->name = rapl_domain_names[RAPL_DOMAIN_PP1]; rd->id = RAPL_DOMAIN_PP1; rd->msrs[0] = MSR_PP1_POWER_LIMIT; rd->msrs[1] = MSR_PP1_ENERGY_STATUS; rd->msrs[2] = 0; rd->msrs[3] = MSR_PP1_POLICY; rd->msrs[4] = 0; rd->rpl[0].prim_id = PL1_ENABLE; rd->rpl[0].name = pl1_name; break; case BIT(RAPL_DOMAIN_DRAM): rd->name = rapl_domain_names[RAPL_DOMAIN_DRAM]; rd->id = RAPL_DOMAIN_DRAM; rd->msrs[0] = MSR_DRAM_POWER_LIMIT; rd->msrs[1] = MSR_DRAM_ENERGY_STATUS; rd->msrs[2] = MSR_DRAM_PERF_STATUS; rd->msrs[3] = 0; rd->msrs[4] = MSR_DRAM_POWER_INFO; rd->rpl[0].prim_id = PL1_ENABLE; rd->rpl[0].name = pl1_name; rd->domain_energy_unit = rapl_defaults->dram_domain_energy_unit; if (rd->domain_energy_unit) pr_info("DRAM domain energy unit %dpj\n", rd->domain_energy_unit); break; } if (mask) { rd->rp = rp; rd++; } } }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan474100.00%3100.00%
Total474100.00%3100.00%


static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type, u64 value, int to_raw) { u64 units = 1; struct rapl_package *rp = rd->rp; u64 scale = 1; switch (type) { case POWER_UNIT: units = rp->power_unit; break; case ENERGY_UNIT: scale = ENERGY_UNIT_SCALE; /* per domain unit takes precedence */ if (rd->domain_energy_unit) units = rd->domain_energy_unit; else units = rp->energy_unit; break; case TIME_UNIT: return rapl_defaults->compute_time_window(rp, value, to_raw); case ARBITRARY_UNIT: default: return value; }; if (to_raw) return div64_u64(value, units) * scale; value *= units; return div64_u64(value, scale); }

Contributors

PersonTokensPropCommitsCommitProp
Jacob jun Pan133100.00%4100.00%
Total133100.00%4100.00%

/* in the order of enum rapl_primitives */ static struct rapl_primitive_info rpi[] = { /* name, mask, shift, msr index, unit divisor */ PRIMITIVE_INFO_INIT(ENERGY_COUNTER, ENERGY_STATUS_MASK, 0, RAPL_DOMAIN_MSR_STATUS, ENERGY_UNIT, 0), PRIMITIVE_INFO_INIT(POWER_LIMIT1, POWER_LIMIT1_MASK, 0, RAPL_DOMAIN_MSR_LIMIT, POWER_UNIT, 0), PRIMITIVE_INFO_INIT(POWER_LIMIT2, POWER_LIMIT2_MASK, 32, RAPL_DOMAIN_MSR_LIMIT, POWER_UNIT, 0), PRIMITIVE_INFO_INIT(FW_LOCK, POWER_PP_LOCK, 31, RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0), PRIMITIVE_INFO_INIT(PL1_ENABLE, POWER_LIMIT1_ENABLE, 15, RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0), PRIMITIVE_INFO_INIT(PL1_CLAMP, POWER_LIMIT1_CLAMP, 16, RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0), PRIMITIVE_INFO_INIT(PL2_ENABLE, POWER_LIMIT2_ENABLE, 47, RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0), PRIMITIVE_INFO_INIT(PL2_CLAMP, POWER_LIMIT2_CLAMP, 48, RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0), PRIMITIVE_INFO_INIT(TIME_WINDOW1, TIME_WINDOW1_MASK, 17