Merge tag 'qemu-macppc-20230206' of https://github.com/mcayland/qemu into staging
[qemu.git] / tests / avocado / acpi-bits / bits-tests / testcpuid.py2
blob7adefbe3558c063108c953754b638673e742356a
1 # Copyright (c) 2012, Intel Corporation
2 # All rights reserved.
4 # SPDX-License-Identifier: BSD-3-Clause
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
9 #     * Redistributions of source code must retain the above copyright notice,
10 #       this list of conditions and the following disclaimer.
11 #     * Redistributions in binary form must reproduce the above copyright notice,
12 #       this list of conditions and the following disclaimer in the documentation
13 #       and/or other materials provided with the distribution.
14 #     * Neither the name of Intel Corporation nor the names of its contributors
15 #       may be used to endorse or promote products derived from this software
16 #       without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 # This script runs only from the biosbits VM.
31 """Tests and helpers for CPUID."""
33 import bits
34 import testsuite
35 import testutil
37 def cpuid_helper(function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0):
38     if index is None:
39         index = 0
40         indexdesc = ""
41     else:
42         indexdesc = " index {0:#x}".format(index)
44     def find_mask(m):
45         if m == ~0:
46             return mask
47         return m
48     masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask])
50     uniques = {}
51     for cpu in bits.cpus():
52         regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)])
53         uniques.setdefault(regs, []).append(cpu)
55     desc = ["CPUID function {:#x}{}".format(function, indexdesc)]
57     if shift != 0:
58         desc.append("Register values have been shifted by {}".format(shift))
59     if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0:
60         desc.append("Register values have been masked:")
61         shifted_masks = bits.cpuid_result(*[m << shift for m in masks])
62         desc.append("Masks:           eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict()))
64     if len(uniques) > 1:
65         regvalues = zip(*uniques.iterkeys())
66         common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues))
67         common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)])
68         desc.append('Register values are not unique across all logical processors')
69         desc.append("Common bits:     eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict()))
70         desc.append("Mask of common bits: {eax:#010x}     {ebx:#010x}     {ecx:#010x}     {edx:#010x}".format(**common_masks._asdict()))
72     for regs in sorted(uniques.iterkeys()):
73         cpus = uniques[regs]
74         desc.append("Register value:  eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict()))
75         desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus)))
77     return uniques, desc
79 def test_cpuid_consistency(text, function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0):
80     uniques, desc = cpuid_helper(function, index, shift, mask, eax_mask, ebx_mask, ecx_mask, edx_mask)
81     desc[0] += " Consistency Check"
82     if text:
83         desc.insert(0, text)
84     status = testsuite.test(desc[0], len(uniques) == 1)
85     for line in desc[1:]:
86         testsuite.print_detail(line)
87     return status