xref: /qemu/tests/functional/acpi-bits/bits-tests/testcpuid.py2 (revision 05caa0624256da44974cd68e8f55dbbde3dfede7)
187853babSAni Sinha# Copyright (c) 2012, Intel Corporation
287853babSAni Sinha# All rights reserved.
387853babSAni Sinha#
4*5a373924SAni Sinha# SPDX-License-Identifier: BSD-3-Clause
5*5a373924SAni Sinha#
687853babSAni Sinha# Redistribution and use in source and binary forms, with or without
787853babSAni Sinha# modification, are permitted provided that the following conditions are met:
887853babSAni Sinha#
987853babSAni Sinha#     * Redistributions of source code must retain the above copyright notice,
1087853babSAni Sinha#       this list of conditions and the following disclaimer.
1187853babSAni Sinha#     * Redistributions in binary form must reproduce the above copyright notice,
1287853babSAni Sinha#       this list of conditions and the following disclaimer in the documentation
1387853babSAni Sinha#       and/or other materials provided with the distribution.
1487853babSAni Sinha#     * Neither the name of Intel Corporation nor the names of its contributors
1587853babSAni Sinha#       may be used to endorse or promote products derived from this software
1687853babSAni Sinha#       without specific prior written permission.
1787853babSAni Sinha#
1887853babSAni Sinha# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1987853babSAni Sinha# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2087853babSAni Sinha# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2187853babSAni Sinha# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
2287853babSAni Sinha# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2387853babSAni Sinha# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2487853babSAni Sinha# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2587853babSAni Sinha# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2687853babSAni Sinha# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2787853babSAni Sinha# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2887853babSAni Sinha
29*5a373924SAni Sinha# This script runs only from the biosbits VM.
30*5a373924SAni Sinha
3187853babSAni Sinha"""Tests and helpers for CPUID."""
3287853babSAni Sinha
3387853babSAni Sinhaimport bits
3487853babSAni Sinhaimport testsuite
3587853babSAni Sinhaimport testutil
3687853babSAni Sinha
3787853babSAni Sinhadef cpuid_helper(function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0):
3887853babSAni Sinha    if index is None:
3987853babSAni Sinha        index = 0
4087853babSAni Sinha        indexdesc = ""
4187853babSAni Sinha    else:
4287853babSAni Sinha        indexdesc = " index {0:#x}".format(index)
4387853babSAni Sinha
4487853babSAni Sinha    def find_mask(m):
4587853babSAni Sinha        if m == ~0:
4687853babSAni Sinha            return mask
4787853babSAni Sinha        return m
4887853babSAni Sinha    masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask])
4987853babSAni Sinha
5087853babSAni Sinha    uniques = {}
5187853babSAni Sinha    for cpu in bits.cpus():
5287853babSAni Sinha        regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)])
5387853babSAni Sinha        uniques.setdefault(regs, []).append(cpu)
5487853babSAni Sinha
5587853babSAni Sinha    desc = ["CPUID function {:#x}{}".format(function, indexdesc)]
5687853babSAni Sinha
5787853babSAni Sinha    if shift != 0:
5887853babSAni Sinha        desc.append("Register values have been shifted by {}".format(shift))
5987853babSAni Sinha    if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0:
6087853babSAni Sinha        desc.append("Register values have been masked:")
6187853babSAni Sinha        shifted_masks = bits.cpuid_result(*[m << shift for m in masks])
6287853babSAni Sinha        desc.append("Masks:           eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict()))
6387853babSAni Sinha
6487853babSAni Sinha    if len(uniques) > 1:
6587853babSAni Sinha        regvalues = zip(*uniques.iterkeys())
6687853babSAni Sinha        common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues))
6787853babSAni Sinha        common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)])
6887853babSAni Sinha        desc.append('Register values are not unique across all logical processors')
6987853babSAni Sinha        desc.append("Common bits:     eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict()))
7087853babSAni Sinha        desc.append("Mask of common bits: {eax:#010x}     {ebx:#010x}     {ecx:#010x}     {edx:#010x}".format(**common_masks._asdict()))
7187853babSAni Sinha
7287853babSAni Sinha    for regs in sorted(uniques.iterkeys()):
7387853babSAni Sinha        cpus = uniques[regs]
7487853babSAni Sinha        desc.append("Register value:  eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict()))
7587853babSAni Sinha        desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus)))
7687853babSAni Sinha
7787853babSAni Sinha    return uniques, desc
7887853babSAni Sinha
7987853babSAni Sinhadef test_cpuid_consistency(text, function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0):
8087853babSAni Sinha    uniques, desc = cpuid_helper(function, index, shift, mask, eax_mask, ebx_mask, ecx_mask, edx_mask)
8187853babSAni Sinha    desc[0] += " Consistency Check"
8287853babSAni Sinha    if text:
8387853babSAni Sinha        desc.insert(0, text)
8487853babSAni Sinha    status = testsuite.test(desc[0], len(uniques) == 1)
8587853babSAni Sinha    for line in desc[1:]:
8687853babSAni Sinha        testsuite.print_detail(line)
8787853babSAni Sinha    return status
88