Exemplo n.º 1
0
def thread(apicid):
    """Return the thread APIC ID, and the APIC IDs of the core and socket in which the thread resides.
    
    Raises RuntimeError if CPUID leaf 0xb not supported."""
    if bits.cpuid(apicid, 0).eax < 0xb:
        raise RuntimeError("Cannot compute topology; CPUID leaf 0xb not supported.")
    coreid = apicid >> bitfields.getbits(bits.cpuid(apicid, 0xb, 0).eax, 4, 0)
    socketid = apicid >> bitfields.getbits(bits.cpuid(apicid, 0xb, 1).eax, 4, 0)
    return socketid, coreid, apicid
Exemplo n.º 2
0
def test_hardware_pstates(ratio_to_control_value):
    IA32_PERF_CTL = 0x199
    with bits.mwait.use_hint(), bits.preserve_msr(IA32_PERF_CTL):
        MSR_PLATFORM_INFO = 0xce
        min_ratio = testmsr.MSR("maximum efficiency ratio",
                                bits.bsp_apicid(),
                                MSR_PLATFORM_INFO,
                                highbit=47,
                                lowbit=40)[0]
        max_ratio = testmsr.MSR("max non-turbo ratio",
                                bits.bsp_apicid(),
                                MSR_PLATFORM_INFO,
                                highbit=15,
                                lowbit=8)[0]

        # Get the Turbo Mode Availability flag
        turbo_mode_available = bits.cpuid(bits.bsp_apicid(), 0).eax >= 6 and (
            bits.cpuid(bits.bsp_apicid(), 6).eax & 0x2)
        last_ratio = max_ratio
        if turbo_mode_available:
            last_ratio += 1

        bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0 / 12) * 1000000

        for ratio in range(min_ratio, last_ratio + 1):
            control_value = ratio_to_control_value(ratio, min_ratio, max_ratio)
            for apicid in bits.cpus():
                bits.wrmsr(apicid, IA32_PERF_CTL, control_value)

            turbo = (ratio == max_ratio + 1)
            if turbo:
                # Needs to busywait, not sleep
                start = time.time()
                while (time.time() - start < 2):
                    pass

            expected = int(ratio * bclk / 1000000)

            for duration in (0.1, 1.0):
                aperf = bits.cpu_frequency(duration)[1]
                aperf = testutil.adjust_to_nearest(aperf, bclk / 2)
                aperf = int(aperf / 1000000)
                if turbo:
                    if aperf >= expected:
                        break
                else:
                    if aperf == expected:
                        break

            if turbo:
                testsuite.test(
                    "Turbo measured frequency {} >= expected {} MHz".format(
                        aperf, expected), aperf >= expected)
            else:
                testsuite.test(
                    "Ratio {} measured frequency {} MHz == expected {} MHz".
                    format(ratio, aperf, expected), aperf == expected)
Exemplo n.º 3
0
def thread(apicid):
    """Return the thread APIC ID, and the APIC IDs of the core and socket in which the thread resides.

    Raises RuntimeError if CPUID leaf 0xb not supported."""
    if bits.cpuid(apicid, 0).eax < 0xb:
        raise RuntimeError(
            "Cannot compute topology; CPUID leaf 0xb not supported.")
    coreid = apicid >> bitfields.getbits(bits.cpuid(apicid, 0xb, 0).eax, 4, 0)
    socketid = apicid >> bitfields.getbits(
        bits.cpuid(apicid, 0xb, 1).eax, 4, 0)
    return socketid, coreid, apicid
Exemplo n.º 4
0
def cmd_brandstring(args):
    uniques = {}
    for cpu in each_apicid(args.cpu):
        brand = ""
        if bits.cpuid(cpu, 0x80000000).eax >= 0x80000004:
            brand = "".join(struct.pack("<LLLL", *bits.cpuid(cpu, func_num)) for func_num in range(0x80000002, 0x80000005))
            brand = brand.rstrip('\0')
        uniques.setdefault(brand, []).append(cpu)
    for value in sorted(uniques.iterkeys()):
        cpus = uniques[value]
        print 'Brandstring: "{0}"'.format(value)
        print "On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))
Exemplo n.º 5
0
def test_hardware_pstates(ratio_to_control_value):
    old_mwait = {}
    try:
        MSR_PLATFORM_INFO = 0xce
        IA32_PERF_CTL = 0x199
        min_ratio = testmsr.MSR("maximum efficiency ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=47, lowbit=40)[0]
        max_ratio = testmsr.MSR("max non-turbo ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=15, lowbit=8)[0]

        # Get the Turbo Mode Availability flag
        turbo_mode_available = bits.cpuid(bits.bsp_apicid(),0).eax >= 6 and (bits.cpuid(bits.bsp_apicid(),6).eax & 0x2)
        last_ratio = max_ratio
        if turbo_mode_available:
            last_ratio += 1

        duration = last_ratio - min_ratio + 1
        if turbo_mode_available:
            duration += 2
        print "Test duration is ~{} seconds...".format(duration)

        # Force use of MWAIT C3
        hint = 0x20
        cpus = bits.cpus()
        for apicid in cpus:
            old_mwait[apicid] = bits.get_mwait(apicid)
            bits.set_mwait(apicid, True, hint)

        bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000

        for ratio in range(min_ratio, last_ratio + 1):
            control_value = ratio_to_control_value(ratio, min_ratio, max_ratio)
            for apicid in cpus:
                bits.wrmsr(apicid, IA32_PERF_CTL, control_value)

            if ratio == max_ratio + 1:
                # Needs to busywait, not sleep
                start = time.time()
                while (time.time() - start < 2):
                    pass

            aperf = bits.cpu_frequency()[1]
            aperf = testutil.adjust_to_nearest(aperf, bclk/2)
            aperf = int(aperf / 1000000)

            expected = int(ratio * bclk / 1000000)

            if ratio == max_ratio + 1:
                testsuite.test("Turbo measured frequency {} >= expected {} MHz".format(aperf, expected), aperf >= expected)
            else:
                testsuite.test("Ratio {} measured frequency {} MHz == expected {} MHz".format(ratio, aperf, expected), aperf == expected)
    finally:
        for apicid, old_mwait_values in old_mwait.iteritems():
            bits.set_mwait(apicid, *old_mwait_values)
Exemplo n.º 6
0
def power_opt_low_power_profile():
    # If CPUID.06H:ECX.SETBH[bit 3] is set, then the processor supports
    # performance-energy bias preference and IA32_ENERGY_PERF_BIAS (1B0H) MSR
    setbh = (bits.cpuid(bits.bsp_apicid(),6).ecx >> 3) & 1
    if not setbh:
        return
    testmsr.test_msr_consistency("Energy Performance Bias", 0x1b0, mask=0xf)
    testmsr.test_msr("Energy Performance Bias 12-15", 0x1b0, expected_value=3, shift=2, mask=3)
Exemplo n.º 7
0
def test_hardware_pstates(ratio_to_control_value):
    IA32_PERF_CTL = 0x199
    with bits.mwait.use_hint(), bits.preserve_msr(IA32_PERF_CTL):
        MSR_PLATFORM_INFO = 0xce
        min_ratio = testmsr.MSR("maximum efficiency ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=47, lowbit=40)[0]
        max_ratio = testmsr.MSR("max non-turbo ratio", bits.bsp_apicid(), MSR_PLATFORM_INFO, highbit=15, lowbit=8)[0]

        # Get the Turbo Mode Availability flag
        turbo_mode_available = bits.cpuid(bits.bsp_apicid(),0).eax >= 6 and (bits.cpuid(bits.bsp_apicid(),6).eax & 0x2)
        last_ratio = max_ratio
        if turbo_mode_available:
            last_ratio += 1

        bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000

        for ratio in range(min_ratio, last_ratio + 1):
            control_value = ratio_to_control_value(ratio, min_ratio, max_ratio)
            for apicid in bits.cpus():
                bits.wrmsr(apicid, IA32_PERF_CTL, control_value)

            turbo = (ratio == max_ratio + 1)
            if turbo:
                # Needs to busywait, not sleep
                start = time.time()
                while (time.time() - start < 2):
                    pass

            expected = int(ratio * bclk / 1000000)

            for duration in (0.1, 1.0):
                aperf = bits.cpu_frequency(duration)[1]
                aperf = testutil.adjust_to_nearest(aperf, bclk/2)
                aperf = int(aperf / 1000000)
                if turbo:
                    if aperf >= expected:
                        break
                else:
                    if aperf == expected:
                        break

            if turbo:
                testsuite.test("Turbo measured frequency {} >= expected {} MHz".format(aperf, expected), aperf >= expected)
            else:
                testsuite.test("Ratio {} measured frequency {} MHz == expected {} MHz".format(ratio, aperf, expected), aperf == expected)
Exemplo n.º 8
0
def max_phys_addr():
    """Return the max physical address width, in bits.

    Computed on first call, and cached for subsequent return."""
    global max_phys_addr
    max_extended_leaf = bits.cpuid(bits.bsp_apicid(), 0x80000000).eax
    if max_extended_leaf >= 0x80000008:
        # cpuid.(eax=0x80000008).eax[7:0] = max physical-address width supported by the processor
        local_max_phys_addr = bitfields.getbits(bits.cpuid(bits.bsp_apicid(), 0x80000008).eax, 7, 0)
    elif bitfields.getbits(bits.cpuid(bits.bsp_apicid(), 1).edx, 6): # PAE supported
        local_max_phys_addr = 36
    else:
        local_max_phys_addr = 32

    old_func = max_phys_addr
    def max_phys_addr():
        return local_max_phys_addr
    functools.update_wrapper(max_phys_addr, old_func)

    return local_max_phys_addr
Exemplo n.º 9
0
def power_opt_low_power_profile():
    # If CPUID.06H:ECX.SETBH[bit 3] is set, then the processor supports
    # performance-energy bias preference and IA32_ENERGY_PERF_BIAS (1B0H) MSR
    setbh = (bits.cpuid(bits.bsp_apicid(), 6).ecx >> 3) & 1
    if not setbh:
        return
    testmsr.test_msr_consistency("Energy Performance Bias", 0x1b0, mask=0xf)
    testmsr.test_msr("Energy Performance Bias 12-15",
                     0x1b0,
                     expected_value=3,
                     shift=2,
                     mask=3)
Exemplo n.º 10
0
def cpuid_helper(function, index=None, cpu=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0):
    if cpu is None:
        cpus = bits.cpus()
    else:
        cpus = [cpu]

    if index is None:
        index = 0
        indexdesc = ""
    else:
        indexdesc = " index {0:#x}".format(index)

    def find_mask(m):
        if m == ~0:
            return mask
        return m
    masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask])

    uniques = {}
    for cpu in cpus:
        regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)])
        uniques.setdefault(regs, []).append(cpu)

    desc = ["CPUID function {:#x}{}".format(function, indexdesc)]

    if shift != 0:
        desc.append("Register values have been shifted by {}".format(shift))
    if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0:
        desc.append("Register values have been masked:")
        shifted_masks = bits.cpuid_result(*[m << shift for m in masks])
        desc.append("Masks:           eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict()))

    if len(uniques) > 1:
        regvalues = zip(*uniques.iterkeys())
        common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues))
        common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)])
        desc.append('Register values are not unique across all logical processors')
        desc.append("Common bits:     eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict()))
        desc.append("Mask of common bits: {eax:#010x}     {ebx:#010x}     {ecx:#010x}     {edx:#010x}".format(**common_masks._asdict()))

    for regs in sorted(uniques.iterkeys()):
        cpus = uniques[regs]
        desc.append("Register value:  eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict()))
        desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus)))

    return uniques, desc
Exemplo n.º 11
0
def cpuid_helper(function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0):
    if index is None:
        index = 0
        indexdesc = ""
    else:
        indexdesc = " index {0:#x}".format(index)

    def find_mask(m):
        if m == ~0:
            return mask
        return m
    masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask])

    uniques = {}
    for cpu in bits.cpus():
        regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)])
        uniques.setdefault(regs, []).append(cpu)

    desc = ["CPUID function {:#x}{}".format(function, indexdesc)]

    if shift != 0:
        desc.append("Register values have been shifted by {}".format(shift))
    if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0:
        desc.append("Register values have been masked:")
        shifted_masks = bits.cpuid_result(*[m << shift for m in masks])
        desc.append("Masks:           eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict()))

    if len(uniques) > 1:
        regvalues = zip(*uniques.iterkeys())
        common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues))
        common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)])
        desc.append('Register values are not unique across all logical processors')
        desc.append("Common bits:     eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict()))
        desc.append("Mask of common bits: {eax:#010x}     {ebx:#010x}     {ecx:#010x}     {edx:#010x}".format(**common_masks._asdict()))

    for regs in sorted(uniques.iterkeys()):
        cpus = uniques[regs]
        desc.append("Register value:  eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict()))
        desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus)))

    return uniques, desc
Exemplo n.º 12
0
def is_cpu():
    return bits.cpuid(bits.bsp_apicid(), 1).eax & ~0xf == 0x106c0
Exemplo n.º 13
0
def log_sysinfo():
    with redirect.logonly():
        signature = bits.cpuid(bits.bsp_apicid(), 1).eax
        print "Processor signature {:#x}, detected CPU as {}".format(
            signature, cpulib.name)
Exemplo n.º 14
0
def generate_mwait_menu():
    global created_mwait_menu
    global supported_mwaits_msg
    if created_mwait_menu:
        return

    cfg = ""
    cfg += 'menuentry "Test round-trip latency via MWAIT" {\n'
    cfg += "    py 'import mwaitmenu; mwaitmenu.test_latency()'\n"
    cfg += '}\n\n'

    cfg += 'menuentry "MWAIT disable" {\n'
    cfg += "    py 'import mwaitmenu; mwaitmenu.mwait_callback(False)'\n"
    cfg += '}\n\n'
    cfg += 'menuentry "MWAIT enable C0" {\n'
    cfg += """    py 'import mwaitmenu; mwaitmenu.mwait_callback(True, "C0", 0xf)'\n"""
    cfg += '}\n\n'

    edx = 0
    if bits.cpuid(bits.bsp_apicid(), 0).eax >= 5:
        edx = bits.cpuid(bits.bsp_apicid(), 5).edx

    mwait_table = (
        ("C1", 0, 4, 1),
        ("C1E", 1, 4, 2),
        ("*C2", 0x10, 8, 1),
        ("*C3", 0x20, 12, 1),
        ("*C4", 0x30, 16, 1),
        ("*C5", 0x40, 20, 1),
        ("*C6", 0x50, 24, 1),
    )

    supported_mwaits_msg = ""
    for name, hint, shift, n in mwait_table:
        if ((edx >> shift) & 0xf) >= n:
            cfg += 'menuentry "MWAIT enable {}" {{\n'.format(name)
            cfg += """    py 'import mwaitmenu; mwaitmenu.mwait_callback(True, "{}", {})'\n""".format(
                name, hint)
            cfg += '}\n\n'
            supported_mwaits_msg += "MWAIT {} is supported\n".format(name)
        else:
            supported_mwaits_msg += "MWAIT {} is not supported\n".format(name)

    supported_mwaits_msg += "For more information, see the Intel Software Developers Manual, CPUID leaf 5\n"

    cfg += 'menuentry "* MWAIT C-state naming is per CPUID leaf 5 & not processor-specific!" {'
    cfg += "    py 'import mwaitmenu; mwaitmenu.show_supported_mwaits()'\n"
    cfg += '}\n\n'

    cfg += 'menuentry "Current state of Interrupt Break Event" {\n'
    cfg += "    py 'import mwaitmenu; mwaitmenu.show_interrupt_break_event()'\n"
    cfg += '}\n\n'
    cfg += 'menuentry "Toggle Interrupt Break Event" {\n'
    cfg += "    py 'import mwaitmenu; mwaitmenu.toggle_interrupt_break_event()'\n"
    cfg += '}\n\n'

    try:
        cfg += cpulib.generate_mwait_menu()
    except AttributeError as e:
        pass

    bits.pyfs.add_static("mwaitmenu.cfg", cfg)
    created_mwait_menu = True
Exemplo n.º 15
0
def is_cpu():
    return bits.cpuid(bits.bsp_apicid(),1).eax & ~0xf == 0x106c0
Exemplo n.º 16
0
def log_sysinfo():
    with redirect.logonly():
        signature = bits.cpuid(bits.bsp_apicid(),1).eax
        print "Processor signature {:#x}, detected CPU as {}".format(signature, cpulib.name)
Exemplo n.º 17
0
def is_cpu():
    return bits.cpuid(bits.bsp_apicid(), 1).eax & ~0xF == 0x206D0
Exemplo n.º 18
0
 def read(cls, apicid, subleaf=0):
     r = cls(bits.cpuid(apicid, cls.leaf, subleaf))
     r.apicid = apicid
     r.subleaf = subleaf
     return r
Exemplo n.º 19
0
 def read(cls, apicid, subleaf=0):
     r = cls(bits.cpuid(apicid, cls.leaf, subleaf))
     r.apicid = apicid
     r.subleaf = subleaf
     return r
Exemplo n.º 20
0
def generate_mwait_menu():
    global created_mwait_menu
    global supported_mwaits_msg
    if created_mwait_menu:
        return

    cfg = ""
    cfg += 'menuentry "Test round-trip latency via MWAIT" {\n'
    cfg += "    py 'import mwaitmenu; mwaitmenu.test_latency()'\n"
    cfg += '}\n\n'

    cfg += 'menuentry "MWAIT disable" {\n'
    cfg += "    py 'import mwaitmenu; mwaitmenu.mwait_callback(False)'\n"
    cfg += '}\n\n'
    cfg += 'menuentry "MWAIT enable C0" {\n'
    cfg += """    py 'import mwaitmenu; mwaitmenu.mwait_callback(True, "C0", 0xf)'\n"""
    cfg += '}\n\n'

    edx = 0
    if bits.cpuid(bits.bsp_apicid(), 0).eax >= 5:
        edx = bits.cpuid(bits.bsp_apicid(), 5).edx

    mwait_table = (
        ("C1", 0, 4, 1),
        ("C1E", 1, 4, 2),
        ("*C2", 0x10, 8, 1),
        ("*C3", 0x20, 12, 1),
        ("*C4", 0x30, 16, 1),
        ("*C5", 0x40, 20, 1),
        ("*C6", 0x50, 24, 1),
    )

    supported_mwaits_msg = ""
    for name, hint, shift, n in mwait_table:
        if ((edx >> shift) & 0xf) >= n:
            cfg += 'menuentry "MWAIT enable {}" {{\n'.format(name)
            cfg += """    py 'import mwaitmenu; mwaitmenu.mwait_callback(True, "{}", {})'\n""".format(name, hint)
            cfg += '}\n\n'
            supported_mwaits_msg += "MWAIT {} is supported\n".format(name)
        else:
            supported_mwaits_msg += "MWAIT {} is not supported\n".format(name)

    supported_mwaits_msg += "For more information, see the Intel Software Developers Manual, CPUID leaf 5\n"

    cfg += 'menuentry "* MWAIT C-state naming is per CPUID leaf 5 & not processor-specific!" {'
    cfg += "    py 'import mwaitmenu; mwaitmenu.show_supported_mwaits()'\n"
    cfg += '}\n\n'

    cfg += 'menuentry "Current state of Interrupt Break Event" {\n'
    cfg += "    py 'import mwaitmenu; mwaitmenu.show_interrupt_break_event()'\n"
    cfg += '}\n\n'
    cfg += 'menuentry "Toggle Interrupt Break Event" {\n'
    cfg += "    py 'import mwaitmenu; mwaitmenu.toggle_interrupt_break_event()'\n"
    cfg += '}\n\n'

    try:
        cfg += cpulib.generate_mwait_menu()
    except AttributeError as e:
        pass

    bits.pyfs.add_static("mwaitmenu.cfg", cfg)
    created_mwait_menu = True