Beispiel #1
0
int get_pkg_rapl_limit(const unsigned socket, struct rapl_limit *limit1, struct rapl_limit *limit2)
{
    static uint64_t *rapl_flags = NULL;
    sockets_assert(&socket, __LINE__, __FILE__);

    if (rapl_flags == NULL)
    {
        if (rapl_storage(NULL, &rapl_flags))
        {
            return -1;
        }
    }

    /* Make sure the pkg power limit register exists. */
    if (*rapl_flags & PKG_POWER_LIMIT)
    {
        if (limit1 != NULL)
        {
            read_msr_by_coord(socket, 0, 0, MSR_PKG_POWER_LIMIT, &(limit1->bits));
        }
        if (limit2 != NULL)
        {
            read_msr_by_coord(socket, 0, 0, MSR_PKG_POWER_LIMIT, &(limit2->bits));
        }
        calc_pkg_rapl_limit(socket, limit1, limit2);
    }
    else
    {
        libmsr_error_handler("get_pkg_rapl_limit(): PKG domain RAPL power limit not supported on this architecture", LIBMSR_ERROR_PLATFORM_NOT_SUPPORTED, getenv("HOSTNAME"), __FILE__, __LINE__);
        return -1;
    }
    return 0;
}
Beispiel #2
0
int get_rapl_power_info(const unsigned socket, struct rapl_power_info *info)
{
    uint64_t val = 0;
    static uint64_t *rapl_flags = NULL;

    sockets_assert(&socket, __LINE__, __FILE__);

    if (rapl_flags == NULL)
    {
        if (rapl_storage(NULL, &rapl_flags))
        {
            libmsr_error_handler("get_rapl_power_info(): Cannot load rapl_flags", LIBMSR_ERROR_RAPL_INIT, getenv("HOSTNAME"), __FILE__, __LINE__);
            return -1;
        }
    }
#ifdef LIBMSR_DEBUG
    fprintf(stderr, "%s %s::%d DEBUG: (get_rapl_power_info)\n", getenv("HOSTNAME"), __FILE__, __LINE__);
#endif
    if (*rapl_flags & PKG_POWER_INFO)
    {
        read_msr_by_coord(socket, 0, 0, MSR_PKG_POWER_INFO, &(info->msr_pkg_power_info));
        val = MASK_VAL(info->msr_pkg_power_info, 54, 48);
        translate(socket, &val, &(info->pkg_max_window), BITS_TO_SECONDS_STD);

        val = MASK_VAL(info->msr_pkg_power_info, 46, 32);
        translate(socket, &val, &(info->pkg_max_power), BITS_TO_WATTS);

        val = MASK_VAL(info->msr_pkg_power_info, 30, 16);
        translate(socket, &val, &(info->pkg_min_power), BITS_TO_WATTS);

        val = MASK_VAL(info->msr_pkg_power_info, 14, 0);
        translate(socket, &val, &(info->pkg_therm_power), BITS_TO_WATTS);
    }
    if (*rapl_flags & DRAM_POWER_INFO)
    {
        read_msr_by_coord(socket, 0, 0, MSR_DRAM_POWER_INFO, &(info->msr_dram_power_info));

        val = MASK_VAL(info->msr_dram_power_info, 54, 48);
        translate(socket, &val, &(info->dram_max_window), BITS_TO_SECONDS_STD);

        val = MASK_VAL(info->msr_dram_power_info, 46, 32);
        translate(socket, &val, &(info->dram_max_power), BITS_TO_WATTS);

        val = MASK_VAL(info->msr_dram_power_info, 30, 16);
        translate(socket, &val, &(info->dram_min_power), BITS_TO_WATTS);

        val = MASK_VAL(info->msr_dram_power_info, 14, 0);
        translate(socket, &val, &(info->dram_therm_power), BITS_TO_WATTS);
    }
    return 0;
}
Beispiel #3
0
void set_misc_enable(int package, struct misc_enable *s)
{
	uint64_t msrVal;
	read_msr_by_coord(package, 0, 0, IA32_MISC_ENABLE, &msrVal);
	//msrVal = 64; //temp value
	assert(s->fast_string_enable == 0 || s->fast_string_enable == 1);
	assert(s->auto_TCC_enable == 0 || s->auto_TCC_enable == 1);
	assert(s->TM2_enable == 0 || s->TM2_enable == 1);
	assert(s->enhanced_Intel_SpeedStep_Tech_enable == 0 || s->enhanced_Intel_SpeedStep_Tech_enable == 1);
	assert(s->limit_CPUID_maxval == 0 || s->limit_CPUID_maxval == 1);
	assert(s->xTPR_message_disable == 0 || s->xTPR_message_disable == 1);
	assert(s->XD_bit_disable == 0 || s->XD_bit_disable == 1);
	assert(s->turbo_mode_disable == 0 || s->turbo_mode_disable == 1);

	msrVal = (msrVal & (~(1<< 0))) | (s->fast_string_enable << 0);
	msrVal = (msrVal & (~(1<< 3))) | (s->auto_TCC_enable << 3);
	msrVal = (msrVal & (~(1<< 13))) | (s->TM2_enable << 13);
	msrVal = (msrVal & (~(1<< 16))) | (s->enhanced_Intel_SpeedStep_Tech_enable << 16);
	msrVal = (msrVal & (~(1<< 22))) | (s->limit_CPUID_maxval << 22);
	msrVal = (msrVal & (~(1<< 23))) | (s->xTPR_message_disable << 23);
	msrVal = (msrVal & (~((uint64_t)1<< (uint64_t)34))) | ((uint64_t)s->XD_bit_disable << (uint64_t)34);
	msrVal = (msrVal & (~((uint64_t)1<< (uint64_t)38))) | ((uint64_t)s->turbo_mode_disable << (uint64_t)38);

	write_msr_by_coord(package, 0, 0, IA32_MISC_ENABLE, msrVal);
}
Beispiel #4
0
void get_clock_mod(int socket, int core, struct clock_mod *s)
{
	read_msr_by_coord(socket, core, 0, IA32_CLOCK_MODULATION, &(s->raw));
	//s->raw = 64; // temp value
	s->duty_cycle = MASK_VAL(s->raw, 3, 1);			// specific encoded values for target duty cycle

	s->duty_cycle_enable = MASK_VAL(s->raw, 4, 4);		// On-Demand Clock Modulation Enable
								// 1 = enabled, 0 disabled
}
Beispiel #5
0
int set_clock_mod(int socket, int core, struct clock_mod *s)
{
	uint64_t msrVal;
	read_msr_by_coord(socket, core, 0, IA32_CLOCK_MODULATION, &msrVal);
	//msrVal = 64; // temp value
    // replaced asserts with these two conditionals
    if (!(s->duty_cycle > 0 && s->duty_cycle < 8))
    {
        return -1;
    }
    if (!(s->duty_cycle_enable == 0 || s->duty_cycle_enable == 1))
    {
        return -1;
    }

	msrVal = (msrVal & (~(3<<1))) | (s->duty_cycle << 1);
	msrVal = (msrVal & (~(1<<4))) | (s->duty_cycle_enable << 4);

	write_msr_by_coord(socket, core, 0, IA32_CLOCK_MODULATION, msrVal);
    return 0;
}
Beispiel #6
0
int set_pkg_rapl_limit(const unsigned socket, struct rapl_limit *limit1, struct rapl_limit *limit2)
{
    uint64_t pkg_limit = 0;
    static uint64_t *rapl_flags = NULL;
    uint64_t currentval = 0;
    int ret = 0;
    sockets_assert(&socket, __LINE__, __FILE__);

    if (rapl_flags == NULL)
    {
        if (rapl_storage(NULL, &rapl_flags))
        {
            return -1;
        }
    }
#ifdef LIBMSR_DEBUG
    fprintf(stderr, "%s %s::%d DEBUG: (set_pkg_rapl_limit) flags are at %p\n", getenv("HOSTNAME"), __FILE__, __LINE__, rapl_flags);
#endif

    /* Make sure the pkg power limit register exists. */
    if (*rapl_flags & PKG_POWER_LIMIT)
    {
        /* If there is only one limit, grab the other existing one. */
        if (limit1 == NULL)
        {
#ifdef LIBMSR_DEBUG
            fprintf(stderr, "%s %s::%d DEBUG: only one rapl limit, retrieving any existing power limits\n", getenv("HOSTNAME"), __FILE__, __LINE__);
#endif
            ret = read_msr_by_coord(socket, 0, 0, MSR_PKG_POWER_LIMIT, &currentval);
            /* We want to keep the lower limit so mask off all other bits. */
            pkg_limit |= currentval & 0x00000000FFFFFFFF;
        }
        else if (limit2 == NULL)
        {
#ifdef LIBMSR_DEBUG
            fprintf(stderr, "%s %s::%d DEBUG: only one rapl limit, retrieving any existing power limits\n", getenv("HOSTNAME"), __FILE__, __LINE__);
#endif
            ret = read_msr_by_coord(socket, 0, 0, MSR_PKG_POWER_LIMIT, &currentval);
            /* We want to keep the upper limit so mask off all other bits. */
            pkg_limit |= currentval & 0xFFFFFFFF00000000;
        }
        if (calc_pkg_rapl_limit(socket, limit1, limit2))
        {
            return -1;
        }
        /* Enable the rapl limit (15 && 47) and turn on clamping (16 && 48). */
        if (limit1 != NULL)
        {
            pkg_limit |= limit1->bits | (1LL << 15) | (1LL << 16);
        }
        if (limit2 != NULL)
        {
            pkg_limit |= limit2->bits | (1LL << 47) | (1LL << 48);
        }
        if (limit1 != NULL || limit2 != NULL)
        {
            ret += write_msr_by_coord(socket, 0, 0, MSR_PKG_POWER_LIMIT, pkg_limit);
        }
    }
    else
    {
        libmsr_error_handler("set_pkg_rapl_limit(): PKG domain RAPL limit not supported on this architecture", LIBMSR_ERROR_PLATFORM_NOT_SUPPORTED, getenv("HOSTNAME"), __FILE__, __LINE__);
        return -1;
    }
#ifdef LIBMSR_DEBUG
    fprintf(stderr, "pkg set\n");
#endif
    return ret;
}
Beispiel #7
0
void get_rapl_power_unit(struct rapl_units *ru)
{
    static int init = 0;
    static uint64_t sockets = 0;
    static uint64_t **val = NULL;
    int i;

    sockets = num_sockets();
    if (!init)
    {
        init = 1;
        val = (uint64_t **) libmsr_calloc(sockets, sizeof(uint64_t *));
        allocate_batch(RAPL_UNIT, sockets);
        load_socket_batch(MSR_RAPL_POWER_UNIT, val, RAPL_UNIT);
    }
    read_batch(RAPL_UNIT);
    /* Initialize the units used for each socket. */
    for (i = 0; i < sockets; i++)
    {
        // See figure 14-16 for bit fields.
        //  1  1 1  1 1
        //  9  6 5  2 1  8 7  4 3  0
        //
        //  1010 0001 0000 0000 0011
        //
        //     A    1    0    0    3
        //ru[i].msr_rapl_power_unit = 0xA1003;

        ru[i].msr_rapl_power_unit = *val[i];
        /* Default is 1010b or 976 microseconds. */
        /* Storing (1/(2^TU))^-1 for maximum precision. */
        ru[i].seconds = (double)(1 << (MASK_VAL(ru[i].msr_rapl_power_unit, 19, 16)));
        /* Default is 10000b or 15.3 microjoules. */
        /* Storing (1/(2^ESU))^-1 for maximum precision. */
        ru[i].joules = (double)(1 << (MASK_VAL(ru[i].msr_rapl_power_unit, 12, 8)));
#ifdef LIBMSR_DEBUG
        fprintf(stderr, "DEBUG: joules unit is %f register has %lx\n", ru[i].joules, ru[i].msr_rapl_power_unit);
#endif
        /* Default is 0011b or 1/8 Watts. */
        ru[i].watts = ((1.0)/((double)(1 << (MASK_VAL(ru[i].msr_rapl_power_unit, 3, 0)))));
#ifdef LIBMSR_DEBUG
        fprintf(stdout, "Pkg %d MSR_RAPL_POWER_UNIT\n", i);
        fprintf(stdout, "Raw: %f sec, %f J, %f watts\n", ru[i].seconds, ru[i].joules, ru[i].watts);
        fprintf(stdout, "Adjusted: %f sec, %f J, %f watts\n", 1/ru[i].seconds, 1/ru[i].joules, ru[i].watts);
#endif
    }

    /* Check consistency between packages. */
    uint64_t *tmp = (uint64_t *) libmsr_calloc(sockets, sizeof(uint64_t));
    for (i = 0; i < sockets; i++)
    {
        read_msr_by_coord(i, 0, 0, MSR_RAPL_POWER_UNIT, tmp);
        double energy = (double)(1 << (MASK_VAL(ru[i].msr_rapl_power_unit, 12, 8)));
        double seconds = (double)(1 << (MASK_VAL(ru[i].msr_rapl_power_unit, 19, 16)));
        double power = ((1.0)/((double)(1 << (MASK_VAL(ru[i].msr_rapl_power_unit, 3, 0)))));
        if (energy != ru[i].joules || power != ru[i].watts || seconds != ru[i].seconds)
        {
            libmsr_error_handler("get_rapl_power_unit(): Inconsistent rapl power units across packages", LIBMSR_ERROR_RUNTIME, getenv("HOSTNAME"), __FILE__, __LINE__);
        }
    }
}
Beispiel #8
0
void get_misc_enable(int package, struct misc_enable *s)
{
	read_msr_by_coord(package, 0, 0, IA32_MISC_ENABLE, &(s->raw));
	//s->raw = 164;
        s->fast_string_enable = MASK_VAL(s->raw, 0, 0);				// When set, fast-strings feature (for REP MOVS and REP STORS) 
										// is enabled (default), (cleared = disabled)

        s->auto_TCC_enable = MASK_VAL(s->raw, 3, 3);				// 0 = disabled (default)
										// Note: clearing might be ignored in critical thermal
										// conditions. In this case, TM1, TM2, and adaptive 
										// thermal throttling will still be active. 
										// 
										// 1 = enables the thermal control circuit (TCC) portion
										// of the Intel Thermal Monitor feature. Allows the
										// processor to automatically reduce power consumption in 
										// response to TCC activation)
										
	s->performance_monitoring = MASK_VAL(s->raw, 7,7);			// 1 = performance monitoring enabled
       										// 0 = disabled

	s->branch_trace_storage_unavail = MASK_VAL(s->raw, 11, 11);		// 1 = Processor doesn't support branch trace storage (BTS)
										// 0 = BTS is supported

	s->precise_event_based_sampling_unavail = MASK_VAL(s->raw, 12, 12);	// 1 = PEBS is not supported
										// 0 = PEBS is supported

	s->TM2_enable = MASK_VAL(s->raw, 13, 13);				// 1 = TM2 enabled
										// 0 = TM2 disabled

	s->enhanced_Intel_SpeedStep_Tech_enable = MASK_VAL(s->raw, 16, 16);	// 1 = Enhanced Intel SpeedStep Technology enabled
										// 0 = disabled

	s->enable_monitor_fsm = MASK_VAL(s->raw, 18, 18);			// 0 = MONITOR feature flag is not set (CPUID.01H:ECX[bit 3]=0)
										// This indicates that MONITOR/MWAIT are not supported.
										// Software attempts to execute MONITOR/MWAIT will cause #UD
										// when this bit is 0.
										// 1 (default) = MONITOR/MWAIT are supported. (CPUID... = 1)
										//
										// If the SSE3 feature flag ECX[0] is not set
										// (CPUID.01H:ECX[bit 0] = 0), the OS must not attempt to 
										// alter this bit. BIOS must leave it in the default state.
										// Writing this bit when SSE3 feature flag is 0 may generate
										// a #GP exception

	s->limit_CPUID_maxval = MASK_VAL(s->raw, 22, 22);			// Before setting this bit, BIOS must execute the CPUID.0H
										// and examine the maximum value returned in EAX[7:0].
										// If the max is greater than 3, bit is supported.
										// Otherwise, this bit is not supported, and writing to this
										// bit when the max value is greater than 3 may generate
										// a #GP exception
										//
										// Setting this bit may cause unexpected behavior in software
										// that depends on the availability of CPUID leaves greater
										// than 3.
										//
										// 1 = CPUID.00H returns a max value in EAX[7:0] of 3.
										// BIOS should contain a setup question that allows users to
										// specify when the installed OS does not support CPUID 
										// functions greater than 3.
										
	s->xTPR_message_disable = MASK_VAL(s->raw, 23, 23);			// xTPR messages are optional messages that allow the 
										// processor to inform the chipset of its priority.
										// 1 = xTPR messages are disabled
										// 0 = enabled

	s->XD_bit_disable = MASK_VAL(s->raw, 34, 34);				// BIOS must not alter the contents of this bit location. If
										// XD is not supported, writing this bit to 1 when the XD Bit 
										// extended flag is set 0 may generate a #GP exception
										// 
										// 1 = Execute Disable Bit feature (XD bit) is disabled
										// and the XD bit extended feature flag will be clear
										// (CPUID.80000001H:EDX[20] = 0
										//
										// 0 (default) = the EX bit feature (if available) allows 
										// the OS to enable PAE paging and take advantage of data 
										// only pages
										
	s->turbo_mode_disable = MASK_VAL(s->raw, 38, 38);			// 1 (on processors that support Intel Turbo Boost Tech) =
										// turbo mode feature disabled and IDA_Enable feature flag 
										// will be clear (CPUID.06H: EAX[1]=0)
										//
										// 0 (on proccessors that support IDA) = CPUID.06H: EAX[1] 
										// reports the processor's support of turbo mode is enabled
										//
										// Note: the power on default value is used by BIOS to detect
										// hardware support of turbo mode. If power-on default is 1,
										// turbo mode is available in the processor. If 0, then turbo
										// mode is not available. 
}